cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
* [Cluster-devel] [PATCH v2] mkfs.gfs2: Add a progress indicator to mkfs.gfs2
@ 2015-10-15 16:43 Paul Evans
  2015-10-16 14:02 ` Andrew Price
  0 siblings, 1 reply; 2+ messages in thread
From: Paul Evans @ 2015-10-15 16:43 UTC (permalink / raw)
  To: cluster-devel.redhat.com

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@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(-)
 create mode 100644 gfs2/mkfs/progress.c
 create mode 100644 gfs2/mkfs/progress.h

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 */
-- 
1.9.3



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [Cluster-devel] [PATCH v2] mkfs.gfs2: Add a progress indicator to mkfs.gfs2
  2015-10-15 16:43 [Cluster-devel] [PATCH v2] mkfs.gfs2: Add a progress indicator to mkfs.gfs2 Paul Evans
@ 2015-10-16 14:02 ` Andrew Price
  0 siblings, 0 replies; 2+ messages in thread
From: Andrew Price @ 2015-10-16 14:02 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Hi Paul,

On 15/10/15 17:43, Paul Evans wrote:
> 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.

Thanks for making those changes. Both patches look good to me. I expect 
they'll get more feedback once they've been pushed as UI changes don't 
tend to attract much review until they're in everyone's faces, but 
that's all the more reason to get them pushed now :)

Thanks,
Andy

> Signed-off-by: Paul Evans <pevans@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(-)
>   create mode 100644 gfs2/mkfs/progress.c
>   create mode 100644 gfs2/mkfs/progress.h
>
> 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 */
>



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-10-16 14:02 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-15 16:43 [Cluster-devel] [PATCH v2] mkfs.gfs2: Add a progress indicator to mkfs.gfs2 Paul Evans
2015-10-16 14:02 ` Andrew Price

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).