If backup target is file then check it is not present or regular
empty file otherwise. If backup target is block device then
check it is present.
---

I decided to use switches instead of more compact if branches as in other
places so that the code will noticeably break when this function will
be called for storage types other then file or block.

 src/qemu/qemu_driver.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 17055b2..a606058 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20261,6 +20261,72 @@ qemuDomainSetGuestVcpus(virDomainPtr dom,
 }
 
 
+static int
+qemuDomainBackupPrepareDisk(virDomainBackupDiskDefPtr disk)
+{
+    int ret = -1;
+    struct stat st;
+    virStorageSourcePtr target = disk->target;
+
+    if (virStorageFileInit(target) < 0)
+        return -1;
+
+    if (virStorageFileStat(target, &st) < 0) {
+        if (errno != ENOENT) {
+            virReportSystemError(errno,
+                                 _("unable to stat target path '%s' for disk 
'%s'"),
+                                 target->path, disk->name);
+            goto cleanup;
+        }
+        switch (target->type) {
+        case VIR_STORAGE_TYPE_FILE:
+            break;
+        case VIR_STORAGE_TYPE_BLOCK:
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("missing target block device '%s' for disk '%s'"),
+                           target->path, disk->name);
+            goto cleanup;
+        default:
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("unexpected backup target type '%s' for disk 
'%s'"),
+                           virStorageTypeToString(target->type),
+                           disk->name);
+            goto cleanup;
+        }
+    } else {
+        switch (target->type) {
+        case VIR_STORAGE_TYPE_FILE:
+            if (!S_ISREG(st.st_mode) || st.st_size > 0) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("invalid existing target file '%s' for disk 
'%s'"),
+                               target->path, disk->name);
+                goto cleanup;
+            }
+            break;
+        case VIR_STORAGE_TYPE_BLOCK:
+            if (!S_ISBLK(st.st_mode)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("target file '%s' for disk '%s' is not a 
block device"),
+                               target->path, disk->name);
+                goto cleanup;
+            }
+            break;
+        default:
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("unexpected backup target type '%s' for disk 
'%s'"),
+                           virStorageTypeToString(target->type), disk->name);
+            goto cleanup;
+        }
+    }
+
+    ret = 0;
+
+ cleanup:
+    virStorageFileDeinit(target);
+    return ret;
+}
+
+
 static virDomainBackupPtr
 qemuDomainBackupCreateXML(virDomainPtr domain,
                           const char *xmlDesc,
@@ -20336,6 +20402,9 @@ qemuDomainBackupCreateXML(virDomainPtr domain,
         if (qemuDomainDiskBlockJobIsActive(disk))
             goto cleanup;
 
+        if (qemuDomainBackupPrepareDisk(&def->disks[i]) < 0)
+            goto cleanup;
+
         if (qemuGetDriveSourceString(target, NULL, &path) < 0)
             goto cleanup;
 
-- 
1.8.3.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to