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 | 73 ++++++++++++++++++++++++++++++++++++++++++ src/conf/storage_conf.h | 3 ++ src/libvirt_private.syms | 1 + src/storage/storage_driver.c | 6 +++ 4 files changed, 83 insertions(+), 0 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 8d14e87..698334e 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -1701,6 +1701,79 @@ cleanup: return ret; } +int virStoragePoolSourceFindDuplicate(virStoragePoolObjListPtr pools, + virStoragePoolDefPtr def) +{ + int i, j, k; + 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); + if (pool->def->type == VIR_STORAGE_POOL_DIR) { + if (STREQ(pool->def->target.path, def->target.path)) { + matchpool = pool; + goto cleanup; + } + } else if (pool->def->type == 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; + goto cleanup; + } + } else if (pool->def->type == VIR_STORAGE_POOL_SCSI) { + if (STREQ(pool->def->source.adapter, def->source.adapter)) { + matchpool = pool; + goto cleanup; + } + } else if (pool->def->type == VIR_STORAGE_POOL_ISCSI) { + for (j = 0; j < pool->def->source.ndevice; j++) { + for (k = 0; k < def->source.ndevice; k++) { + if (pool->def->source.initiator.iqn) { + if ((STREQ(pool->def->source.devices[j].path, def->source.devices[k].path)) \ + && (STREQ(pool->def->source.initiator.iqn, def->source.initiator.iqn))) { + matchpool = pool; + goto cleanup; + } + } else if (pool->def->source.host.name) { + if ((STREQ(pool->def->source.devices[j].path, def->source.devices[k].path)) \ + && (STREQ(pool->def->source.host.name, def->source.host.name))) { + matchpool = pool; + goto cleanup; + } + } + } + } + } else { + /* For the remain three pool type 'fs''logical''disk' that all use device path */ + if (pool->def->source.ndevice) { + for (j = 0; j < pool->def->source.ndevice; j++) { + for (k = 0; k < def->source.ndevice; k++) { + if (STREQ(pool->def->source.devices[j].path, def->source.devices[k].path)) { + matchpool = pool; + goto cleanup; + } + } + } + } + } + virStoragePoolObjUnlock(pool); + } +cleanup: + if (matchpool) { + virStoragePoolObjUnlock(matchpool); + virStorageReportError(VIR_ERR_OPERATION_FAILED, + _("pool source location info is duplicate")); + ret = -1; + } + return ret; +} void virStoragePoolObjLock(virStoragePoolObjPtr obj) { diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 271441a..a8562a6 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -388,6 +388,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..5899d56 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -948,6 +948,7 @@ virStoragePoolObjDeleteDef; virStoragePoolObjFindByName; virStoragePoolObjFindByUUID; 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