The update was originally part of the storageDriverAutostart function, but the pools have to be checked earlier during initialization phase, so the 'checkPool' block has been moved to storagePoolUpdateAllState. Prior to this update virStoragePoolLoadAllConfigs and virStoragePoolLoadAllState functions gather all existing pool in the system, so first it is necessary to filter out the ones that are inactive (only config XML found), then determine storage backends for the rest of the pools and run checkPool on each one of them to update their 'active' property. After update, pools have to be refreshed, otherwise the list of volumes stays empty. Once again we need the connection, but all the storage backends ignore this argument except for RBD, however RBD doesn't support 'checkPool' callback, therefore it is safe to pass connection as NULL pointer. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1177733 --- src/storage/storage_driver.c | 73 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index d09acce..2899521 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -75,6 +75,64 @@ static void storageDriverUnlock(void) } static void +storagePoolUpdateAllState(void) +{ + size_t i; + bool active = false; + + for (i = 0; i < driver->pools.count; i++) { + virStoragePoolObjPtr pool = driver->pools.objs[i]; + virStorageBackendPtr backend; + + virStoragePoolObjLock(pool); + if (!virStoragePoolObjIsActive(pool)) { + virStoragePoolObjUnlock(pool); + continue; + } + + if ((backend = virStorageBackendForType(pool->def->type)) == NULL) { + VIR_ERROR(_("Missing backend %d"), pool->def->type); + virStoragePoolObjUnlock(pool); + continue; + } + + /* Backends which do not support 'checkPool' are considered + * inactive by default. + */ + if (backend->checkPool && + backend->checkPool(pool, &active) < 0) { + virErrorPtr err = virGetLastError(); + VIR_ERROR(_("Failed to initialize storage pool '%s': %s"), + pool->def->name, err ? err->message : + _("no error message found")); + virStoragePoolObjUnlock(pool); + continue; + } + + /* We can pass NULL as connection, most backends do not use + * it anyway, but if they do and fail, we want to log error and + * continue with other pools. + */ + if (active) { + virStoragePoolObjClearVols(pool); + if (backend->refreshPool(NULL, pool) < 0) { + virErrorPtr err = virGetLastError(); + if (backend->stopPool) + backend->stopPool(NULL, pool); + VIR_ERROR(_("Failed to restart storage pool '%s': %s"), + pool->def->name, err ? err->message : + _("no error message found")); + virStoragePoolObjUnlock(pool); + continue; + } + } + + pool->active = active; + virStoragePoolObjUnlock(pool); + } +} + +static void storageDriverAutostart(void) { size_t i; @@ -99,18 +157,7 @@ storageDriverAutostart(void) continue; } - if (backend->checkPool && - backend->checkPool(pool, &started) < 0) { - virErrorPtr err = virGetLastError(); - VIR_ERROR(_("Failed to initialize storage pool '%s': %s"), - pool->def->name, err ? err->message : - _("no error message found")); - virStoragePoolObjUnlock(pool); - continue; - } - - if (!started && - pool->autostart && + if (pool->autostart && !virStoragePoolObjIsActive(pool)) { if (backend->startPool && backend->startPool(conn, pool) < 0) { @@ -207,6 +254,8 @@ storageStateInitialize(bool privileged, driver->autostartDir) < 0) goto error; + storagePoolUpdateAllState(); + storageDriverUnlock(); ret = 0; -- 1.9.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list