[libvirt] [PATCH v3 11/28] lock_driver: Introduce new VIR_LOCK_MANAGER_OBJECT_TYPE_DAEMON

Michal Privoznik mprivozn at redhat.com
Mon Aug 27 08:08:24 UTC 2018


We will want virtlockd to lock files on behalf of libvirtd and
not qemu process, because it is libvirtd that needs an exclusive
access not qemu. This requires new lock context.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/locking/lock_driver.h         |   2 +
 src/locking/lock_driver_lockd.c   | 110 +++++++++++++++++++++++++++++++-------
 src/locking/lock_driver_sanlock.c |  37 ++++++++-----
 3 files changed, 117 insertions(+), 32 deletions(-)

diff --git a/src/locking/lock_driver.h b/src/locking/lock_driver.h
index 8b7cccc521..a9d2041c30 100644
--- a/src/locking/lock_driver.h
+++ b/src/locking/lock_driver.h
@@ -42,6 +42,8 @@ typedef enum {
 typedef enum {
     /* The managed object is a virtual guest domain */
     VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN = 0,
+    /* The managed object is a daemon (e.g. libvirtd) */
+    VIR_LOCK_MANAGER_OBJECT_TYPE_DAEMON = 1,
 } virLockManagerObjectType;
 
 typedef enum {
diff --git a/src/locking/lock_driver_lockd.c b/src/locking/lock_driver_lockd.c
index ca825e6026..8ca0cf5426 100644
--- a/src/locking/lock_driver_lockd.c
+++ b/src/locking/lock_driver_lockd.c
@@ -56,10 +56,21 @@ struct _virLockManagerLockDaemonResource {
 };
 
 struct _virLockManagerLockDaemonPrivate {
-    unsigned char uuid[VIR_UUID_BUFLEN];
-    char *name;
-    int id;
-    pid_t pid;
+    virLockManagerObjectType type;
+    union {
+        struct {
+            unsigned char uuid[VIR_UUID_BUFLEN];
+            char *name;
+            int id;
+            pid_t pid;
+        } dom;
+
+        struct {
+            unsigned char uuid[VIR_UUID_BUFLEN];
+            char *name;
+            pid_t pid;
+        } daemon;
+    } t;
 
     size_t nresources;
     virLockManagerLockDaemonResourcePtr resources;
@@ -156,10 +167,24 @@ virLockManagerLockDaemonConnectionRegister(virLockManagerPtr lock,
     memset(&args, 0, sizeof(args));
 
     args.flags = 0;
-    memcpy(args.owner.uuid, priv->uuid, VIR_UUID_BUFLEN);
-    args.owner.name = priv->name;
-    args.owner.id = priv->id;
-    args.owner.pid = priv->pid;
+
+    switch (priv->type) {
+    case VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN:
+        memcpy(args.owner.uuid, priv->t.dom.uuid, VIR_UUID_BUFLEN);
+        args.owner.name = priv->t.dom.name;
+        args.owner.id = priv->t.dom.id;
+        args.owner.pid = priv->t.dom.pid;
+        break;
+
+    case VIR_LOCK_MANAGER_OBJECT_TYPE_DAEMON:
+        memcpy(args.owner.uuid, priv->t.daemon.uuid, VIR_UUID_BUFLEN);
+        args.owner.name = priv->t.daemon.name;
+        args.owner.pid = priv->t.daemon.pid;
+        break;
+
+    default:
+        return -1;
+    }
 
     if (virNetClientProgramCall(program,
                                 client,
@@ -391,7 +416,18 @@ virLockManagerLockDaemonPrivateFree(virLockManagerLockDaemonPrivatePtr priv)
     }
     VIR_FREE(priv->resources);
 
-    VIR_FREE(priv->name);
+    switch (priv->type) {
+    case VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN:
+        VIR_FREE(priv->t.dom.name);
+        break;
+
+    case VIR_LOCK_MANAGER_OBJECT_TYPE_DAEMON:
+        VIR_FREE(priv->t.daemon.name);
+        break;
+
+    default:
+        break;
+    }
     VIR_FREE(priv);
 }
 
@@ -420,46 +456,82 @@ static int virLockManagerLockDaemonNew(virLockManagerPtr lock,
     if (VIR_ALLOC(priv) < 0)
         return -1;
 
-    switch (type) {
+    priv->type = type;
+
+    switch ((virLockManagerObjectType) type) {
     case VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN:
         for (i = 0; i < nparams; i++) {
             if (STREQ(params[i].key, "uuid")) {
-                memcpy(priv->uuid, params[i].value.uuid, VIR_UUID_BUFLEN);
+                memcpy(priv->t.dom.uuid, params[i].value.uuid, VIR_UUID_BUFLEN);
             } else if (STREQ(params[i].key, "name")) {
-                if (VIR_STRDUP(priv->name, params[i].value.str) < 0)
+                if (VIR_STRDUP(priv->t.dom.name, params[i].value.str) < 0)
                     goto cleanup;
             } else if (STREQ(params[i].key, "id")) {
-                priv->id = params[i].value.iv;
+                priv->t.dom.id = params[i].value.iv;
             } else if (STREQ(params[i].key, "pid")) {
-                priv->pid = params[i].value.iv;
+                priv->t.dom.pid = params[i].value.iv;
             } else if (STREQ(params[i].key, "uri")) {
                 /* ignored */
             } else {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
-                               _("Unexpected parameter %s for object"),
+                               _("Unexpected parameter %s for domain object"),
                                params[i].key);
                 goto cleanup;
             }
         }
-        if (priv->id == 0) {
+        if (priv->t.dom.id == 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Missing ID parameter for domain object"));
             goto cleanup;
         }
-        if (priv->pid == 0)
+        if (priv->t.dom.pid == 0)
             VIR_DEBUG("Missing PID parameter for domain object");
-        if (!priv->name) {
+        if (!priv->t.dom.name) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Missing name parameter for domain object"));
             goto cleanup;
         }
-        if (!virUUIDIsValid(priv->uuid)) {
+        if (!virUUIDIsValid(priv->t.dom.uuid)) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Missing UUID parameter for domain object"));
             goto cleanup;
         }
         break;
 
+    case VIR_LOCK_MANAGER_OBJECT_TYPE_DAEMON:
+        for (i = 0; i < nparams; i++) {
+            if (STREQ(params[i].key, "uuid")) {
+                memcpy(priv->t.daemon.uuid, params[i].value.uuid, VIR_UUID_BUFLEN);
+            } else if (STREQ(params[i].key, "name")) {
+                if (VIR_STRDUP(priv->t.daemon.name, params[i].value.str) < 0)
+                    goto cleanup;
+            } else if (STREQ(params[i].key, "pid")) {
+                priv->t.daemon.pid = params[i].value.iv;
+            } else {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("Unexpected parameter %s for daemon object"),
+                               params[i].key);
+                goto cleanup;
+            }
+        }
+
+        if (!virUUIDIsValid(priv->t.daemon.uuid)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Missing UUID parameter for daemon object"));
+            goto cleanup;
+        }
+        if (!priv->t.daemon.name) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Missing name parameter for daemon object"));
+            goto cleanup;
+        }
+        if (priv->t.daemon.pid == 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Missing PID parameter for daemon object"));
+            goto cleanup;
+        }
+        break;
+
     default:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Unknown lock manager object type %d"),
diff --git a/src/locking/lock_driver_sanlock.c b/src/locking/lock_driver_sanlock.c
index 39c2f94a76..fe422d3be6 100644
--- a/src/locking/lock_driver_sanlock.c
+++ b/src/locking/lock_driver_sanlock.c
@@ -513,21 +513,32 @@ static int virLockManagerSanlockNew(virLockManagerPtr lock,
 
     priv->flags = flags;
 
-    for (i = 0; i < nparams; i++) {
-        param = &params[i];
+    switch ((virLockManagerObjectType) type) {
+    case VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN:
+        for (i = 0; i < nparams; i++) {
+            param = &params[i];
 
-        if (STREQ(param->key, "uuid")) {
-            memcpy(priv->vm_uuid, param->value.uuid, 16);
-        } else if (STREQ(param->key, "name")) {
-            if (VIR_STRDUP(priv->vm_name, param->value.str) < 0)
-                goto error;
-        } else if (STREQ(param->key, "pid")) {
-            priv->vm_pid = param->value.iv;
-        } else if (STREQ(param->key, "id")) {
-            priv->vm_id = param->value.ui;
-        } else if (STREQ(param->key, "uri")) {
-            priv->vm_uri = param->value.cstr;
+            if (STREQ(param->key, "uuid")) {
+                memcpy(priv->vm_uuid, param->value.uuid, 16);
+            } else if (STREQ(param->key, "name")) {
+                if (VIR_STRDUP(priv->vm_name, param->value.str) < 0)
+                    goto error;
+            } else if (STREQ(param->key, "pid")) {
+                priv->vm_pid = param->value.iv;
+            } else if (STREQ(param->key, "id")) {
+                priv->vm_id = param->value.ui;
+            } else if (STREQ(param->key, "uri")) {
+                priv->vm_uri = param->value.cstr;
+            }
         }
+        break;
+
+    case VIR_LOCK_MANAGER_OBJECT_TYPE_DAEMON:
+    default:
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Unknown lock manager object type %d"),
+                       type);
+        goto error;
     }
 
     /* Sanlock needs process registration, but the only way how to probe
-- 
2.16.4




More information about the libvir-list mailing list