// SE Toolkit program - http://www.setoolkit.com // // psio.se - a "ps -ef" style tool that prints I/O. Solaris, SE Toolkit. // // This program could assist finding a process that is causing the most I/O. // The I/O reported is the total of all types: disk I/O, network I/O, // stream I/O, etc.. // // This is an SE Toolkit version of the perl "psio" program. The perl version // reports disk I/O only, and has many different switches and modes of // operation. Future versions of this SE Toolkit program are unlikely to // have any extra features (for more features, see "pea.se"). // // 12-Mar-2004, ver 0.70 // // // USAGE: se psio.se [-h] | [interval [count]] // // se psio.se # "ps -ef" style output, 1 second sample // se psio.se 10 # print a 10 second sample // se psio.se 10 5 # print 5 x 10 second samples // // se psio.se 30 | sort -n +3 # sort by I/O, 30 sec sample // // se psio.se 5 12 | grep [f]sflush # examine "fsflush" for 1 min // // // FIELDS: // IOSIZE Size of I/O (Kbytes) // // SEE ALSO: se -DWIDE pea.se # SE Toolkit // psio # http://www.brendangregg.com/psio.html // // COPYRIGHT: Copyright (c) 2004 Brendan Gregg. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // 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. // // (http://www.gnu.org/copyleft/gpl.html) // // Author: Brendan Gregg [Sydney, Australia] // // 12-Mar-2004 Brendan Gregg Created this. #define BLK 8192 #include #include #include #include #include #include #include #include #include #include main(int argc, string argv[2]) { // // Variable declaration // psinfo_t p; /* raw proc info */ proc_class_t pp; /* advanced proc info */ passwd_t user; /* passwd structure, used for uid->name */ ulong user_ptr; /* passwd pointer */ tm_t time_tm; /* time structure, time conversions */ ulong time_ulong; /* temporary time variable */ char time[16]; /* TIME field */ char stime[16]; /* STIME field */ string username; /* username field */ double io_bytes; /* I/O bytes */ double io_kb; /* I/O Kbytes */ int i = 0; /* main loop counter */ int secs; /* interval seconds */ int loop; /* loop limit */ // // Process command line args // if ((argc > 1) && (argv[1] == "-h" || argv[1] == "--help")) { usage(argv[0]); } switch(argc) { case 3: secs = atoi(argv[1]); loop = atoi(argv[2]); break; case 2: secs = atoi(argv[1]); loop = 1; break; default: secs = 0; loop = 1; break; } // // Prime initial I/O values // refresh$(pp); pp.action$ = PROC_ACTION_NEXT_INDEX; for (;;) { refresh$(pp); if (pp.index$ == -1) { break; } // we read the following to reset the counters io_bytes = pp.inblocks*BLK + pp.outblocks*BLK + pp.charios; } // // Main loop // for (;;) { // print header if (i > 0) { printf("\n"); } printf(" UID PID PPID IOSIZE STIME TTY TIME CMD\n"); // sleep while I/O occurs sleep(secs); // // Print process listing // for (;;) { refresh$(pp); if (pp.index$ == -1) { break; } // we need this structure to fetch the start time and tty p = get_proc(pp.pid$); // calculate start time time_ulong = p.pr_start.tv_sec; time_tm = localtime(&time_ulong); strftime(stime, sizeof(stime), "%b %d", time_tm); // calculate CPU time time_ulong = pp.total_user + pp.total_system; time_tm = gmtime(&time_ulong); strftime(time, sizeof(time), "%M:%S", time_tm); // get username user_ptr = getpwuid(pp.uid); user = *((passwd_t *) user_ptr); username = user.pw_name; // calculate I/O by bytes io_bytes = pp.inblocks*BLK + pp.outblocks*BLK + pp.charios; io_kb = io_bytes / 1024; printf("%8s %5d %5d %7.1f %8s %-6s %6s %s\n", username, pp.pid$, pp.ppid, io_kb, stime, dev_to_tty(p.pr_ttydev), time, pp.args); } if (++i == loop) { break; } } } // // Subroutines // // usage - print usage and exit. // usage (string cmd) { printf("USAGE: se %s [-h] | [interval [count]]\n",cmd); printf(" eg, se %s # print a 1 second sample\n",cmd); printf(" eg, se %s 10 # print a 10 second sample\n",cmd); printf(" eg, se %s 10 5 # print 5 x 10 second samples\n",cmd); exit(1); }