How to backup / restore your VM (virtual machine)

Write tutorials for Linux Mint here
More tutorials on https://github.com/orgs/linuxmint/discu ... /tutorials and (archive) on https://community.linuxmint.com/tutorial
Forum rules
Don't add support questions to tutorials; start your own topic in the appropriate sub-forum instead. Before you post read forum rules
Post Reply
powerhouse
Level 6
Level 6
Posts: 1144
Joined: Thu May 03, 2012 3:54 am
Location: Israel
Contact:

How to backup / restore your VM (virtual machine)

Post by powerhouse »

Introduction

One of the advantages of using virtual machines (VM) is the ease of backing them up and restoring them when needed. This is particularly true for Windows - did you ever have to install Windows from scratch when things went sour and you didn't have a Windows clone?
This how-to provides 2 scripts - one for backup, the other for restore - that utilize "dd" for bit-by-bit cloning and "pigz" for data compression. "pigz" uses parallel processing and - depending on how many cores your CPU has - can really speed up the backup or restore process when comparing it to gzip.

The scripts below are specifically written for the HOW-TO make dual-boot obsolete using XEN VGA passthrough tutorial that can be found here: http://forums.linuxmint.com/viewtopic.php?f=42&t=112013.


Requirements

Although you can modify these simple scripts to suit your needs, they are really written to backup a LVM based RAW image holding your VM. RAW images are used by virtualization solutions such as Xen, kvm, and Virtualbox (see http://www.virtualbox.org/manual/ch09.html#rawdisk).

For the scripts to work, your VM must
1. reside on a logical volume (LV) using LVM (LVM2 to be precise);
2. use the RAW image format;
3. have at least 10GB spare capacity on your LVM volume that holds the VM, in order to create a snapshot*.

* If you don't have that much unused LVM capacity, you can reduce the snapshot size by changing the following line in the script below:

Code: Select all

lvcreate --size 10G --snapshot -n $guest-snap /dev/$group/$guest
Change the --size 10G to the size you want, e.g. --size 5G.

For instructions on how to install Linux Mint onto LVM partitions, see my tutorial here: http://forums.linuxmint.com/viewtopic.php?f=42&t=108442


Disclaimer

The following backup script has been provided in the hope that it might be useful, without any warranty whatsoever. It's been tested on my PC. However, I can't provide any guarantee that it will work on your computer, that it will save-keep your data, or that it won't intentionally or accidentally delete or destroy data. The script contains commands such as "mv" that will overwrite the target file without warning, and the powerful "dd" command that can easily delete a file, a partition, or an entire drive. So be warned!

If you don't have at least some basic understanding of shell scripts and/or if you don't know what this script does - DON'T USE IT !



Backup script

The backup script below creates a backup of the specified guest to the specified backup location. The backup image is named $guest.img.gz, with $guest being the logical volume (LV) name of the guest.

If the $guest.img.gz backup file already exists (e.g. from a previous backup), it will be renamed to $guest.img.gz.old and a new $guest.img.gz file will be created holding the new backup. If the $guest.img.gz.old file already exists, then it will be overwritten when the existing $guest.img.gz file is moved to $guest.img.gz.old.

In summary, when you have executed the backup script 2 or more times, you will have two backup copies:

- The most recent backup is $guest.img.gz
- The previous to the last backup is $guest.img.gz.old


Here the instructions for installing and running the backup script:

1. Copy and paste the script below into a text file using your favorite editor (pluma, gedit, whatever):

Code: Select all

#!/bin/sh

# Script to back up a virtual machine that uses RAW storage on a LVM volume

mt="/media/user/backup"			# mount point of backup drive
dev="/dev/mapper/vol1-backup"		# your backup volume or backup drive to mount
group="vol1"					# LVM group holding guest LV
guest="win7"					# LV name of guest

# See if $mt is already mounted, if not, mount it
if (mount | grep -q "$mt"); then
	mtd="yes"
else
	mtd="no"
	mkdir "$mt"
	mount "$dev" "$mt"
	if (mount | grep -q "$mt"); then
		echo
	else
		echo "Unable to mount $mt"
		exit 2
	fi
fi

sleep 2

# Get the size of the guest VM
size=`lvs --noheadings --units=b -o lv_size /dev/$group/$guest | cut -d'B' -f1`

# Make sure the backup volume is big enough to hold the backup.
# This test assumes uncompressed backup and isn't scientifically correct.
# If you are short on backup space but sure you got enough space for
# a backup, you can remove the following if...else..fi section.
if [ $size -gt `du -sb "$mt" | awk '{print $1}'` ]; then
	echo "Not enough space on backup volume ! Abort"
	exit 2
else
	echo
fi

# Move the existing backup file to ...old (and overwrite the ...old file)
mv "$mt"/$group-$guest.img.gz "$mt"/$group-$guest.img.gz.old

# Create a snapshot of the guest VM
lvcreate --size 10G --snapshot -n $guest-snap /dev/$group/$guest

# Backup guest VM
echo "Creating backup copy of $group-$guest..."
echo
dd if=/dev/$group/$guest-snap bs=1024k | pv -s $size | pigz -c > "$mt"/$group-$guest.img.gz

# Remove snapshot
lvremove -f /dev/$group/$guest-snap
sleep 2

# Unless $mtd flag is 'yes', unmount $mt
if [ "$mtd" = "yes" ]; then
	echo
else
	umount -l "$mt"
	rmdir "$mt"
	echo "$mt unmounted"
fi
2. Replace the following variables to match your needs:

mt="/media/user/backup" # Replace "/media/user/backup" with the mount point where you like to mount the backup drive/volume
dev="/dev/mapper/vol1-backup" # Replace "/dev/mapper/vol1-backup" with the device name of your backup volume (using LVM) or backup drive, for example /dev/sdc1
group="vol1" # Replace "vol1" with the group name of the LVM group holding your guest volume
guest="win7" # Replace "win7" with the volume name of your guest volume

Here some more examples:

mt="/media/tom/backup" - mount point of your backup drive/volume - note that Linux Mint automounts drives under /media/username/...
dev="/dev/sdc1" - if you use /dev/sdc1 as backup drive and don't use LVM on that drive
group="my_vms" - group name of the LVM volume group
guest="win8" - name of the LV (logical volume) that holds your VM

Note: The script can easily be modified to use regular paths to backup devices/partitions/folders when the backup volume doesn't use LVM. Also, if your backup volume is permanently mounted, or if you use external (USB) backup drives that get automatically mounted upon connection to the USB port, you can delete the two mount sections in the script. Just make sure the backup device/partition/folder is accessible while running the script.

3. Save the script as "vmbackup.sh" (or whatever name you fancy) to an appropriate location, for example /home/user or /root.

4. Change the ownership of the vmbackup.sh script to root. Open a terminal window and enter:

Code: Select all

sudo chown root:root vmbackup.sh
5. Change the permissions to rwx (read-write-execute) for root, and r-- (read only) for all other users:

Code: Select all

sudo chmod 744 vmbackup.sh
6. Important: While the backup script uses a snapshot to safely back up while the VM is running, you should shut down the VM before you execute the script! Why? Because Windows and other operating systems generate tons of temporary files, and/or change the state of files while running, so that backing up a VM while it is running can leave you with a useless backup copy that doesn't boot.

To run the backup script, open a terminal window and go to the folder where the script is located, then enter:

Code: Select all

sudo ./vmbackup.sh
Last edited by powerhouse on Sun May 11, 2014 11:59 pm, edited 6 times in total.
Subjects of interest: Linux, vfio passthrough virtualization, photography
See my blog on virtualization, including tutorials: https://www.heiko-sieger.info/category/ ... alization/
powerhouse
Level 6
Level 6
Posts: 1144
Joined: Thu May 03, 2012 3:54 am
Location: Israel
Contact:

Re: How to backup / restore your VM (virtual machine)

Post by powerhouse »

Introduction to restore script

The following script can be used to restore a VM that has been backed up using the previous backup script.

Disclaimer

The following restore script has been provided in the hope that it might be useful, without any warranty whatsoever. It's been tested on my PC, in conjunction with the backup script above. However, I can't provide any guarantee that it will work on your computer, that it will save-keep your data, or that it won't intentionally or accidentally delete or destroy data. The script uses the powerful "dd" command that can easily delete a file, a partition, or an entire drive. So be warned!

If you don't have at least some basic understanding of shell scripts and/or if you don't know what this script does - DON'T USE IT !



Warning: The restore script below will totally erase/overwrite your current VM. This process is irreversible!

You should only use this script when:
1. You have a recent backup file of your VM when your VM was in a working condition;
2. Your current VM is corrupted, virus infected, or otherwise damaged - in other words, you got a reason to restore from backup;
3. You know what you are doing.

If you performed multiple backups using above backup script, the restore script will use the more recent copy of the two backup files that the backup script produces. In other words it uses $guest.img.gz (with $guest being the LV name of the guest).

If you want to restore the older backup file - for example if the more recent backup was made of a corrupted, infected, or damaged VM - rename the backup files (mv ...) so that the $guest.img.gz.old becomes $guest.img.gz (replace $guest with the name of your VM).

The restore script uses pigz -d to decompress a gzipped backup image. The "dd" command stores the image bit-by-bit to the destination volume.


Restore script

Here are the instructions on installing and using the restore script:

1. Copy and paste the script below into a text file using your favorite editor (pluma, gedit, whatever):

Code: Select all

#!/bin/sh

# Script to restore a VM from a gzipped backup image file

mt="/media/user/backup"			# mount point of backup drive
dev="/dev/mapper/vol1-backup"		# your backup volume or backup drive to mount
group="vol1"					# LVM group holding guest LV
guest="win7"					# LV name of guest

echo
echo "This script will restore a VM from your last backup image"
echo "and overwrite your current VM installation."
echo
echo "All data in your current VM will be lost!"
echo
read -p "Are you sure you want to RESTORE your VM from your backup copy (y/n)?" choice

case "$choice" in 
  y|Y ) echo ;
	# See if $mt is already mounted, if not, mount it.

	if (mount | grep -q "$mt"); then
		mtd="yes"
	else
		mtd="no"
		mkdir "$mt"
		mount "$dev" "$mt"
		if (mount | grep -q "$mt"); then
			echo
		else
			echo "Unable to mount $mt"
			exit 2
		fi
	fi

	sleep 2

	echo "Restore $group-$guest from backup..."

	pv "$mt"/$group-$guest.img.gz | pigz -d | dd of=/dev/$group/$guest bs=1024k

	# Unless $mtd flag is 'yes', unmount $mt

	sleep 2

	if [ "$mtd" = "yes" ]; then
		echo
	else
		umount -l "$mt"
		rmdir "$mt"
		echo "$mt unmounted"
	fi

	echo "Done";
	exit 0;;
  n|N ) echo ;
	echo "no...exiting restore script"
	exit 1;;
  * ) echo ;
	echo "invalid answer...exiting restore script"
	exit 1;;
