X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/a30a8ae7ba55cd7912dbfb78eef1d3963215ff6c..d10a01bb6d8645f66b66e1fb3d1c52a0dd7bd8fe:/src/config.c diff --git a/src/config.c b/src/config.c index 9d28d678..793c103b 100644 --- a/src/config.c +++ b/src/config.c @@ -155,6 +155,9 @@ void loadServerConfigFromString(char *config) { loadServerConfig(argv[1],NULL); } else if (!strcasecmp(argv[0],"maxclients") && argc == 2) { server.maxclients = atoi(argv[1]); + if (server.maxclients < 1) { + err = "Invalid max clients limit"; goto loaderr; + } } else if (!strcasecmp(argv[0],"maxmemory") && argc == 2) { server.maxmemory = memtoll(argv[1],NULL); } else if (!strcasecmp(argv[0],"maxmemory-policy") && argc == 2) { @@ -202,12 +205,18 @@ void loadServerConfigFromString(char *config) { if ((server.repl_serve_stale_data = yesnotoi(argv[1])) == -1) { err = "argument must be 'yes' or 'no'"; goto loaderr; } - } else if (!strcasecmp(argv[0],"glueoutputbuf")) { - redisLog(REDIS_WARNING, "Deprecated configuration directive: \"%s\"", argv[0]); + } else if (!strcasecmp(argv[0],"slave-read-only") && argc == 2) { + if ((server.repl_slave_ro = yesnotoi(argv[1])) == -1) { + err = "argument must be 'yes' or 'no'"; goto loaderr; + } } else if (!strcasecmp(argv[0],"rdbcompression") && argc == 2) { if ((server.rdb_compression = yesnotoi(argv[1])) == -1) { err = "argument must be 'yes' or 'no'"; goto loaderr; } + } else if (!strcasecmp(argv[0],"rdbchecksum") && argc == 2) { + if ((server.rdb_checksum = yesnotoi(argv[1])) == -1) { + err = "argument must be 'yes' or 'no'"; goto loaderr; + } } else if (!strcasecmp(argv[0],"activerehashing") && argc == 2) { if ((server.activerehashing = yesnotoi(argv[1])) == -1) { err = "argument must be 'yes' or 'no'"; goto loaderr; @@ -255,6 +264,10 @@ void loadServerConfigFromString(char *config) { { server.aof_rewrite_min_size = memtoll(argv[1],NULL); } else if (!strcasecmp(argv[0],"requirepass") && argc == 2) { + if (strlen(argv[1]) > REDIS_AUTHPASS_MAX_LEN) { + err = "Password is longer than REDIS_AUTHPASS_MAX_LEN"; + goto loaderr; + } server.requirepass = zstrdup(argv[1]); } else if (!strcasecmp(argv[0],"pidfile") && argc == 2) { zfree(server.pidfile); @@ -262,10 +275,10 @@ void loadServerConfigFromString(char *config) { } else if (!strcasecmp(argv[0],"dbfilename") && argc == 2) { zfree(server.rdb_filename); server.rdb_filename = zstrdup(argv[1]); - } else if (!strcasecmp(argv[0],"hash-max-zipmap-entries") && argc == 2) { - server.hash_max_zipmap_entries = memtoll(argv[1], NULL); - } else if (!strcasecmp(argv[0],"hash-max-zipmap-value") && argc == 2) { - server.hash_max_zipmap_value = memtoll(argv[1], NULL); + } else if (!strcasecmp(argv[0],"hash-max-ziplist-entries") && argc == 2) { + server.hash_max_ziplist_entries = memtoll(argv[1], NULL); + } else if (!strcasecmp(argv[0],"hash-max-ziplist-value") && argc == 2) { + server.hash_max_ziplist_value = memtoll(argv[1], NULL); } else if (!strcasecmp(argv[0],"list-max-ziplist-entries") && argc == 2){ server.list_max_ziplist_entries = memtoll(argv[1], NULL); } else if (!strcasecmp(argv[0],"list-max-ziplist-value") && argc == 2) { @@ -336,6 +349,24 @@ void loadServerConfigFromString(char *config) { server.client_obuf_limits[class].hard_limit_bytes = hard; server.client_obuf_limits[class].soft_limit_bytes = soft; server.client_obuf_limits[class].soft_limit_seconds = soft_seconds; + } else if (!strcasecmp(argv[0],"stop-writes-on-bgsave-error") && + argc == 2) { + if ((server.stop_writes_on_bgsave_err = yesnotoi(argv[1])) == -1) { + err = "argument must be 'yes' or 'no'"; goto loaderr; + } + } else if (!strcasecmp(argv[0],"slave-priority") && argc == 2) { + server.slave_priority = atoi(argv[1]); + } else if (!strcasecmp(argv[0],"sentinel")) { + /* argc == 1 is handled by main() as we need to enter the sentinel + * mode ASAP. */ + if (argc != 1) { + if (!server.sentinel_mode) { + err = "sentinel directive while not in sentinel mode"; + goto loaderr; + } + err = sentinelHandleConfiguration(argv+1,argc-1); + if (err) goto loaderr; + } } else { err = "Bad directive or wrong number of arguments"; goto loaderr; } @@ -404,6 +435,7 @@ void configSetCommand(redisClient *c) { zfree(server.rdb_filename); server.rdb_filename = zstrdup(o->ptr); } else if (!strcasecmp(c->argv[2]->ptr,"requirepass")) { + if (sdslen(o->ptr) > REDIS_AUTHPASS_MAX_LEN) goto badfmt; zfree(server.requirepass); server.requirepass = ((char*)o->ptr)[0] ? zstrdup(o->ptr) : NULL; } else if (!strcasecmp(c->argv[2]->ptr,"masterauth")) { @@ -413,7 +445,12 @@ void configSetCommand(redisClient *c) { if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt; server.maxmemory = ll; - if (server.maxmemory) freeMemoryIfNeeded(); + if (server.maxmemory) { + if (server.maxmemory < zmalloc_used_memory()) { + redisLog(REDIS_WARNING,"WARNING: the new maxmemory value set via CONFIG SET is smaller than the current memory usage. This will result in keys eviction and/or inability to accept new write commands depending on the maxmemory-policy."); + } + freeMemoryIfNeeded(); + } } else if (!strcasecmp(c->argv[2]->ptr,"maxmemory-policy")) { if (!strcasecmp(o->ptr,"volatile-lru")) { server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_LRU; @@ -511,17 +548,22 @@ void configSetCommand(redisClient *c) { if (yn == -1) goto badfmt; server.repl_serve_stale_data = yn; + } else if (!strcasecmp(c->argv[2]->ptr,"slave-read-only")) { + int yn = yesnotoi(o->ptr); + + if (yn == -1) goto badfmt; + server.repl_slave_ro = yn; } else if (!strcasecmp(c->argv[2]->ptr,"dir")) { if (chdir((char*)o->ptr) == -1) { addReplyErrorFormat(c,"Changing directory: %s", strerror(errno)); return; } - } else if (!strcasecmp(c->argv[2]->ptr,"hash-max-zipmap-entries")) { + } else if (!strcasecmp(c->argv[2]->ptr,"hash-max-ziplist-entries")) { if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt; - server.hash_max_zipmap_entries = ll; - } else if (!strcasecmp(c->argv[2]->ptr,"hash-max-zipmap-value")) { + server.hash_max_ziplist_entries = ll; + } else if (!strcasecmp(c->argv[2]->ptr,"hash-max-ziplist-value")) { if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt; - server.hash_max_zipmap_value = ll; + server.hash_max_ziplist_value = ll; } else if (!strcasecmp(c->argv[2]->ptr,"list-max-ziplist-entries")) { if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt; server.list_max_ziplist_entries = ll; @@ -604,7 +646,37 @@ void configSetCommand(redisClient *c) { server.client_obuf_limits[class].soft_limit_seconds = soft_seconds; } sdsfreesplitres(v,vlen); + } else if (!strcasecmp(c->argv[2]->ptr,"stop-writes-on-bgsave-error")) { + int yn = yesnotoi(o->ptr); + + if (yn == -1) goto badfmt; + server.stop_writes_on_bgsave_err = yn; + } else if (!strcasecmp(c->argv[2]->ptr,"repl-ping-slave-period")) { + if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll <= 0) goto badfmt; + server.repl_ping_slave_period = ll; + } else if (!strcasecmp(c->argv[2]->ptr,"repl-timeout")) { + if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll <= 0) goto badfmt; + server.repl_timeout = ll; + } else if (!strcasecmp(c->argv[2]->ptr,"watchdog-period")) { + if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt; + if (ll) + enableWatchdog(ll); + else + disableWatchdog(); + } else if (!strcasecmp(c->argv[2]->ptr,"rdbcompression")) { + int yn = yesnotoi(o->ptr); + + if (yn == -1) goto badfmt; + server.rdb_compression = yn; + } else if (!strcasecmp(c->argv[2]->ptr,"rdbchecksum")) { + int yn = yesnotoi(o->ptr); + if (yn == -1) goto badfmt; + server.rdb_checksum = yn; + } else if (!strcasecmp(c->argv[2]->ptr,"slave-priority")) { + if (getLongLongFromObject(o,&ll) == REDIS_ERR || + ll <= 0) goto badfmt; + server.slave_priority = ll; } else { addReplyErrorFormat(c,"Unsupported CONFIG parameter: %s", (char*)c->argv[2]->ptr); @@ -619,6 +691,31 @@ badfmt: /* Bad format errors */ (char*)c->argv[2]->ptr); } +#define config_get_string_field(_name,_var) do { \ + if (stringmatch(pattern,_name,0)) { \ + addReplyBulkCString(c,_name); \ + addReplyBulkCString(c,_var ? _var : ""); \ + matches++; \ + } \ +} while(0); + +#define config_get_bool_field(_name,_var) do { \ + if (stringmatch(pattern,_name,0)) { \ + addReplyBulkCString(c,_name); \ + addReplyBulkCString(c,_var ? "yes" : "no"); \ + matches++; \ + } \ +} while(0); + +#define config_get_numerical_field(_name,_var) do { \ + if (stringmatch(pattern,_name,0)) { \ + ll2string(buf,sizeof(buf),_var); \ + addReplyBulkCString(c,_name); \ + addReplyBulkCString(c,buf); \ + matches++; \ + } \ +} while(0); + void configGetCommand(redisClient *c) { robj *o = c->argv[2]; void *replylen = addDeferredMultiBulkLength(c); @@ -627,6 +724,71 @@ void configGetCommand(redisClient *c) { int matches = 0; redisAssertWithInfo(c,o,o->encoding == REDIS_ENCODING_RAW); + /* String values */ + config_get_string_field("dbfilename",server.rdb_filename); + config_get_string_field("requirepass",server.requirepass); + config_get_string_field("masterauth",server.requirepass); + config_get_string_field("bind",server.bindaddr); + config_get_string_field("unixsocket",server.unixsocket); + config_get_string_field("logfile",server.logfile); + config_get_string_field("pidfile",server.pidfile); + + /* Numerical values */ + config_get_numerical_field("maxmemory",server.maxmemory); + config_get_numerical_field("maxmemory-samples",server.maxmemory_samples); + config_get_numerical_field("timeout",server.maxidletime); + config_get_numerical_field("auto-aof-rewrite-percentage", + server.aof_rewrite_perc); + config_get_numerical_field("auto-aof-rewrite-min-size", + server.aof_rewrite_min_size); + config_get_numerical_field("hash-max-ziplist-entries", + server.hash_max_ziplist_entries); + config_get_numerical_field("hash-max-ziplist-value", + server.hash_max_ziplist_value); + config_get_numerical_field("list-max-ziplist-entries", + server.list_max_ziplist_entries); + config_get_numerical_field("list-max-ziplist-value", + server.list_max_ziplist_value); + config_get_numerical_field("set-max-intset-entries", + server.set_max_intset_entries); + config_get_numerical_field("zset-max-ziplist-entries", + server.zset_max_ziplist_entries); + config_get_numerical_field("zset-max-ziplist-value", + server.zset_max_ziplist_value); + config_get_numerical_field("lua-time-limit",server.lua_time_limit); + config_get_numerical_field("slowlog-log-slower-than", + server.slowlog_log_slower_than); + config_get_numerical_field("slowlog-max-len", + server.slowlog_max_len); + config_get_numerical_field("port",server.port); + config_get_numerical_field("databases",server.dbnum); + config_get_numerical_field("repl-ping-slave-period",server.repl_ping_slave_period); + config_get_numerical_field("repl-timeout",server.repl_timeout); + config_get_numerical_field("maxclients",server.maxclients); + config_get_numerical_field("watchdog-period",server.watchdog_period); + config_get_numerical_field("slave-priority",server.slave_priority); + + /* Bool (yes/no) values */ + config_get_bool_field("no-appendfsync-on-rewrite", + server.aof_no_fsync_on_rewrite); + config_get_bool_field("slave-serve-stale-data", + server.repl_serve_stale_data); + config_get_bool_field("slave-read-only", + server.repl_slave_ro); + config_get_bool_field("stop-writes-on-bgsave-error", + server.stop_writes_on_bgsave_err); + config_get_bool_field("daemonize", server.daemonize); + config_get_bool_field("rdbcompression", server.rdb_compression); + config_get_bool_field("rdbchecksum", server.rdb_checksum); + config_get_bool_field("activerehashing", server.activerehashing); + + /* Everything we can't handle with macros follows. */ + + if (stringmatch(pattern,"appendonly",0)) { + addReplyBulkCString(c,"appendonly"); + addReplyBulkCString(c,server.aof_state == REDIS_AOF_OFF ? "no" : "yes"); + matches++; + } if (stringmatch(pattern,"dir",0)) { char buf[1024]; @@ -637,27 +799,6 @@ void configGetCommand(redisClient *c) { addReplyBulkCString(c,buf); matches++; } - if (stringmatch(pattern,"dbfilename",0)) { - addReplyBulkCString(c,"dbfilename"); - addReplyBulkCString(c,server.rdb_filename); - matches++; - } - if (stringmatch(pattern,"requirepass",0)) { - addReplyBulkCString(c,"requirepass"); - addReplyBulkCString(c,server.requirepass); - matches++; - } - if (stringmatch(pattern,"masterauth",0)) { - addReplyBulkCString(c,"masterauth"); - addReplyBulkCString(c,server.masterauth); - matches++; - } - if (stringmatch(pattern,"maxmemory",0)) { - ll2string(buf,sizeof(buf),server.maxmemory); - addReplyBulkCString(c,"maxmemory"); - addReplyBulkCString(c,buf); - matches++; - } if (stringmatch(pattern,"maxmemory-policy",0)) { char *s; @@ -674,28 +815,6 @@ void configGetCommand(redisClient *c) { addReplyBulkCString(c,s); matches++; } - if (stringmatch(pattern,"maxmemory-samples",0)) { - ll2string(buf,sizeof(buf),server.maxmemory_samples); - addReplyBulkCString(c,"maxmemory-samples"); - addReplyBulkCString(c,buf); - matches++; - } - if (stringmatch(pattern,"timeout",0)) { - ll2string(buf,sizeof(buf),server.maxidletime); - addReplyBulkCString(c,"timeout"); - addReplyBulkCString(c,buf); - matches++; - } - if (stringmatch(pattern,"appendonly",0)) { - addReplyBulkCString(c,"appendonly"); - addReplyBulkCString(c,server.aof_state == REDIS_AOF_OFF ? "no" : "yes"); - matches++; - } - if (stringmatch(pattern,"no-appendfsync-on-rewrite",0)) { - addReplyBulkCString(c,"no-appendfsync-on-rewrite"); - addReplyBulkCString(c,server.aof_no_fsync_on_rewrite ? "yes" : "no"); - matches++; - } if (stringmatch(pattern,"appendfsync",0)) { char *policy; @@ -725,71 +844,6 @@ void configGetCommand(redisClient *c) { sdsfree(buf); matches++; } - if (stringmatch(pattern,"auto-aof-rewrite-percentage",0)) { - addReplyBulkCString(c,"auto-aof-rewrite-percentage"); - addReplyBulkLongLong(c,server.aof_rewrite_perc); - matches++; - } - if (stringmatch(pattern,"auto-aof-rewrite-min-size",0)) { - addReplyBulkCString(c,"auto-aof-rewrite-min-size"); - addReplyBulkLongLong(c,server.aof_rewrite_min_size); - matches++; - } - if (stringmatch(pattern,"slave-serve-stale-data",0)) { - addReplyBulkCString(c,"slave-serve-stale-data"); - addReplyBulkCString(c,server.repl_serve_stale_data ? "yes" : "no"); - matches++; - } - if (stringmatch(pattern,"hash-max-zipmap-entries",0)) { - addReplyBulkCString(c,"hash-max-zipmap-entries"); - addReplyBulkLongLong(c,server.hash_max_zipmap_entries); - matches++; - } - if (stringmatch(pattern,"hash-max-zipmap-value",0)) { - addReplyBulkCString(c,"hash-max-zipmap-value"); - addReplyBulkLongLong(c,server.hash_max_zipmap_value); - matches++; - } - if (stringmatch(pattern,"list-max-ziplist-entries",0)) { - addReplyBulkCString(c,"list-max-ziplist-entries"); - addReplyBulkLongLong(c,server.list_max_ziplist_entries); - matches++; - } - if (stringmatch(pattern,"list-max-ziplist-value",0)) { - addReplyBulkCString(c,"list-max-ziplist-value"); - addReplyBulkLongLong(c,server.list_max_ziplist_value); - matches++; - } - if (stringmatch(pattern,"set-max-intset-entries",0)) { - addReplyBulkCString(c,"set-max-intset-entries"); - addReplyBulkLongLong(c,server.set_max_intset_entries); - matches++; - } - if (stringmatch(pattern,"zset-max-ziplist-entries",0)) { - addReplyBulkCString(c,"zset-max-ziplist-entries"); - addReplyBulkLongLong(c,server.zset_max_ziplist_entries); - matches++; - } - if (stringmatch(pattern,"zset-max-ziplist-value",0)) { - addReplyBulkCString(c,"zset-max-ziplist-value"); - addReplyBulkLongLong(c,server.zset_max_ziplist_value); - matches++; - } - if (stringmatch(pattern,"lua-time-limit",0)) { - addReplyBulkCString(c,"lua-time-limit"); - addReplyBulkLongLong(c,server.lua_time_limit); - matches++; - } - if (stringmatch(pattern,"slowlog-log-slower-than",0)) { - addReplyBulkCString(c,"slowlog-log-slower-than"); - addReplyBulkLongLong(c,server.slowlog_log_slower_than); - matches++; - } - if (stringmatch(pattern,"slowlog-max-len",0)) { - addReplyBulkCString(c,"slowlog-max-len"); - addReplyBulkLongLong(c,server.slowlog_max_len); - matches++; - } if (stringmatch(pattern,"loglevel",0)) { char *s; @@ -822,6 +876,25 @@ void configGetCommand(redisClient *c) { sdsfree(buf); matches++; } + if (stringmatch(pattern,"unixsocketperm",0)) { + char buf[32]; + snprintf(buf,sizeof(buf),"%o",server.unixsocketperm); + addReplyBulkCString(c,"unixsocketperm"); + addReplyBulkCString(c,buf); + matches++; + } + if (stringmatch(pattern,"slaveof",0)) { + char buf[256]; + + addReplyBulkCString(c,"slaveof"); + if (server.masterhost) + snprintf(buf,sizeof(buf),"%s %d", + server.masterhost, server.masterport); + else + buf[0] = '\0'; + addReplyBulkCString(c,buf); + matches++; + } setDeferredMultiBulkLength(c,replylen,matches*2); } @@ -839,6 +912,9 @@ void configCommand(redisClient *c) { server.stat_numcommands = 0; server.stat_numconnections = 0; server.stat_expiredkeys = 0; + server.stat_rejected_conn = 0; + server.stat_fork_time = 0; + server.aof_delayed_fsync = 0; resetCommandTableStats(); addReply(c,shared.ok); } else {