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:
Pawel Jakub Dawidek 2004-07-26 17:14:47 +00:00
parent 889c5dc22b
commit 1d723f1d51
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=132665
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);
switch (sc->sc_type) {
case G_CONCAT_TYPE_AUTOMATIC:
sbuf_printf(sb, "%s<type>%s</type>\n", indent, "automatic");
break;
case G_CONCAT_TYPE_MANUAL:
sbuf_printf(sb, "%s<type>%s</type>\n", indent, "manual");
break;
default:
sbuf_printf(sb, "%s<type>%s</type>\n", indent, "unknown");
break;
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, "AUTOMATIC");
break;
case G_CONCAT_TYPE_MANUAL:
sbuf_printf(sb, "MANUAL");
break;
default:
sbuf_printf(sb, "UNKNOWN");
break;
}
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, "DOWN");
sbuf_printf(sb, "</State>\n");
}
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);
else
sbuf_printf(sb, "%s<state>DOWN</state>\n", indent);
}
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,
(u_int)sc->sc_stripesize);
switch (sc->sc_type) {
case G_STRIPE_TYPE_AUTOMATIC:
sbuf_printf(sb, "%s<type>%s</type>\n", indent, "automatic");
break;
case G_STRIPE_TYPE_MANUAL:
sbuf_printf(sb, "%s<type>%s</type>\n", indent, "manual");
break;
default:
sbuf_printf(sb, "%s<type>%s</type>\n", indent, "unknown");
break;
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, "AUTOMATIC");
break;
case G_STRIPE_TYPE_MANUAL:
sbuf_printf(sb, "MANUAL");
break;
default:
sbuf_printf(sb, "UNKNOWN");
break;
}
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, "DOWN");
sbuf_printf(sb, "</State>\n");
}
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);
else
sbuf_printf(sb, "%s<state>DOWN</state>\n", indent);
}
DECLARE_GEOM_CLASS(g_stripe_class, g_stripe);