mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 11:01:19 +00:00
For libvirt, the volume is just a binary blob and it doesn't interpret data on volume upload/download. But as it turns out, this unspoken assumption is not clear to our users. Document it explicitly. Suggested in: https://bugzilla.redhat.com/show_bug.cgi?id=1851023#c17 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2404 lines
64 KiB
C
2404 lines
64 KiB
C
/*
|
|
* libvirt-storage.c: entry points for virStorage{Pool,Vol}Ptr APIs
|
|
*
|
|
* Copyright (C) 2006-2015 Red Hat, Inc.
|
|
*
|
|
* 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 "datatypes.h"
|
|
#include "virlog.h"
|
|
|
|
VIR_LOG_INIT("libvirt.storage");
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_STORAGE
|
|
|
|
|
|
/**
|
|
* virStoragePoolGetConnect:
|
|
* @pool: pointer to a pool
|
|
*
|
|
* Provides the connection pointer associated with a storage pool. The
|
|
* reference counter on the connection is not increased by this
|
|
* call.
|
|
*
|
|
* Returns the virConnectPtr or NULL in case of failure.
|
|
*/
|
|
virConnectPtr
|
|
virStoragePoolGetConnect(virStoragePoolPtr pool)
|
|
{
|
|
VIR_DEBUG("pool=%p", pool);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, NULL);
|
|
|
|
return pool->conn;
|
|
}
|
|
|
|
|
|
/**
|
|
* virConnectListAllStoragePools:
|
|
* @conn: Pointer to the hypervisor connection.
|
|
* @pools: Pointer to a variable to store the array containing storage pool
|
|
* objects or NULL if the list is not required (just returns number
|
|
* of pools).
|
|
* @flags: bitwise-OR of virConnectListAllStoragePoolsFlags.
|
|
*
|
|
* Collect the list of storage pools, and allocate an array to store those
|
|
* objects. This API solves the race inherent between
|
|
* virConnectListStoragePools and virConnectListDefinedStoragePools.
|
|
*
|
|
* Normally, all storage pools are returned; however, @flags can be used to
|
|
* filter the results for a smaller list of targeted pools. The valid
|
|
* flags are divided into groups, where each group contains bits that
|
|
* describe mutually exclusive attributes of a pool, and where all bits
|
|
* within a group describe all possible pools.
|
|
*
|
|
* The first group of @flags is VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE (online)
|
|
* and VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE (offline) to filter the pools
|
|
* by state.
|
|
*
|
|
* The second group of @flags is VIR_CONNECT_LIST_STORAGE_POOLS_PERSITENT
|
|
* (defined) and VIR_CONNECT_LIST_STORAGE_POOLS_TRANSIENT (running but not
|
|
* defined), to filter the pools by whether they have persistent config or not.
|
|
*
|
|
* The third group of @flags is VIR_CONNECT_LIST_STORAGE_POOLS_AUTOSTART
|
|
* and VIR_CONNECT_LIST_STORAGE_POOLS_NO_AUTOSTART, to filter the pools by
|
|
* whether they are marked as autostart or not.
|
|
*
|
|
* The last group of @flags is provided to filter the pools by the types,
|
|
* the flags include:
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_DIR
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_FS
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_NETFS
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_LOGICAL
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_DISK
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_SCSI
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_MPATH
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_RBD
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_ZFS
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_VSTORAGE
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI_DIRECT
|
|
*
|
|
* Returns the number of storage pools found or -1 and sets @pools to
|
|
* NULL in case of error. On success, the array stored into @pools is
|
|
* guaranteed to have an extra allocated element set to NULL but not included
|
|
* in the return count, to make iteration easier. The caller is responsible
|
|
* for calling virStoragePoolFree() on each array element, then calling
|
|
* free() on @pools.
|
|
*/
|
|
int
|
|
virConnectListAllStoragePools(virConnectPtr conn,
|
|
virStoragePoolPtr **pools,
|
|
unsigned int flags)
|
|
{
|
|
VIR_DEBUG("conn=%p, pools=%p, flags=0x%x", conn, pools, flags);
|
|
|
|
virResetLastError();
|
|
|
|
if (pools)
|
|
*pools = NULL;
|
|
|
|
virCheckConnectReturn(conn, -1);
|
|
|
|
if (conn->storageDriver &&
|
|
conn->storageDriver->connectListAllStoragePools) {
|
|
int ret;
|
|
ret = conn->storageDriver->connectListAllStoragePools(conn, pools, flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virConnectNumOfStoragePools:
|
|
* @conn: pointer to hypervisor connection
|
|
*
|
|
* Provides the number of active storage pools
|
|
*
|
|
* Returns the number of pools found, or -1 on error
|
|
*/
|
|
int
|
|
virConnectNumOfStoragePools(virConnectPtr conn)
|
|
{
|
|
VIR_DEBUG("conn=%p", conn);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, -1);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->connectNumOfStoragePools) {
|
|
int ret;
|
|
ret = conn->storageDriver->connectNumOfStoragePools(conn);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virConnectListStoragePools:
|
|
* @conn: pointer to hypervisor connection
|
|
* @names: array of char * to fill with pool names (allocated by caller)
|
|
* @maxnames: size of the names array
|
|
*
|
|
* Provides the list of names of active storage pools up to maxnames.
|
|
* If there are more than maxnames, the remaining names will be silently
|
|
* ignored.
|
|
*
|
|
* For more control over the results, see virConnectListAllStoragePools().
|
|
*
|
|
* Returns the number of pools found or -1 in case of error. Note that
|
|
* this command is inherently racy; a pool can be started between a call to
|
|
* virConnectNumOfStoragePools() and this call; you are only guaranteed
|
|
* that all currently active pools were listed if the return is less than
|
|
* @maxnames. The client must call free() on each returned name.
|
|
*/
|
|
int
|
|
virConnectListStoragePools(virConnectPtr conn,
|
|
char **const names,
|
|
int maxnames)
|
|
{
|
|
VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, -1);
|
|
virCheckNonNullArrayArgGoto(names, maxnames, error);
|
|
virCheckNonNegativeArgGoto(maxnames, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->connectListStoragePools) {
|
|
int ret;
|
|
ret = conn->storageDriver->connectListStoragePools(conn, names, maxnames);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virConnectNumOfDefinedStoragePools:
|
|
* @conn: pointer to hypervisor connection
|
|
*
|
|
* Provides the number of inactive storage pools
|
|
*
|
|
* Returns the number of pools found, or -1 on error
|
|
*/
|
|
int
|
|
virConnectNumOfDefinedStoragePools(virConnectPtr conn)
|
|
{
|
|
VIR_DEBUG("conn=%p", conn);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, -1);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->connectNumOfDefinedStoragePools) {
|
|
int ret;
|
|
ret = conn->storageDriver->connectNumOfDefinedStoragePools(conn);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virConnectListDefinedStoragePools:
|
|
* @conn: pointer to hypervisor connection
|
|
* @names: array of char * to fill with pool names (allocated by caller)
|
|
* @maxnames: size of the names array
|
|
*
|
|
* Provides the list of names of inactive storage pools up to maxnames.
|
|
* If there are more than maxnames, the remaining names will be silently
|
|
* ignored.
|
|
*
|
|
* For more control over the results, see virConnectListAllStoragePools().
|
|
*
|
|
* Returns the number of names provided in the array or -1 in case of error.
|
|
* Note that this command is inherently racy; a pool can be defined between
|
|
* a call to virConnectNumOfDefinedStoragePools() and this call; you are only
|
|
* guaranteed that all currently defined pools were listed if the return
|
|
* is less than @maxnames. The client must call free() on each returned name.
|
|
*/
|
|
int
|
|
virConnectListDefinedStoragePools(virConnectPtr conn,
|
|
char **const names,
|
|
int maxnames)
|
|
{
|
|
VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, -1);
|
|
virCheckNonNullArrayArgGoto(names, maxnames, error);
|
|
virCheckNonNegativeArgGoto(maxnames, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->connectListDefinedStoragePools) {
|
|
int ret;
|
|
ret = conn->storageDriver->connectListDefinedStoragePools(conn, names, maxnames);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virConnectFindStoragePoolSources:
|
|
* @conn: pointer to hypervisor connection
|
|
* @type: type of storage pool sources to discover
|
|
* @srcSpec: XML document specifying discovery source
|
|
* @flags: extra flags; not used yet, so callers should always pass 0
|
|
*
|
|
* Talks to a storage backend and attempts to auto-discover the set of
|
|
* available storage pool sources. e.g. For iSCSI this would be a set of
|
|
* iSCSI targets. For NFS this would be a list of exported paths. The
|
|
* srcSpec (optional for some storage pool types, e.g. local ones) is
|
|
* an instance of the storage pool's source element specifying where
|
|
* to look for the pools.
|
|
*
|
|
* srcSpec is not required for some types (e.g., those querying
|
|
* local storage resources only)
|
|
*
|
|
* Returns an xml document consisting of a SourceList element
|
|
* containing a source document appropriate to the given pool
|
|
* type for each discovered source.
|
|
*/
|
|
char *
|
|
virConnectFindStoragePoolSources(virConnectPtr conn,
|
|
const char *type,
|
|
const char *srcSpec,
|
|
unsigned int flags)
|
|
{
|
|
VIR_DEBUG("conn=%p, type=%s, src=%s, flags=0x%x",
|
|
conn, NULLSTR(type), NULLSTR(srcSpec), flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, NULL);
|
|
virCheckNonNullArgGoto(type, error);
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->connectFindStoragePoolSources) {
|
|
char *ret;
|
|
ret = conn->storageDriver->connectFindStoragePoolSources(conn, type, srcSpec, flags);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolLookupByName:
|
|
* @conn: pointer to hypervisor connection
|
|
* @name: name of pool to fetch
|
|
*
|
|
* Fetch a storage pool based on its unique name
|
|
*
|
|
* virStoragePoolFree should be used to free the resources after the
|
|
* storage pool object is no longer needed.
|
|
*
|
|
* Returns a virStoragePoolPtr object, or NULL if no matching pool is found
|
|
*/
|
|
virStoragePoolPtr
|
|
virStoragePoolLookupByName(virConnectPtr conn,
|
|
const char *name)
|
|
{
|
|
VIR_DEBUG("conn=%p, name=%s", conn, NULLSTR(name));
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, NULL);
|
|
virCheckNonNullArgGoto(name, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolLookupByName) {
|
|
virStoragePoolPtr ret;
|
|
ret = conn->storageDriver->storagePoolLookupByName(conn, name);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolLookupByUUID:
|
|
* @conn: pointer to hypervisor connection
|
|
* @uuid: globally unique id of pool to fetch
|
|
*
|
|
* Fetch a storage pool based on its globally unique id
|
|
*
|
|
* virStoragePoolFree should be used to free the resources after the
|
|
* storage pool object is no longer needed.
|
|
*
|
|
* Returns a virStoragePoolPtr object, or NULL if no matching pool is found
|
|
*/
|
|
virStoragePoolPtr
|
|
virStoragePoolLookupByUUID(virConnectPtr conn,
|
|
const unsigned char *uuid)
|
|
{
|
|
VIR_UUID_DEBUG(conn, uuid);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, NULL);
|
|
virCheckNonNullArgGoto(uuid, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolLookupByUUID) {
|
|
virStoragePoolPtr ret;
|
|
ret = conn->storageDriver->storagePoolLookupByUUID(conn, uuid);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolLookupByUUIDString:
|
|
* @conn: pointer to hypervisor connection
|
|
* @uuidstr: globally unique id of pool to fetch
|
|
*
|
|
* Fetch a storage pool based on its globally unique id
|
|
*
|
|
* virStoragePoolFree should be used to free the resources after the
|
|
* storage pool object is no longer needed.
|
|
*
|
|
* Returns a virStoragePoolPtr object, or NULL if no matching pool is found
|
|
*/
|
|
virStoragePoolPtr
|
|
virStoragePoolLookupByUUIDString(virConnectPtr conn,
|
|
const char *uuidstr)
|
|
{
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
VIR_DEBUG("conn=%p, uuidstr=%s", conn, NULLSTR(uuidstr));
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, NULL);
|
|
virCheckNonNullArgGoto(uuidstr, error);
|
|
|
|
if (virUUIDParse(uuidstr, uuid) < 0) {
|
|
virReportInvalidArg(uuidstr,
|
|
_("uuidstr in %s must be a valid UUID"),
|
|
__FUNCTION__);
|
|
goto error;
|
|
}
|
|
|
|
return virStoragePoolLookupByUUID(conn, uuid);
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolLookupByVolume:
|
|
* @vol: pointer to storage volume
|
|
*
|
|
* Fetch a storage pool which contains a particular volume
|
|
*
|
|
* virStoragePoolFree should be used to free the resources after the
|
|
* storage pool object is no longer needed.
|
|
*
|
|
* Returns a virStoragePoolPtr object, or NULL if no matching pool is found
|
|
*/
|
|
virStoragePoolPtr
|
|
virStoragePoolLookupByVolume(virStorageVolPtr vol)
|
|
{
|
|
VIR_DEBUG("vol=%p", vol);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, NULL);
|
|
|
|
if (vol->conn->storageDriver && vol->conn->storageDriver->storagePoolLookupByVolume) {
|
|
virStoragePoolPtr ret;
|
|
ret = vol->conn->storageDriver->storagePoolLookupByVolume(vol);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(vol->conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolLookupByTargetPath:
|
|
* @conn: pointer to hypervisor connection
|
|
* @path: path at which the pool is exposed
|
|
*
|
|
* Fetch a storage pool which maps to a particular target directory.
|
|
* If more than one pool maps to the path, it is undefined which
|
|
* will be returned first.
|
|
*
|
|
* virStoragePoolFree should be used to free the resources after the
|
|
* storage pool object is no longer needed.
|
|
*
|
|
* Returns a virStoragePoolPtr object, or NULL if no matching pool is found
|
|
*/
|
|
virStoragePoolPtr
|
|
virStoragePoolLookupByTargetPath(virConnectPtr conn,
|
|
const char *path)
|
|
{
|
|
VIR_DEBUG("conn=%p, path=%s", conn, NULLSTR(path));
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, NULL);
|
|
virCheckNonNullArgGoto(path, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolLookupByTargetPath) {
|
|
virStoragePoolPtr ret;
|
|
ret = conn->storageDriver->storagePoolLookupByTargetPath(conn, path);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* virStoragePoolCreateXML:
|
|
* @conn: pointer to hypervisor connection
|
|
* @xmlDesc: XML description for new pool
|
|
* @flags: bitwise-OR of virStoragePoolCreateFlags
|
|
*
|
|
* Create a new storage based on its XML description. The
|
|
* pool is not persistent, so its definition will disappear
|
|
* when it is destroyed, or if the host is restarted
|
|
*
|
|
* virStoragePoolFree should be used to free the resources after the
|
|
* storage pool object is no longer needed.
|
|
*
|
|
* Returns a virStoragePoolPtr object, or NULL if creation failed
|
|
*/
|
|
virStoragePoolPtr
|
|
virStoragePoolCreateXML(virConnectPtr conn,
|
|
const char *xmlDesc,
|
|
unsigned int flags)
|
|
{
|
|
VIR_DEBUG("conn=%p, xmlDesc=%s, flags=0x%x", conn, NULLSTR(xmlDesc), flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, NULL);
|
|
virCheckNonNullArgGoto(xmlDesc, error);
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolCreateXML) {
|
|
virStoragePoolPtr ret;
|
|
ret = conn->storageDriver->storagePoolCreateXML(conn, xmlDesc, flags);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolDefineXML:
|
|
* @conn: pointer to hypervisor connection
|
|
* @xml: XML description for new pool
|
|
* @flags: extra flags; not used yet, so callers should always pass 0
|
|
*
|
|
* Define an inactive persistent storage pool or modify an existing persistent
|
|
* one from the XML description.
|
|
*
|
|
* virStoragePoolFree should be used to free the resources after the
|
|
* storage pool object is no longer needed.
|
|
*
|
|
* Returns a virStoragePoolPtr object, or NULL if creation failed
|
|
*/
|
|
virStoragePoolPtr
|
|
virStoragePoolDefineXML(virConnectPtr conn,
|
|
const char *xml,
|
|
unsigned int flags)
|
|
{
|
|
VIR_DEBUG("conn=%p, xml=%s, flags=0x%x", conn, NULLSTR(xml), flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, NULL);
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
virCheckNonNullArgGoto(xml, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolDefineXML) {
|
|
virStoragePoolPtr ret;
|
|
ret = conn->storageDriver->storagePoolDefineXML(conn, xml, flags);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolBuild:
|
|
* @pool: pointer to storage pool
|
|
* @flags: bitwise-OR of virStoragePoolBuildFlags
|
|
*
|
|
* Currently only filesystem pool accepts flags VIR_STORAGE_POOL_BUILD_OVERWRITE
|
|
* and VIR_STORAGE_POOL_BUILD_NO_OVERWRITE.
|
|
*
|
|
* Build the underlying storage pool
|
|
*
|
|
* Returns 0 on success, or -1 upon failure
|
|
*/
|
|
int
|
|
virStoragePoolBuild(virStoragePoolPtr pool,
|
|
unsigned int flags)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("pool=%p, flags=0x%x", pool, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
conn = pool->conn;
|
|
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolBuild) {
|
|
int ret;
|
|
ret = conn->storageDriver->storagePoolBuild(pool, flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolUndefine:
|
|
* @pool: pointer to storage pool
|
|
*
|
|
* Undefine an inactive storage pool
|
|
*
|
|
* Returns 0 on success, -1 on failure
|
|
*/
|
|
int
|
|
virStoragePoolUndefine(virStoragePoolPtr pool)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("pool=%p", pool);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
conn = pool->conn;
|
|
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolUndefine) {
|
|
int ret;
|
|
ret = conn->storageDriver->storagePoolUndefine(pool);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolCreate:
|
|
* @pool: pointer to storage pool
|
|
* @flags: bitwise-OR of virStoragePoolCreateFlags
|
|
*
|
|
* Starts an inactive storage pool
|
|
*
|
|
* Returns 0 on success, or -1 if it could not be started
|
|
*/
|
|
int
|
|
virStoragePoolCreate(virStoragePoolPtr pool,
|
|
unsigned int flags)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("pool=%p, flags=0x%x", pool, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
conn = pool->conn;
|
|
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolCreate) {
|
|
int ret;
|
|
ret = conn->storageDriver->storagePoolCreate(pool, flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolDestroy:
|
|
* @pool: pointer to storage pool
|
|
*
|
|
* Destroy an active storage pool. This will deactivate the
|
|
* pool on the host, but keep any persistent config associated
|
|
* with it. If it has a persistent config it can later be
|
|
* restarted with virStoragePoolCreate(). This does not free
|
|
* the associated virStoragePoolPtr object.
|
|
*
|
|
* Returns 0 on success, or -1 if it could not be destroyed
|
|
*/
|
|
int
|
|
virStoragePoolDestroy(virStoragePoolPtr pool)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("pool=%p", pool);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
conn = pool->conn;
|
|
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolDestroy) {
|
|
int ret;
|
|
ret = conn->storageDriver->storagePoolDestroy(pool);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolDelete:
|
|
* @pool: pointer to storage pool
|
|
* @flags: bitwise-OR of virStoragePoolDeleteFlags
|
|
*
|
|
* Delete the underlying pool resources. This is
|
|
* a non-recoverable operation. The virStoragePoolPtr object
|
|
* itself is not free'd.
|
|
*
|
|
* Returns 0 on success, or -1 if it could not be obliterate
|
|
*/
|
|
int
|
|
virStoragePoolDelete(virStoragePoolPtr pool,
|
|
unsigned int flags)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("pool=%p, flags=0x%x", pool, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
conn = pool->conn;
|
|
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolDelete) {
|
|
int ret;
|
|
ret = conn->storageDriver->storagePoolDelete(pool, flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolFree:
|
|
* @pool: pointer to storage pool
|
|
*
|
|
* Free a storage pool object, releasing all memory associated with
|
|
* it. Does not change the state of the pool on the host.
|
|
*
|
|
* Returns 0 on success, or -1 if it could not be free'd.
|
|
*/
|
|
int
|
|
virStoragePoolFree(virStoragePoolPtr pool)
|
|
{
|
|
VIR_DEBUG("pool=%p", pool);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
|
|
virObjectUnref(pool);
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolRef:
|
|
* @pool: the pool to hold a reference on
|
|
*
|
|
* Increment the reference count on the pool. For each
|
|
* additional call to this method, there shall be a corresponding
|
|
* call to virStoragePoolFree to release the reference count, once
|
|
* the caller no longer needs the reference to this object.
|
|
*
|
|
* This method is typically useful for applications where multiple
|
|
* threads are using a connection, and it is required that the
|
|
* connection remain open until all threads have finished using
|
|
* it. ie, each new thread using a pool would increment
|
|
* the reference count.
|
|
*
|
|
* Returns 0 in case of success, -1 in case of failure.
|
|
*/
|
|
int
|
|
virStoragePoolRef(virStoragePoolPtr pool)
|
|
{
|
|
VIR_DEBUG("pool=%p", pool);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
|
|
virObjectRef(pool);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolRefresh:
|
|
* @pool: pointer to storage pool
|
|
* @flags: extra flags; not used yet, so callers should always pass 0
|
|
*
|
|
* Request that the pool refresh its list of volumes. This may
|
|
* involve communicating with a remote server, and/or initializing
|
|
* new devices at the OS layer
|
|
*
|
|
* Returns 0 if the volume list was refreshed, -1 on failure
|
|
*/
|
|
int
|
|
virStoragePoolRefresh(virStoragePoolPtr pool,
|
|
unsigned int flags)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("pool=%p, flags=0x%x", pool, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
conn = pool->conn;
|
|
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolRefresh) {
|
|
int ret;
|
|
ret = conn->storageDriver->storagePoolRefresh(pool, flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolGetName:
|
|
* @pool: pointer to storage pool
|
|
*
|
|
* Fetch the locally unique name of the storage pool
|
|
*
|
|
* Returns the name of the pool, or NULL on error
|
|
*/
|
|
const char*
|
|
virStoragePoolGetName(virStoragePoolPtr pool)
|
|
{
|
|
VIR_DEBUG("pool=%p", pool);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, NULL);
|
|
|
|
return pool->name;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolGetUUID:
|
|
* @pool: pointer to storage pool
|
|
* @uuid: buffer of VIR_UUID_BUFLEN bytes in size
|
|
*
|
|
* Fetch the globally unique ID of the storage pool
|
|
*
|
|
* Returns 0 on success, or -1 on error;
|
|
*/
|
|
int
|
|
virStoragePoolGetUUID(virStoragePoolPtr pool,
|
|
unsigned char *uuid)
|
|
{
|
|
VIR_DEBUG("pool=%p, uuid=%p", pool, uuid);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
virCheckNonNullArgGoto(uuid, error);
|
|
|
|
memcpy(uuid, &pool->uuid[0], VIR_UUID_BUFLEN);
|
|
|
|
return 0;
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolGetUUIDString:
|
|
* @pool: pointer to storage pool
|
|
* @buf: buffer of VIR_UUID_STRING_BUFLEN bytes in size
|
|
*
|
|
* Fetch the globally unique ID of the storage pool as a string
|
|
*
|
|
* Returns 0 on success, or -1 on error;
|
|
*/
|
|
int
|
|
virStoragePoolGetUUIDString(virStoragePoolPtr pool,
|
|
char *buf)
|
|
{
|
|
VIR_DEBUG("pool=%p, buf=%p", pool, buf);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
virCheckNonNullArgGoto(buf, error);
|
|
|
|
virUUIDFormat(pool->uuid, buf);
|
|
return 0;
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolGetInfo:
|
|
* @pool: pointer to storage pool
|
|
* @info: pointer at which to store info
|
|
*
|
|
* Get volatile information about the storage pool
|
|
* such as free space / usage summary
|
|
*
|
|
* Returns 0 on success, or -1 on failure.
|
|
*/
|
|
int
|
|
virStoragePoolGetInfo(virStoragePoolPtr pool,
|
|
virStoragePoolInfoPtr info)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("pool=%p, info=%p", pool, info);
|
|
|
|
virResetLastError();
|
|
|
|
if (info)
|
|
memset(info, 0, sizeof(*info));
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
virCheckNonNullArgGoto(info, error);
|
|
|
|
conn = pool->conn;
|
|
|
|
if (conn->storageDriver->storagePoolGetInfo) {
|
|
int ret;
|
|
ret = conn->storageDriver->storagePoolGetInfo(pool, info);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolGetXMLDesc:
|
|
* @pool: pointer to storage pool
|
|
* @flags: bitwise-OR of virStorageXMLFlags
|
|
*
|
|
* Fetch an XML document describing all aspects of the
|
|
* storage pool. This is suitable for later feeding back
|
|
* into the virStoragePoolCreateXML method.
|
|
*
|
|
* Returns a XML document (caller frees), or NULL on error
|
|
*/
|
|
char *
|
|
virStoragePoolGetXMLDesc(virStoragePoolPtr pool,
|
|
unsigned int flags)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("pool=%p, flags=0x%x", pool, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, NULL);
|
|
conn = pool->conn;
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolGetXMLDesc) {
|
|
char *ret;
|
|
ret = conn->storageDriver->storagePoolGetXMLDesc(pool, flags);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolGetAutostart:
|
|
* @pool: pointer to storage pool
|
|
* @autostart: location in which to store autostart flag
|
|
*
|
|
* Fetches the value of the autostart flag, which determines
|
|
* whether the pool is automatically started at boot time
|
|
*
|
|
* Returns 0 on success, -1 on failure
|
|
*/
|
|
int
|
|
virStoragePoolGetAutostart(virStoragePoolPtr pool,
|
|
int *autostart)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("pool=%p, autostart=%p", pool, autostart);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
virCheckNonNullArgGoto(autostart, error);
|
|
|
|
conn = pool->conn;
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolGetAutostart) {
|
|
int ret;
|
|
ret = conn->storageDriver->storagePoolGetAutostart(pool, autostart);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolSetAutostart:
|
|
* @pool: pointer to storage pool
|
|
* @autostart: whether the storage pool should be automatically started 0 or 1
|
|
*
|
|
* Configure the storage pool to be automatically started
|
|
* when the host machine boots.
|
|
*
|
|
* Returns 0 on success, -1 on failure
|
|
*/
|
|
int
|
|
virStoragePoolSetAutostart(virStoragePoolPtr pool,
|
|
int autostart)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("pool=%p, autostart=%d", pool, autostart);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
conn = pool->conn;
|
|
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storagePoolSetAutostart) {
|
|
int ret;
|
|
ret = conn->storageDriver->storagePoolSetAutostart(pool, autostart);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolListAllVolumes:
|
|
* @pool: Pointer to storage pool
|
|
* @vols: Pointer to a variable to store the array containing storage volume
|
|
* objects or NULL if the list is not required (just returns number
|
|
* of volumes).
|
|
* @flags: extra flags; not used yet, so callers should always pass 0
|
|
*
|
|
* Collect the list of storage volumes, and allocate an array to store those
|
|
* objects.
|
|
*
|
|
* Returns the number of storage volumes found or -1 and sets @vols to
|
|
* NULL in case of error. On success, the array stored into @vols is
|
|
* guaranteed to have an extra allocated element set to NULL but not included
|
|
* in the return count, to make iteration easier. The caller is responsible
|
|
* for calling virStorageVolFree() on each array element, then calling
|
|
* free() on @vols.
|
|
*/
|
|
int
|
|
virStoragePoolListAllVolumes(virStoragePoolPtr pool,
|
|
virStorageVolPtr **vols,
|
|
unsigned int flags)
|
|
{
|
|
VIR_DEBUG("pool=%p, vols=%p, flags=0x%x", pool, vols, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
|
|
if (pool->conn->storageDriver &&
|
|
pool->conn->storageDriver->storagePoolListAllVolumes) {
|
|
int ret;
|
|
ret = pool->conn->storageDriver->storagePoolListAllVolumes(pool, vols, flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolNumOfVolumes:
|
|
* @pool: pointer to storage pool
|
|
*
|
|
* Fetch the number of storage volumes within a pool
|
|
*
|
|
* Returns the number of storage pools, or -1 on failure
|
|
*/
|
|
int
|
|
virStoragePoolNumOfVolumes(virStoragePoolPtr pool)
|
|
{
|
|
VIR_DEBUG("pool=%p", pool);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
|
|
if (pool->conn->storageDriver && pool->conn->storageDriver->storagePoolNumOfVolumes) {
|
|
int ret;
|
|
ret = pool->conn->storageDriver->storagePoolNumOfVolumes(pool);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolListVolumes:
|
|
* @pool: pointer to storage pool
|
|
* @names: array in which to storage volume names
|
|
* @maxnames: size of names array
|
|
*
|
|
* Fetch list of storage volume names, limiting to
|
|
* at most maxnames.
|
|
*
|
|
* To list the volume objects directly, see virStoragePoolListAllVolumes().
|
|
*
|
|
* Returns the number of names fetched, or -1 on error
|
|
*/
|
|
int
|
|
virStoragePoolListVolumes(virStoragePoolPtr pool,
|
|
char **const names,
|
|
int maxnames)
|
|
{
|
|
VIR_DEBUG("pool=%p, names=%p, maxnames=%d", pool, names, maxnames);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
virCheckNonNullArrayArgGoto(names, maxnames, error);
|
|
virCheckNonNegativeArgGoto(maxnames, error);
|
|
|
|
if (pool->conn->storageDriver && pool->conn->storageDriver->storagePoolListVolumes) {
|
|
int ret;
|
|
ret = pool->conn->storageDriver->storagePoolListVolumes(pool, names, maxnames);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolGetConnect:
|
|
* @vol: pointer to a pool
|
|
*
|
|
* Provides the connection pointer associated with a storage volume. The
|
|
* reference counter on the connection is not increased by this
|
|
* call.
|
|
*
|
|
* Returns the virConnectPtr or NULL in case of failure.
|
|
*/
|
|
virConnectPtr
|
|
virStorageVolGetConnect(virStorageVolPtr vol)
|
|
{
|
|
VIR_DEBUG("vol=%p", vol);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, NULL);
|
|
|
|
return vol->conn;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolLookupByName:
|
|
* @pool: pointer to storage pool
|
|
* @name: name of storage volume
|
|
*
|
|
* Fetch a pointer to a storage volume based on its name
|
|
* within a pool
|
|
*
|
|
* virStorageVolFree should be used to free the resources after the
|
|
* storage volume object is no longer needed.
|
|
*
|
|
* Returns a storage volume, or NULL if not found / error
|
|
*/
|
|
virStorageVolPtr
|
|
virStorageVolLookupByName(virStoragePoolPtr pool,
|
|
const char *name)
|
|
{
|
|
VIR_DEBUG("pool=%p, name=%s", pool, NULLSTR(name));
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, NULL);
|
|
virCheckNonNullArgGoto(name, error);
|
|
|
|
if (pool->conn->storageDriver && pool->conn->storageDriver->storageVolLookupByName) {
|
|
virStorageVolPtr ret;
|
|
ret = pool->conn->storageDriver->storageVolLookupByName(pool, name);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolLookupByKey:
|
|
* @conn: pointer to hypervisor connection
|
|
* @key: globally unique key
|
|
*
|
|
* Fetch a pointer to a storage volume based on its
|
|
* globally unique key
|
|
*
|
|
* virStorageVolFree should be used to free the resources after the
|
|
* storage volume object is no longer needed.
|
|
*
|
|
* Returns a storage volume, or NULL if not found / error
|
|
*/
|
|
virStorageVolPtr
|
|
virStorageVolLookupByKey(virConnectPtr conn,
|
|
const char *key)
|
|
{
|
|
VIR_DEBUG("conn=%p, key=%s", conn, NULLSTR(key));
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, NULL);
|
|
virCheckNonNullArgGoto(key, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storageVolLookupByKey) {
|
|
virStorageVolPtr ret;
|
|
ret = conn->storageDriver->storageVolLookupByKey(conn, key);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolLookupByPath:
|
|
* @conn: pointer to hypervisor connection
|
|
* @path: locally unique path
|
|
*
|
|
* Fetch a pointer to a storage volume based on its
|
|
* locally (host) unique path
|
|
*
|
|
* virStorageVolFree should be used to free the resources after the
|
|
* storage volume object is no longer needed.
|
|
*
|
|
* Returns a storage volume, or NULL if not found / error
|
|
*/
|
|
virStorageVolPtr
|
|
virStorageVolLookupByPath(virConnectPtr conn,
|
|
const char *path)
|
|
{
|
|
VIR_DEBUG("conn=%p, path=%s", conn, NULLSTR(path));
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, NULL);
|
|
virCheckNonNullArgGoto(path, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storageVolLookupByPath) {
|
|
virStorageVolPtr ret;
|
|
ret = conn->storageDriver->storageVolLookupByPath(conn, path);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolGetName:
|
|
* @vol: pointer to storage volume
|
|
*
|
|
* Fetch the storage volume name. This is unique
|
|
* within the scope of a pool
|
|
*
|
|
* Returns the volume name, or NULL on error
|
|
*/
|
|
const char*
|
|
virStorageVolGetName(virStorageVolPtr vol)
|
|
{
|
|
VIR_DEBUG("vol=%p", vol);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, NULL);
|
|
|
|
return vol->name;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolGetKey:
|
|
* @vol: pointer to storage volume
|
|
*
|
|
* Fetch the storage volume key. This is globally
|
|
* unique, so the same volume will have the same
|
|
* key no matter what host it is accessed from
|
|
*
|
|
* Returns the volume key, or NULL on error
|
|
*/
|
|
const char*
|
|
virStorageVolGetKey(virStorageVolPtr vol)
|
|
{
|
|
VIR_DEBUG("vol=%p", vol);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, NULL);
|
|
|
|
return vol->key;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolCreateXML:
|
|
* @pool: pointer to storage pool
|
|
* @xmlDesc: description of volume to create
|
|
* @flags: bitwise-OR of virStorageVolCreateFlags
|
|
*
|
|
* Create a storage volume within a pool based
|
|
* on an XML description. Not all pools support
|
|
* creation of volumes.
|
|
*
|
|
* Since 1.0.1 VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA
|
|
* in flags can be used to get higher performance with
|
|
* qcow2 image files which don't support full preallocation,
|
|
* by creating a sparse image file with metadata.
|
|
*
|
|
* virStorageVolFree should be used to free the resources after the
|
|
* storage volume object is no longer needed.
|
|
*
|
|
* Returns the storage volume, or NULL on error
|
|
*/
|
|
virStorageVolPtr
|
|
virStorageVolCreateXML(virStoragePoolPtr pool,
|
|
const char *xmlDesc,
|
|
unsigned int flags)
|
|
{
|
|
VIR_DEBUG("pool=%p, xmlDesc=%s, flags=0x%x", pool, NULLSTR(xmlDesc), flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, NULL);
|
|
virCheckNonNullArgGoto(xmlDesc, error);
|
|
virCheckReadOnlyGoto(pool->conn->flags, error);
|
|
|
|
if (pool->conn->storageDriver && pool->conn->storageDriver->storageVolCreateXML) {
|
|
virStorageVolPtr ret;
|
|
ret = pool->conn->storageDriver->storageVolCreateXML(pool, xmlDesc, flags);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolCreateXMLFrom:
|
|
* @pool: pointer to parent pool for the new volume
|
|
* @xmlDesc: description of volume to create
|
|
* @clonevol: storage volume to use as input
|
|
* @flags: bitwise-OR of virStorageVolCreateFlags
|
|
*
|
|
* Create a storage volume in the parent pool, using the
|
|
* 'clonevol' volume as input. Information for the new
|
|
* volume (name, perms) are passed via a typical volume
|
|
* XML description.
|
|
*
|
|
* Since 1.0.1 VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA
|
|
* in flags can be used to get higher performance with
|
|
* qcow2 image files which don't support full preallocation,
|
|
* by creating a sparse image file with metadata.
|
|
*
|
|
* virStorageVolFree should be used to free the resources after the
|
|
* storage volume object is no longer needed.
|
|
*
|
|
* Returns the storage volume, or NULL on error
|
|
*/
|
|
virStorageVolPtr
|
|
virStorageVolCreateXMLFrom(virStoragePoolPtr pool,
|
|
const char *xmlDesc,
|
|
virStorageVolPtr clonevol,
|
|
unsigned int flags)
|
|
{
|
|
VIR_DEBUG("pool=%p, xmlDesc=%s, clonevol=%p, flags=0x%x",
|
|
pool, NULLSTR(xmlDesc), clonevol, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, NULL);
|
|
virCheckStorageVolGoto(clonevol, error);
|
|
virCheckNonNullArgGoto(xmlDesc, error);
|
|
virCheckReadOnlyGoto(pool->conn->flags | clonevol->conn->flags, error);
|
|
|
|
if (pool->conn->storageDriver &&
|
|
pool->conn->storageDriver->storageVolCreateXMLFrom) {
|
|
virStorageVolPtr ret;
|
|
ret = pool->conn->storageDriver->storageVolCreateXMLFrom(pool, xmlDesc,
|
|
clonevol, flags);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolDownload:
|
|
* @vol: pointer to volume to download from
|
|
* @stream: stream to use as output
|
|
* @offset: position in @vol to start reading from
|
|
* @length: limit on amount of data to download
|
|
* @flags: bitwise-OR of virStorageVolDownloadFlags
|
|
*
|
|
* Download the content of the volume as a stream. If @length
|
|
* is zero, then the remaining contents of the volume after
|
|
* @offset will be downloaded. Please note that the stream
|
|
* transports the volume itself as is, so the downloaded data may
|
|
* not correspond to guest OS visible state in cases when a
|
|
* complex storage format such as qcow2 or vmdk is used.
|
|
*
|
|
* If VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM is set in @flags
|
|
* effective transmission of holes is enabled. This assumes using
|
|
* the @stream with combination of virStreamSparseRecvAll() or
|
|
* virStreamRecvFlags(stream, ..., flags =
|
|
* VIR_STREAM_RECV_STOP_AT_HOLE) for honouring holes sent by
|
|
* server.
|
|
*
|
|
* This call sets up an asynchronous stream; subsequent use of
|
|
* stream APIs is necessary to transfer the actual data,
|
|
* determine how much data is successfully transferred, and
|
|
* detect any errors. The results will be unpredictable if
|
|
* another active stream is writing to the storage volume.
|
|
*
|
|
* Returns 0, or -1 upon error.
|
|
*/
|
|
int
|
|
virStorageVolDownload(virStorageVolPtr vol,
|
|
virStreamPtr stream,
|
|
unsigned long long offset,
|
|
unsigned long long length,
|
|
unsigned int flags)
|
|
{
|
|
VIR_DEBUG("vol=%p, stream=%p, offset=%llu, length=%llu, flags=0x%x",
|
|
vol, stream, offset, length, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, -1);
|
|
virCheckStreamGoto(stream, error);
|
|
virCheckReadOnlyGoto(vol->conn->flags, error);
|
|
|
|
if (vol->conn != stream->conn) {
|
|
virReportInvalidArg(stream,
|
|
_("stream in %s must match connection of volume '%s'"),
|
|
__FUNCTION__, vol->name);
|
|
goto error;
|
|
}
|
|
|
|
if (vol->conn->storageDriver &&
|
|
vol->conn->storageDriver->storageVolDownload) {
|
|
int ret;
|
|
ret = vol->conn->storageDriver->storageVolDownload(vol,
|
|
stream,
|
|
offset,
|
|
length,
|
|
flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(vol->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolUpload:
|
|
* @vol: pointer to volume to upload
|
|
* @stream: stream to use as input
|
|
* @offset: position to start writing to
|
|
* @length: limit on amount of data to upload
|
|
* @flags: bitwise-OR of virStorageVolUploadFlags
|
|
*
|
|
* Upload new content to the volume from a stream. This call
|
|
* will fail if @offset + @length exceeds the size of the
|
|
* volume. Otherwise, if @length is non-zero, an error
|
|
* will be raised if an attempt is made to upload greater
|
|
* than @length bytes of data. Please note that the stream
|
|
* transports the volume itself as is, so the downloaded data may
|
|
* not correspond to guest OS visible state in cases when a
|
|
* complex storage format such as qcow2 or vmdk is used.
|
|
*
|
|
* If VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM is set in @flags
|
|
* effective transmission of holes is enabled. This assumes using
|
|
* the @stream with combination of virStreamSparseSendAll() or
|
|
* virStreamSendHole() to preserve source file sparseness.
|
|
*
|
|
* This call sets up an asynchronous stream; subsequent use of
|
|
* stream APIs is necessary to transfer the actual data,
|
|
* determine how much data is successfully transferred, and
|
|
* detect any errors. The results will be unpredictable if
|
|
* another active stream is writing to the storage volume.
|
|
*
|
|
* When the data stream is closed whether the upload is successful
|
|
* or not an attempt will be made to refresh the target storage pool
|
|
* if an asynchronous build is not running in order to reflect pool
|
|
* and volume changes as a result of the upload. Depending on
|
|
* the target volume storage backend and the source stream type
|
|
* for a successful upload, the target volume may take on the
|
|
* characteristics from the source stream such as format type,
|
|
* capacity, and allocation.
|
|
*
|
|
* Returns 0, or -1 upon error.
|
|
*/
|
|
int
|
|
virStorageVolUpload(virStorageVolPtr vol,
|
|
virStreamPtr stream,
|
|
unsigned long long offset,
|
|
unsigned long long length,
|
|
unsigned int flags)
|
|
{
|
|
VIR_DEBUG("vol=%p, stream=%p, offset=%llu, length=%llu, flags=0x%x",
|
|
vol, stream, offset, length, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, -1);
|
|
virCheckStreamGoto(stream, error);
|
|
virCheckReadOnlyGoto(vol->conn->flags, error);
|
|
|
|
if (vol->conn != stream->conn) {
|
|
virReportInvalidArg(stream,
|
|
_("stream in %s must match connection of volume '%s'"),
|
|
__FUNCTION__, vol->name);
|
|
goto error;
|
|
}
|
|
|
|
if (vol->conn->storageDriver &&
|
|
vol->conn->storageDriver->storageVolUpload) {
|
|
int ret;
|
|
ret = vol->conn->storageDriver->storageVolUpload(vol,
|
|
stream,
|
|
offset,
|
|
length,
|
|
flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(vol->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolDelete:
|
|
* @vol: pointer to storage volume
|
|
* @flags: bitwise-OR of virStorageVolDeleteFlags
|
|
*
|
|
* Delete the storage volume from the pool
|
|
*
|
|
* Returns 0 on success, or -1 on error
|
|
*/
|
|
int
|
|
virStorageVolDelete(virStorageVolPtr vol,
|
|
unsigned int flags)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("vol=%p, flags=0x%x", vol, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, -1);
|
|
conn = vol->conn;
|
|
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storageVolDelete) {
|
|
int ret;
|
|
ret = conn->storageDriver->storageVolDelete(vol, flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(vol->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolWipe:
|
|
* @vol: pointer to storage volume
|
|
* @flags: extra flags; not used yet, so callers should always pass 0
|
|
*
|
|
* Ensure data previously on a volume is not accessible to future reads.
|
|
*
|
|
* The data to be wiped may include the format and possibly size information,
|
|
* so non-raw images might become raw with a different size. It is storage
|
|
* backend dependent whether the format and size information is regenerated
|
|
* once the initial volume wipe is completed.
|
|
*
|
|
* Depending on the actual volume representation, this call may not
|
|
* overwrite the physical location of the volume. For instance, files
|
|
* stored journaled, log structured, copy-on-write, versioned, and
|
|
* network file systems are known to be problematic.
|
|
*
|
|
* Returns 0 on success, or -1 on error
|
|
*/
|
|
int
|
|
virStorageVolWipe(virStorageVolPtr vol,
|
|
unsigned int flags)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("vol=%p, flags=0x%x", vol, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, -1);
|
|
conn = vol->conn;
|
|
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storageVolWipe) {
|
|
int ret;
|
|
ret = conn->storageDriver->storageVolWipe(vol, flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(vol->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolWipePattern:
|
|
* @vol: pointer to storage volume
|
|
* @algorithm: one of virStorageVolWipeAlgorithm
|
|
* @flags: future flags, use 0 for now
|
|
*
|
|
* Similar to virStorageVolWipe, but one can choose between
|
|
* different wiping algorithms. Also note, that depending on the
|
|
* actual volume representation, this call may not really
|
|
* overwrite the physical location of the volume. For instance,
|
|
* files stored journaled, log structured, copy-on-write,
|
|
* versioned, and network file systems are known to be
|
|
* problematic.
|
|
*
|
|
* Returns 0 on success, or -1 on error.
|
|
*/
|
|
int
|
|
virStorageVolWipePattern(virStorageVolPtr vol,
|
|
unsigned int algorithm,
|
|
unsigned int flags)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("vol=%p, algorithm=%u, flags=0x%x", vol, algorithm, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, -1);
|
|
conn = vol->conn;
|
|
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storageVolWipePattern) {
|
|
int ret;
|
|
ret = conn->storageDriver->storageVolWipePattern(vol, algorithm, flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(vol->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolFree:
|
|
* @vol: pointer to storage volume
|
|
*
|
|
* Release the storage volume handle. The underlying
|
|
* storage volume continues to exist.
|
|
*
|
|
* Returns 0 on success, or -1 on error
|
|
*/
|
|
int
|
|
virStorageVolFree(virStorageVolPtr vol)
|
|
{
|
|
VIR_DEBUG("vol=%p", vol);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, -1);
|
|
|
|
virObjectUnref(vol);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolRef:
|
|
* @vol: the vol to hold a reference on
|
|
*
|
|
* Increment the reference count on the vol. For each
|
|
* additional call to this method, there shall be a corresponding
|
|
* call to virStorageVolFree to release the reference count, once
|
|
* the caller no longer needs the reference to this object.
|
|
*
|
|
* This method is typically useful for applications where multiple
|
|
* threads are using a connection, and it is required that the
|
|
* connection remain open until all threads have finished using
|
|
* it. ie, each new thread using a vol would increment
|
|
* the reference count.
|
|
*
|
|
* Returns 0 in case of success, -1 in case of failure.
|
|
*/
|
|
int
|
|
virStorageVolRef(virStorageVolPtr vol)
|
|
{
|
|
VIR_DEBUG("vol=%p", vol);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, -1);
|
|
|
|
virObjectRef(vol);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolGetInfo:
|
|
* @vol: pointer to storage volume
|
|
* @info: pointer at which to store info
|
|
*
|
|
* Fetches volatile information about the storage
|
|
* volume such as its current allocation
|
|
*
|
|
* Returns 0 on success, or -1 on failure
|
|
*/
|
|
int
|
|
virStorageVolGetInfo(virStorageVolPtr vol,
|
|
virStorageVolInfoPtr info)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("vol=%p, info=%p", vol, info);
|
|
|
|
virResetLastError();
|
|
|
|
if (info)
|
|
memset(info, 0, sizeof(*info));
|
|
|
|
virCheckStorageVolReturn(vol, -1);
|
|
virCheckNonNullArgGoto(info, error);
|
|
|
|
conn = vol->conn;
|
|
|
|
if (conn->storageDriver->storageVolGetInfo) {
|
|
int ret;
|
|
ret = conn->storageDriver->storageVolGetInfo(vol, info);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(vol->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolGetInfoFlags:
|
|
* @vol: pointer to storage volume
|
|
* @info: pointer at which to store info
|
|
* @flags: bitwise-OR of virStorageVolInfoFlags
|
|
*
|
|
* Fetches volatile information about the storage
|
|
* volume such as its current allocation.
|
|
*
|
|
* If the @flags argument is VIR_STORAGE_VOL_GET_PHYSICAL, then the physical
|
|
* bytes used for the volume will be returned in the @info allocation field.
|
|
* This is useful for sparse files and certain volume file types where the
|
|
* physical on disk usage can be different than the calculated allocation value
|
|
* as is the case with qcow2 files.
|
|
*
|
|
* Returns 0 on success, or -1 on failure
|
|
*/
|
|
int
|
|
virStorageVolGetInfoFlags(virStorageVolPtr vol,
|
|
virStorageVolInfoPtr info,
|
|
unsigned int flags)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("vol=%p, info=%p, flags=0x%x", vol, info, flags);
|
|
|
|
virResetLastError();
|
|
|
|
if (info)
|
|
memset(info, 0, sizeof(*info));
|
|
|
|
virCheckStorageVolReturn(vol, -1);
|
|
virCheckNonNullArgGoto(info, error);
|
|
|
|
conn = vol->conn;
|
|
|
|
if (conn->storageDriver->storageVolGetInfoFlags) {
|
|
int ret;
|
|
ret = conn->storageDriver->storageVolGetInfoFlags(vol, info, flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(vol->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolGetXMLDesc:
|
|
* @vol: pointer to storage volume
|
|
* @flags: extra flags; not used yet, so callers should always pass 0
|
|
*
|
|
* Fetch an XML document describing all aspects of
|
|
* the storage volume
|
|
*
|
|
* Returns the XML document, or NULL on error
|
|
*/
|
|
char *
|
|
virStorageVolGetXMLDesc(virStorageVolPtr vol,
|
|
unsigned int flags)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("vol=%p, flags=0x%x", vol, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, NULL);
|
|
conn = vol->conn;
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storageVolGetXMLDesc) {
|
|
char *ret;
|
|
ret = conn->storageDriver->storageVolGetXMLDesc(vol, flags);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(vol->conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolGetPath:
|
|
* @vol: pointer to storage volume
|
|
*
|
|
* Fetch the storage volume path. Depending on the pool
|
|
* configuration this is either persistent across hosts,
|
|
* or dynamically assigned at pool startup. Consult
|
|
* pool documentation for information on getting the
|
|
* persistent naming
|
|
*
|
|
* Returns the storage volume path, or NULL on error. The
|
|
* caller must free() the returned path after use.
|
|
*/
|
|
char *
|
|
virStorageVolGetPath(virStorageVolPtr vol)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("vol=%p", vol);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, NULL);
|
|
conn = vol->conn;
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storageVolGetPath) {
|
|
char *ret;
|
|
ret = conn->storageDriver->storageVolGetPath(vol);
|
|
if (!ret)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(vol->conn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStorageVolResize:
|
|
* @vol: pointer to storage volume
|
|
* @capacity: new capacity, in bytes
|
|
* @flags: bitwise-OR of virStorageVolResizeFlags
|
|
*
|
|
* Changes the capacity of the storage volume @vol to @capacity. The
|
|
* operation will fail if the new capacity requires allocation that would
|
|
* exceed the remaining free space in the parent pool. The contents of
|
|
* the new capacity will appear as all zero bytes. The capacity value will
|
|
* be rounded to the granularity supported by the hypervisor.
|
|
*
|
|
* Normally, the operation will attempt to affect capacity with a minimum
|
|
* impact on allocation (that is, the default operation favors a sparse
|
|
* resize). If @flags contains VIR_STORAGE_VOL_RESIZE_ALLOCATE, then the
|
|
* operation will ensure that allocation is sufficient for the new
|
|
* capacity; this may make the operation take noticeably longer.
|
|
*
|
|
* Normally, the operation treats @capacity as the new size in bytes;
|
|
* but if @flags contains VIR_STORAGE_VOL_RESIZE_DELTA, then @capacity
|
|
* represents the size difference to add to the current size. It is
|
|
* up to the storage pool implementation whether unaligned requests are
|
|
* rounded up to the next valid boundary, or rejected.
|
|
*
|
|
* Normally, this operation should only be used to enlarge capacity;
|
|
* but if @flags contains VIR_STORAGE_VOL_RESIZE_SHRINK, it is possible to
|
|
* attempt a reduction in capacity even though it might cause data loss.
|
|
* If VIR_STORAGE_VOL_RESIZE_DELTA is also present, then @capacity is
|
|
* subtracted from the current size; without it, @capacity represents
|
|
* the absolute new size regardless of whether it is larger or smaller
|
|
* than the current size.
|
|
*
|
|
* Returns 0 on success, or -1 on error.
|
|
*/
|
|
int
|
|
virStorageVolResize(virStorageVolPtr vol,
|
|
unsigned long long capacity,
|
|
unsigned int flags)
|
|
{
|
|
virConnectPtr conn;
|
|
VIR_DEBUG("vol=%p capacity=%llu flags=0x%x", vol, capacity, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStorageVolReturn(vol, -1);
|
|
conn = vol->conn;
|
|
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
|
|
|
/* Zero capacity is only valid with either delta or shrink. */
|
|
if (capacity == 0 && !((flags & VIR_STORAGE_VOL_RESIZE_DELTA) ||
|
|
(flags & VIR_STORAGE_VOL_RESIZE_SHRINK))) {
|
|
virReportInvalidArg(capacity,
|
|
_("capacity in %s cannot be zero without 'delta' "
|
|
"or 'shrink' flags set"),
|
|
__FUNCTION__);
|
|
goto error;
|
|
}
|
|
|
|
if (conn->storageDriver && conn->storageDriver->storageVolResize) {
|
|
int ret;
|
|
ret = conn->storageDriver->storageVolResize(vol, capacity, flags);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(vol->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolIsActive:
|
|
* @pool: pointer to the storage pool object
|
|
*
|
|
* Determine if the storage pool is currently running
|
|
*
|
|
* Returns 1 if running, 0 if inactive, -1 on error
|
|
*/
|
|
int
|
|
virStoragePoolIsActive(virStoragePoolPtr pool)
|
|
{
|
|
VIR_DEBUG("pool=%p", pool);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
|
|
if (pool->conn->storageDriver->storagePoolIsActive) {
|
|
int ret;
|
|
ret = pool->conn->storageDriver->storagePoolIsActive(pool);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virStoragePoolIsPersistent:
|
|
* @pool: pointer to the storage pool object
|
|
*
|
|
* Determine if the storage pool has a persistent configuration
|
|
* which means it will still exist after shutting down
|
|
*
|
|
* Returns 1 if persistent, 0 if transient, -1 on error
|
|
*/
|
|
int
|
|
virStoragePoolIsPersistent(virStoragePoolPtr pool)
|
|
{
|
|
VIR_DEBUG("pool=%p", pool);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckStoragePoolReturn(pool, -1);
|
|
|
|
if (pool->conn->storageDriver->storagePoolIsPersistent) {
|
|
int ret;
|
|
ret = pool->conn->storageDriver->storagePoolIsPersistent(pool);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
error:
|
|
virDispatchError(pool->conn);
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* virConnectStoragePoolEventRegisterAny:
|
|
* @conn: pointer to the connection
|
|
* @pool: pointer to the storage pool
|
|
* @eventID: the event type to receive
|
|
* @cb: callback to the function handling network events
|
|
* @opaque: opaque data to pass on to the callback
|
|
* @freecb: optional function to deallocate opaque when not used anymore
|
|
*
|
|
* Adds a callback to receive notifications of arbitrary storage pool events
|
|
* occurring on a storage pool. This function requires that an event loop
|
|
* has been previously registered with virEventRegisterImpl() or
|
|
* virEventRegisterDefaultImpl().
|
|
*
|
|
* If @pool is NULL, then events will be monitored for any storage pool.
|
|
* If @pool is non-NULL, then only the specific storage pool will be monitored.
|
|
*
|
|
* Most types of events have a callback providing a custom set of parameters
|
|
* for the event. When registering an event, it is thus necessary to use
|
|
* the VIR_STORAGE_POOL_EVENT_CALLBACK() macro to cast the
|
|
* supplied function pointer to match the signature of this method.
|
|
*
|
|
* The virStoragePoolPtr object handle passed into the callback upon delivery
|
|
* of an event is only valid for the duration of execution of the callback.
|
|
* If the callback wishes to keep the storage pool object after the callback
|
|
* returns, it shall take a reference to it, by calling virStoragePoolRef().
|
|
* The reference can be released once the object is no longer required
|
|
* by calling virStoragePoolFree().
|
|
*
|
|
* The return value from this method is a positive integer identifier
|
|
* for the callback. To unregister a callback, this callback ID should
|
|
* be passed to the virConnectStoragePoolEventDeregisterAny() method.
|
|
*
|
|
* Returns a callback identifier on success, -1 on failure.
|
|
*/
|
|
int
|
|
virConnectStoragePoolEventRegisterAny(virConnectPtr conn,
|
|
virStoragePoolPtr pool,
|
|
int eventID,
|
|
virConnectStoragePoolEventGenericCallback cb,
|
|
void *opaque,
|
|
virFreeCallback freecb)
|
|
{
|
|
VIR_DEBUG("conn=%p, pool=%p, eventID=%d, cb=%p, opaque=%p, freecb=%p",
|
|
conn, pool, eventID, cb, opaque, freecb);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, -1);
|
|
if (pool) {
|
|
virCheckStoragePoolGoto(pool, error);
|
|
if (pool->conn != conn) {
|
|
virReportInvalidArg(pool,
|
|
_("storage pool '%s' in %s must match connection"),
|
|
pool->name, __FUNCTION__);
|
|
goto error;
|
|
}
|
|
}
|
|
virCheckNonNullArgGoto(cb, error);
|
|
virCheckNonNegativeArgGoto(eventID, error);
|
|
|
|
if (eventID >= VIR_STORAGE_POOL_EVENT_ID_LAST) {
|
|
virReportInvalidArg(eventID,
|
|
_("eventID in %s must be less than %d"),
|
|
__FUNCTION__, VIR_STORAGE_POOL_EVENT_ID_LAST);
|
|
goto error;
|
|
}
|
|
|
|
if (conn->storageDriver &&
|
|
conn->storageDriver->connectStoragePoolEventRegisterAny) {
|
|
int ret;
|
|
ret = conn->storageDriver->connectStoragePoolEventRegisterAny(conn,
|
|
pool,
|
|
eventID,
|
|
cb,
|
|
opaque,
|
|
freecb);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
error:
|
|
virDispatchError(conn);
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* virConnectStoragePoolEventDeregisterAny:
|
|
* @conn: pointer to the connection
|
|
* @callbackID: the callback identifier
|
|
*
|
|
* Removes an event callback. The callbackID parameter should be the
|
|
* value obtained from a previous virConnectStoragePoolEventRegisterAny() method.
|
|
*
|
|
* Returns 0 on success, -1 on failure
|
|
*/
|
|
int
|
|
virConnectStoragePoolEventDeregisterAny(virConnectPtr conn,
|
|
int callbackID)
|
|
{
|
|
VIR_DEBUG("conn=%p, callbackID=%d", conn, callbackID);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, -1);
|
|
virCheckNonNegativeArgGoto(callbackID, error);
|
|
|
|
if (conn->storageDriver &&
|
|
conn->storageDriver->connectStoragePoolEventDeregisterAny) {
|
|
int ret;
|
|
ret = conn->storageDriver->connectStoragePoolEventDeregisterAny(conn,
|
|
callbackID);
|
|
if (ret < 0)
|
|
goto error;
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
error:
|
|
virDispatchError(conn);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**
|
|
* virConnectGetStoragePoolCapabilities:
|
|
* @conn: pointer to the hypervisor connection
|
|
* @flags: extra flags; not used yet, so callers should always pass 0
|
|
*
|
|
* Prior creating a storage pool (for instance via virStoragePoolCreateXML
|
|
* or virStoragePoolDefineXML) it may be suitable to know what pool types
|
|
* are supported along with the file/disk formats for each pool.
|
|
*
|
|
* Returns NULL in case of error or an XML string defining the capabilities.
|
|
*/
|
|
char *
|
|
virConnectGetStoragePoolCapabilities(virConnectPtr conn,
|
|
unsigned int flags)
|
|
{
|
|
VIR_DEBUG("conn=%p, flags=0x%x", conn, flags);
|
|
|
|
virResetLastError();
|
|
|
|
virCheckConnectReturn(conn, NULL);
|
|
|
|
if (conn->storageDriver &&
|
|
conn->storageDriver->connectGetStoragePoolCapabilities) {
|
|
char *ret;
|
|
ret = conn->storageDriver->connectGetStoragePoolCapabilities(conn,
|
|
flags);
|
|
if (!ret)
|
|
goto error;
|
|
VIR_DEBUG("conn=%p, ret=%s", conn, ret);
|
|
return ret;
|
|
}
|
|
|
|
virReportUnsupportedError();
|
|
|
|
error:
|
|
virDispatchError(conn);
|
|
return NULL;
|
|
}
|