|
redis配置文件的头文件,有一些和平台有关的配置,在这里边进行设置。
config.h
1 #ifndef __CONFIG_H
2 #define __CONFIG_H
3
4 #ifdef __APPLE__
5 #include
6 #endif
7
8 /* Define redis_fstat to fstat or fstat64() */
9 #if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6)
10 #define redis_fstat fstat64
11 #define redis_stat stat64
12 #else
13 #define redis_fstat fstat
14 #define redis_stat stat
15 #endif
16
17 /* Test for proc filesystem */
18 //proc filesystem是进程文件系统的意思,包含一个伪文件系统(启动时动态生成的文件系统),用于通过内核访问进程信息。这个文件系统通常挂载在/proc目录下,/proc不是真正的文件系统,仅占用内存空间
19 //redis在获取rss信息(zmalloc.c的zmalloc_get_rss函数)时,需要判断是否有proc filesystem。rss是Resident Set Size的缩写,表示进程占用被hold在内存的那一部分。
20 #ifdef __linux__
21 #define HAVE_PROCFS 1
22 #endif
23
24 /* Test for task_info() */
25 #if defined(__APPLE__)
26 #define HAVE_TASKINFO 1
27 #endif
28
29 //backtrace是指“A backtrace is a list of the function calls that are currently active in a thread. The usual way to inspect a backtrace of a program is to use an external debugger such as gdb. However, sometimes it is useful to obtain a backtrace programmatically from within a program, e.g., for the purposes of logging or diagnostics.”或者说,我们通常说的栈祯。在debug.c和redis.c中均有应用,具体到相关调用处再说明。
30 /* Test for backtrace() */
31 #if defined(__APPLE__) || defined(__linux__) || defined(__sun)
32 #define HAVE_BACKTRACE 1
33 #endif
34
35 //linux下使用epoll构建事件框架
36 /* Test for polling API */
37 #ifdef __linux__
38 #define HAVE_EPOLL 1
39 #endif
40
41 #if (defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6)) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__)
42 #define HAVE_KQUEUE 1
43 #endif
44
45 //linux下使用fdatasync来flush硬盘。apue上讲过,fsync和fdatasync的区别是,fsync同时刷新文件的元数据(精确描述大家自己翻书吧)。redis使用fsync是为了将内存中的业务数据保存下来,具体rdb文件的元数据是否得到及时更新,并不是很重要,因此,如果在fdatasync可用的时候,使用更快的就是一个更明智的选择。
46 /* Define aof_fsync to fdatasync() in Linux and fsync() for all the rest */
47 #ifdef __linux__
48 #define aof_fsync fdatasync
49 #else
50 #define aof_fsync fsync
51 #endif
52
53 #endif
config.c 读取配置文件,以及和配置文件有关的client命令的执行函数,可谓又臭又长,看看就好。
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 int really_use_vm = 0;
34
35 if (filename[0] == '-' && filename[1] == '\0')
36 fp = stdin;
37 else {
38 if ((fp = fopen(filename,"r")) == NULL) {
39 redisLog(REDIS_WARNING, "Fatal error, can't open config file '%s'", filename);
40 exit(1);
41 }
42 }
43
44 while(fgets(buf,REDIS_CONFIGLINE_MAX+1,fp) != NULL) {
45 sds *argv;
46 int argc, j;
47
48 linenum++;
49 line = sdsnew(buf);
50 line = sdstrim(line," \t\r\n");
51
52 /* Skip comments and blank lines*/
53 if (line[0] == '#' || line[0] == '\0') {
54 sdsfree(line);
55 continue;
56 }
57
58 /* Split into arguments */
59 argv = sdssplitargs(line,&argc);
60 sdstolower(argv[0]);
61
62 /* Execute config directives */
63 if (!strcasecmp(argv[0],"timeout") && argc == 2) {
64 server.maxidletime = atoi(argv[1]);
65 if (server.maxidletime < 0) {
66 err = "Invalid timeout value"; goto loaderr;
67 }
68 } else if (!strcasecmp(argv[0],"port") && argc == 2) {
69 server.port = atoi(argv[1]);
70 if (server.port < 0 || server.port > 65535) {
71 err = "Invalid port"; goto loaderr;
72 }
73 } else if (!strcasecmp(argv[0],"bind") && argc == 2) {
74 server.bindaddr = zstrdup(argv[1]);
75 } else if (!strcasecmp(argv[0],"unixsocket") && argc == 2) {
76 server.unixsocket = zstrdup(argv[1]);
77 } else if (!strcasecmp(argv[0],"unixsocketperm") && argc == 2) {
78 errno = 0;
79 server.unixsocketperm = (mode_t)strtol(argv[1], NULL, 8);
80 if (errno || server.unixsocketperm > 0777) {
81 err = "Invalid socket file permissions"; goto loaderr;
82 }
83 } else if (!strcasecmp(argv[0],"save") && argc == 3) {
84 int seconds = atoi(argv[1]);
85 int changes = atoi(argv[2]);
86 if (seconds < 1 || changes < 0) {
87 err = "Invalid save parameters"; goto loaderr;
88 }
89 appendServerSaveParams(seconds,changes);
90 } else if (!strcasecmp(argv[0],"dir") && argc == 2) {
91 if (chdir(argv[1]) == -1) {
92 redisLog(REDIS_WARNING,"Can't chdir to '%s': %s",
93 argv[1], strerror(errno));
94 exit(1);
95 }
96 } else if (!strcasecmp(argv[0],"loglevel") && argc == 2) {
97 if (!strcasecmp(argv[1],"debug")) server.verbosity = REDIS_DEBUG;
98 else if (!strcasecmp(argv[1],"verbose")) server.verbosity = REDIS_VERBOSE;
99 else if (!strcasecmp(argv[1],"notice")) server.verbosity = REDIS_NOTICE;
100 else if (!strcasecmp(argv[1],"warning")) server.verbosity = REDIS_WARNING;
101 else {
102 err = "Invalid log level. Must be one of debug, notice, warning";
103 goto loaderr;
104 }
105 } else if (!strcasecmp(argv[0],"logfile") && argc == 2) {
106 FILE *logfp;
107
108 server.logfile = zstrdup(argv[1]);
109 if (!strcasecmp(server.logfile,"stdout")) {
110 zfree(server.logfile);
111 server.logfile = NULL;
112 }
113 if (server.logfile) {
114 /* Test if we are able to open the file. The server will not
115 * be able to abort just for this problem later... */
116 logfp = fopen(server.logfile,"a");
117 if (logfp == NULL) {
118 err = sdscatprintf(sdsempty(),
119 "Can't open the log file: %s", strerror(errno));
120 goto loaderr;
121 }
122 fclose(logfp);
123 }
124 } else if (!strcasecmp(argv[0],"syslog-enabled") && argc == 2) {
125 if ((server.syslog_enabled = yesnotoi(argv[1])) == -1) {
126 err = "argument must be 'yes' or 'no'"; goto loaderr;
127 }
128 } else if (!strcasecmp(argv[0],"syslog-ident") && argc == 2) {
129 if (server.syslog_ident) zfree(server.syslog_ident);
130 server.syslog_ident = zstrdup(argv[1]);
131 } else if (!strcasecmp(argv[0],"syslog-facility") && argc == 2) {
132 struct {
133 const char *name;
134 const int value;
135 } validSyslogFacilities[] = {
136 {"user", LOG_USER},
137 {"local0", LOG_LOCAL0},
138 {"local1", LOG_LOCAL1},
139 {"local2", LOG_LOCAL2},
140 {"local3", LOG_LOCAL3},
141 {"local4", LOG_LOCAL4},
142 {"local5", LOG_LOCAL5},
143 {"local6", LOG_LOCAL6},
144 {"local7", LOG_LOCAL7},
145 {NULL, 0}
146 };
147 int i;
148
149 for (i = 0; validSyslogFacilities.name; i++) {
150 if (!strcasecmp(validSyslogFacilities.name, argv[1])) {
151 server.syslog_facility = validSyslogFacilities.value;
152 break;
153 }
154 }
155
156 if (!validSyslogFacilities.name) {
157 err = "Invalid log facility. Must be one of USER or between LOCAL0-LOCAL7";
158 goto loaderr;
159 }
160 } else if (!strcasecmp(argv[0],"databases") && argc == 2) {
161 server.dbnum = atoi(argv[1]);
162 if (server.dbnum < 1) {
163 err = "Invalid number of databases"; goto loaderr;
164 }
165 } else if (!strcasecmp(argv[0],"include") && argc == 2) {
166 loadServerConfig(argv[1]);
167 } else if (!strcasecmp(argv[0],"maxclients") && argc == 2) {
168 server.maxclients = atoi(argv[1]);
169 } else if (!strcasecmp(argv[0],"maxmemory") && argc == 2) {
170 server.maxmemory = memtoll(argv[1],NULL);
171 } else if (!strcasecmp(argv[0],"maxmemory-policy") && argc == 2) {
172 if (!strcasecmp(argv[1],"volatile-lru")) {
173 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_LRU;
174 } else if (!strcasecmp(argv[1],"volatile-random")) {
175 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_RANDOM;
176 } else if (!strcasecmp(argv[1],"volatile-ttl")) {
177 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_TTL;
178 } else if (!strcasecmp(argv[1],"allkeys-lru")) {
179 server.maxmemory_policy = REDIS_MAXMEMORY_ALLKEYS_LRU;
180 } else if (!strcasecmp(argv[1],"allkeys-random")) {
181 server.maxmemory_policy = REDIS_MAXMEMORY_ALLKEYS_RANDOM;
182 } else if (!strcasecmp(argv[1],"noeviction")) {
183 server.maxmemory_policy = REDIS_MAXMEMORY_NO_EVICTION;
184 } else {
185 err = "Invalid maxmemory policy";
186 goto loaderr;
187 }
188 } else if (!strcasecmp(argv[0],"maxmemory-samples") && argc == 2) {
189 server.maxmemory_samples = atoi(argv[1]);
190 if (server.maxmemory_samples argv[2]->encoding == REDIS_ENCODING_RAW);
373 redisAssert(c->argv[3]->encoding == REDIS_ENCODING_RAW);
374 o = c->argv[3];
375
376 if (!strcasecmp(c->argv[2]->ptr,"dbfilename")) {
377 zfree(server.dbfilename);
378 server.dbfilename = zstrdup(o->ptr);
379 } else if (!strcasecmp(c->argv[2]->ptr,"requirepass")) {
380 zfree(server.requirepass);
381 server.requirepass = ((char*)o->ptr)[0] ? zstrdup(o->ptr) : NULL;
382 } else if (!strcasecmp(c->argv[2]->ptr,"masterauth")) {
383 zfree(server.masterauth);
384 server.masterauth = zstrdup(o->ptr);
385 } else if (!strcasecmp(c->argv[2]->ptr,"maxmemory")) {
386 if (getLongLongFromObject(o,&ll) == REDIS_ERR ||
387 ll < 0) goto badfmt;
388 server.maxmemory = ll;
389 if (server.maxmemory) freeMemoryIfNeeded();
390 } else if (!strcasecmp(c->argv[2]->ptr,"maxmemory-policy")) {
391 if (!strcasecmp(o->ptr,"volatile-lru")) {
392 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_LRU;
393 } else if (!strcasecmp(o->ptr,"volatile-random")) {
394 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_RANDOM;
395 } else if (!strcasecmp(o->ptr,"volatile-ttl")) {
396 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_TTL;
397 } else if (!strcasecmp(o->ptr,"allkeys-lru")) {
398 server.maxmemory_policy = REDIS_MAXMEMORY_ALLKEYS_LRU;
399 } else if (!strcasecmp(o->ptr,"allkeys-random")) {
400 server.maxmemory_policy = REDIS_MAXMEMORY_ALLKEYS_RANDOM;
401 } else if (!strcasecmp(o->ptr,"noeviction")) {
402 server.maxmemory_policy = REDIS_MAXMEMORY_NO_EVICTION;
403 } else {
404 goto badfmt;
405 }
406 } else if (!strcasecmp(c->argv[2]->ptr,"maxmemory-samples")) {
407 if (getLongLongFromObject(o,&ll) == REDIS_ERR ||
408 ll argv[2]->ptr,"timeout")) {
411 if (getLongLongFromObject(o,&ll) == REDIS_ERR ||
412 ll < 0 || ll > LONG_MAX) goto badfmt;
413 server.maxidletime = ll;
414 } else if (!strcasecmp(c->argv[2]->ptr,"appendfsync")) {
415 if (!strcasecmp(o->ptr,"no")) {
416 server.appendfsync = APPENDFSYNC_NO;
417 } else if (!strcasecmp(o->ptr,"everysec")) {
418 server.appendfsync = APPENDFSYNC_EVERYSEC;
419 } else if (!strcasecmp(o->ptr,"always")) {
420 server.appendfsync = APPENDFSYNC_ALWAYS;
421 } else {
422 goto badfmt;
423 }
424 } else if (!strcasecmp(c->argv[2]->ptr,"no-appendfsync-on-rewrite")) {
425 int yn = yesnotoi(o->ptr);
426
427 if (yn == -1) goto badfmt;
428 server.no_appendfsync_on_rewrite = yn;
429 } else if (!strcasecmp(c->argv[2]->ptr,"appendonly")) {
430 int old = server.appendonly;
431 int new = yesnotoi(o->ptr);
432
433 if (new == -1) goto badfmt;
434 if (old != new) {
435 if (new == 0) {
436 stopAppendOnly();
437 } else {
438 if (startAppendOnly() == REDIS_ERR) {
439 addReplyError(c,
440 "Unable to turn on AOF. Check server logs.");
441 return;
442 }
443 }
444 }
445 } else if (!strcasecmp(c->argv[2]->ptr,"auto-aof-rewrite-percentage")) {
446 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
447 server.auto_aofrewrite_perc = ll;
448 } else if (!strcasecmp(c->argv[2]->ptr,"auto-aof-rewrite-min-size")) {
449 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
450 server.auto_aofrewrite_min_size = ll;
451 } else if (!strcasecmp(c->argv[2]->ptr,"save")) {
452 int vlen, j;
453 sds *v = sdssplitlen(o->ptr,sdslen(o->ptr)," ",1,&vlen);
454
455 /* Perform sanity check before setting the new config:
456 * - Even number of args
457 * - Seconds >= 1, changes >= 0 */
458 if (vlen & 1) {
459 sdsfreesplitres(v,vlen);
460 goto badfmt;
461 }
462 for (j = 0; j < vlen; j++) {
463 char *eptr;
464 long val;
465
466 val = strtoll(v[j], &eptr, 10);
467 if (eptr[0] != '\0' ||
468 ((j & 1) == 0 && val < 1) ||
469 ((j & 1) == 1 && val < 0)) {
470 sdsfreesplitres(v,vlen);
471 goto badfmt;
472 }
473 }
474 /* Finally set the new config */
475 resetServerSaveParams();
476 for (j = 0; j < vlen; j += 2) {
477 time_t seconds;
478 int changes;
479
480 seconds = strtoll(v[j],NULL,10);
481 changes = strtoll(v[j+1],NULL,10);
482 appendServerSaveParams(seconds, changes);
483 }
484 sdsfreesplitres(v,vlen);
485 } else if (!strcasecmp(c->argv[2]->ptr,"slave-serve-stale-data")) {
486 int yn = yesnotoi(o->ptr);
487
488 if (yn == -1) goto badfmt;
489 server.repl_serve_stale_data = yn;
490 } else if (!strcasecmp(c->argv[2]->ptr,"dir")) {
491 if (chdir((char*)o->ptr) == -1) {
492 addReplyErrorFormat(c,"Changing directory: %s", strerror(errno));
493 return;
494 }
495 } else if (!strcasecmp(c->argv[2]->ptr,"hash-max-zipmap-entries")) {
496 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
497 server.hash_max_zipmap_entries = ll;
498 } else if (!strcasecmp(c->argv[2]->ptr,"hash-max-zipmap-value")) {
499 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
500 server.hash_max_zipmap_value = ll;
501 } else if (!strcasecmp(c->argv[2]->ptr,"list-max-ziplist-entries")) {
502 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
503 server.list_max_ziplist_entries = ll;
504 } else if (!strcasecmp(c->argv[2]->ptr,"list-max-ziplist-value")) {
505 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
506 server.list_max_ziplist_value = ll;
507 } else if (!strcasecmp(c->argv[2]->ptr,"set-max-intset-entries")) {
508 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
509 server.set_max_intset_entries = ll;
510 } else if (!strcasecmp(c->argv[2]->ptr,"zset-max-ziplist-entries")) {
511 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
512 server.zset_max_ziplist_entries = ll;
513 } else if (!strcasecmp(c->argv[2]->ptr,"zset-max-ziplist-value")) {
514 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
515 server.zset_max_ziplist_value = ll;
516 } else if (!strcasecmp(c->argv[2]->ptr,"slowlog-log-slower-than")) {
517 if (getLongLongFromObject(o,&ll) == REDIS_ERR) goto badfmt;
518 server.slowlog_log_slower_than = ll;
519 } else if (!strcasecmp(c->argv[2]->ptr,"slowlog-max-len")) {
520 if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
521 server.slowlog_max_len = (unsigned)ll;
522 } else if (!strcasecmp(c->argv[2]->ptr,"loglevel")) {
523 if (!strcasecmp(o->ptr,"warning")) {
524 server.verbosity = REDIS_WARNING;
525 } else if (!strcasecmp(o->ptr,"notice")) {
526 server.verbosity = REDIS_NOTICE;
527 } else if (!strcasecmp(o->ptr,"verbose")) {
528 server.verbosity = REDIS_VERBOSE;
529 } else if (!strcasecmp(o->ptr,"debug")) {
530 server.verbosity = REDIS_DEBUG;
531 } else {
532 goto badfmt;
533 }
534 } else {
535 addReplyErrorFormat(c,"Unsupported CONFIG parameter: %s",
536 (char*)c->argv[2]->ptr);
537 return;
538 }
539 addReply(c,shared.ok);
540 return;
541
542 badfmt: /* Bad format errors */
543 addReplyErrorFormat(c,"Invalid argument '%s' for CONFIG SET '%s'",
544 (char*)o->ptr,
545 (char*)c->argv[2]->ptr);
546 }
547
548 void configGetCommand(redisClient *c) {
549 robj *o = c->argv[2];
550 void *replylen = addDeferredMultiBulkLength(c);
551 char *pattern = o->ptr;
552 char buf[128];
553 int matches = 0;
554 redisAssert(o->encoding == REDIS_ENCODING_RAW);
555
556 if (stringmatch(pattern,"dir",0)) {
557 char buf[1024];
558
559 if (getcwd(buf,sizeof(buf)) == NULL)
560 buf[0] = '\0';
561
562 addReplyBulkCString(c,"dir");
563 addReplyBulkCString(c,buf);
564 matches++;
565 }
566 if (stringmatch(pattern,"dbfilename",0)) {
567 addReplyBulkCString(c,"dbfilename");
568 addReplyBulkCString(c,server.dbfilename);
569 matches++;
570 }
571 if (stringmatch(pattern,"requirepass",0)) {
572 addReplyBulkCString(c,"requirepass");
573 addReplyBulkCString(c,server.requirepass);
574 matches++;
575 }
576 if (stringmatch(pattern,"masterauth",0)) {
577 addReplyBulkCString(c,"masterauth");
578 addReplyBulkCString(c,server.masterauth);
579 matches++;
580 }
581 if (stringmatch(pattern,"maxmemory",0)) {
582 ll2string(buf,sizeof(buf),server.maxmemory);
583 addReplyBulkCString(c,"maxmemory");
584 addReplyBulkCString(c,buf);
585 matches++;
586 }
587 if (stringmatch(pattern,"maxmemory-policy",0)) {
588 char *s;
589
590 switch(server.maxmemory_policy) {
591 case REDIS_MAXMEMORY_VOLATILE_LRU: s = "volatile-lru"; break;
592 case REDIS_MAXMEMORY_VOLATILE_TTL: s = "volatile-ttl"; break;
593 case REDIS_MAXMEMORY_VOLATILE_RANDOM: s = "volatile-random"; break;
594 case REDIS_MAXMEMORY_ALLKEYS_LRU: s = "allkeys-lru"; break;
595 case REDIS_MAXMEMORY_ALLKEYS_RANDOM: s = "allkeys-random"; break;
596 case REDIS_MAXMEMORY_NO_EVICTION: s = "noeviction"; break;
597 default: s = "unknown"; break; /* too harmless to panic */
598 }
599 addReplyBulkCString(c,"maxmemory-policy");
600 addReplyBulkCString(c,s);
601 matches++;
602 }
603 if (stringmatch(pattern,"maxmemory-samples",0)) {
604 ll2string(buf,sizeof(buf),server.maxmemory_samples);
605 addReplyBulkCString(c,"maxmemory-samples");
606 addReplyBulkCString(c,buf);
607 matches++;
608 }
609 if (stringmatch(pattern,"timeout",0)) {
610 ll2string(buf,sizeof(buf),server.maxidletime);
611 addReplyBulkCString(c,"timeout");
612 addReplyBulkCString(c,buf);
613 matches++;
614 }
615 if (stringmatch(pattern,"appendonly",0)) {
616 addReplyBulkCString(c,"appendonly");
617 addReplyBulkCString(c,server.appendonly ? "yes" : "no");
618 matches++;
619 }
620 if (stringmatch(pattern,"no-appendfsync-on-rewrite",0)) {
621 addReplyBulkCString(c,"no-appendfsync-on-rewrite");
622 addReplyBulkCString(c,server.no_appendfsync_on_rewrite ? "yes" : "no");
623 matches++;
624 }
625 if (stringmatch(pattern,"appendfsync",0)) {
626 char *policy;
627
628 switch(server.appendfsync) {
629 case APPENDFSYNC_NO: policy = "no"; break;
630 case APPENDFSYNC_EVERYSEC: policy = "everysec"; break;
631 case APPENDFSYNC_ALWAYS: policy = "always"; break;
632 default: policy = "unknown"; break; /* too harmless to panic */
633 }
634 addReplyBulkCString(c,"appendfsync");
635 addReplyBulkCString(c,policy);
636 matches++;
637 }
638 if (stringmatch(pattern,"save",0)) {
639 sds buf = sdsempty();
640 int j;
641
642 for (j = 0; j < server.saveparamslen; j++) {
643 buf = sdscatprintf(buf,"%ld %d",
644 server.saveparams[j].seconds,
645 server.saveparams[j].changes);
646 if (j != server.saveparamslen-1)
647 buf = sdscatlen(buf," ",1);
648 }
649 addReplyBulkCString(c,"save");
650 addReplyBulkCString(c,buf);
651 sdsfree(buf);
652 matches++;
653 }
654 if (stringmatch(pattern,"auto-aof-rewrite-percentage",0)) {
655 addReplyBulkCString(c,"auto-aof-rewrite-percentage");
656 addReplyBulkLongLong(c,server.auto_aofrewrite_perc);
657 matches++;
658 }
659 if (stringmatch(pattern,"auto-aof-rewrite-min-size",0)) {
660 addReplyBulkCString(c,"auto-aof-rewrite-min-size");
661 addReplyBulkLongLong(c,server.auto_aofrewrite_min_size);
662 matches++;
663 }
664 if (stringmatch(pattern,"slave-serve-stale-data",0)) {
665 addReplyBulkCString(c,"slave-serve-stale-data");
666 addReplyBulkCString(c,server.repl_serve_stale_data ? "yes" : "no");
667 matches++;
668 }
669 if (stringmatch(pattern,"hash-max-zipmap-entries",0)) {
670 addReplyBulkCString(c,"hash-max-zipmap-entries");
671 addReplyBulkLongLong(c,server.hash_max_zipmap_entries);
672 matches++;
673 }
674 if (stringmatch(pattern,"hash-max-zipmap-value",0)) {
675 addReplyBulkCString(c,"hash-max-zipmap-value");
676 addReplyBulkLongLong(c,server.hash_max_zipmap_value);
677 matches++;
678 }
679 if (stringmatch(pattern,"list-max-ziplist-entries",0)) {
680 addReplyBulkCString(c,"list-max-ziplist-entries");
681 addReplyBulkLongLong(c,server.list_max_ziplist_entries);
682 matches++;
683 }
684 if (stringmatch(pattern,"list-max-ziplist-value",0)) {
685 addReplyBulkCString(c,"list-max-ziplist-value");
686 addReplyBulkLongLong(c,server.list_max_ziplist_value);
687 matches++;
688 }
689 if (stringmatch(pattern,"set-max-intset-entries",0)) {
690 addReplyBulkCString(c,"set-max-intset-entries");
691 addReplyBulkLongLong(c,server.set_max_intset_entries);
692 matches++;
693 }
694 if (stringmatch(pattern,"zset-max-ziplist-entries",0)) {
695 addReplyBulkCString(c,"zset-max-ziplist-entries");
696 addReplyBulkLongLong(c,server.zset_max_ziplist_entries);
697 matches++;
698 }
699 if (stringmatch(pattern,"zset-max-ziplist-value",0)) {
700 addReplyBulkCString(c,"zset-max-ziplist-value");
701 addReplyBulkLongLong(c,server.zset_max_ziplist_value);
702 matches++;
703 }
704 if (stringmatch(pattern,"slowlog-log-slower-than",0)) {
705 addReplyBulkCString(c,"slowlog-log-slower-than");
706 addReplyBulkLongLong(c,server.slowlog_log_slower_than);
707 matches++;
708 }
709 if (stringmatch(pattern,"slowlog-max-len",0)) {
710 addReplyBulkCString(c,"slowlog-max-len");
711 addReplyBulkLongLong(c,server.slowlog_max_len);
712 matches++;
713 }
714 if (stringmatch(pattern,"loglevel",0)) {
715 char *s;
716
717 switch(server.verbosity) {
718 case REDIS_WARNING: s = "warning"; break;
719 case REDIS_VERBOSE: s = "verbose"; break;
720 case REDIS_NOTICE: s = "notice"; break;
721 case REDIS_DEBUG: s = "debug"; break;
722 default: s = "unknown"; break; /* too harmless to panic */
723 }
724 addReplyBulkCString(c,"loglevel");
725 addReplyBulkCString(c,s);
726 matches++;
727 }
728 setDeferredMultiBulkLength(c,replylen,matches*2);
729 }
730
731 void configCommand(redisClient *c) {
732 if (!strcasecmp(c->argv[1]->ptr,"set")) {
733 if (c->argc != 4) goto badarity;
734 configSetCommand(c);
735 } else if (!strcasecmp(c->argv[1]->ptr,"get")) {
736 if (c->argc != 3) goto badarity;
737 configGetCommand(c);
738 } else if (!strcasecmp(c->argv[1]->ptr,"resetstat")) {
739 if (c->argc != 2) goto badarity;
740 server.stat_keyspace_hits = 0;
741 server.stat_keyspace_misses = 0;
742 server.stat_numcommands = 0;
743 server.stat_numconnections = 0;
744 server.stat_expiredkeys = 0;
745 addReply(c,shared.ok);
746 } else {
747 addReplyError(c,
748 "CONFIG subcommand must be one of GET, SET, RESETSTAT");
749 }
750 return;
751
752 badarity:
753 addReplyErrorFormat(c,"Wrong number of arguments for CONFIG %s",
754 (char*) c->argv[1]->ptr);
755 } |
|