home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #1 / NN_1993_1.iso / spool / comp / os / vms / 20653 < prev    next >
Encoding:
Text File  |  1993-01-09  |  8.1 KB  |  301 lines

  1. Path: sparky!uunet!elroy.jpl.nasa.gov!news.claremont.edu!nntp-server.caltech.edu!SOL1.GPS.CALTECH.EDU!CARL
  2. From: carl@SOL1.GPS.CALTECH.EDU (Carl J Lydick)
  3. Newsgroups: comp.os.vms
  4. Subject: Re: Question about RMS and MSCP-pair
  5. Date: 9 Jan 1993 11:54:59 GMT
  6. Organization: HST Wide Field/Planetary Camera
  7. Lines: 287
  8. Distribution: world
  9. Message-ID: <1imeejINNg7a@gap.caltech.edu>
  10. References: <9301051405.AA16112@uu3.psi.com>
  11. Reply-To: carl@SOL1.GPS.CALTECH.EDU
  12. NNTP-Posting-Host: sol1.gps.caltech.edu
  13.  
  14. In article <9301051405.AA16112@uu3.psi.com>, leichter@lrw.com (Jerry Leichter) writes:
  15. >Some of this is already in ANALYZE/DISK/READ_CHECK.  The rest is in the old
  16. >BAD utility (ANALYZE/MEDIA), though that will refuse to run on DSA disks.
  17. >However, that utility won't run on DSA disks, reporting "Unable to analyze
  18. ><disk>, due to revector caching".  You really need diagnosic-level code
  19. >(which has its own specialized disk drivers) to do this properly on a DSA
  20. >disk.
  21.  
  22. Not really.  All you really want to do is make sure that the blocks currently
  23. on the logical disk (including those that've been included by revectoring) are
  24. OK.  I've got a program to do that (we once bought a *WHOLE LOT* of magneto
  25. optical disks at a good price;  seems that one reason for the price was that
  26. the manufacturer hadn't bothered to do much quality control.  Result:  Lots of
  27. disks with a few bad sectors on each;  of course, the drive we were using was
  28. DSA, so we couldn't use ANAL/MEDIA/EXERCISE to force revectoring, and I wrote a
  29. simple exerciser.  Since the code's not all that long (OK, it's 255 lines, and
  30. 6.5 kbytes or so), here it is (by the way, one of the features of this program
  31. is that it's pretty safe to run on a disk that already contains useful data: 
  32. After running the program, the disk has exactly the same information it started
  33. with, with the possible exception of the data in bad blocks;  why doesn't BAD
  34. do the same thing, I wonder?):
  35.  
  36.  
  37. #include ssdef
  38. #include dvidef
  39. #include IODEF
  40. #include descrip
  41.  
  42. #define MAXBLK 128
  43. #define MAXBYTE (MAXBLK * 512)
  44. #define RMSMAXBLK 32
  45. #define RMSMAXBYTE (RMSMAXBLK * 512)
  46. long STAT;
  47. #define ckstat(x) if(((STAT = x) & 7) != 1) SYS$EXIT(STAT);
  48. #define $DESCRIPTOR_D(x) struct dsc$descriptor_d x = \
  49.     { 0, DSC$K_DTYPE_T, DSC$K_CLASS_D, 0 }
  50.  
  51. char olddata[MAXBYTE], testdata[MAXBYTE], pattern_0[MAXBYTE],
  52.     pattern_1[MAXBYTE], temp[16];
  53. unsigned short chan;
  54.  
  55. struct IOSB
  56. {    unsigned short stat;
  57.     unsigned long count;
  58.     unsigned short not_used;
  59. } iosb;
  60.  
  61. findbad()
  62. {    $DESCRIPTOR(prompt,"Disk to test: ");
  63.     $DESCRIPTOR_D(dev);
  64.     $DESCRIPTOR_D(temp);
  65.     $DESCRIPTOR_D(prmpt);
  66.     $DESCRIPTOR(mountstr, "Device must be mounted /FOREIGN");
  67.     $DESCRIPTOR(loprompt, "Lowest block to check [0]: ");
  68.     $DESCRIPTOR(hiprompt, "Highest block to check [!UL]: ");
  69.     $DESCRIPTOR(msgdsc, "Testing blocks !UL-!UL");
  70.     unsigned long blocks, mount, foreign, loblk, hiblk, i, tmp;
  71.     struct ITEM_LIST_3
  72.     {       unsigned short buflen, itmcod;
  73.         unsigned char *bufadr;
  74.         unsigned short *lenadr;
  75.     } itmlst[] =
  76.     {    { 4, DVI$_MAXBLOCK, &blocks, 0 },
  77.         { 4, DVI$_MNT, &mount, 0 },
  78.         { 4, DVI$_FOR, &foreign, 0 },
  79.         { 0, 0, 0, 0 }
  80.     };
  81.  
  82.     ckstat(LIB$GET_INPUT(&dev, &prompt, 0));
  83.     for(i = 0; i < MAXBYTE-RMSMAXBYTE; i += RMSMAXBYTE)
  84.     {    ckstat(LIB$MOVC5(&0, 0, &0x55, &16384, pattern_0 + i));
  85.         ckstat(LIB$MOVC5(&0, 0, &0xAA, &16384, pattern_1 + i));
  86.     }
  87.     tmp = MAXBYTE - i;
  88.     ckstat(LIB$MOVC5(&0, 0, &0x55, &tmp, pattern_0 + i));
  89.     ckstat(LIB$MOVC5(&0, 0, &0x55, &tmp, pattern_1 + i));
  90.     ckstat(SYS$ASSIGN(&dev, &chan, 0, 0));
  91.     ckstat(SYS$GETDVIW(0, chan, 0, itmlst, &iosb, 0, 0, 0));
  92.     ckstat(iosb.stat);
  93.     if((((mount & 1) == 1) && ((foreign & 1) != 1)) || ((mount & 1) == 0))
  94.     {    LIB$PUT_OUTPUT(&mountstr);
  95.         SYS$EXIT(1);
  96.     }
  97.     blocks--;
  98.     LIB$GET_INPUT(&temp, &loprompt);
  99.     loblk = dtol(&temp);
  100.     LIB$SYS_FAO(&hiprompt,0,&prmpt,blocks);
  101.     LIB$GET_INPUT(&temp,&prmpt);
  102.     if (temp.dsc$w_length == 0)
  103.         hiblk = blocks;
  104.     else
  105.         hiblk = dtol(&temp);
  106.     LIB$SYS_FAO(&msgdsc,0,&temp, loblk, hiblk);
  107.     LIB$PUT_OUTPUT(&temp);
  108.     for(blocks = loblk; blocks <= hiblk - MAXBLK; blocks += MAXBLK)
  109.         test_00(blocks, MAXBLK);
  110.     if(blocks <= hiblk)
  111.         test_00(blocks, hiblk - blocks + 1);
  112.     SYS$EXIT(1);
  113. }
  114.  
  115. test_00(base, blocks)
  116. long base, blocks;
  117. {    long tmp;
  118.     $DESCRIPTOR(fmt, "Testing blocks !UL-!UL");
  119.     $DESCRIPTOR_D(msg);
  120.  
  121.     LIB$SYS_FAO(&fmt, 0, &msg, base, base + blocks - 1);
  122.     LIB$PUT_OUTPUT(&msg);
  123.     if(blocks == 0)
  124.         return;
  125.     if(qio(olddata, 512 * blocks, base, IO$_READLBLK) != 1)
  126.     {    if(blocks > 1)
  127.         {    tmp = blocks / 2;
  128.             test_00(base, tmp);
  129.             test_00(base + tmp, blocks - tmp);
  130.         }
  131.     }
  132.     else
  133.         test_01(base, blocks);
  134. }
  135.  
  136. test_01(base, blocks)
  137. long base, blocks;
  138. {    long tmp;
  139.  
  140.     if(qio(pattern_0, 512 * blocks, base, IO$_WRITELBLK) !=1)
  141.     {    restore(base, blocks);
  142.         if(blocks > 1)
  143.         {    tmp = blocks / 2;
  144.             test_00(base, tmp);
  145.             test_00(base + tmp, blocks - tmp);
  146.         }
  147.     }
  148.     else
  149.         test_02(base, blocks);
  150. }
  151.  
  152. test_02(base, blocks)
  153. long base, blocks;
  154. {    long tmp;
  155.  
  156.     if(qio(testdata, 512 * blocks, base, IO$_READLBLK) != 1)
  157.     {    restore(base, blocks);
  158.         if(blocks > 1)
  159.         {    tmp = blocks / 2;
  160.              test_00(base, tmp);
  161.             test_00(base + tmp, blocks - tmp);
  162.         }
  163.     }
  164.     else
  165.         test_03(base, blocks);
  166. }
  167.  
  168. test_03(base, blocks)
  169. long base, blocks;
  170. {    long tmp;
  171.  
  172.     compare(testdata, pattern_0, base, blocks);
  173.     test_04(base, blocks);
  174. }
  175.  
  176. test_04(base, blocks)
  177. long base, blocks;
  178. {    long tmp;
  179.  
  180.     if(qio(pattern_1, 512 * blocks, base, IO$_WRITELBLK) != 1)
  181.     {    restore(base, blocks);
  182.         if(blocks > 1)
  183.         {    tmp = blocks / 2;
  184.             test_00(base, tmp);
  185.              test_00(base + tmp, blocks - tmp);
  186.         }
  187.     }
  188.     else
  189.         test_05(base, blocks);
  190. }
  191.  
  192. test_05(base, blocks)
  193. long base, blocks;
  194. {    long tmp;
  195.  
  196.     if(blocks == 0)
  197.         return;
  198.     if(qio(testdata, 512 * blocks, base, IO$_READLBLK) != 1)
  199.     {    restore(base, blocks);
  200.         if(blocks > 1)
  201.         {    tmp = blocks / 2;
  202.             test_00(base, tmp);
  203.             test_00(base + tmp, blocks - tmp);
  204.         }
  205.     }
  206.     else
  207.         test_06(base, blocks);
  208. }
  209.  
  210. test_06(base, blocks)
  211. long base, blocks;
  212. {    long tmp;
  213.  
  214.     compare(testdata, pattern_1, base, blocks);
  215.     restore(base, blocks);
  216. }
  217.  
  218. qio(buff, siz, start, func)
  219. char *buff;
  220. long siz, start, func;
  221. {    $DESCRIPTOR(fmt,
  222.         "!AS FAILED ON BLOCKS !UL-!UL; STAT = !04XW; COUNT = !UL");
  223.     $DESCRIPTOR(str_0, "READ");
  224.     $DESCRIPTOR(str_1, "WRITE");
  225.     $DESCRIPTOR_D(msg);
  226.     $DESCRIPTOR(volinv, "VOLUME HAS DISAPPEARED.  QUITTING.");
  227.     ckstat(SYS$QIOW(0, chan, func, &iosb, 0, 0, buff, siz, start, 0, 0, 0));
  228.     if((iosb.stat & 7) != 1)
  229.     {    LIB$SYS_FAO(&fmt, 0, &msg, func == IO$_READLBLK ? &str_0 :
  230.             &str_1, start, start + (siz / 512) - 1, iosb.stat,
  231.             iosb.count);
  232.         LIB$PUT_OUTPUT(&msg);
  233.         if(iosb.stat == SS$_VOLINV)
  234.         {    LIB$PUT_OUTPUT(&volinv);
  235.             SYS$EXIT(1);
  236.         }
  237.     }
  238.     return iosb.stat & 7;
  239. }
  240.  
  241. dtol(desc)
  242. struct dsc$descriptor *desc;
  243. {    int i, j;
  244.     char c;
  245.            
  246.     for(i = j = 0; j < desc->dsc$w_length && desc->dsc$a_pointer[j] >= '0'
  247.         && desc->dsc$a_pointer[j] <= '9'; ++j)
  248.         i = 10 * i + desc->dsc$a_pointer[j] - '0';
  249.     return i;
  250. }
  251.  
  252. restore(base, blocks)
  253. long base, blocks;
  254. {    long tmp;
  255.  
  256.     if(blocks == 0)
  257.         return;
  258.     if((qio(olddata, 512 * blocks, base, IO$_WRITELBLK) & 7) != 1)
  259.     {    if(blocks > 1)
  260.         {    tmp = blocks / 2;
  261.             restore(base, tmp);
  262.             restore(base + tmp, blocks - tmp);
  263.         }
  264.         else
  265.             for(tmp = 0; ((qio(olddata, 512, base, IO$_WRITELBLK) &
  266.                 7) != 1) && (tmp < 10); ++tmp);
  267.         return;
  268.     }
  269. }
  270.  
  271. compare(str_1, str_2, base, blocks)
  272. char *str_1, *str_2;
  273. long base;
  274. {    $DESCRIPTOR(dsc_1, str_1);
  275.     $DESCRIPTOR(dsc_2, str_2);
  276.     long i;
  277.     $DESCRIPTOR_D(msg);
  278.     $DESCRIPTOR(fmt, "Compare failed on block !UL");
  279.  
  280.     if(blocks == 0)
  281.         return;
  282.     dsc_1.dsc$w_length = dsc_2.dsc$w_length = 512;
  283.     for(i = 0; i < blocks ; i ++)
  284.     {    if(STR$COMPARE(&dsc_1, &dsc_2) != 0)
  285.         {    LIB$SYS_FAO(&fmt, 0, &msg, base + i);
  286.             LIB$PUT_OUTPUT(&msg);
  287.         }
  288.          dsc_1.dsc$a_pointer += 512;
  289.           dsc_2.dsc$a_pointer += 512;
  290.     }
  291. }
  292.  
  293. --------------------------------------------------------------------------------
  294. Carl J Lydick | INTERnet: CARL@SOL1.GPS.CALTECH.EDU | NSI/HEPnet: SOL1::CARL
  295.  
  296. Disclaimer:  Hey, I understand VAXen and VMS.  That's what I get paid for.  My
  297. understanding of astronomy is purely at the amateur level (or below).  So
  298. unless what I'm saying is directly related to VAX/VMS, don't hold me or my
  299. organization responsible for it.  If it IS related to VAX/VMS, you can try to
  300. hold me responsible for it, but my organization had nothing to do with it.
  301.