@@ -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:
@@ -174,6 +174,6 @@ struct btrfs_ioctl_balance_progress {
#define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64)
#define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \
struct btrfs_ioctl_space_args)
-#define BTRFS_IOC_BALANCE_PROGRESS _IOR(BTRFS_IOCTL_MAGIC, 25, \
+#define BTRFS_IOC_BALANCE_PROGRESS _IOR(BTRFS_IOCTL_MAGIC, 27, \
struct btrfs_ioctl_balance_progress)
#endif
@@ -23,7 +23,7 @@ btrfs \- control a btrfs filesystem
.PP
\fBbtrfs\fP \fBdevice scan\fP\fI [<device> [<device>..]]\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 show\fP\fI <dev>|<label> [<dev>|<label>...]\fP
.PP
@@ -163,9 +163,10 @@ across the devices.
Remove device(s) from a filesystem identified by \fI<path>\fR.
.PP
-\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 the
-filesystem mounted at \fI<path>\fP.
+filesystem mounted at \fI<path>\fP. Use --monitor to report progress
+continually, including an estimate of completion time.
.SH EXIT STATUS
\fBbtrfs\fR returns a zero exist status if it succeeds. Non zero is returned in
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 <hugo@carfax.org.uk> --- btrfs_cmds.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++---- ioctl.h | 2 +- man/btrfs.8.in | 7 ++-- 3 files changed, 99 insertions(+), 12 deletions(-)