libimobiledevice / usbmuxd

A socket daemon to multiplex connections from and to iOS devices
https://libimobiledevice.org
GNU General Public License v2.0
1.46k stars 351 forks source link

Freezing on non-systemd GNU/Linux distributions when activated by udev #210

Open BalkanMadman opened 1 year ago

BalkanMadman commented 1 year ago

Gentoo GNU/Linux. I suppose it is because of some kind of data race when it gets executed twice in a very short amount of time. Relevant code snippet from udev rule:

# Initialize iOS devices into "deactivated" USB configuration state and activate usbmuxd
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="5ac/12[9a][0-9a-f]/*|5ac/8600/*", ACTION=="add", ENV{USBMUX_SUPPORTED}="1", ATTR{bConfigurationValue}="0", OWNER="usbmux", RUN+="/usr/sbin/usbmuxd --user usbmux --udev"

# Make sure properties don't get lost when bind action is called
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="5ac/12[9a][0-9a-f]/*|5ac/8600/*", ACTION=="bind", ENV{USBMUX_SUPPORTED}="1", OWNER="usbmux", RUN+="/usr/sbin/usbmuxd --user usbmux --udev"

The latter follows the former almost immediately, causing some kind of a data race (I guess).

Got it working by applying the next fix (simply removed the run part when device is added):

--- /lib/udev/rules.d/39-usbmuxd.rules  2023-01-22 00:01:59.127987197 +0200
+++ /etc/udev/rules.d/39-usbmuxd.rules  2023-01-27 11:51:07.222984812 +0200
@@ -4,7 +4,7 @@
 SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="5ac/12[9a][0-9a-f]/*|5ac/8600/*", TAG+="systemd"

 # Initialize iOS devices into "deactivated" USB configuration state and activate usbmuxd
-SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="5ac/12[9a][0-9a-f]/*|5ac/8600/*", ACTION=="add", ENV{USBMUX_SUPPORTED}="1", ATTR{bConfigurationValue}="0", OWNER="usbmux", RUN+="/usr/sbin/usbmuxd --user usbmux --udev"
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="5ac/12[9a][0-9a-f]/*|5ac/8600/*", ACTION=="add", ENV{USBMUX_SUPPORTED}="1", ATTR{bConfigurationValue}="0", OWNER="usbmux"

 # Make sure properties don't get lost when bind action is called
 SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="5ac/12[9a][0-9a-f]/*|5ac/8600/*", ACTION=="bind", ENV{USBMUX_SUPPORTED}="1", OWNER="usbmux", RUN+="/usr/sbin/usbmuxd --user usbmux --udev"
BalkanMadman commented 1 year ago

Fixed in https://github.com/libimobiledevice/usbmuxd/commit/e55e6e7c6cdcd7954de339be286b3818da69cddd

BalkanMadman commented 1 year ago

It turns out the commit https://github.com/libimobiledevice/usbmuxd/commit/e55e6e7c6cdcd7954de339be286b3818da69cddd didn't actually fix the problem.

I investigated this a bit further and found that the problem may be in one of the functions in https://github.com/libimobiledevice/usbmuxd/blob/master/src/usb.c. I don't remember which one exactly; the corresponding logs will be attached later. So, there are two issues with the current handling of udev activation:

  1. usbmuxd is a daemon — a long living process — and udev manpage especially discourages starting daemons with RUN attribute (this is what is done on non-systemd builds). Being unconditionally killed may be the reason why it freezes.
  2. The actual reason behind freezing lies somewhere in usbmuxd code, i.e. there is a bug.

To deal with 1. we need to provide the actual OpenRC service file and implement udev activation via it. I've already done, so wait for the draft PR shortly after the publication of this comment. The other part of the issue needs to be traced down though.

BalkanMadman commented 1 year ago

The issue on the Gentoo bugzilla: https://bugs.gentoo.org/show_bug.cgi?id=910706