From 4f805dcdc433dc8799dc8a3b02bce813c3047656 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 1 Mar 2011 20:59:38 -0700 Subject: [PATCH] qemu: avoid double close on domain restore 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 | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7fc08e8844..c9095bb05c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -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);