From: Lennart Poettering Date: Mon, 13 Nov 2017 17:14:20 +0000 (+0100) Subject: core: only process one of READY=1, STOPPING=1 or RELOADING=1 in sd_notify() handling X-Git-Tag: v236~105^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cc2b7b11b45f82fb881ac788ec2203c632677f90;p=thirdparty%2Fsystemd.git core: only process one of READY=1, STOPPING=1 or RELOADING=1 in sd_notify() handling Of course, it's not really a valid sd_notify() message if multiple of these fields are used in one, but let's handle this somewhat gracefully, by only processing one of them, and ignoring the rest. --- diff --git a/src/core/service.c b/src/core/service.c index 0beb25b8603..b25ed49cce2 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -3348,6 +3348,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds) Service *s = SERVICE(u); bool notify_dbus = false; const char *e; + char **i; assert(u); @@ -3377,44 +3378,43 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds) } } - /* Interpret RELOADING= */ - if (strv_find(tags, "RELOADING=1")) { + /* Interpret READY=/STOPPING=/RELOADING=. Last one wins. */ + STRV_FOREACH_BACKWARDS(i, tags) { - s->notify_state = NOTIFY_RELOADING; + if (streq(*i, "READY=1")) { + s->notify_state = NOTIFY_READY; - if (s->state == SERVICE_RUNNING) - service_enter_reload_by_notify(s); - - notify_dbus = true; - } + /* Type=notify services inform us about completed + * initialization with READY=1 */ + if (s->type == SERVICE_NOTIFY && s->state == SERVICE_START) + service_enter_start_post(s); - /* Interpret READY= */ - if (strv_find(tags, "READY=1")) { + /* Sending READY=1 while we are reloading informs us + * that the reloading is complete */ + if (s->state == SERVICE_RELOAD && s->control_pid == 0) + service_enter_running(s, SERVICE_SUCCESS); - s->notify_state = NOTIFY_READY; + notify_dbus = true; + break; - /* Type=notify services inform us about completed - * initialization with READY=1 */ - if (s->type == SERVICE_NOTIFY && s->state == SERVICE_START) - service_enter_start_post(s); + } else if (streq(*i, "RELOADING=1")) { + s->notify_state = NOTIFY_RELOADING; - /* Sending READY=1 while we are reloading informs us - * that the reloading is complete */ - if (s->state == SERVICE_RELOAD && s->control_pid == 0) - service_enter_running(s, SERVICE_SUCCESS); + if (s->state == SERVICE_RUNNING) + service_enter_reload_by_notify(s); - notify_dbus = true; - } + notify_dbus = true; + break; - /* Interpret STOPPING= */ - if (strv_find(tags, "STOPPING=1")) { + } else if (streq(*i, "STOPPING=1")) { + s->notify_state = NOTIFY_STOPPING; - s->notify_state = NOTIFY_STOPPING; + if (s->state == SERVICE_RUNNING) + service_enter_stop_by_notify(s); - if (s->state == SERVICE_RUNNING) - service_enter_stop_by_notify(s); - - notify_dbus = true; + notify_dbus = true; + break; + } } /* Interpret STATUS= */ diff --git a/src/systemd/sd-daemon.h b/src/systemd/sd-daemon.h index 54e82562a76..3fd0cc60e3d 100644 --- a/src/systemd/sd-daemon.h +++ b/src/systemd/sd-daemon.h @@ -175,12 +175,22 @@ int sd_is_mq(int fd, const char *path); newline separated environment-style variable assignments in a string. The following variables are known: - READY=1 Tells systemd that daemon startup is finished (only - relevant for services of Type=notify). The passed - argument is a boolean "1" or "0". Since there is - little value in signaling non-readiness the only + MAINPID=... The main PID of a daemon, in case systemd did not + fork off the process itself. Example: "MAINPID=4711" + + READY=1 Tells systemd that daemon startup or daemon reload + is finished (only relevant for services of Type=notify). + The passed argument is a boolean "1" or "0". Since there + is little value in signaling non-readiness the only value daemons should send is "READY=1". + RELOADING=1 Tell systemd that the daemon began reloading its + configuration. When the configuration has been + reloaded completely, READY=1 should be sent to inform + systemd about this. + + STOPPING=1 Tells systemd that the daemon is about to go down. + STATUS=... Passes a single-line status string back to systemd that describes the daemon state. This is free-form and can be used for various purposes: general state @@ -195,9 +205,6 @@ int sd_is_mq(int fd, const char *path); BUSERROR=... If a daemon fails, the D-Bus error-style error code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut" - MAINPID=... The main pid of a daemon, in case systemd did not - fork off the process itself. Example: "MAINPID=4711" - WATCHDOG=1 Tells systemd to update the watchdog timestamp. Services using this feature should do this in regular intervals. A watchdog framework can use the