core: unify common code for preparing for forking off unit processes

This introduces a new function unit_prepare_exec() that encapsulates a
number of calls we do in preparation for spawning off some processes in
all our unit types that do so.

This allows us to neatly unify a bit of code between unit types and
shorten our code.
This commit is contained in:
Lennart Poettering 2017-11-17 16:43:08 +01:00
parent 6925a0de4e
commit 3c7416b6ca
10 changed files with 62 additions and 84 deletions

View File

@ -750,33 +750,21 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
}
static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
pid_t pid;
int r;
ExecParameters exec_params = {
.flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,
};
pid_t pid;
int r;
assert(m);
assert(c);
assert(_pid);
(void) unit_realize_cgroup(UNIT(m));
if (m->reset_accounting) {
(void) unit_reset_cpu_accounting(UNIT(m));
(void) unit_reset_ip_accounting(UNIT(m));
m->reset_accounting = false;
}
unit_export_state_files(UNIT(m));
r = unit_setup_exec_runtime(UNIT(m));
if (r < 0)
return r;
r = unit_setup_dynamic_creds(UNIT(m));
r = unit_prepare_exec(UNIT(m));
if (r < 0)
return r;
@ -1091,7 +1079,8 @@ static int mount_start(Unit *u) {
m->result = MOUNT_SUCCESS;
m->reload_result = MOUNT_SUCCESS;
m->reset_accounting = true;
u->reset_accounting = true;
mount_enter_mounting(m);
return 1;

View File

@ -68,8 +68,6 @@ struct Mount {
bool just_mounted:1;
bool just_changed:1;
bool reset_accounting:1;
bool sloppy_options;
bool lazy_unmount;

View File

@ -1223,24 +1223,26 @@ static int service_spawn(
ExecFlags flags,
pid_t *_pid) {
_cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL;
_cleanup_free_ int *fds = NULL;
unsigned n_storage_fds = 0, n_socket_fds = 0, n_env = 0;
pid_t pid;
ExecParameters exec_params = {
.flags = flags,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,
};
_cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL;
unsigned n_storage_fds = 0, n_socket_fds = 0, n_env = 0;
_cleanup_free_ int *fds = NULL;
pid_t pid;
int r;
assert(s);
assert(c);
assert(_pid);
r = unit_prepare_exec(UNIT(s));
if (r < 0)
return r;
if (flags & EXEC_IS_CONTROL) {
/* If this is a control process, mask the permissions/chroot application if this is requested. */
if (s->permissions_start_only)
@ -1249,23 +1251,6 @@ static int service_spawn(
exec_params.flags &= ~EXEC_APPLY_CHROOT;
}
(void) unit_realize_cgroup(UNIT(s));
if (s->reset_accounting) {
(void) unit_reset_cpu_accounting(UNIT(s));
(void) unit_reset_ip_accounting(UNIT(s));
s->reset_accounting = false;
}
unit_export_state_files(UNIT(s));
r = unit_setup_exec_runtime(UNIT(s));
if (r < 0)
return r;
r = unit_setup_dynamic_creds(UNIT(s));
if (r < 0)
return r;
if ((flags & EXEC_PASS_FDS) ||
s->exec_context.std_input == EXEC_INPUT_SOCKET ||
s->exec_context.std_output == EXEC_OUTPUT_SOCKET ||
@ -2188,7 +2173,8 @@ static int service_start(Unit *u) {
s->main_pid_known = false;
s->main_pid_alien = false;
s->forbid_restart = false;
s->reset_accounting = true;
u->reset_accounting = true;
s->status_text = mfree(s->status_text);
s->status_errno = 0;

View File

@ -166,8 +166,6 @@ struct Service {
bool forbid_restart:1;
bool start_timeout_defined:1;
bool reset_accounting:1;
char *bus_name;
char *bus_name_owner; /* unique name of the current owner */

View File

@ -1865,33 +1865,21 @@ static int socket_coldplug(Unit *u) {
}
static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
pid_t pid;
int r;
ExecParameters exec_params = {
.flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,
};
pid_t pid;
int r;
assert(s);
assert(c);
assert(_pid);
(void) unit_realize_cgroup(UNIT(s));
if (s->reset_accounting) {
(void) unit_reset_cpu_accounting(UNIT(s));
(void) unit_reset_ip_accounting(UNIT(s));
s->reset_accounting = false;
}
unit_export_state_files(UNIT(s));
r = unit_setup_exec_runtime(UNIT(s));
if (r < 0)
return r;
r = unit_setup_dynamic_creds(UNIT(s));
r = unit_prepare_exec(UNIT(s));
if (r < 0)
return r;
@ -2471,7 +2459,8 @@ static int socket_start(Unit *u) {
return r;
s->result = SOCKET_SUCCESS;
s->reset_accounting = true;
u->reset_accounting = true;
socket_enter_start_pre(s);
return 1;

View File

@ -162,8 +162,6 @@ struct Socket {
char *user, *group;
bool reset_accounting:1;
char *fdname;
RateLimit trigger_limit;

View File

@ -603,35 +603,23 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
}
static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
pid_t pid;
int r;
ExecParameters exec_params = {
.flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN,
.stdin_fd = -1,
.stdout_fd = -1,
.stderr_fd = -1,
};
pid_t pid;
int r;
assert(s);
assert(c);
assert(_pid);
(void) unit_realize_cgroup(UNIT(s));
if (s->reset_accounting) {
(void) unit_reset_cpu_accounting(UNIT(s));
(void) unit_reset_ip_accounting(UNIT(s));
s->reset_accounting = false;
}
unit_export_state_files(UNIT(s));
r = unit_setup_exec_runtime(UNIT(s));
r = unit_prepare_exec(UNIT(s));
if (r < 0)
goto fail;
r = unit_setup_dynamic_creds(UNIT(s));
if (r < 0)
goto fail;
return r;
r = swap_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->timeout_usec));
if (r < 0)
@ -868,7 +856,8 @@ static int swap_start(Unit *u) {
return r;
s->result = SWAP_SUCCESS;
s->reset_accounting = true;
u->reset_accounting = true;
swap_enter_activating(s);
return 1;

View File

@ -71,8 +71,6 @@ struct Swap {
bool is_active:1;
bool just_activated:1;
bool reset_accounting:1;
SwapResult result;
usec_t timeout_usec;

View File

@ -5145,6 +5145,34 @@ void unit_unlink_state_files(Unit *u) {
}
}
int unit_prepare_exec(Unit *u) {
int r;
assert(u);
/* Prepares everything so that we can fork of a process for this unit */
(void) unit_realize_cgroup(u);
if (u->reset_accounting) {
(void) unit_reset_cpu_accounting(u);
(void) unit_reset_ip_accounting(u);
u->reset_accounting = false;
}
unit_export_state_files(u);
r = unit_setup_exec_runtime(u);
if (r < 0)
return r;
r = unit_setup_dynamic_creds(u);
if (r < 0)
return r;
return 0;
}
static const char* const collect_mode_table[_COLLECT_MODE_MAX] = {
[COLLECT_INACTIVE] = "inactive",
[COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed",

View File

@ -342,6 +342,9 @@ struct Unit {
UnitCGroupBPFState cgroup_bpf_state:2;
/* Reset cgroup accounting next time we fork something off */
bool reset_accounting:1;
bool start_limit_hit:1;
/* Did we already invoke unit_coldplug() for this unit? */
@ -760,6 +763,8 @@ void unit_remove_dependencies(Unit *u, UnitDependencyMask mask);
void unit_export_state_files(Unit *u);
void unit_unlink_state_files(Unit *u);
int unit_prepare_exec(Unit *u);
/* Macros which append UNIT= or USER_UNIT= to the message */
#define log_unit_full(unit, level, error, ...) \