From abfab1b1c12d89c31a20738c93e60999204d16bc Mon Sep 17 00:00:00 2001 From: Michael Ablassmeier Date: Fri, 26 Jan 2024 14:45:32 +0100 Subject: [PATCH] (#4) backup qcow image configuration if blockdev-backup is used, the backup process must create the target image using blockdev-add/create. In order to correctly backup the image, we also require the original image config. For now, store the image config in the backup folder alongside the disk data. --- libqmpbackup/image.py | 12 ++++++++++++ qmpbackup | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/libqmpbackup/image.py b/libqmpbackup/image.py index c55b6f4..cb5c35f 100644 --- a/libqmpbackup/image.py +++ b/libqmpbackup/image.py @@ -18,6 +18,18 @@ log = logging.getLogger(__name__) +def get_info(filename): + """Query original qemu image information, can be used to re-create + the image during rebase operation with the same options as the + original one.""" + try: + return subprocess.check_output( + ["qemu-img", "info", f"{filename}", "--output", "json", "--force-share"] + ) + except subprocess.CalledProcessError as errmsg: + raise RuntimeError from errmsg + + def rebase(directory, dry_run, until): """Rebase and commit all images in a directory""" if not os.path.exists(directory): diff --git a/qmpbackup b/qmpbackup index bb90119..db00709 100755 --- a/qmpbackup +++ b/qmpbackup @@ -22,6 +22,7 @@ from qemu.qmp import protocol, QMPClient from libqmpbackup.qmpcommon import QmpCommon from libqmpbackup.lib import QmpBackup from libqmpbackup import vm +from libqmpbackup import image from libqmpbackup import version SIGNAL_CATCHED = False @@ -330,6 +331,17 @@ async def main(): common.thaw(qga) sys.exit(1) + for dev in blockdev: + infofile = f"{backupdir}/{dev.node}.config" + try: + info = image.get_info(dev.filename) + except RuntimeError as errmsg: + log.warning("Unable to get qemu image info: [%s]", errmsg) + continue + with open(infofile, "wb+") as info_file: + info_file.write(info) + log.info("Saved image info: [%s]", infofile) + if argv.level == "copy": blockdev = vm.get_block_devices( await qemu_client.do_query_block(), excluded_disks, included_disks