Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 744 lines (704 sloc) 31.418 kb
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
1 #include "redis.h"
2
3 /*-----------------------------------------------------------------------------
4 * Config file parsing
5 *----------------------------------------------------------------------------*/
6
7 int yesnotoi(char *s) {
8 if (!strcasecmp(s,"yes")) return 1;
9 else if (!strcasecmp(s,"no")) return 0;
10 else return -1;
11 }
12
13 void appendServerSaveParams(time_t seconds, int changes) {
14 server.saveparams = zrealloc(server.saveparams,sizeof(struct saveparam)*(server.saveparamslen+1));
15 server.saveparams[server.saveparamslen].seconds = seconds;
16 server.saveparams[server.saveparamslen].changes = changes;
17 server.saveparamslen++;
18 }
19
20 void resetServerSaveParams() {
21 zfree(server.saveparams);
22 server.saveparams = NULL;
23 server.saveparamslen = 0;
24 }
25
26 /* I agree, this is a very rudimental way to load a configuration...
27 will improve later if the config gets more complex */
28 void loadServerConfig(char *filename) {
29 FILE *fp;
30 char buf[REDIS_CONFIGLINE_MAX+1], *err = NULL;
31 int linenum = 0;
32 sds line = NULL;
33
34 if (filename[0] == '-' && filename[1] == '\0')
35 fp = stdin;
36 else {
37 if ((fp = fopen(filename,"r")) == NULL) {
38 redisLog(REDIS_WARNING, "Fatal error, can't open config file '%s'", filename);
39 exit(1);
40 }
41 }
42
43 while(fgets(buf,REDIS_CONFIGLINE_MAX+1,fp) != NULL) {
44 sds *argv;
45 int argc, j;
46
47 linenum++;
48 line = sdsnew(buf);
49 line = sdstrim(line," \t\r\n");
50
51 /* Skip comments and blank lines*/
52 if (line[0] == '#' || line[0] == '\0') {
53 sdsfree(line);
54 continue;
55 }
56
57 /* Split into arguments */
297e77c Salvatore Sanfilippo Now it is possible to use quoted strings in the redis.conf file accordin...
antirez authored
58 argv = sdssplitargs(line,&argc);
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
59 sdstolower(argv[0]);
60
61 /* Execute config directives */
62 if (!strcasecmp(argv[0],"timeout") && argc == 2) {
63 server.maxidletime = atoi(argv[1]);
64 if (server.maxidletime < 0) {
65 err = "Invalid timeout value"; goto loaderr;
66 }
67 } else if (!strcasecmp(argv[0],"port") && argc == 2) {
68 server.port = atoi(argv[1]);
df50d70 Paul Gideon Dann Allow port to be 0 in configuration, in order to allow disabling of TCP.
giddie authored
69 if (server.port < 0 || server.port > 65535) {
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
70 err = "Invalid port"; goto loaderr;
71 }
72 } else if (!strcasecmp(argv[0],"bind") && argc == 2) {
73 server.bindaddr = zstrdup(argv[1]);
5d10923 Pieter Noordhuis Rename variable sockpath to unixsocket
pietern authored
74 } else if (!strcasecmp(argv[0],"unixsocket") && argc == 2) {
75 server.unixsocket = zstrdup(argv[1]);
8523876 Nathan Florea Added a config directive for a Unix socket mask
florean authored
76 } else if (!strcasecmp(argv[0],"unixsocketperm") && argc == 2) {
bb48c5f Nathan Florea Set errno to 0 before calling strtol.
florean authored
77 errno = 0;
8523876 Nathan Florea Added a config directive for a Unix socket mask
florean authored
78 server.unixsocketperm = (mode_t)strtol(argv[1], NULL, 8);
79 if (errno || server.unixsocketperm > 0777) {
80 err = "Invalid socket file permissions"; goto loaderr;
81 }
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
82 } else if (!strcasecmp(argv[0],"save") && argc == 3) {
83 int seconds = atoi(argv[1]);
84 int changes = atoi(argv[2]);
85 if (seconds < 1 || changes < 0) {
86 err = "Invalid save parameters"; goto loaderr;
87 }
88 appendServerSaveParams(seconds,changes);
89 } else if (!strcasecmp(argv[0],"dir") && argc == 2) {
90 if (chdir(argv[1]) == -1) {
91 redisLog(REDIS_WARNING,"Can't chdir to '%s': %s",
92 argv[1], strerror(errno));
93 exit(1);
94 }
95 } else if (!strcasecmp(argv[0],"loglevel") && argc == 2) {
96 if (!strcasecmp(argv[1],"debug")) server.verbosity = REDIS_DEBUG;
97 else if (!strcasecmp(argv[1],"verbose")) server.verbosity = REDIS_VERBOSE;
98 else if (!strcasecmp(argv[1],"notice")) server.verbosity = REDIS_NOTICE;
99 else if (!strcasecmp(argv[1],"warning")) server.verbosity = REDIS_WARNING;
100 else {
101 err = "Invalid log level. Must be one of debug, notice, warning";
102 goto loaderr;
103 }
104 } else if (!strcasecmp(argv[0],"logfile") && argc == 2) {
105 FILE *logfp;
106
107 server.logfile = zstrdup(argv[1]);
108 if (!strcasecmp(server.logfile,"stdout")) {
109 zfree(server.logfile);
110 server.logfile = NULL;
111 }
112 if (server.logfile) {
113 /* Test if we are able to open the file. The server will not
114 * be able to abort just for this problem later... */
115 logfp = fopen(server.logfile,"a");
116 if (logfp == NULL) {
117 err = sdscatprintf(sdsempty(),
118 "Can't open the log file: %s", strerror(errno));
119 goto loaderr;
120 }
121 fclose(logfp);
122 }
e1a586e Jonah H. Harris syslog support
jonahharris authored
123 } else if (!strcasecmp(argv[0],"syslog-enabled") && argc == 2) {
124 if ((server.syslog_enabled = yesnotoi(argv[1])) == -1) {
125 err = "argument must be 'yes' or 'no'"; goto loaderr;
126 }
127 } else if (!strcasecmp(argv[0],"syslog-ident") && argc == 2) {
128 if (server.syslog_ident) zfree(server.syslog_ident);
129 server.syslog_ident = zstrdup(argv[1]);
130 } else if (!strcasecmp(argv[0],"syslog-facility") && argc == 2) {
131 struct {
132 const char *name;
133 const int value;
134 } validSyslogFacilities[] = {
135 {"user", LOG_USER},
136 {"local0", LOG_LOCAL0},
137 {"local1", LOG_LOCAL1},
138 {"local2", LOG_LOCAL2},
139 {"local3", LOG_LOCAL3},
140 {"local4", LOG_LOCAL4},
141 {"local5", LOG_LOCAL5},
142 {"local6", LOG_LOCAL6},
143 {"local7", LOG_LOCAL7},
144 {NULL, 0}
145 };
146 int i;
147
148 for (i = 0; validSyslogFacilities[i].name; i++) {
149 if (!strcasecmp(validSyslogFacilities[i].name, argv[1])) {
150 server.syslog_facility = validSyslogFacilities[i].value;
151 break;
152 }
153 }
154
155 if (!validSyslogFacilities[i].name) {
156 err = "Invalid log facility. Must be one of USER or between LOCAL0-LOCAL7";
157 goto loaderr;
158 }
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
159 } else if (!strcasecmp(argv[0],"databases") && argc == 2) {
160 server.dbnum = atoi(argv[1]);
161 if (server.dbnum < 1) {
162 err = "Invalid number of databases"; goto loaderr;
163 }
164 } else if (!strcasecmp(argv[0],"include") && argc == 2) {
165 loadServerConfig(argv[1]);
166 } else if (!strcasecmp(argv[0],"maxclients") && argc == 2) {
167 server.maxclients = atoi(argv[1]);
168 } else if (!strcasecmp(argv[0],"maxmemory") && argc == 2) {
169 server.maxmemory = memtoll(argv[1],NULL);
165346c Salvatore Sanfilippo implemented different algorithms for maxmemory
antirez authored
170 } else if (!strcasecmp(argv[0],"maxmemory-policy") && argc == 2) {
171 if (!strcasecmp(argv[1],"volatile-lru")) {
172 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_LRU;
173 } else if (!strcasecmp(argv[1],"volatile-random")) {
174 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_RANDOM;
175 } else if (!strcasecmp(argv[1],"volatile-ttl")) {
176 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_TTL;
177 } else if (!strcasecmp(argv[1],"allkeys-lru")) {
178 server.maxmemory_policy = REDIS_MAXMEMORY_ALLKEYS_LRU;
179 } else if (!strcasecmp(argv[1],"allkeys-random")) {
180 server.maxmemory_policy = REDIS_MAXMEMORY_ALLKEYS_RANDOM;
5402c42 Salvatore Sanfilippo added noeviction policy to redis maxmemory. ZSCORE removed from the list...
antirez authored
181 } else if (!strcasecmp(argv[1],"noeviction")) {
182 server.maxmemory_policy = REDIS_MAXMEMORY_NO_EVICTION;
165346c Salvatore Sanfilippo implemented different algorithms for maxmemory
antirez authored
183 } else {
184 err = "Invalid maxmemory policy";
185 goto loaderr;
186 }
a368792 Salvatore Sanfilippo maxmemory-samples implemented in CONFIG command and configuration file
antirez authored
187 } else if (!strcasecmp(argv[0],"maxmemory-samples") && argc == 2) {
188 server.maxmemory_samples = atoi(argv[1]);
189 if (server.maxmemory_samples <= 0) {
190 err = "maxmemory-samples must be 1 or greater";
191 goto loaderr;
192 }
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
193 } else if (!strcasecmp(argv[0],"slaveof") && argc == 3) {
194 server.masterhost = sdsnew(argv[1]);
195 server.masterport = atoi(argv[2]);
196 server.replstate = REDIS_REPL_CONNECT;
8996bf7 Salvatore Sanfilippo 7c6da73
antirez authored
197 } else if (!strcasecmp(argv[0],"repl-ping-slave-period") && argc == 2) {
198 server.repl_ping_slave_period = atoi(argv[1]);
199 if (server.repl_ping_slave_period <= 0) {
200 err = "repl-ping-slave-period must be 1 or greater";
201 goto loaderr;
202 }
203 } else if (!strcasecmp(argv[0],"repl-timeout") && argc == 2) {
204 server.repl_timeout = atoi(argv[1]);
205 if (server.repl_timeout <= 0) {
206 err = "repl-timeout must be 1 or greater";
207 goto loaderr;
208 }
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
209 } else if (!strcasecmp(argv[0],"masterauth") && argc == 2) {
210 server.masterauth = zstrdup(argv[1]);
4ebfc45 Salvatore Sanfilippo config option to select if when replication link with master a slave sho...
antirez authored
211 } else if (!strcasecmp(argv[0],"slave-serve-stale-data") && argc == 2) {
212 if ((server.repl_serve_stale_data = yesnotoi(argv[1])) == -1) {
213 err = "argument must be 'yes' or 'no'"; goto loaderr;
214 }
a510cb0 Pieter Noordhuis Remove glueoutputbuf option and broken code
pietern authored
215 } else if (!strcasecmp(argv[0],"glueoutputbuf")) {
216 redisLog(REDIS_WARNING, "Deprecated configuration directive: \"%s\"", argv[0]);
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
217 } else if (!strcasecmp(argv[0],"rdbcompression") && argc == 2) {
218 if ((server.rdbcompression = yesnotoi(argv[1])) == -1) {
219 err = "argument must be 'yes' or 'no'"; goto loaderr;
220 }
221 } else if (!strcasecmp(argv[0],"activerehashing") && argc == 2) {
222 if ((server.activerehashing = yesnotoi(argv[1])) == -1) {
223 err = "argument must be 'yes' or 'no'"; goto loaderr;
224 }
225 } else if (!strcasecmp(argv[0],"daemonize") && argc == 2) {
226 if ((server.daemonize = yesnotoi(argv[1])) == -1) {
227 err = "argument must be 'yes' or 'no'"; goto loaderr;
228 }
229 } else if (!strcasecmp(argv[0],"appendonly") && argc == 2) {
230 if ((server.appendonly = yesnotoi(argv[1])) == -1) {
231 err = "argument must be 'yes' or 'no'"; goto loaderr;
232 }
233 } else if (!strcasecmp(argv[0],"appendfilename") && argc == 2) {
234 zfree(server.appendfilename);
235 server.appendfilename = zstrdup(argv[1]);
236 } else if (!strcasecmp(argv[0],"no-appendfsync-on-rewrite")
237 && argc == 2) {
238 if ((server.no_appendfsync_on_rewrite= yesnotoi(argv[1])) == -1) {
239 err = "argument must be 'yes' or 'no'"; goto loaderr;
240 }
241 } else if (!strcasecmp(argv[0],"appendfsync") && argc == 2) {
242 if (!strcasecmp(argv[1],"no")) {
243 server.appendfsync = APPENDFSYNC_NO;
244 } else if (!strcasecmp(argv[1],"always")) {
245 server.appendfsync = APPENDFSYNC_ALWAYS;
246 } else if (!strcasecmp(argv[1],"everysec")) {
247 server.appendfsync = APPENDFSYNC_EVERYSEC;
248 } else {
249 err = "argument must be 'no', 'always' or 'everysec'";
250 goto loaderr;
251 }
b333e23 Salvatore Sanfilippo automatic AOF rewrite first implementation. Still to be tested.
antirez authored
252 } else if (!strcasecmp(argv[0],"auto-aof-rewrite-percentage") &&
253 argc == 2)
254 {
4ff34b6 Salvatore Sanfilippo AOF auto rewrite percentage option parsing fixed
antirez authored
255 server.auto_aofrewrite_perc = atoi(argv[1]);
b333e23 Salvatore Sanfilippo automatic AOF rewrite first implementation. Still to be tested.
antirez authored
256 if (server.auto_aofrewrite_perc < 0) {
257 err = "Invalid negative percentage for AOF auto rewrite";
258 goto loaderr;
259 }
260 } else if (!strcasecmp(argv[0],"auto-aof-rewrite-min-size") &&
261 argc == 2)
262 {
263 server.auto_aofrewrite_min_size = memtoll(argv[1],NULL);
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
264 } else if (!strcasecmp(argv[0],"requirepass") && argc == 2) {
265 server.requirepass = zstrdup(argv[1]);
266 } else if (!strcasecmp(argv[0],"pidfile") && argc == 2) {
267 zfree(server.pidfile);
268 server.pidfile = zstrdup(argv[1]);
269 } else if (!strcasecmp(argv[0],"dbfilename") && argc == 2) {
270 zfree(server.dbfilename);
271 server.dbfilename = zstrdup(argv[1]);
8d3e063 Salvatore Sanfilippo added support for command renaming/suppression in redis.conf
antirez authored
272 } else if (!strcasecmp(argv[0],"hash-max-zipmap-entries") && argc == 2) {
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
273 server.hash_max_zipmap_entries = memtoll(argv[1], NULL);
8d3e063 Salvatore Sanfilippo added support for command renaming/suppression in redis.conf
antirez authored
274 } else if (!strcasecmp(argv[0],"hash-max-zipmap-value") && argc == 2) {
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
275 server.hash_max_zipmap_value = memtoll(argv[1], NULL);
276 } else if (!strcasecmp(argv[0],"list-max-ziplist-entries") && argc == 2){
277 server.list_max_ziplist_entries = memtoll(argv[1], NULL);
8d3e063 Salvatore Sanfilippo added support for command renaming/suppression in redis.conf
antirez authored
278 } else if (!strcasecmp(argv[0],"list-max-ziplist-value") && argc == 2) {
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
279 server.list_max_ziplist_value = memtoll(argv[1], NULL);
8d3e063 Salvatore Sanfilippo added support for command renaming/suppression in redis.conf
antirez authored
280 } else if (!strcasecmp(argv[0],"set-max-intset-entries") && argc == 2) {
96ffb2f Pieter Noordhuis merged intset code into the split files
pietern authored
281 server.set_max_intset_entries = memtoll(argv[1], NULL);
3ea204e Pieter Noordhuis Configurable thresholds for encoded sorted sets
pietern authored
282 } else if (!strcasecmp(argv[0],"zset-max-ziplist-entries") && argc == 2) {
283 server.zset_max_ziplist_entries = memtoll(argv[1], NULL);
284 } else if (!strcasecmp(argv[0],"zset-max-ziplist-value") && argc == 2) {
285 server.zset_max_ziplist_value = memtoll(argv[1], NULL);
8d3e063 Salvatore Sanfilippo added support for command renaming/suppression in redis.conf
antirez authored
286 } else if (!strcasecmp(argv[0],"rename-command") && argc == 3) {
287 struct redisCommand *cmd = lookupCommand(argv[1]);
288 int retval;
289
290 if (!cmd) {
291 err = "No such command in rename-command";
292 goto loaderr;
293 }
294
295 /* If the target command name is the emtpy string we just
296 * remove it from the command table. */
297 retval = dictDelete(server.commands, argv[1]);
298 redisAssert(retval == DICT_OK);
299
300 /* Otherwise we re-add the command under a different name. */
301 if (sdslen(argv[2]) != 0) {
302 sds copy = sdsdup(argv[2]);
303
304 retval = dictAdd(server.commands, copy, cmd);
305 if (retval != DICT_OK) {
306 sdsfree(copy);
307 err = "Target command name already exists"; goto loaderr;
308 }
309 }
ecc9109 Salvatore Sanfilippo Cluster branch merged to unstable.
antirez authored
310 } else if (!strcasecmp(argv[0],"cluster-enabled") && argc == 2) {
311 if ((server.cluster_enabled = yesnotoi(argv[1])) == -1) {
312 err = "argument must be 'yes' or 'no'"; goto loaderr;
313 }
1793752 Salvatore Sanfilippo node cluster configuration file configurable via redis.conf
antirez authored
314 } else if (!strcasecmp(argv[0],"cluster-config-file") && argc == 2) {
315 zfree(server.cluster.configfile);
316 server.cluster.configfile = zstrdup(argv[1]);
eeffcf3 Salvatore Sanfilippo Lua scripts max execution time
antirez authored
317 } else if (!strcasecmp(argv[0],"lua-time-limit") && argc == 2) {
318 server.lua_time_limit = strtoll(argv[1],NULL,10);
35a6044 Salvatore Sanfilippo slow log configuration implemented
antirez authored
319 } else if (!strcasecmp(argv[0],"slowlog-log-slower-than") &&
320 argc == 2)
321 {
322 server.slowlog_log_slower_than = strtoll(argv[1],NULL,10);
323 } else if (!strcasecmp(argv[0],"slowlog-max-len") && argc == 2) {
324 server.slowlog_max_len = strtoll(argv[1],NULL,10);
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
325 } else {
326 err = "Bad directive or wrong number of arguments"; goto loaderr;
327 }
328 for (j = 0; j < argc; j++)
329 sdsfree(argv[j]);
330 zfree(argv);
331 sdsfree(line);
332 }
333 if (fp != stdin) fclose(fp);
334 return;
335
336 loaderr:
337 fprintf(stderr, "\n*** FATAL CONFIG FILE ERROR ***\n");
338 fprintf(stderr, "Reading the configuration file, at line %d\n", linenum);
339 fprintf(stderr, ">>> '%s'\n", line);
340 fprintf(stderr, "%s\n", err);
341 exit(1);
342 }
343
344 /*-----------------------------------------------------------------------------
345 * CONFIG command for remote configuration
346 *----------------------------------------------------------------------------*/
347
348 void configSetCommand(redisClient *c) {
a375b07 Pieter Noordhuis Skip object encoding where it doesn't make sense
pietern authored
349 robj *o;
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
350 long long ll;
eab0e26 Salvatore Sanfilippo replaced redisAssert() with redisAssertWithInfo() in a shitload of place...
antirez authored
351 redisAssertWithInfo(c,c->argv[2],c->argv[2]->encoding == REDIS_ENCODING_RAW);
352 redisAssertWithInfo(c,c->argv[2],c->argv[3]->encoding == REDIS_ENCODING_RAW);
a375b07 Pieter Noordhuis Skip object encoding where it doesn't make sense
pietern authored
353 o = c->argv[3];
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
354
355 if (!strcasecmp(c->argv[2]->ptr,"dbfilename")) {
356 zfree(server.dbfilename);
357 server.dbfilename = zstrdup(o->ptr);
358 } else if (!strcasecmp(c->argv[2]->ptr,"requirepass")) {
359 zfree(server.requirepass);
1eceb85 Salvatore Sanfilippo It is now possible to disable password authentication via CONFIG SET. Th...
antirez authored
360 server.requirepass = ((char*)o->ptr)[0] ? zstrdup(o->ptr) : NULL;
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
361 } else if (!strcasecmp(c->argv[2]->ptr,"masterauth")) {
362 zfree(server.masterauth);
363 server.masterauth = zstrdup(o->ptr);
364 } else if (!strcasecmp(c->argv[2]->ptr,"maxmemory")) {
365 if (getLongLongFromObject(o,&ll) == REDIS_ERR ||
366 ll < 0) goto badfmt;
367 server.maxmemory = ll;
b4f2e41 Salvatore Sanfilippo free memory if the maxmemory parameter is reduced via CONFIG SET
antirez authored
368 if (server.maxmemory) freeMemoryIfNeeded();
165346c Salvatore Sanfilippo implemented different algorithms for maxmemory
antirez authored
369 } else if (!strcasecmp(c->argv[2]->ptr,"maxmemory-policy")) {
370 if (!strcasecmp(o->ptr,"volatile-lru")) {
371 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_LRU;
372 } else if (!strcasecmp(o->ptr,"volatile-random")) {
373 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_RANDOM;
374 } else if (!strcasecmp(o->ptr,"volatile-ttl")) {
375 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_TTL;
376 } else if (!strcasecmp(o->ptr,"allkeys-lru")) {
377 server.maxmemory_policy = REDIS_MAXMEMORY_ALLKEYS_LRU;
378 } else if (!strcasecmp(o->ptr,"allkeys-random")) {
379 server.maxmemory_policy = REDIS_MAXMEMORY_ALLKEYS_RANDOM;
5402c42 Salvatore Sanfilippo added noeviction policy to redis maxmemory. ZSCORE removed from the list...
antirez authored
380 } else if (!strcasecmp(o->ptr,"noeviction")) {
381 server.maxmemory_policy = REDIS_MAXMEMORY_NO_EVICTION;
165346c Salvatore Sanfilippo implemented different algorithms for maxmemory
antirez authored
382 } else {
383 goto badfmt;
384 }
a368792 Salvatore Sanfilippo maxmemory-samples implemented in CONFIG command and configuration file
antirez authored
385 } else if (!strcasecmp(c->argv[2]->ptr,"maxmemory-samples")) {
386 if (getLongLongFromObject(o,&ll) == REDIS_ERR ||
387 ll <= 0) goto badfmt;
388 server.maxmemory_samples = ll;
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
389 } else if (!strcasecmp(c->argv[2]->ptr,"timeout")) {
390 if (getLongLongFromObject(o,&ll) == REDIS_ERR ||
391 ll < 0 || ll > LONG_MAX) goto badfmt;
392 server.maxidletime = ll;
393 } else if (!strcasecmp(c->argv[2]->ptr,"appendfsync")) {
394 if (!strcasecmp(o->ptr,"no")) {
395 server.appendfsync = APPENDFSYNC_NO;
396 } else if (!strcasecmp(o->ptr,"everysec")) {
397 server.appendfsync = APPENDFSYNC_EVERYSEC;
398 } else if (!strcasecmp(o->ptr,"always")) {
399 server.appendfsync = APPENDFSYNC_ALWAYS;
400 } else {
401 goto badfmt;
402 }
403 } else if (!strcasecmp(c->argv[2]->ptr,"no-appendfsync-on-rewrite")) {
404 int yn = yesnotoi(o->ptr);
405
406 if (yn == -1) goto badfmt;
407 server.no_appendfsync_on_rewrite = yn;
408 } else if (!strcasecmp(c->argv[2]->ptr,"appendonly")) {
409 int old = server.appendonly;
410 int new = yesnotoi(o->ptr);
411
412 if (new == -1) goto badfmt;
413 if (old != new) {
414 if (new == 0) {
415 stopAppendOnly();
416 } else {
417 if (startAppendOnly() == REDIS_ERR) {
3ab2037 Pieter Noordhuis Use specialized function to add status and error replies
pietern authored
418 addReplyError(c,
419 "Unable to turn on AOF. Check server logs.");
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
420 return;
421 }
422 }
423 }
0ec9322 Salvatore Sanfilippo CONFIG SET/GET support for new automatic AOF rewrite parameters
antirez authored
424 } else if (!strcasecmp(c->argv[2]->ptr,"auto-aof-rewrite-percentage")) {
425 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
426 server.auto_aofrewrite_perc = ll;
427 } else if (!strcasecmp(c->argv[2]->ptr,"auto-aof-rewrite-min-size")) {
428 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
429 server.auto_aofrewrite_min_size = ll;
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
430 } else if (!strcasecmp(c->argv[2]->ptr,"save")) {
431 int vlen, j;
432 sds *v = sdssplitlen(o->ptr,sdslen(o->ptr)," ",1,&vlen);
433
434 /* Perform sanity check before setting the new config:
435 * - Even number of args
436 * - Seconds >= 1, changes >= 0 */
437 if (vlen & 1) {
438 sdsfreesplitres(v,vlen);
439 goto badfmt;
440 }
441 for (j = 0; j < vlen; j++) {
442 char *eptr;
443 long val;
444
445 val = strtoll(v[j], &eptr, 10);
446 if (eptr[0] != '\0' ||
447 ((j & 1) == 0 && val < 1) ||
448 ((j & 1) == 1 && val < 0)) {
449 sdsfreesplitres(v,vlen);
450 goto badfmt;
451 }
452 }
453 /* Finally set the new config */
454 resetServerSaveParams();
455 for (j = 0; j < vlen; j += 2) {
456 time_t seconds;
457 int changes;
458
459 seconds = strtoll(v[j],NULL,10);
460 changes = strtoll(v[j+1],NULL,10);
461 appendServerSaveParams(seconds, changes);
462 }
463 sdsfreesplitres(v,vlen);
4ebfc45 Salvatore Sanfilippo config option to select if when replication link with master a slave sho...
antirez authored
464 } else if (!strcasecmp(c->argv[2]->ptr,"slave-serve-stale-data")) {
465 int yn = yesnotoi(o->ptr);
466
467 if (yn == -1) goto badfmt;
468 server.repl_serve_stale_data = yn;
21cda08 Salvatore Sanfilippo CONFIG GET/SET dir implemented
antirez authored
469 } else if (!strcasecmp(c->argv[2]->ptr,"dir")) {
470 if (chdir((char*)o->ptr) == -1) {
471 addReplyErrorFormat(c,"Changing directory: %s", strerror(errno));
472 return;
473 }
465b418 Salvatore Sanfilippo CONFIG SET/GET for all the special encoding parameters of sets, lists, h...
antirez authored
474 } else if (!strcasecmp(c->argv[2]->ptr,"hash-max-zipmap-entries")) {
475 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
476 server.hash_max_zipmap_entries = ll;
477 } else if (!strcasecmp(c->argv[2]->ptr,"hash-max-zipmap-value")) {
478 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
479 server.hash_max_zipmap_value = ll;
480 } else if (!strcasecmp(c->argv[2]->ptr,"list-max-ziplist-entries")) {
481 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
482 server.list_max_ziplist_entries = ll;
483 } else if (!strcasecmp(c->argv[2]->ptr,"list-max-ziplist-value")) {
484 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
485 server.list_max_ziplist_value = ll;
486 } else if (!strcasecmp(c->argv[2]->ptr,"set-max-intset-entries")) {
487 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
488 server.set_max_intset_entries = ll;
3ea204e Pieter Noordhuis Configurable thresholds for encoded sorted sets
pietern authored
489 } else if (!strcasecmp(c->argv[2]->ptr,"zset-max-ziplist-entries")) {
490 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
491 server.zset_max_ziplist_entries = ll;
492 } else if (!strcasecmp(c->argv[2]->ptr,"zset-max-ziplist-value")) {
493 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
494 server.zset_max_ziplist_value = ll;
eeffcf3 Salvatore Sanfilippo Lua scripts max execution time
antirez authored
495 } else if (!strcasecmp(c->argv[2]->ptr,"lua-time-limit")) {
496 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
497 server.lua_time_limit = ll;
35a6044 Salvatore Sanfilippo slow log configuration implemented
antirez authored
498 } else if (!strcasecmp(c->argv[2]->ptr,"slowlog-log-slower-than")) {
499 if (getLongLongFromObject(o,&ll) == REDIS_ERR) goto badfmt;
500 server.slowlog_log_slower_than = ll;
501 } else if (!strcasecmp(c->argv[2]->ptr,"slowlog-max-len")) {
502 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
503 server.slowlog_max_len = (unsigned)ll;
2aa26d2 Salvatore Sanfilippo CONFIG SET/GET support for loglevel
antirez authored
504 } else if (!strcasecmp(c->argv[2]->ptr,"loglevel")) {
505 if (!strcasecmp(o->ptr,"warning")) {
506 server.verbosity = REDIS_WARNING;
507 } else if (!strcasecmp(o->ptr,"notice")) {
508 server.verbosity = REDIS_NOTICE;
509 } else if (!strcasecmp(o->ptr,"verbose")) {
510 server.verbosity = REDIS_VERBOSE;
511 } else if (!strcasecmp(o->ptr,"debug")) {
512 server.verbosity = REDIS_DEBUG;
513 } else {
514 goto badfmt;
515 }
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
516 } else {
3ab2037 Pieter Noordhuis Use specialized function to add status and error replies
pietern authored
517 addReplyErrorFormat(c,"Unsupported CONFIG parameter: %s",
518 (char*)c->argv[2]->ptr);
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
519 return;
520 }
521 addReply(c,shared.ok);
522 return;
523
524 badfmt: /* Bad format errors */
3ab2037 Pieter Noordhuis Use specialized function to add status and error replies
pietern authored
525 addReplyErrorFormat(c,"Invalid argument '%s' for CONFIG SET '%s'",
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
526 (char*)o->ptr,
3ab2037 Pieter Noordhuis Use specialized function to add status and error replies
pietern authored
527 (char*)c->argv[2]->ptr);
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
528 }
529
530 void configGetCommand(redisClient *c) {
a375b07 Pieter Noordhuis Skip object encoding where it doesn't make sense
pietern authored
531 robj *o = c->argv[2];
b301c1f Pieter Noordhuis Wrapper for adding unknown multi bulk length to reply list
pietern authored
532 void *replylen = addDeferredMultiBulkLength(c);
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
533 char *pattern = o->ptr;
a368792 Salvatore Sanfilippo maxmemory-samples implemented in CONFIG command and configuration file
antirez authored
534 char buf[128];
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
535 int matches = 0;
eab0e26 Salvatore Sanfilippo replaced redisAssert() with redisAssertWithInfo() in a shitload of place...
antirez authored
536 redisAssertWithInfo(c,o,o->encoding == REDIS_ENCODING_RAW);
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
537
21cda08 Salvatore Sanfilippo CONFIG GET/SET dir implemented
antirez authored
538 if (stringmatch(pattern,"dir",0)) {
539 char buf[1024];
540
bb831c3 Pieter Noordhuis Fix adding bulk reply when getcwd fails
pietern authored
541 if (getcwd(buf,sizeof(buf)) == NULL)
09d2abd Salvatore Sanfilippo check return value of getcwd()
antirez authored
542 buf[0] = '\0';
bb831c3 Pieter Noordhuis Fix adding bulk reply when getcwd fails
pietern authored
543
544 addReplyBulkCString(c,"dir");
545 addReplyBulkCString(c,buf);
21cda08 Salvatore Sanfilippo CONFIG GET/SET dir implemented
antirez authored
546 matches++;
547 }
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
548 if (stringmatch(pattern,"dbfilename",0)) {
549 addReplyBulkCString(c,"dbfilename");
550 addReplyBulkCString(c,server.dbfilename);
551 matches++;
552 }
553 if (stringmatch(pattern,"requirepass",0)) {
554 addReplyBulkCString(c,"requirepass");
555 addReplyBulkCString(c,server.requirepass);
556 matches++;
557 }
558 if (stringmatch(pattern,"masterauth",0)) {
559 addReplyBulkCString(c,"masterauth");
560 addReplyBulkCString(c,server.masterauth);
561 matches++;
562 }
563 if (stringmatch(pattern,"maxmemory",0)) {
a368792 Salvatore Sanfilippo maxmemory-samples implemented in CONFIG command and configuration file
antirez authored
564 ll2string(buf,sizeof(buf),server.maxmemory);
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
565 addReplyBulkCString(c,"maxmemory");
566 addReplyBulkCString(c,buf);
567 matches++;
568 }
165346c Salvatore Sanfilippo implemented different algorithms for maxmemory
antirez authored
569 if (stringmatch(pattern,"maxmemory-policy",0)) {
570 char *s;
571
572 switch(server.maxmemory_policy) {
573 case REDIS_MAXMEMORY_VOLATILE_LRU: s = "volatile-lru"; break;
574 case REDIS_MAXMEMORY_VOLATILE_TTL: s = "volatile-ttl"; break;
575 case REDIS_MAXMEMORY_VOLATILE_RANDOM: s = "volatile-random"; break;
576 case REDIS_MAXMEMORY_ALLKEYS_LRU: s = "allkeys-lru"; break;
577 case REDIS_MAXMEMORY_ALLKEYS_RANDOM: s = "allkeys-random"; break;
5402c42 Salvatore Sanfilippo added noeviction policy to redis maxmemory. ZSCORE removed from the list...
antirez authored
578 case REDIS_MAXMEMORY_NO_EVICTION: s = "noeviction"; break;
165346c Salvatore Sanfilippo implemented different algorithms for maxmemory
antirez authored
579 default: s = "unknown"; break; /* too harmless to panic */
580 }
581 addReplyBulkCString(c,"maxmemory-policy");
582 addReplyBulkCString(c,s);
583 matches++;
584 }
a368792 Salvatore Sanfilippo maxmemory-samples implemented in CONFIG command and configuration file
antirez authored
585 if (stringmatch(pattern,"maxmemory-samples",0)) {
586 ll2string(buf,sizeof(buf),server.maxmemory_samples);
587 addReplyBulkCString(c,"maxmemory-samples");
588 addReplyBulkCString(c,buf);
589 matches++;
590 }
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
591 if (stringmatch(pattern,"timeout",0)) {
a368792 Salvatore Sanfilippo maxmemory-samples implemented in CONFIG command and configuration file
antirez authored
592 ll2string(buf,sizeof(buf),server.maxidletime);
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
593 addReplyBulkCString(c,"timeout");
594 addReplyBulkCString(c,buf);
595 matches++;
596 }
597 if (stringmatch(pattern,"appendonly",0)) {
598 addReplyBulkCString(c,"appendonly");
599 addReplyBulkCString(c,server.appendonly ? "yes" : "no");
600 matches++;
601 }
602 if (stringmatch(pattern,"no-appendfsync-on-rewrite",0)) {
603 addReplyBulkCString(c,"no-appendfsync-on-rewrite");
604 addReplyBulkCString(c,server.no_appendfsync_on_rewrite ? "yes" : "no");
605 matches++;
606 }
607 if (stringmatch(pattern,"appendfsync",0)) {
608 char *policy;
609
610 switch(server.appendfsync) {
611 case APPENDFSYNC_NO: policy = "no"; break;
612 case APPENDFSYNC_EVERYSEC: policy = "everysec"; break;
613 case APPENDFSYNC_ALWAYS: policy = "always"; break;
614 default: policy = "unknown"; break; /* too harmless to panic */
615 }
616 addReplyBulkCString(c,"appendfsync");
617 addReplyBulkCString(c,policy);
618 matches++;
619 }
620 if (stringmatch(pattern,"save",0)) {
621 sds buf = sdsempty();
622 int j;
623
624 for (j = 0; j < server.saveparamslen; j++) {
625 buf = sdscatprintf(buf,"%ld %d",
626 server.saveparams[j].seconds,
627 server.saveparams[j].changes);
628 if (j != server.saveparamslen-1)
629 buf = sdscatlen(buf," ",1);
630 }
631 addReplyBulkCString(c,"save");
632 addReplyBulkCString(c,buf);
633 sdsfree(buf);
634 matches++;
635 }
0ec9322 Salvatore Sanfilippo CONFIG SET/GET support for new automatic AOF rewrite parameters
antirez authored
636 if (stringmatch(pattern,"auto-aof-rewrite-percentage",0)) {
637 addReplyBulkCString(c,"auto-aof-rewrite-percentage");
638 addReplyBulkLongLong(c,server.auto_aofrewrite_perc);
639 matches++;
640 }
641 if (stringmatch(pattern,"auto-aof-rewrite-min-size",0)) {
642 addReplyBulkCString(c,"auto-aof-rewrite-min-size");
643 addReplyBulkLongLong(c,server.auto_aofrewrite_min_size);
644 matches++;
645 }
4ebfc45 Salvatore Sanfilippo config option to select if when replication link with master a slave sho...
antirez authored
646 if (stringmatch(pattern,"slave-serve-stale-data",0)) {
647 addReplyBulkCString(c,"slave-serve-stale-data");
648 addReplyBulkCString(c,server.repl_serve_stale_data ? "yes" : "no");
649 matches++;
650 }
465b418 Salvatore Sanfilippo CONFIG SET/GET for all the special encoding parameters of sets, lists, h...
antirez authored
651 if (stringmatch(pattern,"hash-max-zipmap-entries",0)) {
652 addReplyBulkCString(c,"hash-max-zipmap-entries");
653 addReplyBulkLongLong(c,server.hash_max_zipmap_entries);
654 matches++;
655 }
656 if (stringmatch(pattern,"hash-max-zipmap-value",0)) {
657 addReplyBulkCString(c,"hash-max-zipmap-value");
658 addReplyBulkLongLong(c,server.hash_max_zipmap_value);
659 matches++;
660 }
661 if (stringmatch(pattern,"list-max-ziplist-entries",0)) {
662 addReplyBulkCString(c,"list-max-ziplist-entries");
663 addReplyBulkLongLong(c,server.list_max_ziplist_entries);
664 matches++;
665 }
666 if (stringmatch(pattern,"list-max-ziplist-value",0)) {
667 addReplyBulkCString(c,"list-max-ziplist-value");
668 addReplyBulkLongLong(c,server.list_max_ziplist_value);
669 matches++;
670 }
671 if (stringmatch(pattern,"set-max-intset-entries",0)) {
672 addReplyBulkCString(c,"set-max-intset-entries");
673 addReplyBulkLongLong(c,server.set_max_intset_entries);
674 matches++;
675 }
3ea204e Pieter Noordhuis Configurable thresholds for encoded sorted sets
pietern authored
676 if (stringmatch(pattern,"zset-max-ziplist-entries",0)) {
677 addReplyBulkCString(c,"zset-max-ziplist-entries");
678 addReplyBulkLongLong(c,server.zset_max_ziplist_entries);
679 matches++;
680 }
681 if (stringmatch(pattern,"zset-max-ziplist-value",0)) {
682 addReplyBulkCString(c,"zset-max-ziplist-value");
683 addReplyBulkLongLong(c,server.zset_max_ziplist_value);
684 matches++;
685 }
eeffcf3 Salvatore Sanfilippo Lua scripts max execution time
antirez authored
686 if (stringmatch(pattern,"lua-time-limit",0)) {
687 addReplyBulkCString(c,"lua-time-limit");
688 addReplyBulkLongLong(c,server.lua_time_limit);
5f54619 Salvatore Sanfilippo Fix for a typo left after merging.
antirez authored
689 matches++;
690 }
35a6044 Salvatore Sanfilippo slow log configuration implemented
antirez authored
691 if (stringmatch(pattern,"slowlog-log-slower-than",0)) {
692 addReplyBulkCString(c,"slowlog-log-slower-than");
693 addReplyBulkLongLong(c,server.slowlog_log_slower_than);
694 matches++;
695 }
696 if (stringmatch(pattern,"slowlog-max-len",0)) {
697 addReplyBulkCString(c,"slowlog-max-len");
698 addReplyBulkLongLong(c,server.slowlog_max_len);
eeffcf3 Salvatore Sanfilippo Lua scripts max execution time
antirez authored
699 matches++;
700 }
2aa26d2 Salvatore Sanfilippo CONFIG SET/GET support for loglevel
antirez authored
701 if (stringmatch(pattern,"loglevel",0)) {
702 char *s;
703
704 switch(server.verbosity) {
705 case REDIS_WARNING: s = "warning"; break;
706 case REDIS_VERBOSE: s = "verbose"; break;
707 case REDIS_NOTICE: s = "notice"; break;
708 case REDIS_DEBUG: s = "debug"; break;
709 default: s = "unknown"; break; /* too harmless to panic */
710 }
711 addReplyBulkCString(c,"loglevel");
712 addReplyBulkCString(c,s);
713 matches++;
714 }
b301c1f Pieter Noordhuis Wrapper for adding unknown multi bulk length to reply list
pietern authored
715 setDeferredMultiBulkLength(c,replylen,matches*2);
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
716 }
717
718 void configCommand(redisClient *c) {
719 if (!strcasecmp(c->argv[1]->ptr,"set")) {
720 if (c->argc != 4) goto badarity;
721 configSetCommand(c);
722 } else if (!strcasecmp(c->argv[1]->ptr,"get")) {
723 if (c->argc != 3) goto badarity;
724 configGetCommand(c);
725 } else if (!strcasecmp(c->argv[1]->ptr,"resetstat")) {
726 if (c->argc != 2) goto badarity;
9f8ded8 Salvatore Sanfilippo CONFIG RESETSTAT no longer resets the server uptime. Now keyspace hits/m...
antirez authored
727 server.stat_keyspace_hits = 0;
728 server.stat_keyspace_misses = 0;
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
729 server.stat_numcommands = 0;
730 server.stat_numconnections = 0;
731 server.stat_expiredkeys = 0;
d7ed7fd Salvatore Sanfilippo INFO commandstats section reset with config resetstat, a new microsecond...
antirez authored
732 resetCommandTableStats();
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
733 addReply(c,shared.ok);
734 } else {
3ab2037 Pieter Noordhuis Use specialized function to add status and error replies
pietern authored
735 addReplyError(c,
736 "CONFIG subcommand must be one of GET, SET, RESETSTAT");
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
737 }
738 return;
739
740 badarity:
3ab2037 Pieter Noordhuis Use specialized function to add status and error replies
pietern authored
741 addReplyErrorFormat(c,"Wrong number of arguments for CONFIG %s",
742 (char*) c->argv[1]->ptr);
e2641e0 Salvatore Sanfilippo redis.c split into many different C files.
antirez authored
743 }
Something went wrong with that request. Please try again.