free(c->component);
+ c->mounted_dir = umount_and_rmdir_and_free(c->mounted_dir);
+ c->loop_device = loop_device_unref(c->loop_device);
+
FOREACH_ARRAY(tr, c->transfers, c->n_transfers)
transfer_free(*tr);
free(c->transfers);
return 0;
}
+typedef enum ProcessImageFlags {
+ PROCESS_IMAGE_READ_ONLY = 1 << 0,
+} ProcessImageFlags;
+
+static int process_image(
+ Context *c,
+ ProcessImageFlags flags) {
+
+ _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
+ _cleanup_(umount_and_freep) char *mounted_dir = NULL;
+ int r;
+
+ assert(c);
+
+ if (!arg_image)
+ return 0;
+
+ assert(!arg_root);
+ assert(!c->mounted_dir);
+ assert(!c->loop_device);
+
+ r = mount_image_privately_interactively(
+ arg_image,
+ arg_image_policy,
+ (FLAGS_SET(flags, PROCESS_IMAGE_READ_ONLY) ? DISSECT_IMAGE_READ_ONLY : 0) |
+ DISSECT_IMAGE_FSCK |
+ DISSECT_IMAGE_MKDIR |
+ DISSECT_IMAGE_GROWFS |
+ DISSECT_IMAGE_RELAX_VAR_CHECK |
+ DISSECT_IMAGE_USR_NO_ROOT |
+ DISSECT_IMAGE_GENERIC_ROOT |
+ DISSECT_IMAGE_REQUIRE_ROOT |
+ DISSECT_IMAGE_ALLOW_USERSPACE_VERITY,
+ &mounted_dir,
+ /* ret_dir_fd= */ NULL,
+ &loop_device);
+ if (r < 0)
+ return r;
+
+ arg_root = strdup(mounted_dir);
+ if (!arg_root)
+ return log_oom();
+
+ c->mounted_dir = TAKE_PTR(mounted_dir);
+ c->loop_device = TAKE_PTR(loop_device);
+
+ return 0;
+}
+
static int context_make_offline(
Context **ret,
- const char *node,
const char *component,
+ ProcessImageFlags process_image_flags,
ReadDefinitionsFlags read_definitions_flags) {
_cleanup_(context_freep) Context* context = NULL;
int r;
if (r < 0)
return r;
- r = context_read_definitions(context, node, read_definitions_flags);
+ r = process_image(context, process_image_flags);
+ if (r < 0)
+ return r;
+
+ r = context_read_definitions(context, context->loop_device ? context->loop_device->node : NULL, read_definitions_flags);
if (r < 0)
return r;
static int context_make_online(
Context **ret,
- const char *node,
- const char *component) {
+ const char *component,
+ ProcessImageFlags process_image_flags) {
_cleanup_(context_freep) Context* context = NULL;
int r;
r = context_make_offline(
&context,
- node,
component,
+ process_image_flags,
READ_DEFINITIONS_REQUIRES_ENABLED_TRANSFERS|READ_DEFINITIONS_REQUIRES_ANY_TRANSFERS);
if (r < 0)
return r;
return 1;
}
-static int process_image(
- bool ro,
- char **ret_mounted_dir,
- LoopDevice **ret_loop_device) {
-
- _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
- _cleanup_(umount_and_freep) char *mounted_dir = NULL;
- int r;
-
- assert(ret_mounted_dir);
- assert(ret_loop_device);
-
- if (!arg_image)
- return 0;
-
- assert(!arg_root);
-
- r = mount_image_privately_interactively(
- arg_image,
- arg_image_policy,
- (ro ? DISSECT_IMAGE_READ_ONLY : 0) |
- DISSECT_IMAGE_FSCK |
- DISSECT_IMAGE_MKDIR |
- DISSECT_IMAGE_GROWFS |
- DISSECT_IMAGE_RELAX_VAR_CHECK |
- DISSECT_IMAGE_USR_NO_ROOT |
- DISSECT_IMAGE_GENERIC_ROOT |
- DISSECT_IMAGE_REQUIRE_ROOT |
- DISSECT_IMAGE_ALLOW_USERSPACE_VERITY,
- &mounted_dir,
- /* ret_dir_fd= */ NULL,
- &loop_device);
- if (r < 0)
- return r;
-
- arg_root = strdup(mounted_dir);
- if (!arg_root)
- return log_oom();
-
- *ret_mounted_dir = TAKE_PTR(mounted_dir);
- *ret_loop_device = TAKE_PTR(loop_device);
-
- return 0;
-}
-
VERB(verb_list, "list", "[VERSION]", VERB_ANY, 2, VERB_DEFAULT,
"Show installed and available versions");
static int verb_list(int argc, char *argv[], uintptr_t _data, void *userdata) {
- _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
- _cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
_cleanup_(context_freep) Context* context = NULL;
_cleanup_strv_free_ char **appstream_urls = NULL;
const char *version;
if (arg_component_all)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "--component-all currently not supported for '%s'.", argv[0]);
- r = process_image(/* ro= */ true, &mounted_dir, &loop_device);
- if (r < 0)
- return r;
-
r = context_make_online(
&context,
- loop_device ? loop_device->node : NULL,
- arg_component);
+ arg_component,
+ PROCESS_IMAGE_READ_ONLY);
if (r < 0)
return r;
VERB(verb_features, "features", "[FEATURE]", VERB_ANY, 2, 0,
"Show optional features");
static int verb_features(int argc, char *argv[], uintptr_t _data, void *userdata) {
- _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
- _cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
_cleanup_(context_freep) Context* context = NULL;
_cleanup_(table_unrefp) Table *table = NULL;
const char *feature_id;
if (arg_component_all)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "--component-all currently not supported for '%s'.", argv[0]);
- r = process_image(/* ro= */ true, &mounted_dir, &loop_device);
- if (r < 0)
- return r;
-
r = context_make_offline(
&context,
- loop_device ? loop_device->node : NULL,
arg_component,
+ PROCESS_IMAGE_READ_ONLY,
READ_DEFINITIONS_REQUIRES_ANY_TRANSFERS);
if (r < 0)
return r;
VERB_NOARG(verb_check_new, "check-new",
"Check if there's a new version available");
static int verb_check_new(int argc, char *argv[], uintptr_t _data, void *userdata) {
- _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
- _cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
_cleanup_(context_freep) Context* context = NULL;
int r;
if (arg_component_all)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "--component-all currently not supported for '%s'.", argv[0]);
- r = process_image(/* ro= */ true, &mounted_dir, &loop_device);
- if (r < 0)
- return r;
-
r = context_make_online(
&context,
- loop_device ? loop_device->node : NULL,
- arg_component);
+ arg_component,
+ PROCESS_IMAGE_READ_ONLY);
if (r < 0)
return r;
} UpdateActionFlags;
static int verb_update_impl(int argc, char **argv, UpdateActionFlags action_flags) {
- _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
- _cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
_cleanup_(context_freep) Context* context = NULL;
_cleanup_free_ char *booted_version = NULL;
UpdateSet *applied = NULL;
return log_error_errno(SYNTHETIC_ERRNO(ENODATA), "/etc/os-release lacks IMAGE_VERSION field.");
}
- r = process_image(/* ro= */ false, &mounted_dir, &loop_device);
- if (r < 0)
- return r;
-
- const char *node = loop_device ? loop_device->node : NULL;
bool installed = false;
int ret = 0;
r = context_make_online(
&context,
- node,
- arg_component);
+ arg_component,
+ /* process_image_flags= */ 0);
if (r < 0) {
if (r != -ENOENT)
return r;
}
if (arg_cleanup > 0)
- RET_GATHER(ret, installdb_cleanup_component(node, arg_component));
+ RET_GATHER(ret, installdb_cleanup_component(context));
if (installed) {
/* We installed something, yay */
VERB_NOARG(verb_vacuum, "vacuum",
"Make room, by deleting old versions");
static int verb_vacuum(int argc, char *argv[], uintptr_t _data, void *userdata) {
- _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
- _cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
_cleanup_(context_freep) Context* context = NULL;
int r;
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"The --instances-max argument must be >= 1 while vacuuming");
- r = process_image(/* ro= */ false, &mounted_dir, &loop_device);
- if (r < 0)
- return r;
-
r = context_make_offline(
&context,
- loop_device ? loop_device->node : NULL,
arg_component,
+ /* process_image_flags= */ 0,
READ_DEFINITIONS_REQUIRES_ANY_TRANSFERS);
if (r < 0)
return r;
r = context_make_offline(
&context,
- /* node= */ NULL,
arg_component,
+ /* process_image_flags= */ 0,
READ_DEFINITIONS_REQUIRES_ENABLED_TRANSFERS|READ_DEFINITIONS_REQUIRES_ANY_TRANSFERS);
if (r < 0)
return r;
"Show list of components");
static int verb_components(int argc, char *argv[], uintptr_t _data, void *userdata) {
_cleanup_(context_freep) Context* context = NULL;
- _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
- _cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
bool has_default_component = false;
int r;
if (arg_component_all)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "--component-all currently not supported for '%s'.", argv[0]);
- r = process_image(/* ro= */ false, &mounted_dir, &loop_device);
- if (r < 0)
- return r;
-
r = context_make_offline(
&context,
- loop_device ? loop_device->node : NULL,
arg_component,
+ /* process_image_flags= */ 0,
/* read_definitions_flags= */ 0);
if (r < 0)
return r;
if (arg_cleanup == 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invocation of 'cleanup' with --cleanup=no is contradictory, refusing.");
- _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
- _cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
- r = process_image(/* ro= */ false, &mounted_dir, &loop_device);
- if (r < 0)
- return r;
-
- const char *node = loop_device ? loop_device->node : NULL;
-
r = context_make_offline(
&context,
- node,
arg_component,
+ /* process_image_flags= */ 0,
/* read_definitions_flags= */ 0);
if (r < 0)
return r;
r = context_make_offline(
&component_context,
- node,
*i,
+ /* process_image_flags= */ 0,
/* read_definitions_flags= */ 0);
if (r < 0)
return r;