Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F103010920
D34529.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
D34529.diff
View Options
diff --git a/lib/geom/mirror/geom_mirror.c b/lib/geom/mirror/geom_mirror.c
--- a/lib/geom/mirror/geom_mirror.c
+++ b/lib/geom/mirror/geom_mirror.c
@@ -440,32 +440,30 @@
struct gconsumer *cp;
off_t size;
int error, nargs;
- const char *name;
+ const char *name, *g;
char ssize[30];
nargs = gctl_get_int(req, "nargs");
- if (nargs < 1) {
- gctl_error(req, "Too few arguments.");
- return;
- }
- error = geom_gettree(&mesh);
- if (error)
- errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
+ if (nargs != 1)
+ errx(EXIT_FAILURE, "Invalid number of arguments.");
name = gctl_get_ascii(req, "class");
if (name == NULL)
abort();
+ g = gctl_get_ascii(req, "arg0");
+ if (g == NULL)
+ abort();
+ error = geom_gettree_geom(&mesh, name, g, 1);
+ if (error)
+ errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
classp = find_class(&mesh, name);
if (classp == NULL)
errx(EXIT_FAILURE, "Class %s not found.", name);
- name = gctl_get_ascii(req, "arg0");
- if (name == NULL)
- abort();
- gp = find_geom(classp, name);
+ gp = find_geom(classp, g);
if (gp == NULL)
- errx(EXIT_FAILURE, "No such geom: %s.", name);
+ errx(EXIT_FAILURE, "No such geom: %s.", g);
pp = LIST_FIRST(&gp->lg_provider);
if (pp == NULL)
- errx(EXIT_FAILURE, "Provider of geom %s not found.", name);
+ errx(EXIT_FAILURE, "Provider of geom %s not found.", g);
size = pp->lg_mediasize;
name = gctl_get_ascii(req, "size");
if (name == NULL)
diff --git a/lib/geom/part/geom_part.c b/lib/geom/part/geom_part.c
--- a/lib/geom/part/geom_part.c
+++ b/lib/geom/part/geom_part.c
@@ -329,31 +329,31 @@
struct gprovider *pp;
off_t last, size, start, new_size;
off_t lba, new_lba, alignment, offset;
- const char *s;
+ const char *g, *s;
int error, idx, has_alignment;
idx = (int)gctl_get_intmax(req, GPART_PARAM_INDEX);
if (idx < 1)
errx(EXIT_FAILURE, "invalid partition index");
- error = geom_gettree(&mesh);
- if (error)
- return (error);
s = gctl_get_ascii(req, "class");
if (s == NULL)
abort();
+ g = gctl_get_ascii(req, "arg0");
+ if (g == NULL)
+ abort();
+ error = geom_gettree_geom(&mesh, s, g, 1);
+ if (error)
+ return (error);
cp = find_class(&mesh, s);
if (cp == NULL)
errx(EXIT_FAILURE, "Class %s not found.", s);
- s = gctl_get_ascii(req, "arg0");
- if (s == NULL)
- abort();
- gp = find_geom(cp, s);
+ gp = find_geom(cp, g);
if (gp == NULL)
- errx(EXIT_FAILURE, "No such geom: %s.", s);
+ errx(EXIT_FAILURE, "No such geom: %s.", g);
pp = LIST_FIRST(&gp->lg_consumer)->lg_provider;
if (pp == NULL)
- errx(EXIT_FAILURE, "Provider for geom %s not found.", s);
+ errx(EXIT_FAILURE, "Provider for geom %s not found.", g);
s = gctl_get_ascii(req, "alignment");
has_alignment = (*s == '*') ? 0 : 1;
@@ -454,7 +454,7 @@
off_t size, start, a_lba;
off_t lba, len, alignment, offset;
uintmax_t grade;
- const char *s;
+ const char *g, *s;
int error, has_size, has_start, has_alignment;
s = gctl_get_ascii(req, "verb");
@@ -463,22 +463,22 @@
if (strcmp(s, "add") != 0)
return (0);
- error = geom_gettree(&mesh);
- if (error)
- return (error);
s = gctl_get_ascii(req, "class");
if (s == NULL)
abort();
+ g = gctl_get_ascii(req, "arg0");
+ if (g == NULL)
+ abort();
+ error = geom_gettree_geom(&mesh, s, g, 1);
+ if (error)
+ return (error);
cp = find_class(&mesh, s);
if (cp == NULL)
errx(EXIT_FAILURE, "Class %s not found.", s);
- s = gctl_get_ascii(req, "arg0");
- if (s == NULL)
- abort();
- gp = find_geom(cp, s);
+ gp = find_geom(cp, g);
if (gp == NULL) {
- if (g_device_path(s) == NULL) {
- errx(EXIT_FAILURE, "No such geom %s.", s);
+ if (g_device_path(g) == NULL) {
+ errx(EXIT_FAILURE, "No such geom %s.", g);
} else {
/*
* We don't free memory allocated by g_device_path() as
@@ -486,12 +486,12 @@
*/
errx(EXIT_FAILURE,
"No partitioning scheme found on geom %s. Create one first using 'gpart create'.",
- s);
+ g);
}
}
pp = LIST_FIRST(&gp->lg_consumer)->lg_provider;
if (pp == NULL)
- errx(EXIT_FAILURE, "Provider for geom %s not found.", s);
+ errx(EXIT_FAILURE, "Provider for geom %s not found.", g);
s = gctl_get_ascii(req, "alignment");
has_alignment = (*s == '*') ? 0 : 1;
@@ -742,7 +742,12 @@
name = gctl_get_ascii(req, "class");
if (name == NULL)
abort();
- error = geom_gettree(&mesh);
+ nargs = gctl_get_int(req, "nargs");
+ if (nargs == 1) {
+ error = geom_gettree_geom(&mesh, name,
+ gctl_get_ascii(req, "arg0"), 1);
+ } else
+ error = geom_gettree(&mesh);
if (error != 0)
errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
classp = find_class(&mesh, name);
@@ -751,7 +756,6 @@
errx(EXIT_FAILURE, "Class %s not found.", name);
}
show_providers = gctl_get_int(req, "show_providers");
- nargs = gctl_get_int(req, "nargs");
if (nargs > 0) {
for (i = 0; i < nargs; i++) {
name = gctl_get_ascii(req, "arg%d", i);
@@ -776,34 +780,33 @@
struct gclass *classp;
struct gprovider *pp;
struct ggeom *gp;
- const char *s, *scheme;
+ const char *g, *s, *scheme;
off_t sector, end;
off_t length;
int error, i, windex, wblocks, wtype;
if (gctl_get_int(req, "nargs") != 1)
errx(EXIT_FAILURE, "Invalid number of arguments.");
- error = geom_gettree(&mesh);
- if (error != 0)
- errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
s = gctl_get_ascii(req, "class");
if (s == NULL)
abort();
+ g = gctl_get_ascii(req, "arg0");
+ if (g == NULL)
+ abort();
+ error = geom_gettree_geom(&mesh, s, g, 0);
+ if (error != 0)
+ errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
classp = find_class(&mesh, s);
if (classp == NULL) {
geom_deletetree(&mesh);
errx(EXIT_FAILURE, "Class %s not found.", s);
}
- s = gctl_get_ascii(req, "arg0");
- if (s == NULL)
- abort();
- gp = find_geom(classp, s);
+ gp = find_geom(classp, g);
if (gp == NULL)
- errx(EXIT_FAILURE, "No such geom: %s.", s);
+ errx(EXIT_FAILURE, "No such geom: %s.", g);
scheme = find_geomcfg(gp, "scheme");
if (scheme == NULL)
abort();
- pp = LIST_FIRST(&gp->lg_consumer)->lg_provider;
s = find_geomcfg(gp, "last");
if (s == NULL)
abort();
@@ -1201,11 +1204,14 @@
struct gmesh mesh;
struct gclass *classp;
struct ggeom *gp;
- const char *s;
+ const char *g, *s;
void *bootcode, *partcode;
size_t bootsize, partsize;
int error, idx, vtoc8;
+ if (gctl_get_int(req, "nargs") != 1)
+ errx(EXIT_FAILURE, "Invalid number of arguments.");
+
if (gctl_has_param(req, GPART_PARAM_BOOTCODE)) {
s = gctl_get_ascii(req, GPART_PARAM_BOOTCODE);
bootsize = 800 * 1024; /* Arbitrary limit. */
@@ -1228,7 +1234,10 @@
s = gctl_get_ascii(req, "class");
if (s == NULL)
abort();
- error = geom_gettree(&mesh);
+ g = gctl_get_ascii(req, "arg0");
+ if (g == NULL)
+ abort();
+ error = geom_gettree_geom(&mesh, s, g, 0);
if (error != 0)
errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
classp = find_class(&mesh, s);
@@ -1236,14 +1245,9 @@
geom_deletetree(&mesh);
errx(EXIT_FAILURE, "Class %s not found.", s);
}
- if (gctl_get_int(req, "nargs") != 1)
- errx(EXIT_FAILURE, "Invalid number of arguments.");
- s = gctl_get_ascii(req, "arg0");
- if (s == NULL)
- abort();
- gp = find_geom(classp, s);
+ gp = find_geom(classp, g);
if (gp == NULL)
- errx(EXIT_FAILURE, "No such geom: %s.", s);
+ errx(EXIT_FAILURE, "No such geom: %s.", g);
s = find_geomcfg(gp, "scheme");
if (s == NULL)
errx(EXIT_FAILURE, "Scheme not found for geom %s", gp->lg_name);
diff --git a/lib/libgeom/geom_getxml.c b/lib/libgeom/geom_getxml.c
--- a/lib/libgeom/geom_getxml.c
+++ b/lib/libgeom/geom_getxml.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2003 Poul-Henning Kamp
* All rights reserved.
+ * Copyright (c) 2022 Alexander Motin <mav@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -50,6 +51,13 @@
*/
#define GEOM_GETXML_RETRIES 4
+/*
+ * Size of confxml buffer to request via getxml control request. It is
+ * expected to be sufficient for single geom and its parents. In case of
+ * overflow fall back to requesting full confxml via sysctl interface.
+ */
+#define GEOM_GETXML_BUFFER 65536
+
char *
geom_getxml(void)
{
@@ -87,3 +95,36 @@
return (NULL);
}
+
+char *
+geom_getxml_geom(const char *class, const char *geom, int parents)
+{
+ struct gctl_req *r;
+ char *p;
+ const char *errstr;
+ int nargs = 0;
+
+ p = malloc(GEOM_GETXML_BUFFER);
+ if (p == NULL)
+ return (NULL);
+ r = gctl_get_handle();
+ gctl_ro_param(r, "class", -1, class);
+ gctl_ro_param(r, "verb", -1, "getxml");
+ gctl_ro_param(r, "parents", sizeof(parents), &parents);
+ if (geom) {
+ gctl_ro_param(r, "arg0", -1, geom);
+ nargs = 1;
+ }
+ gctl_ro_param(r, "nargs", sizeof(nargs), &nargs);
+ p[0] = '\0';
+ gctl_add_param(r, "output", GEOM_GETXML_BUFFER, p,
+ GCTL_PARAM_WR | GCTL_PARAM_ASCII);
+ errstr = gctl_issue(r);
+ if (errstr != NULL && errstr[0] != '\0') {
+ gctl_free(r);
+ free(p);
+ return (geom_getxml());
+ }
+ gctl_free(r);
+ return (p);
+}
diff --git a/lib/libgeom/geom_xml2tree.c b/lib/libgeom/geom_xml2tree.c
--- a/lib/libgeom/geom_xml2tree.c
+++ b/lib/libgeom/geom_xml2tree.c
@@ -358,6 +358,17 @@
return (NULL);
}
+static void *
+geom_lookupidptr(struct gmesh *gmp, const void *id)
+{
+ struct gident *gip;
+
+ gip = geom_lookupid(gmp, id);
+ if (gip)
+ return (gip->lg_ptr);
+ return (NULL);
+}
+
int
geom_xml2tree(struct gmesh *gmp, char *p)
{
@@ -430,22 +441,19 @@
/* Substitute all identifiers */
LIST_FOREACH(cl, &gmp->lg_class, lg_class) {
LIST_FOREACH(ge, &cl->lg_geom, lg_geom) {
- ge->lg_class =
- geom_lookupid(gmp, ge->lg_class)->lg_ptr;
- LIST_FOREACH(pr, &ge->lg_provider, lg_provider) {
- pr->lg_geom =
- geom_lookupid(gmp, pr->lg_geom)->lg_ptr;
- }
+ ge->lg_class = geom_lookupidptr(gmp, ge->lg_class);
+ LIST_FOREACH(pr, &ge->lg_provider, lg_provider)
+ pr->lg_geom = geom_lookupidptr(gmp, pr->lg_geom);
LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) {
- co->lg_geom =
- geom_lookupid(gmp, co->lg_geom)->lg_ptr;
+ co->lg_geom = geom_lookupidptr(gmp, co->lg_geom);
if (co->lg_provider != NULL) {
- co->lg_provider =
- geom_lookupid(gmp,
- co->lg_provider)->lg_ptr;
- LIST_INSERT_HEAD(
- &co->lg_provider->lg_consumers,
- co, lg_consumers);
+ co->lg_provider = geom_lookupidptr(gmp,
+ co->lg_provider);
+ if (co->lg_provider != NULL) {
+ LIST_INSERT_HEAD(
+ &co->lg_provider->lg_consumers,
+ co, lg_consumers);
+ }
}
}
}
@@ -467,6 +475,20 @@
return (error);
}
+int
+geom_gettree_geom(struct gmesh *gmp, const char *c, const char *g, int parents)
+{
+ char *p;
+ int error;
+
+ p = geom_getxml_geom(c, g, parents);
+ if (p == NULL)
+ return (errno);
+ error = geom_xml2tree(gmp, p);
+ free(p);
+ return (error);
+}
+
static void
delete_config(struct gconf *gp)
{
diff --git a/lib/libgeom/libgeom.h b/lib/libgeom/libgeom.h
--- a/lib/libgeom/libgeom.h
+++ b/lib/libgeom/libgeom.h
@@ -56,6 +56,7 @@
struct devstat *geom_stats_snapshot_next(void *);
char *geom_getxml(void);
+char *geom_getxml_geom(const char *, const char *, int);
/* geom_xml2tree.c */
@@ -137,6 +138,7 @@
struct gident * geom_lookupid(struct gmesh *, const void *);
int geom_xml2tree(struct gmesh *, char *);
int geom_gettree(struct gmesh *);
+int geom_gettree_geom(struct gmesh *, const char *, const char *, int);
void geom_deletetree(struct gmesh *);
/* geom_ctl.c */
diff --git a/sbin/geom/core/geom.c b/sbin/geom/core/geom.c
--- a/sbin/geom/core/geom.c
+++ b/sbin/geom/core/geom.c
@@ -996,7 +996,7 @@
struct gclass *classp;
int error;
- error = geom_gettree(&mesh);
+ error = geom_gettree_geom(&mesh, gclass_name, "", 0);
if (error != 0)
errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
classp = find_class(&mesh, gclass_name);
@@ -1015,7 +1015,12 @@
const char *name;
int all, error, i, nargs;
- error = geom_gettree(&mesh);
+ nargs = gctl_get_int(req, "nargs");
+ if (nargs == 1) {
+ error = geom_gettree_geom(&mesh, gclass_name,
+ gctl_get_ascii(req, "arg0"), 1);
+ } else
+ error = geom_gettree(&mesh);
if (error != 0)
errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
classp = find_class(&mesh, gclass_name);
@@ -1023,7 +1028,6 @@
geom_deletetree(&mesh);
errx(EXIT_FAILURE, "Class '%s' not found.", gclass_name);
}
- nargs = gctl_get_int(req, "nargs");
all = gctl_get_int(req, "all");
if (nargs > 0) {
for (i = 0; i < nargs; i++) {
diff --git a/sys/geom/geom.h b/sys/geom/geom.h
--- a/sys/geom/geom.h
+++ b/sys/geom/geom.h
@@ -431,6 +431,7 @@
int gctl_set_param(struct gctl_req *req, const char *param, void const *ptr, int len);
void gctl_set_param_err(struct gctl_req *req, const char *param, void const *ptr, int len);
void *gctl_get_param(struct gctl_req *req, const char *param, int *len);
+void *gctl_get_param_flags(struct gctl_req *req, const char *param, int flags, int *len);
char const *gctl_get_asciiparam(struct gctl_req *req, const char *param);
void *gctl_get_paraml(struct gctl_req *req, const char *param, int len);
void *gctl_get_paraml_opt(struct gctl_req *req, const char *param, int len);
diff --git a/sys/geom/geom_ctl.c b/sys/geom/geom_ctl.c
--- a/sys/geom/geom_ctl.c
+++ b/sys/geom/geom_ctl.c
@@ -4,6 +4,7 @@
* Copyright (c) 2002 Poul-Henning Kamp
* Copyright (c) 2002 Networks Associates Technology, Inc.
* All rights reserved.
+ * Copyright (c) 2022 Alexander Motin <mav@FreeBSD.org>
*
* This software was developed for the FreeBSD Project by Poul-Henning Kamp
* and NAI Labs, the Security Research Division of Network Associates, Inc.
@@ -363,7 +364,7 @@
}
void *
-gctl_get_param(struct gctl_req *req, const char *param, int *len)
+gctl_get_param_flags(struct gctl_req *req, const char *param, int flags, int *len)
{
u_int i;
void *p;
@@ -373,7 +374,7 @@
ap = &req->arg[i];
if (strcmp(param, ap->name))
continue;
- if (!(ap->flag & GCTL_PARAM_RD))
+ if ((ap->flag & flags) != flags)
continue;
p = ap->kvalue;
if (len != NULL)
@@ -383,31 +384,31 @@
return (NULL);
}
+void *
+gctl_get_param(struct gctl_req *req, const char *param, int *len)
+{
+
+ return (gctl_get_param_flags(req, param, GCTL_PARAM_RD, len));
+}
+
char const *
gctl_get_asciiparam(struct gctl_req *req, const char *param)
{
- u_int i;
char const *p;
- struct gctl_req_arg *ap;
+ int len;
- for (i = 0; i < req->narg; i++) {
- ap = &req->arg[i];
- if (strcmp(param, ap->name))
- continue;
- if (!(ap->flag & GCTL_PARAM_RD))
- continue;
- p = ap->kvalue;
- if (ap->len < 1) {
- gctl_error(req, "No length argument (%s)", param);
- return (NULL);
- }
- if (p[ap->len - 1] != '\0') {
- gctl_error(req, "Unterminated argument (%s)", param);
- return (NULL);
- }
- return (p);
+ p = gctl_get_param_flags(req, param, GCTL_PARAM_RD, &len);
+ if (p == NULL)
+ return (NULL);
+ if (len < 1) {
+ gctl_error(req, "Argument without length (%s)", param);
+ return (NULL);
}
- return (NULL);
+ if (p[len - 1] != '\0') {
+ gctl_error(req, "Unterminated argument (%s)", param);
+ return (NULL);
+ }
+ return (p);
}
void *
@@ -491,6 +492,62 @@
return (NULL);
}
+static void
+g_ctl_getxml(struct gctl_req *req, struct g_class *mp)
+{
+ const char *name;
+ char *buf;
+ struct sbuf *sb;
+ int len, i = 0, n = 0, *parents;
+ struct g_geom *gp, **gps;
+ struct g_consumer *cp;
+
+ parents = gctl_get_paraml(req, "parents", sizeof(*parents));
+ if (parents == NULL)
+ return;
+ name = gctl_get_asciiparam(req, "arg0");
+ n = 0;
+ LIST_FOREACH(gp, &mp->geom, geom) {
+ if (name && strcmp(gp->name, name) != 0)
+ continue;
+ n++;
+ if (*parents) {
+ LIST_FOREACH(cp, &gp->consumer, consumer)
+ n++;
+ }
+ }
+ gps = g_malloc((n + 1) * sizeof(*gps), M_WAITOK);
+ i = 0;
+ LIST_FOREACH(gp, &mp->geom, geom) {
+ if (name && strcmp(gp->name, name) != 0)
+ continue;
+ gps[i++] = gp;
+ if (*parents) {
+ LIST_FOREACH(cp, &gp->consumer, consumer) {
+ if (cp->provider != NULL)
+ gps[i++] = cp->provider->geom;
+ }
+ }
+ }
+ KASSERT(i == n, ("different number of geoms found (%d != %d)",
+ i, n));
+ gps[i] = 0;
+
+ buf = gctl_get_param_flags(req, "output", GCTL_PARAM_WR, &len);
+ if (buf == NULL) {
+ gctl_error(req, "output parameter missing");
+ g_free(gps);
+ return;
+ }
+ sb = sbuf_new(NULL, buf, len, SBUF_FIXEDLEN | SBUF_INCLUDENUL);
+ g_conf_specific(sb, gps);
+ gctl_set_param(req, "output", buf, 0);
+ if (sbuf_error(sb))
+ gctl_error(req, "output buffer overflow");
+ sbuf_delete(sb);
+ g_free(gps);
+}
+
static void
g_ctl_req(void *arg, int flag __unused)
{
@@ -503,16 +560,18 @@
mp = gctl_get_class(req, "class");
if (mp == NULL)
return;
- if (mp->ctlreq == NULL) {
- gctl_error(req, "Class takes no requests");
- return;
- }
verb = gctl_get_param(req, "verb", NULL);
if (verb == NULL) {
gctl_error(req, "Verb missing");
return;
}
- mp->ctlreq(req, mp, verb);
+ if (strcmp(verb, "getxml") == 0) {
+ g_ctl_getxml(req, mp);
+ } else if (mp->ctlreq == NULL) {
+ gctl_error(req, "Class takes no requests");
+ } else {
+ mp->ctlreq(req, mp, verb);
+ }
g_topology_assert();
}
diff --git a/sys/geom/geom_dump.c b/sys/geom/geom_dump.c
--- a/sys/geom/geom_dump.c
+++ b/sys/geom/geom_dump.c
@@ -4,6 +4,7 @@
* Copyright (c) 2002 Poul-Henning Kamp
* Copyright (c) 2002 Networks Associates Technology, Inc.
* All rights reserved.
+ * Copyright (c) 2013-2022 Alexander Motin <mav@FreeBSD.org>
*
* This software was developed for the FreeBSD Project by Poul-Henning Kamp
* and NAI Labs, the Security Research Division of Network Associates, Inc.
@@ -242,10 +243,10 @@
}
static void
-g_conf_geom(struct sbuf *sb, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
+g_conf_geom(struct sbuf *sb, struct g_geom *gp)
{
- struct g_consumer *cp2;
- struct g_provider *pp2;
+ struct g_consumer *cp;
+ struct g_provider *pp;
sbuf_printf(sb, " <geom id=\"%p\">\n", gp);
sbuf_printf(sb, " <class ref=\"%p\"/>\n", gp->class);
@@ -260,48 +261,56 @@
gp->dumpconf(sb, "\t", gp, NULL, NULL);
sbuf_cat(sb, " </config>\n");
}
- LIST_FOREACH(cp2, &gp->consumer, consumer) {
- if (cp != NULL && cp != cp2)
- continue;
- g_conf_consumer(sb, cp2);
- }
+ LIST_FOREACH(cp, &gp->consumer, consumer)
+ g_conf_consumer(sb, cp);
+ LIST_FOREACH(pp, &gp->provider, provider)
+ g_conf_provider(sb, pp);
+ sbuf_cat(sb, " </geom>\n");
+}
- LIST_FOREACH(pp2, &gp->provider, provider) {
- if (pp != NULL && pp != pp2)
- continue;
- g_conf_provider(sb, pp2);
+static bool
+g_conf_matchgp(struct g_geom *gp, struct g_geom **gps)
+{
+
+ if (gps == NULL)
+ return (true);
+ for (; *gps != NULL; gps++) {
+ if (*gps == gp)
+ return (true);
}
- sbuf_cat(sb, " </geom>\n");
+ return (false);
}
static void
-g_conf_class(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
+g_conf_class(struct sbuf *sb, struct g_class *mp, struct g_geom **gps)
{
- struct g_geom *gp2;
+ struct g_geom *gp;
sbuf_printf(sb, " <class id=\"%p\">\n", mp);
sbuf_cat(sb, " <name>");
g_conf_cat_escaped(sb, mp->name);
sbuf_cat(sb, "</name>\n");
- LIST_FOREACH(gp2, &mp->geom, geom) {
- if (gp != NULL && gp != gp2)
+ LIST_FOREACH(gp, &mp->geom, geom) {
+ if (!g_conf_matchgp(gp, gps))
continue;
- g_conf_geom(sb, gp2, pp, cp);
+ g_conf_geom(sb, gp);
+ if (sbuf_error(sb))
+ break;
}
sbuf_cat(sb, " </class>\n");
}
void
-g_conf_specific(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
+g_conf_specific(struct sbuf *sb, struct g_geom **gps)
{
struct g_class *mp2;
g_topology_assert();
sbuf_cat(sb, "<mesh>\n");
LIST_FOREACH(mp2, &g_classes, class) {
- if (mp != NULL && mp != mp2)
- continue;
- g_conf_class(sb, mp2, gp, pp, cp);
+ g_conf_class(sb, mp2, gps);
+ if (sbuf_error(sb))
+ break;
}
sbuf_cat(sb, "</mesh>\n");
sbuf_finish(sb);
@@ -313,7 +322,7 @@
KASSERT(flag != EV_CANCEL, ("g_confxml was cancelled"));
g_topology_assert();
- g_conf_specific(p, NULL, NULL, NULL, NULL);
+ g_conf_specific(p, NULL);
}
void
diff --git a/sys/geom/geom_int.h b/sys/geom/geom_int.h
--- a/sys/geom/geom_int.h
+++ b/sys/geom/geom_int.h
@@ -46,7 +46,7 @@
/* geom_dump.c */
void g_confxml(void *, int flag);
-void g_conf_specific(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp);
+void g_conf_specific(struct sbuf *sb, struct g_geom **gps);
void g_conf_cat_escaped(struct sbuf *sb, const char *buf);
void g_conf_printf_escaped(struct sbuf *sb, const char *fmt, ...);
void g_confdot(void *, int flag);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 20, 7:24 PM (20 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14745589
Default Alt Text
D34529.diff (20 KB)
Attached To
Mode
D34529: GEOM: Introduce partial confxml API
Attached
Detach File
Event Timeline
Log In to Comment