Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Nov 2025 22:55:07 GMT
From:      Kirk McKusick <mckusick@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: c174f518c9c8 - main - Refinements to the --libxo support for geom status and list sub commands.
Message-ID:  <202511032255.5A3Mt7vW031826@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by mckusick:

URL: https://cgit.FreeBSD.org/src/commit/?id=c174f518c9c8cf3a567c5f60414508ac951a2ae4

commit c174f518c9c8cf3a567c5f60414508ac951a2ae4
Author:     Kirk McKusick <mckusick@FreeBSD.org>
AuthorDate: 2025-11-03 22:54:13 +0000
Commit:     Kirk McKusick <mckusick@FreeBSD.org>
CommitDate: 2025-11-03 22:54:53 +0000

    Refinements to the --libxo support for geom status and list sub commands.
    
    Changes based on comments in D53110: tags should be lowercase; rename a
    few containers so that the JSON/XML output says "DISK" or "MULTIPATH"
    (depending on class) instead of a generic "Geom"; adds {t:} to trim
    extra whitespaces that sometimes appeared in the value fields of
    JSON/XML output.
    
    Submitted-by: Johan Söllvander
    MFC-after:    1 week
    Differential Revision: https://reviews.freebsd.org/D53313
---
 sbin/geom/core/geom.c | 125 ++++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 55 deletions(-)

diff --git a/sbin/geom/core/geom.c b/sbin/geom/core/geom.c
index 2de696ce6a43..51ea52a3e858 100644
--- a/sbin/geom/core/geom.c
+++ b/sbin/geom/core/geom.c
@@ -897,23 +897,23 @@ list_one_provider(struct gprovider *pp, const char *padding)
 	struct gconfig *conf;
 	char buf[5];
 
-	xo_emit("{Lcw:Name}{:Name}\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);
-	xo_emit("{P:/%s}{Lcw:Mediasize}{:Mediasize/%jd} ({N:/%s})\n",
+	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",
+	xo_emit("{P:/%s}{Lcw:Sectorsize}{:sectorsize/%u}\n",
 	    padding, pp->lg_sectorsize);
 	if (pp->lg_stripesize > 0 || pp->lg_stripeoffset > 0) {
-		xo_emit("{P:/%s}{Lcw:Stripesize}{Stripesize/%ju}\n",
+		xo_emit("{P:/%s}{Lcw:Stripesize}{:stripesize/%ju}\n",
 		    padding, pp->lg_stripesize);
-		xo_emit("{P:/%s}{Lcw:Stripeoffset}{Stripeoffset/%ju}\n",
+		xo_emit("{P:/%s}{Lcw:Stripeoffset}{:stripeoffset/%ju}\n",
 		    padding, pp->lg_stripeoffset);
 	}
-	xo_emit("{P:/%s}{Lcw:Mode}{Mode}\n", padding, pp->lg_mode);
+	xo_emit("{P:/%s}{Lcw:Mode}{:mode}\n", padding, pp->lg_mode);
 	LIST_FOREACH(conf, &pp->lg_config, lg_config) {
 		xo_emit("{P:/%s}{Lcwa:}{a:}\n", padding, conf->lg_name,
-		    conf->lg_name, conf->lg_val);
+		    conf->lg_name, conf->lg_val ? conf->lg_val : "");
 	}
 }
 
@@ -929,24 +929,24 @@ list_one_consumer(struct gconsumer *cp, const char *padding)
 	else {
 		char buf[5];
 
-		xo_emit("{Lcw:Name}{:Name}\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);
-		xo_emit("{P:/%s}{Lcw:Mediasize}{:Mediasize/%jd} ({N:/%s})\n",
+		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",
+		xo_emit("{P:/%s}{Lcw:Sectorsize}{:sectorsize/%u}\n",
 		    padding, pp->lg_sectorsize);
 		if (pp->lg_stripesize > 0 || pp->lg_stripeoffset > 0) {
-			xo_emit("{P:/%s}{Lcw:Stripesize}{:Stripesize/%ju}\n",
+			xo_emit("{P:/%s}{Lcw:Stripesize}{:stripesize/%ju}\n",
 			    padding, pp->lg_stripesize);
-			xo_emit("{P:/%s}{Lcw:Stripeoffset}{:Stripesize/%ju}\n",
+			xo_emit("{P:/%s}{Lcw:Stripeoffset}{:stripeoffset/%ju}\n",
 			    padding, pp->lg_stripeoffset);
 		}
-		xo_emit("{P:/%s}{Lcw:Mode}{:Mode}\n", padding, pp->lg_mode);
+		xo_emit("{P:/%s}{Lcw:Mode}{:mode}\n", padding, pp->lg_mode);
 	}
 	LIST_FOREACH(conf, &cp->lg_config, lg_config) {
 		xo_emit("{P:/%s}{Lcwa:}{a:}\n", padding, conf->lg_name,
-		    conf->lg_name, conf->lg_val);
+		    conf->lg_name, conf->lg_val ? conf->lg_val : "");
 	}
 }
 
@@ -958,13 +958,13 @@ list_one_geom(struct ggeom *gp)
 	struct gconfig *conf;
 	unsigned n;
 
-	xo_emit("{Lcw:Geom name}{:Name}\n", gp->lg_name);
+	xo_emit("{Lcw:Geom name}{:name}\n", gp->lg_name);
 	LIST_FOREACH(conf, &gp->lg_config, lg_config) {
 		xo_emit("{Lcwa:}{a:}\n", conf->lg_name, conf->lg_name,
-		    conf->lg_val);
+		    conf->lg_val ? conf->lg_val : "");
 	}
 	if (!LIST_EMPTY(&gp->lg_provider)) {
-		xo_open_list("Providers");
+		xo_open_list("providers");
 		xo_emit("{Tc:Providers}\n");
 		n = 1;
 		LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
@@ -973,10 +973,10 @@ list_one_geom(struct ggeom *gp)
 			list_one_provider(pp, "   ");
 			xo_close_instance("provider");
 		}
-		xo_close_list("Providers");
+		xo_close_list("providers");
 	}
 	if (!LIST_EMPTY(&gp->lg_consumer)) {
-		xo_open_list("Consumers");
+		xo_open_list("consumers");
 		xo_emit("{Tc:Consumers}\n");
 		n = 1;
 		LIST_FOREACH(cp, &gp->lg_consumer, lg_consumer) {
@@ -985,7 +985,7 @@ list_one_geom(struct ggeom *gp)
 			list_one_consumer(cp, "   ");
 			xo_close_instance("consumer");
 		}
-		xo_close_list("Consumers");
+		xo_close_list("consumers");
 	}
 	xo_emit("\n");
 }
@@ -1005,10 +1005,10 @@ list_one_geom_by_provider(const char *provider_name)
 	if (gp == NULL)
 		errx(EXIT_FAILURE, "Cannot find provider '%s'.", provider_name);
 
-	xo_open_container("Geom");
-	xo_emit("{Lwc:Geom class}{:Class}\n", gp->lg_class->lg_name);
+	xo_open_container(provider_name);
+	xo_emit("{Lwc:Geom class}{:class}\n", gp->lg_class->lg_name);
 	list_one_geom(gp);
-	xo_close_container("Geom");
+	xo_close_container(provider_name);
 }
 
 static void
