From d3d32e94615bd7b44139c48d97167020d74fa5b0 Mon Sep 17 00:00:00 2001 From: Peter Tribble Date: Sun, 21 May 2017 22:03:05 +0100 Subject: 8262 sadp is neither built nor used Reviewed by: Yuri Pankov Reviewed by: Toomas Soome Approved by: Robert Mustacchi --- usr/src/cmd/sa/Makefile | 5 +- usr/src/cmd/sa/sadp.c | 1449 ----------------------------------------------- 2 files changed, 2 insertions(+), 1452 deletions(-) delete mode 100644 usr/src/cmd/sa/sadp.c (limited to 'usr/src/cmd/sa') diff --git a/usr/src/cmd/sa/Makefile b/usr/src/cmd/sa/Makefile index 33709e45ce..8e8e9bd0ce 100644 --- a/usr/src/cmd/sa/Makefile +++ b/usr/src/cmd/sa/Makefile @@ -39,7 +39,6 @@ CERRWARN += -_gcc=-Wno-uninitialized GREP= grep SADC= sadc -SADP= sadp SAR= sar TIMEX= timex SA1= sa1 @@ -56,7 +55,7 @@ INITSHELL= $(PERF) PROGS= $(BINPROG) $(SBINPROG) $(LIBPROG) SHELLS= $(LIBSHELL) -TXTS= $(SADP).c README +TXTS= README ALL= $(PROGS) $(SHELLS) # Source files @@ -129,7 +128,7 @@ $(ETCINITD)/%: % check: $(CHKMANIFEST) clean: - $(RM) $(SADC_OBJECTS) $(PROGS) $(SHELLS) $(SADP) + $(RM) $(SADC_OBJECTS) $(PROGS) $(SHELLS) lint: lint_SRCS diff --git a/usr/src/cmd/sa/sadp.c b/usr/src/cmd/sa/sadp.c deleted file mode 100644 index d8b259cfb7..0000000000 --- a/usr/src/cmd/sa/sadp.c +++ /dev/null @@ -1,1449 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1994 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* sadp.c 1.14.1.12 of 8/9/89 */ -/* sadp.c - For VAX and PDP11 machines, - disk profiler profiles rp06, rm05 and general disk drives. - It reads system buffer header pool, physical buffer header - pool and swap buffer header pool once every second, - to examine disk drive's I/O queue. - For 3b20s system, it profiles the regular disk drives, - it reads the circular output queue for each drive - once every second. - usage : sadp [-th][-d device[-drive]] s [n] -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#ifdef FIXME -#include -#endif - -#include -#include -#include -#include -#include -#include - -/* - * These includes are for dealing with scsi targets. - */ -#include -#include -#include -#include - - -/* cylinder profiling */ -#define BLANK ' ' -#define BLOB '*' -#define TRACE '.' -#define BRK '=' -#define FOOT '-' -#define CYLNO 1 -#define SEEKD 2 - -struct dk_geom dk_geom; -#define CHUNK 16 -#define CHUNKSHIFT 4 -#define PHYS_CYL dk_geom.dkg_pcyl -#define CHPERCYL (int)(PHYS_CYL/CHUNK) /* - * the number of CHUNK cylinder - * chunks on a disk - */ -#define SECTPERTRK (int)(dk_geom.dkg_nsect) /* sectors per track */ -#define SECTPERCYL (SECTPERTRK * (int)(dk_geom.dkg_nhead)) -#define ERR_BAD_DEV "Device %s is not defined, valid devices are: " -#define ERR_BAD_UNIT \ - "Invalid drive specified for device %s, valid drives are: " -#define ERR_NO_DEV "Please specify a device type, valid devices are: " -#define DRVNUM(devname) strpbrk(devname, "0123456789") - -#define cylin b_resid -#define NDRIVE 10 -#define SNDRIVE NDRIVE /* Not used */ -#define MAX_HDISK_REP NDRIVE -#define MAXDRIVE 20 /* maximum number of configured disks */ -#define NAMESIZE 10 /* size of device names */ - - -struct nlist setup[] = { - -#define X1_V 0 - {"v"}, -#define X1_BUF 1 - {"buf"}, -#define X1_PBUF 2 - {"pbuf"}, -#define X1_SDUNITS 3 - {"sdunits"}, -#ifdef FIXME -#define X1_DK_NDRIVE 4 - {"dk_ndrive"}, -#define X1_DK_BUSY 5 - {"dk_busy"}, -#define X1_DK_TIME 6 - {"dk_time"}, -#define X1_DK_SEEK 7 - {"dk_seek"}, -#define X1_DK_XFER 8 - {"dk_xfer"}, -#define X1_DK_WDS 9 - {"dk_wds"}, -#define X1_DK_BPS 10 - {"dk_bps"}, -#define X1_DK_READ 11 - {"dk_read"}, -#define X1_DK_IVEC 12 - {"dk_ivec"}, -#define X1_NUMSYMBOLS 13 -#else -#define X1_NUMSYMBOLS 4 -#endif - {0} -}; - -void do_disk_stats (); -void usage (); -void prthist (); -void pline (); -void cylhdr (); -void cylftr (); -void cylhist (); -void validate_device (); -void validate_drive (); -void init_geom (); -void bad_device (); -void read_devinfo_names (); -void fail (); -void init_disk (); -void safe_kvm_read (); - -#undef n_name /* to resolve conflict with */ -#define MAXINTSIZE 12 /* sizeof "-2147483648" + 1 */ - -int debug = 1; - -#define Debug if (debug) -#define dfprintf if (debug) fprintf - -/* - * FETCH_XYZ naming convention: - * X = I for nlist index, A for actual address - * Y = V for regular variable, A for array variable - * Z = L if length explicitly specified - */ - -#define FETCH_AAL(addr, var, len, vname)\ - safe_kvm_read(kd, (unsigned long) addr, \ - (char *) var, len, vname) - -#define FETCH_IV(index, var)\ - safe_kvm_read(kd, (unsigned long) setup[index].n_value, \ - (char *) &var, sizeof (var), setup[index].n_name) - -#define FETCH_IAL(index, var, len)\ - safe_kvm_read(kd, (unsigned long)setup[index].n_value, \ - (char *) var, len, setup[index].n_name) - -int dk_ndrive; -int ndrives; -int all = 0; /* - * indicate whether all drives - * are implicitly specified - */ -char *cmdname = "sadp"; -char device[NAMESIZE]; -char dr_name[NDRIVE][NAMESIZE]; -long dk_bps[NDRIVE]; - -struct { - long dk_busy[NDRIVE]; - long dk_time[NDRIVE]; - long dk_wds[NDRIVE]; - long dk_seek[NDRIVE]; - long dk_xfer[NDRIVE]; - long dk_read[NDRIVE]; -} dk; - -struct var tbl; -char *sbuf, *phybuf; -struct buf bp[2]; /* for swap buffers */ -int nonblk; -int index; -int index1; -unsigned temp1; -#define devnm dr_name - -int fflg, dflg, tflg, hflg, errflg; -int s, n, ct; -static int ub = 8; -int sdist; -int m; -int dev; -int temp; -int f; -int i; -int n1, dleng, dashb, k, devlen; -int dashf; -int dn; -int drvlist[NDRIVE]; - -int Sdrvlist[SNDRIVE]; /* SCSI */ - -struct HISTDATA { - long hdata[1]; -}; -struct utsname name; - -char *nopt; -char empty[30]; -char drive[30]; -char *malloc(); - -int SCSI; /* SCSI */ -int ALL; - -long lseek(); -long **dkcyl; -long **skcyl; -long *iocnt; -static kvm_t *kd = NULL; -struct scsi_device *sdunits[SD_MAXUNIT]; -struct scsi_device sdunit[NDRIVE]; -int cyl_no, prev_cyl_no; -int cyl_bk, prev_cyl_bk; -int seek_dist, seek_bk; -int max_cyl_no = 0; -int max_seek_dist = 0; - -main(argc, argv) -int argc; -char **argv; -{ - unsigned sleep(); - extern int optind; - extern char *optarg; - int c, j; - char *ctime(), *stime; - long curt; - extern time_t time(); - long *skdist; - long *disk; - - fail("sadp does not work yet -- no disk statistics in the kernel", 0); - - while ((c = getopt(argc, argv, "thd:")) != EOF) - switch (c) { - case 't': - tflg++; - break; - case 'h': - hflg++; - break; - case 'd': - dleng = strlen(optarg); - - /* - * Controller types can be arbitrary length. - */ - devlen = strchr(optarg, '-') ? - strchr(optarg, '-') - optarg : dleng; - SCSI = 0; - strncpy(device, optarg, devlen); - - if (dleng == (devlen+1)) { - errflg++; - break; - } - if (dleng > devlen) { - for (i = (devlen+1), n1 = (devlen+1); i < dleng; i++){ - - if (optarg[i] == ','){ - if (n1 == i){ - errflg++; - break; - } - if (getdrvn() != 0) { - errflg++; - break; - } - if (dashf != 0) { - if (dashb >= dn){ - errflg++; - break; - } - for (j = dashb; j < dn+1; j++){ - if (SCSI) /* SCSI */ - Sdrvlist[j] = 1; - else - drvlist[j] = 1; - } - dashb = 0; - dashf = 0; - } - else - { - if (SCSI) - Sdrvlist[dn] = 1; - else - drvlist[dn] = 1; - } - n1 = i+1; - } else { - if (optarg[i] == '-'){ - if (dashf != 0) { - errflg++; - break; - } - if (getdrvn() != 0) { - errflg++; - break; - } - if (SCSI) - Sdrvlist[dn] = 1; - else - drvlist[dn] = 1; - dashb = dn; - dashf = 1; - n1 = i+1; - } else { - if (i == dleng-1){ - i++; - if (getdrvn() != 0) { - errflg++; - break; - } - if (dashf != 0) - for (j = dashb; j < dn+1; j++){ - if (SCSI) - Sdrvlist[j] = 1; - else - drvlist[j] = 1; - } - else - { - if (SCSI) - Sdrvlist[dn] = 1; - else - drvlist[dn] = 1; - } - } - } - } - } - } else { - if (dleng != devlen){ - errflg++; - break; - } - all++; - if (SCSI) - ALL++; - else - for (i = 0; i < MAX_HDISK_REP; i++) - drvlist[i] = 1; - } - if (errflg) - break; - dflg++; - break; - case '?': - errflg++; - break; - } - if (errflg) { - fprintf (stderr, "%s: errors in arguments\n", cmdname); - usage(); - } - - /* - * If no frequency arguments present, exit. - */ - if (optind == argc) - usage(); - /* - * If a non-dash field is presented as an argument, - * check if it is a numerical arg. - */ - nopt = argv[optind]; - if (tstdigit(nopt) != 0) - usage(); - /* - * For frequency arguments, if only s is presented , set n to 1 - */ - if ((optind +1) == argc) { - s = atoi(argv[optind]); - n = 1; - } - /* - * If both s and n are specified, check if - * arg n is numeric. - */ - if ((optind +1) < argc) { - nopt = argv[optind + 1]; - if (tstdigit(nopt) != 0) - usage(); - s = atoi(argv[optind]); - n = atoi(argv[optind+1]); - } - if (s <= 0) - fail("bad value of s", 0); - if (n <= 0) - fail("bad value of n", 0); - ct = s; - /* - * Get entries defined in setup from /stand/unix - */ - if ((kd = kvm_open (NULL, NULL, NULL, O_RDONLY, "Bad kvm open")) - == NULL) - fail("kvm_open failed", 1); - - dfprintf (stderr, "main: successful kvm_open\n"); - /* - * Search name list to get offsets. - */ - dfprintf (stderr, "main: about to kvm_nlist\n"); - if (kvm_nlist(kd, setup) == -1) { - fail("kvm_nlist failed", 1); - } - dfprintf (stderr, "main: good nlist\n"); - Debug dump_nlist (setup, "main"); - - /* - * Initialize buffers and get disk info. - */ - init_disk(); - dfprintf (stderr, "init_disk\n"); - skdist = (long *)calloc(dk_ndrive, sizeof (long)); - disk = (long *)calloc(dk_ndrive, sizeof (long)); - - /* - * Make sure device and drive specified is legitimate. - */ - validate_device(); - dfprintf (stderr, "validate_device\n"); - validate_drive(); - dfprintf (stderr, "validate_drive\n"); - - /* - * Get storage from memory for sysbuf pool and physical buf pool - */ - FETCH_IV (X1_V, tbl); - Debug dump_v_struct (&tbl); - sbuf = malloc(sizeof (struct buf) * tbl.v_buf); - if (sbuf == NULL) - fail("malloc of sbuf failed", 1); - phybuf = malloc(sizeof (struct buf) * tbl.v_pbuf); - if (phybuf == NULL) - fail("malloc of physbuf failed", 1); - - /* - * Determine the number of CHUNK cylinder chunks on the disk. - * This will be referenced as CHPERCYL. - */ - init_geom(); - dfprintf (stderr, "init_geom\n"); - - ub = dk_ndrive; -#ifdef FIXME - FETCH_IAL(X1_DK_XFER, dk.dk_xfer, dk_ndrive*sizeof (long)); - FETCH_IAL(X1_DK_READ, dk.dk_read, dk_ndrive*sizeof (long)); - FETCH_IAL(X1_DK_SEEK, dk.dk_seek, dk_ndrive*sizeof (long)); - FETCH_IAL(X1_DK_WDS, dk.dk_wds, dk_ndrive*sizeof (long)); - FETCH_IAL(X1_DK_TIME, dk.dk_time, dk_ndrive*sizeof (long)); -#endif - dfprintf (stderr, "%s: ub %d\n", cmdname, ub); - /* - * Get the list of scsi device pointers from kernel space. - */ - FETCH_IAL(X1_SDUNITS, sdunits, SD_MAXUNIT); - for (i = 0; i < SD_MAXUNIT; i++) { - dfprintf (stderr, "sdunits[%d] 0x%x ", i, (int)sdunits[i]); - } - dfprintf (stderr, "\n"); - for (k = 0, i = 0; k < ub; k++) { - if (drvlist[k] == 0) - continue; - /* - * Make sure that there is a scsi_device struct for - * the chosen device. - */ - if (!sdunits[k]) { - fprintf (stderr, "%s: no valid scsi_device struct\n", - cmdname); - } - dfprintf (stderr, "%s: read unit %d\n", cmdname, k); - /* - * Read the scsi_device struct for the device. - */ - FETCH_AAL(sdunits[k], &sdunit[k], - sizeof (struct scsi_device), "sdunits"); - dfprintf (stderr, "%s: sd_private 0x%x\n", - cmdname, (int)sdunit[k].sd_private); - } - - /* - * Get current I/O count for each drive. - */ - for (;;) { - s = ct; - for (k = 0, i = 0; k < ub; k++) { - if (drvlist[k] == 0) - continue; - for (j = 0; j < CHPERCYL; j++) { - dkcyl[i][j] = 0; - skcyl[i][j] = 0; - } - iocnt[i] = 0; - disk[i] = 0; - skdist[i] = 0; - i++; - } - /* - * If no drives are selected or illegal drive number - * is specified, exit. - */ - if (i == 0) - usage(); - - /* - * Get i/o count for each disk. - */ - - for (k = 0, i = 0; k < ub; k++) { - if (drvlist[k] == 0) - continue; - iocnt[i] = dk.dk_xfer[k]; - i++; - } - - cyl_no = 0; prev_cyl_no = 0; cyl_bk = 0; prev_cyl_bk = 0; seek_dist = 0; - for (;;) { - - /* - * Take a snapshot of buffer header pool, swap - * buffer pool and physical buffer header. - */ - - /* - * read system buffer header pool. - */ - FETCH_IAL(X1_BUF, sbuf, tbl.v_buf*sizeof (struct buf)); - - /* - * Read physical buffer header pool. - */ - FETCH_IAL(X1_PBUF, phybuf, tbl.v_pbuf*sizeof (struct buf)); - - for (k = 0, i = 0; k < ub; k++) { - if (drvlist[k] == 0) - continue; - do_disk_stats (i, k); - i++; - dfprintf (stderr, "%s: i %d\n", cmdname, i); - } - - /* TBD - get more samples */ - - if (--s) - sleep(1); - else { - - /* - * At the end of sampling, get the present I/O - * count, and system name. - */ - uname(&name); - - /* - * Print the report, there are two parts: - * cylinder profile, seeking distance profile. - */ - curt = time((long *) 0); - stime = ctime (&curt); - printf("\n\n%s\n", stime); - printf("%s %s %s %s %s\n", - name.sysname, - name.nodename, - name.release, - name.version, - name.machine); - for (k = 0, i = 0; k < ub; k++) { - if (drvlist[k] == 0) - continue; - for (j = 0; j < CHPERCYL; j++) { - disk[i] = disk[i] +dkcyl[i][j]; - skdist[i] = skdist[i] + skcyl[i][j]; - - } - i++; - } - if ((tflg == 0) && (hflg == 0)) - tflg = 1; - if (tflg){ - printf("\nCYLINDER ACCESS PROFILE\n"); - for (k = 0, i = 0; k < ub; k++) { - if (drvlist[k] == 0) - continue; - if (disk[i] != 0){ - iocnt[i] = dk.dk_xfer[k] - iocnt[i]; - printf("\n%s-%d:\n", - device, k); - printf("Cylinders\tTransfers\n"); - for (j = 0; j < CHPERCYL; j++) { - if (dkcyl[i][j] > 0) - printf("%3d - %3d\t%ld\n", - j*8, j*8+7, dkcyl[i][j]); - } - printf("\nSampled I/O = %ld, Actual I/O = %ld\n", - disk[i], iocnt[i]); - if (iocnt[i] > 0) - printf("Percentage of I/O sampled = %2.2f\n", - ((float)disk[i] /(float)iocnt[i]) * 100.0); - } - i++; - } - - printf("\n\n\nSEEK DISTANCE PROFILE\n"); - for (k = 0, i = 0; k < ub; k++) { - if (drvlist[k] == 0) - continue; - if (skdist[i] != 0){ - printf("\n%s-%d:\n", - device, k); - printf("Seek Distance\tSeeks\n"); - for (j = 0; j < CHPERCYL; j++) - - if (skcyl[i][j] > 0){ - if (j == 0) - printf(" 0\t%ld\n", - skcyl[i][j]); - else - printf("%3d - %3d\t%ld\n", - j*8-7, j*8, skcyl[i][j]); - } - printf("Total Seeks = %ld\n", skdist[i]); - } - i++; - } - } - if (hflg){ - for (k = 0, i = 0; k < ub; k++) { - if (drvlist[k] == 0) - continue; - if (disk[i] != 0) { - cylhdr(CYLNO, disk[i]); - cylhist(disk[i], dkcyl[i]); - cylftr(CYLNO); - } - i++; - } - for (k = 0, i = 0; k < ub; k++) { - if (drvlist[k] == 0) - continue; - if (skdist[i] != 0){ - cylhdr(SEEKD, skdist[i]); - cylhist(skdist[i], skcyl[i]); - cylftr(SEEKD); - } - i++; - } - } - - break; - } - } - if (--n) - continue; - exit(0); - } -} - -void -do_disk_stats (i, k) -{ -#ifdef fixed - struct scsi_disk sddisk[NDRIVE]; - struct diskhd *dp; - struct buf buffer, *bp; - struct buf *last_bp = 0; - - dfprintf (stderr, "do_disk_stats (i %d, k %d)\n", i, k); - /* - * In each scsi_device struct there is a sd_private - * pointer to a specialised scsi_disk struct which - * describes the disk. - */ - do { - FETCH_AAL(sdunit[k].sd_private, &sddisk[k], - sizeof (struct scsi_disk), "sdunit"); - /* - * The diskhd struct describing the active and waiting - * queues is embedded in the scsi_disk struct. - */ - dp = &sddisk[k].un_utab; - Debug dump_diskhd (dp); - /* - * The current SunOS sd.c driver uses the b_forw - * pointer for the currently active buffer, and the - * b_actf (av_forw) pointer for the waiting queue - * of buffers. - */ - dfprintf (stderr, "%s: b_forw 0x%x\n", cmdname, (int)dp->b_forw); - /* - * Trace disk queue for I/O location, seek distance. - */ - if (dp->b_forw) { - if (dp->b_forw == last_bp) { - continue; - } else { - last_bp = dp->b_forw; - } - dfprintf (stderr, "%s: b_forw 0x%x\n", - cmdname, (int)dp->b_forw); - FETCH_AAL(dp->b_forw, &buffer, sizeof (struct buf), - "b_forw"); - bp = &buffer; - dfprintf (stderr, "%s: b_lblkno 0x%x b_blkno 0x%x\n", - cmdname, bp->b_lblkno, bp->b_blkno); - cyl_no = bp->b_blkno / SECTPERCYL; - cyl_bk = cyl_no >> CHUNKSHIFT; - seek_dist = prev_cyl_no - cyl_no; - if (seek_dist < 0) - seek_dist = -seek_dist; - seek_bk = prev_cyl_bk - cyl_bk; - if (seek_bk < 0) - seek_bk = -seek_bk; - prev_cyl_no = cyl_no; - prev_cyl_bk = cyl_bk; - if (cyl_no > max_cyl_no) { - max_cyl_no = cyl_no; - } - if (seek_dist > max_seek_dist) { - max_seek_dist = seek_dist; - } - skcyl[i][seek_bk]++; - dkcyl[i][cyl_bk]++; - } - } while (dp->b_forw); -#endif -} - - -/* - * Determine if the I/O is from system buffer pool, - * or swap buffer pool or physical buffer. - */ - -int -testbuf() -{ - if ((temp1 < setup[X1_BUF].n_value) || (index > tbl.v_buf)){ - index = (int)(temp1 -setup[X1_PBUF].n_value)/ - (sizeof (struct buf)); - if (index < tbl.v_pbuf){ - nonblk = 1; - return (0); - - } -/* TBD - Is it possible to access swap buffers on Sun? */ -#ifndef sun - index = (int)(temp1 -setup[SWP].n_value)/ - (sizeof (struct buf)); - if (index < NSWP) { - m = index; - nonblk = 2; - return (0); - } -#endif - return (-1); - } - return (0); -} - -/* - * Verify the I/O, get the cylinder number. - */ - -ckbits(x) - register struct buf *x; -{ - register p; - for (p = 0; p < index; p++, x++) - continue; - if ((x->b_flags & B_BUSY) && - ((x->b_flags & B_DONE) == 0)){ - temp = x->cylin; - temp1 = (unsigned)x->av_forw; - return (0); - } - else - return (-1); - -} -int -testdev() -{ - if ((nonblk == 0) && (ckbits((struct buf *)sbuf) != -1)) - goto endtest; - else { - if ((nonblk == 1) && (ckbits((struct buf *)phybuf) != -1)) - goto endtest; - - else { - - if ((nonblk == 2) && - ((bp[m].b_flags & B_BUSY) && - ((bp[m].b_flags & B_DONE) == 0))){ - temp = bp[m].cylin; - temp1 = (unsigned)bp[m].av_forw; - } else { - dfprintf (stderr, "testdev -1\n"); - return (-1); - } - } - } -endtest: - dkcyl[i][temp >> 3]++; - return (0); -} - - - -/* - * Get drive number routine. - */ -getdrvn() -{ - extern char *optarg; - char *strcpy(); - char *strncat(); - - strcpy(drive, empty); - strncat(drive, &optarg[n1], i-n1); - if (tstdigit(drive) != 0) - return (-1); - dn = atoi(drive); - if (SCSI) { - if (dn >= SNDRIVE) - return (-1); - } else { - if (dn >= NDRIVE) - return (-1); - } - return (0); -} - -void -usage() -{ - fprintf(stderr, "usage: sadp [-th][-d device[-drive]] s [n]\n"); - exit(1); -} - -int tstdigit(ss) -char *ss; -{ - int kk, cc; - kk = 0; - while ((cc = ss[kk]) != '\0'){ - if (isdigit(cc) == 0) - return (-1); - kk++; - } - return (0); -} - -/* - * The following routines are obtained from iostat. - * - * Output Cylinder Histogram. - */ -void -cylhist(at, dp) -long at; -register struct HISTDATA *dp; -{ - register ii; - int maxrow; - long *graph = (long *)calloc(CHPERCYL, sizeof (long)); - long max, max2; - long data; - long scale; - - for (ii = 0; ii < CHPERCYL; ii++) { - dfprintf (stderr, "(%d %d) ", ii, (int)dp->hdata[ii]); - } - dfprintf (stderr, "\n"); - max = 0; - for (ii = 0; ii < CHPERCYL; ii++) { - if (data = dp->hdata[ii]) { - maxrow = ii; - if (data > max) { - max2 = max; - max = data; - } else if (data > max2 && data != max) - max2 = data; - } - } - maxrow++; - - /* determine scaling */ - scale = 1; - if (max2) { - scale = at / (max2 * 2); - if (scale > 48) - scale = 48; - } - - for (ii = 0; ii < maxrow; ii++) { - if (dp->hdata[ii]) - graph[ii] = (scale * 100 * dp->hdata[ii]) / at; - else - graph[ii] = -1; - } - - prthist(graph, maxrow, scale, (long) (max*100*scale/at)); -} -/* - * Print Histogram. - */ -void -prthist(array, mrow, scale, gmax) - long array[], scale, gmax; -register mrow; -{ - long line; - - line = 50; - /* handle overflow in scaling */ - if (gmax > 51) { - line = 52; - printf("\n%2ld%% -|", gmax/scale); - pline(line--, array, mrow, BLOB); - printf("\n %c", BRK); - pline(line--, array, mrow, BRK); - } else if (gmax = 51) - line = 51; - while (line > 0) { - if ((line & 07) == 0) { - printf("\n%2ld%% -|", line/scale); - } else { - printf("\n |"); - } - pline(line--, array, mrow, BLOB); - } - printf("\n 0%% -+"); - line = -1; - pline(line, array, mrow, FOOT); -} - -/* - * Print Histogram Line. - */ -void -pline(line, array, mrow, dot) - long line, array[]; -int mrow; -char dot; -{ - register ii; - register char *lp; - char lbuff[132]; - - dfprintf (stderr, - "pline(line 0x%x, array 0x%x, mrow 0x%x, dot 0x%x)\n", - line, array, mrow, dot); - lp = lbuff; - for (ii = 0; ii < mrow; ii++) - if (array[ii] < line) - if (line == 1 && array[ii] == 0) - *lp++ = TRACE; - else - *lp++ = BLANK; - else - *lp++ = dot; - *lp++ = 0; - printf("%s", lbuff); -} -/* - * Print Cylinder Profiling Headers. - */ -void -cylhdr(flag, total) - long total; -{ - - dfprintf (stderr, "cylhdr(flag 0x%x, total 0x%x)\n", flag, total); - if (fflg) - printf("\014\n"); - if (flag == CYLNO) - printf("\nCYLINDER ACCESS HISTOGRAM\n"); - if (flag == SEEKD) - printf("\nSEEK DISTANCE HISTOGRAM\n"); - printf("\n%s-%d:\n", - device, k); - printf("Total %s = %ld\n", - flag == CYLNO ? "transfers" : "seeks", total); -} - -#define MAXCOL 80 -/* Print Histogram Footers */ -void -cylftr(flag) -{ - int i; - int chunk_mult = 1; - int col; - char footer[4][MAXCOL]; - char digits[] = "0123456789"; - int significant = 0; - - dfprintf (stderr, "cylftr(flag 0x%x)\n", flag); - if (flag == CYLNO) - printf("\n \t\t\tCylinder number, granularity=%d", CHUNK); - else - printf("\n =<< "); - for (i = 0; i < 4; i++) { - for (col = 0; col < MAXCOL - 1; col++) { - footer[i][col] = ' '; - } - footer[i][MAXCOL - 1] = '\0'; - } - for (i = 0, col = 0; i < (int)PHYS_CYL; - i += (chunk_mult * CHUNK), col += chunk_mult, significant = 0) { - if ((i / 1000) > 0) { - footer[0][col] = digits[(i / 1000)]; - significant = 1; - } - if ((significant) || (((i % 1000) / 100) > 0)) { - footer[1][col] = digits[((i % 1000) / 100)]; - significant = 1; - } - if ((significant) || (((i % 100) / 10) > 0)) { - footer[2][col] = digits[((i % 100) / 10)]; - significant = 1; - } - if ((i == 0) || (significant) || ((i % 10) > 0)) { - footer[3][col] = digits[(i % 10)]; - } - if (i > CHUNK) { - chunk_mult = 2; - } - if (i > (3 * CHUNK)) { - chunk_mult = 4; - if (flag != CYLNO) - printf ("< "); - } - } - for (i = 0; i < 4; i++) { - printf (" %s\n", footer[i]); - } - printf ("\n"); -} - -void -validate_device() -{ - int i; - char tempdev[NAMESIZE]; - - if (dflg == 0) { - - /* - * No device specified, so default to the first - * one if it is the only one, otherwise prompt - * user to enter one. - */ - strcpy(device, devnm[0]); - *DRVNUM(device) = NULL; - devlen = strlen(device); - for (i = 0; i < dk_ndrive; i++) - drvlist[i] = 1; - if (dk_ndrive > 1) - bad_device(device, ERR_NO_DEV); - dev = 0; - } else { - - /* - * Device was specified. Make sure it matches - * one that is configured in the system. - */ - for (i = 0; i < dk_ndrive; i++) { - strncpy(tempdev, devnm[i], DRVNUM(devnm[i])-devnm[i]); - tempdev[DRVNUM(devnm[i])-devnm[i]] = NULL; - if (strcmp(device, tempdev) == 0) - break; - } - if (i == dk_ndrive) - bad_device(device, ERR_BAD_DEV); - dev = i; - } -} - -void -validate_drive() -{ - int i, j, c; - - /* - * For each controller number specified, make sure it exists - * in the configured device list. - */ - for (i = 0; i < dk_ndrive; i++) { - if (drvlist[i] == 0) - continue; - - /* - * Since this controller number (i) was specified, - * find the corresponding entry (j) in the device list. - * If found, save the device list index in drvlist[]. - */ - for (j = 0; j < dk_ndrive; j++) { - if (strncmp(device, devnm[j], devlen) != 0) - continue; - c = atoi(DRVNUM(devnm[j])); - if (c == i) { - /* - * NOTE: saved value actual index+1 - * as entries with 0 imply don't care. - */ - drvlist[i] = j+1; /* not a flag anymore! */ - - break; - } - } - - /* - * If not found, output error, except if all drives - * were implied by only specifying controller type. - * In this case, flag it as don't care. - */ - if (j == dk_ndrive) { - if (all) - drvlist[i] = 0; - else - bad_device(device, ERR_BAD_UNIT); - } - } -} - -void -init_geom() -{ - char tempdev[NAMESIZE]; - int i, fd; -/* - * When the new device naming convention is in effect, switch to it - */ -#ifdef NEW_DEVICE_NAMES -#define DEV_PREFIX "/dev/rdsk/" -#else -#define DEV_PREFIX "/dev/r" -#endif - - for (i = 0; drvlist[i] == 0; i++); - sprintf(tempdev, "%s%s%da", DEV_PREFIX, device, i); - if ((fd = open(tempdev, O_RDONLY)) == -1) - fail("open failed", 1); - if (ioctl(fd, DKIOCGGEOM, &dk_geom) == -1) { - close(fd); - fail("ioctl failed", 1); - } - close(fd); - - /* - * dk_geom structure now has data, and the number - * of 8 cylinder chunks on the disk can now be - * referenced via the CHPERCYL macro. So allocate - * appropriate buffers based on this value. - */ - iocnt = (long *)calloc(dk_ndrive, sizeof (long)); - dkcyl = (long **)calloc(dk_ndrive, sizeof (long *)); - skcyl = (long **)calloc(dk_ndrive, sizeof (long *)); - for (i = 0; i < dk_ndrive; i++) { - dkcyl[i] = (long *)calloc(CHPERCYL, sizeof (long)); - skcyl[i] = (long *)calloc(CHPERCYL, sizeof (long)); - } -} - -/* - * General routine for printing out an error message - * when the specified device/drive is insufficient. - */ -void -bad_device(device, errmsg) - char *device; - char *errmsg; -{ - int i, j; - int unique = 0; - char *p, *p1, **buf; - char s[NAMESIZE]; - char *msg; - - - /* - * Print usage statement if no device is specified. - */ - if (device[0] == NULL) - usage(); - - /* - * Compose a list of unique device controller types, or - * unit numbers for a specified controller type, from - * the complete device list. - */ - buf = (char **)calloc(dk_ndrive, sizeof (char *)); - for (i = 0; i < dk_ndrive; i++) { - - /* - * Get controller type or unit - */ - p = devnm[i]; - p1 = DRVNUM(devnm[i]); - if (!strcmp(errmsg, ERR_BAD_UNIT)) { - if (strncmp(devnm[i], device, devlen)) - continue; - p = p1; - p1++; - } - strncpy(s, p, p1-p); - s[p1-p] = NULL; - - /* - * Have we already logged this one as unique? - * If not, then do so now. - */ - for (j = 0; j < unique; j++) - if (!strcmp(s, buf[j])) - break; - if (j == unique) - buf[unique++] = strdup(s); - } - - /* - * Invalid device was specified. Compose message containing - * list of valid devices. - */ - msg = (char *)malloc(strlen(errmsg) + - strlen(device) + unique*(NAMESIZE+1) + 1); - sprintf(msg, errmsg, device); - for (p = msg + strlen(msg), i = 0; i < unique; i++) { - sprintf(p, "%s ", buf[i]); - p += (strlen(buf[i])+ 1); - } - - /* - * Output the message and exit. - */ - fail(msg, 0); -} - -/* - * Code below here was taken from the SunOS 5.0 iostat command. - */ - -#ifdef FIXME - -void -read_devinfo_names() -{ - int i; - struct dk_ivec dkivec[NDRIVE]; - - safe_kvm_read (kd, nl_4c[X1_DK_IVEC].n_value, dkivec, sizeof dkivec, - "dk_ivec"); - for (i = 0; i < NDRIVE; i++) { - if (dkivec[i].dk_name) { - safe_kvm_read (kd, dkivec[i].dk_name, dr_name[i], 2, - "dk_name"); - sprintf(dr_name[i] + 2, "%d", dkivec[i].dk_unit); - } - } -} - -#endif - -void -init_disk() -{ -#ifdef FIXME - int i; - - for (i = 0; i < NDRIVE; i++) { - dr_select[i] = 0; - dk_bps[i] = 0; - } - - /* - * The default device names: dk# - */ - for (i = 0; i < dk_ndrive; i++) { - dr_name[i] = buf; - (void) sprintf(buf, "dk%d", i); - buf += NAMESIZE; - } - - /* - * Device names must be discovered in this program, and output - * with its io data via the "sa" structure. - */ - - read_devinfo_names(); -#else - return; -#endif -} - -/* - * issue failure message and exit - */ -void -fail(message, doperror) -char *message; -int doperror; -{ - if (kd != NULL) - (void) kvm_close(kd); - - if (doperror) { - fprintf(stderr, "%s: ", cmdname); - perror(message); - } - fprintf(stderr, "%s: %s\n", cmdname, message); - exit(2); -} - -void -safe_kvm_read(kd, addr, buf, size, who) -kvm_t *kd; -unsigned long addr; -char *buf; -unsigned size; -{ - int ret_code; - char errmsg[100]; - - if (addr == 0) { - sprintf(errmsg, "kvm_read of %s failed -- no address", who); - fail(errmsg, 0); - } - - ret_code = kvm_read(kd, addr, buf, size); - if (ret_code != size) { - sprintf(errmsg, "kvm_read of %s failed with code %d", - who, ret_code); - fail(errmsg, 0); - } -} - -/* - * code for debugging dumps - */ - -#include -#include -#include -#include -#include -#include -#include - -int dump_iodev (); - -dump_diskhd (dp) - struct diskhd *dp; -{ - - dfprintf (stderr, "dump_diskhd: dp 0x%x\n", (int)dp); - 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", - (int)dp->b_flags, (int)dp->b_forw, (int)dp->b_back, - (int)dp->av_forw, (int)dp->av_back, (int)dp->b_bcount); - -return (0); -} - -dump_nlist (nlist, str) - struct nlist nlist[]; - char *str; -{ - int i; - - for (i = 0; nlist[i].n_name; i++) { - dfprintf (stderr, "%s: i %d n_name '%s' n_value 0x%x\n", - str, i, nlist[i].n_name, (int)nlist[i].n_value); - } - -return (0); -} - -dump_v_struct (tbl) - struct var *tbl; -{ - dfprintf (stderr, "dump_v_struct: tbl 0x%x\n", (int)tbl); - dfprintf (stderr, "v_buf\tv_call\tv_proc\tv_nglobpris\n%d\t%d\t%d\t%d\n", - tbl->v_buf, tbl->v_call, tbl->v_proc, tbl->v_nglobpris); - dfprintf (stderr, "v_maxsyspri\tv_clist\tv_maxup\tv_hbuf\n%d\t\t%d\t%d\t%d\n", - tbl->v_maxsyspri, tbl->v_clist, tbl->v_maxup, tbl->v_hbuf); - dfprintf (stderr, "v_hmask\tv_pbuf\tv_sptmap\tv_maxpmem\n0x%x\t%d\t%d\t\t%d\n", - tbl->v_hmask, tbl->v_pbuf, tbl->v_sptmap, tbl->v_maxpmem); - dfprintf (stderr, "v_autoup\tv_bufhwm\n%d\t\t%d\n", - tbl->v_autoup, tbl->v_bufhwm); - -return (0); -} - -dump_tblmap (tbl, size) - int *tbl; - int size; -{ - int i; - - dfprintf (stderr, "tblmap size %d/4 = %d ", size, size/4); - for (i = 0; i < size/4; i++) { - dfprintf (stderr, "tblmap[%d] %d ", i, tbl[i]); - } - dfprintf (stderr, "\n"); - -return (0); -} -- cgit v1.2.3