Skip to content

Commit 15db4f5

Browse files
committed
feat(fnos-mount-manager): 添加 x-mount.mkdir 选项支持并改进挂载状态检测
为磁盘挂载配置添加默认的 x-mount.mkdir=0755 选项,确保挂载点目录 自动创建时具有正确的权限。同时新增设备路径解析功能,通过 realpath 解决软链接问题,使 findmnt 和占用检测获得一致结果。 新增 fm_resolve_device_path、fm_find_mount_target_for_device 和 fm_is_exact_mountpoint 函数来准确判断设备挂载状态,并在 fm_repair_disk 中检查设备是否已在其他位置挂载,避免冲突。 更新测试用例以验证新选项的正确应用。
1 parent 0f7c5bc commit 15db4f5

5 files changed

Lines changed: 56 additions & 14 deletions

File tree

linux/fnos/fnos-mount-manager/config.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,10 @@ fm_disk_rendered_options() {
158158
local disk_options="${FM_CONFIG_DISK_OPTIONS[${index}]}"
159159
local mode="${FM_CONFIG_DISK_MODES[${index}]}"
160160
local device_timeout="${FM_CONFIG_DISK_TIMEOUTS[${index}]}"
161-
local mode_options=""
161+
local mode_options="x-mount.mkdir=0755"
162162

163163
if [[ -n "${device_timeout}" ]]; then
164-
mode_options="x-systemd.device-timeout=${device_timeout}"
164+
mode_options="$(fm_merge_csv_options "${mode_options}" "x-systemd.device-timeout=${device_timeout}")"
165165
fi
166166

167167
if [[ "${mode}" == "automount" ]]; then

linux/fnos/fnos-mount-manager/fnos-mount-manager.sh

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,33 @@ fm_source_to_device_path() {
150150
esac
151151
}
152152

153+
# 解析设备软链接到真实块设备路径,方便 findmnt 和占用检测得到一致结果。
154+
fm_resolve_device_path() {
155+
local device_path="$1"
156+
if command -v realpath >/dev/null 2>&1 && [[ -e "${device_path}" ]]; then
157+
realpath "${device_path}"
158+
return 0
159+
fi
160+
printf '%s\n' "${device_path}"
161+
}
162+
163+
# 查找指定设备当前已经挂载到的目标路径。
164+
fm_find_mount_target_for_device() {
165+
local device_path="$1"
166+
local resolved_device
167+
resolved_device="$(fm_resolve_device_path "${device_path}")"
168+
169+
findmnt -rn -S "${resolved_device}" -o TARGET 2>/dev/null | head -n 1
170+
}
171+
172+
# 判断目标路径是否正好是一个独立挂载点,而不是仅仅位于某个已挂载父文件系统下。
173+
fm_is_exact_mountpoint() {
174+
local mountpoint="$1"
175+
local mounted_target
176+
mounted_target="$(findmnt -rn -M "${mountpoint}" -o TARGET 2>/dev/null || true)"
177+
[[ "${mounted_target}" == "${mountpoint}" ]]
178+
}
179+
153180
# 生成 systemd mount/automount unit 名称,优先复用 systemd-escape 以兼容空格路径。
154181
fm_unit_name_for_path() {
155182
local path="$1"
@@ -434,10 +461,10 @@ fm_disk_rendered_options() {
434461
local disk_options="${FM_CONFIG_DISK_OPTIONS[${index}]}"
435462
local mode="${FM_CONFIG_DISK_MODES[${index}]}"
436463
local device_timeout="${FM_CONFIG_DISK_TIMEOUTS[${index}]}"
437-
local mode_options=""
464+
local mode_options="x-mount.mkdir=0755"
438465

439466
if [[ -n "${device_timeout}" ]]; then
440-
mode_options="x-systemd.device-timeout=${device_timeout}"
467+
mode_options="$(fm_merge_csv_options "${mode_options}" "x-systemd.device-timeout=${device_timeout}")"
441468
fi
442469

443470
if [[ "${mode}" == "automount" ]]; then
@@ -819,14 +846,19 @@ fm_print_disk_status() {
819846
local mode="${FM_CONFIG_DISK_MODES[${index}]}"
820847
local device_path
821848
device_path="$(fm_source_to_device_path "${source}")"
849+
local mounted_target=""
850+
mounted_target="$(fm_find_mount_target_for_device "${device_path}")"
822851

823852
printf '%s\n' "${name}"
824853
printf ' source: %s\n' "${source}"
825854
printf ' mountpoint: %s\n' "${mountpoint}"
826855
printf ' mode: %s\n' "${mode}"
827856
printf ' device_path: %s\n' "${device_path}"
828857
printf ' device_exists: %s\n' "$([[ -e "${device_path}" ]] && printf 'yes' || printf 'no')"
829-
printf ' mounted: %s\n' "$([[ -n "$(findmnt -rn -T "${mountpoint}" -o TARGET 2>/dev/null || true)" ]] && printf 'yes' || printf 'no')"
858+
printf ' mounted: %s\n' "$([[ -n "${mounted_target}" && "${mounted_target}" == "${mountpoint}" ]] && printf 'yes' || printf 'no')"
859+
if [[ -n "${mounted_target}" && "${mounted_target}" != "${mountpoint}" ]]; then
860+
printf ' mounted_elsewhere: %s\n' "${mounted_target}"
861+
fi
830862

831863
if command -v systemctl >/dev/null 2>&1; then
832864
local mount_unit
@@ -895,8 +927,19 @@ fm_legacy_service_uses_old_script() {
895927
fm_repair_disk() {
896928
local index="$1"
897929
local force_mode="$2"
930+
local name="${FM_CONFIG_DISK_NAMES[${index}]}"
931+
local source="${FM_CONFIG_DISK_SOURCES[${index}]}"
898932
local mountpoint="${FM_CONFIG_DISK_MOUNTPOINTS[${index}]}"
899933
local mode="${FM_CONFIG_DISK_MODES[${index}]}"
934+
local device_path
935+
device_path="$(fm_source_to_device_path "${source}")"
936+
local mounted_target=""
937+
mounted_target="$(fm_find_mount_target_for_device "${device_path}")"
938+
939+
if [[ -n "${mounted_target}" && "${mounted_target}" != "${mountpoint}" ]]; then
940+
fm_log "warn" "${name} device is already mounted at ${mounted_target}"
941+
return 1
942+
fi
900943

901944
fm_run_privileged mkdir -p "${mountpoint}"
902945

@@ -922,8 +965,6 @@ fm_repair_disk() {
922965
fi
923966

924967
if [[ "${force_mode}" == "1" ]]; then
925-
local device_path
926-
device_path="$(fm_source_to_device_path "${FM_CONFIG_DISK_SOURCES[${index}]}")"
927968
if command -v fuser >/dev/null 2>&1 && [[ -e "${device_path}" ]]; then
928969
fm_run_privileged fuser -k -9 "${device_path}" >/dev/null 2>&1 || true
929970
fi
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# BEGIN FNOS MOUNT MANAGER
22
# Managed by fnos-mount-manager
33
# Source: disks.example.conf
4-
LABEL=book /vol00/bookDisk ntfs nofail,uid=1000,gid=1000,umask=022,iocharset=utf8,windows_names,big_writes,x-systemd.device-timeout=60,x-systemd.automount 0 0
5-
UUID=REPLACE_WITH_DEBUT_UUID /vol00/debutDisk ntfs nofail,uid=1000,gid=1000,umask=022,iocharset=utf8,windows_names,big_writes,x-systemd.device-timeout=60 0 0
6-
UUID=REPLACE_WITH_REMOVABLE_UUID /vol00/RemovableDisk ntfs nofail,uid=1000,gid=1000,umask=022,iocharset=utf8,windows_names,big_writes,x-systemd.device-timeout=60,x-systemd.automount 0 0
4+
LABEL=book /vol00/bookDisk ntfs nofail,uid=1000,gid=1000,umask=022,iocharset=utf8,windows_names,big_writes,x-mount.mkdir=0755,x-systemd.device-timeout=60,x-systemd.automount 0 0
5+
UUID=REPLACE_WITH_DEBUT_UUID /vol00/debutDisk ntfs nofail,uid=1000,gid=1000,umask=022,iocharset=utf8,windows_names,big_writes,x-mount.mkdir=0755,x-systemd.device-timeout=60 0 0
6+
UUID=REPLACE_WITH_REMOVABLE_UUID /vol00/RemovableDisk ntfs nofail,uid=1000,gid=1000,umask=022,iocharset=utf8,windows_names,big_writes,x-mount.mkdir=0755,x-systemd.device-timeout=60,x-systemd.automount 0 0
77
# END FNOS MOUNT MANAGER

linux/fnos/fnos-mount-manager/tests/check.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ describe('fnos mount manager check', () => {
127127
).toBe(0)
128128

129129
const drifted = readText(workspace.targetFstab).replace(
130-
'UUID=local-debut /mnt/local/debutDisk ntfs nofail,uid=1000,gid=1000,umask=022,big_writes,x-systemd.device-timeout=45 0 0',
131-
'UUID=local-debut /mnt/local/debutDisk ntfs nofail,uid=1000,gid=1000,umask=022 0 0',
130+
'UUID=local-debut /mnt/local/debutDisk ntfs nofail,uid=1000,gid=1000,umask=022,big_writes,x-mount.mkdir=0755,x-systemd.device-timeout=45 0 0',
131+
'UUID=local-debut /mnt/local/debutDisk ntfs nofail,uid=1000,gid=1000,umask=022,x-mount.mkdir=0755 0 0',
132132
)
133133
fs.writeFileSync(workspace.targetFstab, drifted, 'utf8')
134134

@@ -142,7 +142,7 @@ describe('fnos mount manager check', () => {
142142
expect(result.stderr + result.stdout).toContain('Managed block diff:')
143143
expect(result.stderr + result.stdout).toContain('--- local-preview')
144144
expect(result.stderr + result.stdout).toContain('+++ target-managed-block')
145-
expect(result.stderr + result.stdout).toContain('-UUID=local-debut /mnt/local/debutDisk ntfs nofail,uid=1000,gid=1000,umask=022,big_writes,x-systemd.device-timeout=45 0 0')
146-
expect(result.stderr + result.stdout).toContain('+UUID=local-debut /mnt/local/debutDisk ntfs nofail,uid=1000,gid=1000,umask=022 0 0')
145+
expect(result.stderr + result.stdout).toContain('-UUID=local-debut /mnt/local/debutDisk ntfs nofail,uid=1000,gid=1000,umask=022,big_writes,x-mount.mkdir=0755,x-systemd.device-timeout=45 0 0')
146+
expect(result.stderr + result.stdout).toContain('+UUID=local-debut /mnt/local/debutDisk ntfs nofail,uid=1000,gid=1000,umask=022,x-mount.mkdir=0755 0 0')
147147
})
148148
})

linux/fnos/fnos-mount-manager/tests/config.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ describe('fnos mount manager config + generate', () => {
3232
expect(readText(workspace.localFstab)).toContain(
3333
'LABEL=local-book /mnt/local/books/bookDisk ntfs',
3434
)
35+
expect(readText(workspace.localFstab)).toContain('x-mount.mkdir=0755')
3536
expect(readText(workspace.localFstab)).toContain('x-systemd.automount')
3637
expect(readText(workspace.localFstab)).toContain(
3738
'UUID=local-debut /mnt/local/debutDisk ntfs',

0 commit comments

Comments
 (0)