diff options
author | Lennart Poettering <lennart@poettering.net> | 2022-11-29 16:39:06 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2022-12-07 17:57:22 +0100 |
commit | 0305cf6e9d208067d249898f1d7bf638f27020fb (patch) | |
tree | c35ef3e348d9dec2384e2e5b0a8b32e1e4512c2b /src/dissect | |
parent | 3775e1410cebc45a6472dd1f9bc539f27e73d552 (diff) | |
download | systemd-0305cf6e9d208067d249898f1d7bf638f27020fb.tar.gz |
dissect: add simple --discover command
Diffstat (limited to 'src/dissect')
-rw-r--r-- | src/dissect/dissect.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 3a882ee12c..e7ea582300 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -17,6 +17,7 @@ #include "copy.h" #include "device-util.h" #include "devnum-util.h" +#include "discover-image.h" #include "dissect-image.h" #include "env-util.h" #include "escape.h" @@ -56,6 +57,7 @@ static enum { ACTION_WITH, ACTION_COPY_FROM, ACTION_COPY_TO, + ACTION_DISCOVER, } arg_action = ACTION_DISSECT; static const char *arg_image = NULL; static const char *arg_path = NULL; @@ -128,6 +130,7 @@ static int help(void) { " --with Mount, run command, unmount\n" " -x --copy-from Copy files from image to host\n" " -a --copy-to Copy files from host to image\n" + " --discover Discover DDIs in well known directories\n" "\nSee the %2$s for details.\n", program_invocation_short_name, link, @@ -199,6 +202,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_RMDIR, ARG_JSON, ARG_MTREE, + ARG_DISCOVER, }; static const struct option options[] = { @@ -223,6 +227,7 @@ static int parse_argv(int argc, char *argv[]) { { "copy-from", no_argument, NULL, 'x' }, { "copy-to", no_argument, NULL, 'a' }, { "json", required_argument, NULL, ARG_JSON }, + { "discover", no_argument, NULL, ARG_DISCOVER }, {} }; @@ -400,6 +405,10 @@ static int parse_argv(int argc, char *argv[]) { break; + case ARG_DISCOVER: + arg_action = ACTION_DISCOVER; + break; + case '?': return -EINVAL; @@ -491,6 +500,13 @@ static int parse_argv(int argc, char *argv[]) { break; + case ACTION_DISCOVER: + if (optind != argc) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Expected no argument."); + + break; + default: assert_not_reached(); } @@ -1325,6 +1341,54 @@ static int action_with(DissectedImage *m, LoopDevice *d) { return rcode; } +static int action_discover(void) { + _cleanup_(hashmap_freep) Hashmap *images = NULL; + _cleanup_(table_unrefp) Table *t = NULL; + Image *img; + int r; + + images = hashmap_new(&image_hash_ops); + if (!images) + return log_oom(); + + for (ImageClass cl = 0; cl < _IMAGE_CLASS_MAX; cl++) { + r = image_discover(cl, NULL, images); + if (r < 0) + return log_error_errno(r, "Failed to discover images: %m"); + } + + if ((arg_json_format_flags & JSON_FORMAT_OFF) && hashmap_isempty(images)) { + log_info("No images found."); + return 0; + } + + t = table_new("name", "type", "class", "ro", "path", "time", "usage"); + if (!t) + return log_oom(); + + HASHMAP_FOREACH(img, images) { + + if (!IN_SET(img->type, IMAGE_RAW, IMAGE_BLOCK)) + continue; + + r = table_add_many( + t, + TABLE_STRING, img->name, + TABLE_STRING, image_type_to_string(img->type), + TABLE_STRING, image_class_to_string(img->class), + TABLE_BOOLEAN, img->read_only, + TABLE_PATH, img->path, + TABLE_TIMESTAMP, img->mtime != 0 ? img->mtime : img->crtime, + TABLE_SIZE, img->usage); + if (r < 0) + return table_log_add_error(r); + } + + (void) table_set_sort(t, (size_t) 0); + + return table_print_with_pager(t, arg_json_format_flags, arg_pager_flags, arg_legend); +} + static int run(int argc, char *argv[]) { _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL; _cleanup_(loop_device_unrefp) LoopDevice *d = NULL; @@ -1338,6 +1402,8 @@ static int run(int argc, char *argv[]) { if (arg_action == ACTION_UMOUNT) return action_umount(arg_path); + if (arg_action == ACTION_DISCOVER) + return action_discover(); r = verity_settings_load( &arg_verity_settings, |