[libvirt] [PATCH 1/3] storage: Create a stateDir

John Ferlan jferlan at redhat.com
Tue Jan 13 21:12:30 UTC 2015


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

In order to allow storage backend drivers to save state between refreshes,
restarts or reloads, create a stateDir in virStorageDriverState and
virStoragePoolObj.

At storage driver initialization generate either a /run/libvirt/storage
or {virGetuserRuntimeDirectory()}/storage/run area to store specific state
that may be needed.

Propagate this to the pool->stateDir which will be the driver->stateDir
plus the pool name. During pool load and libvirtd state initialize or
state reload, create the path for the pool->stateDir. During pool delete,
remove the entire status tree for the pool->stateDir.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 src/conf/storage_conf.c           | 55 +++++++++++++++++++++++++++++++--------
 src/conf/storage_conf.h           |  7 +++--
 src/parallels/parallels_storage.c |  5 ++--
 src/storage/storage_driver.c      | 32 +++++++++++++++++++----
 4 files changed, 79 insertions(+), 20 deletions(-)

diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index e9aaa8a..0901dca 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -1,7 +1,7 @@
 /*
  * storage_conf.c: config handling for storage driver
  *
- * Copyright (C) 2006-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2015 Red Hat, Inc.
  * Copyright (C) 2006-2008 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -421,6 +421,7 @@ virStoragePoolObjFree(virStoragePoolObjPtr obj)
 
     VIR_FREE(obj->configFile);
     VIR_FREE(obj->autostartLink);
+    VIR_FREE(obj->stateDir);
 
     virMutexDestroy(&obj->lock);
 
@@ -1802,7 +1803,8 @@ static virStoragePoolObjPtr
 virStoragePoolObjLoad(virStoragePoolObjListPtr pools,
                       const char *file,
                       const char *path,
-                      const char *autostartLink)
+                      const char *autostartLink,
+                      const char *stateDir)
 {
     virStoragePoolDefPtr def;
     virStoragePoolObjPtr pool;
@@ -1834,6 +1836,15 @@ virStoragePoolObjLoad(virStoragePoolObjListPtr pools,
         virStoragePoolDefFree(def);
         return NULL;
     }
+    VIR_FREE(pool->stateDir); /* for driver reload */
+    if (!(pool->stateDir = virFileBuildPath(stateDir, def->name, NULL))) {
+        virStoragePoolDefFree(def);
+        return NULL;
+    }
+    if (virFileMakePath(pool->stateDir) < 0) {
+        virStoragePoolDefFree(def);
+        return NULL;
+    }
 
     pool->autostart = virFileLinkPointsTo(pool->autostartLink,
                                           pool->configFile);
@@ -1845,7 +1856,8 @@ virStoragePoolObjLoad(virStoragePoolObjListPtr pools,
 int
 virStoragePoolLoadAllConfigs(virStoragePoolObjListPtr pools,
                              const char *configDir,
-                             const char *autostartDir)
+                             const char *autostartDir,
+                             const char *stateDir)
 {
     DIR *dir;
     struct dirent *entry;
@@ -1880,7 +1892,7 @@ virStoragePoolLoadAllConfigs(virStoragePoolObjListPtr pools,
         }
 
         pool = virStoragePoolObjLoad(pools, entry->d_name, path,
-                                     autostartLink);
+                                     autostartLink, stateDir);
         if (pool)
             virStoragePoolObjUnlock(pool);
 
@@ -1925,22 +1937,38 @@ virStoragePoolObjSaveDef(virStorageDriverStatePtr driver,
             virReportSystemError(errno,
                                  _("cannot create config directory %s"),
                                  driver->configDir);
-            return -1;
+            goto error;
         }
 
         if (!(pool->configFile = virFileBuildPath(driver->configDir,
-                                                  def->name, ".xml"))) {
-            return -1;
-        }
+                                                  def->name, ".xml")))
+            goto error;
 
         if (!(pool->autostartLink = virFileBuildPath(driver->autostartDir,
-                                                     def->name, ".xml"))) {
-            VIR_FREE(pool->configFile);
-            return -1;
+                                                     def->name, ".xml")))
+            goto error;
+    }
+
+    if (!pool->stateDir) {
+        if (!(pool->stateDir = virFileBuildPath(driver->stateDir,
+                                                def->name, NULL)))
+            goto error;
+
+        if (virFileMakePath(pool->stateDir) < 0) {
+            virReportSystemError(errno,
+                                 _("cannot create pool state directory %s"),
+                                 pool->stateDir);
+            goto error;
         }
     }
 
     return virStoragePoolSaveConfig(pool->configFile, def);
+
+ error:
+    VIR_FREE(pool->configFile);
+    VIR_FREE(pool->autostartLink);
+    VIR_FREE(pool->stateDir);
+    return -1;
 }
 
 int
@@ -1959,6 +1987,11 @@ virStoragePoolObjDeleteDef(virStoragePoolObjPtr pool)
         return -1;
     }
 
