summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@redhat.com>2013-03-30 18:31:25 +0100
committerChristophe Fergeau <cfergeau@redhat.com>2013-06-06 09:28:43 +0200
commite2734c8d5e7ac6df81326ca58157334113a7da96 (patch)
tree4e04f12d745f9d6b17a84b8804b502f40c5f8391
parente43b9def387dd28c4ec1dd48afa0203990048e1e (diff)
Implement gvir_designer_domain_add_usb_redir()
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 add 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, ...
-rw-r--r--examples/virtxml.c15
-rw-r--r--libvirt-designer/libvirt-designer-domain.c117
-rw-r--r--libvirt-designer/libvirt-designer-domain.h1
-rw-r--r--libvirt-designer/libvirt-designer.sym2
4 files changed, 135 insertions, 0 deletions
diff --git a/examples/virtxml.c b/examples/virtxml.c
index 50eb638..3d9d71f 100644
--- a/examples/virtxml.c
+++ b/examples/virtxml.c
@@ -565,9 +565,11 @@ main(int argc, char *argv[])
static char *connect_uri = NULL;
static char *graphics_str = NULL;
GVirDesignerDomainGraphics graphics;
+ static gboolean enable_usb;
static char *resources_str = NULL;
GVirDesignerDomainResources resources;
GOptionContext *context = NULL;
+ unsigned int i;
static GOptionEntry entries[] =
{
@@ -593,6 +595,8 @@ main(int argc, char *argv[])
"add interface with NETWORK source. Possible ARGs: mac, link={up,down}", "NETWORK[,ARG=VAL]"},
{"graphics", 'g', 0, G_OPTION_ARG_STRING, &graphics_str,
"add graphical output to the VM. Possible values are 'spice' or 'vnc'", "GRAPHICS"},
+ {"usb", 'u', 0, G_OPTION_ARG_NONE, &enable_usb,
+ "add USB redirection to the VM.", NULL},
{"resources", 'r', 0, G_OPTION_ARG_STRING, &resources_str,
"Set minimal or recommended values for cpu count and RAM amount", "{minimal|recommended}"},
{NULL}
@@ -646,6 +650,14 @@ main(int argc, char *argv[])
gvir_designer_domain_setup_machine(domain, &error);
CHECK_ERROR;
+ if (enable_usb) {
+ for (i = 0; i < 4; i++) {
+ /* 4 USB redir channels allow to redirect 4 USB devices at once */
+ 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;
@@ -803,6 +815,9 @@ I<link>={up|down}
Add a graphics device of type I<GRAPHICS>. Valid values are I<spice>
or I<vnc>.
+=item -u
+
+Add USB controllers and setup USB redirection in the VM configuration.
=item -r RESOURCE, --resources=RESOURCES
diff --git a/libvirt-designer/libvirt-designer-domain.c b/libvirt-designer/libvirt-designer-domain.c
index 911fb72..a435ea0 100644
--- a/libvirt-designer/libvirt-designer-domain.c
+++ b/libvirt-designer/libvirt-designer-domain.c
@@ -587,6 +587,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;