udev auto mount usb 注意事项

最近在Raspbian写一个测试程序,硬件是树莓派3b+。期间要用到Linux udev 自动挂载U盘,踩了坑。
我想通过在/etc/udev/rules.d/ 目录中自定义 一个10-usb-stick.rules文件来实现U盘按需自动挂载:

# Match the U stick
KERNEL!="sd[a-z][0-9]", GOTO="media_by_label_auto_mount_end"
# Import FS infos
IMPORT{program}="/sbin/blkid -o udev -p %N"
# Get a label if present, otherwise specify one
ENV{ID_FS_LABEL}!="", ENV{dir_name}="%E{ID_FS_LABEL}"
ENV{ID_FS_LABEL}=="", ENV{dir_name}="usbhd-%k"
# Global mount options
ACTION=="add", ENV{mount_options}="relatime"
# Filesystem-specific mount options
ACTION=="add", ENV{ID_FS_TYPE}=="vfat|ntfs", ENV{mount_options}="$env{mount_options},utf8,gid=100,umask=002"
# Mount the device
ACTION=="add", RUN+="/bin/mkdir -p /media/%E{dir_name}", RUN+="/bin/mount -o $env{mount_options} /dev/%k /media/%E{dir_name}"
# Clean up after removal
ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/umount -l /media/%E{dir_name}", RUN+="/bin/rmdir /media/%E{dir_name}"
# Exit
LABEL="media_by_label_auto_mount_end"

然后执行udevadm命令更新rules文件:

udevadm control --reload-rules

插入U盘后,发现系统并未挂载成功,访问挂载点报错:
Transport endpoint not connected errors
通过文档:https://www.axllent.org/docs/view/auto-mounting-usb-storage/
中的读者回馈建议得知:

In new Raspbian image they have implemented some security features within systemd-udevd.service.
To execute run command from USB mount udev rule as I started my query
you need to comment last few lines inside
/lib/systemd/system/systemd-udevd.service:
Should look like this:

[Service]
Type=notify
OOMScoreAdjust=-1000
Sockets=systemd-udevd-control.socket systemd-udevd-kernel.socket
Restart=always
RestartSec=0
ExecStart=/lib/systemd/systemd-udevd
KillMode=mixed
WatchdogSec=3min
TasksMax=infinity
#MountFlags=slave   注释该行
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6

然后重新加载systemd

systemctl daemon-reload

果然U盘可以按需加载。

查看man手册
man 5 systemd.exec

MountFlags=
           Takes a mount propagation flag: shared, slave or private, which
           control whether mounts in the file system namespace set up for this
           unit's processes will receive or propagate mounts or unmounts. 
           Use slave to run processes so that none of their mounts and unmounts
           will propagate to the host. See
           mount(2) for details. 

man 2 mount

Creating a new mount point
       If   none  of  MS_REMOUNT,  MS_BIND,  MS_MOVE,  MS_SHARED,  MS_PRIVATE,
       MS_SLAVE, or MS_UNBINDABLE is specified  in  mountflags,  then  mount()
       performs its default action: creating a new mount point.

终于知道原因,原来udev中设置了挂载标志(MountFlags)来控制可移动设备mount消息的传递,MountFlags在systemd-udevd.service文件中默认是slave,即不传递mount消息到文件系统。我的需求是由udev自动产生一个新挂载点,所以MountFlags无需赋值,注销掉即可;而不是像其他文档所说,需要把mountflages=slave换成mountflages=shared .

ps:如果要关闭树莓派图形系统下自动挂载U盘,则

1.
1.jpg

2.
2.jpg

3.
3.jpg

The end.

你可能感兴趣的:(udev auto mount usb 注意事项)