1N/A# This prints I/O statistics for each file descriptor within a process. 1N/A# In particular, the time break down during read() and write() events is 1N/A# $Id: pfilestat 4 2007-08-01 11:01:38Z brendan $ 1N/A# USAGE: pfilestat [-r|-w] pid 1N/A# STATE microstate: running, sleeping, waitcpu, read, write 1N/A# FDUM File Descriptor ID 1N/A# Time Percentage of wallclock time in each STATE 1N/A# File Name of file, if known 1N/A# COPYRIGHT: Copyright (c) 2006 Richard McDougall. 1N/A# The contents of this file are subject to the terms of the 1N/A# Common Development and Distribution License, Version 1.0 only 1N/A# (the "License"). You may not use this file except in compliance 1N/A# See the License for the specific language governing permissions 1N/A# and limitations under the License. 1N/A# Trace readv() and writev(). 1N/A# 20-Feb-2006 Richard McDougall created this. 1N/A# 24-Feb-2006 Brendan Gregg tweaked code. 1N/A# 20-Mar-2006 " " tweaked code. 1N/A# 20-Mar-2006 " " last update. 1N/A############################## 1N/A# --- Process Arguments --- 1N/A### Default variables 1N/A USAGE: pfilestat [-r|-w] pid 1N/A pfilestat pid # default, r+w counts 1N/A pfilestat -r pid # read count only 1N/Ashift `expr $OPTIND - 1` 1N/A echo "Must supply pid" 1N/Aif [ $opt_read -eq 0 -a $opt_write -eq 0 ]; then 1N/A opt_read=1; opt_write=1 1N/A################################# 1N/A# --- Main Program, DTrace --- 1N/A/usr/sbin/dtrace -n ' 1N/A #pragma D option quiet 1N/A inline string CLEAR = "'$clearstr'"; 1N/A inline int OPT_read = '$opt_read'; 1N/A inline int OPT_write = '$opt_write'; 1N/A inline int PID = '$PID'; 1N/A unsigned long long totaltime; 1N/A unsigned long long totalbytes; 1N/A OPT_read && OPT_write ? printf("reads and writes") : 1; 1N/A OPT_read && ! OPT_write ? printf("reads") : 1; 1N/A ! OPT_read && OPT_write ? printf("writes") : 1; 1N/A syscall::read:entry, 1N/A syscall::pread*:entry 1N/A /pid == PID && OPT_read/ 1N/A @logical["running", (uint64_t)0, ""] = sum(timestamp - last); 1N/A totaltime += timestamp - last; 1N/A self->fd = arg0 + 1; 1N/A fbt::fop_read:entry, 1N/A fbt::fop_write:entry 1N/A self->path = args[0]->v_path == 0 ? "<none>" : 1N/A cleanpath(args[0]->v_path); 1N/A syscall::read:return, 1N/A syscall::pread*:return 1N/A /pid == PID && OPT_read/ 1N/A this->bytes = (int)arg0 > 0 ? (int)arg0 : 0; 1N/A @logical["read", self->fd - 1, self->path] = sum(timestamp - last); 1N/A @bytes["read", self->fd - 1, self->path] = sum(this->bytes); 1N/A totalbytes += this->bytes; 1N/A totaltime += timestamp - last; 1N/A syscall::write:entry, 1N/A syscall::pwrite*:entry 1N/A /pid == PID && OPT_write/ 1N/A @logical["running", (uint64_t)0, ""] = sum(timestamp - last); 1N/A totaltime += timestamp - last; 1N/A self->fd = (int)arg0 + 1; 1N/A syscall::write:return, 1N/A syscall::pwrite*:return 1N/A /pid == PID && OPT_write/ 1N/A this->bytes = (int)arg0 > 0 ? (int)arg0 : 0; 1N/A @logical["write", self->fd - 1, self->path] = sum(timestamp - last); 1N/A @bytes["write", self->fd - 1, self->path] = sum(this->bytes); 1N/A totalbytes += this->bytes; 1N/A totaltime += timestamp - last; 1N/A @logical["waitcpu", (uint64_t)0, ""] = sum(timestamp - last); 1N/A totaltime += timestamp - last; 1N/A @logical["running", (uint64_t)0, ""] = sum(timestamp - last); 1N/A totaltime += timestamp - last; 1N/A @logical["running", (uint64_t)0, ""] = sum(timestamp - last); 1N/A totaltime += timestamp - last; 1N/A /args[1]->pr_pid == PID && runstate == OTHER/ 1N/A @logical["sleep", (uint64_t)0, ""] = sum(timestamp - last); 1N/A totaltime += timestamp - last; 1N/A /args[1]->pr_pid == PID && runstate == READ/ 1N/A @logical["sleep-r", (uint64_t)0, ""] = sum(timestamp - last); 1N/A totaltime += timestamp - last; 1N/A /args[1]->pr_pid == PID && runstate == WRITE/ 1N/A @logical["sleep-w", (uint64_t)0, ""] = sum(timestamp - last); 1N/A totaltime += timestamp - last; 1N/A /args[1]->pr_pid == PID/ 1N/A @logical["waitcpu", (uint64_t)0, ""] = sum(timestamp - last); 1N/A totaltime += timestamp - last; 1N/A /args[1]->pr_pid == PID/ 1N/A @logical["waitcpu", (uint64_t)0, ""] = sum(timestamp - last); 1N/A totaltime += timestamp - last; 1N/A printf("%s", CLEAR); 1N/A normalize(@logical, totaltime / 100); 1N/A trunc(@logical, 10); 1N/A printf("%10s %7s %9s %-44s\n", "STATE", "FDNUM", "Time", "Filename"); 1N/A printa("%10s %7d %@8d%% %-44.44s\n", @logical); 1N/A delta = timestamp - stamp; 1N/A normalize(@bytes, (1024 * delta) / 1000000000); 1N/A printf("\n%10s %7s %9s %-44s\n", "STATE", "FDNUM", "KB/s", 1N/A printa("%10s %7d %@9d %-44.44s\n", @bytes); 1N/A printf("\nTotal event time (ms): %d Total Mbytes/sec: %d\n", 1N/A totaltime / 1000000, 1N/A (totalbytes * 1000000000) / (delta * 1048576));