All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest
@ 2013-03-20 16:41 George Dunlap
  2013-03-20 16:41 ` [PATCH v2 2/2] xl: Add hvm-host-usb-add and hvm-host-usb-del commands George Dunlap
  2013-03-20 16:52 ` [PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest Ian Jackson
  0 siblings, 2 replies; 5+ messages in thread
From: George Dunlap @ 2013-03-20 16:41 UTC (permalink / raw)
  To: xen-devel; +Cc: George Dunlap, Ian Jackson, Ian Campbell, Roger Pau Monne

This uses the qmp functionality, and is thus only available for qemu-xen,
not qemu-traditional.

Devices must be removed by "id", an identifying string, which must be
specified when the device is created.  The caller can either pass one
in to request; if none is passed in, then libxl will choose one and
pass it back to the caller.  In the second case, it will return a
string containing the id used in the "id" field of the device struct.

Devices can either be removed by passing in the id returned when the
device was added, or by passing a device struct with exactly the same
parameters as when it was added (which will allow libxl to re-generate
the id for device removal).

v2:
 - Make interface async-ready
 - usb_del takes libxl_device_host_usb struct
 - usb_del will re-construct original id given device info if no id is given

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
---
 tools/libxl/libxl.c          |   96 ++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl.h          |   43 +++++++++++++++++++
 tools/libxl/libxl_internal.h |    4 ++
 tools/libxl/libxl_qmp.c      |   54 ++++++++++++++++++++++++
 tools/libxl/libxl_types.idl  |    8 ++++
 5 files changed, 205 insertions(+)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 572c2c6..fbe6fff 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -2498,6 +2498,102 @@ out:
     return AO_INPROGRESS;
 }
 
