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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list