]> xenbits.xensource.com Git - libvirt.git/commitdiff
storage: Introduce storagePoolUpdateAllState function
authorErik Skultety <eskultet@redhat.com>
Mon, 16 Mar 2015 15:30:03 +0000 (16:30 +0100)
committerErik Skultety <eskultet@redhat.com>
Tue, 7 Apr 2015 14:22:40 +0000 (16:22 +0200)
The 'checkPool' callback was originally part of the storageDriverAutostart function,
but the pools need to be checked earlier during initialization phase,
otherwise we can't start a domain which mounts a volume after the
libvirtd daemon restarted. This is because qemuProcessReconnect is called
earlier than storageDriverAutostart. Therefore the 'checkPool' logic has been
moved to storagePoolUpdateAllState which is called inside storageDriverInitialize.

We also need a valid 'conn' reference to be able to execute 'refreshPool'
during initialization phase. Though it isn't available until storageDriverAutostart
all of our storage backends do ignore 'conn' pointer, except for RBD,
but RBD doesn't support 'checkPool' callback, so it's safe to pass
conn = NULL in this case.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1177733

src/storage/storage_driver.c

index 839de13fd24cbd0960271b4f07d550678d0d7974..551a0ca122faa39295596be0fcb27d51dde000ca 100644 (file)
@@ -74,6 +74,65 @@ static void storageDriverUnlock(void)
     virMutexUnlock(&driver->lock);
 }
 
+static void
+storagePoolUpdateAllState(void)
+{
+    size_t i;
+    bool active;
+
+    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.
+         */
+        active = false;
+        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)
 {
@@ -95,23 +154,11 @@ storageDriverAutostart(void)
 
         virStoragePoolObjLock(pool);
         if ((backend = virStorageBackendForType(pool->def->type)) == NULL) {
-            VIR_ERROR(_("Missing backend %d"), pool->def->type);
             virStoragePoolObjUnlock(pool);
             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) {
@@ -213,6 +260,8 @@ storageStateInitialize(bool privileged,
                                      driver->autostartDir) < 0)
         goto error;
 
+    storagePoolUpdateAllState();
+
     storageDriverUnlock();
 
     ret = 0;