[systemd-devel] udev “PROGRAM/RUN” command not working properly for “REMOVE” action

Ziemowit Podwysocki ziemowit.podwysocki at globallogic.com
Thu Jan 31 13:46:47 UTC 2019


Hello,

I have multiple exactly same USB devices. Each device enumerates
multiply ttyACM ports under /dev directory. Each port has it unique
purpose, one is for handling some commands, another is diagnostic, etc.
What I want is to alias tty's for particular device by creating symlinks
with the ability to distinguish to which device this port belongs.

For example:

/    DEVICE_UNIQUENUM_PURPOSE/

/    /dev/MODULE_0_DIAG
    /dev/MODULE_0_CMD
    /dev/MODULE_1_DIAG
    /dev/MODULE_1_CMD/

To achieve this I started working with udev to write rules for my
device. I learned that udev is not able to enumerate symlinks for the
same device in the sophisticated way I want it. So I decided to write
bash script which do all the work. Here are the rules:

/    ACTION=="add", KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty",
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1e2d", ATTRS{idProduct}=="0063",
PROGRAM="/bin/bash /home/user/script.sh %k", SYMLINK+="%c"
    ACTION=="remove", SUBSYSTEM=="usb", DRIVER=="usb",
ATTRS{idVendor}=="1e2d", ATTRS{idProduct}=="0063", PROGRAM="/bin/bash
/home/user/script.sh"/

Basically script starts by checking what action did occur "add" or
"remove" and takes next steps based on that. The tricky part is that
rule for "add" will fire script multiple times at once cause there are
multiple tty devices handled at the same time. So to synchronize my
script I implemented simple mutex based on creating directory at some
place. If directory is present then other scripts will wait until they
can create one. Moving forward, add operation:

1.      Creates temporary database if not present
2.      Based on information passed by udev it determines what type of
device is that and what unique number it should give it.
3.      Writes record to database for this particular tty

Remove operation:

1.      Based on serial number passed from udev it should remove all
records for matching tty devices.

Now the problem. For some reason action "remove" is not triggering my
script properly. For action "add" all works flawlessly. Upon device plug
in records are written to database file correctly for each tty. When I
plug out device script most of the time won't even run. Sometimes it
will. Previously I had almost same rule for action "remove" as for "add":

/    ACTION=="remove", KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty",
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1e2d", ATTRS{idProduct}=="0063",
PROGRAM="/bin/bash /home/user/script.sh %k"/

This one sometimes run script for one tty, sometimes for more.
Completely nondeterministicly. I have no idea why is this behaving like
this.

When I'm using "udevadm test" utility to simulate action "remove" for
device then it works perfectly every time. But for real plug out it is
not. I also checked with "udevadm monitor" what events are occuring and
"remove" actions are present for device so everything looks correct.

Another thing I tried was to change "PROGRAM" command to "RUN" command
but it did not helped.

After that I decided to do the simplest test possible. I have written
this rule:

/    ACTION=="remove", SUBSYSTEM=="usb", DRIVER=="usb",
ATTRS{idVendor}=="1244", ATTRS{idProduct}=="206d", RUN+="/bin/touch
/home/user/udev/%k"/

This one suppose to create file named after "KERNEL" param of the
device. This is also not happening! But for action "add" it works!

This drives me nuts. Am I missing something? I know udev specifies that
only short tasks should be runned via "PROGRAM/RUN" but if this is not
short task then what is? Also everything works for action "add". I'm
simply out of ideas. Maybe this is udev flaw?

Thanks,

Ziemowit Podwysocki

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/systemd-devel/attachments/20190131/df16a018/attachment.html>


More information about the systemd-devel mailing list