From 49df98f5a832790c69fa7d8547643f8181cfacc0 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 7 Jun 2022 23:44:52 -0700 Subject: [PATCH] Add skip-likely-huge print option Add an option to skip printing structures that are likely to be so huge that the print output becomes completely unwieldly on large systems. Signed-off-by: Zach Brown --- utils/man/scoutfs.8 | 16 ++++++++++++- utils/src/print.c | 55 +++++++++++++++++++++++++++++---------------- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/utils/man/scoutfs.8 b/utils/man/scoutfs.8 index bd23b688..9cfb454c 100644 --- a/utils/man/scoutfs.8 +++ b/utils/man/scoutfs.8 @@ -597,7 +597,7 @@ format. .PD .TP -.BI "print META-DEVICE" +.BI "print {-S|--skip-likely-huge} META-DEVICE" .sp Prints out all of the metadata in the file system. This makes no effort to ensure that the structures are consistent as they're traversed and @@ -607,6 +607,20 @@ output. .PD 0 .TP .sp +.B "-S, --skip-likely-huge" +Skip printing structures that are likely to be very large. The +structures that are skipped tend to be global and whose size tends to be +related to the size of the volume. Examples of skipped structures include +the global fs items, srch files, and metadata and data +allocators. Similar structures that are not skipped are related to the +number of mounts and are maintained at a relatively reasonable size. +These include per-mount log trees, srch files, allocators, and the +metadata allocators used by server commits. +.sp +Skipping the larger structures limits the print output to a relatively +constant size rather than being a large multiple of the used metadata +space of the volume making the output much more useful for inspection. +.TP .B "META-DEVICE" The path to the metadata device for the filesystem whose metadata will be printed. Since this command reads via the host's buffer cache, it may not diff --git a/utils/src/print.c b/utils/src/print.c index 7328b6f8..f4975bca 100644 --- a/utils/src/print.c +++ b/utils/src/print.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -989,9 +990,10 @@ static void print_super_block(struct scoutfs_super_block *super, u64 blkno) struct print_args { char *meta_device; + bool skip_likely_huge; }; -static int print_volume(int fd) +static int print_volume(int fd, struct print_args *args) { struct scoutfs_super_block *super = NULL; struct print_recursion_args pa; @@ -1041,23 +1043,26 @@ static int print_volume(int fd) ret = err; } - for (i = 0; i < array_size(super->meta_alloc); i++) { - snprintf(str, sizeof(str), "meta_alloc[%u]", i); - err = print_btree(fd, super, str, &super->meta_alloc[i].root, + if (!args->skip_likely_huge) { + for (i = 0; i < array_size(super->meta_alloc); i++) { + snprintf(str, sizeof(str), "meta_alloc[%u]", i); + err = print_btree(fd, super, str, &super->meta_alloc[i].root, + print_alloc_item, NULL); + if (err && !ret) + ret = err; + } + + err = print_btree(fd, super, "data_alloc", &super->data_alloc.root, print_alloc_item, NULL); if (err && !ret) ret = err; } - err = print_btree(fd, super, "data_alloc", &super->data_alloc.root, - print_alloc_item, NULL); - if (err && !ret) - ret = err; - err = print_btree(fd, super, "srch_root", &super->srch_root, print_srch_root_item, NULL); if (err && !ret) ret = err; + err = print_btree(fd, super, "logs_root", &super->logs_root, print_log_trees_item, NULL); if (err && !ret) @@ -1065,19 +1070,23 @@ static int print_volume(int fd) pa.super = super; pa.fd = fd; - err = print_btree_leaf_items(fd, super, &super->srch_root.ref, - print_srch_root_files, &pa); - if (err && !ret) - ret = err; + if (!args->skip_likely_huge) { + err = print_btree_leaf_items(fd, super, &super->srch_root.ref, + print_srch_root_files, &pa); + if (err && !ret) + ret = err; + } err = print_btree_leaf_items(fd, super, &super->logs_root.ref, print_log_trees_roots, &pa); if (err && !ret) ret = err; - err = print_btree(fd, super, "fs_root", &super->fs_root, - print_fs_item, NULL); - if (err && !ret) - ret = err; + if (!args->skip_likely_huge) { + err = print_btree(fd, super, "fs_root", &super->fs_root, + print_fs_item, NULL); + if (err && !ret) + ret = err; + } out: free(super); @@ -1098,7 +1107,7 @@ static int do_print(struct print_args *args) return ret; } - ret = print_volume(fd); + ret = print_volume(fd, args); close(fd); return ret; }; @@ -1108,6 +1117,9 @@ static int parse_opt(int key, char *arg, struct argp_state *state) struct print_args *args = state->input; switch (key) { + case 'S': + args->skip_likely_huge = true; + break; case ARGP_KEY_ARG: if (!args->meta_device) args->meta_device = strdup_or_error(state, arg); @@ -1125,8 +1137,13 @@ static int parse_opt(int key, char *arg, struct argp_state *state) return 0; } +static struct argp_option options[] = { + { "skip-likely-huge", 'S', NULL, 0, "Skip large structures to minimize output size"}, + { NULL } +}; + static struct argp argp = { - NULL, + options, parse_opt, "META-DEV", "Print metadata structures"