@@ -1067,12 +1067,12 @@ std_list(struct gctl_req *req, unsigned flags __unused)
 				    "an instance named '%s'.",
 				    gclass_name, name);
 			}
-			xo_open_container("Geom");
+			xo_open_container(gclass_name);
 			list_one_geom(gp);
-			xo_close_container("Geom");
+			xo_close_container(gclass_name);
 		}
 	} else {
-		xo_open_list("Geoms");
+		xo_open_list(gclass_name);
 		LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
 			if (LIST_EMPTY(&gp->lg_provider) && !all)
 				continue;
@@ -1080,7 +1080,7 @@ std_list(struct gctl_req *req, unsigned flags __unused)
 			list_one_geom(gp);
 			xo_close_instance("geom");
 		}
-		xo_close_list("Geoms");
+		xo_close_list(gclass_name);
 	}
 	geom_deletetree(&mesh);
 }
@@ -1175,6 +1175,7 @@ status_one_geom(struct ggeom *gp, int script, int name_len, int status_len)
 {
 	struct gconsumer *cp;
 	struct gconfig *conf;
+	char fmt[64];
 	const char *name, *status, *cstate, *csyncr;
 	int gotone, len;
 
@@ -1196,28 +1197,36 @@ status_one_geom(struct ggeom *gp, int script, int name_len, int status_len)
 		csyncr = status_one_consumer(cp, "synchronized");
 		if (!gotone || script) {
 			if (!gotone) {
-				xo_emit("{:name/%*s}  {:status/%*s}  ",
+				xo_emit("{t:name/%*s}  {t:status/%*s}  ",
 				    name_len, name, status_len, status);
+				xo_open_list("components");
 			} else {
-				xo_emit("{d:name/%*s}  {d:status/%*s}  ",
+				/*
+				 * XXX: running the same xo_emit() as above or
+				 * variations of it will cause the XML/JSON to
+				 * produce extra "components" lists in script
+				 * mode
+				 */
+
+				snprintf(fmt, sizeof(fmt), "%*s  %*s  ",
 				    name_len, name, status_len, status);
+				xo_emit(fmt);
 			}
-			xo_open_list("components");
 		}
 
 		xo_open_instance("components");
 		if (cstate != NULL && csyncr != NULL) {
 			xo_emit("{P:/%*s}{:component} ({:state}, {:synchronized})\n",
-			len, "", cp->lg_provider->lg_name, cstate, csyncr);
+			    len, "", cp->lg_provider->lg_name, cstate, csyncr);
 		} else if (cstate != NULL) {
 			xo_emit("{P:/%*s}{:component} ({:state})\n",
-			len, "", cp->lg_provider->lg_name, cstate);
+			    len, "", cp->lg_provider->lg_name, cstate);
 		} else if (csyncr != NULL) {
 			xo_emit("{P:/%*s}{:component} ({:synchronized})\n",
-			len, "", cp->lg_provider->lg_name, csyncr);
+			    len, "", cp->lg_provider->lg_name, csyncr);
 		} else {
 			xo_emit("{P:/%*s}{:component}\n",
-			len, "", cp->lg_provider->lg_name);
+			    len, "", cp->lg_provider->lg_name);
 		}
 		xo_close_instance("components");
 		gotone = 1;
