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
enabled for it. See
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. It is recommended to send
this message if the
<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
for information how to enable this
functionality and
<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>
</variablelist>

View file

@ -69,30 +69,37 @@
which the manager will act on the service if it did
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>
parameter is non-zero,
<function>sd_watchdog_enabled()</function> will unset
the <varname>$WATCHDOG_USEC</varname> and
<varname>$WATCHDOG_PID</varname> environment variables
before returning (regardless of whether the function call
itself succeeded or not). Further calls to
<function>sd_watchdog_enabled()</function> will then
return with zero, but the variable is no longer
inherited by child processes.</para>
before returning (regardless of whether the function
call itself succeeded or not). Those variables are no
longer inherited by child processes. Further calls to
<function>sd_watchdog_enabled()</function> will also
return with zero.</para>
<para>If the <parameter>usec</parameter> parameter is
non-NULL, <function>sd_watchdog_enabled()</function>
will return the timeout in µs for the watchdog
logic. The service manager will usually terminate a
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>
will write the timeout in µs for the watchdog
logic to it.</para>
<para>To enable service supervision with the watchdog
logic, use <varname>WatchdogSec=</varname> in service
@ -126,7 +133,6 @@
of the current process, under the assumption that in
that case, the variables were set for a different
process further up the process tree.</para>
</refsect1>
<refsect1>
@ -156,6 +162,19 @@
</variablelist>
</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>
<title>See Also</title>
<para>

View file

@ -491,34 +491,15 @@ _public_ int sd_booted(void) {
}
_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;
pid_t pid;
int r;
int r = 0;
e = getenv("WATCHDOG_PID");
if (!e) {
r = 0;
goto finish;
}
r = parse_pid(e, &pid);
if (r < 0)
s = getenv("WATCHDOG_USEC");
if (!s)
goto finish;
/* Is this for us? */
if (getpid() != pid) {
r = 0;
goto finish;
}
e = getenv("WATCHDOG_USEC");
if (!e) {
r = -EINVAL;
goto finish;
}
r = safe_atou64(e, &u);
r = safe_atou64(s, &u);
if (r < 0)
goto finish;
if (u <= 0) {
@ -526,16 +507,31 @@ _public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) {
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)
*usec = u;
r = 1;
finish:
if (unset_environment) {
unsetenv("WATCHDOG_PID");
if (unset_environment && s)
unsetenv("WATCHDOG_USEC");
}
if (unset_environment && p)
unsetenv("WATCHDOG_PID");
return r;
}