Improve geom(8)'s 'list' command to show geoms and their providers and

consumers. Teach STRIPE, CONCAT and NOP classes about this improvement.
This commit is contained in:
pjd 2004-07-26 17:14:47 +00:00
parent 3a2f13d5f5
commit 73a684d587
7 changed files with 146 additions and 111 deletions

View File

@ -66,7 +66,7 @@
.Op Ar dev2 Op Ar ...
.Nm
.Cm list
.Op Ar prov Op Ar ...
.Op Ar name Op Ar ...
.Nm
.Cm load
.Op Fl v

View File

@ -68,7 +68,7 @@
.Op Ar dev2 Op Ar ...
.Nm
.Cm list
.Op Ar prov Op Ar ...
.Op Ar name Op Ar ...
.Nm
.Cm load
.Op Fl v

View File

@ -50,8 +50,8 @@ Here is the list of standard commands:
.It Cm help
List all available commands for the given class.
.It Cm list
Print detailed information (within the given class) about all providers
(if no additional arguments were specified) or the given providers.
Print detailed information (within the given class) about all geoms
(if no additional arguments were specified) or the given geoms.
This command is only available if the given class exists in the kernel.
.It Cm load
Load the kernel module that implements the given class.

View File

@ -548,57 +548,88 @@ find_class(struct gmesh *mesh, const char *name)
return (NULL);
}
static struct gprovider *
find_provider(struct gclass *classp, const char *name)
static struct ggeom *
find_geom(struct gclass *classp, const char *name)
{
struct ggeom *gp;
struct gprovider *pp;
LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
if (strcmp(pp->lg_name, name) == 0)
return (pp);
}
if (strcmp(gp->lg_name, name) == 0)
return (gp);
}
return (NULL);
}
static char *
genspaces(const char *text, size_t len)
{
static char spaces[256];
size_t outlen;
if (strlen(text) >= len) {
spaces[0] = '\0';
return (spaces);
}
memset(spaces, ' ', sizeof(spaces));
outlen = len - strlen(text);
if (outlen >= sizeof(spaces)) {
spaces[sizeof(spaces) - 1] = '\0';
return (spaces);
}
spaces[outlen] = '\0';
return (spaces);
}
static void
show_one(struct gprovider *pp)
show_one_provider(struct gprovider *pp, const char *prefix)
{
struct gconfig *conf;
char buf[5];
printf(" NAME: %s\n", pp->lg_name);
printf(" geom name: %s\n", pp->lg_geom->lg_name);
printf("Name: %s\n", pp->lg_name);
humanize_number(buf, sizeof(buf), (int64_t)pp->lg_mediasize, "",
HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
printf(" mediasize: %jd (%s)\n", (intmax_t)pp->lg_mediasize, buf);
printf(" sectorsize: %u\n", pp->lg_sectorsize);
printf(" mode: %s\n", pp->lg_mode);
printf("%sMediasize: %jd (%s)\n", prefix, (intmax_t)pp->lg_mediasize,
buf);
printf("%sSectorsize: %u\n", prefix, pp->lg_sectorsize);
printf("%sMode: %s\n", prefix, pp->lg_mode);
LIST_FOREACH(conf, &pp->lg_config, lg_config) {
printf("%s%s: %s\n", genspaces(conf->lg_name, 11),
conf->lg_name, conf->lg_val);
printf("%s%s: %s\n", prefix, conf->lg_name, conf->lg_val);
}
}
static void
show_one_consumer(struct gconsumer *cp, const char *prefix)
{
struct gprovider *pp;
struct gconfig *conf;
pp = cp->lg_provider;
if (pp == NULL)
printf("[no provider]\n");
else {
char buf[5];
printf("Name: %s\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);
printf("%sMode: %s\n", prefix, cp->lg_mode);
}
LIST_FOREACH(conf, &cp->lg_config, lg_config) {
printf("%s%s: %s\n", prefix, conf->lg_name, conf->lg_val);
}
}
static void
show_one_geom(struct ggeom *gp)
{
struct gprovider *pp;
struct gconsumer *cp;
struct gconfig *conf;
unsigned n;
printf("Geom name: %s\n", gp->lg_name);
LIST_FOREACH(conf, &gp->lg_config, lg_config) {
printf("%s: %s\n", conf->lg_name, conf->lg_val);
}
if (!LIST_EMPTY(&gp->lg_provider)) {
printf("Providers:\n");
n = 1;
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
printf("%u. ", n++);
show_one_provider(pp, " ");
}
}
if (!LIST_EMPTY(&gp->lg_consumer)) {
printf("Consumers:\n");
n = 1;
LIST_FOREACH(cp, &gp->lg_consumer, lg_consumer) {
printf("%u. ", n++);
show_one_consumer(cp, " ");
}
}
printf("\n");
}
@ -632,7 +663,7 @@ std_list(struct gctl_req *req, unsigned flags __unused)
{
struct gmesh mesh;
struct gclass *classp;
struct gprovider *pp;
struct ggeom *gp;
int error, *nargs;
error = geom_gettree(&mesh);
@ -660,21 +691,15 @@ std_list(struct gctl_req *req, unsigned flags __unused)
snprintf(param, sizeof(param), "arg%d", i);
name = gctl_get_asciiparam(req, param);
assert(name != NULL);
pp = find_provider(classp, name);
if (pp != NULL)
show_one(pp);
else {
fprintf(stderr, "No such provider: %s.\n",
name);
}
gp = find_geom(classp, name);
if (gp != NULL)
show_one_geom(gp);
else
fprintf(stderr, "No such geom: %s.\n", name);
}
} else {
struct ggeom *gp;
LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
show_one(pp);
}
show_one_geom(gp);
}
}
geom_deletetree(&mesh);