@@ -1225,13 +1234,11 @@ status_one_geom(struct ggeom *gp, int script, int name_len, int status_len)
 			len = name_len + status_len + 4;
 	}
 	if (!gotone) {
-		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:component}\n", len, "", "N/A");
-		xo_close_instance("components");
+		xo_emit("{t:name/%*s}  {t:status/%*s}  N/A\n",
+		    name_len, name, status_len, status);
+	} else {
+		xo_close_list("components");
 	}
-	xo_close_list("components");
 	xo_close_instance("status");
 }
 
@@ -1242,6 +1249,7 @@ status_one_geom_prs(struct ggeom *gp, int script, int name_len, int status_len)
 	struct gconsumer *cp;
 	struct gconfig *conf;
 	const char *name, *status, *cstate, *csyncr;
+	char fmt[64];
 	int gotone, len;
 
 	xo_open_instance("status");
@@ -1269,28 +1277,37 @@ status_one_geom_prs(struct ggeom *gp, int script, int name_len, int status_len)
 			csyncr = status_one_consumer(cp, "synchronized");
 			if (!gotone || script) {
 				if (!gotone) {
-					xo_emit("{:name/%*s}  {:status/%*s}  ",
+					xo_emit("{t:name/%*s}  {t:status/%*s}  ",
 					    name_len, name, status_len, status);
+					xo_open_list("components");
 				} else {
-					xo_emit("{d:name/%*s}  {d:status/%*s}  ",
+					/*
+					 * XXX: running the same xo_emit() as
+					 * above or variations of it will
+					 * cause the XML/JSON to produce
+					 * extra "components" lists in
+					 * script mode
+					 */
+
+					snprintf(fmt, sizeof(fmt), "%*s  %*s  ",
 					    name_len, name, status_len, status);
+					xo_emit(fmt);
 				}
-				xo_open_list("components");
 			}
 
 			xo_open_instance("component");
 			if (cstate != NULL && csyncr != NULL) {
 				xo_emit("{P:/%*s}{:component} ({:state}, {:synchronized})\n",
-				len, "", cp->lg_provider->lg_name, cstate, csyncr);
+				    len, "", cp->lg_provider->lg_name, cstate, csyncr);
 			} else if (cstate != NULL) {
 				xo_emit("{P:/%*s}{:component} ({:state})\n",
-				len, "", cp->lg_provider->lg_name, cstate);
+				    len, "", cp->lg_provider->lg_name, cstate);
 			} else if (csyncr != NULL) {
 				xo_emit("{P:/%*s}{:component} ({:synchronized})\n",
-				len, "", cp->lg_provider->lg_name, csyncr);
+				    len, "", cp->lg_provider->lg_name, csyncr);
 			} else {
 				xo_emit("{P:/%*s}{:component}\n",
-				len, "", cp->lg_provider->lg_name);
+				    len, "", cp->lg_provider->lg_name);
 			}
 			xo_close_instance("component");
 			gotone = 1;
@@ -1298,13 +1315,11 @@ status_one_geom_prs(struct ggeom *gp, int script, int name_len, int status_len)
 				len = name_len + status_len + 4;
 		}
 		if (!gotone) {
-			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:component}\n", len, "", "N/A");
-			xo_close_instance("components");
+			xo_emit("{t:name/%*s}  {t:status/%*s}  N/A\n",
+			    name_len, name, status_len, status);
+		} else {
+			xo_close_list("components");
 		}
-		xo_close_list("components");
 	}
 	xo_close_instance("status");
 }
@@ -1370,7 +1385,7 @@ std_status(struct gctl_req *req, unsigned flags __unused)
 		xo_emit("{T:/%*s}  {T:/%*s}  {T:Components}\n",
 		    name_len, "Name", status_len, "Status");
 	}
-	xo_open_list("status");
+	xo_open_list(gclass_name);
 	if (nargs > 0) {
 		for (i = 0; i < nargs; i++) {
 			name = gctl_get_ascii(req, "arg%d", i);
@@ -1398,7 +1413,7 @@ std_status(struct gctl_req *req, unsigned flags __unused)
 			}
 		}
 	}
-	xo_close_list("status");
+	xo_close_list(gclass_name);
 end:
 	geom_deletetree(&mesh);
 }



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