我正在尝试自动安装连接到我的电脑的任何USB驱动器。 我的目标是使用标签装载USB设备(如果有的话),如果没有,则使用uuid。
要做到这一点,我在/etc/udev/rules.d/10-usb-detect.rules中写了一个udev规则:
ACTION=="add", KERNEL=="sd?[0-9]", SUBSYSTEM=="block", RUN+="/usr/local/bin/add.sh"
每次在块子系统上追加添加事件时,都会调用该脚本。
udev规则正常但是当我尝试从脚本安装文件系统时它不起作用。 奇怪的是脚本中的mount命令总是返回$?= 0,所以逻辑上应该挂载文件系统但不是。
这是我的剧本:
#!/bin/bash
LOG_FILE=<path_to_file>
echo "New usb device detected at $DEVNAME" >> $LOG_FILE
echo "mount $DEVNAME /media/usb/test" >> $LOG_FILE
mount $DEVNAME /media/usb/test &>> $LOG_FILE
ret=$?
echo "$ret" >> $LOG_FILE
if [ $ret == "0" ]; then
echo "$DEVNAME mounted at /media/usb/test" >> $LOG_FILE
else
echo "Failed to mount $DEVNAME at /media/usb/test" >> $LOG_FILE
fi
echo "" >> $LOG_FILE
我尝试使用/ media / usb / test不存在,并且我遇到了mount命令的预期错误。 但是当文件夹存在时,即使没有挂载文件系统,mount命令也会返回0。
以下是日志文件的输出:
New usb device detected at /dev/sdc1
mount /dev/sdc1 /media/usb/test
mount: mount point /media/usb/test does not exist
32
Failed to mount /dev/sdc1 at /media/usb/test
New usb device detected at /dev/sdc1
mount /dev/sdc1 /media/usb/test
0
/dev/sdc1 mounted at /media/usb/test
即使mount返回0,也不会挂载/ dev / sdc1。
我确切地说,当我从命令行挂载文件系统时,绝对没有问题,文件系统按原样安装。
有人对我如何调试这个有线索吗?
我认为问题是因为脚本是从udev调用的,因为如果我从命令行调用它也可以。
答案 0 :(得分:5)
我想我发现了这个问题。
显然,udev使用特定的命名空间,实际上我可以通过打印/proc/<daemon_pid>/mountinfo
的内容来查看挂载点,其中是systemd-udevd服务的pid。
$ cat /proc/240/mountinfo
[...]
228 43 8:17 / /media/usb/test rw,relatime - vfat /dev/sdb1 rw,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro
$ df
Sys. de fichiers blocs de 1K Utilisé Disponible Uti% Monté sur
udev 1975740 0 1975740 0% /dev
tmpfs 397376 5916 391460 2% /run
/dev/sda2 75733088 69473400 2389532 97% /
tmpfs 1986868 111860 1875008 6% /dev/shm
tmpfs 5120 4 5116 1% /run/lock
tmpfs 1986868 0 1986868 0% /sys/fs/cgroup
tmpfs 397372 28 397344 1% /run/user/112
tmpfs 397372 24 397348 1% /run/user/1001
所以解决方案应该是强制udev在root用户空间中执行脚本。 我尝试了我在https://unix.stackexchange.com/questions/330094/udev-rule-to-mount-disk-does-not-work
找到的解决方案但是,我的系统没有/usr/lib/systemd/system/systemd-udevd.service
文件。我创建了一个包含内容
/etc/systemd/system/systemd-udevd.service
MountFlags=shared
但是使用此解决方案,我的系统无法启动。
有人知道如何在root用户空间中执行脚本或与用户共享挂载点吗?
PS:我确切地说我正在运行64位Debian 9
解决了编辑: 最后,该文件位于/lib/systemd/system/systemd-udevd.service
。我在/etc/systemd/system/systemd-udevd.service
中复制了它
并将MountFlags=slave
更改为MountFlags=shared
,现在它完美无缺:)
答案 1 :(得分:1)
如果通过向命令添加-t FILESYSTEMTYPE参数来指定文件系统类型,则可能更好地解决了系统类型问题。
mount -t FILESYSTEMTYPE /device_name /mount_point
。
还尝试更改记录事件的方式,使用exec命令记录信息,无需每次都重定向输出的命令。
exec > $LOG_FILE 2>&1
也可以替换
mount $DEVNAME /media/usb/test &>> $LOG_FILE
ret=$?
echo "$ret" >> $LOG_FILE
if [ $ret == "0" ]; then
echo "$DEVNAME mounted at /media/usb/test" >> $LOG_FILE
else
echo "Failed to mount $DEVNAME at /media/usb/test" >> $LOG_FILE
fi
带
mount -t vfat $DEVNAME /media/usb/test
if [ $? -eq 0 ]; then
echo " $DEVNAME Mounted"
else
echo " $DEVNAME not Mounted"
fi
我不确定为什么即使您将退出状态视为成功,设备也无法安装。只是尝试优化代码以捕捉真正的问题。
答案 2 :(得分:1)
我希望我的 Raspberrypi Pico 微控制器板能够自动安装和卸载,这与最初的问题非常相似,因为当您插入时按下 bootsel 按钮时,RPi Pico 被识别为 USB 存储。 所以这是我放在 /lib/udev/rules.d/10-usb-storage.rules 中的内容(确切路径可能取决于分布)
root@darkstar:/lib/udev/rules.d# cat 10-usb-storage.rules
ACTION=="add", KERNEL=="sd?[0-9]", SUBSYSTEM=="block", RUN+="usb_automount"
ACTION=="remove", KERNEL=="sd?[0-9]", SUBSYSTEM=="block", RUN+="usb_automount"
root@darkstar:/lib/udev/rules.d#
这是调用的辅助脚本:
root@darkstar:/lib/udev/rules.d# cat /lib/udev/usb_automount
#!/bin/bash
#this will automatically mount and umount th RPi Pico on /mnt/pico
Name=$(basename $0)
Logger="/usr/bin/logger -p local3.info -t $Name "
#logger -p local3.info -t aoutomount -- testing
Message="$* $DEVNAME $ACTION $ID_FS_LABEL"
$Logger <<< $Message
pico_add ()
{ Message="automounting $DEVNAME $ID_FS_LABEL"
$Logger <<< $Message
/sbin/mount $DEVNAME /mnt/pico && $Logger <<< "mounted" || $Logger <<< "failed"
}
pico_remove ()
{ Message="umounting $DEVNAME $ID_FS_LABEL"
$Logger <<< $Message
/sbin/umount -f /mnt/pico && $Logger <<< "umounted" || $LOGGER "failed"
}
case $ID_FS_LABEL in
RPI-RP2) pico_$ACTION ;;
*) $Logger <<< "$ID_FS_LABEL is not configured for any automatic action"
esac
root@darkstar:/lib/udev/rules.d#
要重新加载 udev 规则:https://unix.stackexchange.com/questions/39370/how-to-reload-udev-rules-without-reboot/39371
udevadm control --reload-rules && udevadm trigger
顺便说一句:udev 似乎忽略了 /etc/fstab 的内容