mirror of
https://github.com/fluencelabs/redis
synced 2025-03-17 16:10:50 +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")) {
|
||||
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. */
|
||||
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
|
||||
* the configured max number of clients. It will also account for 32 additional
|
||||
* file descriptors as we need a few more for persistence, listening
|
||||
* sockets, log files and so forth.
|
||||
* the configured max number of clients. It also reserves a number of file
|
||||
* descriptors (REDIS_MIN_RESERVED_FDS) for extra operations of
|
||||
* persistence, listening sockets, log files and so forth.
|
||||
*
|
||||
* 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
|
||||
* server.maxclients to the value that we can actually handle. */
|
||||
void adjustOpenFilesLimit(void) {
|
||||
rlim_t maxfiles = server.maxclients+32;
|
||||
rlim_t maxfiles = server.maxclients+REDIS_MIN_RESERVED_FDS;
|
||||
struct rlimit limit;
|
||||
|
||||
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.",
|
||||
strerror(errno));
|
||||
server.maxclients = 1024-32;
|
||||
server.maxclients = 1024-REDIS_MIN_RESERVED_FDS;
|
||||
} else {
|
||||
rlim_t oldlimit = limit.rlim_cur;
|
||||
|
||||
@ -1518,16 +1518,46 @@ void adjustOpenFilesLimit(void) {
|
||||
limit.rlim_cur = f;
|
||||
limit.rlim_max = f;
|
||||
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 != maxfiles) {
|
||||
server.maxclients = f-32;
|
||||
redisLog(REDIS_WARNING,"Unable to set the max number of files limit to %d (%s), setting the max clients configuration to %d.",
|
||||
(int) maxfiles, strerror(errno), (int) server.maxclients);
|
||||
int old_maxclients = server.maxclients;
|
||||
int original_errno = errno;
|
||||
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 {
|
||||
redisLog(REDIS_NOTICE,"Max number of open files set to %d",
|
||||
(int) maxfiles);
|
||||
redisLog(REDIS_NOTICE,"Increased maximum number of open files "
|
||||
"to %llu (it was originally set to %llu).",
|
||||
maxfiles, oldlimit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,6 +123,7 @@
|
||||
#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_BINDADDR_MAX 16
|
||||
#define REDIS_MIN_RESERVED_FDS 32
|
||||
|
||||
#define ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 20 /* Loopkups per loop. */
|
||||
#define ACTIVE_EXPIRE_CYCLE_FAST_DURATION 1000 /* Microseconds */
|
||||
@ -139,9 +140,9 @@
|
||||
#define REDIS_LONGSTR_SIZE 21 /* Bytes needed for long -> str */
|
||||
#define REDIS_AOF_AUTOSYNC_BYTES (1024*1024*32) /* fdatasync every 32MB */
|
||||
/* 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. */
|
||||
#define REDIS_EVENTLOOP_FDSET_INCR 128
|
||||
#define REDIS_EVENTLOOP_FDSET_INCR (REDIS_MIN_RESERVED_FDS+96)
|
||||
|
||||
/* Hash table parameters */
|
||||
#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. */
|
||||
int get_ack_from_slaves; /* If true we send REPLCONF GETACK. */
|
||||
/* 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 */
|
||||
int maxmemory_policy; /* Policy for key eviction */
|
||||
int maxmemory_samples; /* Pricision of random sampling */
|
||||
|
Loading…
x
Reference in New Issue
Block a user