]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
Many files:
authorTheodore Ts'o <tytso@mit.edu>
Mon, 19 Jul 1999 15:27:37 +0000 (15:27 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 19 Jul 1999 15:27:37 +0000 (15:27 +0000)
  unix.c: Add support for calculating a progress bar if the -C0 option
   is given.  The function e2fsck_clear_progbar() clears the progress bar
   and must be called before any message is issued.  SIGUSR1 will enable
   the progress bar, and SIGUSR2 will disable the progress bar.  This is
   used by fsck to handle parallel filesystem checks.  Also, set the
   device_name from the filesystem label if it is available.
  e2fsck.h: Add new flags E2F_FLAG_PROG_BAR and E2F_FLAG_PROG_SUPRESS.
   Add new field in the e2fsck structure which contains the last tenth of
   a percent printed for the user.
  message.c (print_e2fsck_message): Add call to e2fsck_clear_progbar().
  pass1.c (e2fsck_pass1):
  pass2.c (e2fsck_pass2):
  pass3.c (e2fsck_pass3):
  pass4.c (e2fsck_pass4):
  pass5.c (e2fsck_pass5): Add call to e2fsck_clear_progbar when printing
   the resource tracking information.
  pass5.c (check_block_bitmaps, check_inode_bitmaps): If there is an
   error in the bitmaps, suppress printing the progress bar using the
   suppression flag for the remainder of the check, in order to clean up
   the display.

e2fsck/ChangeLog
e2fsck/e2fsck.8.in
e2fsck/e2fsck.h
e2fsck/message.c
e2fsck/pass1.c
e2fsck/pass2.c
e2fsck/pass3.c
e2fsck/pass4.c
e2fsck/pass5.c
e2fsck/unix.c

index 79bd9aae4fdbbf280d01258252d16fc1f59e743e..c25e478e9f7628263be4777c626503f598013146 100644 (file)
@@ -1,3 +1,34 @@
+1999-07-18    <tytso@valinux.com>
+
+       * unix.c: Add support for calculating a progress bar if the -C0
+               option is given.   The function e2fsck_clear_progbar()
+               clears the progress bar and must be called before any
+               message is issued.  SIGUSR1 will enable the progress bar,
+               and SIGUSR2 will disable the progress bar.  This is used
+               by fsck to handle parallel filesystem checks.  Also, set
+               the device_name from the filesystem label if it is
+               available. 
+
+       * e2fsck.h: Add new flags E2F_FLAG_PROG_BAR and
+               E2F_FLAG_PROG_SUPRESS.  Add new field in the e2fsck
+               structure which contains the last tenth of a percent
+               printed for the user.
+
+       * message.c (print_e2fsck_message): Add call to
+               e2fsck_clear_progbar(). 
+
+       * pass1.c (e2fsck_pass1):
+       * pass2.c (e2fsck_pass2):
+       * pass3.c (e2fsck_pass3):
+       * pass4.c (e2fsck_pass4):
+       * pass5.c (e2fsck_pass5): Add call to e2fsck_clear_progbar when
+               printing the resource tracking information.
+
+       * pass5.c (check_block_bitmaps, check_inode_bitmaps): If there is
+               an error in the bitmaps, suppress printing the progress
+               bar using the suppression flag for the remainder of the
+               check, in order to clean up the display.
+
 1999-06-30    <tytso@valinux.com>
 
        * unix.c (check_mount): Clean up the abort message displayed when
index 41e6dc894457b7bc6ff3e29bc7397e9044a53186..df4e6da6f76f5bbff8460f570115ad431e8a7230 100644 (file)
@@ -78,14 +78,13 @@ This option causes
 .B e2fsck
 to write completion information to the specified file descriptor 
 so that the progress of the filesystem 
-check can be monitored.  This option is typically used by programs which are
-executing 
-.BR e2fsck ,
-although -C 0 is a special case which will output a spinning
-character which can be useful for users who want to have something to watch
-while 
+check can be monitored.  This option is typically used by programs 
+which are running
+.BR e2fsck .
+If the file descriptor specified is 0, 
 .B e2fsck
-goes about its business.
+will print a completion bar as it goes about its business.  This requires
+that e2fsck is running on a video console or terminal.
 .TP
 .I -d
 Print debugging output (useless unless you are debugging
@@ -186,6 +185,21 @@ is the sum of the following conditions:
 .br
 \      128\    \-\ Shared library error
 .br
+.SH SIGNALS
+The following signals have the following effect when sent to 
+.BR e2fsck .
+.TP
+.B SIGUSR1
+This signal causes
+.B e2fsck
+to start displaying a completion bar.  (See discussion of the 
+.I -C
+option.)
+.TP
+.B SIGUSR2
+This signal causes
+.B e2fsck 
+to stop displaying a completion bar.
 .SH REPORTING BUGS
 Almost any piece of software will have bugs.  If you manage to find a
 filesystem which causes 
index 782edbc7f7eb01a99a3f37a8d24fe26a3a9438aa..86b411ce773dcc78ac2c369048f3b2548b958918 100644 (file)
@@ -102,6 +102,9 @@ struct resource_track {
 
 #define E2F_FLAG_SETJMP_OK     0x0010 /* Setjmp valid for abort */
 
+#define E2F_FLAG_PROG_BAR      0x0020 /* Progress bar on screen */
+#define E2F_FLAG_PROG_SUPPRESS 0x0040 /* Progress suspended */
+
 /*
  * Defines for indicating the e2fsck pass number
  */
@@ -196,6 +199,7 @@ struct e2fsck_struct {
         */
        int progress_fd;
        int progress_pos;
+       int progress_last_percent;
 
        /* File counts */
        int fs_directory_count;
@@ -299,3 +303,5 @@ extern void mtrace_print(char *mesg);
 #endif
 extern blk_t get_backup_sb(ext2_filsys fs);
 
+/* unix.c */
+extern void e2fsck_clear_progbar(e2fsck_t ctx);
index 1e440c5cf47f525e0ee172275d9e199baa4cfc79..8bb11df805271280cee3749437a099f7bc9ed0a9 100644 (file)
@@ -385,7 +385,8 @@ void print_e2fsck_message(e2fsck_t ctx, const char *msg,
        ext2_filsys fs = ctx->fs;
        const char *    cp;
        int             i;
-       
+
+       e2fsck_clear_progbar(ctx);
        for (cp = msg; *cp; cp++) {
                if (cp[0] == '@') {
                        cp++;
index 5ebd6e03276a866fa83f4acc8853cf21c8f01f2a..cebc82c50fe7419b2cbf3a64ae15dbf7ed3b3e7a 100644 (file)
@@ -524,8 +524,10 @@ endit:
        }
        
 #ifdef RESOURCE_TRACK
-       if (ctx->options & E2F_OPT_TIME2)
+       if (ctx->options & E2F_OPT_TIME2) {
+               e2fsck_clear_progbar(ctx);
                print_resource_track("Pass 1", &rtrack);
+       }
 #endif
 }
 
index 38c1eda631f6b36aded63f7040c7e45fdbe1c92b..37114e315f1bb8f282ce5b95dd37dcce1e01a331 100644 (file)
@@ -135,8 +135,10 @@ void e2fsck_pass2(e2fsck_t ctx)
                ctx->inode_bad_map = 0;
        }
 #ifdef RESOURCE_TRACK
-       if (ctx->options & E2F_OPT_TIME2)
+       if (ctx->options & E2F_OPT_TIME2) {
+               e2fsck_clear_progbar(ctx);
                print_resource_track("Pass 2", &rtrack);
+       }
 #endif
 }
 
index a3aaa04baf75c06434edb4f3c736d1c0e56595a6..2e4bfe2102e6616e217192e56e71d4bffe52b377 100644 (file)
@@ -99,8 +99,10 @@ void e2fsck_pass3(e2fsck_t ctx)
                goto abort_exit;
        }
 #ifdef RESOURCE_TRACK
-       if (ctx->options & E2F_OPT_TIME)
+       if (ctx->options & E2F_OPT_TIME) {
+               e2fsck_clear_progbar(ctx);
                print_resource_track("Peak memory", &ctx->global_rtrack);
+       }
 #endif
 
        check_root(ctx);
@@ -137,8 +139,10 @@ abort_exit:
        if (inode_done_map)
                ext2fs_free_inode_bitmap(inode_done_map);
 #ifdef RESOURCE_TRACK
-       if (ctx->options & E2F_OPT_TIME2)
+       if (ctx->options & E2F_OPT_TIME2) {
+               e2fsck_clear_progbar(ctx);
                print_resource_track("Pass 3", &rtrack);
+       }
 #endif
 }
 
index e059cc341c835dc36bec53f223436c65e48b9ef0..264b1c7833c31e9825d01cbfa3c061a52672568d 100644 (file)
@@ -153,8 +153,10 @@ void e2fsck_pass4(e2fsck_t ctx)
        ext2fs_free_inode_bitmap(ctx->inode_bb_map);
        ctx->inode_bb_map = 0;
 #ifdef RESOURCE_TRACK
-       if (ctx->options & E2F_OPT_TIME2)
+       if (ctx->options & E2F_OPT_TIME2) {
+               e2fsck_clear_progbar(ctx);
                print_resource_track("Pass 4", &rtrack);
+       }
 #endif
 }
 
index 274052ece2138bb1970a0647a3a0f80bc72b90cb..b39b3134355430201f1e3555de9d943f782c8373 100644 (file)
@@ -65,8 +65,10 @@ void e2fsck_pass5(e2fsck_t ctx)
        ctx->block_found_map = 0;
 
 #ifdef RESOURCE_TRACK
-       if (ctx->options & E2F_OPT_TIME2)
+       if (ctx->options & E2F_OPT_TIME2) {
+               e2fsck_clear_progbar(ctx);
                print_resource_track("Pass 5", &rtrack);
+       }
 #endif
 }
 
@@ -142,6 +144,7 @@ redo_counts:
                }
                pctx.blk = i;
                fix_problem(ctx, problem, &pctx);
+               ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
                had_problem++;
                
        do_counts:
@@ -166,6 +169,8 @@ redo_counts:
                fixit = end_problem_latch(ctx,  PR_LATCH_BBITMAP);
        else
                fixit = -1;
+       ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
+       
        if (fixit == 1) {
                ext2fs_free_block_bitmap(fs->block_map);
                retval = ext2fs_copy_bitmap(ctx->block_found_map,
@@ -282,6 +287,7 @@ redo_counts:
                }
                pctx.ino = i;
                fix_problem(ctx, problem, &pctx);
+               ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
                had_problem++;
                
 do_counts:
@@ -312,6 +318,8 @@ do_counts:
                fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
        else
                fixit = -1;
+       ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
+       
        if (fixit == 1) {
                ext2fs_free_inode_bitmap(fs->inode_map);
                retval = ext2fs_copy_bitmap(ctx->inode_used_map,
index ed8082d583b18010a0d7f45597498bc49d6dcbc3..e33a814ecd245b6b1a2c15cf2a084b536e41d1ad 100644 (file)
@@ -18,6 +18,7 @@
 #include <ctype.h>
 #include <termios.h>
 #include <time.h>
+#include <signal.h>
 #ifdef HAVE_GETOPT_H
 #include <getopt.h>
 #endif
@@ -60,7 +61,8 @@ static void usage(e2fsck_t ctx)
        fprintf(stderr,
                "Usage: %s [-panyrcdfvstFSV] [-b superblock] [-B blocksize]\n"
                "\t\t[-I inode_buffer_blocks] [-P process_inode_size]\n"
-               "\t\t[-l|-L bad_blocks_file] device\n", ctx->program_name);
+               "\t\t[-l|-L bad_blocks_file] [-C fd] device\n",
+               ctx->program_name);
        exit(FSCK_USAGE);
 }
 
@@ -165,11 +167,11 @@ static void check_mount(e2fsck_t ctx)
 #endif
        
        if (ctx->options & E2F_OPT_READONLY) {
-               printf("Warning!  %s is mounted.\n", ctx->device_name);
+               printf("Warning!  %s is mounted.\n", ctx->filesystem_name);
                return;
        }
 
-       printf("%s is mounted.  ", ctx->device_name);
+       printf("%s is mounted.  ", ctx->filesystem_name);
        if (!isatty(0) || !isatty(1)) {
                printf("Cannot continue, aborting.\n\n");
                exit(FSCK_ERROR);
@@ -225,11 +227,51 @@ static void check_if_skip(e2fsck_t ctx)
 /*
  * For completion notice
  */
+struct percent_tbl {
+       int     max_pass;
+       int     table[32];
+};
+struct percent_tbl e2fsck_tbl = {
+       5, { 0, 70, 90, 92,  95, 100 }
+};
+static int dpywidth = 50;
+static char bar[] =
+       "==============================================================="
+       "===============================================================";
+static char spaces[] =
+       "                                                               "
+       "                                                               ";
+
+static float calc_percent(struct percent_tbl *tbl, int pass, int curr,
+                         int max)
+{
+       float   percent;
+       
+       if (pass <= 0)
+               return 0.0;
+       if (pass > tbl->max_pass)
+               return 100.0;
+       percent = ((float) curr) / ((float) max);
+       return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
+               + tbl->table[pass-1]);
+}
+
+extern void e2fsck_clear_progbar(e2fsck_t ctx)
+{
+       if (!(ctx->flags & E2F_FLAG_PROG_BAR))
+               return;
+       
+       printf("%s\r", spaces + (sizeof(spaces) - 80));
+       ctx->flags &= ~E2F_FLAG_PROG_BAR;
+}
+
 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
                                  unsigned long cur, unsigned long max)
 {
        const char spinner[] = "\\|/-";
        char buf[80];
+       int     i;
+       float percent;
 
        if (pass == 0)
                return 0;
@@ -238,9 +280,25 @@ static int e2fsck_update_progress(e2fsck_t ctx, int pass,
                sprintf(buf, "%d %lu %lu\n", pass, cur, max);
                write(ctx->progress_fd, buf, strlen(buf));
        } else {
+               if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
+                       return 0;
                ctx->progress_pos = (ctx->progress_pos+1) & 3;
-               fputc(spinner[ctx->progress_pos], stdout);
-               fputc('\b', stdout);
+               ctx->flags |= E2F_FLAG_PROG_BAR;
+               percent = calc_percent(&e2fsck_tbl, pass, cur, max);
+               if (ctx->progress_last_percent == (int) 1000 * percent)
+                       return 0;
+               ctx->progress_last_percent = (int) 1000 * percent;
+               i = ((percent * dpywidth) + 50) / 100;
+               printf("%s: |%s%s", ctx->device_name,
+                      bar + (sizeof(bar) - (i+1)),
+                      spaces + (sizeof(spaces) - (dpywidth - i + 1)));
+               if (percent == 100.0)
+                       fputc('|', stdout);
+               else
+                       fputc(spinner[ctx->progress_pos & 3], stdout);
+               printf(" %4.1f%%   \r", percent);
+               if (percent == 100.0)
+                       e2fsck_clear_progbar(ctx);
                fflush(stdout);
        }
        return 0;
@@ -266,6 +324,30 @@ static void reserve_stdio_fds(NOARGS)
        close(fd);
 }
 
+static e2fsck_t global_signal_ctx;
+
+static void signal_progress_on(int sig)
+{
+       e2fsck_t ctx = global_signal_ctx;
+
+       if (!ctx)
+               return;
+
+       ctx->progress = e2fsck_update_progress;
+       ctx->progress_fd = 0;
+}
+
+static void signal_progress_off(int sig)
+{
+       e2fsck_t ctx = global_signal_ctx;
+
+       if (!ctx)
+               return;
+
+       e2fsck_clear_progbar(ctx);
+       ctx->progress = 0;
+}
+
 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
 {
        int             flush = 0;
@@ -276,6 +358,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
        char            *oldpath = getenv("PATH");
        e2fsck_t        ctx;
        errcode_t       retval;
+       struct sigaction        sa;
 
        retval = e2fsck_allocate_context(&ctx);
        if (retval)
@@ -407,8 +490,6 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
            !cflag && !swapfs)
                ctx->options |= E2F_OPT_READONLY;
        ctx->filesystem_name = argv[optind];
-       if (ctx->device_name == 0)
-               ctx->device_name = ctx->filesystem_name;
        if (flush) {
 #ifdef BLKFLSBUF
                int     fd = open(ctx->filesystem_name, O_RDONLY, 0);
@@ -435,6 +516,18 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
                        exit(FSCK_ERROR);
                }
        }
