Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add badblocks command line options to control status output #9

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion misc/badblocks.8.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ badblocks \- search a device for bad blocks
.SH SYNOPSIS
.B badblocks
[
.B \-svwnfBX
.B \-svwnfBXP
]
[
.B \-a
.I alarm_interval
]
[
.B \-b
Expand Down Expand Up @@ -83,6 +87,9 @@ and
programs.
.SH OPTIONS
.TP
.BI \-a " alarm_interval"
Interval (in seconds) used for displaying status updates. The default is 1.
.TP
.BI \-b " block_size"
Specify the size of blocks in bytes. The default is 1024.
.TP
Expand Down Expand Up @@ -199,6 +206,13 @@ option, as they are mutually exclusive.
.B \-B
Use buffered I/O and do not use Direct I/O, even if it is available.
.TP
.B \-P
Display status in machine parseable format. The data is comma separated and
LF terminated to make it easier to parsing by external applications. The
data format is:
% completed, time elapsed, read errors, write errors, corruption errors.
Example: 10.06, 1:22, 0, 0, 0
.TP
.B \-X
Internal flag only to be used by
.BR e2fsck (8)
Expand Down
52 changes: 38 additions & 14 deletions misc/badblocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ static int t_max; /* allocated test patterns */
static unsigned int *t_patts; /* test patterns */
static int use_buffered_io;
static int exclusive_ok;
static int parseable_output = 0; /* print output that can be easily parsed */
static int alarm_interval = 1;
static unsigned int max_bb = MAX_BAD_BLOCKS; /* Abort test if more than this
* number of bad blocks has been
* encountered */
Expand All @@ -97,9 +99,10 @@ static unsigned int sys_page_size = 4096;
static void usage(void)
{
fprintf(stderr, _(
"Usage: %s [-b block_size] [-i input_file] [-o output_file] [-svwnf]\n"
"Usage: %s [-b block_size] [-i input_file] [-o output_file] [-svwnfP]\n"
" [-c blocks_at_once] [-d delay_factor_between_reads] [-e max_bad_blocks]\n"
" [-p num_passes] [-t test_pattern [-t test_pattern [...]]]\n"
" [-a alarm_interval]\n"
" device [last_block [first_block]]\n"),
program_name);
exit (1);
Expand Down Expand Up @@ -223,34 +226,44 @@ static void print_status(void)
wchar_t wline_buf[128];
#endif
int len;
char format_str[128];

if (parseable_output) {
strcpy(format_str, "%6.2f, %s, %d, %d, %d");
} else {
strcpy(format_str, "%6.2f%% done, %s elapsed. (%d/%d/%d errors)");
}

gettimeofday(&time_end, 0);
len = snprintf(line_buf, sizeof(line_buf),
_("%6.2f%% done, %s elapsed. "
"(%d/%d/%d errors)"),
calc_percent((unsigned long) currently_testing,
(unsigned long) num_blocks),
time_diff_format(&time_end, &time_start, diff_buf),
num_read_errors,
num_write_errors,
num_corruption_errors);
_(format_str),
calc_percent((unsigned long) currently_testing,
(unsigned long) num_blocks),
time_diff_format(&time_end, &time_start, diff_buf),
num_read_errors,
num_write_errors,
num_corruption_errors);
#ifdef HAVE_MBSTOWCS
mbstowcs(wline_buf, line_buf, sizeof(line_buf));
len = wcswidth(wline_buf, sizeof(line_buf));
if (len < 0)
len = strlen(line_buf); /* Should never happen... */
#endif
fputs(line_buf, stderr);
memset(line_buf, '\b', len);
line_buf[len] = 0;
fputs(line_buf, stderr);
if (!parseable_output) {
memset(line_buf, '\b', len);
line_buf[len] = 0;
fputs(line_buf, stderr);
} else {
fputs("\n", stderr);
}
fflush (stderr);
}

static void alarm_intr(int alnum EXT2FS_ATTR((unused)))
{
signal (SIGALRM, alarm_intr);
alarm(1);
alarm(alarm_interval);
if (!num_blocks)
return;
print_status();
Expand Down Expand Up @@ -1094,7 +1107,7 @@ int main (int argc, char ** argv)

if (argc && *argv)
program_name = *argv;
while ((c = getopt (argc, argv, "b:d:e:fi:o:svwnc:p:h:t:BX")) != EOF) {
while ((c = getopt (argc, argv, "a:b:d:e:fi:o:svwnc:p:h:t:BXP")) != EOF) {
switch (c) {
case 'b':
block_size = parse_uint(optarg, "block size");
Expand Down Expand Up @@ -1183,6 +1196,17 @@ int main (int argc, char ** argv)
case 'X':
exclusive_ok++;
break;
case 'P':
parseable_output = 1;
break;
case 'a':
alarm_interval = parse_uint(optarg, "status alarm interval (seconds)");
if (alarm_interval == 0) {
com_err(program_name, 0, "%s",
_("Minimum alarm interval is 1 second"));
exit(1);
}
break;
default:
usage();
}
Expand Down