]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Avoid create/unlink with block devs used for QEMU save
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 21 Apr 2010 10:42:50 +0000 (11:42 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 28 Apr 2010 12:47:49 +0000 (13:47 +0100)
It is possible to use block devices with domain save/restore. Upon
failure QEMU unlinks the path being saved to. This isn't good when
it is a block device !

* src/qemu/qemu_driver.c: Don't unlink block devices if save fails

src/qemu/qemu_driver.c

index 180f2d67d63d5ed535c50514d46d2d6f90865e98..c485e8fb86b9d31abdd96004f80997f915913f6a 100644 (file)
@@ -4713,6 +4713,8 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
     int rc;
     virDomainEventPtr event = NULL;
     qemuDomainObjPrivatePtr priv;
+    struct stat sb;
+    int is_reg = 0;
 
     memset(&header, 0, sizeof(header));
     memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic));
@@ -4767,6 +4769,20 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
     }
     header.xml_len = strlen(xml) + 1;
 
+    /* path might be a pre-existing block dev, in which case
+     * we need to skip the create step, and also avoid unlink
+     * in the failure case */
+    if (stat(path, &sb) < 0) {
+        /* Avoid throwing an error here, since it is possible
+         * that with NFS we can't actually stat() the file.
+         * The subsequent codepaths will still raise an error
+         * if a truely fatal problem is hit */
+        is_reg = 1;
+    } else {
+        is_reg = S_ISREG(sb.st_mode);
+    }
+
+
     /* Setup hook data needed by virFileOperation hook function */
     hdata.dom = dom;
     hdata.path = path;
@@ -4776,7 +4792,8 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
     /* Write header to file, followed by XML */
 
     /* First try creating the file as root */
-    if ((rc = virFileOperation(path, O_CREAT|O_TRUNC|O_WRONLY,
+    if (is_reg &&
+        (rc = virFileOperation(path, O_CREAT|O_TRUNC|O_WRONLY,
                                S_IRUSR|S_IWUSR,
                                getuid(), getgid(),
                                qemudDomainSaveFileOpHook, &hdata,
@@ -4941,7 +4958,7 @@ endjob:
 
 cleanup:
     VIR_FREE(xml);
-    if (ret != 0)
+    if (ret != 0 && is_reg)
         unlink(path);
     if (vm)
         virDomainObjUnlock(vm);