+    if (virFileExists(pool->stateDir)) {
+        if (virFileDeleteTree(pool->stateDir) < 0)
+            return -1;
+    }
+
     return 0;
 }
 
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index 2c9eaed..064c78c 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -1,7 +1,7 @@
 /*
  * storage_conf.h: config handling for storage driver
  *
- * Copyright (C) 2006-2008, 2010-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2008, 2010-2015 Red Hat, Inc.
  * Copyright (C) 2006-2008 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -266,6 +266,7 @@ struct _virStoragePoolObj {
 
     char *configFile;
     char *autostartLink;
+    char *stateDir;
     int active;
     int autostart;
     unsigned int asyncjobs;
@@ -293,6 +294,7 @@ struct _virStorageDriverState {
 
     char *configDir;
     char *autostartDir;
+    char *stateDir;
     bool privileged;
 };
 
@@ -315,7 +317,8 @@ virStoragePoolObjIsActive(virStoragePoolObjPtr pool)
 
 int virStoragePoolLoadAllConfigs(virStoragePoolObjListPtr pools,
                                  const char *configDir,
-                                 const char *autostartDir);
+                                 const char *autostartDir,
+                                 const char *stateDir);
 
 virStoragePoolObjPtr
 virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools,
diff --git a/src/parallels/parallels_storage.c b/src/parallels/parallels_storage.c
index e916e0f..bde6ecf 100644
--- a/src/parallels/parallels_storage.c
+++ b/src/parallels/parallels_storage.c
@@ -2,7 +2,7 @@
  * parallels_storage.c: core driver functions for managing
  * Parallels Cloud Server hosts
  *
- * Copyright (C) 2013-2014 Red Hat, Inc.
+ * Copyright (C) 2013-2015 Red Hat, Inc.
  * Copyright (C) 2012 Parallels, Inc.
  *
  * This library is free software; you can redistribute it and/or
@@ -424,7 +424,8 @@ static int parallelsLoadPools(virConnectPtr conn)
 
     if (virStoragePoolLoadAllConfigs(&privconn->pools,
                                      storageState->configDir,
-                                     storageState->autostartDir) < 0) {
+                                     storageState->autostartDir,
+                                     storageState->stateDir) < 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Failed to load pool configs"));
         goto error;
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 66dc994..d2ccf1b 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -1,7 +1,7 @@
 /*
  * storage_driver.c: core driver for storage APIs
  *
- * Copyright (C) 2006-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2015 Red Hat, Inc.
  * Copyright (C) 2006-2008 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -146,7 +146,7 @@ storageDriverAutostart(void)
 /**
  * virStorageStartup:
  *
- * Initialization function for the QEmu daemon
+ * Initialization function for the Storage Driver
  */
 static int
 storageStateInitialize(bool privileged,
@@ -154,6 +154,7 @@ storageStateInitialize(bool privileged,
                        void *opaque ATTRIBUTE_UNUSED)
 {
     char *base = NULL;
+    char *rundir = NULL;
 
     if (VIR_ALLOC(driver) < 0)
         return -1;
@@ -167,10 +168,18 @@ storageStateInitialize(bool privileged,
     if (privileged) {
         if (VIR_STRDUP(base, SYSCONFDIR "/libvirt") < 0)
             goto error;
+        if (virAsprintf(&driver->stateDir,
+                        "%s/run/libvirt/storage", LOCALSTATEDIR) < 0)
+            goto error;
     } else {
         base = virGetUserConfigDirectory();
-        if (!base)
+        rundir = virGetUserRuntimeDirectory();
+        if (!(base && rundir))
+            goto error;
+
+        if (virAsprintf(&driver->stateDir, "%s/storage/run", rundir) < 0)
             goto error;
+
     }
     driver->privileged = privileged;
 
@@ -187,10 +196,19 @@ storageStateInitialize(bool privileged,
         goto error;
 
     VIR_FREE(base);
+    VIR_FREE(rundir);
+
+    if (virFileMakePath(driver->stateDir) < 0) {
+        virReportSystemError(errno,
+                             _("failed to create state directory '%s'"),
+                             driver->stateDir);
+        goto error;
+    }
 
     if (virStoragePoolLoadAllConfigs(&driver->pools,
                                      driver->configDir,
-                                     driver->autostartDir) < 0)
+                                     driver->autostartDir,
+                                     driver->stateDir) < 0)
         goto error;
 
     storageDriverUnlock();
@@ -198,6 +216,7 @@ storageStateInitialize(bool privileged,
 
  error:
     VIR_FREE(base);
+    VIR_FREE(rundir);
     storageDriverUnlock();
     storageStateCleanup();
     return -1;
@@ -234,7 +253,8 @@ storageStateReload(void)
     storageDriverLock();
     virStoragePoolLoadAllConfigs(&driver->pools,
                                  driver->configDir,
-                                 driver->autostartDir);
+                                 driver->autostartDir,
+                                 driver->stateDir);
     storageDriverAutostart();
     storageDriverUnlock();
 
@@ -260,6 +280,7 @@ storageStateCleanup(void)
 
     VIR_FREE(driver->configDir);
     VIR_FREE(driver->autostartDir);
+    VIR_FREE(driver->stateDir);
     storageDriverUnlock();
     virMutexDestroy(&driver->lock);
     VIR_FREE(driver);
@@ -743,6 +764,7 @@ storagePoolUndefine(virStoragePoolPtr obj)
 
     VIR_FREE(pool->configFile);
     VIR_FREE(pool->autostartLink);
+    VIR_FREE(pool->stateDir);
 
     VIR_INFO("Undefining storage pool '%s'", pool->def->name);
     virStoragePoolObjRemove(&driver->pools, pool);
-- 
2.1.0




More information about the libvir-list mailing list