[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 2/2] xl: Add commands for usb hot-plug
On 11/04/13 20:51, George Dunlap wrote: > Signed-off-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx> > CC: Ian Jackson <ian.jackson@xxxxxxxxxx> > CC: Roger Pau Monne <roger.pau@xxxxxxxxxx> > CC: sstanisi@xxxxxxxxx > --- > docs/man/xl.pod.1 | 30 +++++++ > tools/libxl/xl.h | 3 + > tools/libxl/xl_cmdimpl.c | 219 > +++++++++++++++++++++++++++++++++++++++++++++ > tools/libxl/xl_cmdtable.c | 15 ++++ > 4 files changed, 267 insertions(+) > > diff --git a/docs/man/xl.pod.1 b/docs/man/xl.pod.1 > index a0e298e..18a8eee 100644 > --- a/docs/man/xl.pod.1 > +++ b/docs/man/xl.pod.1 > @@ -1110,6 +1110,36 @@ List virtual network interfaces for a domain. > > =back > > +=head2 USB DEVICES > + > +=over 4 > + > +=item B<usb-add> I<-d domain-id> I<-v hosbus.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-remove> I<-d domain-id> I<-v 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 b881f92..5c39fa2 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_add(int argc, char **argv); > +int main_usb_remove(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); > diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c > index 61f7b96..a690823 100644 > --- a/tools/libxl/xl_cmdimpl.c > +++ b/tools/libxl/xl_cmdimpl.c > @@ -2600,6 +2600,225 @@ int main_cd_insert(int argc, char **argv) > return 0; > } > > + > + > +static int parse_usb_hostdev_specifier(libxl_device_usb *dev, const char *s) > +{ > + const char * hostbus, *hostaddr, *p; > + > + hostbus = s; > + hostaddr=NULL; > + > +#define is_dec(_c) ((_c) >= '0' && (_c) <= '9') > +#define is_hex(_c) (is_dec(_c) || ((_c) >= 'a' && (_c) <= 'f')) This are kind of general macros, that could be used elsewhere, might be suitable to put them outside of this function and name them CHAR_IS_DEC and CHAR_IS_HEX. > + > + /* 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->u.hostdev.hostbus = strtoul(hostbus, NULL, 10); > + dev->u.hostdev.hostaddr = strtoul(hostaddr, NULL, 10); > +#undef is_dec > +#undef is_hex > + > + return 0; > +} > + > +static int usb_add(uint32_t domid, libxl_device_usb_type type, > + const char * device) > +{ > + libxl_device_usb usbdev; > + int rc; > + > + libxl_device_usb_init(&usbdev); > + > + usbdev.type = type; > + > + switch(type) { > + case LIBXL_DEVICE_USB_TYPE_HOSTDEV: > + if ( parse_usb_hostdev_specifier(&usbdev, device) < 0 ) { > + rc = ERROR_FAIL; > + goto out; > + } > + break; > + default: > + fprintf(stderr, "INTERNAL ERROR: Unimplemented type.\n"); > + rc = ERROR_FAIL; > + goto out; > + } > + > + if ( (rc = libxl_device_usb_add(ctx, domid, &usbdev, NULL)) < 0 ) > + fprintf(stderr, "libxl_usb_add failed.\n"); > + > + libxl_device_usb_dispose(&usbdev); > + > +out: > + return rc; > +} > + > +int main_usb_add(int argc, char **argv) > +{ > + uint32_t domid = -1; You could use INVALID_DOMID that is defined early in the file. > + int opt = 0, rc; > + const char *device = NULL; > + int type = 0; > + > + SWITCH_FOREACH_OPT(opt, "d:v:", NULL, "usb-add", 0) { > + case 'd': > + domid = find_domain(optarg); > + break; > + case 'v': > + type = LIBXL_DEVICE_USB_TYPE_HOSTDEV; > + device = optarg; > + break; > + } > + > + if ( domid == -1 ) { > + fprintf(stderr, "Must specify domid\n\n"); > + help("usb-add"); > + return 2; > + } > + > + if ( !device ) { > + fprintf(stderr, "Must specify a device\n\n"); > + help("usb-add"); > + return 2; > + } > + > + rc = usb_add(domid, type, device); > + if ( rc < 0 ) > + return 1; > + else > + return 0; > +} > + > +static int usb_remove(uint32_t domid, libxl_device_usb_type type, > + const char * device) > +{ > + libxl_device_usb usbdev; > + int rc; > + > + libxl_device_usb_init(&usbdev); > + > + usbdev.type = type; > + > + switch(type) { > + case LIBXL_DEVICE_USB_TYPE_HOSTDEV: > + if ( parse_usb_hostdev_specifier(&usbdev, device) < 0 ) { > + rc = ERROR_FAIL; > + goto out; > + } > + break; > + default: > + fprintf(stderr, "INTERNAL ERROR: Unimplemented type.\n"); > + rc = ERROR_FAIL; > + goto out; > + } > + > + if ( (rc = libxl_device_usb_remove(ctx, domid, &usbdev, NULL)) < 0 ) > + fprintf(stderr, "libxl_usb_remove failed.\n"); > + > + libxl_device_usb_dispose(&usbdev); > + > +out: > + return rc; > +} > + > +int main_usb_remove(int argc, char **argv) > +{ > + uint32_t domid = -1; INVALID_DOMID > + int opt = 0, rc; > + const char *device = NULL; > + int type = 0; > + > + SWITCH_FOREACH_OPT(opt, "d:v:", NULL, "usb-remove", 0) { > + case 'd': > + domid = find_domain(optarg); > + break; > + case 'v': > + type = LIBXL_DEVICE_USB_TYPE_HOSTDEV; > + device = optarg; > + break; > + } > + > + if ( domid == -1 ) { > + fprintf(stderr, "Must specify domid\n\n"); > + help("usb-remove"); > + return 2; > + } > + > + if ( !device ) { > + fprintf(stderr, "Must specify a device\n\n"); > + help("usb-remove"); > + return 2; > + } > + > + rc = usb_remove(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("%8s ", (dev[i].protocol==LIBXL_USB_PROTOCOL_PV)?"pv":"dm"); > + printf("%7d ", dev[i].backend_domid); > + printf("%7s ", > (dev[i].type==LIBXL_DEVICE_USB_TYPE_HOSTDEV)?"hostdev":"unknown"); > + if(dev[i].type == LIBXL_DEVICE_USB_TYPE_HOSTDEV) > + printf("%03d.%03d", > + dev[i].u.hostdev.hostbus, > + dev[i].u.hostdev.hostaddr); > + printf("\n"); > + } > + free(dev); > +} > + > + > +int main_usb_list(int argc, char **argv) > +{ > + uint32_t domid = -1; INVALID_DOMID > + int opt; > + > + SWITCH_FOREACH_OPT(opt, "d:", NULL, "usb-list", 0) { > + case 'd': > + domid = find_domain(optarg); > + break; > + } > + > + if ( domid == -1 ) { > + fprintf(stderr, "Must specify domid\n\n"); > + help("usb-remove"); > + return 2; > + } > + > + 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 b4a87ca..3cf8e65 100644 > --- a/tools/libxl/xl_cmdtable.c > +++ b/tools/libxl/xl_cmdtable.c > @@ -187,6 +187,21 @@ struct cmd_spec cmd_table[] = { > "Eject a cdrom from a guest's cd drive", > "<Domain> <VirtualDevice>", > }, > + { "usb-add", > + &main_usb_add, 1, 1, > + "Hot-plug a usb device to a domain.", > + "-d <Domain> [-v <hostbus.hostaddr>]", > + }, > + { "usb-remove", > + &main_usb_remove, 1, 1, > + "Hot-unplug a usb device from a domain.", > + "-d <Domain> [-v <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", > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |