From 92a4725d9f669cbd63ec19d85424f47fa4eb96b6 Mon Sep 17 00:00:00 2001 From: George Dunlap Date: Tue, 10 Nov 2015 17:22:39 +0000 Subject: [PATCH] tools: Don't use usb hostbus and hostaddr during removal The busid is already stored at a xenstore location we can find with . Read this value before removing the entry; then use it to re-assign the host device back to the original drivers. Change usb_get_all_interfaces() to take busid, rather than looking for it itself. In the remove case, use the busid value we got from the backend; in the add() case, just reorder the calls so that busaddr_to_busid happens first. (This actually avoids a duplicate busaddr_to_busid conversion in the add case.) Signed-off-by: George Dunlap --- tools/libxl/libxl_pvusb.c | 57 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/tools/libxl/libxl_pvusb.c b/tools/libxl/libxl_pvusb.c index ab57371..ead3e50 100644 --- a/tools/libxl/libxl_pvusb.c +++ b/tools/libxl/libxl_pvusb.c @@ -971,6 +971,15 @@ static int libxl__device_usb_remove_xenstore(libxl__gc *gc, uint32_t domid, return 0; } +static char * usbback_busid_from_ctrlport(libxl__gc *gc, uint32_t domid, + libxl_device_usb *usb) +{ + return libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/backend/vusb/%d/%d/port/%d", + libxl__xs_get_dompath(gc, LIBXL_TOOLSTACK_DOMID), + domid, usb->ctrl, usb->port)); +} + /* bind/unbind usb device interface */ static int unbind_usb_intf(libxl__gc *gc, char *intf, char **drvpath) { @@ -1044,25 +1053,17 @@ static int usb_intf_is_assigned(libxl__gc *gc, char *intf) return -1; } -static int usb_get_all_interfaces(libxl__gc *gc, libxl_device_usb *usb, +static int usb_get_all_interfaces(libxl__gc *gc, char *busid, char ***intfs, int *num) { DIR *dir; struct dirent *entry; char *buf; - char *busid; int rc; *intfs = NULL; *num = 0; - busid = usb_busaddr_to_busid(gc, usb->u.hostdev.hostbus, - usb->u.hostdev.hostaddr); - if (!busid) { - rc = ERROR_FAIL; - goto out; - } - buf = GCSPRINTF("%s:", busid); if (!(dir = opendir(SYSFS_USB_DEV))) { @@ -1114,20 +1115,17 @@ static char *usb_interface_xenstore_encode(char *busid) * If there are many interfaces under USB device, check each interface, * unbind from "usbback" driver and rebind to its original driver. */ -static int usbback_dev_unassign(libxl__gc *gc, libxl_device_usb *usb) +static int usbback_dev_unassign(libxl__gc *gc, char *busid) { char **intfs = NULL; char *path; int num = 0, i; int rc; - char *busid; char *usb_encode = NULL; - if (usb_get_all_interfaces(gc, usb, &intfs, &num) < 0) + if (usb_get_all_interfaces(gc, busid, &intfs, &num) < 0) return ERROR_FAIL; - busid = usb_busaddr_to_busid(gc, usb->u.hostdev.hostbus, - usb->u.hostdev.hostaddr); usb_encode = usb_interface_xenstore_encode(busid); for (i = 0; i < num; i++) { @@ -1174,11 +1172,15 @@ static int usbback_dev_assign(libxl__gc *gc, libxl_device_usb *usb) char *busid; char *usb_encode = NULL; - if (usb_get_all_interfaces(gc, usb, &intfs, &num) < 0) - return ERROR_FAIL; - busid = usb_busaddr_to_busid(gc, usb->u.hostdev.hostbus, usb->u.hostdev.hostaddr); + + if (!busid) + return ERROR_FAIL; + + if (usb_get_all_interfaces(gc, busid, &intfs, &num) < 0) + return ERROR_FAIL; + usb_encode = usb_interface_xenstore_encode(busid); for (i = 0; i < num; i++) { @@ -1200,9 +1202,8 @@ static int usbback_dev_assign(libxl__gc *gc, libxl_device_usb *usb) /* 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); - } + if (libxl__xs_write_checked(gc, XBT_NULL, path, drvpath) < 0) + goto out_rebind; } /* bind interface to usbback */ @@ -1220,7 +1221,7 @@ out_rebind: /* some interfaces might be bound to usbback, unbind it then and * rebind to its original driver */ - usbback_dev_unassign(gc, usb); + usbback_dev_unassign(gc, busid); out: free(usb_encode); return rc; @@ -1376,6 +1377,7 @@ static int do_usb_remove(libxl__gc *gc, uint32_t domid, libxl_usbctrlinfo usbctrlinfo; libxl_device_usbctrl usbctrl; int rc; + char *busid; libxl_device_usbctrl_init(&usbctrl); libxl_usbctrlinfo_init(&usbctrlinfo); @@ -1395,10 +1397,14 @@ static int do_usb_remove(libxl__gc *gc, uint32_t domid, LOG(ERROR, "Not supported"); break; case LIBXL_USBCTRL_TYPE_PV: + busid = usbback_busid_from_ctrlport(gc, domid, usbdev); + + if (!busid) goto out; + rc = libxl__device_usb_remove_xenstore(gc, domid, usbdev); if (rc) goto out; - usbback_dev_unassign(gc, usbdev); + usbback_dev_unassign(gc, busid); break; default: rc = ERROR_FAIL; @@ -1432,13 +1438,6 @@ static int libxl__device_usb_remove(libxl__gc *gc, uint32_t domid, goto out; } - if (usb->devtype == LIBXL_USBDEV_TYPE_HOSTDEV && - (usb->u.hostdev.hostbus < 1 || usb->u.hostdev.hostaddr < 1)) { - LOG(ERROR, "Invalid USB device of hostdev"); - rc = ERROR_FAIL; - goto out; - } - /* Do the remove */ rc = do_usb_remove(gc, domid, usb); -- 2.1.4