Source-Changes-HG archive

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

[src/trunk]: src/usr.bin/make Per sjg's suggestion, split filemon API into se...



details:   https://anonhg.NetBSD.org/src/rev/f48f5e1de878
branches:  trunk
changeset: 968543:f48f5e1de878
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Jan 19 19:49:36 2020 +0000

description:
Per sjg's suggestion, split filemon API into separate back ends.

By default we use the ktrace back end, but the /dev/filemon back end
is available as a compile-time option, by setting USE_FILEMON=dev in
make.  sjg raised concerns about ktrace performance and would like to
continue using /dev/filemon on FreeBSD (which has seen more
maintenance kernel-side) without forking make.

diffstat:

 usr.bin/make/Makefile                 |    7 +-
 usr.bin/make/filemon.c                |  870 ---------------------------------
 usr.bin/make/filemon.h                |   50 -
 usr.bin/make/filemon/filemon.h        |   53 ++
 usr.bin/make/filemon/filemon_dev.c    |  151 +++++
 usr.bin/make/filemon/filemon_ktrace.c |  876 ++++++++++++++++++++++++++++++++++
 usr.bin/make/meta.c                   |    8 +-
 7 files changed, 1088 insertions(+), 927 deletions(-)

diffs (truncated from 2078 to 300 lines):

diff -r 082cc3b28833 -r f48f5e1de878 usr.bin/make/Makefile
--- a/usr.bin/make/Makefile     Sun Jan 19 19:42:32 2020 +0000
+++ b/usr.bin/make/Makefile     Sun Jan 19 19:49:36 2020 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.66 2020/01/19 19:42:32 riastradh Exp $
+#      $NetBSD: Makefile,v 1.67 2020/01/19 19:49:36 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
-USE_FILEMON ?= yes
+USE_FILEMON ?= ktrace
 .if ${USE_FILEMON:tl} != "no"
-SRCS+= filemon.c
+.PATH: ${.CURDIR}/filemon
+SRCS+= filemon_${USE_FILEMON}.c
 CPPFLAGS+= -DUSE_FILEMON
 .endif
 .endif
diff -r 082cc3b28833 -r f48f5e1de878 usr.bin/make/filemon.c
--- a/usr.bin/make/filemon.c    Sun Jan 19 19:42:32 2020 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,870 +0,0 @@
-/*     $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;
-
-       /* If we're not open, nothing to do.  */
-       if (F->out == NULL)
-               return 0;
-
-       /*
-        * Flush it, close it, and null it unconditionally, but be
-        * careful to return the earliest error in errno.
-        */
-       if (fflush(F->out) == EOF && error == 0)
-               error = errno;
-       if (fclose(F->out) == EOF && error == 0)
-               error = errno;
-       F->out = NULL;
-
-       /* Set errno and return -1 if anything went wrong.  */
-       if (error) {
-               errno = error;
-               return -1;
-       }
-
-       /* Success!  */
-       return 0;
-}
-
-/*
- * filemon_setfd(F, fd)
- *
- *     Cause filemon activity on F to be sent to fd.  Claims ownership
- *     of fd; caller should not use fd afterward, and any duplicates
- *     of fd may see their file positions changed.
- */
-int
-filemon_setfd(struct filemon *F, int fd)
-{
-



Home | Main Index | Thread Index | Old Index