Skip to content

symbolic link to fifo : rmlint hangs in rm_sys_open from rm_util_is_nonstripped #792

Open

Description

@ashmanskas

I recently used rmlint to deduplicate a decade or so of backup/archive files. It kept getting stuck (completely hanging, no disk or CPU activity, no error message) on what I eventually tracked down to be a (duplicate) symbolic link to a fifo/pipe file.

I asked rmlint only to find duplicate files, yet it also checked for non-stripped ELFs. The link that it opened was a link, not a file, despite the "-T df" option. (I think that lstat() could detect this.) Also, the link was to a file on another filesystem, even though the -x flag indicates that rmlint should stick to a single filesystem. (Though it may have no way to know this before stat'ing the destination file.)

I compiled with 'scons DEBUG=1' and added fprintf to the inline function rm_sys_open as well as before every call to rm_sys_open.

$ ./rmlint/rmlint --version
version 2.10.3 compiled: Aug 10 2026 at [16:50:27] "Ludicrous Lemur" (rev b311f38)
compiled with: +mounts +nonstripped +fiemap +sha512 +bigfiles +intl +replay +xattr +btrfs-support

rmlint was written by Christopher Pahl and Daniel Thomas.
The code at https://github.com/sahib/rmlint is licensed under the terms of the GPLv3.
$

$ ./rmlint/rmlint -x -T df -S m -o sh:rmlint.sh -c sh:hardlink ./foobar/
is_nonstripped: rm_sys_open /mnt/gdrive/ashmansk/foobar/simtest_output.fifo
rm_sys_open: 0 /mnt/gdrive/ashmansk/foobar/simtest_output.fifo
[hangs up here, no further CPU or disk activity, no error message]
^\Quit (core dumped)
[ble: exit 131]
$

$ ls -lR ./foobar/
./foobar/:
total 4
drwxrwxr-x 2 ashmansk ashmansk 4096 Aug 10 16:39 subdir
lrwxrwxrwx 1 ashmansk ashmansk 38 Jul 18 2016 simtest_input.fifo -> /data/ashmansk/temp/simtest_input.fifo
lrwxrwxrwx 1 ashmansk ashmansk 39 Jul 18 2016 simtest_output.fifo -> /data/ashmansk/temp/simtest_output.fifo

./foobar/subdir:
total 0
lrwxrwxrwx 1 ashmansk ashmansk 38 Jul 18 2016 simtest_input.fifo -> /data/ashmansk/temp/simtest_input.fifo
lrwxrwxrwx 1 ashmansk ashmansk 39 Jul 18 2016 simtest_output.fifo -> /data/ashmansk/temp/simtest_output.fifo
$

$ ls -l /data/ashmansk/temp/*.fifo
prw-rw-r-- 1 ashmansk ashmansk 0 Jul 19 2016 /data/ashmansk/temp/simtest_input.fifo
prw-rw-r-- 1 ashmansk ashmansk 0 Jul 19 2016 /data/ashmansk/temp/simtest_output.fifo
$

It appears that even opening the fifo, without reading, is enough to block:

$ python3
Python 3.14.4 (main, Jun 18 2026, 14:25:02) [GCC 15.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

fp = open("foobar/simtest_output.fifo", "r")
[hangs]
^\Quit (core dumped)
[ble: exit 131]
$

$ python3
Python 3.14.4 (main, Jun 18 2026, 14:25:02) [GCC 15.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

open("/data/ashmansk/temp/simtest_output.fifo")
^\Quit (core dumped) python3
[ble: exit 131]
$

But it is possible to lstat the link, to see that it is a link, or to stat the link, to see that the link target is a fifo:

$ python3
Python 3.14.4 (main, Jun 18 2026, 14:25:02) [GCC 15.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

import os
os.lstat("foobar/simtest_output.fifo")
os.stat_result(st_mode=41471, st_ino=78066383, st_dev=2113, st_nlink=1, st_uid=1001, st_gid=1001, st_size=39, st_atime=1786394119, st_mtime=1468858321, st_ctime=1785531874)
os.stat("foobar/simtest_output.fifo")
os.stat_result(st_mode=4532, st_ino=1514250, st_dev=48, st_nlink=1, st_uid=1001, st_gid=1001, st_size=0, st_atime=1578709601, st_mtime=1468959945, st_ctime=1644101480)
import stat
stat.S_ISFIFO(os.stat("foobar/simtest_output.fifo").st_mode)
True
^D
$

I think there may be several questions here about the intended rmlint behavior:

  • If one enters "-T df", should a check using lstat() reject symbolic links before trying to rm_sys_open them?
  • Before rm_sys_open opens a file, should it first use stat() to check that it (or its link target) is not a fifo?
  • If "-x" is applied, should "rm_lint_open" be preceded by checking the stat() result for device number, to reject links to different filesystems?

Please let me know if you need further information. I didn't dig deeply enough through the code to feel confident submitting a PR.

-Bill

Activity

  1. ashmanskas commented on Aug 10, 2026

    @ashmanskas
    Author

    possibly related: #555

  2. self-assigned this
    on Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions