Browse code

systemd: Move the READY=1 signalling to an earlier point

Currently, OpenVPN will first tell systemd it is ready once the
log will be appended with "Initialization Sequence Completed".
This turns out to cause some issues several places.

First, it adds challenges if --chroot is used in the configuration;
this is already fixed. Secondly, it will cause havoc on static key
p2p mode configurations where the log line above will not happen
before either sides have completed establishing a connection. And
thirdly, if a client configuration fails to establish a connection
within 90 seconds, it will also fail. For the third case this may
not be a critical issue itself, as the host just needs to get
an Internet access established first - which in some scenarios may
take much longer than those 90 seconds systemd grants after the
OpenVPN client configuration is started.

The approach this patch takes is to consider OpenVPN ready when
all the initial preparations and configurations have completed - but
before a connection to a remote side have been attempted. This
also removes the need for specially handling the --chroot scenario.

The final "Initialization Sequence Completed" message update is
kept (though slightly simplified) to indicate we're in a good
state - even though this update will not be visible if --chroot
is used (which was the situation also before this patch).

Trac: #827, #801
Signed-off-by: David Sommerseth <davids@openvpn.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
Acked-by: Christian Hesse <mail@eworm.de>
Message-Id: <20170124232344.7825-1-davids@openvpn.net>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg13945.html
Signed-off-by: David Sommerseth <davids@openvpn.net>

David Sommerseth authored on 2017/01/25 08:23:44
Showing 1 changed files
... ...
@@ -562,6 +562,15 @@ context_init_1(struct context *c)
562 562
     }
563 563
 #endif
564 564
 
565
+#ifdef ENABLE_SYSTEMD
566
+    /* We can report the PID via getpid() to systemd here as OpenVPN will not
567
+     * do any fork due to daemon() a future call.
568
+     * See possibly_become_daemon() [init.c] for more details.
569
+     */
570
+    sd_notifyf(0, "READY=1\nSTATUS=Pre-connection initialization succesfull\nMAINPID=%lu",
571
+               (unsigned long) getpid());
572
+#endif
573
+
565 574
 }
566 575
 
567 576
 void
... ...
@@ -1042,24 +1051,6 @@ do_uid_gid_chroot(struct context *c, bool no_delay)
1042 1042
         {
1043 1043
             if (no_delay)
1044 1044
             {
1045
-#ifdef ENABLE_SYSTEMD
1046
-                /* If OpenVPN is started by systemd, the OpenVPN process needs
1047
-                 * to provide a preliminary status report to systemd.  This is
1048
-                 * needed as $NOTIFY_SOCKET will not be available inside the
1049
-                 * chroot, which sd_notify()/sd_notifyf() depends on.
1050
-                 *
1051
-                 * This approach is the simplest and the most non-intrusive
1052
-                 * solution right before the 2.4_rc2 release.
1053
-                 *
1054
-                 * TODO: Consider altnernative solutions - bind mount?
1055
-                 * systemd does not grok OpenVPN configuration files, thus cannot
1056
-                 * have a sane way to know if OpenVPN will chroot or not and to
1057
-                 * which subdirectory it will chroot into.
1058
-                 */
1059
-                sd_notifyf(0, "READY=1\n"
1060
-                           "STATUS=Entering chroot, most of the init completed successfully\n"
1061
-                           "MAINPID=%lu", (unsigned long) getpid());
1062
-#endif
1063 1045
                 platform_chroot(c->options.chroot_dir);
1064 1046
             }
1065 1047
             else if (c->first_time)
... ...
@@ -1409,7 +1400,7 @@ initialization_sequence_completed(struct context *c, const unsigned int flags)
1409 1409
     else
1410 1410
     {
1411 1411
 #ifdef ENABLE_SYSTEMD
1412
-        sd_notifyf(0, "READY=1\nSTATUS=%s\nMAINPID=%lu", message, (unsigned long) getpid());
1412
+        sd_notifyf(0, "STATUS=%s", message);
1413 1413
 #endif
1414 1414
         msg(M_INFO, "%s", message);
1415 1415
     }