udev “PROGRAM/RUN” command not working properly for “REMOVE” action

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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="" 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="" 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="" 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="" 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

 

_______________________________________________
systemd-devel mailing list
systemd-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/systemd-devel

[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux