[libvirt] [PATCH 1/3] Storage pool duplicate UUID/name checking

Daniel P. Berrange berrange at redhat.com
Thu May 27 16:00:10 UTC 2010


The storage pool driver is not doing correct checking for
duplicate UUID/name values. This introduces a new method
virStoragePoolObjIsDuplicate, based on the previously
written virDomainObjIsDuplicate.

* src/conf/storage_conf.c, src/conf/storage_conf.c,
  src/libvirt_private.syms: Add virStoragePoolObjIsDuplicate,
* src/storage/storage_driver.c: Call virStoragePoolObjIsDuplicate
  for checking uniqueness of uuid/names
---
 src/conf/storage_conf.c      |   63 ++++++++++++++++++++++++++++++++++++++++++
 src/conf/storage_conf.h      |    4 ++
 src/libvirt_private.syms     |    1 +
 src/storage/storage_driver.c |   14 ++------
 4 files changed, 72 insertions(+), 10 deletions(-)

diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 422e76a..9ae1a89 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -1628,6 +1628,69 @@ char *virStoragePoolSourceListFormat(virStoragePoolSourceListPtr def)
 }
 
 
+/*
+ * virStoragePoolObjIsDuplicate:
+ * @doms : virStoragePoolObjListPtr to search
+ * @def  : virStoragePoolDefPtr definition of pool to lookup
+ * @check_active: If true, ensure that pool is not active
+ *
+ * Returns: -1 on error
+ *          0 if pool is new
+ *          1 if pool is a duplicate
+ */
+int virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools,
+                                 virStoragePoolDefPtr def,
+                                 unsigned int check_active)
+{
+    int ret = -1;
+    int dupPool = 0;
+    virStoragePoolObjPtr pool = NULL;
+
+    /* See if a Pool with matching UUID already exists */
+    pool = virStoragePoolObjFindByUUID(pools, def->uuid);
+    if (pool) {
+        /* UUID matches, but if names don't match, refuse it */
+        if (STRNEQ(pool->def->name, def->name)) {
+            char uuidstr[VIR_UUID_STRING_BUFLEN];
+            virUUIDFormat(pool->def->uuid, uuidstr);
+            virStorageReportError(VIR_ERR_OPERATION_FAILED,
+                                  _("pool '%s' is already defined with uuid %s"),
+                                  pool->def->name, uuidstr);
+            goto cleanup;
+        }
+
+        if (check_active) {
+            /* UUID & name match, but if Pool is already active, refuse it */
+            if (virStoragePoolObjIsActive(pool)) {
+                virStorageReportError(VIR_ERR_OPERATION_INVALID,
+                                      _("pool is already active as '%s'"),
+                                      pool->def->name);
+                goto cleanup;
+            }
+        }
+
+        dupPool = 1;
+    } else {
+        /* UUID does not match, but if a name matches, refuse it */
+        pool = virStoragePoolObjFindByName(pools, def->name);
+        if (pool) {
+            char uuidstr[VIR_UUID_STRING_BUFLEN];
+            virUUIDFormat(pool->def->uuid, uuidstr);
+            virStorageReportError(VIR_ERR_OPERATION_FAILED,
+                                  _("pool '%s' already exists with uuid %s"),
+                                  def->name, uuidstr);
+            goto cleanup;
+        }
+    }
+
+    ret = dupPool;
+cleanup:
+    if (pool)
+        virStoragePoolObjUnlock(pool);
+    return ret;
+}
+
+
 void virStoragePoolObjLock(virStoragePoolObjPtr obj)
 {
     virMutexLock(&obj->lock);
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index 5813489..bedee9e 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -379,6 +379,10 @@ virStoragePoolSourcePtr
 virStoragePoolSourceListNewSource(virStoragePoolSourceListPtr list);
 char *virStoragePoolSourceListFormat(virStoragePoolSourceListPtr def);
 
+int virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools,
+                                 virStoragePoolDefPtr def,
+                                 unsigned int check_active);
+
 void virStoragePoolObjLock(virStoragePoolObjPtr obj);
 void virStoragePoolObjUnlock(virStoragePoolObjPtr obj);
 
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6cb3d66..e7cd6dd 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -610,6 +610,7 @@ virStoragePoolTypeFromString;
 virStoragePartedFsTypeTypeToString;
 virStoragePoolObjLock;
 virStoragePoolObjUnlock;
+virStoragePoolObjIsDuplicate;
 
 # storage_encryption_conf.h
 virStorageEncryptionFree;
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 0870f74..e53317a 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -521,17 +521,8 @@ storagePoolCreate(virConnectPtr conn,
     if (!(def = virStoragePoolDefParseString(xml)))
         goto cleanup;
 
-    pool = virStoragePoolObjFindByUUID(&driver->pools, def->uuid);
-    if (!pool)
-        pool = virStoragePoolObjFindByName(&driver->pools, def->name);
-
-    if (pool) {
-        virStorageReportError(VIR_ERR_INTERNAL_ERROR,
-                              "%s", _("storage pool already exists"));
-        virStoragePoolObjUnlock(pool);
-        pool = NULL;
+    if (virStoragePoolObjIsDuplicate(&driver->pools, def, 1) < 0)
         goto cleanup;
-    }
 
     if ((backend = virStorageBackendForType(def->type)) == NULL)
         goto cleanup;
@@ -579,6 +570,9 @@ storagePoolDefine(virConnectPtr conn,
     if (!(def = virStoragePoolDefParseString(xml)))
         goto cleanup;
 
+    if (virStoragePoolObjIsDuplicate(&driver->pools, def, 0) < 0)
+        goto cleanup;
+
     if (virStorageBackendForType(def->type) == NULL)
         goto cleanup;
 
-- 
1.6.6.1




More information about the libvir-list mailing list