chiark / gitweb /
service: make main pid guessing optional, and reread pid file after reloads
authorLennart Poettering <lennart@poettering.net>
Sun, 13 Feb 2011 17:51:30 +0000 (18:51 +0100)
committerLennart Poettering <lennart@poettering.net>
Sun, 13 Feb 2011 17:51:30 +0000 (18:51 +0100)
TODO
man/systemd.service.xml
src/dbus-service.c
src/load-fragment.c
src/service.c
src/service.h

diff --git a/TODO b/TODO
index 4d5a144..9827b07 100644 (file)
--- a/TODO
+++ b/TODO
@@ -9,6 +9,8 @@ Bugs:
 
 Features:
 
+* Maybe store in unit files whether a service should be enabled by default on package installation
+
 * perhaps add "systemctl reenable" as combination of "systemctl disable" and "systemctl enable"
 
 * need a way to apply mount options of api vfs from systemd unit files instead of fstab
@@ -23,12 +25,8 @@ Features:
 
 * gnome-shell python script/glxinfo/is-accelerated wech
 
-* PID heuristik bei Type=forking ausmachbar machen
-
 * maybe introduce ExecRestartPre=
 
-* reload PID file after reload, allow dynamically changing main PIDs
-
 * figure out what happened to bluez patch
 
 * introduce StandardOutput=syslog+console and StandardOutput=kmsg+console to support fsck output at boot
index 3bd058f..7200525 100644 (file)
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>GuessMainPID=</varname></term>
+
+                                <listitem><para>Takes a boolean value
+                                that specifies whether systemd should
+                                try to guess the main PID of a service
+                                should if it cannot be determined
+                                reliably. This option is ignored
+                                unless <option>Type=forking</option>
+                                is set and <option>PIDFile=</option>
+                                is unset because for the other types
+                                or with an explicitly configured PID
+                                file the main PID is always known. The
+                                guessing algorithm might come to
+                                incorrect conclusions if a daemon
+                                consists of more than one process. If
+                                the main PID cannot be determined
+                                failure detection and automatic
+                                restarting of a service will not work
+                                reliably. Defaults to
+                                <option>yes</option>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>PIDFile=</varname></term>
 
                                 <listitem><para>Takes an absolute file
index f929627..93fc2a3 100644 (file)
@@ -127,8 +127,9 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio
                 BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Service", u->service.exec_context),
                 { "org.freedesktop.systemd1.Service", "PermissionsStartOnly",   bus_property_append_bool,   "b", &u->service.permissions_start_only    },
                 { "org.freedesktop.systemd1.Service", "RootDirectoryStartOnly", bus_property_append_bool,   "b", &u->service.root_directory_start_only },
-                { "org.freedesktop.systemd1.Service", "RemainAfterExit",        bus_property_append_bool,   "b", &u->service.remain_after_exit          },
-                BUS_EXEC_STATUS_PROPERTIES("org.freedesktop.systemd1.Service", u->service.main_exec_status, "ExecMain"),
+                { "org.freedesktop.systemd1.Service", "RemainAfterExit",        bus_property_append_bool,   "b", &u->service.remain_after_exit         },
+                { "org.freedesktop.systemd1.Service", "GuessMainPID",           bus_property_append_bool,   "b", &u->service.guess_main_pid            },
+               BUS_EXEC_STATUS_PROPERTIES("org.freedesktop.systemd1.Service", u->service.main_exec_status, "ExecMain"),
                 { "org.freedesktop.systemd1.Service", "MainPID",                bus_property_append_pid,    "u", &u->service.main_pid                  },
                 { "org.freedesktop.systemd1.Service", "ControlPID",             bus_property_append_pid,    "u", &u->service.control_pid               },
 #ifdef HAVE_SYSV_COMPAT
index ab2bcd2..eaeaada 100644 (file)
@@ -1854,6 +1854,7 @@ static int load_from_path(Unit *u, const char *path) {
                 { "PermissionsStartOnly",   config_parse_bool,            &u->service.permissions_start_only,              "Service" },
                 { "RootDirectoryStartOnly", config_parse_bool,            &u->service.root_directory_start_only,           "Service" },
                 { "RemainAfterExit",        config_parse_bool,            &u->service.remain_after_exit,                   "Service" },
+                { "GuessMainPID",           config_parse_bool,            &u->service.guess_main_pid,                      "Service" },
 #ifdef HAVE_SYSV_COMPAT
                 { "SysVStartPriority",      config_parse_sysv_priority,   &u->service.sysv_start_priority,                 "Service" },
 #else
index 60576df..243e553 100644 (file)
@@ -118,6 +118,7 @@ static void service_init(Unit *u) {
         s->sysv_start_priority = -1;
 #endif
         s->socket_fd = -1;
+        s->guess_main_pid = true;
 
         exec_context_init(&s->exec_context);
 
@@ -1151,6 +1152,7 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
                 "%sPermissionsStartOnly: %s\n"
                 "%sRootDirectoryStartOnly: %s\n"
                 "%sRemainAfterExit: %s\n"
+                "%sGuessMainPID: %s\n"
                 "%sType: %s\n"
                 "%sRestart: %s\n"
                 "%sNotifyAccess: %s\n",
@@ -1158,6 +1160,7 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
                 prefix, yes_no(s->permissions_start_only),
                 prefix, yes_no(s->root_directory_start_only),
                 prefix, yes_no(s->remain_after_exit),
+                prefix, yes_no(s->guess_main_pid),
                 prefix, service_type_to_string(s->type),
                 prefix, service_restart_to_string(s->restart),
                 prefix, notify_access_to_string(s->notify_access));
@@ -1236,11 +1239,6 @@ static int service_load_pid_file(Service *s) {
 
         assert(s);
 
-        if (s->main_pid_known)
-                return 0;
-
-        assert(s->main_pid <= 0);
-
         if (!s->pid_file)
                 return -ENOENT;
 
@@ -1275,9 +1273,14 @@ static int service_search_main_pid(Service *s) {
 
         assert(s);
 
+        /* If we know it anyway, don't ever fallback to unreliable
+         * heuristics */
         if (s->main_pid_known)
                 return 0;
 
+        if (!s->guess_main_pid)
+                return 0;
+
         assert(s->main_pid <= 0);
 
         if ((pid = cgroup_bonding_search_main_pid_list(s->meta.cgroup_bondings)) <= 0)
@@ -2674,9 +2677,16 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                                 log_warning("%s: failed to load PID file %s: %s", s->meta.id, s->pid_file, strerror(-r));
                                 }
 
-                                /* Fall through */
+                                s->reload_failure = !success;
+                                service_enter_running(s, true);
+                                break;
 
                         case SERVICE_RELOAD:
+                                if (success) {
+                                        service_load_pid_file(s);
+                                        service_search_main_pid(s);
+                                }
+
                                 s->reload_failure = !success;
                                 service_enter_running(s, true);
                                 break;
index e06ff3d..627b356 100644 (file)
@@ -125,6 +125,7 @@ struct Service {
         bool permissions_start_only;
         bool root_directory_start_only;
         bool remain_after_exit;
+        bool guess_main_pid;
 
         /* If we shut down, remember why */
         bool failure:1;