[libvirt] [PATCH 3/5] Implement RPC part of interface config API.

Daniel P. Berrange berrange at redhat.com
Wed May 20 12:04:13 UTC 2009


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 :|




More information about the libvir-list mailing list