/*
* 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
* .
*/
#include
#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
*
* 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);
virCheckNonNullArgGoto(names, 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);
virCheckNonNullArgGoto(names, 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;
}
/**
* 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 refs=%d", pool, pool ? pool->object.u.s.refs : 0);
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: new flag setting
*
* Sets the autostart flag
*
* 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);
virCheckNonNullArgGoto(names, 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.
*
* 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.
*
* 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 the target storage pool will be refreshed 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 refs=%d", vol, vol ? vol->object.u.s.refs : 0);
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;
}