storage: Convert virStoragePoolObjList to use virObjectRWLockable

Now that we have a private storage pool list, we can take the next
step and convert to using objects. In this case, we're going to use
RWLockable objects (just like every other driver) with two hash
tables for lookup by UUID or Name.

Along the way the ForEach and Search API's will be adjusted to use
the related Hash API's and the various FindBy functions altered and
augmented to allow for HashLookup w/ and w/o the pool lock already
taken.

After virStoragePoolObjRemove we will need to virObjectUnref(obj)
after to indicate the caller is "done" with it's reference. The
Unlock occurs during the Remove.

The NumOf, GetNames, and Export functions all have their own callback
functions to return the required data and the FindDuplicate code
can use the HashSearch function callbacks.
This commit is contained in:
John Ferlan 2017-10-09 13:34:45 -04:00
parent 90e65353a2
commit 4b2e0ed6e3
5 changed files with 449 additions and 212 deletions

View File

@ -27,6 +27,7 @@
#include "viralloc.h" #include "viralloc.h"
#include "virerror.h" #include "virerror.h"
#include "virfile.h" #include "virfile.h"
#include "virhash.h"
#include "virlog.h" #include "virlog.h"
#include "virscsihost.h" #include "virscsihost.h"
#include "virstring.h" #include "virstring.h"
@ -37,9 +38,12 @@
VIR_LOG_INIT("conf.virstorageobj"); VIR_LOG_INIT("conf.virstorageobj");
static virClassPtr virStoragePoolObjClass; static virClassPtr virStoragePoolObjClass;
static virClassPtr virStoragePoolObjListClass;
static void static void
virStoragePoolObjDispose(void *opaque); virStoragePoolObjDispose(void *opaque);
static void
virStoragePoolObjListDispose(void *opaque);
struct _virStorageVolDefList { struct _virStorageVolDefList {
@ -63,8 +67,15 @@ struct _virStoragePoolObj {
}; };
struct _virStoragePoolObjList { struct _virStoragePoolObjList {
size_t count; virObjectRWLockable parent;
virStoragePoolObjPtr *objs;
/* uuid string -> virStoragePoolObj mapping
* for (1), lockless lookup-by-uuid */
virHashTable *objs;
/* name string -> virStoragePoolObj mapping
* for (1), lockless lookup-by-name */
virHashTable *objsName;
}; };
@ -77,6 +88,12 @@ virStoragePoolObjOnceInit(void)
virStoragePoolObjDispose))) virStoragePoolObjDispose)))
return -1; return -1;
if (!(virStoragePoolObjListClass = virClassNew(virClassForObjectRWLockable(),
"virStoragePoolObjList",
sizeof(virStoragePoolObjList),
virStoragePoolObjListDispose)))
return -1;
return 0; return 0;
} }
@ -240,13 +257,12 @@ virStoragePoolObjDispose(void *opaque)
void void
virStoragePoolObjListFree(virStoragePoolObjListPtr pools) virStoragePoolObjListDispose(void *opaque)
{ {
size_t i; virStoragePoolObjListPtr pools = opaque;
for (i = 0; i < pools->count; i++)
virObjectUnref(pools->objs[i]); virHashFree(pools->objs);
VIR_FREE(pools->objs); virHashFree(pools->objsName);
VIR_FREE(pools);
} }
@ -255,13 +271,43 @@ virStoragePoolObjListNew(void)
{ {
virStoragePoolObjListPtr pools; virStoragePoolObjListPtr pools;
if (VIR_ALLOC(pools) < 0) if (virStoragePoolObjInitialize() < 0)
return NULL; return NULL;
if (!(pools = virObjectRWLockableNew(virStoragePoolObjListClass)))
return NULL;
if (!(pools->objs = virHashCreate(20, virObjectFreeHashData)) ||
!(pools->objsName = virHashCreate(20, virObjectFreeHashData))) {
virObjectUnref(pools);
return NULL;
}
return pools; return pools;
} }
struct _virStoragePoolObjListForEachData {
virStoragePoolObjListIterator iter;
const void *opaque;
};
static int
virStoragePoolObjListForEachCb(void *payload,
const void *name ATTRIBUTE_UNUSED,
void *opaque)
{
virStoragePoolObjPtr obj = payload;
struct _virStoragePoolObjListForEachData *data = opaque;
virObjectLock(obj);
data->iter(obj, data->opaque);
virObjectUnlock(obj);
return 0;
}
/** /**
* virStoragePoolObjListForEach * virStoragePoolObjListForEach
* @pools: Pointer to pools object * @pools: Pointer to pools object
@ -279,15 +325,35 @@ virStoragePoolObjListForEach(virStoragePoolObjListPtr pools,
virStoragePoolObjListIterator iter, virStoragePoolObjListIterator iter,
const void *opaque) const void *opaque)
{ {
size_t i; struct _virStoragePoolObjListForEachData data = { .iter = iter,
virStoragePoolObjPtr obj; .opaque = opaque };
for (i = 0; i < pools->count; i++) { virObjectRWLockRead(pools);
obj = pools->objs[i]; virHashForEach(pools->objs, virStoragePoolObjListForEachCb, &data);
virObjectLock(obj); virObjectRWUnlock(pools);
iter(obj, opaque);
virObjectUnlock(obj);
} }
struct _virStoragePoolObjListSearchData {
virStoragePoolObjListSearcher searcher;
const void *opaque;
};
static int
virStoragePoolObjListSearchCb(const void *payload,
const void *name ATTRIBUTE_UNUSED,
const void *opaque)
{
virStoragePoolObjPtr obj = (virStoragePoolObjPtr) payload;
struct _virStoragePoolObjListSearchData *data =
(struct _virStoragePoolObjListSearchData *)opaque;
virObjectLock(obj);
if (data->searcher(obj, data->opaque))
return 1;
virObjectUnlock(obj);
return 0;
} }
@ -308,18 +374,15 @@ virStoragePoolObjListSearch(virStoragePoolObjListPtr pools,
virStoragePoolObjListSearcher searcher, virStoragePoolObjListSearcher searcher,
const void *opaque) const void *opaque)
{ {
size_t i; virStoragePoolObjPtr obj = NULL;
virStoragePoolObjPtr obj; struct _virStoragePoolObjListSearchData data = { .searcher = searcher,
.opaque = opaque };
virObjectRWLockRead(pools);
obj = virHashSearch(pools->objs, virStoragePoolObjListSearchCb, &data, NULL);
virObjectRWUnlock(pools);
for (i = 0; i < pools->count; i++) {
obj = pools->objs[i];
virObjectLock(obj);
if (searcher(obj, opaque))
return virObjectRef(obj); return virObjectRef(obj);
virObjectUnlock(obj);
}
return NULL;
} }
@ -327,59 +390,88 @@ void
virStoragePoolObjRemove(virStoragePoolObjListPtr pools, virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
virStoragePoolObjPtr obj) virStoragePoolObjPtr obj)
{ {
size_t i; char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(obj->def->uuid, uuidstr);
virObjectRef(obj);
virObjectUnlock(obj); virObjectUnlock(obj);
virObjectRWLockWrite(pools);
for (i = 0; i < pools->count; i++) { virObjectLock(obj);
virObjectLock(pools->objs[i]); virHashRemoveEntry(pools->objs, uuidstr);
if (pools->objs[i] == obj) { virHashRemoveEntry(pools->objsName, obj->def->name);
virObjectUnlock(pools->objs[i]); virObjectUnlock(obj);
virObjectUnref(pools->objs[i]); virObjectUnref(obj);
virObjectRWUnlock(pools);
VIR_DELETE_ELEMENT(pools->objs, i, pools->count);
break;
}
virObjectUnlock(pools->objs[i]);
}
} }
static virStoragePoolObjPtr
virStoragePoolObjFindByUUIDLocked(virStoragePoolObjListPtr pools,
const unsigned char *uuid)
{
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(uuid, uuidstr);
return virObjectRef(virHashLookup(pools->objs, uuidstr));
}
/**
* virStoragePoolObjFindByUUID
* @pools: Storage pool object list pointer
* @uuid: Storage object uuid to find
*
* Lock the @pools and lookup the object by @uuid
*
* Returns: Locked and reffed storage pool object or NULL if not found
*/
virStoragePoolObjPtr virStoragePoolObjPtr
virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools, virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools,
const unsigned char *uuid) const unsigned char *uuid)
{ {
size_t i; virStoragePoolObjPtr obj;
for (i = 0; i < pools->count; i++) {
virStoragePoolObjPtr obj = pools->objs[i];
virObjectRWLockRead(pools);
obj = virStoragePoolObjFindByUUIDLocked(pools, uuid);
virObjectRWUnlock(pools);
if (obj)
virObjectLock(obj); virObjectLock(obj);
if (!memcmp(obj->def->uuid, uuid, VIR_UUID_BUFLEN))
return virObjectRef(obj);
virObjectUnlock(obj);
}
return NULL; return obj;
} }
static virStoragePoolObjPtr
virStoragePoolObjFindByNameLocked(virStoragePoolObjListPtr pools,
const char *name)
{
return virObjectRef(virHashLookup(pools->objsName, name));
}
/**
* virStoragePoolObjFindByName
* @pools: Storage pool object list pointer
* @name: Storage object name to find
*
* Lock the @pools and lookup the object by @name
*
* Returns: Locked and reffed storage pool object or NULL if not found
*/
virStoragePoolObjPtr virStoragePoolObjPtr
virStoragePoolObjFindByName(virStoragePoolObjListPtr pools, virStoragePoolObjFindByName(virStoragePoolObjListPtr pools,
const char *name) const char *name)
{ {
size_t i; virStoragePoolObjPtr obj;
for (i = 0; i < pools->count; i++) {
virStoragePoolObjPtr obj = pools->objs[i];
virObjectRWLockRead(pools);
obj = virStoragePoolObjFindByNameLocked(pools, name);
virObjectRWUnlock(pools);
if (obj)
virObjectLock(obj); virObjectLock(obj);
if (STREQ(obj->def->name, name))
return virObjectRef(obj);
virObjectUnlock(obj);
}
return NULL; return obj;
} }
@ -623,13 +715,27 @@ virStoragePoolObjVolumeListExport(virConnectPtr conn,
} }
/**
* virStoragePoolObjAssignDef:
* @pools: Storage Pool object list pointer
* @def: Storage pool definition to add or update
*
* Lookup the @def to see if it already exists in the @pools in order
* to either update or add if it does not exist.
*
* Returns locked and reffed object pointer or NULL on error
*/
virStoragePoolObjPtr virStoragePoolObjPtr
virStoragePoolObjAssignDef(virStoragePoolObjListPtr pools, virStoragePoolObjAssignDef(virStoragePoolObjListPtr pools,
virStoragePoolDefPtr def) virStoragePoolDefPtr def)
{ {
virStoragePoolObjPtr obj; virStoragePoolObjPtr obj;
char uuidstr[VIR_UUID_STRING_BUFLEN];
if ((obj = virStoragePoolObjFindByName(pools, def->name))) { virObjectRWLockWrite(pools);
if ((obj = virStoragePoolObjFindByNameLocked(pools, def->name))) {
virObjectLock(obj);
if (!virStoragePoolObjIsActive(obj)) { if (!virStoragePoolObjIsActive(obj)) {
virStoragePoolDefFree(obj->def); virStoragePoolDefFree(obj->def);
obj->def = def; obj->def = def;
@ -637,19 +743,31 @@ virStoragePoolObjAssignDef(virStoragePoolObjListPtr pools,
virStoragePoolDefFree(obj->newDef); virStoragePoolDefFree(obj->newDef);
obj->newDef = def; obj->newDef = def;
} }
virObjectRWUnlock(pools);
return obj; return obj;
} }
if (!(obj = virStoragePoolObjNew())) if (!(obj = virStoragePoolObjNew()))
return NULL; return NULL;
if (VIR_APPEND_ELEMENT_COPY(pools->objs, pools->count, obj) < 0) { virUUIDFormat(def->uuid, uuidstr);
virStoragePoolObjEndAPI(&obj); if (virHashAddEntry(pools->objs, uuidstr, obj) < 0)
return NULL; goto error;
} virObjectRef(obj);
obj->def = def;
return virObjectRef(obj); if (virHashAddEntry(pools->objsName, def->name, obj) < 0) {
virHashRemoveEntry(pools->objs, uuidstr);
goto error;
}
virObjectRef(obj);
obj->def = def;
virObjectRWUnlock(pools);
return obj;
error:
virStoragePoolObjEndAPI(&obj);
virObjectRWUnlock(pools);
return NULL;
} }
@ -682,11 +800,13 @@ virStoragePoolObjLoad(virStoragePoolObjListPtr pools,
VIR_FREE(obj->configFile); /* for driver reload */ VIR_FREE(obj->configFile); /* for driver reload */
if (VIR_STRDUP(obj->configFile, path) < 0) { if (VIR_STRDUP(obj->configFile, path) < 0) {
virStoragePoolObjRemove(pools, obj); virStoragePoolObjRemove(pools, obj);
virObjectUnref(obj);
return NULL; return NULL;
} }
VIR_FREE(obj->autostartLink); /* for driver reload */ VIR_FREE(obj->autostartLink); /* for driver reload */
if (VIR_STRDUP(obj->autostartLink, autostartLink) < 0) { if (VIR_STRDUP(obj->autostartLink, autostartLink) < 0) {
virStoragePoolObjRemove(pools, obj); virStoragePoolObjRemove(pools, obj);
virObjectUnref(obj);
return NULL; return NULL;
} }
@ -875,26 +995,100 @@ virStoragePoolObjDeleteDef(virStoragePoolObjPtr obj)
} }
struct _virStoragePoolCountData {
virConnectPtr conn;
virStoragePoolObjListACLFilter filter;
bool wantActive;
int count;
};
static int
virStoragePoolObjNumOfStoragePoolsCb(void *payload,
const void *name ATTRIBUTE_UNUSED,
void *opaque)
{
virStoragePoolObjPtr obj = payload;
struct _virStoragePoolCountData *data = opaque;
virObjectLock(obj);
if (data->filter && !data->filter(data->conn, obj->def))
goto cleanup;
if (data->wantActive != virStoragePoolObjIsActive(obj))
goto cleanup;
data->count++;
cleanup:
virObjectUnlock(obj);
return 0;
}
int int
virStoragePoolObjNumOfStoragePools(virStoragePoolObjListPtr pools, virStoragePoolObjNumOfStoragePools(virStoragePoolObjListPtr pools,
virConnectPtr conn, virConnectPtr conn,
bool wantActive, bool wantActive,
virStoragePoolObjListACLFilter filter) virStoragePoolObjListACLFilter filter)
{ {
int npools = 0; struct _virStoragePoolCountData data = {
size_t i; .conn = conn, .filter = filter, .wantActive = wantActive, .count = 0 };
virObjectRWLockRead(pools);
virHashForEach(pools->objs, virStoragePoolObjNumOfStoragePoolsCb, &data);
virObjectRWUnlock(pools);
return data.count;
}
struct _virStoragePoolNameData {
virConnectPtr conn;
virStoragePoolObjListACLFilter filter;
bool wantActive;
bool error;
int nnames;
int maxnames;
char **const names;
};
static int
virStoragePoolObjGetNamesCb(void *payload,
const void *name ATTRIBUTE_UNUSED,
void *opaque)
{
virStoragePoolObjPtr obj = payload;
struct _virStoragePoolNameData *data = opaque;
if (data->error)
return 0;
if (data->maxnames >= 0 && data->nnames == data->maxnames)
return 0;
for (i = 0; i < pools->count; i++) {
virStoragePoolObjPtr obj = pools->objs[i];
virObjectLock(obj); virObjectLock(obj);
if (!filter || filter(conn, obj->def)) {
if (wantActive == virStoragePoolObjIsActive(obj)) if (data->filter && !data->filter(data->conn, obj->def))
npools++; goto cleanup;
if (data->wantActive != virStoragePoolObjIsActive(obj))
goto cleanup;
if (data->names) {
if (VIR_STRDUP(data->names[data->nnames], obj->def->name) < 0) {
data->error = true;
goto cleanup;
} }
virObjectUnlock(obj);
} }
return npools; data->nnames++;
cleanup:
virObjectUnlock(obj);
return 0;
} }
@ -906,30 +1100,22 @@ virStoragePoolObjGetNames(virStoragePoolObjListPtr pools,
char **const names, char **const names,
int maxnames) int maxnames)
{ {
int nnames = 0; struct _virStoragePoolNameData data = {
size_t i; .conn = conn, .filter = filter, .wantActive = wantActive,
.error = false, .nnames = 0, .maxnames = maxnames, .names = names };
for (i = 0; i < pools->count && nnames < maxnames; i++) { virObjectRWLockRead(pools);
virStoragePoolObjPtr obj = pools->objs[i]; virHashForEach(pools->objs, virStoragePoolObjGetNamesCb, &data);
virObjectLock(obj); virObjectRWUnlock(pools);
if (!filter || filter(conn, obj->def)) {
if (wantActive == virStoragePoolObjIsActive(obj)) {
if (VIR_STRDUP(names[nnames], obj->def->name) < 0) {
virObjectUnlock(obj);
goto failure;
}
nnames++;
}
}
virObjectUnlock(obj);
}
return nnames; if (data.error)
goto error;
failure: return data.nnames;
while (--nnames >= 0)
VIR_FREE(names[nnames]);
error:
while (data.nnames)
VIR_FREE(data.names[--data.nnames]);
return -1; return -1;
} }
@ -1288,38 +1474,37 @@ virStoragePoolObjSourceMatchTypeDEVICE(virStoragePoolObjPtr obj,
} }
int struct _virStoragePoolObjFindDuplicateData {
virStoragePoolObjSourceFindDuplicate(virConnectPtr conn, virConnectPtr conn;
virStoragePoolObjListPtr pools, virStoragePoolDefPtr def;
virStoragePoolDefPtr def) };
{
size_t i;
int ret = 1;
virStoragePoolObjPtr obj = NULL;
virStoragePoolObjPtr matchobj = NULL;
/* Check the pool list for duplicate underlying storage */ static int
for (i = 0; i < pools->count; i++) { virStoragePoolObjSourceFindDuplicateCb(const void *payload,
obj = pools->objs[i]; const void *name ATTRIBUTE_UNUSED,
const void *opaque)
{
virStoragePoolObjPtr obj = (virStoragePoolObjPtr) payload;
struct _virStoragePoolObjFindDuplicateData *data =
(struct _virStoragePoolObjFindDuplicateData *) opaque;
/* Don't match against ourself if re-defining existing pool ! */ /* Don't match against ourself if re-defining existing pool ! */
if (STREQ(obj->def->name, def->name)) if (STREQ(obj->def->name, data->def->name))
continue; return 0;
virObjectLock(obj);
switch ((virStoragePoolType)obj->def->type) { switch ((virStoragePoolType)obj->def->type) {
case VIR_STORAGE_POOL_DIR: case VIR_STORAGE_POOL_DIR:
case VIR_STORAGE_POOL_GLUSTER: case VIR_STORAGE_POOL_GLUSTER:
case VIR_STORAGE_POOL_NETFS: case VIR_STORAGE_POOL_NETFS:
if (def->type == obj->def->type) if (data->def->type == obj->def->type &&
matchobj = virStoragePoolObjSourceMatchTypeDIR(obj, def); virStoragePoolObjSourceMatchTypeDIR(obj, data->def))
return 1;
break; break;
case VIR_STORAGE_POOL_SCSI: case VIR_STORAGE_POOL_SCSI:
if (def->type == obj->def->type) if (data->def->type == obj->def->type &&
matchobj = virStoragePoolObjSourceMatchTypeISCSI(obj, def, virStoragePoolObjSourceMatchTypeISCSI(obj, data->def, data->conn))
conn); return 1;
break; break;
case VIR_STORAGE_POOL_ISCSI: case VIR_STORAGE_POOL_ISCSI:
@ -1327,50 +1512,65 @@ virStoragePoolObjSourceFindDuplicate(virConnectPtr conn,
case VIR_STORAGE_POOL_LOGICAL: case VIR_STORAGE_POOL_LOGICAL:
case VIR_STORAGE_POOL_DISK: case VIR_STORAGE_POOL_DISK:
case VIR_STORAGE_POOL_ZFS: case VIR_STORAGE_POOL_ZFS:
if (def->type == VIR_STORAGE_POOL_ISCSI || if ((data->def->type == VIR_STORAGE_POOL_ISCSI ||
def->type == VIR_STORAGE_POOL_FS || data->def->type == VIR_STORAGE_POOL_FS ||
def->type == VIR_STORAGE_POOL_LOGICAL || data->def->type == VIR_STORAGE_POOL_LOGICAL ||
def->type == VIR_STORAGE_POOL_DISK || data->def->type == VIR_STORAGE_POOL_DISK ||
def->type == VIR_STORAGE_POOL_ZFS) data->def->type == VIR_STORAGE_POOL_ZFS) &&
matchobj = virStoragePoolObjSourceMatchTypeDEVICE(obj, def); virStoragePoolObjSourceMatchTypeDEVICE(obj, data->def))
return 1;
break; break;
case VIR_STORAGE_POOL_SHEEPDOG: case VIR_STORAGE_POOL_SHEEPDOG:
if (def->type == obj->def->type && if (data->def->type == obj->def->type &&
virStoragePoolSourceMatchSingleHost(&obj->def->source, virStoragePoolSourceMatchSingleHost(&obj->def->source,
&def->source)) &data->def->source))
matchobj = obj; return 1;
break; break;
case VIR_STORAGE_POOL_MPATH: case VIR_STORAGE_POOL_MPATH:
/* Only one mpath pool is valid per host */ /* Only one mpath pool is valid per host */
if (def->type == obj->def->type) if (data->def->type == obj->def->type)
matchobj = obj; return 1;
break; break;
case VIR_STORAGE_POOL_VSTORAGE: case VIR_STORAGE_POOL_VSTORAGE:
if (def->type == obj->def->type && if (data->def->type == obj->def->type &&
STREQ(obj->def->source.name, def->source.name)) STREQ(obj->def->source.name, data->def->source.name))
matchobj = obj; return 1;
break; break;
case VIR_STORAGE_POOL_RBD: case VIR_STORAGE_POOL_RBD:
case VIR_STORAGE_POOL_LAST: case VIR_STORAGE_POOL_LAST:
break; break;
} }
virObjectUnlock(obj);
if (matchobj) return 0;
break;
} }
if (matchobj) {
int
virStoragePoolObjSourceFindDuplicate(virConnectPtr conn,
virStoragePoolObjListPtr pools,
virStoragePoolDefPtr def)
{
struct _virStoragePoolObjFindDuplicateData data = { .conn = conn,
.def = def };
virStoragePoolObjPtr obj = NULL;
virObjectRWLockRead(pools);
obj = virHashSearch(pools->objs, virStoragePoolObjSourceFindDuplicateCb,
&data, NULL);
virObjectRWUnlock(pools);
if (obj) {
virReportError(VIR_ERR_OPERATION_FAILED, virReportError(VIR_ERR_OPERATION_FAILED,
_("Storage source conflict with pool: '%s'"), _("Storage source conflict with pool: '%s'"),
matchobj->def->name); obj->def->name);
ret = -1; return -1;
} }
return ret;
return 0;
} }
@ -1439,6 +1639,56 @@ virStoragePoolMatch(virStoragePoolObjPtr obj,
#undef MATCH #undef MATCH
struct _virStoragePoolExportData {
virConnectPtr conn;
virStoragePoolObjListACLFilter filter;
bool checkActive;
bool wantActive;
bool checkMatch;
unsigned int flags;
bool error;
int nPools;
virStoragePoolPtr *pools;
};
static int
virStoragePoolObjListExportCb(void *payload,
const void *name ATTRIBUTE_UNUSED,
void *opaque)
{
virStoragePoolObjPtr obj = payload;
struct _virStoragePoolExportData *data = opaque;
virStoragePoolPtr pool = NULL;
if (data->error)
return 0;
virObjectLock(obj);
if (data->filter && !data->filter(data->conn, obj->def))
goto cleanup;
if (!virStoragePoolMatch(obj, data->flags))
goto cleanup;
if (data->pools) {
if (!(pool = virGetStoragePool(data->conn, obj->def->name,
obj->def->uuid, NULL, NULL))) {
data->error = true;
goto cleanup;
}
data->pools[data->nPools] = pool;
}
data->nPools++;
cleanup:
virObjectUnlock(obj);
return 0;
}
int int
virStoragePoolObjListExport(virConnectPtr conn, virStoragePoolObjListExport(virConnectPtr conn,
virStoragePoolObjListPtr poolobjs, virStoragePoolObjListPtr poolobjs,
@ -1446,50 +1696,30 @@ virStoragePoolObjListExport(virConnectPtr conn,
virStoragePoolObjListFilter filter, virStoragePoolObjListFilter filter,
unsigned int flags) unsigned int flags)
{ {
virStoragePoolPtr *tmp_pools = NULL; struct _virStoragePoolExportData data = {
virStoragePoolPtr pool = NULL; .conn = conn, .filter = filter, .flags = flags, .error = false,
int npools = 0; .nPools = 0, .pools = NULL };
int ret = -1;
size_t i;
if (pools && VIR_ALLOC_N(tmp_pools, poolobjs->count + 1) < 0) virObjectRWLockRead(poolobjs);
goto cleanup;
for (i = 0; i < poolobjs->count; i++) { if (pools && VIR_ALLOC_N(data.pools, virHashSize(poolobjs->objs) + 1) < 0)
virStoragePoolObjPtr obj = poolobjs->objs[i]; goto error;
virObjectLock(obj);
if ((!filter || filter(conn, obj->def)) &&
virStoragePoolMatch(obj, flags)) {
if (pools) {
if (!(pool = virGetStoragePool(conn,
obj->def->name,
obj->def->uuid,
NULL, NULL))) {
virObjectUnlock(obj);
goto cleanup;
}
tmp_pools[npools] = pool;
}
npools++;
}
virObjectUnlock(obj);
}
if (tmp_pools) { virHashForEach(poolobjs->objs, virStoragePoolObjListExportCb, &data);
virObjectRWUnlock(poolobjs);
if (data.error)
goto error;
if (data.pools) {
/* trim the array to the final size */ /* trim the array to the final size */
ignore_value(VIR_REALLOC_N(tmp_pools, npools + 1)); ignore_value(VIR_REALLOC_N(data.pools, data.nPools + 1));
*pools = tmp_pools; *pools = data.pools;
tmp_pools = NULL;
} }
ret = npools; return data.nPools;
cleanup: error:
if (tmp_pools) { virObjectListFree(data.pools);
for (i = 0; i < npools; i++) return -1;
virObjectUnref(tmp_pools[i]);
}
VIR_FREE(tmp_pools);
return ret;
} }

View File

@ -219,9 +219,6 @@ virStoragePoolObjGetNames(virStoragePoolObjListPtr pools,
void void
virStoragePoolObjFree(virStoragePoolObjPtr obj); virStoragePoolObjFree(virStoragePoolObjPtr obj);
void
virStoragePoolObjListFree(virStoragePoolObjListPtr pools);
typedef void typedef void
(*virStoragePoolObjListIterator)(virStoragePoolObjPtr obj, (*virStoragePoolObjListIterator)(virStoragePoolObjPtr obj,
const void *opaque); const void *opaque);

View File

@ -1095,7 +1095,6 @@ virStoragePoolObjIsAutostart;
virStoragePoolObjIsDuplicate; virStoragePoolObjIsDuplicate;
virStoragePoolObjListExport; virStoragePoolObjListExport;
virStoragePoolObjListForEach; virStoragePoolObjListForEach;
virStoragePoolObjListFree;
virStoragePoolObjListNew; virStoragePoolObjListNew;
virStoragePoolObjListSearch; virStoragePoolObjListSearch;
virStoragePoolObjLoadAllConfigs; virStoragePoolObjLoadAllConfigs;

View File

@ -94,6 +94,7 @@ virStoragePoolUpdateInactive(virStoragePoolObjPtr *objptr)
if (!virStoragePoolObjGetConfigFile(obj)) { if (!virStoragePoolObjGetConfigFile(obj)) {
virStoragePoolObjRemove(driver->pools, obj); virStoragePoolObjRemove(driver->pools, obj);
virObjectUnref(obj);
*objptr = NULL; *objptr = NULL;
} else if (virStoragePoolObjGetNewDef(obj)) { } else if (virStoragePoolObjGetNewDef(obj)) {
virStoragePoolObjDefUseNewDef(obj); virStoragePoolObjDefUseNewDef(obj);
@ -375,7 +376,7 @@ storageStateCleanup(void)
virObjectUnref(driver->storageEventState); virObjectUnref(driver->storageEventState);
/* free inactive pools */ /* free inactive pools */
virStoragePoolObjListFree(driver->pools); virObjectUnref(driver->pools);
VIR_FREE(driver->configDir); VIR_FREE(driver->configDir);
VIR_FREE(driver->autostartDir); VIR_FREE(driver->autostartDir);
@ -713,6 +714,7 @@ storagePoolCreateXML(virConnectPtr conn,
(flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD)) { (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD)) {
if (backend->buildPool(conn, obj, build_flags) < 0) { if (backend->buildPool(conn, obj, build_flags) < 0) {
virStoragePoolObjRemove(driver->pools, obj); virStoragePoolObjRemove(driver->pools, obj);
virObjectUnref(obj);
obj = NULL; obj = NULL;
goto cleanup; goto cleanup;
} }
@ -722,6 +724,7 @@ storagePoolCreateXML(virConnectPtr conn,
if (backend->startPool && if (backend->startPool &&
backend->startPool(conn, obj) < 0) { backend->startPool(conn, obj) < 0) {
virStoragePoolObjRemove(driver->pools, obj); virStoragePoolObjRemove(driver->pools, obj);
virObjectUnref(obj);
obj = NULL; obj = NULL;
goto cleanup; goto cleanup;
} }
@ -736,6 +739,7 @@ storagePoolCreateXML(virConnectPtr conn,
if (backend->stopPool) if (backend->stopPool)
backend->stopPool(conn, obj); backend->stopPool(conn, obj);
virStoragePoolObjRemove(driver->pools, obj); virStoragePoolObjRemove(driver->pools, obj);
virObjectUnref(obj);
obj = NULL; obj = NULL;
goto cleanup; goto cleanup;
} }
@ -799,6 +803,7 @@ storagePoolDefineXML(virConnectPtr conn,
if (virStoragePoolObjSaveDef(driver, obj, def) < 0) { if (virStoragePoolObjSaveDef(driver, obj, def) < 0) {
virStoragePoolObjRemove(driver->pools, obj); virStoragePoolObjRemove(driver->pools, obj);
virObjectUnref(obj);
obj = NULL; obj = NULL;
goto cleanup; goto cleanup;
} }
@ -868,6 +873,7 @@ storagePoolUndefine(virStoragePoolPtr pool)
VIR_INFO("Undefining storage pool '%s'", def->name); VIR_INFO("Undefining storage pool '%s'", def->name);
virStoragePoolObjRemove(driver->pools, obj); virStoragePoolObjRemove(driver->pools, obj);
virObjectUnref(obj);
obj = NULL; obj = NULL;
ret = 0; ret = 0;

View File

@ -155,7 +155,7 @@ testDriverFree(testDriverPtr driver)
virNodeDeviceObjListFree(driver->devs); virNodeDeviceObjListFree(driver->devs);
virObjectUnref(driver->networks); virObjectUnref(driver->networks);
virObjectUnref(driver->ifaces); virObjectUnref(driver->ifaces);
virStoragePoolObjListFree(driver->pools); virObjectUnref(driver->pools);
virObjectUnref(driver->eventState); virObjectUnref(driver->eventState);
virMutexUnlock(&driver->lock); virMutexUnlock(&driver->lock);
virMutexDestroy(&driver->lock); virMutexDestroy(&driver->lock);
@ -4463,6 +4463,7 @@ testStoragePoolCreateXML(virConnectPtr conn,
def->source.adapter.data.fchost.wwnn, def->source.adapter.data.fchost.wwnn,
def->source.adapter.data.fchost.wwpn) < 0) { def->source.adapter.data.fchost.wwpn) < 0) {
virStoragePoolObjRemove(privconn->pools, obj); virStoragePoolObjRemove(privconn->pools, obj);
virObjectUnref(obj);
obj = NULL; obj = NULL;
goto cleanup; goto cleanup;
} }
@ -4470,6 +4471,7 @@ testStoragePoolCreateXML(virConnectPtr conn,
if (testStoragePoolObjSetDefaults(obj) == -1) { if (testStoragePoolObjSetDefaults(obj) == -1) {
virStoragePoolObjRemove(privconn->pools, obj); virStoragePoolObjRemove(privconn->pools, obj);
virObjectUnref(obj);
obj = NULL; obj = NULL;
goto cleanup; goto cleanup;
} }
@ -4529,6 +4531,7 @@ testStoragePoolDefineXML(virConnectPtr conn,
if (testStoragePoolObjSetDefaults(obj) == -1) { if (testStoragePoolObjSetDefaults(obj) == -1) {
virStoragePoolObjRemove(privconn->pools, obj); virStoragePoolObjRemove(privconn->pools, obj);
virObjectUnref(obj);
obj = NULL; obj = NULL;
goto cleanup; goto cleanup;
} }
@ -4559,6 +4562,7 @@ testStoragePoolUndefine(virStoragePoolPtr pool)
0); 0);
virStoragePoolObjRemove(privconn->pools, obj); virStoragePoolObjRemove(privconn->pools, obj);
virObjectUnref(obj);
testObjectEventQueue(privconn, event); testObjectEventQueue(privconn, event);
return 0; return 0;
@ -4652,6 +4656,7 @@ testStoragePoolDestroy(virStoragePoolPtr pool)
if (!(virStoragePoolObjGetConfigFile(obj))) { if (!(virStoragePoolObjGetConfigFile(obj))) {
virStoragePoolObjRemove(privconn->pools, obj); virStoragePoolObjRemove(privconn->pools, obj);
virObjectUnref(obj);
obj = NULL; obj = NULL;
} }
ret = 0; ret = 0;