This patch defines the internal driver API for the storage API calls.
It also provides the cache implementation for the virStoragePoolPtr
and virStorageVolPtr objects. The virStorageVolPtr object is a little
different in that it doesn't reference the virConnectPtr object
directly. Instead it points to the virStoragePoolPtr object. This
makes the reference counting 'interesting', because when we get a
virStorageVolPtr object, we have increment the count on both the pool
and the connection. This was starting to get complex, so to keep it
sane I don't bother with referencing counting on the virStorageVolPtr
object itself.
include/libvirt/virterror.h | 3
src/driver.h | 119 +++++
src/hash.c | 349 +++++++++++++--
src/internal.h | 93 +++-
src/libvirt.c | 975 +++++++++++++++++++++++++++++++++++++++++++-
src/libvirt_sym.version | 4
6 files changed, 1464 insertions(+), 79 deletions(-)
diff -r b5447763aad6 include/libvirt/virterror.h
--- a/include/libvirt/virterror.h Sat Oct 27 16:56:42 2007 -0400
+++ b/include/libvirt/virterror.h Sun Oct 28 22:44:08 2007 -0400
@@ -129,6 +129,9 @@ typedef enum {
VIR_ERR_NO_DOMAIN, /* domain not found or unexpectedly disappeared */
VIR_ERR_NO_NETWORK, /* network not found */
VIR_ERR_INVALID_MAC, /* invalid MAC adress */
+ VIR_ERR_INVALID_STORAGE_POOL, /* invalid storage pool object */
+ VIR_ERR_INVALID_STORAGE_VOL, /* invalid storage vol object */
+ VIR_WAR_NO_STORAGE, /* failed to start storage */
} virErrorNumber;
/**
diff -r b5447763aad6 src/driver.h
--- a/src/driver.h Sat Oct 27 16:56:42 2007 -0400
+++ b/src/driver.h Sun Oct 28 14:34:03 2007 -0400
@@ -414,6 +414,124 @@ struct _virNetworkDriver {
virDrvNetworkSetAutostart networkSetAutostart;
};
+
+typedef int
+ (*virDrvConnectNumOfStoragePools)(virConnectPtr conn);
+typedef int
+ (*virDrvConnectListStoragePools)(virConnectPtr conn,
+ char **const names,
+ int maxnames);
+typedef int
+ (*virDrvConnectNumOfDefinedStoragePools)(virConnectPtr conn);
+typedef int
+ (*virDrvConnectListDefinedStoragePools)(virConnectPtr conn,
+ char **const names,
+ int maxnames);
+typedef virStoragePoolPtr
+ (*virDrvStoragePoolLookupByName)(virConnectPtr conn,
+ const char *name);
+typedef virStoragePoolPtr
+ (*virDrvStoragePoolLookupByUUID)(virConnectPtr conn,
+ const unsigned char *uuid);
+typedef virStoragePoolPtr
+ (*virDrvStoragePoolCreateXML)(virConnectPtr conn,
+ const char *xmlDesc);
+typedef virStoragePoolPtr
+ (*virDrvStoragePoolDefineXML)(virConnectPtr conn,
+ const char *xmlDesc);
+typedef int
+ (*virDrvStoragePoolUndefine)(virStoragePoolPtr pool);
+typedef int
+ (*virDrvStoragePoolCreate)(virStoragePoolPtr pool);
+typedef int
+ (*virDrvStoragePoolShutdown)(virStoragePoolPtr pool);
+typedef int
+ (*virDrvStoragePoolDestroy)(virStoragePoolPtr pool);
+typedef int
+ (*virDrvStoragePoolGetInfo)(virStoragePoolPtr vol,
+ virStoragePoolInfoPtr info);
+typedef char *
+ (*virDrvStoragePoolGetXMLDesc)(virStoragePoolPtr pool,
+ int flags);
+typedef int
+ (*virDrvStoragePoolGetAutostart)(virStoragePoolPtr pool,
+ int *autostart);
+typedef int
+ (*virDrvStoragePoolSetAutostart)(virStoragePoolPtr pool,
+ int autostart);
+typedef int
+ (*virDrvStoragePoolNumOfVolumes)(virStoragePoolPtr pool);
+typedef int
+ (*virDrvStoragePoolListVolumes)(virStoragePoolPtr pool,
+ char **const names,
+ int maxnames);
+typedef virStorageVolPtr
+ (*virDrvStorageVolLookupByName)(virStoragePoolPtr pool,
+ const char *name);
+typedef virStorageVolPtr
+ (*virDrvStorageVolLookupByUUID)(virStoragePoolPtr pool,
+ const unsigned char *uuid);
+typedef virStorageVolPtr
+ (*virDrvStorageVolCreateXML)(virStoragePoolPtr pool,
+ const char *xmldesc,
+ int flags);
+typedef int
+ (*virDrvStorageVolDestroy)(virStorageVolPtr vol);
+typedef int
+ (*virDrvStorageVolGetInfo)(virStorageVolPtr vol,
+ virStorageVolInfoPtr info);
+typedef char *
+ (*virDrvStorageVolGetXMLDesc)(virStorageVolPtr pool,
+ int flags);
+typedef char *
+ (*virDrvStorageVolGetPath)(virStorageVolPtr vol);
+
+
+
+typedef struct _virStorageDriver virStorageDriver;
+typedef virStorageDriver *virStorageDriverPtr;
+
+/**
+ * _virStorageDriver:
+ *
+ * Structure associated to a network virtualization driver, defining the various
+ * entry points for it.
+ *
+ * All drivers must support the following fields/methods:
+ * - open
+ * - close
+ */
+struct _virStorageDriver {
+ const char * name; /* the name of the driver */
+ virDrvOpen open;
+ virDrvClose close;
+ virDrvConnectNumOfStoragePools numOfPools;
+ virDrvConnectListStoragePools listPools;
+ virDrvConnectNumOfDefinedStoragePools numOfDefinedPools;
+ virDrvConnectListDefinedStoragePools listDefinedPools;
+ virDrvStoragePoolLookupByName poolLookupByName;
+ virDrvStoragePoolLookupByUUID poolLookupByUUID;
+ virDrvStoragePoolCreateXML poolCreateXML;
+ virDrvStoragePoolDefineXML poolDefineXML;
+ virDrvStoragePoolUndefine poolUndefine;
+ virDrvStoragePoolCreate poolCreate;
+ virDrvStoragePoolShutdown poolShutdown;
+ virDrvStoragePoolDestroy poolDestroy;
+ virDrvStoragePoolGetInfo poolGetInfo;
+ virDrvStoragePoolGetXMLDesc poolGetXMLDesc;
+ virDrvStoragePoolGetAutostart poolGetAutostart;
+ virDrvStoragePoolSetAutostart poolSetAutostart;
+ virDrvStoragePoolNumOfVolumes poolNumOfVolumes;
+ virDrvStoragePoolListVolumes poolListVolumes;
+ virDrvStorageVolLookupByName volLookupByName;
+ virDrvStorageVolLookupByUUID volLookupByUUID;
+ virDrvStorageVolCreateXML volCreateXML;
+ virDrvStorageVolDestroy volDestroy;
+ virDrvStorageVolGetInfo volGetInfo;
+ virDrvStorageVolGetXMLDesc volGetXMLDesc;
+ virDrvStorageVolGetPath volGetPath;
+};
+
typedef int (*virDrvStateInitialize) (void);
typedef int (*virDrvStateCleanup) (void);
typedef int (*virDrvStateReload) (void);
@@ -436,6 +554,7 @@ struct _virStateDriver {
*/
int virRegisterDriver(virDriverPtr);
int virRegisterNetworkDriver(virNetworkDriverPtr);
+int virRegisterStorageDriver(virStorageDriverPtr);
int virRegisterStateDriver(virStateDriverPtr);
#ifdef __cplusplus
diff -r b5447763aad6 src/hash.c
--- a/src/hash.c Sat Oct 27 16:56:42 2007 -0400
+++ b/src/hash.c Sun Oct 28 22:44:58 2007 -0400
@@ -649,6 +649,20 @@ virNetworkFreeName(virNetworkPtr network
}
/**
+ * virStoragePoolFreeName:
+ * @pool: a storage pool object
+ *
+ * Destroy the storage pool object, this is just used by the storage pool hash callback.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+static int
+virStoragePoolFreeName(virStoragePoolPtr pool, const char *name ATTRIBUTE_UNUSED)
+{
+ return (virStoragePoolFree(pool));
+}
+
+/**
* virGetConnect:
*
* Allocates a new hypervisor connection structure
@@ -675,6 +689,9 @@ virGetConnect(void) {
ret->networks = virHashCreate(20);
if (ret->networks == NULL)
goto failed;
+ ret->storagePools = virHashCreate(20);
+ if (ret->storagePools == NULL)
+ goto failed;
ret->hashes_mux = xmlNewMutex();
if (ret->hashes_mux == NULL)
goto failed;
@@ -688,6 +705,8 @@ failed:
virHashFree(ret->domains, (virHashDeallocator) virDomainFreeName);
if (ret->networks != NULL)
virHashFree(ret->networks, (virHashDeallocator) virNetworkFreeName);
+ if (ret->storagePools != NULL)
+ virHashFree(ret->storagePools, (virHashDeallocator) virStoragePoolFreeName);
if (ret->hashes_mux != NULL)
xmlFreeMutex(ret->hashes_mux);
free(ret);
@@ -695,39 +714,49 @@ failed:
return(NULL);
}
-/**
- * virFreeConnect:
- * @conn: the hypervisor connection
- *
- * Release the connection. if the use count drops to zero, the structure is
- * actually freed.
- *
- * Returns the reference count or -1 in case of failure.
- */
-int
-virFreeConnect(virConnectPtr conn) {
+static int
+virFreeConnectLocked(virConnectPtr conn) {
int ret;
-
- if ((!VIR_IS_CONNECT(conn)) || (conn->hashes_mux == NULL)) {
- virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return(-1);
- }
- xmlMutexLock(conn->hashes_mux);
conn->uses--;
ret = conn->uses;
- if (ret > 0) {
- xmlMutexUnlock(conn->hashes_mux);
- return(ret);
- }
+ if (ret > 0)
+ return(ret);
if (conn->domains != NULL)
virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
if (conn->networks != NULL)
virHashFree(conn->networks, (virHashDeallocator) virNetworkFreeName);
- if (conn->hashes_mux != NULL)
- xmlFreeMutex(conn->hashes_mux);
+ if (conn->storagePools != NULL)
+ virHashFree(conn->storagePools, (virHashDeallocator) virStoragePoolFreeName);
free(conn);
return(0);
+}
+
+/**
+ * virFreeConnect:
+ * @conn: the hypervisor connection
+ *
+ * Release the connection. if the use count drops to zero, the structure is
+ * actually freed.
+ *
+ * Returns the reference count or -1 in case of failure.
+ */
+int
+virFreeConnect(virConnectPtr conn) {
+ int ret;
+ xmlMutexPtr mux;
+
+ if ((!VIR_IS_CONNECT(conn)) || (conn->hashes_mux == NULL)) {
+ virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(-1);
+ }
+ mux = conn->hashes_mux;
+ xmlMutexLock(mux);
+ ret = virFreeConnectLocked(conn);
+ xmlMutexUnlock(mux);
+ if (ret == 0)
+ xmlFreeMutex(mux);
+ return ret;
}
/**
@@ -815,13 +844,15 @@ int
int
virFreeDomain(virConnectPtr conn, virDomainPtr domain) {
int ret = 0;
+ xmlMutexPtr mux;
if ((!VIR_IS_CONNECT(conn)) || (!VIR_IS_CONNECTED_DOMAIN(domain)) ||
(domain->conn != conn) || (conn->hashes_mux == NULL)) {
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
- xmlMutexLock(conn->hashes_mux);
+ mux = conn->hashes_mux;
+ xmlMutexLock(mux);
/*
* decrement the count for the domain
@@ -844,22 +875,14 @@ virFreeDomain(virConnectPtr conn, virDom
free(domain->name);
free(domain);
- /*
- * decrement the count for the connection
- */
- conn->uses--;
- if (conn->uses > 0)
- goto done;
-
- if (conn->domains != NULL)
- virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
- if (conn->hashes_mux != NULL)
- xmlFreeMutex(conn->hashes_mux);
- free(conn);
+ ret = virFreeConnectLocked(conn);
+ xmlMutexUnlock(mux);
+ if (ret == 0)
+ xmlFreeMutex(mux);
return(0);
done:
- xmlMutexUnlock(conn->hashes_mux);
+ xmlMutexUnlock(mux);
return(ret);
}
@@ -947,13 +970,15 @@ int
int
virFreeNetwork(virConnectPtr conn, virNetworkPtr network) {
int ret = 0;
+ xmlMutexPtr mux;
if ((!VIR_IS_CONNECT(conn)) || (!VIR_IS_CONNECTED_NETWORK(network)) ||
(network->conn != conn) || (conn->hashes_mux == NULL)) {
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
- xmlMutexLock(conn->hashes_mux);
+ mux = conn->hashes_mux;
+ xmlMutexLock(mux);
/*
* decrement the count for the network
@@ -975,23 +1000,255 @@ virFreeNetwork(virConnectPtr conn, virNe
free(network->name);
free(network);
+ ret = virFreeConnectLocked(conn);
+ xmlMutexUnlock(mux);
+ if (ret == 0)
+ xmlFreeMutex(mux);
+ return(0);
+
+done:
+ xmlMutexUnlock(mux);
+ return(ret);
+}
+
+/**
+ * virGetStoragePool:
+ * @conn: the hypervisor connection
+ * @name: pointer to the pool name
+ * @uuid: pointer to the uuid
+ *
+ * Lookup if the pool is already registered for that connection,
+ * if yes return a new pointer to it, if no allocate a new structure,
+ * and register it in the table. In any case a corresponding call to
+ * virFreeStoragePool() is needed to not leak data.
+ *
+ * Returns a pointer to the pool, or NULL in case of failure
+ */
+virStoragePoolPtr
+__virGetStoragePool(virConnectPtr conn, const char *name, const unsigned char *uuid) {
+ virStoragePoolPtr ret = NULL;
+
+ if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (uuid == NULL) ||
+ (conn->hashes_mux == NULL)) {
+ virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(NULL);
+ }
+ xmlMutexLock(conn->hashes_mux);
+
+ /* TODO search by UUID first as they are better differenciators */
+
+ ret = (virStoragePoolPtr) virHashLookup(conn->storagePools, name);
+ if (ret != NULL) {
+ /* TODO check the UUID */
+ goto done;
+ }
+
/*
- * decrement the count for the connection
+ * not found, allocate a new one
*/
- conn->uses--;
- if (conn->uses > 0)
+ ret = (virStoragePoolPtr) calloc(1, sizeof(virStoragePool));
+ if (ret == NULL) {
+ virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating storage pool"));
+ goto error;
+ }
+ ret->name = strdup(name);
+ if (ret->name == NULL) {
+ virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating storage pool"));
+ goto error;
+ }
+ ret->magic = VIR_STORAGE_POOL_MAGIC;
+ ret->conn = conn;
+ if (uuid != NULL)
+ memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
+
+ if (virHashAddEntry(conn->storagePools, name, ret) < 0) {
+ virHashError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("failed to add storage pool to connection hash table"));
+ goto error;
+ }
+ conn->uses++;
+done:
+ ret->uses++;
+ xmlMutexUnlock(conn->hashes_mux);
+ return(ret);
+
+error:
+ xmlMutexUnlock(conn->hashes_mux);
+ if (ret != NULL) {
+ if (ret->name != NULL)
+ free(ret->name);
+ free(ret);
+ }
+ return(NULL);
+}
+
+static int
+virFreeStoragePoolLocked(virConnectPtr conn, virStoragePoolPtr pool) {
+ int ret = 0;
+ /*
+ * decrement the count for the pool
+ */
+ pool->uses--;
+ ret = pool->uses;
+ if (ret > 0)
goto done;
- if (conn->networks != NULL)
- virHashFree(conn->networks, (virHashDeallocator) virNetworkFreeName);
- if (conn->hashes_mux != NULL)
- xmlFreeMutex(conn->hashes_mux);
- free(conn);
+ /* TODO search by UUID first as they are better differenciators */
+
+ if (virHashRemoveEntry(conn->storagePools, pool->name, NULL) < 0) {
+ virHashError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("pool missing from connection hash table"));
+ goto done;
+ }
+ pool->magic = -1;
+ if (pool->name)
+ free(pool->name);
+ free(pool);
return(0);
done:
xmlMutexUnlock(conn->hashes_mux);
return(ret);
+}
+/**
+ * virFreeStoragePool:
+ * @conn: the hypervisor connection
+ * @pool: the pool to release
+ *
+ * Release the given storage pool, if the reference count drops to zero, then
+ * the pool is really freed.
+ *
+ * Returns the reference count or -1 in case of failure.
+ */
+int
+virFreeStoragePool(virConnectPtr conn, virStoragePoolPtr pool) {
+ int ret = 0;
+ xmlMutexPtr mux;
+
+ if ((!VIR_IS_CONNECT(conn)) || (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) ||
+ (pool->conn != conn) || (conn->hashes_mux == NULL)) {
+ virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(-1);
+ }
+ mux = conn->hashes_mux;
+ xmlMutexLock(mux);
+
+ ret = virFreeStoragePoolLocked(conn, pool);
+ if (ret > 0)
+ goto done;
+
+ ret = virFreeConnectLocked(conn);
+ xmlMutexUnlock(mux);
+ if (ret == 0)
+ xmlFreeMutex(mux);
+ return(0);
+
+done:
+ xmlMutexUnlock(mux);
+ return(ret);
+}
+
+/**
+ * virGetStorageVol:
+ * @pool: the storage pool
+ * @name: pointer to the pool name
+ * @uuid: pointer to the uuid
+ *
+ * Lookup if the storage is already registered for that connection,
+ * if yes return a new pointer to it, if no allocate a new structure,
+ * and register it in the table. In any case a corresponding call to
+ * virFreeStorageVol() is needed to not leak data.
+ *
+ * Returns a pointer to the vol, or NULL in case of failure
+ */
+virStorageVolPtr
+__virGetStorageVol(virStoragePoolPtr pool, const char *name, const unsigned char *uuid)
{
+ virStorageVolPtr ret = NULL;
+
+ if ((!VIR_IS_STORAGE_POOL(pool)) || (name == NULL) || (uuid == NULL) ||
+ (pool->conn->hashes_mux == NULL)) {
+ virHashError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(NULL);
+ }
+ xmlMutexLock(pool->conn->hashes_mux);
+
+ /*
+ * not found, allocate a new one
+ */
+ ret = (virStorageVolPtr) calloc(1, sizeof(virStorageVol));
+ if (ret == NULL) {
+ virHashError(pool->conn, VIR_ERR_NO_MEMORY, _("allocating storage
vol"));
+ goto error;
+ }
+ ret->name = strdup(name);
+ if (ret->name == NULL) {
+ virHashError(pool->conn, VIR_ERR_NO_MEMORY, _("allocating storage
vol"));
+ goto error;
+ }
+ ret->magic = VIR_STORAGE_VOL_MAGIC;
+ ret->pool = pool;
+ if (uuid != NULL)
+ memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
+
+ pool->uses++;
+ pool->conn->uses++;
+ xmlMutexUnlock(pool->conn->hashes_mux);
+ return(ret);
+
+error:
+ xmlMutexUnlock(pool->conn->hashes_mux);
+ if (ret != NULL) {
+ if (ret->name != NULL)
+ free(ret->name);
+ free(ret);
+ }
+ return(NULL);
+}
+
+/**
+ * virFreeStorageVol:
+ * @conn: the hypervisor connection
+ * @vol: the vol to release
+ *
+ * Release the given storage volume
+ *
+ * Returns zero on success, or -1 in case of failure.
+ */
+int
+virFreeStorageVol(virConnectPtr conn, virStorageVolPtr vol) {
+ int ret = 0;
+ xmlMutexPtr mux;
+ virStoragePoolPtr pool;
+
+ if ((!VIR_IS_CONNECT(conn)) || (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) ||
+ (vol->pool->conn != conn)) {
+ virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(-1);
+ }
+ pool = vol->pool;
+ mux = conn->hashes_mux;
+ xmlMutexLock(conn->hashes_mux);
+
+ vol->magic = -1;
+ if (vol->name)
+ free(vol->name);
+ free(vol);
+
+ ret = virFreeStoragePoolLocked(conn, pool);
+ if (ret > 0)
+ goto done;
+
+ ret = virFreeConnectLocked(conn);
+ xmlMutexUnlock(mux);
+ if (ret == 0)
+ xmlFreeMutex(mux);
+ return(0);
+
+ return(0);
+
+done:
+ xmlMutexUnlock(mux);
+ return(0);
}
/*
diff -r b5447763aad6 src/internal.h
--- a/src/internal.h Sat Oct 27 16:56:42 2007 -0400
+++ b/src/internal.h Sun Oct 28 14:34:03 2007 -0400
@@ -90,7 +90,7 @@ extern "C" {
* VIR_DOMAIN_MAGIC:
*
* magic value used to protect the API when pointers to domain structures
- * are passed down by the uers.
+ * are passed down by the users.
*/
#define VIR_DOMAIN_MAGIC 0xDEAD4321
#define VIR_IS_DOMAIN(obj) ((obj) && (obj)->magic==VIR_DOMAIN_MAGIC)
@@ -100,12 +100,33 @@ extern "C" {
* VIR_NETWORK_MAGIC:
*
* magic value used to protect the API when pointers to network structures
- * are passed down by the uers.
+ * are passed down by the users.
*/
#define VIR_NETWORK_MAGIC 0xDEAD1234
#define VIR_IS_NETWORK(obj) ((obj) && (obj)->magic==VIR_NETWORK_MAGIC)
#define VIR_IS_CONNECTED_NETWORK(obj) (VIR_IS_NETWORK(obj) &&
VIR_IS_CONNECT((obj)->conn))
+/**
+ * VIR_STORAGE_POOL_MAGIC:
+ *
+ * magic value used to protect the API when pointers to storage pool structures
+ * are passed down by the users.
+ */
+#define VIR_STORAGE_POOL_MAGIC 0xDEAD5678
+#define VIR_IS_STORAGE_POOL(obj) ((obj) &&
(obj)->magic==VIR_STORAGE_POOL_MAGIC)
+#define VIR_IS_CONNECTED_STORAGE_POOL(obj) (VIR_IS_STORAGE_POOL(obj) &&
VIR_IS_CONNECT((obj)->conn))
+
+/**
+ * VIR_STORAGE_VOL_MAGIC:
+ *
+ * magic value used to protect the API when pointers to storage vol structures
+ * are passed down by the users.
+ */
+#define VIR_STORAGE_VOL_MAGIC 0xDEAD8765
+#define VIR_IS_STORAGE_VOL(obj) ((obj) &&
(obj)->magic==VIR_STORAGE_VOL_MAGIC)
+#define VIR_IS_CONNECTED_STORAGE_VOL(obj) (VIR_IS_STORAGE_VOL(obj) &&
VIR_IS_CONNECTED_STORAGE_POOL((obj)->pool) \
+ &&
VIR_IS_CONNECT((obj)->pool->conn))
+
/*
* arbitrary limitations
*/
@@ -130,6 +151,7 @@ struct _virConnect {
/* The underlying hypervisor driver and network driver. */
virDriverPtr driver;
virNetworkDriverPtr networkDriver;
+ virStorageDriverPtr storageDriver;
/* Private data pointer which can be used by driver and
* network driver as they wish.
@@ -137,6 +159,7 @@ struct _virConnect {
*/
void * privateData;
void * networkPrivateData;
+ void * storagePrivateData;
/* Per-connection error. */
virError err; /* the last error */
@@ -146,7 +169,8 @@ struct _virConnect {
/* misc */
xmlMutexPtr hashes_mux;/* a mutex to protect the domain and networks hash tables */
virHashTablePtr domains;/* hash table for known domains */
- virHashTablePtr networks;/* hash table for known domains */
+ virHashTablePtr networks;/* hash table for known networks */
+ virHashTablePtr storagePools;/* hash table for known storage pools */
int flags; /* a set of connection flags */
};
@@ -175,6 +199,33 @@ struct _virNetwork {
virConnectPtr conn; /* pointer back to the connection */
char *name; /* the network external name */
unsigned char uuid[VIR_UUID_BUFLEN]; /* the network unique identifier */
+};
+
+/**
+* _virNetwork:
+*
+* Internal structure associated to a domain
+*/
+struct _virStoragePool {
+ unsigned int magic; /* specific value to check */
+ int uses; /* reference count */
+ virConnectPtr conn; /* pointer back to the connection */
+ char *name; /* the storage pool external name */
+ unsigned char uuid[VIR_UUID_BUFLEN]; /* the storage pool unique identifier */
+};
+
+/**
+* _virNetwork:
+*
+* Internal structure associated to a domain.
+* NB, this is not reference counted. They
+* are directly created/freed as needed.
+*/
+struct _virStorageVol {
+ unsigned int magic; /* specific value to check */
+ virStoragePoolPtr pool; /* pointer back to the storage pool */
+ char *name; /* the storage vol external name */
+ unsigned char uuid[VIR_UUID_BUFLEN]; /* the storage vol unique identifier */
};
/*
@@ -208,21 +259,33 @@ const char *__virErrorMsg(virErrorNumber
* *
************************************************************************/
-virConnectPtr virGetConnect (void);
-int virFreeConnect (virConnectPtr conn);
-virDomainPtr __virGetDomain (virConnectPtr conn,
- const char *name,
- const unsigned char *uuid);
-int virFreeDomain (virConnectPtr conn,
- virDomainPtr domain);
-virNetworkPtr __virGetNetwork (virConnectPtr conn,
- const char *name,
- const unsigned char *uuid);
-int virFreeNetwork (virConnectPtr conn,
- virNetworkPtr domain);
+virConnectPtr virGetConnect (void);
+int virFreeConnect (virConnectPtr conn);
+virDomainPtr __virGetDomain (virConnectPtr conn,
+ const char *name,
+ const unsigned char *uuid);
+int virFreeDomain (virConnectPtr conn,
+ virDomainPtr domain);
+virNetworkPtr __virGetNetwork (virConnectPtr conn,
+ const char *name,
+ const unsigned char *uuid);
+int virFreeNetwork (virConnectPtr conn,
+ virNetworkPtr domain);
+virStoragePoolPtr __virGetStoragePool (virConnectPtr conn,
+ const char *name,
+ const unsigned char *uuid);
+int virFreeStoragePool (virConnectPtr conn,
+ virStoragePoolPtr domain);
+virStorageVolPtr __virGetStorageVol (virStoragePoolPtr pool,
+ const char *name,
+ const unsigned char *uuid);
+int virFreeStorageVol (virConnectPtr conn,
+ virStorageVolPtr domain);
#define virGetDomain(c,n,u) __virGetDomain((c),(n),(u))
#define virGetNetwork(c,n,u) __virGetNetwork((c),(n),(u))
+#define virGetStoragePool(c,n,u) __virGetStoragePool((c),(n),(u))
+#define virGetStorageVol(c,n,u) __virGetStorageVol((c),(n),(u))
int __virStateInitialize(void);
int __virStateCleanup(void);
diff -r b5447763aad6 src/libvirt.c
--- a/src/libvirt.c Sat Oct 27 16:56:42 2007 -0400
+++ b/src/libvirt.c Sun Oct 28 22:44:52 2007 -0400
@@ -30,6 +30,7 @@
#include "xen_unified.h"
#include "remote_internal.h"
#include "qemu_driver.h"
+#include "storage_driver.h"
#ifdef WITH_OPENVZ
#include "openvz_driver.h"
#endif
@@ -44,6 +45,8 @@ static int virDriverTabCount = 0;
static int virDriverTabCount = 0;
static virNetworkDriverPtr virNetworkDriverTab[MAX_DRIVERS];
static int virNetworkDriverTabCount = 0;
+static virStorageDriverPtr virStorageDriverTab[MAX_DRIVERS];
+static int virStorageDriverTabCount = 0;
static virStateDriverPtr virStateDriverTab[MAX_DRIVERS];
static int virStateDriverTabCount = 0;
static int initialized = 0;
@@ -52,10 +55,11 @@ static int initialized = 0;
* are printed to stderr for debugging.
*/
#ifdef ENABLE_DEBUG
+static int debug = 0;
#define DEBUG(fs,...) \
- fprintf (stderr, "libvirt: %s (" fs ")\n", __func__,
__VA_ARGS__)
+ do { if (debug) fprintf (stderr, "libvirt: %s (" fs ")\n",
__func__, __VA_ARGS__); } while (0)
#define DEBUG0 \
- fprintf (stderr, "libvirt: %s ()\n", __func__)
+ do { if (debug) fprintf (stderr, "libvirt: %s ()\n", __func__); } while
(0)
#else
#define DEBUG0
#define DEBUG(fs,...)
@@ -73,10 +77,14 @@ int
int
virInitialize(void)
{
- DEBUG0;
+ char *debugFlag = getenv("LIBVIRT_DEBUG");
+ if (debugFlag && *debugFlag)
+ debug = 1;
+
if (initialized)
return(0);
initialized = 1;
+ DEBUG0;
if (!bindtextdomain(GETTEXT_PACKAGE, LOCALEBASEDIR))
return (-1);
@@ -97,6 +105,7 @@ virInitialize(void)
#ifdef WITH_OPENVZ
if (openvzRegister() == -1) return -1;
#endif
+ if (storageRegister() == -1) return -1;
#ifdef WITH_REMOTE
if (remoteRegister () == -1) return -1;
#endif
@@ -201,6 +210,58 @@ virLibNetworkError(virNetworkPtr network
}
/**
+ * virLibStoragePoolError:
+ * @conn: the connection if available
+ * @error: the error noumber
+ * @info: extra information string
+ *
+ * Handle an error at the connection level
+ */
+static void
+virLibStoragePoolError(virStoragePoolPtr pool, virErrorNumber error,
+ const char *info)
+{
+ virConnectPtr conn = NULL;
+ const char *errmsg;
+
+ if (error == VIR_ERR_OK)
+ return;
+
+ errmsg = __virErrorMsg(error, info);
+ if (error != VIR_ERR_INVALID_STORAGE_POOL)
+ conn = pool->conn;
+
+ __virRaiseError(conn, NULL, NULL, VIR_FROM_STORAGE, error, VIR_ERR_ERROR,
+ errmsg, info, NULL, 0, 0, errmsg, info);
+}
+
+/**
+ * virLibStorageVolError:
+ * @conn: the connection if available
+ * @error: the error noumber
+ * @info: extra information string
+ *
+ * Handle an error at the connection level
+ */
+static void
+virLibStorageVolError(virStorageVolPtr vol, virErrorNumber error,
+ const char *info)
+{
+ virConnectPtr conn = NULL;
+ const char *errmsg;
+
+ if (error == VIR_ERR_OK)
+ return;
+
+ errmsg = __virErrorMsg(error, info);
+ if (error != VIR_ERR_INVALID_STORAGE_VOL)
+ conn = vol->pool->conn;
+
+ __virRaiseError(conn, NULL, NULL, VIR_FROM_STORAGE, error, VIR_ERR_ERROR,
+ errmsg, info, NULL, 0, 0, errmsg, info);
+}
+
+/**
* virRegisterNetworkDriver:
* @driver: pointer to a network driver block
*
@@ -226,6 +287,34 @@ virRegisterNetworkDriver(virNetworkDrive
virNetworkDriverTab[virNetworkDriverTabCount] = driver;
return virNetworkDriverTabCount++;
+}
+
+/**
+ * virRegisterStorageDriver:
+ * @driver: pointer to a storage driver block
+ *
+ * Register a storage virtualization driver
+ *
+ * Returns the driver priority or -1 in case of error.
+ */
+int
+virRegisterStorageDriver(virStorageDriverPtr driver)
+{
+ if (virInitialize() < 0)
+ return -1;
+
+ if (driver == NULL) {
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(-1);
+ }
+
+ if (virStorageDriverTabCount >= MAX_DRIVERS) {
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(-1);
+ }
+
+ virStorageDriverTab[virStorageDriverTabCount] = driver;
+ return virStorageDriverTabCount++;
}
/**
@@ -417,21 +506,24 @@ do_open (const char *name, int flags)
}
#ifdef ENABLE_DEBUG
- fprintf (stderr, "libvirt: do_open: proceeding with name=%s\n", name);
+ DEBUG("proceeding with name=%s", name);
#endif
+
+
+ /* Primary driver is for domains. At least one must succeed */
for (i = 0; i < virDriverTabCount; i++) {
#ifdef ENABLE_DEBUG
- fprintf (stderr, "libvirt: do_open: trying driver %d (%s) ...\n",
- i, virDriverTab[i]->name);
+ DEBUG("trying driver %d (%s) ...",
+ i, virDriverTab[i]->name);
#endif
res = virDriverTab[i]->open (ret, name, flags);
#ifdef ENABLE_DEBUG
- fprintf (stderr, "libvirt: do_open: driver %d %s returned %s\n",
- i, virDriverTab[i]->name,
- res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
- (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
- (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown
status")));
+ DEBUG("driver %d %s returned %s",
+ i, virDriverTab[i]->name,
+ res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
+ (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
+ (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown
status")));
#endif
if (res == VIR_DRV_OPEN_ERROR) goto failed;
else if (res == VIR_DRV_OPEN_SUCCESS) {
@@ -446,14 +538,16 @@ do_open (const char *name, int flags)
goto failed;
}
+
+ /* Secondary driver for networks. Optional */
for (i = 0; i < virNetworkDriverTabCount; i++) {
res = virNetworkDriverTab[i]->open (ret, name, flags);
#ifdef ENABLE_DEBUG
- fprintf (stderr, "libvirt: do_open: network driver %d %s returned
%s\n",
- i, virNetworkDriverTab[i]->name,
- res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
- (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
- (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown
status")));
+ DEBUG("network driver %d %s returned %s",
+ i, virNetworkDriverTab[i]->name,
+ res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
+ (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
+ (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown
status")));
#endif
if (res == VIR_DRV_OPEN_ERROR) {
if (STREQ(virNetworkDriverTab[i]->name, "remote")) {
@@ -467,6 +561,29 @@ do_open (const char *name, int flags)
}
}
+
+ /* Secondary driver for storage. Optional */
+ for (i = 0; i < virStorageDriverTabCount; i++) {
+ res = virStorageDriverTab[i]->open (ret, name, flags);
+#ifdef ENABLE_DEBUG
+ DEBUG("storage driver %d %s returned %s",
+ i, virStorageDriverTab[i]->name,
+ res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
+ (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
+ (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown
status")));
+#endif
+ if (res == VIR_DRV_OPEN_ERROR) {
+ if (STREQ(virStorageDriverTab[i]->name, "remote")) {
+ virLibConnWarning (NULL, VIR_WAR_NO_STORAGE,
+ "Is the daemon running ?");
+ }
+ break;
+ } else if (res == VIR_DRV_OPEN_SUCCESS) {
+ ret->storageDriver = virStorageDriverTab[i];
+ break;
+ }
+ }
+
if (flags & VIR_DRV_OPEN_RO) {
ret->flags = VIR_CONNECT_RO;
}
@@ -537,6 +654,8 @@ virConnectClose(virConnectPtr conn)
if (conn->networkDriver)
conn->networkDriver->close (conn);
+ if (conn->storageDriver)
+ conn->storageDriver->close (conn);
conn->driver->close (conn);
if (virFreeConnect(conn) < 0)
@@ -3360,6 +3479,830 @@ virNetworkSetAutostart(virNetworkPtr net
return -1;
}
+
+/**
+ * virStoragePoolGetConnect:
+ * @net: pointer to a poool
+ *
+ * Provides the connection pointer associated with a storage poolk. The
+ * reference counter on the connection is not increased by this
+ * call.
+ *
+ * WARNING: When writing libvirt bindings in other languages, do
+ * not use this function. Instead, store the connection and
+ * the pool object together.
+ *
+ * Returns the virConnectPtr or NULL in case of failure.
+ */
+virConnectPtr
+virStoragePoolGetConnect (virStoragePoolPtr pool)
+{
+ DEBUG("pool=%p", pool);
+
+ if (!VIR_IS_STORAGE_POOL (pool)) {
+ virLibStoragePoolError (NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return NULL;
+ }
+ return pool->conn;
+}
+
+/*
+ * List active storage pools
+ */
+int
+virConnectNumOfStoragePools (virConnectPtr conn)
+{
+ DEBUG("conn=%p", conn);
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->numOfPools)
+ return conn->storageDriver->numOfPools (conn);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int
+virConnectListStoragePools (virConnectPtr conn,
+ char **const names,
+ int maxnames)
+{
+ DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
+
+ if ((names == NULL) || (maxnames < 0)) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->listPools)
+ return conn->storageDriver->listPools (conn, names, maxnames);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+
+}
+
+int
+virConnectNumOfDefinedStoragePools(virConnectPtr conn)
+{
+ DEBUG("conn=%p", conn);
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->numOfDefinedPools)
+ return conn->storageDriver->numOfDefinedPools (conn);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+
+int
+virConnectListDefinedStoragePools(virConnectPtr conn,
+ char **const names,
+ int maxnames)
+{
+ DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
+
+ if ((names == NULL) || (maxnames < 0)) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->listDefinedPools)
+ return conn->storageDriver->listDefinedPools (conn, names, maxnames);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+
+virStoragePoolPtr
+virStoragePoolLookupByName(virConnectPtr conn,
+ const char *name)
+{
+ DEBUG("conn=%p, name=%s", conn, name);
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (name == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolLookupByName)
+ return conn->storageDriver->poolLookupByName (conn, name);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+
+virStoragePoolPtr
+virStoragePoolLookupByUUID(virConnectPtr conn,
+ const unsigned char *uuid)
+{
+ DEBUG("conn=%p, uuid=%s", conn, uuid);
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (uuid == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolLookupByUUID)
+ return conn->storageDriver->poolLookupByUUID (conn, uuid);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+
+}
+
+
+virStoragePoolPtr
+virStoragePoolLookupByUUIDString(virConnectPtr conn,
+ const char *uuidstr)
+{
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ DEBUG("conn=%p, uuidstr=%s", conn, uuidstr);
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (uuidstr == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (virUUIDParse(uuidstr, uuid) < 0) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ return virStoragePoolLookupByUUID(conn, uuid);
+}
+
+virStoragePoolPtr
+virStoragePoolCreateXML(virConnectPtr conn,
+ const char *xmlDesc)
+{
+ DEBUG("conn=%p, xmlDesc=%s", conn, xmlDesc);
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (xmlDesc == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolCreateXML)
+ return conn->storageDriver->poolCreateXML (conn, xmlDesc);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+virStoragePoolPtr
+virStoragePoolDefineXML(virConnectPtr conn,
+ const char *xml)
+{
+ DEBUG("conn=%p, xml=%s", conn, xml);
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ return (NULL);
+ }
+ if (xml == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolDefineXML)
+ return conn->storageDriver->poolDefineXML (conn, xml);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+
+}
+
+int
+virStoragePoolUndefine(virStoragePoolPtr pool)
+{
+ virConnectPtr conn;
+ DEBUG("pool=%p", pool);
+
+ if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
+ return (-1);
+ }
+ conn = pool->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolUndefine)
+ return conn->storageDriver->poolUndefine (pool);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+
+}
+
+int
+virStoragePoolCreate(virStoragePoolPtr pool)
+{
+ virConnectPtr conn;
+ DEBUG("pool=%p", pool);
+
+ if (pool == NULL) {
+ TODO;
+ return (-1);
+ }
+ if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (-1);
+ }
+ conn = pool->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolCreate)
+ return conn->storageDriver->poolCreate (pool);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+
+}
+
+int
+virStoragePoolShutdown(virStoragePoolPtr pool)
+{
+ virConnectPtr conn;
+ DEBUG("pool=%p", pool);
+
+ if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (-1);
+ }
+
+ conn = pool->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolShutdown)
+ return conn->storageDriver->poolShutdown (pool);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+
+int
+virStoragePoolDestroy (virStoragePoolPtr pool)
+{
+ virConnectPtr conn;
+ DEBUG("pool=%p", pool);
+
+ if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (-1);
+ }
+
+ conn = pool->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->poolDestroy)
+ return conn->storageDriver->poolDestroy (pool);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int
+virStoragePoolFree (virStoragePoolPtr pool)
+{
+ DEBUG("pool=%p", pool);
+
+ if (!VIR_IS_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (-1);
+ }
+ if (virFreeStoragePool(pool->conn, pool) < 0)
+ return (-1);
+ return(0);
+
+}
+
+const char*
+virStoragePoolGetName(virStoragePoolPtr pool)
+{
+ DEBUG("pool=%p", pool);
+
+ if (!VIR_IS_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (NULL);
+ }
+ return (pool->name);
+
+}
+
+
+int
+virStoragePoolGetUUID(virStoragePoolPtr pool,
+ unsigned char *uuid)
+{
+ DEBUG("pool=%p, uuid=%p", pool, uuid);
+
+ if (!VIR_IS_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (-1);
+ }
+ if (uuid == NULL) {
+ virLibStoragePoolError(pool, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ memcpy(uuid, &pool->uuid[0], VIR_UUID_BUFLEN);
+
+ return (0);
+
+}
+
+int
+virStoragePoolGetUUIDString(virStoragePoolPtr pool,
+ char *buf)
+{
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ DEBUG("pool=%p, buf=%p", pool, buf);
+
+ if (!VIR_IS_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (-1);
+ }
+ if (buf == NULL) {
+ virLibStoragePoolError(pool, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ if (virStoragePoolGetUUID(pool, &uuid[0]))
+ return (-1);
+
+ virUUIDFormat(uuid, buf);
+ return (0);
+
+}
+
+int
+virStoragePoolGetInfo(virStoragePoolPtr pool,
+ virStoragePoolInfoPtr info)
+{
+ virConnectPtr conn;
+ DEBUG("pool=%p, info=%p", pool, info);
+
+ if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (-1);
+ }
+ if (info == NULL) {
+ virLibStoragePoolError(pool, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ memset(info, 0, sizeof(virStoragePoolInfo));
+
+ conn = pool->conn;
+
+ if (conn->storageDriver->poolGetInfo)
+ return conn->storageDriver->poolGetInfo (pool, info);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+
+}
+
+char *
+virStoragePoolGetXMLDesc(virStoragePoolPtr pool,
+ int flags)
+{
+ virConnectPtr conn;
+ DEBUG("pool=%p, flags=%d", pool, flags);
+
+ if (!VIR_IS_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (NULL);
+ }
+ if (flags != 0) {
+ virLibStoragePoolError(pool, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ conn = pool->conn;
+
+ if (conn->storageDriver && conn->storageDriver->poolGetXMLDesc)
+ return conn->storageDriver->poolGetXMLDesc (pool, flags);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+
+}
+
+int
+virStoragePoolGetAutostart(virStoragePoolPtr pool,
+ int *autostart)
+{
+ virConnectPtr conn;
+ DEBUG("pool=%p, autostart=%p", pool, autostart);
+
+ if (!VIR_IS_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (-1);
+ }
+ if (!autostart) {
+ virLibStoragePoolError(pool, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ conn = pool->conn;
+
+ if (conn->storageDriver && conn->storageDriver->poolGetAutostart)
+ return conn->storageDriver->poolGetAutostart (pool, autostart);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int
+virStoragePoolSetAutostart(virStoragePoolPtr pool,
+ int autostart)
+{
+ virConnectPtr conn;
+ DEBUG("pool=%p, autostart=%d", pool, autostart);
+
+ if (!VIR_IS_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (-1);
+ }
+
+ conn = pool->conn;
+
+ if (conn->storageDriver && conn->storageDriver->poolSetAutostart)
+ return conn->storageDriver->poolSetAutostart (pool, autostart);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int
+virStoragePoolNumOfVolumes(virStoragePoolPtr pool)
+{
+ DEBUG("pool=%p", pool);
+
+ if (!VIR_IS_STORAGE_POOL(pool)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (-1);
+ }
+
+ if (pool->conn->storageDriver &&
pool->conn->storageDriver->poolNumOfVolumes)
+ return pool->conn->storageDriver->poolNumOfVolumes (pool);
+
+ virLibConnError (pool->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+
+int
+virStoragePoolListVolumes(virStoragePoolPtr pool,
+ char **const names,
+ int maxnames)
+{
+ DEBUG("pool=%p, names=%p, maxnames=%d", pool, names, maxnames);
+
+ if (!VIR_IS_STORAGE_POOL(pool)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_STORAGE_POOL, __FUNCTION__);
+ return (-1);
+ }
+
+ if ((names == NULL) || (maxnames < 0)) {
+ virLibConnError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ if (pool->conn->storageDriver &&
pool->conn->storageDriver->poolListVolumes)
+ return pool->conn->storageDriver->poolListVolumes (pool, names,
maxnames);
+
+ virLibConnError (pool->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+virStorageVolPtr
+virStorageVolLookupByName(virStoragePoolPtr pool,
+ const char *name)
+{
+ DEBUG("pool=%p, name=%s", pool, name);
+
+ if (!VIR_IS_STORAGE_POOL(pool)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (name == NULL) {
+ virLibConnError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (pool->conn->storageDriver &&
pool->conn->storageDriver->volLookupByName)
+ return pool->conn->storageDriver->volLookupByName (pool, name);
+
+ virLibConnError (pool->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+virStorageVolPtr
+virStorageVolLookupByUUID(virStoragePoolPtr pool,
+ const unsigned char *uuid)
+{
+ DEBUG("pool=%p, uuid=%p", pool, uuid);
+
+ if (!VIR_IS_STORAGE_POOL(pool)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (uuid == NULL) {
+ virLibConnError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (pool->conn->storageDriver &&
pool->conn->storageDriver->volLookupByUUID)
+ return pool->conn->storageDriver->volLookupByUUID (pool, uuid);
+
+ virLibConnError (pool->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+virStorageVolPtr
+virStorageVolLookupByUUIDString(virStoragePoolPtr pool,
+ const char *uuidstr)
+{
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ DEBUG("pool=%p, uuidstr=%s", pool, uuidstr);
+
+ if (!VIR_IS_STORAGE_POOL(pool)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (uuidstr == NULL) {
+ virLibConnError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (virUUIDParse(uuidstr, uuid) < 0) {
+ virLibConnError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ return virStorageVolLookupByUUID(pool, uuid);
+}
+
+const char*
+virStorageVolGetName(virStorageVolPtr vol)
+{
+ DEBUG("vol=%p", vol);
+
+ if (!VIR_IS_STORAGE_VOL(vol)) {
+ virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+ return (NULL);
+ }
+ return (vol->name);
+}
+
+int
+virStorageVolGetUUID(virStorageVolPtr vol,
+ unsigned char *uuid)
+{
+ DEBUG("vol=%p, uuid=%p", vol, uuid);
+
+ if (!VIR_IS_STORAGE_VOL(vol)) {
+ virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+ return (-1);
+ }
+ if (uuid == NULL) {
+ virLibStorageVolError(vol, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ memcpy(uuid, &vol->uuid[0], VIR_UUID_BUFLEN);
+
+ return (0);
+
+}
+
+
+int
+virStorageVolGetUUIDString(virStorageVolPtr vol,
+ char *buf)
+{
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ DEBUG("vol=%p, buf=%p", vol, buf);
+
+ if (!VIR_IS_STORAGE_VOL(vol)) {
+ virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+ return (-1);
+ }
+ if (buf == NULL) {
+ virLibStorageVolError(vol, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ if (virStorageVolGetUUID(vol, &uuid[0]))
+ return (-1);
+
+ virUUIDFormat(uuid, buf);
+ return (0);
+}
+
+
+
+virStorageVolPtr
+virStorageVolCreateXML(virStoragePoolPtr pool,
+ const char *xmldesc,
+ int flags)
+{
+ virConnectPtr conn;
+ DEBUG("pool=%p", pool);
+
+ if (pool == NULL) {
+ TODO;
+ return (NULL);
+ }
+ if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
+ virLibStoragePoolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+ return (NULL);
+ }
+ conn = pool->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ return (NULL);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->volCreateXML)
+ return conn->storageDriver->volCreateXML (pool, xmldesc, flags);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+int
+virStorageVolDestroy(virStorageVolPtr vol)
+{
+ virConnectPtr conn;
+ DEBUG("vol=%p", vol);
+
+ if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
+ virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+ return (-1);
+ }
+
+ conn = vol->pool->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibStorageVolError(vol, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->storageDriver && conn->storageDriver->volDestroy)
+ return conn->storageDriver->volDestroy (vol);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int
+virStorageVolFree(virStorageVolPtr vol)
+{
+ DEBUG("vol=%p", vol);
+
+ if (!VIR_IS_STORAGE_VOL(vol)) {
+ virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+ return (-1);
+ }
+ if (virFreeStorageVol(vol->pool->conn, vol) < 0)
+ return (-1);
+ return(0);
+}
+
+int
+virStorageVolGetInfo(virStorageVolPtr vol,
+ virStorageVolInfoPtr info)
+{
+ virConnectPtr conn;
+ DEBUG("vol=%p, info=%p", vol, info);
+
+ if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
+ virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+ return (-1);
+ }
+ if (info == NULL) {
+ virLibStorageVolError(vol, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ memset(info, 0, sizeof(virStorageVolInfo));
+
+ conn = vol->pool->conn;
+
+ if (conn->storageDriver->volGetInfo)
+ return conn->storageDriver->volGetInfo (vol, info);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+char *
+virStorageVolGetXMLDesc(virStorageVolPtr vol,
+ int flags)
+{
+ virConnectPtr conn;
+ DEBUG("vol=%p, flags=%d", vol, flags);
+
+ if (!VIR_IS_STORAGE_VOL(vol)) {
+ virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+ return (NULL);
+ }
+ if (flags != 0) {
+ virLibStorageVolError(vol, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ conn = vol->pool->conn;
+
+ if (conn->storageDriver && conn->storageDriver->volGetXMLDesc)
+ return conn->storageDriver->volGetXMLDesc (vol, flags);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+
+}
+
+char *
+virStorageVolGetPath(virStorageVolPtr vol)
+{
+ virConnectPtr conn;
+ DEBUG("vol=%p", vol);
+
+ if (!VIR_IS_STORAGE_VOL(vol)) {
+ virLibStorageVolError(NULL, VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+ return (NULL);
+ }
+
+ conn = vol->pool->conn;
+
+ if (conn->storageDriver && conn->storageDriver->volGetPath)
+ return conn->storageDriver->volGetPath (vol);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+
/*
* vim: set tabstop=4:
* vim: set shiftwidth=4:
diff -r b5447763aad6 src/libvirt_sym.version
--- a/src/libvirt_sym.version Sat Oct 27 16:56:42 2007 -0400
+++ b/src/libvirt_sym.version Sun Oct 28 14:34:03 2007 -0400
@@ -119,8 +119,8 @@
virStoragePoolSetAutostart;
virStoragePoolGetAutostart;
- virConnectNumOfStorageVolumes;
- virConnectListStorageVolumes;
+ virStoragePoolNumOfVolumes;
+ virStoragePoolListVolumes;
virStorageVolCreateXML;
virStorageVolDestroy;
virStorageVolFree;
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules:
http://search.cpan.org/~danberr/ -=|
|=- Projects:
http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|