Re: bin/169723: [patch] find(1) exits with non-zero return code if any file in a directory is deleted while find(1) is traversing the directory

2012-07-20 Thread jilles
Synopsis: [patch] find(1) exits with non-zero return code if any file in a 
directory is deleted while find(1) is traversing the directory

Responsible-Changed-From-To: freebsd-bugs-jilles
Responsible-Changed-By: jilles
Responsible-Changed-When: Fri Jul 20 10:12:44 UTC 2012
Responsible-Changed-Why: 
I'll take it.

http://www.freebsd.org/cgi/query-pr.cgi?pr=169723
___
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to freebsd-bugs-unsubscr...@freebsd.org


Re: bin/169723: [patch] find(1) exits with non-zero return code if any file in a directory is deleted while find(1) is traversing the directory

2012-07-17 Thread Andrey Ignatov
The following reply was made to PR bin/169723; it has been noted by GNATS.

From: Andrey Ignatov r...@rdna.ru
To: Jilles Tjoelker jil...@stack.nl
Cc: bug-follo...@freebsd.org, Valery Khromov qwe...@yandex-team.ru
Subject: Re: bin/169723: [patch] find(1) exits with non-zero return code if
 any file in a directory is deleted while find(1) is traversing the directory
Date: Tue, 17 Jul 2012 21:53:16 +0400

 --LQksG6bCIzRHxTLp
 Content-Type: text/plain; charset=koi8-r
 Content-Disposition: inline
 
 Hi, Jilles!
 
 Thank you for the information!
 
 We've taken into account all your points and impletemted both options
 (-ignore_readdir_race and -noignore_readdir_race). The default behaviour
 is -noignore_readdir_race.
 The patch is attached as well as the new Makefile to test it.
 
 Jilles Tjoelker jil...@stack.nl [2012-07-15 19:43]:
  In PR 169723, you wrote:
   [find(1) prints an error message if a file is deleted between readdir
   and stat or opendir]
  
  This patch appears to match the description of
  -ignore_readdir_race in the documentation of GNU find. Perhaps it is
  appropriate to suppress these error messages only if
  -ignore_readdir_race is given (and -noignore_readdir_race is not given
  afterwards).
  
  Furthermore, it only seems appropriate to me to suppress the error for
  FTS_DNR and FTS_NS. FTS_ERR covers things like inability to open .
  which should never fail (so if they do, find(1) should tell the user
  about it).
  
  -- 
  Jilles Tjoelker
 
 -- 
 Andrey Ignatov
 
 --LQksG6bCIzRHxTLp
 Content-Type: text/x-diff; charset=koi8-r
 Content-Disposition: attachment; 
filename=freebsd9-ignore_readdir_race_v4.patch
 
 Index: usr.bin/find/find.1
 ===
 --- usr.bin/find/find.1(revision 238532)
 +++ usr.bin/find/find.1(working copy)
 @@ -467,7 +467,10 @@
  .Ar gname
  is treated as a group ID.
  .It Ic -ignore_readdir_race
 -This option is for GNU find compatibility and is ignored.
 +Ignore errors which occur if a file or a directory in a starting point gets
 +deleted between reading the name and calling stat on it while find is
 +traversing the starting point.
 +This option doesn't affect errors occuring on starting points.
  .It Ic -ilname Ar pattern
  Like
  .Ic -lname ,
 @@ -615,7 +618,9 @@
  .It Ic -nogroup
  True if the file belongs to an unknown group.
  .It Ic -noignore_readdir_race
 -This option is for GNU find compatibility and is ignored.
 +Turn off the effect of
 +.Ic -ignore_readdir_race .
 +This is default behaviour.
  .It Ic -noleaf
  This option is for GNU find compatibility.
  In GNU find it disables an optimization not relevant to 
 Index: usr.bin/find/find.c
 ===
 --- usr.bin/find/find.c(revision 238532)
 +++ usr.bin/find/find.c(working copy)
 @@ -197,8 +197,11 @@
continue;
break;
case FTS_DNR:
 +  case FTS_NS:
 +  if (ignore_readdir_race 
 +  entry-fts_errno == ENOENT  entry-fts_level)
 +  continue;
case FTS_ERR:
 -  case FTS_NS:
(void)fflush(stdout);
warnx(%s: %s,
entry-fts_path, strerror(entry-fts_errno));
 @@ -228,7 +231,7 @@
for (p = plan; p  (p-execute)(p, entry); p = p-next);
}
finish_execplus();
 -  if (errno)
 +  if (errno  (!ignore_readdir_race || errno != ENOENT))
err(1, fts_read);
return (rval);
  }
 Index: usr.bin/find/main.c
 ===
 --- usr.bin/find/main.c(revision 238532)
 +++ usr.bin/find/main.c(working copy)
 @@ -64,6 +64,7 @@
  time_t now;   /* time find was run */
  int dotfd;/* starting directory */
  int ftsoptions;   /* options for the ftsopen(3) call */
 +int ignore_readdir_race = 0;  /* ignore readdir race */
  int isdeprecated; /* using deprecated syntax */
  int isdepth;  /* do directories on post-order visit */
  int isoutput; /* user specified output operator */
 Index: usr.bin/find/function.c
 ===
 --- usr.bin/find/function.c(revision 238532)
 +++ usr.bin/find/function.c(working copy)
 @@ -975,6 +975,25 @@
  }
  
  /*
 + * -ignore_readdir_race functions --
 + *
 + *Always true. Ignore errors which occur if a file or a directory
 + *in a starting point gets deleted between reading the name and calling
 + *stat on it while find is traversing the starting point.
 + */
 +
 +PLAN *
 +c_ignore_readdir_race(OPTION *option, char ***argvp __unused)
 +{
 +  if (strcmp(option-name, -ignore_readdir_race) == 0)
 +  

Re: bin/169723: [patch] find(1) exits with non-zero return code if any file in a directory is deleted while find(1) is traversing the directory

2012-07-15 Thread Jilles Tjoelker
The following reply was made to PR bin/169723; it has been noted by GNATS.

From: Jilles Tjoelker jil...@stack.nl
To: bug-follo...@freebsd.org, r...@rdna.ru
Cc:  
Subject: Re: bin/169723: [patch] find(1) exits with non-zero return code if
 any file in a directory is deleted while find(1) is traversing the directory
Date: Sun, 15 Jul 2012 17:43:53 +0200

 In PR 169723, you wrote:
  [find(1) prints an error message if a file is deleted between readdir
  and stat or opendir]
 
 This patch appears to match the description of
 -ignore_readdir_race in the documentation of GNU find. Perhaps it is
 appropriate to suppress these error messages only if
 -ignore_readdir_race is given (and -noignore_readdir_race is not given
 afterwards).
 
 Furthermore, it only seems appropriate to me to suppress the error for
 FTS_DNR and FTS_NS. FTS_ERR covers things like inability to open .
 which should never fail (so if they do, find(1) should tell the user
 about it).
 
 -- 
 Jilles Tjoelker
___
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to freebsd-bugs-unsubscr...@freebsd.org


bin/169723: [patch] find(1) exits with non-zero return code if any file in a directory is deleted while find(1) is traversing the directory

2012-07-08 Thread Andrey Ignatov

Number: 169723
Category:   bin
Synopsis:   [patch] find(1) exits with non-zero return code if any file in 
a directory is deleted while find(1) is traversing the directory
Confidential:   no
Severity:   non-critical
Priority:   low
Responsible:freebsd-bugs
State:  open
Quarter:
Keywords:   
Date-Required:
Class:  sw-bug
Submitter-Id:   current-users
Arrival-Date:   Sun Jul 08 22:50:06 UTC 2012
Closed-Date:
Last-Modified:
Originator: Andrey Ignatov
Release:FreeBSD 10.0-CURRENT amd64
Organization:
Yandex
Environment:
System: FreeBSD rdna-s761.yandex.ru 10.0-CURRENT FreeBSD 10.0-CURRENT #0 
r228743M: Sat Dec 31 15:15:00 MSK 2011 
r...@rdna.yandex.ru:/usr/obj/usr/src/sys/RDNA amd64

It seems that the problem appears in find(1) on many versions of FreeBSD
(8-10 at least).

Description:
find(1) exits with non-zero return code if any file in a directory is deleted
while find(1) is traversing the directory, even though the file is completely
out of find's expression.

For example, we can run:
% find /path/to/some/dir/ -type f -a ! -name '*some_mask*'

Then while find is traversing the directory /path/to/some/dir/ we remove some
files which is out of the expression:
% rm /path/to/some/dir/*some_mask*

(Note: I use ! in the expression)

After this find finishes with the result like this:
find: /path/to/some/dir/some_mask: No such file or directory
% echo $?
1

How-To-Repeat:
It's easy to reproduce the problem by using attached Makefile. Just run `make 
all'.

Fix:
The patch is in attached freebsd-find-ENOENT-and-removed-files.patch file.

Reported and patched by: Valery Khromov qwe...@yandex-team.ru

--- Makefile begins here ---
D:=testdir
FIND?=find

all: prepare
$(MAKE) -j16 mkfiles rmfiles find

mkfiles:
dd if=/dev/urandom | hexdump -e ' 8/1 %02x \n' | while read i ; 
do touch $(D)/$$i; done

rmfiles:
while :; do rm -f $(D)/*; sleep 1; done

find:
while :; do $(FIND) $(D)/ -type f -name '*NAME*' || echo FAILED; done

prepare:
rm -rf $(D)
mkdir -p $(D)
--- Makefile ends here ---

--- freebsd-find-ENOENT-and-removed-files.patch begins here ---
Index: /usr/src/usr.bin/find/find.c
===
--- /usr/src/usr.bin/find/find.c(revision 228743)
+++ /usr/src/usr.bin/find/find.c(working copy)
@@ -199,6 +199,8 @@
case FTS_DNR:
case FTS_ERR:
case FTS_NS:
+   if (entry-fts_errno == ENOENT)
+   continue;
(void)fflush(stdout);
warnx(%s: %s,
entry-fts_path, strerror(entry-fts_errno));
--- freebsd-find-ENOENT-and-removed-files.patch ends here ---


Release-Note:
Audit-Trail:
Unformatted:
___
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to freebsd-bugs-unsubscr...@freebsd.org