NAME
filemon —
track interesting system
calls
SYNOPSIS
pseudo-device filemon
DESCRIPTION
In normal situations,
filemon is not built-in to the kernel,
and a call to open
/dev/filemon will auto-load the
filemon module (see
module(7) for more details).
(Although not recommended, the
filemon facility can be
included in a kernel build by adding
to the kernel configuration file.)
filemon provides a means for tracking the successful system
calls performed by a process and its descendants. It is used by
make(1) to track the activities of
build scripts, for the purpose of automatically learning dependencies.
The data captured by
filemon for the script
n=`wc -l /etc/motd`; echo "int motd_lines = $n;" > foo.h.new
cmp -s foo.h foo.h.new 2> /dev/null || mv foo.h.new foo.h
looks like:
# filemon version 4
# Target pid 24291
V 4
E 29676 /bin/sh
R 29676 /etc/ld.so.conf
R 29676 /lib/libedit.so.2
R 29676 /lib/libterminfo.so.1
R 29676 /lib/libc.so.12
F 29676 4899
E 4899 /usr/bin/wc
R 4899 /etc/ld.so.conf
R 4899 /usr/lib/libc.so.12
R 4899 /etc/motd
X 4899 0
W 29676 foo.h.new
X 29676 0
# Bye bye
E 3250 /bin/sh
R 3250 /etc/ld.so.conf
R 3250 /lib/libedit.so.2
R 3250 /lib/libterminfo.so.1
R 3250 /lib/libc.so.12
W 26673 /dev/null
E 26673 /usr/bin/cmp
R 26673 /etc/ld.so.conf
R 26673 /usr/lib/libc.so.12
X 26673 2
E 576 /bin/mv
R 576 /etc/ld.so.conf
R 576 /lib/libc.so.12
M 576 'foo.h.new' 'foo.h'
X 576 0
X 3250 0
# Bye bye
Most records follow the format:
where
type is one of the list below, and unless otherwise
specified,
data is a pathname.
A
filemon instance is created by opening
/dev/filemon. Then use
ioctl(
filemon_fd,
FILEMON_SET_PID,
&pid) to
identify the target process to monitor, and
ioctl(
filemon_fd,
FILEMON_SET_FD,
&output_fd) to
direct the event log to an already-opened output file.
FILES
EXAMPLES
The following example demonstrates the basic usage of
filemon:
#include <filemon.h>
pid_t pid;
int filemon_fd, temp_fd;
int status;
filemon_fd = open("/dev/filemon", O_RDWR);
temp_fd = mkstemp("/tmp/filemon.XXXXXXX");
/* give filemon the temp file to use */
ioctl(filemon_fd, FILEMON_SET_FD, &temp_fd);
/* children do not need these once they exec */
fcntl(filemon_fd, F_SETFD, FD_CLOEXEC);
fcntl(temp_fd, F_SETFD, FD_CLOEXEC);
pid = fork();
switch(pid) {
case -1:
err(1, "cannot fork");
break;
case 0:
pid = getpid();
/* tell filemon to monitor this process */
ioctl(filemon_fd, FILEMON_SET_PID, &pid);
execvp(...);
_exit(1);
break;
default:
status = wait();
close(filemon_fd);
lseek(temp_fd, SEEK_SET, 0);
/* read the captured syscalls from temp_fd */
close(temp_fd);
break;
}
The output of
filemon is intended to be simple to parse. It is
possible to achieve almost equivalent results with
dtrace(1) though on many systems
this requires elevated privileges. Also,
ktrace(1) can capture similar
data, but records failed system calls as well as successful, and is thus more
complex to post-process.
HISTORY
filemon was contributed by Juniper Networks.
SECURITY CONSIDERATIONS
If the monitored process exits, and its pid gets reused,
filemon will continue to report events for the new process
(and its descendants) without any authorization checks.
Monitoring of a process enables the target process to write to the tracking
process's file descriptor.
RESTRICTIONS
The
filemon facility can only be used to track processes
running in the system's native emulation. Neither processes using any of the
COMPAT_xxx
compatibility layers nor any descendants of
such processes can be tracked.
If two processes are monitored, and one is a descendant of the other, events
related to the descendant process and its further descendants are delivered
only to the descendant process's monitor. If a process is being monitored by
two instances of
filemon, events will be delivered only to
the first instance created (when
/dev/filemon was opened),
regardless of the order in which the monitoring processes called
ioctl(
fd,
FILEMON_SET_PID,
pid).