Fix libusb threads when backgrounded#3437
Conversation
Signed-off-by: Doug Nazar <nazard@nazar.ca>
This is needed in particular with libusb on linux as it will create a thread to handle either netlink or udev messages. If this is created before we background, the driver will hang during exit trying to join the non-existant thread in the new process. Shows this warning while stopping the driver. Stopping /run/nut/usbhid-ups-xxxx.pid failed, retrying harder: Success Signed-off-by: Doug Nazar <nazard@nazar.ca>
|
A ZIP file with standard source tarball and another tarball with pre-built docs for commit f7ba488 is temporarily available: NUT-tarballs-PR-3437.zip. |
|
✅ Build nut 2.8.5.4708-master completed (commit 11c4a94a6a by @dougnazar)
|
|
✅ Build nut 2.8.5.4708-master completed (commit 11c4a94a6a by @dougnazar) |
|
I haven't seen the described behavior, I think. Is this something that changed in recent libusb releases and/or Linux distros/kernel? At what point does libusb start that thread - some method we call (so might defer that until after backgrounding), or somehow automatically during library load? |
|
Looks like the thread creation was added in It happens as soon as libusb is initialized, and cancelled when closed. The call trace is: Edit: It just occurred to me that this might only happen on sysvinit style systems. I'm guessing that systemd handles backgrounding itself and wont see this issue. |
|
Thanks for the details, never knew that nuance. As for systemd vs. init systems, I suppose this would have popped up in BSDs etc. as well? Otherwise, the difference is not so much in systemd itself, as in the Previously the only option to stay foregrounded was to hack the init script or similar, to add FWIW, the |
|
Looking around for context, the idea about
As for the libusb threads, I wonder if they should not be inherited by the child process? I guess when the parent exits, the library closes the context and reaps the threads - so there's none to To this end, currently There are several potential I don't know if that would actually help (e.g. |
This is needed in particular with
libusbon linux as it will createa thread to handle either
netlinkorudevmessages. If this is createdbefore we background, the driver will hang during exit trying to join
the non-existant thread in the new process. Shows this warning while
stopping the driver and is delayed until it switches to
SIGKILL.Stopping /run/nut/usbhid-ups-xxxx.pid failed, retrying harder: SuccessI picked closing and then re-opening as the simpler to implement & test,
but has the biggest impact on each driver. Quite possibly some/all might
need to be modified to allow re-opening like the
usb-hiddriver.The other option I considered was breaking up the backgrounding into stages,
creating the background process early, but leaving the forground process
running to report startup messages until initialization is finished.
Or perhaps there is another option?