From e76506b74816174cf9ec26262c7c4669a6d5172d Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Sun, 26 Mar 2023 20:07:36 +0200 Subject: [PATCH 1/4] execute: Rename ExecRuntime to ExecSharedRuntime Preparation for next commit --- src/core/execute.c | 102 +++++++++++++++++------------------ src/core/execute.h | 20 +++---- src/core/manager-serialize.c | 4 +- src/core/manager.c | 8 +-- src/core/manager.h | 4 +- src/core/mount.c | 4 +- src/core/mount.h | 2 +- src/core/service.c | 4 +- src/core/service.h | 2 +- src/core/socket.c | 4 +- src/core/socket.h | 2 +- src/core/swap.c | 4 +- src/core/swap.h | 2 +- src/core/unit-serialize.c | 2 +- src/core/unit.c | 14 ++--- src/core/unit.h | 4 +- 16 files changed, 91 insertions(+), 91 deletions(-) diff --git a/src/core/execute.c b/src/core/execute.c index bfdd2026c6..b5cf140f72 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 ExecRuntime *runtime) { + const ExecSharedRuntime *runtime) { assert(context); @@ -3683,7 +3683,7 @@ static int apply_mount_namespace( ExecCommandFlags command_flags, const ExecContext *context, const ExecParameters *params, - const ExecRuntime *runtime, + const ExecSharedRuntime *runtime, const char *memory_pressure_path, char **error_path) { @@ -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 ExecRuntime *runtime, + const ExecSharedRuntime *runtime, const DynamicCreds *dcreds, int user_lookup_fd, int socket_fd, @@ -4403,7 +4403,7 @@ static int exec_child( const ExecCommand *command, const ExecContext *context, const ExecParameters *params, - ExecRuntime *runtime, + ExecSharedRuntime *runtime, DynamicCreds *dcreds, const CGroupContext *cgroup_context, int socket_fd, @@ -5549,7 +5549,7 @@ int exec_spawn(Unit *unit, ExecCommand *command, const ExecContext *context, const ExecParameters *params, - ExecRuntime *runtime, + ExecSharedRuntime *runtime, DynamicCreds *dcreds, const CGroupContext *cgroup_context, pid_t *ret) { @@ -6956,14 +6956,14 @@ static void *remove_tmpdir_thread(void *p) { return NULL; } -static ExecRuntime* exec_runtime_free(ExecRuntime *rt, bool destroy) { +static ExecSharedRuntime* exec_shared_runtime_free(ExecSharedRuntime *rt, bool destroy) { int r; if (!rt) return NULL; if (rt->manager) - (void) hashmap_remove(rt->manager->exec_runtime_by_id, rt->id); + (void) hashmap_remove(rt->manager->exec_shared_runtime_by_id, rt->id); /* When destroy is true, then rm_rf tmp_dir and var_tmp_dir. */ @@ -6995,13 +6995,13 @@ static ExecRuntime* exec_runtime_free(ExecRuntime *rt, bool destroy) { return mfree(rt); } -static void exec_runtime_freep(ExecRuntime **rt) { - (void) exec_runtime_free(*rt, false); +static void exec_shared_runtime_freep(ExecSharedRuntime **rt) { + (void) exec_shared_runtime_free(*rt, false); } -static int exec_runtime_allocate(ExecRuntime **ret, const char *id) { +static int exec_shared_runtime_allocate(ExecSharedRuntime **ret, const char *id) { _cleanup_free_ char *id_copy = NULL; - ExecRuntime *n; + ExecSharedRuntime *n; assert(ret); @@ -7009,11 +7009,11 @@ static int exec_runtime_allocate(ExecRuntime **ret, const char *id) { if (!id_copy) return -ENOMEM; - n = new(ExecRuntime, 1); + n = new(ExecSharedRuntime, 1); if (!n) return -ENOMEM; - *n = (ExecRuntime) { + *n = (ExecSharedRuntime) { .id = TAKE_PTR(id_copy), .netns_storage_socket = PIPE_EBADF, .ipcns_storage_socket = PIPE_EBADF, @@ -7023,16 +7023,16 @@ static int exec_runtime_allocate(ExecRuntime **ret, const char *id) { return 0; } -static int exec_runtime_add( +static int exec_shared_runtime_add( Manager *m, const char *id, char **tmp_dir, char **var_tmp_dir, int netns_storage_socket[2], int ipcns_storage_socket[2], - ExecRuntime **ret) { + ExecSharedRuntime **ret) { - _cleanup_(exec_runtime_freep) ExecRuntime *rt = NULL; + _cleanup_(exec_shared_runtime_freep) ExecSharedRuntime *rt = NULL; int r; assert(m); @@ -7040,11 +7040,11 @@ static int exec_runtime_add( /* tmp_dir, var_tmp_dir, {net,ipc}ns_storage_socket fds are donated on success */ - r = exec_runtime_allocate(&rt, id); + r = exec_shared_runtime_allocate(&rt, id); if (r < 0) return r; - r = hashmap_ensure_put(&m->exec_runtime_by_id, &string_hash_ops, rt->id, rt); + r = hashmap_ensure_put(&m->exec_shared_runtime_by_id, &string_hash_ops, rt->id, rt); if (r < 0) return r; @@ -7066,16 +7066,16 @@ static int exec_runtime_add( if (ret) *ret = rt; - /* do not remove created ExecRuntime object when the operation succeeds. */ + /* do not remove created ExecSharedRuntime object when the operation succeeds. */ TAKE_PTR(rt); return 0; } -static int exec_runtime_make( +static int exec_shared_runtime_make( Manager *m, const ExecContext *c, const char *id, - ExecRuntime **ret) { + ExecSharedRuntime **ret) { _cleanup_(namespace_cleanup_tmpdirp) char *tmp_dir = NULL, *var_tmp_dir = NULL; _cleanup_close_pair_ int netns_storage_socket[2] = PIPE_EBADF, ipcns_storage_socket[2] = PIPE_EBADF; @@ -7085,7 +7085,7 @@ static int exec_runtime_make( assert(c); assert(id); - /* It is not necessary to create ExecRuntime object. */ + /* It is not necessary to create ExecSharedRuntime object. */ if (!exec_needs_network_namespace(c) && !exec_needs_ipc_namespace(c) && !c->private_tmp) { *ret = NULL; return 0; @@ -7110,24 +7110,24 @@ static int exec_runtime_make( return -errno; } - r = exec_runtime_add(m, id, &tmp_dir, &var_tmp_dir, netns_storage_socket, ipcns_storage_socket, ret); + r = exec_shared_runtime_add(m, id, &tmp_dir, &var_tmp_dir, netns_storage_socket, ipcns_storage_socket, ret); if (r < 0) return r; return 1; } -int exec_runtime_acquire(Manager *m, const ExecContext *c, const char *id, bool create, ExecRuntime **ret) { - ExecRuntime *rt; +int exec_shared_runtime_acquire(Manager *m, const ExecContext *c, const char *id, bool create, ExecSharedRuntime **ret) { + ExecSharedRuntime *rt; int r; assert(m); assert(id); assert(ret); - rt = hashmap_get(m->exec_runtime_by_id, id); + rt = hashmap_get(m->exec_shared_runtime_by_id, id); if (rt) - /* We already have an ExecRuntime object, let's increase the ref count and reuse it */ + /* We already have an ExecSharedRuntime object, let's increase the ref count and reuse it */ goto ref; if (!create) { @@ -7136,11 +7136,11 @@ int exec_runtime_acquire(Manager *m, const ExecContext *c, const char *id, bool } /* If not found, then create a new object. */ - r = exec_runtime_make(m, c, id, &rt); + r = exec_shared_runtime_make(m, c, id, &rt); if (r < 0) return r; if (r == 0) { - /* When r == 0, it is not necessary to create ExecRuntime object. */ + /* When r == 0, it is not necessary to create ExecSharedRuntime object. */ *ret = NULL; return 0; } @@ -7152,7 +7152,7 @@ ref: return 1; } -ExecRuntime *exec_runtime_unref(ExecRuntime *rt, bool destroy) { +ExecSharedRuntime *exec_shared_runtime_unref(ExecSharedRuntime *rt, bool destroy) { if (!rt) return NULL; @@ -7162,17 +7162,17 @@ ExecRuntime *exec_runtime_unref(ExecRuntime *rt, bool destroy) { if (rt->n_ref > 0) return NULL; - return exec_runtime_free(rt, destroy); + return exec_shared_runtime_free(rt, destroy); } -int exec_runtime_serialize(const Manager *m, FILE *f, FDSet *fds) { - ExecRuntime *rt; +int exec_shared_runtime_serialize(const Manager *m, FILE *f, FDSet *fds) { + ExecSharedRuntime *rt; assert(m); assert(f); assert(fds); - HASHMAP_FOREACH(rt, m->exec_runtime_by_id) { + HASHMAP_FOREACH(rt, m->exec_shared_runtime_by_id) { fprintf(f, "exec-runtime=%s", rt->id); if (rt->tmp_dir) @@ -7227,33 +7227,33 @@ int exec_runtime_serialize(const Manager *m, FILE *f, FDSet *fds) { return 0; } -int exec_runtime_deserialize_compat(Unit *u, const char *key, const char *value, FDSet *fds) { - _cleanup_(exec_runtime_freep) ExecRuntime *rt_create = NULL; - ExecRuntime *rt; +int exec_shared_runtime_deserialize_compat(Unit *u, const char *key, const char *value, FDSet *fds) { + _cleanup_(exec_shared_runtime_freep) ExecSharedRuntime *rt_create = NULL; + ExecSharedRuntime *rt; int r; /* This is for the migration from old (v237 or earlier) deserialization text. * Due to the bug #7790, this may not work with the units that use JoinsNamespaceOf=. - * Even if the ExecRuntime object originally created by the other unit, we cannot judge + * Even if the ExecSharedRuntime object originally created by the other unit, we cannot judge * so or not from the serialized text, then we always creates a new object owned by this. */ assert(u); assert(key); assert(value); - /* Manager manages ExecRuntime objects by the unit id. + /* Manager manages ExecSharedRuntime objects by the unit id. * So, we omit the serialized text when the unit does not have id (yet?)... */ if (isempty(u->id)) { log_unit_debug(u, "Invocation ID not found. Dropping runtime parameter."); return 0; } - if (hashmap_ensure_allocated(&u->manager->exec_runtime_by_id, &string_hash_ops) < 0) + if (hashmap_ensure_allocated(&u->manager->exec_shared_runtime_by_id, &string_hash_ops) < 0) return log_oom(); - rt = hashmap_get(u->manager->exec_runtime_by_id, u->id); + rt = hashmap_get(u->manager->exec_shared_runtime_by_id, u->id); if (!rt) { - if (exec_runtime_allocate(&rt_create, u->id) < 0) + if (exec_shared_runtime_allocate(&rt_create, u->id) < 0) return log_oom(); rt = rt_create; @@ -7292,9 +7292,9 @@ int exec_runtime_deserialize_compat(Unit *u, const char *key, const char *value, } else return 0; - /* If the object is newly created, then put it to the hashmap which manages ExecRuntime objects. */ + /* If the object is newly created, then put it to the hashmap which manages ExecSharedRuntime objects. */ if (rt_create) { - r = hashmap_put(u->manager->exec_runtime_by_id, rt_create->id, rt_create); + r = hashmap_put(u->manager->exec_shared_runtime_by_id, rt_create->id, rt_create); if (r < 0) { log_unit_debug_errno(u, r, "Failed to put runtime parameter to manager's storage: %m"); return 0; @@ -7309,7 +7309,7 @@ int exec_runtime_deserialize_compat(Unit *u, const char *key, const char *value, return 1; } -int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) { +int exec_shared_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) { _cleanup_free_ char *tmp_dir = NULL, *var_tmp_dir = NULL; char *id = NULL; int r, netns_fdpair[] = {-1, -1}, ipcns_fdpair[] = {-1, -1}; @@ -7421,24 +7421,24 @@ int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) { } finalize: - r = exec_runtime_add(m, id, &tmp_dir, &var_tmp_dir, netns_fdpair, ipcns_fdpair, NULL); + r = exec_shared_runtime_add(m, id, &tmp_dir, &var_tmp_dir, netns_fdpair, ipcns_fdpair, NULL); if (r < 0) return log_debug_errno(r, "Failed to add exec-runtime: %m"); return 0; } -void exec_runtime_vacuum(Manager *m) { - ExecRuntime *rt; +void exec_shared_runtime_vacuum(Manager *m) { + ExecSharedRuntime *rt; assert(m); - /* Free unreferenced ExecRuntime objects. This is used after manager deserialization process. */ + /* Free unreferenced ExecSharedRuntime objects. This is used after manager deserialization process. */ - HASHMAP_FOREACH(rt, m->exec_runtime_by_id) { + HASHMAP_FOREACH(rt, m->exec_shared_runtime_by_id) { if (rt->n_ref > 0) continue; - (void) exec_runtime_free(rt, false); + (void) exec_shared_runtime_free(rt, false); } } diff --git a/src/core/execute.h b/src/core/execute.h index ff537b77cb..95d5de8fb8 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -4,7 +4,7 @@ typedef struct ExecStatus ExecStatus; typedef struct ExecCommand ExecCommand; typedef struct ExecContext ExecContext; -typedef struct ExecRuntime ExecRuntime; +typedef struct ExecSharedRuntime ExecSharedRuntime; typedef struct ExecParameters ExecParameters; typedef struct Manager Manager; @@ -106,7 +106,7 @@ struct ExecCommand { * invocations of commands. Specifically, this allows sharing of /tmp and /var/tmp data as well as network namespaces * between invocations of commands. This is a reference counted object, with one reference taken by each currently * active command invocation that wants to share this runtime. */ -struct ExecRuntime { +struct ExecSharedRuntime { unsigned n_ref; Manager *manager; @@ -439,7 +439,7 @@ int exec_spawn(Unit *unit, ExecCommand *command, const ExecContext *context, const ExecParameters *exec_params, - ExecRuntime *runtime, + ExecSharedRuntime *runtime, DynamicCreds *dynamic_creds, const CGroupContext *cgroup_context, pid_t *ret); @@ -483,13 +483,13 @@ void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix); void exec_status_reset(ExecStatus *s); -int exec_runtime_acquire(Manager *m, const ExecContext *c, const char *name, bool create, ExecRuntime **ret); -ExecRuntime *exec_runtime_unref(ExecRuntime *r, bool destroy); +int exec_shared_runtime_acquire(Manager *m, const ExecContext *c, const char *name, bool create, ExecSharedRuntime **ret); +ExecSharedRuntime *exec_shared_runtime_unref(ExecSharedRuntime *r, bool destroy); -int exec_runtime_serialize(const Manager *m, FILE *f, FDSet *fds); -int exec_runtime_deserialize_compat(Unit *u, const char *key, const char *value, FDSet *fds); -int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds); -void exec_runtime_vacuum(Manager *m); +int exec_shared_runtime_serialize(const Manager *m, FILE *f, FDSet *fds); +int exec_shared_runtime_deserialize_compat(Unit *u, const char *key, const char *value, FDSet *fds); +int exec_shared_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds); +void exec_shared_runtime_vacuum(Manager *m); void exec_params_clear(ExecParameters *p); @@ -532,5 +532,5 @@ ExecDirectoryType exec_directory_type_symlink_from_string(const char *s) _pure_; const char* exec_resource_type_to_string(ExecDirectoryType i) _const_; ExecDirectoryType exec_resource_type_from_string(const char *s) _pure_; -bool exec_needs_mount_namespace(const ExecContext *context, const ExecParameters *params, const ExecRuntime *runtime); +bool exec_needs_mount_namespace(const ExecContext *context, const ExecParameters *params, const ExecSharedRuntime *runtime); bool exec_needs_network_namespace(const ExecContext *context); diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c index 61a464c06b..080383ced2 100644 --- a/src/core/manager-serialize.c +++ b/src/core/manager-serialize.c @@ -174,7 +174,7 @@ int manager_serialize( manager_serialize_uid_refs(m, f); manager_serialize_gid_refs(m, f); - r = exec_runtime_serialize(m, f, fds); + r = exec_shared_runtime_serialize(m, f, fds); if (r < 0) return r; @@ -519,7 +519,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { else if ((val = startswith(l, "destroy-ipc-gid="))) manager_deserialize_gid_refs_one(m, val); else if ((val = startswith(l, "exec-runtime="))) - (void) exec_runtime_deserialize_one(m, val, fds); + (void) exec_shared_runtime_deserialize_one(m, val, fds); else if ((val = startswith(l, "subscribed="))) { if (strv_extend(&m->deserialized_subscribed, val) < 0) diff --git a/src/core/manager.c b/src/core/manager.c index 14fb2a0f1f..dcc10266ac 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1555,8 +1555,8 @@ Manager* manager_free(Manager *m) { bus_done(m); manager_varlink_done(m); - exec_runtime_vacuum(m); - hashmap_free(m->exec_runtime_by_id); + exec_shared_runtime_vacuum(m); + hashmap_free(m->exec_shared_runtime_by_id); dynamic_user_vacuum(m, false); hashmap_free(m->dynamic_users); @@ -3459,7 +3459,7 @@ int manager_reload(Manager *m) { manager_clear_jobs_and_units(m); lookup_paths_flush_generator(&m->lookup_paths); lookup_paths_free(&m->lookup_paths); - exec_runtime_vacuum(m); + exec_shared_runtime_vacuum(m); dynamic_user_vacuum(m, false); m->uid_refs = hashmap_free(m->uid_refs); m->gid_refs = hashmap_free(m->gid_refs); @@ -4540,7 +4540,7 @@ static void manager_vacuum(Manager *m) { manager_vacuum_gid_refs(m); /* Release any runtimes no longer referenced */ - exec_runtime_vacuum(m); + exec_shared_runtime_vacuum(m); } int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) { diff --git a/src/core/manager.h b/src/core/manager.h index 25fcd275d4..fc95b75120 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -429,8 +429,8 @@ struct Manager { Hashmap *uid_refs; Hashmap *gid_refs; - /* ExecRuntime, indexed by their owner unit id */ - Hashmap *exec_runtime_by_id; + /* ExecSharedRuntime, indexed by their owner unit id */ + Hashmap *exec_shared_runtime_by_id; /* When the user hits C-A-D more than 7 times per 2s, do something immediately... */ RateLimit ctrl_alt_del_ratelimit; diff --git a/src/core/mount.c b/src/core/mount.c index bbe2226946..366986f312 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -254,7 +254,7 @@ static void mount_done(Unit *u) { mount_parameters_done(&m->parameters_proc_self_mountinfo); mount_parameters_done(&m->parameters_fragment); - m->exec_runtime = exec_runtime_unref(m->exec_runtime, false); + m->exec_runtime = exec_shared_runtime_unref(m->exec_runtime, false); exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX); m->control_command = NULL; @@ -948,7 +948,7 @@ static void mount_enter_dead(Mount *m, MountResult f) { mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD); - m->exec_runtime = exec_runtime_unref(m->exec_runtime, true); + m->exec_runtime = exec_shared_runtime_unref(m->exec_runtime, true); unit_destroy_runtime_data(UNIT(m), &m->exec_context); diff --git a/src/core/mount.h b/src/core/mount.h index 1a0d9fc5e5..39d7247170 100644 --- a/src/core/mount.h +++ b/src/core/mount.h @@ -75,7 +75,7 @@ struct Mount { KillContext kill_context; CGroupContext cgroup_context; - ExecRuntime *exec_runtime; + ExecSharedRuntime *exec_runtime; DynamicCreds dynamic_creds; MountState state, deserialized_state; diff --git a/src/core/service.c b/src/core/service.c index 21d1bf6595..bf04237130 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -383,7 +383,7 @@ static void service_done(Unit *u) { s->pid_file = mfree(s->pid_file); s->status_text = mfree(s->status_text); - s->exec_runtime = exec_runtime_unref(s->exec_runtime, false); + s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime, false); exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX); s->control_command = NULL; s->main_command = NULL; @@ -1925,7 +1925,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) s->notify_access_override = _NOTIFY_ACCESS_INVALID; /* We want fresh tmpdirs in case service is started again immediately */ - s->exec_runtime = exec_runtime_unref(s->exec_runtime, true); + s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime, true); /* Also, remove the runtime directory */ unit_destroy_runtime_data(UNIT(s), &s->exec_context); diff --git a/src/core/service.h b/src/core/service.h index 7663f26f70..92eeef4a7b 100644 --- a/src/core/service.h +++ b/src/core/service.h @@ -155,7 +155,7 @@ struct Service { ServiceExecCommand control_command_id; /* Runtime data of the execution context */ - ExecRuntime *exec_runtime; + ExecSharedRuntime *exec_runtime; DynamicCreds dynamic_creds; pid_t main_pid, control_pid; diff --git a/src/core/socket.c b/src/core/socket.c index 6b153a92fa..fddf5d680f 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -150,7 +150,7 @@ static void socket_done(Unit *u) { s->peers_by_address = set_free(s->peers_by_address); - s->exec_runtime = exec_runtime_unref(s->exec_runtime, false); + s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime, false); exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX); s->control_command = NULL; @@ -2049,7 +2049,7 @@ static void socket_enter_dead(Socket *s, SocketResult f) { socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD); - s->exec_runtime = exec_runtime_unref(s->exec_runtime, true); + s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime, true); unit_destroy_runtime_data(UNIT(s), &s->exec_context); diff --git a/src/core/socket.h b/src/core/socket.h index 6813bdcf8c..af65009ab8 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -90,7 +90,7 @@ struct Socket { KillContext kill_context; CGroupContext cgroup_context; - ExecRuntime *exec_runtime; + ExecSharedRuntime *exec_runtime; DynamicCreds dynamic_creds; /* For Accept=no sockets refers to the one service we'll diff --git a/src/core/swap.c b/src/core/swap.c index d0b557cf40..629ed52cf5 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -170,7 +170,7 @@ static void swap_done(Unit *u) { s->parameters_fragment.what = mfree(s->parameters_fragment.what); s->parameters_fragment.options = mfree(s->parameters_fragment.options); - s->exec_runtime = exec_runtime_unref(s->exec_runtime, false); + s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime, false); exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX); s->control_command = NULL; @@ -719,7 +719,7 @@ static void swap_enter_dead(Swap *s, SwapResult f) { unit_warn_leftover_processes(UNIT(s), unit_log_leftover_process_stop); swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD); - s->exec_runtime = exec_runtime_unref(s->exec_runtime, true); + s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime, true); unit_destroy_runtime_data(UNIT(s), &s->exec_context); diff --git a/src/core/swap.h b/src/core/swap.h index c0e3f118e1..49cd82c591 100644 --- a/src/core/swap.h +++ b/src/core/swap.h @@ -67,7 +67,7 @@ struct Swap { KillContext kill_context; CGroupContext cgroup_context; - ExecRuntime *exec_runtime; + ExecSharedRuntime *exec_runtime; DynamicCreds dynamic_creds; SwapState state, deserialized_state; diff --git a/src/core/unit-serialize.c b/src/core/unit-serialize.c index 21457dc6a5..8055d9e533 100644 --- a/src/core/unit-serialize.c +++ b/src/core/unit-serialize.c @@ -522,7 +522,7 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { continue; } - r = exec_runtime_deserialize_compat(u, l, v, fds); + r = exec_shared_runtime_deserialize_compat(u, l, v, fds); if (r < 0) { log_unit_warning(u, "Failed to deserialize runtime parameter '%s', ignoring.", l); continue; diff --git a/src/core/unit.c b/src/core/unit.c index 0418593d25..25e2509f51 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -4268,7 +4268,7 @@ CGroupContext *unit_get_cgroup_context(Unit *u) { return (CGroupContext*) ((uint8_t*) u + offset); } -ExecRuntime *unit_get_exec_runtime(Unit *u) { +ExecSharedRuntime *unit_get_exec_runtime(Unit *u) { size_t offset; if (u->type < 0) @@ -4278,7 +4278,7 @@ ExecRuntime *unit_get_exec_runtime(Unit *u) { if (offset <= 0) return NULL; - return *(ExecRuntime**) ((uint8_t*) u + offset); + return *(ExecSharedRuntime**) ((uint8_t*) u + offset); } static const char* unit_drop_in_dir(Unit *u, UnitWriteFlags flags) { @@ -4791,7 +4791,7 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask) } int unit_setup_exec_runtime(Unit *u) { - ExecRuntime **rt; + ExecSharedRuntime **rt; size_t offset; Unit *other; int r; @@ -4799,19 +4799,19 @@ int unit_setup_exec_runtime(Unit *u) { offset = UNIT_VTABLE(u)->exec_runtime_offset; assert(offset > 0); - /* Check if there already is an ExecRuntime for this unit? */ - rt = (ExecRuntime**) ((uint8_t*) u + offset); + /* Check if there already is an ExecSharedRuntime for this unit? */ + rt = (ExecSharedRuntime**) ((uint8_t*) u + offset); if (*rt) return 0; /* Try to get it from somebody else */ UNIT_FOREACH_DEPENDENCY(other, u, UNIT_ATOM_JOINS_NAMESPACE_OF) { - r = exec_runtime_acquire(u->manager, NULL, other->id, false, rt); + r = exec_shared_runtime_acquire(u->manager, NULL, other->id, false, rt); if (r == 1) return 1; } - return exec_runtime_acquire(u->manager, unit_get_exec_context(u), u->id, true, rt); + return exec_shared_runtime_acquire(u->manager, unit_get_exec_context(u), u->id, true, rt); } int unit_setup_dynamic_creds(Unit *u) { diff --git a/src/core/unit.h b/src/core/unit.h index 8f53773a11..19a50ac690 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -570,7 +570,7 @@ typedef struct UnitVTable { size_t kill_context_offset; /* If greater than 0, the offset into the object where the - * pointer to ExecRuntime is found, if the unit type has + * pointer to ExecSharedRuntime is found, if the unit type has * that */ size_t exec_runtime_offset; @@ -964,7 +964,7 @@ ExecContext *unit_get_exec_context(const Unit *u) _pure_; KillContext *unit_get_kill_context(Unit *u) _pure_; CGroupContext *unit_get_cgroup_context(Unit *u) _pure_; -ExecRuntime *unit_get_exec_runtime(Unit *u) _pure_; +ExecSharedRuntime *unit_get_exec_runtime(Unit *u) _pure_; int unit_setup_exec_runtime(Unit *u); int unit_setup_dynamic_creds(Unit *u); From e52a696a9af9e46e6e2be799a344bd9fb34dd3f4 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 27 Mar 2023 14:32:58 +0200 Subject: [PATCH 2/4] execute: Do not pass destroy as a boolean argument to unref() Let's mimick what we do for DynamicUser and have two separate functions for unreffing and destroying a ExecSharedRuntime object. --- src/core/execute.c | 79 ++++++++++++++++++++++------------------------ src/core/execute.h | 3 +- src/core/mount.c | 4 +-- src/core/service.c | 4 +-- src/core/socket.c | 4 +-- src/core/swap.c | 4 +-- 6 files changed, 48 insertions(+), 50 deletions(-) diff --git a/src/core/execute.c b/src/core/execute.c index b5cf140f72..3011f15dfb 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -6956,37 +6956,13 @@ static void *remove_tmpdir_thread(void *p) { return NULL; } -static ExecSharedRuntime* exec_shared_runtime_free(ExecSharedRuntime *rt, bool destroy) { - int r; - +static ExecSharedRuntime* exec_shared_runtime_free(ExecSharedRuntime *rt) { if (!rt) return NULL; if (rt->manager) (void) hashmap_remove(rt->manager->exec_shared_runtime_by_id, rt->id); - /* When destroy is true, then rm_rf tmp_dir and var_tmp_dir. */ - - if (destroy && rt->tmp_dir && !streq(rt->tmp_dir, RUN_SYSTEMD_EMPTY)) { - log_debug("Spawning thread to nuke %s", rt->tmp_dir); - - r = asynchronous_job(remove_tmpdir_thread, rt->tmp_dir); - if (r < 0) - log_warning_errno(r, "Failed to nuke %s: %m", rt->tmp_dir); - else - rt->tmp_dir = NULL; - } - - if (destroy && rt->var_tmp_dir && !streq(rt->var_tmp_dir, RUN_SYSTEMD_EMPTY)) { - log_debug("Spawning thread to nuke %s", rt->var_tmp_dir); - - r = asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir); - if (r < 0) - log_warning_errno(r, "Failed to nuke %s: %m", rt->var_tmp_dir); - else - rt->var_tmp_dir = NULL; - } - rt->id = mfree(rt->id); rt->tmp_dir = mfree(rt->tmp_dir); rt->var_tmp_dir = mfree(rt->var_tmp_dir); @@ -6995,8 +6971,42 @@ static ExecSharedRuntime* exec_shared_runtime_free(ExecSharedRuntime *rt, bool d return mfree(rt); } -static void exec_shared_runtime_freep(ExecSharedRuntime **rt) { - (void) exec_shared_runtime_free(*rt, false); +DEFINE_TRIVIAL_UNREF_FUNC(ExecSharedRuntime, exec_shared_runtime, exec_shared_runtime_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(ExecSharedRuntime*, exec_shared_runtime_free); + +ExecSharedRuntime* exec_shared_runtime_destroy(ExecSharedRuntime *rt) { + int r; + + if (!rt) + return NULL; + + assert(rt->n_ref > 0); + rt->n_ref--; + + if (rt->n_ref > 0) + return NULL; + + if (rt->tmp_dir && !streq(rt->tmp_dir, RUN_SYSTEMD_EMPTY)) { + log_debug("Spawning thread to nuke %s", rt->tmp_dir); + + r = asynchronous_job(remove_tmpdir_thread, rt->tmp_dir); + if (r < 0) + log_warning_errno(r, "Failed to nuke %s: %m", rt->tmp_dir); + else + rt->tmp_dir = NULL; + } + + if (rt->var_tmp_dir && !streq(rt->var_tmp_dir, RUN_SYSTEMD_EMPTY)) { + log_debug("Spawning thread to nuke %s", rt->var_tmp_dir); + + r = asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir); + if (r < 0) + log_warning_errno(r, "Failed to nuke %s: %m", rt->var_tmp_dir); + else + rt->var_tmp_dir = NULL; + } + + return exec_shared_runtime_free(rt); } static int exec_shared_runtime_allocate(ExecSharedRuntime **ret, const char *id) { @@ -7152,19 +7162,6 @@ ref: return 1; } -ExecSharedRuntime *exec_shared_runtime_unref(ExecSharedRuntime *rt, bool destroy) { - if (!rt) - return NULL; - - assert(rt->n_ref > 0); - - rt->n_ref--; - if (rt->n_ref > 0) - return NULL; - - return exec_shared_runtime_free(rt, destroy); -} - int exec_shared_runtime_serialize(const Manager *m, FILE *f, FDSet *fds) { ExecSharedRuntime *rt; @@ -7438,7 +7435,7 @@ void exec_shared_runtime_vacuum(Manager *m) { if (rt->n_ref > 0) continue; - (void) exec_shared_runtime_free(rt, false); + (void) exec_shared_runtime_free(rt); } } diff --git a/src/core/execute.h b/src/core/execute.h index 95d5de8fb8..10cd2c6046 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -484,7 +484,8 @@ void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix); void exec_status_reset(ExecStatus *s); int exec_shared_runtime_acquire(Manager *m, const ExecContext *c, const char *name, bool create, ExecSharedRuntime **ret); -ExecSharedRuntime *exec_shared_runtime_unref(ExecSharedRuntime *r, bool destroy); +ExecSharedRuntime *exec_shared_runtime_destroy(ExecSharedRuntime *r); +ExecSharedRuntime *exec_shared_runtime_unref(ExecSharedRuntime *r); int exec_shared_runtime_serialize(const Manager *m, FILE *f, FDSet *fds); int exec_shared_runtime_deserialize_compat(Unit *u, const char *key, const char *value, FDSet *fds); diff --git a/src/core/mount.c b/src/core/mount.c index 366986f312..e755a55964 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -254,7 +254,7 @@ static void mount_done(Unit *u) { mount_parameters_done(&m->parameters_proc_self_mountinfo); mount_parameters_done(&m->parameters_fragment); - m->exec_runtime = exec_shared_runtime_unref(m->exec_runtime, false); + m->exec_runtime = exec_shared_runtime_unref(m->exec_runtime); exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX); m->control_command = NULL; @@ -948,7 +948,7 @@ static void mount_enter_dead(Mount *m, MountResult f) { mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD); - m->exec_runtime = exec_shared_runtime_unref(m->exec_runtime, true); + m->exec_runtime = exec_shared_runtime_destroy(m->exec_runtime); unit_destroy_runtime_data(UNIT(m), &m->exec_context); diff --git a/src/core/service.c b/src/core/service.c index bf04237130..4894d94511 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -383,7 +383,7 @@ static void service_done(Unit *u) { s->pid_file = mfree(s->pid_file); s->status_text = mfree(s->status_text); - s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime, false); + s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime); exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX); s->control_command = NULL; s->main_command = NULL; @@ -1925,7 +1925,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) s->notify_access_override = _NOTIFY_ACCESS_INVALID; /* We want fresh tmpdirs in case service is started again immediately */ - s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime, true); + s->exec_runtime = exec_shared_runtime_destroy(s->exec_runtime); /* Also, remove the runtime directory */ unit_destroy_runtime_data(UNIT(s), &s->exec_context); diff --git a/src/core/socket.c b/src/core/socket.c index fddf5d680f..0e33c41def 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -150,7 +150,7 @@ static void socket_done(Unit *u) { s->peers_by_address = set_free(s->peers_by_address); - s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime, false); + s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime); exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX); s->control_command = NULL; @@ -2049,7 +2049,7 @@ static void socket_enter_dead(Socket *s, SocketResult f) { socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD); - s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime, true); + s->exec_runtime = exec_shared_runtime_destroy(s->exec_runtime); unit_destroy_runtime_data(UNIT(s), &s->exec_context); diff --git a/src/core/swap.c b/src/core/swap.c index 629ed52cf5..7b33060ab8 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -170,7 +170,7 @@ static void swap_done(Unit *u) { s->parameters_fragment.what = mfree(s->parameters_fragment.what); s->parameters_fragment.options = mfree(s->parameters_fragment.options); - s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime, false); + s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime); exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX); s->control_command = NULL; @@ -719,7 +719,7 @@ static void swap_enter_dead(Swap *s, SwapResult f) { unit_warn_leftover_processes(UNIT(s), unit_log_leftover_process_stop); swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD); - s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime, true); + s->exec_runtime = exec_shared_runtime_destroy(s->exec_runtime); unit_destroy_runtime_data(UNIT(s), &s->exec_context); From 28135da3cdca53157bd878ae00b15d6e33ca4987 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 9 Mar 2023 15:10:23 +0100 Subject: [PATCH 3/4] 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 ++++++++++++++++++++++++++++++++-------------- src/core/execute.h | 15 ++++++-- src/core/mount.c | 4 +-- src/core/mount.h | 2 +- src/core/service.c | 4 +-- src/core/service.h | 2 +- src/core/socket.c | 19 +++++----- src/core/socket.h | 2 +- src/core/swap.c | 4 +-- src/core/swap.h | 2 +- src/core/unit.c | 33 ++++++++++++----- src/core/unit.h | 2 +- 12 files changed, 123 insertions(+), 56 deletions(-) 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; diff --git a/src/core/execute.h b/src/core/execute.h index 10cd2c6046..32ed912f15 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -5,6 +5,7 @@ typedef struct ExecStatus ExecStatus; typedef struct ExecCommand ExecCommand; typedef struct ExecContext ExecContext; typedef struct ExecSharedRuntime ExecSharedRuntime; +typedef struct ExecRuntime ExecRuntime; typedef struct ExecParameters ExecParameters; typedef struct Manager Manager; @@ -124,6 +125,10 @@ struct ExecSharedRuntime { int ipcns_storage_socket[2]; }; +struct ExecRuntime { + ExecSharedRuntime *shared; +}; + typedef enum ExecDirectoryType { EXEC_DIRECTORY_RUNTIME = 0, EXEC_DIRECTORY_STATE, @@ -439,7 +444,7 @@ int exec_spawn(Unit *unit, ExecCommand *command, const ExecContext *context, const ExecParameters *exec_params, - ExecSharedRuntime *runtime, + ExecRuntime *runtime, DynamicCreds *dynamic_creds, const CGroupContext *cgroup_context, pid_t *ret); @@ -486,12 +491,18 @@ void exec_status_reset(ExecStatus *s); int exec_shared_runtime_acquire(Manager *m, const ExecContext *c, const char *name, bool create, ExecSharedRuntime **ret); ExecSharedRuntime *exec_shared_runtime_destroy(ExecSharedRuntime *r); ExecSharedRuntime *exec_shared_runtime_unref(ExecSharedRuntime *r); +DEFINE_TRIVIAL_CLEANUP_FUNC(ExecSharedRuntime*, exec_shared_runtime_unref); int exec_shared_runtime_serialize(const Manager *m, FILE *f, FDSet *fds); int exec_shared_runtime_deserialize_compat(Unit *u, const char *key, const char *value, FDSet *fds); int exec_shared_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds); void exec_shared_runtime_vacuum(Manager *m); +int exec_runtime_make(ExecSharedRuntime *shared, ExecRuntime **ret); +ExecRuntime* exec_runtime_free(ExecRuntime *rt); +DEFINE_TRIVIAL_CLEANUP_FUNC(ExecRuntime*, exec_runtime_free); +ExecRuntime* exec_runtime_destroy(ExecRuntime *rt); + void exec_params_clear(ExecParameters *p); bool exec_context_get_cpu_affinity_from_numa(const ExecContext *c); @@ -533,5 +544,5 @@ ExecDirectoryType exec_directory_type_symlink_from_string(const char *s) _pure_; const char* exec_resource_type_to_string(ExecDirectoryType i) _const_; ExecDirectoryType exec_resource_type_from_string(const char *s) _pure_; -bool exec_needs_mount_namespace(const ExecContext *context, const ExecParameters *params, const ExecSharedRuntime *runtime); +bool exec_needs_mount_namespace(const ExecContext *context, const ExecParameters *params, const ExecRuntime *runtime); bool exec_needs_network_namespace(const ExecContext *context); diff --git a/src/core/mount.c b/src/core/mount.c index e755a55964..a8a677a531 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -254,7 +254,7 @@ static void mount_done(Unit *u) { mount_parameters_done(&m->parameters_proc_self_mountinfo); mount_parameters_done(&m->parameters_fragment); - m->exec_runtime = exec_shared_runtime_unref(m->exec_runtime); + m->exec_runtime = exec_runtime_free(m->exec_runtime); exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX); m->control_command = NULL; @@ -948,7 +948,7 @@ static void mount_enter_dead(Mount *m, MountResult f) { mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD); - m->exec_runtime = exec_shared_runtime_destroy(m->exec_runtime); + m->exec_runtime = exec_runtime_destroy(m->exec_runtime); unit_destroy_runtime_data(UNIT(m), &m->exec_context); diff --git a/src/core/mount.h b/src/core/mount.h index 39d7247170..1a0d9fc5e5 100644 --- a/src/core/mount.h +++ b/src/core/mount.h @@ -75,7 +75,7 @@ struct Mount { KillContext kill_context; CGroupContext cgroup_context; - ExecSharedRuntime *exec_runtime; + ExecRuntime *exec_runtime; DynamicCreds dynamic_creds; MountState state, deserialized_state; diff --git a/src/core/service.c b/src/core/service.c index 4894d94511..883c4bbd93 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -383,7 +383,7 @@ static void service_done(Unit *u) { s->pid_file = mfree(s->pid_file); s->status_text = mfree(s->status_text); - s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime); + s->exec_runtime = exec_runtime_free(s->exec_runtime); exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX); s->control_command = NULL; s->main_command = NULL; @@ -1925,7 +1925,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) s->notify_access_override = _NOTIFY_ACCESS_INVALID; /* We want fresh tmpdirs in case service is started again immediately */ - s->exec_runtime = exec_shared_runtime_destroy(s->exec_runtime); + s->exec_runtime = exec_runtime_destroy(s->exec_runtime); /* Also, remove the runtime directory */ unit_destroy_runtime_data(UNIT(s), &s->exec_context); diff --git a/src/core/service.h b/src/core/service.h index 92eeef4a7b..7663f26f70 100644 --- a/src/core/service.h +++ b/src/core/service.h @@ -155,7 +155,7 @@ struct Service { ServiceExecCommand control_command_id; /* Runtime data of the execution context */ - ExecSharedRuntime *exec_runtime; + ExecRuntime *exec_runtime; DynamicCreds dynamic_creds; pid_t main_pid, control_pid; diff --git a/src/core/socket.c b/src/core/socket.c index 0e33c41def..163fc0bebf 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -150,7 +150,7 @@ static void socket_done(Unit *u) { s->peers_by_address = set_free(s->peers_by_address); - s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime); + s->exec_runtime = exec_runtime_free(s->exec_runtime); exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX); s->control_command = NULL; @@ -1532,16 +1532,18 @@ static int socket_address_listen_in_cgroup( if (s->exec_context.network_namespace_path && s->exec_runtime && - s->exec_runtime->netns_storage_socket[0] >= 0) { - r = open_shareable_ns_path(s->exec_runtime->netns_storage_socket, s->exec_context.network_namespace_path, CLONE_NEWNET); + s->exec_runtime->shared && + s->exec_runtime->shared->netns_storage_socket[0] >= 0) { + r = open_shareable_ns_path(s->exec_runtime->shared->netns_storage_socket, s->exec_context.network_namespace_path, CLONE_NEWNET); if (r < 0) return log_unit_error_errno(UNIT(s), r, "Failed to open network namespace path %s: %m", s->exec_context.network_namespace_path); } if (s->exec_context.ipc_namespace_path && s->exec_runtime && - s->exec_runtime->ipcns_storage_socket[0] >= 0) { - r = open_shareable_ns_path(s->exec_runtime->ipcns_storage_socket, s->exec_context.ipc_namespace_path, CLONE_NEWIPC); + s->exec_runtime->shared && + s->exec_runtime->shared->ipcns_storage_socket[0] >= 0) { + r = open_shareable_ns_path(s->exec_runtime->shared->ipcns_storage_socket, s->exec_context.ipc_namespace_path, CLONE_NEWIPC); if (r < 0) return log_unit_error_errno(UNIT(s), r, "Failed to open IPC namespace path %s: %m", s->exec_context.ipc_namespace_path); } @@ -1559,10 +1561,11 @@ static int socket_address_listen_in_cgroup( if (exec_needs_network_namespace(&s->exec_context) && s->exec_runtime && - s->exec_runtime->netns_storage_socket[0] >= 0) { + s->exec_runtime->shared && + s->exec_runtime->shared->netns_storage_socket[0] >= 0) { if (ns_type_supported(NAMESPACE_NET)) { - r = setup_shareable_ns(s->exec_runtime->netns_storage_socket, CLONE_NEWNET); + r = setup_shareable_ns(s->exec_runtime->shared->netns_storage_socket, CLONE_NEWNET); if (r < 0) { log_unit_error_errno(UNIT(s), r, "Failed to join network namespace: %m"); _exit(EXIT_NETWORK); @@ -2049,7 +2052,7 @@ static void socket_enter_dead(Socket *s, SocketResult f) { socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD); - s->exec_runtime = exec_shared_runtime_destroy(s->exec_runtime); + s->exec_runtime = exec_runtime_destroy(s->exec_runtime); unit_destroy_runtime_data(UNIT(s), &s->exec_context); diff --git a/src/core/socket.h b/src/core/socket.h index af65009ab8..6813bdcf8c 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -90,7 +90,7 @@ struct Socket { KillContext kill_context; CGroupContext cgroup_context; - ExecSharedRuntime *exec_runtime; + ExecRuntime *exec_runtime; DynamicCreds dynamic_creds; /* For Accept=no sockets refers to the one service we'll diff --git a/src/core/swap.c b/src/core/swap.c index 7b33060ab8..17f8123055 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -170,7 +170,7 @@ static void swap_done(Unit *u) { s->parameters_fragment.what = mfree(s->parameters_fragment.what); s->parameters_fragment.options = mfree(s->parameters_fragment.options); - s->exec_runtime = exec_shared_runtime_unref(s->exec_runtime); + s->exec_runtime = exec_runtime_free(s->exec_runtime); exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX); s->control_command = NULL; @@ -719,7 +719,7 @@ static void swap_enter_dead(Swap *s, SwapResult f) { unit_warn_leftover_processes(UNIT(s), unit_log_leftover_process_stop); swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD); - s->exec_runtime = exec_shared_runtime_destroy(s->exec_runtime); + s->exec_runtime = exec_runtime_destroy(s->exec_runtime); unit_destroy_runtime_data(UNIT(s), &s->exec_context); diff --git a/src/core/swap.h b/src/core/swap.h index 49cd82c591..c0e3f118e1 100644 --- a/src/core/swap.h +++ b/src/core/swap.h @@ -67,7 +67,7 @@ struct Swap { KillContext kill_context; CGroupContext cgroup_context; - ExecSharedRuntime *exec_runtime; + ExecRuntime *exec_runtime; DynamicCreds dynamic_creds; SwapState state, deserialized_state; diff --git a/src/core/unit.c b/src/core/unit.c index 25e2509f51..e569a82e1c 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -4268,7 +4268,7 @@ CGroupContext *unit_get_cgroup_context(Unit *u) { return (CGroupContext*) ((uint8_t*) u + offset); } -ExecSharedRuntime *unit_get_exec_runtime(Unit *u) { +ExecRuntime *unit_get_exec_runtime(Unit *u) { size_t offset; if (u->type < 0) @@ -4278,7 +4278,7 @@ ExecSharedRuntime *unit_get_exec_runtime(Unit *u) { if (offset <= 0) return NULL; - return *(ExecSharedRuntime**) ((uint8_t*) u + offset); + return *(ExecRuntime**) ((uint8_t*) u + offset); } static const char* unit_drop_in_dir(Unit *u, UnitWriteFlags flags) { @@ -4791,7 +4791,8 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask) } int unit_setup_exec_runtime(Unit *u) { - ExecSharedRuntime **rt; + _cleanup_(exec_shared_runtime_unrefp) ExecSharedRuntime *esr = NULL; + ExecRuntime **rt; size_t offset; Unit *other; int r; @@ -4799,19 +4800,33 @@ int unit_setup_exec_runtime(Unit *u) { offset = UNIT_VTABLE(u)->exec_runtime_offset; assert(offset > 0); - /* Check if there already is an ExecSharedRuntime for this unit? */ - rt = (ExecSharedRuntime**) ((uint8_t*) u + offset); + /* Check if there already is an ExecRuntime for this unit? */ + rt = (ExecRuntime**) ((uint8_t*) u + offset); if (*rt) return 0; /* Try to get it from somebody else */ UNIT_FOREACH_DEPENDENCY(other, u, UNIT_ATOM_JOINS_NAMESPACE_OF) { - r = exec_shared_runtime_acquire(u->manager, NULL, other->id, false, rt); - if (r == 1) - return 1; + r = exec_shared_runtime_acquire(u->manager, NULL, other->id, false, &esr); + if (r < 0) + return r; + if (r > 0) + break; } - return exec_shared_runtime_acquire(u->manager, unit_get_exec_context(u), u->id, true, rt); + if (!esr) { + r = exec_shared_runtime_acquire(u->manager, unit_get_exec_context(u), u->id, true, &esr); + if (r < 0) + return r; + } + + r = exec_runtime_make(esr, rt); + if (r < 0) + return r; + + TAKE_PTR(esr); + + return r; } int unit_setup_dynamic_creds(Unit *u) { diff --git a/src/core/unit.h b/src/core/unit.h index 19a50ac690..bf9aea578a 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -964,7 +964,7 @@ ExecContext *unit_get_exec_context(const Unit *u) _pure_; KillContext *unit_get_kill_context(Unit *u) _pure_; CGroupContext *unit_get_cgroup_context(Unit *u) _pure_; -ExecSharedRuntime *unit_get_exec_runtime(Unit *u) _pure_; +ExecRuntime *unit_get_exec_runtime(Unit *u) _pure_; int unit_setup_exec_runtime(Unit *u); int unit_setup_dynamic_creds(Unit *u); From 1522077269c7df21b7f9b85e4749b9e32ccd0139 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Fri, 24 Mar 2023 14:30:16 +0100 Subject: [PATCH 4/4] core: Move DynamicCreds into ExecRuntime This is just another piece of runtime data so let's store it in ExecRuntime alongside the other runtime data. --- src/core/dynamic-user.c | 51 ++++++++++++++++++++++++++--------------- src/core/dynamic-user.h | 9 +++++--- src/core/execute.c | 31 ++++++++++++------------- src/core/execute.h | 5 ++-- src/core/mount.c | 10 +------- src/core/mount.h | 1 - src/core/service.c | 8 ------- src/core/service.h | 1 - src/core/socket.c | 10 +------- src/core/socket.h | 1 - src/core/swap.c | 10 +------- src/core/swap.h | 1 - src/core/unit.c | 40 +++++++++++--------------------- src/core/unit.h | 5 ---- 14 files changed, 74 insertions(+), 109 deletions(-) diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c index 3824ae747f..19cf3faca6 100644 --- a/src/core/dynamic-user.c +++ b/src/core/dynamic-user.c @@ -739,18 +739,28 @@ int dynamic_user_lookup_name(Manager *m, const char *name, uid_t *ret) { return r; } -int dynamic_creds_acquire(DynamicCreds *creds, Manager *m, const char *user, const char *group) { +int dynamic_creds_make(Manager *m, const char *user, const char *group, DynamicCreds **ret) { + _cleanup_(dynamic_creds_unrefp) DynamicCreds *creds = NULL; bool acquired = false; int r; - assert(creds); assert(m); + assert(ret); + + if (!user && !group) { + *ret = NULL; + return 0; + } + + creds = new0(DynamicCreds, 1); + if (!creds) + return -ENOMEM; /* A DynamicUser object encapsulates an allocation of both a UID and a GID for a specific name. However, some * services use different user and groups. For cases like that there's DynamicCreds containing a pair of user * and group. This call allocates a pair. */ - if (!creds->user && user) { + if (user) { r = dynamic_user_acquire(m, user, &creds->user); if (r < 0) return r; @@ -758,20 +768,19 @@ int dynamic_creds_acquire(DynamicCreds *creds, Manager *m, const char *user, con acquired = true; } - if (!creds->group) { - - if (creds->user && (!group || streq_ptr(user, group))) - creds->group = dynamic_user_ref(creds->user); - else if (group) { - r = dynamic_user_acquire(m, group, &creds->group); - if (r < 0) { - if (acquired) - creds->user = dynamic_user_unref(creds->user); - return r; - } + if (creds->user && (!group || streq_ptr(user, group))) + creds->group = dynamic_user_ref(creds->user); + else if (group) { + r = dynamic_user_acquire(m, group, &creds->group); + if (r < 0) { + if (acquired) + creds->user = dynamic_user_unref(creds->user); + return r; } } + *ret = TAKE_PTR(creds); + return 0; } @@ -803,16 +812,22 @@ int dynamic_creds_realize(DynamicCreds *creds, char **suggested_paths, uid_t *ui return 0; } -void dynamic_creds_unref(DynamicCreds *creds) { - assert(creds); +DynamicCreds* dynamic_creds_unref(DynamicCreds *creds) { + if (!creds) + return NULL; creds->user = dynamic_user_unref(creds->user); creds->group = dynamic_user_unref(creds->group); + + return mfree(creds); } -void dynamic_creds_destroy(DynamicCreds *creds) { - assert(creds); +DynamicCreds* dynamic_creds_destroy(DynamicCreds *creds) { + if (!creds) + return NULL; creds->user = dynamic_user_destroy(creds->user); creds->group = dynamic_user_destroy(creds->group); + + return mfree(creds); } diff --git a/src/core/dynamic-user.h b/src/core/dynamic-user.h index 847ef475ca..6539d17571 100644 --- a/src/core/dynamic-user.h +++ b/src/core/dynamic-user.h @@ -33,8 +33,11 @@ int dynamic_user_current(DynamicUser *d, uid_t *ret); int dynamic_user_lookup_uid(Manager *m, uid_t uid, char **ret); int dynamic_user_lookup_name(Manager *m, const char *name, uid_t *ret); -int dynamic_creds_acquire(DynamicCreds *creds, Manager *m, const char *user, const char *group); +int dynamic_creds_make(Manager *m, const char *user, const char *group, DynamicCreds **ret); int dynamic_creds_realize(DynamicCreds *creds, char **suggested_paths, uid_t *uid, gid_t *gid); -void dynamic_creds_unref(DynamicCreds *creds); -void dynamic_creds_destroy(DynamicCreds *creds); +DynamicCreds *dynamic_creds_unref(DynamicCreds *creds); +DynamicCreds *dynamic_creds_destroy(DynamicCreds *creds); + +DEFINE_TRIVIAL_CLEANUP_FUNC(DynamicCreds*, dynamic_creds_unref); +DEFINE_TRIVIAL_CLEANUP_FUNC(DynamicCreds*, dynamic_creds_destroy); diff --git a/src/core/execute.c b/src/core/execute.c index 86cfe99e8b..81e48f12c6 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -4057,7 +4057,6 @@ static void append_socket_pair(int *array, size_t *n, const int pair[static 2]) static int close_remaining_fds( const ExecParameters *params, const ExecRuntime *runtime, - const DynamicCreds *dcreds, int user_lookup_fd, int socket_fd, const int *fds, size_t n_fds) { @@ -4086,11 +4085,11 @@ static int close_remaining_fds( append_socket_pair(dont_close, &n_dont_close, runtime->shared->ipcns_storage_socket); } - if (dcreds) { - if (dcreds->user) - append_socket_pair(dont_close, &n_dont_close, dcreds->user->storage_socket); - if (dcreds->group) - append_socket_pair(dont_close, &n_dont_close, dcreds->group->storage_socket); + if (runtime && runtime->dynamic_creds) { + if (runtime->dynamic_creds->user) + append_socket_pair(dont_close, &n_dont_close, runtime->dynamic_creds->user->storage_socket); + if (runtime->dynamic_creds->group) + append_socket_pair(dont_close, &n_dont_close, runtime->dynamic_creds->group->storage_socket); } if (user_lookup_fd >= 0) @@ -4404,7 +4403,6 @@ static int exec_child( const ExecContext *context, const ExecParameters *params, ExecRuntime *runtime, - DynamicCreds *dcreds, const CGroupContext *cgroup_context, int socket_fd, const int named_iofds[static 3], @@ -4537,7 +4535,7 @@ static int exec_child( } #endif - r = close_remaining_fds(params, runtime, dcreds, user_lookup_fd, socket_fd, keep_fds, n_keep_fds); + r = close_remaining_fds(params, runtime, user_lookup_fd, socket_fd, keep_fds, n_keep_fds); if (r < 0) { *exit_status = EXIT_FDS; return log_unit_error_errno(unit, r, "Failed to close unwanted file descriptors: %m"); @@ -4583,7 +4581,7 @@ static int exec_child( return log_unit_error_errno(unit, errno, "Failed to update environment: %m"); } - if (context->dynamic_user && dcreds) { + if (context->dynamic_user && runtime && runtime->dynamic_creds) { _cleanup_strv_free_ char **suggested_paths = NULL; /* On top of that, make sure we bypass our own NSS module nss-systemd comprehensively for any NSS @@ -4599,7 +4597,7 @@ static int exec_child( return log_oom(); } - r = dynamic_creds_realize(dcreds, suggested_paths, &uid, &gid); + r = dynamic_creds_realize(runtime->dynamic_creds, suggested_paths, &uid, &gid); if (r < 0) { *exit_status = EXIT_USER; if (r == -EILSEQ) @@ -4618,8 +4616,8 @@ static int exec_child( return log_unit_error_errno(unit, SYNTHETIC_ERRNO(ESRCH), "GID validation failed for \""GID_FMT"\"", gid); } - if (dcreds->user) - username = dcreds->user->name; + if (runtime->dynamic_creds->user) + username = runtime->dynamic_creds->user->name; } else { r = get_fixed_user(context, &username, &uid, &gid, &home, &shell); @@ -5550,7 +5548,6 @@ int exec_spawn(Unit *unit, const ExecContext *context, const ExecParameters *params, ExecRuntime *runtime, - DynamicCreds *dcreds, const CGroupContext *cgroup_context, pid_t *ret) { @@ -5640,7 +5637,6 @@ int exec_spawn(Unit *unit, context, params, runtime, - dcreds, cgroup_context, socket_fd, named_iofds, @@ -7439,12 +7435,12 @@ void exec_shared_runtime_vacuum(Manager *m) { } } -int exec_runtime_make(ExecSharedRuntime *shared, ExecRuntime **ret) { +int exec_runtime_make(ExecSharedRuntime *shared, DynamicCreds *creds, ExecRuntime **ret) { _cleanup_(exec_runtime_freep) ExecRuntime *rt = NULL; assert(ret); - if (!shared) { + if (!shared && !creds) { *ret = NULL; return 0; } @@ -7455,6 +7451,7 @@ int exec_runtime_make(ExecSharedRuntime *shared, ExecRuntime **ret) { *rt = (ExecRuntime) { .shared = shared, + .dynamic_creds = creds, }; *ret = TAKE_PTR(rt); @@ -7466,6 +7463,7 @@ ExecRuntime* exec_runtime_free(ExecRuntime *rt) { return NULL; exec_shared_runtime_unref(rt->shared); + dynamic_creds_unref(rt->dynamic_creds); return mfree(rt); } @@ -7474,6 +7472,7 @@ ExecRuntime* exec_runtime_destroy(ExecRuntime *rt) { return NULL; rt->shared = exec_shared_runtime_destroy(rt->shared); + rt->dynamic_creds = dynamic_creds_destroy(rt->dynamic_creds); return exec_runtime_free(rt); } diff --git a/src/core/execute.h b/src/core/execute.h index 32ed912f15..254a1ee2d1 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -5,6 +5,7 @@ typedef struct ExecStatus ExecStatus; typedef struct ExecCommand ExecCommand; typedef struct ExecContext ExecContext; typedef struct ExecSharedRuntime ExecSharedRuntime; +typedef struct DynamicCreds DynamicCreds; typedef struct ExecRuntime ExecRuntime; typedef struct ExecParameters ExecParameters; typedef struct Manager Manager; @@ -127,6 +128,7 @@ struct ExecSharedRuntime { struct ExecRuntime { ExecSharedRuntime *shared; + DynamicCreds *dynamic_creds; }; typedef enum ExecDirectoryType { @@ -445,7 +447,6 @@ int exec_spawn(Unit *unit, const ExecContext *context, const ExecParameters *exec_params, ExecRuntime *runtime, - DynamicCreds *dynamic_creds, const CGroupContext *cgroup_context, pid_t *ret); @@ -498,7 +499,7 @@ int exec_shared_runtime_deserialize_compat(Unit *u, const char *key, const char int exec_shared_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds); void exec_shared_runtime_vacuum(Manager *m); -int exec_runtime_make(ExecSharedRuntime *shared, ExecRuntime **ret); +int exec_runtime_make(ExecSharedRuntime *shared, DynamicCreds *creds, ExecRuntime **ret); ExecRuntime* exec_runtime_free(ExecRuntime *rt); DEFINE_TRIVIAL_CLEANUP_FUNC(ExecRuntime*, exec_runtime_free); ExecRuntime* exec_runtime_destroy(ExecRuntime *rt); diff --git a/src/core/mount.c b/src/core/mount.c index a8a677a531..586151bf67 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -258,8 +258,6 @@ static void mount_done(Unit *u) { exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX); m->control_command = NULL; - dynamic_creds_unref(&m->dynamic_creds); - mount_unwatch_control_pid(m); m->timer_event_source = sd_event_source_disable_unref(m->timer_event_source); @@ -790,10 +788,8 @@ static int mount_coldplug(Unit *u) { return r; } - if (!IN_SET(m->deserialized_state, MOUNT_DEAD, MOUNT_FAILED)) { - (void) unit_setup_dynamic_creds(u); + if (!IN_SET(m->deserialized_state, MOUNT_DEAD, MOUNT_FAILED)) (void) unit_setup_exec_runtime(u); - } mount_set_state(m, m->deserialized_state); return 0; @@ -922,7 +918,6 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { &m->exec_context, &exec_params, m->exec_runtime, - &m->dynamic_creds, &m->cgroup_context, &pid); if (r < 0) @@ -954,8 +949,6 @@ static void mount_enter_dead(Mount *m, MountResult f) { unit_unref_uid_gid(UNIT(m), true); - dynamic_creds_destroy(&m->dynamic_creds); - /* Any dependencies based on /proc/self/mountinfo are now stale. Let's re-generate dependencies from * .mount unit. */ (void) mount_add_non_exec_dependencies(m); @@ -2268,7 +2261,6 @@ const UnitVTable mount_vtable = { .cgroup_context_offset = offsetof(Mount, cgroup_context), .kill_context_offset = offsetof(Mount, kill_context), .exec_runtime_offset = offsetof(Mount, exec_runtime), - .dynamic_creds_offset = offsetof(Mount, dynamic_creds), .sections = "Unit\0" diff --git a/src/core/mount.h b/src/core/mount.h index 1a0d9fc5e5..d6d6d335a4 100644 --- a/src/core/mount.h +++ b/src/core/mount.h @@ -76,7 +76,6 @@ struct Mount { CGroupContext cgroup_context; ExecRuntime *exec_runtime; - DynamicCreds dynamic_creds; MountState state, deserialized_state; diff --git a/src/core/service.c b/src/core/service.c index 883c4bbd93..cfce4594a0 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -388,8 +388,6 @@ static void service_done(Unit *u) { s->control_command = NULL; s->main_command = NULL; - dynamic_creds_unref(&s->dynamic_creds); - exit_status_set_free(&s->restart_prevent_status); exit_status_set_free(&s->restart_force_status); exit_status_set_free(&s->success_status); @@ -1267,7 +1265,6 @@ static int service_coldplug(Unit *u) { if (!IN_SET(s->deserialized_state, SERVICE_DEAD, SERVICE_FAILED, SERVICE_AUTO_RESTART, SERVICE_CLEANING)) { (void) unit_enqueue_rewatch_pids(u); - (void) unit_setup_dynamic_creds(u); (void) unit_setup_exec_runtime(u); } @@ -1719,7 +1716,6 @@ static int service_spawn_internal( &s->exec_context, &exec_params, s->exec_runtime, - &s->dynamic_creds, &s->cgroup_context, &pid); if (r < 0) @@ -1933,9 +1929,6 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) /* Get rid of the IPC bits of the user */ unit_unref_uid_gid(UNIT(s), true); - /* Release the user, and destroy it if we are the only remaining owner */ - dynamic_creds_destroy(&s->dynamic_creds); - /* Try to delete the pid file. At this point it will be * out-of-date, and some software might be confused by it, so * let's remove it. */ @@ -4894,7 +4887,6 @@ const UnitVTable service_vtable = { .cgroup_context_offset = offsetof(Service, cgroup_context), .kill_context_offset = offsetof(Service, kill_context), .exec_runtime_offset = offsetof(Service, exec_runtime), - .dynamic_creds_offset = offsetof(Service, dynamic_creds), .sections = "Unit\0" diff --git a/src/core/service.h b/src/core/service.h index 7663f26f70..1517b81867 100644 --- a/src/core/service.h +++ b/src/core/service.h @@ -156,7 +156,6 @@ struct Service { /* Runtime data of the execution context */ ExecRuntime *exec_runtime; - DynamicCreds dynamic_creds; pid_t main_pid, control_pid; diff --git a/src/core/socket.c b/src/core/socket.c index 163fc0bebf..af6603df07 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -154,8 +154,6 @@ static void socket_done(Unit *u) { exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX); s->control_command = NULL; - dynamic_creds_unref(&s->dynamic_creds); - socket_unwatch_control_pid(s); unit_ref_unset(&s->service); @@ -1908,10 +1906,8 @@ static int socket_coldplug(Unit *u) { return r; } - if (!IN_SET(s->deserialized_state, SOCKET_DEAD, SOCKET_FAILED, SOCKET_CLEANING)) { - (void) unit_setup_dynamic_creds(u); + if (!IN_SET(s->deserialized_state, SOCKET_DEAD, SOCKET_FAILED, SOCKET_CLEANING)) (void) unit_setup_exec_runtime(u); - } socket_set_state(s, s->deserialized_state); return 0; @@ -1950,7 +1946,6 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { &s->exec_context, &exec_params, s->exec_runtime, - &s->dynamic_creds, &s->cgroup_context, &pid); if (r < 0) @@ -2057,8 +2052,6 @@ static void socket_enter_dead(Socket *s, SocketResult f) { unit_destroy_runtime_data(UNIT(s), &s->exec_context); unit_unref_uid_gid(UNIT(s), true); - - dynamic_creds_destroy(&s->dynamic_creds); } static void socket_enter_signal(Socket *s, SocketState state, SocketResult f); @@ -3471,7 +3464,6 @@ const UnitVTable socket_vtable = { .cgroup_context_offset = offsetof(Socket, cgroup_context), .kill_context_offset = offsetof(Socket, kill_context), .exec_runtime_offset = offsetof(Socket, exec_runtime), - .dynamic_creds_offset = offsetof(Socket, dynamic_creds), .sections = "Unit\0" diff --git a/src/core/socket.h b/src/core/socket.h index 6813bdcf8c..308a072756 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -91,7 +91,6 @@ struct Socket { CGroupContext cgroup_context; ExecRuntime *exec_runtime; - DynamicCreds dynamic_creds; /* For Accept=no sockets refers to the one service we'll * activate. For Accept=yes sockets is either NULL, or filled diff --git a/src/core/swap.c b/src/core/swap.c index 17f8123055..c6e2c8b1bd 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -174,8 +174,6 @@ static void swap_done(Unit *u) { exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX); s->control_command = NULL; - dynamic_creds_unref(&s->dynamic_creds); - swap_unwatch_control_pid(s); s->timer_event_source = sd_event_source_disable_unref(s->timer_event_source); @@ -593,10 +591,8 @@ static int swap_coldplug(Unit *u) { return r; } - if (!IN_SET(new_state, SWAP_DEAD, SWAP_FAILED)) { - (void) unit_setup_dynamic_creds(u); + if (!IN_SET(new_state, SWAP_DEAD, SWAP_FAILED)) (void) unit_setup_exec_runtime(u); - } swap_set_state(s, new_state); return 0; @@ -689,7 +685,6 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { &s->exec_context, &exec_params, s->exec_runtime, - &s->dynamic_creds, &s->cgroup_context, &pid); if (r < 0) @@ -724,8 +719,6 @@ static void swap_enter_dead(Swap *s, SwapResult f) { unit_destroy_runtime_data(UNIT(s), &s->exec_context); unit_unref_uid_gid(UNIT(s), true); - - dynamic_creds_destroy(&s->dynamic_creds); } static void swap_enter_active(Swap *s, SwapResult f) { @@ -1619,7 +1612,6 @@ const UnitVTable swap_vtable = { .cgroup_context_offset = offsetof(Swap, cgroup_context), .kill_context_offset = offsetof(Swap, kill_context), .exec_runtime_offset = offsetof(Swap, exec_runtime), - .dynamic_creds_offset = offsetof(Swap, dynamic_creds), .sections = "Unit\0" diff --git a/src/core/swap.h b/src/core/swap.h index c0e3f118e1..d61c7112cf 100644 --- a/src/core/swap.h +++ b/src/core/swap.h @@ -68,7 +68,6 @@ struct Swap { CGroupContext cgroup_context; ExecRuntime *exec_runtime; - DynamicCreds dynamic_creds; SwapState state, deserialized_state; diff --git a/src/core/unit.c b/src/core/unit.c index e569a82e1c..e3a57e3b84 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -4792,7 +4792,9 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask) int unit_setup_exec_runtime(Unit *u) { _cleanup_(exec_shared_runtime_unrefp) ExecSharedRuntime *esr = NULL; + _cleanup_(dynamic_creds_unrefp) DynamicCreds *dcreds = NULL; ExecRuntime **rt; + ExecContext *ec; size_t offset; Unit *other; int r; @@ -4805,6 +4807,9 @@ int unit_setup_exec_runtime(Unit *u) { if (*rt) return 0; + ec = unit_get_exec_context(u); + assert(ec); + /* Try to get it from somebody else */ UNIT_FOREACH_DEPENDENCY(other, u, UNIT_ATOM_JOINS_NAMESPACE_OF) { r = exec_shared_runtime_acquire(u->manager, NULL, other->id, false, &esr); @@ -4815,40 +4820,27 @@ int unit_setup_exec_runtime(Unit *u) { } if (!esr) { - r = exec_shared_runtime_acquire(u->manager, unit_get_exec_context(u), u->id, true, &esr); + r = exec_shared_runtime_acquire(u->manager, ec, u->id, true, &esr); if (r < 0) return r; } - r = exec_runtime_make(esr, rt); + if (ec->dynamic_user) { + r = dynamic_creds_make(u->manager, ec->user, ec->group, &dcreds); + if (r < 0) + return r; + } + + r = exec_runtime_make(esr, dcreds, rt); if (r < 0) return r; TAKE_PTR(esr); + TAKE_PTR(dcreds); return r; } -int unit_setup_dynamic_creds(Unit *u) { - ExecContext *ec; - DynamicCreds *dcreds; - size_t offset; - - assert(u); - - offset = UNIT_VTABLE(u)->dynamic_creds_offset; - assert(offset > 0); - dcreds = (DynamicCreds*) ((uint8_t*) u + offset); - - ec = unit_get_exec_context(u); - assert(ec); - - if (!ec->dynamic_user) - return 0; - - return dynamic_creds_acquire(dcreds, u->manager, ec->user, ec->group); -} - bool unit_type_supported(UnitType t) { static int8_t cache[_UNIT_TYPE_MAX] = {}; /* -1: disabled, 1: enabled: 0: don't know */ int r; @@ -5580,10 +5572,6 @@ int unit_prepare_exec(Unit *u) { if (r < 0) return r; - r = unit_setup_dynamic_creds(u); - if (r < 0) - return r; - return 0; } diff --git a/src/core/unit.h b/src/core/unit.h index bf9aea578a..513c8181f5 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -574,10 +574,6 @@ typedef struct UnitVTable { * that */ size_t exec_runtime_offset; - /* If greater than 0, the offset into the object where the pointer to DynamicCreds is found, if the unit type - * has that. */ - size_t dynamic_creds_offset; - /* The name of the configuration file section with the private settings of this unit */ const char *private_section; @@ -967,7 +963,6 @@ CGroupContext *unit_get_cgroup_context(Unit *u) _pure_; ExecRuntime *unit_get_exec_runtime(Unit *u) _pure_; int unit_setup_exec_runtime(Unit *u); -int unit_setup_dynamic_creds(Unit *u); char* unit_escape_setting(const char *s, UnitWriteFlags flags, char **buf); char* unit_concat_strv(char **l, UnitWriteFlags flags);