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