Académique Documents
Professionnel Documents
Culture Documents
/usr/bin/ksh
#
# iotop - display top disk I/O events by process.
#
Written using DTrace (Solaris 10 3/05).
#
# This is measuring disk events that have made it past system caches.
#
# 20-Apr-2006, ver 0.76
#
# USAGE:
iotop [-C] [-D|-o|-P] [-j|-Z] [-d device] [-f filename]
#
[-m mount_point] [-t top] [interval [count]]
#
#
iotop
# default output, 5 second intervals
#
#
-C
# don't clear the screen
#
-D
# print delta times, elapsed, us
#
-j
# print project ID
#
-o
# print disk delta times, us
#
-P
# print %I/O (disk delta times)
#
-Z
# print zone ID
#
-d device
# instance name to snoop (eg, dad0)
#
-f filename
# full pathname of file to snoop
#
-m mount_point # this FS only (will skip raw events)
#
-t top
# print top number only
#
eg,
#
iotop 1
# 1 second samples
#
iotop -C
# don't clear the screen
#
iotop -P
# print %I/O (time based)
#
iotop -j
# print project IDs
#
iotop -Z
# print zone IDs
#
iotop -t 20
# print top 20 lines only
#
iotop -C 5 12 # print 12 x 5 second samples
#
# FIELDS:
#
UID
user ID
#
PID
process ID
#
PPID
parent process ID
#
PROJ
project ID
#
ZONE
zone ID
#
CMD
process command name
#
DEVICE
device name
#
MAJ
device major number
#
MIN
device minor number
#
D
direction, Read or Write
#
BYTES
total size of operations, bytes
#
ELAPSED
total elapsed from request to completion, us
#
DISKTIME
total time for disk to complete request, us
#
%I/O
percent disk I/O, based on time (DISKTIME)
#
load
1 min load average
#
disk_r
total disk read Kbytes for sample
#
disk_w
total disk write Kbytes for sample
#
# NOTE:
# * There are two different delta times reported. -D prints the
# elapsed time from the disk request (strategy) to the disk completion
# (iodone); -o prints the time for the disk to complete that event
# since it's last event (time between iodones), or, the time to the
# strategy if the disk had been idle.
# * The %I/O value can exceed 100%. It represents how busy a process is
# making the disks, in terms of a single disk. A value of 200% could
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
Brendan Gregg
Created this.
##############################
# --- Process Arguments --#
### default variables
opt_device=0; opt_file=0; opt_mount=0; opt_clear=1; opt_proj=0; opt_zone=0
opt_percent=0; opt_def=1; opt_bytes=1; filter=0; device=.; filename=.; mount=.
opt_top=0; opt_elapsed=0; opt_dtime=0; interval=5; count=-1; top=0
### process options
while getopts CDd:f:hjm:oPt:Z name
do
case $name in
C)
opt_clear=0 ;;
D)
opt_elapsed=1; opt_bytes=0 ;;
d)
opt_device=1; device=$OPTARG ;;
f)
opt_file=1; filename=$OPTARG ;;
j)
opt_proj=1; opt_def=0 ;;
m)
opt_mount=1; mount=$OPTARG ;;
o)
opt_dtime=1; opt_bytes=0 ;;
P)
opt_percent=1; opt_dtime=1; opt_bytes=0 ;;
t)
opt_top=1; top=$OPTARG ;;
Z)
opt_zone=1; opt_def=0 ;;
h|?)
cat <<-END >&2
USAGE: iotop [-C] [-D|-o|-P] [-j|-Z] [-d device] [-f filename]
[-m mount_point] [-t top] [interval [count]]
-C
-D
-j
-o
-P
-Z
-d
-f
-m
-t
# don't
# print
# print
# print
# print
# print
device
filename
mount_point
top
eg,
iotop
iotop
iotop
iotop
iotop
iotop
1
-P
-m /
-t 20
-C 5 12
#
#
#
#
#
#
END
exit 1
esac
done
shift $(( $OPTIND - 1 ))
### option logic
if [[ "$1" > 0 ]]; then
interval=$1; shift
fi
if [[ "$1" > 0 ]]; then
count=$1; shift
fi
if (( opt_proj && opt_zone )); then
opt_proj=0
fi
if (( opt_elapsed && opt_dtime )); then
opt_elapsed=0
fi
if (( opt_device || opt_mount || opt_file )); then
filter=1
fi
if (( opt_clear )); then
clearstr=`clear`
else
clearstr=.
fi
#################################
# --- Main Program, DTrace --#
/usr/sbin/dtrace -n '
/*
* Command line arguments
*/
inline int OPT_def
= '$opt_def';
inline int OPT_proj
= '$opt_proj';
inline int OPT_zone
= '$opt_zone';
inline int OPT_clear = '$opt_clear';
inline
inline
inline
inline
inline
inline
inline
inline
inline
inline
inline
inline
inline
inline
inline
inline
int OPT_bytes
int OPT_elapsed
int OPT_dtime
int OPT_percent
int OPT_device
int OPT_mount
int OPT_file
int OPT_top
int INTERVAL
int COUNTER
int FILTER
int TOP
string DEVICE
string FILENAME
string MOUNT
string CLEAR
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
'$opt_bytes';
'$opt_elapsed';
'$opt_dtime';
'$opt_percent';
'$opt_device';
'$opt_mount';
'$opt_file';
'$opt_top';
'$interval';
'$count';
'$filter';
'$top';
"'$device'";
"'$filename'";
"'$mount'";
"'$clearstr'";
/*
* Store entry details
*/
io:genunix::start
/this->ok/
{
/* these are used as a unique disk event key, */
this->dev = args[0]->b_edev;
this->blk = args[0]->b_blkno;
/* save disk event details, */
start_uid[this->dev, this->blk] = uid;
start_pid[this->dev, this->blk] = pid;
start_ppid[this->dev, this->blk] = ppid;
start_comm[this->dev, this->blk] = execname;
start_time[this->dev, this->blk] = timestamp;
start_proj[this->dev, this->blk] = curpsinfo->pr_projid;
start_zone[this->dev, this->blk] = curpsinfo->pr_zoneid;
start_rw[this->dev, this->blk] = args[0]->b_flags & B_READ ? "R" : "W";
disk_r += args[0]->b_flags & B_READ ? args[0]->b_bcount : 0;
disk_w += args[0]->b_flags & B_READ ? 0 : args[0]->b_bcount;
/* increase disk event pending count */
pending[args[1]->dev_statname]++;
}
/*
* Process and Print completion
*/
io:genunix::done
/this->ok/
{
/* decrease disk event pending count */
pending[args[1]->dev_statname]--;
/*
* Process details
*/
/* fetch entry values */
this->dev = args[0]->b_edev;
this->blk = args[0]->b_blkno;
this->suid = start_uid[this->dev, this->blk];
this->spid = start_pid[this->dev, this->blk];
this->sppid = start_ppid[this->dev, this->blk];
this->sproj = start_proj[this->dev, this->blk];
this->szone = start_zone[this->dev, this->blk];
self->scomm = start_comm[this->dev, this->blk];
this->stime = start_time[this->dev, this->blk];
this->etime = timestamp; /* endtime */
this->elapsed = this->etime - this->stime;
self->rw = start_rw[this->dev, this->blk];
this->dtime = last_event[args[1]->dev_statname] == 0 ? 0 :
timestamp - last_event[args[1]->dev_statname];
/* memory cleanup */
start_uid[this->dev, this->blk] = 0;
start_pid[this->dev, this->blk] = 0;
start_ppid[this->dev, this->blk] = 0;
start_time[this->dev, this->blk]
start_comm[this->dev, this->blk]
start_zone[this->dev, this->blk]
start_proj[this->dev, this->blk]
start_rw[this->dev, this->blk]
=
=
=
=
=
0;
0;
0;
0;
0;
/*
* Choose statistic to track
*/
OPT_bytes ? this->value = args[0]->b_bcount
: 1;
OPT_elapsed ? this->value = this->elapsed / 1000 : 1;
OPT_dtime ? this->value = this->dtime / 1000 : 1;
/*
* Save details
*/
OPT_def ? @out[this->suid, this->spid, this->sppid, self->scomm,
args[1]->dev_statname, args[1]->dev_major, args[1]->dev_minor,
self->rw] = sum(this->value) : 1;
OPT_proj ? @out[this->sproj, this->spid, this->sppid, self->scomm,
args[1]->dev_statname, args[1]->dev_major, args[1]->dev_minor,
self->rw] = sum(this->value) : 1;
OPT_zone ? @out[this->szone, this->spid, this->sppid, self->scomm,
args[1]->dev_statname, args[1]->dev_major, args[1]->dev_minor,
self->rw] = sum(this->value) : 1;
/* save last disk event */
last_event[args[1]->dev_statname] = timestamp;
self->scomm = 0;
self->rw = 0;
}
/*
* Prevent pending from underflowing
* this can happen if this program is started during disk events.
*/
io:genunix::done
/pending[args[1]->dev_statname] < 0/
{
pending[args[1]->dev_statname] = 0;
}
/*
* Timer
*/
profile:::tick-1sec
{
secs--;
}
/*
* Print Report
*/
profile:::tick-1sec
/secs == 0/
{
/* fetch 1 min load average */
this->load1a = `hp_avenrun[0] / 65536;
this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;