Page MenuHomeFreeBSD

D17116.id47917.diff
No OneTemporary

D17116.id47917.diff

Index: sbin/geom/core/geom.8
===================================================================
--- sbin/geom/core/geom.8
+++ sbin/geom/core/geom.8
@@ -52,6 +52,11 @@
.Ar class
.Cm unload
.Op Fl v
+.Nm
+.Fl p
+.Ar provider-name
+.Nm
+.Fl t
.Sh DESCRIPTION
The
.Nm
@@ -101,6 +106,15 @@
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
+Print detailed information about geom which provides
+.Ar provider-name .
+.It Fl t
+Print provider-consumer relationship as a tree.
.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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
@@ -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,8 @@
if (class_name == NULL) {
fprintf(stderr, "usage: geom <class> <command> [options]\n");
+ fprintf(stderr, " geom -p <provider-name>\n");
+ fprintf(stderr, " geom -t\n");
exit(EXIT_FAILURE);
} else {
struct g_command *cmd;
@@ -650,10 +654,118 @@
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);
+}
+
+static void
+show_tree_geom(struct gmesh *mesh, struct ggeom *gp, int indent)
+{
+ struct gclass *classp2;
+ struct ggeom *gp2;
+ struct gconsumer *cp2;
+ struct gprovider *pp;
+ int width;
+
+ width = 20 - indent;
+
+ LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
+ printf("%*s%-*.*s\t%-*.*s\t%s\n", indent, "",
+ width, width, pp->lg_name,
+ width, width, gp->lg_name,
+ gp->lg_class->lg_name);
+
+ LIST_FOREACH(classp2, &mesh->lg_class, lg_class) {
+ LIST_FOREACH(gp2, &classp2->lg_geom, lg_geom) {
+ LIST_FOREACH(cp2, &gp2->lg_consumer, lg_consumer) {
+ if (pp == cp2->lg_provider)
+ show_tree_geom(mesh, gp2, indent + 2);
+ }
+ }
+ }
+ }
+}
+
+static void
+show_tree(void)
+{
+ struct gmesh mesh;
+ struct gclass *classp;
+ struct ggeom *gp;
+ int error;
+
+ error = geom_gettree(&mesh);
+ if (error != 0)
+ errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
+
+ printf("%-*.*s\t%-*.*s\t%s\n", 20, 20, "Provider", 20, 20, "Geom", "Class");
+
+ LIST_FOREACH(classp, &mesh.lg_class, lg_class) {
+ LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
+ if (!LIST_EMPTY(&gp->lg_consumer))
+ continue;
+ show_tree_geom(&mesh, gp, 0);
+ }
+ }
+}
+
int
main(int argc, char *argv[])
{
+ char *provider_name = NULL;
+ bool tflag = false;
+ int ch;
+ if (strcmp(getprogname(), "geom") == 0) {
+ while ((ch = getopt(argc, argv, "hp:t")) != -1) {
+ switch (ch) {
+ case 'p':
+ provider_name = strdup(optarg);
+ if (provider_name == NULL)
+ err(1, "strdup");
+ break;
+ case 't':
+ tflag = true;
+ break;
+ case 'h':
+ default:
+ usage();
+ }
+ }
+
+ /*
+ * Don't adjust argc and argv, it would break get_class().
+ */
+ }
+
+ if (tflag && provider_name != NULL)
+ errx(EXIT_FAILURE, "at most one of -P and -t may be specified");
+
+ if (provider_name) {
+ list_one_geom_by_provider(provider_name);
+ return (0);
+ }
+
+ if (tflag) {
+ show_tree();
+ return (0);
+ }
+
get_class(&argc, &argv);
run_command(argc, argv);
/* NOTREACHED */
@@ -765,6 +877,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

File Metadata

Mime Type
text/plain
Expires
Thu, Dec 26, 10:21 AM (10 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15603773
Default Alt Text
D17116.id47917.diff (4 KB)

Event Timeline