Ultrix-3.1/src/cmd/badstat.c
/**********************************************************************
* Copyright (c) Digital Equipment Corporation 1984, 1985, 1986. *
* All Rights Reserved. *
* Reference "/usr/src/COPYRIGHT" for applicable restrictions. *
**********************************************************************/
/*
* ULTRIX-11 Online Bad Sector status program
*
* Jerry Brenner 1/10/83
* Fred Canter (modified for HP general MASSBUS disk driver)
*
*/
static char Sccsid[] = "@(#)badstat.c 3.0 4/21/86";
#define DKBAD
#include <sys/param.h>
#include <time.h>
#include <sys/timeb.h>
#include <a.out.h>
#include <stdio.h>
#include <sys/hp_info.h>
#include <sys/bads.h>
#include <sys/hkbad.h>
#include <sys/hpbad.h>
/*
* BAD144 info for disk bad blocking. A zero entry in
* di_size indicates that disk type has no bad blocking.
* Borrowed from stand-alone DSKINIT, not all info used here.
*/
#define NP -1
#define HP 1
#define HM 2
#define HJ 3
struct dkinfo {
char *di_type; /* type name of disk */
int di_flag; /* prtdsk() flags */
char *di_name; /* ULTRIX-11 disk name */
long di_size; /* size of entire volume in blocks */
int di_nsect; /* sectors per track */
int di_ntrak; /* tracks per cylinder */
int di_wcpat[2]; /* worst case pattern */
} dkinfo[] = {
"rk06", 0, "hk", 22L*3L*411L, 22, 3, 0135143, 072307,
"rk07", 0, "hk", 22L*3L*815L, 22, 3, 0135143, 072307,
"rm02", NP, "hp", 32L*5L*823L, 32, 5, 0165555, 0133333,
"rm02_0", HP, "hp", 32L*5L*823L, 32, 5, 0165555, 0133333,
"rm02_1", HM, "hm", 32L*5L*823L, 32, 5, 0165555, 0133333,
"rm02_2", HJ, "hj", 32L*5L*823L, 32, 5, 0165555, 0133333,
"rm03", NP, "hp", 32L*5L*823L, 32, 5, 0165555, 0133333,
"rm03_0", HP, "hp", 32L*5L*823L, 32, 5, 0165555, 0133333,
"rm03_1", HM, "hm", 32L*5L*823L, 32, 5, 0165555, 0133333,
"rm03_2", HJ, "hj", 32L*5L*823L, 32, 5, 0165555, 0133333,
"rm05", NP, "hp", 32L*19L*823L, 32, 19, 0165555, 0133333,
"rm05_0", HP, "hp", 32L*19L*823L, 32, 19, 0165555, 0133333,
"rm05_1", HM, "hm", 32L*19L*823L, 32, 19, 0165555, 0133333,
"rm05_2", HJ, "hj", 32L*19L*823L, 32, 19, 0165555, 0133333,
"rp04", NP, "hp", 22L*19L*411L, 22, 19, 0165555, 0133333,
"rp04_0", HP, "hp", 22L*19L*411L, 22, 19, 0165555, 0133333,
"rp04_1", HM, "hm", 22L*19L*411L, 22, 19, 0165555, 0133333,
"rm04_2", HJ, "hj", 22L*19L*411L, 22, 19, 0165555, 0133333,
"rp05", NP, "hp", 22L*19L*411L, 22, 19, 0165555, 0133333,
"rp05_0", HP, "hp", 22L*19L*411L, 22, 19, 0165555, 0133333,
"rp05_1", HM, "hm", 22L*19L*411L, 22, 19, 0165555, 0133333,
"rp05_2", HJ, "hj", 22L*19L*411L, 22, 19, 0165555, 0133333,
"rp06", NP, "hp", 22L*19L*815L, 22, 19, 0165555, 0133333,
"rp06_0", HP, "hp", 22L*19L*815L, 22, 19, 0165555, 0133333,
"rp06_1", HM, "hm", 22L*19L*815L, 22, 19, 0165555, 0133333,
"rp06_2", HJ, "hj", 22L*19L*815L, 22, 19, 0165555, 0133333,
0,
};
struct nlist nli[] =
{
{ "_nhk" },
{ "_nhp" },
{ "_hp_inde" },
{ "_hk_bads" },
{ "_hp_bads" },
{ "_hk_dt" },
{ "_hp_dt" },
{ "" },
};
char *bdhdr[3] = {
"Bad Replace Revector",
"Block # Cyl Trk Sec Block # Cyl Trk Sec Count",
"----------------------------------------------------------"
};
struct dkinfo *dip;
struct bt_bad *bt;
long bn, rbn, atob(), atol();
union {
long serl; /* pack serial number as a long */
int seri[2]; /* serial number as two int's */
}dsk;
struct {
int t_cn;
int t_tn;
int t_sn;
}da;
char *usage="badstat: usage badstat [ifn] [interval] [corefile] [namelist]\n";
char *coref = "/dev/mem";
char *infile = "/unix";
char hp_index[MAXRH]; /* where to find info in HP structures */
char hpn[MAXRH]; /* number units per RH controller */
int nhk, nhp, nhm, nhj, mem, interval, fd;
struct hkbad *hk_bads[8];
int hk_dt[8];
struct hpbad *hp_bads[8];
char hp_dt[8];
struct hpbad *hm_bads[8];
char hm_dt[8];
struct hpbad *hj_bads[8];
char hj_dt[8];
struct dtype{
int dtyp;
char *dname;
}d_typ[] = {
0, "rk06",
02000, "rk07",
RP04, "rp04",
RP05, "rp05",
RP06, "rp06",
RM03, "rm03",
RM02, "rm02",
RM05, "rm05",
-1, "",
};
char dev[30];
char hk_av, hp_av, hm_av, hj_av;
long timbuf;
char *ap, *timezone(), *ctime(), *asctime();
struct tm *localtime();
extern char *ctime();
struct dkbad *bp;
struct bt_bad *bt;
int cnt, bcnt;
main(argc, argp)
int argc;
char *argp[];
{
int cnt, cnt1;
char *ap;
argp++;
for(ap = *argp++; ap && *ap; ap++)
switch(*ap){
case 'f':
coref = *argp++;
break;
case 'i':
interval = atoi(*argp++);
break;
case 'n':
infile = *argp++;
break;
case '-':
break;
default:
fprintf(stderr, "%s", usage);
exit(1);
break;
}
initmem();
while(1){
lmem();
display();
if(interval)
sleep(interval);
else
exit(0);
}
}
initmem()
{
int cnt, cnt1;
nlist(infile, nli);
if((mem = open(coref, 0)) <= 0){
printf("badstat: FATAL : Could not open %s\n", coref);
exit(1);
}
if(nli[0].n_value){ /* Check for nhk */
lseek(mem, (long)nli[0].n_value, 0);
read(mem, &nhk, sizeof(nhk));
}
if((nli[2].n_value) && (nli[1].n_value)){ /* Check for nhp */
lseek(mem, (long)nli[2].n_value, 0);
read(mem, &hp_index, MAXRH);
lseek(mem, (long)nli[1].n_value, 0);
read(mem, &hpn, MAXRH);
nhp = hpn[0]; nhm = hpn[1]; nhj = hpn[2];
}
if(nhk == 0 && nhp == 0 && nhm == 0 && nhj == 0){
printf("badstat: W : No bad sector devices on system\n");
exit(0);
}
if(nhk){
if(nli[3].n_value == 0)
nhk = 0;
else{
for(cnt = 0; cnt < nhk; cnt++){
for(cnt1 = 0; cnt1 < 8;cnt1++){
sprintf(dev, "/dev/hk%d%d", cnt,cnt1);
fd = open(dev, 0);
if(fd > 0){
if(read(fd, &dev, 1) == 1)
hk_av |= (1<<cnt);
close(fd);
break;
}
}
}
for(cnt = 0; cnt < nhk; cnt++){
if((hk_bads[cnt] = malloc(sizeof(struct dkbad)))
<= 0){
printf("badstat: F : malloc failed");
printf(" for hk %d\n", cnt);
exit(1);
}
}
lseek(mem, (long)nli[5].n_value, 0);
for(cnt = 0; cnt < nhk; cnt++)
read(mem, &hk_dt[cnt], sizeof(int));
}
}
if(nhp){
if(nli[4].n_value == 0)
nhp = 0;
else{
for(cnt = 0; cnt < nhp; cnt++){
for(cnt1 = 0; cnt1 < 8;cnt1++){
sprintf(dev, "/dev/hp%d%d", cnt,cnt1);
fd = open(dev, 0);
if(fd > 0){
if(read(fd, &dev, 1) == 1)
hp_av |= (1<<cnt);
close(fd);
break;
}
}
}
for(cnt = 0; cnt < nhp; cnt++){
if((hp_bads[cnt] = malloc(sizeof(struct dkbad)))
<= 0){
printf("badstat: F : malloc failed");
printf(" for hp %d\n", cnt);
exit(1);
}
}
lseek(mem, (long)nli[6].n_value + hp_index[0], 0);
for(cnt = 0; cnt < nhp; cnt++)
read(mem, &hp_dt[cnt], sizeof(char));
}
}
if(nhm){
if(nli[4].n_value == 0)
nhm = 0;
else{
for(cnt = 0; cnt < nhm; cnt++){
for(cnt1 = 0; cnt1 < 8;cnt1++){
sprintf(dev, "/dev/hm%d%d", cnt,cnt1);
fd = open(dev, 0);
if(fd > 0){
if(read(fd, &dev, 1) == 1)
hm_av |= (1<<cnt);
close(fd);
break;
}
}
}
for(cnt = 0; cnt < nhm; cnt++){
if((hm_bads[cnt] = malloc(sizeof(struct dkbad)))
<= 0){
printf("badstat: F : malloc failed");
printf(" for hm %d\n", cnt);
exit(1);
}
}
lseek(mem, (long)nli[6].n_value + hp_index[1], 0);
for(cnt = 0; cnt < nhm; cnt++)
read(mem, &hm_dt[cnt], sizeof(char));
}
}
if(nhj){
if(nli[4].n_value == 0)
nhj = 0;
else{
for(cnt = 0; cnt < nhj; cnt++){
for(cnt1 = 0; cnt1 < 8;cnt1++){
sprintf(dev, "/dev/hj%d%d", cnt,cnt1);
fd = open(dev, 0);
if(fd > 0){
if(read(fd, &dev, 1) == 1)
hj_av |= (1<<cnt);
close(fd);
break;
}
}
}
for(cnt = 0; cnt < nhj; cnt++){
if((hj_bads[cnt] = malloc(sizeof(struct dkbad)))
<= 0){
printf("badstat: F : malloc failed");
printf(" for hj %d\n", cnt);
exit(1);
}
}
lseek(mem, (long)nli[6].n_value + hp_index[2], 0);
for(cnt = 0; cnt < nhj; cnt++)
read(mem, &hj_dt[cnt], sizeof(char));
}
}
if(hk_av == 0 && hp_av == 0 && hm_av == 0 && hj_av == 0){
printf("badstat: F : No bad block info found\n");
exit(0);
}
}
lmem()
{
int cnt, i;
if(nhk){
lseek(mem, (long)nli[3].n_value, 0);
for(cnt = 0; cnt < nhk; cnt++){
read(mem, hk_bads[cnt], sizeof(struct hkbad));
}
}
if(nhp){
i = hp_index[0] * sizeof(struct hpbad);
lseek(mem, (long)nli[4].n_value + i, 0);
for(cnt = 0; cnt < nhp; cnt++){
read(mem, hp_bads[cnt], sizeof(struct hpbad));
}
}
if(nhm){
i = hp_index[1] * sizeof(struct hpbad);
lseek(mem, (long)nli[4].n_value + i, 0);
for(cnt = 0; cnt < nhm; cnt++){
read(mem, hm_bads[cnt], sizeof(struct hpbad));
}
}
if(nhj){
i = hp_index[2] * sizeof(struct hpbad);
lseek(mem, (long)nli[4].n_value + i, 0);
for(cnt = 0; cnt < nhj; cnt++){
read(mem, hj_bads[cnt], sizeof(struct hpbad));
}
}
}
display()
{
printf("\n\tBad Block Status on ");
date();
printf("\n");
if(hk_av){
for(cnt = 0; cnt < nhk; cnt++){
if(hk_av & (1<<cnt)){
bp = hk_bads[cnt];
bt = &bp->bt_badb;
if((dip = drvtyp(hk_dt[cnt])) == 0)
continue;
prtdev(-1, cnt);
}
}
}
if(hp_av){
for(cnt = 0; cnt < nhp; cnt++){
if(hp_av & (1<<cnt)){
bp = hp_bads[cnt];
bt = &bp->bt_badb;
if((dip = drvtyp(hp_dt[cnt])) == 0)
continue;
prtdev(0, cnt);
}
}
}
if(hm_av){
for(cnt = 0; cnt < nhm; cnt++){
if(hm_av & (1<<cnt)){
bp = hm_bads[cnt];
bt = &bp->bt_badb;
if((dip = drvtyp(hm_dt[cnt])) == 0)
continue;
prtdev(1, cnt);
}
}
}
if(hj_av){
for(cnt = 0; cnt < nhj; cnt++){
if(hj_av & (1<<cnt)){
bp = hj_bads[cnt];
bt = &bp->bt_badb;
if((dip = drvtyp(hj_dt[cnt])) == 0)
continue;
prtdev(2, cnt);
}
}
}
}
prtdev(ctrl, unit)
{
int cnt;
if(ctrl >= 0)
printf("RH %d ", ctrl);
printf("%s Unit %d",dip->di_type, unit);
if((bp->bt_csnh+bp->bt_csnl) == 0
|| bp->bt_flag != 0
|| bp->bt_mbz){
printf(" NO VALID BAD SECTOR ");
printf("INFORMATION\n\n");
return;
}
dsk.seri[0] = bp->bt_csnh;
dsk.seri[1] = bp->bt_csnl;
printf(" Cartridge Serial #%D Pack has ", dsk.serl);
for(cnt=0, bt= &bp->bt_badb; cnt < dip->di_nsect ;cnt++, bt++){
if(bt->bt_cyl==-1&&bt->bt_trksec==-1)
break;
if(bt->bt_cyl==0&&bt->bt_trksec==0)
break;
}
if(cnt == 0){
printf("NO bad sectors\n\n");
return;
}
printf("%d bad sectors\n\n", cnt);
bt = &bp->bt_badb;
printf("%s\n%s\n%s\n",bdhdr[0], bdhdr[1]
, bdhdr[2]);
prtsec(bp, bt, setvec());
printf("%s\n\n",bdhdr[2]);
}
prtsec(bp, bt, vec)
struct dkbad *bp;
struct bt_bad *bt;
int *vec;
{
int cnt;
for(cnt=0; cnt < dip->di_nsect ;cnt++, bt++){
if(bt->bt_cyl==-1&&bt->bt_trksec==-1)
break;
if(bt->bt_cyl==0&&bt->bt_trksec==0)
break;
bn = atob(bt);
printf("%7D %4d %3d",bn, bt->bt_cyl,bt->bt_trksec>>8);
printf(" %3d",bt->bt_trksec&0377);
btoa((rbn-1)-cnt);
printf(" %7D",(rbn-1)-cnt);
printf(" %4d %3d %3d " ,da.t_cn, da.t_tn, da.t_sn);
if(vec)
printf(" %u\n", *(vec++));
}
}
btoa(bn)
long bn;
{
da.t_cn = bn/(dip->di_ntrak*dip->di_nsect);
da.t_sn = bn%(dip->di_ntrak*dip->di_nsect);
da.t_tn = da.t_sn/dip->di_nsect;
da.t_sn = da.t_sn%dip->di_nsect;
}
long atob(bt)
struct bt_bad *bt;
{
long blkn;
blkn = (long)bt->bt_cyl * (long)(dip->di_ntrak * dip->di_nsect);
blkn += (long)((bt->bt_trksec >> 8) * dip->di_nsect);
blkn += ((long)bt->bt_trksec & 0377);
return(blkn);
}
drvtyp(type)
int type;
{
register struct dkinfo *dp;
register struct dtype *dt;
for(dt = d_typ; dt->dtyp >= 0; dt++)
if(dt->dtyp == type)
break;
for(dp=dkinfo; dp->di_type; dp++)
if(strcmp(dp->di_type, dt->dname) == 0)
break;
if(dp->di_type == 0)
return(0);
rbn = dp->di_size - dp->di_nsect;
return(dp);
}
date()
{
register char *tzn;
struct timeb info;
struct tm *tp;
ftime(&info);
time(&timbuf);
tp = localtime(&timbuf);
ap = asctime(tp);
tzn = timezone(info.timezone, tp->tm_isdst);
printf("%.20s", ap);
if (tzn)
printf("%s", tzn);
printf("%s", ap+19);
}
setvec()
{
if(strcmp(dip->di_name, "hk") == 0)
return(&bp->kbt_vec);
else if(strcmp(dip->di_name, "hp") == 0)
return(&bp->pbt_vec);
else
return(0);
}