esac
2. Replace the following variables to match your needs:

mt="/media/user/backup" # Replace "/media/user/backup" with the mount point where you like to mount the backup drive/volume
dev="/dev/mapper/vol1-backup" # Replace "/dev/mapper/vol1-backup" with the device name of your backup volume (using LVM) or backup drive, for example /dev/sdc1
group="vol1" # Replace "vol1" with the group name of the LVM group holding your guest volume
guest="win7" # Replace "win7" with the volume name of your guest volume

Note: The script can easily be modified to use regular paths to backup devices/partitions/folders when the backup volume doesn't use LVM. Also, if your backup volume is permanently mounted, or if you use external (USB) backup drives that get automatically mounted upon connection to the USB port, you can delete the two mount sections in the script. Just make sure the backup device/partition/folder is accessible while running the script.

3. Save the script as "vmrestore.sh" (or whatever name you fancy) to an appropriate location, for example /home/user or /root.

4. Change the ownership of the vmrestore.sh script to root:

Code: Select all

    sudo chown root:root vmrestore.sh
Note: This step is actually a safety measure against accidental or intentional alteration of the script.

5. Change the permissions to rwx (read-write-execute) for root, and r-- (read only) for all other users:

Code: Select all

sudo chmod 744 vmrestore.sh
6. Important! Before running the restore script,
make sure your VM is shut down!

