summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bokovoy <ab@samba.org>2014-03-25 12:53:04 +0200
committerJeremy Allison <jra@samba.org>2014-04-23 02:29:08 +0200
commitaa8c8a7b5b062b36a74a505aa48ba7dc5141aa55 (patch)
tree4225d4ca30fdd7b74b66fbd5314f3dd605e43aba
parent13784b74d84e1351e27702fd3bbfb04eeb9a40f8 (diff)
downloadsamba-aa8c8a7b5b062b36a74a505aa48ba7dc5141aa55.tar.gz
add systemd integration
Add --with-systemd / --without-systemd options to check whether libsystemd-daemon library is available and use it to report service startup status to systemd for smbd/winbindd/nmbd and AD DC. The problem it solves is correct reporting of the Samba services at the point when they are ready to serve clients, important for high availability software integration. BUG: https://bugzilla.samba.org/show_bug.cgi?id=10517 Signed-off-by: Alexander Bokovoy <ab@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
-rw-r--r--lib/util/become_daemon.c37
-rw-r--r--lib/util/samba_util.h12
-rwxr-xr-xlib/util/wscript_build2
-rw-r--r--packaging/systemd/nmb.service3
-rw-r--r--packaging/systemd/samba.service3
-rw-r--r--packaging/systemd/smb.service3
-rw-r--r--packaging/systemd/winbind.service3
-rw-r--r--source3/nmbd/nmbd.c4
-rw-r--r--source3/smbd/server.c4
-rw-r--r--source3/winbindd/winbindd.c5
-rw-r--r--source4/smbd/server.c4
-rw-r--r--wscript26
12 files changed, 97 insertions, 9 deletions
diff --git a/lib/util/become_daemon.c b/lib/util/become_daemon.c
index 2ca047861f1..35c8b3252be 100644
--- a/lib/util/become_daemon.c
+++ b/lib/util/become_daemon.c
@@ -24,6 +24,9 @@
#include "includes.h"
#include "system/filesys.h"
#include "system/locale.h"
+#if HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
/*******************************************************************
Close the low 3 fd's and open dev/null in their place.
@@ -75,8 +78,13 @@ _PUBLIC_ void close_low_fds(bool stdin_too, bool stdout_too, bool stderr_too)
_PUBLIC_ void become_daemon(bool do_fork, bool no_process_group, bool log_stdout)
{
+ pid_t newpid;
if (do_fork) {
- if (fork()) {
+ newpid = fork();
+ if (newpid) {
+#if HAVE_SYSTEMD
+ sd_notifyf(0, "READY=0\nSTATUS=Starting process...\nMAINPID=%lu", (unsigned long) newpid);
+#endif /* HAVE_SYSTEMD */
_exit(0);
}
}
@@ -100,3 +108,30 @@ _PUBLIC_ void become_daemon(bool do_fork, bool no_process_group, bool log_stdout
* never close stderr (but debug might dup it onto a log file) */
close_low_fds(do_fork, !log_stdout, false);
}
+
+_PUBLIC_ void exit_daemon(const char *msg, int error)
+{
+#ifdef HAVE_SYSTEMD
+ if (msg == NULL) {
+ msg = strerror(error);
+ }
+
+ sd_notifyf(0, "STATUS=daemon failed to start: %s\n"
+ "ERRNO=%i",
+ msg,
+ error);
+#endif
+ DEBUG(0, ("STATUS=daemon failed to start: %s, error code %d\n", msg, error));
+ exit(1);
+}
+
+_PUBLIC_ void daemon_ready(const char *daemon)
+{
+ if (daemon == NULL) {
+ daemon = "Samba";
+ }
+#ifdef HAVE_SYSTEMD
+ sd_notifyf(0, "READY=1\nSTATUS=%s: ready to serve connections...", daemon);
+#endif
+ DEBUG(0, ("STATUS=daemon '%s' finished starting up and ready to serve connections", daemon));
+}
diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h
index dcb92eed461..e3fe6a60792 100644
--- a/lib/util/samba_util.h
+++ b/lib/util/samba_util.h
@@ -842,6 +842,18 @@ _PUBLIC_ void close_low_fds(bool stdin_too, bool stdout_too, bool stderr_too);
_PUBLIC_ void become_daemon(bool do_fork, bool no_process_group, bool log_stdout);
/**
+ Exit daemon and print error message to the log at level 0
+ Optionally report failure to systemd if systemd integration is enabled
+**/
+_PUBLIC_ void exit_daemon(const char *msg, int error);
+
+/**
+ Report that the daemon is ready to serve connections to the log at level 0
+ Optionally report status to systemd if systemd integration is enabled
+**/
+_PUBLIC_ void daemon_ready(const char *daemon);
+
+/**
* @brief Get a password from the console.
*
* You should make sure that the buffer is an empty string!
diff --git a/lib/util/wscript_build b/lib/util/wscript_build
index a45dbde9a20..fe2c1833923 100755
--- a/lib/util/wscript_build
+++ b/lib/util/wscript_build
@@ -10,7 +10,7 @@ bld.SAMBA_LIBRARY('samba-util',
server_id.c dprintf.c parmlist.c bitmap.c pidfile.c
tevent_debug.c util_process.c''',
deps='DYNCONFIG',
- public_deps='talloc tevent execinfo pthread LIBCRYPTO charset util_setid',
+ public_deps='talloc tevent execinfo pthread LIBCRYPTO charset util_setid systemd-daemon',
public_headers='debug.h attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h samba_util.h string_wrappers.h',
header_path= [ ('dlinklist.h samba_util.h', '.'), ('*', 'util') ],
local_include=False,
diff --git a/packaging/systemd/nmb.service b/packaging/systemd/nmb.service
index e5e81a1fc74..3d71a7dacd2 100644
--- a/packaging/systemd/nmb.service
+++ b/packaging/systemd/nmb.service
@@ -3,7 +3,8 @@ Description=Samba NMB Daemon
After=syslog.target network.target
[Service]
-Type=forking
+Type=notify
+NotifyAccess=all
PIDFile=/run/nmbd.pid
EnvironmentFile=-/etc/sysconfig/samba
ExecStart=/usr/sbin/nmbd $NMBDOPTIONS
diff --git a/packaging/systemd/samba.service b/packaging/systemd/samba.service
index e2878d1a5e1..824f89c2030 100644
--- a/packaging/systemd/samba.service
+++ b/packaging/systemd/samba.service
@@ -3,7 +3,8 @@ Description=Samba AD Daemon
After=syslog.target network.target
[Service]
-Type=forking
+Type=notify
+NotifyAccess=all
PIDFile=/run/samba.pid
LimitNOFILE=16384
EnvironmentFile=-/etc/sysconfig/samba
diff --git a/packaging/systemd/smb.service b/packaging/systemd/smb.service
index d0d945aae79..9810891e8c2 100644
--- a/packaging/systemd/smb.service
+++ b/packaging/systemd/smb.service
@@ -3,7 +3,8 @@ Description=Samba SMB Daemon
After=syslog.target network.target nmb.service winbind.service
[Service]
-Type=forking
+Type=notify
+NotifyAccess=all
PIDFile=/run/smbd.pid
LimitNOFILE=16384
EnvironmentFile=-/etc/sysconfig/samba
diff --git a/packaging/systemd/winbind.service b/packaging/systemd/winbind.service
index eff266f0d83..f711a17f040 100644
--- a/packaging/systemd/winbind.service
+++ b/packaging/systemd/winbind.service
@@ -3,7 +3,8 @@ Description=Samba Winbind Daemon
After=syslog.target network.target nmb.service
[Service]
-Type=forking
+Type=notify
+NotifyAccess=all
PIDFile=/run/winbindd.pid
EnvironmentFile=-/etc/sysconfig/samba
ExecStart=/usr/sbin/winbindd "$WINBINDOPTIONS"
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index 80c2329b2de..c75f3b1063b 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -1097,6 +1097,10 @@ static bool open_sockets(bool isdaemon, int port)
exit(1);
}
+ if (is_daemon && !opt_interactive) {
+ daemon_ready("nmbd");
+ }
+
TALLOC_FREE(frame);
process(msg);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index bc9d293b494..5955c2956d5 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -1531,6 +1531,10 @@ extern void build_options(bool screen);
exit(1);
}
+ if (is_daemon && !interactive) {
+ daemon_ready("smbd");
+ }
+
/* only start other daemons if we are running as a daemon
* -- bad things will happen if smbd is launched via inetd
* and we fork a copy of ourselves here */
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index 8bc13431e8f..9694c6374f1 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -1589,6 +1589,11 @@ int main(int argc, const char **argv)
}
TALLOC_FREE(frame);
+
+ if (!interactive) {
+ daemon_ready("winbindd");
+ }
+
/* Loop waiting for requests */
while (1) {
frame = talloc_stackframe();
diff --git a/source4/smbd/server.c b/source4/smbd/server.c
index 26fd89a10d7..9051b485317 100644
--- a/source4/smbd/server.c
+++ b/source4/smbd/server.c
@@ -498,6 +498,10 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
return 1;
}
+ if (opt_daemon) {
+ daemon_ready("samba");
+ }
+
/* wait for events - this is where smbd sits for most of its
life */
tevent_loop_wait(event_ctx);
diff --git a/wscript b/wscript
index ae4ff50b6d1..87541da62ce 100644
--- a/wscript
+++ b/wscript
@@ -69,8 +69,15 @@ def set_options(opt):
help=("Disable RELRO builds"),
action="store_false", dest='enable_relro')
- gr = opt.option_group('developer options')
+ opt.add_option('--with-systemd',
+ help=("Enable systemd integration"),
+ action='store_true', dest='enable_systemd')
+
+ opt.add_option('--without-systemd',
+ help=("Disable systemd integration"),
+ action='store_false', dest='enable_systemd')
+ gr = opt.option_group('developer options')
opt.tool_options('python') # options for disabling pyc or pyo compilation
# enable options related to building python extensions
@@ -169,8 +176,6 @@ def configure(conf):
addmain=False,
msg='Checking configure summary'):
raise Utils.WafError('configure summary failed')
-
- conf.SAMBA_CONFIG_H('include/config.h')
if Options.options.enable_pie != False:
if Options.options.enable_pie == True:
@@ -192,6 +197,21 @@ def configure(conf):
msg="Checking compiler for full RELRO support"):
conf.env['ENABLE_RELRO'] = True
+ if Options.options.enable_systemd != False:
+ conf.check_cfg(package='libsystemd-daemon', args='--cflags --libs',
+ msg='Checking for libsystemd-daemon', uselib_store="SYSTEMD-DAEMON")
+ conf.CHECK_HEADERS('systemd/sd-daemon.h', lib='systemd-daemon')
+ conf.CHECK_LIB('systemd-daemon', shlib=True)
+
+ if conf.CONFIG_SET('HAVE_SYSTEMD_SD_DAEMON_H'):
+ conf.DEFINE('HAVE_SYSTEMD', '1')
+ conf.env['ENABLE_SYSTEMD'] = True
+ else:
+ conf.SET_TARGET_TYPE('systemd-daemon', 'EMPTY')
+ conf.undefine('HAVE_SYSTEMD')
+
+ conf.SAMBA_CONFIG_H('include/config.h')
+
def etags(ctx):
'''build TAGS file using etags'''
import Utils