]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: avoid double close on domain restore
authorEric Blake <eblake@redhat.com>
Wed, 2 Mar 2011 03:59:38 +0000 (20:59 -0700)
committerEric Blake <eblake@redhat.com>
Wed, 2 Mar 2011 15:58:49 +0000 (08:58 -0700)
qemudDomainSaveImageStartVM was evil - it closed the incoming fd
argument on some, but not all, code paths, without informing the
caller about that action.  No wonder that this resulted in
double-closes: https://bugzilla.redhat.com/show_bug.cgi?id=672725

* src/qemu/qemu_driver.c (qemudDomainSaveImageStartVM): Alter
signature, to avoid double-close.
(qemudDomainRestore, qemudDomainObjRestore): Update callers.

src/qemu/qemu_driver.c

index 7fc08e88444e9059563e361fb384669b7db93f1f..c9095bb05c22e7a8b6203838679dcee5706d9329 100644 (file)
@@ -3248,8 +3248,8 @@ static int ATTRIBUTE_NONNULL(6)
 qemudDomainSaveImageStartVM(virConnectPtr conn,
                             struct qemud_driver *driver,
                             virDomainObjPtr vm,
-                            int fd,
-                            pid_t read_pid,
+                            int *fd,
+                            pid_t *read_pid,
                             const struct qemud_save_header *header,
                             const char *path)
 {
@@ -3273,20 +3273,21 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
 
         if (header->compressed != QEMUD_SAVE_FORMAT_RAW) {
             intermediate_argv[0] = prog;
-            intermediatefd = fd;
-            fd = -1;
+            intermediatefd = *fd;
+            *fd = -1;
             if (virExec(intermediate_argv, NULL, NULL,
-                        &intermediate_pid, intermediatefd, &fd, NULL, 0) < 0) {
+                        &intermediate_pid, intermediatefd, fd, NULL, 0) < 0) {
                 qemuReportError(VIR_ERR_INTERNAL_ERROR,
                                 _("Failed to start decompression binary %s"),
                                 intermediate_argv[0]);
+                *fd = intermediatefd;
                 goto out;
             }
         }
     }
 
     /* Set the migration source and start it up. */
-    ret = qemuProcessStart(conn, driver, vm, "stdio", true, fd, path,
+    ret = qemuProcessStart(conn, driver, vm, "stdio", true, *fd, path,
                            VIR_VM_OP_RESTORE);
 
     if (intermediate_pid != -1) {
@@ -3295,7 +3296,7 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
              * wait forever to write to stdout, so we must manually kill it.
              */
             VIR_FORCE_CLOSE(intermediatefd);
-            VIR_FORCE_CLOSE(fd);
+            VIR_FORCE_CLOSE(*fd);
             kill(intermediate_pid, SIGTERM);
         }
 
@@ -3307,9 +3308,9 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
     }
     VIR_FORCE_CLOSE(intermediatefd);
 
-    wait_ret = qemudDomainSaveImageClose(fd, read_pid, &status);
-    fd = -1;
-    if (read_pid != -1) {
+    wait_ret = qemudDomainSaveImageClose(*fd, *read_pid, &status);
+    *fd = -1;
+    if (*read_pid != -1) {
         if (wait_ret == -1) {
             virReportSystemError(errno,
                                  _("failed to wait for process reading '%s'"),
@@ -3330,6 +3331,7 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
             }
         }
     }
+    *read_pid = -1;
 
     if (ret < 0) {
         qemuDomainStartAudit(vm, "restored", false);
@@ -3398,8 +3400,8 @@ static int qemudDomainRestore(virConnectPtr conn,
     if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
         goto cleanup;
 
-    ret = qemudDomainSaveImageStartVM(conn, driver, vm, fd,
-                                      read_pid, &header, path);
+    ret = qemudDomainSaveImageStartVM(conn, driver, vm, &fd,
+                                      &read_pid, &header, path);
 
     if (qemuDomainObjEndJob(vm) == 0)
         vm = NULL;
@@ -3449,8 +3451,8 @@ static int qemudDomainObjRestore(virConnectPtr conn,
     virDomainObjAssignDef(vm, def, true);
     def = NULL;
 
-    ret = qemudDomainSaveImageStartVM(conn, driver, vm, fd,
-                                      read_pid, &header, path);
+    ret = qemudDomainSaveImageStartVM(conn, driver, vm, &fd,
+                                      &read_pid, &header, path);
 
 cleanup:
     virDomainDefFree(def);