From owner-freebsd-bugs Sat Sep 9 12:20:11 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id C663137B422 for ; Sat, 9 Sep 2000 12:20:01 -0700 (PDT) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id MAA13237; Sat, 9 Sep 2000 12:20:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Date: Sat, 9 Sep 2000 12:20:01 -0700 (PDT) Message-Id: <200009091920.MAA13237@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Gerhard Sittig Subject: Re: bin/21017: mtree's "no such file" message at job's end Reply-To: Gerhard Sittig Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org The following reply was made to PR bin/21017; it has been noted by GNATS. From: Gerhard Sittig To: FreeBSD-gnats-submit@freebsd.org Cc: Subject: Re: bin/21017: mtree's "no such file" message at job's end Date: Sat, 9 Sep 2000 20:14:07 +0200 On Thu, Sep 07, 2000 at 21:08 +0200, Gerhard Sittig wrote: >=20 > In the end I can only see two reasons for mtree's failure: > - readlink(2) barfs on broken symlinks under not known yet > conditions (after "long" runs?) and does so unpredictably > - mtree fails to chdir(2) to the new directory and therefor fails > to read _any_ file there with a relative pathname Obviously I haven't seen the third opportunity: - mtree(1) (or fts(3) used by mtree) should either chdir(2) and readlink(2) with a relative path or stay in the -p base and readlink(2) with a pathname relative to the basedir. see below > Once I can find another spare moment I will try to dump the > relevant info of the readlink invocation's environment (current > dir, fts' root + path + filename, fts' already provided slink > and access failure info, etc). After applying the patch cited below (inspired by Jos Backus' hint) and running another session I got these results: ----------------------------------------------------------------- $ cd /usr/src/usr.sbin/mtree $ cvs diff -u=20 cvs diff: Diffing . Index: compare.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/usr.sbin/mtree/compare.c,v retrieving revision 1.15.2.1 diff -u -r1.15.2.1 compare.c --- compare.c 2000/06/28 02:33:17 1.15.2.1 +++ compare.c 2000/09/09 14:02:49 @@ -64,6 +64,7 @@ extern int lineno; =20 static char *ftype __P((u_int)); +static char *rlink_check __P((char *, FTSENT *)); =20 #define INDENTNAMELEN 8 #define LABEL \ @@ -298,7 +299,7 @@ } #endif /* RMD160 */ =20 - if (s->flags & F_SLINK && strcmp(cp =3D rlink(name), s->slink)) { + if (s->flags & F_SLINK && strcmp(cp =3D rlink_check(name, p), s->slink)) { LABEL; (void)printf("%slink ref (%s, %s)\n", tab, cp, s->slink); } @@ -353,6 +354,44 @@ return ("unknown"); } /* NOTREACHED */ +} + +char * +rlink_check(name, p) + char *name; + FTSENT *p; +{ +#if 1 + FILE *f; + char *buf; + + if (errno) { + warn("nonzero errno before readlink(2)"); + } + + f =3D fopen("/var/tmp/mtree.log", "a"); + if (f) { + buf =3D getcwd(NULL, 0); + fprintf(f, "cwd=3D%s\n", buf); + free(buf); buf =3D NULL; + + fprintf(f, "name=3D%s\n", name); + + fprintf(f, "fts_info=3D%hu\n", p->fts_info); + fprintf(f, "fts_accpath=3D%s\n", p->fts_accpath); + fprintf(f, "fts_path=3D%s\n", p->fts_path); + fprintf(f, "fts_name=3D%s\n", p->fts_name); + fprintf(f, "fts_level=3D%h\n", p->fts_level); + fprintf(f, "fts_errno=3D%d\n", p->fts_errno); + + fprintf(f, "\n"); + fclose(f); + } else { + warn("logfile problem in rlink_check()"); + } +#endif + + return(rlink(name)); } =20 char * $ strings /usr/obj/usr/src/usr.sbin/mtree/mtree | grep rlink logfile problem in rlink_check() $ truss /usr/obj/usr/src/usr.sbin/mtree/mtree \ -K $KEYS -p /usr -x -X $DB/_usr.ex < $DB/_usr.db \ 2>&1 >/dev/null | tail -100 read(0x3,0xbfbff16c,0x400) =3D 0 (0x0) close(3) =3D 0 (0x0) open("./compat/linux/usr/lib/python1.5/site-packages/rpmmodule.so",0,027757= 772554) =3D 3 (0x3) read(0x3,0xbfbff16c,0x400) =3D 1024 (0x400) =2E.. read(0x3,0xbfbff16c,0x400) =3D 1024 (0x400) read(0x3,0xbfbff16c,0x400) =3D 168 (0xa8) read(0x3,0xbfbff16c,0x400) =3D 0 (0x0) close(3) =3D 0 (0x0) open("./compat/linux/usr/lib/python1.5/site-packages/rpmmodule.so",0,027757= 772554) =3D 3 (0x3) read(0x3,0xbfbff16c,0x400) =3D 1024 (0x400) =2E.. read(0x3,0xbfbff16c,0x400) =3D 1024 (0x400) read(0x3,0xbfbff16c,0x400) =3D 168 (0xa8) read(0x3,0xbfbff16c,0x400) =3D 0 (0x0) close(3) =3D 0 (0x0) open("/var/tmp/mtree.log",521,0666) =3D 3 (0x3) lseek(3,0x0,2) =3D 0 (0x0) sigaction(SIGSYS,0xbfbff4b8,0xbfbff4a0) =3D 0 (0x0) __getcwd(0xd2da400,0x3fc) =3D 0 (0x0) sigaction(SIGSYS,0xbfbff4a0,0x0) =3D 0 (0x0) fstat(3,0xbfbff1b0) =3D 0 (0x0) write(3,0xd2de000,142) =3D 142 (0x8e) close(3) =3D 0 (0x0) readlink("X11",0x804f160,1023) ERR#2 'No such file or directory' mtree: write(2,0xbfbfeda8,7) =3D 7 (0x7) line 1361949: X11write(2,0xbfbfedd8,17) =3D 17 (0x11) : write(2,0xbfbfed98,2) =3D 2 (0x2) No such file or directory write(2,0xbfbfed98,26) =3D 26 (0x1a) sigprocmask(0x1,0x280605a0,0xbfbff440) =3D 0 (0x0) sigprocmask(0x3,0x280605b0,0x0) =3D 0 (0x0) write(1,0xd2da000,357) =3D 357 (0x165) exit(0x1) process exit, rval =3D 256 $ file /var/tmp/mtree.log /var/tmp/mtree.log: ASCII text $ tail -100 /var/tmp/mtree.log cwd=3D/usr name=3DX11 fts_info=3D13 fts_accpath=3D./compat/linux/usr/lib/X11 fts_path=3D./compat/linux/usr/lib/X11 fts_name=3DX11 fts_level=3D fts_errno=3D0 ----------------------------------------------------------------- This means that by chance(?) the broken symlink is the first symlink at all in the /usr fs. So I went and "fixed" mtree with the following patch: BTW: Labouring on the topic and using sysmouse for transferring the reports and diffs between machines I'm *very* urged to go and make scmouse work in the _expected_ way. Has nobody ever noticed it's "broken" (I couldn't see a PR in up to and including #21086)? At the very least it's inconsistent with xterm and rather annoying. Prepare to see another PR on this very subject soon ... :> ----------------------------------------------------------------- --- compare.c 2000/06/28 02:33:17 1.15.2.1 +++ compare.c 2000/09/09 15:20:41 @@ -298,7 +298,7 @@ } #endif /* RMD160 */ - if (s->flags & F_SLINK && strcmp(cp =3D rlink(name), s->slink)) { + if (s->flags & F_SLINK && strcmp(cp =3D rlink(p->fts_accpath), s->s= link)) { LABEL; (void)printf("%slink ref (%s, %s)\n", tab, cp, s->slink); } ----------------------------------------------------------------- This patch makes mtree(1) work again. But I'm still not clear as to whether fts(3) has chdir(2) problems (or if it should chdir(2) at all) or if it's mtree(1)'s fault damaging the current directory setting somehow. Having a closer look at the compare() function everywhere fts_accpath is used and the name parameter seems to be for logging or relative pathname database creation only. So it all could have been this simple and the problem is solved and closed? But I still feel mtree should have failed for *any* symlink not residing in the -p base before. Hmmm ... virtually yours 82D1 9B9C 01DC 4FB4 D7B4 61BE 3F49 4F77 72DE DA76 Gerhard Sittig true | mail -s "get gpg key" Gerhard.Sittig@gmx.net --=20 If you don't understand or are scared by any of the above ask your parents or an adult to help you. :r !ssh -l admin 192.168.11.142 cat /var/tmp/mtree.scr Script started on Sat Sep 9 16:06:02 2000 organ# pwd /usr/src/usr.sbin/mtree organ# ^D=08=08exit Script done on Sat Sep 9 16:08:31 2000 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message