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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list