[libvirt] [PATCH 04/14] qemu_domain: Introduce qemuDomainDiskPRObject

Michal Privoznik mprivozn at redhat.com
Thu Jan 18 16:04:36 UTC 2018


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 at redhat.com>
---
 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




More information about the libvir-list mailing list