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

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
  • 1
    @sebelk I believe user83388 means they don't propagate to the "root" namespace – Mark Jun 7 '17 at 19:17

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 acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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