Skip site navigation (1)Skip section navigation (2)


| raw e-mail | index | archive | help
    Add --libxo support for geom status and list sub commands.
    
    Submitted-by: Johan Söllvander
    MFC-after:    1 week
    Differential Revision: https://reviews.freebsd.org/D37615
---
 sbin/geom/Makefile    |   2 +-
 sbin/geom/core/geom.c | 232 +++++++++++++++++++++++++++++++++-----------------
 2 files changed, 157 insertions(+), 77 deletions(-)

diff --git a/sbin/geom/Makefile b/sbin/geom/Makefile
index 078503d3ae67..61561ef1ff1b 100644
--- a/sbin/geom/Makefile
+++ b/sbin/geom/Makefile
@@ -9,7 +9,7 @@ MAN=		geom.8
 CFLAGS+=	-I${.CURDIR} -I${.CURDIR}/core
 CFLAGS+=	-DGEOM_CLASS_DIR=\"${GEOM_CLASS_DIR}\"
 
-LIBADD=		geom util
+LIBADD=		geom util xo
 
 .if defined(RESCUE)
 .PATH:	${SRCTOP}/lib/geom/part \
diff --git a/sbin/geom/core/geom.c b/sbin/geom/core/geom.c
index b78021194ddd..496123f08274 100644
--- a/sbin/geom/core/geom.c
+++ b/sbin/geom/core/geom.c
@@ -49,9 +49,12 @@
 #include <assert.h>
 #include <libgeom.h>
 #include <geom.h>
+#include <libxo/xo.h>
 
 #include "misc/subr.h"
 
+#define GEOM_XO_VERSION "1"
+
 #ifdef STATIC_GEOM_CLASSES
 extern uint32_t gpart_version;
 extern struct g_command gpart_class_commands[];
@@ -513,6 +516,7 @@ run_command(int argc, char *argv[])
 	gctl_free(req);
 	if (verbose)
 		printf("Done.\n");
+	xo_finish();
 	exit(EXIT_SUCCESS);
 }
 
@@ -810,6 +814,10 @@ main(int argc, char *argv[])
 	provider_name = NULL;
 	tflag = false;
 
