[libvirt] PATCH: 10/12: Node devices remote driver

Daniel P. Berrange berrange at redhat.com
Thu Nov 13 17:34:10 UTC 2008


This patch adds support for the node device APIs in the remote driver
and daemon. This is basically just a re-diff to take account of earlier
changes to the remote_protocol.x file

Daniel

diff -r 4b43fb269efe qemud/remote.c
--- a/qemud/remote.c	Wed Nov 12 21:12:02 2008 +0000
+++ b/qemud/remote.c	Wed Nov 12 21:57:50 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"
 
@@ -3658,6 +3659,303 @@
 }
 
 
+/***************************************************************
+ *     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->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,
+                            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
+remoteDispatchNodeNumOfDevicesByCap (struct qemud_server *server ATTRIBUTE_UNUSED,
+                                     struct qemud_client *client,
+                                     remote_message_header *req,
+                                     remote_node_num_of_devices_by_cap_args *args,
+                                     remote_node_num_of_devices_by_cap_ret *ret)
+{
+    CHECK_CONN(client);
+
+    ret->num = virNodeNumOfDevicesByCap (client->conn, args->cap, args->flags);
+    if (ret->num == -1) return -1;
+
+    return 0;
+}
+
+
+static int
+remoteDispatchNodeListDevicesByCap (struct qemud_server *server ATTRIBUTE_UNUSED,
+                                    struct qemud_client *client,
+                                    remote_message_header *req,
+                                    remote_node_list_devices_by_cap_args *args,
+                                    remote_node_list_devices_by_cap_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 =
+        virNodeListDevicesByCap (client->conn, args->cap,
+                                 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;
+}
+
+
+static int
+remoteDispatchNodeDeviceCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
+                                struct qemud_client *client,
+                                remote_message_header *req,
+                                remote_node_device_create_args *args,
+                                remote_node_device_create_ret *ret)
+{
+    virNodeDevicePtr dev;
+
+    CHECK_CONN(client);
+
+    dev = virNodeDeviceCreate (client->conn, args->xml, args->flags);
+    if (dev == NULL) return -1;
+
+    make_nonnull_node_device (&ret->dev, dev);
+    virNodeDeviceFree(dev);
+    return 0;
+}
+
+
+static int
+remoteDispatchNodeDeviceDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
+                                struct qemud_client *client,
+                                remote_message_header *req,
+                                remote_node_device_destroy_args *args,
+                                void *ret ATTRIBUTE_UNUSED)
+{
+    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 (virNodeDeviceDestroy (dev, args->flags) < 0) {
+        virNodeDeviceFree(dev);
+        return -1;
+    }
+    virNodeDeviceFree(dev);
+    return 0;
+}
 /**************************
  * Async Events
  **************************/
@@ -3781,6 +4079,7 @@
     client->bufferLength = len;
     client->bufferOffset = 0;
 }
+
 /*----- Helpers. -----*/
 
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
@@ -3851,3 +4150,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 4b43fb269efe qemud/remote_dispatch_localvars.h
--- a/qemud/remote_dispatch_localvars.h	Wed Nov 12 21:12:02 2008 +0000
+++ b/qemud/remote_dispatch_localvars.h	Wed Nov 12 21:57:50 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,7 +36,11 @@
 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_node_device_create_args lv_remote_node_device_create_args;
+remote_node_device_create_ret lv_remote_node_device_create_ret;
 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;
 remote_storage_vol_lookup_by_path_ret lv_remote_storage_vol_lookup_by_path_ret;
@@ -42,6 +48,8 @@
 remote_list_domains_ret lv_remote_list_domains_ret;
 remote_network_define_xml_args lv_remote_network_define_xml_args;
 remote_network_define_xml_ret lv_remote_network_define_xml_ret;
+remote_node_list_devices_by_cap_args lv_remote_node_list_devices_by_cap_args;
+remote_node_list_devices_by_cap_ret lv_remote_node_list_devices_by_cap_ret;
 remote_get_type_ret lv_remote_get_type_ret;
 remote_domain_block_peek_args lv_remote_domain_block_peek_args;
 remote_domain_block_peek_ret lv_remote_domain_block_peek_ret;
