[Libvir] PATCH: 5/16: remote driver client

Daniel P. Berrange berrange at redhat.com
Wed Feb 20 04:02:01 UTC 2008


On Tue, Feb 12, 2008 at 04:33:03AM +0000, Daniel P. Berrange wrote:
> This patch adds support for the storage APIs to the remote driver
> client end. As with the network driver, things are configured such
> that all virtualization drivers will end up delegating to the remote
> driver for storage APIs. There's not much interesting to say about
> this patch since it just follows pattern for the existing APis.

 remote_internal.c |  820 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 809 insertions(+), 11 deletions(-)


diff -r d2291e4435c7 src/remote_internal.c
--- a/src/remote_internal.c	Tue Feb 19 12:45:55 2008 -0500
+++ b/src/remote_internal.c	Tue Feb 19 12:47:55 2008 -0500
@@ -89,7 +89,7 @@ struct private_data {
     gnutls_session_t session;   /* GnuTLS session (if uses_tls != 0). */
     char *type;                 /* Cached return from remoteType. */
     int counter;                /* Generates serial numbers for RPC. */
-    int networkOnly;            /* Only used for network API */
+    int localUses;              /* Ref count for private data */
     char *hostname;             /* Original hostname */
     FILE *debugLog;             /* Debug remote protocol */
 #if HAVE_SASL
@@ -115,6 +115,15 @@ struct private_data {
                _("tried to use a closed or uninitialised handle"));     \
         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);                                               \
