Check for source conflicts in storage pools

Fix bug  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;