1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1994 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate /* sadp.c 1.14.1.12 of 8/9/89 */ 33*7c478bd9Sstevel@tonic-gate /* sadp.c - For VAX and PDP11 machines, 34*7c478bd9Sstevel@tonic-gate disk profiler profiles rp06, rm05 and general disk drives. 35*7c478bd9Sstevel@tonic-gate It reads system buffer header pool, physical buffer header 36*7c478bd9Sstevel@tonic-gate pool and swap buffer header pool once every second, 37*7c478bd9Sstevel@tonic-gate to examine disk drive's I/O queue. 38*7c478bd9Sstevel@tonic-gate For 3b20s system, it profiles the regular disk drives, 39*7c478bd9Sstevel@tonic-gate it reads the circular output queue for each drive 40*7c478bd9Sstevel@tonic-gate once every second. 41*7c478bd9Sstevel@tonic-gate usage : sadp [-th][-d device[-drive]] s [n] 42*7c478bd9Sstevel@tonic-gate */ 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #include <stdio.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 47*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 48*7c478bd9Sstevel@tonic-gate #include <sys/buf.h> 49*7c478bd9Sstevel@tonic-gate #include <sys/elog.h> 50*7c478bd9Sstevel@tonic-gate #include <nlist.h> 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate #include <string.h> 53*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 54*7c478bd9Sstevel@tonic-gate #include <sys/dkio.h> 55*7c478bd9Sstevel@tonic-gate #ifdef FIXME 56*7c478bd9Sstevel@tonic-gate #include <sys/dk.h> 57*7c478bd9Sstevel@tonic-gate #endif 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate #include <time.h> 60*7c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 61*7c478bd9Sstevel@tonic-gate #include <sys/var.h> 62*7c478bd9Sstevel@tonic-gate #include <ctype.h> 63*7c478bd9Sstevel@tonic-gate #include <sys/sysinfo.h> 64*7c478bd9Sstevel@tonic-gate #include <kvm.h> 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate /* 67*7c478bd9Sstevel@tonic-gate * These includes are for dealing with scsi targets. 68*7c478bd9Sstevel@tonic-gate */ 69*7c478bd9Sstevel@tonic-gate #include <sys/dditypes.h> 70*7c478bd9Sstevel@tonic-gate #include <sys/scsi/scsi.h> 71*7c478bd9Sstevel@tonic-gate #include <sys/scsi/conf/device.h> 72*7c478bd9Sstevel@tonic-gate #include <sys/scsi/targets/sddef.h> 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate /* cylinder profiling */ 76*7c478bd9Sstevel@tonic-gate #define BLANK ' ' 77*7c478bd9Sstevel@tonic-gate #define BLOB '*' 78*7c478bd9Sstevel@tonic-gate #define TRACE '.' 79*7c478bd9Sstevel@tonic-gate #define BRK '=' 80*7c478bd9Sstevel@tonic-gate #define FOOT '-' 81*7c478bd9Sstevel@tonic-gate #define CYLNO 1 82*7c478bd9Sstevel@tonic-gate #define SEEKD 2 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate struct dk_geom dk_geom; 85*7c478bd9Sstevel@tonic-gate #define CHUNK 16 86*7c478bd9Sstevel@tonic-gate #define CHUNKSHIFT 4 87*7c478bd9Sstevel@tonic-gate #define PHYS_CYL dk_geom.dkg_pcyl 88*7c478bd9Sstevel@tonic-gate #define CHPERCYL (int)(PHYS_CYL/CHUNK) /* 89*7c478bd9Sstevel@tonic-gate * the number of CHUNK cylinder 90*7c478bd9Sstevel@tonic-gate * chunks on a disk 91*7c478bd9Sstevel@tonic-gate */ 92*7c478bd9Sstevel@tonic-gate #define SECTPERTRK (int)(dk_geom.dkg_nsect) /* sectors per track */ 93*7c478bd9Sstevel@tonic-gate #define SECTPERCYL (SECTPERTRK * (int)(dk_geom.dkg_nhead)) 94*7c478bd9Sstevel@tonic-gate #define ERR_BAD_DEV "Device %s is not defined, valid devices are: " 95*7c478bd9Sstevel@tonic-gate #define ERR_BAD_UNIT \ 96*7c478bd9Sstevel@tonic-gate "Invalid drive specified for device %s, valid drives are: " 97*7c478bd9Sstevel@tonic-gate #define ERR_NO_DEV "Please specify a device type, valid devices are: " 98*7c478bd9Sstevel@tonic-gate #define DRVNUM(devname) strpbrk(devname, "0123456789") 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate #define cylin b_resid 101*7c478bd9Sstevel@tonic-gate #define NDRIVE 10 102*7c478bd9Sstevel@tonic-gate #define SNDRIVE NDRIVE /* Not used */ 103*7c478bd9Sstevel@tonic-gate #define MAX_HDISK_REP NDRIVE 104*7c478bd9Sstevel@tonic-gate #define MAXDRIVE 20 /* maximum number of configured disks */ 105*7c478bd9Sstevel@tonic-gate #define NAMESIZE 10 /* size of device names */ 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate struct nlist setup[] = { 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate #define X1_V 0 111*7c478bd9Sstevel@tonic-gate {"v"}, 112*7c478bd9Sstevel@tonic-gate #define X1_BUF 1 113*7c478bd9Sstevel@tonic-gate {"buf"}, 114*7c478bd9Sstevel@tonic-gate #define X1_PBUF 2 115*7c478bd9Sstevel@tonic-gate {"pbuf"}, 116*7c478bd9Sstevel@tonic-gate #define X1_SDUNITS 3 117*7c478bd9Sstevel@tonic-gate {"sdunits"}, 118*7c478bd9Sstevel@tonic-gate #ifdef FIXME 119*7c478bd9Sstevel@tonic-gate #define X1_DK_NDRIVE 4 120*7c478bd9Sstevel@tonic-gate {"dk_ndrive"}, 121*7c478bd9Sstevel@tonic-gate #define X1_DK_BUSY 5 122*7c478bd9Sstevel@tonic-gate {"dk_busy"}, 123*7c478bd9Sstevel@tonic-gate #define X1_DK_TIME 6 124*7c478bd9Sstevel@tonic-gate {"dk_time"}, 125*7c478bd9Sstevel@tonic-gate #define X1_DK_SEEK 7 126*7c478bd9Sstevel@tonic-gate {"dk_seek"}, 127*7c478bd9Sstevel@tonic-gate #define X1_DK_XFER 8 128*7c478bd9Sstevel@tonic-gate {"dk_xfer"}, 129*7c478bd9Sstevel@tonic-gate #define X1_DK_WDS 9 130*7c478bd9Sstevel@tonic-gate {"dk_wds"}, 131*7c478bd9Sstevel@tonic-gate #define X1_DK_BPS 10 132*7c478bd9Sstevel@tonic-gate {"dk_bps"}, 133*7c478bd9Sstevel@tonic-gate #define X1_DK_READ 11 134*7c478bd9Sstevel@tonic-gate {"dk_read"}, 135*7c478bd9Sstevel@tonic-gate #define X1_DK_IVEC 12 136*7c478bd9Sstevel@tonic-gate {"dk_ivec"}, 137*7c478bd9Sstevel@tonic-gate #define X1_NUMSYMBOLS 13 138*7c478bd9Sstevel@tonic-gate #else 139*7c478bd9Sstevel@tonic-gate #define X1_NUMSYMBOLS 4 140*7c478bd9Sstevel@tonic-gate #endif 141*7c478bd9Sstevel@tonic-gate {0} 142*7c478bd9Sstevel@tonic-gate }; 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate void do_disk_stats (); 145*7c478bd9Sstevel@tonic-gate void usage (); 146*7c478bd9Sstevel@tonic-gate void prthist (); 147*7c478bd9Sstevel@tonic-gate void pline (); 148*7c478bd9Sstevel@tonic-gate void cylhdr (); 149*7c478bd9Sstevel@tonic-gate void cylftr (); 150*7c478bd9Sstevel@tonic-gate void cylhist (); 151*7c478bd9Sstevel@tonic-gate void validate_device (); 152*7c478bd9Sstevel@tonic-gate void validate_drive (); 153*7c478bd9Sstevel@tonic-gate void init_geom (); 154*7c478bd9Sstevel@tonic-gate void bad_device (); 155*7c478bd9Sstevel@tonic-gate void read_devinfo_names (); 156*7c478bd9Sstevel@tonic-gate void fail (); 157*7c478bd9Sstevel@tonic-gate void init_disk (); 158*7c478bd9Sstevel@tonic-gate void safe_kvm_read (); 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate #undef n_name /* to resolve conflict with <syms.h> */ 161*7c478bd9Sstevel@tonic-gate #define MAXINTSIZE 12 /* sizeof "-2147483648" + 1 */ 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate int debug = 1; 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate #define Debug if (debug) 166*7c478bd9Sstevel@tonic-gate #define dfprintf if (debug) fprintf 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate /* 169*7c478bd9Sstevel@tonic-gate * FETCH_XYZ naming convention: 170*7c478bd9Sstevel@tonic-gate * X = I for nlist index, A for actual address 171*7c478bd9Sstevel@tonic-gate * Y = V for regular variable, A for array variable 172*7c478bd9Sstevel@tonic-gate * Z = L if length explicitly specified 173*7c478bd9Sstevel@tonic-gate */ 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate #define FETCH_AAL(addr, var, len, vname)\ 176*7c478bd9Sstevel@tonic-gate safe_kvm_read(kd, (unsigned long) addr, \ 177*7c478bd9Sstevel@tonic-gate (char *) var, len, vname) 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate #define FETCH_IV(index, var)\ 180*7c478bd9Sstevel@tonic-gate safe_kvm_read(kd, (unsigned long) setup[index].n_value, \ 181*7c478bd9Sstevel@tonic-gate (char *) &var, sizeof (var), setup[index].n_name) 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate #define FETCH_IAL(index, var, len)\ 184*7c478bd9Sstevel@tonic-gate safe_kvm_read(kd, (unsigned long)setup[index].n_value, \ 185*7c478bd9Sstevel@tonic-gate (char *) var, len, setup[index].n_name) 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate int dk_ndrive; 188*7c478bd9Sstevel@tonic-gate int ndrives; 189*7c478bd9Sstevel@tonic-gate int all = 0; /* 190*7c478bd9Sstevel@tonic-gate * indicate whether all drives 191*7c478bd9Sstevel@tonic-gate * are implicitly specified 192*7c478bd9Sstevel@tonic-gate */ 193*7c478bd9Sstevel@tonic-gate char *cmdname = "sadp"; 194*7c478bd9Sstevel@tonic-gate char device[NAMESIZE]; 195*7c478bd9Sstevel@tonic-gate char dr_name[NDRIVE][NAMESIZE]; 196*7c478bd9Sstevel@tonic-gate long dk_bps[NDRIVE]; 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate struct { 199*7c478bd9Sstevel@tonic-gate long dk_busy[NDRIVE]; 200*7c478bd9Sstevel@tonic-gate long dk_time[NDRIVE]; 201*7c478bd9Sstevel@tonic-gate long dk_wds[NDRIVE]; 202*7c478bd9Sstevel@tonic-gate long dk_seek[NDRIVE]; 203*7c478bd9Sstevel@tonic-gate long dk_xfer[NDRIVE]; 204*7c478bd9Sstevel@tonic-gate long dk_read[NDRIVE]; 205*7c478bd9Sstevel@tonic-gate } dk; 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate struct var tbl; 208*7c478bd9Sstevel@tonic-gate char *sbuf, *phybuf; 209*7c478bd9Sstevel@tonic-gate struct buf bp[2]; /* for swap buffers */ 210*7c478bd9Sstevel@tonic-gate int nonblk; 211*7c478bd9Sstevel@tonic-gate int index; 212*7c478bd9Sstevel@tonic-gate int index1; 213*7c478bd9Sstevel@tonic-gate unsigned temp1; 214*7c478bd9Sstevel@tonic-gate #define devnm dr_name 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate int fflg, dflg, tflg, hflg, errflg; 217*7c478bd9Sstevel@tonic-gate int s, n, ct; 218*7c478bd9Sstevel@tonic-gate static int ub = 8; 219*7c478bd9Sstevel@tonic-gate int sdist; 220*7c478bd9Sstevel@tonic-gate int m; 221*7c478bd9Sstevel@tonic-gate int dev; 222*7c478bd9Sstevel@tonic-gate int temp; 223*7c478bd9Sstevel@tonic-gate int f; 224*7c478bd9Sstevel@tonic-gate int i; 225*7c478bd9Sstevel@tonic-gate int n1, dleng, dashb, k, devlen; 226*7c478bd9Sstevel@tonic-gate int dashf; 227*7c478bd9Sstevel@tonic-gate int dn; 228*7c478bd9Sstevel@tonic-gate int drvlist[NDRIVE]; 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate int Sdrvlist[SNDRIVE]; /* SCSI */ 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate struct HISTDATA { 233*7c478bd9Sstevel@tonic-gate long hdata[1]; 234*7c478bd9Sstevel@tonic-gate }; 235*7c478bd9Sstevel@tonic-gate struct utsname name; 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate char *nopt; 238*7c478bd9Sstevel@tonic-gate char empty[30]; 239*7c478bd9Sstevel@tonic-gate char drive[30]; 240*7c478bd9Sstevel@tonic-gate char *malloc(); 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate int SCSI; /* SCSI */ 243*7c478bd9Sstevel@tonic-gate int ALL; 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate long lseek(); 246*7c478bd9Sstevel@tonic-gate long **dkcyl; 247*7c478bd9Sstevel@tonic-gate long **skcyl; 248*7c478bd9Sstevel@tonic-gate long *iocnt; 249*7c478bd9Sstevel@tonic-gate static kvm_t *kd = NULL; 250*7c478bd9Sstevel@tonic-gate struct scsi_device *sdunits[SD_MAXUNIT]; 251*7c478bd9Sstevel@tonic-gate struct scsi_device sdunit[NDRIVE]; 252*7c478bd9Sstevel@tonic-gate int cyl_no, prev_cyl_no; 253*7c478bd9Sstevel@tonic-gate int cyl_bk, prev_cyl_bk; 254*7c478bd9Sstevel@tonic-gate int seek_dist, seek_bk; 255*7c478bd9Sstevel@tonic-gate int max_cyl_no = 0; 256*7c478bd9Sstevel@tonic-gate int max_seek_dist = 0; 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate main(argc, argv) 259*7c478bd9Sstevel@tonic-gate int argc; 260*7c478bd9Sstevel@tonic-gate char **argv; 261*7c478bd9Sstevel@tonic-gate { 262*7c478bd9Sstevel@tonic-gate unsigned sleep(); 263*7c478bd9Sstevel@tonic-gate extern int optind; 264*7c478bd9Sstevel@tonic-gate extern char *optarg; 265*7c478bd9Sstevel@tonic-gate int c, j; 266*7c478bd9Sstevel@tonic-gate char *ctime(), *stime; 267*7c478bd9Sstevel@tonic-gate long curt; 268*7c478bd9Sstevel@tonic-gate extern time_t time(); 269*7c478bd9Sstevel@tonic-gate long *skdist; 270*7c478bd9Sstevel@tonic-gate long *disk; 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate fail("sadp does not work yet -- no disk statistics in the kernel", 0); 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "thd:")) != EOF) 275*7c478bd9Sstevel@tonic-gate switch (c) { 276*7c478bd9Sstevel@tonic-gate case 't': 277*7c478bd9Sstevel@tonic-gate tflg++; 278*7c478bd9Sstevel@tonic-gate break; 279*7c478bd9Sstevel@tonic-gate case 'h': 280*7c478bd9Sstevel@tonic-gate hflg++; 281*7c478bd9Sstevel@tonic-gate break; 282*7c478bd9Sstevel@tonic-gate case 'd': 283*7c478bd9Sstevel@tonic-gate dleng = strlen(optarg); 284*7c478bd9Sstevel@tonic-gate 285*7c478bd9Sstevel@tonic-gate /* 286*7c478bd9Sstevel@tonic-gate * Controller types can be arbitrary length. 287*7c478bd9Sstevel@tonic-gate */ 288*7c478bd9Sstevel@tonic-gate devlen = strchr(optarg, '-') ? 289*7c478bd9Sstevel@tonic-gate strchr(optarg, '-') - optarg : dleng; 290*7c478bd9Sstevel@tonic-gate SCSI = 0; 291*7c478bd9Sstevel@tonic-gate strncpy(device, optarg, devlen); 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate if (dleng == (devlen+1)) { 294*7c478bd9Sstevel@tonic-gate errflg++; 295*7c478bd9Sstevel@tonic-gate break; 296*7c478bd9Sstevel@tonic-gate } 297*7c478bd9Sstevel@tonic-gate if (dleng > devlen) { 298*7c478bd9Sstevel@tonic-gate for (i = (devlen+1), n1 = (devlen+1); i < dleng; i++){ 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate if (optarg[i] == ','){ 301*7c478bd9Sstevel@tonic-gate if (n1 == i){ 302*7c478bd9Sstevel@tonic-gate errflg++; 303*7c478bd9Sstevel@tonic-gate break; 304*7c478bd9Sstevel@tonic-gate } 305*7c478bd9Sstevel@tonic-gate if (getdrvn() != 0) { 306*7c478bd9Sstevel@tonic-gate errflg++; 307*7c478bd9Sstevel@tonic-gate break; 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate if (dashf != 0) { 310*7c478bd9Sstevel@tonic-gate if (dashb >= dn){ 311*7c478bd9Sstevel@tonic-gate errflg++; 312*7c478bd9Sstevel@tonic-gate break; 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate for (j = dashb; j < dn+1; j++){ 315*7c478bd9Sstevel@tonic-gate if (SCSI) /* SCSI */ 316*7c478bd9Sstevel@tonic-gate Sdrvlist[j] = 1; 317*7c478bd9Sstevel@tonic-gate else 318*7c478bd9Sstevel@tonic-gate drvlist[j] = 1; 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate dashb = 0; 321*7c478bd9Sstevel@tonic-gate dashf = 0; 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate else 324*7c478bd9Sstevel@tonic-gate { 325*7c478bd9Sstevel@tonic-gate if (SCSI) 326*7c478bd9Sstevel@tonic-gate Sdrvlist[dn] = 1; 327*7c478bd9Sstevel@tonic-gate else 328*7c478bd9Sstevel@tonic-gate drvlist[dn] = 1; 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate n1 = i+1; 331*7c478bd9Sstevel@tonic-gate } else { 332*7c478bd9Sstevel@tonic-gate if (optarg[i] == '-'){ 333*7c478bd9Sstevel@tonic-gate if (dashf != 0) { 334*7c478bd9Sstevel@tonic-gate errflg++; 335*7c478bd9Sstevel@tonic-gate break; 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate if (getdrvn() != 0) { 338*7c478bd9Sstevel@tonic-gate errflg++; 339*7c478bd9Sstevel@tonic-gate break; 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate if (SCSI) 342*7c478bd9Sstevel@tonic-gate Sdrvlist[dn] = 1; 343*7c478bd9Sstevel@tonic-gate else 344*7c478bd9Sstevel@tonic-gate drvlist[dn] = 1; 345*7c478bd9Sstevel@tonic-gate dashb = dn; 346*7c478bd9Sstevel@tonic-gate dashf = 1; 347*7c478bd9Sstevel@tonic-gate n1 = i+1; 348*7c478bd9Sstevel@tonic-gate } else { 349*7c478bd9Sstevel@tonic-gate if (i == dleng-1){ 350*7c478bd9Sstevel@tonic-gate i++; 351*7c478bd9Sstevel@tonic-gate if (getdrvn() != 0) { 352*7c478bd9Sstevel@tonic-gate errflg++; 353*7c478bd9Sstevel@tonic-gate break; 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate if (dashf != 0) 356*7c478bd9Sstevel@tonic-gate for (j = dashb; j < dn+1; j++){ 357*7c478bd9Sstevel@tonic-gate if (SCSI) 358*7c478bd9Sstevel@tonic-gate Sdrvlist[j] = 1; 359*7c478bd9Sstevel@tonic-gate else 360*7c478bd9Sstevel@tonic-gate drvlist[j] = 1; 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate else 363*7c478bd9Sstevel@tonic-gate { 364*7c478bd9Sstevel@tonic-gate if (SCSI) 365*7c478bd9Sstevel@tonic-gate Sdrvlist[dn] = 1; 366*7c478bd9Sstevel@tonic-gate else 367*7c478bd9Sstevel@tonic-gate drvlist[dn] = 1; 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate } 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate } 373*7c478bd9Sstevel@tonic-gate } else { 374*7c478bd9Sstevel@tonic-gate if (dleng != devlen){ 375*7c478bd9Sstevel@tonic-gate errflg++; 376*7c478bd9Sstevel@tonic-gate break; 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate all++; 379*7c478bd9Sstevel@tonic-gate if (SCSI) 380*7c478bd9Sstevel@tonic-gate ALL++; 381*7c478bd9Sstevel@tonic-gate else 382*7c478bd9Sstevel@tonic-gate for (i = 0; i < MAX_HDISK_REP; i++) 383*7c478bd9Sstevel@tonic-gate drvlist[i] = 1; 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate if (errflg) 386*7c478bd9Sstevel@tonic-gate break; 387*7c478bd9Sstevel@tonic-gate dflg++; 388*7c478bd9Sstevel@tonic-gate break; 389*7c478bd9Sstevel@tonic-gate case '?': 390*7c478bd9Sstevel@tonic-gate errflg++; 391*7c478bd9Sstevel@tonic-gate break; 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate if (errflg) { 394*7c478bd9Sstevel@tonic-gate fprintf (stderr, "%s: errors in arguments\n", cmdname); 395*7c478bd9Sstevel@tonic-gate usage(); 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate /* 399*7c478bd9Sstevel@tonic-gate * If no frequency arguments present, exit. 400*7c478bd9Sstevel@tonic-gate */ 401*7c478bd9Sstevel@tonic-gate if (optind == argc) 402*7c478bd9Sstevel@tonic-gate usage(); 403*7c478bd9Sstevel@tonic-gate /* 404*7c478bd9Sstevel@tonic-gate * If a non-dash field is presented as an argument, 405*7c478bd9Sstevel@tonic-gate * check if it is a numerical arg. 406*7c478bd9Sstevel@tonic-gate */ 407*7c478bd9Sstevel@tonic-gate nopt = argv[optind]; 408*7c478bd9Sstevel@tonic-gate if (tstdigit(nopt) != 0) 409*7c478bd9Sstevel@tonic-gate usage(); 410*7c478bd9Sstevel@tonic-gate /* 411*7c478bd9Sstevel@tonic-gate * For frequency arguments, if only s is presented , set n to 1 412*7c478bd9Sstevel@tonic-gate */ 413*7c478bd9Sstevel@tonic-gate if ((optind +1) == argc) { 414*7c478bd9Sstevel@tonic-gate s = atoi(argv[optind]); 415*7c478bd9Sstevel@tonic-gate n = 1; 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate /* 418*7c478bd9Sstevel@tonic-gate * If both s and n are specified, check if 419*7c478bd9Sstevel@tonic-gate * arg n is numeric. 420*7c478bd9Sstevel@tonic-gate */ 421*7c478bd9Sstevel@tonic-gate if ((optind +1) < argc) { 422*7c478bd9Sstevel@tonic-gate nopt = argv[optind + 1]; 423*7c478bd9Sstevel@tonic-gate if (tstdigit(nopt) != 0) 424*7c478bd9Sstevel@tonic-gate usage(); 425*7c478bd9Sstevel@tonic-gate s = atoi(argv[optind]); 426*7c478bd9Sstevel@tonic-gate n = atoi(argv[optind+1]); 427*7c478bd9Sstevel@tonic-gate } 428*7c478bd9Sstevel@tonic-gate if (s <= 0) 429*7c478bd9Sstevel@tonic-gate fail("bad value of s", 0); 430*7c478bd9Sstevel@tonic-gate if (n <= 0) 431*7c478bd9Sstevel@tonic-gate fail("bad value of n", 0); 432*7c478bd9Sstevel@tonic-gate ct = s; 433*7c478bd9Sstevel@tonic-gate /* 434*7c478bd9Sstevel@tonic-gate * Get entries defined in setup from /stand/unix 435*7c478bd9Sstevel@tonic-gate */ 436*7c478bd9Sstevel@tonic-gate if ((kd = kvm_open (NULL, NULL, NULL, O_RDONLY, "Bad kvm open")) 437*7c478bd9Sstevel@tonic-gate == NULL) 438*7c478bd9Sstevel@tonic-gate fail("kvm_open failed", 1); 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "main: successful kvm_open\n"); 441*7c478bd9Sstevel@tonic-gate /* 442*7c478bd9Sstevel@tonic-gate * Search name list to get offsets. 443*7c478bd9Sstevel@tonic-gate */ 444*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "main: about to kvm_nlist\n"); 445*7c478bd9Sstevel@tonic-gate if (kvm_nlist(kd, setup) == -1) { 446*7c478bd9Sstevel@tonic-gate fail("kvm_nlist failed", 1); 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "main: good nlist\n"); 449*7c478bd9Sstevel@tonic-gate Debug dump_nlist (setup, "main"); 450*7c478bd9Sstevel@tonic-gate 451*7c478bd9Sstevel@tonic-gate /* 452*7c478bd9Sstevel@tonic-gate * Initialize buffers and get disk info. 453*7c478bd9Sstevel@tonic-gate */ 454*7c478bd9Sstevel@tonic-gate init_disk(); 455*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "init_disk\n"); 456*7c478bd9Sstevel@tonic-gate skdist = (long *)calloc(dk_ndrive, sizeof (long)); 457*7c478bd9Sstevel@tonic-gate disk = (long *)calloc(dk_ndrive, sizeof (long)); 458*7c478bd9Sstevel@tonic-gate 459*7c478bd9Sstevel@tonic-gate /* 460*7c478bd9Sstevel@tonic-gate * Make sure device and drive specified is legitimate. 461*7c478bd9Sstevel@tonic-gate */ 462*7c478bd9Sstevel@tonic-gate validate_device(); 463*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "validate_device\n"); 464*7c478bd9Sstevel@tonic-gate validate_drive(); 465*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "validate_drive\n"); 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate /* 468*7c478bd9Sstevel@tonic-gate * Get storage from memory for sysbuf pool and physical buf pool 469*7c478bd9Sstevel@tonic-gate */ 470*7c478bd9Sstevel@tonic-gate FETCH_IV (X1_V, tbl); 471*7c478bd9Sstevel@tonic-gate Debug dump_v_struct (&tbl); 472*7c478bd9Sstevel@tonic-gate sbuf = malloc(sizeof (struct buf) * tbl.v_buf); 473*7c478bd9Sstevel@tonic-gate if (sbuf == NULL) 474*7c478bd9Sstevel@tonic-gate fail("malloc of sbuf failed", 1); 475*7c478bd9Sstevel@tonic-gate phybuf = malloc(sizeof (struct buf) * tbl.v_pbuf); 476*7c478bd9Sstevel@tonic-gate if (phybuf == NULL) 477*7c478bd9Sstevel@tonic-gate fail("malloc of physbuf failed", 1); 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate /* 480*7c478bd9Sstevel@tonic-gate * Determine the number of CHUNK cylinder chunks on the disk. 481*7c478bd9Sstevel@tonic-gate * This will be referenced as CHPERCYL. 482*7c478bd9Sstevel@tonic-gate */ 483*7c478bd9Sstevel@tonic-gate init_geom(); 484*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "init_geom\n"); 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate ub = dk_ndrive; 487*7c478bd9Sstevel@tonic-gate #ifdef FIXME 488*7c478bd9Sstevel@tonic-gate FETCH_IAL(X1_DK_XFER, dk.dk_xfer, dk_ndrive*sizeof (long)); 489*7c478bd9Sstevel@tonic-gate FETCH_IAL(X1_DK_READ, dk.dk_read, dk_ndrive*sizeof (long)); 490*7c478bd9Sstevel@tonic-gate FETCH_IAL(X1_DK_SEEK, dk.dk_seek, dk_ndrive*sizeof (long)); 491*7c478bd9Sstevel@tonic-gate FETCH_IAL(X1_DK_WDS, dk.dk_wds, dk_ndrive*sizeof (long)); 492*7c478bd9Sstevel@tonic-gate FETCH_IAL(X1_DK_TIME, dk.dk_time, dk_ndrive*sizeof (long)); 493*7c478bd9Sstevel@tonic-gate #endif 494*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "%s: ub %d\n", cmdname, ub); 495*7c478bd9Sstevel@tonic-gate /* 496*7c478bd9Sstevel@tonic-gate * Get the list of scsi device pointers from kernel space. 497*7c478bd9Sstevel@tonic-gate */ 498*7c478bd9Sstevel@tonic-gate FETCH_IAL(X1_SDUNITS, sdunits, SD_MAXUNIT); 499*7c478bd9Sstevel@tonic-gate for (i = 0; i < SD_MAXUNIT; i++) { 500*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "sdunits[%d] 0x%x ", i, (int)sdunits[i]); 501*7c478bd9Sstevel@tonic-gate } 502*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "\n"); 503*7c478bd9Sstevel@tonic-gate for (k = 0, i = 0; k < ub; k++) { 504*7c478bd9Sstevel@tonic-gate if (drvlist[k] == 0) 505*7c478bd9Sstevel@tonic-gate continue; 506*7c478bd9Sstevel@tonic-gate /* 507*7c478bd9Sstevel@tonic-gate * Make sure that there is a scsi_device struct for 508*7c478bd9Sstevel@tonic-gate * the chosen device. 509*7c478bd9Sstevel@tonic-gate */ 510*7c478bd9Sstevel@tonic-gate if (!sdunits[k]) { 511*7c478bd9Sstevel@tonic-gate fprintf (stderr, "%s: no valid scsi_device struct\n", 512*7c478bd9Sstevel@tonic-gate cmdname); 513*7c478bd9Sstevel@tonic-gate } 514*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "%s: read unit %d\n", cmdname, k); 515*7c478bd9Sstevel@tonic-gate /* 516*7c478bd9Sstevel@tonic-gate * Read the scsi_device struct for the device. 517*7c478bd9Sstevel@tonic-gate */ 518*7c478bd9Sstevel@tonic-gate FETCH_AAL(sdunits[k], &sdunit[k], 519*7c478bd9Sstevel@tonic-gate sizeof (struct scsi_device), "sdunits"); 520*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "%s: sd_private 0x%x\n", 521*7c478bd9Sstevel@tonic-gate cmdname, (int)sdunit[k].sd_private); 522*7c478bd9Sstevel@tonic-gate } 523*7c478bd9Sstevel@tonic-gate 524*7c478bd9Sstevel@tonic-gate /* 525*7c478bd9Sstevel@tonic-gate * Get current I/O count for each drive. 526*7c478bd9Sstevel@tonic-gate */ 527*7c478bd9Sstevel@tonic-gate for (;;) { 528*7c478bd9Sstevel@tonic-gate s = ct; 529*7c478bd9Sstevel@tonic-gate for (k = 0, i = 0; k < ub; k++) { 530*7c478bd9Sstevel@tonic-gate if (drvlist[k] == 0) 531*7c478bd9Sstevel@tonic-gate continue; 532*7c478bd9Sstevel@tonic-gate for (j = 0; j < CHPERCYL; j++) { 533*7c478bd9Sstevel@tonic-gate dkcyl[i][j] = 0; 534*7c478bd9Sstevel@tonic-gate skcyl[i][j] = 0; 535*7c478bd9Sstevel@tonic-gate } 536*7c478bd9Sstevel@tonic-gate iocnt[i] = 0; 537*7c478bd9Sstevel@tonic-gate disk[i] = 0; 538*7c478bd9Sstevel@tonic-gate skdist[i] = 0; 539*7c478bd9Sstevel@tonic-gate i++; 540*7c478bd9Sstevel@tonic-gate } 541*7c478bd9Sstevel@tonic-gate /* 542*7c478bd9Sstevel@tonic-gate * If no drives are selected or illegal drive number 543*7c478bd9Sstevel@tonic-gate * is specified, exit. 544*7c478bd9Sstevel@tonic-gate */ 545*7c478bd9Sstevel@tonic-gate if (i == 0) 546*7c478bd9Sstevel@tonic-gate usage(); 547*7c478bd9Sstevel@tonic-gate 548*7c478bd9Sstevel@tonic-gate /* 549*7c478bd9Sstevel@tonic-gate * Get i/o count for each disk. 550*7c478bd9Sstevel@tonic-gate */ 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate for (k = 0, i = 0; k < ub; k++) { 553*7c478bd9Sstevel@tonic-gate if (drvlist[k] == 0) 554*7c478bd9Sstevel@tonic-gate continue; 555*7c478bd9Sstevel@tonic-gate iocnt[i] = dk.dk_xfer[k]; 556*7c478bd9Sstevel@tonic-gate i++; 557*7c478bd9Sstevel@tonic-gate } 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate cyl_no = 0; prev_cyl_no = 0; cyl_bk = 0; prev_cyl_bk = 0; seek_dist = 0; 560*7c478bd9Sstevel@tonic-gate for (;;) { 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate /* 563*7c478bd9Sstevel@tonic-gate * Take a snapshot of buffer header pool, swap 564*7c478bd9Sstevel@tonic-gate * buffer pool and physical buffer header. 565*7c478bd9Sstevel@tonic-gate */ 566*7c478bd9Sstevel@tonic-gate 567*7c478bd9Sstevel@tonic-gate /* 568*7c478bd9Sstevel@tonic-gate * read system buffer header pool. 569*7c478bd9Sstevel@tonic-gate */ 570*7c478bd9Sstevel@tonic-gate FETCH_IAL(X1_BUF, sbuf, tbl.v_buf*sizeof (struct buf)); 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate /* 573*7c478bd9Sstevel@tonic-gate * Read physical buffer header pool. 574*7c478bd9Sstevel@tonic-gate */ 575*7c478bd9Sstevel@tonic-gate FETCH_IAL(X1_PBUF, phybuf, tbl.v_pbuf*sizeof (struct buf)); 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate for (k = 0, i = 0; k < ub; k++) { 578*7c478bd9Sstevel@tonic-gate if (drvlist[k] == 0) 579*7c478bd9Sstevel@tonic-gate continue; 580*7c478bd9Sstevel@tonic-gate do_disk_stats (i, k); 581*7c478bd9Sstevel@tonic-gate i++; 582*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "%s: i %d\n", cmdname, i); 583*7c478bd9Sstevel@tonic-gate } 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate /* TBD - get more samples */ 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate if (--s) 588*7c478bd9Sstevel@tonic-gate sleep(1); 589*7c478bd9Sstevel@tonic-gate else { 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate /* 592*7c478bd9Sstevel@tonic-gate * At the end of sampling, get the present I/O 593*7c478bd9Sstevel@tonic-gate * count, and system name. 594*7c478bd9Sstevel@tonic-gate */ 595*7c478bd9Sstevel@tonic-gate uname(&name); 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate /* 598*7c478bd9Sstevel@tonic-gate * Print the report, there are two parts: 599*7c478bd9Sstevel@tonic-gate * cylinder profile, seeking distance profile. 600*7c478bd9Sstevel@tonic-gate */ 601*7c478bd9Sstevel@tonic-gate curt = time((long *) 0); 602*7c478bd9Sstevel@tonic-gate stime = ctime (&curt); 603*7c478bd9Sstevel@tonic-gate printf("\n\n%s\n", stime); 604*7c478bd9Sstevel@tonic-gate printf("%s %s %s %s %s\n", 605*7c478bd9Sstevel@tonic-gate name.sysname, 606*7c478bd9Sstevel@tonic-gate name.nodename, 607*7c478bd9Sstevel@tonic-gate name.release, 608*7c478bd9Sstevel@tonic-gate name.version, 609*7c478bd9Sstevel@tonic-gate name.machine); 610*7c478bd9Sstevel@tonic-gate for (k = 0, i = 0; k < ub; k++) { 611*7c478bd9Sstevel@tonic-gate if (drvlist[k] == 0) 612*7c478bd9Sstevel@tonic-gate continue; 613*7c478bd9Sstevel@tonic-gate for (j = 0; j < CHPERCYL; j++) { 614*7c478bd9Sstevel@tonic-gate disk[i] = disk[i] +dkcyl[i][j]; 615*7c478bd9Sstevel@tonic-gate skdist[i] = skdist[i] + skcyl[i][j]; 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate } 618*7c478bd9Sstevel@tonic-gate i++; 619*7c478bd9Sstevel@tonic-gate } 620*7c478bd9Sstevel@tonic-gate if ((tflg == 0) && (hflg == 0)) 621*7c478bd9Sstevel@tonic-gate tflg = 1; 622*7c478bd9Sstevel@tonic-gate if (tflg){ 623*7c478bd9Sstevel@tonic-gate printf("\nCYLINDER ACCESS PROFILE\n"); 624*7c478bd9Sstevel@tonic-gate for (k = 0, i = 0; k < ub; k++) { 625*7c478bd9Sstevel@tonic-gate if (drvlist[k] == 0) 626*7c478bd9Sstevel@tonic-gate continue; 627*7c478bd9Sstevel@tonic-gate if (disk[i] != 0){ 628*7c478bd9Sstevel@tonic-gate iocnt[i] = dk.dk_xfer[k] - iocnt[i]; 629*7c478bd9Sstevel@tonic-gate printf("\n%s-%d:\n", 630*7c478bd9Sstevel@tonic-gate device, k); 631*7c478bd9Sstevel@tonic-gate printf("Cylinders\tTransfers\n"); 632*7c478bd9Sstevel@tonic-gate for (j = 0; j < CHPERCYL; j++) { 633*7c478bd9Sstevel@tonic-gate if (dkcyl[i][j] > 0) 634*7c478bd9Sstevel@tonic-gate printf("%3d - %3d\t%ld\n", 635*7c478bd9Sstevel@tonic-gate j*8, j*8+7, dkcyl[i][j]); 636*7c478bd9Sstevel@tonic-gate } 637*7c478bd9Sstevel@tonic-gate printf("\nSampled I/O = %ld, Actual I/O = %ld\n", 638*7c478bd9Sstevel@tonic-gate disk[i], iocnt[i]); 639*7c478bd9Sstevel@tonic-gate if (iocnt[i] > 0) 640*7c478bd9Sstevel@tonic-gate printf("Percentage of I/O sampled = %2.2f\n", 641*7c478bd9Sstevel@tonic-gate ((float)disk[i] /(float)iocnt[i]) * 100.0); 642*7c478bd9Sstevel@tonic-gate } 643*7c478bd9Sstevel@tonic-gate i++; 644*7c478bd9Sstevel@tonic-gate } 645*7c478bd9Sstevel@tonic-gate 646*7c478bd9Sstevel@tonic-gate printf("\n\n\nSEEK DISTANCE PROFILE\n"); 647*7c478bd9Sstevel@tonic-gate for (k = 0, i = 0; k < ub; k++) { 648*7c478bd9Sstevel@tonic-gate if (drvlist[k] == 0) 649*7c478bd9Sstevel@tonic-gate continue; 650*7c478bd9Sstevel@tonic-gate if (skdist[i] != 0){ 651*7c478bd9Sstevel@tonic-gate printf("\n%s-%d:\n", 652*7c478bd9Sstevel@tonic-gate device, k); 653*7c478bd9Sstevel@tonic-gate printf("Seek Distance\tSeeks\n"); 654*7c478bd9Sstevel@tonic-gate for (j = 0; j < CHPERCYL; j++) 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate if (skcyl[i][j] > 0){ 657*7c478bd9Sstevel@tonic-gate if (j == 0) 658*7c478bd9Sstevel@tonic-gate printf(" 0\t%ld\n", 659*7c478bd9Sstevel@tonic-gate skcyl[i][j]); 660*7c478bd9Sstevel@tonic-gate else 661*7c478bd9Sstevel@tonic-gate printf("%3d - %3d\t%ld\n", 662*7c478bd9Sstevel@tonic-gate j*8-7, j*8, skcyl[i][j]); 663*7c478bd9Sstevel@tonic-gate } 664*7c478bd9Sstevel@tonic-gate printf("Total Seeks = %ld\n", skdist[i]); 665*7c478bd9Sstevel@tonic-gate } 666*7c478bd9Sstevel@tonic-gate i++; 667*7c478bd9Sstevel@tonic-gate } 668*7c478bd9Sstevel@tonic-gate } 669*7c478bd9Sstevel@tonic-gate if (hflg){ 670*7c478bd9Sstevel@tonic-gate for (k = 0, i = 0; k < ub; k++) { 671*7c478bd9Sstevel@tonic-gate if (drvlist[k] == 0) 672*7c478bd9Sstevel@tonic-gate continue; 673*7c478bd9Sstevel@tonic-gate if (disk[i] != 0) { 674*7c478bd9Sstevel@tonic-gate cylhdr(CYLNO, disk[i]); 675*7c478bd9Sstevel@tonic-gate cylhist(disk[i], dkcyl[i]); 676*7c478bd9Sstevel@tonic-gate cylftr(CYLNO); 677*7c478bd9Sstevel@tonic-gate } 678*7c478bd9Sstevel@tonic-gate i++; 679*7c478bd9Sstevel@tonic-gate } 680*7c478bd9Sstevel@tonic-gate for (k = 0, i = 0; k < ub; k++) { 681*7c478bd9Sstevel@tonic-gate if (drvlist[k] == 0) 682*7c478bd9Sstevel@tonic-gate continue; 683*7c478bd9Sstevel@tonic-gate if (skdist[i] != 0){ 684*7c478bd9Sstevel@tonic-gate cylhdr(SEEKD, skdist[i]); 685*7c478bd9Sstevel@tonic-gate cylhist(skdist[i], skcyl[i]); 686*7c478bd9Sstevel@tonic-gate cylftr(SEEKD); 687*7c478bd9Sstevel@tonic-gate } 688*7c478bd9Sstevel@tonic-gate i++; 689*7c478bd9Sstevel@tonic-gate } 690*7c478bd9Sstevel@tonic-gate } 691*7c478bd9Sstevel@tonic-gate 692*7c478bd9Sstevel@tonic-gate break; 693*7c478bd9Sstevel@tonic-gate } 694*7c478bd9Sstevel@tonic-gate } 695*7c478bd9Sstevel@tonic-gate if (--n) 696*7c478bd9Sstevel@tonic-gate continue; 697*7c478bd9Sstevel@tonic-gate exit(0); 698*7c478bd9Sstevel@tonic-gate } 699*7c478bd9Sstevel@tonic-gate } 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate void 702*7c478bd9Sstevel@tonic-gate do_disk_stats (i, k) 703*7c478bd9Sstevel@tonic-gate { 704*7c478bd9Sstevel@tonic-gate #ifdef fixed 705*7c478bd9Sstevel@tonic-gate struct scsi_disk sddisk[NDRIVE]; 706*7c478bd9Sstevel@tonic-gate struct diskhd *dp; 707*7c478bd9Sstevel@tonic-gate struct buf buffer, *bp; 708*7c478bd9Sstevel@tonic-gate struct buf *last_bp = 0; 709*7c478bd9Sstevel@tonic-gate 710*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "do_disk_stats (i %d, k %d)\n", i, k); 711*7c478bd9Sstevel@tonic-gate /* 712*7c478bd9Sstevel@tonic-gate * In each scsi_device struct there is a sd_private 713*7c478bd9Sstevel@tonic-gate * pointer to a specialised scsi_disk struct which 714*7c478bd9Sstevel@tonic-gate * describes the disk. 715*7c478bd9Sstevel@tonic-gate */ 716*7c478bd9Sstevel@tonic-gate do { 717*7c478bd9Sstevel@tonic-gate FETCH_AAL(sdunit[k].sd_private, &sddisk[k], 718*7c478bd9Sstevel@tonic-gate sizeof (struct scsi_disk), "sdunit"); 719*7c478bd9Sstevel@tonic-gate /* 720*7c478bd9Sstevel@tonic-gate * The diskhd struct describing the active and waiting 721*7c478bd9Sstevel@tonic-gate * queues is embedded in the scsi_disk struct. 722*7c478bd9Sstevel@tonic-gate */ 723*7c478bd9Sstevel@tonic-gate dp = &sddisk[k].un_utab; 724*7c478bd9Sstevel@tonic-gate Debug dump_diskhd (dp); 725*7c478bd9Sstevel@tonic-gate /* 726*7c478bd9Sstevel@tonic-gate * The current SunOS sd.c driver uses the b_forw 727*7c478bd9Sstevel@tonic-gate * pointer for the currently active buffer, and the 728*7c478bd9Sstevel@tonic-gate * b_actf (av_forw) pointer for the waiting queue 729*7c478bd9Sstevel@tonic-gate * of buffers. 730*7c478bd9Sstevel@tonic-gate */ 731*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "%s: b_forw 0x%x\n", cmdname, (int)dp->b_forw); 732*7c478bd9Sstevel@tonic-gate /* 733*7c478bd9Sstevel@tonic-gate * Trace disk queue for I/O location, seek distance. 734*7c478bd9Sstevel@tonic-gate */ 735*7c478bd9Sstevel@tonic-gate if (dp->b_forw) { 736*7c478bd9Sstevel@tonic-gate if (dp->b_forw == last_bp) { 737*7c478bd9Sstevel@tonic-gate continue; 738*7c478bd9Sstevel@tonic-gate } else { 739*7c478bd9Sstevel@tonic-gate last_bp = dp->b_forw; 740*7c478bd9Sstevel@tonic-gate } 741*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "%s: b_forw 0x%x\n", 742*7c478bd9Sstevel@tonic-gate cmdname, (int)dp->b_forw); 743*7c478bd9Sstevel@tonic-gate FETCH_AAL(dp->b_forw, &buffer, sizeof (struct buf), 744*7c478bd9Sstevel@tonic-gate "b_forw"); 745*7c478bd9Sstevel@tonic-gate bp = &buffer; 746*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "%s: b_lblkno 0x%x b_blkno 0x%x\n", 747*7c478bd9Sstevel@tonic-gate cmdname, bp->b_lblkno, bp->b_blkno); 748*7c478bd9Sstevel@tonic-gate cyl_no = bp->b_blkno / SECTPERCYL; 749*7c478bd9Sstevel@tonic-gate cyl_bk = cyl_no >> CHUNKSHIFT; 750*7c478bd9Sstevel@tonic-gate seek_dist = prev_cyl_no - cyl_no; 751*7c478bd9Sstevel@tonic-gate if (seek_dist < 0) 752*7c478bd9Sstevel@tonic-gate seek_dist = -seek_dist; 753*7c478bd9Sstevel@tonic-gate seek_bk = prev_cyl_bk - cyl_bk; 754*7c478bd9Sstevel@tonic-gate if (seek_bk < 0) 755*7c478bd9Sstevel@tonic-gate seek_bk = -seek_bk; 756*7c478bd9Sstevel@tonic-gate prev_cyl_no = cyl_no; 757*7c478bd9Sstevel@tonic-gate prev_cyl_bk = cyl_bk; 758*7c478bd9Sstevel@tonic-gate if (cyl_no > max_cyl_no) { 759*7c478bd9Sstevel@tonic-gate max_cyl_no = cyl_no; 760*7c478bd9Sstevel@tonic-gate } 761*7c478bd9Sstevel@tonic-gate if (seek_dist > max_seek_dist) { 762*7c478bd9Sstevel@tonic-gate max_seek_dist = seek_dist; 763*7c478bd9Sstevel@tonic-gate } 764*7c478bd9Sstevel@tonic-gate skcyl[i][seek_bk]++; 765*7c478bd9Sstevel@tonic-gate dkcyl[i][cyl_bk]++; 766*7c478bd9Sstevel@tonic-gate } 767*7c478bd9Sstevel@tonic-gate } while (dp->b_forw); 768*7c478bd9Sstevel@tonic-gate #endif 769*7c478bd9Sstevel@tonic-gate } 770*7c478bd9Sstevel@tonic-gate 771*7c478bd9Sstevel@tonic-gate 772*7c478bd9Sstevel@tonic-gate /* 773*7c478bd9Sstevel@tonic-gate * Determine if the I/O is from system buffer pool, 774*7c478bd9Sstevel@tonic-gate * or swap buffer pool or physical buffer. 775*7c478bd9Sstevel@tonic-gate */ 776*7c478bd9Sstevel@tonic-gate 777*7c478bd9Sstevel@tonic-gate int 778*7c478bd9Sstevel@tonic-gate testbuf() 779*7c478bd9Sstevel@tonic-gate { 780*7c478bd9Sstevel@tonic-gate if ((temp1 < setup[X1_BUF].n_value) || (index > tbl.v_buf)){ 781*7c478bd9Sstevel@tonic-gate index = (int)(temp1 -setup[X1_PBUF].n_value)/ 782*7c478bd9Sstevel@tonic-gate (sizeof (struct buf)); 783*7c478bd9Sstevel@tonic-gate if (index < tbl.v_pbuf){ 784*7c478bd9Sstevel@tonic-gate nonblk = 1; 785*7c478bd9Sstevel@tonic-gate return (0); 786*7c478bd9Sstevel@tonic-gate 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate /* TBD - Is it possible to access swap buffers on Sun? */ 789*7c478bd9Sstevel@tonic-gate #ifndef sun 790*7c478bd9Sstevel@tonic-gate index = (int)(temp1 -setup[SWP].n_value)/ 791*7c478bd9Sstevel@tonic-gate (sizeof (struct buf)); 792*7c478bd9Sstevel@tonic-gate if (index < NSWP) { 793*7c478bd9Sstevel@tonic-gate m = index; 794*7c478bd9Sstevel@tonic-gate nonblk = 2; 795*7c478bd9Sstevel@tonic-gate return (0); 796*7c478bd9Sstevel@tonic-gate } 797*7c478bd9Sstevel@tonic-gate #endif 798*7c478bd9Sstevel@tonic-gate return (-1); 799*7c478bd9Sstevel@tonic-gate } 800*7c478bd9Sstevel@tonic-gate return (0); 801*7c478bd9Sstevel@tonic-gate } 802*7c478bd9Sstevel@tonic-gate 803*7c478bd9Sstevel@tonic-gate /* 804*7c478bd9Sstevel@tonic-gate * Verify the I/O, get the cylinder number. 805*7c478bd9Sstevel@tonic-gate */ 806*7c478bd9Sstevel@tonic-gate 807*7c478bd9Sstevel@tonic-gate ckbits(x) 808*7c478bd9Sstevel@tonic-gate register struct buf *x; 809*7c478bd9Sstevel@tonic-gate { 810*7c478bd9Sstevel@tonic-gate register p; 811*7c478bd9Sstevel@tonic-gate for (p = 0; p < index; p++, x++) 812*7c478bd9Sstevel@tonic-gate continue; 813*7c478bd9Sstevel@tonic-gate if ((x->b_flags & B_BUSY) && 814*7c478bd9Sstevel@tonic-gate ((x->b_flags & B_DONE) == 0)){ 815*7c478bd9Sstevel@tonic-gate temp = x->cylin; 816*7c478bd9Sstevel@tonic-gate temp1 = (unsigned)x->av_forw; 817*7c478bd9Sstevel@tonic-gate return (0); 818*7c478bd9Sstevel@tonic-gate } 819*7c478bd9Sstevel@tonic-gate else 820*7c478bd9Sstevel@tonic-gate return (-1); 821*7c478bd9Sstevel@tonic-gate 822*7c478bd9Sstevel@tonic-gate } 823*7c478bd9Sstevel@tonic-gate int 824*7c478bd9Sstevel@tonic-gate testdev() 825*7c478bd9Sstevel@tonic-gate { 826*7c478bd9Sstevel@tonic-gate if ((nonblk == 0) && (ckbits((struct buf *)sbuf) != -1)) 827*7c478bd9Sstevel@tonic-gate goto endtest; 828*7c478bd9Sstevel@tonic-gate else { 829*7c478bd9Sstevel@tonic-gate if ((nonblk == 1) && (ckbits((struct buf *)phybuf) != -1)) 830*7c478bd9Sstevel@tonic-gate goto endtest; 831*7c478bd9Sstevel@tonic-gate 832*7c478bd9Sstevel@tonic-gate else { 833*7c478bd9Sstevel@tonic-gate 834*7c478bd9Sstevel@tonic-gate if ((nonblk == 2) && 835*7c478bd9Sstevel@tonic-gate ((bp[m].b_flags & B_BUSY) && 836*7c478bd9Sstevel@tonic-gate ((bp[m].b_flags & B_DONE) == 0))){ 837*7c478bd9Sstevel@tonic-gate temp = bp[m].cylin; 838*7c478bd9Sstevel@tonic-gate temp1 = (unsigned)bp[m].av_forw; 839*7c478bd9Sstevel@tonic-gate } else { 840*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "testdev -1\n"); 841*7c478bd9Sstevel@tonic-gate return (-1); 842*7c478bd9Sstevel@tonic-gate } 843*7c478bd9Sstevel@tonic-gate } 844*7c478bd9Sstevel@tonic-gate } 845*7c478bd9Sstevel@tonic-gate endtest: 846*7c478bd9Sstevel@tonic-gate dkcyl[i][temp >> 3]++; 847*7c478bd9Sstevel@tonic-gate return (0); 848*7c478bd9Sstevel@tonic-gate } 849*7c478bd9Sstevel@tonic-gate 850*7c478bd9Sstevel@tonic-gate 851*7c478bd9Sstevel@tonic-gate 852*7c478bd9Sstevel@tonic-gate /* 853*7c478bd9Sstevel@tonic-gate * Get drive number routine. 854*7c478bd9Sstevel@tonic-gate */ 855*7c478bd9Sstevel@tonic-gate getdrvn() 856*7c478bd9Sstevel@tonic-gate { 857*7c478bd9Sstevel@tonic-gate extern char *optarg; 858*7c478bd9Sstevel@tonic-gate char *strcpy(); 859*7c478bd9Sstevel@tonic-gate char *strncat(); 860*7c478bd9Sstevel@tonic-gate 861*7c478bd9Sstevel@tonic-gate strcpy(drive, empty); 862*7c478bd9Sstevel@tonic-gate strncat(drive, &optarg[n1], i-n1); 863*7c478bd9Sstevel@tonic-gate if (tstdigit(drive) != 0) 864*7c478bd9Sstevel@tonic-gate return (-1); 865*7c478bd9Sstevel@tonic-gate dn = atoi(drive); 866*7c478bd9Sstevel@tonic-gate if (SCSI) { 867*7c478bd9Sstevel@tonic-gate if (dn >= SNDRIVE) 868*7c478bd9Sstevel@tonic-gate return (-1); 869*7c478bd9Sstevel@tonic-gate } else { 870*7c478bd9Sstevel@tonic-gate if (dn >= NDRIVE) 871*7c478bd9Sstevel@tonic-gate return (-1); 872*7c478bd9Sstevel@tonic-gate } 873*7c478bd9Sstevel@tonic-gate return (0); 874*7c478bd9Sstevel@tonic-gate } 875*7c478bd9Sstevel@tonic-gate 876*7c478bd9Sstevel@tonic-gate void 877*7c478bd9Sstevel@tonic-gate usage() 878*7c478bd9Sstevel@tonic-gate { 879*7c478bd9Sstevel@tonic-gate fprintf(stderr, "usage: sadp [-th][-d device[-drive]] s [n]\n"); 880*7c478bd9Sstevel@tonic-gate exit(1); 881*7c478bd9Sstevel@tonic-gate } 882*7c478bd9Sstevel@tonic-gate 883*7c478bd9Sstevel@tonic-gate int tstdigit(ss) 884*7c478bd9Sstevel@tonic-gate char *ss; 885*7c478bd9Sstevel@tonic-gate { 886*7c478bd9Sstevel@tonic-gate int kk, cc; 887*7c478bd9Sstevel@tonic-gate kk = 0; 888*7c478bd9Sstevel@tonic-gate while ((cc = ss[kk]) != '\0'){ 889*7c478bd9Sstevel@tonic-gate if (isdigit(cc) == 0) 890*7c478bd9Sstevel@tonic-gate return (-1); 891*7c478bd9Sstevel@tonic-gate kk++; 892*7c478bd9Sstevel@tonic-gate } 893*7c478bd9Sstevel@tonic-gate return (0); 894*7c478bd9Sstevel@tonic-gate } 895*7c478bd9Sstevel@tonic-gate 896*7c478bd9Sstevel@tonic-gate /* 897*7c478bd9Sstevel@tonic-gate * The following routines are obtained from iostat. 898*7c478bd9Sstevel@tonic-gate * 899*7c478bd9Sstevel@tonic-gate * Output Cylinder Histogram. 900*7c478bd9Sstevel@tonic-gate */ 901*7c478bd9Sstevel@tonic-gate void 902*7c478bd9Sstevel@tonic-gate cylhist(at, dp) 903*7c478bd9Sstevel@tonic-gate long at; 904*7c478bd9Sstevel@tonic-gate register struct HISTDATA *dp; 905*7c478bd9Sstevel@tonic-gate { 906*7c478bd9Sstevel@tonic-gate register ii; 907*7c478bd9Sstevel@tonic-gate int maxrow; 908*7c478bd9Sstevel@tonic-gate long *graph = (long *)calloc(CHPERCYL, sizeof (long)); 909*7c478bd9Sstevel@tonic-gate long max, max2; 910*7c478bd9Sstevel@tonic-gate long data; 911*7c478bd9Sstevel@tonic-gate long scale; 912*7c478bd9Sstevel@tonic-gate 913*7c478bd9Sstevel@tonic-gate for (ii = 0; ii < CHPERCYL; ii++) { 914*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "(%d %d) ", ii, (int)dp->hdata[ii]); 915*7c478bd9Sstevel@tonic-gate } 916*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "\n"); 917*7c478bd9Sstevel@tonic-gate max = 0; 918*7c478bd9Sstevel@tonic-gate for (ii = 0; ii < CHPERCYL; ii++) { 919*7c478bd9Sstevel@tonic-gate if (data = dp->hdata[ii]) { 920*7c478bd9Sstevel@tonic-gate maxrow = ii; 921*7c478bd9Sstevel@tonic-gate if (data > max) { 922*7c478bd9Sstevel@tonic-gate max2 = max; 923*7c478bd9Sstevel@tonic-gate max = data; 924*7c478bd9Sstevel@tonic-gate } else if (data > max2 && data != max) 925*7c478bd9Sstevel@tonic-gate max2 = data; 926*7c478bd9Sstevel@tonic-gate } 927*7c478bd9Sstevel@tonic-gate } 928*7c478bd9Sstevel@tonic-gate maxrow++; 929*7c478bd9Sstevel@tonic-gate 930*7c478bd9Sstevel@tonic-gate /* determine scaling */ 931*7c478bd9Sstevel@tonic-gate scale = 1; 932*7c478bd9Sstevel@tonic-gate if (max2) { 933*7c478bd9Sstevel@tonic-gate scale = at / (max2 * 2); 934*7c478bd9Sstevel@tonic-gate if (scale > 48) 935*7c478bd9Sstevel@tonic-gate scale = 48; 936*7c478bd9Sstevel@tonic-gate } 937*7c478bd9Sstevel@tonic-gate 938*7c478bd9Sstevel@tonic-gate for (ii = 0; ii < maxrow; ii++) { 939*7c478bd9Sstevel@tonic-gate if (dp->hdata[ii]) 940*7c478bd9Sstevel@tonic-gate graph[ii] = (scale * 100 * dp->hdata[ii]) / at; 941*7c478bd9Sstevel@tonic-gate else 942*7c478bd9Sstevel@tonic-gate graph[ii] = -1; 943*7c478bd9Sstevel@tonic-gate } 944*7c478bd9Sstevel@tonic-gate 945*7c478bd9Sstevel@tonic-gate prthist(graph, maxrow, scale, (long) (max*100*scale/at)); 946*7c478bd9Sstevel@tonic-gate } 947*7c478bd9Sstevel@tonic-gate /* 948*7c478bd9Sstevel@tonic-gate * Print Histogram. 949*7c478bd9Sstevel@tonic-gate */ 950*7c478bd9Sstevel@tonic-gate void 951*7c478bd9Sstevel@tonic-gate prthist(array, mrow, scale, gmax) 952*7c478bd9Sstevel@tonic-gate long array[], scale, gmax; 953*7c478bd9Sstevel@tonic-gate register mrow; 954*7c478bd9Sstevel@tonic-gate { 955*7c478bd9Sstevel@tonic-gate long line; 956*7c478bd9Sstevel@tonic-gate 957*7c478bd9Sstevel@tonic-gate line = 50; 958*7c478bd9Sstevel@tonic-gate /* handle overflow in scaling */ 959*7c478bd9Sstevel@tonic-gate if (gmax > 51) { 960*7c478bd9Sstevel@tonic-gate line = 52; 961*7c478bd9Sstevel@tonic-gate printf("\n%2ld%% -|", gmax/scale); 962*7c478bd9Sstevel@tonic-gate pline(line--, array, mrow, BLOB); 963*7c478bd9Sstevel@tonic-gate printf("\n %c", BRK); 964*7c478bd9Sstevel@tonic-gate pline(line--, array, mrow, BRK); 965*7c478bd9Sstevel@tonic-gate } else if (gmax = 51) 966*7c478bd9Sstevel@tonic-gate line = 51; 967*7c478bd9Sstevel@tonic-gate while (line > 0) { 968*7c478bd9Sstevel@tonic-gate if ((line & 07) == 0) { 969*7c478bd9Sstevel@tonic-gate printf("\n%2ld%% -|", line/scale); 970*7c478bd9Sstevel@tonic-gate } else { 971*7c478bd9Sstevel@tonic-gate printf("\n |"); 972*7c478bd9Sstevel@tonic-gate } 973*7c478bd9Sstevel@tonic-gate pline(line--, array, mrow, BLOB); 974*7c478bd9Sstevel@tonic-gate } 975*7c478bd9Sstevel@tonic-gate printf("\n 0%% -+"); 976*7c478bd9Sstevel@tonic-gate line = -1; 977*7c478bd9Sstevel@tonic-gate pline(line, array, mrow, FOOT); 978*7c478bd9Sstevel@tonic-gate } 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate /* 981*7c478bd9Sstevel@tonic-gate * Print Histogram Line. 982*7c478bd9Sstevel@tonic-gate */ 983*7c478bd9Sstevel@tonic-gate void 984*7c478bd9Sstevel@tonic-gate pline(line, array, mrow, dot) 985*7c478bd9Sstevel@tonic-gate long line, array[]; 986*7c478bd9Sstevel@tonic-gate int mrow; 987*7c478bd9Sstevel@tonic-gate char dot; 988*7c478bd9Sstevel@tonic-gate { 989*7c478bd9Sstevel@tonic-gate register ii; 990*7c478bd9Sstevel@tonic-gate register char *lp; 991*7c478bd9Sstevel@tonic-gate char lbuff[132]; 992*7c478bd9Sstevel@tonic-gate 993*7c478bd9Sstevel@tonic-gate dfprintf (stderr, 994*7c478bd9Sstevel@tonic-gate "pline(line 0x%x, array 0x%x, mrow 0x%x, dot 0x%x)\n", 995*7c478bd9Sstevel@tonic-gate line, array, mrow, dot); 996*7c478bd9Sstevel@tonic-gate lp = lbuff; 997*7c478bd9Sstevel@tonic-gate for (ii = 0; ii < mrow; ii++) 998*7c478bd9Sstevel@tonic-gate if (array[ii] < line) 999*7c478bd9Sstevel@tonic-gate if (line == 1 && array[ii] == 0) 1000*7c478bd9Sstevel@tonic-gate *lp++ = TRACE; 1001*7c478bd9Sstevel@tonic-gate else 1002*7c478bd9Sstevel@tonic-gate *lp++ = BLANK; 1003*7c478bd9Sstevel@tonic-gate else 1004*7c478bd9Sstevel@tonic-gate *lp++ = dot; 1005*7c478bd9Sstevel@tonic-gate *lp++ = 0; 1006*7c478bd9Sstevel@tonic-gate printf("%s", lbuff); 1007*7c478bd9Sstevel@tonic-gate } 1008*7c478bd9Sstevel@tonic-gate /* 1009*7c478bd9Sstevel@tonic-gate * Print Cylinder Profiling Headers. 1010*7c478bd9Sstevel@tonic-gate */ 1011*7c478bd9Sstevel@tonic-gate void 1012*7c478bd9Sstevel@tonic-gate cylhdr(flag, total) 1013*7c478bd9Sstevel@tonic-gate long total; 1014*7c478bd9Sstevel@tonic-gate { 1015*7c478bd9Sstevel@tonic-gate 1016*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "cylhdr(flag 0x%x, total 0x%x)\n", flag, total); 1017*7c478bd9Sstevel@tonic-gate if (fflg) 1018*7c478bd9Sstevel@tonic-gate printf("\014\n"); 1019*7c478bd9Sstevel@tonic-gate if (flag == CYLNO) 1020*7c478bd9Sstevel@tonic-gate printf("\nCYLINDER ACCESS HISTOGRAM\n"); 1021*7c478bd9Sstevel@tonic-gate if (flag == SEEKD) 1022*7c478bd9Sstevel@tonic-gate printf("\nSEEK DISTANCE HISTOGRAM\n"); 1023*7c478bd9Sstevel@tonic-gate printf("\n%s-%d:\n", 1024*7c478bd9Sstevel@tonic-gate device, k); 1025*7c478bd9Sstevel@tonic-gate printf("Total %s = %ld\n", 1026*7c478bd9Sstevel@tonic-gate flag == CYLNO ? "transfers" : "seeks", total); 1027*7c478bd9Sstevel@tonic-gate } 1028*7c478bd9Sstevel@tonic-gate 1029*7c478bd9Sstevel@tonic-gate #define MAXCOL 80 1030*7c478bd9Sstevel@tonic-gate /* Print Histogram Footers */ 1031*7c478bd9Sstevel@tonic-gate void 1032*7c478bd9Sstevel@tonic-gate cylftr(flag) 1033*7c478bd9Sstevel@tonic-gate { 1034*7c478bd9Sstevel@tonic-gate int i; 1035*7c478bd9Sstevel@tonic-gate int chunk_mult = 1; 1036*7c478bd9Sstevel@tonic-gate int col; 1037*7c478bd9Sstevel@tonic-gate char footer[4][MAXCOL]; 1038*7c478bd9Sstevel@tonic-gate char digits[] = "0123456789"; 1039*7c478bd9Sstevel@tonic-gate int significant = 0; 1040*7c478bd9Sstevel@tonic-gate 1041*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "cylftr(flag 0x%x)\n", flag); 1042*7c478bd9Sstevel@tonic-gate if (flag == CYLNO) 1043*7c478bd9Sstevel@tonic-gate printf("\n \t\t\tCylinder number, granularity=%d", CHUNK); 1044*7c478bd9Sstevel@tonic-gate else 1045*7c478bd9Sstevel@tonic-gate printf("\n =<< "); 1046*7c478bd9Sstevel@tonic-gate for (i = 0; i < 4; i++) { 1047*7c478bd9Sstevel@tonic-gate for (col = 0; col < MAXCOL - 1; col++) { 1048*7c478bd9Sstevel@tonic-gate footer[i][col] = ' '; 1049*7c478bd9Sstevel@tonic-gate } 1050*7c478bd9Sstevel@tonic-gate footer[i][MAXCOL - 1] = '\0'; 1051*7c478bd9Sstevel@tonic-gate } 1052*7c478bd9Sstevel@tonic-gate for (i = 0, col = 0; i < (int)PHYS_CYL; 1053*7c478bd9Sstevel@tonic-gate i += (chunk_mult * CHUNK), col += chunk_mult, significant = 0) { 1054*7c478bd9Sstevel@tonic-gate if ((i / 1000) > 0) { 1055*7c478bd9Sstevel@tonic-gate footer[0][col] = digits[(i / 1000)]; 1056*7c478bd9Sstevel@tonic-gate significant = 1; 1057*7c478bd9Sstevel@tonic-gate } 1058*7c478bd9Sstevel@tonic-gate if ((significant) || (((i % 1000) / 100) > 0)) { 1059*7c478bd9Sstevel@tonic-gate footer[1][col] = digits[((i % 1000) / 100)]; 1060*7c478bd9Sstevel@tonic-gate significant = 1; 1061*7c478bd9Sstevel@tonic-gate } 1062*7c478bd9Sstevel@tonic-gate if ((significant) || (((i % 100) / 10) > 0)) { 1063*7c478bd9Sstevel@tonic-gate footer[2][col] = digits[((i % 100) / 10)]; 1064*7c478bd9Sstevel@tonic-gate significant = 1; 1065*7c478bd9Sstevel@tonic-gate } 1066*7c478bd9Sstevel@tonic-gate if ((i == 0) || (significant) || ((i % 10) > 0)) { 1067*7c478bd9Sstevel@tonic-gate footer[3][col] = digits[(i % 10)]; 1068*7c478bd9Sstevel@tonic-gate } 1069*7c478bd9Sstevel@tonic-gate if (i > CHUNK) { 1070*7c478bd9Sstevel@tonic-gate chunk_mult = 2; 1071*7c478bd9Sstevel@tonic-gate } 1072*7c478bd9Sstevel@tonic-gate if (i > (3 * CHUNK)) { 1073*7c478bd9Sstevel@tonic-gate chunk_mult = 4; 1074*7c478bd9Sstevel@tonic-gate if (flag != CYLNO) 1075*7c478bd9Sstevel@tonic-gate printf ("< "); 1076*7c478bd9Sstevel@tonic-gate } 1077*7c478bd9Sstevel@tonic-gate } 1078*7c478bd9Sstevel@tonic-gate for (i = 0; i < 4; i++) { 1079*7c478bd9Sstevel@tonic-gate printf (" %s\n", footer[i]); 1080*7c478bd9Sstevel@tonic-gate } 1081*7c478bd9Sstevel@tonic-gate printf ("\n"); 1082*7c478bd9Sstevel@tonic-gate } 1083*7c478bd9Sstevel@tonic-gate 1084*7c478bd9Sstevel@tonic-gate void 1085*7c478bd9Sstevel@tonic-gate validate_device() 1086*7c478bd9Sstevel@tonic-gate { 1087*7c478bd9Sstevel@tonic-gate int i; 1088*7c478bd9Sstevel@tonic-gate char tempdev[NAMESIZE]; 1089*7c478bd9Sstevel@tonic-gate 1090*7c478bd9Sstevel@tonic-gate if (dflg == 0) { 1091*7c478bd9Sstevel@tonic-gate 1092*7c478bd9Sstevel@tonic-gate /* 1093*7c478bd9Sstevel@tonic-gate * No device specified, so default to the first 1094*7c478bd9Sstevel@tonic-gate * one if it is the only one, otherwise prompt 1095*7c478bd9Sstevel@tonic-gate * user to enter one. 1096*7c478bd9Sstevel@tonic-gate */ 1097*7c478bd9Sstevel@tonic-gate strcpy(device, devnm[0]); 1098*7c478bd9Sstevel@tonic-gate *DRVNUM(device) = NULL; 1099*7c478bd9Sstevel@tonic-gate devlen = strlen(device); 1100*7c478bd9Sstevel@tonic-gate for (i = 0; i < dk_ndrive; i++) 1101*7c478bd9Sstevel@tonic-gate drvlist[i] = 1; 1102*7c478bd9Sstevel@tonic-gate if (dk_ndrive > 1) 1103*7c478bd9Sstevel@tonic-gate bad_device(device, ERR_NO_DEV); 1104*7c478bd9Sstevel@tonic-gate dev = 0; 1105*7c478bd9Sstevel@tonic-gate } else { 1106*7c478bd9Sstevel@tonic-gate 1107*7c478bd9Sstevel@tonic-gate /* 1108*7c478bd9Sstevel@tonic-gate * Device was specified. Make sure it matches 1109*7c478bd9Sstevel@tonic-gate * one that is configured in the system. 1110*7c478bd9Sstevel@tonic-gate */ 1111*7c478bd9Sstevel@tonic-gate for (i = 0; i < dk_ndrive; i++) { 1112*7c478bd9Sstevel@tonic-gate strncpy(tempdev, devnm[i], DRVNUM(devnm[i])-devnm[i]); 1113*7c478bd9Sstevel@tonic-gate tempdev[DRVNUM(devnm[i])-devnm[i]] = NULL; 1114*7c478bd9Sstevel@tonic-gate if (strcmp(device, tempdev) == 0) 1115*7c478bd9Sstevel@tonic-gate break; 1116*7c478bd9Sstevel@tonic-gate } 1117*7c478bd9Sstevel@tonic-gate if (i == dk_ndrive) 1118*7c478bd9Sstevel@tonic-gate bad_device(device, ERR_BAD_DEV); 1119*7c478bd9Sstevel@tonic-gate dev = i; 1120*7c478bd9Sstevel@tonic-gate } 1121*7c478bd9Sstevel@tonic-gate } 1122*7c478bd9Sstevel@tonic-gate 1123*7c478bd9Sstevel@tonic-gate void 1124*7c478bd9Sstevel@tonic-gate validate_drive() 1125*7c478bd9Sstevel@tonic-gate { 1126*7c478bd9Sstevel@tonic-gate int i, j, c; 1127*7c478bd9Sstevel@tonic-gate 1128*7c478bd9Sstevel@tonic-gate /* 1129*7c478bd9Sstevel@tonic-gate * For each controller number specified, make sure it exists 1130*7c478bd9Sstevel@tonic-gate * in the configured device list. 1131*7c478bd9Sstevel@tonic-gate */ 1132*7c478bd9Sstevel@tonic-gate for (i = 0; i < dk_ndrive; i++) { 1133*7c478bd9Sstevel@tonic-gate if (drvlist[i] == 0) 1134*7c478bd9Sstevel@tonic-gate continue; 1135*7c478bd9Sstevel@tonic-gate 1136*7c478bd9Sstevel@tonic-gate /* 1137*7c478bd9Sstevel@tonic-gate * Since this controller number (i) was specified, 1138*7c478bd9Sstevel@tonic-gate * find the corresponding entry (j) in the device list. 1139*7c478bd9Sstevel@tonic-gate * If found, save the device list index in drvlist[]. 1140*7c478bd9Sstevel@tonic-gate */ 1141*7c478bd9Sstevel@tonic-gate for (j = 0; j < dk_ndrive; j++) { 1142*7c478bd9Sstevel@tonic-gate if (strncmp(device, devnm[j], devlen) != 0) 1143*7c478bd9Sstevel@tonic-gate continue; 1144*7c478bd9Sstevel@tonic-gate c = atoi(DRVNUM(devnm[j])); 1145*7c478bd9Sstevel@tonic-gate if (c == i) { 1146*7c478bd9Sstevel@tonic-gate /* 1147*7c478bd9Sstevel@tonic-gate * NOTE: saved value actual index+1 1148*7c478bd9Sstevel@tonic-gate * as entries with 0 imply don't care. 1149*7c478bd9Sstevel@tonic-gate */ 1150*7c478bd9Sstevel@tonic-gate drvlist[i] = j+1; /* not a flag anymore! */ 1151*7c478bd9Sstevel@tonic-gate 1152*7c478bd9Sstevel@tonic-gate break; 1153*7c478bd9Sstevel@tonic-gate } 1154*7c478bd9Sstevel@tonic-gate } 1155*7c478bd9Sstevel@tonic-gate 1156*7c478bd9Sstevel@tonic-gate /* 1157*7c478bd9Sstevel@tonic-gate * If not found, output error, except if all drives 1158*7c478bd9Sstevel@tonic-gate * were implied by only specifying controller type. 1159*7c478bd9Sstevel@tonic-gate * In this case, flag it as don't care. 1160*7c478bd9Sstevel@tonic-gate */ 1161*7c478bd9Sstevel@tonic-gate if (j == dk_ndrive) { 1162*7c478bd9Sstevel@tonic-gate if (all) 1163*7c478bd9Sstevel@tonic-gate drvlist[i] = 0; 1164*7c478bd9Sstevel@tonic-gate else 1165*7c478bd9Sstevel@tonic-gate bad_device(device, ERR_BAD_UNIT); 1166*7c478bd9Sstevel@tonic-gate } 1167*7c478bd9Sstevel@tonic-gate } 1168*7c478bd9Sstevel@tonic-gate } 1169*7c478bd9Sstevel@tonic-gate 1170*7c478bd9Sstevel@tonic-gate void 1171*7c478bd9Sstevel@tonic-gate init_geom() 1172*7c478bd9Sstevel@tonic-gate { 1173*7c478bd9Sstevel@tonic-gate char tempdev[NAMESIZE]; 1174*7c478bd9Sstevel@tonic-gate int i, fd; 1175*7c478bd9Sstevel@tonic-gate /* 1176*7c478bd9Sstevel@tonic-gate * When the new device naming convention is in effect, switch to it 1177*7c478bd9Sstevel@tonic-gate */ 1178*7c478bd9Sstevel@tonic-gate #ifdef NEW_DEVICE_NAMES 1179*7c478bd9Sstevel@tonic-gate #define DEV_PREFIX "/dev/rdsk/" 1180*7c478bd9Sstevel@tonic-gate #else 1181*7c478bd9Sstevel@tonic-gate #define DEV_PREFIX "/dev/r" 1182*7c478bd9Sstevel@tonic-gate #endif 1183*7c478bd9Sstevel@tonic-gate 1184*7c478bd9Sstevel@tonic-gate for (i = 0; drvlist[i] == 0; i++); 1185*7c478bd9Sstevel@tonic-gate sprintf(tempdev, "%s%s%da", DEV_PREFIX, device, i); 1186*7c478bd9Sstevel@tonic-gate if ((fd = open(tempdev, O_RDONLY)) == -1) 1187*7c478bd9Sstevel@tonic-gate fail("open failed", 1); 1188*7c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCGGEOM, &dk_geom) == -1) { 1189*7c478bd9Sstevel@tonic-gate close(fd); 1190*7c478bd9Sstevel@tonic-gate fail("ioctl failed", 1); 1191*7c478bd9Sstevel@tonic-gate } 1192*7c478bd9Sstevel@tonic-gate close(fd); 1193*7c478bd9Sstevel@tonic-gate 1194*7c478bd9Sstevel@tonic-gate /* 1195*7c478bd9Sstevel@tonic-gate * dk_geom structure now has data, and the number 1196*7c478bd9Sstevel@tonic-gate * of 8 cylinder chunks on the disk can now be 1197*7c478bd9Sstevel@tonic-gate * referenced via the CHPERCYL macro. So allocate 1198*7c478bd9Sstevel@tonic-gate * appropriate buffers based on this value. 1199*7c478bd9Sstevel@tonic-gate */ 1200*7c478bd9Sstevel@tonic-gate iocnt = (long *)calloc(dk_ndrive, sizeof (long)); 1201*7c478bd9Sstevel@tonic-gate dkcyl = (long **)calloc(dk_ndrive, sizeof (long *)); 1202*7c478bd9Sstevel@tonic-gate skcyl = (long **)calloc(dk_ndrive, sizeof (long *)); 1203*7c478bd9Sstevel@tonic-gate for (i = 0; i < dk_ndrive; i++) { 1204*7c478bd9Sstevel@tonic-gate dkcyl[i] = (long *)calloc(CHPERCYL, sizeof (long)); 1205*7c478bd9Sstevel@tonic-gate skcyl[i] = (long *)calloc(CHPERCYL, sizeof (long)); 1206*7c478bd9Sstevel@tonic-gate } 1207*7c478bd9Sstevel@tonic-gate } 1208*7c478bd9Sstevel@tonic-gate 1209*7c478bd9Sstevel@tonic-gate /* 1210*7c478bd9Sstevel@tonic-gate * General routine for printing out an error message 1211*7c478bd9Sstevel@tonic-gate * when the specified device/drive is insufficient. 1212*7c478bd9Sstevel@tonic-gate */ 1213*7c478bd9Sstevel@tonic-gate void 1214*7c478bd9Sstevel@tonic-gate bad_device(device, errmsg) 1215*7c478bd9Sstevel@tonic-gate char *device; 1216*7c478bd9Sstevel@tonic-gate char *errmsg; 1217*7c478bd9Sstevel@tonic-gate { 1218*7c478bd9Sstevel@tonic-gate int i, j; 1219*7c478bd9Sstevel@tonic-gate int unique = 0; 1220*7c478bd9Sstevel@tonic-gate char *p, *p1, **buf; 1221*7c478bd9Sstevel@tonic-gate char s[NAMESIZE]; 1222*7c478bd9Sstevel@tonic-gate char *msg; 1223*7c478bd9Sstevel@tonic-gate 1224*7c478bd9Sstevel@tonic-gate 1225*7c478bd9Sstevel@tonic-gate /* 1226*7c478bd9Sstevel@tonic-gate * Print usage statement if no device is specified. 1227*7c478bd9Sstevel@tonic-gate */ 1228*7c478bd9Sstevel@tonic-gate if (device[0] == NULL) 1229*7c478bd9Sstevel@tonic-gate usage(); 1230*7c478bd9Sstevel@tonic-gate 1231*7c478bd9Sstevel@tonic-gate /* 1232*7c478bd9Sstevel@tonic-gate * Compose a list of unique device controller types, or 1233*7c478bd9Sstevel@tonic-gate * unit numbers for a specified controller type, from 1234*7c478bd9Sstevel@tonic-gate * the complete device list. 1235*7c478bd9Sstevel@tonic-gate */ 1236*7c478bd9Sstevel@tonic-gate buf = (char **)calloc(dk_ndrive, sizeof (char *)); 1237*7c478bd9Sstevel@tonic-gate for (i = 0; i < dk_ndrive; i++) { 1238*7c478bd9Sstevel@tonic-gate 1239*7c478bd9Sstevel@tonic-gate /* 1240*7c478bd9Sstevel@tonic-gate * Get controller type or unit 1241*7c478bd9Sstevel@tonic-gate */ 1242*7c478bd9Sstevel@tonic-gate p = devnm[i]; 1243*7c478bd9Sstevel@tonic-gate p1 = DRVNUM(devnm[i]); 1244*7c478bd9Sstevel@tonic-gate if (!strcmp(errmsg, ERR_BAD_UNIT)) { 1245*7c478bd9Sstevel@tonic-gate if (strncmp(devnm[i], device, devlen)) 1246*7c478bd9Sstevel@tonic-gate continue; 1247*7c478bd9Sstevel@tonic-gate p = p1; 1248*7c478bd9Sstevel@tonic-gate p1++; 1249*7c478bd9Sstevel@tonic-gate } 1250*7c478bd9Sstevel@tonic-gate strncpy(s, p, p1-p); 1251*7c478bd9Sstevel@tonic-gate s[p1-p] = NULL; 1252*7c478bd9Sstevel@tonic-gate 1253*7c478bd9Sstevel@tonic-gate /* 1254*7c478bd9Sstevel@tonic-gate * Have we already logged this one as unique? 1255*7c478bd9Sstevel@tonic-gate * If not, then do so now. 1256*7c478bd9Sstevel@tonic-gate */ 1257*7c478bd9Sstevel@tonic-gate for (j = 0; j < unique; j++) 1258*7c478bd9Sstevel@tonic-gate if (!strcmp(s, buf[j])) 1259*7c478bd9Sstevel@tonic-gate break; 1260*7c478bd9Sstevel@tonic-gate if (j == unique) 1261*7c478bd9Sstevel@tonic-gate buf[unique++] = strdup(s); 1262*7c478bd9Sstevel@tonic-gate } 1263*7c478bd9Sstevel@tonic-gate 1264*7c478bd9Sstevel@tonic-gate /* 1265*7c478bd9Sstevel@tonic-gate * Invalid device was specified. Compose message containing 1266*7c478bd9Sstevel@tonic-gate * list of valid devices. 1267*7c478bd9Sstevel@tonic-gate */ 1268*7c478bd9Sstevel@tonic-gate msg = (char *)malloc(strlen(errmsg) + 1269*7c478bd9Sstevel@tonic-gate strlen(device) + unique*(NAMESIZE+1) + 1); 1270*7c478bd9Sstevel@tonic-gate sprintf(msg, errmsg, device); 1271*7c478bd9Sstevel@tonic-gate for (p = msg + strlen(msg), i = 0; i < unique; i++) { 1272*7c478bd9Sstevel@tonic-gate sprintf(p, "%s ", buf[i]); 1273*7c478bd9Sstevel@tonic-gate p += (strlen(buf[i])+ 1); 1274*7c478bd9Sstevel@tonic-gate } 1275*7c478bd9Sstevel@tonic-gate 1276*7c478bd9Sstevel@tonic-gate /* 1277*7c478bd9Sstevel@tonic-gate * Output the message and exit. 1278*7c478bd9Sstevel@tonic-gate */ 1279*7c478bd9Sstevel@tonic-gate fail(msg, 0); 1280*7c478bd9Sstevel@tonic-gate } 1281*7c478bd9Sstevel@tonic-gate 1282*7c478bd9Sstevel@tonic-gate /* 1283*7c478bd9Sstevel@tonic-gate * Code below here was taken from the SunOS 5.0 iostat command. 1284*7c478bd9Sstevel@tonic-gate */ 1285*7c478bd9Sstevel@tonic-gate 1286*7c478bd9Sstevel@tonic-gate #ifdef FIXME 1287*7c478bd9Sstevel@tonic-gate 1288*7c478bd9Sstevel@tonic-gate void 1289*7c478bd9Sstevel@tonic-gate read_devinfo_names() 1290*7c478bd9Sstevel@tonic-gate { 1291*7c478bd9Sstevel@tonic-gate int i; 1292*7c478bd9Sstevel@tonic-gate struct dk_ivec dkivec[NDRIVE]; 1293*7c478bd9Sstevel@tonic-gate 1294*7c478bd9Sstevel@tonic-gate safe_kvm_read (kd, nl_4c[X1_DK_IVEC].n_value, dkivec, sizeof dkivec, 1295*7c478bd9Sstevel@tonic-gate "dk_ivec"); 1296*7c478bd9Sstevel@tonic-gate for (i = 0; i < NDRIVE; i++) { 1297*7c478bd9Sstevel@tonic-gate if (dkivec[i].dk_name) { 1298*7c478bd9Sstevel@tonic-gate safe_kvm_read (kd, dkivec[i].dk_name, dr_name[i], 2, 1299*7c478bd9Sstevel@tonic-gate "dk_name"); 1300*7c478bd9Sstevel@tonic-gate sprintf(dr_name[i] + 2, "%d", dkivec[i].dk_unit); 1301*7c478bd9Sstevel@tonic-gate } 1302*7c478bd9Sstevel@tonic-gate } 1303*7c478bd9Sstevel@tonic-gate } 1304*7c478bd9Sstevel@tonic-gate 1305*7c478bd9Sstevel@tonic-gate #endif 1306*7c478bd9Sstevel@tonic-gate 1307*7c478bd9Sstevel@tonic-gate void 1308*7c478bd9Sstevel@tonic-gate init_disk() 1309*7c478bd9Sstevel@tonic-gate { 1310*7c478bd9Sstevel@tonic-gate #ifdef FIXME 1311*7c478bd9Sstevel@tonic-gate int i; 1312*7c478bd9Sstevel@tonic-gate 1313*7c478bd9Sstevel@tonic-gate for (i = 0; i < NDRIVE; i++) { 1314*7c478bd9Sstevel@tonic-gate dr_select[i] = 0; 1315*7c478bd9Sstevel@tonic-gate dk_bps[i] = 0; 1316*7c478bd9Sstevel@tonic-gate } 1317*7c478bd9Sstevel@tonic-gate 1318*7c478bd9Sstevel@tonic-gate /* 1319*7c478bd9Sstevel@tonic-gate * The default device names: dk# 1320*7c478bd9Sstevel@tonic-gate */ 1321*7c478bd9Sstevel@tonic-gate for (i = 0; i < dk_ndrive; i++) { 1322*7c478bd9Sstevel@tonic-gate dr_name[i] = buf; 1323*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "dk%d", i); 1324*7c478bd9Sstevel@tonic-gate buf += NAMESIZE; 1325*7c478bd9Sstevel@tonic-gate } 1326*7c478bd9Sstevel@tonic-gate 1327*7c478bd9Sstevel@tonic-gate /* 1328*7c478bd9Sstevel@tonic-gate * Device names must be discovered in this program, and output 1329*7c478bd9Sstevel@tonic-gate * with its io data via the "sa" structure. 1330*7c478bd9Sstevel@tonic-gate */ 1331*7c478bd9Sstevel@tonic-gate 1332*7c478bd9Sstevel@tonic-gate read_devinfo_names(); 1333*7c478bd9Sstevel@tonic-gate #else 1334*7c478bd9Sstevel@tonic-gate return; 1335*7c478bd9Sstevel@tonic-gate #endif 1336*7c478bd9Sstevel@tonic-gate } 1337*7c478bd9Sstevel@tonic-gate 1338*7c478bd9Sstevel@tonic-gate /* 1339*7c478bd9Sstevel@tonic-gate * issue failure message and exit 1340*7c478bd9Sstevel@tonic-gate */ 1341*7c478bd9Sstevel@tonic-gate void 1342*7c478bd9Sstevel@tonic-gate fail(message, doperror) 1343*7c478bd9Sstevel@tonic-gate char *message; 1344*7c478bd9Sstevel@tonic-gate int doperror; 1345*7c478bd9Sstevel@tonic-gate { 1346*7c478bd9Sstevel@tonic-gate if (kd != NULL) 1347*7c478bd9Sstevel@tonic-gate (void) kvm_close(kd); 1348*7c478bd9Sstevel@tonic-gate 1349*7c478bd9Sstevel@tonic-gate if (doperror) { 1350*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: ", cmdname); 1351*7c478bd9Sstevel@tonic-gate perror(message); 1352*7c478bd9Sstevel@tonic-gate } 1353*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s\n", cmdname, message); 1354*7c478bd9Sstevel@tonic-gate exit(2); 1355*7c478bd9Sstevel@tonic-gate } 1356*7c478bd9Sstevel@tonic-gate 1357*7c478bd9Sstevel@tonic-gate void 1358*7c478bd9Sstevel@tonic-gate safe_kvm_read(kd, addr, buf, size, who) 1359*7c478bd9Sstevel@tonic-gate kvm_t *kd; 1360*7c478bd9Sstevel@tonic-gate unsigned long addr; 1361*7c478bd9Sstevel@tonic-gate char *buf; 1362*7c478bd9Sstevel@tonic-gate unsigned size; 1363*7c478bd9Sstevel@tonic-gate { 1364*7c478bd9Sstevel@tonic-gate int ret_code; 1365*7c478bd9Sstevel@tonic-gate char errmsg[100]; 1366*7c478bd9Sstevel@tonic-gate 1367*7c478bd9Sstevel@tonic-gate if (addr == 0) { 1368*7c478bd9Sstevel@tonic-gate sprintf(errmsg, "kvm_read of %s failed -- no address", who); 1369*7c478bd9Sstevel@tonic-gate fail(errmsg, 0); 1370*7c478bd9Sstevel@tonic-gate } 1371*7c478bd9Sstevel@tonic-gate 1372*7c478bd9Sstevel@tonic-gate ret_code = kvm_read(kd, addr, buf, size); 1373*7c478bd9Sstevel@tonic-gate if (ret_code != size) { 1374*7c478bd9Sstevel@tonic-gate sprintf(errmsg, "kvm_read of %s failed with code %d", 1375*7c478bd9Sstevel@tonic-gate who, ret_code); 1376*7c478bd9Sstevel@tonic-gate fail(errmsg, 0); 1377*7c478bd9Sstevel@tonic-gate } 1378*7c478bd9Sstevel@tonic-gate } 1379*7c478bd9Sstevel@tonic-gate 1380*7c478bd9Sstevel@tonic-gate /* 1381*7c478bd9Sstevel@tonic-gate * code for debugging dumps 1382*7c478bd9Sstevel@tonic-gate */ 1383*7c478bd9Sstevel@tonic-gate 1384*7c478bd9Sstevel@tonic-gate #include <sys/tuneable.h> 1385*7c478bd9Sstevel@tonic-gate #include <sys/var.h> 1386*7c478bd9Sstevel@tonic-gate #include <sys/file.h> 1387*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 1388*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 1389*7c478bd9Sstevel@tonic-gate #include <sys/buf.h> 1390*7c478bd9Sstevel@tonic-gate #include <sys/fs/rf_acct.h> 1391*7c478bd9Sstevel@tonic-gate 1392*7c478bd9Sstevel@tonic-gate int dump_iodev (); 1393*7c478bd9Sstevel@tonic-gate 1394*7c478bd9Sstevel@tonic-gate dump_diskhd (dp) 1395*7c478bd9Sstevel@tonic-gate struct diskhd *dp; 1396*7c478bd9Sstevel@tonic-gate { 1397*7c478bd9Sstevel@tonic-gate 1398*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "dump_diskhd: dp 0x%x\n", (int)dp); 1399*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "flags\tb_forw\tb_back\tav_forw\tav_back\tb_bcount\n0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t%d\n", 1400*7c478bd9Sstevel@tonic-gate (int)dp->b_flags, (int)dp->b_forw, (int)dp->b_back, 1401*7c478bd9Sstevel@tonic-gate (int)dp->av_forw, (int)dp->av_back, (int)dp->b_bcount); 1402*7c478bd9Sstevel@tonic-gate 1403*7c478bd9Sstevel@tonic-gate return (0); 1404*7c478bd9Sstevel@tonic-gate } 1405*7c478bd9Sstevel@tonic-gate 1406*7c478bd9Sstevel@tonic-gate dump_nlist (nlist, str) 1407*7c478bd9Sstevel@tonic-gate struct nlist nlist[]; 1408*7c478bd9Sstevel@tonic-gate char *str; 1409*7c478bd9Sstevel@tonic-gate { 1410*7c478bd9Sstevel@tonic-gate int i; 1411*7c478bd9Sstevel@tonic-gate 1412*7c478bd9Sstevel@tonic-gate for (i = 0; nlist[i].n_name; i++) { 1413*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "%s: i %d n_name '%s' n_value 0x%x\n", 1414*7c478bd9Sstevel@tonic-gate str, i, nlist[i].n_name, (int)nlist[i].n_value); 1415*7c478bd9Sstevel@tonic-gate } 1416*7c478bd9Sstevel@tonic-gate 1417*7c478bd9Sstevel@tonic-gate return (0); 1418*7c478bd9Sstevel@tonic-gate } 1419*7c478bd9Sstevel@tonic-gate 1420*7c478bd9Sstevel@tonic-gate dump_v_struct (tbl) 1421*7c478bd9Sstevel@tonic-gate struct var *tbl; 1422*7c478bd9Sstevel@tonic-gate { 1423*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "dump_v_struct: tbl 0x%x\n", (int)tbl); 1424*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "v_buf\tv_call\tv_proc\tv_nglobpris\n%d\t%d\t%d\t%d\n", 1425*7c478bd9Sstevel@tonic-gate tbl->v_buf, tbl->v_call, tbl->v_proc, tbl->v_nglobpris); 1426*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "v_maxsyspri\tv_clist\tv_maxup\tv_hbuf\n%d\t\t%d\t%d\t%d\n", 1427*7c478bd9Sstevel@tonic-gate tbl->v_maxsyspri, tbl->v_clist, tbl->v_maxup, tbl->v_hbuf); 1428*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "v_hmask\tv_pbuf\tv_sptmap\tv_maxpmem\n0x%x\t%d\t%d\t\t%d\n", 1429*7c478bd9Sstevel@tonic-gate tbl->v_hmask, tbl->v_pbuf, tbl->v_sptmap, tbl->v_maxpmem); 1430*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "v_autoup\tv_bufhwm\n%d\t\t%d\n", 1431*7c478bd9Sstevel@tonic-gate tbl->v_autoup, tbl->v_bufhwm); 1432*7c478bd9Sstevel@tonic-gate 1433*7c478bd9Sstevel@tonic-gate return (0); 1434*7c478bd9Sstevel@tonic-gate } 1435*7c478bd9Sstevel@tonic-gate 1436*7c478bd9Sstevel@tonic-gate dump_tblmap (tbl, size) 1437*7c478bd9Sstevel@tonic-gate int *tbl; 1438*7c478bd9Sstevel@tonic-gate int size; 1439*7c478bd9Sstevel@tonic-gate { 1440*7c478bd9Sstevel@tonic-gate int i; 1441*7c478bd9Sstevel@tonic-gate 1442*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "tblmap size %d/4 = %d ", size, size/4); 1443*7c478bd9Sstevel@tonic-gate for (i = 0; i < size/4; i++) { 1444*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "tblmap[%d] %d ", i, tbl[i]); 1445*7c478bd9Sstevel@tonic-gate } 1446*7c478bd9Sstevel@tonic-gate dfprintf (stderr, "\n"); 1447*7c478bd9Sstevel@tonic-gate 1448*7c478bd9Sstevel@tonic-gate return (0); 1449*7c478bd9Sstevel@tonic-gate } 1450