5

I'm trying to understand the udev operators so I can create rules for my device, but there seems to be a discrepancy between a couple online sources about the operator that prevents later changes to keys. Which udev operator, if any, will prevent later changes to keys?

There seems to be a discrepancy between the following two sources about the udev operators that prevent later changes to keys.

http://www.reactivated.net/writing_udev_rules.html states that +: ensures that no later rule can have any effect, but man udev states that := will Assign a value to a key finally; disallow any later changes.. man udev also states that "+=" will Add the value to a key that holds a list of entries.. So, which udev operator, if any, will prevent later changes to keys?

I tested this question by creating /etc/udev/rules.d/80-test.rules for my USB flash drive. The rule had the following key-value lines...

SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added.sh" 
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added_2.sh"

The executable file device_added.sh contains ...

`echo "USB device removed  at $(date)" >>/tmp/scripts.log`

...and the executable file device_added_2.sh contains ...

`echo "USB device removed  at $(date)" >>/tmp/scripts_2.log`

I registered the changes to udev: $ sudo udevadm control --reload and then I plugged in the USB flash drive. Then I checked if /tmp/scripts.log and /tmp/scripts_2.log were created and had the appropriate strings, which they did. So, it seems that += does NOT prevent later changes to keys.

Then I tested to know if := prevents later changes to keys by subbing := for += in the first key pair of my rule...

SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN:="/bin/device_added.sh"
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added_2.sh"

Then I registered the changes with udev again, unplugged my USB drive, plugged it in, then checked the test log files for updates. I expected scripts_2.log to NOT be updated. However, it was! So, it seems that := also does NOT prevent later changes to keys.

So, can the += and/or := operator(s) prevent later changes to keys some way? Is there another operator I should be using to prevent later changes?

It seems unlikely that both man udev and http://www.reactivated.net/writing_udev_rules.html would be wrong about this, so I'm probably misunderstanding something about this.

I expected := to prevent scripts_2.log from being updated.

UPDATE - 2019-05-12: I found this stackexchange post asking a very similar question, but the two answers provided there do not answer the question in this post. One answer suggests the use of GOTO, which is a workaround that I understand, and the other answer suggests the use of :=, which, like the previously mentioned sources, seems false.

UPDATE - 2019-05-19: I just realized that the following statement, in http://www.reactivated.net/writing_udev_rules.html...

Additional options
Another assignment which can prove useful is the OPTIONS list. A few options are available:

all_partitions - create all possible partitions for a block device, rather than only those that were initially detected
ignore_device - ignore the event completely
last_rule - ensure that no later rules have any effect

For example, the rule below sets the group ownership on my hard disk node, and ensures that no later rule can have any effect:

KERNEL=="sda", GROUP="disk", OPTIONS+="last_rule"

...uses += to add the last_rule assignment, which seems it is supposed to have the same effect as :=. So, I edited my rule again to...

SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN:="/bin/device_added.sh"
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", OPTIONS+="last_rule"
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added_2.sh"

Then I registered the changes with udev again, unplugged my USB drive, plugged it in, then checked the test log files for updates. I expected scripts_2.log to NOT be updated, but it was. So, it seems that OPTIONS +="last_rule" also does NOT prevent later changes to keys.

Arya
  • 566
  • 2
  • 9
  • 22

1 Answers1

2

It appears that the documentation for := is incomplete; it does what is described, but across rule files. I repeated your experiment like so:

In 50-udevoptest.rules:

SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device",  RUN:="/bin/device_added.sh"
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added_2.sh"

In another rules file from upstream named 73-seat-late.rules, there is this rule

TAG=="uaccess", ENV{MAJOR}!="", RUN{builtin}+="uaccess"

Now I test the rules with udevadm test /sys/... for a device which both rulesets apply, which gets us:

run: '/bin/device_added.sh'
run: '/bin/device_added_2.sh'
run: 'uaccess'
Unload module index
Unloaded link configuration context.

Then I rename the experiment like so mv 50-udevoptest.rules 99-udevoptest.rules, and repeat udevadm test /sys/..., which gets us:

run: '/bin/device_added.sh'
run: '/bin/device_added_2.sh'
Unload module index
Unloaded link configuration context.

(because rule filenames with higher lexical rank receive priority - another ambiguity in the manuals)

Michael Foukarakis
  • 39,737
  • 6
  • 87
  • 123