1
0
mirror of https://github.com/systemd/systemd.git synced 2025-02-23 13:57:33 +03:00

sd-daemon,man: ignore missing $WATCHDOG_PID

Systemd 209 started setting $WATCHDOG_PID, and sd-daemon watch was
modified to check for this variable. This means that
sd_watchdog_enabled() stopped working with previous versions of
systemd. But sd-event is a public library and API and we must keep it
working even when a program compiled with a newer version of the
libary is used on a system running an older version of the manager.

getenv() and unsetenv() are fairly expensive calls, so optimize
sd_watchdog_enabled() by not calling them when unnecessary.

man: centralize the description of $WATCHDOG_PID and $WATCHDOG_USEC in
the sd_watchdog_enabled manpage. It is better not to repeat the same
stuff in two places.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2014-10-21 18:44:09 -04:00
parent 203af57fcd
commit a9becdd65b
3 changed files with 64 additions and 54 deletions

View File

@ -192,17 +192,12 @@
<varname>WatchdogSec=</varname> is <varname>WatchdogSec=</varname> is
enabled for it. See enabled for it. See
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. It is recommended to send for information how to enable this
this message if the functionality and
<varname>$WATCHDOG_PID</varname>
environment variable has been set to
the PID of the service process, in
every half the time interval that is
specified in the
<varname>$WATCHDOG_USEC</varname>
environment variable. See
<citerefentry><refentrytitle>sd_watchdog_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry> <citerefentry><refentrytitle>sd_watchdog_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for details.</para></listitem> for the details of how the service can
check if the the watchdog is enabled.
</para></listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>

View File

@ -69,30 +69,37 @@
which the manager will act on the service if it did which the manager will act on the service if it did
not get such a notification.</para> not get such a notification.</para>
<para>If the <varname>$WATCHDOG_USEC</varname>
environment variable is set, and the
<varname>$WATCHDOG_PID</varname> variable is unset or
set to the PID of the current process, the service
manager expects notifications from this process. The
manager will usually terminate a service when it does
not get a notification message within the specified
time after startup and after each previous message. It
is recommended that a daemon sends a keep-alive
notification message to the service manager every half
of the time returned here. Notification messages may
be sent with
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
with a message string of
<literal>WATCHDOG=1</literal>.</para>
<para>If the <parameter>unset_environment</parameter> <para>If the <parameter>unset_environment</parameter>
parameter is non-zero, parameter is non-zero,
<function>sd_watchdog_enabled()</function> will unset <function>sd_watchdog_enabled()</function> will unset
the <varname>$WATCHDOG_USEC</varname> and the <varname>$WATCHDOG_USEC</varname> and
<varname>$WATCHDOG_PID</varname> environment variables <varname>$WATCHDOG_PID</varname> environment variables
before returning (regardless of whether the function call before returning (regardless of whether the function
itself succeeded or not). Further calls to call itself succeeded or not). Those variables are no
<function>sd_watchdog_enabled()</function> will then longer inherited by child processes. Further calls to
return with zero, but the variable is no longer <function>sd_watchdog_enabled()</function> will also
inherited by child processes.</para> return with zero.</para>
<para>If the <parameter>usec</parameter> parameter is <para>If the <parameter>usec</parameter> parameter is
non-NULL, <function>sd_watchdog_enabled()</function> non-NULL, <function>sd_watchdog_enabled()</function>
will return the timeout in µs for the watchdog will write the timeout in µs for the watchdog
logic. The service manager will usually terminate a logic to it.</para>
service when it did not get a notification message
within the specified time after startup and after each
previous message. It is recommended that a daemon
sends a keep-alive notification message to the service
manager every half of the time returned
here. Notification messages may be sent with
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
with a message string of
<literal>WATCHDOG=1</literal>.</para>
<para>To enable service supervision with the watchdog <para>To enable service supervision with the watchdog
logic, use <varname>WatchdogSec=</varname> in service logic, use <varname>WatchdogSec=</varname> in service
@ -126,7 +133,6 @@
of the current process, under the assumption that in of the current process, under the assumption that in
that case, the variables were set for a different that case, the variables were set for a different
process further up the process tree.</para> process further up the process tree.</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
@ -156,6 +162,19 @@
</variablelist> </variablelist>
</refsect1> </refsect1>
<refsect1>
<title>History</title>
<para>The watchdog functionality and the
<varname>$WATCHDOG_USEC</varname> variable were
added in systemd-41.</para>
<para><function>sd_watchdog_enabled()</function>
function was added in systemd-209. Since that version
the <varname>$WATCHDOG_PID</varname> variable is also
set.</para>
</refsect1>
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para>

View File

@ -491,34 +491,15 @@ _public_ int sd_booted(void) {
} }
_public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) { _public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) {
const char *e; const char *s, *p = ""; /* p is set to dummy value to do unsetting */
uint64_t u; uint64_t u;
pid_t pid; int r = 0;
int r;
e = getenv("WATCHDOG_PID"); s = getenv("WATCHDOG_USEC");
if (!e) { if (!s)
r = 0;
goto finish;
}
r = parse_pid(e, &pid);
if (r < 0)
goto finish; goto finish;
/* Is this for us? */ r = safe_atou64(s, &u);
if (getpid() != pid) {
r = 0;
goto finish;
}
e = getenv("WATCHDOG_USEC");
if (!e) {
r = -EINVAL;
goto finish;
}
r = safe_atou64(e, &u);
if (r < 0) if (r < 0)
goto finish; goto finish;
if (u <= 0) { if (u <= 0) {
@ -526,16 +507,31 @@ _public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) {
goto finish; goto finish;
} }
p = getenv("WATCHDOG_PID");
if (p) {
pid_t pid;
r = parse_pid(p, &pid);
if (r < 0)
goto finish;
/* Is this for us? */
if (getpid() != pid) {
r = 0;
goto finish;
}
}
if (usec) if (usec)
*usec = u; *usec = u;
r = 1; r = 1;
finish: finish:
if (unset_environment) { if (unset_environment && s)
unsetenv("WATCHDOG_PID");
unsetenv("WATCHDOG_USEC"); unsetenv("WATCHDOG_USEC");
} if (unset_environment && p)
unsetenv("WATCHDOG_PID");
return r; return r;
} }