]> xenbits.xensource.com Git - libvirt.git/commitdiff
secret: Introduce virSecretObjListAdd* and virSecretObjListRemove
authorJohn Ferlan <jferlan@redhat.com>
Tue, 19 Apr 2016 20:05:38 +0000 (16:05 -0400)
committerJohn Ferlan <jferlan@redhat.com>
Mon, 25 Apr 2016 19:45:29 +0000 (15:45 -0400)
Add the functions to add/remove elements from the hashed secret obj list.
These will replace secret_driver functions secretAssignDef and secretObjRemove.

The virSecretObjListAddLocked will perform the necessary lookups and
decide whether to replace an existing hash entry or create a new one.
This includes setting up the configPath and base64Path as well as being
able to support the caller's need to restore from a previous definition
in case something goes wrong in the caller.

po/POTFILES.in
src/conf/virsecretobj.c
src/conf/virsecretobj.h

index 2f530796e608e2b0592302c24cd3196c3e2279c4..506d5352e15fc72cfb3470044e17937c9c679221 100644 (file)
@@ -39,6 +39,7 @@ src/conf/snapshot_conf.c
 src/conf/storage_conf.c
 src/conf/virchrdev.c
 src/conf/virdomainobjlist.c
+src/conf/virsecretobj.c
 src/cpu/cpu.c
 src/cpu/cpu_generic.c
 src/cpu/cpu_map.c
index 1fd9f57f8da07d1a882ca1ccc46f0b22a8c1ef25..b808902f296e9d9e1d9fd980b4d77291514cd8cd 100644 (file)
 #include "datatypes.h"
 #include "virsecretobj.h"
 #include "viralloc.h"
+#include "virerror.h"
+#include "virfile.h"
 #include "virhash.h"
+#include "virlog.h"
 
+#define VIR_FROM_THIS VIR_FROM_SECRET
+
+VIR_LOG_INIT("conf.virsecretobj");
 
 static virClassPtr virSecretObjClass;
 static virClassPtr virSecretObjListClass;
@@ -276,3 +282,151 @@ virSecretObjListFindByUsage(virSecretObjListPtr secrets,
         virObjectLock(ret);
     return ret;
 }
