gfs2-utils: master - mkfs.gfs2: Add a progress indicator to mkfs.gfs2

Paul Evans pevans at fedoraproject.org
Mon Oct 19 13:06:42 UTC 2015


Gitweb:        http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=cbb17b94ce6aa3813f0544acd8e1f3c6f8d4f038
Commit:        cbb17b94ce6aa3813f0544acd8e1f3c6f8d4f038
Parent:        cf30857d5cfc236f382b578d8820e1e0f72945b7
Author:        Paul Evans <pevans at redhat.com>
AuthorDate:    Thu Oct 15 17:27:27 2015 +0100
Committer:     Paul Evans <pevans at redhat.com>
CommitterDate: Thu Oct 15 17:27:27 2015 +0100

mkfs.gfs2: Add a progress indicator to mkfs.gfs2

Add a progress indicator to mkfs based on an adapted version of
the simple progress indicator used in e2fsprogs.

Update mkfs.gfs2 to make use of this progress bar allowing progress
to be reported during the creation of journals and resource groups
during filesystem creation.

Signed-off-by: Paul Evans <pevans at redhat.com>
---
 gfs2/mkfs/Makefile.am |    6 +++-
 gfs2/mkfs/main_mkfs.c |   37 +++++++++++++++++--
 gfs2/mkfs/progress.c  |   95 +++++++++++++++++++++++++++++++++++++++++++++++++
 gfs2/mkfs/progress.h  |   14 +++++++
 4 files changed, 148 insertions(+), 4 deletions(-)

diff --git a/gfs2/mkfs/Makefile.am b/gfs2/mkfs/Makefile.am
index 6c49d3b..074c4c1 100644
--- a/gfs2/mkfs/Makefile.am
+++ b/gfs2/mkfs/Makefile.am
@@ -16,7 +16,11 @@ noinst_HEADERS = \
 	gfs2_mkfs.h \
 	metafs.h
 
-mkfs_gfs2_SOURCES = main_mkfs.c
+mkfs_gfs2_SOURCES = \
+	main_mkfs.c \
+	progress.c \
+	progress.h
+
 mkfs_gfs2_CPPFLAGS = $(COMMON_CPPFLAGS)
 mkfs_gfs2_CFLAGS = $(blkid_CFLAGS)
 mkfs_gfs2_LDFLAGS = $(blkid_LIBS)
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index d3d8edf..ab525d1 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -28,6 +28,7 @@
 #include <linux/types.h>
 #include "libgfs2.h"
 #include "gfs2_mkfs.h"
+#include "progress.h"
 
 static void print_usage(const char *prog_name)
 {
@@ -653,10 +654,14 @@ static int add_rgrp(lgfs2_rgrps_t rgs, uint64_t *addr, uint32_t len, lgfs2_rgrp_
 
 static int place_journals(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts *opts, uint64_t *rgaddr)
 {
+	struct gfs2_progress_bar progress;
 	uint64_t jfsize = lgfs2_space_for_data(sdp, sdp->bsize, opts->jsize << 20);
 	uint32_t rgsize = lgfs2_rgsize_for_data(jfsize, sdp->bsize);
 	unsigned j;
 
+	/* Initialise a progress bar for resource group creation. */
+	gfs2_progress_init(&progress, opts->journals, _("Adding journals: "), opts->quiet);
+
 	/* We'll build the jindex later so remember where we put the journals */
 	mkfs_journals = calloc(opts->journals, sizeof(*mkfs_journals));
 	if (mkfs_journals == NULL)
@@ -668,6 +673,9 @@ static int place_journals(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_o
 		lgfs2_rgrp_t rg;
 		struct gfs2_inode in = {0};
 
+		/* Update progress bar for journal creation. */
+		gfs2_progress_update(&progress, (j + 1));
+
 		if (opts->debug)
 			printf(_("Placing resource group for journal%u\n"), j);
 
@@ -715,21 +723,27 @@ static int place_journals(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_o
 		}
 		mkfs_journals[j] = in.i_di.di_num;
 	}
+	gfs2_progress_close(&progress, _("Done\n"));
 
 	return 0;
 }
 
 static int place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts *opts)
 {
+	struct gfs2_progress_bar progress;
 	uint64_t rgaddr = lgfs2_rgrp_align_addr(rgs, sdp->sb_addr + 1);
 	uint32_t rgblks = ((opts->rgsize << 20) / sdp->bsize);
+	uint32_t rgnum;
 	int result;
 
 	result = place_journals(sdp, rgs, opts, &rgaddr);
 	if (result != 0)
 		return result;
 
-	lgfs2_rgrps_plan(rgs, sdp->device.length - rgaddr, rgblks);
+	rgnum = lgfs2_rgrps_plan(rgs, sdp->device.length - rgaddr, rgblks);
+
+	/* Initialise a progress bar for resource group creation (after journal creation). */
+	gfs2_progress_init(&progress, (rgnum + opts->journals), _("Building resource groups: "), opts->quiet);
 
 	while (1) {
 		lgfs2_rgrp_t rg;
@@ -744,7 +758,12 @@ static int place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts
 			fprintf(stderr, _("Failed to build resource groups\n"));
 			return result;
 		}
+
+		/* Update progress bar with resource group address. */
+		gfs2_progress_update(&progress, (sdp->rgrps));
 	}
+	gfs2_progress_close(&progress, _("Done\n"));
+
 	return 0;
 }
 
