]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
notify: add --stopping + --reloading switches
authorLennart Poettering <lennart@poettering.net>
Tue, 3 Jan 2023 11:55:50 +0000 (12:55 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 10 Jan 2023 17:28:38 +0000 (18:28 +0100)
These wrap RELOADING=1 and STOPPING=1 messages. The former is
particularly useful, since we want to insert the MONOTONIC_USEC= field
into the message automatically, which is easy from C but harder from
shell.

man/systemd-notify.xml
src/notify/notify.c

index 9479fbd75923e0d05ea3621914aa4f956db0e4b5..dd76cc0fb6608b1ecad51bad5256014520d08292 100644 (file)
   <refsect1>
     <title>Description</title>
 
-    <para><command>systemd-notify</command> may be called by daemon
-    scripts to notify the init system about status changes. It can be
-    used to send arbitrary information, encoded in an
-    environment-block-like list of strings. Most importantly, it can be
-    used for start-up completion notification.</para>
-
-    <para>This is mostly just a wrapper around
-    <function>sd_notify()</function> and makes this functionality
+    <para><command>systemd-notify</command> may be called by service scripts to notify the invoking service
+    manager about status changes. It can be used to send arbitrary information, encoded in an
+    environment-block-like list of strings. Most importantly, it can be used for start-up completion
+    notification.</para>
+
+    <para>This is mostly just a wrapper around <function>sd_notify()</function> and makes this functionality
     available to shell scripts. For details see
     <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
     </para>
 
-    <para>The command line may carry a list of environment variables
-    to send as part of the status update.</para>
+    <para>The command line may carry a list of environment variables to send as part of the status
+    update.</para>
 
     <para>Note that systemd will refuse reception of status updates from this command unless
     <varname>NotifyAccess=</varname> is appropriately set for the service unit this command is called
@@ -52,9 +50,9 @@
     details.</para>
 
     <para>Note that <function>sd_notify()</function> notifications may be attributed to units correctly only
-    if either the sending process is still around at the time PID 1 processes the message, or if the sending
-    process is explicitly runtime-tracked by the service manager. The latter is the case if the service
-    manager originally forked off the process, i.e. on all processes that match
+    if either the sending process is still around at the time the service manager processes the message, or
+    if the sending process is explicitly runtime-tracked by the service manager. The latter is the case if
+    the service manager originally forked off the process, i.e. on all processes that match
     <varname>NotifyAccess=</varname><option>main</option> or
     <varname>NotifyAccess=</varname><option>exec</option>. Conversely, if an auxiliary process of the unit
     sends an <function>sd_notify()</function> message and immediately exits, the service manager might not be
       <varlistentry>
         <term><option>--ready</option></term>
 
-        <listitem><para>Inform the init system about service start-up
-        completion. This is equivalent to <command>systemd-notify
-        READY=1</command>. For details about the semantics of this
-        option see
+        <listitem><para>Inform the invoking service manager about service start-up or configuration reload
+        completion. This is equivalent to <command>systemd-notify READY=1</command>. For details about the
+        semantics of this option see
+        <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--reloading</option></term>
+
+        <listitem><para>Inform the invoking service manager about the beginning of a configuration reload
+        cycle. This is equivalent to <command>systemd-notify RELOADING=1</command> (but implicitly also sets
+        a <varname>MONOTONIC_USEC=</varname> field as required for <varname>Type=notify-reload</varname>
+        services, see
+        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+        for details). For details about the semantics of this option see
+        <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--stopping</option></term>
+
+        <listitem><para>Inform the invoking service manager about the beginning of the shutdown phase of the
+        service. This is equivalent to <command>systemd-notify STOPPING=1</command>. For details about the
+        semantics of this option see
         <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><option>--pid=</option></term>
 
-        <listitem><para>Inform the service manager about the main PID of the daemon. Takes a PID as
+        <listitem><para>Inform the service manager about the main PID of the service. Takes a PID as
         argument. If the argument is specified as <literal>auto</literal> or omitted, the PID of the process
         that invoked <command>systemd-notify</command> is used, except if that's the service manager. If the
         argument is specified as <literal>self</literal>, the PID of the <command>systemd-notify</command>
         command itself is used, and if <literal>parent</literal> is specified the calling process' PID is
-        used — even if it is the service manager. This is equivalent to <command>systemd-notify
+        used — even if it is the service manager. The latter is equivalent to <command>systemd-notify
         MAINPID=$PID</command>. For details about the semantics of this option see
         <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
 
       <varlistentry>
         <term><option>--status=</option></term>
 
-        <listitem><para>Send a free-form status string for the daemon
-        to the init systemd. This option takes the status string as
-        argument. This is equivalent to <command>systemd-notify
-        STATUS=…</command>. For details about the semantics of this
-        option see
-        <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
+        <listitem><para>Send a free-form human readable status string for the daemon to the service
+        manager. This option takes the status string as argument. This is equivalent to
+        <command>systemd-notify STATUS=…</command>. For details about the semantics of this option see
+        <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>. This
+        information is shown in
+        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+        <command>status</command> output, among other places.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><option>--booted</option></term>
 
-        <listitem><para>Returns 0 if the system was booted up with
-        systemd, non-zero otherwise. If this option is passed, no
-        message is sent. This option is hence unrelated to the other
-        options. For details about the semantics of this option, see
+        <listitem><para>Returns 0 if the system was booted up with systemd, non-zero otherwise. If this
+        option is passed, no message is sent. This option is hence unrelated to the other options. For
+        details about the semantics of this option, see
         <citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>. An
         alternate way to check for this state is to call
-        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-        with the <command>is-system-running</command> command. It will
-        return <literal>offline</literal> if the system was not booted
-        with systemd.  </para></listitem>
+        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> with
+        the <command>is-system-running</command> command. It will return <literal>offline</literal> if the
+        system was not booted with systemd.  </para></listitem>
       </varlistentry>
 
       <varlistentry>
     <example>
       <title>Start-up Notification and Status Updates</title>
 
-      <para>A simple shell daemon that sends start-up notifications
-      after having set up its communication channel. During runtime it
-      sends further status updates to the init system:</para>
+      <para>A simple shell daemon that sends start-up notifications after having set up its communication
+      channel. During runtime it sends further status updates to the init system:</para>
 
       <programlisting>#!/bin/sh
 
@@ -207,5 +223,4 @@ done</programlisting>
       <citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     </para>
   </refsect1>
-
 </refentry>
index c4f54920aca29a9113f57afd267016d5cae1ec5d..b1348383f5b8196bf242be1641f4844665e5a6bf 100644 (file)
@@ -23,6 +23,8 @@
 #include "user-util.h"
 
 static bool arg_ready = false;
+static bool arg_reloading = false;
+static bool arg_stopping = false;
 static pid_t arg_pid = 0;
 static const char *arg_status = NULL;
 static bool arg_booted = false;
@@ -42,7 +44,10 @@ static int help(void) {
                "\n%sNotify the init system about service status updates.%s\n\n"
                "  -h --help            Show this help\n"
                "     --version         Show package version\n"
-               "     --ready           Inform the init system about service start-up completion\n"
+               "     --ready           Inform the service manager about service start-up/reload\n"
+               "                       completion\n"
+               "     --reloading       Inform the service manager about configuration reloading\n"
+               "     --stopping        Inform the service manager about service shutdown\n"
                "     --pid[=PID]       Set main PID of daemon\n"
                "     --uid=USER        Set user to send from\n"
                "     --status=TEXT     Set status text\n"
@@ -81,6 +86,8 @@ static int parse_argv(int argc, char *argv[]) {
 
         enum {
                 ARG_READY = 0x100,
+                ARG_RELOADING,
+                ARG_STOPPING,
                 ARG_VERSION,
                 ARG_PID,
                 ARG_STATUS,
@@ -93,6 +100,8 @@ static int parse_argv(int argc, char *argv[]) {
                 { "help",      no_argument,       NULL, 'h'           },
                 { "version",   no_argument,       NULL, ARG_VERSION   },
                 { "ready",     no_argument,       NULL, ARG_READY     },
+                { "reloading", no_argument,       NULL, ARG_RELOADING },
+                { "stopping",  no_argument,       NULL, ARG_STOPPING  },
                 { "pid",       optional_argument, NULL, ARG_PID       },
                 { "status",    required_argument, NULL, ARG_STATUS    },
                 { "booted",    no_argument,       NULL, ARG_BOOTED    },
@@ -120,6 +129,14 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_ready = true;
                         break;
 
+                case ARG_RELOADING:
+                        arg_reloading = true;
+                        break;
+
+                case ARG_STOPPING:
+                        arg_stopping = true;
+                        break;
+
                 case ARG_PID:
                         if (isempty(optarg) || streq(optarg, "auto")) {
                                 arg_pid = getppid();
@@ -176,6 +193,8 @@ static int parse_argv(int argc, char *argv[]) {
 
         if (optind >= argc &&
             !arg_ready &&
+            !arg_stopping &&
+            !arg_reloading &&
             !arg_status &&
             !arg_pid &&
             !arg_booted) {
@@ -187,10 +206,10 @@ static int parse_argv(int argc, char *argv[]) {
 }
 
 static int run(int argc, char* argv[]) {
-        _cleanup_free_ char *status = NULL, *cpid = NULL, *n = NULL;
+        _cleanup_free_ char *status = NULL, *cpid = NULL, *n = NULL, *monotonic_usec = NULL;
         _cleanup_strv_free_ char **final_env = NULL;
-        char* our_env[4];
-        unsigned i = 0;
+        char* our_env[7];
+        size_t i = 0;
         pid_t source_pid;
         int r;
 
@@ -212,9 +231,21 @@ static int run(int argc, char* argv[]) {
                 return r <= 0;
         }
 
+        if (arg_reloading) {
+                our_env[i++] = (char*) "RELOADING=1";
+
+                if (asprintf(&monotonic_usec, "MONOTONIC_USEC=" USEC_FMT, now(CLOCK_MONOTONIC)) < 0)
+                        return log_oom();
+
+                our_env[i++] = monotonic_usec;
+        }
+
         if (arg_ready)
                 our_env[i++] = (char*) "READY=1";
 
+        if (arg_stopping)
+                our_env[i++] = (char*) "STOPPING=1";
+
         if (arg_status) {
                 status = strjoin("STATUS=", arg_status);
                 if (!status)