diff options
author | Krzesimir Nowak <knowak@microsoft.com> | 2024-02-15 15:16:08 +0100 |
---|---|---|
committer | Krzesimir Nowak <knowak@microsoft.com> | 2024-02-22 19:06:22 +0100 |
commit | 58a28be5ac53af74fbd7bcc2e8adabb33d0d1b18 (patch) | |
tree | 6a94523e5fec2f427cd3899cb8c8629694fe75c5 /src/sysext | |
parent | sysext: Add minimal support for optional mutability for extensions (diff) | |
download | systemd-58a28be5ac53af74fbd7bcc2e8adabb33d0d1b18.tar.xz systemd-58a28be5ac53af74fbd7bcc2e8adabb33d0d1b18.zip |
sysext: Add --mutable mode flag
The flag takes "auto" or "import" or a boolean value.
"auto" causes systemd-sysext to make a decision about mutability of the merged
hierarchy based on existence of the upper directory in
`/var/lib/extensions.mutable/${hierarchy}`.
"import" causes the existing upper dir to be actually used as another lower
dir, which results in read-only merged hierarchy.
True value makes systemd-sysext to create the upper dir if it's missing and to
make the merged hierarchy mutable.
False value makes systemd-sysext to ignore upper dir completely, and create a
read-only merged hierarchy.
The default is false value.
Diffstat (limited to 'src/sysext')
-rw-r--r-- | src/sysext/sysext.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index e381b346b0..cb55d62322 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -51,6 +51,15 @@ #include "varlink-io.systemd.sysext.h" #include "verbs.h" +typedef enum MutableMode { + MUTABLE_YES, + MUTABLE_NO, + MUTABLE_AUTO, + MUTABLE_IMPORT, + _MUTABLE_MAX, + _MUTABLE_INVALID = -EINVAL, +} MutableMode; + static char **arg_hierarchies = NULL; /* "/usr" + "/opt" by default for sysext and /etc by default for confext */ static char *arg_root = NULL; static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF; @@ -61,6 +70,7 @@ static bool arg_no_reload = false; static int arg_noexec = -1; static ImagePolicy *arg_image_policy = NULL; static bool arg_varlink = false; +static MutableMode arg_mutable = MUTABLE_NO; /* Is set to IMAGE_CONFEXT when systemd is called with the confext functionality instead of the default */ static ImageClass arg_image_class = IMAGE_SYSEXT; @@ -745,10 +755,28 @@ static int resolve_mutable_directory(const char *hierarchy, char **ret_resolved_ assert(hierarchy); assert(ret_resolved_mutable_directory); + if (arg_mutable == MUTABLE_NO) { + log_debug("Mutability for hierarchy '%s' is disabled, not resolving mutable directory.", hierarchy); + *ret_resolved_mutable_directory = NULL; + return 0; + } + path = determine_mutable_directory_path_for_hierarchy(hierarchy); if (!path) return log_oom(); + if (arg_mutable == MUTABLE_YES) { + _cleanup_free_ char *path_in_root = NULL; + + path_in_root = path_join(arg_root, path); + if (!path_in_root) + return log_oom(); + + r = mkdir_p(path_in_root, 0700); + if (r < 0) + return log_error_errno(r, "Failed to create a directory '%s': %m", path_in_root); + } + r = chase(path, arg_root, CHASE_PREFIX_ROOT, &resolved_path, NULL); if (r < 0 && r != -ENOENT) return log_error_errno(r, "Failed to resolve mutable directory '%s': %m", path); @@ -801,6 +829,13 @@ static int determine_top_lower_dirs(OverlayFSPaths *op, const char *meta_path) { if (r < 0) return log_oom(); + /* If importing mutable layer and it actually exists, add it just below the meta path */ + if (arg_mutable == MUTABLE_IMPORT && op->resolved_mutable_directory) { + r = strv_extend(&op->lower_dirs, op->resolved_mutable_directory); + if (r < 0) + return r; + } + return 0; } @@ -862,6 +897,11 @@ static int hierarchy_as_lower_dir(OverlayFSPaths *op) { return 1; } + if (arg_mutable == MUTABLE_IMPORT) { + log_debug("Mutability for host hierarchy '%s' is disabled, so it will be a lowerdir", op->resolved_hierarchy); + return 0; + } + if (!op->resolved_mutable_directory) { log_debug("No mutable directory found, so host hierarchy '%s' will be used as lowerdir", op->resolved_hierarchy); return 0; @@ -933,6 +973,11 @@ static int determine_upper_dir(OverlayFSPaths *op) { assert(op); assert(!op->upper_dir); + if (arg_mutable == MUTABLE_IMPORT) { + log_debug("Mutability is disabled, there will be no upperdir for host hierarchy '%s'", op->hierarchy); + return 0; + } + if (!op->resolved_mutable_directory) { log_debug("No mutable directory found for host hierarchy '%s', there will be no upperdir", op->hierarchy); return 0; @@ -963,6 +1008,9 @@ static int determine_work_dir(OverlayFSPaths *op) { if (!op->upper_dir) return 0; + if (arg_mutable == MUTABLE_IMPORT) + return 0; + r = work_dir_for_hierarchy(op->hierarchy, op->upper_dir, &work_dir); if (r < 0) return r; @@ -1981,6 +2029,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_IMAGE_POLICY, ARG_NOEXEC, ARG_NO_RELOAD, + ARG_MUTABLE, }; static const struct option options[] = { @@ -1994,6 +2043,7 @@ static int parse_argv(int argc, char *argv[]) { { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, { "noexec", required_argument, NULL, ARG_NOEXEC }, { "no-reload", no_argument, NULL, ARG_NO_RELOAD }, + { "mutable", required_argument, NULL, ARG_MUTABLE }, {} }; @@ -2057,6 +2107,19 @@ static int parse_argv(int argc, char *argv[]) { arg_no_reload = true; break; + case ARG_MUTABLE: + if (streq(optarg, "auto")) + arg_mutable = MUTABLE_AUTO; + else if (streq(optarg, "import")) + arg_mutable = MUTABLE_IMPORT; + else { + r = parse_boolean(optarg); + if (r < 0) + return log_error_errno(r, "Failed to parse argument to --mutable=: %s", optarg); + arg_mutable = r ? MUTABLE_YES : MUTABLE_NO; + } + break; + case '?': return -EINVAL; |