diff --git a/qemud/remote.c b/qemud/remote.c index 39f6487890..651e9fbfc1 100644 --- a/qemud/remote.c +++ b/qemud/remote.c @@ -2356,6 +2356,57 @@ remoteDispatchListInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED, return 0; } +static int +remoteDispatchNumOfDefinedInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_error *rerr, + void *args ATTRIBUTE_UNUSED, + remote_num_of_defined_interfaces_ret *ret) +{ + + ret->num = virConnectNumOfDefinedInterfaces (conn); + if (ret->num == -1) { + remoteDispatchConnError(rerr, conn); + return -1; + } + + return 0; +} + +static int +remoteDispatchListDefinedInterfaces (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_error *rerr, + remote_list_defined_interfaces_args *args, + remote_list_defined_interfaces_ret *ret) +{ + + if (args->maxnames > REMOTE_DEFINED_INTERFACE_NAME_LIST_MAX) { + remoteDispatchFormatError (rerr, + "%s", _("maxnames > REMOTE_DEFINED_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 = + virConnectListDefinedInterfaces (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, diff --git a/qemud/remote_dispatch_args.h b/qemud/remote_dispatch_args.h index 1322a5456b..9dacfb80b5 100644 --- a/qemud/remote_dispatch_args.h +++ b/qemud/remote_dispatch_args.h @@ -116,3 +116,4 @@ remote_interface_destroy_args val_remote_interface_destroy_args; remote_domain_xml_from_native_args val_remote_domain_xml_from_native_args; remote_domain_xml_to_native_args val_remote_domain_xml_to_native_args; + remote_list_defined_interfaces_args val_remote_list_defined_interfaces_args; diff --git a/qemud/remote_dispatch_prototypes.h b/qemud/remote_dispatch_prototypes.h index aa9c3fc739..d9f6aad19e 100644 --- a/qemud/remote_dispatch_prototypes.h +++ b/qemud/remote_dispatch_prototypes.h @@ -471,6 +471,13 @@ static int remoteDispatchListDefinedDomains( remote_error *err, remote_list_defined_domains_args *args, remote_list_defined_domains_ret *ret); +static int remoteDispatchListDefinedInterfaces( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + remote_list_defined_interfaces_args *args, + remote_list_defined_interfaces_ret *ret); static int remoteDispatchListDefinedNetworks( struct qemud_server *server, struct qemud_client *client, @@ -709,6 +716,13 @@ static int remoteDispatchNumOfDefinedDomains( remote_error *err, void *args, remote_num_of_defined_domains_ret *ret); +static int remoteDispatchNumOfDefinedInterfaces( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + void *args, + remote_num_of_defined_interfaces_ret *ret); static int remoteDispatchNumOfDefinedNetworks( struct qemud_server *server, struct qemud_client *client, diff --git a/qemud/remote_dispatch_ret.h b/qemud/remote_dispatch_ret.h index fb4a86e7b9..5376960f9a 100644 --- a/qemud/remote_dispatch_ret.h +++ b/qemud/remote_dispatch_ret.h @@ -97,3 +97,5 @@ remote_interface_define_xml_ret val_remote_interface_define_xml_ret; remote_domain_xml_from_native_ret val_remote_domain_xml_from_native_ret; remote_domain_xml_to_native_ret val_remote_domain_xml_to_native_ret; + remote_num_of_defined_interfaces_ret val_remote_num_of_defined_interfaces_ret; + remote_list_defined_interfaces_ret val_remote_list_defined_interfaces_ret; diff --git a/qemud/remote_dispatch_table.h b/qemud/remote_dispatch_table.h index f3a0b109ff..449786d4f6 100644 --- a/qemud/remote_dispatch_table.h +++ b/qemud/remote_dispatch_table.h @@ -687,3 +687,13 @@ .args_filter = (xdrproc_t) xdr_remote_domain_xml_to_native_args, .ret_filter = (xdrproc_t) xdr_remote_domain_xml_to_native_ret, }, +{ /* NumOfDefinedInterfaces => 137 */ + .fn = (dispatch_fn) remoteDispatchNumOfDefinedInterfaces, + .args_filter = (xdrproc_t) xdr_void, + .ret_filter = (xdrproc_t) xdr_remote_num_of_defined_interfaces_ret, +}, +{ /* ListDefinedInterfaces => 138 */ + .fn = (dispatch_fn) remoteDispatchListDefinedInterfaces, + .args_filter = (xdrproc_t) xdr_remote_list_defined_interfaces_args, + .ret_filter = (xdrproc_t) xdr_remote_list_defined_interfaces_ret, +}, diff --git a/qemud/remote_protocol.c b/qemud/remote_protocol.c index 65f9a73c0e..7b460966a4 100644 --- a/qemud/remote_protocol.c +++ b/qemud/remote_protocol.c @@ -1517,6 +1517,35 @@ xdr_remote_list_interfaces_ret (XDR *xdrs, remote_list_interfaces_ret *objp) return TRUE; } +bool_t +xdr_remote_num_of_defined_interfaces_ret (XDR *xdrs, remote_num_of_defined_interfaces_ret *objp) +{ + + if (!xdr_int (xdrs, &objp->num)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_list_defined_interfaces_args (XDR *xdrs, remote_list_defined_interfaces_args *objp) +{ + + if (!xdr_int (xdrs, &objp->maxnames)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_list_defined_interfaces_ret (XDR *xdrs, remote_list_defined_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_DEFINED_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) { diff --git a/qemud/remote_protocol.h b/qemud/remote_protocol.h index dae304e544..2e5bc81d5f 100644 --- a/qemud/remote_protocol.h +++ b/qemud/remote_protocol.h @@ -29,6 +29,7 @@ typedef remote_nonnull_string *remote_string; #define REMOTE_MIGRATE_COOKIE_MAX 256 #define REMOTE_NETWORK_NAME_LIST_MAX 256 #define REMOTE_INTERFACE_NAME_LIST_MAX 256 +#define REMOTE_DEFINED_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 @@ -847,6 +848,24 @@ struct remote_list_interfaces_ret { }; typedef struct remote_list_interfaces_ret remote_list_interfaces_ret; +struct remote_num_of_defined_interfaces_ret { + int num; +}; +typedef struct remote_num_of_defined_interfaces_ret remote_num_of_defined_interfaces_ret; + +struct remote_list_defined_interfaces_args { + int maxnames; +}; +typedef struct remote_list_defined_interfaces_args remote_list_defined_interfaces_args; + +struct remote_list_defined_interfaces_ret { + struct { + u_int names_len; + remote_nonnull_string *names_val; + } names; +}; +typedef struct remote_list_defined_interfaces_ret remote_list_defined_interfaces_ret; + struct remote_interface_lookup_by_name_args { remote_nonnull_string name; }; @@ -1548,6 +1567,8 @@ enum remote_procedure { REMOTE_PROC_INTERFACE_DESTROY = 134, REMOTE_PROC_DOMAIN_XML_FROM_NATIVE = 135, REMOTE_PROC_DOMAIN_XML_TO_NATIVE = 136, + REMOTE_PROC_NUM_OF_DEFINED_INTERFACES = 137, + REMOTE_PROC_LIST_DEFINED_INTERFACES = 138, }; typedef enum remote_procedure remote_procedure; @@ -1710,6 +1731,9 @@ extern bool_t xdr_remote_network_set_autostart_args (XDR *, remote_network_set_ 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_num_of_defined_interfaces_ret (XDR *, remote_num_of_defined_interfaces_ret*); +extern bool_t xdr_remote_list_defined_interfaces_args (XDR *, remote_list_defined_interfaces_args*); +extern bool_t xdr_remote_list_defined_interfaces_ret (XDR *, remote_list_defined_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*); @@ -1945,6 +1969,9 @@ 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_num_of_defined_interfaces_ret (); +extern bool_t xdr_remote_list_defined_interfaces_args (); +extern bool_t xdr_remote_list_defined_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 (); diff --git a/qemud/remote_protocol.x b/qemud/remote_protocol.x index 9e75c59ef9..8f9b6dbd74 100644 --- a/qemud/remote_protocol.x +++ b/qemud/remote_protocol.x @@ -82,6 +82,9 @@ 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 defined interface names. */ +const REMOTE_DEFINED_INTERFACE_NAME_LIST_MAX = 256; + /* Upper limit on lists of storage pool names. */ const REMOTE_STORAGE_POOL_NAME_LIST_MAX = 256; @@ -793,6 +796,18 @@ struct remote_list_interfaces_ret { remote_nonnull_string names; }; +struct remote_num_of_defined_interfaces_ret { + int num; +}; + +struct remote_list_defined_interfaces_args { + int maxnames; +}; + +struct remote_list_defined_interfaces_ret { + remote_nonnull_string names; +}; + struct remote_interface_lookup_by_name_args { remote_nonnull_string name; }; @@ -1406,7 +1421,10 @@ enum remote_procedure { REMOTE_PROC_INTERFACE_CREATE = 133, REMOTE_PROC_INTERFACE_DESTROY = 134, REMOTE_PROC_DOMAIN_XML_FROM_NATIVE = 135, - REMOTE_PROC_DOMAIN_XML_TO_NATIVE = 136 + REMOTE_PROC_DOMAIN_XML_TO_NATIVE = 136, + + REMOTE_PROC_NUM_OF_DEFINED_INTERFACES = 137, + REMOTE_PROC_LIST_DEFINED_INTERFACES = 138 }; diff --git a/src/driver.h b/src/driver.h index ca759ff035..2502c63e56 100644 --- a/src/driver.h +++ b/src/driver.h @@ -508,6 +508,12 @@ typedef int (*virDrvListInterfaces) (virConnectPtr conn, char **const names, int maxnames); +typedef int + (*virDrvNumOfDefinedInterfaces) (virConnectPtr conn); +typedef int + (*virDrvListDefinedInterfaces) (virConnectPtr conn, + char **const names, + int maxnames); typedef virInterfacePtr (*virDrvInterfaceLookupByName) (virConnectPtr conn, const char *name); @@ -551,6 +557,8 @@ struct _virInterfaceDriver { virDrvClose close; virDrvNumOfInterfaces numOfInterfaces; virDrvListInterfaces listInterfaces; + virDrvNumOfDefinedInterfaces numOfDefinedInterfaces; + virDrvListDefinedInterfaces listDefinedInterfaces; virDrvInterfaceLookupByName interfaceLookupByName; virDrvInterfaceLookupByMACString interfaceLookupByMACString; virDrvInterfaceGetXMLDesc interfaceGetXMLDesc; diff --git a/src/libvirt.c b/src/libvirt.c index cb39636e8f..f4a7fa72eb 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -5533,9 +5533,9 @@ virInterfaceGetConnect (virInterfacePtr iface) * virConnectNumOfInterfaces: * @conn: pointer to the hypervisor connection * - * Provides the number of interfaces on the physical host. + * Provides the number of active interfaces on the physical host. * - * Returns the number of interface found or -1 in case of error + * Returns the number of active interfaces found or -1 in case of error */ int virConnectNumOfInterfaces(virConnectPtr conn) @@ -5571,7 +5571,8 @@ error: * @names: array to collect the list of names of interfaces * @maxnames: size of @names * - * Collect the list of physical host interfaces, and store their names in @names + * Collect the list of active physical host interfaces, + * and store their names in @names * * Returns the number of interfaces found or -1 in case of error */ @@ -5608,6 +5609,88 @@ error: return -1; } +/** + * virConnectNumOfDefinedInterfaces: + * @conn: pointer to the hypervisor connection + * + * Provides the number of defined (inactive) interfaces on the physical host. + * + * Returns the number of defined interface found or -1 in case of error + */ +int +virConnectNumOfDefinedInterfaces(virConnectPtr conn) +{ + DEBUG("conn=%p", conn); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return (-1); + } + + if (conn->interfaceDriver && conn->interfaceDriver->numOfDefinedInterfaces) { + int ret; + ret = conn->interfaceDriver->numOfDefinedInterfaces (conn); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(conn); + return -1; +} + +/** + * virConnectListDefinedInterfaces: + * @conn: pointer to the hypervisor connection + * @names: array to collect the list of names of interfaces + * @maxnames: size of @names + * + * Collect the list of defined (inactive) physical host interfaces, + * and store their names in @names. + * + * Returns the number of interfaces found or -1 in case of error + */ +int +virConnectListDefinedInterfaces(virConnectPtr conn, + char **const names, + int maxnames) +{ + DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return (-1); + } + + if ((names == NULL) || (maxnames < 0)) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (conn->interfaceDriver && conn->interfaceDriver->listDefinedInterfaces) { + int ret; + ret = conn->interfaceDriver->listDefinedInterfaces (conn, names, maxnames); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(conn); + return -1; +} + /** * virInterfaceLookupByName: * @conn: pointer to the hypervisor connection diff --git a/src/remote_internal.c b/src/remote_internal.c index 61a2cc4788..f20ed6ef3d 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -3897,6 +3897,78 @@ done: return rv; } +static int +remoteNumOfDefinedInterfaces (virConnectPtr conn) +{ + int rv = -1; + remote_num_of_defined_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_DEFINED_INTERFACES, + (xdrproc_t) xdr_void, (char *) NULL, + (xdrproc_t) xdr_remote_num_of_defined_interfaces_ret, (char *) &ret) == -1) + goto done; + + rv = ret.num; + +done: + remoteDriverUnlock(priv); + return rv; +} + +static int +remoteListDefinedInterfaces (virConnectPtr conn, char **const names, int maxnames) +{ + int rv = -1; + int i; + remote_list_defined_interfaces_args args; + remote_list_defined_interfaces_ret ret; + struct private_data *priv = conn->interfacePrivateData; + + remoteDriverLock(priv); + + if (maxnames > REMOTE_DEFINED_INTERFACE_NAME_LIST_MAX) { + errorf (conn, VIR_ERR_RPC, + _("too many remote interfaces: %d > %d"), + maxnames, REMOTE_DEFINED_INTERFACE_NAME_LIST_MAX); + goto done; + } + args.maxnames = maxnames; + + memset (&ret, 0, sizeof ret); + if (call (conn, priv, 0, REMOTE_PROC_LIST_DEFINED_INTERFACES, + (xdrproc_t) xdr_remote_list_defined_interfaces_args, (char *) &args, + (xdrproc_t) xdr_remote_list_defined_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_defined_interfaces_ret, (char *) &ret); + +done: + remoteDriverUnlock(priv); + return rv; +} + static virInterfacePtr remoteInterfaceLookupByName (virConnectPtr conn, const char *name) @@ -7440,6 +7512,8 @@ static virInterfaceDriver interface_driver = { .close = remoteInterfaceClose, .numOfInterfaces = remoteNumOfInterfaces, .listInterfaces = remoteListInterfaces, + .numOfDefinedInterfaces = remoteNumOfDefinedInterfaces, + .listDefinedInterfaces = remoteListDefinedInterfaces, .interfaceLookupByName = remoteInterfaceLookupByName, .interfaceLookupByMACString = remoteInterfaceLookupByMACString, .interfaceGetXMLDesc = remoteInterfaceGetXMLDesc,