Lincoln Turner
2006-Apr-20 12:58 UTC
[Nut-upsdev] Fun and games with newhidups, udev rules and permissions
Thought I would write some notes about how I got an APC BackUPS XS 1500 working with newhidups under Gentoo 2006.0. The specific issue here is the permissions on the device files used that libusb uses to access the USB hardware. I followed Peter Selinger's instructions at http://www.mscs.dal.ca/~selinger/ups/backups.html on getting newhidups going with an APC device. The sticking point for me was setting these permissions. Basically, I could run newhidups -DD -u root /dev/whatever (when I say 'whatever', I mean it - newhidups doesn't seem to care) and see all the variables from the UPS scroll up the screen. But running without the '-u root' results in: [snip] Bus: 004 Trying to match device Device matches failed to claim USB device, trying 2 more time(s)... detaching kernel driver from USB device... failed to detach kernel driver from USB device... trying again to claim USB device... failed to claim USB device, trying 1 more time(s)... detaching kernel driver from USB device... failed to detach kernel driver from USB device... trying again to claim USB device... failed to claim USB device, trying 0 more time(s)... detaching kernel driver from USB device... failed to detach kernel driver from USB device... trying again to claim USB device... Unable to get HID descriptor (error sending control message: Operation not permitted) Doing a manual chgrp ups /proc/bus/usb/002/002 allows newhidups to work without '-u root'. But the chgrp setting unsurprisingly evaporates on reboot. The older hotplug systems seem to work by re-chowning/chmoding things in /proc/bus/usb, but I don't have this apparatus on my system. Peter's instructions cover the older 'hotplug' method of handling permissions. The hardware abstraction seems to have changed quite rapidly in recent kernels, and as of 2.6.15 I believe that /proc/bus/usb is obsolete and the recommended method of setting permissions on USB devices is with udev rules. Also, recent udev rule sets implement a replica of /proc/bus/usb under /dev/bus/usb - although the former is handled by 'usbfs' and the latter by a single elaborate (and rather hackish) rule in /etc/udev/rules.d (or wherever your distro stores your udev rules). It _seems_ that the two bus/usb heirarchies are equivalent as far as libusb is concerned. Gentoo and probably other systems will implement both heirarchies as a transitional step. It also seems that recent versions of libusb (and I have read conflicting reports on when this was implemented) are capable of looking at either /dev/bus/usb or /proc/bus/usb. So the first step is getting udev to set the appropriate ownership in /dev/bus/usb, and the second step is getting libusb (and ergo newhidups) to recognise /dev/bus/usb. To get ownership and permissions set correctly in /dev/bus/usb, I added a file named 60-nut-usbups.rules to my /etc/udev/rules.d directory. It contains the two lines: BUS=="usb", SYSFS{idVendor}=="051d", SYSFS{idProduct}=="0002", \ ACTION=="add", NAME="%k", GROUP="ups", MODE="0660" SUBSYSTEM=="usb_device", SYSFS{idVendor}=="051d", \ SYSFS{idProduct}=="0002", ACTION=="add", GROUP="ups", MODE="0660" The first matches an APC ups (051d/0002) and then creates a default-named hiddev device, which appears on my system as /dev/hiddev0. It sets the permissions root:ups 0660. Although this device appears as expected as a char device with maj,min = 180,96, it seems that newhidups takes no notice of this. Running newhidups -DD /dev/hiddev0 proceeds to scan the USB as always and fails as above. The second line somehow manages to interact with the dev/bus/usb-populating rule (on my system in 50-udev.rules) to get the permissions set on the appropriate file, in my case /dev/bus/usb/002/002. Running newhidups still doesn't work at this point, as it is still looking by default at /proc/bus/usb. I've read that libusb-0.1.12 will search /dev/bus/usb first then /proc/bus/usb. But it's not in gentoo's portage yet so I haven't tried it. I have libusb-0.1.11, and it appears that if I do an export USB_DEVFS_PATH=/dev/bus/usb then I can run newhidups -DD /dev/whatever and get a successful spew of all the UPS variables. So this seems to work, although I'm not quite sure how I got there. Any advice on udev rule improvements would be very welcome. Also, it appears odd that newhidups insists on scanning the bus nomatter what is fed to it as the mandatory command-line device filename. Finally, a disclaimer - I only just got this going. I thought I had the bugs out last night, but they all came back after a reboot. I've rebooted, restarted udev with udevstart, unplugged and replugged the UPS into different USB ports etc. And it still seems to be OK. But no guarantees I'm not missing something here! Hope this might be useful to someone. Lincoln
Lincoln Turner
2006-Apr-20 15:00 UTC
[Nut-upsdev] Fun and games with newhidups, udev rules and permissions
Thought I would write some notes about how I got an APC BackUPS XS 1500 working with newhidups under Gentoo 2006.0. The specific issue here is the permissions on the device files used that libusb uses to access the USB hardware. I followed Peter Selinger's instructions at http://www.mscs.dal.ca/~selinger/ups/backups.html on getting newhidups going with an APC device. The sticking point for me was setting these permissions. Basically, I could run newhidups -DD -u root /dev/whatever (when I say 'whatever', I mean it - newhidups doesn't seem to care) and see all the variables from the UPS scroll up the screen. But running without the '-u root' results in: [snip] Bus: 004 Trying to match device Device matches failed to claim USB device, trying 2 more time(s)... detaching kernel driver from USB device... failed to detach kernel driver from USB device... trying again to claim USB device... failed to claim USB device, trying 1 more time(s)... detaching kernel driver from USB device... failed to detach kernel driver from USB device... trying again to claim USB device... failed to claim USB device, trying 0 more time(s)... detaching kernel driver from USB device... failed to detach kernel driver from USB device... trying again to claim USB device... Unable to get HID descriptor (error sending control message: Operation not permitted) Doing a manual chgrp ups /proc/bus/usb/002/002 allows newhidups to work without '-u root'. But the chgrp setting unsurprisingly evaporates on reboot. The older hotplug systems seem to work by re-chowning/chmoding things in /proc/bus/usb, but I don't have this apparatus on my system. Peter's instructions cover the older 'hotplug' method of handling permissions. The hardware abstraction seems to have changed quite rapidly in recent kernels, and as of 2.6.15 I believe that /proc/bus/usb is obsolete and the recommended method of setting permissions on USB devices is with udev rules. Also, recent udev rule sets implement a replica of /proc/bus/usb under /dev/bus/usb - although the former is handled by 'usbfs' and the latter by a single elaborate (and rather hackish) rule in /etc/udev/rules.d (or wherever your distro stores your udev rules). It _seems_ that the two bus/usb heirarchies are equivalent as far as libusb is concerned. Gentoo and probably other systems will implement both heirarchies as a transitional step. It also seems that recent versions of libusb (and I have read conflicting reports on when this was implemented) are capable of looking at either /dev/bus/usb or /proc/bus/usb. So the first step is getting udev to set the appropriate ownership in /dev/bus/usb, and the second step is getting libusb (and ergo newhidups) to recognise /dev/bus/usb. To get ownership and permissions set correctly in /dev/bus/usb, I added a file named 60-nut-usbups.rules to my /etc/udev/rules.d directory. It contains the two lines: BUS=="usb", SYSFS{idVendor}=="051d", SYSFS{idProduct}=="0002", \ ACTION=="add", NAME="%k", GROUP="ups", MODE="0660" SUBSYSTEM=="usb_device", SYSFS{idVendor}=="051d", \ SYSFS{idProduct}=="0002", ACTION=="add", GROUP="ups", MODE="0660" The first matches an APC ups (051d/0002) and then creates a default-named hiddev device, which appears on my system as /dev/hiddev0. It sets the permissions root:ups 0660. Although this device appears as expected as a char device with maj,min = 180,96, it seems that newhidups takes no notice of this. Running newhidups -DD /dev/hiddev0 proceeds to scan the USB as always and fails as above. The second line somehow manages to interact with the dev/bus/usb-populating rule (on my system in 50-udev.rules) to get the permissions set on the appropriate file, in my case /dev/bus/usb/002/002. Running newhidups still doesn't work at this point, as it is still looking by default at /proc/bus/usb. I've read that libusb-0.1.12 will search /dev/bus/usb first then /proc/bus/usb. But it's not in gentoo's portage yet so I haven't tried it. I have libusb-0.1.11, and it appears that if I do an export USB_DEVFS_PATH=/dev/bus/usb then I can run newhidups -DD /dev/whatever and get a successful spew of all the UPS variables. So this seems to work, although I'm not quite sure how I got there. Any advice on udev rule improvements would be very welcome. Also, it appears odd that newhidups insists on scanning the bus nomatter what is fed to it as the mandatory command-line device filename. Finally, a disclaimer - I only just got this going. I thought I had the bugs out last night, but they all came back after a reboot. I've rebooted, restarted udev with udevstart, unplugged and replugged the UPS into different USB ports etc. And it still seems to be OK. But no guarantees I'm not missing something here! Hope this might be useful to someone. Lincoln