Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
f4b81970
Unverified
Commit
f4b81970
authored
Dec 19, 2019
by
Salvatore Sanfilippo
Committed by
GitHub
Dec 19, 2019
Browse files
Merge pull request #6052 from jtru/better-systemd-integration-v2
Better systemd integration v2
parents
c5bc1c14
c7b68d10
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/Makefile
View file @
f4b81970
...
...
@@ -32,6 +32,7 @@ OPT=$(OPTIMIZATION)
PREFIX
?=
/usr/local
INSTALL_BIN
=
$(PREFIX)
/bin
INSTALL
=
install
PKG_CONFIG
?=
pkg-config
# Default allocator defaults to Jemalloc if it's not an ARM
MALLOC
=
libc
...
...
@@ -140,6 +141,30 @@ endif
# Include paths to dependencies
FINAL_CFLAGS
+=
-I
../deps/hiredis
-I
../deps/linenoise
-I
../deps/lua/src
# Determine systemd support and/or build preference (defaulting to auto-detection)
BUILD_WITH_SYSTEMD
=
no
# If 'USE_SYSTEMD' in the environment is neither "no" nor "yes", try to
# auto-detect libsystemd's presence and link accordingly.
ifneq
($(USE_SYSTEMD),no)
LIBSYSTEMD_PKGCONFIG
:=
$(
shell
$(PKG_CONFIG)
--exists
libsystemd
&&
echo
$$
?
)
# If libsystemd cannot be detected, continue building without support for it
# (unless a later check tells us otherwise)
ifeq
($(LIBSYSTEMD_PKGCONFIG),0)
BUILD_WITH_SYSTEMD
=
yes
endif
endif
ifeq
($(USE_SYSTEMD),yes)
ifneq
($(LIBSYSTEMD_PKGCONFIG),0)
$(error
USE_SYSTEMD
is
set
to
"$(USE_SYSTEMD)"
,
but
$(PKG_CONFIG)
cannot
find
libsystemd)
endif
# Force building with libsystemd
BUILD_WITH_SYSTEMD
=
yes
endif
ifeq
($(BUILD_WITH_SYSTEMD),yes)
FINAL_LIBS
+=
$(
shell
$(PKG_CONFIG)
--libs
libsystemd
)
FINAL_CFLAGS
+=
-DHAVE_LIBSYSTEMD
endif
ifeq
($(MALLOC),tcmalloc)
FINAL_CFLAGS
+=
-DUSE_TCMALLOC
FINAL_LIBS
+=
-ltcmalloc
...
...
src/replication.c
View file @
f4b81970
...
...
@@ -1665,6 +1665,11 @@ void readSyncBulkPayload(connection *conn) {
if
(
server
.
repl_backlog
==
NULL
)
createReplicationBacklog
();
serverLog
(
LL_NOTICE
,
"MASTER <-> REPLICA sync: Finished with success"
);
if
(
server
.
supervised_mode
==
SUPERVISED_SYSTEMD
)
{
redisCommunicateSystemd
(
"STATUS=MASTER <-> REPLICA sync: Finished with success. Ready to accept connections.
\n
"
);
redisCommunicateSystemd
(
"READY=1
\n
"
);
}
/* Restart the AOF subsystem now that we finished the sync. This
* will trigger an AOF rewrite, and when done will start appending
* to the new file. */
...
...
src/server.c
View file @
f4b81970
...
...
@@ -3558,6 +3558,8 @@ int prepareForShutdown(int flags) {
int
nosave
=
flags
&
SHUTDOWN_NOSAVE
;
serverLog
(
LL_WARNING
,
"User requested shutdown..."
);
if
(
server
.
supervised_mode
==
SUPERVISED_SYSTEMD
)
redisCommunicateSystemd
(
"STOPPING=1
\n
"
);
/* Kill all the Lua debugger forked sessions. */
ldbKillForkedSessions
();
...
...
@@ -3599,6 +3601,8 @@ int prepareForShutdown(int flags) {
/* Create a new RDB file before exiting. */
if
((
server
.
saveparamslen
>
0
&&
!
nosave
)
||
save
)
{
serverLog
(
LL_NOTICE
,
"Saving the final RDB snapshot before exiting."
);
if
(
server
.
supervised_mode
==
SUPERVISED_SYSTEMD
)
redisCommunicateSystemd
(
"STATUS=Saving the final RDB snapshot
\n
"
);
/* Snapshotting. Perform a SYNC SAVE and exit */
rdbSaveInfo
rsi
,
*
rsiptr
;
rsiptr
=
rdbPopulateSaveInfo
(
&
rsi
);
...
...
@@ -3609,6 +3613,8 @@ int prepareForShutdown(int flags) {
* saving aborted, handling special stuff like slaves pending for
* synchronization... */
serverLog
(
LL_WARNING
,
"Error trying to save the DB, can't exit."
);
if
(
server
.
supervised_mode
==
SUPERVISED_SYSTEMD
)
redisCommunicateSystemd
(
"STATUS=Error trying to save the DB, can't exit.
\n
"
);
return
C_ERR
;
}
}
...
...
@@ -4774,61 +4780,19 @@ int redisSupervisedUpstart(void) {
return
1
;
}
int
redis
SupervisedSystemd
(
void
)
{
int
redis
CommunicateSystemd
(
const
char
*
sd_notify_msg
)
{
const
char
*
notify_socket
=
getenv
(
"NOTIFY_SOCKET"
);
int
fd
=
1
;
struct
sockaddr_un
su
;
struct
iovec
iov
;
struct
msghdr
hdr
;
int
sendto_flags
=
0
;
if
(
!
notify_socket
)
{
serverLog
(
LL_WARNING
,
"systemd supervision requested, but NOTIFY_SOCKET not found"
);
return
0
;
}
if
((
strchr
(
"@/"
,
notify_socket
[
0
]))
==
NULL
||
strlen
(
notify_socket
)
<
2
)
{
return
0
;
}
serverLog
(
LL_NOTICE
,
"supervised by systemd, will signal readiness"
);
if
((
fd
=
socket
(
AF_UNIX
,
SOCK_DGRAM
,
0
))
==
-
1
)
{
serverLog
(
LL_WARNING
,
"Can't connect to systemd socket %s"
,
notify_socket
);
return
0
;
}
memset
(
&
su
,
0
,
sizeof
(
su
));
su
.
sun_family
=
AF_UNIX
;
strncpy
(
su
.
sun_path
,
notify_socket
,
sizeof
(
su
.
sun_path
)
-
1
);
su
.
sun_path
[
sizeof
(
su
.
sun_path
)
-
1
]
=
'\0'
;
if
(
notify_socket
[
0
]
==
'@'
)
su
.
sun_path
[
0
]
=
'\0'
;
memset
(
&
iov
,
0
,
sizeof
(
iov
));
iov
.
iov_base
=
"READY=1"
;
iov
.
iov_len
=
strlen
(
"READY=1"
);
memset
(
&
hdr
,
0
,
sizeof
(
hdr
));
hdr
.
msg_name
=
&
su
;
hdr
.
msg_namelen
=
offsetof
(
struct
sockaddr_un
,
sun_path
)
+
strlen
(
notify_socket
);
hdr
.
msg_iov
=
&
iov
;
hdr
.
msg_iovlen
=
1
;
unsetenv
(
"NOTIFY_SOCKET"
);
#ifdef HAVE_MSG_NOSIGNAL
sendto_flags
|=
MSG_NOSIGNAL
;
#endif
if
(
sendmsg
(
fd
,
&
hdr
,
sendto_flags
)
<
0
)
{
serverLog
(
LL_WARNING
,
"Can't send notification to systemd"
);
close
(
fd
);
return
0
;
}
close
(
fd
);
return
1
;
#ifdef HAVE_LIBSYSTEMD
(
void
)
sd_notify
(
0
,
sd_notify_msg
);
#else
UNUSED
(
sd_notify_msg
);
#endif
return
0
;
}
int
redisIsSupervised
(
int
mode
)
{
...
...
@@ -4839,12 +4803,17 @@ int redisIsSupervised(int mode) {
if
(
upstart_job
)
{
redisSupervisedUpstart
();
}
else
if
(
notify_socket
)
{
redisSupervisedSystemd
();
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
"
);
}
}
else
if
(
mode
==
SUPERVISED_UPSTART
)
{
return
redisSupervisedUpstart
();
}
else
if
(
mode
==
SUPERVISED_SYSTEMD
)
{
return
redisSupervisedSystemd
();
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
;
...
...
@@ -5037,6 +5006,14 @@ int main(int argc, char **argv) {
serverLog
(
LL_NOTICE
,
"Ready to accept connections"
);
if
(
server
.
sofd
>
0
)
serverLog
(
LL_NOTICE
,
"The server is now ready to accept connections at %s"
,
server
.
unixsocket
);
if
(
server
.
supervised_mode
==
SUPERVISED_SYSTEMD
)
{
if
(
!
server
.
masterhost
)
{
redisCommunicateSystemd
(
"STATUS=Ready to accept connections
\n
"
);
redisCommunicateSystemd
(
"READY=1
\n
"
);
}
else
{
redisCommunicateSystemd
(
"STATUS=Waiting for MASTER <-> REPLICA sync
\n
"
);
}
}
}
else
{
InitServerLast
();
sentinelIsRunning
();
...
...
src/server.h
View file @
f4b81970
...
...
@@ -50,6 +50,10 @@
#include <lua.h>
#include <signal.h>
#ifdef HAVE_LIBSYSTEMD
#include <systemd/sd-daemon.h>
#endif
typedef
long
long
mstime_t
;
/* millisecond time type. */
typedef
long
long
ustime_t
;
/* microsecond time type. */
...
...
@@ -1544,6 +1548,7 @@ uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l);
void
exitFromChild
(
int
retcode
);
size_t
redisPopcount
(
void
*
s
,
long
count
);
void
redisSetProcTitle
(
char
*
title
);
int
redisCommunicateSystemd
(
const
char
*
sd_notify_msg
);
/* networking.c -- Networking and Client related operations */
client
*
createClient
(
connection
*
conn
);
...
...
utils/install_server.sh
View file @
f4b81970
...
...
@@ -73,6 +73,16 @@ if [ "$(id -u)" -ne 0 ] ; then
exit
1
fi
#bail if this system is managed by systemd
_pid_1_exe
=
"
$(
readlink
-f
/proc/1/exe
)
"
if
[
"
${
_pid_1_exe
##*/
}
"
=
systemd
]
then
echo
"This systems seems to use systemd."
echo
"Please take a look at the provided example service unit files in this directory, and adapt and install them. Sorry!"
exit
1
fi
unset
_pid_1_exe
if
!
echo
$REDIS_PORT
| egrep
-q
'^[0-9]+$'
;
then
_MANUAL_EXECUTION
=
true
#Read the redis port
...
...
utils/systemd-redis_multiple_servers@.service
0 → 100644
View file @
f4b81970
# example systemd template service unit file for multiple redis-servers
#
# You can use this file as a blueprint for your actual template service unit
# file, if you intend to run multiple independent redis-server instances in
# parallel using systemd's "template unit files" feature. If you do, you will
# want to choose a better basename for your service unit by renaming this file
# when copying it.
#
# Please take a look at the provided "systemd-redis_server.service" example
# service unit file, too, if you choose to use this approach at managing
# multiple redis-server instances via systemd.
[Unit]
Description
=
Redis data structure server - instance %i
Documentation
=
https://redis.io/documentation
# This template unit assumes your redis-server configuration file(s)
# to live at /etc/redis/redis_server_<INSTANCE_NAME>.conf
AssertPathExists
=
/etc/redis/redis_server_%i.conf
#Before=your_application.service another_example_application.service
#AssertPathExists=/var/lib/redis
[Service]
ExecStart
=
/usr/local/bin/redis-server /etc/redis/redis_server_%i.conf
LimitNOFILE
=
10032
NoNewPrivileges
=
yes
#OOMScoreAdjust=-900
#PrivateTmp=yes
Type
=
notify
TimeoutStartSec
=
infinity
TimeoutStopSec
=
infinity
UMask
=
0077
#User=redis
#Group=redis
#WorkingDirectory=/var/lib/redis
[Install]
WantedBy
=
multi-user.target
utils/systemd-redis_server.service
0 → 100644
View file @
f4b81970
# example systemd service unit file for redis-server
#
# In order to use this as a template for providing a redis service in your
# environment, _at the very least_ make sure to adapt the redis configuration
# file you intend to use as needed (make sure to set "supervised systemd"), and
# to set sane TimeoutStartSec and TimeoutStopSec property values in the unit's
# "[Service]" section to fit your needs.
#
# Some properties, such as User= and Group=, are highly desirable for virtually
# all deployments of redis, but cannot be provided in a manner that fits all
# expectable environments. Some of these properties have been commented out in
# this example service unit file, but you are highly encouraged to set them to
# fit your needs.
#
# Please refer to systemd.unit(5), systemd.service(5), and systemd.exec(5) for
# more information.
[Unit]
Description
=
Redis data structure server
Documentation
=
https://redis.io/documentation
#Before=your_application.service another_example_application.service
#AssertPathExists=/var/lib/redis
[Service]
ExecStart
=
/usr/local/bin/redis-server --supervised systemd --daemonize no
## Alternatively, have redis-server load a configuration file:
#ExecStart=/usr/local/bin/redis-server /path/to/your/redis.conf
LimitNOFILE
=
10032
NoNewPrivileges
=
yes
#OOMScoreAdjust=-900
#PrivateTmp=yes
Type
=
notify
TimeoutStartSec
=
infinity
TimeoutStopSec
=
infinity
UMask
=
0077
#User=redis
#Group=redis
#WorkingDirectory=/var/lib/redis
[Install]
WantedBy
=
multi-user.target
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment