Whamcloud - gitweb
e2fsck: print thread log properly
authorLi Xi <lixi@ddn.com>
Mon, 26 Aug 2019 14:34:06 +0000 (22:34 +0800)
committerAndreas Dilger <adilger@whamcloud.com>
Mon, 19 Sep 2022 23:10:42 +0000 (17:10 -0600)
When multi-thread fsck is enabled, logs printed from multiple
threads could overlap with each other. The overlap sometimes
makes the logs unreadable because log_out() is used multiple times
for a single line.

This patch adds leading [Thread XXX] to each logs if multi-thread
is enabed by -m option.

This patch also adds message to show the group ranges and inode
numbers for each thread, which is useful for debuging multi-thread
check.

E2fsprogs-commit: 5b071ed80deca2cdc87585a673076529dd47ca6e

Change-Id: I4bd08bc48813a399ab3a79130ff159b12d22f3a0
Signed-off-by: Li Xi <lixi@ddn.com>
Signed-off-by: Wang Shilong <wshilong@ddn.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/e2fsck.h
e2fsck/logfile.c
e2fsck/pass1.c
e2fsck/problem.c
e2fsck/util.c
tests/f_multithread/expect.1
tests/f_multithread_logfile/expect.1
tests/f_multithread_no/expect.1

index 7613fc7..be89caa 100644 (file)
@@ -274,6 +274,10 @@ struct e2fsck_thread {
        dgrp_t          et_group_end;
        /* The next group number to check */
        dgrp_t          et_group_next;
+       /* Scanned inode number */
+       ext2_ino_t      et_inode_number;
+       char            et_log_buf[2048];
+       int             et_log_length;
 };
 #endif
 
index cc811d5..46ec2ac 100644 (file)
@@ -295,7 +295,6 @@ static FILE *set_up_log_file(e2fsck_t ctx, const char *key, const char *fn)
        struct string s, s1, s2;
        char *s0 = 0, *log_dir = 0, *log_fn = 0;
        int log_dir_wait = 0;
-       int string_size;
        char string_index[10];
 
        s.s = s1.s = s2.s = 0;
index 822b1d6..22b7509 100644 (file)
@@ -1460,6 +1460,10 @@ void e2fsck_pass1_run(e2fsck_t ctx)
                }
                if (!ino)
                        break;
+#ifdef HAVE_PTHREAD
+               if (ctx->global_ctx)
+                       ctx->thread_info.et_inode_number++;
+#endif
                pctx.ino = ino;
                pctx.inode = inode;
                ctx->stashed_ino = ino;
@@ -2330,7 +2334,12 @@ static errcode_t e2fsck_pass1_thread_prepare(e2fsck_t global_ctx, e2fsck_t *thre
        else
                tinfo->et_group_end = average_group * (thread_index + 1);
        tinfo->et_group_next = tinfo->et_group_start;
-
+       tinfo->et_inode_number = 0;
+       tinfo->et_log_buf[0] = '\0';
+       tinfo->et_log_length = 0;
+       if (thread_context->options & E2F_OPT_MULTITHREAD)
+               log_out(thread_context, _("Scan group range [%d, %d)\n"),
+                       tinfo->et_group_start, tinfo->et_group_end);
        thread_context->fs = thread_fs;
        *thread_ctx = thread_context;
        return 0;
@@ -2371,6 +2380,7 @@ static int e2fsck_pass1_thread_join_one(e2fsck_t global_ctx, e2fsck_t thread_ctx
        global_ctx->fs = global_fs;
        global_ctx->logf = global_logf;
        global_ctx->problem_logf = global_problem_logf;
+       global_ctx->global_ctx = NULL;
 
        if (thread_ctx->inode_used_map) {
                retval = e2fsck_pass1_copy_bitmap(global_fs,
@@ -2520,6 +2530,12 @@ static void *e2fsck_pass1_thread(void *arg)
        e2fsck_pass1_run(thread_ctx);
 
 out:
+       if (thread_ctx->options & E2F_OPT_MULTITHREAD)
+               log_out(thread_ctx,
+                       _("Scanned group range [%lu, %lu), inodes %lu\n"),
+                       thread_ctx->thread_info.et_group_start,
+                       thread_ctx->thread_info.et_group_end,
+                       thread_ctx->thread_info.et_inode_number);
        return NULL;
 }
 
@@ -2655,6 +2671,10 @@ static errcode_t scan_callback(ext2_filsys fs,
        if (ctx->global_ctx) {
                tinfo = &ctx->thread_info;
                tinfo->et_group_next++;
+               if (ctx->options & E2F_OPT_DEBUG &&
+                   ctx->options & E2F_OPT_MULTITHREAD)
+                       log_out(ctx, _("group %d finished\n"),
+                               tinfo->et_group_next);
                if (tinfo->et_group_next >= tinfo->et_group_end)
                        return EXT2_ET_SCAN_FINISHED;
        }
index 3c1b216..2f2c8fc 100644 (file)
@@ -2514,6 +2514,12 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
        if (*message)
                message = _(message);
        if (!suppress) {
+#ifdef HAVE_PTHREAD
+               if ((ctx->options & E2F_OPT_MULTITHREAD) && ctx->global_ctx)
+                       printf("[Thread %d] ",
+                              ctx->thread_info.et_thread_index);
+#endif
+
                if ((ctx->options & E2F_OPT_PREEN) &&
                    !(ptr->flags & PR_PREEN_NOHDR)) {
                        printf("%s: ", ctx->device_name ?
index 42740d9..254b4d0 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "config.h"
 #include <stdlib.h>
+#include <assert.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
@@ -84,13 +85,67 @@ out:
        exit(exit_value);
 }
 
+#ifdef HAVE_PTHREAD
+static void thread_log_out(struct e2fsck_thread *tinfo)
+{
+       printf("[Thread %d] %s", tinfo->et_thread_index,
+              tinfo->et_log_buf);
+       tinfo->et_log_length = 0;
+       tinfo->et_log_buf[0] = '\0';
+}
+#endif
+
 void log_out(e2fsck_t ctx, const char *fmt, ...)
 {
        va_list pvar;
+       struct e2fsck_thread *tinfo;
+       int buf_size;
+       int msg_size;
+       int left_size;
+       int fmt_length = strlen(fmt);
+
+#ifdef HAVE_PTHREAD
+       if ((ctx->options & E2F_OPT_MULTITHREAD) && ctx->global_ctx) {
+               tinfo = &ctx->thread_info;
+               buf_size = sizeof(tinfo->et_log_buf);
+               left_size = buf_size - tinfo->et_log_length;
+
+               va_start(pvar, fmt);
+               msg_size = vsnprintf(tinfo->et_log_buf + tinfo->et_log_length,
+                                    left_size, fmt, pvar);
+               va_end(pvar);
+
+               if (msg_size >= left_size) {
+                       tinfo->et_log_buf[tinfo->et_log_length] = '\0';
+
+                       assert(msg_size < buf_size);
+                       if (msg_size < buf_size) {
+                               thread_log_out(tinfo);
+
+                               va_start(pvar, fmt);
+                               msg_size = vsnprintf(tinfo->et_log_buf, buf_size,
+                                                    fmt, pvar);
+                               va_end(pvar);
+
+                               tinfo->et_log_length += msg_size;
+                               tinfo->et_log_buf[tinfo->et_log_length] = '\0';
+                       }
+               } else {
+                       tinfo->et_log_length += msg_size;
+                       tinfo->et_log_buf[tinfo->et_log_length] = '\0';
+               }
+
+               if (tinfo->et_log_length > 0 &&
+                   tinfo->et_log_buf[tinfo->et_log_length - 1] == '\n')
+                       thread_log_out(tinfo);
+       } else
+#endif
+       {
+               va_start(pvar, fmt);
+               vprintf(fmt, pvar);
+               va_end(pvar);
+       }
 
-       va_start(pvar, fmt);
-       vprintf(fmt, pvar);
-       va_end(pvar);
        if (ctx->logf) {
                va_start(pvar, fmt);
                vfprintf(ctx->logf, fmt, pvar);
index e2b954d..8d2acd2 100644 (file)
@@ -1,6 +1,8 @@
 ext2fs_open2: Bad magic number in super-block
 ../e2fsck/e2fsck: Superblock invalid, trying backup blocks...
-Pass 1: Checking inodes, blocks, and sizes
+[Thread 0] Scan group range [0, 2)
+[Thread 0] Pass 1: Checking inodes, blocks, and sizes
+[Thread 0] Scanned group range [0, 2), inodes 3008
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
index e2b954d..8d2acd2 100644 (file)
@@ -1,6 +1,8 @@
 ext2fs_open2: Bad magic number in super-block
 ../e2fsck/e2fsck: Superblock invalid, trying backup blocks...
-Pass 1: Checking inodes, blocks, and sizes
+[Thread 0] Scan group range [0, 2)
+[Thread 0] Pass 1: Checking inodes, blocks, and sizes
+[Thread 0] Scanned group range [0, 2), inodes 3008
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
index d14c408..f85a338 100644 (file)
@@ -1,6 +1,8 @@
 ext2fs_open2: Bad magic number in super-block
 ../e2fsck/e2fsck: Superblock invalid, trying backup blocks...
-Pass 1: Checking inodes, blocks, and sizes
+[Thread 0] Scan group range [0, 2)
+[Thread 0] Pass 1: Checking inodes, blocks, and sizes
+[Thread 0] Scanned group range [0, 2), inodes 3008
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts