/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* diskscan:
* performs a verification pass over a device specified on command line;
* display progress on stdout, and print bad sector numbers to stderr
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stropts.h>
#include <memory.h>
#include <ctype.h>
#include <malloc.h>
#include <signal.h>
static void verexit(); /* signal handler and exit routine */
static void report(); /* tell user how we're getting on */
#define FALSE 0
static char *progname;
int
extern int optind;
int c;
int errflag = 0;
char *device;
/* Don't buffer stdout - we don't want to see bursts */
{
switch (c) {
case 'W':
break;
case 'n':
eol = '\r';
break;
case 'y':
print_warn = 0;
break;
default:
++errflag;
break;
}
}
errflag++;
if (errflag) {
"\nUsage: %s [-W] [-n] [-y] <phys_device_name> \n",
progname);
exit(1);
}
perror("");
exit(4);
}
"%s: device %s is not character special\n",
exit(5);
}
perror("");
exit(8);
}
"%s: unable to get disk geometry.\n", progname);
perror("");
exit(9);
}
} else {
} else {
"info.\n", progname);
perror("");
exit(9);
}
}
return (0);
}
/*
* scandisk:
* attempt to read every sector of the drive;
* display bad sectors found on stderr
*/
static void
{
int trksiz = 0;
char *verbuf;
int i;
char *rptr;
} else {
}
/* #define LIBMALLOC */
#ifdef LIBMALLOC
extern int mallopt();
/* This adds 5k to the binary, but it's a lot prettier */
/* make track buffer sector aligned */
perror("mallopt");
exit(1);
}
(char *)NULL) {
perror("malloc");
exit(1);
}
#else
== (char *)NULL) {
perror("malloc");
exit(1);
}
(-sector_size));
#endif
/* write pattern in track buffer */
for (i = 0; i < trksiz; i++)
verbuf[i] = (char)0xe5;
/* Turn off retry, and set trap to turn them on again */
goto do_readonly;
/*
* display warning only if -n arg not passed
* (otherwise the UI system will take care of it)
*/
if (print_warn == 1) {
(void) printf(
"\nCAUTION: ABOUT TO DO DESTRUCTIVE WRITE ON %s\n", device);
(void) printf(" THIS WILL DESTROY ANY DATA YOU HAVE ON\n");
(void) printf(" THAT PARTITION OR SLICE.\n");
(void) printf("Do you want to continue (y/n)? ");
exit(10);
}
"Error seeking sector %llu Cylinder %llu\n",
verexit(1);
}
/*
* verify sector at a time only when
* the whole track write fails;
* (if we write a sector at a time, it takes forever)
*/
/*
* try writing to it once; if this fails,
* then announce the sector bad on stderr
*/
0) == -1) {
"sector %llu Cylinder %llu\n",
verexit(1);
}
!= sector_size) {
numbadwr++;
}
}
}
}
"Error seeking sector %llu Cylinder %llu\n",
verexit(1);
}
/*
* read a sector at a time only when
* the whole track write fails;
* (if we do a sector at a time read, it takes forever)
*/
0) == -1) {
" sector %llu Cylinder %llu\n",
verexit(1);
}
sector_size) {
numbadrd++;
}
}
}
}
(void) printf("%cFound %ld bad sector(s) on read,"
" %ld bad sector(s) on write%c",
}
}
static void
{
(void) printf("\n");
}
/*
* report where we are...
*/
static void
{
}