From 28135da3cdca53157bd878ae00b15d6e33ca4987 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 9 Mar 2023 15:10:23 +0100 Subject: core: Introduce unit private exec runtime Currently, exec runtimes can be shared between units (using JoinsNamespaceOf=). Let's introduce a concept of a private exec runtime that isn't shared with JoinsNamespaceOf=. The existing ExecRuntime struct is renamed to ExecRuntimeShared and becomes a private member of the new private ExecRuntime. --- src/core/execute.c | 90 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 26 deletions(-) (limited to 'src/core/execute.c') diff --git a/src/core/execute.c b/src/core/execute.c index 3011f15dfb..86cfe99e8b 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2178,7 +2178,7 @@ static bool exec_needs_ipc_namespace(const ExecContext *context) { bool exec_needs_mount_namespace( const ExecContext *context, const ExecParameters *params, - const ExecSharedRuntime *runtime) { + const ExecRuntime *runtime) { assert(context); @@ -2210,7 +2210,7 @@ bool exec_needs_mount_namespace( if (!IN_SET(context->mount_propagation_flag, 0, MS_SHARED)) return true; - if (context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir)) + if (context->private_tmp && runtime && runtime->shared && (runtime->shared->tmp_dir || runtime->shared->var_tmp_dir)) return true; if (context->private_devices || @@ -3683,7 +3683,7 @@ static int apply_mount_namespace( ExecCommandFlags command_flags, const ExecContext *context, const ExecParameters *params, - const ExecSharedRuntime *runtime, + const ExecRuntime *runtime, const char *memory_pressure_path, char **error_path) { @@ -3742,16 +3742,16 @@ static int apply_mount_namespace( * that is sticky, and that's the one we want to use here. * This does not apply when we are using /run/systemd/empty as fallback. */ - if (context->private_tmp && runtime) { - if (streq_ptr(runtime->tmp_dir, RUN_SYSTEMD_EMPTY)) - tmp_dir = runtime->tmp_dir; - else if (runtime->tmp_dir) - tmp_dir = strjoina(runtime->tmp_dir, "/tmp"); + if (context->private_tmp && runtime && runtime->shared) { + if (streq_ptr(runtime->shared->tmp_dir, RUN_SYSTEMD_EMPTY)) + tmp_dir = runtime->shared->tmp_dir; + else if (runtime->shared->tmp_dir) + tmp_dir = strjoina(runtime->shared->tmp_dir, "/tmp"); - if (streq_ptr(runtime->var_tmp_dir, RUN_SYSTEMD_EMPTY)) - var_tmp_dir = runtime->var_tmp_dir; - else if (runtime->var_tmp_dir) - var_tmp_dir = strjoina(runtime->var_tmp_dir, "/tmp"); + if (streq_ptr(runtime->shared->var_tmp_dir, RUN_SYSTEMD_EMPTY)) + var_tmp_dir = runtime->shared->var_tmp_dir; + else if (runtime->shared->var_tmp_dir) + var_tmp_dir = strjoina(runtime->shared->var_tmp_dir, "/tmp"); } ns_info = (NamespaceInfo) { @@ -4056,7 +4056,7 @@ static void append_socket_pair(int *array, size_t *n, const int pair[static 2]) static int close_remaining_fds( const ExecParameters *params, - const ExecSharedRuntime *runtime, + const ExecRuntime *runtime, const DynamicCreds *dcreds, int user_lookup_fd, int socket_fd, @@ -4081,9 +4081,9 @@ static int close_remaining_fds( n_dont_close += n_fds; } - if (runtime) { - append_socket_pair(dont_close, &n_dont_close, runtime->netns_storage_socket); - append_socket_pair(dont_close, &n_dont_close, runtime->ipcns_storage_socket); + if (runtime && runtime->shared) { + append_socket_pair(dont_close, &n_dont_close, runtime->shared->netns_storage_socket); + append_socket_pair(dont_close, &n_dont_close, runtime->shared->ipcns_storage_socket); } if (dcreds) { @@ -4403,7 +4403,7 @@ static int exec_child( const ExecCommand *command, const ExecContext *context, const ExecParameters *params, - ExecSharedRuntime *runtime, + ExecRuntime *runtime, DynamicCreds *dcreds, const CGroupContext *cgroup_context, int socket_fd, @@ -4686,16 +4686,16 @@ static int exec_child( } } - if (context->network_namespace_path && runtime && runtime->netns_storage_socket[0] >= 0) { - r = open_shareable_ns_path(runtime->netns_storage_socket, context->network_namespace_path, CLONE_NEWNET); + if (context->network_namespace_path && runtime && runtime->shared && runtime->shared->netns_storage_socket[0] >= 0) { + r = open_shareable_ns_path(runtime->shared->netns_storage_socket, context->network_namespace_path, CLONE_NEWNET); if (r < 0) { *exit_status = EXIT_NETWORK; return log_unit_error_errno(unit, r, "Failed to open network namespace path %s: %m", context->network_namespace_path); } } - if (context->ipc_namespace_path && runtime && runtime->ipcns_storage_socket[0] >= 0) { - r = open_shareable_ns_path(runtime->ipcns_storage_socket, context->ipc_namespace_path, CLONE_NEWIPC); + if (context->ipc_namespace_path && runtime && runtime->shared && runtime->shared->ipcns_storage_socket[0] >= 0) { + r = open_shareable_ns_path(runtime->shared->ipcns_storage_socket, context->ipc_namespace_path, CLONE_NEWIPC); if (r < 0) { *exit_status = EXIT_NAMESPACE; return log_unit_error_errno(unit, r, "Failed to open IPC namespace path %s: %m", context->ipc_namespace_path); @@ -5045,10 +5045,10 @@ static int exec_child( } } - if (exec_needs_network_namespace(context) && runtime && runtime->netns_storage_socket[0] >= 0) { + if (exec_needs_network_namespace(context) && runtime && runtime->shared && runtime->shared->netns_storage_socket[0] >= 0) { if (ns_type_supported(NAMESPACE_NET)) { - r = setup_shareable_ns(runtime->netns_storage_socket, CLONE_NEWNET); + r = setup_shareable_ns(runtime->shared->netns_storage_socket, CLONE_NEWNET); if (r < 0) { if (ERRNO_IS_PRIVILEGE(r)) log_unit_warning_errno(unit, r, @@ -5066,10 +5066,10 @@ static int exec_child( log_unit_warning(unit, "PrivateNetwork=yes is configured, but the kernel does not support network namespaces, ignoring."); } - if (exec_needs_ipc_namespace(context) && runtime && runtime->ipcns_storage_socket[0] >= 0) { + if (exec_needs_ipc_namespace(context) && runtime && runtime->shared && runtime->shared->ipcns_storage_socket[0] >= 0) { if (ns_type_supported(NAMESPACE_IPC)) { - r = setup_shareable_ns(runtime->ipcns_storage_socket, CLONE_NEWIPC); + r = setup_shareable_ns(runtime->shared->ipcns_storage_socket, CLONE_NEWIPC); if (r == -EPERM) log_unit_warning_errno(unit, r, "PrivateIPC=yes is configured, but IPC namespace setup failed, ignoring: %m"); @@ -5549,7 +5549,7 @@ int exec_spawn(Unit *unit, ExecCommand *command, const ExecContext *context, const ExecParameters *params, - ExecSharedRuntime *runtime, + ExecRuntime *runtime, DynamicCreds *dcreds, const CGroupContext *cgroup_context, pid_t *ret) { @@ -7439,6 +7439,44 @@ void exec_shared_runtime_vacuum(Manager *m) { } } +int exec_runtime_make(ExecSharedRuntime *shared, ExecRuntime **ret) { + _cleanup_(exec_runtime_freep) ExecRuntime *rt = NULL; + + assert(ret); + + if (!shared) { + *ret = NULL; + return 0; + } + + rt = new(ExecRuntime, 1); + if (!rt) + return -ENOMEM; + + *rt = (ExecRuntime) { + .shared = shared, + }; + + *ret = TAKE_PTR(rt); + return 1; +} + +ExecRuntime* exec_runtime_free(ExecRuntime *rt) { + if (!rt) + return NULL; + + exec_shared_runtime_unref(rt->shared); + return mfree(rt); +} + +ExecRuntime* exec_runtime_destroy(ExecRuntime *rt) { + if (!rt) + return NULL; + + rt->shared = exec_shared_runtime_destroy(rt->shared); + return exec_runtime_free(rt); +} + void exec_params_clear(ExecParameters *p) { if (!p) return; -- cgit v1.2.1