2000-07-06 Theodore Ts'o <tytso@valinux.com>
+ * badblocks.c (check_mount, main): Check to see if the filesystem
+ is mounted before doing a read/write or non-destructive
+ test. This can be overriden using the new -f option.
+
* badblocks.8.in: Update manual page to reflect that the
blocks-count parameter is now optional. Also properly
- document the start-block parameter.
+ document the start-block parameter. Added documentation
+ for the -f option.
* badblocks.c (main): Allow the blocks-count parameter to be
optional. If it's not specified, use the size of the
.SH SYNOPSIS
.B badblocks
[
-.B \-svwn
+.B \-svwnf
]
[
.B \-b
test, then it's possble for questionable blocks on an unreliable
hard drive to be hidden by the effects of the hard disk track buffer.
.TP
+.B \-f
+Normally, badblocks will refuse to do a read/write or a non-destructive
+test on a device which is mounted, since this can cause the system to
+potentially crash. This can be overriden using the
+.B \-
+flag, but this should not be done under normal circumstances. The only time
+when this option might be safe is if the /etc/mtab file is incorrect, and
+the device really isn't mounted.
+.TP
.BI \-i " input_file"
Read a list of already existing known bad blocks.
.B Badblocks
static int w_flag = 0; /* do r/w test: 0=no, 1=yes,
* 2=non-destructive */
static int s_flag = 0; /* show progress of test */
+static int force = 0; /* force check of mounted device */
static char *blkbuf; /* Allocation array for bad block testing */
-static void usage(void)
+static void usage(NOARGS)
{
- fprintf(stderr, _("Usage: %s [-b block_size] [-i input_file] [-o output_file] [-svwn]\n [-c blocks_at_once] [-p num_passes] device [blocks_count] [start_count]\n"),
+ fprintf(stderr, _("Usage: %s [-b block_size] [-i input_file] [-o output_file] [-svwnf]\n [-c blocks_at_once] [-p num_passes] device [blocks_count] [start_count]\n"),
program_name);
exit (1);
}
static blk_t next_bad = 0;
static ext2_badblocks_iterate bb_iter = NULL;
+/* Everything is STDC, these days */
+#define NOARGS void
+
/*
* This routine reports a new bad block. If the bad block has already
* been seen before, then it returns 0; otherwise it returns 1.
return 1;
}
-static void print_status (void)
+static void print_status(NOARGS)
{
fprintf(stderr, "%9ld/%9ld", currently_testing, num_blocks);
fprintf(stderr, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
fflush (stderr);
}
-static void alarm_intr (int alnum)
+static void alarm_intr(int alnum)
{
signal (SIGALRM, alarm_intr);
alarm(1);
static void *terminate_addr = NULL;
-static void terminate_intr (int signo)
+static void terminate_intr(int signo)
{
if (terminate_addr)
longjmp(terminate_addr,1);
exit(1);
}
-static void capture_terminate (jmp_buf term_addr)
+static void capture_terminate(jmp_buf term_addr)
{
terminate_addr = term_addr;
signal (SIGHUP, terminate_intr);
signal (SIGUSR2, terminate_intr);
}
-static void uncapture_terminate()
+static void uncapture_terminate(NOARGS)
{
terminate_addr = NULL;
signal (SIGHUP, SIG_DFL);
return bb_count;
}
+static void check_mount(char *device_name)
+{
+ errcode_t retval;
+ int mount_flags;
+
+ retval = ext2fs_check_if_mounted(device_name, &mount_flags);
+ if (retval) {
+ com_err("ext2fs_check_if_mount", retval,
+ _("while determining whether %s is mounted."),
+ device_name);
+ return;
+ }
+ if (!(mount_flags & EXT2_MF_MOUNTED))
+ return;
+
+ fprintf(stderr, _("%s is mounted; "), device_name);
+ if (force) {
+ fprintf(stderr, _("badblocks forced anyway. "
+ "Hope /etc/mtab is incorrect.\n"));
+ return;
+ }
+ fprintf(stderr, _("it's not safe to run badblocks!\n"));
+ exit(1);
+}
+
+
int main (int argc, char ** argv)
{
int c;
if (argc && *argv)
program_name = *argv;
- while ((c = getopt (argc, argv, "b:i:o:svwnc:p:h:")) != EOF) {
+ while ((c = getopt (argc, argv, "bf:i:o:svwnc:p:h:")) != EOF) {
switch (c) {
case 'b':
block_size = strtoul (optarg, &tmp, 0);
exit (1);
}
break;
+ case 'f':
+ force++;
+ break;
case 'i':
input_file = optarg;
break;
from_count, blocks_count);
exit (1);
}
+ if (w_flag)
+ check_mount(device_name);
+
dev = open (device_name, w_flag ? O_RDWR : O_RDONLY);
if (dev == -1)
{