opensnoop: Introduce process name filtering

Signed-off-by: KarimAllah Ahmed <[email protected]>
diff --git a/man/man8/opensnoop.8 b/man/man8/opensnoop.8
index c30a946..5c17672 100644
--- a/man/man8/opensnoop.8
+++ b/man/man8/opensnoop.8
@@ -2,11 +2,11 @@
 .SH NAME
 opensnoop \- Trace open() syscalls. Uses Linux eBPF/bcc.
 .SH SYNOPSIS
-.B opensnoop [\-h] [\-t] [\-x] [\-p PID]
+.B opensnoop [\-h] [\-t] [\-x] [\-p PID] [\-n name]
 .SH DESCRIPTION
 opensnoop traces the open() syscall, showing which processes are attempting
 to open which files. This can be useful for determining the location of config
-and log files, or for troubleshooting applications that are failing, especially
+and log files, or for troubleshooting applications that are failing, specially
 on startup.
 
 This works by tracing the kernel sys_open() function using dynamic tracing, and
@@ -32,6 +32,9 @@
 .TP
 \-p PID
 Trace this process ID only (filtered in-kernel).
+.TP
+\-n name
+Only print processes where its name partially matches 'name'
 .SH EXAMPLES
 .TP
 Trace all open() syscalls:
@@ -49,6 +52,10 @@
 Trace PID 181 only:
 #
 .B opensnoop \-p 181
+.TP
+Trace all open() syscalls from processes where its name partially matches 'ed':
+#
+.B opensnoop \-n ed
 .SH FIELDS
 .TP
 TIME(s)
diff --git a/tools/opensnoop.py b/tools/opensnoop.py
index 78c3fea..f2bac4b 100755
--- a/tools/opensnoop.py
+++ b/tools/opensnoop.py
@@ -23,6 +23,7 @@
     ./opensnoop -t        # include timestamps
     ./opensnoop -x        # only show failed opens
     ./opensnoop -p 181    # only trace PID 181
+    ./opensnoop -n main   # only print process names containing "main"
 """
 parser = argparse.ArgumentParser(
     description="Trace open() syscalls",
@@ -34,6 +35,8 @@
     help="only show failed opens")
 parser.add_argument("-p", "--pid",
     help="trace this PID only")
+parser.add_argument("-n", "--name",
+    help="only print process names containing this name")
 args = parser.parse_args()
 debug = 0
 
@@ -155,6 +158,9 @@
     if args.failed and (event.ret >= 0):
         return
 
+    if args.name and args.name not in event.comm:
+        return
+
     if args.timestamp:
         delta = event.ts - initial_ts
         print("%-14.9f" % (float(delta) / 1000000), end="")
diff --git a/tools/opensnoop_example.txt b/tools/opensnoop_example.txt
index d84f16a..b297e33 100644
--- a/tools/opensnoop_example.txt
+++ b/tools/opensnoop_example.txt
@@ -89,6 +89,37 @@
 file or directory.
 
 
+The -n option can be used to filter on process name using partial matches:
+
+# ./opensnoop -n ed
+
+PID    COMM               FD ERR PATH
+2679   sed                 3   0 /etc/ld.so.cache
+2679   sed                 3   0 /lib/x86_64-linux-gnu/libselinux.so.1
+2679   sed                 3   0 /lib/x86_64-linux-gnu/libc.so.6
+2679   sed                 3   0 /lib/x86_64-linux-gnu/libpcre.so.3
+2679   sed                 3   0 /lib/x86_64-linux-gnu/libdl.so.2
+2679   sed                 3   0 /lib/x86_64-linux-gnu/libpthread.so.0
+2679   sed                 3   0 /proc/filesystems
+2679   sed                 3   0 /usr/lib/locale/locale-archive
+2679   sed                -1   2
+2679   sed                 3   0 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
+2679   sed                 3   0 /dev/null
+2680   sed                 3   0 /etc/ld.so.cache
+2680   sed                 3   0 /lib/x86_64-linux-gnu/libselinux.so.1
+2680   sed                 3   0 /lib/x86_64-linux-gnu/libc.so.6
+2680   sed                 3   0 /lib/x86_64-linux-gnu/libpcre.so.3
+2680   sed                 3   0 /lib/x86_64-linux-gnu/libdl.so.2
+2680   sed                 3   0 /lib/x86_64-linux-gnu/libpthread.so.0
+2680   sed                 3   0 /proc/filesystems
+2680   sed                 3   0 /usr/lib/locale/locale-archive
+2680   sed                -1   2
+^C
+
+This caught the 'sed' command because it partially matches 'ed' that's passed
+to the '-n' option.
+
+
 USAGE message:
 
 # ./opensnoop -h