问题场景分析
在Gentoo系统中使用autofs-5.0.4-r5时遇到两个典型问题:
- 预定义挂载点名称在设备顺序变化时(如MMC卡与U盘设备号交换)会导致混乱
- 无法实现基于文件系统LABEL的动态挂载点创建
核心需求
需要实现以下功能组合:
1. 设备插入时仅创建LABEL命名的挂载点(ghost mount)
2. 首次访问时才实际挂载文件系统(autofs特性)
3. 实时监控所有自动挂载点的状态
4. 支持本地和网络文件系统(NFS/CIFS)的统一管理
技术方案实现
1. udev规则配置
创建/etc/udev/rules.d/99-automount.rules:
# USB设备规则
ACTION=="add", KERNEL=="sd*[!0-9]", SUBSYSTEM=="block", ENV{ID_FS_LABEL_ENC}=="?*", \
RUN+="/usr/local/bin/automount-notify.sh add %k $env{ID_FS_LABEL_ENC}"
# MMC设备规则
ACTION=="add", KERNEL=="mmcblk*", SUBSYSTEM=="block", ENV{ID_FS_LABEL_ENC}=="?*", \
RUN+="/usr/local/bin/automount-notify.sh add %k $env{ID_FS_LABEL_ENC}"
2. autofs主配置
/etc/autofs/auto.master配置:
/media/autofs /etc/autofs/auto.media --timeout=30 --ghost
/etc/autofs/auto.media配置模板:
# 动态生成挂载点
* -fstype=auto,noatime,nosuid,nodev :/dev/disk/by-label/&
3. udisks2集成脚本
/usr/local/bin/automount-notify.sh示例:
#!/bin/bash
ACTION=$1
DEVICE=$2
LABEL=$3
case $ACTION in
add)
# 确保挂载点目录存在
mkdir -p "/media/autofs/${LABEL}"
# 发送桌面通知
notify-send -i drive-removable-media "设备就绪" "${LABEL} 已准备就绪"
;;
remove)
# 清理空目录
rmdir "/media/autofs/${LABEL}" 2>/dev/null
notify-send -i drive-removable-media "设备移除" "${LABEL} 已安全移除"
;;
esac
状态监控方案
1. 系统托盘指示器
使用Python+GTK实现状态监控:
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
import os
import subprocess
class MountNotifier(Gtk.StatusIcon):
def __init__(self):
super().__init__()
self.set_from_icon_name("drive-removable")
self.set_tooltip_text("自动挂载监控")
self.connect("activate", self.on_click)
GLib.timeout_add_seconds(5, self.update_status)
def update_status(self):
mounts = subprocess.getoutput("mount | grep '/media/autofs/'")
if mounts:
self.set_from_icon_name("drive-removable-media")
self.set_tooltip_text(f"已挂载设备:\n{mounts}")
else:
self.set_from_icon_name("drive-removable")
self.set_tooltip_text("无挂载设备")
return True
def on_click(self, widget):
menu = Gtk.Menu()
item = Gtk.MenuItem(label="退出")
item.connect("activate", Gtk.main_quit)
menu.append(item)
menu.show_all()
menu.popup(None, None, None, None, 0, Gtk.get_current_event_time())
if __name__ == "__main__":
app = MountNotifier()
Gtk.main()
2. 网络文件系统支持
在auto.media中添加NFS/CIFS支持:
# NFS示例
nfs-share -fstype=nfs4,rw,noatime,nodiratime server:/path/to/share
# SMB示例
smb-share -fstype=cifs,rw,credentials=/etc/samba/creds ://server/share
注意事项
- 确保所有脚本具有可执行权限:
chmod +x /usr/local/bin/*.sh
- udev规则生效需要重新加载:
udevadm control --reload-rules
- autofs服务需要正确配置:
rc-service autofs restart
扩展优化
对于需要更精细控制的场景,可以结合DBus监控:
#!/bin/bash
# 监控udisks2事件
dbus-monitor --system \
"interface='org.freedesktop.UDisks2'" \
"type='signal',member='InterfacesAdded'" |
while read -r line; do
if [[ $line == *"org.freedesktop.UDisks2.Filesystem"* ]]; then
DEVICE=$(echo "$line" | grep -oP "/org/freedesktop/UDisks2/block_devices/\K\w+")
LABEL=$(udisksctl info -b "/dev/$DEVICE" | grep IdLabel | cut -d: -f2 | tr -d ' ')
notify-send "设备检测" "准备挂载 $LABEL"
fi
done