15

I tried to create some udev rules to mount and unmount my USB flash drives; the rules for the moment are very simple:

ACTION=="add",KERNEL=="sd[b-z]",RUN+="/root/scripts/plug_flash_drive.sh %k"
ACTION=="remove",KERNEL=="sd[b-z]",RUN+="/root/scripts/unplug_flash_drive.sh %k"

plug_flash_drive.sh is also very simple:

device_name=$1
mount_options="umask=000,utf8"
if [ ! -e "/media/$device_name" ]; then
    mkdir "/media/$device_name"
fi
sleep 1
/usr/bin/mount "/dev/$device_name" "/media/$device_name" -o "$mount_options"

unplug_flash_drive.sh:

device_name=$1

umount "/dev/$device_name"
rmdir "/media/$device_name"

I have done some tests so I can ascertain that:

  • When plugged in, my flash drive is detected; a file is created in /dev
  • plug_flash_drive.sh is called by udev
  • the mkdir part of the script works
  • however, it seems that the "mount" part of the script is not executed, so my drive is not mounted
  • when I call my scripts on the command line, they perfectly work

Does anybody know why mount is not executed when called by udev?

EDIT 28/08/14: I added "grep -q /proc/mounts && echo success || echo failure" at the end of my script to check in my debug log if the device is actually mounted before the script ends. It appears that the device is mounted at that point even when the script is called by udev. So the real problem is now "my block device is seemingly unmounted after the mount script end when called through udev" :s

  • This may be beside the point, but why do you mkdir "$mount_dir" but rmdir "/media/$device_name"? Where is $mount_dir set? – G-Man Aug 27 '14 at 20:22
  • sorry, this is a typo, I used some quite useless variables aliasing in the original codes and I removed them here for the sake of clarity – magva Aug 27 '14 at 20:26
  • Have you tried old-school debugging; e.g., by putting set -xv and exec >> "$HOME"/mount.log 2>&1 into the .sh files? – G-Man Aug 27 '14 at 20:43
  • 1
    I have done that, but according to the log I get, mount is executed when the script is called by udev. There is no difference in the log between a call from udev and from command line... that's actually rather baffling – magva Aug 27 '14 at 21:11
  • 1
    in that case, the script would also fail when run from command line – magva Aug 27 '14 at 22:48
22

systemd-udevd runs in its own file system namespace and by default mounts done within udev .rules do not propagate to the host. To make your old scripts work you can set MountFlags=shared in /usr/lib/systemd/system/systemd-udevd.service or (better) creating and editing its copy at /etc/systemd/system/

See man 5 systemd.exec for more information, MountFlags option.

  • What do you mean by "do not propagate to the host"? – sebelk Dec 13 '16 at 16:01
  • 2
    @sebelk I believe user83388 means they don't propagate to the "root" namespace – Mark Jun 7 '17 at 19:17
0

As of this writing, the other answers are incorrect (or out of date).

You should not run mount from a Systemd service. Even after commenting the MountFlags and PrivateMounts lines in systemd-udevd.service, your rule will not work for FUSE filesystems like NTFS or exFAT, because the FUSE process will get helpfully killed by Systemd.

See this ArchWiki page which lists several better options. My preference is a tiny project on GitHub called udev-media-automount, which simply restarts a Systemd service from the Udev rule. This is a convenient way to get around Udev's various cumbersome restrictions on namespaces and child processes.

See also this anwser, which shows how to use the SYSTEMD_WANTS Udev variable to start a Systemd unit.

-1

You could try to use := instead of += in the rules RUN assignments.

The := operator sets the list value and disallows further changes.

  • thanks, but mount still not works :( – magva Aug 27 '14 at 20:33
  • 1
    Maybe not your case, but in my system mount is located at /bin/mount. Try "command -v mount". – xae Aug 27 '14 at 21:04
  • 1
    In my system, the path returned by "command -v mount" is /usr/bin/mount. I noticed that I also had a /bin/mount executable, but it doesnt work either when called by udev – magva Aug 27 '14 at 21:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.