ITADN

fclones triggers all autofs mounts on startup, hanging when any target is unreachable

#337OpenRaminTorabiAWS 创建于 2026-04-19
R
RaminTorabiAWScommented
# Upstream bug report for fclones **Title**: `fclones` triggers all autofs mounts on startup via sysinfo disk enumeration **Project**: https://github.com/pkolaczk/fclones **Affected version**: 0.35.0 (verified against source) **Date reported**: 2026-04-19 ## Summary On Linux systems with systemd-automount (autofs) or unreachable network mounts listed in `/proc/mounts`, `fclones` hangs or is dramatically slowed on startup — *before* it even begins walking the user-specified scan path. The cause is that `DiskDevices::new()` in `fclones/src/device.rs` calls `sysinfo::System::refresh_disks_list()`, which enumerates every mount point in `/proc/mounts` and calls `statvfs(2)` on each one to detect its filesystem kind, rotational flag, and mount point. On Linux, any mount point managed by systemd-automount or a classic autofs map is itself an autofs trigger — stat-ing it fires the auto-mount handler, which tries to attach the underlying storage (USB drive, NFS share, CIFS, FUSE, S3FS, etc.). If the target is unreachable, `statvfs()` blocks until the kernel or user-space timeout expires. ## Reproduction System context: - Linux with systemd - Two or more systemd-automount units whose target devices are either unattached (a CD-ROM, a detached USB drive) or unreachable (an NFS server that is down). - A directory to scan that lives on an already-mounted filesystem and has nothing to do with any of the automount units. Example `/proc/mounts` excerpt (real system): ``` systemd-1 /mnt/2tb_usb_transcend autofs rw,relatime,fd=67,pgrp=1,timeout=1800,… systemd-1 /srv/nfs/home autofs rw,relatime,fd=72,pgrp=1,timeout=1800,… ``` Steps: 1. Create three tiny test files on the root/home filesystem: `mkdir ~/tmp/test && echo a > ~/tmp/test/{a,b}.jpg && echo c > ~/tmp/test/c.jpg` 2. Run `fclones group --one-fs --name '*.jpg' ~/tmp/test` Expected: fclones scans three files, reports duplicates in well under a second. Observed: fclones blocks for many seconds (occasionally tens of seconds) before producing any output. `strace -f` shows the process `openat`/`statvfs` on unrelated autofs mount points such as `/mnt/2tb_usb_transcend` during the `sys.refresh_disks_list()` phase, *before* any operation on the scan path. Strace fragment showing the problem: ``` statfs("/mnt/2tb_usb_transcend", …) = … # triggers automount of absent USB drive statx(…, "/sys/block/sdl/queue/rotational", …) = … openat(…, "/dev/disk/by-id/…", …) = … ``` ## Why `--one-fs` does not help `--one-fs` only affects directory traversal, not the startup device enumeration. By the time `--one-fs` would matter, the process is already stuck probing unrelated mounts. ## Why `--threads main:N` does not help The `--threads` flag overrides the per-device thread-pool *sizes* but does not skip the device-discovery phase itself. `DiskDevices::new()` still runs and still calls `sysinfo::refresh_disks_list()`. ## Root cause `fclones/src/device.rs` around line 228: ```rust pub fn new(pool_sizes: &HashMap<OsString, Parallelism>) -> DiskDevices { let mut sys = System::new(); sys.refresh_disks_list(); // <— enumerates every mount point ... for d in sys.disks() { ... result.mount_points.push((Path::from(d.mount_point()), index)); } } ``` The `sysinfo` crate's `refresh_disks_list` is documented to read `/proc/mounts` on Linux and probe every entry for metadata. ## Suggested fix `DiskDevices` is only consulted via `get_by_path(path)` and `get_mount_point(path)` for paths that the user actually asked to scan. A lazy device-discovery implementation would: 1. Enumerate the *devices* (via `/sys/block`) eagerly — this is cheap and local, it only needs kernel data, and it cannot block on any filesystem. 2. Enumerate *mount points* lazily, either: - only for mount points that are the prefix of a scan path, or - by reading `/proc/self/mountinfo` (which is purely text and does not trigger autofs), parsing it directly, and never calling `stat()` or `statvfs()` on the mount target. A less invasive interim fix: in `DiskDevices::new()`, filter out mount entries whose filesystem type is `autofs` before probing them, since those are trigger-points that block until the backing filesystem is actually mounted. ## Workarounds users can apply today - Comment out or disable `systemd-automount` units for unreachable devices (this is what the reporter did). - Set `MOUNT_WAIT=40` on autofs maps (does not help if the target is absent). - Unmount the `autofs` trigger with `umount -l` before running `fclones` (hostile — breaks autofs). - Run fclones with `sudo -u nobody` in a mount namespace that does not inherit the autofs mounts (heavy-handed). None of these are a satisfactory alternative to a real fix in fclones. ## Related prior art The same class of bug was filed against `telegraf` (which also used a generic sysinfo-style disk enumeration): https://github.com/influxdata/telegraf/issues/3430 Labels: `bug`, `platform:linux`, `performance`
0 条评论