[systemd-commits] 3 commits - man/pam_systemd.xml man/systemd.mount.xml man/systemd.service.xml man/systemd.socket.xml man/systemd.swap.xml src/execute.c src/execute.h src/load-fragment.c src/mount.c src/pam-module.c src/service.c src/service.h src/socket.c src/swap.c TODO

Lennart Poettering lennart at kemper.freedesktop.org
Tue Jan 18 14:07:18 PST 2011


 TODO                    |    8 --------
 man/pam_systemd.xml     |   17 ++++++++++++++++-
 man/systemd.mount.xml   |   10 ++++++++++
 man/systemd.service.xml |   20 +++++++++++++++++---
 man/systemd.socket.xml  |   11 +++++++++++
 man/systemd.swap.xml    |   11 +++++++++++
 src/execute.c           |    7 +++++--
 src/execute.h           |    1 +
 src/load-fragment.c     |    1 +
 src/mount.c             |   39 +++++++++++++++++++++++++++++++++------
 src/pam-module.c        |   19 +++++++++++++++----
 src/service.c           |   22 +++++++++++++++++-----
 src/service.h           |    2 +-
 src/socket.c            |   18 ++++++++++++++----
 src/swap.c              |   18 ++++++++++++++----
 15 files changed, 166 insertions(+), 38 deletions(-)

New commits:
commit 3add4d215b30c746ee617d7412ee007ed3c87249
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 18 23:07:06 2011 +0100

    pam: optionally keep processes of root user around

diff --git a/TODO b/TODO
index 61a8cfc..48f4628 100644
--- a/TODO
+++ b/TODO
@@ -4,8 +4,6 @@
 
 * figure out what happened to bluez patch
 
-* in pam_systemd: add option to kill normal user sessions on logout but only those with uid != 0
-
 * introduce StandardOutput=syslog+console and StandardOutput=kmsg+console to support fsck output at boot
 
 * Patch systemd-fsck to use -C and pass console fd to it
diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml
index cd806da..eddd8e0 100644
--- a/man/pam_systemd.xml
+++ b/man/pam_systemd.xml
@@ -202,6 +202,20 @@
                         </varlistentry>
 
                         <varlistentry>
+                                <term><option>keep-root=</option></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true, all processes
+                                created by the root user (UID 0) during his
+                                session and from his session will be
+                                kept around after he logged out. This
+                                option allows cancelling the effect of
+                                <option>kill-session=1</option> and
+                                <option>kill-user=1</option> for the
+                                root user.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><option>controllers=</option></term>
 
                                 <listitem><para>Takes a comma
@@ -230,7 +244,8 @@
                 <para>If the options are omitted they default to
                 <option>create-session=1</option>,
                 <option>kill-session=0</option>,
-                <option>kill-user=0</option>.</para>
+                <option>kill-user=0</option>,
+                <option>keep-root=1</option>.</para>
         </refsect1>
 
         <refsect1>
diff --git a/src/pam-module.c b/src/pam-module.c
index 6fbaecf..52507a4 100644
--- a/src/pam-module.c
+++ b/src/pam-module.c
@@ -42,6 +42,7 @@ static int parse_argv(pam_handle_t *handle,
                       bool *create_session,
                       bool *kill_session,
                       bool *kill_user,
+                      bool *keep_root,
                       char ***controllers) {
 
         unsigned i;
@@ -80,6 +81,15 @@ static int parse_argv(pam_handle_t *handle,
                         if (kill_user)
                                 *kill_user = k;
 
+                } else if (startswith(argv[i], "keep-root=")) {
+                        if ((k = parse_boolean(argv[i] + 10)) < 0) {
+                                pam_syslog(handle, LOG_ERR, "Failed to parse keep-root= argument.");
+                                return k;
+                        }
+
+                        if (keep_root)
+                                *keep_root = k;
+
                 } else if (startswith(argv[i], "controllers=")) {
 
                         if (controllers) {
@@ -327,7 +337,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         if (sd_booted() <= 0)
                 return PAM_SUCCESS;
 
-        if (parse_argv(handle, argc, argv, &create_session, NULL, NULL, &controllers) < 0)
+        if (parse_argv(handle, argc, argv, &create_session, NULL, NULL, NULL, &controllers) < 0)
                 return PAM_SESSION_ERR;
 
         if ((r = get_user_data(handle, &username, &pw)) != PAM_SUCCESS)
@@ -462,6 +472,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
         const char *username = NULL;
         bool kill_session = false;
         bool kill_user = false;
+        bool keep_root = true;
         int lock_fd = -1, r;
         char *session_path = NULL, *nosession_path = NULL, *user_path = NULL;
         const char *id;
@@ -475,7 +486,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
         if (sd_booted() <= 0)
                 return PAM_SUCCESS;
 
-        if (parse_argv(handle, argc, argv, NULL, &kill_session, &kill_user, &controllers) < 0)
+        if (parse_argv(handle, argc, argv, NULL, &kill_session, &kill_user, &keep_root, &controllers) < 0)
                 return PAM_SESSION_ERR;
 
         if ((r = get_user_data(handle, &username, &pw)) != PAM_SUCCESS)
@@ -510,7 +521,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
                         goto finish;
                 }
 
-                if (kill_session)  {
+                if (kill_session && (pw->pw_uid != 0 || !keep_root))  {
                         pam_syslog(handle, LOG_INFO, "Killing remaining processes of user session %s of %s.", id, username);
 
                         /* Kill processes in session cgroup, and delete it */
@@ -544,7 +555,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
                 pam_syslog(handle, LOG_ERR, "Failed to determine whether a session remains: %s", strerror(-r));
 
         /* Kill user processes not attached to any session */
-        if (kill_user && r == 0) {
+        if (kill_user && r == 0 && (pw->pw_uid != 0 || !keep_root)) {
 
                 /* Kill user cgroup */
                 if ((r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, user_path, true)) < 0)

commit d8cfa085894607afdeb8bba025d842adf09ab7ea
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 18 22:57:46 2011 +0100

    service: if a reload operation fails, don't shut down the service

diff --git a/TODO b/TODO
index 4605115..61a8cfc 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,3 @@
-* don't fail a service if reload fails
-
 * reload PID file after reload, allow dynamically changing main PIDs
 
 * Fix multiple reload statements
diff --git a/src/service.c b/src/service.c
index e765004..67b1dfd 100644
--- a/src/service.c
+++ b/src/service.c
@@ -2650,7 +2650,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                 if (success)
                                         service_enter_running(s, true);
                                 else
-                                        service_enter_stop(s, false);
+                                        service_enter_running(s, false);
 
                                 break;
 

commit ba035df230e41bf9d70ebb47915c9472b7884412
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 18 22:55:54 2011 +0100

    execute: make sending of SIGKILL on shutdown optional

diff --git a/TODO b/TODO
index f87f7d1..4605115 100644
--- a/TODO
+++ b/TODO
@@ -4,8 +4,6 @@
 
 * Fix multiple reload statements
 
-* make usage of SIGKILL when shutting down services optional
-
 * figure out what happened to bluez patch
 
 * in pam_systemd: add option to kill normal user sessions on logout but only those with uid != 0
@@ -23,8 +21,6 @@
 
 * finish syslog socket stuff
 
-* when starting systemd --user we get "Failed to set udev event buffer size."
-
 * configurable jitter for timer events
 
 * dbus should run with oom adjust set
diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
index e2a9f22..c7045e8 100644
--- a/man/systemd.mount.xml
+++ b/man/systemd.mount.xml
@@ -240,6 +240,16 @@
                                 </para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><varname>SendSIGKILL=</varname></term>
+                                <listitem><para>Specifies whether to
+                                send SIGKILL to remaining processes
+                                after a timeout, if the normal
+                                shutdown procedure left processes of
+                                the mount around. Takes a boolean
+                                value. Defaults to "yes".
+                                </para></listitem>
+                        </varlistentry>
                 </variablelist>
         </refsect1>
 
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index e5262f6..ee4d393 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -560,14 +560,17 @@
                                 <option>control-group</option>.</para>
 
                                 <para>Processes will first be
-                                terminated via SIGTERM (unless this is
-                                changed via
+                                terminated via SIGTERM (unless the
+                                signal to send is changed via
                                 <varname>KillSignal=</varname>). If
                                 then after a delay (configured via the
                                 <varname>TimeoutSec=</varname> option)
                                 processes still remain, the
                                 termination request is repeated with
-                                the SIGKILL signal. See
+                                the SIGKILL signal (unless this is
+                                disabled via the
+                                <varname>SendSIGKILL=</varname>
+                                option). See
                                 <citerefentry><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>
                                 for more
                                 information.</para></listitem>
@@ -582,6 +585,17 @@
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>SendSIGKILL=</varname></term>
+                                <listitem><para>Specifies whether to
+                                send SIGKILL to remaining processes
+                                after a timeout, if the normal
+                                shutdown procedure left processes of
+                                the service around. Takes a boolean
+                                value. Defaults to "yes".
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>NonBlocking=</varname></term>
                                 <listitem><para>Set O_NONBLOCK flag
                                 for all file descriptors passed via
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 47ad913..1aea2f8 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -528,6 +528,17 @@
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>SendSIGKILL=</varname></term>
+                                <listitem><para>Specifies whether to
+                                send SIGKILL to remaining processes
+                                after a timeout, if the normal
+                                shutdown procedure left processes of
+                                the socket around. Takes a boolean
+                                value. Defaults to "yes".
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>Service=</varname></term>
                                 <listitem><para>Specifies the service
                                 unit name to activate on incoming
diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml
index 4546703..45f8f40 100644
--- a/man/systemd.swap.xml
+++ b/man/systemd.swap.xml
@@ -176,6 +176,17 @@
                                 swap. Defaults to SIGTERM.
                                 </para></listitem>
                         </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SendSIGKILL=</varname></term>
+                                <listitem><para>Specifies whether to
+                                send SIGKILL to remaining processes
+                                after a timeout, if the normal
+                                shutdown procedure left processes of
+                                the swap around. Takes a boolean
+                                value. Defaults to "yes".
+                                </para></listitem>
+                        </varlistentry>
                 </variablelist>
         </refsect1>
 
diff --git a/src/execute.c b/src/execute.c
index 1e8dfaf..10ce951 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -1349,6 +1349,7 @@ void exec_context_init(ExecContext *c) {
         c->syslog_level_prefix = true;
         c->mount_flags = MS_SHARED;
         c->kill_signal = SIGTERM;
+        c->send_sigkill = true;
 }
 
 void exec_context_done(ExecContext *c) {
@@ -1618,9 +1619,11 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
 
         fprintf(f,
                 "%sKillMode: %s\n"
-                "%sKillSignal: SIG%s\n",
+                "%sKillSignal: SIG%s\n"
+                "%sSendSIGKILL: %s\n",
                 prefix, kill_mode_to_string(c->kill_mode),
-                prefix, signal_to_string(c->kill_signal));
+                prefix, signal_to_string(c->kill_signal),
+                prefix, yes_no(c->send_sigkill));
 
         if (c->utmp_id)
                 fprintf(f,
diff --git a/src/execute.h b/src/execute.h
index dd84c3d..a6766f9 100644
--- a/src/execute.h
+++ b/src/execute.h
@@ -145,6 +145,7 @@ struct ExecContext {
         /* Not relevant for spawning processes, just for killing */
         KillMode kill_mode;
         int kill_signal;
+        bool send_sigkill;
 
         cap_t capabilities;
         int secure_bits;
diff --git a/src/load-fragment.c b/src/load-fragment.c
index b7c3cbb..44b2cf0 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -1820,6 +1820,7 @@ static int load_from_path(Unit *u, const char *path) {
                 { "PAMName",                config_parse_string_printf,   &(context).pam_name,                             section   }, \
                 { "KillMode",               config_parse_kill_mode,       &(context).kill_mode,                            section   }, \
                 { "KillSignal",             config_parse_kill_signal,     &(context).kill_signal,                          section   }, \
+                { "SendSIGKILL",            config_parse_bool,            &(context).send_sigkill,                         section   }, \
                 { "UtmpIdentifier",         config_parse_string_printf,   &(context).utmp_id,                              section   }
 
         const ConfigItem items[] = {
diff --git a/src/mount.c b/src/mount.c
index 077ab91..5b433c9 100644
--- a/src/mount.c
+++ b/src/mount.c
@@ -1156,18 +1156,45 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
                 break;
 
         case MOUNT_MOUNTING_SIGTERM:
-                log_warning("%s mounting timed out. Killing.", u->meta.id);
-                mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, false);
+                if (m->exec_context.send_sigkill) {
+                        log_warning("%s mounting timed out. Killing.", u->meta.id);
+                        mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, false);
+                } else {
+                        log_warning("%s mounting timed out. Skipping SIGKILL. Ignoring.", u->meta.id);
+
+                        if (m->from_proc_self_mountinfo)
+                                mount_enter_mounted(m, false);
+                        else
+                                mount_enter_dead(m, false);
+                }
                 break;
 
         case MOUNT_REMOUNTING_SIGTERM:
-                log_warning("%s remounting timed out. Killing.", u->meta.id);
-                mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, false);
+                if (m->exec_context.send_sigkill) {
+                        log_warning("%s remounting timed out. Killing.", u->meta.id);
+                        mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, false);
+                } else {
+                        log_warning("%s remounting timed out. Skipping SIGKILL. Ignoring.", u->meta.id);
+
+                        if (m->from_proc_self_mountinfo)
+                                mount_enter_mounted(m, false);
+                        else
+                                mount_enter_dead(m, false);
+                }
                 break;
 
         case MOUNT_UNMOUNTING_SIGTERM:
-                log_warning("%s unmounting timed out. Killing.", u->meta.id);
-                mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, false);
+                if (m->exec_context.send_sigkill) {
+                        log_warning("%s unmounting timed out. Killing.", u->meta.id);
+                        mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, false);
+                } else {
+                        log_warning("%s unmounting timed out. Skipping SIGKILL. Ignoring.", u->meta.id);
+
+                        if (m->from_proc_self_mountinfo)
+                                mount_enter_mounted(m, false);
+                        else
+                                mount_enter_dead(m, false);
+                }
                 break;
 
         case MOUNT_MOUNTING_SIGKILL:
diff --git a/src/service.c b/src/service.c
index e4dfa40..e765004 100644
--- a/src/service.c
+++ b/src/service.c
@@ -2712,8 +2712,14 @@ static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) {
                 break;
 
         case SERVICE_STOP_SIGTERM:
-                log_warning("%s stopping timed out. Killing.", u->meta.id);
-                service_enter_signal(s, SERVICE_STOP_SIGKILL, false);
+                if (s->exec_context.send_sigkill) {
+                        log_warning("%s stopping timed out. Killing.", u->meta.id);
+                        service_enter_signal(s, SERVICE_STOP_SIGKILL, false);
+                } else {
+                        log_warning("%s stopping timed out. Skipping SIGKILL.", u->meta.id);
+                        service_enter_stop_post(s, false);
+                }
+
                 break;
 
         case SERVICE_STOP_SIGKILL:
@@ -2731,8 +2737,14 @@ static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) {
                 break;
 
         case SERVICE_FINAL_SIGTERM:
-                log_warning("%s stopping timed out (2). Killing.", u->meta.id);
-                service_enter_signal(s, SERVICE_FINAL_SIGKILL, false);
+                if (s->exec_context.send_sigkill) {
+                        log_warning("%s stopping timed out (2). Killing.", u->meta.id);
+                        service_enter_signal(s, SERVICE_FINAL_SIGKILL, false);
+                } else {
+                        log_warning("%s stopping timed out (2). Skipping SIGKILL. Entering failed mode.", u->meta.id);
+                        service_enter_dead(s, false, true);
+                }
+
                 break;
 
         case SERVICE_FINAL_SIGKILL:
diff --git a/src/service.h b/src/service.h
index 500bebf..1b59dad 100644
--- a/src/service.h
+++ b/src/service.h
@@ -33,7 +33,7 @@ typedef enum ServiceState {
         SERVICE_START,
         SERVICE_START_POST,
         SERVICE_RUNNING,
-        SERVICE_EXITED,            /* Nothing is running anymore, but RemainAfterExit is true, ehnce this is OK */
+        SERVICE_EXITED,            /* Nothing is running anymore, but RemainAfterExit is true hence this is OK */
         SERVICE_RELOAD,
         SERVICE_STOP,              /* No STOP_PRE state, instead just register multiple STOP executables */
         SERVICE_STOP_SIGTERM,
diff --git a/src/socket.c b/src/socket.c
index cb38ab3..6ec49de 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -1688,8 +1688,13 @@ static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
                 break;
 
         case SOCKET_STOP_PRE_SIGTERM:
-                log_warning("%s stopping timed out. Killing.", u->meta.id);
-                socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, false);
+                if (s->exec_context.send_sigkill) {
+                        log_warning("%s stopping timed out. Killing.", u->meta.id);
+                        socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, false);
+                } else {
+                        log_warning("%s stopping timed out. Skipping SIGKILL. Ignoring.", u->meta.id);
+                        socket_enter_stop_post(s, false);
+                }
                 break;
 
         case SOCKET_STOP_PRE_SIGKILL:
@@ -1703,8 +1708,13 @@ static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
                 break;
 
         case SOCKET_FINAL_SIGTERM:
-                log_warning("%s stopping timed out (2). Killing.", u->meta.id);
-                socket_enter_signal(s, SOCKET_FINAL_SIGKILL, false);
+                if (s->exec_context.send_sigkill) {
+                        log_warning("%s stopping timed out (2). Killing.", u->meta.id);
+                        socket_enter_signal(s, SOCKET_FINAL_SIGKILL, false);
+                } else {
+                        log_warning("%s stopping timed out (2). Skipping SIGKILL. Ignoring.", u->meta.id);
+                        socket_enter_dead(s, false);
+                }
                 break;
 
         case SOCKET_FINAL_SIGKILL:
diff --git a/src/swap.c b/src/swap.c
index 0d3cb2f..9bdb5aa 100644
--- a/src/swap.c
+++ b/src/swap.c
@@ -995,13 +995,23 @@ static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
                 break;
 
         case SWAP_ACTIVATING_SIGTERM:
-                log_warning("%s activation timed out. Killing.", u->meta.id);
-                swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, false);
+                if (s->exec_context.send_sigkill) {
+                        log_warning("%s activation timed out. Killing.", u->meta.id);
+                        swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, false);
+                } else {
+                        log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->meta.id);
+                        swap_enter_dead(s, false);
+                }
                 break;
 
         case SWAP_DEACTIVATING_SIGTERM:
-                log_warning("%s deactivation timed out. Killing.", u->meta.id);
-                swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, false);
+                if (s->exec_context.send_sigkill) {
+                        log_warning("%s deactivation timed out. Killing.", u->meta.id);
+                        swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, false);
+                } else {
+                        log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->meta.id);
+                        swap_enter_dead(s, false);
+                }
                 break;
 
         case SWAP_ACTIVATING_SIGKILL:



More information about the systemd-commits mailing list