Module Name: src Committed By: sjg Date: Thu Sep 9 00:10:16 UTC 2010
Added Files: src/sys/dev/filemon: filemon.c filemon.h filemon_wrapper.c mknod-sh src/sys/modules/filemon: Makefile Log Message: First cut of simple syscall wrapper, which make(1) can use to track process activity. To generate a diff of this commit: cvs rdiff -u -r0 -r1.1 src/sys/dev/filemon/filemon.c \ src/sys/dev/filemon/filemon.h src/sys/dev/filemon/filemon_wrapper.c \ src/sys/dev/filemon/mknod-sh cvs rdiff -u -r0 -r1.1 src/sys/modules/filemon/Makefile Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Added files: Index: src/sys/dev/filemon/filemon.c diff -u /dev/null src/sys/dev/filemon/filemon.c:1.1 --- /dev/null Thu Sep 9 00:10:16 2010 +++ src/sys/dev/filemon/filemon.c Thu Sep 9 00:10:16 2010 @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2010, Juniper Networks, Inc. + * + * 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 COPYRIGHT HOLDERS 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 COPYRIGHT + * OWNER 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. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: filemon.c,v 1.1 2010/09/09 00:10:16 sjg Exp $"); + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/conf.h> +#include <sys/file.h> +#include <sys/filedesc.h> +#include <sys/systm.h> +#include <sys/buf.h> +#include <sys/fcntl.h> +#include <sys/rwlock.h> +#include <sys/condvar.h> +#include <sys/lwp.h> +#include <sys/proc.h> +#include <sys/kmem.h> +#include <sys/syslog.h> + +#include "filemon.h" + +MODULE(MODULE_CLASS_DRIVER, filemon, NULL); + +static dev_type_open(filemon_open); + +static struct cdevsw filemon_cdevsw = { + .d_open = filemon_open, + .d_flag = D_MPSAFE, + .d_close = noclose, + .d_read = noread, + .d_write = nowrite, + .d_ioctl = noioctl, + .d_stop = nostop, + .d_tty = notty, + .d_poll = nopoll, + .d_mmap = nommap, + .d_kqfilter = nokqfilter, +}; + +static int filemon_ioctl(struct file *, u_long, void *); +static int filemon_close(struct file *); + +static const struct fileops filemon_fileops = { + .fo_ioctl = filemon_ioctl, + .fo_close = filemon_close, + .fo_read = fbadop_read, + .fo_write = fbadop_write, + .fo_fcntl = fnullop_fcntl, + .fo_poll = fnullop_poll, + .fo_stat = fbadop_stat, + .fo_kqfilter = fnullop_kqfilter, +}; + +static krwlock_t filemon_mtx; + +static TAILQ_HEAD(, filemon) filemons_inuse = + TAILQ_HEAD_INITIALIZER(filemons_inuse); + +#ifdef DEBUG +static int logLevel = LOG_DEBUG; +#endif + +void +filemon_output(struct filemon * filemon, char *msg, size_t len) +{ + struct uio auio; + struct iovec aiov; + + if (filemon->fm_fp == NULL) + return; + + aiov.iov_base = msg; + aiov.iov_len = len; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_resid = len; + auio.uio_rw = UIO_WRITE; + auio.uio_offset = (off_t) - 1; + uio_setup_sysspace(&auio); + +#ifdef DEBUG + { + char *cp; + int x = 16; + + cp = strchr(msg, '\n'); + if (cp && cp - msg <= 16) + x = (cp - msg) - 2; + log(logLevel, "filemont_output:('%.*s%s'", x, + (x < 16) ? "..." : "", msg); + } +#endif + (*filemon->fm_fp->f_ops->fo_write) (filemon->fm_fp, + &(filemon->fm_fp->f_offset), + &auio, curlwp->l_cred, FOF_UPDATE_OFFSET); +} + +static void +filemon_comment(struct filemon * filemon) +{ + int len; + + len = snprintf(filemon->fm_msgbufr, sizeof(filemon->fm_msgbufr), + "# filemon version 2\n# Target pid %d\nV 2\n", + curproc->p_pid); + + filemon_output(filemon, filemon->fm_msgbufr, len); +} + + +static struct filemon * +filemon_pid_check(struct proc * p) +{ + struct filemon *filemon; + + TAILQ_FOREACH(filemon, &filemons_inuse, fm_link) { + if (p->p_pid == filemon->fm_pid) + return (filemon); + } + + if (p->p_pptr == NULL) + return (NULL); + + return (filemon_pid_check(p->p_pptr)); +} + +/* + * return exclusive access to a filemon struct + */ +struct filemon * +filemon_lookup(struct proc * p) +{ + struct filemon *filemon; + + rw_enter(&filemon_mtx, RW_READER); + filemon = filemon_pid_check(p); + if (filemon) { + rw_enter(&filemon->fm_mtx, RW_WRITER); + } + rw_exit(&filemon_mtx); + return filemon; +} + +static struct filemon * +filemon_fp_data(struct file * fp, int lck) +{ + struct filemon *filemon; + + rw_enter(&filemon_mtx, RW_READER); + filemon = fp->f_data; + if (filemon && lck) { + rw_enter(&filemon->fm_mtx, lck); + } + rw_exit(&filemon_mtx); + return filemon; +} + +static int n_open = 0; + +static int +filemon_open(dev_t dev, int oflags __unused, int mode __unused, + struct lwp * l __unused) +{ + struct filemon *filemon; + struct file *fp; + int error, fd; + + /* falloc() will use the descriptor for us. */ + if ((error = fd_allocfile(&fp, &fd)) != 0) + return error; + + filemon = kmem_alloc(sizeof(struct filemon), KM_SLEEP); + if (!filemon) + return ENOMEM; + + rw_init(&filemon->fm_mtx); + filemon->fm_fd = -1; + filemon->fm_fp = NULL; + filemon->fm_pid = curproc->p_pid; + + rw_enter(&filemon_mtx, RW_WRITER); + n_open++; + + TAILQ_INSERT_TAIL(&filemons_inuse, filemon, fm_link); + + rw_exit(&filemon_mtx); + return fd_clone(fp, fd, oflags, &filemon_fileops, filemon); +} + + +static int +filemon_close(struct file * fp) +{ + struct filemon *filemon; + +#ifdef DEBUG + log(logLevel, "filemon_close()"); +#endif + /* + * Follow the same lock order as filemon_lookup() + * and filemon_fp_data() but hold exclusive access to + * filemon_mtx until we are done. + */ + rw_enter(&filemon_mtx, RW_WRITER); + filemon = fp->f_data; + if (!filemon) { + rw_exit(&filemon_mtx); + return EBADF; + } + /* ensure that filemon_lookup() will now fail */ + TAILQ_REMOVE(&filemons_inuse, filemon, fm_link); + n_open--; + /* ensure that filemon_fp_data() will now fail */ + fp->f_data = NULL; + + /* + * once we have exclusive access, it should never be used again + */ + rw_enter(&filemon->fm_mtx, RW_WRITER); + if (filemon->fm_fp) { + fd_putfile(filemon->fm_fd); /* release our reference */ + filemon->fm_fp = NULL; + } + rw_exit(&filemon->fm_mtx); + rw_destroy(&filemon->fm_mtx); + kmem_free(filemon, sizeof(struct filemon)); + rw_exit(&filemon_mtx); + return (0); +} + +static int +filemon_ioctl(struct file * fp, u_long cmd, void *data) +{ + int error = 0; + struct filemon *filemon; + + +#ifdef DEBUG + log(logLevel, "filemon_ioctl(%lu)", cmd);; +#endif + + /* + * this ensures we cannot get filemon if it is closing. + */ + filemon = filemon_fp_data(fp, RW_WRITER); + if (!filemon) + return EBADF; + + switch (cmd) { + case FILEMON_SET_FD: + /* Set the output file descriptor. */ + filemon->fm_fd = *((int *) data); + if ((filemon->fm_fp = fd_getfile(filemon->fm_fd)) == NULL) { + rw_exit(&filemon->fm_mtx); + return EBADF; + } + /* Write the file header. */ + filemon_comment(filemon); + break; + + case FILEMON_SET_PID: + /* Set the monitored process ID. */ + filemon->fm_pid = *((pid_t *) data); + break; + + default: + error = EINVAL; + break; + } + + rw_exit(&filemon->fm_mtx); + return (error); +} + +static void +filemon_load(void *dummy __unused) +{ + rw_init(&filemon_mtx); + + /* Install the syscall wrappers. */ + filemon_wrapper_install(); +} + + +static int +filemon_unload(void) +{ + int error = 0; + + rw_enter(&filemon_mtx, RW_WRITER); + + if (TAILQ_FIRST(&filemons_inuse) != NULL) + error = EBUSY; + else { + /* Deinstall the syscall wrappers. */ + filemon_wrapper_deinstall(); + } + rw_exit(&filemon_mtx); + + if (error == 0) { + rw_destroy(&filemon_mtx); + } + return (error); +} + +static int +filemon_modcmd(modcmd_t cmd, void *data) +{ + int error = 0; + int bmajor = -1; + int cmajor = -1; + + switch (cmd) { + case MODULE_CMD_INIT: +#ifdef DEBUG + logLevel = LOG_INFO; +#endif + + filemon_load(data); + error = devsw_attach("filemon", NULL, &bmajor, + &filemon_cdevsw, &cmajor); + break; + + case MODULE_CMD_FINI: + error = filemon_unload(); + if (!error) + error = devsw_detach(NULL, &filemon_cdevsw); + break; + + case MODULE_CMD_STAT: + log(LOG_INFO, "filemon: open=%d", n_open); + break; + + default: + error = EOPNOTSUPP; + break; + + } + + return (error); +} Index: src/sys/dev/filemon/filemon.h diff -u /dev/null src/sys/dev/filemon/filemon.h:1.1 --- /dev/null Thu Sep 9 00:10:16 2010 +++ src/sys/dev/filemon/filemon.h Thu Sep 9 00:10:16 2010 @@ -0,0 +1,52 @@ +/* $NetBSD: filemon.h,v 1.1 2010/09/09 00:10:16 sjg Exp $ */ +/* + * Copyright (c) 2010, Juniper Networks, Inc. + * + * 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 COPYRIGHT HOLDERS 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 COPYRIGHT + * OWNER 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. + */ +#ifndef FILEMON_SET_FD + +#ifndef _PATH_FILEMON +#define _PATH_FILEMON "/dev/filemon" +#endif +#define FILEMON_SET_FD _IOWR('S', 1, int) +#define FILEMON_SET_PID _IOWR('S', 2, pid_t) + +#ifdef _KERNEL +struct filemon { + pid_t fm_pid; /* The process ID being monitored. */ + char fm_fname1[MAXPATHLEN];/* Temporary filename buffer. */ + char fm_fname2[MAXPATHLEN];/* Temporary filename buffer. */ + char fm_msgbufr[32 + 2 * MAXPATHLEN]; /* Output message buffer. */ + int fm_fd; /* Output fd */ + struct file *fm_fp; /* Output file pointer. */ + krwlock_t fm_mtx; /* Lock mutex for this filemon. */ + TAILQ_ENTRY(filemon) fm_link; /* Link into the in-use list. */ +}; + +struct filemon * filemon_lookup(struct proc *); +void filemon_output(struct filemon *, char *, size_t); +void filemon_wrapper_install(void); +void filemon_wrapper_deinstall(void); +#endif + +#endif Index: src/sys/dev/filemon/filemon_wrapper.c diff -u /dev/null src/sys/dev/filemon/filemon_wrapper.c:1.1 --- /dev/null Thu Sep 9 00:10:16 2010 +++ src/sys/dev/filemon/filemon_wrapper.c Thu Sep 9 00:10:16 2010 @@ -0,0 +1,385 @@ +/* + * Copyright (c) 2010, Juniper Networks, Inc. + * + * 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 COPYRIGHT HOLDERS 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 COPYRIGHT + * OWNER 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. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: filemon_wrapper.c,v 1.1 2010/09/09 00:10:16 sjg Exp $"); + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/fcntl.h> +#include <sys/kernel.h> +#include <sys/lwp.h> +#include <sys/proc.h> +#include <sys/syscall.h> +#include <sys/syscallargs.h> + +#include "filemon.h" + +static int +filemon_wrapper_chdir(struct lwp * l, const struct sys_chdir_args * uap, + register_t * retval) +{ + int ret; + int error; + size_t done; + size_t len; + struct filemon *filemon; + + if ((ret = sys_chdir(l, uap, retval)) == 0) { + filemon = filemon_lookup(curproc); + + if (filemon) { + + error = copyinstr(SCARG(uap, path), filemon->fm_fname1, + sizeof(filemon->fm_fname1), &done); + if (error == 0) { + len = snprintf(filemon->fm_msgbufr, + sizeof(filemon->fm_msgbufr), + "C %d %s\n", + curproc->p_pid, filemon->fm_fname1); + + filemon_output(filemon, filemon->fm_msgbufr, + len); + } + rw_exit(&filemon->fm_mtx); + } + } + return (ret); +} + +static int +filemon_wrapper_execve(struct lwp * l, struct sys_execve_args * uap, + register_t * retval) +{ + char fname[MAXPATHLEN]; + int ret; + int error; + size_t done; + size_t len; + struct filemon *filemon; + + error = copyinstr(SCARG(uap, path), fname, sizeof(fname), &done); + + if ((ret = sys_execve(l, uap, retval)) == 0 && error == 0) { + filemon = filemon_lookup(curproc); + + if (filemon) { + + len = snprintf(filemon->fm_msgbufr, sizeof(filemon->fm_msgbufr), + "E %d %s\n", + curproc->p_pid, fname); + + filemon_output(filemon, filemon->fm_msgbufr, len); + rw_exit(&filemon->fm_mtx); + } + } + return (ret); +} + + +static int +filemon_wrapper_fork(struct lwp * l, const void *v, register_t * retval) +{ + int ret; + size_t len; + struct filemon *filemon; + + if ((ret = sys_fork(l, v, retval)) == 0) { + filemon = filemon_lookup(curproc); + + if (filemon) { + len = snprintf(filemon->fm_msgbufr, + sizeof(filemon->fm_msgbufr), + "F %d %ld\n", + curproc->p_pid, (long) retval[0]); + + filemon_output(filemon, filemon->fm_msgbufr, len); + + rw_exit(&filemon->fm_mtx); + } + } + return (ret); +} + +static int +filemon_wrapper_vfork(struct lwp * l, const void *v, register_t * retval) +{ + int ret; + size_t len; + struct filemon *filemon; + + if ((ret = sys_vfork(l, v, retval)) == 0) { + filemon = filemon_lookup(curproc); + + if (filemon) { + len = snprintf(filemon->fm_msgbufr, + sizeof(filemon->fm_msgbufr), + "F %d %ld\n", + curproc->p_pid, (long) retval[0]); + + filemon_output(filemon, filemon->fm_msgbufr, len); + + rw_exit(&filemon->fm_mtx); + } + } + return (ret); +} + +static int +filemon_wrapper_open(struct lwp * l, struct sys_open_args * uap, + register_t * retval) +{ + int ret; + int error; + size_t done; + size_t len; + struct filemon *filemon; + + if ((ret = sys_open(l, uap, retval)) == 0) { + filemon = filemon_lookup(curproc); + + if (filemon) { + error = copyinstr(SCARG(uap, path), filemon->fm_fname1, + sizeof(filemon->fm_fname1), &done); + if (error == 0) { + len = snprintf(filemon->fm_msgbufr, + sizeof(filemon->fm_msgbufr), + "%c %d %s\n", + (SCARG(uap, flags) & O_ACCMODE) ? 'W' : 'R', + curproc->p_pid, filemon->fm_fname1); + + filemon_output(filemon, filemon->fm_msgbufr, + len); + } + rw_exit(&filemon->fm_mtx); + } + } + return (ret); +} + +static int +filemon_wrapper_rename(struct lwp * l, struct sys_rename_args * uap, + register_t * retval) +{ + int ret; + int error; + size_t done; + size_t len; + struct filemon *filemon; + + if ((ret = sys_rename(l, uap, retval)) == 0) { + filemon = filemon_lookup(curproc); + + if (filemon) { + error = copyinstr(SCARG(uap, from), filemon->fm_fname1, + sizeof(filemon->fm_fname1), &done); + if (error == 0) + error = copyinstr(SCARG(uap, to), + filemon->fm_fname2, + sizeof(filemon->fm_fname2), &done); + if (error == 0) { + len = snprintf(filemon->fm_msgbufr, + sizeof(filemon->fm_msgbufr), + "M %d '%s' '%s'\n", + curproc->p_pid, filemon->fm_fname1, + filemon->fm_fname2); + + filemon_output(filemon, filemon->fm_msgbufr, + len); + } + rw_exit(&filemon->fm_mtx); + } + } + return (ret); +} + +static int +filemon_wrapper_link(struct lwp * l, struct sys_link_args * uap, + register_t * retval) +{ + int ret; + int error; + size_t done; + size_t len; + struct filemon *filemon; + + if ((ret = sys_link(l, uap, retval)) == 0) { + filemon = filemon_lookup(curproc); + + if (filemon) { + error = copyinstr(SCARG(uap, path), + filemon->fm_fname1, sizeof(filemon->fm_fname1), + &done); + if (error == 0) + error = copyinstr(SCARG(uap, link), + filemon->fm_fname2, + sizeof(filemon->fm_fname2), &done); + if (error == 0) { + len = snprintf(filemon->fm_msgbufr, + sizeof(filemon->fm_msgbufr), "L %d '%s' '%s'\n", + curproc->p_pid, filemon->fm_fname1, + filemon->fm_fname2); + + filemon_output(filemon, filemon->fm_msgbufr, + len); + } + rw_exit(&filemon->fm_mtx); + } + } + return (ret); +} + +static int +filemon_wrapper_symlink(struct lwp * l, struct sys_symlink_args * uap, + register_t * retval) +{ + int ret; + int error; + size_t done; + size_t len; + struct filemon *filemon; + + if ((ret = sys_symlink(l, uap, retval)) == 0) { + filemon = filemon_lookup(curproc); + + if (filemon) { + error = copyinstr(SCARG(uap, path), + filemon->fm_fname1, + sizeof(filemon->fm_fname1), &done); + if (error == 0) + error = copyinstr(SCARG(uap, link), + filemon->fm_fname2, + sizeof(filemon->fm_fname2), &done); + if (error == 0) { + len = snprintf(filemon->fm_msgbufr, + sizeof(filemon->fm_msgbufr), + "L %d '%s' '%s'\n", + curproc->p_pid, filemon->fm_fname1, + filemon->fm_fname2); + + filemon_output(filemon, filemon->fm_msgbufr, + len); + } + rw_exit(&filemon->fm_mtx); + } + } + return (ret); +} + + +static void +filemon_wrapper_sys_exit(struct lwp * l, struct sys_exit_args * uap, + register_t * retval) +{ + size_t len; + struct filemon *filemon; + + filemon = filemon_lookup(curproc); + + if (filemon) { + len = snprintf(filemon->fm_msgbufr, + sizeof(filemon->fm_msgbufr), "X %d %d\n", + curproc->p_pid, SCARG(uap, rval)); + + filemon_output(filemon, filemon->fm_msgbufr, len); + + /* Check if the monitored process is about to exit. */ + if (filemon->fm_pid == curproc->p_pid) { + len = snprintf(filemon->fm_msgbufr, + sizeof(filemon->fm_msgbufr), "# Bye bye\n"); + + filemon_output(filemon, filemon->fm_msgbufr, len); + } + rw_exit(&filemon->fm_mtx); + } + sys_exit(l, uap, retval); +} + +static int +filemon_wrapper_unlink(struct lwp * l, struct sys_unlink_args * uap, + register_t * retval) +{ + int ret; + int error; + size_t done; + size_t len; + struct filemon *filemon; + + if ((ret = sys_unlink(l, uap, retval)) == 0) { + filemon = filemon_lookup(curproc); + + if (filemon) { + error = copyinstr(SCARG(uap, path), + filemon->fm_fname1, + sizeof(filemon->fm_fname1), &done); + if (error == 0) { + len = snprintf(filemon->fm_msgbufr, + sizeof(filemon->fm_msgbufr), + "D %d %s\n", + curproc->p_pid, filemon->fm_fname1); + + filemon_output(filemon, filemon->fm_msgbufr, + len); + } + rw_exit(&filemon->fm_mtx); + } + } + return (ret); +} + + +void +filemon_wrapper_install(void) +{ + struct sysent *sv_table = curproc->p_emul->e_sysent; + + sv_table[SYS_chdir].sy_call = (sy_call_t *) filemon_wrapper_chdir; + sv_table[SYS_execve].sy_call = (sy_call_t *) filemon_wrapper_execve; + sv_table[SYS_exit].sy_call = (sy_call_t *) filemon_wrapper_sys_exit; + sv_table[SYS_fork].sy_call = (sy_call_t *) filemon_wrapper_fork; + sv_table[SYS_link].sy_call = (sy_call_t *) filemon_wrapper_link; + sv_table[SYS_open].sy_call = (sy_call_t *) filemon_wrapper_open; + sv_table[SYS_rename].sy_call = (sy_call_t *) filemon_wrapper_rename; + sv_table[SYS_symlink].sy_call = (sy_call_t *) filemon_wrapper_symlink; + sv_table[SYS_unlink].sy_call = (sy_call_t *) filemon_wrapper_unlink; + sv_table[SYS_vfork].sy_call = (sy_call_t *) filemon_wrapper_vfork; +} + +void +filemon_wrapper_deinstall(void) +{ + struct sysent *sv_table = curproc->p_emul->e_sysent; + + sv_table[SYS_chdir].sy_call = (sy_call_t *) sys_chdir; + sv_table[SYS_execve].sy_call = (sy_call_t *) sys_execve; + sv_table[SYS_exit].sy_call = (sy_call_t *) sys_exit; + sv_table[SYS_fork].sy_call = (sy_call_t *) sys_fork; + sv_table[SYS_link].sy_call = (sy_call_t *) sys_link; + sv_table[SYS_open].sy_call = (sy_call_t *) sys_open; + sv_table[SYS_rename].sy_call = (sy_call_t *) sys_rename; + sv_table[SYS_symlink].sy_call = (sy_call_t *) sys_symlink; + sv_table[SYS_unlink].sy_call = (sy_call_t *) sys_unlink; + sv_table[SYS_vfork].sy_call = (sy_call_t *) sys_vfork; +} Index: src/sys/dev/filemon/mknod-sh diff -u /dev/null src/sys/dev/filemon/mknod-sh:1.1 --- /dev/null Thu Sep 9 00:10:16 2010 +++ src/sys/dev/filemon/mknod-sh Thu Sep 9 00:10:16 2010 @@ -0,0 +1,22 @@ +#!/bin/sh + +# Note that filemon.kmod needs the 6.x version of modload. + +Error() { + echo "ERROR: $@" >&2; exit 1 +} + +major=`sysctl kern.drivers | tr ',' '\012' | sed -n '/filemon/s,.*\[\([0-9][0-9]*\).*,\1,p'` + +[ ${major:-0} -gt 0 ] || Error filemon not loaded +dev=/dev/filemon + +if [ -c $dev ]; then + x=`'ls' -l $dev` + case "$x" in + *" $major,"*) exit 0;; + esac + rm -f $dev +fi +mknod -m 666 $dev c $major 0 + Index: src/sys/modules/filemon/Makefile diff -u /dev/null src/sys/modules/filemon/Makefile:1.1 --- /dev/null Thu Sep 9 00:10:16 2010 +++ src/sys/modules/filemon/Makefile Thu Sep 9 00:10:16 2010 @@ -0,0 +1,11 @@ +# $NetBSD: Makefile,v 1.1 2010/09/09 00:10:16 sjg Exp $ + +.include "../Makefile.inc" + +.PATH: ${S}/dev/filemon + +KMOD = filemon +SRCS = filemon.c filemon_wrapper.c +NOMAN = no + +.include <bsd.kmodule.mk>