mirror of
https://github.com/systemd/systemd.git
synced 2024-11-02 02:21:44 +03:00
core: properly reset all ExecStatus structures when entering a new unit cycle
Whenever a unit is started fresh we should flush out any runtime data from the previous cycle. We are pretty good at that already, but what so far we missed was the ExecStart=/ExecStop=/… command exit status data. Let's fix that, and properly flush out that stuff too. Consider this service: [Service] ExecStart=/bin/sleep infinity ExecStop=/bin/false When this service is started, then stopped and then started again "systemctl status" would show the ExecStop= results of the previous run along with the ExecStart= results of the current one, which is very confusing. With this patch this is corrected: the data is kept right until the moment the new service cycle starts, and then flushed out. Hence "systemctl status" in that case will only show the ExecStart= data, but no ExecStop= data, like it should be. This should fix part of the confusion of #9588
This commit is contained in:
parent
42cb05d5ff
commit
6a1d4d9fa6
@ -3685,6 +3685,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;
|
||||
@ -4364,6 +4382,12 @@ void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
|
@ -340,10 +340,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, ...);
|
||||
@ -367,6 +367,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);
|
||||
|
@ -1074,6 +1074,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;
|
||||
|
||||
|
@ -1673,7 +1673,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];
|
||||
@ -2252,8 +2251,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;
|
||||
|
||||
@ -2262,12 +2259,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;
|
||||
}
|
||||
|
@ -2457,6 +2457,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;
|
||||
|
||||
|
@ -853,6 +853,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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user