Skip to content

Can't write to a file from udev Run+= #2497

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
davthomaspilot opened this issue Apr 8, 2018 · 11 comments
Open

Can't write to a file from udev Run+= #2497

davthomaspilot opened this issue Apr 8, 2018 · 11 comments
Labels
Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator.

Comments

@davthomaspilot
Copy link

davthomaspilot commented Apr 8, 2018

Fresh install of 3/13/2018 stretch-lite on an rpi zero W. The only things that were done to the "stock" image:

headless config--added wpa_supplicant.conf and ssh file to /boot
raspi-config stuff
added /home/pi/.ssh directory (for ssh keys)

I have a udev rule that matches when a bluetooth device disconnects:

ACTION=="remove", KERNEL=="input[0-9]*", RUN+="/home/pi/bt_disconnected"

The script bt_disconnected runs when the device is disconnected, but fails if it tries to write to a file in /tmp or /home/pi. It fails, even if the rule is not added to /etc/udev/rules.d/99-bt.rules until after a fresh boot. File permissions are 777.

It seems the file system is readonly for udev after boot has finished.- At least directories /tmp and /home/pi--tried both those locations for the disconnects file). Yet, the logger command has no problem writing to /var/log/syslog.

Here's the script:

#!/bin/bash
logger "Disconnected"
#logger "$(whoami)"
echo "hello"  >> "/tmp/disconnects"

The udev rule triggers, when I disconnect a connected bluetooth device from the device. The logger command works and reports the user is root, when the command is not commented. But, the last line fails without writing to the file and a message in /var/log/syslog reports it exited with return code 1:

Apr 7 20:32:29 Ipad2GMA root: Bluetooth Disconnected
Apr 7 20:32:29 Ipad2GMA systemd-udevd[690]: Process '/home/pi/bt_disconnected' failed with exit code 1.

If the following command is executed:

sudo /etc/init.d/udev restart

future bt disconnects trigger the udev rule and the bt_disconnected script writes to the /tmp/disconnects file without issue.

Using the command:

udevadm control --reload-rules

doesn't "fix" the issue. Just the udev restart.

Workaround is to restart udev in /etc/rc.local or in a daemon that runs late in the boot process.

Maybe related--this message occurs in /var/log/syslog, whether my rules are in udev or not:

Apr 7 20:32:21 Ipad2GMA systemd-udevd[685]: Process '/usr/sbin/th-cmd --socket /var/run/thd.socket --passfd --udev' failed with exit code 1.

Not sure if it's normal, but I see this in dmesg after booting (before adding the udev rules);

[ 1.448736] VFS: Mounted root (ext4 filesystem) readonly on device 179:2

Here's the syslog without the udev rules added:

syslog.txt

And, with the 99-bt.rules file:

syslog_after.txt

Note these records which only appear in /var/log/syslog when the 99-bt.rules file has the rule for triggering the script execution:

Apr 8 10:33:29 Ipad2GMA systemd[1]: Stopping Session c1 of user pi.
Apr 8 10:33:29 Ipad2GMA systemd[1]: Unmounting RPC Pipe File System...
Apr 8 10:33:29 Ipad2GMA systemd[449]: Stopped target Basic System.

But, based on the timestamps and the location of these records in the /var/syslog file, they were written at shutdown, not at the beginning of the reboot sequence.

@davthomaspilot
Copy link
Author

davthomaspilot commented Apr 8, 2018

Here's the syslog after running

udevadm control --log-priority=debug

syslog_debug.txt

Note the records:

Apr 8 11:02:28 Ipad2GMA systemd-udevd[601]: RUN '/home/pi/bt_disconnected' /etc/udev/rules.d/99-bt.rules:2
Apr 8 11:02:28 Ipad2GMA systemd-udevd[602]: starting '/home/pi/bt_disconnected'
Apr 8 11:02:28 Ipad2GMA root: Bluetooth Disconnected
Apr 8 11:02:28 Ipad2GMA systemd-udevd[601]: '/home/pi/bt_disconnected'(err) '/home/pi/bt_disconnected: line 3: /tmp/disconnects: Read-only file system'

@JamesH65
Copy link
Contributor

@davthomaspilot Sorry about the delay - are you still experiencing this issue? It sound more like a generic kernel issue than Pi specific, does Google throw up anything?

@JamesH65 JamesH65 added the Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator. label May 11, 2018
@davthomaspilot
Copy link
Author

I've been using a work-around. When you say "are you still experiencing..", do you want want me to test on something newer?

Google searches show many have reported what seems like the same issue

@JamesH65
Copy link
Contributor

