Fix bug #611823 storage driver should prohibit pools with duplicate underlying storage. Add API virStoragePoolSourceFindDuplicate() to do uniqueness check based on source location infomation for pool type. Signed-off-by: Lei Li <lilei@xxxxxxxxxxxxxxxxxx> --- src/conf/storage_conf.c | 80 ++++++++++++++++++++++++++++++++++++++++++ src/conf/storage_conf.h | 5 +++ src/libvirt_private.syms | 2 + src/storage/storage_driver.c | 6 +++ 4 files changed, 93 insertions(+), 0 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 8d14e87..1e7da69 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -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) { diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 271441a..d115a15 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -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); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 9f03e30..316eb7e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -947,7 +947,9 @@ virStoragePoolObjClearVols; virStoragePoolObjDeleteDef; virStoragePoolObjFindByName; virStoragePoolObjFindByUUID; +virStoragePoolSourceFindDuplicateDevices; virStoragePoolObjIsDuplicate; +virStoragePoolSourceFindDuplicate; virStoragePoolObjListFree; virStoragePoolObjLock; virStoragePoolObjRemove; diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 68cac1f..c05b74e 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -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; -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list