From nobody Mon Nov 03 22:55:07 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4d0n3b4NgBz6FxM4; Mon, 03 Nov 2025 22:55:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4d0n3b1v47z3gcD; Mon, 03 Nov 2025 22:55:07 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1762210507; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=cAfaxGpUCT6GYqe4EigLkxysIqIdgneLZ9r02PQoE/E=; b=x4NNXFGogF6EcuErGq32U2rnkbIVv2tqT1A+VzLrklG33RqQUD9DB1lyyJwc8ZGgxHCw6X vNAhiUX1GcV+PGXX7V35US8dBLxeNBxvi9gKv8jDyPB97/6KoAe/d+pvvdDXWPA62e59iU De9nMJxJXRiHvWyEBJsMX/EuovZiwiTVe8RPnYHLUC/lzZggnFhvUekxfxEJu3ElfofGhb wnIrI2fgpR910awmpjzwIz9KctPvKBifn2NWOVA9yjhW22yTh5xchRzK13QGGyMEBY7HSI AnK/IbTdEqKVA1JWhYzDsuYHNFfbU7J4EbGCdnqjUN6FcfNo7bBISwQAd7yv+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1762210507; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=cAfaxGpUCT6GYqe4EigLkxysIqIdgneLZ9r02PQoE/E=; b=Yx6ahxJ2Q+1V/f+nBmkXCb1wKU1VtNdXKNDhHV22iQpGIC620YslQGjaFkjQYa746vY5LH 1YthAZ8O6JhrxAuK6/rWONl2pHq7vTXnyztGBVCJCaUqdq3+rsFhJ+rTIa5Ek4/4/MPlaO vXBhAZSIOwl4nnP3nqmTOxT3mkQoEsSmbraCjDr/3BnZ1OGO4fB/TlqTGEYwytgYu2Je7Z ilHAw33GgK+/th4Gb7LlHH5iuSWw1MdptPnKE6U8GVNnIWK5rGFr3ENk2i5eJ/fny4Xmdy P78DpOHBI/FlJk78XqLh5H0S5Z8tgfD7QdnQrY/KfMpB/EW8VZAuwm/zbk0j2A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1762210507; a=rsa-sha256; cv=none; b=YQWN6OkCy61SvreEwDDRazcrAgoLORfxwvfHKkEyJyq2mJPs5UOQhX5UNwwAfNLlpaElct pHOX/Q32yYJJqABud6QCkWOlM3n0cqt52sqIMSRX9Cu3LHv4fGJ0AAm49QCxfOmjux1aZy COMlUzwLKMpX+qB3yG0znwFqXw1X9PzjL+Ga5aeHQwEBr+yEaC5QDc+ARfzTLbfo/sPeF7 sjOXZZ+u/ZY2Yuj43kzUSf+hSiC8uZ/hzNF9hUFXObGeFy8Zj3bBAZy+Px0Q9Sqe39hG6f T8dlCq+e5JuN4R3MMjolJRb6MSdenZtEZQV8PrBs0AXYid9ftwYv8tlR0mAHTg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4d0n3b1H9YzWpZ; Mon, 03 Nov 2025 22:55:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 5A3Mt7Rr031829; Mon, 3 Nov 2025 22:55:07 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 5A3Mt7vW031826; Mon, 3 Nov 2025 22:55:07 GMT (envelope-from git) Date: Mon, 3 Nov 2025 22:55:07 GMT Message-Id: <202511032255.5A3Mt7vW031826@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kirk McKusick Subject: git: c174f518c9c8 - main - Refinements to the --libxo support for geom status and list sub commands. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mckusick X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: c174f518c9c8cf3a567c5f60414508ac951a2ae4 Auto-Submitted: auto-generated The branch main has been updated by mckusick: URL: https://cgit.FreeBSD.org/src/commit/?id=c174f518c9c8cf3a567c5f60414508ac951a2ae4 commit c174f518c9c8cf3a567c5f60414508ac951a2ae4 Author: Kirk McKusick AuthorDate: 2025-11-03 22:54:13 +0000 Commit: Kirk McKusick 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); }