You are not logged in.

#1 2025-11-11 14:27:15

ivanbrennan
Member
Registered: 2020-08-16
Posts: 3

[SOLVED] udev rule runs before attribute exists; how to delay write?

I use a Lenovo TrackPoint Keyboard II over bluetooth. It supports a fn_lock sysfs attribute that controls whether the Fn row acts as F1–F12 or as media keys.

/sys/bus/hid/devices/0005:17EF:60E1.*/fn_lock

I prefer FnLock off, so I used the following udev rule to set that automatically when the keyboard connects:

ACTION=="add", SUBSYSTEM=="hid", ENV{HID_ID}=="0005:000017EF:000060E1", ATTR{fn_lock}="0"

This worked until recently, when I updated my system, including a newer kernel version. After the update, the fn_lock attribute still exists, but is created shortly after the "add" udev event. When the rule fired, fn_lock did not yet exist, so setting it with ATTR did nothing.

To confirm this, I temporarily changed ATTR{fn_lock}="0" to a debugging RUN command:

RUN+="/bin/sh -c 'ls %S%p >> /home/ivan/udev-debug.txt; sleep 0.5; ls %S%p >> /home/ivan/udev-debug.txt'"

The first ls showed no fn_lock; the second (after a short delay) did.

So my fix was to use a RUN+= command and delay briefly so the write occurs after the attribute appears:

ACTION=="add", SUBSYSTEM=="hid", ENV{HID_ID}=="0005:000017EF:000060E1", \
  RUN+="/bin/sh -c 'sleep 0.05; echo 0 > %S%p/fn_lock'"
Questions
  • Is there a recommended way to run a follow-up action after all attributes are created?

  • Is there a better synchronization point for hid-lenovo devices (e.g., a different udev event, or waiting for a specific attribute)?

  • Would bind/unbind rules or change events be more appropriate here?

UPDATE: 2025-11-17
Solution: Matching a "bind" event instead of "add" fixed this, so my updated udev rule is:

ACTION=="bind", SUBSYSTEM=="hid", ENV{HID_ID}=="0005:000017EF:000060E1", ATTR{fn_lock}="0"

Last edited by ivanbrennan (2025-11-17 13:06:23)

Offline

#2 2025-11-11 16:04:38

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 447

Re: [SOLVED] udev rule runs before attribute exists; how to delay write?

This commit to the kernel looks sligtly related: https://github.com/torvalds/linux/commi … f670ed88b6
But this shouldn't lead to RUN+= execution before attributes created. If that's true, something is fundamentally broken either in the kernel or in systemd. A lot of udev rules rely on attributes creation atomicity.

ivanbrennan wrote:

This worked until recently, when I updated my system, including a newer kernel version.

Could you identify which package update causes the behavior change? Likely it is linux or systemd, try to downgrade both and update one by one.

Also logs from udev could be helpful. You can increace udev logs verbosity by placing "udev_log=debug" to /etc/udev/udev.conf or by running "udevadm control -l debug".

Last edited by dimich (2025-11-11 16:05:35)

Offline

#3 2025-11-11 16:37:20

mpan
Member
Registered: 2012-08-01
Posts: 1,536
Website

Re: [SOLVED] udev rule runs before attribute exists; how to delay write?

Welcome to the forum, ivanbrennan.

Assuming this is not a bug in kernel, check if the device has more specific matches later. As devices are recognized by the kernel, they go through multiple matches. If one tries to match against a too generic one, that may happen too early.

As an example my USB mouse, upon being added, is matched by “pci”, then “usb”, “hid”, and then finally “input” subsystems. If I’d wish to modify its properties as an input device, I’d match against SUBSYSTEM=="input" and not SUBSYSTEM=="usb". Despite the latter already knows the VID:PID pair.

Adding a delay to the command executed by Udev is a bad idea. Per man 7 udev:

This can only be used for very short-running foreground tasks. Running an event process for a long period of time may block all further events for this or a dependent device.


Paperclips in avatars? | Sometimes I seem a bit harsh — don’t get offended too easily!

Offline

#4 2025-11-17 03:41:28

ivanbrennan
Member
Registered: 2020-08-16
Posts: 3

Re: [SOLVED] udev rule runs before attribute exists; how to delay write?

Thank you both for your help on this.

dimich wrote:

Could you identify which package update causes the behavior change? Likely it is linux or systemd, try to downgrade both and update one by one.

I downgraded, then tried different versions of the kernel and of systemd, and though I wasn't able to identify the version(s) where the behavior changed (switching systemd versions was kind of a rough ride), it seemed to depend on the systemd version rather than that of the kernel.

mpan wrote:

...check if the device has more specific matches later.

This set me in the right direction. Running `udevadm monitor`, when I turned on the keyboard, I noticed a bind event later in the sequence of events, so I adjusted my udev rule to match on that, and it seems to have done the trick.

ACTION=="bind", SUBSYSTEM=="hid", ENV{HID_ID}=="0005:000017EF:000060E1", ATTR{fn_lock}="0"

Offline

#5 2025-11-17 09:49:10

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 71,549

Re: [SOLVED] udev rule runs before attribute exists; how to delay write?

check if the device has more specific matches later. …  seems to have done the trick

\o/
Please always remember to mark resolved threads by editing your initial posts subject - so others will know that there's no task left, but maybe a solution to find.
Thanks.

Offline

Board footer

Powered by FluxBB