commit - e4873b4d63d0bcd4914a1cee82599a13cfd77e47
commit + 791778d7b6e2f0e92c67e6812f85445171c24572
blob - 215f5052714806693d37fec4e32aefdcd70e7df1
blob + 5ab73553cffdc5e60328b95e6de5e2a44b64de3d
--- contrib/ngircd.service
+++ contrib/ngircd.service
# Start ngIRCd. Note: systemd doesn't allow to use $DAEMON here!
ExecStart=/usr/sbin/ngircd --nodaemon --syslog $PARAMS
ExecReload=/bin/kill -HUP $MAINPID
+# Error handling:
+# ngIRCd tries to "ping" the service manager every 3 seconds.
+WatchdogSec=10
Restart=on-failure
[Install]
blob - 61f296ab5d1e6c4359a302f744f9cbae88ce8568
blob + b7838ea857e723cab0a16ee52d3f835d4ddc3e88
--- src/ngircd/conn.c
+++ src/ngircd/conn.c
int i;
size_t wdatalen;
struct timeval tv;
- time_t t;
+ time_t t, notify_t = 0;
bool command_available;
+ char status[200];
Log(LOG_NOTICE, "Server \"%s\" (on \"%s\") ready.",
Client_ID(Client_ThisServer()), Client_Hostname(Client_ThisServer()));
exit(1);
}
- /* Should ngIRCd timeout when idle? */
+ t = time(NULL);
if (Conf_IdleTimeout > 0 && NumConnectionsAccepted > 0
- && idle_t > 0 && time(NULL) - idle_t >= Conf_IdleTimeout) {
+ && idle_t > 0 && t - idle_t >= Conf_IdleTimeout) {
+ /* Should ngIRCd timeout when idle? */
LogDebug("Server idle timeout reached: %d second%s. Initiating shutdown ...",
Conf_IdleTimeout,
Conf_IdleTimeout == 1 ? "" : "s");
NGIRCd_SignalQuit = true;
+ } else if (Signal_NotifySvcMgr_Possible() && t - notify_t > 3) {
+ /* Send the current status to the service manager. */
+ snprintf(status, sizeof(status),
+ "WATCHDOG=1\nSTATUS=%ld connection%s established (%ld user%s, %ld server%s), %ld maximum. %ld accepted in total.\n",
+ NumConnections, NumConnections == 1 ? "" : "s",
+ Client_MyUserCount(), Client_MyUserCount() == 1 ? "" : "s",
+ Client_MyServerCount(), Client_MyServerCount() == 1 ? "" : "s",
+ NumConnectionsMax, NumConnectionsAccepted);
+ Signal_NotifySvcMgr(status);
+ notify_t = t;
}
}
blob - 56fd8aea2382a6d588220eb3a7ba1a241384d989
blob + 00f5ae8555708e1c616f54a5263916a14311720b
--- src/ngircd/sighandlers.c
+++ src/ngircd/sighandlers.c
}
/**
+ * Check if the service manager of the system can be notified.
+ *
+ * @returns true if notifying the service manager is theoretically possible.
+ */
+GLOBAL bool
+Signal_NotifySvcMgr_Possible(void)
+{
+#if !defined(HAVE_SYS_UN_H) || !defined(SOCK_CLOEXEC)
+ return false;
+#else
+ return getenv("NOTIFY_SOCKET") != NULL;
+#endif
+}
+
+/**
* Notify the service manager using the "sd_notify" protocol.
*
* This function is based on the example notify() function shown in the
blob - e03864a3d26bd9160f4cf5667c6282bb258c8f08
blob + a7cafd1fd9a9ac3e605f43b23b6000566d9bcccc
--- src/ngircd/sighandlers.h
+++ src/ngircd/sighandlers.h
bool Signals_Init PARAMS((void));
void Signals_Exit PARAMS((void));
+GLOBAL bool Signal_NotifySvcMgr_Possible PARAMS((void));
GLOBAL void Signal_NotifySvcMgr PARAMS((const char *message));
#endif