Date: Sat, 9 Sep 2000 12:20:01 -0700 (PDT) From: Gerhard Sittig <Gerhard.Sittig@gmx.net> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/21017: mtree's "no such file" message at job's end Message-ID: <200009091920.MAA13237@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/21017; it has been noted by GNATS.
From: Gerhard Sittig <Gerhard.Sittig@gmx.net>
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200009091920.MAA13237>
