--- 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 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list