This provides the implementation of the remote driver client end. In the same way
as the network APIs, all the storage API calls have to go to server, since the
APIs have state to maintain. So things are setup such that no matter what hypervisor
is being used, this remote driver will provide the storage API impls.
The implementation here is just the methodical serialization & de-serialization
of objects to/from the XDR wire format. The style follows that of the network APIs.
remote_internal.c | 722 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 716 insertions(+), 6 deletions(-)
diff -r 658fbf7974c1 src/remote_internal.c
--- a/src/remote_internal.c Sun Oct 28 14:34:26 2007 -0400
+++ b/src/remote_internal.c Sun Oct 28 22:44:25 2007 -0400
@@ -70,7 +70,7 @@ struct private_data {
char *type; /* Cached return from remoteType. */
int counter; /* Generates serial numbers for RPC. */
char *uri; /* Original (remote) URI. */
- int networkOnly; /* Only used for network API */
+ int localUses; /* Ref count for private data */
};
#define GET_PRIVATE(conn,retcode) \
@@ -89,13 +89,25 @@ struct private_data {
return (retcode); \
}
+#define GET_STORAGE_PRIVATE(conn,retcode) \
+ struct private_data *priv = (struct private_data *) (conn)->storagePrivateData; \
+ if (!priv || priv->magic != MAGIC) { \
+ error (conn, VIR_ERR_INVALID_ARG, \
+ "tried to use a closed or uninitialised handle"); \
+ return (retcode); \
+ }
+
static int call (virConnectPtr conn, struct private_data *priv, int in_open, int proc_nr,
xdrproc_t args_filter, char *args, xdrproc_t ret_filter, char *ret);
static void error (virConnectPtr conn, virErrorNumber code, const char *info);
static void server_error (virConnectPtr conn, remote_error *err);
static virDomainPtr get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain
domain);
static virNetworkPtr get_nonnull_network (virConnectPtr conn, remote_nonnull_network
network);
+static virStoragePoolPtr get_nonnull_storage_pool (virConnectPtr conn,
remote_nonnull_storage_pool pool);
+static virStorageVolPtr get_nonnull_storage_vol (virConnectPtr conn,
remote_nonnull_storage_vol vol);
static void make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src);
static void make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr
net_src);
+static void make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst,
virStoragePoolPtr vol_src);
+static void make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst,
virStorageVolPtr vol_src);
/*----------------------------------------------------------------------*/
@@ -2414,7 +2426,7 @@ remoteNetworkOpen (virConnectPtr conn,
free(priv);
} else {
priv->magic = MAGIC;
- priv->networkOnly = 1;
+ priv->localUses = 1;
conn->networkPrivateData = priv;
}
return ret;
@@ -2426,10 +2438,13 @@ remoteNetworkClose (virConnectPtr conn)
{
int ret = 0;
GET_NETWORK_PRIVATE (conn, -1);
- if (priv->networkOnly) {
- ret = doRemoteClose(conn, priv);
- free(priv);
- conn->networkPrivateData = NULL;
+ if (priv->localUses) {
+ priv->localUses--;
+ if (!priv->localUses) {
+ ret = doRemoteClose(conn, priv);
+ free(priv);
+ conn->networkPrivateData = NULL;
+ }
}
return ret;
}
@@ -2756,6 +2771,634 @@ remoteNetworkSetAutostart (virNetworkPtr
return 0;
}
+
+
+
+
+/*----------------------------------------------------------------------*/
+
+static int
+remoteStorageOpen (virConnectPtr conn,
+ const char *uri_str,
+ int flags)
+{
+ if (inside_daemon)
+ return VIR_DRV_OPEN_DECLINED;
+
+ if (conn &&
+ conn->driver &&
+ strcmp (conn->driver->name, "remote") == 0) {
+ /* If we're here, the remote driver is already
+ * in use due to a) a QEMU uri, or b) a remote
+ * URI. So we can re-use existing connection
+ */
+ conn->storagePrivateData = conn->privateData;
+ return VIR_DRV_OPEN_SUCCESS;
+ } else if (conn->networkDriver &&
+ strcmp (conn->networkDriver->name, "remote") == 0) {
+ conn->storagePrivateData = conn->networkPrivateData;
+ ((struct private_data *)conn->storagePrivateData)->localUses++;
+ return VIR_DRV_OPEN_SUCCESS;
+ } else {
+ /* Using a non-remote driver, so we need to open a
+ * new connection for network APIs, forcing it to
+ * use the UNIX transport. This handles Xen driver
+ * which doesn't have its own impl of the network APIs.
+ */
+ struct private_data *priv = malloc (sizeof(struct private_data));
+ int ret, rflags = 0;
+ if (!priv) {
+ error (NULL, VIR_ERR_NO_MEMORY, "struct private_data");
+ return VIR_DRV_OPEN_ERROR;
+ }
+ if (flags & VIR_DRV_OPEN_RO)
+ rflags |= VIR_DRV_OPEN_REMOTE_RO;
+ rflags |= VIR_DRV_OPEN_REMOTE_UNIX;
+
+ memset(priv, 0, sizeof(struct private_data));
+ priv->magic = DEAD;
+ priv->sock = -1;
+ ret = doRemoteOpen(conn, priv, uri_str, rflags);
+ if (ret != VIR_DRV_OPEN_SUCCESS) {
+ conn->storagePrivateData = NULL;
+ free(priv);
+ } else {
+ priv->magic = MAGIC;
+ priv->localUses = 1;
+ conn->storagePrivateData = priv;
+ }
+ return ret;
+ }
+}
+
+static int
+remoteStorageClose (virConnectPtr conn)
+{
+ int ret = 0;
+ GET_STORAGE_PRIVATE (conn, -1);
+ if (priv->localUses) {
+ priv->localUses--;
+ if (!priv->localUses) {
+ ret = doRemoteClose(conn, priv);
+ free(priv);
+ conn->storagePrivateData = NULL;
+ }
+ }
+ return ret;
+}
+
+static int
+remoteNumOfStoragePools (virConnectPtr conn)
+{
+ remote_num_of_storage_pools_ret ret;
+ GET_STORAGE_PRIVATE (conn, -1);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_STORAGE_POOLS,
+ (xdrproc_t) xdr_void, (char *) NULL,
+ (xdrproc_t) xdr_remote_num_of_storage_pools_ret, (char *) &ret) == -1)
+ return -1;
+
+ return ret.num;
+}
+
+static int
+remoteListStoragePools (virConnectPtr conn, char **const names, int maxnames)
+{
+ int i;
+ remote_list_storage_pools_args args;
+ remote_list_storage_pools_ret ret;
+ GET_STORAGE_PRIVATE (conn, -1);
+
+ if (maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX) {
+ error (conn, VIR_ERR_RPC, "maxnames >
REMOTE_STORAGE_POOL_NAME_LIST_MAX");
+ return -1;
+ }
+ args.maxnames = maxnames;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_LIST_STORAGE_POOLS,
+ (xdrproc_t) xdr_remote_list_storage_pools_args, (char *) &args,
+ (xdrproc_t) xdr_remote_list_storage_pools_ret, (char *) &ret) == -1)
+ return -1;
+
+ if (ret.names.names_len > maxnames) {
+ error (conn, VIR_ERR_RPC, "ret.names.names_len > maxnames");
+ xdr_free ((xdrproc_t) xdr_remote_list_storage_pools_ret, (char *) &ret);
+ return -1;
+ }
+
+ /* This call is caller-frees (although that isn't clear from
+ * the documentation). However xdr_free will free up both the
+ * names and the list of pointers, so we have to strdup the
+ * names here.
+ */
+ for (i = 0; i < ret.names.names_len; ++i)
+ names[i] = strdup (ret.names.names_val[i]);
+
+ xdr_free ((xdrproc_t) xdr_remote_list_storage_pools_ret, (char *) &ret);
+
+ return ret.names.names_len;
+}
+
+static int
+remoteNumOfDefinedStoragePools (virConnectPtr conn)
+{
+ remote_num_of_defined_storage_pools_ret ret;
+ GET_STORAGE_PRIVATE (conn, -1);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_DEFINED_STORAGE_POOLS,
+ (xdrproc_t) xdr_void, (char *) NULL,
+ (xdrproc_t) xdr_remote_num_of_defined_storage_pools_ret, (char *) &ret)
== -1)
+ return -1;
+
+ return ret.num;
+}
+
+static int
+remoteListDefinedStoragePools (virConnectPtr conn,
+ char **const names, int maxnames)
+{
+ int i;
+ remote_list_defined_storage_pools_args args;
+ remote_list_defined_storage_pools_ret ret;
+ GET_STORAGE_PRIVATE (conn, -1);
+
+ if (maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX) {
+ error (conn, VIR_ERR_RPC, "maxnames >
REMOTE_STORAGE_POOL_NAME_LIST_MAX");
+ return -1;
+ }
+ args.maxnames = maxnames;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_LIST_DEFINED_STORAGE_POOLS,
+ (xdrproc_t) xdr_remote_list_defined_storage_pools_args, (char *)
&args,
+ (xdrproc_t) xdr_remote_list_defined_storage_pools_ret, (char *) &ret)
== -1)
+ return -1;
+
+ if (ret.names.names_len > maxnames) {
+ error (conn, VIR_ERR_RPC, "ret.names.names_len > maxnames");
+ xdr_free ((xdrproc_t) xdr_remote_list_defined_storage_pools_ret, (char *)
&ret);
+ return -1;
+ }
+
+ /* This call is caller-frees (although that isn't clear from
+ * the documentation). However xdr_free will free up both the
+ * names and the list of pointers, so we have to strdup the
+ * names here.
+ */
+ for (i = 0; i < ret.names.names_len; ++i)
+ names[i] = strdup (ret.names.names_val[i]);
+
+ xdr_free ((xdrproc_t) xdr_remote_list_defined_storage_pools_ret, (char *) &ret);
+
+ return ret.names.names_len;
+}
+
+static virStoragePoolPtr
+remoteStoragePoolLookupByUUID (virConnectPtr conn,
+ const unsigned char *uuid)
+{
+ virStoragePoolPtr pool;
+ remote_storage_pool_lookup_by_uuid_args args;
+ remote_storage_pool_lookup_by_uuid_ret ret;
+ GET_STORAGE_PRIVATE (conn, NULL);
+
+ memcpy (args.uuid, uuid, VIR_UUID_BUFLEN);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_UUID,
+ (xdrproc_t) xdr_remote_storage_pool_lookup_by_uuid_args, (char *)
&args,
+ (xdrproc_t) xdr_remote_storage_pool_lookup_by_uuid_ret, (char *) &ret)
== -1)
+ return NULL;
+
+ pool = get_nonnull_storage_pool (conn, ret.pool);
+ xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_uuid_ret, (char *)
&ret);
+
+ return pool;
+}
+
+static virStoragePoolPtr
+remoteStoragePoolLookupByName (virConnectPtr conn,
+ const char *name)
+{
+ virStoragePoolPtr pool;
+ remote_storage_pool_lookup_by_name_args args;
+ remote_storage_pool_lookup_by_name_ret ret;
+ GET_STORAGE_PRIVATE (conn, NULL);
+
+ args.name = (char *) name;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_NAME,
+ (xdrproc_t) xdr_remote_storage_pool_lookup_by_name_args, (char *)
&args,
+ (xdrproc_t) xdr_remote_storage_pool_lookup_by_name_ret, (char *) &ret)
== -1)
+ return NULL;
+
+ pool = get_nonnull_storage_pool (conn, ret.pool);
+ xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_name_ret, (char *)
&ret);
+
+ return pool;
+}
+
+static virStoragePoolPtr
+remoteStoragePoolCreateXML (virConnectPtr conn, const char *xmlDesc)
+{
+ virStoragePoolPtr pool;
+ remote_storage_pool_create_xml_args args;
+ remote_storage_pool_create_xml_ret ret;
+ GET_STORAGE_PRIVATE (conn, NULL);
+
+ args.xml = (char *) xmlDesc;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_STORAGE_POOL_CREATE_XML,
+ (xdrproc_t) xdr_remote_storage_pool_create_xml_args, (char *) &args,
+ (xdrproc_t) xdr_remote_storage_pool_create_xml_ret, (char *) &ret) ==
-1)
+ return NULL;
+
+ pool = get_nonnull_storage_pool (conn, ret.pool);
+ xdr_free ((xdrproc_t) &xdr_remote_storage_pool_create_xml_ret, (char *)
&ret);
+
+ return pool;
+}
+
+static virStoragePoolPtr
+remoteStoragePoolDefineXML (virConnectPtr conn, const char *xml)
+{
+ virStoragePoolPtr pool;
+ remote_storage_pool_define_xml_args args;
+ remote_storage_pool_define_xml_ret ret;
+ GET_STORAGE_PRIVATE (conn, NULL);
+
+ args.xml = (char *) xml;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_STORAGE_POOL_DEFINE_XML,
+ (xdrproc_t) xdr_remote_storage_pool_define_xml_args, (char *) &args,
+ (xdrproc_t) xdr_remote_storage_pool_define_xml_ret, (char *) &ret) ==
-1)
+ return NULL;
+
+ pool = get_nonnull_storage_pool (conn, ret.pool);
+ xdr_free ((xdrproc_t) &xdr_remote_storage_pool_define_xml_ret, (char *)
&ret);
+
+ return pool;
+}
+
+static int
+remoteStoragePoolUndefine (virStoragePoolPtr pool)
+{
+ remote_storage_pool_undefine_args args;
+ GET_STORAGE_PRIVATE (pool->conn, -1);
+
+ make_nonnull_storage_pool (&args.pool, pool);
+
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_UNDEFINE,
+ (xdrproc_t) xdr_remote_storage_pool_undefine_args, (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ return -1;
+
+ return 0;
+}
+
+static int
+remoteStoragePoolCreate (virStoragePoolPtr pool)
+{
+ remote_storage_pool_create_args args;
+ GET_STORAGE_PRIVATE (pool->conn, -1);
+
+ make_nonnull_storage_pool (&args.pool, pool);
+
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_CREATE,
+ (xdrproc_t) xdr_remote_storage_pool_create_args, (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ return -1;
+
+ return 0;
+}
+
+static int
+remoteStoragePoolShutdown (virStoragePoolPtr pool)
+{
+ remote_storage_pool_destroy_args args;
+ GET_STORAGE_PRIVATE (pool->conn, -1);
+
+ make_nonnull_storage_pool (&args.pool, pool);
+
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_DESTROY,
+ (xdrproc_t) xdr_remote_storage_pool_destroy_args, (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ return -1;
+
+ return 0;
+}
+
+static int
+remoteStoragePoolDestroy (virStoragePoolPtr pool)
+{
+ remote_storage_pool_destroy_args args;
+ GET_STORAGE_PRIVATE (pool->conn, -1);
+
+ make_nonnull_storage_pool (&args.pool, pool);
+
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_DESTROY,
+ (xdrproc_t) xdr_remote_storage_pool_destroy_args, (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ return -1;
+
+ return 0;
+}
+
+static int
+remoteStoragePoolGetInfo (virStoragePoolPtr pool, virStoragePoolInfoPtr info)
+{
+ remote_storage_pool_get_info_args args;
+ remote_storage_pool_get_info_ret ret;
+ GET_STORAGE_PRIVATE (pool->conn, -1);
+
+ make_nonnull_storage_pool (&args.pool, pool);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_GET_INFO,
+ (xdrproc_t) xdr_remote_storage_pool_get_info_args, (char *) &args,
+ (xdrproc_t) xdr_remote_storage_pool_get_info_ret, (char *) &ret) ==
-1)
+ return -1;
+
+ info->state = ret.state;
+ info->capacity = ret.capacity;
+ info->allocation = ret.allocation;
+
+ return 0;
+}
+
+static char *
+remoteStoragePoolDumpXML (virStoragePoolPtr pool, int flags)
+{
+ remote_storage_pool_dump_xml_args args;
+ remote_storage_pool_dump_xml_ret ret;
+ GET_STORAGE_PRIVATE (pool->conn, NULL);
+
+ make_nonnull_storage_pool (&args.pool, pool);
+ args.flags = flags;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_DUMP_XML,
+ (xdrproc_t) xdr_remote_storage_pool_dump_xml_args, (char *) &args,
+ (xdrproc_t) xdr_remote_storage_pool_dump_xml_ret, (char *) &ret) ==
-1)
+ return NULL;
+
+ /* Caller frees. */
+ return ret.xml;
+}
+
+static int
+remoteStoragePoolGetAutostart (virStoragePoolPtr pool, int *autostart)
+{
+ remote_storage_pool_get_autostart_args args;
+ remote_storage_pool_get_autostart_ret ret;
+ GET_STORAGE_PRIVATE (pool->conn, -1);
+
+ make_nonnull_storage_pool (&args.pool, pool);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_GET_AUTOSTART,
+ (xdrproc_t) xdr_remote_storage_pool_get_autostart_args, (char *)
&args,
+ (xdrproc_t) xdr_remote_storage_pool_get_autostart_ret, (char *) &ret)
== -1)
+ return -1;
+
+ if (autostart) *autostart = ret.autostart;
+
+ return 0;
+}
+
+static int
+remoteStoragePoolSetAutostart (virStoragePoolPtr pool, int autostart)
+{
+ remote_storage_pool_set_autostart_args args;
+ GET_STORAGE_PRIVATE (pool->conn, -1);
+
+ make_nonnull_storage_pool (&args.pool, pool);
+ args.autostart = autostart;
+
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_SET_AUTOSTART,
+ (xdrproc_t) xdr_remote_storage_pool_set_autostart_args, (char *)
&args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+remoteStoragePoolNumOfVolumes (virStoragePoolPtr pool)
+{
+ remote_storage_pool_num_of_volumes_args args;
+ remote_storage_pool_num_of_volumes_ret ret;
+ GET_STORAGE_PRIVATE (pool->conn, -1);
+
+ make_nonnull_storage_pool(&args.pool, pool);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_NUM_OF_VOLUMES,
+ (xdrproc_t) xdr_remote_storage_pool_num_of_volumes_args, (char *)
&args,
+ (xdrproc_t) xdr_remote_storage_pool_num_of_volumes_ret, (char *) &ret)
== -1)
+ return -1;
+
+ return ret.num;
+}
+
+static int
+remoteStoragePoolListVolumes (virStoragePoolPtr pool, char **const names, int maxnames)
+{
+ int i;
+ remote_storage_pool_list_volumes_args args;
+ remote_storage_pool_list_volumes_ret ret;
+ GET_STORAGE_PRIVATE (pool->conn, -1);
+
+ if (maxnames > REMOTE_STORAGE_VOL_NAME_LIST_MAX) {
+ error (pool->conn, VIR_ERR_RPC, "maxnames >
REMOTE_STORAGE_VOL_NAME_LIST_MAX");
+ return -1;
+ }
+ args.maxnames = maxnames;
+ make_nonnull_storage_pool(&args.pool, pool);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_LIST_VOLUMES,
+ (xdrproc_t) xdr_remote_storage_pool_list_volumes_args, (char *) &args,
+ (xdrproc_t) xdr_remote_storage_pool_list_volumes_ret, (char *) &ret) ==
-1)
+ return -1;
+
+ if (ret.names.names_len > maxnames) {
+ error (pool->conn, VIR_ERR_RPC, "ret.names.names_len >
maxnames");
+ xdr_free ((xdrproc_t) xdr_remote_storage_pool_list_volumes_ret, (char *)
&ret);
+ return -1;
+ }
+
+ /* This call is caller-frees (although that isn't clear from
+ * the documentation). However xdr_free will free up both the
+ * names and the list of pointers, so we have to strdup the
+ * names here.
+ */
+ for (i = 0; i < ret.names.names_len; ++i)
+ names[i] = strdup (ret.names.names_val[i]);
+
+ xdr_free ((xdrproc_t) xdr_remote_storage_pool_list_volumes_ret, (char *) &ret);
+
+ return ret.names.names_len;
+}
+
+
+
+static virStorageVolPtr
+remoteStorageVolLookupByUUID (virStoragePoolPtr pool,
+ const unsigned char *uuid)
+{
+ virStorageVolPtr vol;
+ remote_storage_vol_lookup_by_uuid_args args;
+ remote_storage_vol_lookup_by_uuid_ret ret;
+ GET_STORAGE_PRIVATE (pool->conn, NULL);
+
+ make_nonnull_storage_pool(&args.pool, pool);
+ memcpy (args.uuid, uuid, VIR_UUID_BUFLEN);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_LOOKUP_BY_UUID,
+ (xdrproc_t) xdr_remote_storage_vol_lookup_by_uuid_args, (char *)
&args,
+ (xdrproc_t) xdr_remote_storage_vol_lookup_by_uuid_ret, (char *) &ret)
== -1)
+ return NULL;
+
+ vol = get_nonnull_storage_vol (pool->conn, ret.vol);
+ xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_uuid_ret, (char *)
&ret);
+
+ return vol;
+}
+
+static virStorageVolPtr
+remoteStorageVolLookupByName (virStoragePoolPtr pool,
+ const char *name)
+{
+ virStorageVolPtr vol;
+ remote_storage_vol_lookup_by_name_args args;
+ remote_storage_vol_lookup_by_name_ret ret;
+ GET_STORAGE_PRIVATE (pool->conn, NULL);
+
+ make_nonnull_storage_pool(&args.pool, pool);
+ args.name = (char *) name;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_LOOKUP_BY_NAME,
+ (xdrproc_t) xdr_remote_storage_vol_lookup_by_name_args, (char *)
&args,
+ (xdrproc_t) xdr_remote_storage_vol_lookup_by_name_ret, (char *) &ret)
== -1)
+ return NULL;
+
+ vol = get_nonnull_storage_vol (pool->conn, ret.vol);
+ xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_name_ret, (char *)
&ret);
+
+ return vol;
+}
+
+static virStorageVolPtr
+remoteStorageVolCreateXML (virStoragePoolPtr pool, const char *xmlDesc, int flags)
+{
+ virStorageVolPtr vol;
+ remote_storage_vol_create_xml_args args;
+ remote_storage_vol_create_xml_ret ret;
+ GET_STORAGE_PRIVATE (pool->conn, NULL);
+
+ make_nonnull_storage_pool(&args.pool, pool);
+ args.xml = (char *) xmlDesc;
+ args.flags = flags;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_CREATE_XML,
+ (xdrproc_t) xdr_remote_storage_vol_create_xml_args, (char *) &args,
+ (xdrproc_t) xdr_remote_storage_vol_create_xml_ret, (char *) &ret) ==
-1)
+ return NULL;
+
+ vol = get_nonnull_storage_vol (pool->conn, ret.vol);
+ xdr_free ((xdrproc_t) &xdr_remote_storage_vol_create_xml_ret, (char *)
&ret);
+
+ return vol;
+}
+
+static int
+remoteStorageVolDestroy (virStorageVolPtr vol)
+{
+ remote_storage_vol_destroy_args args;
+ GET_STORAGE_PRIVATE (vol->pool->conn, -1);
+
+ make_nonnull_storage_vol (&args.vol, vol);
+
+ if (call (vol->pool->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_DESTROY,
+ (xdrproc_t) xdr_remote_storage_vol_destroy_args, (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ return -1;
+
+ return 0;
+}
+
+static int
+remoteStorageVolGetInfo (virStorageVolPtr vol, virStorageVolInfoPtr info)
+{
+ remote_storage_vol_get_info_args args;
+ remote_storage_vol_get_info_ret ret;
+ GET_STORAGE_PRIVATE (vol->pool->conn, -1);
+
+ make_nonnull_storage_vol (&args.vol, vol);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (vol->pool->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_GET_INFO,
+ (xdrproc_t) xdr_remote_storage_vol_get_info_args, (char *) &args,
+ (xdrproc_t) xdr_remote_storage_vol_get_info_ret, (char *) &ret) == -1)
+ return -1;
+
+ info->type = ret.type;
+ info->capacity = ret.capacity;
+ info->allocation = ret.allocation;
+
+ return 0;
+}
+
+static char *
+remoteStorageVolDumpXML (virStorageVolPtr vol, int flags)
+{
+ remote_storage_vol_dump_xml_args args;
+ remote_storage_vol_dump_xml_ret ret;
+ GET_STORAGE_PRIVATE (vol->pool->conn, NULL);
+
+ make_nonnull_storage_vol (&args.vol, vol);
+ args.flags = flags;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (vol->pool->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_DUMP_XML,
+ (xdrproc_t) xdr_remote_storage_vol_dump_xml_args, (char *) &args,
+ (xdrproc_t) xdr_remote_storage_vol_dump_xml_ret, (char *) &ret) == -1)
+ return NULL;
+
+ /* Caller frees. */
+ return ret.xml;
+}
+
+static char *
+remoteStorageVolGetPath (virStorageVolPtr vol)
+{
+ remote_storage_vol_get_path_args args;
+ remote_storage_vol_get_path_ret ret;
+ GET_NETWORK_PRIVATE (vol->pool->conn, NULL);
+
+ make_nonnull_storage_vol (&args.vol, vol);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (vol->pool->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_GET_PATH,
+ (xdrproc_t) xdr_remote_storage_vol_get_path_args, (char *) &args,
+ (xdrproc_t) xdr_remote_storage_vol_get_path_ret, (char *) &ret) == -1)
+ return NULL;
+
+ /* Caller frees. */
+ return ret.name;
+}
+
/*----------------------------------------------------------------------*/
@@ -3096,6 +3739,25 @@ get_nonnull_network (virConnectPtr conn,
return virGetNetwork (conn, network.name, BAD_CAST network.uuid);
}
+static virStoragePoolPtr
+get_nonnull_storage_pool (virConnectPtr conn, remote_nonnull_storage_pool pool)
+{
+ return virGetStoragePool (conn, pool.name, BAD_CAST pool.uuid);
+}
+
+static virStorageVolPtr
+get_nonnull_storage_vol (virConnectPtr conn, remote_nonnull_storage_vol vol)
+{
+ virStoragePoolPtr pool;
+ virStorageVolPtr ret;
+ pool = get_nonnull_storage_pool (conn, vol.pool);
+ if (pool == NULL)
+ return NULL;
+ ret = virGetStorageVol (pool, vol.name, BAD_CAST vol.uuid);
+ virStoragePoolFree(pool);
+ return ret;
+}
+
/* Make remote_nonnull_domain and remote_nonnull_network. */
static void
make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src)
@@ -3110,6 +3772,21 @@ make_nonnull_network (remote_nonnull_net
{
net_dst->name = net_src->name;
memcpy (net_dst->uuid, net_src->uuid, VIR_UUID_BUFLEN);
+}
+
+static void
+make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr
pool_src)
+{
+ pool_dst->name = pool_src->name;
+ memcpy (pool_dst->uuid, pool_src->uuid, VIR_UUID_BUFLEN);
+}
+
+static void
+make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src)
+{
+ make_nonnull_storage_pool(&vol_dst->pool, vol_src->pool);
+ vol_dst->name = vol_src->name;
+ memcpy (vol_dst->uuid, vol_src->uuid, VIR_UUID_BUFLEN);
}
/*----------------------------------------------------------------------*/
@@ -3193,6 +3870,38 @@ static virNetworkDriver network_driver =
.networkSetAutostart = remoteNetworkSetAutostart,
};
+static virStorageDriver storage_driver = {
+ .name = "remote",
+ .open = remoteStorageOpen,
+ .close = remoteStorageClose,
+ .numOfPools = remoteNumOfStoragePools,
+ .listPools = remoteListStoragePools,
+ .numOfDefinedPools = remoteNumOfDefinedStoragePools,
+ .listDefinedPools = remoteListDefinedStoragePools,
+ .poolLookupByUUID = remoteStoragePoolLookupByUUID,
+ .poolLookupByName = remoteStoragePoolLookupByName,
+ .poolCreateXML = remoteStoragePoolCreateXML,
+ .poolDefineXML = remoteStoragePoolDefineXML,
+ .poolUndefine = remoteStoragePoolUndefine,
+ .poolCreate = remoteStoragePoolCreate,
+ .poolShutdown = remoteStoragePoolShutdown,
+ .poolDestroy = remoteStoragePoolDestroy,
+ .poolGetInfo = remoteStoragePoolGetInfo,
+ .poolGetXMLDesc = remoteStoragePoolDumpXML,
+ .poolGetAutostart = remoteStoragePoolGetAutostart,
+ .poolSetAutostart = remoteStoragePoolSetAutostart,
+
+ .poolNumOfVolumes = remoteStoragePoolNumOfVolumes,
+ .poolListVolumes = remoteStoragePoolListVolumes,
+ .volLookupByUUID = remoteStorageVolLookupByUUID,
+ .volLookupByName = remoteStorageVolLookupByName,
+ .volCreateXML = remoteStorageVolCreateXML,
+ .volDestroy = remoteStorageVolDestroy,
+ .volGetInfo = remoteStorageVolGetInfo,
+ .volGetXMLDesc = remoteStorageVolDumpXML,
+ .volGetPath = remoteStorageVolGetPath,
+};
+
static virStateDriver state_driver = {
remoteStartup,
NULL,
@@ -3212,6 +3921,7 @@ remoteRegister (void)
{
if (virRegisterDriver (&driver) == -1) return -1;
if (virRegisterNetworkDriver (&network_driver) == -1) return -1;
+ if (virRegisterStorageDriver (&storage_driver) == -1) return -1;
if (virRegisterStateDriver (&state_driver) == -1) return -1;
return 0;
--
|=- 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 -=|