Check for source conflicts in storage pools

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
This commit is contained in:
Lei Li 2011-09-05 15:52:03 +08:00 committed by Daniel Veillard
parent ddc9036281
commit 5a1f272875
5 changed files with 94 additions and 0 deletions

View File

@ -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....]

View 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)
{

View 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);

View File

@ -956,7 +956,9 @@ virStoragePoolObjClearVols;
virStoragePoolObjDeleteDef;
virStoragePoolObjFindByName;
virStoragePoolObjFindByUUID;
virStoragePoolSourceFindDuplicateDevices;
virStoragePoolObjIsDuplicate;
virStoragePoolSourceFindDuplicate;
virStoragePoolObjListFree;
virStoragePoolObjLock;
virStoragePoolObjRemove;

View 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;