diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-08-07 16:47:18 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-08-07 16:47:18 -0400 |
commit | 384c5fe974abe35ab11dce4446dc5eed86585a3b (patch) | |
tree | 9bbdc8206d4a9c08866dc2251e40f4f7249696d4 /testsuite/systemtap.examples/io | |
parent | 9b3f22a9b83c4fd5e66874d78f4d35ad742ff802 (diff) | |
download | systemtap-steved-384c5fe974abe35ab11dce4446dc5eed86585a3b.tar.gz systemtap-steved-384c5fe974abe35ab11dce4446dc5eed86585a3b.tar.xz systemtap-steved-384c5fe974abe35ab11dce4446dc5eed86585a3b.zip |
samples: separate into subdirectories by subsystem
Diffstat (limited to 'testsuite/systemtap.examples/io')
-rw-r--r-- | testsuite/systemtap.examples/io/disktop.meta | 13 | ||||
-rw-r--r-- | testsuite/systemtap.examples/io/disktop.stp | 69 | ||||
-rw-r--r-- | testsuite/systemtap.examples/io/io_submit.meta | 13 | ||||
-rw-r--r-- | testsuite/systemtap.examples/io/io_submit.stp | 71 | ||||
-rwxr-xr-x | testsuite/systemtap.examples/io/iostat-scsi.stp | 81 | ||||
-rw-r--r-- | testsuite/systemtap.examples/io/iostat-scsi.txt | 14 | ||||
-rw-r--r-- | testsuite/systemtap.examples/io/iotime.meta | 13 | ||||
-rwxr-xr-x | testsuite/systemtap.examples/io/iotime.stp | 113 | ||||
-rw-r--r-- | testsuite/systemtap.examples/io/iotop.meta | 13 | ||||
-rw-r--r-- | testsuite/systemtap.examples/io/iotop.stp | 25 | ||||
-rw-r--r-- | testsuite/systemtap.examples/io/traceio.meta | 13 | ||||
-rw-r--r-- | testsuite/systemtap.examples/io/traceio.stp | 32 | ||||
-rw-r--r-- | testsuite/systemtap.examples/io/traceio2.meta | 13 | ||||
-rw-r--r-- | testsuite/systemtap.examples/io/traceio2.stp | 20 |
14 files changed, 503 insertions, 0 deletions
diff --git a/testsuite/systemtap.examples/io/disktop.meta b/testsuite/systemtap.examples/io/disktop.meta new file mode 100644 index 00000000..b063075b --- /dev/null +++ b/testsuite/systemtap.examples/io/disktop.meta @@ -0,0 +1,13 @@ +title: Summarize Disk Read/Write Traffic +name: disktop.stp +version: 1.0 +author: Oracle +keywords: disk +subsystem: disk +status: production +exit: user-controlled +output: timed +scope: system-wide +description: Get the status of reading/writing disk every 5 seconds, output top ten entries during that period. +test_check: stap -p4 disktop.stp +test_installcheck: stap disktop.stp -c "sleep 1" diff --git a/testsuite/systemtap.examples/io/disktop.stp b/testsuite/systemtap.examples/io/disktop.stp new file mode 100644 index 00000000..2637d735 --- /dev/null +++ b/testsuite/systemtap.examples/io/disktop.stp @@ -0,0 +1,69 @@ +#!/usr/bin/env stap +# +# Copyright (C) 2007 Oracle Corp. +# +# Get the status of reading/writing disk every 5 seconds, output top ten entries +# +# This is free software,GNU General Public License (GPL); either version 2, or (at your option) any +# later version. +# +# Usage: +# ./disktop.stp +# + +global io_stat,device +global read_bytes,write_bytes + +probe kernel.function("vfs_read").return { + if ($return>0) { + dev = __file_dev($file) + devname = __find_bdevname(dev,__file_bdev($file)) + + if (devname!="N/A") {/*skip read from cache*/ + io_stat[pid(),execname(),uid(),ppid(),"R"] += $return + device[pid(),execname(),uid(),ppid(),"R"] = devname + read_bytes += $return + } + } +} + +probe kernel.function("vfs_write").return { + if ($return>0) { + dev = __file_dev($file) + devname = __find_bdevname(dev,__file_bdev($file)) + + if (devname!="N/A") { /*skip update cache*/ + io_stat[pid(),execname(),uid(),ppid(),"W"] += $return + device[pid(),execname(),uid(),ppid(),"W"] = devname + write_bytes += $return + } + } +} + +probe timer.ms(5000) { + /* skip non-read/write disk */ + if (read_bytes+write_bytes) { + + printf("\n%-25s, %-8s%4dKb/sec, %-7s%6dKb, %-7s%6dKb\n\n",ctime(gettimeofday_s()),"Average:", + ((read_bytes+write_bytes)/1024)/5,"Read:",read_bytes/1024,"Write:",write_bytes/1024) + + /* print header */ + printf("%8s %8s %8s %25s %8s %4s %12s\n","UID","PID","PPID","CMD","DEVICE","T","BYTES") + } + /* print top ten I/O */ + foreach ([process,cmd,userid,parent,action] in io_stat- limit 10) + printf("%8d %8d %8d %25s %8s %4s %12d\n",userid,process,parent,cmd,device[process,cmd,userid,parent,action],action,io_stat[process,cmd,userid,parent,action]) + + /* clear data */ + delete io_stat + delete device + read_bytes = 0 + write_bytes = 0 +} + +probe end{ + delete io_stat + delete device + delete read_bytes + delete write_bytes +} diff --git a/testsuite/systemtap.examples/io/io_submit.meta b/testsuite/systemtap.examples/io/io_submit.meta new file mode 100644 index 00000000..911cb837 --- /dev/null +++ b/testsuite/systemtap.examples/io/io_submit.meta @@ -0,0 +1,13 @@ +title: Tally Reschedule Reason During AIO io_submit Call +name: io_submit.stp +version: 1.0 +author: Oracle +keywords: io backtrace +subsystem: io +status: production +exit: user-controlled +output: sorted on-exit +scope: system-wide +description: When a reschedule occurs during an AIO io_submit call, accumulate the traceback in a histogram. When the script exits prints out a sorted list from most common to least common backtrace. +test_check: stap -p4 io_submit.stp +test_installcheck: stap io_submit.stp -c "sleep 1" diff --git a/testsuite/systemtap.examples/io/io_submit.stp b/testsuite/systemtap.examples/io/io_submit.stp new file mode 100644 index 00000000..735dd6f9 --- /dev/null +++ b/testsuite/systemtap.examples/io/io_submit.stp @@ -0,0 +1,71 @@ +#!/bin/env stap
+#
+# Copyright (C) 2007 Oracle Corp. Chris Mason <chris.mason@oracle.com>
+#
+# This was implemented to find the most common causes of schedule during
+# the AIO io_submit call. It does this by recording which pids are inside
+# AIO, and recording the current stack trace if one of those pids is
+# inside schedule.
+# When the probe exits, it prints out the 30 most common call stacks for
+# schedule().
+#
+# This file is free software. You can redistribute it and/or modify it under
+# the terms of the GNU General Public License (GPL); either version 2, or (at
+# your option) any later version.
+
+global in_iosubmit
+global traces
+
+/*
+ * add a probe to sys_io_submit, on entry, record in the in_iosubmit
+ * hash table that this proc is in io_submit
+ */
+probe syscall.io_submit {
+ in_iosubmit[tid()] = 1
+}
+
+/*
+ * when we return from sys_io_submit, record that we're no longer there
+ */
+probe syscall.io_submit.return {
+ /* this assumes a given proc will do lots of io_submit calls, and
+ * so doesn't do the more expensive "delete in_iosubmit[p]". If
+ * there are lots of procs doing small number of io_submit calls,
+ * the hash may grow pretty big, so using delete may be better
+ */
+ in_iosubmit[tid()] = 0
+}
+
+/*
+ * every time we call schedule, check to see if we started off in
+ * io_submit. If so, record our backtrace into the traces histogram
+ */
+probe kernel.function("schedule") {
+ if (tid() in in_iosubmit) {
+ traces[backtrace()]++
+
+ /*
+ * change this to if (1) if you want a backtrace every time
+ * you go into schedule from io_submit. Unfortunately, the traces
+ * saved into the traces histogram above are truncated to just a
+ * few lines. so the only way to see the full trace is via the
+ * more verbose print_backtrace() right here.
+ */
+ if (0) {
+ printf("schedule in io_submit!\n")
+ print_backtrace()
+ }
+ }
+}
+
+/*
+ * when stap is done (via ctrl-c) go through the record of all the
+ * trace paths and print the 30 most common.
+ */
+probe end {
+ foreach (stack in traces- limit 30) {
+ printf("%d:", traces[stack])
+ print_stack(stack);
+ }
+}
+
diff --git a/testsuite/systemtap.examples/io/iostat-scsi.stp b/testsuite/systemtap.examples/io/iostat-scsi.stp new file mode 100755 index 00000000..ef778e53 --- /dev/null +++ b/testsuite/systemtap.examples/io/iostat-scsi.stp @@ -0,0 +1,81 @@ +#! /usr/bin/env stap + +global devices, reads, writes + +/* data collection: SCSI disk */ +%(kernel_v<"2.6.24" %? +probe module("sd_mod").function("sd_init_command") !, kernel.function("sd_init_command") { + device=kernel_string($SCpnt->request->rq_disk->disk_name) + sector_size=$SCpnt->device->sector_size + nr_sectors=$SCpnt->request->nr_sectors + devices[device] = 1 +%(kernel_v>="2.6.19" %? + if ($SCpnt->request->cmd_flags & 1) +%: + if ($SCpnt->request->flags & 1) +%) + writes[device] <<< nr_sectors * sector_size + else + reads[device] <<< nr_sectors * sector_size +} +%: +%{ +#include <scsi/scsi_device.h> +%} + +function get_sector_size:long (data:long) %{ /* pure */ + struct scsi_device *sdp = (struct scsi_device *)((long)THIS->data); + THIS->__retvalue = kread(&(sdp->sector_size)); + CATCH_DEREF_FAULT(); +%} + +probe module("sd_mod").function("sd_prep_fn") !, kernel.function("sd_prep_fn") { + device=kernel_string($rq->rq_disk->disk_name) + sector_size=get_sector_size($q->queuedata) + nr_sectors=$rq->nr_sectors + devices[device] = 1 + if ($rq->cmd_flags & 1) + writes[device] <<< nr_sectors * sector_size + else + reads[device] <<< nr_sectors * sector_size +} +%) + +/* data collection: SCSI tape */ +probe module("st").function("st_do_scsi") !, kernel.function("st_do_scsi") { + device=kernel_string($STp->disk->disk_name) + devices[device] = 1 + if ($direction) + writes[device] <<< $bytes + else + reads[device] <<< $bytes +} + + +/* reporting */ +global blksize=512 +global hdrcount +probe timer.s($1) { + if ((hdrcount++ % 10) == 0) + printf("%9s %9s %9s %9s %9s %9s\n", + "Device:","tps","blk_read/s","blk_wrtn/s","blk_read","blk_wrtn") + + foreach (dev in devices) { + rdcount=@count(reads[dev]) + wrcount=@count(writes[dev]) + tps=(rdcount+wrcount)*100/$1 + rdblkcount=rdcount ? @sum(reads[dev])/blksize : 0 + wrblkcount=wrcount ? @sum(writes[dev])/blksize : 0 + rdblkrate=rdblkcount*100/$1 + wrblkrate=wrblkcount*100/$1 + printf("%9s %6d.%02d %6d.%02d %6d.%02d %9d %9d\n", + dev, tps/100,tps%100, + rdblkrate/100,rdblkrate%100, + wrblkrate/100,wrblkrate%100, + rdblkcount, wrblkcount) + } + printf ("\n") + delete devices + delete reads + delete writes +} diff --git a/testsuite/systemtap.examples/io/iostat-scsi.txt b/testsuite/systemtap.examples/io/iostat-scsi.txt new file mode 100644 index 00000000..8222f659 --- /dev/null +++ b/testsuite/systemtap.examples/io/iostat-scsi.txt @@ -0,0 +1,14 @@ +From: http://sourceware.org/systemtap/wiki/WSiostatSCSI + +# stap -g iostat-scsi.stp 10 # seconds between reports + Device: tps blk_read/s blk_wrtn/s blk_read blk_wrtn + sda 1.30 2.40 105.60 24 1056 + + sda 0.30 0.00 4.00 0 40 + + sda 21.30 1.60 428.80 16 4288 + + sda 30.40 2820.80 11.60 28208 116 + + sda 38.10 2816.80 53.60 28168 536 +^C diff --git a/testsuite/systemtap.examples/io/iotime.meta b/testsuite/systemtap.examples/io/iotime.meta new file mode 100644 index 00000000..f656ff85 --- /dev/null +++ b/testsuite/systemtap.examples/io/iotime.meta @@ -0,0 +1,13 @@ +title: Trace Time Spent in Read and Write for Files +name: iotime.stp +version: 1.0 +author: Daniel Berrange and Will Cohen +keywords: syscall read write time io +subsystem: syscall +status: production +exit: user-controlled +output: trace +scope: system-wide +description: The script watches each open, close, read, and write syscalls on the system. For each file the scripts observes opened it accumulates the amount of wall clock time spend in read and write operations and the number of bytes read and written. When a file is closed the script prints out a pair of lines for the file. Both lines begin with a timestamp in microseconds, the PID number, and the executable name in parenthesese. The first line with the "access" keyword lists the file name, the attempted number of bytes for the read and write operations. The second line with the "iotime" keyword list the file name and the number of microseconds accumulated in the read and write syscalls. +test_check: stap -p4 iotime.stp +test_installcheck: stap iotime.stp -c "sleep 1" diff --git a/testsuite/systemtap.examples/io/iotime.stp b/testsuite/systemtap.examples/io/iotime.stp new file mode 100755 index 00000000..4fbd6b6e --- /dev/null +++ b/testsuite/systemtap.examples/io/iotime.stp @@ -0,0 +1,113 @@ +#! /usr/bin/env stap + +/* + * Copyright (C) 2006-2007 Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Print out the amount of time spent in the read and write systemcall + * when a process closes each file is closed. Note that the systemtap + * script needs to be running before the open operations occur for + * the script to record data. + * + * This script could be used to to find out which files are slow to load + * on a machine. e.g. + * + * stap iotime.stp -c 'firefox' + * + * Output format is: + * timestamp pid (executabable) info_type path ... + * + * 200283135 2573 (cupsd) access /etc/printcap read: 0 write: 7063 + * 200283143 2573 (cupsd) iotime /etc/printcap time: 69 + * + */ + +global start +global entry_io +global fd_io +global time_io + +function timestamp:long() { + return gettimeofday_us() - start +} + +function proc:string() { + return sprintf("%d (%s)", pid(), execname()) +} + +probe begin { + start = gettimeofday_us() +} + +global filenames +global filehandles +global fileread +global filewrite + +probe syscall.open { + filenames[pid()] = user_string($filename) +} + +probe syscall.open.return { + if ($return != -1) { + filehandles[pid(), $return] = filenames[pid()] + fileread[pid(), $return] = 0 + filewrite[pid(), $return] = 0 + } else { + printf("%d %s access %s fail\n", timestamp(), proc(), filenames[pid()]) + } + delete filenames[pid()] +} + +probe syscall.read { + if ($count > 0) { + fileread[pid(), $fd] += $count + } + t = gettimeofday_us(); p = pid() + entry_io[p] = t + fd_io[p] = $fd +} + +probe syscall.read.return { + t = gettimeofday_us(); p = pid() + fd = fd_io[p] + time_io[p,fd] <<< t - entry_io[p] +} + +probe syscall.write { + if ($count > 0) { + filewrite[pid(), $fd] += $count + } + t = gettimeofday_us(); p = pid() + entry_io[p] = t + fd_io[p] = $fd +} + +probe syscall.write.return { + t = gettimeofday_us(); p = pid() + fd = fd_io[p] + time_io[p,fd] <<< t - entry_io[p] +} + +probe syscall.close { + if (filehandles[pid(), $fd] != "") { + printf("%d %s access %s read: %d write: %d\n", timestamp(), proc(), + filehandles[pid(), $fd], fileread[pid(), $fd], filewrite[pid(), $fd]) + if (@count(time_io[pid(), $fd])) + printf("%d %s iotime %s time: %d\n", timestamp(), proc(), + filehandles[pid(), $fd], @sum(time_io[pid(), $fd])) + } + delete fileread[pid(), $fd] + delete filewrite[pid(), $fd] + delete filehandles[pid(), $fd] + delete fd_io[pid()] + delete entry_io[pid()] + delete time_io[pid(),$fd] +} diff --git a/testsuite/systemtap.examples/io/iotop.meta b/testsuite/systemtap.examples/io/iotop.meta new file mode 100644 index 00000000..d5331eda --- /dev/null +++ b/testsuite/systemtap.examples/io/iotop.meta @@ -0,0 +1,13 @@ +title: Periodically Print I/O Activity by Process Name +name: iotop.stp +version: 1.0 +author: anonymous +keywords: io +subsystem: io +status: production +exit: user-controlled +output: timed +scope: system-wide +description: Every five seconds print out the top ten executables generating I/O traffic during that interval sorted in descending order. +test_check: stap -p4 iotop.stp +test_installcheck: stap iotop.stp -c "sleep 1" diff --git a/testsuite/systemtap.examples/io/iotop.stp b/testsuite/systemtap.examples/io/iotop.stp new file mode 100644 index 00000000..6050343c --- /dev/null +++ b/testsuite/systemtap.examples/io/iotop.stp @@ -0,0 +1,25 @@ +global reads, writes, total_io + +probe kernel.function("vfs_read") { + reads[execname()] += $count +} + +probe kernel.function("vfs_write") { + writes[execname()] += $count +} + +# print top 10 IO processes every 5 seconds +probe timer.s(5) { + foreach (name in writes) + total_io[name] += writes[name] + foreach (name in reads) + total_io[name] += reads[name] + printf ("%16s\t%10s\t%10s\n", "Process", "KB Read", "KB Written") + foreach (name in total_io- limit 10) + printf("%16s\t%10d\t%10d\n", name, + reads[name]/1024, writes[name]/1024) + delete reads + delete writes + delete total_io + print("\n") +} diff --git a/testsuite/systemtap.examples/io/traceio.meta b/testsuite/systemtap.examples/io/traceio.meta new file mode 100644 index 00000000..da0b99f3 --- /dev/null +++ b/testsuite/systemtap.examples/io/traceio.meta @@ -0,0 +1,13 @@ +title: Track Cumulative I/O Activity by Process Name +name: traceio.stp +version: 1.0 +author: Red Hat +keywords: io +subsystem: io +status: production +exit: user-controlled +output: timed +scope: system-wide +description: Every second print out the top ten executables sorted in descending order based on cumulative I/O traffic observed. +test_check: stap -p4 traceio.stp +test_installcheck: stap traceio.stp -c "sleep 1" diff --git a/testsuite/systemtap.examples/io/traceio.stp b/testsuite/systemtap.examples/io/traceio.stp new file mode 100644 index 00000000..d3757c23 --- /dev/null +++ b/testsuite/systemtap.examples/io/traceio.stp @@ -0,0 +1,32 @@ +#!/usr/bin/env stap +# traceio.stp +# Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# + +global reads, writes, total_io + +probe kernel.function("vfs_read").return { + reads[execname()] += $return +} + +probe kernel.function("vfs_write").return { + writes[execname()] += $return +} + +probe timer.s(1) { + foreach (p in reads) + total_io[p] += reads[p] + foreach (p in writes) + total_io[p] += writes[p] + foreach(p in total_io- limit 10) + printf("%15s r: %8d KiB w: %8d KiB\n", + p, reads[p]/1024, + writes[p]/1024) + printf("\n") + # Note we don't zero out reads, writes and total_io, + # so the values are cumulative since the script started. +} diff --git a/testsuite/systemtap.examples/io/traceio2.meta b/testsuite/systemtap.examples/io/traceio2.meta new file mode 100644 index 00000000..4b63108c --- /dev/null +++ b/testsuite/systemtap.examples/io/traceio2.meta @@ -0,0 +1,13 @@ +title: Watch I/O Activity on a Particular Device +name: traceio2.stp +version: 1.0 +author: Red Hat +keywords: io +subsystem: io +status: production +exit: user-controlled +output: trace +scope: system-wide +description: Print out the executable name and process number as reads and writes to the specified device occur. +test_check: stap -p4 traceio2.stp 0x0801 +test_installcheck: stap traceio2.stp 0x0801 -c "sleep 1" diff --git a/testsuite/systemtap.examples/io/traceio2.stp b/testsuite/systemtap.examples/io/traceio2.stp new file mode 100644 index 00000000..656c38b3 --- /dev/null +++ b/testsuite/systemtap.examples/io/traceio2.stp @@ -0,0 +1,20 @@ +global device_of_interest + +probe begin { + /* The following is not the most efficient way to do this. + One could directly put the result of usrdev2kerndev() + into device_of_interest. However, want to test out + the other device functions */ + dev = usrdev2kerndev($1) + device_of_interest = MKDEV(MAJOR(dev), MINOR(dev)) +} + +probe kernel.function ("vfs_write"), + kernel.function ("vfs_read") +{ + dev_nr = $file->f_path->dentry->d_inode->i_sb->s_dev + + if (dev_nr == device_of_interest) + printf ("%s(%d) %s 0x%x\n", + execname(), pid(), probefunc(), dev_nr) +} |