Index: sbin/geom/core/geom.8 =================================================================== --- sbin/geom/core/geom.8 +++ sbin/geom/core/geom.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 5, 2011 +.Dd September 13, 2011 .Dt GEOM 8 .Os .Sh NAME @@ -52,6 +52,9 @@ .Ar class .Cm unload .Op Fl v +.Nm +.Fl p +.Ar provider-name .Sh DESCRIPTION The .Nm @@ -101,6 +104,13 @@ Unload the kernel module which implements the given class. This command is only available if the given class is loaded as a kernel module. +.El +.Pp +Additional options include: +.Bl -tag -width ".Cm status" +.It Fl p Ar provider-name +Print detailed information about the geom which provides +.Ar provider-name . .El .Pp Class-specific commands are implemented as shared libraries which Index: sbin/geom/core/geom.c =================================================================== --- sbin/geom/core/geom.c +++ sbin/geom/core/geom.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,7 @@ #define GEOM_CLASS_CMDS 0x01 #define GEOM_STD_CMDS 0x02 static struct g_command *find_command(const char *cmdstr, int flags); +static void list_one_geom_by_provider(const char *provider_name); static int std_available(const char *name); static void std_help(struct gctl_req *req, unsigned flags); @@ -146,6 +148,7 @@ if (class_name == NULL) { fprintf(stderr, "usage: geom [options]\n"); + fprintf(stderr, " geom -p \n"); exit(EXIT_FAILURE); } else { struct g_command *cmd; @@ -650,10 +653,57 @@ usage(); } +static struct ggeom * +find_geom_by_provider(struct gmesh *mesh, const char *name) +{ + struct gclass *classp; + struct ggeom *gp; + struct gprovider *pp; + + LIST_FOREACH(classp, &mesh->lg_class, lg_class) { + LIST_FOREACH(gp, &classp->lg_geom, lg_geom) { + LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { + if (strcmp(pp->lg_name, name) == 0) + return (gp); + } + } + } + + return (NULL); +} + int main(int argc, char *argv[]) { + char *provider_name; + int ch; + provider_name = NULL; + + if (strcmp(getprogname(), "geom") == 0) { + while ((ch = getopt(argc, argv, "hp:")) != -1) { + switch (ch) { + case 'p': + provider_name = strdup(optarg); + if (provider_name == NULL) + err(1, "strdup"); + break; + case 'h': + default: + usage(); + } + } + + /* + * Don't adjust argc and argv, it would break get_class(). + */ + } + + if (provider_name) { + list_one_geom_by_provider(provider_name); + return (0); + } + get_class(&argc, &argv); run_command(argc, argv); /* NOTREACHED */ @@ -765,6 +815,25 @@ } } printf("\n"); +} + +static void +list_one_geom_by_provider(const char *provider_name) +{ + struct gmesh mesh; + struct ggeom *gp; + int error; + + error = geom_gettree(&mesh); + if (error != 0) + errc(EXIT_FAILURE, error, "Cannot get GEOM tree"); + + gp = find_geom_by_provider(&mesh, provider_name); + if (gp == NULL) + errx(EXIT_FAILURE, "Cannot find provider '%s'.", provider_name); + + printf("Geom class: %s\n", gp->lg_class->lg_name); + list_one_geom(gp); } static void