+	argc = xo_parse_args(argc, argv);
+	if (argc < 0)
+		return (argc);
+
 	if (strcmp(getprogname(), "geom") == 0) {
 		while ((ch = getopt(argc, argv, "hp:t")) != -1) {
 			switch (ch) {
@@ -831,6 +839,7 @@ main(int argc, char *argv[])
 		 * Don't adjust argc and argv, it would break get_class().
 		 */
 	}
+	xo_set_version(GEOM_XO_VERSION);
 
 	if (tflag && provider_name != NULL) {
 		errx(EXIT_FAILURE,
@@ -839,6 +848,7 @@ main(int argc, char *argv[])
 
 	if (provider_name != NULL) {
 		list_one_geom_by_provider(provider_name);
+		xo_finish();
 		return (0);
 	}
 
@@ -882,29 +892,33 @@ find_geom(struct gclass *classp, const char *name)
 }
 
 static void
-list_one_provider(struct gprovider *pp, const char *prefix)
+list_one_provider(struct gprovider *pp, const char *padding)
 {
 	struct gconfig *conf;
 	char buf[5];
 
-	printf("Name: %s\n", pp->lg_name);
+	xo_emit("{Lcw:Name}{:Name}\n", pp->lg_name);
 	humanize_number(buf, sizeof(buf), (int64_t)pp->lg_mediasize, "",
 	    HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
-	printf("%sMediasize: %jd (%s)\n", prefix, (intmax_t)pp->lg_mediasize,
-	    buf);
-	printf("%sSectorsize: %u\n", prefix, pp->lg_sectorsize);
+	xo_emit("{P:/%s}{Lcw:Mediasize}{:Mediasize/%jd} ({N:/%s})\n",
+	    padding, (intmax_t)pp->lg_mediasize, buf);
+	xo_emit("{P:/%s}{Lcw:Sectorsize}{:Sectorsize/%u} \n",
+	    padding, pp->lg_sectorsize);
 	if (pp->lg_stripesize > 0 || pp->lg_stripeoffset > 0) {
-		printf("%sStripesize: %ju\n", prefix, pp->lg_stripesize);
-		printf("%sStripeoffset: %ju\n", prefix, pp->lg_stripeoffset);
+		xo_emit("{P:/%s}{Lcw:Stripesize}{Stripesize/%ju}\n",
+		    padding, pp->lg_stripesize);
+		xo_emit("{P:/%s}{Lcw:Stripeoffset}{Stripeoffset/%ju}\n",
+		    padding, pp->lg_stripeoffset);
 	}
-	printf("%sMode: %s\n", prefix, pp->lg_mode);
+	xo_emit("{P:/%s}{Lcw:Mode}{Mode}\n", padding, pp->lg_mode);
 	LIST_FOREACH(conf, &pp->lg_config, lg_config) {
-		printf("%s%s: %s\n", prefix, conf->lg_name, conf->lg_val);
+		xo_emit("{P:/%s}{Lcwa:}{a:}\n", padding, conf->lg_name,
+		    conf->lg_name, conf->lg_val);
 	}
 }
 
 static void
-list_one_consumer(struct gconsumer *cp, const char *prefix)
+list_one_consumer(struct gconsumer *cp, const char *padding)
 {
 	struct gprovider *pp;
 	struct gconfig *conf;
@@ -915,20 +929,24 @@ list_one_consumer(struct gconsumer *cp, const char *prefix)
 	else {
 		char buf[5];
 
-		printf("Name: %s\n", pp->lg_name);
+		xo_emit("{Lcw:Name}{:Name}\n", pp->lg_name);
 		humanize_number(buf, sizeof(buf), (int64_t)pp->lg_mediasize, "",
 		    HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
-		printf("%sMediasize: %jd (%s)\n", prefix,
-		    (intmax_t)pp->lg_mediasize, buf);
-		printf("%sSectorsize: %u\n", prefix, pp->lg_sectorsize);
+		xo_emit("{P:/%s}{Lcw:Mediasize}{:Mediasize/%jd} ({N:/%s})\n",
+		    padding, (intmax_t)pp->lg_mediasize, buf);
+		xo_emit("{P:/%s}{Lcw:Sectorsize}{:Sectorsize/%u}\n",
+		    padding, pp->lg_sectorsize);
 		if (pp->lg_stripesize > 0 || pp->lg_stripeoffset > 0) {
-			printf("%sStripesize: %ju\n", prefix, pp->lg_stripesize);
-			printf("%sStripeoffset: %ju\n", prefix, pp->lg_stripeoffset);
+			xo_emit("{P:/%s}{Lcw:Stripesize}{:Stripesize/%ju}\n",
+			    padding, pp->lg_stripesize);
+			xo_emit("{P:/%s}{Lcw:Stripeoffset}{:Stripesize/%ju}\n",
+			    padding, pp->lg_stripeoffset);
 		}
-		printf("%sMode: %s\n", prefix, cp->lg_mode);
+		xo_emit("{P:/%s}{Lcw:Mode}{:Mode}\n", padding, pp->lg_mode);
 	}
 	LIST_FOREACH(conf, &cp->lg_config, lg_config) {
-		printf("%s%s: %s\n", prefix, conf->lg_name, conf->lg_val);
+		xo_emit("{P:/%s}{Lcwa:}{a:}\n", padding, conf->lg_name,
+		    conf->lg_name, conf->lg_val);
 	}
 }
 
@@ -940,27 +958,36 @@ list_one_geom(struct ggeom *gp)
 	struct gconfig *conf;
 	unsigned n;
 
-	printf("Geom name: %s\n", gp->lg_name);
+	xo_emit("{Lcw:Geom name}{:Name}\n", gp->lg_name);
 	LIST_FOREACH(conf, &gp->lg_config, lg_config) {
-		printf("%s: %s\n", conf->lg_name, conf->lg_val);
+		xo_emit("{Lcwa:}{a:}\n", conf->lg_name, conf->lg_name,
+		    conf->lg_val);
 	}
 	if (!LIST_EMPTY(&gp->lg_provider)) {
-		printf("Providers:\n");
+		xo_open_list("Providers");
+		xo_emit("{Tc:Providers}\n");
 		n = 1;
 		LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
-			printf("%u. ", n++);
+			xo_emit("{T:/%u} ", n++);
+			xo_open_instance("provider");
 			list_one_provider(pp, "   ");
+			xo_close_instance("provider");
 		}
+		xo_close_list("Providers");
 	}
 	if (!LIST_EMPTY(&gp->lg_consumer)) {
-		printf("Consumers:\n");
+		xo_open_list("Consumers");
+		xo_emit("{Tc:Consumers}\n");
 		n = 1;
 		LIST_FOREACH(cp, &gp->lg_consumer, lg_consumer) {
-			printf("%u. ", n++);
+			xo_emit("{T:/%u} ", n++);
+			xo_open_instance("consumer");
 			list_one_consumer(cp, "   ");
+			xo_close_instance("consumer");
 		}
+		xo_close_list("Consumers");
 	}
-	printf("\n");
+	xo_emit("\n");
 }
 
 static void
@@ -978,8 +1005,10 @@ list_one_geom_by_provider(const char *provider_name)
 	if (gp == NULL)
 		errx(EXIT_FAILURE, "Cannot find provider '%s'.", provider_name);
 
-	printf("Geom class: %s\n", gp->lg_class->lg_name);
+	xo_open_container("Geom");
+	xo_emit("{Lwc:Geom class}{:Class}\n", gp->lg_class->lg_name);
 	list_one_geom(gp);
+	xo_close_container("Geom");
 }
 
 static void
@@ -1038,14 +1067,20 @@ std_list(struct gctl_req *req, unsigned flags __unused)
 				    "an instance named '%s'.",
 				    gclass_name, name);
 			}
