home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!elroy.jpl.nasa.gov!news.claremont.edu!nntp-server.caltech.edu!SOL1.GPS.CALTECH.EDU!CARL
- From: carl@SOL1.GPS.CALTECH.EDU (Carl J Lydick)
- Newsgroups: comp.os.vms
- Subject: Re: Question about RMS and MSCP-pair
- Date: 9 Jan 1993 11:54:59 GMT
- Organization: HST Wide Field/Planetary Camera
- Lines: 287
- Distribution: world
- Message-ID: <1imeejINNg7a@gap.caltech.edu>
- References: <9301051405.AA16112@uu3.psi.com>
- Reply-To: carl@SOL1.GPS.CALTECH.EDU
- NNTP-Posting-Host: sol1.gps.caltech.edu
-
- In article <9301051405.AA16112@uu3.psi.com>, leichter@lrw.com (Jerry Leichter) writes:
- >Some of this is already in ANALYZE/DISK/READ_CHECK. The rest is in the old
- >BAD utility (ANALYZE/MEDIA), though that will refuse to run on DSA disks.
- >However, that utility won't run on DSA disks, reporting "Unable to analyze
- ><disk>, due to revector caching". You really need diagnosic-level code
- >(which has its own specialized disk drivers) to do this properly on a DSA
- >disk.
-
- Not really. All you really want to do is make sure that the blocks currently
- on the logical disk (including those that've been included by revectoring) are
- OK. I've got a program to do that (we once bought a *WHOLE LOT* of magneto
- optical disks at a good price; seems that one reason for the price was that
- the manufacturer hadn't bothered to do much quality control. Result: Lots of
- disks with a few bad sectors on each; of course, the drive we were using was
- DSA, so we couldn't use ANAL/MEDIA/EXERCISE to force revectoring, and I wrote a
- simple exerciser. Since the code's not all that long (OK, it's 255 lines, and
- 6.5 kbytes or so), here it is (by the way, one of the features of this program
- is that it's pretty safe to run on a disk that already contains useful data:
- After running the program, the disk has exactly the same information it started
- with, with the possible exception of the data in bad blocks; why doesn't BAD
- do the same thing, I wonder?):
-
-
- #include ssdef
- #include dvidef
- #include IODEF
- #include descrip
-
- #define MAXBLK 128
- #define MAXBYTE (MAXBLK * 512)
- #define RMSMAXBLK 32
- #define RMSMAXBYTE (RMSMAXBLK * 512)
- long STAT;
- #define ckstat(x) if(((STAT = x) & 7) != 1) SYS$EXIT(STAT);
- #define $DESCRIPTOR_D(x) struct dsc$descriptor_d x = \
- { 0, DSC$K_DTYPE_T, DSC$K_CLASS_D, 0 }
-
- char olddata[MAXBYTE], testdata[MAXBYTE], pattern_0[MAXBYTE],
- pattern_1[MAXBYTE], temp[16];
- unsigned short chan;
-
- struct IOSB
- { unsigned short stat;
- unsigned long count;
- unsigned short not_used;
- } iosb;
-
- findbad()
- { $DESCRIPTOR(prompt,"Disk to test: ");
- $DESCRIPTOR_D(dev);
- $DESCRIPTOR_D(temp);
- $DESCRIPTOR_D(prmpt);
- $DESCRIPTOR(mountstr, "Device must be mounted /FOREIGN");
- $DESCRIPTOR(loprompt, "Lowest block to check [0]: ");
- $DESCRIPTOR(hiprompt, "Highest block to check [!UL]: ");
- $DESCRIPTOR(msgdsc, "Testing blocks !UL-!UL");
- unsigned long blocks, mount, foreign, loblk, hiblk, i, tmp;
- struct ITEM_LIST_3
- { unsigned short buflen, itmcod;
- unsigned char *bufadr;
- unsigned short *lenadr;
- } itmlst[] =
- { { 4, DVI$_MAXBLOCK, &blocks, 0 },
- { 4, DVI$_MNT, &mount, 0 },
- { 4, DVI$_FOR, &foreign, 0 },
- { 0, 0, 0, 0 }
- };
-
- ckstat(LIB$GET_INPUT(&dev, &prompt, 0));
- for(i = 0; i < MAXBYTE-RMSMAXBYTE; i += RMSMAXBYTE)
- { ckstat(LIB$MOVC5(&0, 0, &0x55, &16384, pattern_0 + i));
- ckstat(LIB$MOVC5(&0, 0, &0xAA, &16384, pattern_1 + i));
- }
- tmp = MAXBYTE - i;
- ckstat(LIB$MOVC5(&0, 0, &0x55, &tmp, pattern_0 + i));
- ckstat(LIB$MOVC5(&0, 0, &0x55, &tmp, pattern_1 + i));
- ckstat(SYS$ASSIGN(&dev, &chan, 0, 0));
- ckstat(SYS$GETDVIW(0, chan, 0, itmlst, &iosb, 0, 0, 0));
- ckstat(iosb.stat);
- if((((mount & 1) == 1) && ((foreign & 1) != 1)) || ((mount & 1) == 0))
- { LIB$PUT_OUTPUT(&mountstr);
- SYS$EXIT(1);
- }
- blocks--;
- LIB$GET_INPUT(&temp, &loprompt);
- loblk = dtol(&temp);
- LIB$SYS_FAO(&hiprompt,0,&prmpt,blocks);
- LIB$GET_INPUT(&temp,&prmpt);
- if (temp.dsc$w_length == 0)
- hiblk = blocks;
- else
- hiblk = dtol(&temp);
- LIB$SYS_FAO(&msgdsc,0,&temp, loblk, hiblk);
- LIB$PUT_OUTPUT(&temp);
- for(blocks = loblk; blocks <= hiblk - MAXBLK; blocks += MAXBLK)
- test_00(blocks, MAXBLK);
- if(blocks <= hiblk)
- test_00(blocks, hiblk - blocks + 1);
- SYS$EXIT(1);
- }
-
- test_00(base, blocks)
- long base, blocks;
- { long tmp;
- $DESCRIPTOR(fmt, "Testing blocks !UL-!UL");
- $DESCRIPTOR_D(msg);
-
- LIB$SYS_FAO(&fmt, 0, &msg, base, base + blocks - 1);
- LIB$PUT_OUTPUT(&msg);
- if(blocks == 0)
- return;
- if(qio(olddata, 512 * blocks, base, IO$_READLBLK) != 1)
- { if(blocks > 1)
- { tmp = blocks / 2;
- test_00(base, tmp);
- test_00(base + tmp, blocks - tmp);
- }
- }
- else
- test_01(base, blocks);
- }
-
- test_01(base, blocks)
- long base, blocks;
- { long tmp;
-
- if(qio(pattern_0, 512 * blocks, base, IO$_WRITELBLK) !=1)
- { restore(base, blocks);
- if(blocks > 1)
- { tmp = blocks / 2;
- test_00(base, tmp);
- test_00(base + tmp, blocks - tmp);
- }
- }
- else
- test_02(base, blocks);
- }
-
- test_02(base, blocks)
- long base, blocks;
- { long tmp;
-
- if(qio(testdata, 512 * blocks, base, IO$_READLBLK) != 1)
- { restore(base, blocks);
- if(blocks > 1)
- { tmp = blocks / 2;
- test_00(base, tmp);
- test_00(base + tmp, blocks - tmp);
- }
- }
- else
- test_03(base, blocks);
- }
-
- test_03(base, blocks)
- long base, blocks;
- { long tmp;
-
- compare(testdata, pattern_0, base, blocks);
- test_04(base, blocks);
- }
-
- test_04(base, blocks)
- long base, blocks;
- { long tmp;
-
- if(qio(pattern_1, 512 * blocks, base, IO$_WRITELBLK) != 1)
- { restore(base, blocks);
- if(blocks > 1)
- { tmp = blocks / 2;
- test_00(base, tmp);
- test_00(base + tmp, blocks - tmp);
- }
- }
- else
- test_05(base, blocks);
- }
-
- test_05(base, blocks)
- long base, blocks;
- { long tmp;
-
- if(blocks == 0)
- return;
- if(qio(testdata, 512 * blocks, base, IO$_READLBLK) != 1)
- { restore(base, blocks);
- if(blocks > 1)
- { tmp = blocks / 2;
- test_00(base, tmp);
- test_00(base + tmp, blocks - tmp);
- }
- }
- else
- test_06(base, blocks);
- }
-
- test_06(base, blocks)
- long base, blocks;
- { long tmp;
-
- compare(testdata, pattern_1, base, blocks);
- restore(base, blocks);
- }
-
- qio(buff, siz, start, func)
- char *buff;
- long siz, start, func;
- { $DESCRIPTOR(fmt,
- "!AS FAILED ON BLOCKS !UL-!UL; STAT = !04XW; COUNT = !UL");
- $DESCRIPTOR(str_0, "READ");
- $DESCRIPTOR(str_1, "WRITE");
- $DESCRIPTOR_D(msg);
- $DESCRIPTOR(volinv, "VOLUME HAS DISAPPEARED. QUITTING.");
- ckstat(SYS$QIOW(0, chan, func, &iosb, 0, 0, buff, siz, start, 0, 0, 0));
- if((iosb.stat & 7) != 1)
- { LIB$SYS_FAO(&fmt, 0, &msg, func == IO$_READLBLK ? &str_0 :
- &str_1, start, start + (siz / 512) - 1, iosb.stat,
- iosb.count);
- LIB$PUT_OUTPUT(&msg);
- if(iosb.stat == SS$_VOLINV)
- { LIB$PUT_OUTPUT(&volinv);
- SYS$EXIT(1);
- }
- }
- return iosb.stat & 7;
- }
-
- dtol(desc)
- struct dsc$descriptor *desc;
- { int i, j;
- char c;
-
- for(i = j = 0; j < desc->dsc$w_length && desc->dsc$a_pointer[j] >= '0'
- && desc->dsc$a_pointer[j] <= '9'; ++j)
- i = 10 * i + desc->dsc$a_pointer[j] - '0';
- return i;
- }
-
- restore(base, blocks)
- long base, blocks;
- { long tmp;
-
- if(blocks == 0)
- return;
- if((qio(olddata, 512 * blocks, base, IO$_WRITELBLK) & 7) != 1)
- { if(blocks > 1)
- { tmp = blocks / 2;
- restore(base, tmp);
- restore(base + tmp, blocks - tmp);
- }
- else
- for(tmp = 0; ((qio(olddata, 512, base, IO$_WRITELBLK) &
- 7) != 1) && (tmp < 10); ++tmp);
- return;
- }
- }
-
- compare(str_1, str_2, base, blocks)
- char *str_1, *str_2;
- long base;
- { $DESCRIPTOR(dsc_1, str_1);
- $DESCRIPTOR(dsc_2, str_2);
- long i;
- $DESCRIPTOR_D(msg);
- $DESCRIPTOR(fmt, "Compare failed on block !UL");
-
- if(blocks == 0)
- return;
- dsc_1.dsc$w_length = dsc_2.dsc$w_length = 512;
- for(i = 0; i < blocks ; i ++)
- { if(STR$COMPARE(&dsc_1, &dsc_2) != 0)
- { LIB$SYS_FAO(&fmt, 0, &msg, base + i);
- LIB$PUT_OUTPUT(&msg);
- }
- dsc_1.dsc$a_pointer += 512;
- dsc_2.dsc$a_pointer += 512;
- }
- }
-
- --------------------------------------------------------------------------------
- Carl J Lydick | INTERnet: CARL@SOL1.GPS.CALTECH.EDU | NSI/HEPnet: SOL1::CARL
-
- Disclaimer: Hey, I understand VAXen and VMS. That's what I get paid for. My
- understanding of astronomy is purely at the amateur level (or below). So
- unless what I'm saying is directly related to VAX/VMS, don't hold me or my
- organization responsible for it. If it IS related to VAX/VMS, you can try to
- hold me responsible for it, but my organization had nothing to do with it.
-