Move all the StoragePoolObj related API's into their own module
virstorageobj from the storage_conf
Purely code motion at this point, plus adjustments to cleanly build
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
po/POTFILES.in | 1 +
src/Makefile.am | 3 +-
src/conf/storage_conf.c | 931 +---------------------------------------
src/conf/storage_conf.h | 116 +----
src/conf/virstorageobj.c | 968 ++++++++++++++++++++++++++++++++++++++++++
src/conf/virstorageobj.h | 142 +++++++
src/libvirt_private.syms | 35 +-
src/storage/storage_backend.h | 2 +-
src/storage/storage_driver.h | 2 +-
src/storage/storage_util.h | 1 -
src/test/test_driver.c | 1 +
11 files changed, 1137 insertions(+), 1065 deletions(-)
create mode 100644 src/conf/virstorageobj.c
create mode 100644 src/conf/virstorageobj.h
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ceda3ed..be8b366 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -46,6 +46,7 @@ src/conf/virinterfaceobj.c
src/conf/virnodedeviceobj.c
src/conf/virnwfilterobj.c
src/conf/virsecretobj.c
+src/conf/virstorageobj.c
src/cpu/cpu.c
src/cpu/cpu_arm.c
src/cpu/cpu_map.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 0257965..92634e4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -379,7 +379,8 @@ NWFILTER_CONF_SOURCES = \
# Storage driver generic impl APIs
STORAGE_CONF_SOURCES = \
- conf/storage_conf.h conf/storage_conf.c
+ conf/storage_conf.h conf/storage_conf.c \
+ conf/virstorageobj.h conf/virstorageobj.c
# Interface driver generic impl APIs
INTERFACE_CONF_SOURCES = \
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index a52eeba..58682d1 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -26,7 +26,6 @@
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
@@ -412,56 +411,6 @@ virStoragePoolDefFree(virStoragePoolDefPtr def)
}
-void
-virStoragePoolObjFree(virStoragePoolObjPtr obj)
-{
- if (!obj)
- return;
-
- virStoragePoolObjClearVols(obj);
-
- virStoragePoolDefFree(obj->def);
- virStoragePoolDefFree(obj->newDef);
-
- VIR_FREE(obj->configFile);
- VIR_FREE(obj->autostartLink);
-
- virMutexDestroy(&obj->lock);
-
- VIR_FREE(obj);
-}
-
-void
-virStoragePoolObjListFree(virStoragePoolObjListPtr pools)
-{
- size_t i;
- for (i = 0; i < pools->count; i++)
- virStoragePoolObjFree(pools->objs[i]);
- VIR_FREE(pools->objs);
- pools->count = 0;
-}
-
-void
-virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
- virStoragePoolObjPtr pool)
-{
- size_t i;
-
- virStoragePoolObjUnlock(pool);
-
- for (i = 0; i < pools->count; i++) {
- virStoragePoolObjLock(pools->objs[i]);
- if (pools->objs[i] == pool) {
- virStoragePoolObjUnlock(pools->objs[i]);
- virStoragePoolObjFree(pools->objs[i]);
-
- VIR_DELETE_ELEMENT(pools->objs, i, pools->count);
- break;
- }
- virStoragePoolObjUnlock(pools->objs[i]);
- }
-}
-
static int
virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
virStoragePoolSourcePtr source,
@@ -831,7 +780,7 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt,
return ret;
}
-static virStoragePoolDefPtr
+virStoragePoolDefPtr
virStoragePoolDefParseXML(xmlXPathContextPtr ctxt)
{
virStoragePoolOptionsPtr options;
@@ -1731,318 +1680,6 @@ virStorageVolDefFormat(virStoragePoolDefPtr pool,
}
-virStoragePoolObjPtr
-virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools,
- const unsigned char *uuid)
-{
- size_t i;
-
- for (i = 0; i < pools->count; i++) {
- virStoragePoolObjLock(pools->objs[i]);
- if (!memcmp(pools->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN))
- return pools->objs[i];
- virStoragePoolObjUnlock(pools->objs[i]);
- }
-
- return NULL;
-}
-
-virStoragePoolObjPtr
-virStoragePoolObjFindByName(virStoragePoolObjListPtr pools,
- const char *name)
-{
- size_t i;
-
- for (i = 0; i < pools->count; i++) {
- virStoragePoolObjLock(pools->objs[i]);
- if (STREQ(pools->objs[i]->def->name, name))
- return pools->objs[i];
- virStoragePoolObjUnlock(pools->objs[i]);
- }
-
- return NULL;
-}
-
-virStoragePoolObjPtr
-virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool,
- virStoragePoolDefPtr def)
-{
- size_t i, j;
-
- for (i = 0; i < pool->def->source.ndevice; i++) {
- for (j = 0; j < def->source.ndevice; j++) {
- if (STREQ(pool->def->source.devices[i].path,
def->source.devices[j].path))
- return pool;
- }
- }
-
- return NULL;
-}
-
-void
-virStoragePoolObjClearVols(virStoragePoolObjPtr pool)
-{
- size_t i;
- for (i = 0; i < pool->volumes.count; i++)
- virStorageVolDefFree(pool->volumes.objs[i]);
-
- VIR_FREE(pool->volumes.objs);
- pool->volumes.count = 0;
-}
-
-virStorageVolDefPtr
-virStorageVolDefFindByKey(virStoragePoolObjPtr pool,
- const char *key)
-{
- size_t i;
-
- for (i = 0; i < pool->volumes.count; i++)
- if (STREQ(pool->volumes.objs[i]->key, key))
- return pool->volumes.objs[i];
-
- return NULL;
-}
-
-virStorageVolDefPtr
-virStorageVolDefFindByPath(virStoragePoolObjPtr pool,
- const char *path)
-{
- size_t i;
-
- for (i = 0; i < pool->volumes.count; i++)
- if (STREQ(pool->volumes.objs[i]->target.path, path))
- return pool->volumes.objs[i];
-
- return NULL;
-}
-
-virStorageVolDefPtr
-virStorageVolDefFindByName(virStoragePoolObjPtr pool,
- const char *name)
-{
- size_t i;
-
- for (i = 0; i < pool->volumes.count; i++)
- if (STREQ(pool->volumes.objs[i]->name, name))
- return pool->volumes.objs[i];
-
- return NULL;
-}
-
-virStoragePoolObjPtr
-virStoragePoolObjAssignDef(virStoragePoolObjListPtr pools,
- virStoragePoolDefPtr def)
-{
- virStoragePoolObjPtr pool;
-
- if ((pool = virStoragePoolObjFindByName(pools, def->name))) {
- if (!virStoragePoolObjIsActive(pool)) {
- virStoragePoolDefFree(pool->def);
- pool->def = def;
- } else {
- virStoragePoolDefFree(pool->newDef);
- pool->newDef = def;
- }
- return pool;
- }
-
- if (VIR_ALLOC(pool) < 0)
- return NULL;
-
- if (virMutexInit(&pool->lock) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot initialize mutex"));
- VIR_FREE(pool);
- return NULL;
- }
- virStoragePoolObjLock(pool);
- pool->active = 0;
-
- if (VIR_APPEND_ELEMENT_COPY(pools->objs, pools->count, pool) < 0) {
- virStoragePoolObjUnlock(pool);
- virStoragePoolObjFree(pool);
- return NULL;
- }
- pool->def = def;
-
- return pool;
-}
-
-static virStoragePoolObjPtr
-virStoragePoolObjLoad(virStoragePoolObjListPtr pools,
- const char *file,
- const char *path,
- const char *autostartLink)
-{
- virStoragePoolDefPtr def;
- virStoragePoolObjPtr pool;
-
- if (!(def = virStoragePoolDefParseFile(path)))
- return NULL;
-
- if (!virFileMatchesNameSuffix(file, def->name, ".xml")) {
- virReportError(VIR_ERR_XML_ERROR,
- _("Storage pool config filename '%s' does "
- "not match pool name '%s'"),
- path, def->name);
- virStoragePoolDefFree(def);
- return NULL;
- }
-
- if (!(pool = virStoragePoolObjAssignDef(pools, def))) {
- virStoragePoolDefFree(def);
- return NULL;
- }
-
- VIR_FREE(pool->configFile); /* for driver reload */
- if (VIR_STRDUP(pool->configFile, path) < 0) {
- virStoragePoolObjRemove(pools, pool);
- return NULL;
- }
- VIR_FREE(pool->autostartLink); /* for driver reload */
- if (VIR_STRDUP(pool->autostartLink, autostartLink) < 0) {
- virStoragePoolObjRemove(pools, pool);
- return NULL;
- }
-
- pool->autostart = virFileLinkPointsTo(pool->autostartLink,
- pool->configFile);
-
- return pool;
-}
-
-
-virStoragePoolObjPtr
-virStoragePoolLoadState(virStoragePoolObjListPtr pools,
- const char *stateDir,
- const char *name)
-{
- char *stateFile = NULL;
- virStoragePoolDefPtr def = NULL;
- virStoragePoolObjPtr pool = NULL;
- xmlDocPtr xml = NULL;
- xmlXPathContextPtr ctxt = NULL;
- xmlNodePtr node = NULL;
-
- if (!(stateFile = virFileBuildPath(stateDir, name, ".xml")))
- goto error;
-
- if (!(xml = virXMLParseCtxt(stateFile, NULL, _("(pool state)"),
&ctxt)))
- goto error;
-
- if (!(node = virXPathNode("//pool", ctxt))) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Could not find any 'pool' element in state
file"));
- goto error;
- }
-
- ctxt->node = node;
- if (!(def = virStoragePoolDefParseXML(ctxt)))
- goto error;
-
- if (STRNEQ(name, def->name)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Storage pool state file '%s' does not match
"
- "pool name '%s'"),
- stateFile, def->name);
- goto error;
- }
-
- /* create the object */
- if (!(pool = virStoragePoolObjAssignDef(pools, def)))
- goto error;
-
- /* XXX: future handling of some additional useful status data,
- * for now, if a status file for a pool exists, the pool will be marked
- * as active
- */
-
- pool->active = 1;
-
- cleanup:
- VIR_FREE(stateFile);
- xmlFreeDoc(xml);
- xmlXPathFreeContext(ctxt);
- return pool;
-
- error:
- virStoragePoolDefFree(def);
- goto cleanup;
-}
-
-
-int
-virStoragePoolLoadAllState(virStoragePoolObjListPtr pools,
- const char *stateDir)
-{
- DIR *dir;
- struct dirent *entry;
- int ret = -1;
- int rc;
-
- if ((rc = virDirOpenIfExists(&dir, stateDir)) <= 0)
- return rc;
-
- while ((ret = virDirRead(dir, &entry, stateDir)) > 0) {
- virStoragePoolObjPtr pool;
-
- if (!virFileStripSuffix(entry->d_name, ".xml"))
- continue;
-
- if (!(pool = virStoragePoolLoadState(pools, stateDir, entry->d_name)))
- continue;
- virStoragePoolObjUnlock(pool);
- }
-
- VIR_DIR_CLOSE(dir);
- return ret;
-}
-
-
-int
-virStoragePoolLoadAllConfigs(virStoragePoolObjListPtr pools,
- const char *configDir,
- const char *autostartDir)
-{
- DIR *dir;
- struct dirent *entry;
- int ret;
- int rc;
-
- if ((rc = virDirOpenIfExists(&dir, configDir)) <= 0)
- return rc;
-
- while ((ret = virDirRead(dir, &entry, configDir)) > 0) {
- char *path;
- char *autostartLink;
- virStoragePoolObjPtr pool;
-
- if (!virFileHasSuffix(entry->d_name, ".xml"))
- continue;
-
- if (!(path = virFileBuildPath(configDir, entry->d_name, NULL)))
- continue;
-
- if (!(autostartLink = virFileBuildPath(autostartDir, entry->d_name,
- NULL))) {
- VIR_FREE(path);
- continue;
- }
-
- pool = virStoragePoolObjLoad(pools, entry->d_name, path,
- autostartLink);
- if (pool)
- virStoragePoolObjUnlock(pool);
-
- VIR_FREE(path);
- VIR_FREE(autostartLink);
- }
-
- VIR_DIR_CLOSE(dir);
- return ret;
-}
-
-
static int virStoragePoolSaveXML(const char *path,
virStoragePoolDefPtr def,
const char *xml)
@@ -2115,52 +1752,6 @@ virStoragePoolSaveConfig(const char *configFile,
return ret;
}
-int
-virStoragePoolObjSaveDef(virStorageDriverStatePtr driver,
- virStoragePoolObjPtr pool,
- virStoragePoolDefPtr def)
-{
- if (!pool->configFile) {
- if (virFileMakePath(driver->configDir) < 0) {
- virReportSystemError(errno,
- _("cannot create config directory %s"),
- driver->configDir);
- return -1;
- }
-
- if (!(pool->configFile = virFileBuildPath(driver->configDir,
- def->name, ".xml"))) {
- return -1;
- }
-
- if (!(pool->autostartLink = virFileBuildPath(driver->autostartDir,
- def->name, ".xml"))) {
- VIR_FREE(pool->configFile);
- return -1;
- }
- }
-
- return virStoragePoolSaveConfig(pool->configFile, def);
-}
-
-int
-virStoragePoolObjDeleteDef(virStoragePoolObjPtr pool)
-{
- if (!pool->configFile) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("no config file for %s"), pool->def->name);
- return -1;
- }
-
- if (unlink(pool->configFile) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot remove config for %s"),
- pool->def->name);
- return -1;
- }
-
- return 0;
-}
virStoragePoolSourcePtr
virStoragePoolSourceListNewSource(virStoragePoolSourceListPtr list)
@@ -2213,523 +1804,3 @@ virStoragePoolSourceListFormat(virStoragePoolSourceListPtr def)
virBufferFreeAndReset(&buf);
return NULL;
}
-
-
-/*
- * virStoragePoolObjIsDuplicate:
- * @doms : virStoragePoolObjListPtr to search
- * @def : virStoragePoolDefPtr definition of pool to lookup
- * @check_active: If true, ensure that pool is not active
- *
- * Returns: -1 on error
- * 0 if pool is new
- * 1 if pool is a duplicate
- */
-int
-virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools,
- virStoragePoolDefPtr def,
- unsigned int check_active)
-{
- int ret = -1;
- virStoragePoolObjPtr pool = NULL;
-
- /* See if a Pool with matching UUID already exists */
- pool = virStoragePoolObjFindByUUID(pools, def->uuid);
- if (pool) {
- /* UUID matches, but if names don't match, refuse it */
- if (STRNEQ(pool->def->name, def->name)) {
- char uuidstr[VIR_UUID_STRING_BUFLEN];
- virUUIDFormat(pool->def->uuid, uuidstr);
- virReportError(VIR_ERR_OPERATION_FAILED,
- _("pool '%s' is already defined with uuid
%s"),
- pool->def->name, uuidstr);
- goto cleanup;
- }
-
- if (check_active) {
- /* UUID & name match, but if Pool is already active, refuse it */
- if (virStoragePoolObjIsActive(pool)) {
- virReportError(VIR_ERR_OPERATION_INVALID,
- _("pool is already active as '%s'"),
- pool->def->name);
- goto cleanup;
- }
- }
-
- ret = 1;
- } else {
- /* UUID does not match, but if a name matches, refuse it */
- pool = virStoragePoolObjFindByName(pools, def->name);
- if (pool) {
- char uuidstr[VIR_UUID_STRING_BUFLEN];
- virUUIDFormat(pool->def->uuid, uuidstr);
- virReportError(VIR_ERR_OPERATION_FAILED,
- _("pool '%s' already exists with uuid %s"),
- def->name, uuidstr);
- goto cleanup;
- }
- ret = 0;
- }
-
- cleanup:
- if (pool)
- virStoragePoolObjUnlock(pool);
- return ret;
-}
-
-
-static int
-getSCSIHostNumber(virStoragePoolSourceAdapter adapter,
- unsigned int *hostnum)
-{
- int ret = -1;
- unsigned int num;
- char *name = NULL;
-
- if (adapter.data.scsi_host.has_parent) {
- virPCIDeviceAddress addr = adapter.data.scsi_host.parentaddr;
- unsigned int unique_id = adapter.data.scsi_host.unique_id;
-
- if (!(name = virSCSIHostGetNameByParentaddr(addr.domain,
- addr.bus,
- addr.slot,
- addr.function,
- unique_id)))
- goto cleanup;
- if (virSCSIHostGetNumber(name, &num) < 0)
- goto cleanup;
- } else {
- if (virSCSIHostGetNumber(adapter.data.scsi_host.name, &num) < 0)
- goto cleanup;
- }
-
- *hostnum = num;
- ret = 0;
-
- cleanup:
- VIR_FREE(name);
- return ret;
-}
-
-
-static bool
-virStorageIsSameHostnum(const char *name,
- unsigned int scsi_hostnum)
-{
- unsigned int fc_hostnum;
-
- if (virSCSIHostGetNumber(name, &fc_hostnum) == 0 &&
- scsi_hostnum == fc_hostnum)
- return true;
-
- return false;
-}
-
-
-/*
- * matchFCHostToSCSIHost:
- *
- * @conn: Connection pointer
- * @fc_adapter: fc_host adapter (either def or pool->def)
- * @scsi_hostnum: Already determined "scsi_pool" hostnum
- *
- * Returns true/false whether there is a match between the incoming
- * fc_adapter host# and the scsi_host host#
- */
-static bool
-matchFCHostToSCSIHost(virConnectPtr conn,
- virStoragePoolSourceAdapter fc_adapter,
- unsigned int scsi_hostnum)
-{
- bool ret = false;
- char *name = NULL;
- char *scsi_host_name = NULL;
- char *parent_name = NULL;
-
- /* If we have a parent defined, get its hostnum, and compare to the
- * scsi_hostnum. If they are the same, then we have a match
- */
- if (fc_adapter.data.fchost.parent &&
- virStorageIsSameHostnum(fc_adapter.data.fchost.parent, scsi_hostnum))
- return true;
-
- /* If we find an fc_adapter name, then either libvirt created a vHBA
- * for this fc_host or a 'virsh nodedev-create' generated a vHBA.
- */
- if ((name = virVHBAGetHostByWWN(NULL, fc_adapter.data.fchost.wwnn,
- fc_adapter.data.fchost.wwpn))) {
-
- /* Get the scsi_hostN for the vHBA in order to see if it
- * matches our scsi_hostnum
- */
- if (virStorageIsSameHostnum(name, scsi_hostnum)) {
- ret = true;
- goto cleanup;
- }
-
- /* We weren't provided a parent, so we have to query the node
- * device driver in order to ascertain the parent of the vHBA.
- * If the parent fc_hostnum is the same as the scsi_hostnum, we
- * have a match.
- */
- if (conn && !fc_adapter.data.fchost.parent) {
- if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0)
- goto cleanup;
- if ((parent_name = virNodeDeviceGetParentName(conn,
- scsi_host_name))) {
- if (virStorageIsSameHostnum(parent_name, scsi_hostnum)) {
- ret = true;
- goto cleanup;
- }
- } else {
- /* Throw away the error and fall through */
- virResetLastError();
- VIR_DEBUG("Could not determine parent vHBA");
- }
- }
- }
-
- /* NB: Lack of a name means that this vHBA hasn't yet been created,
- * which means our scsi_host cannot be using the vHBA. Furthermore,
- * lack of a provided parent means libvirt is going to choose the
- * "best" fc_host capable adapter based on availabilty. That could
- * conflict with an existing scsi_host definition, but there's no
- * way to know that now.
- */
-
- cleanup:
- VIR_FREE(name);
- VIR_FREE(parent_name);
- VIR_FREE(scsi_host_name);
- return ret;
-}
-
-static bool
-matchSCSIAdapterParent(virStoragePoolObjPtr pool,
- virStoragePoolDefPtr def)
-{
- virPCIDeviceAddressPtr pooladdr =
- &pool->def->source.adapter.data.scsi_host.parentaddr;
- virPCIDeviceAddressPtr defaddr =
- &def->source.adapter.data.scsi_host.parentaddr;
- int pool_unique_id =
- pool->def->source.adapter.data.scsi_host.unique_id;
- int def_unique_id =
- def->source.adapter.data.scsi_host.unique_id;
- if (pooladdr->domain == defaddr->domain &&
- pooladdr->bus == defaddr->bus &&
- pooladdr->slot == defaddr->slot &&
- pooladdr->function == defaddr->function &&
- pool_unique_id == def_unique_id) {
- return true;
- }
- return false;
-}
-
-static bool
-virStoragePoolSourceMatchSingleHost(virStoragePoolSourcePtr poolsrc,
- virStoragePoolSourcePtr defsrc)
-{
- if (poolsrc->nhost != 1 && defsrc->nhost != 1)
- return false;
-
- if (defsrc->hosts[0].port &&
- poolsrc->hosts[0].port != defsrc->hosts[0].port)
- return false;
-
- return STREQ(poolsrc->hosts[0].name, defsrc->hosts[0].name);
-}
-
-
-static bool
-virStoragePoolSourceISCSIMatch(virStoragePoolObjPtr matchpool,
- virStoragePoolDefPtr def)
-{
- virStoragePoolSourcePtr poolsrc = &matchpool->def->source;
- virStoragePoolSourcePtr defsrc = &def->source;
-
- /* NB: Do not check the source host name */
- if (STRNEQ_NULLABLE(poolsrc->initiator.iqn, defsrc->initiator.iqn))
- return false;
-
- return true;
-}
-
-
-int
-virStoragePoolSourceFindDuplicate(virConnectPtr conn,
- virStoragePoolObjListPtr pools,
- virStoragePoolDefPtr def)
-{
- size_t i;
- int ret = 1;
- virStoragePoolObjPtr pool = NULL;
- virStoragePoolObjPtr matchpool = NULL;
-
- /* Check the pool list for duplicate underlying storage */
- for (i = 0; i < pools->count; i++) {
- pool = pools->objs[i];
- if (def->type != pool->def->type)
- continue;
-
- /* Don't match against ourself if re-defining existing pool ! */
- if (STREQ(pool->def->name, def->name))
- continue;
-
- virStoragePoolObjLock(pool);
-
- switch ((virStoragePoolType)pool->def->type) {
- case VIR_STORAGE_POOL_DIR:
- if (STREQ(pool->def->target.path, def->target.path))
- matchpool = pool;
- break;
-
- case VIR_STORAGE_POOL_GLUSTER:
- if (STREQ(pool->def->source.name, def->source.name) &&
- STREQ_NULLABLE(pool->def->source.dir, def->source.dir)
&&
- virStoragePoolSourceMatchSingleHost(&pool->def->source,
- &def->source))
- matchpool = pool;
- break;
-
- case VIR_STORAGE_POOL_NETFS:
- if (STREQ(pool->def->source.dir, def->source.dir) &&
- virStoragePoolSourceMatchSingleHost(&pool->def->source,
- &def->source))
- matchpool = pool;
- break;
-
- case VIR_STORAGE_POOL_SCSI:
- if (pool->def->source.adapter.type ==
- VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST &&
- def->source.adapter.type ==
- VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) {
- if (STREQ(pool->def->source.adapter.data.fchost.wwnn,
- def->source.adapter.data.fchost.wwnn) &&
- STREQ(pool->def->source.adapter.data.fchost.wwpn,
- def->source.adapter.data.fchost.wwpn))
- matchpool = pool;
- } else if (pool->def->source.adapter.type ==
- VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST &&
- def->source.adapter.type ==
- VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) {
- unsigned int pool_hostnum, def_hostnum;
-
- if (pool->def->source.adapter.data.scsi_host.has_parent &&
- def->source.adapter.data.scsi_host.has_parent &&
- matchSCSIAdapterParent(pool, def)) {
- matchpool = pool;
- break;
- }
-
- if (getSCSIHostNumber(pool->def->source.adapter,
- &pool_hostnum) < 0 ||
- getSCSIHostNumber(def->source.adapter, &def_hostnum) < 0)
- break;
- if (pool_hostnum == def_hostnum)
- matchpool = pool;
- } else if (pool->def->source.adapter.type ==
- VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST &&
- def->source.adapter.type ==
- VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) {
- unsigned int scsi_hostnum;
-
- /* Get the scsi_hostN for the scsi_host source adapter def */
- if (getSCSIHostNumber(def->source.adapter,
- &scsi_hostnum) < 0)
- break;
-
- if (matchFCHostToSCSIHost(conn, pool->def->source.adapter,
- scsi_hostnum)) {
- matchpool = pool;
- break;
- }
-
- } else if (pool->def->source.adapter.type ==
- VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST &&
- def->source.adapter.type ==
- VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) {
- unsigned int scsi_hostnum;
-
- if (getSCSIHostNumber(pool->def->source.adapter,
- &scsi_hostnum) < 0)
- break;
-
- if (matchFCHostToSCSIHost(conn, def->source.adapter,
- scsi_hostnum)) {
- matchpool = pool;
- break;
- }
- }
- break;
- case VIR_STORAGE_POOL_ISCSI:
- matchpool = virStoragePoolSourceFindDuplicateDevices(pool, def);
- if (matchpool) {
- if (!virStoragePoolSourceISCSIMatch(matchpool, def))
- matchpool = NULL;
- }
- break;
- case VIR_STORAGE_POOL_FS:
- case VIR_STORAGE_POOL_LOGICAL:
- case VIR_STORAGE_POOL_DISK:
- case VIR_STORAGE_POOL_ZFS:
- matchpool = virStoragePoolSourceFindDuplicateDevices(pool, def);
- break;
- case VIR_STORAGE_POOL_SHEEPDOG:
- if (virStoragePoolSourceMatchSingleHost(&pool->def->source,
- &def->source))
- matchpool = pool;
- break;
- case VIR_STORAGE_POOL_MPATH:
- /* Only one mpath pool is valid per host */
- matchpool = pool;
- break;
- case VIR_STORAGE_POOL_VSTORAGE:
- if (STREQ(pool->def->source.name, def->source.name))
- matchpool = pool;
- break;
- case VIR_STORAGE_POOL_RBD:
- case VIR_STORAGE_POOL_LAST:
- break;
- }
- virStoragePoolObjUnlock(pool);
-
- if (matchpool)
- break;
- }
-
- if (matchpool) {
- virReportError(VIR_ERR_OPERATION_FAILED,
- _("Storage source conflict with pool: '%s'"),
- matchpool->def->name);
- ret = -1;
- }
- return ret;
-}
-
-void
-virStoragePoolObjLock(virStoragePoolObjPtr obj)
-{
- virMutexLock(&obj->lock);
-}
-
-void
-virStoragePoolObjUnlock(virStoragePoolObjPtr obj)
-{
- virMutexUnlock(&obj->lock);
-}
-
-#define MATCH(FLAG) (flags & (FLAG))
-static bool
-virStoragePoolMatch(virStoragePoolObjPtr poolobj,
- unsigned int flags)
-{
- /* filter by active state */
- if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ACTIVE) &&
- !((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE) &&
- virStoragePoolObjIsActive(poolobj)) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE) &&
- !virStoragePoolObjIsActive(poolobj))))
- return false;
-
- /* filter by persistence */
- if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_PERSISTENT) &&
- !((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_PERSISTENT) &&
- poolobj->configFile) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_TRANSIENT) &&
- !poolobj->configFile)))
- return false;
-
- /* filter by autostart option */
- if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_AUTOSTART) &&
- !((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_AUTOSTART) &&
- poolobj->autostart) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_NO_AUTOSTART) &&
- !poolobj->autostart)))
- return false;
-
- /* filter by pool type */
- if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_POOL_TYPE)) {
- if (!((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_DIR) &&
- (poolobj->def->type == VIR_STORAGE_POOL_DIR)) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FS) &&
- (poolobj->def->type == VIR_STORAGE_POOL_FS)) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_NETFS) &&
- (poolobj->def->type == VIR_STORAGE_POOL_NETFS)) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_LOGICAL) &&
- (poolobj->def->type == VIR_STORAGE_POOL_LOGICAL)) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_DISK) &&
- (poolobj->def->type == VIR_STORAGE_POOL_DISK)) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI) &&
- (poolobj->def->type == VIR_STORAGE_POOL_ISCSI)) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_SCSI) &&
- (poolobj->def->type == VIR_STORAGE_POOL_SCSI)) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_MPATH) &&
- (poolobj->def->type == VIR_STORAGE_POOL_MPATH)) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_RBD) &&
- (poolobj->def->type == VIR_STORAGE_POOL_RBD)) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG) &&
- (poolobj->def->type == VIR_STORAGE_POOL_SHEEPDOG)) ||
- (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER) &&
- (poolobj->def->type == VIR_STORAGE_POOL_GLUSTER))))
- return false;
- }
-
- return true;
-}
-#undef MATCH
-
-int
-virStoragePoolObjListExport(virConnectPtr conn,
- virStoragePoolObjList poolobjs,
- virStoragePoolPtr **pools,
- virStoragePoolObjListFilter filter,
- unsigned int flags)
-{
- virStoragePoolPtr *tmp_pools = NULL;
- virStoragePoolPtr pool = NULL;
- int npools = 0;
- int ret = -1;
- size_t i;
-
- if (pools && VIR_ALLOC_N(tmp_pools, poolobjs.count + 1) < 0)
- goto cleanup;
-
- for (i = 0; i < poolobjs.count; i++) {
- virStoragePoolObjPtr poolobj = poolobjs.objs[i];
- virStoragePoolObjLock(poolobj);
- if ((!filter || filter(conn, poolobj->def)) &&
- virStoragePoolMatch(poolobj, flags)) {
- if (pools) {
- if (!(pool = virGetStoragePool(conn,
- poolobj->def->name,
- poolobj->def->uuid,
- NULL, NULL))) {
- virStoragePoolObjUnlock(poolobj);
- goto cleanup;
- }
- tmp_pools[npools] = pool;
- }
- npools++;
- }
- virStoragePoolObjUnlock(poolobj);
- }
-
- if (tmp_pools) {
- /* trim the array to the final size */
- ignore_value(VIR_REALLOC_N(tmp_pools, npools + 1));
- *pools = tmp_pools;
- tmp_pools = NULL;
- }
-
- ret = npools;
-
- cleanup:
- if (tmp_pools) {
- for (i = 0; i < npools; i++)
- virObjectUnref(tmp_pools[i]);
- }
-
- VIR_FREE(tmp_pools);
- return ret;
-}
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index 1723afc..b5753c3 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -263,48 +263,6 @@ struct _virStoragePoolDef {
virStoragePoolTarget target;
};
-typedef struct _virStoragePoolObj virStoragePoolObj;
-typedef virStoragePoolObj *virStoragePoolObjPtr;
-
-struct _virStoragePoolObj {
- virMutex lock;
-
- char *configFile;
- char *autostartLink;
- bool active;
- int autostart;
- unsigned int asyncjobs;
-
- virStoragePoolDefPtr def;
- virStoragePoolDefPtr newDef;
-
- virStorageVolDefList volumes;
-};
-
-typedef struct _virStoragePoolObjList virStoragePoolObjList;
-typedef virStoragePoolObjList *virStoragePoolObjListPtr;
-struct _virStoragePoolObjList {
- size_t count;
- virStoragePoolObjPtr *objs;
-};
-
-typedef struct _virStorageDriverState virStorageDriverState;
-typedef virStorageDriverState *virStorageDriverStatePtr;
-
-struct _virStorageDriverState {
- virMutex lock;
-
- virStoragePoolObjList pools;
-
- char *configDir;
- char *autostartDir;
- char *stateDir;
- bool privileged;
-
- /* Immutable pointer, self-locking APIs */
- virObjectEventStatePtr storageEventState;
-};
-
typedef struct _virStoragePoolSourceList virStoragePoolSourceList;
typedef virStoragePoolSourceList *virStoragePoolSourceListPtr;
struct _virStoragePoolSourceList {
@@ -313,48 +271,7 @@ struct _virStoragePoolSourceList {
virStoragePoolSourcePtr sources;
};
-typedef bool (*virStoragePoolObjListFilter)(virConnectPtr conn,
- virStoragePoolDefPtr def);
-
-static inline int
-virStoragePoolObjIsActive(virStoragePoolObjPtr pool)
-{
- return pool->active;
-}
-
-int virStoragePoolLoadAllConfigs(virStoragePoolObjListPtr pools,
- const char *configDir,
- const char *autostartDir);
-
-int virStoragePoolLoadAllState(virStoragePoolObjListPtr pools,
- const char *stateDir);
-
-virStoragePoolObjPtr
-virStoragePoolLoadState(virStoragePoolObjListPtr pools,
- const char *stateDir,
- const char *name);
-virStoragePoolObjPtr
-virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools,
- const unsigned char *uuid);
-virStoragePoolObjPtr
-virStoragePoolObjFindByName(virStoragePoolObjListPtr pools,
- const char *name);
-virStoragePoolObjPtr
-virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool,
- virStoragePoolDefPtr def);
-
-virStorageVolDefPtr
-virStorageVolDefFindByKey(virStoragePoolObjPtr pool,
- const char *key);
-virStorageVolDefPtr
-virStorageVolDefFindByPath(virStoragePoolObjPtr pool,
- const char *path);
-virStorageVolDefPtr
-virStorageVolDefFindByName(virStoragePoolObjPtr pool,
- const char *name);
-
-void virStoragePoolObjClearVols(virStoragePoolObjPtr pool);
-
+virStoragePoolDefPtr virStoragePoolDefParseXML(xmlXPathContextPtr ctxt);
virStoragePoolDefPtr virStoragePoolDefParseString(const char *xml);
virStoragePoolDefPtr virStoragePoolDefParseFile(const char *filename);
virStoragePoolDefPtr virStoragePoolDefParseNode(xmlDocPtr xml,
@@ -383,28 +300,15 @@ virStorageVolDefParseNode(virStoragePoolDefPtr pool,
char *virStorageVolDefFormat(virStoragePoolDefPtr pool,
virStorageVolDefPtr def);
-virStoragePoolObjPtr
-virStoragePoolObjAssignDef(virStoragePoolObjListPtr pools,
- virStoragePoolDefPtr def);
-
int virStoragePoolSaveState(const char *stateFile,
virStoragePoolDefPtr def);
int virStoragePoolSaveConfig(const char *configFile,
virStoragePoolDefPtr def);
-int virStoragePoolObjSaveDef(virStorageDriverStatePtr driver,
- virStoragePoolObjPtr pool,
- virStoragePoolDefPtr def);
-int virStoragePoolObjDeleteDef(virStoragePoolObjPtr pool);
-
void virStorageVolDefFree(virStorageVolDefPtr def);
void virStoragePoolSourceClear(virStoragePoolSourcePtr source);
void virStoragePoolSourceDeviceClear(virStoragePoolSourceDevicePtr dev);
void virStoragePoolSourceFree(virStoragePoolSourcePtr source);
void virStoragePoolDefFree(virStoragePoolDefPtr def);
-void virStoragePoolObjFree(virStoragePoolObjPtr pool);
-void virStoragePoolObjListFree(virStoragePoolObjListPtr pools);
-void virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
- virStoragePoolObjPtr pool);
virStoragePoolSourcePtr
virStoragePoolDefParseSourceString(const char *srcSpec,
@@ -413,18 +317,6 @@ virStoragePoolSourcePtr
virStoragePoolSourceListNewSource(virStoragePoolSourceListPtr list);
char *virStoragePoolSourceListFormat(virStoragePoolSourceListPtr def);
-int virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools,
- virStoragePoolDefPtr def,
- unsigned int check_active);
-
-int virStoragePoolSourceFindDuplicate(virConnectPtr conn,
- virStoragePoolObjListPtr pools,
- virStoragePoolDefPtr def);
-
-void virStoragePoolObjLock(virStoragePoolObjPtr obj);
-void virStoragePoolObjUnlock(virStoragePoolObjPtr obj);
-
-
typedef enum {
VIR_STORAGE_POOL_FS_AUTO = 0,
VIR_STORAGE_POOL_FS_EXT2,
@@ -552,10 +444,4 @@ VIR_ENUM_DECL(virStoragePartedFs)
VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_AUTOSTART | \
VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_POOL_TYPE)
-int virStoragePoolObjListExport(virConnectPtr conn,
- virStoragePoolObjList poolobjs,
- virStoragePoolPtr **pools,
- virStoragePoolObjListFilter filter,
- unsigned int flags);
-
#endif /* __VIR_STORAGE_CONF_H__ */
diff --git a/src/conf/virstorageobj.c b/src/conf/virstorageobj.c
new file mode 100644
index 0000000..5c0f827
--- /dev/null
+++ b/src/conf/virstorageobj.c
@@ -0,0 +1,968 @@
+/*
+ * virstorageobj.c: internal storage pool and volume objects handling
+ * (derived from storage_conf.c)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <dirent.h>
+
+#include "datatypes.h"
+#include "node_device_conf.h"
+#include "virstorageobj.h"
+
+#include "viralloc.h"
+#include "virerror.h"
+#include "virfile.h"
+#include "virlog.h"
+#include "virscsihost.h"
+#include "virstring.h"
+#include "virvhba.h"
+
+#define VIR_FROM_THIS VIR_FROM_STORAGE
+
+VIR_LOG_INIT("conf.virstorageobj");
+
+
+void
+virStoragePoolObjFree(virStoragePoolObjPtr obj)
+{
+ if (!obj)
+ return;
+
+ virStoragePoolObjClearVols(obj);
+
+ virStoragePoolDefFree(obj->def);
+ virStoragePoolDefFree(obj->newDef);
+
+ VIR_FREE(obj->configFile);
+ VIR_FREE(obj->autostartLink);
+
+ virMutexDestroy(&obj->lock);
+
+ VIR_FREE(obj);
+}
+
+void
+virStoragePoolObjListFree(virStoragePoolObjListPtr pools)
+{
+ size_t i;
+ for (i = 0; i < pools->count; i++)
+ virStoragePoolObjFree(pools->objs[i]);
+ VIR_FREE(pools->objs);
+ pools->count = 0;
+}
+
+void
+virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
+ virStoragePoolObjPtr pool)
+{
+ size_t i;
+
+ virStoragePoolObjUnlock(pool);
+
+ for (i = 0; i < pools->count; i++) {
+ virStoragePoolObjLock(pools->objs[i]);
+ if (pools->objs[i] == pool) {
+ virStoragePoolObjUnlock(pools->objs[i]);
+ virStoragePoolObjFree(pools->objs[i]);
+
+ VIR_DELETE_ELEMENT(pools->objs, i, pools->count);
+ break;
+ }
+ virStoragePoolObjUnlock(pools->objs[i]);
+ }
+}
+
+
+virStoragePoolObjPtr
+virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools,
+ const unsigned char *uuid)
+{
+ size_t i;
+
+ for (i = 0; i < pools->count; i++) {
+ virStoragePoolObjLock(pools->objs[i]);
+ if (!memcmp(pools->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN))
+ return pools->objs[i];
+ virStoragePoolObjUnlock(pools->objs[i]);
+ }
+
+ return NULL;
+}
+
+virStoragePoolObjPtr
+virStoragePoolObjFindByName(virStoragePoolObjListPtr pools,
+ const char *name)
+{
+ size_t i;
+
+ for (i = 0; i < pools->count; i++) {
+ virStoragePoolObjLock(pools->objs[i]);
+ if (STREQ(pools->objs[i]->def->name, name))
+ return pools->objs[i];
+ virStoragePoolObjUnlock(pools->objs[i]);
+ }
+
+ return NULL;
+}
+
+virStoragePoolObjPtr
+virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool,
+ virStoragePoolDefPtr def)
+{
+ size_t i, j;
+
+ for (i = 0; i < pool->def->source.ndevice; i++) {
+ for (j = 0; j < def->source.ndevice; j++) {
+ if (STREQ(pool->def->source.devices[i].path,
def->source.devices[j].path))
+ return pool;
+ }
+ }
+
+ return NULL;
+}
+
+void
+virStoragePoolObjClearVols(virStoragePoolObjPtr pool)
+{
+ size_t i;
+ for (i = 0; i < pool->volumes.count; i++)
+ virStorageVolDefFree(pool->volumes.objs[i]);
+
+ VIR_FREE(pool->volumes.objs);
+ pool->volumes.count = 0;
+}
+
+virStorageVolDefPtr
+virStorageVolDefFindByKey(virStoragePoolObjPtr pool,
+ const char *key)
+{
+ size_t i;
+
+ for (i = 0; i < pool->volumes.count; i++)
+ if (STREQ(pool->volumes.objs[i]->key, key))
+ return pool->volumes.objs[i];
+
+ return NULL;
+}
+
+virStorageVolDefPtr
+virStorageVolDefFindByPath(virStoragePoolObjPtr pool,
+ const char *path)
+{
+ size_t i;
+
+ for (i = 0; i < pool->volumes.count; i++)
+ if (STREQ(pool->volumes.objs[i]->target.path, path))
+ return pool->volumes.objs[i];
+
+ return NULL;
+}
+
+virStorageVolDefPtr
+virStorageVolDefFindByName(virStoragePoolObjPtr pool,
+ const char *name)
+{
+ size_t i;
+
+ for (i = 0; i < pool->volumes.count; i++)
+ if (STREQ(pool->volumes.objs[i]->name, name))
+ return pool->volumes.objs[i];
+
+ return NULL;
+}
+
+virStoragePoolObjPtr
+virStoragePoolObjAssignDef(virStoragePoolObjListPtr pools,
+ virStoragePoolDefPtr def)
+{
+ virStoragePoolObjPtr pool;
+
+ if ((pool = virStoragePoolObjFindByName(pools, def->name))) {
+ if (!virStoragePoolObjIsActive(pool)) {
+ virStoragePoolDefFree(pool->def);
+ pool->def = def;
+ } else {
+ virStoragePoolDefFree(pool->newDef);
+ pool->newDef = def;
+ }
+ return pool;
+ }
+
+ if (VIR_ALLOC(pool) < 0)
+ return NULL;
+
+ if (virMutexInit(&pool->lock) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot initialize mutex"));
+ VIR_FREE(pool);
+ return NULL;
+ }
+ virStoragePoolObjLock(pool);
+ pool->active = 0;
+
+ if (VIR_APPEND_ELEMENT_COPY(pools->objs, pools->count, pool) < 0) {
+ virStoragePoolObjUnlock(pool);
+ virStoragePoolObjFree(pool);
+ return NULL;
+ }
+ pool->def = def;
+
+ return pool;
+}
+
+static virStoragePoolObjPtr
+virStoragePoolObjLoad(virStoragePoolObjListPtr pools,
+ const char *file,
+ const char *path,
+ const char *autostartLink)
+{
+ virStoragePoolDefPtr def;
+ virStoragePoolObjPtr pool;
+
+ if (!(def = virStoragePoolDefParseFile(path)))
+ return NULL;
+
+ if (!virFileMatchesNameSuffix(file, def->name, ".xml")) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Storage pool config filename '%s' does "
+ "not match pool name '%s'"),
+ path, def->name);
+ virStoragePoolDefFree(def);
+ return NULL;
+ }
+
+ if (!(pool = virStoragePoolObjAssignDef(pools, def))) {
+ virStoragePoolDefFree(def);
+ return NULL;
+ }
+
+ VIR_FREE(pool->configFile); /* for driver reload */
+ if (VIR_STRDUP(pool->configFile, path) < 0) {
+ virStoragePoolObjRemove(pools, pool);
+ return NULL;
+ }
+ VIR_FREE(pool->autostartLink); /* for driver reload */
+ if (VIR_STRDUP(pool->autostartLink, autostartLink) < 0) {
+ virStoragePoolObjRemove(pools, pool);
+ return NULL;
+ }
+
+ pool->autostart = virFileLinkPointsTo(pool->autostartLink,
+ pool->configFile);
+
+ return pool;
+}
+
+
+virStoragePoolObjPtr
+virStoragePoolLoadState(virStoragePoolObjListPtr pools,
+ const char *stateDir,
+ const char *name)
+{
+ char *stateFile = NULL;
+ virStoragePoolDefPtr def = NULL;
+ virStoragePoolObjPtr pool = NULL;
+ xmlDocPtr xml = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ xmlNodePtr node = NULL;
+
+ if (!(stateFile = virFileBuildPath(stateDir, name, ".xml")))
+ goto error;
+
+ if (!(xml = virXMLParseCtxt(stateFile, NULL, _("(pool state)"),
&ctxt)))
+ goto error;
+
+ if (!(node = virXPathNode("//pool", ctxt))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not find any 'pool' element in state
file"));
+ goto error;
+ }
+
+ ctxt->node = node;
+ if (!(def = virStoragePoolDefParseXML(ctxt)))
+ goto error;
+
+ if (STRNEQ(name, def->name)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Storage pool state file '%s' does not match
"
+ "pool name '%s'"),
+ stateFile, def->name);
+ goto error;
+ }
+
+ /* create the object */
+ if (!(pool = virStoragePoolObjAssignDef(pools, def)))
+ goto error;
+
+ /* XXX: future handling of some additional useful status data,
+ * for now, if a status file for a pool exists, the pool will be marked
+ * as active
+ */
+
+ pool->active = 1;
+
+ cleanup:
+ VIR_FREE(stateFile);
+ xmlFreeDoc(xml);
+ xmlXPathFreeContext(ctxt);
+ return pool;
+
+ error:
+ virStoragePoolDefFree(def);
+ goto cleanup;
+}
+
+
+int
+virStoragePoolLoadAllState(virStoragePoolObjListPtr pools,
+ const char *stateDir)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int ret = -1;
+ int rc;
+
+ if ((rc = virDirOpenIfExists(&dir, stateDir)) <= 0)
+ return rc;
+
+ while ((ret = virDirRead(dir, &entry, stateDir)) > 0) {
+ virStoragePoolObjPtr pool;
+
+ if (!virFileStripSuffix(entry->d_name, ".xml"))
+ continue;
+
+ if (!(pool = virStoragePoolLoadState(pools, stateDir, entry->d_name)))
+ continue;
+ virStoragePoolObjUnlock(pool);
+ }
+
+ VIR_DIR_CLOSE(dir);
+ return ret;
+}
+
+
+int
+virStoragePoolLoadAllConfigs(virStoragePoolObjListPtr pools,
+ const char *configDir,
+ const char *autostartDir)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int ret;
+ int rc;
+
+ if ((rc = virDirOpenIfExists(&dir, configDir)) <= 0)
+ return rc;
+
+ while ((ret = virDirRead(dir, &entry, configDir)) > 0) {
+ char *path;
+ char *autostartLink;
+ virStoragePoolObjPtr pool;
+
+ if (!virFileHasSuffix(entry->d_name, ".xml"))
+ continue;
+
+ if (!(path = virFileBuildPath(configDir, entry->d_name, NULL)))
+ continue;
+
+ if (!(autostartLink = virFileBuildPath(autostartDir, entry->d_name,
+ NULL))) {
+ VIR_FREE(path);
+ continue;
+ }
+
+ pool = virStoragePoolObjLoad(pools, entry->d_name, path,
+ autostartLink);
+ if (pool)
+ virStoragePoolObjUnlock(pool);
+
+ VIR_FREE(path);
+ VIR_FREE(autostartLink);
+ }
+
+ VIR_DIR_CLOSE(dir);
+ return ret;
+}
+
+
+int
+virStoragePoolObjSaveDef(virStorageDriverStatePtr driver,
+ virStoragePoolObjPtr pool,
+ virStoragePoolDefPtr def)
+{
+ if (!pool->configFile) {
+ if (virFileMakePath(driver->configDir) < 0) {
+ virReportSystemError(errno,
+ _("cannot create config directory %s"),
+ driver->configDir);
+ return -1;
+ }
+
+ if (!(pool->configFile = virFileBuildPath(driver->configDir,
+ def->name, ".xml"))) {
+ return -1;
+ }
+
+ if (!(pool->autostartLink = virFileBuildPath(driver->autostartDir,
+ def->name, ".xml"))) {
+ VIR_FREE(pool->configFile);
+ return -1;
+ }
+ }
+
+ return virStoragePoolSaveConfig(pool->configFile, def);
+}
+
+int
+virStoragePoolObjDeleteDef(virStoragePoolObjPtr pool)
+{
+ if (!pool->configFile) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("no config file for %s"), pool->def->name);
+ return -1;
+ }
+
+ if (unlink(pool->configFile) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot remove config for %s"),
+ pool->def->name);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * virStoragePoolObjIsDuplicate:
+ * @doms : virStoragePoolObjListPtr to search
+ * @def : virStoragePoolDefPtr definition of pool to lookup
+ * @check_active: If true, ensure that pool is not active
+ *
+ * Returns: -1 on error
+ * 0 if pool is new
+ * 1 if pool is a duplicate
+ */
+int
+virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools,
+ virStoragePoolDefPtr def,
+ unsigned int check_active)
+{
+ int ret = -1;
+ virStoragePoolObjPtr pool = NULL;
+
+ /* See if a Pool with matching UUID already exists */
+ pool = virStoragePoolObjFindByUUID(pools, def->uuid);
+ if (pool) {
+ /* UUID matches, but if names don't match, refuse it */
+ if (STRNEQ(pool->def->name, def->name)) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(pool->def->uuid, uuidstr);
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("pool '%s' is already defined with uuid
%s"),
+ pool->def->name, uuidstr);
+ goto cleanup;
+ }
+
+ if (check_active) {
+ /* UUID & name match, but if Pool is already active, refuse it */
+ if (virStoragePoolObjIsActive(pool)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("pool is already active as '%s'"),
+ pool->def->name);
+ goto cleanup;
+ }
+ }
+
+ ret = 1;
+ } else {
+ /* UUID does not match, but if a name matches, refuse it */
+ pool = virStoragePoolObjFindByName(pools, def->name);
+ if (pool) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(pool->def->uuid, uuidstr);
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("pool '%s' already exists with uuid %s"),
+ def->name, uuidstr);
+ goto cleanup;
+ }
+ ret = 0;
+ }
+
+ cleanup:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
+ return ret;
+}
+
+
+static int
+getSCSIHostNumber(virStoragePoolSourceAdapter adapter,
+ unsigned int *hostnum)
+{
+ int ret = -1;
+ unsigned int num;
+ char *name = NULL;
+
+ if (adapter.data.scsi_host.has_parent) {
+ virPCIDeviceAddress addr = adapter.data.scsi_host.parentaddr;
+ unsigned int unique_id = adapter.data.scsi_host.unique_id;
+
+ if (!(name = virSCSIHostGetNameByParentaddr(addr.domain,
+ addr.bus,
+ addr.slot,
+ addr.function,
+ unique_id)))
+ goto cleanup;
+ if (virSCSIHostGetNumber(name, &num) < 0)
+ goto cleanup;
+ } else {
+ if (virSCSIHostGetNumber(adapter.data.scsi_host.name, &num) < 0)
+ goto cleanup;
+ }
+
+ *hostnum = num;
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(name);
+ return ret;
+}
+
+
+static bool
+virStorageIsSameHostnum(const char *name,
+ unsigned int scsi_hostnum)
+{
+ unsigned int fc_hostnum;
+
+ if (virSCSIHostGetNumber(name, &fc_hostnum) == 0 &&
+ scsi_hostnum == fc_hostnum)
+ return true;
+
+ return false;
+}
+
+
+/*
+ * matchFCHostToSCSIHost:
+ *
+ * @conn: Connection pointer
+ * @fc_adapter: fc_host adapter (either def or pool->def)
+ * @scsi_hostnum: Already determined "scsi_pool" hostnum
+ *
+ * Returns true/false whether there is a match between the incoming
+ * fc_adapter host# and the scsi_host host#
+ */
+static bool
+matchFCHostToSCSIHost(virConnectPtr conn,
+ virStoragePoolSourceAdapter fc_adapter,
+ unsigned int scsi_hostnum)
+{
+ bool ret = false;
+ char *name = NULL;
+ char *scsi_host_name = NULL;
+ char *parent_name = NULL;
+
+ /* If we have a parent defined, get its hostnum, and compare to the
+ * scsi_hostnum. If they are the same, then we have a match
+ */
+ if (fc_adapter.data.fchost.parent &&
+ virStorageIsSameHostnum(fc_adapter.data.fchost.parent, scsi_hostnum))
+ return true;
+
+ /* If we find an fc_adapter name, then either libvirt created a vHBA
+ * for this fc_host or a 'virsh nodedev-create' generated a vHBA.
+ */
+ if ((name = virVHBAGetHostByWWN(NULL, fc_adapter.data.fchost.wwnn,
+ fc_adapter.data.fchost.wwpn))) {
+
+ /* Get the scsi_hostN for the vHBA in order to see if it
+ * matches our scsi_hostnum
+ */
+ if (virStorageIsSameHostnum(name, scsi_hostnum)) {
+ ret = true;
+ goto cleanup;
+ }
+
+ /* We weren't provided a parent, so we have to query the node
+ * device driver in order to ascertain the parent of the vHBA.
+ * If the parent fc_hostnum is the same as the scsi_hostnum, we
+ * have a match.
+ */
+ if (conn && !fc_adapter.data.fchost.parent) {
+ if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0)
+ goto cleanup;
+ if ((parent_name = virNodeDeviceGetParentName(conn,
+ scsi_host_name))) {
+ if (virStorageIsSameHostnum(parent_name, scsi_hostnum)) {
+ ret = true;
+ goto cleanup;
+ }
+ } else {
+ /* Throw away the error and fall through */
+ virResetLastError();
+ VIR_DEBUG("Could not determine parent vHBA");
+ }
+ }
+ }
+
+ /* NB: Lack of a name means that this vHBA hasn't yet been created,
+ * which means our scsi_host cannot be using the vHBA. Furthermore,
+ * lack of a provided parent means libvirt is going to choose the
+ * "best" fc_host capable adapter based on availabilty. That could
+ * conflict with an existing scsi_host definition, but there's no
+ * way to know that now.
+ */
+
+ cleanup:
+ VIR_FREE(name);
+ VIR_FREE(parent_name);
+ VIR_FREE(scsi_host_name);
+ return ret;
+}
+
+static bool
+matchSCSIAdapterParent(virStoragePoolObjPtr pool,
+ virStoragePoolDefPtr def)
+{
+ virPCIDeviceAddressPtr pooladdr =
+ &pool->def->source.adapter.data.scsi_host.parentaddr;
+ virPCIDeviceAddressPtr defaddr =
+ &def->source.adapter.data.scsi_host.parentaddr;
+ int pool_unique_id =
+ pool->def->source.adapter.data.scsi_host.unique_id;
+ int def_unique_id =
+ def->source.adapter.data.scsi_host.unique_id;
+ if (pooladdr->domain == defaddr->domain &&
+ pooladdr->bus == defaddr->bus &&
+ pooladdr->slot == defaddr->slot &&
+ pooladdr->function == defaddr->function &&
+ pool_unique_id == def_unique_id) {
+ return true;
+ }
+ return false;
+}
+
+static bool
+virStoragePoolSourceMatchSingleHost(virStoragePoolSourcePtr poolsrc,
+ virStoragePoolSourcePtr defsrc)
+{
+ if (poolsrc->nhost != 1 && defsrc->nhost != 1)
+ return false;
+
+ if (defsrc->hosts[0].port &&
+ poolsrc->hosts[0].port != defsrc->hosts[0].port)
+ return false;
+
+ return STREQ(poolsrc->hosts[0].name, defsrc->hosts[0].name);
+}
+
+
+static bool
+virStoragePoolSourceISCSIMatch(virStoragePoolObjPtr matchpool,
+ virStoragePoolDefPtr def)
+{
+ virStoragePoolSourcePtr poolsrc = &matchpool->def->source;
+ virStoragePoolSourcePtr defsrc = &def->source;
+
+ /* NB: Do not check the source host name */
+ if (STRNEQ_NULLABLE(poolsrc->initiator.iqn, defsrc->initiator.iqn))
+ return false;
+
+ return true;
+}
+
+
+int
+virStoragePoolSourceFindDuplicate(virConnectPtr conn,
+ virStoragePoolObjListPtr pools,
+ virStoragePoolDefPtr def)
+{
+ size_t i;
+ int ret = 1;
+ virStoragePoolObjPtr pool = NULL;
+ virStoragePoolObjPtr matchpool = NULL;
+
+ /* Check the pool list for duplicate underlying storage */
+ for (i = 0; i < pools->count; i++) {
+ pool = pools->objs[i];
+ if (def->type != pool->def->type)
+ continue;
+
+ /* Don't match against ourself if re-defining existing pool ! */
+ if (STREQ(pool->def->name, def->name))
+ continue;
+
+ virStoragePoolObjLock(pool);
+
+ switch ((virStoragePoolType)pool->def->type) {
+ case VIR_STORAGE_POOL_DIR:
+ if (STREQ(pool->def->target.path, def->target.path))
+ matchpool = pool;
+ break;
+
+ case VIR_STORAGE_POOL_GLUSTER:
+ if (STREQ(pool->def->source.name, def->source.name) &&
+ STREQ_NULLABLE(pool->def->source.dir, def->source.dir)
&&
+ virStoragePoolSourceMatchSingleHost(&pool->def->source,
+ &def->source))
+ matchpool = pool;
+ break;
+
+ case VIR_STORAGE_POOL_NETFS:
+ if (STREQ(pool->def->source.dir, def->source.dir) &&
+ virStoragePoolSourceMatchSingleHost(&pool->def->source,
+ &def->source))
+ matchpool = pool;
+ break;
+
+ case VIR_STORAGE_POOL_SCSI:
+ if (pool->def->source.adapter.type ==
+ VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST &&
+ def->source.adapter.type ==
+ VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) {
+ if (STREQ(pool->def->source.adapter.data.fchost.wwnn,
+ def->source.adapter.data.fchost.wwnn) &&
+ STREQ(pool->def->source.adapter.data.fchost.wwpn,
+ def->source.adapter.data.fchost.wwpn))
+ matchpool = pool;
+ } else if (pool->def->source.adapter.type ==
+ VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST &&
+ def->source.adapter.type ==
+ VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) {
+ unsigned int pool_hostnum, def_hostnum;
+
+ if (pool->def->source.adapter.data.scsi_host.has_parent &&
+ def->source.adapter.data.scsi_host.has_parent &&
+ matchSCSIAdapterParent(pool, def)) {
+ matchpool = pool;
+ break;
+ }
+
+ if (getSCSIHostNumber(pool->def->source.adapter,
+ &pool_hostnum) < 0 ||
+ getSCSIHostNumber(def->source.adapter, &def_hostnum) < 0)
+ break;
+ if (pool_hostnum == def_hostnum)
+ matchpool = pool;
+ } else if (pool->def->source.adapter.type ==
+ VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST &&
+ def->source.adapter.type ==
+ VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) {
+ unsigned int scsi_hostnum;
+
+ /* Get the scsi_hostN for the scsi_host source adapter def */
+ if (getSCSIHostNumber(def->source.adapter,
+ &scsi_hostnum) < 0)
+ break;
+
+ if (matchFCHostToSCSIHost(conn, pool->def->source.adapter,
+ scsi_hostnum)) {
+ matchpool = pool;
+ break;
+ }
+
+ } else if (pool->def->source.adapter.type ==
+ VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST &&
+ def->source.adapter.type ==
+ VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) {
+ unsigned int scsi_hostnum;
+
+ if (getSCSIHostNumber(pool->def->source.adapter,
+ &scsi_hostnum) < 0)
+ break;
+
+ if (matchFCHostToSCSIHost(conn, def->source.adapter,
+ scsi_hostnum)) {
+ matchpool = pool;
+ break;
+ }
+ }
+ break;
+ case VIR_STORAGE_POOL_ISCSI:
+ matchpool = virStoragePoolSourceFindDuplicateDevices(pool, def);
+ if (matchpool) {
+ if (!virStoragePoolSourceISCSIMatch(matchpool, def))
+ matchpool = NULL;
+ }
+ break;
+ case VIR_STORAGE_POOL_FS:
+ case VIR_STORAGE_POOL_LOGICAL:
+ case VIR_STORAGE_POOL_DISK:
+ case VIR_STORAGE_POOL_ZFS:
+ matchpool = virStoragePoolSourceFindDuplicateDevices(pool, def);
+ break;
+ case VIR_STORAGE_POOL_SHEEPDOG:
+ if (virStoragePoolSourceMatchSingleHost(&pool->def->source,
+ &def->source))
+ matchpool = pool;
+ break;
+ case VIR_STORAGE_POOL_MPATH:
+ /* Only one mpath pool is valid per host */
+ matchpool = pool;
+ break;
+ case VIR_STORAGE_POOL_VSTORAGE:
+ if (STREQ(pool->def->source.name, def->source.name))
+ matchpool = pool;
+ break;
+ case VIR_STORAGE_POOL_RBD:
+ case VIR_STORAGE_POOL_LAST:
+ break;
+ }
+ virStoragePoolObjUnlock(pool);
+
+ if (matchpool)
+ break;
+ }
+
+ if (matchpool) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("Storage source conflict with pool: '%s'"),
+ matchpool->def->name);
+ ret = -1;
+ }
+ return ret;
+}
+
+void
+virStoragePoolObjLock(virStoragePoolObjPtr obj)
+{
+ virMutexLock(&obj->lock);
+}
+
+void
+virStoragePoolObjUnlock(virStoragePoolObjPtr obj)
+{
+ virMutexUnlock(&obj->lock);
+}
+
+#define MATCH(FLAG) (flags & (FLAG))
+static bool
+virStoragePoolMatch(virStoragePoolObjPtr poolobj,
+ unsigned int flags)
+{
+ /* filter by active state */
+ if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ACTIVE) &&
+ !((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE) &&
+ virStoragePoolObjIsActive(poolobj)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE) &&
+ !virStoragePoolObjIsActive(poolobj))))
+ return false;
+
+ /* filter by persistence */
+ if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_PERSISTENT) &&
+ !((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_PERSISTENT) &&
+ poolobj->configFile) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_TRANSIENT) &&
+ !poolobj->configFile)))
+ return false;
+
+ /* filter by autostart option */
+ if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_AUTOSTART) &&
+ !((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_AUTOSTART) &&
+ poolobj->autostart) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_NO_AUTOSTART) &&
+ !poolobj->autostart)))
+ return false;
+
+ /* filter by pool type */
+ if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_POOL_TYPE)) {
+ if (!((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_DIR) &&
+ (poolobj->def->type == VIR_STORAGE_POOL_DIR)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FS) &&
+ (poolobj->def->type == VIR_STORAGE_POOL_FS)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_NETFS) &&
+ (poolobj->def->type == VIR_STORAGE_POOL_NETFS)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_LOGICAL) &&
+ (poolobj->def->type == VIR_STORAGE_POOL_LOGICAL)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_DISK) &&
+ (poolobj->def->type == VIR_STORAGE_POOL_DISK)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI) &&
+ (poolobj->def->type == VIR_STORAGE_POOL_ISCSI)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_SCSI) &&
+ (poolobj->def->type == VIR_STORAGE_POOL_SCSI)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_MPATH) &&
+ (poolobj->def->type == VIR_STORAGE_POOL_MPATH)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_RBD) &&
+ (poolobj->def->type == VIR_STORAGE_POOL_RBD)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG) &&
+ (poolobj->def->type == VIR_STORAGE_POOL_SHEEPDOG)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER) &&
+ (poolobj->def->type == VIR_STORAGE_POOL_GLUSTER))))
+ return false;
+ }
+
+ return true;
+}
+#undef MATCH
+
+int
+virStoragePoolObjListExport(virConnectPtr conn,
+ virStoragePoolObjList poolobjs,
+ virStoragePoolPtr **pools,
+ virStoragePoolObjListFilter filter,
+ unsigned int flags)
+{
+ virStoragePoolPtr *tmp_pools = NULL;
+ virStoragePoolPtr pool = NULL;
+ int npools = 0;
+ int ret = -1;
+ size_t i;
+
+ if (pools && VIR_ALLOC_N(tmp_pools, poolobjs.count + 1) < 0)
+ goto cleanup;
+
+ for (i = 0; i < poolobjs.count; i++) {
+ virStoragePoolObjPtr poolobj = poolobjs.objs[i];
+ virStoragePoolObjLock(poolobj);
+ if ((!filter || filter(conn, poolobj->def)) &&
+ virStoragePoolMatch(poolobj, flags)) {
+ if (pools) {
+ if (!(pool = virGetStoragePool(conn,
+ poolobj->def->name,
+ poolobj->def->uuid,
+ NULL, NULL))) {
+ virStoragePoolObjUnlock(poolobj);
+ goto cleanup;
+ }
+ tmp_pools[npools] = pool;
+ }
+ npools++;
+ }
+ virStoragePoolObjUnlock(poolobj);
+ }
+
+ if (tmp_pools) {
+ /* trim the array to the final size */
+ ignore_value(VIR_REALLOC_N(tmp_pools, npools + 1));
+ *pools = tmp_pools;
+ tmp_pools = NULL;
+ }
+
+ ret = npools;
+
+ cleanup:
+ if (tmp_pools) {
+ for (i = 0; i < npools; i++)
+ virObjectUnref(tmp_pools[i]);
+ }
+
+ VIR_FREE(tmp_pools);
+ return ret;
+}
diff --git a/src/conf/virstorageobj.h b/src/conf/virstorageobj.h
new file mode 100644
index 0000000..e00954e
--- /dev/null
+++ b/src/conf/virstorageobj.h
@@ -0,0 +1,142 @@
+/*
+ * virstorageobj.h: internal storage pool and volume objects handling
+ * (derived from storage_conf.h)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __VIRSTORAGEOBJ_H__
+# define __VIRSTORAGEOBJ_H__
+
+# include "internal.h"
+
+# include "storage_conf.h"
+
+typedef struct _virStoragePoolObj virStoragePoolObj;
+typedef virStoragePoolObj *virStoragePoolObjPtr;
+
+struct _virStoragePoolObj {
+ virMutex lock;
+
+ char *configFile;
+ char *autostartLink;
+ bool active;
+ int autostart;
+ unsigned int asyncjobs;
+
+ virStoragePoolDefPtr def;
+ virStoragePoolDefPtr newDef;
+
+ virStorageVolDefList volumes;
+};
+
+typedef struct _virStoragePoolObjList virStoragePoolObjList;
+typedef virStoragePoolObjList *virStoragePoolObjListPtr;
+struct _virStoragePoolObjList {
+ size_t count;
+ virStoragePoolObjPtr *objs;
+};
+
+typedef struct _virStorageDriverState virStorageDriverState;
+typedef virStorageDriverState *virStorageDriverStatePtr;
+
+struct _virStorageDriverState {
+ virMutex lock;
+
+ virStoragePoolObjList pools;
+
+ char *configDir;
+ char *autostartDir;
+ char *stateDir;
+ bool privileged;
+
+ /* Immutable pointer, self-locking APIs */
+ virObjectEventStatePtr storageEventState;
+};
+
+typedef bool (*virStoragePoolObjListFilter)(virConnectPtr conn,
+ virStoragePoolDefPtr def);
+
+static inline int
+virStoragePoolObjIsActive(virStoragePoolObjPtr pool)
+{
+ return pool->active;
+}
+
+int virStoragePoolLoadAllConfigs(virStoragePoolObjListPtr pools,
+ const char *configDir,
+ const char *autostartDir);
+
+int virStoragePoolLoadAllState(virStoragePoolObjListPtr pools,
+ const char *stateDir);
+
+virStoragePoolObjPtr
+virStoragePoolLoadState(virStoragePoolObjListPtr pools,
+ const char *stateDir,
+ const char *name);
+virStoragePoolObjPtr
+virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools,
+ const unsigned char *uuid);
+virStoragePoolObjPtr
+virStoragePoolObjFindByName(virStoragePoolObjListPtr pools,
+ const char *name);
+virStoragePoolObjPtr
+virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool,
+ virStoragePoolDefPtr def);
+
+virStorageVolDefPtr
+virStorageVolDefFindByKey(virStoragePoolObjPtr pool,
+ const char *key);
+virStorageVolDefPtr
+virStorageVolDefFindByPath(virStoragePoolObjPtr pool,
+ const char *path);
+virStorageVolDefPtr
+virStorageVolDefFindByName(virStoragePoolObjPtr pool,
+ const char *name);
+
+void virStoragePoolObjClearVols(virStoragePoolObjPtr pool);
+
+virStoragePoolObjPtr
+virStoragePoolObjAssignDef(virStoragePoolObjListPtr pools,
+ virStoragePoolDefPtr def);
+
+int virStoragePoolObjSaveDef(virStorageDriverStatePtr driver,
+ virStoragePoolObjPtr pool,
+ virStoragePoolDefPtr def);
+int virStoragePoolObjDeleteDef(virStoragePoolObjPtr pool);
+
+void virStoragePoolObjFree(virStoragePoolObjPtr pool);
+void virStoragePoolObjListFree(virStoragePoolObjListPtr pools);
+void virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
+ virStoragePoolObjPtr pool);
+
+int virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools,
+ virStoragePoolDefPtr def,
+ unsigned int check_active);
+
+int virStoragePoolSourceFindDuplicate(virConnectPtr conn,
+ virStoragePoolObjListPtr pools,
+ virStoragePoolDefPtr def);
+
+void virStoragePoolObjLock(virStoragePoolObjPtr obj);
+void virStoragePoolObjUnlock(virStoragePoolObjPtr obj);
+
+int virStoragePoolObjListExport(virConnectPtr conn,
+ virStoragePoolObjList poolobjs,
+ virStoragePoolPtr **pools,
+ virStoragePoolObjListFilter filter,
+ unsigned int flags);
+
+#endif /* __VIRSTORAGEOBJ_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6c89d44..030f58a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -860,28 +860,12 @@ virStoragePoolFormatDiskTypeToString;
virStoragePoolFormatFileSystemNetTypeToString;
virStoragePoolFormatFileSystemTypeToString;
virStoragePoolFormatLogicalTypeToString;
-virStoragePoolLoadAllConfigs;
-virStoragePoolLoadAllState;
-virStoragePoolObjAssignDef;
-virStoragePoolObjClearVols;
-virStoragePoolObjDeleteDef;
-virStoragePoolObjFindByName;
-virStoragePoolObjFindByUUID;
-virStoragePoolObjIsDuplicate;
-virStoragePoolObjListExport;
-virStoragePoolObjListFree;
-virStoragePoolObjLock;
-virStoragePoolObjRemove;
-virStoragePoolObjSaveDef;
-virStoragePoolObjUnlock;
virStoragePoolSaveConfig;
virStoragePoolSaveState;
virStoragePoolSourceAdapterTypeFromString;
virStoragePoolSourceAdapterTypeToString;
virStoragePoolSourceClear;
virStoragePoolSourceDeviceClear;
-virStoragePoolSourceFindDuplicate;
-virStoragePoolSourceFindDuplicateDevices;
virStoragePoolSourceFree;
virStoragePoolSourceListFormat;
virStoragePoolSourceListNewSource;
@@ -991,6 +975,25 @@ virSecretObjSetValue;
virSecretObjSetValueSize;
+# conf/virstorageobj.h
+virStoragePoolLoadAllConfigs;
+virStoragePoolLoadAllState;
+virStoragePoolObjAssignDef;
+virStoragePoolObjClearVols;
+virStoragePoolObjDeleteDef;
+virStoragePoolObjFindByName;
+virStoragePoolObjFindByUUID;
+virStoragePoolObjIsDuplicate;
+virStoragePoolObjListExport;
+virStoragePoolObjListFree;
+virStoragePoolObjLock;
+virStoragePoolObjRemove;
+virStoragePoolObjSaveDef;
+virStoragePoolObjUnlock;
+virStoragePoolSourceFindDuplicate;
+virStoragePoolSourceFindDuplicateDevices;
+
+
# cpu/cpu.h
cpuBaseline;
cpuBaselineXML;
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
index f433071..21ac845 100644
--- a/src/storage/storage_backend.h
+++ b/src/storage/storage_backend.h
@@ -22,7 +22,7 @@
# include <sys/stat.h>
# include "internal.h"
-# include "storage_conf.h"
+# include "virstorageobj.h"
# include "storage_driver.h"
typedef char * (*virStorageBackendFindPoolSources)(virConnectPtr conn,
diff --git a/src/storage/storage_driver.h b/src/storage/storage_driver.h
index f0aca36..530bc33 100644
--- a/src/storage/storage_driver.h
+++ b/src/storage/storage_driver.h
@@ -27,7 +27,7 @@
# include <sys/stat.h>
# include "domain_conf.h"
-# include "storage_conf.h"
+# include "virstorageobj.h"
# include "virstoragefile.h"
int virStorageFileInit(virStorageSourcePtr src);
diff --git a/src/storage/storage_util.h b/src/storage/storage_util.h
index 326d555..fa3b652 100644
--- a/src/storage/storage_util.h
+++ b/src/storage/storage_util.h
@@ -22,7 +22,6 @@
# include <sys/stat.h>
# include "internal.h"
-# include "storage_conf.h"
# include "vircommand.h"
# include "storage_driver.h"
# include "storage_backend.h"
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 7128bfa..88aadce 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -49,6 +49,7 @@
#include "snapshot_conf.h"
#include "fdstream.h"
#include "storage_conf.h"
+#include "virstorageobj.h"
#include "storage_event.h"
#include "node_device_conf.h"
#include "virnodedeviceobj.h"
--
2.9.3