daemons: Do not notify systemd in child processes started by main samba
authorSamuel Cabrero <scabrero@samba.org>
Fri, 26 Feb 2021 09:36:02 +0000 (10:36 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 1 Mar 2021 03:50:35 +0000 (03:50 +0000)
When samba runs as ADDC only the main 'samba' daemon have to notify
its status to systemd because our systemd unit files contains implied
NotifyAccess=main since commit d1740fb3d5a72cb49e30b330bb0b01e7ef3e09cc.

This commit adds a function to disable the systemd notification in the
smbd and winbinddd child processes started by the main 'samba' daemon in
AD DC mode to avoid warnings like:

systemd[1]: samba-ad-dc.service: Got notification message from PID 26194,
    but reception only permitted for main PID 26187
systemd[1]: samba-ad-dc.service: Got notification message from PID 26222,
    but reception only permitted for main PID 26187

$ pstree -p
...
├─samba(26187)─┬─tfork(26189)(26188)───s3fs[master](26189)───tfork(26194)(26193)───smbd(26194)─┬─cleanupd(+
│              │                                                                               ├─lpqd(2623+
│              │                                                                               └─smbd-noti+
│              ├─tfork(26191)(26190)───rpc[master](26191)─┬─tfork(26198)(26195)───rpc(0)(26198)
│              │                                          ├─tfork(26200)(26199)───rpc(1)(26200)
│              │                                          ├─tfork(26206)(26201)───rpc(2)(26206)
│              │                                          └─tfork(26212)(26207)───rpc(3)(26212)
│              ├─tfork(26196)(26192)───nbt[master](26196)
│              ├─tfork(26202)(26197)───wrepl[master](26202)
│              ├─tfork(26204)(26203)───ldap[master](26204)─┬─tfork(26242)(26241)───ldap(0)(26242)
│              │                                           ├─tfork(26244)(26243)───ldap(1)(26244)
│              │                                           ├─tfork(26246)(26245)───ldap(2)(26246)
│              │                                           └─tfork(26248)(26247)───ldap(3)(26248)
│              ├─tfork(26208)(26205)───cldap[master](26208)
│              ├─tfork(26210)(26209)───kdc[master](26210)───tfork(26218)(26215)───krb5kdc(26218)
│              ├─tfork(26213)(26211)───drepl[master](26213)
│              ├─tfork(26216)(26214)───winbindd[master(26216)───tfork(26222)(26219)───winbindd(26222)───wi+
│              ├─tfork(26220)(26217)───ntp_signd[maste(26220)
│              ├─tfork(26223)(26221)───kcc[master](26223)
│              ├─tfork(26225)(26224)───dnsupdate[maste(26225)
│              └─tfork(26227)(26226)───dns[master](26227)

Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/util/become_daemon.c
lib/util/become_daemon.h
source3/smbd/server.c
source3/winbindd/winbindd.c

index 047c54ba49d2e5f34bbd690d29938eca3342d84a..800a57437cc31980ea784d66326898c180f308b0 100644 (file)
 
 #include "become_daemon.h"
 
+static bool sd_notifications = true;
+
+/*******************************************************************
+ Enable or disable daemon status systemd notifications
+********************************************************************/
+void daemon_sd_notifications(bool enable)
+{
+       sd_notifications = enable;
+       DBG_DEBUG("Daemon status systemd notifications %s\n",
+                 sd_notifications ? "enabled" : "disabled");
+}
+
 /*******************************************************************
  Close the low 3 fd's and open dev/null in their place.
 ********************************************************************/
@@ -76,7 +88,7 @@ void become_daemon(bool do_fork, bool no_session, bool log_stdout)
                        _exit(0);
                }
 #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
-       } else {
+       } else if (sd_notifications) {
                sd_notify(0, "STATUS=Starting process...");
 #endif
        }
@@ -113,10 +125,12 @@ void exit_daemon(const char *msg, int error)
        }
 
 #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
-       sd_notifyf(0, "STATUS=daemon failed to start: %s\n"
+       if (sd_notifications) {
+               sd_notifyf(0, "STATUS=daemon failed to start: %s\n"
                                  "ERRNO=%i",
                                  msg,
                                  error);
+       }
 #endif
        DBG_ERR("daemon failed to start: %s, error code %d\n",
                msg, error);
@@ -129,8 +143,11 @@ void daemon_ready(const char *daemon)
                daemon = "Samba";
        }
 #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
-       sd_notifyf(0, "READY=1\nSTATUS=%s: ready to serve connections...",
-                  daemon);
+       if (sd_notifications) {
+               sd_notifyf(0,
+                          "READY=1\nSTATUS=%s: ready to serve connections...",
+                          daemon);
+       }
 #endif
        DBG_ERR("daemon '%s' finished starting up and ready to serve "
                "connections\n", daemon);
@@ -142,7 +159,9 @@ void daemon_status(const char *daemon, const char *msg)
                daemon = "Samba";
        }
 #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
-       sd_notifyf(0, "STATUS=%s: %s", daemon, msg);
+       if (sd_notifications) {
+               sd_notifyf(0, "STATUS=%s: %s", daemon, msg);
+       }
 #endif
        DBG_ERR("daemon '%s' : %s\n", daemon, msg);
 }
index d697a689cdc03010ebd6184f6645fde320d39018..149d4c0175ee01ae0c0938296b8a126fb36b4885 100644 (file)
 **/
 void close_low_fds(bool stdin_too, bool stdout_too, bool stderr_too);
 
+/**
+ * @brief Enable or disable daemon status systemd notifications
+ *
+ * When samba runs as AD DC only the main 'samba' process has to
+ * notify systemd. Child processes started by the main 'samba', like
+ * smbd and winbindd should call this function to disable sd_notify()
+ * calls.
+ *
+ * @param[in] enable True to enable notifications, false to disable
+**/
+void daemon_sd_notifications(bool enable);
+
 /**
  * @brief Become a daemon, optionally discarding the controlling terminal
  *
index a0456100afe1aee3bea88b5f0f0001cddddd488c..792a04141fded8acb0c25116877cc8658ba3e284 100644 (file)
@@ -1852,11 +1852,14 @@ extern void build_options(bool screen);
                exit(1);
        }
 
-       if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
-           && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
-               DEBUG(0, ("server role = 'active directory domain controller' not compatible with running smbd standalone. \n"));
-               DEBUGADD(0, ("You should start 'samba' instead, and it will control starting smbd if required\n"));
-               exit(1);
+       if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
+               if (!lp_parm_bool(-1, "server role check", "inhibit", false)) {
+                       DBG_ERR("server role = 'active directory domain controller' not compatible with running smbd standalone. \n");
+                       DEBUGADD(0, ("You should start 'samba' instead, and it will control starting smbd if required\n"));
+                       exit(1);
+               }
+               /* Main 'samba' daemon will notify */
+               daemon_sd_notifications(false);
        }
 
        /* ...NOTE... Log files are working from this point! */
index 3049faa32373ee7119fedc0b18ad69f9d609b729..bccd1726ce132158f03acf76a49cff27858c2256 100644 (file)
@@ -1784,11 +1784,14 @@ int main(int argc, const char **argv)
         */
        dump_core_setup("winbindd", lp_logfile(talloc_tos(), lp_sub));
 
-       if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
-           && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
-               DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
-               DEBUGADD(0, ("You should start 'samba' instead, and it will control starting the internal AD DC winbindd implementation, which is not the same as this one\n"));
-               exit(1);
+       if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
+               if (!lp_parm_bool(-1, "server role check", "inhibit", false)) {
+                       DBG_ERR("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n");
+                       DEBUGADD(0, ("You should start 'samba' instead, and it will control starting the internal AD DC winbindd implementation, which is not the same as this one\n"));
+                       exit(1);
+               }
+               /* Main 'samba' daemon will notify */
+               daemon_sd_notifications(false);
        }
 
        if (!cluster_probe_ok()) {