@@ -949,11 +968,17 @@ int main(int argc, char *argv[])
 		fprintf(stderr, _("Error building '%s': %s\n"), "rindex", strerror(errno));
 		exit(EXIT_FAILURE);
 	}
+	if (!opts.quiet) {
+		printf("%s", _("Creating quota file: "));
+		fflush(stdout);
+	}
 	error = build_quota(&sbd);
 	if (error) {
 		fprintf(stderr, _("Error building '%s': %s\n"), "quota", strerror(errno));
 		exit(EXIT_FAILURE);
 	}
+	if (!opts.quiet)
+		printf("%s", _("Done\n"));
 
 	build_root(&sbd);
 	sb.sb_root_dir = sbd.md.rooti->i_di.di_num;
@@ -973,6 +998,11 @@ int main(int argc, char *argv[])
 
 	lgfs2_rgrps_free(&rgs);
 
+	if (!opts.quiet) {
+		printf("%s", _("Writing superblock and syncing: "));
+		fflush(stdout);
+	}
+
 	error = lgfs2_sb_write(&sb, opts.dev.fd, sbd.bsize);
 	if (error) {
 		perror(_("Failed to write superblock\n"));
@@ -991,8 +1021,9 @@ int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
-	if (!opts.quiet)
+	if (!opts.quiet) {
+		printf("%s", _("Done\n"));
 		print_results(&sb, &opts, sbd.rgrps, sbd.fssize);
-
+	}
 	return 0;
 }
diff --git a/gfs2/mkfs/progress.c b/gfs2/mkfs/progress.c
new file mode 100644
index 0000000..538ee71
--- /dev/null
+++ b/gfs2/mkfs/progress.c
@@ -0,0 +1,95 @@
+/**
+ * Progress bar to give updates for operations in gfs2-utils.
+ * Adapted from the simple progress bar in e2fsprogs progress.c
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "progress.h"
+
+static char spaces[44], backspaces[44];
+static time_t last_update;
+
+static int number_of_digits(int value)
+{
+	int digits = 0;
+
+	do {
+		value /= 10;
+		digits++;
+	} while (value != 0);
+
+	return digits;
+}
+
+void gfs2_progress_init(struct gfs2_progress_bar *progress, uint64_t max, const char *message, int quiet)
+{
+	/**
+	 * NOTE:
+	 *
+	 * Default operation is to output the progress indication
+	 * in full. Although we will honor the quiet flag in the
+	 * application, if this is set we skip progress bar any
+	 * update operations and output.
+	 *
+	 */
+
+	memset(spaces, ' ', sizeof(spaces)-1);
+	spaces[sizeof(spaces)-1] = 0;
+
+	memset(backspaces, '\b', sizeof(backspaces)-1);
+	backspaces[sizeof(backspaces)-1] = 0;
+
+	memset(progress, 0, sizeof(*progress));
+
+	if (quiet) {
+		progress->skip_progress++;
+		return;
+	}
+
+	progress->max = max;
+	progress->max_digits = number_of_digits(max);
+
+	if (message) {
+		fputs(message, stdout);
+		fflush(stdout);
+	}
+	last_update = 0;
+}
+
+extern void gfs2_progress_update(struct gfs2_progress_bar *progress, uint64_t value)
+{
+	time_t current_time;
+
+	if (progress->skip_progress || (!isatty(STDOUT_FILENO)))
+		return;
+
+	current_time = time(0);
+	if (current_time == last_update)
+		return;
+	last_update = current_time;
+
+	printf("[%*"PRIu64"/%*"PRIu64"]", progress->max_digits, value,
+		progress->max_digits, progress->max);
+	fflush(stdout);
+	fprintf(stdout, "%.*s", (2 * progress->max_digits) + 3, backspaces);
+}
+
+extern void gfs2_progress_close(struct gfs2_progress_bar *progress, const char *message)
+{
+	if (progress->skip_progress)
+		return;
+
+	if (isatty(STDOUT_FILENO)) {
+		fprintf(stdout, "%.*s", (2 * progress->max_digits) + 3, spaces);
+		fprintf(stdout, "%.*s", (2 * progress->max_digits) + 3, backspaces);
+	}
+
+	if (message)
+		fputs(message, stdout);
+}
diff --git a/gfs2/mkfs/progress.h b/gfs2/mkfs/progress.h
new file mode 100644
index 0000000..545bf58
--- /dev/null
+++ b/gfs2/mkfs/progress.h
@@ -0,0 +1,14 @@
+#ifndef PROGRESS_H
+#define PROGRESS_H
+
+struct gfs2_progress_bar {
+	uint64_t max;
+	int max_digits;
+	int skip_progress;
+};
+
+extern void gfs2_progress_init(struct gfs2_progress_bar *progress, uint64_t max, const char *message, int quiet);
+extern void gfs2_progress_update(struct gfs2_progress_bar *progress, uint64_t value);
+extern void gfs2_progress_close(struct gfs2_progress_bar *progress, const char *message);
+
+#endif /* PROGRESS_H */


More information about the cluster-commits mailing list