+       /*
+        * Set up signal action
+        */
+       memset(&sa, 0, sizeof(struct sigaction));
+#ifdef SA_RESTART
+       sa.sa_flags = SA_RESTART;
+#endif
+       global_signal_ctx = ctx;
+       sa.sa_handler = signal_progress_on;
+       sigaction(SIGUSR1, &sa, 0);
+       sa.sa_handler = signal_progress_off;
+       sigaction(SIGUSR2, &sa, 0);
        return 0;
 }
 
@@ -594,6 +687,18 @@ restart:
                        "(%s)", ctx->filesystem_name);
                goto get_newer;
        }
+       if (ctx->device_name == 0 &&
+           (s->s_volume_name[0] != 0)) {
+               char *cp = malloc(sizeof(s->s_volume_name)+1);
+               if (cp) {
+                       strncpy(cp, s->s_volume_name,
+                               sizeof(s->s_volume_name));
+                       cp[sizeof(s->s_volume_name)] = 0;
+                       ctx->device_name = cp;
+               }
+       }
+       if (ctx->device_name == 0)
+               ctx->device_name = ctx->filesystem_name;
        
        /*
         * If the user specified a specific superblock, presumably the
@@ -653,6 +758,7 @@ restart:
        }
 
        run_result = e2fsck_run(ctx);
+       e2fsck_clear_progbar(ctx);
        if (run_result == E2F_FLAG_RESTART) {
                printf("Restarting e2fsck from the beginning...\n");
                retval = e2fsck_reset_context(ctx);