All of lore.kernel.org
 help / color / mirror / Atom feed
From: George Dunlap <george.dunlap@eu.citrix.com>
To: xen-devel@lists.xen.org
Cc: Ian Campbell <ian.campbell@citrix.com>,
	George Dunlap <george.dunlap@eu.citrix.com>,
	sstanisi@cbnco.com, Fabio Fantoni <fabio.fantoni@m2r.biz>,
	Anthony Perard <anthony.perard@citrix.com>,
	Ian Jackson <ian.jackson@citrix.com>,
	"Simon (Bo) Cao" <caobosimon@gmail.com>,
	Roger Pau Monne <roger.pau@citrix.com>
Subject: [PATCH v7 RFC 2/2] xl: Add commands for usb hot-plug
Date: Mon, 2 Jun 2014 14:44:18 +0100	[thread overview]
Message-ID: <1401716658-22393-3-git-send-email-george.dunlap@eu.citrix.com> (raw)
In-Reply-To: <1401716658-22393-1-git-send-email-george.dunlap@eu.citrix.com>

Add xl commands for USB hot-plug.  Domain creation and config file
support not yet added.

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
---
v7:
 - Don't check for invalid return values for find_domain()
 - Use {foo}_to_string in usb_list()
 - call dispose on list elements to avoid leaks
v6:
 - Rename to usb-attach and usb-detach to fit better w/ other device
   add/remove commands
 - Use positional arguments, to fit better w/ other device add/remove
   commands
 - Change specifier to "hostdev:xx.yy", looking forward to a day when
   we may be able to accept something like "tablet"
 - Style fix-ups
v5:
 - Remove extraneous is_hex
 - Replace is_dec with ctype.h isdigit()
 - Replace domid -1 with INVALID_DOMID
 - Fix up a couple of mistaken function names in strings
 - Copy CTYPE macro from libxl_internal.h
 - Fix to usb-list manpage (use -d domid)

CC: Ian Jackson <ian.jackson@citrix.com>
CC: Roger Pau Monne <roger.pau@citrix.com>
CC: sstanisi@cbnco.com
CC: Fabio Fantoni <fabio.fantoni@m2r.biz>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Anthony Perard <anthony.perard@citrix.com>
CC: Simon (Bo) Cao <caobosimon@gmail.com>
---
 docs/man/xl.pod.1         |   30 ++++++++
 tools/libxl/xl.h          |   21 ++++++
 tools/libxl/xl_cmdimpl.c  |  182 +++++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/xl_cmdtable.c |   15 ++++
 4 files changed, 248 insertions(+)

diff --git a/docs/man/xl.pod.1 b/docs/man/xl.pod.1
index 30bd4bf..e04a4a8 100644
--- a/docs/man/xl.pod.1
+++ b/docs/man/xl.pod.1
@@ -1194,6 +1194,36 @@ List virtual network interfaces for a domain.
 
 =back
 
+=head2 USB DEVICES
+
+=over 4
+
+=item B<usb-attach> I<domain-id> I<hostdev:hostbus.hostaddr>
+
+Passes through the host USB device specified by I<hostbus.hostaddr>.  At
+the moment this will only work for HVM domains via qemu.
+
+The best way to find out the information for the device is typically using
+lsusb.
+
+This command is only available for domains using qemu-xen, not
+qemu-traditional.
+
+=item B<usb-detach> I<domain-id> I<hostdev:hosbus.hostaddr>
+
+Remove the host USB device from I<domain-id> which is specified
+by <hostbus.hostaddr>.  This command only works for devices added
+with usb-add; not for those specified in the config file.
+
+This command is only available for domains using qemu-xen, not
+qemu-traditional.
+
+=item B<usb-list> I<domain-id>
+
+Show host USB devices assigned to the guest.
+
+=back
+
 =head2 VTPM DEVICES
 
 =over 4
diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
index 10a2e66..2f1f612 100644
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -35,6 +35,9 @@ int main_info(int argc, char **argv);
 int main_sharing(int argc, char **argv);
 int main_cd_eject(int argc, char **argv);
 int main_cd_insert(int argc, char **argv);
+int main_usb_attach(int argc, char **argv);
+int main_usb_detach(int argc, char **argv);
+int main_usb_list(int argc, char **argv);
 int main_console(int argc, char **argv);
 int main_vncviewer(int argc, char **argv);
 int main_pcilist(int argc, char **argv);
@@ -183,6 +186,24 @@ extern void printf_info_sexp(int domid, libxl_domain_config *d_config);
 #define XL_GLOBAL_CONFIG XEN_CONFIG_DIR "/xl.conf"
 #define XL_LOCK_FILE XEN_LOCK_DIR "/xl"
 
+/*
+ * int CTYPE(ISFOO, char c);
+ * int CTYPE(toupper, char c);
+ * int CTYPE(tolower, char c);
+ *
+ * This is necessary because passing a simple char to a ctype.h
+ * is forbidden.  ctype.h macros take ints derived from _unsigned_ chars.
+ *
+ * If you have a char which might be EOF then you should already have
+ * it in an int representing an unsigned char, and you can use the
+ * <ctype.h> macros directly.  This generally happens only with values
+ * from fgetc et al.
+ *
+ * For any value known to be a character (eg, anything that came from
+ * a char[]), use CTYPE.
+ */
+#define CTYPE(isfoo,c) (isfoo((unsigned char)(c)))
+
 #endif /* XL_H */
 
 /*
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 5195914..7973b4c 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -2771,6 +2771,188 @@ int main_cd_insert(int argc, char **argv)
     return 0;
 }
 
+static int parse_usb_specifier(libxl_device_usb *dev, char *s)
+{
+    char *devtype, * hostbus, *hostaddr, *p;
+
+    /*
+     * General format:
+     * <type>[:<type-specific options>]
+     */
+    p = s;
+    devtype = strsep(&p, ":");
+
+    if (strcmp(devtype, "hostdev")) {
+        fprintf(stderr, "Unknown device type: %s\n", devtype);
+        return -1;
+    }
+    
+    hostbus = strsep(&p, ".");
+
+    hostaddr = p;
+
+    if (!hostbus) {
+        fprintf(stderr, "Device type %s requires hostaddr\n",
+                devtype);
+        return -1;
+    }
+
+    if (!hostaddr) {
+        fprintf(stderr, "Device type %s requires hostaddr\n",
+                devtype);
+        return -1;
+    }
+
+    /* Make sure they look right */
+    for (p=hostbus; *p; p++) {
+        if (!CTYPE(isdigit,*p)) {
+            fprintf(stderr, "Bad hostbus: %s\n", hostbus);
+            return -1;
+        }
+    }
+    
+    for (p=hostaddr; *p; p++) {
+        if (!CTYPE(isdigit,*p)) {
+            fprintf(stderr, "Bad hostaddr: %s\n", hostaddr);
+            return -1;
+        }
+    }
+
+    dev->type = LIBXL_DEVICE_USB_TYPE_HOSTDEV;
+
+    dev->u.hostdev.hostbus  = atoi(hostbus);
+    dev->u.hostdev.hostaddr = atoi(hostaddr);
+
+    return 0;
+}
+
+static int usb_attach(uint32_t domid, char * device)
+{
+    libxl_device_usb usbdev;
+    int rc;
+
+    libxl_device_usb_init(&usbdev);
+
+    if (parse_usb_specifier(&usbdev, device)<0) {
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    rc = libxl_device_usb_add(ctx, domid, &usbdev, NULL);
+    if (rc<0)
+        fprintf(stderr, "libxl_device_usb_add failed.\n");
+
+    libxl_device_usb_dispose(&usbdev);
+
+out:
+    return rc;
+}
+
+int main_usb_attach(int argc, char **argv)
+{
+    uint32_t domid = INVALID_DOMID;
+    int opt = 0, rc;
+    char *device = NULL;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "usb-attach", 2) {
+        /* No options */
+    }
+
+    domid = find_domain(argv[optind]);
+    device = argv[optind + 1];
+
+    rc = usb_attach(domid, device);
+    if (rc<0)
+        return 1;
+    else
+        return 0;
+}
+
+static int usb_detach(uint32_t domid, libxl_device_usb_type type,
+                      char * device)
+{
+    libxl_device_usb usbdev;
+    int rc;
+
+    libxl_device_usb_init(&usbdev);
+
+    if (parse_usb_specifier(&usbdev, device)<0) {
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    rc = libxl_device_usb_remove(ctx, domid, &usbdev, NULL);
+    if (rc<0)
+        fprintf(stderr, "libxl_device_usb_remove failed.\n");
+
+    libxl_device_usb_dispose(&usbdev);
+
+out:
+    return rc;
+}
+
+int main_usb_detach(int argc, char **argv)
+{
+    uint32_t domid = INVALID_DOMID;
+    int opt = 0, rc;
+    char *device = NULL;
+    int type = 0;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "usb-detach", 2) {
+        /* No options */
+    }
+
+    domid = find_domain(argv[optind]);
+    device = argv[optind + 1];
+
+    rc = usb_detach(domid, type, device);
+    if (rc < 0)
+        return 1;
+    else
+        return 0;
+}
+
+static void usb_list(uint32_t domid)
+{
+    libxl_device_usb *dev;
+    int num, i;
+
+    dev = libxl_device_usb_list(ctx, domid, &num);
+    if (dev == NULL)
+        return;
+    printf("protocol    backend  type     device\n");
+    for (i = 0; i < num; i++) {
+        printf("%10s  ", 
+               libxl_usb_protocol_to_string(dev[i].protocol));
+        printf("%7d  ", dev[i].backend_domid);
+        printf("%7s  ", libxl_device_usb_type_to_string(dev[i].type));
+        if (dev[i].type == LIBXL_DEVICE_USB_TYPE_HOSTDEV)
+            printf("%03d.%03d",
+                   dev[i].u.hostdev.hostbus,
+                   dev[i].u.hostdev.hostaddr);
+        printf("\n");
+        libxl_device_usb_dispose(&dev[i]);
+    }
+    free(dev);
+}
+
+
+int main_usb_list(int argc, char **argv)
+{
+    uint32_t domid = INVALID_DOMID;
+    int opt;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "usb-list", 1) {
+        /* No options */
+    }
+
+    domid = find_domain(argv[optind]);
+    usb_list(domid);
+    return 0;
+}
+
+
+
 int main_console(int argc, char **argv)
 {
     uint32_t domid;
diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c
index 4279b9f..c97796b 100644
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -194,6 +194,21 @@ struct cmd_spec cmd_table[] = {
       "Eject a cdrom from a guest's cd drive",
       "<Domain> <VirtualDevice>",
     },
+    { "usb-attach",
+      &main_usb_attach, 1, 1,
+      "Hot-plug a usb device to a domain.",
+      "<Domain> <hostdev:<hostbus.hostaddr>>",
+    },
+    { "usb-detach",
+      &main_usb_detach, 1, 1,
+      "Hot-unplug a usb device from a domain.",
+      "<Domain> <hostdev:hostbus.hostaddr>",
+    },
+    { "usb-list",
+      &main_usb_list, 0, 0,
+      "List usb devices for a domain",
+      "<Domain>",
+    },
     { "mem-max",
       &main_memmax, 0, 1,
       "Set the maximum amount reservation for a domain",
-- 
1.7.9.5

  parent reply	other threads:[~2014-06-02 13:44 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1401716658-22393-1-git-send-email-george.dunlap@eu.citrix.com>
2014-06-02 13:44 ` [PATCH v7 RFC 1/2] libxl: Introduce functions to add and remove USB devices to an HVM guest George Dunlap
2014-06-18 13:08   ` Ian Campbell
2014-06-18 13:22     ` George Dunlap
2014-06-18 13:49       ` Ian Campbell
2014-06-18 13:58         ` George Dunlap
2014-06-18 14:30           ` Ian Campbell
2014-06-18 14:47             ` George Dunlap
2014-06-02 13:44 ` George Dunlap [this message]
2014-06-05 10:14 ` [PATCH v7 RFC 0/2] libxl USB prototype and design discussion Daniel P. Berrange
     [not found] ` <20140605101438.GD19077@redhat.com>
2014-06-05 15:04   ` George Dunlap
2014-06-18 12:57 ` Ian Campbell
     [not found] ` <1403096222.32540.14.camel@kazak.uk.xensource.com>
2014-06-18 13:15   ` George Dunlap
2014-06-18 14:04   ` George Dunlap
     [not found]   ` <53A19C67.3070809@eu.citrix.com>
2014-06-30 14:41     ` Simon Cao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1401716658-22393-3-git-send-email-george.dunlap@eu.citrix.com \
    --to=george.dunlap@eu.citrix.com \
    --cc=anthony.perard@citrix.com \
    --cc=caobosimon@gmail.com \
    --cc=fabio.fantoni@m2r.biz \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@citrix.com \
    --cc=roger.pau@citrix.com \
    --cc=sstanisi@cbnco.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.