The same issue only on Raspberry Pi, or on other systems as well?

@davthomaspilot
Copy link
Author

Both, just google it. Here are a couple of examples:

https://www.raspberrypi.org/forums/viewtopic.php?t=210243

https://stackoverflow.com/questions/49182368/udev-does-not-have-permissions-to-write-to-the-file-system?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

I'd guess the issue is in how services get started at boot time. Perhaps some service needs an additional dependency.

Probably udev getting started too soon is the issue, since the filesystem becomes writeable if you restart udev.

@snhenson
Copy link

I had a similar problem. I've seen various workarounds suggested, one is to comment out the line:

MountFlags=slave

in /lib/systemd/system/systemd-udevd.service

@dfgweb
Copy link

dfgweb commented Nov 16, 2018

While investigating why my 'th-cmd' rules are all failed, I just found that systemd-udevd daemon is running with / mounted RO ! (Saw this by checking /process//mounts of udev daemon)
Thus all scripts launched from it don't have write permission on all files/sockets in /run which isn't a tmpfs.
Seems related to previous comments, but don't know exactly why.

@dbrgn
Copy link
Contributor

dbrgn commented Dec 27, 2018

Probably udev getting started too soon is the issue, since the filesystem becomes writeable if you restart udev.

I think I can confirm this. For some reason, on a Raspberry Pi running Debian 9 (Stretch), I cannot write to files from an USB mount script after boot. But if I restart the systemd-udevd service, it works. Until the next reboot.

I'm using a MountFlags=shared override in order to be able to udev-mount devices that are then visible from the regular system/namespace. Maybe something else is necessary?

@dbrgn
Copy link
Contributor

dbrgn commented Dec 27, 2018

This is one of the ugliest hacks I wrote this year, but it seems to work so far 🙈

# /etc/systemd/system/udev-restart-after-boot.service

[Unit]
Description=Restart udev service after boot (ugly hack to work around file system being readonly)

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/systemctl restart systemd-udevd.service

[Install]
WantedBy=multi-user.target

There is surely a cleaner way to fix this problem though.

@JamesH65
Copy link
Contributor

I suspect this is a generic systemD issues, rather than Pi specific, so this issue will be closed within 30 days unless further interactions are posted. If you wish this issue to remain open, please add a comment. A closed issue may be reopened if requested.

@JamesH65 JamesH65 added the Close within 30 days Issue will be closed within 30 days unless requested to stay open label Jul 31, 2019
@junavar
Copy link

junavar commented Aug 27, 2019

I wish to contribute with two facts:

  1. In Ubuntu 16.04 LTS ( $ uname -a: Linux jubutieci 4.4.0-145-generic rpi-3.6: CONFIG_CFG80211_WEXT #171-Ubuntu SMP Tue Mar 26 12:43:40 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux) a process executed from a UDEV rule can write in the file system without restart UDEV system. It seems it’s a Raspberry - Raspian specific issue.

  2. In raspian (uname -a: Linux rpi4 4.14.50-v7+ vchiq: fix NULL pointer deference when closing driver #1122 SMP Tue Jun 19 12:26:26 BST 2018 armv7l GNU/Linux) it is possible to write in some paths of the file system, for example in /dev, without restart UDEV system

This is the shell script (write same log message in two different file system paths) and rule used in both sceneries:
$ cat device-added.sh
#!/bin/bash
echo "USB device added at $(date)">> /dev/device-added.log
echo "USB device added at $(date)">> /tmp/device-added.log

$ cat /etc/udev/rules.d/70-ics-reles.rules
ACTION=="add", KERNEL=="ttyUSB*", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK+="ics_reles%n", RUN+="/home/juan/device-added.sh
"

Following is a partial list of /dev after insertion of USB serial device showing the symlink of the rule and the file written by the shell script:
$ ls -l /dev
total 4
···
-rw-r--r-- 1 root root 50 ago 27 10:30 device-added.log
···
lrwxrwxrwx 1 root root 7 ago 27 10:30 ics_reles0 -> ttyUSB0
···
crw-rw---- 1 root dialout 188, 0 ago 27 10:30 ttyUSB0
···

Here the content of log file created in /dev and /tmp:

$ cat /dev/device-added.log
USB device added at Tue Aug 27 10:30:01 CEST 2019

$ cat /tmp/device-added.log
USB device added at Tue Aug 27 10:30:01 CEST 2019

Saludos.

@JamesH65 JamesH65 removed the Close within 30 days Issue will be closed within 30 days unless requested to stay open label Sep 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator.
Projects
None yet
Development

No branches or pull requests

6 participants