提交 23087cfd 编写于 作者: P Peter Krempa

qemu: migration: Refactor code now that we assume support for fd migration

After removing capability check for fd migration the code that was left
behind didn't make quite sense. The old exec migration would be used in
case when pipe() failed. Remove the old code and make failure of pipe()
a hard error.

This additionally removes usage of virCgroupAllowDevicePath outside of
qemu_cgroup.c.
上级 21212fca
...@@ -3188,9 +3188,7 @@ qemuDomainSaveMemory(virQEMUDriverPtr driver, ...@@ -3188,9 +3188,7 @@ qemuDomainSaveMemory(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
/* Perform the migration */ /* Perform the migration */
if (qemuMigrationToFile(driver, vm, fd, offset, path, if (qemuMigrationToFile(driver, vm, fd, qemuCompressProgramName(compressed),
qemuCompressProgramName(compressed),
bypassSecurityDriver,
asyncJob) < 0) asyncJob) < 0)
goto cleanup; goto cleanup;
...@@ -3691,8 +3689,8 @@ doCoreDump(virQEMUDriverPtr driver, ...@@ -3691,8 +3689,8 @@ doCoreDump(virQEMUDriverPtr driver,
if (!qemuMigrationIsAllowed(driver, vm, false, 0)) if (!qemuMigrationIsAllowed(driver, vm, false, 0))
goto cleanup; goto cleanup;
ret = qemuMigrationToFile(driver, vm, fd, 0, path, ret = qemuMigrationToFile(driver, vm, fd,
qemuCompressProgramName(compress), false, qemuCompressProgramName(compress),
QEMU_ASYNC_JOB_DUMP); QEMU_ASYNC_JOB_DUMP);
} }
......
...@@ -5940,15 +5940,13 @@ qemuMigrationFinish(virQEMUDriverPtr driver, ...@@ -5940,15 +5940,13 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
/* Helper function called while vm is active. */ /* Helper function called while vm is active. */
int int
qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm, qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
int fd, off_t offset, const char *path, int fd,
const char *compressor, const char *compressor,
bool bypassSecurityDriver,
qemuDomainAsyncJob asyncJob) qemuDomainAsyncJob asyncJob)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
int rc; int rc;
int ret = -1; int ret = -1;
bool restoreLabel = false;
virCommandPtr cmd = NULL; virCommandPtr cmd = NULL;
int pipeFD[2] = { -1, -1 }; int pipeFD[2] = { -1, -1 };
unsigned long saveMigBandwidth = priv->migMaxBandwidth; unsigned long saveMigBandwidth = priv->migMaxBandwidth;
...@@ -5972,54 +5970,27 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm, ...@@ -5972,54 +5970,27 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
return -1; return -1;
} }
if ((!compressor || pipe(pipeFD) == 0)) { if (compressor && pipe(pipeFD) < 0) {
/* All right! We can use fd migration, which means that qemu virReportSystemError(errno, "%s",
* doesn't have to open() the file, so while we still have to _("Failed to create pipe for migration"));
* grant SELinux access, we can do it on fd and avoid cleanup return -1;
* later, as well as skip futzing with cgroup. */
if (virSecurityManagerSetImageFDLabel(driver->securityManager, vm->def,
compressor ? pipeFD[1] : fd) < 0)
goto cleanup;
bypassSecurityDriver = true;
} else {
/* Phooey - we have to fall back on exec migration, where qemu
* has to popen() the file by name, and block devices have to be
* given cgroup ACL permission. We might also stumble on
* a race present in some qemu versions where it does a wait()
* that botches pclose. */
if (virCgroupHasController(priv->cgroup,
VIR_CGROUP_CONTROLLER_DEVICES)) {
int rv = virCgroupAllowDevicePath(priv->cgroup, path,
VIR_CGROUP_DEVICE_RW);
virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path, "rw", rv == 0);
if (rv == 1) {
/* path was not a device, no further need for cgroup */
} else if (rv < 0) {
goto cleanup;
}
}
if ((!bypassSecurityDriver) &&
virSecurityManagerSetSavedStateLabel(driver->securityManager,
vm->def, path) < 0)
goto cleanup;
restoreLabel = true;
} }
/* All right! We can use fd migration, which means that qemu
* doesn't have to open() the file, so while we still have to
* grant SELinux access, we can do it on fd and avoid cleanup
* later, as well as skip futzing with cgroup. */
if (virSecurityManagerSetImageFDLabel(driver->securityManager, vm->def,
compressor ? pipeFD[1] : fd) < 0)
goto cleanup;
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
goto cleanup; goto cleanup;
if (!compressor) { if (!compressor) {
const char *args[] = { "cat", NULL }; rc = qemuMonitorMigrateToFd(priv->mon,
QEMU_MONITOR_MIGRATE_BACKGROUND,
if (priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX) { fd);
rc = qemuMonitorMigrateToFd(priv->mon,
QEMU_MONITOR_MIGRATE_BACKGROUND,
fd);
} else {
rc = qemuMonitorMigrateToFile(priv->mon,
QEMU_MONITOR_MIGRATE_BACKGROUND,
args, path, offset);
}
} else { } else {
const char *prog = compressor; const char *prog = compressor;
const char *args[] = { const char *args[] = {
...@@ -6027,33 +5998,28 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm, ...@@ -6027,33 +5998,28 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
"-c", "-c",
NULL NULL
}; };
if (pipeFD[0] != -1) {
cmd = virCommandNewArgs(args); cmd = virCommandNewArgs(args);
virCommandSetInputFD(cmd, pipeFD[0]); virCommandSetInputFD(cmd, pipeFD[0]);
virCommandSetOutputFD(cmd, &fd); virCommandSetOutputFD(cmd, &fd);
virCommandSetErrorBuffer(cmd, &errbuf); virCommandSetErrorBuffer(cmd, &errbuf);
virCommandDoAsyncIO(cmd); virCommandDoAsyncIO(cmd);
if (virSetCloseExec(pipeFD[1]) < 0) { if (virSetCloseExec(pipeFD[1]) < 0) {
virReportSystemError(errno, "%s", virReportSystemError(errno, "%s",
_("Unable to set cloexec flag")); _("Unable to set cloexec flag"));
ignore_value(qemuDomainObjExitMonitor(driver, vm)); ignore_value(qemuDomainObjExitMonitor(driver, vm));
goto cleanup; goto cleanup;
}
if (virCommandRunAsync(cmd, NULL) < 0) {
ignore_value(qemuDomainObjExitMonitor(driver, vm));
goto cleanup;
}
rc = qemuMonitorMigrateToFd(priv->mon,
QEMU_MONITOR_MIGRATE_BACKGROUND,
pipeFD[1]);
if (VIR_CLOSE(pipeFD[0]) < 0 ||
VIR_CLOSE(pipeFD[1]) < 0)
VIR_WARN("failed to close intermediate pipe");
} else {
rc = qemuMonitorMigrateToFile(priv->mon,
QEMU_MONITOR_MIGRATE_BACKGROUND,
args, path, offset);
} }
if (virCommandRunAsync(cmd, NULL) < 0) {
ignore_value(qemuDomainObjExitMonitor(driver, vm));
goto cleanup;
}
rc = qemuMonitorMigrateToFd(priv->mon,
QEMU_MONITOR_MIGRATE_BACKGROUND,
pipeFD[1]);
if (VIR_CLOSE(pipeFD[0]) < 0 ||
VIR_CLOSE(pipeFD[1]) < 0)
VIR_WARN("failed to close intermediate pipe");
} }
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup; goto cleanup;
...@@ -6100,17 +6066,6 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm, ...@@ -6100,17 +6066,6 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
VIR_FREE(errbuf); VIR_FREE(errbuf);
virCommandFree(cmd); virCommandFree(cmd);
} }
if (restoreLabel && (!bypassSecurityDriver) &&
virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
vm->def, path) < 0)
VIR_WARN("failed to restore save state label on %s", path);
if (virCgroupHasController(priv->cgroup,
VIR_CGROUP_CONTROLLER_DEVICES)) {
int rv = virCgroupDenyDevicePath(priv->cgroup, path,
VIR_CGROUP_DEVICE_RWM);
virDomainAuditCgroupPath(vm, priv->cgroup, "deny", path, "rwm", rv == 0);
}
if (orig_err) { if (orig_err) {
virSetError(orig_err); virSetError(orig_err);
......
...@@ -176,13 +176,12 @@ int qemuMigrationConfirm(virConnectPtr conn, ...@@ -176,13 +176,12 @@ int qemuMigrationConfirm(virConnectPtr conn,
bool qemuMigrationIsAllowed(virQEMUDriverPtr driver, virDomainObjPtr vm, bool qemuMigrationIsAllowed(virQEMUDriverPtr driver, virDomainObjPtr vm,
bool remote, unsigned int flags); bool remote, unsigned int flags);
int qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm, int qemuMigrationToFile(virQEMUDriverPtr driver,
int fd, off_t offset, const char *path, virDomainObjPtr vm,
int fd,
const char *compressor, const char *compressor,
bool bypassSecurityDriver,
qemuDomainAsyncJob asyncJob) qemuDomainAsyncJob asyncJob)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
ATTRIBUTE_RETURN_CHECK;
int qemuMigrationCancel(virQEMUDriverPtr driver, int qemuMigrationCancel(virQEMUDriverPtr driver,
virDomainObjPtr vm); virDomainObjPtr vm);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册