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 | 21 +++++++++++---------- 1 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7fc08e8..5acddcb 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3248,7 +3248,7 @@ static int ATTRIBUTE_NONNULL(6) qemudDomainSaveImageStartVM(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm, - int fd, + 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,8 +3308,8 @@ qemudDomainSaveImageStartVM(virConnectPtr conn, } VIR_FORCE_CLOSE(intermediatefd); - wait_ret = qemudDomainSaveImageClose(fd, read_pid, &status); - fd = -1; + wait_ret = qemudDomainSaveImageClose(*fd, read_pid, &status); + *fd = -1; if (read_pid != -1) { if (wait_ret == -1) { virReportSystemError(errno, @@ -3398,7 +3399,7 @@ static int qemudDomainRestore(virConnectPtr conn, if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) goto cleanup; - ret = qemudDomainSaveImageStartVM(conn, driver, vm, fd, + ret = qemudDomainSaveImageStartVM(conn, driver, vm, &fd, read_pid, &header, path); if (qemuDomainObjEndJob(vm) == 0) @@ -3449,7 +3450,7 @@ static int qemudDomainObjRestore(virConnectPtr conn, virDomainObjAssignDef(vm, def, true); def = NULL; - ret = qemudDomainSaveImageStartVM(conn, driver, vm, fd, + ret = qemudDomainSaveImageStartVM(conn, driver, vm, &fd, read_pid, &header, path); cleanup: -- 1.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list