问题描述
项目功能开发需要支持自动将 U 盘挂载到某个业务文件夹中进行访问,不能使用缺省方式。
版本信息
UOS 桌面专业版
基线行为
将 U 盘插入到安装了 UOS 桌面专业版的笔记本后, UOS 会自动将 U 盘分区挂载到 /media/user/ 目录下,user 为登录的用户名称。
提问环节
-
UOS 上 U 盘自动挂载操作是谁做的?
初步判断是 udevd
-
如何修改 udevd 的配置来观测 u 盘自动挂载的处理过程?
参考 从 systemd-udevd 运行 log 中研究其自动加载内核模块的过程 这篇文章,前台拉起 systemd-udevd 并添加 -D 参数。 -
在 2 的基础上,修改 udevd 的配置文件,能否实现将 U 盘自动挂载到指定目录中的操作?
测试与信息收集
-
硬件环境中收集信息
如下信息包含插入 U 盘与拔出 U 盘的 log 信息:
3-3: Device (SEQNUM=5874, ACTION=add) is queued Validate module index Check if link configuration needs reloading. Successfully forked off 'n/a' as PID 6738. 3-3: Worker [6738] is forked for processing SEQNUM=5874. 3-3: Processing device (SEQNUM=5874, ACTION=add) 3-3: IMPORT builtin 'usb_id' /usr/lib/udev/rules.d/50-udev-default.rules:13 3-3:1.0: Device (SEQNUM=5875, ACTION=add) is queued scsi_tmf_2: Device (SEQNUM=5876, ACTION=add) is queued Successfully forked off 'n/a' as PID 6744. 3-3: IMPORT builtin 'hwdb' /usr/lib/udev/rules.d/50-udev-default.rules:13 scsi_tmf_2: Worker [6744] is forked for processing SEQNUM=5876. 3-3: MODE 0664 /usr/lib/udev/rules.d/50-udev-default.rules:45 host2: Device (SEQNUM=5877, ACTION=add) is queued host2: Device (SEQNUM=5878, ACTION=add) is queued 3-3:1.0: Device (SEQNUM=5879, ACTION=bind) is queued scsi_tmf_2: Processing device (SEQNUM=5876, ACTION=add) 3-3: Device (SEQNUM=5880, ACTION=bind) is queued 3-3: PROGRAM 'mtp-probe /sys/devices/pci0000:00/0000:00:14.0/usb3/3-3 3 9' /usr/lib/udev/rules.d/69-libmtp.rules:2541 .......................................................
-
信息整理汇总
udevd 识别 U 盘热插拔期间使用的规则内容:
3-3: IMPORT builtin 'usb_id' /usr/lib/udev/rules.d/50-udev-default.rules:13
3-3: IMPORT builtin 'hwdb' /usr/lib/udev/rules.d/50-udev-default.rules:13
3-3: MODE 0664 /usr/lib/udev/rules.d/50-udev-default.rules:45
3-3: PROGRAM 'mtp-probe /sys/devices/pci0000:00/0000:00:14.0/usb3/3-3 3 9' /usr/lib/udev/rules.d/69-libmtp.rules:2541
3-3:1.0: IMPORT builtin 'hwdb' /usr/lib/udev/rules.d/50-udev-default.rules:14
3-3:1.0: IMPORT builtin 'usb_id' /usr/lib/udev/rules.d/60-libgphoto2-6.rules:9
3-3:1.0: RUN 'kmod load $env{MODALIAS}' /usr/lib/udev/rules.d/80-drivers.rules:5
3-3:1.0: IMPORT builtin 'hwdb' /usr/lib/udev/rules.d/50-udev-default.rules:14
3-3:1.0: IMPORT builtin 'usb_id' /usr/lib/udev/rules.d/60-libgphoto2-6.rules:9
3-3:1.0: RUN '/usr/bin/uos-usb-guard -path %p' /usr/lib/udev/rules.d/88-filter-block-device.rules:3
3-3: IMPORT builtin 'usb_id' /usr/lib/udev/rules.d/50-udev-default.rules:13
3-3: IMPORT builtin 'hwdb' /usr/lib/udev/rules.d/50-udev-default.rules:13
3-3: PROGRAM 'mtp-probe /sys/devices/pci0000:00/0000:00:14.0/usb3/3-3 3 9' /usr/lib/udev/rules.d/69-libmtp.rules:2541
2:0:0:0: IMPORT builtin 'hwdb' /usr/lib/udev/rules.d/50-udev-default.rules:14
2:0:0:0: RUN 'kmod load $env{MODALIAS}' /usr/lib/udev/rules.d/80-drivers.rules:5
sg0: GROUP 6 /usr/lib/udev/rules.d/50-udev-default.rules:67
sda: GROUP 6 /usr/lib/udev/rules.d/50-udev-default.rules:59
sda: IMPORT builtin 'usb_id' /usr/lib/udev/rules.d/60-persistent-storage.rules:63
sda: LINK 'disk/by-id/usb-AS_Mass_Storage-0:0' /usr/lib/udev/rules.d/60-persistent-storage.rules:68
sda: IMPORT builtin 'path_id' /usr/lib/udev/rules.d/60-persistent-storage.rules:92
sda: LINK 'disk/by-path/pci-0000:00:14.0-usb-0:3:1.0-scsi-0:0:0:0' /usr/lib/udev/rules.d/60-persistent-storage.rules:94
sda: IMPORT builtin 'blkid' /usr/lib/udev/rules.d/60-persistent-storage.rules:109
sda: LINK 'disk/by-uuid/1234-5678' /usr/lib/udev/rules.d/60-persistent-storage.rules:112
sda: LINK 'disk/by-label/U\x20盘' /usr/lib/udev/rules.d/60-persistent-storage.rules:113
sda: RUN '/lib/udev/hdparm' /usr/lib/udev/rules.d/85-hdparm.rules:1
sda: RUN '/usr/libexec/openconnect/USBadd.sh' /usr/lib/udev/rules.d/99-diskmanager.rules:4
sda: ATTR '/sys/devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3:1.0/host2/target2:0:0/2:0:0:0/block/sda/queue/nr_requests' writing '128' /usr/lib/udev/rules.d/99-uos.rules:1
sda: ATTR '/sys/devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3:1.0/host2/target2:0:0/2:0:0:0/block/sda/queue/read_ahead_kb' writing '4096' /usr/lib/udev/rules.d/99-uos.rules:2
sda: ATTR '/sys/devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3:1.0/host2/target2:0:0/2:0:0:0/block/sda/queue/scheduler' writing 'deadline' /usr/lib/udev/rules.d/99-uos.rules:3
2:0:0:0: IMPORT builtin 'hwdb' /usr/lib/udev/rules.d/50-udev-default.rules:14
sda: RUN '/usr/libexec/openconnect/USBremove.sh' /usr/lib/udev/rules.d/99-diskmanager.rules:5
3-3: IMPORT builtin 'usb_id' /usr/lib/udev/rules.d/50-udev-default.rules:13
留意到如下两条规则:
- sda: RUN ‘/usr/libexec/openconnect/USBadd.sh’ /usr/lib/udev/rules.d/99-diskmanager.rules:4
- sda: RUN ‘/usr/libexec/openconnect/USBremove.sh’ /usr/lib/udev/rules.d/99-diskmanager.rules:5
/usr/libexec/openconnect/USBadd.sh 脚本内容如下:
#!/bin/bash
# SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd.
#
# SPDX-License-Identifier: GPL-3.0-only
PROC_NAME='deepin-diskmanager'
#ProcNumber=`pidof $PROC_NAME`
ProcNumber=`ps aux |grep deepin-diskmanager-service |sed '/grep/d' |sed '/tail/d'`
if [ -n "$ProcNumber" ];then
/usr/bin/dbus-send --system --type=method_call --dest=com.deepin.diskmanager /com/deepin/diskmanager com.deepin.diskmanager.updateUsb
else
exit 0
fi
确认此脚本会被调用,但是 deepin-diskmanager 服务并不存在,脚本的主要逻辑并不会执行。
U 盘实际是在哪里挂载的?
使用 strace 跟踪 systemd-udevd 并没有发现挂载 U 盘的地方,说明 U 盘不是通过 systemd-udevd 直接挂载的。继续研究发现 udisksd 程序负责挂载 U 盘,初步观测它依赖 /run/mount/utab 文件的内容来挂载 U 盘的分区。
既然判断 udisksd 程序使用 /run/mount/utab 文件来挂载 U 盘,那只需要修改该文件里面挂载点内容应该就能够达成目标,于是尝试修改 /usr/libexec/openconnect/USBadd.sh 脚本,在脚本中添加修改 /run/mount/utab 文件的操作,测试无效。
udisksd 程序是否能够配置挂载路径?
参考 http://storaged.org/doc/udisks2-api/latest/mount_options.html 链接内容,发现并没有相关选项。
修改源码是否可行?该修改哪里?
获取 udisks 源码,检索到如下代码:
nsecos@nsecos-PC:~/udisks2-2.8.1.14/src$ grep 'MOUNT_BASE' ./udiskslinuxfilesystem.c
#define MOUNT_BASE "/media"
#define MOUNT_BASE_PERSISTENT TRUE
#define MOUNT_BASE "/run/media"
#define MOUNT_BASE_PERSISTENT FALSE
* it, mount in MOUNT_BASE/$USER
mount_dir = g_strdup_printf (MOUNT_BASE "/%s", user_name);
*persistent = MOUNT_BASE_PERSISTENT;
/* First ensure that MOUNT_BASE exists */
if (g_mkdir (MOUNT_BASE, 0755) != 0 && errno != EEXIST)
"Error creating directory " MOUNT_BASE ": %m");
/* Then create the per-user MOUNT_BASE/$USER */
上述逻辑就是 udisksd 自动挂载 U 盘使用的目录,可能看到目录是固定的,修改代码理论上是能够解决这个问题的,尝试编译发现此包的依赖非常多,编译起来非常麻烦,只能暂且放弃。
其它可能解决方案
https://blog.51cto.com/u_15047489/4333013
验证无效,可能需要添加其它内容,需要了解下 udevd 用户自定义规则的添加方式与优先级。
最终的解决方案
通过 mount bind 自动挂载特定位置目录到指定目录解决这个问题。
参考链接
自定义 udevd 规则:https://www.cnblogs.com/mikeguan/p/8471485.html