drbd: show progress bar and ETA for online-verify
authorLars Ellenberg <lars.ellenberg@linbit.com>
Fri, 5 Nov 2010 08:52:46 +0000 (09:52 +0100)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Thu, 10 Mar 2011 10:18:58 +0000 (11:18 +0100)
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_proc.c

index 6cba131011d577507b7805b804bf8e71109f7d62..7131bf2af6ae704ed9e4f1e0fa26b084c820d36a 100644 (file)
@@ -2157,7 +2157,10 @@ static inline void drbd_get_syncer_progress(struct drbd_conf *mdev,
         * units of BM_BLOCK_SIZE.
         * for the percentage, we don't care. */
 
-       *bits_left = drbd_bm_total_weight(mdev) - mdev->rs_failed;
+       if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T)
+               *bits_left = mdev->ov_left;
+       else
+               *bits_left = drbd_bm_total_weight(mdev) - mdev->rs_failed;
        /* >> 10 to prevent overflow,
         * +1 to prevent division by zero */
        if (*bits_left > mdev->rs_total) {
index 0b20aa8370229c0e90fe884e31efdeafb0c63054..0ec6f4b6a4a80b490d286f11cc20a29af9950ec8 100644 (file)
@@ -45,6 +45,19 @@ const struct file_operations drbd_proc_fops = {
        .release        = single_release,
 };
 
+void seq_printf_with_thousands_grouping(struct seq_file *seq, long v)
+{
+       /* v is in kB/sec. We don't expect TiByte/sec yet. */
+       if (unlikely(v >= 1000000)) {
+               /* cool: > GiByte/s */
+               seq_printf(seq, "%ld,", v / 1000000);
+               v /= 1000000;
+               seq_printf(seq, "%03ld,%03ld", v/1000, v % 1000);
+       } else if (likely(v >= 1000))
+               seq_printf(seq, "%ld,%03ld", v/1000, v % 1000);
+       else
+               seq_printf(seq, "%ld", v);
+}
 
 /*lge
  * progress bars shamelessly adapted from driver/md/md.c
@@ -94,6 +107,7 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq)
        /* Rolling marks. last_mark+1 may just now be modified.  last_mark+2 is
         * at least (DRBD_SYNC_MARKS-2)*DRBD_SYNC_MARK_STEP old, and has at
         * least DRBD_SYNC_MARK_STEP time before it will be modified. */
+       /* ------------------------ ~18s average ------------------------ */
        i = (mdev->rs_last_mark + 2) % DRBD_SYNC_MARKS;
        dt = (jiffies - mdev->rs_mark_time[i]) / HZ;
        if (dt > (DRBD_SYNC_MARK_STEP * DRBD_SYNC_MARKS))
@@ -107,14 +121,29 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq)
        seq_printf(seq, "finish: %lu:%02lu:%02lu",
                rt / 3600, (rt % 3600) / 60, rt % 60);
 
-       /* current speed average over (SYNC_MARKS * SYNC_MARK_STEP) jiffies */
        dbdt = Bit2KB(db/dt);
-       if (dbdt > 1000)
-               seq_printf(seq, " speed: %ld,%03ld",
-                       dbdt/1000, dbdt % 1000);
-       else
-               seq_printf(seq, " speed: %ld", dbdt);
+       seq_printf(seq, " speed: ");
+       seq_printf_with_thousands_grouping(seq, dbdt);
+       seq_printf(seq, " (");
+       /* ------------------------- ~3s average ------------------------ */
+       if (proc_details >= 1) {
+               /* this is what drbd_rs_should_slow_down() uses */
+               i = (mdev->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
+               dt = (jiffies - mdev->rs_mark_time[i]) / HZ;
+               if (dt > (DRBD_SYNC_MARK_STEP * DRBD_SYNC_MARKS))
+                       stalled = 1;
+
+               if (!dt)
+                       dt++;
+               db = mdev->rs_mark_left[i] - rs_left;
+               rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */
+
+               dbdt = Bit2KB(db/dt);
+               seq_printf_with_thousands_grouping(seq, dbdt);
+               seq_printf(seq, " -- ");
+       }
 
+       /* --------------------- long term average ---------------------- */
        /* mean speed since syncer started
         * we do account for PausedSync periods */
        dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ;
@@ -122,11 +151,8 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq)
                dt = 1;
        db = mdev->rs_total - rs_left;
        dbdt = Bit2KB(db/dt);
-       if (dbdt > 1000)
-               seq_printf(seq, " (%ld,%03ld)",
-                       dbdt/1000, dbdt % 1000);
-       else
-               seq_printf(seq, " (%ld)", dbdt);
+       seq_printf_with_thousands_grouping(seq, dbdt);
+       seq_printf(seq, ")");
 
        if (mdev->state.conn == C_SYNC_TARGET) {
                if (mdev->c_sync_rate > 1000)
@@ -236,7 +262,9 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
                                   Bit2KB(drbd_bm_total_weight(mdev)));
                }
                if (mdev->state.conn == C_SYNC_SOURCE ||
-                   mdev->state.conn == C_SYNC_TARGET)
+                   mdev->state.conn == C_SYNC_TARGET ||
+                   mdev->state.conn == C_VERIFY_S ||
+                   mdev->state.conn == C_VERIFY_T)
                        drbd_syncer_progress(mdev, seq);
 
                if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T) {