diff --git a/src/conf/virstorageobj.c b/src/conf/virstorageobj.c index 2ca8453139..3cae34d970 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 a4d7186d12..c84877694e 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 ab1f1f5e60..9fb302b693 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 7cc3c518b4..454b1b0df0 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); }