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(a)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