1

I need to redirect output from udevadm monitor to a named pipe. For that end I use the following command:

sudo socat -u SYSTEM:"udevadm monitor" PIPE:/tmp/test & 

It works until a process reading from the pipe is interrupted and socat exists with a "Broken pipe" error, which is expected. However, when I list running processes it turns out that udevadm is still running.

 $ ps -a PID TTY TIME CMD 3539 tty1 00:00:00 bash 3619 tty2 00:00:00 bash 3972 pts/0 00:00:00 ps $ sudo socat -u SYSTEM:"udevadm monitor" PIPE:/tmp/test & [1] 3973 $ ps -a PID TTY TIME CMD 3539 tty1 00:00:00 bash 3619 tty2 00:00:00 bash 3973 pts/0 00:00:00 sudo 3974 pts/0 00:00:00 socat 3975 pts/0 00:00:00 socat 3976 pts/0 00:00:00 udevadm 3977 pts/0 00:00:00 ps $ cat /tmp/test monitor will print the received events for: UDEV - the event which udev sends out after rule processing KERNEL - the kernel uevent ^C $ 2020/06/01 12:36:06 socat[3974] E write(6, 0x1dfbc60, 147): Broken pipe [1]+ Exit 1 sudo socat -u SYSTEM:"udevadm monitor" PIPE:/tmp/test $ ps -a PID TTY TIME CMD 3539 tty1 00:00:00 bash 3619 tty2 00:00:00 bash 3976 pts/0 00:00:00 udevadm 3980 pts/0 00:00:00 ps $ 

When I replaced udevadm monitor with yes (to simply feed a stream of data to the pipe), it died along with socat.

If I simply interrupt socat with kill command, udevadm perishes neatly.

If I kill parent bash process socat and udevadm die as well, so I tried wrapping udevadm with sh -c:

sudo socat -u SYSTEM:'sh -c \"udevadm monitor\"' PIPE:/tmp/test & 

hoping that dying shell would kill udevadm, but to no avail.

I am aware, that orphaned process can be adopted by INIT, but it doesn't seem to be the case, because out of all processes only udevadm seems to cheat death like this. To sum up my experiments:

  1. Process tree bash->sudo->socat->udevadm - kill socat - all die
  2. Process tree bash->sudo->socat->udevadm - broken pipe - only udevadm lives on
  3. Process tree bash->sudo->socat->sh->udevadm - broken pipe - only udevadm lives on
  4. Process tree bash->sudo->socat->yes- broken pipe - all die
  5. Process tree bash->sudo->socat->udevadm - kill sudo - all die
  6. Process tree bash->sudo->socat->udevadm - kill bash - all die

The problem I really want to solve are lingering udevadm processes.

My preferred solution would be to udevadm die nicely along with other processes. Acceptable solution would be to have persistent pipe, which would not break when reading process dies.

Are there any options or settings I can pass either to socat or to udevadm to solve my problem?

If socat if a wrong tool for my ultimate objective to have udevadm output sent to a pipe, I am obviously open for suggestions.

1 Answer 1

1

It seems to use a little magic, but you can try inverting the two addresses so you can then add option nofork to the system command. You need to swap -u to -U of course to change direction:

socat -U PIPE:/tmp/test SYSTEM:"udevadm monitor",nofork 

This seems to ignore the closing of the pipe, and you can re-open it again. Don't ask me about the magic.

1
  • This works very nicely, and the pipe it creates a pipe which survives not only reader's death, but even creator's death. I like it, thank you :) But I'll be honest, I wish I knew how the magic works, cargo cult is hardly a sound engineering practice ;) Commented Jun 2, 2020 at 6:46

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.