Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make Reimplement make(1) meta mode without filemon(4).



details:   https://anonhg.NetBSD.org/src/rev/4b91e7516fff
branches:  trunk
changeset: 1006577:4b91e7516fff
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Jan 19 19:42:32 2020 +0000

description:
Reimplement make(1) meta mode without filemon(4).

diffstat:

 usr.bin/make/Makefile  |    9 +-
 usr.bin/make/compat.c  |    8 +-
 usr.bin/make/filemon.c |  870 +++++++++++++++++++++++++++++++++++++++++++++++++
 usr.bin/make/filemon.h |   50 ++
 usr.bin/make/job.c     |   72 +++-
 usr.bin/make/meta.c    |  170 +++++++--
 usr.bin/make/meta.h    |    9 +-
 7 files changed, 1129 insertions(+), 59 deletions(-)

diffs (truncated from 1451 to 300 lines):

diff -r 6fc06065be59 -r 4b91e7516fff usr.bin/make/Makefile
--- a/usr.bin/make/Makefile     Sun Jan 19 18:34:24 2020 +0000
+++ b/usr.bin/make/Makefile     Sun Jan 19 19:42:32 2020 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.65 2019/12/19 07:14:07 maxv Exp $
+#      $NetBSD: Makefile,v 1.66 2020/01/19 19:42:32 riastradh Exp $
 #      @(#)Makefile    5.2 (Berkeley) 12/28/90
 
 PROG=  make
@@ -17,9 +17,10 @@
 .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}
+USE_FILEMON ?= yes
+.if ${USE_FILEMON:tl} != "no"
+SRCS+= filemon.c
+CPPFLAGS+= -DUSE_FILEMON
 .endif
 .endif
 
diff -r 6fc06065be59 -r 4b91e7516fff usr.bin/make/compat.c
--- a/usr.bin/make/compat.c     Sun Jan 19 18:34:24 2020 +0000
+++ b/usr.bin/make/compat.c     Sun Jan 19 19:42:32 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: compat.c,v 1.109 2019/12/19 07:14:07 maxv Exp $        */
+/*     $NetBSD: compat.c,v 1.110 2020/01/19 19:42:32 riastradh 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.109 2019/12/19 07:14:07 maxv Exp $";
+static char rcsid[] = "$NetBSD: compat.c,v 1.110 2020/01/19 19:42:32 riastradh 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.109 2019/12/19 07:14:07 maxv Exp $");
+__RCSID("$NetBSD: compat.c,v 1.110 2020/01/19 19:42:32 riastradh Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -404,7 +404,7 @@
 
 #ifdef USE_META
     if (useMeta) {
-       meta_compat_parent();
+       meta_compat_parent(cpid);
     }
 #endif
 
diff -r 6fc06065be59 -r 4b91e7516fff usr.bin/make/filemon.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/filemon.c    Sun Jan 19 19:42:32 2020 +0000
@@ -0,0 +1,870 @@
+/*     $NetBSD: filemon.c,v 1.1 2020/01/19 19:42:32 riastradh Exp $    */
+
+/*-
+ * Copyright (c) 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef USE_FILEMON
+
+#include "filemon.h"
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/rbtree.h>
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+
+#include <sys/ktrace.h>
+
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "make.h"
+
+#ifndef AT_CWD
+#define AT_CWD -1
+#endif
+
+struct filemon;
+struct filemon_key;
+struct filemon_state;
+
+typedef struct filemon_state *filemon_syscall_t(struct filemon *,
+    const struct filemon_key *, const struct ktr_syscall *);
+
+static filemon_syscall_t filemon_sys_chdir;
+static filemon_syscall_t filemon_sys_execve;
+static filemon_syscall_t filemon_sys_exit;
+static filemon_syscall_t filemon_sys_fork;
+static filemon_syscall_t filemon_sys_link;
+static filemon_syscall_t filemon_sys_open;
+static filemon_syscall_t filemon_sys_openat;
+static filemon_syscall_t filemon_sys_symlink;
+static filemon_syscall_t filemon_sys_unlink;
+static filemon_syscall_t filemon_sys_rename;
+
+static filemon_syscall_t *const filemon_syscalls[] = {
+       [SYS_chdir] = &filemon_sys_chdir,
+       [SYS_execve] = &filemon_sys_execve,
+       [SYS_exit] = &filemon_sys_exit,
+       [SYS_fork] = &filemon_sys_fork,
+       [SYS_link] = &filemon_sys_link,
+       [SYS_open] = &filemon_sys_open,
+       [SYS_openat] = &filemon_sys_openat,
+       [SYS_symlink] = &filemon_sys_symlink,
+       [SYS_unlink] = &filemon_sys_unlink,
+       [SYS_rename] = &filemon_sys_rename,
+};
+
+struct filemon {
+       int                     ktrfd; /* kernel writes ktrace events here */
+       FILE                    *in;   /* we read ktrace events from here */
+       FILE                    *out;  /* we write filemon events to here */
+       rb_tree_t               active;
+       pid_t                   child;
+
+       /* I/O state machine.  */
+       enum {
+               FILEMON_START = 0,
+               FILEMON_HEADER,
+               FILEMON_PAYLOAD,
+               FILEMON_ERROR,
+       }                       state;
+       unsigned char           *p;
+       size_t                  resid;
+
+       /* I/O buffer.  */
+       struct ktr_header       hdr;
+       union {
+               struct ktr_syscall      syscall;
+               struct ktr_sysret       sysret;
+               char                    namei[PATH_MAX];
+               unsigned char           buf[4096];
+       }                       payload;
+};
+
+struct filemon_state {
+       struct filemon_key {
+               pid_t           pid;
+               lwpid_t         lid;
+       }               key;
+       struct rb_node  node;
+       int             syscode;
+       void            (*show)(struct filemon *, const struct filemon_state *,
+                           const struct ktr_sysret *);
+       unsigned        i;
+       unsigned        npath;
+       char            *path[/*npath*/];
+};
+
+static int
+compare_filemon_states(void *cookie MAKE_ATTR_UNUSED, const void *na,
+    const void *nb)
+{
+       const struct filemon_state *Sa = na;
+       const struct filemon_state *Sb = nb;
+
+       if (Sa->key.pid < Sb->key.pid)
+               return -1;
+       if (Sa->key.pid > Sb->key.pid)
+               return +1;
+       if (Sa->key.lid < Sb->key.lid)
+               return -1;
+       if (Sa->key.lid > Sb->key.lid)
+               return +1;
+       return 0;
+}
+
+static int
+compare_filemon_key(void *cookie MAKE_ATTR_UNUSED, const void *n,
+    const void *k)
+{
+       const struct filemon_state *S = n;
+       const struct filemon_key *key = k;
+
+       if (S->key.pid < key->pid)
+               return -1;
+       if (S->key.pid > key->pid)
+               return +1;
+       if (S->key.lid < key->lid)
+               return -1;
+       if (S->key.lid > key->lid)
+               return +1;
+       return 0;
+}
+
+static const rb_tree_ops_t filemon_rb_ops = {
+       .rbto_compare_nodes = &compare_filemon_states,
+       .rbto_compare_key = &compare_filemon_key,
+       .rbto_node_offset = offsetof(struct filemon_state, node),
+       .rbto_context = NULL,
+};
+
+/*
+ * filemon_open()
+ *
+ *     Allocate a filemon descriptor.  Returns NULL and sets errno on
+ *     failure.
+ */
+struct filemon *
+filemon_open(void)
+{
+       struct filemon *F;
+       int ktrpipe[2];
+       int error;
+
+       /* Allocate and zero a struct filemon object.  */
+       F = calloc(1, sizeof(*F));
+       if (F == NULL)
+               return NULL;
+
+       /* Create a pipe for ktrace events.  */
+       if (pipe2(ktrpipe, O_CLOEXEC|O_NONBLOCK) == -1) {
+               error = errno;
+               goto fail0;
+       }
+
+       /* Create a file stream for reading the ktrace events.  */
+       if ((F->in = fdopen(ktrpipe[0], "r")) == NULL) {
+               error = errno;
+               goto fail1;
+       }
+       ktrpipe[0] = -1;        /* claimed by fdopen */
+
+       /*
+        * Set the fd for writing ktrace events and initialize the
+        * rbtree.  The rest can be safely initialized to zero.
+        */
+       F->ktrfd = ktrpipe[1];
+       rb_tree_init(&F->active, &filemon_rb_ops);
+
+       /* Success!  */
+       return F;
+
+fail2: __unused
+       (void)fclose(F->in);
+fail1: (void)close(ktrpipe[0]);
+       (void)close(ktrpipe[1]);
+fail0: free(F);
+       errno = error;
+       return NULL;
+}
+
+/*
+ * filemon_closefd(F)
+ *
+ *     Internal subroutine to try to flush and close the output file.
+ *     If F is not open for output, do nothing.  Never leaves F open
+ *     for output even on failure.  Returns 0 on success; sets errno
+ *     and return -1 on failure.
+ */
+static int
+filemon_closefd(struct filemon *F)
+{
+       int error = 0;



Home | Main Index | Thread Index | Old Index