From e2f3b44cfc8864bfea7c77ff4c383ce9b535f27e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 20 Jan 2011 13:17:22 +0100 Subject: [PATCH] service: when reloading a service fails don't fail the entire service but just the reload job --- TODO | 2 ++ src/automount.c | 2 +- src/device.c | 2 +- src/mount.c | 24 ++++++++++++++++++------ src/mount.h | 1 + src/path.c | 2 +- src/service.c | 25 ++++++++++++++++--------- src/service.h | 2 ++ src/snapshot.c | 2 +- src/socket.c | 2 +- src/swap.c | 2 +- src/target.c | 2 +- src/timer.c | 2 +- src/unit.c | 4 ++-- src/unit.h | 2 +- 15 files changed, 50 insertions(+), 26 deletions(-) diff --git a/TODO b/TODO index 65aebb5c..317fe88a 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,7 @@ Bugs: +* Don't try to connect to dbus during early boot + * Fix multiple reload statements * sometimes processes seem to remain when we kill a service diff --git a/src/automount.c b/src/automount.c index b45cbcf5..0ae467cb 100644 --- a/src/automount.c +++ b/src/automount.c @@ -244,7 +244,7 @@ static void automount_set_state(Automount *a, AutomountState state) { automount_state_to_string(old_state), automount_state_to_string(state)); - unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true); } static int automount_coldplug(Unit *u) { diff --git a/src/device.c b/src/device.c index b36bfc1a..5289da3e 100644 --- a/src/device.c +++ b/src/device.c @@ -92,7 +92,7 @@ static void device_set_state(Device *d, DeviceState state) { device_state_to_string(old_state), device_state_to_string(state)); - unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true); } static int device_coldplug(Unit *u) { diff --git a/src/mount.c b/src/mount.c index 5b433c97..08e99141 100644 --- a/src/mount.c +++ b/src/mount.c @@ -554,7 +554,8 @@ static void mount_set_state(Mount *m, MountState state) { mount_state_to_string(old_state), mount_state_to_string(state)); - unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], !m->reload_failure); + m->reload_failure = false; } static int mount_coldplug(Unit *u) { @@ -910,7 +911,8 @@ static void mount_enter_remounting(Mount *m, bool success) { fail: log_warning("%s failed to run 'remount' task: %s", m->meta.id, strerror(-r)); - mount_enter_mounted(m, false); + m->reload_failure = true; + mount_enter_mounted(m, true); } static int mount_start(Unit *u) { @@ -1098,9 +1100,6 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) { case MOUNT_MOUNTING_DONE: case MOUNT_MOUNTING_SIGKILL: case MOUNT_MOUNTING_SIGTERM: - case MOUNT_REMOUNTING: - case MOUNT_REMOUNTING_SIGKILL: - case MOUNT_REMOUNTING_SIGTERM: if (success) mount_enter_mounted(m, true); @@ -1110,6 +1109,18 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) { mount_enter_dead(m, false); break; + case MOUNT_REMOUNTING: + case MOUNT_REMOUNTING_SIGKILL: + case MOUNT_REMOUNTING_SIGTERM: + + m->reload_failure = !success; + if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, true); + else + mount_enter_dead(m, true); + + break; + case MOUNT_UNMOUNTING: case MOUNT_UNMOUNTING_SIGKILL: case MOUNT_UNMOUNTING_SIGTERM: @@ -1147,7 +1158,8 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) { case MOUNT_REMOUNTING: log_warning("%s remounting timed out. Stopping.", u->meta.id); - mount_enter_signal(m, MOUNT_REMOUNTING_SIGTERM, false); + m->reload_failure = true; + mount_enter_mounted(m, true); break; case MOUNT_UNMOUNTING: diff --git a/src/mount.h b/src/mount.h index 954058ce..7c5d9d1f 100644 --- a/src/mount.h +++ b/src/mount.h @@ -79,6 +79,7 @@ struct Mount { bool just_changed:1; bool failure:1; + bool reload_failure:1; mode_t directory_mode; diff --git a/src/path.c b/src/path.c index 77de32d1..bd40ab6f 100644 --- a/src/path.c +++ b/src/path.c @@ -279,7 +279,7 @@ static void path_set_state(Path *p, PathState state) { path_state_to_string(old_state), path_state_to_string(state)); - unit_notify(UNIT(p), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(p), state_translation_table[old_state], state_translation_table[state], true); } static void path_enter_waiting(Path *p, bool initial, bool recheck); diff --git a/src/service.c b/src/service.c index 67b1dfd4..431bccc4 100644 --- a/src/service.c +++ b/src/service.c @@ -1446,7 +1446,8 @@ static void service_set_state(Service *s, ServiceState state) { if (old_state != state) log_debug("%s changed %s -> %s", s->meta.id, service_state_to_string(old_state), service_state_to_string(state)); - unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], !s->reload_failure); + s->reload_failure = false; } static int service_coldplug(Unit *u) { @@ -2120,7 +2121,8 @@ static void service_enter_reload(Service *s) { fail: log_warning("%s failed to run 'reload' task: %s", s->meta.id, strerror(-r)); - service_enter_stop(s, false); + s->reload_failure = true; + service_enter_running(s, true); } static void service_run_next_control(Service *s, bool success) { @@ -2161,7 +2163,10 @@ fail: service_enter_signal(s, SERVICE_STOP_SIGTERM, false); else if (s->state == SERVICE_STOP_POST) service_enter_dead(s, false, true); - else + else if (s->state == SERVICE_RELOAD) { + s->reload_failure = true; + service_enter_running(s, true); + } else service_enter_stop(s, false); } @@ -2647,11 +2652,8 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { /* Fall through */ case SERVICE_RELOAD: - if (success) - service_enter_running(s, true); - else - service_enter_running(s, false); - + s->reload_failure = !success; + service_enter_running(s, true); break; case SERVICE_STOP: @@ -2701,11 +2703,16 @@ static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) { break; case SERVICE_START_POST: - case SERVICE_RELOAD: log_warning("%s operation timed out. Stopping.", u->meta.id); service_enter_stop(s, false); break; + case SERVICE_RELOAD: + log_warning("%s operation timed out. Stopping.", u->meta.id); + s->reload_failure = true; + service_enter_running(s, true); + break; + case SERVICE_STOP: log_warning("%s stopping timed out. Terminating.", u->meta.id); service_enter_signal(s, SERVICE_STOP_SIGTERM, false); diff --git a/src/service.h b/src/service.h index 1b59dad9..75860462 100644 --- a/src/service.h +++ b/src/service.h @@ -118,6 +118,8 @@ struct Service { /* If we shut down, remember why */ bool failure:1; + bool reload_failure:1; + bool main_pid_known:1; bool bus_name_good:1; bool forbid_restart:1; diff --git a/src/snapshot.c b/src/snapshot.c index a23f2dba..7cde25d4 100644 --- a/src/snapshot.c +++ b/src/snapshot.c @@ -45,7 +45,7 @@ static void snapshot_set_state(Snapshot *s, SnapshotState state) { snapshot_state_to_string(old_state), snapshot_state_to_string(state)); - unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true); } static int snapshot_load(Unit *u) { diff --git a/src/socket.c b/src/socket.c index 6ec49de4..7dc205ab 100644 --- a/src/socket.c +++ b/src/socket.c @@ -880,7 +880,7 @@ static void socket_set_state(Socket *s, SocketState state) { socket_state_to_string(old_state), socket_state_to_string(state)); - unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true); } static int socket_coldplug(Unit *u) { diff --git a/src/swap.c b/src/swap.c index 9bdb5aab..6ab99d57 100644 --- a/src/swap.c +++ b/src/swap.c @@ -501,7 +501,7 @@ static void swap_set_state(Swap *s, SwapState state) { swap_state_to_string(old_state), swap_state_to_string(state)); - unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true); } static int swap_coldplug(Unit *u) { diff --git a/src/target.c b/src/target.c index f322ce72..a73a9898 100644 --- a/src/target.c +++ b/src/target.c @@ -49,7 +49,7 @@ static void target_set_state(Target *t, TargetState state) { target_state_to_string(old_state), target_state_to_string(state)); - unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true); } static int target_add_default_dependencies(Target *t) { diff --git a/src/timer.c b/src/timer.c index 6f1f02dd..1477aa52 100644 --- a/src/timer.c +++ b/src/timer.c @@ -152,7 +152,7 @@ static void timer_set_state(Timer *t, TimerState state) { timer_state_to_string(old_state), timer_state_to_string(state)); - unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true); } static void timer_enter_waiting(Timer *t, bool initial); diff --git a/src/unit.c b/src/unit.c index 7d673e13..9dd02676 100644 --- a/src/unit.c +++ b/src/unit.c @@ -1067,7 +1067,7 @@ static void retroactively_stop_dependencies(Unit *u) { unit_check_unneeded(other); } -void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { +void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) { dual_timestamp ts; bool unexpected; @@ -1134,7 +1134,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { if (u->meta.job->state == JOB_RUNNING) { if (ns == UNIT_ACTIVE) - job_finish_and_invalidate(u->meta.job, true); + job_finish_and_invalidate(u->meta.job, reload_success); else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) { unexpected = true; diff --git a/src/unit.h b/src/unit.h index 9eda138f..b30f0cf9 100644 --- a/src/unit.h +++ b/src/unit.h @@ -456,7 +456,7 @@ int unit_reload(Unit *u); int unit_kill(Unit *u, KillWho w, KillMode m, int signo, DBusError *error); -void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns); +void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success); int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w); void unit_unwatch_fd(Unit *u, Watch *w); -- 2.39.5