Kexec Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Pingfan Liu <piliu@redhat.com>
To: kexec@lists.infradead.org
Cc: Pratyush Anand <panand@redhat.com>,
	Atsushi Kumagai <ats-kumagai@wm.jp.nec.com>
Subject: [makedumpfile PATCH v3 2/2] print_info: show the remaining time of dump progress
Date: Wed, 14 Jun 2017 17:41:32 +0800	[thread overview]
Message-ID: <1497433292-6015-2-git-send-email-piliu@redhat.com> (raw)
In-Reply-To: <1497433292-6015-1-git-send-email-piliu@redhat.com>

If the dump progress is slow, it is better to show  an estimate of
remaining time of the progress to the user. The estimator simply uses
the average speed to work.
Before this patch, the bar looks like:
  Copying data                                      : [  1.8 %] /
After this patch:
  Copying data                                      : [  1.8 %] /          eta: 39s

Signed-off-by: Pingfan Liu <piliu@redhat.com>
---
v2 -> v3: improve the commit log

 makedumpfile.c | 46 +++++++++++++++++++++++-----------------------
 print_info.c   | 41 +++++++++++++++++++++++++++++++++++------
 print_info.h   |  3 ++-
 3 files changed, 60 insertions(+), 30 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 301772a..35a36ce 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -5175,7 +5175,7 @@ _exclude_free_page(struct cycle *cycle)
 
 	for (num_nodes = 1; num_nodes <= vt.numnodes; num_nodes++) {
 
-		print_progress(PROGRESS_FREE_PAGES, num_nodes - 1, vt.numnodes);
+		print_progress(PROGRESS_FREE_PAGES, num_nodes - 1, vt.numnodes, NULL);
 
 		node_zones = pgdat + OFFSET(pglist_data.node_zones);
 
@@ -5188,7 +5188,7 @@ _exclude_free_page(struct cycle *cycle)
 		for (i = 0; i < nr_zones; i++) {
 
 			print_progress(PROGRESS_FREE_PAGES, i + nr_zones * (num_nodes - 1),
-					nr_zones * vt.numnodes);
+					nr_zones * vt.numnodes, NULL);
 
 			zone = node_zones + (i * SIZE(zone));
 			if (!readmem(VADDR, zone + OFFSET(zone.spanned_pages),
@@ -5216,7 +5216,7 @@ _exclude_free_page(struct cycle *cycle)
 	/*
 	 * print [100 %]
 	 */
-	print_progress(PROGRESS_FREE_PAGES, vt.numnodes, vt.numnodes);
+	print_progress(PROGRESS_FREE_PAGES, vt.numnodes, vt.numnodes, NULL);
 	print_execution_time(PROGRESS_FREE_PAGES, &tv_start);
 
 	return TRUE;
@@ -5403,7 +5403,7 @@ create_1st_bitmap_file(void)
 	for (i = 0; get_pt_load(i, &phys_start, &phys_end, NULL, NULL); i++) {
 
 		if (!info->flag_mem_usage)
-			print_progress(PROGRESS_HOLES, i, num_pt_loads);
+			print_progress(PROGRESS_HOLES, i, num_pt_loads, NULL);
 
 		pfn_start = paddr_to_pfn(phys_start);
 		pfn_end   = paddr_to_pfn(phys_end);
@@ -5422,7 +5422,7 @@ create_1st_bitmap_file(void)
 	 * print 100 %
 	 */
 	if (!info->flag_mem_usage) {
-		print_progress(PROGRESS_HOLES, info->max_mapnr, info->max_mapnr);
+		print_progress(PROGRESS_HOLES, info->max_mapnr, info->max_mapnr, NULL);
 		print_execution_time(PROGRESS_HOLES, &tv_start);
 	}
 
@@ -5548,7 +5548,7 @@ create_bitmap_from_memhole(struct cycle *cycle, struct dump_bitmap *bitmap, int
 		pfn_start = MAX(paddr_to_pfn(phys_start), cycle->start_pfn);
 		pfn_end = MIN(paddr_to_pfn(phys_end), cycle->end_pfn);
 
-		print_progress(PROGRESS_HOLES, i, num_pt_loads);
+		print_progress(PROGRESS_HOLES, i, num_pt_loads, NULL);
 
 		if (pfn_start >= pfn_end)
 			continue;
@@ -5587,7 +5587,7 @@ create_bitmap_from_memhole(struct cycle *cycle, struct dump_bitmap *bitmap, int
 	/*
 	 * print 100 %
 	 */
-	print_progress(PROGRESS_HOLES, info->max_mapnr, info->max_mapnr);
+	print_progress(PROGRESS_HOLES, info->max_mapnr, info->max_mapnr, NULL);
 	print_execution_time(PROGRESS_HOLES, &tv_start);
 
 	return TRUE;
@@ -5842,7 +5842,7 @@ exclude_unnecessary_pages(struct cycle *cycle)
 	for (mm = 0; mm < info->num_mem_map; mm++) {
 
 		if (!info->flag_mem_usage)
-			print_progress(PROGRESS_UNN_PAGES, mm, info->num_mem_map);
+			print_progress(PROGRESS_UNN_PAGES, mm, info->num_mem_map, NULL);
 
 		mmd = &info->mem_map_data[mm];
 
@@ -5860,7 +5860,7 @@ exclude_unnecessary_pages(struct cycle *cycle)
 	 * print [100 %]
 	 */
 	if (!info->flag_mem_usage) {
-		print_progress(PROGRESS_UNN_PAGES, info->num_mem_map, info->num_mem_map);
+		print_progress(PROGRESS_UNN_PAGES, info->num_mem_map, info->num_mem_map, NULL);
 		print_execution_time(PROGRESS_UNN_PAGES, &tv_start);
 	}
 
@@ -7334,7 +7334,7 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page)
 				}
 
 				if ((num_dumped % per) == 0)
-					print_progress(PROGRESS_COPY, num_dumped, num_dumpable);
+					print_progress(PROGRESS_COPY, num_dumped, num_dumpable, &tv_start);
 
 				num_dumped++;
 
@@ -7453,7 +7453,7 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page)
 	/*
 	 * print [100 %]
 	 */
-	print_progress(PROGRESS_COPY, num_dumpable, num_dumpable);
+	print_progress(PROGRESS_COPY, num_dumpable, num_dumpable, &tv_start);
 	print_execution_time(PROGRESS_COPY, &tv_start);
 	PROGRESS_MSG("\n");
 
@@ -7931,7 +7931,7 @@ write_kdump_pages_parallel_cyclic(struct cache_data *cd_header,
 		}
 
 		if ((num_dumped % per) == 0)
-			print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable);
+			print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start);
 
 		num_dumped++;
 
@@ -7967,7 +7967,7 @@ finish:
 	/*
 	 * print [100 %]
 	 */
-	print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable);
+	print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start);
 	print_execution_time(PROGRESS_COPY, &tv_start);
 	PROGRESS_MSG("\n");
 