+int libxl_hvm_host_usb_add(libxl_ctx *ctx, uint32_t domid,
+                           libxl_device_host_usb *dev,
+                           const libxl_asyncop_how *ao_how)
+{
+    AO_CREATE(ctx, domid, ao_how);
+    int rc = ERROR_FAIL, dm_ver;
+
+    libxl_domain_type type = libxl__domain_type(gc, domid);
+    if (type == LIBXL_DOMAIN_TYPE_INVALID) {
+        goto out;
+    }
+    if (type != LIBXL_DOMAIN_TYPE_HVM) {
+        LOG(ERROR, "hvm-host-usb-add requires an HVM domain");
+        goto out;
+    }
+
+    if (libxl_get_stubdom_id(ctx, domid) != 0) {
+        LOG(ERROR, "hvm-host-usb-add doesn't work for stub domains");
+        goto out;
+    }
+
+    dm_ver = libxl__device_model_version_running(gc, domid);
+    if (dm_ver == -1) {
+        LOG(ERROR, "cannot determine device model version");
+        goto out;
+    }
+
+    if (dm_ver == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
+        rc = libxl__qmp_host_usb_add(gc, domid, dev);
+    } else {
+        LOG(ERROR, "hvm-host-usb-add not yet implemented for qemu-traditional");
+    }
+
+    /* success, no actual async */
+    libxl__ao_complete(egc, ao, 0);
+
+    rc = 0;
+out:
+    if (rc) return AO_ABORT(rc);
+    return AO_INPROGRESS;
+}
+
+int libxl_hvm_host_usb_del(libxl_ctx *ctx, uint32_t domid,
+                           libxl_device_host_usb *dev,
+                           const libxl_asyncop_how *ao_how)
+{
+    AO_CREATE(ctx, domid, ao_how);
+    int rc = ERROR_FAIL, dm_ver;
+    libxl_domain_type type;
+
+    if (dev->id
+        && (dev->hostbus != LIBXL_DEVICE_HOST_USB_ANY
+            || dev->hostaddr != LIBXL_DEVICE_HOST_USB_ANY
+            || dev->vendorid != LIBXL_DEVICE_HOST_USB_ANY
+            || dev->productid != LIBXL_DEVICE_HOST_USB_ANY) ) {
+        LOG(ERROR, "hvm-host-usb-del cannot accept both id and device specifier!");
+        rc = ERROR_INVAL;
+        goto out;
+    }
+
+    type = libxl__domain_type(gc, domid);
+    if (type == LIBXL_DOMAIN_TYPE_INVALID) {
+        goto out;
+    }
+    if (type != LIBXL_DOMAIN_TYPE_HVM) {
+        LOG(ERROR, "hvm-host-usb-del requires an HVM domain");
+        goto out;
+    }
+
+    if (libxl_get_stubdom_id(ctx, domid) != 0) {
+        LOG(ERROR, "hvm-host-usb-del doesn't work for stub domains");
+        goto out;
+    }
+
+    dm_ver = libxl__device_model_version_running(gc, domid);
+    if (dm_ver == -1) {
+        LOG(ERROR, "cannot determine device model version");
+        goto out;
+    }
+
+    if (dm_ver == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
+        rc = libxl__qmp_host_usb_del(gc, domid, dev);
+    } else {
+        LOG(ERROR, "hvm-host-usb-del not yet implemented for qemu-traditional");
+    }
+
+    /* success, no actual async */
+    libxl__ao_complete(egc, ao, 0);
+
+    rc = 0;
+out:
+    if (rc) return AO_ABORT(rc);
+    return AO_INPROGRESS;
+}
+
+
 /* libxl__alloc_vdev only works on the local domain, that is the domain
  * where the toolstack is running */
 static char * libxl__alloc_vdev(libxl__gc *gc, void *get_vdev_user,
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 030aa86..aac6f3f 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -75,6 +75,15 @@
 #define LIBXL_HAVE_FIRMWARE_PASSTHROUGH 1
 
 /*
+ * LIBXL_HAVE_HVM_HOST_USB indicates that the structure libxl_device_host_usb
+ * exists, as well as the following two functions, relating to passing through
+ * host USB devices to HVM guests:
+ * - libxl_hvm_host_usb_add
+ * - libxl_hvm_host_usb_del.
+ */
+#define LIBXL_HAVE_HVM_HOST_USB 1
+
+/*
  * libxl ABI compatibility
  *
  * The only guarantee which libxl makes regarding ABI compatibility
@@ -719,6 +728,40 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk,
                        const libxl_asyncop_how *ao_how)
                        LIBXL_EXTERNAL_CALLERS_ONLY;
 
+/*
+ * HVM Host USB
+ * 
+ * Add and remove specified host USB device to an HVM guest.
+ *
+ * libxl_device_host_usb contains four potential specifiers which are
+ * initialized to LIBXL_DEVICE_HOST_USB_ANY.  According to the qemu
+ * documentation, any parameter that is left empty will match
+ * anything.  It is recommended to at least specify hostbus.hostid, or
+ * vendorid:productid.
+ *
+ * The caller can specify the 'id' field of libxl_device_host_usb.  If
+ * this is left NULL, then libxl will choose one and return the value
+ * in the id field.  Id's must be unique to the device within a VM;
+ * attempting to assign a device with an existing id will return an
+ * error.
+ *
+ * When calling libxl_hvm_host_usb_del, devices can be removed either
+ * by passing the id string with which the device was created, or by
+ * passing the exact same values as when the device was created.  If
+ * "id" is passed, then all other parameters must be set to
+ * LIBXL_DEVICE_HOST_USB_ANY (the default setting).  If the 'id' was
+ * specified on device creation, then 'id' must be used to remove the
+ * device; passing the parameters will fail.
+ */
+#define LIBXL_DEVICE_HOST_USB_ANY (-1)
+int libxl_hvm_host_usb_add(libxl_ctx *ctx, uint32_t domid,
+                           libxl_device_host_usb *dev,
+                           const libxl_asyncop_how *ao_how)
+                           LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_hvm_host_usb_del(libxl_ctx *ctx, uint32_t domid, 
+                           libxl_device_host_usb *dev,
+                           const libxl_asyncop_how *ao_how)
+                           LIBXL_EXTERNAL_CALLERS_ONLY;
 /* Network Interfaces */
 int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic,
                          const libxl_asyncop_how *ao_how)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 8be086d..f8dd886 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1411,6 +1411,10 @@ _hidden int libxl__qmp_save(libxl__gc *gc, int domid, const char *filename);
 /* Set dirty bitmap logging status */
 _hidden int libxl__qmp_set_global_dirty_log(libxl__gc *gc, int domid, bool enable);
 _hidden int libxl__qmp_insert_cdrom(libxl__gc *gc, int domid, const libxl_device_disk *disk);
+_hidden int libxl__qmp_host_usb_add(libxl__gc *gc, int domid, 
+                                    libxl_device_host_usb *dev);
+_hidden int libxl__qmp_host_usb_del(libxl__gc *gc, int domid, 
+                                    libxl_device_host_usb *dev);
 /* close and free the QMP handler */
 _hidden void libxl__qmp_close(libxl__qmp_handler *qmp);
 /* remove the socket file, if the file has already been removed,
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 644d2c0..49b9e48 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -42,6 +42,7 @@
 
 #define QMP_RECEIVE_BUFFER_SIZE 4096
 #define PCI_PT_QDEV_ID "pci-pt-%02x_%02x.%01x"
+#define HOST_USB_QDEV_ID "host-usb-%04x.%04x-%04x.%04x"
 
 typedef int (*qmp_callback_t)(libxl__qmp_handler *qmp,
                               const libxl__json_object *tree,
@@ -929,6 +930,59 @@ int libxl__qmp_insert_cdrom(libxl__gc *gc, int domid,
     }
 }
 
+int libxl__qmp_host_usb_add(libxl__gc *gc, int domid,
+                            libxl_device_host_usb *dev)
+{
+    libxl__json_object *args = NULL;
+
+    if (dev->id == NULL )
+    {
+        dev->id = libxl__sprintf(NOGC, HOST_USB_QDEV_ID,
+                                 (uint16_t) dev->hostbus,
+                                 (uint16_t) dev->hostaddr,
+                                 (uint16_t) dev->vendorid,
+                                 (uint16_t) dev->productid);
+    }
+
+    qmp_parameters_add_string(gc, &args, "driver", "usb-host");
+    if(dev->hostbus != LIBXL_DEVICE_HOST_USB_ANY) {
+        QMP_PARAMETERS_SPRINTF(&args, "hostbus", "0x%x", dev->hostbus);
+    }
+    if(dev->hostaddr != LIBXL_DEVICE_HOST_USB_ANY) {
+        QMP_PARAMETERS_SPRINTF(&args, "hostaddr", "0x%x", dev->hostaddr);
+    }
+    if(dev->vendorid != LIBXL_DEVICE_HOST_USB_ANY) {
+        QMP_PARAMETERS_SPRINTF(&args, "vendorid", "0x%x", dev->vendorid);
+    }
+    if(dev->productid != LIBXL_DEVICE_HOST_USB_ANY) {
+        QMP_PARAMETERS_SPRINTF(&args, "productid", "0x%x", dev->productid);
+    }
+
+    qmp_parameters_add_string(gc, &args, "id", dev->id);
+
+    return qmp_run_command(gc, domid, "device_add", args, NULL, NULL);
+}
+
+int libxl__qmp_host_usb_del(libxl__gc *gc, int domid, 
+                            libxl_device_host_usb *dev)
+{
+    libxl__json_object *args = NULL;
+
+    if (dev->id == NULL )
+    {
+        dev->id = libxl__sprintf(NOGC, HOST_USB_QDEV_ID,
+                                 (uint16_t) dev->hostbus,
+                                 (uint16_t) dev->hostaddr,
+                                 (uint16_t) dev->vendorid,
+                                 (uint16_t) dev->productid);
+    }
+
+    qmp_parameters_add_string(gc, &args, "id", dev->id);
+
+    return qmp_run_command(gc, domid, "device_del", args, NULL, NULL);
+}
+
+
 int libxl__qmp_initializations(libxl__gc *gc, uint32_t domid,
                                const libxl_domain_config *guest_config)
 {
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index f3c212b..45ee531 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -406,6 +406,14 @@ libxl_device_vtpm = Struct("device_vtpm", [
     ("uuid",             libxl_uuid),
 ])
 
+libxl_device_host_usb = Struct("device_host_usb", [
+    ("hostbus",   integer, {'init_val': 'LIBXL_DEVICE_HOST_USB_ANY'}),
+    ("hostaddr",  integer, {'init_val': 'LIBXL_DEVICE_HOST_USB_ANY'}),
+    ("vendorid",  integer, {'init_val': 'LIBXL_DEVICE_HOST_USB_ANY'}),
+    ("productid", integer, {'init_val': 'LIBXL_DEVICE_HOST_USB_ANY'}),
+    ("id",         string),
+    ])
+
 libxl_domain_config = Struct("domain_config", [
     ("c_info", libxl_domain_create_info),
     ("b_info", libxl_domain_build_info),
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/2] xl: Add hvm-host-usb-add and hvm-host-usb-del commands
  2013-03-20 16:41 [PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest George Dunlap
@ 2013-03-20 16:41 ` George Dunlap
  2013-03-20 16:52 ` [PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest Ian Jackson
  1 sibling, 0 replies; 5+ messages in thread
From: George Dunlap @ 2013-03-20 16:41 UTC (permalink / raw)
  To: xen-devel; +Cc: George Dunlap, Ian Jackson, Ian Campbell, Roger Pau Monne

Add commands to add and remove host USB to HVM guests.

v2:
 - Ported to suggested libxl interface
 - Allow user to specify either host-device-spec or devname on remove
 - Options specified with -d, -v, and -i, rather than implicit ordering

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
---
 docs/man/xl.pod.1         |   51 +++++++++
 tools/libxl/xl.h          |    2 +
 tools/libxl/xl_cmdimpl.c  |  267 +++++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/xl_cmdtable.c |   10 ++
 4 files changed, 330 insertions(+)

diff --git a/docs/man/xl.pod.1 b/docs/man/xl.pod.1
index a0e298e..2b5e6d7 100644
--- a/docs/man/xl.pod.1
+++ b/docs/man/xl.pod.1
@@ -1110,6 +1110,57 @@ List virtual network interfaces for a domain.
 
 =back
 
+=head2 HVM DEVICES
+
+=over 4
+
+=item B<hvm-host-usb-add> I<-d domain-id> I<-v host-device-spec> [I<-i devname>]  
+
+Passes through the host USB device specified by I<host-device-spec> to the 
+HVM domain I<domain-id>.  Host-device-spec can be one of the following:
+
+=over 4
+
+=item <hostbus>.<hostaddr>
+
+=item <vendorid>:<productid>
+
+=item <hostbus>.<hostaddr>:<vendorid>:<productid>
+
+=back
+
+The best way to find out the information for the device is typically using
+lsusb.
+
+Using the I<-i> option, you can specify a I<devname> for the
+device. This is an arbitrary string that can be used by
+I<hvm-host-usb-del> to remove the device later.  If no name is
+specified, then one will be chosen automatically.  In any case the
+devname will be printed to stdout if the device is successfully added.
+
+If the I<-i> option is used, then it must be used on device removal;
+I<host-device-spec> cannot be used.
+
+This command is only available for domains using qemu-xen, not
+qemu-traditional.
+
+=item B<hvm-host-usb-del> I<-d domain-id> (I<-i devname> | I<-v host-device-spec>)
+
+Remove the host USB device from I<domain-id> which is specified either
+by I<devname> or I<host-device-spec>.  Exactly one of the two must be
+specified.  I<devname> is a string that was specified when the device
+was inserted by B<hvm-host-usb-add>.  I<host-device-spec> can only be
+used if no name I<devname> was specified when the device was added,
+and it must match exactly the specification given at that time.
+
+Devices specified in the config file do not have an associated
+devname, and thus cannot be removed using this command.
+
+This command is only available for domains using qemu-xen, not
+qemu-traditional.
+
+=back
+
 =head2 VTPM DEVICES
 
 =over 4
diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
index b881f92..8eb368c 100644
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -35,6 +35,8 @@ 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_hvm_host_usb_add(int argc, char **argv);
+int main_hvm_host_usb_del(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);
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 2d40f8f..721343b 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -2584,6 +2584,273 @@ int main_cd_insert(int argc, char **argv)
     return 0;
 }
 
+
+
+static int parse_usb_specifier_hbhavipi(libxl_device_host_usb *dev, const char *s)
+{
+    const char * vid, *pid, *p;
+    const char * hostbus, *hostaddr;
+
+    hostbus = s;
+    hostaddr = vid = pid = NULL;
+
+#define is_dec(_c) ((_c) >= '0' && (_c) <= '9')
+#define is_hex(_c) (is_dec(_c) || ((_c) >= 'a' && (_c) <= 'f'))
+
+    /* Match [0-9]+\.[0-9]:[0-9a-f]+:[0-9a-f] */
+
+    /* First look for [0-9]+\.[0-9]:*/
+    if ( !is_dec(*hostbus) )
+        return -1;
+
+    for(p=s; *p; p++) {
+        if(*p == '.') {
+            if ( !hostaddr )
+                hostaddr = p+1;
+            else {
+                return -1;
+            }
+        } else if (*p == ':') {
+            break;
+        } else if (!is_dec(*p)) {
+            return -1;
+        }
+    }
+    if ( !hostaddr || !is_dec(*hostaddr) )
+        return -1;
+    if ( *p != ':' )
+        return -1;
+
+    p++;
+    /* Now match [0-9a-f]+:[0-9a-f] */
+    vid = p;
+    if ( !is_hex(*vid) )
+        return -1;
+
+    for(; *p; p++) {
+        if(*p == ':') {
+            if ( !pid )
+                pid = p+1;
+            else
+                return -1;
+        } else if (!is_hex(*p)) {
+            return -1;
+        }
+    }
+    if (!pid || !is_hex(*pid))
+        return -1;
+
+    dev->hostbus  = strtoul(hostbus,  NULL, 10);
+    dev->hostaddr = strtoul(hostaddr, NULL, 10);
+    dev->vendorid  = strtoul(vid, NULL, 16);
+    dev->productid = strtoul(pid, NULL, 16);
+
+    return 0;
+}
+
+static int parse_usb_specifier_vipi(libxl_device_host_usb *dev, const char *s)
+{
+    const char * vid, *pid, *p;
+
+    vid = s;
+    pid = NULL;
+
+    /* Match [0-9a-f]+:[0-9a-f] */
+    if ( !is_hex(*vid) )
+        return -1;
+
+    for(p=s; *p; p++) {
+        if(*p == ':') {
+            if ( !pid )
+                pid = p+1;
+            else
+                return -1;
+        } else if (!is_hex(*p)) {
+            return -1;
+        }
+    }
+    if (!pid || !is_hex(*pid))
+        return -1;
+    dev->vendorid  = strtoul(vid, NULL, 16);
+    dev->productid = strtoul(pid, NULL, 16);
+
+    return 0;
+}
+
+static int parse_usb_specifier_hbha(libxl_device_host_usb *dev, const char *s)
+{
+    const char * hostbus, *hostaddr, *p;
+
+    hostbus = s;
+    hostaddr=NULL;
+
+    /* Match [0-9]+\.[0-9] */
+    if (!is_dec(*hostbus))
+        return -1;
+
+    for(p=s; *p; p++) {
+        if(*p == '.') {
+            if ( !hostaddr )
+                hostaddr = p+1;
+            else {
+                return -1;
+            }
+        } else if (!is_dec(*p)) {
+            return -1;
+        }
+    }
+    if (!hostaddr || !is_dec(*hostaddr))
+        return -1;
+    dev->hostbus  = strtoul(hostbus,  NULL, 10);
+    dev->hostaddr = strtoul(hostaddr, NULL, 10);
+
+    return 0;
+}
+
+static int parse_usb_specifier(libxl_device_host_usb *dev, const char *s)
+{
+    /*
+     * Acceptable formats:
+     * - hostbus.hostaddr
+     * - vendorid:productid
+     * - hostbus.hostaddr:vendorid:productid
+     */
+    if ( !parse_usb_specifier_hbha(dev, s) )
+        return 0;
+    if ( !parse_usb_specifier_vipi(dev, s) )
+        return 0;
+    if ( !parse_usb_specifier_hbhavipi(dev, s) )
+        return 0;
+
+    return -1;
+}
+
+#undef is_dec
+#undef is_hex
+
+static int hvm_host_usb_add(uint32_t domid, const char * device,
+                            const char * id)
+{
+    libxl_device_host_usb usbdev;
+    int rc;
+
+    libxl_device_host_usb_init(&usbdev);
+
+    if ( id )
+        usbdev.id = strdup(id);
+
+    if ( parse_usb_specifier(&usbdev, device) < 0 )
+        return -1;
+
+    if ( (rc = libxl_hvm_host_usb_add(ctx, domid, &usbdev, NULL)) >= 0 )
+        printf("Added device with name %s\n", usbdev.id);
+
+    libxl_device_host_usb_dispose(&usbdev);
+
+    return rc;
+}
+
+int main_hvm_host_usb_add(int argc, char **argv)
+{
+    uint32_t domid = -1;
+    int opt = 0, rc;
+    const char *id = NULL, *device = NULL;
+
+    SWITCH_FOREACH_OPT(opt, "d:v:i:", NULL, "hvm-host-usb-add", 0) {
+    case 'd':
+        domid = find_domain(optarg);
+        break;
+    case 'v':
+        device = optarg;
+        break;
+    case 'i':
+        id = optarg;
+        break;
+    }
+
+    if ( domid == -1 ) {
+        fprintf(stderr, "Must specify domid\n\n");
+        help("hvm-host-usb-add");
+        return 2;
+    }
+
+    if ( !device ) {
+        fprintf(stderr, "Must specify a device\n\n");
+        help("hvm-host-usb-add");
+        return 2;
+    }
+
+    rc = hvm_host_usb_add(domid, device, id);
+    if ( rc < 0 )
+        return 1;
+    else
+        return 0;
+}
+
+static int hvm_host_usb_del(uint32_t domid, const char * device,
+                            const char * id)
+{
+    libxl_device_host_usb usbdev;
+    int rc;
+
+    libxl_device_host_usb_init(&usbdev);
+
+    if ( id ) {
+        usbdev.id = strdup(id);
+    } else if ( device && (parse_usb_specifier(&usbdev, device) < 0) ) { 
+            return -1;
+    }
+
+    rc = libxl_hvm_host_usb_del(ctx, domid, &usbdev, NULL);
+
+    libxl_device_host_usb_dispose(&usbdev);
+
+    return rc;
+}
+
+int main_hvm_host_usb_del(int argc, char **argv)
+{
+    uint32_t domid = -1;
+    int opt = 0, rc;
+    const char *id = NULL, *device = NULL;
+
+    SWITCH_FOREACH_OPT(opt, "d:v:i:", NULL, "hvm-host-usb-add", 0) {
+    case 'd':
+        domid = find_domain(optarg);
+        break;
+    case 'v':
+        device = optarg;
+        break;
+    case 'i':
+        id = optarg;
+        break;
+    }
+
+    if ( domid == -1 ) {
+        fprintf(stderr, "Must specify domid\n\n");
+        help("hvm-host-usb-del");
+        return 2;
+    }
+
+    if ( device && id ) {
+        fprintf(stderr, "Cannot specify both device and device-id\n\n");
+        help("hvm-host-usb-del");
+        return 2;
+    }
+
+    if ( !device && !id ) {
+        help("hvm-host-usb-del");
+        fprintf(stderr, "Must specify either device or device-id\n\n");
+        return 2;
+    }
+
+    rc = hvm_host_usb_del(domid, device, id);
+    if ( rc < 0 )
+        return 1;
+    else
+        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 b4a87ca..62ba4f2 100644
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -187,6 +187,16 @@ struct cmd_spec cmd_table[] = {
       "Eject a cdrom from a guest's cd drive",
       "<Domain> <VirtualDevice>",
     },
+    { "hvm-host-usb-add",
+      &main_hvm_host_usb_add, 1, 1,
+      "Hot-plug a host usb device to an HVM domain.",
+      "-d <Domain> -v <host-device-spec> [-i <devname>] ",
+    },
+    { "hvm-host-usb-del",
+      &main_hvm_host_usb_del, 1, 1,
+      "Hot-unplug the named host device from an HVM domain.",
+      "-d <Domain> (-i <devname> | -v <host-device-spec>)",
+    },
     { "mem-max",
       &main_memmax, 0, 1,
       "Set the maximum amount reservation for a domain",
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest
  2013-03-20 16:41 [PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest George Dunlap
  2013-03-20 16:41 ` [PATCH v2 2/2] xl: Add hvm-host-usb-add and hvm-host-usb-del commands George Dunlap
@ 2013-03-20 16:52 ` Ian Jackson
  2013-03-20 17:04   ` George Dunlap
  1 sibling, 1 reply; 5+ messages in thread
From: Ian Jackson @ 2013-03-20 16:52 UTC (permalink / raw)
  To: George Dunlap; +Cc: Roger Pau Monne, Ian Campbell, xen-devel

George Dunlap writes ("[PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest"):
> Devices must be removed by "id", an identifying string, which must be
> specified when the device is created.  The caller can either pass one
> in to request; if none is passed in, then libxl will choose one and
> pass it back to the caller.  In the second case, it will return a
> string containing the id used in the "id" field of the device struct.

IMO we shouldn't expose these ids like this.  Rather, we should do
what we do with block, network, etc. and have functions for listing
and removing devices by their virtual names ("device tree path" or
whatever as the guest sees it).

If QMP is deficient then this may mean keeping a separate list
somewhere.

Ian.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest
  2013-03-20 16:52 ` [PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest Ian Jackson
@ 2013-03-20 17:04   ` George Dunlap
  2013-03-20 17:48     ` Ian Jackson
  0 siblings, 1 reply; 5+ messages in thread
From: George Dunlap @ 2013-03-20 17:04 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Roger Pau Monne, Ian Campbell, xen-devel

On 20/03/13 16:52, Ian Jackson wrote:
> George Dunlap writes ("[PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest"):
>> Devices must be removed by "id", an identifying string, which must be
>> specified when the device is created.  The caller can either pass one
>> in to request; if none is passed in, then libxl will choose one and
>> pass it back to the caller.  In the second case, it will return a
>> string containing the id used in the "id" field of the device struct.
> IMO we shouldn't expose these ids like this.  Rather, we should do
> what we do with block, network, etc. and have functions for listing
> and removing devices by their virtual names ("device tree path" or
> whatever as the guest sees it).
>
> If QMP is deficient then this may mean keeping a separate list
> somewhere.

Right -- I was hoping to have such an implementation as a 
"nice-to-have", which I would try to get in as a best-effort, rather 
than a requirement.

  -George

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest
  2013-03-20 17:04   ` George Dunlap
@ 2013-03-20 17:48     ` Ian Jackson
  0 siblings, 0 replies; 5+ messages in thread
From: Ian Jackson @ 2013-03-20 17:48 UTC (permalink / raw)
  To: George Dunlap; +Cc: Roger Pau Monne, Ian Campbell, xen-devel

George Dunlap writes ("Re: [PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest"):
> Right -- I was hoping to have such an implementation as a 
> "nice-to-have", which I would try to get in as a best-effort, rather 
> than a requirement.

Right.  If at the moment that's too hard then surely the
protocol/driver/wossname field can be made mandatory for now ?

I'm just thinking of the shape of the future interface.

Ian.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-03-20 17:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-20 16:41 [PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest George Dunlap
2013-03-20 16:41 ` [PATCH v2 2/2] xl: Add hvm-host-usb-add and hvm-host-usb-del commands George Dunlap
2013-03-20 16:52 ` [PATCH v2 1/2] libxl: Introduce functions to add and remove host USB devices to an HVM guest Ian Jackson
2013-03-20 17:04   ` George Dunlap
2013-03-20 17:48     ` Ian Jackson

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.