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 <[email protected]> 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 >

