Add new option to the geom(8) utility, "-p". It makes it easy to look up

the GEOM class instance from the provider name.

Reviewed by:	oshogbo, 0mp
Approved by:	re (kib)
MFC after:	2 weeks
Relnotes:	yes
Sponsored by:	DARPA, AFRL
Differential Revision:	https://reviews.freebsd.org/D17116
This commit is contained in:
Edward Tomasz Napierala 2018-09-13 14:06:01 +00:00
parent 9696ba7fc0
commit 0f73f7016b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=338640
2 changed files with 80 additions and 1 deletions

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd January 5, 2011
.Dd September 13, 2018
.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
@ -103,6 +106,13 @@ 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
are stored in
.Pa /lib/geom/

View File

@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
@ -68,6 +69,7 @@ static struct g_command *class_commands = NULL;
#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 @@ usage(void)
if (class_name == NULL) {
fprintf(stderr, "usage: geom <class> <command> [options]\n");
fprintf(stderr, " geom -p <provider-name>\n");
exit(EXIT_FAILURE);
} else {
struct g_command *cmd;
@ -650,9 +653,56 @@ get_class(int *argc, char ***argv)
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 != NULL) {
list_one_geom_by_provider(provider_name);
return (0);
}
get_class(&argc, &argv);
run_command(argc, argv);
@ -767,6 +817,25 @@ list_one_geom(struct ggeom *gp)
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
std_help(struct gctl_req *req __unused, unsigned flags __unused)
{