* [PATCH V4 0/7] xen pvusb toolstack work @ 2015-06-10 3:20 Chunyan Liu 2015-06-10 3:20 ` [PATCH V4 1/7] libxl: export some functions for pvusb use Chunyan Liu ` (6 more replies) 0 siblings, 7 replies; 88+ messages in thread From: Chunyan Liu @ 2015-06-10 3:20 UTC (permalink / raw) To: xen-devel; +Cc: george.dunlap, wei.liu2, Ian.Jackson, ian.campbell, Chunyan Liu This patch series is to add pvusb toolstack work, supporting hot add|remove USB device to|from guest and specify USB device in domain configuration file. Changes to v3: * add new entry for reading sysfs file contents to get usb device info. * merge pv|qemu protocol in earlier patches, instead of refacotring in a separate patch, with minimum code to handle that. * change libxl_device_usbctrl_add to be async, consistent with usbctrl_remove. Using MACROs as possible, adjusting related codes. * use libxl_* helpers as possible, instead of calloc, realloc, strdup, etc. * correct update_json related processing. * other fixes addring V3 comments V3 is here: http://lists.xen.org/archives/html/xen-devel/2015-04/msg02114.html Related Discussion Threads: http://www.redhat.com/archives/libvir-list/2014-June/msg00038.html http://lists.xen.org/archives/html/xen-devel/2014-06/msg00086.html For better understanding, a summary about pvusb is posted in following. 1. Overview There are two general methods for passing through individual host devices to a guest. The first is via an emulated USB device controller; the second is PVUSB. Additionally, there are two ways to add USB devices to a guest: via the config file at domain creation time, and via hot-plug while the VM is running. * Emulated USB In emulated USB, the device model (qemu) presents an emulated USB controller to the guest. The device model process then grabs control of the device from domain 0 and and passes the USB commands between the guest OS and the host USB device. This method is only available to HVM domains, and is not available for domains running with device model stubdomains. * PVUSB PVUSB uses a paravirtialized front-end/back-end interface, similar to the traditional Xen PV network and disk protocols. In order to use PVUSB, you need usbfront in your guest OS, and usbback in dom0 (or your USB driver domain). Additionally, for easy use of PVUSB, you need support in the toolstack to get the two sides to talk to each other. 2. Specifying a host USB device QEMU hmp commands allows USB devices to be specified either by their bus address (in the form bus.device) or their device tag (in the form vendorid:deviceid). Each way of specifying has its advantages: Specifying by device tag will always get the same device, regardless of where the device ends up in the USB bus topology. However, if there are two identical devices, it will not allow you to specify which one. Specifying by bus address will always allow you to choose a specific device, even if you have duplicates. However, the bus address may change depending on which port you plugged the device into, and possibly also after a reboot. To avoid duplication of vendorid:deviceid, we'll use bus address to specify host USB device in xl toolstack. You can use lsusb to list the USB devices on the system: Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub Bus 003 Device 002: ID f617:0905 Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 001 Device 004: ID 0424:2640 Standard Microsystems Corp. USB 2.0 Hub Bus 001 Device 005: ID 0424:4060 Standard Microsystems Corp. Ultra Fast Media Reader Bus 001 Device 006: ID 046d:c016 Logitech, Inc. Optical Wheel Mouse To pass through the Logitec mouse, for instance, you could specify 1.6 (remove leading zeroes). Note: USB Hub could not be assigned to guest. 3. PVUSB toolstack * Specify USB device in xl config file You can just specify usb devices, like: usb=['1.6'] Then it will create a USB controller automatically and attach the USB device to the first available USB controller:port. or, you can explicitly specify usb controllers and usb devices, like: usbctrl=['verison=1, ports=4', 'version=2, ports=8', ] usb=['1.6, controller=0, port=1'] Then it will create two USB controllers as you specified. And if controller and port are specified in usb config, then it will attach the USB device to that controller:port. About the controller and port value: Each USB controller has a index (or called devid) based on 0. The 1st controller has index 0, the 2nd controller has index 1, ... Under controller, each port has a port number based on 1. In above configuration, the 1st controller will have port 1,2,3,4. To be compatible with QEMU emulated USB, this interface could be extended to: usb=['1.6, type=pv|qemu',] type=pv means attaching the USB device in pvusb way; type=qemu means attaching USB device in QEMU emulated way. * Hot-Plug USB device To attach a USB device, you should first create a USB controller. e.g. xl usb-ctrl-attach domain [version=1|2] [ports=value] By default, it will create a USB2.0 controller with 8 ports. Then you could attach a USB device. e.g. xl usb-attach domain 1.6 [controller=index port=number] By default, it will find the 1st available controller:port to attach the USB device. You could view USB device status of the domain by usb-list. e.g. xl usb-list domain It will list USB controllers and USB devices under each controller. You could detach a USB device with usb-detach command. e.g. xl usb-detach domain 1.6 You can also remove the whole USB controller by usb-ctrl-detach command. e.g. xl usb-ctrl-detach domain 0 It will remove the USB controller with index 0 and all USB devices under it. To be compatible with QEMU emulated USB, these interfaces could be extended to: xl usb-attach domain 1.6 type=pv|qemu xl usb-detach domain 1.6 type=pv|qemu QEMU emulated USB won't handle USB controller create/delete through xl, so usb-ctrl-attach|detach operations are currently pvusb only. 4. PVUSB Libxl implementation * usb-ctrl-attach To create a usb controller, we need: 1) generate usb controler related information 2) write usb controller frontend/backend info to xenstore PVUSB frontend and backend driver will probe xenstore paths and build connection between frontend and backend. * usb-ctrl-detach To remove a usb controller, we need: 1) check if the usb controller exists or not 2) remove all usb devices under controller 3) remove usb controller info from xenstore * usb-attach To attach a usb device, we need: 1) check if the usb device type is assignable 2) check if the usb device is already assigned to a domain 3) add 'busid' of the usb device to xenstore contoller/port/. PVUSB driver watches the xenstore changes and detects that, and needs to use 'busid' to do following work. 4) unbind usb device from original driver and bind to usbback. If usb device has many interfaces, then: - unbind each interface from its original driver and bind to usbback. - store the original driver to xenstore for later rebinding when detaching the device. * usb-detach To detach a usb device, we need: 1) check if the usb device is assigned to the domain 2) remove the usb device from xenstore controller/port. 3) unbind usb device from usbback and rebind to its original driver. If usb device has many interfaces, do it to each interface. * usb-list List all USB controllers and USB devices under each controller. Chunyan Liu (7): libxl: export some functions for pvusb use libxl_read_file_contents: add new entry to read sysfs file libxl: add pvusb API libxl: add libxl_device_usb_assignable_list API xl: add pvusb commands xl: add usb-assignable-list command domcreate: support pvusb in configuration file docs/man/xl.cfg.pod.5 | 75 ++ docs/man/xl.pod.1 | 38 + docs/misc/pvusb.txt | 243 +++++++ tools/libxl/Makefile | 2 +- tools/libxl/libxl.c | 12 +- tools/libxl/libxl.h | 68 ++ tools/libxl/libxl_create.c | 73 +- tools/libxl/libxl_device.c | 2 + tools/libxl/libxl_internal.h | 25 +- tools/libxl/libxl_osdeps.h | 13 + tools/libxl/libxl_pvusb.c | 1295 ++++++++++++++++++++++++++++++++++ tools/libxl/libxl_types.idl | 52 ++ tools/libxl/libxl_types_internal.idl | 1 + tools/libxl/libxl_utils.c | 40 +- tools/libxl/libxl_utils.h | 2 + tools/libxl/xl.h | 6 + tools/libxl/xl_cmdimpl.c | 387 +++++++++- tools/libxl/xl_cmdtable.c | 29 + 18 files changed, 2350 insertions(+), 13 deletions(-) create mode 100644 docs/misc/pvusb.txt create mode 100644 tools/libxl/libxl_pvusb.c -- 2.1.4 ^ permalink raw reply [flat|nested] 88+ messages in thread
* [PATCH V4 1/7] libxl: export some functions for pvusb use 2015-06-10 3:20 [PATCH V4 0/7] xen pvusb toolstack work Chunyan Liu @ 2015-06-10 3:20 ` Chunyan Liu 2015-06-11 16:08 ` Ian Jackson 2015-06-10 3:20 ` [PATCH V4 2/7] libxl_read_file_contents: add new entry to read sysfs file Chunyan Liu ` (5 subsequent siblings) 6 siblings, 1 reply; 88+ messages in thread From: Chunyan Liu @ 2015-06-10 3:20 UTC (permalink / raw) To: xen-devel Cc: wei.liu2, ian.campbell, george.dunlap, Ian.Jackson, Chunyan Liu, Simon Cao Signed-off-by: Chunyan Liu <cyliu@suse.com> Signed-off-by: Simon Cao <caobosimon@gmail.com> Acked-by: Wei Liu <wei.liu2@citrix.com> --- tools/libxl/libxl.c | 6 +++--- tools/libxl/libxl_internal.h | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 9117b01..bd4daea 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1963,7 +1963,7 @@ out: /******************************************************************************/ /* generic callback for devices that only need to set ao_complete */ -static void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev) +void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev) { STATE_AO_GC(aodev->ao); @@ -1986,7 +1986,7 @@ out: } /* common function to get next device id */ -static int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device) +int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device) { char *dompath, **l; unsigned int nb; @@ -2005,7 +2005,7 @@ static int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device) return nextid; } -static int libxl__resolve_domid(libxl__gc *gc, const char *name, +int libxl__resolve_domid(libxl__gc *gc, const char *name, uint32_t *domid) { if (!name) diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index bb3a5c7..ef7aa1d 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1083,6 +1083,9 @@ _hidden int libxl__init_console_from_channel(libxl__gc *gc, libxl__device_console *console, int dev_num, libxl_device_channel *channel); +_hidden int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device); +_hidden int libxl__resolve_domid(libxl__gc *gc, const char *name, + uint32_t *domid); /* * For each aggregate type which can be used as an input we provide: @@ -2225,6 +2228,8 @@ struct libxl__ao_device { /* Starts preparing to add/remove a bunch of devices. */ _hidden void libxl__multidev_begin(libxl__ao *ao, libxl__multidev*); +/* generic callback for devices that only need to set ao_complete */ +_hidden void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev); /* Prepares to add/remove one of many devices. * Calls libxl__prepare_ao_device on libxl__ao_device argument provided and -- 2.1.4 ^ permalink raw reply related [flat|nested] 88+ messages in thread
* Re: [PATCH V4 1/7] libxl: export some functions for pvusb use 2015-06-10 3:20 ` [PATCH V4 1/7] libxl: export some functions for pvusb use Chunyan Liu @ 2015-06-11 16:08 ` Ian Jackson 2015-06-11 16:28 ` Wei Liu 0 siblings, 1 reply; 88+ messages in thread From: Ian Jackson @ 2015-06-11 16:08 UTC (permalink / raw) To: Chunyan Liu; +Cc: george.dunlap, Simon Cao, wei.liu2, ian.campbell, xen-devel Chunyan Liu writes ("[Xen-devel] [PATCH V4 1/7] libxl: export some functions for pvusb use"): > Signed-off-by: Chunyan Liu <cyliu@suse.com> > Signed-off-by: Simon Cao <caobosimon@gmail.com> > Acked-by: Wei Liu <wei.liu2@citrix.com> ... > /* generic callback for devices that only need to set ao_complete */ > -static void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev) > +void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev) Functions in libxl with external linkage should have the appropriate namespacing (ie, their names must start with libxl__). So, I'm afraid, contrary to Wei's opinion: Nacked-by: Ian Jackson <ian.jackson@eu.citrix.com> Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 1/7] libxl: export some functions for pvusb use 2015-06-11 16:08 ` Ian Jackson @ 2015-06-11 16:28 ` Wei Liu 2015-06-12 15:14 ` Ian Jackson 0 siblings, 1 reply; 88+ messages in thread From: Wei Liu @ 2015-06-11 16:28 UTC (permalink / raw) To: Ian Jackson Cc: wei.liu2, ian.campbell, george.dunlap, Chunyan Liu, xen-devel, Simon Cao On Thu, Jun 11, 2015 at 05:08:57PM +0100, Ian Jackson wrote: > Chunyan Liu writes ("[Xen-devel] [PATCH V4 1/7] libxl: export some functions for pvusb use"): > > Signed-off-by: Chunyan Liu <cyliu@suse.com> > > Signed-off-by: Simon Cao <caobosimon@gmail.com> > > Acked-by: Wei Liu <wei.liu2@citrix.com> > ... > > /* generic callback for devices that only need to set ao_complete */ > > -static void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev) > > +void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev) > > Functions in libxl with external linkage should have the appropriate > namespacing (ie, their names must start with libxl__). > > So, I'm afraid, contrary to Wei's opinion: > > Nacked-by: Ian Jackson <ian.jackson@eu.citrix.com> > I think if Chunyan moves that function to libxl__ namespace this patch should be fine, right? Wei. > Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 1/7] libxl: export some functions for pvusb use 2015-06-11 16:28 ` Wei Liu @ 2015-06-12 15:14 ` Ian Jackson 0 siblings, 0 replies; 88+ messages in thread From: Ian Jackson @ 2015-06-12 15:14 UTC (permalink / raw) To: Wei Liu; +Cc: george.dunlap, ian.campbell, Simon Cao, Chunyan Liu, xen-devel Wei Liu writes ("Re: [Xen-devel] [PATCH V4 1/7] libxl: export some functions for pvusb use"): > On Thu, Jun 11, 2015 at 05:08:57PM +0100, Ian Jackson wrote: > > Functions in libxl with external linkage should have the appropriate > > namespacing (ie, their names must start with libxl__). > > > > So, I'm afraid, contrary to Wei's opinion: > > > > Nacked-by: Ian Jackson <ian.jackson@eu.citrix.com> > > > > I think if Chunyan moves that function to libxl__ namespace this patch > should be fine, right? Yes. Thanks, Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* [PATCH V4 2/7] libxl_read_file_contents: add new entry to read sysfs file 2015-06-10 3:20 [PATCH V4 0/7] xen pvusb toolstack work Chunyan Liu 2015-06-10 3:20 ` [PATCH V4 1/7] libxl: export some functions for pvusb use Chunyan Liu @ 2015-06-10 3:20 ` Chunyan Liu 2015-06-11 16:16 ` Ian Jackson 2015-06-10 3:20 ` [PATCH V4 3/7] libxl: add pvusb API Chunyan Liu ` (4 subsequent siblings) 6 siblings, 1 reply; 88+ messages in thread From: Chunyan Liu @ 2015-06-10 3:20 UTC (permalink / raw) To: xen-devel; +Cc: george.dunlap, wei.liu2, Ian.Jackson, ian.campbell, Chunyan Liu Sysfs file has size=4096 but actual file content is less than that. Current libxl_read_file_contents will treat it as error when file size and actual file content differs, so reading sysfs file content with this function always fails. Add a new entry libxl_read_sysfs_file_contents to handle sysfs file specially. It would be used in later pvusb work. Signed-off-by: Chunyan Liu <cyliu@suse.com> --- Changes: - instead of hacking lixbl_read_file_contents for sysfs file, add a new entry libxl_read_sysfs_file_contents to do the work. tools/libxl/libxl_utils.c | 24 ++++++++++++++++++++---- tools/libxl/libxl_utils.h | 2 ++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c index f6be2d7..d0d56c2 100644 --- a/tools/libxl/libxl_utils.c +++ b/tools/libxl/libxl_utils.c @@ -322,8 +322,10 @@ out: return rc; } -int libxl_read_file_contents(libxl_ctx *ctx, const char *filename, - void **data_r, int *datalen_r) { +static int libxl_read_file_contents_core(libxl_ctx *ctx, const char *filename, + void **data_r, int *datalen_r, + bool is_sysfs_file) +{ GC_INIT(ctx); FILE *f = 0; uint8_t *data = 0; @@ -360,15 +362,16 @@ int libxl_read_file_contents(libxl_ctx *ctx, const char *filename, if (stab.st_size && data_r) { data = malloc(datalen); + memset(data, 0, datalen); if (!data) goto xe; rs = fread(data, 1, datalen, f); - if (rs != datalen) { + if (rs != datalen && !(feof(f) && is_sysfs_file)) { if (ferror(f)) LOGE(ERROR, "failed to read %s", filename); else if (feof(f)) LOG(ERROR, "%s changed size while we were reading it", - filename); + filename); else abort(); goto xe; @@ -396,6 +399,19 @@ int libxl_read_file_contents(libxl_ctx *ctx, const char *filename, return e; } +int libxl_read_file_contents(libxl_ctx *ctx, const char *filename, + void **data_r, int *datalen_r) +{ + return libxl_read_file_contents_core(ctx, filename, data_r, datalen_r, 0); +} + +int libxl_read_sysfs_file_contents(libxl_ctx *ctx, const char *filename, + void **data_r, int *datalen_r) +{ + return libxl_read_file_contents_core(ctx, filename, data_r, datalen_r, 1); +} + + #define READ_WRITE_EXACTLY(rw, zero_is_eof, constdata) \ \ int libxl_##rw##_exactly(libxl_ctx *ctx, int fd, \ diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h index 1c1761d..7639662 100644 --- a/tools/libxl/libxl_utils.h +++ b/tools/libxl/libxl_utils.h @@ -38,6 +38,8 @@ int libxl_is_stubdom(libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid); int libxl_create_logfile(libxl_ctx *ctx, const char *name, char **full_name); int libxl_string_to_backend(libxl_ctx *ctx, char *s, libxl_disk_backend *backend); +int libxl_read_sysfs_file_contents(libxl_ctx *ctx, const char *filename, + void **data_r, int *datalen_r); int libxl_read_file_contents(libxl_ctx *ctx, const char *filename, void **data_r, int *datalen_r); /* Reads the contents of the plain file filename into a mallocd -- 2.1.4 ^ permalink raw reply related [flat|nested] 88+ messages in thread
* Re: [PATCH V4 2/7] libxl_read_file_contents: add new entry to read sysfs file 2015-06-10 3:20 ` [PATCH V4 2/7] libxl_read_file_contents: add new entry to read sysfs file Chunyan Liu @ 2015-06-11 16:16 ` Ian Jackson 2015-06-12 7:00 ` Chun Yan Liu 0 siblings, 1 reply; 88+ messages in thread From: Ian Jackson @ 2015-06-11 16:16 UTC (permalink / raw) To: Chunyan Liu; +Cc: george.dunlap, wei.liu2, ian.campbell, xen-devel Chunyan Liu writes ("[Xen-devel] [PATCH V4 2/7] libxl_read_file_contents: add new entry to read sysfs file"): > Sysfs file has size=4096 but actual file content is less than that. > Current libxl_read_file_contents will treat it as error when file size > and actual file content differs, so reading sysfs file content with > this function always fails. > > Add a new entry libxl_read_sysfs_file_contents to handle sysfs file > specially. It would be used in later pvusb work. I think this patch is roughly right, but: > -int libxl_read_file_contents(libxl_ctx *ctx, const char *filename, > - void **data_r, int *datalen_r) { > +static int libxl_read_file_contents_core(libxl_ctx *ctx, const char *filename, > + void **data_r, int *datalen_r, > + bool is_sysfs_file) I would prefer a functional rather than contextual name for the variabvle is_sysfs_file. How about `tolerate_shrinking_file' ? > @@ -360,15 +362,16 @@ int libxl_read_file_contents(libxl_ctx *ctx, const char *filename, > > if (stab.st_size && data_r) { > data = malloc(datalen); > + memset(data, 0, datalen); What is this for ? > if (!data) goto xe; > > rs = fread(data, 1, datalen, f); > - if (rs != datalen) { > + if (rs != datalen && !(feof(f) && is_sysfs_file)) { > if (ferror(f)) > LOGE(ERROR, "failed to read %s", filename); > else if (feof(f)) I think it would be better to handle the special case here, with something like if (!tolerate_shrinking_file) error stuff else { assert(datalen_r); and to move the `goto xe' into the individual branches. Is there any risk that the file is actually bigger than advertised, rather than smaller ? > diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h > index 1c1761d..7639662 100644 > --- a/tools/libxl/libxl_utils.h > +++ b/tools/libxl/libxl_utils.h ... > +int libxl_read_sysfs_file_contents(libxl_ctx *ctx, const char *filename, > + void **data_r, int *datalen_r); I think this is a function with sufficiently odd semantics, and a sufficiently internal purpose, that it should probably not be exposed in the API. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 2/7] libxl_read_file_contents: add new entry to read sysfs file 2015-06-11 16:16 ` Ian Jackson @ 2015-06-12 7:00 ` Chun Yan Liu 2015-06-12 15:11 ` Ian Jackson 0 siblings, 1 reply; 88+ messages in thread From: Chun Yan Liu @ 2015-06-12 7:00 UTC (permalink / raw) To: Ian Jackson; +Cc: george.dunlap, wei.liu2, ian.campbell, xen-devel >>> On 6/12/2015 at 12:16 AM, in message <21881.46148.466883.923039@mariner.uk.xensource.com>, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote: > Chunyan Liu writes ("[Xen-devel] [PATCH V4 2/7] libxl_read_file_contents: add > new entry to read sysfs file"): > > Sysfs file has size=4096 but actual file content is less than that. > > Current libxl_read_file_contents will treat it as error when file size > > and actual file content differs, so reading sysfs file content with > > this function always fails. > > > > Add a new entry libxl_read_sysfs_file_contents to handle sysfs file > > specially. It would be used in later pvusb work. > > I think this patch is roughly right, but: > > > -int libxl_read_file_contents(libxl_ctx *ctx, const char *filename, > > - void **data_r, int *datalen_r) { > > +static int libxl_read_file_contents_core(libxl_ctx *ctx, const char > *filename, > > + void **data_r, int *datalen_r, > > + bool is_sysfs_file) > > I would prefer a functional rather than contextual name for the > variabvle is_sysfs_file. How about `tolerate_shrinking_file' ? OK. > > > @@ -360,15 +362,16 @@ int libxl_read_file_contents(libxl_ctx *ctx, const > char *filename, > > > > if (stab.st_size && data_r) { > > data = malloc(datalen); > > + memset(data, 0, datalen); > > What is this for ? I found sometimes reading sysfs file contents, at the end, there is some random character. With this line, there is no problem then. > > > if (!data) goto xe; > > > > rs = fread(data, 1, datalen, f); > > - if (rs != datalen) { > > + if (rs != datalen && !(feof(f) && is_sysfs_file)) { > > if (ferror(f)) > > LOGE(ERROR, "failed to read %s", filename); > > else if (feof(f)) > > I think it would be better to handle the special case here, with > something like > if (!tolerate_shrinking_file) > error stuff > else { > assert(datalen_r); > and to move the `goto xe' into the individual branches. OK. Will update. > > > Is there any risk that the file is actually bigger than advertised, > rather than smaller ? For sysfs file, couldn't be bigger. > > > diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h > > index 1c1761d..7639662 100644 > > --- a/tools/libxl/libxl_utils.h > > +++ b/tools/libxl/libxl_utils.h > ... > > +int libxl_read_sysfs_file_contents(libxl_ctx *ctx, const char *filename, > > + void **data_r, int *datalen_r); > > I think this is a function with sufficiently odd semantics, and a > sufficiently internal purpose, that it should probably not be exposed > in the API. So move to libxl_internal.h? Or not hacking here but just adding an internal function in libxl_pvusb.c with repeated codes? > > Ian > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel > > ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 2/7] libxl_read_file_contents: add new entry to read sysfs file 2015-06-12 7:00 ` Chun Yan Liu @ 2015-06-12 15:11 ` Ian Jackson 0 siblings, 0 replies; 88+ messages in thread From: Ian Jackson @ 2015-06-12 15:11 UTC (permalink / raw) To: Chun Yan Liu; +Cc: george.dunlap, wei.liu2, ian.campbell, xen-devel Chun Yan Liu writes ("Re: [Xen-devel] [PATCH V4 2/7] libxl_read_file_contents: add new entry to read sysfs file"): > <21881.46148.466883.923039@mariner.uk.xensource.com>, Ian Jackson > <Ian.Jackson@eu.citrix.com> wrote: > > Chunyan Liu writes ("[Xen-devel] [PATCH V4 2/7] libxl_read_file_contents: add > > What is this for ? > > I found sometimes reading sysfs file contents, at the end, there is > some random character. With this line, there is no problem then. I'm afraid that's not really a complete explanation. Guessing, I think your calling code expected a trailing nul. If you want to make an API which is useable for such code, and not intended for byte blocks, that's fine, but you must then always nul-terminate (not only if the data was less than 4k) and your new function probably doesn't want to return a length at all. > > Is there any risk that the file is actually bigger than advertised, > > rather than smaller ? > > For sysfs file, couldn't be bigger. Then you should detect the condition that the file is bigger, and call it an error. > > > +int libxl_read_sysfs_file_contents(libxl_ctx *ctx, const char *filename, > > > + void **data_r, int *datalen_r); > > > > I think this is a function with sufficiently odd semantics, and a > > sufficiently internal purpose, that it should probably not be exposed > > in the API. > > So move to libxl_internal.h? Or not hacking here but just adding an internal > function in libxl_pvusb.c with repeated codes? I meant to move it to libxl_internal.h. Subject to consideration of what its API ought to be. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* [PATCH V4 3/7] libxl: add pvusb API 2015-06-10 3:20 [PATCH V4 0/7] xen pvusb toolstack work Chunyan Liu 2015-06-10 3:20 ` [PATCH V4 1/7] libxl: export some functions for pvusb use Chunyan Liu 2015-06-10 3:20 ` [PATCH V4 2/7] libxl_read_file_contents: add new entry to read sysfs file Chunyan Liu @ 2015-06-10 3:20 ` Chunyan Liu 2015-06-11 15:00 ` Juergen Gross ` (3 more replies) 2015-06-10 3:20 ` [PATCH V4 4/7] libxl: add libxl_device_usb_assignable_list API Chunyan Liu ` (3 subsequent siblings) 6 siblings, 4 replies; 88+ messages in thread From: Chunyan Liu @ 2015-06-10 3:20 UTC (permalink / raw) To: xen-devel Cc: wei.liu2, ian.campbell, george.dunlap, Ian.Jackson, Chunyan Liu, Simon Cao Add pvusb APIs, including: - attach/detach (create/destroy) virtual usb controller. - attach/detach usb device - list usb controller and usb devices - some other helper functions Signed-off-by: Chunyan Liu <cyliu@suse.com> Signed-off-by: Simon Cao <caobosimon@gmail.com> --- changes: - make libxl_device_usbctrl_add async, to be consistent with libxl_device_usbctrl_remove, using MACROs DEFINE_DEVICE_ADD and DEFINE_DEVICES_ADD, adjusting related codes. - correct update_json related processing. - use libxl__* helper functions instead of calloc, realloc and strdup, etc. whereever possible. - merge protocol definition pv|qemu in this patch - treat it as warning at rebind failure instead of error in usb_remove - add documentation docs/misc/pvusb.txt to describe pvusb details (toolstack design, libxl design, xenstore info, etc.) - other fixes addring Wei and George's comments docs/misc/pvusb.txt | 243 +++++++ tools/libxl/Makefile | 2 +- tools/libxl/libxl.c | 6 + tools/libxl/libxl.h | 65 ++ tools/libxl/libxl_internal.h | 16 +- tools/libxl/libxl_osdeps.h | 13 + tools/libxl/libxl_pvusb.c | 1249 ++++++++++++++++++++++++++++++++++ tools/libxl/libxl_types.idl | 52 ++ tools/libxl/libxl_types_internal.idl | 1 + tools/libxl/libxl_utils.c | 16 + 10 files changed, 1661 insertions(+), 2 deletions(-) create mode 100644 docs/misc/pvusb.txt create mode 100644 tools/libxl/libxl_pvusb.c diff --git a/docs/misc/pvusb.txt b/docs/misc/pvusb.txt new file mode 100644 index 0000000..4cdf965 --- /dev/null +++ b/docs/misc/pvusb.txt @@ -0,0 +1,243 @@ +1. Overview + +There are two general methods for passing through individual host +devices to a guest. The first is via an emulated USB device +controller; the second is PVUSB. + +Additionally, there are two ways to add USB devices to a guest: via +the config file at domain creation time, and via hot-plug while the VM +is running. + +* Emulated USB + +In emulated USB, the device model (qemu) presents an emulated USB +controller to the guest. The device model process then grabs control +of the device from domain 0 and and passes the USB commands between +the guest OS and the host USB device. + +This method is only available to HVM domains, and is not available for +domains running with device model stubdomains. + +* PVUSB + +PVUSB uses a paravirtialized front-end/back-end interface, similar to +the traditional Xen PV network and disk protocols. In order to use +PVUSB, you need usbfront in your guest OS, and usbback in dom0 (or +your USB driver domain). + +Additionally, for easy use of PVUSB, you need support in the toolstack +to get the two sides to talk to each other. + +2. Specifying a host USB device + +QEMU hmp commands allows USB devices to be specified either by their +bus address (in the form bus.device) or their device tag (in the form +vendorid:deviceid). + +Each way of specifying has its advantages: + + Specifying by device tag will always get the same device, +regardless of where the device ends up in the USB bus topology. +However, if there are two identical devices, it will not allow you to +specify which one. + + Specifying by bus address will always allow you to choose a +specific device, even if you have duplicates. However, the bus address +may change depending on which port you plugged the device into, and +possibly also after a reboot. + +To avoid duplication of vendorid:deviceid, we'll use bus address to +specify host USB device in xl toolstack. + +You can use lsusb to list the USB devices on the system: + +Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 +Hub +Bus 003 Device 002: ID f617:0905 +Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub +Bus 001 Device 004: ID 0424:2640 Standard Microsystems Corp. USB 2.0 +Hub +Bus 001 Device 005: ID 0424:4060 Standard Microsystems Corp. Ultra +Fast Media Reader +Bus 001 Device 006: ID 046d:c016 Logitech, Inc. Optical Wheel Mouse + +To pass through the Logitec mouse, for instance, you could specify +1.6 (remove leading zeroes). + +Note: USB Hub could not be assigned to guest. + +3. PVUSB toolstack + +* Specify USB device in xl config file + +You can just specify usb devices, like: +usbdev=['1.6'] + +Then it will create a USB controller automatically and attach the USB +device to the first available USB controller:port. + +or, you can explicitly specify usb controllers and usb devices, like: +usbctrl=['verison=1, ports=4', 'version=2, ports=8', ] +usbdev=['1.6, controller=0, port=1'] + +Then it will create two USB controllers as you specified. +And if controller and port are specified in usb config, then it will +attach the USB device to that controller:port. About the controller +and port value: +Each USB controller has a index (or called devid) based on 0. The 1st +controller has index 0, the 2nd controller has index 1, ... +Under controller, each port has a port number based on 1. In above +configuration, the 1st controller will have port 1,2,3,4. + +* Hot-Plug USB device + +To attach a USB device, you should first create a USB controller. +e.g. +xl usb-ctrl-attach domain [version=1|2] [ports=value] +By default, it will create a USB2.0 controller with 8 ports. + +Then you could attach a USB device. +e.g. +xl usb-attach domain 1.6 [controller=index port=number] +By default, it will find the 1st available controller:port to attach +the USB device. + +You could view USB device status of the domain by usb-list. +e.g. +xl usb-list domain +It will list USB controllers and USB devices under each controller. + +You could detach a USB device with usb-detach command. +e.g. +xl usb-detach domain 1.6 + +You can also remove the whole USB controller by usb-ctrl-detach +command. +e.g. +xl usb-ctrl-detach domain 0 +It will remove the USB controller with index 0 and all USB devices +under it. + +4. PVUSB Libxl implementation + +* usb-ctrl-attach +To create a usb controller, we need: +1) generate usb controler related information +2) write usb controller frontend/backend info to xenstore +PVUSB frontend and backend driver will probe xenstore paths and build +connection between frontend and backend. + +* usb-ctrl-detach +To remove a usb controller, we need: +1) check if the usb controller exists or not +2) remove all usb devices under controller +3) remove usb controller info from xenstore + +* usb-attach +To attach a usb device, we need: +1) check if the usb device type is assignable +2) check if the usb device is already assigned to a domain +3) add 'busid' of the usb device to xenstore contoller/port/. + PVUSB driver watches the xenstore changes and detects that, + and needs to use 'busid' to do following work. +4) unbind usb device from original driver and bind to usbback. + If usb device has many interfaces, then: + - unbind each interface from its original driver and bind to usbback. + - store the original driver to xenstore for later rebinding when + detaching the device. + +* usb-detach +To detach a usb device, we need: +1) check if the usb device is assigned to the domain +2) remove the usb device from xenstore controller/port. +3) unbind usb device from usbback and rebind to its original driver. + If usb device has many interfaces, do it to each interface. + +* usb-list +List all USB controllers and USB devices under each controller. + +5. PVUSB xenstore information + +PVUSB xenstore information includes three parts: frontend, backend +and /libxl part. + +A USB controller is corresponding to a "vusb" device in xenstore. +Adding a USB controller will add a new "vusb" device, removing a +USB controller will delete the related "vusb" device. + +Following is an example xenstore values of a USB controller. +Backend: + backend = "" + vusb = "" + 1 = "" + 0 = "" + frontend = "/local/domain/1/device/vusb/0" + frontend-id = "1" + online = "1" + state = "4" + type = "pv" + usb-ver = "1" + num-ports = "4" + port = "" + 1 = "" + 2 = "" + 3 = "" + 4 = "" + +Frontend: + device = "" + vusb = "" + 0 = "" + backend = "/local/domain/0/backend/vusb/1/0" + backend-id = "0" + state = "4" + urb-ring-ref = "348" + conn-ring-ref = "346" + event-channel = "20" + +Adding a USB device won't create a new "vusb" device, but only write +the USB device busid to one port of USB controller. +For example, attaching a USB device (busid is 2-1.6) to above USB +controller port 1, it only need write 2-1.6 to port 1 of this USB +controller: +Backend: + backend = "" + vusb = "" + 1 = "" + 0 = "" + frontend = "/local/domain/1/device/vusb/0" + frontend-id = "1" + online = "1" + state = "4" + type = "pv" + usb-ver = "1" + num-ports = "4" + port = "" + 1 = "2-1.6" + 2 = "" + 3 = "" + 4 = "" +Frontend doesn't change. + +Since assign a host USB device to guest, we'll unbind USB interfaces +from their original drivers and bind them to usbback. After detaching +this USB device from guest, one would hope the USB interfaces could +be rebind to their original drivers, so there should some place to +get the original driver info. To support that, when attaching a USB +device to guest, we'll save the original driver info in xenstore too, +the place is /libxl/usbback, for example: +libxl = "" + 1 = "" + dm-version = "qemu_xen" + usbback = "" + 3-11 = "" + 3-11-1_0 = "" + driver_path = "/sys/bus/usb/drivers/btusb" + +In this example, USB device (busid is 3-11, /sys/bus/usb/devices/3-11). +It has interface 3-11:1.0, whose original dirver is btusb. +Since xenstore doesn't allow ':' and '.' in a key, so we encode the +interface by changing ':' to '-' and changing '.' to '_'. + +When detaching the USB device from guest, we can rebind 3-11:1.0 to +btusb driver. diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile index cc9c152..b820105 100644 --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -95,7 +95,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \ libxl_internal.o libxl_utils.o libxl_uuid.o \ libxl_json.o libxl_aoutils.o libxl_numa.o libxl_vnuma.o \ libxl_save_callout.o _libxl_save_msgs_callout.o \ - libxl_qmp.o libxl_event.o libxl_fork.o $(LIBXL_OBJS-y) + libxl_qmp.o libxl_event.o libxl_fork.o libxl_pvusb.o $(LIBXL_OBJS-y) LIBXL_OBJS += libxl_genid.o LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index bd4daea..f9331f4 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1611,6 +1611,8 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis) if (libxl__device_pci_destroy_all(gc, domid) < 0) LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "pci shutdown failed for domid %d", domid); + if (libxl__device_usb_destroy_all(gc, domid) < 0) + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "usb shutdown failed for domid %d", domid); rc = xc_domain_pause(ctx->xch, domid); if (rc < 0) { LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "xc_domain_pause failed for %d", domid); @@ -6760,6 +6762,10 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid, MERGE(pci, pcidevs, COMPARE_PCI, {}); + MERGE(usbctrl, usbctrls, COMPARE_USBCTRL, {}); + + MERGE(usb, usbs, COMPARE_USB, {}); + /* Take care of removable device. We maintain invariant in the * insert / remove operation so that: * 1. if xenstore is "empty" while JSON is not, the result diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index 0a7913b..d192300 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -123,6 +123,23 @@ #define LIBXL_HAVE_DOMAIN_NODEAFFINITY 1 /* + * LIBXL_HAVE_PVUSB indicates the functions for doing hot-plug of + * USB devices through pvusb. + * + * With this functionality, one can add/remove USB controllers to/from + * guest, and attach/detach USB devices to/from USB controllers. To add + * USB controllers and USB devices, one can either adding USB controllers + * first and then attaching USB devices to some USB controller, or adding + * USB devices to guest directly, it will automatically create a USB + * controller for USB devices to attach. To remove USB controllers or USB + * devices, one can either remove USB devices under USB controller one by + * one and then remove USB controller, or remove USB controller directly, + * it will remove all USB devices under it automatically. + * + */ +#define LIBXL_HAVE_PVUSB 1 + +/* * LIBXL_HAVE_BUILDINFO_HVM_VENDOR_DEVICE indicates that the * libxl_vendor_device field is present in the hvm sections of * libxl_domain_build_info. This field tells libxl which @@ -1269,6 +1286,54 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, const libxl_asyncop_how *ao_how) LIBXL_EXTERNAL_CALLERS_ONLY; +/* USB Controllers*/ +int libxl_device_usbctrl_add(libxl_ctx *ctx, uint32_t domid, + libxl_device_usbctrl *usbctrl, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; + +int libxl_device_usbctrl_remove(libxl_ctx *ctx, uint32_t domid, + libxl_device_usbctrl *usbctrl, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; + +int libxl_device_usbctrl_destroy(libxl_ctx *ctx, uint32_t domid, + libxl_device_usbctrl *usbctrl, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; + +libxl_device_usbctrl *libxl_device_usbctrl_list(libxl_ctx *ctx, + uint32_t domid, int *num); + +void libxl_device_usbctrl_list_free(libxl_device_usbctrl* list, int nr); + + +int libxl_device_usbctrl_getinfo(libxl_ctx *ctx, uint32_t domid, + libxl_device_usbctrl *usbctrl, + libxl_usbctrlinfo *usbctrlinfo) + LIBXL_EXTERNAL_CALLERS_ONLY; + +/* USB Devices */ +int libxl_device_usb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_usb *usb, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; + +int libxl_device_usb_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_usb *usb, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; + +libxl_device_usb * +libxl_device_usb_list(libxl_ctx *ctx, uint32_t domid, int *num); + +libxl_device_usb * +libxl_device_usb_list_per_usbctrl(libxl_ctx *ctx, uint32_t domid, + int usbctrl, int *num); + +void libxl_device_usb_list_free(libxl_device_usb* list, int nr); + +int libxl_device_usb_getinfo(libxl_ctx *ctx, libxl_device_usb *usb, + libxl_usbinfo *usbinfo) + 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 ef7aa1d..89a9f07 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -2439,6 +2439,18 @@ _hidden void libxl__device_vtpm_add(libxl__egc *egc, uint32_t domid, libxl_device_vtpm *vtpm, libxl__ao_device *aodev); +/* AO operation to connect a PVUSB controller. + * Adding a PVUSB controller will add a 'vusb' device entry in xenstore, + * and will wait for device connection. + */ +_hidden void libxl__device_usbctrl_add(libxl__egc *egc, uint32_t domid, + libxl_device_usbctrl *usbctrl, + libxl__ao_device *aodev); +_hidden int libxl__device_usb_add(libxl__gc *gc, uint32_t domid, + libxl_device_usb *usb, + bool update_json); +_hidden int libxl__device_usb_destroy_all(libxl__gc *gc, uint32_t domid); + /* Internal function to connect a vkb device */ _hidden int libxl__device_vkb_add(libxl__gc *gc, uint32_t domid, libxl_device_vkb *vkb); @@ -3646,7 +3658,9 @@ static inline void libxl__update_config_vtpm(libxl__gc *gc, #define COMPARE_PCI(a, b) ((a)->func == (b)->func && \ (a)->bus == (b)->bus && \ (a)->dev == (b)->dev) - +#define COMPARE_USB(a, b) (!strcmp((a)->busid, (b)->busid)) +#define COMPARE_USBCTRL(a, b) ((a)->devid == (b)->devid) + /* DEVICE_ADD * * Add a device in libxl_domain_config structure diff --git a/tools/libxl/libxl_osdeps.h b/tools/libxl/libxl_osdeps.h index 08eaf0c..55caf71 100644 --- a/tools/libxl/libxl_osdeps.h +++ b/tools/libxl/libxl_osdeps.h @@ -24,6 +24,8 @@ #define _GNU_SOURCE #if defined(__NetBSD__) +#define SYSFS_USB_DEV "/sys/bus/usb/devices" +#define SYSFS_USBBACK_DRIVER "/kern/xen/usb" #define SYSFS_PCI_DEV "/sys/bus/pci/devices" #define SYSFS_PCIBACK_DRIVER "/kern/xen/pci" #define NETBACK_NIC_NAME "xvif%ui%d" @@ -31,6 +33,8 @@ #elif defined(__OpenBSD__) #include <util.h> #elif defined(__linux__) +#define SYSFS_USB_DEV "/sys/bus/usb/devices" +#define SYSFS_USBBACK_DRIVER "/sys/bus/usb/drivers/usbback" #define SYSFS_PCI_DEV "/sys/bus/pci/devices" #define SYSFS_PCIBACK_DRIVER "/sys/bus/pci/drivers/pciback" #define NETBACK_NIC_NAME "vif%u.%d" @@ -38,12 +42,21 @@ #elif defined(__sun__) #include <stropts.h> #elif defined(__FreeBSD__) +#define SYSFS_USB_DEV "/dev/null" +#define SYSFS_USBBACK_DRIVER "/dev/null" #define SYSFS_PCI_DEV "/dev/null" #define SYSFS_PCIBACK_DRIVER "/dev/null" #define NETBACK_NIC_NAME "xnb%u.%d" #include <libutil.h> #endif +#ifndef SYSFS_USBBACK_DRIVER +#error define SYSFS_USBBACK_DRIVER for your platform +#endif +#ifndef SYSFS_USB_DEV +#error define SYSFS_USB_DEV for your platform +#endif + #ifndef SYSFS_PCIBACK_DRIVER #error define SYSFS_PCIBACK_DRIVER for your platform #endif diff --git a/tools/libxl/libxl_pvusb.c b/tools/libxl/libxl_pvusb.c new file mode 100644 index 0000000..a6e1aa1 --- /dev/null +++ b/tools/libxl/libxl_pvusb.c @@ -0,0 +1,1249 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +#include "libxl_osdeps.h" /* must come before any other headers */ + +#include "libxl_internal.h" + +#define USBBACK_INFO_PATH "/libxl/usbback" + +#define USBHUB_CLASS_CODE 0x09 + +static int libxl__device_usbctrl_setdefault(libxl__gc *gc, uint32_t domid, + libxl_device_usbctrl *usbctrl) +{ + int rc; + + if (!usbctrl->version) + usbctrl->version = 2; + + if (!usbctrl->ports) + usbctrl->ports = 8; + + if (usbctrl->protocol == LIBXL_USB_PROTOCOL_AUTO) + usbctrl->protocol = LIBXL_USB_PROTOCOL_PV; + + rc = libxl__resolve_domid(gc, usbctrl->backend_domname, + &usbctrl->backend_domid); + return rc; +} + +static int libxl__device_from_usbctrl(libxl__gc *gc, uint32_t domid, + libxl_device_usbctrl *usbctrl, + libxl__device *device) +{ + device->backend_devid = usbctrl->devid; + device->backend_domid = usbctrl->backend_domid; + device->backend_kind = LIBXL__DEVICE_KIND_VUSB; + device->devid = usbctrl->devid; + device->domid = domid; + device->kind = LIBXL__DEVICE_KIND_VUSB; + + return 0; +} + +void libxl__device_usbctrl_add(libxl__egc *egc, uint32_t domid, + libxl_device_usbctrl *usbctrl, + libxl__ao_device *aodev) +{ + STATE_AO_GC(aodev->ao); + flexarray_t *front; + flexarray_t *back; + libxl__device *device; + xs_transaction_t t = XBT_NULL; + char *path; + int i, rc; + libxl_domain_config d_config; + libxl_device_usbctrl usbctrl_saved; + libxl__domain_userdata_lock *lock = NULL; + + rc = libxl__device_usbctrl_setdefault(gc, domid, usbctrl); + if (rc < 0) goto out; + + if (usbctrl->devid == -1) { + usbctrl->devid = libxl__device_nextid(gc, domid, "vusb"); + if (usbctrl->devid < 0) { + rc = ERROR_FAIL; + goto out; + } + } + + libxl_domain_config_init(&d_config); + libxl_device_usbctrl_init(&usbctrl_saved); + libxl_device_usbctrl_copy(CTX, &usbctrl_saved, usbctrl); + + GCNEW(device); + rc = libxl__device_from_usbctrl(gc, domid, usbctrl, device); + if (rc) goto out; + + front = flexarray_make(gc, 4, 1); + back = flexarray_make(gc, 12, 1); + + flexarray_append_pair(back, "frontend-id", GCSPRINTF("%d", domid)); + flexarray_append_pair(back, "online", "1"); + flexarray_append_pair(back, "state", "1"); + flexarray_append_pair(back, "type", + (char *)libxl_usb_protocol_to_string(usbctrl->protocol)); + flexarray_append_pair(back, "usb-ver", GCSPRINTF("%d", usbctrl->version)); + flexarray_append_pair(back, "num-ports", GCSPRINTF("%d", usbctrl->ports)); + flexarray_append_pair(front, "backend-id", + GCSPRINTF("%d", usbctrl->backend_domid)); + flexarray_append_pair(front, "state", "1"); + + if (aodev->update_json) { + lock = libxl__lock_domain_userdata(gc, domid); + if (!lock) { + rc = ERROR_LOCK_FAIL; + goto out; + } + + rc = libxl__get_domain_configuration(gc, domid, &d_config); + if (rc) goto out; + + DEVICE_ADD(usbctrl, usbctrls, domid, &usbctrl_saved, + COMPARE_USBCTRL, &d_config); + } + + for (;;) { + rc = libxl__xs_transaction_start(gc, &t); + if (rc) goto out; + + rc = libxl__device_exists(gc, t, device); + if (rc < 0) goto out; + if (rc == 1) { + /* already exists in xenstore */ + LOG(ERROR, "device already exists in xenstore"); + rc = ERROR_DEVICE_EXISTS; + goto out; + } + + if (aodev->update_json) { + rc = libxl__set_domain_configuration(gc, domid, &d_config); + if (rc) goto out; + } + + libxl__device_generic_add(gc, t, device, + libxl__xs_kvs_of_flexarray(gc, back, back->count), + libxl__xs_kvs_of_flexarray(gc, front, front->count), + NULL); + + path = GCSPRINTF("%s/port", libxl__device_backend_path(gc, device)); + libxl__xs_mkdir(gc, t, path, NULL, 0); + for (i = 0; i < usbctrl->ports; i++) { + rc = libxl__xs_write_checked(gc, t, + GCSPRINTF("%s/%d", path, i + 1), ""); + if (rc) goto out; + } + + rc = libxl__xs_transaction_commit(gc, &t); + if (!rc) break; + if (rc < 0) goto out; + } + + aodev->dev = device; + aodev->action = LIBXL__DEVICE_ACTION_ADD; + libxl__wait_device_connection(egc, aodev); + + rc = 0; + +out: + libxl__xs_transaction_abort(gc, &t); + if (lock) libxl__unlock_domain_userdata(lock); + libxl_device_usbctrl_dispose(&usbctrl_saved); + libxl_domain_config_dispose(&d_config); + aodev->rc = rc; + if (rc) aodev->callback(egc, aodev); + return; +} + +static int libxl_device_usbctrl_add_common(libxl_ctx *ctx, + uint32_t domid, + libxl_device_usbctrl *usbctrl, + const libxl_asyncop_how *ao_how, + bool update_json) +{ + AO_CREATE(ctx, domid, ao_how); + libxl__ao_device *aodev; + + GCNEW(aodev); + libxl__prepare_ao_device(ao, aodev); + aodev->action = LIBXL__DEVICE_ACTION_ADD; + aodev->callback = device_addrm_aocomplete; + aodev->update_json = update_json; + libxl__device_usbctrl_add(egc, domid, usbctrl, aodev); + + return AO_INPROGRESS; +} + +int libxl_device_usbctrl_add(libxl_ctx *ctx, uint32_t domid, + libxl_device_usbctrl *usbctrl, + const libxl_asyncop_how *ao_how) +{ + return libxl_device_usbctrl_add_common(ctx, domid, usbctrl, ao_how, 1); +} + +static int +libxl__device_usb_list_per_usbctrl(libxl__gc *gc, uint32_t domid, int usbctrl, + libxl_device_usb **usbs, int *num); + +static int +do_usb_remove(libxl__gc *gc, uint32_t domid, libxl_device_usb *usb); + +static int +libxl_device_usbctrl_remove_common(libxl_ctx *ctx, uint32_t domid, + libxl_device_usbctrl *usbctrl, + const libxl_asyncop_how *ao_how, + int force) +{ + AO_CREATE(ctx, domid, ao_how); + libxl__device *device; + libxl__ao_device *aodev; + libxl_device_usbctrl *usbctrls = NULL; + libxl_device_usbctrl *usbctrl_find = NULL; + int numctrl = 0; + libxl_device_usb *usbs = NULL; + int numusb = 0; + int i, rc; + + usbctrls = libxl_device_usbctrl_list(ctx, domid, &numctrl); + if (!numctrl) { + LOG(ERROR, "No USB controller exists in this domain"); + rc = ERROR_FAIL; + goto out; + } + + for (i = 0; i < numctrl; i++) { + if (usbctrl->devid == usbctrls[i].devid) { + usbctrl_find = usbctrls + i; + break; + } + } + + if (!usbctrl_find) { + LOG(ERROR, "USB controller %d is not attached to this domain", + usbctrl->devid); + rc = ERROR_FAIL; + goto out; + } + + GCNEW(device); + libxl__device_from_usbctrl(gc, domid, usbctrl_find, device); + + /* Remove usb devices first */ + rc = libxl__device_usb_list_per_usbctrl(gc, domid, usbctrl->devid, + &usbs, &numusb); + if (rc) goto out; + + for (i = 0; i < numusb; i++) { + if (do_usb_remove(gc, domid, &usbs[i])) { + LOG(ERROR, "do_usb_remove failed"); + rc = ERROR_FAIL; + goto out; + } + } + + /* Remove usbctrl */ + GCNEW(aodev); + libxl__prepare_ao_device(ao, aodev); + aodev->action = LIBXL__DEVICE_ACTION_REMOVE; + aodev->dev = device; + aodev->callback = device_addrm_aocomplete; + aodev->force = force; + libxl__initiate_device_remove(egc, aodev); + +out: + libxl_device_usbctrl_list_free(usbctrls, numctrl); + libxl_device_usb_list_free(usbs, numusb); + if (rc) return AO_ABORT(rc); + return AO_INPROGRESS; +} + +int libxl_device_usbctrl_remove(libxl_ctx *ctx, uint32_t domid, + libxl_device_usbctrl *usbctrl, + const libxl_asyncop_how *ao_how) +{ + return libxl_device_usbctrl_remove_common(ctx, domid, usbctrl, ao_how, 0); +} + +int libxl_device_usbctrl_destroy(libxl_ctx *ctx, uint32_t domid, + libxl_device_usbctrl *usbctrl, + const libxl_asyncop_how *ao_how) +{ + return libxl_device_usbctrl_remove_common(ctx, domid, usbctrl, ao_how, 1); +} + +libxl_device_usbctrl * +libxl_device_usbctrl_list(libxl_ctx *ctx, uint32_t domid, int *num) +{ + GC_INIT(ctx); + libxl_device_usbctrl *usbctrls = NULL; + char *fe_path = NULL; + char **dir = NULL; + unsigned int ndirs = 0; + + *num = 0; + + fe_path = GCSPRINTF("%s/device/vusb", + libxl__xs_get_dompath(gc, domid)); + dir = libxl__xs_directory(gc, XBT_NULL, fe_path, &ndirs); + + if (dir && ndirs) { + usbctrls = malloc(sizeof(*usbctrls) * ndirs); + libxl_device_usbctrl* usbctrl; + libxl_device_usbctrl* end = usbctrls + ndirs; + for (usbctrl = usbctrls; usbctrl < end; usbctrl++, dir++, (*num)++) { + char *tmp; + const char *be_path = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/%s/backend", fe_path, *dir)); + + libxl_device_usbctrl_init(usbctrl); + usbctrl->devid = atoi(*dir); + + tmp = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/%s/backend-id", fe_path, *dir)); + if (!tmp) goto outerr; + usbctrl->backend_domid = atoi(tmp); + + tmp = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/usb-ver", be_path)); + if (!tmp) goto outerr; + usbctrl->version = atoi(tmp); + + tmp = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/num-ports", be_path)); + if (!tmp) goto outerr; + usbctrl->ports = atoi(tmp); + + tmp = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/type", be_path)); + if (!tmp || + libxl_usb_protocol_from_string(tmp, &usbctrl->protocol)) + goto outerr; + } + } + + goto out; + +outerr: + LOG(ERROR, "Unable to list USB Controllers"); + libxl_device_usbctrl_list_free(usbctrls, *num); + *num = 0; + usbctrls = NULL; + +out: + GC_FREE; + return usbctrls; +} + +int libxl_device_usbctrl_getinfo(libxl_ctx *ctx, uint32_t domid, + libxl_device_usbctrl *usbctrl, + libxl_usbctrlinfo *usbctrlinfo) +{ + GC_INIT(ctx); + char *dompath, *usbctrlpath; + char *val; + int rc = 0; + + usbctrlinfo->devid = usbctrl->devid; + usbctrlinfo->ports = usbctrl->ports; + usbctrlinfo->version = usbctrl->version; + usbctrlinfo->protocol = usbctrl->protocol; + + dompath = libxl__xs_get_dompath(gc, domid); + usbctrlpath = GCSPRINTF("%s/device/vusb/%d", dompath, usbctrlinfo->devid); + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/backend", usbctrlpath)); + usbctrlinfo->backend = libxl__strdup(NOGC, val); + if (!usbctrlinfo->backend) { + rc = ERROR_FAIL; + goto out; + } + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/backend-id", usbctrlpath)); + usbctrlinfo->backend_id = val ? strtoul(val, NULL, 10) : -1; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/state", usbctrlpath)); + usbctrlinfo->state = val ? strtoul(val, NULL, 10) : -1; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/event-channel", usbctrlpath)); + usbctrlinfo->evtch = val ? strtoul(val, NULL, 10) : -1; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/urb-ring-ref", usbctrlpath)); + usbctrlinfo->ref_urb = val ? strtoul(val, NULL, 10) : -1; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/conn-ring-ref", usbctrlpath)); + usbctrlinfo->ref_conn= val ? strtoul(val, NULL, 10) : -1; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/frontend", usbctrlinfo->backend)); + usbctrlinfo->frontend = libxl__strdup(NOGC, val); + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/frontend-id", usbctrlinfo->backend)); + usbctrlinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1; + +out: + GC_FREE; + return rc; +} + +static char *usb_busaddr_to_busid(libxl__gc *gc, int bus, int addr) +{ + libxl_ctx *ctx = CTX; + struct dirent *de; + DIR *dir; + char *busid = NULL; + + assert((bus > 0) && (addr > 0)); + + if (!(dir = opendir(SYSFS_USB_DEV))) + return NULL; + + while((de = readdir(dir))) { + char *filename; + void *buf; + int busnum = -1; + int devnum = -1; + + if (!de->d_name) + continue; + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/devnum", de->d_name); + if (!libxl_read_sysfs_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", &devnum); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/busnum", de->d_name); + if (!libxl_read_sysfs_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", &busnum); + + if (bus == busnum && addr == devnum) { + busid = libxl__strdup(NOGC, de->d_name); + break; + } + } + + closedir(dir); + return busid; +} + +static void usb_busaddr_from_busid(libxl__gc *gc, char *busid, + int *bus, int *addr) +{ + libxl_ctx *ctx = CTX; + char *filename; + void *buf; + + assert(busid); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/devnum", busid); + if (!libxl_read_sysfs_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", bus); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/busnum", busid); + if (!libxl_read_sysfs_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", addr); +} + +static int +libxl__device_usb_assigned_list(libxl__gc *gc, + libxl_device_usb **list, int *num) +{ + char **domlist; + unsigned int nd = 0, i, j; + char *be_path; + libxl_device_usb *usb; + + *list = NULL; + *num = 0; + + domlist = libxl__xs_directory(gc, XBT_NULL, "/local/domain", &nd); + be_path = GCSPRINTF("/local/domain/%d/backend/vusb", LIBXL_TOOLSTACK_DOMID); + for (i = 0; i < nd; i++) { + char *path, *num_ports, **ctrl_list; + unsigned int nc = 0; + path = GCSPRINTF("%s/%s", be_path, domlist[i]); + ctrl_list = libxl__xs_directory(gc, XBT_NULL, path , &nc); + + for (j = 0; j < nc; j++) { + path = GCSPRINTF("%s/%s/%s/num-ports", be_path, + domlist[i], ctrl_list[j]); + num_ports = libxl__xs_read(gc, XBT_NULL, path); + if (num_ports) { + int nport = atoi(num_ports), k; + char *devpath, *busid; + + for (k = 0; k < nport; k++) { + devpath = GCSPRINTF("%s/%s/%s/port/%u", be_path, + domlist[i], ctrl_list[j], k + 1); + busid = libxl__xs_read(gc, XBT_NULL, devpath); + /* If there are USB device attached, add it to list */ + if (busid && strcmp(busid, "")) { + GCREALLOC_ARRAY(*list, *num + 1); + usb = *list + *num; + usb->ctrl = atoi(ctrl_list[j]); + usb->port = k + 1; + usb->busid = libxl__strdup(gc, busid); + usb_busaddr_from_busid(gc, usb->busid, + &usb->hostbus, &usb->hostaddr); + (*num)++; + } + } + } + } + } + + return 0; +} + +static bool is_usb_in_array(libxl_device_usb *usbs, int num, + libxl_device_usb *usb) +{ + int i; + + for (i = 0; i < num; i++) { + if (COMPARE_USB(&usbs[i], usb)) + return true; + } + + return false; +} + +/* check if USB device is already assigned to a domain */ +static bool is_usb_assigned(libxl__gc *gc, libxl_device_usb *usb) +{ + libxl_device_usb *usbs; + int rc, num; + + rc = libxl__device_usb_assigned_list(gc, &usbs, &num); + if (rc) { + LOG(ERROR, "Fail to get assigned usb list"); + return true; + } + + return is_usb_in_array(usbs, num, usb); +} + +/* check if USB device type is assignable */ +static bool is_usb_assignable(libxl__gc *gc, libxl_device_usb *usb) +{ + libxl_ctx *ctx = CTX; + int classcode; + char *filename; + void *buf = NULL; + + assert(usb->busid); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/bDeviceClass", usb->busid); + if (libxl_read_sysfs_file_contents(ctx, filename, &buf, NULL)) + return false; + + sscanf(buf, "%x", &classcode); + return classcode != USBHUB_CLASS_CODE; +} + +/* get usb devices under certain usb controller */ +static int +libxl__device_usb_list_per_usbctrl(libxl__gc *gc, uint32_t domid, int usbctrl, + libxl_device_usb **usbs, int *num) +{ + char *be_path, *num_devs; + int n, i; + + *usbs = NULL; + *num = 0; + + be_path = GCSPRINTF("%s/backend/vusb/%d/%d", + libxl__xs_get_dompath(gc, LIBXL_TOOLSTACK_DOMID), + domid, usbctrl); + num_devs = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/num-ports", be_path)); + if (!num_devs) + return 0; + + n = atoi(num_devs); + *usbs = libxl__calloc(NOGC, n, sizeof(libxl_device_usb)); + + for (i = 0; i < n; i++) { + char *busid; + libxl_device_usb *usb = NULL; + + busid = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/port/%d", be_path, i + 1)); + if (busid && strcmp(busid, "")) { + usb = *usbs + *num; + usb->ctrl = usbctrl; + usb->port = i + 1; + usb->busid = libxl__strdup(NOGC, busid); + usb_busaddr_from_busid(gc, usb->busid, + &usb->hostbus, &usb->hostaddr); + (*num)++; + } + } + + return 0; +} + +/* get all usb devices of the domain */ +static libxl_device_usb * +libxl__device_usb_list(libxl__gc *gc, uint32_t domid, int *num) +{ + char **usbctrls; + unsigned int nd = 0, i, j; + char *be_path; + int rc; + libxl_device_usb *usbs = NULL; + + *num = 0; + + be_path = GCSPRINTF("/local/domain/%d/backend/vusb/%d", + LIBXL_TOOLSTACK_DOMID, domid); + usbctrls = libxl__xs_directory(gc, XBT_NULL, be_path, &nd); + + for (i = 0; i < nd; i++) { + int nc = 0; + libxl_device_usb *tmp = NULL; + rc = libxl__device_usb_list_per_usbctrl(gc, domid, + atoi(usbctrls[i]), &tmp, &nc); + if (!nc) continue; + + usbs = libxl__realloc(NOGC, usbs, sizeof(*usbs) * (*num + nc)); + for (j = 0; j < nc; j++) { + usbs[*num] = tmp[j]; + usbs[*num].busid = libxl__strdup(NOGC, tmp[j].busid); + (*num)++; + } + libxl_device_usb_list_free(tmp, nc); + } + return usbs; +} + +libxl_device_usb * +libxl_device_usb_list(libxl_ctx *ctx, uint32_t domid, int *num) +{ + GC_INIT(ctx); + libxl_device_usb *usbs = NULL; + + usbs = libxl__device_usb_list(gc, domid, num); + + GC_FREE; + return usbs; +} + +libxl_device_usb * +libxl_device_usb_list_per_usbctrl(libxl_ctx *ctx, uint32_t domid, + int usbctrl, int *num) +{ + GC_INIT(ctx); + libxl_device_usb *usbs = NULL; + + libxl__device_usb_list_per_usbctrl(gc, domid, usbctrl, &usbs, num); + + GC_FREE; + return usbs; +} + +/* find first unused controller:port and give that to usb device */ +static int +libxl__device_usb_set_default_usbctrl(libxl__gc *gc, uint32_t domid, + libxl_device_usb *usb) +{ + libxl_ctx *ctx = CTX; + libxl_device_usbctrl *usbctrls = NULL; + int numctrl = 0; + int i, j, rc = -1; + char *be_path, *tmp; + + usbctrls = libxl_device_usbctrl_list(ctx, domid, &numctrl); + if (!numctrl) + goto out; + + for (i = 0; i < numctrl; i++) { + for (j = 0; j < usbctrls[i].ports; j++) { + be_path = GCSPRINTF("%s/backend/vusb/%d/%d/port/%d", + libxl__xs_get_dompath(gc, LIBXL_TOOLSTACK_DOMID), + domid, usbctrls[i].devid, j + 1); + tmp = libxl__xs_read(gc, XBT_NULL, be_path); + if (tmp && !strcmp(tmp, "")) { + usb->ctrl = usbctrls[i].devid; + usb->port = j + 1; + rc = 0; + break; + } + } + } + +out: + libxl_device_usbctrl_list_free(usbctrls, numctrl); + return rc; +} + +static int libxl__device_usb_setdefault(libxl__gc *gc, uint32_t domid, + libxl_device_usb *usb, + bool update_json) +{ + char *be_path, *tmp; + + if (usb->ctrl == -1) { + int ret = libxl__device_usb_set_default_usbctrl(gc, domid, usb); + /* If no existing ctrl to host this usb device, setup a new one */ + if (ret) { + libxl_device_usbctrl usbctrl; + libxl_device_usbctrl_init(&usbctrl); + if (libxl_device_usbctrl_add_common(CTX, domid, &usbctrl, + 0, update_json)) { + LOG(ERROR, "Failed to create usb controller"); + return ERROR_INVAL; + } + usb->ctrl = usbctrl.devid; + usb->port = 1; + libxl_device_usbctrl_dispose(&usbctrl); + } + } + + be_path = GCSPRINTF("%s/backend/vusb/%d/%d/port/%d", + libxl__xs_get_dompath(gc, LIBXL_TOOLSTACK_DOMID), + domid, usb->ctrl, usb->port); + tmp = libxl__xs_read(gc, XBT_NULL, be_path); + if (!tmp || strcmp(tmp, "")) { + LOG(ERROR, "The controller port isn't available"); + return ERROR_INVAL; + } + + return 0; +} + +static int libxl__device_usb_add_xenstore(libxl__gc *gc, uint32_t domid, + libxl_device_usb *usb, + bool update_json) +{ + char *be_path; + int rc; + xs_transaction_t t = XBT_NULL; + libxl_domain_config d_config; + libxl_device_usb usb_saved; + libxl__domain_userdata_lock *lock = NULL; + + libxl_domain_config_init(&d_config); + libxl_device_usb_init(&usb_saved); + libxl_device_usb_copy(CTX, &usb_saved, usb); + + if (update_json) { + lock = libxl__lock_domain_userdata(gc, domid); + if (!lock) { + rc = ERROR_LOCK_FAIL; + goto out; + } + + rc = libxl__get_domain_configuration(gc, domid, &d_config); + if (rc) goto out; + + DEVICE_ADD(usb, usbs, domid, &usb_saved, COMPARE_USB, &d_config); + } + + for (;;) { + rc = libxl__xs_transaction_start(gc, &t); + if (rc) goto out; + + if (update_json) { + rc = libxl__set_domain_configuration(gc, domid, &d_config); + if (rc) goto out; + } + + be_path = GCSPRINTF("%s/backend/vusb/%d/%d/port/%d", + libxl__xs_get_dompath(gc, LIBXL_TOOLSTACK_DOMID), + domid, usb->ctrl, usb->port); + + LOG(DEBUG, "Adding new usb device to xenstore"); + if (libxl__xs_write_checked(gc, t, be_path, usb->busid)) { + rc = ERROR_FAIL; + goto out; + } + + rc = libxl__xs_transaction_commit(gc, &t); + if (!rc) break; + if (rc < 0) goto out; + } + + rc = 0; + +out: + if (lock) libxl__unlock_domain_userdata(lock); + libxl_device_usb_dispose(&usb_saved); + libxl_domain_config_dispose(&d_config); + return rc; +} + +static int libxl__device_usb_remove_xenstore(libxl__gc *gc, uint32_t domid, + libxl_device_usb *usb) +{ + char *be_path; + + be_path = GCSPRINTF("%s/backend/vusb/%d/%d/port/%d", + libxl__xs_get_dompath(gc, LIBXL_TOOLSTACK_DOMID), + domid, usb->ctrl, usb->port); + LOG(DEBUG, "Removing USB device from xenstore"); + if (libxl__xs_write_checked(gc,XBT_NULL, be_path, "")) + return ERROR_FAIL; + + return 0; +} + +/* bind/unbind usb device interface */ +static int unbind_usb_intf(libxl__gc *gc, char *intf, char **drvpath) +{ + char *path, *spath, *dp = NULL; + int fd = -1; + int rc = 0; + struct stat st; + + spath = GCSPRINTF(SYSFS_USB_DEV"/%s/driver", intf); + if (!lstat(spath, &st)) { + /* Find the canonical path to the driver. */ + dp = libxl__zalloc(gc, PATH_MAX); + dp = realpath(spath, dp); + + path = GCSPRINTF("%s/unbind", spath); + fd = open(path, O_WRONLY); + if (fd < 0) + return ERROR_FAIL; + rc = write(fd, intf, strlen(intf)); + close(fd); + if (rc < 0) + return ERROR_FAIL; + } + + if (drvpath) + *drvpath = dp; + + return 0; +} + +static int bind_usb_intf(libxl__gc *gc, char *intf, char *drvpath) +{ + char *path; + struct stat st; + int fd, rc = 0; + + path = GCSPRINTF("%s/%s", drvpath, intf); + rc = lstat(path, &st); + /* already bind, return */ + if (rc == 0) + return 0; + + path = GCSPRINTF("%s/bind", drvpath); + fd = open(path, O_WRONLY); + if (fd < 0) + return ERROR_FAIL; + + rc = write(fd, intf, strlen(intf)); + close(fd); + if (rc < 0) + return ERROR_FAIL; + + return 0; +} + +/* Is usb interface bound to usbback? */ +static int usb_intf_is_assigned(libxl__gc *gc, char *intf) +{ + char *spath; + int rc; + struct stat st; + + spath = GCSPRINTF(SYSFS_USBBACK_DRIVER"/%s", intf); + rc = lstat(spath, &st); + + if (rc == 0) + return 1; + if (rc < 0 && errno == ENOENT) + return 0; + LOGE(ERROR, "Accessing %s", spath); + return -1; +} + +static int usb_get_all_interfaces(libxl__gc *gc, libxl_device_usb *usb, + char ***intfs, int *num) +{ + DIR *dir; + struct dirent *entry; + char *buf; + int rc = 0; + + *intfs = NULL; + *num = 0; + + buf = GCSPRINTF("%s:", usb->busid); + + if (!(dir = opendir(SYSFS_USB_DEV))) { + rc = ERROR_FAIL; + goto out; + } + + while ((entry = readdir(dir)) != NULL) { + if (!strncmp(entry->d_name, buf, strlen(buf))) { + GCREALLOC_ARRAY(*intfs, *num + 1); + if (*intfs == NULL) { + rc = ERROR_FAIL; + goto out; + } + (*intfs)[*num] = libxl__strdup(gc, entry->d_name); + (*num)++; + } + } + + closedir(dir); + +out: + return rc; +} + +/* Cann't write '.' or ':' into Xenstore as key. So, change '.' to '_', + * change ':' to '-'. + */ +static char *usb_interface_xenstore_encode(char *busid) +{ + char *str = strdup(busid); + int i, len = strlen(str); + + for (i = 0; i < len; i++) { + if (str[i] == '.') + str[i] = '_'; + if (str[i] == ':') + str[i] = '-'; + } + return str; +} + +/* unbind usb device from usbback driver, if there are many interfaces + * under the usb device, then check each interface, unbind from usbback + * driver and rebind to original driver + */ +static int usbback_dev_unassign(libxl__gc *gc, libxl_device_usb *usb) +{ + char **intfs = NULL; + char *path; + int num = 0, i; + int rc = 0; + char *usb_encode = NULL; + + if (usb_get_all_interfaces(gc, usb, &intfs, &num) < 0) + return ERROR_FAIL; + + usb_encode = usb_interface_xenstore_encode(usb->busid); + + for (i = 0; i < num; i++) { + char *intf = intfs[i]; + char *drvpath = NULL; + + if (usb_intf_is_assigned(gc, intf) > 0) { + /* unbind interface from usbback driver */ + if (unbind_usb_intf(gc, intf, NULL) < 0) { + rc = ERROR_FAIL; + goto out; + } + } + + /* bind interface to its originial driver */ + drvpath = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF(USBBACK_INFO_PATH"/%s/%s/driver_path", + usb_encode, usb_interface_xenstore_encode(intf))); + if (drvpath && bind_usb_intf(gc, intf, drvpath)) + LOGE(WARN, "Couldn't bind %s to %s", intf, drvpath); + } + + /* finally, remove xs driver path */ + path = GCSPRINTF(USBBACK_INFO_PATH"/%s", usb_encode); + libxl__xs_rm_checked(gc, XBT_NULL, path); + +out: + free(usb_encode); + return rc; +} + +/* bind usb device to "usbback" driver, if there are many interfaces + * under the usb device, check each interface, unbind from original + * driver and bind to usbback driver. + */ +static int usbback_dev_assign(libxl__gc *gc, libxl_device_usb *usb) +{ + char **intfs = NULL; + int num = 0, i; + int rc = 0; + char *usb_encode = NULL; + + if (usb_get_all_interfaces(gc, usb, &intfs, &num) < 0) + return ERROR_FAIL; + + usb_encode = usb_interface_xenstore_encode(usb->busid); + + for (i = 0; i < num; i++) { + char *intf = intfs[i]; + char *path = NULL; + char *drvpath = NULL; + + /* already assigned to usbback */ + if (usb_intf_is_assigned(gc, intf) > 0) + continue; + + /* unbind interface from original driver */ + if (unbind_usb_intf(gc, intf, &drvpath) < 0) { + rc = ERROR_FAIL; + goto out_rebind; + } + + if (drvpath) { + /* write driver path to xenstore for later rebinding */ + path = GCSPRINTF(USBBACK_INFO_PATH"/%s/%s/driver_path", + usb_encode, usb_interface_xenstore_encode(intf)); + if (libxl__xs_write_checked(gc, XBT_NULL, path, drvpath) < 0) { + LOG(WARN, "Write of %s to node %s failed", drvpath, path); + } + } + + /* bind interface to usbback */ + if (bind_usb_intf(gc, intf, SYSFS_USBBACK_DRIVER) < 0) { + LOGE(ERROR, "Couldn't bind %s to %s", intf, SYSFS_USBBACK_DRIVER); + rc = ERROR_FAIL; + goto out_rebind; + } + } + + goto out; + +out_rebind: + /* some interfaces might be bound to usbback, unbind it then and + * rebind to its original driver + */ + usbback_dev_unassign(gc, usb); +out: + free(usb_encode); + return rc; +} + +int libxl__device_usb_add(libxl__gc *gc, uint32_t domid, + libxl_device_usb *usb, + bool update_json) +{ + int rc; + + assert(usb->busid || (usb->hostbus > 0 && usb->hostaddr > 0)); + + if (!usb->busid) { + usb->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); + if (!usb->busid) { + LOG(ERROR, "USB device doesn't exist in sysfs"); + return ERROR_INVAL; + } + } + + if (!is_usb_assignable(gc, usb)) { + LOG(ERROR, "USB device is not assignable."); + rc = ERROR_FAIL; + goto out; + } + + /* check usb device is already assigned */ + if (is_usb_assigned(gc, usb)) { + LOG(ERROR, "USB device is already attached to a domain."); + rc = ERROR_FAIL; + goto out; + } + + rc = libxl__device_usb_setdefault(gc, domid, usb, update_json); + if (rc) goto out; + + rc = libxl__device_usb_add_xenstore(gc, domid, usb, update_json); + if (rc) goto out; + + rc = usbback_dev_assign(gc, usb); + if (rc) + libxl__device_usb_remove_xenstore(gc, domid, usb); + +out: + return rc; +} + +int libxl_device_usb_add(libxl_ctx *ctx, uint32_t domid, + libxl_device_usb *usb, + const libxl_asyncop_how *ao_how) +{ + AO_CREATE(ctx, domid, ao_how); + int rc; + + rc = libxl__device_usb_add(gc, domid, usb, 1); + libxl__ao_complete(egc, ao, rc); + return AO_INPROGRESS; +} + +static int do_usb_remove(libxl__gc *gc, uint32_t domid, + libxl_device_usb *usb) +{ + if (libxl__device_usb_remove_xenstore(gc, domid, usb)) + return -1; + + usbback_dev_unassign(gc, usb); + + return 0; +} + +static int libxl__device_usb_remove(libxl__gc *gc, uint32_t domid, + libxl_device_usb *usb) +{ + libxl_device_usb *usbs = NULL; + libxl_device_usb *usb_find = NULL; + int i, num = 0, rc; + + assert(usb->busid || (usb->hostbus > 0 && usb->hostaddr > 0)); + + if (!usb->busid) { + usb->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); + if (!usb->busid) { + LOG(ERROR, "USB device doesn't exist in sysfs"); + return ERROR_INVAL; + } + } + + usbs = libxl__device_usb_list(gc, domid, &num); + if (!usbs) { + LOG(ERROR, "No USB device attached to this domain"); + return ERROR_FAIL; + } + + for (i = 0; i < num; i++) { + if (COMPARE_USB(usb, &usbs[i])) { + usb_find = usbs + i; + break; + } + } + + /* doesn't find the usb device in domain's usb device list*/ + if (!usb_find) { + LOG(ERROR, "USB device %x.%x is not attached to this domain", + usb->hostbus, usb->hostaddr); + rc = ERROR_FAIL; + goto out; + } + + rc = do_usb_remove(gc, domid, usb_find); + +out: + libxl_device_usb_list_free(usbs, num); + return rc; +} + +int libxl_device_usb_remove(libxl_ctx *ctx, uint32_t domid, + libxl_device_usb *usb, + const libxl_asyncop_how *ao_how) + +{ + AO_CREATE(ctx, domid, ao_how); + int rc; + + rc = libxl__device_usb_remove(gc, domid, usb); + + libxl__ao_complete(egc, ao, rc); + return AO_INPROGRESS; +} + +int libxl__device_usb_destroy_all(libxl__gc *gc, uint32_t domid) +{ + libxl_ctx *ctx = CTX; + libxl_device_usbctrl *usbctrls = NULL; + int i, num = 0, rc = 0; + + usbctrls = libxl_device_usbctrl_list(ctx, domid, &num); + if (!usbctrls) + return 0; + + for (i = 0; i < num; i++) { + /* Force remove on shutdown since, on HVM, qemu will not always + * respond to SCI interrupt because the guest kernel has shut + * down the devices by the time we even get here! + */ + if (libxl_device_usbctrl_remove_common(ctx, domid, + usbctrls + i, 0, 1) < 0) { + rc = ERROR_FAIL; + goto out; + } + } + +out: + libxl_device_usbctrl_list_free(usbctrls, num); + return rc; +} + +int libxl_device_usb_getinfo(libxl_ctx *ctx, libxl_device_usb *usb, + libxl_usbinfo *usbinfo) +{ + GC_INIT(ctx); + char *filename; + void *buf = NULL; + + usbinfo->ctrl = usb->ctrl; + usbinfo->port = usb->port; + + if (usb->busid) + usbinfo->busid = libxl__strdup(NOGC, usb->busid); + else if (usb->hostbus > 0 && usb->hostaddr > 0) + usbinfo->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); + + assert(usbinfo->busid); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/devnum", usbinfo->busid); + if (!libxl_read_sysfs_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", &usbinfo->devnum); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/busnum", usbinfo->busid); + if (!libxl_read_sysfs_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", &usbinfo->busnum); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/idVendor", usbinfo->busid); + if (!libxl_read_sysfs_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", &usbinfo->idVendor); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/idProduct", usbinfo->busid); + if (!libxl_read_sysfs_file_contents(ctx, filename, &buf, NULL)) + sscanf(buf, "%x", &usbinfo->idProduct); + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/manufacturer", usbinfo->busid); + if (!libxl_read_sysfs_file_contents(ctx, filename, &buf, NULL)) { + /* replace \n to \0 */ + usbinfo->manuf = libxl__strdup(NOGC, buf); + if (usbinfo->manuf && strlen(usbinfo->manuf) > 0 && + usbinfo->manuf[strlen(usbinfo->manuf) - 1] == '\n') + usbinfo->manuf[strlen(usbinfo->manuf) - 1] = '\0'; + } + + filename = GCSPRINTF(SYSFS_USB_DEV"/%s/product", usbinfo->busid); + if (!libxl_read_sysfs_file_contents(ctx, filename, &buf, NULL)) { + /* replace \n to \0 */ + usbinfo->prod = libxl__strdup(NOGC, buf); + if (usbinfo->prod && strlen(usbinfo->prod) > 0 && + usbinfo->prod[strlen(usbinfo->prod) - 1] == '\n') + usbinfo->prod[strlen(usbinfo->prod) - 1] = '\0'; + } + + GC_FREE; + return 0; +} +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index 23f27d4..4561e1b 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -541,6 +541,29 @@ libxl_device_pci = Struct("device_pci", [ ("seize", bool), ]) +libxl_usb_protocol = Enumeration("usb_protocol", [ + (0, "AUTO"), + (1, "PV"), + (2, "QEMU"), + ]) + +libxl_device_usbctrl = Struct("device_usbctrl", [ + ("protocol", libxl_usb_protocol), + ("devid", libxl_devid), + ("version", integer), + ("ports", integer), + ("backend_domid", libxl_domid), + ("backend_domname", string), + ]) + +libxl_device_usb = Struct("device_usb", [ + ("ctrl", libxl_devid), + ("port", integer), + ("busid", string), + ("hostbus", integer), + ("hostaddr", integer), + ]) + libxl_device_dtdev = Struct("device_dtdev", [ ("path", string), ]) @@ -572,6 +595,8 @@ libxl_domain_config = Struct("domain_config", [ ("nics", Array(libxl_device_nic, "num_nics")), ("pcidevs", Array(libxl_device_pci, "num_pcidevs")), ("dtdevs", Array(libxl_device_dtdev, "num_dtdevs")), + ("usbctrls", Array(libxl_device_usbctrl, "num_usbctrls")), + ("usbs", Array(libxl_device_usb, "num_usbs")), ("vfbs", Array(libxl_device_vfb, "num_vfbs")), ("vkbs", Array(libxl_device_vkb, "num_vkbs")), ("vtpms", Array(libxl_device_vtpm, "num_vtpms")), @@ -620,6 +645,33 @@ libxl_vtpminfo = Struct("vtpminfo", [ ("uuid", libxl_uuid), ], dir=DIR_OUT) +libxl_usbctrlinfo = Struct("usbctrlinfo", [ + ("protocol", libxl_usb_protocol), + ("devid", libxl_devid), + ("version", integer), + ("ports", integer), + ("backend", string), + ("backend_id", uint32), + ("frontend", string), + ("frontend_id", uint32), + ("state", integer), + ("evtch", integer), + ("ref_urb", integer), + ("ref_conn", integer), + ], dir=DIR_OUT) + +libxl_usbinfo = Struct("usbinfo", [ + ("ctrl", libxl_devid), + ("port", integer), + ("busid", string), + ("busnum", integer), + ("devnum", integer), + ("idVendor", integer), + ("idProduct", integer), + ("prod", string), + ("manuf", string), + ], dir=DIR_OUT) + libxl_vcpuinfo = Struct("vcpuinfo", [ ("vcpuid", uint32), ("cpu", uint32), diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl index 5e55685..696f5f8 100644 --- a/tools/libxl/libxl_types_internal.idl +++ b/tools/libxl/libxl_types_internal.idl @@ -22,6 +22,7 @@ libxl__device_kind = Enumeration("device_kind", [ (6, "VKBD"), (7, "CONSOLE"), (8, "VTPM"), + (9, "VUSB"), ]) libxl__console_backend = Enumeration("console_backend", [ diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c index d0d56c2..aca4bb9 100644 --- a/tools/libxl/libxl_utils.c +++ b/tools/libxl/libxl_utils.c @@ -1182,6 +1182,22 @@ int libxl__random_bytes(libxl__gc *gc, uint8_t *buf, size_t len) return ret; } +void libxl_device_usbctrl_list_free(libxl_device_usbctrl* list, int nr) +{ + int i; + for (i = 0; i < nr; i++) + libxl_device_usbctrl_dispose(&list[i]); + free(list); +} + +void libxl_device_usb_list_free(libxl_device_usb* list, int nr) +{ + int i; + for (i = 0; i < nr; i++) + libxl_device_usb_dispose(&list[i]); + free(list); +} + /* * Local variables: * mode: C -- 2.1.4 ^ permalink raw reply related [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-10 3:20 ` [PATCH V4 3/7] libxl: add pvusb API Chunyan Liu @ 2015-06-11 15:00 ` Juergen Gross 2015-06-11 16:07 ` Ian Jackson 2015-06-11 16:42 ` Ian Jackson ` (2 subsequent siblings) 3 siblings, 1 reply; 88+ messages in thread From: Juergen Gross @ 2015-06-11 15:00 UTC (permalink / raw) To: Chunyan Liu, xen-devel Cc: george.dunlap, Ian.Jackson, Simon Cao, wei.liu2, ian.campbell On 06/10/2015 05:20 AM, Chunyan Liu wrote: > Add pvusb APIs, including: > - attach/detach (create/destroy) virtual usb controller. > - attach/detach usb device > - list usb controller and usb devices > - some other helper functions > > Signed-off-by: Chunyan Liu <cyliu@suse.com> > Signed-off-by: Simon Cao <caobosimon@gmail.com> I've tested the patches with an old SUSE pvusb backend and my new one. While all cases I tried worked with xm, the xl variant had some problems with both backends, the new one being worse. I suspect especially this patch to be faulty, as it has IMHO a potential structural problem: when trying to attach a USB device without having created a usb-controller for the domain, an asynchronous libxl-operation will itself call another async operation. The second async operation is being called with ao_how being NULL, but I'm not sure whether this is allowed (libxl_internal.h comments are not clear for me regarding such a scenario). libxl_device_usb_add() AO_CREATE(ctx, domid, ao_how) libxl__device_usb_add() libxl__device_usb_setdefault() libxl_device_usbctrl_add_common() AO_CREATE(ctx, domid, NULL) Tests with the new backend: What I'm seeing is an error message that the controller couldn't be assigned and the device would fail, too. The real result, however, is an assigned controller, but no device. Manual assignment of the device succeeds afterwards. doing "xl usb-ctrl-attach" and then "xl usb-attach" is working, too. Assigning a device via config file fails always (binding of device to backend failed). Tests with the old backend: All tests but assigning a device via config file worked (again the same binding error). As I'm currently trying to write a new pvusb backend in qemu, I don't want to investigate the xl problems with the new kernel backend. I suspect some timing differences between old and new kernel drivers leading to the different results. As the qemu variant wouldn't need any driver rebinding in libxl (qemu is handling this by itself) I wouldn't be worried too much about the config file problem. If, however, the nested usage of AO_CREATE is forbidden, this has to be changed, of course. Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-11 15:00 ` Juergen Gross @ 2015-06-11 16:07 ` Ian Jackson 0 siblings, 0 replies; 88+ messages in thread From: Ian Jackson @ 2015-06-11 16:07 UTC (permalink / raw) To: Juergen Gross Cc: wei.liu2, ian.campbell, george.dunlap, Chunyan Liu, xen-devel, Simon Cao Juergen Gross writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > The second async operation is being called with ao_how being NULL, but > I'm not sure whether this is allowed (libxl_internal.h comments are not > clear for me regarding such a scenario). It is not allowed. I'll have a look through this series. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-10 3:20 ` [PATCH V4 3/7] libxl: add pvusb API Chunyan Liu 2015-06-11 15:00 ` Juergen Gross @ 2015-06-11 16:42 ` Ian Jackson 2015-06-12 7:39 ` Chun Yan Liu 2015-06-15 14:17 ` George Dunlap 2015-06-15 17:47 ` George Dunlap 3 siblings, 1 reply; 88+ messages in thread From: Ian Jackson @ 2015-06-11 16:42 UTC (permalink / raw) To: Chunyan Liu; +Cc: george.dunlap, Simon Cao, wei.liu2, ian.campbell, xen-devel Chunyan Liu writes ("[Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > Add pvusb APIs, including: ... Thanks for your contribution. I'm afraid I haven't had time to completely finish my review this, but here's what I have: > --- /dev/null > +++ b/docs/misc/pvusb.txt > @@ -0,0 +1,243 @@ > +1. Overview It's good that you have provided documentation. But I think this document is a bit confused about its audience. Information about design choices should be removed from this user- and application-facing document, and put in comments in the code, or commit messages, I think. > +int libxl_device_usbctrl_getinfo(libxl_ctx *ctx, uint32_t domid, > + libxl_device_usbctrl *usbctrl, > + libxl_usbctrlinfo *usbctrlinfo) > + LIBXL_EXTERNAL_CALLERS_ONLY; Why is this function marked LIBXL_EXTERNAL_CALLERS_ONLY ? > diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h > index ef7aa1d..89a9f07 100644 > --- a/tools/libxl/libxl_internal.h > +++ b/tools/libxl/libxl_internal.h > @@ -2439,6 +2439,18 @@ _hidden void libxl__device_vtpm_add(libxl__egc *egc, uint32_t domid, ... > +/* AO operation to connect a PVUSB controller. > + * Adding a PVUSB controller will add a 'vusb' device entry in xenstore, > + * and will wait for device connection. In this context I think "will wait for device connection" is misleading. What you mean is that the vusb is available for adding devices to, but won't have any yet. Nothing in libxl is "waiting". > diff --git a/tools/libxl/libxl_pvusb.c b/tools/libxl/libxl_pvusb.c > new file mode 100644 > index 0000000..a6e1aa1 > --- /dev/null > +++ b/tools/libxl/libxl_pvusb.c > @@ -0,0 +1,1249 @@ ... > +void libxl__device_usbctrl_add(libxl__egc *egc, uint32_t domid, > + libxl_device_usbctrl *usbctrl, > + libxl__ao_device *aodev) > +{ > + STATE_AO_GC(aodev->ao); ... > + libxl_domain_config_init(&d_config); > + libxl_device_usbctrl_init(&usbctrl_saved); > + libxl_device_usbctrl_copy(CTX, &usbctrl_saved, usbctrl); Wei will need to review the saved/live saved device info handling, and the json, etc. > +static int > +libxl_device_usbctrl_remove_common(libxl_ctx *ctx, uint32_t domid, > + libxl_device_usbctrl *usbctrl, > + const libxl_asyncop_how *ao_how, > + int force) As discussed, you mustn't call this within libxl. If you need to, you need to break it out into an internal function (libxl__initiate_device_usbctrl_remove, maybe) which makes a callback when done. > +libxl_device_usbctrl * > +libxl_device_usbctrl_list(libxl_ctx *ctx, uint32_t domid, int *num) > +{ > + GC_INIT(ctx); > + libxl_device_usbctrl *usbctrls = NULL; > + char *fe_path = NULL; > + char **dir = NULL; > + unsigned int ndirs = 0; > + > + *num = 0; > + > + fe_path = GCSPRINTF("%s/device/vusb", > + libxl__xs_get_dompath(gc, domid)); > + dir = libxl__xs_directory(gc, XBT_NULL, fe_path, &ndirs); > + > + if (dir && ndirs) { > + usbctrls = malloc(sizeof(*usbctrls) * ndirs); Please use libxl__calloc with NOGC. > + libxl_device_usbctrl* usbctrl; > + libxl_device_usbctrl* end = usbctrls + ndirs; > + for (usbctrl = usbctrls; usbctrl < end; usbctrl++, dir++, (*num)++) { > + char *tmp; > + const char *be_path = libxl__xs_read(gc, XBT_NULL, > + GCSPRINTF("%s/%s/backend", fe_path, *dir)); > + > + libxl_device_usbctrl_init(usbctrl); > + usbctrl->devid = atoi(*dir); This function (and the corresponding writing code) is quite formulaic. Perhaps a macro or something could be used. I would make a similar criticism of libxl_device_usbctrl_getinfo. > +/* check if USB device is already assigned to a domain */ > +static bool is_usb_assigned(libxl__gc *gc, libxl_device_usb *usb) > +{ > + libxl_device_usb *usbs; > + int rc, num; > + > + rc = libxl__device_usb_assigned_list(gc, &usbs, &num); > + if (rc) { > + LOG(ERROR, "Fail to get assigned usb list"); > + return true; I don't think this is proper error handling. You need to either encode the boolean return value in the error code, or have the boolean result be a reference parameter. Thanks, Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-11 16:42 ` Ian Jackson @ 2015-06-12 7:39 ` Chun Yan Liu 2015-06-12 8:06 ` Chun Yan Liu 2015-06-12 11:22 ` Ian Jackson 0 siblings, 2 replies; 88+ messages in thread From: Chun Yan Liu @ 2015-06-12 7:39 UTC (permalink / raw) To: Ian Jackson; +Cc: george.dunlap, Simon Cao, wei.liu2, ian.campbell, xen-devel >>> On 6/12/2015 at 12:42 AM, in message <21881.47707.526863.158586@mariner.uk.xensource.com>, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote: > Chunyan Liu writes ("[Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > > Add pvusb APIs, including: > ... > > Thanks for your contribution. I'm afraid I haven't had time to > completely finish my review this, but here's what I have: > > > --- /dev/null > > +++ b/docs/misc/pvusb.txt > > @@ -0,0 +1,243 @@ > > +1. Overview > > It's good that you have provided documentation. But I think this > document is a bit confused about its audience. > > Information about design choices should be removed from this user- and > application-facing document, and put in comments in the code, or > commit messages, I think. Thanks. Will update. > > > > +int libxl_device_usbctrl_getinfo(libxl_ctx *ctx, uint32_t domid, > > + libxl_device_usbctrl *usbctrl, > > + libxl_usbctrlinfo *usbctrlinfo) > > + LIBXL_EXTERNAL_CALLERS_ONLY; > > Why is this function marked LIBXL_EXTERNAL_CALLERS_ONLY ? Currently libxl itself won't call it. Exposed for toolstack usage. Will remove that if it's not proper. > > > diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h > > index ef7aa1d..89a9f07 100644 > > --- a/tools/libxl/libxl_internal.h > > +++ b/tools/libxl/libxl_internal.h > > @@ -2439,6 +2439,18 @@ _hidden void libxl__device_vtpm_add(libxl__egc *egc, > uint32_t domid, > ... > > +/* AO operation to connect a PVUSB controller. > > + * Adding a PVUSB controller will add a 'vusb' device entry in xenstore, > > + * and will wait for device connection. > > In this context I think "will wait for device connection" is > misleading. What you mean is that the vusb is available for adding > devices to, but won't have any yet. Nothing in libxl is "waiting". Here I mean libxl_wait_for_device_connection. Since it adds a new device entry to xenstore, it needs to wait for a moment for frontend/backend connection. > > > diff --git a/tools/libxl/libxl_pvusb.c b/tools/libxl/libxl_pvusb.c > > new file mode 100644 > > index 0000000..a6e1aa1 > > --- /dev/null > > +++ b/tools/libxl/libxl_pvusb.c > > @@ -0,0 +1,1249 @@ > ... > > +void libxl__device_usbctrl_add(libxl__egc *egc, uint32_t domid, > > + libxl_device_usbctrl *usbctrl, > > + libxl__ao_device *aodev) > > +{ > > + STATE_AO_GC(aodev->ao); > ... > > + libxl_domain_config_init(&d_config); > > + libxl_device_usbctrl_init(&usbctrl_saved); > > + libxl_device_usbctrl_copy(CTX, &usbctrl_saved, usbctrl); > > Wei will need to review the saved/live saved device info handling, and > the json, etc. > > > +static int > > +libxl_device_usbctrl_remove_common(libxl_ctx *ctx, uint32_t domid, > > + libxl_device_usbctrl *usbctrl, > > + const libxl_asyncop_how *ao_how, > > + int force) > > As discussed, you mustn't call this within libxl. I don't quite understand why. I guess it's the same as usb_add problem, something related to embedded ao? As in usb_add: libxl_device_usb_add() AO_CREATE(ctx, domid, ao_how) libxl__device_usb_add() libxl__device_usb_setdefault() libxl_device_usbctrl_add_common() AO_CREATE(ctx, domid, NULL) if this is not allowed, what is the correct way? > If you need to, you > need to break it out into an internal function > (libxl__initiate_device_usbctrl_remove, maybe) which makes a callback > when done. > > > +libxl_device_usbctrl * > > +libxl_device_usbctrl_list(libxl_ctx *ctx, uint32_t domid, int *num) > > +{ > > + GC_INIT(ctx); > > + libxl_device_usbctrl *usbctrls = NULL; > > + char *fe_path = NULL; > > + char **dir = NULL; > > + unsigned int ndirs = 0; > > + > > + *num = 0; > > + > > + fe_path = GCSPRINTF("%s/device/vusb", > > + libxl__xs_get_dompath(gc, domid)); > > + dir = libxl__xs_directory(gc, XBT_NULL, fe_path, &ndirs); > > + > > + if (dir && ndirs) { > > + usbctrls = malloc(sizeof(*usbctrls) * ndirs); > > Please use libxl__calloc with NOGC. Thanks. Missing this one. > > > + libxl_device_usbctrl* usbctrl; > > + libxl_device_usbctrl* end = usbctrls + ndirs; > > + for (usbctrl = usbctrls; usbctrl < end; usbctrl++, dir++, (*num)++) > { > > + char *tmp; > > + const char *be_path = libxl__xs_read(gc, XBT_NULL, > > + GCSPRINTF("%s/%s/backend", fe_path, > *dir)); > > + > > + libxl_device_usbctrl_init(usbctrl); > > + usbctrl->devid = atoi(*dir); > > This function (and the corresponding writing code) is quite formulaic. > Perhaps a macro or something could be used. > > I would make a similar criticism of libxl_device_usbctrl_getinfo. > > > +/* check if USB device is already assigned to a domain */ > > +static bool is_usb_assigned(libxl__gc *gc, libxl_device_usb *usb) > > +{ > > + libxl_device_usb *usbs; > > + int rc, num; > > + > > + rc = libxl__device_usb_assigned_list(gc, &usbs, &num); > > + if (rc) { > > + LOG(ERROR, "Fail to get assigned usb list"); > > + return true; > > I don't think this is proper error handling. You need to either > encode the boolean return value in the error code, or have the boolean > result be a reference parameter. Will improve that. Thanks, Chunyan > > > Thanks, > Ian. > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel > > ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-12 7:39 ` Chun Yan Liu @ 2015-06-12 8:06 ` Chun Yan Liu 2015-06-12 11:22 ` Ian Jackson 1 sibling, 0 replies; 88+ messages in thread From: Chun Yan Liu @ 2015-06-12 8:06 UTC (permalink / raw) To: Ian Jackson, Chun Yan Liu Cc: george.dunlap, Simon Cao, wei.liu2, ian.campbell, xen-devel >>> On 6/12/2015 at 03:39 PM, in message <557AFD2F02000066000D4C7D@relay2.provo.novell.com>, "Chun Yan Liu" <cyliu@suse.com> wrote: > >>>> On 6/12/2015 at 12:42 AM, in message > <21881.47707.526863.158586@mariner.uk.xensource.com>, Ian Jackson > <Ian.Jackson@eu.citrix.com> wrote: > > Chunyan Liu writes ("[Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > > > Add pvusb APIs, including: > > ... > > > > Thanks for your contribution. I'm afraid I haven't had time to > > completely finish my review this, but here's what I have: > > > > > --- /dev/null > > > +++ b/docs/misc/pvusb.txt > > > @@ -0,0 +1,243 @@ > > > +1. Overview > > > > It's good that you have provided documentation. But I think this > > document is a bit confused about its audience. > > > > Information about design choices should be removed from this user- and > > application-facing document, and put in comments in the code, or > > commit messages, I think. > > Thanks. Will update. > > > > > > > > +int libxl_device_usbctrl_getinfo(libxl_ctx *ctx, uint32_t domid, > > > + libxl_device_usbctrl *usbctrl, > > > + libxl_usbctrlinfo *usbctrlinfo) > > > + LIBXL_EXTERNAL_CALLERS_ONLY; > > > > Why is this function marked LIBXL_EXTERNAL_CALLERS_ONLY ? > > Currently libxl itself won't call it. Exposed for toolstack usage. Will > remove that if it's not proper. > > > > > > diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h > > > index ef7aa1d..89a9f07 100644 > > > --- a/tools/libxl/libxl_internal.h > > > +++ b/tools/libxl/libxl_internal.h > > > @@ -2439,6 +2439,18 @@ _hidden void libxl__device_vtpm_add(libxl__egc *egc, > > > uint32_t domid, > > ... > > > +/* AO operation to connect a PVUSB controller. > > > + * Adding a PVUSB controller will add a 'vusb' device entry in xenstore, > > > + * and will wait for device connection. > > > > In this context I think "will wait for device connection" is > > misleading. What you mean is that the vusb is available for adding > > devices to, but won't have any yet. Nothing in libxl is "waiting". > > Here I mean libxl_wait_for_device_connection. Since it adds a new device > entry > to xenstore, it needs to wait for a moment for frontend/backend connection. > > > > > > diff --git a/tools/libxl/libxl_pvusb.c b/tools/libxl/libxl_pvusb.c > > > new file mode 100644 > > > index 0000000..a6e1aa1 > > > --- /dev/null > > > +++ b/tools/libxl/libxl_pvusb.c > > > @@ -0,0 +1,1249 @@ > > ... > > > +void libxl__device_usbctrl_add(libxl__egc *egc, uint32_t domid, > > > + libxl_device_usbctrl *usbctrl, > > > + libxl__ao_device *aodev) > > > +{ > > > + STATE_AO_GC(aodev->ao); > > ... > > > + libxl_domain_config_init(&d_config); > > > + libxl_device_usbctrl_init(&usbctrl_saved); > > > + libxl_device_usbctrl_copy(CTX, &usbctrl_saved, usbctrl); > > > > Wei will need to review the saved/live saved device info handling, and > > the json, etc. > > > > > +static int > > > +libxl_device_usbctrl_remove_common(libxl_ctx *ctx, uint32_t domid, > > > + libxl_device_usbctrl *usbctrl, > > > + const libxl_asyncop_how *ao_how, > > > + int force) > > > > As discussed, you mustn't call this within libxl. > I don't quite understand why. I guess it's the same as usb_add problem, > something related to embedded ao? > As in usb_add: > libxl_device_usb_add() > AO_CREATE(ctx, domid, ao_how) > libxl__device_usb_add() > libxl__device_usb_setdefault() > libxl_device_usbctrl_add_common() > AO_CREATE(ctx, domid, NULL) > if this is not allowed, what is the correct way? Saw the discussion thread and got it. Will update the codes. > > > If you need to, you > > need to break it out into an internal function > > (libxl__initiate_device_usbctrl_remove, maybe) which makes a callback > > when done. > > > > > +libxl_device_usbctrl * > > > +libxl_device_usbctrl_list(libxl_ctx *ctx, uint32_t domid, int *num) > > > +{ > > > + GC_INIT(ctx); > > > + libxl_device_usbctrl *usbctrls = NULL; > > > + char *fe_path = NULL; > > > + char **dir = NULL; > > > + unsigned int ndirs = 0; > > > + > > > + *num = 0; > > > + > > > + fe_path = GCSPRINTF("%s/device/vusb", > > > + libxl__xs_get_dompath(gc, domid)); > > > + dir = libxl__xs_directory(gc, XBT_NULL, fe_path, &ndirs); > > > + > > > + if (dir && ndirs) { > > > + usbctrls = malloc(sizeof(*usbctrls) * ndirs); > > > > Please use libxl__calloc with NOGC. > > Thanks. Missing this one. > > > > > > + libxl_device_usbctrl* usbctrl; > > > + libxl_device_usbctrl* end = usbctrls + ndirs; > > > + for (usbctrl = usbctrls; usbctrl < end; usbctrl++, dir++, > (*num)++) > > { > > > + char *tmp; > > > + const char *be_path = libxl__xs_read(gc, XBT_NULL, > > > + GCSPRINTF("%s/%s/backend", fe_path, > > *dir)); > > > + > > > + libxl_device_usbctrl_init(usbctrl); > > > + usbctrl->devid = atoi(*dir); > > > > This function (and the corresponding writing code) is quite formulaic. > > Perhaps a macro or something could be used. > > > > I would make a similar criticism of libxl_device_usbctrl_getinfo. > > > > > +/* check if USB device is already assigned to a domain */ > > > +static bool is_usb_assigned(libxl__gc *gc, libxl_device_usb *usb) > > > +{ > > > + libxl_device_usb *usbs; > > > + int rc, num; > > > + > > > + rc = libxl__device_usb_assigned_list(gc, &usbs, &num); > > > + if (rc) { > > > + LOG(ERROR, "Fail to get assigned usb list"); > > > + return true; > > > > I don't think this is proper error handling. You need to either > > encode the boolean return value in the error code, or have the boolean > > result be a reference parameter. > > Will improve that. > > Thanks, > Chunyan > > > > > > > Thanks, > > Ian. > > > > _______________________________________________ > > Xen-devel mailing list > > Xen-devel@lists.xen.org > > http://lists.xen.org/xen-devel > > > > > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel > > ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-12 7:39 ` Chun Yan Liu 2015-06-12 8:06 ` Chun Yan Liu @ 2015-06-12 11:22 ` Ian Jackson 1 sibling, 0 replies; 88+ messages in thread From: Ian Jackson @ 2015-06-12 11:22 UTC (permalink / raw) To: Chun Yan Liu; +Cc: george.dunlap, Simon Cao, wei.liu2, ian.campbell, xen-devel Chun Yan Liu writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > <21881.47707.526863.158586@mariner.uk.xensource.com>, Ian Jackson > <Ian.Jackson@eu.citrix.com> wrote: > > Chunyan Liu writes ("[Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > > > +int libxl_device_usbctrl_getinfo(libxl_ctx *ctx, uint32_t domid, > > > + libxl_device_usbctrl *usbctrl, > > > + libxl_usbctrlinfo *usbctrlinfo) > > > + LIBXL_EXTERNAL_CALLERS_ONLY; > > > > Why is this function marked LIBXL_EXTERNAL_CALLERS_ONLY ? > > Currently libxl itself won't call it. Exposed for toolstack usage. Will > remove that if it's not proper. LIBXL_EXTERNAL_CALLERS_ONLY is a special macro which _prevents_ anyone from adding calls to the function from inside libxl. It should be used where adding such an internal caller would be a mistake, not simply where there happen not to be any internal callers right now. > > > +/* AO operation to connect a PVUSB controller. > > > + * Adding a PVUSB controller will add a 'vusb' device entry in xenstore, > > > + * and will wait for device connection. > > > > In this context I think "will wait for device connection" is > > misleading. What you mean is that the vusb is available for adding > > devices to, but won't have any yet. Nothing in libxl is "waiting". > > Here I mean libxl_wait_for_device_connection. Since it adds a new > device entry to xenstore, it needs to wait for a moment for > frontend/backend connection. Oh, I see. I don't think you should mention that here. That part of the implementation, not the interface. AFAICT libxl__device_usbctrl_add works just like all the other libxl__device_*_add functions, in that it adds the device and when completed it calls aodev->callback. There is no need to mention this explicitly in a comment - indeed, mentioning it for this device type but not for others would lead the reader to wonder what was different. Thanks, Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-10 3:20 ` [PATCH V4 3/7] libxl: add pvusb API Chunyan Liu 2015-06-11 15:00 ` Juergen Gross 2015-06-11 16:42 ` Ian Jackson @ 2015-06-15 14:17 ` George Dunlap 2015-06-15 14:25 ` Jürgen Groß 2015-06-16 10:41 ` [PATCH V4 3/7] libxl: add pvusb API Ian Jackson 2015-06-15 17:47 ` George Dunlap 3 siblings, 2 replies; 88+ messages in thread From: George Dunlap @ 2015-06-15 14:17 UTC (permalink / raw) To: Chunyan Liu Cc: Wei Liu, Ian Campbell, Ian Jackson, xen-devel, Jim Fehlig, Simon Cao On Wed, Jun 10, 2015 at 4:20 AM, Chunyan Liu <cyliu@suse.com> wrote: > diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl > index 23f27d4..4561e1b 100644 > --- a/tools/libxl/libxl_types.idl > +++ b/tools/libxl/libxl_types.idl > @@ -541,6 +541,29 @@ libxl_device_pci = Struct("device_pci", [ > ("seize", bool), > ]) > > +libxl_usb_protocol = Enumeration("usb_protocol", [ > + (0, "AUTO"), > + (1, "PV"), > + (2, "QEMU"), > + ]) > + > +libxl_device_usbctrl = Struct("device_usbctrl", [ > + ("protocol", libxl_usb_protocol), > + ("devid", libxl_devid), > + ("version", integer), > + ("ports", integer), > + ("backend_domid", libxl_domid), > + ("backend_domname", string), > + ]) > + > +libxl_device_usb = Struct("device_usb", [ > + ("ctrl", libxl_devid), > + ("port", integer), > + ("busid", string), > + ("hostbus", integer), > + ("hostaddr", integer), > + ]) Ian / Ian / Wei / Jim: Question about the design of the interface here. The way that most systems in Linux specify particular USB devices is with the bus:addr format. It's the output you get when you run tools like lsusb, for example, and it's the interface that qemu (and thus KVM) uses when talking about host devices to assign. bus:addr might look like "002:006". But the bus:addr is a "public api" for Linux; internally, it has a more structured format, which contains more about the USB topology. Chunyan is calling this "busid". An example is something like this: "2-3.1.1:1.0". Internally, pvusb needs "busid" in order to find the right sysfs files. qemu, on the other hand, does not take busid; so the devicemodel / HVM implementation of USB would need bus:addr internally. Converting bus:addr to busid involves looping through all devices and seeing which one matches, so it's inefficient to do it every time we need to do some operation. (See libxl_pvusb.c:usb_busaddr_to_busid().) Converting busid to bus:addr is simpler: you read the bus and addr keys from sysfs using the busid. I think for a public UI (i.e., xl), bus:addr is really the only option; I'm pretty sure that's the main interface libvirt provides as well. At the libxl level, we basically have 3 options: 1. Have the libxl layer accept bus:addr. For the pvusb code, translate bus:addr to busid and place it in an internal structure. 2. Have the libxl layer accept busid. For the devicemodel code, 2a. ...translate busid to bus:addr and place it in an internal structure. 2b. ...translate it to bus:addr when it's used (i.e., when speaking over qmp to qemu). 3. Have the libxl layer accept both busid and bus:addr. Translate as necessary and store in the libxl_device_usb struct. For #2, I think we need to provide a helper function to convert bus:addr into busid, since bus:addr is the interface most toolstacks will want to expose to their users. Chunyan's initial submission had #2 (without a or b, since the devicemodel code doesn't exist yet). I suggested #1, and she pushed back by compromising (#3). The advantage of #3 internally is that the functions can do the translation once (if necessary), and can then pass around the public libxl_device_usb struct as-is without needing any extra parameters or a separate libxl_device_usb_internal. The disadvantage, I think, is that from an interface perspective, it's fairly pointless to have both. busid doesn't really give you any better or more control than the other, and it's not any more convenient for the user (in fact it's less convenient because it's more difficult to find). I *think* 2b wouldn't be terrible from a performance point of view, since (I think) you'd probably only have to do the translation once before calling the qmp command. I still prefer #1; but if people thought #3 or #2b would be preferable, I could live with that. Any thoughts? -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-15 14:17 ` George Dunlap @ 2015-06-15 14:25 ` Jürgen Groß 2015-06-15 14:34 ` George Dunlap 2015-06-16 10:41 ` [PATCH V4 3/7] libxl: add pvusb API Ian Jackson 1 sibling, 1 reply; 88+ messages in thread From: Jürgen Groß @ 2015-06-15 14:25 UTC (permalink / raw) To: George Dunlap, Chunyan Liu Cc: Wei Liu, Ian Campbell, Ian Jackson, xen-devel, Jim Fehlig, Simon Cao On 06/15/2015 04:17 PM, George Dunlap wrote: > On Wed, Jun 10, 2015 at 4:20 AM, Chunyan Liu <cyliu@suse.com> wrote: >> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl >> index 23f27d4..4561e1b 100644 >> --- a/tools/libxl/libxl_types.idl >> +++ b/tools/libxl/libxl_types.idl >> @@ -541,6 +541,29 @@ libxl_device_pci = Struct("device_pci", [ >> ("seize", bool), >> ]) >> >> +libxl_usb_protocol = Enumeration("usb_protocol", [ >> + (0, "AUTO"), >> + (1, "PV"), >> + (2, "QEMU"), >> + ]) >> + >> +libxl_device_usbctrl = Struct("device_usbctrl", [ >> + ("protocol", libxl_usb_protocol), >> + ("devid", libxl_devid), >> + ("version", integer), >> + ("ports", integer), >> + ("backend_domid", libxl_domid), >> + ("backend_domname", string), >> + ]) >> + >> +libxl_device_usb = Struct("device_usb", [ >> + ("ctrl", libxl_devid), >> + ("port", integer), >> + ("busid", string), >> + ("hostbus", integer), >> + ("hostaddr", integer), >> + ]) > > Ian / Ian / Wei / Jim: > > Question about the design of the interface here. > > The way that most systems in Linux specify particular USB devices is > with the bus:addr format. It's the output you get when you run tools > like lsusb, for example, and it's the interface that qemu (and thus > KVM) uses when talking about host devices to assign. bus:addr might > look like "002:006". > > But the bus:addr is a "public api" for Linux; internally, it has a > more structured format, which contains more about the USB topology. > Chunyan is calling this "busid". An example is something like this: > "2-3.1.1:1.0". > > Internally, pvusb needs "busid" in order to find the right sysfs > files. qemu, on the other hand, does not take busid; so the > devicemodel / HVM implementation of USB would need bus:addr > internally. A patch for qemu to support the busid is trivial, as the structures already contain the necessary elements: --- a/hw/usb/host-legacy.c +++ b/hw/usb/host-legacy.c @@ -53,11 +53,6 @@ static int parse_filter(const char *spec, struct USBAutoFilter *f) const char *p = spec; int i; - f->bus_num = 0; - f->addr = 0; - f->vendor_id = 0; - f->product_id = 0; - for (i = BUS; i < DONE; i++) { p = strpbrk(p, ":."); if (!p) { @@ -100,32 +95,47 @@ USBDevice *usb_host_device_open(USBBus *bus, const char *devname) dev = usb_create(bus, "usb-host"); + memset(&filter, 0, sizeof(filter)); + if (strstr(devname, "auto:")) { if (parse_filter(devname, &filter) < 0) { goto fail; } - } else { - p = strchr(devname, '.'); - if (p) { - filter.bus_num = strtoul(devname, NULL, 0); - filter.addr = strtoul(p + 1, NULL, 0); - filter.vendor_id = 0; - filter.product_id = 0; - } else { - p = strchr(devname, ':'); - if (p) { - filter.bus_num = 0; - filter.addr = 0; - filter.vendor_id = strtoul(devname, NULL, 16); - filter.product_id = strtoul(p + 1, NULL, 16); - } else { - goto fail; - } - } + goto out; } + /* Check for <bus>-<port> specification. */ + p = strchr(devname, '-'); + if (p && p != devname) { + filter.bus_num = strtoul(devname, NULL, 0); + filter.port = p + 1; + goto out; + } + + /* Check for <bus>.<addr> specification. */ + p = strchr(devname, '.'); + if (p) { + filter.bus_num = strtoul(devname, NULL, 0); + filter.addr = strtoul(p + 1, NULL, 0); + goto out; + } + + /* Check for <vendorid>:<productid> specification. */ + p = strchr(devname, ':'); + if (p) { + filter.vendor_id = strtoul(devname, NULL, 16); + filter.product_id = strtoul(p + 1, NULL, 16); + goto out; + } + + goto fail; + +out: qdev_prop_set_uint32(&dev->qdev, "hostbus", filter.bus_num); qdev_prop_set_uint32(&dev->qdev, "hostaddr", filter.addr); + if (filter.port) { + qdev_prop_set_string(&dev->qdev, "port", filter.port); + } qdev_prop_set_uint32(&dev->qdev, "vendorid", filter.vendor_id); qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id); qdev_init_nofail(&dev->qdev); Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-15 14:25 ` Jürgen Groß @ 2015-06-15 14:34 ` George Dunlap 2015-06-15 18:26 ` Juergen Gross 0 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-15 14:34 UTC (permalink / raw) To: Jürgen Groß Cc: Wei Liu, Ian Campbell, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Mon, Jun 15, 2015 at 3:25 PM, Jürgen Groß <jgross@suse.com> wrote: > On 06/15/2015 04:17 PM, George Dunlap wrote: >> >> On Wed, Jun 10, 2015 at 4:20 AM, Chunyan Liu <cyliu@suse.com> wrote: >>> >>> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl >>> index 23f27d4..4561e1b 100644 >>> --- a/tools/libxl/libxl_types.idl >>> +++ b/tools/libxl/libxl_types.idl >>> @@ -541,6 +541,29 @@ libxl_device_pci = Struct("device_pci", [ >>> ("seize", bool), >>> ]) >>> >>> +libxl_usb_protocol = Enumeration("usb_protocol", [ >>> + (0, "AUTO"), >>> + (1, "PV"), >>> + (2, "QEMU"), >>> + ]) >>> + >>> +libxl_device_usbctrl = Struct("device_usbctrl", [ >>> + ("protocol", libxl_usb_protocol), >>> + ("devid", libxl_devid), >>> + ("version", integer), >>> + ("ports", integer), >>> + ("backend_domid", libxl_domid), >>> + ("backend_domname", string), >>> + ]) >>> + >>> +libxl_device_usb = Struct("device_usb", [ >>> + ("ctrl", libxl_devid), >>> + ("port", integer), >>> + ("busid", string), >>> + ("hostbus", integer), >>> + ("hostaddr", integer), >>> + ]) >> >> >> Ian / Ian / Wei / Jim: >> >> Question about the design of the interface here. >> >> The way that most systems in Linux specify particular USB devices is >> with the bus:addr format. It's the output you get when you run tools >> like lsusb, for example, and it's the interface that qemu (and thus >> KVM) uses when talking about host devices to assign. bus:addr might >> look like "002:006". >> >> But the bus:addr is a "public api" for Linux; internally, it has a >> more structured format, which contains more about the USB topology. >> Chunyan is calling this "busid". An example is something like this: >> "2-3.1.1:1.0". >> >> Internally, pvusb needs "busid" in order to find the right sysfs >> files. qemu, on the other hand, does not take busid; so the >> devicemodel / HVM implementation of USB would need bus:addr >> internally. > > > A patch for qemu to support the busid is trivial, as the structures > already contain the necessary elements: > > --- a/hw/usb/host-legacy.c > +++ b/hw/usb/host-legacy.c > @@ -53,11 +53,6 @@ static int parse_filter(const char *spec, struct > USBAutoFilter *f) > const char *p = spec; > int i; > > - f->bus_num = 0; > - f->addr = 0; > - f->vendor_id = 0; > - f->product_id = 0; > - > for (i = BUS; i < DONE; i++) { > p = strpbrk(p, ":."); > if (!p) { > @@ -100,32 +95,47 @@ USBDevice *usb_host_device_open(USBBus *bus, const char > *devname) > > dev = usb_create(bus, "usb-host"); > > + memset(&filter, 0, sizeof(filter)); > + > if (strstr(devname, "auto:")) { > if (parse_filter(devname, &filter) < 0) { > goto fail; > } > - } else { > - p = strchr(devname, '.'); > - if (p) { > - filter.bus_num = strtoul(devname, NULL, 0); > - filter.addr = strtoul(p + 1, NULL, 0); > - filter.vendor_id = 0; > - filter.product_id = 0; > - } else { > - p = strchr(devname, ':'); > - if (p) { > - filter.bus_num = 0; > - filter.addr = 0; > - filter.vendor_id = strtoul(devname, NULL, 16); > - filter.product_id = strtoul(p + 1, NULL, 16); > - } else { > - goto fail; > - } > - } > + goto out; > } > > + /* Check for <bus>-<port> specification. */ > + p = strchr(devname, '-'); > + if (p && p != devname) { > + filter.bus_num = strtoul(devname, NULL, 0); > + filter.port = p + 1; > + goto out; > + } On my system bus:addr for my mouse is 002:005, while the "busid" (the corresponding directory in sysfs) is 2-3.3. This code doesn't appear to me to parse the above properly; or did I miss something? -George _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-15 14:34 ` George Dunlap @ 2015-06-15 18:26 ` Juergen Gross 2015-06-16 10:30 ` George Dunlap 0 siblings, 1 reply; 88+ messages in thread From: Juergen Gross @ 2015-06-15 18:26 UTC (permalink / raw) To: George Dunlap Cc: Wei Liu, Ian Campbell, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/15/2015 04:34 PM, George Dunlap wrote: > On Mon, Jun 15, 2015 at 3:25 PM, Jürgen Groß <jgross@suse.com> wrote: >> On 06/15/2015 04:17 PM, George Dunlap wrote: >>> >>> On Wed, Jun 10, 2015 at 4:20 AM, Chunyan Liu <cyliu@suse.com> wrote: >>>> >>>> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl >>>> index 23f27d4..4561e1b 100644 >>>> --- a/tools/libxl/libxl_types.idl >>>> +++ b/tools/libxl/libxl_types.idl >>>> @@ -541,6 +541,29 @@ libxl_device_pci = Struct("device_pci", [ >>>> ("seize", bool), >>>> ]) >>>> >>>> +libxl_usb_protocol = Enumeration("usb_protocol", [ >>>> + (0, "AUTO"), >>>> + (1, "PV"), >>>> + (2, "QEMU"), >>>> + ]) >>>> + >>>> +libxl_device_usbctrl = Struct("device_usbctrl", [ >>>> + ("protocol", libxl_usb_protocol), >>>> + ("devid", libxl_devid), >>>> + ("version", integer), >>>> + ("ports", integer), >>>> + ("backend_domid", libxl_domid), >>>> + ("backend_domname", string), >>>> + ]) >>>> + >>>> +libxl_device_usb = Struct("device_usb", [ >>>> + ("ctrl", libxl_devid), >>>> + ("port", integer), >>>> + ("busid", string), >>>> + ("hostbus", integer), >>>> + ("hostaddr", integer), >>>> + ]) >>> >>> >>> Ian / Ian / Wei / Jim: >>> >>> Question about the design of the interface here. >>> >>> The way that most systems in Linux specify particular USB devices is >>> with the bus:addr format. It's the output you get when you run tools >>> like lsusb, for example, and it's the interface that qemu (and thus >>> KVM) uses when talking about host devices to assign. bus:addr might >>> look like "002:006". >>> >>> But the bus:addr is a "public api" for Linux; internally, it has a >>> more structured format, which contains more about the USB topology. >>> Chunyan is calling this "busid". An example is something like this: >>> "2-3.1.1:1.0". >>> >>> Internally, pvusb needs "busid" in order to find the right sysfs >>> files. qemu, on the other hand, does not take busid; so the >>> devicemodel / HVM implementation of USB would need bus:addr >>> internally. >> >> >> A patch for qemu to support the busid is trivial, as the structures >> already contain the necessary elements: >> >> --- a/hw/usb/host-legacy.c >> +++ b/hw/usb/host-legacy.c >> @@ -53,11 +53,6 @@ static int parse_filter(const char *spec, struct >> USBAutoFilter *f) >> const char *p = spec; >> int i; >> >> - f->bus_num = 0; >> - f->addr = 0; >> - f->vendor_id = 0; >> - f->product_id = 0; >> - >> for (i = BUS; i < DONE; i++) { >> p = strpbrk(p, ":."); >> if (!p) { >> @@ -100,32 +95,47 @@ USBDevice *usb_host_device_open(USBBus *bus, const char >> *devname) >> >> dev = usb_create(bus, "usb-host"); >> >> + memset(&filter, 0, sizeof(filter)); >> + >> if (strstr(devname, "auto:")) { >> if (parse_filter(devname, &filter) < 0) { >> goto fail; >> } >> - } else { >> - p = strchr(devname, '.'); >> - if (p) { >> - filter.bus_num = strtoul(devname, NULL, 0); >> - filter.addr = strtoul(p + 1, NULL, 0); >> - filter.vendor_id = 0; >> - filter.product_id = 0; >> - } else { >> - p = strchr(devname, ':'); >> - if (p) { >> - filter.bus_num = 0; >> - filter.addr = 0; >> - filter.vendor_id = strtoul(devname, NULL, 16); >> - filter.product_id = strtoul(p + 1, NULL, 16); >> - } else { >> - goto fail; >> - } >> - } >> + goto out; >> } >> >> + /* Check for <bus>-<port> specification. */ >> + p = strchr(devname, '-'); >> + if (p && p != devname) { >> + filter.bus_num = strtoul(devname, NULL, 0); >> + filter.port = p + 1; >> + goto out; >> + } > > > On my system bus:addr for my mouse is 002:005, while the "busid" (the > corresponding directory in sysfs) is 2-3.3. > > This code doesn't appear to me to parse the above properly; or did I > miss something? Filling filter.bus_num and filter.port is enough. This was the only part missing in qemu, finding the device via libusb using bus_num and port is already existing. At least it is working for me. :-) Juergen _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-15 18:26 ` Juergen Gross @ 2015-06-16 10:30 ` George Dunlap 2015-06-16 10:51 ` Juergen Gross 0 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-16 10:30 UTC (permalink / raw) To: Juergen Gross Cc: Wei Liu, Ian Campbell, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Mon, Jun 15, 2015 at 7:26 PM, Juergen Gross <jgross@suse.com> wrote: > On 06/15/2015 04:34 PM, George Dunlap wrote: >> >> On Mon, Jun 15, 2015 at 3:25 PM, Jürgen Groß <jgross@suse.com> wrote: >>> >>> On 06/15/2015 04:17 PM, George Dunlap wrote: >>>> >>>> >>>> On Wed, Jun 10, 2015 at 4:20 AM, Chunyan Liu <cyliu@suse.com> wrote: >>>>> >>>>> >>>>> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl >>>>> index 23f27d4..4561e1b 100644 >>>>> --- a/tools/libxl/libxl_types.idl >>>>> +++ b/tools/libxl/libxl_types.idl >>>>> @@ -541,6 +541,29 @@ libxl_device_pci = Struct("device_pci", [ >>>>> ("seize", bool), >>>>> ]) >>>>> >>>>> +libxl_usb_protocol = Enumeration("usb_protocol", [ >>>>> + (0, "AUTO"), >>>>> + (1, "PV"), >>>>> + (2, "QEMU"), >>>>> + ]) >>>>> + >>>>> +libxl_device_usbctrl = Struct("device_usbctrl", [ >>>>> + ("protocol", libxl_usb_protocol), >>>>> + ("devid", libxl_devid), >>>>> + ("version", integer), >>>>> + ("ports", integer), >>>>> + ("backend_domid", libxl_domid), >>>>> + ("backend_domname", string), >>>>> + ]) >>>>> + >>>>> +libxl_device_usb = Struct("device_usb", [ >>>>> + ("ctrl", libxl_devid), >>>>> + ("port", integer), >>>>> + ("busid", string), >>>>> + ("hostbus", integer), >>>>> + ("hostaddr", integer), >>>>> + ]) >>>> >>>> >>>> >>>> Ian / Ian / Wei / Jim: >>>> >>>> Question about the design of the interface here. >>>> >>>> The way that most systems in Linux specify particular USB devices is >>>> with the bus:addr format. It's the output you get when you run tools >>>> like lsusb, for example, and it's the interface that qemu (and thus >>>> KVM) uses when talking about host devices to assign. bus:addr might >>>> look like "002:006". >>>> >>>> But the bus:addr is a "public api" for Linux; internally, it has a >>>> more structured format, which contains more about the USB topology. >>>> Chunyan is calling this "busid". An example is something like this: >>>> "2-3.1.1:1.0". >>>> >>>> Internally, pvusb needs "busid" in order to find the right sysfs >>>> files. qemu, on the other hand, does not take busid; so the >>>> devicemodel / HVM implementation of USB would need bus:addr >>>> internally. >>> >>> >>> >>> A patch for qemu to support the busid is trivial, as the structures >>> already contain the necessary elements: >>> >>> --- a/hw/usb/host-legacy.c >>> +++ b/hw/usb/host-legacy.c >>> @@ -53,11 +53,6 @@ static int parse_filter(const char *spec, struct >>> USBAutoFilter *f) >>> const char *p = spec; >>> int i; >>> >>> - f->bus_num = 0; >>> - f->addr = 0; >>> - f->vendor_id = 0; >>> - f->product_id = 0; >>> - >>> for (i = BUS; i < DONE; i++) { >>> p = strpbrk(p, ":."); >>> if (!p) { >>> @@ -100,32 +95,47 @@ USBDevice *usb_host_device_open(USBBus *bus, const >>> char >>> *devname) >>> >>> dev = usb_create(bus, "usb-host"); >>> >>> + memset(&filter, 0, sizeof(filter)); >>> + >>> if (strstr(devname, "auto:")) { >>> if (parse_filter(devname, &filter) < 0) { >>> goto fail; >>> } >>> - } else { >>> - p = strchr(devname, '.'); >>> - if (p) { >>> - filter.bus_num = strtoul(devname, NULL, 0); >>> - filter.addr = strtoul(p + 1, NULL, 0); >>> - filter.vendor_id = 0; >>> - filter.product_id = 0; >>> - } else { >>> - p = strchr(devname, ':'); >>> - if (p) { >>> - filter.bus_num = 0; >>> - filter.addr = 0; >>> - filter.vendor_id = strtoul(devname, NULL, 16); >>> - filter.product_id = strtoul(p + 1, NULL, 16); >>> - } else { >>> - goto fail; >>> - } >>> - } >>> + goto out; >>> } >>> >>> + /* Check for <bus>-<port> specification. */ >>> + p = strchr(devname, '-'); >>> + if (p && p != devname) { >>> + filter.bus_num = strtoul(devname, NULL, 0); >>> + filter.port = p + 1; >>> + goto out; >>> + } >> >> >> >> On my system bus:addr for my mouse is 002:005, while the "busid" (the >> corresponding directory in sysfs) is 2-3.3. >> >> This code doesn't appear to me to parse the above properly; or did I >> miss something? > > > Filling filter.bus_num and filter.port is enough. This was the only part > missing in qemu, finding the device via libusb using bus_num and port is > already existing. At least it is working for me. :-) Well, one of us is completely wrong. Let's follow the example above: $ ls /sys/bus/usb/devices/2-3* /sys/bus/usb/devices/2-3@ /sys/bus/usb/devices/2-3.1@ /sys/bus/usb/devices/2-3:1.0@ /sys/bus/usb/devices/2-3.1.1@ /sys/bus/usb/devices/2-3.1:1.0@ /sys/bus/usb/devices/2-3.1.1:1.0@ /sys/bus/usb/devices/2-3.1.2@ /sys/bus/usb/devices/2-3.1.2:1.0@ /sys/bus/usb/devices/2-3.1.2:1.1@ /sys/bus/usb/devices/2-3.2@ /sys/bus/usb/devices/2-3.2:1.0@ /sys/bus/usb/devices/2-3.3@ /sys/bus/usb/devices/2-3.3:1.0@ $ for i in /sys/bus/usb/devices/2-3*/; do grep . $i/{bus,dev}num ; done /sys/bus/usb/devices/2-3//busnum:2 /sys/bus/usb/devices/2-3//devnum:2 /sys/bus/usb/devices/2-3.1//busnum:2 /sys/bus/usb/devices/2-3.1//devnum:3 /sys/bus/usb/devices/2-3.1.1//busnum:2 /sys/bus/usb/devices/2-3.1.1//devnum:6 /sys/bus/usb/devices/2-3.1.2//busnum:2 /sys/bus/usb/devices/2-3.1.2//devnum:10 /sys/bus/usb/devices/2-3.2//busnum:2 /sys/bus/usb/devices/2-3.2//devnum:4 /sys/bus/usb/devices/2-3.3//busnum:2 /sys/bus/usb/devices/2-3.3//devnum:5 $ lsusb | grep "Bus 002" Bus 002 Device 005: ID 046d:c016 Logitech, Inc. Optical Wheel Mouse Bus 002 Device 004: ID f617:0905 Bus 002 Device 010: ID 1050:0111 Yubico.com Bus 002 Device 006: ID 0424:4060 Standard Microsystems Corp. Ultra Fast Media Reader Bus 002 Device 003: ID 0424:2640 Standard Microsystems Corp. USB 2.0 Hub Bus 002 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub In other words, there are 6 distinct devices that correspond to "bus 2 port 3". I don't know what it was you were passing through, but giving qemu (or libusb) only "2-3" is absolutely not enough for it to distinquish between my mouse (002:005, at 2-3.3) and my yubikey (002:010 at 2-3.1.2). That's why the bus:addr convention was invented in the first place, I presume -- to abstract away the topology of the USB hubs for the user. The "busid" interface that Chunyan is describing requires the caller to find out that long name -- 2-3.1.2 -- rather than the traditional short name (002:010). Just accepting "2-3" is not sufficient. -George _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 10:30 ` George Dunlap @ 2015-06-16 10:51 ` Juergen Gross 2015-06-16 11:11 ` George Dunlap 0 siblings, 1 reply; 88+ messages in thread From: Juergen Gross @ 2015-06-16 10:51 UTC (permalink / raw) To: George Dunlap Cc: Wei Liu, Ian Campbell, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 12:30 PM, George Dunlap wrote: > On Mon, Jun 15, 2015 at 7:26 PM, Juergen Gross <jgross@suse.com> wrote: >> On 06/15/2015 04:34 PM, George Dunlap wrote: >>> >>> On Mon, Jun 15, 2015 at 3:25 PM, Jürgen Groß <jgross@suse.com> wrote: >>>> >>>> On 06/15/2015 04:17 PM, George Dunlap wrote: >>>>> >>>>> >>>>> On Wed, Jun 10, 2015 at 4:20 AM, Chunyan Liu <cyliu@suse.com> wrote: >>>>>> >>>>>> >>>>>> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl >>>>>> index 23f27d4..4561e1b 100644 >>>>>> --- a/tools/libxl/libxl_types.idl >>>>>> +++ b/tools/libxl/libxl_types.idl >>>>>> @@ -541,6 +541,29 @@ libxl_device_pci = Struct("device_pci", [ >>>>>> ("seize", bool), >>>>>> ]) >>>>>> >>>>>> +libxl_usb_protocol = Enumeration("usb_protocol", [ >>>>>> + (0, "AUTO"), >>>>>> + (1, "PV"), >>>>>> + (2, "QEMU"), >>>>>> + ]) >>>>>> + >>>>>> +libxl_device_usbctrl = Struct("device_usbctrl", [ >>>>>> + ("protocol", libxl_usb_protocol), >>>>>> + ("devid", libxl_devid), >>>>>> + ("version", integer), >>>>>> + ("ports", integer), >>>>>> + ("backend_domid", libxl_domid), >>>>>> + ("backend_domname", string), >>>>>> + ]) >>>>>> + >>>>>> +libxl_device_usb = Struct("device_usb", [ >>>>>> + ("ctrl", libxl_devid), >>>>>> + ("port", integer), >>>>>> + ("busid", string), >>>>>> + ("hostbus", integer), >>>>>> + ("hostaddr", integer), >>>>>> + ]) >>>>> >>>>> >>>>> >>>>> Ian / Ian / Wei / Jim: >>>>> >>>>> Question about the design of the interface here. >>>>> >>>>> The way that most systems in Linux specify particular USB devices is >>>>> with the bus:addr format. It's the output you get when you run tools >>>>> like lsusb, for example, and it's the interface that qemu (and thus >>>>> KVM) uses when talking about host devices to assign. bus:addr might >>>>> look like "002:006". >>>>> >>>>> But the bus:addr is a "public api" for Linux; internally, it has a >>>>> more structured format, which contains more about the USB topology. >>>>> Chunyan is calling this "busid". An example is something like this: >>>>> "2-3.1.1:1.0". >>>>> >>>>> Internally, pvusb needs "busid" in order to find the right sysfs >>>>> files. qemu, on the other hand, does not take busid; so the >>>>> devicemodel / HVM implementation of USB would need bus:addr >>>>> internally. >>>> >>>> >>>> >>>> A patch for qemu to support the busid is trivial, as the structures >>>> already contain the necessary elements: >>>> >>>> --- a/hw/usb/host-legacy.c >>>> +++ b/hw/usb/host-legacy.c >>>> @@ -53,11 +53,6 @@ static int parse_filter(const char *spec, struct >>>> USBAutoFilter *f) >>>> const char *p = spec; >>>> int i; >>>> >>>> - f->bus_num = 0; >>>> - f->addr = 0; >>>> - f->vendor_id = 0; >>>> - f->product_id = 0; >>>> - >>>> for (i = BUS; i < DONE; i++) { >>>> p = strpbrk(p, ":."); >>>> if (!p) { >>>> @@ -100,32 +95,47 @@ USBDevice *usb_host_device_open(USBBus *bus, const >>>> char >>>> *devname) >>>> >>>> dev = usb_create(bus, "usb-host"); >>>> >>>> + memset(&filter, 0, sizeof(filter)); >>>> + >>>> if (strstr(devname, "auto:")) { >>>> if (parse_filter(devname, &filter) < 0) { >>>> goto fail; >>>> } >>>> - } else { >>>> - p = strchr(devname, '.'); >>>> - if (p) { >>>> - filter.bus_num = strtoul(devname, NULL, 0); >>>> - filter.addr = strtoul(p + 1, NULL, 0); >>>> - filter.vendor_id = 0; >>>> - filter.product_id = 0; >>>> - } else { >>>> - p = strchr(devname, ':'); >>>> - if (p) { >>>> - filter.bus_num = 0; >>>> - filter.addr = 0; >>>> - filter.vendor_id = strtoul(devname, NULL, 16); >>>> - filter.product_id = strtoul(p + 1, NULL, 16); >>>> - } else { >>>> - goto fail; >>>> - } >>>> - } >>>> + goto out; >>>> } >>>> >>>> + /* Check for <bus>-<port> specification. */ >>>> + p = strchr(devname, '-'); >>>> + if (p && p != devname) { >>>> + filter.bus_num = strtoul(devname, NULL, 0); >>>> + filter.port = p + 1; >>>> + goto out; >>>> + } >>> >>> >>> >>> On my system bus:addr for my mouse is 002:005, while the "busid" (the >>> corresponding directory in sysfs) is 2-3.3. >>> >>> This code doesn't appear to me to parse the above properly; or did I >>> miss something? >> >> >> Filling filter.bus_num and filter.port is enough. This was the only part >> missing in qemu, finding the device via libusb using bus_num and port is >> already existing. At least it is working for me. :-) > > Well, one of us is completely wrong. > > Let's follow the example above: > > $ ls /sys/bus/usb/devices/2-3* > /sys/bus/usb/devices/2-3@ > /sys/bus/usb/devices/2-3.1@ > /sys/bus/usb/devices/2-3:1.0@ > /sys/bus/usb/devices/2-3.1.1@ > /sys/bus/usb/devices/2-3.1:1.0@ > /sys/bus/usb/devices/2-3.1.1:1.0@ > /sys/bus/usb/devices/2-3.1.2@ > /sys/bus/usb/devices/2-3.1.2:1.0@ > /sys/bus/usb/devices/2-3.1.2:1.1@ > /sys/bus/usb/devices/2-3.2@ > /sys/bus/usb/devices/2-3.2:1.0@ > /sys/bus/usb/devices/2-3.3@ > /sys/bus/usb/devices/2-3.3:1.0@ > > $ for i in /sys/bus/usb/devices/2-3*/; do grep . $i/{bus,dev}num ; done > /sys/bus/usb/devices/2-3//busnum:2 > /sys/bus/usb/devices/2-3//devnum:2 > /sys/bus/usb/devices/2-3.1//busnum:2 > /sys/bus/usb/devices/2-3.1//devnum:3 > /sys/bus/usb/devices/2-3.1.1//busnum:2 > /sys/bus/usb/devices/2-3.1.1//devnum:6 > /sys/bus/usb/devices/2-3.1.2//busnum:2 > /sys/bus/usb/devices/2-3.1.2//devnum:10 > /sys/bus/usb/devices/2-3.2//busnum:2 > /sys/bus/usb/devices/2-3.2//devnum:4 > /sys/bus/usb/devices/2-3.3//busnum:2 > /sys/bus/usb/devices/2-3.3//devnum:5 > > $ lsusb | grep "Bus 002" > Bus 002 Device 005: ID 046d:c016 Logitech, Inc. Optical Wheel Mouse > Bus 002 Device 004: ID f617:0905 > Bus 002 Device 010: ID 1050:0111 Yubico.com > Bus 002 Device 006: ID 0424:4060 Standard Microsystems Corp. Ultra > Fast Media Reader > Bus 002 Device 003: ID 0424:2640 Standard Microsystems Corp. USB 2.0 Hub > Bus 002 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub > Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub > > In other words, there are 6 distinct devices that correspond to "bus 2 > port 3". I don't know what it was you were passing through, but > giving qemu (or libusb) only "2-3" is absolutely not enough for it to > distinquish between my mouse (002:005, at 2-3.3) and my yubikey > (002:010 at 2-3.1.2). That's why the bus:addr convention was invented > in the first place, I presume -- to abstract away the topology of the > USB hubs for the user. > > The "busid" interface that Chunyan is describing requires the caller > to find out that long name -- 2-3.1.2 -- rather than the traditional > short name (002:010). Just accepting "2-3" is not sufficient. qemu with my patch will find the device only if the long name is used. So the "port" in qemu would be "3.1.2" in your example above. BTW: be careful with the syntax: x:y is used by qemu to specify a device by vendorId:productId, you should write "002.010" to use the short name above. Juergen _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 10:51 ` Juergen Gross @ 2015-06-16 11:11 ` George Dunlap 2015-06-16 11:19 ` Juergen Gross 0 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-16 11:11 UTC (permalink / raw) To: Juergen Gross Cc: Wei Liu, Ian Campbell, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Tue, Jun 16, 2015 at 11:51 AM, Juergen Gross <jgross@suse.com> wrote: >> The "busid" interface that Chunyan is describing requires the caller >> to find out that long name -- 2-3.1.2 -- rather than the traditional >> short name (002:010). Just accepting "2-3" is not sufficient. > > > qemu with my patch will find the device only if the long name is used. > So the "port" in qemu would be "3.1.2" in your example above. Ah, right -- sorry, looking at the patch I saw that "port" was converted using strtoul, but now I see that was "bus", and that "port" is a string. That's what I was missing. > BTW: be careful with the syntax: x:y is used by qemu to specify a device > by vendorId:productId, you should write "002.010" to use the short name > above. Yes, thanks for the reminder. I knew there was some way to distinguish bus.addr and vendor:device, but I'd forgotten the exact semantics. So as Juergen says, the typical way to write these would be: - bus-port; e.g., 2-3.1.2 is bus=2, port=3.1.2. Stable in topology, not in device - bus.addr: e.g., 2.10 is bus=2, address=10. Unique every time a device is plugged in (so no risk of aliasing, but not stable across reboots) - vendorid:deviceid: e.g., 1050:0111 is vendorid=1050, deviceid=0111. Stable on device class (so same no matter when or where you plug it in, but can't tell two identical devices apart). -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:11 ` George Dunlap @ 2015-06-16 11:19 ` Juergen Gross 2015-06-16 11:23 ` George Dunlap 0 siblings, 1 reply; 88+ messages in thread From: Juergen Gross @ 2015-06-16 11:19 UTC (permalink / raw) To: George Dunlap Cc: Wei Liu, Ian Campbell, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 01:11 PM, George Dunlap wrote: > On Tue, Jun 16, 2015 at 11:51 AM, Juergen Gross <jgross@suse.com> wrote: >>> The "busid" interface that Chunyan is describing requires the caller >>> to find out that long name -- 2-3.1.2 -- rather than the traditional >>> short name (002:010). Just accepting "2-3" is not sufficient. >> >> >> qemu with my patch will find the device only if the long name is used. >> So the "port" in qemu would be "3.1.2" in your example above. > > Ah, right -- sorry, looking at the patch I saw that "port" was > converted using strtoul, but now I see that was "bus", and that "port" > is a string. That's what I was missing. > >> BTW: be careful with the syntax: x:y is used by qemu to specify a device >> by vendorId:productId, you should write "002.010" to use the short name >> above. > > Yes, thanks for the reminder. I knew there was some way to > distinguish bus.addr and vendor:device, but I'd forgotten the exact > semantics. > > So as Juergen says, the typical way to write these would be: > - bus-port; e.g., 2-3.1.2 is bus=2, port=3.1.2. Stable in topology, > not in device Nah, not stable in topology. At least on my laptop I've seen a memory stick plugged in at the same position as "3-3" or as "1-3". I'm pretty sure this is just a matter of timing during boot: the busses are all (or at least some of them) queried at the same time and the first answering gets number 1, the next 2, and so on. And timing seems to be different enough to result in unstable bus numbers. Juergen > - bus.addr: e.g., 2.10 is bus=2, address=10. Unique every time a > device is plugged in (so no risk of aliasing, but not stable across > reboots) > - vendorid:deviceid: e.g., 1050:0111 is vendorid=1050, deviceid=0111. > Stable on device class (so same no matter when or where you plug it > in, but can't tell two identical devices apart). > > -George > ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:19 ` Juergen Gross @ 2015-06-16 11:23 ` George Dunlap 2015-06-16 11:44 ` Ian Jackson 0 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-16 11:23 UTC (permalink / raw) To: Juergen Gross Cc: Wei Liu, Ian Campbell, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Tue, Jun 16, 2015 at 12:19 PM, Juergen Gross <jgross@suse.com> wrote: > On 06/16/2015 01:11 PM, George Dunlap wrote: >> >> On Tue, Jun 16, 2015 at 11:51 AM, Juergen Gross <jgross@suse.com> wrote: >>>> >>>> The "busid" interface that Chunyan is describing requires the caller >>>> to find out that long name -- 2-3.1.2 -- rather than the traditional >>>> short name (002:010). Just accepting "2-3" is not sufficient. >>> >>> >>> >>> qemu with my patch will find the device only if the long name is used. >>> So the "port" in qemu would be "3.1.2" in your example above. >> >> >> Ah, right -- sorry, looking at the patch I saw that "port" was >> converted using strtoul, but now I see that was "bus", and that "port" >> is a string. That's what I was missing. >> >>> BTW: be careful with the syntax: x:y is used by qemu to specify a device >>> by vendorId:productId, you should write "002.010" to use the short name >>> above. >> >> >> Yes, thanks for the reminder. I knew there was some way to >> distinguish bus.addr and vendor:device, but I'd forgotten the exact >> semantics. >> >> So as Juergen says, the typical way to write these would be: >> - bus-port; e.g., 2-3.1.2 is bus=2, port=3.1.2. Stable in topology, >> not in device > > > Nah, not stable in topology. At least on my laptop I've seen a memory > stick plugged in at the same position as "3-3" or as "1-3". > > I'm pretty sure this is just a matter of timing during boot: the busses > are all (or at least some of them) queried at the same time and the > first answering gets number 1, the next 2, and so on. And timing seems > to be different enough to result in unstable bus numbers. Right -- I meant "stable in topology within one boot", but at least two of you have now understood me to mean "across reboots" by default, so that's obviously a detail that needs to be specified. :-) -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:23 ` George Dunlap @ 2015-06-16 11:44 ` Ian Jackson 2015-06-17 11:24 ` Ian Campbell 0 siblings, 1 reply; 88+ messages in thread From: Ian Jackson @ 2015-06-16 11:44 UTC (permalink / raw) To: George Dunlap Cc: Juergen Gross, Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > On Tue, Jun 16, 2015 at 12:19 PM, Juergen Gross <jgross@suse.com> wrote: > > I'm pretty sure this is just a matter of timing during boot: the busses > > are all (or at least some of them) queried at the same time and the > > first answering gets number 1, the next 2, and so on. And timing seems > > to be different enough to result in unstable bus numbers. > > Right -- I meant "stable in topology within one boot", but at least > two of you have now understood me to mean "across reboots" by default, > so that's obviously a detail that needs to be specified. :-) I think "stable in topology within one boot" is nearly vacuous (or are we expecting buses or devices to spontaneously renumber themselves for no reason) and also nearly useless. We definitely need _some_ way for a user to identify a specific device uniquely in a way that is reliable from one boot to the next. vid:pid is one way to do this, but not always sufficient. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:44 ` Ian Jackson @ 2015-06-17 11:24 ` Ian Campbell 2015-06-18 11:50 ` George Dunlap 2015-06-18 12:08 ` George Dunlap 0 siblings, 2 replies; 88+ messages in thread From: Ian Campbell @ 2015-06-17 11:24 UTC (permalink / raw) To: Ian Jackson Cc: Juergen Gross, Wei Liu, George Dunlap, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Tue, 2015-06-16 at 12:44 +0100, Ian Jackson wrote: > George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > > On Tue, Jun 16, 2015 at 12:19 PM, Juergen Gross <jgross@suse.com> wrote: > > > I'm pretty sure this is just a matter of timing during boot: the busses > > > are all (or at least some of them) queried at the same time and the > > > first answering gets number 1, the next 2, and so on. And timing seems > > > to be different enough to result in unstable bus numbers. > > > > Right -- I meant "stable in topology within one boot", but at least > > two of you have now understood me to mean "across reboots" by default, > > so that's obviously a detail that needs to be specified. :-) > > I think "stable in topology within one boot" is nearly vacuous (or are > we expecting buses or devices to spontaneously renumber themselves for > no reason) and also nearly useless. > > We definitely need _some_ way for a user to identify a specific device > uniquely in a way that is reliable from one boot to the next. vid:pid > is one way to do this, but not always sufficient. We should perhaps separate out the "end user" from the "libxl user" (i.e. the toolstack application) in our deliberations here. We have the option of settling on a single way of describing a device to libxl in the libxl API but allowing the toolstack to choose to present the user with multiple different ways to specify things by providing a suitable set of helper functions (in either libxlu or libxl proper) from a variety of schemes to the one true way of describing a device. That sounds better to me than having the libxl API consist of the union of all potentially useful ways to refer to a device. I'm not sure whether that also gives us the freedom to use something which is only stable for a given boot at the libxl API layer though. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-17 11:24 ` Ian Campbell @ 2015-06-18 11:50 ` George Dunlap 2015-06-18 12:08 ` George Dunlap 1 sibling, 0 replies; 88+ messages in thread From: George Dunlap @ 2015-06-18 11:50 UTC (permalink / raw) To: Ian Campbell, Ian Jackson Cc: Juergen Gross, Wei Liu, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/17/2015 12:24 PM, Ian Campbell wrote: > On Tue, 2015-06-16 at 12:44 +0100, Ian Jackson wrote: >> George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): >>> On Tue, Jun 16, 2015 at 12:19 PM, Juergen Gross <jgross@suse.com> wrote: >>>> I'm pretty sure this is just a matter of timing during boot: the busses >>>> are all (or at least some of them) queried at the same time and the >>>> first answering gets number 1, the next 2, and so on. And timing seems >>>> to be different enough to result in unstable bus numbers. >>> >>> Right -- I meant "stable in topology within one boot", but at least >>> two of you have now understood me to mean "across reboots" by default, >>> so that's obviously a detail that needs to be specified. :-) >> >> I think "stable in topology within one boot" is nearly vacuous (or are >> we expecting buses or devices to spontaneously renumber themselves for >> no reason) and also nearly useless. >> >> We definitely need _some_ way for a user to identify a specific device >> uniquely in a way that is reliable from one boot to the next. vid:pid >> is one way to do this, but not always sufficient. > > We should perhaps separate out the "end user" from the "libxl > user" (i.e. the toolstack application) in our deliberations here. > > We have the option of settling on a single way of describing a device to > libxl in the libxl API but allowing the toolstack to choose to present > the user with multiple different ways to specify things by providing a > suitable set of helper functions (in either libxlu or libxl proper) from > a variety of schemes to the one true way of describing a device. > > That sounds better to me than having the libxl API consist of the union > of all potentially useful ways to refer to a device. > > I'm not sure whether that also gives us the freedom to use something > which is only stable for a given boot at the libxl API layer though. [snip] > As a slight aside to this, can't libxl use libusb for a lot of this > stuff and therefore avoid being Linux specific? > > http://libusb.info/ claims to support "Linux, OS X, Windows, Windows CE, > Android, OpenBSD/NetBSD, Haiku.". Interestingly FreeBSD is missing there > but I don't think that need to be a blocker. > > I don't see a problem with adding libusb to our set of dependencies, and > it's certainly got to be better than (re)implementing a bunch of sysfs > stuff (which I presume is what libusb does under the hood anyway). OK, so we have three interfaces: * User <-> toolstack * toolstack <-> libxl * libxl <-> underlying functionality (Linux pvusbback and qemu, at the moment) And we're also now considering whether to do a "minimal interface" in libxl (i.e., only accept one kind of specification and make the toolstack do the conversion from a more useful spec) or do a "rich interface" (i.e., accept many different kinds of specification, allowing the toolstack to just pass things through). qemu already uses libusb, and so can already do almost everything that libxl could use libusb to accomplish. The only things it doesn't do that we've talked about doing are the bus-ports specification, and the "vendorid:deviceid:serialno" specification; both of which would be trivial (and probably useful) to add. So for all the things libusb can be used to convert between, we don't actually need to do any conversion when speaking to qemu (unless we want to be backwards compatible with older versions). The udev "id_path" specification isn't something that libusb can handle; we'd have to mess around with sysfs and/or udev-created device nodes / symbolic links into sysfs anyway. So for the qemu side of things, libusb is mostly useless. We can't get around using sysfs to talk to pvusbback -- that's how it works. At the moment, the pvusbback interface requires sysfs strings, which happen to be described in the bus-ports:interface format. So the main reason we're messing around with sysfs at the moment is to convert other specifications into the sysfs strings suitable for using with pvusb. To convert into a sysfs string ourselves: * readdir on /sys/bus/usb/devices * for each entry, look inside to see if it matches the specification (i.e., bus==busnum, addr==devnum, &c) * take the directory name of the entry that matches * look inside that directory for all the interfaces for that device (so we can assign each one to pvusbback). * Write the strings you read from sysfs into the appropriate "bind" nodes in pvusbback To convert bus.addr into a sysfs string with libusb: * libusb_get_device_list [1] * for each entry, call libusb_get_device_descriptor and see if it matches the specification (i.e., bus==bus, addr==addr, &c) * Call libusb_get_ports to get an array of the port numbers * Construct a sysfs string from the bus number and the array of port numbers (i.e., %d-%d[.%d.%d]) * Get information about all the interfaces, and construct sysfs strings from those as well * Write the constructed strings into the pciback sysfs nodes A couple of points: 1. The second is certainly not simpler than the first 2. The only code that needs to do it is completely linux-specific at the moment anyway (since it's talking to the linux driver) 3. The first uses strings that it pulled directly from sysfs; the second relies on constructing strings 4. If we do a "minimal interface" in libxl, then the toolstack will also have to link against libusb to convert from a more useful specification to the libxl specification So it seems to me that libusb doesn't actually have that much to offer us. For the only situation where it actually is cross-platform (i.e., qemu), it's not needed; for the one situation where it could be used (converting to sysfs-style strings for pvusbback), it's not simpler, probably less robust, and its cross-platform capability is moot (since it's a Linux-only driver anyway). -George [1] See http://libusb.sourceforge.net/api-1.0/group__dev.html and http://libusb.sourceforge.net/api-1.0/group__desc.html ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-17 11:24 ` Ian Campbell 2015-06-18 11:50 ` George Dunlap @ 2015-06-18 12:08 ` George Dunlap 2015-06-18 13:03 ` Juergen Gross 2015-06-22 13:29 ` Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) George Dunlap 1 sibling, 2 replies; 88+ messages in thread From: George Dunlap @ 2015-06-18 12:08 UTC (permalink / raw) To: Ian Campbell, Ian Jackson Cc: Juergen Gross, Wei Liu, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/17/2015 12:24 PM, Ian Campbell wrote: > On Tue, 2015-06-16 at 12:44 +0100, Ian Jackson wrote: >> George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): >>> On Tue, Jun 16, 2015 at 12:19 PM, Juergen Gross <jgross@suse.com> wrote: >>>> I'm pretty sure this is just a matter of timing during boot: the busses >>>> are all (or at least some of them) queried at the same time and the >>>> first answering gets number 1, the next 2, and so on. And timing seems >>>> to be different enough to result in unstable bus numbers. >>> >>> Right -- I meant "stable in topology within one boot", but at least >>> two of you have now understood me to mean "across reboots" by default, >>> so that's obviously a detail that needs to be specified. :-) >> >> I think "stable in topology within one boot" is nearly vacuous (or are >> we expecting buses or devices to spontaneously renumber themselves for >> no reason) and also nearly useless. >> >> We definitely need _some_ way for a user to identify a specific device >> uniquely in a way that is reliable from one boot to the next. vid:pid >> is one way to do this, but not always sufficient. > > We should perhaps separate out the "end user" from the "libxl > user" (i.e. the toolstack application) in our deliberations here. > > We have the option of settling on a single way of describing a device to > libxl in the libxl API but allowing the toolstack to choose to present > the user with multiple different ways to specify things by providing a > suitable set of helper functions (in either libxlu or libxl proper) from > a variety of schemes to the one true way of describing a device. > > That sounds better to me than having the libxl API consist of the union > of all potentially useful ways to refer to a device. This was my original design. :-) > I'm not sure whether that also gives us the freedom to use something > which is only stable for a given boot at the libxl API layer though. I'm not sure why it doesn't -- as long as things don't change between the time the toostack converts a "stable name" into a specification and the time libxl uses it, it should be fine. One advantage of having a richer interface that Juergen pointed out previously was the ability to specify attaching devices automatically when they show yp; i.e., "If a device with this vendorid:deviceid:serialnumber shows up, please attach it to this VM". But we don't have that functionality now; and there's no reason we couldn't add extra ways of specifying devices in the future. This usb interface stuff is really becoming a morass. The core functionality is fairly independent of the interface. I'm inclined to say that we should start with a simple specification (only bus.addr), and try to get both pvusb and hvmusb in. Then we can talk about where to add additional specifications (including cross-boot stable specifcations). -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-18 12:08 ` George Dunlap @ 2015-06-18 13:03 ` Juergen Gross 2015-06-22 13:29 ` Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) George Dunlap 1 sibling, 0 replies; 88+ messages in thread From: Juergen Gross @ 2015-06-18 13:03 UTC (permalink / raw) To: George Dunlap, Ian Campbell, Ian Jackson Cc: Jim Fehlig, Simon Cao, Wei Liu, Chunyan Liu, xen-devel On 06/18/2015 02:08 PM, George Dunlap wrote: > On 06/17/2015 12:24 PM, Ian Campbell wrote: >> On Tue, 2015-06-16 at 12:44 +0100, Ian Jackson wrote: >>> George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): >>>> On Tue, Jun 16, 2015 at 12:19 PM, Juergen Gross <jgross@suse.com> wrote: >>>>> I'm pretty sure this is just a matter of timing during boot: the busses >>>>> are all (or at least some of them) queried at the same time and the >>>>> first answering gets number 1, the next 2, and so on. And timing seems >>>>> to be different enough to result in unstable bus numbers. >>>> >>>> Right -- I meant "stable in topology within one boot", but at least >>>> two of you have now understood me to mean "across reboots" by default, >>>> so that's obviously a detail that needs to be specified. :-) >>> >>> I think "stable in topology within one boot" is nearly vacuous (or are >>> we expecting buses or devices to spontaneously renumber themselves for >>> no reason) and also nearly useless. >>> >>> We definitely need _some_ way for a user to identify a specific device >>> uniquely in a way that is reliable from one boot to the next. vid:pid >>> is one way to do this, but not always sufficient. >> >> We should perhaps separate out the "end user" from the "libxl >> user" (i.e. the toolstack application) in our deliberations here. >> >> We have the option of settling on a single way of describing a device to >> libxl in the libxl API but allowing the toolstack to choose to present >> the user with multiple different ways to specify things by providing a >> suitable set of helper functions (in either libxlu or libxl proper) from >> a variety of schemes to the one true way of describing a device. >> >> That sounds better to me than having the libxl API consist of the union >> of all potentially useful ways to refer to a device. > > This was my original design. :-) > >> I'm not sure whether that also gives us the freedom to use something >> which is only stable for a given boot at the libxl API layer though. > > I'm not sure why it doesn't -- as long as things don't change between > the time the toostack converts a "stable name" into a specification and > the time libxl uses it, it should be fine. > > One advantage of having a richer interface that Juergen pointed out > previously was the ability to specify attaching devices automatically > when they show yp; i.e., "If a device with this > vendorid:deviceid:serialnumber shows up, please attach it to this VM". > > But we don't have that functionality now; and there's no reason we > couldn't add extra ways of specifying devices in the future. > > This usb interface stuff is really becoming a morass. The core > functionality is fairly independent of the interface. I'm inclined to > say that we should start with a simple specification (only bus.addr), > and try to get both pvusb and hvmusb in. Then we can talk about where > to add additional specifications (including cross-boot stable > specifcations). +1 Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) 2015-06-18 12:08 ` George Dunlap 2015-06-18 13:03 ` Juergen Gross @ 2015-06-22 13:29 ` George Dunlap 2015-06-22 14:14 ` Juergen Gross ` (4 more replies) 1 sibling, 5 replies; 88+ messages in thread From: George Dunlap @ 2015-06-22 13:29 UTC (permalink / raw) To: Ian Campbell, Ian Jackson Cc: Juergen Gross, Wei Liu, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/18/2015 01:08 PM, George Dunlap wrote: > This usb interface stuff is really becoming a morass. The core > functionality is fairly independent of the interface. I'm inclined to > say that we should start with a simple specification (only bus.addr), > and try to get both pvusb and hvmusb in. Then we can talk about where > to add additional specifications (including cross-boot stable > specifcations). So Ian J, Ian C, Wei and I chatted face-to-face about what to do going forward; below are some key points we discussed and the conclusion we came to. Decisions are only official when they've been discussed on the list, so please consider this a proposal and give your feedback. :-) (Also, Ian/Ian/Wei, let me know if I've misremembered or forgotten something.) Points of discussion: * We would ideally like to be able to have the released interface work both for both PV and HVM; for one so that we don't have to have separate #defines for that functionality; but also to make sure that the interface is suitable for both functionalities. * It's difficult at the moment to actually do collaborative development on the libxl USB feature, because the code is not yet in the tree. * Regarding user-facing interfaces (like xl, as opposed to libxl): the interface cannot be half-baked; it should not provide functionality which works most of the time but sometimes will fail. Having only "bus-ports" or "vendorid:deviceid" is not sufficient, because it will lure the user into thinking that they can put those numbers into a config file and get repeatable results every time. But since bus numbers change, and vendorid:deviceid is not unique, either of these would be a false promise. Udevs ID_PATH naming scheme seems like a sensible thing to adopt, at least for Linux. We could consider making an OS-specific string for identifying the same device across reboots. On the other hand, bus.address is very obviously unstable; nobody in their right mind would use it for anything they wanted to persist across reboots. So including bus.address as a temporary measure to be able to test the underlying library until we get a more reliable naming scheme in place would be OK, as long as the UI interface could be extended going forward. * We should avoid adding complexity to the libxl interface until it's needed; accepting one way of specifying USB devices, and letting the toolstack do translation into that way of specifying it (perhaps providing helper libraries to do so), should be enough for now. The way of specifying USB devices does not need to be stable across reboots, as long as it won't change between the time the toolstack does the translation and the time the device is plugged in. bus.address is the best specification from that point of view: it's unique (unlike device:vendorid), and if a device is unplugged and another one plugged in between the time the translation happens and the time libxl gets around to doing something, the old bus.address won't exist anymore and the command will fail. * There may be a point in the future when we want to be able provide device auto-plug functionality at the libxl layer. (i.e., "When device X shows up, please plug it into VM Y.") For this we will need a reliable way of specifying devices; bus.address will not do. But that functionality doesn't exist yet; so for now we should stick with bus.address, but design the interface such that it can be extended with more options for specifying a device when such functionality is neede. With all that in mind, here is a proposal: 1. For the moment, only use bus.address at the libxl layer to specify a device. 2. Let's check in the libxl part of Chunyan's PVUSB series as soon as the 4.7 development window opens (assuming the coding style issues have all been addressed). We can also check in the xl functionality with minimal bus.address support for testing. 3. I will the port the HVM USB series and submit them as soon as possible. 4. We work on a set of helper functions that a toolstack can use to translate other ways of specifying a device, much like the disk specification helper functions that we provide. One of these should be something which is reliably stable over reboots, such as the udev ID_PATH specification. Thoughts? -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) 2015-06-22 13:29 ` Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) George Dunlap @ 2015-06-22 14:14 ` Juergen Gross 2015-06-22 14:22 ` Ian Jackson ` (3 subsequent siblings) 4 siblings, 0 replies; 88+ messages in thread From: Juergen Gross @ 2015-06-22 14:14 UTC (permalink / raw) To: George Dunlap, Ian Campbell, Ian Jackson Cc: Jim Fehlig, Simon Cao, Wei Liu, Chunyan Liu, xen-devel On 06/22/2015 03:29 PM, George Dunlap wrote: > On 06/18/2015 01:08 PM, George Dunlap wrote: >> This usb interface stuff is really becoming a morass. The core >> functionality is fairly independent of the interface. I'm inclined to >> say that we should start with a simple specification (only bus.addr), >> and try to get both pvusb and hvmusb in. Then we can talk about where >> to add additional specifications (including cross-boot stable >> specifcations). > > So Ian J, Ian C, Wei and I chatted face-to-face about what to do going > forward; below are some key points we discussed and the conclusion we > came to. Decisions are only official when they've been discussed on the > list, so please consider this a proposal and give your feedback. :-) > > (Also, Ian/Ian/Wei, let me know if I've misremembered or forgotten > something.) > > Points of discussion: > > * We would ideally like to be able to have the released interface work > both for both PV and HVM; for one so that we don't have to have separate > #defines for that functionality; but also to make sure that the > interface is suitable for both functionalities. > > * It's difficult at the moment to actually do collaborative development > on the libxl USB feature, because the code is not yet in the tree. > > * Regarding user-facing interfaces (like xl, as opposed to libxl): the > interface cannot be half-baked; it should not provide functionality > which works most of the time but sometimes will fail. > > Having only "bus-ports" or "vendorid:deviceid" is not sufficient, > because it will lure the user into thinking that they can put those > numbers into a config file and get repeatable results every time. But > since bus numbers change, and vendorid:deviceid is not unique, either of > these would be a false promise. > > Udevs ID_PATH naming scheme seems like a sensible thing to adopt, at > least for Linux. We could consider making an OS-specific string for > identifying the same device across reboots. > > On the other hand, bus.address is very obviously unstable; nobody in > their right mind would use it for anything they wanted to persist across > reboots. So including bus.address as a temporary measure to be able to > test the underlying library until we get a more reliable naming scheme > in place would be OK, as long as the UI interface could be extended > going forward. > > * We should avoid adding complexity to the libxl interface until it's > needed; accepting one way of specifying USB devices, and letting the > toolstack do translation into that way of specifying it (perhaps > providing helper libraries to do so), should be enough for now. The way > of specifying USB devices does not need to be stable across reboots, as > long as it won't change between the time the toolstack does the > translation and the time the device is plugged in. > > bus.address is the best specification from that point of view: it's > unique (unlike device:vendorid), and if a device is unplugged and > another one plugged in between the time the translation happens and the > time libxl gets around to doing something, the old bus.address won't > exist anymore and the command will fail. > > * There may be a point in the future when we want to be able provide > device auto-plug functionality at the libxl layer. (i.e., "When device > X shows up, please plug it into VM Y.") For this we will need a > reliable way of specifying devices; bus.address will not do. > > But that functionality doesn't exist yet; so for now we should stick > with bus.address, but design the interface such that it can be extended > with more options for specifying a device when such functionality is neede. > > With all that in mind, here is a proposal: > > 1. For the moment, only use bus.address at the libxl layer to specify a > device. > > 2. Let's check in the libxl part of Chunyan's PVUSB series as soon as > the 4.7 development window opens (assuming the coding style issues have > all been addressed). We can also check in the xl functionality with > minimal bus.address support for testing. > > 3. I will the port the HVM USB series and submit them as soon as possible. > > 4. We work on a set of helper functions that a toolstack can use to > translate other ways of specifying a device, much like the disk > specification helper functions that we provide. One of these should be > something which is reliably stable over reboots, such as the udev > ID_PATH specification. > > Thoughts? I'm absolutely fine with this proposal. Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) 2015-06-22 13:29 ` Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) George Dunlap 2015-06-22 14:14 ` Juergen Gross @ 2015-06-22 14:22 ` Ian Jackson 2015-06-23 2:42 ` Chun Yan Liu ` (2 subsequent siblings) 4 siblings, 0 replies; 88+ messages in thread From: Ian Jackson @ 2015-06-22 14:22 UTC (permalink / raw) To: George Dunlap Cc: Juergen Gross, Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao George Dunlap writes ("Proposed plan for libxl USB interface (was Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API)"): > With all that in mind, here is a proposal: FAOD, this all sounds good. I have one comment on this: > 4. We work on a set of helper functions that a toolstack can use to > translate other ways of specifying a device, much like the disk > specification helper functions that we provide. One of these should be > something which is reliably stable over reboots, such as the udev > ID_PATH specification. We should invent, similar to the disk specification, a specification for how to interpret a string referring to a usb device. That can be used by xl but also by libvirt and anyone else that wants to. If we don't know right away how this will work, then we should come up with a temporary arrangement which encodes bus.address in a region of the string syntax space which we are confident we won't need in the future for something else. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) 2015-06-22 13:29 ` Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) George Dunlap 2015-06-22 14:14 ` Juergen Gross 2015-06-22 14:22 ` Ian Jackson @ 2015-06-23 2:42 ` Chun Yan Liu 2015-06-23 2:43 ` Chun Yan Liu 2015-06-23 2:44 ` Chun Yan Liu 4 siblings, 0 replies; 88+ messages in thread From: Chun Yan Liu @ 2015-06-23 2:42 UTC (permalink / raw) To: Ian Campbell, George Dunlap, Ian Jackson Cc: Juergen Gross, Jim Fehlig, Simon Cao, Wei Liu, xen-devel >>> On 6/22/2015 at 09:29 PM, in message <55880DCC.6070902@eu.citrix.com>, George Dunlap <george.dunlap@eu.citrix.com> wrote: > On 06/18/2015 01:08 PM, George Dunlap wrote: > > This usb interface stuff is really becoming a morass. The core > > functionality is fairly independent of the interface. I'm inclined to > > say that we should start with a simple specification (only bus.addr), > > and try to get both pvusb and hvmusb in. Then we can talk about where > > to add additional specifications (including cross-boot stable > > specifcations). > > So Ian J, Ian C, Wei and I chatted face-to-face about what to do going > forward; below are some key points we discussed and the conclusion we > came to. Decisions are only official when they've been discussed on the > list, so please consider this a proposal and give your feedback. :-) > > (Also, Ian/Ian/Wei, let me know if I've misremembered or forgotten > something.) > > Points of discussion: > > * We would ideally like to be able to have the released interface work > both for both PV and HVM; for one so that we don't have to have separate > #defines for that functionality; but also to make sure that the > interface is suitable for both functionalities. > > * It's difficult at the moment to actually do collaborative development > on the libxl USB feature, because the code is not yet in the tree. > > * Regarding user-facing interfaces (like xl, as opposed to libxl): the > interface cannot be half-baked; it should not provide functionality > which works most of the time but sometimes will fail. > > Having only "bus-ports" or "vendorid:deviceid" is not sufficient, > because it will lure the user into thinking that they can put those > numbers into a config file and get repeatable results every time. But > since bus numbers change, and vendorid:deviceid is not unique, either of > these would be a false promise. > > Udevs ID_PATH naming scheme seems like a sensible thing to adopt, at > least for Linux. We could consider making an OS-specific string for > identifying the same device across reboots. > > On the other hand, bus.address is very obviously unstable; nobody in > their right mind would use it for anything they wanted to persist across > reboots. So including bus.address as a temporary measure to be able to > test the underlying library until we get a more reliable naming scheme > in place would be OK, as long as the UI interface could be extended > going forward. > > * We should avoid adding complexity to the libxl interface until it's > needed; accepting one way of specifying USB devices, and letting the > toolstack do translation into that way of specifying it (perhaps > providing helper libraries to do so), should be enough for now. The way > of specifying USB devices does not need to be stable across reboots, as > long as it won't change between the time the toolstack does the > translation and the time the device is plugged in. > > bus.address is the best specification from that point of view: it's > unique (unlike device:vendorid), and if a device is unplugged and > another one plugged in between the time the translation happens and the > time libxl gets around to doing something, the old bus.address won't > exist anymore and the command will fail. > > * There may be a point in the future when we want to be able provide > device auto-plug functionality at the libxl layer. (i.e., "When device > X shows up, please plug it into VM Y.") For this we will need a > reliable way of specifying devices; bus.address will not do. > > But that functionality doesn't exist yet; so for now we should stick > with bus.address, but design the interface such that it can be extended > with more options for specifying a device when such functionality is neede. > > With all that in mind, here is a proposal: > > 1. For the moment, only use bus.address at the libxl layer to specify a > device. > > 2. Let's check in the libxl part of Chunyan's PVUSB series as soon as > the 4.7 development window opens (assuming the coding style issues have > all been addressed). We can also check in the xl functionality with > minimal bus.address support for testing. > > 3. I will the port the HVM USB series and submit them as soon as possible. > > 4. We work on a set of helper functions that a toolstack can use to > translate other ways of specifying a device, much like the disk > specification helper functions that we provide. One of these should be > something which is reliably stable over reboots, such as the udev > ID_PATH specification. > > Thoughts? Fine to me. > > -George > > ^ permalink raw reply [flat|nested] 88+ messages in thread
* Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) 2015-06-22 13:29 ` Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) George Dunlap ` (2 preceding siblings ...) 2015-06-23 2:42 ` Chun Yan Liu @ 2015-06-23 2:43 ` Chun Yan Liu 2015-06-23 2:44 ` Chun Yan Liu 4 siblings, 0 replies; 88+ messages in thread From: Chun Yan Liu @ 2015-06-23 2:43 UTC (permalink / raw) To: Ian Campbell, George Dunlap, Ian Jackson Cc: Juergen Gross, Jim Fehlig, Simon Cao, Wei Liu, xen-devel >>> On 6/22/2015 at 09:29 PM, in message <55880DCC.6070902@eu.citrix.com>, George Dunlap <george.dunlap@eu.citrix.com> wrote: > On 06/18/2015 01:08 PM, George Dunlap wrote: > > This usb interface stuff is really becoming a morass. The core > > functionality is fairly independent of the interface. I'm inclined to > > say that we should start with a simple specification (only bus.addr), > > and try to get both pvusb and hvmusb in. Then we can talk about where > > to add additional specifications (including cross-boot stable > > specifcations). > > So Ian J, Ian C, Wei and I chatted face-to-face about what to do going > forward; below are some key points we discussed and the conclusion we > came to. Decisions are only official when they've been discussed on the > list, so please consider this a proposal and give your feedback. :-) > > (Also, Ian/Ian/Wei, let me know if I've misremembered or forgotten > something.) > > Points of discussion: > > * We would ideally like to be able to have the released interface work > both for both PV and HVM; for one so that we don't have to have separate > #defines for that functionality; but also to make sure that the > interface is suitable for both functionalities. > > * It's difficult at the moment to actually do collaborative development > on the libxl USB feature, because the code is not yet in the tree. > > * Regarding user-facing interfaces (like xl, as opposed to libxl): the > interface cannot be half-baked; it should not provide functionality > which works most of the time but sometimes will fail. > > Having only "bus-ports" or "vendorid:deviceid" is not sufficient, > because it will lure the user into thinking that they can put those > numbers into a config file and get repeatable results every time. But > since bus numbers change, and vendorid:deviceid is not unique, either of > these would be a false promise. > > Udevs ID_PATH naming scheme seems like a sensible thing to adopt, at > least for Linux. We could consider making an OS-specific string for > identifying the same device across reboots. > > On the other hand, bus.address is very obviously unstable; nobody in > their right mind would use it for anything they wanted to persist across > reboots. So including bus.address as a temporary measure to be able to > test the underlying library until we get a more reliable naming scheme > in place would be OK, as long as the UI interface could be extended > going forward. > > * We should avoid adding complexity to the libxl interface until it's > needed; accepting one way of specifying USB devices, and letting the > toolstack do translation into that way of specifying it (perhaps > providing helper libraries to do so), should be enough for now. The way > of specifying USB devices does not need to be stable across reboots, as > long as it won't change between the time the toolstack does the > translation and the time the device is plugged in. > > bus.address is the best specification from that point of view: it's > unique (unlike device:vendorid), and if a device is unplugged and > another one plugged in between the time the translation happens and the > time libxl gets around to doing something, the old bus.address won't > exist anymore and the command will fail. > > * There may be a point in the future when we want to be able provide > device auto-plug functionality at the libxl layer. (i.e., "When device > X shows up, please plug it into VM Y.") For this we will need a > reliable way of specifying devices; bus.address will not do. > > But that functionality doesn't exist yet; so for now we should stick > with bus.address, but design the interface such that it can be extended > with more options for specifying a device when such functionality is neede. > > With all that in mind, here is a proposal: > > 1. For the moment, only use bus.address at the libxl layer to specify a > device. > > 2. Let's check in the libxl part of Chunyan's PVUSB series as soon as > the 4.7 development window opens (assuming the coding style issues have > all been addressed). We can also check in the xl functionality with > minimal bus.address support for testing. > > 3. I will the port the HVM USB series and submit them as soon as possible. > > 4. We work on a set of helper functions that a toolstack can use to > translate other ways of specifying a device, much like the disk > specification helper functions that we provide. One of these should be > something which is reliably stable over reboots, such as the udev > ID_PATH specification. > > Thoughts? Fine to me. > > -George > > ^ permalink raw reply [flat|nested] 88+ messages in thread
* Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) 2015-06-22 13:29 ` Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) George Dunlap ` (3 preceding siblings ...) 2015-06-23 2:43 ` Chun Yan Liu @ 2015-06-23 2:44 ` Chun Yan Liu 4 siblings, 0 replies; 88+ messages in thread From: Chun Yan Liu @ 2015-06-23 2:44 UTC (permalink / raw) To: Ian Campbell, George Dunlap, Ian Jackson Cc: Juergen Gross, Jim Fehlig, Simon Cao, Wei Liu, xen-devel >>> On 6/22/2015 at 09:29 PM, in message <55880DCC.6070902@eu.citrix.com>, George Dunlap <george.dunlap@eu.citrix.com> wrote: > On 06/18/2015 01:08 PM, George Dunlap wrote: > > This usb interface stuff is really becoming a morass. The core > > functionality is fairly independent of the interface. I'm inclined to > > say that we should start with a simple specification (only bus.addr), > > and try to get both pvusb and hvmusb in. Then we can talk about where > > to add additional specifications (including cross-boot stable > > specifcations). > > So Ian J, Ian C, Wei and I chatted face-to-face about what to do going > forward; below are some key points we discussed and the conclusion we > came to. Decisions are only official when they've been discussed on the > list, so please consider this a proposal and give your feedback. :-) > > (Also, Ian/Ian/Wei, let me know if I've misremembered or forgotten > something.) > > Points of discussion: > > * We would ideally like to be able to have the released interface work > both for both PV and HVM; for one so that we don't have to have separate > #defines for that functionality; but also to make sure that the > interface is suitable for both functionalities. > > * It's difficult at the moment to actually do collaborative development > on the libxl USB feature, because the code is not yet in the tree. > > * Regarding user-facing interfaces (like xl, as opposed to libxl): the > interface cannot be half-baked; it should not provide functionality > which works most of the time but sometimes will fail. > > Having only "bus-ports" or "vendorid:deviceid" is not sufficient, > because it will lure the user into thinking that they can put those > numbers into a config file and get repeatable results every time. But > since bus numbers change, and vendorid:deviceid is not unique, either of > these would be a false promise. > > Udevs ID_PATH naming scheme seems like a sensible thing to adopt, at > least for Linux. We could consider making an OS-specific string for > identifying the same device across reboots. > > On the other hand, bus.address is very obviously unstable; nobody in > their right mind would use it for anything they wanted to persist across > reboots. So including bus.address as a temporary measure to be able to > test the underlying library until we get a more reliable naming scheme > in place would be OK, as long as the UI interface could be extended > going forward. > > * We should avoid adding complexity to the libxl interface until it's > needed; accepting one way of specifying USB devices, and letting the > toolstack do translation into that way of specifying it (perhaps > providing helper libraries to do so), should be enough for now. The way > of specifying USB devices does not need to be stable across reboots, as > long as it won't change between the time the toolstack does the > translation and the time the device is plugged in. > > bus.address is the best specification from that point of view: it's > unique (unlike device:vendorid), and if a device is unplugged and > another one plugged in between the time the translation happens and the > time libxl gets around to doing something, the old bus.address won't > exist anymore and the command will fail. > > * There may be a point in the future when we want to be able provide > device auto-plug functionality at the libxl layer. (i.e., "When device > X shows up, please plug it into VM Y.") For this we will need a > reliable way of specifying devices; bus.address will not do. > > But that functionality doesn't exist yet; so for now we should stick > with bus.address, but design the interface such that it can be extended > with more options for specifying a device when such functionality is neede. > > With all that in mind, here is a proposal: > > 1. For the moment, only use bus.address at the libxl layer to specify a > device. > > 2. Let's check in the libxl part of Chunyan's PVUSB series as soon as > the 4.7 development window opens (assuming the coding style issues have > all been addressed). We can also check in the xl functionality with > minimal bus.address support for testing. > > 3. I will the port the HVM USB series and submit them as soon as possible. > > 4. We work on a set of helper functions that a toolstack can use to > translate other ways of specifying a device, much like the disk > specification helper functions that we provide. One of these should be > something which is reliably stable over reboots, such as the udev > ID_PATH specification. > > Thoughts? Fine to me. > > -George > > ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-15 14:17 ` George Dunlap 2015-06-15 14:25 ` Jürgen Groß @ 2015-06-16 10:41 ` Ian Jackson 2015-06-16 10:56 ` Jürgen Groß 2015-06-16 11:01 ` George Dunlap 1 sibling, 2 replies; 88+ messages in thread From: Ian Jackson @ 2015-06-16 10:41 UTC (permalink / raw) To: George Dunlap Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > Ian / Ian / Wei / Jim: Hi. > 3. Have the libxl layer accept both busid and bus:addr. Translate as > necessary and store in the libxl_device_usb struct. ... > The advantage of #3 internally is that the functions can do the > translation once (if necessary), and can then pass around the public > libxl_device_usb struct as-is without needing any extra parameters or > a separate libxl_device_usb_internal. The disadvantage, I think, is > that from an interface perspective, it's fairly pointless to have > both. busid doesn't really give you any better or more control than > the other, and it's not any more convenient for the user (in fact it's > less convenient because it's more difficult to find). Is the busid more stable in the face of plug/unplug ? This is the normal reason for a more path-like device specification. If so then we must support it, even if it's not the usual way an ordinary user would use it for a one-off. Otherwise you have to write something in your config files for the VMs on your VM host, which will break when someone plugs a keyboard into the `wrong' USB port. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 10:41 ` [PATCH V4 3/7] libxl: add pvusb API Ian Jackson @ 2015-06-16 10:56 ` Jürgen Groß 2015-06-16 11:03 ` George Dunlap 2015-06-16 11:10 ` Ian Jackson 2015-06-16 11:01 ` George Dunlap 1 sibling, 2 replies; 88+ messages in thread From: Jürgen Groß @ 2015-06-16 10:56 UTC (permalink / raw) To: Ian Jackson, George Dunlap Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 12:41 PM, Ian Jackson wrote: > George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): >> Ian / Ian / Wei / Jim: > > Hi. > >> 3. Have the libxl layer accept both busid and bus:addr. Translate as >> necessary and store in the libxl_device_usb struct. > ... >> The advantage of #3 internally is that the functions can do the >> translation once (if necessary), and can then pass around the public >> libxl_device_usb struct as-is without needing any extra parameters or >> a separate libxl_device_usb_internal. The disadvantage, I think, is >> that from an interface perspective, it's fairly pointless to have >> both. busid doesn't really give you any better or more control than >> the other, and it's not any more convenient for the user (in fact it's >> less convenient because it's more difficult to find). > > Is the busid more stable in the face of plug/unplug ? This is the > normal reason for a more path-like device specification. > > If so then we must support it, even if it's not the usual way an > ordinary user would use it for a one-off. Otherwise you have to write > something in your config files for the VMs on your VM host, which will > break when someone plugs a keyboard into the `wrong' USB port. Unfortunately the busid isn't stable at least across reboots. qemu does support specifying a USB device via <vendorId>:<productId>, which is stable even across reboots, but unfortunately it isn't guaranteed to be unique (you can have plugged in two devices of the same type). My pvUSB backend in qemu will accept all three variants of device specification, so may be libxl should do so, too. Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 10:56 ` Jürgen Groß @ 2015-06-16 11:03 ` George Dunlap 2015-06-16 11:10 ` Ian Jackson 1 sibling, 0 replies; 88+ messages in thread From: George Dunlap @ 2015-06-16 11:03 UTC (permalink / raw) To: Jürgen Groß Cc: Wei Liu, Ian Campbell, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Tue, Jun 16, 2015 at 11:56 AM, Jürgen Groß <jgross@suse.com> wrote: > On 06/16/2015 12:41 PM, Ian Jackson wrote: >> >> George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb >> API"): >>> >>> Ian / Ian / Wei / Jim: >> >> >> Hi. >> >>> 3. Have the libxl layer accept both busid and bus:addr. Translate as >>> necessary and store in the libxl_device_usb struct. >> >> ... >>> >>> The advantage of #3 internally is that the functions can do the >>> translation once (if necessary), and can then pass around the public >>> libxl_device_usb struct as-is without needing any extra parameters or >>> a separate libxl_device_usb_internal. The disadvantage, I think, is >>> that from an interface perspective, it's fairly pointless to have >>> both. busid doesn't really give you any better or more control than >>> the other, and it's not any more convenient for the user (in fact it's >>> less convenient because it's more difficult to find). >> >> >> Is the busid more stable in the face of plug/unplug ? This is the >> normal reason for a more path-like device specification. >> >> If so then we must support it, even if it's not the usual way an >> ordinary user would use it for a one-off. Otherwise you have to write >> something in your config files for the VMs on your VM host, which will >> break when someone plugs a keyboard into the `wrong' USB port. > > > Unfortunately the busid isn't stable at least across reboots. Isn't it based on the physical topology of the USB network? Shouldn't it be the same as long as you don't actually unplug anything? -George _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 10:56 ` Jürgen Groß 2015-06-16 11:03 ` George Dunlap @ 2015-06-16 11:10 ` Ian Jackson 2015-06-16 11:25 ` Juergen Gross 1 sibling, 1 reply; 88+ messages in thread From: Ian Jackson @ 2015-06-16 11:10 UTC (permalink / raw) To: Jürgen Groß Cc: Wei Liu, Ian Campbell, George Dunlap, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao Jürgen Groß writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > On 06/16/2015 12:41 PM, Ian Jackson wrote: > > Is the busid more stable in the face of plug/unplug ? This is the > > normal reason for a more path-like device specification. ... > Unfortunately the busid isn't stable at least across reboots. I see. Presumably the busdev isn't either. We need to be let users specify something that _is_ stable, obviously. On my netbook I have this kind of thing in /etc/fstab: /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 /media/usb1 auto rw,user,noauto 0 0 Is a similar specification possible ? > qemu does support specifying a USB device via <vendorId>:<productId>, > which is stable even across reboots, but unfortunately it isn't > guaranteed to be unique (you can have plugged in two devices of the > same type). Indeed. That would also be a thing we should allow people to do. AIUI some devices have serial numbers, which means you can distinguish them ? Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:10 ` Ian Jackson @ 2015-06-16 11:25 ` Juergen Gross 2015-06-16 11:45 ` George Dunlap ` (2 more replies) 0 siblings, 3 replies; 88+ messages in thread From: Juergen Gross @ 2015-06-16 11:25 UTC (permalink / raw) To: Ian Jackson Cc: Wei Liu, Ian Campbell, George Dunlap, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 01:10 PM, Ian Jackson wrote: > Jürgen Groß writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): >> On 06/16/2015 12:41 PM, Ian Jackson wrote: >>> Is the busid more stable in the face of plug/unplug ? This is the >>> normal reason for a more path-like device specification. > ... >> Unfortunately the busid isn't stable at least across reboots. > > I see. > > Presumably the busdev isn't either. We need to be let users specify > something that _is_ stable, obviously. > > On my netbook I have this kind of thing in /etc/fstab: > > /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 /media/usb1 auto rw,user,noauto 0 0 > > Is a similar specification possible ? > >> qemu does support specifying a USB device via <vendorId>:<productId>, >> which is stable even across reboots, but unfortunately it isn't >> guaranteed to be unique (you can have plugged in two devices of the >> same type). > > Indeed. That would also be a thing we should allow people to do. > > AIUI some devices have serial numbers, which means you can distinguish > them ? Yes, they have. The question is whether those are different on multiple instances? With "lsusb" I've found a device with serial number 0123456789ABCD. Do you really believe I'm just lucky owning the one with such a nice serial number? ;-) Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:25 ` Juergen Gross @ 2015-06-16 11:45 ` George Dunlap 2015-06-16 12:02 ` Ian Jackson 2015-06-16 11:45 ` [PATCH V4 3/7] libxl: add pvusb API Ian Jackson 2015-06-16 15:38 ` George Dunlap 2 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-16 11:45 UTC (permalink / raw) To: Juergen Gross Cc: Wei Liu, Ian Campbell, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Tue, Jun 16, 2015 at 12:25 PM, Juergen Gross <jgross@suse.com> wrote: >>> qemu does support specifying a USB device via <vendorId>:<productId>, >>> which is stable even across reboots, but unfortunately it isn't >>> guaranteed to be unique (you can have plugged in two devices of the >>> same type). >> >> >> Indeed. That would also be a thing we should allow people to do. >> >> AIUI some devices have serial numbers, which means you can distinguish >> them ? > > > Yes, they have. The question is whether those are different on multiple > instances? With "lsusb" I've found a device with serial number > 0123456789ABCD. Do you really believe I'm just lucky owning the one with > such a nice serial number? ;-) So it sounds like we're converging on "Allow multiple ways to specify the interface", with at least the following fields: - bus (int - 1,2,3, &c) - port (string - 2.1.3, &c) - address/devnum (int) - vendorid (uint16_t) - deviceid (uint16_t) That solves the basic problem, because then the missing information needed by the various paths can be looked up and added to the device struct as needed. -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:45 ` George Dunlap @ 2015-06-16 12:02 ` Ian Jackson 2015-06-16 13:19 ` George Dunlap 0 siblings, 1 reply; 88+ messages in thread From: Ian Jackson @ 2015-06-16 12:02 UTC (permalink / raw) To: George Dunlap Cc: Juergen Gross, Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > So it sounds like we're converging on "Allow multiple ways to specify > the interface", with at least the following fields: > - bus (int - 1,2,3, &c) > - port (string - 2.1.3, &c) > - address/devnum (int) > - vendorid (uint16_t) > - deviceid (uint16_t) You're missing the full device path from that list. Typically that will include at least one pci bus address. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 12:02 ` Ian Jackson @ 2015-06-16 13:19 ` George Dunlap 2015-06-16 13:32 ` Juergen Gross 2015-06-16 13:37 ` [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages] Ian Jackson 0 siblings, 2 replies; 88+ messages in thread From: George Dunlap @ 2015-06-16 13:19 UTC (permalink / raw) To: Ian Jackson Cc: Juergen Gross, Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Tue, Jun 16, 2015 at 1:02 PM, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote: > George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): >> So it sounds like we're converging on "Allow multiple ways to specify >> the interface", with at least the following fields: >> - bus (int - 1,2,3, &c) >> - port (string - 2.1.3, &c) >> - address/devnum (int) >> - vendorid (uint16_t) >> - deviceid (uint16_t) > > You're missing the full device path from that list. Typically that > will include at least one pci bus address. I'm not sure what constitutes a "full device path". Is that defined somewhere? Remember that the path you gave in your previous e-mail isn't the path for the *usb device*, it's the path for the *block device*. It contains a PCI address, but it looks like it also contains part of the USB topology. Are you sure that's actually a stable interface, or does it just happen that on your hardware the discovery always happens in the same order? On my system /sys/bus/usb/devices/2-3.3 is a link to /sys/devices/pci0000:00/0000:00:1d.7/usb2/2-3/2-3.3/. This contains the pci bus address, but it also contains the bus number, which we've just said may be unstable across reboots. I suppose it might be possible to specify <buspci,port> -- the pci address of the root bus, and the topology from there. In theory I guess that should be stable? In any case, at the moment you're essentially inventing from whole cloth a new way of specifying USB devices that (as far as I know) isn't supported by any other program that uses USB. -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 13:19 ` George Dunlap @ 2015-06-16 13:32 ` Juergen Gross 2015-06-16 13:37 ` [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages] Ian Jackson 1 sibling, 0 replies; 88+ messages in thread From: Juergen Gross @ 2015-06-16 13:32 UTC (permalink / raw) To: George Dunlap, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 03:19 PM, George Dunlap wrote: > On Tue, Jun 16, 2015 at 1:02 PM, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote: >> George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): >>> So it sounds like we're converging on "Allow multiple ways to specify >>> the interface", with at least the following fields: >>> - bus (int - 1,2,3, &c) >>> - port (string - 2.1.3, &c) >>> - address/devnum (int) >>> - vendorid (uint16_t) >>> - deviceid (uint16_t) >> >> You're missing the full device path from that list. Typically that >> will include at least one pci bus address. > > I'm not sure what constitutes a "full device path". Is that defined somewhere? > > Remember that the path you gave in your previous e-mail isn't the path > for the *usb device*, it's the path for the *block device*. It > contains a PCI address, but it looks like it also contains part of the > USB topology. Are you sure that's actually a stable interface, or > does it just happen that on your hardware the discovery always happens > in the same order? > > On my system /sys/bus/usb/devices/2-3.3 is a link to > /sys/devices/pci0000:00/0000:00:1d.7/usb2/2-3/2-3.3/. This contains > the pci bus address, but it also contains the bus number, which we've > just said may be unstable across reboots. > > I suppose it might be possible to specify <buspci,port> -- the pci > address of the root bus, and the topology from there. In theory I > guess that should be stable? Hmm, perhaps. On my system I've got: /sys/devices/pci0000:00/0000:00:14.0/usb3/ /sys/devices/pci0000:00/0000:00:14.0/usb4/ So two busses on one pci bus address. Are usb3 and usb4 always in this order or are they sometimes just numbered the other way round? Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages] 2015-06-16 13:19 ` George Dunlap 2015-06-16 13:32 ` Juergen Gross @ 2015-06-16 13:37 ` Ian Jackson 2015-06-16 14:41 ` George Dunlap 1 sibling, 1 reply; 88+ messages in thread From: Ian Jackson @ 2015-06-16 13:37 UTC (permalink / raw) To: George Dunlap Cc: Jürgen Groß, Wei Liu, Ian Campbell, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > Remember that the path you gave in your previous e-mail isn't the path > for the *usb device*, it's the path for the *block device*. It > contains a PCI address, but it looks like it also contains part of the > USB topology. Are you sure that's actually a stable interface, or > does it just happen that on your hardware the discovery always happens > in the same order? The block device is (in path terms) underneath the usb device, obviously. Not all of that path is relevant to identifying the USB device. > On my system /sys/bus/usb/devices/2-3.3 is a link to > /sys/devices/pci0000:00/0000:00:1d.7/usb2/2-3/2-3.3/. This contains > the pci bus address, but it also contains the bus number, which we've > just said may be unstable across reboots. You mean the 2 in `usb2' ? I think that bus number is the bus number within the controller, not globally. > I suppose it might be possible to specify <buspci,port> -- the pci > address of the root bus, and the topology from there. In theory I > guess that should be stable? Yes. The whole point of paths like this is that they are stable if the physical topology doesn't change. So on my netbook /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 always refers to the 1st MBR partition on logical device 0 on the USB storage device plugged into the USB port physically on the front left of the computer. > In any case, at the moment you're essentially inventing from whole > cloth a new way of specifying USB devices that (as far as I know) > isn't supported by any other program that uses USB. If you can't specify the device by hardware path, you can't specify it deterministically. And as you can see it _is_ supported by other programs that use USB. "mount" can use it! I think the hardware path to the controller, at least, should be treated as an opaque OS-specific string. It might have a different format on BSD. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages] 2015-06-16 13:37 ` [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages] Ian Jackson @ 2015-06-16 14:41 ` George Dunlap 2015-06-16 15:58 ` Sander Eikelenboom 2015-06-16 15:59 ` Ian Jackson 0 siblings, 2 replies; 88+ messages in thread From: George Dunlap @ 2015-06-16 14:41 UTC (permalink / raw) To: Ian Jackson Cc: Jürgen Groß, Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 02:37 PM, Ian Jackson wrote: > George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): >> Remember that the path you gave in your previous e-mail isn't the path >> for the *usb device*, it's the path for the *block device*. It >> contains a PCI address, but it looks like it also contains part of the >> USB topology. Are you sure that's actually a stable interface, or >> does it just happen that on your hardware the discovery always happens >> in the same order? > > The block device is (in path terms) underneath the usb device, > obviously. Not all of that path is relevant to identifying the > USB device. > >> On my system /sys/bus/usb/devices/2-3.3 is a link to >> /sys/devices/pci0000:00/0000:00:1d.7/usb2/2-3/2-3.3/. This contains >> the pci bus address, but it also contains the bus number, which we've >> just said may be unstable across reboots. > > You mean the 2 in `usb2' ? I think that bus number is the bus number > within the controller, not globally. On the contrary: $ ls -l usb* lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb1 -> ../../../devices/pci0000:00/0000:00:1a.7/usb1/ lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb2 -> ../../../devices/pci0000:00/0000:00:1d.7/usb2/ lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb3 -> ../../../devices/pci0000:00/0000:00:1a.0/usb3/ lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb4 -> ../../../devices/pci0000:00/0000:00:1a.1/usb4/ lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb5 -> ../../../devices/pci0000:00/0000:00:1a.2/usb5/ lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb6 -> ../../../devices/pci0000:00/0000:00:1d.0/usb6/ lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb7 -> ../../../devices/pci0000:00/0000:00:1d.1/usb7/ lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb8 -> ../../../devices/pci0000:00/0000:00:1d.2/usb8/ $ ls /sys//devices/pci0000:00/0000:00:1d.7/ | grep usb usb2/ In other words, the global bus enumeration leaks its way into the device path; which means at very least the sysfs device path is potentially unstable across reboots even if you include the pci controller it's on. >> I suppose it might be possible to specify <buspci,port> -- the pci >> address of the root bus, and the topology from there. In theory I >> guess that should be stable? > > Yes. The whole point of paths like this is that they are stable if > the physical topology doesn't change. So on my netbook > > /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 > > always refers to the 1st MBR partition on logical device 0 on the USB > storage device plugged into the USB port physically on the front left > of the computer. That would be great if it were true, but I'm not convinced that the above path doesn't include a globally-enumerated bus number, which might change across reboots if it's enumerated in a different order. It may be that the format above is *not* based on the sysfs path of the device; that the '0' immediately after the USB means "the first (and perhaps only) controller at this PCI address". In which case, yes, having a string like this might be a unique identifier for a particular port that would be stable across reboots. That needs some investigation. >> In any case, at the moment you're essentially inventing from whole >> cloth a new way of specifying USB devices that (as far as I know) >> isn't supported by any other program that uses USB. > > If you can't specify the device by hardware path, you can't specify it > deterministically. > > And as you can see it _is_ supported by other programs that use USB. > "mount" can use it! Mount doesn't know anything about USB devices; all it knows are block devices. You might as well say that 'ls' knows about USB devices because it can read files on a filesystem that resides on a USB stick. I'm talking about programs that explicitly manipulate USB devices -- in particular, those that may pass them through to a guest or seize them, like libvirt, qemu, virtualbox, &c. I'm not opposed to doing something new if it really is better. But when you find that a dozen other projects before you have done things one way, you should at least take care before you decide to do something radically different, to make sure that it's because you actually have something better, and not because you've just missed something. > I think the hardware path to the controller, at least, should be > treated as an opaque OS-specific string. It might have a different > format on BSD. If we can make an actual path that's stable across reboots, that would certainly be a good thing. But if it's not stable across reboots, it has no advantage over the bus-port[.port.port] interface. -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages] 2015-06-16 14:41 ` George Dunlap @ 2015-06-16 15:58 ` Sander Eikelenboom 2015-06-16 15:59 ` Ian Jackson 1 sibling, 0 replies; 88+ messages in thread From: Sander Eikelenboom @ 2015-06-16 15:58 UTC (permalink / raw) To: George Dunlap Cc: Jürgen Groß, Wei Liu, Ian Campbell, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao Tuesday, June 16, 2015, 4:41:52 PM, you wrote: > On 06/16/2015 02:37 PM, Ian Jackson wrote: >> George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): >>> Remember that the path you gave in your previous e-mail isn't the path >>> for the *usb device*, it's the path for the *block device*. It >>> contains a PCI address, but it looks like it also contains part of the >>> USB topology. Are you sure that's actually a stable interface, or >>> does it just happen that on your hardware the discovery always happens >>> in the same order? >> >> The block device is (in path terms) underneath the usb device, >> obviously. Not all of that path is relevant to identifying the >> USB device. >> >>> On my system /sys/bus/usb/devices/2-3.3 is a link to >>> /sys/devices/pci0000:00/0000:00:1d.7/usb2/2-3/2-3.3/. This contains >>> the pci bus address, but it also contains the bus number, which we've >>> just said may be unstable across reboots. >> >> You mean the 2 in `usb2' ? I think that bus number is the bus number >> within the controller, not globally. > On the contrary: > $ ls -l usb* > lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb1 -> > ../../../devices/pci0000:00/0000:00:1a.7/usb1/ > lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb2 -> > ../../../devices/pci0000:00/0000:00:1d.7/usb2/ > lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb3 -> > ../../../devices/pci0000:00/0000:00:1a.0/usb3/ > lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb4 -> > ../../../devices/pci0000:00/0000:00:1a.1/usb4/ > lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb5 -> > ../../../devices/pci0000:00/0000:00:1a.2/usb5/ > lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb6 -> > ../../../devices/pci0000:00/0000:00:1d.0/usb6/ > lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb7 -> > ../../../devices/pci0000:00/0000:00:1d.1/usb7/ > lrwxrwxrwx 1 root root 0 Jun 15 10:14 usb8 -> > ../../../devices/pci0000:00/0000:00:1d.2/usb8/ > $ ls /sys//devices/pci0000:00/0000:00:1d.7/ | grep usb > usb2/ > In other words, the global bus enumeration leaks its way into the device > path; which means at very least the sysfs device path is potentially > unstable across reboots even if you include the pci controller it's on. >>> I suppose it might be possible to specify <buspci,port> -- the pci >>> address of the root bus, and the topology from there. In theory I >>> guess that should be stable? >> >> Yes. The whole point of paths like this is that they are stable if >> the physical topology doesn't change. So on my netbook >> >> /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 >> >> always refers to the 1st MBR partition on logical device 0 on the USB >> storage device plugged into the USB port physically on the front left >> of the computer. > That would be great if it were true, but I'm not convinced that the > above path doesn't include a globally-enumerated bus number, which might > change across reboots if it's enumerated in a different order. > It may be that the format above is *not* based on the sysfs path of the > device; that the '0' immediately after the USB means "the first (and > perhaps only) controller at this PCI address". In which case, yes, > having a string like this might be a unique identifier for a particular > port that would be stable across reboots. That needs some investigation. >>> In any case, at the moment you're essentially inventing from whole >>> cloth a new way of specifying USB devices that (as far as I know) >>> isn't supported by any other program that uses USB. >> >> If you can't specify the device by hardware path, you can't specify it >> deterministically. >> >> And as you can see it _is_ supported by other programs that use USB. >> "mount" can use it! > Mount doesn't know anything about USB devices; all it knows are block > devices. You might as well say that 'ls' knows about USB devices > because it can read files on a filesystem that resides on a USB stick. > I'm talking about programs that explicitly manipulate USB devices -- in > particular, those that may pass them through to a guest or seize them, > like libvirt, qemu, virtualbox, &c. > I'm not opposed to doing something new if it really is better. But when > you find that a dozen other projects before you have done things one > way, you should at least take care before you decide to do something > radically different, to make sure that it's because you actually have > something better, and not because you've just missed something. >> I think the hardware path to the controller, at least, should be >> treated as an opaque OS-specific string. It might have a different >> format on BSD. > If we can make an actual path that's stable across reboots, that would > certainly be a good thing. But if it's not stable across reboots, it > has no advantage over the bus-port[.port.port] interface. > -George Would a symlink to a sysfs or device node entry also be allowed ? That way you can leverage the power of tools like udev or other device managers and script the linkage based on a multitude of device properties (f.e. serial numbers, manufacturer id, device id, etc.). Which can make it persistent across reboots or do other funky stuff with it, according to ones needs. -- Sander ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages] 2015-06-16 14:41 ` George Dunlap 2015-06-16 15:58 ` Sander Eikelenboom @ 2015-06-16 15:59 ` Ian Jackson 2015-06-16 16:34 ` George Dunlap 1 sibling, 1 reply; 88+ messages in thread From: Ian Jackson @ 2015-06-16 15:59 UTC (permalink / raw) To: George Dunlap Cc: Jürgen Groß, Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages]"): > On 06/16/2015 02:37 PM, Ian Jackson wrote: > > George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"> >> /sys/devices/pci0000:00/0000:00:1d.7/usb2/2-3/2-3.3/. This contains > >> the pci bus address, but it also contains the bus number, which we've > >> just said may be unstable across reboots. > > > > You mean the 2 in `usb2' ? I think that bus number is the bus number > > within the controller, not globally. > > On the contrary: > [...] Oh dear. > In other words, the global bus enumeration leaks its way into the device > path; which means at very least the sysfs device path is potentially > unstable across reboots even if you include the pci controller it's on. How unhelpful. > > Yes. The whole point of paths like this is that they are stable if > > the physical topology doesn't change. So on my netbook > > > > /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 > > > > always refers to the 1st MBR partition on logical device 0 on the USB > > storage device plugged into the USB port physically on the front left > > of the computer. > > That would be great if it were true, but I'm not convinced that the > above path doesn't include a globally-enumerated bus number, which might > change across reboots if it's enumerated in a different order. > > It may be that the format above is *not* based on the sysfs path of the > device; that the '0' immediately after the USB means "the first (and > perhaps only) controller at this PCI address". In which case, yes, > having a string like this might be a unique identifier for a particular > port that would be stable across reboots. That needs some investigation. That does seem to be the case: zealot:~> ls -al /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 lrwxrwxrwx 1 root root 10 Jun 16 16:45 /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 -> ../../sdc1 zealot:~> ls -al /sys/class/block/sdc lrwxrwxrwx 1 root root 0 Jun 16 16:45 /sys/class/block/sdc -> ../../devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host19/target19:0:0/19:0:0:0/block/sdc/ zealot:~> Observe that the sysfs path contains not only `usb1' (which isn't stable) but also `host19' which is also not stable. If I unplug and replug: zealot:~> ls -al /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 lrwxrwxrwx 1 root root 10 Jun 16 16:49 /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 -> ../../sdc1 zealot:~> ls -al /sys/class/block/sdc lrwxrwxrwx 1 root root 0 Jun 16 16:50 /sys/class/block/sdc -> ../../devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host20/target20:0:0/20:0:0:0/block/sdc/ zealot:~> Looking at the output of udevadm monitor --property for sdc1 (on another plug): DEVPATH=/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host22/target22:0:0/22:0:0:0/block/sdc/sdc1 ID_PATH=pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0 ID_PATH_TAG=pci-0000_00_1d_7-usb-0_1_1_0-scsi-0_0_0_0 I don't know where that ID_PATH comes from. I can't seem to find anything relevant in my /sys/devices/pci0000:00/0000:00:1d.7 > > I think the hardware path to the controller, at least, should be > > treated as an opaque OS-specific string. It might have a different > > format on BSD. > > If we can make an actual path that's stable across reboots, that would > certainly be a good thing. But if it's not stable across reboots, it > has no advantage over the bus-port[.port.port] interface. Yes. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages] 2015-06-16 15:59 ` Ian Jackson @ 2015-06-16 16:34 ` George Dunlap 2015-06-17 3:59 ` Juergen Gross 0 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-16 16:34 UTC (permalink / raw) To: Ian Jackson Cc: Jürgen Groß, Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Tue, Jun 16, 2015 at 4:59 PM, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote: > George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages]"): >> > Yes. The whole point of paths like this is that they are stable if >> > the physical topology doesn't change. So on my netbook >> > >> > /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 >> > >> > always refers to the 1st MBR partition on logical device 0 on the USB >> > storage device plugged into the USB port physically on the front left >> > of the computer. >> >> That would be great if it were true, but I'm not convinced that the >> above path doesn't include a globally-enumerated bus number, which might >> change across reboots if it's enumerated in a different order. >> >> It may be that the format above is *not* based on the sysfs path of the >> device; that the '0' immediately after the USB means "the first (and >> perhaps only) controller at this PCI address". In which case, yes, >> having a string like this might be a unique identifier for a particular >> port that would be stable across reboots. That needs some investigation. > > That does seem to be the case: What seems to be the case -- that it contains the global bus, or not? > Looking at the output of udevadm monitor --property for sdc1 (on > another plug): > > DEVPATH=/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host22/target22:0:0/22:0:0:0/block/sdc/sdc1 > ID_PATH=pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0 > ID_PATH_TAG=pci-0000_00_1d_7-usb-0_1_1_0-scsi-0_0_0_0 > > I don't know where that ID_PATH comes from. It looks like that's constructed in udev: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-path_id.c See handle_usb() (line 542) in particular. If I'm reading it right, what it basically does it take the [bus]-[port], and replace it with usb-0:[port]. (IOW, the '0' is hard-coded.) Also, if I'm reading it right, this won't work properly for Juergen's system that has two USB devices at the same pci address -- they'll both end up resolving to [pciaddr]-usb-0:[whatever]. Juergen -- can you give this a try? Run "udevadm info" on the two USB busses that share the same PCI slot, and see if the ID_PATH is the same for both? -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages] 2015-06-16 16:34 ` George Dunlap @ 2015-06-17 3:59 ` Juergen Gross 2015-06-17 10:27 ` George Dunlap 0 siblings, 1 reply; 88+ messages in thread From: Juergen Gross @ 2015-06-17 3:59 UTC (permalink / raw) To: George Dunlap, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 06:34 PM, George Dunlap wrote: > On Tue, Jun 16, 2015 at 4:59 PM, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote: >> George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages]"): >>>> Yes. The whole point of paths like this is that they are stable if >>>> the physical topology doesn't change. So on my netbook >>>> >>>> /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 >>>> >>>> always refers to the 1st MBR partition on logical device 0 on the USB >>>> storage device plugged into the USB port physically on the front left >>>> of the computer. >>> >>> That would be great if it were true, but I'm not convinced that the >>> above path doesn't include a globally-enumerated bus number, which might >>> change across reboots if it's enumerated in a different order. >>> >>> It may be that the format above is *not* based on the sysfs path of the >>> device; that the '0' immediately after the USB means "the first (and >>> perhaps only) controller at this PCI address". In which case, yes, >>> having a string like this might be a unique identifier for a particular >>> port that would be stable across reboots. That needs some investigation. >> >> That does seem to be the case: > > What seems to be the case -- that it contains the global bus, or not? > >> Looking at the output of udevadm monitor --property for sdc1 (on >> another plug): >> >> DEVPATH=/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host22/target22:0:0/22:0:0:0/block/sdc/sdc1 >> ID_PATH=pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0 >> ID_PATH_TAG=pci-0000_00_1d_7-usb-0_1_1_0-scsi-0_0_0_0 >> >> I don't know where that ID_PATH comes from. > > It looks like that's constructed in udev: > > http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-path_id.c > > See handle_usb() (line 542) in particular. > > If I'm reading it right, what it basically does it take the > [bus]-[port], and replace it with usb-0:[port]. (IOW, the '0' is > hard-coded.) > > Also, if I'm reading it right, this won't work properly for Juergen's > system that has two USB devices at the same pci address -- they'll > both end up resolving to [pciaddr]-usb-0:[whatever]. > > Juergen -- can you give this a try? Run "udevadm info" on the two USB > busses that share the same PCI slot, and see if the ID_PATH is the > same for both? This was the correct question. :-) The ID_PATH is the same, but: It turns out that the two busses are for one physical hcd. One is the bus for USB 3.0, the other one for USB 2.0. I guess the bus is just selected by the capability of the plugged in device. So the [port] in "usb-0:[port]" is unique across the two logical busses. Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages] 2015-06-17 3:59 ` Juergen Gross @ 2015-06-17 10:27 ` George Dunlap 2015-06-18 6:24 ` Chun Yan Liu 0 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-17 10:27 UTC (permalink / raw) To: Juergen Gross, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/17/2015 04:59 AM, Juergen Gross wrote: > On 06/16/2015 06:34 PM, George Dunlap wrote: >> On Tue, Jun 16, 2015 at 4:59 PM, Ian Jackson >> <Ian.Jackson@eu.citrix.com> wrote: >>> George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add >>> pvusb API [and 1 more messages]"): >>>>> Yes. The whole point of paths like this is that they are stable if >>>>> the physical topology doesn't change. So on my netbook >>>>> >>>>> /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 >>>>> >>>>> always refers to the 1st MBR partition on logical device 0 on the USB >>>>> storage device plugged into the USB port physically on the front left >>>>> of the computer. >>>> >>>> That would be great if it were true, but I'm not convinced that the >>>> above path doesn't include a globally-enumerated bus number, which >>>> might >>>> change across reboots if it's enumerated in a different order. >>>> >>>> It may be that the format above is *not* based on the sysfs path of the >>>> device; that the '0' immediately after the USB means "the first (and >>>> perhaps only) controller at this PCI address". In which case, yes, >>>> having a string like this might be a unique identifier for a particular >>>> port that would be stable across reboots. That needs some >>>> investigation. >>> >>> That does seem to be the case: >> >> What seems to be the case -- that it contains the global bus, or not? >> >>> Looking at the output of udevadm monitor --property for sdc1 (on >>> another plug): >>> >>> DEVPATH=/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host22/target22:0:0/22:0:0:0/block/sdc/sdc1 >>> >>> ID_PATH=pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0 >>> ID_PATH_TAG=pci-0000_00_1d_7-usb-0_1_1_0-scsi-0_0_0_0 >>> >>> I don't know where that ID_PATH comes from. >> >> It looks like that's constructed in udev: >> >> http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-path_id.c >> >> >> See handle_usb() (line 542) in particular. >> >> If I'm reading it right, what it basically does it take the >> [bus]-[port], and replace it with usb-0:[port]. (IOW, the '0' is >> hard-coded.) >> >> Also, if I'm reading it right, this won't work properly for Juergen's >> system that has two USB devices at the same pci address -- they'll >> both end up resolving to [pciaddr]-usb-0:[whatever]. >> >> Juergen -- can you give this a try? Run "udevadm info" on the two USB >> busses that share the same PCI slot, and see if the ID_PATH is the >> same for both? > > This was the correct question. :-) > > The ID_PATH is the same, but: > > It turns out that the two busses are for one physical hcd. One is the > bus for USB 3.0, the other one for USB 2.0. I guess the bus is just > selected by the capability of the plugged in device. > > So the [port] in "usb-0:[port]" is unique across the two logical > busses. Right -- I think I had come to the conclusion that would probably be the case later yesterday evening. Glad to have it confirmed. So in addition to our other identifiers, stealing udev's naming scheme should work, and would be useful. The next challenge would be how to implement it effectively. It's already udev's job to make sure that a string is unique -- as much as possible we want to leverage their efforts, rather than re-implementing our own. One thing that Ian suggested was that we could add a udev rule that would create links from the ID_PATH of the usb device into the sysfs device node. (Both seem to be available in the udev rule environment.) That would allow us to easily translate the ID_PATH into the other things we might want (bus-port, bus.addr, &c) and vice versa. But I think all that will certainly not be done by the feature freeze. The core functionality of Chunyan's series, wrt the pvusb functionality is complete; as with my HVM series before, it's mainly the interface that is being discussed. There are two options here: Chunyan could try to implement the interface we've been discussing here (assuming that she doesn't have any objections to what we've described); or, I could take Chunyan's series, try to implement what we've been talking about, and then add in the HVM functionality as well. What does everyone think? -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages] 2015-06-17 10:27 ` George Dunlap @ 2015-06-18 6:24 ` Chun Yan Liu 0 siblings, 0 replies; 88+ messages in thread From: Chun Yan Liu @ 2015-06-18 6:24 UTC (permalink / raw) To: George Dunlap, Ian Jackson, Juergen Gross Cc: Jim Fehlig, Simon Cao, Wei Liu, Ian Campbell, xen-devel >>> On 6/17/2015 at 06:27 PM, in message <55814B9F.6070909@eu.citrix.com>, George Dunlap <george.dunlap@eu.citrix.com> wrote: > On 06/17/2015 04:59 AM, Juergen Gross wrote: > > On 06/16/2015 06:34 PM, George Dunlap wrote: > >> On Tue, Jun 16, 2015 at 4:59 PM, Ian Jackson > >> <Ian.Jackson@eu.citrix.com> wrote: > >>> George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add > >>> pvusb API [and 1 more messages]"): > >>>>> Yes. The whole point of paths like this is that they are stable if > >>>>> the physical topology doesn't change. So on my netbook > >>>>> > >>>>> /dev/disk/by-path/pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 > >>>>> > >>>>> always refers to the 1st MBR partition on logical device 0 on the USB > >>>>> storage device plugged into the USB port physically on the front left > >>>>> of the computer. > >>>> > >>>> That would be great if it were true, but I'm not convinced that the > >>>> above path doesn't include a globally-enumerated bus number, which > >>>> might > >>>> change across reboots if it's enumerated in a different order. > >>>> > >>>> It may be that the format above is *not* based on the sysfs path of the > >>>> device; that the '0' immediately after the USB means "the first (and > >>>> perhaps only) controller at this PCI address". In which case, yes, > >>>> having a string like this might be a unique identifier for a particular > >>>> port that would be stable across reboots. That needs some > >>>> investigation. > >>> > >>> That does seem to be the case: > >> > >> What seems to be the case -- that it contains the global bus, or not? > >> > >>> Looking at the output of udevadm monitor --property for sdc1 (on > >>> another plug): > >>> > >>> > DEVPATH=/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host22/target22:0:0 > /22:0:0:0/block/sdc/sdc1 > >>> > >>> ID_PATH=pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0 > >>> ID_PATH_TAG=pci-0000_00_1d_7-usb-0_1_1_0-scsi-0_0_0_0 > >>> > >>> I don't know where that ID_PATH comes from. > >> > >> It looks like that's constructed in udev: > >> > >> > http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-path_i > d.c > >> > >> > >> See handle_usb() (line 542) in particular. > >> > >> If I'm reading it right, what it basically does it take the > >> [bus]-[port], and replace it with usb-0:[port]. (IOW, the '0' is > >> hard-coded.) > >> > >> Also, if I'm reading it right, this won't work properly for Juergen's > >> system that has two USB devices at the same pci address -- they'll > >> both end up resolving to [pciaddr]-usb-0:[whatever]. > >> > >> Juergen -- can you give this a try? Run "udevadm info" on the two USB > >> busses that share the same PCI slot, and see if the ID_PATH is the > >> same for both? > > > > This was the correct question. :-) > > > > The ID_PATH is the same, but: > > > > It turns out that the two busses are for one physical hcd. One is the > > bus for USB 3.0, the other one for USB 2.0. I guess the bus is just > > selected by the capability of the plugged in device. > > > > So the [port] in "usb-0:[port]" is unique across the two logical > > busses. > > Right -- I think I had come to the conclusion that would probably be the > case later yesterday evening. Glad to have it confirmed. > > So in addition to our other identifiers, stealing udev's naming scheme > should work, and would be useful. > > The next challenge would be how to implement it effectively. It's > already udev's job to make sure that a string is unique -- as much as > possible we want to leverage their efforts, rather than re-implementing > our own. > > One thing that Ian suggested was that we could add a udev rule that > would create links from the ID_PATH of the usb device into the sysfs > device node. (Both seem to be available in the udev rule environment.) > That would allow us to easily translate the ID_PATH into the other > things we might want (bus-port, bus.addr, &c) and vice versa. > > But I think all that will certainly not be done by the feature freeze. > > The core functionality of Chunyan's series, wrt the pvusb functionality > is complete; as with my HVM series before, it's mainly the interface > that is being discussed. > > There are two options here: Chunyan could try to implement the interface > we've been discussing here (assuming that she doesn't have any > objections to what we've described); No, I don't have any objections. I can do that. - Chunyan > or, I could take Chunyan's series, > try to implement what we've been talking about, and then add in the HVM > functionality as well. > > What does everyone think? > > -George > > > > ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:25 ` Juergen Gross 2015-06-16 11:45 ` George Dunlap @ 2015-06-16 11:45 ` Ian Jackson 2015-06-16 13:06 ` Juergen Gross 2015-06-16 15:38 ` George Dunlap 2 siblings, 1 reply; 88+ messages in thread From: Ian Jackson @ 2015-06-16 11:45 UTC (permalink / raw) To: Juergen Gross Cc: Wei Liu, Ian Campbell, George Dunlap, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao Juergen Gross writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > On 06/16/2015 01:10 PM, Ian Jackson wrote: > > AIUI some devices have serial numbers, which means you can distinguish > > them ? > > Yes, they have. The question is whether those are different on multiple > instances? With "lsusb" I've found a device with serial number > 0123456789ABCD. Do you really believe I'm just lucky owning the one with > such a nice serial number? ;-) Heh. I think, though, that this suggests that if the user has devices whose serial numbers are actually different, they should be able to specify a device by vid/pid/serial. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:45 ` [PATCH V4 3/7] libxl: add pvusb API Ian Jackson @ 2015-06-16 13:06 ` Juergen Gross 2015-06-16 13:09 ` George Dunlap 0 siblings, 1 reply; 88+ messages in thread From: Juergen Gross @ 2015-06-16 13:06 UTC (permalink / raw) To: Ian Jackson Cc: Wei Liu, Ian Campbell, George Dunlap, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 01:45 PM, Ian Jackson wrote: > Juergen Gross writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): >> On 06/16/2015 01:10 PM, Ian Jackson wrote: >>> AIUI some devices have serial numbers, which means you can distinguish >>> them ? >> >> Yes, they have. The question is whether those are different on multiple >> instances? With "lsusb" I've found a device with serial number >> 0123456789ABCD. Do you really believe I'm just lucky owning the one with >> such a nice serial number? ;-) > > Heh. I think, though, that this suggests that if the user has devices > whose serial numbers are actually different, they should be able to > specify a device by vid/pid/serial. I think you are right. The next question: should this be part of libxl or qemu? It should be possible to extend the qemu <vendorId>:<productId> syntax to <vendorId>:<productId>:<serial> without too much effort, as libusb includes some support to obtain the serial number. Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 13:06 ` Juergen Gross @ 2015-06-16 13:09 ` George Dunlap 2015-06-16 13:23 ` Juergen Gross 0 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-16 13:09 UTC (permalink / raw) To: Juergen Gross, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 02:06 PM, Juergen Gross wrote: > On 06/16/2015 01:45 PM, Ian Jackson wrote: >> Juergen Gross writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb >> API"): >>> On 06/16/2015 01:10 PM, Ian Jackson wrote: >>>> AIUI some devices have serial numbers, which means you can distinguish >>>> them ? >>> >>> Yes, they have. The question is whether those are different on multiple >>> instances? With "lsusb" I've found a device with serial number >>> 0123456789ABCD. Do you really believe I'm just lucky owning the one with >>> such a nice serial number? ;-) >> >> Heh. I think, though, that this suggests that if the user has devices >> whose serial numbers are actually different, they should be able to >> specify a device by vid/pid/serial. > > I think you are right. > > The next question: should this be part of libxl or qemu? It should be > possible to extend the qemu <vendorId>:<productId> syntax to > <vendorId>:<productId>:<serial> without too much effort, as libusb > includes some support to obtain the serial number. It doesn't really matter what qemu or pvusb can do, as long as libxl can convert what it has into something that they can use. So if libxl is given vid, pid, and serial (remember, this will be a struct, not a string), it can look in sysfs and find the bus:addr (which is unique at any given time) and hand it to qemu (or the bus-port in the case of pvusb). -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 13:09 ` George Dunlap @ 2015-06-16 13:23 ` Juergen Gross 2015-06-16 13:29 ` George Dunlap 0 siblings, 1 reply; 88+ messages in thread From: Juergen Gross @ 2015-06-16 13:23 UTC (permalink / raw) To: George Dunlap, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 03:09 PM, George Dunlap wrote: > On 06/16/2015 02:06 PM, Juergen Gross wrote: >> On 06/16/2015 01:45 PM, Ian Jackson wrote: >>> Juergen Gross writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb >>> API"): >>>> On 06/16/2015 01:10 PM, Ian Jackson wrote: >>>>> AIUI some devices have serial numbers, which means you can distinguish >>>>> them ? >>>> >>>> Yes, they have. The question is whether those are different on multiple >>>> instances? With "lsusb" I've found a device with serial number >>>> 0123456789ABCD. Do you really believe I'm just lucky owning the one with >>>> such a nice serial number? ;-) >>> >>> Heh. I think, though, that this suggests that if the user has devices >>> whose serial numbers are actually different, they should be able to >>> specify a device by vid/pid/serial. >> >> I think you are right. >> >> The next question: should this be part of libxl or qemu? It should be >> possible to extend the qemu <vendorId>:<productId> syntax to >> <vendorId>:<productId>:<serial> without too much effort, as libusb >> includes some support to obtain the serial number. > > It doesn't really matter what qemu or pvusb can do, as long as libxl can > convert what it has into something that they can use. So if libxl is > given vid, pid, and serial (remember, this will be a struct, not a > string), it can look in sysfs and find the bus:addr (which is unique at > any given time) and hand it to qemu (or the bus-port in the case of pvusb). Hmm, I'd rather have it all in one place. Putting it in qemu would enable us to handle hotplug as well. A USB device assigned via it's serial to a domU could be automatically passed through by qemu when showing up. This isn't possible today, but we wouldn't have to change libxl again for supporting it, only qemu would have to be adapted. Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 13:23 ` Juergen Gross @ 2015-06-16 13:29 ` George Dunlap 2015-06-16 13:49 ` Juergen Gross 0 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-16 13:29 UTC (permalink / raw) To: Juergen Gross, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 02:23 PM, Juergen Gross wrote: > On 06/16/2015 03:09 PM, George Dunlap wrote: >> On 06/16/2015 02:06 PM, Juergen Gross wrote: >>> On 06/16/2015 01:45 PM, Ian Jackson wrote: >>>> Juergen Gross writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb >>>> API"): >>>>> On 06/16/2015 01:10 PM, Ian Jackson wrote: >>>>>> AIUI some devices have serial numbers, which means you can >>>>>> distinguish >>>>>> them ? >>>>> >>>>> Yes, they have. The question is whether those are different on >>>>> multiple >>>>> instances? With "lsusb" I've found a device with serial number >>>>> 0123456789ABCD. Do you really believe I'm just lucky owning the one >>>>> with >>>>> such a nice serial number? ;-) >>>> >>>> Heh. I think, though, that this suggests that if the user has devices >>>> whose serial numbers are actually different, they should be able to >>>> specify a device by vid/pid/serial. >>> >>> I think you are right. >>> >>> The next question: should this be part of libxl or qemu? It should be >>> possible to extend the qemu <vendorId>:<productId> syntax to >>> <vendorId>:<productId>:<serial> without too much effort, as libusb >>> includes some support to obtain the serial number. >> >> It doesn't really matter what qemu or pvusb can do, as long as libxl can >> convert what it has into something that they can use. So if libxl is >> given vid, pid, and serial (remember, this will be a struct, not a >> string), it can look in sysfs and find the bus:addr (which is unique at >> any given time) and hand it to qemu (or the bus-port in the case of >> pvusb). > > Hmm, I'd rather have it all in one place. Putting it in qemu would > enable us to handle hotplug as well. A USB device assigned via it's > serial to a domU could be automatically passed through by qemu when > showing up. This isn't possible today, but we wouldn't have to change > libxl again for supporting it, only qemu would have to be adapted. Look, we're talking here about the libxl interface. Ian thinks that *at the libxl layer* we need to be able to specify all these things. It doesn't matter at this point whether qemu can also do it or not. In the future, if we actually implement the "automatically grab this device when it shows up" functionality, then yes, having it in qemu rather than having a libxl daemon sit around and watch for those things, might be handy. But we can cross that bridge when we come to it. -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 13:29 ` George Dunlap @ 2015-06-16 13:49 ` Juergen Gross 2015-06-16 14:06 ` George Dunlap 0 siblings, 1 reply; 88+ messages in thread From: Juergen Gross @ 2015-06-16 13:49 UTC (permalink / raw) To: George Dunlap, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 03:29 PM, George Dunlap wrote: > On 06/16/2015 02:23 PM, Juergen Gross wrote: >> On 06/16/2015 03:09 PM, George Dunlap wrote: >>> On 06/16/2015 02:06 PM, Juergen Gross wrote: >>>> On 06/16/2015 01:45 PM, Ian Jackson wrote: >>>>> Juergen Gross writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb >>>>> API"): >>>>>> On 06/16/2015 01:10 PM, Ian Jackson wrote: >>>>>>> AIUI some devices have serial numbers, which means you can >>>>>>> distinguish >>>>>>> them ? >>>>>> >>>>>> Yes, they have. The question is whether those are different on >>>>>> multiple >>>>>> instances? With "lsusb" I've found a device with serial number >>>>>> 0123456789ABCD. Do you really believe I'm just lucky owning the one >>>>>> with >>>>>> such a nice serial number? ;-) >>>>> >>>>> Heh. I think, though, that this suggests that if the user has devices >>>>> whose serial numbers are actually different, they should be able to >>>>> specify a device by vid/pid/serial. >>>> >>>> I think you are right. >>>> >>>> The next question: should this be part of libxl or qemu? It should be >>>> possible to extend the qemu <vendorId>:<productId> syntax to >>>> <vendorId>:<productId>:<serial> without too much effort, as libusb >>>> includes some support to obtain the serial number. >>> >>> It doesn't really matter what qemu or pvusb can do, as long as libxl can >>> convert what it has into something that they can use. So if libxl is >>> given vid, pid, and serial (remember, this will be a struct, not a >>> string), it can look in sysfs and find the bus:addr (which is unique at >>> any given time) and hand it to qemu (or the bus-port in the case of >>> pvusb). >> >> Hmm, I'd rather have it all in one place. Putting it in qemu would >> enable us to handle hotplug as well. A USB device assigned via it's >> serial to a domU could be automatically passed through by qemu when >> showing up. This isn't possible today, but we wouldn't have to change >> libxl again for supporting it, only qemu would have to be adapted. > > Look, we're talking here about the libxl interface. Ian thinks that *at > the libxl layer* we need to be able to specify all these things. It > doesn't matter at this point whether qemu can also do it or not. When I'm adding new functionality (and this is the case here) I always try to add it at the level where it should be. qemu already is capable of finding a USB device by various means and can be extended easily to support our needs. And please remember, for writing the pvusb backend I'm already doing changes to qemu. So why should we add the same functionality to libxl by reading sysfs instead of letting it do qemu via libusb? And what about BSD? Letting qemu find the device would avoid two variants in libxl. > In the future, if we actually implement the "automatically grab this > device when it shows up" functionality, then yes, having it in qemu > rather than having a libxl daemon sit around and watch for those things, > might be handy. But we can cross that bridge when we come to it. I would agree if the efforts in libxl would be much smaller than in qemu. But if the efforts are comparable I'd rather do it in the component which will make such an enhancement easier. Just my $0.02 Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 13:49 ` Juergen Gross @ 2015-06-16 14:06 ` George Dunlap 2015-06-16 14:20 ` Juergen Gross 0 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-16 14:06 UTC (permalink / raw) To: Juergen Gross, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 02:49 PM, Juergen Gross wrote: > On 06/16/2015 03:29 PM, George Dunlap wrote: >> On 06/16/2015 02:23 PM, Juergen Gross wrote: >>> Hmm, I'd rather have it all in one place. Putting it in qemu would >>> enable us to handle hotplug as well. A USB device assigned via it's >>> serial to a domU could be automatically passed through by qemu when >>> showing up. This isn't possible today, but we wouldn't have to change >>> libxl again for supporting it, only qemu would have to be adapted. >> >> Look, we're talking here about the libxl interface. Ian thinks that *at >> the libxl layer* we need to be able to specify all these things. It >> doesn't matter at this point whether qemu can also do it or not. > > When I'm adding new functionality (and this is the case here) I always > try to add it at the level where it should be. qemu already is capable > of finding a USB device by various means and can be extended easily to > support our needs. And please remember, for writing the pvusb backend > I'm already doing changes to qemu. > > So why should we add the same functionality to libxl by reading sysfs > instead of letting it do qemu via libusb? And what about BSD? Letting > qemu find the device would avoid two variants in libxl. If the libxl interface only has "bus" and "port", then it doesn't matter what qemu can do -- the caller has no way of asking qemu to watch for vid:did:serial. If libxl has vid:did:serial in the interface, then it's only an implementation detail whether we pass that into qemu or whether we pass some other way of uniquely indentifying a particular device. And given that no *current* versions of qemu support vid:did:serial, the most sensible way to implement this would be to have libxl do the conversion and send over bus:addr -- that way when you update libxl you get that functionality regardless of whether qemu has it. Unless you're suggesting that the libxl interface should be a string that we just pass verbatim to qemu. If that's what you mean, it's a complete non-starter, and I'm sure Ian will agree with me. There's no way that we can provide any interface consistency or any documentation of what this string does if it boils down to "This does whatever the version of qemu you happen to be running does". >> In the future, if we actually implement the "automatically grab this >> device when it shows up" functionality, then yes, having it in qemu >> rather than having a libxl daemon sit around and watch for those things, >> might be handy. But we can cross that bridge when we come to it. > > I would agree if the efforts in libxl would be much smaller than in > qemu. But if the efforts are comparable I'd rather do it in the > component which will make such an enhancement easier. They're both small, so this is really bikeshedding at the moment. The most important question is the interface: do we include vid:did:serial in the libxl interface. Since you want qemu to do that, I take it that your answer to that is "yes". When we have patches submitted, we can discuss whether libxl should only support the (as-yet unreleased) versions of qemu that do the search themselves, or whether they should support all versions of qemu-xen. (The answer seems pretty obvious to me...) -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 14:06 ` George Dunlap @ 2015-06-16 14:20 ` Juergen Gross 2015-06-16 14:37 ` George Dunlap 2015-06-17 11:34 ` Ian Campbell 0 siblings, 2 replies; 88+ messages in thread From: Juergen Gross @ 2015-06-16 14:20 UTC (permalink / raw) To: George Dunlap, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 04:06 PM, George Dunlap wrote: > On 06/16/2015 02:49 PM, Juergen Gross wrote: >> On 06/16/2015 03:29 PM, George Dunlap wrote: >>> On 06/16/2015 02:23 PM, Juergen Gross wrote: >>>> Hmm, I'd rather have it all in one place. Putting it in qemu would >>>> enable us to handle hotplug as well. A USB device assigned via it's >>>> serial to a domU could be automatically passed through by qemu when >>>> showing up. This isn't possible today, but we wouldn't have to change >>>> libxl again for supporting it, only qemu would have to be adapted. >>> >>> Look, we're talking here about the libxl interface. Ian thinks that *at >>> the libxl layer* we need to be able to specify all these things. It >>> doesn't matter at this point whether qemu can also do it or not. >> >> When I'm adding new functionality (and this is the case here) I always >> try to add it at the level where it should be. qemu already is capable >> of finding a USB device by various means and can be extended easily to >> support our needs. And please remember, for writing the pvusb backend >> I'm already doing changes to qemu. >> >> So why should we add the same functionality to libxl by reading sysfs >> instead of letting it do qemu via libusb? And what about BSD? Letting >> qemu find the device would avoid two variants in libxl. > > If the libxl interface only has "bus" and "port", then it doesn't matter > what qemu can do -- the caller has no way of asking qemu to watch for > vid:did:serial. > > If libxl has vid:did:serial in the interface, then it's only an > implementation detail whether we pass that into qemu or whether we pass > some other way of uniquely indentifying a particular device. And given > that no *current* versions of qemu support vid:did:serial, the most > sensible way to implement this would be to have libxl do the conversion > and send over bus:addr -- that way when you update libxl you get that > functionality regardless of whether qemu has it. > > Unless you're suggesting that the libxl interface should be a string > that we just pass verbatim to qemu. If that's what you mean, it's a > complete non-starter, and I'm sure Ian will agree with me. There's no > way that we can provide any interface consistency or any documentation > of what this string does if it boils down to "This does whatever the > version of qemu you happen to be running does". No, I didn't expect libxl to just pass an arbitrary string to qemu. My point was to avoid the sysfs accesses in libxl in order to support BSD as well and to reduce the complexity. >>> In the future, if we actually implement the "automatically grab this >>> device when it shows up" functionality, then yes, having it in qemu >>> rather than having a libxl daemon sit around and watch for those things, >>> might be handy. But we can cross that bridge when we come to it. >> >> I would agree if the efforts in libxl would be much smaller than in >> qemu. But if the efforts are comparable I'd rather do it in the >> component which will make such an enhancement easier. > > They're both small, so this is really bikeshedding at the moment. The > most important question is the interface: do we include vid:did:serial > in the libxl interface. Since you want qemu to do that, I take it that > your answer to that is "yes". Correct. > When we have patches submitted, we can discuss whether libxl should only > support the (as-yet unreleased) versions of qemu that do the search > themselves, or whether they should support all versions of qemu-xen. > (The answer seems pretty obvious to me...) May be I made one wrong assumption: I thought adding USB-passthrough for HVM domains would require qemu changes as well. If this is not the case I can understand your reasoning. Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 14:20 ` Juergen Gross @ 2015-06-16 14:37 ` George Dunlap 2015-06-17 11:34 ` Ian Campbell 1 sibling, 0 replies; 88+ messages in thread From: George Dunlap @ 2015-06-16 14:37 UTC (permalink / raw) To: Juergen Gross, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 03:20 PM, Juergen Gross wrote: > On 06/16/2015 04:06 PM, George Dunlap wrote: >> On 06/16/2015 02:49 PM, Juergen Gross wrote: >>> On 06/16/2015 03:29 PM, George Dunlap wrote: >>>> On 06/16/2015 02:23 PM, Juergen Gross wrote: >>>>> Hmm, I'd rather have it all in one place. Putting it in qemu would >>>>> enable us to handle hotplug as well. A USB device assigned via it's >>>>> serial to a domU could be automatically passed through by qemu when >>>>> showing up. This isn't possible today, but we wouldn't have to change >>>>> libxl again for supporting it, only qemu would have to be adapted. >>>> >>>> Look, we're talking here about the libxl interface. Ian thinks that >>>> *at >>>> the libxl layer* we need to be able to specify all these things. It >>>> doesn't matter at this point whether qemu can also do it or not. >>> >>> When I'm adding new functionality (and this is the case here) I always >>> try to add it at the level where it should be. qemu already is capable >>> of finding a USB device by various means and can be extended easily to >>> support our needs. And please remember, for writing the pvusb backend >>> I'm already doing changes to qemu. >>> >>> So why should we add the same functionality to libxl by reading sysfs >>> instead of letting it do qemu via libusb? And what about BSD? Letting >>> qemu find the device would avoid two variants in libxl. >> >> If the libxl interface only has "bus" and "port", then it doesn't matter >> what qemu can do -- the caller has no way of asking qemu to watch for >> vid:did:serial. >> >> If libxl has vid:did:serial in the interface, then it's only an >> implementation detail whether we pass that into qemu or whether we pass >> some other way of uniquely indentifying a particular device. And given >> that no *current* versions of qemu support vid:did:serial, the most >> sensible way to implement this would be to have libxl do the conversion >> and send over bus:addr -- that way when you update libxl you get that >> functionality regardless of whether qemu has it. >> >> Unless you're suggesting that the libxl interface should be a string >> that we just pass verbatim to qemu. If that's what you mean, it's a >> complete non-starter, and I'm sure Ian will agree with me. There's no >> way that we can provide any interface consistency or any documentation >> of what this string does if it boils down to "This does whatever the >> version of qemu you happen to be running does". > > No, I didn't expect libxl to just pass an arbitrary string to qemu. > My point was to avoid the sysfs accesses in libxl in order to support > BSD as well and to reduce the complexity. > >>>> In the future, if we actually implement the "automatically grab this >>>> device when it shows up" functionality, then yes, having it in qemu >>>> rather than having a libxl daemon sit around and watch for those >>>> things, >>>> might be handy. But we can cross that bridge when we come to it. >>> >>> I would agree if the efforts in libxl would be much smaller than in >>> qemu. But if the efforts are comparable I'd rather do it in the >>> component which will make such an enhancement easier. >> >> They're both small, so this is really bikeshedding at the moment. The >> most important question is the interface: do we include vid:did:serial >> in the libxl interface. Since you want qemu to do that, I take it that >> your answer to that is "yes". > > Correct. > >> When we have patches submitted, we can discuss whether libxl should only >> support the (as-yet unreleased) versions of qemu that do the search >> themselves, or whether they should support all versions of qemu-xen. >> (The answer seems pretty obvious to me...) > > May be I made one wrong assumption: I thought adding USB-passthrough for > HVM domains would require qemu changes as well. If this is not the case > I can understand your reasoning. Oh, right. No, getting HVM hotplug working over QMP was pretty straightforward; probably only a week's work. It's been the interface that has been the real difficult bit. There are some things that would be nicer to implement in qemu. Right now there's no way to *query* what devices have been plugged in; my patch series had to store information in xenstore. At some point in the future, it might make sense for libxl to mainly just ferry the options back and forth to qemu; even then I'm not sure. In any case it's an implementation detail that can be changed at any time. It's the interface we have to be really careful about. -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 14:20 ` Juergen Gross 2015-06-16 14:37 ` George Dunlap @ 2015-06-17 11:34 ` Ian Campbell 2015-06-17 11:40 ` Juergen Gross 2015-06-18 6:20 ` Chun Yan Liu 1 sibling, 2 replies; 88+ messages in thread From: Ian Campbell @ 2015-06-17 11:34 UTC (permalink / raw) To: Juergen Gross Cc: Wei Liu, George Dunlap, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Tue, 2015-06-16 at 16:20 +0200, Juergen Gross wrote: > My point was to avoid the sysfs accesses in libxl in order to support > BSD as well and to reduce the complexity. As a slight aside to this, can't libxl use libusb for a lot of this stuff and therefore avoid being Linux specific? http://libusb.info/ claims to support "Linux, OS X, Windows, Windows CE, Android, OpenBSD/NetBSD, Haiku.". Interestingly FreeBSD is missing there but I don't think that need to be a blocker. I don't see a problem with adding libusb to our set of dependencies, and it's certainly got to be better than (re)implementing a bunch of sysfs stuff (which I presume is what libusb does under the hood anyway). Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-17 11:34 ` Ian Campbell @ 2015-06-17 11:40 ` Juergen Gross 2015-06-18 6:20 ` Chun Yan Liu 1 sibling, 0 replies; 88+ messages in thread From: Juergen Gross @ 2015-06-17 11:40 UTC (permalink / raw) To: Ian Campbell Cc: Wei Liu, George Dunlap, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/17/2015 01:34 PM, Ian Campbell wrote: > On Tue, 2015-06-16 at 16:20 +0200, Juergen Gross wrote: >> My point was to avoid the sysfs accesses in libxl in order to support >> BSD as well and to reduce the complexity. > > As a slight aside to this, can't libxl use libusb for a lot of this > stuff and therefore avoid being Linux specific? > > http://libusb.info/ claims to support "Linux, OS X, Windows, Windows CE, > Android, OpenBSD/NetBSD, Haiku.". Interestingly FreeBSD is missing there > but I don't think that need to be a blocker. > > I don't see a problem with adding libusb to our set of dependencies, and > it's certainly got to be better than (re)implementing a bunch of sysfs > stuff (which I presume is what libusb does under the hood anyway). +1 Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-17 11:34 ` Ian Campbell 2015-06-17 11:40 ` Juergen Gross @ 2015-06-18 6:20 ` Chun Yan Liu 2015-06-18 7:02 ` Juergen Gross 1 sibling, 1 reply; 88+ messages in thread From: Chun Yan Liu @ 2015-06-18 6:20 UTC (permalink / raw) To: Ian Campbell, Juergen Gross Cc: Wei Liu, George Dunlap, Ian Jackson, xen-devel, Jim Fehlig, Simon Cao >>> On 6/17/2015 at 07:34 PM, in message <1434540857.13744.334.camel@citrix.com>, Ian Campbell <ian.campbell@citrix.com> wrote: > On Tue, 2015-06-16 at 16:20 +0200, Juergen Gross wrote: > > My point was to avoid the sysfs accesses in libxl in order to support > > BSD as well and to reduce the complexity. > > As a slight aside to this, can't libxl use libusb for a lot of this > stuff and therefore avoid being Linux specific? > > http://libusb.info/ claims to support "Linux, OS X, Windows, Windows CE, > Android, OpenBSD/NetBSD, Haiku.". Interestingly FreeBSD is missing there > but I don't think that need to be a blocker. > > I don't see a problem with adding libusb to our set of dependencies, and > it's certainly got to be better than (re)implementing a bunch of sysfs > stuff (which I presume is what libusb does under the hood anyway). Using libusb is certainly good and can save effort to implement things by ourself. Only one concern: some functions require newer version of libusb. For example, functions to get port (quite like busid) information libusb_get_port_numbers or libusb_get_port_path need libusb version >= 1.0.12. If libusb version is not satisfied, the whole pvusb work might be blocked. - Chunyan > > Ian. > > > ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-18 6:20 ` Chun Yan Liu @ 2015-06-18 7:02 ` Juergen Gross 2015-06-18 8:50 ` Ian Campbell 0 siblings, 1 reply; 88+ messages in thread From: Juergen Gross @ 2015-06-18 7:02 UTC (permalink / raw) To: Chun Yan Liu, Ian Campbell Cc: Wei Liu, George Dunlap, Ian Jackson, xen-devel, Jim Fehlig, Simon Cao On 06/18/2015 08:20 AM, Chun Yan Liu wrote: > > >>>> On 6/17/2015 at 07:34 PM, in message <1434540857.13744.334.camel@citrix.com>, > Ian Campbell <ian.campbell@citrix.com> wrote: >> On Tue, 2015-06-16 at 16:20 +0200, Juergen Gross wrote: >>> My point was to avoid the sysfs accesses in libxl in order to support >>> BSD as well and to reduce the complexity. >> >> As a slight aside to this, can't libxl use libusb for a lot of this >> stuff and therefore avoid being Linux specific? >> >> http://libusb.info/ claims to support "Linux, OS X, Windows, Windows CE, >> Android, OpenBSD/NetBSD, Haiku.". Interestingly FreeBSD is missing there >> but I don't think that need to be a blocker. >> >> I don't see a problem with adding libusb to our set of dependencies, and >> it's certainly got to be better than (re)implementing a bunch of sysfs >> stuff (which I presume is what libusb does under the hood anyway). > > Using libusb is certainly good and can save effort to implement things by > ourself. Only one concern: some functions require newer version of libusb. > For example, functions to get port (quite like busid) information > libusb_get_port_numbers or libusb_get_port_path need > libusb version >= 1.0.12. If libusb version is not satisfied, the whole pvusb > work might be blocked. Is this really a problem? lubusb version 1.0.12 is out for three years now. Would we really need to support pvUSB on dom0 not being capable to install a more recent libusb? Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-18 7:02 ` Juergen Gross @ 2015-06-18 8:50 ` Ian Campbell 2015-06-18 13:02 ` Juergen Gross 0 siblings, 1 reply; 88+ messages in thread From: Ian Campbell @ 2015-06-18 8:50 UTC (permalink / raw) To: Juergen Gross Cc: Wei Liu, George Dunlap, Ian Jackson, Chun Yan Liu, xen-devel, Jim Fehlig, Simon Cao On Thu, 2015-06-18 at 09:02 +0200, Juergen Gross wrote: > On 06/18/2015 08:20 AM, Chun Yan Liu wrote: > > > > > >>>> On 6/17/2015 at 07:34 PM, in message <1434540857.13744.334.camel@citrix.com>, > > Ian Campbell <ian.campbell@citrix.com> wrote: > >> On Tue, 2015-06-16 at 16:20 +0200, Juergen Gross wrote: > >>> My point was to avoid the sysfs accesses in libxl in order to support > >>> BSD as well and to reduce the complexity. > >> > >> As a slight aside to this, can't libxl use libusb for a lot of this > >> stuff and therefore avoid being Linux specific? > >> > >> http://libusb.info/ claims to support "Linux, OS X, Windows, Windows CE, > >> Android, OpenBSD/NetBSD, Haiku.". Interestingly FreeBSD is missing there > >> but I don't think that need to be a blocker. > >> > >> I don't see a problem with adding libusb to our set of dependencies, and > >> it's certainly got to be better than (re)implementing a bunch of sysfs > >> stuff (which I presume is what libusb does under the hood anyway). > > > > Using libusb is certainly good and can save effort to implement things by > > ourself. Only one concern: some functions require newer version of libusb. > > For example, functions to get port (quite like busid) information > > libusb_get_port_numbers or libusb_get_port_path need > > libusb version >= 1.0.12. If libusb version is not satisfied, the whole pvusb > > work might be blocked. > > Is this really a problem? lubusb version 1.0.12 is out for three years > now. Would we really need to support pvUSB on dom0 not being capable > to install a more recent libusb? Of interest would be which distro versions have >= 1.0.12 i.e. for common things like Debian, SuSE, SLE, Fedora etc. Even that may not be an absolute blocker, I don't think it would be too bad to say that for an older stable distro either an up to date libusb is made available or the pvusb functionality is disabled at build time (automatically, by configure.ac). The latter would be some faff to arrange but I think saying that Xen doesn't build on older stable distros unless you backport a libusb might be a step to far. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-18 8:50 ` Ian Campbell @ 2015-06-18 13:02 ` Juergen Gross 0 siblings, 0 replies; 88+ messages in thread From: Juergen Gross @ 2015-06-18 13:02 UTC (permalink / raw) To: Ian Campbell Cc: Wei Liu, George Dunlap, Ian Jackson, Chun Yan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/18/2015 10:50 AM, Ian Campbell wrote: > On Thu, 2015-06-18 at 09:02 +0200, Juergen Gross wrote: >> On 06/18/2015 08:20 AM, Chun Yan Liu wrote: >>> >>> >>>>>> On 6/17/2015 at 07:34 PM, in message <1434540857.13744.334.camel@citrix.com>, >>> Ian Campbell <ian.campbell@citrix.com> wrote: >>>> On Tue, 2015-06-16 at 16:20 +0200, Juergen Gross wrote: >>>>> My point was to avoid the sysfs accesses in libxl in order to support >>>>> BSD as well and to reduce the complexity. >>>> >>>> As a slight aside to this, can't libxl use libusb for a lot of this >>>> stuff and therefore avoid being Linux specific? >>>> >>>> http://libusb.info/ claims to support "Linux, OS X, Windows, Windows CE, >>>> Android, OpenBSD/NetBSD, Haiku.". Interestingly FreeBSD is missing there >>>> but I don't think that need to be a blocker. >>>> >>>> I don't see a problem with adding libusb to our set of dependencies, and >>>> it's certainly got to be better than (re)implementing a bunch of sysfs >>>> stuff (which I presume is what libusb does under the hood anyway). >>> >>> Using libusb is certainly good and can save effort to implement things by >>> ourself. Only one concern: some functions require newer version of libusb. >>> For example, functions to get port (quite like busid) information >>> libusb_get_port_numbers or libusb_get_port_path need >>> libusb version >= 1.0.12. If libusb version is not satisfied, the whole pvusb >>> work might be blocked. >> >> Is this really a problem? lubusb version 1.0.12 is out for three years >> now. Would we really need to support pvUSB on dom0 not being capable >> to install a more recent libusb? > > Of interest would be which distro versions have >= 1.0.12 i.e. for > common things like Debian, SuSE, SLE, Fedora etc. openSUSE since 13.2 (13.1 has 1.0.9) SLE since 12 Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:25 ` Juergen Gross 2015-06-16 11:45 ` George Dunlap 2015-06-16 11:45 ` [PATCH V4 3/7] libxl: add pvusb API Ian Jackson @ 2015-06-16 15:38 ` George Dunlap 2 siblings, 0 replies; 88+ messages in thread From: George Dunlap @ 2015-06-16 15:38 UTC (permalink / raw) To: Juergen Gross Cc: Wei Liu, Ian Campbell, Ian Jackson, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Tue, Jun 16, 2015 at 12:25 PM, Juergen Gross <jgross@suse.com> wrote: > Yes, they have. The question is whether those are different on multiple > instances? With "lsusb" I've found a device with serial number > 0123456789ABCD. Do you really believe I'm just lucky owning the one with > such a nice serial number? ;-) FWIW apparently the spec for USB printers requires a unique serial number; so there are probably cases where serial number is actually useful. -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 10:41 ` [PATCH V4 3/7] libxl: add pvusb API Ian Jackson 2015-06-16 10:56 ` Jürgen Groß @ 2015-06-16 11:01 ` George Dunlap 2015-06-16 11:12 ` Ian Jackson 1 sibling, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-16 11:01 UTC (permalink / raw) To: Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Tue, Jun 16, 2015 at 11:41 AM, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote: >> 3. Have the libxl layer accept both busid and bus:addr. Translate as >> necessary and store in the libxl_device_usb struct. > ... >> The advantage of #3 internally is that the functions can do the >> translation once (if necessary), and can then pass around the public >> libxl_device_usb struct as-is without needing any extra parameters or >> a separate libxl_device_usb_internal. The disadvantage, I think, is >> that from an interface perspective, it's fairly pointless to have >> both. busid doesn't really give you any better or more control than >> the other, and it's not any more convenient for the user (in fact it's >> less convenient because it's more difficult to find). > > Is the busid more stable in the face of plug/unplug ? This is the > normal reason for a more path-like device specification. > > If so then we must support it, even if it's not the usual way an > ordinary user would use it for a one-off. Otherwise you have to write > something in your config files for the VMs on your VM host, which will > break when someone plugs a keyboard into the `wrong' USB port. It's complicated. :-) The "busid" we're talking about here will identify a device at a particular *port* in the USB topology; the busid will take whatever is plugged into that particular port. So in the example in my other thread, the Yubikey "busid" is 2-3.1.2; but if I were to unplug the yubikey and plud my mouse into that port, the mouse would then be at 2-3.1.2. The "bus:addr" thing that Linux uses assigns a new "addr" every time you plug in a device. The first time I plugged in my Yubikey it got "002:010"; but when I unplugged it and plugged it back in again, it got "002:011". I take it this is on purpose, to solve exactly the problem above -- my mouse was at 2-3.1.2 before, and then I plug in a USB disk or a smartcard, I want to make sure I don't accidentally send commands to the wrong device. The other thing that most programs seem to handle is vendor:deviceid. The vendor:deviceid is the same every time you plug the device in, no matter where. The vendorid:deviceid for my Yubikey is "1050:0111"; so if I put that in my config file for libvirt or qemu, it will pass through my Yubikey to the VM, no matter where it's plugged in and no matter how many times it's been plugged in. Unfortunately, vendorid:deviceid is not like a MAC address; it's meant to describe the *type* of device, not be unique to the device itself. So if you have multiple devices of the same kind (say, several different Yubikeys) then vendorid:deviceid can't distinguish which is which. That's why qemu accepts at both bus:addr and vendorid:deviceid. We could in theory do the same thing -- accept any subset of {bus, port, address, vendorid, deviceid} which will uniquely identify a specific device. That may actually be a feature as well -- "Pass through the device at this bus / port, and by the way I expect it to be a mouse, so don't pass it through if it's something else." -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:01 ` George Dunlap @ 2015-06-16 11:12 ` Ian Jackson 2015-06-16 11:21 ` George Dunlap 0 siblings, 1 reply; 88+ messages in thread From: Ian Jackson @ 2015-06-16 11:12 UTC (permalink / raw) To: George Dunlap Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): > The "busid" we're talking about here will identify a device at a > particular *port* in the USB topology; the busid will take whatever is > plugged into that particular port. So in the example in my other > thread, the Yubikey "busid" is 2-3.1.2; but if I were to unplug the > yubikey and plud my mouse into that port, the mouse would then be at > 2-3.1.2. What you have just said contradicts Juergen's assertion that the busid is not stable across reboots. I think perhaps the difficulty is that the very first number, the usb controller number, may not be stable, because it depends on the order of device discovery. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:12 ` Ian Jackson @ 2015-06-16 11:21 ` George Dunlap 2015-06-16 16:32 ` Ian Jackson 0 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-16 11:21 UTC (permalink / raw) To: Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On Tue, Jun 16, 2015 at 12:12 PM, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote: > George Dunlap writes ("Re: [Xen-devel] [PATCH V4 3/7] libxl: add pvusb API"): >> The "busid" we're talking about here will identify a device at a >> particular *port* in the USB topology; the busid will take whatever is >> plugged into that particular port. So in the example in my other >> thread, the Yubikey "busid" is 2-3.1.2; but if I were to unplug the >> yubikey and plud my mouse into that port, the mouse would then be at >> 2-3.1.2. > > What you have just said contradicts Juergen's assertion that the busid > is not stable across reboots. > > I think perhaps the difficulty is that the very first number, the usb > controller number, may not be stable, because it depends on the order > of device discovery. I wasn't considering reboots when I made my statement. According to a comment on the libusb mailing list: "The operating system does not guarantee that bus numbers will remain fixed across reboots. Usually they will (if the computer's hardware hasn't been changed), but it isn't guaranteed." [1] I just used "lsusb -v" to scan through all the devices I have connected; some of them do have a field called "iSerial", but as most of these are '0' and the ones that are non-zero are between 1 and 3, I doubt that will be much use in most cases. I don't immediately see anything that might be a unique identifier. -George [1] http://sourceforge.net/p/libusb/mailman/libusb-devel/thread/20080324215139.22289.qmail@cdy.org/ ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 11:21 ` George Dunlap @ 2015-06-16 16:32 ` Ian Jackson 2015-06-16 16:39 ` George Dunlap 0 siblings, 1 reply; 88+ messages in thread From: Ian Jackson @ 2015-06-16 16:32 UTC (permalink / raw) To: George Dunlap Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao I have just discovered that the value used in /dev/disk/by-path is not from sysfs, or at least, not directly. udev cobbles it together with a bunch of string mangling, from information mostly from sysfs. There is no corresponding thing for usb devices. So Linux, the kernel, does not actually provide a stable device name string. This is obviously absurd, but I think fixing it is out of scope. I suggest we provide a facility to allow a user to specify a fnmatch glob pattern to be applied to the sysfs path. That way when they see their device is /devices/pci0000:00/0000:00:1d.7/usb1/1-1 they can write /devices/pci0000:00/0000:00:1d.7/usb*/*-1 which will match exactly and only the right thing. Ian. ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 16:32 ` Ian Jackson @ 2015-06-16 16:39 ` George Dunlap 2015-06-16 16:51 ` Ross Philipson 0 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-16 16:39 UTC (permalink / raw) To: Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 05:32 PM, Ian Jackson wrote: > I have just discovered that the value used in /dev/disk/by-path is not > from sysfs, or at least, not directly. > > udev cobbles it together with a bunch of string mangling, from > information mostly from sysfs. There is no corresponding thing for > usb devices. > > So Linux, the kernel, does not actually provide a stable device name > string. This is obviously absurd, but I think fixing it is out of > scope. > > I suggest we provide a facility to allow a user to specify a fnmatch > glob pattern to be applied to the sysfs path. That way when they see > their device is > /devices/pci0000:00/0000:00:1d.7/usb1/1-1 > they can write > /devices/pci0000:00/0000:00:1d.7/usb*/*-1 > which will match exactly and only the right thing. What about Juergen's system that has two usbN directories in a single pci node? Quoting: --- Hmm, perhaps. On my system I've got: /sys/devices/pci0000:00/0000:00:14.0/usb3/ /sys/devices/pci0000:00/0000:00:14.0/usb4/ So two busses on one pci bus address. Are usb3 and usb4 always in this order or are they sometimes just numbered the other way round? --- Assuming that usb3 and usb4 are actually distinct busses, and they might both have something plugged into port; in which case a glob like this: devices/pci0000:00/0000:00:14.0/usb*/*-1 Might match both of the following: /sys/devices/pci0000:00/0000:00:14.0/usb3/3-1 /sys/devices/pci0000:00/0000:00:14.0/usb4/4-1 -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 16:39 ` George Dunlap @ 2015-06-16 16:51 ` Ross Philipson 2015-06-17 4:03 ` Jürgen Groß 0 siblings, 1 reply; 88+ messages in thread From: Ross Philipson @ 2015-06-16 16:51 UTC (permalink / raw) To: George Dunlap, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 12:39 PM, George Dunlap wrote: > On 06/16/2015 05:32 PM, Ian Jackson wrote: >> I have just discovered that the value used in /dev/disk/by-path is not >> from sysfs, or at least, not directly. >> >> udev cobbles it together with a bunch of string mangling, from >> information mostly from sysfs. There is no corresponding thing for >> usb devices. >> >> So Linux, the kernel, does not actually provide a stable device name >> string. This is obviously absurd, but I think fixing it is out of >> scope. >> >> I suggest we provide a facility to allow a user to specify a fnmatch >> glob pattern to be applied to the sysfs path. That way when they see >> their device is >> /devices/pci0000:00/0000:00:1d.7/usb1/1-1 >> they can write >> /devices/pci0000:00/0000:00:1d.7/usb*/*-1 >> which will match exactly and only the right thing. > > What about Juergen's system that has two usbN directories in a single > pci node? > > Quoting: > --- > Hmm, perhaps. On my system I've got: > > /sys/devices/pci0000:00/0000:00:14.0/usb3/ > /sys/devices/pci0000:00/0000:00:14.0/usb4/ > > So two busses on one pci bus address. Are usb3 and usb4 always in this > order or are they sometimes just numbered the other way round? > --- > > Assuming that usb3 and usb4 are actually distinct busses, and they might > both have something plugged into port; in which case a glob like this: > > devices/pci0000:00/0000:00:14.0/usb*/*-1 > > Might match both of the following: > > /sys/devices/pci0000:00/0000:00:14.0/usb3/3-1 > /sys/devices/pci0000:00/0000:00:14.0/usb4/4-1 Is that an xHCI host controller? If so that might be how the system represents the 2 logical (USB2/USB3) root hubs - each as its own separate bus. > > -George > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel > -- Ross Philipson ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-16 16:51 ` Ross Philipson @ 2015-06-17 4:03 ` Jürgen Groß 2015-06-17 13:48 ` Ross Philipson 0 siblings, 1 reply; 88+ messages in thread From: Jürgen Groß @ 2015-06-17 4:03 UTC (permalink / raw) To: Ross Philipson, George Dunlap, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/16/2015 06:51 PM, Ross Philipson wrote: > On 06/16/2015 12:39 PM, George Dunlap wrote: >> On 06/16/2015 05:32 PM, Ian Jackson wrote: >>> I have just discovered that the value used in /dev/disk/by-path is not >>> from sysfs, or at least, not directly. >>> >>> udev cobbles it together with a bunch of string mangling, from >>> information mostly from sysfs. There is no corresponding thing for >>> usb devices. >>> >>> So Linux, the kernel, does not actually provide a stable device name >>> string. This is obviously absurd, but I think fixing it is out of >>> scope. >>> >>> I suggest we provide a facility to allow a user to specify a fnmatch >>> glob pattern to be applied to the sysfs path. That way when they see >>> their device is >>> /devices/pci0000:00/0000:00:1d.7/usb1/1-1 >>> they can write >>> /devices/pci0000:00/0000:00:1d.7/usb*/*-1 >>> which will match exactly and only the right thing. >> >> What about Juergen's system that has two usbN directories in a single >> pci node? >> >> Quoting: >> --- >> Hmm, perhaps. On my system I've got: >> >> /sys/devices/pci0000:00/0000:00:14.0/usb3/ >> /sys/devices/pci0000:00/0000:00:14.0/usb4/ >> >> So two busses on one pci bus address. Are usb3 and usb4 always in this >> order or are they sometimes just numbered the other way round? >> --- >> >> Assuming that usb3 and usb4 are actually distinct busses, and they might >> both have something plugged into port; in which case a glob like this: >> >> devices/pci0000:00/0000:00:14.0/usb*/*-1 >> >> Might match both of the following: >> >> /sys/devices/pci0000:00/0000:00:14.0/usb3/3-1 >> /sys/devices/pci0000:00/0000:00:14.0/usb4/4-1 > > Is that an xHCI host controller? If so that might be how the system > represents the 2 logical (USB2/USB3) root hubs - each as its own > separate bus. See my other reply: this is the case. So Ian's suggestion would still work. Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-17 4:03 ` Jürgen Groß @ 2015-06-17 13:48 ` Ross Philipson 0 siblings, 0 replies; 88+ messages in thread From: Ross Philipson @ 2015-06-17 13:48 UTC (permalink / raw) To: Jürgen Groß, George Dunlap, Ian Jackson Cc: Wei Liu, Ian Campbell, Chunyan Liu, xen-devel, Jim Fehlig, Simon Cao On 06/17/2015 12:03 AM, Jürgen Groß wrote: > On 06/16/2015 06:51 PM, Ross Philipson wrote: >> On 06/16/2015 12:39 PM, George Dunlap wrote: >>> On 06/16/2015 05:32 PM, Ian Jackson wrote: >>>> I have just discovered that the value used in /dev/disk/by-path is not >>>> from sysfs, or at least, not directly. >>>> >>>> udev cobbles it together with a bunch of string mangling, from >>>> information mostly from sysfs. There is no corresponding thing for >>>> usb devices. >>>> >>>> So Linux, the kernel, does not actually provide a stable device name >>>> string. This is obviously absurd, but I think fixing it is out of >>>> scope. >>>> >>>> I suggest we provide a facility to allow a user to specify a fnmatch >>>> glob pattern to be applied to the sysfs path. That way when they see >>>> their device is >>>> /devices/pci0000:00/0000:00:1d.7/usb1/1-1 >>>> they can write >>>> /devices/pci0000:00/0000:00:1d.7/usb*/*-1 >>>> which will match exactly and only the right thing. >>> >>> What about Juergen's system that has two usbN directories in a single >>> pci node? >>> >>> Quoting: >>> --- >>> Hmm, perhaps. On my system I've got: >>> >>> /sys/devices/pci0000:00/0000:00:14.0/usb3/ >>> /sys/devices/pci0000:00/0000:00:14.0/usb4/ >>> >>> So two busses on one pci bus address. Are usb3 and usb4 always in this >>> order or are they sometimes just numbered the other way round? >>> --- >>> >>> Assuming that usb3 and usb4 are actually distinct busses, and they might >>> both have something plugged into port; in which case a glob like this: >>> >>> devices/pci0000:00/0000:00:14.0/usb*/*-1 >>> >>> Might match both of the following: >>> >>> /sys/devices/pci0000:00/0000:00:14.0/usb3/3-1 >>> /sys/devices/pci0000:00/0000:00:14.0/usb4/4-1 >> >> Is that an xHCI host controller? If so that might be how the system >> represents the 2 logical (USB2/USB3) root hubs - each as its own >> separate bus. > > See my other reply: this is the case. So Ian's suggestion would still > work. Ack, saw it, thanks. > > > Juergen > -- Ross Philipson ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-10 3:20 ` [PATCH V4 3/7] libxl: add pvusb API Chunyan Liu ` (2 preceding siblings ...) 2015-06-15 14:17 ` George Dunlap @ 2015-06-15 17:47 ` George Dunlap 2015-06-23 10:18 ` Chun Yan Liu 3 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-15 17:47 UTC (permalink / raw) To: Chunyan Liu, xen-devel; +Cc: wei.liu2, Simon Cao, Ian.Jackson, ian.campbell On 06/10/2015 04:20 AM, Chunyan Liu wrote: > Add pvusb APIs, including: > - attach/detach (create/destroy) virtual usb controller. > - attach/detach usb device > - list usb controller and usb devices > - some other helper functions > > Signed-off-by: Chunyan Liu <cyliu@suse.com> > Signed-off-by: Simon Cao <caobosimon@gmail.com> > > --- > changes: > - make libxl_device_usbctrl_add async, to be consistent with > libxl_device_usbctrl_remove, using MACROs DEFINE_DEVICE_ADD > and DEFINE_DEVICES_ADD, adjusting related codes. > - correct update_json related processing. > - use libxl__* helper functions instead of calloc, realloc > and strdup, etc. whereever possible. > - merge protocol definition pv|qemu in this patch > - treat it as warning at rebind failure instead of error in usb_remove > - add documentation docs/misc/pvusb.txt to describe pvusb > details (toolstack design, libxl design, xenstore info, etc.) > - other fixes addring Wei and George's comments > > docs/misc/pvusb.txt | 243 +++++++ > tools/libxl/Makefile | 2 +- > tools/libxl/libxl.c | 6 + > tools/libxl/libxl.h | 65 ++ > tools/libxl/libxl_internal.h | 16 +- > tools/libxl/libxl_osdeps.h | 13 + > tools/libxl/libxl_pvusb.c | 1249 ++++++++++++++++++++++++++++++++++ > tools/libxl/libxl_types.idl | 52 ++ > tools/libxl/libxl_types_internal.idl | 1 + > tools/libxl/libxl_utils.c | 16 + > 10 files changed, 1661 insertions(+), 2 deletions(-) > create mode 100644 docs/misc/pvusb.txt > create mode 100644 tools/libxl/libxl_pvusb.c > > diff --git a/docs/misc/pvusb.txt b/docs/misc/pvusb.txt > new file mode 100644 > index 0000000..4cdf965 > --- /dev/null > +++ b/docs/misc/pvusb.txt > @@ -0,0 +1,243 @@ > +1. Overview > + > +There are two general methods for passing through individual host > +devices to a guest. The first is via an emulated USB device > +controller; the second is PVUSB. > + > +Additionally, there are two ways to add USB devices to a guest: via > +the config file at domain creation time, and via hot-plug while the VM > +is running. > + > +* Emulated USB > + > +In emulated USB, the device model (qemu) presents an emulated USB > +controller to the guest. The device model process then grabs control > +of the device from domain 0 and and passes the USB commands between > +the guest OS and the host USB device. > + > +This method is only available to HVM domains, and is not available for > +domains running with device model stubdomains. > + > +* PVUSB > + > +PVUSB uses a paravirtialized front-end/back-end interface, similar to > +the traditional Xen PV network and disk protocols. In order to use > +PVUSB, you need usbfront in your guest OS, and usbback in dom0 (or > +your USB driver domain). > + > +Additionally, for easy use of PVUSB, you need support in the toolstack > +to get the two sides to talk to each other. I think this paragraph is probably unnecessary. By the time this is checked in, the toolstack will have the necessary support. > +2. Specifying a host USB device > + > +QEMU hmp commands allows USB devices to be specified either by their s/hmp/qmp/; ? > +bus address (in the form bus.device) or their device tag (in the form > +vendorid:deviceid). > + > +Each way of specifying has its advantages: > + > + Specifying by device tag will always get the same device, > +regardless of where the device ends up in the USB bus topology. > +However, if there are two identical devices, it will not allow you to > +specify which one. > + > + Specifying by bus address will always allow you to choose a > +specific device, even if you have duplicates. However, the bus address > +may change depending on which port you plugged the device into, and > +possibly also after a reboot. > + > +To avoid duplication of vendorid:deviceid, we'll use bus address to > +specify host USB device in xl toolstack. This paragraph comparing the different ways of specifying devices makes sense to include in the 0/N series summary, but not so much in a file we're checking in. > + > +You can use lsusb to list the USB devices on the system: > + > +Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 > +Hub > +Bus 003 Device 002: ID f617:0905 > +Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub > +Bus 001 Device 004: ID 0424:2640 Standard Microsystems Corp. USB 2.0 > +Hub > +Bus 001 Device 005: ID 0424:4060 Standard Microsystems Corp. Ultra > +Fast Media Reader > +Bus 001 Device 006: ID 046d:c016 Logitech, Inc. Optical Wheel Mouse > + > +To pass through the Logitec mouse, for instance, you could specify > +1.6 (remove leading zeroes). > + > +Note: USB Hub could not be assigned to guest. "USB hubs cannot be assigned to a guest." [snip] > +int libxl_device_usbctrl_getinfo(libxl_ctx *ctx, uint32_t domid, > + libxl_device_usbctrl *usbctrl, > + libxl_usbctrlinfo *usbctrlinfo) > +{ > + GC_INIT(ctx); > + char *dompath, *usbctrlpath; > + char *val; > + int rc = 0; > + > + usbctrlinfo->devid = usbctrl->devid; > + usbctrlinfo->ports = usbctrl->ports; > + usbctrlinfo->version = usbctrl->version; > + usbctrlinfo->protocol = usbctrl->protocol; You seem to have missed my message about this -- the only thing you are allowed to read from usbctrl in this function is the devid. Everything else you have to look up and give back to the user. That's the point of the function -- the user has the devid and is asking *you* how many ports there are, what usb version it is, &c. [snip] > +/* get usb devices under certain usb controller */ > +static int > +libxl__device_usb_list_per_usbctrl(libxl__gc *gc, uint32_t domid, int usbctrl, Should usbctrl be of type libxl_devid? > +static int libxl__device_usb_setdefault(libxl__gc *gc, uint32_t domid, > + libxl_device_usb *usb, > + bool update_json) > +{ > + char *be_path, *tmp; > + > + if (usb->ctrl == -1) { > + int ret = libxl__device_usb_set_default_usbctrl(gc, domid, usb); > + /* If no existing ctrl to host this usb device, setup a new one */ > + if (ret) { > + libxl_device_usbctrl usbctrl; > + libxl_device_usbctrl_init(&usbctrl); > + if (libxl_device_usbctrl_add_common(CTX, domid, &usbctrl, > + 0, update_json)) { > + LOG(ERROR, "Failed to create usb controller"); > + return ERROR_INVAL; > + } > + usb->ctrl = usbctrl.devid; > + usb->port = 1; > + libxl_device_usbctrl_dispose(&usbctrl); > + } > + } Sorry for not noticing this before -- it looks like if you set usb->ctrl to -1, it will automatically choose both a controller and a port number. But what if you want to specify that you want a particular controller (for example, if you want to specify the PV controller rather than the emulated one, or vice versa), but didn't want to have to manually keep track of which ports were free? It seems like it would be better to have the code treat port 0 as "automatically choose a port for me". (If this were the only thing holding it up I would say this wouldn't be a blocker to going in.) > +static int libxl__device_usb_remove(libxl__gc *gc, uint32_t domid, > + libxl_device_usb *usb) > +{ > + libxl_device_usb *usbs = NULL; > + libxl_device_usb *usb_find = NULL; > + int i, num = 0, rc; > + > + assert(usb->busid || (usb->hostbus > 0 && usb->hostaddr > 0)); > + > + if (!usb->busid) { > + usb->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); > + if (!usb->busid) { > + LOG(ERROR, "USB device doesn't exist in sysfs"); > + return ERROR_INVAL; > + } > + } So here you're keying the removal on the *host* idea of what the device is. But the standard would be to key this on the *guest* idea of what the device is. When you're doing disk removal, you don't say "xl block-detach 1 /images/foo.img" that is, the path to the disk image; you say "xl block-detach 1 xvda" that is, the image as seen from the guest. Since there is no devid, you should make it possible to remove by <ctrl,port>. Removing also by hostbus:hostaddr seems like useful functionality, so it's probably not bad to keep it; but the <ctrl,port> should be the main functionality. > +int libxl_device_usb_getinfo(libxl_ctx *ctx, libxl_device_usb *usb, > + libxl_usbinfo *usbinfo) > +{ > + GC_INIT(ctx); > + char *filename; > + void *buf = NULL; > + > + usbinfo->ctrl = usb->ctrl; > + usbinfo->port = usb->port; > + > + if (usb->busid) > + usbinfo->busid = libxl__strdup(NOGC, usb->busid); > + else if (usb->hostbus > 0 && usb->hostaddr > 0) > + usbinfo->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); Similar to my libxl_device_usbctrl_getinfo() comment -- the purpose of this function is to specify a minimal amount of information, and have the library return and look up everything else. Since libxl_device_usb doesn't have a devid, the "key" for this should probably be <ctrl,port>. Which means, you are only allowed to read usb->{ctrl,port}; everything else you have to look up. -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-15 17:47 ` George Dunlap @ 2015-06-23 10:18 ` Chun Yan Liu 2015-06-23 11:29 ` George Dunlap 0 siblings, 1 reply; 88+ messages in thread From: Chun Yan Liu @ 2015-06-23 10:18 UTC (permalink / raw) To: George Dunlap, xen-devel; +Cc: Ian.Jackson, Simon Cao, wei.liu2, ian.campbell >>> On 6/16/2015 at 01:47 AM, in message <557F0FA7.2060402@eu.citrix.com>, George Dunlap <george.dunlap@eu.citrix.com> wrote: > On 06/10/2015 04:20 AM, Chunyan Liu wrote: > > Add pvusb APIs, including: > > - attach/detach (create/destroy) virtual usb controller. > > - attach/detach usb device > > - list usb controller and usb devices > > - some other helper functions > > > > Signed-off-by: Chunyan Liu <cyliu@suse.com> > > Signed-off-by: Simon Cao <caobosimon@gmail.com> > > > > --- > > changes: > > - make libxl_device_usbctrl_add async, to be consistent with > > libxl_device_usbctrl_remove, using MACROs DEFINE_DEVICE_ADD > > and DEFINE_DEVICES_ADD, adjusting related codes. > > - correct update_json related processing. > > - use libxl__* helper functions instead of calloc, realloc > > and strdup, etc. whereever possible. > > - merge protocol definition pv|qemu in this patch > > - treat it as warning at rebind failure instead of error in usb_remove > > - add documentation docs/misc/pvusb.txt to describe pvusb > > details (toolstack design, libxl design, xenstore info, etc.) > > - other fixes addring Wei and George's comments > > > > docs/misc/pvusb.txt | 243 +++++++ > > tools/libxl/Makefile | 2 +- > > tools/libxl/libxl.c | 6 + > > tools/libxl/libxl.h | 65 ++ > > tools/libxl/libxl_internal.h | 16 +- > > tools/libxl/libxl_osdeps.h | 13 + > > tools/libxl/libxl_pvusb.c | 1249 > ++++++++++++++++++++++++++++++++++ > > tools/libxl/libxl_types.idl | 52 ++ > > tools/libxl/libxl_types_internal.idl | 1 + > > tools/libxl/libxl_utils.c | 16 + > > 10 files changed, 1661 insertions(+), 2 deletions(-) > > create mode 100644 docs/misc/pvusb.txt > > create mode 100644 tools/libxl/libxl_pvusb.c > > > > diff --git a/docs/misc/pvusb.txt b/docs/misc/pvusb.txt > > new file mode 100644 > > index 0000000..4cdf965 > > --- /dev/null > > +++ b/docs/misc/pvusb.txt > > @@ -0,0 +1,243 @@ > > +1. Overview > > + > > +There are two general methods for passing through individual host > > +devices to a guest. The first is via an emulated USB device > > +controller; the second is PVUSB. > > + > > +Additionally, there are two ways to add USB devices to a guest: via > > +the config file at domain creation time, and via hot-plug while the VM > > +is running. > > + > > +* Emulated USB > > + > > +In emulated USB, the device model (qemu) presents an emulated USB > > +controller to the guest. The device model process then grabs control > > +of the device from domain 0 and and passes the USB commands between > > +the guest OS and the host USB device. > > + > > +This method is only available to HVM domains, and is not available for > > +domains running with device model stubdomains. > > + > > +* PVUSB > > + > > +PVUSB uses a paravirtialized front-end/back-end interface, similar to > > +the traditional Xen PV network and disk protocols. In order to use > > +PVUSB, you need usbfront in your guest OS, and usbback in dom0 (or > > +your USB driver domain). > > + > > +Additionally, for easy use of PVUSB, you need support in the toolstack > > +to get the two sides to talk to each other. > > I think this paragraph is probably unnecessary. By the time this is > checked in, the toolstack will have the necessary support. > > > +2. Specifying a host USB device > > + > > +QEMU hmp commands allows USB devices to be specified either by their > > s/hmp/qmp/; ? > > > +bus address (in the form bus.device) or their device tag (in the form > > +vendorid:deviceid). > > + > > +Each way of specifying has its advantages: > > + > > + Specifying by device tag will always get the same device, > > +regardless of where the device ends up in the USB bus topology. > > +However, if there are two identical devices, it will not allow you to > > +specify which one. > > + > > + Specifying by bus address will always allow you to choose a > > +specific device, even if you have duplicates. However, the bus address > > +may change depending on which port you plugged the device into, and > > +possibly also after a reboot. > > + > > +To avoid duplication of vendorid:deviceid, we'll use bus address to > > +specify host USB device in xl toolstack. > > This paragraph comparing the different ways of specifying devices makes > sense to include in the 0/N series summary, but not so much in a file > we're checking in. > > > + > > +You can use lsusb to list the USB devices on the system: > > + > > +Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 > > +Hub > > +Bus 003 Device 002: ID f617:0905 > > +Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub > > +Bus 001 Device 004: ID 0424:2640 Standard Microsystems Corp. USB 2.0 > > +Hub > > +Bus 001 Device 005: ID 0424:4060 Standard Microsystems Corp. Ultra > > +Fast Media Reader > > +Bus 001 Device 006: ID 046d:c016 Logitech, Inc. Optical Wheel Mouse > > + > > +To pass through the Logitec mouse, for instance, you could specify > > +1.6 (remove leading zeroes). > > + > > +Note: USB Hub could not be assigned to guest. > > "USB hubs cannot be assigned to a guest." > > [snip] > > > +int libxl_device_usbctrl_getinfo(libxl_ctx *ctx, uint32_t domid, > > + libxl_device_usbctrl *usbctrl, > > + libxl_usbctrlinfo *usbctrlinfo) > > +{ > > + GC_INIT(ctx); > > + char *dompath, *usbctrlpath; > > + char *val; > > + int rc = 0; > > + > > + usbctrlinfo->devid = usbctrl->devid; > > + usbctrlinfo->ports = usbctrl->ports; > > + usbctrlinfo->version = usbctrl->version; > > + usbctrlinfo->protocol = usbctrl->protocol; > > You seem to have missed my message about this -- the only thing you are > allowed to read from usbctrl in this function is the devid. Everything > else you have to look up and give back to the user. That's the point of > the function -- the user has the devid and is asking *you* how many > ports there are, what usb version it is, &c. Agree. Will update. > > [snip] > > +/* get usb devices under certain usb controller */ > > +static int > > +libxl__device_usb_list_per_usbctrl(libxl__gc *gc, uint32_t domid, int > usbctrl, > > Should usbctrl be of type libxl_devid? To be strict, it should be libxl_devid. But libxl_devid is actually 'int'. I see most current APIs also uses 'int'. Like libxl_devid_to_device_vtpm API, devid also uses 'int'. Anyway, I can update :) > > > > +static int libxl__device_usb_setdefault(libxl__gc *gc, uint32_t domid, > > + libxl_device_usb *usb, > > + bool update_json) > > +{ > > + char *be_path, *tmp; > > + > > + if (usb->ctrl == -1) { > > + int ret = libxl__device_usb_set_default_usbctrl(gc, domid, usb); > > + /* If no existing ctrl to host this usb device, setup a new one */ > > + if (ret) { > > + libxl_device_usbctrl usbctrl; > > + libxl_device_usbctrl_init(&usbctrl); > > + if (libxl_device_usbctrl_add_common(CTX, domid, &usbctrl, > > + 0, update_json)) { > > + LOG(ERROR, "Failed to create usb controller"); > > + return ERROR_INVAL; > > + } > > + usb->ctrl = usbctrl.devid; > > + usb->port = 1; > > + libxl_device_usbctrl_dispose(&usbctrl); > > + } > > + } > > Sorry for not noticing this before -- it looks like if you set > usb->ctrl to -1, it will automatically choose both a controller and a > port number. But what if you want to specify that you want a particular > controller (for example, if you want to specify the PV controller rather > than the emulated one, or vice versa), but didn't want to have to > manually keep track of which ports were free? That is libxl__device_usb_set_default_usbctrl's work, it will try to find an available port for USB device. If there is no available port, then it will create a new USB controller and by default uses its first port. > > It seems like it would be better to have the code treat port 0 as > "automatically choose a port for me". Here we set port=1 because port number is starting from 1. Like, if there are 4 ports, port number will be 1, 2, 3, 4 (not 0,1 ,2, 3). Since xend, it behaves like this. I think that's what pvusb driver needs. Juergen, right? > > (If this were the only thing holding it up I would say this wouldn't be > a blocker to going in.) > > > +static int libxl__device_usb_remove(libxl__gc *gc, uint32_t domid, > > + libxl_device_usb *usb) > > +{ > > + libxl_device_usb *usbs = NULL; > > + libxl_device_usb *usb_find = NULL; > > + int i, num = 0, rc; > > + > > + assert(usb->busid || (usb->hostbus > 0 && usb->hostaddr > 0)); > > + > > + if (!usb->busid) { > > + usb->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); > > + if (!usb->busid) { > > + LOG(ERROR, "USB device doesn't exist in sysfs"); > > + return ERROR_INVAL; > > + } > > + } > > So here you're keying the removal on the *host* idea of what the device > is. But the standard would be to key this on the *guest* idea of what > the device is. When you're doing disk removal, you don't say > > "xl block-detach 1 /images/foo.img" > > that is, the path to the disk image; you say > > "xl block-detach 1 xvda" > > that is, the image as seen from the guest. > > Since there is no devid, you should make it possible to remove by > <ctrl,port>. Removing also by hostbus:hostaddr seems like useful > functionality, so it's probably not bad to keep it; but the <ctrl,port> > should be the main functionality. Do you think <ctrl,port> is better? That means in qemu emulated way, user also need to know the <ctrl, port> info of the USB device. In the past, for usb-add or usb-delete, <ctrl, port> info is hidden to user, it used bus.addr or verndorid.deviceid. > > > +int libxl_device_usb_getinfo(libxl_ctx *ctx, libxl_device_usb *usb, > > + libxl_usbinfo *usbinfo) > > +{ > > + GC_INIT(ctx); > > + char *filename; > > + void *buf = NULL; > > + > > + usbinfo->ctrl = usb->ctrl; > > + usbinfo->port = usb->port; > > + > > + if (usb->busid) > > + usbinfo->busid = libxl__strdup(NOGC, usb->busid); > > + else if (usb->hostbus > 0 && usb->hostaddr > 0) > > + usbinfo->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); > > Similar to my libxl_device_usbctrl_getinfo() comment -- the purpose of > this function is to specify a minimal amount of information, and have > the library return and look up everything else. Since libxl_device_usb > doesn't have a devid, the "key" for this should probably be <ctrl,port>. > Which means, you are only allowed to read usb->{ctrl,port}; everything > else you have to look up. Agree. Will update. Thanks, Chunyan > > -George > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel > > ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-23 10:18 ` Chun Yan Liu @ 2015-06-23 11:29 ` George Dunlap 2015-06-24 2:26 ` Chun Yan Liu 0 siblings, 1 reply; 88+ messages in thread From: George Dunlap @ 2015-06-23 11:29 UTC (permalink / raw) To: Chun Yan Liu, xen-devel; +Cc: Ian.Jackson, Simon Cao, wei.liu2, ian.campbell On 06/23/2015 11:18 AM, Chun Yan Liu wrote: >>>> On 6/16/2015 at 01:47 AM, in message <557F0FA7.2060402@eu.citrix.com>, George > Dunlap <george.dunlap@eu.citrix.com> wrote: >>> +static int libxl__device_usb_setdefault(libxl__gc *gc, uint32_t domid, >>> + libxl_device_usb *usb, >>> + bool update_json) >>> +{ >>> + char *be_path, *tmp; >>> + >>> + if (usb->ctrl == -1) { >>> + int ret = libxl__device_usb_set_default_usbctrl(gc, domid, usb); >>> + /* If no existing ctrl to host this usb device, setup a new one */ >>> + if (ret) { >>> + libxl_device_usbctrl usbctrl; >>> + libxl_device_usbctrl_init(&usbctrl); >>> + if (libxl_device_usbctrl_add_common(CTX, domid, &usbctrl, >>> + 0, update_json)) { >>> + LOG(ERROR, "Failed to create usb controller"); >>> + return ERROR_INVAL; >>> + } >>> + usb->ctrl = usbctrl.devid; >>> + usb->port = 1; >>> + libxl_device_usbctrl_dispose(&usbctrl); >>> + } >>> + } >> >> Sorry for not noticing this before -- it looks like if you set >> usb->ctrl to -1, it will automatically choose both a controller and a >> port number. But what if you want to specify that you want a particular >> controller (for example, if you want to specify the PV controller rather >> than the emulated one, or vice versa), but didn't want to have to >> manually keep track of which ports were free? > > That is libxl__device_usb_set_default_usbctrl's work, it will try to find > an available port for USB device. If there is no available port, then it will > create a new USB controller and by default uses its first port. >> >> It seems like it would be better to have the code treat port 0 as >> "automatically choose a port for me". > > Here we set port=1 because port number is starting from 1. Like, if there > are 4 ports, port number will be 1, 2, 3, 4 (not 0,1 ,2, 3). Since xend, it > behaves like this. I think that's what pvusb driver needs. Juergen, right? I think you misunderstood what I was saying. There are three cases I think we want to consider: 1. The caller knows both the controller and the port number they want to assign it to. 2. The caller knows what controller they want to assign it to, but they want libxl to choose the port number automatically. 3. The caller wants libxl to choose both the controller and the port automatically. 3a. A controller already exists with a free port 3b. No controllers with free ports exist. Your code handles #1 properly -- if both controller and port number are set, it will try to add the USB device to that specific controller and port number. Your code also handles #3a properly -- if the controller is not set, it will automatically choose a controller and a port number. It also handles #3b properly -- if there are no controllers, or if the controllers have no ports available, then it will create a new one and assign it to port 1. Your code does not, however, handle the second case -- where the user knows they want to plug it into a specific controller (for instance, the PVUSB one rather than the emulated one), but don't want to keep track of which ports are available. Since ports start as 1, then '0' is an invalid number for a port (just as -1 is an invalid id for a controller). I was suggesting that you could use '0' as a magic number meaning, "Please choose a port for me." However, after our discussion here about providing "helpers" to translate stuff for the libxl interface, if the other maintainers will like the "automatically create a controller" functionality at all; or if they would rather we (again) provide helper functions so that the toolstack can do this work. >>> +static int libxl__device_usb_remove(libxl__gc *gc, uint32_t domid, >>> + libxl_device_usb *usb) >>> +{ >>> + libxl_device_usb *usbs = NULL; >>> + libxl_device_usb *usb_find = NULL; >>> + int i, num = 0, rc; >>> + >>> + assert(usb->busid || (usb->hostbus > 0 && usb->hostaddr > 0)); >>> + >>> + if (!usb->busid) { >>> + usb->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); >>> + if (!usb->busid) { >>> + LOG(ERROR, "USB device doesn't exist in sysfs"); >>> + return ERROR_INVAL; >>> + } >>> + } >> >> So here you're keying the removal on the *host* idea of what the device >> is. But the standard would be to key this on the *guest* idea of what >> the device is. When you're doing disk removal, you don't say >> >> "xl block-detach 1 /images/foo.img" >> >> that is, the path to the disk image; you say >> >> "xl block-detach 1 xvda" >> >> that is, the image as seen from the guest. >> >> Since there is no devid, you should make it possible to remove by >> <ctrl,port>. Removing also by hostbus:hostaddr seems like useful >> functionality, so it's probably not bad to keep it; but the <ctrl,port> >> should be the main functionality. > > Do you think <ctrl,port> is better? That means in qemu emulated way, > user also need to know the <ctrl, port> info of the USB device. In the past, > for usb-add or usb-delete, <ctrl, port> info is hidden to user, it used > bus.addr or verndorid.deviceid. Hmm -- you know, you're right. For vif, vfb, and vkb it seems to use devid (which is libxl specific, but indexed per vm); disk uses vdev (which is indexed per vm); but pci pass-through uses BDF, which is based on the host. (And that's what my HVM series from last year did as well.) BTW, to remove a device over qmp, you need the name you gave the device when you assigned it. But at least as of a year ago, there was no way to query qemu to see which devices you had assigned; so you have to store that information away in xenstore somewhere anyway. So from a qemu perspective, having a devid or guest <ctrl,port> mapping isn't a big deal. Also, from a UI perspective: it should be easy for xl to translate host bus.addr into guest <ctrl,port>, so I don't think that's as big a deal. The main reason I have for wanting to do it at the guest level is so that we can use the same interface for things which have no host handle -- i.e., plugging or unplugging a virtual tablet, or maybe a USB disk. -George ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 3/7] libxl: add pvusb API 2015-06-23 11:29 ` George Dunlap @ 2015-06-24 2:26 ` Chun Yan Liu 0 siblings, 0 replies; 88+ messages in thread From: Chun Yan Liu @ 2015-06-24 2:26 UTC (permalink / raw) To: George Dunlap, xen-devel; +Cc: Ian.Jackson, Simon Cao, wei.liu2, ian.campbell >>> On 6/23/2015 at 07:29 PM, in message <558942FF.5060702@eu.citrix.com>, George Dunlap <george.dunlap@eu.citrix.com> wrote: > On 06/23/2015 11:18 AM, Chun Yan Liu wrote: >>>>> On 6/16/2015 at 01:47 AM, in message <557F0FA7.2060402@eu.citrix.com>, George > > Dunlap <george.dunlap@eu.citrix.com> wrote: > >>> +static int libxl__device_usb_setdefault(libxl__gc *gc, uint32_t domid, > >>> + libxl_device_usb *usb, > >>> + bool update_json) > >>> +{ > >>> + char *be_path, *tmp; > >>> + > >>> + if (usb->ctrl == -1) { > >>> + int ret = libxl__device_usb_set_default_usbctrl(gc, domid, usb); > >>> + /* If no existing ctrl to host this usb device, setup a new one */ > > >>> + if (ret) { > >>> + libxl_device_usbctrl usbctrl; > >>> + libxl_device_usbctrl_init(&usbctrl); > >>> + if (libxl_device_usbctrl_add_common(CTX, domid, &usbctrl, > >>> + 0, update_json)) { > >>> + LOG(ERROR, "Failed to create usb controller"); > >>> + return ERROR_INVAL; > >>> + } > >>> + usb->ctrl = usbctrl.devid; > >>> + usb->port = 1; > >>> + libxl_device_usbctrl_dispose(&usbctrl); > >>> + } > >>> + } > >> > >> Sorry for not noticing this before -- it looks like if you set > >> usb->ctrl to -1, it will automatically choose both a controller and a > >> port number. But what if you want to specify that you want a particular > >> controller (for example, if you want to specify the PV controller rather > >> than the emulated one, or vice versa), but didn't want to have to > >> manually keep track of which ports were free? > > > > That is libxl__device_usb_set_default_usbctrl's work, it will try to find > > an available port for USB device. If there is no available port, then it > will > > create a new USB controller and by default uses its first port. > >> > >> It seems like it would be better to have the code treat port 0 as > >> "automatically choose a port for me". > > > > Here we set port=1 because port number is starting from 1. Like, if there > > are 4 ports, port number will be 1, 2, 3, 4 (not 0,1 ,2, 3). Since xend, it > > behaves like this. I think that's what pvusb driver needs. Juergen, right? > > I think you misunderstood what I was saying. > > There are three cases I think we want to consider: > > 1. The caller knows both the controller and the port number they want to > assign it to. > > 2. The caller knows what controller they want to assign it to, but they > want libxl to choose the port number automatically. > > 3. The caller wants libxl to choose both the controller and the port > automatically. > 3a. A controller already exists with a free port > 3b. No controllers with free ports exist. > > Your code handles #1 properly -- if both controller and port number are > set, it will try to add the USB device to that specific controller and > port number. > > Your code also handles #3a properly -- if the controller is not set, it > will automatically choose a controller and a port number. It also > handles #3b properly -- if there are no controllers, or if the > controllers have no ports available, then it will create a new one and > assign it to port 1. > > Your code does not, however, handle the second case -- where the user > knows they want to plug it into a specific controller (for instance, the > PVUSB one rather than the emulated one), but don't want to keep track of > which ports are available. > > Since ports start as 1, then '0' is an invalid number for a port (just > as -1 is an invalid id for a controller). I was suggesting that you > could use '0' as a magic number meaning, "Please choose a port for me." Oh, I see. Thanks for explanation. This IS what we didn't cover, currently only support either specifying both controller and port, or both not. If user specifies controller and port, then we will use that controller and port, if it's not available, we just report error, but won't choose a default available one for it. Choosing a port or creating a new controller only happens when use doesn't specify controller and port. I think case 2 is very useful. I will update code to cover. > > However, after our discussion here about providing "helpers" to > translate stuff for the libxl interface, if the other maintainers will > like the "automatically create a controller" functionality at all; or if > they would rather we (again) provide helper functions so that the > toolstack can do this work. > > >>> +static int libxl__device_usb_remove(libxl__gc *gc, uint32_t domid, > >>> + libxl_device_usb *usb) > >>> +{ > >>> + libxl_device_usb *usbs = NULL; > >>> + libxl_device_usb *usb_find = NULL; > >>> + int i, num = 0, rc; > >>> + > >>> + assert(usb->busid || (usb->hostbus > 0 && usb->hostaddr > 0)); > >>> + > >>> + if (!usb->busid) { > >>> + usb->busid = usb_busaddr_to_busid(gc, usb->hostbus, usb->hostaddr); > >>> + if (!usb->busid) { > >>> + LOG(ERROR, "USB device doesn't exist in sysfs"); > >>> + return ERROR_INVAL; > >>> + } > >>> + } > >> > >> So here you're keying the removal on the *host* idea of what the device > >> is. But the standard would be to key this on the *guest* idea of what > >> the device is. When you're doing disk removal, you don't say > >> > >> "xl block-detach 1 /images/foo.img" > >> > >> that is, the path to the disk image; you say > >> > >> "xl block-detach 1 xvda" > >> > >> that is, the image as seen from the guest. > >> > >> Since there is no devid, you should make it possible to remove by > >> <ctrl,port>. Removing also by hostbus:hostaddr seems like useful > >> functionality, so it's probably not bad to keep it; but the <ctrl,port> > >> should be the main functionality. > > > > Do you think <ctrl,port> is better? That means in qemu emulated way, > > user also need to know the <ctrl, port> info of the USB device. In the past, > > for usb-add or usb-delete, <ctrl, port> info is hidden to user, it used > > bus.addr or verndorid.deviceid. > > Hmm -- you know, you're right. For vif, vfb, and vkb it seems to use > devid (which is libxl specific, but indexed per vm); disk uses vdev > (which is indexed per vm); but pci pass-through uses BDF, which is based > on the host. (And that's what my HVM series from last year did as well.) > > BTW, to remove a device over qmp, you need the name you gave the device > when you assigned it. But at least as of a year ago, there was no way > to query qemu to see which devices you had assigned; so you have to > store that information away in xenstore somewhere anyway. So from a > qemu perspective, having a devid or guest <ctrl,port> mapping isn't a > big deal. OK. If qemu side has no problem, I'll change the interface to be <ctrl, port>. Thanks, Chunyan > > Also, from a UI perspective: it should be easy for xl to translate host > bus.addr into guest <ctrl,port>, so I don't think that's as big a deal. > > The main reason I have for wanting to do it at the guest level is so > that we can use the same interface for things which have no host handle > -- i.e., plugging or unplugging a virtual tablet, or maybe a USB disk. > > -George > > > ^ permalink raw reply [flat|nested] 88+ messages in thread
* [PATCH V4 4/7] libxl: add libxl_device_usb_assignable_list API 2015-06-10 3:20 [PATCH V4 0/7] xen pvusb toolstack work Chunyan Liu ` (2 preceding siblings ...) 2015-06-10 3:20 ` [PATCH V4 3/7] libxl: add pvusb API Chunyan Liu @ 2015-06-10 3:20 ` Chunyan Liu 2015-06-10 3:20 ` [PATCH V4 5/7] xl: add pvusb commands Chunyan Liu ` (2 subsequent siblings) 6 siblings, 0 replies; 88+ messages in thread From: Chunyan Liu @ 2015-06-10 3:20 UTC (permalink / raw) To: xen-devel; +Cc: george.dunlap, wei.liu2, Ian.Jackson, ian.campbell, Chunyan Liu Add API for listing assignable USB devices info. Assignable USB device means the USB device type is assignable and it's not assigned to any guest yet. Signed-off-by: Chunyan Liu <cyliu@suse.com> --- This could be squashed with previous patch. Split because there is some dispute on this. If this is acceptable, could be squashed, otherwise could be removed. tools/libxl/libxl.h | 3 +++ tools/libxl/libxl_pvusb.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index d192300..b65a096 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -1314,6 +1314,9 @@ int libxl_device_usbctrl_getinfo(libxl_ctx *ctx, uint32_t domid, LIBXL_EXTERNAL_CALLERS_ONLY; /* USB Devices */ +libxl_device_usb * +libxl_device_usb_assignable_list(libxl_ctx *ctx, int *num); + int libxl_device_usb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_usb *usb, const libxl_asyncop_how *ao_how) LIBXL_EXTERNAL_CALLERS_ONLY; diff --git a/tools/libxl/libxl_pvusb.c b/tools/libxl/libxl_pvusb.c index a6e1aa1..739a16d 100644 --- a/tools/libxl/libxl_pvusb.c +++ b/tools/libxl/libxl_pvusb.c @@ -555,6 +555,52 @@ static bool is_usb_assignable(libxl__gc *gc, libxl_device_usb *usb) return classcode != USBHUB_CLASS_CODE; } +libxl_device_usb * +libxl_device_usb_assignable_list(libxl_ctx *ctx, int *num) +{ + GC_INIT(ctx); + libxl_device_usb *usbs = NULL; + libxl_device_usb *assigned; + int num_assigned; + struct dirent *de; + DIR *dir; + + *num = 0; + + if (libxl__device_usb_assigned_list(gc, &assigned, &num_assigned) < 0) + goto out; + + if (!(dir = opendir(SYSFS_USB_DEV))) + goto out; + + while ((de = readdir(dir))) { + libxl_device_usb usb; + + if (!de->d_name) + continue; + + usb.busid = de->d_name; + if (!is_usb_assignable(gc, &usb)) + continue; + + if (is_usb_in_array(assigned, num_assigned, &usb)) + continue; + + usbs = libxl__realloc(NOGC, usbs, sizeof(*usbs) * (*num + 1)); + libxl_device_usb_init(usbs + *num); + usbs[*num].busid = libxl__strdup(NOGC, de->d_name); + usb_busaddr_from_busid(gc, usbs[*num].busid, + &(usbs[*num].hostbus), &(usbs[*num].hostaddr)); + (*num)++; + } + + closedir(dir); + +out: + GC_FREE; + return usbs; +} + /* get usb devices under certain usb controller */ static int libxl__device_usb_list_per_usbctrl(libxl__gc *gc, uint32_t domid, int usbctrl, -- 2.1.4 ^ permalink raw reply related [flat|nested] 88+ messages in thread
* [PATCH V4 5/7] xl: add pvusb commands 2015-06-10 3:20 [PATCH V4 0/7] xen pvusb toolstack work Chunyan Liu ` (3 preceding siblings ...) 2015-06-10 3:20 ` [PATCH V4 4/7] libxl: add libxl_device_usb_assignable_list API Chunyan Liu @ 2015-06-10 3:20 ` Chunyan Liu 2015-06-12 7:37 ` Juergen Gross 2015-06-10 3:20 ` [PATCH V4 6/7] xl: add usb-assignable-list command Chunyan Liu 2015-06-10 3:20 ` [PATCH V4 7/7] domcreate: support pvusb in configuration file Chunyan Liu 6 siblings, 1 reply; 88+ messages in thread From: Chunyan Liu @ 2015-06-10 3:20 UTC (permalink / raw) To: xen-devel Cc: wei.liu2, ian.campbell, george.dunlap, Ian.Jackson, Chunyan Liu, Simon Cao Add pvusb commands: usb-ctrl-attach, usb-ctrl-detach, usb-list, usb-attach and usb-detach. To attach a usb device to guest through pvusb, one could follow following example: #xl usb-ctrl-attach test_vm version=1 num_ports=8 #xl usb-list test_vm will show the usb controllers and port usage under the domain. #xl usb-assignable-list will list assignable USB devices #xl usb-attach test_vm 1.6 will find the first usable controller:port, and attach usb device whose bus address is 1.6 (busnum is 1, devnum is 6) to it. One could also specify which <controller> and which <port>. #xl usb-detach test_vm 1.6 #xl usb-ctrl-detach test_vm dev_id will destroy the controller with specified dev_id. Dev_id can be traced in usb-list info. Signed-off-by: Chunyan Liu <cyliu@suse.com> Signed-off-by: Simon Cao <caobosimon@gmail.com> --- docs/man/xl.pod.1 | 38 +++++++ tools/libxl/xl.h | 5 + tools/libxl/xl_cmdimpl.c | 251 ++++++++++++++++++++++++++++++++++++++++++++++ tools/libxl/xl_cmdtable.c | 25 +++++ 4 files changed, 319 insertions(+) diff --git a/docs/man/xl.pod.1 b/docs/man/xl.pod.1 index 4eb929d..0259b43 100644 --- a/docs/man/xl.pod.1 +++ b/docs/man/xl.pod.1 @@ -1387,6 +1387,44 @@ List pass-through pci devices for a domain. =back +=head1 USB PASS-THROUGH + +=over 4 + +=item B<usb-ctrl-attach> I<domain-id> [I<version=val>] [I<ports=number>] + +Create a new USB controller for the specified domain. +B<version=val> is the usb controller version, could be 1 (USB1.1) or 2 (USB2.0). +B<ports=number> is the total ports of the usb controller. +By default, it will create a USB2.0 controller with 8 ports. + +=item B<usb-ctrl-detach> I<domain-id> I<devid> + +Destroy a USB controller from the specified domain. +B<devid> is devid of the USB controller. + +=item B<usb-attach> I<domain-id> I<bus.addr> [I<controller=devid> [I<port=number>]] + +Hot-plug a new pass-through USB device to the specified domain. +B<bus.addr> is the busnum.devnum of the physical USB device to pass-through. +B<controller=devid> B<port=number> is the USB controller:port to hotplug the +USB device to. By default, it will find the first available controller:port +and use it; if there is no controller, it will create one. + +=item B<usb-detach> I<domain-id> I<bus.addr> + +Hot-unplug a previously assigned USB device from a domain. B<bus.addr> is +busnum.devnum of the physical USB device to be removed from the guest domain. + +If B<-f> is specified, B<xl> is going to forcefully remove the device even +without guest's collaboration. + +=item B<usb-list> I<domain-id> + +List pass-through usb devices for a domain. + +=back + =head1 TMEM =over 4 diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h index 5bc138c..2d57ee3 100644 --- a/tools/libxl/xl.h +++ b/tools/libxl/xl.h @@ -86,6 +86,11 @@ int main_blockdetach(int argc, char **argv); int main_vtpmattach(int argc, char **argv); int main_vtpmlist(int argc, char **argv); int main_vtpmdetach(int argc, char **argv); +int main_usbctrl_attach(int argc, char **argv); +int main_usbctrl_detach(int argc, char **argv); +int main_usbattach(int argc, char **argv); +int main_usbdetach(int argc, char **argv); +int main_usblist(int argc, char **argv); int main_uptime(int argc, char **argv); int main_claims(int argc, char **argv); int main_tmem_list(int argc, char **argv); diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index c858068..b29d0fc 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -3219,6 +3219,257 @@ int main_cd_insert(int argc, char **argv) return 0; } +static void usbinfo_print(libxl_device_usb *usbs, int num) { + int i; + if (usbs == NULL) + return; + for (i = 0; i < num; i++) { + libxl_usbinfo usbinfo; + libxl_usbinfo_init(&usbinfo); + + if (usbs[i].port) + printf(" Port %d:", usbs[i].port); + if (!libxl_device_usb_getinfo(ctx, &usbs[i], &usbinfo)) { + printf(" Bus %03x Device %03x: ID %04x:%04x %s %s\n", + usbinfo.busnum, usbinfo.devnum, + usbinfo.idVendor, usbinfo.idProduct, + usbinfo.manuf ?: "", usbinfo.prod ?: ""); + } + libxl_usbinfo_dispose(&usbinfo); + } +} + +int main_usbctrl_attach(int argc, char **argv) +{ + uint32_t domid; + int opt; + char *oparg; + libxl_device_usbctrl usbctrl; + + SWITCH_FOREACH_OPT(opt, "", NULL, "usb-ctrl-attach", 1) { + /* No options */ + } + + domid = find_domain(argv[optind++]); + + libxl_device_usbctrl_init(&usbctrl); + + while (argc > optind) { + if (MATCH_OPTION("type", argv[optind], oparg)) { + if (!strcmp(oparg, "pv")) { + usbctrl.protocol = LIBXL_USB_PROTOCOL_PV; + } else { + fprintf(stderr, "unsupported type `%s'\n", oparg); + exit(-1); + } + } else if (MATCH_OPTION("version", argv[optind], oparg)) { + usbctrl.version = atoi(oparg); + } else if (MATCH_OPTION("ports", argv[optind], oparg)) { + usbctrl.ports = atoi(oparg); + } else { + fprintf(stderr, "unrecognized argument `%s'\n", argv[optind]); + exit(-1); + } + optind++; + } + + if (usbctrl.protocol == LIBXL_USB_PROTOCOL_AUTO) + usbctrl.protocol = LIBXL_USB_PROTOCOL_PV; + + if (dryrun_only) { + char* json = libxl_device_usbctrl_to_json(ctx, &usbctrl); + printf("usb controller: %s\n", json); + free(json); + libxl_device_usbctrl_dispose(&usbctrl); + if (ferror(stdout) || fflush(stdout)) { + perror("stdout"); + exit(-1); + } + return 0; + } + + if (libxl_device_usbctrl_add(ctx, domid, &usbctrl, 0)) { + fprintf(stderr, "libxl_device_usbctrl_add failed.\n"); + exit(-1); + } + libxl_device_usbctrl_dispose(&usbctrl); + return 0; +} + +int main_usbctrl_detach(int argc, char **argv) +{ + uint32_t domid; + int opt; + libxl_device_usbctrl usbctrl; + + SWITCH_FOREACH_OPT(opt, "", NULL, "usb-ctrl-detach", 2) { + /* No options */ + } + + domid = find_domain(argv[optind]); + + libxl_device_usbctrl_init(&usbctrl); + usbctrl.devid = atoi(argv[optind+1]); + + if (libxl_device_usbctrl_remove(ctx, domid, &usbctrl, 0)) { + fprintf(stderr, "libxl_device_usbctrl_remove failed.\n"); + exit(-1); + } + libxl_device_usbctrl_dispose(&usbctrl); + return 0; + +} + +int main_usbattach(int argc, char **argv) +{ + uint32_t domid; + char *devname, *p; + int opt; + char *oparg; + libxl_device_usb usb; + + SWITCH_FOREACH_OPT(opt, "", NULL, "usb-attach", 2) { + /* No options */ + } + + libxl_device_usb_init(&usb); + + domid = find_domain(argv[optind++]); + devname = argv[optind++]; + p = strchr(devname, '.'); + if (p) { + usb.hostbus = strtoul(devname, NULL, 0); + usb.hostaddr = strtoul(p + 1, NULL, 0); + } + + if (usb.hostbus < 1 || usb.hostaddr < 1) { + fprintf(stderr, "Invalid usb device.\n"); + exit(-1); + } + + while (argc > optind) { + if (MATCH_OPTION("controller", argv[optind], oparg)) { + usb.ctrl = atoi(oparg); + } else if (MATCH_OPTION("port", argv[optind], oparg)) { + usb.port = atoi(oparg); + } else { + fprintf(stderr, "unrecognized argument `%s'\n", argv[optind]); + exit(-1); + } + optind++; + } + + if (dryrun_only) { + char *json = libxl_device_usb_to_json(ctx, &usb); + printf("usb: %s\n", json); + free(json); + libxl_device_usb_dispose(&usb); + if (ferror(stdout) || fflush(stdout)) { + perror("stdout"); + exit(-1); + } + return 0; + } + + if (libxl_device_usb_add(ctx, domid, &usb, 0)) { + fprintf(stderr, "libxl_device_usb_add failed.\n"); + exit(-1); + } + + libxl_device_usb_dispose(&usb); + return 0; +} + +int main_usbdetach(int argc, char **argv) +{ + uint32_t domid; + char *devname, *p; + int opt; + libxl_device_usb usb; + + SWITCH_FOREACH_OPT(opt, "", NULL, "usb-detach", 2) { + /* No options */ + } + + libxl_device_usb_init(&usb); + + domid = find_domain(argv[optind++]); + devname = argv[optind++]; + + if (argc > optind) { + fprintf(stderr, "Invalid arguments.\n"); + exit(-1); + } + + p = strchr(devname, '.'); + if (p) { + usb.hostbus = strtoul(devname, NULL, 0); + usb.hostaddr = strtoul(p + 1, NULL, 0); + } + + if (usb.hostbus < 1 || usb.hostaddr < 1) { + fprintf(stderr, "Invalid usb device.\n"); + exit(-1); + } + + if (libxl_device_usb_remove(ctx, domid, &usb, 0) ) { + fprintf(stderr, "libxl_device_usb_remove failed.\n"); + exit(-1); + } + libxl_device_usb_dispose(&usb); + return 0; +} + +int main_usblist(int argc, char **argv) +{ + uint32_t domid; + libxl_device_usbctrl *usbctrls; + libxl_device_usb *usbs; + libxl_usbctrlinfo usbctrlinfo; + int numctrl, numusb, i, opt; + + SWITCH_FOREACH_OPT(opt, "", NULL, "usb-list", 1) { + /* No options */ + } + + domid = find_domain(argv[optind++]); + + if (argc > optind) { + fprintf(stderr, "Invalid arguments.\n"); + exit(-1); + } + + usbctrls = libxl_device_usbctrl_list(ctx, domid, &numctrl); + if (!usbctrls) { + return 0; + } + + for (i = 0; i < numctrl; ++i) { + printf("%-6s %-6s %-3s %-5s %-7s %-5s %-30s\n", + "Devid", "Type", "BE", "state", "usb-ver", "ports", "BE-path"); + + if (!libxl_device_usbctrl_getinfo(ctx, domid, + &usbctrls[i], &usbctrlinfo)) { + printf("%-6d %-6s %-3d %-5d %-7d %-5d %-30s\n", + usbctrlinfo.devid, + libxl_usb_protocol_to_string(usbctrlinfo.protocol), + usbctrlinfo.backend_id, usbctrlinfo.state, + usbctrlinfo.version, usbctrlinfo.ports, + usbctrlinfo.backend); + + usbs = libxl_device_usb_list_per_usbctrl(ctx, domid, + usbctrlinfo.devid, &numusb); + usbinfo_print(usbs, numusb); + + libxl_usbctrlinfo_dispose(&usbctrlinfo); + } + libxl_device_usbctrl_dispose(&usbctrls[i]); + } + + free(usbctrls); + 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 7f4759b..f1c5b43 100644 --- a/tools/libxl/xl_cmdtable.c +++ b/tools/libxl/xl_cmdtable.c @@ -545,6 +545,31 @@ struct cmd_spec cmd_table[] = { "\"local_mem_bandwidth\": Show local memory bandwidth(KB/s)\n", }, #endif + { "usb-ctrl-attach", + &main_usbctrl_attach, 1, 1, + "Create a virtual USB controller for a domain", + "<Domain> [type=pv] [version=<version>] [ports=<number>]", + }, + { "usb-ctrl-detach", + &main_usbctrl_detach, 0, 1, + "Remove the virtual USB controller specified by <DevId> for a domain", + "<Domain> <DevId>", + }, + { "usb-attach", + &main_usbattach, 1, 2, + "Attach a USB device to a domain", + "<Domain> <bus.addr> [controller=<DevId> [port=<port>]]", + }, + { "usb-detach", + &main_usbdetach, 0, 1, + "Detach a USB device from a domain", + "<Domain> <bus.addr>", + }, + { "usb-list", + &main_usblist, 0, 0, + "List information about USB devices for a domain", + "<Domain>", + }, }; int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec); -- 2.1.4 ^ permalink raw reply related [flat|nested] 88+ messages in thread
* Re: [PATCH V4 5/7] xl: add pvusb commands 2015-06-10 3:20 ` [PATCH V4 5/7] xl: add pvusb commands Chunyan Liu @ 2015-06-12 7:37 ` Juergen Gross 2015-06-12 8:03 ` Chun Yan Liu 0 siblings, 1 reply; 88+ messages in thread From: Juergen Gross @ 2015-06-12 7:37 UTC (permalink / raw) To: Chunyan Liu, xen-devel Cc: george.dunlap, Ian.Jackson, Simon Cao, wei.liu2, ian.campbell On 06/10/2015 05:20 AM, Chunyan Liu wrote: > Add pvusb commands: usb-ctrl-attach, usb-ctrl-detach, usb-list, > usb-attach and usb-detach. > > To attach a usb device to guest through pvusb, one could follow > following example: > > #xl usb-ctrl-attach test_vm version=1 num_ports=8 > > #xl usb-list test_vm > will show the usb controllers and port usage under the domain. > > #xl usb-assignable-list > will list assignable USB devices xl usb-assignable-list is not part of this patch. Either merge this patch and the following one, or describe the command in the next patch. > > #xl usb-attach test_vm 1.6 > will find the first usable controller:port, and attach usb > device whose bus address is 1.6 (busnum is 1, devnum is 6) > to it. One could also specify which <controller> and which <port>. > > #xl usb-detach test_vm 1.6 > > #xl usb-ctrl-detach test_vm dev_id > will destroy the controller with specified dev_id. Dev_id > can be traced in usb-list info. > > Signed-off-by: Chunyan Liu <cyliu@suse.com> > Signed-off-by: Simon Cao <caobosimon@gmail.com> > --- > docs/man/xl.pod.1 | 38 +++++++ > tools/libxl/xl.h | 5 + > tools/libxl/xl_cmdimpl.c | 251 ++++++++++++++++++++++++++++++++++++++++++++++ > tools/libxl/xl_cmdtable.c | 25 +++++ > 4 files changed, 319 insertions(+) > ... > diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c > index c858068..b29d0fc 100644 > --- a/tools/libxl/xl_cmdimpl.c > +++ b/tools/libxl/xl_cmdimpl.c > @@ -3219,6 +3219,257 @@ int main_cd_insert(int argc, char **argv) > return 0; > } > > +static void usbinfo_print(libxl_device_usb *usbs, int num) { > + int i; Blank line missing. > + if (usbs == NULL) > + return; > + for (i = 0; i < num; i++) { > + libxl_usbinfo usbinfo; Blank line missing. > + libxl_usbinfo_init(&usbinfo); > + > + if (usbs[i].port) > + printf(" Port %d:", usbs[i].port); > + if (!libxl_device_usb_getinfo(ctx, &usbs[i], &usbinfo)) { > + printf(" Bus %03x Device %03x: ID %04x:%04x %s %s\n", > + usbinfo.busnum, usbinfo.devnum, > + usbinfo.idVendor, usbinfo.idProduct, > + usbinfo.manuf ?: "", usbinfo.prod ?: ""); Is it really possible for a device to be assigned but without a port number? I'd rather combine the two if's and printf statements. This would avoid the case where " Port 1: Port 2: ..." is printed due to a failing libxl_device_usb_getinfo() for port 1. > + } > + libxl_usbinfo_dispose(&usbinfo); > + } > +} > + > +int main_usbctrl_attach(int argc, char **argv) > +{ > + uint32_t domid; > + int opt; > + char *oparg; > + libxl_device_usbctrl usbctrl; > + > + SWITCH_FOREACH_OPT(opt, "", NULL, "usb-ctrl-attach", 1) { > + /* No options */ > + } > + > + domid = find_domain(argv[optind++]); > + > + libxl_device_usbctrl_init(&usbctrl); > + > + while (argc > optind) { > + if (MATCH_OPTION("type", argv[optind], oparg)) { > + if (!strcmp(oparg, "pv")) { > + usbctrl.protocol = LIBXL_USB_PROTOCOL_PV; > + } else { > + fprintf(stderr, "unsupported type `%s'\n", oparg); > + exit(-1); > + } > + } else if (MATCH_OPTION("version", argv[optind], oparg)) { > + usbctrl.version = atoi(oparg); Shouldn't you check for valid versions? > + } else if (MATCH_OPTION("ports", argv[optind], oparg)) { > + usbctrl.ports = atoi(oparg); Same here for number of ports. Otherwise you could blow up xenstore by e.g. specifying 2 billion ports here. > + } else { > + fprintf(stderr, "unrecognized argument `%s'\n", argv[optind]); > + exit(-1); > + } > + optind++; > + } > + > + if (usbctrl.protocol == LIBXL_USB_PROTOCOL_AUTO) > + usbctrl.protocol = LIBXL_USB_PROTOCOL_PV; Is this really necessary? You do it in libxl, too. Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 5/7] xl: add pvusb commands 2015-06-12 7:37 ` Juergen Gross @ 2015-06-12 8:03 ` Chun Yan Liu 2015-06-12 8:22 ` Juergen Gross 0 siblings, 1 reply; 88+ messages in thread From: Chun Yan Liu @ 2015-06-12 8:03 UTC (permalink / raw) To: xen-devel, Juergen Gross Cc: george.dunlap, Ian.Jackson, Simon Cao, wei.liu2, ian.campbell >>> On 6/12/2015 at 03:37 PM, in message <557A8C57.1040108@suse.com>, Juergen Gross <jgross@suse.com> wrote: > On 06/10/2015 05:20 AM, Chunyan Liu wrote: > > Add pvusb commands: usb-ctrl-attach, usb-ctrl-detach, usb-list, > > usb-attach and usb-detach. > > > > To attach a usb device to guest through pvusb, one could follow > > following example: > > > > #xl usb-ctrl-attach test_vm version=1 num_ports=8 > > > > #xl usb-list test_vm > > will show the usb controllers and port usage under the domain. > > > > #xl usb-assignable-list > > will list assignable USB devices > > xl usb-assignable-list is not part of this patch. Either merge this > patch and the following one, or describe the command in the next patch. Oh, yes, I forget to split. > > > > > #xl usb-attach test_vm 1.6 > > will find the first usable controller:port, and attach usb > > device whose bus address is 1.6 (busnum is 1, devnum is 6) > > to it. One could also specify which <controller> and which <port>. > > > > #xl usb-detach test_vm 1.6 > > > > #xl usb-ctrl-detach test_vm dev_id > > will destroy the controller with specified dev_id. Dev_id > > can be traced in usb-list info. > > > > Signed-off-by: Chunyan Liu <cyliu@suse.com> > > Signed-off-by: Simon Cao <caobosimon@gmail.com> > > --- > > docs/man/xl.pod.1 | 38 +++++++ > > tools/libxl/xl.h | 5 + > > tools/libxl/xl_cmdimpl.c | 251 > ++++++++++++++++++++++++++++++++++++++++++++++ > > tools/libxl/xl_cmdtable.c | 25 +++++ > > 4 files changed, 319 insertions(+) > > > > ... > > > diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c > > index c858068..b29d0fc 100644 > > --- a/tools/libxl/xl_cmdimpl.c > > +++ b/tools/libxl/xl_cmdimpl.c > > @@ -3219,6 +3219,257 @@ int main_cd_insert(int argc, char **argv) > > return 0; > > } > > > > +static void usbinfo_print(libxl_device_usb *usbs, int num) { > > + int i; > > Blank line missing. > > > + if (usbs == NULL) > > + return; > > + for (i = 0; i < num; i++) { > > + libxl_usbinfo usbinfo; > > Blank line missing. > > > + libxl_usbinfo_init(&usbinfo); > > + > > + if (usbs[i].port) > > + printf(" Port %d:", usbs[i].port); > > + if (!libxl_device_usb_getinfo(ctx, &usbs[i], &usbinfo)) { > > + printf(" Bus %03x Device %03x: ID %04x:%04x %s %s\n", > > + usbinfo.busnum, usbinfo.devnum, > > + usbinfo.idVendor, usbinfo.idProduct, > > + usbinfo.manuf ?: "", usbinfo.prod ?: ""); > > Is it really possible for a device to be assigned but without a port > number? For assigned usb device, it's not possible. But this function will be called in two places, one is to list assigned usb devices in 'xl usb-list'; another is to list assignable usb devices in 'xl usb-assignable-list'. If 'usb-assignable-list' is not taken, this could be improved. > > I'd rather combine the two if's and printf statements. This would avoid > the case where " Port 1: Port 2: ..." is printed due to a failing > libxl_device_usb_getinfo() for port 1. > > > + } > > + libxl_usbinfo_dispose(&usbinfo); > > + } > > +} > > + > > +int main_usbctrl_attach(int argc, char **argv) > > +{ > > + uint32_t domid; > > + int opt; > > + char *oparg; > > + libxl_device_usbctrl usbctrl; > > + > > + SWITCH_FOREACH_OPT(opt, "", NULL, "usb-ctrl-attach", 1) { > > + /* No options */ > > + } > > + > > + domid = find_domain(argv[optind++]); > > + > > + libxl_device_usbctrl_init(&usbctrl); > > + > > + while (argc > optind) { > > + if (MATCH_OPTION("type", argv[optind], oparg)) { > > + if (!strcmp(oparg, "pv")) { > > + usbctrl.protocol = LIBXL_USB_PROTOCOL_PV; > > + } else { > > + fprintf(stderr, "unsupported type `%s'\n", oparg); > > + exit(-1); > > + } > > + } else if (MATCH_OPTION("version", argv[optind], oparg)) { > > + usbctrl.version = atoi(oparg); > > Shouldn't you check for valid versions? OK. Will check. > > > + } else if (MATCH_OPTION("ports", argv[optind], oparg)) { > > + usbctrl.ports = atoi(oparg); > > Same here for number of ports. Otherwise you could blow up xenstore by > e.g. specifying 2 billion ports here. Will add check. What's the supported max ports? > > > + } else { > > + fprintf(stderr, "unrecognized argument `%s'\n", argv[optind]); > > + exit(-1); > > + } > > + optind++; > > + } > > + > > + if (usbctrl.protocol == LIBXL_USB_PROTOCOL_AUTO) > > + usbctrl.protocol = LIBXL_USB_PROTOCOL_PV; > > Is this really necessary? You do it in libxl, too. Yes, seems not necessary. Anyway (from config file or hotplug), it will call libxl_device_usbctrl_setdefault and do that. Thanks, Chunyan > > > Juergen > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel > > ^ permalink raw reply [flat|nested] 88+ messages in thread
* Re: [PATCH V4 5/7] xl: add pvusb commands 2015-06-12 8:03 ` Chun Yan Liu @ 2015-06-12 8:22 ` Juergen Gross 0 siblings, 0 replies; 88+ messages in thread From: Juergen Gross @ 2015-06-12 8:22 UTC (permalink / raw) To: Chun Yan Liu, xen-devel Cc: george.dunlap, wei.liu2, Simon Cao, Ian.Jackson, ian.campbell On 06/12/2015 10:03 AM, Chun Yan Liu wrote: > > >>>> On 6/12/2015 at 03:37 PM, in message <557A8C57.1040108@suse.com>, Juergen Gross > <jgross@suse.com> wrote: >> On 06/10/2015 05:20 AM, Chunyan Liu wrote: ... >>> + } else if (MATCH_OPTION("ports", argv[optind], oparg)) { >>> + usbctrl.ports = atoi(oparg); >> >> Same here for number of ports. Otherwise you could blow up xenstore by >> e.g. specifying 2 billion ports here. > > Will add check. What's the supported max ports? 31. I'm about to send a patch updating the pvusb interface description which will then contain a define for that (USBIF_MAX_PORTNR). Juergen ^ permalink raw reply [flat|nested] 88+ messages in thread
* [PATCH V4 6/7] xl: add usb-assignable-list command 2015-06-10 3:20 [PATCH V4 0/7] xen pvusb toolstack work Chunyan Liu ` (4 preceding siblings ...) 2015-06-10 3:20 ` [PATCH V4 5/7] xl: add pvusb commands Chunyan Liu @ 2015-06-10 3:20 ` Chunyan Liu 2015-06-10 3:20 ` [PATCH V4 7/7] domcreate: support pvusb in configuration file Chunyan Liu 6 siblings, 0 replies; 88+ messages in thread From: Chunyan Liu @ 2015-06-10 3:20 UTC (permalink / raw) To: xen-devel; +Cc: george.dunlap, wei.liu2, Ian.Jackson, ian.campbell, Chunyan Liu Add xl usb-assignable-list command to list assignable USB devices. Assignable USB device means the USB device type is assignable and it's not assigned to any guest yet. Signed-off-by: Chunyan Liu <cyliu@suse.com> --- Same as "libxl: add libxl_device_usb_assignable_list API" patch, this patch could be sqaushed to previous one. Split because of some dispute. Could be squashed if acceptable, otherwise could be removed. tools/libxl/xl.h | 1 + tools/libxl/xl_cmdimpl.c | 24 ++++++++++++++++++++++++ tools/libxl/xl_cmdtable.c | 4 ++++ 3 files changed, 29 insertions(+) diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h index 2d57ee3..f37a99f 100644 --- a/tools/libxl/xl.h +++ b/tools/libxl/xl.h @@ -86,6 +86,7 @@ int main_blockdetach(int argc, char **argv); int main_vtpmattach(int argc, char **argv); int main_vtpmlist(int argc, char **argv); int main_vtpmdetach(int argc, char **argv); +int main_usbassignable_list(int argc, char **argv); int main_usbctrl_attach(int argc, char **argv); int main_usbctrl_detach(int argc, char **argv); int main_usbattach(int argc, char **argv); diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index b29d0fc..840faca 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -3239,6 +3239,30 @@ static void usbinfo_print(libxl_device_usb *usbs, int num) { } } +static void usb_assignable_list(void) +{ + libxl_device_usb *usbs; + int num; + + usbs = libxl_device_usb_assignable_list(ctx, &num); + + usbinfo_print(usbs, num); + + free(usbs); +} + +int main_usbassignable_list(int argc, char **argv) +{ + int opt; + + SWITCH_FOREACH_OPT(opt, "", NULL, "usb-assignable-list", 0) { + /* No options */ + } + + usb_assignable_list(); + return 0; +} + int main_usbctrl_attach(int argc, char **argv) { uint32_t domid; diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c index f1c5b43..b6e8786 100644 --- a/tools/libxl/xl_cmdtable.c +++ b/tools/libxl/xl_cmdtable.c @@ -570,6 +570,10 @@ struct cmd_spec cmd_table[] = { "List information about USB devices for a domain", "<Domain>", }, + { "usb-assignable-list", + &main_usbassignable_list, 0, 0, + "List all assignable USB devices", + }, }; int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec); -- 2.1.4 ^ permalink raw reply related [flat|nested] 88+ messages in thread
* [PATCH V4 7/7] domcreate: support pvusb in configuration file 2015-06-10 3:20 [PATCH V4 0/7] xen pvusb toolstack work Chunyan Liu ` (5 preceding siblings ...) 2015-06-10 3:20 ` [PATCH V4 6/7] xl: add usb-assignable-list command Chunyan Liu @ 2015-06-10 3:20 ` Chunyan Liu 6 siblings, 0 replies; 88+ messages in thread From: Chunyan Liu @ 2015-06-10 3:20 UTC (permalink / raw) To: xen-devel Cc: wei.liu2, ian.campbell, george.dunlap, Ian.Jackson, Chunyan Liu, Simon Cao Add code to support pvusb in domain config file. One could specify usbctrl and usb in domain's configuration file and create domain, then usb controllers will be created and usb device would be attached to guest automatically. One could specify usb controllers and usb devices in config file like this: usbctrl=['version=2,ports=4', 'version=1, ports=4', ] usbdev=['2.1,controller=0,port=1', ] Signed-off-by: Chunyan Liu <cyliu@suse.com> Signed-off-by: Simon Cao <caobosimon@gmail.com> --- Changes: - add DEFINE_DEVICES_ADD(usbctrl) and adjust codes to use that. - now support type='pv' in usbctrl specification, for future qemu extension. - use "usbdev" to specify pvusb device. Keep "usb" as its original usage. - extract codes to parse_usbctrl_config and parse_usb_config as George suggests docs/man/xl.cfg.pod.5 | 75 +++++++++++++++++++++++++++++ tools/libxl/libxl_create.c | 73 ++++++++++++++++++++++++++-- tools/libxl/libxl_device.c | 2 + tools/libxl/libxl_internal.h | 4 ++ tools/libxl/xl_cmdimpl.c | 112 ++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 262 insertions(+), 4 deletions(-) diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5 index a3e0e2e..0af1802 100644 --- a/docs/man/xl.cfg.pod.5 +++ b/docs/man/xl.cfg.pod.5 @@ -655,6 +655,81 @@ assigned slave device. =back +=item B<usbctrl=[ "USBCTRL_SPEC_STRING", "USBCTRL_SPEC_STRING", ... ]> + +Specifies the USB controllers created for this guest. Each +B<USB_SPEC_STRING> has the form C<KEY=VALUE,KEY=VALUE,...> where: + +=over 4 + +=item B<KEY=VALUE> + +Possible B<KEY>s are: + +=over 4 + +=item B<type=TYPE> + +Specifies the protocol to implement USB controller, could be "pv" (indicates +PVUSB) or "qemu" (indicates QEMU emulated). Currently only "pv" is supported. + +=item B<version=VERSION> + +Specifies version of the USB controller, could be 1 (USB1.1) or 2 (USB2.0). +Default is 2 (USB2.0). + +=item B<ports=PORTS> + +Specifies port number of the USB controller. Default is 8. + +Each USB controller will have an index starting from 0. On the same +controller, each port will have an index starting from 1. + +E.g. +usbctrl=["version=1,ports=4", "version=2,ports=8",] +The first controller has: +controller index = 0, and port 1,2,3,4. +The second controller has: +controller index = 1, and port 1,2,3,4,5,6,7,8. + +=back + +=back + +=item B<usbdev=[ "USB_SPEC_STRING", "USB_SPEC_STRING", ... ]> + +Specifies the host USB devices to passthrough to this guest. Each +B<USB_SPEC_STRING> has the form C<bus.addr,KEY=VALUE,KEY=VALUE,...> where: + +=over 4 + +=item B<bus.addr> + +Identifies the busnum.devnum of the USB device from the host perspective. +This is the same scheme as used in the output of C<lsusb> for the device in +question. + +=item B<KEY=VALUE> + +Possible B<KEY>s are: + +=over 4 + +=item B<controller=CONTROLLER> + +Specifies USB controller index, to which controller the USB device is attached. + +=item B<port=PORT> + +Specifies USB port index, to which port the USB device is attached. B<port=PORT> +is valid only when B<controller=CONTROLLER> is specified. Without +B<controller=CONTROLLER>, it will find the first available USB controller:port +and use it. If there is no controller at all, it will create one. + +=back + +=back + =item B<pci=[ "PCI_SPEC_STRING", "PCI_SPEC_STRING", ... ]> Specifies the host PCI devices to passthrough to this guest. Each B<PCI_SPEC_STRING> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index 86384d2..f10bb7e 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -771,6 +771,10 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *aodevs, static void domcreate_attach_vtpms(libxl__egc *egc, libxl__multidev *multidev, int ret); +static void domcreate_attach_usbctrls(libxl__egc *egc, libxl__multidev *multidev, + int ret); +static void domcreate_attach_usbs(libxl__egc *egc, libxl__multidev *multidev, + int ret); static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *aodevs, int ret); static void domcreate_attach_dtdev(libxl__egc *egc, @@ -1418,13 +1422,13 @@ static void domcreate_attach_vtpms(libxl__egc *egc, if (d_config->num_vtpms > 0) { /* Attach vtpms */ libxl__multidev_begin(ao, &dcs->multidev); - dcs->multidev.callback = domcreate_attach_pci; + dcs->multidev.callback = domcreate_attach_usbctrls; libxl__add_vtpms(egc, ao, domid, d_config, &dcs->multidev); libxl__multidev_prepared(egc, &dcs->multidev, 0); return; } - domcreate_attach_pci(egc, multidev, 0); + domcreate_attach_usbctrls(egc, multidev, 0); return; error_out: @@ -1432,6 +1436,69 @@ error_out: domcreate_complete(egc, dcs, ret); } +static void domcreate_attach_usbctrls(libxl__egc *egc, libxl__multidev *multidev, + int ret) +{ + libxl__domain_create_state *dcs = CONTAINER_OF(multidev, *dcs, multidev); + STATE_AO_GC(dcs->ao); + int domid = dcs->guest_domid; + + libxl_domain_config *const d_config = dcs->guest_config; + + if (ret) { + LOG(ERROR, "unable to add vtpm devices"); + goto error_out; + } + + if (d_config->num_usbctrls > 0) { + /* Attach usbctrls */ + libxl__multidev_begin(ao, &dcs->multidev); + dcs->multidev.callback = domcreate_attach_usbs; + libxl__add_usbctrls(egc, ao, domid, d_config, &dcs->multidev); + libxl__multidev_prepared(egc, &dcs->multidev, 0); + return; + } + + domcreate_attach_usbs(egc, multidev, 0); + return; + +error_out: + assert(ret); + domcreate_complete(egc, dcs, ret); +} + + +static void domcreate_attach_usbs(libxl__egc *egc, libxl__multidev *multidev, + int ret) +{ + libxl__domain_create_state *dcs = CONTAINER_OF(multidev, *dcs, multidev); + STATE_AO_GC(dcs->ao); + int i; + int domid = dcs->guest_domid; + + libxl_domain_config *const d_config = dcs->guest_config; + + if (ret) { + LOG(ERROR, "unable to add usbctrl devices"); + goto error_out; + } + + for (i = 0; i < d_config->num_usbs; i++) { + ret = libxl__device_usb_add(gc, domid, &d_config->usbs[i], 0); + if (ret < 0) { + LOG(ERROR, "libxl__device_usb_add failed: %d", ret); + goto error_out; + } + } + + domcreate_attach_pci(egc, multidev, 0); + return; + +error_out: + assert(ret); + domcreate_complete(egc, dcs, ret); +} + static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *multidev, int ret) { @@ -1445,7 +1512,7 @@ static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *multidev, libxl_domain_config *const d_config = dcs->guest_config; if (ret) { - LOG(ERROR, "unable to add vtpm devices"); + LOG(ERROR, "unable to add usb devices"); goto error_out; } diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index 93bb41e..7bca841 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -544,6 +544,7 @@ void libxl__multidev_prepared(libxl__egc *egc, * libxl__add_disks * libxl__add_nics * libxl__add_vtpms + * libxl__add_usbctrls */ #define DEFINE_DEVICES_ADD(type) \ @@ -563,6 +564,7 @@ void libxl__multidev_prepared(libxl__egc *egc, DEFINE_DEVICES_ADD(disk) DEFINE_DEVICES_ADD(nic) DEFINE_DEVICES_ADD(vtpm) +DEFINE_DEVICES_ADD(usbctrl) #undef DEFINE_DEVICES_ADD diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 89a9f07..465aaaa 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -3076,6 +3076,10 @@ _hidden void libxl__add_vtpms(libxl__egc *egc, libxl__ao *ao, uint32_t domid, libxl_domain_config *d_config, libxl__multidev *multidev); +_hidden void libxl__add_usbctrls(libxl__egc *egc, libxl__ao *ao, + uint32_t domid, libxl_domain_config *d_config, + libxl__multidev *multidev); + /*----- device model creation -----*/ /* First layer; wraps libxl__spawn_spawn. */ diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index 840faca..1ff48a2 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -1160,6 +1160,79 @@ static void parse_vnuma_config(const XLU_Config *config, free(vcpu_range_parsed); } +static void parse_usbctrl_config(libxl_device_usbctrl *usbctrl, + const char * buf) +{ + char *buf2 = strdup(buf); + char *p, *p2; + + p = strtok(buf2, ","); + if (!p) + goto out; + do { + while (*p == ' ') + p++; + if ((p2 = strchr(p, '=')) == NULL) + break; + *p2 = '\0'; + if (!strcmp(p, "type")) { + if (!strcmp(p2 + 1, "pv")) { + usbctrl->protocol = LIBXL_USB_PROTOCOL_PV; + } else { + fprintf(stderr, + "Unsupported USB controller type '%s'\n", + p2 + 1); + exit(1); + } + } else if (!strcmp(p, "version")){ + usbctrl->version = atoi(p2 + 1); + } else if (!strcmp(p, "ports")){ + usbctrl->ports = atoi(p2 + 1); + } else { + fprintf(stderr, "Unknown string `%s' in usb spec\n", p); + exit(1); + } + } while ((p = strtok(NULL, ",")) != NULL); + +out: + free(buf2); +} + +static void parse_usb_config(libxl_device_usb *usb, const char *buf) +{ + char *buf2 = strdup(buf); + char *p, *p2; + + p = strtok(buf2, ","); + if (!p) + goto out; + do { + while(*p == ' ') + ++p; + if ((p2 = strchr(p, '=')) == NULL) { + char *busaddr = p; + p = strchr(busaddr, '.'); + if (p) { + usb->hostbus = strtoul(busaddr, NULL, 0); + usb->hostaddr = strtoul(p + 1, NULL, 0); + } + continue; + } + *p2 = '\0'; + if (!strcmp(p, "controller")) { + usb->ctrl = atoi(p2 + 1); + } else if (!strcmp(p, "port")) { + usb->port = atoi(p2 + 1); + } else { + fprintf(stderr, "Unknown string `%s' in usb spec\n", p); + exit(1); + } + } while ((p = strtok(NULL, ",")) != NULL); + +out: + free(buf2); +} + static void parse_config_data(const char *config_source, const char *config_data, int config_len, @@ -1168,7 +1241,8 @@ static void parse_config_data(const char *config_source, const char *buf; long l, vcpus = 0; XLU_Config *config; - XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms; + XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms, + *usbctrls, *usbs; XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs; int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian; int pci_power_mgmt = 0; @@ -1961,6 +2035,42 @@ skip_vfb: } } + if (!xlu_cfg_get_list (config, "usbctrl", &usbctrls, 0, 0) ) { + d_config->num_usbctrls = 0; + d_config->usbctrls = NULL; + while ((buf = xlu_cfg_get_listitem (usbctrls, d_config->num_usbctrls)) + != NULL) { + libxl_device_usbctrl *usbctrl; + + d_config->usbctrls = + (libxl_device_usbctrl *) realloc(d_config->usbctrls, + sizeof (libxl_device_usbctrl) * (d_config->num_usbctrls + 1)); + usbctrl = d_config->usbctrls + d_config->num_usbctrls; + libxl_device_usbctrl_init(usbctrl); + + parse_usbctrl_config(usbctrl, buf); + + d_config->num_usbctrls++; + } + } + + if (!xlu_cfg_get_list (config, "usbdev", &usbs, 0, 0) ) { + d_config->num_usbs = 0; + d_config->usbs = NULL; + while ((buf = xlu_cfg_get_listitem (usbs, d_config->num_usbs)) != NULL) { + libxl_device_usb *usb; + + d_config->usbs = (libxl_device_usb *) realloc(d_config->usbs, + sizeof (libxl_device_usb) * (d_config->num_usbs+1)); + usb = d_config->usbs + d_config->num_usbs; + libxl_device_usb_init(usb); + + parse_usb_config(usb, buf); + + d_config->num_usbs++; + } + } + switch (xlu_cfg_get_list(config, "cpuid", &cpuids, 0, 1)) { case 0: { -- 2.1.4 ^ permalink raw reply related [flat|nested] 88+ messages in thread
end of thread, other threads:[~2015-06-24 2:26 UTC | newest] Thread overview: 88+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-06-10 3:20 [PATCH V4 0/7] xen pvusb toolstack work Chunyan Liu 2015-06-10 3:20 ` [PATCH V4 1/7] libxl: export some functions for pvusb use Chunyan Liu 2015-06-11 16:08 ` Ian Jackson 2015-06-11 16:28 ` Wei Liu 2015-06-12 15:14 ` Ian Jackson 2015-06-10 3:20 ` [PATCH V4 2/7] libxl_read_file_contents: add new entry to read sysfs file Chunyan Liu 2015-06-11 16:16 ` Ian Jackson 2015-06-12 7:00 ` Chun Yan Liu 2015-06-12 15:11 ` Ian Jackson 2015-06-10 3:20 ` [PATCH V4 3/7] libxl: add pvusb API Chunyan Liu 2015-06-11 15:00 ` Juergen Gross 2015-06-11 16:07 ` Ian Jackson 2015-06-11 16:42 ` Ian Jackson 2015-06-12 7:39 ` Chun Yan Liu 2015-06-12 8:06 ` Chun Yan Liu 2015-06-12 11:22 ` Ian Jackson 2015-06-15 14:17 ` George Dunlap 2015-06-15 14:25 ` Jürgen Groß 2015-06-15 14:34 ` George Dunlap 2015-06-15 18:26 ` Juergen Gross 2015-06-16 10:30 ` George Dunlap 2015-06-16 10:51 ` Juergen Gross 2015-06-16 11:11 ` George Dunlap 2015-06-16 11:19 ` Juergen Gross 2015-06-16 11:23 ` George Dunlap 2015-06-16 11:44 ` Ian Jackson 2015-06-17 11:24 ` Ian Campbell 2015-06-18 11:50 ` George Dunlap 2015-06-18 12:08 ` George Dunlap 2015-06-18 13:03 ` Juergen Gross 2015-06-22 13:29 ` Proposed plan for libxl USB interface (was Re: [PATCH V4 3/7] libxl: add pvusb API) George Dunlap 2015-06-22 14:14 ` Juergen Gross 2015-06-22 14:22 ` Ian Jackson 2015-06-23 2:42 ` Chun Yan Liu 2015-06-23 2:43 ` Chun Yan Liu 2015-06-23 2:44 ` Chun Yan Liu 2015-06-16 10:41 ` [PATCH V4 3/7] libxl: add pvusb API Ian Jackson 2015-06-16 10:56 ` Jürgen Groß 2015-06-16 11:03 ` George Dunlap 2015-06-16 11:10 ` Ian Jackson 2015-06-16 11:25 ` Juergen Gross 2015-06-16 11:45 ` George Dunlap 2015-06-16 12:02 ` Ian Jackson 2015-06-16 13:19 ` George Dunlap 2015-06-16 13:32 ` Juergen Gross 2015-06-16 13:37 ` [PATCH V4 3/7] libxl: add pvusb API [and 1 more messages] Ian Jackson 2015-06-16 14:41 ` George Dunlap 2015-06-16 15:58 ` Sander Eikelenboom 2015-06-16 15:59 ` Ian Jackson 2015-06-16 16:34 ` George Dunlap 2015-06-17 3:59 ` Juergen Gross 2015-06-17 10:27 ` George Dunlap 2015-06-18 6:24 ` Chun Yan Liu 2015-06-16 11:45 ` [PATCH V4 3/7] libxl: add pvusb API Ian Jackson 2015-06-16 13:06 ` Juergen Gross 2015-06-16 13:09 ` George Dunlap 2015-06-16 13:23 ` Juergen Gross 2015-06-16 13:29 ` George Dunlap 2015-06-16 13:49 ` Juergen Gross 2015-06-16 14:06 ` George Dunlap 2015-06-16 14:20 ` Juergen Gross 2015-06-16 14:37 ` George Dunlap 2015-06-17 11:34 ` Ian Campbell 2015-06-17 11:40 ` Juergen Gross 2015-06-18 6:20 ` Chun Yan Liu 2015-06-18 7:02 ` Juergen Gross 2015-06-18 8:50 ` Ian Campbell 2015-06-18 13:02 ` Juergen Gross 2015-06-16 15:38 ` George Dunlap 2015-06-16 11:01 ` George Dunlap 2015-06-16 11:12 ` Ian Jackson 2015-06-16 11:21 ` George Dunlap 2015-06-16 16:32 ` Ian Jackson 2015-06-16 16:39 ` George Dunlap 2015-06-16 16:51 ` Ross Philipson 2015-06-17 4:03 ` Jürgen Groß 2015-06-17 13:48 ` Ross Philipson 2015-06-15 17:47 ` George Dunlap 2015-06-23 10:18 ` Chun Yan Liu 2015-06-23 11:29 ` George Dunlap 2015-06-24 2:26 ` Chun Yan Liu 2015-06-10 3:20 ` [PATCH V4 4/7] libxl: add libxl_device_usb_assignable_list API Chunyan Liu 2015-06-10 3:20 ` [PATCH V4 5/7] xl: add pvusb commands Chunyan Liu 2015-06-12 7:37 ` Juergen Gross 2015-06-12 8:03 ` Chun Yan Liu 2015-06-12 8:22 ` Juergen Gross 2015-06-10 3:20 ` [PATCH V4 6/7] xl: add usb-assignable-list command Chunyan Liu 2015-06-10 3:20 ` [PATCH V4 7/7] domcreate: support pvusb in configuration file Chunyan Liu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).