[libvirt] [PATCH v2 RFC 08/12] qemu: backup: check backup destination before start

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Fri May 12 13:37:24 UTC 2017


If backup target is file then check it is not present or regular
empty file otherwise. If backup target is block device then
check that it is present and block device actually.
---
 src/qemu/qemu_driver.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b20e359..f4456da 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20468,6 +20468,76 @@ qemuDomainSetBlockThreshold(virDomainPtr dom,
 }
 
 
+static int
+qemuDomainBackupCheckTarget(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,
@@ -20529,6 +20599,9 @@ qemuDomainBackupCreateXML(virDomainPtr domain,
         if (qemuDomainDiskBlockJobIsActive(disk))
             goto cleanup;
 
+        if (qemuDomainBackupCheckTarget(&def->disks[i]) < 0)
+            goto cleanup;
+
         if (qemuGetDriveSourceString(target, NULL, &path) < 0)
             goto cleanup;
 
-- 
1.8.3.1




More information about the libvir-list mailing list