[libvirt] PATCH: 4/7: Remove driver API calls

Daniel P. Berrange berrange at redhat.com
Thu Nov 20 17:56:34 UTC 2008


This provides the remote driver implementation for node device APIs

This is basically just fixing up to add the optional 'cap' arg
to the List methods, and remove the Create/Destroy/ByCap methods

Daniel

diff -r acc38454f32d qemud/remote.c
--- a/qemud/remote.c	Thu Nov 20 16:16:37 2008 +0000
+++ b/qemud/remote.c	Thu Nov 20 16:26:13 2008 +0000
@@ -67,6 +67,7 @@
 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 pool_src);
 static void make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src);
+static void make_nonnull_node_device (remote_nonnull_node_device *dev_dst, virNodeDevicePtr dev_src);
 
 #include "remote_dispatch_prototypes.h"
 
@@ -3723,6 +3724,213 @@
 }
 
 
+/***************************************************************
+ *     NODE INFO APIS
+ **************************************************************/
+
+static int
+remoteDispatchNodeNumOfDevices (struct qemud_server *server ATTRIBUTE_UNUSED,
+                                struct qemud_client *client,
+                                remote_message_header *req,
+                                remote_node_num_of_devices_args *args,
+                                remote_node_num_of_devices_ret *ret)
+{
+    CHECK_CONN(client);
+
+    ret->num = virNodeNumOfDevices (client->conn,
+                                    args->cap ? *args->cap : NULL,
+                                    args->flags);
+    if (ret->num == -1) return -1;
+
+    return 0;
+}
+
+
+static int
+remoteDispatchNodeListDevices (struct qemud_server *server ATTRIBUTE_UNUSED,
+                               struct qemud_client *client,
+                               remote_message_header *req,
+                               remote_node_list_devices_args *args,
+                               remote_node_list_devices_ret *ret)
+{
+    CHECK_CONN(client);
+
+    if (args->maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
+        remoteDispatchError (client, req,
+                             "%s", _("maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX"));
+        return -2;
+    }
+
+    /* Allocate return buffer. */
+    if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
+        remoteDispatchSendError(client, req, VIR_ERR_NO_MEMORY, NULL);
+        return -2;
+    }
+
+    ret->names.names_len =
+        virNodeListDevices (client->conn,
+                            args->cap ? *args->cap : NULL,
+                            ret->names.names_val, args->maxnames, args->flags);
+    if (ret->names.names_len == -1) {
+        VIR_FREE(ret->names.names_val);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+static int
+remoteDispatchNodeDeviceLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
+                                      struct qemud_client *client,
+                                      remote_message_header *req,
+                                      remote_node_device_lookup_by_name_args *args,
+                                      remote_node_device_lookup_by_name_ret *ret)
+{
+    virNodeDevicePtr dev;
+
+    CHECK_CONN(client);
+
+    dev = virNodeDeviceLookupByName (client->conn, args->name);
+    if (dev == NULL) return -1;
+
+    make_nonnull_node_device (&ret->dev, dev);
+    virNodeDeviceFree(dev);
+    return 0;
+}
+
+
+static int
+remoteDispatchNodeDeviceDumpXml (struct qemud_server *server ATTRIBUTE_UNUSED,
+                                 struct qemud_client *client,
+                                 remote_message_header *req,
+                                 remote_node_device_dump_xml_args *args,
+                                 remote_node_device_dump_xml_ret *ret)
+{
+    virNodeDevicePtr dev;
+    CHECK_CONN(client);
+
+    dev = virNodeDeviceLookupByName(client->conn, args->name);
+    if (dev == NULL) {
+        remoteDispatchError (client, req, "%s", _("node_device not found"));
+        return -2;
+    }
+
+    /* remoteDispatchClientRequest will free this. */
+    ret->xml = virNodeDeviceGetXMLDesc (dev, args->flags);
+    if (!ret->xml) {
+        virNodeDeviceFree(dev);
+        return -1;
+    }
+    virNodeDeviceFree(dev);
+    return 0;
+}
+
+
+static int
+remoteDispatchNodeDeviceGetParent (struct qemud_server *server ATTRIBUTE_UNUSED,
+                                   struct qemud_client *client,
+                                   remote_message_header *req,
+                                   remote_node_device_get_parent_args *args,
+                                   remote_node_device_get_parent_ret *ret)
+{
+    virNodeDevicePtr dev;
+    const char *parent;
+    CHECK_CONN(client);
+
+    dev = virNodeDeviceLookupByName(client->conn, args->name);
+    if (dev == NULL) {
+        remoteDispatchError (client, req, "%s", _("node_device not found"));
+        return -2;
+    }
+
+    parent = virNodeDeviceGetParent(dev);
+
+    if (parent == NULL) {
+        ret->parent = NULL;
+    } else {
+        /* remoteDispatchClientRequest will free this. */
+        char **parent_p;
+        if (VIR_ALLOC(parent_p) < 0) {
+            remoteDispatchSendError(client, req, VIR_ERR_NO_MEMORY, NULL);
+            return -2;
+        }
+        *parent_p = strdup(parent);
+        if (*parent_p == NULL) {
+            remoteDispatchSendError(client, req, VIR_ERR_NO_MEMORY, NULL);
+            return -2;
+        }
+        ret->parent = parent_p;
+    }
+
+    virNodeDeviceFree(dev);
+    return 0;
+}
+
+
+static int
+remoteDispatchNodeDeviceNumOfCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
+                                   struct qemud_client *client,
+                                   remote_message_header *req,
+                                   remote_node_device_num_of_caps_args *args,
+                                   remote_node_device_num_of_caps_ret *ret)
+{
+    virNodeDevicePtr dev;
+    CHECK_CONN(client);
+
+    dev = virNodeDeviceLookupByName(client->conn, args->name);
+    if (dev == NULL) {
+        remoteDispatchError (client, req, "%s", _("node_device not found"));
+        return -2;
+    }
+
+    ret->num = virNodeDeviceNumOfCaps(dev);
+
+    virNodeDeviceFree(dev);
+    return 0;
+}
+
+
+static int
+remoteDispatchNodeDeviceListCaps (struct qemud_server *server ATTRIBUTE_UNUSED,
+                                  struct qemud_client *client,
+                                  remote_message_header *req,
+                                  remote_node_device_list_caps_args *args,
+                                  remote_node_device_list_caps_ret *ret)
+{
+    virNodeDevicePtr dev;
+    CHECK_CONN(client);
+
+    dev = virNodeDeviceLookupByName(client->conn, args->name);
+    if (dev == NULL) {
+        remoteDispatchError (client, req, "%s", _("node_device not found"));
+        return -2;
+    }
+
+    if (args->maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
+        remoteDispatchError (client, req,
+                             "%s", _("maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX"));
+        return -2;
+    }
+
+    /* Allocate return buffer. */
+    if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
+        remoteDispatchSendError(client, req, VIR_ERR_NO_MEMORY, NULL);
+        return -2;
+    }
+
+    ret->names.names_len =
+        virNodeDeviceListCaps (dev, ret->names.names_val,
+                               args->maxnames);
+    if (ret->names.names_len == -1) {
+        VIR_FREE(ret->names.names_val);
+        return -1;
+    }
+
+    return 0;
+}
+
+
 /**************************
  * Async Events
  **************************/
