summaryrefslogtreecommitdiffstats
path: root/src/analyze/analyze.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analyze/analyze.c')
-rw-r--r--src/analyze/analyze.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index f5ce2c3ad3..8d637ff8de 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -34,6 +34,7 @@
#include "locale-util.h"
#include "log.h"
#include "main-func.h"
+#include "mount-util.h"
#include "nulstr-util.h"
#include "pager.h"
#include "parse-argument.h"
@@ -87,12 +88,14 @@ static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
static bool arg_man = true;
static bool arg_generators = false;
static char *arg_root = NULL;
+static char *arg_image = NULL;
static unsigned arg_iterations = 1;
static usec_t arg_base_time = USEC_INFINITY;
STATIC_DESTRUCTOR_REGISTER(arg_dot_from_patterns, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_dot_to_patterns, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
typedef struct BootTimes {
usec_t firmware_time;
@@ -2232,6 +2235,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_ORDER,
ARG_REQUIRE,
ARG_ROOT,
+ ARG_IMAGE,
ARG_SYSTEM,
ARG_USER,
ARG_GLOBAL,
@@ -2251,6 +2255,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "order", no_argument, NULL, ARG_ORDER },
{ "require", no_argument, NULL, ARG_REQUIRE },
{ "root", required_argument, NULL, ARG_ROOT },
+ { "image", required_argument, NULL, ARG_IMAGE },
{ "system", no_argument, NULL, ARG_SYSTEM },
{ "user", no_argument, NULL, ARG_USER },
{ "global", no_argument, NULL, ARG_GLOBAL },
@@ -2287,6 +2292,12 @@ static int parse_argv(int argc, char *argv[]) {
return r;
break;
+ case ARG_IMAGE:
+ r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_image);
+ if (r < 0)
+ return r;
+ break;
+
case ARG_SYSTEM:
arg_scope = UNIT_FILE_SYSTEM;
break;
@@ -2381,14 +2392,21 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --user is not supported for cat-config right now.");
- if (arg_root && !STRPTR_IN_SET(argv[optind], "cat-config", "verify"))
+ if ((arg_root || arg_image) && !STRPTR_IN_SET(argv[optind], "cat-config", "verify"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Option --root is only supported for cat-config and verify right now.");
+ "Options --root= and --image= are only supported for cat-config and verify right now.");
+
+ /* Having both an image and a root is not supported by the code */
+ if (arg_root && arg_image)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported.");
return 1; /* work to do */
}
static int run(int argc, char *argv[]) {
+ _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
+ _cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
+ _cleanup_(umount_and_rmdir_and_freep) char *unlink_dir = NULL;
static const Verb verbs[] = {
{ "help", VERB_ANY, VERB_ANY, 0, help },
@@ -2432,6 +2450,26 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
+ /* Open up and mount the image */
+ if (arg_image) {
+ assert(!arg_root);
+
+ r = mount_image_privately_interactively(
+ arg_image,
+ DISSECT_IMAGE_GENERIC_ROOT |
+ DISSECT_IMAGE_RELAX_VAR_CHECK |
+ DISSECT_IMAGE_READ_ONLY,
+ &unlink_dir,
+ &loop_device,
+ &decrypted_image);
+ if (r < 0)
+ return r;
+
+ arg_root = strdup(unlink_dir);
+ if (!arg_root)
+ return log_oom();
+ }
+
return dispatch_verb(argc, argv, verbs, NULL);
}