+
+
+/*
+ * virSecretObjListRemove:
+ * @secrets: list of secret objects
+ * @secret: a secret object
+ *
+ * Remove the object from the hash table.  The caller must hold the lock
+ * on the driver owning @secrets and must have also locked @secret to
+ * ensure no one else is either waiting for @secret or still using it.
+ */
+void
+virSecretObjListRemove(virSecretObjListPtr secrets,
+                       virSecretObjPtr secret)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+    virUUIDFormat(secret->def->uuid, uuidstr);
+    virObjectRef(secret);
+    virObjectUnlock(secret);
+
+    virObjectLock(secrets);
+    virObjectLock(secret);
+    virHashRemoveEntry(secrets->objs, uuidstr);
+    virObjectUnlock(secret);
+    virObjectUnref(secret);
+    virObjectUnlock(secrets);
+}
+
+
+/*
+ * virSecretObjListAddLocked:
+ * @secrets: list of secret objects
+ * @def: new secret definition
+ * @configDir: directory to place secret config files
+ * @oldDef: Former secret def (e.g. a reload path perhaps)
+ *
+ * Add the new def to the secret obj table hash
+ *
+ * This functions requires @secrets to be locked already!
+ *
+ * Returns pointer to secret or NULL if failure to add
+ */
+virSecretObjPtr
+virSecretObjListAddLocked(virSecretObjListPtr secrets,
+                          virSecretDefPtr def,
+                          const char *configDir,
+                          virSecretDefPtr *oldDef)
+{
+    virSecretObjPtr secret;
+    virSecretObjPtr ret = NULL;
+    const char *newUsageID = virSecretUsageIDForDef(def);
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+    char *configFile = NULL, *base64File = NULL;
+
+    if (oldDef)
+        *oldDef = NULL;
+
+    /* Is there a secret already matching this UUID */
+    if ((secret = virSecretObjListFindByUUIDLocked(secrets, def->uuid))) {
+        const char *oldUsageID;
+
+        virObjectLock(secret);
+
+        oldUsageID = virSecretUsageIDForDef(secret->def);
+        if (STRNEQ(oldUsageID, newUsageID)) {
+            virUUIDFormat(secret->def->uuid, uuidstr);
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("a secret with UUID %s is already defined for "
+                             "use with %s"),
+                           uuidstr, oldUsageID);
+            goto cleanup;
+        }
+
+        if (secret->def->private && !def->private) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("cannot change private flag on existing secret"));
+            goto cleanup;
+        }
+
+        if (oldDef)
+            *oldDef = secret->def;
+        else
+            virSecretDefFree(secret->def);
+        secret->def = def;
+    } else {
+        /* No existing secret with same UUID,
+         * try look for matching usage instead */
+        if ((secret = virSecretObjListFindByUsageLocked(secrets,
+                                                        def->usage_type,
+                                                        newUsageID))) {
+            virObjectLock(secret);
+            virUUIDFormat(secret->def->uuid, uuidstr);
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("a secret with UUID %s already defined for "
+                             "use with %s"),
+                           uuidstr, newUsageID);
+            goto cleanup;
+        }
+
+        /* Generate the possible configFile and base64File strings
+         * using the configDir, uuidstr, and appropriate suffix
+         */
+        virUUIDFormat(def->uuid, uuidstr);
+        if (!(configFile = virFileBuildPath(configDir, uuidstr, ".xml")) ||
+            !(base64File = virFileBuildPath(configDir, uuidstr, ".base64")))
+            goto cleanup;
+
+        if (!(secret = virSecretObjNew()))
+            goto cleanup;
+
+        virObjectLock(secret);
+
+        if (virHashAddEntry(secrets->objs, uuidstr, secret) < 0)
+            goto cleanup;
+
+        secret->def = def;
+        secret->configFile = configFile;
+        secret->base64File = base64File;
+        configFile = NULL;
+        base64File = NULL;
+        virObjectRef(secret);
+    }
+
+    ret = secret;
+    secret = NULL;
+
+ cleanup:
+    virSecretObjEndAPI(&secret);
+    VIR_FREE(configFile);
+    VIR_FREE(base64File);
+    return ret;
+}
+
+
+virSecretObjPtr
+virSecretObjListAdd(virSecretObjListPtr secrets,
+                    virSecretDefPtr def,
+                    const char *configDir,
+                    virSecretDefPtr *oldDef)
+{
+    virSecretObjPtr ret;
+
+    virObjectLock(secrets);
+    ret = virSecretObjListAddLocked(secrets, def, configDir, oldDef);
+    virObjectUnlock(secrets);
+    return ret;
+}
index 0effcd65a346f4f4b079ebdb19c77e5f3d589b78..290e91b84a4ad29442eead54e5eebaa159fca993 100644 (file)
@@ -60,4 +60,17 @@ virSecretObjPtr virSecretObjListFindByUsage(virSecretObjListPtr secrets,
                                             int usageType,
                                             const char *usageID);
 
+void virSecretObjListRemove(virSecretObjListPtr secrets,
+                            virSecretObjPtr secret);
+
+virSecretObjPtr virSecretObjListAddLocked(virSecretObjListPtr secrets,
+                                          virSecretDefPtr def,
+                                          const char *configDir,
+                                          virSecretDefPtr *oldDef);
+
+virSecretObjPtr virSecretObjListAdd(virSecretObjListPtr secrets,
+                                    virSecretDefPtr def,
+                                    const char *configDir,
+                                    virSecretDefPtr *oldDef);
+
 #endif /* __VIRSECRETOBJ_H__ */