@@ -3848,6 +4056,7 @@
     client->bufferLength = len;
     client->bufferOffset = 0;
 }
+
 /*----- Helpers. -----*/
 
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
@@ -3918,3 +4127,9 @@
     vol_dst->name = strdup (vol_src->name);
     vol_dst->key = strdup (vol_src->key);
 }
+
+static void
+make_nonnull_node_device (remote_nonnull_node_device *dev_dst, virNodeDevicePtr dev_src)
+{
+    dev_dst->name = strdup(dev_src->name);
+}
diff -r acc38454f32d qemud/remote_dispatch_localvars.h
--- a/qemud/remote_dispatch_localvars.h	Thu Nov 20 16:16:37 2008 +0000
+++ b/qemud/remote_dispatch_localvars.h	Thu Nov 20 16:26:13 2008 +0000
@@ -7,6 +7,8 @@
 remote_storage_pool_list_volumes_args lv_remote_storage_pool_list_volumes_args;
 remote_storage_pool_list_volumes_ret lv_remote_storage_pool_list_volumes_ret;
 remote_domain_events_deregister_ret lv_remote_domain_events_deregister_ret;
+remote_node_device_get_parent_args lv_remote_node_device_get_parent_args;
+remote_node_device_get_parent_ret lv_remote_node_device_get_parent_ret;
 remote_domain_shutdown_args lv_remote_domain_shutdown_args;
 remote_list_defined_domains_args lv_remote_list_defined_domains_args;
 remote_list_defined_domains_ret lv_remote_list_defined_domains_ret;
@@ -34,6 +36,8 @@
 remote_list_defined_networks_ret lv_remote_list_defined_networks_ret;
 remote_network_create_xml_args lv_remote_network_create_xml_args;
 remote_network_create_xml_ret lv_remote_network_create_xml_ret;
+remote_node_device_list_caps_args lv_remote_node_device_list_caps_args;
+remote_node_device_list_caps_ret lv_remote_node_device_list_caps_ret;
 remote_open_args lv_remote_open_args;
 remote_storage_pool_refresh_args lv_remote_storage_pool_refresh_args;
 remote_storage_vol_lookup_by_path_args lv_remote_storage_vol_lookup_by_path_args;
@@ -67,6 +71,8 @@
 remote_storage_pool_lookup_by_volume_ret lv_remote_storage_pool_lookup_by_volume_ret;
 remote_domain_get_max_vcpus_args lv_remote_domain_get_max_vcpus_args;
 remote_domain_get_max_vcpus_ret lv_remote_domain_get_max_vcpus_ret;
+remote_node_device_num_of_caps_args lv_remote_node_device_num_of_caps_args;
+remote_node_device_num_of_caps_ret lv_remote_node_device_num_of_caps_ret;
 remote_domain_get_info_args lv_remote_domain_get_info_args;
 remote_domain_get_info_ret lv_remote_domain_get_info_ret;
 remote_storage_pool_num_of_volumes_args lv_remote_storage_pool_num_of_volumes_args;
@@ -82,6 +88,8 @@
 remote_domain_destroy_args lv_remote_domain_destroy_args;
 remote_find_storage_pool_sources_args lv_remote_find_storage_pool_sources_args;
 remote_find_storage_pool_sources_ret lv_remote_find_storage_pool_sources_ret;
+remote_node_num_of_devices_args lv_remote_node_num_of_devices_args;
+remote_node_num_of_devices_ret lv_remote_node_num_of_devices_ret;
 remote_auth_sasl_step_args lv_remote_auth_sasl_step_args;
 remote_auth_sasl_step_ret lv_remote_auth_sasl_step_ret;
 remote_domain_migrate_finish_args lv_remote_domain_migrate_finish_args;
@@ -91,11 +99,17 @@
 remote_domain_get_scheduler_parameters_args lv_remote_domain_get_scheduler_parameters_args;
 remote_domain_get_scheduler_parameters_ret lv_remote_domain_get_scheduler_parameters_ret;
 remote_node_get_info_ret lv_remote_node_get_info_ret;
+remote_node_device_dump_xml_args lv_remote_node_device_dump_xml_args;
+remote_node_device_dump_xml_ret lv_remote_node_device_dump_xml_ret;
+remote_node_device_lookup_by_name_args lv_remote_node_device_lookup_by_name_args;
+remote_node_device_lookup_by_name_ret lv_remote_node_device_lookup_by_name_ret;
 remote_network_lookup_by_name_args lv_remote_network_lookup_by_name_args;
 remote_network_lookup_by_name_ret lv_remote_network_lookup_by_name_ret;
 remote_domain_memory_peek_args lv_remote_domain_memory_peek_args;
 remote_domain_memory_peek_ret lv_remote_domain_memory_peek_ret;
 remote_num_of_defined_domains_ret lv_remote_num_of_defined_domains_ret;
+remote_node_list_devices_args lv_remote_node_list_devices_args;
+remote_node_list_devices_ret lv_remote_node_list_devices_ret;
 remote_domain_block_stats_args lv_remote_domain_block_stats_args;
 remote_domain_block_stats_ret lv_remote_domain_block_stats_ret;
 remote_domain_detach_device_args lv_remote_domain_detach_device_args;
diff -r acc38454f32d qemud/remote_dispatch_proc_switch.h
--- a/qemud/remote_dispatch_proc_switch.h	Thu Nov 20 16:16:37 2008 +0000
+++ b/qemud/remote_dispatch_proc_switch.h	Thu Nov 20 16:26:13 2008 +0000
@@ -560,6 +560,51 @@
         args = (char *) &lv_remote_network_undefine_args;
         memset (&lv_remote_network_undefine_args, 0, sizeof lv_remote_network_undefine_args);
         break;
