From owner-freebsd-hackers Thu Sep 21 19:37:58 2000 Delivered-To: freebsd-hackers@freebsd.org Received: from aurora.sol.net (aurora.sol.net [206.55.65.76]) by hub.freebsd.org (Postfix) with ESMTP id 80DBF37B423; Thu, 21 Sep 2000 19:37:49 -0700 (PDT) Received: (from jgreco@localhost) by aurora.sol.net (8.9.3/8.9.2/SNNS-1.02) id VAA16401; Thu, 21 Sep 2000 21:37:47 -0500 (CDT) From: Joe Greco Message-Id: <200009220237.VAA16401@aurora.sol.net> Subject: Re: Frustration with SCSI system To: imp@village.org Date: Thu, 21 Sep 2000 21:37:46 -0500 (CDT) Cc: hackers@freebsd.org, isp@freebsd.org X-Mailer: ELM [version 2.5 PL3] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Whoops, sorry about the previous misfire... > In message <200009201958.MAA45703@ns2.uncanny.net> Edward Elhauge writes: > : to autorecover on bad sectors, but every system that I've had to recover > : seems to be in a state where the bad sectors aren't remapping. I've tried > > I've often wanted to write a bad block remapper. While SCSI is > supposed to do this automatically, I've found that a scan on any > adaptec controller will remap these blocks (forces the remapping). I've got a program which attempts to read all blocks and may be able to rewrite bad blocks. It's nothing fancy. Only works if you've got auto-reallocate turned on in the drive. % cat diskscan.c #include #include #include #include int fixup(off, fd) off_t off; int fd; { char buffer[512]; int i, rval; for (i = 0; i < 65536; i += 512) { if (lseek(fd, off + i, SEEK_SET) < 0) { doerror("lseek", off + i, 0); } if ((rval = read(fd, buffer, sizeof(buffer))) != sizeof(buffer)) { if (errno) { if (lseek(fd, off + i, SEEK_SET) < 0) { doerror("lseek", off + i, 0); } write(fd, buffer, sizeof(buffer)); } } } } int doerror(str, off, type) char *str; off_t off; int type; { static int ign = 0; char buffer[80]; fprintf(stderr, "\nError at %qx, ", (quad_t) off); perror(str); if (! ign) { if (type) { fprintf(stderr, "Attempt to correct? (y/n/a) "); } else { fprintf(stderr, "Press 'y' to continue: "); } while (! ign) { fgets(buffer, sizeof(buffer), stdin); if (*buffer == 'y') { return(0); } if (*buffer == 'n') { return(1); } if (*buffer == 'a') { ign++; return(0); } } } return(0); } int main(argc, argv) int argc; char *argv[]; { int fd, rval; char buffer[65536]; off_t off = 0; int eof = 0; int count = 0; if (argc != 2) { fprintf(stderr, "usage: diskscan \n"); exit(1); } if ((fd = open(argv[1], O_RDWR, 0644)) < 0) { perror(argv[1]); } while (! eof) { if (! count) { fprintf(stderr, "%qx, ", (quad_t) off); } count++; count %= 8; if (lseek(fd, off, SEEK_SET) < 0) { doerror("lseek", off, 0); } if ((rval = read(fd, buffer, sizeof(buffer))) != sizeof(buffer)) { if (errno) { if (! doerror("read", off, 1)) { fixup(off, fd); } } } off += sizeof(buffer); } } I don't even guarantee that it's correct, but I do use it with some success... vinum takes an entire drive offline when it sees an error, and I use this to scan for and fix errors before turning the drive back on. -- ... Joe ------------------------------------------------------------------------------- Joe Greco - Systems Administrator jgreco@ns.sol.net Solaria Public Access UNIX - Milwaukee, WI 414/342-4847 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message