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
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
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
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
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