Module Name: src Committed By: maxv Date: Thu Dec 19 07:14:07 UTC 2019
Modified Files: src/usr.bin/make: Makefile compat.c make.1 meta.c Log Message: Revert the filemon removal in bmake, as pointed out by maya we do care about not introducing divergence with FreeBSD, and the cost of unused is acceptable here. To generate a diff of this commit: cvs rdiff -u -r1.64 -r1.65 src/usr.bin/make/Makefile cvs rdiff -u -r1.108 -r1.109 src/usr.bin/make/compat.c cvs rdiff -u -r1.275 -r1.276 src/usr.bin/make/make.1 cvs rdiff -u -r1.72 -r1.73 src/usr.bin/make/meta.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/make/Makefile diff -u src/usr.bin/make/Makefile:1.64 src/usr.bin/make/Makefile:1.65 --- src/usr.bin/make/Makefile:1.64 Wed Dec 18 07:37:19 2019 +++ src/usr.bin/make/Makefile Thu Dec 19 07:14:07 2019 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.64 2019/12/18 07:37:19 maxv Exp $ +# $NetBSD: Makefile,v 1.65 2019/12/19 07:14:07 maxv Exp $ # @(#)Makefile 5.2 (Berkeley) 12/28/90 PROG= make @@ -17,6 +17,10 @@ USE_META ?= yes .if ${USE_META:tl} != "no" SRCS+= meta.c CPPFLAGS+= -DUSE_META +FILEMON_H ?= ${.CURDIR:H:H}/sys/dev/filemon/filemon.h +.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h" +COPTS.meta.c += -DHAVE_FILEMON_H -I${FILEMON_H:H} +.endif .endif .PATH: ${.CURDIR}/lst.lib Index: src/usr.bin/make/compat.c diff -u src/usr.bin/make/compat.c:1.108 src/usr.bin/make/compat.c:1.109 --- src/usr.bin/make/compat.c:1.108 Wed Dec 18 07:37:19 2019 +++ src/usr.bin/make/compat.c Thu Dec 19 07:14:07 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: compat.c,v 1.108 2019/12/18 07:37:19 maxv Exp $ */ +/* $NetBSD: compat.c,v 1.109 2019/12/19 07:14:07 maxv Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -70,14 +70,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: compat.c,v 1.108 2019/12/18 07:37:19 maxv Exp $"; +static char rcsid[] = "$NetBSD: compat.c,v 1.109 2019/12/19 07:14:07 maxv Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: compat.c,v 1.108 2019/12/18 07:37:19 maxv Exp $"); +__RCSID("$NetBSD: compat.c,v 1.109 2019/12/19 07:14:07 maxv Exp $"); #endif #endif /* not lint */ #endif @@ -426,6 +426,11 @@ again: status = WSTOPSIG(reason); /* stopped */ } else if (WIFEXITED(reason)) { status = WEXITSTATUS(reason); /* exited */ +#if defined(USE_META) && defined(USE_FILEMON_ONCE) + if (useMeta) { + meta_cmd_finish(NULL); + } +#endif if (status != 0) { if (DEBUG(ERROR)) { fprintf(debug_file, "\n*** Failed target: %s\n*** Failed command: ", Index: src/usr.bin/make/make.1 diff -u src/usr.bin/make/make.1:1.275 src/usr.bin/make/make.1:1.276 --- src/usr.bin/make/make.1:1.275 Wed Dec 18 07:37:19 2019 +++ src/usr.bin/make/make.1 Thu Dec 19 07:14:07 2019 @@ -1,4 +1,4 @@ -.\" $NetBSD: make.1,v 1.275 2019/12/18 07:37:19 maxv Exp $ +.\" $NetBSD: make.1,v 1.276 2019/12/19 07:14:07 maxv Exp $ .\" .\" Copyright (c) 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" -.Dd December 17, 2019 +.Dd February 16, 2019 .Dt MAKE 1 .Os .Sh NAME @@ -883,7 +883,10 @@ into "compat" mode. Puts .Nm into "meta" mode, where meta files are created for each target -to capture the command run. +to capture the command run, the output generated and if +.Xr filemon 4 +is available, the system calls which are of interest to +.Nm . The captured output can be very useful when diagnosing errors. .It Pa curdirOk= Ar bf Normally @@ -971,6 +974,13 @@ by appending their names to is re-exported whenever .Ql Va .MAKEOVERRIDES is modified. +.It Va .MAKE.PATH_FILEMON +If +.Nm +was built with +.Xr filemon 4 +support, this is set to the path of the device node. +This allows makefiles to test for this support. .It Va .MAKE.PID The process-id of .Nm . Index: src/usr.bin/make/meta.c diff -u src/usr.bin/make/meta.c:1.72 src/usr.bin/make/meta.c:1.73 --- src/usr.bin/make/meta.c:1.72 Wed Dec 18 10:30:23 2019 +++ src/usr.bin/make/meta.c Thu Dec 19 07:14:07 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: meta.c,v 1.72 2019/12/18 10:30:23 martin Exp $ */ +/* $NetBSD: meta.c,v 1.73 2019/12/19 07:14:07 maxv Exp $ */ /* * Implement 'meta' mode. @@ -46,6 +46,13 @@ #include "make.h" #include "job.h" +#ifdef HAVE_FILEMON_H +# include <filemon.h> +#endif +#if !defined(USE_FILEMON) && defined(FILEMON_SET_FD) +# define USE_FILEMON +#endif + static BuildMon Mybm; /* for compat */ static Lst metaBailiwick; /* our scope of control */ static char *metaBailiwickStr; /* string storage for the list */ @@ -93,6 +100,100 @@ extern char **environ; #endif /* + * Filemon is a kernel module which snoops certain syscalls. + * + * C chdir + * E exec + * F [v]fork + * L [sym]link + * M rename + * R read + * W write + * S stat + * + * See meta_oodate below - we mainly care about 'E' and 'R'. + * + * We can still use meta mode without filemon, but + * the benefits are more limited. + */ +#ifdef USE_FILEMON +# ifndef _PATH_FILEMON +# define _PATH_FILEMON "/dev/filemon" +# endif + +/* + * Open the filemon device. + */ +static void +filemon_open(BuildMon *pbm) +{ + int retry; + + pbm->mon_fd = pbm->filemon_fd = -1; + if (!useFilemon) + return; + + for (retry = 5; retry >= 0; retry--) { + if ((pbm->filemon_fd = open(_PATH_FILEMON, O_RDWR)) >= 0) + break; + } + + if (pbm->filemon_fd < 0) { + useFilemon = FALSE; + warn("Could not open %s", _PATH_FILEMON); + return; + } + + /* + * We use a file outside of '.' + * to avoid a FreeBSD kernel bug where unlink invalidates + * cwd causing getcwd to do a lot more work. + * We only care about the descriptor. + */ + pbm->mon_fd = mkTempFile("filemon.XXXXXX", NULL); + if (ioctl(pbm->filemon_fd, FILEMON_SET_FD, &pbm->mon_fd) < 0) { + err(1, "Could not set filemon file descriptor!"); + } + /* we don't need these once we exec */ + (void)fcntl(pbm->mon_fd, F_SETFD, FD_CLOEXEC); + (void)fcntl(pbm->filemon_fd, F_SETFD, FD_CLOEXEC); +} + +/* + * Read the build monitor output file and write records to the target's + * metadata file. + */ +static int +filemon_read(FILE *mfp, int fd) +{ + char buf[BUFSIZ]; + int n; + int error; + + /* Check if we're not writing to a meta data file.*/ + if (mfp == NULL) { + if (fd >= 0) + close(fd); /* not interested */ + return 0; + } + /* rewind */ + (void)lseek(fd, (off_t)0, SEEK_SET); + + error = 0; + fprintf(mfp, "\n-- filemon acquired metadata --\n"); + + while ((n = read(fd, buf, sizeof(buf))) > 0) { + if ((int)fwrite(buf, 1, n, mfp) < n) + error = EIO; + } + fflush(mfp); + if (close(fd) < 0) + error = errno; + return error; +} +#endif + +/* * when realpath() fails, * we use this, to clean up ./ and ../ */ @@ -467,6 +568,10 @@ boolValue(char *s) void meta_init(void) { +#ifdef USE_FILEMON + /* this allows makefiles to test if we have filemon support */ + Var_Set(".MAKE.PATH_FILEMON", _PATH_FILEMON, VAR_GLOBAL, 0); +#endif } @@ -568,6 +673,18 @@ meta_job_start(Job *job, GNode *gn) pbm = &Mybm; } pbm->mfp = meta_create(pbm, gn); +#ifdef USE_FILEMON_ONCE + /* compat mode we open the filemon dev once per command */ + if (job == NULL) + return; +#endif +#ifdef USE_FILEMON + if (pbm->mfp != NULL && useFilemon) { + filemon_open(pbm); + } else { + pbm->mon_fd = pbm->filemon_fd = -1; + } +#endif } /* @@ -577,6 +694,26 @@ meta_job_start(Job *job, GNode *gn) void meta_job_child(Job *job) { +#ifdef USE_FILEMON + BuildMon *pbm; + + if (job != NULL) { + pbm = &job->bm; + } else { + pbm = &Mybm; + } + if (pbm->mfp != NULL) { + close(fileno(pbm->mfp)); + if (useFilemon) { + pid_t pid; + + pid = getpid(); + if (ioctl(pbm->filemon_fd, FILEMON_SET_PID, &pid) < 0) { + err(1, "Could not set filemon pid!"); + } + } + } +#endif } void @@ -649,11 +786,24 @@ meta_cmd_finish(void *pbmp) { int error = 0; BuildMon *pbm = pbmp; +#ifdef USE_FILEMON + int x; +#endif if (!pbm) pbm = &Mybm; - fprintf(pbm->mfp, "\n"); /* ensure end with newline */ +#ifdef USE_FILEMON + if (pbm->filemon_fd >= 0) { + if (close(pbm->filemon_fd) < 0) + error = errno; + x = filemon_read(pbm->mfp, pbm->mon_fd); + if (error == 0 && x != 0) + error = x; + pbm->filemon_fd = pbm->mon_fd = -1; + } else +#endif + fprintf(pbm->mfp, "\n"); /* ensure end with newline */ return error; } @@ -1442,6 +1592,18 @@ static int childPipe[2]; void meta_compat_start(void) { +#ifdef USE_FILEMON_ONCE + /* + * We need to re-open filemon for each cmd. + */ + BuildMon *pbm = &Mybm; + + if (pbm->mfp != NULL && useFilemon) { + filemon_open(pbm); + } else { + pbm->mon_fd = pbm->filemon_fd = -1; + } +#endif if (pipe(childPipe) < 0) Punt("Cannot create pipe: %s", strerror(errno)); /* Set close-on-exec flag for both */