View File

@ -798,35 +798,44 @@ g_concat_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
g_topology_assert();
sc = gp->softc;
if (sc == NULL || pp == NULL)
if (sc == NULL)
return;
sbuf_printf(sb, "%s<id>%u</id>\n", indent, (u_int)sc->sc_id);
if (pp != NULL) {
/* Nothing here. */
} else if (cp != NULL) {
struct g_concat_disk *disk;
disk = cp->private;
if (disk == NULL)
return;
sbuf_printf(sb, "%s<End>%jd</End>\n", indent,
(intmax_t)disk->d_end);
sbuf_printf(sb, "%s<Start>%jd</Start>\n", indent,
(intmax_t)disk->d_start);
} else {
sbuf_printf(sb, "%s<ID>%u</ID>\n", indent, (u_int)sc->sc_id);
sbuf_printf(sb, "%s<Type>", indent);
switch (sc->sc_type) {
case G_CONCAT_TYPE_AUTOMATIC:
sbuf_printf(sb, "%s<type>%s</type>\n", indent, "automatic");
sbuf_printf(sb, "AUTOMATIC");
break;
case G_CONCAT_TYPE_MANUAL:
sbuf_printf(sb, "%s<type>%s</type>\n", indent, "manual");
sbuf_printf(sb, "MANUAL");
break;
default:
sbuf_printf(sb, "%s<type>%s</type>\n", indent, "unknown");
sbuf_printf(sb, "UNKNOWN");
break;
}
sbuf_printf(sb, "%s<providers>", indent);
LIST_FOREACH(cp, &gp->consumer, consumer) {
if (cp->provider == NULL)
continue;
sbuf_printf(sb, "%s", cp->provider->name);
if (LIST_NEXT(cp, consumer) != NULL)
sbuf_printf(sb, " ");
}
sbuf_printf(sb, "</providers>\n");
sbuf_printf(sb, "%s<status>total=%u, online=%u</status>\n", indent,
sc->sc_ndisks, g_concat_nvalid(sc));
if (pp->error == 0)
sbuf_printf(sb, "%s<state>UP</state>\n", indent);
sbuf_printf(sb, "</Type>\n");
sbuf_printf(sb, "%s<Status>Total=%u, Online=%u</Status>\n",
indent, sc->sc_ndisks, g_concat_nvalid(sc));
sbuf_printf(sb, "%s<State>", indent);
if (sc->sc_provider != NULL && sc->sc_provider->error == 0)
sbuf_printf(sb, "UP");
else
sbuf_printf(sb, "%s<state>DOWN</state>\n", indent);
sbuf_printf(sb, "DOWN");
sbuf_printf(sb, "</State>\n");
}
}
DECLARE_GEOM_CLASS(g_concat_class, g_concat);

