storage: Introduce virStoragePoolObjListForEach

Create an API to walk the pools->objs[] list in order to perform a
callback function for each element of the objs array that doesn't care
about whether the action succeeds or fails as the desire is to run the
code over every element in the array rather than fail as soon as or if
one fails.
This commit is contained in:
John Ferlan 2017-10-08 08:14:56 -04:00
parent 770aa08e48
commit d0258dd9d6
4 changed files with 93 additions and 55 deletions

View File

@ -230,6 +230,35 @@ virStoragePoolObjListFree(virStoragePoolObjListPtr pools)
} }
/**
* virStoragePoolObjListForEach
* @pools: Pointer to pools object
* @iter: Callback iteration helper
* @opaque: Opaque data to use as argument to helper
*
* For each object in @pools, call the @iter helper using @opaque as
* an argument. This function doesn't care whether the @iter fails or
* not as it's being used for Autostart and UpdateAllState callers
* that want to iterate over all the @pools objects not stopping if
* one happens to fail.
*/
void
virStoragePoolObjListForEach(virStoragePoolObjListPtr pools,
virStoragePoolObjListIterator iter,
const void *opaque)
{
size_t i;
virStoragePoolObjPtr obj;
for (i = 0; i < pools->count; i++) {
obj = pools->objs[i];
virStoragePoolObjLock(obj);
iter(obj, opaque);
virStoragePoolObjUnlock(obj);
}
}
void void
virStoragePoolObjRemove(virStoragePoolObjListPtr pools, virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
virStoragePoolObjPtr obj) virStoragePoolObjPtr obj)

View File

@ -226,6 +226,15 @@ virStoragePoolObjFree(virStoragePoolObjPtr obj);
void void
virStoragePoolObjListFree(virStoragePoolObjListPtr pools); virStoragePoolObjListFree(virStoragePoolObjListPtr pools);
typedef void
(*virStoragePoolObjListIterator)(virStoragePoolObjPtr obj,
const void *opaque);
void
virStoragePoolObjListForEach(virStoragePoolObjListPtr pools,
virStoragePoolObjListIterator iter,
const void *opaque);
void void
virStoragePoolObjRemove(virStoragePoolObjListPtr pools, virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
virStoragePoolObjPtr obj); virStoragePoolObjPtr obj);

View File

@ -1090,6 +1090,7 @@ virStoragePoolObjIsActive;
virStoragePoolObjIsAutostart; virStoragePoolObjIsAutostart;
virStoragePoolObjIsDuplicate; virStoragePoolObjIsDuplicate;
virStoragePoolObjListExport; virStoragePoolObjListExport;
virStoragePoolObjListForEach;
virStoragePoolObjListFree; virStoragePoolObjListFree;
virStoragePoolObjLoadAllConfigs; virStoragePoolObjLoadAllConfigs;
virStoragePoolObjLoadAllState; virStoragePoolObjLoadAllState;

View File

@ -102,7 +102,8 @@ virStoragePoolUpdateInactive(virStoragePoolObjPtr *objptr)
static void static void
storagePoolUpdateState(virStoragePoolObjPtr obj) storagePoolUpdateStateCallback(virStoragePoolObjPtr obj,
const void *opaque ATTRIBUTE_UNUSED)
{ {
virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj); virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
bool active = false; bool active = false;
@ -157,24 +158,66 @@ storagePoolUpdateState(virStoragePoolObjPtr obj)
return; return;
} }
static void static void
storagePoolUpdateAllState(void) storagePoolUpdateAllState(void)
{ {
size_t i; virStoragePoolObjListForEach(&driver->pools,
storagePoolUpdateStateCallback,
NULL);
}
for (i = 0; i < driver->pools.count; i++) {
virStoragePoolObjPtr obj = driver->pools.objs[i];
virStoragePoolObjLock(obj); static void
storagePoolUpdateState(obj); storageDriverAutostartCallback(virStoragePoolObjPtr obj,
virStoragePoolObjEndAPI(&obj); const void *opaque)
{
virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
virConnectPtr conn = (virConnectPtr) opaque;
virStorageBackendPtr backend;
bool started = false;
if (!(backend = virStorageBackendForType(def->type)))
return;
if (virStoragePoolObjIsAutostart(obj) &&
!virStoragePoolObjIsActive(obj)) {
if (backend->startPool &&
backend->startPool(conn, obj) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to autostart storage pool '%s': %s"),
def->name, virGetLastErrorMessage());
return;
}
started = true;
}
if (started) {
char *stateFile;
virStoragePoolObjClearVols(obj);
stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml");
if (!stateFile ||
virStoragePoolSaveState(stateFile, def) < 0 ||
backend->refreshPool(conn, obj) < 0) {
if (stateFile)
unlink(stateFile);
if (backend->stopPool)
backend->stopPool(conn, obj);
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to autostart storage pool '%s': %s"),
def->name, virGetLastErrorMessage());
} else {
virStoragePoolObjSetActive(obj, true);
}
VIR_FREE(stateFile);
} }
} }
static void static void
storageDriverAutostart(void) storageDriverAutostart(void)
{ {
size_t i;
virConnectPtr conn = NULL; virConnectPtr conn = NULL;
/* XXX Remove hardcoding of QEMU URI */ /* XXX Remove hardcoding of QEMU URI */
@ -184,53 +227,9 @@ storageDriverAutostart(void)
conn = virConnectOpen("qemu:///session"); conn = virConnectOpen("qemu:///session");
/* Ignoring NULL conn - let backends decide */ /* Ignoring NULL conn - let backends decide */
for (i = 0; i < driver->pools.count; i++) { virStoragePoolObjListForEach(&driver->pools,
virStoragePoolObjPtr obj = driver->pools.objs[i]; storageDriverAutostartCallback,
virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj); conn);
virStorageBackendPtr backend;
bool started = false;
virStoragePoolObjLock(obj);
if ((backend = virStorageBackendForType(def->type)) == NULL) {
virStoragePoolObjEndAPI(&obj);
continue;
}
if (virStoragePoolObjIsAutostart(obj) &&
!virStoragePoolObjIsActive(obj)) {
if (backend->startPool &&
backend->startPool(conn, obj) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to autostart storage pool '%s': %s"),
def->name, virGetLastErrorMessage());
virStoragePoolObjEndAPI(&obj);
continue;
}
started = true;
}
if (started) {
char *stateFile;
virStoragePoolObjClearVols(obj);
stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml");
if (!stateFile ||
virStoragePoolSaveState(stateFile, def) < 0 ||
backend->refreshPool(conn, obj) < 0) {
if (stateFile)
unlink(stateFile);
if (backend->stopPool)
backend->stopPool(conn, obj);
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to autostart storage pool '%s': %s"),
def->name, virGetLastErrorMessage());
} else {
virStoragePoolObjSetActive(obj, true);
}
VIR_FREE(stateFile);
}
virStoragePoolObjEndAPI(&obj);
}
virObjectUnref(conn); virObjectUnref(conn);
} }