+    }
+
 
 enum {
     REMOTE_CALL_IN_OPEN = 1,
@@ -140,8 +149,12 @@ static void server_error (virConnectPtr 
 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);
 
 /*----------------------------------------------------------------------*/
 
@@ -797,7 +810,7 @@ remoteOpen (virConnectPtr conn,
     if (inside_daemon)
         return VIR_DRV_OPEN_DECLINED;
 
-    priv = malloc (sizeof(*priv));
+    priv = calloc (1, sizeof(*priv));
     if (!priv) {
         error (conn, VIR_ERR_NO_MEMORY, _("struct private_data"));
         return VIR_DRV_OPEN_ERROR;
@@ -823,7 +836,6 @@ remoteOpen (virConnectPtr conn,
     }
 #endif
 
-    memset(priv, 0, sizeof(struct private_data));
     priv->magic = DEAD;
     priv->sock = -1;
     ret = doRemoteOpen(conn, priv, uri, auth, rflags);
@@ -2292,7 +2304,7 @@ remoteNetworkOpen (virConnectPtr conn,
 
     if (conn &&
         conn->driver &&
-        strcmp (conn->driver->name, "remote") == 0) {
+        STREQ (conn->driver->name, "remote")) {
         /* 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
@@ -2305,7 +2317,7 @@ remoteNetworkOpen (virConnectPtr conn,
          * 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(*priv));
+        struct private_data *priv = calloc (1, sizeof(*priv));
         int ret, rflags = 0;
         if (!priv) {
             error (conn, VIR_ERR_NO_MEMORY, _("struct private_data"));
@@ -2315,7 +2327,6 @@ remoteNetworkOpen (virConnectPtr conn,
             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, auth, rflags);
@@ -2324,7 +2335,7 @@ remoteNetworkOpen (virConnectPtr conn,
             free(priv);
         } else {
             priv->magic = MAGIC;
-            priv->networkOnly = 1;
+            priv->localUses = 1;
             conn->networkPrivateData = priv;
         }
         return ret;
@@ -2336,10 +2347,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;
 }
@@ -2666,6 +2680,726 @@ remoteNetworkSetAutostart (virNetworkPtr
 
     return 0;
 }
+
+
+
+
+/*----------------------------------------------------------------------*/
+
+static int
+remoteStorageOpen (virConnectPtr conn,
+                   xmlURIPtr uri,
+                   virConnectAuthPtr auth,
+                   int flags)
+{
+    if (inside_daemon)
+        return VIR_DRV_OPEN_DECLINED;
+
+    if (conn &&
+        conn->driver &&
+        STREQ (conn->driver->name, "remote")) {
+        /* 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 &&
+               STREQ (conn->networkDriver->name, "remote")) {
+        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 = calloc (1, 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_CONNECT_RO)
+            rflags |= VIR_DRV_OPEN_REMOTE_RO;
+        rflags |= VIR_DRV_OPEN_REMOTE_UNIX;
+
+        priv->magic = DEAD;
+        priv->sock = -1;
+        ret = doRemoteOpen(conn, priv, uri, auth, 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, _("too many storage pools requested"));
+        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, _("too many storage pools received"));
+        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, _("too many storage pools requested"));
+        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, _("too many storage pools received"));
+        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
+remoteStoragePoolLookupByVolume (virStorageVolPtr vol)
+{
+    virStoragePoolPtr pool;
+    remote_storage_pool_lookup_by_volume_args args;
+    remote_storage_pool_lookup_by_volume_ret ret;
+    GET_STORAGE_PRIVATE (vol->conn, NULL);
+
+    make_nonnull_storage_vol (&args.vol, vol);
+
+    memset (&ret, 0, sizeof ret);
+    if (call (vol->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_VOLUME,
+              (xdrproc_t) xdr_remote_storage_pool_lookup_by_volume_args, (char *) &args,
+              (xdrproc_t) xdr_remote_storage_pool_lookup_by_volume_ret, (char *) &ret) == -1)
+        return NULL;
+
+    pool = get_nonnull_storage_pool (vol->conn, ret.pool);
+    xdr_free ((xdrproc_t) &xdr_remote_storage_pool_lookup_by_volume_ret, (char *) &ret);
+
+    return pool;
+}
+
+
+static virStoragePoolPtr
+remoteStoragePoolCreateXML (virConnectPtr conn, const char *xmlDesc, unsigned int flags)
+{
+    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;
+    args.flags = flags;
+
+    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, unsigned int flags)
+{
+    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;
+    args.flags = flags;
+
+    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, unsigned int flags)
+{
+    remote_storage_pool_create_args args;
+    GET_STORAGE_PRIVATE (pool->conn, -1);
+
+    make_nonnull_storage_pool (&args.pool, pool);
+    args.flags = flags;
+
+    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
+remoteStoragePoolBuild (virStoragePoolPtr pool,
+                        unsigned int flags)
+{
+    remote_storage_pool_build_args args;
+    GET_STORAGE_PRIVATE (pool->conn, -1);
+
+    make_nonnull_storage_pool (&args.pool, pool);
+    args.flags = flags;
+
+    if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_BUILD,
+              (xdrproc_t) xdr_remote_storage_pool_build_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
+remoteStoragePoolDelete (virStoragePoolPtr pool,
+                         unsigned int flags)
+{
+    remote_storage_pool_delete_args args;
+    GET_STORAGE_PRIVATE (pool->conn, -1);
+
+    make_nonnull_storage_pool (&args.pool, pool);
+    args.flags = flags;
+
+    if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_DELETE,
+              (xdrproc_t) xdr_remote_storage_pool_delete_args, (char *) &args,
+              (xdrproc_t) xdr_void, (char *) NULL) == -1)
+        return -1;
+
+    return 0;
+}
+
+static int
+remoteStoragePoolRefresh (virStoragePoolPtr pool,
+                          unsigned int flags)
+{
+    remote_storage_pool_refresh_args args;
+    GET_STORAGE_PRIVATE (pool->conn, -1);
+
+    make_nonnull_storage_pool (&args.pool, pool);
+    args.flags = flags;
+
+    if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_REFRESH,
+              (xdrproc_t) xdr_remote_storage_pool_refresh_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;
+    info->available = ret.available;
+
+    return 0;
+}
+
+static char *
+remoteStoragePoolDumpXML (virStoragePoolPtr pool,
+                          unsigned 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, _("too many storage volumes requested"));
+        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, _("too many storage volumes received"));
+        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
+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
+remoteStorageVolLookupByKey (virConnectPtr conn,
+                             const char *key)
+{
+    virStorageVolPtr vol;
+    remote_storage_vol_lookup_by_key_args args;
+    remote_storage_vol_lookup_by_key_ret ret;
+    GET_STORAGE_PRIVATE (conn, NULL);
+
+    args.key = (char *) key;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, 0, REMOTE_PROC_STORAGE_VOL_LOOKUP_BY_KEY,
+              (xdrproc_t) xdr_remote_storage_vol_lookup_by_key_args, (char *) &args,
+              (xdrproc_t) xdr_remote_storage_vol_lookup_by_key_ret, (char *) &ret) == -1)
+        return NULL;
+
+    vol = get_nonnull_storage_vol (conn, ret.vol);
+    xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_key_ret, (char *) &ret);
+
+    return vol;
+}
+
+static virStorageVolPtr
+remoteStorageVolLookupByPath (virConnectPtr conn,
+                              const char *path)
+{
+    virStorageVolPtr vol;
+    remote_storage_vol_lookup_by_path_args args;
+    remote_storage_vol_lookup_by_path_ret ret;
+    GET_STORAGE_PRIVATE (conn, NULL);
+
+    args.path = (char *) path;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, 0, REMOTE_PROC_STORAGE_VOL_LOOKUP_BY_PATH,
+              (xdrproc_t) xdr_remote_storage_vol_lookup_by_path_args, (char *) &args,
+              (xdrproc_t) xdr_remote_storage_vol_lookup_by_path_ret, (char *) &ret) == -1)
+        return NULL;
+
+    vol = get_nonnull_storage_vol (conn, ret.vol);
+    xdr_free ((xdrproc_t) &xdr_remote_storage_vol_lookup_by_path_ret, (char *) &ret);
+
+    return vol;
+}
+
+static virStorageVolPtr
+remoteStorageVolCreateXML (virStoragePoolPtr pool, const char *xmlDesc,
+                           unsigned 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
+remoteStorageVolDelete (virStorageVolPtr vol,
+                        unsigned int flags)
+{
+    remote_storage_vol_delete_args args;
+    GET_STORAGE_PRIVATE (vol->conn, -1);
+
+    make_nonnull_storage_vol (&args.vol, vol);
+    args.flags = flags;
+
+    if (call (vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_DELETE,
+              (xdrproc_t) xdr_remote_storage_vol_delete_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->conn, -1);
+
+    make_nonnull_storage_vol (&args.vol, vol);
+
+    memset (&ret, 0, sizeof ret);
+    if (call (vol->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,
+                         unsigned int flags)
+{
+    remote_storage_vol_dump_xml_args args;
+    remote_storage_vol_dump_xml_ret ret;
+    GET_STORAGE_PRIVATE (vol->conn, NULL);
+
+    make_nonnull_storage_vol (&args.vol, vol);
+    args.flags = flags;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (vol->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->conn, NULL);
+
+    make_nonnull_storage_vol (&args.vol, vol);
+
+    memset (&ret, 0, sizeof ret);
+    if (call (vol->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;
+}
+
 
 /*----------------------------------------------------------------------*/
 
@@ -3816,6 +4550,18 @@ 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)
+{
+    return virGetStorageVol (conn, vol.pool, vol.name, vol.key);
+}
+
 /* Make remote_nonnull_domain and remote_nonnull_network. */
 static void
 make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src)
@@ -3830,6 +4576,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)
+{
+    vol_dst->pool = vol_src->pool;
+    vol_dst->name = vol_src->name;
+    vol_dst->key = vol_src->key;
 }
 
 /*----------------------------------------------------------------------*/
@@ -3912,6 +4673,42 @@ 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,
+    .poolLookupByVolume = remoteStoragePoolLookupByVolume,
+    .poolCreateXML = remoteStoragePoolCreateXML,
+    .poolDefineXML = remoteStoragePoolDefineXML,
+    .poolUndefine = remoteStoragePoolUndefine,
+    .poolCreate = remoteStoragePoolCreate,
+    .poolBuild = remoteStoragePoolBuild,
+    .poolDestroy = remoteStoragePoolDestroy,
+    .poolDelete = remoteStoragePoolDelete,
+    .poolRefresh = remoteStoragePoolRefresh,
+    .poolGetInfo = remoteStoragePoolGetInfo,
+    .poolGetXMLDesc = remoteStoragePoolDumpXML,
+    .poolGetAutostart = remoteStoragePoolGetAutostart,
+    .poolSetAutostart = remoteStoragePoolSetAutostart,
+    .poolNumOfVolumes = remoteStoragePoolNumOfVolumes,
+    .poolListVolumes = remoteStoragePoolListVolumes,
+
+    .volLookupByName = remoteStorageVolLookupByName,
+    .volLookupByKey = remoteStorageVolLookupByKey,
+    .volLookupByPath = remoteStorageVolLookupByPath,
+    .volCreateXML = remoteStorageVolCreateXML,
+    .volDelete = remoteStorageVolDelete,
+    .volGetInfo = remoteStorageVolGetInfo,
+    .volGetXMLDesc = remoteStorageVolDumpXML,
+    .volGetPath = remoteStorageVolGetPath,
+};
+
 static virStateDriver state_driver = {
     remoteStartup,
     NULL,
@@ -3931,6 +4728,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  -=| 




More information about the libvir-list mailing list