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

Christophe Fergeau cfergeau at redhat.com
Thu Apr 18 16:12:31 UTC 2013


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
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;
+    }
 
     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 1a622bf..e6db016 100644
--- a/libvirt-designer/libvirt-designer-domain.c
+++ b/libvirt-designer/libvirt-designer-domain.c
@@ -581,6 +581,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 eb8419e..15faac1 100644
--- a/libvirt-designer/libvirt-designer.sym
+++ b/libvirt-designer/libvirt-designer.sym
@@ -23,6 +23,8 @@ LIBVIRT_DESIGNER_0.0.1 {
 	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;
 
-- 
1.8.1.4




More information about the libvir-list mailing list