---
qemud/remote.c | 235 ++++++++++++++++++++++++
qemud/remote_dispatch_args.h | 8 +
qemud/remote_dispatch_prototypes.h | 63 +++++++
qemud/remote_dispatch_ret.h | 6 +
qemud/remote_dispatch_table.h | 50 +++++
qemud/remote_protocol.c | 156 ++++++++++++++++
qemud/remote_protocol.h | 127 +++++++++++++
qemud/remote_protocol.x | 90 +++++++++-
src/datatypes.c | 154 ++++++++++++++++
src/datatypes.h | 6 +
src/libvirt.c | 10 -
src/remote_internal.c | 351 ++++++++++++++++++++++++++++++++++++
12 files changed, 1245 insertions(+), 11 deletions(-)
diff --git a/qemud/remote.c b/qemud/remote.c
index 8d24a3a..6dfd83a 100644
--- a/qemud/remote.c
+++ b/qemud/remote.c
@@ -60,10 +60,12 @@ static void remoteDispatchFormatError (remote_error *rerr,
ATTRIBUTE_FORMAT(printf, 2, 3);
static virDomainPtr get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain
domain);
static virNetworkPtr get_nonnull_network (virConnectPtr conn, remote_nonnull_network
network);
+static virInterfacePtr get_nonnull_interface (virConnectPtr conn,
remote_nonnull_interface interface);
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 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_interface (remote_nonnull_interface *interface_dst,
virInterfacePtr interface_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);
@@ -2559,6 +2561,225 @@ remoteDispatchNumOfNetworks (struct qemud_server *server
ATTRIBUTE_UNUSED,
}
+/*-------------------------------------------------------------*/
+static int
+remoteDispatchNumOfInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ void *args ATTRIBUTE_UNUSED,
+ remote_num_of_interfaces_ret *ret)
+{
+
+ ret->num = virConnectNumOfInterfaces (conn);
+ if (ret->num == -1) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+remoteDispatchListInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_list_interfaces_args *args,
+ remote_list_interfaces_ret *ret)
+{
+
+ if (args->maxnames > REMOTE_INTERFACE_NAME_LIST_MAX) {
+ remoteDispatchFormatError (rerr,
+ "%s", _("maxnames >
REMOTE_INTERFACE_NAME_LIST_MAX"));
+ return -1;
+ }
+
+ /* Allocate return buffer. */
+ if (VIR_ALLOC_N(ret->names.names_val, args->maxnames) < 0) {
+ remoteDispatchOOMError(rerr);
+ return -1;
+ }
+
+ ret->names.names_len =
+ virConnectListInterfaces (conn,
+ ret->names.names_val, args->maxnames);
+ if (ret->names.names_len == -1) {
+ VIR_FREE(ret->names.names_len);
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+remoteDispatchInterfaceLookupByName (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_interface_lookup_by_name_args *args,
+ remote_interface_lookup_by_name_ret *ret)
+{
+ virInterfacePtr interface;
+
+ interface = virInterfaceLookupByName (conn, args->name);
+ if (interface == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ make_nonnull_interface (&ret->interface, interface);
+ virInterfaceFree(interface);
+ return 0;
+}
+
+static int
+remoteDispatchInterfaceLookupByMac (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_interface_lookup_by_mac_args *args,
+ remote_interface_lookup_by_mac_ret *ret)
+{
+ virInterfacePtr interface;
+
+ interface = virInterfaceLookupByMAC (conn, (unsigned char *) args->mac);
+ if (interface == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ make_nonnull_interface (&ret->interface, interface);
+ virInterfaceFree(interface);
+ return 0;
+}
+
+static int
+remoteDispatchInterfaceGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_interface_get_xml_desc_args *args,
+ remote_interface_get_xml_desc_ret *ret)
+{
+ virInterfacePtr interface;
+
+ interface = get_nonnull_interface (conn, args->interface);
+ if (interface == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ /* remoteDispatchClientRequest will free this. */
+ ret->xml = virInterfaceGetXMLDesc (interface, args->flags);
+ if (!ret->xml) {
+ virInterfaceFree(interface);
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+ virInterfaceFree(interface);
+ return 0;
+}
+
+static int
+remoteDispatchInterfaceDefineXml (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_interface_define_xml_args *args,
+ remote_interface_define_xml_ret *ret)
+{
+ virInterfacePtr interface;
+
+ interface = virInterfaceDefineXML (conn, args->xml, args->flags);
+ if (interface == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ make_nonnull_interface (&ret->interface, interface);
+ virInterfaceFree(interface);
+ return 0;
+}
+
+static int
+remoteDispatchInterfaceUndefine (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_interface_undefine_args *args,
+ void *ret ATTRIBUTE_UNUSED)
+{
+ virInterfacePtr interface;
+
+ interface = get_nonnull_interface (conn, args->interface);
+ if (interface == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ if (virInterfaceUndefine (interface) == -1) {
+ virInterfaceFree(interface);
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+ virInterfaceFree(interface);
+ return 0;
+}
+
+static int
+remoteDispatchInterfaceCreate (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_interface_create_args *args,
+ void *ret ATTRIBUTE_UNUSED)
+{
+ virInterfacePtr interface;
+
+ interface = get_nonnull_interface (conn, args->interface);
+ if (interface == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ if (virInterfaceCreate (interface, args->flags) == -1) {
+ virInterfaceFree(interface);
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+ virInterfaceFree(interface);
+ return 0;
+}
+
+static int
+remoteDispatchInterfaceDestroy (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_interface_destroy_args *args,
+ void *ret ATTRIBUTE_UNUSED)
+{
+ virInterfacePtr interface;
+
+ interface = get_nonnull_interface (conn, args->interface);
+ if (interface == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ if (virInterfaceDestroy (interface, args->flags) == -1) {
+ virInterfaceFree(interface);
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+ virInterfaceFree(interface);
+ return 0;
+}
+
+/*-------------------------------------------------------------*/
+
static int
remoteDispatchAuthList (struct qemud_server *server,
struct qemud_client *client,
@@ -4527,6 +4748,12 @@ get_nonnull_network (virConnectPtr conn, remote_nonnull_network
network)
return virGetNetwork (conn, network.name, BAD_CAST network.uuid);
}
+static virInterfacePtr
+get_nonnull_interface (virConnectPtr conn, remote_nonnull_interface interface)
+{
+ return virGetInterface (conn, interface.name, BAD_CAST interface.mac);
+}
+
static virStoragePoolPtr
get_nonnull_storage_pool (virConnectPtr conn, remote_nonnull_storage_pool pool)
{
@@ -4558,6 +4785,14 @@ make_nonnull_network (remote_nonnull_network *net_dst,
virNetworkPtr net_src)
}
static void
+make_nonnull_interface (remote_nonnull_interface *interface_dst,
+ virInterfacePtr interface_src)
+{
+ interface_dst->name = strdup (interface_src->name);
+ memcpy (interface_dst->mac, interface_src->mac, VIR_MAC_BUFLEN);
+}
+
+static void
make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr
pool_src)
{
pool_dst->name = strdup (pool_src->name);
diff --git a/qemud/remote_dispatch_args.h b/qemud/remote_dispatch_args.h
index 58eccf5..2297a48 100644
--- a/qemud/remote_dispatch_args.h
+++ b/qemud/remote_dispatch_args.h
@@ -105,3 +105,11 @@
remote_domain_get_security_label_args val_remote_domain_get_security_label_args;
remote_node_device_create_xml_args val_remote_node_device_create_xml_args;
remote_node_device_destroy_args val_remote_node_device_destroy_args;
+ remote_list_interfaces_args val_remote_list_interfaces_args;
+ remote_interface_lookup_by_name_args val_remote_interface_lookup_by_name_args;
+ remote_interface_lookup_by_mac_args val_remote_interface_lookup_by_mac_args;
+ remote_interface_get_xml_desc_args val_remote_interface_get_xml_desc_args;
+ remote_interface_define_xml_args val_remote_interface_define_xml_args;
+ remote_interface_undefine_args val_remote_interface_undefine_args;
+ remote_interface_create_args val_remote_interface_create_args;
+ remote_interface_destroy_args val_remote_interface_destroy_args;
diff --git a/qemud/remote_dispatch_prototypes.h b/qemud/remote_dispatch_prototypes.h
index 96dcb2a..80044c1 100644
--- a/qemud/remote_dispatch_prototypes.h
+++ b/qemud/remote_dispatch_prototypes.h
@@ -408,6 +408,55 @@ static int remoteDispatchGetVersion(
remote_error *err,
void *args,
remote_get_version_ret *ret);
+static int remoteDispatchInterfaceCreate(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_interface_create_args *args,
+ void *ret);
+static int remoteDispatchInterfaceDefineXml(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_interface_define_xml_args *args,
+ remote_interface_define_xml_ret *ret);
+static int remoteDispatchInterfaceDestroy(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_interface_destroy_args *args,
+ void *ret);
+static int remoteDispatchInterfaceGetXmlDesc(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_interface_get_xml_desc_args *args,
+ remote_interface_get_xml_desc_ret *ret);
+static int remoteDispatchInterfaceLookupByMac(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_interface_lookup_by_mac_args *args,
+ remote_interface_lookup_by_mac_ret *ret);
+static int remoteDispatchInterfaceLookupByName(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_interface_lookup_by_name_args *args,
+ remote_interface_lookup_by_name_ret *ret);
+static int remoteDispatchInterfaceUndefine(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_interface_undefine_args *args,
+ void *ret);
static int remoteDispatchListDefinedDomains(
struct qemud_server *server,
struct qemud_client *client,
@@ -436,6 +485,13 @@ static int remoteDispatchListDomains(
remote_error *err,
remote_list_domains_args *args,
remote_list_domains_ret *ret);
+static int remoteDispatchListInterfaces(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_list_interfaces_args *args,
+ remote_list_interfaces_ret *ret);
static int remoteDispatchListNetworks(
struct qemud_server *server,
struct qemud_client *client,
@@ -667,6 +723,13 @@ static int remoteDispatchNumOfDomains(
remote_error *err,
void *args,
remote_num_of_domains_ret *ret);
+static int remoteDispatchNumOfInterfaces(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ void *args,
+ remote_num_of_interfaces_ret *ret);
static int remoteDispatchNumOfNetworks(
struct qemud_server *server,
struct qemud_client *client,
diff --git a/qemud/remote_dispatch_ret.h b/qemud/remote_dispatch_ret.h
index 3325c8b..1c5380a 100644
--- a/qemud/remote_dispatch_ret.h
+++ b/qemud/remote_dispatch_ret.h
@@ -89,3 +89,9 @@
remote_domain_get_security_label_ret val_remote_domain_get_security_label_ret;
remote_node_get_security_model_ret val_remote_node_get_security_model_ret;
remote_node_device_create_xml_ret val_remote_node_device_create_xml_ret;
+ remote_num_of_interfaces_ret val_remote_num_of_interfaces_ret;
+ remote_list_interfaces_ret val_remote_list_interfaces_ret;
+ remote_interface_lookup_by_name_ret val_remote_interface_lookup_by_name_ret;
+ remote_interface_lookup_by_mac_ret val_remote_interface_lookup_by_mac_ret;
+ remote_interface_get_xml_desc_ret val_remote_interface_get_xml_desc_ret;
+ remote_interface_define_xml_ret val_remote_interface_define_xml_ret;
diff --git a/qemud/remote_dispatch_table.h b/qemud/remote_dispatch_table.h
index ac7f9b9..68e67e5 100644
--- a/qemud/remote_dispatch_table.h
+++ b/qemud/remote_dispatch_table.h
@@ -627,3 +627,53 @@
.args_filter = (xdrproc_t) xdr_remote_node_device_destroy_args,
.ret_filter = (xdrproc_t) xdr_void,
},
+{ /* (unused) => 125 */
+ .fn = NULL,
+ .args_filter = (xdrproc_t) xdr_void,
+ .ret_filter = (xdrproc_t) xdr_void,
+},
+{ /* NumOfInterfaces => 126 */
+ .fn = (dispatch_fn) remoteDispatchNumOfInterfaces,
+ .args_filter = (xdrproc_t) xdr_void,
+ .ret_filter = (xdrproc_t) xdr_remote_num_of_interfaces_ret,
+},
+{ /* ListInterfaces => 127 */
+ .fn = (dispatch_fn) remoteDispatchListInterfaces,
+ .args_filter = (xdrproc_t) xdr_remote_list_interfaces_args,
+ .ret_filter = (xdrproc_t) xdr_remote_list_interfaces_ret,
+},
+{ /* InterfaceLookupByName => 128 */
+ .fn = (dispatch_fn) remoteDispatchInterfaceLookupByName,
+ .args_filter = (xdrproc_t) xdr_remote_interface_lookup_by_name_args,
+ .ret_filter = (xdrproc_t) xdr_remote_interface_lookup_by_name_ret,
+},
+{ /* InterfaceLookupByMac => 129 */
+ .fn = (dispatch_fn) remoteDispatchInterfaceLookupByMac,
+ .args_filter = (xdrproc_t) xdr_remote_interface_lookup_by_mac_args,
+ .ret_filter = (xdrproc_t) xdr_remote_interface_lookup_by_mac_ret,
+},
+{ /* InterfaceGetXmlDesc => 130 */
+ .fn = (dispatch_fn) remoteDispatchInterfaceGetXmlDesc,
+ .args_filter = (xdrproc_t) xdr_remote_interface_get_xml_desc_args,
+ .ret_filter = (xdrproc_t) xdr_remote_interface_get_xml_desc_ret,
+},
+{ /* InterfaceDefineXml => 131 */
+ .fn = (dispatch_fn) remoteDispatchInterfaceDefineXml,
+ .args_filter = (xdrproc_t) xdr_remote_interface_define_xml_args,
+ .ret_filter = (xdrproc_t) xdr_remote_interface_define_xml_ret,
+},
+{ /* InterfaceUndefine => 132 */
+ .fn = (dispatch_fn) remoteDispatchInterfaceUndefine,
+ .args_filter = (xdrproc_t) xdr_remote_interface_undefine_args,
+ .ret_filter = (xdrproc_t) xdr_void,
+},
+{ /* InterfaceCreate => 133 */
+ .fn = (dispatch_fn) remoteDispatchInterfaceCreate,
+ .args_filter = (xdrproc_t) xdr_remote_interface_create_args,
+ .ret_filter = (xdrproc_t) xdr_void,
+},
+{ /* InterfaceDestroy => 134 */
+ .fn = (dispatch_fn) remoteDispatchInterfaceDestroy,
+ .args_filter = (xdrproc_t) xdr_remote_interface_destroy_args,
+ .ret_filter = (xdrproc_t) xdr_void,
+},
diff --git a/qemud/remote_protocol.c b/qemud/remote_protocol.c
index af3c792..578857d 100644
--- a/qemud/remote_protocol.c
+++ b/qemud/remote_protocol.c
@@ -36,6 +36,15 @@ xdr_remote_uuid (XDR *xdrs, remote_uuid objp)
}
bool_t
+xdr_remote_mac (XDR *xdrs, remote_mac objp)
+{
+
+ if (!xdr_opaque (xdrs, objp, VIR_MAC_BUFLEN))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_remote_nonnull_domain (XDR *xdrs, remote_nonnull_domain *objp)
{
@@ -60,6 +69,17 @@ xdr_remote_nonnull_network (XDR *xdrs, remote_nonnull_network *objp)
}
bool_t
+xdr_remote_nonnull_interface (XDR *xdrs, remote_nonnull_interface *objp)
+{
+
+ if (!xdr_remote_nonnull_string (xdrs, &objp->name))
+ return FALSE;
+ if (!xdr_remote_mac (xdrs, objp->mac))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_remote_nonnull_storage_pool (XDR *xdrs, remote_nonnull_storage_pool *objp)
{
@@ -1478,6 +1498,142 @@ xdr_remote_network_set_autostart_args (XDR *xdrs,
remote_network_set_autostart_a
}
bool_t
+xdr_remote_num_of_interfaces_ret (XDR *xdrs, remote_num_of_interfaces_ret *objp)
+{
+
+ if (!xdr_int (xdrs, &objp->num))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_list_interfaces_args (XDR *xdrs, remote_list_interfaces_args *objp)
+{
+
+ if (!xdr_int (xdrs, &objp->maxnames))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_list_interfaces_ret (XDR *xdrs, remote_list_interfaces_ret *objp)
+{
+ char **objp_cpp0 = (char **) (void *) &objp->names.names_val;
+
+ if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->names.names_len,
REMOTE_INTERFACE_NAME_LIST_MAX,
+ sizeof (remote_nonnull_string), (xdrproc_t) xdr_remote_nonnull_string))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_interface_lookup_by_name_args (XDR *xdrs, remote_interface_lookup_by_name_args
*objp)
+{
+
+ if (!xdr_remote_nonnull_string (xdrs, &objp->name))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_interface_lookup_by_name_ret (XDR *xdrs, remote_interface_lookup_by_name_ret
*objp)
+{
+
+ if (!xdr_remote_nonnull_interface (xdrs, &objp->interface))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_interface_lookup_by_mac_args (XDR *xdrs, remote_interface_lookup_by_mac_args
*objp)
+{
+
+ if (!xdr_remote_mac (xdrs, objp->mac))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_interface_lookup_by_mac_ret (XDR *xdrs, remote_interface_lookup_by_mac_ret
*objp)
+{
+
+ if (!xdr_remote_nonnull_interface (xdrs, &objp->interface))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_interface_get_xml_desc_args (XDR *xdrs, remote_interface_get_xml_desc_args
*objp)
+{
+
+ if (!xdr_remote_nonnull_interface (xdrs, &objp->interface))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->flags))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_interface_get_xml_desc_ret (XDR *xdrs, remote_interface_get_xml_desc_ret
*objp)
+{
+
+ if (!xdr_remote_nonnull_string (xdrs, &objp->xml))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_interface_define_xml_args (XDR *xdrs, remote_interface_define_xml_args *objp)
+{
+
+ if (!xdr_remote_nonnull_string (xdrs, &objp->xml))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->flags))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_interface_define_xml_ret (XDR *xdrs, remote_interface_define_xml_ret *objp)
+{
+
+ if (!xdr_remote_nonnull_interface (xdrs, &objp->interface))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_interface_undefine_args (XDR *xdrs, remote_interface_undefine_args *objp)
+{
+
+ if (!xdr_remote_nonnull_interface (xdrs, &objp->interface))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_interface_create_args (XDR *xdrs, remote_interface_create_args *objp)
+{
+
+ if (!xdr_remote_nonnull_interface (xdrs, &objp->interface))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->flags))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_interface_destroy_args (XDR *xdrs, remote_interface_destroy_args *objp)
+{
+
+ if (!xdr_remote_nonnull_interface (xdrs, &objp->interface))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->flags))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_remote_auth_list_ret (XDR *xdrs, remote_auth_list_ret *objp)
{
char **objp_cpp0 = (char **) (void *) &objp->types.types_val;
diff --git a/qemud/remote_protocol.h b/qemud/remote_protocol.h
index 9d67e58..7201720 100644
--- a/qemud/remote_protocol.h
+++ b/qemud/remote_protocol.h
@@ -28,6 +28,7 @@ typedef remote_nonnull_string *remote_string;
#define REMOTE_CPUMAPS_MAX 16384
#define REMOTE_MIGRATE_COOKIE_MAX 256
#define REMOTE_NETWORK_NAME_LIST_MAX 256
+#define REMOTE_INTERFACE_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
@@ -44,6 +45,8 @@ typedef remote_nonnull_string *remote_string;
typedef char remote_uuid[VIR_UUID_BUFLEN];
+typedef char remote_mac[VIR_MAC_BUFLEN];
+
struct remote_nonnull_domain {
remote_nonnull_string name;
remote_uuid uuid;
@@ -57,6 +60,12 @@ struct remote_nonnull_network {
};
typedef struct remote_nonnull_network remote_nonnull_network;
+struct remote_nonnull_interface {
+ remote_nonnull_string name;
+ remote_mac mac;
+};
+typedef struct remote_nonnull_interface remote_nonnull_interface;
+
struct remote_nonnull_storage_pool {
remote_nonnull_string name;
remote_uuid uuid;
@@ -822,6 +831,83 @@ struct remote_network_set_autostart_args {
};
typedef struct remote_network_set_autostart_args remote_network_set_autostart_args;
+struct remote_num_of_interfaces_ret {
+ int num;
+};
+typedef struct remote_num_of_interfaces_ret remote_num_of_interfaces_ret;
+
+struct remote_list_interfaces_args {
+ int maxnames;
+};
+typedef struct remote_list_interfaces_args remote_list_interfaces_args;
+
+struct remote_list_interfaces_ret {
+ struct {
+ u_int names_len;
+ remote_nonnull_string *names_val;
+ } names;
+};
+typedef struct remote_list_interfaces_ret remote_list_interfaces_ret;
+
+struct remote_interface_lookup_by_name_args {
+ remote_nonnull_string name;
+};
+typedef struct remote_interface_lookup_by_name_args
remote_interface_lookup_by_name_args;
+
+struct remote_interface_lookup_by_name_ret {
+ remote_nonnull_interface interface;
+};
+typedef struct remote_interface_lookup_by_name_ret remote_interface_lookup_by_name_ret;
+
+struct remote_interface_lookup_by_mac_args {
+ remote_mac mac;
+};
+typedef struct remote_interface_lookup_by_mac_args remote_interface_lookup_by_mac_args;
+
+struct remote_interface_lookup_by_mac_ret {
+ remote_nonnull_interface interface;
+};
+typedef struct remote_interface_lookup_by_mac_ret remote_interface_lookup_by_mac_ret;
+
+struct remote_interface_get_xml_desc_args {
+ remote_nonnull_interface interface;
+ int flags;
+};
+typedef struct remote_interface_get_xml_desc_args remote_interface_get_xml_desc_args;
+
+struct remote_interface_get_xml_desc_ret {
+ remote_nonnull_string xml;
+};
+typedef struct remote_interface_get_xml_desc_ret remote_interface_get_xml_desc_ret;
+
+struct remote_interface_define_xml_args {
+ remote_nonnull_string xml;
+ int flags;
+};
+typedef struct remote_interface_define_xml_args remote_interface_define_xml_args;
+
+struct remote_interface_define_xml_ret {
+ remote_nonnull_interface interface;
+};
+typedef struct remote_interface_define_xml_ret remote_interface_define_xml_ret;
+
+struct remote_interface_undefine_args {
+ remote_nonnull_interface interface;
+};
+typedef struct remote_interface_undefine_args remote_interface_undefine_args;
+
+struct remote_interface_create_args {
+ remote_nonnull_interface interface;
+ int flags;
+};
+typedef struct remote_interface_create_args remote_interface_create_args;
+
+struct remote_interface_destroy_args {
+ remote_nonnull_interface interface;
+ int flags;
+};
+typedef struct remote_interface_destroy_args remote_interface_destroy_args;
+
struct remote_auth_list_ret {
struct {
u_int types_len;
@@ -1415,6 +1501,15 @@ enum remote_procedure {
REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122,
REMOTE_PROC_NODE_DEVICE_CREATE_XML = 123,
REMOTE_PROC_NODE_DEVICE_DESTROY = 124,
+ REMOTE_PROC_NUM_OF_INTERFACES = 126,
+ REMOTE_PROC_LIST_INTERFACES = 127,
+ REMOTE_PROC_INTERFACE_LOOKUP_BY_NAME = 128,
+ REMOTE_PROC_INTERFACE_LOOKUP_BY_MAC = 129,
+ REMOTE_PROC_INTERFACE_GET_XML_DESC = 130,
+ REMOTE_PROC_INTERFACE_DEFINE_XML = 131,
+ REMOTE_PROC_INTERFACE_UNDEFINE = 132,
+ REMOTE_PROC_INTERFACE_CREATE = 133,
+ REMOTE_PROC_INTERFACE_DESTROY = 134,
};
typedef enum remote_procedure remote_procedure;
@@ -1448,8 +1543,10 @@ typedef struct remote_message_header remote_message_header;
extern bool_t xdr_remote_nonnull_string (XDR *, remote_nonnull_string*);
extern bool_t xdr_remote_string (XDR *, remote_string*);
extern bool_t xdr_remote_uuid (XDR *, remote_uuid);
+extern bool_t xdr_remote_mac (XDR *, remote_mac);
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_interface (XDR *, remote_nonnull_interface*);
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*);
@@ -1573,6 +1670,20 @@ extern bool_t xdr_remote_network_get_bridge_name_ret (XDR *,
remote_network_get
extern bool_t xdr_remote_network_get_autostart_args (XDR *,
remote_network_get_autostart_args*);
extern bool_t xdr_remote_network_get_autostart_ret (XDR *,
remote_network_get_autostart_ret*);
extern bool_t xdr_remote_network_set_autostart_args (XDR *,
remote_network_set_autostart_args*);
+extern bool_t xdr_remote_num_of_interfaces_ret (XDR *, remote_num_of_interfaces_ret*);
+extern bool_t xdr_remote_list_interfaces_args (XDR *, remote_list_interfaces_args*);
+extern bool_t xdr_remote_list_interfaces_ret (XDR *, remote_list_interfaces_ret*);
+extern bool_t xdr_remote_interface_lookup_by_name_args (XDR *,
remote_interface_lookup_by_name_args*);
+extern bool_t xdr_remote_interface_lookup_by_name_ret (XDR *,
remote_interface_lookup_by_name_ret*);
+extern bool_t xdr_remote_interface_lookup_by_mac_args (XDR *,
remote_interface_lookup_by_mac_args*);
+extern bool_t xdr_remote_interface_lookup_by_mac_ret (XDR *,
remote_interface_lookup_by_mac_ret*);
+extern bool_t xdr_remote_interface_get_xml_desc_args (XDR *,
remote_interface_get_xml_desc_args*);
+extern bool_t xdr_remote_interface_get_xml_desc_ret (XDR *,
remote_interface_get_xml_desc_ret*);
+extern bool_t xdr_remote_interface_define_xml_args (XDR *,
remote_interface_define_xml_args*);
+extern bool_t xdr_remote_interface_define_xml_ret (XDR *,
remote_interface_define_xml_ret*);
+extern bool_t xdr_remote_interface_undefine_args (XDR *,
remote_interface_undefine_args*);
+extern bool_t xdr_remote_interface_create_args (XDR *, remote_interface_create_args*);
+extern bool_t xdr_remote_interface_destroy_args (XDR *,
remote_interface_destroy_args*);
extern bool_t xdr_remote_auth_list_ret (XDR *, remote_auth_list_ret*);
extern bool_t xdr_remote_auth_sasl_init_ret (XDR *, remote_auth_sasl_init_ret*);
extern bool_t xdr_remote_auth_sasl_start_args (XDR *, remote_auth_sasl_start_args*);
@@ -1662,8 +1773,10 @@ extern bool_t xdr_remote_message_header (XDR *,
remote_message_header*);
extern bool_t xdr_remote_nonnull_string ();
extern bool_t xdr_remote_string ();
extern bool_t xdr_remote_uuid ();
+extern bool_t xdr_remote_mac ();
extern bool_t xdr_remote_nonnull_domain ();
extern bool_t xdr_remote_nonnull_network ();
+extern bool_t xdr_remote_nonnull_interface ();
extern bool_t xdr_remote_nonnull_storage_pool ();
extern bool_t xdr_remote_nonnull_storage_vol ();
extern bool_t xdr_remote_nonnull_node_device ();
@@ -1787,6 +1900,20 @@ extern bool_t xdr_remote_network_get_bridge_name_ret ();
extern bool_t xdr_remote_network_get_autostart_args ();
extern bool_t xdr_remote_network_get_autostart_ret ();
extern bool_t xdr_remote_network_set_autostart_args ();
+extern bool_t xdr_remote_num_of_interfaces_ret ();
+extern bool_t xdr_remote_list_interfaces_args ();
+extern bool_t xdr_remote_list_interfaces_ret ();
+extern bool_t xdr_remote_interface_lookup_by_name_args ();
+extern bool_t xdr_remote_interface_lookup_by_name_ret ();
+extern bool_t xdr_remote_interface_lookup_by_mac_args ();
+extern bool_t xdr_remote_interface_lookup_by_mac_ret ();
+extern bool_t xdr_remote_interface_get_xml_desc_args ();
+extern bool_t xdr_remote_interface_get_xml_desc_ret ();
+extern bool_t xdr_remote_interface_define_xml_args ();
+extern bool_t xdr_remote_interface_define_xml_ret ();
+extern bool_t xdr_remote_interface_undefine_args ();
+extern bool_t xdr_remote_interface_create_args ();
+extern bool_t xdr_remote_interface_destroy_args ();
extern bool_t xdr_remote_auth_list_ret ();
extern bool_t xdr_remote_auth_sasl_init_ret ();
extern bool_t xdr_remote_auth_sasl_start_args ();
diff --git a/qemud/remote_protocol.x b/qemud/remote_protocol.x
index 2c79949..6abc908 100644
--- a/qemud/remote_protocol.x
+++ b/qemud/remote_protocol.x
@@ -79,6 +79,9 @@ const REMOTE_MIGRATE_COOKIE_MAX = 256;
/* Upper limit on lists of network names. */
const REMOTE_NETWORK_NAME_LIST_MAX = 256;
+/* Upper limit on lists of interface names. */
+const REMOTE_INTERFACE_NAME_LIST_MAX = 256;
+
/* Upper limit on lists of storage pool names. */
const REMOTE_STORAGE_POOL_NAME_LIST_MAX = 256;
@@ -133,6 +136,9 @@ const REMOTE_SECURITY_DOI_MAX = VIR_SECURITY_DOI_BUFLEN;
/* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */
typedef opaque remote_uuid[VIR_UUID_BUFLEN];
+/* MAC. VIR_MAC_BUFLEN definition comes from libvirt.h */
+typedef opaque remote_mac[VIR_MAC_BUFLEN];
+
/* A domain which may not be NULL. */
struct remote_nonnull_domain {
remote_nonnull_string name;
@@ -146,6 +152,12 @@ struct remote_nonnull_network {
remote_uuid uuid;
};
+/* An interface which may not be NULL. */
+struct remote_nonnull_interface {
+ remote_nonnull_string name;
+ remote_mac mac;
+};
+
/* A storage pool which may not be NULL. */
struct remote_nonnull_storage_pool {
remote_nonnull_string name;
@@ -770,6 +782,71 @@ struct remote_network_set_autostart_args {
};
+/* Interface calls: */
+
+struct remote_num_of_interfaces_ret {
+ int num;
+};
+
+struct remote_list_interfaces_args {
+ int maxnames;
+};
+
+struct remote_list_interfaces_ret {
+ remote_nonnull_string names<REMOTE_INTERFACE_NAME_LIST_MAX>;
+};
+
+struct remote_interface_lookup_by_name_args {
+ remote_nonnull_string name;
+};
+
+struct remote_interface_lookup_by_name_ret {
+ remote_nonnull_interface interface;
+};
+
+struct remote_interface_lookup_by_mac_args {
+ remote_mac mac;
+};
+
+struct remote_interface_lookup_by_mac_ret {
+ remote_nonnull_interface interface;
+};
+
+struct remote_interface_get_xml_desc_args {
+ remote_nonnull_interface interface;
+ int flags;
+};
+
+struct remote_interface_get_xml_desc_ret {
+ remote_nonnull_string xml;
+};
+
+struct remote_interface_define_xml_args {
+ remote_nonnull_string xml;
+ int flags;
+};
+
+struct remote_interface_define_xml_ret {
+ remote_nonnull_interface interface;
+};
+
+struct remote_interface_undefine_args {
+ remote_nonnull_interface interface;
+};
+
+struct remote_interface_create_args {
+ remote_nonnull_interface interface;
+ int flags;
+};
+
+struct remote_interface_destroy_args {
+ remote_nonnull_interface interface;
+ int flags;
+};
+
+
+/* Auth calls: */
+
struct remote_auth_list_ret {
remote_auth_type types<REMOTE_AUTH_TYPE_LIST_MAX>;
};
@@ -1286,7 +1363,18 @@ enum remote_procedure {
REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122,
REMOTE_PROC_NODE_DEVICE_CREATE_XML = 123,
- REMOTE_PROC_NODE_DEVICE_DESTROY = 124
+ REMOTE_PROC_NODE_DEVICE_DESTROY = 124,
+
+ REMOTE_PROC_NUM_OF_INTERFACES = 126,
+ REMOTE_PROC_LIST_INTERFACES = 127,
+ REMOTE_PROC_INTERFACE_LOOKUP_BY_NAME = 128,
+ REMOTE_PROC_INTERFACE_LOOKUP_BY_MAC = 129,
+ REMOTE_PROC_INTERFACE_GET_XML_DESC = 130,
+ REMOTE_PROC_INTERFACE_DEFINE_XML = 131,
+ REMOTE_PROC_INTERFACE_UNDEFINE = 132,
+ REMOTE_PROC_INTERFACE_CREATE = 133,
+ REMOTE_PROC_INTERFACE_DESTROY = 134
+
};
/* Custom RPC structure. */
diff --git a/src/datatypes.c b/src/datatypes.c
index b1013f2..8593e2b 100644
--- a/src/datatypes.c
+++ b/src/datatypes.c
@@ -67,6 +67,20 @@ virNetworkFreeName(virNetworkPtr network, const char *name
ATTRIBUTE_UNUSED)
}
/**
+ * virInterfaceFreeName:
+ * @interface: a interface object
+ *
+ * Destroy the interface object, this is just used by the interface hash callback.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+static int
+virInterfaceFreeName(virInterfacePtr interface, const char *name ATTRIBUTE_UNUSED)
+{
+ return (virUnrefInterface(interface));
+}
+
+/**
* virStoragePoolFreeName:
* @pool: a pool object
*
@@ -119,12 +133,16 @@ virGetConnect(void) {
ret->networkDriver = NULL;
ret->privateData = NULL;
ret->networkPrivateData = NULL;
+ ret->interfacePrivateData = NULL;
ret->domains = virHashCreate(20);
if (ret->domains == NULL)
goto failed;
ret->networks = virHashCreate(20);
if (ret->networks == NULL)
goto failed;
+ ret->interfaces = virHashCreate(20);
+ if (ret->interfaces == NULL)
+ goto failed;
ret->storagePools = virHashCreate(20);
if (ret->storagePools == NULL)
goto failed;
@@ -144,6 +162,8 @@ failed:
virHashFree(ret->domains, (virHashDeallocator) virDomainFreeName);
if (ret->networks != NULL)
virHashFree(ret->networks, (virHashDeallocator) virNetworkFreeName);
+ if (ret->interfaces != NULL)
+ virHashFree(ret->interfaces, (virHashDeallocator) virInterfaceFreeName);
if (ret->storagePools != NULL)
virHashFree(ret->storagePools, (virHashDeallocator)
virStoragePoolFreeName);
if (ret->storageVols != NULL)
@@ -173,6 +193,8 @@ virReleaseConnect(virConnectPtr conn) {
virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
if (conn->networks != NULL)
virHashFree(conn->networks, (virHashDeallocator) virNetworkFreeName);
+ if (conn->interfaces != NULL)
+ virHashFree(conn->interfaces, (virHashDeallocator) virInterfaceFreeName);
if (conn->storagePools != NULL)
virHashFree(conn->storagePools, (virHashDeallocator) virStoragePoolFreeName);
if (conn->storageVols != NULL)
@@ -488,6 +510,138 @@ virUnrefNetwork(virNetworkPtr network) {
/**
+ * virGetInterface:
+ * @conn: the hypervisor connection
+ * @name: pointer to the interface name
+ * @mac: pointer to the mac
+ *
+ * Lookup if the interface is already registered for that connection,
+ * if yes return a new pointer to it, if no allocate a new structure,
+ * and register it in the table. In any case a corresponding call to
+ * virUnrefInterface() is needed to not leak data.
+ *
+ * Returns a pointer to the interface, or NULL in case of failure
+ */
+virInterfacePtr
+virGetInterface(virConnectPtr conn, const char *name, const unsigned char *mac) {
+ virInterfacePtr ret = NULL;
+
+ if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (mac == NULL)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(NULL);
+ }
+ virMutexLock(&conn->lock);
+
+ /* TODO search by MAC first as they are better differentiators */
+
+ ret = (virInterfacePtr) virHashLookup(conn->interfaces, name);
+ /* TODO check the MAC */
+ if (ret == NULL) {
+ if (VIR_ALLOC(ret) < 0) {
+ virReportOOMError(conn);
+ goto error;
+ }
+ ret->name = strdup(name);
+ if (ret->name == NULL) {
+ virReportOOMError(conn);
+ goto error;
+ }
+ ret->magic = VIR_INTERFACE_MAGIC;
+ ret->conn = conn;
+ if (mac != NULL)
+ memcpy(&(ret->mac[0]), mac, VIR_MAC_BUFLEN);
+
+ if (virHashAddEntry(conn->interfaces, name, ret) < 0) {
+ virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("failed to add interface to connection hash
table"));
+ goto error;
+ }
+ conn->refs++;
+ }
+ ret->refs++;
+ virMutexUnlock(&conn->lock);
+ return(ret);
+
+ error:
+ virMutexUnlock(&conn->lock);
+ if (ret != NULL) {
+ VIR_FREE(ret->name);
+ VIR_FREE(ret);
+ }
+ return(NULL);
+}
+
+/**
+ * virReleaseInterface:
+ * @interface: the interface to release
+ *
+ * Unconditionally release all memory associated with a interface.
+ * The conn.lock mutex must be held prior to calling this, and will
+ * be released prior to this returning. The interface obj must not
+ * be used once this method returns.
+ *
+ * It will also unreference the associated connection object,
+ * which may also be released if its ref count hits zero.
+ */
+static void
+virReleaseInterface(virInterfacePtr interface) {
+ virConnectPtr conn = interface->conn;
+ DEBUG("release interface %p %s", interface, interface->name);
+
+ /* TODO search by MAC first as they are better differenciators */
+ if (virHashRemoveEntry(conn->interfaces, interface->name, NULL) < 0)
+ virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("interface missing from connection hash table"));
+
+ interface->magic = -1;
+ VIR_FREE(interface->name);
+ VIR_FREE(interface);
+
+ DEBUG("unref connection %p %d", conn, conn->refs);
+ conn->refs--;
+ if (conn->refs == 0) {
+ virReleaseConnect(conn);
+ /* Already unlocked mutex */
+ return;
+ }
+
+ virMutexUnlock(&conn->lock);
+}
+
+
+/**
+ * virUnrefInterface:
+ * @interface: the interface to unreference
+ *
+ * Unreference the interface. If the use count drops to zero, the structure is
+ * actually freed.
+ *
+ * Returns the reference count or -1 in case of failure.
+ */
+int
+virUnrefInterface(virInterfacePtr interface) {
+ int refs;
+
+ if (!VIR_IS_CONNECTED_INTERFACE(interface)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(-1);
+ }
+ virMutexLock(&interface->conn->lock);
+ DEBUG("unref interface %p %s %d", interface, interface->name,
interface->refs);
+ interface->refs--;
+ refs = interface->refs;
+ if (refs == 0) {
+ virReleaseInterface(interface);
+ /* Already unlocked mutex */
+ return (0);
+ }
+
+ virMutexUnlock(&interface->conn->lock);
+ return (refs);
+}
+
+
+/**
* virGetStoragePool:
* @conn: the hypervisor connection
* @name: pointer to the storage pool name
diff --git a/src/datatypes.h b/src/datatypes.h
index deac9df..e56755b 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -145,6 +145,7 @@ struct _virConnect {
virHashTablePtr domains; /* hash table for known domains */
virHashTablePtr networks; /* hash table for known domains */
+ virHashTablePtr interfaces; /* hash table for known interfaces */
virHashTablePtr storagePools;/* hash table for known storage pools */
virHashTablePtr storageVols;/* hash table for known storage vols */
virHashTablePtr nodeDevices; /* hash table for known node devices */
@@ -250,6 +251,11 @@ virNetworkPtr virGetNetwork(virConnectPtr conn,
const unsigned char *uuid);
int virUnrefNetwork(virNetworkPtr network);
+virInterfacePtr virGetInterface(virConnectPtr conn,
+ const char *name,
+ const unsigned char *mac);
+int virUnrefInterface(virInterfacePtr interface);
+
virStoragePoolPtr virGetStoragePool(virConnectPtr conn,
const char *name,
const unsigned char *uuid);
diff --git a/src/libvirt.c b/src/libvirt.c
index 4bd85a7..15f107a 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -5958,18 +5958,8 @@ virInterfaceFree(virInterfacePtr interface)
virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
return (-1);
}
-#if 0
- /*
- * FIXME: This needs to be uncommented when the stubs are replaced
- * with actual functionality.
- */
-
if (virUnrefInterface(interface) < 0)
return (-1);
-#else
- interface->refs--;
-#endif
-
return(0);
}
diff --git a/src/remote_internal.c b/src/remote_internal.c
index 24226e5..6bc2b9c 100644
--- a/src/remote_internal.c
+++ b/src/remote_internal.c
@@ -211,11 +211,13 @@ static void errorf (virConnectPtr conn, virErrorNumber code,
static void server_error (virConnectPtr conn, remote_error *err);
static virDomainPtr get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain
domain);
static virNetworkPtr get_nonnull_network (virConnectPtr conn, remote_nonnull_network
network);
+static virInterfacePtr get_nonnull_interface (virConnectPtr conn,
remote_nonnull_interface interface);
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_interface (remote_nonnull_interface *interface_dst,
virInterfacePtr interface_src);
static void make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst,
virStoragePoolPtr vol_src);
static void make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst,
virStorageVolPtr vol_src);
void remoteDomainEventFired(int watch, int fd, int event, void *data);
@@ -3684,6 +3686,325 @@ done:
/*----------------------------------------------------------------------*/
static virDrvOpenStatus
+remoteInterfaceOpen (virConnectPtr conn,
+ virConnectAuthPtr auth,
+ int flags)
+{
+ if (inside_daemon)
+ return VIR_DRV_OPEN_DECLINED;
+
+ if (conn &&
+ conn->driver &&
+ STREQ (conn->driver->name, "remote")) {
+ struct private_data *priv;
+
+ /* 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
+ */
+ priv = conn->privateData;
+ remoteDriverLock(priv);
+ priv->localUses++;
+ conn->interfacePrivateData = priv;
+ remoteDriverUnlock(priv);
+ return VIR_DRV_OPEN_SUCCESS;
+ } else {
+ /* Using a non-remote driver, so we need to open a
+ * new connection for interface APIs, forcing it to
+ * use the UNIX transport. This handles Xen driver
+ * which doesn't have its own impl of the interface APIs.
+ */
+ struct private_data *priv;
+ int ret;
+ ret = remoteOpenSecondaryDriver(conn,
+ auth,
+ flags,
+ &priv);
+ if (ret == VIR_DRV_OPEN_SUCCESS)
+ conn->interfacePrivateData = priv;
+ return ret;
+ }
+}
+
+static int
+remoteInterfaceClose (virConnectPtr conn)
+{
+ int rv = 0;
+ struct private_data *priv = conn->interfacePrivateData;
+
+ remoteDriverLock(priv);
+ priv->localUses--;
+ if (!priv->localUses) {
+ rv = doRemoteClose(conn, priv);
+ conn->interfacePrivateData = NULL;
+ remoteDriverUnlock(priv);
+ virMutexDestroy(&priv->lock);
+ VIR_FREE(priv);
+ }
+ if (priv)
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+static int
+remoteNumOfInterfaces (virConnectPtr conn)
+{
+ int rv = -1;
+ remote_num_of_interfaces_ret ret;
+ struct private_data *priv = conn->interfacePrivateData;
+
+ remoteDriverLock(priv);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_INTERFACES,
+ (xdrproc_t) xdr_void, (char *) NULL,
+ (xdrproc_t) xdr_remote_num_of_interfaces_ret, (char *) &ret) == -1)
+ goto done;
+
+ rv = ret.num;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+static int
+remoteListInterfaces (virConnectPtr conn, char **const names, int maxnames)
+{
+ int rv = -1;
+ int i;
+ remote_list_interfaces_args args;
+ remote_list_interfaces_ret ret;
+ struct private_data *priv = conn->interfacePrivateData;
+
+ remoteDriverLock(priv);
+
+ if (maxnames > REMOTE_INTERFACE_NAME_LIST_MAX) {
+ errorf (conn, VIR_ERR_RPC,
+ _("too many remote interfaces: %d > %d"),
+ maxnames, REMOTE_INTERFACE_NAME_LIST_MAX);
+ goto done;
+ }
+ args.maxnames = maxnames;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_LIST_INTERFACES,
+ (xdrproc_t) xdr_remote_list_interfaces_args, (char *) &args,
+ (xdrproc_t) xdr_remote_list_interfaces_ret, (char *) &ret) == -1)
+ goto done;
+
+ if (ret.names.names_len > maxnames) {
+ errorf (conn, VIR_ERR_RPC,
+ _("too many remote interfaces: %d > %d"),
+ ret.names.names_len, maxnames);
+ goto cleanup;
+ }
+
+ /* 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]);
+
+ rv = ret.names.names_len;
+
+cleanup:
+ xdr_free ((xdrproc_t) xdr_remote_list_interfaces_ret, (char *) &ret);
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+static virInterfacePtr
+remoteInterfaceLookupByName (virConnectPtr conn,
+ const char *name)
+{
+ virInterfacePtr interface = NULL;
+ remote_interface_lookup_by_name_args args;
+ remote_interface_lookup_by_name_ret ret;
+ struct private_data *priv = conn->interfacePrivateData;
+
+ remoteDriverLock(priv);
+
+ args.name = (char *) name;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_INTERFACE_LOOKUP_BY_NAME,
+ (xdrproc_t) xdr_remote_interface_lookup_by_name_args, (char *) &args,
+ (xdrproc_t) xdr_remote_interface_lookup_by_name_ret, (char *) &ret) ==
-1)
+ goto done;
+
+ interface = get_nonnull_interface (conn, ret.interface);
+ xdr_free ((xdrproc_t) &xdr_remote_interface_lookup_by_name_ret, (char *)
&ret);
+
+done:
+ remoteDriverUnlock(priv);
+ return interface;
+}
+
+static virInterfacePtr
+remoteInterfaceLookupByMAC (virConnectPtr conn,
+ const unsigned char *mac)
+{
+ virInterfacePtr interface = NULL;
+ remote_interface_lookup_by_mac_args args;
+ remote_interface_lookup_by_mac_ret ret;
+ struct private_data *priv = conn->interfacePrivateData;
+
+ remoteDriverLock(priv);
+
+ memcpy (args.mac, mac, VIR_MAC_BUFLEN);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_INTERFACE_LOOKUP_BY_MAC,
+ (xdrproc_t) xdr_remote_interface_lookup_by_mac_args, (char *) &args,
+ (xdrproc_t) xdr_remote_interface_lookup_by_mac_ret, (char *) &ret) ==
-1)
+ goto done;
+
+ interface = get_nonnull_interface (conn, ret.interface);
+ xdr_free ((xdrproc_t) &xdr_remote_interface_lookup_by_mac_ret, (char *)
&ret);
+
+done:
+ remoteDriverUnlock(priv);
+ return interface;
+}
+
+static char *
+remoteInterfaceGetXMLDesc (virInterfacePtr interface,
+ int flags)
+{
+ char *rv = NULL;
+ remote_interface_get_xml_desc_args args;
+ remote_interface_get_xml_desc_ret ret;
+ struct private_data *priv = interface->conn->interfacePrivateData;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_interface (&args.interface, interface);
+ args.flags = flags;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (interface->conn, priv, 0, REMOTE_PROC_INTERFACE_GET_XML_DESC,
+ (xdrproc_t) xdr_remote_interface_get_xml_desc_args, (char *) &args,
+ (xdrproc_t) xdr_remote_interface_get_xml_desc_ret, (char *) &ret) ==
-1)
+ goto done;
+
+ /* Caller frees. */
+ rv = ret.xml;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+static virInterfacePtr
+remoteInterfaceDefineXML (virConnectPtr conn,
+ const char *xmlDesc,
+ int flags)
+{
+ virInterfacePtr interface = NULL;
+ remote_interface_define_xml_args args;
+ remote_interface_define_xml_ret ret;
+ struct private_data *priv = conn->interfacePrivateData;
+
+ remoteDriverLock(priv);
+
+ args.xml = (char *) xmlDesc;
+ args.flags = flags;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_INTERFACE_DEFINE_XML,
+ (xdrproc_t) xdr_remote_interface_define_xml_args, (char *) &args,
+ (xdrproc_t) xdr_remote_interface_define_xml_ret, (char *) &ret) == -1)
+ goto done;
+
+ interface = get_nonnull_interface (conn, ret.interface);
+ xdr_free ((xdrproc_t) &xdr_remote_interface_define_xml_ret, (char *) &ret);
+
+done:
+ remoteDriverUnlock(priv);
+ return interface;
+}
+
+static int
+remoteInterfaceUndefine (virInterfacePtr interface)
+{
+ int rv = -1;
+ remote_interface_undefine_args args;
+ struct private_data *priv = interface->conn->interfacePrivateData;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_interface (&args.interface, interface);
+
+ if (call (interface->conn, priv, 0, REMOTE_PROC_INTERFACE_UNDEFINE,
+ (xdrproc_t) xdr_remote_interface_undefine_args, (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ goto done;
+
+ rv = 0;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+static int
+remoteInterfaceCreate (virInterfacePtr interface,
+ int flags)
+{
+ int rv = -1;
+ remote_interface_create_args args;
+ struct private_data *priv = interface->conn->interfacePrivateData;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_interface (&args.interface, interface);
+ args.flags = flags;
+
+ if (call (interface->conn, priv, 0, REMOTE_PROC_INTERFACE_CREATE,
+ (xdrproc_t) xdr_remote_interface_create_args, (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ goto done;
+
+ rv = 0;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+static int
+remoteInterfaceDestroy (virInterfacePtr interface,
+ int flags)
+{
+ int rv = -1;
+ remote_interface_destroy_args args;
+ struct private_data *priv = interface->conn->interfacePrivateData;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_interface (&args.interface, interface);
+ args.flags = flags;
+
+ if (call (interface->conn, priv, 0, REMOTE_PROC_INTERFACE_DESTROY,
+ (xdrproc_t) xdr_remote_interface_destroy_args, (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ goto done;
+
+ rv = 0;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+/*----------------------------------------------------------------------*/
+
+static virDrvOpenStatus
remoteStorageOpen (virConnectPtr conn,
virConnectAuthPtr auth,
int flags)
@@ -6851,6 +7172,12 @@ get_nonnull_network (virConnectPtr conn, remote_nonnull_network
network)
return virGetNetwork (conn, network.name, BAD_CAST network.uuid);
}
+static virInterfacePtr
+get_nonnull_interface (virConnectPtr conn, remote_nonnull_interface interface)
+{
+ return virGetInterface (conn, interface.name, BAD_CAST interface.mac);
+}
+
static virStoragePoolPtr
get_nonnull_storage_pool (virConnectPtr conn, remote_nonnull_storage_pool pool)
{
@@ -6886,6 +7213,14 @@ make_nonnull_network (remote_nonnull_network *net_dst,
virNetworkPtr net_src)
}
static void
+make_nonnull_interface (remote_nonnull_interface *interface_dst,
+ virInterfacePtr interface_src)
+{
+ interface_dst->name = interface_src->name;
+ memcpy (interface_dst->mac, interface_src->mac, VIR_MAC_BUFLEN);
+}
+
+static void
make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr
pool_src)
{
pool_dst->name = pool_src->name;
@@ -6996,6 +7331,21 @@ static virNetworkDriver network_driver = {
.networkSetAutostart = remoteNetworkSetAutostart,
};
+static virInterfaceDriver interface_driver = {
+ .name = "remote",
+ .open = remoteInterfaceOpen,
+ .close = remoteInterfaceClose,
+ .numOfInterfaces = remoteNumOfInterfaces,
+ .listInterfaces = remoteListInterfaces,
+ .interfaceLookupByName = remoteInterfaceLookupByName,
+ .interfaceLookupByMAC = remoteInterfaceLookupByMAC,
+ .interfaceGetXMLDesc = remoteInterfaceGetXMLDesc,
+ .interfaceDefineXML = remoteInterfaceDefineXML,
+ .interfaceUndefine = remoteInterfaceUndefine,
+ .interfaceCreate = remoteInterfaceCreate,
+ .interfaceDestroy = remoteInterfaceDestroy,
+};
+
static virStorageDriver storage_driver = {
.name = "remote",
.open = remoteStorageOpen,
@@ -7067,6 +7417,7 @@ remoteRegister (void)
{
if (virRegisterDriver (&driver) == -1) return -1;
if (virRegisterNetworkDriver (&network_driver) == -1) return -1;
+ if (virRegisterInterfaceDriver (&interface_driver) == -1) return -1;
if (virRegisterStorageDriver (&storage_driver) == -1) return -1;
if (virRegisterDeviceMonitor (&dev_monitor) == -1) return -1;
#ifdef WITH_LIBVIRTD
--
1.6.0.6