@@ -67,6 +75,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;
@@ -80,8 +90,12 @@
 remote_network_get_bridge_name_args lv_remote_network_get_bridge_name_args;
 remote_network_get_bridge_name_ret lv_remote_network_get_bridge_name_ret;
 remote_domain_destroy_args lv_remote_domain_destroy_args;
+remote_node_num_of_devices_by_cap_args lv_remote_node_num_of_devices_by_cap_args;
+remote_node_num_of_devices_by_cap_ret lv_remote_node_num_of_devices_by_cap_ret;
 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 +105,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;
@@ -162,6 +182,7 @@
 remote_storage_vol_dump_xml_ret lv_remote_storage_vol_dump_xml_ret;
 remote_domain_dump_xml_args lv_remote_domain_dump_xml_args;
 remote_domain_dump_xml_ret lv_remote_domain_dump_xml_ret;
+remote_node_device_destroy_args lv_remote_node_device_destroy_args;
 remote_get_max_vcpus_args lv_remote_get_max_vcpus_args;
 remote_get_max_vcpus_ret lv_remote_get_max_vcpus_ret;
 remote_domain_migrate_perform_args lv_remote_domain_migrate_perform_args;
diff -r 4b43fb269efe qemud/remote_dispatch_proc_switch.h
--- a/qemud/remote_dispatch_proc_switch.h	Wed Nov 12 21:12:02 2008 +0000
+++ b/qemud/remote_dispatch_proc_switch.h	Wed Nov 12 21:57:50 2008 +0000
@@ -542,6 +542,66 @@
         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_CREATE:
+        fn = (dispatch_fn) remoteDispatchNodeDeviceCreate;
+        args_filter = (xdrproc_t) xdr_remote_node_device_create_args;
+        args = (char *) &lv_remote_node_device_create_args;
+        memset (&lv_remote_node_device_create_args, 0, sizeof lv_remote_node_device_create_args);
+        ret_filter = (xdrproc_t) xdr_remote_node_device_create_ret;
+        ret = (char *) &lv_remote_node_device_create_ret;
+        memset (&lv_remote_node_device_create_ret, 0, sizeof lv_remote_node_device_create_ret);
+        break;
+case REMOTE_PROC_NODE_DEVICE_DESTROY:
+        fn = (dispatch_fn) remoteDispatchNodeDeviceDestroy;
+        args_filter = (xdrproc_t) xdr_remote_node_device_destroy_args;
+        args = (char *) &lv_remote_node_device_destroy_args;
+        memset (&lv_remote_node_device_destroy_args, 0, sizeof lv_remote_node_device_destroy_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;
@@ -562,6 +622,42 @@
         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_LIST_DEVICES_BY_CAP:
+        fn = (dispatch_fn) remoteDispatchNodeListDevicesByCap;
+        args_filter = (xdrproc_t) xdr_remote_node_list_devices_by_cap_args;
+        args = (char *) &lv_remote_node_list_devices_by_cap_args;
+        memset (&lv_remote_node_list_devices_by_cap_args, 0, sizeof lv_remote_node_list_devices_by_cap_args);
+        ret_filter = (xdrproc_t) xdr_remote_node_list_devices_by_cap_ret;
+        ret = (char *) &lv_remote_node_list_devices_by_cap_ret;
+        memset (&lv_remote_node_list_devices_by_cap_ret, 0, sizeof lv_remote_node_list_devices_by_cap_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_NODE_NUM_OF_DEVICES_BY_CAP:
+        fn = (dispatch_fn) remoteDispatchNodeNumOfDevicesByCap;
+        args_filter = (xdrproc_t) xdr_remote_node_num_of_devices_by_cap_args;
+        args = (char *) &lv_remote_node_num_of_devices_by_cap_args;
+        memset (&lv_remote_node_num_of_devices_by_cap_args, 0, sizeof lv_remote_node_num_of_devices_by_cap_args);
+        ret_filter = (xdrproc_t) xdr_remote_node_num_of_devices_by_cap_ret;
+        ret = (char *) &lv_remote_node_num_of_devices_by_cap_ret;
+        memset (&lv_remote_node_num_of_devices_by_cap_ret, 0, sizeof lv_remote_node_num_of_devices_by_cap_ret);
         break;
 case REMOTE_PROC_NUM_OF_DEFINED_DOMAINS:
         fn = (dispatch_fn) remoteDispatchNumOfDefinedDomains;
diff -r 4b43fb269efe qemud/remote_dispatch_prototypes.h
--- a/qemud/remote_dispatch_prototypes.h	Wed Nov 12 21:12:02 2008 +0000
+++ b/qemud/remote_dispatch_prototypes.h	Wed Nov 12 21:57:50 2008 +0000
@@ -74,9 +74,20 @@
 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 remoteDispatchNodeDeviceCreate (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_node_device_create_args *args, remote_node_device_create_ret *ret);
+static int remoteDispatchNodeDeviceDestroy (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_node_device_destroy_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 remoteDispatchNodeListDevicesByCap (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_node_list_devices_by_cap_args *args, remote_node_list_devices_by_cap_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 remoteDispatchNodeNumOfDevicesByCap (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_node_num_of_devices_by_cap_args *args, remote_node_num_of_devices_by_cap_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 4b43fb269efe qemud/remote_protocol.c
--- a/qemud/remote_protocol.c	Wed Nov 12 21:12:02 2008 +0000
+++ b/qemud/remote_protocol.c	Wed Nov 12 21:57:50 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;
 }
@@ -1952,6 +1970,217 @@
 }
 
 bool_t
+xdr_remote_node_num_of_devices_args (XDR *xdrs, remote_node_num_of_devices_args *objp)
+{
+
+         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_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_num_of_devices_by_cap_args (XDR *xdrs, remote_node_num_of_devices_by_cap_args *objp)
+{
+
+         if (!xdr_remote_nonnull_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_by_cap_ret (XDR *xdrs, remote_node_num_of_devices_by_cap_ret *objp)
+{
+
+         if (!xdr_int (xdrs, &objp->num))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_list_devices_by_cap_args (XDR *xdrs, remote_node_list_devices_by_cap_args *objp)
+{
+
+         if (!xdr_int (xdrs, &objp->maxnames))
+                 return FALSE;
+         if (!xdr_remote_nonnull_string (xdrs, &objp->cap))
+                 return FALSE;
+         if (!xdr_u_int (xdrs, &objp->flags))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_list_devices_by_cap_ret (XDR *xdrs, remote_node_list_devices_by_cap_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_node_device_create_args (XDR *xdrs, remote_node_device_create_args *objp)
+{
+
+         if (!xdr_remote_nonnull_string (xdrs, &objp->xml))
+                 return FALSE;
+         if (!xdr_u_int (xdrs, &objp->flags))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_create_ret (XDR *xdrs, remote_node_device_create_ret *objp)
+{
+
+         if (!xdr_remote_nonnull_node_device (xdrs, &objp->dev))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_destroy_args (XDR *xdrs, remote_node_device_destroy_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_domain_events_register_ret (XDR *xdrs, remote_domain_events_register_ret *objp)
 {
 
diff -r 4b43fb269efe qemud/remote_protocol.h
--- a/qemud/remote_protocol.h	Wed Nov 12 21:12:02 2008 +0000
+++ b/qemud/remote_protocol.h	Wed Nov 12 21:57:50 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;
@@ -1087,6 +1096,128 @@
 };
 typedef struct remote_storage_vol_get_path_ret remote_storage_vol_get_path_ret;
 
+struct remote_node_num_of_devices_args {
+        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 {
+        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_num_of_devices_by_cap_args {
+        remote_nonnull_string cap;
+        u_int flags;
+};
+typedef struct remote_node_num_of_devices_by_cap_args remote_node_num_of_devices_by_cap_args;
+
+struct remote_node_num_of_devices_by_cap_ret {
+        int num;
+};
+typedef struct remote_node_num_of_devices_by_cap_ret remote_node_num_of_devices_by_cap_ret;
+
+struct remote_node_list_devices_by_cap_args {
+        int maxnames;
+        remote_nonnull_string cap;
+        u_int flags;
+};
+typedef struct remote_node_list_devices_by_cap_args remote_node_list_devices_by_cap_args;
+
+struct remote_node_list_devices_by_cap_ret {
+        struct {
+                u_int names_len;
+                remote_nonnull_string *names_val;
+        } names;
+};
+typedef struct remote_node_list_devices_by_cap_ret remote_node_list_devices_by_cap_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_node_device_create_args {
+        remote_nonnull_string xml;
+        u_int flags;
+};
+typedef struct remote_node_device_create_args remote_node_device_create_args;
+
+struct remote_node_device_create_ret {
+        remote_nonnull_node_device dev;
+};
+typedef struct remote_node_device_create_ret remote_node_device_create_ret;
+
+struct remote_node_device_destroy_args {
+        remote_nonnull_string name;
+        u_int flags;
+};
+typedef struct remote_node_device_destroy_args remote_node_device_destroy_args;
+
 struct remote_domain_events_register_ret {
         int cb_registered;
 };
@@ -1214,6 +1345,17 @@
         REMOTE_PROC_DOMAIN_EVENTS_DEREGISTER = 106,
         REMOTE_PROC_DOMAIN_EVENT = 107,
         REMOTE_PROC_GET_URI = 108,
+        REMOTE_PROC_NODE_NUM_OF_DEVICES = 109,
+        REMOTE_PROC_NODE_LIST_DEVICES = 110,
+        REMOTE_PROC_NODE_NUM_OF_DEVICES_BY_CAP = 111,
+        REMOTE_PROC_NODE_LIST_DEVICES_BY_CAP = 112,
+        REMOTE_PROC_NODE_DEVICE_LOOKUP_BY_NAME = 113,
+        REMOTE_PROC_NODE_DEVICE_DUMP_XML = 114,
+        REMOTE_PROC_NODE_DEVICE_CREATE = 115,
+        REMOTE_PROC_NODE_DEVICE_DESTROY = 116,
+        REMOTE_PROC_NODE_DEVICE_GET_PARENT = 117,
+        REMOTE_PROC_NODE_DEVICE_NUM_OF_CAPS = 118,
+        REMOTE_PROC_NODE_DEVICE_LIST_CAPS = 119,
 };
 typedef enum remote_procedure remote_procedure;
 
@@ -1251,10 +1393,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*);
@@ -1420,6 +1564,27 @@
 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_num_of_devices_by_cap_args (XDR *, remote_node_num_of_devices_by_cap_args*);
+extern  bool_t xdr_remote_node_num_of_devices_by_cap_ret (XDR *, remote_node_num_of_devices_by_cap_ret*);
+extern  bool_t xdr_remote_node_list_devices_by_cap_args (XDR *, remote_node_list_devices_by_cap_args*);
+extern  bool_t xdr_remote_node_list_devices_by_cap_ret (XDR *, remote_node_list_devices_by_cap_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_node_device_create_args (XDR *, remote_node_device_create_args*);
+extern  bool_t xdr_remote_node_device_create_ret (XDR *, remote_node_device_create_ret*);
+extern  bool_t xdr_remote_node_device_destroy_args (XDR *, remote_node_device_destroy_args*);
 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*);
@@ -1436,10 +1601,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 ();
@@ -1605,6 +1772,27 @@
 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_num_of_devices_by_cap_args ();
+extern bool_t xdr_remote_node_num_of_devices_by_cap_ret ();
+extern bool_t xdr_remote_node_list_devices_by_cap_args ();
+extern bool_t xdr_remote_node_list_devices_by_cap_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_node_device_create_args ();
+extern bool_t xdr_remote_node_device_create_ret ();
+extern bool_t xdr_remote_node_device_destroy_args ();
 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 4b43fb269efe qemud/remote_protocol.x
--- a/qemud/remote_protocol.x	Wed Nov 12 21:12:02 2008 +0000
+++ b/qemud/remote_protocol.x	Wed Nov 12 21:57:50 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. */
 
@@ -969,6 +981,100 @@
     remote_nonnull_string name;
 };
 
+/* Node driver calls: */
+
+struct remote_node_num_of_devices_args {
+    unsigned flags;
+};
+
+struct remote_node_num_of_devices_ret {
+    int num;
+};
+
+struct remote_node_list_devices_args {
+    int maxnames;
+    unsigned flags;
+};
+
+struct remote_node_list_devices_ret {
+    remote_nonnull_string names<REMOTE_NODE_DEVICE_NAME_LIST_MAX>;
+};
+
+struct remote_node_num_of_devices_by_cap_args {
+    remote_nonnull_string cap;
+    unsigned flags;
+};
+
+struct remote_node_num_of_devices_by_cap_ret {
+    int num;
+};
+
+struct remote_node_list_devices_by_cap_args {
+    int maxnames;
+    remote_nonnull_string cap;
+    unsigned flags;
+};
+
+struct remote_node_list_devices_by_cap_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>;
+};
+
+struct remote_node_device_create_args {
+    remote_nonnull_string xml;
+    unsigned flags;
+};
+
+struct remote_node_device_create_ret {
+    remote_nonnull_node_device dev;
+};
+
+struct remote_node_device_destroy_args {
+    remote_nonnull_string name;
+    unsigned flags;
+};
+
 /**
  * Events Register/Deregister:
  * It would seem rpcgen does not like both args, and ret
@@ -1112,7 +1218,19 @@
     REMOTE_PROC_DOMAIN_EVENTS_REGISTER = 105,
     REMOTE_PROC_DOMAIN_EVENTS_DEREGISTER = 106,
     REMOTE_PROC_DOMAIN_EVENT = 107,
-    REMOTE_PROC_GET_URI = 108
+    REMOTE_PROC_GET_URI = 108,
+    REMOTE_PROC_NODE_NUM_OF_DEVICES = 109,
+    REMOTE_PROC_NODE_LIST_DEVICES = 110,
+
+    REMOTE_PROC_NODE_NUM_OF_DEVICES_BY_CAP = 111,
+    REMOTE_PROC_NODE_LIST_DEVICES_BY_CAP = 112,
+    REMOTE_PROC_NODE_DEVICE_LOOKUP_BY_NAME = 113,
+    REMOTE_PROC_NODE_DEVICE_DUMP_XML = 114,
+    REMOTE_PROC_NODE_DEVICE_CREATE = 115,
+    REMOTE_PROC_NODE_DEVICE_DESTROY = 116,
+    REMOTE_PROC_NODE_DEVICE_GET_PARENT = 117,
+    REMOTE_PROC_NODE_DEVICE_NUM_OF_CAPS = 118,
+    REMOTE_PROC_NODE_DEVICE_LIST_CAPS = 119
 };
 
 /* Custom RPC structure. */
diff -r 4b43fb269efe src/remote_internal.c
--- a/src/remote_internal.c	Wed Nov 12 21:12:02 2008 +0000
+++ b/src/remote_internal.c	Wed Nov 12 21:57:51 2008 +0000
@@ -142,6 +142,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,
@@ -171,6 +179,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);
@@ -3696,6 +3705,331 @@
 
 /*----------------------------------------------------------------------*/
 
+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,
+                                  unsigned int flags)
+{
+    remote_node_num_of_devices_args args;
+    remote_node_num_of_devices_ret ret;
+    GET_STORAGE_PRIVATE (conn, -1);
+
+    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,
+                                 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.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 int remoteNodeNumOfDevicesByCap(virConnectPtr conn,
+                                       const char *cap,
+                                       unsigned int flags)
+{
+    remote_node_num_of_devices_by_cap_args args;
+    remote_node_num_of_devices_by_cap_ret ret;
+    GET_STORAGE_PRIVATE (conn, -1);
+
+    args.cap = (char *)cap;
+    args.flags = flags;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, 0, REMOTE_PROC_NODE_NUM_OF_DEVICES_BY_CAP,
+              (xdrproc_t) xdr_remote_node_num_of_devices_by_cap_args, (char *) &args,
+              (xdrproc_t) xdr_remote_node_num_of_devices_by_cap_ret, (char *) &ret) == -1)
+        return -1;
+
+    return ret.num;
+}
+
+static int remoteNodeListDevicesByCap(virConnectPtr conn,
+                                      const char *cap,
+                                      char **const names,
+                                      int maxnames,
+                                      unsigned int flags)
+{
+    int i;
+    remote_node_list_devices_by_cap_args args;
+    remote_node_list_devices_by_cap_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.maxnames = maxnames;
+    args.cap = (char *)cap;
+    args.flags = flags;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, 0, REMOTE_PROC_NODE_LIST_DEVICES_BY_CAP,
+              (xdrproc_t) xdr_remote_node_list_devices_by_cap_args, (char *) &args,
+              (xdrproc_t) xdr_remote_node_list_devices_by_cap_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_by_cap_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 virNodeDevicePtr remoteNodeDeviceCreate(virConnectPtr conn,
+                                               const char *xml,
+                                               unsigned int flags)
+{
+    remote_node_device_create_args args;
+    remote_node_device_create_ret ret;
+    virNodeDevicePtr dev;
+    GET_STORAGE_PRIVATE (conn, NULL);
+
+    args.xml = (char *)xml;
+    args.flags = flags;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, 0, REMOTE_PROC_NODE_DEVICE_CREATE,
+              (xdrproc_t) xdr_remote_node_device_create_args, (char *) &args,
+              (xdrproc_t) xdr_remote_node_device_create_ret, (char *) &ret) == -1)
+        return NULL;
+
+    dev = get_nonnull_node_device(conn, ret.dev);
+
+    xdr_free ((xdrproc_t) xdr_remote_node_device_create_ret, (char *) &ret);
+
+    return dev;
+}
+
+static int remoteNodeDeviceDestroy(virNodeDevicePtr dev,
+                                   unsigned int flags)
+{
+    remote_node_device_destroy_args args;
+    GET_STORAGE_PRIVATE (dev->conn, -1);
+
+    args.name = dev->name;
+    args.flags = flags;
+
+    if (call (dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_DESTROY,
+              (xdrproc_t) xdr_remote_node_device_destroy_args, (char *) &args,
+              (xdrproc_t) xdr_void, (char *) NULL) == -1)
+        return -1;
+
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------*/
+
 static int
 remoteAuthenticate (virConnectPtr conn, struct private_data *priv, int in_open,
                     virConnectAuthPtr auth
@@ -4949,6 +5283,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. */
@@ -5104,6 +5444,24 @@
     .volGetPath = remoteStorageVolGetPath,
 };
 
+static virDeviceMonitor dev_monitor = {
+    .name = "remote",
+    .open = remoteDevMonOpen,
+    .close = remoteDevMonClose,
+    .numOfDevices = remoteNodeNumOfDevices,
+    .listDevices = remoteNodeListDevices,
+    .numOfDevicesByCap = remoteNodeNumOfDevicesByCap,
+    .listDevicesByCap = remoteNodeListDevicesByCap,
+    .deviceLookupByName = remoteNodeDeviceLookupByName,
+    .deviceDumpXML = remoteNodeDeviceDumpXML,
+    .deviceCreate = remoteNodeDeviceCreate,
+    .deviceDestroy = remoteNodeDeviceDestroy,
+    .deviceGetParent = remoteNodeDeviceGetParent,
+    .deviceNumOfCaps = remoteNodeDeviceNumOfCaps,
+    .deviceListCaps = remoteNodeDeviceListCaps,
+};
+
+
 #ifdef WITH_LIBVIRTD
 static virStateDriver state_driver = {
     .initialize = remoteStartup,
@@ -5123,6 +5481,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