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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 :|

--
Libvir-list mailing list
Libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]