Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153072177
D17151.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D17151.diff
View Options
Index: head/sbin/geom/core/geom.8
===================================================================
--- head/sbin/geom/core/geom.8
+++ head/sbin/geom/core/geom.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 13, 2018
+.Dd September 14, 2018
.Dt GEOM 8
.Os
.Sh NAME
@@ -55,6 +55,8 @@
.Nm
.Fl p
.Ar provider-name
+.Nm
+.Fl t
.Sh DESCRIPTION
The
.Nm
@@ -111,6 +113,8 @@
.It Fl p Ar provider-name
Print detailed information about the geom which provides
.Ar provider-name .
+.It Fl t
+Display geoms hierarchy as a tree.
.El
.Pp
Class-specific commands are implemented as shared libraries which
Index: head/sbin/geom/core/geom.c
===================================================================
--- head/sbin/geom/core/geom.c
+++ head/sbin/geom/core/geom.c
@@ -66,8 +66,11 @@
static int verbose = 0;
static struct g_command *class_commands = NULL;
-#define GEOM_CLASS_CMDS 0x01
-#define GEOM_STD_CMDS 0x02
+#define GEOM_CLASS_CMDS 0x01
+#define GEOM_STD_CMDS 0x02
+
+#define GEOM_CLASS_WIDTH 10
+
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);
@@ -149,6 +152,7 @@
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;
@@ -672,22 +676,142 @@
return (NULL);
}
+static int
+compute_tree_width_geom(struct gmesh *mesh, struct ggeom *gp, int indent)
+{
+ struct gclass *classp2;
+ struct ggeom *gp2;
+ struct gconsumer *cp2;
+ struct gprovider *pp;
+ int max_width, width;
+
+ max_width = width = indent + strlen(gp->lg_name);
+
+ LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
+ 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)
+ continue;
+ width = compute_tree_width_geom(mesh,
+ gp2, indent + 2);
+ if (width > max_width)
+ max_width = width;
+ }
+ }
+ }
+ }
+
+ return (max_width);
+}
+
+static int
+compute_tree_width(struct gmesh *mesh)
+{
+ struct gclass *classp;
+ struct ggeom *gp;
+ int max_width, width;
+
+ max_width = width = 0;
+
+ LIST_FOREACH(classp, &mesh->lg_class, lg_class) {
+ LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
+ if (!LIST_EMPTY(&gp->lg_consumer))
+ continue;
+ width = compute_tree_width_geom(mesh, gp, 0);
+ if (width > max_width)
+ max_width = width;
+ }
+ }
+
+ return (max_width);
+}
+
+static void
+show_tree_geom(struct gmesh *mesh, struct ggeom *gp, int indent, int width)
+{
+ struct gclass *classp2;
+ struct ggeom *gp2;
+ struct gconsumer *cp2;
+ struct gprovider *pp;
+
+ if (LIST_EMPTY(&gp->lg_provider)) {
+ printf("%*s%-*.*s %-*.*s\n", indent, "",
+ width - indent, width - indent, gp->lg_name,
+ GEOM_CLASS_WIDTH, GEOM_CLASS_WIDTH, gp->lg_class->lg_name);
+ return;
+ }
+
+ LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
+ printf("%*s%-*.*s %-*.*s %s\n", indent, "",
+ width - indent, width - indent, gp->lg_name,
+ GEOM_CLASS_WIDTH, GEOM_CLASS_WIDTH, gp->lg_class->lg_name,
+ pp->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)
+ continue;
+ show_tree_geom(mesh, gp2,
+ indent + 2, width);
+ }
+ }
+ }
+ }
+}
+
+static void
+show_tree(void)
+{
+ struct gmesh mesh;
+ struct gclass *classp;
+ struct ggeom *gp;
+ int error, width;
+
+ error = geom_gettree(&mesh);
+ if (error != 0)
+ errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
+
+ width = compute_tree_width(&mesh);
+
+ printf("%-*.*s %-*.*s %s\n",
+ width, width, "Geom",
+ GEOM_CLASS_WIDTH, GEOM_CLASS_WIDTH, "Class",
+ "Provider");
+
+ 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, width);
+ }
+ }
+}
+
int
main(int argc, char *argv[])
{
char *provider_name;
+ bool tflag;
int ch;
provider_name = NULL;
+ tflag = false;
if (strcmp(getprogname(), "geom") == 0) {
- while ((ch = getopt(argc, argv, "hp:")) != -1) {
+ 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();
@@ -699,8 +823,18 @@
*/
}
+ if (tflag && provider_name != NULL) {
+ errx(EXIT_FAILURE,
+ "At most one of -P and -t may be specified.");
+ }
+
if (provider_name != NULL) {
list_one_geom_by_provider(provider_name);
+ return (0);
+ }
+
+ if (tflag) {
+ show_tree();
return (0);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 19, 11:18 PM (1 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31806953
Default Alt Text
D17151.diff (4 KB)
Attached To
Mode
D17151: Add "geom -t".
Attached
Detach File
Event Timeline
Log In to Comment