diff --git a/0001-core-introduce-new-KillMode-mixed-which-sends-SIGTER.patch b/0001-core-introduce-new-KillMode-mixed-which-sends-SIGTER.patch new file mode 100644 index 0000000..3729198 --- /dev/null +++ b/0001-core-introduce-new-KillMode-mixed-which-sends-SIGTER.patch @@ -0,0 +1,225 @@ +From 6fa7e1a944a2dbb89e794ad0f9da5d0fda5dc4a9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 29 Jan 2014 13:38:55 +0100 +Subject: [PATCH 1/3] core: introduce new KillMode=mixed which sends SIGTERM + only to the main process, but SIGKILL to all daemon processes + +This should fix some race with terminating systemd --user, where the +system systemd instance might race against the user systemd instance +when sending SIGTERM. +--- + man/systemd.kill.xml | 77 +++++++++++++++++++++++++++++++++----------------- + src/core/kill.c | 1 + + src/core/kill.h | 1 + + src/core/unit.c | 3 +- + units/user@.service.in | 1 + + 5 files changed, 56 insertions(+), 27 deletions(-) + +diff --git a/man/systemd.kill.xml b/man/systemd.kill.xml +index 1b10fba..a4009aa 100644 +--- a/man/systemd.kill.xml ++++ b/man/systemd.kill.xml +@@ -44,39 +44,44 @@ + + + systemd.kill +- Kill environment configuration ++ Process killing procedure ++ configuration + + + + service.service, + socket.socket, + mount.mount, +- swap.swap ++ swap.swap, ++ scope.scope + + + + Description + + Unit configuration files for services, sockets, +- mount points and swap devices share a subset of +- configuration options which define the process killing +- parameters of spawned processes. ++ mount points, swap devices and scopes share a subset ++ of configuration options which define the ++ killing procedure of processes belonging to the unit. + + This man page lists the configuration options +- shared by these four unit types. See ++ shared by these five unit types. See + systemd.unit5 +- for the common options of all unit configuration +- files, and ++ for the common options shared by all unit ++ configuration files, and + systemd.service5, + systemd.socket5, +- systemd.swap5 +- and ++ systemd.swap5, + systemd.mount5 +- for more information on the specific unit +- configuration files. The execution specific ++ and ++ systemd.scope5 ++ for more information on the configuration file options ++ specific to each unit type. ++ ++ The kill procedure + configuration options are configured in the [Service], +- [Socket], [Mount], or [Swap] section, depending on the unit +- type. ++ [Socket], [Mount] or [Swap] section, depending on the ++ unit type. + + + +@@ -87,32 +92,40 @@ + + KillMode= + Specifies how +- processes of this service shall be ++ processes of this unit shall be + killed. One of + , + , ++ , + . + + If set to + , all + remaining processes in the control +- group of this unit will be terminated +- on unit stop (for services: after the ++ group of this unit will be killed on ++ unit stop (for services: after the + stop command is executed, as + configured with + ExecStop=). If set + to , only the + main process itself is killed. If set +- to , no process is ++ to the ++ SIGTERM signal ++ (see below) is sent to the main ++ process while the subsequent ++ SIGKILL signal ++ (see below) is sent to all remaining ++ processes of the unit's control ++ group. If set to ++ , no process is + killed. In this case only the stop +- command will be executed on unit +- stop, but no process be killed ++ command will be executed on unit stop, ++ but no process be killed + otherwise. Processes remaining alive + after stop are left in their control + group and the control group continues + to exist after stop unless it is +- empty. Defaults to +- . ++ empty. + + Processes will first be + terminated via +@@ -133,14 +146,24 @@ + option). See + kill2 + for more +- information. ++ information. ++ ++ Defaults to ++ . + + + + KillSignal= + Specifies which signal +- to use when killing a +- service. Defaults to SIGTERM. ++ to use when killing a service. This ++ controls the signal that is sent as ++ first step of shutting down a unit ++ (see above), and is usually followed ++ by SIGKILL (see ++ above and below). For a list of valid ++ signals, see ++ signal7. Defaults ++ to SIGTERM. + + + +@@ -184,7 +207,9 @@ + systemd.swap5, + systemd.mount5, + systemd.exec5, +- systemd.directives7 ++ systemd.directives7, ++ kill2, ++ signal7 + + + +diff --git a/src/core/kill.c b/src/core/kill.c +index ea947c2..4271346 100644 +--- a/src/core/kill.c ++++ b/src/core/kill.c +@@ -52,6 +52,7 @@ void kill_context_dump(KillContext *c, FILE *f, const char *prefix) { + static const char* const kill_mode_table[_KILL_MODE_MAX] = { + [KILL_CONTROL_GROUP] = "control-group", + [KILL_PROCESS] = "process", ++ [KILL_MIXED] = "mixed", + [KILL_NONE] = "none" + }; + +diff --git a/src/core/kill.h b/src/core/kill.h +index 41773f0..d5f125f 100644 +--- a/src/core/kill.h ++++ b/src/core/kill.h +@@ -32,6 +32,7 @@ typedef enum KillMode { + /* The kill mode is a property of a unit. */ + KILL_CONTROL_GROUP = 0, + KILL_PROCESS, ++ KILL_MIXED, + KILL_NONE, + _KILL_MODE_MAX, + _KILL_MODE_INVALID = -1 +diff --git a/src/core/unit.c b/src/core/unit.c +index 4b97710..0b10e57 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -3007,7 +3007,7 @@ int unit_kill_context( + } + } + +- if (c->kill_mode == KILL_CONTROL_GROUP && u->cgroup_path) { ++ if ((c->kill_mode == KILL_CONTROL_GROUP || (c->kill_mode == KILL_MIXED && sigkill)) && u->cgroup_path) { + _cleanup_set_free_ Set *pid_set = NULL; + + /* Exclude the main/control pids from being killed via the cgroup */ +@@ -3021,6 +3021,7 @@ int unit_kill_context( + log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r)); + } else if (r > 0) { + wait_for_exit = true; ++ + if (c->send_sighup) { + set_free(pid_set); + +diff --git a/units/user@.service.in b/units/user@.service.in +index 3718a57..3bb8696 100644 +--- a/units/user@.service.in ++++ b/units/user@.service.in +@@ -17,3 +17,4 @@ Environment=SHELL=%s + ExecStart=-@rootlibexecdir@/systemd --user + Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket + Slice=user-%i.slice ++KillMode=mixed +-- +1.8.4 + diff --git a/0002-service-allow-KillMode-mixed-in-conjunction-with-PAM.patch b/0002-service-allow-KillMode-mixed-in-conjunction-with-PAM.patch new file mode 100644 index 0000000..76624f9 --- /dev/null +++ b/0002-service-allow-KillMode-mixed-in-conjunction-with-PAM.patch @@ -0,0 +1,62 @@ +From 95d57e7b631a2d78b9b5d841125194052895470f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 29 Jan 2014 13:49:54 +0100 +Subject: [PATCH 2/3] service: allow KillMode=mixed in conjunction with + PAMName= + +--- + src/core/service.c | 20 +++++++------------- + 1 file changed, 7 insertions(+), 13 deletions(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 6792024..e7f03e1 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -1105,37 +1105,31 @@ static int service_verify(Service *s) { + return 0; + + if (!s->exec_command[SERVICE_EXEC_START]) { +- log_error_unit(UNIT(s)->id, +- "%s lacks ExecStart setting. Refusing.", UNIT(s)->id); ++ log_error_unit(UNIT(s)->id, "%s lacks ExecStart setting. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->type != SERVICE_ONESHOT && + s->exec_command[SERVICE_EXEC_START]->command_next) { +- log_error_unit(UNIT(s)->id, +- "%s has more than one ExecStart setting, which is only allowed for Type=oneshot services. Refusing.", UNIT(s)->id); ++ log_error_unit(UNIT(s)->id, "%s has more than one ExecStart setting, which is only allowed for Type=oneshot services. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->type == SERVICE_ONESHOT && s->restart != SERVICE_RESTART_NO) { +- log_error_unit(UNIT(s)->id, +- "%s has Restart setting other than no, which isn't allowed for Type=oneshot services. Refusing.", UNIT(s)->id); ++ log_error_unit(UNIT(s)->id, "%s has Restart setting other than no, which isn't allowed for Type=oneshot services. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->type == SERVICE_DBUS && !s->bus_name) { +- log_error_unit(UNIT(s)->id, +- "%s is of type D-Bus but no D-Bus service name has been specified. Refusing.", UNIT(s)->id); ++ log_error_unit(UNIT(s)->id, "%s is of type D-Bus but no D-Bus service name has been specified. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->bus_name && s->type != SERVICE_DBUS) +- log_warning_unit(UNIT(s)->id, +- "%s has a D-Bus service name specified, but is not of type dbus. Ignoring.", UNIT(s)->id); ++ log_warning_unit(UNIT(s)->id, "%s has a D-Bus service name specified, but is not of type dbus. Ignoring.", UNIT(s)->id); + +- if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) { +- log_error_unit(UNIT(s)->id, +- "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id); ++ if (s->exec_context.pam_name && !(s->kill_context.kill_mode == KILL_CONTROL_GROUP || s->kill_context.kill_mode == KILL_MIXED)) { ++ log_error_unit(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group' or 'mixed'. Refusing.", UNIT(s)->id); + return -EINVAL; + } + +-- +1.8.4 + diff --git a/0003-core-make-sure-to-always-go-through-both-SIGTERM-and.patch b/0003-core-make-sure-to-always-go-through-both-SIGTERM-and.patch new file mode 100644 index 0000000..e6423f5 --- /dev/null +++ b/0003-core-make-sure-to-always-go-through-both-SIGTERM-and.patch @@ -0,0 +1,128 @@ +From b2ffdc8da536cd88a305f97517f356e2c5383a52 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 29 Jan 2014 14:58:04 +0100 +Subject: [PATCH 3/3] core: make sure to always go through both SIGTERM and + SIGKILL states of units + +Given that we now have KillMode=mixed where SIGTERM might kill a smaller +set than SIGKILL we need to make sure to always go explicitly throught +the SIGKILL state to get the right end result. +--- + src/core/mount.c | 8 +++++++- + src/core/scope.c | 4 +++- + src/core/service.c | 10 +++++++--- + src/core/socket.c | 6 +++++- + src/core/swap.c | 6 +++++- + 5 files changed, 27 insertions(+), 7 deletions(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 3d46557..e418d09 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -854,8 +854,14 @@ static void mount_enter_signal(Mount *m, MountState state, MountResult f) { + goto fail; + + mount_set_state(m, state); +- } else if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL) ++ } else if (state == MOUNT_REMOUNTING_SIGTERM) ++ mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_SUCCESS); ++ else if (state == MOUNT_REMOUNTING_SIGKILL) + mount_enter_mounted(m, MOUNT_SUCCESS); ++ else if (state == MOUNT_MOUNTING_SIGTERM) ++ mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_SUCCESS); ++ else if (state == MOUNT_UNMOUNTING_SIGTERM) ++ mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_SUCCESS); + else + mount_enter_dead(m, MOUNT_SUCCESS); + +diff --git a/src/core/scope.c b/src/core/scope.c +index 50e5dba..3a5c95e 100644 +--- a/src/core/scope.c ++++ b/src/core/scope.c +@@ -221,7 +221,9 @@ static void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) { + } + + scope_set_state(s, state); +- } else ++ } else if (state == SCOPE_STOP_SIGTERM) ++ scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_SUCCESS); ++ else + scope_enter_dead(s, SCOPE_SUCCESS); + + return; +diff --git a/src/core/service.c b/src/core/service.c +index e7f03e1..4b481c2 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -1964,10 +1964,9 @@ static void service_enter_stop_post(Service *s, ServiceResult f) { + if (r < 0) + goto fail; + +- + service_set_state(s, SERVICE_STOP_POST); + } else +- service_enter_dead(s, SERVICE_SUCCESS, true); ++ service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_SUCCESS); + + return; + +@@ -1993,6 +1992,7 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f + s->main_pid, + s->control_pid, + s->main_pid_alien); ++ + if (r < 0) + goto fail; + +@@ -2005,8 +2005,12 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f + } + + service_set_state(s, state); +- } else if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL) ++ } else if (state == SERVICE_STOP_SIGTERM) ++ service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_SUCCESS); ++ else if (state == SERVICE_STOP_SIGKILL) + service_enter_stop_post(s, SERVICE_SUCCESS); ++ else if (state == SERVICE_FINAL_SIGTERM) ++ service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_SUCCESS); + else + service_enter_dead(s, SERVICE_SUCCESS, true); + +diff --git a/src/core/socket.c b/src/core/socket.c +index 6c0ac1a..831876f 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -1298,8 +1298,12 @@ static void socket_enter_signal(Socket *s, SocketState state, SocketResult f) { + goto fail; + + socket_set_state(s, state); +- } else if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL) ++ } else if (state == SOCKET_STOP_PRE_SIGTERM) ++ socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_SUCCESS); ++ else if (state == SOCKET_STOP_PRE_SIGKILL) + socket_enter_stop_post(s, SOCKET_SUCCESS); ++ else if (state == SOCKET_FINAL_SIGTERM) ++ socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_SUCCESS); + else + socket_enter_dead(s, SOCKET_SUCCESS); + +diff --git a/src/core/swap.c b/src/core/swap.c +index a68ab7c..8886fe8 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -655,7 +655,11 @@ static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) { + goto fail; + + swap_set_state(s, state); +- } else ++ } else if (state == SWAP_ACTIVATING_SIGTERM) ++ swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS); ++ else if (state == SWAP_DEACTIVATING_SIGTERM) ++ swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS); ++ else + swap_enter_dead(s, SWAP_SUCCESS); + + return; +-- +1.8.4 + diff --git a/systemd-mini.changes b/systemd-mini.changes index 0bafb0b..3967568 100644 --- a/systemd-mini.changes +++ b/systemd-mini.changes @@ -4,6 +4,14 @@ Thu Jan 30 08:29:00 UTC 2014 - werner@suse.de - Change patch 0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch to skip already by the kernel managed devices +------------------------------------------------------------------- +Wed Jan 29 18:03:39 UTC 2014 - arvidjaar@gmail.com + +- fix timeout stopping user@.service (bnc#841544) + * 0001-core-introduce-new-KillMode-mixed-which-sends-SIGTER.patch + * 0002-service-allow-KillMode-mixed-in-conjunction-with-PAM.patch + * 0003-core-make-sure-to-always-go-through-both-SIGTERM-and.patch + ------------------------------------------------------------------- Tue Jan 28 12:44:07 UTC 2014 - werner@suse.de diff --git a/systemd-mini.spec b/systemd-mini.spec index 736ac29..33ae73a 100644 --- a/systemd-mini.spec +++ b/systemd-mini.spec @@ -265,6 +265,12 @@ Patch84: make-emergency.service-conflict-with-syslog.socket.patch Patch85: 0001-upstream-systemctl-halt-reboot-error-handling.patch # PATCH-FIX-SUSE 0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch Patch86: 0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch +# PATCH-FIX-UPSTREAM 0001-core-introduce-new-KillMode-mixed-which-sends-SIGTER.patch -- Allow sending SIGTERM to main PID only (bnc#841544) +Patch87: 0001-core-introduce-new-KillMode-mixed-which-sends-SIGTER.patch +# PATCH-FIX-UPSTREAM 0002-service-allow-KillMode-mixed-in-conjunction-with-PAM.patch -- Allow using it with PAM enabled services (bnc#841544) +Patch88: 0002-service-allow-KillMode-mixed-in-conjunction-with-PAM.patch +# PATCH-FIX-UPSTREAM 0003-core-make-sure-to-always-go-through-both-SIGTERM-and.patch -- Make sure final SIGKILL actually kills everything (bnc#841544) +Patch89: 0003-core-make-sure-to-always-go-through-both-SIGTERM-and.patch # udev patches # PATCH-FIX-OPENSUSE 1001-re-enable-by_path-links-for-ata-devices.patch @@ -571,6 +577,9 @@ cp %{SOURCE7} m4/ %patch84 -p1 %patch85 -p1 %patch86 -p1 +%patch87 -p1 +%patch88 -p1 +%patch89 -p1 # udev patches %patch1001 -p1 diff --git a/systemd.changes b/systemd.changes index 0bafb0b..3967568 100644 --- a/systemd.changes +++ b/systemd.changes @@ -4,6 +4,14 @@ Thu Jan 30 08:29:00 UTC 2014 - werner@suse.de - Change patch 0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch to skip already by the kernel managed devices +------------------------------------------------------------------- +Wed Jan 29 18:03:39 UTC 2014 - arvidjaar@gmail.com + +- fix timeout stopping user@.service (bnc#841544) + * 0001-core-introduce-new-KillMode-mixed-which-sends-SIGTER.patch + * 0002-service-allow-KillMode-mixed-in-conjunction-with-PAM.patch + * 0003-core-make-sure-to-always-go-through-both-SIGTERM-and.patch + ------------------------------------------------------------------- Tue Jan 28 12:44:07 UTC 2014 - werner@suse.de diff --git a/systemd.spec b/systemd.spec index f2bab5c..07823db 100644 --- a/systemd.spec +++ b/systemd.spec @@ -260,6 +260,12 @@ Patch84: make-emergency.service-conflict-with-syslog.socket.patch Patch85: 0001-upstream-systemctl-halt-reboot-error-handling.patch # PATCH-FIX-SUSE 0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch Patch86: 0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch +# PATCH-FIX-UPSTREAM 0001-core-introduce-new-KillMode-mixed-which-sends-SIGTER.patch -- Allow sending SIGTERM to main PID only (bnc#841544) +Patch87: 0001-core-introduce-new-KillMode-mixed-which-sends-SIGTER.patch +# PATCH-FIX-UPSTREAM 0002-service-allow-KillMode-mixed-in-conjunction-with-PAM.patch -- Allow using it with PAM enabled services (bnc#841544) +Patch88: 0002-service-allow-KillMode-mixed-in-conjunction-with-PAM.patch +# PATCH-FIX-UPSTREAM 0003-core-make-sure-to-always-go-through-both-SIGTERM-and.patch -- Make sure final SIGKILL actually kills everything (bnc#841544) +Patch89: 0003-core-make-sure-to-always-go-through-both-SIGTERM-and.patch # udev patches # PATCH-FIX-OPENSUSE 1001-re-enable-by_path-links-for-ata-devices.patch @@ -566,6 +572,9 @@ cp %{SOURCE7} m4/ %patch84 -p1 %patch85 -p1 %patch86 -p1 +%patch87 -p1 +%patch88 -p1 +%patch89 -p1 # udev patches %patch1001 -p1