For the impatient, this patch introduces the pot-watching --monitor option, which checks the balance progress at regular intervals, and updates a single status line with the current progress and an estimated completion time.
Signed-off-by: Hugo Mills <h...@carfax.org.uk> --- btrfs_cmds.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++---- man/btrfs.8.in | 4 +- 2 files changed, 96 insertions(+), 10 deletions(-) diff --git a/btrfs_cmds.c b/btrfs_cmds.c index 2745d64..c681b5a 100644 --- a/btrfs_cmds.c +++ b/btrfs_cmds.c @@ -797,22 +797,108 @@ int get_balance_progress(char *path, struct btrfs_ioctl_balance_progress *bal) return err; } +const struct option progress_options[] = { + { "monitor", 0, NULL, 'm' }, + { NULL, 0, NULL, 0 } +}; + int do_balance_progress(int argc, char **argv) { char *path; int ret = 0; int err = 0; struct btrfs_ioctl_balance_progress bal; + __u64 last_completed = -1; + __u64 initial_completed = -1; + struct timeval now; + struct timeval started; + int monitor = 0; + + optind = 1; + while(1) { + int c = getopt_long(argc, argv, "m", progress_options, NULL); + if (c < 0) + break; + switch(c) { + case 'm': + monitor = 1; + break; + default: + fprintf(stderr, "Invalid arguments for balance progress\n"); + free(argv); + return 1; + } + } + + if(optind >= argc) { + fprintf(stderr, "No filesystem path given for progress\n"); + return 1; + } - path = argv[1]; + path = argv[optind]; + do { + int prs = 0; - ret = get_balance_progress(path, &bal); - if (!ret) - printf("\r%llu/%llu block groups moved, " - "%0.2f%% complete.\n", - bal.completed, - bal.expected, - (float)bal.completed/bal.expected*100.0); + ret = get_balance_progress(path, &bal); + if (ret) + break; + + if (last_completed != bal.completed) { + printf("\r%llu/%llu block groups moved, " + "%0.2f%% complete.", + bal.completed, + bal.expected, + (float)bal.completed/bal.expected*100.0); + } + + if (initial_completed != -1 + && initial_completed != bal.completed) { + ret = gettimeofday(&now, NULL); + if (ret) { + fprintf(stderr, "Can't read current time\n"); + return 22; + } + /* Seconds per block */ + float rate = (float)(now.tv_sec - started.tv_sec) + / (bal.completed - initial_completed); + int secs_remaining = rate + * (bal.expected - bal.completed); + printf(" Time remaining"); + if (secs_remaining >= 60*60*24) { + printf(" %dd", secs_remaining / (60*60*24)); + secs_remaining %= 60*60*24; + prs = 1; + } + if (prs || secs_remaining >= 60*60) { + printf(" %dh", secs_remaining / (60*60)); + secs_remaining %= 60*60; + prs = 1; + } + if (prs || secs_remaining > 60) { + printf(" %dm", secs_remaining / 60); + secs_remaining %= 60; + } + printf(" %ds\x1b[K", secs_remaining); + } + + if (last_completed != -1 && last_completed != bal.completed) { + initial_completed = bal.completed; + ret = gettimeofday(&started, NULL); + if (ret) { + fprintf(stderr, "Can't read current time\n"); + return 22; + } + } + + last_completed = bal.completed; + + if (monitor) { + fflush(stdout); + sleep(1); + } else { + printf("\n"); + } + } while(monitor); switch(ret) { case 0: diff --git a/man/btrfs.8.in b/man/btrfs.8.in index 69d8613..3f7642e 100644 --- a/man/btrfs.8.in +++ b/man/btrfs.8.in @@ -21,7 +21,7 @@ btrfs \- control a btrfs filesystem .PP \fBbtrfs\fP \fBfilesystem resize\fP\fI [+/\-]<size>[gkm]|max <filesystem>\fP .PP -\fBbtrfs\fP \fBbalance progress\fP \fI<path>\fP +\fBbtrfs\fP \fBbalance progress\fP [\fB-m\fP|\fB--monitor\fP] \fI<path>\fP .PP \fBbtrfs\fP \fBdevice scan\fP\fI [<device> [<device>..]]\fP .PP @@ -150,7 +150,7 @@ Balance the chunks of the filesystem identified by \fI<path>\fR across the devices. .TP -\fBbalance progress\fP \fI<path>\fP +\fBbalance progress\fP [\fB-m\fP|\fB--monitor\fP] \fI<path>\fP Report progress on the currently-running balance operation on \fI<path>\fP. .TP -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html