[libvirt] [RFC PATCH 09/10] qemu: prepare backup destination

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Mon Nov 14 07:15:01 UTC 2016


Prepare here is usual preparation for a disk to be used by qemu made
by qemuDomainDiskChainElementPrepare. That is set security labels,
add to lock manager and whitelist in cgroups. All three are related to
backup target too. Adding to a lock manager is less obvious but
can be useful if mirations with a running backup will be possible.
---
 src/qemu/qemu_driver.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a606058..c7f1b4f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20261,8 +20261,17 @@ qemuDomainSetGuestVcpus(virDomainPtr dom,
 }
 
 
+typedef struct _qemuDomainBackupDiskTrackInfo qemuDomainBackupDiskTrackInfo;
+typedef qemuDomainBackupDiskTrackInfo *qemuDomainBackupDiskTrackInfoPtr;
+struct _qemuDomainBackupDiskTrackInfo {
+    bool created;
+    bool prepared;
+};
+
+
 static int
-qemuDomainBackupPrepareDisk(virDomainBackupDiskDefPtr disk)
+qemuDomainBackupPrepareDisk(virDomainBackupDiskDefPtr disk,
+                            qemuDomainBackupDiskTrackInfoPtr track)
 {
     int ret = -1;
     struct stat st;
@@ -20280,6 +20289,12 @@ qemuDomainBackupPrepareDisk(virDomainBackupDiskDefPtr disk)
         }
         switch (target->type) {
         case VIR_STORAGE_TYPE_FILE:
+            if (virStorageFileCreate(target) < 0) {
+                virReportSystemError(errno, _("failed to create image file '%s'"),
+                                     target->path);
+                goto cleanup;
+            }
+            track->created = true;
             break;
         case VIR_STORAGE_TYPE_BLOCK:
             virReportError(VIR_ERR_INVALID_ARG,
@@ -20327,6 +20342,22 @@ qemuDomainBackupPrepareDisk(virDomainBackupDiskDefPtr disk)
 }
 
 
+static void
+qemuDomainBackupDiskUnlink(virDomainBackupDiskDefPtr disk)
+{
+    virStorageSourcePtr target = disk->target;
+
+    if (virStorageFileInit(target) < 0)
+        return;
+
+    if (virStorageFileUnlink(target) < 0)
+        VIR_WARN("unable to unlink target path '%s' for disk '%s', errno: %d",
+                 target->path, disk->name, errno);
+
+    virStorageFileDeinit(target);
+}
+
+
 static virDomainBackupPtr
 qemuDomainBackupCreateXML(virDomainPtr domain,
                           const char *xmlDesc,
@@ -20339,6 +20370,7 @@ qemuDomainBackupCreateXML(virDomainPtr domain,
     virDomainBackupPtr ret = NULL;
     virJSONValuePtr actions = NULL;
     virDomainObjPtr vm = NULL;
+    qemuDomainBackupDiskTrackInfoPtr track_disks = NULL;
     char *path = NULL, *device = NULL;
     bool job = false;
     int rc;
@@ -20371,6 +20403,9 @@ qemuDomainBackupCreateXML(virDomainPtr domain,
     if (!(actions = virJSONValueNewArray()))
         goto cleanup;
 
+    if (VIR_ALLOC_N(track_disks, def->ndisks) < 0)
+        goto cleanup;
+
     for (i = 0; i < def->ndisks; i++) {
         virStorageSourcePtr target = def->disks[i].target;
         virDomainDiskDefPtr disk;
@@ -20402,9 +20437,14 @@ qemuDomainBackupCreateXML(virDomainPtr domain,
         if (qemuDomainDiskBlockJobIsActive(disk))
             goto cleanup;
 
-        if (qemuDomainBackupPrepareDisk(&def->disks[i]) < 0)
+        if (qemuDomainBackupPrepareDisk(&def->disks[i], &track_disks[i]) < 0)
             goto cleanup;
 
+        if (qemuDomainDiskChainElementPrepare(driver, vm, def->disks[i].target,
+                                              false) < 0)
+            goto cleanup;
+        track_disks[i].prepared = true;
+
         if (qemuGetDriveSourceString(target, NULL, &path) < 0)
             goto cleanup;
 
@@ -20442,11 +20482,23 @@ qemuDomainBackupCreateXML(virDomainPtr domain,
     }
 
  cleanup:
+    if (!ret && def && track_disks) {
+        for (i = 0; i < def->ndisks; i++) {
+            virDomainBackupDiskDefPtr backup_disk = &def->disks[i];
+
+            if (track_disks[i].prepared)
+                qemuDomainDiskChainElementRevoke(driver, vm, backup_disk->target);
+            if (track_disks[i].created)
+                qemuDomainBackupDiskUnlink(backup_disk);
+        }
+    }
+
     if (job)
         qemuDomainObjEndJob(driver, vm);
 
     VIR_FREE(path);
     VIR_FREE(device);
+    VIR_FREE(track_disks);
 
     virDomainBackupDefFree(def);
     virJSONValueFree(actions);
-- 
1.8.3.1




More information about the libvir-list mailing list