Add 'show geom [addr]' ddb(4) command, which prints entire GEOM topology if
no additional argument is given or details about the given GEOM object (class, geom, provider or consumer). Approved by: phk
This commit is contained in:
parent
e168227ed2
commit
556424a17a
@ -58,7 +58,7 @@
|
||||
.\" [90/08/30 dbg]
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.Dd February 27, 2006
|
||||
.Dd September 15, 2006
|
||||
.Dt DDB 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -423,6 +423,17 @@ The support of the
|
||||
modifier depends on the machine.
|
||||
If not supported, incorrect information will be displayed.
|
||||
.It Xo
|
||||
.Cm show geom
|
||||
.Op Ar addr
|
||||
.Xc
|
||||
If the
|
||||
.Ar addr
|
||||
argument is not given, displays the entire GEOM topology.
|
||||
If the
|
||||
.Ar addr
|
||||
is given, displays details about the given GEOM object (class, geom, provider
|
||||
or consumer).
|
||||
.It Xo
|
||||
.Cm show map Ns Op Cm /f
|
||||
.Ar addr
|
||||
.Xc
|
||||
|
@ -241,8 +241,10 @@ void g_wither_geom(struct g_geom *gp, int error);
|
||||
void g_wither_geom_close(struct g_geom *gp, int error);
|
||||
void g_wither_provider(struct g_provider *pp, int error);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
#if defined(DIAGNOSTIC) || defined(DDB)
|
||||
int g_valid_obj(void const *ptr);
|
||||
#endif
|
||||
#ifdef DIAGNOSTIC
|
||||
#define G_VALID_CLASS(foo) \
|
||||
KASSERT(g_valid_obj(foo) == 1, ("%p is not a g_class", foo))
|
||||
#define G_VALID_GEOM(foo) \
|
||||
|
@ -36,6 +36,8 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/devicestat.h>
|
||||
@ -53,6 +55,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <geom/geom_int.h>
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#ifdef DDB
|
||||
#include <ddb/ddb.h>
|
||||
#endif
|
||||
|
||||
struct class_list_head g_classes = LIST_HEAD_INITIALIZER(g_classes);
|
||||
static struct g_tailq_head geoms = TAILQ_HEAD_INITIALIZER(geoms);
|
||||
char *g_wait_event, *g_wait_up, *g_wait_down, *g_wait_sim;
|
||||
@ -920,7 +926,7 @@ g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
#if defined(DIAGNOSTIC) || defined(DDB)
|
||||
/*
|
||||
* This function walks (topologically unsafely) the mesh and return a
|
||||
* non-zero integer if it finds the argument pointer is an object.
|
||||
@ -954,3 +960,208 @@ g_valid_obj(void const *ptr)
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DDB
|
||||
|
||||
#define gprintf(...) do { \
|
||||
printf("%*s", indent, ""); \
|
||||
printf(__VA_ARGS__); \
|
||||
} while (0)
|
||||
#define gprintln(...) do { \
|
||||
gprintf(__VA_ARGS__); \
|
||||
printf("\n"); \
|
||||
} while (0)
|
||||
|
||||
#define ADDFLAG(obj, flag, sflag) do { \
|
||||
if ((obj)->flags & (flag)) { \
|
||||
if (comma) \
|
||||
strlcat(str, ",", size); \
|
||||
strlcat(str, (sflag), size); \
|
||||
comma = 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static char *
|
||||
provider_flags_to_string(struct g_provider *pp, char *str, size_t size)
|
||||
{
|
||||
int comma = 0;
|
||||
|
||||
bzero(str, size);
|
||||
if (pp->flags == 0) {
|
||||
strlcpy(str, "NONE", size);
|
||||
return (str);
|
||||
}
|
||||
ADDFLAG(pp, G_PF_CANDELETE, "G_PF_CANDELETE");
|
||||
ADDFLAG(pp, G_PF_WITHER, "G_PF_WITHER");
|
||||
ADDFLAG(pp, G_PF_ORPHAN, "G_PF_ORPHAN");
|
||||
return (str);
|
||||
}
|
||||
|
||||
static char *
|
||||
geom_flags_to_string(struct g_geom *gp, char *str, size_t size)
|
||||
{
|
||||
int comma = 0;
|
||||
|
||||
bzero(str, size);
|
||||
if (gp->flags == 0) {
|
||||
strlcpy(str, "NONE", size);
|
||||
return (str);
|
||||
}
|
||||
ADDFLAG(gp, G_GEOM_WITHER, "G_GEOM_WITHER");
|
||||
return (str);
|
||||
}
|
||||
static void
|
||||
db_show_geom_consumer(int indent, struct g_consumer *cp)
|
||||
{
|
||||
|
||||
if (indent == 0) {
|
||||
gprintln("consumer: %p", cp);
|
||||
gprintln(" class: %s (%p)", cp->geom->class->name,
|
||||
cp->geom->class);
|
||||
gprintln(" geom: %s (%p)", cp->geom->name, cp->geom);
|
||||
if (cp->provider == NULL)
|
||||
gprintln(" provider: none");
|
||||
else {
|
||||
gprintln(" provider: %s (%p)", cp->provider->name,
|
||||
cp->provider);
|
||||
}
|
||||
gprintln(" access: r%dw%de%d", cp->acr, cp->acw, cp->ace);
|
||||
gprintln(" spoiled: %d", cp->spoiled);
|
||||
gprintln(" nstart: %u", cp->nstart);
|
||||
gprintln(" nend: %u", cp->nend);
|
||||
} else {
|
||||
gprintf("consumer: %p (%s), access=r%dw%de%d", cp,
|
||||
cp->provider != NULL ? cp->provider->name : "none",
|
||||
cp->acr, cp->acw, cp->ace);
|
||||
if (cp->spoiled)
|
||||
printf(", spoiled=%d", cp->spoiled);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
db_show_geom_provider(int indent, struct g_provider *pp)
|
||||
{
|
||||
struct g_consumer *cp;
|
||||
char flags[64];
|
||||
|
||||
if (indent == 0) {
|
||||
gprintln("provider: %s (%p)", pp->name, pp);
|
||||
gprintln(" class: %s (%p)", pp->geom->class->name,
|
||||
pp->geom->class);
|
||||
gprintln(" geom: %s (%p)", pp->geom->name, pp->geom);
|
||||
gprintln(" mediasize: %jd", (intmax_t)pp->mediasize);
|
||||
gprintln(" sectorsize: %u", pp->sectorsize);
|
||||
gprintln(" stripesize: %u", pp->stripesize);
|
||||
gprintln(" stripeoffset: %u", pp->stripeoffset);
|
||||
gprintln(" access: r%dw%de%d", pp->acr, pp->acw,
|
||||
pp->ace);
|
||||
gprintln(" flags: %s (0x%04x)",
|
||||
provider_flags_to_string(pp, flags, sizeof(flags)),
|
||||
pp->flags);
|
||||
gprintln(" error: %d", pp->error);
|
||||
gprintln(" nstart: %u", pp->nstart);
|
||||
gprintln(" nend: %u", pp->nend);
|
||||
if (LIST_EMPTY(&pp->consumers))
|
||||
gprintln(" consumers: none");
|
||||
} else {
|
||||
gprintf("provider: %s (%p), access=r%dw%de%d",
|
||||
pp->name, pp, pp->acr, pp->acw, pp->ace);
|
||||
if (pp->flags != 0) {
|
||||
printf(", flags=%s (0x%04x)",
|
||||
provider_flags_to_string(pp, flags, sizeof(flags)),
|
||||
pp->flags);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if (!LIST_EMPTY(&pp->consumers)) {
|
||||
LIST_FOREACH(cp, &pp->consumers, consumers)
|
||||
db_show_geom_consumer(indent + 2, cp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
db_show_geom_geom(int indent, struct g_geom *gp)
|
||||
{
|
||||
struct g_provider *pp;
|
||||
struct g_consumer *cp;
|
||||
char flags[64];
|
||||
|
||||
if (indent == 0) {
|
||||
gprintln("geom: %s (%p)", gp->name, gp);
|
||||
gprintln(" class: %s (%p)", gp->class->name, gp->class);
|
||||
gprintln(" flags: %s (0x%04x)",
|
||||
geom_flags_to_string(gp, flags, sizeof(flags)), gp->flags);
|
||||
gprintln(" rank: %d", gp->rank);
|
||||
if (LIST_EMPTY(&gp->provider))
|
||||
gprintln(" providers: none");
|
||||
if (LIST_EMPTY(&gp->consumer))
|
||||
gprintln(" consumers: none");
|
||||
} else {
|
||||
gprintf("geom: %s (%p), rank=%d", gp->name, gp, gp->rank);
|
||||
if (gp->flags != 0) {
|
||||
printf(", flags=%s (0x%04x)",
|
||||
geom_flags_to_string(gp, flags, sizeof(flags)),
|
||||
gp->flags);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if (!LIST_EMPTY(&gp->provider)) {
|
||||
LIST_FOREACH(pp, &gp->provider, provider)
|
||||
db_show_geom_provider(indent + 2, pp);
|
||||
}
|
||||
if (!LIST_EMPTY(&gp->consumer)) {
|
||||
LIST_FOREACH(cp, &gp->consumer, consumer)
|
||||
db_show_geom_consumer(indent + 2, cp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
db_show_geom_class(struct g_class *mp)
|
||||
{
|
||||
struct g_geom *gp;
|
||||
|
||||
printf("class: %s (%p)\n", mp->name, mp);
|
||||
LIST_FOREACH(gp, &mp->geom, geom)
|
||||
db_show_geom_geom(2, gp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the GEOM topology or the given object.
|
||||
*/
|
||||
DB_SHOW_COMMAND(geom, db_show_geom)
|
||||
{
|
||||
struct g_class *mp;
|
||||
|
||||
if (!have_addr) {
|
||||
/* No address given, print the entire topology. */
|
||||
LIST_FOREACH(mp, &g_classes, class) {
|
||||
db_show_geom_class(mp);
|
||||
printf("\n");
|
||||
}
|
||||
} else {
|
||||
switch (g_valid_obj((void *)addr)) {
|
||||
case 1:
|
||||
db_show_geom_class((struct g_class *)addr);
|
||||
break;
|
||||
case 2:
|
||||
db_show_geom_geom(0, (struct g_geom *)addr);
|
||||
break;
|
||||
case 3:
|
||||
db_show_geom_consumer(0, (struct g_consumer *)addr);
|
||||
break;
|
||||
case 4:
|
||||
db_show_geom_provider(0, (struct g_provider *)addr);
|
||||
break;
|
||||
default:
|
||||
printf("Not a GEOM object.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef gprintf
|
||||
#undef gprintln
|
||||
#undef ADDFLAG
|
||||
|
||||
#endif /* DDB */
|
||||
|
Loading…
Reference in New Issue
Block a user