與udev鬥爭
我想
automount
在 Ubuntu 上使用我的 SD 卡。udevadm
我使用(或)嘗試了以下規則/lib/systemd/systemd-udevd
。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|change", ENV{mount_options}="relatime" # Filesystem-specific mount options ACTION=="add|change", ENV{ID_FS_TYPE}=="vfat|ntfs", ENV{mount_options}="$env{mount_options},utf8,gid=100,umask=002" # Mount the device ACTION=="add|change", RUN+="/bin/mkdir -p /media/%E{dir_name}", RUN+="/bin/mount -o $env{mount_options} /dev/%k /media/%E{dir_name}", RUN+=" echo /bin/mount -o $env{mount_options} /dev/%k /media/%E{dir_name\ } > /tmp/debug_out.txt" #ACTION=="add|change" # 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 monitor` indicates that the card is detected KERNEL[1778159.935932] change /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host11/target11:0:0/11:0:0:0/block/sdc (block) KERNEL[1778159.939553] remove /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host11/target11:0:0/11:0:0:0/block/sdc/sdc1 (block) KERNEL[1778159.942501] change /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host11/target11:0:0/11:0:0:0/block/sdc (block) KERNEL[1778159.942615] add /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host11/target11:0:0/11:0:0:0/block/sdc/sdc1 (block) UDEV [1778160.026230] change /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host11/target11:0:0/11:0:0:0/block/sdc (block) UDEV [1778160.101285] remove /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host11/target11:0:0/11:0:0:0/block/sdc/sdc1 (block) UDEV [1778160.184648] change /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host11/target11:0:0/11:0:0:0/block/sdc (block) KERNEL[1778160.320013] add /kernel/slab/ext4_inode_cache/cgroup/ext4_inode_cache(14341:systemd-udevd.service) (cgroup) UDEV [1778160.322555] add /kernel/slab/ext4_inode_cache/cgroup/ext4_inode_cache(14341:systemd-udevd.service) (cgroup) KERNEL[1778160.387280] add /kernel/slab/fat_inode_cache/cgroup/fat_inode_cache(14341:systemd-udevd.service) (cgroup) UDEV [1778160.388849] add /kernel/slab/fat_inode_cache/cgroup/fat_inode_cache(14341:systemd-udevd.service) (cgroup) UDEV [1778160.418509] add /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host11/target11:0:0/11:0:0:0/block/sdc/sdc1 (block)
並且輸出
udevadm test /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host11/target11:0:0/11:0:0:0/block/sdc/sdc1
看起來也不錯[...] run: '/bin/mkdir -p /media/usbhd-sdc1' run: '/bin/mount -o relatime /dev/sdc1 /media/usbhd-sdc1' run: '/usr/bin/unshare -m /usr/bin/snap auto-import --mount=/dev/sdc1' [...]
但是,規則只創建目錄而不掛載卡。使用權限手動執行上述規則可以
sudo
按預期工作(無法創建目錄,sudo
因此這不是問題)(小後續問題:我想從卡中復製文件,觸發作業和
unmount
卡。我也應該這樣做unmount
還是使用不同的機制)========================
如下所述更改了所有內容:
Udev/rules.d KERNEL!="sd[a-z][0-9]", GOTO="media_by_label_auto_mount_end" ACTION=="add", SUBSYSTEM=="block",TAG+="systemd", ENV{SYSTEMD_WANTS}=sd-automounter@%k.service ACTION=="change", SUBSYSTEM=="block",TAG+="systemd", RUN+="systemctl start sd-automounter@%k" # 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
服務說明
# /etc/systemd/system/sd-automounter@.service [Service] Type=oneshot ExecStart=/usr/local/libexec/sd-automounter %I(base)
和服務
#!/bin/sh # /usr/local/libexec/sd-automounter echo "" > /tmp/debug.out DEVICE_NAME=/dev/"$1" echo $DEVICE_NAME >>/tmp/debug.out udevadm info --query=property --export $DEVICE_NAME >> /tmp/debug.out echo "" >> /tmp/debug.out CARD_NAME=$(udevadm info --query=property --export $DEVICE_NAME | grep ID_FS_LABEL= | awk -F\' '{print $2}') echo $CARD_NAME >> /tmp/debug.out #CARD_NAME=$(/sbin/blkid | grep "$DEVICE_NAME" | awk -F\" '{print $2}' |sed 's/ /_/g') udevadm info --query=property --export /dev/sdc1 echo $CARD_NAME mkdir -p /media/$CARD_NAME mount -t vfat $DEVICE_NAME /media/$CARD_NAME thanks for all help in advance
手動執行它
systemctl start sd-automounter@sdd1
就像一個魅力。
udevadm monitor
但是在顯示時刪除和插入什麼也沒發生monitor will print the received events for: UDEV - the event which udev sends out after rule processing KERNEL - the kernel uevent KERNEL[1977111.519970] change /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host12/target12:0:0/12:0:0:0/block/sdd (block) KERNEL[1977111.523252] remove /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host12/target12:0:0/12:0:0:0/block/sdd/sdd1 (block) KERNEL[1977111.526457] change /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host12/target12:0:0/12:0:0:0/block/sdd (block) KERNEL[1977111.526572] add /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host12/target12:0:0/12:0:0:0/block/sdd/sdd1 (block) UDEV [1977111.612257] change /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host12/target12:0:0/12:0:0:0/block/sdd (block) UDEV [1977111.614914] remove /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host12/target12:0:0/12:0:0:0/block/sdd/sdd1 (block) UDEV [1977111.697870] change /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host12/target12:0:0/12:0:0:0/block/sdd (block) UDEV [1977111.791344] add /devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host12/target12:0:0/12:0:0:0/block/sdd/sdd1 (block)
第二個選項的問題是我必須使用完整路徑
ACTION=="add", SUBSYSTEM=="block",TAG+="systemd", RUN+="/bin/systemctl start sd-automounter@%k" ACTION=="change", SUBSYSTEM=="block",TAG+="systemd", RUN+="/bin/systemctl start sd-automounter@%k"
並使用執行選項也添加
systemd-udev
真的不希望您再直接從規則掛載文件系統。你可以在這個網站上找到很多關於它的問題:-)。在最新版本的 systemd 中,udev 服務文件具有
SystemCallFilter=@system-service @module @raw-io
. 這不允許掛載文件系統所需的系統呼叫。(此外,我相信如果您直接用於 FUSE 文件系統,則與 systemd 存在普遍衝突,
mount
例如ntfs-3g
。如果您啟動 FUSE 伺服器程序,最好將它放在專用的 systemd 單元中,例如.mount
單元。如果您讓 FUSE 程序留在您目前的單元內,那麼 FUSE 程序的生命週期將與您正在執行的單元的生命週期耦合)。為了避免將來(或目前)中的命令出現問題
RUN+=
,您的規則可以改為使用ENV{SYSTEMD_WANTS}=my-automounter@%k.service
, 然後# /etc/systemd/system/my-automounter@.service [Service] Type=oneshot ExecStart=/usr/local/libexec/my-automounter %I
#!/bin/sh # /usr/local/libexec/my-automounter DEV=/dev/"$1" # You can make this script as complicated as you want. # You can read udev properties if you want, using # eval "$(udevadm info --query=property --export "$DEV")" ...
如果您想測試手動呼叫該單元,您可以使用
systemctl start my-automounter@sdc1
.
systemctl status my-automounter@*
如果 systemd 執行您的腳本時發生錯誤,您可以使用, 或.查看錯誤消息journalctl -b -u my-automounter@*
。這也避免了您必須處理
udev
特定的錯誤報告。我認為兩者sh
都有systemd
有用的錯誤報告,以防程序突然死亡。例如,他們應該報告一個程序是否被信號殺死SIGSYS
,因為它試圖呼叫一個已被阻止使用的系統呼叫SystemCallFilter=
:-)。