mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-27 18:55:09 +03:00
Merge pull request #9624 from poettering/service-state-flush
flush out ExecStatus structures when a new service cycle begins
This commit is contained in:
commit
5b316330be
@ -2724,7 +2724,6 @@ static int exec_child(
|
||||
const ExecParameters *params,
|
||||
ExecRuntime *runtime,
|
||||
DynamicCreds *dcreds,
|
||||
char **argv,
|
||||
int socket_fd,
|
||||
int named_iofds[3],
|
||||
int *fds,
|
||||
@ -2820,7 +2819,7 @@ static int exec_child(
|
||||
const char *vc = params->confirm_spawn;
|
||||
_cleanup_free_ char *cmdline = NULL;
|
||||
|
||||
cmdline = exec_command_line(argv);
|
||||
cmdline = exec_command_line(command->argv);
|
||||
if (!cmdline) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return log_oom();
|
||||
@ -3452,7 +3451,7 @@ static int exec_child(
|
||||
strv_free_and_replace(accum_env, ee);
|
||||
}
|
||||
|
||||
final_argv = replace_env_argv(argv, accum_env);
|
||||
final_argv = replace_env_argv(command->argv, accum_env);
|
||||
if (!final_argv) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return log_oom();
|
||||
@ -3523,13 +3522,10 @@ int exec_spawn(Unit *unit,
|
||||
DynamicCreds *dcreds,
|
||||
pid_t *ret) {
|
||||
|
||||
int socket_fd, r, named_iofds[3] = { -1, -1, -1 }, *fds = NULL;
|
||||
_cleanup_strv_free_ char **files_env = NULL;
|
||||
int *fds = NULL;
|
||||
size_t n_storage_fds = 0, n_socket_fds = 0;
|
||||
_cleanup_free_ char *line = NULL;
|
||||
int socket_fd, r;
|
||||
int named_iofds[3] = { -1, -1, -1 };
|
||||
char **argv;
|
||||
pid_t pid;
|
||||
|
||||
assert(unit);
|
||||
@ -3569,8 +3565,7 @@ int exec_spawn(Unit *unit,
|
||||
if (r < 0)
|
||||
return log_unit_error_errno(unit, r, "Failed to load environment files: %m");
|
||||
|
||||
argv = params->argv ?: command->argv;
|
||||
line = exec_command_line(argv);
|
||||
line = exec_command_line(command->argv);
|
||||
if (!line)
|
||||
return log_oom();
|
||||
|
||||
@ -3593,7 +3588,6 @@ int exec_spawn(Unit *unit,
|
||||
params,
|
||||
runtime,
|
||||
dcreds,
|
||||
argv,
|
||||
socket_fd,
|
||||
named_iofds,
|
||||
fds,
|
||||
@ -3743,7 +3737,6 @@ static void exec_command_done(ExecCommand *c) {
|
||||
assert(c);
|
||||
|
||||
c->path = mfree(c->path);
|
||||
|
||||
c->argv = strv_free(c->argv);
|
||||
}
|
||||
|
||||
@ -3773,6 +3766,24 @@ void exec_command_free_array(ExecCommand **c, size_t n) {
|
||||
c[i] = exec_command_free_list(c[i]);
|
||||
}
|
||||
|
||||
void exec_command_reset_status_array(ExecCommand *c, size_t n) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
exec_status_reset(&c[i].exec_status);
|
||||
}
|
||||
|
||||
void exec_command_reset_status_list_array(ExecCommand **c, size_t n) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
ExecCommand *z;
|
||||
|
||||
LIST_FOREACH(command, z, c[i])
|
||||
exec_status_reset(&z->exec_status);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct InvalidEnvInfo {
|
||||
const Unit *unit;
|
||||
const char *path;
|
||||
@ -4423,18 +4434,22 @@ void exec_context_free_log_extra_fields(ExecContext *c) {
|
||||
void exec_status_start(ExecStatus *s, pid_t pid) {
|
||||
assert(s);
|
||||
|
||||
zero(*s);
|
||||
s->pid = pid;
|
||||
*s = (ExecStatus) {
|
||||
.pid = pid,
|
||||
};
|
||||
|
||||
dual_timestamp_get(&s->start_timestamp);
|
||||
}
|
||||
|
||||
void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int code, int status) {
|
||||
assert(s);
|
||||
|
||||
if (s->pid && s->pid != pid)
|
||||
zero(*s);
|
||||
if (s->pid != pid) {
|
||||
*s = (ExecStatus) {
|
||||
.pid = pid,
|
||||
};
|
||||
}
|
||||
|
||||
s->pid = pid;
|
||||
dual_timestamp_get(&s->exit_timestamp);
|
||||
|
||||
s->code = code;
|
||||
@ -4442,12 +4457,18 @@ void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int
|
||||
|
||||
if (context) {
|
||||
if (context->utmp_id)
|
||||
utmp_put_dead_process(context->utmp_id, pid, code, status);
|
||||
(void) utmp_put_dead_process(context->utmp_id, pid, code, status);
|
||||
|
||||
exec_context_tty_reset(context, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void exec_status_reset(ExecStatus *s) {
|
||||
assert(s);
|
||||
|
||||
*s = (ExecStatus) {};
|
||||
}
|
||||
|
||||
void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix) {
|
||||
char buf[FORMAT_TIMESTAMP_MAX];
|
||||
|
||||
|
@ -77,10 +77,11 @@ typedef enum ExecKeyringMode {
|
||||
_EXEC_KEYRING_MODE_INVALID = -1,
|
||||
} ExecKeyringMode;
|
||||
|
||||
/* Contains start and exit information about an executed command. */
|
||||
struct ExecStatus {
|
||||
pid_t pid;
|
||||
dual_timestamp start_timestamp;
|
||||
dual_timestamp exit_timestamp;
|
||||
pid_t pid;
|
||||
int code; /* as in siginfo_t::si_code */
|
||||
int status; /* as in sigingo_t::si_status */
|
||||
};
|
||||
@ -92,6 +93,7 @@ typedef enum ExecCommandFlags {
|
||||
EXEC_COMMAND_AMBIENT_MAGIC = 1 << 3,
|
||||
} ExecCommandFlags;
|
||||
|
||||
/* Stores information about commands we execute. Covers both configuration settings as well as runtime data. */
|
||||
struct ExecCommand {
|
||||
char *path;
|
||||
char **argv;
|
||||
@ -100,13 +102,16 @@ struct ExecCommand {
|
||||
LIST_FIELDS(ExecCommand, command); /* useful for chaining commands */
|
||||
};
|
||||
|
||||
/* Encapsulates certain aspects of the runtime environment that is to be shared between multiple otherwise separate
|
||||
* 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 {
|
||||
int n_ref;
|
||||
|
||||
Manager *manager;
|
||||
|
||||
/* unit id of the owner */
|
||||
char *id;
|
||||
char *id; /* Unit id of the owner */
|
||||
|
||||
char *tmp_dir;
|
||||
char *var_tmp_dir;
|
||||
@ -131,6 +136,9 @@ typedef struct ExecDirectory {
|
||||
mode_t mode;
|
||||
} ExecDirectory;
|
||||
|
||||
/* Encodes configuration parameters applied to invoked commands. Does not carry runtime data, but only configuration
|
||||
* changes sourced from unit files and suchlike. ExecContext objects are usually embedded into Unit objects, and do not
|
||||
* change after being loaded. */
|
||||
struct ExecContext {
|
||||
char **environment;
|
||||
char **environment_files;
|
||||
@ -291,8 +299,9 @@ typedef enum ExecFlags {
|
||||
EXEC_SET_WATCHDOG = 1 << 11,
|
||||
} ExecFlags;
|
||||
|
||||
/* Parameters for a specific invocation of a command. This structure is put together right before a command is
|
||||
* executed. */
|
||||
struct ExecParameters {
|
||||
char **argv;
|
||||
char **environment;
|
||||
|
||||
int *fds;
|
||||
@ -334,10 +343,10 @@ int exec_spawn(Unit *unit,
|
||||
pid_t *ret);
|
||||
|
||||
void exec_command_done_array(ExecCommand *c, size_t n);
|
||||
|
||||
ExecCommand* exec_command_free_list(ExecCommand *c);
|
||||
void exec_command_free_array(ExecCommand **c, size_t n);
|
||||
|
||||
void exec_command_reset_status_array(ExecCommand *c, size_t n);
|
||||
void exec_command_reset_status_list_array(ExecCommand **c, size_t n);
|
||||
void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix);
|
||||
void exec_command_append_list(ExecCommand **l, ExecCommand *e);
|
||||
int exec_command_set(ExecCommand *c, const char *path, ...);
|
||||
@ -361,6 +370,7 @@ void exec_context_free_log_extra_fields(ExecContext *c);
|
||||
void exec_status_start(ExecStatus *s, pid_t pid);
|
||||
void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int code, int status);
|
||||
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);
|
||||
|
@ -1075,6 +1075,7 @@ static int mount_start(Unit *u) {
|
||||
|
||||
m->result = MOUNT_SUCCESS;
|
||||
m->reload_result = MOUNT_SUCCESS;
|
||||
exec_command_reset_status_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
|
||||
|
||||
u->reset_accounting = true;
|
||||
|
||||
|
@ -1521,7 +1521,6 @@ static int service_spawn(
|
||||
SET_FLAG(exec_params.flags, EXEC_NSS_BYPASS_BUS,
|
||||
MANAGER_IS_SYSTEM(UNIT(s)->manager) && unit_has_name(UNIT(s), SPECIAL_DBUS_SERVICE));
|
||||
|
||||
exec_params.argv = c->argv;
|
||||
exec_params.environment = final_env;
|
||||
exec_params.fds = fds;
|
||||
exec_params.fd_names = fd_names;
|
||||
@ -1753,7 +1752,6 @@ static void service_enter_stop_post(Service *s, ServiceResult f) {
|
||||
s->result = f;
|
||||
|
||||
service_unwatch_control_pid(s);
|
||||
|
||||
(void) unit_enqueue_rewatch_pids(UNIT(s));
|
||||
|
||||
s->control_command = s->exec_command[SERVICE_EXEC_STOP_POST];
|
||||
@ -2330,8 +2328,6 @@ static int service_start(Unit *u) {
|
||||
s->main_pid_alien = false;
|
||||
s->forbid_restart = false;
|
||||
|
||||
u->reset_accounting = true;
|
||||
|
||||
s->status_text = mfree(s->status_text);
|
||||
s->status_errno = 0;
|
||||
|
||||
@ -2340,12 +2336,17 @@ static int service_start(Unit *u) {
|
||||
s->watchdog_override_enable = false;
|
||||
s->watchdog_override_usec = 0;
|
||||
|
||||
exec_command_reset_status_list_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX);
|
||||
exec_status_reset(&s->main_exec_status);
|
||||
|
||||
/* This is not an automatic restart? Flush the restart counter then */
|
||||
if (s->flush_n_restarts) {
|
||||
s->n_restarts = 0;
|
||||
s->flush_n_restarts = false;
|
||||
}
|
||||
|
||||
u->reset_accounting = true;
|
||||
|
||||
service_enter_start_pre(s);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1890,8 +1890,6 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
|
||||
|
||||
unit_set_exec_params(UNIT(s), &exec_params);
|
||||
|
||||
exec_params.argv = c->argv;
|
||||
|
||||
r = exec_spawn(UNIT(s),
|
||||
c,
|
||||
&s->exec_context,
|
||||
@ -2460,6 +2458,7 @@ static int socket_start(Unit *u) {
|
||||
return r;
|
||||
|
||||
s->result = SOCKET_SUCCESS;
|
||||
exec_command_reset_status_list_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX);
|
||||
|
||||
u->reset_accounting = true;
|
||||
|
||||
|
@ -854,6 +854,7 @@ static int swap_start(Unit *u) {
|
||||
return r;
|
||||
|
||||
s->result = SWAP_SUCCESS;
|
||||
exec_command_reset_status_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
|
||||
|
||||
u->reset_accounting = true;
|
||||
|
||||
|
@ -4548,6 +4548,7 @@ static int map_asserts(sd_bus *bus, const char *member, sd_bus_message *m, sd_bu
|
||||
|
||||
static int map_exec(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
|
||||
_cleanup_free_ ExecStatusInfo *info = NULL;
|
||||
ExecStatusInfo *last;
|
||||
UnitStatusInfo *i = userdata;
|
||||
int r;
|
||||
|
||||
@ -4559,13 +4560,16 @@ static int map_exec(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_e
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
LIST_FIND_TAIL(exec, i->exec, last);
|
||||
|
||||
while ((r = exec_status_info_deserialize(m, info)) > 0) {
|
||||
|
||||
info->name = strdup(member);
|
||||
if (!info->name)
|
||||
return -ENOMEM;
|
||||
|
||||
LIST_PREPEND(exec, i->exec, info);
|
||||
LIST_INSERT_AFTER(exec, i->exec, last, info);
|
||||
last = info;
|
||||
|
||||
info = new0(ExecStatusInfo, 1);
|
||||
if (!info)
|
||||
|
Loading…
Reference in New Issue
Block a user