2

I need to log output from /dev/ttyUSB0. This is how I start the start-log script on a connection

pi@raspberrypi:/etc/udev/rules.d $ cat 50-text-log.rules 
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", RUN+="/bin/bash /scripts/start-log"

all it essentially does is cat /dev/ttyUSB0 > somefile, besides figuring out the path in /dev

but it will result into this message from service udev status

raspberrypi systemd-udevd[4990]: Spawned process '/bin/bash /scripts/start-log' [5018] is taking longer than 59s to complete

I have tried this: How to run long time process on Udev event?

By doing a double fork it already stops after 8 seconds, making it even worse. Changing the cgroup like this: echo $$ >> /sys/fs/cgroup/cpu/tasks (tried to repllicate what was described in the link above in bash) does not change a thing, still exists after 8 seconds.

How can I start a script that may run forever when my USB device connects?

Or how can this be done with a .device file in /etc/systemd/system ("device unit")? There is so little information on this.

3

1 Answer 1

1

Ended up figuring this stuff with systemd services out.


Here is the old stuff that could not run for more than 59 seconds:

old udev rule

cat /etc/udev/rules.d/50-text-log.rules

ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", RUN+="/bin/bash /scripts/start-log"

old script

/scripts/start-log

BASENAME="$(basename $DEVPATH)"
DEVICE="/dev/$BASENAME"
cat "${DEVICE}" >> somefile

Whereas this has been running for 15 minutes now or something:

new udev rule

cat /etc/udev/rules.d/50-text-log.rules

ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ENV{SYSTEMD_WANTS}="log@$env{DEVPATH}.service"

$env{DEVPATH} will be passed to the service as regular command line arg in the $1 bash variable

new service

/etc/systemd/system/[email protected]

[Service]
Type=simple
TimeoutSec=0
GuessMainPID=false
ExecStart=/bin/bash -c "/scripts/start-log %I"

or maybe use TimeoutSec=infinity, looks like that's the newer variation of setting to run forever. But since =0 works for me I didn't try. (see man systemd.service and go down to TimeoutStopSec= which is configured over the shorthand of TimeoutSec=). And I think I also needed to reboot.

new script

DEVPATH=$1
BASENAME="$(basename $DEVPATH)"
DEVICE="/dev/$BASENAME"
cat "${DEVICE}" >> somefile

The old environment variable is not available anymore, have to get it over the arguments

1
  • The important part, that this glosses over, is that the long-running process is no longer being spawned by udev. udev is explicitly designed not to spawn long-running processes.
    – JdeBP
    Commented Apr 22, 2020 at 18:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .