summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYossi Gottlieb <yossigo@gmail.com>2020-11-17 12:52:49 +0200
committerGitHub <noreply@github.com>2020-11-17 12:52:49 +0200
commitd638b058341c0cc09871848848ed0f59a2a23fc8 (patch)
tree568e80350cdae4edb100aaede3a6565b43b8678f
parentea7cf737a1ff65524994ce6731eb9320891aa946 (diff)
downloadredis-d638b058341c0cc09871848848ed0f59a2a23fc8.tar.gz
Improve and clean up supervised process support. (#8036)
* Configuration file default should now be "auto". * Expose "process_supervised" as an info field. * Log messages improvements (clarify required systemd config, report auto-detected supervision mode, etc.) * Set server.supervised properly, so it can take precedence of "daemonize" configuration. * Produce clear warning if systemd is detected/requested but executable is compiled without support for it, instead of silently ignoring. * Handle systemd notification error on startup, and turn off supervised mode if it failed.
-rw-r--r--redis.conf9
-rw-r--r--src/server.c101
2 files changed, 74 insertions, 36 deletions
diff --git a/redis.conf b/redis.conf
index d28c17b64..dcb5f6241 100644
--- a/redis.conf
+++ b/redis.conf
@@ -228,6 +228,7 @@ tcp-keepalive 300
# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
+# When Redis is supervised by upstart or systemd, this parameter has no impact.
daemonize no
# If you run Redis from upstart or systemd, Redis can interact with your
@@ -236,11 +237,17 @@ daemonize no
# supervised upstart - signal upstart by putting Redis into SIGSTOP mode
# requires "expect stop" in your upstart job config
# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
+# on startup, and updating Redis status on a regular
+# basis.
# supervised auto - detect upstart or systemd method based on
# UPSTART_JOB or NOTIFY_SOCKET environment variables
# Note: these supervision methods only signal "process is ready."
# They do not enable continuous pings back to your supervisor.
-supervised no
+#
+# The default is "no". To run under upstart/systemd, you can simply uncomment
+# the line below:
+#
+# supervised auto
# If a pid file is specified, Redis writes it where specified at startup
# and removes it at exit.
diff --git a/src/server.c b/src/server.c
index cef9f7185..1ce6b68bd 100644
--- a/src/server.c
+++ b/src/server.c
@@ -4247,11 +4247,20 @@ sds genRedisInfoString(const char *section) {
static int call_uname = 1;
static struct utsname name;
char *mode;
+ char *supervised;
if (server.cluster_enabled) mode = "cluster";
else if (server.sentinel_mode) mode = "sentinel";
else mode = "standalone";
+ if (server.supervised) {
+ if (server.supervised_mode == SUPERVISED_UPSTART) supervised = "upstart";
+ else if (server.supervised_mode == SUPERVISED_SYSTEMD) supervised = "systemd";
+ else supervised = "unknown";
+ } else {
+ supervised = "no";
+ }
+
if (sections++) info = sdscat(info,"\r\n");
if (call_uname) {
@@ -4275,6 +4284,7 @@ sds genRedisInfoString(const char *section) {
"atomicvar_api:%s\r\n"
"gcc_version:%i.%i.%i\r\n"
"process_id:%I\r\n"
+ "process_supervised:%s\r\n"
"run_id:%s\r\n"
"tcp_port:%i\r\n"
"uptime_in_seconds:%I\r\n"
@@ -4300,6 +4310,7 @@ sds genRedisInfoString(const char *section) {
0,0,0,
#endif
(int64_t) getpid(),
+ supervised,
server.runid,
server.port ? server.port : server.tls_port,
(int64_t)uptime,
@@ -5224,62 +5235,82 @@ void redisSetCpuAffinity(const char *cpulist) {
#endif
}
-/*
- * Check whether systemd or upstart have been used to start redis.
- */
+/* Send a notify message to systemd. Returns sd_notify return code which is
+ * a positive number on success. */
+int redisCommunicateSystemd(const char *sd_notify_msg) {
+#ifdef HAVE_LIBSYSTEMD
+ int ret = sd_notify(0, sd_notify_msg);
+
+ if (ret == 0)
+ serverLog(LL_WARNING, "systemd supervision error: NOTIFY_SOCKET not found!");
+ else if (ret < 0)
+ serverLog(LL_WARNING, "systemd supervision error: sd_notify: %d", ret);
+ return ret;
+#else
+ UNUSED(sd_notify_msg);
+ return 0;
+#endif
+}
-int redisSupervisedUpstart(void) {
+/* Attempt to set up upstart supervision. Returns 1 if successful. */
+static int redisSupervisedUpstart(void) {
const char *upstart_job = getenv("UPSTART_JOB");
if (!upstart_job) {
serverLog(LL_WARNING,
- "upstart supervision requested, but UPSTART_JOB not found");
+ "upstart supervision requested, but UPSTART_JOB not found!");
return 0;
}
- serverLog(LL_NOTICE, "supervised by upstart, will stop to signal readiness");
+ serverLog(LL_NOTICE, "supervised by upstart, will stop to signal readiness.");
raise(SIGSTOP);
unsetenv("UPSTART_JOB");
return 1;
}
-int redisCommunicateSystemd(const char *sd_notify_msg) {
- const char *notify_socket = getenv("NOTIFY_SOCKET");
- if (!notify_socket) {
- serverLog(LL_WARNING,
- "systemd supervision requested, but NOTIFY_SOCKET not found");
- }
-
- #ifdef HAVE_LIBSYSTEMD
- (void) sd_notify(0, sd_notify_msg);
- #else
- UNUSED(sd_notify_msg);
- #endif
+/* Attempt to set up systemd supervision. Returns 1 if successful. */
+static int redisSupervisedSystemd(void) {
+#ifndef HAVE_LIBSYSTEMD
+ serverLog(LL_WARNING,
+ "systemd supervision requested or auto-detected, but Redis is compiled without libsystemd support!");
return 0;
+#else
+ if (redisCommunicateSystemd("STATUS=Redis is loading...\n") <= 0)
+ return 0;
+ serverLog(LL_NOTICE,
+ "Supervised by systemd. Please make sure you set appropriate values for TimeoutStartSec and TimeoutStopSec in your service unit.");
+ return 1;
+#endif
}
int redisIsSupervised(int mode) {
- if (mode == SUPERVISED_AUTODETECT) {
- const char *upstart_job = getenv("UPSTART_JOB");
- const char *notify_socket = getenv("NOTIFY_SOCKET");
+ int ret = 0;
- if (upstart_job) {
- redisSupervisedUpstart();
- } else if (notify_socket) {
- server.supervised_mode = SUPERVISED_SYSTEMD;
- serverLog(LL_WARNING,
- "WARNING auto-supervised by systemd - you MUST set appropriate values for TimeoutStartSec and TimeoutStopSec in your service unit.");
- return redisCommunicateSystemd("STATUS=Redis is loading...\n");
+ if (mode == SUPERVISED_AUTODETECT) {
+ if (getenv("UPSTART_JOB")) {
+ serverLog(LL_VERBOSE, "Upstart supervision detected.");
+ mode = SUPERVISED_UPSTART;
+ } else if (getenv("NOTIFY_SOCKET")) {
+ serverLog(LL_VERBOSE, "Systemd supervision detected.");
+ mode = SUPERVISED_SYSTEMD;
}
- } else if (mode == SUPERVISED_UPSTART) {
- return redisSupervisedUpstart();
- } else if (mode == SUPERVISED_SYSTEMD) {
- serverLog(LL_WARNING,
- "WARNING supervised by systemd - you MUST set appropriate values for TimeoutStartSec and TimeoutStopSec in your service unit.");
- return redisCommunicateSystemd("STATUS=Redis is loading...\n");
}
- return 0;
+ switch (mode) {
+ case SUPERVISED_UPSTART:
+ ret = redisSupervisedUpstart();
+ break;
+ case SUPERVISED_SYSTEMD:
+ ret = redisSupervisedSystemd();
+ break;
+ default:
+ break;
+ }
+
+ if (ret)
+ server.supervised_mode = mode;
+
+ return ret;
}
int iAmMaster(void) {