From d0258dd9d6e1acff65816809c08a3b046c1624dc Mon Sep 17 00:00:00 2001 From: John Ferlan Date: Nov 24 2017 12:26:06 +0000 Subject: 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. --- diff --git a/src/conf/virstorageobj.c b/src/conf/virstorageobj.c index 2ca8453..3cae34d 100644 --- a/src/conf/virstorageobj.c +++ b/src/conf/virstorageobj.c @@ -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 virStoragePoolObjRemove(virStoragePoolObjListPtr pools, virStoragePoolObjPtr obj) diff --git a/src/conf/virstorageobj.h b/src/conf/virstorageobj.h index a4d7186..c848776 100644 --- a/src/conf/virstorageobj.h +++ b/src/conf/virstorageobj.h @@ -226,6 +226,15 @@ virStoragePoolObjFree(virStoragePoolObjPtr obj); void virStoragePoolObjListFree(virStoragePoolObjListPtr pools); +typedef void +(*virStoragePoolObjListIterator)(virStoragePoolObjPtr obj, + const void *opaque); + +void +virStoragePoolObjListForEach(virStoragePoolObjListPtr pools, + virStoragePoolObjListIterator iter, + const void *opaque); + void virStoragePoolObjRemove(virStoragePoolObjListPtr pools, virStoragePoolObjPtr obj); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ab1f1f5..9fb302b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1090,6 +1090,7 @@ virStoragePoolObjIsActive; virStoragePoolObjIsAutostart; virStoragePoolObjIsDuplicate; virStoragePoolObjListExport; +virStoragePoolObjListForEach; virStoragePoolObjListFree; virStoragePoolObjLoadAllConfigs; virStoragePoolObjLoadAllState; diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 7cc3c51..454b1b0 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -102,7 +102,8 @@ virStoragePoolUpdateInactive(virStoragePoolObjPtr *objptr) static void -storagePoolUpdateState(virStoragePoolObjPtr obj) +storagePoolUpdateStateCallback(virStoragePoolObjPtr obj, + const void *opaque ATTRIBUTE_UNUSED) { virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj); bool active = false; @@ -157,24 +158,66 @@ storagePoolUpdateState(virStoragePoolObjPtr obj) return; } + static 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); - storagePoolUpdateState(obj); - virStoragePoolObjEndAPI(&obj); +static void +storageDriverAutostartCallback(virStoragePoolObjPtr 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 storageDriverAutostart(void) { - size_t i; virConnectPtr conn = NULL; /* XXX Remove hardcoding of QEMU URI */ @@ -184,53 +227,9 @@ storageDriverAutostart(void) conn = virConnectOpen("qemu:///session"); /* Ignoring NULL conn - let backends decide */ - for (i = 0; i < driver->pools.count; i++) { - virStoragePoolObjPtr obj = driver->pools.objs[i]; - virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj); - 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); - } + virStoragePoolObjListForEach(&driver->pools, + storageDriverAutostartCallback, + conn); virObjectUnref(conn); }