This patch contains the remote impl of the node driver.
diff --git a/qemud/remote.c b/qemud/remote.c
index 72e064e..48564e6 100644
--- a/qemud/remote.c
+++ b/qemud/remote.c
@@ -66,6 +66,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"
@@ -3620,6 +3621,304 @@ 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->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;
+}
+
/*----- Helpers. -----*/
/* get_nonnull_domain and get_nonnull_network turn an on-wire
@@ -3690,3 +3989,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_protocol.x b/qemud/remote_protocol.x
index f1bd9ff..71fba79 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 <virterror.h> for explanation of fields. */
@@ -965,6 +977,100 @@ struct remote_storage_vol_get_path_ret {
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;
+};
+
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@@ -1086,7 +1192,21 @@ enum remote_procedure {
REMOTE_PROC_NODE_GET_FREE_MEMORY = 102,
REMOTE_PROC_DOMAIN_BLOCK_PEEK = 103,
- REMOTE_PROC_DOMAIN_MEMORY_PEEK = 104
+ REMOTE_PROC_DOMAIN_MEMORY_PEEK = 104,
+
+ REMOTE_PROC_NODE_NUM_OF_DEVICES = 105,
+ REMOTE_PROC_NODE_LIST_DEVICES = 106,
+ REMOTE_PROC_NODE_NUM_OF_DEVICES_BY_CAP = 107,
+ REMOTE_PROC_NODE_LIST_DEVICES_BY_CAP = 108,
+ REMOTE_PROC_NODE_DEVICE_LOOKUP_BY_NAME = 109,
+ REMOTE_PROC_NODE_DEVICE_DUMP_XML = 110,
+ REMOTE_PROC_NODE_DEVICE_CREATE = 111,
+ REMOTE_PROC_NODE_DEVICE_DESTROY = 112,
+ REMOTE_PROC_NODE_DEVICE_GET_PARENT = 120,
+ REMOTE_PROC_NODE_DEVICE_NUM_OF_CAPS = 121,
+ REMOTE_PROC_NODE_DEVICE_LIST_CAPS = 122,
+
+ REMOTE_PROC_DOMAIN_ASYNC_EVENT = 117
};
/* Custom RPC structure. */
diff --git a/src/remote_internal.c b/src/remote_internal.c
index 35b7b4b..d8dca14 100644
--- a/src/remote_internal.c
+++ b/src/remote_internal.c
@@ -123,6 +123,14 @@ struct private_data {
return (retcode); \
}
+#define GET_NODE_PRIVATE(conn,retcode) \
+ struct private_data *priv = (struct private_data *) (conn)->nodePrivateData; \
+ 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,
@@ -152,6 +160,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);
@@ -3580,6 +3589,331 @@ remoteStorageVolGetPath (virStorageVolPtr vol)
/*----------------------------------------------------------------------*/
+static virDrvOpenStatus remoteNodeDrvOpen(virConnectPtr conn,
+ xmlURIPtr uri ATTRIBUTE_UNUSED,
+ 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->nodePrivateData = conn->privateData;
+ return VIR_DRV_OPEN_SUCCESS;
+ }
+
+ /* Decline open. Will fallback to appropriate local node driver. */
+ return VIR_DRV_OPEN_DECLINED;
+}
+
+static int remoteNodeDrvClose(virConnectPtr conn)
+{
+ int ret = 0;
+ GET_NODE_PRIVATE (conn, -1);
+ if (priv->localUses) {
+ priv->localUses--;
+ if (!priv->localUses) {
+ ret = doRemoteClose(conn, priv);
+ VIR_FREE(priv);
+ conn->nodePrivateData = 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
@@ -4780,6 +5114,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)
@@ -4932,6 +5272,24 @@ static virStorageDriver storage_driver = {
.volGetPath = remoteStorageVolGetPath,
};
+static virNodeDriver node_driver = {
+ .name = "remote",
+ .open = remoteNodeDrvOpen,
+ .close = remoteNodeDrvClose,
+ .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,
@@ -4951,6 +5309,7 @@ remoteRegister (void)
if (virRegisterDriver (&driver) == -1) return -1;
if (virRegisterNetworkDriver (&network_driver) == -1) return -1;
if (virRegisterStorageDriver (&storage_driver) == -1) return -1;
+ if (virRegisterNodeDriver (&node_driver) == -1) return -1;
#ifdef WITH_LIBVIRTD
if (virRegisterStateDriver (&state_driver) == -1) return -1;
#endif
--
Libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list