View File

@ -468,12 +468,12 @@ g_nop_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
{
struct g_nop_softc *sc;
if (pp == NULL)
if (pp != NULL || cp != NULL)
return;
sc = gp->softc;
sbuf_printf(sb, "%s<offset>%jd</offset>\n", indent,
sbuf_printf(sb, "%s<Offset>%jd</Offset>\n", indent,
(intmax_t)sc->sc_offset);
sbuf_printf(sb, "%s<failprob>%u</failprob>\n", indent, sc->sc_failprob);
sbuf_printf(sb, "%s<Failprob>%u</Failprob>\n", indent, sc->sc_failprob);
}
DECLARE_GEOM_CLASS(g_nop_class, g_nop);

View File

@ -1128,37 +1128,38 @@ g_stripe_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
struct g_stripe_softc *sc;
sc = gp->softc;
if (sc == NULL || pp == NULL)
if (sc == NULL)
return;
sbuf_printf(sb, "%s<id>%u</id>\n", indent, (u_int)sc->sc_id);
sbuf_printf(sb, "%s<stripesize>%u</stripesize>\n", indent,
if (pp != NULL) {
/* Nothing here. */
} else if (cp != NULL) {
/* Nothing here. */
} else {
sbuf_printf(sb, "%s<ID>%u</ID>\n", indent, (u_int)sc->sc_id);
sbuf_printf(sb, "%s<Stripesize>%u</Stripesize>\n", indent,
(u_int)sc->sc_stripesize);
sbuf_printf(sb, "%s<Type>", indent);
switch (sc->sc_type) {
case G_STRIPE_TYPE_AUTOMATIC:
sbuf_printf(sb, "%s<type>%s</type>\n", indent, "automatic");
sbuf_printf(sb, "AUTOMATIC");
break;
case G_STRIPE_TYPE_MANUAL:
sbuf_printf(sb, "%s<type>%s</type>\n", indent, "manual");
sbuf_printf(sb, "MANUAL");
break;
default:
sbuf_printf(sb, "%s<type>%s</type>\n", indent, "unknown");
sbuf_printf(sb, "UNKNOWN");
break;
}
sbuf_printf(sb, "%s<providers>", indent);
LIST_FOREACH(cp, &gp->consumer, consumer) {
if (cp->provider == NULL)
continue;
sbuf_printf(sb, "%s", cp->provider->name);
if (LIST_NEXT(cp, consumer) != NULL)
sbuf_printf(sb, " ");
}
sbuf_printf(sb, "</providers>\n");
sbuf_printf(sb, "%s<status>total=%u, online=%u</status>\n", indent,
sc->sc_ndisks, g_stripe_nvalid(sc));
if (pp->error == 0)
sbuf_printf(sb, "%s<state>UP</state>\n", indent);
sbuf_printf(sb, "</Type>\n");
sbuf_printf(sb, "%s<Status>Total=%u, Online=%u</Status>\n",
indent, sc->sc_ndisks, g_stripe_nvalid(sc));
sbuf_printf(sb, "%s<State>", indent);
if (sc->sc_provider != NULL && sc->sc_provider->error == 0)
sbuf_printf(sb, "UP");
else
sbuf_printf(sb, "%s<state>DOWN</state>\n", indent);
sbuf_printf(sb, "DOWN");
sbuf_printf(sb, "</State>\n");
}
}
DECLARE_GEOM_CLASS(g_stripe_class, g_stripe);