7. Don't run the vmrestore.sh script unless really necessary - see warning above!

To run the restore script, open a terminal window and go to the folder where the script is located. Then enter:

Code: Select all

sudo ./vmrestore.sh
Last edited by powerhouse on Sun Jun 23, 2013 3:26 am, edited 4 times in total.
Subjects of interest: Linux, vfio passthrough virtualization, photography
See my blog on virtualization, including tutorials: https://www.heiko-sieger.info/category/ ... alization/
powerhouse
Level 6
Level 6
Posts: 1144
Joined: Thu May 03, 2012 3:54 am
Location: Israel
Contact:

Re: How to backup / restore your VM (virtual machine)

Post by powerhouse »

Last not least, some performance figures.

Hardware:
Drive holding VM: Sandisk Extreme 120GB SSD drive, formatted to LVM
Backup drives: 2 WD 2TB Green drives formatted to striped LVM (similar to RAID 0)
CPU: i7 3930K 6-core CPU
(see below for more)

Size of Windows VM: 71GB
Size of backup file ($guest.img.gz): 40.5GB

Backup time: 7:24 minutes
Restore time: 6:24 minutes
Subjects of interest: Linux, vfio passthrough virtualization, photography
See my blog on virtualization, including tutorials: https://www.heiko-sieger.info/category/ ... alization/
powerhouse
Level 6
Level 6
Posts: 1144
Joined: Thu May 03, 2012 3:54 am
Location: Israel
Contact:

Re: How to backup / restore your VM (virtual machine)

Post by powerhouse »

I modified the scripts to allow for white space in the mount point. Now you can enter for example:

Code: Select all

mt="/media/user/My funny Valentine"         # mount point of backup drive
However, the group and guest variables don't allow for white space, so

Code: Select all

guest="win8"               # LV name of guest
is fine, but

Code: Select all

guest="Windows 8"      # LV name of guest
will NOT work!
Subjects of interest: Linux, vfio passthrough virtualization, photography
See my blog on virtualization, including tutorials: https://www.heiko-sieger.info/category/ ... alization/
powerhouse
Level 6
Level 6
Posts: 1144
Joined: Thu May 03, 2012 3:54 am
Location: Israel
Contact:

Re: How to backup / restore your VM (virtual machine)

Post by powerhouse »

My original Windows 7 partition on a 120GB SSD ran out of space. I needed more room and added a 250GB Samsung SSD. I could have enlarged the LV (logical volume) and grown the file system, but I decided to move the Windows VM onto the new SSD.

I used the backup and restore scripts together with some LVM commands to move the Windows VM from the old to the new SSD, and then enlarged it. Now my Windows VM has 140GB, with plenty of unallocated disk space to grow even larger. Of course, backup and restore takes a little longer now (the Windows volume size has doubled), but who cares when everything works smooth :D .
Subjects of interest: Linux, vfio passthrough virtualization, photography
See my blog on virtualization, including tutorials: https://www.heiko-sieger.info/category/ ... alization/
Post Reply

Return to “Tutorials”