+case REMOTE_PROC_NODE_DEVICE_DUMP_XML:
+        fn = (dispatch_fn) remoteDispatchNodeDeviceDumpXml;
+        args_filter = (xdrproc_t) xdr_remote_node_device_dump_xml_args;
+        args = (char *) &lv_remote_node_device_dump_xml_args;
+        memset (&lv_remote_node_device_dump_xml_args, 0, sizeof lv_remote_node_device_dump_xml_args);
+        ret_filter = (xdrproc_t) xdr_remote_node_device_dump_xml_ret;
+        ret = (char *) &lv_remote_node_device_dump_xml_ret;
+        memset (&lv_remote_node_device_dump_xml_ret, 0, sizeof lv_remote_node_device_dump_xml_ret);
+        break;
+case REMOTE_PROC_NODE_DEVICE_GET_PARENT:
+        fn = (dispatch_fn) remoteDispatchNodeDeviceGetParent;
+        args_filter = (xdrproc_t) xdr_remote_node_device_get_parent_args;
+        args = (char *) &lv_remote_node_device_get_parent_args;
+        memset (&lv_remote_node_device_get_parent_args, 0, sizeof lv_remote_node_device_get_parent_args);
+        ret_filter = (xdrproc_t) xdr_remote_node_device_get_parent_ret;
+        ret = (char *) &lv_remote_node_device_get_parent_ret;
+        memset (&lv_remote_node_device_get_parent_ret, 0, sizeof lv_remote_node_device_get_parent_ret);
+        break;
+case REMOTE_PROC_NODE_DEVICE_LIST_CAPS:
+        fn = (dispatch_fn) remoteDispatchNodeDeviceListCaps;
+        args_filter = (xdrproc_t) xdr_remote_node_device_list_caps_args;
+        args = (char *) &lv_remote_node_device_list_caps_args;
+        memset (&lv_remote_node_device_list_caps_args, 0, sizeof lv_remote_node_device_list_caps_args);
+        ret_filter = (xdrproc_t) xdr_remote_node_device_list_caps_ret;
+        ret = (char *) &lv_remote_node_device_list_caps_ret;
+        memset (&lv_remote_node_device_list_caps_ret, 0, sizeof lv_remote_node_device_list_caps_ret);
+        break;
+case REMOTE_PROC_NODE_DEVICE_LOOKUP_BY_NAME:
+        fn = (dispatch_fn) remoteDispatchNodeDeviceLookupByName;
+        args_filter = (xdrproc_t) xdr_remote_node_device_lookup_by_name_args;
+        args = (char *) &lv_remote_node_device_lookup_by_name_args;
+        memset (&lv_remote_node_device_lookup_by_name_args, 0, sizeof lv_remote_node_device_lookup_by_name_args);
+        ret_filter = (xdrproc_t) xdr_remote_node_device_lookup_by_name_ret;
+        ret = (char *) &lv_remote_node_device_lookup_by_name_ret;
+        memset (&lv_remote_node_device_lookup_by_name_ret, 0, sizeof lv_remote_node_device_lookup_by_name_ret);
+        break;
+case REMOTE_PROC_NODE_DEVICE_NUM_OF_CAPS:
+        fn = (dispatch_fn) remoteDispatchNodeDeviceNumOfCaps;
+        args_filter = (xdrproc_t) xdr_remote_node_device_num_of_caps_args;
+        args = (char *) &lv_remote_node_device_num_of_caps_args;
+        memset (&lv_remote_node_device_num_of_caps_args, 0, sizeof lv_remote_node_device_num_of_caps_args);
+        ret_filter = (xdrproc_t) xdr_remote_node_device_num_of_caps_ret;
+        ret = (char *) &lv_remote_node_device_num_of_caps_ret;
+        memset (&lv_remote_node_device_num_of_caps_ret, 0, sizeof lv_remote_node_device_num_of_caps_ret);
+        break;
 case REMOTE_PROC_NODE_GET_CELLS_FREE_MEMORY:
         fn = (dispatch_fn) remoteDispatchNodeGetCellsFreeMemory;
         args_filter = (xdrproc_t) xdr_remote_node_get_cells_free_memory_args;
@@ -580,6 +625,24 @@
         ret_filter = (xdrproc_t) xdr_remote_node_get_info_ret;
         ret = (char *) &lv_remote_node_get_info_ret;
         memset (&lv_remote_node_get_info_ret, 0, sizeof lv_remote_node_get_info_ret);
+        break;
+case REMOTE_PROC_NODE_LIST_DEVICES:
+        fn = (dispatch_fn) remoteDispatchNodeListDevices;
+        args_filter = (xdrproc_t) xdr_remote_node_list_devices_args;
+        args = (char *) &lv_remote_node_list_devices_args;
+        memset (&lv_remote_node_list_devices_args, 0, sizeof lv_remote_node_list_devices_args);
+        ret_filter = (xdrproc_t) xdr_remote_node_list_devices_ret;
+        ret = (char *) &lv_remote_node_list_devices_ret;
+        memset (&lv_remote_node_list_devices_ret, 0, sizeof lv_remote_node_list_devices_ret);
+        break;
+case REMOTE_PROC_NODE_NUM_OF_DEVICES:
+        fn = (dispatch_fn) remoteDispatchNodeNumOfDevices;
+        args_filter = (xdrproc_t) xdr_remote_node_num_of_devices_args;
+        args = (char *) &lv_remote_node_num_of_devices_args;
+        memset (&lv_remote_node_num_of_devices_args, 0, sizeof lv_remote_node_num_of_devices_args);
+        ret_filter = (xdrproc_t) xdr_remote_node_num_of_devices_ret;
+        ret = (char *) &lv_remote_node_num_of_devices_ret;
+        memset (&lv_remote_node_num_of_devices_ret, 0, sizeof lv_remote_node_num_of_devices_ret);
         break;
 case REMOTE_PROC_NUM_OF_DEFINED_DOMAINS:
         fn = (dispatch_fn) remoteDispatchNumOfDefinedDomains;
