This repository has the intention to help you to create and manage your VM's backups. To do this, it uses the Dirty bitmaps and the QMP protocol.
Before starting, your VM has to be reachable via QMP through unix socket. This can be done by adding the following option to your command that runs the virtual machine:
-qmp unix:/path/vm_name.socket,server,nowait
Furthermore, you need qmp-shell because it makes communication via QMP much easier and qemu-backup uses it to run commands and get needed information about VM.
You also have to edit your -drive
option, because it has to have id=disk
. It should looks like this:
-drive file=/path/file.img,format=qcow2,id=disk
Obviously if you want to have another id
you can, but you have to edit bitmap.py.
The first thing you need to do to use qemu-backup is to edit the config.ini file.
[DEFAULT]
QmpShellPath = /home/tux/Documents/qemu/scripts/qmp/qmp-shell
SocketPath = /home/tux/Documents/sockets
BackupPath = /media/backups
QmpShellPath
: you have to enter the path to the qmp-shell fileSocketPath
: you have to enter the path to the folder that will contain all unix sockets of VMs for communication via QMPBackupPath
: you have to enter the path that will contain all the backups of the virtual machines.
Then, you can create the bitmap with this command:
python3 main.py bitmap <VM_NAME>
ℹ️ Basically <VM_NAME> is the name you have given to the socket. It will also be the name that will be given to the folder under
BackupPath
.
Once this command has been run, if you run the following commands you will see something like this:
$ printf 'query-block' | sudo /home/tux/Documents/qemu/scripts/qmp/qmp-shell /home/tux/Documents/sockets/mint.socket
Welcome to the QMP low-level shell!
Connected to QEMU 4.2.1
(QEMU) {
"return":
...
"dirty-bitmaps": [{"name": "bitmap0", "recording": true, "persistent": true, "busy": false, "status": "active", "granularity": 65536, "count": 1900806144}],
...
}
$ tree /media/backups
/media/backups/
├── mint
│ ├── current
│ └── old
Now, you are ready to run the first full backup for your virtual machine. So, run the following command:
python3 main.py full <VM_NAME>
You should see a progress bar that displays the backup completion with the remaining bytes and, when it has finished, the path where the backup was saved:
$ python3 main.py full mint
Running full backup |#######...........................................| 0 of 10737418240 bytes
Backup completed
Path: "/media/backups/mint/current/full-20211109171941.img"
After full backup, you can perform the incremental backup whenever you like with this command:
python3 main.py inc <VM_NAME>
As for full backup, you should see an output like this:
$ python3 main.py inc mint
Running incremental backup |#######...........................................| 0 of 1073741824 bytes
Backup completed
Path: "/media/backups/mint/current/inc-0.img"
The rebase action allows you to restore all saved changes inside your incremental backups to the single full backup in the current folder. This way you have an image ready to boot, but if you don't need to make another full backup you can continue to use that image for the other incremental backups. For example, I run a rebase every 10 incremental backups.
$ python3 main.py rebase mint
"/media/backups/mint/current/full-20211112175452.img" is based on "/media/backups/mint/current/inc-0.img"
sudo qemu-img check /media/backups/mint/current/inc-0.img
sudo qemu-img rebase -b "/media/backups/mint/current/full-20211112175452.img" "/media/backups/mint/current/inc-0.img"
sudo qemu-img commit "/media/backups/mint/current/inc-0.img"
sudo rm /media/backups/mint/current/inc-0.img
Rollback of latest [FULL]<-[INC] chain complete
In addition to those python scripts, I developed two other scripts in bash to perform backups before shutting down the virtual machine.
This script is placed directly on the virtual machine. To execute it, I created a shortcut on the desktop that runs the script in a terminal. If you want, you can have the command run automatically before shutdown but I don't recommend it because, for example, if you make any changes that don't boot up the VM anymore, you take them with you in the backups. So I prefer to run them manually with a double click.
This script is the one that is executed by run_backup.sh, so it is placed on the host, basically with the other python scripts. After performing the backup, it sends a shutdown to the virtual machine.