+			xo_open_container("Geom");
 			list_one_geom(gp);
+			xo_close_container("Geom");
 		}
 	} else {
+		xo_open_list("Geoms");
 		LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
 			if (LIST_EMPTY(&gp->lg_provider) && !all)
 				continue;
+			xo_open_instance("geom");
 			list_one_geom(gp);
+			xo_close_instance("geom");
 		}
+		xo_close_list("Geoms");
 	}
 	geom_deletetree(&mesh);
 }
@@ -1115,34 +1150,24 @@ status_update_len_prs(struct ggeom *gp, int *name_len, int *status_len)
 }
 
 static char *
-status_one_consumer(struct gconsumer *cp)
+status_one_consumer(struct gconsumer *cp, const char *value)
 {
-	static char buf[256];
 	struct gprovider *pp;
 	struct gconfig *conf;
-	const char *state, *syncr;
+	char *ret;
 
 	pp = cp->lg_provider;
 	if (pp == NULL)
 		return (NULL);
-	state = NULL;
-	syncr = NULL;
+	ret = NULL;
 	LIST_FOREACH(conf, &cp->lg_config, lg_config) {
-		if (strcasecmp(conf->lg_name, "state") == 0)
-			state = conf->lg_val;
-		if (strcasecmp(conf->lg_name, "synchronized") == 0)
-			syncr = conf->lg_val;
-	}
-	if (state == NULL && syncr == NULL)
-		snprintf(buf, sizeof(buf), "%s", pp->lg_name);
-	else if (state != NULL && syncr != NULL) {
-		snprintf(buf, sizeof(buf), "%s (%s, %s)", pp->lg_name,
-		    state, syncr);
-	} else {
-		snprintf(buf, sizeof(buf), "%s (%s)", pp->lg_name,
-		    state ? state : syncr);
+		if (strcasecmp(conf->lg_name, value) == 0)
+			ret = conf->lg_val;
 	}
-	return (buf);
+
+	if (ret == NULL)
+		return (NULL);
+	return (ret);
 }
 
 static void
@@ -1150,8 +1175,8 @@ status_one_geom(struct ggeom *gp, int script, int name_len, int status_len)
 {
 	struct gconsumer *cp;
 	struct gconfig *conf;
-	const char *name, *status, *component;
-	int gotone;
+	const char *name, *status, *cstate, *csyncr;
+	int gotone, len;
 
 	name = gp->lg_name;
 	status = "N/A";
@@ -1161,21 +1186,49 @@ status_one_geom(struct ggeom *gp, int script, int name_len, int status_len)
 			break;
 		}
 	}
-	gotone = 0;
+	gotone = len = 0;
+	xo_open_instance("status");
 	LIST_FOREACH(cp, &gp->lg_consumer, lg_consumer) {
-		component = status_one_consumer(cp);
-		if (component == NULL)
+		cstate = status_one_consumer(cp, "state");
+		csyncr = status_one_consumer(cp, "synchronized");
+		if (cstate == NULL && csyncr == NULL)
 			continue;
+		if (!gotone || script) {
+			if (!gotone) {
+				xo_emit("{:name/%*s}  {:status/%*s}  ",
+				    name_len, name, status_len, status);
+			} else {
+				xo_emit("{d:name/%*s}  {d:status/%*s}  ",
+				    name_len, name, status_len, status);
+			}
+			xo_open_list("components");
+		}
+
+		xo_open_instance("components");
+		if (cstate != NULL && csyncr != NULL) {
+			xo_emit("{P:/%*s}{:compontent} ({:state}, {:synchronized})\n",
+			len, "", cp->lg_provider->lg_name, cstate, csyncr);
+		} else if (cstate != NULL) {
+			xo_emit("{P:/%*s}{:compontent} ({:state})\n",
+			len, "", cp->lg_provider->lg_name, cstate);
+		} else {
+			xo_emit("{P:/%*s}{:compontent} ({:synchronized})\n",
+			len, "", cp->lg_provider->lg_name, csyncr);
+		}
+		xo_close_instance("components");
 		gotone = 1;
-		printf("%*s  %*s  %s\n", name_len, name, status_len, status,
-		    component);
-		if (!script)
-			name = status = "";
+		if (!len && !script)
+			len = name_len + status_len + 4;
 	}
 	if (!gotone) {
-		printf("%*s  %*s  %s\n", name_len, name, status_len, status,
-		    "N/A");
+		xo_emit("{:name/%*s}  {:status/%*s}  ", name_len, name, status_len, status);
+		xo_open_list("components");
+		xo_open_instance("components");
+		xo_emit("{P:/%*s}{d:compontent}\n", len, "", "N/A");
+		xo_close_instance("components");
 	}
