From patchwork Mon Nov 6 17:34:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wyllys Ingersoll X-Patchwork-Id: 834859 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=keepertech-com.20150623.gappssmtp.com header.i=@keepertech-com.20150623.gappssmtp.com header.b="SSblx+3P"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yW06V2rVhz9s7f for ; Tue, 7 Nov 2017 04:34:10 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753512AbdKFReJ (ORCPT ); Mon, 6 Nov 2017 12:34:09 -0500 Received: from mail-lf0-f52.google.com ([209.85.215.52]:43135 "EHLO mail-lf0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753505AbdKFReI (ORCPT ); Mon, 6 Nov 2017 12:34:08 -0500 Received: by mail-lf0-f52.google.com with SMTP id a16so11407569lfk.0 for ; Mon, 06 Nov 2017 09:34:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=keepertech-com.20150623.gappssmtp.com; s=20150623; h=mime-version:from:date:message-id:subject:to; bh=U/GZVxMYW6XaWxeAecIjnQuuVTomuzgE6lBJ9B04NHc=; b=SSblx+3Px1g0uQyGAZ26BOSIpMmhe0A3q4dAllaO/fZ2Ml2esQ7tGpxx0dGvghwQWy xmeO9wYXGLQtpZGIChKl65DdPvipYryC/YlHN5QngZ3msqfkf/9z8Urr0SaJtYOmueAf zKlZP/cTmjExvLMx5NQOCO7n6I8s4WUbLnwyCpQvT6cMYjI+Kuk5WJngCrmz5OdKGFgD p0SpKrCMgT5HZdXVFxyCJQ8Z7TWcrSvt2r4zTj6tRuWMefAQlkTwhvNFe3ohRwuy9d47 dR6XQ9xejmTZvSwWbrsH+BHdKtLAI1mCuXx8a+/SF7Q5C1MAOkRO3sHRMcdVzu+iRWtk HX9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=U/GZVxMYW6XaWxeAecIjnQuuVTomuzgE6lBJ9B04NHc=; b=EbhvE5EXYxoYjWV89pYRfPtJAdkpRDWIo9SKCguuhpmO/Erlln+jqVkmCjK9ErTSdQ Q5pHXa9H1rp647fWcwyC05+gKtE5eMphYbKhuKwczvbBX993DD5vCc0JwiOp1mj1dWTw xD1oU5YtuzwAf9Bc9Oc10DVbfOIhn1YvwBRy8JQX2JxNClq3GHFkUaceqgcoG4KFeHBF 4M99TOPb4wcI1AcHOUEXWqj2EObZ2sn31VOCuoqSnpNOzyUEyTl8jkf4mgzmqImBTcQp 7ReVEPOcMj1/3pJzxcXbP2jEs5JoxubqxqY7A12CmEqx1dGSd5PYn11tl/8YXXg9o9U8 C+EA== X-Gm-Message-State: AMCzsaU25QovR1hLYdOfFLZi72vFzMjWZQRrRN6alWLbH1oJY5g8NKQh NowAqrFpIUs/SiY5FfLqIadnvYdqq3PoesDnqjOju9fM X-Google-Smtp-Source: ABhQp+QYCodcpQftpXnp8C0t522ORZ0EUpOpjtUKgmW2JmGkF46o71qd64GHlWHrFAGZyDC/8CNGqrb7tJfkVAlFBKU= X-Received: by 10.46.68.73 with SMTP id r70mr6592366lja.174.1509989646780; Mon, 06 Nov 2017 09:34:06 -0800 (PST) MIME-Version: 1.0 Received: by 10.25.26.199 with HTTP; Mon, 6 Nov 2017 09:34:06 -0800 (PST) From: Wyllys Ingersoll Date: Mon, 6 Nov 2017 12:34:06 -0500 Message-ID: Subject: [PATCH] badblocks: Add options for parseable status output To: linux-ext4@vger.kernel.org, tytso@mit.edu Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org This patch adds a couple of new command line arguments to make it easier to control the frequency of the status output and make the output more parseable. Add new command line arguments for badblocks utility: [-a alarm_interval ] Control the frequency of status output (in seconds) [-P] makes the output more parseable by external programs (comma separated, LF terminated) Signed-off-by: Wyllys Ingersoll --- misc/badblocks.8.in | 16 +++++++++++++++- misc/badblocks.c | 52 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 53 insertions(+), 15 deletions(-) exit (1); @@ -223,17 +226,23 @@ 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)); @@ -241,16 +250,20 @@ static void print_status(void) 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(); @@ -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"); @@ -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(); } diff --git a/misc/badblocks.8.in b/misc/badblocks.8.in index ca4359382..043e420db 100644 --- a/misc/badblocks.8.in +++ b/misc/badblocks.8.in @@ -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 @@ -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 @@ -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) diff --git a/misc/badblocks.c b/misc/badblocks.c index e45939187..571856c21 100644 --- a/misc/badblocks.c +++ b/misc/badblocks.c @@ -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 */ @@ -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);