[libvirt] [PATCH 02/10] qemu: migration: Refactor code now that we assume support for fd migration
Ján Tomko
jtomko at redhat.com
Tue Feb 16 17:15:39 UTC 2016
On Tue, Feb 16, 2016 at 04:29:44PM +0100, Peter Krempa wrote:
> 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.
> ---
> src/qemu/qemu_driver.c | 4 +-
> src/qemu/qemu_migration.c | 114 ++++++++++++++++------------------------------
> src/qemu/qemu_migration.h | 2 +-
> 3 files changed, 41 insertions(+), 79 deletions(-)
>
> @@ -5972,54 +5972,28 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
> return -1;
> }
>
> - if ((!compressor || pipe(pipeFD) == 0)) {
> - /* 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;
> - 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;
This is the only place that set restoreLabel to true.
> + if (compressor && pipe(pipeFD) < 0) {
> + virReportSystemError(errno, "%s",
> + _("Failed to create pipe for migration"));
> + return -1;
> }
>
> + /* 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;
Can you really relabel a pipe after it's been created?
> + bypassSecurityDriver = true;
> +
> if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
> goto cleanup;
>
> if (!compressor) {
> - const char *args[] = { "cat", NULL };
> -
> - if (priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX) {
While it seems it's (in theory) possible to get a different monType through
qemuProcessReconnect, I think we can safely ignore it.
> - rc = qemuMonitorMigrateToFd(priv->mon,
> - QEMU_MONITOR_MIGRATE_BACKGROUND,
> - fd);
> - } else {
> - rc = qemuMonitorMigrateToFile(priv->mon,
> - QEMU_MONITOR_MIGRATE_BACKGROUND,
> - args, path, offset);
> - }
> + rc = qemuMonitorMigrateToFd(priv->mon,
> + QEMU_MONITOR_MIGRATE_BACKGROUND,
> + fd);
> } else {
> const char *prog = compressor;
> const char *args[] = {
> @@ -6027,33 +6001,28 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
> "-c",
> NULL
> };
> - if (pipeFD[0] != -1) {
> - cmd = virCommandNewArgs(args);
> - virCommandSetInputFD(cmd, pipeFD[0]);
> - virCommandSetOutputFD(cmd, &fd);
> - virCommandSetErrorBuffer(cmd, &errbuf);
> - virCommandDoAsyncIO(cmd);
> - if (virSetCloseExec(pipeFD[1]) < 0) {
> - virReportSystemError(errno, "%s",
> - _("Unable to set cloexec flag"));
> - ignore_value(qemuDomainObjExitMonitor(driver, vm));
> - 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);
This was the last usage of qemuMonitorMigrateToFile.
> +
> + cmd = virCommandNewArgs(args);
> + virCommandSetInputFD(cmd, pipeFD[0]);
> + virCommandSetOutputFD(cmd, &fd);
> + virCommandSetErrorBuffer(cmd, &errbuf);
> + virCommandDoAsyncIO(cmd);
> + if (virSetCloseExec(pipeFD[1]) < 0) {
> + virReportSystemError(errno, "%s",
> + _("Unable to set cloexec flag"));
> + ignore_value(qemuDomainObjExitMonitor(driver, vm));
> + 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");
> }
> if (qemuDomainObjExitMonitor(driver, vm) < 0)
> goto cleanup;
> @@ -6105,13 +6074,6 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
> vm->def, path) < 0)
> VIR_WARN("failed to restore save state label on %s", path);
>
The hunk of code not displayed here will disappear after you delete the
unused bool.
ACK with restoreLabel removed.
Your call if you remove qemuMonitorMigrateToFile here or in a separate
patch.
Jan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20160216/84963bd4/attachment-0001.sig>
More information about the libvir-list
mailing list