networkupstools / nut

The Network UPS Tools repository. UPS management protocol Informational RFC 9271 published by IETF at https://www.rfc-editor.org/info/rfc9271 Please star NUT on GitHub, this helps with sponsorships!
https://networkupstools.org/
Other
1.99k stars 349 forks source link

Duplicate USB devices don't connect in 2.8.0 #1414

Open ProjectInitiative opened 2 years ago

ProjectInitiative commented 2 years ago

OS: Fresh installed raspberry pi OS 64 bit NAME="Debian GNU/Linux" VERSION_ID="11" VERSION="11 (bullseye)" VERSION_CODENAME=bullseye

Build commands used

Built from source with provided instructions. All commands used below:

sudo apt-get install -y make g++ gcc build-essential autoconf gettext m4 libtool libudev-dev automake pkg-config libusb-0.1-4 libusb-1.0-0-dev libsnmp-dev libgd-dev

groupadd nut
useradd -ms /bin/bash ups
usermod -aG nut ups
usermod -aG nut root

mkdir -p /var/run/nut
chown root:nut /var/run/nut
mkdir -p /var/state/ups
chown root:nut /var/state/ups
chmod 0770 /var/state/ups

git clone https://github.com/networkupstools/nut.git
/nut
./autogen.sh
./configure --with-user=ups --with-group=nut --with-usb --with-snmp --with-cgi
make -j $(nproc)
make install

nut-scanner output

sudo /usr/local/ups/bin/nut-scanner
Scanning USB bus.
No start IP, skipping SNMP
No start IP, skipping NUT bus (old connect method)
[nutdev1]
        driver = "usbhid-ups"
        port = "auto"
        vendorid = "0764"
        productid = "0601"
        product = "OR1500LCDRM1U"
        vendor = "CPS"
        bus = "001"
[nutdev2]
        driver = "usbhid-ups"
        port = "auto"
        vendorid = "0764"
        productid = "0601"
        product = "OR1500LCDRM1U"
        vendor = "CPS"
        bus = "001"

Adding this info to /usr/local/ups/etc/ups.conf and running sudo /usr/local/ups/sbin/upsdrvctl -u root start worked in previous versions, connected to both devices.

Presently upsdrvctl returns the following:

Network UPS Tools - UPS driver controller 2.8.0-18-gaaa72bebd
Network UPS Tools - Generic HID driver 0.47 (2.8.0-18-gaaa72bebd)
USB communication driver (libusb 1.0) 0.43
Using subdriver: CyberPower HID 0.6
Network UPS Tools - Generic HID driver 0.47 (2.8.0-18-gaaa72bebd)
USB communication driver (libusb 1.0) 0.43
Can't claim USB device [0764:0601]@0/0: Entity not found
Driver failed to start (exit status=1)

NOTE: only having one UPS plugged in works just fine, the problem only comes up when 2 or more are connected.

ProjectInitiative commented 2 years ago

I would like to also note that I have tried this in a x86 installation of Debian as well. Same behavior.

jimklimov commented 2 years ago

Can some other metadata be unique to the device? Serial number? (there are also issues about trying to monitor several devices without unique serials)

I think it boils down to libusb giving us a set of device descriptors (AFAIK no devfs path there, so "port" value is ignored), and a driver picking one and binding to it. So if you find a way to specify how one of otherwise identical devices is different from another - great!

Note that connection path details should not be "it" (at worst as non-recommended fallback), to allow re-enumeration of buses and re-plugging of cables.

On Wed, May 4, 2022, 17:41 Kyle Petryszak @.***> wrote:

I would like to also note that I have tried this in a x86 installation of Debian as well. Same behavior.

— Reply to this email directly, view it on GitHub https://github.com/networkupstools/nut/issues/1414#issuecomment-1117507038, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMPTFAR3CNQUSBDERNF663VIKLENANCNFSM5VCMDHZA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

ProjectInitiative commented 2 years ago

So I went down the rabbit hole a bit. There are no unique identifying bits of meta data for these two devices (the ups does not return a serial number).

I have found two ways to differentiate the two: using the devnum outputted by lsusb, or by the physical bus port.

Making the problem worse: the upses (cyberpower) constantly disconnect and reconnect themselves until a driver binds to them. Therefore the devnum gets increased frequently.

I wrote a python script to read /sys/bus/usb/devices/1-1.1/devnum for instance, and add that to ups.conf as "device=000", and restart the driver's if the cables were ever unplugged or the kernel re-numbered things.

The problem is, the "device=000" parameter seems to be ignored by upsdrvctl and usbhid-ups.

ProjectInitiative commented 2 years ago

I was poking through the code, and trying to figure out where to add a new ups.conf parameter to use a dev path or bus port to the usbhid-ups driver.

jimklimov commented 2 years ago

Regarding regular disconnects, that rings a bell. Please trawl issues (possibly closed, maybe labeled for Cyberpower/CPS), I read that somewhere. Could be on a distro site recommendations on NUT though (maybe Arch Linux then, they had a useful troubleshooting page).

...read /sys/bus/usb/devices/1-1.1/devnum for instance, and add that to ups.conf as "device=000"

Is something similar achievable with libusb API? Looking into these paths is very systems-dependent and the world is not only Linux :\ Not saying '"no" outright, on platforms that can detect the value in some manner it can be useful, and others would have a blank and ignore.

As for driver code, look for "vendorid" as it is a criterion for all usb driver matchers; then for other fields it varies.

I raised an issue recently to compare nutdrv_qx matcher with usbhid-ups one, they seem to be advanced in different ways so could be a good idea to reconcile the approaches or even refactor them out to e.g. usb-common.c/.h code for all drivers to use the same featured matcher eventually.

Also some part of equation could be in libusb0.c and libusb1.c with API-variant dependent pieces...

On Thu, May 5, 2022, 00:04 Kyle Petryszak @.***> wrote:

I was poking through the code, and trying to figure out where to add a new ups.conf parameter to use a dev path or bus port to the usbhid-ups driver.

— Reply to this email directly, view it on GitHub https://github.com/networkupstools/nut/issues/1414#issuecomment-1117978303, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMPTFCAW325GJDQB6FFPETVILX7XANCNFSM5VCMDHZA . You are receiving this because you commented.Message ID: @.***>

jimklimov commented 2 years ago

UPDATES:

ProjectInitiative commented 2 years ago

The cross referenced issue is the same issue, different UPS. I'm still looking at libusb functions that could help bind to the correct HID device

jimklimov commented 2 years ago

Someone mentioned on the mailing list recently that libusb-0.1 API did not allow to connect to devices by path; however libusb-1.0 should have a way to do so (and this honor the port setting which is now ignored) => #1565

jimklimov commented 1 year ago

Interesting, I don't remember seeing Can't claim USB device [0764:0601]@0/0: Entity not found earlier. Googling points "Entity not found" to possibly "not claiming an interface first".

jimklimov commented 1 year ago

Regarding "device=000": how is it reported by OS? In a Linux system I have, there are no 000s in lsusb output, seems it is 001 based for each bus.

Note that the argument is a regex (in trivial case a fixed string), not a numeric comparison.

If you run the driver with debug verbosity 2 (or higher) it should report the mismatches in detail.