mirror of
https://github.com/osmarks/ngircd.git
synced 2024-12-11 17:30:29 +00:00
Add support for the "sd_notify" protocol
This allows the "ngircd.service" systemd(8) unit to use the "notify" service type, which allows for better status tracking by the service manager.
This commit is contained in:
parent
3e535a2955
commit
e4873b4d63
@ -193,6 +193,7 @@ AC_CHECK_HEADERS_ONCE([ \
|
|||||||
stddef.h \
|
stddef.h \
|
||||||
stdint.h \
|
stdint.h \
|
||||||
sys/resource.h \
|
sys/resource.h \
|
||||||
|
sys/un.h \
|
||||||
varargs.h \
|
varargs.h \
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ Before=anope.service atheme.service irc-services.service
|
|||||||
Before=bopm.service hopm.service
|
Before=bopm.service hopm.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=forking
|
Type=notify
|
||||||
User=irc
|
User=irc
|
||||||
Group=irc
|
Group=irc
|
||||||
# Settings & limits:
|
# Settings & limits:
|
||||||
@ -35,7 +35,7 @@ EnvironmentFile=-/etc/default/ngircd
|
|||||||
EnvironmentFile=-/etc/default/ngircd-full
|
EnvironmentFile=-/etc/default/ngircd-full
|
||||||
EnvironmentFile=-/etc/default/ngircd-full-dbg
|
EnvironmentFile=-/etc/default/ngircd-full-dbg
|
||||||
# Start ngIRCd. Note: systemd doesn't allow to use $DAEMON here!
|
# Start ngIRCd. Note: systemd doesn't allow to use $DAEMON here!
|
||||||
ExecStart=/usr/sbin/ngircd $PARAMS
|
ExecStart=/usr/sbin/ngircd --nodaemon --syslog $PARAMS
|
||||||
ExecReload=/bin/kill -HUP $MAINPID
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
#include "ng_ipaddr.h"
|
#include "ng_ipaddr.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "resolve.h"
|
#include "resolve.h"
|
||||||
|
#include "sighandlers.h"
|
||||||
|
|
||||||
#define SERVER_WAIT (NONE - 1) /** "Wait for outgoing connection" flag */
|
#define SERVER_WAIT (NONE - 1) /** "Wait for outgoing connection" flag */
|
||||||
|
|
||||||
@ -673,6 +674,7 @@ Conn_Handler(void)
|
|||||||
|
|
||||||
Log(LOG_NOTICE, "Server \"%s\" (on \"%s\") ready.",
|
Log(LOG_NOTICE, "Server \"%s\" (on \"%s\") ready.",
|
||||||
Client_ID(Client_ThisServer()), Client_Hostname(Client_ThisServer()));
|
Client_ID(Client_ThisServer()), Client_Hostname(Client_ThisServer()));
|
||||||
|
Signal_NotifySvcMgr("READY=1\n");
|
||||||
|
|
||||||
while (!NGIRCd_SignalQuit && !NGIRCd_SignalRestart) {
|
while (!NGIRCd_SignalQuit && !NGIRCd_SignalRestart) {
|
||||||
t = time(NULL);
|
t = time(NULL);
|
||||||
@ -791,10 +793,13 @@ Conn_Handler(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NGIRCd_SignalQuit)
|
if (NGIRCd_SignalQuit) {
|
||||||
Log(LOG_NOTICE | LOG_snotice, "Server going down NOW!");
|
Log(LOG_NOTICE | LOG_snotice, "Server going down NOW!");
|
||||||
else if (NGIRCd_SignalRestart)
|
Signal_NotifySvcMgr("STOPPING=1\n");
|
||||||
|
} else if (NGIRCd_SignalRestart) {
|
||||||
Log(LOG_NOTICE | LOG_snotice, "Server restarting NOW!");
|
Log(LOG_NOTICE | LOG_snotice, "Server restarting NOW!");
|
||||||
|
Signal_NotifySvcMgr("RELOADING=1\n");
|
||||||
|
}
|
||||||
} /* Conn_Handler */
|
} /* Conn_Handler */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ngIRCd -- The Next Generation IRC Daemon
|
* ngIRCd -- The Next Generation IRC Daemon
|
||||||
* Copyright (c)2001-2015 Alexander Barton (alex@barton.de) and Contributors.
|
* Copyright (c)2001-2024 Alexander Barton (alex@barton.de) and Contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -26,6 +26,11 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_UN_H
|
||||||
|
# include <sys/socket.h>
|
||||||
|
# include <sys/un.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "conn.h"
|
#include "conn.h"
|
||||||
#include "channel.h"
|
#include "channel.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
@ -100,14 +105,17 @@ Rehash(void)
|
|||||||
unsigned old_nicklen;
|
unsigned old_nicklen;
|
||||||
|
|
||||||
Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
|
Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
|
||||||
|
Signal_NotifySvcMgr("RELOADING=1\n");
|
||||||
|
|
||||||
/* Remember old server name and nickname length */
|
/* Remember old server name and nickname length */
|
||||||
strlcpy( old_name, Conf_ServerName, sizeof old_name );
|
strlcpy( old_name, Conf_ServerName, sizeof old_name );
|
||||||
old_nicklen = Conf_MaxNickLength;
|
old_nicklen = Conf_MaxNickLength;
|
||||||
|
|
||||||
/* Re-read configuration ... */
|
/* Re-read configuration ... */
|
||||||
if (!Conf_Rehash( ))
|
if (!Conf_Rehash()) {
|
||||||
|
Signal_NotifySvcMgr("READY=1\n");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Close down all listening sockets */
|
/* Close down all listening sockets */
|
||||||
Conn_ExitListeners( );
|
Conn_ExitListeners( );
|
||||||
@ -139,6 +147,7 @@ Rehash(void)
|
|||||||
Conn_SyncServerStruct( );
|
Conn_SyncServerStruct( );
|
||||||
|
|
||||||
Log( LOG_NOTICE|LOG_snotice, "Re-reading of configuration done." );
|
Log( LOG_NOTICE|LOG_snotice, "Re-reading of configuration done." );
|
||||||
|
Signal_NotifySvcMgr("READY=1\n");
|
||||||
} /* Rehash */
|
} /* Rehash */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -339,4 +348,89 @@ Signals_Exit(void)
|
|||||||
signalpipe[0] = signalpipe[1] = 0;
|
signalpipe[0] = signalpipe[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -eof- */
|
/**
|
||||||
|
* Notify the service manager using the "sd_notify" protocol.
|
||||||
|
*
|
||||||
|
* This function is based on the example notify() function shown in the
|
||||||
|
* sd_notify(3) manual page, with one significant difference: we keep the file
|
||||||
|
* descriptor open to reduce overhead when called multiple times.
|
||||||
|
*
|
||||||
|
* @param message: The message to pass to the service manager including "\n".
|
||||||
|
*/
|
||||||
|
GLOBAL void
|
||||||
|
#if !defined(HAVE_SYS_UN_H) || !defined(SOCK_CLOEXEC)
|
||||||
|
Signal_NotifySvcMgr(UNUSED const char *message)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
Signal_NotifySvcMgr(const char *message)
|
||||||
|
{
|
||||||
|
struct sockaddr_un socket_addr;
|
||||||
|
const char *socket_path;
|
||||||
|
size_t path_length, message_length;
|
||||||
|
static int fd = NONE;
|
||||||
|
|
||||||
|
assert(message != NULL);
|
||||||
|
assert(message[0] != '\0');
|
||||||
|
|
||||||
|
if (fd == NONE) {
|
||||||
|
/* No socket to the service manager open: Check if a path name
|
||||||
|
* is given in the environment and try to open it! */
|
||||||
|
socket_path = getenv("NOTIFY_SOCKET");
|
||||||
|
if (!socket_path)
|
||||||
|
return; /* No socket specified, nothing to do. */
|
||||||
|
|
||||||
|
/* Only AF_UNIX is supported, with path or abstract sockets */
|
||||||
|
if (socket_path[0] != '/' && socket_path[0] != '@') {
|
||||||
|
Log(LOG_CRIT,
|
||||||
|
"Failed to notify service manager: Unsupported socket path!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
path_length = strlen(socket_path);
|
||||||
|
|
||||||
|
/* Ensure there is room for NUL byte */
|
||||||
|
if (path_length >= sizeof(socket_addr.sun_path)) {
|
||||||
|
Log(LOG_CRIT,
|
||||||
|
"Failed to notify service manager: Socket path too long!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&socket_addr, 0, sizeof(struct sockaddr_un));
|
||||||
|
socket_addr.sun_family = AF_UNIX;
|
||||||
|
memcpy(socket_addr.sun_path, socket_path, path_length);
|
||||||
|
|
||||||
|
/* Support for abstract socket */
|
||||||
|
if (socket_addr.sun_path[0] == '@')
|
||||||
|
socket_addr.sun_path[0] = 0;
|
||||||
|
|
||||||
|
fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
Log(LOG_CRIT,
|
||||||
|
"Failed to notify service manager: %s [socket()]",
|
||||||
|
strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connect(fd, (struct sockaddr *)&socket_addr,
|
||||||
|
sizeof(struct sockaddr_un)) != 0) {
|
||||||
|
Log(LOG_CRIT,
|
||||||
|
"Failed to notify service manager: %s [connect()]",
|
||||||
|
strerror(errno));
|
||||||
|
close(fd);
|
||||||
|
fd = NONE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message_length = strlen(message);
|
||||||
|
ssize_t written = write(fd, message, message_length);
|
||||||
|
if (written != (ssize_t)message_length) {
|
||||||
|
Log(LOG_CRIT,
|
||||||
|
"Failed to notify service manager: %s [write()]",
|
||||||
|
strerror(errno));
|
||||||
|
close(fd);
|
||||||
|
fd = NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ngIRCd -- The Next Generation IRC Daemon
|
* ngIRCd -- The Next Generation IRC Daemon
|
||||||
|
* Copyright (c)2001-2024 Alexander Barton (alex@barton.de) and Contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -21,6 +22,8 @@
|
|||||||
bool Signals_Init PARAMS((void));
|
bool Signals_Init PARAMS((void));
|
||||||
void Signals_Exit PARAMS((void));
|
void Signals_Exit PARAMS((void));
|
||||||
|
|
||||||
|
GLOBAL void Signal_NotifySvcMgr PARAMS((const char *message));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* -eof- */
|
/* -eof- */
|
||||||
|
Loading…
Reference in New Issue
Block a user