+	xo_close_list("components");
+	xo_close_instance("status");
 }
 
 static void
@@ -1184,9 +1237,10 @@ status_one_geom_prs(struct ggeom *gp, int script, int name_len, int status_len)
 	struct gprovider *pp;
 	struct gconsumer *cp;
 	struct gconfig *conf;
-	const char *name, *status, *component;
-	int gotone;
+	const char *name, *status, *cstate, *csyncr;
+	int gotone, len;
 
+	xo_open_instance("status");
 	LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
 		name = pp->lg_name;
 		status = "N/A";
@@ -1202,22 +1256,50 @@ status_one_geom_prs(struct ggeom *gp, int script, int name_len, int status_len)
 				break;
 			}
 		}
-		gotone = 0;
+		gotone = len = 0;
 		LIST_FOREACH(cp, &gp->lg_consumer, lg_consumer) {
-			component = status_one_consumer(cp);
-			if (component == NULL)
+			cstate = status_one_consumer(cp, "state");
+			csyncr = status_one_consumer(cp, "synchronized");
+			if (cstate == NULL && csyncr == NULL)
 				continue;
+
+			if (!gotone || script) {
+				if (!gotone) {
+					xo_emit("{:name/%*s}  {:status/%*s}  ",
+					    name_len, name, status_len, status);
+				} else {
+					xo_emit("{d:name/%*s}  {d:status/%*s}  ",
+					    name_len, name, status_len, status);
+				}
+				xo_open_list("components");
+			}
+
+			xo_open_instance("component");
+			if (cstate != NULL && csyncr != NULL) {
+				xo_emit("{P:/%*s}{:compontent} ({:state}, {:synchronized})\n",
+				len, "", cp->lg_provider->lg_name, cstate, csyncr);
+			} else if (cstate != NULL) {
+				xo_emit("{P:/%*s}{:compontent} ({:state})\n",
+				len, "", cp->lg_provider->lg_name, cstate);
+			} else {
+				xo_emit("{P:/%*s}{:compontent} ({:synchronized})\n",
+				len, "", cp->lg_provider->lg_name, csyncr);
+			}
+			xo_close_instance("component");
 			gotone = 1;
-			printf("%*s  %*s  %s\n", name_len, name,
-			    status_len, status, component);
-			if (!script)
-				name = status = "";
+			if (!len && !script)
+				len = name_len + status_len + 4;
 		}
 		if (!gotone) {
-			printf("%*s  %*s  %s\n", name_len, name,
-			    status_len, status, "N/A");
+			xo_emit("{:name/%*s}  {:status/%*s}  ", name_len, name, status_len, status);
+			xo_open_list("components");
+			xo_open_instance("components");
+			xo_emit("{P:/%*s}{d:compontent}\n", len, "", "N/A");
+			xo_close_instance("components");
 		}
+		xo_close_list("components");
 	}
+	xo_close_instance("status");
 }
 
 static void
@@ -1240,13 +1322,9 @@ std_status(struct gctl_req *req, unsigned flags __unused)
 	all = gctl_get_int(req, "all");
 	geoms = gctl_get_int(req, "geoms");
 	script = gctl_get_int(req, "script");
-	if (script) {
-		name_len = 0;
-		status_len = 0;
-	} else {
-		name_len = strlen("Name");
-		status_len = strlen("Status");
-	}
+	name_len = strlen("Name");
+	status_len = strlen("Status");
+
 	if (nargs > 0) {
 		for (i = 0, n = 0; i < nargs; i++) {
 			name = gctl_get_ascii(req, "arg%d", i);
@@ -1282,9 +1360,10 @@ std_status(struct gctl_req *req, unsigned flags __unused)
 			goto end;
 	}
 	if (!script) {
-		printf("%*s  %*s  %s\n", name_len, "Name", status_len, "Status",
-		    "Components");
+		xo_emit("{T:/%*s}  {T:/%*s}  {T:Components}\n",
+		    name_len, "Name", status_len, "Status");
 	}
+	xo_open_list("status");
 	if (nargs > 0) {
 		for (i = 0; i < nargs; i++) {
 			name = gctl_get_ascii(req, "arg%d", i);
@@ -1312,6 +1391,7 @@ std_status(struct gctl_req *req, unsigned flags __unused)
 			}
 		}
 	}
+	xo_close_list("status");
 end:
 	geom_deletetree(&mesh);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?>