One of the things that I love about Netapp is the snapshot and flexclone capabilities. fast backups and fast restores.
The problem that if you want to restore the WHOLE VM then it’s a simple process (the Netapp VSC provides a simple way to do this) but the single file restore has always seemed a bit hodgepodge, especially on Linux.
I wanted to share the process and scripts that I created to restore single file inside of Linux (RHEL systems that uses LVM and ext4 filesystems) just to save someone out there some time.
NOTE: I take no responsibility for the use of any of these scripts in your environment! Please thoroughly read the scripts and test to see if it fits with your setup.
Process to Attach Disks
- Right Click on the VM and Choose Netapp -> Backup and Recovery -> Mount
- Choose the backup that you want to mount and the ESXi host that the VM you want to restore the files on is located and click Mount
- Right Click the VM and choose Edit Settings
- Choose Add, Hard Disk, Use an Existing Virtual Disk
- Choose the datastore that was just mounted (it should have the date of the snapshot in it), choose the folder of the VM, choose a vmdk (the script below assumes all vmdks are attached)
- Click Next->Next->Finish
- You will see a new disk added, repeat the steps above to add the rest of the disks
- Click OK on the Edit Hardware screen
Process to scan and mount disks
- Run the mount_recovery script
- Answer y and press enter
- Import the vgs with word “clone” appended to it
- Activate the vgs
- Activate the LVs
- Convert labels to device names
- Match the original devices with the backup devices
- Use sed to replace the original and backup devices as well as the original and clone volume groups
- Mount the ext filesystems under /mnt/<servername>/root
- Copy the files that you want to recover
- Run the umount_recovery script, this will do the following
- Unmount all of the filesystems under /mnt/<servername>
- Deactivate all of the clone logical volumes
- Deactivate all of the clone volume groups
Process to Detach Disks
- Edit the VM’s hardware
- Select the backup hard disk
- Click Remove
- Repeat steps 2-4 for all backup hard disks
- Click OK (the os SHOULD clean up all device files)
- Right Click the VM ->Netapp -> Backup and Recovery -> Unmount
- Choose the backup to unmount and click unmount
mount_recovery script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
#!/bin/bash #this script assumes that every disk that ALL disks are attached (every disk will have a duplicate) and that every disk has a LVM partition on it IFS=' ' SERVERNAME=$(hostname | awk -F'.' '{print $1}') PATHTOMOUNT=/mnt/$SERVERNAME if [ ! -d $PATHTOMOUNT ] then mkdir $PATHTOMOUNT fi rm -rf $PATHTOMOUNT/* if [ -f $PATHTOMOUNT/drivemapfile ] then rm -f $PATHTOMOUNT/drivemapfile fi if [ ! -d $PATHTOMOUNT/root ] then mkdir $PATHTOMOUNT/root fi function mount_backup { for subvg in $(vgs 2>&1|awk '{print $1}'| grep -v ^Found | grep -v ^VG) do allpvs=$(pvs 2>&1|awk '{print $1 "," $2}'|grep '^/'| grep $subvg | awk -F',' '{print $1}'|tr '\n' ' ') command="vgimportclone -n ${subvg}clone" for dude in $(echo $allpvs) do command+=" " command+=$dude done echo $command eval $command if [ $? -eq 0 ]; then echo vgchange -ay echo lvchange -ay /dev/${subvg}clone/* vgchange -ay lvchange -ay /dev/${subvg}clone/* else echo "error with vgimportclone -n ${subvg}clone $allpvs" exit 1 fi done #only handling ext filesystems grep ext /etc/fstab >$PATHTOMOUNT/fstab #if any mounts are labels or uuids, then convert to sd* or lvm notation MYRA=($(grep -e LABEL -e UUID $PATHTOMOUNT/fstab | awk '{print $1}')) for LABELID in ${MYRA[@]}; do DEVNAME=($(/sbin/blkid -t $LABELID | /bin/cut -d " " -f 1 | /bin/cut -d ":" -f1)); sed --in-place "s#$LABELID #$DEVNAME #g" $PATHTOMOUNT/fstab; done #change sd* names in fstab from the original to the backup for PARTORIG in $(grep "/dev/sd" /etc/fstab | awk '{print $1}') do PARTORIGUUID=$(blkid $PARTORIG|awk '{print $2}') for DEVBKUP in $(pvs | grep clone | awk '{print $1}' | sed s#[0-9]##g | sort -u) do for PARTBKUP in $(fdisk -lu $DEVBKUP| grep -v "Linux LVM"| grep -v "swap" |grep Linux | awk '{print $1}') do PARTBKUPUUID=$(blkid $PARTBKUP | awk '{print $2}') if [ "$PARTORIGUUID" = "$PARTBKUPUUID" ] then echo "$PARTORIG is $PARTBKUP" sed -i "s#$PARTORIG#$PARTBKUP#g" $PATHTOMOUNT/fstab break fi done done done #change vg names in fstab from the original to the backup for VG in $(vgs | grep -v VFree | awk '{print $1}'| grep clone) do VGORIG=$(echo $VG | awk -F'clone' '{print $1}') echo "$VGORIG is $VG" sed -i "s#$VGORIG#$VG#g" $PATHTOMOUNT/fstab done #ignore MIRROR devices to save time #use the single fs mount to mount those for FILESYS in $(cat $PATHTOMOUNT/fstab|grep -v MIRROR) do DEVICE=$(echo $FILESYS | awk '{print $1}') DEVICEMOUNT=$(echo $FILESYS | awk '{print $2}') DEVICETYPE=$(echo $FILESYS | awk '{print $3}') echo $DEVICEMOUNT | grep boot > /dev/null if [ $? -eq 0 ]; then #using regular mount echo "Mounting $PATHTOMOUNT/root$DEVICEMOUNT" mount -t $DEVICETYPE $DEVICE $PATHTOMOUNT/root$DEVICEMOUNT else if [ ! -d $PATHTOMOUNT/root$DEVICEMOUNT ]; then echo "$PATHTOMOUNT/root$DEVICEMOUNT doesn't exist, creating $PATHTOMOUNT/tmpmount/root$DEVICEMOUNT" mkdir -p $PATHTOMOUNT/root$DEVICEMOUNT echo "Mounting $PATHTOMOUNT/tmpmount/root$DEVICEMOUNT" mount -t $DEVICETYPE $DEVICE $PATHTOMOUNT/root$DEVICEMOUNT else echo "Mounting $PATHTOMOUNT/root$DEVICEMOUNT" mount -t $DEVICETYPE $DEVICE $PATHTOMOUNT/root$DEVICEMOUNT fi fi done } #vgdisplay to recognize the new disks vgdisplay > /dev/null echo "These are the pvs that were probably added, please verify this against dmesg prior to continuing" pvs 2>&1|awk '{print $1 "," $2}'|grep '^/' for subvg in $(vgs 2>&1|awk '{print $1}'| grep -v ^Found | grep -v ^VG) do allpvs=$(pvs 2>&1|awk '{print $1 "," $2}'|grep '^/'| grep $subvg | awk -F',' '{print $1}'|tr '\n' ' ') echo "vgimportclone -n ${subvg}clone $allpvs" echo "vgchange -ay" echo "lvchange -ay /dev/${subvg}clone/*" done while true; do read -p "Do you wish to continue?" yn case $yn in [Yy]* ) mount_backup; break;; [Nn]* ) exit;; * ) echo "Please answer yes or no.";; esac done |
1 2 3 4 5 6 7 8 9 10 11 |
#!/bin/bash SERVERNAME=$(hostname | awk -F'.' '{print $1}') PATHTOUNMOUNT=/mnt/$SERVERNAME #unmount filesystems for FSTOUNMOUNT in $(mount | awk '{print $3}' | grep $PATHTOUNMOUNT | sort -r) do umount $FSTOUNMOUNT done for MYVG in $(vgdisplay -c | awk -F':' '{print $1}'| awk '{print $1}' | grep clone); do lvchange -an /dev/$MYVG/*;vgchange -an $MYVG; done |
Hi Chris,
Sorry I am probably doing something very daft but the script that you have posted, should that work just as it is or are there certain sections that need changing depending on our environment?
Craig
It’s been a while, but is assumes that every disk has a LVM partition, that you are using ext3, and that uuids are not used in fstab.
If you post your fstab, fdisk -l vgdisplay and lvdisplay maybe i can figure out what’s going on.