diff -r acc38454f32d qemud/remote_dispatch_prototypes.h
--- a/qemud/remote_dispatch_prototypes.h	Thu Nov 20 16:16:37 2008 +0000
+++ b/qemud/remote_dispatch_prototypes.h	Thu Nov 20 16:26:13 2008 +0000
@@ -76,9 +76,16 @@
 static int remoteDispatchNetworkLookupByUuid (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_network_lookup_by_uuid_args *args, remote_network_lookup_by_uuid_ret *ret);
 static int remoteDispatchNetworkSetAutostart (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_network_set_autostart_args *args, void *ret);
 static int remoteDispatchNetworkUndefine (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_network_undefine_args *args, void *ret);
+static int remoteDispatchNodeDeviceDumpXml (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_node_device_dump_xml_args *args, remote_node_device_dump_xml_ret *ret);
+static int remoteDispatchNodeDeviceGetParent (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_node_device_get_parent_args *args, remote_node_device_get_parent_ret *ret);
+static int remoteDispatchNodeDeviceListCaps (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_node_device_list_caps_args *args, remote_node_device_list_caps_ret *ret);
+static int remoteDispatchNodeDeviceLookupByName (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_node_device_lookup_by_name_args *args, remote_node_device_lookup_by_name_ret *ret);
+static int remoteDispatchNodeDeviceNumOfCaps (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_node_device_num_of_caps_args *args, remote_node_device_num_of_caps_ret *ret);
 static int remoteDispatchNodeGetCellsFreeMemory (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_node_get_cells_free_memory_args *args, remote_node_get_cells_free_memory_ret *ret);
 static int remoteDispatchNodeGetFreeMemory (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, remote_node_get_free_memory_ret *ret);
 static int remoteDispatchNodeGetInfo (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, remote_node_get_info_ret *ret);
+static int remoteDispatchNodeListDevices (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_node_list_devices_args *args, remote_node_list_devices_ret *ret);
+static int remoteDispatchNodeNumOfDevices (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_node_num_of_devices_args *args, remote_node_num_of_devices_ret *ret);
 static int remoteDispatchNumOfDefinedDomains (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, remote_num_of_defined_domains_ret *ret);
 static int remoteDispatchNumOfDefinedNetworks (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, remote_num_of_defined_networks_ret *ret);
 static int remoteDispatchNumOfDefinedStoragePools (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, remote_num_of_defined_storage_pools_ret *ret);
diff -r acc38454f32d qemud/remote_protocol.c
--- a/qemud/remote_protocol.c	Thu Nov 20 16:16:37 2008 +0000
+++ b/qemud/remote_protocol.c	Thu Nov 20 16:26:13 2008 +0000
@@ -84,6 +84,15 @@
 }
 
 bool_t
