From 5d9614077de26a294348bc9c872cd08da21c468d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 7 May 2018 21:57:00 +0200 Subject: [PATCH] nspawn: split out merging of settings object Let's separate the loading of the settings object and the merging into our arg_xyz fields into two. This will become particularly useful when we eventually are able to load settings from OCI runtime files in addition to .nspawn files. --- src/nspawn/nspawn.c | 171 +++++++++++++++++++++++++++------------------------- 1 file changed, 90 insertions(+), 81 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 460f109..7d0cc11 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3174,79 +3174,14 @@ static int setup_sd_notify_parent(sd_event *event, int fd, pid_t *inner_child_pi return 0; } -static int load_settings(void) { - _cleanup_(settings_freep) Settings *settings = NULL; - _cleanup_fclose_ FILE *f = NULL; - _cleanup_free_ char *p = NULL; - const char *fn, *i; - int r, rl; - - /* If all settings are masked, there's no point in looking for - * the settings file */ - if ((arg_settings_mask & _SETTINGS_MASK_ALL) == _SETTINGS_MASK_ALL) - return 0; - - fn = strjoina(arg_machine, ".nspawn"); - - /* We first look in the admin's directories in /etc and /run */ - FOREACH_STRING(i, "/etc/systemd/nspawn", "/run/systemd/nspawn") { - _cleanup_free_ char *j = NULL; - - j = strjoin(i, "/", fn); - if (!j) - return log_oom(); - - f = fopen(j, "re"); - if (f) { - p = TAKE_PTR(j); - - /* By default, we trust configuration from /etc and /run */ - if (arg_settings_trusted < 0) - arg_settings_trusted = true; - - break; - } - - if (errno != ENOENT) - return log_error_errno(errno, "Failed to open %s: %m", j); - } - - if (!f) { - /* After that, let's look for a file next to the - * actual image we shall boot. */ - - if (arg_image) { - p = file_in_same_dir(arg_image, fn); - if (!p) - return log_oom(); - } else if (arg_directory) { - p = file_in_same_dir(arg_directory, fn); - if (!p) - return log_oom(); - } - - if (p) { - f = fopen(p, "re"); - if (!f && errno != ENOENT) - return log_error_errno(errno, "Failed to open %s: %m", p); - - /* By default, we do not trust configuration from /var/lib/machines */ - if (arg_settings_trusted < 0) - arg_settings_trusted = false; - } - } - - if (!f) - return 0; - - log_debug("Settings are trusted: %s", yes_no(arg_settings_trusted)); +static int merge_settings(Settings *settings, const char *path) { + int rl; - r = settings_load(f, p, &settings); - if (r < 0) - return r; + assert(settings); + assert(path); - /* Copy over bits from the settings, unless they have been - * explicitly masked by command line switches. */ + /* Copy over bits from the settings, unless they have been explicitly masked by command line switches. Note + * that this steals the fields of the Settings* structure, and hence modifies it. */ if ((arg_settings_mask & SETTING_START_MODE) == 0 && settings->start_mode >= 0) { @@ -3281,7 +3216,7 @@ static int load_settings(void) { if (!arg_settings_trusted && plus != 0) { if (settings->capability != 0) - log_warning("Ignoring Capability= setting, file %s is not trusted.", p); + log_warning("Ignoring Capability= setting, file %s is not trusted.", path); } else arg_caps_retain |= plus; @@ -3300,7 +3235,7 @@ static int load_settings(void) { !sd_id128_is_null(settings->machine_id)) { if (!arg_settings_trusted) - log_warning("Ignoring MachineID= setting, file %s is not trusted.", p); + log_warning("Ignoring MachineID= setting, file %s is not trusted.", path); else arg_uuid = settings->machine_id; } @@ -3317,7 +3252,7 @@ static int load_settings(void) { settings->n_custom_mounts > 0) { if (!arg_settings_trusted) - log_warning("Ignoring TemporaryFileSystem=, Bind= and BindReadOnly= settings, file %s is not trusted.", p); + log_warning("Ignoring TemporaryFileSystem=, Bind= and BindReadOnly= settings, file %s is not trusted.", path); else { custom_mount_free_all(arg_custom_mounts, arg_n_custom_mounts); arg_custom_mounts = TAKE_PTR(settings->custom_mounts); @@ -3337,7 +3272,7 @@ static int load_settings(void) { settings->network_veth_extra)) { if (!arg_settings_trusted) - log_warning("Ignoring network settings, file %s is not trusted.", p); + log_warning("Ignoring network settings, file %s is not trusted.", path); else { arg_network_veth = settings_network_veth(settings); arg_private_network = settings_private_network(settings); @@ -3356,7 +3291,7 @@ static int load_settings(void) { settings->expose_ports) { if (!arg_settings_trusted) - log_warning("Ignoring Port= setting, file %s is not trusted.", p); + log_warning("Ignoring Port= setting, file %s is not trusted.", path); else { expose_port_free_all(arg_expose_ports); arg_expose_ports = TAKE_PTR(settings->expose_ports); @@ -3367,7 +3302,7 @@ static int load_settings(void) { settings->userns_mode != _USER_NAMESPACE_MODE_INVALID) { if (!arg_settings_trusted) - log_warning("Ignoring PrivateUsers= and PrivateUsersChown= settings, file %s is not trusted.", p); + log_warning("Ignoring PrivateUsers= and PrivateUsersChown= settings, file %s is not trusted.", path); else { arg_userns_mode = settings->userns_mode; arg_uid_shift = settings->uid_shift; @@ -3382,7 +3317,7 @@ static int load_settings(void) { if ((arg_settings_mask & SETTING_SYSCALL_FILTER) == 0) { if (!arg_settings_trusted && !strv_isempty(arg_syscall_whitelist)) - log_warning("Ignoring SystemCallFilter= settings, file %s is not trusted.", p); + log_warning("Ignoring SystemCallFilter= settings, file %s is not trusted.", path); else { strv_free_and_replace(arg_syscall_whitelist, settings->syscall_whitelist); strv_free_and_replace(arg_syscall_blacklist, settings->syscall_blacklist); @@ -3397,7 +3332,7 @@ static int load_settings(void) { continue; if (!arg_settings_trusted) { - log_warning("Ignoring Limit%s= setting, file '%s' is not trusted.", rlimit_to_string(rl), p); + log_warning("Ignoring Limit%s= setting, file '%s' is not trusted.", rlimit_to_string(rl), path); continue; } @@ -3416,7 +3351,7 @@ static int load_settings(void) { settings->oom_score_adjust_set) { if (!arg_settings_trusted) - log_warning("Ignoring OOMScoreAdjust= setting, file '%s' is not trusted.", p); + log_warning("Ignoring OOMScoreAdjust= setting, file '%s' is not trusted.", path); else { arg_oom_score_adjust = settings->oom_score_adjust; arg_oom_score_adjust_set = true; @@ -3427,7 +3362,7 @@ static int load_settings(void) { settings->cpuset) { if (!arg_settings_trusted) - log_warning("Ignoring CPUAffinity= setting, file '%s' is not trusted.", p); + log_warning("Ignoring CPUAffinity= setting, file '%s' is not trusted.", path); else { if (arg_cpuset) CPU_FREE(arg_cpuset); @@ -3439,6 +3374,80 @@ static int load_settings(void) { return 0; } +static int load_settings(void) { + _cleanup_(settings_freep) Settings *settings = NULL; + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *p = NULL; + const char *fn, *i; + int r; + + /* If all settings are masked, there's no point in looking for + * the settings file */ + if ((arg_settings_mask & _SETTINGS_MASK_ALL) == _SETTINGS_MASK_ALL) + return 0; + + fn = strjoina(arg_machine, ".nspawn"); + + /* We first look in the admin's directories in /etc and /run */ + FOREACH_STRING(i, "/etc/systemd/nspawn", "/run/systemd/nspawn") { + _cleanup_free_ char *j = NULL; + + j = strjoin(i, "/", fn); + if (!j) + return log_oom(); + + f = fopen(j, "re"); + if (f) { + p = TAKE_PTR(j); + + /* By default, we trust configuration from /etc and /run */ + if (arg_settings_trusted < 0) + arg_settings_trusted = true; + + break; + } + + if (errno != ENOENT) + return log_error_errno(errno, "Failed to open %s: %m", j); + } + + if (!f) { + /* After that, let's look for a file next to the + * actual image we shall boot. */ + + if (arg_image) { + p = file_in_same_dir(arg_image, fn); + if (!p) + return log_oom(); + } else if (arg_directory) { + p = file_in_same_dir(arg_directory, fn); + if (!p) + return log_oom(); + } + + if (p) { + f = fopen(p, "re"); + if (!f && errno != ENOENT) + return log_error_errno(errno, "Failed to open %s: %m", p); + + /* By default, we do not trust configuration from /var/lib/machines */ + if (arg_settings_trusted < 0) + arg_settings_trusted = false; + } + } + + if (!f) + return 0; + + log_debug("Settings are trusted: %s", yes_no(arg_settings_trusted)); + + r = settings_load(f, p, &settings); + if (r < 0) + return r; + + return merge_settings(settings, p); +} + static int run(int master, const char* console, DissectedImage *dissected_image, -- 2.7.4