From 8325fcf13d9939e3e320d93641259bf23e3fd743 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 21 Nov 2008 12:31:04 +0000 Subject: [PATCH] Remote protocol support for node devices (David Lively) --- ChangeLog | 11 ++ qemud/remote.c | 215 +++++++++++++++++++++++ qemud/remote_dispatch_localvars.h | 14 ++ qemud/remote_dispatch_proc_switch.h | 63 +++++++ qemud/remote_dispatch_prototypes.h | 7 + qemud/remote_protocol.c | 158 +++++++++++++++++ qemud/remote_protocol.h | 129 ++++++++++++++ qemud/remote_protocol.x | 86 +++++++++- src/remote_internal.c | 253 ++++++++++++++++++++++++++++ 9 files changed, 935 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index eef667a8e9..cb5f9588df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Fri Nov 21 12:30:14 BST 2008 Daniel P. Berrange + + Remote protocol support for node devices (David Lively) + * src/remote_internal.c: driver impl for node device APIs + * qemud/remote_protocol.x: Define wire protocol for node device + APIs + * qemud/remote_dispatch*, qemud/remote_protocol.{c,h}: Update + for new APIs + * qemud/remote.c: server dispatch functions for node device + APIs + Fri Nov 21 12:23:14 BST 2008 Daniel P. Berrange Primary internal driver for node devices with HAL (default) diff --git a/qemud/remote.c b/qemud/remote.c index 68030eadad..6b94ee3e10 100644 --- a/qemud/remote.c +++ b/qemud/remote.c @@ -67,6 +67,7 @@ static void make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr do 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 @@ remoteDispatchStorageVolLookupByPath (struct qemud_server *server ATTRIBUTE_UNUS } +/*************************************************************** + * 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 @@ remoteDispatchDomainEventSend (struct qemud_client *client, client->bufferLength = len; client->bufferOffset = 0; } + /*----- Helpers. -----*/ /* get_nonnull_domain and get_nonnull_network turn an on-wire @@ -3918,3 +4127,9 @@ make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr 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 --git a/qemud/remote_dispatch_localvars.h b/qemud/remote_dispatch_localvars.h index 84134dfc89..3d98a450af 100644 --- a/qemud/remote_dispatch_localvars.h +++ b/qemud/remote_dispatch_localvars.h @@ -7,6 +7,8 @@ remote_domain_lookup_by_uuid_ret lv_remote_domain_lookup_by_uuid_ret; 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_args lv_remote_list_defined_networks_args; 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_args lv_remote_storage_pool_lookup_by_volum 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_network_get_bridge_name_ret lv_remote_network_get_bridge_name_ret; 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_vcpus_ret lv_remote_domain_get_vcpus_ret; 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 --git a/qemud/remote_dispatch_proc_switch.h b/qemud/remote_dispatch_proc_switch.h index 3c788a47de..f574f7e357 100644 --- a/qemud/remote_dispatch_proc_switch.h +++ b/qemud/remote_dispatch_proc_switch.h @@ -560,6 +560,51 @@ case REMOTE_PROC_NETWORK_UNDEFINE: 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; @@ -581,6 +626,24 @@ case REMOTE_PROC_NODE_GET_INFO: 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; ret_filter = (xdrproc_t) xdr_remote_num_of_defined_domains_ret; diff --git a/qemud/remote_dispatch_prototypes.h b/qemud/remote_dispatch_prototypes.h index ae50416963..e0bcd29dfe 100644 --- a/qemud/remote_dispatch_prototypes.h +++ b/qemud/remote_dispatch_prototypes.h @@ -76,9 +76,16 @@ static int remoteDispatchNetworkLookupByName (struct qemud_server *server, struc 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 --git a/qemud/remote_protocol.c b/qemud/remote_protocol.c index 0994e046e5..ec8e6537b5 100644 --- a/qemud/remote_protocol.c +++ b/qemud/remote_protocol.c @@ -83,6 +83,15 @@ xdr_remote_nonnull_storage_vol (XDR *xdrs, remote_nonnull_storage_vol *objp) return TRUE; } +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) { @@ -119,6 +128,15 @@ xdr_remote_storage_vol (XDR *xdrs, remote_storage_vol *objp) 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; +} + bool_t xdr_remote_error (XDR *xdrs, remote_error *objp) { @@ -2007,6 +2025,146 @@ xdr_remote_storage_vol_get_path_ret (XDR *xdrs, remote_storage_vol_get_path_ret return TRUE; } +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 --git a/qemud/remote_protocol.h b/qemud/remote_protocol.h index 89bd2ea03a..bf107ae619 100644 --- a/qemud/remote_protocol.h +++ b/qemud/remote_protocol.h @@ -31,6 +31,8 @@ typedef remote_nonnull_string *remote_string; #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 @@ struct remote_nonnull_storage_vol { }; 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; @@ -74,6 +81,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; int domain; @@ -1122,6 +1131,87 @@ struct remote_storage_vol_get_path_ret { }; 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 @@ enum remote_procedure { 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_domain (XDR *, remote_nonnull_domain*); 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_args (XDR *, remote_storage_vol_g 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_domain (); 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_args (); 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 --git a/qemud/remote_protocol.x b/qemud/remote_protocol.x index e97375284b..22327fdf69 100644 --- a/qemud/remote_protocol.x +++ b/qemud/remote_protocol.x @@ -86,6 +86,12 @@ const REMOTE_STORAGE_POOL_NAME_LIST_MAX = 256; /* 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 @@ struct remote_nonnull_storage_vol { 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 for explanation of fields. */ @@ -994,6 +1006,70 @@ struct remote_storage_vol_get_path_ret { 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; +}; + +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; +}; + + /** * Events Register/Deregister: * It would seem rpcgen does not like both args, and ret @@ -1140,7 +1216,15 @@ enum remote_procedure { 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 --git a/src/remote_internal.c b/src/remote_internal.c index 508325afc8..3fdbc8bbb5 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -143,6 +143,14 @@ struct private_data { 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 virDomainPtr get_nonnull_domain (virConnectPtr conn, remote_nonnull_domai 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); @@ -3767,6 +3776,229 @@ remoteStorageVolGetPath (virStorageVolPtr vol) } +/*----------------------------------------------------------------------*/ + +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 @@ -5029,6 +5261,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. */ static void make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src) @@ -5184,6 +5422,20 @@ static virStorageDriver storage_driver = { .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, @@ -5203,6 +5455,7 @@ remoteRegister (void) 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