mirror of
https://github.com/fluencelabs/redis
synced 2025-04-12 12:16:03 +00:00
Merge pull request #1630 from mattsta/fix-infinite-loop-ulimit
Fix infinite loop ulimit
This commit is contained in:
commit
72c5ebcba4
@ -600,7 +600,7 @@ void configSetCommand(redisClient *c) {
|
|||||||
} else if (!strcasecmp(c->argv[2]->ptr,"maxclients")) {
|
} else if (!strcasecmp(c->argv[2]->ptr,"maxclients")) {
|
||||||
int orig_value = server.maxclients;
|
int orig_value = server.maxclients;
|
||||||
|
|
||||||
if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
|
if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 1) goto badfmt;
|
||||||
|
|
||||||
/* Try to check if the OS is capable of supporting so many FDs. */
|
/* Try to check if the OS is capable of supporting so many FDs. */
|
||||||
server.maxclients = ll;
|
server.maxclients = ll;
|
||||||
|
52
src/redis.c
52
src/redis.c
@ -1490,21 +1490,21 @@ void initServerConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This function will try to raise the max number of open files accordingly to
|
/* This function will try to raise the max number of open files accordingly to
|
||||||
* the configured max number of clients. It will also account for 32 additional
|
* the configured max number of clients. It also reserves a number of file
|
||||||
* file descriptors as we need a few more for persistence, listening
|
* descriptors (REDIS_MIN_RESERVED_FDS) for extra operations of
|
||||||
* sockets, log files and so forth.
|
* persistence, listening sockets, log files and so forth.
|
||||||
*
|
*
|
||||||
* If it will not be possible to set the limit accordingly to the configured
|
* If it will not be possible to set the limit accordingly to the configured
|
||||||
* max number of clients, the function will do the reverse setting
|
* max number of clients, the function will do the reverse setting
|
||||||
* server.maxclients to the value that we can actually handle. */
|
* server.maxclients to the value that we can actually handle. */
|
||||||
void adjustOpenFilesLimit(void) {
|
void adjustOpenFilesLimit(void) {
|
||||||
rlim_t maxfiles = server.maxclients+32;
|
rlim_t maxfiles = server.maxclients+REDIS_MIN_RESERVED_FDS;
|
||||||
struct rlimit limit;
|
struct rlimit limit;
|
||||||
|
|
||||||
if (getrlimit(RLIMIT_NOFILE,&limit) == -1) {
|
if (getrlimit(RLIMIT_NOFILE,&limit) == -1) {
|
||||||
redisLog(REDIS_WARNING,"Unable to obtain the current NOFILE limit (%s), assuming 1024 and setting the max clients configuration accordingly.",
|
redisLog(REDIS_WARNING,"Unable to obtain the current NOFILE limit (%s), assuming 1024 and setting the max clients configuration accordingly.",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
server.maxclients = 1024-32;
|
server.maxclients = 1024-REDIS_MIN_RESERVED_FDS;
|
||||||
} else {
|
} else {
|
||||||
rlim_t oldlimit = limit.rlim_cur;
|
rlim_t oldlimit = limit.rlim_cur;
|
||||||
|
|
||||||
@ -1518,16 +1518,46 @@ void adjustOpenFilesLimit(void) {
|
|||||||
limit.rlim_cur = f;
|
limit.rlim_cur = f;
|
||||||
limit.rlim_max = f;
|
limit.rlim_max = f;
|
||||||
if (setrlimit(RLIMIT_NOFILE,&limit) != -1) break;
|
if (setrlimit(RLIMIT_NOFILE,&limit) != -1) break;
|
||||||
f -= 128;
|
f -= REDIS_MIN_RESERVED_FDS;
|
||||||
|
if (f > limit.rlim_cur) {
|
||||||
|
/* Instead of getting smaller, f just got bigger.
|
||||||
|
* That means it wrapped around its unsigned floor
|
||||||
|
* and is now closer to 2^64. We can't help anymore. */
|
||||||
|
redisLog(REDIS_WARNING,"Failed to set max file limit. "
|
||||||
|
"You requested maxclients of %d "
|
||||||
|
"but your 'ulimit -n' is set to %llu. "
|
||||||
|
"Please increase your 'ulimit -n' to at least %llu.",
|
||||||
|
server.maxclients, oldlimit, maxfiles);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (f < oldlimit) f = oldlimit;
|
if (f < oldlimit) f = oldlimit;
|
||||||
if (f != maxfiles) {
|
if (f != maxfiles) {
|
||||||
server.maxclients = f-32;
|
int old_maxclients = server.maxclients;
|
||||||
redisLog(REDIS_WARNING,"Unable to set the max number of files limit to %d (%s), setting the max clients configuration to %d.",
|
int original_errno = errno;
|
||||||
(int) maxfiles, strerror(errno), (int) server.maxclients);
|
server.maxclients = f-REDIS_MIN_RESERVED_FDS;
|
||||||
|
if (server.maxclients < 1) {
|
||||||
|
redisLog(REDIS_WARNING,"Your current 'ulimit -n' "
|
||||||
|
"of %llu is not enough for Redis to start. "
|
||||||
|
"Please increase your open file limit to at least "
|
||||||
|
"%llu. Exiting.", oldlimit, maxfiles);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
redisLog(REDIS_WARNING,"You requested maxclients of %d "
|
||||||
|
"requiring at least %llu max file descriptors.",
|
||||||
|
old_maxclients, maxfiles);
|
||||||
|
redisLog(REDIS_WARNING,"Redis can't set maximum open files "
|
||||||
|
"to %llu because of OS error: %s.",
|
||||||
|
maxfiles, strerror(original_errno));
|
||||||
|
redisLog(REDIS_WARNING,"Current maximum open files is %llu. "
|
||||||
|
"maxclients has been reduced to %d to compensate for "
|
||||||
|
"low ulimit. "
|
||||||
|
"If you need higher maxclients increase 'ulimit -n'.",
|
||||||
|
oldlimit, server.maxclients);
|
||||||
} else {
|
} else {
|
||||||
redisLog(REDIS_NOTICE,"Max number of open files set to %d",
|
redisLog(REDIS_NOTICE,"Increased maximum number of open files "
|
||||||
(int) maxfiles);
|
"to %llu (it was originally set to %llu).",
|
||||||
|
maxfiles, oldlimit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,6 +123,7 @@
|
|||||||
#define REDIS_IP_STR_LEN INET6_ADDRSTRLEN
|
#define REDIS_IP_STR_LEN INET6_ADDRSTRLEN
|
||||||
#define REDIS_PEER_ID_LEN (REDIS_IP_STR_LEN+32) /* Must be enough for ip:port */
|
#define REDIS_PEER_ID_LEN (REDIS_IP_STR_LEN+32) /* Must be enough for ip:port */
|
||||||
#define REDIS_BINDADDR_MAX 16
|
#define REDIS_BINDADDR_MAX 16
|
||||||
|
#define REDIS_MIN_RESERVED_FDS 32
|
||||||
|
|
||||||
#define ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 20 /* Loopkups per loop. */
|
#define ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 20 /* Loopkups per loop. */
|
||||||
#define ACTIVE_EXPIRE_CYCLE_FAST_DURATION 1000 /* Microseconds */
|
#define ACTIVE_EXPIRE_CYCLE_FAST_DURATION 1000 /* Microseconds */
|
||||||
@ -139,9 +140,9 @@
|
|||||||
#define REDIS_LONGSTR_SIZE 21 /* Bytes needed for long -> str */
|
#define REDIS_LONGSTR_SIZE 21 /* Bytes needed for long -> str */
|
||||||
#define REDIS_AOF_AUTOSYNC_BYTES (1024*1024*32) /* fdatasync every 32MB */
|
#define REDIS_AOF_AUTOSYNC_BYTES (1024*1024*32) /* fdatasync every 32MB */
|
||||||
/* When configuring the Redis eventloop, we setup it so that the total number
|
/* When configuring the Redis eventloop, we setup it so that the total number
|
||||||
* of file descriptors we can handle are server.maxclients + FDSET_INCR
|
* of file descriptors we can handle are server.maxclients + RESERVED_FDS + FDSET_INCR
|
||||||
* that is our safety margin. */
|
* that is our safety margin. */
|
||||||
#define REDIS_EVENTLOOP_FDSET_INCR 128
|
#define REDIS_EVENTLOOP_FDSET_INCR (REDIS_MIN_RESERVED_FDS+96)
|
||||||
|
|
||||||
/* Hash table parameters */
|
/* Hash table parameters */
|
||||||
#define REDIS_HT_MINFILL 10 /* Minimal hash table fill 10% */
|
#define REDIS_HT_MINFILL 10 /* Minimal hash table fill 10% */
|
||||||
@ -786,7 +787,7 @@ struct redisServer {
|
|||||||
list *clients_waiting_acks; /* Clients waiting in WAIT command. */
|
list *clients_waiting_acks; /* Clients waiting in WAIT command. */
|
||||||
int get_ack_from_slaves; /* If true we send REPLCONF GETACK. */
|
int get_ack_from_slaves; /* If true we send REPLCONF GETACK. */
|
||||||
/* Limits */
|
/* Limits */
|
||||||
unsigned int maxclients; /* Max number of simultaneous clients */
|
int maxclients; /* Max number of simultaneous clients */
|
||||||
unsigned long long maxmemory; /* Max number of memory bytes to use */
|
unsigned long long maxmemory; /* Max number of memory bytes to use */
|
||||||
int maxmemory_policy; /* Policy for key eviction */
|
int maxmemory_policy; /* Policy for key eviction */
|
||||||
int maxmemory_samples; /* Pricision of random sampling */
|
int maxmemory_samples; /* Pricision of random sampling */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user