提交 4f805dcd 编写于 作者: E Eric Blake

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.
上级 6a8ef183
...@@ -3248,8 +3248,8 @@ static int ATTRIBUTE_NONNULL(6) ...@@ -3248,8 +3248,8 @@ static int ATTRIBUTE_NONNULL(6)
qemudDomainSaveImageStartVM(virConnectPtr conn, qemudDomainSaveImageStartVM(virConnectPtr conn,
struct qemud_driver *driver, struct qemud_driver *driver,
virDomainObjPtr vm, virDomainObjPtr vm,
int fd, int *fd,
pid_t read_pid, pid_t *read_pid,
const struct qemud_save_header *header, const struct qemud_save_header *header,
const char *path) const char *path)
{ {
...@@ -3273,20 +3273,21 @@ qemudDomainSaveImageStartVM(virConnectPtr conn, ...@@ -3273,20 +3273,21 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
if (header->compressed != QEMUD_SAVE_FORMAT_RAW) { if (header->compressed != QEMUD_SAVE_FORMAT_RAW) {
intermediate_argv[0] = prog; intermediate_argv[0] = prog;
intermediatefd = fd; intermediatefd = *fd;
fd = -1; *fd = -1;
if (virExec(intermediate_argv, NULL, NULL, 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, qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to start decompression binary %s"), _("Failed to start decompression binary %s"),
intermediate_argv[0]); intermediate_argv[0]);
*fd = intermediatefd;
goto out; goto out;
} }
} }
} }
/* Set the migration source and start it up. */ /* 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); VIR_VM_OP_RESTORE);
if (intermediate_pid != -1) { if (intermediate_pid != -1) {
...@@ -3295,7 +3296,7 @@ qemudDomainSaveImageStartVM(virConnectPtr conn, ...@@ -3295,7 +3296,7 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
* wait forever to write to stdout, so we must manually kill it. * wait forever to write to stdout, so we must manually kill it.
*/ */
VIR_FORCE_CLOSE(intermediatefd); VIR_FORCE_CLOSE(intermediatefd);
VIR_FORCE_CLOSE(fd); VIR_FORCE_CLOSE(*fd);
kill(intermediate_pid, SIGTERM); kill(intermediate_pid, SIGTERM);
} }
...@@ -3307,9 +3308,9 @@ qemudDomainSaveImageStartVM(virConnectPtr conn, ...@@ -3307,9 +3308,9 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
} }
VIR_FORCE_CLOSE(intermediatefd); VIR_FORCE_CLOSE(intermediatefd);
wait_ret = qemudDomainSaveImageClose(fd, read_pid, &status); wait_ret = qemudDomainSaveImageClose(*fd, *read_pid, &status);
fd = -1; *fd = -1;
if (read_pid != -1) { if (*read_pid != -1) {
if (wait_ret == -1) { if (wait_ret == -1) {
virReportSystemError(errno, virReportSystemError(errno,
_("failed to wait for process reading '%s'"), _("failed to wait for process reading '%s'"),
...@@ -3330,6 +3331,7 @@ qemudDomainSaveImageStartVM(virConnectPtr conn, ...@@ -3330,6 +3331,7 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
} }
} }
} }
*read_pid = -1;
if (ret < 0) { if (ret < 0) {
qemuDomainStartAudit(vm, "restored", false); qemuDomainStartAudit(vm, "restored", false);
...@@ -3398,8 +3400,8 @@ static int qemudDomainRestore(virConnectPtr conn, ...@@ -3398,8 +3400,8 @@ static int qemudDomainRestore(virConnectPtr conn,
if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
goto cleanup; goto cleanup;
ret = qemudDomainSaveImageStartVM(conn, driver, vm, fd, ret = qemudDomainSaveImageStartVM(conn, driver, vm, &fd,
read_pid, &header, path); &read_pid, &header, path);
if (qemuDomainObjEndJob(vm) == 0) if (qemuDomainObjEndJob(vm) == 0)
vm = NULL; vm = NULL;
...@@ -3449,8 +3451,8 @@ static int qemudDomainObjRestore(virConnectPtr conn, ...@@ -3449,8 +3451,8 @@ static int qemudDomainObjRestore(virConnectPtr conn,
virDomainObjAssignDef(vm, def, true); virDomainObjAssignDef(vm, def, true);
def = NULL; def = NULL;
ret = qemudDomainSaveImageStartVM(conn, driver, vm, fd, ret = qemudDomainSaveImageStartVM(conn, driver, vm, &fd,
read_pid, &header, path); &read_pid, &header, path);
cleanup: cleanup:
virDomainDefFree(def); virDomainDefFree(def);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册