udisks
udisks 提供了一个守护进程 udisksd,它实现了用于查询和操作存储设备的 D-Bus 接口,以及一个命令行工具 udisksctl,用于查询和使用该守护进程。
安装
udisksd(8) 由 D-Bus 按需启动,不应显式启用。它可以通过命令行 udisksctl(1) 进行控制。
配置
权限
用户可以使用 udisks 执行的操作受 polkit 限制。如果 用户会话 未激活或不存在(例如,当从 systemd/User 服务控制 udisks 时),请相应地调整 polkit 规则。
请参阅 https://github.com/coldfix/udiskie/wiki/Permissions,了解 storage
组的常见 udisks 权限,以及 [1],了解更严格的示例。如果您正在使用 Dolphin,您可能会看到 [2]。
默认挂载选项
可以在 /etc/udisks2/mount_options.conf
中定义默认挂载选项。如果该文件尚不存在,请创建它。内置默认值和一些示例可以在 /etc/udisks2/mount_options.conf.example
中看到。[3]
这些选项可以针对特定的文件系统类型。例如,使用 zstd 压缩启用挂载 btrfs 文件系统
/etc/udisks2/mount_options.conf
[defaults] btrfs_defaults=compress=zstd
用法
要手动挂载可移动驱动器,例如 /dev/sdc
$ udisksctl mount -b /dev/sdc1
要卸载
$ udisksctl unmount -b /dev/sdc1
有关更多信息,请参阅 udisksctl help
。
技巧与提示
挂载助手
使用 udisks 封装器可以轻松实现设备的自动挂载。另请参阅 应用程序列表/实用程序#挂载工具。
- bashmount — 一个 bash 脚本,用于以普通用户身份挂载和管理可移动媒体。
- udiskie — 自动挂载器,具有可选的通知、托盘图标以及对密码保护的 LUKS 设备的支持。有关详细信息,请参阅 udiskie wiki
- udiskie-dmenu — udiskie 的 dmenu 界面。
- udisksvm — 用 Python3 编写并使用 Qt5 框架的 GUI 封装器。它使用鼠标点击来挂载、卸载可移动设备或弹出 CD/DVD。有关详细信息,请参阅 README 文件。
- udevil — 包括 devmon。
- 注意: devmon 仅在 udevil 或 pmount 缺少 SUID 权限时才使用 udisks2 进行挂载(按此顺序)。要删除此权限,请以 root 身份运行
chmod -s /usr/bin/udevil
。
udevadm monitor
您可以使用 udevadm monitor
监控块设备事件,并在创建新的块设备时挂载驱动器。udisksd 会自动删除过时的挂载点,因此删除时无需特殊操作。
#!/bin/sh pathtoname() { udevadm info -p /sys/"$1" | awk -v FS== '/DEVNAME/ {print $2}' } stdbuf -oL -- udevadm monitor --udev -s block | while read -r -- _ _ event devpath _; do if [ "$event" = add ]; then devname=$(pathtoname "$devpath") udisksctl mount --block-device "$devname" --no-user-interaction fi done
挂载到 /media
默认情况下,udisks2 将可移动驱动器挂载在 ACL 控制的目录 /run/media/$USER/
下。如果您希望挂载到 /media
,请使用此规则
/etc/udev/rules.d/99-udisks2.rules
# UDISKS_FILESYSTEM_SHARED # ==1: mount filesystem to a shared directory (/media/VolumeName) # ==0: mount filesystem to a private directory (/run/media/$USER/VolumeName) # See udisks(8) ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{UDISKS_FILESYSTEM_SHARED}="1"
由于 /media
与 /run
不同,默认情况下未作为 tmpfs 挂载,您可能还希望创建一个 tmpfiles.d 代码片段,以便在每次启动时清除过时的挂载点
/etc/tmpfiles.d/media.conf
D /media 0755 root root 0 -
挂载 loop 设备
要轻松挂载 ISO 镜像,请使用以下命令
$ udisksctl loop-setup -r -f image.iso
这将创建一个只读 loop 设备,并显示准备好挂载的 ISO 镜像。删除 -r
标志即可对其进行写入。创建的 loop 设备的名称由上面的 loop-setup
命令输出。
只要特定的 loop 设备就位,您就可以卸载和重新挂载镜像。完成对特定 loop 设备的操作后,请使用
$ udisksctl loop-delete -b /dev/loop0
删除它。将 /dev/loop0
替换为特定 loop 设备的名称。
Loop 设备很廉价。因此,在实践中可以创建许多 loop 设备,而无需担心拒绝服务问题。请参阅 [4]。
隐藏选定的分区
如果您希望阻止某些分区或驱动器出现在桌面上,您可以创建一个 udev 规则,例如 /etc/udev/rules.d/10-local.rules
KERNEL=="sda1", ENV{UDISKS_IGNORE}="1" KERNEL=="sda2", ENV{UDISKS_IGNORE}="1"
显示除桌面上的 sda1
和 sda2
之外的所有分区。
由于块设备名称在重启之间可能会更改,因此也可以使用 UUID 来隐藏分区或整个设备。仅在 /usr/lib/udev/rules.d/60-persistent-storage.rules
处理后才能通过 UUID 进行匹配,因此请确保选择的文件名在该文件之后排序。例如
/etc/udev/rules.d/61-hide-partitions.rules
SUBSYSTEM=="block", ENV{ID_FS_UUID}=="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX", ENV{UDISKS_IGNORE}="1"
上面的一行也适用于隐藏多设备 btrfs 文件系统,因为来自单个 btrfs 文件系统的所有设备将在设备之间共享相同的 UUID,但每个单独的设备将具有不同的 SUB_UUID。
应用 ATA 设置
在启动时以及连接驱动器时,udisksd 将应用存储在文件 /etc/udisks2/IDENTIFIER.conf
中的配置,其中 IDENTIFIER
是驱动器的 Drive:Id 属性的值。目前支持 ATA 设置。有关可用选项,请参阅 udisks(8)。这些设置的效果与 hdparm 的设置基本相同,但只要 udisks 守护进程自动启动,它们就是持久的。
例如,要将驱动器的待机超时设置为 240(20 分钟),请添加以下内容
/etc/udisks2/DriveId.conf
[ATA] StandbyTimeout=240
要获取驱动器的 DriveId,请使用 udevadm info --query=all --name=sdx | grep ID_SERIAL | sed "s/_/-/g"
或者,使用 GUI 实用程序来管理配置文件,例如 gnome-disk-utility。
故障排除
隐藏的设备
默认情况下,Udisks2 会向用户隐藏某些设备。如果这是不希望的或存在问题,请将 /usr/lib/udev/rules.d/80-udisks2.rules
复制到 /etc/udev/rules.d/80-udisks2.rules
,并删除副本中的以下部分
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Devices which should not be display in the user interface [...]
损坏的待机计时器
udisks 守护进程定期轮询驱动器的 S.M.A.R.T. 数据。待机超时时间长于轮询间隔的硬盘驱动器可能无法进入待机状态。已经停止旋转的驱动器通常不受影响。目前似乎无法禁用轮询或更改 udisks2 的间隔。请参阅 [5]、[6]。
但是,udisks2 应用的待机超时似乎不受影响。要通过 udisks 设置待机超时,请参阅 #应用 ATA 设置。
其他可能的解决方法可能是将超时时间设置为低于轮询间隔(10 分钟),或者使用 hdparm -y /dev/sdx
强制手动停止旋转。
NTFS 挂载失败
如果挂载 ntfs 分区失败并出现错误
Error mounting /dev/sdXY at [...]: wrong fs type, bad option, bad superblock on /dev/sdXY, missing codepage or helper program, or other error
并且在以 root 身份运行的 journalctl
/dmesg
的内核日志中
ntfs: (device sdXY): parse_options(): Unrecognized mount option windows_names.
问题是(截至 udisks 2.10),默认设置是使用 NTFS-3G 驱动程序,并且有两种解决方案
1:安装 NTFS-3G,然后重启您的机器。
2:配置 udisks2。默认情况下,udisks2 未在 Arch 系统上配置,并且未为非原生文件系统定义任何默认值。最简单的方法是将 /etc/udisks2/mount.options.conf.example
复制到 /etc/udisks2/mount.options.conf
并取消注释以下行
/etc/udisks2/mount_options.conf
[defaults] # 'ntfs' signature, the new 'ntfs3' kernel driver ntfs:ntfs3_defaults=uid=$UID,gid=$GID ntfs:ntfs3_allow=uid=$UID,gid=$GID,umask,dmask,fmask,iocharset,discard,nodiscard,sparse,nosparse,hidden,nohidden,sys_immutable,showmeta,noshowmeta,prealloc,noprealloc,hide_dot_files,nohide_dot_files,windows_names,nocase,case
并重启 udisk2 守护进程,或重启您的机器。
NTFS 文件创建失败(文件名相关)
udisks 2.8.2 引入了一个重大更改,通过将 windows_names
添加到 NTFS 挂载选项,阻止创建与 Win32 不兼容的文件名,例如 nul
、screenshot 23-08-21 19:22.jpg
。除其他事项外,这会导致 Steam Proton 停止初始化。要恢复此行为,请使用
/etc/udisks2/mount_options.conf
[defaults] ntfs:ntfs_defaults=uid=$UID,gid=$GID
除非访问,否则错误的文件名通常不会在 Windows 中引起问题。chkdsk 会将这些名称视为错误,并将重命名的文件移动到文件系统根目录下的 found.nnn
文件夹。
在关机时自动关闭外部 HDD
如果外部 HDD 在系统关机时未正确断电,则可能需要修复此问题。
启用 udisks2.service
。
一个调用我们脚本的服务可能如下所示
/etc/systemd/system/handle_external_hdds.service
[Unit] Requires=udisks2.service Requires=graphical.target After=graphical.target [Service] Type=oneshot RemainAfterExit=yes ExecStop=/usr/local/bin/handle_external_hdds.sh [Install] WantedBy=graphical.target
启用 handle_external_hdds.service
执行 systemd daemon-reload 以应用新设置。
重启或重新启动 graphical.target
以检查是否有效。
一个用于处理单个磁盘上任意数量分区的示例脚本如下所示
/usr/local/bin/handle_external_hdds.sh
#!/bin/bash -u declare -a uuids=(uuid_list) # Only proceed if the drive is present. if [[ ! -L "/dev/disk/by-uuid/${uuids[0]}" ]]; then exit 0 fi for uuid in "${uuids[@]}"; do if findmnt "/dev/disk/by-uuid/$uuid"; then umount "/dev/disk/by-uuid/$uuid" fi done # udisksctl powers off proper drive even if its partition is supplied udisksctl power-off -b "/dev/disk/by-uuid/${uuids[0]}"
uuid_list 是一个空格分隔的 UUID 列表,对应于要检查的设备的分区,例如 "uuid_1" "uuid_2"
。