Ingo,
Thank you for the detailed explanation. I wasn't thinking about atomically
handling both at the same time. I also see why lsof in Linux can be
deceiving.
@marc Yes I think it is of pretty poor design. With Ingo's explanation and
the fact they both read /proc and/or use lsof.
And the learning continues.
On Thursday, August 9, 2018, Ingo Schwarze <schwarze@usta.de> wrote:
> Hi Edward,
>
> Edward Lopez-Acosta wrote on Thu, Aug 09, 2018 at 06:29:04PM -0500:
>
>> I was looking to port bleachbit, system cleanup tool, to OpenBSD
>> and one function is to make sure certain files are not in use before
>> it proceeds.
>
> Strictly speaking, that is impossible due to a TOCTOU race condition.
> You cannot do the check and the removal atomically in one step.
> If you do the check and find that no process has it open, then by
> the time you proceed to removing it, another process may have opened
> it. Or even worse, someone may have deleted the old file or moved
> it to a different name and a third person may have created a
> completely new file for a completely different purpose with the old
> name. None of that is OpenBSD-specific, by the way, the same
> arguments hold on Linux.
>
> If you are willing to ignore the dangers posed by such race conditions,
> then both fuser(1) and fstat(1) can be used: both take "file"
> arguments.
>
> By the way, i just confirmed that the /proc/PID/fd/FDNUM filename
> feature is indeed broken on Linux:
>
> $ uname -a
> Linux donnerwolke.asta-kit.de 4.9.0-0.bpo.3-686 #1 SMP Debian
> 4.9.30-2+deb9u5~bpo8+1 (2017-09-28) i686 GNU/Linux
> $ cd /tmp
> $ touch old.txt
> $ tail -f old.txt
>
> In another terminal:
>
> $ cd /tmp
> $ ln old.txt new.txt
> $ rm old.txt
> $ pgrep tail
> 24052
> $ readlink /proc/24052/fd/3
> /tmp/old.txt (deleted)
> $ lsof | grep new.txt
> $ lsof | grep tail | grep 3r
> /tmp/old.txt (deleted)
>
> So the kernel claims that "new.txt" is not open by any process,
> and it also claims that the file open by tail(1) can no longer
> be accessed via the file system. However, typing
>
> $ echo test >> new.txt
>
> in the second terminal makes "test" appear on the first terminal,
> so it is a totally normal, fully functional file.
>
> So the description
>
> "Obsolete package: lsof (ancient software that doesn't work)"
>
> is indeed accurate. If lsof says a file isn't open, it may well
> be open anyway. If lsof says a file was deleted, that may be an
> outright lie. If lsof reports that a given process has a file open
> with some name, then that name may be neither the name the process
> used for opening the file nor any of the names the file has now,
> though it usually is one of the names that the file may have had
> at some undefined time in between. You cannot rely on any of those
> statements from lsof because making such statements is just impossible
> by the basic way how UNIX (including Linux) works, even without any
> race conditions. And then you get the race conditions on top of
> all that. Enjoy the mix!
>
> Yours,
> Ingo
>
No comments:
Post a Comment