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.

sezanzeb
  • 407
  • 4
  • 22
  • If you don't want to learn about systemd's quirks, you can try the first suggestion from the link: start your script with at now. –  Apr 22 '20 at 16:46
  • thanks. I have been trying to follow this tutorial: http://blog.fraggod.net/2012/06/16/proper-ish-way-to-start-long-running-systemd-service-on-udev-event-device-hotplug.html But I ended up having this problem: https://unix.stackexchange.com/questions/559833/how-do-i-properly-invoke-a-systemd-service-from-udev-with-an-argument. I'm going to use at now because this is ridiculous – sezanzeb Apr 22 '20 at 17:35
  • solved: https://unix.stackexchange.com/a/581834/227331 – sezanzeb Apr 22 '20 at 17:56

1 Answers1

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/log@.service

[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

sezanzeb
  • 407
  • 4
  • 22
  • 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 Apr 22 '20 at 18:58