Linux equivalent to Mac OS X's fs_usage
You can use auditctl to monitor system calls related to filesystem activity like open
, stat
or lstat
. Unfortunately, monitoring read
or write
seems to be problematic.
auditctl
is an utility to assist controlling the kernel's audit system. You'll need to be root in order to use it. It supports various filters like:
devmajor Device Major Number
devminor Device Minor Number
dir Full Path of Directory to watch. This will place a recursive
watch on the directory and its whole subtree. It can only be
used on exit list. See "-w".
egid Effective Group ID. May be numeric or the groups name.
euid Effective User ID. May be numeric or the user account name.
filetype The target file's type. Can be either file, dir, socket, symlink,
char, block, or fifo.
path Full Path of File to watch. It can only be used on exit list.
pid Process ID
ppid Parent's Process ID
Example (tested on Fedora 16 x86_64)
To add the audit rules, run as root:
for syscall in open stat lstat read write; do
auditctl -a exit,always -F arch=b64 -S $syscall \
-F euid=1000 \
-F dir=/tmp/superuser.com/questions/370070
done
To delete them later replace -a
with -d
:
for syscall in open stat lstat read write; do
auditctl -d exit,always -F arch=b64 -S $syscall \
-F euid=1000 \
-F dir=/tmp/superuser.com/questions/370070
done
After adding the rules do something under that directory as the user with UID 1000:
cd /tmp/superuser.com/questions/370070
echo foo > bar
cat bar
stat bar
ausearch --start 00:00:00 --uid-effective 1000
will return the following (the log is /var/log/audit/audit.log
):
time->Thu Jun 14 00:02:32 2012
type=PATH msg=audit(1339621352.871:18529): item=0 name="/tmp/superuser.com/questions/370070" inode=178 dev=fd:03 mode=040775 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0
type=CWD msg=audit(1339621352.871:18529): cwd="/home/ciupicri"
type=SYSCALL msg=audit(1339621352.871:18529): arch=c000003e syscall=4 success=yes exit=0 a0=139bbf0 a1=7fff32d832d0 a2=7fff32d832d0 a3=24 items=1 ppid=2249 pid=3446 auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts6 ses=1 comm="bash" exe="/bin/bash" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
[root@hermes ~]# ausearch --start 00:00:00 --uid-effective 1000
----
time->Thu Jun 14 00:02:32 2012
type=PATH msg=audit(1339621352.871:18529): item=0 name="/tmp/superuser.com/questions/370070" inode=178 dev=fd:03 mode=040775 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0
type=CWD msg=audit(1339621352.871:18529): cwd="/home/ciupicri"
type=SYSCALL msg=audit(1339621352.871:18529): arch=c000003e syscall=4 success=yes exit=0 a0=139bbf0 a1=7fff32d832d0 a2=7fff32d832d0 a3=24 items=1 ppid=2249 pid=3446 auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts6 ses=1 comm="bash" exe="/bin/bash" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
----
time->Thu Jun 14 00:02:47 2012
type=PATH msg=audit(1339621367.175:18531): item=0 name="bar" inode=218 dev=fd:03 mode=0100664 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0
type=CWD msg=audit(1339621367.175:18531): cwd="/tmp/superuser.com/questions/370070"
type=SYSCALL msg=audit(1339621367.175:18531): arch=c000003e syscall=2 success=yes exit=3 a0=7fff5ed6b37f a1=0 a2=0 a3=7fff5ed69460 items=1 ppid=3446 pid=4735 auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts6 ses=1 comm="cat" exe="/bin/cat" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
----
time->Thu Jun 14 00:02:47 2012
type=PATH msg=audit(1339621367.172:18530): item=1 name="bar" inode=218 dev=fd:03 mode=0100664 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0
type=PATH msg=audit(1339621367.172:18530): item=0 name="/tmp/superuser.com/questions/370070" inode=178 dev=fd:03 mode=040775 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0
type=CWD msg=audit(1339621367.172:18530): cwd="/tmp/superuser.com/questions/370070"
type=SYSCALL msg=audit(1339621367.172:18530): arch=c000003e syscall=2 success=yes exit=3 a0=1665500 a1=241 a2=1b6 a3=4 items=2 ppid=2249 pid=3446 auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts6 ses=1 comm="bash" exe="/bin/bash" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
----
time->Thu Jun 14 00:02:47 2012
type=PATH msg=audit(1339621367.971:18532): item=0 name="bar" inode=218 dev=fd:03 mode=0100664 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0
type=CWD msg=audit(1339621367.971:18532): cwd="/tmp/superuser.com/questions/370070"
type=SYSCALL msg=audit(1339621367.971:18532): arch=c000003e syscall=6 success=yes exit=0 a0=7fffdc713375 a1=7fffdc711580 a2=7fffdc711580 a3=7fffdc7112f0 items=1 ppid=3446 pid=4736 auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts6 ses=1 comm="stat" exe="/usr/bin/stat" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
The syscall numbers can be found in /usr/include/asm/unistd_64.h
.
iowatch might be a possibility.
to watch activity in /etc you would run
$ iwatch /etc
Features
- command line and daemon mode
- xml configuration file
- ability to watch a directory recursively and watch new created directories
- can specify a list of exceptions
- can use regex to compare the file/directory name
- can execute a command if an event occurs
- send email
- syslog
- print time stamps
Events available
access : file was modified
modify : file was modified
attrib : file attributes changed
close_write : file closed, after being opened in writeable mode
close_nowrite : file closed, after being opened in read-only mode
close : file closed, regardless of read/write mode
open : file was opened
moved_from : File was moved away from.
moved_to : File was moved to.
move : a file/dir within watched directory was moved
create : a file was created within watched director
delete : a file was deleted within watched directory
delete_self : the watched file was deleted
unmount : file system on which watched file exists was unmounted
q_overflow : Event queued overflowed
ignored : File was ignored
isdir : event occurred against dir
oneshot : only send event once
Yes, Yes, I know... old thread...
But still... The Apple source code for fs_usage is available online, it's quite possible to compile it yourself. Of course, there ARE some caveats...
It's based on the Apple OS X's netbsd system calls, so some (ha!) editing would be needed...
Even comes with a complimentary Makefile (netbsd flavored, alas).
But if you call within the next 10 minutes, they'll even throw in a usable man page... all for free!
I've been watching too much late night infomercials.
Apple's fs_usage source code
(No refunds, batteries not included, do not return to store, some assembly required)
(and after looking through the code, and seeing your example, I do believe something could be created to do a 'subset' of fs_usage's features pretty quickly... let me tinker...)
I've got a working program, beginning to look similar to what you're looking for, have to do some more work on it to get closer, but you're all welcome to try it.
Bitbucket Hg Repository - fs_usage
The two closest options I can see (built-in) would be iostat
and inotify
. iostat will just show input/output stats for a device or partition on the system. inotify is a system file watcher, that you can hook into with a script to alert you of file changes. You would have to write your own event code to tell it to listen for file reads/writes, and then what to do with that signal.
From the link/man page :
Inotify can be used to monitor individual files, or to monitor directories. When a directory is monitored, inotify will return events for the directory itself, and for files inside the directory.
Personally, I'd write a Python or bash script to run the inotify when I needed to monitor for changes, and disable it when uneeded.