以前用udev规则自动挂载U盘是很简单的,直接在规则里匹配然后执行mkidr
和mount
就搞定了。不过systemd在212版之后,systemd-udevd守护进程回在另一个命名空间里运行,在里面进行的mount
是“没效”的,change log:
* systemd-udevd will now run in a disassociated mount
namespace. To mount directories from udev rules make sure to
pull in mount units via SYSTEMD_WANTS properties.
看来要写个systemd service,然后在udev规则里用SYSTEMD_WANTS
来执行。这就好办了,在udev规则里启动systemd service时,我们通过%I
来传递设备路径,然后在systemd service再用一个脚本重新获得其他必要的信息然后挂载。
上面是正解,下面我的折腾,因为udev规则里已经有了文件系统类型、UUID这些信息,我不想再去获取,所以直接构造一个命令,通过%I
传过去。
首先是udev规则:
KERNEL!="sd[b-z]?", GOTO="automount_exit"
ACTION!="add", GOTO="automount_exit"
ENV{ID_FS_TYPE}=="ext4", ENV{MOUNT_OPTS}="defaults,delalloc,nodiratime,noatime,commit=300"
ENV{ID_FS_TYPE}=="ext2|ext3", ENV{MOUNT_OPTS}="defaults,nodiratime,noatime,commit=350"
ENV{ID_FS_TYPE}=="vfat", ENV{MOUNT_OPTS}="defaults,utf8"
ACTION=="add", SUBSYSTEM=="block", \
RUN+="/usr/bin/mkdir -p /tmp/mnt/%E{ID_PART_TABLE_UUID}", \
ENV{SYSTEMD_WANTS}+="automount@%E{MOUNT_OPTS}\x20$root/%k\x20\x2d\x2d\x20/tmp/mnt/%E{ID_PART_TABLE_UUID}.service"
LABEL="automount_exit"
automount@和.service之间就是我传递的参数。
然后是服务(automount@.service
):
[Unit]
Description=Automount(Damn Systemd and Udev)
[Service]
Type=oneshot
ExecStart=/bin/sh -c "exec mount -o %I"
sh -c
好像挺危险的,所以我只用了uuid构造命令。
纯折腾啊。