@@ -8084,7 +8084,7 @@ write_kdump_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_pag
 	for (pfn = start_pfn; pfn < end_pfn; pfn++) {
 
 		if ((num_dumped % per) == 0)
-			print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable);
+			print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start);
 
 		/*
 		 * Check the excluded page.
@@ -8164,7 +8164,7 @@ out:
 		free(wrkmem);
 #endif
 
-	print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable);
+	print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start);
 	print_execution_time(PROGRESS_COPY, &tv_start);
 
 	return ret;
@@ -8622,7 +8622,7 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d
 	/*
 	 * print [100 %]
 	 */
-	print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable);
+	print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start);
 	print_execution_time(PROGRESS_COPY, &tv_start);
 	PROGRESS_MSG("\n");
 
@@ -9216,7 +9216,7 @@ exclude_xen3_user_domain(void)
 	 */
 	for (i = 0; get_pt_load(i, &phys_start, &phys_end, NULL, NULL); i++) {
 
-		print_progress(PROGRESS_XEN_DOMAIN, i, num_pt_loads);
+		print_progress(PROGRESS_XEN_DOMAIN, i, num_pt_loads, NULL);
 
 		pfn     = paddr_to_pfn(phys_start);
 		pfn_end = paddr_to_pfn(phys_end);
@@ -9224,7 +9224,7 @@ exclude_xen3_user_domain(void)
 
 		for (j = 0; pfn < pfn_end; pfn++, j++) {
 			print_progress(PROGRESS_XEN_DOMAIN, j + (size * i),
-					size * num_pt_loads);
+					size * num_pt_loads, NULL);
 
 			if (!allocated_in_map(pfn)) {
 				clear_bit_on_2nd_bitmap(pfn, NULL);
@@ -9280,7 +9280,7 @@ exclude_xen4_user_domain(void)
 	 */
 	for (i = 0; get_pt_load(i, &phys_start, &phys_end, NULL, NULL); i++) {
 
-		print_progress(PROGRESS_XEN_DOMAIN, i, num_pt_loads);
+		print_progress(PROGRESS_XEN_DOMAIN, i, num_pt_loads, NULL);
 
 		pfn     = paddr_to_pfn(phys_start);
 		pfn_end = paddr_to_pfn(phys_end);
@@ -9288,7 +9288,7 @@ exclude_xen4_user_domain(void)
 
 		for (j = 0; pfn < pfn_end; pfn++, j++) {
 			print_progress(PROGRESS_XEN_DOMAIN, j + (size * i),
-					size * num_pt_loads);
+					size * num_pt_loads, NULL);
 
 			page_info_addr = info->frame_table_vaddr + pfn * SIZE(page_info);
 			if (!readmem(VADDR_XEN,
@@ -9356,7 +9356,7 @@ exclude_xen_user_domain(void)
 	/*
 	 * print [100 %]
 	 */
-	print_progress(PROGRESS_XEN_DOMAIN, 1, 1);
+	print_progress(PROGRESS_XEN_DOMAIN, 1, 1, NULL);
 	print_execution_time(PROGRESS_XEN_DOMAIN, &tv_start);
 
 	return ret;
@@ -10342,7 +10342,7 @@ reassemble_kdump_pages(void)
 
 			num_dumped++;
 
-			print_progress(PROGRESS_COPY, num_dumped, num_dumpable);
+			print_progress(PROGRESS_COPY, num_dumped, num_dumpable, &tv_start);
 
 			if (lseek(fd, offset_ph_org, SEEK_SET) < 0) {
 				ERRMSG("Can't seek a file(%s). %s\n",
@@ -10439,7 +10439,7 @@ reassemble_kdump_pages(void)
 						    size_eraseinfo))
 			goto out;
 	}
-	print_progress(PROGRESS_COPY, num_dumpable, num_dumpable);
+	print_progress(PROGRESS_COPY, num_dumpable, num_dumpable, &tv_start);
 	print_execution_time(PROGRESS_COPY, &tv_start);
 
 	ret = TRUE;
diff --git a/print_info.c b/print_info.c
index 79dfe5e..e0e6a27 100644
--- a/print_info.c
+++ b/print_info.c
@@ -15,8 +15,9 @@
  */
 #include "print_info.h"
 #include <time.h>
+#include <string.h>
 
-#define PROGRESS_MAXLEN		"35"
+#define PROGRESS_MAXLEN		"50"
 
 int message_level;
 int flag_strerr_message;
@@ -350,14 +351,36 @@ static void calc_delta(struct timeval *tv_start, struct timeval *delta)
 	}
 }
 
+/* produce less than 12 bytes on msg */
+static int eta_to_human_short (int secs, char* msg)
+{
+	strcpy(msg, "eta: ");
+	msg += strlen("eta: ");
+	if (secs < 100)
+		sprintf(msg, "%ds", secs);
+	else if (secs < 100 * 60)
+		sprintf(msg, "%dm%ds", secs / 60, secs % 60);
+	else if (secs < 48 * 3600)
+		sprintf(msg, "%dh%dm", secs / 3600, (secs / 60) % 60);
+	else if (secs < 100 * 86400)
+		sprintf(msg, "%dd%dh", secs / 86400, (secs / 3600) % 24);
+	else
+		sprintf(msg, ">2day");
+	return 0;
+}
+
+
 void
-print_progress(const char *msg, unsigned long current, unsigned long end)
+print_progress(const char *msg, unsigned long current, unsigned long end, struct timeval *start)
 {
 	float progress;
 	time_t tm;
 	static time_t last_time = 0;
 	static unsigned int lapse = 0;
 	static const char *spinner = "/|\\-";
+	struct timeval delta;
+	double eta;
+	char eta_msg[16] = " ";
 
 	if (current < end) {
 		tm = time(NULL);
@@ -368,13 +391,19 @@ print_progress(const char *msg, unsigned long current, unsigned long end)
 	} else
 		progress = 100;
 
+	if (start != NULL) {
+		calc_delta(start, &delta);
+		eta = delta.tv_sec + delta.tv_usec / 1e6;
+		eta = (100 - progress) * eta / progress;
+		eta_to_human_short(eta, eta_msg);
+	}
 	if (flag_ignore_r_char) {
-		PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%5.1f %%] %c\n",
-			     msg, progress, spinner[lapse % 4]);
+		PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%5.1f %%] %c  %16s\n",
+			     msg, progress, spinner[lapse % 4], eta_msg);
 	} else {
 		PROGRESS_MSG("\r");
-		PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%5.1f %%] %c",
-			     msg, progress, spinner[lapse % 4]);
+		PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%5.1f %%] %c  %16s",
+			     msg, progress, spinner[lapse % 4], eta_msg);
 	}
 	lapse++;
 }
diff --git a/print_info.h b/print_info.h
index 01e3706..1ce3593 100644
--- a/print_info.h
+++ b/print_info.h
@@ -25,7 +25,8 @@ extern int flag_ignore_r_char;
 
 void show_version(void);
 void print_usage(void);
-void print_progress(const char *msg, unsigned long current, unsigned long end);
+void print_progress(const char *msg, unsigned long current, unsigned long end, struct timeval *start);
+
 void print_execution_time(char *step_name, struct timeval *tv_start);
 
 /*
-- 
2.7.4


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

  reply	other threads:[~2017-06-14  9:41 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-14  9:41 [makedumpfile PATCHv3 1/2] fold the calc of time delta into a func Pingfan Liu
2017-06-14  9:41 ` Pingfan Liu [this message]
2017-06-15  2:37   ` [makedumpfile PATCH v3 2/2] print_info: show the remaining time of dump progress Pratyush Anand
2017-06-15  2:58     ` Atsushi Kumagai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1497433292-6015-2-git-send-email-piliu@redhat.com \
    --to=piliu@redhat.com \
    --cc=ats-kumagai@wm.jp.nec.com \
    --cc=kexec@lists.infradead.org \
    --cc=panand@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox