tools/biolatpcts: Accept device name/node for target device selection MAJ:MIN is cumbersome. Update it to accept DEVNAME and /dev/DEVNAME too.
diff --git a/tools/biolatpcts.py b/tools/biolatpcts.py index 358414d..9db210e 100755 --- a/tools/biolatpcts.py +++ b/tools/biolatpcts.py
@@ -2,8 +2,8 @@ # # biolatpcts.py Monitor IO latency distribution of a block device. # -# $ ./biolatpcts.py 259:0 -# 259:0 p1 p5 p10 p16 p25 p50 p75 p84 p90 p95 p99 p100 +# $ ./biolatpcts.py /dev/nvme0n1 +# nvme0n1 p1 p5 p10 p16 p25 p50 p75 p84 p90 p95 p99 p100 # read 95us 175us 305us 515us 895us 985us 995us 1.5ms 2.5ms 3.5ms 4.5ms 10ms # write 5us 5us 5us 15us 25us 135us 765us 855us 885us 895us 965us 1.5ms # discard 5us 5us 5us 5us 135us 145us 165us 205us 385us 875us 1.5ms 2.5ms @@ -18,6 +18,7 @@ import argparse import json import sys +import os description = """ Monitor IO latency distribution of a block device @@ -25,8 +26,8 @@ parser = argparse.ArgumentParser(description = description, formatter_class = argparse.ArgumentDefaultsHelpFormatter) -parser.add_argument('devno', metavar='MAJ:MIN', type=str, - help='Target block device number') +parser.add_argument('dev', metavar='DEV', type=str, + help='Target block device (/dev/DEVNAME, DEVNAME or MAJ:MIN)') parser.add_argument('-i', '--interval', type=int, default=3, help='Report interval') parser.add_argument('-w', '--which', choices=['from-rq-alloc', 'after-rq-alloc', 'on-device'], @@ -100,6 +101,18 @@ args.pcts = args.pcts.split(',') args.pcts.sort(key=lambda x: float(x)) +try: + major = int(args.dev.split(':')[0]) + minor = int(args.dev.split(':')[1]) +except Exception: + if '/' in args.dev: + stat = os.stat(args.dev) + else: + stat = os.stat('/dev/' + args.dev) + + major = os.major(stat.st_rdev) + minor = os.minor(stat.st_rdev) + if args.which == 'from-rq-alloc': start_time_field = 'alloc_time_ns' elif args.which == 'after-rq-alloc': @@ -110,8 +123,8 @@ die() bpf_source = bpf_source.replace('__START_TIME_FIELD__', start_time_field) -bpf_source = bpf_source.replace('__MAJOR__', str(int(args.devno.split(':')[0]))) -bpf_source = bpf_source.replace('__MINOR__', str(int(args.devno.split(':')[1]))) +bpf_source = bpf_source.replace('__MAJOR__', str(major)) +bpf_source = bpf_source.replace('__MINOR__', str(minor)) bpf = BPF(text=bpf_source) bpf.attach_kprobe(event="blk_account_io_done", fn_name="kprobe_blk_account_io_done") @@ -236,7 +249,7 @@ result[io_type[iot]] = lats print(json.dumps(result), flush=True) else: - print('\n{:<7}'.format(args.devno), end='') + print('\n{:<7}'.format(os.path.basename(args.dev)), end='') widths = [] for pct in args.pcts: widths.append(max(len(pct), 5))