On Tue, May 19, 2009 at 12:51:25PM -0400, Laine Stump wrote: > --- > 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 | 45 +++++ > qemud/remote_protocol.c | 147 +++++++++++++++ > qemud/remote_protocol.h | 123 +++++++++++++ > qemud/remote_protocol.x | 86 +++++++++- > src/datatypes.c | 160 ++++++++++++++++ > src/datatypes.h | 6 + > src/libvirt.c | 10 - > src/remote_internal.c | 352 ++++++++++++++++++++++++++++++++++++ > 12 files changed, 1230 insertions(+), 11 deletions(-) > > diff --git a/qemud/remote.c b/qemud/remote.c > index a92dea9..4881fc2 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 > +remoteDispatchInterfaceLookupByMacString (struct qemud_server *server ATTRIBUTE_UNUSED, > + struct qemud_client *client ATTRIBUTE_UNUSED, > + virConnectPtr conn, > + remote_error *rerr, > + remote_interface_lookup_by_mac_string_args *args, > + remote_interface_lookup_by_mac_string_ret *ret) > +{ > + virInterfacePtr interface; > + > + interface = virInterfaceLookupByMACString (conn, 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, > @@ -4561,6 +4782,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, interface.mac); > +} > + > static virStoragePoolPtr > get_nonnull_storage_pool (virConnectPtr conn, remote_nonnull_storage_pool pool) > { > @@ -4592,6 +4819,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); > + interface_dst->mac = strdup (interface_src->mac); > +} > + > +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 8f8b05b..27b840f 100644 > --- a/qemud/remote_dispatch_args.h > +++ b/qemud/remote_dispatch_args.h > @@ -106,3 +106,11 @@ > 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_storage_vol_create_xml_from_args val_remote_storage_vol_create_xml_from_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_string_args val_remote_interface_lookup_by_mac_string_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 1a2d98b..9918aee 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 remoteDispatchInterfaceLookupByMacString( > + struct qemud_server *server, > + struct qemud_client *client, > + virConnectPtr conn, > + remote_error *err, > + remote_interface_lookup_by_mac_string_args *args, > + remote_interface_lookup_by_mac_string_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 75e2ca6..4502182 100644 > --- a/qemud/remote_dispatch_ret.h > +++ b/qemud/remote_dispatch_ret.h > @@ -90,3 +90,9 @@ > 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_storage_vol_create_xml_from_ret val_remote_storage_vol_create_xml_from_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_string_ret val_remote_interface_lookup_by_mac_string_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 e601a6c..92e0d40 100644 > --- a/qemud/remote_dispatch_table.h > +++ b/qemud/remote_dispatch_table.h > @@ -632,3 +632,48 @@ > .args_filter = (xdrproc_t) xdr_remote_storage_vol_create_xml_from_args, > .ret_filter = (xdrproc_t) xdr_remote_storage_vol_create_xml_from_ret, > }, > +{ /* 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, > +}, > +{ /* InterfaceLookupByMacString => 129 */ > + .fn = (dispatch_fn) remoteDispatchInterfaceLookupByMacString, > + .args_filter = (xdrproc_t) xdr_remote_interface_lookup_by_mac_string_args, > + .ret_filter = (xdrproc_t) xdr_remote_interface_lookup_by_mac_string_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 e9b84aa..a15db31 100644 > --- a/qemud/remote_protocol.c > +++ b/qemud/remote_protocol.c > @@ -60,6 +60,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_nonnull_string (xdrs, &objp->mac)) > + return FALSE; > + return TRUE; > +} > + > +bool_t > xdr_remote_nonnull_storage_pool (XDR *xdrs, remote_nonnull_storage_pool *objp) > { > > @@ -1478,6 +1489,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_string_args (XDR *xdrs, remote_interface_lookup_by_mac_string_args *objp) > +{ > + > + if (!xdr_remote_nonnull_string (xdrs, &objp->mac)) > + return FALSE; > + return TRUE; > +} > + > +bool_t > +xdr_remote_interface_lookup_by_mac_string_ret (XDR *xdrs, remote_interface_lookup_by_mac_string_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_u_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_u_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_u_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_u_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 9ee17a9..280cba6 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 > @@ -57,6 +58,12 @@ struct remote_nonnull_network { > }; > typedef struct remote_nonnull_network remote_nonnull_network; > > +struct remote_nonnull_interface { > + remote_nonnull_string name; > + remote_nonnull_string mac; > +}; > +typedef struct remote_nonnull_interface remote_nonnull_interface; > + > struct remote_nonnull_storage_pool { > remote_nonnull_string name; > remote_uuid uuid; > @@ -822,6 +829,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_string_args { > + remote_nonnull_string mac; > +}; > +typedef struct remote_interface_lookup_by_mac_string_args remote_interface_lookup_by_mac_string_args; > + > +struct remote_interface_lookup_by_mac_string_ret { > + remote_nonnull_interface interface; > +}; > +typedef struct remote_interface_lookup_by_mac_string_ret remote_interface_lookup_by_mac_string_ret; > + > +struct remote_interface_get_xml_desc_args { > + remote_nonnull_interface interface; > + u_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; > + u_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; > + u_int flags; > +}; > +typedef struct remote_interface_create_args remote_interface_create_args; > + > +struct remote_interface_destroy_args { > + remote_nonnull_interface interface; > + u_int flags; > +}; > +typedef struct remote_interface_destroy_args remote_interface_destroy_args; > + > struct remote_auth_list_ret { > struct { > u_int types_len; > @@ -1429,6 +1513,15 @@ enum remote_procedure { > REMOTE_PROC_NODE_DEVICE_CREATE_XML = 123, > REMOTE_PROC_NODE_DEVICE_DESTROY = 124, > REMOTE_PROC_STORAGE_VOL_CREATE_XML_FROM = 125, > + REMOTE_PROC_NUM_OF_INTERFACES = 126, > + REMOTE_PROC_LIST_INTERFACES = 127, > + REMOTE_PROC_INTERFACE_LOOKUP_BY_NAME = 128, > + REMOTE_PROC_INTERFACE_LOOKUP_BY_MAC_STRING = 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; > > @@ -1464,6 +1557,7 @@ extern bool_t xdr_remote_string (XDR *, remote_string*); > extern bool_t xdr_remote_uuid (XDR *, remote_uuid); > 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*); > @@ -1587,6 +1681,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_string_args (XDR *, remote_interface_lookup_by_mac_string_args*); > +extern bool_t xdr_remote_interface_lookup_by_mac_string_ret (XDR *, remote_interface_lookup_by_mac_string_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*); > @@ -1680,6 +1788,7 @@ extern bool_t xdr_remote_string (); > extern bool_t xdr_remote_uuid (); > 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 (); > @@ -1803,6 +1912,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_string_args (); > +extern bool_t xdr_remote_interface_lookup_by_mac_string_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 1f27350..0bd7e6f 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; > > @@ -146,6 +149,12 @@ struct remote_nonnull_network { > remote_uuid uuid; > }; > > +/* An interface which may not be NULL. */ > +struct remote_nonnull_interface { > + remote_nonnull_string name; > + remote_nonnull_string mac; > +}; > + > /* A storage pool which may not be NULL. */ > struct remote_nonnull_storage_pool { > remote_nonnull_string name; > @@ -770,6 +779,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_string_args { > + remote_nonnull_string mac; > +}; > + > +struct remote_interface_lookup_by_mac_string_ret { > + remote_nonnull_interface interface; > +}; > + > +struct remote_interface_get_xml_desc_args { > + remote_nonnull_interface interface; > + unsigned int flags; > +}; > + > +struct remote_interface_get_xml_desc_ret { > + remote_nonnull_string xml; > +}; > + > +struct remote_interface_define_xml_args { > + remote_nonnull_string xml; > + unsigned 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; > + unsigned int flags; > +}; > + > +struct remote_interface_destroy_args { > + remote_nonnull_interface interface; > + unsigned int flags; > +}; > + > + > +/* Auth calls: */ > + > struct remote_auth_list_ret { > remote_auth_type types<REMOTE_AUTH_TYPE_LIST_MAX>; > }; > @@ -1299,7 +1373,17 @@ enum remote_procedure { > REMOTE_PROC_NODE_DEVICE_CREATE_XML = 123, > REMOTE_PROC_NODE_DEVICE_DESTROY = 124, > > - REMOTE_PROC_STORAGE_VOL_CREATE_XML_FROM = 125 > + REMOTE_PROC_STORAGE_VOL_CREATE_XML_FROM = 125, > + > + REMOTE_PROC_NUM_OF_INTERFACES = 126, > + REMOTE_PROC_LIST_INTERFACES = 127, > + REMOTE_PROC_INTERFACE_LOOKUP_BY_NAME = 128, > + REMOTE_PROC_INTERFACE_LOOKUP_BY_MAC_STRING = 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 eceb839..e1227aa 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,144 @@ 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 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->mac = strdup(mac); > + if (ret->mac == NULL) { > + virReportOOMError(conn); > + goto error; > + } > + > + ret->magic = VIR_INTERFACE_MAGIC; > + ret->conn = conn; > + > + 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->mac); > + 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->mac); > + 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 756e0a5..a83777a 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 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 f63a47b..97b92d0 100644 > --- a/src/libvirt.c > +++ b/src/libvirt.c > @@ -5870,18 +5870,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 1ca7784..513ff17 100644 > --- a/src/remote_internal.c > +++ b/src/remote_internal.c > @@ -1,3 +1,4 @@ > + > /* > * remote_internal.c: driver to provide access to libvirtd running > * on a remote machine > @@ -211,11 +212,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); > @@ -3675,6 +3678,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 > +remoteInterfaceLookupByMACString (virConnectPtr conn, > + const char *mac) > +{ > + virInterfacePtr interface = NULL; > + remote_interface_lookup_by_mac_string_args args; > + remote_interface_lookup_by_mac_string_ret ret; > + struct private_data *priv = conn->interfacePrivateData; > + > + remoteDriverLock(priv); > + > + args.mac = (char *) mac; > + > + memset (&ret, 0, sizeof ret); > + if (call (conn, priv, 0, REMOTE_PROC_INTERFACE_LOOKUP_BY_MAC_STRING, > + (xdrproc_t) xdr_remote_interface_lookup_by_mac_string_args, (char *) &args, > + (xdrproc_t) xdr_remote_interface_lookup_by_mac_string_ret, (char *) &ret) == -1) > + goto done; > + > + interface = get_nonnull_interface (conn, ret.interface); > + xdr_free ((xdrproc_t) &xdr_remote_interface_lookup_by_mac_string_ret, (char *) &ret); > + > +done: > + remoteDriverUnlock(priv); > + return interface; > +} > + > +static char * > +remoteInterfaceGetXMLDesc (virInterfacePtr interface, > + unsigned 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, > + unsigned 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, > + unsigned 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, > + unsigned 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) > @@ -6874,6 +7196,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, interface.mac); > +} > + > static virStoragePoolPtr > get_nonnull_storage_pool (virConnectPtr conn, remote_nonnull_storage_pool pool) > { > @@ -6909,6 +7237,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; > + interface_dst->mac = interface_src->mac; > +} > + > +static void > make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr pool_src) > { > pool_dst->name = pool_src->name; > @@ -7019,6 +7355,21 @@ static virNetworkDriver network_driver = { > .networkSetAutostart = remoteNetworkSetAutostart, > }; > > +static virInterfaceDriver interface_driver = { > + .name = "remote", > + .open = remoteInterfaceOpen, > + .close = remoteInterfaceClose, > + .numOfInterfaces = remoteNumOfInterfaces, > + .listInterfaces = remoteListInterfaces, > + .interfaceLookupByName = remoteInterfaceLookupByName, > + .interfaceLookupByMACString = remoteInterfaceLookupByMACString, > + .interfaceGetXMLDesc = remoteInterfaceGetXMLDesc, > + .interfaceDefineXML = remoteInterfaceDefineXML, > + .interfaceUndefine = remoteInterfaceUndefine, > + .interfaceCreate = remoteInterfaceCreate, > + .interfaceDestroy = remoteInterfaceDestroy, > +}; > + > static virStorageDriver storage_driver = { > .name = "remote", > .open = remoteStorageOpen, > @@ -7091,6 +7442,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 ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list