bug#44883: "rm -rf *" performs an extra skip when it encounters an immutable empty directory

2020-11-26 Thread Nishant Nayan

Hi,

The 'rm' utility' is skipping a mutable file when it encounters an 
immutable empty
directory (while deleting group of files and directories). 
Version(/8.22-18.0.1)/


Description: The bug is that rm skips an extra file while it encounters
an immutable empty directory. For example, on doing an "rm -rf *" on "a 
b c foo x y z",
where a,b,c,x,y,z are mutable files and foo is an immutable empty 
directory, the output
was "foo x", as soon as rm encounters an immutable directory, it skips 
it's immediate

next file(x in this case) and deletes all other files.

I would like to know if it's a known bug?


Regards
Nishant Nayan






bug#44884: "rm -rf *" performs an extra skip when it encounters an immutable empty directory

2020-11-26 Thread Nishant Nayan

Hi,

The 'rm' utility' is skipping a mutable file when it encounters an 
immutable empty
directory (while deleting group of files and directories). 
Version(/8.22-18.0.1)/


Description: The bug is that rm skips an extra file while it encounters
an immutable empty directory. For example, on doing an "rm -rf *" on "a 
b c foo x y z",
where a,b,c,x,y,z are mutable files and foo is an immutable empty 
directory, the output
was "foo x", as soon as rm encounters an immutable directory, it skips 
it's immediate

next file(x in this case) and deletes all other files.

I would like to know if it's a known bug?


Regards
Nishant Nayan






bug#9813: rm -rf calls rmdir() prior to close(), which can fail

2011-10-24 Thread Jim Meyering
Jim Meyering wrote:
 Here is the patch that I expect to push tomorrow:
...
 I've fixed/improved the ChangeLog/commit-log:

 Subject: [PATCH] fts: close parent dir FD before returning from
  post-traversal fts_read

 The problem: the fts-using mkdir -p A/B; rm -rf A would attempt to
 unlink A, even though an FD open on A remained.  This is suboptimal
 (holding a file descriptor open longer than needed), but otherwise not
 a problem on Unix-like kernels.  However, on Cygwin with certain Novell
 file systems, (see http://cygwin.com/ml/cygwin/2011-10/msg00365.html),
 that represents a real problem: it causes the removal of A to fail
 with e.g., rm: cannot remove `A': Device or resource busy

 fts visits each directory twice and keeps a cache (fts_fd_ring) of
 directory file descriptors.  After completing the final, FTS_DP,
 visit of a directory, RESTORE_INITIAL_CWD intended to clear the FD
 cache, but then proceeded to add a new FD to it via the subsequent
 FCHDIR (which calls cwd_advance_fd and i_ring_push).  Before, the
 final file descriptor would be closed only via fts_close's call to
 fd_ring_clear.  Now, it is usually closed earlier, via the final
 FTS_DP-returning fts_read call.
 * lib/fts.c (restore_initial_cwd): New function, converted from
 the macro.  Call fd_ring_clear *after* FCHDIR, not before it.
 Update callers.
 Reported by Franz Sirl via the above URL, with analysis by Eric Blake
 in http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/28739

I pushed that, along with the following in coreutils.
The gnulib update induced a new (coreutils-specific) syntax-check failure:

src/system.h:# define ENODATA (-1)
make[3]: *** [sc_prohibit_always-defined_macros] Error 1

because gnulib now defines that symbol, so I have also removed
that definition from coreutils:


From f8ae6440eb8f943fd1f040d039753851824512d3 Mon Sep 17 00:00:00 2001
From: Jim Meyering meyer...@redhat.com
Date: Mon, 24 Oct 2011 10:27:22 +0200
Subject: [PATCH] rm: update gnulib to get an fts fix for Cygwin+NWFS/NcFsd
 file systems

* NEWS (Bug fixes): Mention it.
As far as we know, this fix affects only Cygwin with NWFS or NcFsd
file systems.  See these:
http://git.sv.gnu.org/cgit/gnulib.git/commit/?id=71f13422f3e634
http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/28739
http://cygwin.com/ml/cygwin/2011-10/msg00365.html
* src/system.h (ENODATA): Remove fall-back definition, now that
gnulib provides one.  Caught by the sc_prohibit_always-defined_macros
syntax-check rule.
Also remove now-irrelevant Don't use bcopy... comment.
---
 NEWS |4 
 gnulib   |2 +-
 src/system.h |   11 ---
 3 files changed, 5 insertions(+), 12 deletions(-)

diff --git a/NEWS b/NEWS
index 4d210b5..b73057a 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,10 @@ GNU coreutils NEWS-*- 
outline -*-

 ** Bug fixes

+  rm -rf DIR would fail with Device or resource busy on Cygwin with NWFS
+  and NcFsd file systems.  This did not affect Unix/Linux-based kernels.
+  [bug introduced in coreutils-7.0, when rm began using fts]
+
   tac no longer fails to handle two or more non-seekable inputs
   [bug introduced in coreutils-5.3.0]

diff --git a/gnulib b/gnulib
index 6a4c64c..71f1342 16
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit 6a4c64ce4a59bd9589e63fb5ee480765d356f8c7
+Subproject commit 71f13422f3e6345933513607255f1f7a7526e937
diff --git a/src/system.h b/src/system.h
index 18ac0cc..19421a9 100644
--- a/src/system.h
+++ b/src/system.h
@@ -74,19 +74,8 @@ you must include sys/types.h before including this file
 # define makedev(maj, min)  mkdev (maj, min)
 #endif

-/* Don't use bcopy!  Use memmove if source and destination may overlap,
-   memcpy otherwise.  */
-
 #include string.h
-
 #include errno.h
-
-/* Some systems don't define this; POSIX mentions it but says it is
-   obsolete, so gnulib does not provide it either.  */
-#ifndef ENODATA
-# define ENODATA (-1)
-#endif
-
 #include stdbool.h
 #include stdlib.h
 #include version.h
--
1.7.7.419.g87009





bug#9813: rm -rf calls rmdir() prior to close(), which can fail

2011-10-24 Thread Eric Blake

On 10/24/2011 02:58 AM, Jim Meyering wrote:

  ** Bug fixes

+  rm -rf DIR would fail with Device or resource busy on Cygwin with NWFS
+  and NcFsd file systems.  This did not affect Unix/Linux-based kernels.
+  [bug introduced in coreutils-7.0, when rm began using fts]


rm didn't use fts() until coreutils 8.0 (the cygwin testing proved that 
coreutils 7.0 did not suffer from the problem).  See also the news for 
8.13 mentioning an rm regression introduced by fts() in 8.0.


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org





bug#9813: rm -rf calls rmdir() prior to close(), which can fail

2011-10-24 Thread Jim Meyering
Eric Blake wrote:
 On 10/24/2011 02:58 AM, Jim Meyering wrote:
   ** Bug fixes

 +  rm -rf DIR would fail with Device or resource busy on Cygwin with NWFS
 +  and NcFsd file systems.  This did not affect Unix/Linux-based kernels.
 +  [bug introduced in coreutils-7.0, when rm began using fts]

 rm didn't use fts() until coreutils 8.0 (the cygwin testing proved
 that coreutils 7.0 did not suffer from the problem).  See also the
 news for 8.13 mentioning an rm regression introduced by fts() in 8.0.

Thanks.

From 5bb6316bd71f3a52990a57d94203d8855e4b6b90 Mon Sep 17 00:00:00 2001
From: Eric Blake ebl...@redhat.com
Date: Mon, 24 Oct 2011 16:20:34 +0200
Subject: [PATCH] doc: NEWS: correct bug introduced in ... version number

* NEWS: s/7.0/8.0/
---
 NEWS |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/NEWS b/NEWS
index b73057a..081989d 100644
--- a/NEWS
+++ b/NEWS
@@ -6,7 +6,7 @@ GNU coreutils NEWS-*- 
outline -*-

   rm -rf DIR would fail with Device or resource busy on Cygwin with NWFS
   and NcFsd file systems.  This did not affect Unix/Linux-based kernels.
-  [bug introduced in coreutils-7.0, when rm began using fts]
+  [bug introduced in coreutils-8.0, when rm began using fts]

   tac no longer fails to handle two or more non-seekable inputs
   [bug introduced in coreutils-5.3.0]
--
1.7.7.419.g87009





bug#9813: rm -rf calls rmdir() prior to close(), which can fail

2011-10-23 Thread Jim Meyering
Eric Blake wrote:
 POSIX is clear that attempts to rmdir() a directory that still has
 open descriptors may fail.  Of course, on Linux, this (rather
 limiting) restriction is not present, so we don't notice it; but on
 Cygwin, there are certain file systems where this is a real problem,
 such as in this thread:
 http://cygwin.com/ml/cygwin/2011-10/msg00365.html

 Looking at an strace on Linux reveals the problem (abbreviated to show
 highlights here):

 $ mkdir -p a/b
 $ strace rm -f a
 ...
 openat(AT_FDCWD, a, O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
 ...
 fcntl(3, F_DUPFD, 3)= 4
 ...
 close(3)= 0
 ...
 openat(4, b, O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
 ...
 fcntl(3, F_DUPFD, 3)= 5
 ...
 close(3)= 0
 close(5)= 0
 unlinkat(4, b, AT_REMOVEDIR)  = 0
 unlinkat(AT_FDCWD, a, AT_REMOVEDIR)   = 0
 close(4)= 0

 Notice that for subdirectories, we opened the directory, then used dup
 to have a handle for use in further *at calls, then do
 fdopendir/readdir/closedir on the DIR*, then close the duplicate fd,
 all before calling unlinkat (aka rmdir) on that subdirectory.  But for
 the top-level directory, the dup'd fd (4) is still open when we
 attempt the unlinkat.

Thanks for the analysis, Eric.
That was due to a rather subtle but easy/safe-to-fix bug.

While the rm from coreutils-8.14 worked as your strace above shows, the
fixed one does this: (note how the close(4) now precedes the removal of a)

  $ mkdir -p a/b
  $ strace -e openat,close,unlinkat ./rm -rf a
  close(3)= 0
  close(3)= 0
  openat(AT_FDCWD, a, O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
  close(3)= 0
  openat(4, b, O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
  close(3)= 0
  close(5)= 0
  unlinkat(4, b, AT_REMOVEDIR)  = 0
  close(4)= 0
  unlinkat(AT_FDCWD, a, AT_REMOVEDIR)   = 0
  close(0)= 0
  close(1)= 0
  close(2)= 0

Here is the patch that I expect to push tomorrow:

From a11c49cd72a91c05a272e36ff5d3cd92675cbfb5 Mon Sep 17 00:00:00 2001
From: Jim Meyering meyer...@redhat.com
Date: Sun, 23 Oct 2011 22:42:25 +0200
Subject: [PATCH] fts: close parent dir FD before returning from
 post-traversal fts_read

The problem: the fts-using rm -rf A/B/ would attempt to unlink A,
while a file descriptor open on A remained.  This is suboptimal
(holding a file descriptor open longer than needed) on Linux, but
otherwise not a problem.  However, on Cygwin with certain file system
types, (see http://cygwin.com/ml/cygwin/2011-10/msg00365.html), that
represents a real problem: it causes the removal of A to fail with
e.g., rm: cannot remove `A': Device or resource busy

fts visits each directory twice and keeps a cache (fts_fd_ring) of
directory file descriptors.  After completing the final, FTS_DP,
visit of a directory, RESTORE_INITIAL_CWD intended to clear the FD
cache, but then proceeded to add a new FD to it via the subsequent
FCHDIR (which calls cwd_advance_fd and i_ring_push).  Before, the
final file descriptor would be closed only via fts_close's call to
fd_ring_clear.  Now, it is usually closed earlier, via the final
FTS_DP-returning fts_read call.
* lib/fts.c (restore_initial_cwd): New function, converted from
the macro.  Call fd_ring_clear *after* FCHDIR, not before it.
Update callers.
Reported by Franz Sirl via the above URL, with analysis by Eric Blake
in http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/28739
---
 ChangeLog |   25 +
 lib/fts.c |   23 +++
 2 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 93ee45e..3a2d2cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2011-10-23  Jim Meyering  meyer...@redhat.com
+
+   fts: close parent dir FD before returning from post-traversal fts_read
+   The problem: the fts-using rm -rf A/B/ would attempt to unlink A,
+   while a file descriptor open on A remained.  This is suboptimal
+   (holding a file descriptor open longer than needed) on Linux, but
+   otherwise not a problem.  However, on Cygwin with certain file system
+   types, (see http://cygwin.com/ml/cygwin/2011-10/msg00365.html), that
+   represents a real problem: it causes the removal of A to fail with
+   e.g., rm: cannot remove `A': Device or resource busy
+
+   fts visits each directory twice and keeps a cache (fts_fd_ring) of
+   directory file descriptors.  After completing the final, FTS_DP,
+   visit of a directory, RESTORE_INITIAL_CWD intended to clear the FD
+   cache, but then 

bug#9813: rm -rf calls rmdir() prior to close(), which can fail

2011-10-20 Thread Eric Blake
POSIX is clear that attempts to rmdir() a directory that still has open 
descriptors may fail.  Of course, on Linux, this (rather limiting) 
restriction is not present, so we don't notice it; but on Cygwin, there 
are certain file systems where this is a real problem, such as in this 
thread:

http://cygwin.com/ml/cygwin/2011-10/msg00365.html

Looking at an strace on Linux reveals the problem (abbreviated to show 
highlights here):


$ mkdir -p a/b
$ strace rm -f a
...
openat(AT_FDCWD, a, 
O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3

...
fcntl(3, F_DUPFD, 3)= 4
...
close(3)= 0
...
openat(4, b, O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
...
fcntl(3, F_DUPFD, 3)= 5
...
close(3)= 0
close(5)= 0
unlinkat(4, b, AT_REMOVEDIR)  = 0
unlinkat(AT_FDCWD, a, AT_REMOVEDIR)   = 0
close(4)= 0

Notice that for subdirectories, we opened the directory, then used dup 
to have a handle for use in further *at calls, then do 
fdopendir/readdir/closedir on the DIR*, then close the duplicate fd, all 
before calling unlinkat (aka rmdir) on that subdirectory.  But for the 
top-level directory, the dup'd fd (4) is still open when we attempt the 
unlinkat.


I'm still trying to investigate whether the fix needs to be in gnulib or 
just coreutils, but something needs to be done to swap the order so that 
the last handle to the directory is closed prior to the rmdir attempt.


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org





bug#9813: rm -rf calls rmdir() prior to close(), which can fail

2011-10-20 Thread Paul Eggert
On 10/20/11 10:38, Eric Blake wrote:
 POSIX is clear that attempts to rmdir() a directory that still has open 
 descriptors may fail.

Hmm, that's news to me.  And on the contrary, the spec
http://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html
explicitly talks about what rmdir() does when there are open descriptors:

 If one or more processes have the directory open when the last link is 
removed,
  the dot and dot-dot entries, if present, shall be removed before rmdir() 
returns
  and no new entries may be created in the directory, but the directory shall 
not
  be removed until all references to the directory are closed.

which very much sounds like rmdir() is supposed to succeed in this case.

Also, there's no entry for this situation under the may fail section
of ERRORS.  And there's longstanding Unix tradition that you can unlink
a file that you have an open file descriptor to, which suggests that
rmdir() should do likewise.

So, if this is a problem under Cygwin, it's probably better to handle it
in the rmdir() wrapper that deals with Cygwin and file descriptors.





bug#9813: rm -rf calls rmdir() prior to close(), which can fail

2011-10-20 Thread Eric Blake

On 10/20/2011 01:47 PM, Paul Eggert wrote:

On 10/20/11 10:38, Eric Blake wrote:

POSIX is clear that attempts to rmdir() a directory that still has open 
descriptors may fail.


Hmm, that's news to me.  And on the contrary, the spec
http://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html
explicitly talks about what rmdir() does when there are open descriptors:

  If one or more processes have the directory open when the last link is 
removed,
   the dot and dot-dot entries, if present, shall be removed before rmdir() 
returns
   and no new entries may be created in the directory, but the directory shall 
not
   be removed until all references to the directory are closed.

which very much sounds like rmdir() is supposed to succeed in this case.

Also, there's no entry for this situation under the may fail section
of ERRORS.  And there's longstanding Unix tradition that you can unlink
a file that you have an open file descriptor to, which suggests that
rmdir() should do likewise.


That's because it's a shall fail, not a may fail error:

[EBUSY]
The directory to be removed is currently in use by the system or some 
process and the implementation considers this to be an error.




So, if this is a problem under Cygwin, it's probably better to handle it
in the rmdir() wrapper that deals with Cygwin and file descriptors.


It's more than just cygwin.  And while cygwin _is_ working around this 
in many cases (cygwin is going to some rather extreme lengths for NTFS 
and NFS, for example), it only works on a per-filesystem basis (the 
latest bug is that a Novell device driver, exposing the NWFS file 
system, has bugs in its mapping to Windows system calls that are 
preventing cygwin's normal workarounds from working).  But even when 
cygwin can work around it, it is expensive (it involves reopening the 
handle multiple times, with varying level of permission requests, to see 
if the file is previously opened in sharing mode, and depending on that 
result, temporarily moving the file to the recycle bin so that it will 
disappear when the last handle closes); whereas fixing coreutils to do 
things in the correct order in the first place would make the overall rm 
process faster because it isn't wasting time on corner case file 
shuffling for a directory that is being deleted in the first place.


At any rate, this is a regression introduced by coreutils 8.0, when rm 
switched to fts().  Prior to that point, coreutils used the correct 
ordering, where rmdir() was not attempted until after the close(); and 
the Cygwin report demonstrated that coreutils 7.0 worked on NWFS where 
coreutils 8.x fails.


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org





bug#9813: rm -rf calls rmdir() prior to close(), which can fail

2011-10-20 Thread Paul Eggert
On 10/20/11 12:57, Eric Blake wrote:
 That's because it's a shall fail, not a may fail error:
 
 [EBUSY]
 The directory to be removed is currently in use by the system
 or some process and the implementation considers this to be an error.

But in use by does not mean accessed by an open
file descriptor owned by.  It means that the directory
is mounted, or is the working directory of a process,
or is the root directory.  The interpretation of in use by
to mean tied down by a file descriptor
flies in the face of the plain meaning of the earlier part
of the text, which talks about what happens when one invokes
rmdir() on a directory that has an open file descriptor.

If we allow the phrase in use by to mean whatever the
operating system wants it to mean, then an operating system
where rmdir() always fails with errno==EBUSY would conform
to POSIX, because the O.S. could always say that the directory
is in use by the rmdir() call itself.  That's not what was
intended here.

 It's more than just cygwin.

So far, I've seen only Cygwin mentioned.
Where does it happen in a typical GNUish environment?

This isn't just a coreutils issue: I expect that it'll occur
many programs that do the equivalent of rm -fr.





bug#9813: rm -rf calls rmdir() prior to close(), which can fail

2011-10-20 Thread Eric Blake

On 10/20/2011 05:46 PM, Paul Eggert wrote:

It's more than just cygwin.


So far, I've seen only Cygwin mentioned.
Where does it happen in a typical GNUish environment?


Try the same exercise using NFSv2 or NFSv3 mounts (NFSv4 is getting 
closer to POSIX compliance, but I don't know if it will handle this any 
better).  I suspect that it would be possible to find a testcase under 
Linux and Solaris clients using a less-than-stellar remote NFS server 
that reproduces this issue, at least on any setup where you would also 
see a failure in unlink()ing a regular file with open fds (rmdir() a 
directory with open handles is conceptually no different than unlink()).




This isn't just a coreutils issue: I expect that it'll occur
many programs that do the equivalent of rm -fr.


Many programs that do the equivalent of rm -fr are using more naive 
algorithms (like coreutils 7.0 rm did) that do not involve fts() and 
unlinkat(), and thus do not hit the problem in the first place, because 
they aren't leaving the directory fd open during the rmdir().  But you 
are right that an strace of 'find a -delete' shows that find suffers 
from the same issue, while 'oldfind a -delete' is immune; again a 
problem where the difference is the use of gnulib's fts().


Maybe we need to ask for clarification from the Austin Group on how much 
of Window's default behavior should affect POSIX compliance (that 
behavior being that a directory is busy if any process has it as a 
current working directory or if any fd is open on the directory).


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org





bug#9813: rm -rf calls rmdir() prior to close(), which can fail

2011-10-20 Thread Paul Eggert
On 10/20/11 17:06, Eric Blake wrote:
 So far, I've seen only Cygwin mentioned.
 Where does it happen in a typical GNUish environment?
 
 Try the same exercise using NFSv2 or NFSv3 mounts

I don't see why NFSv3 or v3 would be different.
I just tried your test case with an NFSv3 mount
(RHEL 5.7 client, NetApp server) and it did not
exhibit the problem.

 I suspect that it would be possible to find a testcase under Linux

Possibly, but I'd like to see it before worrying about this.

 at least on any setup where you would also see a failure in unlink()ing a 
 regular file with open fds

Yes, if regular files don't conform to POSIX, then maybe directories don't
either.  But we generally don't have workarounds for those regular-file
issues in gnulib, and we shouldn't really: the glitches are relatively
rare in practice and people who are used to NFS know about the glitches
and deal with them manually as they come up.  Surely directories should be
treated similarly.





Re: Bug in rm -rf

2005-02-15 Thread Jim Meyering
Geoffrey Odhner [EMAIL PROTECTED] wrote:
 I have encountered a bug with the rm command.  If I unpack the
 coreutils-5.0 in a directory named .temp (I haven't tried any other
 names for this bug) and then from the parent of the .temp directory say:

 rm -rf .temp/

 then I get the following message:

 rm: cannot remove directory `.temp//coreutils-5.0/lib': Directory
 not empty

 Then I say:

 rm -rf .temp/coreutils-5.0/

 and it succeeds.  On the other hand, if I initially say:

 rm -rf .temp

 then it works sometimes.

 I am running MacOS X 10.3.8 on a 667MHz PPC 15 Titanium PowerBook.  Let
 me know if there is any other information I can provide to assist.

Thanks for the report.
That's due to a bug in their implementation of readdir.
With the work-around in the latest test release, GNU rm works
fine even there:

  ftp://alpha.gnu.org/gnu/coreutils/coreutils-5.3.0.tar.gz
  ftp://alpha.gnu.org/gnu/coreutils/coreutils-5.3.0.tar.bz2


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils