diff --git a/libmultipath/foreign.c b/libmultipath/foreign.c
index c69c5c3..e80eb3e 100644
--- a/libmultipath/foreign.c
+++ b/libmultipath/foreign.c
@@ -30,10 +30,10 @@
 #include "vector.h"
 #include "debug.h"
 #include "util.h"
-#include "foreign.h"
 #include "structs.h"
 #include "structs_vec.h"
 #include "print.h"
+#include "foreign.h"
 #include "strbuf.h"
 
 static vector foreigns;
@@ -437,7 +437,7 @@ void check_foreign(void)
 }
 
 /* Call this after get_path_layout */
-void foreign_path_layout(void)
+void foreign_path_layout(fieldwidth_t *width)
 {
 	struct foreign *fgn;
 	int i;
@@ -457,7 +457,7 @@ void foreign_path_layout(void)
 
 		vec = fgn->get_paths(fgn->context);
 		if (vec != NULL) {
-			_get_path_layout(vec, LAYOUT_RESET_NOT);
+			_get_path_layout(vec, LAYOUT_RESET_NOT, width);
 		}
 		fgn->release_paths(fgn->context, vec);
 
@@ -468,7 +468,7 @@ void foreign_path_layout(void)
 }
 
 /* Call this after get_multipath_layout */
-void foreign_multipath_layout(void)
+void foreign_multipath_layout(fieldwidth_t *width)
 {
 	struct foreign *fgn;
 	int i;
@@ -488,7 +488,7 @@ void foreign_multipath_layout(void)
 
 		vec = fgn->get_multipaths(fgn->context);
 		if (vec != NULL) {
-			_get_multipath_layout(vec, LAYOUT_RESET_NOT);
+			_get_multipath_layout(vec, LAYOUT_RESET_NOT, width);
 		}
 		fgn->release_multipaths(fgn->context, vec);
 
@@ -498,7 +498,8 @@ void foreign_multipath_layout(void)
 	pthread_cleanup_pop(1);
 }
 
-static int __snprint_foreign_topology(struct strbuf *buf, int verbosity)
+static int __snprint_foreign_topology(struct strbuf *buf, int verbosity,
+				      const fieldwidth_t *width)
 {
 	struct foreign *fgn;
 	int i;
@@ -516,7 +517,7 @@ static int __snprint_foreign_topology(struct strbuf *buf, int verbosity)
 		if (vec != NULL) {
 			vector_foreach_slot(vec, gm, j) {
 				if (_snprint_multipath_topology(
-					    gm, buf, verbosity) < 0)
+					    gm, buf, verbosity, width) < 0)
 					break;
 			}
 		}
@@ -527,7 +528,8 @@ static int __snprint_foreign_topology(struct strbuf *buf, int verbosity)
 	return get_strbuf_len(buf) - initial_len;
 }
 
-int snprint_foreign_topology(struct strbuf *buf, int verbosity)
+int snprint_foreign_topology(struct strbuf *buf, int verbosity,
+			     const fieldwidth_t *width)
 {
 	int rc;
 
@@ -537,7 +539,7 @@ int snprint_foreign_topology(struct strbuf *buf, int verbosity)
 		return 0;
 	}
 	pthread_cleanup_push(unlock_foreigns, NULL);
-	rc = __snprint_foreign_topology(buf, verbosity);
+	rc = __snprint_foreign_topology(buf, verbosity, width);
 	pthread_cleanup_pop(1);
 	return rc;
 }
@@ -545,12 +547,35 @@ int snprint_foreign_topology(struct strbuf *buf, int verbosity)
 void print_foreign_topology(int verbosity)
 {
 	STRBUF_ON_STACK(buf);
+	struct foreign *fgn;
+	int i;
+	fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL;
 
-	snprint_foreign_topology(&buf, verbosity);
+	if ((width = alloc_path_layout()) == NULL)
+		return;
+	rdlock_foreigns();
+	if (foreigns == NULL) {
+		unlock_foreigns(NULL);
+		return;
+	}
+	pthread_cleanup_push(unlock_foreigns, NULL);
+	vector_foreach_slot(foreigns, fgn, i) {
+		const struct _vector *vec;
+
+		fgn->lock(fgn->context);
+		pthread_cleanup_push(fgn->unlock, fgn->context);
+		vec = fgn->get_paths(fgn->context);
+		_get_multipath_layout(vec, LAYOUT_RESET_NOT, width);
+		fgn->release_paths(fgn->context, vec);
+		pthread_cleanup_pop(1);
+	}
+	__snprint_foreign_topology(&buf, verbosity, width);
+	pthread_cleanup_pop(1);
 	printf("%s", get_strbuf_str(&buf));
 }
 
-int snprint_foreign_paths(struct strbuf *buf, const char *style, int pretty)
+int snprint_foreign_paths(struct strbuf *buf, const char *style,
+			  const fieldwidth_t *width)
 {
 	struct foreign *fgn;
 	int i;
@@ -574,7 +599,7 @@ int snprint_foreign_paths(struct strbuf *buf, const char *style, int pretty)
 		vec = fgn->get_paths(fgn->context);
 		if (vec != NULL) {
 			vector_foreach_slot(vec, gp, j) {
-				ret = _snprint_path(gp, buf, style, pretty);
+				ret = _snprint_path(gp, buf, style, width);
 				if (ret < 0)
 					break;
 			}
@@ -589,8 +614,8 @@ int snprint_foreign_paths(struct strbuf *buf, const char *style, int pretty)
 	return get_strbuf_len(buf) - initial_len;
 }
 
-int snprint_foreign_multipaths(struct strbuf *buf,
-			       const char *style, int pretty)
+int snprint_foreign_multipaths(struct strbuf *buf, const char *style,
+			       const fieldwidth_t *width)
 {
 	struct foreign *fgn;
 	int i;
@@ -615,7 +640,7 @@ int snprint_foreign_multipaths(struct strbuf *buf,
 		if (vec != NULL) {
 			vector_foreach_slot(vec, gm, j) {
 				ret = _snprint_multipath(gm, buf,
-							 style, pretty);
+							 style, width);
 				if (ret < 0)
 					break;
 			}
diff --git a/libmultipath/foreign.h b/libmultipath/foreign.h
index 77fc485..cf8f570 100644
--- a/libmultipath/foreign.h
+++ b/libmultipath/foreign.h
@@ -18,7 +18,7 @@
 #define _FOREIGN_H
 #include <stdbool.h>
 #include <libudev.h>
-#define LIBMP_FOREIGN_API ((1 << 8) | 1)
+#define LIBMP_FOREIGN_API ((1 << 8) | 2)
 
 struct strbuf;
 struct context;
@@ -252,15 +252,17 @@ void check_foreign(void);
  * foreign_path_layout()
  * call this before printing paths, after get_path_layout(), to determine
  * output field width.
+ * @param width: an array allocated by alloc_path_layout()
  */
-void foreign_path_layout(void);
+void foreign_path_layout(fieldwidth_t *width);
 
 /**
  * foreign_multipath_layout()
  * call this before printing maps, after get_multipath_layout(), to determine
  * output field width.
+ * @param width: an array allocated by alloc_multipath_layout()
  */
-void foreign_multipath_layout(void);
+void foreign_multipath_layout(fieldwidth_t *width);
 
 /**
  * snprint_foreign_topology(buf, len, verbosity);
@@ -268,9 +270,11 @@ void foreign_multipath_layout(void);
  * '\0' - terminated.
  * @param buf: output buffer
  * @param verbosity: verbosity level
+ * @param width: an array of field widths, initialized by _get_path_layout()
  * @returns: number of printed characters excluding trailing '\0'.
  */
-int snprint_foreign_topology(struct strbuf *buf, int verbosity);
+int snprint_foreign_topology(struct strbuf *buf, int verbosity,
+			     const fieldwidth_t *width);
 
 /**
  * snprint_foreign_paths(buf, len, style, pad);
@@ -278,10 +282,11 @@ int snprint_foreign_topology(struct strbuf *buf, int verbosity);
  * '\0' - terminated.
  * @param buf: output buffer
  * @param style: format string
- * @param pad: whether to pad field width
+ * @param width: array initialized with get_path_layout(), or NULL for no padding
  * @returns: number of printed characters excluding trailing '\0'.
  */
-int snprint_foreign_paths(struct strbuf *buf, const char *style, int pad);
+int snprint_foreign_paths(struct strbuf *buf, const char *style,
+			  const fieldwidth_t *width);
 
 /**
  * snprint_foreign_multipaths(buf, len, style, pad);
@@ -289,11 +294,11 @@ int snprint_foreign_paths(struct strbuf *buf, const char *style, int pad);
  * '\0' - terminated.
  * @param buf: output buffer
  * @param style: format string
- * @param pad: whether to pad field width
+ * @param width: array initialized with get_path_layout(), or NULL for no padding
  * @returns: number of printed characters excluding trailing '\0'.
  */
-int snprint_foreign_multipaths(struct strbuf *buf,
-			       const char *style, int pretty);
+int snprint_foreign_multipaths(struct strbuf *buf, const char *style,
+			       const fieldwidth_t *width);
 
 /**
  * print_foreign_topology(v)
diff --git a/libmultipath/generic.h b/libmultipath/generic.h
index 57c123c..e89848f 100644
--- a/libmultipath/generic.h
+++ b/libmultipath/generic.h
@@ -18,6 +18,14 @@
 #define _GENERIC_H
 #include "vector.h"
 
+/*
+ * fieldwidth_t is required in print.h and foreign.h.
+ * Defining it twice is not allowed before C11.
+ * So do it here.
+ */
+typedef unsigned char fieldwidth_t;
+#define MAX_FIELD_WIDTH UCHAR_MAX
+
 struct strbuf;
 struct gen_multipath;
 struct gen_pathgroup;
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
index 4c22995..0c5417d 100644
--- a/libmultipath/libmultipath.version
+++ b/libmultipath/libmultipath.version
@@ -31,14 +31,16 @@
  *   The new version inherits the previous ones.
  */
 
-LIBMULTIPATH_12.0.0 {
+LIBMULTIPATH_13.0.0 {
 global:
 	/* symbols referenced by multipath and multipathd */
 	add_foreign;
 	add_map_with_path;
 	adopt_paths;
 	alloc_multipath;
+	alloc_multipath_layout;
 	alloc_path;
+	alloc_path_layout;
 	alloc_path_with_pathinfo;
 	alloc_strvec;
 	change_foreign;
@@ -270,6 +272,7 @@ global:
 
 	/* added in 7.0.0 */
 	cleanup_charp;
+	cleanup_ucharp;
 
 	/* added in 8.1.0 */
 	reset_strbuf;
diff --git a/libmultipath/print.c b/libmultipath/print.c
index b5aeca8..033d663 100644
--- a/libmultipath/print.c
+++ b/libmultipath/print.c
@@ -884,18 +884,22 @@ int snprint_wildcards(struct strbuf *buff)
 	return get_strbuf_len(buff) - initial_len;
 }
 
-void
-get_path_layout(vector pathvec, int header)
+fieldwidth_t *alloc_path_layout(void) {
+	return calloc(ARRAY_SIZE(pd), sizeof(fieldwidth_t));
+}
+
+void get_path_layout(vector pathvec, int header, fieldwidth_t *width)
 {
 	vector gpvec = vector_convert(NULL, pathvec, struct path,
 				      dm_path_to_gen);
 	_get_path_layout(gpvec,
-			 header ? LAYOUT_RESET_HEADER : LAYOUT_RESET_ZERO);
+			 header ? LAYOUT_RESET_HEADER : LAYOUT_RESET_ZERO,
+			 width);
 	vector_free(gpvec);
 }
 
 static void
-reset_width(unsigned int *width, enum layout_reset reset, const char *header)
+reset_width(fieldwidth_t *width, enum layout_reset reset, const char *header)
 {
 	switch (reset) {
 	case LAYOUT_RESET_HEADER:
@@ -910,67 +914,70 @@ reset_width(unsigned int *width, enum layout_reset reset, const char *header)
 	}
 }
 
-void
-_get_path_layout (const struct _vector *gpvec, enum layout_reset reset)
+void _get_path_layout (const struct _vector *gpvec, enum layout_reset reset,
+		       fieldwidth_t *width)
 {
 	unsigned int i, j;
 	const struct gen_path *gp;
 
+	if (width == NULL)
+		return;
+
 	for (j = 0; j < ARRAY_SIZE(pd); j++) {
 		STRBUF_ON_STACK(buff);
 
-		reset_width(&pd[j].width, reset, pd[j].header);
+		reset_width(&width[j], reset, pd[j].header);
 
 		if (gpvec == NULL)
 			continue;
 
 		vector_foreach_slot (gpvec, gp, i) {
 			gp->ops->snprint(gp, &buff, pd[j].wildcard);
-			pd[j].width = MAX(pd[j].width, get_strbuf_len(&buff));
+			width[j] = MAX(width[j],
+				       MIN(get_strbuf_len(&buff), MAX_FIELD_WIDTH));
 			truncate_strbuf(&buff, 0);
 		}
 	}
 }
 
-static void
-reset_multipath_layout (void)
-{
-	unsigned int i;
+fieldwidth_t *alloc_multipath_layout(void) {
 
-	for (i = 0; i < ARRAY_SIZE(mpd); i++)
-		mpd[i].width = 0;
+	return calloc(ARRAY_SIZE(mpd), sizeof(fieldwidth_t));
 }
 
-void
-get_multipath_layout (vector mpvec, int header) {
+void get_multipath_layout (vector mpvec, int header, fieldwidth_t *width) {
 	vector gmvec = vector_convert(NULL, mpvec, struct multipath,
 				      dm_multipath_to_gen);
 	_get_multipath_layout(gmvec,
-			 header ? LAYOUT_RESET_HEADER : LAYOUT_RESET_ZERO);
+			      header ? LAYOUT_RESET_HEADER : LAYOUT_RESET_ZERO,
+			      width);
 	vector_free(gmvec);
 }
 
 void
-_get_multipath_layout (const struct _vector *gmvec,
-			    enum layout_reset reset)
+_get_multipath_layout (const struct _vector *gmvec, enum layout_reset reset,
+		       fieldwidth_t *width)
 {
 	unsigned int i, j;
 	const struct gen_multipath * gm;
 
+	if (width == NULL)
+		return;
 	for (j = 0; j < ARRAY_SIZE(mpd); j++) {
 		STRBUF_ON_STACK(buff);
 
-		reset_width(&mpd[j].width, reset, mpd[j].header);
+		reset_width(&width[j], reset, mpd[j].header);
 
 		if (gmvec == NULL)
 			continue;
 
 		vector_foreach_slot (gmvec, gm, i) {
 			gm->ops->snprint(gm, &buff, mpd[j].wildcard);
-			mpd[j].width = MAX(mpd[j].width, get_strbuf_len(&buff));
+			width[j] = MAX(width[j],
+				       MIN(get_strbuf_len(&buff), MAX_FIELD_WIDTH));
 			truncate_strbuf(&buff, 0);
 		}
-		condlog(4, "%s: width %d", mpd[j].header, mpd[j].width);
+		condlog(4, "%s: width %d", mpd[j].header, width[j]);
 	}
 }
 
@@ -1040,7 +1047,8 @@ int snprint_pathgroup_attr(const struct gen_pathgroup* gpg,
 	return pgd[i].snprint(buf, pg);
 }
 
-int snprint_multipath_header(struct strbuf *line, const char *format)
+int snprint_multipath_header(struct strbuf *line, const char *format,
+			     const fieldwidth_t *width)
 {
 	int initial_len = get_strbuf_len(line);
 	const char *f;
@@ -1060,8 +1068,8 @@ int snprint_multipath_header(struct strbuf *line, const char *format)
 
 		if ((rc = append_strbuf_str(line, data->header)) < 0)
 			return rc;
-		else if ((unsigned int)rc < data->width)
-			if ((rc = fill_strbuf(line, ' ', data->width - rc)) < 0)
+		else if ((unsigned int)rc < width[iwc])
+			if ((rc = fill_strbuf(line, ' ', width[iwc] - rc)) < 0)
 				return rc;
 	}
 
@@ -1071,11 +1079,11 @@ int snprint_multipath_header(struct strbuf *line, const char *format)
 }
 
 int _snprint_multipath(const struct gen_multipath *gmp,
-		       struct strbuf *line, const char *format, int pad)
+		       struct strbuf *line, const char *format,
+		       const fieldwidth_t *width)
 {
 	int initial_len = get_strbuf_len(line);
 	const char *f;
-	struct multipath_data * data;
 	int rc;
 
 	for (f = strchr(format, '%'); f; f = strchr(++format, '%')) {
@@ -1087,12 +1095,11 @@ int _snprint_multipath(const struct gen_multipath *gmp,
 		format = f + 1;
 		if ((iwc = mpd_lookup(*format)) == -1)
 			continue; /* unknown wildcard */
-		data = &mpd[iwc];
 
 		if ((rc = gmp->ops->snprint(gmp, line, *format)) < 0)
 			return rc;
-		else if (pad && (unsigned int)rc < data->width)
-			if ((rc = fill_strbuf(line, ' ', data->width - rc)) < 0)
+		else if (width != NULL && (unsigned int)rc < width[iwc])
+			if ((rc = fill_strbuf(line, ' ', width[iwc] - rc)) < 0)
 				return rc;
 	}
 
@@ -1101,7 +1108,8 @@ int _snprint_multipath(const struct gen_multipath *gmp,
 	return get_strbuf_len(line) - initial_len;
 }
 
-int snprint_path_header(struct strbuf *line, const char *format)
+int snprint_path_header(struct strbuf *line, const char *format,
+			const fieldwidth_t *width)
 {
 	int initial_len = get_strbuf_len(line);
 	const char *f;
@@ -1121,8 +1129,8 @@ int snprint_path_header(struct strbuf *line, const char *format)
 
 		if ((rc = append_strbuf_str(line, data->header)) < 0)
 			return rc;
-		else if ((unsigned int)rc < data->width)
-			if ((rc = fill_strbuf(line, ' ', data->width - rc)) < 0)
+		else if ((unsigned int)rc < width[iwc])
+			if ((rc = fill_strbuf(line, ' ', width[iwc] - rc)) < 0)
 				return rc;
 	}
 
@@ -1132,11 +1140,10 @@ int snprint_path_header(struct strbuf *line, const char *format)
 }
 
 int _snprint_path(const struct gen_path *gp, struct strbuf *line,
-		  const char *format, int pad)
+		  const char *format, const fieldwidth_t *width)
 {
 	int initial_len = get_strbuf_len(line);
 	const char *f;
-	struct path_data * data;
 	int rc;
 
 	for (f = strchr(format, '%'); f; f = strchr(++format, '%')) {
@@ -1148,12 +1155,11 @@ int _snprint_path(const struct gen_path *gp, struct strbuf *line,
 		format = f + 1;
 		if ((iwc = pd_lookup(*format)) == -1)
 			continue; /* unknown wildcard */
-		data = &pd[iwc];
 
 		if ((rc = gp->ops->snprint(gp, line, *format)) < 0)
 			return rc;
-		else if (pad && (unsigned int)rc < data->width)
-			if ((rc = fill_strbuf(line, ' ', data->width - rc)) < 0)
+		else if (width != NULL && (unsigned int)rc < width[iwc])
+			if ((rc = fill_strbuf(line, ' ', width[iwc] - rc)) < 0)
 				return rc;
 	}
 
@@ -1190,8 +1196,26 @@ int _snprint_pathgroup(const struct gen_pathgroup *ggp, struct strbuf *line,
 void _print_multipath_topology(const struct gen_multipath *gmp, int verbosity)
 {
 	STRBUF_ON_STACK(buff);
+	fieldwidth_t *p_width __attribute__((cleanup(cleanup_ucharp))) = NULL;
+	const struct gen_pathgroup *gpg;
+	const struct _vector *pgvec, *pathvec;
+	int j;
 
-	_snprint_multipath_topology(gmp, &buff, verbosity);
+	p_width = alloc_path_layout();
+	pgvec = gmp->ops->get_pathgroups(gmp);
+
+	if (pgvec != NULL) {
+		vector_foreach_slot (pgvec, gpg, j) {
+			pathvec = gpg->ops->get_paths(gpg);
+			if (pathvec == NULL)
+				continue;
+			_get_path_layout(pathvec, LAYOUT_RESET_NOT, p_width);
+			gpg->ops->rel_paths(gpg, pathvec);
+		}
+		gmp->ops->rel_pathgroups(gmp, pgvec);
+	}
+
+	_snprint_multipath_topology(gmp, &buff, verbosity, p_width);
 	printf("%s", get_strbuf_str(&buff));
 }
 
@@ -1211,21 +1235,24 @@ int snprint_multipath_style(const struct gen_multipath *gmp,
 }
 
 int _snprint_multipath_topology(const struct gen_multipath *gmp,
-				struct strbuf *buff, int verbosity)
+				struct strbuf *buff, int verbosity,
+				const fieldwidth_t *p_width)
 {
 	int j, i, rc;
 	const struct _vector *pgvec;
 	const struct gen_pathgroup *gpg;
 	STRBUF_ON_STACK(style);
 	size_t initial_len = get_strbuf_len(buff);
+	fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL;
 
 	if (verbosity <= 0)
 		return 0;
 
-	reset_multipath_layout();
+	if ((width = alloc_multipath_layout()) == NULL)
+		return -ENOMEM;
 
 	if (verbosity == 1)
-		return _snprint_multipath(gmp, buff, "%n", 1);
+		return _snprint_multipath(gmp, buff, "%n", width);
 
 	if(isatty(1) &&
 	   (rc = print_strbuf(&style, "%c[%dm", 0x1B, 1)) < 0) /* bold on */
@@ -1236,8 +1263,8 @@ int _snprint_multipath_topology(const struct gen_multipath *gmp,
 	   (rc = print_strbuf(&style, "%c[%dm", 0x1B, 0)) < 0) /* bold off */
 		return rc;
 
-	if ((rc = _snprint_multipath(gmp, buff, get_strbuf_str(&style), 1)) < 0
-	    || (rc = _snprint_multipath(gmp, buff, PRINT_MAP_PROPS, 1)) < 0)
+	if ((rc = _snprint_multipath(gmp, buff, get_strbuf_str(&style), width)) < 0
+	    || (rc = _snprint_multipath(gmp, buff, PRINT_MAP_PROPS, width)) < 0)
 		return rc;
 
 	pgvec = gmp->ops->get_pathgroups(gmp);
@@ -1264,7 +1291,7 @@ int _snprint_multipath_topology(const struct gen_multipath *gmp,
 					       i + 1 == VECTOR_SIZE(pathvec) ?
 					       '`': '|')) < 0 ||
 			    (rc = _snprint_path(gp, buff,
-						PRINT_PATH_INDENT, 1)) < 0)
+						PRINT_PATH_INDENT, p_width)) < 0)
 				return rc;
 		}
 		gpg->ops->rel_paths(gpg, pathvec);
@@ -1949,6 +1976,7 @@ static void print_all_paths_custo(vector pathvec, int banner, const char *fmt)
 	int i;
 	struct path * pp;
 	STRBUF_ON_STACK(line);
+	fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL;
 
 	if (!VECTOR_SIZE(pathvec)) {
 		if (banner)
@@ -1956,14 +1984,17 @@ static void print_all_paths_custo(vector pathvec, int banner, const char *fmt)
 		return;
 	}
 
+	if ((width = alloc_path_layout()) == NULL)
+		return;
+	get_path_layout(pathvec, 1, width);
+
 	if (banner)
 		append_strbuf_str(&line, "===== paths list =====\n");
 
-	get_path_layout(pathvec, 1);
-	snprint_path_header(&line, fmt);
+	snprint_path_header(&line, fmt, width);
 
 	vector_foreach_slot (pathvec, pp, i)
-		snprint_path(&line, fmt, pp, 1);
+		snprint_path(&line, fmt, pp, width);
 
 	printf("%s", get_strbuf_str(&line));
 }
diff --git a/libmultipath/print.h b/libmultipath/print.h
index 4322f6e..52f5b25 100644
--- a/libmultipath/print.h
+++ b/libmultipath/print.h
@@ -15,23 +15,30 @@ enum layout_reset {
 	LAYOUT_RESET_HEADER,
 };
 
-void _get_path_layout (const struct _vector *gpvec, enum layout_reset);
-void get_path_layout (vector pathvec, int header);
-void _get_multipath_layout (const struct _vector *gmvec, enum layout_reset);
-void get_multipath_layout (vector mpvec, int header);
-int snprint_path_header(struct strbuf *, const char *);
-int snprint_multipath_header(struct strbuf *, const char *);
-int _snprint_path (const struct gen_path *, struct strbuf *, const char *, int);
-#define snprint_path(buf, fmt, pp, v) \
-	_snprint_path(dm_path_to_gen(pp), buf, fmt,  v)
+/* fieldwidth_t is defined in generic.h */
+fieldwidth_t *alloc_path_layout(void);
+void _get_path_layout (const struct _vector *gpvec, enum layout_reset,
+		       fieldwidth_t *width);
+void get_path_layout (vector pathvec, int header, fieldwidth_t *width);
+fieldwidth_t *alloc_multipath_layout(void);
+void _get_multipath_layout (const struct _vector *gmvec, enum layout_reset,
+			    fieldwidth_t *width);
+void get_multipath_layout (vector mpvec, int header, fieldwidth_t *width);
+int snprint_path_header(struct strbuf *, const char *, const fieldwidth_t *);
+int snprint_multipath_header(struct strbuf *, const char *,
+			     const fieldwidth_t *);
+int _snprint_path (const struct gen_path *, struct strbuf *, const char *,
+		   const fieldwidth_t *);
+#define snprint_path(buf, fmt, pp, w)		\
+	_snprint_path(dm_path_to_gen(pp), buf, fmt, w)
 int _snprint_multipath (const struct gen_multipath *, struct strbuf *,
-			const char *, int);
-#define snprint_multipath(buf, fmt, mp, v)				\
-	_snprint_multipath(dm_multipath_to_gen(mp), buf, fmt,  v)
+			const char *, const fieldwidth_t *);
+#define snprint_multipath(buf, fmt, mp, w)				\
+	_snprint_multipath(dm_multipath_to_gen(mp), buf, fmt, w)
 int _snprint_multipath_topology (const struct gen_multipath *, struct strbuf *,
-				 int verbosity);
-#define snprint_multipath_topology(buf, mpp, v) \
-	_snprint_multipath_topology (dm_multipath_to_gen(mpp), buf, v)
+				 int verbosity, const fieldwidth_t *);
+#define snprint_multipath_topology(buf, mpp, v, w)			\
+	_snprint_multipath_topology (dm_multipath_to_gen(mpp), buf, v, w)
 int snprint_multipath_topology_json(struct strbuf *, const struct vectors *vecs);
 int __snprint_config(const struct config *conf, struct strbuf *buff,
 		     const struct _vector *hwtable, const struct _vector *mpvec);
