[libvirt] [libvirt-designer PATCHv3 7/9] Implement gvir_designer_domain_add_usb_redir()

Michal Privoznik mprivozn at redhat.com
Tue Jun 4 17:11:05 UTC 2013


On 04.06.2013 16:33, Christophe Fergeau wrote:
> This will add an USB redirection channel to the VM. This can
> be called multiple times to redirect several USB devices at once.
> This will also adds the needed controllers if they are not already

s/adds/add/

> present in the VM.
> The current code has 2 shortcomings:
> - USB redirection is only supported with SPICE, but this is not
>   checked for
> - the USB controller added to the VM are hardcoded, no check if they
>   are supported by the OS, hypervisor, ...
> ---
>  examples/virtxml.c                         |   5 ++
>  libvirt-designer/libvirt-designer-domain.c | 117 +++++++++++++++++++++++++++++
>  libvirt-designer/libvirt-designer-domain.h |   1 +
>  libvirt-designer/libvirt-designer.sym      |   2 +
>  4 files changed, 125 insertions(+)
> 
> diff --git a/examples/virtxml.c b/examples/virtxml.c
> index 46fb551..bd3bfb3 100644
> --- a/examples/virtxml.c
> +++ b/examples/virtxml.c
> @@ -566,6 +566,7 @@ main(int argc, char *argv[])
>      static char *resources_str = NULL;
>      GVirDesignerDomainResources resources;
>      GOptionContext *context = NULL;
> +    unsigned int i;
>  
>      static GOptionEntry entries[] =
>      {
> @@ -645,6 +646,10 @@ main(int argc, char *argv[])
>                                                       GVIR_DESIGNER_DOMAIN_GRAPHICS_SPICE,
>                                                       &error));
>      CHECK_ERROR;
> +    for (i = 0; i < 4; i++) {
> +        g_object_unref(gvir_designer_domain_add_usb_redir(domain, &error));
> +        CHECK_ERROR;
> +    }

Why 4 times? Moreover, I'd rather see this as optional.

>  
>      g_object_unref(gvir_designer_domain_add_sound(domain, &error));
>      CHECK_ERROR;
> diff --git a/libvirt-designer/libvirt-designer-domain.c b/libvirt-designer/libvirt-designer-domain.c
> index 7466ee9..ae816e0 100644
> --- a/libvirt-designer/libvirt-designer-domain.c
> +++ b/libvirt-designer/libvirt-designer-domain.c
> @@ -580,6 +580,123 @@ gvir_designer_domain_add_graphics(GVirDesignerDomain *design,
>  }
>  
>  
> +static gboolean
> +gvir_designer_domain_supports_usb(GVirDesignerDomain *design)
> +{
> +    GList *devices;
> +    devices = gvir_designer_domain_get_device_by_type(design,
> +                                                      GVIR_CONFIG_TYPE_DOMAIN_CONTROLLER_USB);
> +    g_list_free_full(devices, g_object_unref);
> +
> +    return (devices != NULL);
> +}
> +
> +
> +static GVirConfigDomainControllerUsb *
> +gvir_designer_domain_create_usb_controller(GVirDesignerDomain *design,
> +                                           GVirConfigDomainControllerUsbModel model,
> +                                           guint indx,
> +                                           GVirConfigDomainControllerUsb *master,
> +                                           guint start_port)
> +{
> +    GVirConfigDomainControllerUsb *controller;
> +
> +    controller = gvir_config_domain_controller_usb_new();
> +    gvir_config_domain_controller_usb_set_model(controller, model);
> +    gvir_config_domain_controller_set_index(GVIR_CONFIG_DOMAIN_CONTROLLER(controller), indx);
> +    if (master)
> +        gvir_config_domain_controller_usb_set_master(controller, master, start_port);
> +
> +    gvir_config_domain_add_device(design->priv->config,
> +                                  GVIR_CONFIG_DOMAIN_DEVICE(controller));
> +
> +    return controller;
> +}
> +
> +
> +static void
> +gvir_designer_domain_add_usb_controllers(GVirDesignerDomain *design)
> +{
> +    GVirConfigDomainControllerUsb *master;
> +    GVirConfigDomainControllerUsb *controller;
> +
> +    g_debug("Adding USB controllers");
> +
> +    master = gvir_designer_domain_create_usb_controller(design,
> +                                                        GVIR_CONFIG_DOMAIN_CONTROLLER_USB_MODEL_ICH9_EHCI1,
> +                                                        0,
> +                                                        NULL,
> +                                                        0);
> +    controller = gvir_designer_domain_create_usb_controller(design,
> +                                                            GVIR_CONFIG_DOMAIN_CONTROLLER_USB_MODEL_ICH9_UHCI1,
> +                                                            0,
> +                                                            master,
> +                                                            0);
> +    g_object_unref(G_OBJECT(controller));
> +    controller = gvir_designer_domain_create_usb_controller(design,
> +                                                            GVIR_CONFIG_DOMAIN_CONTROLLER_USB_MODEL_ICH9_UHCI2,
> +                                                            0,
> +                                                            master,
> +                                                            2);
> +    g_object_unref(G_OBJECT(controller));
> +    controller = gvir_designer_domain_create_usb_controller(design,
> +                                                            GVIR_CONFIG_DOMAIN_CONTROLLER_USB_MODEL_ICH9_UHCI3,
> +                                                            0,
> +                                                            master,
> +                                                            4);
> +    g_object_unref(G_OBJECT(controller));
> +    g_object_unref(G_OBJECT(master));
> +}
> +
> +
> +/**
> + * gvir_designer_domain_add_usb_redir:
> + * @design: (transfer none): the domain designer instance
> + * @error: return location for a #GError, or NULL
> + *
> + * Add a new usb redirection channel into @design. This allows to redirect
> + * an USB device from the SPICE client to the guest. One USB device
> + * can be redirected per redirection channel, this function can
> + * be called multiple times if you need to redirect multiple devices
> + * simultaneously. An USB2 EHCI controller and USB1 UHCI controllers
> + * will be automatically added to @design if @design does not have
> + * USB controllers yet.
> + *
> + * Returns: (transfer full): the pointer to the new USB redir channel
> + */
> +GVirConfigDomainRedirdev *
> +gvir_designer_domain_add_usb_redir(GVirDesignerDomain *design, GError **error)
> +{
> +    /* FIXME: check if OS/hypervisor support USB
> +     *        check if SPICE is being used
> +     */
> +    GVirConfigDomainRedirdev *redirdev;
> +    GVirConfigDomainChardevSourceSpiceVmc *vmc;
> +
> +    g_return_val_if_fail(GVIR_DESIGNER_IS_DOMAIN(design), NULL);
> +    g_return_val_if_fail(!error_is_set(error), NULL);
> +
> +    redirdev = gvir_config_domain_redirdev_new();
> +    gvir_config_domain_redirdev_set_bus(redirdev,
> +                                        GVIR_CONFIG_DOMAIN_REDIRDEV_BUS_USB);
> +    vmc = gvir_config_domain_chardev_source_spicevmc_new();
> +    gvir_config_domain_chardev_set_source(GVIR_CONFIG_DOMAIN_CHARDEV(redirdev),
> +                                          GVIR_CONFIG_DOMAIN_CHARDEV_SOURCE(vmc));
> +    g_object_unref(G_OBJECT(vmc));
> +
> +    gvir_config_domain_add_device(design->priv->config,
> +                                  GVIR_CONFIG_DOMAIN_DEVICE(redirdev));
> +
> +    if (!gvir_designer_domain_supports_usb(design)) {
> +        gvir_designer_domain_add_usb_controllers(design);
> +    } else {
> +        g_debug("USB controllers are already present");
> +    }
> +
> +    return redirdev;
> +}
> +
> +
>  static void gvir_designer_domain_add_power_management(GVirDesignerDomain *design)
>  {
>      GVirConfigDomainPowerManagement *pm;
> diff --git a/libvirt-designer/libvirt-designer-domain.h b/libvirt-designer/libvirt-designer-domain.h
> index 1399bd4..981fd2e 100644
> --- a/libvirt-designer/libvirt-designer-domain.h
> +++ b/libvirt-designer/libvirt-designer-domain.h
> @@ -136,6 +136,7 @@ GVirConfigDomainGraphics *gvir_designer_domain_add_graphics(GVirDesignerDomain *
>                                                              GVirDesignerDomainGraphics type,
>                                                              GError **error);
>  GVirConfigDomainSound *gvir_designer_domain_add_sound(GVirDesignerDomain *design, GError **error);
> +GVirConfigDomainRedirdev *gvir_designer_domain_add_usb_redir(GVirDesignerDomain *design, GError **error);
>  
>  gboolean gvir_designer_domain_setup_resources(GVirDesignerDomain *design,
>                                                GVirDesignerDomainResources req,
> diff --git a/libvirt-designer/libvirt-designer.sym b/libvirt-designer/libvirt-designer.sym
> index 9a73993..2894dee 100644
> --- a/libvirt-designer/libvirt-designer.sym
> +++ b/libvirt-designer/libvirt-designer.sym
> @@ -23,6 +23,8 @@ LIBVIRT_DESIGNER_0.0.2 {
>  	gvir_designer_domain_add_graphics;
>  	gvir_designer_domain_add_interface_network;
>  	gvir_designer_domain_add_sound;
> +	gvir_designer_domain_add_usb_redir;
> +
>  	gvir_designer_domain_setup_resources;
>  	gvir_designer_domain_resources_get_type;
>  
> 




More information about the libvir-list mailing list