From 91bf57fefbc93e16e7a6a02317350cf5ad66f32c Mon Sep 17 00:00:00 2001 Message-Id: <91bf57fefbc93e16e7a6a02317350cf5ad66f32c.1304950498.git.jdenemar@redhat.com> From: Eric Blake <eblake@redhat.com> Date: Fri, 22 Apr 2011 11:43:22 -0600 Subject: [PATCH] qemu: avoid double close on domain restore 5.7: https://bugzilla.redhat.com/show_bug.cgi?id=681623 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. (cherry picked from commit 4f805dcdc433dc8799dc8a3b02bce813c3047656) Conflicts: src/qemu/qemu_driver.c - deal with upstream qemu_process refactor, no VIR_FORCE_CLOSE, changed signature of qemudStartVMDaemon --- src/qemu/qemu_driver.c | 36 +++++++++++++++++++----------------- 1 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 84dc7b8..98767bd 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6430,8 +6430,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) { @@ -6455,20 +6455,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 = qemudStartVMDaemon(conn, driver, vm, "stdio", true, fd, path); + ret = qemudStartVMDaemon(conn, driver, vm, "stdio", true, *fd, path); if (intermediate_pid != -1) { if (ret < 0) { @@ -6479,9 +6480,9 @@ qemudDomainSaveImageStartVM(virConnectPtr conn, close(intermediatefd); intermediatefd = -1; } - if (fd != -1) { - close(fd); - fd = -1; + if (*fd != -1) { + close(*fd); + *fd = -1; } kill(intermediate_pid, SIGTERM); } @@ -6495,10 +6496,10 @@ qemudDomainSaveImageStartVM(virConnectPtr conn, if (intermediatefd != -1) close(intermediatefd); - wait_ret = qemudDomainSaveImageClose(fd, read_pid, &status); - fd = -1; - if (read_pid != -1) { - read_pid = -1; + wait_ret = qemudDomainSaveImageClose(*fd, *read_pid, &status); + *fd = -1; + if (*read_pid != -1) { + *read_pid = -1; if (wait_ret == -1) { virReportSystemError(errno, _("failed to wait for process reading '%s'"), @@ -6519,6 +6520,7 @@ qemudDomainSaveImageStartVM(virConnectPtr conn, } } } + *read_pid = -1; if (ret < 0) { qemuDomainStartAudit(vm, "restored", false); @@ -6594,8 +6596,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; @@ -6645,8 +6647,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); -- 1.7.5.rc3