diff --git a/multipath/main.c b/multipath/main.c
index 5711acf..0a9377e 100644
--- a/multipath/main.c
+++ b/multipath/main.c
@@ -460,6 +460,7 @@ configure (struct config *conf, enum mpath_cmds cmd,
 	int di_flag = 0;
 	char * refwwid = NULL;
 	char * dev = NULL;
+	fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL;
 
 	/*
 	 * allocate core vectors to store paths and multipaths
@@ -546,8 +547,10 @@ configure (struct config *conf, enum mpath_cmds cmd,
 	if (libmp_verbosity > 2)
 		print_all_paths(pathvec, 1);
 
-	get_path_layout(pathvec, 0);
-	foreign_path_layout();
+	if ((width = alloc_path_layout()) == NULL)
+		goto out;
+	get_path_layout(pathvec, 0, width);
+	foreign_path_layout(width);
 
 	if (get_dm_mpvec(cmd, curmp, pathvec, refwwid))
 		goto out;
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
index 1b7f258..d79cdd7 100644
--- a/multipathd/cli_handlers.c
+++ b/multipathd/cli_handlers.c
@@ -38,18 +38,22 @@ show_paths (struct strbuf *reply, struct vectors *vecs, char *style, int pretty)
 	int i;
 	struct path * pp;
 	int hdr_len = 0;
+	fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL;
 
-	get_path_layout(vecs->pathvec, 1);
-	foreign_path_layout();
-
-	if (pretty && (hdr_len = snprint_path_header(reply, style)) < 0)
+	if (pretty) {
+		if ((width = alloc_path_layout()) == NULL)
+			return 1;
+		get_path_layout(vecs->pathvec, 1, width);
+		foreign_path_layout(width);
+	}
+	if (pretty && (hdr_len = snprint_path_header(reply, style, width)) < 0)
 		return 1;
 
 	vector_foreach_slot(vecs->pathvec, pp, i) {
-		if (snprint_path(reply, style, pp, pretty) < 0)
+		if (snprint_path(reply, style, pp, width) < 0)
 			return 1;
 	}
-	if (snprint_foreign_paths(reply, style, pretty) < 0)
+	if (snprint_foreign_paths(reply, style, width) < 0)
 		return 1;
 
 	if (pretty && get_strbuf_len(reply) == (size_t)hdr_len)
@@ -63,7 +67,11 @@ static int
 show_path (struct strbuf *reply, struct vectors *vecs, struct path *pp,
 	   char *style)
 {
-	get_path_layout(vecs->pathvec, 1);
+	fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL;
+
+	if ((width = alloc_path_layout()) == NULL)
+		return 1;
+	get_path_layout(vecs->pathvec, 1, width);
 	if (snprint_path(reply, style, pp, 0) < 0)
 		return 1;
 	return 0;
@@ -71,12 +79,12 @@ show_path (struct strbuf *reply, struct vectors *vecs, struct path *pp,
 
 static int
 show_map_topology (struct strbuf *reply, struct multipath *mpp,
-		   struct vectors *vecs)
+		   struct vectors *vecs, const fieldwidth_t *width)
 {
 	if (update_multipath(vecs, mpp->alias, 0))
 		return 1;
 
-	if (snprint_multipath_topology(reply, mpp, 2) < 0)
+	if (snprint_multipath_topology(reply, mpp, 2, width) < 0)
 		return 1;
 
 	return 0;
@@ -87,19 +95,22 @@ show_maps_topology (struct strbuf *reply, struct vectors * vecs)
 {
 	int i;
 	struct multipath * mpp;
+	fieldwidth_t *p_width __attribute__((cleanup(cleanup_ucharp))) = NULL;
 
-	get_path_layout(vecs->pathvec, 0);
-	foreign_path_layout();
+	if ((p_width = alloc_path_layout()) == NULL)
+		return 1;
+	get_path_layout(vecs->pathvec, 0, p_width);
+	foreign_path_layout(p_width);
 
 	vector_foreach_slot(vecs->mpvec, mpp, i) {
 		if (update_multipath(vecs, mpp->alias, 0)) {
 			i--;
 			continue;
 		}
-		if (snprint_multipath_topology(reply, mpp, 2) < 0)
+		if (snprint_multipath_topology(reply, mpp, 2, p_width) < 0)
 			return 1;
 	}
-	if (snprint_foreign_topology(reply, 2) < 0)
+	if (snprint_foreign_topology(reply, 2, p_width) < 0)
 		return 1;
 
 	return 0;
@@ -247,9 +258,12 @@ cli_list_map_topology (void *v, struct strbuf *reply, void *data)
 	struct multipath * mpp;
 	struct vectors * vecs = (struct vectors *)data;
 	char * param = get_keyparam(v, MAP);
+	fieldwidth_t *p_width __attribute__((cleanup(cleanup_ucharp))) = NULL;
 
+	if ((p_width = alloc_path_layout()) == NULL)
+		return 1;
+	get_path_layout(vecs->pathvec, 0, p_width);
 	param = convert_dev(param, 0);
-	get_path_layout(vecs->pathvec, 0);
 	mpp = find_mp_by_str(vecs->mpvec, param);
 
 	if (!mpp)
@@ -257,7 +271,7 @@ cli_list_map_topology (void *v, struct strbuf *reply, void *data)
 
 	condlog(3, "list multipath %s (operator)", param);
 
-	return show_map_topology(reply, mpp, vecs);
+	return show_map_topology(reply, mpp, vecs, p_width);
 }
 
 static int
@@ -328,9 +342,9 @@ show_daemon (struct strbuf *reply)
 
 static int
 show_map (struct strbuf *reply, struct multipath *mpp, char *style,
-	  int pretty)
+	  const fieldwidth_t *width)
 {
-	if (snprint_multipath(reply, style, mpp, pretty) < 0)
+	if (snprint_multipath(reply, style, mpp, width) < 0)
 		return 1;
 
 	return 0;
@@ -343,11 +357,16 @@ show_maps (struct strbuf *reply, struct vectors *vecs, char *style,
 	int i;
 	struct multipath * mpp;
 	int hdr_len = 0;
+	fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL;
 
-	get_multipath_layout(vecs->mpvec, 1);
-	foreign_multipath_layout();
+	if (pretty) {
+		if ((width = alloc_multipath_layout()) == NULL)
+			return 1;
+		get_multipath_layout(vecs->mpvec, 1, width);
+		foreign_multipath_layout(width);
+	}
 
-	if (pretty && (hdr_len = snprint_multipath_header(reply, style)) < 0)
+	if (pretty && (hdr_len = snprint_multipath_header(reply, style, width)) < 0)
 		return 1;
 
 	vector_foreach_slot(vecs->mpvec, mpp, i) {
@@ -355,10 +374,10 @@ show_maps (struct strbuf *reply, struct vectors *vecs, char *style,
 			i--;
 			continue;
 		}
-		if (snprint_multipath(reply, style, mpp, pretty) < 0)
+		if (snprint_multipath(reply, style, mpp, width) < 0)
 			return 1;
 	}
-	if (snprint_foreign_multipaths(reply, style, pretty) < 0)
+	if (snprint_foreign_multipaths(reply, style, width) < 0)
 		return 1;
 
 	if (pretty && get_strbuf_len(reply) == (size_t)hdr_len)
@@ -397,16 +416,19 @@ cli_list_map_fmt (void *v, struct strbuf *reply, void *data)
 	struct vectors * vecs = (struct vectors *)data;
 	char * param = get_keyparam(v, MAP);
 	char * fmt = get_keyparam(v, FMT);
+	fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL;
 
+	if ((width = alloc_multipath_layout()) == NULL)
+		return 1;
+	get_multipath_layout(vecs->pathvec, 1, width);
 	param = convert_dev(param, 0);
-	get_multipath_layout(vecs->mpvec, 1);
 	mpp = find_mp_by_str(vecs->mpvec, param);
 	if (!mpp)
 		return 1;
 
 	condlog(3, "list map %s fmt %s (operator)", param, fmt);
 
-	return show_map(reply, mpp, fmt, 1);
+	return show_map(reply, mpp, fmt, width);
 }
 
 static int
