From 269cdd19207ce00287eaced36ede8a8d2a36e043 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 11 Sep 2012 09:54:02 -0700 Subject: [PATCH] hammer - Add scoreboard file option * Add -e option for mirror-stream, so one can see the progress of mirror-streams running in the background. --- sbin/hammer/cmd_mirror.c | 52 ++++++++++++++++++++++++++++++++++----- sbin/hammer/hammer.8 | 3 +++ sbin/hammer/hammer.c | 6 ++++- sbin/hammer/hammer_util.h | 3 +++ sbin/hammer/misc.c | 37 ++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 7 deletions(-) diff --git a/sbin/hammer/cmd_mirror.c b/sbin/hammer/cmd_mirror.c index e115ea28b7..fd4f913421 100644 --- a/sbin/hammer/cmd_mirror.c +++ b/sbin/hammer/cmd_mirror.c @@ -34,6 +34,10 @@ #include "hammer.h" +#define LINE1 0,20 +#define LINE2 20,78 +#define LINE3 90,70 + #define SERIALBUF_SIZE (512 * 1024) typedef struct histogram { @@ -120,6 +124,9 @@ again: fd = getpfs(&pfs, filesystem); + if (streaming >= 0) + score_printf(LINE1, "Running"); + if (streaming >= 0 && VerboseOpt && VerboseOpt < 2) { fprintf(stderr, "%cRunning \b\b", (sameline ? '\r' : '\n')); fflush(stderr); @@ -273,11 +280,15 @@ again: mirror.pfs_id = pfs.pfs_id; mirror.shared_uuid = pfs.ondisk->shared_uuid; if (ioctl(fd, HAMMERIOC_MIRROR_READ, &mirror) < 0) { + score_printf(LINE3, "Mirror-read %s failed: %s", + filesystem, strerror(errno)); fprintf(stderr, "Mirror-read %s failed: %s\n", filesystem, strerror(errno)); exit(1); } if (mirror.head.flags & HAMMER_IOC_HEAD_ERROR) { + score_printf(LINE3, "Mirror-read %s fatal error %d", + filesystem, mirror.head.error); fprintf(stderr, "Mirror-read %s fatal error %d\n", filesystem, mirror.head.error); @@ -291,8 +302,13 @@ again: n = write(1, mirror.ubuf, mirror.count); } if (n != mirror.count) { - fprintf(stderr, "Mirror-read %s failed: " - "short write\n", + score_printf(LINE3, + "Mirror-read %s failed: " + "short write", + filesystem); + fprintf(stderr, + "Mirror-read %s failed: " + "short write\n", filesystem); exit(1); } @@ -307,6 +323,13 @@ again: (intmax_t)total_bytes); fflush(stderr); sameline = 0; + } else if (streaming) { + score_printf(LINE2, + "obj=%016jx tids=%016jx:%016jx %11jd", + (uintmax_t)mirror.key_cur.obj_id, + (uintmax_t)mirror.tid_beg, + (uintmax_t)mirror.tid_end, + (intmax_t)total_bytes); } mirror.key_beg = mirror.key_cur; @@ -315,6 +338,11 @@ again: */ if (TimeoutOpt && (unsigned)(time(NULL) - base_t) > (unsigned)TimeoutOpt) { + score_printf(LINE3, + "Mirror-read %s interrupted by timer at" + " %016jx", + filesystem, + (uintmax_t)mirror.key_cur.obj_id); fprintf(stderr, "Mirror-read %s interrupted by timer at" " %016jx\n", @@ -406,6 +434,8 @@ done: if (VerboseOpt && streaming >= 0) { fprintf(stderr, " W"); fflush(stderr); + } else if (streaming >= 0) { + score_printf(LINE1, "Waiting"); } pfs.ondisk->sync_end_tid = mirror.tid_end; if (streaming < 0) { @@ -415,7 +445,11 @@ done: */ streaming = 0; } else if (ioctl(fd, HAMMERIOC_WAI_PSEUDOFS, &pfs) < 0) { - fprintf(stderr, "Mirror-read %s: cannot stream: %s\n", + score_printf(LINE3, + "Mirror-read %s: cannot stream: %s\n", + filesystem, strerror(errno)); + fprintf(stderr, + "Mirror-read %s: cannot stream: %s\n", filesystem, strerror(errno)); } else { t2 = time(NULL) - t1; @@ -472,6 +506,7 @@ generate_histogram(int fd, const char *filesystem, u_int64_t *tid_bytes; u_int64_t total; u_int64_t accum; + int chunkno; int i; int res; int off; @@ -509,6 +544,7 @@ generate_histogram(int fd, const char *filesystem, */ total = 0; accum = 0; + chunkno = 0; for (;;) { mirror.count = 0; if (ioctl(fd, HAMMERIOC_MIRROR_READ, &mirror) < 0) { @@ -590,12 +626,14 @@ generate_histogram(int fd, const char *filesystem, accum += len; } } - if (VerboseOpt > 1) { - if (*repeatp == 0 && accum > SplitupOpt) { + if (*repeatp == 0 && accum > SplitupOpt) { + if (VerboseOpt > 1) { fprintf(stderr, "."); fflush(stderr); - accum = 0; } + ++chunkno; + score_printf(LINE2, "Prescan chunk %d", chunkno); + accum = 0; } if (mirror.count == 0) break; @@ -631,6 +669,8 @@ generate_histogram(int fd, const char *filesystem, if (*repeatp == 0) { if (VerboseOpt > 1) fprintf(stderr, "\n"); /* newline after ... */ + score_printf(LINE3, "Prescan %d chunks, total %ju MBytes", + res, (uintmax_t)total / (1024 * 1024)); fprintf(stderr, "Prescan %d chunks, total %ju MBytes (", res, (uintmax_t)total / (1024 * 1024)); for (i = 0; i < res && i < 3; ++i) { diff --git a/sbin/hammer/hammer.8 b/sbin/hammer/hammer.8 index 4e88fefc66..644f013348 100644 --- a/sbin/hammer/hammer.8 +++ b/sbin/hammer/hammer.8 @@ -44,6 +44,7 @@ .Op Fl b Ar bandwidth .Op Fl C Ar cachesize Ns Op Ns Cm \&: Ns Ar readahead .Op Fl c Ar cyclefile +.Op Fl e Ar scoreboardfile .Op Fl f Ar blkdevs .\" .Op Fl s Ar linkpath .Op Fl i Ar delay @@ -134,6 +135,8 @@ If .Nm runs to completion it will delete .Ar cyclefile . +.It Fl e Ar scoreboardfile +Update scoreboard file with progress, primarily used by mirror-stream. .It Fl F Force operation. E.g.\& diff --git a/sbin/hammer/hammer.c b/sbin/hammer/hammer.c index f1b87a1577..6815379cb6 100644 --- a/sbin/hammer/hammer.c +++ b/sbin/hammer/hammer.c @@ -74,7 +74,8 @@ main(int ac, char **av) int ch; int cacheSize = 0; - while ((ch = getopt(ac, av, "b:c:dhf:i:m:p:qrs:t:v2yBC:FS:X")) != -1) { + while ((ch = getopt(ac, av, + "b:c:de:hf:i:m:p:qrs:t:v2yBC:FS:X")) != -1) { switch(ch) { case '2': TwoWayPipeOpt = 1; @@ -133,6 +134,9 @@ main(int ac, char **av) case 'd': ++DebugOpt; break; + case 'e': + ScoreBoardFile = optarg; + break; case 'h': usage(0); /* not reached */ diff --git a/sbin/hammer/hammer_util.h b/sbin/hammer/hammer_util.h index 678a189c7a..de1e7ec026 100644 --- a/sbin/hammer/hammer_util.h +++ b/sbin/hammer/hammer_util.h @@ -107,6 +107,7 @@ extern int64_t BootAreaSize; extern int64_t MemAreaSize; extern int64_t UndoBufferSize; extern int DebugOpt; +extern const char *ScoreBoardFile; extern int NumVolumes; extern int RootVolNo; extern struct volume_list VolList; @@ -159,5 +160,7 @@ void hammer_cache_del(struct cache_info *cache); void hammer_cache_used(struct cache_info *cache); void hammer_cache_flush(void); +void score_printf(size_t i, size_t w, const char *ctl, ...); + void panic(const char *ctl, ...) __printflike(1, 2); diff --git a/sbin/hammer/misc.c b/sbin/hammer/misc.c index b9decb7593..a27dc1dd80 100644 --- a/sbin/hammer/misc.c +++ b/sbin/hammer/misc.c @@ -36,6 +36,8 @@ #include "hammer.h" +const char *ScoreBoardFile; + /* * (taken from /usr/src/sys/vfs/hammer/hammer_btree.c) * @@ -130,3 +132,38 @@ hammer_crc_test_leaf(void *data, hammer_btree_leaf_elm_t leaf) return (leaf->data_crc == crc); } +void +score_printf(size_t i, size_t w, const char *ctl, ...) +{ + va_list va; + size_t n; + static size_t SSize; + static int SFd = -1; + static char ScoreBuf[1024]; + + if (ScoreBoardFile == NULL) + return; + assert(i + w < sizeof(ScoreBuf)); + if (SFd < 0) { + SFd = open(ScoreBoardFile, O_RDWR|O_CREAT|O_TRUNC, 0644); + if (SFd < 0) + return; + SSize = 0; + } + for (n = 0; n < i; ++n) { + if (ScoreBuf[n] == 0) + ScoreBuf[n] = ' '; + } + va_start(va, ctl); + vsnprintf(ScoreBuf + i, w - 1, ctl, va); + va_end(va); + n = strlen(ScoreBuf + i); + while (n < w - 1) { + ScoreBuf[i + n] = ' '; + ++n; + } + ScoreBuf[i + n] = '\n'; + if (SSize < i + w) + SSize = i + w; + pwrite(SFd, ScoreBuf, SSize, 0); +} -- 2.41.0