UOS 如何实现自动将 U 盘挂载到指定目录中?

文章探讨了在UOS桌面专业版中,如何改变U盘自动挂载到默认目录的行为。通过分析udevd的日志和udisksd程序,发现udisksd负责实际的挂载操作,而源码中挂载目录是固定的。最终,通过使用mountbind实现了将U盘挂载到指定目录的功能。
摘要由CSDN通过智能技术生成

问题描述

项目功能开发需要支持自动将 U 盘挂载到某个业务文件夹中进行访问,不能使用缺省方式。

版本信息

UOS 桌面专业版

基线行为

将 U 盘插入到安装了 UOS 桌面专业版的笔记本后, UOS 会自动将 U 盘分区挂载到 /media/user/ 目录下,user 为登录的用户名称。

提问环节

  1. UOS 上 U 盘自动挂载操作是谁做的?

    初步判断是 udevd

  2. 如何修改 udevd 的配置来观测 u 盘自动挂载的处理过程?
    参考 从 systemd-udevd 运行 log 中研究其自动加载内核模块的过程 这篇文章,前台拉起 systemd-udevd 并添加 -D 参数。

  3. 在 2 的基础上,修改 udevd 的配置文件,能否实现将 U 盘自动挂载到指定目录中的操作?

测试与信息收集

  1. 硬件环境中收集信息

    如下信息包含插入 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
    .......................................................
    
  2. 信息整理汇总
    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

留意到如下两条规则:

  1. sda: RUN ‘/usr/libexec/openconnect/USBadd.sh’ /usr/lib/udev/rules.d/99-diskmanager.rules:4
  2. 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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值