]> xenbits.xensource.com Git - libvirt.git/commitdiff
Check for source conflicts in storage pools
authorLei Li <lilei@linux.vnet.ibm.com>
Mon, 5 Sep 2011 07:52:03 +0000 (15:52 +0800)
committerDaniel Veillard <veillard@redhat.com>
Mon, 5 Sep 2011 07:52:03 +0000 (15:52 +0800)
Fix bug #611823 storage driver should prohibit pools with duplicate
underlying storage.

Add internal API virStoragePoolSourceFindDuplicate() to do uniqueness
check based on source location infomation for pool type.

* AUTHORS: add Lei Li

AUTHORS
src/conf/storage_conf.c
src/conf/storage_conf.h
src/libvirt_private.syms
src/storage/storage_driver.c

diff --git a/AUTHORS b/AUTHORS
index faec2182f9e71e76a9fcdb97557d7201104c6986..dcbb711e2f4570ed0aea00ab7d346dd3bfad77ed 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -193,6 +193,7 @@ Patches have also been contributed by:
   Shradha Shah         <sshah@solarflare.com>
   Steve Hodgson        <shodgson@solarflare.com>
   Xu He Jie            <xuhj@linux.vnet.ibm.com>
+  Lei Li               <lilei@linux.vnet.ibm.com>
 
   [....send patches to get your name here....]
 
index 8d14e872ca44ac40e6b1c9c411a149953dc44eff..1e7da69345379737fe8a0fbe6998461d1ffcc003 100644 (file)
@@ -1311,6 +1311,21 @@ virStoragePoolObjFindByName(virStoragePoolObjListPtr pools,
     return NULL;
 }
 
+virStoragePoolObjPtr
+virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool,
+                                         virStoragePoolDefPtr def) {
+    unsigned int i, j;
+
+    for (i = 0; i < pool->def->source.ndevice; i++) {
+        for (j = 0; j < def->source.ndevice; j++) {
+            if (STREQ(pool->def->source.devices[i].path, def->source.devices[j].path))
+                return pool;
+        }
+    }
+
+    return NULL;
+}
+
 void
 virStoragePoolObjClearVols(virStoragePoolObjPtr pool)
 {
@@ -1701,6 +1716,71 @@ cleanup:
     return ret;
 }
 
+int virStoragePoolSourceFindDuplicate(virStoragePoolObjListPtr pools,
+                                      virStoragePoolDefPtr def)
+{
+    int i;
+    int ret = 1;
+    virStoragePoolObjPtr pool = NULL;
+    virStoragePoolObjPtr matchpool = NULL;
+
+    /* Check the pool list for duplicate underlying storage */
+    for (i = 0; i < pools->count; i++) {
+        pool = pools->objs[i];
+        if (def->type != pool->def->type)
+            continue;
+
+        virStoragePoolObjLock(pool);
+
+        switch (pool->def->type) {
+        case VIR_STORAGE_POOL_DIR:
+            if (STREQ(pool->def->target.path, def->target.path))
+                matchpool = pool;
+            break;
+        case VIR_STORAGE_POOL_NETFS:
+            if ((STREQ(pool->def->source.dir, def->source.dir)) \
+                && (STREQ(pool->def->source.host.name, def->source.host.name)))
+                matchpool = pool;
+            break;
+        case VIR_STORAGE_POOL_SCSI:
+            if (STREQ(pool->def->source.adapter, def->source.adapter))
+                matchpool = pool;
+            break;
+        case VIR_STORAGE_POOL_ISCSI:
+        {
+            matchpool = virStoragePoolSourceFindDuplicateDevices(pool, def);
+            if (matchpool) {
+                if (STREQ(matchpool->def->source.host.name, def->source.host.name)) {
+                    if ((matchpool->def->source.initiator.iqn) && (def->source.initiator.iqn)) {
+                        if (STREQ(matchpool->def->source.initiator.iqn, def->source.initiator.iqn))
+                            break;
+                        matchpool = NULL;
+                    }
+                    break;
+                }
+                matchpool = NULL;
+            }
+            break;
+        }
+        case VIR_STORAGE_POOL_FS:
+        case VIR_STORAGE_POOL_LOGICAL:
+        case VIR_STORAGE_POOL_DISK:
+            matchpool = virStoragePoolSourceFindDuplicateDevices(pool, def);
+            break;
+        default:
+            break;
+        }
+        virStoragePoolObjUnlock(pool);
+    }
+
+    if (matchpool) {
+        virStorageReportError(VIR_ERR_OPERATION_FAILED,
+                              _("Storage source conflict with pool: '%s'"),
+                              matchpool->def->name);
+        ret = -1;
+    }
+    return ret;
+}
 
 void virStoragePoolObjLock(virStoragePoolObjPtr obj)
 {
index 271441a9559ace9e16f583ceb65128ca46a04108..d115a152053635c750faee72a439cfdf9673db7b 100644 (file)
@@ -335,6 +335,8 @@ virStoragePoolObjPtr virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools,
                                                  const unsigned char *uuid);
 virStoragePoolObjPtr virStoragePoolObjFindByName(virStoragePoolObjListPtr pools,
                                                  const char *name);
+virStoragePoolObjPtr virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool,
+                                                              virStoragePoolDefPtr def);
 
 virStorageVolDefPtr virStorageVolDefFindByKey(virStoragePoolObjPtr pool,
                                               const char *key);
@@ -388,6 +390,9 @@ int virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools,
                                  virStoragePoolDefPtr def,
                                  unsigned int check_active);
 
+int virStoragePoolSourceFindDuplicate(virStoragePoolObjListPtr pools,
+                                      virStoragePoolDefPtr def);
+
 void virStoragePoolObjLock(virStoragePoolObjPtr obj);
 void virStoragePoolObjUnlock(virStoragePoolObjPtr obj);
 
index 52fc06d7c02ae3a31f1ce02b5b1fdf9a7a9aaa13..011f7522d0f2c378a30b7c28f0e58546265de93c 100644 (file)
@@ -956,7 +956,9 @@ virStoragePoolObjClearVols;
 virStoragePoolObjDeleteDef;
 virStoragePoolObjFindByName;
 virStoragePoolObjFindByUUID;
+virStoragePoolSourceFindDuplicateDevices;
 virStoragePoolObjIsDuplicate;
+virStoragePoolSourceFindDuplicate;
 virStoragePoolObjListFree;
 virStoragePoolObjLock;
 virStoragePoolObjRemove;
index 68cac1fc474b03fcf49ee140be3eab4c4dcdec46..c05b74ebf6569ca5c6d0bfed6c967e3c4ab4c753 100644 (file)
@@ -536,6 +536,9 @@ storagePoolCreate(virConnectPtr conn,
     if (virStoragePoolObjIsDuplicate(&driver->pools, def, 1) < 0)
         goto cleanup;
 
+    if (virStoragePoolSourceFindDuplicate(&driver->pools, def) < 0)
+        goto cleanup;
+
     if ((backend = virStorageBackendForType(def->type)) == NULL)
         goto cleanup;
 
@@ -589,6 +592,9 @@ storagePoolDefine(virConnectPtr conn,
     if (virStoragePoolObjIsDuplicate(&driver->pools, def, 0) < 0)
         goto cleanup;
 
+    if (virStoragePoolSourceFindDuplicate(&driver->pools, def) < 0)
+        goto cleanup;
+
     if (virStorageBackendForType(def->type) == NULL)
         goto cleanup;