This is an extended definition of virStoragePRDef because it contains runtime information (like path to pr helper socket, its pid and alias). Since these are driver dependant we should have a driver specific structure instead of putting all of that into driver agnostic structure. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/qemu/qemu_domain.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_domain.h | 18 ++++++++ 2 files changed, 138 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e8539dcab..7fa8c93b7 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -65,6 +65,7 @@ #endif #include <sys/time.h> #include <fcntl.h> +#include <signal.h> #if defined(HAVE_SYS_MOUNT_H) # include <sys/mount.h> #endif @@ -1829,6 +1830,9 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePtr priv) virBitmapFree(priv->migrationCaps); priv->migrationCaps = NULL; + + virHashFree(priv->prHelpers); + priv->prHelpers = NULL; } @@ -10917,6 +10921,122 @@ qemuDomainCheckMigrationCapabilities(virQEMUDriverPtr driver, } +static void +qemuDomainDiskPRObjectHashFree(void *payload, + const void *name) +{ + qemuDomainDiskPRObjectPtr tmp = payload; + + if (tmp->managed && + tmp->pid != (pid_t) -1) { + VIR_DEBUG("Forcibly killing pr-manager: %s", (const char *) name); + virProcessKillPainfully(tmp->pid, true); + } + VIR_FREE(tmp->path); + VIR_FREE(tmp); +} + + +/** + * qemuDomainDiskPRObjectRegister: + * @priv: Domain private data + * @alias: alias of the pr-manager object + * @managed: true if pr-managed object is manged by libvirt + * @path: socket path for the pr-manager object + * + * Records [alias, managed, path] tuple for pr-manager objects. + * On successful return @path is stolen and set to NULL. + * + * Returns 0 on success (with @path stolen), + * -1 otherwise (with error reported). + */ +int +qemuDomainDiskPRObjectRegister(qemuDomainObjPrivatePtr priv, + const char *alias, + bool managed, + char **path) +{ + qemuDomainDiskPRObjectPtr tmp; + int ret = -1; + + if (!priv->prHelpers && + !(priv->prHelpers = virHashCreate(10, qemuDomainDiskPRObjectHashFree))) + return -1; + + if ((tmp = virHashLookup(priv->prHelpers, alias))) { + /* Entry exists, check if it matches path. This shouldn't + * happen, but it's better to be safe than sorry. */ + if (STRNEQ(tmp->path, *path)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("trying to change path for pr helper object")); + + return -1; + } + + /* Claim success */ + VIR_FREE(*path); + return 0; + } + + if (VIR_ALLOC(tmp) < 0) + goto cleanup; + + tmp->managed = managed, + tmp->path = *path; + tmp->pid = (pid_t) -1; + + if (virHashAddEntry(priv->prHelpers, alias, tmp) < 0) + goto cleanup; + + *path = NULL; + tmp = NULL; + ret = 0; + cleanup: + VIR_FREE(tmp); + return ret; +} + + +static int +qemuDomainDiskPRObjectKillOne(void *payload, + const void *name, + void *data ATTRIBUTE_UNUSED) +{ + qemuDomainDiskPRObjectPtr tmp = payload; + + if (!tmp->managed) + return 0; + + VIR_DEBUG("Killing pr-manager: %s", (const char *) name); + if (tmp->pid != (pid_t) -1 && + virProcessKill(tmp->pid, SIGTERM) < 0) { + virReportSystemError(errno, + _("Unable to kill pr-manager: %s"), + (const char *) name); + /* Don't return error; we want to kill as many as + * possible. */ + } else { + tmp->pid = (pid_t) -1; + } + + return 0; +} + + +void +qemuDomainDiskPRObjectKillAll(qemuDomainObjPrivatePtr priv) +{ + if (!priv->prHelpers) + return; + + virHashForEach(priv->prHelpers, + qemuDomainDiskPRObjectKillOne, NULL); + + virHashFree(priv->prHelpers); + priv->prHelpers = NULL; +} + + int qemuDomainPrepareDiskSource(virConnectPtr conn, virDomainDiskDefPtr disk, diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index ddfc46dcd..f741f3039 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -329,6 +329,8 @@ struct _qemuDomainObjPrivate { /* Migration capabilities. Rechecked on reconnect, not to be saved in * private XML. */ virBitmapPtr migrationCaps; + + virHashTablePtr prHelpers; }; # define QEMU_DOMAIN_PRIVATE(vm) \ @@ -990,4 +992,20 @@ qemuDomainPrepareDiskSource(virConnectPtr conn, qemuDomainObjPrivatePtr priv, virQEMUDriverConfigPtr cfg); +typedef struct _qemuDomainDiskPRObject qemuDomainDiskPRObject; +typedef qemuDomainDiskPRObject *qemuDomainDiskPRObjectPtr; +struct _qemuDomainDiskPRObject { + bool managed; + char *path; /* socket path */ + pid_t pid; /* daemon pid */ +}; + +int +qemuDomainDiskPRObjectRegister(qemuDomainObjPrivatePtr priv, + const char *alias, + bool managed, + char **path); +void +qemuDomainDiskPRObjectKillAll(qemuDomainObjPrivatePtr priv); + #endif /* __QEMU_DOMAIN_H__ */ -- 2.13.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list