Surprisingly, nothing special is happening here. If we are the first to use the managed helper then spawn it. If not, we're almost done. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/qemu/qemu_hotplug.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_process.c | 38 +++++++++++++++++++++----- src/qemu/qemu_process.h | 7 +++++ 3 files changed, 110 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index e0a5300f0..8cc0b631d 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -348,6 +348,58 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, } +static int +qemuBuildPRDefInfoProps(virDomainObjPtr vm, + virDomainDiskDefPtr disk, + virJSONValuePtr *prmgrProps, + const char **prAlias, + const char **prPath) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + qemuDomainStorageSourcePrivatePtr srcPriv; + virJSONValuePtr props = NULL; + int ret = -1; + + srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(disk->src); + + *prmgrProps = NULL; + + if (priv->prPid != (pid_t) -1 || + !srcPriv->prd || + !srcPriv->prd->alias) + return 0; + + if (virJSONValueObjectCreate(&props, + "s:path", srcPriv->prd->path, + NULL) < 0) + goto cleanup; + + if (qemuProcessSetupOnePRDaemon(vm, disk) < 0) + goto cleanup; + + *prAlias = srcPriv->prd->alias; + *prPath = srcPriv->prd->path; + *prmgrProps = props; + props = NULL; + ret = 0; + cleanup: + virJSONValueFree(props); + return ret; +} + + +static void +qemuDestroyPRDefObject(virDomainObjPtr vm, + const char *alias, + const char *path) +{ + if (!alias) + return; + + qemuProcessKillPRDaemon(vm, path, false); +} + + /** * qemuDomainAttachDiskGeneric: * @@ -365,12 +417,16 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver, char *devstr = NULL; char *drivestr = NULL; char *drivealias = NULL; + const char *prAlias = NULL; + const char *prPath = NULL; bool driveAdded = false; bool secobjAdded = false; bool encobjAdded = false; + bool prmgrAdded = false; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virJSONValuePtr secobjProps = NULL; virJSONValuePtr encobjProps = NULL; + virJSONValuePtr prmgrProps = NULL; qemuDomainStorageSourcePrivatePtr srcPriv; qemuDomainSecretInfoPtr secinfo = NULL; qemuDomainSecretInfoPtr encinfo = NULL; @@ -403,6 +459,9 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver, disk->info.alias) < 0) goto error; + if (qemuBuildPRDefInfoProps(vm, disk, &prmgrProps, &prAlias, &prPath) < 0) + goto error; + if (!(drivestr = qemuBuildDriveStr(disk, false, priv->qemuCaps))) goto error; @@ -435,6 +494,15 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver, encobjAdded = true; } + if (prmgrProps) { + rv = qemuMonitorAddObject(priv->mon, "pr-manager-helper", prAlias, + prmgrProps); + prmgrProps = NULL; /* qemuMonitorAddObject consumes */ + if (rv < 0) + goto exit_monitor; + prmgrAdded = true; + } + if (qemuMonitorAddDrive(priv->mon, drivestr) < 0) goto exit_monitor; driveAdded = true; @@ -455,6 +523,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver, cleanup: virJSONValueFree(secobjProps); virJSONValueFree(encobjProps); + virJSONValueFree(prmgrProps); qemuDomainSecretDiskDestroy(disk); VIR_FREE(devstr); VIR_FREE(drivestr); @@ -472,6 +541,8 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver, ignore_value(qemuMonitorDelObject(priv->mon, secinfo->s.aes.alias)); if (encobjAdded) ignore_value(qemuMonitorDelObject(priv->mon, encinfo->s.aes.alias)); + if (prmgrAdded) + ignore_value(qemuMonitorDelObject(priv->mon, prAlias)); if (qemuDomainObjExitMonitor(driver, vm) < 0) ret = -2; virErrorRestore(&orig_err); @@ -481,6 +552,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver, error: qemuDomainDelDiskSrcTLSObject(driver, vm, disk->src); ignore_value(qemuHotplugPrepareDiskAccess(driver, vm, disk, NULL, true)); + qemuDestroyPRDefObject(vm, prAlias, prPath); goto cleanup; } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index b876d293a..cb160727c 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2556,16 +2556,40 @@ qemuProcessResctrlCreate(virQEMUDriverPtr driver, } -static void -qemuProcessKillPRDaemon(virDomainObjPtr vm) +void +qemuProcessKillPRDaemon(virDomainObjPtr vm, + const char *socketPath, + bool force) { qemuDomainObjPrivatePtr priv = vm->privateData; + size_t nmanaged = 0; + size_t i; if (priv->prPid == (pid_t) -1) return; - virProcessKillPainfully(priv->prPid, true); - priv->prPid = (pid_t) -1; + for (i = 0; i < vm->def->ndisks; i++) { + qemuDomainStorageSourcePrivatePtr srcPriv; + virDomainDiskDefPtr disk = vm->def->disks[i]; + + if (!virStoragePRDefIsManaged(disk->src->pr)) + continue; + + nmanaged++; + + srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(disk->src); + if (!socketPath) + socketPath = srcPriv->prd->path; + } + + if (force || nmanaged <= 1) { + virProcessKillPainfully(priv->prPid, true); + priv->prPid = (pid_t) -1; + if (socketPath && + unlink(socketPath) < 0 && + errno != ENOENT) + VIR_WARN("Unable to remove pr helper socket %s", socketPath); + } } @@ -2593,7 +2617,7 @@ qemuProcessSetupOnePRDaemonHook(void *opaque) } -static int +int qemuProcessSetupOnePRDaemon(virDomainObjPtr vm, virDomainDiskDefPtr disk) { @@ -2713,7 +2737,7 @@ qemuProcessSetupPRDaemon(virDomainObjPtr vm) ret = 0; cleanup: if (ret < 0) - qemuProcessKillPRDaemon(vm); + qemuProcessKillPRDaemon(vm, NULL, true); return ret; } @@ -6812,7 +6836,7 @@ void qemuProcessStop(virQEMUDriverPtr driver, VIR_FREE(vm->def->seclabels[i]->imagelabel); } - qemuProcessKillPRDaemon(vm); + qemuProcessKillPRDaemon(vm, NULL, true); qemuHostdevReAttachDomainDevices(driver, vm->def); diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 274111567..fab45eb2d 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -203,4 +203,11 @@ int qemuProcessRefreshDisks(virQEMUDriverPtr driver, virDomainObjPtr vm, qemuDomainAsyncJob asyncJob); +int qemuProcessSetupOnePRDaemon(virDomainObjPtr vm, + virDomainDiskDefPtr disk); + +void qemuProcessKillPRDaemon(virDomainObjPtr vm, + const char *socketPath, + bool force); + #endif /* __QEMU_PROCESS_H__ */ -- 2.16.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list