Exercise 2
We will have to use count()
aggregation to count open()
and openat()
system calls. It can be cleaned up from outdated data with trunc()
action in DTrace or delete
operation in SystemTap. These scripts are roughly based on wstat.d
and wstat.stp
from aggregations example.
To print current timestamp we can use %Y
formatting specifier and walltimestamp
variable in DTrace. Same can be achieved with ctime()
and gettimeofday_s()
functions from SystemTap. To print data periodically, we can use timer probes: timer.s($1)
in SystemTap or tick-$1s
from DTrace. $1
here represents first command line argument.
Finally, we need to determine if open operation requests creation of file or not. We should write predicate for that which tests flags passed to open for O_CREAT
flag (we have learned how to access flags in previous exercise).
Here are resulting scripts:
syscall::openat*:entry /(arg2 & O_CREAT) == O_CREAT/ { @create[execname, pid] = count(); } syscall::openat*:entry /(arg2 & O_CREAT) == 0/ { @open[execname, pid] = count(); } syscall::openat*:return / arg1 > 0 / { @success[execname, pid] = count(); } tick-$1s { printf("%Y\n", walltimestamp); printf("%12s %6s %6s %6s %s\n", "EXECNAME", "PID", "CREATE", "OPEN", "SUCCESS"); printa("%12s %6d %@6d %@6d %@d\n", @create, @open, @success); trunc(@create); trunc(@open); trunc(@success); }
global open, creat, success global O_CREAT = 64; probe syscall.open { if(flags & O_CREAT) creat[execname(), pid()] <<< 1; else open[execname(), pid()] <<< 1; } probe syscall.open.return { if($return >= 0) success[execname(), pid()] <<< 1; } probe timer.s($1) { println(ctime(gettimeofday_s())); printf("%12s %6s %6s %6s %s\n", "EXECNAME", "PID", "CREATE", "OPEN", "SUCCESS"); foreach([en, pid+] in open) { printf("%12s %6d %6d %6d %d\n", en, pid, @count(creat[en, pid]), @count(open[en, pid]), @count(success[en, pid])); } delete open; delete creat; delete success; }