home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / os / linux / 10746 < prev    next >
Encoding:
Text File  |  1992-09-15  |  11.1 KB  |  375 lines

  1. Path: sparky!uunet!haven.umd.edu!mimsy!afterlife!swaliff
  2. From: swaliff@afterlife.ncsc.mil (Steve Aliff)
  3. Newsgroups: comp.os.linux
  4. Subject: Maxtor 7213/HD Timeouts/Disk read doesn't match write??
  5. Summary: Problems with disk I/O under Linux. Bad hardware? Bugged Software?
  6. Keywords: Linux I/O, Maxtor 7213, Kouwei KW-556A controller, HD timeout.
  7. Message-ID: <1992Sep15.175932.13580@afterlife.ncsc.mil>
  8. Date: 15 Sep 92 17:59:32 GMT
  9. Organization: The Great Beyond
  10. Lines: 363
  11.  
  12. Recently, I have been experimenting with Linux on my home PC. I have
  13. tried both the MCC and SLS releases with a variety of different disk
  14. partitioning schemes. I noticed a number of HD timeouts/controller
  15. reset messages with both the MCC and SLS releases. Most recently, I
  16. re-partitioned my disk and loaded the SLS release. With this setup, I
  17. didn't notice any HD timeouts, but I was using only a small part of my
  18. disk. Namely, I had /dev/hdb1 (32M) as /, swap on /dev/hdb2 (16M), and
  19. the rest of the disk as one large unused partition (were I had been
  20. experimenting with extfs under the MCC release).
  21.  
  22. Since I wasn't having any problems with this minimal setup, I decided
  23. to see if my problems were caused by something related to the portions
  24. of my disk not presently in use. So I created a 64M Minix filesystem
  25. on /dev/hdb3 and mounted it on /mnt. I then ran a trivial little disk
  26. exerciser program I just wrote (attached below), and got some puzzling
  27. results. Sometimes the program would read 0xd0 instead of 0.
  28. Sometimes it would read 0xd5 instead of 0x55. The differences were
  29. never at exactly the same place. The random reads always produce HD
  30. timeouts. I have attached a screen dump of one of these errors. Only
  31. once did I think to do an "od" of the file. The one time I did so, the
  32. file had the correct values throughout. I have been invoking my tests
  33. with "ufstst 8000" (write/read 8,000 8192 byte chunks).
  34.  
  35. My system is a Technology Power Sonic Motherboard 386@33MHz, 8MHz ISA
  36. bus, 8MB DRAM, Diamond Speedstar Plus SVGA card, Zoom VFP32bis modem
  37. card, Kouwei KW-556A IDE/Multi-I/O card. The disks are a Quantum
  38. lps105 master and Maxtor 7213 slave. There are also the obligatory
  39. floppies (Teac 3.5 and 5.25 and a CMS DJ-10 off the floppy
  40. controller).
  41.  
  42. I'm left with several questions. Do I have a bad or failing disk?
  43. Could there be unmapped bad spots on the disk? Is there a bug in Linux
  44. causing this? Could it be that my disk controller is simply
  45. incompatible? Is anyone else running with either the Maxtor 7213 disk
  46. or the Kouwei controller, and if so, any problems? If you have a setup
  47. which gives you HD timeouts, would you take a few minutes to try my
  48. program and see what happens? If you have a 7213, would you try my
  49. program regardless? With a few simple mods, this program should
  50. compile and run under DOS, the open would need to explicitly call for
  51. binary mode, but that's about it.
  52.  
  53. Thanks for your patience. I'm open for suggestions.
  54.  
  55. --Cut here--
  56. /*
  57.   
  58.   ufstst [#blocks]
  59.   Compile with "cc -O2 -o ufstst ufstst.c"
  60.   
  61.   */
  62.  
  63. #define DEBUG 0
  64. #define MAX 512L
  65. #define BLK 8192L
  66. #define ME "ufstst"
  67.  
  68. #include <memory.h>
  69. #include <stdlib.h>
  70. #include <fcntl.h>
  71. #include <sys/types.h>
  72. #include <sys/stat.h>
  73. #include <errno.h>
  74. #include <stdio.h>
  75. #include <time.h>
  76.  
  77. extern int errno;
  78.  
  79. main(argc, argv)
  80.      int argc;
  81.      char *argv[];
  82. {
  83.   int ufs;
  84.   char *filename = "junk";
  85.   unsigned char pattern[4][BLK];
  86.   unsigned char buff[BLK+1];
  87.   int i, j, k;
  88.   long place, rem;
  89.   long max;
  90.   struct stat stat_buff;
  91.   long seek_status;
  92.   int status;
  93.   long blksize;
  94.   time_t start_time, end_time, elapsed_time;
  95.   double xfer_rate, avg_read_rate, avg_write_rate, avg_random_read_rate;
  96.   int amtwrit;
  97.   int bad_cnt;
  98.   
  99. #if DEBUG
  100.   long smin, smax;
  101. #endif
  102.   
  103.   if (argc > 2) {
  104.     fprintf(stderr, "Usage: %s <number of blocks>\n", ME);
  105.     exit(1);
  106.   }
  107.   
  108.   if (argc == 2)
  109.     max = atoi(argv[1]);
  110.   else
  111.     max = MAX;
  112.   
  113.   errno = 0;
  114.   if ((status = stat(filename, &stat_buff)) < 0)
  115.     if (errno != ENOENT) {
  116.       perror(ME);
  117.       exit(99);
  118.     }
  119.   
  120.   if (status == 0) {
  121.     fprintf(stderr,"%s: '%s' exists, continue? (y/n) ", ME, filename);
  122.     if (!yes_no()) exit(99);
  123.     unlink(filename);
  124.   }
  125.   
  126.   if ((ufs = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0666)) <= 0)
  127.     {
  128.       fprintf(stderr, "%s: Couldn't open '%s'.\n", ME, filename);
  129.       perror("open:");
  130.       exit(99);
  131.     }
  132.   
  133.   errno = 0;
  134.   if ((status = stat(filename, &stat_buff)) < 0)
  135.     {
  136.       perror(ME);
  137.       exit(99);
  138.     }
  139.   
  140.   blksize = BLK;
  141.   printf("%s: Writing %ld blocks of %ld bytes. (%0.2f MB, %ld bytes)\n",
  142.      ME, max, blksize, (double) ((max * blksize)/(1024.0 * 1024.0)),
  143.      max * blksize);
  144.   
  145.   for(i=0; i<blksize; i++)
  146.     pattern[0][i] = 0x00;
  147.   
  148.   for(i=0; i<blksize; i++)
  149.     pattern[1][i] = 0xff;
  150.   
  151.   for(i=0; i<blksize; i++)
  152.     pattern[2][i] = 0xaa;
  153.   
  154.   for(i=0; i<blksize; i++)
  155.     pattern[3][i] = 0x55;
  156.   
  157.   avg_write_rate = 0.0;
  158.   avg_read_rate = 0.0;
  159.   avg_random_read_rate = 0.0;
  160.   
  161.   for(i=0; i<4; i++)
  162.     {
  163.       printf("Sequential writes, pattern %d (0x%02x):\n", i, pattern[i][0]);
  164.       start_time = time(NULL);
  165.       for(k=0; k<max; k++)
  166.     {
  167.       amtwrit = write(ufs, pattern[i], blksize);
  168.       if ((amtwrit < 0) || (amtwrit != blksize))
  169.         {
  170.           fprintf(stderr, "%s: error in write. amtwrit = %d\n",
  171.               ME, amtwrit);
  172.           perror("write:");
  173.           exit(99);
  174.         }
  175.       printf("%5d\015", k);
  176.     }
  177.       end_time = time(NULL);
  178.       elapsed_time = end_time - start_time;
  179.       printf("Elapsed time = %ld seconds.\n", elapsed_time);
  180.       xfer_rate = (float) ((max * blksize) /
  181.                (elapsed_time <= 0 ? (-1) : elapsed_time));
  182.       avg_write_rate += xfer_rate;
  183.       printf("Approximately %0.2f bytes per second (%0.2f KB/s).\n",
  184.          xfer_rate,
  185.          xfer_rate/1024.0);
  186.       
  187.       lseek(ufs, 0L, SEEK_SET);
  188.       
  189.       printf("Sequential reads, pattern %d:\n", i);
  190.       start_time = time(NULL);
  191.       for(k=0; k<max; k++)
  192.     {
  193.       if (read(ufs, buff, blksize) < 0)
  194.         {
  195.           fprintf(stderr, "%s: error in read.\n", ME);
  196.           perror("read:");
  197.           exit(99);
  198.         }
  199.       if (memcmp(buff, pattern[i], blksize) != 0)
  200.         {
  201.           fprintf(stderr, "%s: pattern read differs from what was written!\n", ME);
  202.           bad_cnt = 0;
  203.           for(j=0; j<blksize; j++)
  204.         {
  205.           if (buff[j] != pattern[i][j])
  206.             {
  207.               printf("Record %d, offset %d: was %02x should have been %02x\n",
  208.                  k, j, buff[j], pattern[i][j]);
  209.               if (bad_cnt++ >= 20)
  210.             {
  211.               fprintf(stderr,"more? (y/n) ");
  212.               if (!yes_no()) break;
  213.               bad_cnt = 0;
  214.             }
  215.             }
  216.         }
  217.           fprintf(stderr,"Continue tests? (y/n)");
  218.           if (!yes_no()) exit(99);
  219.         }
  220.       printf("%5d\015", k);
  221.     }
  222.       end_time = time(NULL);
  223.       elapsed_time = end_time - start_time;
  224.       printf("Elapsed time = %ld seconds.\n", elapsed_time);
  225.       xfer_rate = (float) ((max * blksize) /
  226.                (elapsed_time <= 0 ? (-1) : elapsed_time));
  227.       avg_read_rate += xfer_rate;
  228.       printf("Approximately %0.2f bytes per second (%0.2f KB/s).\n",
  229.          xfer_rate,
  230.          xfer_rate/1024.0);
  231.       
  232. #if DEBUG
  233.       smin = max * blksize + 1;
  234.       smax = 0;
  235. #endif
  236.       srand(1);
  237.       printf("Random reads, pattern %d:\n", i);
  238.       start_time = time(NULL);
  239.       for(k=0; k<max; k++)
  240.     {
  241.       place = (long) rand();
  242.       place = (long) (place % (max * blksize));
  243.       if ((rem = place % blksize) != 0) place += (blksize - rem);
  244.       if (place == (max * blksize)) place -= (long) blksize;
  245. #if DEBUG
  246.       smin = (smin < place) ? smin : place;
  247.       smax = (smax > place) ? smax : place;
  248. #endif
  249.       if ((seek_status = lseek(ufs, place, SEEK_SET)) < 0L)
  250.         {
  251.           fprintf(stderr, "%s: lseek failed. seek_status = %ld\n", ME, seek_status);
  252.           perror("lseek");
  253.           printf("place = %ld\n", place);
  254.           exit(99);
  255.         }
  256.       if (read(ufs, buff, blksize) < 0)
  257.         {
  258.           fprintf(stderr, "%s: error in read.\n", ME);
  259.           perror("read:");
  260.           exit(99);
  261.         }
  262.       if (memcmp(buff, pattern[i], blksize) != 0)
  263.         {
  264.           fprintf(stderr, "%s: pattern read differs from what was written!\n", ME);
  265.           bad_cnt = 0;
  266.           for(j=0; j<blksize; j++)
  267.         {
  268.           if (buff[j] != pattern[i][j])
  269.             {
  270.               printf("at %d: was: %2x should have been %2x\n",
  271.                  j, buff[j], pattern[i][j]);
  272.               if (bad_cnt++ >= 20)
  273.             {
  274.               fprintf(stderr,"more? (y/n) ");
  275.               if (!yes_no()) break;
  276.               bad_cnt = 0;
  277.             }
  278.             }
  279.         }
  280.           fprintf(stderr,"Continue tests? (y/n)");
  281.           if (!yes_no()) exit(99);
  282.         }
  283.       printf("%5d %10ld\015", k, place);
  284.     }
  285.       end_time = time(NULL);
  286.       elapsed_time = end_time - start_time;
  287.       printf("Elapsed time = %ld seconds.\n", elapsed_time);
  288.       xfer_rate = (float) ((max * blksize) /
  289.                (elapsed_time <= 0 ? (-1) : elapsed_time));
  290.       avg_random_read_rate += xfer_rate;
  291.       printf("Approximately %0.2f bytes per second (%0.2f KB/s).\n\n",
  292.          xfer_rate,
  293.          xfer_rate/1024.0);
  294. #if DEBUG
  295.       printf("DEBUG: smin=%ld, smax=%ld\n", smin, smax);
  296. #endif
  297.       
  298.       lseek(ufs, 0L, SEEK_SET);
  299.     }
  300.   
  301.   avg_write_rate = avg_write_rate/(4.0 * 1024.0);
  302.   avg_read_rate = avg_read_rate/(4.0 * 1024.0);
  303.   avg_random_read_rate = avg_random_read_rate/(4.0 * 1024.0);
  304.   printf("Avg. write rate = %0.2f, read = %0.2f, rand = %0.2f\n",
  305.      avg_write_rate, avg_read_rate, avg_random_read_rate);
  306.   
  307.   close(ufs);
  308.   if (unlink(filename) < 0)
  309.     fprintf(stderr,"%s: %s not removed.\n", ME, filename);
  310.   printf("%s: completed.\n", ME);
  311.   return 0;
  312. }
  313.  
  314.  
  315. int yes_no()
  316. {
  317.   int ans, dummy;
  318.   
  319.   while((ans = dummy = getchar()) != EOF) {
  320.     switch(ans) {
  321.     case 'y':
  322.     case 'Y':
  323.       while(dummy != '\n' && dummy != EOF)
  324.     dummy = getchar();
  325.       return(1);
  326.     case 'n':
  327.     case 'N':
  328.       while(dummy != '\n' && dummy != EOF)
  329.     dummy = getchar();
  330.       return(0);
  331.     default:
  332.       fprintf(stderr, "%s: '%c' is not valid here, enter 'y' or 'n'\n",
  333.           ME, ans);
  334.       while(dummy != '\n' && dummy != EOF)
  335.     dummy = getchar();
  336.       break;
  337.     } /* end switch */
  338.   } /* end while */
  339.   
  340.   return(-99);
  341.   
  342. } /* end yes_no() */
  343. --Cut here--
  344.  
  345. The screendump:
  346.  
  347.  6468Unexpected HD interrupt
  348. ufstst: pattern read differs from what was written!
  349. Record 6469, offset 1262: was d5 should have been 55
  350. Record 6469, offset 1264: was d5 should have been 55
  351. Record 6469, offset 1266: was d5 should have been 55
  352. Record 6469, offset 1268: was d5 should have been 55
  353. Record 6469, offset 1270: was d5 should have been 55
  354. Record 6469, offset 1272: was d5 should have been 55
  355. Record 6469, offset 1274: was d5 should have been 55
  356. Record 6469, offset 1276: was d5 should have been 55
  357. Record 6469, offset 1278: was d5 should have been 55
  358. Record 6469, offset 1280: was d5 should have been 55
  359. Record 6469, offset 1282: was d5 should have been 55
  360. Record 6469, offset 1284: was d5 should have been 55
  361. Record 6469, offset 1286: was d5 should have been 55
  362. Record 6469, offset 1288: was d5 should have been 55
  363. Record 6469, offset 1290: was d5 should have been 55
  364. Record 6469, offset 1292: was d5 should have been 55
  365. Record 6469, offset 1294: was d5 should have been 55
  366. Record 6469, offset 1296: was d5 should have been 55
  367. Record 6469, offset 1298: was d5 should have been 55
  368. Record 6469, offset 1300: was d5 should have been 55
  369. Record 6469, offset 1302: was d5 should have been 55
  370. more? (y/n) HD-controller reset
  371.  
  372. --End of Message--
  373. -- 
  374. Steve Aliff (swaliff@afterlife.ncsc.mil [144.51.1.1])
  375.