Subject: bug#29038: df hangs on fifos/named pipes

From: Stephane Chazelas <[email-masked]>
Date: Mon, 30 Oct 2017 07:06:10 +0000

2017-10-29 23:16:50 -0700, Paul Eggert:
> Pádraig Brady wrote:
> 
> >I suppose we could stat() and if that succeeds && !fifo, only then call open() ?
> >Patch to do that is attached.
> 
> Better is to use open with O_NONBLOCK, as this avoids interpreting the file
> name twice in the usual case.

That would still have the unwanted side effect of instantiating
(and kill thereafter) the pipe when opening a fifo that has a
writer and no reader.

As in, if some process does a fd = open("fifo", O_WRONLY)

The "df fifo" would cause that open() to return, and the next
write() to it possibly cause a SIGPIPE because df is already
gone.

It's different for O_DIRECTORY as the open() would fail on
fifos (it also fails if you don't have read permission,
which is another advantage of using O_PATH I suppose)

> Better yet is to use O_PATH if available, as
> this avoids interpreting the file name twice even when the file is
> unreadable or is a FIFO that would block.

Note that according to the man page, fstat() on fds open with
O_PATH only works since Linux 3.6. Note that we're already
interpreting the file path twice as we're not using fstatfs (as we
wouldn't want to cause a "too many open files" situation I
suppose by keeping all the files open before we get to the
second phase).

[...]
> It is puzzling that df calls fstat or stat, when it should just be calling
> fstatfs or statfs. But that is a different matter.

I suppose that's because it needs to determine if the file is a
device file or not as for device files where a fs is mounted, it
needs to report details for that fs as opposed to the fs the
device file is on.

-- 
Stephane