mirror of
https://github.com/libvirt/libvirt.git
synced 2026-07-29 15:54:48 -05:00
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.
This commit is contained in:
+16
-14
@@ -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,
|
|||||||
|
|
||||||
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,
|
|||||||
* 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,
|
|||||||
}
|
}
|
||||||
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,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*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,
|
|||||||
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,
|
|||||||
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user