+xdr_remote_nonnull_node_device (XDR *xdrs, remote_nonnull_node_device *objp)
+{
+
+         if (!xdr_remote_nonnull_string (xdrs, &objp->name))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
 xdr_remote_domain (XDR *xdrs, remote_domain *objp)
 {
 
@@ -115,6 +124,15 @@
 {
 
          if (!xdr_pointer (xdrs, (char **)objp, sizeof (remote_nonnull_storage_vol), (xdrproc_t) xdr_remote_nonnull_storage_vol))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device (XDR *xdrs, remote_node_device *objp)
+{
+
+         if (!xdr_pointer (xdrs, (char **)objp, sizeof (remote_nonnull_node_device), (xdrproc_t) xdr_remote_nonnull_node_device))
                  return FALSE;
         return TRUE;
 }
@@ -2008,6 +2026,146 @@
 }
 
 bool_t
+xdr_remote_node_num_of_devices_args (XDR *xdrs, remote_node_num_of_devices_args *objp)
+{
+
+         if (!xdr_remote_string (xdrs, &objp->cap))
+                 return FALSE;
+         if (!xdr_u_int (xdrs, &objp->flags))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_num_of_devices_ret (XDR *xdrs, remote_node_num_of_devices_ret *objp)
+{
+
+         if (!xdr_int (xdrs, &objp->num))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_list_devices_args (XDR *xdrs, remote_node_list_devices_args *objp)
+{
+
+         if (!xdr_remote_string (xdrs, &objp->cap))
+                 return FALSE;
+         if (!xdr_int (xdrs, &objp->maxnames))
+                 return FALSE;
+         if (!xdr_u_int (xdrs, &objp->flags))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_list_devices_ret (XDR *xdrs, remote_node_list_devices_ret *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->names.names_val;
+
+         if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->names.names_len, REMOTE_NODE_DEVICE_NAME_LIST_MAX,
+                sizeof (remote_nonnull_string), (xdrproc_t) xdr_remote_nonnull_string))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_lookup_by_name_args (XDR *xdrs, remote_node_device_lookup_by_name_args *objp)
+{
+
+         if (!xdr_remote_nonnull_string (xdrs, &objp->name))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_lookup_by_name_ret (XDR *xdrs, remote_node_device_lookup_by_name_ret *objp)
+{
+
+         if (!xdr_remote_nonnull_node_device (xdrs, &objp->dev))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_dump_xml_args (XDR *xdrs, remote_node_device_dump_xml_args *objp)
+{
+
+         if (!xdr_remote_nonnull_string (xdrs, &objp->name))
+                 return FALSE;
+         if (!xdr_u_int (xdrs, &objp->flags))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_dump_xml_ret (XDR *xdrs, remote_node_device_dump_xml_ret *objp)
+{
+
+         if (!xdr_remote_nonnull_string (xdrs, &objp->xml))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_get_parent_args (XDR *xdrs, remote_node_device_get_parent_args *objp)
+{
+
+         if (!xdr_remote_nonnull_string (xdrs, &objp->name))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_get_parent_ret (XDR *xdrs, remote_node_device_get_parent_ret *objp)
+{
+
+         if (!xdr_remote_string (xdrs, &objp->parent))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_num_of_caps_args (XDR *xdrs, remote_node_device_num_of_caps_args *objp)
+{
+
+         if (!xdr_remote_nonnull_string (xdrs, &objp->name))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_num_of_caps_ret (XDR *xdrs, remote_node_device_num_of_caps_ret *objp)
+{
+
+         if (!xdr_int (xdrs, &objp->num))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_list_caps_args (XDR *xdrs, remote_node_device_list_caps_args *objp)
+{
+
+         if (!xdr_remote_nonnull_string (xdrs, &objp->name))
+                 return FALSE;
+         if (!xdr_int (xdrs, &objp->maxnames))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_list_caps_ret (XDR *xdrs, remote_node_device_list_caps_ret *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->names.names_val;
+
+         if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->names.names_len, REMOTE_NODE_DEVICE_CAPS_LIST_MAX,
+                sizeof (remote_nonnull_string), (xdrproc_t) xdr_remote_nonnull_string))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
 xdr_remote_domain_events_register_ret (XDR *xdrs, remote_domain_events_register_ret *objp)
 {
 
diff -r acc38454f32d qemud/remote_protocol.h
--- a/qemud/remote_protocol.h	Thu Nov 20 16:16:37 2008 +0000
+++ b/qemud/remote_protocol.h	Thu Nov 20 16:26:13 2008 +0000
@@ -31,6 +31,8 @@
 #define REMOTE_NETWORK_NAME_LIST_MAX 256
 #define REMOTE_STORAGE_POOL_NAME_LIST_MAX 256
 #define REMOTE_STORAGE_VOL_NAME_LIST_MAX 1024
+#define REMOTE_NODE_DEVICE_NAME_LIST_MAX 16384
+#define REMOTE_NODE_DEVICE_CAPS_LIST_MAX 16384
 #define REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX 16
 #define REMOTE_NODE_MAX_CELLS 1024
 #define REMOTE_AUTH_SASL_DATA_MAX 65536
@@ -66,6 +68,11 @@
 };
 typedef struct remote_nonnull_storage_vol remote_nonnull_storage_vol;
 
+struct remote_nonnull_node_device {
+        remote_nonnull_string name;
+};
+typedef struct remote_nonnull_node_device remote_nonnull_node_device;
+
 typedef remote_nonnull_domain *remote_domain;
 
 typedef remote_nonnull_network *remote_network;
@@ -73,6 +80,8 @@
 typedef remote_nonnull_storage_pool *remote_storage_pool;
 
 typedef remote_nonnull_storage_vol *remote_storage_vol;
+
+typedef remote_nonnull_node_device *remote_node_device;
 
 struct remote_error {
         int code;
@@ -1122,6 +1131,87 @@
 };
 typedef struct remote_storage_vol_get_path_ret remote_storage_vol_get_path_ret;
 
+struct remote_node_num_of_devices_args {
+        remote_string cap;
+        u_int flags;
+};
+typedef struct remote_node_num_of_devices_args remote_node_num_of_devices_args;
+
+struct remote_node_num_of_devices_ret {
+        int num;
+};
+typedef struct remote_node_num_of_devices_ret remote_node_num_of_devices_ret;
+
+struct remote_node_list_devices_args {
+        remote_string cap;
+        int maxnames;
+        u_int flags;
+};
+typedef struct remote_node_list_devices_args remote_node_list_devices_args;
+
+struct remote_node_list_devices_ret {
+        struct {
+                u_int names_len;
+                remote_nonnull_string *names_val;
+        } names;
+};
+typedef struct remote_node_list_devices_ret remote_node_list_devices_ret;
+
+struct remote_node_device_lookup_by_name_args {
+        remote_nonnull_string name;
+};
+typedef struct remote_node_device_lookup_by_name_args remote_node_device_lookup_by_name_args;
+
+struct remote_node_device_lookup_by_name_ret {
+        remote_nonnull_node_device dev;
+};
+typedef struct remote_node_device_lookup_by_name_ret remote_node_device_lookup_by_name_ret;
+
+struct remote_node_device_dump_xml_args {
+        remote_nonnull_string name;
+        u_int flags;
+};
+typedef struct remote_node_device_dump_xml_args remote_node_device_dump_xml_args;
+
+struct remote_node_device_dump_xml_ret {
+        remote_nonnull_string xml;
+};
+typedef struct remote_node_device_dump_xml_ret remote_node_device_dump_xml_ret;
+
+struct remote_node_device_get_parent_args {
+        remote_nonnull_string name;
+};
+typedef struct remote_node_device_get_parent_args remote_node_device_get_parent_args;
+
+struct remote_node_device_get_parent_ret {
+        remote_string parent;
+};
+typedef struct remote_node_device_get_parent_ret remote_node_device_get_parent_ret;
+
+struct remote_node_device_num_of_caps_args {
+        remote_nonnull_string name;
+};
+typedef struct remote_node_device_num_of_caps_args remote_node_device_num_of_caps_args;
+
+struct remote_node_device_num_of_caps_ret {
+        int num;
+};
+typedef struct remote_node_device_num_of_caps_ret remote_node_device_num_of_caps_ret;
+
+struct remote_node_device_list_caps_args {
+        remote_nonnull_string name;
+        int maxnames;
+};
+typedef struct remote_node_device_list_caps_args remote_node_device_list_caps_args;
+
+struct remote_node_device_list_caps_ret {
+        struct {
+                u_int names_len;
+                remote_nonnull_string *names_val;
+        } names;
+};
+typedef struct remote_node_device_list_caps_ret remote_node_device_list_caps_ret;
+
 struct remote_domain_events_register_ret {
         int cb_registered;
 };
@@ -1252,6 +1342,13 @@
         REMOTE_PROC_DOMAIN_MIGRATE_PREPARE2 = 108,
         REMOTE_PROC_DOMAIN_MIGRATE_FINISH2 = 109,
         REMOTE_PROC_GET_URI = 110,
+        REMOTE_PROC_NODE_NUM_OF_DEVICES = 111,
+        REMOTE_PROC_NODE_LIST_DEVICES = 112,
+        REMOTE_PROC_NODE_DEVICE_LOOKUP_BY_NAME = 113,
+        REMOTE_PROC_NODE_DEVICE_DUMP_XML = 114,
+        REMOTE_PROC_NODE_DEVICE_GET_PARENT = 115,
+        REMOTE_PROC_NODE_DEVICE_NUM_OF_CAPS = 116,
+        REMOTE_PROC_NODE_DEVICE_LIST_CAPS = 117,
 };
 typedef enum remote_procedure remote_procedure;
 
@@ -1289,10 +1386,12 @@
 extern  bool_t xdr_remote_nonnull_network (XDR *, remote_nonnull_network*);
 extern  bool_t xdr_remote_nonnull_storage_pool (XDR *, remote_nonnull_storage_pool*);
 extern  bool_t xdr_remote_nonnull_storage_vol (XDR *, remote_nonnull_storage_vol*);
+extern  bool_t xdr_remote_nonnull_node_device (XDR *, remote_nonnull_node_device*);
 extern  bool_t xdr_remote_domain (XDR *, remote_domain*);
 extern  bool_t xdr_remote_network (XDR *, remote_network*);
 extern  bool_t xdr_remote_storage_pool (XDR *, remote_storage_pool*);
 extern  bool_t xdr_remote_storage_vol (XDR *, remote_storage_vol*);
+extern  bool_t xdr_remote_node_device (XDR *, remote_node_device*);
 extern  bool_t xdr_remote_error (XDR *, remote_error*);
 extern  bool_t xdr_remote_auth_type (XDR *, remote_auth_type*);
 extern  bool_t xdr_remote_vcpu_info (XDR *, remote_vcpu_info*);
@@ -1462,6 +1561,20 @@
 extern  bool_t xdr_remote_storage_vol_get_info_ret (XDR *, remote_storage_vol_get_info_ret*);
 extern  bool_t xdr_remote_storage_vol_get_path_args (XDR *, remote_storage_vol_get_path_args*);
 extern  bool_t xdr_remote_storage_vol_get_path_ret (XDR *, remote_storage_vol_get_path_ret*);
+extern  bool_t xdr_remote_node_num_of_devices_args (XDR *, remote_node_num_of_devices_args*);
+extern  bool_t xdr_remote_node_num_of_devices_ret (XDR *, remote_node_num_of_devices_ret*);
+extern  bool_t xdr_remote_node_list_devices_args (XDR *, remote_node_list_devices_args*);
+extern  bool_t xdr_remote_node_list_devices_ret (XDR *, remote_node_list_devices_ret*);
+extern  bool_t xdr_remote_node_device_lookup_by_name_args (XDR *, remote_node_device_lookup_by_name_args*);
+extern  bool_t xdr_remote_node_device_lookup_by_name_ret (XDR *, remote_node_device_lookup_by_name_ret*);
+extern  bool_t xdr_remote_node_device_dump_xml_args (XDR *, remote_node_device_dump_xml_args*);
+extern  bool_t xdr_remote_node_device_dump_xml_ret (XDR *, remote_node_device_dump_xml_ret*);
+extern  bool_t xdr_remote_node_device_get_parent_args (XDR *, remote_node_device_get_parent_args*);
+extern  bool_t xdr_remote_node_device_get_parent_ret (XDR *, remote_node_device_get_parent_ret*);
+extern  bool_t xdr_remote_node_device_num_of_caps_args (XDR *, remote_node_device_num_of_caps_args*);
+extern  bool_t xdr_remote_node_device_num_of_caps_ret (XDR *, remote_node_device_num_of_caps_ret*);
+extern  bool_t xdr_remote_node_device_list_caps_args (XDR *, remote_node_device_list_caps_args*);
+extern  bool_t xdr_remote_node_device_list_caps_ret (XDR *, remote_node_device_list_caps_ret*);
 extern  bool_t xdr_remote_domain_events_register_ret (XDR *, remote_domain_events_register_ret*);
 extern  bool_t xdr_remote_domain_events_deregister_ret (XDR *, remote_domain_events_deregister_ret*);
 extern  bool_t xdr_remote_domain_event_ret (XDR *, remote_domain_event_ret*);
@@ -1478,10 +1591,12 @@
 extern bool_t xdr_remote_nonnull_network ();
 extern bool_t xdr_remote_nonnull_storage_pool ();
 extern bool_t xdr_remote_nonnull_storage_vol ();
+extern bool_t xdr_remote_nonnull_node_device ();
 extern bool_t xdr_remote_domain ();
 extern bool_t xdr_remote_network ();
 extern bool_t xdr_remote_storage_pool ();
 extern bool_t xdr_remote_storage_vol ();
+extern bool_t xdr_remote_node_device ();
 extern bool_t xdr_remote_error ();
 extern bool_t xdr_remote_auth_type ();
 extern bool_t xdr_remote_vcpu_info ();
@@ -1651,6 +1766,20 @@
 extern bool_t xdr_remote_storage_vol_get_info_ret ();
 extern bool_t xdr_remote_storage_vol_get_path_args ();
 extern bool_t xdr_remote_storage_vol_get_path_ret ();
+extern bool_t xdr_remote_node_num_of_devices_args ();
+extern bool_t xdr_remote_node_num_of_devices_ret ();
+extern bool_t xdr_remote_node_list_devices_args ();
+extern bool_t xdr_remote_node_list_devices_ret ();
+extern bool_t xdr_remote_node_device_lookup_by_name_args ();
+extern bool_t xdr_remote_node_device_lookup_by_name_ret ();
+extern bool_t xdr_remote_node_device_dump_xml_args ();
+extern bool_t xdr_remote_node_device_dump_xml_ret ();
+extern bool_t xdr_remote_node_device_get_parent_args ();
+extern bool_t xdr_remote_node_device_get_parent_ret ();
+extern bool_t xdr_remote_node_device_num_of_caps_args ();
+extern bool_t xdr_remote_node_device_num_of_caps_ret ();
+extern bool_t xdr_remote_node_device_list_caps_args ();
+extern bool_t xdr_remote_node_device_list_caps_ret ();
 extern bool_t xdr_remote_domain_events_register_ret ();
 extern bool_t xdr_remote_domain_events_deregister_ret ();
 extern bool_t xdr_remote_domain_event_ret ();
diff -r acc38454f32d qemud/remote_protocol.x
--- a/qemud/remote_protocol.x	Thu Nov 20 16:16:37 2008 +0000
+++ b/qemud/remote_protocol.x	Thu Nov 20 16:26:13 2008 +0000
@@ -86,6 +86,12 @@
 /* Upper limit on lists of storage vol names. */
 const REMOTE_STORAGE_VOL_NAME_LIST_MAX = 1024;
 
+/* Upper limit on lists of node device names. */
+const REMOTE_NODE_DEVICE_NAME_LIST_MAX = 16384;
+
+/* Upper limit on lists of node device capabilities. */
+const REMOTE_NODE_DEVICE_CAPS_LIST_MAX = 16384;
+
 /* Upper limit on list of scheduler parameters. */
 const REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX = 16;
 
@@ -139,11 +145,17 @@
     remote_nonnull_string key;
 };
 
+/* A node device which may not be NULL. */
+struct remote_nonnull_node_device {
+    remote_nonnull_string name;
+};
+
 /* A domain or network which may be NULL. */
 typedef remote_nonnull_domain *remote_domain;
 typedef remote_nonnull_network *remote_network;
 typedef remote_nonnull_storage_pool *remote_storage_pool;
 typedef remote_nonnull_storage_vol *remote_storage_vol;
+typedef remote_nonnull_node_device *remote_node_device;
 
 /* Error message. See <virterror.h> for explanation of fields. */
 
@@ -994,6 +1006,70 @@
     remote_nonnull_string name;
 };
 
+/* Node driver calls: */
+
+struct remote_node_num_of_devices_args {
+    remote_string cap;
+    unsigned flags;
+};
+
+struct remote_node_num_of_devices_ret {
+    int num;
+};
+
+struct remote_node_list_devices_args {
+    remote_string cap;
+    int maxnames;
+    unsigned flags;
+};
+
+struct remote_node_list_devices_ret {
+    remote_nonnull_string names<REMOTE_NODE_DEVICE_NAME_LIST_MAX>;
+};
+
+struct remote_node_device_lookup_by_name_args {
+    remote_nonnull_string name;
+};
+
+struct remote_node_device_lookup_by_name_ret {
+    remote_nonnull_node_device dev;
+};
+
+struct remote_node_device_dump_xml_args {
+    remote_nonnull_string name;
+    unsigned flags;
+};
+
+struct remote_node_device_dump_xml_ret {
+    remote_nonnull_string xml;
+};
+
+struct remote_node_device_get_parent_args {
+    remote_nonnull_string name;
+};
+
+struct remote_node_device_get_parent_ret {
+    remote_string parent;
+};
+
+struct remote_node_device_num_of_caps_args {
+    remote_nonnull_string name;
+};
+
+struct remote_node_device_num_of_caps_ret {
+    int num;
+};
+
+struct remote_node_device_list_caps_args {
+    remote_nonnull_string name;
+    int maxnames;
+};
+
+struct remote_node_device_list_caps_ret {
+    remote_nonnull_string names<REMOTE_NODE_DEVICE_CAPS_LIST_MAX>;
+};
+
+
 /**
  * Events Register/Deregister:
  * It would seem rpcgen does not like both args, and ret
@@ -1140,7 +1216,15 @@
     REMOTE_PROC_DOMAIN_EVENT = 107,
     REMOTE_PROC_DOMAIN_MIGRATE_PREPARE2 = 108,
     REMOTE_PROC_DOMAIN_MIGRATE_FINISH2 = 109,
-    REMOTE_PROC_GET_URI = 110
+    REMOTE_PROC_GET_URI = 110,
+
+    REMOTE_PROC_NODE_NUM_OF_DEVICES = 111,
+    REMOTE_PROC_NODE_LIST_DEVICES = 112,
+    REMOTE_PROC_NODE_DEVICE_LOOKUP_BY_NAME = 113,
+    REMOTE_PROC_NODE_DEVICE_DUMP_XML = 114,
+    REMOTE_PROC_NODE_DEVICE_GET_PARENT = 115,
+    REMOTE_PROC_NODE_DEVICE_NUM_OF_CAPS = 116,
+    REMOTE_PROC_NODE_DEVICE_LIST_CAPS = 117
 };
 
 /* Custom RPC structure. */
diff -r acc38454f32d src/remote_internal.c
--- a/src/remote_internal.c	Thu Nov 20 16:16:37 2008 +0000
+++ b/src/remote_internal.c	Thu Nov 20 16:26:13 2008 +0000
@@ -143,6 +143,14 @@
         return (retcode);                                               \
     }
 
+#define GET_DEVMON_PRIVATE(conn,retcode)                               \
+    struct private_data *priv = (struct private_data *) (conn)->devMonPrivateData; \
+    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,
@@ -172,6 +180,7 @@
 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 virNodeDevicePtr get_nonnull_node_device (virConnectPtr conn, remote_nonnull_node_device dev);
 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);
@@ -3764,6 +3773,229 @@
 
 /*----------------------------------------------------------------------*/
 
+static virDrvOpenStatus
+remoteDevMonOpen(virConnectPtr conn,
+                 virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+                 int flags ATTRIBUTE_UNUSED)
+{
+    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->devMonPrivateData = conn->privateData;
+        return VIR_DRV_OPEN_SUCCESS;
+    }
+
+    /* Decline open.  Will fallback to appropriate local node driver. */
+    return VIR_DRV_OPEN_DECLINED;
+}
+
+static int remoteDevMonClose(virConnectPtr conn)
+{
+    int ret = 0;
+    GET_DEVMON_PRIVATE (conn, -1);
+    if (priv->localUses) {
+        priv->localUses--;
+        if (!priv->localUses) {
+            ret = doRemoteClose(conn, priv);
+            VIR_FREE(priv);
+            conn->devMonPrivateData = NULL;
+        }
+    }
+    return ret;
+}
+
+static int remoteNodeNumOfDevices(virConnectPtr conn,
+                                  const char *cap,
+                                  unsigned int flags)
+{
+    remote_node_num_of_devices_args args;
+    remote_node_num_of_devices_ret ret;
+    GET_STORAGE_PRIVATE (conn, -1);
+
+    args.cap = cap ? (char **)&cap : NULL;
+    args.flags = flags;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, 0, REMOTE_PROC_NODE_NUM_OF_DEVICES,
+              (xdrproc_t) xdr_remote_node_num_of_devices_args, (char *) &args,
+              (xdrproc_t) xdr_remote_node_num_of_devices_ret, (char *) &ret) == -1)
+        return -1;
+
+    return ret.num;
+}
+
+
+static int remoteNodeListDevices(virConnectPtr conn,
+                                 const char *cap,
+                                 char **const names,
+                                 int maxnames,
+                                 unsigned int flags)
+{
+    int i;
+    remote_node_list_devices_args args;
+    remote_node_list_devices_ret ret;
+    GET_STORAGE_PRIVATE (conn, -1);
+
+    if (maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
+        error (conn, VIR_ERR_RPC, _("too many device names requested"));
+        return -1;
+    }
+    args.cap = cap ? (char **)&cap : NULL;
+    args.maxnames = maxnames;
+    args.flags = flags;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, 0, REMOTE_PROC_NODE_LIST_DEVICES,
+              (xdrproc_t) xdr_remote_node_list_devices_args, (char *) &args,
+              (xdrproc_t) xdr_remote_node_list_devices_ret, (char *) &ret) == -1)
+        return -1;
+
+    if (ret.names.names_len > maxnames) {
+        error (conn, VIR_ERR_RPC, _("too many device names received"));
+        xdr_free ((xdrproc_t) xdr_remote_node_list_devices_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_node_list_devices_ret, (char *) &ret);
+
+    return ret.names.names_len;
+}
+
+
+static virNodeDevicePtr remoteNodeDeviceLookupByName(virConnectPtr conn,
+                                                     const char *name)
+{
+    remote_node_device_lookup_by_name_args args;
+    remote_node_device_lookup_by_name_ret ret;
+    virNodeDevicePtr dev;
+    GET_STORAGE_PRIVATE (conn, NULL);
+
+    args.name = (char *)name;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, 0, REMOTE_PROC_NODE_DEVICE_LOOKUP_BY_NAME,
+              (xdrproc_t) xdr_remote_node_device_lookup_by_name_args, (char *) &args,
+              (xdrproc_t) xdr_remote_node_device_lookup_by_name_ret, (char *) &ret) == -1)
+        return NULL;
+
+    dev = get_nonnull_node_device(conn, ret.dev);
+
+    xdr_free ((xdrproc_t) xdr_remote_node_device_lookup_by_name_ret, (char *) &ret);
+
+    return dev;
+}
+
+static char *remoteNodeDeviceDumpXML(virNodeDevicePtr dev,
+                                     unsigned int flags)
+{
+    remote_node_device_dump_xml_args args;
+    remote_node_device_dump_xml_ret ret;
+    GET_STORAGE_PRIVATE (dev->conn, NULL);
+
+    args.name = dev->name;
+    args.flags = flags;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_DUMP_XML,
+              (xdrproc_t) xdr_remote_node_device_dump_xml_args, (char *) &args,
+              (xdrproc_t) xdr_remote_node_device_dump_xml_ret, (char *) &ret) == -1)
+        return NULL;
+
+    /* Caller frees. */
+    return ret.xml;
+}
+
+static char *remoteNodeDeviceGetParent(virNodeDevicePtr dev)
+{
+    remote_node_device_get_parent_args args;
+    remote_node_device_get_parent_ret ret;
+    GET_STORAGE_PRIVATE (dev->conn, NULL);
+
+    args.name = dev->name;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_GET_PARENT,
+              (xdrproc_t) xdr_remote_node_device_get_parent_args, (char *) &args,
+              (xdrproc_t) xdr_remote_node_device_get_parent_ret, (char *) &ret) == -1)
+        return NULL;
+
+    /* Caller frees. */
+    return ret.parent ? *ret.parent : NULL;
+}
+
+static int remoteNodeDeviceNumOfCaps(virNodeDevicePtr dev)
+{
+    remote_node_device_num_of_caps_args args;
+    remote_node_device_num_of_caps_ret ret;
+    GET_STORAGE_PRIVATE (dev->conn, -1);
+
+    args.name = dev->name;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_NUM_OF_CAPS,
+              (xdrproc_t) xdr_remote_node_device_num_of_caps_args, (char *) &args,
+              (xdrproc_t) xdr_remote_node_device_num_of_caps_ret, (char *) &ret) == -1)
+        return -1;
+
+    return ret.num;
+}
+
+static int remoteNodeDeviceListCaps(virNodeDevicePtr dev,
+                                    char **const names,
+                                    int maxnames)
+{
+    int i;
+    remote_node_device_list_caps_args args;
+    remote_node_device_list_caps_ret ret;
+    GET_STORAGE_PRIVATE (dev->conn, -1);
+
+    if (maxnames > REMOTE_NODE_DEVICE_CAPS_LIST_MAX) {
+        error (dev->conn, VIR_ERR_RPC, _("too many capability names requested"));
+        return -1;
+    }
+    args.maxnames = maxnames;
+    args.name = dev->name;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_LIST_CAPS,
+              (xdrproc_t) xdr_remote_node_device_list_caps_args, (char *) &args,
+              (xdrproc_t) xdr_remote_node_device_list_caps_ret, (char *) &ret) == -1)
+        return -1;
+
+    if (ret.names.names_len > maxnames) {
+        error (dev->conn, VIR_ERR_RPC, _("too many capability names received"));
+        xdr_free ((xdrproc_t) xdr_remote_node_device_list_caps_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_node_device_list_caps_ret, (char *) &ret);
+
+    return ret.names.names_len;
+}
+
+
+/*----------------------------------------------------------------------*/
+
 static int
 remoteAuthenticate (virConnectPtr conn, struct private_data *priv, int in_open,
                     virConnectAuthPtr auth
@@ -5018,6 +5250,12 @@
 get_nonnull_storage_vol (virConnectPtr conn, remote_nonnull_storage_vol vol)
 {
     return virGetStorageVol (conn, vol.pool, vol.name, vol.key);
+}
+
+static virNodeDevicePtr
+get_nonnull_node_device (virConnectPtr conn, remote_nonnull_node_device dev)
+{
+    return virGetNodeDevice(conn, dev.name);
 }
 
 /* Make remote_nonnull_domain and remote_nonnull_network. */
@@ -5175,6 +5413,20 @@
     .volGetPath = remoteStorageVolGetPath,
 };
 
+static virDeviceMonitor dev_monitor = {
+    .name = "remote",
+    .open = remoteDevMonOpen,
+    .close = remoteDevMonClose,
+    .numOfDevices = remoteNodeNumOfDevices,
+    .listDevices = remoteNodeListDevices,
+    .deviceLookupByName = remoteNodeDeviceLookupByName,
+    .deviceDumpXML = remoteNodeDeviceDumpXML,
+    .deviceGetParent = remoteNodeDeviceGetParent,
+    .deviceNumOfCaps = remoteNodeDeviceNumOfCaps,
+    .deviceListCaps = remoteNodeDeviceListCaps,
+};
+
+
 #ifdef WITH_LIBVIRTD
 static virStateDriver state_driver = {
     .initialize = remoteStartup,
@@ -5194,6 +5446,7 @@
     if (virRegisterDriver (&driver) == -1) return -1;
     if (virRegisterNetworkDriver (&network_driver) == -1) return -1;
     if (virRegisterStorageDriver (&storage_driver) == -1) return -1;
+    if (virRegisterDeviceMonitor (&dev_monitor) == -1) return -1;
 #ifdef WITH_LIBVIRTD
     if (virRegisterStateDriver (&state_driver) == -1) return -1;
 #endif

-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list