start adding -e/--ebpf option to the python tools/ scripts

Several python tools allow their eBPF code to be printed to
stdout for debugging.  There are other projects that would
like to share these program definitions however, instead of
duplicating code.  Formalise an -e/--ebpf option, and start
using it in several tools (more to come).

Signed-off-by: Nathan Scott <nathans@redhat.com>
diff --git a/tools/biolatency.py b/tools/biolatency.py
index 46bebc4..6994878 100755
--- a/tools/biolatency.py
+++ b/tools/biolatency.py
@@ -4,7 +4,7 @@
 # biolatency    Summarize block device I/O latency as a histogram.
 #       For Linux, uses BCC, eBPF.
 #
-# USAGE: biolatency [-h] [-T] [-Q] [-m] [-D] [interval] [count]
+# USAGE: biolatency [-h] [-T] [-Q] [-m] [-D] [-e] [interval] [count]
 #
 # Copyright (c) 2015 Brendan Gregg.
 # Licensed under the Apache License, Version 2.0 (the "License")
@@ -36,6 +36,8 @@
     help="millisecond histogram")
 parser.add_argument("-D", "--disks", action="store_true",
     help="print a histogram per disk device")
+parser.add_argument("-e", "--ebpf", action="store_true",
+    help="report the eBPF program and exit")
 parser.add_argument("interval", nargs="?", default=99999999,
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
@@ -103,8 +105,10 @@
     bpf_text = bpf_text.replace('STORAGE', 'BPF_HISTOGRAM(dist);')
     bpf_text = bpf_text.replace('STORE',
         'dist.increment(bpf_log2l(delta));')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # load BPF program
 b = BPF(text=bpf_text)
diff --git a/tools/biotop.py b/tools/biotop.py
index 8da9255..bb6c378 100755
--- a/tools/biotop.py
+++ b/tools/biotop.py
@@ -4,7 +4,7 @@
 # biotop  block device (disk) I/O by process.
 #         For Linux, uses BCC, eBPF.
 #
-# USAGE: biotop.py [-h] [-C] [-r MAXROWS] [interval] [count]
+# USAGE: biotop.py [-h] [-C] [-r MAXROWS] [-e] [interval] [count]
 #
 # This uses in-kernel eBPF maps to cache process details (PID and comm) by I/O
 # request, as well as a starting timestamp for calculating I/O latency.
@@ -36,6 +36,8 @@
     help="don't clear the screen")
 parser.add_argument("-r", "--maxrows", default=20,
     help="maximum rows to print, default 20")
+parser.add_argument("-e", "--ebpf", action="store_true",
+    help="report the eBPF program and exit")
 parser.add_argument("interval", nargs="?", default=1,
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
@@ -55,7 +57,7 @@
     print()
 
 # load BPF program
-b = BPF(text="""
+bpf_text = """
 #include <uapi/linux/ptrace.h>
 #include <linux/blkdev.h>
 
@@ -163,7 +165,13 @@
 
     return 0;
 }
-""", debug=0)
+"""
+
+if args.ebpf:
+    print(bpf_text)
+    exit()
+
+b = BPF(text=bpf_text)
 b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start")
 b.attach_kprobe(event="blk_start_request", fn_name="trace_req_start")
 b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_req_start")
diff --git a/tools/tcplife.py b/tools/tcplife.py
index df68453..c87126e 100755
--- a/tools/tcplife.py
+++ b/tools/tcplife.py
@@ -58,6 +58,8 @@
     help="comma-separated list of local ports to trace.")
 parser.add_argument("-D", "--remoteport",
     help="comma-separated list of remote ports to trace.")
+parser.add_argument("-e", "--ebpf", action="store_true",
+    help="report the eBPF program and exit")
 args = parser.parse_args()
 debug = 0
 
@@ -375,8 +377,10 @@
 bpf_text = bpf_text.replace('FILTER_DPORT', '')
 bpf_text = bpf_text.replace('FILTER_LPORT', '')
 
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # event data
 TASK_COMM_LEN = 16      # linux/sched.h