diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2017-10-25 23:35:56 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2017-10-25 23:35:56 -0400 |
commit | 2f6febc5aa0dedd5ca1fb8437e122efdf3a33de0 (patch) | |
tree | 789e4adc702fcc398d3efd2d2af752897849e0f7 | |
parent | 84947e3c16c4052a1ab2b63a4dd67ba9b7423832 (diff) |
a
-rw-r--r-- | src/nspawn/nspawn.c | 302 |
1 files changed, 14 insertions, 288 deletions
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 016f40b30d..ba8f5fccf4 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -136,11 +136,6 @@ static sd_id128_t arg_uuid = {}; static char *arg_machine = NULL; static const char *arg_selinux_context = NULL; static const char *arg_selinux_apifs_context = NULL; -static const char *arg_slice = NULL; -static bool arg_read_only = false; -static StartMode arg_start_mode = START_PID1; -static LinkJournal arg_link_journal = LINK_AUTO; -static bool arg_link_journal_try = false; static uint64_t arg_caps_retain = (1ULL << CAP_AUDIT_CONTROL) | (1ULL << CAP_AUDIT_WRITE) | @@ -172,14 +167,6 @@ static CustomMount *arg_custom_mounts = NULL; static unsigned arg_n_custom_mounts = 0; static char **arg_setenv = NULL; static bool arg_quiet = false; -static char **arg_network_interfaces = NULL; -static char **arg_network_macvlan = NULL; -static char **arg_network_ipvlan = NULL; -static char *arg_network_bridge = NULL; -static char *arg_network_zone = NULL; -static unsigned long arg_personality = PERSONALITY_INVALID; -static VolatileMode arg_volatile_mode = VOLATILE_NO; -static char **arg_property = NULL; static uid_t arg_uid_shift = UID_INVALID, arg_uid_range = 0x10000U; static int arg_kill_signal = 0; static CGroupUnified arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_UNKNOWN; @@ -239,40 +226,6 @@ static int detect_unified_cgroup_hierarchy(const char *directory) { return 0; } -static void parse_share_ns_env(const char *name, unsigned long ns_flag) { - int r; - - r = getenv_bool(name); - if (r == -ENXIO) - return; - if (r < 0) - log_warning_errno(r, "Failed to parse %s from environment, defaulting to false.", name); - arg_clone_ns_flags = (arg_clone_ns_flags & ~ns_flag) | (r > 0 ? 0 : ns_flag); -} - -static void parse_mount_settings_env(void) { - int r; - const char *e; - - e = getenv("SYSTEMD_NSPAWN_API_VFS_WRITABLE"); - if (!e) - return; - - if (streq(e, "network")) { - arg_mount_settings |= MOUNT_APPLY_APIVFS_RO|MOUNT_APPLY_APIVFS_NETNS; - return; - } - - r = parse_boolean(e); - if (r < 0) { - log_warning_errno(r, "Failed to parse SYSTEMD_NSPAWN_API_VFS_WRITABLE from environment, ignoring."); - return; - } - - SET_FLAG(arg_mount_settings, MOUNT_APPLY_APIVFS_RO, r == 0); - SET_FLAG(arg_mount_settings, MOUNT_APPLY_APIVFS_NETNS, false); -} - static int parse_argv(int argc, char *argv[]) { static const struct option options[] = { @@ -281,7 +234,6 @@ static int parse_argv(int argc, char *argv[]) { }; int c, r; - const char *e; uint64_t plus = 0, minus = 0; bool mask_all_settings = false, mask_no_settings = false; @@ -305,26 +257,6 @@ static int parse_argv(int argc, char *argv[]) { assert_not_reached("Unhandled option"); } - parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_IPC", CLONE_NEWIPC); - parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_PID", CLONE_NEWPID); - parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_UTS", CLONE_NEWUTS); - parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_SYSTEM", CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS); - - parse_mount_settings_env(); - - if (!(arg_clone_ns_flags & CLONE_NEWPID) || - !(arg_clone_ns_flags & CLONE_NEWUTS)) { - if (arg_start_mode != START_PID1) { - log_error("--boot cannot be used without namespacing."); - return -EINVAL; - } - } - - if (arg_network_bridge && arg_network_zone) { - log_error("--network-bridge= and --network-zone= may not be combined."); - return -EINVAL; - } - if (argc > optind) { arg_parameters = strv_copy(argv + optind); if (!arg_parameters) @@ -347,31 +279,11 @@ static int parse_argv(int argc, char *argv[]) { if (r < 0) return log_error_errno(r, "Failed to determine whether the unified cgroups hierarchy is used: %m"); - e = getenv("SYSTEMD_NSPAWN_CONTAINER_SERVICE"); - if (e) - arg_container_service_name = e; - - r = getenv_bool("SYSTEMD_NSPAWN_USE_CGNS"); - if (r < 0) - arg_use_cgns = cg_ns_supported(); - else - arg_use_cgns = r; + arg_use_cgns = cg_ns_supported(); return 1; } -static int verify_arguments(void) { - if (arg_volatile_mode != VOLATILE_NO && arg_read_only) { - log_error("Cannot combine --read-only with --volatile. Note that --volatile already implies a read-only base hierarchy."); - return -EINVAL; - } - - if (arg_start_mode == START_BOOT && arg_kill_signal <= 0) - arg_kill_signal = SIGRTMIN+3; - - return 0; -} - static int userns_mkdir(const char *root, const char *path, mode_t mode, uid_t uid, gid_t gid) { const char *q; @@ -672,137 +584,6 @@ static int setup_hostname(void) { return 0; } -static int setup_journal(const char *directory) { - sd_id128_t this_id; - _cleanup_free_ char *d = NULL; - const char *p, *q; - bool try; - char id[33]; - int r; - - if (arg_link_journal == LINK_NO) - return 0; - - try = arg_link_journal_try || arg_link_journal == LINK_AUTO; - - r = sd_id128_get_machine(&this_id); - if (r < 0) - return log_error_errno(r, "Failed to retrieve machine ID: %m"); - - if (sd_id128_equal(arg_uuid, this_id)) { - log_full(try ? LOG_WARNING : LOG_ERR, - "Host and machine ids are equal (%s): refusing to link journals", sd_id128_to_string(arg_uuid, id)); - if (try) - return 0; - return -EEXIST; - } - - r = userns_mkdir(directory, "/var", 0755, 0, 0); - if (r < 0) - return log_error_errno(r, "Failed to create /var: %m"); - - r = userns_mkdir(directory, "/var/log", 0755, 0, 0); - if (r < 0) - return log_error_errno(r, "Failed to create /var/log: %m"); - - r = userns_mkdir(directory, "/var/log/journal", 0755, 0, 0); - if (r < 0) - return log_error_errno(r, "Failed to create /var/log/journal: %m"); - - (void) sd_id128_to_string(arg_uuid, id); - - p = strjoina("/var/log/journal/", id); - q = prefix_roota(directory, p); - - if (path_is_mount_point(p, NULL, 0) > 0) { - if (try) - return 0; - - log_error("%s: already a mount point, refusing to use for journal", p); - return -EEXIST; - } - - if (path_is_mount_point(q, NULL, 0) > 0) { - if (try) - return 0; - - log_error("%s: already a mount point, refusing to use for journal", q); - return -EEXIST; - } - - r = readlink_and_make_absolute(p, &d); - if (r >= 0) { - if ((arg_link_journal == LINK_GUEST || - arg_link_journal == LINK_AUTO) && - path_equal(d, q)) { - - r = userns_mkdir(directory, p, 0755, 0, 0); - if (r < 0) - log_warning_errno(r, "Failed to create directory %s: %m", q); - return 0; - } - - if (unlink(p) < 0) - return log_error_errno(errno, "Failed to remove symlink %s: %m", p); - } else if (r == -EINVAL) { - - if (arg_link_journal == LINK_GUEST && - rmdir(p) < 0) { - - if (errno == ENOTDIR) { - log_error("%s already exists and is neither a symlink nor a directory", p); - return r; - } else - return log_error_errno(errno, "Failed to remove %s: %m", p); - } - } else if (r != -ENOENT) - return log_error_errno(r, "readlink(%s) failed: %m", p); - - if (arg_link_journal == LINK_GUEST) { - - if (symlink(q, p) < 0) { - if (try) { - log_debug_errno(errno, "Failed to symlink %s to %s, skipping journal setup: %m", q, p); - return 0; - } else - return log_error_errno(errno, "Failed to symlink %s to %s: %m", q, p); - } - - r = userns_mkdir(directory, p, 0755, 0, 0); - if (r < 0) - log_warning_errno(r, "Failed to create directory %s: %m", q); - return 0; - } - - if (arg_link_journal == LINK_HOST) { - /* don't create parents here — if the host doesn't have - * permanent journal set up, don't force it here */ - - if (mkdir(p, 0755) < 0 && errno != EEXIST) { - if (try) { - log_debug_errno(errno, "Failed to create %s, skipping journal setup: %m", p); - return 0; - } else - return log_error_errno(errno, "Failed to create %s: %m", p); - } - - } else if (access(p, F_OK) < 0) - return 0; - - if (dir_is_empty(q) == 0) - log_warning("%s is not empty, proceeding anyway.", q); - - r = userns_mkdir(directory, p, 0755, 0, 0); - if (r < 0) - return log_error_errno(r, "Failed to create %s: %m", q); - - r = mount_verbose(LOG_DEBUG, p, q, NULL, MS_BIND, NULL); - if (r < 0) - return log_error_errno(errno, "Failed to bind mount journal from host into guest: %m"); - - return 0; -} - static int drop_capabilities(void) { return capability_bounding_set_drop(arg_caps_retain, false); } @@ -1138,10 +919,7 @@ static int inner_child( setup_hostname(); - if (arg_personality != PERSONALITY_INVALID) { - if (personality(arg_personality) < 0) - return log_error_errno(errno, "personality() failed: %m"); - } else if (secondary) { + if (secondary) { if (personality(PER_LINUX32) < 0) return log_error_errno(errno, "personality() failed: %m"); } @@ -1201,12 +979,6 @@ static int inner_child( if (chdir(arg_chdir) < 0) return log_error_errno(errno, "Failed to change to specified working directory %s: %m", arg_chdir); - if (arg_start_mode == START_PID2) { - r = stub_pid1(arg_uuid); - if (r < 0) - return r; - } - /* Now, explicitly close the log, so that we * then can close all remaining fds. Closing * the log explicitly first has the benefit @@ -1218,28 +990,7 @@ static int inner_child( log_close(); (void) fdset_close_others(fds); - if (arg_start_mode == START_BOOT) { - char **a; - size_t m; - - /* Automatically search for the init system */ - - m = strv_length(arg_parameters); - a = newa(char*, m + 2); - memcpy_safe(a + 1, arg_parameters, m * sizeof(char*)); - a[1 + m] = NULL; - - a[0] = (char*) "/usr/lib/systemd/systemd"; - execve(a[0], a, env_use); - - a[0] = (char*) "/lib/systemd/systemd"; - execve(a[0], a, env_use); - - a[0] = (char*) "/sbin/init"; - execve(a[0], a, env_use); - - exec_target = "/usr/lib/systemd/systemd, /lib/systemd/systemd, /sbin/init"; - } else if (!strv_isempty(arg_parameters)) { + if (!strv_isempty(arg_parameters)) { exec_target = arg_parameters[0]; execvpe(arg_parameters[0], arg_parameters, env_use); } else { @@ -1353,7 +1104,7 @@ static int outer_child( return r; if (dissected_image) { - r = dissected_image_mount(dissected_image, directory, DISSECT_IMAGE_DISCARD_ON_LOOP|(arg_read_only ? DISSECT_IMAGE_READ_ONLY : 0)); + r = dissected_image_mount(dissected_image, directory, DISSECT_IMAGE_DISCARD_ON_LOOP); if (r < 0) return r; } @@ -1371,7 +1122,7 @@ static int outer_child( r = setup_volatile( directory, - arg_volatile_mode, + false, false, arg_uid_shift, arg_uid_range, @@ -1381,7 +1132,7 @@ static int outer_child( r = setup_volatile_state( directory, - arg_volatile_mode, + false, false, arg_uid_shift, arg_uid_range, @@ -1403,12 +1154,6 @@ static int outer_child( if (r < 0) return r; - if (arg_read_only) { - r = bind_remount_recursive(directory, true, NULL); - if (r < 0) - return log_error_errno(r, "Failed to make tree read-only: %m"); - } - r = mount_all(directory, arg_mount_settings, arg_uid_shift, @@ -1451,10 +1196,6 @@ static int outer_child( if (r < 0) return r; - r = setup_journal(directory); - if (r < 0) - return r; - r = mount_custom( directory, arg_custom_mounts, @@ -1775,9 +1516,6 @@ static int run(int master, log_debug("Init process invoked as PID "PID_FMT, *pid); - if (arg_slice || arg_property) - log_notice("Machine and scope registration turned off, --slice= and --property= settings will have no effect."); - r = sync_cgroup(*pid, arg_unified_cgroup_hierarchy, arg_uid_shift); if (r < 0) return r; @@ -1929,11 +1667,9 @@ int main(int argc, char *argv[]) { if (r < 0) goto finish; - r = verify_arguments(); - if (r < 0) - goto finish; - if (arg_directory) { + const char *p; + if (path_equal(arg_directory, "/")) { log_error("Spawning container on root directory is not supported. Consider using --ephemeral."); r = -EINVAL; @@ -1944,7 +1680,7 @@ int main(int argc, char *argv[]) { if (r < 0) goto finish; - r = image_path_lock(arg_directory, (arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB, &tree_global_lock, &tree_local_lock); + r = image_path_lock(arg_directory, LOCK_EX | LOCK_NB, &tree_global_lock, &tree_local_lock); if (r == -EBUSY) { log_error_errno(r, "Directory tree %s is currently busy.", arg_directory); goto finish; @@ -1954,18 +1690,12 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_start_mode == START_BOOT) { - } else { - const char *p; - - p = strjoina(arg_directory, "/usr/"); - if (laccess(p, F_OK) < 0) { - log_error("Directory %s doesn't look like it has an OS tree. Refusing.", arg_directory); - r = -EINVAL; - goto finish; - } + p = strjoina(arg_directory, "/usr/"); + if (laccess(p, F_OK) < 0) { + log_error("Directory %s doesn't look like it has an OS tree. Refusing.", arg_directory); + r = -EINVAL; + goto finish; } - } r = detect_unified_cgroup_hierarchy(arg_directory); @@ -2025,10 +1755,6 @@ finish: free(arg_machine); free(arg_chdir); strv_free(arg_setenv); - free(arg_network_bridge); - strv_free(arg_network_interfaces); - strv_free(arg_network_macvlan); - strv_free(arg_network_ipvlan); strv_free(arg_parameters); custom_mount_free_all(arg_custom_mounts, arg_n_custom_mounts); free(arg_root_hash); |