bool exec_needs_mount_namespace(
const ExecContext *context,
const ExecParameters *params,
- const ExecSharedRuntime *runtime) {
+ const ExecRuntime *runtime) {
assert(context);
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 ||
ExecCommandFlags command_flags,
const ExecContext *context,
const ExecParameters *params,
- const ExecSharedRuntime *runtime,
+ const ExecRuntime *runtime,
const char *memory_pressure_path,
char **error_path) {
* 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) {
static int close_remaining_fds(
const ExecParameters *params,
- const ExecSharedRuntime *runtime,
+ const ExecRuntime *runtime,
const DynamicCreds *dcreds,
int user_lookup_fd,
int socket_fd,
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) {
const ExecCommand *command,
const ExecContext *context,
const ExecParameters *params,
- ExecSharedRuntime *runtime,
+ ExecRuntime *runtime,
DynamicCreds *dcreds,
const CGroupContext *cgroup_context,
int socket_fd,
}
}
- 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);
}
}
- 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,
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");
ExecCommand *command,
const ExecContext *context,
const ExecParameters *params,
- ExecSharedRuntime *runtime,
+ ExecRuntime *runtime,
DynamicCreds *dcreds,
const CGroupContext *cgroup_context,
pid_t *ret) {
}
}
+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;
typedef struct ExecCommand ExecCommand;
typedef struct ExecContext ExecContext;
typedef struct ExecSharedRuntime ExecSharedRuntime;
+typedef struct ExecRuntime ExecRuntime;
typedef struct ExecParameters ExecParameters;
typedef struct Manager Manager;
int ipcns_storage_socket[2];
};
+struct ExecRuntime {
+ ExecSharedRuntime *shared;
+};
+
typedef enum ExecDirectoryType {
EXEC_DIRECTORY_RUNTIME = 0,
EXEC_DIRECTORY_STATE,
ExecCommand *command,
const ExecContext *context,
const ExecParameters *exec_params,
- ExecSharedRuntime *runtime,
+ ExecRuntime *runtime,
DynamicCreds *dynamic_creds,
const CGroupContext *cgroup_context,
pid_t *ret);
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);
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);
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;
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);
KillContext kill_context;
CGroupContext cgroup_context;
- ExecSharedRuntime *exec_runtime;
+ ExecRuntime *exec_runtime;
DynamicCreds dynamic_creds;
MountState state, deserialized_state;
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;
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);
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;
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;
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);
}
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);
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);
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
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;
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);
KillContext kill_context;
CGroupContext cgroup_context;
- ExecSharedRuntime *exec_runtime;
+ ExecRuntime *exec_runtime;
DynamicCreds dynamic_creds;
SwapState state, deserialized_state;
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)
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) {
}
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;
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;
+ }
+
+ if (!esr) {
+ r = exec_shared_runtime_acquire(u->manager, unit_get_exec_context(u), u->id, true, &esr);
+ if (r < 0)
+ return r;
}
- return exec_shared_runtime_acquire(u->manager, unit_get_exec_context(u), u->id, true, rt);
+ r = exec_runtime_make(esr, rt);
+ if (r < 0)
+ return r;
+
+ TAKE_PTR(esr);
+
+ return r;
}
int unit_setup_dynamic_creds(Unit *u) {
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);