From unknown Sat Sep 13 04:54:48 2025 X-Loop: help-debbugs@gnu.org Subject: bug#9813: rm -rf calls rmdir() prior to close(), which can fail Resent-From: Eric Blake Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-coreutils@gnu.org Resent-Date: Thu, 20 Oct 2011 17:41:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 9813 X-GNU-PR-Package: coreutils X-GNU-PR-Keywords: To: 9813@debbugs.gnu.org, bug-gnulib@gnu.org X-Debbugs-Original-To: bug-coreutils , bug-gnulib Received: via spool by submit@debbugs.gnu.org id=B.13191324097585 (code B ref -1); Thu, 20 Oct 2011 17:41:01 +0000 Received: (at submit) by debbugs.gnu.org; 20 Oct 2011 17:40:09 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RGwb7-0001yC-TL for submit@debbugs.gnu.org; Thu, 20 Oct 2011 13:40:07 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RGwb2-0001xV-EO for submit@debbugs.gnu.org; Thu, 20 Oct 2011 13:40:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RGwZn-0003yl-Vl for submit@debbugs.gnu.org; Thu, 20 Oct 2011 13:38:45 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([140.186.70.17]:45108) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGwZn-0003yc-Rt for submit@debbugs.gnu.org; Thu, 20 Oct 2011 13:38:43 -0400 Received: from eggs.gnu.org ([140.186.70.92]:41549) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGwZl-0004hU-4D for bug-coreutils@gnu.org; Thu, 20 Oct 2011 13:38:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RGwZi-0003xk-Vy for bug-coreutils@gnu.org; Thu, 20 Oct 2011 13:38:41 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52415) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGwZi-0003xG-MB; Thu, 20 Oct 2011 13:38:38 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p9KHcav6011331 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 20 Oct 2011 13:38:37 -0400 Received: from [10.3.113.158] (ovpn-113-158.phx2.redhat.com [10.3.113.158]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p9KHcaJf019394; Thu, 20 Oct 2011 13:38:36 -0400 Message-ID: <4EA05C9C.1070809@redhat.com> Date: Thu, 20 Oct 2011 11:38:36 -0600 From: Eric Blake Organization: Red Hat User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.23) Gecko/20110928 Fedora/3.1.15-1.fc14 Lightning/1.0b3pre Mnenhy/0.8.4 Thunderbird/3.1.15 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.17 X-Spam-Score: -8.0 (--------) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -8.0 (--------) 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 eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org From unknown Sat Sep 13 04:54:48 2025 X-Loop: help-debbugs@gnu.org Subject: bug#9813: rm -rf calls rmdir() prior to close(), which can fail Resent-From: Paul Eggert Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-coreutils@gnu.org Resent-Date: Thu, 20 Oct 2011 19:49:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 9813 X-GNU-PR-Package: coreutils X-GNU-PR-Keywords: To: Eric Blake Cc: bug-gnulib@gnu.org, 9813@debbugs.gnu.org X-Debbugs-Original-Cc: bug-gnulib , bug-coreutils Received: via spool by submit@debbugs.gnu.org id=B.131914014118943 (code B ref -1); Thu, 20 Oct 2011 19:49:01 +0000 Received: (at submit) by debbugs.gnu.org; 20 Oct 2011 19:49:01 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RGybr-0004vT-Lg for submit@debbugs.gnu.org; Thu, 20 Oct 2011 15:49:00 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RGybo-0004vG-Gk for submit@debbugs.gnu.org; Thu, 20 Oct 2011 15:48:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RGyaa-0006xA-Lv for submit@debbugs.gnu.org; Thu, 20 Oct 2011 15:47:41 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([140.186.70.17]:43187) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGyaa-0006x1-KQ for submit@debbugs.gnu.org; Thu, 20 Oct 2011 15:47:40 -0400 Received: from eggs.gnu.org ([140.186.70.92]:45930) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGyaZ-0007Xx-Nq for bug-coreutils@gnu.org; Thu, 20 Oct 2011 15:47:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RGyaU-0006w7-8c for bug-coreutils@gnu.org; Thu, 20 Oct 2011 15:47:39 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:43960) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGyaT-0006vo-SB; Thu, 20 Oct 2011 15:47:34 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id C8F2BA60003; Thu, 20 Oct 2011 12:47:30 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id di3j+CqAtAU6; Thu, 20 Oct 2011 12:47:28 -0700 (PDT) Received: from [131.179.64.200] (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id C48E8A60002; Thu, 20 Oct 2011 12:47:28 -0700 (PDT) Message-ID: <4EA07AD0.2050908@cs.ucla.edu> Date: Thu, 20 Oct 2011 12:47:28 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.23) Gecko/20110928 Fedora/3.1.15-1.fc14 Thunderbird/3.1.15 MIME-Version: 1.0 References: <4EA05C9C.1070809@redhat.com> In-Reply-To: <4EA05C9C.1070809@redhat.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.17 X-Spam-Score: -4.8 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -4.8 (----) 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 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. From unknown Sat Sep 13 04:54:48 2025 X-Loop: help-debbugs@gnu.org Subject: bug#9813: rm -rf calls rmdir() prior to close(), which can fail Resent-From: Eric Blake Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-coreutils@gnu.org Resent-Date: Thu, 20 Oct 2011 19:59:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 9813 X-GNU-PR-Package: coreutils X-GNU-PR-Keywords: To: Paul Eggert Cc: bug-gnulib@gnu.org, 9813@debbugs.gnu.org X-Debbugs-Original-Cc: bug-gnulib , bug-coreutils Received: via spool by submit@debbugs.gnu.org id=B.131914073619822 (code B ref -1); Thu, 20 Oct 2011 19:59:02 +0000 Received: (at submit) by debbugs.gnu.org; 20 Oct 2011 19:58:56 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RGylU-00059f-HA for submit@debbugs.gnu.org; Thu, 20 Oct 2011 15:58:56 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RGylQ-00059P-4r for submit@debbugs.gnu.org; Thu, 20 Oct 2011 15:58:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RGyk9-0000ud-IY for submit@debbugs.gnu.org; Thu, 20 Oct 2011 15:57:37 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([140.186.70.17]:43998) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGyk9-0000uR-6w for submit@debbugs.gnu.org; Thu, 20 Oct 2011 15:57:33 -0400 Received: from eggs.gnu.org ([140.186.70.92]:52501) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGyk6-00038V-TZ for bug-coreutils@gnu.org; Thu, 20 Oct 2011 15:57:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RGyk5-0000tX-5o for bug-coreutils@gnu.org; Thu, 20 Oct 2011 15:57:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50688) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGyk4-0000tL-RO; Thu, 20 Oct 2011 15:57:29 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p9KJvL3r011576 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 20 Oct 2011 15:57:21 -0400 Received: from [10.3.113.158] (ovpn-113-158.phx2.redhat.com [10.3.113.158]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p9KJvK0B013081; Thu, 20 Oct 2011 15:57:20 -0400 Message-ID: <4EA07D20.2050206@redhat.com> Date: Thu, 20 Oct 2011 13:57:20 -0600 From: Eric Blake Organization: Red Hat User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.23) Gecko/20110928 Fedora/3.1.15-1.fc14 Lightning/1.0b3pre Mnenhy/0.8.4 Thunderbird/3.1.15 MIME-Version: 1.0 References: <4EA05C9C.1070809@redhat.com> <4EA07AD0.2050908@cs.ucla.edu> In-Reply-To: <4EA07AD0.2050908@cs.ucla.edu> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.17 X-Spam-Score: -8.0 (--------) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -8.0 (--------) 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 > > 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 eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org From unknown Sat Sep 13 04:54:48 2025 X-Loop: help-debbugs@gnu.org Subject: bug#9813: rm -rf calls rmdir() prior to close(), which can fail Resent-From: Paul Eggert Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-coreutils@gnu.org Resent-Date: Thu, 20 Oct 2011 23:48:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 9813 X-GNU-PR-Package: coreutils X-GNU-PR-Keywords: To: Eric Blake Cc: bug-gnulib@gnu.org, 9813@debbugs.gnu.org Received: via spool by 9813-submit@debbugs.gnu.org id=B9813.13191544487961 (code B ref 9813); Thu, 20 Oct 2011 23:48:01 +0000 Received: (at 9813) by debbugs.gnu.org; 20 Oct 2011 23:47:28 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RH2Kc-00024K-Ke for submit@debbugs.gnu.org; Thu, 20 Oct 2011 19:47:28 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RH2KZ-00023x-BZ for 9813@debbugs.gnu.org; Thu, 20 Oct 2011 19:47:24 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id DCC8739E8007; Thu, 20 Oct 2011 16:46:06 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pLh38vQtZF1m; Thu, 20 Oct 2011 16:46:06 -0700 (PDT) Received: from [131.179.64.200] (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 1A8E239E8006; Thu, 20 Oct 2011 16:46:06 -0700 (PDT) Message-ID: <4EA0B2BD.5020101@cs.ucla.edu> Date: Thu, 20 Oct 2011 16:46:05 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.23) Gecko/20110928 Fedora/3.1.15-1.fc14 Thunderbird/3.1.15 MIME-Version: 1.0 References: <4EA05C9C.1070809@redhat.com> <4EA07AD0.2050908@cs.ucla.edu> <4EA07D20.2050206@redhat.com> In-Reply-To: <4EA07D20.2050206@redhat.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.1 (---) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.1 (---) 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". From unknown Sat Sep 13 04:54:48 2025 X-Loop: help-debbugs@gnu.org Subject: bug#9813: rm -rf calls rmdir() prior to close(), which can fail Resent-From: Eric Blake Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-coreutils@gnu.org Resent-Date: Fri, 21 Oct 2011 00:08:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 9813 X-GNU-PR-Package: coreutils X-GNU-PR-Keywords: To: Paul Eggert Cc: bug-gnulib@gnu.org, 9813@debbugs.gnu.org Received: via spool by 9813-submit@debbugs.gnu.org id=B9813.13191556479644 (code B ref 9813); Fri, 21 Oct 2011 00:08:01 +0000 Received: (at 9813) by debbugs.gnu.org; 21 Oct 2011 00:07:27 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RH2dz-0002VV-1y for submit@debbugs.gnu.org; Thu, 20 Oct 2011 20:07:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RH2du-0002VH-5r for 9813@debbugs.gnu.org; Thu, 20 Oct 2011 20:07:24 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p9L064ft009333 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 20 Oct 2011 20:06:04 -0400 Received: from [10.3.113.158] (ovpn-113-158.phx2.redhat.com [10.3.113.158]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p9L0633p005724; Thu, 20 Oct 2011 20:06:03 -0400 Message-ID: <4EA0B76B.7040104@redhat.com> Date: Thu, 20 Oct 2011 18:06:03 -0600 From: Eric Blake Organization: Red Hat User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.23) Gecko/20110928 Fedora/3.1.15-1.fc14 Lightning/1.0b3pre Mnenhy/0.8.4 Thunderbird/3.1.15 MIME-Version: 1.0 References: <4EA05C9C.1070809@redhat.com> <4EA07AD0.2050908@cs.ucla.edu> <4EA07D20.2050206@redhat.com> <4EA0B2BD.5020101@cs.ucla.edu> In-Reply-To: <4EA0B2BD.5020101@cs.ucla.edu> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-Spam-Score: -10.3 (----------) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -10.3 (----------) 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 eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org From unknown Sat Sep 13 04:54:48 2025 X-Loop: help-debbugs@gnu.org Subject: bug#9813: rm -rf calls rmdir() prior to close(), which can fail Resent-From: Eric Blake Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-coreutils@gnu.org Resent-Date: Fri, 21 Oct 2011 00:13:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 9813 X-GNU-PR-Package: coreutils X-GNU-PR-Keywords: Cc: Paul Eggert , bug-gnulib@gnu.org, 9813@debbugs.gnu.org Received: via spool by 9813-submit@debbugs.gnu.org id=B9813.131915596510088 (code B ref 9813); Fri, 21 Oct 2011 00:13:02 +0000 Received: (at 9813) by debbugs.gnu.org; 21 Oct 2011 00:12:45 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RH2j5-0002cd-Qi for submit@debbugs.gnu.org; Thu, 20 Oct 2011 20:12:44 -0400 Received: from mx1.redhat.com ([209.132.183.28]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RH2j3-0002cW-Ac for 9813@debbugs.gnu.org; Thu, 20 Oct 2011 20:12:42 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p9L0BSR6028990 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 20 Oct 2011 20:11:28 -0400 Received: from [10.3.113.158] (ovpn-113-158.phx2.redhat.com [10.3.113.158]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p9L0BRhS018719; Thu, 20 Oct 2011 20:11:28 -0400 Message-ID: <4EA0B8AF.9070505@redhat.com> Date: Thu, 20 Oct 2011 18:11:27 -0600 From: Eric Blake Organization: Red Hat User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.23) Gecko/20110928 Fedora/3.1.15-1.fc14 Lightning/1.0b3pre Mnenhy/0.8.4 Thunderbird/3.1.15 MIME-Version: 1.0 References: <4EA05C9C.1070809@redhat.com> <4EA07AD0.2050908@cs.ucla.edu> <4EA07D20.2050206@redhat.com> <4EA0B2BD.5020101@cs.ucla.edu> <4EA0B76B.7040104@redhat.com> In-Reply-To: <4EA0B76B.7040104@redhat.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Spam-Score: -9.7 (---------) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -9.7 (---------) On 10/20/2011 06:06 PM, Eric Blake wrote: > 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()). Also, notice that the POSIX requirement on unlink() is that ETXTBSY is a may fail (a file is currently being executed by some other process), but that EBUSY is a shall fail, with the same wording as for rmdir(), namely: [EBUSY] The file named by the path argument cannot be unlinked because it is being used by the system or another process and the implementation considers this an error. This "shall fail" EBUSY is _how_ NFS justifies their behavior of failing to unlink files with open fds, even though I agree with you that it flies in the face of traditional Unix semantics, and explains why many GNU programs have already made efforts to ensure that all fds to a file are closed before attempting unlink/rmdir. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org From unknown Sat Sep 13 04:54:48 2025 X-Loop: help-debbugs@gnu.org Subject: bug#9813: rm -rf calls rmdir() prior to close(), which can fail Resent-From: Paul Eggert Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-coreutils@gnu.org Resent-Date: Fri, 21 Oct 2011 05:33:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 9813 X-GNU-PR-Package: coreutils X-GNU-PR-Keywords: To: Eric Blake Cc: bug-gnulib@gnu.org, 9813@debbugs.gnu.org Received: via spool by 9813-submit@debbugs.gnu.org id=B9813.13191751405599 (code B ref 9813); Fri, 21 Oct 2011 05:33:02 +0000 Received: (at 9813) by debbugs.gnu.org; 21 Oct 2011 05:32:20 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RH7iN-0001SF-4f for submit@debbugs.gnu.org; Fri, 21 Oct 2011 01:32:19 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RH7iK-0001S2-Hd for 9813@debbugs.gnu.org; Fri, 21 Oct 2011 01:32:18 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 6E5F9A60005; Thu, 20 Oct 2011 22:30:58 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Y+LUkITHNJwZ; Thu, 20 Oct 2011 22:30:57 -0700 (PDT) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 7DE0339E8007; Thu, 20 Oct 2011 22:30:57 -0700 (PDT) Message-ID: <4EA1038C.4090107@cs.ucla.edu> Date: Thu, 20 Oct 2011 22:30:52 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.23) Gecko/20110922 Thunderbird/3.1.15 MIME-Version: 1.0 References: <4EA05C9C.1070809@redhat.com> <4EA07AD0.2050908@cs.ucla.edu> <4EA07D20.2050206@redhat.com> <4EA0B2BD.5020101@cs.ucla.edu> <4EA0B76B.7040104@redhat.com> In-Reply-To: <4EA0B76B.7040104@redhat.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Score: -2.9 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.9 (--) 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. From unknown Sat Sep 13 04:54:48 2025 MIME-Version: 1.0 X-Mailer: MIME-tools 5.427 (Entity 5.427) X-Loop: help-debbugs@gnu.org From: help-debbugs@gnu.org (GNU bug Tracking System) To: Eric Blake Subject: bug#9813: closed (Re: rm -rf calls rmdir() prior to close(), which can fail) Message-ID: References: <87ipnfe8fl.fsf@rho.meyering.net> <4EA05C9C.1070809@redhat.com> X-Gnu-PR-Message: they-closed 9813 X-Gnu-PR-Package: coreutils Reply-To: 9813@debbugs.gnu.org Date: Sun, 23 Oct 2011 20:56:02 +0000 Content-Type: multipart/mixed; boundary="----------=_1319403362-31655-1" This is a multi-part message in MIME format... ------------=_1319403362-31655-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Your bug report #9813: rm -rf calls rmdir() prior to close(), which can fail which was filed against the coreutils package, has been closed. The explanation is attached below, along with your original report. If you require more details, please reply to 9813@debbugs.gnu.org. --=20 9813: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D9813 GNU Bug Tracking System Contact help-debbugs@gnu.org with problems ------------=_1319403362-31655-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at 9813-done) by debbugs.gnu.org; 23 Oct 2011 20:55:06 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RI54T-0008DU-Uv for submit@debbugs.gnu.org; Sun, 23 Oct 2011 16:55:06 -0400 Received: from mx.meyering.net ([88.168.87.75]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RI54Q-0008DM-IC for 9813-done@debbugs.gnu.org; Sun, 23 Oct 2011 16:55:04 -0400 Received: from rho.meyering.net (localhost.localdomain [127.0.0.1]) by rho.meyering.net (Acme Bit-Twister) with ESMTP id 2A4FA60079; Sun, 23 Oct 2011 22:53:34 +0200 (CEST) From: Jim Meyering To: Eric Blake Subject: Re: rm -rf calls rmdir() prior to close(), which can fail In-Reply-To: <4EA05C9C.1070809@redhat.com> (Eric Blake's message of "Thu, 20 Oct 2011 11:38:36 -0600") References: <4EA05C9C.1070809@redhat.com> Date: Sun, 23 Oct 2011 22:53:34 +0200 Message-ID: <87ipnfe8fl.fsf@rho.meyering.net> Lines: 190 MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -2.8 (--) X-Debbugs-Envelope-To: 9813-done Cc: cygwin@cygwin.com, bug-gnulib , 9813-done@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.8 (--) 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 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 + + 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 + 2011-10-23 Gary V. Vaughan Bruno Haible Jim Meyering diff --git a/lib/fts.c b/lib/fts.c index e3829f3..f61a91e 100644 --- a/lib/fts.c +++ b/lib/fts.c @@ -229,11 +229,6 @@ static int fts_safe_changedir (FTS *, FTSENT *, int, const char *) #define ISSET(opt) (sp->fts_options & (opt)) #define SET(opt) (sp->fts_options |= (opt)) -/* FIXME: make this a function */ -#define RESTORE_INITIAL_CWD(sp) \ - (fd_ring_clear (&((sp)->fts_fd_ring)), \ - FCHDIR ((sp), (ISSET (FTS_CWDFD) ? AT_FDCWD : (sp)->fts_rfd))) - /* FIXME: FTS_NOCHDIR is now misnamed. Call it FTS_USE_FULL_RELATIVE_FILE_NAMES instead. */ #define FCHDIR(sp, fd) \ @@ -349,6 +344,18 @@ cwd_advance_fd (FTS *sp, int fd, bool chdir_down_one) sp->fts_cwd_fd = fd; } +/* Restore the initial, pre-traversal, "working directory". + In FTS_CWDFD mode, we merely call cwd_advance_fd, otherwise, + we may actually change the working directory. + Return 0 upon success. Upon failure, set errno and return nonzero. */ +static int +restore_initial_cwd (FTS *sp) +{ + int fail = FCHDIR (sp, ISSET (FTS_CWDFD) ? AT_FDCWD : sp->fts_rfd); + fd_ring_clear (&(sp->fts_fd_ring)); + return fail; +} + /* Open the directory DIR if possible, and return a file descriptor. Return -1 and set errno on failure. It doesn't matter whether the file descriptor has read or write access. */ @@ -948,7 +955,7 @@ next: tmp = p; * root. */ if (p->fts_level == FTS_ROOTLEVEL) { - if (RESTORE_INITIAL_CWD(sp)) { + if (restore_initial_cwd(sp)) { SET(FTS_STOP); return (NULL); } @@ -1055,7 +1062,7 @@ cd_dot_dot: * one level, via "..". */ if (p->fts_level == FTS_ROOTLEVEL) { - if (RESTORE_INITIAL_CWD(sp)) { + if (restore_initial_cwd(sp)) { p->fts_errno = errno; SET(FTS_STOP); } @@ -1579,7 +1586,7 @@ mem1: saved_errno = errno; */ if (!continue_readdir && descend && (type == BCHILD || !nitems) && (cur->fts_level == FTS_ROOTLEVEL - ? RESTORE_INITIAL_CWD(sp) + ? restore_initial_cwd(sp) : fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) { cur->fts_info = FTS_ERR; SET(FTS_STOP); -- 1.7.7.419.g87009 ------------=_1319403362-31655-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at submit) by debbugs.gnu.org; 20 Oct 2011 17:40:09 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RGwb7-0001yC-TL for submit@debbugs.gnu.org; Thu, 20 Oct 2011 13:40:07 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RGwb2-0001xV-EO for submit@debbugs.gnu.org; Thu, 20 Oct 2011 13:40:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RGwZn-0003yl-Vl for submit@debbugs.gnu.org; Thu, 20 Oct 2011 13:38:45 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([140.186.70.17]:45108) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGwZn-0003yc-Rt for submit@debbugs.gnu.org; Thu, 20 Oct 2011 13:38:43 -0400 Received: from eggs.gnu.org ([140.186.70.92]:41549) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGwZl-0004hU-4D for bug-coreutils@gnu.org; Thu, 20 Oct 2011 13:38:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RGwZi-0003xk-Vy for bug-coreutils@gnu.org; Thu, 20 Oct 2011 13:38:41 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52415) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGwZi-0003xG-MB; Thu, 20 Oct 2011 13:38:38 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p9KHcav6011331 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 20 Oct 2011 13:38:37 -0400 Received: from [10.3.113.158] (ovpn-113-158.phx2.redhat.com [10.3.113.158]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p9KHcaJf019394; Thu, 20 Oct 2011 13:38:36 -0400 Message-ID: <4EA05C9C.1070809@redhat.com> Date: Thu, 20 Oct 2011 11:38:36 -0600 From: Eric Blake Organization: Red Hat User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.23) Gecko/20110928 Fedora/3.1.15-1.fc14 Lightning/1.0b3pre Mnenhy/0.8.4 Thunderbird/3.1.15 MIME-Version: 1.0 To: bug-coreutils , bug-gnulib Subject: rm -rf calls rmdir() prior to close(), which can fail Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.17 X-Spam-Score: -8.0 (--------) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -8.0 (--------) 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 eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org ------------=_1319403362-31655-1-- From unknown Sat Sep 13 04:54:48 2025 X-Loop: help-debbugs@gnu.org Subject: bug#9813: rm -rf calls rmdir() prior to close(), which can fail Resent-From: Jim Meyering Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-coreutils@gnu.org Resent-Date: Mon, 24 Oct 2011 09:00:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 9813 X-GNU-PR-Package: coreutils X-GNU-PR-Keywords: To: Eric Blake Cc: cygwin@cygwin.com, bug-gnulib , 9813@debbugs.gnu.org Received: via spool by 9813-submit@debbugs.gnu.org id=B9813.13194467813509 (code B ref 9813); Mon, 24 Oct 2011 09:00:02 +0000 Received: (at 9813) by debbugs.gnu.org; 24 Oct 2011 08:59:41 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RIGNg-0000uY-O7 for submit@debbugs.gnu.org; Mon, 24 Oct 2011 04:59:41 -0400 Received: from mx.meyering.net ([88.168.87.75]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RIGNc-0000uO-Te for 9813@debbugs.gnu.org; Mon, 24 Oct 2011 04:59:39 -0400 Received: from rho.meyering.net (localhost.localdomain [127.0.0.1]) by rho.meyering.net (Acme Bit-Twister) with ESMTP id 7FDF460039; Mon, 24 Oct 2011 10:58:05 +0200 (CEST) From: Jim Meyering In-Reply-To: <87d3dmerh9.fsf@rho.meyering.net> (Jim Meyering's message of "Mon, 24 Oct 2011 10:14:26 +0200") References: <4EA05C9C.1070809@redhat.com> <87ipnfe8fl.fsf@rho.meyering.net> <87d3dmerh9.fsf@rho.meyering.net> Date: Mon, 24 Oct 2011 10:58:05 +0200 Message-ID: <8739eiepgi.fsf@rho.meyering.net> Lines: 110 MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -2.8 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.8 (--) 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 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 160000 --- 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 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 - #include - -/* 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 #include #include "version.h" -- 1.7.7.419.g87009 From unknown Sat Sep 13 04:54:48 2025 X-Loop: help-debbugs@gnu.org Subject: bug#9813: rm -rf calls rmdir() prior to close(), which can fail Resent-From: Eric Blake Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-coreutils@gnu.org Resent-Date: Mon, 24 Oct 2011 14:00:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 9813 X-GNU-PR-Package: coreutils X-GNU-PR-Keywords: To: Jim Meyering Cc: cygwin@cygwin.com, bug-gnulib , 9813@debbugs.gnu.org Received: via spool by 9813-submit@debbugs.gnu.org id=B9813.1319464798701 (code B ref 9813); Mon, 24 Oct 2011 14:00:02 +0000 Received: (at 9813) by debbugs.gnu.org; 24 Oct 2011 13:59:58 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RIL4H-0000BC-7C for submit@debbugs.gnu.org; Mon, 24 Oct 2011 09:59:58 -0400 Received: from mx1.redhat.com ([209.132.183.28]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RIL4D-0000Ay-4w for 9813@debbugs.gnu.org; Mon, 24 Oct 2011 09:59:55 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p9ODvxdn000571 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 24 Oct 2011 09:57:59 -0400 Received: from [10.3.113.133] (ovpn-113-133.phx2.redhat.com [10.3.113.133]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p9ODvwmX019184; Mon, 24 Oct 2011 09:57:58 -0400 Message-ID: <4EA56EE5.7060204@redhat.com> Date: Mon, 24 Oct 2011 07:57:57 -0600 From: Eric Blake Organization: Red Hat User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.23) Gecko/20110928 Fedora/3.1.15-1.fc14 Lightning/1.0b3pre Mnenhy/0.8.4 Thunderbird/3.1.15 MIME-Version: 1.0 References: <4EA05C9C.1070809@redhat.com> <87ipnfe8fl.fsf@rho.meyering.net> <87d3dmerh9.fsf@rho.meyering.net> <8739eiepgi.fsf@rho.meyering.net> In-Reply-To: <8739eiepgi.fsf@rho.meyering.net> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -10.3 (----------) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -10.3 (----------) 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 eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org From unknown Sat Sep 13 04:54:48 2025 X-Loop: help-debbugs@gnu.org Subject: bug#9813: rm -rf calls rmdir() prior to close(), which can fail Resent-From: Jim Meyering Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-coreutils@gnu.org Resent-Date: Mon, 24 Oct 2011 14:23:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 9813 X-GNU-PR-Package: coreutils X-GNU-PR-Keywords: To: Eric Blake Cc: 9813@debbugs.gnu.org Received: via spool by 9813-submit@debbugs.gnu.org id=B9813.13194661562691 (code B ref 9813); Mon, 24 Oct 2011 14:23:01 +0000 Received: (at 9813) by debbugs.gnu.org; 24 Oct 2011 14:22:36 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RILQB-0000hM-Rn for submit@debbugs.gnu.org; Mon, 24 Oct 2011 10:22:36 -0400 Received: from mx.meyering.net ([88.168.87.75]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RILQ8-0000h8-OW for 9813@debbugs.gnu.org; Mon, 24 Oct 2011 10:22:34 -0400 Received: from rho.meyering.net (localhost.localdomain [127.0.0.1]) by rho.meyering.net (Acme Bit-Twister) with ESMTP id 657D260039; Mon, 24 Oct 2011 16:21:00 +0200 (CEST) From: Jim Meyering In-Reply-To: <4EA56EE5.7060204@redhat.com> (Eric Blake's message of "Mon, 24 Oct 2011 07:57:57 -0600") References: <4EA05C9C.1070809@redhat.com> <87ipnfe8fl.fsf@rho.meyering.net> <87d3dmerh9.fsf@rho.meyering.net> <8739eiepgi.fsf@rho.meyering.net> <4EA56EE5.7060204@redhat.com> Date: Mon, 24 Oct 2011 16:21:00 +0200 Message-ID: <877h3ucvxv.fsf@rho.meyering.net> Lines: 39 MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -2.8 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.8 (--) 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 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