summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2011-02-13 18:51:30 +0100
committerLennart Poettering <lennart@poettering.net>2011-02-13 18:51:30 +0100
commit3185a36b05d53757a412f847d8c510978b9b00f0 (patch)
tree14e95eaae6c7dc0ecfc4486efbbbb9446e4be0ed
parente9fbc77c8f6a396ce9432e3791710e30de6e570b (diff)
service: make main pid guessing optional, and reread pid file after reloads
-rw-r--r--TODO6
-rw-r--r--man/systemd.service.xml24
-rw-r--r--src/dbus-service.c5
-rw-r--r--src/load-fragment.c1
-rw-r--r--src/service.c22
-rw-r--r--src/service.h1
6 files changed, 47 insertions, 12 deletions
diff --git a/TODO b/TODO
index 4d5a144611..9827b07588 100644
--- 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
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 3bd058f00b..7200525c03 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -216,6 +216,30 @@
</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
diff --git a/src/dbus-service.c b/src/dbus-service.c
index f929627666..93fc2a3b68 100644
--- a/src/dbus-service.c
+++ b/src/dbus-service.c
@@ -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
diff --git a/src/load-fragment.c b/src/load-fragment.c
index ab2bcd2d2f..eaeaadaea4 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -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
diff --git a/src/service.c b/src/service.c
index 60576dfed7..243e5536a7 100644
--- a/src/service.c
+++ b/src/service.c
@@ -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;
diff --git a/src/service.h b/src/service.h
index e06ff3d45a..627b356e2b 100644
--- a/src/service.h
+++ b/src/service.h
@@ -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;