[libvirt] [PATCH] storage: Fix several issues with transient pool cleanup

Cole Robinson crobinso at redhat.com
Mon Jun 20 18:16:17 UTC 2016


On 06/20/2016 12:18 PM, Jovanka Gulicoska wrote:
> There are several cases where we do not handle transient pool destroy
> and cleanup correctly. For example:
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=1227475
> 
> Move the pool cleanup logic to a new function storagePoolSetInactive and
> use it consistently.
> ---
>  src/storage/storage_driver.c | 38 ++++++++++++++++++++------------------
>  1 file changed, 20 insertions(+), 18 deletions(-)
> 
> diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
> index e2d729f..74af35d 100644
> --- a/src/storage/storage_driver.c
> +++ b/src/storage/storage_driver.c
> @@ -77,6 +77,21 @@ static void storageDriverUnlock(void)
>  }
>  
>  static void
> +storagePoolSetInactive(virStoragePoolObjPtr pool)
> +{
> +    pool->active = false;
> +
> +    if (pool->configFile == NULL) {
> +        virStoragePoolObjRemove(&driver->pools, pool);
> +        pool = NULL;
> +    } else if (pool->newDef) {
> +        virStoragePoolDefFree(pool->def);
> +        pool->def = pool->newDef;
> +        pool->newDef = NULL;
> +    }
> +}
> +

Hmm. I'm testing this, and I see one problem here. The pool = NULL bit is not
propagated to the caller in any way, which is required to not crash in cleanup
paths if the pool disappears.

I think this function needs to take virStoragePoolObjPtr *pool, and callers
pass in &pool, so the *pool = NULL; bit affects the caller.

> +static void
>  storagePoolUpdateState(virStoragePoolObjPtr pool)
>  {
>      bool active;
> @@ -143,6 +158,7 @@ storagePoolUpdateAllState(void)
>          virStoragePoolObjPtr pool = driver->pools.objs[i];
>  
>          virStoragePoolObjLock(pool);
> +        storagePoolSetInactive(pool);
>          storagePoolUpdateState(pool);
>          virStoragePoolObjUnlock(pool);

I see this bit here is required to fix the reported bug, but I think it should
be pushed into storagePoolUpdateState(pool), since there are cases there where
the pool may be marked as 'inactive' as well. This is the diff I came up with:

diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 74af35d..ae965ee 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -130,16 +130,19 @@ storagePoolUpdateState(virStoragePoolObjPtr pool)
         if (backend->refreshPool(NULL, pool) < 0) {
             if (backend->stopPool)
                 backend->stopPool(NULL, pool);
+            active = false;
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Failed to restart storage pool '%s': %s"),
                            pool->def->name, virGetLastErrorMessage());
             goto error;
         }
+        pool->active = true;
     }

-    pool->active = active;
     ret = 0;
  error:
+    if (!active)
+        storagePoolSetInactive(pool);
     if (ret < 0) {
         if (stateFile)
             unlink(stateFile);
@@ -158,7 +161,6 @@ storagePoolUpdateAllState(void)
         virStoragePoolObjPtr pool = driver->pools.objs[i];

         virStoragePoolObjLock(pool);
-        storagePoolSetInactive(pool);
         storagePoolUpdateState(pool);
         virStoragePoolObjUnlock(pool);
     }


>      }
> @@ -198,6 +214,7 @@ storageDriverAutostart(void)
>                      unlink(stateFile);
>                  if (backend->stopPool)
>                      backend->stopPool(conn, pool);
> +                storagePoolSetInactive(pool);
>                  virReportError(VIR_ERR_INTERNAL_ERROR,
>                                 _("Failed to autostart storage pool '%s': %s"),
>                                 pool->def->name, virGetLastErrorMessage());
> @@ -737,7 +754,7 @@ storagePoolCreateXML(virConnectPtr conn,
>              unlink(stateFile);
>          if (backend->stopPool)
>              backend->stopPool(conn, pool);
> -        virStoragePoolObjRemove(&driver->pools, pool);
> +        storagePoolSetInactive(pool);
>          pool = NULL;

This pool = NULL; line can be dropped if the above first suggestion is
implemented.

Otherwise this looks correct to me

Thanks,
Cole




More information about the libvir-list mailing list