[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v5 2/2] xl: Add commands for usb hot-plug
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) 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 | 21 +++++ tools/libxl/xl_cmdimpl.c | 214 +++++++++++++++++++++++++++++++++++++++++++++ tools/libxl/xl_cmdtable.c | 15 ++++ 4 files changed, 280 insertions(+) diff --git a/docs/man/xl.pod.1 b/docs/man/xl.pod.1 index 57c6a79..f6d61e4 100644 --- a/docs/man/xl.pod.1 +++ b/docs/man/xl.pod.1 @@ -1147,6 +1147,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<-d 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 771b4af..0ded61e 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); @@ -164,6 +167,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 98ecf67..e357eb1 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -2602,6 +2602,220 @@ 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; + + /* Match [0-9]+\.[0-9] */ + if (!CTYPE(isdigit,*hostbus)) + return -1; + + for(p=s; *p; p++) { + if(*p == '.') { + if ( !hostaddr ) + hostaddr = p+1; + else { + return -1; + } + } else if (!CTYPE(isdigit,*p)) { + return -1; + } + } + if (!hostaddr || !CTYPE(isdigit,*hostaddr)) + return -1; + dev->u.hostdev.hostbus = strtoul(hostbus, NULL, 10); + dev->u.hostdev.hostaddr = strtoul(hostaddr, NULL, 10); + + 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_device_usb_add failed.\n"); + + libxl_device_usb_dispose(&usbdev); + +out: + return rc; +} + +int main_usb_add(int argc, char **argv) +{ + uint32_t domid = INVALID_DOMID; + 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 == INVALID_DOMID ) { + 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_device_usb_remove failed.\n"); + + libxl_device_usb_dispose(&usbdev); + +out: + return rc; +} + +int main_usb_remove(int argc, char **argv) +{ + uint32_t domid = 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 == INVALID_DOMID ) { + 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 = INVALID_DOMID; + int opt; + + SWITCH_FOREACH_OPT(opt, "d:", NULL, "usb-list", 0) { + case 'd': + domid = find_domain(optarg); + break; + } + + if ( domid == INVALID_DOMID ) { + fprintf(stderr, "Must specify domid\n\n"); + help("usb-list"); + 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 00899f5..a21b1d4 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", + "-d <Domain>", + }, { "mem-max", &main_memmax, 0, 1, "Set the maximum amount reservation for a domain", -- 1.7.9.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |