From 7d728c75b7f4ecf3ea0bce40a72879eee34085eb Mon Sep 17 00:00:00 2001 From: Ping Xie Date: Tue, 7 May 2024 01:22:27 -0700 Subject: [PATCH] Clnag-format the entire codebase Signed-off-by: Ping Xie --- src/acl.c | 1547 ++++++------ src/adlist.c | 121 +- src/adlist.h | 6 +- src/ae.c | 216 +- src/ae.h | 41 +- src/ae_epoll.c | 59 +- src/ae_evport.c | 96 +- src/ae_kqueue.c | 45 +- src/ae_select.c | 41 +- src/anet.c | 333 +-- src/anet.h | 6 +- src/aof.c | 1118 +++++---- src/asciilogo.h | 39 +- src/atomicvar.h | 168 +- src/bio.c | 90 +- src/bitops.c | 723 +++--- src/blocked.c | 189 +- src/call_reply.c | 124 +- src/childinfo.c | 47 +- src/cli_commands.c | 8 +- src/cli_commands.h | 6 +- src/cli_common.c | 128 +- src/cli_common.h | 8 +- src/cluster.c | 696 +++--- src/cluster.h | 23 +- src/cluster_legacy.c | 2958 +++++++++++----------- src/cluster_legacy.h | 270 +- src/commands.c | 9 +- src/commands.h | 10 +- src/config.c | 2071 ++++++++------- src/config.h | 77 +- src/connection.c | 33 +- src/connection.h | 38 +- src/connhelpers.h | 10 +- src/crc16.c | 59 +- src/crc16_slottable.h | 1847 ++++++++------ src/crc64.c | 6 +- src/crccombine.c | 318 +-- src/crccombine.h | 2 +- src/crcspeed.c | 107 +- src/crcspeed.h | 18 +- src/db.c | 803 +++--- src/debug.c | 2234 ++++++++--------- src/debugmacro.h | 14 +- src/defrag.c | 448 ++-- src/dict.c | 693 +++--- src/dict.h | 59 +- src/endianconv.c | 6 +- src/eval.c | 1058 ++++---- src/evict.c | 229 +- src/expire.c | 287 ++- src/fmacros.h | 9 +- src/fmtargs.h | 19 +- src/function_lua.c | 108 +- src/functions.c | 292 ++- src/functions.h | 14 +- src/geo.c | 401 +-- src/geohash.c | 86 +- src/geohash.h | 23 +- src/geohash_helper.c | 101 +- src/geohash_helper.h | 15 +- src/hyperloglog.c | 689 ++--- src/intset.c | 170 +- src/kvstore.c | 253 +- src/kvstore.h | 21 +- src/latency.c | 452 ++-- src/latency.h | 36 +- src/lazyfree.c | 74 +- src/listpack.c | 1215 +++++---- src/listpack.h | 18 +- src/listpack_malloc.h | 4 +- src/localtime.c | 43 +- src/logreqres.c | 56 +- src/lolwut.c | 66 +- src/lolwut5.c | 127 +- src/lolwut6.c | 133 +- src/lzf.h | 9 +- src/lzfP.h | 81 +- src/lzf_c.c | 389 +-- src/lzf_d.c | 232 +- src/memtest.c | 232 +- src/module.c | 4455 ++++++++++++++++++++------------- src/monotonic.c | 38 +- src/mt19937-64.c | 109 +- src/mt19937-64.h | 3 +- src/multi.c | 165 +- src/networking.c | 2282 +++++++++-------- src/notify.c | 143 +- src/object.c | 923 ++++--- src/pqsort.c | 241 +- src/pqsort.h | 4 +- src/pubsub.c | 316 +-- src/quicklist.c | 1141 +++++---- src/quicklist.h | 69 +- src/rand.c | 53 +- src/rax.c | 802 +++--- src/rax.h | 42 +- src/rdb.c | 2310 +++++++++-------- src/rdb.h | 101 +- src/redismodule.h | 6 +- src/release.c | 4 +- src/replication.c | 1809 +++++++------- src/resp_parser.c | 103 +- src/resp_parser.h | 3 +- src/rio.c | 203 +- src/rio.h | 60 +- src/script.c | 129 +- src/script.h | 37 +- src/script_lua.c | 803 +++--- src/script_lua.h | 15 +- src/sds.c | 971 +++++--- src/sds.h | 231 +- src/sentinel.c | 3383 +++++++++++++------------ src/server.c | 3987 +++++++++++++++-------------- src/server.h | 2238 +++++++++-------- src/serverassert.c | 12 +- src/serverassert.h | 4 +- src/setcpuaffinity.c | 37 +- src/setproctitle.c | 400 +-- src/sha1.c | 181 +- src/sha1.h | 6 +- src/sha256.c | 246 +- src/sha256.h | 28 +- src/siphash.c | 867 ++++++- src/slowlog.c | 111 +- src/socket.c | 137 +- src/solarisfixes.h | 24 +- src/sort.c | 310 +-- src/sparkline.c | 62 +- src/stream.h | 82 +- src/strl.c | 33 +- src/syncio.c | 52 +- src/syscheck.c | 122 +- src/t_hash.c | 460 ++-- src/t_list.c | 647 ++--- src/t_set.c | 603 +++-- src/t_stream.c | 2265 +++++++++-------- src/t_string.c | 559 +++-- src/t_zset.c | 1891 +++++++------- src/testhelp.h | 37 +- src/threads_mngr.c | 21 +- src/threads_mngr.h | 8 +- src/timeout.c | 88 +- src/tls.c | 606 +++-- src/tracking.c | 340 +-- src/unix.c | 21 +- src/util.c | 797 +++--- src/util.h | 13 +- src/valkey-benchmark.c | 1421 ++++++----- src/valkey-check-aof.c | 161 +- src/valkey-check-rdb.c | 181 +- src/valkey-cli.c | 5403 ++++++++++++++++++++++------------------ src/valkeymodule.h | 1177 +++++---- src/ziplist.c | 1061 ++++---- src/ziplist.h | 11 +- src/zipmap.c | 254 +- src/zipmap.h | 6 +- src/zmalloc.c | 379 +-- src/zmalloc.h | 29 +- 159 files changed, 40548 insertions(+), 32694 deletions(-) diff --git a/src/acl.c b/src/acl.c index d29afbc28..7b5bc8bc2 100644 --- a/src/acl.c +++ b/src/acl.c @@ -38,20 +38,20 @@ rax *Users; /* Table mapping usernames to user structures. */ -user *DefaultUser; /* Global reference to the default user. - Every new connection is associated to it, if no - AUTH or HELLO is used to authenticate with a - different user. */ - -list *UsersToLoad; /* This is a list of users found in the configuration file - that we'll need to load in the final stage of Redis - initialization, after all the modules are already - loaded. Every list element is a NULL terminated - array of SDS pointers: the first is the user name, - all the remaining pointers are ACL rules in the same - format as ACLSetUser(). */ -list *ACLLog; /* Our security log, the user is able to inspect that - using the ACL LOG command .*/ +user *DefaultUser; /* Global reference to the default user. + Every new connection is associated to it, if no + AUTH or HELLO is used to authenticate with a + different user. */ + +list *UsersToLoad; /* This is a list of users found in the configuration file + that we'll need to load in the final stage of Redis + initialization, after all the modules are already + loaded. Every list element is a NULL terminated + array of SDS pointers: the first is the user name, + all the remaining pointers are ACL rules in the same + format as ACLSetUser(). */ +list *ACLLog; /* Our security log, the user is able to inspect that + using the ACL LOG command .*/ long long ACLLogEntryCount = 0; /* Number of ACL log entries created */ @@ -64,7 +64,8 @@ static unsigned long nextid = 0; /* Next command id that has not been assigned * struct ACLCategoryItem { char *name; uint64_t flag; -} ACLDefaultCommandCategories[] = { /* See valkey.conf for details on each category. */ +} ACLDefaultCommandCategories[] = { + /* See valkey.conf for details on each category. */ {"keyspace", ACL_CATEGORY_KEYSPACE}, {"read", ACL_CATEGORY_READ}, {"write", ACL_CATEGORY_WRITE}, @@ -86,7 +87,7 @@ struct ACLCategoryItem { {"connection", ACL_CATEGORY_CONNECTION}, {"transaction", ACL_CATEGORY_TRANSACTION}, {"scripting", ACL_CATEGORY_SCRIPTING}, - {NULL,0} /* Terminator. */ + {NULL, 0} /* Terminator. */ }; static struct ACLCategoryItem *ACLCommandCategories = NULL; @@ -96,7 +97,7 @@ static size_t nextCommandCategory = 0; /* Index of the next command category to * also requires a bit in the acl_categories flag, there is a limit to the number that can be added. * The new ACL categories occupy the remaining bits of acl_categories flag, other than the bits * occupied by the default ACL command categories. - * + * * The optional `flag` argument allows the assignment of the `acl_categories` flag bit to the ACL category. * When adding a new category, except for the default ACL command categories, this arguments should be `0` * to allow the function to assign the next available `acl_categories` flag bit to the new ACL category. @@ -106,14 +107,16 @@ static size_t nextCommandCategory = 0; /* Index of the next command category to * This function is present here to gain access to the ACLCommandCategories array and add a new ACL category. */ int ACLAddCommandCategory(const char *name, uint64_t flag) { - if (nextCommandCategory >= ACL_MAX_CATEGORIES) return 0; + if (nextCommandCategory >= ACL_MAX_CATEGORIES) { + return 0; + } ACLCommandCategories[nextCommandCategory].name = zstrdup(name); - ACLCommandCategories[nextCommandCategory].flag = flag != 0 ? flag : (1ULL<>4)]; - hex[j*2+1] = cset[(hash[j]&0xF)]; + hex[j * 2] = cset[((hash[j] & 0xF0) >> 4)]; + hex[j * 2 + 1] = cset[(hash[j] & 0xF)]; } - return sdsnewlen(hex,HASH_PASSWORD_LEN); + return sdsnewlen(hex, HASH_PASSWORD_LEN); } /* Given a hash and the hash length, returns C_OK if it is a valid password @@ -246,7 +249,7 @@ int ACLCheckPasswordHash(unsigned char *hash, int hashlen) { /* Password hashes can only be characters that represent * hexadecimal values, which are numbers and lowercase * characters 'a' through 'f'. */ - for(int i = 0; i < HASH_PASSWORD_LEN; i++) { + for (int i = 0; i < HASH_PASSWORD_LEN; i++) { char c = hash[i]; if ((c < 'a' || c > 'f') && (c < '0' || c > '9')) { return C_ERR; @@ -266,7 +269,9 @@ int ACLCheckPasswordHash(unsigned char *hash, int hashlen) { * The function returns 0 if the string has no spaces. */ int ACLStringHasSpaces(const char *s, size_t len) { for (size_t i = 0; i < len; i++) { - if (isspace(s[i]) || s[i] == 0) return 1; + if (isspace(s[i]) || s[i] == 0) { + return 1; + } } return 0; } @@ -275,7 +280,7 @@ int ACLStringHasSpaces(const char *s, size_t len) { * zero if there is no match. */ uint64_t ACLGetCommandCategoryFlagByName(const char *name) { for (int j = 0; ACLCommandCategories[j].flag != 0; j++) { - if (!strcasecmp(name,ACLCommandCategories[j].name)) { + if (!strcasecmp(name, ACLCommandCategories[j].name)) { return ACLCommandCategories[j].flag; } } @@ -293,7 +298,7 @@ int ACLListMatchLoadedUser(void *definition, void *user) { /* Method for passwords/pattern comparison used for the user->passwords list * so that we can search for items with listSearchKey(). */ int ACLListMatchSds(void *a, void *b) { - return sdscmp(a,b) == 0; + return sdscmp(a, b) == 0; } /* Method to free list elements from ACL users password/patterns lists. */ @@ -309,13 +314,13 @@ void *ACLListDupSds(void *item) { /* Structure used for handling key patterns with different key * based permissions. */ typedef struct { - int flags; /* The ACL key permission types for this key pattern */ + int flags; /* The ACL key permission types for this key pattern */ sds pattern; /* The pattern to match keys against */ } keyPattern; /* Create a new key pattern. */ keyPattern *ACLKeyPatternCreate(sds pattern, int flags) { - keyPattern *new = (keyPattern *) zmalloc(sizeof(keyPattern)); + keyPattern *new = (keyPattern *)zmalloc(sizeof(keyPattern)); new->pattern = pattern; new->flags = flags; return new; @@ -330,7 +335,7 @@ void ACLKeyPatternFree(keyPattern *pattern) { /* Method for passwords/pattern comparison used for the user->passwords list * so that we can search for items with listSearchKey(). */ int ACLListMatchKeyPattern(void *a, void *b) { - return sdscmp(((keyPattern *) a)->pattern,((keyPattern *) b)->pattern) == 0; + return sdscmp(((keyPattern *)a)->pattern, ((keyPattern *)b)->pattern) == 0; } /* Method to free list elements from ACL users password/patterns lists. */ @@ -340,7 +345,7 @@ void ACLListFreeKeyPattern(void *item) { /* Method to duplicate list elements from ACL users password/patterns lists. */ void *ACLListDupKeyPattern(void *item) { - keyPattern *old = (keyPattern *) item; + keyPattern *old = (keyPattern *)item; return ACLKeyPatternCreate(sdsdup(old->pattern), old->flags); } @@ -348,11 +353,11 @@ void *ACLListDupKeyPattern(void *item) { * provided base string. */ sds sdsCatPatternString(sds base, keyPattern *pat) { if (pat->flags == ACL_ALL_PERMISSION) { - base = sdscatlen(base,"~",1); + base = sdscatlen(base, "~", 1); } else if (pat->flags == ACL_READ_PERMISSION) { - base = sdscatlen(base,"%R~",3); + base = sdscatlen(base, "%R~", 3); } else if (pat->flags == ACL_WRITE_PERMISSION) { - base = sdscatlen(base,"%W~",3); + base = sdscatlen(base, "%W~", 3); } else { serverPanic("Invalid key pattern flag detected"); } @@ -369,13 +374,13 @@ aclSelector *ACLCreateSelector(int flags) { selector->allowed_firstargs = NULL; selector->command_rules = sdsempty(); - listSetMatchMethod(selector->patterns,ACLListMatchKeyPattern); - listSetFreeMethod(selector->patterns,ACLListFreeKeyPattern); - listSetDupMethod(selector->patterns,ACLListDupKeyPattern); - listSetMatchMethod(selector->channels,ACLListMatchSds); - listSetFreeMethod(selector->channels,ACLListFreeSds); - listSetDupMethod(selector->channels,ACLListDupSds); - memset(selector->allowed_commands,0,sizeof(selector->allowed_commands)); + listSetMatchMethod(selector->patterns, ACLListMatchKeyPattern); + listSetFreeMethod(selector->patterns, ACLListFreeKeyPattern); + listSetDupMethod(selector->patterns, ACLListDupKeyPattern); + listSetMatchMethod(selector->channels, ACLListMatchSds); + listSetFreeMethod(selector->channels, ACLListFreeSds); + listSetDupMethod(selector->channels, ACLListDupSds); + memset(selector->allowed_commands, 0, sizeof(selector->allowed_commands)); return selector; } @@ -396,13 +401,14 @@ aclSelector *ACLCopySelector(aclSelector *src) { dst->patterns = listDup(src->patterns); dst->channels = listDup(src->channels); dst->command_rules = sdsdup(src->command_rules); - memcpy(dst->allowed_commands,src->allowed_commands, - sizeof(dst->allowed_commands)); + memcpy(dst->allowed_commands, src->allowed_commands, sizeof(dst->allowed_commands)); dst->allowed_firstargs = NULL; /* Copy the allowed first-args array of array of SDS strings. */ if (src->allowed_firstargs) { for (int j = 0; j < USER_COMMAND_BITS_COUNT; j++) { - if (!(src->allowed_firstargs[j])) continue; + if (!(src->allowed_firstargs[j])) { + continue; + } for (int i = 0; src->allowed_firstargs[j][i]; i++) { ACLAddAllowedFirstArg(dst, j, src->allowed_firstargs[j][i]); } @@ -413,7 +419,7 @@ aclSelector *ACLCopySelector(aclSelector *src) { /* List method for freeing a selector */ void ACLListFreeSelector(void *a) { - ACLFreeSelector((aclSelector *) a); + ACLFreeSelector((aclSelector *)a); } /* List method for duplicating a selector */ @@ -426,7 +432,7 @@ void *ACLListDuplicateSelector(void *src) { * permissions. */ aclSelector *ACLUserGetRootSelector(user *u) { serverAssert(listLength(u->selectors)); - aclSelector *s = (aclSelector *) listNodeValue(listFirst(u->selectors)); + aclSelector *s = (aclSelector *)listNodeValue(listFirst(u->selectors)); serverAssert(s->flags & SELECTOR_FLAG_ROOT); return s; } @@ -437,26 +443,28 @@ aclSelector *ACLUserGetRootSelector(user *u) { * * If the user with such name already exists NULL is returned. */ user *ACLCreateUser(const char *name, size_t namelen) { - if (raxFind(Users,(unsigned char*)name,namelen,NULL)) return NULL; + if (raxFind(Users, (unsigned char *)name, namelen, NULL)) { + return NULL; + } user *u = zmalloc(sizeof(*u)); - u->name = sdsnewlen(name,namelen); + u->name = sdsnewlen(name, namelen); u->flags = USER_FLAG_DISABLED; u->flags |= USER_FLAG_SANITIZE_PAYLOAD; u->passwords = listCreate(); u->acl_string = NULL; - listSetMatchMethod(u->passwords,ACLListMatchSds); - listSetFreeMethod(u->passwords,ACLListFreeSds); - listSetDupMethod(u->passwords,ACLListDupSds); + listSetMatchMethod(u->passwords, ACLListMatchSds); + listSetFreeMethod(u->passwords, ACLListFreeSds); + listSetDupMethod(u->passwords, ACLListDupSds); u->selectors = listCreate(); - listSetFreeMethod(u->selectors,ACLListFreeSelector); - listSetDupMethod(u->selectors,ACLListDuplicateSelector); + listSetFreeMethod(u->selectors, ACLListFreeSelector); + listSetDupMethod(u->selectors, ACLListDuplicateSelector); /* Add the initial root selector */ aclSelector *s = ACLCreateSelector(SELECTOR_FLAG_ROOT); listAddNodeHead(u->selectors, s); - raxInsert(Users,(unsigned char*)name,namelen,u,NULL); + raxInsert(Users, (unsigned char *)name, namelen, u, NULL); return u; } @@ -466,12 +474,13 @@ user *ACLCreateUser(const char *name, size_t namelen) { * user should be released with ACLFreeUser() as usually. */ user *ACLCreateUnlinkedUser(void) { char username[64]; - for (int j = 0; ; j++) { - snprintf(username,sizeof(username),"__fakeuser:%d__",j); - user *fakeuser = ACLCreateUser(username,strlen(username)); - if (fakeuser == NULL) continue; - int retval = raxRemove(Users,(unsigned char*) username, - strlen(username),NULL); + for (int j = 0;; j++) { + snprintf(username, sizeof(username), "__fakeuser:%d__", j); + user *fakeuser = ACLCreateUser(username, strlen(username)); + if (fakeuser == NULL) { + continue; + } + int retval = raxRemove(Users, (unsigned char *)username, strlen(username), NULL); serverAssert(retval != 0); return fakeuser; } @@ -496,7 +505,7 @@ void ACLFreeUser(user *u) { void ACLFreeUserAndKillClients(user *u) { listIter li; listNode *ln; - listRewind(server.clients,&li); + listRewind(server.clients, &li); while ((ln = listNext(&li)) != NULL) { client *c = listNodeValue(ln); if (c->user == u) { @@ -546,7 +555,9 @@ void ACLCopyUser(user *dst, user *src) { * bit. The function returns C_ERR in case the specified ID overflows * the bitmap in the user representation. */ int ACLGetCommandBitCoordinates(uint64_t id, uint64_t *word, uint64_t *bit) { - if (id >= USER_COMMAND_BITS_COUNT) return C_ERR; + if (id >= USER_COMMAND_BITS_COUNT) { + return C_ERR; + } *word = id / sizeof(uint64_t) / 8; *bit = 1ULL << (id % (sizeof(uint64_t) * 8)); return C_OK; @@ -561,7 +572,9 @@ int ACLGetCommandBitCoordinates(uint64_t id, uint64_t *word, uint64_t *bit) { * in order to disallow the execution of the command in such edge case. */ int ACLGetSelectorCommandBit(const aclSelector *selector, unsigned long id) { uint64_t word, bit; - if (ACLGetCommandBitCoordinates(id,&word,&bit) == C_ERR) return 0; + if (ACLGetCommandBitCoordinates(id, &word, &bit) == C_ERR) { + return 0; + } return (selector->allowed_commands[word] & bit) != 0; } @@ -569,7 +582,7 @@ int ACLGetSelectorCommandBit(const aclSelector *selector, unsigned long id) { * can later test, to see if the user has the right to execute "future commands", * that is, commands loaded later via modules. */ int ACLSelectorCanExecuteFutureCommands(aclSelector *selector) { - return ACLGetSelectorCommandBit(selector,USER_COMMAND_BITS_COUNT-1); + return ACLGetSelectorCommandBit(selector, USER_COMMAND_BITS_COUNT - 1); } /* Set the specified command bit for the specified user to 'value' (0 or 1). @@ -579,7 +592,9 @@ int ACLSelectorCanExecuteFutureCommands(aclSelector *selector) { * to skip the command bit explicit test. */ void ACLSetSelectorCommandBit(aclSelector *selector, unsigned long id, int value) { uint64_t word, bit; - if (ACLGetCommandBitCoordinates(id,&word,&bit) == C_ERR) return; + if (ACLGetCommandBitCoordinates(id, &word, &bit) == C_ERR) { + return; + } if (value) { selector->allowed_commands[word] |= bit; } else { @@ -589,7 +604,7 @@ void ACLSetSelectorCommandBit(aclSelector *selector, unsigned long id, int value } /* Remove a rule from the retained command rules. Always match rules - * verbatim, but also remove subcommand rules if we are adding or removing the + * verbatim, but also remove subcommand rules if we are adding or removing the * entire command. */ void ACLSelectorRemoveCommandRule(aclSelector *selector, sds new_rule) { size_t new_len = sdslen(new_rule); @@ -598,7 +613,7 @@ void ACLSelectorRemoveCommandRule(aclSelector *selector, sds new_rule) { /* Loop over the existing rules, trying to find a rule that "matches" * the new rule. If we find a match, then remove the command from the string by * copying the later rules over it. */ - while(existing_rule[0]) { + while (existing_rule[0]) { /* The first character of the rule is +/-, which we don't need to compare. */ char *copy_position = existing_rule; existing_rule += 1; @@ -612,10 +627,14 @@ void ACLSelectorRemoveCommandRule(aclSelector *selector, sds new_rule) { /* This approach can leave a trailing space if the last rule is removed, * but only if it's not the first rule, so handle that case. */ - if (copy_position != selector->command_rules) copy_position -= 1; + if (copy_position != selector->command_rules) { + copy_position -= 1; + } } char *copy_end = rule_end; - if (*copy_end == ' ') copy_end++; + if (*copy_end == ' ') { + copy_end++; + } /* Exact match or the rule we are comparing is a subcommand denoted by '|' */ size_t existing_len = rule_end - existing_rule; @@ -642,7 +661,9 @@ void ACLUpdateCommandRules(aclSelector *selector, const char *rule, int allow) { sdstolower(new_rule); ACLSelectorRemoveCommandRule(selector, new_rule); - if (sdslen(selector->command_rules)) selector->command_rules = sdscat(selector->command_rules, " "); + if (sdslen(selector->command_rules)) { + selector->command_rules = sdscat(selector->command_rules, " "); + } selector->command_rules = sdscatfmt(selector->command_rules, allow ? "+%S" : "-%S", new_rule); sdsfree(new_rule); } @@ -651,14 +672,14 @@ void ACLUpdateCommandRules(aclSelector *selector, const char *rule, int allow) { * Allowing/blocking a container command also applies for its subcommands */ void ACLChangeSelectorPerm(aclSelector *selector, struct serverCommand *cmd, int allow) { unsigned long id = cmd->id; - ACLSetSelectorCommandBit(selector,id,allow); - ACLResetFirstArgsForCommand(selector,id); + ACLSetSelectorCommandBit(selector, id, allow); + ACLResetFirstArgsForCommand(selector, id); if (cmd->subcommands_dict) { dictEntry *de; dictIterator *di = dictGetSafeIterator(cmd->subcommands_dict); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { struct serverCommand *sub = (struct serverCommand *)dictGetVal(de); - ACLSetSelectorCommandBit(selector,sub->id,allow); + ACLSetSelectorCommandBit(selector, sub->id, allow); } dictReleaseIterator(di); } @@ -676,7 +697,7 @@ void ACLSetSelectorCommandBitsForCategory(dict *commands, aclSelector *selector, while ((de = dictNext(di)) != NULL) { struct serverCommand *cmd = dictGetVal(de); if (cmd->acl_categories & cflag) { - ACLChangeSelectorPerm(selector,cmd,value); + ACLChangeSelectorPerm(selector, cmd, value); } if (cmd->subcommands_dict) { ACLSetSelectorCommandBitsForCategory(cmd->subcommands_dict, selector, cflag, value); @@ -686,33 +707,33 @@ void ACLSetSelectorCommandBitsForCategory(dict *commands, aclSelector *selector, } /* This function is responsible for recomputing the command bits for all selectors of the existing users. - * It uses the 'command_rules', a string representation of the ordered categories and commands, + * It uses the 'command_rules', a string representation of the ordered categories and commands, * to recompute the command bits. */ void ACLRecomputeCommandBitsFromCommandRulesAllUsers(void) { raxIterator ri; - raxStart(&ri,Users); - raxSeek(&ri,"^",NULL,0); - while(raxNext(&ri)) { + raxStart(&ri, Users); + raxSeek(&ri, "^", NULL, 0); + while (raxNext(&ri)) { user *u = ri.data; listIter li; listNode *ln; - listRewind(u->selectors,&li); - while((ln = listNext(&li))) { - aclSelector *selector = (aclSelector *) listNodeValue(ln); + listRewind(u->selectors, &li); + while ((ln = listNext(&li))) { + aclSelector *selector = (aclSelector *)listNodeValue(ln); int argc = 0; sds *argv = sdssplitargs(selector->command_rules, &argc); serverAssert(argv != NULL); /* Checking selector's permissions for all commands to start with a clean state. */ if (ACLSelectorCanExecuteFutureCommands(selector)) { - int res = ACLSetSelector(selector,"+@all",-1); + int res = ACLSetSelector(selector, "+@all", -1); serverAssert(res == C_OK); } else { - int res = ACLSetSelector(selector,"-@all",-1); + int res = ACLSetSelector(selector, "-@all", -1); serverAssert(res == C_OK); } /* Apply all of the commands and categories to this selector. */ - for(int i = 0; i < argc; i++) { + for (int i = 0; i < argc; i++) { int res = ACLSetSelector(selector, argv[i], sdslen(argv[i])); serverAssert(res == C_OK); } @@ -720,12 +741,13 @@ void ACLRecomputeCommandBitsFromCommandRulesAllUsers(void) { } } raxStop(&ri); - } int ACLSetSelectorCategory(aclSelector *selector, const char *category, int allow) { uint64_t cflag = ACLGetCommandCategoryFlagByName(category + 1); - if (!cflag) return C_ERR; + if (!cflag) { + return C_ERR; + } ACLUpdateCommandRules(selector, category, allow); @@ -734,16 +756,18 @@ int ACLSetSelectorCategory(aclSelector *selector, const char *category, int allo return C_OK; } -void ACLCountCategoryBitsForCommands(dict *commands, aclSelector *selector, unsigned long *on, unsigned long *off, uint64_t cflag) { +void ACLCountCategoryBitsForCommands(dict *commands, aclSelector *selector, unsigned long *on, unsigned long *off, + uint64_t cflag) { dictIterator *di = dictGetIterator(commands); dictEntry *de; while ((de = dictNext(di)) != NULL) { struct serverCommand *cmd = dictGetVal(de); if (cmd->acl_categories & cflag) { - if (ACLGetSelectorCommandBit(selector,cmd->id)) + if (ACLGetSelectorCommandBit(selector, cmd->id)) { (*on)++; - else + } else { (*off)++; + } } if (cmd->subcommands_dict) { ACLCountCategoryBitsForCommands(cmd->subcommands_dict, selector, on, off, cflag); @@ -757,10 +781,11 @@ void ACLCountCategoryBitsForCommands(dict *commands, aclSelector *selector, unsi * If the category name is not valid, C_ERR is returned, otherwise C_OK is * returned and on and off are populated by reference. */ int ACLCountCategoryBitsForSelector(aclSelector *selector, unsigned long *on, unsigned long *off, - const char *category) -{ + const char *category) { uint64_t cflag = ACLGetCommandCategoryFlagByName(category); - if (!cflag) return C_ERR; + if (!cflag) { + return C_ERR; + } *on = *off = 0; ACLCountCategoryBitsForCommands(server.orig_commands, selector, on, off, cflag); @@ -788,11 +813,11 @@ sds ACLDescribeSelectorCommandRules(aclSelector *selector) { * How do we test for that? We use the trick of a reserved command ID bit * that is set only by +@all (and its alias "allcommands"). */ if (ACLSelectorCanExecuteFutureCommands(selector)) { - rules = sdscat(rules,"+@all "); - ACLSetSelector(fake_selector,"+@all",-1); + rules = sdscat(rules, "+@all "); + ACLSetSelector(fake_selector, "+@all", -1); } else { - rules = sdscat(rules,"-@all "); - ACLSetSelector(fake_selector,"-@all",-1); + rules = sdscat(rules, "-@all "); + ACLSetSelector(fake_selector, "-@all", -1); } /* Apply all of the commands and categories to the fake selector. */ @@ -800,7 +825,7 @@ sds ACLDescribeSelectorCommandRules(aclSelector *selector) { sds *argv = sdssplitargs(selector->command_rules, &argc); serverAssert(argv != NULL); - for(int i = 0; i < argc; i++) { + for (int i = 0; i < argc; i++) { int res = ACLSetSelector(fake_selector, argv[i], -1); serverAssert(res == C_OK); } @@ -810,19 +835,14 @@ sds ACLDescribeSelectorCommandRules(aclSelector *selector) { sdsfreesplitres(argv, argc); /* Trim the final useless space. */ - sdsrange(rules,0,-2); + sdsrange(rules, 0, -2); /* This is technically not needed, but we want to verify that now the * predicted bitmap is exactly the same as the user bitmap, and abort * otherwise, because aborting is better than a security risk in this * code path. */ - if (memcmp(fake_selector->allowed_commands, - selector->allowed_commands, - sizeof(selector->allowed_commands)) != 0) - { - serverLog(LL_WARNING, - "CRITICAL ERROR: User ACLs don't match final bitmap: '%s'", - rules); + if (memcmp(fake_selector->allowed_commands, selector->allowed_commands, sizeof(selector->allowed_commands)) != 0) { + serverLog(LL_WARNING, "CRITICAL ERROR: User ACLs don't match final bitmap: '%s'", rules); serverPanic("No bitmap match in ACLDescribeSelectorCommandRules()"); } ACLFreeSelector(fake_selector); @@ -835,33 +855,33 @@ sds ACLDescribeSelector(aclSelector *selector) { sds res = sdsempty(); /* Key patterns. */ if (selector->flags & SELECTOR_FLAG_ALLKEYS) { - res = sdscatlen(res,"~* ",3); + res = sdscatlen(res, "~* ", 3); } else { - listRewind(selector->patterns,&li); - while((ln = listNext(&li))) { + listRewind(selector->patterns, &li); + while ((ln = listNext(&li))) { keyPattern *thispat = (keyPattern *)listNodeValue(ln); res = sdsCatPatternString(res, thispat); - res = sdscatlen(res," ",1); + res = sdscatlen(res, " ", 1); } } /* Pub/sub channel patterns. */ if (selector->flags & SELECTOR_FLAG_ALLCHANNELS) { - res = sdscatlen(res,"&* ",3); + res = sdscatlen(res, "&* ", 3); } else { - res = sdscatlen(res,"resetchannels ",14); - listRewind(selector->channels,&li); - while((ln = listNext(&li))) { + res = sdscatlen(res, "resetchannels ", 14); + listRewind(selector->channels, &li); + while ((ln = listNext(&li))) { sds thispat = listNodeValue(ln); - res = sdscatlen(res,"&",1); - res = sdscatsds(res,thispat); - res = sdscatlen(res," ",1); + res = sdscatlen(res, "&", 1); + res = sdscatsds(res, thispat); + res = sdscatlen(res, " ", 1); } } /* Command rules. */ sds rules = ACLDescribeSelectorCommandRules(selector); - res = sdscatsds(res,rules); + res = sdscatsds(res, rules); sdsfree(rules); return res; } @@ -883,26 +903,26 @@ robj *ACLDescribeUser(user *u) { /* Flags. */ for (int j = 0; ACLUserFlags[j].flag; j++) { if (u->flags & ACLUserFlags[j].flag) { - res = sdscat(res,ACLUserFlags[j].name); - res = sdscatlen(res," ",1); + res = sdscat(res, ACLUserFlags[j].name); + res = sdscatlen(res, " ", 1); } } /* Passwords. */ listIter li; listNode *ln; - listRewind(u->passwords,&li); - while((ln = listNext(&li))) { + listRewind(u->passwords, &li); + while ((ln = listNext(&li))) { sds thispass = listNodeValue(ln); - res = sdscatlen(res,"#",1); - res = sdscatsds(res,thispass); - res = sdscatlen(res," ",1); + res = sdscatlen(res, "#", 1); + res = sdscatsds(res, thispass); + res = sdscatlen(res, " ", 1); } /* Selectors (Commands and keys) */ - listRewind(u->selectors,&li); - while((ln = listNext(&li))) { - aclSelector *selector = (aclSelector *) listNodeValue(ln); + listRewind(u->selectors, &li); + while ((ln = listNext(&li))) { + aclSelector *selector = (aclSelector *)listNodeValue(ln); sds default_perm = ACLDescribeSelector(selector); if (selector->flags & SELECTOR_FLAG_ROOT) { res = sdscatfmt(res, "%s", default_perm); @@ -925,7 +945,7 @@ robj *ACLDescribeUser(user *u) { struct serverCommand *ACLLookupCommand(const char *name) { struct serverCommand *cmd; sds sdsname = sdsnew(name); - cmd = lookupCommandBySdsLogic(server.orig_commands,sdsname); + cmd = lookupCommandBySdsLogic(server.orig_commands, sdsname); sdsfree(sdsname); return cmd; } @@ -934,8 +954,9 @@ struct serverCommand *ACLLookupCommand(const char *name) { * and command ID. */ void ACLResetFirstArgsForCommand(aclSelector *selector, unsigned long id) { if (selector->allowed_firstargs && selector->allowed_firstargs[id]) { - for (int i = 0; selector->allowed_firstargs[id][i]; i++) + for (int i = 0; selector->allowed_firstargs[id][i]; i++) { sdsfree(selector->allowed_firstargs[id][i]); + } zfree(selector->allowed_firstargs[id]); selector->allowed_firstargs[id] = NULL; } @@ -945,11 +966,14 @@ void ACLResetFirstArgsForCommand(aclSelector *selector, unsigned long id) { * or similar to return back to the minimal memory usage (and checks to do) * for the user. */ void ACLResetFirstArgs(aclSelector *selector) { - if (selector->allowed_firstargs == NULL) return; + if (selector->allowed_firstargs == NULL) { + return; + } for (int j = 0; j < USER_COMMAND_BITS_COUNT; j++) { if (selector->allowed_firstargs[j]) { - for (int i = 0; selector->allowed_firstargs[j][i]; i++) + for (int i = 0; selector->allowed_firstargs[j][i]; i++) { sdsfree(selector->allowed_firstargs[j][i]); + } zfree(selector->allowed_firstargs[j]); } } @@ -963,7 +987,7 @@ void ACLAddAllowedFirstArg(aclSelector *selector, unsigned long id, const char * /* If this is the first first-arg to be configured for * this user, we have to allocate the first-args array. */ if (selector->allowed_firstargs == NULL) { - selector->allowed_firstargs = zcalloc(USER_COMMAND_BITS_COUNT * sizeof(sds*)); + selector->allowed_firstargs = zcalloc(USER_COMMAND_BITS_COUNT * sizeof(sds *)); } /* We also need to enlarge the allocation pointing to the @@ -972,23 +996,24 @@ void ACLAddAllowedFirstArg(aclSelector *selector, unsigned long id, const char * * make sure the first-arg is not already specified inside. */ long items = 0; if (selector->allowed_firstargs[id]) { - while(selector->allowed_firstargs[id][items]) { + while (selector->allowed_firstargs[id][items]) { /* If it's already here do not add it again. */ - if (!strcasecmp(selector->allowed_firstargs[id][items],sub)) + if (!strcasecmp(selector->allowed_firstargs[id][items], sub)) { return; + } items++; } } /* Now we can make space for the new item (and the null term). */ items += 2; - selector->allowed_firstargs[id] = zrealloc(selector->allowed_firstargs[id], sizeof(sds)*items); - selector->allowed_firstargs[id][items-2] = sdsnew(sub); - selector->allowed_firstargs[id][items-1] = NULL; + selector->allowed_firstargs[id] = zrealloc(selector->allowed_firstargs[id], sizeof(sds) * items); + selector->allowed_firstargs[id][items - 2] = sdsnew(sub); + selector->allowed_firstargs[id][items - 1] = NULL; } -/* Create an ACL selector from the given ACL operations, which should be - * a list of space separate ACL operations that starts and ends +/* Create an ACL selector from the given ACL operations, which should be + * a list of space separate ACL operations that starts and ends * with parentheses. * * If any of the operations are invalid, NULL will be returned instead @@ -1051,34 +1076,26 @@ aclSelector *aclCreateSelectorFromOpSet(const char *opset, size_t opsetlen) { * allchannels Alias for &* * resetchannels Flush the list of allowed channel patterns. */ -int ACLSetSelector(aclSelector *selector, const char* op, size_t oplen) { - if (!strcasecmp(op,"allkeys") || - !strcasecmp(op,"~*")) - { +int ACLSetSelector(aclSelector *selector, const char *op, size_t oplen) { + if (!strcasecmp(op, "allkeys") || !strcasecmp(op, "~*")) { selector->flags |= SELECTOR_FLAG_ALLKEYS; listEmpty(selector->patterns); - } else if (!strcasecmp(op,"resetkeys")) { + } else if (!strcasecmp(op, "resetkeys")) { selector->flags &= ~SELECTOR_FLAG_ALLKEYS; listEmpty(selector->patterns); - } else if (!strcasecmp(op,"allchannels") || - !strcasecmp(op,"&*")) - { + } else if (!strcasecmp(op, "allchannels") || !strcasecmp(op, "&*")) { selector->flags |= SELECTOR_FLAG_ALLCHANNELS; listEmpty(selector->channels); - } else if (!strcasecmp(op,"resetchannels")) { + } else if (!strcasecmp(op, "resetchannels")) { selector->flags &= ~SELECTOR_FLAG_ALLCHANNELS; listEmpty(selector->channels); - } else if (!strcasecmp(op,"allcommands") || - !strcasecmp(op,"+@all")) - { - memset(selector->allowed_commands,255,sizeof(selector->allowed_commands)); + } else if (!strcasecmp(op, "allcommands") || !strcasecmp(op, "+@all")) { + memset(selector->allowed_commands, 255, sizeof(selector->allowed_commands)); selector->flags |= SELECTOR_FLAG_ALLCOMMANDS; sdsclear(selector->command_rules); ACLResetFirstArgs(selector); - } else if (!strcasecmp(op,"nocommands") || - !strcasecmp(op,"-@all")) - { - memset(selector->allowed_commands,0,sizeof(selector->allowed_commands)); + } else if (!strcasecmp(op, "nocommands") || !strcasecmp(op, "-@all")) { + memset(selector->allowed_commands, 0, sizeof(selector->allowed_commands)); selector->flags &= ~SELECTOR_FLAG_ALLCOMMANDS; sdsclear(selector->command_rules); ACLResetFirstArgs(selector); @@ -1107,15 +1124,15 @@ int ACLSetSelector(aclSelector *selector, const char* op, size_t oplen) { flags = ACL_ALL_PERMISSION; } - if (ACLStringHasSpaces(op+offset,oplen-offset)) { + if (ACLStringHasSpaces(op + offset, oplen - offset)) { errno = EINVAL; return C_ERR; } - keyPattern *newpat = ACLKeyPatternCreate(sdsnewlen(op+offset,oplen-offset), flags); - listNode *ln = listSearchKey(selector->patterns,newpat); + keyPattern *newpat = ACLKeyPatternCreate(sdsnewlen(op + offset, oplen - offset), flags); + listNode *ln = listSearchKey(selector->patterns, newpat); /* Avoid re-adding the same key pattern multiple times. */ if (ln == NULL) { - listAddNodeTail(selector->patterns,newpat); + listAddNodeTail(selector->patterns, newpat); } else { ((keyPattern *)listNodeValue(ln))->flags |= flags; ACLKeyPatternFree(newpat); @@ -1126,31 +1143,32 @@ int ACLSetSelector(aclSelector *selector, const char* op, size_t oplen) { errno = EISDIR; return C_ERR; } - if (ACLStringHasSpaces(op+1,oplen-1)) { + if (ACLStringHasSpaces(op + 1, oplen - 1)) { errno = EINVAL; return C_ERR; } - sds newpat = sdsnewlen(op+1,oplen-1); - listNode *ln = listSearchKey(selector->channels,newpat); + sds newpat = sdsnewlen(op + 1, oplen - 1); + listNode *ln = listSearchKey(selector->channels, newpat); /* Avoid re-adding the same channel pattern multiple times. */ - if (ln == NULL) - listAddNodeTail(selector->channels,newpat); - else + if (ln == NULL) { + listAddNodeTail(selector->channels, newpat); + } else { sdsfree(newpat); + } selector->flags &= ~SELECTOR_FLAG_ALLCHANNELS; } else if (op[0] == '+' && op[1] != '@') { - if (strrchr(op,'|') == NULL) { - struct serverCommand *cmd = ACLLookupCommand(op+1); + if (strrchr(op, '|') == NULL) { + struct serverCommand *cmd = ACLLookupCommand(op + 1); if (cmd == NULL) { errno = ENOENT; return C_ERR; } - ACLChangeSelectorPerm(selector,cmd,1); - ACLUpdateCommandRules(selector,cmd->fullname,1); + ACLChangeSelectorPerm(selector, cmd, 1); + ACLUpdateCommandRules(selector, cmd->fullname, 1); } else { /* Split the command and subcommand parts. */ - char *copy = zstrdup(op+1); - char *sub = strrchr(copy,'|'); + char *copy = zstrdup(op + 1); + char *sub = strrchr(copy, '|'); sub[0] = '\0'; sub++; @@ -1181,38 +1199,40 @@ int ACLSetSelector(aclSelector *selector, const char* op, size_t oplen) { if (cmd->subcommands_dict) { /* If user is trying to allow a valid subcommand we can just add its unique ID */ - cmd = ACLLookupCommand(op+1); + cmd = ACLLookupCommand(op + 1); if (cmd == NULL) { zfree(copy); errno = ENOENT; return C_ERR; } - ACLChangeSelectorPerm(selector,cmd,1); + ACLChangeSelectorPerm(selector, cmd, 1); } else { /* If user is trying to use the ACL mech to block SELECT except SELECT 0 or * block DEBUG except DEBUG OBJECT (DEBUG subcommands are not considered * subcommands for now) we use the allowed_firstargs mechanism. */ /* Add the first-arg to the list of valid ones. */ - serverLog(LL_WARNING, "Deprecation warning: Allowing a first arg of an otherwise " - "blocked command is a misuse of ACL and may get disabled " - "in the future (offender: +%s)", op+1); - ACLAddAllowedFirstArg(selector,cmd->id,sub); + serverLog(LL_WARNING, + "Deprecation warning: Allowing a first arg of an otherwise " + "blocked command is a misuse of ACL and may get disabled " + "in the future (offender: +%s)", + op + 1); + ACLAddAllowedFirstArg(selector, cmd->id, sub); } - ACLUpdateCommandRules(selector,op+1,1); + ACLUpdateCommandRules(selector, op + 1, 1); zfree(copy); } } else if (op[0] == '-' && op[1] != '@') { - struct serverCommand *cmd = ACLLookupCommand(op+1); + struct serverCommand *cmd = ACLLookupCommand(op + 1); if (cmd == NULL) { errno = ENOENT; return C_ERR; } - ACLChangeSelectorPerm(selector,cmd,0); - ACLUpdateCommandRules(selector,cmd->fullname,0); + ACLChangeSelectorPerm(selector, cmd, 0); + ACLUpdateCommandRules(selector, cmd->fullname, 0); } else if ((op[0] == '+' || op[0] == '-') && op[1] == '@') { int bitval = op[0] == '+' ? 1 : 0; - if (ACLSetSelectorCategory(selector,op+1,bitval) == C_ERR) { + if (ACLSetSelectorCategory(selector, op + 1, bitval) == C_ERR) { errno = ENOENT; return C_ERR; } @@ -1261,11 +1281,11 @@ int ACLSetSelector(aclSelector *selector, const char* op, size_t oplen) { * parentheses and attach it to the user. Each option should be * space separated. The first character must be ( and the last * character must be ). - * clearselectors Remove all of the currently attached selectors. + * clearselectors Remove all of the currently attached selectors. * Note this does not change the "root" user permissions, * which are the permissions directly applied onto the * user (outside the parentheses). - * + * * Selector options can also be specified by this function, in which case * they update the root selector for the user. * @@ -1300,60 +1320,65 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) { u->acl_string = NULL; } - if (oplen == -1) oplen = strlen(op); - if (oplen == 0) return C_OK; /* Empty string is a no-operation. */ - if (!strcasecmp(op,"on")) { + if (oplen == -1) { + oplen = strlen(op); + } + if (oplen == 0) { + return C_OK; /* Empty string is a no-operation. */ + } + if (!strcasecmp(op, "on")) { u->flags |= USER_FLAG_ENABLED; u->flags &= ~USER_FLAG_DISABLED; - } else if (!strcasecmp(op,"off")) { + } else if (!strcasecmp(op, "off")) { u->flags |= USER_FLAG_DISABLED; u->flags &= ~USER_FLAG_ENABLED; - } else if (!strcasecmp(op,"skip-sanitize-payload")) { + } else if (!strcasecmp(op, "skip-sanitize-payload")) { u->flags |= USER_FLAG_SANITIZE_PAYLOAD_SKIP; u->flags &= ~USER_FLAG_SANITIZE_PAYLOAD; - } else if (!strcasecmp(op,"sanitize-payload")) { + } else if (!strcasecmp(op, "sanitize-payload")) { u->flags &= ~USER_FLAG_SANITIZE_PAYLOAD_SKIP; u->flags |= USER_FLAG_SANITIZE_PAYLOAD; - } else if (!strcasecmp(op,"nopass")) { + } else if (!strcasecmp(op, "nopass")) { u->flags |= USER_FLAG_NOPASS; listEmpty(u->passwords); - } else if (!strcasecmp(op,"resetpass")) { + } else if (!strcasecmp(op, "resetpass")) { u->flags &= ~USER_FLAG_NOPASS; listEmpty(u->passwords); } else if (op[0] == '>' || op[0] == '#') { sds newpass; if (op[0] == '>') { - newpass = ACLHashPassword((unsigned char*)op+1,oplen-1); + newpass = ACLHashPassword((unsigned char *)op + 1, oplen - 1); } else { - if (ACLCheckPasswordHash((unsigned char*)op+1,oplen-1) == C_ERR) { + if (ACLCheckPasswordHash((unsigned char *)op + 1, oplen - 1) == C_ERR) { errno = EBADMSG; return C_ERR; } - newpass = sdsnewlen(op+1,oplen-1); + newpass = sdsnewlen(op + 1, oplen - 1); } - listNode *ln = listSearchKey(u->passwords,newpass); + listNode *ln = listSearchKey(u->passwords, newpass); /* Avoid re-adding the same password multiple times. */ - if (ln == NULL) - listAddNodeTail(u->passwords,newpass); - else + if (ln == NULL) { + listAddNodeTail(u->passwords, newpass); + } else { sdsfree(newpass); + } u->flags &= ~USER_FLAG_NOPASS; } else if (op[0] == '<' || op[0] == '!') { sds delpass; if (op[0] == '<') { - delpass = ACLHashPassword((unsigned char*)op+1,oplen-1); + delpass = ACLHashPassword((unsigned char *)op + 1, oplen - 1); } else { - if (ACLCheckPasswordHash((unsigned char*)op+1,oplen-1) == C_ERR) { + if (ACLCheckPasswordHash((unsigned char *)op + 1, oplen - 1) == C_ERR) { errno = EBADMSG; return C_ERR; } - delpass = sdsnewlen(op+1,oplen-1); + delpass = sdsnewlen(op + 1, oplen - 1); } - listNode *ln = listSearchKey(u->passwords,delpass); + listNode *ln = listSearchKey(u->passwords, delpass); sdsfree(delpass); if (ln) { - listDelNode(u->passwords,ln); + listDelNode(u->passwords, ln); } else { errno = ENODEV; return C_ERR; @@ -1366,26 +1391,27 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) { } listAddNodeTail(u->selectors, selector); return C_OK; - } else if (!strcasecmp(op,"clearselectors")) { + } else if (!strcasecmp(op, "clearselectors")) { listIter li; listNode *ln; - listRewind(u->selectors,&li); + listRewind(u->selectors, &li); /* There has to be a root selector */ serverAssert(listNext(&li)); - while((ln = listNext(&li))) { + while ((ln = listNext(&li))) { listDelNode(u->selectors, ln); } return C_OK; - } else if (!strcasecmp(op,"reset")) { - serverAssert(ACLSetUser(u,"resetpass",-1) == C_OK); - serverAssert(ACLSetUser(u,"resetkeys",-1) == C_OK); - serverAssert(ACLSetUser(u,"resetchannels",-1) == C_OK); - if (server.acl_pubsub_default & SELECTOR_FLAG_ALLCHANNELS) - serverAssert(ACLSetUser(u,"allchannels",-1) == C_OK); - serverAssert(ACLSetUser(u,"off",-1) == C_OK); - serverAssert(ACLSetUser(u,"sanitize-payload",-1) == C_OK); - serverAssert(ACLSetUser(u,"clearselectors",-1) == C_OK); - serverAssert(ACLSetUser(u,"-@all",-1) == C_OK); + } else if (!strcasecmp(op, "reset")) { + serverAssert(ACLSetUser(u, "resetpass", -1) == C_OK); + serverAssert(ACLSetUser(u, "resetkeys", -1) == C_OK); + serverAssert(ACLSetUser(u, "resetchannels", -1) == C_OK); + if (server.acl_pubsub_default & SELECTOR_FLAG_ALLCHANNELS) { + serverAssert(ACLSetUser(u, "allchannels", -1) == C_OK); + } + serverAssert(ACLSetUser(u, "off", -1) == C_OK); + serverAssert(ACLSetUser(u, "sanitize-payload", -1) == C_OK); + serverAssert(ACLSetUser(u, "clearselectors", -1) == C_OK); + serverAssert(ACLSetUser(u, "-@all", -1) == C_OK); } else { aclSelector *selector = ACLUserGetRootSelector(u); if (ACLSetSelector(selector, op, oplen) == C_ERR) { @@ -1399,42 +1425,43 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) { * the errno value set by the function on error. */ const char *ACLSetUserStringError(void) { const char *errmsg = "Wrong format"; - if (errno == ENOENT) + if (errno == ENOENT) { errmsg = "Unknown command or category name in ACL"; - else if (errno == EINVAL) + } else if (errno == EINVAL) { errmsg = "Syntax error"; - else if (errno == EEXIST) + } else if (errno == EEXIST) { errmsg = "Adding a pattern after the * pattern (or the " "'allkeys' flag) is not valid and does not have any " "effect. Try 'resetkeys' to start with an empty " "list of patterns"; - else if (errno == EISDIR) + } else if (errno == EISDIR) { errmsg = "Adding a pattern after the * pattern (or the " "'allchannels' flag) is not valid and does not have any " "effect. Try 'resetchannels' to start with an empty " "list of channels"; - else if (errno == ENODEV) + } else if (errno == ENODEV) { errmsg = "The password you are trying to remove from the user does " "not exist"; - else if (errno == EBADMSG) + } else if (errno == EBADMSG) { errmsg = "The password hash must be exactly 64 characters and contain " "only lowercase hexadecimal characters"; - else if (errno == EALREADY) + } else if (errno == EALREADY) { errmsg = "Duplicate user found. A user can only be defined once in " "config files"; - else if (errno == ECHILD) + } else if (errno == ECHILD) { errmsg = "Allowing first-arg of a subcommand is not supported"; + } return errmsg; } /* Create the default user, this has special permissions. */ user *ACLCreateDefaultUser(void) { - user *new = ACLCreateUser("default",7); - ACLSetUser(new,"+@all",-1); - ACLSetUser(new,"~*",-1); - ACLSetUser(new,"&*",-1); - ACLSetUser(new,"on",-1); - ACLSetUser(new,"nopass",-1); + user *new = ACLCreateUser("default", 7); + ACLSetUser(new, "+@all", -1); + ACLSetUser(new, "~*", -1); + ACLSetUser(new, "&*", -1); + ACLSetUser(new, "on", -1); + ACLSetUser(new, "nopass", -1); return new; } @@ -1455,7 +1482,7 @@ void ACLInit(void) { * ENOENT: if the specified user does not exist at all. */ int ACLCheckUserCredentials(robj *username, robj *password) { - user *u = ACLGetUserByName(username->ptr,sdslen(username->ptr)); + user *u = ACLGetUserByName(username->ptr, sdslen(username->ptr)); if (u == NULL) { errno = ENOENT; return C_ERR; @@ -1469,14 +1496,16 @@ int ACLCheckUserCredentials(robj *username, robj *password) { /* If the user is configured to don't require any password, we * are already fine here. */ - if (u->flags & USER_FLAG_NOPASS) return C_OK; + if (u->flags & USER_FLAG_NOPASS) { + return C_OK; + } /* Check all the user passwords for at least one to match. */ listIter li; listNode *ln; - listRewind(u->passwords,&li); - sds hashed = ACLHashPassword(password->ptr,sdslen(password->ptr)); - while((ln = listNext(&li))) { + listRewind(u->passwords, &li); + sds hashed = ACLHashPassword(password->ptr, sdslen(password->ptr)); + while ((ln = listNext(&li))) { sds thispass = listNodeValue(ln); if (!time_independent_strcmp(hashed, thispass, HASH_PASSWORD_LEN)) { sdsfree(hashed); @@ -1493,7 +1522,9 @@ int ACLCheckUserCredentials(robj *username, robj *password) { /* If `err` is provided, this is added as an error reply to the client. * Otherwise, the standard Auth error is added as a reply. */ void addAuthErrReply(client *c, robj *err) { - if (clientHasPendingReplies(c)) return; + if (clientHasPendingReplies(c)) { + return; + } if (!err) { addReplyError(c, "-WRONGPASS invalid username-password pair or user is disabled."); return; @@ -1507,13 +1538,14 @@ void addAuthErrReply(client *c, robj *err) { * * The return value is AUTH_OK on success (valid username / password pair) & AUTH_ERR otherwise. */ int checkPasswordBasedAuth(client *c, robj *username, robj *password) { - if (ACLCheckUserCredentials(username,password) == C_OK) { + if (ACLCheckUserCredentials(username, password) == C_OK) { c->authenticated = 1; - c->user = ACLGetUserByName(username->ptr,sdslen(username->ptr)); + c->user = ACLGetUserByName(username->ptr, sdslen(username->ptr)); moduleNotifyUserChanged(c); return AUTH_OK; } else { - addACLLogEntry(c,ACL_DENIED_AUTH,(c->flags & CLIENT_MULTI) ? ACL_LOG_CTX_MULTI : ACL_LOG_CTX_TOPLEVEL,0,username->ptr,NULL); + addACLLogEntry(c, ACL_DENIED_AUTH, (c->flags & CLIENT_MULTI) ? ACL_LOG_CTX_MULTI : ACL_LOG_CTX_TOPLEVEL, 0, + username->ptr, NULL); return AUTH_ERR; } } @@ -1546,14 +1578,15 @@ int ACLAuthenticateUser(client *c, robj *username, robj *password, robj **err) { unsigned long ACLGetCommandID(sds cmdname) { sds lowername = sdsdup(cmdname); sdstolower(lowername); - if (commandId == NULL) commandId = raxNew(); + if (commandId == NULL) { + commandId = raxNew(); + } void *id; - if (raxFind(commandId,(unsigned char*)lowername,sdslen(lowername),&id)) { + if (raxFind(commandId, (unsigned char *)lowername, sdslen(lowername), &id)) { sdsfree(lowername); return (unsigned long)id; } - raxInsert(commandId,(unsigned char*)lowername,strlen(lowername), - (void*)nextid,NULL); + raxInsert(commandId, (unsigned char *)lowername, strlen(lowername), (void *)nextid, NULL); sdsfree(lowername); unsigned long thisid = nextid; nextid++; @@ -1566,13 +1599,17 @@ unsigned long ACLGetCommandID(sds cmdname) { * and command categories from scratch, not allowing future commands by * default (loaded via modules). This is useful when rewriting the ACLs * with ACL SAVE. */ - if (nextid == USER_COMMAND_BITS_COUNT-1) nextid++; + if (nextid == USER_COMMAND_BITS_COUNT - 1) { + nextid++; + } return thisid; } /* Clear command id table and reset nextid to 0. */ void ACLClearCommandID(void) { - if (commandId) raxFree(commandId); + if (commandId) { + raxFree(commandId); + } commandId = NULL; nextid = 0; } @@ -1580,7 +1617,7 @@ void ACLClearCommandID(void) { /* Return an username by its name, or NULL if the user does not exist. */ user *ACLGetUserByName(const char *name, size_t namelen) { void *myuser = NULL; - raxFind(Users,(unsigned char*)name,namelen,&myuser); + raxFind(Users, (unsigned char *)name, namelen, &myuser); return myuser; } @@ -1594,66 +1631,89 @@ user *ACLGetUserByName(const char *name, size_t namelen) { * ACL_DENIED_KEY is returned. */ static int ACLSelectorCheckKey(aclSelector *selector, const char *key, int keylen, int keyspec_flags) { /* The selector can access any key */ - if (selector->flags & SELECTOR_FLAG_ALLKEYS) return ACL_OK; + if (selector->flags & SELECTOR_FLAG_ALLKEYS) { + return ACL_OK; + } listIter li; listNode *ln; - listRewind(selector->patterns,&li); + listRewind(selector->patterns, &li); int key_flags = 0; - if (keyspec_flags & CMD_KEY_ACCESS) key_flags |= ACL_READ_PERMISSION; - if (keyspec_flags & CMD_KEY_INSERT) key_flags |= ACL_WRITE_PERMISSION; - if (keyspec_flags & CMD_KEY_DELETE) key_flags |= ACL_WRITE_PERMISSION; - if (keyspec_flags & CMD_KEY_UPDATE) key_flags |= ACL_WRITE_PERMISSION; + if (keyspec_flags & CMD_KEY_ACCESS) { + key_flags |= ACL_READ_PERMISSION; + } + if (keyspec_flags & CMD_KEY_INSERT) { + key_flags |= ACL_WRITE_PERMISSION; + } + if (keyspec_flags & CMD_KEY_DELETE) { + key_flags |= ACL_WRITE_PERMISSION; + } + if (keyspec_flags & CMD_KEY_UPDATE) { + key_flags |= ACL_WRITE_PERMISSION; + } /* Test this key against every pattern. */ - while((ln = listNext(&li))) { + while ((ln = listNext(&li))) { keyPattern *pattern = listNodeValue(ln); - if ((pattern->flags & key_flags) != key_flags) + if ((pattern->flags & key_flags) != key_flags) { continue; + } size_t plen = sdslen(pattern->pattern); - if (stringmatchlen(pattern->pattern,plen,key,keylen,0)) + if (stringmatchlen(pattern->pattern, plen, key, keylen, 0)) { return ACL_OK; + } } return ACL_DENIED_KEY; } /* Checks if the provided selector selector has access specified in flags * to all keys in the keyspace. For example, CMD_KEY_READ access requires either - * '%R~*', '~*', or allkeys to be granted to the selector. Returns 1 if all + * '%R~*', '~*', or allkeys to be granted to the selector. Returns 1 if all * the access flags are satisfied with this selector or 0 otherwise. */ static int ACLSelectorHasUnrestrictedKeyAccess(aclSelector *selector, int flags) { /* The selector can access any key */ - if (selector->flags & SELECTOR_FLAG_ALLKEYS) return 1; + if (selector->flags & SELECTOR_FLAG_ALLKEYS) { + return 1; + } listIter li; listNode *ln; - listRewind(selector->patterns,&li); + listRewind(selector->patterns, &li); int access_flags = 0; - if (flags & CMD_KEY_ACCESS) access_flags |= ACL_READ_PERMISSION; - if (flags & CMD_KEY_INSERT) access_flags |= ACL_WRITE_PERMISSION; - if (flags & CMD_KEY_DELETE) access_flags |= ACL_WRITE_PERMISSION; - if (flags & CMD_KEY_UPDATE) access_flags |= ACL_WRITE_PERMISSION; + if (flags & CMD_KEY_ACCESS) { + access_flags |= ACL_READ_PERMISSION; + } + if (flags & CMD_KEY_INSERT) { + access_flags |= ACL_WRITE_PERMISSION; + } + if (flags & CMD_KEY_DELETE) { + access_flags |= ACL_WRITE_PERMISSION; + } + if (flags & CMD_KEY_UPDATE) { + access_flags |= ACL_WRITE_PERMISSION; + } /* Test this key against every pattern. */ - while((ln = listNext(&li))) { + while ((ln = listNext(&li))) { keyPattern *pattern = listNodeValue(ln); - if ((pattern->flags & access_flags) != access_flags) + if ((pattern->flags & access_flags) != access_flags) { continue; - if (!strcmp(pattern->pattern,"*")) { - return 1; - } + } + if (!strcmp(pattern->pattern, "*")) { + return 1; + } } return 0; } -/* Checks a channel against a provided list of channels. The is_pattern +/* Checks a channel against a provided list of channels. The is_pattern * argument should only be used when subscribing (not when publishing) * and controls whether the input channel is evaluated as a channel pattern - * (like in PSUBSCRIBE) or a plain channel name (like in SUBSCRIBE). - * + * (like in PSUBSCRIBE) or a plain channel name (like in SUBSCRIBE). + * * Note that a plain channel name like in PUBLISH or SUBSCRIBE can be * matched against ACL channel patterns, but the pattern provided in PSUBSCRIBE * can only be matched as a literal against an ACL pattern (using plain string compare). */ @@ -1662,14 +1722,13 @@ static int ACLCheckChannelAgainstList(list *reference, const char *channel, int listNode *ln; listRewind(reference, &li); - while((ln = listNext(&li))) { + while ((ln = listNext(&li))) { sds pattern = listNodeValue(ln); size_t plen = sdslen(pattern); /* Channel patterns are matched literally against the channels in * the list. Regular channels perform pattern matching. */ - if ((is_pattern && !strcmp(pattern,channel)) || - (!is_pattern && stringmatchlen(pattern,plen,channel,channellen,0))) - { + if ((is_pattern && !strcmp(pattern, channel)) || + (!is_pattern && stringmatchlen(pattern, plen, channel, channellen, 0))) { return ACL_OK; } } @@ -1688,7 +1747,9 @@ void initACLKeyResultCache(aclKeyResultCache *cache) { } void cleanupACLKeyResultCache(aclKeyResultCache *cache) { - if (cache->keys_init) getKeysFreeResult(&(cache->keys)); + if (cache->keys_init) { + getKeysFreeResult(&(cache->keys)); + } } /* Check if the command is ready to be executed according to the @@ -1699,28 +1760,28 @@ void cleanupACLKeyResultCache(aclKeyResultCache *cache) { * command cannot be executed because the selector is not allowed to run such * command, the second and third if the command is denied because the selector is trying * to access a key or channel that are not among the specified patterns. */ -static int ACLSelectorCheckCmd(aclSelector *selector, struct serverCommand *cmd, robj **argv, int argc, int *keyidxptr, aclKeyResultCache *cache) { +static int ACLSelectorCheckCmd(aclSelector *selector, struct serverCommand *cmd, robj **argv, int argc, int *keyidxptr, + aclKeyResultCache *cache) { uint64_t id = cmd->id; int ret; if (!(selector->flags & SELECTOR_FLAG_ALLCOMMANDS) && !(cmd->flags & CMD_NO_AUTH)) { /* If the bit is not set we have to check further, in case the * command is allowed just with that specific first argument. */ - if (ACLGetSelectorCommandBit(selector,id) == 0) { + if (ACLGetSelectorCommandBit(selector, id) == 0) { /* Check if the first argument matches. */ - if (argc < 2 || - selector->allowed_firstargs == NULL || - selector->allowed_firstargs[id] == NULL) - { + if (argc < 2 || selector->allowed_firstargs == NULL || selector->allowed_firstargs[id] == NULL) { return ACL_DENIED_CMD; } long subid = 0; while (1) { - if (selector->allowed_firstargs[id][subid] == NULL) + if (selector->allowed_firstargs[id][subid] == NULL) { return ACL_DENIED_CMD; + } int idx = cmd->parent ? 2 : 1; - if (!strcasecmp(argv[idx]->ptr,selector->allowed_firstargs[id][subid])) + if (!strcasecmp(argv[idx]->ptr, selector->allowed_firstargs[id][subid])) { break; /* First argument match found. Stop here. */ + } subid++; } } @@ -1730,7 +1791,7 @@ static int ACLSelectorCheckCmd(aclSelector *selector, struct serverCommand *cmd, * mentioned in the command arguments. */ if (!(selector->flags & SELECTOR_FLAG_ALLKEYS) && doesCommandHaveKeys(cmd)) { if (!(cache->keys_init)) { - cache->keys = (getKeysResult) GETKEYS_RESULT_INIT; + cache->keys = (getKeysResult)GETKEYS_RESULT_INIT; getKeysFromCommandWithSpecs(cmd, argv, argc, GET_KEYSPEC_DEFAULT, &(cache->keys)); cache->keys_init = 1; } @@ -1740,7 +1801,9 @@ static int ACLSelectorCheckCmd(aclSelector *selector, struct serverCommand *cmd, int idx = resultidx[j].pos; ret = ACLSelectorCheckKey(selector, argv[idx]->ptr, sdslen(argv[idx]->ptr), resultidx[j].flags); if (ret != ACL_OK) { - if (keyidxptr) *keyidxptr = resultidx[j].pos; + if (keyidxptr) { + *keyidxptr = resultidx[j].pos; + } return ret; } } @@ -1750,16 +1813,21 @@ static int ACLSelectorCheckCmd(aclSelector *selector, struct serverCommand *cmd, * mentioned in the command arguments */ const int channel_flags = CMD_CHANNEL_PUBLISH | CMD_CHANNEL_SUBSCRIBE; if (!(selector->flags & SELECTOR_FLAG_ALLCHANNELS) && doesCommandHaveChannelsWithFlags(cmd, channel_flags)) { - getKeysResult channels = (getKeysResult) GETKEYS_RESULT_INIT; + getKeysResult channels = (getKeysResult)GETKEYS_RESULT_INIT; getChannelsFromCommand(cmd, argv, argc, &channels); keyReference *channelref = channels.keys; for (int j = 0; j < channels.numkeys; j++) { int idx = channelref[j].pos; - if (!(channelref[j].flags & channel_flags)) continue; + if (!(channelref[j].flags & channel_flags)) { + continue; + } int is_pattern = channelref[j].flags & CMD_CHANNEL_PATTERN; - int ret = ACLCheckChannelAgainstList(selector->channels, argv[idx]->ptr, sdslen(argv[idx]->ptr), is_pattern); + int ret = + ACLCheckChannelAgainstList(selector->channels, argv[idx]->ptr, sdslen(argv[idx]->ptr), is_pattern); if (ret != ACL_OK) { - if (keyidxptr) *keyidxptr = channelref[j].pos; + if (keyidxptr) { + *keyidxptr = channelref[j].pos; + } getKeysFreeResult(&channels); return ret; } @@ -1780,12 +1848,14 @@ int ACLUserCheckKeyPerm(user *u, const char *key, int keylen, int flags) { listNode *ln; /* If there is no associated user, the connection can run anything. */ - if (u == NULL) return ACL_OK; + if (u == NULL) { + return ACL_OK; + } /* Check all of the selectors */ - listRewind(u->selectors,&li); - while((ln = listNext(&li))) { - aclSelector *s = (aclSelector *) listNodeValue(ln); + listRewind(u->selectors, &li); + while ((ln = listNext(&li))) { + aclSelector *s = (aclSelector *)listNodeValue(ln); if (ACLSelectorCheckKey(s, key, keylen, flags) == ACL_OK) { return ACL_OK; } @@ -1794,9 +1864,9 @@ int ACLUserCheckKeyPerm(user *u, const char *key, int keylen, int flags) { } /* Checks if the user can execute the given command with the added restriction - * it must also have the access specified in flags to any key in the key space. - * For example, CMD_KEY_READ access requires either '%R~*', '~*', or allkeys to be - * granted in addition to the access required by the command. Returns 1 + * it must also have the access specified in flags to any key in the key space. + * For example, CMD_KEY_READ access requires either '%R~*', '~*', or allkeys to be + * granted in addition to the access required by the command. Returns 1 * if the user has access or 0 otherwise. */ int ACLUserCheckCmdWithUnrestrictedKeyAccess(user *u, struct serverCommand *cmd, robj **argv, int argc, int flags) { @@ -1805,7 +1875,9 @@ int ACLUserCheckCmdWithUnrestrictedKeyAccess(user *u, struct serverCommand *cmd, int local_idxptr; /* If there is no associated user, the connection can run anything. */ - if (u == NULL) return 1; + if (u == NULL) { + return 1; + } /* For multiple selectors, we cache the key result in between selector * calls to prevent duplicate lookups. */ @@ -1813,9 +1885,9 @@ int ACLUserCheckCmdWithUnrestrictedKeyAccess(user *u, struct serverCommand *cmd, initACLKeyResultCache(&cache); /* Check each selector sequentially */ - listRewind(u->selectors,&li); - while((ln = listNext(&li))) { - aclSelector *s = (aclSelector *) listNodeValue(ln); + listRewind(u->selectors, &li); + while ((ln = listNext(&li))) { + aclSelector *s = (aclSelector *)listNodeValue(ln); int acl_retval = ACLSelectorCheckCmd(s, cmd, argv, argc, &local_idxptr, &cache); if (acl_retval == ACL_OK && ACLSelectorHasUnrestrictedKeyAccess(s, flags)) { cleanupACLKeyResultCache(&cache); @@ -1836,14 +1908,18 @@ int ACLUserCheckChannelPerm(user *u, sds channel, int is_pattern) { listNode *ln; /* If there is no associated user, the connection can run anything. */ - if (u == NULL) return ACL_OK; + if (u == NULL) { + return ACL_OK; + } /* Check all of the selectors */ - listRewind(u->selectors,&li); - while((ln = listNext(&li))) { - aclSelector *s = (aclSelector *) listNodeValue(ln); + listRewind(u->selectors, &li); + while ((ln = listNext(&li))) { + aclSelector *s = (aclSelector *)listNodeValue(ln); /* The selector can run any keys */ - if (s->flags & SELECTOR_FLAG_ALLCHANNELS) return ACL_OK; + if (s->flags & SELECTOR_FLAG_ALLCHANNELS) { + return ACL_OK; + } /* Otherwise, loop over the selectors list and check each channel */ if (ACLCheckChannelAgainstList(s->channels, channel, sdslen(channel), is_pattern) == ACL_OK) { @@ -1863,7 +1939,9 @@ int ACLCheckAllUserCommandPerm(user *u, struct serverCommand *cmd, robj **argv, listNode *ln; /* If there is no associated user, the connection can run anything. */ - if (u == NULL) return ACL_OK; + if (u == NULL) { + return ACL_OK; + } /* We have to pick a single error to log, the logic for picking is as follows: * 1) If no selector can execute the command, return the command. @@ -1877,17 +1955,15 @@ int ACLCheckAllUserCommandPerm(user *u, struct serverCommand *cmd, robj **argv, initACLKeyResultCache(&cache); /* Check each selector sequentially */ - listRewind(u->selectors,&li); - while((ln = listNext(&li))) { - aclSelector *s = (aclSelector *) listNodeValue(ln); + listRewind(u->selectors, &li); + while ((ln = listNext(&li))) { + aclSelector *s = (aclSelector *)listNodeValue(ln); int acl_retval = ACLSelectorCheckCmd(s, cmd, argv, argc, &local_idxptr, &cache); if (acl_retval == ACL_OK) { cleanupACLKeyResultCache(&cache); return ACL_OK; } - if (acl_retval > relevant_error || - (acl_retval == relevant_error && local_idxptr > last_idx)) - { + if (acl_retval > relevant_error || (acl_retval == relevant_error && local_idxptr > last_idx)) { relevant_error = acl_retval; last_idx = local_idxptr; } @@ -1910,10 +1986,12 @@ list *getUpcomingChannelList(user *new, user *original) { listNode *ln, *lpn; /* Optimization: we check if any selector has all channel permissions. */ - listRewind(new->selectors,&li); - while((ln = listNext(&li))) { - aclSelector *s = (aclSelector *) listNodeValue(ln); - if (s->flags & SELECTOR_FLAG_ALLCHANNELS) return NULL; + listRewind(new->selectors, &li); + while ((ln = listNext(&li))) { + aclSelector *s = (aclSelector *)listNodeValue(ln); + if (s->flags & SELECTOR_FLAG_ALLCHANNELS) { + return NULL; + } } /* Next, check if the new list of channels @@ -1922,19 +2000,19 @@ list *getUpcomingChannelList(user *new, user *original) { * the new user and checking each of the existing channels * against it. */ list *upcoming = listCreate(); - listRewind(new->selectors,&li); - while((ln = listNext(&li))) { - aclSelector *s = (aclSelector *) listNodeValue(ln); + listRewind(new->selectors, &li); + while ((ln = listNext(&li))) { + aclSelector *s = (aclSelector *)listNodeValue(ln); listRewind(s->channels, &lpi); - while((lpn = listNext(&lpi))) { + while ((lpn = listNext(&lpi))) { listAddNodeTail(upcoming, listNodeValue(lpn)); } } int match = 1; - listRewind(original->selectors,&li); - while((ln = listNext(&li)) && match) { - aclSelector *s = (aclSelector *) listNodeValue(ln); + listRewind(original->selectors, &li); + while ((ln = listNext(&li)) && match) { + aclSelector *s = (aclSelector *)listNodeValue(ln); /* If any of the original selectors has the all-channels permission, but * the new ones don't (this is checked earlier in this function), then the * new list is not a strict superset of the original. */ @@ -1943,7 +2021,7 @@ list *getUpcomingChannelList(user *new, user *original) { break; } listRewind(s->channels, &lpi); - while((lpn = listNext(&lpi)) && match) { + while ((lpn = listNext(&lpi)) && match) { if (!listSearchKey(upcoming, listNodeValue(lpn))) { match = 0; break; @@ -2011,13 +2089,15 @@ int ACLShouldKillPubsubClient(client *c, list *upcoming) { * permissions specified via the upcoming argument, and kill them if so. */ void ACLKillPubsubClientsIfNeeded(user *new, user *original) { /* Do nothing if there are no subscribers. */ - if (pubsubTotalSubscriptions() == 0) + if (pubsubTotalSubscriptions() == 0) { return; + } list *channels = getUpcomingChannelList(new, original); /* If the new user's pubsub permissions are a strict superset of the original, return early. */ - if (!channels) + if (!channels) { return; + } listIter li; listNode *ln; @@ -2025,13 +2105,15 @@ void ACLKillPubsubClientsIfNeeded(user *new, user *original) { /* Permissions have changed, so we need to iterate through all * the clients and disconnect those that are no longer valid. * Scan all connected clients to find the user's pub/subs. */ - listRewind(server.clients,&li); + listRewind(server.clients, &li); while ((ln = listNext(&li)) != NULL) { client *c = listNodeValue(ln); - if (c->user != original) + if (c->user != original) { continue; - if (ACLShouldKillPubsubClient(c, channels)) + } + if (ACLShouldKillPubsubClient(c, channels)) { freeClient(c); + } } listRelease(channels); @@ -2043,28 +2125,27 @@ void ACLKillPubsubClientsIfNeeded(user *new, user *original) { /* Selector definitions should be sent as a single argument, however - * we will be lenient and try to find selector definitions spread + * we will be lenient and try to find selector definitions spread * across multiple arguments since it makes for a simpler user experience - * for ACL SETUSER as well as when loading from conf files. - * + * for ACL SETUSER as well as when loading from conf files. + * * This function takes in an array of ACL operators, excluding the username, * and merges selector operations that are spread across multiple arguments. The return - * value is a new SDS array, with length set to the passed in merged_argc. Arguments - * that are untouched are still duplicated. If there is an unmatched parenthesis, NULL + * value is a new SDS array, with length set to the passed in merged_argc. Arguments + * that are untouched are still duplicated. If there is an unmatched parenthesis, NULL * is returned and invalid_idx is set to the argument with the start of the opening * parenthesis. */ sds *ACLMergeSelectorArguments(sds *argv, int argc, int *merged_argc, int *invalid_idx) { *merged_argc = 0; int open_bracket_start = -1; - sds *acl_args = (sds *) zmalloc(sizeof(sds) * argc); + sds *acl_args = (sds *)zmalloc(sizeof(sds) * argc); sds selector = NULL; for (int j = 0; j < argc; j++) { char *op = argv[j]; - if (open_bracket_start == -1 && - (op[0] == '(' && op[sdslen(op) - 1] != ')')) { + if (open_bracket_start == -1 && (op[0] == '(' && op[sdslen(op) - 1] != ')')) { selector = sdsdup(argv[j]); open_bracket_start = j; continue; @@ -2074,7 +2155,7 @@ sds *ACLMergeSelectorArguments(sds *argv, int argc, int *merged_argc, int *inval selector = sdscatfmt(selector, " %s", op); if (op[sdslen(op) - 1] == ')') { open_bracket_start = -1; - acl_args[*merged_argc] = selector; + acl_args[*merged_argc] = selector; (*merged_argc)++; } continue; @@ -2085,10 +2166,14 @@ sds *ACLMergeSelectorArguments(sds *argv, int argc, int *merged_argc, int *inval } if (open_bracket_start != -1) { - for (int i = 0; i < *merged_argc; i++) sdsfree(acl_args[i]); + for (int i = 0; i < *merged_argc; i++) { + sdsfree(acl_args[i]); + } zfree(acl_args); sdsfree(selector); - if (invalid_idx) *invalid_idx = open_bracket_start; + if (invalid_idx) { + *invalid_idx = open_bracket_start; + } return NULL; } @@ -2111,7 +2196,8 @@ sds ACLStringSetUser(user *u, sds username, sds *argv, int argc) { if (!acl_args) { return sdscatfmt(sdsempty(), "Unmatched parenthesis in acl selector starting " - "at '%s'.", (char *) argv[invalid_idx]); + "at '%s'.", + (char *)argv[invalid_idx]); } /* Create a temporary user to validate and stage all changes against @@ -2124,11 +2210,9 @@ sds ACLStringSetUser(user *u, sds username, sds *argv, int argc) { } for (int j = 0; j < merged_argc; j++) { - if (ACLSetUser(tempu,acl_args[j],(ssize_t) sdslen(acl_args[j])) != C_OK) { + if (ACLSetUser(tempu, acl_args[j], (ssize_t)sdslen(acl_args[j])) != C_OK) { const char *errmsg = ACLSetUserStringError(); - error = sdscatfmt(sdsempty(), - "Error in ACL SETUSER modifier '%s': %s", - (char*)acl_args[j], errmsg); + error = sdscatfmt(sdsempty(), "Error in ACL SETUSER modifier '%s': %s", (char *)acl_args[j], errmsg); goto cleanup; } } @@ -2141,7 +2225,7 @@ sds ACLStringSetUser(user *u, sds username, sds *argv, int argc) { /* Overwrite the user with the temporary user we modified above. */ if (!u) { - u = ACLCreateUser(username,sdslen(username)); + u = ACLCreateUser(username, sdslen(username)); } serverAssert(u != NULL); @@ -2176,15 +2260,19 @@ sds ACLStringSetUser(user *u, sds username, sds *argv, int argc) { * by reference (if not set to NULL) the argc_err argument with the index * of the argv vector that caused the error. */ int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err) { - if (argc < 2 || strcasecmp(argv[0],"user")) { - if (argc_err) *argc_err = 0; + if (argc < 2 || strcasecmp(argv[0], "user")) { + if (argc_err) { + *argc_err = 0; + } return C_ERR; } if (listSearchKey(UsersToLoad, argv[1])) { - if (argc_err) *argc_err = 1; + if (argc_err) { + *argc_err = 1; + } errno = EALREADY; - return C_ERR; + return C_ERR; } /* Merged selectors before trying to process */ @@ -2200,11 +2288,15 @@ int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err) { user *fakeuser = ACLCreateUnlinkedUser(); for (int j = 0; j < merged_argc; j++) { - if (ACLSetUser(fakeuser,acl_args[j],sdslen(acl_args[j])) == C_ERR) { + if (ACLSetUser(fakeuser, acl_args[j], sdslen(acl_args[j])) == C_ERR) { if (errno != ENOENT) { ACLFreeUser(fakeuser); - if (argc_err) *argc_err = j; - for (int i = 0; i < merged_argc; i++) sdsfree(acl_args[i]); + if (argc_err) { + *argc_err = j; + } + for (int i = 0; i < merged_argc; i++) { + sdsfree(acl_args[i]); + } zfree(acl_args); return C_ERR; } @@ -2212,13 +2304,17 @@ int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err) { } /* Rules look valid, let's append the user to the list. */ - sds *copy = zmalloc(sizeof(sds)*(merged_argc + 2)); + sds *copy = zmalloc(sizeof(sds) * (merged_argc + 2)); copy[0] = sdsdup(argv[1]); - for (int j = 0; j < merged_argc; j++) copy[j+1] = sdsdup(acl_args[j]); + for (int j = 0; j < merged_argc; j++) { + copy[j + 1] = sdsdup(acl_args[j]); + } copy[merged_argc + 1] = NULL; - listAddNodeTail(UsersToLoad,copy); + listAddNodeTail(UsersToLoad, copy); ACLFreeUser(fakeuser); - for (int i = 0; i < merged_argc; i++) sdsfree(acl_args[i]); + for (int i = 0; i < merged_argc; i++) { + sdsfree(acl_args[i]); + } zfree(acl_args); return C_OK; } @@ -2229,31 +2325,32 @@ int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err) { int ACLLoadConfiguredUsers(void) { listIter li; listNode *ln; - listRewind(UsersToLoad,&li); + listRewind(UsersToLoad, &li); while ((ln = listNext(&li)) != NULL) { sds *aclrules = listNodeValue(ln); sds username = aclrules[0]; - if (ACLStringHasSpaces(aclrules[0],sdslen(aclrules[0]))) { - serverLog(LL_WARNING,"Spaces not allowed in ACL usernames"); + if (ACLStringHasSpaces(aclrules[0], sdslen(aclrules[0]))) { + serverLog(LL_WARNING, "Spaces not allowed in ACL usernames"); return C_ERR; } - user *u = ACLCreateUser(username,sdslen(username)); + user *u = ACLCreateUser(username, sdslen(username)); if (!u) { /* Only valid duplicate user is the default one. */ serverAssert(!strcmp(username, "default")); - u = ACLGetUserByName("default",7); - ACLSetUser(u,"reset",-1); + u = ACLGetUserByName("default", 7); + ACLSetUser(u, "reset", -1); } /* Load every rule defined for this user. */ for (int j = 1; aclrules[j]; j++) { - if (ACLSetUser(u,aclrules[j],sdslen(aclrules[j])) != C_OK) { + if (ACLSetUser(u, aclrules[j], sdslen(aclrules[j])) != C_OK) { const char *errmsg = ACLSetUserStringError(); - serverLog(LL_WARNING,"Error loading ACL rule '%s' for " - "the user named '%s': %s", - aclrules[j],aclrules[0],errmsg); + serverLog(LL_WARNING, + "Error loading ACL rule '%s' for " + "the user named '%s': %s", + aclrules[j], aclrules[0], errmsg); return C_ERR; } } @@ -2261,9 +2358,10 @@ int ACLLoadConfiguredUsers(void) { /* Having a disabled user in the configuration may be an error, * warn about it without returning any error to the caller. */ if (u->flags & USER_FLAG_DISABLED) { - serverLog(LL_NOTICE, "The user '%s' is disabled (there is no " - "'on' modifier in the user description). Make " - "sure this is not a configuration error.", + serverLog(LL_NOTICE, + "The user '%s' is disabled (there is no " + "'on' modifier in the user description). Make " + "sure this is not a configuration error.", aclrules[0]); } } @@ -2298,23 +2396,22 @@ sds ACLLoadFromFile(const char *filename) { char buf[1024]; /* Open the ACL file. */ - if ((fp = fopen(filename,"r")) == NULL) { - sds errors = sdscatprintf(sdsempty(), - "Error loading ACLs, opening file '%s': %s", - filename, strerror(errno)); + if ((fp = fopen(filename, "r")) == NULL) { + sds errors = sdscatprintf(sdsempty(), "Error loading ACLs, opening file '%s': %s", filename, strerror(errno)); return errors; } /* Load the whole file as a single string in memory. */ sds acls = sdsempty(); - while(fgets(buf,sizeof(buf),fp) != NULL) - acls = sdscat(acls,buf); + while (fgets(buf, sizeof(buf), fp) != NULL) { + acls = sdscat(acls, buf); + } fclose(fp); /* Split the file into lines and attempt to load each line. */ int totlines; sds *lines, errors = sdsempty(); - lines = sdssplitlen(acls,strlen(acls),"\n",1,&totlines); + lines = sdssplitlen(acls, strlen(acls), "\n", 1, &totlines); sdsfree(acls); /* We do all the loading in a fresh instance of the Users radix tree, @@ -2327,53 +2424,52 @@ sds ACLLoadFromFile(const char *filename) { for (int i = 0; i < totlines; i++) { sds *argv; int argc; - int linenum = i+1; + int linenum = i + 1; - lines[i] = sdstrim(lines[i]," \t\r\n"); + lines[i] = sdstrim(lines[i], " \t\r\n"); /* Skip blank lines */ - if (lines[i][0] == '\0') continue; + if (lines[i][0] == '\0') { + continue; + } /* Split into arguments */ - argv = sdssplitlen(lines[i],sdslen(lines[i])," ",1,&argc); + argv = sdssplitlen(lines[i], sdslen(lines[i]), " ", 1, &argc); if (argv == NULL) { - errors = sdscatprintf(errors, - "%s:%d: unbalanced quotes in acl line. ", - server.acl_filename, linenum); + errors = sdscatprintf(errors, "%s:%d: unbalanced quotes in acl line. ", server.acl_filename, linenum); continue; } /* Skip this line if the resulting command vector is empty. */ if (argc == 0) { - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); continue; } /* The line should start with the "user" keyword. */ - if (strcmp(argv[0],"user") || argc < 2) { + if (strcmp(argv[0], "user") || argc < 2) { errors = sdscatprintf(errors, - "%s:%d should start with user keyword followed " - "by the username. ", server.acl_filename, - linenum); - sdsfreesplitres(argv,argc); + "%s:%d should start with user keyword followed " + "by the username. ", + server.acl_filename, linenum); + sdsfreesplitres(argv, argc); continue; } /* Spaces are not allowed in usernames. */ - if (ACLStringHasSpaces(argv[1],sdslen(argv[1]))) { - errors = sdscatprintf(errors, - "'%s:%d: username '%s' contains invalid characters. ", - server.acl_filename, linenum, argv[1]); - sdsfreesplitres(argv,argc); + if (ACLStringHasSpaces(argv[1], sdslen(argv[1]))) { + errors = sdscatprintf(errors, "'%s:%d: username '%s' contains invalid characters. ", server.acl_filename, + linenum, argv[1]); + sdsfreesplitres(argv, argc); continue; } - user *u = ACLCreateUser(argv[1],sdslen(argv[1])); + user *u = ACLCreateUser(argv[1], sdslen(argv[1])); /* If the user already exists we assume it's an error and abort. */ if (!u) { - errors = sdscatprintf(errors,"WARNING: Duplicate user '%s' found on line %d. ", argv[1], linenum); - sdsfreesplitres(argv,argc); + errors = sdscatprintf(errors, "WARNING: Duplicate user '%s' found on line %d. ", argv[1], linenum); + sdsfreesplitres(argv, argc); continue; } @@ -2384,63 +2480,61 @@ sds ACLLoadFromFile(const char *filename) { int merged_argc; sds *acl_args = ACLMergeSelectorArguments(argv + 2, argc - 2, &merged_argc, NULL); if (!acl_args) { - errors = sdscatprintf(errors, - "%s:%d: Unmatched parenthesis in selector definition.", - server.acl_filename, linenum); + errors = sdscatprintf(errors, "%s:%d: Unmatched parenthesis in selector definition.", server.acl_filename, + linenum); } int syntax_error = 0; for (int j = 0; j < merged_argc; j++) { - acl_args[j] = sdstrim(acl_args[j],"\t\r\n"); - if (ACLSetUser(u,acl_args[j],sdslen(acl_args[j])) != C_OK) { + acl_args[j] = sdstrim(acl_args[j], "\t\r\n"); + if (ACLSetUser(u, acl_args[j], sdslen(acl_args[j])) != C_OK) { const char *errmsg = ACLSetUserStringError(); if (errno == ENOENT) { /* For missing commands, we print out more information since * it shouldn't contain any sensitive information. */ - errors = sdscatprintf(errors, - "%s:%d: Error in applying operation '%s': %s. ", - server.acl_filename, linenum, acl_args[j], errmsg); + errors = sdscatprintf(errors, "%s:%d: Error in applying operation '%s': %s. ", server.acl_filename, + linenum, acl_args[j], errmsg); } else if (syntax_error == 0) { /* For all other errors, only print out the first error encountered * since it might affect future operations. */ - errors = sdscatprintf(errors, - "%s:%d: %s. ", - server.acl_filename, linenum, errmsg); + errors = sdscatprintf(errors, "%s:%d: %s. ", server.acl_filename, linenum, errmsg); syntax_error = 1; } } } - for (int i = 0; i < merged_argc; i++) sdsfree(acl_args[i]); + for (int i = 0; i < merged_argc; i++) { + sdsfree(acl_args[i]); + } zfree(acl_args); /* Apply the rule to the new users set only if so far there * are no errors, otherwise it's useless since we are going * to discard the new users set anyway. */ if (sdslen(errors) != 0) { - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); continue; } - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); } - sdsfreesplitres(lines,totlines); + sdsfreesplitres(lines, totlines); /* Check if we found errors and react accordingly. */ if (sdslen(errors) == 0) { /* The default user pointer is referenced in different places: instead * of replacing such occurrences it is much simpler to copy the new * default user configuration in the old one. */ - user *new_default = ACLGetUserByName("default",7); + user *new_default = ACLGetUserByName("default", 7); if (!new_default) { new_default = ACLCreateDefaultUser(); } - ACLCopyUser(DefaultUser,new_default); + ACLCopyUser(DefaultUser, new_default); ACLFreeUser(new_default); - raxInsert(Users,(unsigned char*)"default",7,DefaultUser,NULL); - raxRemove(old_users,(unsigned char*)"default",7,NULL); + raxInsert(Users, (unsigned char *)"default", 7, DefaultUser, NULL); + raxRemove(old_users, (unsigned char *)"default", 7, NULL); /* If there are some subscribers, we need to check if we need to drop some clients. */ rax *user_channels = NULL; @@ -2451,19 +2545,20 @@ sds ACLLoadFromFile(const char *filename) { listIter li; listNode *ln; - listRewind(server.clients,&li); + listRewind(server.clients, &li); while ((ln = listNext(&li)) != NULL) { client *c = listNodeValue(ln); user *original = c->user; list *channels = NULL; user *new = ACLGetUserByName(c->user->name, sdslen(c->user->name)); - if (new && user_channels) { - if (!raxFind(user_channels, (unsigned char*)(new->name), sdslen(new->name), (void**)&channels)) { + if (new &&user_channels) { + if (!raxFind(user_channels, (unsigned char *)(new->name), sdslen(new->name), (void **)&channels)) { channels = getUpcomingChannelList(new, original); - raxInsert(user_channels, (unsigned char*)(new->name), sdslen(new->name), channels, NULL); + raxInsert(user_channels, (unsigned char *)(new->name), sdslen(new->name), channels, NULL); } } - /* When the new channel list is NULL, it means the new user's channel list is a superset of the old user's list. */ + /* When the new channel list is NULL, it means the new user's channel list is a superset of the old user's + * list. */ if (!new || (channels && ACLShouldKillPubsubClient(c, channels))) { freeClient(c); continue; @@ -2471,15 +2566,17 @@ sds ACLLoadFromFile(const char *filename) { c->user = new; } - if (user_channels) - raxFreeWithCallback(user_channels, (void(*)(void*))listRelease); - raxFreeWithCallback(old_users,(void(*)(void*))ACLFreeUser); + if (user_channels) { + raxFreeWithCallback(user_channels, (void (*)(void *))listRelease); + } + raxFreeWithCallback(old_users, (void (*)(void *))ACLFreeUser); sdsfree(errors); return NULL; } else { - raxFreeWithCallback(Users,(void(*)(void*))ACLFreeUser); + raxFreeWithCallback(Users, (void (*)(void *))ACLFreeUser); Users = old_users; - errors = sdscat(errors,"WARNING: ACL errors detected, no change to the previously active ACL rules was performed"); + errors = + sdscat(errors, "WARNING: ACL errors detected, no change to the previously active ACL rules was performed"); return errors; } } @@ -2496,69 +2593,71 @@ int ACLSaveToFile(const char *filename) { /* Let's generate an SDS string containing the new version of the * ACL file. */ raxIterator ri; - raxStart(&ri,Users); - raxSeek(&ri,"^",NULL,0); - while(raxNext(&ri)) { + raxStart(&ri, Users); + raxSeek(&ri, "^", NULL, 0); + while (raxNext(&ri)) { user *u = ri.data; /* Return information in the configuration file format. */ sds user = sdsnew("user "); - user = sdscatsds(user,u->name); - user = sdscatlen(user," ",1); + user = sdscatsds(user, u->name); + user = sdscatlen(user, " ", 1); robj *descr = ACLDescribeUser(u); - user = sdscatsds(user,descr->ptr); + user = sdscatsds(user, descr->ptr); decrRefCount(descr); - acl = sdscatsds(acl,user); - acl = sdscatlen(acl,"\n",1); + acl = sdscatsds(acl, user); + acl = sdscatlen(acl, "\n", 1); sdsfree(user); } raxStop(&ri); /* Create a temp file with the new content. */ tmpfilename = sdsnew(filename); - tmpfilename = sdscatfmt(tmpfilename,".tmp-%i-%I", - (int) getpid(),commandTimeSnapshot()); - if ((fd = open(tmpfilename,O_WRONLY|O_CREAT,0644)) == -1) { - serverLog(LL_WARNING,"Opening temp ACL file for ACL SAVE: %s", - strerror(errno)); + tmpfilename = sdscatfmt(tmpfilename, ".tmp-%i-%I", (int)getpid(), commandTimeSnapshot()); + if ((fd = open(tmpfilename, O_WRONLY | O_CREAT, 0644)) == -1) { + serverLog(LL_WARNING, "Opening temp ACL file for ACL SAVE: %s", strerror(errno)); goto cleanup; } /* Write it. */ size_t offset = 0; while (offset < sdslen(acl)) { - ssize_t written_bytes = write(fd,acl + offset,sdslen(acl) - offset); + ssize_t written_bytes = write(fd, acl + offset, sdslen(acl) - offset); if (written_bytes <= 0) { - if (errno == EINTR) continue; - serverLog(LL_WARNING,"Writing ACL file for ACL SAVE: %s", - strerror(errno)); + if (errno == EINTR) { + continue; + } + serverLog(LL_WARNING, "Writing ACL file for ACL SAVE: %s", strerror(errno)); goto cleanup; } offset += written_bytes; } if (valkey_fsync(fd) == -1) { - serverLog(LL_WARNING,"Syncing ACL file for ACL SAVE: %s", - strerror(errno)); + serverLog(LL_WARNING, "Syncing ACL file for ACL SAVE: %s", strerror(errno)); goto cleanup; } - close(fd); fd = -1; + close(fd); + fd = -1; /* Let's replace the new file with the old one. */ - if (rename(tmpfilename,filename) == -1) { - serverLog(LL_WARNING,"Renaming ACL file for ACL SAVE: %s", - strerror(errno)); + if (rename(tmpfilename, filename) == -1) { + serverLog(LL_WARNING, "Renaming ACL file for ACL SAVE: %s", strerror(errno)); goto cleanup; } if (fsyncFileDir(filename) == -1) { - serverLog(LL_WARNING,"Syncing ACL directory for ACL SAVE: %s", - strerror(errno)); + serverLog(LL_WARNING, "Syncing ACL directory for ACL SAVE: %s", strerror(errno)); goto cleanup; } - sdsfree(tmpfilename); tmpfilename = NULL; + sdsfree(tmpfilename); + tmpfilename = NULL; retval = C_OK; /* If we reached this point, everything is fine. */ cleanup: - if (fd != -1) close(fd); - if (tmpfilename) unlink(tmpfilename); + if (fd != -1) { + close(fd); + } + if (tmpfilename) { + unlink(tmpfilename); + } sdsfree(tmpfilename); sdsfree(acl); return retval; @@ -2572,25 +2671,24 @@ int ACLSaveToFile(const char *filename) { void ACLLoadUsersAtStartup(void) { if (server.acl_filename[0] != '\0' && listLength(UsersToLoad) != 0) { serverLog(LL_WARNING, - "Configuring %s with users defined in valkey.conf and at " - "the same setting an ACL file path is invalid. This setup " - "is very likely to lead to configuration errors and security " - "holes, please define either an ACL file or declare users " - "directly in your valkey.conf, but not both.", SERVER_TITLE); + "Configuring %s with users defined in valkey.conf and at " + "the same setting an ACL file path is invalid. This setup " + "is very likely to lead to configuration errors and security " + "holes, please define either an ACL file or declare users " + "directly in your valkey.conf, but not both.", + SERVER_TITLE); exit(1); } if (ACLLoadConfiguredUsers() == C_ERR) { - serverLog(LL_WARNING, - "Critical error while loading ACLs. Exiting."); + serverLog(LL_WARNING, "Critical error while loading ACLs. Exiting."); exit(1); } if (server.acl_filename[0] != '\0') { sds errors = ACLLoadFromFile(server.acl_filename); if (errors) { - serverLog(LL_WARNING, - "Aborting %s startup because of ACL errors: %s", SERVER_TITLE, errors); + serverLog(LL_WARNING, "Aborting %s startup because of ACL errors: %s", SERVER_TITLE, errors); sdsfree(errors); exit(1); } @@ -2605,15 +2703,15 @@ void ACLLoadUsersAtStartup(void) { /* This structure defines an entry inside the ACL log. */ typedef struct ACLLogEntry { - uint64_t count; /* Number of times this happened recently. */ - int reason; /* Reason for denying the command. ACL_DENIED_*. */ - int context; /* Toplevel, Lua or MULTI/EXEC? ACL_LOG_CTX_*. */ - sds object; /* The key name or command name. */ - sds username; /* User the client is authenticated with. */ - mstime_t ctime; /* Milliseconds time of last update to this entry. */ - sds cinfo; /* Client info (last client if updated). */ - long long entry_id; /* The pair (entry_id, timestamp_created) is a unique identifier of this entry - * in case the node dies and is restarted, it can detect that if it's a new series. */ + uint64_t count; /* Number of times this happened recently. */ + int reason; /* Reason for denying the command. ACL_DENIED_*. */ + int context; /* Toplevel, Lua or MULTI/EXEC? ACL_LOG_CTX_*. */ + sds object; /* The key name or command name. */ + sds username; /* User the client is authenticated with. */ + mstime_t ctime; /* Milliseconds time of last update to this entry. */ + sds cinfo; /* Client info (last client if updated). */ + long long entry_id; /* The pair (entry_id, timestamp_created) is a unique identifier of this entry + * in case the node dies and is restarted, it can detect that if it's a new series. */ mstime_t timestamp_created; /* UNIX time in milliseconds at the time of this entry's creation. */ } ACLLogEntry; @@ -2621,13 +2719,25 @@ typedef struct ACLLogEntry { * that we should actually update the existing entry in our ACL log instead * of creating a new one. */ int ACLLogMatchEntry(ACLLogEntry *a, ACLLogEntry *b) { - if (a->reason != b->reason) return 0; - if (a->context != b->context) return 0; + if (a->reason != b->reason) { + return 0; + } + if (a->context != b->context) { + return 0; + } mstime_t delta = a->ctime - b->ctime; - if (delta < 0) delta = -delta; - if (delta > ACL_LOG_GROUPING_MAX_TIME_DELTA) return 0; - if (sdscmp(a->object,b->object) != 0) return 0; - if (sdscmp(a->username,b->username) != 0) return 0; + if (delta < 0) { + delta = -delta; + } + if (delta > ACL_LOG_GROUPING_MAX_TIME_DELTA) { + return 0; + } + if (sdscmp(a->object, b->object) != 0) { + return 0; + } + if (sdscmp(a->username, b->username) != 0) { + return 0; + } return 1; } @@ -2641,7 +2751,7 @@ void ACLFreeLogEntry(void *leptr) { } /* Update the relevant counter by the reason */ -void ACLUpdateInfoMetrics(int reason){ +void ACLUpdateInfoMetrics(int reason) { if (reason == ACL_DENIED_AUTH) { server.acl_info.user_auth_failures++; } else if (reason == ACL_DENIED_CMD) { @@ -2656,11 +2766,11 @@ void ACLUpdateInfoMetrics(int reason){ } static void trimACLLogEntriesToMaxLen(void) { - while(listLength(ACLLog) > server.acllog_max_len) { + while (listLength(ACLLog) > server.acllog_max_len) { listNode *ln = listLast(ACLLog); ACLLogEntry *le = listNodeValue(ln); ACLFreeLogEntry(le); - listDelNode(ACLLog,ln); + listDelNode(ACLLog, ln); } } @@ -2670,7 +2780,7 @@ static void trimACLLogEntriesToMaxLen(void) { * the log entry instead of creating many entries for very similar ACL * rules issues. * - * The argpos argument is used when the reason is ACL_DENIED_KEY or + * The argpos argument is used when the reason is ACL_DENIED_KEY or * ACL_DENIED_CHANNEL, since it allows the function to log the key or channel * name that caused the problem. * @@ -2682,12 +2792,12 @@ static void trimACLLogEntriesToMaxLen(void) { void addACLLogEntry(client *c, int reason, int context, int argpos, sds username, sds object) { /* Update ACL info metrics */ ACLUpdateInfoMetrics(reason); - + if (server.acllog_max_len == 0) { trimACLLogEntriesToMaxLen(); return; } - + /* Create a new entry. */ struct ACLLogEntry *le = zmalloc(sizeof(*le)); le->count = 1; @@ -2700,19 +2810,28 @@ void addACLLogEntry(client *c, int reason, int context, int argpos, sds username if (object) { le->object = object; } else { - switch(reason) { - case ACL_DENIED_CMD: le->object = sdsdup(c->cmd->fullname); break; - case ACL_DENIED_KEY: le->object = sdsdup(c->argv[argpos]->ptr); break; - case ACL_DENIED_CHANNEL: le->object = sdsdup(c->argv[argpos]->ptr); break; - case ACL_DENIED_AUTH: le->object = sdsdup(c->argv[0]->ptr); break; - default: le->object = sdsempty(); + switch (reason) { + case ACL_DENIED_CMD: + le->object = sdsdup(c->cmd->fullname); + break; + case ACL_DENIED_KEY: + le->object = sdsdup(c->argv[argpos]->ptr); + break; + case ACL_DENIED_CHANNEL: + le->object = sdsdup(c->argv[argpos]->ptr); + break; + case ACL_DENIED_AUTH: + le->object = sdsdup(c->argv[0]->ptr); + break; + default: + le->object = sdsempty(); } } /* if we have a real client from the network, use it (could be missing on module timers) */ - client *realclient = server.current_client? server.current_client : c; + client *realclient = server.current_client ? server.current_client : c; - le->cinfo = catClientInfoString(sdsempty(),realclient); + le->cinfo = catClientInfoString(sdsempty(), realclient); le->context = context; /* Try to match this entry with past ones, to see if we can just @@ -2720,14 +2839,14 @@ void addACLLogEntry(client *c, int reason, int context, int argpos, sds username long toscan = 10; /* Do a limited work trying to find duplicated. */ listIter li; listNode *ln; - listRewind(ACLLog,&li); + listRewind(ACLLog, &li); ACLLogEntry *match = NULL; while (toscan-- && (ln = listNext(&li)) != NULL) { ACLLogEntry *current = listNodeValue(ln); - if (ACLLogMatchEntry(current,le)) { + if (ACLLogMatchEntry(current, le)) { match = current; - listDelNode(ACLLog,ln); - listAddNodeHead(ACLLog,current); + listDelNode(ACLLog, ln); + listAddNodeHead(ACLLog, current); break; } } @@ -2757,19 +2876,25 @@ void addACLLogEntry(client *c, int reason, int context, int argpos, sds username sds getAclErrorMessage(int acl_res, user *user, struct serverCommand *cmd, sds errored_val, int verbose) { switch (acl_res) { case ACL_DENIED_CMD: - return sdscatfmt(sdsempty(), "User %S has no permissions to run " - "the '%S' command", user->name, cmd->fullname); + return sdscatfmt(sdsempty(), + "User %S has no permissions to run " + "the '%S' command", + user->name, cmd->fullname); case ACL_DENIED_KEY: if (verbose) { - return sdscatfmt(sdsempty(), "User %S has no permissions to access " - "the '%S' key", user->name, errored_val); + return sdscatfmt(sdsempty(), + "User %S has no permissions to access " + "the '%S' key", + user->name, errored_val); } else { return sdsnew("No permissions to access a key"); } case ACL_DENIED_CHANNEL: if (verbose) { - return sdscatfmt(sdsempty(), "User %S has no permissions to access " - "the '%S' channel", user->name, errored_val); + return sdscatfmt(sdsempty(), + "User %S has no permissions to access " + "the '%S' channel", + user->name, errored_val); } else { return sdsnew("No permissions to access a channel"); } @@ -2788,7 +2913,9 @@ void aclCatWithFlags(client *c, dict *commands, uint64_t cflag, int *arraylen) { while ((de = dictNext(di)) != NULL) { struct serverCommand *cmd = dictGetVal(de); - if (cmd->flags & CMD_MODULE) continue; + if (cmd->flags & CMD_MODULE) { + continue; + } if (cmd->acl_categories & cflag) { addReplyBulkCBuffer(c, cmd->fullname, sdslen(cmd->fullname)); (*arraylen)++; @@ -2802,8 +2929,8 @@ void aclCatWithFlags(client *c, dict *commands, uint64_t cflag, int *arraylen) { } /* Add the formatted response from a single selector to the ACL GETUSER - * response. This function returns the number of fields added. - * + * response. This function returns the number of fields added. + * * Setting verbose to 1 means that the full qualifier for key and channel * permissions are shown. */ @@ -2812,35 +2939,39 @@ int aclAddReplySelectorDescription(client *c, aclSelector *s) { listNode *ln; /* Commands */ - addReplyBulkCString(c,"commands"); + addReplyBulkCString(c, "commands"); sds cmddescr = ACLDescribeSelectorCommandRules(s); - addReplyBulkSds(c,cmddescr); - + addReplyBulkSds(c, cmddescr); + /* Key patterns */ - addReplyBulkCString(c,"keys"); + addReplyBulkCString(c, "keys"); if (s->flags & SELECTOR_FLAG_ALLKEYS) { - addReplyBulkCBuffer(c,"~*",2); + addReplyBulkCBuffer(c, "~*", 2); } else { sds dsl = sdsempty(); - listRewind(s->patterns,&li); - while((ln = listNext(&li))) { - keyPattern *thispat = (keyPattern *) listNodeValue(ln); - if (ln != listFirst(s->patterns)) dsl = sdscat(dsl, " "); + listRewind(s->patterns, &li); + while ((ln = listNext(&li))) { + keyPattern *thispat = (keyPattern *)listNodeValue(ln); + if (ln != listFirst(s->patterns)) { + dsl = sdscat(dsl, " "); + } dsl = sdsCatPatternString(dsl, thispat); } addReplyBulkSds(c, dsl); } /* Pub/sub patterns */ - addReplyBulkCString(c,"channels"); + addReplyBulkCString(c, "channels"); if (s->flags & SELECTOR_FLAG_ALLCHANNELS) { - addReplyBulkCBuffer(c,"&*",2); + addReplyBulkCBuffer(c, "&*", 2); } else { sds dsl = sdsempty(); - listRewind(s->channels,&li); - while((ln = listNext(&li))) { + listRewind(s->channels, &li); + while ((ln = listNext(&li))) { sds thispat = listNodeValue(ln); - if (ln != listFirst(s->channels)) dsl = sdscat(dsl, " "); + if (ln != listFirst(s->channels)) { + dsl = sdscat(dsl, " "); + } dsl = sdscatfmt(dsl, "&%S", thispat); } addReplyBulkSds(c, dsl); @@ -2864,7 +2995,7 @@ int aclAddReplySelectorDescription(client *c, aclSelector *s) { */ void aclCommand(client *c) { char *sub = c->argv[1]->ptr; - if (!strcasecmp(sub,"setuser") && c->argc >= 3) { + if (!strcasecmp(sub, "setuser") && c->argc >= 3) { /* Initially redact all of the arguments to not leak any information * about the user. */ for (int j = 2; j < c->argc; j++) { @@ -2873,34 +3004,38 @@ void aclCommand(client *c) { sds username = c->argv[2]->ptr; /* Check username validity. */ - if (ACLStringHasSpaces(username,sdslen(username))) { + if (ACLStringHasSpaces(username, sdslen(username))) { addReplyError(c, "Usernames can't contain spaces or null characters"); return; } - user *u = ACLGetUserByName(username,sdslen(username)); + user *u = ACLGetUserByName(username, sdslen(username)); sds *temp_argv = zmalloc(c->argc * sizeof(sds)); - for (int i = 3; i < c->argc; i++) temp_argv[i-3] = c->argv[i]->ptr; + for (int i = 3; i < c->argc; i++) { + temp_argv[i - 3] = c->argv[i]->ptr; + } sds error = ACLStringSetUser(u, username, temp_argv, c->argc - 3); zfree(temp_argv); if (error == NULL) { - addReply(c,shared.ok); + addReply(c, shared.ok); } else { addReplyErrorSdsSafe(c, error); } return; - } else if (!strcasecmp(sub,"deluser") && c->argc >= 3) { + } else if (!strcasecmp(sub, "deluser") && c->argc >= 3) { /* Initially redact all the arguments to not leak any information * about the users. */ - for (int j = 2; j < c->argc; j++) redactClientCommandArgument(c, j); + for (int j = 2; j < c->argc; j++) { + redactClientCommandArgument(c, j); + } int deleted = 0; for (int j = 2; j < c->argc; j++) { sds username = c->argv[j]->ptr; - if (!strcmp(username,"default")) { - addReplyError(c,"The 'default' user cannot be removed"); + if (!strcmp(username, "default")) { + addReplyError(c, "The 'default' user cannot be removed"); return; } } @@ -2908,20 +3043,17 @@ void aclCommand(client *c) { for (int j = 2; j < c->argc; j++) { sds username = c->argv[j]->ptr; user *u; - if (raxRemove(Users,(unsigned char*)username, - sdslen(username), - (void**)&u)) - { + if (raxRemove(Users, (unsigned char *)username, sdslen(username), (void **)&u)) { ACLFreeUserAndKillClients(u); deleted++; } } - addReplyLongLong(c,deleted); - } else if (!strcasecmp(sub,"getuser") && c->argc == 3) { + addReplyLongLong(c, deleted); + } else if (!strcasecmp(sub, "getuser") && c->argc == 3) { /* Redact the username to not leak any information about the user. */ redactClientCommandArgument(c, 2); - user *u = ACLGetUserByName(c->argv[2]->ptr,sdslen(c->argv[2]->ptr)); + user *u = ACLGetUserByName(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); if (u == NULL) { addReplyNull(c); return; @@ -2931,194 +3063,214 @@ void aclCommand(client *c) { int fields = 3; /* Flags */ - addReplyBulkCString(c,"flags"); + addReplyBulkCString(c, "flags"); void *deflen = addReplyDeferredLen(c); int numflags = 0; for (int j = 0; ACLUserFlags[j].flag; j++) { if (u->flags & ACLUserFlags[j].flag) { - addReplyBulkCString(c,ACLUserFlags[j].name); + addReplyBulkCString(c, ACLUserFlags[j].name); numflags++; } } - setDeferredSetLen(c,deflen,numflags); + setDeferredSetLen(c, deflen, numflags); /* Passwords */ - addReplyBulkCString(c,"passwords"); - addReplyArrayLen(c,listLength(u->passwords)); + addReplyBulkCString(c, "passwords"); + addReplyArrayLen(c, listLength(u->passwords)); listIter li; listNode *ln; - listRewind(u->passwords,&li); - while((ln = listNext(&li))) { + listRewind(u->passwords, &li); + while ((ln = listNext(&li))) { sds thispass = listNodeValue(ln); - addReplyBulkCBuffer(c,thispass,sdslen(thispass)); + addReplyBulkCBuffer(c, thispass, sdslen(thispass)); } /* Include the root selector at the top level for backwards compatibility */ fields += aclAddReplySelectorDescription(c, ACLUserGetRootSelector(u)); /* Describe all of the selectors on this user, including duplicating the root selector */ - addReplyBulkCString(c,"selectors"); + addReplyBulkCString(c, "selectors"); addReplyArrayLen(c, listLength(u->selectors) - 1); - listRewind(u->selectors,&li); + listRewind(u->selectors, &li); serverAssert(listNext(&li)); - while((ln = listNext(&li))) { + while ((ln = listNext(&li))) { void *slen = addReplyDeferredLen(c); int sfields = aclAddReplySelectorDescription(c, (aclSelector *)listNodeValue(ln)); setDeferredMapLen(c, slen, sfields); - } + } setDeferredMapLen(c, ufields, fields); - } else if ((!strcasecmp(sub,"list") || !strcasecmp(sub,"users")) && - c->argc == 2) - { - int justnames = !strcasecmp(sub,"users"); - addReplyArrayLen(c,raxSize(Users)); + } else if ((!strcasecmp(sub, "list") || !strcasecmp(sub, "users")) && c->argc == 2) { + int justnames = !strcasecmp(sub, "users"); + addReplyArrayLen(c, raxSize(Users)); raxIterator ri; - raxStart(&ri,Users); - raxSeek(&ri,"^",NULL,0); - while(raxNext(&ri)) { + raxStart(&ri, Users); + raxSeek(&ri, "^", NULL, 0); + while (raxNext(&ri)) { user *u = ri.data; if (justnames) { - addReplyBulkCBuffer(c,u->name,sdslen(u->name)); + addReplyBulkCBuffer(c, u->name, sdslen(u->name)); } else { /* Return information in the configuration file format. */ sds config = sdsnew("user "); - config = sdscatsds(config,u->name); - config = sdscatlen(config," ",1); + config = sdscatsds(config, u->name); + config = sdscatlen(config, " ", 1); robj *descr = ACLDescribeUser(u); - config = sdscatsds(config,descr->ptr); + config = sdscatsds(config, descr->ptr); decrRefCount(descr); - addReplyBulkSds(c,config); + addReplyBulkSds(c, config); } } raxStop(&ri); - } else if (!strcasecmp(sub,"whoami") && c->argc == 2) { + } else if (!strcasecmp(sub, "whoami") && c->argc == 2) { if (c->user != NULL) { - addReplyBulkCBuffer(c,c->user->name,sdslen(c->user->name)); + addReplyBulkCBuffer(c, c->user->name, sdslen(c->user->name)); } else { addReplyNull(c); } - } else if (server.acl_filename[0] == '\0' && - (!strcasecmp(sub,"load") || !strcasecmp(sub,"save"))) - { - addReplyError(c,"This instance is not configured to use an ACL file. You may want to specify users via the ACL SETUSER command and then issue a CONFIG REWRITE (assuming you have a configuration file set) in order to store users in the configuration."); + } else if (server.acl_filename[0] == '\0' && (!strcasecmp(sub, "load") || !strcasecmp(sub, "save"))) { + addReplyError(c, "This instance is not configured to use an ACL file. You may want to specify users via the " + "ACL SETUSER command and then issue a CONFIG REWRITE (assuming you have a configuration file " + "set) in order to store users in the configuration."); return; - } else if (!strcasecmp(sub,"load") && c->argc == 2) { + } else if (!strcasecmp(sub, "load") && c->argc == 2) { sds errors = ACLLoadFromFile(server.acl_filename); if (errors == NULL) { - addReply(c,shared.ok); + addReply(c, shared.ok); } else { - addReplyError(c,errors); + addReplyError(c, errors); sdsfree(errors); } - } else if (!strcasecmp(sub,"save") && c->argc == 2) { + } else if (!strcasecmp(sub, "save") && c->argc == 2) { if (ACLSaveToFile(server.acl_filename) == C_OK) { - addReply(c,shared.ok); + addReply(c, shared.ok); } else { - addReplyError(c,"There was an error trying to save the ACLs. " - "Please check the server logs for more " - "information"); + addReplyError(c, "There was an error trying to save the ACLs. " + "Please check the server logs for more " + "information"); } - } else if (!strcasecmp(sub,"cat") && c->argc == 2) { + } else if (!strcasecmp(sub, "cat") && c->argc == 2) { void *dl = addReplyDeferredLen(c); int j; - for (j = 0; ACLCommandCategories[j].flag != 0; j++) - addReplyBulkCString(c,ACLCommandCategories[j].name); - setDeferredArrayLen(c,dl,j); - } else if (!strcasecmp(sub,"cat") && c->argc == 3) { + for (j = 0; ACLCommandCategories[j].flag != 0; j++) { + addReplyBulkCString(c, ACLCommandCategories[j].name); + } + setDeferredArrayLen(c, dl, j); + } else if (!strcasecmp(sub, "cat") && c->argc == 3) { uint64_t cflag = ACLGetCommandCategoryFlagByName(c->argv[2]->ptr); if (cflag == 0) { - addReplyErrorFormat(c, "Unknown category '%.128s'", (char*)c->argv[2]->ptr); + addReplyErrorFormat(c, "Unknown category '%.128s'", (char *)c->argv[2]->ptr); return; } int arraylen = 0; void *dl = addReplyDeferredLen(c); aclCatWithFlags(c, server.orig_commands, cflag, &arraylen); - setDeferredArrayLen(c,dl,arraylen); - } else if (!strcasecmp(sub,"genpass") && (c->argc == 2 || c->argc == 3)) { - #define GENPASS_MAX_BITS 4096 - char pass[GENPASS_MAX_BITS/8*2]; /* Hex representation. */ - long bits = 256; /* By default generate 256 bits passwords. */ + setDeferredArrayLen(c, dl, arraylen); + } else if (!strcasecmp(sub, "genpass") && (c->argc == 2 || c->argc == 3)) { +#define GENPASS_MAX_BITS 4096 + char pass[GENPASS_MAX_BITS / 8 * 2]; /* Hex representation. */ + long bits = 256; /* By default generate 256 bits passwords. */ - if (c->argc == 3 && getLongFromObjectOrReply(c,c->argv[2],&bits,NULL) - != C_OK) return; + if (c->argc == 3 && getLongFromObjectOrReply(c, c->argv[2], &bits, NULL) != C_OK) { + return; + } if (bits <= 0 || bits > GENPASS_MAX_BITS) { addReplyErrorFormat(c, - "ACL GENPASS argument must be the number of " - "bits for the output password, a positive number " - "up to %d",GENPASS_MAX_BITS); + "ACL GENPASS argument must be the number of " + "bits for the output password, a positive number " + "up to %d", + GENPASS_MAX_BITS); return; } - long chars = (bits+3)/4; /* Round to number of characters to emit. */ - getRandomHexChars(pass,chars); - addReplyBulkCBuffer(c,pass,chars); - } else if (!strcasecmp(sub,"log") && (c->argc == 2 || c->argc ==3)) { + long chars = (bits + 3) / 4; /* Round to number of characters to emit. */ + getRandomHexChars(pass, chars); + addReplyBulkCBuffer(c, pass, chars); + } else if (!strcasecmp(sub, "log") && (c->argc == 2 || c->argc == 3)) { long count = 10; /* Number of entries to emit by default. */ /* Parse the only argument that LOG may have: it could be either * the number of entries the user wants to display, or alternatively * the "RESET" command in order to flush the old entries. */ if (c->argc == 3) { - if (!strcasecmp(c->argv[2]->ptr,"reset")) { - listSetFreeMethod(ACLLog,ACLFreeLogEntry); + if (!strcasecmp(c->argv[2]->ptr, "reset")) { + listSetFreeMethod(ACLLog, ACLFreeLogEntry); listEmpty(ACLLog); - listSetFreeMethod(ACLLog,NULL); - addReply(c,shared.ok); + listSetFreeMethod(ACLLog, NULL); + addReply(c, shared.ok); return; - } else if (getLongFromObjectOrReply(c,c->argv[2],&count,NULL) - != C_OK) - { + } else if (getLongFromObjectOrReply(c, c->argv[2], &count, NULL) != C_OK) { return; } - if (count < 0) count = 0; + if (count < 0) { + count = 0; + } } /* Fix the count according to the number of entries we got. */ - if ((size_t)count > listLength(ACLLog)) + if ((size_t)count > listLength(ACLLog)) { count = listLength(ACLLog); + } - addReplyArrayLen(c,count); + addReplyArrayLen(c, count); listIter li; listNode *ln; - listRewind(ACLLog,&li); + listRewind(ACLLog, &li); mstime_t now = commandTimeSnapshot(); while (count-- && (ln = listNext(&li)) != NULL) { ACLLogEntry *le = listNodeValue(ln); - addReplyMapLen(c,10); - addReplyBulkCString(c,"count"); - addReplyLongLong(c,le->count); + addReplyMapLen(c, 10); + addReplyBulkCString(c, "count"); + addReplyLongLong(c, le->count); - addReplyBulkCString(c,"reason"); + addReplyBulkCString(c, "reason"); char *reasonstr; - switch(le->reason) { - case ACL_DENIED_CMD: reasonstr="command"; break; - case ACL_DENIED_KEY: reasonstr="key"; break; - case ACL_DENIED_CHANNEL: reasonstr="channel"; break; - case ACL_DENIED_AUTH: reasonstr="auth"; break; - default: reasonstr="unknown"; + switch (le->reason) { + case ACL_DENIED_CMD: + reasonstr = "command"; + break; + case ACL_DENIED_KEY: + reasonstr = "key"; + break; + case ACL_DENIED_CHANNEL: + reasonstr = "channel"; + break; + case ACL_DENIED_AUTH: + reasonstr = "auth"; + break; + default: + reasonstr = "unknown"; } - addReplyBulkCString(c,reasonstr); + addReplyBulkCString(c, reasonstr); - addReplyBulkCString(c,"context"); + addReplyBulkCString(c, "context"); char *ctxstr; - switch(le->context) { - case ACL_LOG_CTX_TOPLEVEL: ctxstr="toplevel"; break; - case ACL_LOG_CTX_MULTI: ctxstr="multi"; break; - case ACL_LOG_CTX_LUA: ctxstr="lua"; break; - case ACL_LOG_CTX_MODULE: ctxstr="module"; break; - default: ctxstr="unknown"; + switch (le->context) { + case ACL_LOG_CTX_TOPLEVEL: + ctxstr = "toplevel"; + break; + case ACL_LOG_CTX_MULTI: + ctxstr = "multi"; + break; + case ACL_LOG_CTX_LUA: + ctxstr = "lua"; + break; + case ACL_LOG_CTX_MODULE: + ctxstr = "module"; + break; + default: + ctxstr = "unknown"; } - addReplyBulkCString(c,ctxstr); - - addReplyBulkCString(c,"object"); - addReplyBulkCBuffer(c,le->object,sdslen(le->object)); - addReplyBulkCString(c,"username"); - addReplyBulkCBuffer(c,le->username,sdslen(le->username)); - addReplyBulkCString(c,"age-seconds"); - double age = (double)(now - le->ctime)/1000; - addReplyDouble(c,age); - addReplyBulkCString(c,"client-info"); - addReplyBulkCBuffer(c,le->cinfo,sdslen(le->cinfo)); + addReplyBulkCString(c, ctxstr); + + addReplyBulkCString(c, "object"); + addReplyBulkCBuffer(c, le->object, sdslen(le->object)); + addReplyBulkCString(c, "username"); + addReplyBulkCBuffer(c, le->username, sdslen(le->username)); + addReplyBulkCString(c, "age-seconds"); + double age = (double)(now - le->ctime) / 1000; + addReplyDouble(c, age); + addReplyBulkCString(c, "client-info"); + addReplyBulkCBuffer(c, le->cinfo, sdslen(le->cinfo)); addReplyBulkCString(c, "entry-id"); addReplyLongLong(c, le->entry_id); addReplyBulkCString(c, "timestamp-created"); @@ -3126,9 +3278,9 @@ void aclCommand(client *c) { addReplyBulkCString(c, "timestamp-last-updated"); addReplyLongLong(c, le->ctime); } - } else if (!strcasecmp(sub,"dryrun") && c->argc >= 4) { + } else if (!strcasecmp(sub, "dryrun") && c->argc >= 4) { struct serverCommand *cmd; - user *u = ACLGetUserByName(c->argv[2]->ptr,sdslen(c->argv[2]->ptr)); + user *u = ACLGetUserByName(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); if (u == NULL) { addReplyErrorFormat(c, "User '%s' not found", (char *)c->argv[2]->ptr); return; @@ -3139,53 +3291,50 @@ void aclCommand(client *c) { return; } - if ((cmd->arity > 0 && cmd->arity != c->argc-3) || - (c->argc-3 < -cmd->arity)) - { - addReplyErrorFormat(c,"wrong number of arguments for '%s' command", cmd->fullname); + if ((cmd->arity > 0 && cmd->arity != c->argc - 3) || (c->argc - 3 < -cmd->arity)) { + addReplyErrorFormat(c, "wrong number of arguments for '%s' command", cmd->fullname); return; } int idx; int result = ACLCheckAllUserCommandPerm(u, cmd, c->argv + 3, c->argc - 3, &idx); if (result != ACL_OK) { - sds err = getAclErrorMessage(result, u, cmd, c->argv[idx+3]->ptr, 1); + sds err = getAclErrorMessage(result, u, cmd, c->argv[idx + 3]->ptr, 1); addReplyBulkSds(c, err); return; } - addReply(c,shared.ok); - } else if (c->argc == 2 && !strcasecmp(sub,"help")) { + addReply(c, shared.ok); + } else if (c->argc == 2 && !strcasecmp(sub, "help")) { const char *help[] = { -"CAT []", -" List all commands that belong to , or all command categories", -" when no category is specified.", -"DELUSER [ ...]", -" Delete a list of users.", -"DRYRUN [ ...]", -" Returns whether the user can execute the given command without executing the command.", -"GETUSER ", -" Get the user's details.", -"GENPASS []", -" Generate a secure 256-bit user password. The optional `bits` argument can", -" be used to specify a different size.", -"LIST", -" Show users details in config file format.", -"LOAD", -" Reload users from the ACL file.", -"LOG [ | RESET]", -" Show the ACL log entries.", -"SAVE", -" Save the current config to the ACL file.", -"SETUSER [ ...]", -" Create or modify a user with the specified attributes.", -"USERS", -" List all the registered usernames.", -"WHOAMI", -" Return the current connection username.", -NULL - }; - addReplyHelp(c,help); + "CAT []", + " List all commands that belong to , or all command categories", + " when no category is specified.", + "DELUSER [ ...]", + " Delete a list of users.", + "DRYRUN [ ...]", + " Returns whether the user can execute the given command without executing the command.", + "GETUSER ", + " Get the user's details.", + "GENPASS []", + " Generate a secure 256-bit user password. The optional `bits` argument can", + " be used to specify a different size.", + "LIST", + " Show users details in config file format.", + "LOAD", + " Reload users from the ACL file.", + "LOG [ | RESET]", + " Show the ACL log entries.", + "SAVE", + " Save the current config to the ACL file.", + "SETUSER [ ...]", + " Create or modify a user with the specified attributes.", + "USERS", + " List all the registered usernames.", + "WHOAMI", + " Return the current connection username.", + NULL}; + addReplyHelp(c, help); } else { addReplySubcommandSyntaxError(c); } @@ -3211,7 +3360,7 @@ void addReplyCommandCategories(client *c, struct serverCommand *cmd) { void authCommand(client *c) { /* Only two or three argument forms are allowed. */ if (c->argc > 3) { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } /* Always redact the second argument */ @@ -3224,13 +3373,13 @@ void authCommand(client *c) { /* Mimic the old behavior of giving an error for the two argument * form if no password is configured. */ if (DefaultUser->flags & USER_FLAG_NOPASS) { - addReplyError(c,"AUTH called without any password " - "configured for the default user. Are you sure " - "your configuration is correct?"); + addReplyError(c, "AUTH called without any password " + "configured for the default user. Are you sure " + "your configuration is correct?"); return; } - username = shared.default_username; + username = shared.default_username; password = c->argv[1]; } else { username = c->argv[1]; @@ -3245,18 +3394,20 @@ void authCommand(client *c) { } else if (result == AUTH_ERR) { addAuthErrReply(c, err); } - if (err) decrRefCount(err); + if (err) { + decrRefCount(err); + } } /* Set the password for the "default" ACL user. This implements supports for * requirepass config, so passing in NULL will set the user to be nopass. */ void ACLUpdateDefaultUserPassword(sds password) { - ACLSetUser(DefaultUser,"resetpass",-1); + ACLSetUser(DefaultUser, "resetpass", -1); if (password) { sds aclop = sdscatlen(sdsnew(">"), password, sdslen(password)); - ACLSetUser(DefaultUser,aclop,sdslen(aclop)); + ACLSetUser(DefaultUser, aclop, sdslen(aclop)); sdsfree(aclop); } else { - ACLSetUser(DefaultUser,"nopass",-1); + ACLSetUser(DefaultUser, "nopass", -1); } } diff --git a/src/adlist.c b/src/adlist.c index 06eca7c47..824014e58 100644 --- a/src/adlist.c +++ b/src/adlist.c @@ -39,12 +39,12 @@ * listSetFreeMethod. * * On error, NULL is returned. Otherwise the pointer to the new list. */ -list *listCreate(void) -{ +list *listCreate(void) { struct list *list; - if ((list = zmalloc(sizeof(*list))) == NULL) + if ((list = zmalloc(sizeof(*list))) == NULL) { return NULL; + } list->head = list->tail = NULL; list->len = 0; list->dup = NULL; @@ -54,16 +54,17 @@ list *listCreate(void) } /* Remove all the elements from the list without destroying the list itself. */ -void listEmpty(list *list) -{ +void listEmpty(list *list) { unsigned long len; listNode *current, *next; current = list->head; len = list->len; - while(len--) { + while (len--) { next = current->next; - if (list->free) list->free(current->value); + if (list->free) { + list->free(current->value); + } zfree(current); current = next; } @@ -74,10 +75,10 @@ void listEmpty(list *list) /* Free the whole list. * * This function can't fail. */ -void listRelease(list *list) -{ - if (!list) +void listRelease(list *list) { + if (!list) { return; + } listEmpty(list); zfree(list); } @@ -88,12 +89,12 @@ void listRelease(list *list) * On error, NULL is returned and no operation is performed (i.e. the * list remains unaltered). * On success the 'list' pointer you pass to the function is returned. */ -list *listAddNodeHead(list *list, void *value) -{ +list *listAddNodeHead(list *list, void *value) { listNode *node; - if ((node = zmalloc(sizeof(*node))) == NULL) + if ((node = zmalloc(sizeof(*node))) == NULL) { return NULL; + } node->value = value; listLinkNodeHead(list, node); return list; @@ -102,7 +103,7 @@ list *listAddNodeHead(list *list, void *value) /* * Add a node that has already been allocated to the head of list */ -void listLinkNodeHead(list* list, listNode *node) { +void listLinkNodeHead(list *list, listNode *node) { if (list->len == 0) { list->head = list->tail = node; node->prev = node->next = NULL; @@ -121,12 +122,12 @@ void listLinkNodeHead(list* list, listNode *node) { * On error, NULL is returned and no operation is performed (i.e. the * list remains unaltered). * On success the 'list' pointer you pass to the function is returned. */ -list *listAddNodeTail(list *list, void *value) -{ +list *listAddNodeTail(list *list, void *value) { listNode *node; - if ((node = zmalloc(sizeof(*node))) == NULL) + if ((node = zmalloc(sizeof(*node))) == NULL) { return NULL; + } node->value = value; listLinkNodeTail(list, node); return list; @@ -151,8 +152,9 @@ void listLinkNodeTail(list *list, listNode *node) { list *listInsertNode(list *list, listNode *old_node, void *value, int after) { listNode *node; - if ((node = zmalloc(sizeof(*node))) == NULL) + if ((node = zmalloc(sizeof(*node))) == NULL) { return NULL; + } node->value = value; if (after) { node->prev = old_node; @@ -181,10 +183,11 @@ list *listInsertNode(list *list, listNode *old_node, void *value, int after) { * The node is freed. If free callback is provided the value is freed as well. * * This function can't fail. */ -void listDelNode(list *list, listNode *node) -{ +void listDelNode(list *list, listNode *node) { listUnlinkNode(list, node); - if (list->free) list->free(node->value); + if (list->free) { + list->free(node->value); + } zfree(node); } @@ -192,14 +195,16 @@ void listDelNode(list *list, listNode *node) * Remove the specified node from the list without freeing it. */ void listUnlinkNode(list *list, listNode *node) { - if (node->prev) + if (node->prev) { node->prev->next = node->next; - else + } else { list->head = node->next; - if (node->next) + } + if (node->next) { node->next->prev = node->prev; - else + } else { list->tail = node->prev; + } node->next = NULL; node->prev = NULL; @@ -211,15 +216,17 @@ void listUnlinkNode(list *list, listNode *node) { * call to listNext() will return the next element of the list. * * This function can't fail. */ -listIter *listGetIterator(list *list, int direction) -{ +listIter *listGetIterator(list *list, int direction) { listIter *iter; - if ((iter = zmalloc(sizeof(*iter))) == NULL) return NULL; - if (direction == AL_START_HEAD) + if ((iter = zmalloc(sizeof(*iter))) == NULL) { + return NULL; + } + if (direction == AL_START_HEAD) { iter->next = list->head; - else + } else { iter->next = list->tail; + } iter->direction = direction; return iter; } @@ -254,15 +261,15 @@ void listRewindTail(list *list, listIter *li) { * } * * */ -listNode *listNext(listIter *iter) -{ +listNode *listNext(listIter *iter) { listNode *current = iter->next; if (current != NULL) { - if (iter->direction == AL_START_HEAD) + if (iter->direction == AL_START_HEAD) { iter->next = current->next; - else + } else { iter->next = current->prev; + } } return current; } @@ -275,19 +282,19 @@ listNode *listNext(listIter *iter) * the original node is used as value of the copied node. * * The original list both on success or error is never modified. */ -list *listDup(list *orig) -{ +list *listDup(list *orig) { list *copy; listIter iter; listNode *node; - if ((copy = listCreate()) == NULL) + if ((copy = listCreate()) == NULL) { return NULL; + } copy->dup = orig->dup; copy->free = orig->free; copy->match = orig->match; listRewind(orig, &iter); - while((node = listNext(&iter)) != NULL) { + while ((node = listNext(&iter)) != NULL) { void *value; if (copy->dup) { @@ -299,10 +306,12 @@ list *listDup(list *orig) } else { value = node->value; } - + if (listAddNodeTail(copy, value) == NULL) { /* Free value if dup succeed but listAddNodeTail failed. */ - if (copy->free) copy->free(value); + if (copy->free) { + copy->free(value); + } listRelease(copy); return NULL; @@ -320,13 +329,12 @@ list *listDup(list *orig) * On success the first matching node pointer is returned * (search starts from head). If no matching node exists * NULL is returned. */ -listNode *listSearchKey(list *list, void *key) -{ +listNode *listSearchKey(list *list, void *key) { listIter iter; listNode *node; listRewind(list, &iter); - while((node = listNext(&iter)) != NULL) { + while ((node = listNext(&iter)) != NULL) { if (list->match) { if (list->match(node->value, key)) { return node; @@ -349,19 +357,25 @@ listNode *listIndex(list *list, long index) { listNode *n; if (index < 0) { - index = (-index)-1; + index = (-index) - 1; n = list->tail; - while(index-- && n) n = n->prev; + while (index-- && n) { + n = n->prev; + } } else { n = list->head; - while(index-- && n) n = n->next; + while (index-- && n) { + n = n->next; + } } return n; } /* Rotate the list removing the tail node and inserting it to the head. */ void listRotateTailToHead(list *list) { - if (listLength(list) <= 1) return; + if (listLength(list) <= 1) { + return; + } /* Detach current tail */ listNode *tail = list->tail; @@ -376,7 +390,9 @@ void listRotateTailToHead(list *list) { /* Rotate the list removing the head node and inserting it to the tail. */ void listRotateHeadToTail(list *list) { - if (listLength(list) <= 1) return; + if (listLength(list) <= 1) { + return; + } listNode *head = list->head; /* Detach current head */ @@ -392,14 +408,17 @@ void listRotateHeadToTail(list *list) { /* Add all the elements of the list 'o' at the end of the * list 'l'. The list 'other' remains empty but otherwise valid. */ void listJoin(list *l, list *o) { - if (o->len == 0) return; + if (o->len == 0) { + return; + } o->head->prev = l->tail; - if (l->tail) + if (l->tail) { l->tail->next = o->head; - else + } else { l->head = o->head; + } l->tail = o->tail; l->len += o->len; diff --git a/src/adlist.h b/src/adlist.h index 7c5443769..6d28f3abc 100644 --- a/src/adlist.h +++ b/src/adlist.h @@ -61,9 +61,9 @@ typedef struct list { #define listNextNode(n) ((n)->next) #define listNodeValue(n) ((n)->value) -#define listSetDupMethod(l,m) ((l)->dup = (m)) -#define listSetFreeMethod(l,m) ((l)->free = (m)) -#define listSetMatchMethod(l,m) ((l)->match = (m)) +#define listSetDupMethod(l, m) ((l)->dup = (m)) +#define listSetFreeMethod(l, m) ((l)->free = (m)) +#define listSetMatchMethod(l, m) ((l)->match = (m)) #define listGetDupMethod(l) ((l)->dup) #define listGetFreeMethod(l) ((l)->free) diff --git a/src/ae.c b/src/ae.c index cc67f2580..664c64889 100644 --- a/src/ae.c +++ b/src/ae.c @@ -52,15 +52,15 @@ #ifdef HAVE_EVPORT #include "ae_evport.c" #else - #ifdef HAVE_EPOLL - #include "ae_epoll.c" - #else - #ifdef HAVE_KQUEUE - #include "ae_kqueue.c" - #else - #include "ae_select.c" - #endif - #endif +#ifdef HAVE_EPOLL +#include "ae_epoll.c" +#else +#ifdef HAVE_KQUEUE +#include "ae_kqueue.c" +#else +#include "ae_select.c" +#endif +#endif #endif @@ -68,12 +68,16 @@ aeEventLoop *aeCreateEventLoop(int setsize) { aeEventLoop *eventLoop; int i; - monotonicInit(); /* just in case the calling app didn't initialize */ + monotonicInit(); /* just in case the calling app didn't initialize */ - if ((eventLoop = zmalloc(sizeof(*eventLoop))) == NULL) goto err; - eventLoop->events = zmalloc(sizeof(aeFileEvent)*setsize); - eventLoop->fired = zmalloc(sizeof(aeFiredEvent)*setsize); - if (eventLoop->events == NULL || eventLoop->fired == NULL) goto err; + if ((eventLoop = zmalloc(sizeof(*eventLoop))) == NULL) { + goto err; + } + eventLoop->events = zmalloc(sizeof(aeFileEvent) * setsize); + eventLoop->fired = zmalloc(sizeof(aeFiredEvent) * setsize); + if (eventLoop->events == NULL || eventLoop->fired == NULL) { + goto err; + } eventLoop->setsize = setsize; eventLoop->timeEventHead = NULL; eventLoop->timeEventNextId = 0; @@ -82,11 +86,14 @@ aeEventLoop *aeCreateEventLoop(int setsize) { eventLoop->beforesleep = NULL; eventLoop->aftersleep = NULL; eventLoop->flags = 0; - if (aeApiCreate(eventLoop) == -1) goto err; + if (aeApiCreate(eventLoop) == -1) { + goto err; + } /* Events with mask == AE_NONE are not set. So let's initialize the * vector with it. */ - for (i = 0; i < setsize; i++) + for (i = 0; i < setsize; i++) { eventLoop->events[i].mask = AE_NONE; + } return eventLoop; err: @@ -109,10 +116,11 @@ int aeGetSetSize(aeEventLoop *eventLoop) { * Note: it just means you turn on/off the global AE_DONT_WAIT. */ void aeSetDontWait(aeEventLoop *eventLoop, int noWait) { - if (noWait) + if (noWait) { eventLoop->flags |= AE_DONT_WAIT; - else + } else { eventLoop->flags &= ~AE_DONT_WAIT; + } } /* Resize the maximum set size of the event loop. @@ -125,18 +133,25 @@ void aeSetDontWait(aeEventLoop *eventLoop, int noWait) { int aeResizeSetSize(aeEventLoop *eventLoop, int setsize) { int i; - if (setsize == eventLoop->setsize) return AE_OK; - if (eventLoop->maxfd >= setsize) return AE_ERR; - if (aeApiResize(eventLoop,setsize) == -1) return AE_ERR; + if (setsize == eventLoop->setsize) { + return AE_OK; + } + if (eventLoop->maxfd >= setsize) { + return AE_ERR; + } + if (aeApiResize(eventLoop, setsize) == -1) { + return AE_ERR; + } - eventLoop->events = zrealloc(eventLoop->events,sizeof(aeFileEvent)*setsize); - eventLoop->fired = zrealloc(eventLoop->fired,sizeof(aeFiredEvent)*setsize); + eventLoop->events = zrealloc(eventLoop->events, sizeof(aeFileEvent) * setsize); + eventLoop->fired = zrealloc(eventLoop->fired, sizeof(aeFiredEvent) * setsize); eventLoop->setsize = setsize; /* Make sure that if we created new slots, they are initialized with * an AE_NONE mask. */ - for (i = eventLoop->maxfd+1; i < setsize; i++) + for (i = eventLoop->maxfd + 1; i < setsize; i++) { eventLoop->events[i].mask = AE_NONE; + } return AE_OK; } @@ -149,8 +164,9 @@ void aeDeleteEventLoop(aeEventLoop *eventLoop) { aeTimeEvent *next_te, *te = eventLoop->timeEventHead; while (te) { next_te = te->next; - if (te->finalizerProc) + if (te->finalizerProc) { te->finalizerProc(eventLoop, te->clientData); + } zfree(te); te = next_te; } @@ -161,35 +177,44 @@ void aeStop(aeEventLoop *eventLoop) { eventLoop->stop = 1; } -int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, - aeFileProc *proc, void *clientData) -{ +int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData) { if (fd >= eventLoop->setsize) { errno = ERANGE; return AE_ERR; } aeFileEvent *fe = &eventLoop->events[fd]; - if (aeApiAddEvent(eventLoop, fd, mask) == -1) + if (aeApiAddEvent(eventLoop, fd, mask) == -1) { return AE_ERR; + } fe->mask |= mask; - if (mask & AE_READABLE) fe->rfileProc = proc; - if (mask & AE_WRITABLE) fe->wfileProc = proc; + if (mask & AE_READABLE) { + fe->rfileProc = proc; + } + if (mask & AE_WRITABLE) { + fe->wfileProc = proc; + } fe->clientData = clientData; - if (fd > eventLoop->maxfd) + if (fd > eventLoop->maxfd) { eventLoop->maxfd = fd; + } return AE_OK; } -void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) -{ - if (fd >= eventLoop->setsize) return; +void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) { + if (fd >= eventLoop->setsize) { + return; + } aeFileEvent *fe = &eventLoop->events[fd]; - if (fe->mask == AE_NONE) return; + if (fe->mask == AE_NONE) { + return; + } /* We want to always remove AE_BARRIER if set when AE_WRITABLE * is removed. */ - if (mask & AE_WRITABLE) mask |= AE_BARRIER; + if (mask & AE_WRITABLE) { + mask |= AE_BARRIER; + } aeApiDelEvent(eventLoop, fd, mask); fe->mask = fe->mask & (~mask); @@ -197,36 +222,45 @@ void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) /* Update the max fd */ int j; - for (j = eventLoop->maxfd-1; j >= 0; j--) - if (eventLoop->events[j].mask != AE_NONE) break; + for (j = eventLoop->maxfd - 1; j >= 0; j--) { + if (eventLoop->events[j].mask != AE_NONE) { + break; + } + } eventLoop->maxfd = j; } } void *aeGetFileClientData(aeEventLoop *eventLoop, int fd) { - if (fd >= eventLoop->setsize) return NULL; + if (fd >= eventLoop->setsize) { + return NULL; + } aeFileEvent *fe = &eventLoop->events[fd]; - if (fe->mask == AE_NONE) return NULL; + if (fe->mask == AE_NONE) { + return NULL; + } return fe->clientData; } int aeGetFileEvents(aeEventLoop *eventLoop, int fd) { - if (fd >= eventLoop->setsize) return 0; + if (fd >= eventLoop->setsize) { + return 0; + } aeFileEvent *fe = &eventLoop->events[fd]; return fe->mask; } -long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, - aeTimeProc *proc, void *clientData, - aeEventFinalizerProc *finalizerProc) -{ +long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, aeTimeProc *proc, void *clientData, + aeEventFinalizerProc *finalizerProc) { long long id = eventLoop->timeEventNextId++; aeTimeEvent *te; te = zmalloc(sizeof(*te)); - if (te == NULL) return AE_ERR; + if (te == NULL) { + return AE_ERR; + } te->id = id; te->when = getMonotonicUs() + milliseconds * 1000; te->timeProc = proc; @@ -235,16 +269,16 @@ long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, te->prev = NULL; te->next = eventLoop->timeEventHead; te->refcount = 0; - if (te->next) + if (te->next) { te->next->prev = te; + } eventLoop->timeEventHead = te; return id; } -int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id) -{ +int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id) { aeTimeEvent *te = eventLoop->timeEventHead; - while(te) { + while (te) { if (te->id == id) { te->id = AE_DELETED_EVENT_ID; return AE_OK; @@ -265,12 +299,15 @@ int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id) */ static int64_t usUntilEarliestTimer(aeEventLoop *eventLoop) { aeTimeEvent *te = eventLoop->timeEventHead; - if (te == NULL) return -1; + if (te == NULL) { + return -1; + } aeTimeEvent *earliest = NULL; while (te) { - if ((!earliest || te->when < earliest->when) && te->id != AE_DELETED_EVENT_ID) + if ((!earliest || te->when < earliest->when) && te->id != AE_DELETED_EVENT_ID) { earliest = te; + } te = te->next; } @@ -285,9 +322,9 @@ static int processTimeEvents(aeEventLoop *eventLoop) { long long maxId; te = eventLoop->timeEventHead; - maxId = eventLoop->timeEventNextId-1; + maxId = eventLoop->timeEventNextId - 1; monotime now = getMonotonicUs(); - while(te) { + while (te) { long long id; /* Remove events scheduled for deletion. */ @@ -300,12 +337,14 @@ static int processTimeEvents(aeEventLoop *eventLoop) { te = next; continue; } - if (te->prev) + if (te->prev) { te->prev->next = te->next; - else + } else { eventLoop->timeEventHead = te->next; - if (te->next) + } + if (te->next) { te->next->prev = te->prev; + } if (te->finalizerProc) { te->finalizerProc(eventLoop, te->clientData); now = getMonotonicUs(); @@ -360,25 +399,26 @@ static int processTimeEvents(aeEventLoop *eventLoop) { * if flags has AE_CALL_BEFORE_SLEEP set, the beforesleep callback is called. * * The function returns the number of events processed. */ -int aeProcessEvents(aeEventLoop *eventLoop, int flags) -{ +int aeProcessEvents(aeEventLoop *eventLoop, int flags) { int processed = 0, numevents; /* Nothing to do? return ASAP */ - if (!(flags & AE_TIME_EVENTS) && !(flags & AE_FILE_EVENTS)) return 0; + if (!(flags & AE_TIME_EVENTS) && !(flags & AE_FILE_EVENTS)) { + return 0; + } /* Note that we want to call aeApiPoll() even if there are no * file events to process as long as we want to process time * events, in order to sleep until the next time event is ready * to fire. */ - if (eventLoop->maxfd != -1 || - ((flags & AE_TIME_EVENTS) && !(flags & AE_DONT_WAIT))) { + if (eventLoop->maxfd != -1 || ((flags & AE_TIME_EVENTS) && !(flags & AE_DONT_WAIT))) { int j; struct timeval tv, *tvp = NULL; /* NULL means infinite wait. */ int64_t usUntilTimer; - if (eventLoop->beforesleep != NULL && (flags & AE_CALL_BEFORE_SLEEP)) + if (eventLoop->beforesleep != NULL && (flags & AE_CALL_BEFORE_SLEEP)) { eventLoop->beforesleep(eventLoop); + } /* The eventLoop->flags may be changed inside beforesleep. * So we should check it after beforesleep be called. At the same time, @@ -406,8 +446,9 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags) } /* After sleep callback. */ - if (eventLoop->aftersleep != NULL && flags & AE_CALL_AFTER_SLEEP) + if (eventLoop->aftersleep != NULL && flags & AE_CALL_AFTER_SLEEP) { eventLoop->aftersleep(eventLoop); + } for (j = 0; j < numevents; j++) { int fd = eventLoop->fired[j].fd; @@ -435,7 +476,7 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags) * Fire the readable event if the call sequence is not * inverted. */ if (!invert && fe->mask & mask & AE_READABLE) { - fe->rfileProc(eventLoop,fd,fe->clientData,mask); + fe->rfileProc(eventLoop, fd, fe->clientData, mask); fired++; fe = &eventLoop->events[fd]; /* Refresh in case of resize. */ } @@ -443,7 +484,7 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags) /* Fire the writable event. */ if (fe->mask & mask & AE_WRITABLE) { if (!fired || fe->wfileProc != fe->rfileProc) { - fe->wfileProc(eventLoop,fd,fe->clientData,mask); + fe->wfileProc(eventLoop, fd, fe->clientData, mask); fired++; } } @@ -452,10 +493,8 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags) * after the writable one. */ if (invert) { fe = &eventLoop->events[fd]; /* Refresh in case of resize. */ - if ((fe->mask & mask & AE_READABLE) && - (!fired || fe->wfileProc != fe->rfileProc)) - { - fe->rfileProc(eventLoop,fd,fe->clientData,mask); + if ((fe->mask & mask & AE_READABLE) && (!fired || fe->wfileProc != fe->rfileProc)) { + fe->rfileProc(eventLoop, fd, fe->clientData, mask); fired++; } } @@ -464,8 +503,9 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags) } } /* Check time events */ - if (flags & AE_TIME_EVENTS) + if (flags & AE_TIME_EVENTS) { processed += processTimeEvents(eventLoop); + } return processed; /* return the number of processed file/time events */ } @@ -478,14 +518,26 @@ int aeWait(int fd, int mask, long long milliseconds) { memset(&pfd, 0, sizeof(pfd)); pfd.fd = fd; - if (mask & AE_READABLE) pfd.events |= POLLIN; - if (mask & AE_WRITABLE) pfd.events |= POLLOUT; - - if ((retval = poll(&pfd, 1, milliseconds))== 1) { - if (pfd.revents & POLLIN) retmask |= AE_READABLE; - if (pfd.revents & POLLOUT) retmask |= AE_WRITABLE; - if (pfd.revents & POLLERR) retmask |= AE_WRITABLE; - if (pfd.revents & POLLHUP) retmask |= AE_WRITABLE; + if (mask & AE_READABLE) { + pfd.events |= POLLIN; + } + if (mask & AE_WRITABLE) { + pfd.events |= POLLOUT; + } + + if ((retval = poll(&pfd, 1, milliseconds)) == 1) { + if (pfd.revents & POLLIN) { + retmask |= AE_READABLE; + } + if (pfd.revents & POLLOUT) { + retmask |= AE_WRITABLE; + } + if (pfd.revents & POLLERR) { + retmask |= AE_WRITABLE; + } + if (pfd.revents & POLLHUP) { + retmask |= AE_WRITABLE; + } return retmask; } else { return retval; @@ -495,9 +547,7 @@ int aeWait(int fd, int mask, long long milliseconds) { void aeMain(aeEventLoop *eventLoop) { eventLoop->stop = 0; while (!eventLoop->stop) { - aeProcessEvents(eventLoop, AE_ALL_EVENTS| - AE_CALL_BEFORE_SLEEP| - AE_CALL_AFTER_SLEEP); + aeProcessEvents(eventLoop, AE_ALL_EVENTS | AE_CALL_BEFORE_SLEEP | AE_CALL_AFTER_SLEEP); } } diff --git a/src/ae.h b/src/ae.h index 70ce8a2d5..bf2e621a0 100644 --- a/src/ae.h +++ b/src/ae.h @@ -38,27 +38,28 @@ #define AE_OK 0 #define AE_ERR -1 -#define AE_NONE 0 /* No events registered. */ -#define AE_READABLE 1 /* Fire when descriptor is readable. */ -#define AE_WRITABLE 2 /* Fire when descriptor is writable. */ -#define AE_BARRIER 4 /* With WRITABLE, never fire the event if the - READABLE event already fired in the same event - loop iteration. Useful when you want to persist - things to disk before sending replies, and want - to do that in a group fashion. */ +#define AE_NONE 0 /* No events registered. */ +#define AE_READABLE 1 /* Fire when descriptor is readable. */ +#define AE_WRITABLE 2 /* Fire when descriptor is writable. */ +#define AE_BARRIER \ + 4 /* With WRITABLE, never fire the event if the \ + READABLE event already fired in the same event \ + loop iteration. Useful when you want to persist \ + things to disk before sending replies, and want \ + to do that in a group fashion. */ -#define AE_FILE_EVENTS (1<<0) -#define AE_TIME_EVENTS (1<<1) -#define AE_ALL_EVENTS (AE_FILE_EVENTS|AE_TIME_EVENTS) -#define AE_DONT_WAIT (1<<2) -#define AE_CALL_BEFORE_SLEEP (1<<3) -#define AE_CALL_AFTER_SLEEP (1<<4) +#define AE_FILE_EVENTS (1 << 0) +#define AE_TIME_EVENTS (1 << 1) +#define AE_ALL_EVENTS (AE_FILE_EVENTS | AE_TIME_EVENTS) +#define AE_DONT_WAIT (1 << 2) +#define AE_CALL_BEFORE_SLEEP (1 << 3) +#define AE_CALL_AFTER_SLEEP (1 << 4) #define AE_NOMORE -1 #define AE_DELETED_EVENT_ID -1 /* Macros */ -#define AE_NOTUSED(V) ((void) V) +#define AE_NOTUSED(V) ((void)V) struct aeEventLoop; @@ -86,7 +87,7 @@ typedef struct aeTimeEvent { struct aeTimeEvent *prev; struct aeTimeEvent *next; int refcount; /* refcount to prevent timer events from being - * freed in recursive time event calls. */ + * freed in recursive time event calls. */ } aeTimeEvent; /* A fired event */ @@ -114,14 +115,12 @@ typedef struct aeEventLoop { aeEventLoop *aeCreateEventLoop(int setsize); void aeDeleteEventLoop(aeEventLoop *eventLoop); void aeStop(aeEventLoop *eventLoop); -int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, - aeFileProc *proc, void *clientData); +int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData); void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask); int aeGetFileEvents(aeEventLoop *eventLoop, int fd); void *aeGetFileClientData(aeEventLoop *eventLoop, int fd); -long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, - aeTimeProc *proc, void *clientData, - aeEventFinalizerProc *finalizerProc); +long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, aeTimeProc *proc, void *clientData, + aeEventFinalizerProc *finalizerProc); int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id); int aeProcessEvents(aeEventLoop *eventLoop, int flags); int aeWait(int fd, int mask, long long milliseconds); diff --git a/src/ae_epoll.c b/src/ae_epoll.c index 493ffcad2..00b008cfc 100644 --- a/src/ae_epoll.c +++ b/src/ae_epoll.c @@ -39,8 +39,10 @@ typedef struct aeApiState { static int aeApiCreate(aeEventLoop *eventLoop) { aeApiState *state = zmalloc(sizeof(aeApiState)); - if (!state) return -1; - state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize); + if (!state) { + return -1; + } + state->events = zmalloc(sizeof(struct epoll_event) * eventLoop->setsize); if (!state->events) { zfree(state); return -1; @@ -59,7 +61,7 @@ static int aeApiCreate(aeEventLoop *eventLoop) { static int aeApiResize(aeEventLoop *eventLoop, int setsize) { aeApiState *state = eventLoop->apidata; - state->events = zrealloc(state->events, sizeof(struct epoll_event)*setsize); + state->events = zrealloc(state->events, sizeof(struct epoll_event) * setsize); return 0; } @@ -76,15 +78,20 @@ static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { struct epoll_event ee = {0}; /* avoid valgrind warning */ /* If the fd was already monitored for some event, we need a MOD * operation. Otherwise we need an ADD operation. */ - int op = eventLoop->events[fd].mask == AE_NONE ? - EPOLL_CTL_ADD : EPOLL_CTL_MOD; + int op = eventLoop->events[fd].mask == AE_NONE ? EPOLL_CTL_ADD : EPOLL_CTL_MOD; ee.events = 0; mask |= eventLoop->events[fd].mask; /* Merge old events */ - if (mask & AE_READABLE) ee.events |= EPOLLIN; - if (mask & AE_WRITABLE) ee.events |= EPOLLOUT; + if (mask & AE_READABLE) { + ee.events |= EPOLLIN; + } + if (mask & AE_WRITABLE) { + ee.events |= EPOLLOUT; + } ee.data.fd = fd; - if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1; + if (epoll_ctl(state->epfd, op, fd, &ee) == -1) { + return -1; + } return 0; } @@ -94,15 +101,19 @@ static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) { int mask = eventLoop->events[fd].mask & (~delmask); ee.events = 0; - if (mask & AE_READABLE) ee.events |= EPOLLIN; - if (mask & AE_WRITABLE) ee.events |= EPOLLOUT; + if (mask & AE_READABLE) { + ee.events |= EPOLLIN; + } + if (mask & AE_WRITABLE) { + ee.events |= EPOLLOUT; + } ee.data.fd = fd; if (mask != AE_NONE) { - epoll_ctl(state->epfd,EPOLL_CTL_MOD,fd,&ee); + epoll_ctl(state->epfd, EPOLL_CTL_MOD, fd, &ee); } else { /* Note, Kernel < 2.6.9 requires a non null event pointer even for * EPOLL_CTL_DEL. */ - epoll_ctl(state->epfd,EPOLL_CTL_DEL,fd,&ee); + epoll_ctl(state->epfd, EPOLL_CTL_DEL, fd, &ee); } } @@ -110,20 +121,28 @@ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { aeApiState *state = eventLoop->apidata; int retval, numevents = 0; - retval = epoll_wait(state->epfd,state->events,eventLoop->setsize, - tvp ? (tvp->tv_sec*1000 + (tvp->tv_usec + 999)/1000) : -1); + retval = epoll_wait(state->epfd, state->events, eventLoop->setsize, + tvp ? (tvp->tv_sec * 1000 + (tvp->tv_usec + 999) / 1000) : -1); if (retval > 0) { int j; numevents = retval; for (j = 0; j < numevents; j++) { int mask = 0; - struct epoll_event *e = state->events+j; - - if (e->events & EPOLLIN) mask |= AE_READABLE; - if (e->events & EPOLLOUT) mask |= AE_WRITABLE; - if (e->events & EPOLLERR) mask |= AE_WRITABLE|AE_READABLE; - if (e->events & EPOLLHUP) mask |= AE_WRITABLE|AE_READABLE; + struct epoll_event *e = state->events + j; + + if (e->events & EPOLLIN) { + mask |= AE_READABLE; + } + if (e->events & EPOLLOUT) { + mask |= AE_WRITABLE; + } + if (e->events & EPOLLERR) { + mask |= AE_WRITABLE | AE_READABLE; + } + if (e->events & EPOLLHUP) { + mask |= AE_WRITABLE | AE_READABLE; + } eventLoop->fired[j].fd = e->data.fd; eventLoop->fired[j].mask = mask; } diff --git a/src/ae_evport.c b/src/ae_evport.c index 55393e96b..8a018428e 100644 --- a/src/ae_evport.c +++ b/src/ae_evport.c @@ -65,16 +65,18 @@ static int evport_debug = 0; #define MAX_EVENT_BATCHSZ 512 typedef struct aeApiState { - int portfd; /* event port */ - uint_t npending; /* # of pending fds */ - int pending_fds[MAX_EVENT_BATCHSZ]; /* pending fds */ - int pending_masks[MAX_EVENT_BATCHSZ]; /* pending fds' masks */ + int portfd; /* event port */ + uint_t npending; /* # of pending fds */ + int pending_fds[MAX_EVENT_BATCHSZ]; /* pending fds */ + int pending_masks[MAX_EVENT_BATCHSZ]; /* pending fds' masks */ } aeApiState; static int aeApiCreate(aeEventLoop *eventLoop) { int i; aeApiState *state = zmalloc(sizeof(aeApiState)); - if (!state) return -1; + if (!state) { + return -1; + } state->portfd = port_create(); if (state->portfd == -1) { @@ -95,8 +97,8 @@ static int aeApiCreate(aeEventLoop *eventLoop) { } static int aeApiResize(aeEventLoop *eventLoop, int setsize) { - (void) eventLoop; - (void) setsize; + (void)eventLoop; + (void)setsize; /* Nothing to resize here. */ return 0; } @@ -112,8 +114,9 @@ static int aeApiLookupPending(aeApiState *state, int fd) { uint_t i; for (i = 0; i < state->npending; i++) { - if (state->pending_fds[i] == fd) + if (state->pending_fds[i] == fd) { return (i); + } } return (-1); @@ -126,26 +129,30 @@ static int aeApiAssociate(const char *where, int portfd, int fd, int mask) { int events = 0; int rv, err; - if (mask & AE_READABLE) + if (mask & AE_READABLE) { events |= POLLIN; - if (mask & AE_WRITABLE) + } + if (mask & AE_WRITABLE) { events |= POLLOUT; + } - if (evport_debug) + if (evport_debug) { fprintf(stderr, "%s: port_associate(%d, 0x%x) = ", where, fd, events); + } - rv = port_associate(portfd, PORT_SOURCE_FD, fd, events, - (void *)(uintptr_t)mask); + rv = port_associate(portfd, PORT_SOURCE_FD, fd, events, (void *)(uintptr_t)mask); err = errno; - if (evport_debug) + if (evport_debug) { fprintf(stderr, "%d (%s)\n", rv, rv == 0 ? "no error" : strerror(err)); + } if (rv == -1) { fprintf(stderr, "%s: port_associate: %s\n", where, strerror(err)); - if (err == EAGAIN) + if (err == EAGAIN) { fprintf(stderr, "aeApiAssociate: event port limit exceeded."); + } } return rv; @@ -155,8 +162,9 @@ static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { aeApiState *state = eventLoop->apidata; int fullmask, pfd; - if (evport_debug) + if (evport_debug) { fprintf(stderr, "aeApiAddEvent: fd %d mask 0x%x\n", fd, mask); + } /* * Since port_associate's "events" argument replaces any existing events, we @@ -173,8 +181,9 @@ static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { * it safer by simply updating pending_mask. The fd will be * re-associated as usual when aeApiPoll is called again. */ - if (evport_debug) + if (evport_debug) { fprintf(stderr, "aeApiAddEvent: adding to pending fd %d\n", fd); + } state->pending_masks[pfd] |= fullmask; return 0; } @@ -186,14 +195,16 @@ static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) { aeApiState *state = eventLoop->apidata; int fullmask, pfd; - if (evport_debug) + if (evport_debug) { fprintf(stderr, "del fd %d mask 0x%x\n", fd, mask); + } pfd = aeApiLookupPending(state, fd); if (pfd != -1) { - if (evport_debug) + if (evport_debug) { fprintf(stderr, "deleting event from pending fd %d\n", fd); + } /* * This fd was just returned from aeApiPoll, so it's not currently @@ -202,8 +213,9 @@ static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) { */ state->pending_masks[pfd] &= ~mask; - if (state->pending_masks[pfd] == AE_NONE) + if (state->pending_masks[pfd] == AE_NONE) { state->pending_fds[pfd] = -1; + } return; } @@ -222,15 +234,15 @@ static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) { * We're removing *all* events, so use port_dissociate to remove the * association completely. Failure here indicates a bug. */ - if (evport_debug) + if (evport_debug) { fprintf(stderr, "aeApiDelEvent: port_dissociate(%d)\n", fd); + } if (port_dissociate(state->portfd, PORT_SOURCE_FD, fd) != 0) { perror("aeApiDelEvent: port_dissociate"); abort(); /* will not return */ } - } else if (aeApiAssociate("aeApiDelEvent", state->portfd, fd, - fullmask) != 0) { + } else if (aeApiAssociate("aeApiDelEvent", state->portfd, fd, fullmask) != 0) { /* * ENOMEM is a potentially transient condition, but the kernel won't * generally return it unless things are really bad. EAGAIN indicates @@ -255,12 +267,12 @@ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { * this file for an explanation of why. */ for (i = 0; i < state->npending; i++) { - if (state->pending_fds[i] == -1) + if (state->pending_fds[i] == -1) { /* This fd has since been deleted. */ continue; + } - if (aeApiAssociate("aeApiPoll", state->portfd, - state->pending_fds[i], state->pending_masks[i]) != 0) { + if (aeApiAssociate("aeApiPoll", state->portfd, state->pending_fds[i], state->pending_masks[i]) != 0) { /* See aeApiDelEvent for why this case is fatal. */ abort(); } @@ -284,10 +296,10 @@ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { * So if we get ETIME, we check nevents, too. */ nevents = 1; - if (port_getn(state->portfd, event, MAX_EVENT_BATCHSZ, &nevents, - tsp) == -1 && (errno != ETIME || nevents == 0)) { - if (errno == ETIME || errno == EINTR) + if (port_getn(state->portfd, event, MAX_EVENT_BATCHSZ, &nevents, tsp) == -1 && (errno != ETIME || nevents == 0)) { + if (errno == ETIME || errno == EINTR) { return 0; + } /* Any other error indicates a bug. */ panic("aeApiPoll: port_getn, %s", strerror(errno)); @@ -296,21 +308,23 @@ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { state->npending = nevents; for (i = 0; i < nevents; i++) { - mask = 0; - if (event[i].portev_events & POLLIN) - mask |= AE_READABLE; - if (event[i].portev_events & POLLOUT) - mask |= AE_WRITABLE; + mask = 0; + if (event[i].portev_events & POLLIN) { + mask |= AE_READABLE; + } + if (event[i].portev_events & POLLOUT) { + mask |= AE_WRITABLE; + } - eventLoop->fired[i].fd = event[i].portev_object; - eventLoop->fired[i].mask = mask; + eventLoop->fired[i].fd = event[i].portev_object; + eventLoop->fired[i].mask = mask; - if (evport_debug) - fprintf(stderr, "aeApiPoll: fd %d mask 0x%x\n", - (int)event[i].portev_object, mask); + if (evport_debug) { + fprintf(stderr, "aeApiPoll: fd %d mask 0x%x\n", (int)event[i].portev_object, mask); + } - state->pending_fds[i] = event[i].portev_object; - state->pending_masks[i] = (uintptr_t)event[i].portev_user; + state->pending_fds[i] = event[i].portev_object; + state->pending_masks[i] = (uintptr_t)event[i].portev_user; } return nevents; diff --git a/src/ae_kqueue.c b/src/ae_kqueue.c index e8454245f..b31df9c72 100644 --- a/src/ae_kqueue.c +++ b/src/ae_kqueue.c @@ -40,7 +40,7 @@ typedef struct aeApiState { /* Events mask for merge read and write event. * To reduce memory consumption, we use 2 bits to store the mask * of an event, so that 1 byte will store the mask of 4 events. */ - char *eventsMask; + char *eventsMask; } aeApiState; #define EVENT_MASK_MALLOC_SIZE(sz) (((sz) + 3) / 4) @@ -48,22 +48,24 @@ typedef struct aeApiState { #define EVENT_MASK_ENCODE(fd, mask) (((mask) & 0x3) << EVENT_MASK_OFFSET(fd)) static inline int getEventMask(const char *eventsMask, int fd) { - return (eventsMask[fd/4] >> EVENT_MASK_OFFSET(fd)) & 0x3; + return (eventsMask[fd / 4] >> EVENT_MASK_OFFSET(fd)) & 0x3; } static inline void addEventMask(char *eventsMask, int fd, int mask) { - eventsMask[fd/4] |= EVENT_MASK_ENCODE(fd, mask); + eventsMask[fd / 4] |= EVENT_MASK_ENCODE(fd, mask); } static inline void resetEventMask(char *eventsMask, int fd) { - eventsMask[fd/4] &= ~EVENT_MASK_ENCODE(fd, 0x3); + eventsMask[fd / 4] &= ~EVENT_MASK_ENCODE(fd, 0x3); } static int aeApiCreate(aeEventLoop *eventLoop) { aeApiState *state = zmalloc(sizeof(aeApiState)); - if (!state) return -1; - state->events = zmalloc(sizeof(struct kevent)*eventLoop->setsize); + if (!state) { + return -1; + } + state->events = zmalloc(sizeof(struct kevent) * eventLoop->setsize); if (!state->events) { zfree(state); return -1; @@ -84,7 +86,7 @@ static int aeApiCreate(aeEventLoop *eventLoop) { static int aeApiResize(aeEventLoop *eventLoop, int setsize) { aeApiState *state = eventLoop->apidata; - state->events = zrealloc(state->events, sizeof(struct kevent)*setsize); + state->events = zrealloc(state->events, sizeof(struct kevent) * setsize); state->eventsMask = zrealloc(state->eventsMask, EVENT_MASK_MALLOC_SIZE(setsize)); memset(state->eventsMask, 0, EVENT_MASK_MALLOC_SIZE(setsize)); return 0; @@ -105,11 +107,15 @@ static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { if (mask & AE_READABLE) { EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, NULL); - if (kevent(state->kqfd, &ke, 1, NULL, 0, NULL) == -1) return -1; + if (kevent(state->kqfd, &ke, 1, NULL, 0, NULL) == -1) { + return -1; + } } if (mask & AE_WRITABLE) { EV_SET(&ke, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL); - if (kevent(state->kqfd, &ke, 1, NULL, 0, NULL) == -1) return -1; + if (kevent(state->kqfd, &ke, 1, NULL, 0, NULL) == -1) { + return -1; + } } return 0; } @@ -136,11 +142,9 @@ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { struct timespec timeout; timeout.tv_sec = tvp->tv_sec; timeout.tv_nsec = tvp->tv_usec * 1000; - retval = kevent(state->kqfd, NULL, 0, state->events, eventLoop->setsize, - &timeout); + retval = kevent(state->kqfd, NULL, 0, state->events, eventLoop->setsize, &timeout); } else { - retval = kevent(state->kqfd, NULL, 0, state->events, eventLoop->setsize, - NULL); + retval = kevent(state->kqfd, NULL, 0, state->events, eventLoop->setsize, NULL); } if (retval > 0) { @@ -148,18 +152,21 @@ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { /* Normally we execute the read event first and then the write event. * When the barrier is set, we will do it reverse. - * + * * However, under kqueue, read and write events would be separate * events, which would make it impossible to control the order of * reads and writes. So we store the event's mask we've got and merge * the same fd events later. */ for (j = 0; j < retval; j++) { - struct kevent *e = state->events+j; + struct kevent *e = state->events + j; int fd = e->ident; - int mask = 0; + int mask = 0; - if (e->filter == EVFILT_READ) mask = AE_READABLE; - else if (e->filter == EVFILT_WRITE) mask = AE_WRITABLE; + if (e->filter == EVFILT_READ) { + mask = AE_READABLE; + } else if (e->filter == EVFILT_WRITE) { + mask = AE_WRITABLE; + } addEventMask(state->eventsMask, fd, mask); } @@ -167,7 +174,7 @@ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { * 0 so that events are not added again when the fd is encountered again. */ numevents = 0; for (j = 0; j < retval; j++) { - struct kevent *e = state->events+j; + struct kevent *e = state->events + j; int fd = e->ident; int mask = getEventMask(state->eventsMask, fd); diff --git a/src/ae_select.c b/src/ae_select.c index f8ef95966..70a2e762c 100644 --- a/src/ae_select.c +++ b/src/ae_select.c @@ -42,7 +42,9 @@ typedef struct aeApiState { static int aeApiCreate(aeEventLoop *eventLoop) { aeApiState *state = zmalloc(sizeof(aeApiState)); - if (!state) return -1; + if (!state) { + return -1; + } FD_ZERO(&state->rfds); FD_ZERO(&state->wfds); eventLoop->apidata = state; @@ -52,7 +54,9 @@ static int aeApiCreate(aeEventLoop *eventLoop) { static int aeApiResize(aeEventLoop *eventLoop, int setsize) { AE_NOTUSED(eventLoop); /* Just ensure we have enough room in the fd_set type. */ - if (setsize >= FD_SETSIZE) return -1; + if (setsize >= FD_SETSIZE) { + return -1; + } return 0; } @@ -63,37 +67,48 @@ static void aeApiFree(aeEventLoop *eventLoop) { static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { aeApiState *state = eventLoop->apidata; - if (mask & AE_READABLE) FD_SET(fd,&state->rfds); - if (mask & AE_WRITABLE) FD_SET(fd,&state->wfds); + if (mask & AE_READABLE) { + FD_SET(fd, &state->rfds); + } + if (mask & AE_WRITABLE) { + FD_SET(fd, &state->wfds); + } return 0; } static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) { aeApiState *state = eventLoop->apidata; - if (mask & AE_READABLE) FD_CLR(fd,&state->rfds); - if (mask & AE_WRITABLE) FD_CLR(fd,&state->wfds); + if (mask & AE_READABLE) { + FD_CLR(fd, &state->rfds); + } + if (mask & AE_WRITABLE) { + FD_CLR(fd, &state->wfds); + } } static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { aeApiState *state = eventLoop->apidata; int retval, j, numevents = 0; - memcpy(&state->_rfds,&state->rfds,sizeof(fd_set)); - memcpy(&state->_wfds,&state->wfds,sizeof(fd_set)); + memcpy(&state->_rfds, &state->rfds, sizeof(fd_set)); + memcpy(&state->_wfds, &state->wfds, sizeof(fd_set)); - retval = select(eventLoop->maxfd+1, - &state->_rfds,&state->_wfds,NULL,tvp); + retval = select(eventLoop->maxfd + 1, &state->_rfds, &state->_wfds, NULL, tvp); if (retval > 0) { for (j = 0; j <= eventLoop->maxfd; j++) { int mask = 0; aeFileEvent *fe = &eventLoop->events[j]; - if (fe->mask == AE_NONE) continue; - if (fe->mask & AE_READABLE && FD_ISSET(j,&state->_rfds)) + if (fe->mask == AE_NONE) { + continue; + } + if (fe->mask & AE_READABLE && FD_ISSET(j, &state->_rfds)) { mask |= AE_READABLE; - if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds)) + } + if (fe->mask & AE_WRITABLE && FD_ISSET(j, &state->_wfds)) { mask |= AE_WRITABLE; + } eventLoop->fired[numevents].fd = j; eventLoop->fired[numevents].mask = mask; numevents++; diff --git a/src/anet.c b/src/anet.c index d90af6d9e..1c5f727ef 100644 --- a/src/anet.c +++ b/src/anet.c @@ -52,11 +52,12 @@ #define UNUSED(x) (void)(x) -static void anetSetError(char *err, const char *fmt, ...) -{ +static void anetSetError(char *err, const char *fmt, ...) { va_list ap; - if (!err) return; + if (!err) { + return; + } va_start(ap, fmt); vsnprintf(err, ANET_ERR_LEN, fmt, ap); va_end(ap); @@ -66,8 +67,9 @@ int anetGetError(int fd) { int sockerr = 0; socklen_t errlen = sizeof(sockerr); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &errlen) == -1) + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &errlen) == -1) { sockerr = errno; + } return sockerr; } @@ -84,13 +86,15 @@ int anetSetBlock(char *err, int fd, int non_block) { /* Check if this flag has been set or unset, if so, * then there is no need to call fcntl to set/unset it again. */ - if (!!(flags & O_NONBLOCK) == !!non_block) + if (!!(flags & O_NONBLOCK) == !!non_block) { return ANET_OK; + } - if (non_block) + if (non_block) { flags |= O_NONBLOCK; - else + } else { flags &= ~O_NONBLOCK; + } if (fcntl(fd, F_SETFL, flags) == -1) { anetSetError(err, "fcntl(F_SETFL,O_NONBLOCK): %s", strerror(errno)); @@ -100,11 +104,11 @@ int anetSetBlock(char *err, int fd, int non_block) { } int anetNonBlock(char *err, int fd) { - return anetSetBlock(err,fd,1); + return anetSetBlock(err, fd, 1); } int anetBlock(char *err, int fd) { - return anetSetBlock(err,fd,0); + return anetSetBlock(err, fd, 0); } /* Enable the FD_CLOEXEC on the given fd to avoid fd leaks. @@ -118,8 +122,9 @@ int anetCloexec(int fd) { r = fcntl(fd, F_GETFD); } while (r == -1 && errno == EINTR); - if (r == -1 || (r & FD_CLOEXEC)) + if (r == -1 || (r & FD_CLOEXEC)) { return r; + } flags = r | FD_CLOEXEC; @@ -132,11 +137,9 @@ int anetCloexec(int fd) { /* Enable TCP keep-alive mechanism to detect dead peers, * TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT will be set accordingly. */ -int anetKeepAlive(char *err, int fd, int interval) -{ +int anetKeepAlive(char *err, int fd, int interval) { int enabled = 1; - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enabled, sizeof(enabled))) - { + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enabled, sizeof(enabled))) { anetSetError(err, "setsockopt SO_KEEPALIVE: %s", strerror(errno)); return ANET_ERR; } @@ -149,9 +152,8 @@ int anetKeepAlive(char *err, int fd, int interval) * we want the compiler to emit warnings of unused variables if the preprocessor directives * somehow fail, and other than those platforms, just omit these warnings if they happen. */ -#if !(defined(_AIX) || defined(__APPLE__) || defined(__DragonFly__) || \ - defined(__FreeBSD__) || defined(__illumos__) || defined(__linux__) || \ - defined(__NetBSD__) || defined(__sun)) +#if !(defined(_AIX) || defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__illumos__) || \ + defined(__linux__) || defined(__NetBSD__) || defined(__sun)) UNUSED(interval); UNUSED(idle); UNUSED(intvl); @@ -168,22 +170,27 @@ int anetKeepAlive(char *err, int fd, int interval) * If the peer does not respond to the probe within eight minutes, the TCP connection is aborted. * You can alter the interval for sending out the first probe using the socket option TCP_KEEPALIVE_THRESHOLD * in milliseconds or TCP_KEEPIDLE in seconds. - * The system default is controlled by the TCP ndd parameter tcp_keepalive_interval. The minimum value is ten seconds. - * The maximum is ten days, while the default is two hours. If you receive no response to the probe, - * you can use the TCP_KEEPALIVE_ABORT_THRESHOLD socket option to change the time threshold for aborting a TCP connection. - * The option value is an unsigned integer in milliseconds. The value zero indicates that TCP should never time out and - * abort the connection when probing. The system default is controlled by the TCP ndd parameter tcp_keepalive_abort_interval. - * The default is eight minutes. + * The system default is controlled by the TCP ndd parameter tcp_keepalive_interval. The minimum value is ten + * seconds. The maximum is ten days, while the default is two hours. If you receive no response to the probe, you + * can use the TCP_KEEPALIVE_ABORT_THRESHOLD socket option to change the time threshold for aborting a TCP + * connection. The option value is an unsigned integer in milliseconds. The value zero indicates that TCP should + * never time out and abort the connection when probing. The system default is controlled by the TCP ndd parameter + * tcp_keepalive_abort_interval. The default is eight minutes. * * - The second implementation is activated if socket option TCP_KEEPINTVL and/or TCP_KEEPCNT are set. * The time between each consequent probes is set by TCP_KEEPINTVL in seconds. * The minimum value is ten seconds. The maximum is ten days, while the default is two hours. - * The TCP connection will be aborted after certain amount of probes, which is set by TCP_KEEPCNT, without receiving response. + * The TCP connection will be aborted after certain amount of probes, which is set by TCP_KEEPCNT, without receiving + * response. */ idle = interval; - if (idle < 10) idle = 10; // kernel expects at least 10 seconds - if (idle > 10*24*60*60) idle = 10*24*60*60; // kernel expects at most 10 days + if (idle < 10) { + idle = 10; // kernel expects at least 10 seconds + } + if (idle > 10 * 24 * 60 * 60) { + idle = 10 * 24 * 60 * 60; // kernel expects at most 10 days + } /* `TCP_KEEPIDLE`, `TCP_KEEPINTVL`, and `TCP_KEEPCNT` were not available on Solaris * until version 11.4, but let's take a chance here. */ @@ -193,8 +200,10 @@ int anetKeepAlive(char *err, int fd, int interval) return ANET_ERR; } - intvl = idle/3; - if (intvl < 10) intvl = 10; /* kernel expects at least 10 seconds */ + intvl = idle / 3; + if (intvl < 10) { + intvl = 10; /* kernel expects at least 10 seconds */ + } if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl))) { anetSetError(err, "setsockopt TCP_KEEPINTVL: %s\n", strerror(errno)); return ANET_ERR; @@ -207,7 +216,8 @@ int anetKeepAlive(char *err, int fd, int interval) } #else /* Fall back to the first implementation of tcp-alive mechanism for older Solaris, - * simulate the tcp-alive mechanism on other platforms via `TCP_KEEPALIVE_THRESHOLD` + `TCP_KEEPALIVE_ABORT_THRESHOLD`. + * simulate the tcp-alive mechanism on other platforms via `TCP_KEEPALIVE_THRESHOLD` + + * `TCP_KEEPALIVE_ABORT_THRESHOLD`. */ idle *= 1000; // kernel expects milliseconds if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD, &idle, sizeof(idle))) { @@ -252,8 +262,10 @@ int anetKeepAlive(char *err, int fd, int interval) /* Send next probes after the specified interval. Note that we set the * delay as interval / 3, as we send three probes before detecting * an error (see the next setsockopt call). */ - intvl = interval/3; - if (intvl == 0) intvl = 1; + intvl = interval / 3; + if (intvl == 0) { + intvl = 1; + } if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl))) { anetSetError(err, "setsockopt TCP_KEEPINTVL: %s\n", strerror(errno)); return ANET_ERR; @@ -273,23 +285,19 @@ int anetKeepAlive(char *err, int fd, int interval) return ANET_OK; } -static int anetSetTcpNoDelay(char *err, int fd, int val) -{ - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) == -1) - { +static int anetSetTcpNoDelay(char *err, int fd, int val) { + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) == -1) { anetSetError(err, "setsockopt TCP_NODELAY: %s", strerror(errno)); return ANET_ERR; } return ANET_OK; } -int anetEnableTcpNoDelay(char *err, int fd) -{ +int anetEnableTcpNoDelay(char *err, int fd) { return anetSetTcpNoDelay(err, fd, 1); } -int anetDisableTcpNoDelay(char *err, int fd) -{ +int anetDisableTcpNoDelay(char *err, int fd) { return anetSetTcpNoDelay(err, fd, 0); } @@ -298,8 +306,8 @@ int anetDisableTcpNoDelay(char *err, int fd) int anetSendTimeout(char *err, int fd, long long ms) { struct timeval tv; - tv.tv_sec = ms/1000; - tv.tv_usec = (ms%1000)*1000; + tv.tv_sec = ms / 1000; + tv.tv_usec = (ms % 1000) * 1000; if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) { anetSetError(err, "setsockopt SO_SNDTIMEO: %s", strerror(errno)); return ANET_ERR; @@ -312,8 +320,8 @@ int anetSendTimeout(char *err, int fd, long long ms) { int anetRecvTimeout(char *err, int fd, long long ms) { struct timeval tv; - tv.tv_sec = ms/1000; - tv.tv_usec = (ms%1000)*1000; + tv.tv_sec = ms / 1000; + tv.tv_usec = (ms % 1000) * 1000; if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) { anetSetError(err, "setsockopt SO_RCVTIMEO: %s", strerror(errno)); return ANET_ERR; @@ -331,21 +339,21 @@ int anetRecvTimeout(char *err, int fd, long long ms) { * If the flag ANET_PREFER_IPV4 is set, IPv4 is preferred over IPv6. * If the flag ANET_PREFER_IPV6 is set, IPv6 is preferred over IPv4. * */ -int anetResolve(char *err, char *host, char *ipbuf, size_t ipbuf_len, - int flags) -{ +int anetResolve(char *err, char *host, char *ipbuf, size_t ipbuf_len, int flags) { struct addrinfo hints, *info; int rv; - memset(&hints,0,sizeof(hints)); - if (flags & ANET_IP_ONLY) hints.ai_flags = AI_NUMERICHOST; + memset(&hints, 0, sizeof(hints)); + if (flags & ANET_IP_ONLY) { + hints.ai_flags = AI_NUMERICHOST; + } hints.ai_family = AF_UNSPEC; if (flags & ANET_PREFER_IPV4 && !(flags & ANET_PREFER_IPV6)) { hints.ai_family = AF_INET; } else if (flags & ANET_PREFER_IPV6 && !(flags & ANET_PREFER_IPV4)) { hints.ai_family = AF_INET6; } - hints.ai_socktype = SOCK_STREAM; /* specify socktype to avoid dups */ + hints.ai_socktype = SOCK_STREAM; /* specify socktype to avoid dups */ rv = getaddrinfo(host, NULL, &hints, &info); if (rv != 0 && hints.ai_family != AF_UNSPEC) { @@ -393,15 +401,15 @@ static int anetCreateSocket(char *err, int domain, int type, int protocol, int f #ifdef SOCK_CLOEXEC if (flags & ANET_SOCKET_CLOEXEC) { - type |= SOCK_CLOEXEC; - flags &= ~ANET_SOCKET_CLOEXEC; + type |= SOCK_CLOEXEC; + flags &= ~ANET_SOCKET_CLOEXEC; } #endif #ifdef SOCK_NONBLOCK if (flags & ANET_SOCKET_NONBLOCK) { - type |= SOCK_NONBLOCK; - flags &= ~ANET_SOCKET_NONBLOCK; + type |= SOCK_NONBLOCK; + flags &= ~ANET_SOCKET_NONBLOCK; } #endif @@ -420,7 +428,7 @@ static int anetCreateSocket(char *err, int domain, int type, int protocol, int f return ANET_ERR; } - if (flags & ANET_SOCKET_REUSEADDR && anetSetReuseAddr(err,s) == ANET_ERR) { + if (flags & ANET_SOCKET_REUSEADDR && anetSetReuseAddr(err, s) == ANET_ERR) { close(s); return ANET_ERR; } @@ -431,19 +439,17 @@ static int anetCreateSocket(char *err, int domain, int type, int protocol, int f #define ANET_CONNECT_NONE 0 #define ANET_CONNECT_NONBLOCK 1 #define ANET_CONNECT_BE_BINDING 2 /* Best effort binding. */ -static int anetTcpGenericConnect(char *err, const char *addr, int port, - const char *source_addr, int flags) -{ +static int anetTcpGenericConnect(char *err, const char *addr, int port, const char *source_addr, int flags) { int s = ANET_ERR, rv; - char portstr[6]; /* strlen("65535") + 1; */ + char portstr[6]; /* strlen("65535") + 1; */ struct addrinfo hints, *servinfo, *bservinfo, *p, *b; - snprintf(portstr,sizeof(portstr),"%d",port); - memset(&hints,0,sizeof(hints)); + snprintf(portstr, sizeof(portstr), "%d", port); + memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - if ((rv = getaddrinfo(addr,portstr,&hints,&servinfo)) != 0) { + if ((rv = getaddrinfo(addr, portstr, &hints, &servinfo)) != 0) { anetSetError(err, "%s", gai_strerror(rv)); return ANET_ERR; } @@ -456,19 +462,21 @@ static int anetTcpGenericConnect(char *err, const char *addr, int port, * will be able to close/open sockets a zillion of times. */ int sockflags = ANET_SOCKET_CLOEXEC | ANET_SOCKET_REUSEADDR; - if (flags & ANET_CONNECT_NONBLOCK) sockflags |= ANET_SOCKET_NONBLOCK; - if ((s = anetCreateSocket(err,p->ai_family,p->ai_socktype,p->ai_protocol,sockflags)) == ANET_ERR) + if (flags & ANET_CONNECT_NONBLOCK) { + sockflags |= ANET_SOCKET_NONBLOCK; + } + if ((s = anetCreateSocket(err, p->ai_family, p->ai_socktype, p->ai_protocol, sockflags)) == ANET_ERR) { continue; + } if (source_addr) { int bound = 0; /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */ - if ((rv = getaddrinfo(source_addr, NULL, &hints, &bservinfo)) != 0) - { + if ((rv = getaddrinfo(source_addr, NULL, &hints, &bservinfo)) != 0) { anetSetError(err, "%s", gai_strerror(rv)); goto error; } for (b = bservinfo; b != NULL; b = b->ai_next) { - if (bind(s,b->ai_addr,b->ai_addrlen) != -1) { + if (bind(s, b->ai_addr, b->ai_addrlen) != -1) { bound = 1; break; } @@ -479,11 +487,12 @@ static int anetTcpGenericConnect(char *err, const char *addr, int port, goto error; } } - if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { + if (connect(s, p->ai_addr, p->ai_addrlen) == -1) { /* If the socket is non-blocking, it is ok for connect() to * return an EINPROGRESS error here. */ - if (errno == EINPROGRESS && flags & ANET_CONNECT_NONBLOCK) + if (errno == EINPROGRESS && flags & ANET_CONNECT_NONBLOCK) { goto end; + } close(s); s = ANET_ERR; continue; @@ -493,8 +502,9 @@ static int anetTcpGenericConnect(char *err, const char *addr, int port, * have a connected socket. Let's return to the caller. */ goto end; } - if (p == NULL) + if (p == NULL) { anetSetError(err, "creating socket: %s", strerror(errno)); + } error: if (s != ANET_ERR) { @@ -508,33 +518,30 @@ static int anetTcpGenericConnect(char *err, const char *addr, int port, /* Handle best effort binding: if a binding address was used, but it is * not possible to create a socket, try again without a binding address. */ if (s == ANET_ERR && source_addr && (flags & ANET_CONNECT_BE_BINDING)) { - return anetTcpGenericConnect(err,addr,port,NULL,flags); + return anetTcpGenericConnect(err, addr, port, NULL, flags); } else { return s; } } -int anetTcpNonBlockConnect(char *err, const char *addr, int port) -{ - return anetTcpGenericConnect(err,addr,port,NULL,ANET_CONNECT_NONBLOCK); +int anetTcpNonBlockConnect(char *err, const char *addr, int port) { + return anetTcpGenericConnect(err, addr, port, NULL, ANET_CONNECT_NONBLOCK); } -int anetTcpNonBlockBestEffortBindConnect(char *err, const char *addr, int port, - const char *source_addr) -{ - return anetTcpGenericConnect(err,addr,port,source_addr, - ANET_CONNECT_NONBLOCK|ANET_CONNECT_BE_BINDING); +int anetTcpNonBlockBestEffortBindConnect(char *err, const char *addr, int port, const char *source_addr) { + return anetTcpGenericConnect(err, addr, port, source_addr, ANET_CONNECT_NONBLOCK | ANET_CONNECT_BE_BINDING); } static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog, mode_t perm) { - if (bind(s,sa,len) == -1) { + if (bind(s, sa, len) == -1) { anetSetError(err, "bind: %s", strerror(errno)); close(s); return ANET_ERR; } - if (sa->sa_family == AF_LOCAL && perm) - chmod(((struct sockaddr_un *) sa)->sun_path, perm); + if (sa->sa_family == AF_LOCAL && perm) { + chmod(((struct sockaddr_un *)sa)->sun_path, perm); + } if (listen(s, backlog) == -1) { anetSetError(err, "listen: %s", strerror(errno)); @@ -546,40 +553,48 @@ static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int static int anetV6Only(char *err, int s) { int yes = 1; - if (setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,&yes,sizeof(yes)) == -1) { + if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes)) == -1) { anetSetError(err, "setsockopt: %s", strerror(errno)); return ANET_ERR; } return ANET_OK; } -static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backlog) -{ +static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backlog) { int s = -1, rv; - char _port[6]; /* strlen("65535") */ + char _port[6]; /* strlen("65535") */ struct addrinfo hints, *servinfo, *p; - snprintf(_port,6,"%d",port); - memset(&hints,0,sizeof(hints)); + snprintf(_port, 6, "%d", port); + memset(&hints, 0, sizeof(hints)); hints.ai_family = af; hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; /* No effect if bindaddr != NULL */ - if (bindaddr && !strcmp("*", bindaddr)) + hints.ai_flags = AI_PASSIVE; /* No effect if bindaddr != NULL */ + if (bindaddr && !strcmp("*", bindaddr)) { bindaddr = NULL; - if (af == AF_INET6 && bindaddr && !strcmp("::*", bindaddr)) + } + if (af == AF_INET6 && bindaddr && !strcmp("::*", bindaddr)) { bindaddr = NULL; + } - if ((rv = getaddrinfo(bindaddr,_port,&hints,&servinfo)) != 0) { + if ((rv = getaddrinfo(bindaddr, _port, &hints, &servinfo)) != 0) { anetSetError(err, "%s", gai_strerror(rv)); return ANET_ERR; } for (p = servinfo; p != NULL; p = p->ai_next) { - if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1) + if ((s = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { continue; + } - if (af == AF_INET6 && anetV6Only(err,s) == ANET_ERR) goto error; - if (anetSetReuseAddr(err,s) == ANET_ERR) goto error; - if (anetListen(err,s,p->ai_addr,p->ai_addrlen,backlog,0) == ANET_ERR) s = ANET_ERR; + if (af == AF_INET6 && anetV6Only(err, s) == ANET_ERR) { + goto error; + } + if (anetSetReuseAddr(err, s) == ANET_ERR) { + goto error; + } + if (anetListen(err, s, p->ai_addr, p->ai_addrlen, backlog, 0) == ANET_ERR) { + s = ANET_ERR; + } goto end; } if (p == NULL) { @@ -588,43 +603,44 @@ static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backl } error: - if (s != -1) close(s); + if (s != -1) { + close(s); + } s = ANET_ERR; end: freeaddrinfo(servinfo); return s; } -int anetTcpServer(char *err, int port, char *bindaddr, int backlog) -{ +int anetTcpServer(char *err, int port, char *bindaddr, int backlog) { return _anetTcpServer(err, port, bindaddr, AF_INET, backlog); } -int anetTcp6Server(char *err, int port, char *bindaddr, int backlog) -{ +int anetTcp6Server(char *err, int port, char *bindaddr, int backlog) { return _anetTcpServer(err, port, bindaddr, AF_INET6, backlog); } -int anetUnixServer(char *err, char *path, mode_t perm, int backlog) -{ +int anetUnixServer(char *err, char *path, mode_t perm, int backlog) { int s; struct sockaddr_un sa; - if (strlen(path) > sizeof(sa.sun_path)-1) { - anetSetError(err,"unix socket path too long (%zu), must be under %zu", strlen(path), sizeof(sa.sun_path)); + if (strlen(path) > sizeof(sa.sun_path) - 1) { + anetSetError(err, "unix socket path too long (%zu), must be under %zu", strlen(path), sizeof(sa.sun_path)); return ANET_ERR; } int type = SOCK_STREAM; int flags = ANET_SOCKET_CLOEXEC | ANET_SOCKET_NONBLOCK | ANET_SOCKET_REUSEADDR; - if ((s = anetCreateSocket(err,AF_LOCAL,type,0,flags)) == ANET_ERR) + if ((s = anetCreateSocket(err, AF_LOCAL, type, 0, flags)) == ANET_ERR) { return ANET_ERR; + } - memset(&sa,0,sizeof(sa)); + memset(&sa, 0, sizeof(sa)); sa.sun_family = AF_LOCAL; - valkey_strlcpy(sa.sun_path,path,sizeof(sa.sun_path)); - if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog,perm) == ANET_ERR) + valkey_strlcpy(sa.sun_path, path, sizeof(sa.sun_path)); + if (anetListen(err, s, (struct sockaddr *)&sa, sizeof(sa), backlog, perm) == ANET_ERR) { return ANET_ERR; + } return s; } @@ -636,11 +652,11 @@ static int anetGenericAccept(char *err, int s, struct sockaddr *sa, socklen_t *l /* Use the accept4() call on linux to simultaneously accept and * set a socket as non-blocking. */ #ifdef HAVE_ACCEPT4 - fd = accept4(s, sa, len, SOCK_NONBLOCK | SOCK_CLOEXEC); + fd = accept4(s, sa, len, SOCK_NONBLOCK | SOCK_CLOEXEC); #else - fd = accept(s,sa,len); + fd = accept(s, sa, len); #endif - } while(fd == -1 && errno == EINTR); + } while (fd == -1 && errno == EINTR); if (fd == -1) { anetSetError(err, "accept: %s", strerror(errno)); return ANET_ERR; @@ -665,17 +681,26 @@ int anetTcpAccept(char *err, int serversock, char *ip, size_t ip_len, int *port) int fd; struct sockaddr_storage sa; socklen_t salen = sizeof(sa); - if ((fd = anetGenericAccept(err,serversock,(struct sockaddr*)&sa,&salen)) == ANET_ERR) + if ((fd = anetGenericAccept(err, serversock, (struct sockaddr *)&sa, &salen)) == ANET_ERR) { return ANET_ERR; + } if (sa.ss_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in *)&sa; - if (ip) inet_ntop(AF_INET,(void*)&(s->sin_addr),ip,ip_len); - if (port) *port = ntohs(s->sin_port); + if (ip) { + inet_ntop(AF_INET, (void *)&(s->sin_addr), ip, ip_len); + } + if (port) { + *port = ntohs(s->sin_port); + } } else { struct sockaddr_in6 *s = (struct sockaddr_in6 *)&sa; - if (ip) inet_ntop(AF_INET6,(void*)&(s->sin6_addr),ip,ip_len); - if (port) *port = ntohs(s->sin6_port); + if (ip) { + inet_ntop(AF_INET6, (void *)&(s->sin6_addr), ip, ip_len); + } + if (port) { + *port = ntohs(s->sin6_port); + } } return fd; } @@ -686,8 +711,9 @@ int anetUnixAccept(char *err, int s) { int fd; struct sockaddr_un sa; socklen_t salen = sizeof(sa); - if ((fd = anetGenericAccept(err,s,(struct sockaddr*)&sa,&salen)) == ANET_ERR) + if ((fd = anetGenericAccept(err, s, (struct sockaddr *)&sa, &salen)) == ANET_ERR) { return ANET_ERR; + } return fd; } @@ -697,31 +723,45 @@ int anetFdToString(int fd, char *ip, size_t ip_len, int *port, int remote) { socklen_t salen = sizeof(sa); if (remote) { - if (getpeername(fd, (struct sockaddr *)&sa, &salen) == -1) goto error; + if (getpeername(fd, (struct sockaddr *)&sa, &salen) == -1) { + goto error; + } } else { - if (getsockname(fd, (struct sockaddr *)&sa, &salen) == -1) goto error; + if (getsockname(fd, (struct sockaddr *)&sa, &salen) == -1) { + goto error; + } } if (sa.ss_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in *)&sa; if (ip) { - if (inet_ntop(AF_INET,(void*)&(s->sin_addr),ip,ip_len) == NULL) + if (inet_ntop(AF_INET, (void *)&(s->sin_addr), ip, ip_len) == NULL) { goto error; + } + } + if (port) { + *port = ntohs(s->sin_port); } - if (port) *port = ntohs(s->sin_port); } else if (sa.ss_family == AF_INET6) { struct sockaddr_in6 *s = (struct sockaddr_in6 *)&sa; if (ip) { - if (inet_ntop(AF_INET6,(void*)&(s->sin6_addr),ip,ip_len) == NULL) + if (inet_ntop(AF_INET6, (void *)&(s->sin6_addr), ip, ip_len) == NULL) { goto error; + } + } + if (port) { + *port = ntohs(s->sin6_port); } - if (port) *port = ntohs(s->sin6_port); } else if (sa.ss_family == AF_UNIX) { if (ip) { int res = snprintf(ip, ip_len, "/unixsocket"); - if (res < 0 || (unsigned int) res >= ip_len) goto error; + if (res < 0 || (unsigned int)res >= ip_len) { + goto error; + } + } + if (port) { + *port = 0; } - if (port) *port = 0; } else { goto error; } @@ -736,7 +776,9 @@ int anetFdToString(int fd, char *ip, size_t ip_len, int *port, int remote) { ip[0] = '\0'; } } - if (port) *port = 0; + if (port) { + *port = 0; + } return -1; } @@ -751,13 +793,15 @@ int anetPipe(int fds[2], int read_flags, int write_flags) { pipe_flags = O_CLOEXEC | (read_flags & write_flags); if (pipe2(fds, pipe_flags)) { /* Fail on real failures, and fallback to simple pipe if pipe2 is unsupported. */ - if (errno != ENOSYS && errno != EINVAL) + if (errno != ENOSYS && errno != EINVAL) { return -1; + } pipe_flags = 0; } else { /* If the flags on both ends are identical, no need to do anything else. */ - if ((O_CLOEXEC | read_flags) == (O_CLOEXEC | write_flags)) + if ((O_CLOEXEC | read_flags) == (O_CLOEXEC | write_flags)) { return 0; + } /* Clear the flags which have already been set using pipe2. */ read_flags &= ~pipe_flags; write_flags &= ~pipe_flags; @@ -766,27 +810,36 @@ int anetPipe(int fds[2], int read_flags, int write_flags) { /* When we reach here with pipe_flags of 0, it means pipe2 failed (or was not attempted), * so we try to use pipe. Otherwise, we skip and proceed to set specific flags below. */ - if (pipe_flags == 0 && pipe(fds)) + if (pipe_flags == 0 && pipe(fds)) { return -1; + } /* File descriptor flags. * Currently, only one such flag is defined: FD_CLOEXEC, the close-on-exec flag. */ - if (read_flags & O_CLOEXEC) - if (fcntl(fds[0], F_SETFD, FD_CLOEXEC)) + if (read_flags & O_CLOEXEC) { + if (fcntl(fds[0], F_SETFD, FD_CLOEXEC)) { goto error; - if (write_flags & O_CLOEXEC) - if (fcntl(fds[1], F_SETFD, FD_CLOEXEC)) + } + } + if (write_flags & O_CLOEXEC) { + if (fcntl(fds[1], F_SETFD, FD_CLOEXEC)) { goto error; + } + } /* File status flags after clearing the file descriptor flag O_CLOEXEC. */ read_flags &= ~O_CLOEXEC; - if (read_flags) - if (fcntl(fds[0], F_SETFL, read_flags)) + if (read_flags) { + if (fcntl(fds[0], F_SETFL, read_flags)) { goto error; + } + } write_flags &= ~O_CLOEXEC; - if (write_flags) - if (fcntl(fds[1], F_SETFL, write_flags)) + if (write_flags) { + if (fcntl(fds[1], F_SETFL, write_flags)) { goto error; + } + } return 0; @@ -806,13 +859,15 @@ int anetSetSockMarkId(char *err, int fd, uint32_t id) { #else UNUSED(fd); UNUSED(id); - anetSetError(err,"anetSetSockMarkid unsupported on this platform"); + anetSetError(err, "anetSetSockMarkid unsupported on this platform"); return ANET_OK; #endif } int anetIsFifo(char *filepath) { struct stat sb; - if (stat(filepath, &sb) == -1) return 0; + if (stat(filepath, &sb) == -1) { + return 0; + } return S_ISFIFO(sb.st_mode); } diff --git a/src/anet.h b/src/anet.h index 08e01a4bc..c3642f8e7 100644 --- a/src/anet.h +++ b/src/anet.h @@ -39,9 +39,9 @@ /* Flags used with certain functions. */ #define ANET_NONE 0 -#define ANET_IP_ONLY (1<<0) -#define ANET_PREFER_IPV4 (1<<1) -#define ANET_PREFER_IPV6 (1<<2) +#define ANET_IP_ONLY (1 << 0) +#define ANET_PREFER_IPV4 (1 << 1) +#define ANET_PREFER_IPV6 (1 << 2) #if defined(__sun) || defined(_AIX) #define AF_LOCAL AF_UNIX diff --git a/src/aof.c b/src/aof.c index 00914d1e6..4b4b995d0 100644 --- a/src/aof.c +++ b/src/aof.c @@ -83,17 +83,17 @@ void aof_background_fsync_and_close(int fd); * ------------------------------------------------------------------------- */ /* Naming rules. */ -#define BASE_FILE_SUFFIX ".base" -#define INCR_FILE_SUFFIX ".incr" -#define RDB_FORMAT_SUFFIX ".rdb" -#define AOF_FORMAT_SUFFIX ".aof" -#define MANIFEST_NAME_SUFFIX ".manifest" -#define TEMP_FILE_NAME_PREFIX "temp-" +#define BASE_FILE_SUFFIX ".base" +#define INCR_FILE_SUFFIX ".incr" +#define RDB_FORMAT_SUFFIX ".rdb" +#define AOF_FORMAT_SUFFIX ".aof" +#define MANIFEST_NAME_SUFFIX ".manifest" +#define TEMP_FILE_NAME_PREFIX "temp-" /* AOF manifest key. */ -#define AOF_MANIFEST_KEY_FILE_NAME "file" -#define AOF_MANIFEST_KEY_FILE_SEQ "seq" -#define AOF_MANIFEST_KEY_FILE_TYPE "type" +#define AOF_MANIFEST_KEY_FILE_NAME "file" +#define AOF_MANIFEST_KEY_FILE_SEQ "seq" +#define AOF_MANIFEST_KEY_FILE_TYPE "type" /* Create an empty aofInfo. */ aofInfo *aofInfoCreate(void) { @@ -103,7 +103,9 @@ aofInfo *aofInfoCreate(void) { /* Free the aofInfo structure (pointed to by ai) and its embedded file_name. */ void aofInfoFree(aofInfo *ai) { serverAssert(ai != NULL); - if (ai->file_name) sdsfree(ai->file_name); + if (ai->file_name) { + sdsfree(ai->file_name); + } zfree(ai); } @@ -123,13 +125,13 @@ aofInfo *aofInfoDup(aofInfo *orig) { sds aofInfoFormat(sds buf, aofInfo *ai) { sds filename_repr = NULL; - if (sdsneedsrepr(ai->file_name)) + if (sdsneedsrepr(ai->file_name)) { filename_repr = sdscatrepr(sdsempty(), ai->file_name, sdslen(ai->file_name)); + } - sds ret = sdscatprintf(buf, "%s %s %s %lld %s %c\n", - AOF_MANIFEST_KEY_FILE_NAME, filename_repr ? filename_repr : ai->file_name, - AOF_MANIFEST_KEY_FILE_SEQ, ai->file_seq, - AOF_MANIFEST_KEY_FILE_TYPE, ai->file_type); + sds ret = sdscatprintf(buf, "%s %s %s %lld %s %c\n", AOF_MANIFEST_KEY_FILE_NAME, + filename_repr ? filename_repr : ai->file_name, AOF_MANIFEST_KEY_FILE_SEQ, ai->file_seq, + AOF_MANIFEST_KEY_FILE_TYPE, ai->file_type); sdsfree(filename_repr); return ret; @@ -160,20 +162,24 @@ aofManifest *aofManifestCreate(void) { /* Free the aofManifest structure (pointed to by am) and its embedded members. */ void aofManifestFree(aofManifest *am) { - if (am->base_aof_info) aofInfoFree(am->base_aof_info); - if (am->incr_aof_list) listRelease(am->incr_aof_list); - if (am->history_aof_list) listRelease(am->history_aof_list); + if (am->base_aof_info) { + aofInfoFree(am->base_aof_info); + } + if (am->incr_aof_list) { + listRelease(am->incr_aof_list); + } + if (am->history_aof_list) { + listRelease(am->history_aof_list); + } zfree(am); } sds getAofManifestFileName(void) { - return sdscatprintf(sdsempty(), "%s%s", server.aof_filename, - MANIFEST_NAME_SUFFIX); + return sdscatprintf(sdsempty(), "%s%s", server.aof_filename, MANIFEST_NAME_SUFFIX); } sds getTempAofManifestFileName(void) { - return sdscatprintf(sdsempty(), "%s%s%s", TEMP_FILE_NAME_PREFIX, - server.aof_filename, MANIFEST_NAME_SUFFIX); + return sdscatprintf(sdsempty(), "%s%s%s", TEMP_FILE_NAME_PREFIX, server.aof_filename, MANIFEST_NAME_SUFFIX); } /* Returns the string representation of aofManifest pointed to by am. @@ -207,14 +213,14 @@ sds getAofManifestAsString(aofManifest *am) { /* 2. Add HISTORY type AOF information. */ listRewind(am->history_aof_list, &li); while ((ln = listNext(&li)) != NULL) { - aofInfo *ai = (aofInfo*)ln->value; + aofInfo *ai = (aofInfo *)ln->value; buf = aofInfoFormat(buf, ai); } /* 3. Add INCR type AOF information. */ listRewind(am->incr_aof_list, &li); while ((ln = listNext(&li)) != NULL) { - aofInfo *ai = (aofInfo*)ln->value; + aofInfo *ai = (aofInfo *)ln->value; buf = aofInfoFormat(buf, ai); } @@ -248,7 +254,9 @@ void aofLoadManifestFromDisk(void) { } aofManifest *am = aofLoadManifestFromFile(am_filepath); - if (am) aofManifestFreeAndUpdate(am); + if (am) { + aofManifestFreeAndUpdate(am); + } sdsfree(am_name); sdsfree(am_filepath); } @@ -262,12 +270,14 @@ aofManifest *aofLoadManifestFromFile(sds am_filepath) { aofManifest *am = aofManifestCreate(); FILE *fp = fopen(am_filepath, "r"); if (fp == NULL) { - serverLog(LL_WARNING, "Fatal error: can't open the AOF manifest " - "file %s for reading: %s", am_filepath, strerror(errno)); + serverLog(LL_WARNING, + "Fatal error: can't open the AOF manifest " + "file %s for reading: %s", + am_filepath, strerror(errno)); exit(1); } - char buf[MANIFEST_MAX_LINE+1]; + char buf[MANIFEST_MAX_LINE + 1]; sds *argv = NULL; int argc; aofInfo *ai = NULL; @@ -276,7 +286,7 @@ aofManifest *aofLoadManifestFromFile(sds am_filepath) { int linenum = 0; while (1) { - if (fgets(buf, MANIFEST_MAX_LINE+1, fp) == NULL) { + if (fgets(buf, MANIFEST_MAX_LINE + 1, fp) == NULL) { if (feof(fp)) { if (linenum == 0) { err = "Found an empty AOF manifest"; @@ -293,7 +303,9 @@ aofManifest *aofLoadManifestFromFile(sds am_filepath) { linenum++; /* Skip comments lines */ - if (buf[0] == '#') continue; + if (buf[0] == '#') { + continue; + } if (strchr(buf, '\n') == NULL) { err = "The AOF manifest file contains too long line"; @@ -316,15 +328,15 @@ aofManifest *aofLoadManifestFromFile(sds am_filepath) { ai = aofInfoCreate(); for (int i = 0; i < argc; i += 2) { if (!strcasecmp(argv[i], AOF_MANIFEST_KEY_FILE_NAME)) { - ai->file_name = sdsnew(argv[i+1]); + ai->file_name = sdsnew(argv[i + 1]); if (!pathIsBaseName(ai->file_name)) { err = "File can't be a path, just a filename"; goto loaderr; } } else if (!strcasecmp(argv[i], AOF_MANIFEST_KEY_FILE_SEQ)) { - ai->file_seq = atoll(argv[i+1]); + ai->file_seq = atoll(argv[i + 1]); } else if (!strcasecmp(argv[i], AOF_MANIFEST_KEY_FILE_TYPE)) { - ai->file_type = (argv[i+1])[0]; + ai->file_type = (argv[i + 1])[0]; } /* else if (!strcasecmp(argv[i], AOF_MANIFEST_KEY_OTHER)) {} */ } @@ -371,8 +383,12 @@ aofManifest *aofLoadManifestFromFile(sds am_filepath) { loaderr: /* Sanitizer suppression: may report a false positive if we goto loaderr * and exit(1) without freeing these allocations. */ - if (argv) sdsfreesplitres(argv, argc); - if (ai) aofInfoFree(ai); + if (argv) { + sdsfreesplitres(argv, argc); + } + if (ai) { + aofInfoFree(ai); + } serverLog(LL_WARNING, "\n*** FATAL AOF MANIFEST FILE ERROR ***\n"); if (line) { @@ -413,7 +429,9 @@ aofManifest *aofManifestDup(aofManifest *orig) { * one if we have. */ void aofManifestFreeAndUpdate(aofManifest *am) { serverAssert(am != NULL); - if (server.aof_manifest) aofManifestFree(server.aof_manifest); + if (server.aof_manifest) { + aofManifestFree(server.aof_manifest); + } server.aof_manifest = am; } @@ -434,12 +452,11 @@ sds getNewBaseFileNameAndMarkPreAsHistory(aofManifest *am) { listAddNodeHead(am->history_aof_list, am->base_aof_info); } - char *format_suffix = server.aof_use_rdb_preamble ? - RDB_FORMAT_SUFFIX:AOF_FORMAT_SUFFIX; + char *format_suffix = server.aof_use_rdb_preamble ? RDB_FORMAT_SUFFIX : AOF_FORMAT_SUFFIX; aofInfo *ai = aofInfoCreate(); - ai->file_name = sdscatprintf(sdsempty(), "%s.%lld%s%s", server.aof_filename, - ++am->curr_base_file_seq, BASE_FILE_SUFFIX, format_suffix); + ai->file_name = sdscatprintf(sdsempty(), "%s.%lld%s%s", server.aof_filename, ++am->curr_base_file_seq, + BASE_FILE_SUFFIX, format_suffix); ai->file_seq = am->curr_base_file_seq; ai->file_type = AOF_FILE_TYPE_BASE; am->base_aof_info = ai; @@ -457,8 +474,8 @@ sds getNewBaseFileNameAndMarkPreAsHistory(aofManifest *am) { sds getNewIncrAofName(aofManifest *am) { aofInfo *ai = aofInfoCreate(); ai->file_type = AOF_FILE_TYPE_INCR; - ai->file_name = sdscatprintf(sdsempty(), "%s.%lld%s%s", server.aof_filename, - ++am->curr_incr_file_seq, INCR_FILE_SUFFIX, AOF_FORMAT_SUFFIX); + ai->file_name = sdscatprintf(sdsempty(), "%s.%lld%s%s", server.aof_filename, ++am->curr_incr_file_seq, + INCR_FILE_SUFFIX, AOF_FORMAT_SUFFIX); ai->file_seq = am->curr_incr_file_seq; listAddNodeTail(am->incr_aof_list, ai); am->dirty = 1; @@ -467,8 +484,7 @@ sds getNewIncrAofName(aofManifest *am) { /* Get temp INCR type AOF name. */ sds getTempIncrAofName(void) { - return sdscatprintf(sdsempty(), "%s%s%s", TEMP_FILE_NAME_PREFIX, server.aof_filename, - INCR_FILE_SUFFIX); + return sdscatprintf(sdsempty(), "%s%s%s", TEMP_FILE_NAME_PREFIX, server.aof_filename, INCR_FILE_SUFFIX); } /* Get the last INCR AOF name or create a new one. */ @@ -511,7 +527,7 @@ void markRewrittenIncrAofAsHistory(aofManifest *am) { /* Move aofInfo from 'incr_aof_list' to 'history_aof_list'. */ while ((ln = listNext(&li)) != NULL) { - aofInfo *ai = (aofInfo*)ln->value; + aofInfo *ai = (aofInfo *)ln->value; serverAssert(ai->file_type == AOF_FILE_TYPE_INCR); aofInfo *hai = aofInfoDup(ai); @@ -534,24 +550,25 @@ int writeAofManifestFile(sds buf) { sds tmp_am_name = getTempAofManifestFileName(); sds tmp_am_filepath = makePath(server.aof_dirname, tmp_am_name); - int fd = open(tmp_am_filepath, O_WRONLY|O_TRUNC|O_CREAT, 0644); + int fd = open(tmp_am_filepath, O_WRONLY | O_TRUNC | O_CREAT, 0644); if (fd == -1) { - serverLog(LL_WARNING, "Can't open the AOF manifest file %s: %s", - tmp_am_name, strerror(errno)); + serverLog(LL_WARNING, "Can't open the AOF manifest file %s: %s", tmp_am_name, strerror(errno)); ret = C_ERR; goto cleanup; } len = sdslen(buf); - while(len) { + while (len) { nwritten = write(fd, buf, len); if (nwritten < 0) { - if (errno == EINTR) continue; + if (errno == EINTR) { + continue; + } - serverLog(LL_WARNING, "Error trying to write the temporary AOF manifest file %s: %s", - tmp_am_name, strerror(errno)); + serverLog(LL_WARNING, "Error trying to write the temporary AOF manifest file %s: %s", tmp_am_name, + strerror(errno)); ret = C_ERR; goto cleanup; @@ -562,17 +579,15 @@ int writeAofManifestFile(sds buf) { } if (valkey_fsync(fd) == -1) { - serverLog(LL_WARNING, "Fail to fsync the temp AOF file %s: %s.", - tmp_am_name, strerror(errno)); + serverLog(LL_WARNING, "Fail to fsync the temp AOF file %s: %s.", tmp_am_name, strerror(errno)); ret = C_ERR; goto cleanup; } if (rename(tmp_am_filepath, am_filepath) != 0) { - serverLog(LL_WARNING, - "Error trying to rename the temporary AOF manifest file %s into %s: %s", - tmp_am_name, am_name, strerror(errno)); + serverLog(LL_WARNING, "Error trying to rename the temporary AOF manifest file %s into %s: %s", tmp_am_name, + am_name, strerror(errno)); ret = C_ERR; goto cleanup; @@ -580,15 +595,16 @@ int writeAofManifestFile(sds buf) { /* Also sync the AOF directory as new AOF files may be added in the directory */ if (fsyncFileDir(am_filepath) == -1) { - serverLog(LL_WARNING, "Fail to fsync AOF directory %s: %s.", - am_filepath, strerror(errno)); + serverLog(LL_WARNING, "Fail to fsync AOF directory %s: %s.", am_filepath, strerror(errno)); ret = C_ERR; goto cleanup; } cleanup: - if (fd != -1) close(fd); + if (fd != -1) { + close(fd); + } sdsfree(am_name); sdsfree(am_filepath); sdsfree(tmp_am_name); @@ -605,7 +621,9 @@ int persistAofManifest(aofManifest *am) { sds amstr = getAofManifestAsString(am); int ret = writeAofManifestFile(amstr); sdsfree(amstr); - if (ret == C_OK) am->dirty = 0; + if (ret == C_OK) { + am->dirty = 0; + } return ret; } @@ -624,13 +642,14 @@ void aofUpgradePrepare(aofManifest *am) { /* Create AOF directory use 'server.aof_dirname' as the name. */ if (dirCreateIfMissing(server.aof_dirname) == -1) { - serverLog(LL_WARNING, "Can't open or create append-only dir %s: %s", - server.aof_dirname, strerror(errno)); + serverLog(LL_WARNING, "Can't open or create append-only dir %s: %s", server.aof_dirname, strerror(errno)); exit(1); } /* Manually construct a BASE type aofInfo and add it to aofManifest. */ - if (am->base_aof_info) aofInfoFree(am->base_aof_info); + if (am->base_aof_info) { + aofInfoFree(am->base_aof_info); + } aofInfo *ai = aofInfoCreate(); ai->file_name = sdsnew(server.aof_filename); ai->file_seq = 1; @@ -647,18 +666,15 @@ void aofUpgradePrepare(aofManifest *am) { /* Move the old AOF file to AOF directory. */ sds aof_filepath = makePath(server.aof_dirname, server.aof_filename); if (rename(server.aof_filename, aof_filepath) == -1) { - serverLog(LL_WARNING, - "Error trying to move the old AOF file %s into dir %s: %s", - server.aof_filename, - server.aof_dirname, - strerror(errno)); + serverLog(LL_WARNING, "Error trying to move the old AOF file %s into dir %s: %s", server.aof_filename, + server.aof_dirname, strerror(errno)); sdsfree(aof_filepath); exit(1); } sdsfree(aof_filepath); serverLog(LL_NOTICE, "Successfully migrated an old-style AOF file (%s) into the AOF directory (%s).", - server.aof_filename, server.aof_dirname); + server.aof_filename, server.aof_dirname); } /* When AOFRW success, the previous BASE and INCR AOFs will @@ -668,10 +684,8 @@ void aofUpgradePrepare(aofManifest *am) { * the delete task to the bio thread. */ int aofDelHistoryFiles(void) { - if (server.aof_manifest == NULL || - server.aof_disable_auto_gc == 1 || - !listLength(server.aof_manifest->history_aof_list)) - { + if (server.aof_manifest == NULL || server.aof_disable_auto_gc == 1 || + !listLength(server.aof_manifest->history_aof_list)) { return C_OK; } @@ -680,7 +694,7 @@ int aofDelHistoryFiles(void) { listRewind(server.aof_manifest->history_aof_list, &li); while ((ln = listNext(&li)) != NULL) { - aofInfo *ai = (aofInfo*)ln->value; + aofInfo *ai = (aofInfo *)ln->value; serverAssert(ai->file_type == AOF_FILE_TYPE_HIST); serverLog(LL_NOTICE, "Removing the history file %s in the background", ai->file_name); sds aof_filepath = makePath(server.aof_dirname, ai->file_name); @@ -721,8 +735,7 @@ void aofOpenIfNeededOnServerStart(void) { serverAssert(server.aof_fd == -1); if (dirCreateIfMissing(server.aof_dirname) == -1) { - serverLog(LL_WARNING, "Can't open or create append-only dir %s: %s", - server.aof_dirname, strerror(errno)); + serverLog(LL_WARNING, "Can't open or create append-only dir %s: %s", server.aof_dirname, strerror(errno)); exit(1); } @@ -735,8 +748,7 @@ void aofOpenIfNeededOnServerStart(void) { exit(1); } sdsfree(base_filepath); - serverLog(LL_NOTICE, "Creating AOF base file %s on server start", - base_name); + serverLog(LL_NOTICE, "Creating AOF base file %s on server start", base_name); } /* Because we will 'exit(1)' if open AOF or persistent manifest fails, so @@ -745,11 +757,10 @@ void aofOpenIfNeededOnServerStart(void) { /* Here we should use 'O_APPEND' flag. */ sds aof_filepath = makePath(server.aof_dirname, aof_name); - server.aof_fd = open(aof_filepath, O_WRONLY|O_APPEND|O_CREAT, 0644); + server.aof_fd = open(aof_filepath, O_WRONLY | O_APPEND | O_CREAT, 0644); sdsfree(aof_filepath); if (server.aof_fd == -1) { - serverLog(LL_WARNING, "Can't open the append-only file %s: %s", - aof_name, strerror(errno)); + serverLog(LL_WARNING, "Can't open the append-only file %s: %s", aof_name, strerror(errno)); exit(1); } @@ -784,9 +795,9 @@ int aofFileExist(char *filename) { * The above two steps of modification are atomic, that is, if * any step fails, the entire operation will rollback and returns * C_ERR, and if all succeeds, it returns C_OK. - * - * If `server.aof_state` is 'AOF_WAIT_REWRITE', It will open a temporary INCR AOF - * file to accumulate data during AOF_WAIT_REWRITE, and it will eventually be + * + * If `server.aof_state` is 'AOF_WAIT_REWRITE', It will open a temporary INCR AOF + * file to accumulate data during AOF_WAIT_REWRITE, and it will eventually be * renamed in the `backgroundRewriteDoneHandler` and written to the manifest file. * */ int openNewIncrAofForAppend(void) { @@ -796,7 +807,9 @@ int openNewIncrAofForAppend(void) { sds new_aof_name = NULL; /* Only open new INCR AOF when AOF enabled. */ - if (server.aof_state == AOF_OFF) return C_OK; + if (server.aof_state == AOF_OFF) { + return C_OK; + } /* Open new AOF. */ if (server.aof_state == AOF_WAIT_REWRITE) { @@ -808,11 +821,10 @@ int openNewIncrAofForAppend(void) { new_aof_name = sdsdup(getNewIncrAofName(temp_am)); } sds new_aof_filepath = makePath(server.aof_dirname, new_aof_name); - newfd = open(new_aof_filepath, O_WRONLY|O_TRUNC|O_CREAT, 0644); + newfd = open(new_aof_filepath, O_WRONLY | O_TRUNC | O_CREAT, 0644); sdsfree(new_aof_filepath); if (newfd == -1) { - serverLog(LL_WARNING, "Can't open the append-only file %s: %s", - new_aof_name, strerror(errno)); + serverLog(LL_WARNING, "Can't open the append-only file %s: %s", new_aof_name, strerror(errno)); goto cleanup; } @@ -823,8 +835,7 @@ int openNewIncrAofForAppend(void) { } } - serverLog(LL_NOTICE, "Creating AOF incr file %s on background rewrite", - new_aof_name); + serverLog(LL_NOTICE, "Creating AOF incr file %s on background rewrite", new_aof_name); sdsfree(new_aof_name); /* If reaches here, we can safely modify the `server.aof_manifest` @@ -844,13 +855,21 @@ int openNewIncrAofForAppend(void) { /* Reset the aof_last_incr_fsync_offset. */ server.aof_last_incr_fsync_offset = 0; /* Update `server.aof_manifest`. */ - if (temp_am) aofManifestFreeAndUpdate(temp_am); + if (temp_am) { + aofManifestFreeAndUpdate(temp_am); + } return C_OK; cleanup: - if (new_aof_name) sdsfree(new_aof_name); - if (newfd != -1) close(newfd); - if (temp_am) aofManifestFree(temp_am); + if (new_aof_name) { + sdsfree(new_aof_name); + } + if (newfd != -1) { + close(newfd); + } + if (temp_am) { + aofManifestFree(temp_am); + } return C_ERR; } @@ -874,8 +893,8 @@ int openNewIncrAofForAppend(void) { * AOFRW, which may be that we have reached the 'next_rewrite_time' or the number of INCR * AOFs has not reached the limit threshold. * */ -#define AOF_REWRITE_LIMITE_THRESHOLD 3 -#define AOF_REWRITE_LIMITE_MAX_MINUTES 60 /* 1 hour */ +#define AOF_REWRITE_LIMITE_THRESHOLD 3 +#define AOF_REWRITE_LIMITE_MAX_MINUTES 60 /* 1 hour */ int aofRewriteLimited(void) { static int next_delay_minutes = 0; static time_t next_rewrite_time = 0; @@ -904,7 +923,8 @@ int aofRewriteLimited(void) { next_rewrite_time = server.unixtime + next_delay_minutes * 60; serverLog(LL_WARNING, - "Background AOF rewrite has repeatedly failed and triggered the limit, will retry in %d minutes", next_delay_minutes); + "Background AOF rewrite has repeatedly failed and triggered the limit, will retry in %d minutes", + next_delay_minutes); return 1; } @@ -936,12 +956,14 @@ void aof_background_fsync_and_close(int fd) { void killAppendOnlyChild(void) { int statloc; /* No AOFRW child? return. */ - if (server.child_type != CHILD_TYPE_AOF) return; + if (server.child_type != CHILD_TYPE_AOF) { + return; + } /* Kill AOFRW child, wait for child exit. */ - serverLog(LL_NOTICE,"Killing running AOF rewrite child: %ld", - (long) server.child_pid); - if (kill(server.child_pid,SIGUSR1) != -1) { - while(waitpid(-1, &statloc, 0) != server.child_pid); + serverLog(LL_NOTICE, "Killing running AOF rewrite child: %ld", (long)server.child_pid); + if (kill(server.child_pid, SIGUSR1) != -1) { + while (waitpid(-1, &statloc, 0) != server.child_pid) + ; } aofRemoveTempFile(server.child_pid); resetChildState(); @@ -954,7 +976,7 @@ void stopAppendOnly(void) { serverAssert(server.aof_state != AOF_OFF); flushAppendOnlyFile(1); if (valkey_fsync(server.aof_fd) == -1) { - serverLog(LL_WARNING,"Fail to fsync the AOF file: %s",strerror(errno)); + serverLog(LL_WARNING, "Fail to fsync the AOF file: %s", strerror(errno)); } else { server.aof_last_fsync = server.mstime; } @@ -981,22 +1003,26 @@ int startAppendOnly(void) { server.aof_state = AOF_WAIT_REWRITE; if (hasActiveChildProcess() && server.child_type != CHILD_TYPE_AOF) { server.aof_rewrite_scheduled = 1; - serverLog(LL_NOTICE,"AOF was enabled but there is already another background operation. An AOF background was scheduled to start when possible."); - } else if (server.in_exec){ + serverLog(LL_NOTICE, "AOF was enabled but there is already another background operation. An AOF background was " + "scheduled to start when possible."); + } else if (server.in_exec) { server.aof_rewrite_scheduled = 1; - serverLog(LL_NOTICE,"AOF was enabled during a transaction. An AOF background was scheduled to start when possible."); + serverLog(LL_NOTICE, + "AOF was enabled during a transaction. An AOF background was scheduled to start when possible."); } else { /* If there is a pending AOF rewrite, we need to switch it off and * start a new one: the old one cannot be reused because it is not * accumulating the AOF buffer. */ if (server.child_type == CHILD_TYPE_AOF) { - serverLog(LL_NOTICE,"AOF was enabled but there is already an AOF rewriting in background. Stopping background AOF and starting a rewrite now."); + serverLog(LL_NOTICE, "AOF was enabled but there is already an AOF rewriting in background. Stopping " + "background AOF and starting a rewrite now."); killAppendOnlyChild(); } if (rewriteAppendOnlyFileBackground() == C_ERR) { server.aof_state = AOF_OFF; - serverLog(LL_WARNING,"The server needs to enable the AOF but can't trigger a background AOF rewrite operation. Check the above logs for more info about the error."); + serverLog(LL_WARNING, "The server needs to enable the AOF but can't trigger a background AOF rewrite " + "operation. Check the above logs for more info about the error."); return C_ERR; } } @@ -1005,14 +1031,13 @@ int startAppendOnly(void) { int aof_bio_fsync_status; atomicGet(server.aof_bio_fsync_status, aof_bio_fsync_status); if (aof_bio_fsync_status == C_ERR) { - serverLog(LL_WARNING, - "AOF reopen, just ignore the AOF fsync error in bio job"); - atomicSet(server.aof_bio_fsync_status,C_OK); + serverLog(LL_WARNING, "AOF reopen, just ignore the AOF fsync error in bio job"); + atomicSet(server.aof_bio_fsync_status, C_OK); } /* If AOF was in error state, we just ignore it and log the event. */ if (server.aof_last_write_status == C_ERR) { - serverLog(LL_WARNING,"AOF reopen, just ignore the last error."); + serverLog(LL_WARNING, "AOF reopen, just ignore the last error."); server.aof_last_write_status = C_OK; } return C_OK; @@ -1028,11 +1053,13 @@ int startAppendOnly(void) { ssize_t aofWrite(int fd, const char *buf, size_t len) { ssize_t nwritten = 0, totwritten = 0; - while(len) { + while (len) { nwritten = write(fd, buf, len); if (nwritten < 0) { - if (errno == EINTR) continue; + if (errno == EINTR) { + continue; + } return totwritten ? totwritten : -1; } @@ -1074,19 +1101,16 @@ void flushAppendOnlyFile(int force) { * called only when aof buffer is not empty, so if users * stop write commands before fsync called in one second, * the data in page cache cannot be flushed in time. */ - if (server.aof_fsync == AOF_FSYNC_EVERYSEC && - server.aof_last_incr_fsync_offset != server.aof_last_incr_size && - server.mstime - server.aof_last_fsync >= 1000 && - !(sync_in_progress = aofFsyncInProgress())) { + if (server.aof_fsync == AOF_FSYNC_EVERYSEC && server.aof_last_incr_fsync_offset != server.aof_last_incr_size && + server.mstime - server.aof_last_fsync >= 1000 && !(sync_in_progress = aofFsyncInProgress())) { goto try_fsync; - /* Check if we need to do fsync even the aof buffer is empty, - * the reason is described in the previous AOF_FSYNC_EVERYSEC block, - * and AOF_FSYNC_ALWAYS is also checked here to handle a case where - * aof_fsync is changed from everysec to always. */ + /* Check if we need to do fsync even the aof buffer is empty, + * the reason is described in the previous AOF_FSYNC_EVERYSEC block, + * and AOF_FSYNC_ALWAYS is also checked here to handle a case where + * aof_fsync is changed from everysec to always. */ } else if (server.aof_fsync == AOF_FSYNC_ALWAYS && - server.aof_last_incr_fsync_offset != server.aof_last_incr_size) - { + server.aof_last_incr_fsync_offset != server.aof_last_incr_size) { goto try_fsync; } else { /* All data is fsync'd already: Update fsynced_reploff_pending just in case. @@ -1094,14 +1118,16 @@ void flushAppendOnlyFile(int force) { * in which case master_repl_offset will increase but fsynced_reploff_pending won't be updated * (because there's no reason, from the AOF POV, to call fsync) and then WAITAOF may wait on * the higher offset (which contains data that was only propagated to replicas, and not to AOF) */ - if (!sync_in_progress && server.aof_fsync != AOF_FSYNC_NO) + if (!sync_in_progress && server.aof_fsync != AOF_FSYNC_NO) { atomicSet(server.fsynced_reploff_pending, server.master_repl_offset); + } return; } } - if (server.aof_fsync == AOF_FSYNC_EVERYSEC) + if (server.aof_fsync == AOF_FSYNC_EVERYSEC) { sync_in_progress = aofFsyncInProgress(); + } if (server.aof_fsync == AOF_FSYNC_EVERYSEC && !force) { /* With this append fsync policy we do background fsyncing. @@ -1121,7 +1147,8 @@ void flushAppendOnlyFile(int force) { /* Otherwise fall through, and go write since we can't wait * over two seconds. */ server.aof_delayed_fsync++; - serverLog(LL_NOTICE,"Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down the server."); + serverLog(LL_NOTICE, "Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer " + "without waiting for fsync to complete, this may slow down the server."); } } /* We want to perform a single write. This should be guaranteed atomic @@ -1135,7 +1162,7 @@ void flushAppendOnlyFile(int force) { } latencyStartMonitor(latency); - nwritten = aofWrite(server.aof_fd,server.aof_buf,sdslen(server.aof_buf)); + nwritten = aofWrite(server.aof_fd, server.aof_buf, sdslen(server.aof_buf)); latencyEndMonitor(latency); /* We want to capture different events for delayed writes: * when the delay happens with a pending fsync, or with a saving child @@ -1143,13 +1170,13 @@ void flushAppendOnlyFile(int force) { * We also use an additional event name to save all samples which is * useful for graphing / monitoring purposes. */ if (sync_in_progress) { - latencyAddSampleIfNeeded("aof-write-pending-fsync",latency); + latencyAddSampleIfNeeded("aof-write-pending-fsync", latency); } else if (hasActiveChildProcess()) { - latencyAddSampleIfNeeded("aof-write-active-child",latency); + latencyAddSampleIfNeeded("aof-write-active-child", latency); } else { - latencyAddSampleIfNeeded("aof-write-alone",latency); + latencyAddSampleIfNeeded("aof-write-alone", latency); } - latencyAddSampleIfNeeded("aof-write",latency); + latencyAddSampleIfNeeded("aof-write", latency); /* We performed the write so reset the postponed flush sentinel to zero. */ server.aof_flush_postponed_start = 0; @@ -1167,25 +1194,26 @@ void flushAppendOnlyFile(int force) { /* Log the AOF write error and record the error code. */ if (nwritten == -1) { if (can_log) { - serverLog(LL_WARNING,"Error writing to the AOF file: %s", - strerror(errno)); + serverLog(LL_WARNING, "Error writing to the AOF file: %s", strerror(errno)); } server.aof_last_write_errno = errno; } else { if (can_log) { - serverLog(LL_WARNING,"Short write while writing to " - "the AOF file: (nwritten=%lld, " - "expected=%lld)", - (long long)nwritten, - (long long)sdslen(server.aof_buf)); + serverLog(LL_WARNING, + "Short write while writing to " + "the AOF file: (nwritten=%lld, " + "expected=%lld)", + (long long)nwritten, (long long)sdslen(server.aof_buf)); } if (ftruncate(server.aof_fd, server.aof_last_incr_size) == -1) { if (can_log) { - serverLog(LL_WARNING, "Could not remove short write " - "from the append-only file. The server may refuse " - "to load the AOF the next time it starts. " - "ftruncate: %s", strerror(errno)); + serverLog(LL_WARNING, + "Could not remove short write " + "from the append-only file. The server may refuse " + "to load the AOF the next time it starts. " + "ftruncate: %s", + strerror(errno)); } } else { /* If the ftruncate() succeeded we can set nwritten to @@ -1202,7 +1230,8 @@ void flushAppendOnlyFile(int force) { * reads), and the changes to the db can't be rolled back. Since we * have a contract with the user that on acknowledged or observed * writes are is synced on disk, we must exit. */ - serverLog(LL_WARNING,"Can't recover from AOF write error when the AOF fsync policy is 'always'. Exiting..."); + serverLog(LL_WARNING, + "Can't recover from AOF write error when the AOF fsync policy is 'always'. Exiting..."); exit(1); } else { /* Recover from failed write leaving data into the buffer. However @@ -1215,7 +1244,7 @@ void flushAppendOnlyFile(int force) { if (nwritten > 0) { server.aof_current_size += nwritten; server.aof_last_incr_size += nwritten; - sdsrange(server.aof_buf,nwritten,-1); + sdsrange(server.aof_buf, nwritten, -1); } return; /* We'll try again on the next call... */ } @@ -1223,8 +1252,7 @@ void flushAppendOnlyFile(int force) { /* Successful write(2). If AOF was in error state, restore the * OK state and log the event. */ if (server.aof_last_write_status == C_ERR) { - serverLog(LL_NOTICE, - "AOF write error looks solved. The server can write again."); + serverLog(LL_NOTICE, "AOF write error looks solved. The server can write again."); server.aof_last_write_status = C_OK; } } @@ -1233,7 +1261,7 @@ void flushAppendOnlyFile(int force) { /* Re-use AOF buffer when it is small enough. The maximum comes from the * arena size of 4k minus some overhead (but is otherwise arbitrary). */ - if ((sdslen(server.aof_buf)+sdsavail(server.aof_buf)) < 4000) { + if ((sdslen(server.aof_buf) + sdsavail(server.aof_buf)) < 4000) { sdsclear(server.aof_buf); } else { sdsfree(server.aof_buf); @@ -1243,8 +1271,9 @@ void flushAppendOnlyFile(int force) { try_fsync: /* Don't fsync if no-appendfsync-on-rewrite is set to yes and there are * children doing I/O in the background. */ - if (server.aof_no_fsync_on_rewrite && hasActiveChildProcess()) + if (server.aof_no_fsync_on_rewrite && hasActiveChildProcess()) { return; + } /* Perform the fsync if needed. */ if (server.aof_fsync == AOF_FSYNC_ALWAYS) { @@ -1255,17 +1284,18 @@ void flushAppendOnlyFile(int force) { * the AOF fsync policy is 'always', we should exit if failed to fsync * AOF (see comment next to the exit(1) after write error above). */ if (valkey_fsync(server.aof_fd) == -1) { - serverLog(LL_WARNING,"Can't persist AOF for fsync error when the " - "AOF fsync policy is 'always': %s. Exiting...", strerror(errno)); + serverLog(LL_WARNING, + "Can't persist AOF for fsync error when the " + "AOF fsync policy is 'always': %s. Exiting...", + strerror(errno)); exit(1); } latencyEndMonitor(latency); - latencyAddSampleIfNeeded("aof-fsync-always",latency); + latencyAddSampleIfNeeded("aof-fsync-always", latency); server.aof_last_incr_fsync_offset = server.aof_last_incr_size; server.aof_last_fsync = server.mstime; atomicSet(server.fsynced_reploff_pending, server.master_repl_offset); - } else if (server.aof_fsync == AOF_FSYNC_EVERYSEC && - server.mstime - server.aof_last_fsync >= 1000) { + } else if (server.aof_fsync == AOF_FSYNC_EVERYSEC && server.mstime - server.aof_last_fsync >= 1000) { if (!sync_in_progress) { aof_background_fsync(server.aof_fd); server.aof_last_incr_fsync_offset = server.aof_last_incr_size; @@ -1280,20 +1310,20 @@ sds catAppendOnlyGenericCommand(sds dst, int argc, robj **argv) { robj *o; buf[0] = '*'; - len = 1+ll2string(buf+1,sizeof(buf)-1,argc); + len = 1 + ll2string(buf + 1, sizeof(buf) - 1, argc); buf[len++] = '\r'; buf[len++] = '\n'; - dst = sdscatlen(dst,buf,len); + dst = sdscatlen(dst, buf, len); for (j = 0; j < argc; j++) { o = getDecodedObject(argv[j]); buf[0] = '$'; - len = 1+ll2string(buf+1,sizeof(buf)-1,sdslen(o->ptr)); + len = 1 + ll2string(buf + 1, sizeof(buf) - 1, sdslen(o->ptr)); buf[len++] = '\r'; buf[len++] = '\n'; - dst = sdscatlen(dst,buf,len); - dst = sdscatlen(dst,o->ptr,sdslen(o->ptr)); - dst = sdscatlen(dst,"\r\n",2); + dst = sdscatlen(dst, buf, len); + dst = sdscatlen(dst, o->ptr, sdslen(o->ptr)); + dst = sdscatlen(dst, "\r\n", 2); decrRefCount(o); } return dst; @@ -1345,22 +1375,19 @@ void feedAppendOnlyFile(int dictid, robj **argv, int argc) { if (dictid != -1 && dictid != server.aof_selected_db) { char seldb[64]; - snprintf(seldb,sizeof(seldb),"%d",dictid); - buf = sdscatprintf(buf,"*2\r\n$6\r\nSELECT\r\n$%lu\r\n%s\r\n", - (unsigned long)strlen(seldb),seldb); + snprintf(seldb, sizeof(seldb), "%d", dictid); + buf = sdscatprintf(buf, "*2\r\n$6\r\nSELECT\r\n$%lu\r\n%s\r\n", (unsigned long)strlen(seldb), seldb); server.aof_selected_db = dictid; } /* All commands should be propagated the same way in AOF as in replication. * No need for AOF-specific translation. */ - buf = catAppendOnlyGenericCommand(buf,argc,argv); + buf = catAppendOnlyGenericCommand(buf, argc, argv); /* Append to the AOF buffer. This will be flushed on disk just before * of re-entering the event loop, so before the client will get a * positive reply about the operation performed. */ - if (server.aof_state == AOF_ON || - (server.aof_state == AOF_WAIT_REWRITE && server.child_type == CHILD_TYPE_AOF)) - { + if (server.aof_state == AOF_ON || (server.aof_state == AOF_WAIT_REWRITE && server.child_type == CHILD_TYPE_AOF)) { server.aof_buf = sdscatlen(server.aof_buf, buf, sdslen(buf)); } @@ -1406,7 +1433,7 @@ int loadSingleAppendOnlyFile(char *filename) { struct valkey_stat sb; int old_aof_state = server.aof_state; long loops = 0; - off_t valid_up_to = 0; /* Offset of latest well-formed command loaded. */ + off_t valid_up_to = 0; /* Offset of latest well-formed command loaded. */ off_t valid_before_multi = 0; /* Offset before MULTI command loaded. */ off_t last_progress_report_size = 0; int ret = AOF_OK; @@ -1416,11 +1443,12 @@ int loadSingleAppendOnlyFile(char *filename) { if (fp == NULL) { int en = errno; if (valkey_stat(aof_filepath, &sb) == 0 || errno != ENOENT) { - serverLog(LL_WARNING,"Fatal error: can't open the append log file %s for reading: %s", filename, strerror(en)); + serverLog(LL_WARNING, "Fatal error: can't open the append log file %s for reading: %s", filename, + strerror(en)); sdsfree(aof_filepath); return AOF_OPEN_ERR; } else { - serverLog(LL_WARNING,"The append log file %s doesn't exist: %s", filename, strerror(errno)); + serverLog(LL_WARNING, "The append log file %s doesn't exist: %s", filename, strerror(errno)); sdsfree(aof_filepath); return AOF_NOT_EXIST; } @@ -1442,40 +1470,49 @@ int loadSingleAppendOnlyFile(char *filename) { server.current_client = server.executing_client = fakeClient; /* Check if the AOF file is in RDB format (it may be RDB encoded base AOF - * or old style RDB-preamble AOF). In that case we need to load the RDB file + * or old style RDB-preamble AOF). In that case we need to load the RDB file * and later continue loading the AOF tail if it is an old style RDB-preamble AOF. */ char sig[5]; /* "REDIS" */ - if (fread(sig,1,5,fp) != 5 || memcmp(sig,"REDIS",5) != 0) { + if (fread(sig, 1, 5, fp) != 5 || memcmp(sig, "REDIS", 5) != 0) { /* Not in RDB format, seek back at 0 offset. */ - if (fseek(fp,0,SEEK_SET) == -1) goto readerr; + if (fseek(fp, 0, SEEK_SET) == -1) { + goto readerr; + } } else { /* RDB format. Pass loading the RDB functions. */ rio rdb; int old_style = !strcmp(filename, server.aof_filename); - if (old_style) + if (old_style) { serverLog(LL_NOTICE, "Reading RDB preamble from AOF file..."); - else - serverLog(LL_NOTICE, "Reading RDB base file on AOF loading..."); - - if (fseek(fp,0,SEEK_SET) == -1) goto readerr; - rioInitWithFile(&rdb,fp); - if (rdbLoadRio(&rdb,RDBFLAGS_AOF_PREAMBLE,NULL) != C_OK) { - if (old_style) - serverLog(LL_WARNING, "Error reading the RDB preamble of the AOF file %s, AOF loading aborted", filename); - else + } else { + serverLog(LL_NOTICE, "Reading RDB base file on AOF loading..."); + } + + if (fseek(fp, 0, SEEK_SET) == -1) { + goto readerr; + } + rioInitWithFile(&rdb, fp); + if (rdbLoadRio(&rdb, RDBFLAGS_AOF_PREAMBLE, NULL) != C_OK) { + if (old_style) { + serverLog(LL_WARNING, "Error reading the RDB preamble of the AOF file %s, AOF loading aborted", + filename); + } else { serverLog(LL_WARNING, "Error reading the RDB base file %s, AOF loading aborted", filename); + } ret = AOF_FAILED; goto cleanup; } else { loadingAbsProgress(ftello(fp)); last_progress_report_size = ftello(fp); - if (old_style) serverLog(LL_NOTICE, "Reading the remaining AOF tail..."); + if (old_style) { + serverLog(LL_NOTICE, "Reading the remaining AOF tail..."); + } } } /* Read the actual AOF file, in REPL format, command by command. */ - while(1) { + while (1) { int argc, j; unsigned long len; robj **argv; @@ -1491,76 +1528,86 @@ int loadSingleAppendOnlyFile(char *filename) { processEventsWhileBlocked(); processModuleLoadingProgressEvent(1); } - if (fgets(buf,sizeof(buf),fp) == NULL) { + if (fgets(buf, sizeof(buf), fp) == NULL) { if (feof(fp)) { break; } else { goto readerr; } } - if (buf[0] == '#') continue; /* Skip annotations */ - if (buf[0] != '*') goto fmterr; - if (buf[1] == '\0') goto readerr; - argc = atoi(buf+1); - if (argc < 1) goto fmterr; - if ((size_t)argc > SIZE_MAX / sizeof(robj*)) goto fmterr; + if (buf[0] == '#') { + continue; /* Skip annotations */ + } + if (buf[0] != '*') { + goto fmterr; + } + if (buf[1] == '\0') { + goto readerr; + } + argc = atoi(buf + 1); + if (argc < 1) { + goto fmterr; + } + if ((size_t)argc > SIZE_MAX / sizeof(robj *)) { + goto fmterr; + } /* Load the next command in the AOF as our fake client * argv. */ - argv = zmalloc(sizeof(robj*)*argc); + argv = zmalloc(sizeof(robj *) * argc); fakeClient->argc = argc; fakeClient->argv = argv; fakeClient->argv_len = argc; for (j = 0; j < argc; j++) { /* Parse the argument len. */ - char *readres = fgets(buf,sizeof(buf),fp); + char *readres = fgets(buf, sizeof(buf), fp); if (readres == NULL || buf[0] != '$') { fakeClient->argc = j; /* Free up to j-1. */ freeClientArgv(fakeClient); - if (readres == NULL) + if (readres == NULL) { goto readerr; - else + } else { goto fmterr; + } } - len = strtol(buf+1,NULL,10); + len = strtol(buf + 1, NULL, 10); /* Read it into a string object. */ - argsds = sdsnewlen(SDS_NOINIT,len); - if (len && fread(argsds,len,1,fp) == 0) { + argsds = sdsnewlen(SDS_NOINIT, len); + if (len && fread(argsds, len, 1, fp) == 0) { sdsfree(argsds); fakeClient->argc = j; /* Free up to j-1. */ freeClientArgv(fakeClient); goto readerr; } - argv[j] = createObject(OBJ_STRING,argsds); + argv[j] = createObject(OBJ_STRING, argsds); /* Discard CRLF. */ - if (fread(buf,2,1,fp) == 0) { - fakeClient->argc = j+1; /* Free up to j. */ + if (fread(buf, 2, 1, fp) == 0) { + fakeClient->argc = j + 1; /* Free up to j. */ freeClientArgv(fakeClient); goto readerr; } } /* Command lookup */ - cmd = lookupCommand(argv,argc); + cmd = lookupCommand(argv, argc); if (!cmd) { - serverLog(LL_WARNING, - "Unknown command '%s' reading the append only file %s", - (char*)argv[0]->ptr, filename); + serverLog(LL_WARNING, "Unknown command '%s' reading the append only file %s", (char *)argv[0]->ptr, + filename); freeClientArgv(fakeClient); ret = AOF_FAILED; goto cleanup; } - if (cmd->proc == multiCommand) valid_before_multi = valid_up_to; + if (cmd->proc == multiCommand) { + valid_before_multi = valid_up_to; + } /* Run the command in the context of a fake client */ fakeClient->cmd = fakeClient->lastcmd = cmd; - if (fakeClient->flags & CLIENT_MULTI && - fakeClient->cmd->proc != execCommand) - { + if (fakeClient->flags & CLIENT_MULTI && fakeClient->cmd->proc != execCommand) { /* Note: we don't have to attempt calling evalGetCommandFlags, * since this is AOF, the checks in processCommand are not made * anyway.*/ @@ -1570,8 +1617,7 @@ int loadSingleAppendOnlyFile(char *filename) { } /* The fake client should not have a reply */ - serverAssert(fakeClient->bufpos == 0 && - listLength(fakeClient->reply) == 0); + serverAssert(fakeClient->bufpos == 0 && listLength(fakeClient->reply) == 0); /* The fake client should never get blocked */ serverAssert((fakeClient->flags & CLIENT_BLOCKED) == 0); @@ -1579,9 +1625,12 @@ int loadSingleAppendOnlyFile(char *filename) { /* Clean up. Command code may have changed argv/argc so we use the * argv/argc of the client instead of the local variables. */ freeClientArgv(fakeClient); - if (server.aof_load_truncated) valid_up_to = ftello(fp); - if (server.key_load_delay) + if (server.aof_load_truncated) { + valid_up_to = ftello(fp); + } + if (server.key_load_delay) { debugDelay(server.key_load_delay); + } } /* This point can only be reached when EOF is reached without errors. @@ -1589,8 +1638,7 @@ int loadSingleAppendOnlyFile(char *filename) { * a short read, even if technically the protocol is correct: we want * to remove the unprocessed tail and continue. */ if (fakeClient->flags & CLIENT_MULTI) { - serverLog(LL_WARNING, - "Revert incomplete MULTI/EXEC transaction in AOF file %s", filename); + serverLog(LL_WARNING, "Revert incomplete MULTI/EXEC transaction in AOF file %s", filename); valid_up_to = valid_before_multi; goto uxeof; } @@ -1602,51 +1650,55 @@ int loadSingleAppendOnlyFile(char *filename) { readerr: /* Read error. If feof(fp) is true, fall through to unexpected EOF. */ if (!feof(fp)) { - serverLog(LL_WARNING,"Unrecoverable error reading the append only file %s: %s", filename, strerror(errno)); + serverLog(LL_WARNING, "Unrecoverable error reading the append only file %s: %s", filename, strerror(errno)); ret = AOF_FAILED; goto cleanup; } uxeof: /* Unexpected AOF end of file. */ if (server.aof_load_truncated) { - serverLog(LL_WARNING,"!!! Warning: short read while loading the AOF file %s!!!", filename); - serverLog(LL_WARNING,"!!! Truncating the AOF %s at offset %llu !!!", - filename, (unsigned long long) valid_up_to); - if (valid_up_to == -1 || truncate(aof_filepath,valid_up_to) == -1) { + serverLog(LL_WARNING, "!!! Warning: short read while loading the AOF file %s!!!", filename); + serverLog(LL_WARNING, "!!! Truncating the AOF %s at offset %llu !!!", filename, + (unsigned long long)valid_up_to); + if (valid_up_to == -1 || truncate(aof_filepath, valid_up_to) == -1) { if (valid_up_to == -1) { - serverLog(LL_WARNING,"Last valid command offset is invalid"); + serverLog(LL_WARNING, "Last valid command offset is invalid"); } else { - serverLog(LL_WARNING,"Error truncating the AOF file %s: %s", - filename, strerror(errno)); + serverLog(LL_WARNING, "Error truncating the AOF file %s: %s", filename, strerror(errno)); } } else { /* Make sure the AOF file descriptor points to the end of the * file after the truncate call. */ - if (server.aof_fd != -1 && lseek(server.aof_fd,0,SEEK_END) == -1) { - serverLog(LL_WARNING,"Can't seek the end of the AOF file %s: %s", - filename, strerror(errno)); + if (server.aof_fd != -1 && lseek(server.aof_fd, 0, SEEK_END) == -1) { + serverLog(LL_WARNING, "Can't seek the end of the AOF file %s: %s", filename, strerror(errno)); } else { - serverLog(LL_WARNING, - "AOF %s loaded anyway because aof-load-truncated is enabled", filename); + serverLog(LL_WARNING, "AOF %s loaded anyway because aof-load-truncated is enabled", filename); ret = AOF_TRUNCATED; goto loaded_ok; } } } - serverLog(LL_WARNING, "Unexpected end of file reading the append only file %s. You can: " + serverLog( + LL_WARNING, + "Unexpected end of file reading the append only file %s. You can: " "1) Make a backup of your AOF file, then use ./valkey-check-aof --fix . " - "2) Alternatively you can set the 'aof-load-truncated' configuration option to yes and restart the server.", filename); + "2) Alternatively you can set the 'aof-load-truncated' configuration option to yes and restart the server.", + filename); ret = AOF_FAILED; goto cleanup; fmterr: /* Format error. */ - serverLog(LL_WARNING, "Bad file format reading the append only file %s: " - "make a backup of your AOF file, then use ./valkey-check-aof --fix ", filename); + serverLog(LL_WARNING, + "Bad file format reading the append only file %s: " + "make a backup of your AOF file, then use ./valkey-check-aof --fix ", + filename); ret = AOF_FAILED; /* fall through to cleanup. */ cleanup: - if (fakeClient) freeClient(fakeClient); + if (fakeClient) { + freeClient(fakeClient); + } server.current_client = old_cur_client; server.executing_client = old_exec_client; fclose(fp); @@ -1673,11 +1725,9 @@ int loadAppendOnlyFiles(aofManifest *am) { * and the 'server.aof_filename' file not exist in 'server.aof_dirname' directory * */ if (fileExist(server.aof_filename)) { - if (!dirExists(server.aof_dirname) || - (am->base_aof_info == NULL && listLength(am->incr_aof_list) == 0) || + if (!dirExists(server.aof_dirname) || (am->base_aof_info == NULL && listLength(am->incr_aof_list) == 0) || (am->base_aof_info != NULL && listLength(am->incr_aof_list) == 0 && - !strcmp(am->base_aof_info->file_name, server.aof_filename) && !aofFileExist(server.aof_filename))) - { + !strcmp(am->base_aof_info->file_name, server.aof_filename) && !aofFileExist(server.aof_filename))) { aofUpgradePrepare(am); } } @@ -1694,7 +1744,9 @@ int loadAppendOnlyFiles(aofManifest *am) { total_size = getBaseAndIncrAppendOnlyFilesSize(am, &status); if (status != AOF_OK) { /* If an AOF exists in the manifest but not on the disk, we consider this to be a fatal error. */ - if (status == AOF_NOT_EXIST) status = AOF_FAILED; + if (status == AOF_NOT_EXIST) { + status = AOF_FAILED; + } return status; } else if (total_size == 0) { @@ -1706,15 +1758,15 @@ int loadAppendOnlyFiles(aofManifest *am) { /* Load BASE AOF if needed. */ if (am->base_aof_info) { serverAssert(am->base_aof_info->file_type == AOF_FILE_TYPE_BASE); - aof_name = (char*)am->base_aof_info->file_name; + aof_name = (char *)am->base_aof_info->file_name; updateLoadingFileName(aof_name); base_size = getAppendOnlyFileSize(aof_name, NULL); last_file = ++aof_num == total_num; start = ustime(); ret = loadSingleAppendOnlyFile(aof_name); if (ret == AOF_OK || (ret == AOF_TRUNCATED && last_file)) { - serverLog(LL_NOTICE, "DB loaded from base file %s: %.3f seconds", - aof_name, (float)(ustime()-start)/1000000); + serverLog(LL_NOTICE, "DB loaded from base file %s: %.3f seconds", aof_name, + (float)(ustime() - start) / 1000000); } /* If the truncated file is not the last file, we consider this to be a fatal error. */ @@ -1735,21 +1787,23 @@ int loadAppendOnlyFiles(aofManifest *am) { listRewind(am->incr_aof_list, &li); while ((ln = listNext(&li)) != NULL) { - aofInfo *ai = (aofInfo*)ln->value; + aofInfo *ai = (aofInfo *)ln->value; serverAssert(ai->file_type == AOF_FILE_TYPE_INCR); - aof_name = (char*)ai->file_name; + aof_name = (char *)ai->file_name; updateLoadingFileName(aof_name); last_file = ++aof_num == total_num; start = ustime(); ret = loadSingleAppendOnlyFile(aof_name); if (ret == AOF_OK || (ret == AOF_TRUNCATED && last_file)) { - serverLog(LL_NOTICE, "DB loaded from incr file %s: %.3f seconds", - aof_name, (float)(ustime()-start)/1000000); + serverLog(LL_NOTICE, "DB loaded from incr file %s: %.3f seconds", aof_name, + (float)(ustime() - start) / 1000000); } /* We know that (at least) one of the AOF files has data (total_size > 0), * so empty incr AOF file doesn't count as a AOF_EMPTY result */ - if (ret == AOF_EMPTY) ret = AOF_OK; + if (ret == AOF_EMPTY) { + ret = AOF_OK; + } /* If the truncated file is not the last file, we consider this to be a fatal error. */ if (ret == AOF_TRUNCATED && !last_file) { @@ -1790,9 +1844,9 @@ int rioWriteBulkObject(rio *r, robj *obj) { /* Avoid using getDecodedObject to help copy-on-write (we are often * in a child process when this function is called). */ if (obj->encoding == OBJ_ENCODING_INT) { - return rioWriteBulkLongLong(r,(long)obj->ptr); + return rioWriteBulkLongLong(r, (long)obj->ptr); } else if (sdsEncodedObject(obj)) { - return rioWriteBulkString(r,obj->ptr,sdslen(obj->ptr)); + return rioWriteBulkString(r, obj->ptr, sdslen(obj->ptr)); } else { serverPanic("Unknown string encoding"); } @@ -1803,16 +1857,13 @@ int rioWriteBulkObject(rio *r, robj *obj) { int rewriteListObject(rio *r, robj *key, robj *o) { long long count = 0, items = listTypeLength(o); - listTypeIterator *li = listTypeInitIterator(o,0,LIST_TAIL); + listTypeIterator *li = listTypeInitIterator(o, 0, LIST_TAIL); listTypeEntry entry; - while (listTypeNext(li,&entry)) { + while (listTypeNext(li, &entry)) { if (count == 0) { - int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? - AOF_REWRITE_ITEMS_PER_CMD : items; - if (!rioWriteBulkCount(r,'*',2+cmd_items) || - !rioWriteBulkString(r,"RPUSH",5) || - !rioWriteBulkObject(r,key)) - { + int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? AOF_REWRITE_ITEMS_PER_CMD : items; + if (!rioWriteBulkCount(r, '*', 2 + cmd_items) || !rioWriteBulkString(r, "RPUSH", 5) || + !rioWriteBulkObject(r, key)) { listTypeReleaseIterator(li); return 0; } @@ -1821,19 +1872,21 @@ int rewriteListObject(rio *r, robj *key, robj *o) { unsigned char *vstr; size_t vlen; long long lval; - vstr = listTypeGetValue(&entry,&vlen,&lval); + vstr = listTypeGetValue(&entry, &vlen, &lval); if (vstr) { - if (!rioWriteBulkString(r,(char*)vstr,vlen)) { + if (!rioWriteBulkString(r, (char *)vstr, vlen)) { listTypeReleaseIterator(li); return 0; } } else { - if (!rioWriteBulkLongLong(r,lval)) { + if (!rioWriteBulkLongLong(r, lval)) { listTypeReleaseIterator(li); return 0; } } - if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0; + if (++count == AOF_REWRITE_ITEMS_PER_CMD) { + count = 0; + } items--; } listTypeReleaseIterator(li); @@ -1850,23 +1903,21 @@ int rewriteSetObject(rio *r, robj *key, robj *o) { int64_t llval; while (setTypeNext(si, &str, &len, &llval) != -1) { if (count == 0) { - int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? - AOF_REWRITE_ITEMS_PER_CMD : items; - if (!rioWriteBulkCount(r,'*',2+cmd_items) || - !rioWriteBulkString(r,"SADD",4) || - !rioWriteBulkObject(r,key)) - { + int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? AOF_REWRITE_ITEMS_PER_CMD : items; + if (!rioWriteBulkCount(r, '*', 2 + cmd_items) || !rioWriteBulkString(r, "SADD", 4) || + !rioWriteBulkObject(r, key)) { setTypeReleaseIterator(si); return 0; } } - size_t written = str ? - rioWriteBulkString(r, str, len) : rioWriteBulkLongLong(r, llval); + size_t written = str ? rioWriteBulkString(r, str, len) : rioWriteBulkLongLong(r, llval); if (!written) { setTypeReleaseIterator(si); return 0; } - if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0; + if (++count == AOF_REWRITE_ITEMS_PER_CMD) { + count = 0; + } items--; } setTypeReleaseIterator(si); @@ -1886,34 +1937,39 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) { long long vll; double score; - eptr = lpSeek(zl,0); + eptr = lpSeek(zl, 0); serverAssert(eptr != NULL); - sptr = lpNext(zl,eptr); + sptr = lpNext(zl, eptr); serverAssert(sptr != NULL); while (eptr != NULL) { - vstr = lpGetValue(eptr,&vlen,&vll); + vstr = lpGetValue(eptr, &vlen, &vll); score = zzlGetScore(sptr); if (count == 0) { - int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? - AOF_REWRITE_ITEMS_PER_CMD : items; + int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? AOF_REWRITE_ITEMS_PER_CMD : items; - if (!rioWriteBulkCount(r,'*',2+cmd_items*2) || - !rioWriteBulkString(r,"ZADD",4) || - !rioWriteBulkObject(r,key)) - { + if (!rioWriteBulkCount(r, '*', 2 + cmd_items * 2) || !rioWriteBulkString(r, "ZADD", 4) || + !rioWriteBulkObject(r, key)) { return 0; } } - if (!rioWriteBulkDouble(r,score)) return 0; + if (!rioWriteBulkDouble(r, score)) { + return 0; + } if (vstr != NULL) { - if (!rioWriteBulkString(r,(char*)vstr,vlen)) return 0; + if (!rioWriteBulkString(r, (char *)vstr, vlen)) { + return 0; + } } else { - if (!rioWriteBulkLongLong(r,vll)) return 0; + if (!rioWriteBulkLongLong(r, vll)) { + return 0; + } + } + zzlNext(zl, &eptr, &sptr); + if (++count == AOF_REWRITE_ITEMS_PER_CMD) { + count = 0; } - zzlNext(zl,&eptr,&sptr); - if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0; items--; } } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { @@ -1921,29 +1977,26 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) { dictIterator *di = dictGetIterator(zs->dict); dictEntry *de; - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { sds ele = dictGetKey(de); double *score = dictGetVal(de); if (count == 0) { - int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? - AOF_REWRITE_ITEMS_PER_CMD : items; + int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? AOF_REWRITE_ITEMS_PER_CMD : items; - if (!rioWriteBulkCount(r,'*',2+cmd_items*2) || - !rioWriteBulkString(r,"ZADD",4) || - !rioWriteBulkObject(r,key)) - { + if (!rioWriteBulkCount(r, '*', 2 + cmd_items * 2) || !rioWriteBulkString(r, "ZADD", 4) || + !rioWriteBulkObject(r, key)) { dictReleaseIterator(di); return 0; } } - if (!rioWriteBulkDouble(r,*score) || - !rioWriteBulkString(r,ele,sdslen(ele))) - { + if (!rioWriteBulkDouble(r, *score) || !rioWriteBulkString(r, ele, sdslen(ele))) { dictReleaseIterator(di); return 0; } - if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0; + if (++count == AOF_REWRITE_ITEMS_PER_CMD) { + count = 0; + } items--; } dictReleaseIterator(di); @@ -1966,10 +2019,11 @@ static int rioWriteHashIteratorCursor(rio *r, hashTypeIterator *hi, int what) { long long vll = LLONG_MAX; hashTypeCurrentFromListpack(hi, what, &vstr, &vlen, &vll); - if (vstr) - return rioWriteBulkString(r, (char*)vstr, vlen); - else + if (vstr) { + return rioWriteBulkString(r, (char *)vstr, vlen); + } else { return rioWriteBulkLongLong(r, vll); + } } else if (hi->encoding == OBJ_ENCODING_HT) { sds value = hashTypeCurrentFromHashTable(hi, what); return rioWriteBulkString(r, value, sdslen(value)); @@ -1988,25 +2042,22 @@ int rewriteHashObject(rio *r, robj *key, robj *o) { hi = hashTypeInitIterator(o); while (hashTypeNext(hi) != C_ERR) { if (count == 0) { - int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? - AOF_REWRITE_ITEMS_PER_CMD : items; + int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? AOF_REWRITE_ITEMS_PER_CMD : items; - if (!rioWriteBulkCount(r,'*',2+cmd_items*2) || - !rioWriteBulkString(r,"HMSET",5) || - !rioWriteBulkObject(r,key)) - { + if (!rioWriteBulkCount(r, '*', 2 + cmd_items * 2) || !rioWriteBulkString(r, "HMSET", 5) || + !rioWriteBulkObject(r, key)) { hashTypeReleaseIterator(hi); return 0; } } - if (!rioWriteHashIteratorCursor(r, hi, OBJ_HASH_KEY) || - !rioWriteHashIteratorCursor(r, hi, OBJ_HASH_VALUE)) - { + if (!rioWriteHashIteratorCursor(r, hi, OBJ_HASH_KEY) || !rioWriteHashIteratorCursor(r, hi, OBJ_HASH_VALUE)) { hashTypeReleaseIterator(hi); - return 0; + return 0; + } + if (++count == AOF_REWRITE_ITEMS_PER_CMD) { + count = 0; } - if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0; items--; } @@ -2017,11 +2068,11 @@ int rewriteHashObject(rio *r, robj *key, robj *o) { /* Helper for rewriteStreamObject() that generates a bulk string into the * AOF representing the ID 'id'. */ -int rioWriteBulkStreamID(rio *r,streamID *id) { +int rioWriteBulkStreamID(rio *r, streamID *id) { int retval; - sds replyid = sdscatfmt(sdsempty(),"%U-%U",id->ms,id->seq); - retval = rioWriteBulkString(r,replyid,sdslen(replyid)); + sds replyid = sdscatfmt(sdsempty(), "%U-%U", id->ms, id->seq); + retval = rioWriteBulkString(r, replyid, sdslen(replyid)); sdsfree(replyid); return retval; } @@ -2030,38 +2081,78 @@ int rioWriteBulkStreamID(rio *r,streamID *id) { * add the message described by 'nack' having the id 'rawid', into the pending * list of the specified consumer. All this in the context of the specified * key and group. */ -int rioWriteStreamPendingEntry(rio *r, robj *key, const char *groupname, size_t groupname_len, streamConsumer *consumer, unsigned char *rawid, streamNACK *nack) { - /* XCLAIM 0 TIME - RETRYCOUNT JUSTID FORCE. */ +int rioWriteStreamPendingEntry(rio *r, robj *key, const char *groupname, size_t groupname_len, streamConsumer *consumer, + unsigned char *rawid, streamNACK *nack) { + /* XCLAIM 0 TIME + RETRYCOUNT JUSTID FORCE. */ streamID id; - streamDecodeID(rawid,&id); - if (rioWriteBulkCount(r,'*',12) == 0) return 0; - if (rioWriteBulkString(r,"XCLAIM",6) == 0) return 0; - if (rioWriteBulkObject(r,key) == 0) return 0; - if (rioWriteBulkString(r,groupname,groupname_len) == 0) return 0; - if (rioWriteBulkString(r,consumer->name,sdslen(consumer->name)) == 0) return 0; - if (rioWriteBulkString(r,"0",1) == 0) return 0; - if (rioWriteBulkStreamID(r,&id) == 0) return 0; - if (rioWriteBulkString(r,"TIME",4) == 0) return 0; - if (rioWriteBulkLongLong(r,nack->delivery_time) == 0) return 0; - if (rioWriteBulkString(r,"RETRYCOUNT",10) == 0) return 0; - if (rioWriteBulkLongLong(r,nack->delivery_count) == 0) return 0; - if (rioWriteBulkString(r,"JUSTID",6) == 0) return 0; - if (rioWriteBulkString(r,"FORCE",5) == 0) return 0; + streamDecodeID(rawid, &id); + if (rioWriteBulkCount(r, '*', 12) == 0) { + return 0; + } + if (rioWriteBulkString(r, "XCLAIM", 6) == 0) { + return 0; + } + if (rioWriteBulkObject(r, key) == 0) { + return 0; + } + if (rioWriteBulkString(r, groupname, groupname_len) == 0) { + return 0; + } + if (rioWriteBulkString(r, consumer->name, sdslen(consumer->name)) == 0) { + return 0; + } + if (rioWriteBulkString(r, "0", 1) == 0) { + return 0; + } + if (rioWriteBulkStreamID(r, &id) == 0) { + return 0; + } + if (rioWriteBulkString(r, "TIME", 4) == 0) { + return 0; + } + if (rioWriteBulkLongLong(r, nack->delivery_time) == 0) { + return 0; + } + if (rioWriteBulkString(r, "RETRYCOUNT", 10) == 0) { + return 0; + } + if (rioWriteBulkLongLong(r, nack->delivery_count) == 0) { + return 0; + } + if (rioWriteBulkString(r, "JUSTID", 6) == 0) { + return 0; + } + if (rioWriteBulkString(r, "FORCE", 5) == 0) { + return 0; + } return 1; } /* Helper for rewriteStreamObject(): emit the XGROUP CREATECONSUMER is * needed in order to create consumers that do not have any pending entries. * All this in the context of the specified key and group. */ -int rioWriteStreamEmptyConsumer(rio *r, robj *key, const char *groupname, size_t groupname_len, streamConsumer *consumer) { +int rioWriteStreamEmptyConsumer(rio *r, robj *key, const char *groupname, size_t groupname_len, + streamConsumer *consumer) { /* XGROUP CREATECONSUMER */ - if (rioWriteBulkCount(r,'*',5) == 0) return 0; - if (rioWriteBulkString(r,"XGROUP",6) == 0) return 0; - if (rioWriteBulkString(r,"CREATECONSUMER",14) == 0) return 0; - if (rioWriteBulkObject(r,key) == 0) return 0; - if (rioWriteBulkString(r,groupname,groupname_len) == 0) return 0; - if (rioWriteBulkString(r,consumer->name,sdslen(consumer->name)) == 0) return 0; + if (rioWriteBulkCount(r, '*', 5) == 0) { + return 0; + } + if (rioWriteBulkString(r, "XGROUP", 6) == 0) { + return 0; + } + if (rioWriteBulkString(r, "CREATECONSUMER", 14) == 0) { + return 0; + } + if (rioWriteBulkObject(r, key) == 0) { + return 0; + } + if (rioWriteBulkString(r, groupname, groupname_len) == 0) { + return 0; + } + if (rioWriteBulkString(r, consumer->name, sdslen(consumer->name)) == 0) { + return 0; + } return 1; } @@ -2070,34 +2161,30 @@ int rioWriteStreamEmptyConsumer(rio *r, robj *key, const char *groupname, size_t int rewriteStreamObject(rio *r, robj *key, robj *o) { stream *s = o->ptr; streamIterator si; - streamIteratorStart(&si,s,NULL,NULL,0); + streamIteratorStart(&si, s, NULL, NULL, 0); streamID id; int64_t numfields; if (s->length) { /* Reconstruct the stream data using XADD commands. */ - while(streamIteratorGetID(&si,&id,&numfields)) { + while (streamIteratorGetID(&si, &id, &numfields)) { /* Emit a two elements array for each item. The first is * the ID, the second is an array of field-value pairs. */ /* Emit the XADD ...fields... command. */ - if (!rioWriteBulkCount(r,'*',3+numfields*2) || - !rioWriteBulkString(r,"XADD",4) || - !rioWriteBulkObject(r,key) || - !rioWriteBulkStreamID(r,&id)) - { + if (!rioWriteBulkCount(r, '*', 3 + numfields * 2) || !rioWriteBulkString(r, "XADD", 4) || + !rioWriteBulkObject(r, key) || !rioWriteBulkStreamID(r, &id)) { streamIteratorStop(&si); return 0; } - while(numfields--) { + while (numfields--) { unsigned char *field, *value; int64_t field_len, value_len; - streamIteratorGetField(&si,&field,&value,&field_len,&value_len); - if (!rioWriteBulkString(r,(char*)field,field_len) || - !rioWriteBulkString(r,(char*)value,value_len)) - { + streamIteratorGetField(&si, &field, &value, &field_len, &value_len); + if (!rioWriteBulkString(r, (char *)field, field_len) || + !rioWriteBulkString(r, (char *)value, value_len)) { streamIteratorStop(&si); - return 0; + return 0; } } } @@ -2105,54 +2192,39 @@ int rewriteStreamObject(rio *r, robj *key, robj *o) { /* Use the XADD MAXLEN 0 trick to generate an empty stream if * the key we are serializing is an empty string, which is possible * for the Stream type. */ - id.ms = 0; id.seq = 1; - if (!rioWriteBulkCount(r,'*',7) || - !rioWriteBulkString(r,"XADD",4) || - !rioWriteBulkObject(r,key) || - !rioWriteBulkString(r,"MAXLEN",6) || - !rioWriteBulkString(r,"0",1) || - !rioWriteBulkStreamID(r,&id) || - !rioWriteBulkString(r,"x",1) || - !rioWriteBulkString(r,"y",1)) - { + id.ms = 0; + id.seq = 1; + if (!rioWriteBulkCount(r, '*', 7) || !rioWriteBulkString(r, "XADD", 4) || !rioWriteBulkObject(r, key) || + !rioWriteBulkString(r, "MAXLEN", 6) || !rioWriteBulkString(r, "0", 1) || !rioWriteBulkStreamID(r, &id) || + !rioWriteBulkString(r, "x", 1) || !rioWriteBulkString(r, "y", 1)) { streamIteratorStop(&si); - return 0; + return 0; } } /* Append XSETID after XADD, make sure lastid is correct, * in case of XDEL lastid. */ - if (!rioWriteBulkCount(r,'*',7) || - !rioWriteBulkString(r,"XSETID",6) || - !rioWriteBulkObject(r,key) || - !rioWriteBulkStreamID(r,&s->last_id) || - !rioWriteBulkString(r,"ENTRIESADDED",12) || - !rioWriteBulkLongLong(r,s->entries_added) || - !rioWriteBulkString(r,"MAXDELETEDID",12) || - !rioWriteBulkStreamID(r,&s->max_deleted_entry_id)) - { + if (!rioWriteBulkCount(r, '*', 7) || !rioWriteBulkString(r, "XSETID", 6) || !rioWriteBulkObject(r, key) || + !rioWriteBulkStreamID(r, &s->last_id) || !rioWriteBulkString(r, "ENTRIESADDED", 12) || + !rioWriteBulkLongLong(r, s->entries_added) || !rioWriteBulkString(r, "MAXDELETEDID", 12) || + !rioWriteBulkStreamID(r, &s->max_deleted_entry_id)) { streamIteratorStop(&si); - return 0; + return 0; } /* Create all the stream consumer groups. */ if (s->cgroups) { raxIterator ri; - raxStart(&ri,s->cgroups); - raxSeek(&ri,"^",NULL,0); - while(raxNext(&ri)) { + raxStart(&ri, s->cgroups); + raxSeek(&ri, "^", NULL, 0); + while (raxNext(&ri)) { streamCG *group = ri.data; /* Emit the XGROUP CREATE in order to create the group. */ - if (!rioWriteBulkCount(r,'*',7) || - !rioWriteBulkString(r,"XGROUP",6) || - !rioWriteBulkString(r,"CREATE",6) || - !rioWriteBulkObject(r,key) || - !rioWriteBulkString(r,(char*)ri.key,ri.key_len) || - !rioWriteBulkStreamID(r,&group->last_id) || - !rioWriteBulkString(r,"ENTRIESREAD",11) || - !rioWriteBulkLongLong(r,group->entries_read)) - { + if (!rioWriteBulkCount(r, '*', 7) || !rioWriteBulkString(r, "XGROUP", 6) || + !rioWriteBulkString(r, "CREATE", 6) || !rioWriteBulkObject(r, key) || + !rioWriteBulkString(r, (char *)ri.key, ri.key_len) || !rioWriteBulkStreamID(r, &group->last_id) || + !rioWriteBulkString(r, "ENTRIESREAD", 11) || !rioWriteBulkLongLong(r, group->entries_read)) { raxStop(&ri); streamIteratorStop(&si); return 0; @@ -2162,15 +2234,13 @@ int rewriteStreamObject(rio *r, robj *key, robj *o) { * have pending entries. Empty consumers would be generated with * XGROUP CREATECONSUMER. */ raxIterator ri_cons; - raxStart(&ri_cons,group->consumers); - raxSeek(&ri_cons,"^",NULL,0); - while(raxNext(&ri_cons)) { + raxStart(&ri_cons, group->consumers); + raxSeek(&ri_cons, "^", NULL, 0); + while (raxNext(&ri_cons)) { streamConsumer *consumer = ri_cons.data; /* If there are no pending entries, just emit XGROUP CREATECONSUMER */ if (raxSize(consumer->pel) == 0) { - if (rioWriteStreamEmptyConsumer(r,key,(char*)ri.key, - ri.key_len,consumer) == 0) - { + if (rioWriteStreamEmptyConsumer(r, key, (char *)ri.key, ri.key_len, consumer) == 0) { raxStop(&ri_cons); raxStop(&ri); streamIteratorStop(&si); @@ -2181,14 +2251,12 @@ int rewriteStreamObject(rio *r, robj *key, robj *o) { /* For the current consumer, iterate all the PEL entries * to emit the XCLAIM protocol. */ raxIterator ri_pel; - raxStart(&ri_pel,consumer->pel); - raxSeek(&ri_pel,"^",NULL,0); - while(raxNext(&ri_pel)) { + raxStart(&ri_pel, consumer->pel); + raxSeek(&ri_pel, "^", NULL, 0); + while (raxNext(&ri_pel)) { streamNACK *nack = ri_pel.data; - if (rioWriteStreamPendingEntry(r,key,(char*)ri.key, - ri.key_len,consumer, - ri_pel.key,nack) == 0) - { + if (rioWriteStreamPendingEntry(r, key, (char *)ri.key, ri.key_len, consumer, ri_pel.key, nack) == + 0) { raxStop(&ri_pel); raxStop(&ri_cons); raxStop(&ri); @@ -2214,8 +2282,8 @@ int rewriteModuleObject(rio *r, robj *key, robj *o, int dbid) { ValkeyModuleIO io; moduleValue *mv = o->ptr; moduleType *mt = mv->type; - moduleInitIOContext(io,mt,r,key,dbid); - mt->aof_rewrite(&io,key,mv->value); + moduleInitIOContext(io, mt, r, key, dbid); + mt->aof_rewrite(&io, key, mv->value); if (io.ctx) { moduleFreeContext(io.ctx); zfree(io.ctx); @@ -2229,10 +2297,16 @@ static int rewriteFunctions(rio *aof) { dictEntry *entry = NULL; while ((entry = dictNext(iter))) { functionLibInfo *li = dictGetVal(entry); - if (rioWrite(aof, "*3\r\n", 4) == 0) goto werr; + if (rioWrite(aof, "*3\r\n", 4) == 0) { + goto werr; + } char function_load[] = "$8\r\nFUNCTION\r\n$4\r\nLOAD\r\n"; - if (rioWrite(aof, function_load, sizeof(function_load) - 1) == 0) goto werr; - if (rioWriteBulkString(aof, li->code, sdslen(li->code)) == 0) goto werr; + if (rioWrite(aof, function_load, sizeof(function_load) - 1) == 0) { + goto werr; + } + if (rioWriteBulkString(aof, li->code, sdslen(li->code)) == 0) { + goto werr; + } } dictReleaseIterator(iter); return 1; @@ -2252,24 +2326,35 @@ int rewriteAppendOnlyFileRio(rio *aof) { /* Record timestamp at the beginning of rewriting AOF. */ if (server.aof_timestamp_enabled) { sds ts = genAofTimestampAnnotationIfNeeded(1); - if (rioWrite(aof,ts,sdslen(ts)) == 0) { sdsfree(ts); goto werr; } + if (rioWrite(aof, ts, sdslen(ts)) == 0) { + sdsfree(ts); + goto werr; + } sdsfree(ts); } - if (rewriteFunctions(aof) == 0) goto werr; + if (rewriteFunctions(aof) == 0) { + goto werr; + } for (j = 0; j < server.dbnum; j++) { char selectcmd[] = "*2\r\n$6\r\nSELECT\r\n"; serverDb *db = server.db + j; - if (kvstoreSize(db->keys) == 0) continue; + if (kvstoreSize(db->keys) == 0) { + continue; + } /* SELECT the new DB */ - if (rioWrite(aof,selectcmd,sizeof(selectcmd)-1) == 0) goto werr; - if (rioWriteBulkLongLong(aof,j) == 0) goto werr; + if (rioWrite(aof, selectcmd, sizeof(selectcmd) - 1) == 0) { + goto werr; + } + if (rioWriteBulkLongLong(aof, j) == 0) { + goto werr; + } kvs_it = kvstoreIteratorInit(db->keys); /* Iterate this DB writing every entry */ - while((de = kvstoreIteratorNext(kvs_it)) != NULL) { + while ((de = kvstoreIteratorNext(kvs_it)) != NULL) { sds keystr; robj key, *o; long long expiretime; @@ -2277,30 +2362,48 @@ int rewriteAppendOnlyFileRio(rio *aof) { keystr = dictGetKey(de); o = dictGetVal(de); - initStaticStringObject(key,keystr); + initStaticStringObject(key, keystr); - expiretime = getExpire(db,&key); + expiretime = getExpire(db, &key); /* Save the key and associated value */ if (o->type == OBJ_STRING) { /* Emit a SET command */ - char cmd[]="*3\r\n$3\r\nSET\r\n"; - if (rioWrite(aof,cmd,sizeof(cmd)-1) == 0) goto werr; + char cmd[] = "*3\r\n$3\r\nSET\r\n"; + if (rioWrite(aof, cmd, sizeof(cmd) - 1) == 0) { + goto werr; + } /* Key and value */ - if (rioWriteBulkObject(aof,&key) == 0) goto werr; - if (rioWriteBulkObject(aof,o) == 0) goto werr; + if (rioWriteBulkObject(aof, &key) == 0) { + goto werr; + } + if (rioWriteBulkObject(aof, o) == 0) { + goto werr; + } } else if (o->type == OBJ_LIST) { - if (rewriteListObject(aof,&key,o) == 0) goto werr; + if (rewriteListObject(aof, &key, o) == 0) { + goto werr; + } } else if (o->type == OBJ_SET) { - if (rewriteSetObject(aof,&key,o) == 0) goto werr; + if (rewriteSetObject(aof, &key, o) == 0) { + goto werr; + } } else if (o->type == OBJ_ZSET) { - if (rewriteSortedSetObject(aof,&key,o) == 0) goto werr; + if (rewriteSortedSetObject(aof, &key, o) == 0) { + goto werr; + } } else if (o->type == OBJ_HASH) { - if (rewriteHashObject(aof,&key,o) == 0) goto werr; + if (rewriteHashObject(aof, &key, o) == 0) { + goto werr; + } } else if (o->type == OBJ_STREAM) { - if (rewriteStreamObject(aof,&key,o) == 0) goto werr; + if (rewriteStreamObject(aof, &key, o) == 0) { + goto werr; + } } else if (o->type == OBJ_MODULE) { - if (rewriteModuleObject(aof,&key,o,j) == 0) goto werr; + if (rewriteModuleObject(aof, &key, o, j) == 0) { + goto werr; + } } else { serverPanic("Unknown object type"); } @@ -2309,14 +2412,22 @@ int rewriteAppendOnlyFileRio(rio *aof) { * OS and possibly avoid or decrease COW. We give the dismiss * mechanism a hint about an estimated size of the object we stored. */ size_t dump_size = aof->processed_bytes - aof_bytes_before_key; - if (server.in_fork_child) dismissObject(o, dump_size); + if (server.in_fork_child) { + dismissObject(o, dump_size); + } /* Save the expire time */ if (expiretime != -1) { - char cmd[]="*3\r\n$9\r\nPEXPIREAT\r\n"; - if (rioWrite(aof,cmd,sizeof(cmd)-1) == 0) goto werr; - if (rioWriteBulkObject(aof,&key) == 0) goto werr; - if (rioWriteBulkLongLong(aof,expiretime) == 0) goto werr; + char cmd[] = "*3\r\n$9\r\nPEXPIREAT\r\n"; + if (rioWrite(aof, cmd, sizeof(cmd) - 1) == 0) { + goto werr; + } + if (rioWriteBulkObject(aof, &key) == 0) { + goto werr; + } + if (rioWriteBulkLongLong(aof, expiretime) == 0) { + goto werr; + } } /* Update info every 1 second (approximately). @@ -2331,15 +2442,18 @@ int rewriteAppendOnlyFileRio(rio *aof) { } /* Delay before next key if required (for testing) */ - if (server.rdb_key_save_delay) + if (server.rdb_key_save_delay) { debugDelay(server.rdb_key_save_delay); + } } kvstoreIteratorRelease(kvs_it); } return C_OK; werr: - if (kvs_it) kvstoreIteratorRelease(kvs_it); + if (kvs_it) { + kvstoreIteratorRelease(kvs_it); + } return C_ERR; } @@ -2357,46 +2471,55 @@ int rewriteAppendOnlyFile(char *filename) { /* Note that we have to use a different temp name here compared to the * one used by rewriteAppendOnlyFileBackground() function. */ - snprintf(tmpfile,256,"temp-rewriteaof-%d.aof", (int) getpid()); - fp = fopen(tmpfile,"w"); + snprintf(tmpfile, 256, "temp-rewriteaof-%d.aof", (int)getpid()); + fp = fopen(tmpfile, "w"); if (!fp) { serverLog(LL_WARNING, "Opening the temp file for AOF rewrite in rewriteAppendOnlyFile(): %s", strerror(errno)); return C_ERR; } - rioInitWithFile(&aof,fp); + rioInitWithFile(&aof, fp); if (server.aof_rewrite_incremental_fsync) { - rioSetAutoSync(&aof,REDIS_AUTOSYNC_BYTES); - rioSetReclaimCache(&aof,1); + rioSetAutoSync(&aof, REDIS_AUTOSYNC_BYTES); + rioSetReclaimCache(&aof, 1); } startSaving(RDBFLAGS_AOF_PREAMBLE); if (server.aof_use_rdb_preamble) { int error; - if (rdbSaveRio(SLAVE_REQ_NONE,&aof,&error,RDBFLAGS_AOF_PREAMBLE,NULL) == C_ERR) { + if (rdbSaveRio(SLAVE_REQ_NONE, &aof, &error, RDBFLAGS_AOF_PREAMBLE, NULL) == C_ERR) { errno = error; goto werr; } } else { - if (rewriteAppendOnlyFileRio(&aof) == C_ERR) goto werr; + if (rewriteAppendOnlyFileRio(&aof) == C_ERR) { + goto werr; + } } /* Make sure data will not remain on the OS's output buffers */ - if (fflush(fp)) goto werr; - if (fsync(fileno(fp))) goto werr; + if (fflush(fp)) { + goto werr; + } + if (fsync(fileno(fp))) { + goto werr; + } if (reclaimFilePageCache(fileno(fp), 0, 0) == -1) { /* A minor error. Just log to know what happens */ - serverLog(LL_NOTICE,"Unable to reclaim page cache: %s", strerror(errno)); + serverLog(LL_NOTICE, "Unable to reclaim page cache: %s", strerror(errno)); + } + if (fclose(fp)) { + fp = NULL; + goto werr; } - if (fclose(fp)) { fp = NULL; goto werr; } fp = NULL; /* Use RENAME to make sure the DB file is changed atomically only * if the generate DB file is ok. */ - if (rename(tmpfile,filename) == -1) { - serverLog(LL_WARNING,"Error moving temp append only file on the final destination: %s", strerror(errno)); + if (rename(tmpfile, filename) == -1) { + serverLog(LL_WARNING, "Error moving temp append only file on the final destination: %s", strerror(errno)); unlink(tmpfile); stopSaving(0); return C_ERR; @@ -2406,8 +2529,10 @@ int rewriteAppendOnlyFile(char *filename) { return C_OK; werr: - serverLog(LL_WARNING,"Write error writing append only file on disk: %s", strerror(errno)); - if (fp) fclose(fp); + serverLog(LL_WARNING, "Write error writing append only file on disk: %s", strerror(errno)); + if (fp) { + fclose(fp); + } unlink(tmpfile); stopSaving(0); return C_ERR; @@ -2433,11 +2558,12 @@ int rewriteAppendOnlyFile(char *filename) { int rewriteAppendOnlyFileBackground(void) { pid_t childpid; - if (hasActiveChildProcess()) return C_ERR; + if (hasActiveChildProcess()) { + return C_ERR; + } if (dirCreateIfMissing(server.aof_dirname) == -1) { - serverLog(LL_WARNING, "Can't open or create append-only dir %s: %s", - server.aof_dirname, strerror(errno)); + serverLog(LL_WARNING, "Can't open or create append-only dir %s: %s", server.aof_dirname, strerror(errno)); server.aof_lastbgrewrite_status = C_ERR; return C_ERR; } @@ -2471,16 +2597,15 @@ int rewriteAppendOnlyFileBackground(void) { char tmpfile[256]; /* Child */ - if (strstr(server.exec_argv[0],"redis-server") != NULL) { + if (strstr(server.exec_argv[0], "redis-server") != NULL) { serverSetProcTitle("redis-aof-rewrite"); } else { serverSetProcTitle("valkey-aof-rewrite"); } serverSetCpuAffinity(server.aof_rewrite_cpulist); - snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid()); + snprintf(tmpfile, 256, "temp-rewriteaof-bg-%d.aof", (int)getpid()); if (rewriteAppendOnlyFile(tmpfile) == C_OK) { - serverLog(LL_NOTICE, - "Successfully created the temporary AOF base file %s", tmpfile); + serverLog(LL_NOTICE, "Successfully created the temporary AOF base file %s", tmpfile); sendChildCowInfo(CHILD_INFO_TYPE_AOF_COW_SIZE, "AOF rewrite"); exitFromChild(0); } else { @@ -2490,13 +2615,10 @@ int rewriteAppendOnlyFileBackground(void) { /* Parent */ if (childpid == -1) { server.aof_lastbgrewrite_status = C_ERR; - serverLog(LL_WARNING, - "Can't rewrite append only file in background: fork: %s", - strerror(errno)); + serverLog(LL_WARNING, "Can't rewrite append only file in background: fork: %s", strerror(errno)); return C_ERR; } - serverLog(LL_NOTICE, - "Background append only file rewriting started by pid %ld",(long) childpid); + serverLog(LL_NOTICE, "Background append only file rewriting started by pid %ld", (long)childpid); server.aof_rewrite_scheduled = 0; server.aof_rewrite_time_start = time(NULL); return C_OK; @@ -2506,28 +2628,28 @@ int rewriteAppendOnlyFileBackground(void) { void bgrewriteaofCommand(client *c) { if (server.child_type == CHILD_TYPE_AOF) { - addReplyError(c,"Background append only file rewriting already in progress"); + addReplyError(c, "Background append only file rewriting already in progress"); } else if (hasActiveChildProcess() || server.in_exec) { server.aof_rewrite_scheduled = 1; - /* When manually triggering AOFRW we reset the count + /* When manually triggering AOFRW we reset the count * so that it can be executed immediately. */ server.stat_aofrw_consecutive_failures = 0; - addReplyStatus(c,"Background append only file rewriting scheduled"); + addReplyStatus(c, "Background append only file rewriting scheduled"); } else if (rewriteAppendOnlyFileBackground() == C_OK) { - addReplyStatus(c,"Background append only file rewriting started"); + addReplyStatus(c, "Background append only file rewriting started"); } else { - addReplyError(c,"Can't execute an AOF background rewriting. " - "Please check the server logs for more information."); + addReplyError(c, "Can't execute an AOF background rewriting. " + "Please check the server logs for more information."); } } void aofRemoveTempFile(pid_t childpid) { char tmpfile[256]; - snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) childpid); + snprintf(tmpfile, 256, "temp-rewriteaof-bg-%d.aof", (int)childpid); bg_unlink(tmpfile); - snprintf(tmpfile,256,"temp-rewriteaof-%d.aof", (int) childpid); + snprintf(tmpfile, 256, "temp-rewriteaof-%d.aof", (int)childpid); bg_unlink(tmpfile); } @@ -2542,12 +2664,15 @@ off_t getAppendOnlyFileSize(sds filename, int *status) { sds aof_filepath = makePath(server.aof_dirname, filename); latencyStartMonitor(latency); if (valkey_stat(aof_filepath, &sb) == -1) { - if (status) *status = errno == ENOENT ? AOF_NOT_EXIST : AOF_OPEN_ERR; - serverLog(LL_WARNING, "Unable to obtain the AOF file %s length. stat: %s", - filename, strerror(errno)); + if (status) { + *status = errno == ENOENT ? AOF_NOT_EXIST : AOF_OPEN_ERR; + } + serverLog(LL_WARNING, "Unable to obtain the AOF file %s length. stat: %s", filename, strerror(errno)); size = 0; } else { - if (status) *status = AOF_OK; + if (status) { + *status = AOF_OK; + } size = sb.st_size; } latencyEndMonitor(latency); @@ -2568,15 +2693,19 @@ off_t getBaseAndIncrAppendOnlyFilesSize(aofManifest *am, int *status) { serverAssert(am->base_aof_info->file_type == AOF_FILE_TYPE_BASE); size += getAppendOnlyFileSize(am->base_aof_info->file_name, status); - if (*status != AOF_OK) return 0; + if (*status != AOF_OK) { + return 0; + } } listRewind(am->incr_aof_list, &li); while ((ln = listNext(&li)) != NULL) { - aofInfo *ai = (aofInfo*)ln->value; + aofInfo *ai = (aofInfo *)ln->value; serverAssert(ai->file_type == AOF_FILE_TYPE_INCR); size += getAppendOnlyFileSize(ai->file_name, status); - if (*status != AOF_OK) return 0; + if (*status != AOF_OK) { + return 0; + } } return size; @@ -2584,8 +2713,12 @@ off_t getBaseAndIncrAppendOnlyFilesSize(aofManifest *am, int *status) { int getBaseAndIncrAppendOnlyFilesNum(aofManifest *am) { int num = 0; - if (am->base_aof_info) num++; - if (am->incr_aof_list) num += listLength(am->incr_aof_list); + if (am->base_aof_info) { + num++; + } + if (am->incr_aof_list) { + num += listLength(am->incr_aof_list); + } return num; } @@ -2600,11 +2733,9 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) { aofManifest *temp_am; mstime_t latency; - serverLog(LL_NOTICE, - "Background AOF rewrite terminated with success"); + serverLog(LL_NOTICE, "Background AOF rewrite terminated with success"); - snprintf(tmpfile, 256, "temp-rewriteaof-bg-%d.aof", - (int)server.child_pid); + snprintf(tmpfile, 256, "temp-rewriteaof-bg-%d.aof", (int)server.child_pid); serverAssert(server.aof_manifest != NULL); @@ -2620,11 +2751,8 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) { /* Rename the temporary aof file to 'new_base_filename'. */ latencyStartMonitor(latency); if (rename(tmpfile, new_base_filepath) == -1) { - serverLog(LL_WARNING, - "Error trying to rename the temporary AOF base file %s into %s: %s", - tmpfile, - new_base_filepath, - strerror(errno)); + serverLog(LL_WARNING, "Error trying to rename the temporary AOF base file %s into %s: %s", tmpfile, + new_base_filepath, strerror(errno)); aofManifestFree(temp_am); sdsfree(new_base_filepath); server.aof_lastbgrewrite_status = C_ERR; @@ -2633,8 +2761,7 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) { } latencyEndMonitor(latency); latencyAddSampleIfNeeded("aof-rename", latency); - serverLog(LL_NOTICE, - "Successfully renamed the temporary AOF base file %s into %s", tmpfile, new_base_filename); + serverLog(LL_NOTICE, "Successfully renamed the temporary AOF base file %s into %s", tmpfile, new_base_filename); /* Rename the temporary incr aof file to 'new_incr_filename'. */ if (server.aof_state == AOF_WAIT_REWRITE) { @@ -2646,11 +2773,8 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) { new_incr_filepath = makePath(server.aof_dirname, new_incr_filename); latencyStartMonitor(latency); if (rename(temp_incr_filepath, new_incr_filepath) == -1) { - serverLog(LL_WARNING, - "Error trying to rename the temporary AOF incr file %s into %s: %s", - temp_incr_filepath, - new_incr_filepath, - strerror(errno)); + serverLog(LL_WARNING, "Error trying to rename the temporary AOF incr file %s into %s: %s", + temp_incr_filepath, new_incr_filepath, strerror(errno)); bg_unlink(new_base_filepath); sdsfree(new_base_filepath); aofManifestFree(temp_am); @@ -2663,8 +2787,8 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) { } latencyEndMonitor(latency); latencyAddSampleIfNeeded("aof-rename", latency); - serverLog(LL_NOTICE, - "Successfully renamed the temporary AOF incr file %s into %s", temp_incr_aof_name, new_incr_filename); + serverLog(LL_NOTICE, "Successfully renamed the temporary AOF incr file %s into %s", temp_incr_aof_name, + new_incr_filename); sdsfree(temp_incr_filepath); sdsfree(temp_incr_aof_name); } @@ -2687,7 +2811,9 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) { goto cleanup; } sdsfree(new_base_filepath); - if (new_incr_filepath) sdsfree(new_incr_filepath); + if (new_incr_filepath) { + sdsfree(new_incr_filepath); + } /* We can safely let `server.aof_manifest` point to 'temp_am' and free the previous one. */ aofManifestFreeAndUpdate(temp_am); @@ -2718,14 +2844,12 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) { server.fsynced_reploff = fsynced_reploff_pending; } - serverLog(LL_VERBOSE, - "Background AOF rewrite signal handler took %lldus", ustime()-now); + serverLog(LL_VERBOSE, "Background AOF rewrite signal handler took %lldus", ustime() - now); } else if (!bysignal && exitcode != 0) { server.aof_lastbgrewrite_status = C_ERR; server.stat_aofrw_consecutive_failures++; - serverLog(LL_WARNING, - "Background AOF rewrite terminated with error"); + serverLog(LL_WARNING, "Background AOF rewrite terminated with error"); } else { /* SIGUSR1 is whitelisted, so we have a way to kill a child without * triggering an error condition. */ @@ -2734,8 +2858,7 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) { server.stat_aofrw_consecutive_failures++; } - serverLog(LL_WARNING, - "Background AOF rewrite terminated by signal %d", bysignal); + serverLog(LL_WARNING, "Background AOF rewrite terminated by signal %d", bysignal); } cleanup: @@ -2746,9 +2869,10 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) { server.aof_buf = sdsempty(); aofDelTempIncrAofFile(); } - server.aof_rewrite_time_last = time(NULL)-server.aof_rewrite_time_start; + server.aof_rewrite_time_last = time(NULL) - server.aof_rewrite_time_start; server.aof_rewrite_time_start = -1; /* Schedule a new rewrite if we are waiting for it to switch the AOF ON. */ - if (server.aof_state == AOF_WAIT_REWRITE) + if (server.aof_state == AOF_WAIT_REWRITE) { server.aof_rewrite_scheduled = 1; + } } diff --git a/src/asciilogo.h b/src/asciilogo.h index d41f8a4c7..8d9b6e88b 100644 --- a/src/asciilogo.h +++ b/src/asciilogo.h @@ -27,23 +27,22 @@ * POSSIBILITY OF SUCH DAMAGE. */ -const char *ascii_logo = -" .+^+. \n" -" .+#########+. \n" -" .+########+########+. Valkey %s (%s/%d) %s bit\n" -" .+########+' '+########+. \n" -" .########+' .+. '+########. Running in %s mode\n" -" |####+' .+#######+. '+####| Port: %d\n" -" |###| .+###############+. |###| PID: %ld \n" -" |###| |#####*'' ''*#####| |###| \n" -" |###| |####' .-. '####| |###| \n" -" |###| |###( (@@@) )###| |###| https://valkey.io \n" -" |###| |####. '-' .####| |###| \n" -" |###| |#####*. .*#####| |###| \n" -" |###| '+#####| |#####+' |###| \n" -" |####+. +##| |#+' .+####| \n" -" '#######+ |##| .+########' \n" -" '+###| |##| .+########+' \n" -" '| |####+########+' \n" -" +#########+' \n" -" '+v+' \n\n"; +const char *ascii_logo = " .+^+. \n" + " .+#########+. \n" + " .+########+########+. Valkey %s (%s/%d) %s bit\n" + " .+########+' '+########+. \n" + " .########+' .+. '+########. Running in %s mode\n" + " |####+' .+#######+. '+####| Port: %d\n" + " |###| .+###############+. |###| PID: %ld \n" + " |###| |#####*'' ''*#####| |###| \n" + " |###| |####' .-. '####| |###| \n" + " |###| |###( (@@@) )###| |###| https://valkey.io \n" + " |###| |####. '-' .####| |###| \n" + " |###| |#####*. .*#####| |###| \n" + " |###| '+#####| |#####+' |###| \n" + " |####+. +##| |#+' .+####| \n" + " '#######+ |##| .+########' \n" + " '+###| |##| .+########+' \n" + " '| |####+########+' \n" + " +#########+' \n" + " '+v+' \n\n"; diff --git a/src/atomicvar.h b/src/atomicvar.h index 17d1c15a6..bfd95302d 100644 --- a/src/atomicvar.h +++ b/src/atomicvar.h @@ -11,31 +11,30 @@ * atomicSet(var,value) -- Set the atomic counter value * atomicGetWithSync(var,value) -- 'atomicGet' with inter-thread synchronization * atomicSetWithSync(var,value) -- 'atomicSet' with inter-thread synchronization - * - * Atomic operations on flags. + * + * Atomic operations on flags. * Flag type can be int, long, long long or their unsigned counterparts. * The value of the flag can be 1 or 0. - * + * * atomicFlagGetSet(var,oldvalue_var) -- Get and set the atomic counter value - * - * NOTE1: __atomic* and _Atomic implementations can be actually elaborated to support any value by changing the + * + * NOTE1: __atomic* and _Atomic implementations can be actually elaborated to support any value by changing the * hardcoded new value passed to __atomic_exchange* from 1 to @param count * i.e oldvalue_var = atomic_exchange_explicit(&var, count). * However, in order to be compatible with the __sync functions family, we can use only 0 and 1. - * The only exchange alternative suggested by __sync is __sync_lock_test_and_set, + * The only exchange alternative suggested by __sync is __sync_lock_test_and_set, * But as described by the gnu manual for __sync_lock_test_and_set(): * https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html - * "A target may support reduced functionality here by which the only valid value to store is the immediate constant 1. The exact value - * actually stored in *ptr is implementation defined." - * Hence, we can't rely on it for a any value other than 1. - * We eventually chose to implement this method with __sync_val_compare_and_swap since it satisfies functionality needed for atomicFlagGetSet - * (if the flag was 0 -> set to 1, if it's already 1 -> do nothing, but the final result is that the flag is set), - * and also it has a full barrier (__sync_lock_test_and_set has acquire barrier). - * + * "A target may support reduced functionality here by which the only valid value to store is the immediate constant 1. + * The exact value actually stored in *ptr is implementation defined." Hence, we can't rely on it for a any value other + * than 1. We eventually chose to implement this method with __sync_val_compare_and_swap since it satisfies + * functionality needed for atomicFlagGetSet (if the flag was 0 -> set to 1, if it's already 1 -> do nothing, but the + * final result is that the flag is set), and also it has a full barrier (__sync_lock_test_and_set has acquire barrier). + * * NOTE2: Unlike other atomic type, which aren't guaranteed to be lock free, c11 atomic_flag does. - * To check whether a type is lock free, atomic_is_lock_free() can be used. + * To check whether a type is lock free, atomic_is_lock_free() can be used. * It can be considered to limit the flag type to atomic_flag to improve performance. - * + * * Never use return value from the macros, instead use the AtomicGetIncr() * if you need to get the current value and increment it atomically, like * in the following example: @@ -102,90 +101,95 @@ #ifdef __ATOMIC_VAR_FORCE_SYNC_MACROS #include #else -#define ANNOTATE_HAPPENS_BEFORE(v) ((void) v) -#define ANNOTATE_HAPPENS_AFTER(v) ((void) v) +#define ANNOTATE_HAPPENS_BEFORE(v) ((void)v) +#define ANNOTATE_HAPPENS_AFTER(v) ((void)v) #endif -#if !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && defined(__STDC_VERSION__) && \ - (__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__) +#if !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ + !defined(__STDC_NO_ATOMICS__) /* Use '_Atomic' keyword if the compiler supports. */ -#undef serverAtomic +#undef serverAtomic #define serverAtomic _Atomic /* Implementation using _Atomic in C11. */ #include -#define atomicIncr(var,count) atomic_fetch_add_explicit(&var,(count),memory_order_relaxed) -#define atomicGetIncr(var,oldvalue_var,count) do { \ - oldvalue_var = atomic_fetch_add_explicit(&var,(count),memory_order_relaxed); \ -} while(0) -#define atomicIncrGet(var, newvalue_var, count) \ - newvalue_var = atomicIncr(var,count) + count -#define atomicDecr(var,count) atomic_fetch_sub_explicit(&var,(count),memory_order_relaxed) -#define atomicGet(var,dstvar) do { \ - dstvar = atomic_load_explicit(&var,memory_order_relaxed); \ -} while(0) -#define atomicSet(var,value) atomic_store_explicit(&var,value,memory_order_relaxed) -#define atomicGetWithSync(var,dstvar) do { \ - dstvar = atomic_load_explicit(&var,memory_order_seq_cst); \ -} while(0) -#define atomicSetWithSync(var,value) \ - atomic_store_explicit(&var,value,memory_order_seq_cst) -#define atomicFlagGetSet(var,oldvalue_var) \ - oldvalue_var = atomic_exchange_explicit(&var,1,memory_order_relaxed) +#define atomicIncr(var, count) atomic_fetch_add_explicit(&var, (count), memory_order_relaxed) +#define atomicGetIncr(var, oldvalue_var, count) \ + do { \ + oldvalue_var = atomic_fetch_add_explicit(&var, (count), memory_order_relaxed); \ + } while (0) +#define atomicIncrGet(var, newvalue_var, count) newvalue_var = atomicIncr(var, count) + count +#define atomicDecr(var, count) atomic_fetch_sub_explicit(&var, (count), memory_order_relaxed) +#define atomicGet(var, dstvar) \ + do { \ + dstvar = atomic_load_explicit(&var, memory_order_relaxed); \ + } while (0) +#define atomicSet(var, value) atomic_store_explicit(&var, value, memory_order_relaxed) +#define atomicGetWithSync(var, dstvar) \ + do { \ + dstvar = atomic_load_explicit(&var, memory_order_seq_cst); \ + } while (0) +#define atomicSetWithSync(var, value) atomic_store_explicit(&var, value, memory_order_seq_cst) +#define atomicFlagGetSet(var, oldvalue_var) oldvalue_var = atomic_exchange_explicit(&var, 1, memory_order_relaxed) #define REDIS_ATOMIC_API "c11-builtin" -#elif !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && \ - (!defined(__clang__) || !defined(__APPLE__) || __apple_build_version__ > 4210057) && \ - defined(__ATOMIC_RELAXED) && defined(__ATOMIC_SEQ_CST) +#elif !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && \ + (!defined(__clang__) || !defined(__APPLE__) || __apple_build_version__ > 4210057) && defined(__ATOMIC_RELAXED) && \ + defined(__ATOMIC_SEQ_CST) /* Implementation using __atomic macros. */ -#define atomicIncr(var,count) __atomic_add_fetch(&var,(count),__ATOMIC_RELAXED) -#define atomicIncrGet(var, newvalue_var, count) \ - newvalue_var = __atomic_add_fetch(&var,(count),__ATOMIC_RELAXED) -#define atomicGetIncr(var,oldvalue_var,count) do { \ - oldvalue_var = __atomic_fetch_add(&var,(count),__ATOMIC_RELAXED); \ -} while(0) -#define atomicDecr(var,count) __atomic_sub_fetch(&var,(count),__ATOMIC_RELAXED) -#define atomicGet(var,dstvar) do { \ - dstvar = __atomic_load_n(&var,__ATOMIC_RELAXED); \ -} while(0) -#define atomicSet(var,value) __atomic_store_n(&var,value,__ATOMIC_RELAXED) -#define atomicGetWithSync(var,dstvar) do { \ - dstvar = __atomic_load_n(&var,__ATOMIC_SEQ_CST); \ -} while(0) -#define atomicSetWithSync(var,value) \ - __atomic_store_n(&var,value,__ATOMIC_SEQ_CST) -#define atomicFlagGetSet(var,oldvalue_var) \ - oldvalue_var = __atomic_exchange_n(&var,1,__ATOMIC_RELAXED) +#define atomicIncr(var, count) __atomic_add_fetch(&var, (count), __ATOMIC_RELAXED) +#define atomicIncrGet(var, newvalue_var, count) newvalue_var = __atomic_add_fetch(&var, (count), __ATOMIC_RELAXED) +#define atomicGetIncr(var, oldvalue_var, count) \ + do { \ + oldvalue_var = __atomic_fetch_add(&var, (count), __ATOMIC_RELAXED); \ + } while (0) +#define atomicDecr(var, count) __atomic_sub_fetch(&var, (count), __ATOMIC_RELAXED) +#define atomicGet(var, dstvar) \ + do { \ + dstvar = __atomic_load_n(&var, __ATOMIC_RELAXED); \ + } while (0) +#define atomicSet(var, value) __atomic_store_n(&var, value, __ATOMIC_RELAXED) +#define atomicGetWithSync(var, dstvar) \ + do { \ + dstvar = __atomic_load_n(&var, __ATOMIC_SEQ_CST); \ + } while (0) +#define atomicSetWithSync(var, value) __atomic_store_n(&var, value, __ATOMIC_SEQ_CST) +#define atomicFlagGetSet(var, oldvalue_var) oldvalue_var = __atomic_exchange_n(&var, 1, __ATOMIC_RELAXED) #define REDIS_ATOMIC_API "atomic-builtin" #elif defined(HAVE_ATOMIC) /* Implementation using __sync macros. */ -#define atomicIncr(var,count) __sync_add_and_fetch(&var,(count)) -#define atomicIncrGet(var, newvalue_var, count) \ - newvalue_var = __sync_add_and_fetch(&var,(count)) -#define atomicGetIncr(var,oldvalue_var,count) do { \ - oldvalue_var = __sync_fetch_and_add(&var,(count)); \ -} while(0) -#define atomicDecr(var,count) __sync_sub_and_fetch(&var,(count)) -#define atomicGet(var,dstvar) do { \ - dstvar = __sync_sub_and_fetch(&var,0); \ -} while(0) -#define atomicSet(var,value) do { \ - while(!__sync_bool_compare_and_swap(&var,var,value)); \ -} while(0) +#define atomicIncr(var, count) __sync_add_and_fetch(&var, (count)) +#define atomicIncrGet(var, newvalue_var, count) newvalue_var = __sync_add_and_fetch(&var, (count)) +#define atomicGetIncr(var, oldvalue_var, count) \ + do { \ + oldvalue_var = __sync_fetch_and_add(&var, (count)); \ + } while (0) +#define atomicDecr(var, count) __sync_sub_and_fetch(&var, (count)) +#define atomicGet(var, dstvar) \ + do { \ + dstvar = __sync_sub_and_fetch(&var, 0); \ + } while (0) +#define atomicSet(var, value) \ + do { \ + while (!__sync_bool_compare_and_swap(&var, var, value)) \ + ; \ + } while (0) /* Actually the builtin issues a full memory barrier by default. */ -#define atomicGetWithSync(var,dstvar) do { \ - dstvar = __sync_sub_and_fetch(&var,0,__sync_synchronize); \ - ANNOTATE_HAPPENS_AFTER(&var); \ -} while(0) -#define atomicSetWithSync(var,value) do { \ - ANNOTATE_HAPPENS_BEFORE(&var); \ - while(!__sync_bool_compare_and_swap(&var,var,value,__sync_synchronize)); \ -} while(0) -#define atomicFlagGetSet(var,oldvalue_var) \ - oldvalue_var = __sync_val_compare_and_swap(&var,0,1) +#define atomicGetWithSync(var, dstvar) \ + do { \ + dstvar = __sync_sub_and_fetch(&var, 0, __sync_synchronize); \ + ANNOTATE_HAPPENS_AFTER(&var); \ + } while (0) +#define atomicSetWithSync(var, value) \ + do { \ + ANNOTATE_HAPPENS_BEFORE(&var); \ + while (!__sync_bool_compare_and_swap(&var, var, value, __sync_synchronize)) \ + ; \ + } while (0) +#define atomicFlagGetSet(var, oldvalue_var) oldvalue_var = __sync_val_compare_and_swap(&var, 0, 1) #define REDIS_ATOMIC_API "sync-builtin" #else diff --git a/src/bio.c b/src/bio.c index e0da64025..ea754e525 100644 --- a/src/bio.c +++ b/src/bio.c @@ -63,7 +63,7 @@ #include "server.h" #include "bio.h" -static char* bio_worker_title[] = { +static char *bio_worker_title[] = { "bio_close_file", "bio_aof", "bio_lazy_free", @@ -94,18 +94,18 @@ typedef union bio_job { /* Job specific arguments.*/ struct { int type; - int fd; /* Fd for file based background jobs */ - long long offset; /* A job-specific offset, if applicable */ - unsigned need_fsync:1; /* A flag to indicate that a fsync is required before - * the file is closed. */ - unsigned need_reclaim_cache:1; /* A flag to indicate that reclaim cache is required before - * the file is closed. */ + int fd; /* Fd for file based background jobs */ + long long offset; /* A job-specific offset, if applicable */ + unsigned need_fsync : 1; /* A flag to indicate that a fsync is required before + * the file is closed. */ + unsigned need_reclaim_cache : 1; /* A flag to indicate that reclaim cache is required before + * the file is closed. */ } fd_args; struct { int type; lazy_free_fn *free_fn; /* Function that will free the provided arguments */ - void *free_args[]; /* List of arguments to be passed to the free function */ + void *free_args[]; /* List of arguments to be passed to the free function */ } free_args; } bio_job; @@ -113,7 +113,7 @@ void *bioProcessBackgroundJobs(void *arg); /* Make sure we have enough stack to perform all the things we do in the * main thread. */ -#define VALKEY_THREAD_STACK_SIZE (1024*1024*4) +#define VALKEY_THREAD_STACK_SIZE (1024 * 1024 * 4) /* Initialize the background system, spawning the thread. */ void bioInit(void) { @@ -124,24 +124,28 @@ void bioInit(void) { /* Initialization of state vars and objects */ for (j = 0; j < BIO_WORKER_NUM; j++) { - pthread_mutex_init(&bio_mutex[j],NULL); - pthread_cond_init(&bio_newjob_cond[j],NULL); + pthread_mutex_init(&bio_mutex[j], NULL); + pthread_cond_init(&bio_newjob_cond[j], NULL); bio_jobs[j] = listCreate(); } /* Set the stack size as by default it may be small in some system */ pthread_attr_init(&attr); - pthread_attr_getstacksize(&attr,&stacksize); - if (!stacksize) stacksize = 1; /* The world is full of Solaris Fixes */ - while (stacksize < VALKEY_THREAD_STACK_SIZE) stacksize *= 2; + pthread_attr_getstacksize(&attr, &stacksize); + if (!stacksize) { + stacksize = 1; /* The world is full of Solaris Fixes */ + } + while (stacksize < VALKEY_THREAD_STACK_SIZE) { + stacksize *= 2; + } pthread_attr_setstacksize(&attr, stacksize); /* Ready to spawn our threads. We use the single argument the thread * function accepts in order to pass the job ID the thread is * responsible for. */ for (j = 0; j < BIO_WORKER_NUM; j++) { - void *arg = (void*)(unsigned long) j; - if (pthread_create(&thread,&attr,bioProcessBackgroundJobs,arg) != 0) { + void *arg = (void *)(unsigned long)j; + if (pthread_create(&thread, &attr, bioProcessBackgroundJobs, arg) != 0) { serverLog(LL_WARNING, "Fatal: Can't initialize Background Jobs. Error message: %s", strerror(errno)); exit(1); } @@ -153,7 +157,7 @@ void bioSubmitJob(int type, bio_job *job) { job->header.type = type; unsigned long worker = bio_job_to_worker[type]; pthread_mutex_lock(&bio_mutex[worker]); - listAddNodeTail(bio_jobs[worker],job); + listAddNodeTail(bio_jobs[worker], job); bio_jobs_counter[type]++; pthread_cond_signal(&bio_newjob_cond[worker]); pthread_mutex_unlock(&bio_mutex[worker]); @@ -204,7 +208,7 @@ void bioCreateFsyncJob(int fd, long long offset, int need_reclaim_cache) { void *bioProcessBackgroundJobs(void *arg) { bio_job *job; - unsigned long worker = (unsigned long) arg; + unsigned long worker = (unsigned long)arg; sigset_t sigset; /* Check that the worker is within the right interval. */ @@ -221,11 +225,11 @@ void *bioProcessBackgroundJobs(void *arg) { * receive the watchdog signal. */ sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); - if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) - serverLog(LL_WARNING, - "Warning: can't mask SIGALRM in bio.c thread: %s", strerror(errno)); + if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) { + serverLog(LL_WARNING, "Warning: can't mask SIGALRM in bio.c thread: %s", strerror(errno)); + } - while(1) { + while (1) { listNode *ln; /* The loop always starts with the lock hold. */ @@ -244,15 +248,12 @@ void *bioProcessBackgroundJobs(void *arg) { int job_type = job->header.type; if (job_type == BIO_CLOSE_FILE) { - if (job->fd_args.need_fsync && - valkey_fsync(job->fd_args.fd) == -1 && - errno != EBADF && errno != EINVAL) - { - serverLog(LL_WARNING, "Fail to fsync the AOF file: %s",strerror(errno)); + if (job->fd_args.need_fsync && valkey_fsync(job->fd_args.fd) == -1 && errno != EBADF && errno != EINVAL) { + serverLog(LL_WARNING, "Fail to fsync the AOF file: %s", strerror(errno)); } if (job->fd_args.need_reclaim_cache) { if (reclaimFilePageCache(job->fd_args.fd, 0, 0) == -1) { - serverLog(LL_NOTICE,"Unable to reclaim page cache: %s", strerror(errno)); + serverLog(LL_NOTICE, "Unable to reclaim page cache: %s", strerror(errno)); } } close(job->fd_args.fd); @@ -260,29 +261,27 @@ void *bioProcessBackgroundJobs(void *arg) { /* The fd may be closed by main thread and reused for another * socket, pipe, or file. We just ignore these errno because * aof fsync did not really fail. */ - if (valkey_fsync(job->fd_args.fd) == -1 && - errno != EBADF && errno != EINVAL) - { + if (valkey_fsync(job->fd_args.fd) == -1 && errno != EBADF && errno != EINVAL) { int last_status; - atomicGet(server.aof_bio_fsync_status,last_status); - atomicSet(server.aof_bio_fsync_status,C_ERR); - atomicSet(server.aof_bio_fsync_errno,errno); + atomicGet(server.aof_bio_fsync_status, last_status); + atomicSet(server.aof_bio_fsync_status, C_ERR); + atomicSet(server.aof_bio_fsync_errno, errno); if (last_status == C_OK) { - serverLog(LL_WARNING, - "Fail to fsync the AOF file: %s",strerror(errno)); + serverLog(LL_WARNING, "Fail to fsync the AOF file: %s", strerror(errno)); } } else { - atomicSet(server.aof_bio_fsync_status,C_OK); + atomicSet(server.aof_bio_fsync_status, C_OK); atomicSet(server.fsynced_reploff_pending, job->fd_args.offset); } if (job->fd_args.need_reclaim_cache) { if (reclaimFilePageCache(job->fd_args.fd, 0, 0) == -1) { - serverLog(LL_NOTICE,"Unable to reclaim page cache: %s", strerror(errno)); + serverLog(LL_NOTICE, "Unable to reclaim page cache: %s", strerror(errno)); } } - if (job_type == BIO_CLOSE_AOF) + if (job_type == BIO_CLOSE_AOF) { close(job->fd_args.fd); + } } else if (job_type == BIO_LAZY_FREE) { job->free_args.free_fn(job->free_args.free_args); } else { @@ -330,15 +329,14 @@ void bioKillThreads(void) { unsigned long j; for (j = 0; j < BIO_WORKER_NUM; j++) { - if (bio_threads[j] == pthread_self()) continue; + if (bio_threads[j] == pthread_self()) { + continue; + } if (bio_threads[j] && pthread_cancel(bio_threads[j]) == 0) { - if ((err = pthread_join(bio_threads[j],NULL)) != 0) { - serverLog(LL_WARNING, - "Bio worker thread #%lu can not be joined: %s", - j, strerror(err)); + if ((err = pthread_join(bio_threads[j], NULL)) != 0) { + serverLog(LL_WARNING, "Bio worker thread #%lu can not be joined: %s", j, strerror(err)); } else { - serverLog(LL_WARNING, - "Bio worker thread #%lu terminated",j); + serverLog(LL_WARNING, "Bio worker thread #%lu terminated", j); } } } diff --git a/src/bitops.c b/src/bitops.c index 4d2fcbf7c..69db06906 100644 --- a/src/bitops.c +++ b/src/bitops.c @@ -41,17 +41,24 @@ long long serverPopcount(void *s, long count) { long long bits = 0; unsigned char *p = s; uint32_t *p4; - static const unsigned char bitsinbyte[256] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8}; + static const unsigned char bitsinbyte[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, + 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, + 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, + 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, + 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, + 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, + 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}; /* Count initial bytes not aligned to 32 bit. */ - while((unsigned long)p & 3 && count) { + while ((unsigned long)p & 3 && count) { bits += bitsinbyte[*p++]; count--; } /* Count bits 28 bytes at a time */ - p4 = (uint32_t*)p; - while(count>=28) { + p4 = (uint32_t *)p; + while (count >= 28) { uint32_t aux1, aux2, aux3, aux4, aux5, aux6, aux7; aux1 = *p4++; @@ -77,17 +84,18 @@ long long serverPopcount(void *s, long count) { aux6 = (aux6 & 0x33333333) + ((aux6 >> 2) & 0x33333333); aux7 = aux7 - ((aux7 >> 1) & 0x55555555); aux7 = (aux7 & 0x33333333) + ((aux7 >> 2) & 0x33333333); - bits += ((((aux1 + (aux1 >> 4)) & 0x0F0F0F0F) + - ((aux2 + (aux2 >> 4)) & 0x0F0F0F0F) + - ((aux3 + (aux3 >> 4)) & 0x0F0F0F0F) + - ((aux4 + (aux4 >> 4)) & 0x0F0F0F0F) + - ((aux5 + (aux5 >> 4)) & 0x0F0F0F0F) + - ((aux6 + (aux6 >> 4)) & 0x0F0F0F0F) + - ((aux7 + (aux7 >> 4)) & 0x0F0F0F0F))* 0x01010101) >> 24; + bits += ((((aux1 + (aux1 >> 4)) & 0x0F0F0F0F) + ((aux2 + (aux2 >> 4)) & 0x0F0F0F0F) + + ((aux3 + (aux3 >> 4)) & 0x0F0F0F0F) + ((aux4 + (aux4 >> 4)) & 0x0F0F0F0F) + + ((aux5 + (aux5 >> 4)) & 0x0F0F0F0F) + ((aux6 + (aux6 >> 4)) & 0x0F0F0F0F) + + ((aux7 + (aux7 >> 4)) & 0x0F0F0F0F)) * + 0x01010101) >> + 24; } /* Count the remaining bytes. */ - p = (unsigned char*)p4; - while(count--) bits += bitsinbyte[*p++]; + p = (unsigned char *)p4; + while (count--) { + bits += bitsinbyte[*p++]; + } return bits; } @@ -117,9 +125,9 @@ long long serverBitpos(void *s, unsigned long count, int bit) { /* Skip initial bits not aligned to sizeof(unsigned long) byte by byte. */ skipval = bit ? 0 : UCHAR_MAX; - c = (unsigned char*) s; + c = (unsigned char *)s; found = 0; - while((unsigned long)c & (sizeof(*l)-1) && count) { + while ((unsigned long)c & (sizeof(*l) - 1) && count) { if (*c != skipval) { found = 1; break; @@ -130,14 +138,16 @@ long long serverBitpos(void *s, unsigned long count, int bit) { } /* Skip bits with full word step. */ - l = (unsigned long*) c; + l = (unsigned long *)c; if (!found) { skipval = bit ? 0 : ULONG_MAX; while (count >= sizeof(*l)) { - if (*l != skipval) break; + if (*l != skipval) { + break; + } l++; count -= sizeof(*l); - pos += sizeof(*l)*8; + pos += sizeof(*l) * 8; } } @@ -148,7 +158,7 @@ long long serverBitpos(void *s, unsigned long count, int bit) { * * Note that the loading is designed to work even when the bytes left * (count) are less than a full word. We pad it with zero on the right. */ - c = (unsigned char*)l; + c = (unsigned char *)l; for (j = 0; j < sizeof(*l); j++) { word <<= 8; if (count) { @@ -163,7 +173,9 @@ long long serverBitpos(void *s, unsigned long count, int bit) { * return -1 to signal that there is not a single "1" in the whole * string. This can't happen when we are looking for "0" as we assume * that the right of the string is zero padded. */ - if (bit == 1 && word == 0) return -1; + if (bit == 1 && word == 0) { + return -1; + } /* Last word left, scan bit by bit. The first thing we need is to * have a single "1" set in the most significant position in an @@ -173,8 +185,10 @@ long long serverBitpos(void *s, unsigned long count, int bit) { one >>= 1; /* All bits set to 1 but the MSB. */ one = ~one; /* All bits set to 0 but the MSB. */ - while(one) { - if (((one & word) != 0) == bit) return pos; + while (one) { + if (((one & word) != 0) == bit) { + return pos; + } pos++; one >>= 1; } @@ -210,7 +224,7 @@ void setUnsignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits, uint6 uint64_t byte, bit, byteval, bitval, j; for (j = 0; j < bits; j++) { - bitval = (value & ((uint64_t)1<<(bits-1-j))) != 0; + bitval = (value & ((uint64_t)1 << (bits - 1 - j))) != 0; byte = offset >> 3; bit = 7 - (offset & 0x7); byteval = p[byte]; @@ -223,7 +237,7 @@ void setUnsignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits, uint6 void setSignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits, int64_t value) { uint64_t uv = value; /* Casting will add UINT64_MAX + 1 if v is negative. */ - setUnsignedBitfield(p,offset,bits,uv); + setUnsignedBitfield(p, offset, bits, uv); } uint64_t getUnsignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits) { @@ -234,7 +248,7 @@ uint64_t getUnsignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits) { bit = 7 - (offset & 0x7); byteval = p[byte]; bitval = (byteval >> bit) & 1; - value = (value<<1) | bitval; + value = (value << 1) | bitval; offset++; } return value; @@ -242,7 +256,10 @@ uint64_t getUnsignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits) { int64_t getSignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits) { int64_t value; - union {uint64_t u; int64_t i;} conv; + union { + uint64_t u; + int64_t i; + } conv; /* Converting from unsigned to signed is undefined when the value does * not fit, however here we assume two's complement and the original value @@ -251,14 +268,15 @@ int64_t getSignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits) { * * Note that two's complement is mandatory for exact-width types * according to the C99 standard. */ - conv.u = getUnsignedBitfield(p,offset,bits); + conv.u = getUnsignedBitfield(p, offset, bits); value = conv.i; /* If the top significant bit is 1, propagate it to all the * higher bits for two's complement representation of signed * integers. */ - if (bits < 64 && (value & ((uint64_t)1 << (bits-1)))) + if (bits < 64 && (value & ((uint64_t)1 << (bits - 1)))) { value |= ((uint64_t)-1) << bits; + } return value; } @@ -286,8 +304,8 @@ int64_t getSignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits) { #define BFOVERFLOW_FAIL 2 /* Used by the BITFIELD command implementation. */ int checkUnsignedBitfieldOverflow(uint64_t value, int64_t incr, uint64_t bits, int owtype, uint64_t *limit) { - uint64_t max = (bits == 64) ? UINT64_MAX : (((uint64_t)1< max || (incr > 0 && incr > maxincr)) { @@ -311,30 +329,28 @@ int checkUnsignedBitfieldOverflow(uint64_t value, int64_t incr, uint64_t bits, i } return 0; -handle_wrap: - { - uint64_t mask = ((uint64_t)-1) << bits; - uint64_t res = value+incr; +handle_wrap: { + uint64_t mask = ((uint64_t)-1) << bits; + uint64_t res = value + incr; - res &= ~mask; - *limit = res; - } + res &= ~mask; + *limit = res; +} return 1; } int checkSignedBitfieldOverflow(int64_t value, int64_t incr, uint64_t bits, int owtype, int64_t *limit) { - int64_t max = (bits == 64) ? INT64_MAX : (((int64_t)1<<(bits-1))-1); - int64_t min = (-max)-1; + int64_t max = (bits == 64) ? INT64_MAX : (((int64_t)1 << (bits - 1)) - 1); + int64_t min = (-max) - 1; /* Note that maxincr and minincr could overflow, but we use the values * only after checking 'value' range, so when we use it no overflow * happens. 'uint64_t' cast is there just to prevent undefined behavior on * overflow */ - int64_t maxincr = (uint64_t)max-value; - int64_t minincr = min-value; + int64_t maxincr = (uint64_t)max - value; + int64_t minincr = min - value; - if (value > max || (bits != 64 && incr > maxincr) || (value >= 0 && incr > 0 && incr > maxincr)) - { + if (value > max || (bits != 64 && incr > maxincr) || (value >= 0 && incr > 0 && incr > maxincr)) { if (limit) { if (owtype == BFOVERFLOW_WRAP) { goto handle_wrap; @@ -355,25 +371,24 @@ int checkSignedBitfieldOverflow(int64_t value, int64_t incr, uint64_t bits, int } return 0; -handle_wrap: - { - uint64_t msb = (uint64_t)1 << (bits-1); - uint64_t a = value, b = incr, c; - c = a+b; /* Perform addition as unsigned so that's defined. */ - - /* If the sign bit is set, propagate to all the higher order - * bits, to cap the negative value. If it's clear, mask to - * the positive integer limit. */ - if (bits < 64) { - uint64_t mask = ((uint64_t)-1) << bits; - if (c & msb) { - c |= mask; - } else { - c &= ~mask; - } +handle_wrap: { + uint64_t msb = (uint64_t)1 << (bits - 1); + uint64_t a = value, b = incr, c; + c = a + b; /* Perform addition as unsigned so that's defined. */ + + /* If the sign bit is set, propagate to all the higher order + * bits, to cap the negative value. If it's clear, mask to + * the positive integer limit. */ + if (bits < 64) { + uint64_t mask = ((uint64_t)-1) << bits; + if (c & msb) { + c |= mask; + } else { + c &= ~mask; } - *limit = c; } + *limit = c; +} return 1; } @@ -384,8 +399,9 @@ void printBits(unsigned char *p, unsigned long count) { for (j = 0; j < count; j++) { byte = p[j]; - for (i = 0x80; i > 0; i /= 2) + for (i = 0x80; i > 0; i /= 2) { printf("%c", (byte & i) ? '1' : '0'); + } printf("|"); } printf("\n"); @@ -395,10 +411,10 @@ void printBits(unsigned char *p, unsigned long count) { * Bits related string commands: GETBIT, SETBIT, BITCOUNT, BITOP. * -------------------------------------------------------------------------- */ -#define BITOP_AND 0 -#define BITOP_OR 1 -#define BITOP_XOR 2 -#define BITOP_NOT 3 +#define BITOP_AND 0 +#define BITOP_OR 1 +#define BITOP_XOR 2 +#define BITOP_NOT 3 #define BITFIELDOP_GET 0 #define BITFIELDOP_SET 1 @@ -419,20 +435,23 @@ int getBitOffsetFromArgument(client *c, robj *o, uint64_t *offset, int hash, int int usehash = 0; /* Handle # form. */ - if (p[0] == '#' && hash && bits > 0) usehash = 1; + if (p[0] == '#' && hash && bits > 0) { + usehash = 1; + } - if (string2ll(p+usehash,plen-usehash,&loffset) == 0) { - addReplyError(c,err); + if (string2ll(p + usehash, plen - usehash, &loffset) == 0) { + addReplyError(c, err); return C_ERR; } /* Adjust the offset by 'bits' for # form. */ - if (usehash) loffset *= bits; + if (usehash) { + loffset *= bits; + } /* Limit offset to server.proto_max_bulk_len (512MB in bytes by default) */ - if (loffset < 0 || (!mustObeyClient(c) && (loffset >> 3) >= server.proto_max_bulk_len)) - { - addReplyError(c,err); + if (loffset < 0 || (!mustObeyClient(c) && (loffset >> 3) >= server.proto_max_bulk_len)) { + addReplyError(c, err); return C_ERR; } @@ -457,16 +476,13 @@ int getBitfieldTypeFromArgument(client *c, robj *o, int *sign, int *bits) { } else if (p[0] == 'u') { *sign = 0; } else { - addReplyError(c,err); + addReplyError(c, err); return C_ERR; } - if ((string2ll(p+1,strlen(p+1),&llbits)) == 0 || - llbits < 1 || - (*sign == 1 && llbits > 64) || - (*sign == 0 && llbits > 63)) - { - addReplyError(c,err); + if ((string2ll(p + 1, strlen(p + 1), &llbits)) == 0 || llbits < 1 || (*sign == 1 && llbits > 64) || + (*sign == 0 && llbits > 63)) { + addReplyError(c, err); return C_ERR; } *bits = llbits; @@ -480,19 +496,27 @@ int getBitfieldTypeFromArgument(client *c, robj *o, int *sign, int *bits) { * an error is sent to the client. */ robj *lookupStringForBitCommand(client *c, uint64_t maxbit, int *dirty) { size_t byte = maxbit >> 3; - robj *o = lookupKeyWrite(c->db,c->argv[1]); - if (checkType(c,o,OBJ_STRING)) return NULL; - if (dirty) *dirty = 0; + robj *o = lookupKeyWrite(c->db, c->argv[1]); + if (checkType(c, o, OBJ_STRING)) { + return NULL; + } + if (dirty) { + *dirty = 0; + } if (o == NULL) { - o = createObject(OBJ_STRING,sdsnewlen(NULL, byte+1)); - dbAdd(c->db,c->argv[1],o); - if (dirty) *dirty = 1; + o = createObject(OBJ_STRING, sdsnewlen(NULL, byte + 1)); + dbAdd(c->db, c->argv[1], o); + if (dirty) { + *dirty = 1; + } } else { - o = dbUnshareStringValue(c->db,c->argv[1],o); + o = dbUnshareStringValue(c->db, c->argv[1], o); size_t oldlen = sdslen(o->ptr); - o->ptr = sdsgrowzero(o->ptr,byte+1); - if (dirty && oldlen != sdslen(o->ptr)) *dirty = 1; + o->ptr = sdsgrowzero(o->ptr, byte + 1); + if (dirty && oldlen != sdslen(o->ptr)) { + *dirty = 1; + } } return o; } @@ -517,13 +541,19 @@ unsigned char *getObjectReadOnlyString(robj *o, long *len, char *llbuf) { /* Set the 'p' pointer to the string, that can be just a stack allocated * array if our string was integer encoded. */ if (o && o->encoding == OBJ_ENCODING_INT) { - p = (unsigned char*) llbuf; - if (len) *len = ll2string(llbuf,LONG_STR_SIZE,(long)o->ptr); + p = (unsigned char *)llbuf; + if (len) { + *len = ll2string(llbuf, LONG_STR_SIZE, (long)o->ptr); + } } else if (o) { - p = (unsigned char*) o->ptr; - if (len) *len = sdslen(o->ptr); + p = (unsigned char *)o->ptr; + if (len) { + *len = sdslen(o->ptr); + } } else { - if (len) *len = 0; + if (len) { + *len = 0; + } } return p; } @@ -537,24 +567,28 @@ void setbitCommand(client *c) { int byteval, bitval; long on; - if (getBitOffsetFromArgument(c,c->argv[2],&bitoffset,0,0) != C_OK) + if (getBitOffsetFromArgument(c, c->argv[2], &bitoffset, 0, 0) != C_OK) { return; + } - if (getLongFromObjectOrReply(c,c->argv[3],&on,err) != C_OK) + if (getLongFromObjectOrReply(c, c->argv[3], &on, err) != C_OK) { return; + } /* Bits can only be set or cleared... */ if (on & ~1) { - addReplyError(c,err); + addReplyError(c, err); return; } int dirty; - if ((o = lookupStringForBitCommand(c,bitoffset,&dirty)) == NULL) return; + if ((o = lookupStringForBitCommand(c, bitoffset, &dirty)) == NULL) { + return; + } /* Get current values */ byte = bitoffset >> 3; - byteval = ((uint8_t*)o->ptr)[byte]; + byteval = ((uint8_t *)o->ptr)[byte]; bit = 7 - (bitoffset & 0x7); bitval = byteval & (1 << bit); @@ -565,9 +599,9 @@ void setbitCommand(client *c) { /* Update byte with new bit value. */ byteval &= ~(1 << bit); byteval |= ((on & 0x1) << bit); - ((uint8_t*)o->ptr)[byte] = byteval; - signalModifiedKey(c,c->db,c->argv[1]); - notifyKeyspaceEvent(NOTIFY_STRING,"setbit",c->argv[1],c->db->id); + ((uint8_t *)o->ptr)[byte] = byteval; + signalModifiedKey(c, c->db, c->argv[1]); + notifyKeyspaceEvent(NOTIFY_STRING, "setbit", c->argv[1], c->db->id); server.dirty++; } @@ -583,20 +617,24 @@ void getbitCommand(client *c) { size_t byte, bit; size_t bitval = 0; - if (getBitOffsetFromArgument(c,c->argv[2],&bitoffset,0,0) != C_OK) + if (getBitOffsetFromArgument(c, c->argv[2], &bitoffset, 0, 0) != C_OK) { return; + } - if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL || - checkType(c,o,OBJ_STRING)) return; + if ((o = lookupKeyReadOrReply(c, c->argv[1], shared.czero)) == NULL || checkType(c, o, OBJ_STRING)) { + return; + } byte = bitoffset >> 3; bit = 7 - (bitoffset & 0x7); if (sdsEncodedObject(o)) { - if (byte < sdslen(o->ptr)) - bitval = ((uint8_t*)o->ptr)[byte] & (1 << bit); + if (byte < sdslen(o->ptr)) { + bitval = ((uint8_t *)o->ptr)[byte] & (1 << bit); + } } else { - if (byte < (size_t)ll2string(llbuf,sizeof(llbuf),(long)o->ptr)) + if (byte < (size_t)ll2string(llbuf, sizeof(llbuf), (long)o->ptr)) { bitval = llbuf[byte] & (1 << bit); + } } addReply(c, bitval ? shared.cone : shared.czero); @@ -608,40 +646,40 @@ void bitopCommand(client *c) { char *opname = c->argv[1]->ptr; robj *o, *targetkey = c->argv[2]; unsigned long op, j, numkeys; - robj **objects; /* Array of source objects. */ - unsigned char **src; /* Array of source strings pointers. */ + robj **objects; /* Array of source objects. */ + unsigned char **src; /* Array of source strings pointers. */ unsigned long *len, maxlen = 0; /* Array of length of src strings, and max len. */ - unsigned long minlen = 0; /* Min len among the input keys. */ - unsigned char *res = NULL; /* Resulting string. */ + unsigned long minlen = 0; /* Min len among the input keys. */ + unsigned char *res = NULL; /* Resulting string. */ /* Parse the operation name. */ - if ((opname[0] == 'a' || opname[0] == 'A') && !strcasecmp(opname,"and")) + if ((opname[0] == 'a' || opname[0] == 'A') && !strcasecmp(opname, "and")) { op = BITOP_AND; - else if((opname[0] == 'o' || opname[0] == 'O') && !strcasecmp(opname,"or")) + } else if ((opname[0] == 'o' || opname[0] == 'O') && !strcasecmp(opname, "or")) { op = BITOP_OR; - else if((opname[0] == 'x' || opname[0] == 'X') && !strcasecmp(opname,"xor")) + } else if ((opname[0] == 'x' || opname[0] == 'X') && !strcasecmp(opname, "xor")) { op = BITOP_XOR; - else if((opname[0] == 'n' || opname[0] == 'N') && !strcasecmp(opname,"not")) + } else if ((opname[0] == 'n' || opname[0] == 'N') && !strcasecmp(opname, "not")) { op = BITOP_NOT; - else { - addReplyErrorObject(c,shared.syntaxerr); + } else { + addReplyErrorObject(c, shared.syntaxerr); return; } /* Sanity check: NOT accepts only a single key argument. */ if (op == BITOP_NOT && c->argc != 4) { - addReplyError(c,"BITOP NOT must be called with a single source key."); + addReplyError(c, "BITOP NOT must be called with a single source key."); return; } /* Lookup keys, and store pointers to the string objects into an array. */ numkeys = c->argc - 3; - src = zmalloc(sizeof(unsigned char*) * numkeys); + src = zmalloc(sizeof(unsigned char *) * numkeys); len = zmalloc(sizeof(long) * numkeys); - objects = zmalloc(sizeof(robj*) * numkeys); + objects = zmalloc(sizeof(robj *) * numkeys); for (j = 0; j < numkeys; j++) { - o = lookupKeyRead(c->db,c->argv[j+3]); + o = lookupKeyRead(c->db, c->argv[j + 3]); /* Handle non-existing keys as empty strings. */ if (o == NULL) { objects[j] = NULL; @@ -651,11 +689,12 @@ void bitopCommand(client *c) { continue; } /* Return an error if one of the keys is not a string. */ - if (checkType(c,o,OBJ_STRING)) { + if (checkType(c, o, OBJ_STRING)) { unsigned long i; for (i = 0; i < j; i++) { - if (objects[i]) + if (objects[i]) { decrRefCount(objects[i]); + } } zfree(src); zfree(len); @@ -665,13 +704,17 @@ void bitopCommand(client *c) { objects[j] = getDecodedObject(o); src[j] = objects[j]->ptr; len[j] = sdslen(objects[j]->ptr); - if (len[j] > maxlen) maxlen = len[j]; - if (j == 0 || len[j] < minlen) minlen = len[j]; + if (len[j] > maxlen) { + maxlen = len[j]; + } + if (j == 0 || len[j] < minlen) { + minlen = len[j]; + } } /* Compute the bit operation, if at least one string is not empty. */ if (maxlen) { - res = (unsigned char*) sdsnewlen(NULL,maxlen); + res = (unsigned char *)sdsnewlen(NULL, maxlen); unsigned char output, byte; unsigned long i; @@ -681,76 +724,78 @@ void bitopCommand(client *c) { * result in GCC compiling the code using multiple-words load/store * operations that are not supported even in ARM >= v6. */ j = 0; - #ifndef USE_ALIGNED_ACCESS - if (minlen >= sizeof(unsigned long)*4 && numkeys <= 16) { +#ifndef USE_ALIGNED_ACCESS + if (minlen >= sizeof(unsigned long) * 4 && numkeys <= 16) { unsigned long *lp[16]; - unsigned long *lres = (unsigned long*) res; + unsigned long *lres = (unsigned long *)res; - memcpy(lp,src,sizeof(unsigned long*)*numkeys); - memcpy(res,src[0],minlen); + memcpy(lp, src, sizeof(unsigned long *) * numkeys); + memcpy(res, src[0], minlen); /* Different branches per different operations for speed (sorry). */ if (op == BITOP_AND) { - while(minlen >= sizeof(unsigned long)*4) { + while (minlen >= sizeof(unsigned long) * 4) { for (i = 1; i < numkeys; i++) { lres[0] &= lp[i][0]; lres[1] &= lp[i][1]; lres[2] &= lp[i][2]; lres[3] &= lp[i][3]; - lp[i]+=4; + lp[i] += 4; } - lres+=4; - j += sizeof(unsigned long)*4; - minlen -= sizeof(unsigned long)*4; + lres += 4; + j += sizeof(unsigned long) * 4; + minlen -= sizeof(unsigned long) * 4; } } else if (op == BITOP_OR) { - while(minlen >= sizeof(unsigned long)*4) { + while (minlen >= sizeof(unsigned long) * 4) { for (i = 1; i < numkeys; i++) { lres[0] |= lp[i][0]; lres[1] |= lp[i][1]; lres[2] |= lp[i][2]; lres[3] |= lp[i][3]; - lp[i]+=4; + lp[i] += 4; } - lres+=4; - j += sizeof(unsigned long)*4; - minlen -= sizeof(unsigned long)*4; + lres += 4; + j += sizeof(unsigned long) * 4; + minlen -= sizeof(unsigned long) * 4; } } else if (op == BITOP_XOR) { - while(minlen >= sizeof(unsigned long)*4) { + while (minlen >= sizeof(unsigned long) * 4) { for (i = 1; i < numkeys; i++) { lres[0] ^= lp[i][0]; lres[1] ^= lp[i][1]; lres[2] ^= lp[i][2]; lres[3] ^= lp[i][3]; - lp[i]+=4; + lp[i] += 4; } - lres+=4; - j += sizeof(unsigned long)*4; - minlen -= sizeof(unsigned long)*4; + lres += 4; + j += sizeof(unsigned long) * 4; + minlen -= sizeof(unsigned long) * 4; } } else if (op == BITOP_NOT) { - while(minlen >= sizeof(unsigned long)*4) { + while (minlen >= sizeof(unsigned long) * 4) { lres[0] = ~lres[0]; lres[1] = ~lres[1]; lres[2] = ~lres[2]; lres[3] = ~lres[3]; - lres+=4; - j += sizeof(unsigned long)*4; - minlen -= sizeof(unsigned long)*4; + lres += 4; + j += sizeof(unsigned long) * 4; + minlen -= sizeof(unsigned long) * 4; } } } - #endif +#endif /* j is set to the next byte to process by the previous loop. */ for (; j < maxlen; j++) { output = (len[0] <= j) ? 0 : src[0][j]; - if (op == BITOP_NOT) output = ~output; + if (op == BITOP_NOT) { + output = ~output; + } for (i = 1; i < numkeys; i++) { int skip = 0; byte = (len[i] <= j) ? 0 : src[i][j]; - switch(op) { + switch (op) { case BITOP_AND: output &= byte; skip = (output == 0); @@ -759,7 +804,9 @@ void bitopCommand(client *c) { output |= byte; skip = (output == 0xff); break; - case BITOP_XOR: output ^= byte; break; + case BITOP_XOR: + output ^= byte; + break; } if (skip) { @@ -770,8 +817,9 @@ void bitopCommand(client *c) { } } for (j = 0; j < numkeys; j++) { - if (objects[j]) + if (objects[j]) { decrRefCount(objects[j]); + } } zfree(src); zfree(len); @@ -779,17 +827,17 @@ void bitopCommand(client *c) { /* Store the computed value into the target key */ if (maxlen) { - o = createObject(OBJ_STRING,res); - setKey(c,c->db,targetkey,o,0); - notifyKeyspaceEvent(NOTIFY_STRING,"set",targetkey,c->db->id); + o = createObject(OBJ_STRING, res); + setKey(c, c->db, targetkey, o, 0); + notifyKeyspaceEvent(NOTIFY_STRING, "set", targetkey, c->db->id); decrRefCount(o); server.dirty++; - } else if (dbDelete(c->db,targetkey)) { - signalModifiedKey(c,c->db,targetkey); - notifyKeyspaceEvent(NOTIFY_GENERIC,"del",targetkey,c->db->id); + } else if (dbDelete(c->db, targetkey)) { + signalModifiedKey(c, c->db, targetkey); + notifyKeyspaceEvent(NOTIFY_GENERIC, "del", targetkey, c->db->id); server.dirty++; } - addReplyLongLong(c,maxlen); /* Return the output string length in bytes. */ + addReplyLongLong(c, maxlen); /* Return the output string length in bytes. */ } /* BITCOUNT key [start end [BIT|BYTE]] */ @@ -804,22 +852,28 @@ void bitcountCommand(client *c) { /* Parse start/end range if any. */ if (c->argc == 4 || c->argc == 5) { - if (getLongLongFromObjectOrReply(c,c->argv[2],&start,NULL) != C_OK) + if (getLongLongFromObjectOrReply(c, c->argv[2], &start, NULL) != C_OK) { return; - if (getLongLongFromObjectOrReply(c,c->argv[3],&end,NULL) != C_OK) + } + if (getLongLongFromObjectOrReply(c, c->argv[3], &end, NULL) != C_OK) { return; + } if (c->argc == 5) { - if (!strcasecmp(c->argv[4]->ptr,"bit")) isbit = 1; - else if (!strcasecmp(c->argv[4]->ptr,"byte")) isbit = 0; - else { - addReplyErrorObject(c,shared.syntaxerr); + if (!strcasecmp(c->argv[4]->ptr, "bit")) { + isbit = 1; + } else if (!strcasecmp(c->argv[4]->ptr, "byte")) { + isbit = 0; + } else { + addReplyErrorObject(c, shared.syntaxerr); return; } } /* Lookup, check for type. */ o = lookupKeyRead(c->db, c->argv[1]); - if (checkType(c, o, OBJ_STRING)) return; - p = getObjectReadOnlyString(o,&strlen,llbuf); + if (checkType(c, o, OBJ_STRING)) { + return; + } + p = getObjectReadOnlyString(o, &strlen, llbuf); long long totlen = strlen; /* Make sure we will not overflow */ @@ -827,34 +881,48 @@ void bitcountCommand(client *c) { /* Convert negative indexes */ if (start < 0 && end < 0 && start > end) { - addReply(c,shared.czero); + addReply(c, shared.czero); return; } - if (isbit) totlen <<= 3; - if (start < 0) start = totlen+start; - if (end < 0) end = totlen+end; - if (start < 0) start = 0; - if (end < 0) end = 0; - if (end >= totlen) end = totlen-1; + if (isbit) { + totlen <<= 3; + } + if (start < 0) { + start = totlen + start; + } + if (end < 0) { + end = totlen + end; + } + if (start < 0) { + start = 0; + } + if (end < 0) { + end = 0; + } + if (end >= totlen) { + end = totlen - 1; + } if (isbit && start <= end) { /* Before converting bit offset to byte offset, create negative masks * for the edges. */ - first_byte_neg_mask = ~((1<<(8-(start&7)))-1) & 0xFF; - last_byte_neg_mask = (1<<(7-(end&7)))-1; + first_byte_neg_mask = ~((1 << (8 - (start & 7))) - 1) & 0xFF; + last_byte_neg_mask = (1 << (7 - (end & 7))) - 1; start >>= 3; end >>= 3; } } else if (c->argc == 2) { /* Lookup, check for type. */ o = lookupKeyRead(c->db, c->argv[1]); - if (checkType(c, o, OBJ_STRING)) return; - p = getObjectReadOnlyString(o,&strlen,llbuf); + if (checkType(c, o, OBJ_STRING)) { + return; + } + p = getObjectReadOnlyString(o, &strlen, llbuf); /* The whole string. */ start = 0; - end = strlen-1; + end = strlen - 1; } else { /* Syntax error. */ - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } @@ -867,20 +935,24 @@ void bitcountCommand(client *c) { /* Precondition: end >= 0 && end < strlen, so the only condition where * zero can be returned is: start > end. */ if (start > end) { - addReply(c,shared.czero); + addReply(c, shared.czero); } else { - long bytes = (long)(end-start+1); - long long count = serverPopcount(p+start,bytes); + long bytes = (long)(end - start + 1); + long long count = serverPopcount(p + start, bytes); if (first_byte_neg_mask != 0 || last_byte_neg_mask != 0) { unsigned char firstlast[2] = {0, 0}; /* We may count bits of first byte and last byte which are out of - * range. So we need to subtract them. Here we use a trick. We set - * bits in the range to zero. So these bit will not be excluded. */ - if (first_byte_neg_mask != 0) firstlast[0] = p[start] & first_byte_neg_mask; - if (last_byte_neg_mask != 0) firstlast[1] = p[end] & last_byte_neg_mask; - count -= serverPopcount(firstlast,2); + * range. So we need to subtract them. Here we use a trick. We set + * bits in the range to zero. So these bit will not be excluded. */ + if (first_byte_neg_mask != 0) { + firstlast[0] = p[start] & first_byte_neg_mask; + } + if (last_byte_neg_mask != 0) { + firstlast[1] = p[end] & last_byte_neg_mask; + } + count -= serverPopcount(firstlast, 2); } - addReplyLongLong(c,count); + addReplyLongLong(c, count); } } @@ -896,8 +968,9 @@ void bitposCommand(client *c) { /* Parse the bit argument to understand what we are looking for, set * or clear bits. */ - if (getLongFromObjectOrReply(c,c->argv[2],&bit,NULL) != C_OK) + if (getLongFromObjectOrReply(c, c->argv[2], &bit, NULL) != C_OK) { return; + } if (bit != 0 && bit != 1) { addReplyError(c, "The bit argument must be 1 or 0."); return; @@ -905,25 +978,31 @@ void bitposCommand(client *c) { /* Parse start/end range if any. */ if (c->argc == 4 || c->argc == 5 || c->argc == 6) { - if (getLongLongFromObjectOrReply(c,c->argv[3],&start,NULL) != C_OK) + if (getLongLongFromObjectOrReply(c, c->argv[3], &start, NULL) != C_OK) { return; + } if (c->argc == 6) { - if (!strcasecmp(c->argv[5]->ptr,"bit")) isbit = 1; - else if (!strcasecmp(c->argv[5]->ptr,"byte")) isbit = 0; - else { - addReplyErrorObject(c,shared.syntaxerr); + if (!strcasecmp(c->argv[5]->ptr, "bit")) { + isbit = 1; + } else if (!strcasecmp(c->argv[5]->ptr, "byte")) { + isbit = 0; + } else { + addReplyErrorObject(c, shared.syntaxerr); return; } } if (c->argc >= 5) { - if (getLongLongFromObjectOrReply(c,c->argv[4],&end,NULL) != C_OK) + if (getLongLongFromObjectOrReply(c, c->argv[4], &end, NULL) != C_OK) { return; + } end_given = 1; } /* Lookup, check for type. */ o = lookupKeyRead(c->db, c->argv[1]); - if (checkType(c, o, OBJ_STRING)) return; + if (checkType(c, o, OBJ_STRING)) { + return; + } p = getObjectReadOnlyString(o, &strlen, llbuf); /* Make sure we will not overflow */ @@ -931,37 +1010,54 @@ void bitposCommand(client *c) { serverAssert(totlen <= LLONG_MAX >> 3); if (c->argc < 5) { - if (isbit) end = (totlen<<3) + 7; - else end = totlen-1; + if (isbit) { + end = (totlen << 3) + 7; + } else { + end = totlen - 1; + } } - if (isbit) totlen <<= 3; + if (isbit) { + totlen <<= 3; + } /* Convert negative indexes */ - if (start < 0) start = totlen+start; - if (end < 0) end = totlen+end; - if (start < 0) start = 0; - if (end < 0) end = 0; - if (end >= totlen) end = totlen-1; + if (start < 0) { + start = totlen + start; + } + if (end < 0) { + end = totlen + end; + } + if (start < 0) { + start = 0; + } + if (end < 0) { + end = 0; + } + if (end >= totlen) { + end = totlen - 1; + } if (isbit && start <= end) { /* Before converting bit offset to byte offset, create negative masks * for the edges. */ - first_byte_neg_mask = ~((1<<(8-(start&7)))-1) & 0xFF; - last_byte_neg_mask = (1<<(7-(end&7)))-1; + first_byte_neg_mask = ~((1 << (8 - (start & 7))) - 1) & 0xFF; + last_byte_neg_mask = (1 << (7 - (end & 7))) - 1; start >>= 3; end >>= 3; } } else if (c->argc == 3) { /* Lookup, check for type. */ o = lookupKeyRead(c->db, c->argv[1]); - if (checkType(c,o,OBJ_STRING)) return; - p = getObjectReadOnlyString(o,&strlen,llbuf); + if (checkType(c, o, OBJ_STRING)) { + return; + } + p = getObjectReadOnlyString(o, &strlen, llbuf); /* The whole string. */ start = 0; - end = strlen-1; + end = strlen - 1; } else { /* Syntax error. */ - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } @@ -978,35 +1074,48 @@ void bitposCommand(client *c) { if (start > end) { addReplyLongLong(c, -1); } else { - long bytes = end-start+1; + long bytes = end - start + 1; long long pos; unsigned char tmpchar; if (first_byte_neg_mask) { - if (bit) tmpchar = p[start] & ~first_byte_neg_mask; - else tmpchar = p[start] | first_byte_neg_mask; + if (bit) { + tmpchar = p[start] & ~first_byte_neg_mask; + } else { + tmpchar = p[start] | first_byte_neg_mask; + } /* Special case, there is only one byte */ if (last_byte_neg_mask && bytes == 1) { - if (bit) tmpchar = tmpchar & ~last_byte_neg_mask; - else tmpchar = tmpchar | last_byte_neg_mask; + if (bit) { + tmpchar = tmpchar & ~last_byte_neg_mask; + } else { + tmpchar = tmpchar | last_byte_neg_mask; + } } - pos = serverBitpos(&tmpchar,1,bit); + pos = serverBitpos(&tmpchar, 1, bit); /* If there are no more bytes or we get valid pos, we can exit early */ - if (bytes == 1 || (pos != -1 && pos != 8)) goto result; + if (bytes == 1 || (pos != -1 && pos != 8)) { + goto result; + } start++; bytes--; } /* If the last byte has not bits in the range, we should exclude it */ long curbytes = bytes - (last_byte_neg_mask ? 1 : 0); if (curbytes > 0) { - pos = serverBitpos(p+start,curbytes,bit); + pos = serverBitpos(p + start, curbytes, bit); /* If there is no more bytes or we get valid pos, we can exit early */ - if (bytes == curbytes || (pos != -1 && pos != (long long)curbytes<<3)) goto result; + if (bytes == curbytes || (pos != -1 && pos != (long long)curbytes << 3)) { + goto result; + } start += curbytes; bytes -= curbytes; } - if (bit) tmpchar = p[end] & ~last_byte_neg_mask; - else tmpchar = p[end] | last_byte_neg_mask; - pos = serverBitpos(&tmpchar,1,bit); + if (bit) { + tmpchar = p[end] & ~last_byte_neg_mask; + } else { + tmpchar = p[end] | last_byte_neg_mask; + } + pos = serverBitpos(&tmpchar, 1, bit); result: /* If we are looking for clear bits, and the user specified an exact @@ -1016,12 +1125,14 @@ void bitposCommand(client *c) { * So if serverBitpos() returns the first bit outside the range, * we return -1 to the caller, to mean, in the specified range there * is not a single "0" bit. */ - if (end_given && bit == 0 && pos == (long long)bytes<<3) { - addReplyLongLong(c,-1); + if (end_given && bit == 0 && pos == (long long)bytes << 3) { + addReplyLongLong(c, -1); return; } - if (pos != -1) pos += (long long)start<<3; /* Adjust for the bytes we skipped. */ - addReplyLongLong(c,pos); + if (pos != -1) { + pos += (long long)start << 3; /* Adjust for the bytes we skipped. */ + } + addReplyLongLong(c, pos); } } @@ -1035,16 +1146,16 @@ void bitposCommand(client *c) { * OVERFLOW [WRAP|SAT|FAIL] */ -#define BITFIELD_FLAG_NONE 0 -#define BITFIELD_FLAG_READONLY (1<<0) +#define BITFIELD_FLAG_NONE 0 +#define BITFIELD_FLAG_READONLY (1 << 0) struct bitfieldOp { - uint64_t offset; /* Bitfield offset. */ - int64_t i64; /* Increment amount (INCRBY) or SET value */ - int opcode; /* Operation id. */ - int owtype; /* Overflow type to use. */ - int bits; /* Integer bitfield bits width. */ - int sign; /* True if signed, otherwise unsigned op. */ + uint64_t offset; /* Bitfield offset. */ + int64_t i64; /* Increment amount (INCRBY) or SET value */ + int opcode; /* Operation id. */ + int owtype; /* Overflow type to use. */ + int bits; /* Integer bitfield bits width. */ + int sign; /* True if signed, otherwise unsigned op. */ }; /* This implements both the BITFIELD command and the BITFIELD_RO command @@ -1055,69 +1166,70 @@ void bitfieldGeneric(client *c, int flags) { uint64_t bitoffset; int j, numops = 0, changes = 0, dirty = 0; struct bitfieldOp *ops = NULL; /* Array of ops to execute at end. */ - int owtype = BFOVERFLOW_WRAP; /* Overflow type. */ + int owtype = BFOVERFLOW_WRAP; /* Overflow type. */ int readonly = 1; uint64_t highest_write_offset = 0; for (j = 2; j < c->argc; j++) { - int remargs = c->argc-j-1; /* Remaining args other than current. */ + int remargs = c->argc - j - 1; /* Remaining args other than current. */ char *subcmd = c->argv[j]->ptr; /* Current command name. */ - int opcode; /* Current operation code. */ - long long i64 = 0; /* Signed SET value. */ - int sign = 0; /* Signed or unsigned type? */ - int bits = 0; /* Bitfield width in bits. */ + int opcode; /* Current operation code. */ + long long i64 = 0; /* Signed SET value. */ + int sign = 0; /* Signed or unsigned type? */ + int bits = 0; /* Bitfield width in bits. */ - if (!strcasecmp(subcmd,"get") && remargs >= 2) + if (!strcasecmp(subcmd, "get") && remargs >= 2) { opcode = BITFIELDOP_GET; - else if (!strcasecmp(subcmd,"set") && remargs >= 3) + } else if (!strcasecmp(subcmd, "set") && remargs >= 3) { opcode = BITFIELDOP_SET; - else if (!strcasecmp(subcmd,"incrby") && remargs >= 3) + } else if (!strcasecmp(subcmd, "incrby") && remargs >= 3) { opcode = BITFIELDOP_INCRBY; - else if (!strcasecmp(subcmd,"overflow") && remargs >= 1) { - char *owtypename = c->argv[j+1]->ptr; + } else if (!strcasecmp(subcmd, "overflow") && remargs >= 1) { + char *owtypename = c->argv[j + 1]->ptr; j++; - if (!strcasecmp(owtypename,"wrap")) + if (!strcasecmp(owtypename, "wrap")) { owtype = BFOVERFLOW_WRAP; - else if (!strcasecmp(owtypename,"sat")) + } else if (!strcasecmp(owtypename, "sat")) { owtype = BFOVERFLOW_SAT; - else if (!strcasecmp(owtypename,"fail")) + } else if (!strcasecmp(owtypename, "fail")) { owtype = BFOVERFLOW_FAIL; - else { - addReplyError(c,"Invalid OVERFLOW type specified"); + } else { + addReplyError(c, "Invalid OVERFLOW type specified"); zfree(ops); return; } continue; } else { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); zfree(ops); return; } /* Get the type and offset arguments, common to all the ops. */ - if (getBitfieldTypeFromArgument(c,c->argv[j+1],&sign,&bits) != C_OK) { + if (getBitfieldTypeFromArgument(c, c->argv[j + 1], &sign, &bits) != C_OK) { zfree(ops); return; } - if (getBitOffsetFromArgument(c,c->argv[j+2],&bitoffset,1,bits) != C_OK){ + if (getBitOffsetFromArgument(c, c->argv[j + 2], &bitoffset, 1, bits) != C_OK) { zfree(ops); return; } if (opcode != BITFIELDOP_GET) { readonly = 0; - if (highest_write_offset < bitoffset + bits - 1) + if (highest_write_offset < bitoffset + bits - 1) { highest_write_offset = bitoffset + bits - 1; + } /* INCRBY and SET require another argument. */ - if (getLongLongFromObjectOrReply(c,c->argv[j+3],&i64,NULL) != C_OK){ + if (getLongLongFromObjectOrReply(c, c->argv[j + 3], &i64, NULL) != C_OK) { zfree(ops); return; } } /* Populate the array of operations we'll process. */ - ops = zrealloc(ops,sizeof(*ops)*(numops+1)); + ops = zrealloc(ops, sizeof(*ops) * (numops + 1)); ops[numops].offset = bitoffset; ops[numops].i64 = i64; ops[numops].opcode = opcode; @@ -1132,8 +1244,8 @@ void bitfieldGeneric(client *c, int flags) { if (readonly) { /* Lookup for read is ok if key doesn't exit, but errors * if it's not a string. */ - o = lookupKeyRead(c->db,c->argv[1]); - if (o != NULL && checkType(c,o,OBJ_STRING)) { + o = lookupKeyRead(c->db, c->argv[1]); + if (o != NULL && checkType(c, o, OBJ_STRING)) { zfree(ops); return; } @@ -1146,23 +1258,20 @@ void bitfieldGeneric(client *c, int flags) { /* Lookup by making room up to the farthest bit reached by * this operation. */ - if ((o = lookupStringForBitCommand(c, - highest_write_offset,&dirty)) == NULL) { + if ((o = lookupStringForBitCommand(c, highest_write_offset, &dirty)) == NULL) { zfree(ops); return; } } - addReplyArrayLen(c,numops); + addReplyArrayLen(c, numops); /* Actually process the operations. */ for (j = 0; j < numops; j++) { - struct bitfieldOp *thisop = ops+j; + struct bitfieldOp *thisop = ops + j; /* Execute the operation. */ - if (thisop->opcode == BITFIELDOP_SET || - thisop->opcode == BITFIELDOP_INCRBY) - { + if (thisop->opcode == BITFIELDOP_SET || thisop->opcode == BITFIELDOP_INCRBY) { /* SET and INCRBY: We handle both with the same code path * for simplicity. SET return value is the previous value so * we need fetch & store as well. */ @@ -1174,65 +1283,66 @@ void bitfieldGeneric(client *c, int flags) { int64_t oldval, newval, wrapped, retval; int overflow; - oldval = getSignedBitfield(o->ptr,thisop->offset, - thisop->bits); + oldval = getSignedBitfield(o->ptr, thisop->offset, thisop->bits); if (thisop->opcode == BITFIELDOP_INCRBY) { - overflow = checkSignedBitfieldOverflow(oldval, - thisop->i64,thisop->bits,thisop->owtype,&wrapped); + overflow = checkSignedBitfieldOverflow(oldval, thisop->i64, thisop->bits, thisop->owtype, &wrapped); newval = overflow ? wrapped : oldval + thisop->i64; retval = newval; } else { newval = thisop->i64; - overflow = checkSignedBitfieldOverflow(newval, - 0,thisop->bits,thisop->owtype,&wrapped); - if (overflow) newval = wrapped; + overflow = checkSignedBitfieldOverflow(newval, 0, thisop->bits, thisop->owtype, &wrapped); + if (overflow) { + newval = wrapped; + } retval = oldval; } /* On overflow of type is "FAIL", don't write and return * NULL to signal the condition. */ if (!(overflow && thisop->owtype == BFOVERFLOW_FAIL)) { - addReplyLongLong(c,retval); - setSignedBitfield(o->ptr,thisop->offset, - thisop->bits,newval); + addReplyLongLong(c, retval); + setSignedBitfield(o->ptr, thisop->offset, thisop->bits, newval); - if (dirty || (oldval != newval)) + if (dirty || (oldval != newval)) { changes++; + } } else { addReplyNull(c); } } else { /* Initialization of 'wrapped' is required to avoid - * false-positive warning "-Wmaybe-uninitialized" */ + * false-positive warning "-Wmaybe-uninitialized" */ uint64_t oldval, newval, retval, wrapped = 0; int overflow; - oldval = getUnsignedBitfield(o->ptr,thisop->offset, - thisop->bits); + oldval = getUnsignedBitfield(o->ptr, thisop->offset, thisop->bits); if (thisop->opcode == BITFIELDOP_INCRBY) { newval = oldval + thisop->i64; - overflow = checkUnsignedBitfieldOverflow(oldval, - thisop->i64,thisop->bits,thisop->owtype,&wrapped); - if (overflow) newval = wrapped; + overflow = + checkUnsignedBitfieldOverflow(oldval, thisop->i64, thisop->bits, thisop->owtype, &wrapped); + if (overflow) { + newval = wrapped; + } retval = newval; } else { newval = thisop->i64; - overflow = checkUnsignedBitfieldOverflow(newval, - 0,thisop->bits,thisop->owtype,&wrapped); - if (overflow) newval = wrapped; + overflow = checkUnsignedBitfieldOverflow(newval, 0, thisop->bits, thisop->owtype, &wrapped); + if (overflow) { + newval = wrapped; + } retval = oldval; } /* On overflow of type is "FAIL", don't write and return * NULL to signal the condition. */ if (!(overflow && thisop->owtype == BFOVERFLOW_FAIL)) { - addReplyLongLong(c,retval); - setUnsignedBitfield(o->ptr,thisop->offset, - thisop->bits,newval); + addReplyLongLong(c, retval); + setUnsignedBitfield(o->ptr, thisop->offset, thisop->bits, newval); - if (dirty || (oldval != newval)) + if (dirty || (oldval != newval)) { changes++; + } } else { addReplyNull(c); } @@ -1244,38 +1354,39 @@ void bitfieldGeneric(client *c, int flags) { unsigned char *src = NULL; char llbuf[LONG_STR_SIZE]; - if (o != NULL) - src = getObjectReadOnlyString(o,&strlen,llbuf); + if (o != NULL) { + src = getObjectReadOnlyString(o, &strlen, llbuf); + } /* For GET we use a trick: before executing the operation * copy up to 9 bytes to a local buffer, so that we can easily * execute up to 64 bit operations that are at actual string * object boundaries. */ - memset(buf,0,9); + memset(buf, 0, 9); int i; uint64_t byte = thisop->offset >> 3; for (i = 0; i < 9; i++) { - if (src == NULL || i+byte >= (uint64_t)strlen) break; - buf[i] = src[i+byte]; + if (src == NULL || i + byte >= (uint64_t)strlen) { + break; + } + buf[i] = src[i + byte]; } /* Now operate on the copied buffer which is guaranteed * to be zero-padded. */ if (thisop->sign) { - int64_t val = getSignedBitfield(buf,thisop->offset-(byte*8), - thisop->bits); - addReplyLongLong(c,val); + int64_t val = getSignedBitfield(buf, thisop->offset - (byte * 8), thisop->bits); + addReplyLongLong(c, val); } else { - uint64_t val = getUnsignedBitfield(buf,thisop->offset-(byte*8), - thisop->bits); - addReplyLongLong(c,val); + uint64_t val = getUnsignedBitfield(buf, thisop->offset - (byte * 8), thisop->bits); + addReplyLongLong(c, val); } } } if (changes) { - signalModifiedKey(c,c->db,c->argv[1]); - notifyKeyspaceEvent(NOTIFY_STRING,"setbit",c->argv[1],c->db->id); + signalModifiedKey(c, c->db, c->argv[1]); + notifyKeyspaceEvent(NOTIFY_STRING, "setbit", c->argv[1], c->db->id); server.dirty += changes; } zfree(ops); diff --git a/src/blocked.c b/src/blocked.c index e4ec86779..fab12795d 100644 --- a/src/blocked.c +++ b/src/blocked.c @@ -87,13 +87,13 @@ void initClientBlockingState(client *c) { * and will be processed when the client is unblocked. */ void blockClient(client *c, int btype) { /* Master client should never be blocked unless pause or module */ - serverAssert(!(c->flags & CLIENT_MASTER && - btype != BLOCKED_MODULE && - btype != BLOCKED_POSTPONE)); + serverAssert(!(c->flags & CLIENT_MASTER && btype != BLOCKED_MODULE && btype != BLOCKED_POSTPONE)); c->flags |= CLIENT_BLOCKED; c->bstate.btype = btype; - if (!(c->flags & CLIENT_MODULE)) server.blocked_clients++; /* We count blocked client stats on regular clients and not on module clients */ + if (!(c->flags & CLIENT_MODULE)) { + server.blocked_clients++; /* We count blocked client stats on regular clients and not on module clients */ + } server.blocked_clients_by_type[btype]++; addClientToTimeoutTable(c); } @@ -103,21 +103,23 @@ void blockClient(client *c, int btype) { * However in case the client was timed out or in case of module blocked client is being unblocked * the command will not be reprocessed and we need to make stats update. * This function will make updates to the commandstats, slowlog and monitors.*/ -void updateStatsOnUnblock(client *c, long blocked_us, long reply_us, int had_errors){ +void updateStatsOnUnblock(client *c, long blocked_us, long reply_us, int had_errors) { const ustime_t total_cmd_duration = c->duration + blocked_us + reply_us; c->lastcmd->microseconds += total_cmd_duration; c->lastcmd->calls++; c->commands_processed++; server.stat_numcommands++; - if (had_errors) + if (had_errors) { c->lastcmd->failed_calls++; - if (server.latency_tracking_enabled) - updateCommandLatencyHistogram(&(c->lastcmd->latency_histogram), total_cmd_duration*1000); + } + if (server.latency_tracking_enabled) { + updateCommandLatencyHistogram(&(c->lastcmd->latency_histogram), total_cmd_duration * 1000); + } /* Log the command into the Slow log if needed. */ slowlogPushCurrentCommand(c, c->lastcmd, total_cmd_duration); c->duration = 0; /* Log the reply duration event. */ - latencyAddSampleIfNeeded("command-unblocking",reply_us/1000); + latencyAddSampleIfNeeded("command-unblocking", reply_us / 1000); } /* This function is called in the beforeSleep() function of the event loop @@ -131,7 +133,7 @@ void processUnblockedClients(void) { ln = listFirst(server.unblocked_clients); serverAssert(ln != NULL); c = ln->value; - listDelNode(server.unblocked_clients,ln); + listDelNode(server.unblocked_clients, ln); c->flags &= ~CLIENT_UNBLOCKED; if (c->flags & CLIENT_MODULE) { @@ -176,25 +178,25 @@ void queueClientForReprocessing(client *c) { * blocking operation, don't add back it into the list multiple times. */ if (!(c->flags & CLIENT_UNBLOCKED)) { c->flags |= CLIENT_UNBLOCKED; - listAddNodeTail(server.unblocked_clients,c); + listAddNodeTail(server.unblocked_clients, c); } } /* Unblock a client calling the right function depending on the kind * of operation the client is blocking for. */ void unblockClient(client *c, int queue_for_reprocessing) { - if (c->bstate.btype == BLOCKED_LIST || - c->bstate.btype == BLOCKED_ZSET || - c->bstate.btype == BLOCKED_STREAM) { + if (c->bstate.btype == BLOCKED_LIST || c->bstate.btype == BLOCKED_ZSET || c->bstate.btype == BLOCKED_STREAM) { unblockClientWaitingData(c); } else if (c->bstate.btype == BLOCKED_WAIT || c->bstate.btype == BLOCKED_WAITAOF || c->bstate.btype == BLOCKED_WAIT_PREREPL) { unblockClientWaitingReplicas(c); } else if (c->bstate.btype == BLOCKED_MODULE) { - if (moduleClientIsBlockedOnKeys(c)) unblockClientWaitingData(c); + if (moduleClientIsBlockedOnKeys(c)) { + unblockClientWaitingData(c); + } unblockClientFromModule(c); } else if (c->bstate.btype == BLOCKED_POSTPONE) { - listDelNode(server.postponed_clients,c->postponed_list_node); + listDelNode(server.postponed_clients, c->postponed_list_node); c->postponed_list_node = NULL; } else if (c->bstate.btype == BLOCKED_SHUTDOWN) { /* No special cleanup. */ @@ -217,30 +219,32 @@ void unblockClient(client *c, int queue_for_reprocessing) { /* Clear the flags, and put the client in the unblocked list so that * we'll process new commands in its query buffer ASAP. */ - if (!(c->flags & CLIENT_MODULE)) server.blocked_clients--; /* We count blocked client stats on regular clients and not on module clients */ + if (!(c->flags & CLIENT_MODULE)) { + server.blocked_clients--; /* We count blocked client stats on regular clients and not on module clients */ + } server.blocked_clients_by_type[c->bstate.btype]--; c->flags &= ~CLIENT_BLOCKED; c->bstate.btype = BLOCKED_NONE; c->bstate.unblock_on_nokey = 0; removeClientFromTimeoutTable(c); - if (queue_for_reprocessing) queueClientForReprocessing(c); + if (queue_for_reprocessing) { + queueClientForReprocessing(c); + } } /* This function gets called when a blocked client timed out in order to * send it a reply of some kind. After this function is called, * unblockClient() will be called with the same client as argument. */ void replyToBlockedClientTimedOut(client *c) { - if (c->bstate.btype == BLOCKED_LIST || - c->bstate.btype == BLOCKED_ZSET || - c->bstate.btype == BLOCKED_STREAM) { + if (c->bstate.btype == BLOCKED_LIST || c->bstate.btype == BLOCKED_ZSET || c->bstate.btype == BLOCKED_STREAM) { addReplyNullArray(c); updateStatsOnUnblock(c, 0, 0, 0); } else if (c->bstate.btype == BLOCKED_WAIT) { - addReplyLongLong(c,replicationCountAcksByOffset(c->bstate.reploffset)); + addReplyLongLong(c, replicationCountAcksByOffset(c->bstate.reploffset)); } else if (c->bstate.btype == BLOCKED_WAITAOF) { - addReplyArrayLen(c,2); - addReplyLongLong(c,server.fsynced_reploff >= c->bstate.reploffset); - addReplyLongLong(c,replicationCountAOFAcksByOffset(c->bstate.reploffset)); + addReplyArrayLen(c, 2); + addReplyLongLong(c, server.fsynced_reploff >= c->bstate.reploffset); + addReplyLongLong(c, replicationCountAOFAcksByOffset(c->bstate.reploffset)); } else if (c->bstate.btype == BLOCKED_MODULE) { moduleBlockedClientTimedOut(c, 0); } else if (c->bstate.btype == BLOCKED_WAIT_PREREPL) { @@ -253,11 +257,13 @@ void replyToBlockedClientTimedOut(client *c) { /* If one or more clients are blocked on the SHUTDOWN command, this function * sends them an error reply and unblocks them. */ void replyToClientsBlockedOnShutdown(void) { - if (server.blocked_clients_by_type[BLOCKED_SHUTDOWN] == 0) return; + if (server.blocked_clients_by_type[BLOCKED_SHUTDOWN] == 0) { + return; + } listNode *ln; listIter li; listRewind(server.clients, &li); - while((ln = listNext(&li))) { + while ((ln = listNext(&li))) { client *c = listNodeValue(ln); if (c->flags & CLIENT_BLOCKED && c->bstate.btype == BLOCKED_SHUTDOWN) { addReplyError(c, "Errors trying to SHUTDOWN. Check logs."); @@ -277,8 +283,8 @@ void disconnectAllBlockedClients(void) { listNode *ln; listIter li; - listRewind(server.clients,&li); - while((ln = listNext(&li))) { + listRewind(server.clients, &li); + while ((ln = listNext(&li))) { client *c = listNodeValue(ln); if (c->flags & CLIENT_BLOCKED) { @@ -286,12 +292,12 @@ void disconnectAllBlockedClients(void) { * command processing will start from scratch, and the command will * be either executed or rejected. (unlike LIST blocked clients for * which the command is already in progress in a way. */ - if (c->bstate.btype == BLOCKED_POSTPONE) + if (c->bstate.btype == BLOCKED_POSTPONE) { continue; + } - unblockClientOnError(c, - "-UNBLOCKED force unblock from blocking operation, " - "instance state changed (master -> replica?)"); + unblockClientOnError(c, "-UNBLOCKED force unblock from blocking operation, " + "instance state changed (master -> replica?)"); c->flags |= CLIENT_CLOSE_AFTER_REPLY; } } @@ -318,12 +324,12 @@ void disconnectAllBlockedClients(void) { * be used only for a single type, like virtually any application will * do, the function is already fair. */ void handleClientsBlockedOnKeys(void) { - /* In case we are already in the process of unblocking clients we should * not make a recursive call, in order to prevent breaking fairness. */ static int in_handling_blocked_clients = 0; - if (in_handling_blocked_clients) + if (in_handling_blocked_clients) { return; + } in_handling_blocked_clients = 1; /* This function is called only when also_propagate is in its basic state @@ -333,7 +339,7 @@ void handleClientsBlockedOnKeys(void) { /* If a command being unblocked causes another command to get unblocked, * like a BLMOVE would do, then the new unblocked command will get processed * right away rather than wait for later. */ - while(listLength(server.ready_keys) != 0) { + while (listLength(server.ready_keys) != 0) { list *l; /* Point server.ready_keys to a fresh list and save the current one @@ -343,20 +349,20 @@ void handleClientsBlockedOnKeys(void) { l = server.ready_keys; server.ready_keys = listCreate(); - while(listLength(l) != 0) { + while (listLength(l) != 0) { listNode *ln = listFirst(l); readyList *rl = ln->value; /* First of all remove this key from db->ready_keys so that * we can safely call signalKeyAsReady() against this key. */ - dictDelete(rl->db->ready_keys,rl->key); + dictDelete(rl->db->ready_keys, rl->key); handleClientsBlockedOnKey(rl); /* Free this item. */ decrRefCount(rl->key); zfree(rl); - listDelNode(l,ln); + listDelNode(l, ln); } listRelease(l); /* We have the new list on place at this point. */ } @@ -383,13 +389,13 @@ void blockForKeys(client *c, int btype, robj **keys, int numkeys, mstime_t timeo for (j = 0; j < numkeys; j++) { /* If the key already exists in the dictionary ignore it. */ - if (!(client_blocked_entry = dictAddRaw(c->bstate.keys,keys[j],NULL))) { + if (!(client_blocked_entry = dictAddRaw(c->bstate.keys, keys[j], NULL))) { continue; } incrRefCount(keys[j]); /* And in the other "side", to map keys -> clients */ - db_blocked_entry = dictAddRaw(c->db->blocking_keys,keys[j], &db_blocked_existing_entry); + db_blocked_entry = dictAddRaw(c->db->blocking_keys, keys[j], &db_blocked_existing_entry); /* In case key[j] did not have blocking clients yet, we need to create a new list */ if (db_blocked_entry != NULL) { @@ -399,8 +405,8 @@ void blockForKeys(client *c, int btype, robj **keys, int numkeys, mstime_t timeo } else { l = dictGetVal(db_blocked_existing_entry); } - listAddNodeTail(l,c); - dictSetVal(c->bstate.keys,client_blocked_entry,listLast(l)); + listAddNodeTail(l, c); + dictSetVal(c->bstate.keys, client_blocked_entry, listLast(l)); /* We need to add the key to blocking_keys_unblock_on_nokey, if the client * wants to be awakened if key is deleted (like XREADGROUP) */ @@ -418,9 +424,10 @@ void blockForKeys(client *c, int btype, robj **keys, int numkeys, mstime_t timeo /* Currently we assume key blocking will require reprocessing the command. * However in case of modules, they have a different way to handle the reprocessing * which does not require setting the pending command flag */ - if (btype != BLOCKED_MODULE) + if (btype != BLOCKED_MODULE) { c->flags |= CLIENT_PENDING_COMMAND; - blockClient(c,btype); + } + blockClient(c, btype); } /* Helper function to unblock a client that's waiting in a blocking operation such as BLPOP. @@ -429,12 +436,13 @@ static void unblockClientWaitingData(client *c) { dictEntry *de; dictIterator *di; - if (dictSize(c->bstate.keys) == 0) + if (dictSize(c->bstate.keys) == 0) { return; + } di = dictGetIterator(c->bstate.keys); /* The client may wait for multiple keys, so unblock it for every key. */ - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { releaseBlockedEntry(c, de, 0); } dictReleaseIterator(di); @@ -443,11 +451,16 @@ static void unblockClientWaitingData(client *c) { static blocking_type getBlockedTypeByType(int type) { switch (type) { - case OBJ_LIST: return BLOCKED_LIST; - case OBJ_ZSET: return BLOCKED_ZSET; - case OBJ_MODULE: return BLOCKED_MODULE; - case OBJ_STREAM: return BLOCKED_STREAM; - default: return BLOCKED_NONE; + case OBJ_LIST: + return BLOCKED_LIST; + case OBJ_ZSET: + return BLOCKED_ZSET; + case OBJ_MODULE: + return BLOCKED_MODULE; + case OBJ_STREAM: + return BLOCKED_STREAM; + default: + return BLOCKED_NONE; } } @@ -467,8 +480,7 @@ static void signalKeyAsReadyLogic(serverDb *db, robj *key, int type, int deleted /* The type can never block. */ return; } - if (!server.blocked_clients_by_type[btype] && - !server.blocked_clients_by_type[BLOCKED_MODULE]) { + if (!server.blocked_clients_by_type[btype] && !server.blocked_clients_by_type[BLOCKED_MODULE]) { /* No clients block on this type. Note: Blocked modules are represented * by BLOCKED_MODULE, even if the intention is to wake up by normal * types (list, zset, stream), so we need to check that there are no @@ -478,13 +490,15 @@ static void signalKeyAsReadyLogic(serverDb *db, robj *key, int type, int deleted if (deleted) { /* Key deleted and no clients blocking for this key? No need to queue it. */ - if (dictFind(db->blocking_keys_unblock_on_nokey,key) == NULL) + if (dictFind(db->blocking_keys_unblock_on_nokey, key) == NULL) { return; + } /* Note: if we made it here it means the key is also present in db->blocking_keys */ } else { /* No clients blocking for this key? No need to queue it. */ - if (dictFind(db->blocking_keys,key) == NULL) + if (dictFind(db->blocking_keys, key) == NULL) { return; + } } dictEntry *de, *existing; @@ -504,7 +518,7 @@ static void signalKeyAsReadyLogic(serverDb *db, robj *key, int type, int deleted rl->key = key; rl->db = db; incrRefCount(key); - listAddNodeTail(server.ready_keys,rl); + listAddNodeTail(server.ready_keys, rl); } /* Helper function to wrap the logic of removing a client blocked key entry @@ -528,8 +542,8 @@ static void releaseBlockedEntry(client *c, dictEntry *de, int remove_key) { pos = dictGetVal(de); /* Remove this client from the list of clients waiting for this key. */ l = dictFetchValue(c->db->blocking_keys, key); - serverAssertWithInfo(c,key,l != NULL); - listUnlinkNode(l,pos); + serverAssertWithInfo(c, key, l != NULL); + listUnlinkNode(l, pos); /* If the list is empty we need to remove it to avoid wasting memory * We will also remove the key (if exists) from the blocking_keys_unblock_on_nokey dict. * However, in case the list is not empty, we will have to still perform reference accounting @@ -539,18 +553,19 @@ static void releaseBlockedEntry(client *c, dictEntry *de, int remove_key) { * signalDeletedKeyAsReady. */ if (listLength(l) == 0) { dictDelete(c->db->blocking_keys, key); - dictDelete(c->db->blocking_keys_unblock_on_nokey,key); + dictDelete(c->db->blocking_keys_unblock_on_nokey, key); } else if (c->bstate.unblock_on_nokey) { - unblock_on_nokey_entry = dictFind(c->db->blocking_keys_unblock_on_nokey,key); + unblock_on_nokey_entry = dictFind(c->db->blocking_keys_unblock_on_nokey, key); /* it is not possible to have a client blocked on nokey with no matching entry */ - serverAssertWithInfo(c,key,unblock_on_nokey_entry != NULL); + serverAssertWithInfo(c, key, unblock_on_nokey_entry != NULL); if (!dictIncrUnsignedIntegerVal(unblock_on_nokey_entry, -1)) { /* in case the count is zero, we can delete the entry */ - dictDelete(c->db->blocking_keys_unblock_on_nokey,key); + dictDelete(c->db->blocking_keys_unblock_on_nokey, key); } } - if (remove_key) + if (remove_key) { dictDelete(c->bstate.keys, key); + } } void signalKeyAsReady(serverDb *db, robj *key, int type) { @@ -565,16 +580,15 @@ void signalDeletedKeyAsReady(serverDb *db, robj *key, int type) { * whenever a key is ready. we iterate over all the clients blocked on this key * and try to re-execute the command (in case the key is still available). */ static void handleClientsBlockedOnKey(readyList *rl) { - /* We serve clients in the same order they blocked for * this key, from the first blocked to the last. */ - dictEntry *de = dictFind(rl->db->blocking_keys,rl->key); + dictEntry *de = dictFind(rl->db->blocking_keys, rl->key); if (de) { list *clients = dictGetVal(de); listNode *ln; listIter li; - listRewind(clients,&li); + listRewind(clients, &li); /* Avoid processing more than the initial count so that we're not stuck * in an endless loop in case the reprocessing of the command blocks again. */ @@ -590,20 +604,20 @@ static void handleClientsBlockedOnKey(readyList *rl) { * 3. In case of XREADGROUP call we will want to unblock on any change in object type * or in case the key was deleted, since the group is no longer valid. */ if ((o != NULL && (receiver->bstate.btype == getBlockedTypeByType(o->type))) || - (o != NULL && (receiver->bstate.btype == BLOCKED_MODULE)) || - (receiver->bstate.unblock_on_nokey)) - { - if (receiver->bstate.btype != BLOCKED_MODULE) + (o != NULL && (receiver->bstate.btype == BLOCKED_MODULE)) || (receiver->bstate.unblock_on_nokey)) { + if (receiver->bstate.btype != BLOCKED_MODULE) { unblockClientOnKey(receiver, rl->key); - else + } else { moduleUnblockClientOnKey(receiver, rl->key); + } } } } } /* block a client for replica acknowledgement */ -void blockClientForReplicaAck(client *c, mstime_t timeout, long long offset, long numreplicas, int btype, int numlocal) { +void blockClientForReplicaAck(client *c, mstime_t timeout, long long offset, long numreplicas, int btype, + int numlocal) { c->bstate.timeout = timeout; c->bstate.reploffset = offset; c->bstate.numreplicas = numreplicas; @@ -633,7 +647,7 @@ void blockForAofFsync(client *c, mstime_t timeout, long long offset, int numloca * when the it is ready to accept them. */ void blockPostponeClient(client *c) { c->bstate.timeout = 0; - blockClient(c,BLOCKED_POSTPONE); + blockClient(c, BLOCKED_POSTPONE); listAddNodeTail(server.postponed_clients, c); c->postponed_list_node = listLast(server.postponed_clients); /* Mark this client to execute its command */ @@ -657,9 +671,8 @@ static void unblockClientOnKey(client *c, robj *key) { /* Only in case of blocking API calls, we might be blocked on several keys. however we should force unblock the entire blocking keys */ - serverAssert(c->bstate.btype == BLOCKED_STREAM || - c->bstate.btype == BLOCKED_LIST || - c->bstate.btype == BLOCKED_ZSET); + serverAssert(c->bstate.btype == BLOCKED_STREAM || c->bstate.btype == BLOCKED_LIST || + c->bstate.btype == BLOCKED_ZSET); /* We need to unblock the client before calling processCommandAndResetClient * because it checks the CLIENT_BLOCKED flag */ @@ -720,22 +733,27 @@ static void moduleUnblockClientOnKey(client *c, robj *key) { * command with timeout reply. */ void unblockClientOnTimeout(client *c) { /* The client has been unlocked (in the moduleUnblocked list), return ASAP. */ - if (c->bstate.btype == BLOCKED_MODULE && isModuleClientUnblocked(c)) return; + if (c->bstate.btype == BLOCKED_MODULE && isModuleClientUnblocked(c)) { + return; + } replyToBlockedClientTimedOut(c); - if (c->flags & CLIENT_PENDING_COMMAND) + if (c->flags & CLIENT_PENDING_COMMAND) { c->flags &= ~CLIENT_PENDING_COMMAND; + } unblockClient(c, 1); } /* Unblock a client which is currently Blocked with error. * If err_str is provided it will be used to reply to the blocked client */ void unblockClientOnError(client *c, const char *err_str) { - if (err_str) + if (err_str) { addReplyError(c, err_str); + } updateStatsOnUnblock(c, 0, 0, 1); - if (c->flags & CLIENT_PENDING_COMMAND) + if (c->flags & CLIENT_PENDING_COMMAND) { c->flags &= ~CLIENT_PENDING_COMMAND; + } unblockClient(c, 1); } @@ -745,8 +763,9 @@ void blockedBeforeSleep(void) { /* Unblock all the clients blocked for synchronous replication * in WAIT or WAITAOF. */ - if (listLength(server.clients_waiting_acks)) + if (listLength(server.clients_waiting_acks)) { processClientsWaitingReplicas(); + } /* Try to process blocked clients every once in while. * @@ -758,10 +777,12 @@ void blockedBeforeSleep(void) { /* Check if there are clients unblocked by modules that implement * blocking commands. */ - if (moduleCount()) + if (moduleCount()) { moduleHandleBlockedClients(); + } /* Try to process pending commands for clients that were just unblocked. */ - if (listLength(server.unblocked_clients)) + if (listLength(server.unblocked_clients)) { processUnblockedClients(); + } } diff --git a/src/call_reply.c b/src/call_reply.c index 9e910f50c..3b953cd81 100644 --- a/src/call_reply.c +++ b/src/call_reply.c @@ -30,9 +30,9 @@ #include "server.h" #include "call_reply.h" -#define REPLY_FLAG_ROOT (1<<0) -#define REPLY_FLAG_PARSED (1<<1) -#define REPLY_FLAG_RESP3 (1<<2) +#define REPLY_FLAG_ROOT (1 << 0) +#define REPLY_FLAG_PARSED (1 << 1) +#define REPLY_FLAG_RESP3 (1 << 2) /* -------------------------------------------------------- * An opaque struct used to parse a RESP protocol reply and @@ -44,9 +44,9 @@ struct CallReply { sds original_proto; /* Available only for root reply. */ const char *proto; size_t proto_len; - int type; /* REPLY_... */ - int flags; /* REPLY_FLAG... */ - size_t len; /* Length of a string, or the number elements in an array. */ + int type; /* REPLY_... */ + int flags; /* REPLY_FLAG... */ + size_t len; /* Length of a string, or the number elements in an array. */ union { const char *str; /* String pointer for string and error replies. This * does not need to be freed, always points inside @@ -55,9 +55,9 @@ struct CallReply { struct { const char *str; const char *format; - } verbatim_str; /* Reply value for verbatim string */ - long long ll; /* Reply value for integer reply. */ - double d; /* Reply value for double reply. */ + } verbatim_str; /* Reply value for verbatim string */ + long long ll; /* Reply value for integer reply. */ + double d; /* Reply value for double reply. */ struct CallReply *array; /* Array of sub-reply elements. used for set, array, map, and attribute */ } val; list *deferred_error_list; /* list of errors in sds form or NULL */ @@ -119,7 +119,8 @@ static void callReplyDouble(void *ctx, double val, const char *proto, size_t pro rep->val.d = val; } -static void callReplyVerbatimString(void *ctx, const char *format, const char *str, size_t len, const char *proto, size_t proto_len) { +static void callReplyVerbatimString(void *ctx, const char *format, const char *str, size_t len, const char *proto, + size_t proto_len) { CallReply *rep = ctx; callReplySetSharedData(rep, VALKEYMODULE_REPLY_VERBATIM_STRING, proto, proto_len, REPLY_FLAG_RESP3); rep->len = len; @@ -140,11 +141,12 @@ static void callReplyBool(void *ctx, int val, const char *proto, size_t proto_le rep->val.ll = val; } -static void callReplyParseCollection(ReplyParser *parser, CallReply *rep, size_t len, const char *proto, size_t elements_per_entry) { +static void callReplyParseCollection(ReplyParser *parser, CallReply *rep, size_t len, const char *proto, + size_t elements_per_entry) { rep->len = len; rep->val.array = zcalloc(elements_per_entry * len * sizeof(CallReply)); for (size_t i = 0; i < len * elements_per_entry; i += elements_per_entry) { - for (size_t j = 0 ; j < elements_per_entry ; ++j) { + for (size_t j = 0; j < elements_per_entry; ++j) { rep->val.array[i + j].private_data = rep->private_data; parseReply(parser, rep->val.array + i + j); rep->val.array[i + j].flags |= REPLY_FLAG_PARSED; @@ -206,14 +208,14 @@ static void callReplyParseError(void *ctx) { /* Recursively free the current call reply and its sub-replies. */ static void freeCallReplyInternal(CallReply *rep) { if (rep->type == VALKEYMODULE_REPLY_ARRAY || rep->type == VALKEYMODULE_REPLY_SET) { - for (size_t i = 0 ; i < rep->len ; ++i) { + for (size_t i = 0; i < rep->len; ++i) { freeCallReplyInternal(rep->val.array + i); } zfree(rep->val.array); } if (rep->type == VALKEYMODULE_REPLY_MAP || rep->type == VALKEYMODULE_REPLY_ATTRIBUTE) { - for (size_t i = 0 ; i < rep->len ; ++i) { + for (size_t i = 0; i < rep->len; ++i) { freeCallReplyInternal(rep->val.array + i * 2); freeCallReplyInternal(rep->val.array + i * 2 + 1); } @@ -241,8 +243,9 @@ void freeCallReply(CallReply *rep) { freeCallReplyInternal(rep); } sdsfree(rep->original_proto); - if (rep->deferred_error_list) + if (rep->deferred_error_list) { listRelease(rep->deferred_error_list); + } zfree(rep); } @@ -291,7 +294,9 @@ static void callReplyParse(CallReply *rep) { /* Return the call reply type (VALKEYMODULE_REPLY_...). */ int callReplyType(CallReply *rep) { - if (!rep) return VALKEYMODULE_REPLY_UNKNOWN; + if (!rep) { + return VALKEYMODULE_REPLY_UNKNOWN; + } callReplyParse(rep); return rep->type; } @@ -308,9 +313,12 @@ int callReplyType(CallReply *rep) { */ const char *callReplyGetString(CallReply *rep, size_t *len) { callReplyParse(rep); - if (rep->type != VALKEYMODULE_REPLY_STRING && - rep->type != VALKEYMODULE_REPLY_ERROR) return NULL; - if (len) *len = rep->len; + if (rep->type != VALKEYMODULE_REPLY_STRING && rep->type != VALKEYMODULE_REPLY_ERROR) { + return NULL; + } + if (len) { + *len = rep->len; + } return rep->val.str; } @@ -319,7 +327,9 @@ const char *callReplyGetString(CallReply *rep, size_t *len) { */ long long callReplyGetLongLong(CallReply *rep) { callReplyParse(rep); - if (rep->type != VALKEYMODULE_REPLY_INTEGER) return LLONG_MIN; + if (rep->type != VALKEYMODULE_REPLY_INTEGER) { + return LLONG_MIN; + } return rep->val.ll; } @@ -328,7 +338,9 @@ long long callReplyGetLongLong(CallReply *rep) { */ double callReplyGetDouble(CallReply *rep) { callReplyParse(rep); - if (rep->type != VALKEYMODULE_REPLY_DOUBLE) return LLONG_MIN; + if (rep->type != VALKEYMODULE_REPLY_DOUBLE) { + return LLONG_MIN; + } return rep->val.d; } @@ -337,7 +349,9 @@ double callReplyGetDouble(CallReply *rep) { */ int callReplyGetBool(CallReply *rep) { callReplyParse(rep); - if (rep->type != VALKEYMODULE_REPLY_BOOL) return INT_MIN; + if (rep->type != VALKEYMODULE_REPLY_BOOL) { + return INT_MIN; + } return rep->val.ll; } @@ -351,22 +365,24 @@ int callReplyGetBool(CallReply *rep) { */ size_t callReplyGetLen(CallReply *rep) { callReplyParse(rep); - switch(rep->type) { - case VALKEYMODULE_REPLY_STRING: - case VALKEYMODULE_REPLY_ERROR: - case VALKEYMODULE_REPLY_ARRAY: - case VALKEYMODULE_REPLY_SET: - case VALKEYMODULE_REPLY_MAP: - case VALKEYMODULE_REPLY_ATTRIBUTE: - return rep->len; - default: - return 0; + switch (rep->type) { + case VALKEYMODULE_REPLY_STRING: + case VALKEYMODULE_REPLY_ERROR: + case VALKEYMODULE_REPLY_ARRAY: + case VALKEYMODULE_REPLY_SET: + case VALKEYMODULE_REPLY_MAP: + case VALKEYMODULE_REPLY_ATTRIBUTE: + return rep->len; + default: + return 0; } } static CallReply *callReplyGetCollectionElement(CallReply *rep, size_t idx, int elements_per_entry) { - if (idx >= rep->len * elements_per_entry) return NULL; // real len is rep->len * elements_per_entry - return rep->val.array+idx; + if (idx >= rep->len * elements_per_entry) { + return NULL; // real len is rep->len * elements_per_entry + } + return rep->val.array + idx; } /* Return a reply array element at a given index. Applicable to: @@ -377,7 +393,9 @@ static CallReply *callReplyGetCollectionElement(CallReply *rep, size_t idx, int */ CallReply *callReplyGetArrayElement(CallReply *rep, size_t idx) { callReplyParse(rep); - if (rep->type != VALKEYMODULE_REPLY_ARRAY) return NULL; + if (rep->type != VALKEYMODULE_REPLY_ARRAY) { + return NULL; + } return callReplyGetCollectionElement(rep, idx, 1); } @@ -389,16 +407,26 @@ CallReply *callReplyGetArrayElement(CallReply *rep, size_t idx) { */ CallReply *callReplyGetSetElement(CallReply *rep, size_t idx) { callReplyParse(rep); - if (rep->type != VALKEYMODULE_REPLY_SET) return NULL; + if (rep->type != VALKEYMODULE_REPLY_SET) { + return NULL; + } return callReplyGetCollectionElement(rep, idx, 1); } static int callReplyGetMapElementInternal(CallReply *rep, size_t idx, CallReply **key, CallReply **val, int type) { callReplyParse(rep); - if (rep->type != type) return C_ERR; - if (idx >= rep->len) return C_ERR; - if (key) *key = callReplyGetCollectionElement(rep, idx * 2, 2); - if (val) *val = callReplyGetCollectionElement(rep, idx * 2 + 1, 2); + if (rep->type != type) { + return C_ERR; + } + if (idx >= rep->len) { + return C_ERR; + } + if (key) { + *key = callReplyGetCollectionElement(rep, idx * 2, 2); + } + if (val) { + *val = callReplyGetCollectionElement(rep, idx * 2 + 1, 2); + } return C_OK; } @@ -457,7 +485,9 @@ int callReplyGetAttributeElement(CallReply *rep, size_t idx, CallReply **key, Ca */ const char *callReplyGetBigNumber(CallReply *rep, size_t *len) { callReplyParse(rep); - if (rep->type != VALKEYMODULE_REPLY_BIG_NUMBER) return NULL; + if (rep->type != VALKEYMODULE_REPLY_BIG_NUMBER) { + return NULL; + } *len = rep->len; return rep->val.str; } @@ -476,11 +506,15 @@ const char *callReplyGetBigNumber(CallReply *rep, size_t *len) { * The returned value is not NULL terminated and its length is returned by * reference through len, which must not be NULL. */ -const char *callReplyGetVerbatim(CallReply *rep, size_t *len, const char **format){ +const char *callReplyGetVerbatim(CallReply *rep, size_t *len, const char **format) { callReplyParse(rep); - if (rep->type != VALKEYMODULE_REPLY_VERBATIM_STRING) return NULL; + if (rep->type != VALKEYMODULE_REPLY_VERBATIM_STRING) { + return NULL; + } *len = rep->len; - if (format) *format = rep->val.verbatim_str.format; + if (format) { + *format = rep->val.verbatim_str.format; + } return rep->val.verbatim_str.str; } @@ -554,7 +588,7 @@ CallReply *callReplyCreateError(sds reply, void *private_data) { sdsfree(reply); } list *deferred_error_list = listCreate(); - listSetFreeMethod(deferred_error_list, (void (*)(void*))sdsfree); + listSetFreeMethod(deferred_error_list, (void (*)(void *))sdsfree); listAddNodeTail(deferred_error_list, sdsnew(err_buff)); return callReplyCreate(err_buff, deferred_error_list, private_data); } diff --git a/src/childinfo.c b/src/childinfo.c index 1303dd043..7af6a707d 100644 --- a/src/childinfo.c +++ b/src/childinfo.c @@ -54,9 +54,7 @@ void openChildInfoPipe(void) { /* Close the pipes opened with openChildInfoPipe(). */ void closeChildInfoPipe(void) { - if (server.child_info_pipe[0] != -1 || - server.child_info_pipe[1] != -1) - { + if (server.child_info_pipe[0] != -1 || server.child_info_pipe[1] != -1) { close(server.child_info_pipe[0]); close(server.child_info_pipe[1]); server.child_info_pipe[0] = -1; @@ -67,7 +65,9 @@ void closeChildInfoPipe(void) { /* Send save data to parent. */ void sendChildInfoGeneric(childInfoType info_type, size_t keys, double progress, char *pname) { - if (server.child_info_pipe[1] == -1) return; + if (server.child_info_pipe[1] == -1) { + return; + } static monotime cow_updated = 0; static uint64_t cow_update_cost = 0; @@ -84,22 +84,22 @@ void sendChildInfoGeneric(childInfoType info_type, size_t keys, double progress, * passes. */ monotime now = getMonotonicUs(); - if (info_type != CHILD_INFO_TYPE_CURRENT_INFO || - !cow_updated || - now - cow_updated > cow_update_cost * CHILD_COW_DUTY_CYCLE) - { + if (info_type != CHILD_INFO_TYPE_CURRENT_INFO || !cow_updated || + now - cow_updated > cow_update_cost * CHILD_COW_DUTY_CYCLE) { cow = zmalloc_get_private_dirty(-1); cow_updated = getMonotonicUs(); cow_update_cost = cow_updated - now; - if (cow > peak_cow) peak_cow = cow; + if (cow > peak_cow) { + peak_cow = cow; + } sum_cow += cow; update_count++; int cow_info = (info_type != CHILD_INFO_TYPE_CURRENT_INFO); if (cow || cow_info) { serverLog(cow_info ? LL_NOTICE : LL_VERBOSE, - "Fork CoW for %s: current %zu MB, peak %zu MB, average %llu MB", - pname, cow>>20, peak_cow>>20, (sum_cow/update_count)>>20); + "Fork CoW for %s: current %zu MB, peak %zu MB, average %llu MB", pname, cow >> 20, peak_cow >> 20, + (sum_cow / update_count) >> 20); } } @@ -113,20 +113,24 @@ void sendChildInfoGeneric(childInfoType info_type, size_t keys, double progress, if (write(server.child_info_pipe[1], &data, wlen) != wlen) { /* Failed writing to parent, it could have been killed, exit. */ - serverLog(LL_WARNING,"Child failed reporting info to parent, exiting. %s", strerror(errno)); + serverLog(LL_WARNING, "Child failed reporting info to parent, exiting. %s", strerror(errno)); exitFromChild(1); } } /* Update Child info. */ void updateChildInfo(childInfoType information_type, size_t cow, monotime cow_updated, size_t keys, double progress) { - if (cow > server.stat_current_cow_peak) server.stat_current_cow_peak = cow; + if (cow > server.stat_current_cow_peak) { + server.stat_current_cow_peak = cow; + } if (information_type == CHILD_INFO_TYPE_CURRENT_INFO) { server.stat_current_cow_bytes = cow; server.stat_current_cow_updated = cow_updated; server.stat_current_save_keys_processed = keys; - if (progress != -1) server.stat_module_progress = progress; + if (progress != -1) { + server.stat_module_progress = progress; + } } else if (information_type == CHILD_INFO_TYPE_AOF_COW_SIZE) { server.stat_aof_cow_bytes = server.stat_current_cow_peak; } else if (information_type == CHILD_INFO_TYPE_RDB_COW_SIZE) { @@ -137,18 +141,21 @@ void updateChildInfo(childInfoType information_type, size_t cow, monotime cow_up } /* Read child info data from the pipe. - * if complete data read into the buffer, + * if complete data read into the buffer, * data is stored into *buffer, and returns 1. * otherwise, the partial data is left in the buffer, waiting for the next read, and returns 0. */ -int readChildInfo(childInfoType *information_type, size_t *cow, monotime *cow_updated, size_t *keys, double* progress) { +int readChildInfo(childInfoType *information_type, size_t *cow, monotime *cow_updated, size_t *keys, double *progress) { /* We are using here a static buffer in combination with the server.child_info_nread to handle short reads */ static child_info_data buffer; ssize_t wlen = sizeof(buffer); /* Do not overlap */ - if (server.child_info_nread == wlen) server.child_info_nread = 0; + if (server.child_info_nread == wlen) { + server.child_info_nread = 0; + } - int nread = read(server.child_info_pipe[0], (char *)&buffer + server.child_info_nread, wlen - server.child_info_nread); + int nread = + read(server.child_info_pipe[0], (char *)&buffer + server.child_info_nread, wlen - server.child_info_nread); if (nread > 0) { server.child_info_nread += nread; } @@ -168,7 +175,9 @@ int readChildInfo(childInfoType *information_type, size_t *cow, monotime *cow_up /* Receive info data from child. */ void receiveChildInfo(void) { - if (server.child_info_pipe[0] == -1) return; + if (server.child_info_pipe[0] == -1) { + return; + } size_t cow; monotime cow_updated; diff --git a/src/cli_commands.c b/src/cli_commands.c index e56d48cfa..1a6ab545b 100644 --- a/src/cli_commands.c +++ b/src/cli_commands.c @@ -2,8 +2,12 @@ #include "cli_commands.h" /* Definitions to configure commands.c to generate the above structs. */ -#define MAKE_CMD(name,summary,complexity,since,doc_flags,replaced,deprecated,group,group_enum,history,num_history,tips,num_tips,function,arity,flags,acl,key_specs,key_specs_num,get_keys,numargs) name,summary,group,since,numargs -#define MAKE_ARG(name,type,key_spec_index,token,summary,since,flags,numsubargs,deprecated_since) name,type,token,since,flags,numsubargs +#define MAKE_CMD(name, summary, complexity, since, doc_flags, replaced, deprecated, group, group_enum, history, \ + num_history, tips, num_tips, function, arity, flags, acl, key_specs, key_specs_num, get_keys, \ + numargs) \ + name, summary, group, since, numargs +#define MAKE_ARG(name, type, key_spec_index, token, summary, since, flags, numsubargs, deprecated_since) \ + name, type, token, since, flags, numsubargs #define COMMAND_ARG cliCommandArg #define COMMAND_STRUCT commandDocs #define SKIP_CMD_HISTORY_TABLE diff --git a/src/cli_commands.h b/src/cli_commands.h index 5669d2cf4..a8174e430 100644 --- a/src/cli_commands.h +++ b/src/cli_commands.h @@ -23,10 +23,10 @@ typedef struct cliCommandArg { * For use at runtime. * Fields used to keep track of input word matches for command-line hinting. */ - int matched; /* How many input words have been matched by this argument? */ - int matched_token; /* Has the token been matched? */ + int matched; /* How many input words have been matched by this argument? */ + int matched_token; /* Has the token been matched? */ int matched_name; /* Has the name been matched? */ - int matched_all; /* Has the whole argument been consumed (no hint needed)? */ + int matched_all; /* Has the whole argument been consumed (no hint needed)? */ } cliCommandArg; /* Command documentation info used for help output */ diff --git a/src/cli_common.c b/src/cli_common.c index 879e5a236..42b03648c 100644 --- a/src/cli_common.c +++ b/src/cli_common.c @@ -1,5 +1,5 @@ /* CLI (command line interface) common methods - * + * * Copyright (c) 2020, Redis Labs * All rights reserved. * @@ -38,7 +38,7 @@ #include #include #include /* Use hiredis' sds compat header that maps sds calls to their hi_ variants */ -#include /* use sds.h from hiredis, so that only one set of sds functions will be present in the binary */ +#include /* use sds.h from hiredis, so that only one set of sds functions will be present in the binary */ #include #include #include @@ -48,7 +48,7 @@ #include #endif -#define UNUSED(V) ((void) V) +#define UNUSED(V) ((void)V) char *serverGitSHA1(void); char *serverGitDirty(void); @@ -121,9 +121,9 @@ int cliSecureConnection(redisContext *c, cliSSLconfig config, const char **err) ssl_ctx = NULL; return REDIS_ERR; #else - (void) config; - (void) c; - (void) err; + (void)config; + (void)c; + (void)err; return REDIS_OK; #endif } @@ -142,8 +142,7 @@ int cliSecureConnection(redisContext *c, cliSSLconfig config, const char **err) * in the buffer (leftovers from hiredis operations) it will be written * as well. */ -ssize_t cliWriteConn(redisContext *c, const char *buf, size_t buf_len) -{ +ssize_t cliWriteConn(redisContext *c, const char *buf, size_t buf_len) { int done = 0; /* Append data to buffer which is *usually* expected to be empty @@ -151,16 +150,18 @@ ssize_t cliWriteConn(redisContext *c, const char *buf, size_t buf_len) */ c->obuf = sdscatlen(c->obuf, buf, buf_len); if (redisBufferWrite(c, &done) == REDIS_ERR) { - if (!(c->flags & REDIS_BLOCK)) + if (!(c->flags & REDIS_BLOCK)) { errno = EAGAIN; + } /* On error, we assume nothing was written and we roll back the * buffer to its original state. */ - if (sdslen(c->obuf) > buf_len) - sdsrange(c->obuf, 0, -(buf_len+1)); - else + if (sdslen(c->obuf) > buf_len) { + sdsrange(c->obuf, 0, -(buf_len + 1)); + } else { sdsclear(c->obuf); + } return -1; } @@ -182,7 +183,7 @@ ssize_t cliWriteConn(redisContext *c, const char *buf, size_t buf_len) * written. */ if (sdslen(c->obuf) > buf_len) { - sdsrange(c->obuf, 0, -(buf_len+1)); + sdsrange(c->obuf, 0, -(buf_len + 1)); return 0; } @@ -196,8 +197,7 @@ ssize_t cliWriteConn(redisContext *c, const char *buf, size_t buf_len) /* Wrapper around OpenSSL (libssl and libcrypto) initialisation */ -int cliSecureInit(void) -{ +int cliSecureInit(void) { #ifdef USE_OPENSSL ERR_load_crypto_strings(); SSL_load_error_strings(); @@ -211,15 +211,16 @@ sds readArgFromStdin(void) { char buf[1024]; sds arg = sdsempty(); - while(1) { - int nread = read(fileno(stdin),buf,1024); + while (1) { + int nread = read(fileno(stdin), buf, 1024); - if (nread == 0) break; - else if (nread == -1) { + if (nread == 0) { + break; + } else if (nread == -1) { perror("Reading from standard input"); exit(1); } - arg = sdscatlen(arg,buf,nread); + arg = sdscatlen(arg, buf, nread); } return arg; } @@ -231,14 +232,16 @@ sds readArgFromStdin(void) { * The caller should free the resulting array of sds strings with * sdsfreesplitres(). */ -sds *getSdsArrayFromArgv(int argc,char **argv, int quoted) { +sds *getSdsArrayFromArgv(int argc, char **argv, int quoted) { sds *res = sds_malloc(sizeof(sds) * argc); for (int j = 0; j < argc; j++) { if (quoted) { sds unquoted = unquoteCString(argv[j]); if (!unquoted) { - while (--j >= 0) sdsfree(res[j]); + while (--j >= 0) { + sdsfree(res[j]); + } sds_free(res); return NULL; } @@ -262,8 +265,9 @@ sds unquoteCString(char *str) { unquoted[0] = NULL; } - if (unquoted) + if (unquoted) { sdsfreesplitres(unquoted, count); + } return res; } @@ -311,7 +315,7 @@ static sds percentDecode(const char *pe, size_t len) { * path: ["/" []] * * [1]: https://www.iana.org/assignments/uri-schemes/prov/redis */ -void parseRedisUri(const char *uri, const char* tool_name, cliConnInfo *connInfo, int *tls_flag) { +void parseRedisUri(const char *uri, const char *tool_name, cliConnInfo *connInfo, int *tls_flag) { #ifdef USE_OPENSSL UNUSED(tool_name); #else @@ -337,22 +341,23 @@ void parseRedisUri(const char *uri, const char* tool_name, cliConnInfo *connInfo #else char *copy = strdup(curr); char *curr_scheme = strtok(copy, "://"); - fprintf(stderr,"%s:// is only supported when %s is compiled with OpenSSL\n", curr_scheme, tool_name); + fprintf(stderr, "%s:// is only supported when %s is compiled with OpenSSL\n", curr_scheme, tool_name); free(copy); exit(1); #endif - } else if (!strncasecmp(scheme, curr, strlen(scheme)) || - !strncasecmp(redisScheme, curr, strlen(redisScheme))) { + } else if (!strncasecmp(scheme, curr, strlen(scheme)) || !strncasecmp(redisScheme, curr, strlen(redisScheme))) { char *del = strstr(curr, "://"); curr += (del - curr) + 3; } else { - fprintf(stderr,"Invalid URI scheme\n"); + fprintf(stderr, "Invalid URI scheme\n"); exit(1); } - if (curr == end) return; + if (curr == end) { + return; + } /* Extract user info. */ - if ((userinfo = strchr(curr,'@'))) { + if ((userinfo = strchr(curr, '@'))) { if ((username = strchr(curr, ':')) && username < userinfo) { connInfo->user = percentDecode(curr, username - curr); curr = username + 1; @@ -361,7 +366,9 @@ void parseRedisUri(const char *uri, const char* tool_name, cliConnInfo *connInfo connInfo->auth = percentDecode(curr, userinfo - curr); curr = userinfo + 1; } - if (curr == end) return; + if (curr == end) { + return; + } /* Extract host and port. */ path = strchr(curr, '/'); @@ -370,7 +377,7 @@ void parseRedisUri(const char *uri, const char* tool_name, cliConnInfo *connInfo if (*curr == '[') { curr += 1; if ((port = strchr(curr, ']'))) { - if (*(port+1) == ':') { + if (*(port + 1) == ':') { connInfo->hostport = atoi(port + 2); } host = port - 1; @@ -385,51 +392,70 @@ void parseRedisUri(const char *uri, const char* tool_name, cliConnInfo *connInfo connInfo->hostip = sdsnewlen(curr, host - curr + 1); } curr = path ? path + 1 : end; - if (curr == end) return; + if (curr == end) { + return; + } /* Extract database number. */ connInfo->input_dbnum = atoi(curr); } -void freeCliConnInfo(cliConnInfo connInfo){ - if (connInfo.hostip) sdsfree(connInfo.hostip); - if (connInfo.auth) sdsfree(connInfo.auth); - if (connInfo.user) sdsfree(connInfo.user); +void freeCliConnInfo(cliConnInfo connInfo) { + if (connInfo.hostip) { + sdsfree(connInfo.hostip); + } + if (connInfo.auth) { + sdsfree(connInfo.auth); + } + if (connInfo.user) { + sdsfree(connInfo.user); + } } /* * Escape a Unicode string for JSON output (--json), following RFC 7159: * https://datatracker.ietf.org/doc/html/rfc7159#section-7 -*/ + */ sds escapeJsonString(sds s, const char *p, size_t len) { - s = sdscatlen(s,"\"",1); - while(len--) { - switch(*p) { + s = sdscatlen(s, "\"", 1); + while (len--) { + switch (*p) { case '\\': case '"': - s = sdscatprintf(s,"\\%c",*p); + s = sdscatprintf(s, "\\%c", *p); + break; + case '\n': + s = sdscatlen(s, "\\n", 2); + break; + case '\f': + s = sdscatlen(s, "\\f", 2); + break; + case '\r': + s = sdscatlen(s, "\\r", 2); + break; + case '\t': + s = sdscatlen(s, "\\t", 2); + break; + case '\b': + s = sdscatlen(s, "\\b", 2); break; - case '\n': s = sdscatlen(s,"\\n",2); break; - case '\f': s = sdscatlen(s,"\\f",2); break; - case '\r': s = sdscatlen(s,"\\r",2); break; - case '\t': s = sdscatlen(s,"\\t",2); break; - case '\b': s = sdscatlen(s,"\\b",2); break; default: - s = sdscatprintf(s,*(unsigned char *)p <= 0x1f ? "\\u%04x" : "%c",*p); + s = sdscatprintf(s, *(unsigned char *)p <= 0x1f ? "\\u%04x" : "%c", *p); } p++; } - return sdscatlen(s,"\"",1); + return sdscatlen(s, "\"", 1); } sds cliVersion(void) { sds version = sdscatprintf(sdsempty(), "%s", VALKEY_VERSION); /* Add git commit and working tree status when available. */ - if (strtoll(serverGitSHA1(),NULL,16)) { + if (strtoll(serverGitSHA1(), NULL, 16)) { version = sdscatprintf(version, " (git:%s", serverGitSHA1()); - if (strtoll(serverGitDirty(),NULL,10)) + if (strtoll(serverGitDirty(), NULL, 10)) { version = sdscatprintf(version, "-dirty"); + } version = sdscat(version, ")"); } return version; diff --git a/src/cli_common.h b/src/cli_common.h index a5b8e44a2..c5008a2e0 100644 --- a/src/cli_common.h +++ b/src/cli_common.h @@ -18,9 +18,9 @@ typedef struct cliSSLconfig { /* Private key file to authenticate with, or NULL */ char *key; /* Preferred cipher list, or NULL (applies only to <= TLSv1.2) */ - char* ciphers; + char *ciphers; /* Preferred ciphersuites list, or NULL (applies only to TLSv1.3) */ - char* ciphersuites; + char *ciphersuites; } cliSSLconfig; @@ -41,11 +41,11 @@ int cliSecureInit(void); sds readArgFromStdin(void); -sds *getSdsArrayFromArgv(int argc,char **argv, int quoted); +sds *getSdsArrayFromArgv(int argc, char **argv, int quoted); sds unquoteCString(char *str); -void parseRedisUri(const char *uri, const char* tool_name, cliConnInfo *connInfo, int *tls_flag); +void parseRedisUri(const char *uri, const char *tool_name, cliConnInfo *connInfo, int *tls_flag); void freeCliConnInfo(cliConnInfo connInfo); diff --git a/src/cluster.c b/src/cluster.c index 99c02cd86..8b83b61d7 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -51,22 +51,32 @@ unsigned int keyHashSlot(char *key, int keylen) { int s, e; /* start-end indexes of { and } */ - for (s = 0; s < keylen; s++) - if (key[s] == '{') break; + for (s = 0; s < keylen; s++) { + if (key[s] == '{') { + break; + } + } /* No '{' ? Hash the whole key. This is the base case. */ - if (s == keylen) return crc16(key,keylen) & 0x3FFF; + if (s == keylen) { + return crc16(key, keylen) & 0x3FFF; + } /* '{' found? Check if we have the corresponding '}'. */ - for (e = s+1; e < keylen; e++) - if (key[e] == '}') break; + for (e = s + 1; e < keylen; e++) { + if (key[e] == '}') { + break; + } + } /* No '}' or nothing between {} ? Hash the whole key. */ - if (e == keylen || e == s+1) return crc16(key,keylen) & 0x3FFF; + if (e == keylen || e == s + 1) { + return crc16(key, keylen) & 0x3FFF; + } /* If we are here there is both a { and a } on its right. Hash * what is in the middle between { and }. */ - return crc16(key+s+1,e-s-1) & 0x3FFF; + return crc16(key + s + 1, e - s - 1) & 0x3FFF; } /* If it can be inferred that the given glob-style pattern, as implemented in @@ -119,9 +129,9 @@ void createDumpPayload(rio *payload, robj *o, robj *key, int dbid) { /* Serialize the object in an RDB-like format. It consist of an object type * byte followed by the serialized object. This is understood by RESTORE. */ - rioInitWithBuffer(payload,sdsempty()); - serverAssert(rdbSaveObjectType(payload,o)); - serverAssert(rdbSaveObject(payload,o,key,dbid)); + rioInitWithBuffer(payload, sdsempty()); + serverAssert(rdbSaveObjectType(payload, o)); + serverAssert(rdbSaveObject(payload, o, key, dbid)); /* Write the footer, this is how it looks like: * ----------------+---------------------+---------------+ @@ -133,13 +143,12 @@ void createDumpPayload(rio *payload, robj *o, robj *key, int dbid) { /* RDB version */ buf[0] = RDB_VERSION & 0xff; buf[1] = (RDB_VERSION >> 8) & 0xff; - payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr,buf,2); + payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr, buf, 2); /* CRC64 */ - crc = crc64(0,(unsigned char*)payload->io.buffer.ptr, - sdslen(payload->io.buffer.ptr)); + crc = crc64(0, (unsigned char *)payload->io.buffer.ptr, sdslen(payload->io.buffer.ptr)); memrev64ifbe(&crc); - payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr,&crc,8); + payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr, &crc, 8); } /* Verify that the RDB version of the dump payload matches the one of this @@ -153,23 +162,28 @@ int verifyDumpPayload(unsigned char *p, size_t len, uint16_t *rdbver_ptr) { uint64_t crc; /* At least 2 bytes of RDB version and 8 of CRC64 should be present. */ - if (len < 10) return C_ERR; - footer = p+(len-10); + if (len < 10) { + return C_ERR; + } + footer = p + (len - 10); /* Set and verify RDB version. */ rdbver = (footer[1] << 8) | footer[0]; if (rdbver_ptr) { *rdbver_ptr = rdbver; } - if (rdbver > RDB_VERSION) return C_ERR; + if (rdbver > RDB_VERSION) { + return C_ERR; + } - if (server.skip_checksum_validation) + if (server.skip_checksum_validation) { return C_OK; + } /* Verify CRC64 */ - crc = crc64(0,p,len-8); + crc = crc64(0, p, len - 8); memrev64ifbe(&crc); - return (memcmp(&crc,footer+2,8) == 0) ? C_OK : C_ERR; + return (memcmp(&crc, footer + 2, 8) == 0) ? C_OK : C_ERR; } /* DUMP keyname @@ -180,16 +194,16 @@ void dumpCommand(client *c) { rio payload; /* Check if the key is here. */ - if ((o = lookupKeyRead(c->db,c->argv[1])) == NULL) { + if ((o = lookupKeyRead(c->db, c->argv[1])) == NULL) { addReplyNull(c); return; } /* Create the DUMP encoded representation. */ - createDumpPayload(&payload,o,c->argv[1],c->db->id); + createDumpPayload(&payload, o, c->argv[1], c->db->id); /* Transfer to the client */ - addReplyBulkSds(c,payload.io.buffer.ptr); + addReplyBulkSds(c, payload.io.buffer.ptr); return; } @@ -202,80 +216,79 @@ void restoreCommand(client *c) { /* Parse additional options */ for (j = 4; j < c->argc; j++) { - int additional = c->argc-j-1; - if (!strcasecmp(c->argv[j]->ptr,"replace")) { + int additional = c->argc - j - 1; + if (!strcasecmp(c->argv[j]->ptr, "replace")) { replace = 1; - } else if (!strcasecmp(c->argv[j]->ptr,"absttl")) { + } else if (!strcasecmp(c->argv[j]->ptr, "absttl")) { absttl = 1; - } else if (!strcasecmp(c->argv[j]->ptr,"idletime") && additional >= 1 && - lfu_freq == -1) - { - if (getLongLongFromObjectOrReply(c,c->argv[j+1],&lru_idle,NULL) - != C_OK) return; + } else if (!strcasecmp(c->argv[j]->ptr, "idletime") && additional >= 1 && lfu_freq == -1) { + if (getLongLongFromObjectOrReply(c, c->argv[j + 1], &lru_idle, NULL) != C_OK) { + return; + } if (lru_idle < 0) { - addReplyError(c,"Invalid IDLETIME value, must be >= 0"); + addReplyError(c, "Invalid IDLETIME value, must be >= 0"); return; } lru_clock = LRU_CLOCK(); j++; /* Consume additional arg. */ - } else if (!strcasecmp(c->argv[j]->ptr,"freq") && additional >= 1 && - lru_idle == -1) - { - if (getLongLongFromObjectOrReply(c,c->argv[j+1],&lfu_freq,NULL) - != C_OK) return; + } else if (!strcasecmp(c->argv[j]->ptr, "freq") && additional >= 1 && lru_idle == -1) { + if (getLongLongFromObjectOrReply(c, c->argv[j + 1], &lfu_freq, NULL) != C_OK) { + return; + } if (lfu_freq < 0 || lfu_freq > 255) { - addReplyError(c,"Invalid FREQ value, must be >= 0 and <= 255"); + addReplyError(c, "Invalid FREQ value, must be >= 0 and <= 255"); return; } j++; /* Consume additional arg. */ } else { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } } /* Make sure this key does not already exist here... */ robj *key = c->argv[1]; - if (!replace && lookupKeyWrite(c->db,key) != NULL) { - addReplyErrorObject(c,shared.busykeyerr); + if (!replace && lookupKeyWrite(c->db, key) != NULL) { + addReplyErrorObject(c, shared.busykeyerr); return; } /* Check if the TTL value makes sense */ - if (getLongLongFromObjectOrReply(c,c->argv[2],&ttl,NULL) != C_OK) { + if (getLongLongFromObjectOrReply(c, c->argv[2], &ttl, NULL) != C_OK) { return; } else if (ttl < 0) { - addReplyError(c,"Invalid TTL value, must be >= 0"); + addReplyError(c, "Invalid TTL value, must be >= 0"); return; } /* Verify RDB version and data checksum. */ - if (verifyDumpPayload(c->argv[3]->ptr,sdslen(c->argv[3]->ptr),NULL) == C_ERR) - { - addReplyError(c,"DUMP payload version or checksum are wrong"); + if (verifyDumpPayload(c->argv[3]->ptr, sdslen(c->argv[3]->ptr), NULL) == C_ERR) { + addReplyError(c, "DUMP payload version or checksum are wrong"); return; } - rioInitWithBuffer(&payload,c->argv[3]->ptr); + rioInitWithBuffer(&payload, c->argv[3]->ptr); if (((type = rdbLoadObjectType(&payload)) == -1) || - ((obj = rdbLoadObject(type,&payload,key->ptr,c->db->id,NULL)) == NULL)) - { - addReplyError(c,"Bad data format"); + ((obj = rdbLoadObject(type, &payload, key->ptr, c->db->id, NULL)) == NULL)) { + addReplyError(c, "Bad data format"); return; } /* Remove the old key if needed. */ int deleted = 0; - if (replace) - deleted = dbDelete(c->db,key); + if (replace) { + deleted = dbDelete(c->db, key); + } - if (ttl && !absttl) ttl+=commandTimeSnapshot(); + if (ttl && !absttl) { + ttl += commandTimeSnapshot(); + } if (ttl && checkAlreadyExpired(ttl)) { if (deleted) { robj *aux = server.lazyfree_lazy_server_del ? shared.unlink : shared.del; rewriteClientCommandVector(c, 2, aux, key); - signalModifiedKey(c,c->db,key); - notifyKeyspaceEvent(NOTIFY_GENERIC,"del",key,c->db->id); + signalModifiedKey(c, c->db, key); + notifyKeyspaceEvent(NOTIFY_GENERIC, "del", key, c->db->id); server.dirty++; } decrRefCount(obj); @@ -284,21 +297,21 @@ void restoreCommand(client *c) { } /* Create the key and set the TTL if any */ - dbAdd(c->db,key,obj); + dbAdd(c->db, key, obj); if (ttl) { - setExpire(c,c->db,key,ttl); + setExpire(c, c->db, key, ttl); if (!absttl) { /* Propagate TTL as absolute timestamp */ robj *ttl_obj = createStringObjectFromLongLong(ttl); - rewriteClientCommandArgument(c,2,ttl_obj); + rewriteClientCommandArgument(c, 2, ttl_obj); decrRefCount(ttl_obj); - rewriteClientCommandArgument(c,c->argc,shared.absttl); + rewriteClientCommandArgument(c, c->argc, shared.absttl); } } - objectSetLRUOrLFU(obj,lfu_freq,lru_idle,lru_clock,1000); - signalModifiedKey(c,c->db,key); - notifyKeyspaceEvent(NOTIFY_GENERIC,"restore",key,c->db->id); - addReply(c,shared.ok); + objectSetLRUOrLFU(obj, lfu_freq, lru_idle, lru_clock, 1000); + signalModifiedKey(c, c->db, key); + notifyKeyspaceEvent(NOTIFY_GENERIC, "restore", key, c->db->id); + addReply(c, shared.ok); server.dirty++; } /* MIGRATE socket cache implementation. @@ -308,7 +321,7 @@ void restoreCommand(client *c) { * This sockets are closed when the max number we cache is reached, and also * in serverCron() when they are around for more than a few seconds. */ #define MIGRATE_SOCKET_CACHE_ITEMS 64 /* max num of items in the cache. */ -#define MIGRATE_SOCKET_CACHE_TTL 10 /* close cached sockets after 10 sec. */ +#define MIGRATE_SOCKET_CACHE_TTL 10 /* close cached sockets after 10 sec. */ typedef struct migrateCachedSocket { connection *conn; @@ -327,16 +340,16 @@ typedef struct migrateCachedSocket { * If the caller detects an error while using the socket, migrateCloseSocket() * should be called so that the connection will be created from scratch * the next time. */ -migrateCachedSocket* migrateGetSocket(client *c, robj *host, robj *port, long timeout) { +migrateCachedSocket *migrateGetSocket(client *c, robj *host, robj *port, long timeout) { connection *conn; sds name = sdsempty(); migrateCachedSocket *cs; /* Check if we have an already cached socket for this ip:port pair. */ - name = sdscatlen(name,host->ptr,sdslen(host->ptr)); - name = sdscatlen(name,":",1); - name = sdscatlen(name,port->ptr,sdslen(port->ptr)); - cs = dictFetchValue(server.migrate_cached_sockets,name); + name = sdscatlen(name, host->ptr, sdslen(host->ptr)); + name = sdscatlen(name, ":", 1); + name = sdscatlen(name, port->ptr, sdslen(port->ptr)); + cs = dictFetchValue(server.migrate_cached_sockets, name); if (cs) { sdsfree(name); cs->last_use_time = server.unixtime; @@ -350,14 +363,13 @@ migrateCachedSocket* migrateGetSocket(client *c, robj *host, robj *port, long ti cs = dictGetVal(de); connClose(cs->conn); zfree(cs); - dictDelete(server.migrate_cached_sockets,dictGetKey(de)); + dictDelete(server.migrate_cached_sockets, dictGetKey(de)); } /* Create the connection */ conn = connCreate(connTypeOfCluster()); - if (connBlockingConnect(conn, host->ptr, atoi(port->ptr), timeout) - != C_OK) { - addReplyError(c,"-IOERR error or timeout connecting to the client"); + if (connBlockingConnect(conn, host->ptr, atoi(port->ptr), timeout) != C_OK) { + addReplyError(c, "-IOERR error or timeout connecting to the client"); connClose(conn); sdsfree(name); return NULL; @@ -370,7 +382,7 @@ migrateCachedSocket* migrateGetSocket(client *c, robj *host, robj *port, long ti cs->last_dbid = -1; cs->last_use_time = server.unixtime; - dictAdd(server.migrate_cached_sockets,name,cs); + dictAdd(server.migrate_cached_sockets, name, cs); return cs; } @@ -379,10 +391,10 @@ void migrateCloseSocket(robj *host, robj *port) { sds name = sdsempty(); migrateCachedSocket *cs; - name = sdscatlen(name,host->ptr,sdslen(host->ptr)); - name = sdscatlen(name,":",1); - name = sdscatlen(name,port->ptr,sdslen(port->ptr)); - cs = dictFetchValue(server.migrate_cached_sockets,name); + name = sdscatlen(name, host->ptr, sdslen(host->ptr)); + name = sdscatlen(name, ":", 1); + name = sdscatlen(name, port->ptr, sdslen(port->ptr)); + cs = dictFetchValue(server.migrate_cached_sockets, name); if (!cs) { sdsfree(name); return; @@ -390,7 +402,7 @@ void migrateCloseSocket(robj *host, robj *port) { connClose(cs->conn); zfree(cs); - dictDelete(server.migrate_cached_sockets,name); + dictDelete(server.migrate_cached_sockets, name); sdsfree(name); } @@ -398,13 +410,13 @@ void migrateCloseTimedoutSockets(void) { dictIterator *di = dictGetSafeIterator(server.migrate_cached_sockets); dictEntry *de; - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { migrateCachedSocket *cs = dictGetVal(de); if ((server.unixtime - cs->last_use_time) > MIGRATE_SOCKET_CACHE_TTL) { connClose(cs->conn); zfree(cs); - dictDelete(server.migrate_cached_sockets,dictGetKey(de)); + dictDelete(server.migrate_cached_sockets, dictGetKey(de)); } } dictReleaseIterator(di); @@ -424,8 +436,8 @@ void migrateCommand(client *c) { char *password = NULL; long timeout; long dbid; - robj **ov = NULL; /* Objects to migrate. */ - robj **kv = NULL; /* Key names. */ + robj **ov = NULL; /* Objects to migrate. */ + robj **kv = NULL; /* Key names. */ robj **newargv = NULL; /* Used to rewrite the command as DEL ... keys ... */ rio cmd, payload; int may_retry = 1; @@ -438,105 +450,105 @@ void migrateCommand(client *c) { /* Parse additional options */ for (j = 6; j < c->argc; j++) { - int moreargs = (c->argc-1) - j; - if (!strcasecmp(c->argv[j]->ptr,"copy")) { + int moreargs = (c->argc - 1) - j; + if (!strcasecmp(c->argv[j]->ptr, "copy")) { copy = 1; - } else if (!strcasecmp(c->argv[j]->ptr,"replace")) { + } else if (!strcasecmp(c->argv[j]->ptr, "replace")) { replace = 1; - } else if (!strcasecmp(c->argv[j]->ptr,"auth")) { + } else if (!strcasecmp(c->argv[j]->ptr, "auth")) { if (!moreargs) { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } j++; password = c->argv[j]->ptr; - redactClientCommandArgument(c,j); - } else if (!strcasecmp(c->argv[j]->ptr,"auth2")) { + redactClientCommandArgument(c, j); + } else if (!strcasecmp(c->argv[j]->ptr, "auth2")) { if (moreargs < 2) { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } username = c->argv[++j]->ptr; - redactClientCommandArgument(c,j); + redactClientCommandArgument(c, j); password = c->argv[++j]->ptr; - redactClientCommandArgument(c,j); - } else if (!strcasecmp(c->argv[j]->ptr,"keys")) { + redactClientCommandArgument(c, j); + } else if (!strcasecmp(c->argv[j]->ptr, "keys")) { if (sdslen(c->argv[3]->ptr) != 0) { - addReplyError(c, - "When using MIGRATE KEYS option, the key argument" - " must be set to the empty string"); + addReplyError(c, "When using MIGRATE KEYS option, the key argument" + " must be set to the empty string"); return; } - first_key = j+1; + first_key = j + 1; num_keys = c->argc - j - 1; break; /* All the remaining args are keys. */ } else { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } } /* Sanity check */ - if (getLongFromObjectOrReply(c,c->argv[5],&timeout,NULL) != C_OK || - getLongFromObjectOrReply(c,c->argv[4],&dbid,NULL) != C_OK) - { + if (getLongFromObjectOrReply(c, c->argv[5], &timeout, NULL) != C_OK || + getLongFromObjectOrReply(c, c->argv[4], &dbid, NULL) != C_OK) { return; } - if (timeout <= 0) timeout = 1000; + if (timeout <= 0) { + timeout = 1000; + } /* Check if the keys are here. If at least one key is to migrate, do it * otherwise if all the keys are missing reply with "NOKEY" to signal * the caller there was nothing to migrate. We don't return an error in * this case, since often this is due to a normal condition like the key * expiring in the meantime. */ - ov = zrealloc(ov,sizeof(robj*)*num_keys); - kv = zrealloc(kv,sizeof(robj*)*num_keys); + ov = zrealloc(ov, sizeof(robj *) * num_keys); + kv = zrealloc(kv, sizeof(robj *) * num_keys); int oi = 0; for (j = 0; j < num_keys; j++) { - if ((ov[oi] = lookupKeyRead(c->db,c->argv[first_key+j])) != NULL) { - kv[oi] = c->argv[first_key+j]; + if ((ov[oi] = lookupKeyRead(c->db, c->argv[first_key + j])) != NULL) { + kv[oi] = c->argv[first_key + j]; oi++; } } num_keys = oi; if (num_keys == 0) { - zfree(ov); zfree(kv); - addReplySds(c,sdsnew("+NOKEY\r\n")); + zfree(ov); + zfree(kv); + addReplySds(c, sdsnew("+NOKEY\r\n")); return; } - try_again: +try_again: write_error = 0; /* Connect */ - cs = migrateGetSocket(c,c->argv[1],c->argv[2],timeout); + cs = migrateGetSocket(c, c->argv[1], c->argv[2], timeout); if (cs == NULL) { - zfree(ov); zfree(kv); + zfree(ov); + zfree(kv); return; /* error sent to the client by migrateGetSocket() */ } - rioInitWithBuffer(&cmd,sdsempty()); + rioInitWithBuffer(&cmd, sdsempty()); /* Authentication */ if (password) { int arity = username ? 3 : 2; - serverAssertWithInfo(c,NULL,rioWriteBulkCount(&cmd,'*',arity)); - serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"AUTH",4)); + serverAssertWithInfo(c, NULL, rioWriteBulkCount(&cmd, '*', arity)); + serverAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, "AUTH", 4)); if (username) { - serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,username, - sdslen(username))); + serverAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, username, sdslen(username))); } - serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,password, - sdslen(password))); + serverAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, password, sdslen(password))); } /* Send the SELECT command if the current DB is not already selected. */ int select = cs->last_dbid != dbid; /* Should we emit SELECT? */ if (select) { - serverAssertWithInfo(c,NULL,rioWriteBulkCount(&cmd,'*',2)); - serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"SELECT",6)); - serverAssertWithInfo(c,NULL,rioWriteBulkLongLong(&cmd,dbid)); + serverAssertWithInfo(c, NULL, rioWriteBulkCount(&cmd, '*', 2)); + serverAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, "SELECT", 6)); + serverAssertWithInfo(c, NULL, rioWriteBulkLongLong(&cmd, dbid)); } int non_expired = 0; /* Number of keys that we'll find non expired. @@ -547,14 +559,16 @@ void migrateCommand(client *c) { /* Create RESTORE payload and generate the protocol to call the command. */ for (j = 0; j < num_keys; j++) { long long ttl = 0; - long long expireat = getExpire(c->db,kv[j]); + long long expireat = getExpire(c->db, kv[j]); if (expireat != -1) { - ttl = expireat-commandTimeSnapshot(); + ttl = expireat - commandTimeSnapshot(); if (ttl < 0) { continue; } - if (ttl < 1) ttl = 1; + if (ttl < 1) { + ttl = 1; + } } /* Relocate valid (non expired) keys and values into the array in successive @@ -563,31 +577,28 @@ void migrateCommand(client *c) { ov[non_expired] = ov[j]; kv[non_expired++] = kv[j]; - serverAssertWithInfo(c,NULL, - rioWriteBulkCount(&cmd,'*',replace ? 5 : 4)); + serverAssertWithInfo(c, NULL, rioWriteBulkCount(&cmd, '*', replace ? 5 : 4)); - if (server.cluster_enabled) - serverAssertWithInfo(c,NULL, - rioWriteBulkString(&cmd,"RESTORE-ASKING",14)); - else - serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"RESTORE",7)); - serverAssertWithInfo(c,NULL,sdsEncodedObject(kv[j])); - serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,kv[j]->ptr, - sdslen(kv[j]->ptr))); - serverAssertWithInfo(c,NULL,rioWriteBulkLongLong(&cmd,ttl)); + if (server.cluster_enabled) { + serverAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, "RESTORE-ASKING", 14)); + } else { + serverAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, "RESTORE", 7)); + } + serverAssertWithInfo(c, NULL, sdsEncodedObject(kv[j])); + serverAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, kv[j]->ptr, sdslen(kv[j]->ptr))); + serverAssertWithInfo(c, NULL, rioWriteBulkLongLong(&cmd, ttl)); /* Emit the payload argument, that is the serialized object using * the DUMP format. */ - createDumpPayload(&payload,ov[j],kv[j],dbid); - serverAssertWithInfo(c,NULL, - rioWriteBulkString(&cmd,payload.io.buffer.ptr, - sdslen(payload.io.buffer.ptr))); + createDumpPayload(&payload, ov[j], kv[j], dbid); + serverAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, payload.io.buffer.ptr, sdslen(payload.io.buffer.ptr))); sdsfree(payload.io.buffer.ptr); /* Add the REPLACE option to the RESTORE command if it was specified * as a MIGRATE option. */ - if (replace) - serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"REPLACE",7)); + if (replace) { + serverAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, "REPLACE", 7)); + } } /* Fix the actual number of keys we are migrating. */ @@ -600,9 +611,9 @@ void migrateCommand(client *c) { size_t pos = 0, towrite; int nwritten = 0; - while ((towrite = sdslen(buf)-pos) > 0) { - towrite = (towrite > (64*1024) ? (64*1024) : towrite); - nwritten = connSyncWrite(cs->conn,buf+pos,towrite,timeout); + while ((towrite = sdslen(buf) - pos) > 0) { + towrite = (towrite > (64 * 1024) ? (64 * 1024) : towrite); + nwritten = connSyncWrite(cs->conn, buf + pos, towrite, timeout); if (nwritten != (signed)towrite) { write_error = 1; goto socket_err; @@ -616,12 +627,14 @@ void migrateCommand(client *c) { char buf2[1024]; /* Restore reply. */ /* Read the AUTH reply if needed. */ - if (password && connSyncReadLine(cs->conn, buf0, sizeof(buf0), timeout) <= 0) + if (password && connSyncReadLine(cs->conn, buf0, sizeof(buf0), timeout) <= 0) { goto socket_err; + } /* Read the SELECT reply if needed. */ - if (select && connSyncReadLine(cs->conn, buf1, sizeof(buf1), timeout) <= 0) + if (select && connSyncReadLine(cs->conn, buf1, sizeof(buf1), timeout) <= 0) { goto socket_err; + } /* Read the RESTORE replies. */ int error_from_target = 0; @@ -632,35 +645,37 @@ void migrateCommand(client *c) { * to propagate the MIGRATE as a DEL command (if no COPY option was given). * We allocate num_keys+1 because the additional argument is for "DEL" * command name itself. */ - if (!copy) newargv = zmalloc(sizeof(robj*)*(num_keys+1)); + if (!copy) { + newargv = zmalloc(sizeof(robj *) * (num_keys + 1)); + } for (j = 0; j < num_keys; j++) { if (connSyncReadLine(cs->conn, buf2, sizeof(buf2), timeout) <= 0) { socket_error = 1; break; } - if ((password && buf0[0] == '-') || - (select && buf1[0] == '-') || - buf2[0] == '-') - { + if ((password && buf0[0] == '-') || (select && buf1[0] == '-') || buf2[0] == '-') { /* On error assume that last_dbid is no longer valid. */ if (!error_from_target) { cs->last_dbid = -1; char *errbuf; - if (password && buf0[0] == '-') errbuf = buf0; - else if (select && buf1[0] == '-') errbuf = buf1; - else errbuf = buf2; + if (password && buf0[0] == '-') { + errbuf = buf0; + } else if (select && buf1[0] == '-') { + errbuf = buf1; + } else { + errbuf = buf2; + } error_from_target = 1; - addReplyErrorFormat(c,"Target instance replied with error: %s", - errbuf+1); + addReplyErrorFormat(c, "Target instance replied with error: %s", errbuf + 1); } } else { if (!copy) { /* No COPY option: remove the local key, signal the change. */ - dbDelete(c->db,kv[j]); - signalModifiedKey(c,c->db,kv[j]); - notifyKeyspaceEvent(NOTIFY_GENERIC,"del",kv[j],c->db->id); + dbDelete(c->db, kv[j]); + signalModifiedKey(c, c->db, kv[j]); + notifyKeyspaceEvent(NOTIFY_GENERIC, "del", kv[j], c->db->id); server.dirty++; /* Populate the argument vector to replace the old one. */ @@ -673,25 +688,25 @@ void migrateCommand(client *c) { /* On socket error, if we want to retry, do it now before rewriting the * command vector. We only retry if we are sure nothing was processed * and we failed to read the first reply (j == 0 test). */ - if (!error_from_target && socket_error && j == 0 && may_retry && - errno != ETIMEDOUT) - { + if (!error_from_target && socket_error && j == 0 && may_retry && errno != ETIMEDOUT) { goto socket_err; /* A retry is guaranteed because of tested conditions.*/ } /* On socket errors, close the migration socket now that we still have * the original host/port in the ARGV. Later the original command may be * rewritten to DEL and will be too later. */ - if (socket_error) migrateCloseSocket(c->argv[1],c->argv[2]); + if (socket_error) { + migrateCloseSocket(c->argv[1], c->argv[2]); + } if (!copy) { /* Translate MIGRATE as DEL for replication/AOF. Note that we do * this only for the keys for which we received an acknowledgement * from the receiving server, by using the del_idx index. */ if (del_idx > 1) { - newargv[0] = createStringObject("DEL",3); + newargv[0] = createStringObject("DEL", 3); /* Note that the following call takes ownership of newargv. */ - replaceClientCommandVector(c,del_idx,newargv); + replaceClientCommandVector(c, del_idx, newargv); argv_rewritten = 1; } else { /* No key transfer acknowledged, no need to rewrite as DEL. */ @@ -716,20 +731,22 @@ void migrateCommand(client *c) { * still the SELECT command succeeded (otherwise the code jumps to * socket_err label. */ cs->last_dbid = dbid; - addReply(c,shared.ok); + addReply(c, shared.ok); } else { /* On error we already sent it in the for loop above, and set * the currently selected socket to -1 to force SELECT the next time. */ } sdsfree(cmd.io.buffer.ptr); - zfree(ov); zfree(kv); zfree(newargv); + zfree(ov); + zfree(kv); + zfree(newargv); return; -/* On socket errors we try to close the cached socket and try again. - * It is very common for the cached socket to get closed, if just reopening - * it works it's a shame to notify the error to the caller. */ - socket_err: + /* On socket errors we try to close the cached socket and try again. + * It is very common for the cached socket to get closed, if just reopening + * it works it's a shame to notify the error to the caller. */ +socket_err: /* Cleanup we want to perform in both the retry and no retry case. * Note: Closing the migrate socket will also force SELECT next time. */ sdsfree(cmd.io.buffer.ptr); @@ -738,7 +755,9 @@ void migrateCommand(client *c) { * we already closed the socket earlier. While migrateCloseSocket() * is idempotent, the host/port arguments are now gone, so don't do it * again. */ - if (!argv_rewritten) migrateCloseSocket(c->argv[1],c->argv[2]); + if (!argv_rewritten) { + migrateCloseSocket(c->argv[1], c->argv[2]); + } zfree(newargv); newargv = NULL; /* This will get reallocated on retry. */ @@ -750,9 +769,9 @@ void migrateCommand(client *c) { } /* Cleanup we want to do if no retry is attempted. */ - zfree(ov); zfree(kv); - addReplyErrorSds(c, sdscatprintf(sdsempty(), - "-IOERR error or timeout %s to target instance", + zfree(ov); + zfree(kv); + addReplyErrorSds(c, sdscatprintf(sdsempty(), "-IOERR error or timeout %s to target instance", write_error ? "writing" : "reading")); return; } @@ -760,10 +779,16 @@ void migrateCommand(client *c) { /* Cluster node sanity check. Returns C_OK if the node id * is valid an C_ERR otherwise. */ int verifyClusterNodeId(const char *name, int length) { - if (length != CLUSTER_NAMELEN) return C_ERR; + if (length != CLUSTER_NAMELEN) { + return C_ERR; + } for (int i = 0; i < length; i++) { - if (name[i] >= 'a' && name[i] <= 'z') continue; - if (name[i] >= '0' && name[i] <= '9') continue; + if (name[i] >= 'a' && name[i] <= 'z') { + continue; + } + if (name[i] >= '0' && name[i] <= '9') { + continue; + } return C_ERR; } return C_OK; @@ -775,7 +800,9 @@ int isValidAuxChar(int c) { int isValidAuxString(char *s, unsigned int length) { for (unsigned i = 0; i < length; i++) { - if (!isValidAuxChar(s[i])) return 0; + if (!isValidAuxChar(s[i])) { + return 0; + } } return 1; } @@ -783,20 +810,20 @@ int isValidAuxString(char *s, unsigned int length) { void clusterCommandMyId(client *c) { char *name = clusterNodeGetName(getMyClusterNode()); if (name) { - addReplyBulkCBuffer(c,name, CLUSTER_NAMELEN); + addReplyBulkCBuffer(c, name, CLUSTER_NAMELEN); } else { addReplyError(c, "No ID yet"); } } -char* getMyClusterId(void) { +char *getMyClusterId(void) { return clusterNodeGetName(getMyClusterNode()); } void clusterCommandMyShardId(client *c) { char *sid = clusterNodeGetShardId(getMyClusterNode()); if (sid) { - addReplyBulkCBuffer(c,sid, CLUSTER_NAMELEN); + addReplyBulkCBuffer(c, sid, CLUSTER_NAMELEN); } else { addReplyError(c, "No shard ID yet"); } @@ -822,101 +849,102 @@ unsigned int countKeysInSlot(unsigned int slot) { void clusterCommandHelp(client *c) { const char *help[] = { - "COUNTKEYSINSLOT ", - " Return the number of keys in .", - "GETKEYSINSLOT ", - " Return key names stored by current node in a slot.", - "INFO", - " Return information about the cluster.", - "KEYSLOT ", - " Return the hash slot for .", - "MYID", - " Return the node id.", - "MYSHARDID", - " Return the node's shard id.", - "NODES", - " Return cluster configuration seen by node. Output format:", - " ...", - "REPLICAS ", - " Return replicas.", - "SLOTS", - " Return information about slots range mappings. Each range is made of:", - " start, end, master and replicas IP addresses, ports and ids", - "SHARDS", - " Return information about slot range mappings and the nodes associated with them.", - NULL - }; + "COUNTKEYSINSLOT ", + " Return the number of keys in .", + "GETKEYSINSLOT ", + " Return key names stored by current node in a slot.", + "INFO", + " Return information about the cluster.", + "KEYSLOT ", + " Return the hash slot for .", + "MYID", + " Return the node id.", + "MYSHARDID", + " Return the node's shard id.", + "NODES", + " Return cluster configuration seen by node. Output format:", + " ...", + "REPLICAS ", + " Return replicas.", + "SLOTS", + " Return information about slots range mappings. Each range is made of:", + " start, end, master and replicas IP addresses, ports and ids", + "SHARDS", + " Return information about slot range mappings and the nodes associated with them.", + NULL}; addExtendedReplyHelp(c, help, clusterCommandExtendedHelp()); } void clusterCommand(client *c) { if (server.cluster_enabled == 0) { - addReplyError(c,"This instance has cluster support disabled"); + addReplyError(c, "This instance has cluster support disabled"); return; } - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"help")) { + if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "help")) { clusterCommandHelp(c); - } else if (!strcasecmp(c->argv[1]->ptr,"nodes") && c->argc == 2) { + } else if (!strcasecmp(c->argv[1]->ptr, "nodes") && c->argc == 2) { /* CLUSTER NODES */ /* Report TLS ports to TLS client, and report non-TLS port to non-TLS client. */ sds nodes = clusterGenNodesDescription(c, 0, shouldReturnTlsInfo()); - addReplyVerbatim(c,nodes,sdslen(nodes),"txt"); + addReplyVerbatim(c, nodes, sdslen(nodes), "txt"); sdsfree(nodes); - } else if (!strcasecmp(c->argv[1]->ptr,"myid") && c->argc == 2) { + } else if (!strcasecmp(c->argv[1]->ptr, "myid") && c->argc == 2) { /* CLUSTER MYID */ clusterCommandMyId(c); - } else if (!strcasecmp(c->argv[1]->ptr,"myshardid") && c->argc == 2) { + } else if (!strcasecmp(c->argv[1]->ptr, "myshardid") && c->argc == 2) { /* CLUSTER MYSHARDID */ clusterCommandMyShardId(c); - } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { + } else if (!strcasecmp(c->argv[1]->ptr, "slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterCommandSlots(c); - } else if (!strcasecmp(c->argv[1]->ptr,"shards") && c->argc == 2) { + } else if (!strcasecmp(c->argv[1]->ptr, "shards") && c->argc == 2) { /* CLUSTER SHARDS */ clusterCommandShards(c); - } else if (!strcasecmp(c->argv[1]->ptr,"info") && c->argc == 2) { + } else if (!strcasecmp(c->argv[1]->ptr, "info") && c->argc == 2) { /* CLUSTER INFO */ sds info = genClusterInfoString(); /* Produce the reply protocol. */ - addReplyVerbatim(c,info,sdslen(info),"txt"); + addReplyVerbatim(c, info, sdslen(info), "txt"); sdsfree(info); - } else if (!strcasecmp(c->argv[1]->ptr,"keyslot") && c->argc == 3) { + } else if (!strcasecmp(c->argv[1]->ptr, "keyslot") && c->argc == 3) { /* CLUSTER KEYSLOT */ sds key = c->argv[2]->ptr; - addReplyLongLong(c,keyHashSlot(key,sdslen(key))); - } else if (!strcasecmp(c->argv[1]->ptr,"countkeysinslot") && c->argc == 3) { + addReplyLongLong(c, keyHashSlot(key, sdslen(key))); + } else if (!strcasecmp(c->argv[1]->ptr, "countkeysinslot") && c->argc == 3) { /* CLUSTER COUNTKEYSINSLOT */ long long slot; - if (getLongLongFromObjectOrReply(c,c->argv[2],&slot,NULL) != C_OK) + if (getLongLongFromObjectOrReply(c, c->argv[2], &slot, NULL) != C_OK) { return; + } if (slot < 0 || slot >= CLUSTER_SLOTS) { - addReplyError(c,"Invalid slot"); + addReplyError(c, "Invalid slot"); return; } - addReplyLongLong(c,countKeysInSlot(slot)); - } else if (!strcasecmp(c->argv[1]->ptr,"getkeysinslot") && c->argc == 4) { + addReplyLongLong(c, countKeysInSlot(slot)); + } else if (!strcasecmp(c->argv[1]->ptr, "getkeysinslot") && c->argc == 4) { /* CLUSTER GETKEYSINSLOT */ long long maxkeys, slot; - if (getLongLongFromObjectOrReply(c,c->argv[2],&slot,NULL) != C_OK) + if (getLongLongFromObjectOrReply(c, c->argv[2], &slot, NULL) != C_OK) { return; - if (getLongLongFromObjectOrReply(c,c->argv[3],&maxkeys,NULL) - != C_OK) + } + if (getLongLongFromObjectOrReply(c, c->argv[3], &maxkeys, NULL) != C_OK) { return; + } if (slot < 0 || slot >= CLUSTER_SLOTS || maxkeys < 0) { - addReplyError(c,"Invalid slot or number of keys"); + addReplyError(c, "Invalid slot or number of keys"); return; } unsigned int keys_in_slot = countKeysInSlot(slot); unsigned int numkeys = maxkeys > keys_in_slot ? keys_in_slot : maxkeys; - addReplyArrayLen(c,numkeys); + addReplyArrayLen(c, numkeys); kvstoreDictIterator *kvs_di = NULL; dictEntry *de = NULL; kvs_di = kvstoreGetDictIterator(server.db->keys, slot); @@ -927,8 +955,7 @@ void clusterCommand(client *c) { addReplyBulkCBuffer(c, sdskey, sdslen(sdskey)); } kvstoreReleaseDictIterator(kvs_di); - } else if ((!strcasecmp(c->argv[1]->ptr,"slaves") || - !strcasecmp(c->argv[1]->ptr,"replicas")) && c->argc == 3) { + } else if ((!strcasecmp(c->argv[1]->ptr, "slaves") || !strcasecmp(c->argv[1]->ptr, "replicas")) && c->argc == 3) { /* CLUSTER SLAVES */ /* CLUSTER REPLICAS */ clusterNode *n = clusterLookupNode(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); @@ -936,12 +963,12 @@ void clusterCommand(client *c) { /* Lookup the specified node in our table. */ if (!n) { - addReplyErrorFormat(c,"Unknown node %s", (char*)c->argv[2]->ptr); + addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[2]->ptr); return; } if (clusterNodeIsSlave(n)) { - addReplyError(c,"The specified node is not a master"); + addReplyError(c, "The specified node is not a master"); return; } @@ -949,10 +976,10 @@ void clusterCommand(client *c) { addReplyArrayLen(c, clusterNodeNumSlaves(n)); for (j = 0; j < clusterNodeNumSlaves(n); j++) { sds ni = clusterGenNodeDescription(c, clusterNodeGetSlave(n, j), shouldReturnTlsInfo()); - addReplyBulkCString(c,ni); + addReplyBulkCString(c, ni); sdsfree(ni); } - } else if(!clusterCommandSpecial(c)) { + } else if (!clusterCommandSpecial(c)) { addReplySubcommandSyntaxError(c); return; } @@ -990,22 +1017,25 @@ void clusterCommand(client *c) { * * CLUSTER_REDIR_DOWN_STATE and CLUSTER_REDIR_DOWN_RO_STATE if the cluster is * down but the user attempts to execute a command that addresses one or more keys. */ -clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, int argc, int *hashslot, int *error_code) { +clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, int argc, int *hashslot, + int *error_code) { clusterNode *myself = getMyClusterNode(); clusterNode *n = NULL; robj *firstkey = NULL; int multiple_keys = 0; multiState *ms, _ms; multiCmd mc; - int i, slot = 0, migrating_slot = 0, importing_slot = 0, missing_keys = 0, - existing_keys = 0; + int i, slot = 0, migrating_slot = 0, importing_slot = 0, missing_keys = 0, existing_keys = 0; /* Allow any key to be set if a module disabled cluster redirections. */ - if (server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_REDIRECTION) + if (server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_REDIRECTION) { return myself; + } /* Set error code optimistically for the base case. */ - if (error_code) *error_code = CLUSTER_REDIR_NONE; + if (error_code) { + *error_code = CLUSTER_REDIR_NONE; + } /* Modules can turn off Cluster redirection: this is useful * when writing a module that implements a completely different @@ -1016,7 +1046,9 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i if (cmd->proc == execCommand) { /* If CLIENT_MULTI flag is not set EXEC is just going to return an * error. */ - if (!(c->flags & CLIENT_MULTI)) return myself; + if (!(c->flags & CLIENT_MULTI)) { + return myself; + } ms = &c->mstate; } else { /* In order to have a single codepath create a fake Multi State @@ -1031,10 +1063,10 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i } uint64_t cmd_flags = getCommandFlags(c); - + /* Only valid for sharded pubsub as regular pubsub can operate on any node and bypasses this layer. */ - int pubsubshard_included = (cmd_flags & CMD_PUBSUB) || - (c->cmd->proc == execCommand && (c->mstate.cmd_flags & CMD_PUBSUB)); + int pubsubshard_included = + (cmd_flags & CMD_PUBSUB) || (c->cmd->proc == execCommand && (c->mstate.cmd_flags & CMD_PUBSUB)); /* Check that all the keys are in the same hash slot, and obtain this * slot and the node associated. */ @@ -1049,13 +1081,12 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i margv = ms->commands[i].argv; getKeysResult result = GETKEYS_RESULT_INIT; - numkeys = getKeysFromCommand(mcmd,margv,margc,&result); + numkeys = getKeysFromCommand(mcmd, margv, margc, &result); keyindex = result.keys; for (j = 0; j < numkeys; j++) { robj *thiskey = margv[keyindex[j].pos]; - int thisslot = keyHashSlot((char*)thiskey->ptr, - sdslen(thiskey->ptr)); + int thisslot = keyHashSlot((char *)thiskey->ptr, sdslen(thiskey->ptr)); if (firstkey == NULL) { /* This is the first key we see. Check what is the slot @@ -1070,8 +1101,9 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i * error to the client. */ if (n == NULL) { getKeysFreeResult(&result); - if (error_code) + if (error_code) { *error_code = CLUSTER_REDIR_DOWN_UNBOUND; + } return NULL; } @@ -1080,9 +1112,7 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i * can safely serve the request, otherwise we return a TRYAGAIN * error). To do so we set the importing/migrating state and * increment a counter for every missing key. */ - if (n == myself && - getMigratingSlotDest(slot) != NULL) - { + if (n == myself && getMigratingSlotDest(slot) != NULL) { migrating_slot = 1; } else if (getImportingSlotSource(slot) != NULL) { importing_slot = 1; @@ -1093,11 +1123,12 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i if (slot != thisslot) { /* Error: multiple keys from different slots. */ getKeysFreeResult(&result); - if (error_code) + if (error_code) { *error_code = CLUSTER_REDIR_CROSS_SLOT; + } return NULL; } - if (importing_slot && !multiple_keys && !equalStringObjects(firstkey,thiskey)) { + if (importing_slot && !multiple_keys && !equalStringObjects(firstkey, thiskey)) { /* Flag this request as one with multiple different * keys/channels when the slot is in importing state. */ multiple_keys = 1; @@ -1111,10 +1142,12 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i * node until the migration completes with CLUSTER SETSLOT * NODE . */ int flags = LOOKUP_NOTOUCH | LOOKUP_NOSTATS | LOOKUP_NONOTIFY | LOOKUP_NOEXPIRE; - if ((migrating_slot || importing_slot) && !pubsubshard_included) - { - if (lookupKeyReadWithFlags(&server.db[0], thiskey, flags) == NULL) missing_keys++; - else existing_keys++; + if ((migrating_slot || importing_slot) && !pubsubshard_included) { + if (lookupKeyReadWithFlags(&server.db[0], thiskey, flags) == NULL) { + missing_keys++; + } else { + existing_keys++; + } } } getKeysFreeResult(&result); @@ -1122,24 +1155,32 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i /* No key at all in command? then we can serve the request * without redirections or errors in all the cases. */ - if (n == NULL) return myself; + if (n == NULL) { + return myself; + } /* Cluster is globally down but we got keys? We only serve the request * if it is a read command and when allow_reads_when_down is enabled. */ if (!isClusterHealthy()) { if (pubsubshard_included) { if (!server.cluster_allow_pubsubshard_when_down) { - if (error_code) *error_code = CLUSTER_REDIR_DOWN_STATE; + if (error_code) { + *error_code = CLUSTER_REDIR_DOWN_STATE; + } return NULL; } } else if (!server.cluster_allow_reads_when_down) { /* The cluster is configured to block commands when the * cluster is down. */ - if (error_code) *error_code = CLUSTER_REDIR_DOWN_STATE; + if (error_code) { + *error_code = CLUSTER_REDIR_DOWN_STATE; + } return NULL; } else if (cmd_flags & CMD_WRITE) { /* The cluster is configured to allow read only commands */ - if (error_code) *error_code = CLUSTER_REDIR_DOWN_RO_STATE; + if (error_code) { + *error_code = CLUSTER_REDIR_DOWN_RO_STATE; + } return NULL; } else { /* Fall through and allow the command to be executed: @@ -1149,23 +1190,30 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i } /* Return the hashslot by reference. */ - if (hashslot) *hashslot = slot; + if (hashslot) { + *hashslot = slot; + } /* MIGRATE always works in the context of the local node if the slot * is open (migrating or importing state). We need to be able to freely * move keys among instances in this case. */ - if ((migrating_slot || importing_slot) && cmd->proc == migrateCommand) + if ((migrating_slot || importing_slot) && cmd->proc == migrateCommand) { return myself; + } /* If we don't have all the keys and we are migrating the slot, send * an ASK redirection or TRYAGAIN. */ if (migrating_slot && missing_keys) { /* If we have keys but we don't have all keys, we return TRYAGAIN */ if (existing_keys) { - if (error_code) *error_code = CLUSTER_REDIR_UNSTABLE; + if (error_code) { + *error_code = CLUSTER_REDIR_UNSTABLE; + } return NULL; } else { - if (error_code) *error_code = CLUSTER_REDIR_ASK; + if (error_code) { + *error_code = CLUSTER_REDIR_ASK; + } return getMigratingSlotDest(slot); } } @@ -1174,11 +1222,11 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i * request as "ASKING", we can serve the request. However if the request * involves multiple keys and we don't have them all, the only option is * to send a TRYAGAIN error. */ - if (importing_slot && - (c->flags & CLIENT_ASKING || cmd_flags & CMD_ASKING)) - { + if (importing_slot && (c->flags & CLIENT_ASKING || cmd_flags & CMD_ASKING)) { if (multiple_keys && missing_keys) { - if (error_code) *error_code = CLUSTER_REDIR_UNSTABLE; + if (error_code) { + *error_code = CLUSTER_REDIR_UNSTABLE; + } return NULL; } else { return myself; @@ -1188,19 +1236,18 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i /* Handle the read-only client case reading from a slave: if this * node is a slave and the request is about a hash slot our master * is serving, we can reply without redirection. */ - int is_write_command = (cmd_flags & CMD_WRITE) || - (c->cmd->proc == execCommand && (c->mstate.cmd_flags & CMD_WRITE)); - if (((c->flags & CLIENT_READONLY) || pubsubshard_included) && - !is_write_command && - clusterNodeIsSlave(myself) && - clusterNodeGetSlaveof(myself) == n) - { + int is_write_command = + (cmd_flags & CMD_WRITE) || (c->cmd->proc == execCommand && (c->mstate.cmd_flags & CMD_WRITE)); + if (((c->flags & CLIENT_READONLY) || pubsubshard_included) && !is_write_command && clusterNodeIsSlave(myself) && + clusterNodeGetSlaveof(myself) == n) { return myself; } /* Base case: just return the right node. However, if this node is not * myself, set error_code to MOVED since we need to issue a redirection. */ - if (n != myself && error_code) *error_code = CLUSTER_REDIR_MOVED; + if (n != myself && error_code) { + *error_code = CLUSTER_REDIR_MOVED; + } return n; } @@ -1213,27 +1260,24 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i * be set to the hash slot that caused the redirection. */ void clusterRedirectClient(client *c, clusterNode *n, int hashslot, int error_code) { if (error_code == CLUSTER_REDIR_CROSS_SLOT) { - addReplyError(c,"-CROSSSLOT Keys in request don't hash to the same slot"); + addReplyError(c, "-CROSSSLOT Keys in request don't hash to the same slot"); } else if (error_code == CLUSTER_REDIR_UNSTABLE) { /* The request spawns multiple keys in the same slot, * but the slot is not "stable" currently as there is * a migration or import in progress. */ - addReplyError(c,"-TRYAGAIN Multiple keys request during rehashing of slot"); + addReplyError(c, "-TRYAGAIN Multiple keys request during rehashing of slot"); } else if (error_code == CLUSTER_REDIR_DOWN_STATE) { - addReplyError(c,"-CLUSTERDOWN The cluster is down"); + addReplyError(c, "-CLUSTERDOWN The cluster is down"); } else if (error_code == CLUSTER_REDIR_DOWN_RO_STATE) { - addReplyError(c,"-CLUSTERDOWN The cluster is down and only accepts read commands"); + addReplyError(c, "-CLUSTERDOWN The cluster is down and only accepts read commands"); } else if (error_code == CLUSTER_REDIR_DOWN_UNBOUND) { - addReplyError(c,"-CLUSTERDOWN Hash slot not served"); - } else if (error_code == CLUSTER_REDIR_MOVED || - error_code == CLUSTER_REDIR_ASK) - { + addReplyError(c, "-CLUSTERDOWN Hash slot not served"); + } else if (error_code == CLUSTER_REDIR_MOVED || error_code == CLUSTER_REDIR_ASK) { /* Report TLS ports to TLS client, and report non-TLS port to non-TLS client. */ int port = clusterNodeClientPort(n, shouldReturnTlsInfo()); - addReplyErrorSds(c,sdscatprintf(sdsempty(), - "-%s %d %s:%d", - (error_code == CLUSTER_REDIR_ASK) ? "ASK" : "MOVED", - hashslot, clusterNodePreferredEndpoint(n), port)); + addReplyErrorSds(c, + sdscatprintf(sdsempty(), "-%s %d %s:%d", (error_code == CLUSTER_REDIR_ASK) ? "ASK" : "MOVED", + hashslot, clusterNodePreferredEndpoint(n), port)); } else { serverPanic("getNodeByQuery() unknown error."); } @@ -1252,12 +1296,8 @@ void clusterRedirectClient(client *c, clusterNode *n, int hashslot, int error_co * returns 1. Otherwise 0 is returned and no operation is performed. */ int clusterRedirectBlockedClientIfNeeded(client *c) { clusterNode *myself = getMyClusterNode(); - if (c->flags & CLIENT_BLOCKED && - (c->bstate.btype == BLOCKED_LIST || - c->bstate.btype == BLOCKED_ZSET || - c->bstate.btype == BLOCKED_STREAM || - c->bstate.btype == BLOCKED_MODULE)) - { + if (c->flags & CLIENT_BLOCKED && (c->bstate.btype == BLOCKED_LIST || c->bstate.btype == BLOCKED_ZSET || + c->bstate.btype == BLOCKED_STREAM || c->bstate.btype == BLOCKED_MODULE)) { dictEntry *de; dictIterator *di; @@ -1266,42 +1306,38 @@ int clusterRedirectBlockedClientIfNeeded(client *c) { * still want to emit this error since a write will be required * to unblock them which may never come. */ if (!isClusterHealthy()) { - clusterRedirectClient(c,NULL,0,CLUSTER_REDIR_DOWN_STATE); + clusterRedirectClient(c, NULL, 0, CLUSTER_REDIR_DOWN_STATE); return 1; } /* If the client is blocked on module, but not on a specific key, * don't unblock it (except for the CLUSTER_FAIL case above). */ - if (c->bstate.btype == BLOCKED_MODULE && !moduleClientIsBlockedOnKeys(c)) + if (c->bstate.btype == BLOCKED_MODULE && !moduleClientIsBlockedOnKeys(c)) { return 0; + } /* All keys must belong to the same slot, so check first key only. */ di = dictGetIterator(c->bstate.keys); if ((de = dictNext(di)) != NULL) { robj *key = dictGetKey(de); - int slot = keyHashSlot((char*)key->ptr, sdslen(key->ptr)); + int slot = keyHashSlot((char *)key->ptr, sdslen(key->ptr)); clusterNode *node = getNodeBySlot(slot); /* if the client is read-only and attempting to access key that our * replica can handle, allow it. */ - if ((c->flags & CLIENT_READONLY) && - !(c->lastcmd->flags & CMD_WRITE) && - clusterNodeIsSlave(myself) && clusterNodeGetSlaveof(myself) == node) - { + if ((c->flags & CLIENT_READONLY) && !(c->lastcmd->flags & CMD_WRITE) && clusterNodeIsSlave(myself) && + clusterNodeGetSlaveof(myself) == node) { node = myself; } /* We send an error and unblock the client if: * 1) The slot is unassigned, emitting a cluster down error. * 2) The slot is not handled by this node, nor being imported. */ - if (node != myself && getImportingSlotSource(slot) == NULL) - { + if (node != myself && getImportingSlotSource(slot) == NULL) { if (node == NULL) { - clusterRedirectClient(c,NULL,0, - CLUSTER_REDIR_DOWN_UNBOUND); + clusterRedirectClient(c, NULL, 0, CLUSTER_REDIR_DOWN_UNBOUND); } else { - clusterRedirectClient(c,node,slot, - CLUSTER_REDIR_MOVED); + clusterRedirectClient(c, node, slot, CLUSTER_REDIR_MOVED); } dictReleaseIterator(di); return 1; @@ -1331,7 +1367,7 @@ static int isReplicaAvailable(clusterNode *node) { } void addNodeToNodeReply(client *c, clusterNode *node) { - char* hostname = clusterNodeHostname(node); + char *hostname = clusterNodeHostname(node); addReplyArrayLen(c, 4); if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_IP) { addReplyBulkCString(c, clusterNodeIp(node)); @@ -1359,9 +1395,8 @@ void addNodeToNodeReply(client *c, clusterNode *node) { if (server.cluster_preferred_endpoint_type != CLUSTER_ENDPOINT_TYPE_IP) { length++; } - if (server.cluster_preferred_endpoint_type != CLUSTER_ENDPOINT_TYPE_HOSTNAME - && hostname != NULL && hostname[0] != '\0') - { + if (server.cluster_preferred_endpoint_type != CLUSTER_ENDPOINT_TYPE_HOSTNAME && hostname != NULL && + hostname[0] != '\0') { length++; } addReplyMapLen(c, length); @@ -1371,9 +1406,8 @@ void addNodeToNodeReply(client *c, clusterNode *node) { addReplyBulkCString(c, clusterNodeIp(node)); length--; } - if (server.cluster_preferred_endpoint_type != CLUSTER_ENDPOINT_TYPE_HOSTNAME - && hostname != NULL && hostname[0] != '\0') - { + if (server.cluster_preferred_endpoint_type != CLUSTER_ENDPOINT_TYPE_HOSTNAME && hostname != NULL && + hostname[0] != '\0') { addReplyBulkCString(c, "hostname"); addReplyBulkCString(c, hostname); length--; @@ -1384,7 +1418,9 @@ void addNodeToNodeReply(client *c, clusterNode *node) { void addNodeReplyForClusterSlot(client *c, clusterNode *node, int start_slot, int end_slot) { int i, nested_elements = 3; /* slots (2) + master addr (1) */ for (i = 0; i < clusterNodeNumSlaves(node); i++) { - if (!isReplicaAvailable(clusterNodeGetSlave(node, i))) continue; + if (!isReplicaAvailable(clusterNodeGetSlave(node, i))) { + continue; + } nested_elements++; } addReplyArrayLen(c, nested_elements); @@ -1396,14 +1432,16 @@ void addNodeReplyForClusterSlot(client *c, clusterNode *node, int start_slot, in for (i = 0; i < clusterNodeNumSlaves(node); i++) { /* This loop is copy/pasted from clusterGenNodeDescription() * with modifications for per-slot node aggregation. */ - if (!isReplicaAvailable(clusterNodeGetSlave(node, i))) continue; + if (!isReplicaAvailable(clusterNodeGetSlave(node, i))) { + continue; + } addNodeToNodeReply(c, clusterNodeGetSlave(node, i)); nested_elements--; } serverAssert(nested_elements == 3); /* Original 3 elements */ } -void clusterCommandSlots(client * c) { +void clusterCommandSlots(client *c) { /* Format: 1) 1) start slot * 2) end slot * 3) 1) master IP @@ -1421,7 +1459,9 @@ void clusterCommandSlots(client * c) { for (int i = 0; i <= CLUSTER_SLOTS; i++) { /* Find start node and slot id. */ if (n == NULL) { - if (i == CLUSTER_SLOTS) break; + if (i == CLUSTER_SLOTS) { + break; + } n = getNodeBySlot(i); start = i; continue; @@ -1430,9 +1470,11 @@ void clusterCommandSlots(client * c) { /* Add cluster slots info when occur different node with start * or end of slot. */ if (i == CLUSTER_SLOTS || n != getNodeBySlot(i)) { - addNodeReplyForClusterSlot(c, n, start, i-1); + addNodeReplyForClusterSlot(c, n, start, i - 1); num_masters++; - if (i == CLUSTER_SLOTS) break; + if (i == CLUSTER_SLOTS) { + break; + } n = getNodeBySlot(i); start = i; } @@ -1450,11 +1492,11 @@ void clusterCommandSlots(client * c) { * information. */ void askingCommand(client *c) { if (server.cluster_enabled == 0) { - addReplyError(c,"This instance has cluster support disabled"); + addReplyError(c, "This instance has cluster support disabled"); return; } c->flags |= CLIENT_ASKING; - addReply(c,shared.ok); + addReply(c, shared.ok); } /* The READONLY command is used by clients to enter the read-only mode. @@ -1462,19 +1504,19 @@ void askingCommand(client *c) { * with read-only commands to keys that are served by the slave's master. */ void readonlyCommand(client *c) { if (server.cluster_enabled == 0) { - addReplyError(c,"This instance has cluster support disabled"); + addReplyError(c, "This instance has cluster support disabled"); return; } c->flags |= CLIENT_READONLY; - addReply(c,shared.ok); + addReply(c, shared.ok); } /* The READWRITE command just clears the READONLY command state. */ void readwriteCommand(client *c) { if (server.cluster_enabled == 0) { - addReplyError(c,"This instance has cluster support disabled"); + addReplyError(c, "This instance has cluster support disabled"); return; } c->flags &= ~CLIENT_READONLY; - addReply(c,shared.ok); + addReply(c, shared.ok); } diff --git a/src/cluster.h b/src/cluster.h index 8a2b97cad..ebc700a47 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -5,12 +5,12 @@ * Cluster exported API. *----------------------------------------------------------------------------*/ -#define CLUSTER_SLOT_MASK_BITS 14 /* Number of bits used for slot id. */ -#define CLUSTER_SLOTS (1<slots[slot] == NULL || \ - bitmapTestBit(server.cluster->owner_not_claiming_slot, slot)) +#define isSlotUnclaimed(slot) \ + (server.cluster->slots[slot] == NULL || bitmapTestBit(server.cluster->owner_not_claiming_slot, slot)) #define RCVBUF_INIT_LEN 1024 -#define RCVBUF_MAX_PREALLOC (1<<20) /* 1MB */ +#define RCVBUF_MAX_PREALLOC (1 << 20) /* 1MB */ /* Fixed timeout value for cluster operations (milliseconds) */ #define CLUSTER_OPERATION_TIMEOUT 2000 @@ -139,37 +139,37 @@ static inline int defaultClientPort(void) { /* Cluster nodes hash table, mapping nodes addresses 1.2.3.4:6379 to * clusterNode structures. */ dictType clusterNodesDictType = { - dictSdsHash, /* hash function */ - NULL, /* key dup */ - NULL, /* val dup */ - dictSdsKeyCompare, /* key compare */ - dictSdsDestructor, /* key destructor */ - NULL, /* val destructor */ - NULL /* allow to expand */ + dictSdsHash, /* hash function */ + NULL, /* key dup */ + NULL, /* val dup */ + dictSdsKeyCompare, /* key compare */ + dictSdsDestructor, /* key destructor */ + NULL, /* val destructor */ + NULL /* allow to expand */ }; /* Cluster re-addition blacklist. This maps node IDs to the time * we can re-add this node. The goal is to avoid reading a removed * node for some time. */ dictType clusterNodesBlackListDictType = { - dictSdsCaseHash, /* hash function */ - NULL, /* key dup */ - NULL, /* val dup */ - dictSdsKeyCaseCompare, /* key compare */ - dictSdsDestructor, /* key destructor */ - NULL, /* val destructor */ - NULL /* allow to expand */ + dictSdsCaseHash, /* hash function */ + NULL, /* key dup */ + NULL, /* val dup */ + dictSdsKeyCaseCompare, /* key compare */ + dictSdsDestructor, /* key destructor */ + NULL, /* val destructor */ + NULL /* allow to expand */ }; /* Cluster shards hash table, mapping shard id to list of nodes */ dictType clusterSdsToListType = { - dictSdsHash, /* hash function */ - NULL, /* key dup */ - NULL, /* val dup */ - dictSdsKeyCompare, /* key compare */ - dictSdsDestructor, /* key destructor */ - dictListDestructor, /* val destructor */ - NULL /* allow to expand */ + dictSdsHash, /* hash function */ + NULL, /* key dup */ + NULL, /* val dup */ + dictSdsKeyCompare, /* key compare */ + dictSdsDestructor, /* key destructor */ + dictListDestructor, /* val destructor */ + NULL /* allow to expand */ }; /* Aux fields were introduced in Redis OSS 7.2 to support the persistence @@ -182,13 +182,13 @@ dictType clusterSdsToListType = { /* Aux field setter function prototype * return C_OK when the update is successful; C_ERR otherwise */ -typedef int (aux_value_setter) (clusterNode* n, void *value, int length); +typedef int(aux_value_setter)(clusterNode *n, void *value, int length); /* Aux field getter function prototype * return an sds that is a concatenation of the input sds string and * the aux value */ -typedef sds (aux_value_getter) (clusterNode* n, sds s); +typedef sds(aux_value_getter)(clusterNode *n, sds s); -typedef int (aux_value_present) (clusterNode* n); +typedef int(aux_value_present)(clusterNode *n); typedef struct { char *field; @@ -270,7 +270,7 @@ int auxTcpPortSetter(clusterNode *n, void *value, int length) { return C_ERR; } char buf[length + 1]; - memcpy(buf, (char*)value, length); + memcpy(buf, (char *)value, length); buf[length] = '\0'; n->tcp_port = atoi(buf); return (n->tcp_port < 0 || n->tcp_port >= 65536) ? C_ERR : C_OK; @@ -289,7 +289,7 @@ int auxTlsPortSetter(clusterNode *n, void *value, int length) { return C_ERR; } char buf[length + 1]; - memcpy(buf, (char*)value, length); + memcpy(buf, (char *)value, length); buf[length] = '\0'; n->tls_port = atoi(buf); return (n->tls_port < 0 || n->tls_port >= 65536) ? C_ERR : C_OK; @@ -321,7 +321,7 @@ typedef struct { * sake of locking if it does not already exist), C_ERR is returned. * If the configuration was loaded from the file, C_OK is returned. */ int clusterLoadConfig(char *filename) { - FILE *fp = fopen(filename,"r"); + FILE *fp = fopen(filename, "r"); struct stat sb; char *line; int maxline, j; @@ -330,17 +330,13 @@ int clusterLoadConfig(char *filename) { if (errno == ENOENT) { return C_ERR; } else { - serverLog(LL_WARNING, - "Loading the cluster node config from %s: %s", - filename, strerror(errno)); + serverLog(LL_WARNING, "Loading the cluster node config from %s: %s", filename, strerror(errno)); exit(1); } } if (valkey_fstat(fileno(fp), &sb) == -1) { - serverLog(LL_WARNING, - "Unable to obtain the cluster node config file stat %s: %s", - filename, strerror(errno)); + serverLog(LL_WARNING, "Unable to obtain the cluster node config file stat %s: %s", filename, strerror(errno)); exit(1); } /* Check if the file is zero-length: if so return C_ERR to signal @@ -357,9 +353,9 @@ int clusterLoadConfig(char *filename) { * together with the node ID of the sender/receiver. * * To simplify we allocate 1024+CLUSTER_SLOTS*128 bytes per line. */ - maxline = 1024+CLUSTER_SLOTS*128; + maxline = 1024 + CLUSTER_SLOTS * 128; line = zmalloc(maxline); - while(fgets(line,maxline,fp) != NULL) { + while (fgets(line, maxline, fp) != NULL) { int argc, aux_argc; sds *argv, *aux_argv; clusterNode *n, *master; @@ -368,36 +364,38 @@ int clusterLoadConfig(char *filename) { /* Skip blank lines, they can be created either by users manually * editing nodes.conf or by the config writing process if stopped * before the truncate() call. */ - if (line[0] == '\n' || line[0] == '\0') continue; + if (line[0] == '\n' || line[0] == '\0') { + continue; + } /* Split the line into arguments for processing. */ - argv = sdssplitargs(line,&argc); - if (argv == NULL) goto fmterr; + argv = sdssplitargs(line, &argc); + if (argv == NULL) { + goto fmterr; + } /* Handle the special "vars" line. Don't pretend it is the last * line even if it actually is when generated by the server. */ - if (strcasecmp(argv[0],"vars") == 0) { - if (!(argc % 2)) goto fmterr; + if (strcasecmp(argv[0], "vars") == 0) { + if (!(argc % 2)) { + goto fmterr; + } for (j = 1; j < argc; j += 2) { - if (strcasecmp(argv[j],"currentEpoch") == 0) { - server.cluster->currentEpoch = - strtoull(argv[j+1],NULL,10); - } else if (strcasecmp(argv[j],"lastVoteEpoch") == 0) { - server.cluster->lastVoteEpoch = - strtoull(argv[j+1],NULL,10); + if (strcasecmp(argv[j], "currentEpoch") == 0) { + server.cluster->currentEpoch = strtoull(argv[j + 1], NULL, 10); + } else if (strcasecmp(argv[j], "lastVoteEpoch") == 0) { + server.cluster->lastVoteEpoch = strtoull(argv[j + 1], NULL, 10); } else { - serverLog(LL_NOTICE, - "Skipping unknown cluster config variable '%s'", - argv[j]); + serverLog(LL_NOTICE, "Skipping unknown cluster config variable '%s'", argv[j]); } } - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); continue; } /* Regular config lines have at least eight fields */ if (argc < 8) { - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); goto fmterr; } @@ -408,7 +406,7 @@ int clusterLoadConfig(char *filename) { } n = clusterLookupNode(argv[0], sdslen(argv[0])); if (!n) { - n = createClusterNode(argv[0],0); + n = createClusterNode(argv[0], 0); clusterAddNode(n); } /* Format for the node address and auxiliary argument information: @@ -416,7 +414,7 @@ int clusterLoadConfig(char *filename) { aux_argv = sdssplitlen(argv[1], sdslen(argv[1]), ",", 1, &aux_argc); if (aux_argv == NULL) { - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); goto fmterr; } @@ -440,19 +438,21 @@ int clusterLoadConfig(char *filename) { field_argv = sdssplitlen(aux_argv[i], sdslen(aux_argv[i]), "=", 1, &field_argc); if (field_argv == NULL || field_argc != 2) { /* Invalid aux field format */ - if (field_argv != NULL) sdsfreesplitres(field_argv, field_argc); + if (field_argv != NULL) { + sdsfreesplitres(field_argv, field_argc); + } sdsfreesplitres(aux_argv, aux_argc); - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); goto fmterr; } /* Validate that both aux and value contain valid characters only */ for (unsigned j = 0; j < 2; j++) { - if (!isValidAuxString(field_argv[j],sdslen(field_argv[j]))){ + if (!isValidAuxString(field_argv[j], sdslen(field_argv[j]))) { /* Invalid aux field format */ sdsfreesplitres(field_argv, field_argc); sdsfreesplitres(aux_argv, aux_argc); - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); goto fmterr; } } @@ -472,7 +472,7 @@ int clusterLoadConfig(char *filename) { /* Invalid aux field format */ sdsfreesplitres(field_argv, field_argc); sdsfreesplitres(aux_argv, aux_argc); - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); goto fmterr; } } @@ -481,22 +481,22 @@ int clusterLoadConfig(char *filename) { /* Invalid aux field format */ sdsfreesplitres(field_argv, field_argc); sdsfreesplitres(aux_argv, aux_argc); - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); goto fmterr; } sdsfreesplitres(field_argv, field_argc); } /* Address and port */ - if ((p = strrchr(aux_argv[0],':')) == NULL) { + if ((p = strrchr(aux_argv[0], ':')) == NULL) { sdsfreesplitres(aux_argv, aux_argc); - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); goto fmterr; } *p = '\0'; - memcpy(n->ip,aux_argv[0],strlen(aux_argv[0])+1); - char *port = p+1; - char *busp = strchr(port,'@'); + memcpy(n->ip, aux_argv[0], strlen(aux_argv[0]) + 1); + char *port = p + 1; + char *busp = strchr(port, '@'); if (busp) { *busp = '\0'; busp++; @@ -526,34 +526,38 @@ int clusterLoadConfig(char *filename) { /* Parse flags */ p = s = argv[2]; - while(p) { - p = strchr(s,','); - if (p) *p = '\0'; - if (!strcasecmp(s,"myself")) { + while (p) { + p = strchr(s, ','); + if (p) { + *p = '\0'; + } + if (!strcasecmp(s, "myself")) { serverAssert(server.cluster->myself == NULL); myself = server.cluster->myself = n; n->flags |= CLUSTER_NODE_MYSELF; - } else if (!strcasecmp(s,"master")) { + } else if (!strcasecmp(s, "master")) { n->flags |= CLUSTER_NODE_MASTER; - } else if (!strcasecmp(s,"slave")) { + } else if (!strcasecmp(s, "slave")) { n->flags |= CLUSTER_NODE_SLAVE; - } else if (!strcasecmp(s,"fail?")) { + } else if (!strcasecmp(s, "fail?")) { n->flags |= CLUSTER_NODE_PFAIL; - } else if (!strcasecmp(s,"fail")) { + } else if (!strcasecmp(s, "fail")) { n->flags |= CLUSTER_NODE_FAIL; n->fail_time = mstime(); - } else if (!strcasecmp(s,"handshake")) { + } else if (!strcasecmp(s, "handshake")) { n->flags |= CLUSTER_NODE_HANDSHAKE; - } else if (!strcasecmp(s,"noaddr")) { + } else if (!strcasecmp(s, "noaddr")) { n->flags |= CLUSTER_NODE_NOADDR; - } else if (!strcasecmp(s,"nofailover")) { + } else if (!strcasecmp(s, "nofailover")) { n->flags |= CLUSTER_NODE_NOFAILOVER; - } else if (!strcasecmp(s,"noflags")) { + } else if (!strcasecmp(s, "noflags")) { /* nothing to do */ } else { serverPanic("Unknown flag in redis cluster config file"); } - if (p) s = p+1; + if (p) { + s = p + 1; + } } /* Get master if any. Set the master and populate master's @@ -565,7 +569,7 @@ int clusterLoadConfig(char *filename) { } master = clusterLookupNode(argv[3], sdslen(argv[3])); if (!master) { - master = createClusterNode(argv[3],0); + master = createClusterNode(argv[3], 0); clusterAddNode(master); } /* shard_id can be absent if we are loading a nodes.conf generated @@ -575,14 +579,13 @@ int clusterLoadConfig(char *filename) { memcpy(n->shard_id, master->shard_id, CLUSTER_NAMELEN); clusterAddNodeToShard(master->shard_id, n); } else if (clusterGetNodesInMyShard(master) != NULL && - memcmp(master->shard_id, n->shard_id, CLUSTER_NAMELEN) != 0) - { + memcmp(master->shard_id, n->shard_id, CLUSTER_NAMELEN) != 0) { /* If the primary has been added to a shard, make sure this * node has the same persisted shard id as the primary. */ goto fmterr; } n->slaveof = master; - clusterNodeAddSlave(master,n); + clusterNodeAddSlave(master, n); } else if (auxFieldHandlers[af_shard_id].isPresent(n) == 0) { /* n is a primary but it does not have a persisted shard_id. * This happens if we are loading a nodes.conf generated by @@ -592,13 +595,17 @@ int clusterLoadConfig(char *filename) { } /* Set ping sent / pong received timestamps */ - if (atoi(argv[4])) n->ping_sent = mstime(); - if (atoi(argv[5])) n->pong_received = mstime(); + if (atoi(argv[4])) { + n->ping_sent = mstime(); + } + if (atoi(argv[5])) { + n->pong_received = mstime(); + } /* Set configEpoch for this node. * If the node is a replica, set its config epoch to 0. * If it's a primary, load the config epoch from the configuration file. */ - n->configEpoch = (nodeIsSlave(n) && n->slaveof) ? 0 : strtoull(argv[6],NULL,10); + n->configEpoch = (nodeIsSlave(n) && n->slaveof) ? 0 : strtoull(argv[6], NULL, 10); /* Populate hash slots served by this instance. */ for (j = 8; j < argc; j++) { @@ -610,13 +617,13 @@ int clusterLoadConfig(char *filename) { char direction; clusterNode *cn; - p = strchr(argv[j],'-'); + p = strchr(argv[j], '-'); serverAssert(p != NULL); *p = '\0'; direction = p[1]; /* Either '>' or '<' */ - slot = atoi(argv[j]+1); + slot = atoi(argv[j] + 1); if (slot < 0 || slot >= CLUSTER_SLOTS) { - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); goto fmterr; } p += 3; @@ -629,7 +636,7 @@ int clusterLoadConfig(char *filename) { } cn = clusterLookupNode(p, CLUSTER_NAMELEN); if (!cn) { - cn = createClusterNode(p,0); + cn = createClusterNode(p, 0); clusterAddNode(cn); } if (direction == '>') { @@ -638,31 +645,33 @@ int clusterLoadConfig(char *filename) { server.cluster->importing_slots_from[slot] = cn; } continue; - } else if ((p = strchr(argv[j],'-')) != NULL) { + } else if ((p = strchr(argv[j], '-')) != NULL) { *p = '\0'; start = atoi(argv[j]); - stop = atoi(p+1); + stop = atoi(p + 1); } else { start = stop = atoi(argv[j]); } - if (start < 0 || start >= CLUSTER_SLOTS || - stop < 0 || stop >= CLUSTER_SLOTS) - { - sdsfreesplitres(argv,argc); + if (start < 0 || start >= CLUSTER_SLOTS || stop < 0 || stop >= CLUSTER_SLOTS) { + sdsfreesplitres(argv, argc); goto fmterr; } - while(start <= stop) clusterAddSlot(n, start++); + while (start <= stop) { + clusterAddSlot(n, start++); + } } - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); } /* Config sanity check */ - if (server.cluster->myself == NULL) goto fmterr; + if (server.cluster->myself == NULL) { + goto fmterr; + } zfree(line); fclose(fp); - serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s", myself->name); + serverLog(LL_NOTICE, "Node configuration loaded, I'm %.40s", myself->name); /* Something that should never happen: currentEpoch smaller than * the max epoch found in the nodes configuration. However we handle this @@ -673,10 +682,11 @@ int clusterLoadConfig(char *filename) { return C_OK; fmterr: - serverLog(LL_WARNING, - "Unrecoverable error: corrupted cluster config file \"%s\".", line); + serverLog(LL_WARNING, "Unrecoverable error: corrupted cluster config file \"%s\".", line); zfree(line); - if (fp) fclose(fp); + if (fp) { + fclose(fp); + } exit(1); } @@ -693,8 +703,8 @@ int clusterLoadConfig(char *filename) { * bigger we pad our payload with newlines that are anyway ignored and truncate * the file afterward. */ int clusterSaveConfig(int do_fsync) { - sds ci,tmpfilename; - size_t content_size,offset = 0; + sds ci, tmpfilename; + size_t content_size, offset = 0; ssize_t written_bytes; int fd = -1; int retval = C_ERR; @@ -704,25 +714,26 @@ int clusterSaveConfig(int do_fsync) { /* Get the nodes description and concatenate our "vars" directive to * save currentEpoch and lastVoteEpoch. */ ci = clusterGenNodesDescription(NULL, CLUSTER_NODE_HANDSHAKE, 0); - ci = sdscatprintf(ci,"vars currentEpoch %llu lastVoteEpoch %llu\n", - (unsigned long long) server.cluster->currentEpoch, - (unsigned long long) server.cluster->lastVoteEpoch); + ci = sdscatprintf(ci, "vars currentEpoch %llu lastVoteEpoch %llu\n", + (unsigned long long)server.cluster->currentEpoch, + (unsigned long long)server.cluster->lastVoteEpoch); content_size = sdslen(ci); /* Create a temp file with the new content. */ - tmpfilename = sdscatfmt(sdsempty(),"%s.tmp-%i-%I", - server.cluster_configfile,(int) getpid(),mstime()); - if ((fd = open(tmpfilename,O_WRONLY|O_CREAT,0644)) == -1) { - serverLog(LL_WARNING,"Could not open temp cluster config file: %s",strerror(errno)); + tmpfilename = sdscatfmt(sdsempty(), "%s.tmp-%i-%I", server.cluster_configfile, (int)getpid(), mstime()); + if ((fd = open(tmpfilename, O_WRONLY | O_CREAT, 0644)) == -1) { + serverLog(LL_WARNING, "Could not open temp cluster config file: %s", strerror(errno)); goto cleanup; } while (offset < content_size) { - written_bytes = write(fd,ci + offset,content_size - offset); + written_bytes = write(fd, ci + offset, content_size - offset); if (written_bytes <= 0) { - if (errno == EINTR) continue; - serverLog(LL_WARNING,"Failed after writing (%zd) bytes to tmp cluster config file: %s", - offset,strerror(errno)); + if (errno == EINTR) { + continue; + } + serverLog(LL_WARNING, "Failed after writing (%zd) bytes to tmp cluster config file: %s", offset, + strerror(errno)); goto cleanup; } offset += written_bytes; @@ -731,27 +742,31 @@ int clusterSaveConfig(int do_fsync) { if (do_fsync) { server.cluster->todo_before_sleep &= ~CLUSTER_TODO_FSYNC_CONFIG; if (valkey_fsync(fd) == -1) { - serverLog(LL_WARNING,"Could not sync tmp cluster config file: %s",strerror(errno)); + serverLog(LL_WARNING, "Could not sync tmp cluster config file: %s", strerror(errno)); goto cleanup; } } if (rename(tmpfilename, server.cluster_configfile) == -1) { - serverLog(LL_WARNING,"Could not rename tmp cluster config file: %s",strerror(errno)); + serverLog(LL_WARNING, "Could not rename tmp cluster config file: %s", strerror(errno)); goto cleanup; } if (do_fsync) { if (fsyncFileDir(server.cluster_configfile) == -1) { - serverLog(LL_WARNING,"Could not sync cluster config file dir: %s",strerror(errno)); + serverLog(LL_WARNING, "Could not sync cluster config file dir: %s", strerror(errno)); goto cleanup; } } retval = C_OK; /* If we reached this point, everything is fine. */ cleanup: - if (fd != -1) close(fd); - if (retval) unlink(tmpfilename); + if (fd != -1) { + close(fd); + } + if (retval) { + unlink(tmpfilename); + } sdsfree(tmpfilename); sdsfree(ci); return retval; @@ -759,7 +774,7 @@ int clusterSaveConfig(int do_fsync) { void clusterSaveConfigOrDie(int do_fsync) { if (clusterSaveConfig(do_fsync) == -1) { - serverLog(LL_WARNING,"Fatal: can't update cluster config file."); + serverLog(LL_WARNING, "Fatal: can't update cluster config file."); exit(1); } } @@ -782,24 +797,22 @@ int clusterLockConfig(char *filename) { /* To lock it, we need to open the file in a way it is created if * it does not exist, otherwise there is a race condition with other * processes. */ - int fd = open(filename,O_WRONLY|O_CREAT|O_CLOEXEC,0644); + int fd = open(filename, O_WRONLY | O_CREAT | O_CLOEXEC, 0644); if (fd == -1) { - serverLog(LL_WARNING, - "Can't open %s in order to acquire a lock: %s", - filename, strerror(errno)); + serverLog(LL_WARNING, "Can't open %s in order to acquire a lock: %s", filename, strerror(errno)); return C_ERR; } - if (flock(fd,LOCK_EX|LOCK_NB) == -1) { + if (flock(fd, LOCK_EX | LOCK_NB) == -1) { if (errno == EWOULDBLOCK) { serverLog(LL_WARNING, - "Sorry, the cluster configuration file %s is already used " - "by a different Cluster node. Please make sure that " - "different nodes use different cluster configuration " - "files.", filename); + "Sorry, the cluster configuration file %s is already used " + "by a different Cluster node. Please make sure that " + "different nodes use different cluster configuration " + "files.", + filename); } else { - serverLog(LL_WARNING, - "Impossible to lock %s: %s", filename, strerror(errno)); + serverLog(LL_WARNING, "Impossible to lock %s: %s", filename, strerror(errno)); } close(fd); return C_ERR; @@ -822,13 +835,10 @@ int clusterLockConfig(char *filename) { } /* Derives our ports to be announced in the cluster bus. */ -void deriveAnnouncedPorts(int *announced_tcp_port, int *announced_tls_port, - int *announced_cport) { +void deriveAnnouncedPorts(int *announced_tcp_port, int *announced_tls_port, int *announced_cport) { /* Config overriding announced ports. */ - *announced_tcp_port = server.cluster_announce_port ? - server.cluster_announce_port : server.port; - *announced_tls_port = server.cluster_announce_tls_port ? - server.cluster_announce_tls_port : server.tls_port; + *announced_tcp_port = server.cluster_announce_port ? server.cluster_announce_port : server.port; + *announced_tls_port = server.cluster_announce_tls_port ? server.cluster_announce_tls_port : server.tls_port; /* Derive cluster bus port. */ if (server.cluster_announce_bus_port) { *announced_cport = server.cluster_announce_bus_port; @@ -844,49 +854,59 @@ void deriveAnnouncedPorts(int *announced_tcp_port, int *announced_tls_port, * that may change at runtime via CONFIG SET. This function changes the * set of flags in myself->flags accordingly. */ void clusterUpdateMyselfFlags(void) { - if (!myself) return; + if (!myself) { + return; + } int oldflags = myself->flags; - int nofailover = server.cluster_slave_no_failover ? - CLUSTER_NODE_NOFAILOVER : 0; + int nofailover = server.cluster_slave_no_failover ? CLUSTER_NODE_NOFAILOVER : 0; myself->flags &= ~CLUSTER_NODE_NOFAILOVER; myself->flags |= nofailover; if (myself->flags != oldflags) { - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE); } } /* We want to take myself->port/cport/pport in sync with the -* cluster-announce-port/cluster-announce-bus-port/cluster-announce-tls-port option. -* The option can be set at runtime via CONFIG SET. */ + * cluster-announce-port/cluster-announce-bus-port/cluster-announce-tls-port option. + * The option can be set at runtime via CONFIG SET. */ void clusterUpdateMyselfAnnouncedPorts(void) { - if (!myself) return; - deriveAnnouncedPorts(&myself->tcp_port,&myself->tls_port,&myself->cport); + if (!myself) { + return; + } + deriveAnnouncedPorts(&myself->tcp_port, &myself->tls_port, &myself->cport); } /* We want to take myself->ip in sync with the cluster-announce-ip option. -* The option can be set at runtime via CONFIG SET. */ + * The option can be set at runtime via CONFIG SET. */ void clusterUpdateMyselfIp(void) { - if (!myself) return; + if (!myself) { + return; + } static char *prev_ip = NULL; char *curr_ip = server.cluster_announce_ip; int changed = 0; - if (prev_ip == NULL && curr_ip != NULL) changed = 1; - else if (prev_ip != NULL && curr_ip == NULL) changed = 1; - else if (prev_ip && curr_ip && strcmp(prev_ip,curr_ip)) changed = 1; + if (prev_ip == NULL && curr_ip != NULL) { + changed = 1; + } else if (prev_ip != NULL && curr_ip == NULL) { + changed = 1; + } else if (prev_ip && curr_ip && strcmp(prev_ip, curr_ip)) { + changed = 1; + } if (changed) { - if (prev_ip) zfree(prev_ip); + if (prev_ip) { + zfree(prev_ip); + } prev_ip = curr_ip; if (curr_ip) { /* We always take a copy of the previous IP address, by - * duplicating the string. This way later we can check if - * the address really changed. */ + * duplicating the string. This way later we can check if + * the address really changed. */ prev_ip = zstrdup(prev_ip); - valkey_strlcpy(myself->ip,server.cluster_announce_ip,NET_IP_STR_LEN); + valkey_strlcpy(myself->ip, server.cluster_announce_ip, NET_IP_STR_LEN); } else { myself->ip[0] = '\0'; /* Force autodetection. */ } @@ -916,7 +936,7 @@ static void updateAnnouncedHumanNodename(clusterNode *node, char *new) { } else if (!new && (sdslen(node->human_nodename) == 0)) { return; } - + if (new) { node->human_nodename = sdscpy(node->human_nodename, new); } else if (sdslen(node->human_nodename) != 0) { @@ -940,7 +960,7 @@ static void updateShardId(clusterNode *node, const char *shard_id) { clusterRemoveNodeFromShard(myself); memcpy(myself->shard_id, shard_id, CLUSTER_NAMELEN); clusterAddNodeToShard(shard_id, myself); - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_FSYNC_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_FSYNC_CONFIG); } } } @@ -955,12 +975,16 @@ static inline uint64_t nodeEpoch(clusterNode *n) { /* Update my hostname based on server configuration values */ void clusterUpdateMyselfHostname(void) { - if (!myself) return; + if (!myself) { + return; + } updateAnnouncedHostname(myself, server.cluster_announce_hostname); } void clusterUpdateMyselfHumanNodename(void) { - if (!myself) return; + if (!myself) { + return; + } updateAnnouncedHumanNodename(myself, server.cluster_announce_human_nodename); } @@ -975,8 +999,7 @@ void clusterInit(void) { server.cluster->todo_before_sleep = 0; server.cluster->nodes = dictCreate(&clusterNodesDictType); server.cluster->shards = dictCreate(&clusterSdsToListType); - server.cluster->nodes_black_list = - dictCreate(&clusterNodesBlackListDictType); + server.cluster->nodes_black_list = dictCreate(&clusterNodesBlackListDictType); server.cluster->failover_auth_time = 0; server.cluster->failover_auth_count = 0; server.cluster->failover_auth_rank = 0; @@ -992,7 +1015,7 @@ void clusterInit(void) { server.cluster->stats_pfail_nodes = 0; server.cluster->stat_cluster_links_buffer_limit_exceeded = 0; - memset(server.cluster->slots,0, sizeof(server.cluster->slots)); + memset(server.cluster->slots, 0, sizeof(server.cluster->slots)); clusterCloseAllSlots(); memset(server.cluster->owner_not_claiming_slot, 0, sizeof(server.cluster->owner_not_claiming_slot)); @@ -1000,32 +1023,35 @@ void clusterInit(void) { /* Lock the cluster config file to make sure every node uses * its own nodes.conf. */ server.cluster_config_file_lock_fd = -1; - if (clusterLockConfig(server.cluster_configfile) == C_ERR) + if (clusterLockConfig(server.cluster_configfile) == C_ERR) { exit(1); + } /* Load or create a new nodes configuration. */ if (clusterLoadConfig(server.cluster_configfile) == C_ERR) { /* No configuration found. We will just use the random name provided * by the createClusterNode() function. */ - myself = server.cluster->myself = - createClusterNode(NULL,CLUSTER_NODE_MYSELF|CLUSTER_NODE_MASTER); - serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s", - myself->name); + myself = server.cluster->myself = createClusterNode(NULL, CLUSTER_NODE_MYSELF | CLUSTER_NODE_MASTER); + serverLog(LL_NOTICE, "No cluster configuration found, I'm %.40s", myself->name); clusterAddNode(myself); clusterAddNodeToShard(myself->shard_id, myself); saveconf = 1; } - if (saveconf) clusterSaveConfigOrDie(1); + if (saveconf) { + clusterSaveConfigOrDie(1); + } /* Port sanity check II * The other handshake port check is triggered too late to stop * us from trying to use a too-high cluster port number. */ int port = defaultClientPort(); - if (!server.cluster_port && port > (65535-CLUSTER_PORT_INCR)) { - serverLog(LL_WARNING, "%s port number too high. " - "Cluster communication port is 10,000 port " - "numbers higher than your %s port. " - "Your %s port number must be 55535 or less.", SERVER_TITLE, SERVER_TITLE, SERVER_TITLE); + if (!server.cluster_port && port > (65535 - CLUSTER_PORT_INCR)) { + serverLog(LL_WARNING, + "%s port number too high. " + "Cluster communication port is 10,000 port " + "numbers higher than your %s port. " + "Your %s port number must be 55535 or less.", + SERVER_TITLE, SERVER_TITLE, SERVER_TITLE); exit(1); } if (!server.bindaddr_count) { @@ -1048,7 +1074,8 @@ void clusterInit(void) { void clusterInitLast(void) { if (connectionIndexByType(connTypeOfCluster()->get_type(NULL)) < 0) { - serverLog(LL_WARNING, "Missing connection type %s, but it is required for the Cluster bus.", connTypeOfCluster()->get_type(NULL)); + serverLog(LL_WARNING, "Missing connection type %s, but it is required for the Cluster bus.", + connTypeOfCluster()->get_type(NULL)); exit(1); } @@ -1059,12 +1086,12 @@ void clusterInitLast(void) { listener->bindaddr_count = server.bindaddr_count; listener->port = server.cluster_port ? server.cluster_port : port + CLUSTER_PORT_INCR; listener->ct = connTypeOfCluster(); - if (connListen(listener) == C_ERR ) { + if (connListen(listener) == C_ERR) { /* Note: the following log text is matched by the test suite. */ serverLog(LL_WARNING, "Failed listening on port %u (cluster), aborting.", listener->port); exit(1); } - + if (createSocketAcceptHandler(&server.clistener, clusterAcceptHandler) != C_OK) { serverPanic("Unrecoverable error creating Cluster socket accept handler."); } @@ -1088,7 +1115,7 @@ void clusterReset(int hard) { if (nodeIsSlave(myself)) { clusterSetNodeAsMaster(myself); replicationUnsetMaster(); - emptyData(-1,EMPTYDB_NO_FLAGS,NULL); + emptyData(-1, EMPTYDB_NO_FLAGS, NULL); } /* Close slots, reset manual failover state. */ @@ -1096,17 +1123,21 @@ void clusterReset(int hard) { resetManualFailover(); /* Unassign all the slots. */ - for (j = 0; j < CLUSTER_SLOTS; j++) clusterDelSlot(j); + for (j = 0; j < CLUSTER_SLOTS; j++) { + clusterDelSlot(j); + } /* Recreate shards dict */ dictEmpty(server.cluster->shards, NULL); /* Forget all the nodes, but myself. */ di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); - if (node == myself) continue; + if (node == myself) { + continue; + } clusterDelNode(node); } dictReleaseIterator(di); @@ -1126,21 +1157,19 @@ void clusterReset(int hard) { /* To change the Node ID we need to remove the old name from the * nodes table, change the ID, and re-add back with new name. */ oldname = sdsnewlen(myself->name, CLUSTER_NAMELEN); - dictDelete(server.cluster->nodes,oldname); + dictDelete(server.cluster->nodes, oldname); sdsfree(oldname); getRandomHexChars(myself->name, CLUSTER_NAMELEN); getRandomHexChars(myself->shard_id, CLUSTER_NAMELEN); clusterAddNode(myself); - serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s", myself->name); + serverLog(LL_NOTICE, "Node hard reset, now I'm %.40s", myself->name); } /* Re-populate shards */ clusterAddNodeToShard(myself->shard_id, myself); /* Make sure to persist the new config and update the state. */ - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE| - CLUSTER_TODO_FSYNC_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_FSYNC_CONFIG); } /* ----------------------------------------------------------------------------- @@ -1152,12 +1181,12 @@ static clusterMsgSendBlock *createClusterMsgSendBlock(int type, uint32_t msglen) msgblock->refcount = 1; msgblock->totlen = blocklen; server.stat_cluster_links_memory += blocklen; - clusterBuildMessageHdr(&msgblock->msg,type,msglen); + clusterBuildMessageHdr(&msgblock->msg, type, msglen); return msgblock; } static void clusterMsgSendBlockDecrRefCount(void *node) { - clusterMsgSendBlock *msgblock = (clusterMsgSendBlock*)node; + clusterMsgSendBlock *msgblock = (clusterMsgSendBlock *)node; msgblock->refcount--; serverAssert(msgblock->refcount >= 0); if (msgblock->refcount == 0) { @@ -1194,7 +1223,7 @@ void freeClusterLink(clusterLink *link) { connClose(link->conn); link->conn = NULL; } - server.stat_cluster_links_memory -= sizeof(list) + listLength(link->send_msg_queue)*sizeof(listNode); + server.stat_cluster_links_memory -= sizeof(list) + listLength(link->send_msg_queue) * sizeof(listNode); listRelease(link->send_msg_queue); server.stat_cluster_links_memory -= link->rcvbuf_alloc; zfree(link->rcvbuf); @@ -1221,8 +1250,8 @@ void setClusterNodeToInboundClusterLink(clusterNode *node, clusterLink *link) { * a one to one relationship between nodes and inbound links, so we need to kill * one of the links. The existing link is more likely the outdated one, but it's * possible the other node may need to open another link. */ - serverLog(LL_DEBUG, "Replacing inbound link fd %d from node %.40s with fd %d", - node->inbound_link->conn->fd, node->name, link->conn->fd); + serverLog(LL_DEBUG, "Replacing inbound link fd %d from node %.40s with fd %d", node->inbound_link->conn->fd, + node->name, link->conn->fd); freeClusterLink(node->inbound_link); } serverAssert(!node->inbound_link); @@ -1234,8 +1263,7 @@ static void clusterConnAcceptHandler(connection *conn) { clusterLink *link; if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, - "Error accepting cluster node connection: %s", connGetLastError(conn)); + serverLog(LL_VERBOSE, "Error accepting cluster node connection: %s", connGetLastError(conn)); connClose(conn); return; } @@ -1265,14 +1293,16 @@ void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) { /* If the server is starting up, don't accept cluster connections: * UPDATE messages may interact with the database content. */ - if (server.masterhost == NULL && server.loading) return; + if (server.masterhost == NULL && server.loading) { + return; + } - while(max--) { + while (max--) { cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport); if (cfd == ANET_ERR) { - if (errno != EWOULDBLOCK) - serverLog(LL_VERBOSE, - "Error accepting cluster node: %s", server.neterr); + if (errno != EWOULDBLOCK) { + serverLog(LL_VERBOSE, "Error accepting cluster node: %s", server.neterr); + } return; } @@ -1280,26 +1310,24 @@ void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) { /* Make sure connection is not in an error state */ if (connGetState(conn) != CONN_STATE_ACCEPTING) { - serverLog(LL_VERBOSE, - "Error creating an accepting connection for cluster node: %s", - connGetLastError(conn)); + serverLog(LL_VERBOSE, "Error creating an accepting connection for cluster node: %s", + connGetLastError(conn)); connClose(conn); return; } connEnableTcpNoDelay(conn); - connKeepAlive(conn,server.cluster_node_timeout / 1000 * 2); + connKeepAlive(conn, server.cluster_node_timeout / 1000 * 2); /* Use non-blocking I/O for cluster messages. */ - serverLog(LL_VERBOSE,"Accepting cluster node connection from %s:%d", cip, cport); + serverLog(LL_VERBOSE, "Accepting cluster node connection from %s:%d", cip, cport); /* Accept the connection now. connAccept() may call our handler directly * or schedule it for later depending on connection implementation. */ if (connAccept(conn, clusterConnAcceptHandler) == C_ERR) { - if (connGetState(conn) == CONN_STATE_ERROR) - serverLog(LL_VERBOSE, - "Error accepting cluster node connection: %s", - connGetLastError(conn)); + if (connGetState(conn) == CONN_STATE_ERROR) { + serverLog(LL_VERBOSE, "Error accepting cluster node connection: %s", connGetLastError(conn)); + } connClose(conn); return; } @@ -1312,8 +1340,7 @@ unsigned long getClusterConnectionsCount(void) { /* We decrement the number of nodes by one, since there is the * "myself" node too in the list. Each node uses two file descriptors, * one incoming and one outgoing, thus the multiplication by 2. */ - return server.cluster_enabled ? - ((dictSize(server.cluster->nodes)-1)*2) : 0; + return server.cluster_enabled ? ((dictSize(server.cluster->nodes) - 1) * 2) : 0; } /* ----------------------------------------------------------------------------- @@ -1330,15 +1357,16 @@ unsigned long getClusterConnectionsCount(void) { clusterNode *createClusterNode(char *nodename, int flags) { clusterNode *node = zmalloc(sizeof(*node)); - if (nodename) + if (nodename) { memcpy(node->name, nodename, CLUSTER_NAMELEN); - else + } else { getRandomHexChars(node->name, CLUSTER_NAMELEN); + } getRandomHexChars(node->shard_id, CLUSTER_NAMELEN); node->ctime = mstime(); node->configEpoch = 0; node->flags = flags; - memset(node->slots,0,sizeof(node->slots)); + memset(node->slots, 0, sizeof(node->slots)); node->slot_info_pairs = NULL; node->slot_info_pairs_count = 0; node->numslots = 0; @@ -1351,7 +1379,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { node->fail_time = 0; node->link = NULL; node->inbound_link = NULL; - memset(node->ip,0,sizeof(node->ip)); + memset(node->ip, 0, sizeof(node->ip)); node->hostname = sdsempty(); node->human_nodename = sdsempty(); node->tcp_port = 0; @@ -1362,7 +1390,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { node->orphaned_time = 0; node->repl_offset_time = 0; node->repl_offset = 0; - listSetFreeMethod(node->fail_reports,zfree); + listSetFreeMethod(node->fail_reports, zfree); return node; } @@ -1384,7 +1412,7 @@ int clusterNodeAddFailureReport(clusterNode *failing, clusterNode *sender) { /* If a failure report from the same sender already exists, just update * the timestamp. */ - listRewind(l,&li); + listRewind(l, &li); while ((ln = listNext(&li)) != NULL) { fr = ln->value; if (fr->node == sender) { @@ -1397,7 +1425,7 @@ int clusterNodeAddFailureReport(clusterNode *failing, clusterNode *sender) { fr = zmalloc(sizeof(*fr)); fr->node = sender; fr->time = mstime(); - listAddNodeTail(l,fr); + listAddNodeTail(l, fr); return 1; } @@ -1411,14 +1439,15 @@ void clusterNodeCleanupFailureReports(clusterNode *node) { listNode *ln; listIter li; clusterNodeFailReport *fr; - mstime_t maxtime = server.cluster_node_timeout * - CLUSTER_FAIL_REPORT_VALIDITY_MULT; + mstime_t maxtime = server.cluster_node_timeout * CLUSTER_FAIL_REPORT_VALIDITY_MULT; mstime_t now = mstime(); - listRewind(l,&li); + listRewind(l, &li); while ((ln = listNext(&li)) != NULL) { fr = ln->value; - if (now - fr->time > maxtime) listDelNode(l,ln); + if (now - fr->time > maxtime) { + listDelNode(l, ln); + } } } @@ -1440,15 +1469,19 @@ int clusterNodeDelFailureReport(clusterNode *node, clusterNode *sender) { clusterNodeFailReport *fr; /* Search for a failure report from this sender. */ - listRewind(l,&li); + listRewind(l, &li); while ((ln = listNext(&li)) != NULL) { fr = ln->value; - if (fr->node == sender) break; + if (fr->node == sender) { + break; + } + } + if (!ln) { + return 0; /* No failure report from this sender. */ } - if (!ln) return 0; /* No failure report from this sender. */ /* Remove the failure report. */ - listDelNode(l,ln); + listDelNode(l, ln); clusterNodeCleanupFailureReports(node); return 1; } @@ -1470,14 +1503,14 @@ int clusterNodeRemoveSlave(clusterNode *master, clusterNode *slave) { for (j = 0; j < master->numslaves; j++) { if (master->slaves[j] == slave) { - if ((j+1) < master->numslaves) { + if ((j + 1) < master->numslaves) { int remaining_slaves = (master->numslaves - j) - 1; - memmove(master->slaves+j,master->slaves+(j+1), - (sizeof(*master->slaves) * remaining_slaves)); + memmove(master->slaves + j, master->slaves + (j + 1), (sizeof(*master->slaves) * remaining_slaves)); } master->numslaves--; - if (master->numslaves == 0) + if (master->numslaves == 0) { master->flags &= ~CLUSTER_NODE_MIGRATE_TO; + } return C_OK; } } @@ -1488,10 +1521,12 @@ int clusterNodeAddSlave(clusterNode *master, clusterNode *slave) { int j; /* If it's already a slave, don't add it again. */ - for (j = 0; j < master->numslaves; j++) - if (master->slaves[j] == slave) return C_ERR; - master->slaves = zrealloc(master->slaves, - sizeof(clusterNode*)*(master->numslaves+1)); + for (j = 0; j < master->numslaves; j++) { + if (master->slaves[j] == slave) { + return C_ERR; + } + } + master->slaves = zrealloc(master->slaves, sizeof(clusterNode *) * (master->numslaves + 1)); master->slaves[master->numslaves] = slave; master->numslaves++; qsort(master->slaves, master->numslaves, sizeof(clusterNode *), clusterNodeNameComparator); @@ -1502,8 +1537,11 @@ int clusterNodeAddSlave(clusterNode *master, clusterNode *slave) { int clusterCountNonFailingSlaves(clusterNode *n) { int j, okslaves = 0; - for (j = 0; j < n->numslaves; j++) - if (!nodeFailed(n->slaves[j])) okslaves++; + for (j = 0; j < n->numslaves; j++) { + if (!nodeFailed(n->slaves[j])) { + okslaves++; + } + } return okslaves; } @@ -1514,22 +1552,29 @@ void freeClusterNode(clusterNode *n) { /* If the node has associated slaves, we have to set * all the slaves->slaveof fields to NULL (unknown). */ - for (j = 0; j < n->numslaves; j++) + for (j = 0; j < n->numslaves; j++) { n->slaves[j]->slaveof = NULL; + } /* Remove this node from the list of slaves of its master. */ - if (nodeIsSlave(n) && n->slaveof) clusterNodeRemoveSlave(n->slaveof,n); + if (nodeIsSlave(n) && n->slaveof) { + clusterNodeRemoveSlave(n->slaveof, n); + } /* Unlink from the set of nodes. */ nodename = sdsnewlen(n->name, CLUSTER_NAMELEN); - serverAssert(dictDelete(server.cluster->nodes,nodename) == DICT_OK); + serverAssert(dictDelete(server.cluster->nodes, nodename) == DICT_OK); sdsfree(nodename); sdsfree(n->hostname); sdsfree(n->human_nodename); /* Release links and associated data structures. */ - if (n->link) freeClusterLink(n->link); - if (n->inbound_link) freeClusterLink(n->inbound_link); + if (n->link) { + freeClusterLink(n->link); + } + if (n->inbound_link) { + freeClusterLink(n->inbound_link); + } listRelease(n->fail_reports); zfree(n->slaves); zfree(n); @@ -1539,8 +1584,7 @@ void freeClusterNode(clusterNode *n) { void clusterAddNode(clusterNode *node) { int retval; - retval = dictAdd(server.cluster->nodes, - sdsnewlen(node->name,CLUSTER_NAMELEN), node); + retval = dictAdd(server.cluster->nodes, sdsnewlen(node->name, CLUSTER_NAMELEN), node); serverAssert(retval == DICT_OK); } @@ -1563,21 +1607,26 @@ void clusterDelNode(clusterNode *delnode) { /* 1) Mark slots as unassigned. */ for (j = 0; j < CLUSTER_SLOTS; j++) { - if (server.cluster->importing_slots_from[j] == delnode) + if (server.cluster->importing_slots_from[j] == delnode) { server.cluster->importing_slots_from[j] = NULL; - if (server.cluster->migrating_slots_to[j] == delnode) + } + if (server.cluster->migrating_slots_to[j] == delnode) { server.cluster->migrating_slots_to[j] = NULL; - if (server.cluster->slots[j] == delnode) + } + if (server.cluster->slots[j] == delnode) { clusterDelSlot(j); + } } /* 2) Remove failure reports. */ di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); - if (node == delnode) continue; - clusterNodeDelFailureReport(node,delnode); + if (node == delnode) { + continue; + } + clusterNodeDelFailureReport(node, delnode); } dictReleaseIterator(di); @@ -1590,11 +1639,15 @@ void clusterDelNode(clusterNode *delnode) { /* Node lookup by name */ clusterNode *clusterLookupNode(const char *name, int length) { - if (verifyClusterNodeId(name, length) != C_OK) return NULL; + if (verifyClusterNodeId(name, length) != C_OK) { + return NULL; + } sds s = sdsnewlen(name, length); dictEntry *de = dictFind(server.cluster->nodes, s); sdsfree(s); - if (de == NULL) return NULL; + if (de == NULL) { + return NULL; + } return dictGetVal(de); } @@ -1606,7 +1659,7 @@ clusterNode *clusterLookupNode(const char *name, int length) { * release the list. */ list *clusterGetNodesInMyShard(clusterNode *node) { sds s = sdsnewlen(node->shard_id, CLUSTER_NAMELEN); - dictEntry *de = dictFind(server.cluster->shards,s); + dictEntry *de = dictFind(server.cluster->shards, s); sdsfree(s); return (de != NULL) ? dictGetVal(de) : NULL; } @@ -1619,10 +1672,7 @@ void clusterRenameNode(clusterNode *node, char *newname) { int retval; sds s = sdsnewlen(node->name, CLUSTER_NAMELEN); - serverLog(LL_DEBUG,"Renaming node %.40s (%s) into %.40s", - node->name, - node->human_nodename, - newname); + serverLog(LL_DEBUG, "Renaming node %.40s (%s) into %.40s", node->name, node->human_nodename, newname); retval = dictDelete(server.cluster->nodes, s); sdsfree(s); serverAssert(retval == DICT_OK); @@ -1633,7 +1683,7 @@ void clusterRenameNode(clusterNode *node, char *newname) { void clusterAddNodeToShard(const char *shard_id, clusterNode *node) { sds s = sdsnewlen(shard_id, CLUSTER_NAMELEN); - dictEntry *de = dictFind(server.cluster->shards,s); + dictEntry *de = dictFind(server.cluster->shards, s); if (de == NULL) { list *l = listCreate(); listAddNodeTail(l, node); @@ -1675,12 +1725,16 @@ uint64_t clusterGetMaxEpoch(void) { dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); - if (node->configEpoch > max) max = node->configEpoch; + if (node->configEpoch > max) { + max = node->configEpoch; + } } dictReleaseIterator(di); - if (max < server.cluster->currentEpoch) max = server.cluster->currentEpoch; + if (max < server.cluster->currentEpoch) { + max = server.cluster->currentEpoch; + } return max; } @@ -1716,16 +1770,11 @@ uint64_t clusterGetMaxEpoch(void) { int clusterBumpConfigEpochWithoutConsensus(void) { uint64_t maxEpoch = clusterGetMaxEpoch(); - if (myself->configEpoch == 0 || - myself->configEpoch != maxEpoch) - { + if (myself->configEpoch == 0 || myself->configEpoch != maxEpoch) { server.cluster->currentEpoch++; myself->configEpoch = server.cluster->currentEpoch; - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_FSYNC_CONFIG); - serverLog(LL_NOTICE, - "New configEpoch set to %llu", - (unsigned long long) myself->configEpoch); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_FSYNC_CONFIG); + serverLog(LL_NOTICE, "New configEpoch set to %llu", (unsigned long long)myself->configEpoch); return C_OK; } else { return C_ERR; @@ -1780,19 +1829,21 @@ int clusterBumpConfigEpochWithoutConsensus(void) { */ void clusterHandleConfigEpochCollision(clusterNode *sender) { /* Prerequisites: nodes have the same configEpoch and are both masters. */ - if (sender->configEpoch != myself->configEpoch || - !clusterNodeIsMaster(sender) || !clusterNodeIsMaster(myself)) return; + if (sender->configEpoch != myself->configEpoch || !clusterNodeIsMaster(sender) || !clusterNodeIsMaster(myself)) { + return; + } /* Don't act if the colliding node has a smaller Node ID. */ - if (memcmp(sender->name,myself->name,CLUSTER_NAMELEN) <= 0) return; + if (memcmp(sender->name, myself->name, CLUSTER_NAMELEN) <= 0) { + return; + } /* Get the next ID available at the best of this node knowledge. */ server.cluster->currentEpoch++; myself->configEpoch = server.cluster->currentEpoch; clusterSaveConfigOrDie(1); serverLog(LL_VERBOSE, - "WARNING: configEpoch collision with node %.40s (%s)." - " configEpoch set to %llu", - sender->name,sender->human_nodename, - (unsigned long long) myself->configEpoch); + "WARNING: configEpoch collision with node %.40s (%s)." + " configEpoch set to %llu", + sender->name, sender->human_nodename, (unsigned long long)myself->configEpoch); } /* ----------------------------------------------------------------------------- @@ -1817,7 +1868,7 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { * value. * -------------------------------------------------------------------------- */ -#define CLUSTER_BLACKLIST_TTL 60 /* 1 minute. */ +#define CLUSTER_BLACKLIST_TTL 60 /* 1 minute. */ /* Before of the addNode() or Exists() operations we always remove expired @@ -1831,11 +1882,12 @@ void clusterBlacklistCleanup(void) { dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes_black_list); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { int64_t expire = dictGetUnsignedIntegerVal(de); - if (expire < server.unixtime) - dictDelete(server.cluster->nodes_black_list,dictGetKey(de)); + if (expire < server.unixtime) { + dictDelete(server.cluster->nodes_black_list, dictGetKey(de)); + } } dictReleaseIterator(di); } @@ -1843,16 +1895,16 @@ void clusterBlacklistCleanup(void) { /* Cleanup the blacklist and add a new node ID to the black list. */ void clusterBlacklistAddNode(clusterNode *node) { dictEntry *de; - sds id = sdsnewlen(node->name,CLUSTER_NAMELEN); + sds id = sdsnewlen(node->name, CLUSTER_NAMELEN); clusterBlacklistCleanup(); - if (dictAdd(server.cluster->nodes_black_list,id,NULL) == DICT_OK) { + if (dictAdd(server.cluster->nodes_black_list, id, NULL) == DICT_OK) { /* If the key was added, duplicate the sds string representation of * the key for the next lookup. We'll free it at the end. */ id = sdsdup(id); } - de = dictFind(server.cluster->nodes_black_list,id); - dictSetUnsignedIntegerVal(de,time(NULL)+CLUSTER_BLACKLIST_TTL); + de = dictFind(server.cluster->nodes_black_list, id); + dictSetUnsignedIntegerVal(de, time(NULL) + CLUSTER_BLACKLIST_TTL); sdsfree(id); } @@ -1860,11 +1912,11 @@ void clusterBlacklistAddNode(clusterNode *node) { * You don't need to pass an sds string here, any pointer to 40 bytes * will work. */ int clusterBlacklistExists(char *nodeid) { - sds id = sdsnewlen(nodeid,CLUSTER_NAMELEN); + sds id = sdsnewlen(nodeid, CLUSTER_NAMELEN); int retval; clusterBlacklistCleanup(); - retval = dictFind(server.cluster->nodes_black_list,id) != NULL; + retval = dictFind(server.cluster->nodes_black_list, id) != NULL; sdsfree(id); return retval; } @@ -1898,16 +1950,23 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { int failures; int needed_quorum = (server.cluster->size / 2) + 1; - if (!nodeTimedOut(node)) return; /* We can reach it. */ - if (nodeFailed(node)) return; /* Already FAILing. */ + if (!nodeTimedOut(node)) { + return; /* We can reach it. */ + } + if (nodeFailed(node)) { + return; /* Already FAILing. */ + } failures = clusterNodeFailureReportsCount(node); /* Also count myself as a voter if I'm a master. */ - if (clusterNodeIsMaster(myself)) failures++; - if (failures < needed_quorum) return; /* No weak agreement from masters. */ + if (clusterNodeIsMaster(myself)) { + failures++; + } + if (failures < needed_quorum) { + return; /* No weak agreement from masters. */ + } - serverLog(LL_NOTICE, - "Marking node %.40s (%s) as failing (quorum reached).", node->name, node->human_nodename); + serverLog(LL_NOTICE, "Marking node %.40s (%s) as failing (quorum reached).", node->name, node->human_nodename); /* Mark the node as failing. */ node->flags &= ~CLUSTER_NODE_PFAIL; @@ -1920,7 +1979,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { * the failing state is triggered collecting failure reports from masters, * so here the replica is only helping propagating this status. */ clusterSendFail(node->name); - clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); } /* This function is called only if a node is marked as FAIL, but we are able @@ -1934,12 +1993,10 @@ void clearNodeFailureIfNeeded(clusterNode *node) { /* For slaves we always clear the FAIL flag if we can contact the * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { - serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s (%s):%s is reachable again.", - node->name,node->human_nodename, - nodeIsSlave(node) ? "replica" : "master without slots"); + serverLog(LL_NOTICE, "Clear FAIL state for node %.40s (%s):%s is reachable again.", node->name, + node->human_nodename, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; - clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); } /* If it is a master and... @@ -1947,14 +2004,13 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * 2) It is yet serving slots from our point of view (not failed over). * Apparently no one is going to fix these slots, clear the FAIL flag. */ if (clusterNodeIsMaster(node) && node->numslots > 0 && - (now - node->fail_time) > - (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) - { - serverLog(LL_NOTICE, + (now - node->fail_time) > (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { + serverLog( + LL_NOTICE, "Clear FAIL state for node %.40s (%s): is reachable again and nobody is serving its slots after some time.", - node->name, node->human_nodename); + node->name, node->human_nodename); node->flags &= ~CLUSTER_NODE_FAIL; - clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); } } @@ -1966,13 +2022,15 @@ int clusterHandshakeInProgress(char *ip, int port, int cport) { dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); - if (!nodeInHandshake(node)) continue; - if (!strcasecmp(node->ip,ip) && - getNodeDefaultClientPort(node) == port && - node->cport == cport) break; + if (!nodeInHandshake(node)) { + continue; + } + if (!strcasecmp(node->ip, ip) && getNodeDefaultClientPort(node) == port && node->cport == cport) { + break; + } } dictReleaseIterator(di); return de != NULL; @@ -1991,13 +2049,9 @@ int clusterStartHandshake(char *ip, int port, int cport) { struct sockaddr_storage sa; /* IP sanity check */ - if (inet_pton(AF_INET,ip, - &(((struct sockaddr_in *)&sa)->sin_addr))) - { + if (inet_pton(AF_INET, ip, &(((struct sockaddr_in *)&sa)->sin_addr))) { sa.ss_family = AF_INET; - } else if (inet_pton(AF_INET6,ip, - &(((struct sockaddr_in6 *)&sa)->sin6_addr))) - { + } else if (inet_pton(AF_INET6, ip, &(((struct sockaddr_in6 *)&sa)->sin6_addr))) { sa.ss_family = AF_INET6; } else { errno = EINVAL; @@ -2012,17 +2066,14 @@ int clusterStartHandshake(char *ip, int port, int cport) { /* Set norm_ip as the normalized string representation of the node * IP address. */ - memset(norm_ip,0,NET_IP_STR_LEN); - if (sa.ss_family == AF_INET) - inet_ntop(AF_INET, - (void*)&(((struct sockaddr_in *)&sa)->sin_addr), - norm_ip,NET_IP_STR_LEN); - else - inet_ntop(AF_INET6, - (void*)&(((struct sockaddr_in6 *)&sa)->sin6_addr), - norm_ip,NET_IP_STR_LEN); - - if (clusterHandshakeInProgress(norm_ip,port,cport)) { + memset(norm_ip, 0, NET_IP_STR_LEN); + if (sa.ss_family == AF_INET) { + inet_ntop(AF_INET, (void *)&(((struct sockaddr_in *)&sa)->sin_addr), norm_ip, NET_IP_STR_LEN); + } else { + inet_ntop(AF_INET6, (void *)&(((struct sockaddr_in6 *)&sa)->sin6_addr), norm_ip, NET_IP_STR_LEN); + } + + if (clusterHandshakeInProgress(norm_ip, port, cport)) { errno = EAGAIN; return 0; } @@ -2030,8 +2081,8 @@ int clusterStartHandshake(char *ip, int port, int cport) { /* Add the node with a random address (NULL as first argument to * createClusterNode()). Everything will be fixed during the * handshake. */ - n = createClusterNode(NULL,CLUSTER_NODE_HANDSHAKE|CLUSTER_NODE_MEET); - memcpy(n->ip,norm_ip,sizeof(n->ip)); + n = createClusterNode(NULL, CLUSTER_NODE_HANDSHAKE | CLUSTER_NODE_MEET); + memcpy(n->ip, norm_ip, sizeof(n->ip)); if (server.tls_cluster) { n->tls_port = port; } else { @@ -2067,14 +2118,14 @@ static void getClientPortFromGossip(clusterMsgDataGossip *g, int *tls_port, int char *getCorruptedNodeIdByteString(clusterMsgDataGossip *gossip_msg) { const int num_bytes = CLUSTER_NAMELEN + 8; /* Allocate enough room for 4 chars per byte + null terminator */ - char *byte_string = (char*) zmalloc((num_bytes*4) + 1); + char *byte_string = (char *)zmalloc((num_bytes * 4) + 1); const char *name_ptr = gossip_msg->nodename; /* Ensure we won't print beyond the bounds of the message */ - serverAssert(name_ptr + num_bytes <= (char*)gossip_msg + sizeof(clusterMsgDataGossip)); + serverAssert(name_ptr + num_bytes <= (char *)gossip_msg + sizeof(clusterMsgDataGossip)); for (int i = 0; i < num_bytes; i++) { - snprintf(byte_string + 4*i, 5, "\\x%02hhX", name_ptr[i]); + snprintf(byte_string + 4 * i, 5, "\\x%02hhX", name_ptr[i]); } return byte_string; } @@ -2103,7 +2154,7 @@ int verifyGossipSectionNodeIds(clusterMsgDataGossip *g, uint16_t count) { * length. */ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { uint16_t count = ntohs(hdr->count); - clusterMsgDataGossip *g = (clusterMsgDataGossip*) hdr->data.ping.gossip; + clusterMsgDataGossip *g = (clusterMsgDataGossip *)hdr->data.ping.gossip; clusterNode *sender = link->node ? link->node : clusterLookupNode(hdr->sender, CLUSTER_NAMELEN); /* Abort if the gossip contains invalid node IDs to avoid adding incorrect information to @@ -2111,26 +2162,22 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { int invalid_ids = verifyGossipSectionNodeIds(g, count); if (invalid_ids) { if (sender) { - serverLog(LL_WARNING, "Node %.40s (%s) gossiped %d nodes with invalid IDs.", sender->name, sender->human_nodename, invalid_ids); + serverLog(LL_WARNING, "Node %.40s (%s) gossiped %d nodes with invalid IDs.", sender->name, + sender->human_nodename, invalid_ids); } else { serverLog(LL_WARNING, "Unknown node gossiped %d nodes with invalid IDs.", invalid_ids); } return; } - while(count--) { + while (count--) { uint16_t flags = ntohs(g->flags); clusterNode *node; sds ci; if (server.verbosity == LL_DEBUG) { ci = representClusterNodeFlags(sdsempty(), flags); - serverLog(LL_DEBUG,"GOSSIP %.40s %s:%d@%d %s", - g->nodename, - g->ip, - ntohs(g->port), - ntohs(g->cport), - ci); + serverLog(LL_DEBUG, "GOSSIP %.40s %s:%d@%d %s", g->nodename, g->ip, ntohs(g->port), ntohs(g->cport), ci); sdsfree(ci); } @@ -2145,18 +2192,16 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { /* We already know this node. Handle failure reports, only when the sender is a master. */ if (sender && clusterNodeIsMaster(sender)) { - if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { - if (clusterNodeAddFailureReport(node,sender)) { - serverLog(LL_VERBOSE, - "Node %.40s (%s) reported node %.40s (%s) as not reachable.", - sender->name, sender->human_nodename, node->name, node->human_nodename); + if (flags & (CLUSTER_NODE_FAIL | CLUSTER_NODE_PFAIL)) { + if (clusterNodeAddFailureReport(node, sender)) { + serverLog(LL_VERBOSE, "Node %.40s (%s) reported node %.40s (%s) as not reachable.", + sender->name, sender->human_nodename, node->name, node->human_nodename); } markNodeAsFailingIfNeeded(node); } else { - if (clusterNodeDelFailureReport(node,sender)) { - serverLog(LL_VERBOSE, - "Node %.40s (%s) reported node %.40s (%s) is back online.", - sender->name, sender->human_nodename, node->name, node->human_nodename); + if (clusterNodeDelFailureReport(node, sender)) { + serverLog(LL_VERBOSE, "Node %.40s (%s) reported node %.40s (%s) is back online.", sender->name, + sender->human_nodename, node->name, node->human_nodename); } } } @@ -2165,10 +2210,8 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { * we have no pending ping for the node, nor we have failure * reports for this node, update the last pong time with the * one we see from the other nodes. */ - if (!(flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) && - node->ping_sent == 0 && - clusterNodeFailureReportsCount(node) == 0) - { + if (!(flags & (CLUSTER_NODE_FAIL | CLUSTER_NODE_PFAIL)) && node->ping_sent == 0 && + clusterNodeFailureReportsCount(node) == 0) { mstime_t pongtime = ntohl(g->pong_received); pongtime *= 1000; /* Convert back to milliseconds. */ @@ -2176,9 +2219,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { * it's greater than our view but is not in the future * (with 500 milliseconds tolerance) from the POV of our * clock. */ - if (pongtime <= (server.mstime+500) && - pongtime > node->pong_received) - { + if (pongtime <= (server.mstime + 500) && pongtime > node->pong_received) { node->pong_received = pongtime; } } @@ -2188,16 +2229,16 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { * can talk with this other node, update the address, disconnect * the old link if any, so that we'll attempt to connect with the * new address. */ - if (node->flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL) && - !(flags & CLUSTER_NODE_NOADDR) && - !(flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) && - (strcasecmp(node->ip,g->ip) || + if (node->flags & (CLUSTER_NODE_FAIL | CLUSTER_NODE_PFAIL) && !(flags & CLUSTER_NODE_NOADDR) && + !(flags & (CLUSTER_NODE_FAIL | CLUSTER_NODE_PFAIL)) && + (strcasecmp(node->ip, g->ip) || node->tls_port != (server.tls_cluster ? ntohs(g->port) : ntohs(g->pport)) || node->tcp_port != (server.tls_cluster ? ntohs(g->pport) : ntohs(g->port)) || - node->cport != ntohs(g->cport))) - { - if (node->link) freeClusterLink(node->link); - memcpy(node->ip,g->ip,NET_IP_STR_LEN); + node->cport != ntohs(g->cport))) { + if (node->link) { + freeClusterLink(node->link); + } + memcpy(node->ip, g->ip, NET_IP_STR_LEN); node->tcp_port = msg_tcp_port; node->tls_port = msg_tls_port; node->cport = ntohs(g->cport); @@ -2213,13 +2254,10 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { * Note that we require that the sender of this gossip message * is a well known node in our cluster, otherwise we risk * joining another cluster. */ - if (sender && - !(flags & CLUSTER_NODE_NOADDR) && - !clusterBlacklistExists(g->nodename)) - { + if (sender && !(flags & CLUSTER_NODE_NOADDR) && !clusterBlacklistExists(g->nodename)) { clusterNode *node; node = createClusterNode(g->nodename, flags); - memcpy(node->ip,g->ip,NET_IP_STR_LEN); + memcpy(node->ip, g->ip, NET_IP_STR_LEN); node->tcp_port = msg_tcp_port; node->tls_port = msg_tls_port; node->cport = ntohs(g->cport); @@ -2238,13 +2276,13 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { * the IP from the socket peer address. */ int nodeIp2String(char *buf, clusterLink *link, char *announced_ip) { if (announced_ip[0] != '\0') { - memcpy(buf,announced_ip,NET_IP_STR_LEN); - buf[NET_IP_STR_LEN-1] = '\0'; /* We are not sure the input is sane. */ + memcpy(buf, announced_ip, NET_IP_STR_LEN); + buf[NET_IP_STR_LEN - 1] = '\0'; /* We are not sure the input is sane. */ return C_OK; } else { if (connAddrPeerName(link->conn, buf, NET_IP_STR_LEN, NULL) == -1) { serverLog(LL_NOTICE, "Error converting peer IP to string: %s", - link->conn ? connGetLastError(link->conn) : "no link"); + link->conn ? connGetLastError(link->conn) : "no link"); return C_ERR; } return C_OK; @@ -2263,9 +2301,7 @@ int nodeIp2String(char *buf, clusterLink *link, char *announced_ip) { * * The function returns 0 if the node address is still the same, * otherwise 1 is returned. */ -int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, - clusterMsg *hdr) -{ +int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, clusterMsg *hdr) { char ip[NET_IP_STR_LEN] = {0}; int cport = ntohs(hdr->cport); int tcp_port, tls_port; @@ -2277,30 +2313,38 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, * * As a side effect this function never frees the passed 'link', so * it is safe to call during packet processing. */ - if (link == node->link) return 0; + if (link == node->link) { + return 0; + } /* If the peer IP is unavailable for some reasons like invalid fd or closed * link, just give up the update this time, and the update will be retried * in the next round of PINGs */ - if (nodeIp2String(ip,link,hdr->myip) == C_ERR) return 0; + if (nodeIp2String(ip, link, hdr->myip) == C_ERR) { + return 0; + } - if (node->tcp_port == tcp_port && node->cport == cport && node->tls_port == tls_port && - strcmp(ip,node->ip) == 0) return 0; + if (node->tcp_port == tcp_port && node->cport == cport && node->tls_port == tls_port && strcmp(ip, node->ip) == 0) { + return 0; + } /* IP / port is different, update it. */ - memcpy(node->ip,ip,sizeof(ip)); + memcpy(node->ip, ip, sizeof(ip)); node->tcp_port = tcp_port; node->tls_port = tls_port; node->cport = cport; - if (node->link) freeClusterLink(node->link); + if (node->link) { + freeClusterLink(node->link); + } node->flags &= ~CLUSTER_NODE_NOADDR; - serverLog(LL_NOTICE,"Address updated for node %.40s (%s), now %s:%d", - node->name, node->human_nodename, node->ip, getNodeDefaultClientPort(node)); + serverLog(LL_NOTICE, "Address updated for node %.40s (%s), now %s:%d", node->name, node->human_nodename, node->ip, + getNodeDefaultClientPort(node)); /* Check if this is our master and we have to change the * replication target as well. */ - if (nodeIsSlave(myself) && myself->slaveof == node) + if (nodeIsSlave(myself) && myself->slaveof == node) { replicationSetMaster(node->ip, getNodeDefaultReplicationPort(node)); + } return 1; } @@ -2308,19 +2352,22 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, * a node that we believed to be a slave is now acting as master in order to * update the state of the node. */ void clusterSetNodeAsMaster(clusterNode *n) { - if (clusterNodeIsMaster(n)) return; + if (clusterNodeIsMaster(n)) { + return; + } if (n->slaveof) { - clusterNodeRemoveSlave(n->slaveof,n); - if (n != myself) n->flags |= CLUSTER_NODE_MIGRATE_TO; + clusterNodeRemoveSlave(n->slaveof, n); + if (n != myself) { + n->flags |= CLUSTER_NODE_MIGRATE_TO; + } } n->flags &= ~CLUSTER_NODE_SLAVE; n->flags |= CLUSTER_NODE_MASTER; n->slaveof = NULL; /* Update config and state. */ - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE); } /* This function is called when we receive a master configuration via a @@ -2359,12 +2406,12 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc curmaster = clusterNodeIsMaster(myself) ? myself : myself->slaveof; if (sender == myself) { - serverLog(LL_NOTICE,"Discarding UPDATE message about myself."); + serverLog(LL_NOTICE, "Discarding UPDATE message about myself."); return; } for (j = 0; j < CLUSTER_SLOTS; j++) { - if (bitmapTestBit(slots,j)) { + if (bitmapTestBit(slots, j)) { sender_slots++; /* The slot is already bound to the sender of this message. */ @@ -2376,30 +2423,19 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc /* We rebind the slot to the new node claiming it if * the slot was unassigned or the new node claims it with a * greater configEpoch. */ - if (isSlotUnclaimed(j) || - server.cluster->slots[j]->configEpoch < senderConfigEpoch) - { - if (!isSlotUnclaimed(j) && - !areInSameShard(server.cluster->slots[j], sender)) - { + if (isSlotUnclaimed(j) || server.cluster->slots[j]->configEpoch < senderConfigEpoch) { + if (!isSlotUnclaimed(j) && !areInSameShard(server.cluster->slots[j], sender)) { serverLog(LL_NOTICE, - "Slot %d is migrated from node %.40s (%s) in shard %.40s" - " to node %.40s (%s) in shard %.40s.", - j, - server.cluster->slots[j]->name, - server.cluster->slots[j]->human_nodename, - server.cluster->slots[j]->shard_id, - sender->name, - sender->human_nodename, - sender->shard_id); + "Slot %d is migrated from node %.40s (%s) in shard %.40s" + " to node %.40s (%s) in shard %.40s.", + j, server.cluster->slots[j]->name, server.cluster->slots[j]->human_nodename, + server.cluster->slots[j]->shard_id, sender->name, sender->human_nodename, + sender->shard_id); } /* Was this slot mine, and still contains keys? Mark it as * a dirty slot. */ - if (server.cluster->slots[j] == myself && - countKeysInSlot(j) && - sender != myself) - { + if (server.cluster->slots[j] == myself && countKeysInSlot(j) && sender != myself) { dirty_slots[dirty_slots_count] = j; dirty_slots_count++; } @@ -2417,113 +2453,91 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc * for the slot in question */ if (server.cluster->migrating_slots_to[j] != NULL) { if (!areInSameShard(sender, myself)) { - serverLog(LL_NOTICE, - "Slot %d is no longer being migrated to node %.40s (%s) in shard %.40s.", - j, - server.cluster->migrating_slots_to[j]->name, - server.cluster->migrating_slots_to[j]->human_nodename, - server.cluster->migrating_slots_to[j]->shard_id); + serverLog(LL_NOTICE, "Slot %d is no longer being migrated to node %.40s (%s) in shard %.40s.", + j, server.cluster->migrating_slots_to[j]->name, + server.cluster->migrating_slots_to[j]->human_nodename, + server.cluster->migrating_slots_to[j]->shard_id); server.cluster->migrating_slots_to[j] = NULL; } } /* Handle the case where we are importing this slot and the ownership changes */ if (server.cluster->importing_slots_from[j] != NULL && - server.cluster->importing_slots_from[j] != sender) - { + server.cluster->importing_slots_from[j] != sender) { /* Update importing_slots_from to point to the sender, if it is in the * same shard as the previous slot owner */ if (areInSameShard(sender, server.cluster->importing_slots_from[j])) { serverLog(LL_NOTICE, - "Failover occurred in migration source. Update importing " - "source for slot %d to node %.40s (%s) in shard %.40s.", - j, - sender->name, - sender->human_nodename, - sender->shard_id); + "Failover occurred in migration source. Update importing " + "source for slot %d to node %.40s (%s) in shard %.40s.", + j, sender->name, sender->human_nodename, sender->shard_id); server.cluster->importing_slots_from[j] = sender; } else { /* If the sender is from a different shard, it must be a result * of deliberate operator actions. We should clear the importing * state to conform to the operator's will. */ - serverLog(LL_NOTICE, - "Slot %d is no longer being imported from node %.40s (%s) in shard %.40s.", - j, - server.cluster->importing_slots_from[j]->name, - server.cluster->importing_slots_from[j]->human_nodename, - server.cluster->importing_slots_from[j]->shard_id); + serverLog(LL_NOTICE, "Slot %d is no longer being imported from node %.40s (%s) in shard %.40s.", + j, server.cluster->importing_slots_from[j]->name, + server.cluster->importing_slots_from[j]->human_nodename, + server.cluster->importing_slots_from[j]->shard_id); server.cluster->importing_slots_from[j] = NULL; } } clusterDelSlot(j); - clusterAddSlot(sender,j); + clusterAddSlot(sender, j); bitmapClearBit(server.cluster->owner_not_claiming_slot, j); - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE| - CLUSTER_TODO_FSYNC_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_FSYNC_CONFIG); } } else { if (server.cluster->slots[j] == sender) { /* The slot is currently bound to the sender but the sender is no longer - * claiming it. We don't want to unbind the slot yet as it can cause the cluster - * to move to FAIL state and also throw client error. Keeping the slot bound to - * the previous owner will cause a few client side redirects, but won't throw - * any errors. We will keep track of the uncertainty in ownership to avoid - * propagating misinformation about this slot's ownership using UPDATE - * messages. */ + * claiming it. We don't want to unbind the slot yet as it can cause the cluster + * to move to FAIL state and also throw client error. Keeping the slot bound to + * the previous owner will cause a few client side redirects, but won't throw + * any errors. We will keep track of the uncertainty in ownership to avoid + * propagating misinformation about this slot's ownership using UPDATE + * messages. */ bitmapSetBit(server.cluster->owner_not_claiming_slot, j); } /* If the sender doesn't claim the slot, check if we are migrating - * any slot to its shard and if there is a primaryship change in - * the shard. Update the migrating_slots_to state to point to the - * sender if it has just taken over the primary role. */ - if (server.cluster->migrating_slots_to[j] != NULL && - server.cluster->migrating_slots_to[j] != sender && + * any slot to its shard and if there is a primaryship change in + * the shard. Update the migrating_slots_to state to point to the + * sender if it has just taken over the primary role. */ + if (server.cluster->migrating_slots_to[j] != NULL && server.cluster->migrating_slots_to[j] != sender && (server.cluster->migrating_slots_to[j]->configEpoch < senderConfigEpoch || - nodeIsSlave(server.cluster->migrating_slots_to[j])) && - areInSameShard(server.cluster->migrating_slots_to[j], sender)) - { + nodeIsSlave(server.cluster->migrating_slots_to[j])) && + areInSameShard(server.cluster->migrating_slots_to[j], sender)) { serverLog(LL_NOTICE, - "Failover occurred in migration target." - " Slot %d is now being migrated to node %.40s (%s) in shard %.40s.", - j, - sender->name, - sender->human_nodename, - sender->shard_id); + "Failover occurred in migration target." + " Slot %d is now being migrated to node %.40s (%s) in shard %.40s.", + j, sender->name, sender->human_nodename, sender->shard_id); server.cluster->migrating_slots_to[j] = sender; - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE| - CLUSTER_TODO_FSYNC_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_FSYNC_CONFIG); } /* If the sender is no longer the owner of the slot, and I am a primary - * and I am still in the process of importing the slot from the sender, - * there are two possibilities: - * - * 1. I could be a replica of the target primary and missed the slot - * finalization step on my primary due to my primary crashing during - * the slot migration process. - * 2. I could be the original primary and missed the slot finalization - * step entirely. - * - * To ensure complete slot coverage in either case, the following steps - * will be taken: - * - * 1. Remove the importing state for the specific slot. - * 2. Finalize the slot's ownership, if I am not already the owner of - * the slot. */ - if (nodeIsMaster(myself) && - server.cluster->importing_slots_from[j] == sender) - { + * and I am still in the process of importing the slot from the sender, + * there are two possibilities: + * + * 1. I could be a replica of the target primary and missed the slot + * finalization step on my primary due to my primary crashing during + * the slot migration process. + * 2. I could be the original primary and missed the slot finalization + * step entirely. + * + * To ensure complete slot coverage in either case, the following steps + * will be taken: + * + * 1. Remove the importing state for the specific slot. + * 2. Finalize the slot's ownership, if I am not already the owner of + * the slot. */ + if (nodeIsMaster(myself) && server.cluster->importing_slots_from[j] == sender) { serverLog(LL_NOTICE, - "Slot %d is no longer being imported from node %.40s (%s) in shard %.40s;" - " Clear my importing source for the slot.", - j, - sender->name, - sender->human_nodename, - sender->shard_id); + "Slot %d is no longer being imported from node %.40s (%s) in shard %.40s;" + " Clear my importing source for the slot.", + j, sender->name, sender->human_nodename, sender->shard_id); server.cluster->importing_slots_from[j] = NULL; /* Take over the slot ownership if I am not the owner yet*/ if (server.cluster->slots[j] != myself) { @@ -2540,10 +2554,9 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc * this as a very rare case and err on the side of being consistent with the current * practice. */ clusterDelSlot(j); - clusterAddSlot(myself,j); + clusterAddSlot(myself, j); clusterBumpConfigEpochWithoutConsensus(); - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE| + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_FSYNC_CONFIG); } } @@ -2553,20 +2566,16 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc /* After updating the slots configuration, don't do any actual change * in the state of the server if a module disabled Cluster * keys redirections. */ - if (server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_REDIRECTION) + if (server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_REDIRECTION) { return; + } /* Handle a special case where newmaster is not set but both sender * and myself own no slots and in the same shard. Set the sender as * the new primary if my current config epoch is lower than the * sender's. */ - if (!newmaster && - myself->slaveof != sender && - sender_slots == 0 && - myself->numslots == 0 && - nodeEpoch(myself) < senderConfigEpoch && - areInSameShard(sender, myself)) - { + if (!newmaster && myself->slaveof != sender && sender_slots == 0 && myself->numslots == 0 && + nodeEpoch(myself) < senderConfigEpoch && areInSameShard(sender, myself)) { newmaster = sender; } @@ -2589,32 +2598,24 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc * shard and our primary just had its last slot migrated to the * sender. In this case we don't reconfigure ourselves as a replica * of the sender. */ - if (newmaster && curmaster->numslots == 0) { + if (newmaster && curmaster->numslots == 0) { if (server.cluster_allow_replica_migration || areInSameShard(sender, myself)) { serverLog(LL_NOTICE, - "Configuration change detected. Reconfiguring myself " - "as a replica of node %.40s (%s) in shard %.40s", - sender->name, - sender->human_nodename, - sender->shard_id); + "Configuration change detected. Reconfiguring myself " + "as a replica of node %.40s (%s) in shard %.40s", + sender->name, sender->human_nodename, sender->shard_id); /* Don't clear the migrating/importing states if this is a replica that * just gets promoted to the new primary in the shard. */ clusterSetMaster(sender, !areInSameShard(sender, myself)); - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE| - CLUSTER_TODO_FSYNC_CONFIG); - } else if ((sender_slots >= migrated_our_slots) && - !areInSameShard(sender, myself)) - { + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_FSYNC_CONFIG); + } else if ((sender_slots >= migrated_our_slots) && !areInSameShard(sender, myself)) { /* When all our slots are lost to the sender and the sender belongs to * a different shard, this is likely due to a client triggered slot * migration. Don't reconfigure this node to migrate to the new shard * in this case. */ serverLog(LL_NOTICE, - "My last slot was migrated to node %.40s (%s) in shard %.40s. I am now an empty master.", - sender->name, - sender->human_nodename, - sender->shard_id); + "My last slot was migrated to node %.40s (%s) in shard %.40s. I am now an empty master.", + sender->name, sender->human_nodename, sender->shard_id); } } else if (dirty_slots_count) { /* If we are here, we received an update message which removed @@ -2625,13 +2626,8 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc * In order to maintain a consistent state between keys and slots * we need to remove all the keys from the slots we lost. */ for (int j = 0; j < dirty_slots_count; j++) { - serverLog(LL_NOTICE, - "Deleting keys in dirty slot %d on node %.40s (%s) in shard %.40s", - dirty_slots[j], - myself->name, - myself->human_nodename, - myself->shard_id - ); + serverLog(LL_NOTICE, "Deleting keys in dirty slot %d on node %.40s (%s) in shard %.40s", dirty_slots[j], + myself->name, myself->human_nodename, myself->shard_id); delKeysInSlot(dirty_slots[j]); } } @@ -2642,7 +2638,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc * The ping/pong/meet messages support arbitrary extensions to add additional * metadata to the messages that are sent between the various nodes in the * cluster. The extensions take the form: - * [ Header length + type (8 bytes) ] + * [ Header length + type (8 bytes) ] * [ Extension information (Arbitrary length, but must be 8 byte padded) ] */ @@ -2655,20 +2651,19 @@ static uint32_t getPingExtLength(clusterMsgPingExt *ext) { /* Returns the initial position of ping extensions. May return an invalid * address if there are no ping extensions. */ static clusterMsgPingExt *getInitialPingExt(clusterMsg *hdr, int count) { - clusterMsgPingExt *initial = (clusterMsgPingExt*) &(hdr->data.ping.gossip[count]); + clusterMsgPingExt *initial = (clusterMsgPingExt *)&(hdr->data.ping.gossip[count]); return initial; -} +} /* Given a current ping extension, returns the start of the next extension. May return * an invalid address if there are no further ping extensions. */ static clusterMsgPingExt *getNextPingExt(clusterMsgPingExt *ext) { - clusterMsgPingExt *next = (clusterMsgPingExt *) (((char *) ext) + getPingExtLength(ext)); + clusterMsgPingExt *next = (clusterMsgPingExt *)(((char *)ext) + getPingExtLength(ext)); return next; } /* All PING extensions must be 8-byte aligned */ uint32_t getAlignedPingExtSize(uint32_t dataSize) { - return sizeof(clusterMsgPingExt) + EIGHT_BYTE_ALIGN(dataSize); } @@ -2701,7 +2696,7 @@ void *preparePingExt(clusterMsgPingExt *ext, uint16_t type, uint32_t length) { } clusterMsgPingExt *nextPingExt(clusterMsgPingExt *ext) { - return (clusterMsgPingExt *)((char*)ext + ntohl(ext->length)); + return (clusterMsgPingExt *)((char *)ext + ntohl(ext->length)); } /* 1. If a NULL hdr is provided, compute the extension size; @@ -2710,7 +2705,7 @@ clusterMsgPingExt *nextPingExt(clusterMsgPingExt *ext) { * will update the cursor to point to the end of the * written extension and will return the amount of bytes * written. */ -uint32_t writePingExt(clusterMsg *hdr, int gossipcount) { +uint32_t writePingExt(clusterMsg *hdr, int gossipcount) { uint16_t extensions = 0; uint32_t totlen = 0; clusterMsgPingExt *cursor = NULL; @@ -2723,7 +2718,8 @@ uint32_t writePingExt(clusterMsg *hdr, int gossipcount) { if (sdslen(myself->hostname) != 0) { if (cursor != NULL) { /* Populate hostname */ - clusterMsgPingExtHostname *ext = preparePingExt(cursor, CLUSTERMSG_EXT_TYPE_HOSTNAME, getHostnamePingExtSize()); + clusterMsgPingExtHostname *ext = + preparePingExt(cursor, CLUSTERMSG_EXT_TYPE_HOSTNAME, getHostnamePingExtSize()); memcpy(ext->hostname, myself->hostname, sdslen(myself->hostname)); /* Move the write cursor */ @@ -2737,9 +2733,10 @@ uint32_t writePingExt(clusterMsg *hdr, int gossipcount) { if (sdslen(myself->human_nodename) != 0) { if (cursor != NULL) { /* Populate human_nodename */ - clusterMsgPingExtHumanNodename *ext = preparePingExt(cursor, CLUSTERMSG_EXT_TYPE_HUMAN_NODENAME, getHumanNodenamePingExtSize()); + clusterMsgPingExtHumanNodename *ext = + preparePingExt(cursor, CLUSTERMSG_EXT_TYPE_HUMAN_NODENAME, getHumanNodenamePingExtSize()); memcpy(ext->human_nodename, myself->human_nodename, sdslen(myself->human_nodename)); - + /* Move the write cursor */ cursor = nextPingExt(cursor); } @@ -2755,9 +2752,12 @@ uint32_t writePingExt(clusterMsg *hdr, int gossipcount) { while ((de = dictNext(di)) != NULL) { if (cursor != NULL) { uint64_t expire = dictGetUnsignedIntegerVal(de); - if ((time_t)expire < server.unixtime) continue; /* already expired */ + if ((time_t)expire < server.unixtime) { + continue; /* already expired */ + } uint64_t ttl = expire - server.unixtime; - clusterMsgPingExtForgottenNode *ext = preparePingExt(cursor, CLUSTERMSG_EXT_TYPE_FORGOTTEN_NODE, getForgottenNodeExtSize()); + clusterMsgPingExtForgottenNode *ext = + preparePingExt(cursor, CLUSTERMSG_EXT_TYPE_FORGOTTEN_NODE, getForgottenNodeExtSize()); memcpy(ext->name, dictGetKey(de), CLUSTER_NAMELEN); ext->ttl = htonu64(ttl); @@ -2802,10 +2802,11 @@ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { while (extensions--) { uint16_t type = ntohs(ext->type); if (type == CLUSTERMSG_EXT_TYPE_HOSTNAME) { - clusterMsgPingExtHostname *hostname_ext = (clusterMsgPingExtHostname *) &(ext->ext[0].hostname); + clusterMsgPingExtHostname *hostname_ext = (clusterMsgPingExtHostname *)&(ext->ext[0].hostname); ext_hostname = hostname_ext->hostname; } else if (type == CLUSTERMSG_EXT_TYPE_HUMAN_NODENAME) { - clusterMsgPingExtHumanNodename *humannodename_ext = (clusterMsgPingExtHumanNodename *) &(ext->ext[0].human_nodename); + clusterMsgPingExtHumanNodename *humannodename_ext = + (clusterMsgPingExtHumanNodename *)&(ext->ext[0].human_nodename); ext_humannodename = humannodename_ext->human_nodename; } else if (type == CLUSTERMSG_EXT_TYPE_FORGOTTEN_NODE) { clusterMsgPingExtForgottenNode *forgotten_node_ext = &(ext->ext[0].forgotten_node); @@ -2816,11 +2817,10 @@ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { uint64_t expire = server.unixtime + ntohu64(forgotten_node_ext->ttl); dictSetUnsignedIntegerVal(de, expire); clusterDelNode(n); - clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE| - CLUSTER_TODO_SAVE_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); } } else if (type == CLUSTERMSG_EXT_TYPE_SHARDID) { - clusterMsgPingExtShardId *shardid_ext = (clusterMsgPingExtShardId *) &(ext->ext[0].shard_id); + clusterMsgPingExtShardId *shardid_ext = (clusterMsgPingExtShardId *)&(ext->ext[0].shard_id); ext_shardid = shardid_ext->shard_id; } else { /* Unknown type, we will ignore it but log what happened. */ @@ -2845,7 +2845,9 @@ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { * * If sender is a replica, set the shard_id to the shard_id of its master. * Otherwise, we'll set it now. */ - if (ext_shardid == NULL) ext_shardid = clusterNodeGetMaster(sender)->shard_id; + if (ext_shardid == NULL) { + ext_shardid = clusterNodeGetMaster(sender)->shard_id; + } updateShardId(sender, ext_shardid); } @@ -2871,20 +2873,24 @@ static clusterNode *getNodeFromLinkAndMsg(clusterLink *link, clusterMsg *hdr) { } int clusterIsValidPacket(clusterLink *link) { - clusterMsg *hdr = (clusterMsg*) link->rcvbuf; + clusterMsg *hdr = (clusterMsg *)link->rcvbuf; uint32_t totlen = ntohl(hdr->totlen); uint16_t type = ntohs(hdr->type); - if (type < CLUSTERMSG_TYPE_COUNT) server.cluster->stats_bus_messages_received[type]++; + if (type < CLUSTERMSG_TYPE_COUNT) { + server.cluster->stats_bus_messages_received[type]++; + } - serverLog(LL_DEBUG, - "--- Processing packet of type %s, %lu bytes", - clusterGetMessageTypeString(type), - (unsigned long) totlen); + serverLog(LL_DEBUG, "--- Processing packet of type %s, %lu bytes", clusterGetMessageTypeString(type), + (unsigned long)totlen); /* Perform sanity checks */ - if (totlen < 16) return 0; /* At least signature, version, totlen, count. */ - if (totlen > link->rcvbuf_len) return 0; + if (totlen < 16) { + return 0; /* At least signature, version, totlen, count. */ + } + if (totlen > link->rcvbuf_len) { + return 0; + } if (ntohs(hdr->ver) != CLUSTER_PROTO_VER) { /* Can't handle messages of different versions. */ @@ -2898,14 +2904,12 @@ int clusterIsValidPacket(clusterLink *link) { uint32_t explen; /* expected length of this packet */ - if (type == CLUSTERMSG_TYPE_PING || type == CLUSTERMSG_TYPE_PONG || - type == CLUSTERMSG_TYPE_MEET) - { + if (type == CLUSTERMSG_TYPE_PING || type == CLUSTERMSG_TYPE_PONG || type == CLUSTERMSG_TYPE_MEET) { uint16_t extensions = ntohs(hdr->extensions); uint16_t count = ntohs(hdr->count); - explen = sizeof(clusterMsg)-sizeof(union clusterMsgData); - explen += (sizeof(clusterMsgDataGossip)*count); + explen = sizeof(clusterMsg) - sizeof(union clusterMsgData); + explen += (sizeof(clusterMsgDataGossip) * count); /* If there is extension data, which doesn't have a fixed length, * loop through them and validate the length of it now. */ @@ -2915,13 +2919,14 @@ int clusterIsValidPacket(clusterLink *link) { uint16_t extlen = getPingExtLength(ext); if (extlen % 8 != 0) { serverLog(LL_WARNING, "Received a %s packet without proper padding (%d bytes)", - clusterGetMessageTypeString(type), (int) extlen); + clusterGetMessageTypeString(type), (int)extlen); return 0; } if ((totlen - explen) < extlen) { - serverLog(LL_WARNING, "Received invalid %s packet with extension data that exceeds " - "total packet length (%lld)", clusterGetMessageTypeString(type), - (unsigned long long) totlen); + serverLog(LL_WARNING, + "Received invalid %s packet with extension data that exceeds " + "total packet length (%lld)", + clusterGetMessageTypeString(type), (unsigned long long)totlen); return 0; } explen += extlen; @@ -2929,26 +2934,21 @@ int clusterIsValidPacket(clusterLink *link) { } } } else if (type == CLUSTERMSG_TYPE_FAIL) { - explen = sizeof(clusterMsg)-sizeof(union clusterMsgData); + explen = sizeof(clusterMsg) - sizeof(union clusterMsgData); explen += sizeof(clusterMsgDataFail); } else if (type == CLUSTERMSG_TYPE_PUBLISH || type == CLUSTERMSG_TYPE_PUBLISHSHARD) { - explen = sizeof(clusterMsg)-sizeof(union clusterMsgData); - explen += sizeof(clusterMsgDataPublish) - - 8 + - ntohl(hdr->data.publish.msg.channel_len) + - ntohl(hdr->data.publish.msg.message_len); - } else if (type == CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST || - type == CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK || - type == CLUSTERMSG_TYPE_MFSTART) - { - explen = sizeof(clusterMsg)-sizeof(union clusterMsgData); + explen = sizeof(clusterMsg) - sizeof(union clusterMsgData); + explen += sizeof(clusterMsgDataPublish) - 8 + ntohl(hdr->data.publish.msg.channel_len) + + ntohl(hdr->data.publish.msg.message_len); + } else if (type == CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST || type == CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK || + type == CLUSTERMSG_TYPE_MFSTART) { + explen = sizeof(clusterMsg) - sizeof(union clusterMsgData); } else if (type == CLUSTERMSG_TYPE_UPDATE) { - explen = sizeof(clusterMsg)-sizeof(union clusterMsgData); + explen = sizeof(clusterMsg) - sizeof(union clusterMsgData); explen += sizeof(clusterMsgDataUpdate); } else if (type == CLUSTERMSG_TYPE_MODULE) { - explen = sizeof(clusterMsg)-sizeof(union clusterMsgData); - explen += sizeof(clusterMsgModule) - - 3 + ntohl(hdr->data.module.msg.len); + explen = sizeof(clusterMsg) - sizeof(union clusterMsgData); + explen += sizeof(clusterMsgModule) - 3 + ntohl(hdr->data.module.msg.len); } else { /* We don't know this type of packet, so we assume it's well formed. */ explen = totlen; @@ -2956,7 +2956,7 @@ int clusterIsValidPacket(clusterLink *link) { if (totlen != explen) { serverLog(LL_WARNING, "Received invalid %s packet of length %lld but expected length %lld", - clusterGetMessageTypeString(type), (unsigned long long) totlen, (unsigned long long) explen); + clusterGetMessageTypeString(type), (unsigned long long)totlen, (unsigned long long)explen); return 0; } @@ -2973,11 +2973,12 @@ int clusterIsValidPacket(clusterLink *link) { * processing lead to some inconsistency error (for instance a PONG * received from the wrong sender ID). */ int clusterProcessPacket(clusterLink *link) { - /* Validate that the packet is well-formed */ - if (!clusterIsValidPacket(link)) return 1; + if (!clusterIsValidPacket(link)) { + return 1; + } - clusterMsg *hdr = (clusterMsg*) link->rcvbuf; + clusterMsg *hdr = (clusterMsg *)link->rcvbuf; uint16_t type = ntohs(hdr->type); mstime_t now = mstime(); @@ -2993,38 +2994,36 @@ int clusterProcessPacket(clusterLink *link) { * use this in order to avoid detecting a timeout from a node that * is just sending a lot of data in the cluster bus, for instance * because of Pub/Sub. */ - if (sender) sender->data_received = now; + if (sender) { + sender->data_received = now; + } if (sender && !nodeInHandshake(sender)) { /* Update our currentEpoch if we see a newer epoch in the cluster. */ senderCurrentEpoch = ntohu64(hdr->currentEpoch); senderConfigEpoch = ntohu64(hdr->configEpoch); - if (senderCurrentEpoch > server.cluster->currentEpoch) + if (senderCurrentEpoch > server.cluster->currentEpoch) { server.cluster->currentEpoch = senderCurrentEpoch; + } /* Update the sender configEpoch if it is a primary publishing a newer one. */ if (!memcmp(hdr->slaveof, CLUSTER_NODE_NULL_NAME, sizeof(hdr->slaveof)) && senderConfigEpoch > sender->configEpoch) { sender->configEpoch = senderConfigEpoch; - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_FSYNC_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_FSYNC_CONFIG); } /* Update the replication offset info for this node. */ sender->repl_offset = ntohu64(hdr->offset); sender->repl_offset_time = now; /* If we are a slave performing a manual failover and our master * sent its offset while already paused, populate the MF state. */ - if (server.cluster->mf_end && - nodeIsSlave(myself) && - myself->slaveof == sender && - hdr->mflags[0] & CLUSTERMSG_FLAG0_PAUSED && - server.cluster->mf_master_offset == -1) - { + if (server.cluster->mf_end && nodeIsSlave(myself) && myself->slaveof == sender && + hdr->mflags[0] & CLUSTERMSG_FLAG0_PAUSED && server.cluster->mf_master_offset == -1) { server.cluster->mf_master_offset = sender->repl_offset; clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_MANUALFAILOVER); serverLog(LL_NOTICE, - "Received replication offset for paused " - "master manual failover: %lld", - server.cluster->mf_master_offset); + "Received replication offset for paused " + "master manual failover: %lld", + server.cluster->mf_master_offset); } } @@ -3041,17 +3040,12 @@ int clusterProcessPacket(clusterLink *link) { * However if we don't have an address at all, we update the address * even with a normal PING packet. If it's wrong it will be fixed * by MEET later. */ - if ((type == CLUSTERMSG_TYPE_MEET || myself->ip[0] == '\0') && - server.cluster_announce_ip == NULL) - { + if ((type == CLUSTERMSG_TYPE_MEET || myself->ip[0] == '\0') && server.cluster_announce_ip == NULL) { char ip[NET_IP_STR_LEN]; - if (connAddrSockName(link->conn,ip,sizeof(ip),NULL) != -1 && - strcmp(ip,myself->ip)) - { - memcpy(myself->ip,ip,NET_IP_STR_LEN); - serverLog(LL_NOTICE,"IP address for this node updated to %s", - myself->ip); + if (connAddrSockName(link->conn, ip, sizeof(ip), NULL) != -1 && strcmp(ip, myself->ip)) { + memcpy(myself->ip, ip, NET_IP_STR_LEN); + serverLog(LL_NOTICE, "IP address for this node updated to %s", myself->ip); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } } @@ -3063,8 +3057,8 @@ int clusterProcessPacket(clusterLink *link) { if (!sender && type == CLUSTERMSG_TYPE_MEET) { clusterNode *node; - node = createClusterNode(NULL,CLUSTER_NODE_HANDSHAKE); - serverAssert(nodeIp2String(node->ip,link,hdr->myip) == C_OK); + node = createClusterNode(NULL, CLUSTER_NODE_HANDSHAKE); + serverAssert(nodeIp2String(node->ip, link, hdr->myip) == C_OK); getClientPortFromClusterMsg(hdr, &node->tls_port, &node->tcp_port); node->cport = ntohs(hdr->cport); clusterAddNode(node); @@ -3074,32 +3068,29 @@ int clusterProcessPacket(clusterLink *link) { /* If this is a MEET packet from an unknown node, we still process * the gossip section here since we have to trust the sender because * of the message type. */ - if (!sender && type == CLUSTERMSG_TYPE_MEET) - clusterProcessGossipSection(hdr,link); + if (!sender && type == CLUSTERMSG_TYPE_MEET) { + clusterProcessGossipSection(hdr, link); + } /* Anyway reply with a PONG */ - clusterSendPing(link,CLUSTERMSG_TYPE_PONG); + clusterSendPing(link, CLUSTERMSG_TYPE_PONG); } /* PING, PONG, MEET: process config information. */ - if (type == CLUSTERMSG_TYPE_PING || type == CLUSTERMSG_TYPE_PONG || - type == CLUSTERMSG_TYPE_MEET) - { - serverLog(LL_DEBUG,"%s packet received: %.40s", - clusterGetMessageTypeString(type), - link->node ? link->node->name : "NULL"); + if (type == CLUSTERMSG_TYPE_PING || type == CLUSTERMSG_TYPE_PONG || type == CLUSTERMSG_TYPE_MEET) { + serverLog(LL_DEBUG, "%s packet received: %.40s", clusterGetMessageTypeString(type), + link->node ? link->node->name : "NULL"); if (!link->inbound) { if (nodeInHandshake(link->node)) { /* If we already have this node, try to change the * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s (%s), " - "updating the address if needed.", sender->name, sender->human_nodename); - if (nodeUpdateAddressIfNeeded(sender,link,hdr)) - { - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE); + "Handshake: we already know node %.40s (%s), " + "updating the address if needed.", + sender->name, sender->human_nodename); + if (nodeUpdateAddressIfNeeded(sender, link, hdr)) { + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE); } /* Free this node as we already have it. This will * cause the link to be freed as well. */ @@ -3110,24 +3101,19 @@ int clusterProcessPacket(clusterLink *link) { /* First thing to do is replacing the random name with the * right node name if this was a handshake stage. */ clusterRenameNode(link->node, hdr->sender); - serverLog(LL_DEBUG,"Handshake with node %.40s completed.", - link->node->name); + serverLog(LL_DEBUG, "Handshake with node %.40s completed.", link->node->name); link->node->flags &= ~CLUSTER_NODE_HANDSHAKE; - link->node->flags |= flags&(CLUSTER_NODE_MASTER|CLUSTER_NODE_SLAVE); + link->node->flags |= flags & (CLUSTER_NODE_MASTER | CLUSTER_NODE_SLAVE); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); - } else if (memcmp(link->node->name,hdr->sender, - CLUSTER_NAMELEN) != 0) - { + } else if (memcmp(link->node->name, hdr->sender, CLUSTER_NAMELEN) != 0) { /* If the reply has a non matching node ID we * disconnect this node and set it as not having an associated * address. */ serverLog(LL_DEBUG, - "PONG contains mismatching sender ID. About node %.40s (%s) in shard %.40s added %d ms ago, having flags %d", - link->node->name, - link->node->human_nodename, - link->node->shard_id, - (int)(now-(link->node->ctime)), - link->node->flags); + "PONG contains mismatching sender ID. About node %.40s (%s) in shard %.40s added %d ms ago, " + "having flags %d", + link->node->name, link->node->human_nodename, link->node->shard_id, + (int)(now - (link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; link->node->ip[0] = '\0'; link->node->tcp_port = 0; @@ -3152,12 +3138,9 @@ int clusterProcessPacket(clusterLink *link) { } /* Update the node address if it changed. */ - if (sender && type == CLUSTERMSG_TYPE_PING && - !nodeInHandshake(sender) && - nodeUpdateAddressIfNeeded(sender,link,hdr)) - { - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE); + if (sender && type == CLUSTERMSG_TYPE_PING && !nodeInHandshake(sender) && + nodeUpdateAddressIfNeeded(sender, link, hdr)) { + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE); } /* Update our info about the node */ @@ -3173,8 +3156,7 @@ int clusterProcessPacket(clusterLink *link) { * conditions detected by clearNodeFailureIfNeeded(). */ if (nodeTimedOut(link->node)) { link->node->flags &= ~CLUSTER_NODE_PFAIL; - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE); } else if (nodeFailed(link->node)) { clearNodeFailureIfNeeded(link->node); } @@ -3182,9 +3164,7 @@ int clusterProcessPacket(clusterLink *link) { /* Check for role switch: slave -> master or master -> slave. */ if (sender) { - serverLog(LL_DEBUG, - "node %.40s (%s) announces that it is a %s in shard %.40s", - sender->name, + serverLog(LL_DEBUG, "node %.40s (%s) announces that it is a %s in shard %.40s", sender->name, sender->human_nodename, !memcmp(hdr->slaveof, CLUSTER_NODE_NULL_NAME, sizeof(hdr->slaveof)) ? "master" : "slave", sender->shard_id); @@ -3201,64 +3181,50 @@ int clusterProcessPacket(clusterLink *link) { /* `sender` was a primary and was in the same shard as `master`, its new primary */ if (sender->configEpoch > senderConfigEpoch) { serverLog(LL_NOTICE, - "Ignore stale message from %.40s (%s) in shard %.40s;" - " gossip config epoch: %llu, current config epoch: %llu", - sender->name, - sender->human_nodename, - sender->shard_id, - (unsigned long long)senderConfigEpoch, - (unsigned long long)sender->configEpoch); + "Ignore stale message from %.40s (%s) in shard %.40s;" + " gossip config epoch: %llu, current config epoch: %llu", + sender->name, sender->human_nodename, sender->shard_id, + (unsigned long long)senderConfigEpoch, (unsigned long long)sender->configEpoch); } else { - /* `master` is still a `slave` in this observer node's view; update its role and configEpoch */ + /* `master` is still a `slave` in this observer node's view; update its role and configEpoch + */ clusterSetNodeAsMaster(master); master->configEpoch = senderConfigEpoch; - serverLog(LL_NOTICE, "A failover occurred in shard %.40s; node %.40s (%s)" - " failed over to node %.40s (%s) with a config epoch of %llu", - sender->shard_id, - sender->name, - sender->human_nodename, - master->name, - master->human_nodename, - (unsigned long long) master->configEpoch); + serverLog(LL_NOTICE, + "A failover occurred in shard %.40s; node %.40s (%s)" + " failed over to node %.40s (%s) with a config epoch of %llu", + sender->shard_id, sender->name, sender->human_nodename, master->name, + master->human_nodename, (unsigned long long)master->configEpoch); } } else { /* `sender` was moved to another shard and has become a replica, remove its slot assignment */ int slots = clusterDelNodeSlots(sender); - serverLog(LL_NOTICE, "Node %.40s (%s) is no longer master of shard %.40s;" - " removed all %d slot(s) it used to own", - sender->name, - sender->human_nodename, - sender->shard_id, - slots); - if (master != NULL) { - serverLog(LL_NOTICE, "Node %.40s (%s) is now part of shard %.40s", - sender->name, - sender->human_nodename, - master->shard_id); + serverLog(LL_NOTICE, + "Node %.40s (%s) is no longer master of shard %.40s;" + " removed all %d slot(s) it used to own", + sender->name, sender->human_nodename, sender->shard_id, slots); + if (master != NULL) { + serverLog(LL_NOTICE, "Node %.40s (%s) is now part of shard %.40s", sender->name, + sender->human_nodename, master->shard_id); } } - sender->flags &= ~(CLUSTER_NODE_MASTER| - CLUSTER_NODE_MIGRATE_TO); + sender->flags &= ~(CLUSTER_NODE_MASTER | CLUSTER_NODE_MIGRATE_TO); sender->flags |= CLUSTER_NODE_SLAVE; /* Update config and state. */ - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE); } /* Master node changed for this slave? */ if (master && sender->slaveof != master) { - if (sender->slaveof) - clusterNodeRemoveSlave(sender->slaveof,sender); - serverLog(LL_NOTICE, - "Node %.40s (%s) is now a replica of node %.40s (%s) in shard %.40s", - sender->name, - sender->human_nodename, - master->name, - master->human_nodename, + if (sender->slaveof) { + clusterNodeRemoveSlave(sender->slaveof, sender); + } + serverLog(LL_NOTICE, "Node %.40s (%s) is now a replica of node %.40s (%s) in shard %.40s", + sender->name, sender->human_nodename, master->name, master->human_nodename, sender->shard_id); - clusterNodeAddSlave(master,sender); + clusterNodeAddSlave(master, sender); sender->slaveof = master; /* Update the shard_id when a replica is connected to its @@ -3281,7 +3247,7 @@ int clusterProcessPacket(clusterLink *link) { * for it. Check this ASAP to avoid other computational expansive * checks later. */ clusterNode *sender_master = NULL; /* Sender or its master if slave. */ - int dirty_slots = 0; /* Sender claimed slots don't match my view? */ + int dirty_slots = 0; /* Sender claimed slots don't match my view? */ if (sender) { sender_master = clusterNodeIsMaster(sender) ? sender : sender->slaveof; @@ -3298,8 +3264,9 @@ int clusterProcessPacket(clusterLink *link) { /* 1) If the sender of the message is a master, and we detected that * the set of slots it claims changed, scan the slots to see if we * need to update our configuration. */ - if (sender_master && dirty_slots) + if (sender_master && dirty_slots) { clusterUpdateSlotsConfigWith(sender_master, senderConfigEpoch, hdr->myslots); + } /* Explicitly check for a replication loop before attempting the replication * chain folding logic. @@ -3335,20 +3302,14 @@ int clusterProcessPacket(clusterLink *link) { * e. Finally, the pre-failover PING message queued up in A*'s outgoing * buffer to A is delivered and processed, out of order though, to A. * f. This stale PING message creates the replication loop */ - if (myself->slaveof && - myself->slaveof->slaveof && - myself->slaveof->slaveof != myself) { + if (myself->slaveof && myself->slaveof->slaveof && myself->slaveof->slaveof != myself) { /* Safeguard against sub-replicas. A replica's master can turn itself * into a replica if its last slot is removed. If no other node takes * over the slot, there is nothing else to trigger replica migration. */ - serverLog(LL_NOTICE, - "I'm a sub-replica! Reconfiguring myself as a replica of %.40s from %.40s", - myself->slaveof->slaveof->name, - myself->slaveof->name); + serverLog(LL_NOTICE, "I'm a sub-replica! Reconfiguring myself as a replica of %.40s from %.40s", + myself->slaveof->slaveof->name, myself->slaveof->name); clusterSetMaster(myself->slaveof->slaveof, 1); - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE| - CLUSTER_TODO_FSYNC_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_FSYNC_CONFIG); } /* 2) We also check for the reverse condition, that is, the sender @@ -3373,18 +3334,16 @@ int clusterProcessPacket(clusterLink *link) { int j; for (j = 0; j < CLUSTER_SLOTS; j++) { - if (bitmapTestBit(hdr->myslots,j)) { - if (server.cluster->slots[j] == sender || - isSlotUnclaimed(j)) continue; - if (server.cluster->slots[j]->configEpoch > - senderConfigEpoch) - { + if (bitmapTestBit(hdr->myslots, j)) { + if (server.cluster->slots[j] == sender || isSlotUnclaimed(j)) { + continue; + } + if (server.cluster->slots[j]->configEpoch > senderConfigEpoch) { serverLog(LL_VERBOSE, - "Node %.40s has old slots configuration, sending " - "an UPDATE message about %.40s", - sender->name, server.cluster->slots[j]->name); - clusterSendUpdate(sender->link, - server.cluster->slots[j]); + "Node %.40s has old slots configuration, sending " + "an UPDATE message about %.40s", + sender->name, server.cluster->slots[j]->name); + clusterSendUpdate(sender->link, server.cluster->slots[j]); /* TODO: instead of exiting the loop send every other * UPDATE packet for other nodes that are the new owner @@ -3398,73 +3357,66 @@ int clusterProcessPacket(clusterLink *link) { /* If our config epoch collides with the sender's try to fix * the problem. */ if (sender && clusterNodeIsMaster(myself) && clusterNodeIsMaster(sender) && - senderConfigEpoch == myself->configEpoch) - { + senderConfigEpoch == myself->configEpoch) { clusterHandleConfigEpochCollision(sender); } /* Get info from the gossip section */ if (sender) { - clusterProcessGossipSection(hdr,link); - clusterProcessPingExtensions(hdr,link); + clusterProcessGossipSection(hdr, link); + clusterProcessPingExtensions(hdr, link); } } else if (type == CLUSTERMSG_TYPE_FAIL) { clusterNode *failing; if (sender) { failing = clusterLookupNode(hdr->data.fail.about.nodename, CLUSTER_NAMELEN); - if (failing && - !(failing->flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_MYSELF))) - { - serverLog(LL_NOTICE, - "FAIL message received from %.40s (%s) about %.40s (%s)", - hdr->sender, sender->human_nodename, hdr->data.fail.about.nodename, failing->human_nodename); + if (failing && !(failing->flags & (CLUSTER_NODE_FAIL | CLUSTER_NODE_MYSELF))) { + serverLog(LL_NOTICE, "FAIL message received from %.40s (%s) about %.40s (%s)", hdr->sender, + sender->human_nodename, hdr->data.fail.about.nodename, failing->human_nodename); failing->flags |= CLUSTER_NODE_FAIL; failing->fail_time = now; failing->flags &= ~CLUSTER_NODE_PFAIL; - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE); } } else { - serverLog(LL_NOTICE, - "Ignoring FAIL message from unknown node %.40s about %.40s", - hdr->sender, hdr->data.fail.about.nodename); + serverLog(LL_NOTICE, "Ignoring FAIL message from unknown node %.40s about %.40s", hdr->sender, + hdr->data.fail.about.nodename); } } else if (type == CLUSTERMSG_TYPE_PUBLISH || type == CLUSTERMSG_TYPE_PUBLISHSHARD) { - if (!sender) return 1; /* We don't know that node. */ + if (!sender) { + return 1; /* We don't know that node. */ + } robj *channel, *message; uint32_t channel_len, message_len; /* Don't bother creating useless objects if there are no * Pub/Sub subscribers. */ - if ((type == CLUSTERMSG_TYPE_PUBLISH - && serverPubsubSubscriptionCount() > 0) - || (type == CLUSTERMSG_TYPE_PUBLISHSHARD - && serverPubsubShardSubscriptionCount() > 0)) - { + if ((type == CLUSTERMSG_TYPE_PUBLISH && serverPubsubSubscriptionCount() > 0) || + (type == CLUSTERMSG_TYPE_PUBLISHSHARD && serverPubsubShardSubscriptionCount() > 0)) { channel_len = ntohl(hdr->data.publish.msg.channel_len); message_len = ntohl(hdr->data.publish.msg.message_len); - channel = createStringObject( - (char*)hdr->data.publish.msg.bulk_data,channel_len); - message = createStringObject( - (char*)hdr->data.publish.msg.bulk_data+channel_len, - message_len); + channel = createStringObject((char *)hdr->data.publish.msg.bulk_data, channel_len); + message = createStringObject((char *)hdr->data.publish.msg.bulk_data + channel_len, message_len); pubsubPublishMessage(channel, message, type == CLUSTERMSG_TYPE_PUBLISHSHARD); decrRefCount(channel); decrRefCount(message); } } else if (type == CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST) { - if (!sender) return 1; /* We don't know that node. */ - clusterSendFailoverAuthIfNeeded(sender,hdr); + if (!sender) { + return 1; /* We don't know that node. */ + } + clusterSendFailoverAuthIfNeeded(sender, hdr); } else if (type == CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK) { - if (!sender) return 1; /* We don't know that node. */ + if (!sender) { + return 1; /* We don't know that node. */ + } /* We consider this vote only if the sender is a master serving * a non zero number of slots, and its currentEpoch is greater or * equal to epoch where this node started the election. */ if (clusterNodeIsMaster(sender) && sender->numslots > 0 && - senderCurrentEpoch >= server.cluster->failover_auth_epoch) - { + senderCurrentEpoch >= server.cluster->failover_auth_epoch) { server.cluster->failover_auth_count++; /* Maybe we reached a quorum here, set a flag to make sure * we check ASAP. */ @@ -3473,17 +3425,17 @@ int clusterProcessPacket(clusterLink *link) { } else if (type == CLUSTERMSG_TYPE_MFSTART) { /* This message is acceptable only if I'm a master and the sender * is one of my slaves. */ - if (!sender || sender->slaveof != myself) return 1; + if (!sender || sender->slaveof != myself) { + return 1; + } /* Manual failover requested from slaves. Initialize the state * accordingly. */ resetManualFailover(); server.cluster->mf_end = now + CLUSTER_MF_TIMEOUT; server.cluster->mf_slave = sender; - pauseActions(PAUSE_DURING_FAILOVER, - now + (CLUSTER_MF_TIMEOUT * CLUSTER_MF_PAUSE_MULT), + pauseActions(PAUSE_DURING_FAILOVER, now + (CLUSTER_MF_TIMEOUT * CLUSTER_MF_PAUSE_MULT), PAUSE_ACTIONS_CLIENT_WRITE_SET); - serverLog(LL_NOTICE,"Manual failover requested by replica %.40s (%s).", - sender->name, sender->human_nodename); + serverLog(LL_NOTICE, "Manual failover requested by replica %.40s (%s).", sender->name, sender->human_nodename); /* We need to send a ping message to the replica, as it would carry * `server.cluster->mf_master_offset`, which means the master paused clients * at offset `server.cluster->mf_master_offset`, so that the replica would @@ -3492,37 +3444,44 @@ int clusterProcessPacket(clusterLink *link) { clusterSendPing(link, CLUSTERMSG_TYPE_PING); } else if (type == CLUSTERMSG_TYPE_UPDATE) { clusterNode *n; /* The node the update is about. */ - uint64_t reportedConfigEpoch = - ntohu64(hdr->data.update.nodecfg.configEpoch); + uint64_t reportedConfigEpoch = ntohu64(hdr->data.update.nodecfg.configEpoch); - if (!sender) return 1; /* We don't know the sender. */ + if (!sender) { + return 1; /* We don't know the sender. */ + } n = clusterLookupNode(hdr->data.update.nodecfg.nodename, CLUSTER_NAMELEN); - if (!n) return 1; /* We don't know the reported node. */ - if (n->configEpoch >= reportedConfigEpoch) return 1; /* Nothing new. */ + if (!n) { + return 1; /* We don't know the reported node. */ + } + if (n->configEpoch >= reportedConfigEpoch) { + return 1; /* Nothing new. */ + } /* If in our current config the node is a slave, set it as a master. */ - if (nodeIsSlave(n)) clusterSetNodeAsMaster(n); + if (nodeIsSlave(n)) { + clusterSetNodeAsMaster(n); + } /* Update the node's configEpoch. */ n->configEpoch = reportedConfigEpoch; - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_FSYNC_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_FSYNC_CONFIG); /* Check the bitmap of served slots and update our * config accordingly. */ - clusterUpdateSlotsConfigWith(n,reportedConfigEpoch, - hdr->data.update.nodecfg.slots); + clusterUpdateSlotsConfigWith(n, reportedConfigEpoch, hdr->data.update.nodecfg.slots); } else if (type == CLUSTERMSG_TYPE_MODULE) { - if (!sender) return 1; /* Protect the module from unknown nodes. */ + if (!sender) { + return 1; /* Protect the module from unknown nodes. */ + } /* We need to route this message back to the right module subscribed * for the right message type. */ uint64_t module_id = hdr->data.module.msg.module_id; /* Endian-safe ID */ uint32_t len = ntohl(hdr->data.module.msg.len); uint8_t type = hdr->data.module.msg.type; unsigned char *payload = hdr->data.module.msg.bulk_data; - moduleCallClusterReceivers(sender->name,module_id,type,payload,len); + moduleCallClusterReceivers(sender->name, module_id, type, payload, len); } else { - serverLog(LL_WARNING,"Received unknown packet type: %d", type); + serverLog(LL_WARNING, "Received unknown packet type: %d", type); } return 1; } @@ -3545,15 +3504,15 @@ void clusterWriteHandler(connection *conn) { while (totwritten < NET_MAX_WRITES_PER_EVENT && listLength(link->send_msg_queue) > 0) { listNode *head = listFirst(link->send_msg_queue); - clusterMsgSendBlock *msgblock = (clusterMsgSendBlock*)head->value; + clusterMsgSendBlock *msgblock = (clusterMsgSendBlock *)head->value; clusterMsg *msg = &msgblock->msg; size_t msg_offset = link->head_msg_send_offset; size_t msg_len = ntohl(msg->totlen); - nwritten = connWrite(conn, (char*)msg + msg_offset, msg_len - msg_offset); + nwritten = connWrite(conn, (char *)msg + msg_offset, msg_len - msg_offset); if (nwritten <= 0) { - serverLog(LL_DEBUG,"I/O error writing to node link: %s", - (nwritten == -1) ? connGetLastError(conn) : "short write"); + serverLog(LL_DEBUG, "I/O error writing to node link: %s", + (nwritten == -1) ? connGetLastError(conn) : "short write"); handleLinkIOError(link); return; } @@ -3575,8 +3534,9 @@ void clusterWriteHandler(connection *conn) { totwritten += nwritten; } - if (listLength(link->send_msg_queue) == 0) + if (listLength(link->send_msg_queue) == 0) { connSetWriteHandler(link->conn, NULL); + } } /* A connect handler that gets called when a connection to another node @@ -3588,9 +3548,8 @@ void clusterLinkConnectHandler(connection *conn) { /* Check if connection succeeded */ if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, "Connection with Node %.40s at %s:%d failed: %s", - node->name, node->ip, node->cport, - connGetLastError(conn)); + serverLog(LL_VERBOSE, "Connection with Node %.40s at %s:%d failed: %s", node->name, node->ip, node->cport, + connGetLastError(conn)); freeClusterLink(link); return; } @@ -3605,8 +3564,7 @@ void clusterLinkConnectHandler(connection *conn) { * of a PING one, to force the receiver to add us in its node * table. */ mstime_t old_ping_sent = node->ping_sent; - clusterSendPing(link, node->flags & CLUSTER_NODE_MEET ? - CLUSTERMSG_TYPE_MEET : CLUSTERMSG_TYPE_PING); + clusterSendPing(link, node->flags & CLUSTER_NODE_MEET ? CLUSTERMSG_TYPE_MEET : CLUSTERMSG_TYPE_PING); if (old_ping_sent) { /* If there was an active ping before the link was * disconnected, we want to restore the ping time, otherwise @@ -3620,8 +3578,7 @@ void clusterLinkConnectHandler(connection *conn) { * normal PING packets. */ node->flags &= ~CLUSTER_NODE_MEET; - serverLog(LL_DEBUG,"Connecting with Node %.40s at %s:%d", - node->name, node->ip, node->cport); + serverLog(LL_DEBUG, "Connecting with Node %.40s at %s:%d", node->name, node->ip, node->cport); } /* Read data. Try to read the first field of the header first to check the @@ -3634,7 +3591,7 @@ void clusterReadHandler(connection *conn) { clusterLink *link = connGetPrivateData(conn); unsigned int readlen, rcvbuflen; - while(1) { /* Read as long as there is data to read. */ + while (1) { /* Read as long as there is data to read. */ rcvbuflen = link->rcvbuf_len; if (rcvbuflen < 8) { /* First, obtain the first 8 bytes to get the full message @@ -3642,39 +3599,41 @@ void clusterReadHandler(connection *conn) { readlen = 8 - rcvbuflen; } else { /* Finally read the full message. */ - hdr = (clusterMsg*) link->rcvbuf; + hdr = (clusterMsg *)link->rcvbuf; if (rcvbuflen == 8) { /* Perform some sanity check on the message signature * and length. */ - if (memcmp(hdr->sig,"RCmb",4) != 0 || - ntohl(hdr->totlen) < CLUSTERMSG_MIN_LEN) - { + if (memcmp(hdr->sig, "RCmb", 4) != 0 || ntohl(hdr->totlen) < CLUSTERMSG_MIN_LEN) { char ip[NET_IP_STR_LEN]; int port; if (connAddrPeerName(conn, ip, sizeof(ip), &port) == -1) { - serverLog(LL_WARNING, - "Bad message length or signature received " - "on the Cluster bus."); + serverLog(LL_WARNING, "Bad message length or signature received " + "on the Cluster bus."); } else { serverLog(LL_WARNING, - "Bad message length or signature received " - "on the Cluster bus from %s:%d", ip, port); + "Bad message length or signature received " + "on the Cluster bus from %s:%d", + ip, port); } handleLinkIOError(link); return; } } readlen = ntohl(hdr->totlen) - rcvbuflen; - if (readlen > sizeof(buf)) readlen = sizeof(buf); + if (readlen > sizeof(buf)) { + readlen = sizeof(buf); + } } - nread = connRead(conn,buf,readlen); - if (nread == -1 && (connGetState(conn) == CONN_STATE_CONNECTED)) return; /* No more data ready. */ + nread = connRead(conn, buf, readlen); + if (nread == -1 && (connGetState(conn) == CONN_STATE_CONNECTED)) { + return; /* No more data ready. */ + } if (nread <= 0) { /* I/O error... */ - serverLog(LL_DEBUG,"I/O error reading from node link: %s", - (nread == 0) ? "connection closed" : connGetLastError(conn)); + serverLog(LL_DEBUG, "I/O error reading from node link: %s", + (nread == 0) ? "connection closed" : connGetLastError(conn)); handleLinkIOError(link); return; } else { @@ -3684,13 +3643,13 @@ void clusterReadHandler(connection *conn) { size_t required = link->rcvbuf_len + nread; size_t prev_rcvbuf_alloc = link->rcvbuf_alloc; /* If less than 1mb, grow to twice the needed size, if larger grow by 1mb. */ - link->rcvbuf_alloc = required < RCVBUF_MAX_PREALLOC ? required * 2: required + RCVBUF_MAX_PREALLOC; + link->rcvbuf_alloc = required < RCVBUF_MAX_PREALLOC ? required * 2 : required + RCVBUF_MAX_PREALLOC; link->rcvbuf = zrealloc(link->rcvbuf, link->rcvbuf_alloc); server.stat_cluster_links_memory += link->rcvbuf_alloc - prev_rcvbuf_alloc; } memcpy(link->rcvbuf + link->rcvbuf_len, buf, nread); link->rcvbuf_len += nread; - hdr = (clusterMsg*) link->rcvbuf; + hdr = (clusterMsg *)link->rcvbuf; rcvbuflen += nread; } @@ -3720,8 +3679,9 @@ void clusterSendMessage(clusterLink *link, clusterMsgSendBlock *msgblock) { if (!link) { return; } - if (listLength(link->send_msg_queue) == 0 && msgblock->msg.totlen != 0) + if (listLength(link->send_msg_queue) == 0 && msgblock->msg.totlen != 0) { connSetWriteHandlerWithBarrier(link->conn, clusterWriteHandler, 1); + } listAddNodeTail(link->send_msg_queue, msgblock); msgblock->refcount++; @@ -3732,8 +3692,9 @@ void clusterSendMessage(clusterLink *link, clusterMsgSendBlock *msgblock) { /* Populate sent messages stats. */ uint16_t type = ntohs(msgblock->msg.type); - if (type < CLUSTERMSG_TYPE_COUNT) + if (type < CLUSTERMSG_TYPE_COUNT) { server.cluster->stats_bus_messages_sent[type]++; + } } /* Send a message to all the nodes that are part of the cluster having @@ -3747,12 +3708,13 @@ void clusterBroadcastMessage(clusterMsgSendBlock *msgblock) { dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); - if (node->flags & (CLUSTER_NODE_MYSELF|CLUSTER_NODE_HANDSHAKE)) + if (node->flags & (CLUSTER_NODE_MYSELF | CLUSTER_NODE_HANDSHAKE)) { continue; - clusterSendMessage(node->link,msgblock); + } + clusterSendMessage(node->link, msgblock); } dictReleaseIterator(di); } @@ -3767,8 +3729,7 @@ static void clusterBuildMessageHdr(clusterMsg *hdr, int type, size_t msglen) { * If this node is a slave we send the master's information instead (the * node is flagged as slave so the receiver knows that it is NOT really * in charge for this slots. */ - master = (nodeIsSlave(myself) && myself->slaveof) ? - myself->slaveof : myself; + master = (nodeIsSlave(myself) && myself->slaveof) ? myself->slaveof : myself; hdr->ver = htons(CLUSTER_PROTO_VER); hdr->sig[0] = 'R'; @@ -3776,24 +3737,25 @@ static void clusterBuildMessageHdr(clusterMsg *hdr, int type, size_t msglen) { hdr->sig[2] = 'm'; hdr->sig[3] = 'b'; hdr->type = htons(type); - memcpy(hdr->sender,myself->name,CLUSTER_NAMELEN); + memcpy(hdr->sender, myself->name, CLUSTER_NAMELEN); /* If cluster-announce-ip option is enabled, force the receivers of our * packets to use the specified address for this node. Otherwise if the * first byte is zero, they'll do auto discovery. */ - memset(hdr->myip,0,NET_IP_STR_LEN); + memset(hdr->myip, 0, NET_IP_STR_LEN); if (server.cluster_announce_ip) { - valkey_strlcpy(hdr->myip,server.cluster_announce_ip,NET_IP_STR_LEN); + valkey_strlcpy(hdr->myip, server.cluster_announce_ip, NET_IP_STR_LEN); } /* Handle cluster-announce-[tls-|bus-]port. */ int announced_tcp_port, announced_tls_port, announced_cport; deriveAnnouncedPorts(&announced_tcp_port, &announced_tls_port, &announced_cport); - memcpy(hdr->myslots,master->slots,sizeof(hdr->myslots)); - memset(hdr->slaveof,0,CLUSTER_NAMELEN); - if (myself->slaveof != NULL) - memcpy(hdr->slaveof,myself->slaveof->name, CLUSTER_NAMELEN); + memcpy(hdr->myslots, master->slots, sizeof(hdr->myslots)); + memset(hdr->slaveof, 0, CLUSTER_NAMELEN); + if (myself->slaveof != NULL) { + memcpy(hdr->slaveof, myself->slaveof->name, CLUSTER_NAMELEN); + } if (server.tls_cluster) { hdr->port = htons(announced_tls_port); hdr->pport = htons(announced_tcp_port); @@ -3810,15 +3772,17 @@ static void clusterBuildMessageHdr(clusterMsg *hdr, int type, size_t msglen) { hdr->configEpoch = htonu64(master->configEpoch); /* Set the replication offset. */ - if (nodeIsSlave(myself)) + if (nodeIsSlave(myself)) { offset = replicationGetSlaveOffset(); - else + } else { offset = server.master_repl_offset; + } hdr->offset = htonu64(offset); /* Set the message flags. */ - if (clusterNodeIsMaster(myself) && server.cluster->mf_end) + if (clusterNodeIsMaster(myself) && server.cluster->mf_end) { hdr->mflags[0] |= CLUSTERMSG_FLAG0_PAUSED; + } hdr->totlen = htonl(msglen); } @@ -3828,10 +3792,10 @@ static void clusterBuildMessageHdr(clusterMsg *hdr, int type, size_t msglen) { void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) { clusterMsgDataGossip *gossip; gossip = &(hdr->data.ping.gossip[i]); - memcpy(gossip->nodename,n->name,CLUSTER_NAMELEN); - gossip->ping_sent = htonl(n->ping_sent/1000); - gossip->pong_received = htonl(n->pong_received/1000); - memcpy(gossip->ip,n->ip,sizeof(n->ip)); + memcpy(gossip->nodename, n->name, CLUSTER_NAMELEN); + gossip->ping_sent = htonl(n->ping_sent / 1000); + gossip->pong_received = htonl(n->pong_received / 1000); + memcpy(gossip->ip, n->ip, sizeof(n->ip)); if (server.tls_cluster) { gossip->port = htons(n->tls_port); gossip->pport = htons(n->tcp_port); @@ -3850,13 +3814,13 @@ void clusterSendPing(clusterLink *link, int type) { static unsigned long long cluster_pings_sent = 0; cluster_pings_sent++; int gossipcount = 0; /* Number of gossip sections added so far. */ - int wanted; /* Number of gossip sections we want to append if possible. */ - int estlen; /* Upper bound on estimated packet length */ + int wanted; /* Number of gossip sections we want to append if possible. */ + int estlen; /* Upper bound on estimated packet length */ /* freshnodes is the max number of nodes we can hope to append at all: * nodes available minus two (ourself and the node we are sending the * message to). However practically there may be less valid nodes since * nodes in handshake state, disconnected, are not considered. */ - int freshnodes = dictSize(server.cluster->nodes)-2; + int freshnodes = dictSize(server.cluster->nodes) - 2; /* How many gossip sections we want to add? 1/10 of the number of nodes * and anyway at least 3. Why 1/10? @@ -3884,9 +3848,13 @@ void clusterSendPing(clusterLink *link, int type) { * Since we have non-voting slaves that lower the probability of an entry * to feature our node, we set the number of entries per packet as * 10% of the total nodes we have. */ - wanted = floor(dictSize(server.cluster->nodes)/10); - if (wanted < 3) wanted = 3; - if (wanted > freshnodes) wanted = freshnodes; + wanted = floor(dictSize(server.cluster->nodes) / 10); + if (wanted < 3) { + wanted = 3; + } + if (wanted > freshnodes) { + wanted = freshnodes; + } /* Include all the nodes in PFAIL state, so that failure reports are * faster to propagate to go from PFAIL to FAIL state. */ @@ -3896,22 +3864,25 @@ void clusterSendPing(clusterLink *link, int type) { * later according to the number of gossip sections we really were able * to put inside the packet. */ estlen = sizeof(clusterMsg) - sizeof(union clusterMsgData); - estlen += (sizeof(clusterMsgDataGossip)*(wanted + pfail_wanted)); + estlen += (sizeof(clusterMsgDataGossip) * (wanted + pfail_wanted)); if (link->node && nodeSupportsExtensions(link->node)) { estlen += writePingExt(NULL, 0); } /* Note: clusterBuildMessageHdr() expects the buffer to be always at least * sizeof(clusterMsg) or more. */ - if (estlen < (int)sizeof(clusterMsg)) estlen = sizeof(clusterMsg); + if (estlen < (int)sizeof(clusterMsg)) { + estlen = sizeof(clusterMsg); + } clusterMsgSendBlock *msgblock = createClusterMsgSendBlock(type, estlen); clusterMsg *hdr = &msgblock->msg; - if (!link->inbound && type == CLUSTERMSG_TYPE_PING) + if (!link->inbound && type == CLUSTERMSG_TYPE_PING) { link->node->ping_sent = mstime(); + } /* Populate the gossip fields */ - int maxiterations = wanted*3; - while(freshnodes > 0 && gossipcount < wanted && maxiterations--) { + int maxiterations = wanted * 3; + while (freshnodes > 0 && gossipcount < wanted && maxiterations--) { dictEntry *de = dictGetRandomKey(server.cluster->nodes); clusterNode *this = dictGetVal(de); @@ -3919,28 +3890,33 @@ void clusterSendPing(clusterLink *link, int type) { * already, so we just gossip about other nodes. * Also, don't include the receiver. Receiver will not update its state * based on gossips about itself. */ - if (this == myself || this == link->node) continue; + if (this == myself || this == link->node) { + continue; + } /* PFAIL nodes will be added later. */ - if (this->flags & CLUSTER_NODE_PFAIL) continue; + if (this->flags & CLUSTER_NODE_PFAIL) { + continue; + } /* In the gossip section don't include: * 1) Nodes in HANDSHAKE state. * 3) Nodes with the NOADDR flag set. * 4) Disconnected nodes if they don't have configured slots. */ - if (this->flags & (CLUSTER_NODE_HANDSHAKE|CLUSTER_NODE_NOADDR) || - (this->link == NULL && this->numslots == 0)) - { + if (this->flags & (CLUSTER_NODE_HANDSHAKE | CLUSTER_NODE_NOADDR) || + (this->link == NULL && this->numslots == 0)) { freshnodes--; /* Technically not correct, but saves CPU. */ continue; } /* Do not add a node we already have. */ - if (this->last_in_ping_gossip == cluster_pings_sent) continue; + if (this->last_in_ping_gossip == cluster_pings_sent) { + continue; + } /* Add it */ - clusterSetGossipEntry(hdr,gossipcount,this); + clusterSetGossipEntry(hdr, gossipcount, this); this->last_in_ping_gossip = cluster_pings_sent; freshnodes--; gossipcount++; @@ -3952,12 +3928,18 @@ void clusterSendPing(clusterLink *link, int type) { dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL && pfail_wanted > 0) { + while ((de = dictNext(di)) != NULL && pfail_wanted > 0) { clusterNode *node = dictGetVal(de); - if (node->flags & CLUSTER_NODE_HANDSHAKE) continue; - if (node->flags & CLUSTER_NODE_NOADDR) continue; - if (!(node->flags & CLUSTER_NODE_PFAIL)) continue; - clusterSetGossipEntry(hdr,gossipcount,node); + if (node->flags & CLUSTER_NODE_HANDSHAKE) { + continue; + } + if (node->flags & CLUSTER_NODE_NOADDR) { + continue; + } + if (!(node->flags & CLUSTER_NODE_PFAIL)) { + continue; + } + clusterSetGossipEntry(hdr, gossipcount, node); gossipcount++; /* We take the count of the slots we allocated, since the * PFAIL stats may not match perfectly with the current number @@ -3976,13 +3958,13 @@ void clusterSendPing(clusterLink *link, int type) { serverLog(LL_DEBUG, "Unable to send extensions data, however setting ext data flag to true"); hdr->mflags[0] |= CLUSTERMSG_FLAG0_EXT_DATA; } - totlen += sizeof(clusterMsg)-sizeof(union clusterMsgData); - totlen += (sizeof(clusterMsgDataGossip)*gossipcount); + totlen += sizeof(clusterMsg) - sizeof(union clusterMsgData); + totlen += (sizeof(clusterMsgDataGossip) * gossipcount); serverAssert(gossipcount < USHRT_MAX); hdr->count = htons(gossipcount); hdr->totlen = htonl(totlen); - clusterSendMessage(link,msgblock); + clusterSendMessage(link, msgblock); clusterMsgSendBlockDecrRefCount(msgblock); } @@ -4007,18 +3989,23 @@ void clusterBroadcastPong(int target) { dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); - if (!node->link) continue; - if (node == myself || nodeInHandshake(node)) continue; + if (!node->link) { + continue; + } + if (node == myself || nodeInHandshake(node)) { + continue; + } if (target == CLUSTER_BROADCAST_LOCAL_SLAVES) { int local_slave = - nodeIsSlave(node) && node->slaveof && - (node->slaveof == myself || node->slaveof == myself->slaveof); - if (!local_slave) continue; + nodeIsSlave(node) && node->slaveof && (node->slaveof == myself || node->slaveof == myself->slaveof); + if (!local_slave) { + continue; + } } - clusterSendPing(node->link,CLUSTERMSG_TYPE_PONG); + clusterSendPing(node->link, CLUSTERMSG_TYPE_PONG); } dictReleaseIterator(di); } @@ -4031,7 +4018,6 @@ void clusterBroadcastPong(int target) { * positive in this context. */ VALKEY_NO_SANITIZE("bounds") clusterMsgSendBlock *clusterCreatePublishMsgBlock(robj *channel, robj *message, uint16_t type) { - uint32_t channel_len, message_len; channel = getDecodedObject(channel); @@ -4039,20 +4025,19 @@ clusterMsgSendBlock *clusterCreatePublishMsgBlock(robj *channel, robj *message, channel_len = sdslen(channel->ptr); message_len = sdslen(message->ptr); - size_t msglen = sizeof(clusterMsg)-sizeof(union clusterMsgData); + size_t msglen = sizeof(clusterMsg) - sizeof(union clusterMsgData); msglen += sizeof(clusterMsgDataPublish) - 8 + channel_len + message_len; clusterMsgSendBlock *msgblock = createClusterMsgSendBlock(type, msglen); clusterMsg *hdr = &msgblock->msg; hdr->data.publish.msg.channel_len = htonl(channel_len); hdr->data.publish.msg.message_len = htonl(message_len); - memcpy(hdr->data.publish.msg.bulk_data,channel->ptr,sdslen(channel->ptr)); - memcpy(hdr->data.publish.msg.bulk_data+sdslen(channel->ptr), - message->ptr,sdslen(message->ptr)); + memcpy(hdr->data.publish.msg.bulk_data, channel->ptr, sdslen(channel->ptr)); + memcpy(hdr->data.publish.msg.bulk_data + sdslen(channel->ptr), message->ptr, sdslen(message->ptr)); decrRefCount(channel); decrRefCount(message); - + return msgblock; } @@ -4062,12 +4047,11 @@ clusterMsgSendBlock *clusterCreatePublishMsgBlock(robj *channel, robj *message, * we switch the node state to CLUSTER_NODE_FAIL and ask all the other * nodes to do the same ASAP. */ void clusterSendFail(char *nodename) { - uint32_t msglen = sizeof(clusterMsg) - sizeof(union clusterMsgData) - + sizeof(clusterMsgDataFail); + uint32_t msglen = sizeof(clusterMsg) - sizeof(union clusterMsgData) + sizeof(clusterMsgDataFail); clusterMsgSendBlock *msgblock = createClusterMsgSendBlock(CLUSTERMSG_TYPE_FAIL, msglen); clusterMsg *hdr = &msgblock->msg; - memcpy(hdr->data.fail.about.nodename,nodename,CLUSTER_NAMELEN); + memcpy(hdr->data.fail.about.nodename, nodename, CLUSTER_NAMELEN); clusterBroadcastMessage(msgblock); clusterMsgSendBlockDecrRefCount(msgblock); @@ -4077,31 +4061,32 @@ void clusterSendFail(char *nodename) { * slots configuration. The node name, slots bitmap, and configEpoch info * are included. */ void clusterSendUpdate(clusterLink *link, clusterNode *node) { - if (link == NULL) return; + if (link == NULL) { + return; + } - uint32_t msglen = sizeof(clusterMsg) - sizeof(union clusterMsgData) - + sizeof(clusterMsgDataUpdate); + uint32_t msglen = sizeof(clusterMsg) - sizeof(union clusterMsgData) + sizeof(clusterMsgDataUpdate); clusterMsgSendBlock *msgblock = createClusterMsgSendBlock(CLUSTERMSG_TYPE_UPDATE, msglen); clusterMsg *hdr = &msgblock->msg; - memcpy(hdr->data.update.nodecfg.nodename,node->name,CLUSTER_NAMELEN); + memcpy(hdr->data.update.nodecfg.nodename, node->name, CLUSTER_NAMELEN); hdr->data.update.nodecfg.configEpoch = htonu64(node->configEpoch); - memcpy(hdr->data.update.nodecfg.slots,node->slots,sizeof(node->slots)); + memcpy(hdr->data.update.nodecfg.slots, node->slots, sizeof(node->slots)); for (unsigned int i = 0; i < sizeof(node->slots); i++) { /* Don't advertise slots that the node stopped claiming */ - hdr->data.update.nodecfg.slots[i] = hdr->data.update.nodecfg.slots[i] & (~server.cluster->owner_not_claiming_slot[i]); + hdr->data.update.nodecfg.slots[i] = + hdr->data.update.nodecfg.slots[i] & (~server.cluster->owner_not_claiming_slot[i]); } - clusterSendMessage(link,msgblock); + clusterSendMessage(link, msgblock); clusterMsgSendBlockDecrRefCount(msgblock); } /* Send a MODULE message. * * If link is NULL, then the message is broadcasted to the whole cluster. */ -void clusterSendModule(clusterLink *link, uint64_t module_id, uint8_t type, - const char *payload, uint32_t len) { - uint32_t msglen = sizeof(clusterMsg)-sizeof(union clusterMsgData); +void clusterSendModule(clusterLink *link, uint64_t module_id, uint8_t type, const char *payload, uint32_t len) { + uint32_t msglen = sizeof(clusterMsg) - sizeof(union clusterMsgData); msglen += sizeof(clusterMsgModule) - 3 + len; clusterMsgSendBlock *msgblock = createClusterMsgSendBlock(CLUSTERMSG_TYPE_MODULE, msglen); @@ -4109,12 +4094,13 @@ void clusterSendModule(clusterLink *link, uint64_t module_id, uint8_t type, hdr->data.module.msg.module_id = module_id; /* Already endian adjusted. */ hdr->data.module.msg.type = type; hdr->data.module.msg.len = htonl(len); - memcpy(hdr->data.module.msg.bulk_data,payload,len); + memcpy(hdr->data.module.msg.bulk_data, payload, len); - if (link) - clusterSendMessage(link,msgblock); - else + if (link) { + clusterSendMessage(link, msgblock); + } else { clusterBroadcastMessage(msgblock); + } clusterMsgSendBlockDecrRefCount(msgblock); } @@ -4125,16 +4111,18 @@ void clusterSendModule(clusterLink *link, uint64_t module_id, uint8_t type, * * The function returns C_OK if the target is valid, otherwise C_ERR is * returned. */ -int clusterSendModuleMessageToTarget(const char *target, uint64_t module_id, uint8_t type, const char *payload, uint32_t len) { +int clusterSendModuleMessageToTarget(const char *target, uint64_t module_id, uint8_t type, const char *payload, + uint32_t len) { clusterNode *node = NULL; if (target != NULL) { node = clusterLookupNode(target, strlen(target)); - if (node == NULL || node->link == NULL) return C_ERR; + if (node == NULL || node->link == NULL) { + return C_ERR; + } } - clusterSendModule(target ? node->link : NULL, - module_id, type, payload, len); + clusterSendModule(target ? node->link : NULL, module_id, type, payload, len); return C_OK; } @@ -4164,11 +4152,12 @@ void clusterPropagatePublish(robj *channel, robj *message, int sharded) { serverAssert(nodes_for_slot != NULL); listRewind(nodes_for_slot, &li); msgblock = clusterCreatePublishMsgBlock(channel, message, CLUSTERMSG_TYPE_PUBLISHSHARD); - while((ln = listNext(&li))) { + while ((ln = listNext(&li))) { clusterNode *node = listNodeValue(ln); - if (node->flags & (CLUSTER_NODE_MYSELF|CLUSTER_NODE_HANDSHAKE)) + if (node->flags & (CLUSTER_NODE_MYSELF | CLUSTER_NODE_HANDSHAKE)) { continue; - clusterSendMessage(node->link,msgblock); + } + clusterSendMessage(node->link, msgblock); } clusterMsgSendBlockDecrRefCount(msgblock); } @@ -4184,37 +4173,43 @@ void clusterPropagatePublish(robj *channel, robj *message, int sharded) { * Note that we send the failover request to everybody, master and slave nodes, * but only the masters are supposed to reply to our query. */ void clusterRequestFailoverAuth(void) { - uint32_t msglen = sizeof(clusterMsg)-sizeof(union clusterMsgData); + uint32_t msglen = sizeof(clusterMsg) - sizeof(union clusterMsgData); clusterMsgSendBlock *msgblock = createClusterMsgSendBlock(CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST, msglen); clusterMsg *hdr = &msgblock->msg; /* If this is a manual failover, set the CLUSTERMSG_FLAG0_FORCEACK bit * in the header to communicate the nodes receiving the message that * they should authorized the failover even if the master is working. */ - if (server.cluster->mf_end) hdr->mflags[0] |= CLUSTERMSG_FLAG0_FORCEACK; + if (server.cluster->mf_end) { + hdr->mflags[0] |= CLUSTERMSG_FLAG0_FORCEACK; + } clusterBroadcastMessage(msgblock); clusterMsgSendBlockDecrRefCount(msgblock); } /* Send a FAILOVER_AUTH_ACK message to the specified node. */ void clusterSendFailoverAuth(clusterNode *node) { - if (!node->link) return; + if (!node->link) { + return; + } - uint32_t msglen = sizeof(clusterMsg)-sizeof(union clusterMsgData); + uint32_t msglen = sizeof(clusterMsg) - sizeof(union clusterMsgData); clusterMsgSendBlock *msgblock = createClusterMsgSendBlock(CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK, msglen); - clusterSendMessage(node->link,msgblock); + clusterSendMessage(node->link, msgblock); clusterMsgSendBlockDecrRefCount(msgblock); } /* Send a MFSTART message to the specified node. */ void clusterSendMFStart(clusterNode *node) { - if (!node->link) return; + if (!node->link) { + return; + } - uint32_t msglen = sizeof(clusterMsg)-sizeof(union clusterMsgData); + uint32_t msglen = sizeof(clusterMsg) - sizeof(union clusterMsgData); clusterMsgSendBlock *msgblock = createClusterMsgSendBlock(CLUSTERMSG_TYPE_MFSTART, msglen); - clusterSendMessage(node->link,msgblock); + clusterSendMessage(node->link, msgblock); clusterMsgSendBlockDecrRefCount(msgblock); } @@ -4231,48 +4226,41 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * right to vote, as the cluster size is the number * of masters serving at least one slot, and quorum is the cluster * size + 1 */ - if (nodeIsSlave(myself) || myself->numslots == 0) return; + if (nodeIsSlave(myself) || myself->numslots == 0) { + return; + } /* Request epoch must be >= our currentEpoch. * Note that it is impossible for it to actually be greater since * our currentEpoch was updated as a side effect of receiving this * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { - serverLog(LL_WARNING, - "Failover auth denied to %.40s (%s): reqEpoch (%llu) < curEpoch(%llu)", - node->name, node->human_nodename, - (unsigned long long) requestCurrentEpoch, - (unsigned long long) server.cluster->currentEpoch); + serverLog(LL_WARNING, "Failover auth denied to %.40s (%s): reqEpoch (%llu) < curEpoch(%llu)", node->name, + node->human_nodename, (unsigned long long)requestCurrentEpoch, + (unsigned long long)server.cluster->currentEpoch); return; } /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { - serverLog(LL_WARNING, - "Failover auth denied to %.40s (%s): already voted for epoch %llu", - node->name, node->human_nodename, - (unsigned long long) server.cluster->currentEpoch); + serverLog(LL_WARNING, "Failover auth denied to %.40s (%s): already voted for epoch %llu", node->name, + node->human_nodename, (unsigned long long)server.cluster->currentEpoch); return; } /* Node must be a slave and its master down. * The master can be non failing if the request is flagged * with CLUSTERMSG_FLAG0_FORCEACK (manual failover). */ - if (clusterNodeIsMaster(node) || master == NULL || - (!nodeFailed(master) && !force_ack)) - { + if (clusterNodeIsMaster(node) || master == NULL || (!nodeFailed(master) && !force_ack)) { if (clusterNodeIsMaster(node)) { - serverLog(LL_WARNING, - "Failover auth denied to %.40s (%s): it is a master node", - node->name, node->human_nodename); + serverLog(LL_WARNING, "Failover auth denied to %.40s (%s): it is a master node", node->name, + node->human_nodename); } else if (master == NULL) { - serverLog(LL_WARNING, - "Failover auth denied to %.40s (%s): I don't know its master", - node->name, node->human_nodename); + serverLog(LL_WARNING, "Failover auth denied to %.40s (%s): I don't know its master", node->name, + node->human_nodename); } else if (!nodeFailed(master)) { - serverLog(LL_WARNING, - "Failover auth denied to %.40s (%s): its master is up", - node->name, node->human_nodename); + serverLog(LL_WARNING, "Failover auth denied to %.40s (%s): its master is up", node->name, + node->human_nodename); } return; } @@ -4280,14 +4268,12 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* We did not voted for a slave about this master for two * times the node timeout. This is not strictly needed for correctness * of the algorithm but makes the base case more linear. */ - if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) - { + if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: " - "can't vote about this master before %lld milliseconds", - node->name, node->human_nodename, - (long long) ((server.cluster_node_timeout*2)- - (mstime() - node->slaveof->voted_time))); + "Failover auth denied to %.40s %s: " + "can't vote about this master before %lld milliseconds", + node->name, node->human_nodename, + (long long)((server.cluster_node_timeout * 2) - (mstime() - node->slaveof->voted_time))); return; } @@ -4295,31 +4281,30 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * slots that is >= the one of the masters currently serving the same * slots in the current configuration. */ for (j = 0; j < CLUSTER_SLOTS; j++) { - if (bitmapTestBit(claimed_slots, j) == 0) continue; - if (isSlotUnclaimed(j) || - server.cluster->slots[j]->configEpoch <= requestConfigEpoch) - { + if (bitmapTestBit(claimed_slots, j) == 0) { + continue; + } + if (isSlotUnclaimed(j) || server.cluster->slots[j]->configEpoch <= requestConfigEpoch) { continue; } /* If we reached this point we found a slot that in our current slots * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s (%s): " - "slot %d epoch (%llu) > reqEpoch (%llu)", - node->name, node->human_nodename, j, - (unsigned long long) server.cluster->slots[j]->configEpoch, - (unsigned long long) requestConfigEpoch); + "Failover auth denied to %.40s (%s): " + "slot %d epoch (%llu) > reqEpoch (%llu)", + node->name, node->human_nodename, j, (unsigned long long)server.cluster->slots[j]->configEpoch, + (unsigned long long)requestConfigEpoch); return; } /* We can vote for this slave. */ server.cluster->lastVoteEpoch = server.cluster->currentEpoch; node->slaveof->voted_time = mstime(); - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_FSYNC_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_FSYNC_CONFIG); clusterSendFailoverAuth(node); - serverLog(LL_NOTICE, "Failover auth granted to %.40s (%s) for epoch %llu", - node->name, node->human_nodename, (unsigned long long) server.cluster->currentEpoch); + serverLog(LL_NOTICE, "Failover auth granted to %.40s (%s) for epoch %llu", node->name, node->human_nodename, + (unsigned long long)server.cluster->currentEpoch); } /* This function returns the "rank" of this instance, a slave, in the context @@ -4341,13 +4326,17 @@ int clusterGetSlaveRank(void) { serverAssert(nodeIsSlave(myself)); master = myself->slaveof; - if (master == NULL) return 0; /* Never called by slaves without master. */ + if (master == NULL) { + return 0; /* Never called by slaves without master. */ + } myoffset = replicationGetSlaveOffset(); - for (j = 0; j < master->numslaves; j++) - if (master->slaves[j] != myself && - !nodeCantFailover(master->slaves[j]) && - master->slaves[j]->repl_offset > myoffset) rank++; + for (j = 0; j < master->numslaves; j++) { + if (master->slaves[j] != myself && !nodeCantFailover(master->slaves[j]) && + master->slaves[j]->repl_offset > myoffset) { + rank++; + } + } return rank; } @@ -4380,19 +4369,20 @@ void clusterLogCantFailover(int reason) { /* Don't log if we have the same reason for some time. */ if (reason == server.cluster->cant_failover_reason && - time(NULL)-lastlog_time < CLUSTER_CANT_FAILOVER_RELOG_PERIOD) + time(NULL) - lastlog_time < CLUSTER_CANT_FAILOVER_RELOG_PERIOD) { return; + } server.cluster->cant_failover_reason = reason; /* We also don't emit any log if the master failed no long ago, the * goal of this function is to log slaves in a stalled condition for * a long time. */ - if (myself->slaveof && - nodeFailed(myself->slaveof) && - (mstime() - myself->slaveof->fail_time) < nolog_fail_time) return; + if (myself->slaveof && nodeFailed(myself->slaveof) && (mstime() - myself->slaveof->fail_time) < nolog_fail_time) { + return; + } - switch(reason) { + switch (reason) { case CLUSTER_CANT_FAILOVER_DATA_AGE: msg = "Disconnected from master for longer than allowed. " "Please check the 'cluster-replica-validity-factor' configuration " @@ -4412,14 +4402,14 @@ void clusterLogCantFailover(int reason) { break; } lastlog_time = time(NULL); - serverLog(LL_NOTICE,"Currently unable to failover: %s", msg); - + serverLog(LL_NOTICE, "Currently unable to failover: %s", msg); + int cur_vote = server.cluster->failover_auth_count; int cur_quorum = (server.cluster->size / 2) + 1; /* Emits a log when an election is in progress and waiting for votes or when the failover attempt expired. */ if (reason == CLUSTER_CANT_FAILOVER_WAITING_VOTES || reason == CLUSTER_CANT_FAILOVER_EXPIRED) { serverLog(LL_NOTICE, "Needed quorum: %d. Number of votes received so far: %d", cur_quorum, cur_vote); - } + } } /* This function implements the final part of automatic and manual failovers, @@ -4432,7 +4422,9 @@ void clusterFailoverReplaceYourMaster(void) { int j; clusterNode *oldmaster = myself->slaveof; - if (clusterNodeIsMaster(myself) || oldmaster == NULL) return; + if (clusterNodeIsMaster(myself) || oldmaster == NULL) { + return; + } /* 1) Turn this node into a master. */ clusterSetNodeAsMaster(myself); @@ -4442,7 +4434,7 @@ void clusterFailoverReplaceYourMaster(void) { for (j = 0; j < CLUSTER_SLOTS; j++) { if (clusterNodeCoversSlot(oldmaster, j)) { clusterDelSlot(j); - clusterAddSlot(myself,j); + clusterAddSlot(myself, j); } } @@ -4470,8 +4462,7 @@ void clusterHandleSlaveFailover(void) { mstime_t data_age; mstime_t auth_age = mstime() - server.cluster->failover_auth_time; int needed_quorum = (server.cluster->size / 2) + 1; - int manual_failover = server.cluster->mf_end != 0 && - server.cluster->mf_can_start; + int manual_failover = server.cluster->mf_end != 0 && server.cluster->mf_can_start; mstime_t auth_timeout, auth_retry_time; server.cluster->todo_before_sleep &= ~CLUSTER_TODO_HANDLE_FAILOVER; @@ -4483,9 +4474,11 @@ void clusterHandleSlaveFailover(void) { * Timeout is MAX(NODE_TIMEOUT*2,2000) milliseconds. * Retry is two times the Timeout. */ - auth_timeout = server.cluster_node_timeout*2; - if (auth_timeout < CLUSTER_OPERATION_TIMEOUT) auth_timeout = CLUSTER_OPERATION_TIMEOUT; - auth_retry_time = auth_timeout*2; + auth_timeout = server.cluster_node_timeout * 2; + if (auth_timeout < CLUSTER_OPERATION_TIMEOUT) { + auth_timeout = CLUSTER_OPERATION_TIMEOUT; + } + auth_retry_time = auth_timeout * 2; /* Pre conditions to run the function, that must be met both in case * of an automatic or manual failover: @@ -4493,11 +4486,8 @@ void clusterHandleSlaveFailover(void) { * 2) Our master is flagged as FAIL, or this is a manual failover. * 3) We don't have the no failover configuration set, and this is * not a manual failover. */ - if (clusterNodeIsMaster(myself) || - myself->slaveof == NULL || - (!nodeFailed(myself->slaveof) && !manual_failover) || - (server.cluster_slave_no_failover && !manual_failover)) - { + if (clusterNodeIsMaster(myself) || myself->slaveof == NULL || (!nodeFailed(myself->slaveof) && !manual_failover) || + (server.cluster_slave_no_failover && !manual_failover)) { /* There are no reasons to failover, so we set the reason why we * are returning without failing over to NONE. */ server.cluster->cant_failover_reason = CLUSTER_CANT_FAILOVER_NONE; @@ -4507,8 +4497,7 @@ void clusterHandleSlaveFailover(void) { /* Set data_age to the number of milliseconds we are disconnected from * the master. */ if (server.repl_state == REPL_STATE_CONNECTED) { - data_age = (mstime_t)(server.unixtime - server.master->lastinteraction) - * 1000; + data_age = (mstime_t)(server.unixtime - server.master->lastinteraction) * 1000; } else { data_age = (mstime_t)(server.unixtime - server.repl_down_since) * 1000; } @@ -4516,18 +4505,17 @@ void clusterHandleSlaveFailover(void) { /* Remove the node timeout from the data age as it is fine that we are * disconnected from our master at least for the time it was down to be * flagged as FAIL, that's the baseline. */ - if (data_age > server.cluster_node_timeout) + if (data_age > server.cluster_node_timeout) { data_age -= server.cluster_node_timeout; + } /* Check if our data is recent enough according to the slave validity * factor configured by the user. * * Check bypassed for manual failovers. */ if (server.cluster_slave_validity_factor && - data_age > - (((mstime_t)server.repl_ping_slave_period * 1000) + - (server.cluster_node_timeout * server.cluster_slave_validity_factor))) - { + data_age > (((mstime_t)server.repl_ping_slave_period * 1000) + + (server.cluster_node_timeout * server.cluster_slave_validity_factor))) { if (!manual_failover) { clusterLogCantFailover(CLUSTER_CANT_FAILOVER_DATA_AGE); return; @@ -4538,16 +4526,15 @@ void clusterHandleSlaveFailover(void) { * elapsed, we can setup a new one. */ if (auth_age > auth_retry_time) { server.cluster->failover_auth_time = mstime() + - 500 + /* Fixed delay of 500 milliseconds, let FAIL msg propagate. */ - random() % 500; /* Random delay between 0 and 500 milliseconds. */ + 500 + /* Fixed delay of 500 milliseconds, let FAIL msg propagate. */ + random() % 500; /* Random delay between 0 and 500 milliseconds. */ server.cluster->failover_auth_count = 0; server.cluster->failover_auth_sent = 0; server.cluster->failover_auth_rank = clusterGetSlaveRank(); /* We add another delay that is proportional to the slave rank. * Specifically 1 second * rank. This way slaves that have a probably * less updated replication offset, are penalized. */ - server.cluster->failover_auth_time += - server.cluster->failover_auth_rank * 1000; + server.cluster->failover_auth_time += server.cluster->failover_auth_rank * 1000; /* However if this is a manual failover, no delay is needed. */ if (server.cluster->mf_end) { server.cluster->failover_auth_time = mstime(); @@ -4555,11 +4542,10 @@ void clusterHandleSlaveFailover(void) { clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); } serverLog(LL_NOTICE, - "Start of election delayed for %lld milliseconds " - "(rank #%d, offset %lld).", - server.cluster->failover_auth_time - mstime(), - server.cluster->failover_auth_rank, - replicationGetSlaveOffset()); + "Start of election delayed for %lld milliseconds " + "(rank #%d, offset %lld).", + server.cluster->failover_auth_time - mstime(), server.cluster->failover_auth_rank, + replicationGetSlaveOffset()); /* Now that we have a scheduled election, broadcast our offset * to all the other slaves so that they'll updated their offsets * if our offset is better. */ @@ -4572,18 +4558,14 @@ void clusterHandleSlaveFailover(void) { * Update the delay if our rank changed. * * Not performed if this is a manual failover. */ - if (server.cluster->failover_auth_sent == 0 && - server.cluster->mf_end == 0) - { + if (server.cluster->failover_auth_sent == 0 && server.cluster->mf_end == 0) { int newrank = clusterGetSlaveRank(); if (newrank > server.cluster->failover_auth_rank) { - long long added_delay = - (newrank - server.cluster->failover_auth_rank) * 1000; + long long added_delay = (newrank - server.cluster->failover_auth_rank) * 1000; server.cluster->failover_auth_time += added_delay; server.cluster->failover_auth_rank = newrank; - serverLog(LL_NOTICE, - "Replica rank updated to #%d, added %lld milliseconds of delay.", - newrank, added_delay); + serverLog(LL_NOTICE, "Replica rank updated to #%d, added %lld milliseconds of delay.", newrank, + added_delay); } } @@ -4603,13 +4585,11 @@ void clusterHandleSlaveFailover(void) { if (server.cluster->failover_auth_sent == 0) { server.cluster->currentEpoch++; server.cluster->failover_auth_epoch = server.cluster->currentEpoch; - serverLog(LL_NOTICE,"Starting a failover election for epoch %llu.", - (unsigned long long) server.cluster->currentEpoch); + serverLog(LL_NOTICE, "Starting a failover election for epoch %llu.", + (unsigned long long)server.cluster->currentEpoch); clusterRequestFailoverAuth(); server.cluster->failover_auth_sent = 1; - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| - CLUSTER_TODO_UPDATE_STATE| - CLUSTER_TODO_FSYNC_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_FSYNC_CONFIG); return; /* Wait for replies. */ } @@ -4617,15 +4597,13 @@ void clusterHandleSlaveFailover(void) { if (server.cluster->failover_auth_count >= needed_quorum) { /* We have the quorum, we can finally failover the master. */ - serverLog(LL_NOTICE, - "Failover election won: I'm the new master."); + serverLog(LL_NOTICE, "Failover election won: I'm the new master."); /* Update my configEpoch to the epoch of the election. */ if (myself->configEpoch < server.cluster->failover_auth_epoch) { myself->configEpoch = server.cluster->failover_auth_epoch; - serverLog(LL_NOTICE, - "configEpoch set to %llu after successful failover", - (unsigned long long) myself->configEpoch); + serverLog(LL_NOTICE, "configEpoch set to %llu after successful failover", + (unsigned long long)myself->configEpoch); } /* Take responsibility for the cluster slots. */ @@ -4669,15 +4647,23 @@ void clusterHandleSlaveMigration(int max_slaves) { dictEntry *de; /* Step 1: Don't migrate if the cluster state is not ok. */ - if (server.cluster->state != CLUSTER_OK) return; + if (server.cluster->state != CLUSTER_OK) { + return; + } /* Step 2: Don't migrate if my master will not be left with at least * 'migration-barrier' slaves after my migration. */ - if (mymaster == NULL) return; - for (j = 0; j < mymaster->numslaves; j++) - if (!nodeFailed(mymaster->slaves[j]) && - !nodeTimedOut(mymaster->slaves[j])) okslaves++; - if (okslaves <= server.cluster_migration_barrier) return; + if (mymaster == NULL) { + return; + } + for (j = 0; j < mymaster->numslaves; j++) { + if (!nodeFailed(mymaster->slaves[j]) && !nodeTimedOut(mymaster->slaves[j])) { + okslaves++; + } + } + if (okslaves <= server.cluster_migration_barrier) { + return; + } /* Step 3: Identify a candidate for migration, and check if among the * masters with the greatest number of ok slaves, I'm the one with the @@ -4691,7 +4677,7 @@ void clusterHandleSlaveMigration(int max_slaves) { * happen and relatively harmless when it does. */ candidate = myself; di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); int okslaves = 0, is_orphaned = 1; @@ -4699,19 +4685,31 @@ void clusterHandleSlaveMigration(int max_slaves) { * used to have slaves or if failed over a master that had slaves * (MIGRATE_TO flag). This way we only migrate to instances that were * supposed to have replicas. */ - if (nodeIsSlave(node) || nodeFailed(node)) is_orphaned = 0; - if (!(node->flags & CLUSTER_NODE_MIGRATE_TO)) is_orphaned = 0; + if (nodeIsSlave(node) || nodeFailed(node)) { + is_orphaned = 0; + } + if (!(node->flags & CLUSTER_NODE_MIGRATE_TO)) { + is_orphaned = 0; + } /* Check number of working slaves. */ - if (clusterNodeIsMaster(node)) okslaves = clusterCountNonFailingSlaves(node); - if (okslaves > 0) is_orphaned = 0; + if (clusterNodeIsMaster(node)) { + okslaves = clusterCountNonFailingSlaves(node); + } + if (okslaves > 0) { + is_orphaned = 0; + } if (is_orphaned) { - if (!target && node->numslots > 0) target = node; + if (!target && node->numslots > 0) { + target = node; + } /* Track the starting time of the orphaned condition for this * master. */ - if (!node->orphaned_time) node->orphaned_time = mstime(); + if (!node->orphaned_time) { + node->orphaned_time = mstime(); + } } else { node->orphaned_time = 0; } @@ -4721,10 +4719,7 @@ void clusterHandleSlaveMigration(int max_slaves) { * node ID. */ if (okslaves == max_slaves) { for (j = 0; j < node->numslaves; j++) { - if (memcmp(node->slaves[j]->name, - candidate->name, - CLUSTER_NAMELEN) < 0) - { + if (memcmp(node->slaves[j]->name, candidate->name, CLUSTER_NAMELEN) < 0) { candidate = node->slaves[j]; } } @@ -4737,14 +4732,10 @@ void clusterHandleSlaveMigration(int max_slaves) { * couple of seconds, so that during failovers, we give some time to * the natural slaves of this instance to advertise their switch from * the old master to the new one. */ - if (target && candidate == myself && - (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && - !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) - { - serverLog(LL_NOTICE,"Migrating to orphaned master %.40s (%s) in shard %.40s", - target->name, - target->human_nodename, - target->shard_id); + if (target && candidate == myself && (mstime() - target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && + !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { + serverLog(LL_NOTICE, "Migrating to orphaned master %.40s (%s) in shard %.40s", target->name, + target->human_nodename, target->shard_id); clusterSetMaster(target, 1); } } @@ -4798,7 +4789,7 @@ void resetManualFailover(void) { /* If a manual failover timed out, abort it. */ void manualFailoverCheckTimeout(void) { if (server.cluster->mf_end && server.cluster->mf_end < mstime()) { - serverLog(LL_WARNING,"Manual failover timed out."); + serverLog(LL_WARNING, "Manual failover timed out."); resetManualFailover(); } } @@ -4807,21 +4798,26 @@ void manualFailoverCheckTimeout(void) { * forward with a manual failover state machine. */ void clusterHandleManualFailover(void) { /* Return ASAP if no manual failover is in progress. */ - if (server.cluster->mf_end == 0) return; + if (server.cluster->mf_end == 0) { + return; + } /* If mf_can_start is non-zero, the failover was already triggered so the * next steps are performed by clusterHandleSlaveFailover(). */ - if (server.cluster->mf_can_start) return; + if (server.cluster->mf_can_start) { + return; + } - if (server.cluster->mf_master_offset == -1) return; /* Wait for offset... */ + if (server.cluster->mf_master_offset == -1) { + return; /* Wait for offset... */ + } if (server.cluster->mf_master_offset == replicationGetSlaveOffset()) { /* Our replication offset matches the master replication offset * announced after clients were paused. We can start the failover. */ server.cluster->mf_can_start = 1; - serverLog(LL_NOTICE, - "All master replication stream processed, " - "manual failover can start."); + serverLog(LL_NOTICE, "All master replication stream processed, " + "manual failover can start."); clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); return; } @@ -4838,10 +4834,13 @@ void clusterHandleManualFailover(void) { static int clusterNodeCronHandleReconnect(clusterNode *node, mstime_t handshake_timeout, mstime_t now) { /* Not interested in reconnecting the link with myself or nodes * for which we have no address. */ - if (node->flags & (CLUSTER_NODE_MYSELF|CLUSTER_NODE_NOADDR)) return 1; + if (node->flags & (CLUSTER_NODE_MYSELF | CLUSTER_NODE_NOADDR)) { + return 1; + } - if (node->flags & CLUSTER_NODE_PFAIL) + if (node->flags & CLUSTER_NODE_PFAIL) { server.cluster->stats_pfail_nodes++; + } /* A Node in HANDSHAKE state has a limited lifespan equal to the * configured node timeout. */ @@ -4854,17 +4853,20 @@ static int clusterNodeCronHandleReconnect(clusterNode *node, mstime_t handshake_ clusterLink *link = createClusterLink(node); link->conn = connCreate(connTypeOfCluster()); connSetPrivateData(link->conn, link); - if (connConnect(link->conn, node->ip, node->cport, server.bind_source_addr, - clusterLinkConnectHandler) == C_ERR) { + if (connConnect(link->conn, node->ip, node->cport, server.bind_source_addr, clusterLinkConnectHandler) == + C_ERR) { /* We got a synchronous error from connect before * clusterSendPing() had a chance to be called. * If node->ping_sent is zero, failure detection can't work, * so we claim we actually sent a ping now (that will * be really sent as soon as the link is obtained). */ - if (node->ping_sent == 0) node->ping_sent = mstime(); - serverLog(LL_DEBUG, "Unable to connect to " - "Cluster Node [%s]:%d -> %s", node->ip, - node->cport, server.neterr); + if (node->ping_sent == 0) { + node->ping_sent = mstime(); + } + serverLog(LL_DEBUG, + "Unable to connect to " + "Cluster Node [%s]:%d -> %s", + node->ip, node->cport, server.neterr); freeClusterLink(link); return 0; @@ -4880,9 +4882,10 @@ static void freeClusterLinkOnBufferLimitReached(clusterLink *link) { unsigned long long mem_link = link->send_msg_queue_mem; if (mem_link > server.cluster_link_msg_queue_limit_bytes) { - serverLog(LL_WARNING, "Freeing cluster link(%s node %.40s, used memory: %llu) due to " - "exceeding send buffer memory limit.", link->inbound ? "from" : "to", - link->node ? link->node->name : "", mem_link); + serverLog(LL_WARNING, + "Freeing cluster link(%s node %.40s, used memory: %llu) due to " + "exceeding send buffer memory limit.", + link->inbound ? "from" : "to", link->node ? link->node->name : "", mem_link); freeClusterLink(link); server.cluster->stat_cluster_links_buffer_limit_exceeded++; } @@ -4900,8 +4903,8 @@ void clusterCron(void) { dictEntry *de; int update_state = 0; int orphaned_masters; /* How many masters there are without ok slaves. */ - int max_slaves; /* Max number of ok slaves for a single master. */ - int this_slaves; /* Number of ok slaves for our master (if we are slave). */ + int max_slaves; /* Max number of ok slaves for a single master. */ + int this_slaves; /* Number of ok slaves for our master (if we are slave). */ mstime_t min_pong = 0, now = mstime(); clusterNode *min_pong_node = NULL; static unsigned long long iteration = 0; @@ -4916,13 +4919,15 @@ void clusterCron(void) { * just the NODE_TIMEOUT value, but when NODE_TIMEOUT is too small we use * the value of 1 second. */ handshake_timeout = server.cluster_node_timeout; - if (handshake_timeout < 1000) handshake_timeout = 1000; + if (handshake_timeout < 1000) { + handshake_timeout = 1000; + } /* Clear so clusterNodeCronHandleReconnect can count the number of nodes in PFAIL. */ server.cluster->stats_pfail_nodes = 0; /* Run through some of the operations we want to do on each cluster node. */ di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); /* We free the inbound or outboud link to the node if the link has an * oversized message send queue and immediately try reconnecting. */ @@ -4930,9 +4935,11 @@ void clusterCron(void) { /* The protocol is that function(s) below return non-zero if the node was * terminated. */ - if(clusterNodeCronHandleReconnect(node, handshake_timeout, now)) continue; + if (clusterNodeCronHandleReconnect(node, handshake_timeout, now)) { + continue; + } } - dictReleaseIterator(di); + dictReleaseIterator(di); /* Ping some random node 1 time every 10 iterations, so that we usually ping * one random node every second. */ @@ -4946,16 +4953,19 @@ void clusterCron(void) { clusterNode *this = dictGetVal(de); /* Don't ping nodes disconnected or with a ping currently active. */ - if (this->link == NULL || this->ping_sent != 0) continue; - if (this->flags & (CLUSTER_NODE_MYSELF|CLUSTER_NODE_HANDSHAKE)) + if (this->link == NULL || this->ping_sent != 0) { continue; + } + if (this->flags & (CLUSTER_NODE_MYSELF | CLUSTER_NODE_HANDSHAKE)) { + continue; + } if (min_pong_node == NULL || min_pong > this->pong_received) { min_pong_node = this; min_pong = this->pong_received; } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s", min_pong_node->name); + serverLog(LL_DEBUG, "Pinging node %.40s", min_pong_node->name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4970,13 +4980,13 @@ void clusterCron(void) { max_slaves = 0; this_slaves = 0; di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); now = mstime(); /* Use an updated time at every iteration. */ - if (node->flags & - (CLUSTER_NODE_MYSELF|CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE)) - continue; + if (node->flags & (CLUSTER_NODE_MYSELF | CLUSTER_NODE_NOADDR | CLUSTER_NODE_HANDSHAKE)) { + continue; + } /* Orphaned master check, useful only if the current instance * is a slave that may migrate to another master. */ @@ -4986,14 +4996,15 @@ void clusterCron(void) { /* A master is orphaned if it is serving a non-zero number of * slots, have no working slaves, but used to have at least one * slave, or failed over a master that used to have slaves. */ - if (okslaves == 0 && node->numslots > 0 && - node->flags & CLUSTER_NODE_MIGRATE_TO) - { + if (okslaves == 0 && node->numslots > 0 && node->flags & CLUSTER_NODE_MIGRATE_TO) { orphaned_masters++; } - if (okslaves > max_slaves) max_slaves = okslaves; - if (myself->slaveof == node) + if (okslaves > max_slaves) { + max_slaves = okslaves; + } + if (myself->slaveof == node) { this_slaves = okslaves; + } } /* If we are not receiving any data for more than half the cluster @@ -5001,15 +5012,13 @@ void clusterCron(void) { * issue even if the node is alive. */ mstime_t ping_delay = now - node->ping_sent; mstime_t data_delay = now - node->data_received; - if (node->link && /* is connected */ - now - node->link->ctime > - server.cluster_node_timeout && /* was not already reconnected */ - node->ping_sent && /* we already sent a ping */ + if (node->link && /* is connected */ + now - node->link->ctime > server.cluster_node_timeout && /* was not already reconnected */ + node->ping_sent && /* we already sent a ping */ /* and we are waiting for the pong more than timeout/2 */ - ping_delay > server.cluster_node_timeout/2 && + ping_delay > server.cluster_node_timeout / 2 && /* and in such interval we are not seeing any traffic at all. */ - data_delay > server.cluster_node_timeout/2) - { + data_delay > server.cluster_node_timeout / 2) { /* Disconnect the link, it will be reconnected automatically. */ freeClusterLink(node->link); } @@ -5018,29 +5027,24 @@ void clusterCron(void) { * received PONG is older than half the cluster timeout, send * a new ping now, to ensure all the nodes are pinged without * a too big delay. */ - mstime_t ping_interval = server.cluster_ping_interval ? - server.cluster_ping_interval : server.cluster_node_timeout/2; - if (node->link && - node->ping_sent == 0 && - (now - node->pong_received) > ping_interval) - { + mstime_t ping_interval = + server.cluster_ping_interval ? server.cluster_ping_interval : server.cluster_node_timeout / 2; + if (node->link && node->ping_sent == 0 && (now - node->pong_received) > ping_interval) { clusterSendPing(node->link, CLUSTERMSG_TYPE_PING); continue; } /* If we are a master and one of the slaves requested a manual * failover, ping it continuously. */ - if (server.cluster->mf_end && - clusterNodeIsMaster(myself) && - server.cluster->mf_slave == node && - node->link) - { + if (server.cluster->mf_end && clusterNodeIsMaster(myself) && server.cluster->mf_slave == node && node->link) { clusterSendPing(node->link, CLUSTERMSG_TYPE_PING); continue; } /* Check only if we have an active ping for this instance. */ - if (node->ping_sent == 0) continue; + if (node->ping_sent == 0) { + continue; + } /* Check if this node looks unreachable. * Note that if we already received the PONG, then node->ping_sent @@ -5050,19 +5054,18 @@ void clusterCron(void) { * We also consider every incoming data as proof of liveness, since * our cluster bus link is also used for data: under heavy data * load pong delays are possible. */ - mstime_t node_delay = (ping_delay < data_delay) ? ping_delay : - data_delay; + mstime_t node_delay = (ping_delay < data_delay) ? ping_delay : data_delay; if (node_delay > server.cluster_node_timeout) { /* Timeout reached. Set the node as possibly failing if it is * not already in this state. */ - if (!(node->flags & (CLUSTER_NODE_PFAIL|CLUSTER_NODE_FAIL))) { + if (!(node->flags & (CLUSTER_NODE_PFAIL | CLUSTER_NODE_FAIL))) { node->flags |= CLUSTER_NODE_PFAIL; update_state = 1; if (clusterNodeIsMaster(myself) && server.cluster->size == 1) { - markNodeAsFailingIfNeeded(node); + markNodeAsFailingIfNeeded(node); } else { - serverLog(LL_DEBUG,"*** NODE %.40s possibly failing", node->name); + serverLog(LL_DEBUG, "*** NODE %.40s possibly failing", node->name); } } } @@ -5072,11 +5075,7 @@ void clusterCron(void) { /* If we are a slave node but the replication is still turned off, * enable it if we know the address of our master and it appears to * be up. */ - if (nodeIsSlave(myself) && - server.masterhost == NULL && - myself->slaveof && - nodeHasAddr(myself->slaveof)) - { + if (nodeIsSlave(myself) && server.masterhost == NULL && myself->slaveof && nodeHasAddr(myself->slaveof)) { replicationSetMaster(myself->slaveof->ip, getNodeDefaultReplicationPort(myself->slaveof)); } @@ -5085,20 +5084,23 @@ void clusterCron(void) { if (nodeIsSlave(myself)) { clusterHandleManualFailover(); - if (!(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) + if (!(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { clusterHandleSlaveFailover(); + } /* If there are orphaned slaves, and we are a slave among the masters * with the max number of non-failing slaves, consider migrating to * the orphaned masters. Note that it does not make sense to try * a migration if there is no master with at least *two* working * slaves. */ if (orphaned_masters && max_slaves >= 2 && this_slaves == max_slaves && - server.cluster_allow_replica_migration) + server.cluster_allow_replica_migration) { clusterHandleSlaveMigration(max_slaves); + } } - if (update_state || server.cluster->state == CLUSTER_FAIL) + if (update_state || server.cluster->state == CLUSTER_FAIL) { clusterUpdateState(); + } } /* This function is called before the event handler returns to sleep for @@ -5118,8 +5120,9 @@ void clusterBeforeSleep(void) { * as it was handled only in clusterCron */ if (nodeIsSlave(myself)) { clusterHandleManualFailover(); - if (!(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) + if (!(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { clusterHandleSlaveFailover(); + } } } else if (flags & CLUSTER_TODO_HANDLE_FAILOVER) { /* Handle failover, this is needed when it is likely that there is already @@ -5128,8 +5131,9 @@ void clusterBeforeSleep(void) { } /* Update the cluster state. */ - if (flags & CLUSTER_TODO_UPDATE_STATE) + if (flags & CLUSTER_TODO_UPDATE_STATE) { clusterUpdateState(); + } /* Save the config, possibly using fsync. */ if (flags & CLUSTER_TODO_SAVE_CONFIG) { @@ -5149,23 +5153,23 @@ void clusterDoBeforeSleep(int flags) { /* Test bit 'pos' in a generic bitmap. Return 1 if the bit is set, * otherwise 0. */ int bitmapTestBit(unsigned char *bitmap, int pos) { - off_t byte = pos/8; - int bit = pos&7; - return (bitmap[byte] & (1<nodes); dictEntry *de; int slaves = 0; - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); - if (nodeIsSlave(node)) continue; + if (nodeIsSlave(node)) { + continue; + } slaves += node->numslaves; } dictReleaseIterator(di); @@ -5187,9 +5193,9 @@ int clusterMastersHaveSlaves(void) { /* Set the slot bit and return the old value. */ int clusterNodeSetSlotBit(clusterNode *n, int slot) { - int old = bitmapTestBit(n->slots,slot); + int old = bitmapTestBit(n->slots, slot); if (!old) { - bitmapSetBit(n->slots,slot); + bitmapSetBit(n->slots, slot); n->numslots++; /* When a master gets its first slot, even if it has no slaves, * it gets flagged with MIGRATE_TO, that is, the master is a valid @@ -5204,17 +5210,18 @@ int clusterNodeSetSlotBit(clusterNode *n, int slot) { * migration targets if the rest of the cluster is not a slave-less. * * See https://github.com/redis/redis/issues/3043 for more info. */ - if (n->numslots == 1 && clusterMastersHaveSlaves()) + if (n->numslots == 1 && clusterMastersHaveSlaves()) { n->flags |= CLUSTER_NODE_MIGRATE_TO; + } } return old; } /* Clear the slot bit and return the old value. */ int clusterNodeClearSlotBit(clusterNode *n, int slot) { - int old = bitmapTestBit(n->slots,slot); + int old = bitmapTestBit(n->slots, slot); if (old) { - bitmapClearBit(n->slots,slot); + bitmapClearBit(n->slots, slot); n->numslots--; } return old; @@ -5222,7 +5229,7 @@ int clusterNodeClearSlotBit(clusterNode *n, int slot) { /* Return the slot bit from the cluster node structure. */ int clusterNodeCoversSlot(clusterNode *n, int slot) { - return bitmapTestBit(n->slots,slot); + return bitmapTestBit(n->slots, slot); } /* Add the specified slot to the list of slots that node 'n' will @@ -5230,8 +5237,10 @@ int clusterNodeCoversSlot(clusterNode *n, int slot) { * If the slot is already assigned to another instance this is considered * an error and C_ERR is returned. */ int clusterAddSlot(clusterNode *n, int slot) { - if (server.cluster->slots[slot]) return C_ERR; - clusterNodeSetSlotBit(n,slot); + if (server.cluster->slots[slot]) { + return C_ERR; + } + clusterNodeSetSlotBit(n, slot); server.cluster->slots[slot] = n; bitmapClearBit(server.cluster->owner_not_claiming_slot, slot); return C_OK; @@ -5243,12 +5252,14 @@ int clusterAddSlot(clusterNode *n, int slot) { int clusterDelSlot(int slot) { clusterNode *n = server.cluster->slots[slot]; - if (!n) return C_ERR; + if (!n) { + return C_ERR; + } /* Cleanup the channels in master/replica as part of slot deletion. */ removeChannelsInSlot(slot); /* Clear the slot bit. */ - serverAssert(clusterNodeClearSlotBit(n,slot) == 1); + serverAssert(clusterNodeClearSlotBit(n, slot) == 1); server.cluster->slots[slot] = NULL; /* Make owner_not_claiming_slot flag consistent with slot ownership information. */ bitmapClearBit(server.cluster->owner_not_claiming_slot, slot); @@ -5272,10 +5283,8 @@ int clusterDelNodeSlots(clusterNode *node) { /* Clear the migrating / importing state for all the slots. * This is useful at initialization and when turning a master into slave. */ void clusterCloseAllSlots(void) { - memset(server.cluster->migrating_slots_to,0, - sizeof(server.cluster->migrating_slots_to)); - memset(server.cluster->importing_slots_from,0, - sizeof(server.cluster->importing_slots_from)); + memset(server.cluster->migrating_slots_to, 0, sizeof(server.cluster->migrating_slots_to)); + memset(server.cluster->importing_slots_from, 0, sizeof(server.cluster->importing_slots_from)); } /* ----------------------------------------------------------------------------- @@ -5304,10 +5313,13 @@ void clusterUpdateState(void) { * reconfigure this node. Note that the delay is calculated starting from * the first call to this function and not since the server start, in order * to not count the DB loading time. */ - if (first_call_time == 0) first_call_time = mstime(); - if (clusterNodeIsMaster(myself) && - server.cluster->state == CLUSTER_FAIL && - mstime() - first_call_time < CLUSTER_WRITABLE_DELAY) return; + if (first_call_time == 0) { + first_call_time = mstime(); + } + if (clusterNodeIsMaster(myself) && server.cluster->state == CLUSTER_FAIL && + mstime() - first_call_time < CLUSTER_WRITABLE_DELAY) { + return; + } /* Start assuming the state is OK. We'll turn it into FAIL if there * are the right conditions. */ @@ -5316,9 +5328,7 @@ void clusterUpdateState(void) { /* Check if all the slots are covered. */ if (server.cluster_require_full_coverage) { for (j = 0; j < CLUSTER_SLOTS; j++) { - if (server.cluster->slots[j] == NULL || - server.cluster->slots[j]->flags & (CLUSTER_NODE_FAIL)) - { + if (server.cluster->slots[j] == NULL || server.cluster->slots[j]->flags & (CLUSTER_NODE_FAIL)) { new_state = CLUSTER_FAIL; break; } @@ -5336,13 +5346,14 @@ void clusterUpdateState(void) { server.cluster->size = 0; di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); if (clusterNodeIsMaster(node) && node->numslots) { server.cluster->size++; - if ((node->flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) == 0) + if ((node->flags & (CLUSTER_NODE_FAIL | CLUSTER_NODE_PFAIL)) == 0) { reachable_masters++; + } } } dictReleaseIterator(di); @@ -5367,22 +5378,20 @@ void clusterUpdateState(void) { * minority, don't let it accept queries for some time after the * partition heals, to make sure there is enough time to receive * a configuration update. */ - if (rejoin_delay > CLUSTER_MAX_REJOIN_DELAY) + if (rejoin_delay > CLUSTER_MAX_REJOIN_DELAY) { rejoin_delay = CLUSTER_MAX_REJOIN_DELAY; - if (rejoin_delay < CLUSTER_MIN_REJOIN_DELAY) + } + if (rejoin_delay < CLUSTER_MIN_REJOIN_DELAY) { rejoin_delay = CLUSTER_MIN_REJOIN_DELAY; + } - if (new_state == CLUSTER_OK && - clusterNodeIsMaster(myself) && - mstime() - among_minority_time < rejoin_delay) - { + if (new_state == CLUSTER_OK && clusterNodeIsMaster(myself) && mstime() - among_minority_time < rejoin_delay) { return; } /* Change the state and log the event. */ - serverLog(new_state == CLUSTER_OK ? LL_NOTICE : LL_WARNING, - "Cluster state changed: %s", - new_state == CLUSTER_OK ? "ok" : "fail"); + serverLog(new_state == CLUSTER_OK ? LL_NOTICE : LL_WARNING, "Cluster state changed: %s", + new_state == CLUSTER_OK ? "ok" : "fail"); server.cluster->state = new_state; } } @@ -5410,27 +5419,35 @@ int verifyClusterConfigWithData(void) { /* Return ASAP if a module disabled cluster redirections. In that case * every master can store keys about every possible hash slot. */ - if (server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_REDIRECTION) + if (server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_REDIRECTION) { return C_OK; + } /* If this node is a slave, don't perform the check at all as we * completely depend on the replication stream. */ - if (nodeIsSlave(myself)) return C_OK; + if (nodeIsSlave(myself)) { + return C_OK; + } /* Make sure we only have keys in DB0. */ for (j = 1; j < server.dbnum; j++) { - if (kvstoreSize(server.db[j].keys)) return C_ERR; + if (kvstoreSize(server.db[j].keys)) { + return C_ERR; + } } /* Check that all the slots we see populated memory have a corresponding * entry in the cluster table. Otherwise fix the table. */ for (j = 0; j < CLUSTER_SLOTS; j++) { - if (!countKeysInSlot(j)) continue; /* No keys in this slot. */ + if (!countKeysInSlot(j)) { + continue; /* No keys in this slot. */ + } /* Check if we are assigned to this slot or if we are importing it. * In both cases check the next slot as the configuration makes * sense. */ - if (server.cluster->slots[j] == myself || - server.cluster->importing_slots_from[j] != NULL) continue; + if (server.cluster->slots[j] == myself || server.cluster->importing_slots_from[j] != NULL) { + continue; + } /* If we are here data and cluster config don't agree, and we have * slot 'j' populated even if we are not importing it, nor we are @@ -5439,34 +5456,40 @@ int verifyClusterConfigWithData(void) { update_config++; /* slot is unassigned. Take responsibility for it. */ if (server.cluster->slots[j] == NULL) { - serverLog(LL_NOTICE, "I have keys for unassigned slot %d. " - "Taking responsibility for it.",j); - clusterAddSlot(myself,j); + serverLog(LL_NOTICE, + "I have keys for unassigned slot %d. " + "Taking responsibility for it.", + j); + clusterAddSlot(myself, j); } else if (server.cluster->importing_slots_from[j] != server.cluster->slots[j]) { if (server.cluster->importing_slots_from[j] == NULL) { - serverLog(LL_NOTICE, "I have keys for slot %d, but the slot is " - "assigned to another node. Deleting keys in the slot.", j); + serverLog(LL_NOTICE, + "I have keys for slot %d, but the slot is " + "assigned to another node. Deleting keys in the slot.", + j); } else { - serverLog(LL_NOTICE, "I am importing keys from node %.40s (%s) in shard %.40s to slot %d, " - "but the slot is now owned by node %.40s (%s) in shard %.40s. Deleting keys in the slot", - server.cluster->importing_slots_from[j]->name, - server.cluster->importing_slots_from[j]->human_nodename, - server.cluster->importing_slots_from[j]->shard_id, - j, - server.cluster->slots[j]->name, - server.cluster->slots[j]->human_nodename, - server.cluster->slots[j]->shard_id); + serverLog(LL_NOTICE, + "I am importing keys from node %.40s (%s) in shard %.40s to slot %d, " + "but the slot is now owned by node %.40s (%s) in shard %.40s. Deleting keys in the slot", + server.cluster->importing_slots_from[j]->name, + server.cluster->importing_slots_from[j]->human_nodename, + server.cluster->importing_slots_from[j]->shard_id, j, server.cluster->slots[j]->name, + server.cluster->slots[j]->human_nodename, server.cluster->slots[j]->shard_id); } delKeysInSlot(j); } } - if (update_config) clusterSaveConfigOrDie(1); + if (update_config) { + clusterSaveConfigOrDie(1); + } return C_OK; } /* Remove all the shard channel related information not owned by the current shard. */ static inline void removeAllNotOwnedShardChannelSubscriptions(void) { - if (!kvstoreSize(server.pubsubshard_channels)) return; + if (!kvstoreSize(server.pubsubshard_channels)) { + return; + } clusterNode *currmaster = clusterNodeIsMaster(myself) ? myself : myself->slaveof; for (int j = 0; j < CLUSTER_SLOTS; j++) { if (server.cluster->slots[j] != currmaster) { @@ -5486,16 +5509,19 @@ void clusterSetMaster(clusterNode *n, int closeSlots) { serverAssert(myself->numslots == 0); if (clusterNodeIsMaster(myself)) { - myself->flags &= ~(CLUSTER_NODE_MASTER|CLUSTER_NODE_MIGRATE_TO); + myself->flags &= ~(CLUSTER_NODE_MASTER | CLUSTER_NODE_MIGRATE_TO); myself->flags |= CLUSTER_NODE_SLAVE; } else { - if (myself->slaveof) - clusterNodeRemoveSlave(myself->slaveof,myself); + if (myself->slaveof) { + clusterNodeRemoveSlave(myself->slaveof, myself); + } + } + if (closeSlots) { + clusterCloseAllSlots(); } - if (closeSlots) clusterCloseAllSlots(); myself->slaveof = n; updateShardId(myself, n->shard_id); - clusterNodeAddSlave(n,myself); + clusterNodeAddSlave(n, myself); replicationSetMaster(n->ip, getNodeDefaultReplicationPort(n)); removeAllNotOwnedShardChannelSubscriptions(); resetManualFailover(); @@ -5511,28 +5537,27 @@ struct clusterNodeFlags { }; static struct clusterNodeFlags clusterNodeFlagsTable[] = { - {CLUSTER_NODE_MYSELF, "myself,"}, - {CLUSTER_NODE_MASTER, "master,"}, - {CLUSTER_NODE_SLAVE, "slave,"}, - {CLUSTER_NODE_PFAIL, "fail?,"}, - {CLUSTER_NODE_FAIL, "fail,"}, - {CLUSTER_NODE_HANDSHAKE, "handshake,"}, - {CLUSTER_NODE_NOADDR, "noaddr,"}, - {CLUSTER_NODE_NOFAILOVER, "nofailover,"} -}; + {CLUSTER_NODE_MYSELF, "myself,"}, {CLUSTER_NODE_MASTER, "master,"}, + {CLUSTER_NODE_SLAVE, "slave,"}, {CLUSTER_NODE_PFAIL, "fail?,"}, + {CLUSTER_NODE_FAIL, "fail,"}, {CLUSTER_NODE_HANDSHAKE, "handshake,"}, + {CLUSTER_NODE_NOADDR, "noaddr,"}, {CLUSTER_NODE_NOFAILOVER, "nofailover,"}}; /* Concatenate the comma separated list of node flags to the given SDS * string 'ci'. */ sds representClusterNodeFlags(sds ci, uint16_t flags) { size_t orig_len = sdslen(ci); - int i, size = sizeof(clusterNodeFlagsTable)/sizeof(struct clusterNodeFlags); + int i, size = sizeof(clusterNodeFlagsTable) / sizeof(struct clusterNodeFlags); for (i = 0; i < size; i++) { struct clusterNodeFlags *nodeflag = clusterNodeFlagsTable + i; - if (flags & nodeflag->flag) ci = sdscat(ci, nodeflag->name); + if (flags & nodeflag->flag) { + ci = sdscat(ci, nodeflag->name); + } } /* If no flag was added, add the "noflags" special flag. */ - if (sdslen(ci) == orig_len) ci = sdscat(ci,"noflags,"); - sdsIncrLen(ci,-1); /* Remove trailing comma. */ + if (sdslen(ci) == orig_len) { + ci = sdscat(ci, "noflags,"); + } + sdsIncrLen(ci, -1); /* Remove trailing comma. */ return ci; } @@ -5540,9 +5565,9 @@ sds representClusterNodeFlags(sds ci, uint16_t flags) { * If the slot ownership is in a contiguous block, it's represented as start-end pair, * else each slot is added separately. */ sds representSlotInfo(sds ci, uint16_t *slot_info_pairs, int slot_info_pairs_count) { - for (int i = 0; i< slot_info_pairs_count; i+=2) { + for (int i = 0; i < slot_info_pairs_count; i += 2) { unsigned long start = slot_info_pairs[i]; - unsigned long end = slot_info_pairs[i+1]; + unsigned long end = slot_info_pairs[i + 1]; if (start == end) { ci = sdscatfmt(ci, " %i", start); } else { @@ -5562,21 +5587,18 @@ sds clusterGenNodeDescription(client *c, clusterNode *node, int tls_primary) { int port = clusterNodeClientPort(node, tls_primary); /* Node coordinates */ - ci = sdscatlen(sdsempty(),node->name,CLUSTER_NAMELEN); - ci = sdscatfmt(ci," %s:%i@%i", - node->ip, - port, - node->cport); + ci = sdscatlen(sdsempty(), node->name, CLUSTER_NAMELEN); + ci = sdscatfmt(ci, " %s:%i@%i", node->ip, port, node->cport); if (sdslen(node->hostname) != 0) { - ci = sdscatfmt(ci,",%s", node->hostname); + ci = sdscatfmt(ci, ",%s", node->hostname); } /* Don't expose aux fields to any clients yet but do allow them * to be persisted to nodes.conf */ if (c == NULL) { if (sdslen(node->hostname) == 0) { - ci = sdscatfmt(ci,",", 1); + ci = sdscatfmt(ci, ",", 1); } - for (int i = af_count-1; i >=0; i--) { + for (int i = af_count - 1; i >= 0; i--) { if ((tls_primary && i == af_tls_port) || (!tls_primary && i == af_tcp_port)) { continue; } @@ -5588,23 +5610,20 @@ sds clusterGenNodeDescription(client *c, clusterNode *node, int tls_primary) { } /* Flags */ - ci = sdscatlen(ci," ",1); + ci = sdscatlen(ci, " ", 1); ci = representClusterNodeFlags(ci, node->flags); /* Slave of... or just "-" */ - ci = sdscatlen(ci," ",1); - if (node->slaveof) - ci = sdscatlen(ci,node->slaveof->name,CLUSTER_NAMELEN); - else - ci = sdscatlen(ci,"-",1); + ci = sdscatlen(ci, " ", 1); + if (node->slaveof) { + ci = sdscatlen(ci, node->slaveof->name, CLUSTER_NAMELEN); + } else { + ci = sdscatlen(ci, "-", 1); + } /* Latency from the POV of this node, config epoch, link status */ - ci = sdscatfmt(ci," %I %I %U %s", - (long long) node->ping_sent, - (long long) node->pong_received, - nodeEpoch(node), - (node->link || node->flags & CLUSTER_NODE_MYSELF) ? - "connected" : "disconnected"); + ci = sdscatfmt(ci, " %I %I %U %s", (long long)node->ping_sent, (long long)node->pong_received, nodeEpoch(node), + (node->link || node->flags & CLUSTER_NODE_MYSELF) ? "connected" : "disconnected"); /* Slots served by this instance. If we already have slots info, * append it directly, otherwise, generate slots only if it has. */ @@ -5616,15 +5635,19 @@ sds clusterGenNodeDescription(client *c, clusterNode *node, int tls_primary) { int bit; if ((bit = clusterNodeCoversSlot(node, j)) != 0) { - if (start == -1) start = j; + if (start == -1) { + start = j; + } } - if (start != -1 && (!bit || j == CLUSTER_SLOTS-1)) { - if (bit && j == CLUSTER_SLOTS-1) j++; + if (start != -1 && (!bit || j == CLUSTER_SLOTS - 1)) { + if (bit && j == CLUSTER_SLOTS - 1) { + j++; + } - if (start == j-1) { - ci = sdscatfmt(ci," %i",start); + if (start == j - 1) { + ci = sdscatfmt(ci, " %i", start); } else { - ci = sdscatfmt(ci," %i-%i",start,j-1); + ci = sdscatfmt(ci, " %i-%i", start, j - 1); } start = -1; } @@ -5637,11 +5660,9 @@ sds clusterGenNodeDescription(client *c, clusterNode *node, int tls_primary) { if (node->flags & CLUSTER_NODE_MYSELF) { for (j = 0; j < CLUSTER_SLOTS; j++) { if (server.cluster->migrating_slots_to[j]) { - ci = sdscatprintf(ci," [%d->-%.40s]",j, - server.cluster->migrating_slots_to[j]->name); + ci = sdscatprintf(ci, " [%d->-%.40s]", j, server.cluster->migrating_slots_to[j]->name); } else if (server.cluster->importing_slots_from[j]) { - ci = sdscatprintf(ci," [%d-<-%.40s]",j, - server.cluster->importing_slots_from[j]->name); + ci = sdscatprintf(ci, " [%d-<-%.40s]", j, server.cluster->importing_slots_from[j]->name); } } } @@ -5659,7 +5680,9 @@ void clusterGenNodesSlotsInfo(int filter) { for (int i = 0; i <= CLUSTER_SLOTS; i++) { /* Find start node and slot id. */ if (n == NULL) { - if (i == CLUSTER_SLOTS) break; + if (i == CLUSTER_SLOTS) { + break; + } n = server.cluster->slots[i]; start = i; continue; @@ -5674,9 +5697,11 @@ void clusterGenNodesSlotsInfo(int filter) { } serverAssert((n->slot_info_pairs_count + 1) < (2 * n->numslots)); n->slot_info_pairs[n->slot_info_pairs_count++] = start; - n->slot_info_pairs[n->slot_info_pairs_count++] = i-1; + n->slot_info_pairs[n->slot_info_pairs_count++] = i - 1; + } + if (i == CLUSTER_SLOTS) { + break; } - if (i == CLUSTER_SLOTS) break; n = server.cluster->slots[i]; start = i; } @@ -5698,7 +5723,7 @@ void clusterFreeNodesSlotsInfo(clusterNode *n) { * include all the known nodes in the representation, including nodes in * the HANDSHAKE state. * - * Setting tls_primary to 1 to put TLS port in the main : + * Setting tls_primary to 1 to put TLS port in the main : * field and put TCP port in aux field, instead of the opposite way. * * The representation obtained using this function is used for the output @@ -5713,14 +5738,16 @@ sds clusterGenNodesDescription(client *c, int filter, int tls_primary) { clusterGenNodesSlotsInfo(filter); di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); - if (node->flags & filter) continue; + if (node->flags & filter) { + continue; + } ni = clusterGenNodeDescription(c, node, tls_primary); - ci = sdscatsds(ci,ni); + ci = sdscatsds(ci, ni); sdsfree(ni); - ci = sdscatlen(ci,"\n",1); + ci = sdscatlen(ci, "\n", 1); /* Release slots info. */ clusterFreeNodesSlotsInfo(node); @@ -5752,8 +5779,12 @@ void addReplyClusterLinkDescription(client *c, clusterLink *link) { char events[3], *p; p = events; if (link->conn) { - if (connHasReadHandler(link->conn)) *p++ = 'r'; - if (connHasWriteHandler(link->conn)) *p++ = 'w'; + if (connHasReadHandler(link->conn)) { + *p++ = 'r'; + } + if (connHasWriteHandler(link->conn)) { + *p++ = 'w'; + } } *p = '\0'; addReplyBulkCString(c, "events"); @@ -5777,7 +5808,7 @@ void addReplyClusterLinksDescription(client *c) { arraylen_ptr = addReplyDeferredLen(c); di = dictGetSafeIterator(server.cluster->nodes); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); if (node->link) { num_links++; @@ -5798,18 +5829,29 @@ void addReplyClusterLinksDescription(client *c) { * -------------------------------------------------------------------------- */ const char *clusterGetMessageTypeString(int type) { - switch(type) { - case CLUSTERMSG_TYPE_PING: return "ping"; - case CLUSTERMSG_TYPE_PONG: return "pong"; - case CLUSTERMSG_TYPE_MEET: return "meet"; - case CLUSTERMSG_TYPE_FAIL: return "fail"; - case CLUSTERMSG_TYPE_PUBLISH: return "publish"; - case CLUSTERMSG_TYPE_PUBLISHSHARD: return "publishshard"; - case CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST: return "auth-req"; - case CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK: return "auth-ack"; - case CLUSTERMSG_TYPE_UPDATE: return "update"; - case CLUSTERMSG_TYPE_MFSTART: return "mfstart"; - case CLUSTERMSG_TYPE_MODULE: return "module"; + switch (type) { + case CLUSTERMSG_TYPE_PING: + return "ping"; + case CLUSTERMSG_TYPE_PONG: + return "pong"; + case CLUSTERMSG_TYPE_MEET: + return "meet"; + case CLUSTERMSG_TYPE_FAIL: + return "fail"; + case CLUSTERMSG_TYPE_PUBLISH: + return "publish"; + case CLUSTERMSG_TYPE_PUBLISHSHARD: + return "publishshard"; + case CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST: + return "auth-req"; + case CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK: + return "auth-ack"; + case CLUSTERMSG_TYPE_UPDATE: + return "update"; + case CLUSTERMSG_TYPE_MFSTART: + return "mfstart"; + case CLUSTERMSG_TYPE_MODULE: + return "module"; } return "unknown"; } @@ -5817,27 +5859,25 @@ const char *clusterGetMessageTypeString(int type) { int getSlotOrReply(client *c, robj *o) { long long slot; - if (getLongLongFromObject(o,&slot) != C_OK || - slot < 0 || slot >= CLUSTER_SLOTS) - { - addReplyError(c,"Invalid or out of range slot"); + if (getLongLongFromObject(o, &slot) != C_OK || slot < 0 || slot >= CLUSTER_SLOTS) { + addReplyError(c, "Invalid or out of range slot"); return -1; } - return (int) slot; + return (int)slot; } int checkSlotAssignmentsOrReply(client *c, unsigned char *slots, int del, int start_slot, int end_slot) { int slot; for (slot = start_slot; slot <= end_slot; slot++) { if (del && server.cluster->slots[slot] == NULL) { - addReplyErrorFormat(c,"Slot %d is already unassigned", slot); + addReplyErrorFormat(c, "Slot %d is already unassigned", slot); return C_ERR; } else if (!del && server.cluster->slots[slot]) { - addReplyErrorFormat(c,"Slot %d is already busy", slot); + addReplyErrorFormat(c, "Slot %d is already busy", slot); return C_ERR; } if (slots[slot]++ == 1) { - addReplyErrorFormat(c,"Slot %d specified multiple times",(int)slot); + addReplyErrorFormat(c, "Slot %d specified multiple times", (int)slot); return C_ERR; } } @@ -5849,15 +5889,15 @@ void clusterUpdateSlots(client *c, unsigned char *slots, int del) { for (j = 0; j < CLUSTER_SLOTS; j++) { if (slots[j]) { int retval; - + /* If this slot was set as importing we can clear this * state as now we are the real owner of the slot. */ - if (server.cluster->importing_slots_from[j]) + if (server.cluster->importing_slots_from[j]) { server.cluster->importing_slots_from[j] = NULL; + } - retval = del ? clusterDelSlot(j) : - clusterAddSlot(myself,j); - serverAssertWithInfo(c,NULL,retval == C_OK); + retval = del ? clusterDelSlot(j) : clusterAddSlot(myself, j); + serverAssertWithInfo(c, NULL, retval == C_OK); } } } @@ -5939,8 +5979,9 @@ void addShardReplyForClusterShards(client *c, list *nodes) { if (n->slot_info_pairs != NULL) { serverAssert((n->slot_info_pairs_count % 2) == 0); addReplyArrayLen(c, n->slot_info_pairs_count); - for (int i = 0; i < n->slot_info_pairs_count; i++) + for (int i = 0; i < n->slot_info_pairs_count; i++) { addReplyLongLong(c, (unsigned long)n->slot_info_pairs[i]); + } } else { /* If no slot info pair is provided, the node owns no slots */ addReplyArrayLen(c, 0); @@ -5965,7 +6006,7 @@ void clusterCommandShards(client *c) { /* This call will add slot_info_pairs to all nodes */ clusterGenNodesSlotsInfo(0); dictIterator *di = dictGetSafeIterator(server.cluster->shards); - for(dictEntry *de = dictNext(di); de != NULL; de = dictNext(di)) { + for (dictEntry *de = dictNext(di); de != NULL; de = dictNext(di)) { addShardReplyForClusterShards(c, dictGetVal(de)); } dictReleaseIterator(di); @@ -5973,14 +6014,16 @@ void clusterCommandShards(client *c) { sds genClusterInfoString(void) { sds info = sdsempty(); - char *statestr[] = {"ok","fail"}; + char *statestr[] = {"ok", "fail"}; int slots_assigned = 0, slots_ok = 0, slots_pfail = 0, slots_fail = 0; int j; for (j = 0; j < CLUSTER_SLOTS; j++) { clusterNode *n = server.cluster->slots[j]; - if (n == NULL) continue; + if (n == NULL) { + continue; + } slots_assigned++; if (nodeFailed(n)) { slots_fail++; @@ -5992,62 +6035,54 @@ sds genClusterInfoString(void) { } info = sdscatprintf(info, - "cluster_state:%s\r\n" - "cluster_slots_assigned:%d\r\n" - "cluster_slots_ok:%d\r\n" - "cluster_slots_pfail:%d\r\n" - "cluster_slots_fail:%d\r\n" - "cluster_known_nodes:%lu\r\n" - "cluster_size:%d\r\n" - "cluster_current_epoch:%llu\r\n" - "cluster_my_epoch:%llu\r\n" - , statestr[server.cluster->state], - slots_assigned, - slots_ok, - slots_pfail, - slots_fail, - dictSize(server.cluster->nodes), - server.cluster->size, - (unsigned long long) server.cluster->currentEpoch, - (unsigned long long) nodeEpoch(myself) - ); + "cluster_state:%s\r\n" + "cluster_slots_assigned:%d\r\n" + "cluster_slots_ok:%d\r\n" + "cluster_slots_pfail:%d\r\n" + "cluster_slots_fail:%d\r\n" + "cluster_known_nodes:%lu\r\n" + "cluster_size:%d\r\n" + "cluster_current_epoch:%llu\r\n" + "cluster_my_epoch:%llu\r\n", + statestr[server.cluster->state], slots_assigned, slots_ok, slots_pfail, slots_fail, + dictSize(server.cluster->nodes), server.cluster->size, + (unsigned long long)server.cluster->currentEpoch, (unsigned long long)nodeEpoch(myself)); /* Show stats about messages sent and received. */ long long tot_msg_sent = 0; long long tot_msg_received = 0; for (int i = 0; i < CLUSTERMSG_TYPE_COUNT; i++) { - if (server.cluster->stats_bus_messages_sent[i] == 0) continue; + if (server.cluster->stats_bus_messages_sent[i] == 0) { + continue; + } tot_msg_sent += server.cluster->stats_bus_messages_sent[i]; - info = sdscatprintf(info, - "cluster_stats_messages_%s_sent:%lld\r\n", - clusterGetMessageTypeString(i), - server.cluster->stats_bus_messages_sent[i]); + info = sdscatprintf(info, "cluster_stats_messages_%s_sent:%lld\r\n", clusterGetMessageTypeString(i), + server.cluster->stats_bus_messages_sent[i]); } - info = sdscatprintf(info, - "cluster_stats_messages_sent:%lld\r\n", tot_msg_sent); + info = sdscatprintf(info, "cluster_stats_messages_sent:%lld\r\n", tot_msg_sent); for (int i = 0; i < CLUSTERMSG_TYPE_COUNT; i++) { - if (server.cluster->stats_bus_messages_received[i] == 0) continue; + if (server.cluster->stats_bus_messages_received[i] == 0) { + continue; + } tot_msg_received += server.cluster->stats_bus_messages_received[i]; - info = sdscatprintf(info, - "cluster_stats_messages_%s_received:%lld\r\n", - clusterGetMessageTypeString(i), - server.cluster->stats_bus_messages_received[i]); + info = sdscatprintf(info, "cluster_stats_messages_%s_received:%lld\r\n", clusterGetMessageTypeString(i), + server.cluster->stats_bus_messages_received[i]); } - info = sdscatprintf(info, - "cluster_stats_messages_received:%lld\r\n", tot_msg_received); + info = sdscatprintf(info, "cluster_stats_messages_received:%lld\r\n", tot_msg_received); - info = sdscatprintf(info, - "total_cluster_links_buffer_limit_exceeded:%llu\r\n", - server.cluster->stat_cluster_links_buffer_limit_exceeded); + info = sdscatprintf(info, "total_cluster_links_buffer_limit_exceeded:%llu\r\n", + server.cluster->stat_cluster_links_buffer_limit_exceeded); return info; } void removeChannelsInSlot(unsigned int slot) { - if (countChannelsInSlot(slot) == 0) return; + if (countChannelsInSlot(slot) == 0) { + return; + } pubsubShardUnsubscribeAllChannelsInSlot(slot); } @@ -6055,15 +6090,16 @@ void removeChannelsInSlot(unsigned int slot) { /* Remove all the keys in the specified hash slot. * The number of removed items is returned. */ unsigned int delKeysInSlot(unsigned int hashslot) { - if (!kvstoreDictSize(server.db->keys, hashslot)) + if (!kvstoreDictSize(server.db->keys, hashslot)) { return 0; + } unsigned int j = 0; kvstoreDictIterator *kvs_di = NULL; dictEntry *de = NULL; kvs_di = kvstoreGetDictSafeIterator(server.db->keys, hashslot); - while((de = kvstoreDictIteratorNext(kvs_di)) != NULL) { + while ((de = kvstoreDictIteratorNext(kvs_di)) != NULL) { enterExecutionUnit(1, 0); sds sdskey = dictGetKey(de); robj *key = createStringObject(sdskey, sdslen(sdskey)); @@ -6118,15 +6154,17 @@ int getMyShardSlotCount(void) { char **getClusterNodesList(size_t *numnodes) { size_t count = dictSize(server.cluster->nodes); - char **ids = zmalloc((count+1)*CLUSTER_NAMELEN); + char **ids = zmalloc((count + 1) * CLUSTER_NAMELEN); dictIterator *di = dictGetIterator(server.cluster->nodes); dictEntry *de; int j = 0; - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de); - if (node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE)) continue; + if (node->flags & (CLUSTER_NODE_NOADDR | CLUSTER_NODE_HANDSHAKE)) { + continue; + } ids[j] = zmalloc(CLUSTER_NAMELEN); - memcpy(ids[j],node->name,CLUSTER_NAMELEN); + memcpy(ids[j], node->name, CLUSTER_NAMELEN); j++; } *numnodes = j; @@ -6141,9 +6179,7 @@ int clusterNodeIsMaster(clusterNode *n) { } int handleDebugClusterCommand(client *c) { - if (strcasecmp(c->argv[1]->ptr, "CLUSTERLINK") || - strcasecmp(c->argv[2]->ptr, "KILL") || - c->argc != 5) { + if (strcasecmp(c->argv[1]->ptr, "CLUSTERLINK") || strcasecmp(c->argv[2]->ptr, "KILL") || c->argc != 5) { return 0; } @@ -6155,28 +6191,36 @@ int handleDebugClusterCommand(client *c) { /* Find the node. */ clusterNode *n = clusterLookupNode(c->argv[4]->ptr, sdslen(c->argv[4]->ptr)); if (!n) { - addReplyErrorFormat(c, "Unknown node %s", (char *) c->argv[4]->ptr); + addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[4]->ptr); return 1; } /* Terminate the link based on the direction or all. */ if (!strcasecmp(c->argv[3]->ptr, "from")) { - if (n->inbound_link) freeClusterLink(n->inbound_link); + if (n->inbound_link) { + freeClusterLink(n->inbound_link); + } } else if (!strcasecmp(c->argv[3]->ptr, "to")) { - if (n->link) freeClusterLink(n->link); + if (n->link) { + freeClusterLink(n->link); + } } else if (!strcasecmp(c->argv[3]->ptr, "all")) { - if (n->link) freeClusterLink(n->link); - if (n->inbound_link) freeClusterLink(n->inbound_link); + if (n->link) { + freeClusterLink(n->link); + } + if (n->inbound_link) { + freeClusterLink(n->inbound_link); + } } else { - addReplyErrorFormat(c, "Unknown direction %s", (char *) c->argv[3]->ptr); + addReplyErrorFormat(c, "Unknown direction %s", (char *)c->argv[3]->ptr); } addReply(c, shared.ok); return 1; } -int clusterNodePending(clusterNode *node) { - return node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE); +int clusterNodePending(clusterNode *node) { + return node->flags & (CLUSTER_NODE_NOADDR | CLUSTER_NODE_HANDSHAKE); } char *clusterNodeIp(clusterNode *node) { @@ -6192,7 +6236,9 @@ clusterNode *clusterNodeGetSlaveof(clusterNode *node) { } clusterNode *clusterNodeGetMaster(clusterNode *node) { - while (node->slaveof != NULL) node = node->slaveof; + while (node->slaveof != NULL) { + node = node->slaveof; + } return node; } @@ -6213,11 +6259,9 @@ int clusterNodeIsNoFailover(clusterNode *node) { } const char **clusterDebugCommandExtendedHelp(void) { - static const char *help[] = { - "CLUSTERLINK KILL ", - " Kills the link based on the direction to/from (both) with the provided node.", - NULL - }; + static const char *help[] = {"CLUSTERLINK KILL ", + " Kills the link based on the direction to/from (both) with the provided node.", + NULL}; return help; } @@ -6233,69 +6277,71 @@ int clusterParseSetSlotCommand(client *c, int *slot_out, clusterNode **node_out, /* Allow primaries to replicate "CLUSTER SETSLOT" */ if (!(c->flags & CLIENT_MASTER) && nodeIsSlave(myself)) { - addReplyError(c,"Please use SETSLOT only with masters."); + addReplyError(c, "Please use SETSLOT only with masters."); return 0; } /* Process optional arguments */ for (int i = 0; i < c->argc;) { - if (!strcasecmp(c->argv[i]->ptr, "timeout")) { - if(i+1 < c->argc) { - timeout = (int)strtol(c->argv[i+1]->ptr, NULL, 10); - decrRefCount(c->argv[i]); - decrRefCount(c->argv[i+1]); - memmove(&c->argv[i], &c->argv[i+2], c->argc-i-2); - c->argc -= 2; - continue; - } - addReplyError(c, "Missing timeout value."); - return 0; - } - i++; - } - - if ((slot = getSlotOrReply(c, c->argv[2])) == -1) return 0; - - if (!strcasecmp(c->argv[3]->ptr,"migrating") && c->argc >= 5) { + if (!strcasecmp(c->argv[i]->ptr, "timeout")) { + if (i + 1 < c->argc) { + timeout = (int)strtol(c->argv[i + 1]->ptr, NULL, 10); + decrRefCount(c->argv[i]); + decrRefCount(c->argv[i + 1]); + memmove(&c->argv[i], &c->argv[i + 2], c->argc - i - 2); + c->argc -= 2; + continue; + } + addReplyError(c, "Missing timeout value."); + return 0; + } + i++; + } + + if ((slot = getSlotOrReply(c, c->argv[2])) == -1) { + return 0; + } + + if (!strcasecmp(c->argv[3]->ptr, "migrating") && c->argc >= 5) { /* Scope the check to primaries only */ if (nodeIsMaster(myself) && server.cluster->slots[slot] != myself) { - addReplyErrorFormat(c,"I'm not the owner of hash slot %u", slot); + addReplyErrorFormat(c, "I'm not the owner of hash slot %u", slot); return 0; } n = clusterLookupNode(c->argv[4]->ptr, sdslen(c->argv[4]->ptr)); if (n == NULL) { - addReplyErrorFormat(c,"I don't know about node %s", (char*)c->argv[4]->ptr); + addReplyErrorFormat(c, "I don't know about node %s", (char *)c->argv[4]->ptr); return 0; } if (nodeIsSlave(n)) { - addReplyError(c,"Target node is not a master"); + addReplyError(c, "Target node is not a master"); return 0; } - } else if (!strcasecmp(c->argv[3]->ptr,"importing") && c->argc >= 5) { + } else if (!strcasecmp(c->argv[3]->ptr, "importing") && c->argc >= 5) { if (server.cluster->slots[slot] == myself) { addReplyErrorFormat(c, "I'm already the owner of hash slot %u", slot); return 0; } n = clusterLookupNode(c->argv[4]->ptr, sdslen(c->argv[4]->ptr)); if (n == NULL) { - addReplyErrorFormat(c,"I don't know about node %s", (char*)c->argv[4]->ptr); + addReplyErrorFormat(c, "I don't know about node %s", (char *)c->argv[4]->ptr); return 0; } if (nodeIsSlave(n)) { - addReplyError(c,"Target node is not a master"); + addReplyError(c, "Target node is not a master"); return 0; } - } else if (!strcasecmp(c->argv[3]->ptr,"stable") && c->argc >= 4) { + } else if (!strcasecmp(c->argv[3]->ptr, "stable") && c->argc >= 4) { /* Do nothing */ - } else if (!strcasecmp(c->argv[3]->ptr,"node") && c->argc >= 5) { + } else if (!strcasecmp(c->argv[3]->ptr, "node") && c->argc >= 5) { /* CLUSTER SETSLOT NODE */ n = clusterLookupNode(c->argv[4]->ptr, sdslen(c->argv[4]->ptr)); if (!n) { - addReplyErrorFormat(c,"Unknown node %s", (char*)c->argv[4]->ptr); + addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[4]->ptr); return 0; } if (nodeIsSlave(n)) { - addReplyError(c,"Target node is not a master"); + addReplyError(c, "Target node is not a master"); return 0; } /* If this hash slot was served by 'myself' before to switch @@ -6303,14 +6349,14 @@ int clusterParseSetSlotCommand(client *c, int *slot_out, clusterNode **node_out, if (server.cluster->slots[slot] == myself && n != myself) { if (countKeysInSlot(slot) != 0) { addReplyErrorFormat(c, - "Can't assign hashslot %d to a different node " - "while I still hold keys for this hash slot.", slot); + "Can't assign hashslot %d to a different node " + "while I still hold keys for this hash slot.", + slot); return 0; } } } else { - addReplyError(c, - "Invalid CLUSTER SETSLOT action or number of arguments. Try CLUSTER HELP"); + addReplyError(c, "Invalid CLUSTER SETSLOT action or number of arguments. Try CLUSTER HELP"); return 0; } @@ -6325,7 +6371,9 @@ void clusterSetSlotCommand(client *c) { int timeout_ms; clusterNode *n; - if (!clusterParseSetSlotCommand(c, &slot, &n, &timeout_ms)) return; + if (!clusterParseSetSlotCommand(c, &slot, &n, &timeout_ms)) { + return; + } /* Enhance cluster topology change resilience against primary failures by * replicating SETSLOT before execution. @@ -6370,39 +6418,28 @@ void clusterSetSlotCommand(client *c) { if (timeout_ms == 0) { timeout_ms = CLUSTER_OPERATION_TIMEOUT; } - blockForPreReplication(c, mstime()+timeout_ms, server.master_repl_offset+1, myself->numslaves); + blockForPreReplication(c, mstime() + timeout_ms, server.master_repl_offset + 1, myself->numslaves); replicationRequestAckFromSlaves(); return; } /* Slot states have been updated on the replicas (if any). * Now exuecte the command on the primary. */ - if (!strcasecmp(c->argv[3]->ptr,"migrating")) { - serverLog(LL_NOTICE, - "Migrating slot %d to node %.40s (%s)", - slot, - n->name, - n->human_nodename); + if (!strcasecmp(c->argv[3]->ptr, "migrating")) { + serverLog(LL_NOTICE, "Migrating slot %d to node %.40s (%s)", slot, n->name, n->human_nodename); server.cluster->migrating_slots_to[slot] = n; - } else if (!strcasecmp(c->argv[3]->ptr,"importing")) { - serverLog(LL_NOTICE, - "Importing slot %d from node %.40s (%s)", - slot, - n->name, - n->human_nodename); + } else if (!strcasecmp(c->argv[3]->ptr, "importing")) { + serverLog(LL_NOTICE, "Importing slot %d from node %.40s (%s)", slot, n->name, n->human_nodename); server.cluster->importing_slots_from[slot] = n; - } else if (!strcasecmp(c->argv[3]->ptr,"stable")) { + } else if (!strcasecmp(c->argv[3]->ptr, "stable")) { /* CLUSTER SETSLOT STABLE */ serverLog(LL_NOTICE, "Marking slot %d stable", slot); server.cluster->importing_slots_from[slot] = NULL; server.cluster->migrating_slots_to[slot] = NULL; - } else if (!strcasecmp(c->argv[3]->ptr,"node")) { + } else if (!strcasecmp(c->argv[3]->ptr, "node")) { /* CLUSTER SETSLOT NODE */ - serverLog(LL_NOTICE, "Assigning slot %d to node %.40s (%s) in shard %.40s", - slot, - n->name, - n->human_nodename, - n->shard_id); + serverLog(LL_NOTICE, "Assigning slot %d to node %.40s (%s) in shard %.40s", slot, n->name, n->human_nodename, + n->shard_id); /* If this slot is in migrating status but we have no keys * for it assigning the slot to another node will clear @@ -6417,20 +6454,13 @@ void clusterSetSlotCommand(client *c) { /* If we are a master left without slots, we should turn into a * replica of the new master. */ - if (slot_was_mine && - n != myself && - myself->numslots == 0 && - server.cluster_allow_replica_migration) { + if (slot_was_mine && n != myself && myself->numslots == 0 && server.cluster_allow_replica_migration) { serverLog(LL_NOTICE, - "Lost my last slot during slot migration. Reconfiguring myself " - "as a replica of %.40s (%s) in shard %.40s", - n->name, - n->human_nodename, - n->shard_id); + "Lost my last slot during slot migration. Reconfiguring myself " + "as a replica of %.40s (%s) in shard %.40s", + n->name, n->human_nodename, n->shard_id); clusterSetMaster(n, 1); - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | - CLUSTER_TODO_UPDATE_STATE | - CLUSTER_TODO_FSYNC_CONFIG); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_FSYNC_CONFIG); } /* If this node or this node's primary was importing this slot, @@ -6450,9 +6480,7 @@ void clusterSetSlotCommand(client *c) { * configEpoch collision resolution will fix it assigning * a different epoch to each node. */ if (clusterBumpConfigEpochWithoutConsensus() == C_OK) { - serverLog(LL_NOTICE, - "ConfigEpoch updated after importing slot %d", - slot); + serverLog(LL_NOTICE, "ConfigEpoch updated after importing slot %d", slot); } /* After importing this slot, let the other nodes know as * soon as possible. */ @@ -6461,67 +6489,62 @@ void clusterSetSlotCommand(client *c) { } } - clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_UPDATE_STATE); - addReply(c,shared.ok); + clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE); + addReply(c, shared.ok); } int clusterCommandSpecial(client *c) { - if (!strcasecmp(c->argv[1]->ptr,"meet") && (c->argc == 4 || c->argc == 5)) { + if (!strcasecmp(c->argv[1]->ptr, "meet") && (c->argc == 4 || c->argc == 5)) { /* CLUSTER MEET [cport] */ long long port, cport; if (getLongLongFromObject(c->argv[3], &port) != C_OK) { - addReplyErrorFormat(c,"Invalid base port specified: %s", - (char*)c->argv[3]->ptr); + addReplyErrorFormat(c, "Invalid base port specified: %s", (char *)c->argv[3]->ptr); return 1; } if (c->argc == 5) { if (getLongLongFromObject(c->argv[4], &cport) != C_OK) { - addReplyErrorFormat(c,"Invalid bus port specified: %s", - (char*)c->argv[4]->ptr); + addReplyErrorFormat(c, "Invalid bus port specified: %s", (char *)c->argv[4]->ptr); return 1; } } else { cport = port + CLUSTER_PORT_INCR; } - if (clusterStartHandshake(c->argv[2]->ptr,port,cport) == 0 && - errno == EINVAL) - { - addReplyErrorFormat(c,"Invalid node address specified: %s:%s", - (char*)c->argv[2]->ptr, (char*)c->argv[3]->ptr); + if (clusterStartHandshake(c->argv[2]->ptr, port, cport) == 0 && errno == EINVAL) { + addReplyErrorFormat(c, "Invalid node address specified: %s:%s", (char *)c->argv[2]->ptr, + (char *)c->argv[3]->ptr); } else { - addReply(c,shared.ok); + addReply(c, shared.ok); } - } else if (!strcasecmp(c->argv[1]->ptr,"flushslots") && c->argc == 2) { + } else if (!strcasecmp(c->argv[1]->ptr, "flushslots") && c->argc == 2) { /* CLUSTER FLUSHSLOTS */ if (kvstoreSize(server.db[0].keys) != 0) { - addReplyError(c,"DB must be empty to perform CLUSTER FLUSHSLOTS."); + addReplyError(c, "DB must be empty to perform CLUSTER FLUSHSLOTS."); return 1; } clusterDelNodeSlots(myself); - clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); - addReply(c,shared.ok); - } else if ((!strcasecmp(c->argv[1]->ptr,"addslots") || - !strcasecmp(c->argv[1]->ptr,"delslots")) && c->argc >= 3) { + clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); + addReply(c, shared.ok); + } else if ((!strcasecmp(c->argv[1]->ptr, "addslots") || !strcasecmp(c->argv[1]->ptr, "delslots")) && c->argc >= 3) { /* CLUSTER ADDSLOTS [slot] ... */ /* CLUSTER DELSLOTS [slot] ... */ int j, slot; unsigned char *slots = zmalloc(CLUSTER_SLOTS); - int del = !strcasecmp(c->argv[1]->ptr,"delslots"); + int del = !strcasecmp(c->argv[1]->ptr, "delslots"); - memset(slots,0,CLUSTER_SLOTS); + memset(slots, 0, CLUSTER_SLOTS); /* Check that all the arguments are parseable.*/ for (j = 2; j < c->argc; j++) { - if ((slot = getSlotOrReply(c,c->argv[j])) == C_ERR) { + if ((slot = getSlotOrReply(c, c->argv[j])) == C_ERR) { zfree(slots); return 1; } } /* Check that the slots are not already busy. */ for (j = 2; j < c->argc; j++) { - slot = getSlotOrReply(c,c->argv[j]); + slot = getSlotOrReply(c, c->argv[j]); if (checkSlotAssignmentsOrReply(c, slots, del, slot, slot) == C_ERR) { zfree(slots); return 1; @@ -6529,10 +6552,10 @@ int clusterCommandSpecial(client *c) { } clusterUpdateSlots(c, slots, del); zfree(slots); - clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); - addReply(c,shared.ok); - } else if ((!strcasecmp(c->argv[1]->ptr,"addslotsrange") || - !strcasecmp(c->argv[1]->ptr,"delslotsrange")) && c->argc >= 4) { + clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); + addReply(c, shared.ok); + } else if ((!strcasecmp(c->argv[1]->ptr, "addslotsrange") || !strcasecmp(c->argv[1]->ptr, "delslotsrange")) && + c->argc >= 4) { if (c->argc % 2 == 1) { addReplyErrorArity(c); return 1; @@ -6541,22 +6564,22 @@ int clusterCommandSpecial(client *c) { /* CLUSTER DELSLOTSRANGE [ ...] */ int j, startslot, endslot; unsigned char *slots = zmalloc(CLUSTER_SLOTS); - int del = !strcasecmp(c->argv[1]->ptr,"delslotsrange"); + int del = !strcasecmp(c->argv[1]->ptr, "delslotsrange"); - memset(slots,0,CLUSTER_SLOTS); + memset(slots, 0, CLUSTER_SLOTS); /* Check that all the arguments are parseable and that all the * slots are not already busy. */ for (j = 2; j < c->argc; j += 2) { - if ((startslot = getSlotOrReply(c,c->argv[j])) == C_ERR) { + if ((startslot = getSlotOrReply(c, c->argv[j])) == C_ERR) { zfree(slots); return 1; } - if ((endslot = getSlotOrReply(c,c->argv[j+1])) == C_ERR) { + if ((endslot = getSlotOrReply(c, c->argv[j + 1])) == C_ERR) { zfree(slots); return 1; } if (startslot > endslot) { - addReplyErrorFormat(c,"start slot number %d is greater than end slot number %d", startslot, endslot); + addReplyErrorFormat(c, "start slot number %d is greater than end slot number %d", startslot, endslot); zfree(slots); return 1; } @@ -6568,132 +6591,122 @@ int clusterCommandSpecial(client *c) { } clusterUpdateSlots(c, slots, del); zfree(slots); - clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); - addReply(c,shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr,"setslot") && c->argc >= 4) { + clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); + addReply(c, shared.ok); + } else if (!strcasecmp(c->argv[1]->ptr, "setslot") && c->argc >= 4) { /* SETSLOT 10 MIGRATING */ /* SETSLOT 10 IMPORTING */ /* SETSLOT 10 STABLE */ /* SETSLOT 10 NODE */ clusterSetSlotCommand(c); - } else if (!strcasecmp(c->argv[1]->ptr,"bumpepoch") && c->argc == 2) { + } else if (!strcasecmp(c->argv[1]->ptr, "bumpepoch") && c->argc == 2) { /* CLUSTER BUMPEPOCH */ int retval = clusterBumpConfigEpochWithoutConsensus(); - sds reply = sdscatprintf(sdsempty(),"+%s %llu\r\n", - (retval == C_OK) ? "BUMPED" : "STILL", - (unsigned long long) myself->configEpoch); - addReplySds(c,reply); - } else if (!strcasecmp(c->argv[1]->ptr,"saveconfig") && c->argc == 2) { + sds reply = sdscatprintf(sdsempty(), "+%s %llu\r\n", (retval == C_OK) ? "BUMPED" : "STILL", + (unsigned long long)myself->configEpoch); + addReplySds(c, reply); + } else if (!strcasecmp(c->argv[1]->ptr, "saveconfig") && c->argc == 2) { int retval = clusterSaveConfig(1); - if (retval == 0) - addReply(c,shared.ok); - else - addReplyErrorFormat(c,"error saving the cluster node config: %s", - strerror(errno)); - } else if (!strcasecmp(c->argv[1]->ptr,"forget") && c->argc == 3) { + if (retval == 0) { + addReply(c, shared.ok); + } else { + addReplyErrorFormat(c, "error saving the cluster node config: %s", strerror(errno)); + } + } else if (!strcasecmp(c->argv[1]->ptr, "forget") && c->argc == 3) { /* CLUSTER FORGET */ clusterNode *n = clusterLookupNode(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); if (!n) { - if (clusterBlacklistExists((char*)c->argv[2]->ptr)) + if (clusterBlacklistExists((char *)c->argv[2]->ptr)) { /* Already forgotten. The deletion may have been gossipped by * another node, so we pretend it succeeded. */ - addReply(c,shared.ok); - else - addReplyErrorFormat(c,"Unknown node %s", (char*)c->argv[2]->ptr); + addReply(c, shared.ok); + } else { + addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[2]->ptr); + } return 1; } else if (n == myself) { - addReplyError(c,"I tried hard but I can't forget myself..."); + addReplyError(c, "I tried hard but I can't forget myself..."); return 1; } else if (nodeIsSlave(myself) && myself->slaveof == n) { - addReplyError(c,"Can't forget my master!"); + addReplyError(c, "Can't forget my master!"); return 1; } clusterBlacklistAddNode(n); clusterDelNode(n); - clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE| - CLUSTER_TODO_SAVE_CONFIG); - addReply(c,shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr,"replicate") && c->argc == 3) { + clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); + addReply(c, shared.ok); + } else if (!strcasecmp(c->argv[1]->ptr, "replicate") && c->argc == 3) { /* CLUSTER REPLICATE */ /* Lookup the specified node in our table. */ clusterNode *n = clusterLookupNode(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); if (!n) { - addReplyErrorFormat(c,"Unknown node %s", (char*)c->argv[2]->ptr); + addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[2]->ptr); return 1; } /* I can't replicate myself. */ if (n == myself) { - addReplyError(c,"Can't replicate myself"); + addReplyError(c, "Can't replicate myself"); return 1; } /* Can't replicate a slave. */ if (nodeIsSlave(n)) { - addReplyError(c,"I can only replicate a master, not a replica."); + addReplyError(c, "I can only replicate a master, not a replica."); return 1; } /* If the instance is currently a master, it should have no assigned * slots nor keys to accept to replicate some other node. * Slaves can switch to another master without issues. */ - if (clusterNodeIsMaster(myself) && - (myself->numslots != 0 || kvstoreSize(server.db[0].keys) != 0)) { - addReplyError(c, - "To set a master the node must be empty and " - "without assigned slots."); + if (clusterNodeIsMaster(myself) && (myself->numslots != 0 || kvstoreSize(server.db[0].keys) != 0)) { + addReplyError(c, "To set a master the node must be empty and " + "without assigned slots."); return 1; } /* Set the master. */ clusterSetMaster(n, 1); clusterBroadcastPong(CLUSTER_BROADCAST_ALL); - clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); - addReply(c,shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr,"count-failure-reports") && - c->argc == 3) - { + clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); + addReply(c, shared.ok); + } else if (!strcasecmp(c->argv[1]->ptr, "count-failure-reports") && c->argc == 3) { /* CLUSTER COUNT-FAILURE-REPORTS */ clusterNode *n = clusterLookupNode(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); if (!n) { - addReplyErrorFormat(c,"Unknown node %s", (char*)c->argv[2]->ptr); + addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[2]->ptr); return 1; } else { - addReplyLongLong(c,clusterNodeFailureReportsCount(n)); + addReplyLongLong(c, clusterNodeFailureReportsCount(n)); } - } else if (!strcasecmp(c->argv[1]->ptr,"failover") && - (c->argc == 2 || c->argc == 3)) - { + } else if (!strcasecmp(c->argv[1]->ptr, "failover") && (c->argc == 2 || c->argc == 3)) { /* CLUSTER FAILOVER [FORCE|TAKEOVER] */ int force = 0, takeover = 0; if (c->argc == 3) { - if (!strcasecmp(c->argv[2]->ptr,"force")) { + if (!strcasecmp(c->argv[2]->ptr, "force")) { force = 1; - } else if (!strcasecmp(c->argv[2]->ptr,"takeover")) { + } else if (!strcasecmp(c->argv[2]->ptr, "takeover")) { takeover = 1; force = 1; /* Takeover also implies force. */ } else { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return 1; } } /* Check preconditions. */ if (clusterNodeIsMaster(myself)) { - addReplyError(c,"You should send CLUSTER FAILOVER to a replica"); + addReplyError(c, "You should send CLUSTER FAILOVER to a replica"); return 1; } else if (myself->slaveof == NULL) { - addReplyError(c,"I'm a replica but my master is unknown to me"); + addReplyError(c, "I'm a replica but my master is unknown to me"); return 1; - } else if (!force && - (nodeFailed(myself->slaveof) || - myself->slaveof->link == NULL)) - { - addReplyError(c,"Master is down or failed, " - "please use CLUSTER FAILOVER FORCE"); + } else if (!force && (nodeFailed(myself->slaveof) || myself->slaveof->link == NULL)) { + addReplyError(c, "Master is down or failed, " + "please use CLUSTER FAILOVER FORCE"); return 1; } resetManualFailover(); @@ -6704,22 +6717,21 @@ int clusterCommandSpecial(client *c) { * generates a new configuration epoch for this node without * consensus, claims the master's slots, and broadcast the new * configuration. */ - serverLog(LL_NOTICE,"Taking over the master (user request)."); + serverLog(LL_NOTICE, "Taking over the master (user request)."); clusterBumpConfigEpochWithoutConsensus(); clusterFailoverReplaceYourMaster(); } else if (force) { /* If this is a forced failover, we don't need to talk with our * master to agree about the offset. We just failover taking over * it without coordination. */ - serverLog(LL_NOTICE,"Forced failover user request accepted."); + serverLog(LL_NOTICE, "Forced failover user request accepted."); server.cluster->mf_can_start = 1; } else { - serverLog(LL_NOTICE,"Manual failover user request accepted."); + serverLog(LL_NOTICE, "Manual failover user request accepted."); clusterSendMFStart(myself->slaveof); } - addReply(c,shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr,"set-config-epoch") && c->argc == 3) - { + addReply(c, shared.ok); + } else if (!strcasecmp(c->argv[1]->ptr, "set-config-epoch") && c->argc == 3) { /* CLUSTER SET-CONFIG-EPOCH * * The user is allowed to set the config epoch only when a node is @@ -6729,45 +6741,43 @@ int clusterCommandSpecial(client *c) { * resolution system which is too slow when a big cluster is created. */ long long epoch; - if (getLongLongFromObjectOrReply(c,c->argv[2],&epoch,NULL) != C_OK) + if (getLongLongFromObjectOrReply(c, c->argv[2], &epoch, NULL) != C_OK) { return 1; + } if (epoch < 0) { - addReplyErrorFormat(c,"Invalid config epoch specified: %lld",epoch); + addReplyErrorFormat(c, "Invalid config epoch specified: %lld", epoch); } else if (dictSize(server.cluster->nodes) > 1) { - addReplyError(c,"The user can assign a config epoch only when the " - "node does not know any other node."); + addReplyError(c, "The user can assign a config epoch only when the " + "node does not know any other node."); } else if (myself->configEpoch != 0) { - addReplyError(c,"Node config epoch is already non-zero"); + addReplyError(c, "Node config epoch is already non-zero"); } else { myself->configEpoch = epoch; - serverLog(LL_NOTICE, - "configEpoch set to %llu via CLUSTER SET-CONFIG-EPOCH", - (unsigned long long) myself->configEpoch); + serverLog(LL_NOTICE, "configEpoch set to %llu via CLUSTER SET-CONFIG-EPOCH", + (unsigned long long)myself->configEpoch); - if (server.cluster->currentEpoch < (uint64_t)epoch) + if (server.cluster->currentEpoch < (uint64_t)epoch) { server.cluster->currentEpoch = epoch; + } /* No need to fsync the config here since in the unlucky event * of a failure to persist the config, the conflict resolution code * will assign a unique config to this node. */ - clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE| - CLUSTER_TODO_SAVE_CONFIG); - addReply(c,shared.ok); + clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); + addReply(c, shared.ok); } - } else if (!strcasecmp(c->argv[1]->ptr,"reset") && - (c->argc == 2 || c->argc == 3)) - { + } else if (!strcasecmp(c->argv[1]->ptr, "reset") && (c->argc == 2 || c->argc == 3)) { /* CLUSTER RESET [SOFT|HARD] */ int hard = 0; /* Parse soft/hard argument. Default is soft. */ if (c->argc == 3) { - if (!strcasecmp(c->argv[2]->ptr,"hard")) { + if (!strcasecmp(c->argv[2]->ptr, "hard")) { hard = 1; - } else if (!strcasecmp(c->argv[2]->ptr,"soft")) { + } else if (!strcasecmp(c->argv[2]->ptr, "soft")) { hard = 0; } else { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return 1; } } @@ -6775,13 +6785,13 @@ int clusterCommandSpecial(client *c) { /* Slaves can be reset while containing data, but not master nodes * that must be empty. */ if (clusterNodeIsMaster(myself) && kvstoreSize(c->db->keys) != 0) { - addReplyError(c,"CLUSTER RESET can't be called with " - "master nodes containing keys"); + addReplyError(c, "CLUSTER RESET can't be called with " + "master nodes containing keys"); return 1; } clusterReset(hard); - addReply(c,shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr,"links") && c->argc == 2) { + addReply(c, shared.ok); + } else if (!strcasecmp(c->argv[1]->ptr, "links") && c->argc == 2) { /* CLUSTER LINKS */ addReplyClusterLinksDescription(c); } else { @@ -6826,8 +6836,7 @@ const char **clusterCommandExtendedHelp(void) { "LINKS", " Return information about all network links between this node and its peers.", " Output format is an array where each array element is a map containing attributes of a link", - NULL - }; + NULL}; return help; } @@ -6867,12 +6876,12 @@ long long clusterNodeReplOffset(clusterNode *node) { const char *clusterNodePreferredEndpoint(clusterNode *n) { char *hostname = clusterNodeHostname(n); switch (server.cluster_preferred_endpoint_type) { - case CLUSTER_ENDPOINT_TYPE_IP: - return clusterNodeIp(n); - case CLUSTER_ENDPOINT_TYPE_HOSTNAME: - return (hostname != NULL && hostname[0] != '\0') ? hostname : "?"; - case CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT: - return ""; + case CLUSTER_ENDPOINT_TYPE_IP: + return clusterNodeIp(n); + case CLUSTER_ENDPOINT_TYPE_HOSTNAME: + return (hostname != NULL && hostname[0] != '\0') ? hostname : "?"; + case CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT: + return ""; } return "unknown"; } @@ -6881,8 +6890,8 @@ int clusterAllowFailoverCmd(client *c) { if (!server.cluster_enabled) { return 1; } - addReplyError(c,"FAILOVER not allowed in cluster mode. " - "Use CLUSTER FAILOVER command instead."); + addReplyError(c, "FAILOVER not allowed in cluster mode. " + "Use CLUSTER FAILOVER command instead."); return 0; } @@ -6891,12 +6900,13 @@ void clusterPromoteSelfToMaster(void) { } /* Replicate migrating and importing slot states to all replicas */ -void clusterReplicateOpenSlots(void) -{ - if (!server.cluster_enabled) return; +void clusterReplicateOpenSlots(void) { + if (!server.cluster_enabled) { + return; + } int argc = 5; - robj **argv = zmalloc(sizeof(robj*)*argc); + robj **argv = zmalloc(sizeof(robj *) * argc); argv[0] = shared.cluster; argv[1] = shared.setslot; @@ -6912,7 +6922,9 @@ void clusterReplicateOpenSlots(void) } for (int j = 0; j < CLUSTER_SLOTS; j++) { - if (nodes_ptr[j] == NULL) continue; + if (nodes_ptr[j] == NULL) { + continue; + } argv[2] = createStringObjectFromLongLongForValue(j); sds name = sdsnewlen(nodes_ptr[j]->name, sizeof(nodes_ptr[j]->name)); diff --git a/src/cluster_legacy.h b/src/cluster_legacy.h index 68bddbbb9..bf1ce8d6e 100644 --- a/src/cluster_legacy.h +++ b/src/cluster_legacy.h @@ -6,10 +6,10 @@ /* The following defines are amount of time, sometimes expressed as * multiplicators of the node timeout value (when ending with MULT). */ #define CLUSTER_FAIL_REPORT_VALIDITY_MULT 2 /* Fail report validity. */ -#define CLUSTER_FAIL_UNDO_TIME_MULT 2 /* Undo fail if master is back. */ -#define CLUSTER_MF_TIMEOUT 5000 /* Milliseconds to do a manual failover. */ -#define CLUSTER_MF_PAUSE_MULT 2 /* Master pause manual failover mult. */ -#define CLUSTER_SLAVE_MIGRATION_DELAY 5000 /* Delay for slave migration. */ +#define CLUSTER_FAIL_UNDO_TIME_MULT 2 /* Undo fail if master is back. */ +#define CLUSTER_MF_TIMEOUT 5000 /* Milliseconds to do a manual failover. */ +#define CLUSTER_MF_PAUSE_MULT 2 /* Master pause manual failover mult. */ +#define CLUSTER_SLAVE_MIGRATION_DELAY 5000 /* Delay for slave migration. */ /* Reasons why a slave is not able to failover. */ #define CLUSTER_CANT_FAILOVER_NONE 0 @@ -20,39 +20,41 @@ #define CLUSTER_CANT_FAILOVER_RELOG_PERIOD (10) /* seconds. */ /* clusterState todo_before_sleep flags. */ -#define CLUSTER_TODO_HANDLE_FAILOVER (1<<0) -#define CLUSTER_TODO_UPDATE_STATE (1<<1) -#define CLUSTER_TODO_SAVE_CONFIG (1<<2) -#define CLUSTER_TODO_FSYNC_CONFIG (1<<3) -#define CLUSTER_TODO_HANDLE_MANUALFAILOVER (1<<4) +#define CLUSTER_TODO_HANDLE_FAILOVER (1 << 0) +#define CLUSTER_TODO_UPDATE_STATE (1 << 1) +#define CLUSTER_TODO_SAVE_CONFIG (1 << 2) +#define CLUSTER_TODO_FSYNC_CONFIG (1 << 3) +#define CLUSTER_TODO_HANDLE_MANUALFAILOVER (1 << 4) /* clusterLink encapsulates everything needed to talk with a remote node. */ typedef struct clusterLink { - mstime_t ctime; /* Link creation time */ - connection *conn; /* Connection to remote node */ - list *send_msg_queue; /* List of messages to be sent */ - size_t head_msg_send_offset; /* Number of bytes already sent of message at head of queue */ + mstime_t ctime; /* Link creation time */ + connection *conn; /* Connection to remote node */ + list *send_msg_queue; /* List of messages to be sent */ + size_t head_msg_send_offset; /* Number of bytes already sent of message at head of queue */ unsigned long long send_msg_queue_mem; /* Memory in bytes used by message queue */ - char *rcvbuf; /* Packet reception buffer */ - size_t rcvbuf_len; /* Used size of rcvbuf */ - size_t rcvbuf_alloc; /* Allocated size of rcvbuf */ - clusterNode *node; /* Node related to this link. Initialized to NULL when unknown */ - int inbound; /* 1 if this link is an inbound link accepted from the related node */ + char *rcvbuf; /* Packet reception buffer */ + size_t rcvbuf_len; /* Used size of rcvbuf */ + size_t rcvbuf_alloc; /* Allocated size of rcvbuf */ + clusterNode *node; /* Node related to this link. Initialized to NULL when unknown */ + int inbound; /* 1 if this link is an inbound link accepted from the related node */ } clusterLink; /* Cluster node flags and macros. */ -#define CLUSTER_NODE_MASTER 1 /* The node is a master */ -#define CLUSTER_NODE_SLAVE 2 /* The node is a slave */ -#define CLUSTER_NODE_PFAIL 4 /* Failure? Need acknowledge */ -#define CLUSTER_NODE_FAIL 8 /* The node is believed to be malfunctioning */ -#define CLUSTER_NODE_MYSELF 16 /* This node is myself */ -#define CLUSTER_NODE_HANDSHAKE 32 /* We have still to exchange the first ping */ -#define CLUSTER_NODE_NOADDR 64 /* We don't know the address of this node */ -#define CLUSTER_NODE_MEET 128 /* Send a MEET message to this node */ -#define CLUSTER_NODE_MIGRATE_TO 256 /* Master eligible for replica migration. */ -#define CLUSTER_NODE_NOFAILOVER 512 /* Slave will not try to failover. */ +#define CLUSTER_NODE_MASTER 1 /* The node is a master */ +#define CLUSTER_NODE_SLAVE 2 /* The node is a slave */ +#define CLUSTER_NODE_PFAIL 4 /* Failure? Need acknowledge */ +#define CLUSTER_NODE_FAIL 8 /* The node is believed to be malfunctioning */ +#define CLUSTER_NODE_MYSELF 16 /* This node is myself */ +#define CLUSTER_NODE_HANDSHAKE 32 /* We have still to exchange the first ping */ +#define CLUSTER_NODE_NOADDR 64 /* We don't know the address of this node */ +#define CLUSTER_NODE_MEET 128 /* Send a MEET message to this node */ +#define CLUSTER_NODE_MIGRATE_TO 256 /* Master eligible for replica migration. */ +#define CLUSTER_NODE_NOFAILOVER 512 /* Slave will not try to failover. */ #define CLUSTER_NODE_EXTENSIONS_SUPPORTED 1024 /* This node supports extensions. */ -#define CLUSTER_NODE_NULL_NAME "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" +#define CLUSTER_NODE_NULL_NAME \ + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" \ + "\000\000\000\000\000\000\000\000\000\000\000\000" #define nodeIsMaster(n) ((n)->flags & CLUSTER_NODE_MASTER) #define nodeIsSlave(n) ((n)->flags & CLUSTER_NODE_SLAVE) @@ -65,8 +67,8 @@ typedef struct clusterLink { /* This structure represent elements of node->fail_reports. */ typedef struct clusterNodeFailReport { - clusterNode *node; /* Node reporting the failure condition. */ - mstime_t time; /* Time of the last report from this node. */ + clusterNode *node; /* Node reporting the failure condition. */ + mstime_t time; /* Time of the last report from this node. */ } clusterNodeFailReport; /* Cluster messages header */ @@ -77,18 +79,18 @@ typedef struct clusterNodeFailReport { * kind of packet. PONG is the reply to ping, in the exact format as a PING, * while MEET is a special PING that forces the receiver to add the sender * as a node (if it is not already in the list). */ -#define CLUSTERMSG_TYPE_PING 0 /* Ping */ -#define CLUSTERMSG_TYPE_PONG 1 /* Pong (reply to Ping) */ -#define CLUSTERMSG_TYPE_MEET 2 /* Meet "let's join" message */ -#define CLUSTERMSG_TYPE_FAIL 3 /* Mark node xxx as failing */ -#define CLUSTERMSG_TYPE_PUBLISH 4 /* Pub/Sub Publish propagation */ +#define CLUSTERMSG_TYPE_PING 0 /* Ping */ +#define CLUSTERMSG_TYPE_PONG 1 /* Pong (reply to Ping) */ +#define CLUSTERMSG_TYPE_MEET 2 /* Meet "let's join" message */ +#define CLUSTERMSG_TYPE_FAIL 3 /* Mark node xxx as failing */ +#define CLUSTERMSG_TYPE_PUBLISH 4 /* Pub/Sub Publish propagation */ #define CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST 5 /* May I failover? */ #define CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK 6 /* Yes, you have my vote */ -#define CLUSTERMSG_TYPE_UPDATE 7 /* Another node slots configuration */ -#define CLUSTERMSG_TYPE_MFSTART 8 /* Pause clients for manual failover */ -#define CLUSTERMSG_TYPE_MODULE 9 /* Module cluster API message. */ -#define CLUSTERMSG_TYPE_PUBLISHSHARD 10 /* Pub/Sub Publish shard propagation */ -#define CLUSTERMSG_TYPE_COUNT 11 /* Total number of message types. */ +#define CLUSTERMSG_TYPE_UPDATE 7 /* Another node slots configuration */ +#define CLUSTERMSG_TYPE_MFSTART 8 /* Pause clients for manual failover */ +#define CLUSTERMSG_TYPE_MODULE 9 /* Module cluster API message. */ +#define CLUSTERMSG_TYPE_PUBLISHSHARD 10 /* Pub/Sub Publish shard propagation */ +#define CLUSTERMSG_TYPE_COUNT 11 /* Total number of message types. */ /* Initially we don't know our "name", but we'll find it once we connect * to the first node, using the getsockname() function. Then we'll use this @@ -97,11 +99,11 @@ typedef struct { char nodename[CLUSTER_NAMELEN]; uint32_t ping_sent; uint32_t pong_received; - char ip[NET_IP_STR_LEN]; /* IP address last time it was seen */ - uint16_t port; /* primary port last time it was seen */ - uint16_t cport; /* cluster port last time it was seen */ - uint16_t flags; /* node->flags copy */ - uint16_t pport; /* secondary port last time it was seen */ + char ip[NET_IP_STR_LEN]; /* IP address last time it was seen */ + uint16_t port; /* primary port last time it was seen */ + uint16_t cport; /* cluster port last time it was seen */ + uint16_t flags; /* node->flags copy */ + uint16_t pport; /* secondary port last time it was seen */ uint16_t notused1; } clusterMsgDataGossip; @@ -116,15 +118,15 @@ typedef struct { } clusterMsgDataPublish; typedef struct { - uint64_t configEpoch; /* Config epoch of the specified instance. */ - char nodename[CLUSTER_NAMELEN]; /* Name of the slots owner. */ - unsigned char slots[CLUSTER_SLOTS/8]; /* Slots bitmap. */ + uint64_t configEpoch; /* Config epoch of the specified instance. */ + char nodename[CLUSTER_NAMELEN]; /* Name of the slots owner. */ + unsigned char slots[CLUSTER_SLOTS / 8]; /* Slots bitmap. */ } clusterMsgDataUpdate; typedef struct { - uint64_t module_id; /* ID of the sender module. */ - uint32_t len; /* ID of the sender module. */ - uint8_t type; /* Type from 0 to 255. */ + uint64_t module_id; /* ID of the sender module. */ + uint32_t len; /* ID of the sender module. */ + uint8_t type; /* Type from 0 to 255. */ unsigned char bulk_data[3]; /* 3 bytes just as placeholder. */ } clusterMsgModule; @@ -151,7 +153,7 @@ typedef struct { typedef struct { char name[CLUSTER_NAMELEN]; /* Node name. */ - uint64_t ttl; /* Remaining time to blacklist the node, in seconds. */ + uint64_t ttl; /* Remaining time to blacklist the node, in seconds. */ } clusterMsgPingExtForgottenNode; static_assert(sizeof(clusterMsgPingExtForgottenNode) % 8 == 0, ""); @@ -162,7 +164,7 @@ typedef struct { typedef struct { uint32_t length; /* Total length of this extension message (including this header) */ - uint16_t type; /* Type of this extension message (see clusterMsgPingtypes) */ + uint16_t type; /* Type of this extension message (see clusterMsgPingtypes) */ uint16_t unused; /* 16 bits of padding to make this structure 8 byte aligned. */ union { clusterMsgPingExtHostname hostname; @@ -207,30 +209,30 @@ union clusterMsgData { #define CLUSTER_PROTO_VER 1 /* Cluster bus protocol version. */ typedef struct { - char sig[4]; /* Signature "RCmb" (Cluster message bus). */ - uint32_t totlen; /* Total length of this message */ - uint16_t ver; /* Protocol version, currently set to CLUSTER_PROTO_VER. */ - uint16_t port; /* Primary port number (TCP or TLS). */ - uint16_t type; /* Message type */ - uint16_t count; /* Number of gossip sections. */ - uint64_t currentEpoch; /* The epoch accordingly to the sending node. */ - uint64_t configEpoch; /* The config epoch if it's a master, or the last - epoch advertised by its master if it is a - slave. */ - uint64_t offset; /* Master replication offset if node is a master or - processed replication offset if node is a slave. */ + char sig[4]; /* Signature "RCmb" (Cluster message bus). */ + uint32_t totlen; /* Total length of this message */ + uint16_t ver; /* Protocol version, currently set to CLUSTER_PROTO_VER. */ + uint16_t port; /* Primary port number (TCP or TLS). */ + uint16_t type; /* Message type */ + uint16_t count; /* Number of gossip sections. */ + uint64_t currentEpoch; /* The epoch accordingly to the sending node. */ + uint64_t configEpoch; /* The config epoch if it's a master, or the last + epoch advertised by its master if it is a + slave. */ + uint64_t offset; /* Master replication offset if node is a master or + processed replication offset if node is a slave. */ char sender[CLUSTER_NAMELEN]; /* Name of the sender node */ - unsigned char myslots[CLUSTER_SLOTS/8]; + unsigned char myslots[CLUSTER_SLOTS / 8]; char slaveof[CLUSTER_NAMELEN]; - char myip[NET_IP_STR_LEN]; /* Sender IP, if not all zeroed. */ - uint16_t extensions; /* Number of extensions sent along with this packet. */ - char notused1[30]; /* 30 bytes reserved for future usage. */ - uint16_t pport; /* Secondary port number: if primary port is TCP port, this is - TLS port, and if primary port is TLS port, this is TCP port.*/ - uint16_t cport; /* Sender TCP cluster bus port */ - uint16_t flags; /* Sender node flags */ - unsigned char state; /* Cluster state from the POV of the sender */ - unsigned char mflags[3]; /* Message flags: CLUSTERMSG_FLAG[012]_... */ + char myip[NET_IP_STR_LEN]; /* Sender IP, if not all zeroed. */ + uint16_t extensions; /* Number of extensions sent along with this packet. */ + char notused1[30]; /* 30 bytes reserved for future usage. */ + uint16_t pport; /* Secondary port number: if primary port is TCP port, this is + TLS port, and if primary port is TLS port, this is TCP port.*/ + uint16_t cport; /* Sender TCP cluster bus port */ + uint16_t flags; /* Sender node flags */ + unsigned char state; /* Cluster state from the POV of the sender */ + unsigned char mflags[3]; /* Message flags: CLUSTERMSG_FLAG[012]_... */ union clusterMsgData data; } clusterMsg; @@ -265,90 +267,92 @@ static_assert(offsetof(clusterMsg, state) == 2252, "unexpected field offset"); static_assert(offsetof(clusterMsg, mflags) == 2253, "unexpected field offset"); static_assert(offsetof(clusterMsg, data) == 2256, "unexpected field offset"); -#define CLUSTERMSG_MIN_LEN (sizeof(clusterMsg)-sizeof(union clusterMsgData)) +#define CLUSTERMSG_MIN_LEN (sizeof(clusterMsg) - sizeof(union clusterMsgData)) /* Message flags better specify the packet content or are used to * provide some information about the node state. */ -#define CLUSTERMSG_FLAG0_PAUSED (1<<0) /* Master paused for manual failover. */ -#define CLUSTERMSG_FLAG0_FORCEACK (1<<1) /* Give ACK to AUTH_REQUEST even if - master is up. */ -#define CLUSTERMSG_FLAG0_EXT_DATA (1<<2) /* Message contains extension data */ +#define CLUSTERMSG_FLAG0_PAUSED (1 << 0) /* Master paused for manual failover. */ +#define CLUSTERMSG_FLAG0_FORCEACK \ + (1 << 1) /* Give ACK to AUTH_REQUEST even if \ + master is up. */ +#define CLUSTERMSG_FLAG0_EXT_DATA (1 << 2) /* Message contains extension data */ struct _clusterNode { - mstime_t ctime; /* Node object creation time. */ - char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ - char shard_id[CLUSTER_NAMELEN]; /* shard id, hex string, sha1-size */ - int flags; /* CLUSTER_NODE_... */ - uint64_t configEpoch; /* Last configEpoch observed for this node */ - unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ - uint16_t *slot_info_pairs; /* Slots info represented as (start/end) pair (consecutive index). */ - int slot_info_pairs_count; /* Used number of slots in slot_info_pairs */ - int numslots; /* Number of slots handled by this node */ - int numslaves; /* Number of slave nodes, if this is a master */ - clusterNode **slaves; /* pointers to slave nodes */ - clusterNode *slaveof; /* pointer to the master node. Note that it - may be NULL even if the node is a slave - if we don't have the master node in our - tables. */ + mstime_t ctime; /* Node object creation time. */ + char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ + char shard_id[CLUSTER_NAMELEN]; /* shard id, hex string, sha1-size */ + int flags; /* CLUSTER_NODE_... */ + uint64_t configEpoch; /* Last configEpoch observed for this node */ + unsigned char slots[CLUSTER_SLOTS / 8]; /* slots handled by this node */ + uint16_t *slot_info_pairs; /* Slots info represented as (start/end) pair (consecutive index). */ + int slot_info_pairs_count; /* Used number of slots in slot_info_pairs */ + int numslots; /* Number of slots handled by this node */ + int numslaves; /* Number of slave nodes, if this is a master */ + clusterNode **slaves; /* pointers to slave nodes */ + clusterNode *slaveof; /* pointer to the master node. Note that it + may be NULL even if the node is a slave + if we don't have the master node in our + tables. */ unsigned long long last_in_ping_gossip; /* The number of the last carried in the ping gossip section */ - mstime_t ping_sent; /* Unix time we sent latest ping */ - mstime_t pong_received; /* Unix time we received the pong */ - mstime_t data_received; /* Unix time we received any data */ - mstime_t fail_time; /* Unix time when FAIL flag was set */ - mstime_t voted_time; /* Last time we voted for a slave of this master */ - mstime_t repl_offset_time; /* Unix time we received offset for this node */ - mstime_t orphaned_time; /* Starting time of orphaned master condition */ - long long repl_offset; /* Last known repl offset for this node. */ - char ip[NET_IP_STR_LEN]; /* Latest known IP address of this node */ - sds hostname; /* The known hostname for this node */ - sds human_nodename; /* The known human readable nodename for this node */ - int tcp_port; /* Latest known clients TCP port. */ - int tls_port; /* Latest known clients TLS port */ - int cport; /* Latest known cluster port of this node. */ - clusterLink *link; /* TCP/IP link established toward this node */ - clusterLink *inbound_link; /* TCP/IP link accepted from this node */ - list *fail_reports; /* List of nodes signaling this as failing */ + mstime_t ping_sent; /* Unix time we sent latest ping */ + mstime_t pong_received; /* Unix time we received the pong */ + mstime_t data_received; /* Unix time we received any data */ + mstime_t fail_time; /* Unix time when FAIL flag was set */ + mstime_t voted_time; /* Last time we voted for a slave of this master */ + mstime_t repl_offset_time; /* Unix time we received offset for this node */ + mstime_t orphaned_time; /* Starting time of orphaned master condition */ + long long repl_offset; /* Last known repl offset for this node. */ + char ip[NET_IP_STR_LEN]; /* Latest known IP address of this node */ + sds hostname; /* The known hostname for this node */ + sds human_nodename; /* The known human readable nodename for this node */ + int tcp_port; /* Latest known clients TCP port. */ + int tls_port; /* Latest known clients TLS port */ + int cport; /* Latest known cluster port of this node. */ + clusterLink *link; /* TCP/IP link established toward this node */ + clusterLink *inbound_link; /* TCP/IP link accepted from this node */ + list *fail_reports; /* List of nodes signaling this as failing */ }; struct clusterState { - clusterNode *myself; /* This node */ + clusterNode *myself; /* This node */ uint64_t currentEpoch; - int state; /* CLUSTER_OK, CLUSTER_FAIL, ... */ - int size; /* Num of master nodes with at least one slot */ - dict *nodes; /* Hash table of name -> clusterNode structures */ - dict *shards; /* Hash table of shard_id -> list (of nodes) structures */ + int state; /* CLUSTER_OK, CLUSTER_FAIL, ... */ + int size; /* Num of master nodes with at least one slot */ + dict *nodes; /* Hash table of name -> clusterNode structures */ + dict *shards; /* Hash table of shard_id -> list (of nodes) structures */ dict *nodes_black_list; /* Nodes we don't re-add for a few seconds. */ clusterNode *migrating_slots_to[CLUSTER_SLOTS]; clusterNode *importing_slots_from[CLUSTER_SLOTS]; clusterNode *slots[CLUSTER_SLOTS]; /* The following fields are used to take the slave state on elections. */ - mstime_t failover_auth_time; /* Time of previous or next election. */ - int failover_auth_count; /* Number of votes received so far. */ - int failover_auth_sent; /* True if we already asked for votes. */ - int failover_auth_rank; /* This slave rank for current auth request. */ + mstime_t failover_auth_time; /* Time of previous or next election. */ + int failover_auth_count; /* Number of votes received so far. */ + int failover_auth_sent; /* True if we already asked for votes. */ + int failover_auth_rank; /* This slave rank for current auth request. */ uint64_t failover_auth_epoch; /* Epoch of the current election. */ - int cant_failover_reason; /* Why a slave is currently not able to - failover. See the CANT_FAILOVER_* macros. */ + int cant_failover_reason; /* Why a slave is currently not able to + failover. See the CANT_FAILOVER_* macros. */ /* Manual failover state in common. */ - mstime_t mf_end; /* Manual failover time limit (ms unixtime). - It is zero if there is no MF in progress. */ + mstime_t mf_end; /* Manual failover time limit (ms unixtime). + It is zero if there is no MF in progress. */ /* Manual failover state of master. */ - clusterNode *mf_slave; /* Slave performing the manual failover. */ + clusterNode *mf_slave; /* Slave performing the manual failover. */ /* Manual failover state of slave. */ long long mf_master_offset; /* Master offset the slave needs to start MF or -1 if still not received. */ int mf_can_start; /* If non-zero signal that the manual failover can start requesting masters vote. */ /* The following fields are used by masters to take state on elections. */ - uint64_t lastVoteEpoch; /* Epoch of the last vote granted. */ - int todo_before_sleep; /* Things to do in clusterBeforeSleep(). */ + uint64_t lastVoteEpoch; /* Epoch of the last vote granted. */ + int todo_before_sleep; /* Things to do in clusterBeforeSleep(). */ /* Stats */ /* Messages received and sent by type. */ long long stats_bus_messages_sent[CLUSTERMSG_TYPE_COUNT]; long long stats_bus_messages_received[CLUSTERMSG_TYPE_COUNT]; - long long stats_pfail_nodes; /* Number of nodes in PFAIL status, - excluding nodes without address. */ - unsigned long long stat_cluster_links_buffer_limit_exceeded; /* Total number of cluster links freed due to exceeding buffer limit */ + long long stats_pfail_nodes; /* Number of nodes in PFAIL status, + excluding nodes without address. */ + unsigned long long stat_cluster_links_buffer_limit_exceeded; /* Total number of cluster links freed due to exceeding + buffer limit */ /* Bit map for slots that are no longer claimed by the owner in cluster PING * messages. During slot migration, the owner will stop claiming the slot after @@ -359,4 +363,4 @@ struct clusterState { }; -#endif //CLUSTER_LEGACY_H +#endif // CLUSTER_LEGACY_H diff --git a/src/commands.c b/src/commands.c index bb93f9818..36a4930a2 100644 --- a/src/commands.c +++ b/src/commands.c @@ -1,8 +1,13 @@ #include "commands.h" #include "server.h" -#define MAKE_CMD(name,summary,complexity,since,doc_flags,replaced,deprecated,group,group_enum,history,num_history,tips,num_tips,function,arity,flags,acl,key_specs,key_specs_num,get_keys,numargs) name,summary,complexity,since,doc_flags,replaced,deprecated,group_enum,history,num_history,tips,num_tips,function,arity,flags,acl,key_specs,key_specs_num,get_keys,numargs -#define MAKE_ARG(name,type,key_spec_index,token,summary,since,flags,numsubargs,deprecated_since) name,type,key_spec_index,token,summary,since,flags,deprecated_since,numsubargs +#define MAKE_CMD(name, summary, complexity, since, doc_flags, replaced, deprecated, group, group_enum, history, \ + num_history, tips, num_tips, function, arity, flags, acl, key_specs, key_specs_num, get_keys, \ + numargs) \ + name, summary, complexity, since, doc_flags, replaced, deprecated, group_enum, history, num_history, tips, \ + num_tips, function, arity, flags, acl, key_specs, key_specs_num, get_keys, numargs +#define MAKE_ARG(name, type, key_spec_index, token, summary, since, flags, numsubargs, deprecated_since) \ + name, type, key_spec_index, token, summary, since, flags, deprecated_since, numsubargs #define COMMAND_STRUCT serverCommand #define COMMAND_ARG serverCommandArg diff --git a/src/commands.h b/src/commands.h index fe8bb680c..096a06f31 100644 --- a/src/commands.h +++ b/src/commands.h @@ -11,13 +11,13 @@ typedef enum { ARG_TYPE_UNIX_TIME, ARG_TYPE_PURE_TOKEN, ARG_TYPE_ONEOF, /* Has subargs */ - ARG_TYPE_BLOCK /* Has subargs */ + ARG_TYPE_BLOCK /* Has subargs */ } serverCommandArgType; -#define CMD_ARG_NONE (0) -#define CMD_ARG_OPTIONAL (1<<0) -#define CMD_ARG_MULTIPLE (1<<1) -#define CMD_ARG_MULTIPLE_TOKEN (1<<2) +#define CMD_ARG_NONE (0) +#define CMD_ARG_OPTIONAL (1 << 0) +#define CMD_ARG_MULTIPLE (1 << 1) +#define CMD_ARG_MULTIPLE_TOKEN (1 << 2) /* Must be compatible with RedisModuleCommandArg. See moduleCopyCommandArgs. */ typedef struct serverCommandArg { diff --git a/src/config.c b/src/config.c index 38e6d1d2f..e035ecfe4 100644 --- a/src/config.c +++ b/src/config.c @@ -50,129 +50,80 @@ typedef struct deprecatedConfig { const int argc_max; } deprecatedConfig; -configEnum maxmemory_policy_enum[] = { - {"volatile-lru", MAXMEMORY_VOLATILE_LRU}, - {"volatile-lfu", MAXMEMORY_VOLATILE_LFU}, - {"volatile-random",MAXMEMORY_VOLATILE_RANDOM}, - {"volatile-ttl",MAXMEMORY_VOLATILE_TTL}, - {"allkeys-lru",MAXMEMORY_ALLKEYS_LRU}, - {"allkeys-lfu",MAXMEMORY_ALLKEYS_LFU}, - {"allkeys-random",MAXMEMORY_ALLKEYS_RANDOM}, - {"noeviction",MAXMEMORY_NO_EVICTION}, - {NULL, 0} -}; - -configEnum syslog_facility_enum[] = { - {"user", LOG_USER}, - {"local0", LOG_LOCAL0}, - {"local1", LOG_LOCAL1}, - {"local2", LOG_LOCAL2}, - {"local3", LOG_LOCAL3}, - {"local4", LOG_LOCAL4}, - {"local5", LOG_LOCAL5}, - {"local6", LOG_LOCAL6}, - {"local7", LOG_LOCAL7}, - {NULL, 0} -}; - -configEnum loglevel_enum[] = { - {"debug", LL_DEBUG}, - {"verbose", LL_VERBOSE}, - {"notice", LL_NOTICE}, - {"warning", LL_WARNING}, - {"nothing", LL_NOTHING}, - {NULL,0} -}; - -configEnum supervised_mode_enum[] = { - {"upstart", SUPERVISED_UPSTART}, - {"systemd", SUPERVISED_SYSTEMD}, - {"auto", SUPERVISED_AUTODETECT}, - {"no", SUPERVISED_NONE}, - {NULL, 0} -}; +configEnum maxmemory_policy_enum[] = {{"volatile-lru", MAXMEMORY_VOLATILE_LRU}, + {"volatile-lfu", MAXMEMORY_VOLATILE_LFU}, + {"volatile-random", MAXMEMORY_VOLATILE_RANDOM}, + {"volatile-ttl", MAXMEMORY_VOLATILE_TTL}, + {"allkeys-lru", MAXMEMORY_ALLKEYS_LRU}, + {"allkeys-lfu", MAXMEMORY_ALLKEYS_LFU}, + {"allkeys-random", MAXMEMORY_ALLKEYS_RANDOM}, + {"noeviction", MAXMEMORY_NO_EVICTION}, + {NULL, 0}}; + +configEnum syslog_facility_enum[] = {{"user", LOG_USER}, {"local0", LOG_LOCAL0}, + {"local1", LOG_LOCAL1}, {"local2", LOG_LOCAL2}, + {"local3", LOG_LOCAL3}, {"local4", LOG_LOCAL4}, + {"local5", LOG_LOCAL5}, {"local6", LOG_LOCAL6}, + {"local7", LOG_LOCAL7}, {NULL, 0}}; + +configEnum loglevel_enum[] = {{"debug", LL_DEBUG}, {"verbose", LL_VERBOSE}, {"notice", LL_NOTICE}, + {"warning", LL_WARNING}, {"nothing", LL_NOTHING}, {NULL, 0}}; + +configEnum supervised_mode_enum[] = {{"upstart", SUPERVISED_UPSTART}, + {"systemd", SUPERVISED_SYSTEMD}, + {"auto", SUPERVISED_AUTODETECT}, + {"no", SUPERVISED_NONE}, + {NULL, 0}}; configEnum aof_fsync_enum[] = { - {"everysec", AOF_FSYNC_EVERYSEC}, - {"always", AOF_FSYNC_ALWAYS}, - {"no", AOF_FSYNC_NO}, - {NULL, 0} -}; + {"everysec", AOF_FSYNC_EVERYSEC}, {"always", AOF_FSYNC_ALWAYS}, {"no", AOF_FSYNC_NO}, {NULL, 0}}; -configEnum shutdown_on_sig_enum[] = { - {"default", 0}, - {"save", SHUTDOWN_SAVE}, - {"nosave", SHUTDOWN_NOSAVE}, - {"now", SHUTDOWN_NOW}, - {"force", SHUTDOWN_FORCE}, - {NULL, 0} -}; +configEnum shutdown_on_sig_enum[] = {{"default", 0}, {"save", SHUTDOWN_SAVE}, {"nosave", SHUTDOWN_NOSAVE}, + {"now", SHUTDOWN_NOW}, {"force", SHUTDOWN_FORCE}, {NULL, 0}}; -configEnum repl_diskless_load_enum[] = { - {"disabled", REPL_DISKLESS_LOAD_DISABLED}, - {"on-empty-db", REPL_DISKLESS_LOAD_WHEN_DB_EMPTY}, - {"swapdb", REPL_DISKLESS_LOAD_SWAPDB}, - {NULL, 0} -}; +configEnum repl_diskless_load_enum[] = {{"disabled", REPL_DISKLESS_LOAD_DISABLED}, + {"on-empty-db", REPL_DISKLESS_LOAD_WHEN_DB_EMPTY}, + {"swapdb", REPL_DISKLESS_LOAD_SWAPDB}, + {NULL, 0}}; configEnum tls_auth_clients_enum[] = { - {"no", TLS_CLIENT_AUTH_NO}, - {"yes", TLS_CLIENT_AUTH_YES}, - {"optional", TLS_CLIENT_AUTH_OPTIONAL}, - {NULL, 0} -}; + {"no", TLS_CLIENT_AUTH_NO}, {"yes", TLS_CLIENT_AUTH_YES}, {"optional", TLS_CLIENT_AUTH_OPTIONAL}, {NULL, 0}}; -configEnum oom_score_adj_enum[] = { - {"no", OOM_SCORE_ADJ_NO}, - {"yes", OOM_SCORE_RELATIVE}, - {"relative", OOM_SCORE_RELATIVE}, - {"absolute", OOM_SCORE_ADJ_ABSOLUTE}, - {NULL, 0} -}; +configEnum oom_score_adj_enum[] = {{"no", OOM_SCORE_ADJ_NO}, + {"yes", OOM_SCORE_RELATIVE}, + {"relative", OOM_SCORE_RELATIVE}, + {"absolute", OOM_SCORE_ADJ_ABSOLUTE}, + {NULL, 0}}; -configEnum acl_pubsub_default_enum[] = { - {"allchannels", SELECTOR_FLAG_ALLCHANNELS}, - {"resetchannels", 0}, - {NULL, 0} -}; +configEnum acl_pubsub_default_enum[] = {{"allchannels", SELECTOR_FLAG_ALLCHANNELS}, {"resetchannels", 0}, {NULL, 0}}; configEnum sanitize_dump_payload_enum[] = { - {"no", SANITIZE_DUMP_NO}, - {"yes", SANITIZE_DUMP_YES}, - {"clients", SANITIZE_DUMP_CLIENTS}, - {NULL, 0} -}; + {"no", SANITIZE_DUMP_NO}, {"yes", SANITIZE_DUMP_YES}, {"clients", SANITIZE_DUMP_CLIENTS}, {NULL, 0}}; -configEnum protected_action_enum[] = { - {"no", PROTECTED_ACTION_ALLOWED_NO}, - {"yes", PROTECTED_ACTION_ALLOWED_YES}, - {"local", PROTECTED_ACTION_ALLOWED_LOCAL}, - {NULL, 0} -}; +configEnum protected_action_enum[] = {{"no", PROTECTED_ACTION_ALLOWED_NO}, + {"yes", PROTECTED_ACTION_ALLOWED_YES}, + {"local", PROTECTED_ACTION_ALLOWED_LOCAL}, + {NULL, 0}}; -configEnum cluster_preferred_endpoint_type_enum[] = { - {"ip", CLUSTER_ENDPOINT_TYPE_IP}, - {"hostname", CLUSTER_ENDPOINT_TYPE_HOSTNAME}, - {"unknown-endpoint", CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT}, - {NULL, 0} -}; +configEnum cluster_preferred_endpoint_type_enum[] = {{"ip", CLUSTER_ENDPOINT_TYPE_IP}, + {"hostname", CLUSTER_ENDPOINT_TYPE_HOSTNAME}, + {"unknown-endpoint", CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT}, + {NULL, 0}}; -configEnum propagation_error_behavior_enum[] = { - {"ignore", PROPAGATION_ERR_BEHAVIOR_IGNORE}, - {"panic", PROPAGATION_ERR_BEHAVIOR_PANIC}, - {"panic-on-replicas", PROPAGATION_ERR_BEHAVIOR_PANIC_ON_REPLICAS}, - {NULL, 0} -}; +configEnum propagation_error_behavior_enum[] = {{"ignore", PROPAGATION_ERR_BEHAVIOR_IGNORE}, + {"panic", PROPAGATION_ERR_BEHAVIOR_PANIC}, + {"panic-on-replicas", PROPAGATION_ERR_BEHAVIOR_PANIC_ON_REPLICAS}, + {NULL, 0}}; /* Output buffer limits presets. */ clientBufferLimitsConfig clientBufferLimitsDefaults[CLIENT_TYPE_OBUF_COUNT] = { - {0, 0, 0}, /* normal */ - {1024*1024*256, 1024*1024*64, 60}, /* slave */ - {1024*1024*32, 1024*1024*8, 60} /* pubsub */ + {0, 0, 0}, /* normal */ + {1024 * 1024 * 256, 1024 * 1024 * 64, 60}, /* slave */ + {1024 * 1024 * 32, 1024 * 1024 * 8, 60} /* pubsub */ }; /* OOM Score defaults */ -int configOOMScoreAdjValuesDefaults[CONFIG_OOM_COUNT] = { 0, 200, 800 }; +int configOOMScoreAdjValuesDefaults[CONFIG_OOM_COUNT] = {0, 200, 800}; /* Generic config infrastructure function pointers * int is_valid_fn(val, err) @@ -183,32 +134,36 @@ int configOOMScoreAdjValuesDefaults[CONFIG_OOM_COUNT] = { 0, 200, 800 }; /* Configuration values that require no special handling to set, get, load or * rewrite. */ typedef struct boolConfigData { - int *config; /* The pointer to the server config this value is stored in */ + int *config; /* The pointer to the server config this value is stored in */ int default_value; /* The default value of the config on rewrite */ - int (*is_valid_fn)(int val, const char **err); /* Optional function to check validity of new value (generic doc above) */ + int (*is_valid_fn)(int val, + const char **err); /* Optional function to check validity of new value (generic doc above) */ } boolConfigData; typedef struct stringConfigData { - char **config; /* Pointer to the server config this value is stored in. */ + char **config; /* Pointer to the server config this value is stored in. */ const char *default_value; /* Default value of the config on rewrite. */ - int (*is_valid_fn)(char* val, const char **err); /* Optional function to check validity of new value (generic doc above) */ - int convert_empty_to_null; /* Boolean indicating if empty strings should - be stored as a NULL value. */ + int (*is_valid_fn)(char *val, + const char **err); /* Optional function to check validity of new value (generic doc above) */ + int convert_empty_to_null; /* Boolean indicating if empty strings should + be stored as a NULL value. */ } stringConfigData; typedef struct sdsConfigData { - sds *config; /* Pointer to the server config this value is stored in. */ + sds *config; /* Pointer to the server config this value is stored in. */ char *default_value; /* Default value of the config on rewrite. */ - int (*is_valid_fn)(sds val, const char **err); /* Optional function to check validity of new value (generic doc above) */ - int convert_empty_to_null; /* Boolean indicating if empty SDS strings should - be stored as a NULL value. */ + int (*is_valid_fn)(sds val, + const char **err); /* Optional function to check validity of new value (generic doc above) */ + int convert_empty_to_null; /* Boolean indicating if empty SDS strings should + be stored as a NULL value. */ } sdsConfigData; typedef struct enumConfigData { - int *config; /* The pointer to the server config this value is stored in */ + int *config; /* The pointer to the server config this value is stored in */ configEnum *enum_value; /* The underlying enum type this data represents */ - int default_value; /* The default value of the config on rewrite */ - int (*is_valid_fn)(int val, const char **err); /* Optional function to check validity of new value (generic doc above) */ + int default_value; /* The default value of the config on rewrite */ + int (*is_valid_fn)(int val, + const char **err); /* Optional function to check validity of new value (generic doc above) */ } enumConfigData; typedef enum numericType { @@ -239,10 +194,11 @@ typedef struct numericConfigData { } config; /* The pointer to the numeric config this value is stored in */ unsigned int flags; numericType numeric_type; /* An enum indicating the type of this value */ - long long lower_bound; /* The lower bound of this numeric value */ - long long upper_bound; /* The upper bound of this numeric value */ - long long default_value; /* The default value of the config on rewrite */ - int (*is_valid_fn)(long long val, const char **err); /* Optional function to check validity of new value (generic doc above) */ + long long lower_bound; /* The lower bound of this numeric value */ + long long upper_bound; /* The upper bound of this numeric value */ + long long default_value; /* The default value of the config on rewrite */ + int (*is_valid_fn)(long long val, + const char **err); /* Optional function to check validity of new value (generic doc above) */ } numericConfigData; typedef union typeData { @@ -274,13 +230,13 @@ typedef struct typeInterface { } typeInterface; struct standardConfig { - const char *name; /* The user visible name of this config */ - const char *alias; /* An alias that can also be used for this config */ - unsigned int flags; /* Flags for this specific config */ + const char *name; /* The user visible name of this config */ + const char *alias; /* An alias that can also be used for this config */ + unsigned int flags; /* Flags for this specific config */ typeInterface interface; /* The function pointers that define the type interface */ - typeData data; /* The type specific data exposed used by the interface */ - configType type; /* The type of config this is. */ - void *privdata; /* privdata for this config, for module configs this is a ModuleConfig struct */ + typeData data; /* The type specific data exposed used by the interface */ + configType type; /* The type of config this is. */ + void *privdata; /* privdata for this config, for module configs this is a ModuleConfig struct */ }; dict *configs = NULL; /* Runtime config values */ @@ -298,17 +254,21 @@ static standardConfig *lookupConfig(sds name) { /* Get enum value from name. If there is no match INT_MIN is returned. */ int configEnumGetValue(configEnum *ce, sds *argv, int argc, int bitflags) { - if (argc == 0 || (!bitflags && argc != 1)) return INT_MIN; + if (argc == 0 || (!bitflags && argc != 1)) { + return INT_MIN; + } int values = 0; for (int i = 0; i < argc; i++) { int matched = 0; for (configEnum *ceItem = ce; ceItem->name != NULL; ceItem++) { - if (!strcasecmp(argv[i],ceItem->name)) { + if (!strcasecmp(argv[i], ceItem->name)) { values |= ceItem->val; matched = 1; } } - if (!matched) return INT_MIN; + if (!matched) { + return INT_MIN; + } } return values; } @@ -317,7 +277,7 @@ int configEnumGetValue(configEnum *ce, sds *argv, int argc, int bitflags) { static sds configEnumGetName(configEnum *ce, int values, int bitflags) { sds names = NULL; int unmatched = values; - for( ; ce->name != NULL; ce++) { + for (; ce->name != NULL; ce++) { if (values == ce->val) { /* Short path for perfect match */ sdsfree(names); return sdsnew(ce->name); @@ -340,8 +300,9 @@ static sds configEnumGetName(configEnum *ce, int values, int bitflags) { /* Used for INFO generation. */ const char *evictPolicyToString(void) { for (configEnum *ce = maxmemory_policy_enum; ce->name != NULL; ce++) { - if (server.maxmemory_policy == ce->val) + if (server.maxmemory_policy == ce->val) { return ce->name; + } } serverPanic("unknown eviction policy"); } @@ -351,13 +312,17 @@ const char *evictPolicyToString(void) { *----------------------------------------------------------------------------*/ int yesnotoi(char *s) { - if (!strcasecmp(s,"yes")) return 1; - else if (!strcasecmp(s,"no")) return 0; - else return -1; + if (!strcasecmp(s, "yes")) { + return 1; + } else if (!strcasecmp(s, "no")) { + return 0; + } else { + return -1; + } } void appendServerSaveParams(time_t seconds, int changes) { - server.saveparams = zrealloc(server.saveparams,sizeof(struct saveparam)*(server.saveparamslen+1)); + server.saveparams = zrealloc(server.saveparams, sizeof(struct saveparam) * (server.saveparamslen + 1)); server.saveparams[server.saveparamslen].seconds = seconds; server.saveparams[server.saveparamslen].changes = changes; server.saveparamslen++; @@ -374,13 +339,13 @@ void queueLoadModule(sds path, sds *argv, int argc) { struct moduleLoadQueueEntry *loadmod; loadmod = zmalloc(sizeof(struct moduleLoadQueueEntry)); - loadmod->argv = argc ? zmalloc(sizeof(robj*)*argc) : NULL; + loadmod->argv = argc ? zmalloc(sizeof(robj *) * argc) : NULL; loadmod->path = sdsnew(path); loadmod->argc = argc; for (i = 0; i < argc; i++) { - loadmod->argv[i] = createRawStringObject(argv[i],sdslen(argv[i])); + loadmod->argv[i] = createRawStringObject(argv[i], sdslen(argv[i])); } - listAddNodeTail(server.loadmodule_queue,loadmod); + listAddNodeTail(server.loadmodule_queue, loadmod); } /* Parse an array of `arg_len` sds strings, validate and populate @@ -398,8 +363,10 @@ static int updateClientOutputBufferLimit(sds *args, int arg_len, const char **er /* We need a multiple of 4: */ if (arg_len % 4) { - if (err) *err = "Wrong number of arguments in " - "buffer limit configuration."; + if (err) { + *err = "Wrong number of arguments in " + "buffer limit configuration."; + } return 0; } @@ -409,19 +376,21 @@ static int updateClientOutputBufferLimit(sds *args, int arg_len, const char **er for (j = 0; j < arg_len; j += 4) { class = getClientTypeByName(args[j]); if (class == -1 || class == CLIENT_TYPE_MASTER) { - if (err) *err = "Invalid client class specified in " - "buffer limit configuration."; + if (err) { + *err = "Invalid client class specified in " + "buffer limit configuration."; + } return 0; } - hard = memtoull(args[j+1], &hard_err); - soft = memtoull(args[j+2], &soft_err); - soft_seconds = strtoll(args[j+3], &soft_seconds_eptr, 10); - if (hard_err || soft_err || - soft_seconds < 0 || *soft_seconds_eptr != '\0') - { - if (err) *err = "Error in hard, soft or soft_seconds setting in " - "buffer limit configuration."; + hard = memtoull(args[j + 1], &hard_err); + soft = memtoull(args[j + 2], &soft_err); + soft_seconds = strtoll(args[j + 3], &soft_seconds_eptr, 10); + if (hard_err || soft_err || soft_seconds < 0 || *soft_seconds_eptr != '\0') { + if (err) { + *err = "Error in hard, soft or soft_seconds setting in " + "buffer limit configuration."; + } return 0; } @@ -433,7 +402,9 @@ static int updateClientOutputBufferLimit(sds *args, int arg_len, const char **er /* Finally set the new config. */ for (j = 0; j < CLIENT_TYPE_OBUF_COUNT; j++) { - if (classes[j]) server.client_obuf_limits[j] = values[j]; + if (classes[j]) { + server.client_obuf_limits[j] = values[j]; + } } return 1; @@ -459,17 +430,19 @@ void loadServerConfigFromString(char *config) { int argc; reading_config_file = 1; - lines = sdssplitlen(config,strlen(config),"\n",1,&totlines); + lines = sdssplitlen(config, strlen(config), "\n", 1, &totlines); for (i = 0; i < totlines; i++) { - linenum = i+1; - lines[i] = sdstrim(lines[i]," \t\r\n"); + linenum = i + 1; + lines[i] = sdstrim(lines[i], " \t\r\n"); /* Skip comments and blank lines */ - if (lines[i][0] == '#' || lines[i][0] == '\0') continue; + if (lines[i][0] == '#' || lines[i][0] == '\0') { + continue; + } /* Split into arguments */ - argv = sdssplitargs(lines[i],&argc); + argv = sdssplitargs(lines[i], &argc); if (argv == NULL) { err = "Unbalanced quotes in configuration line"; goto loaderr; @@ -477,7 +450,7 @@ void loadServerConfigFromString(char *config) { /* Skip this line if the resulting command vector is empty. */ if (argc == 0) { - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); argv = NULL; continue; } @@ -501,42 +474,41 @@ void loadServerConfigFromString(char *config) { int new_argc; new_argv = sdssplitargs(argv[1], &new_argc); if (!config->interface.set(config, new_argv, new_argc, &err)) { - if(new_argv) sdsfreesplitres(new_argv, new_argc); + if (new_argv) { + sdsfreesplitres(new_argv, new_argc); + } goto loaderr; } sdsfreesplitres(new_argv, new_argc); } else { /* Set config using all arguments that follows */ - if (!config->interface.set(config, &argv[1], argc-1, &err)) { + if (!config->interface.set(config, &argv[1], argc - 1, &err)) { goto loaderr; } } - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); argv = NULL; continue; } else { int match = 0; for (deprecatedConfig *config = deprecated_configs; config->name != NULL; config++) { - if (!strcasecmp(argv[0], config->name) && - config->argc_min <= argc && - argc <= config->argc_max) - { + if (!strcasecmp(argv[0], config->name) && config->argc_min <= argc && argc <= config->argc_max) { match = 1; break; } } if (match) { - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); argv = NULL; continue; } } /* Execute config directives */ - if (!strcasecmp(argv[0],"include") && argc == 2) { + if (!strcasecmp(argv[0], "include") && argc == 2) { loadServerConfig(argv[1], 0, NULL); - } else if (!strcasecmp(argv[0],"rename-command") && argc == 3) { + } else if (!strcasecmp(argv[0], "rename-command") && argc == 3) { struct serverCommand *cmd = lookupCommandBySds(argv[1]); int retval; @@ -557,20 +529,20 @@ void loadServerConfigFromString(char *config) { retval = dictAdd(server.commands, copy, cmd); if (retval != DICT_OK) { sdsfree(copy); - err = "Target command name already exists"; goto loaderr; + err = "Target command name already exists"; + goto loaderr; } } - } else if (!strcasecmp(argv[0],"user") && argc >= 2) { + } else if (!strcasecmp(argv[0], "user") && argc >= 2) { int argc_err; - if (ACLAppendUserForLoading(argv,argc,&argc_err) == C_ERR) { + if (ACLAppendUserForLoading(argv, argc, &argc_err) == C_ERR) { const char *errmsg = ACLSetUserStringError(); - snprintf(buf,sizeof(buf),"Error in user declaration '%s': %s", - argv[argc_err],errmsg); + snprintf(buf, sizeof(buf), "Error in user declaration '%s': %s", argv[argc_err], errmsg); err = buf; goto loaderr; } - } else if (!strcasecmp(argv[0],"loadmodule") && argc >= 2) { - queueLoadModule(argv[1],&argv[2],argc-2); + } else if (!strcasecmp(argv[0], "loadmodule") && argc >= 2) { + queueLoadModule(argv[1], &argv[2], argc - 2); } else if (strchr(argv[0], '.')) { if (argc < 2) { err = "Module config specified without value"; @@ -578,10 +550,13 @@ void loadServerConfigFromString(char *config) { } sds name = sdsdup(argv[0]); sds val = sdsdup(argv[1]); - for (int i = 2; i < argc; i++) + for (int i = 2; i < argc; i++) { val = sdscatfmt(val, " %S", argv[i]); - if (!dictReplace(server.module_configs_queue, name, val)) sdsfree(name); - } else if (!strcasecmp(argv[0],"sentinel")) { + } + if (!dictReplace(server.module_configs_queue, name, val)) { + sdsfree(name); + } + } else if (!strcasecmp(argv[0], "sentinel")) { /* argc == 1 is handled by main() as we need to enter the sentinel * mode ASAP. */ if (argc != 1) { @@ -589,12 +564,13 @@ void loadServerConfigFromString(char *config) { err = "sentinel directive while not in sentinel mode"; goto loaderr; } - queueSentinelConfig(argv+1,argc-1,linenum,lines[i]); + queueSentinelConfig(argv + 1, argc - 1, linenum, lines[i]); } } else { - err = "Bad directive or wrong number of arguments"; goto loaderr; + err = "Bad directive or wrong number of arguments"; + goto loaderr; } - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); argv = NULL; } @@ -603,10 +579,9 @@ void loadServerConfigFromString(char *config) { /* Test if we are able to open the file. The server will not * be able to abort just for this problem later... */ - logfp = fopen(server.logfile,"a"); + logfp = fopen(server.logfile, "a"); if (logfp == NULL) { - err = sdscatprintf(sdsempty(), - "Can't open the log file: %s", strerror(errno)); + err = sdscatprintf(sdsempty(), "Can't open the log file: %s", strerror(errno)); goto loaderr; } fclose(logfp); @@ -620,20 +595,27 @@ void loadServerConfigFromString(char *config) { /* in case cluster mode is enabled dbnum must be 1 */ if (server.cluster_enabled && server.dbnum > 1) { - serverLog(LL_WARNING, "WARNING: Changing databases number from %d to 1 since we are in cluster mode", server.dbnum); + serverLog(LL_WARNING, "WARNING: Changing databases number from %d to 1 since we are in cluster mode", + server.dbnum); server.dbnum = 1; } /* To ensure backward compatibility and work while hz is out of range */ - if (server.config_hz < CONFIG_MIN_HZ) server.config_hz = CONFIG_MIN_HZ; - if (server.config_hz > CONFIG_MAX_HZ) server.config_hz = CONFIG_MAX_HZ; + if (server.config_hz < CONFIG_MIN_HZ) { + server.config_hz = CONFIG_MIN_HZ; + } + if (server.config_hz > CONFIG_MAX_HZ) { + server.config_hz = CONFIG_MAX_HZ; + } - sdsfreesplitres(lines,totlines); + sdsfreesplitres(lines, totlines); reading_config_file = 0; return; loaderr: - if (argv) sdsfreesplitres(argv,argc); + if (argv) { + sdsfreesplitres(argv, argc); + } fprintf(stderr, "\n*** FATAL CONFIG FILE ERROR (Version %s) ***\n", VALKEY_VERSION); if (i < totlines) { fprintf(stderr, "Reading the configuration file, at line %d\n", linenum); @@ -653,13 +635,12 @@ void loadServerConfigFromString(char *config) { #define CONFIG_READ_LEN 1024 void loadServerConfig(char *filename, char config_from_stdin, char *options) { sds config = sdsempty(); - char buf[CONFIG_READ_LEN+1]; + char buf[CONFIG_READ_LEN + 1]; FILE *fp; glob_t globbuf; /* Load the file content */ if (filename) { - /* The logic for handling wildcards has slightly different behavior in cases where * there is a failure to locate the included file. * Whether or not a wildcard is specified, we should ALWAYS log errors when attempting @@ -677,16 +658,15 @@ void loadServerConfig(char *filename, char config_from_stdin, char *options) { if (strchr(filename, '*') || strchr(filename, '?') || strchr(filename, '[')) { /* A wildcard character detected in filename, so let us use glob */ if (glob(filename, 0, NULL, &globbuf) == 0) { - for (size_t i = 0; i < globbuf.gl_pathc; i++) { if ((fp = fopen(globbuf.gl_pathv[i], "r")) == NULL) { - serverLog(LL_WARNING, - "Fatal error, can't open config file '%s': %s", - globbuf.gl_pathv[i], strerror(errno)); + serverLog(LL_WARNING, "Fatal error, can't open config file '%s': %s", globbuf.gl_pathv[i], + strerror(errno)); exit(1); } - while(fgets(buf,CONFIG_READ_LEN+1,fp) != NULL) - config = sdscat(config,buf); + while (fgets(buf, CONFIG_READ_LEN + 1, fp) != NULL) { + config = sdscat(config, buf); + } fclose(fp); } @@ -696,29 +676,29 @@ void loadServerConfig(char *filename, char config_from_stdin, char *options) { /* No wildcard in filename means we can use the original logic to read and * potentially fail traditionally */ if ((fp = fopen(filename, "r")) == NULL) { - serverLog(LL_WARNING, - "Fatal error, can't open config file '%s': %s", - filename, strerror(errno)); + serverLog(LL_WARNING, "Fatal error, can't open config file '%s': %s", filename, strerror(errno)); exit(1); } - while(fgets(buf,CONFIG_READ_LEN+1,fp) != NULL) - config = sdscat(config,buf); + while (fgets(buf, CONFIG_READ_LEN + 1, fp) != NULL) { + config = sdscat(config, buf); + } fclose(fp); } } /* Append content from stdin */ if (config_from_stdin) { - serverLog(LL_NOTICE,"Reading config from stdin"); + serverLog(LL_NOTICE, "Reading config from stdin"); fp = stdin; - while(fgets(buf,CONFIG_READ_LEN+1,fp) != NULL) - config = sdscat(config,buf); + while (fgets(buf, CONFIG_READ_LEN + 1, fp) != NULL) { + config = sdscat(config, buf); + } } /* Append the additional options */ if (options) { - config = sdscat(config,"\n"); - config = sdscat(config,options); + config = sdscat(config, "\n"); + config = sdscat(config, options); } loadServerConfigFromString(config); sdsfree(config); @@ -731,13 +711,15 @@ static int performInterfaceSet(standardConfig *config, sds value, const char **e if (config->flags & MULTI_ARG_CONFIG) { argv = sdssplitlen(value, sdslen(value), " ", 1, &argc); } else { - argv = (char**)&value; + argv = (char **)&value; argc = 1; } /* Set the config */ res = config->interface.set(config, argv, argc, errstr); - if (config->flags & MULTI_ARG_CONFIG) sdsfreesplitres(argv, argc); + if (config->flags & MULTI_ARG_CONFIG) { + sdsfreesplitres(argv, argc); + } return res; } @@ -760,39 +742,43 @@ int performModuleConfigSetDefaultFromName(sds name, const char **err) { return 0; } switch (config->type) { - case BOOL_CONFIG: - return setModuleBoolConfig(config->privdata, config->data.yesno.default_value, err); - case SDS_CONFIG: - return setModuleStringConfig(config->privdata, config->data.sds.default_value, err); - case NUMERIC_CONFIG: - return setModuleNumericConfig(config->privdata, config->data.numeric.default_value, err); - case ENUM_CONFIG: - return setModuleEnumConfig(config->privdata, config->data.enumd.default_value, err); - default: - serverPanic("Config type of module config is not allowed."); + case BOOL_CONFIG: + return setModuleBoolConfig(config->privdata, config->data.yesno.default_value, err); + case SDS_CONFIG: + return setModuleStringConfig(config->privdata, config->data.sds.default_value, err); + case NUMERIC_CONFIG: + return setModuleNumericConfig(config->privdata, config->data.numeric.default_value, err); + case ENUM_CONFIG: + return setModuleEnumConfig(config->privdata, config->data.enumd.default_value, err); + default: + serverPanic("Config type of module config is not allowed."); } return 0; } -static void restoreBackupConfig(standardConfig **set_configs, sds *old_values, int count, apply_fn *apply_fns, list *module_configs) { +static void restoreBackupConfig(standardConfig **set_configs, sds *old_values, int count, apply_fn *apply_fns, + list *module_configs) { int i; const char *errstr = "unknown error"; /* Set all backup values */ for (i = 0; i < count; i++) { - if (!performInterfaceSet(set_configs[i], old_values[i], &errstr)) + if (!performInterfaceSet(set_configs[i], old_values[i], &errstr)) { serverLog(LL_WARNING, "Failed restoring failed CONFIG SET command. Error setting %s to '%s': %s", set_configs[i]->name, old_values[i], errstr); + } } /* Apply backup */ if (apply_fns) { for (i = 0; i < count && apply_fns[i] != NULL; i++) { - if (!apply_fns[i](&errstr)) + if (!apply_fns[i](&errstr)) { serverLog(LL_WARNING, "Failed applying restored failed CONFIG SET command: %s", errstr); + } } } if (module_configs) { - if (!moduleConfigApplyConfig(module_configs, &errstr, NULL)) + if (!moduleConfigApplyConfig(module_configs, &errstr, NULL)) { serverLog(LL_WARNING, "Failed applying restored failed CONFIG SET command: %s", errstr); + } } } @@ -822,41 +808,43 @@ void configSetCommand(client *c) { config_count = (c->argc - 2) / 2; module_configs_apply = listCreate(); - set_configs = zcalloc(sizeof(standardConfig*)*config_count); - config_names = zcalloc(sizeof(char*)*config_count); - new_values = zmalloc(sizeof(sds*)*config_count); - old_values = zcalloc(sizeof(sds*)*config_count); - apply_fns = zcalloc(sizeof(apply_fn)*config_count); - config_map_fns = zmalloc(sizeof(int)*config_count); + set_configs = zcalloc(sizeof(standardConfig *) * config_count); + config_names = zcalloc(sizeof(char *) * config_count); + new_values = zmalloc(sizeof(sds *) * config_count); + old_values = zcalloc(sizeof(sds *) * config_count); + apply_fns = zcalloc(sizeof(apply_fn) * config_count); + config_map_fns = zmalloc(sizeof(int) * config_count); /* Find all relevant configs */ for (i = 0; i < config_count; i++) { - standardConfig *config = lookupConfig(c->argv[2+i*2]->ptr); + standardConfig *config = lookupConfig(c->argv[2 + i * 2]->ptr); /* Fail if we couldn't find this config */ if (!config) { if (!invalid_args) { - invalid_arg_name = c->argv[2+i*2]->ptr; + invalid_arg_name = c->argv[2 + i * 2]->ptr; invalid_args = 1; } continue; } - /* Note: it's important we run over ALL passed configs and check if we need to call `redactClientCommandArgument()`. - * This is in order to avoid anyone using this command for a log/slowlog/monitor/etc. displaying sensitive info. - * So even if we encounter an error we still continue running over the remaining arguments. */ + /* Note: it's important we run over ALL passed configs and check if we need to call + * `redactClientCommandArgument()`. This is in order to avoid anyone using this command for a + * log/slowlog/monitor/etc. displaying sensitive info. So even if we encounter an error we still continue + * running over the remaining arguments. */ if (config->flags & SENSITIVE_CONFIG) { - redactClientCommandArgument(c,2+i*2+1); + redactClientCommandArgument(c, 2 + i * 2 + 1); } - /* We continue to make sure we redact all the configs */ - if (invalid_args) continue; + /* We continue to make sure we redact all the configs */ + if (invalid_args) { + continue; + } if (config->flags & IMMUTABLE_CONFIG || - (config->flags & PROTECTED_CONFIG && !allowProtectedAction(server.enable_protected_configs, c))) - { + (config->flags & PROTECTED_CONFIG && !allowProtectedAction(server.enable_protected_configs, c))) { /* Note: we don't abort the loop since we still want to handle redacting sensitive configs (above) */ errstr = (config->flags & IMMUTABLE_CONFIG) ? "can't set immutable config" : "can't set protected config"; - err_arg_name = c->argv[2+i*2]->ptr; + err_arg_name = c->argv[2 + i * 2]->ptr; invalid_args = 1; continue; } @@ -873,27 +861,30 @@ void configSetCommand(client *c) { if (set_configs[j] == config) { /* Note: we don't abort the loop since we still want to handle redacting sensitive configs (above) */ errstr = "duplicate parameter"; - err_arg_name = c->argv[2+i*2]->ptr; + err_arg_name = c->argv[2 + i * 2]->ptr; invalid_args = 1; break; } } set_configs[i] = config; config_names[i] = config->name; - new_values[i] = c->argv[2+i*2+1]->ptr; + new_values[i] = c->argv[2 + i * 2 + 1]->ptr; + } + + if (invalid_args) { + goto err; } - - if (invalid_args) goto err; /* Backup old values before setting new ones */ - for (i = 0; i < config_count; i++) + for (i = 0; i < config_count; i++) { old_values[i] = set_configs[i]->interface.get(set_configs[i]); + } /* Set all new values (don't apply yet) */ for (i = 0; i < config_count; i++) { int res = performInterfaceSet(set_configs[i], new_values[i], &errstr); if (!res) { - restoreBackupConfig(set_configs, old_values, i+1, NULL, NULL); + restoreBackupConfig(set_configs, old_values, i + 1, NULL, NULL); err_arg_name = set_configs[i]->name; goto err; } else if (res == 1) { @@ -921,7 +912,10 @@ void configSetCommand(client *c) { /* Apply all configs after being set */ for (i = 0; i < config_count && apply_fns[i] != NULL; i++) { if (!apply_fns[i](&errstr)) { - serverLog(LL_WARNING, "Failed applying new configuration. Possibly related to new %s setting. Restoring previous settings.", set_configs[config_map_fns[i]]->name); + serverLog( + LL_WARNING, + "Failed applying new configuration. Possibly related to new %s setting. Restoring previous settings.", + set_configs[config_map_fns[i]]->name); restoreBackupConfig(set_configs, old_values, config_count, apply_fns, NULL); err_arg_name = set_configs[config_map_fns[i]]->name; goto err; @@ -936,26 +930,27 @@ void configSetCommand(client *c) { ValkeyModuleConfigChangeV1 cc = {.num_changes = config_count, .config_names = config_names}; moduleFireServerEvent(VALKEYMODULE_EVENT_CONFIG, VALKEYMODULE_SUBEVENT_CONFIG_CHANGE, &cc); - addReply(c,shared.ok); + addReply(c, shared.ok); goto end; err: if (deny_loading_error) { /* We give the loading error precedence because it may be handled by clients differently, unlike a plain -ERR. */ - addReplyErrorObject(c,shared.loadingerr); + addReplyErrorObject(c, shared.loadingerr); } else if (invalid_arg_name) { - addReplyErrorFormat(c,"Unknown option or number of arguments for CONFIG SET - '%s'", invalid_arg_name); + addReplyErrorFormat(c, "Unknown option or number of arguments for CONFIG SET - '%s'", invalid_arg_name); } else if (errstr) { - addReplyErrorFormat(c,"CONFIG SET failed (possibly related to argument '%s') - %s", err_arg_name, errstr); + addReplyErrorFormat(c, "CONFIG SET failed (possibly related to argument '%s') - %s", err_arg_name, errstr); } else { - addReplyErrorFormat(c,"CONFIG SET failed (possibly related to argument '%s')", err_arg_name); + addReplyErrorFormat(c, "CONFIG SET failed (possibly related to argument '%s')", err_arg_name); } end: zfree(set_configs); zfree(config_names); zfree(new_values); - for (i = 0; i < config_count; i++) + for (i = 0; i < config_count; i++) { sdsfree(old_values[i]); + } zfree(old_values); zfree(apply_fns); zfree(config_map_fns); @@ -973,13 +968,15 @@ void configGetCommand(client *c) { /* Create a dictionary to store the matched configs */ dict *matches = dictCreate(&externalStringType); for (i = 0; i < c->argc - 2; i++) { - robj *o = c->argv[2+i]; + robj *o = c->argv[2 + i]; sds name = o->ptr; /* If the string doesn't contain glob patterns, just directly * look up the key in the dictionary. */ if (!strpbrk(name, "[*?")) { - if (dictFind(matches, name)) continue; + if (dictFind(matches, name)) { + continue; + } standardConfig *config = lookupConfig(name); if (config) { @@ -990,23 +987,27 @@ void configGetCommand(client *c) { /* Otherwise, do a match against all items in the dictionary. */ di = dictGetIterator(configs); - + while ((de = dictNext(di)) != NULL) { standardConfig *config = dictGetVal(de); /* Note that hidden configs require an exact match (not a pattern) */ - if (config->flags & HIDDEN_CONFIG) continue; - if (dictFind(matches, config->name)) continue; + if (config->flags & HIDDEN_CONFIG) { + continue; + } + if (dictFind(matches, config->name)) { + continue; + } if (stringmatch(name, dictGetKey(de), 1)) { dictAdd(matches, dictGetKey(de), config); } } dictReleaseIterator(di); } - + di = dictGetIterator(matches); addReplyMapLen(c, dictSize(matches)); while ((de = dictNext(di)) != NULL) { - standardConfig *config = (standardConfig *) dictGetVal(de); + standardConfig *config = (standardConfig *)dictGetVal(de); addReplyBulkCString(c, dictGetKey(de)); addReplyBulkSds(c, config->interface.get(config)); } @@ -1030,23 +1031,23 @@ void dictListDestructor(dict *d, void *val); void rewriteConfigSentinelOption(struct rewriteConfigState *state); dictType optionToLineDictType = { - dictSdsCaseHash, /* hash function */ - NULL, /* key dup */ - NULL, /* val dup */ - dictSdsKeyCaseCompare, /* key compare */ - dictSdsDestructor, /* key destructor */ - dictListDestructor, /* val destructor */ - NULL /* allow to expand */ + dictSdsCaseHash, /* hash function */ + NULL, /* key dup */ + NULL, /* val dup */ + dictSdsKeyCaseCompare, /* key compare */ + dictSdsDestructor, /* key destructor */ + dictListDestructor, /* val destructor */ + NULL /* allow to expand */ }; dictType optionSetDictType = { - dictSdsCaseHash, /* hash function */ - NULL, /* key dup */ - NULL, /* val dup */ - dictSdsKeyCaseCompare, /* key compare */ - dictSdsDestructor, /* key destructor */ - NULL, /* val destructor */ - NULL /* allow to expand */ + dictSdsCaseHash, /* hash function */ + NULL, /* key dup */ + NULL, /* val dup */ + dictSdsKeyCaseCompare, /* key compare */ + dictSdsDestructor, /* key destructor */ + NULL, /* val destructor */ + NULL /* allow to expand */ }; /* The config rewrite state. */ @@ -1064,7 +1065,7 @@ struct rewriteConfigState { /* Free the configuration rewrite state. */ void rewriteConfigReleaseState(struct rewriteConfigState *state) { - sdsfreesplitres(state->lines,state->numlines); + sdsfreesplitres(state->lines, state->numlines); dictRelease(state->option_to_line); dictRelease(state->rewritten); zfree(state); @@ -1084,19 +1085,19 @@ struct rewriteConfigState *rewriteConfigCreateState(void) { /* Append the new line to the current configuration state. */ void rewriteConfigAppendLine(struct rewriteConfigState *state, sds line) { - state->lines = zrealloc(state->lines, sizeof(char*) * (state->numlines+1)); + state->lines = zrealloc(state->lines, sizeof(char *) * (state->numlines + 1)); state->lines[state->numlines++] = line; } /* Populate the option -> list of line numbers map. */ void rewriteConfigAddLineNumberToOption(struct rewriteConfigState *state, sds option, int linenum) { - list *l = dictFetchValue(state->option_to_line,option); + list *l = dictFetchValue(state->option_to_line, option); if (l == NULL) { l = listCreate(); - dictAdd(state->option_to_line,sdsdup(option),l); + dictAdd(state->option_to_line, sdsdup(option), l); } - listAddNodeTail(l,(void*)(long)linenum); + listAddNodeTail(l, (void *)(long)linenum); } /* Add the specified option to the set of processed options. @@ -1106,7 +1107,9 @@ void rewriteConfigAddLineNumberToOption(struct rewriteConfigState *state, sds op void rewriteConfigMarkAsProcessed(struct rewriteConfigState *state, const char *option) { sds opt = sdsnew(option); - if (dictAdd(state->rewritten,opt,NULL) != DICT_OK) sdsfree(opt); + if (dictAdd(state->rewritten, opt, NULL) != DICT_OK) { + sdsfree(opt); + } } /* Read the old file, split it into lines to populate a newly created @@ -1115,8 +1118,10 @@ void rewriteConfigMarkAsProcessed(struct rewriteConfigState *state, const char * * If it is impossible to read the old file, NULL is returned. * If the old file does not exist at all, an empty state is returned. */ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) { - FILE *fp = fopen(path,"r"); - if (fp == NULL && errno != ENOENT) return NULL; + FILE *fp = fopen(path, "r"); + if (fp == NULL && errno != ENOENT) { + return NULL; + } struct valkey_stat sb; if (fp && valkey_fstat(fileno(fp), &sb) == -1) { @@ -1134,11 +1139,11 @@ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) { if (sb.st_size == 0) { fclose(fp); return state; - } + } /* Load the file content */ - sds config = sdsnewlen(SDS_NOINIT,sb.st_size); - if (fread(config,1,sb.st_size,fp) == 0) { + sds config = sdsnewlen(SDS_NOINIT, sb.st_size); + if (fread(config, 1, sb.st_size, fp) == 0) { sdsfree(config); rewriteConfigReleaseState(state); fclose(fp); @@ -1146,47 +1151,46 @@ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) { } int i, totlines; - sds *lines = sdssplitlen(config,sdslen(config),"\n",1,&totlines); + sds *lines = sdssplitlen(config, sdslen(config), "\n", 1, &totlines); /* Read the old content line by line, populate the state. */ for (i = 0; i < totlines; i++) { int argc; sds *argv; - sds line = sdstrim(lines[i],"\r\n\t "); + sds line = sdstrim(lines[i], "\r\n\t "); lines[i] = NULL; linenum++; /* Zero based, so we init at -1 */ /* Handle comments and empty lines. */ if (line[0] == '#' || line[0] == '\0') { - if (state->needs_signature && !strcmp(line,CONFIG_REWRITE_SIGNATURE)) + if (state->needs_signature && !strcmp(line, CONFIG_REWRITE_SIGNATURE)) { state->needs_signature = 0; - rewriteConfigAppendLine(state,line); + } + rewriteConfigAppendLine(state, line); continue; } /* Not a comment, split into arguments. */ - argv = sdssplitargs(line,&argc); + argv = sdssplitargs(line, &argc); if (argv == NULL || (!lookupConfig(argv[0]) && /* The following is a list of config features that are only supported in * config file parsing and are not recognized by lookupConfig */ - strcasecmp(argv[0],"include") && - strcasecmp(argv[0],"rename-command") && - strcasecmp(argv[0],"user") && - strcasecmp(argv[0],"loadmodule") && - strcasecmp(argv[0],"sentinel"))) - { + strcasecmp(argv[0], "include") && strcasecmp(argv[0], "rename-command") && strcasecmp(argv[0], "user") && + strcasecmp(argv[0], "loadmodule") && strcasecmp(argv[0], "sentinel"))) { /* The line is either unparsable for some reason, for * instance it may have unbalanced quotes, may contain a * config that doesn't exist anymore, for instance a module that got * unloaded. Load it as a comment. */ sds aux = sdsnew("# ??? "); - aux = sdscatsds(aux,line); - if (argv) sdsfreesplitres(argv, argc); + aux = sdscatsds(aux, line); + if (argv) { + sdsfreesplitres(argv, argc); + } sdsfree(line); - rewriteConfigAppendLine(state,aux); + rewriteConfigAppendLine(state, aux); continue; } @@ -1194,7 +1198,7 @@ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) { /* Now we populate the state according to the content of this line. * Append the line and populate the option -> line numbers map. */ - rewriteConfigAppendLine(state,line); + rewriteConfigAppendLine(state, line); /* If this is a alias config, replace it with the original name. */ standardConfig *s_conf = lookupConfig(argv[0]); @@ -1203,20 +1207,20 @@ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) { argv[0] = sdsnew(s_conf->alias); } - /* If this is sentinel config, we use sentinel "sentinel " as option + /* If this is sentinel config, we use sentinel "sentinel " as option to avoid messing up the sequence. */ - if (server.sentinel_mode && argc > 1 && !strcasecmp(argv[0],"sentinel")) { + if (server.sentinel_mode && argc > 1 && !strcasecmp(argv[0], "sentinel")) { sds sentinelOption = sdsempty(); - sentinelOption = sdscatfmt(sentinelOption,"%S %S",argv[0],argv[1]); - rewriteConfigAddLineNumberToOption(state,sentinelOption,linenum); + sentinelOption = sdscatfmt(sentinelOption, "%S %S", argv[0], argv[1]); + rewriteConfigAddLineNumberToOption(state, sentinelOption, linenum); sdsfree(sentinelOption); } else { - rewriteConfigAddLineNumberToOption(state,argv[0],linenum); + rewriteConfigAddLineNumberToOption(state, argv[0], linenum); } - sdsfreesplitres(argv,argc); + sdsfreesplitres(argv, argc); } fclose(fp); - sdsfreesplitres(lines,totlines); + sdsfreesplitres(lines, totlines); sdsfree(config); return state; } @@ -1239,9 +1243,9 @@ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) { * in any way. */ int rewriteConfigRewriteLine(struct rewriteConfigState *state, const char *option, sds line, int force) { sds o = sdsnew(option); - list *l = dictFetchValue(state->option_to_line,o); + list *l = dictFetchValue(state->option_to_line, o); - rewriteConfigMarkAsProcessed(state,option); + rewriteConfigMarkAsProcessed(state, option); if (!l && !force && !state->force_write) { /* Option not used previously, and we are not forced to use it. */ @@ -1252,22 +1256,23 @@ int rewriteConfigRewriteLine(struct rewriteConfigState *state, const char *optio if (l) { listNode *ln = listFirst(l); - int linenum = (long) ln->value; + int linenum = (long)ln->value; /* There are still lines in the old configuration file we can reuse * for this option. Replace the line with the new one. */ - listDelNode(l,ln); - if (listLength(l) == 0) dictDelete(state->option_to_line,o); + listDelNode(l, ln); + if (listLength(l) == 0) { + dictDelete(state->option_to_line, o); + } sdsfree(state->lines[linenum]); state->lines[linenum] = line; } else { /* Append a new line. */ if (state->needs_signature) { - rewriteConfigAppendLine(state, - sdsnew(CONFIG_REWRITE_SIGNATURE)); + rewriteConfigAppendLine(state, sdsnew(CONFIG_REWRITE_SIGNATURE)); state->needs_signature = 0; } - rewriteConfigAppendLine(state,line); + rewriteConfigAppendLine(state, line); } sdsfree(o); return 1; @@ -1276,69 +1281,73 @@ int rewriteConfigRewriteLine(struct rewriteConfigState *state, const char *optio /* Write the long long 'bytes' value as a string in a way that is parsable * inside valkey.conf. If possible uses the GB, MB, KB notation. */ int rewriteConfigFormatMemory(char *buf, size_t len, long long bytes) { - int gb = 1024*1024*1024; - int mb = 1024*1024; + int gb = 1024 * 1024 * 1024; + int mb = 1024 * 1024; int kb = 1024; if (bytes && (bytes % gb) == 0) { - return snprintf(buf,len,"%lldgb",bytes/gb); + return snprintf(buf, len, "%lldgb", bytes / gb); } else if (bytes && (bytes % mb) == 0) { - return snprintf(buf,len,"%lldmb",bytes/mb); + return snprintf(buf, len, "%lldmb", bytes / mb); } else if (bytes && (bytes % kb) == 0) { - return snprintf(buf,len,"%lldkb",bytes/kb); + return snprintf(buf, len, "%lldkb", bytes / kb); } else { - return snprintf(buf,len,"%lld",bytes); + return snprintf(buf, len, "%lld", bytes); } } /* Rewrite a simple "option-name " configuration option. */ -void rewriteConfigBytesOption(struct rewriteConfigState *state, const char *option, long long value, long long defvalue) { +void rewriteConfigBytesOption(struct rewriteConfigState *state, const char *option, long long value, + long long defvalue) { char buf[64]; int force = value != defvalue; sds line; - rewriteConfigFormatMemory(buf,sizeof(buf),value); - line = sdscatprintf(sdsempty(),"%s %s",option,buf); - rewriteConfigRewriteLine(state,option,line,force); + rewriteConfigFormatMemory(buf, sizeof(buf), value); + line = sdscatprintf(sdsempty(), "%s %s", option, buf); + rewriteConfigRewriteLine(state, option, line, force); } /* Rewrite a simple "option-name n%" configuration option. */ -void rewriteConfigPercentOption(struct rewriteConfigState *state, const char *option, long long value, long long defvalue) { +void rewriteConfigPercentOption(struct rewriteConfigState *state, const char *option, long long value, + long long defvalue) { int force = value != defvalue; - sds line = sdscatprintf(sdsempty(),"%s %lld%%",option,value); + sds line = sdscatprintf(sdsempty(), "%s %lld%%", option, value); - rewriteConfigRewriteLine(state,option,line,force); + rewriteConfigRewriteLine(state, option, line, force); } /* Rewrite a yes/no option. */ void rewriteConfigYesNoOption(struct rewriteConfigState *state, const char *option, int value, int defvalue) { int force = value != defvalue; - sds line = sdscatprintf(sdsempty(),"%s %s",option, - value ? "yes" : "no"); + sds line = sdscatprintf(sdsempty(), "%s %s", option, value ? "yes" : "no"); - rewriteConfigRewriteLine(state,option,line,force); + rewriteConfigRewriteLine(state, option, line, force); } /* Rewrite a string option. */ -void rewriteConfigStringOption(struct rewriteConfigState *state, const char *option, char *value, const char *defvalue) { +void rewriteConfigStringOption(struct rewriteConfigState *state, const char *option, char *value, + const char *defvalue) { int force = 1; sds line; /* String options set to NULL need to be not present at all in the * configuration file to be set to NULL again at the next reboot. */ if (value == NULL) { - rewriteConfigMarkAsProcessed(state,option); + rewriteConfigMarkAsProcessed(state, option); return; } /* Set force to zero if the value is set to its default. */ - if (defvalue && strcmp(value,defvalue) == 0) force = 0; + if (defvalue && strcmp(value, defvalue) == 0) { + force = 0; + } line = sdsnew(option); line = sdscatlen(line, " ", 1); line = sdscatrepr(line, value, strlen(value)); - rewriteConfigRewriteLine(state,option,line,force); + rewriteConfigRewriteLine(state, option, line, force); } /* Rewrite a SDS string option. */ @@ -1354,7 +1363,9 @@ void rewriteConfigSdsOption(struct rewriteConfigState *state, const char *option } /* Set force to zero if the value is set to its default. */ - if (defvalue && strcmp(value, defvalue) == 0) force = 0; + if (defvalue && strcmp(value, defvalue) == 0) { + force = 0; + } line = sdsnew(option); line = sdscatlen(line, " ", 1); @@ -1364,19 +1375,21 @@ void rewriteConfigSdsOption(struct rewriteConfigState *state, const char *option } /* Rewrite a numerical (long long range) option. */ -void rewriteConfigNumericalOption(struct rewriteConfigState *state, const char *option, long long value, long long defvalue) { +void rewriteConfigNumericalOption(struct rewriteConfigState *state, const char *option, long long value, + long long defvalue) { int force = value != defvalue; - sds line = sdscatprintf(sdsempty(),"%s %lld",option,value); + sds line = sdscatprintf(sdsempty(), "%s %lld", option, value); - rewriteConfigRewriteLine(state,option,line,force); + rewriteConfigRewriteLine(state, option, line, force); } /* Rewrite an octal option. */ -void rewriteConfigOctalOption(struct rewriteConfigState *state, const char *option, long long value, long long defvalue) { +void rewriteConfigOctalOption(struct rewriteConfigState *state, const char *option, long long value, + long long defvalue) { int force = value != defvalue; - sds line = sdscatprintf(sdsempty(),"%s %llo",option,value); + sds line = sdscatprintf(sdsempty(), "%s %llo", option, value); - rewriteConfigRewriteLine(state,option,line,force); + rewriteConfigRewriteLine(state, option, line, force); } /* Rewrite an enumeration option. It takes as usually state and option name, @@ -1384,12 +1397,12 @@ void rewriteConfigOctalOption(struct rewriteConfigState *state, const char *opti * option. */ void rewriteConfigEnumOption(struct rewriteConfigState *state, const char *option, int value, standardConfig *config) { int multiarg = config->flags & MULTI_ARG_CONFIG; - sds names = configEnumGetName(config->data.enumd.enum_value,value,multiarg); - sds line = sdscatfmt(sdsempty(),"%s %s",option,names); + sds names = configEnumGetName(config->data.enumd.enum_value, value, multiarg); + sds line = sdscatfmt(sdsempty(), "%s %s", option, names); sdsfree(names); int force = value != config->data.enumd.default_value; - rewriteConfigRewriteLine(state,option,line,force); + rewriteConfigRewriteLine(state, option, line, force); } /* Rewrite the save option. */ @@ -1400,7 +1413,7 @@ void rewriteConfigSaveOption(standardConfig *config, const char *name, struct re /* In Sentinel mode we don't need to rewrite the save parameters */ if (server.sentinel_mode) { - rewriteConfigMarkAsProcessed(state,name); + rewriteConfigMarkAsProcessed(state, name); return; } @@ -1408,17 +1421,17 @@ void rewriteConfigSaveOption(standardConfig *config, const char *name, struct re * defaults from being used. */ if (!server.saveparamslen) { - rewriteConfigRewriteLine(state,name,sdsnew("save \"\""),1); + rewriteConfigRewriteLine(state, name, sdsnew("save \"\""), 1); } else { for (j = 0; j < server.saveparamslen; j++) { - line = sdscatprintf(sdsempty(),"save %ld %d", - (long) server.saveparams[j].seconds, server.saveparams[j].changes); - rewriteConfigRewriteLine(state,name,line,1); + line = sdscatprintf(sdsempty(), "save %ld %d", (long)server.saveparams[j].seconds, + server.saveparams[j].changes); + rewriteConfigRewriteLine(state, name, line, 1); } } /* Mark "save" as processed in case server.saveparamslen is zero. */ - rewriteConfigMarkAsProcessed(state,name); + rewriteConfigMarkAsProcessed(state, name); } /* Rewrite the user option. */ @@ -1427,7 +1440,7 @@ void rewriteConfigUserOption(struct rewriteConfigState *state) { * directive as processed, so that all the lines containing users * inside the config file gets discarded. */ if (server.acl_filename[0] != '\0') { - rewriteConfigMarkAsProcessed(state,"user"); + rewriteConfigMarkAsProcessed(state, "user"); return; } @@ -1435,22 +1448,22 @@ void rewriteConfigUserOption(struct rewriteConfigState *state) { * in case the list here is empty, the effect will just be to comment * all the users directive inside the config file. */ raxIterator ri; - raxStart(&ri,Users); - raxSeek(&ri,"^",NULL,0); - while(raxNext(&ri)) { + raxStart(&ri, Users); + raxSeek(&ri, "^", NULL, 0); + while (raxNext(&ri)) { user *u = ri.data; sds line = sdsnew("user "); - line = sdscatsds(line,u->name); - line = sdscatlen(line," ",1); + line = sdscatsds(line, u->name); + line = sdscatlen(line, " ", 1); robj *descr = ACLDescribeUser(u); - line = sdscatsds(line,descr->ptr); + line = sdscatsds(line, descr->ptr); decrRefCount(descr); - rewriteConfigRewriteLine(state,"user",line,1); + rewriteConfigRewriteLine(state, "user", line, 1); } raxStop(&ri); /* Mark "user" as processed in case there are no defined users. */ - rewriteConfigMarkAsProcessed(state,"user"); + rewriteConfigMarkAsProcessed(state, "user"); } /* Rewrite the dir option, always using absolute paths.*/ @@ -1458,11 +1471,11 @@ void rewriteConfigDirOption(standardConfig *config, const char *name, struct rew UNUSED(config); char cwd[1024]; - if (getcwd(cwd,sizeof(cwd)) == NULL) { - rewriteConfigMarkAsProcessed(state,name); + if (getcwd(cwd, sizeof(cwd)) == NULL) { + rewriteConfigMarkAsProcessed(state, name); return; /* no rewrite on error. */ } - rewriteConfigStringOption(state,name,cwd,NULL); + rewriteConfigStringOption(state, name, cwd, NULL); } /* Rewrite the slaveof option. */ @@ -1477,13 +1490,13 @@ void rewriteConfigReplicaOfOption(standardConfig *config, const char *name, stru rewriteConfigMarkAsProcessed(state, name); return; } - line = sdscatprintf(sdsempty(),"%s %s %d", name, - server.masterhost, server.masterport); - rewriteConfigRewriteLine(state,name,line,1); + line = sdscatprintf(sdsempty(), "%s %s %d", name, server.masterhost, server.masterport); + rewriteConfigRewriteLine(state, name, line, 1); } /* Rewrite the notify-keyspace-events option. */ -void rewriteConfigNotifyKeyspaceEventsOption(standardConfig *config, const char *name, struct rewriteConfigState *state) { +void rewriteConfigNotifyKeyspaceEventsOption(standardConfig *config, const char *name, + struct rewriteConfigState *state) { UNUSED(config); int force = server.notify_keyspace_events != 0; sds line, flags; @@ -1493,34 +1506,32 @@ void rewriteConfigNotifyKeyspaceEventsOption(standardConfig *config, const char line = sdscatlen(line, " ", 1); line = sdscatrepr(line, flags, sdslen(flags)); sdsfree(flags); - rewriteConfigRewriteLine(state,name,line,force); + rewriteConfigRewriteLine(state, name, line, force); } /* Rewrite the client-output-buffer-limit option. */ -void rewriteConfigClientOutputBufferLimitOption(standardConfig *config, const char *name, struct rewriteConfigState *state) { +void rewriteConfigClientOutputBufferLimitOption(standardConfig *config, const char *name, + struct rewriteConfigState *state) { UNUSED(config); int j; for (j = 0; j < CLIENT_TYPE_OBUF_COUNT; j++) { - int force = (server.client_obuf_limits[j].hard_limit_bytes != - clientBufferLimitsDefaults[j].hard_limit_bytes) || - (server.client_obuf_limits[j].soft_limit_bytes != - clientBufferLimitsDefaults[j].soft_limit_bytes) || - (server.client_obuf_limits[j].soft_limit_seconds != - clientBufferLimitsDefaults[j].soft_limit_seconds); + int force = + (server.client_obuf_limits[j].hard_limit_bytes != clientBufferLimitsDefaults[j].hard_limit_bytes) || + (server.client_obuf_limits[j].soft_limit_bytes != clientBufferLimitsDefaults[j].soft_limit_bytes) || + (server.client_obuf_limits[j].soft_limit_seconds != clientBufferLimitsDefaults[j].soft_limit_seconds); sds line; char hard[64], soft[64]; - rewriteConfigFormatMemory(hard,sizeof(hard), - server.client_obuf_limits[j].hard_limit_bytes); - rewriteConfigFormatMemory(soft,sizeof(soft), - server.client_obuf_limits[j].soft_limit_bytes); + rewriteConfigFormatMemory(hard, sizeof(hard), server.client_obuf_limits[j].hard_limit_bytes); + rewriteConfigFormatMemory(soft, sizeof(soft), server.client_obuf_limits[j].soft_limit_bytes); char *typename = getClientTypeName(j); - if (!strcmp(typename,"slave")) typename = "replica"; - line = sdscatprintf(sdsempty(),"%s %s %s %s %ld", - name, typename, hard, soft, - (long) server.client_obuf_limits[j].soft_limit_seconds); - rewriteConfigRewriteLine(state,name,line,force); + if (!strcmp(typename, "slave")) { + typename = "replica"; + } + line = sdscatprintf(sdsempty(), "%s %s %s %s %ld", name, typename, hard, soft, + (long)server.client_obuf_limits[j].soft_limit_seconds); + rewriteConfigRewriteLine(state, name, line, force); } } @@ -1534,14 +1545,16 @@ void rewriteConfigOOMScoreAdjValuesOption(standardConfig *config, const char *na line = sdsnew(name); line = sdscatlen(line, " ", 1); for (j = 0; j < CONFIG_OOM_COUNT; j++) { - if (server.oom_score_adj_values[j] != configOOMScoreAdjValuesDefaults[j]) + if (server.oom_score_adj_values[j] != configOOMScoreAdjValuesDefaults[j]) { force = 1; + } line = sdscatprintf(line, "%d", server.oom_score_adj_values[j]); - if (j+1 != CONFIG_OOM_COUNT) + if (j + 1 != CONFIG_OOM_COUNT) { line = sdscatlen(line, " ", 1); + } } - rewriteConfigRewriteLine(state,name,line,force); + rewriteConfigRewriteLine(state, name, line, force); } /* Rewrite the bind option. */ @@ -1564,21 +1577,22 @@ void rewriteConfigBindOption(standardConfig *config, const char *name, struct re } if (is_default) { - rewriteConfigMarkAsProcessed(state,name); + rewriteConfigMarkAsProcessed(state, name); return; } /* Rewrite as bind ... */ - if (server.bindaddr_count > 0) - addresses = sdsjoin(server.bindaddr,server.bindaddr_count," "); - else + if (server.bindaddr_count > 0) { + addresses = sdsjoin(server.bindaddr, server.bindaddr_count, " "); + } else { addresses = sdsnew("\"\""); + } line = sdsnew(name); line = sdscatlen(line, " ", 1); line = sdscatsds(line, addresses); sdsfree(addresses); - rewriteConfigRewriteLine(state,name,line,force); + rewriteConfigRewriteLine(state, name, line, force); } /* Rewrite the loadmodule option. */ @@ -1595,11 +1609,11 @@ void rewriteConfigLoadmoduleOption(struct rewriteConfigState *state) { line = sdscatlen(line, " ", 1); line = sdscatsds(line, module->loadmod->argv[i]->ptr); } - rewriteConfigRewriteLine(state,"loadmodule",line,1); + rewriteConfigRewriteLine(state, "loadmodule", line, 1); } dictReleaseIterator(di); /* Mark "loadmodule" as processed in case modules is empty. */ - rewriteConfigMarkAsProcessed(state,"loadmodule"); + rewriteConfigMarkAsProcessed(state, "loadmodule"); } /* Glue together the configuration lines in the current configuration @@ -1611,13 +1625,15 @@ sds rewriteConfigGetContentFromState(struct rewriteConfigState *state) { for (j = 0; j < state->numlines; j++) { /* Every cluster of empty lines is turned into a single empty line. */ if (sdslen(state->lines[j]) == 0) { - if (was_empty) continue; + if (was_empty) { + continue; + } was_empty = 1; } else { was_empty = 0; } - content = sdscatsds(content,state->lines[j]); - content = sdscatlen(content,"\n",1); + content = sdscatsds(content, state->lines[j]); + content = sdscatlen(content, "\n", 1); } return content; } @@ -1634,24 +1650,24 @@ void rewriteConfigRemoveOrphaned(struct rewriteConfigState *state) { dictIterator *di = dictGetIterator(state->option_to_line); dictEntry *de; - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { list *l = dictGetVal(de); sds option = dictGetKey(de); /* Don't blank lines about options the rewrite process * don't understand. */ - if (dictFind(state->rewritten,option) == NULL) { - serverLog(LL_DEBUG,"Not rewritten option: %s", option); + if (dictFind(state->rewritten, option) == NULL) { + serverLog(LL_DEBUG, "Not rewritten option: %s", option); continue; } - while(listLength(l)) { + while (listLength(l)) { listNode *ln = listFirst(l); - int linenum = (long) ln->value; + int linenum = (long)ln->value; sdsfree(state->lines[linenum]); state->lines[linenum] = sdsempty(); - listDelNode(l,ln); + listDelNode(l, ln); } } dictReleaseIterator(di); @@ -1661,16 +1677,18 @@ void rewriteConfigRemoveOrphaned(struct rewriteConfigState *state) { * marked with DEBUG_CONFIG, which can be used to help with debugging. */ sds getConfigDebugInfo(void) { struct rewriteConfigState *state = rewriteConfigCreateState(); - state->force_write = 1; /* Force the output */ + state->force_write = 1; /* Force the output */ state->needs_signature = 0; /* Omit the rewrite signature */ - /* Iterate the configs and "rewrite" the ones that have + /* Iterate the configs and "rewrite" the ones that have * the debug flag. */ dictIterator *di = dictGetIterator(configs); dictEntry *de; while ((de = dictNext(di)) != NULL) { standardConfig *config = dictGetVal(de); - if (!(config->flags & DEBUG_CONFIG)) continue; + if (!(config->flags & DEBUG_CONFIG)) { + continue; + } config->interface.rewrite(config, config->name, state); } dictReleaseIterator(di); @@ -1713,24 +1731,26 @@ int rewriteConfigOverwriteFile(char *configfile, sds content) { } while (offset < sdslen(content)) { - written_bytes = write(fd, content + offset, sdslen(content) - offset); - if (written_bytes <= 0) { - if (errno == EINTR) continue; /* FD is blocking, no other retryable errors */ - serverLog(LL_WARNING, "Failed after writing (%zd) bytes to tmp config file (%s)", offset, strerror(errno)); - goto cleanup; - } - offset+=written_bytes; + written_bytes = write(fd, content + offset, sdslen(content) - offset); + if (written_bytes <= 0) { + if (errno == EINTR) { + continue; /* FD is blocking, no other retryable errors */ + } + serverLog(LL_WARNING, "Failed after writing (%zd) bytes to tmp config file (%s)", offset, strerror(errno)); + goto cleanup; + } + offset += written_bytes; } - if (fsync(fd)) + if (fsync(fd)) { serverLog(LL_WARNING, "Could not sync tmp config file to disk (%s)", strerror(errno)); - else if (fchmod(fd, 0644 & ~server.umask) == -1) + } else if (fchmod(fd, 0644 & ~server.umask) == -1) { serverLog(LL_WARNING, "Could not chmod config file (%s)", strerror(errno)); - else if (rename(tmp_conffile, configfile) == -1) + } else if (rename(tmp_conffile, configfile) == -1) { serverLog(LL_WARNING, "Could not rename tmp config file (%s)", strerror(errno)); - else if (fsyncFileDir(configfile) == -1) + } else if (fsyncFileDir(configfile) == -1) { serverLog(LL_WARNING, "Could not sync config file dir (%s)", strerror(errno)); - else { + } else { retval = 0; serverLog(LL_DEBUG, "Rewritten config file (%s) successfully", configfile); } @@ -1738,7 +1758,9 @@ int rewriteConfigOverwriteFile(char *configfile, sds content) { cleanup: old_errno = errno; close(fd); - if (retval) unlink(tmp_conffile); + if (retval) { + unlink(tmp_conffile); + } errno = old_errno; return retval; } @@ -1759,8 +1781,12 @@ int rewriteConfig(char *path, int force_write) { int retval; /* Step 1: read the old config into our rewrite state. */ - if ((state = rewriteConfigReadOldFile(path)) == NULL) return -1; - if (force_write) state->force_write = 1; + if ((state = rewriteConfigReadOldFile(path)) == NULL) { + return -1; + } + if (force_write) { + state->force_write = 1; + } /* Step 2: rewrite every single option, replacing or appending it inside * the rewrite state. */ @@ -1771,8 +1797,12 @@ int rewriteConfig(char *path, int force_write) { while ((de = dictNext(di)) != NULL) { standardConfig *config = dictGetVal(de); /* Only rewrite the primary names */ - if (config->flags & ALIAS_CONFIG) continue; - if (config->interface.rewrite) config->interface.rewrite(config, dictGetKey(de), state); + if (config->flags & ALIAS_CONFIG) { + continue; + } + if (config->interface.rewrite) { + config->interface.rewrite(config, dictGetKey(de), state); + } } dictReleaseIterator(di); @@ -1780,7 +1810,9 @@ int rewriteConfig(char *path, int force_write) { rewriteConfigLoadmoduleOption(state); /* Rewrite Sentinel config if in Sentinel mode. */ - if (server.sentinel_mode) rewriteConfigSentinelOption(state); + if (server.sentinel_mode) { + rewriteConfigSentinelOption(state); + } /* Step 3: remove all the orphaned lines in the old file, that is, lines * that were used by a config option and are no longer used, like in case @@ -1790,7 +1822,7 @@ int rewriteConfig(char *path, int force_write) { /* Step 4: generate a new configuration file from the modified state * and write it into the original file. */ newcontent = rewriteConfigGetContentFromState(state); - retval = rewriteConfigOverwriteFile(server.configfile,newcontent); + retval = rewriteConfigOverwriteFile(server.configfile, newcontent); sdsfree(newcontent); rewriteConfigReleaseState(state); @@ -1803,18 +1835,11 @@ int rewriteConfig(char *path, int force_write) { #define LOADBUF_SIZE 256 static char loadbuf[LOADBUF_SIZE]; -#define embedCommonConfig(config_name, config_alias, config_flags) \ - .name = (config_name), \ - .alias = (config_alias), \ - .flags = (config_flags), +#define embedCommonConfig(config_name, config_alias, config_flags) \ + .name = (config_name), .alias = (config_alias), .flags = (config_flags), -#define embedConfigInterface(initfn, setfn, getfn, rewritefn, applyfn) .interface = { \ - .init = (initfn), \ - .set = (setfn), \ - .get = (getfn), \ - .rewrite = (rewritefn), \ - .apply = (applyfn) \ -}, +#define embedConfigInterface(initfn, setfn, getfn, rewritefn, applyfn) \ + .interface = {.init = (initfn), .set = (setfn), .get = (getfn), .rewrite = (rewritefn), .apply = (applyfn)}, /* What follows is the generic config types that are supported. To add a new * config with one of these types, add it to the standardConfig table with @@ -1840,8 +1865,9 @@ static int boolConfigSet(standardConfig *config, sds *argv, int argc, const char *err = "argument must be 'yes' or 'no'"; return 0; } - if (config->data.yesno.is_valid_fn && !config->data.yesno.is_valid_fn(yn, err)) + if (config->data.yesno.is_valid_fn && !config->data.yesno.is_valid_fn(yn, err)) { return 0; + } int prev = config->flags & MODULE_CONFIG ? getModuleBoolConfig(config->privdata) : *(config->data.yesno.config); if (prev != yn) { if (config->flags & MODULE_CONFIG) { @@ -1865,26 +1891,30 @@ static void boolConfigRewrite(standardConfig *config, const char *name, struct r rewriteConfigYesNoOption(state, name, val, config->data.yesno.default_value); } -#define createBoolConfig(name, alias, flags, config_addr, default, is_valid, apply) { \ - embedCommonConfig(name, alias, flags) \ - embedConfigInterface(boolConfigInit, boolConfigSet, boolConfigGet, boolConfigRewrite, apply) \ - .type = BOOL_CONFIG, \ - .data.yesno = { \ - .config = &(config_addr), \ - .default_value = (default), \ - .is_valid_fn = (is_valid), \ - } \ -} +#define createBoolConfig(name, alias, flags, config_addr, default, is_valid, apply) \ + { \ + embedCommonConfig(name, alias, flags) \ + embedConfigInterface(boolConfigInit, boolConfigSet, boolConfigGet, boolConfigRewrite, apply) \ + .type = BOOL_CONFIG, \ + .data.yesno = { \ + .config = &(config_addr), \ + .default_value = (default), \ + .is_valid_fn = (is_valid), \ + } \ + } /* String Configs */ static void stringConfigInit(standardConfig *config) { - *config->data.string.config = (config->data.string.convert_empty_to_null && !config->data.string.default_value) ? NULL : zstrdup(config->data.string.default_value); + *config->data.string.config = (config->data.string.convert_empty_to_null && !config->data.string.default_value) + ? NULL + : zstrdup(config->data.string.default_value); } static int stringConfigSet(standardConfig *config, sds *argv, int argc, const char **err) { UNUSED(argc); - if (config->data.string.is_valid_fn && !config->data.string.is_valid_fn(argv[0], err)) + if (config->data.string.is_valid_fn && !config->data.string.is_valid_fn(argv[0], err)) { return 0; + } char *prev = *config->data.string.config; char *new = (config->data.string.convert_empty_to_null && !argv[0][0]) ? NULL : argv[0]; if (new != prev && (new == NULL || prev == NULL || strcmp(prev, new))) { @@ -1900,18 +1930,21 @@ static sds stringConfigGet(standardConfig *config) { } static void stringConfigRewrite(standardConfig *config, const char *name, struct rewriteConfigState *state) { - rewriteConfigStringOption(state, name,*(config->data.string.config), config->data.string.default_value); + rewriteConfigStringOption(state, name, *(config->data.string.config), config->data.string.default_value); } /* SDS Configs */ static void sdsConfigInit(standardConfig *config) { - *config->data.sds.config = (config->data.sds.convert_empty_to_null && !config->data.sds.default_value) ? NULL : sdsnew(config->data.sds.default_value); + *config->data.sds.config = (config->data.sds.convert_empty_to_null && !config->data.sds.default_value) + ? NULL + : sdsnew(config->data.sds.default_value); } static int sdsConfigSet(standardConfig *config, sds *argv, int argc, const char **err) { UNUSED(argc); - if (config->data.sds.is_valid_fn && !config->data.sds.is_valid_fn(argv[0], err)) + if (config->data.sds.is_valid_fn && !config->data.sds.is_valid_fn(argv[0], err)) { return 0; + } sds prev = config->flags & MODULE_CONFIG ? getModuleStringConfig(config->privdata) : *config->data.sds.config; sds new = (config->data.string.convert_empty_to_null && (sdslen(argv[0]) == 0)) ? NULL : argv[0]; @@ -1928,14 +1961,18 @@ static int sdsConfigSet(standardConfig *config, sds *argv, int argc, const char *config->data.sds.config = new != NULL ? sdsdup(new) : NULL; return 1; } - if (config->flags & MODULE_CONFIG && prev) sdsfree(prev); + if (config->flags & MODULE_CONFIG && prev) { + sdsfree(prev); + } return (config->flags & VOLATILE_CONFIG) ? 1 : 2; } static sds sdsConfigGet(standardConfig *config) { sds val = config->flags & MODULE_CONFIG ? getModuleStringConfig(config->privdata) : *config->data.sds.config; if (val) { - if (config->flags & MODULE_CONFIG) return val; + if (config->flags & MODULE_CONFIG) { + return val; + } return sdsdup(val); } else { return sdsnew(""); @@ -1945,36 +1982,40 @@ static sds sdsConfigGet(standardConfig *config) { static void sdsConfigRewrite(standardConfig *config, const char *name, struct rewriteConfigState *state) { sds val = config->flags & MODULE_CONFIG ? getModuleStringConfig(config->privdata) : *config->data.sds.config; rewriteConfigSdsOption(state, name, val, config->data.sds.default_value); - if ((val) && (config->flags & MODULE_CONFIG)) sdsfree(val); + if ((val) && (config->flags & MODULE_CONFIG)) { + sdsfree(val); + } } #define ALLOW_EMPTY_STRING 0 #define EMPTY_STRING_IS_NULL 1 -#define createStringConfig(name, alias, flags, empty_to_null, config_addr, default, is_valid, apply) { \ - embedCommonConfig(name, alias, flags) \ - embedConfigInterface(stringConfigInit, stringConfigSet, stringConfigGet, stringConfigRewrite, apply) \ - .type = STRING_CONFIG, \ - .data.string = { \ - .config = &(config_addr), \ - .default_value = (default), \ - .is_valid_fn = (is_valid), \ - .convert_empty_to_null = (empty_to_null), \ - } \ -} - -#define createSDSConfig(name, alias, flags, empty_to_null, config_addr, default, is_valid, apply) { \ - embedCommonConfig(name, alias, flags) \ - embedConfigInterface(sdsConfigInit, sdsConfigSet, sdsConfigGet, sdsConfigRewrite, apply) \ - .type = SDS_CONFIG, \ - .data.sds = { \ - .config = &(config_addr), \ - .default_value = (default), \ - .is_valid_fn = (is_valid), \ - .convert_empty_to_null = (empty_to_null), \ - } \ -} +#define createStringConfig(name, alias, flags, empty_to_null, config_addr, default, is_valid, apply) \ + { \ + embedCommonConfig(name, alias, flags) \ + embedConfigInterface(stringConfigInit, stringConfigSet, stringConfigGet, stringConfigRewrite, apply) \ + .type = STRING_CONFIG, \ + .data.string = { \ + .config = &(config_addr), \ + .default_value = (default), \ + .is_valid_fn = (is_valid), \ + .convert_empty_to_null = (empty_to_null), \ + } \ + } + +#define createSDSConfig(name, alias, flags, empty_to_null, config_addr, default, is_valid, apply) \ + { \ + embedCommonConfig(name, alias, flags) \ + embedConfigInterface(sdsConfigInit, sdsConfigSet, sdsConfigGet, sdsConfigRewrite, apply) \ + .type = SDS_CONFIG, \ + .data.sds = { \ + .config = &(config_addr), \ + .default_value = (default), \ + .is_valid_fn = (is_valid), \ + .convert_empty_to_null = (empty_to_null), \ + } \ + } /* Enum configs */ static void enumConfigInit(standardConfig *config) { @@ -1989,13 +2030,12 @@ static int enumConfigSet(standardConfig *config, sds *argv, int argc, const char if (enumval == INT_MIN) { sds enumerr = sdsnew("argument(s) must be one of the following: "); configEnum *enumNode = config->data.enumd.enum_value; - while(enumNode->name != NULL) { - enumerr = sdscatlen(enumerr, enumNode->name, - strlen(enumNode->name)); + while (enumNode->name != NULL) { + enumerr = sdscatlen(enumerr, enumNode->name, strlen(enumNode->name)); enumerr = sdscatlen(enumerr, ", ", 2); enumNode++; } - sdsrange(enumerr,0,-3); /* Remove final ", ". */ + sdsrange(enumerr, 0, -3); /* Remove final ", ". */ valkey_strlcpy(loadbuf, enumerr, LOADBUF_SIZE); @@ -2003,12 +2043,14 @@ static int enumConfigSet(standardConfig *config, sds *argv, int argc, const char *err = loadbuf; return 0; } - if (config->data.enumd.is_valid_fn && !config->data.enumd.is_valid_fn(enumval, err)) + if (config->data.enumd.is_valid_fn && !config->data.enumd.is_valid_fn(enumval, err)) { return 0; + } int prev = config->flags & MODULE_CONFIG ? getModuleEnumConfig(config->privdata) : *(config->data.enumd.config); if (prev != enumval) { - if (config->flags & MODULE_CONFIG) + if (config->flags & MODULE_CONFIG) { return setModuleEnumConfig(config->privdata, enumval, err); + } *(config->data.enumd.config) = enumval; return 1; } @@ -2018,7 +2060,7 @@ static int enumConfigSet(standardConfig *config, sds *argv, int argc, const char static sds enumConfigGet(standardConfig *config) { int val = config->flags & MODULE_CONFIG ? getModuleEnumConfig(config->privdata) : *(config->data.enumd.config); int bitflags = !!(config->flags & MULTI_ARG_CONFIG); - return configEnumGetName(config->data.enumd.enum_value,val,bitflags); + return configEnumGetName(config->data.enumd.enum_value, val, bitflags); } static void enumConfigRewrite(standardConfig *config, const char *name, struct rewriteConfigState *state) { @@ -2026,71 +2068,76 @@ static void enumConfigRewrite(standardConfig *config, const char *name, struct r rewriteConfigEnumOption(state, name, val, config); } -#define createEnumConfig(name, alias, flags, enum, config_addr, default, is_valid, apply) { \ - embedCommonConfig(name, alias, flags) \ - embedConfigInterface(enumConfigInit, enumConfigSet, enumConfigGet, enumConfigRewrite, apply) \ - .type = ENUM_CONFIG, \ - .data.enumd = { \ - .config = &(config_addr), \ - .default_value = (default), \ - .is_valid_fn = (is_valid), \ - .enum_value = (enum), \ - } \ -} +#define createEnumConfig(name, alias, flags, enum, config_addr, default, is_valid, apply) \ + { \ + embedCommonConfig(name, alias, flags) \ + embedConfigInterface(enumConfigInit, enumConfigSet, enumConfigGet, enumConfigRewrite, apply) \ + .type = ENUM_CONFIG, \ + .data.enumd = { \ + .config = &(config_addr), \ + .default_value = (default), \ + .is_valid_fn = (is_valid), \ + .enum_value = (enum), \ + } \ + } /* Gets a 'long long val' and sets it into the union, using a macro to get * compile time type check. */ int setNumericType(standardConfig *config, long long val, const char **err) { if (config->data.numeric.numeric_type == NUMERIC_TYPE_INT) { - *(config->data.numeric.config.i) = (int) val; + *(config->data.numeric.config.i) = (int)val; } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_UINT) { - *(config->data.numeric.config.ui) = (unsigned int) val; + *(config->data.numeric.config.ui) = (unsigned int)val; } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_LONG) { - *(config->data.numeric.config.l) = (long) val; + *(config->data.numeric.config.l) = (long)val; } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_ULONG) { - *(config->data.numeric.config.ul) = (unsigned long) val; + *(config->data.numeric.config.ul) = (unsigned long)val; } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_LONG_LONG) { - if (config->flags & MODULE_CONFIG) + if (config->flags & MODULE_CONFIG) { return setModuleNumericConfig(config->privdata, val, err); - else *(config->data.numeric.config.ll) = (long long) val; + } else { + *(config->data.numeric.config.ll) = (long long)val; + } } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_ULONG_LONG) { - *(config->data.numeric.config.ull) = (unsigned long long) val; + *(config->data.numeric.config.ull) = (unsigned long long)val; } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_SIZE_T) { - *(config->data.numeric.config.st) = (size_t) val; + *(config->data.numeric.config.st) = (size_t)val; } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_SSIZE_T) { - *(config->data.numeric.config.sst) = (ssize_t) val; + *(config->data.numeric.config.sst) = (ssize_t)val; } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_OFF_T) { - *(config->data.numeric.config.ot) = (off_t) val; + *(config->data.numeric.config.ot) = (off_t)val; } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_TIME_T) { - *(config->data.numeric.config.tt) = (time_t) val; + *(config->data.numeric.config.tt) = (time_t)val; } return 1; } /* Gets a 'long long val' and sets it with the value from the union, using a * macro to get compile time type check. */ -#define GET_NUMERIC_TYPE(val) \ - if (config->data.numeric.numeric_type == NUMERIC_TYPE_INT) { \ - val = *(config->data.numeric.config.i); \ - } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_UINT) { \ - val = *(config->data.numeric.config.ui); \ - } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_LONG) { \ - val = *(config->data.numeric.config.l); \ - } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_ULONG) { \ - val = *(config->data.numeric.config.ul); \ - } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_LONG_LONG) { \ - if (config->flags & MODULE_CONFIG) val = getModuleNumericConfig(config->privdata); \ - else val = *(config->data.numeric.config.ll); \ - } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_ULONG_LONG) { \ - val = *(config->data.numeric.config.ull); \ - } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_SIZE_T) { \ - val = *(config->data.numeric.config.st); \ - } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_SSIZE_T) { \ - val = *(config->data.numeric.config.sst); \ - } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_OFF_T) { \ - val = *(config->data.numeric.config.ot); \ - } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_TIME_T) { \ - val = *(config->data.numeric.config.tt); \ +#define GET_NUMERIC_TYPE(val) \ + if (config->data.numeric.numeric_type == NUMERIC_TYPE_INT) { \ + val = *(config->data.numeric.config.i); \ + } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_UINT) { \ + val = *(config->data.numeric.config.ui); \ + } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_LONG) { \ + val = *(config->data.numeric.config.l); \ + } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_ULONG) { \ + val = *(config->data.numeric.config.ul); \ + } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_LONG_LONG) { \ + if (config->flags & MODULE_CONFIG) \ + val = getModuleNumericConfig(config->privdata); \ + else \ + val = *(config->data.numeric.config.ll); \ + } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_ULONG_LONG) { \ + val = *(config->data.numeric.config.ull); \ + } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_SIZE_T) { \ + val = *(config->data.numeric.config.st); \ + } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_SSIZE_T) { \ + val = *(config->data.numeric.config.sst); \ + } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_OFF_T) { \ + val = *(config->data.numeric.config.ot); \ + } else if (config->data.numeric.numeric_type == NUMERIC_TYPE_TIME_T) { \ + val = *(config->data.numeric.config.tt); \ } /* Numeric configs */ @@ -2108,15 +2155,11 @@ static int numericBoundaryCheck(standardConfig *config, long long ll, const char unsigned long long lower_bound = config->data.numeric.lower_bound; if (ull > upper_bound || ull < lower_bound) { if (config->data.numeric.flags & OCTAL_CONFIG) { - snprintf(loadbuf, LOADBUF_SIZE, - "argument must be between %llo and %llo inclusive", - lower_bound, - upper_bound); + snprintf(loadbuf, LOADBUF_SIZE, "argument must be between %llo and %llo inclusive", lower_bound, + upper_bound); } else { - snprintf(loadbuf, LOADBUF_SIZE, - "argument must be between %llu and %llu inclusive", - lower_bound, - upper_bound); + snprintf(loadbuf, LOADBUF_SIZE, "argument must be between %llu and %llu inclusive", lower_bound, + upper_bound); } *err = loadbuf; return 0; @@ -2125,8 +2168,7 @@ static int numericBoundaryCheck(standardConfig *config, long long ll, const char /* Boundary check for percentages */ if (config->data.numeric.flags & PERCENT_CONFIG && ll < 0) { if (ll < config->data.numeric.lower_bound) { - snprintf(loadbuf, LOADBUF_SIZE, - "percentage argument must be less or equal to %lld", + snprintf(loadbuf, LOADBUF_SIZE, "percentage argument must be less or equal to %lld", -config->data.numeric.lower_bound); *err = loadbuf; return 0; @@ -2134,10 +2176,8 @@ static int numericBoundaryCheck(standardConfig *config, long long ll, const char } /* Boundary check for signed types */ else if (ll > config->data.numeric.upper_bound || ll < config->data.numeric.lower_bound) { - snprintf(loadbuf, LOADBUF_SIZE, - "argument must be between %lld and %lld inclusive", - config->data.numeric.lower_bound, - config->data.numeric.upper_bound); + snprintf(loadbuf, LOADBUF_SIZE, "argument must be between %lld and %lld inclusive", + config->data.numeric.lower_bound, config->data.numeric.upper_bound); *err = loadbuf; return 0; } @@ -2150,18 +2190,17 @@ static int numericParseString(standardConfig *config, sds value, const char **er if (config->data.numeric.flags & MEMORY_CONFIG) { int memerr; *res = memtoull(value, &memerr); - if (!memerr) + if (!memerr) { return 1; + } } /* Attempt to parse as percent */ - if (config->data.numeric.flags & PERCENT_CONFIG && - sdslen(value) > 1 && value[sdslen(value)-1] == '%' && - string2ll(value, sdslen(value)-1, res) && - *res >= 0) { - /* We store percentage as negative value */ - *res = -*res; - return 1; + if (config->data.numeric.flags & PERCENT_CONFIG && sdslen(value) > 1 && value[sdslen(value) - 1] == '%' && + string2ll(value, sdslen(value) - 1, res) && *res >= 0) { + /* We store percentage as negative value */ + *res = -*res; + return 1; } /* Attempt to parse as an octal number */ @@ -2169,24 +2208,26 @@ static int numericParseString(standardConfig *config, sds value, const char **er char *endptr; errno = 0; *res = strtoll(value, &endptr, 8); - if (errno == 0 && *endptr == '\0') + if (errno == 0 && *endptr == '\0') { return 1; /* No overflow or invalid characters */ + } } /* Attempt a simple number (no special flags set) */ - if (!config->data.numeric.flags && string2ll(value, sdslen(value), res)) + if (!config->data.numeric.flags && string2ll(value, sdslen(value), res)) { return 1; + } /* Select appropriate error string */ - if (config->data.numeric.flags & MEMORY_CONFIG && - config->data.numeric.flags & PERCENT_CONFIG) - *err = "argument must be a memory or percent value" ; - else if (config->data.numeric.flags & MEMORY_CONFIG) + if (config->data.numeric.flags & MEMORY_CONFIG && config->data.numeric.flags & PERCENT_CONFIG) { + *err = "argument must be a memory or percent value"; + } else if (config->data.numeric.flags & MEMORY_CONFIG) { *err = "argument must be a memory value"; - else if (config->data.numeric.flags & OCTAL_CONFIG) + } else if (config->data.numeric.flags & OCTAL_CONFIG) { *err = "argument couldn't be parsed as an octal number"; - else + } else { *err = "argument couldn't be parsed into an integer"; + } return 0; } @@ -2194,14 +2235,17 @@ static int numericConfigSet(standardConfig *config, sds *argv, int argc, const c UNUSED(argc); long long ll, prev = 0; - if (!numericParseString(config, argv[0], err, &ll)) + if (!numericParseString(config, argv[0], err, &ll)) { return 0; + } - if (!numericBoundaryCheck(config, ll, err)) + if (!numericBoundaryCheck(config, ll, err)) { return 0; + } - if (config->data.numeric.is_valid_fn && !config->data.numeric.is_valid_fn(ll, err)) + if (config->data.numeric.is_valid_fn && !config->data.numeric.is_valid_fn(ll, err)) { return 0; + } GET_NUMERIC_TYPE(prev) if (prev != ll) { @@ -2220,9 +2264,8 @@ static sds numericConfigGet(standardConfig *config) { if (config->data.numeric.flags & PERCENT_CONFIG && value < 0) { int len = ll2string(buf, sizeof(buf), -value); buf[len] = '%'; - buf[len+1] = '\0'; - } - else if (config->data.numeric.flags & MEMORY_CONFIG) { + buf[len + 1] = '\0'; + } else if (config->data.numeric.flags & MEMORY_CONFIG) { ull2string(buf, sizeof(buf), value); } else if (config->data.numeric.flags & OCTAL_CONFIG) { snprintf(buf, sizeof(buf), "%llo", value); @@ -2248,92 +2291,104 @@ static void numericConfigRewrite(standardConfig *config, const char *name, struc } } -#define embedCommonNumericalConfig(name, alias, _flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) { \ - embedCommonConfig(name, alias, _flags) \ - embedConfigInterface(numericConfigInit, numericConfigSet, numericConfigGet, numericConfigRewrite, apply) \ - .type = NUMERIC_CONFIG, \ - .data.numeric = { \ - .lower_bound = (lower), \ - .upper_bound = (upper), \ - .default_value = (default), \ - .is_valid_fn = (is_valid), \ - .flags = (num_conf_flags), +#define embedCommonNumericalConfig(name, alias, _flags, lower, upper, config_addr, default, num_conf_flags, is_valid, \ + apply) \ + { \ + embedCommonConfig(name, alias, _flags) \ + embedConfigInterface(numericConfigInit, numericConfigSet, numericConfigGet, numericConfigRewrite, apply) \ + .type = NUMERIC_CONFIG, \ + .data.numeric = { \ + .lower_bound = (lower), \ + .upper_bound = (upper), \ + .default_value = (default), \ + .is_valid_fn = (is_valid), \ + .flags = (num_conf_flags), -#define createIntConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - .numeric_type = NUMERIC_TYPE_INT, \ - .config.i = &(config_addr) \ - } \ -} +#define createIntConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ + embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, \ + apply) \ + .numeric_type = NUMERIC_TYPE_INT, \ + .config.i = &(config_addr) \ + } \ + } -#define createUIntConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - .numeric_type = NUMERIC_TYPE_UINT, \ - .config.ui = &(config_addr) \ - } \ -} +#define createUIntConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ + embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, \ + apply) \ + .numeric_type = NUMERIC_TYPE_UINT, \ + .config.ui = &(config_addr) \ + } \ + } -#define createLongConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - .numeric_type = NUMERIC_TYPE_LONG, \ - .config.l = &(config_addr) \ - } \ -} +#define createLongConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ + embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, \ + apply) \ + .numeric_type = NUMERIC_TYPE_LONG, \ + .config.l = &(config_addr) \ + } \ + } -#define createULongConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - .numeric_type = NUMERIC_TYPE_ULONG, \ - .config.ul = &(config_addr) \ - } \ -} +#define createULongConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ + embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, \ + apply) \ + .numeric_type = NUMERIC_TYPE_ULONG, \ + .config.ul = &(config_addr) \ + } \ + } -#define createLongLongConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - .numeric_type = NUMERIC_TYPE_LONG_LONG, \ - .config.ll = &(config_addr) \ - } \ -} +#define createLongLongConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ + embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, \ + apply) \ + .numeric_type = NUMERIC_TYPE_LONG_LONG, \ + .config.ll = &(config_addr) \ + } \ + } #define createULongLongConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - .numeric_type = NUMERIC_TYPE_ULONG_LONG, \ - .config.ull = &(config_addr) \ - } \ -} + embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, \ + apply) \ + .numeric_type = NUMERIC_TYPE_ULONG_LONG, \ + .config.ull = &(config_addr) \ + } \ + } -#define createSizeTConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - .numeric_type = NUMERIC_TYPE_SIZE_T, \ - .config.st = &(config_addr) \ - } \ -} +#define createSizeTConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ + embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, \ + apply) \ + .numeric_type = NUMERIC_TYPE_SIZE_T, \ + .config.st = &(config_addr) \ + } \ + } -#define createSSizeTConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - .numeric_type = NUMERIC_TYPE_SSIZE_T, \ - .config.sst = &(config_addr) \ - } \ -} +#define createSSizeTConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ + embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, \ + apply) \ + .numeric_type = NUMERIC_TYPE_SSIZE_T, \ + .config.sst = &(config_addr) \ + } \ + } -#define createTimeTConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - .numeric_type = NUMERIC_TYPE_TIME_T, \ - .config.tt = &(config_addr) \ - } \ -} +#define createTimeTConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ + embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, \ + apply) \ + .numeric_type = NUMERIC_TYPE_TIME_T, \ + .config.tt = &(config_addr) \ + } \ + } -#define createOffTConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ - .numeric_type = NUMERIC_TYPE_OFF_T, \ - .config.ot = &(config_addr) \ - } \ -} +#define createOffTConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, apply) \ + embedCommonNumericalConfig(name, alias, flags, lower, upper, config_addr, default, num_conf_flags, is_valid, \ + apply) \ + .numeric_type = NUMERIC_TYPE_OFF_T, \ + .config.ot = &(config_addr) \ + } \ + } -#define createSpecialConfig(name, alias, modifiable, setfn, getfn, rewritefn, applyfn) { \ - .type = SPECIAL_CONFIG, \ - embedCommonConfig(name, alias, modifiable) \ - embedConfigInterface(NULL, setfn, getfn, rewritefn, applyfn) \ -} +#define createSpecialConfig(name, alias, modifiable, setfn, getfn, rewritefn, applyfn) \ + { \ + .type = SPECIAL_CONFIG, \ + embedCommonConfig(name, alias, modifiable) embedConfigInterface(NULL, setfn, getfn, rewritefn, applyfn) \ + } static int isValidActiveDefrag(int val, const char **err) { #ifndef HAVE_DEFRAG @@ -2393,8 +2448,8 @@ static int isValidShutdownOnSigFlags(int val, const char **err) { return 1; } -static int isValidAnnouncedNodename(char *val,const char **err) { - if (!(isValidAuxString(val,sdslen(val)))) { +static int isValidAnnouncedNodename(char *val, const char **err) { + if (!(isValidAuxString(val, sdslen(val)))) { *err = "Announced human node name contained invalid character"; return 0; } @@ -2403,8 +2458,7 @@ static int isValidAnnouncedNodename(char *val,const char **err) { static int isValidAnnouncedHostname(char *val, const char **err) { if (strlen(val) >= NET_HOST_STR_LEN) { - *err = "Hostnames must be less than " - STRINGIFY(NET_HOST_STR_LEN) " characters"; + *err = "Hostnames must be less than " STRINGIFY(NET_HOST_STR_LEN) " characters"; return 0; } @@ -2413,11 +2467,9 @@ static int isValidAnnouncedHostname(char *val, const char **err) { while ((c = val[i])) { /* We just validate the character set to make sure that everything * is parsed and handled correctly. */ - if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') - || (c >= '0' && c <= '9') || (c == '-') || (c == '.'))) - { + if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '-') || (c == '.'))) { *err = "Hostnames may only contain alphanumeric characters, " - "hyphens or dots"; + "hyphens or dots"; return 0; } c = val[i++]; @@ -2455,8 +2507,12 @@ static int updateHZ(const char **err) { UNUSED(err); /* Hz is more a hint from the user, so we accept values out of range * but cap them to reasonable values. */ - if (server.config_hz < CONFIG_MIN_HZ) server.config_hz = CONFIG_MIN_HZ; - if (server.config_hz > CONFIG_MAX_HZ) server.config_hz = CONFIG_MAX_HZ; + if (server.config_hz < CONFIG_MIN_HZ) { + server.config_hz = CONFIG_MIN_HZ; + } + if (server.config_hz > CONFIG_MAX_HZ) { + server.config_hz = CONFIG_MAX_HZ; + } server.hz = server.config_hz; return 1; } @@ -2498,9 +2554,13 @@ static int updateReplBacklogSize(const char **err) { static int updateMaxmemory(const char **err) { UNUSED(err); if (server.maxmemory) { - size_t used = zmalloc_used_memory()-freeMemoryGetNotCountedMemory(); + size_t used = zmalloc_used_memory() - freeMemoryGetNotCountedMemory(); if (server.maxmemory < used) { - serverLog(LL_WARNING,"WARNING: the new maxmemory value set via CONFIG SET (%llu) is smaller than the current memory usage (%zu). This will result in key eviction and/or the inability to accept new write commands depending on the maxmemory-policy.", server.maxmemory, used); + serverLog(LL_WARNING, + "WARNING: the new maxmemory value set via CONFIG SET (%llu) is smaller than the current memory " + "usage (%zu). This will result in key eviction and/or the inability to accept new write commands " + "depending on the maxmemory-policy.", + server.maxmemory, used); } startEvictionTimeProc(); } @@ -2548,10 +2608,11 @@ static int updateExtendedRedisCompat(const char **err) { static int updateSighandlerEnabled(const char **err) { UNUSED(err); - if (server.crashlog_enabled) + if (server.crashlog_enabled) { setupSigSegvHandler(); - else + } else { removeSigSegvHandlers(); + } return 1; } @@ -2560,16 +2621,14 @@ static int updateMaxclients(const char **err) { adjustOpenFilesLimit(); if (server.maxclients != new_maxclients) { static char msg[128]; - snprintf(msg, sizeof(msg), "The operating system is not able to handle the specified number of clients, try with %d", server.maxclients); + snprintf(msg, sizeof(msg), + "The operating system is not able to handle the specified number of clients, try with %d", + server.maxclients); *err = msg; return 0; } - if ((unsigned int) aeGetSetSize(server.el) < - server.maxclients + CONFIG_FDSET_INCR) - { - if (aeResizeSetSize(server.el, - server.maxclients + CONFIG_FDSET_INCR) == AE_ERR) - { + if ((unsigned int)aeGetSetSize(server.el) < server.maxclients + CONFIG_FDSET_INCR) { + if (aeResizeSetSize(server.el, server.maxclients + CONFIG_FDSET_INCR) == AE_ERR) { *err = "The event loop API is not able to handle the specified number of clients"; return 0; } @@ -2619,8 +2678,9 @@ static int applyBind(const char **err) { tcp_listener->ct = connectionByType(CONN_TYPE_SOCKET); if (changeListener(tcp_listener) == C_ERR) { *err = "Failed to bind to specified addresses."; - if (tls_listener) + if (tls_listener) { closeListener(tls_listener); /* failed with TLS together */ + } return 0; } @@ -2674,8 +2734,8 @@ static int applyTlsCfg(const char **err) { UNUSED(err); /* If TLS is enabled, try to configure OpenSSL. */ - if ((server.tls_port || server.tls_replication || server.tls_cluster) - && connTypeConfigure(connectionTypeTls(), &server.tls_ctx_config, 1) == C_ERR) { + if ((server.tls_port || server.tls_replication || server.tls_cluster) && + connTypeConfigure(connectionTypeTls(), &server.tls_ctx_config, 1) == C_ERR) { *err = "Unable to update TLS configuration. Check server logs."; return 0; } @@ -2720,8 +2780,9 @@ static sds getConfigDirOption(standardConfig *config) { UNUSED(config); char buf[1024]; - if (getcwd(buf,sizeof(buf)) == NULL) + if (getcwd(buf, sizeof(buf)) == NULL) { buf[0] = '\0'; + } return sdsnew(buf); } @@ -2731,14 +2792,14 @@ static int setConfigSaveOption(standardConfig *config, sds *argv, int argc, cons int j; /* Special case: treat single arg "" as zero args indicating empty save configuration */ - if (argc == 1 && !strcasecmp(argv[0],"")) { + if (argc == 1 && !strcasecmp(argv[0], "")) { resetServerSaveParams(); argc = 0; } /* Perform sanity check before setting the new config: - * - Even number of args - * - Seconds >= 1, changes >= 0 */ + * - Even number of args + * - Seconds >= 1, changes >= 0 */ if (argc & 1) { *err = "Invalid save parameters"; return 0; @@ -2748,9 +2809,7 @@ static int setConfigSaveOption(standardConfig *config, sds *argv, int argc, cons long val; val = strtoll(argv[j], &eptr, 10); - if (eptr[0] != '\0' || - ((j & 1) == 0 && val < 1) || - ((j & 1) == 1 && val < 0)) { + if (eptr[0] != '\0' || ((j & 1) == 0 && val < 1) || ((j & 1) == 1 && val < 0)) { *err = "Invalid save parameters"; return 0; } @@ -2773,8 +2832,8 @@ static int setConfigSaveOption(standardConfig *config, sds *argv, int argc, cons time_t seconds; int changes; - seconds = strtoll(argv[j],NULL,10); - changes = strtoll(argv[j+1],NULL,10); + seconds = strtoll(argv[j], NULL, 10); + changes = strtoll(argv[j + 1], NULL, 10); appendServerSaveParams(seconds, changes); } @@ -2787,11 +2846,10 @@ static sds getConfigSaveOption(standardConfig *config) { int j; for (j = 0; j < server.saveparamslen; j++) { - buf = sdscatprintf(buf,"%jd %d", - (intmax_t)server.saveparams[j].seconds, - server.saveparams[j].changes); - if (j != server.saveparamslen-1) - buf = sdscatlen(buf," ",1); + buf = sdscatprintf(buf, "%jd %d", (intmax_t)server.saveparams[j].seconds, server.saveparams[j].changes); + if (j != server.saveparamslen - 1) { + buf = sdscatlen(buf, " ", 1); + } } return buf; @@ -2807,13 +2865,12 @@ static sds getConfigClientOutputBufferLimitOption(standardConfig *config) { sds buf = sdsempty(); int j; for (j = 0; j < CLIENT_TYPE_OBUF_COUNT; j++) { - buf = sdscatprintf(buf,"%s %llu %llu %ld", - getClientTypeName(j), - server.client_obuf_limits[j].hard_limit_bytes, + buf = sdscatprintf(buf, "%s %llu %llu %ld", getClientTypeName(j), server.client_obuf_limits[j].hard_limit_bytes, server.client_obuf_limits[j].soft_limit_bytes, - (long) server.client_obuf_limits[j].soft_limit_seconds); - if (j != CLIENT_TYPE_OBUF_COUNT-1) - buf = sdscatlen(buf," ",1); + (long)server.client_obuf_limits[j].soft_limit_seconds); + if (j != CLIENT_TYPE_OBUF_COUNT - 1) { + buf = sdscatlen(buf, " ", 1); + } } return buf; } @@ -2837,7 +2894,9 @@ static int setConfigOOMScoreAdjValuesOption(standardConfig *config, sds *argv, i long long val = strtoll(argv[i], &eptr, 10); if (*eptr != '\0' || val < -2000 || val > 2000) { - if (err) *err = "Invalid oom-score-adj-values, elements must be between -2000 and 2000."; + if (err) { + *err = "Invalid oom-score-adj-values, elements must be between -2000 and 2000."; + } return 0; } @@ -2849,11 +2908,9 @@ static int setConfigOOMScoreAdjValuesOption(standardConfig *config, sds *argv, i */ if (values[CONFIG_OOM_REPLICA] < values[CONFIG_OOM_MASTER] || - values[CONFIG_OOM_BGCHILD] < values[CONFIG_OOM_REPLICA]) - { - serverLog(LL_WARNING, - "The oom-score-adj-values configuration may not work for non-privileged processes! " - "Please consult the documentation."); + values[CONFIG_OOM_BGCHILD] < values[CONFIG_OOM_REPLICA]) { + serverLog(LL_WARNING, "The oom-score-adj-values configuration may not work for non-privileged processes! " + "Please consult the documentation."); } for (i = 0; i < CONFIG_OOM_COUNT; i++) { @@ -2872,9 +2929,10 @@ static sds getConfigOOMScoreAdjValuesOption(standardConfig *config) { int j; for (j = 0; j < CONFIG_OOM_COUNT; j++) { - buf = sdscatprintf(buf,"%d", server.oom_score_adj_values[j]); - if (j != CONFIG_OOM_COUNT-1) - buf = sdscatlen(buf," ",1); + buf = sdscatprintf(buf, "%d", server.oom_score_adj_values[j]); + if (j != CONFIG_OOM_COUNT - 1) { + buf = sdscatlen(buf, " ", 1); + } } return buf; @@ -2900,7 +2958,7 @@ static sds getConfigNotifyKeyspaceEventsOption(standardConfig *config) { return keyspaceEventsFlagsToString(server.notify_keyspace_events); } -static int setConfigBindOption(standardConfig *config, sds* argv, int argc, const char **err) { +static int setConfigBindOption(standardConfig *config, sds *argv, int argc, const char **err) { UNUSED(config); int j; @@ -2910,20 +2968,23 @@ static int setConfigBindOption(standardConfig *config, sds* argv, int argc, cons } /* A single empty argument is treated as a zero bindaddr count */ - if (argc == 1 && sdslen(argv[0]) == 0) argc = 0; + if (argc == 1 && sdslen(argv[0]) == 0) { + argc = 0; + } /* Free old bind addresses */ for (j = 0; j < server.bindaddr_count; j++) { zfree(server.bindaddr[j]); } - for (j = 0; j < argc; j++) + for (j = 0; j < argc; j++) { server.bindaddr[j] = zstrdup(argv[j]); + } server.bindaddr_count = argc; return 1; } -static int setConfigReplicaOfOption(standardConfig *config, sds* argv, int argc, const char **err) { +static int setConfigReplicaOfOption(standardConfig *config, sds *argv, int argc, const char **err) { UNUSED(config); if (argc != 2) { @@ -2949,17 +3010,17 @@ static int setConfigReplicaOfOption(standardConfig *config, sds* argv, int argc, static sds getConfigBindOption(standardConfig *config) { UNUSED(config); - return sdsjoin(server.bindaddr,server.bindaddr_count," "); + return sdsjoin(server.bindaddr, server.bindaddr_count, " "); } static sds getConfigReplicaOfOption(standardConfig *config) { UNUSED(config); char buf[256]; - if (server.masterhost) - snprintf(buf,sizeof(buf),"%s %d", - server.masterhost, server.masterport); - else + if (server.masterhost) { + snprintf(buf, sizeof(buf), "%s %d", server.masterhost, server.masterport); + } else { buf[0] = '\0'; + } return sdsnew(buf); } @@ -2969,17 +3030,19 @@ int allowProtectedAction(int config, client *c) { } -static int setConfigLatencyTrackingInfoPercentilesOutputOption(standardConfig *config, sds *argv, int argc, const char **err) { +static int setConfigLatencyTrackingInfoPercentilesOutputOption(standardConfig *config, sds *argv, int argc, + const char **err) { UNUSED(config); zfree(server.latency_tracking_info_percentiles); server.latency_tracking_info_percentiles = NULL; server.latency_tracking_info_percentiles_len = argc; /* Special case: treat single arg "" as zero args indicating empty percentile configuration */ - if (argc == 1 && sdslen(argv[0]) == 0) + if (argc == 1 && sdslen(argv[0]) == 0) { server.latency_tracking_info_percentiles_len = 0; - else - server.latency_tracking_info_percentiles = zmalloc(sizeof(double)*argc); + } else { + server.latency_tracking_info_percentiles = zmalloc(sizeof(double) * argc); + } for (int j = 0; j < server.latency_tracking_info_percentiles_len; j++) { double percentile; @@ -3010,14 +3073,16 @@ static sds getConfigLatencyTrackingInfoPercentilesOutputOption(standardConfig *c size_t len = snprintf(fbuf, sizeof(fbuf), "%f", server.latency_tracking_info_percentiles[j]); len = trimDoubleString(fbuf, len); buf = sdscatlen(buf, fbuf, len); - if (j != server.latency_tracking_info_percentiles_len-1) - buf = sdscatlen(buf," ",1); + if (j != server.latency_tracking_info_percentiles_len - 1) { + buf = sdscatlen(buf, " ", 1); + } } return buf; } /* Rewrite the latency-tracking-info-percentiles option. */ -void rewriteConfigLatencyTrackingInfoPercentilesOutputOption(standardConfig *config, const char *name, struct rewriteConfigState *state) { +void rewriteConfigLatencyTrackingInfoPercentilesOutputOption(standardConfig *config, const char *name, + struct rewriteConfigState *state) { UNUSED(config); sds line = sdsnew(name); /* Rewrite latency-tracking-info-percentiles parameters, @@ -3025,7 +3090,7 @@ void rewriteConfigLatencyTrackingInfoPercentilesOutputOption(standardConfig *con * defaults from being used. */ if (!server.latency_tracking_info_percentiles_len) { - line = sdscat(line," \"\""); + line = sdscat(line, " \"\""); } else { for (int j = 0; j < server.latency_tracking_info_percentiles_len; j++) { char fbuf[128]; @@ -3034,7 +3099,7 @@ void rewriteConfigLatencyTrackingInfoPercentilesOutputOption(standardConfig *con line = sdscatlen(line, fbuf, len); } } - rewriteConfigRewriteLine(state,name,line,1); + rewriteConfigRewriteLine(state, name, line, 1); } static int applyClientMaxMemoryUsage(const char **err) { @@ -3044,10 +3109,12 @@ static int applyClientMaxMemoryUsage(const char **err) { /* server.client_mem_usage_buckets is an indication that the previous config * was non-zero, in which case we can exit and no apply is needed. */ - if(server.maxmemory_clients !=0 && server.client_mem_usage_buckets) + if (server.maxmemory_clients != 0 && server.client_mem_usage_buckets) { return 1; - if (server.maxmemory_clients != 0) + } + if (server.maxmemory_clients != 0) { initServerClientMemUsageBuckets(); + } /* When client eviction is enabled update memory buckets for all clients. * When disabled, clear that data structure. */ @@ -3063,8 +3130,9 @@ static int applyClientMaxMemoryUsage(const char **err) { } } - if (server.maxmemory_clients == 0) + if (server.maxmemory_clients == 0) { freeServerClientMemUsageBuckets(); + } return 1; } @@ -3072,223 +3140,398 @@ standardConfig static_configs[] = { /* Bool configs */ createBoolConfig("rdbchecksum", NULL, IMMUTABLE_CONFIG, server.rdb_checksum, 1, NULL, NULL), createBoolConfig("daemonize", NULL, IMMUTABLE_CONFIG, server.daemonize, 0, NULL, NULL), - createBoolConfig("io-threads-do-reads", NULL, DEBUG_CONFIG | IMMUTABLE_CONFIG, server.io_threads_do_reads, 0,NULL, NULL), /* Read + parse from threads? */ + createBoolConfig("io-threads-do-reads", NULL, DEBUG_CONFIG | IMMUTABLE_CONFIG, server.io_threads_do_reads, 0, NULL, + NULL), /* Read + parse from threads? */ createBoolConfig("always-show-logo", NULL, IMMUTABLE_CONFIG, server.always_show_logo, 0, NULL, NULL), createBoolConfig("protected-mode", NULL, MODIFIABLE_CONFIG, server.protected_mode, 1, NULL, NULL), createBoolConfig("rdbcompression", NULL, MODIFIABLE_CONFIG, server.rdb_compression, 1, NULL, NULL), createBoolConfig("rdb-del-sync-files", NULL, MODIFIABLE_CONFIG, server.rdb_del_sync_files, 0, NULL, NULL), createBoolConfig("activerehashing", NULL, MODIFIABLE_CONFIG, server.activerehashing, 1, NULL, NULL), - createBoolConfig("stop-writes-on-bgsave-error", NULL, MODIFIABLE_CONFIG, server.stop_writes_on_bgsave_err, 1, NULL, NULL), - createBoolConfig("set-proc-title", NULL, IMMUTABLE_CONFIG, server.set_proc_title, 1, NULL, NULL), /* Should setproctitle be used? */ - createBoolConfig("dynamic-hz", NULL, MODIFIABLE_CONFIG, server.dynamic_hz, 1, NULL, NULL), /* Adapt hz to # of clients.*/ - createBoolConfig("lazyfree-lazy-eviction", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, server.lazyfree_lazy_eviction, 0, NULL, NULL), - createBoolConfig("lazyfree-lazy-expire", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, server.lazyfree_lazy_expire, 0, NULL, NULL), - createBoolConfig("lazyfree-lazy-server-del", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, server.lazyfree_lazy_server_del, 0, NULL, NULL), - createBoolConfig("lazyfree-lazy-user-del", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, server.lazyfree_lazy_user_del , 0, NULL, NULL), - createBoolConfig("lazyfree-lazy-user-flush", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, server.lazyfree_lazy_user_flush , 0, NULL, NULL), - createBoolConfig("repl-disable-tcp-nodelay", NULL, MODIFIABLE_CONFIG, server.repl_disable_tcp_nodelay, 0, NULL, NULL), - createBoolConfig("repl-diskless-sync", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, server.repl_diskless_sync, 1, NULL, NULL), - createBoolConfig("aof-rewrite-incremental-fsync", NULL, MODIFIABLE_CONFIG, server.aof_rewrite_incremental_fsync, 1, NULL, NULL), - createBoolConfig("no-appendfsync-on-rewrite", NULL, MODIFIABLE_CONFIG, server.aof_no_fsync_on_rewrite, 0, NULL, NULL), - createBoolConfig("cluster-require-full-coverage", NULL, MODIFIABLE_CONFIG, server.cluster_require_full_coverage, 1, NULL, NULL), - createBoolConfig("rdb-save-incremental-fsync", NULL, MODIFIABLE_CONFIG, server.rdb_save_incremental_fsync, 1, NULL, NULL), + createBoolConfig("stop-writes-on-bgsave-error", NULL, MODIFIABLE_CONFIG, server.stop_writes_on_bgsave_err, 1, NULL, + NULL), + createBoolConfig("set-proc-title", NULL, IMMUTABLE_CONFIG, server.set_proc_title, 1, NULL, + NULL), /* Should setproctitle be used? */ + createBoolConfig("dynamic-hz", NULL, MODIFIABLE_CONFIG, server.dynamic_hz, 1, NULL, + NULL), /* Adapt hz to # of clients.*/ + createBoolConfig("lazyfree-lazy-eviction", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, server.lazyfree_lazy_eviction, 0, + NULL, NULL), + createBoolConfig("lazyfree-lazy-expire", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, server.lazyfree_lazy_expire, 0, + NULL, NULL), + createBoolConfig("lazyfree-lazy-server-del", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, + server.lazyfree_lazy_server_del, 0, NULL, NULL), + createBoolConfig("lazyfree-lazy-user-del", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, server.lazyfree_lazy_user_del, 0, + NULL, NULL), + createBoolConfig("lazyfree-lazy-user-flush", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, + server.lazyfree_lazy_user_flush, 0, NULL, NULL), + createBoolConfig("repl-disable-tcp-nodelay", NULL, MODIFIABLE_CONFIG, server.repl_disable_tcp_nodelay, 0, NULL, + NULL), + createBoolConfig("repl-diskless-sync", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, server.repl_diskless_sync, 1, NULL, + NULL), + createBoolConfig("aof-rewrite-incremental-fsync", NULL, MODIFIABLE_CONFIG, server.aof_rewrite_incremental_fsync, 1, + NULL, NULL), + createBoolConfig("no-appendfsync-on-rewrite", NULL, MODIFIABLE_CONFIG, server.aof_no_fsync_on_rewrite, 0, NULL, + NULL), + createBoolConfig("cluster-require-full-coverage", NULL, MODIFIABLE_CONFIG, server.cluster_require_full_coverage, 1, + NULL, NULL), + createBoolConfig("rdb-save-incremental-fsync", NULL, MODIFIABLE_CONFIG, server.rdb_save_incremental_fsync, 1, NULL, + NULL), createBoolConfig("aof-load-truncated", NULL, MODIFIABLE_CONFIG, server.aof_load_truncated, 1, NULL, NULL), createBoolConfig("aof-use-rdb-preamble", NULL, MODIFIABLE_CONFIG, server.aof_use_rdb_preamble, 1, NULL, NULL), createBoolConfig("aof-timestamp-enabled", NULL, MODIFIABLE_CONFIG, server.aof_timestamp_enabled, 0, NULL, NULL), - createBoolConfig("cluster-replica-no-failover", "cluster-slave-no-failover", MODIFIABLE_CONFIG, server.cluster_slave_no_failover, 0, NULL, updateClusterFlags), /* Failover by default. */ - createBoolConfig("replica-lazy-flush", "slave-lazy-flush", MODIFIABLE_CONFIG, server.repl_slave_lazy_flush, 0, NULL, NULL), - createBoolConfig("replica-serve-stale-data", "slave-serve-stale-data", MODIFIABLE_CONFIG, server.repl_serve_stale_data, 1, NULL, NULL), - createBoolConfig("replica-read-only", "slave-read-only", DEBUG_CONFIG | MODIFIABLE_CONFIG, server.repl_slave_ro, 1, NULL, NULL), - createBoolConfig("replica-ignore-maxmemory", "slave-ignore-maxmemory", MODIFIABLE_CONFIG, server.repl_slave_ignore_maxmemory, 1, NULL, NULL), - createBoolConfig("jemalloc-bg-thread", NULL, MODIFIABLE_CONFIG, server.jemalloc_bg_thread, 1, NULL, updateJemallocBgThread), - createBoolConfig("activedefrag", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, server.active_defrag_enabled, 0, isValidActiveDefrag, NULL), + createBoolConfig("cluster-replica-no-failover", "cluster-slave-no-failover", MODIFIABLE_CONFIG, + server.cluster_slave_no_failover, 0, NULL, updateClusterFlags), /* Failover by default. */ + createBoolConfig("replica-lazy-flush", "slave-lazy-flush", MODIFIABLE_CONFIG, server.repl_slave_lazy_flush, 0, NULL, + NULL), + createBoolConfig("replica-serve-stale-data", "slave-serve-stale-data", MODIFIABLE_CONFIG, + server.repl_serve_stale_data, 1, NULL, NULL), + createBoolConfig("replica-read-only", "slave-read-only", DEBUG_CONFIG | MODIFIABLE_CONFIG, server.repl_slave_ro, 1, + NULL, NULL), + createBoolConfig("replica-ignore-maxmemory", "slave-ignore-maxmemory", MODIFIABLE_CONFIG, + server.repl_slave_ignore_maxmemory, 1, NULL, NULL), + createBoolConfig("jemalloc-bg-thread", NULL, MODIFIABLE_CONFIG, server.jemalloc_bg_thread, 1, NULL, + updateJemallocBgThread), + createBoolConfig("activedefrag", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, server.active_defrag_enabled, 0, + isValidActiveDefrag, NULL), createBoolConfig("syslog-enabled", NULL, IMMUTABLE_CONFIG, server.syslog_enabled, 0, NULL, NULL), createBoolConfig("cluster-enabled", NULL, IMMUTABLE_CONFIG, server.cluster_enabled, 0, NULL, NULL), - createBoolConfig("appendonly", NULL, MODIFIABLE_CONFIG | DENY_LOADING_CONFIG, server.aof_enabled, 0, NULL, updateAppendonly), - createBoolConfig("cluster-allow-reads-when-down", NULL, MODIFIABLE_CONFIG, server.cluster_allow_reads_when_down, 0, NULL, NULL), - createBoolConfig("cluster-allow-pubsubshard-when-down", NULL, MODIFIABLE_CONFIG, server.cluster_allow_pubsubshard_when_down, 1, NULL, NULL), - createBoolConfig("crash-log-enabled", NULL, MODIFIABLE_CONFIG, server.crashlog_enabled, 1, NULL, updateSighandlerEnabled), + createBoolConfig("appendonly", NULL, MODIFIABLE_CONFIG | DENY_LOADING_CONFIG, server.aof_enabled, 0, NULL, + updateAppendonly), + createBoolConfig("cluster-allow-reads-when-down", NULL, MODIFIABLE_CONFIG, server.cluster_allow_reads_when_down, 0, + NULL, NULL), + createBoolConfig("cluster-allow-pubsubshard-when-down", NULL, MODIFIABLE_CONFIG, + server.cluster_allow_pubsubshard_when_down, 1, NULL, NULL), + createBoolConfig("crash-log-enabled", NULL, MODIFIABLE_CONFIG, server.crashlog_enabled, 1, NULL, + updateSighandlerEnabled), createBoolConfig("crash-memcheck-enabled", NULL, MODIFIABLE_CONFIG, server.memcheck_enabled, 1, NULL, NULL), - createBoolConfig("use-exit-on-panic", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, server.use_exit_on_panic, 0, NULL, NULL), + createBoolConfig("use-exit-on-panic", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, server.use_exit_on_panic, 0, NULL, + NULL), createBoolConfig("disable-thp", NULL, IMMUTABLE_CONFIG, server.disable_thp, 1, NULL, NULL), - createBoolConfig("cluster-allow-replica-migration", NULL, MODIFIABLE_CONFIG, server.cluster_allow_replica_migration, 1, NULL, NULL), + createBoolConfig("cluster-allow-replica-migration", NULL, MODIFIABLE_CONFIG, server.cluster_allow_replica_migration, + 1, NULL, NULL), createBoolConfig("replica-announced", NULL, MODIFIABLE_CONFIG, server.replica_announced, 1, NULL, NULL), createBoolConfig("latency-tracking", NULL, MODIFIABLE_CONFIG, server.latency_tracking_enabled, 1, NULL, NULL), - createBoolConfig("aof-disable-auto-gc", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, server.aof_disable_auto_gc, 0, NULL, updateAofAutoGCEnabled), - createBoolConfig("replica-ignore-disk-write-errors", NULL, MODIFIABLE_CONFIG, server.repl_ignore_disk_write_error, 0, NULL, NULL), - createBoolConfig("extended-redis-compatibility", NULL, MODIFIABLE_CONFIG, server.extended_redis_compat, 0, NULL, updateExtendedRedisCompat), + createBoolConfig("aof-disable-auto-gc", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, server.aof_disable_auto_gc, 0, + NULL, updateAofAutoGCEnabled), + createBoolConfig("replica-ignore-disk-write-errors", NULL, MODIFIABLE_CONFIG, server.repl_ignore_disk_write_error, + 0, NULL, NULL), + createBoolConfig("extended-redis-compatibility", NULL, MODIFIABLE_CONFIG, server.extended_redis_compat, 0, NULL, + updateExtendedRedisCompat), /* String Configs */ createStringConfig("aclfile", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.acl_filename, "", NULL, NULL), createStringConfig("unixsocket", NULL, IMMUTABLE_CONFIG, EMPTY_STRING_IS_NULL, server.unixsocket, NULL, NULL, NULL), createStringConfig("pidfile", NULL, IMMUTABLE_CONFIG, EMPTY_STRING_IS_NULL, server.pidfile, NULL, NULL, NULL), - createStringConfig("replica-announce-ip", "slave-announce-ip", MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.slave_announce_ip, NULL, NULL, NULL), - createStringConfig("masteruser", NULL, MODIFIABLE_CONFIG | SENSITIVE_CONFIG, EMPTY_STRING_IS_NULL, server.masteruser, NULL, NULL, NULL), - createStringConfig("cluster-announce-ip", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_ip, NULL, NULL, updateClusterIp), - createStringConfig("cluster-config-file", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.cluster_configfile, "nodes.conf", NULL, NULL), - createStringConfig("cluster-announce-hostname", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_hostname, NULL, isValidAnnouncedHostname, updateClusterHostname), - createStringConfig("cluster-announce-human-nodename", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_human_nodename, NULL, isValidAnnouncedNodename, updateClusterHumanNodename), - createStringConfig("syslog-ident", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.syslog_ident, SERVER_NAME, NULL, NULL), - createStringConfig("dbfilename", NULL, MODIFIABLE_CONFIG | PROTECTED_CONFIG, ALLOW_EMPTY_STRING, server.rdb_filename, "dump.rdb", isValidDBfilename, NULL), - createStringConfig("appendfilename", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.aof_filename, "appendonly.aof", isValidAOFfilename, NULL), - createStringConfig("appenddirname", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.aof_dirname, "appendonlydir", isValidAOFdirname, NULL), - createStringConfig("server-cpulist", "server_cpulist", IMMUTABLE_CONFIG, EMPTY_STRING_IS_NULL, server.server_cpulist, NULL, NULL, NULL), - createStringConfig("bio-cpulist", "bio_cpulist", IMMUTABLE_CONFIG, EMPTY_STRING_IS_NULL, server.bio_cpulist, NULL, NULL, NULL), - createStringConfig("aof-rewrite-cpulist", "aof_rewrite_cpulist", IMMUTABLE_CONFIG, EMPTY_STRING_IS_NULL, server.aof_rewrite_cpulist, NULL, NULL, NULL), - createStringConfig("bgsave-cpulist", "bgsave_cpulist", IMMUTABLE_CONFIG, EMPTY_STRING_IS_NULL, server.bgsave_cpulist, NULL, NULL, NULL), - createStringConfig("ignore-warnings", NULL, MODIFIABLE_CONFIG, ALLOW_EMPTY_STRING, server.ignore_warnings, "", NULL, NULL), - createStringConfig("proc-title-template", NULL, MODIFIABLE_CONFIG, ALLOW_EMPTY_STRING, server.proc_title_template, CONFIG_DEFAULT_PROC_TITLE_TEMPLATE, isValidProcTitleTemplate, updateProcTitleTemplate), - createStringConfig("bind-source-addr", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.bind_source_addr, NULL, NULL, NULL), + createStringConfig("replica-announce-ip", "slave-announce-ip", MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.slave_announce_ip, NULL, NULL, NULL), + createStringConfig("masteruser", NULL, MODIFIABLE_CONFIG | SENSITIVE_CONFIG, EMPTY_STRING_IS_NULL, + server.masteruser, NULL, NULL, NULL), + createStringConfig("cluster-announce-ip", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_ip, + NULL, NULL, updateClusterIp), + createStringConfig("cluster-config-file", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.cluster_configfile, + "nodes.conf", NULL, NULL), + createStringConfig("cluster-announce-hostname", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.cluster_announce_hostname, NULL, isValidAnnouncedHostname, updateClusterHostname), + createStringConfig("cluster-announce-human-nodename", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.cluster_announce_human_nodename, NULL, isValidAnnouncedNodename, + updateClusterHumanNodename), + createStringConfig("syslog-ident", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.syslog_ident, SERVER_NAME, + NULL, NULL), + createStringConfig("dbfilename", NULL, MODIFIABLE_CONFIG | PROTECTED_CONFIG, ALLOW_EMPTY_STRING, + server.rdb_filename, "dump.rdb", isValidDBfilename, NULL), + createStringConfig("appendfilename", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.aof_filename, + "appendonly.aof", isValidAOFfilename, NULL), + createStringConfig("appenddirname", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.aof_dirname, "appendonlydir", + isValidAOFdirname, NULL), + createStringConfig("server-cpulist", "server_cpulist", IMMUTABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.server_cpulist, NULL, NULL, NULL), + createStringConfig("bio-cpulist", "bio_cpulist", IMMUTABLE_CONFIG, EMPTY_STRING_IS_NULL, server.bio_cpulist, NULL, + NULL, NULL), + createStringConfig("aof-rewrite-cpulist", "aof_rewrite_cpulist", IMMUTABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.aof_rewrite_cpulist, NULL, NULL, NULL), + createStringConfig("bgsave-cpulist", "bgsave_cpulist", IMMUTABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.bgsave_cpulist, NULL, NULL, NULL), + createStringConfig("ignore-warnings", NULL, MODIFIABLE_CONFIG, ALLOW_EMPTY_STRING, server.ignore_warnings, "", NULL, + NULL), + createStringConfig("proc-title-template", NULL, MODIFIABLE_CONFIG, ALLOW_EMPTY_STRING, server.proc_title_template, + CONFIG_DEFAULT_PROC_TITLE_TEMPLATE, isValidProcTitleTemplate, updateProcTitleTemplate), + createStringConfig("bind-source-addr", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.bind_source_addr, NULL, + NULL, NULL), createStringConfig("logfile", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.logfile, "", NULL, NULL), #ifdef LOG_REQ_RES - createStringConfig("req-res-logfile", NULL, IMMUTABLE_CONFIG | HIDDEN_CONFIG, EMPTY_STRING_IS_NULL, server.req_res_logfile, NULL, NULL, NULL), + createStringConfig("req-res-logfile", NULL, IMMUTABLE_CONFIG | HIDDEN_CONFIG, EMPTY_STRING_IS_NULL, + server.req_res_logfile, NULL, NULL, NULL), #endif - createStringConfig("locale-collate", NULL, MODIFIABLE_CONFIG, ALLOW_EMPTY_STRING, server.locale_collate, "", NULL, updateLocaleCollate), + createStringConfig("locale-collate", NULL, MODIFIABLE_CONFIG, ALLOW_EMPTY_STRING, server.locale_collate, "", NULL, + updateLocaleCollate), /* SDS Configs */ - createSDSConfig("masterauth", NULL, MODIFIABLE_CONFIG | SENSITIVE_CONFIG, EMPTY_STRING_IS_NULL, server.masterauth, NULL, NULL, NULL), - createSDSConfig("requirepass", NULL, MODIFIABLE_CONFIG | SENSITIVE_CONFIG, EMPTY_STRING_IS_NULL, server.requirepass, NULL, NULL, updateRequirePass), + createSDSConfig("masterauth", NULL, MODIFIABLE_CONFIG | SENSITIVE_CONFIG, EMPTY_STRING_IS_NULL, server.masterauth, + NULL, NULL, NULL), + createSDSConfig("requirepass", NULL, MODIFIABLE_CONFIG | SENSITIVE_CONFIG, EMPTY_STRING_IS_NULL, server.requirepass, + NULL, NULL, updateRequirePass), /* Enum Configs */ - createEnumConfig("supervised", NULL, IMMUTABLE_CONFIG, supervised_mode_enum, server.supervised_mode, SUPERVISED_NONE, NULL, NULL), - createEnumConfig("syslog-facility", NULL, IMMUTABLE_CONFIG, syslog_facility_enum, server.syslog_facility, LOG_LOCAL0, NULL, NULL), - createEnumConfig("repl-diskless-load", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG | DENY_LOADING_CONFIG, repl_diskless_load_enum, server.repl_diskless_load, REPL_DISKLESS_LOAD_DISABLED, NULL, NULL), + createEnumConfig("supervised", NULL, IMMUTABLE_CONFIG, supervised_mode_enum, server.supervised_mode, + SUPERVISED_NONE, NULL, NULL), + createEnumConfig("syslog-facility", NULL, IMMUTABLE_CONFIG, syslog_facility_enum, server.syslog_facility, + LOG_LOCAL0, NULL, NULL), + createEnumConfig("repl-diskless-load", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG | DENY_LOADING_CONFIG, + repl_diskless_load_enum, server.repl_diskless_load, REPL_DISKLESS_LOAD_DISABLED, NULL, NULL), createEnumConfig("loglevel", NULL, MODIFIABLE_CONFIG, loglevel_enum, server.verbosity, LL_NOTICE, NULL, NULL), - createEnumConfig("maxmemory-policy", NULL, MODIFIABLE_CONFIG, maxmemory_policy_enum, server.maxmemory_policy, MAXMEMORY_NO_EVICTION, NULL, NULL), - createEnumConfig("appendfsync", NULL, MODIFIABLE_CONFIG, aof_fsync_enum, server.aof_fsync, AOF_FSYNC_EVERYSEC, NULL, updateAppendFsync), - createEnumConfig("oom-score-adj", NULL, MODIFIABLE_CONFIG, oom_score_adj_enum, server.oom_score_adj, OOM_SCORE_ADJ_NO, NULL, updateOOMScoreAdj), - createEnumConfig("acl-pubsub-default", NULL, MODIFIABLE_CONFIG, acl_pubsub_default_enum, server.acl_pubsub_default, 0, NULL, NULL), - createEnumConfig("sanitize-dump-payload", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, sanitize_dump_payload_enum, server.sanitize_dump_payload, SANITIZE_DUMP_NO, NULL, NULL), - createEnumConfig("enable-protected-configs", NULL, IMMUTABLE_CONFIG, protected_action_enum, server.enable_protected_configs, PROTECTED_ACTION_ALLOWED_NO, NULL, NULL), - createEnumConfig("enable-debug-command", NULL, IMMUTABLE_CONFIG, protected_action_enum, server.enable_debug_cmd, PROTECTED_ACTION_ALLOWED_NO, NULL, NULL), - createEnumConfig("enable-module-command", NULL, IMMUTABLE_CONFIG, protected_action_enum, server.enable_module_cmd, PROTECTED_ACTION_ALLOWED_NO, NULL, NULL), - createEnumConfig("cluster-preferred-endpoint-type", NULL, MODIFIABLE_CONFIG, cluster_preferred_endpoint_type_enum, server.cluster_preferred_endpoint_type, CLUSTER_ENDPOINT_TYPE_IP, NULL, NULL), - createEnumConfig("propagation-error-behavior", NULL, MODIFIABLE_CONFIG, propagation_error_behavior_enum, server.propagation_error_behavior, PROPAGATION_ERR_BEHAVIOR_IGNORE, NULL, NULL), - createEnumConfig("shutdown-on-sigint", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, shutdown_on_sig_enum, server.shutdown_on_sigint, 0, isValidShutdownOnSigFlags, NULL), - createEnumConfig("shutdown-on-sigterm", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, shutdown_on_sig_enum, server.shutdown_on_sigterm, 0, isValidShutdownOnSigFlags, NULL), + createEnumConfig("maxmemory-policy", NULL, MODIFIABLE_CONFIG, maxmemory_policy_enum, server.maxmemory_policy, + MAXMEMORY_NO_EVICTION, NULL, NULL), + createEnumConfig("appendfsync", NULL, MODIFIABLE_CONFIG, aof_fsync_enum, server.aof_fsync, AOF_FSYNC_EVERYSEC, NULL, + updateAppendFsync), + createEnumConfig("oom-score-adj", NULL, MODIFIABLE_CONFIG, oom_score_adj_enum, server.oom_score_adj, + OOM_SCORE_ADJ_NO, NULL, updateOOMScoreAdj), + createEnumConfig("acl-pubsub-default", NULL, MODIFIABLE_CONFIG, acl_pubsub_default_enum, server.acl_pubsub_default, + 0, NULL, NULL), + createEnumConfig("sanitize-dump-payload", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, sanitize_dump_payload_enum, + server.sanitize_dump_payload, SANITIZE_DUMP_NO, NULL, NULL), + createEnumConfig("enable-protected-configs", NULL, IMMUTABLE_CONFIG, protected_action_enum, + server.enable_protected_configs, PROTECTED_ACTION_ALLOWED_NO, NULL, NULL), + createEnumConfig("enable-debug-command", NULL, IMMUTABLE_CONFIG, protected_action_enum, server.enable_debug_cmd, + PROTECTED_ACTION_ALLOWED_NO, NULL, NULL), + createEnumConfig("enable-module-command", NULL, IMMUTABLE_CONFIG, protected_action_enum, server.enable_module_cmd, + PROTECTED_ACTION_ALLOWED_NO, NULL, NULL), + createEnumConfig("cluster-preferred-endpoint-type", NULL, MODIFIABLE_CONFIG, cluster_preferred_endpoint_type_enum, + server.cluster_preferred_endpoint_type, CLUSTER_ENDPOINT_TYPE_IP, NULL, NULL), + createEnumConfig("propagation-error-behavior", NULL, MODIFIABLE_CONFIG, propagation_error_behavior_enum, + server.propagation_error_behavior, PROPAGATION_ERR_BEHAVIOR_IGNORE, NULL, NULL), + createEnumConfig("shutdown-on-sigint", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, shutdown_on_sig_enum, + server.shutdown_on_sigint, 0, isValidShutdownOnSigFlags, NULL), + createEnumConfig("shutdown-on-sigterm", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, shutdown_on_sig_enum, + server.shutdown_on_sigterm, 0, isValidShutdownOnSigFlags, NULL), /* Integer configs */ createIntConfig("databases", NULL, IMMUTABLE_CONFIG, 1, INT_MAX, server.dbnum, 16, INTEGER_CONFIG, NULL, NULL), - createIntConfig("port", NULL, MODIFIABLE_CONFIG, 0, 65535, server.port, 6379, INTEGER_CONFIG, NULL, updatePort), /* TCP port. */ - createIntConfig("io-threads", NULL, DEBUG_CONFIG | IMMUTABLE_CONFIG, 1, 128, server.io_threads_num, 1, INTEGER_CONFIG, NULL, NULL), /* Single threaded by default */ - createIntConfig("auto-aof-rewrite-percentage", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.aof_rewrite_perc, 100, INTEGER_CONFIG, NULL, NULL), - createIntConfig("cluster-replica-validity-factor", "cluster-slave-validity-factor", MODIFIABLE_CONFIG, 0, INT_MAX, server.cluster_slave_validity_factor, 10, INTEGER_CONFIG, NULL, NULL), /* Slave max data age factor. */ - createIntConfig("list-max-listpack-size", "list-max-ziplist-size", MODIFIABLE_CONFIG, INT_MIN, INT_MAX, server.list_max_listpack_size, -2, INTEGER_CONFIG, NULL, NULL), - createIntConfig("tcp-keepalive", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.tcpkeepalive, 300, INTEGER_CONFIG, NULL, NULL), - createIntConfig("cluster-migration-barrier", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.cluster_migration_barrier, 1, INTEGER_CONFIG, NULL, NULL), - createIntConfig("active-defrag-cycle-min", NULL, MODIFIABLE_CONFIG, 1, 99, server.active_defrag_cycle_min, 1, INTEGER_CONFIG, NULL, updateDefragConfiguration), /* Default: 1% CPU min (at lower threshold) */ - createIntConfig("active-defrag-cycle-max", NULL, MODIFIABLE_CONFIG, 1, 99, server.active_defrag_cycle_max, 25, INTEGER_CONFIG, NULL, updateDefragConfiguration), /* Default: 25% CPU max (at upper threshold) */ - createIntConfig("active-defrag-threshold-lower", NULL, MODIFIABLE_CONFIG, 0, 1000, server.active_defrag_threshold_lower, 10, INTEGER_CONFIG, NULL, NULL), /* Default: don't defrag when fragmentation is below 10% */ - createIntConfig("active-defrag-threshold-upper", NULL, MODIFIABLE_CONFIG, 0, 1000, server.active_defrag_threshold_upper, 100, INTEGER_CONFIG, NULL, updateDefragConfiguration), /* Default: maximum defrag force at 100% fragmentation */ - createIntConfig("lfu-log-factor", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.lfu_log_factor, 10, INTEGER_CONFIG, NULL, NULL), - createIntConfig("lfu-decay-time", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.lfu_decay_time, 1, INTEGER_CONFIG, NULL, NULL), - createIntConfig("replica-priority", "slave-priority", MODIFIABLE_CONFIG, 0, INT_MAX, server.slave_priority, 100, INTEGER_CONFIG, NULL, NULL), - createIntConfig("repl-diskless-sync-delay", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.repl_diskless_sync_delay, 5, INTEGER_CONFIG, NULL, NULL), - createIntConfig("maxmemory-samples", NULL, MODIFIABLE_CONFIG, 1, 64, server.maxmemory_samples, 5, INTEGER_CONFIG, NULL, NULL), - createIntConfig("maxmemory-eviction-tenacity", NULL, MODIFIABLE_CONFIG, 0, 100, server.maxmemory_eviction_tenacity, 10, INTEGER_CONFIG, NULL, NULL), - createIntConfig("timeout", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.maxidletime, 0, INTEGER_CONFIG, NULL, NULL), /* Default client timeout: infinite */ - createIntConfig("replica-announce-port", "slave-announce-port", MODIFIABLE_CONFIG, 0, 65535, server.slave_announce_port, 0, INTEGER_CONFIG, NULL, NULL), - createIntConfig("tcp-backlog", NULL, IMMUTABLE_CONFIG, 0, INT_MAX, server.tcp_backlog, 511, INTEGER_CONFIG, NULL, NULL), /* TCP listen backlog. */ - createIntConfig("cluster-port", NULL, IMMUTABLE_CONFIG, 0, 65535, server.cluster_port, 0, INTEGER_CONFIG, NULL, NULL), - createIntConfig("cluster-announce-bus-port", NULL, MODIFIABLE_CONFIG, 0, 65535, server.cluster_announce_bus_port, 0, INTEGER_CONFIG, NULL, updateClusterAnnouncedPort), /* Default: Use +10000 offset. */ - createIntConfig("cluster-announce-port", NULL, MODIFIABLE_CONFIG, 0, 65535, server.cluster_announce_port, 0, INTEGER_CONFIG, NULL, updateClusterAnnouncedPort), /* Use server.port */ - createIntConfig("cluster-announce-tls-port", NULL, MODIFIABLE_CONFIG, 0, 65535, server.cluster_announce_tls_port, 0, INTEGER_CONFIG, NULL, updateClusterAnnouncedPort), /* Use server.tls_port */ - createIntConfig("repl-timeout", NULL, MODIFIABLE_CONFIG, 1, INT_MAX, server.repl_timeout, 60, INTEGER_CONFIG, NULL, NULL), - createIntConfig("repl-ping-replica-period", "repl-ping-slave-period", MODIFIABLE_CONFIG, 1, INT_MAX, server.repl_ping_slave_period, 10, INTEGER_CONFIG, NULL, NULL), - createIntConfig("list-compress-depth", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, 0, INT_MAX, server.list_compress_depth, 0, INTEGER_CONFIG, NULL, NULL), - createIntConfig("rdb-key-save-delay", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, INT_MIN, INT_MAX, server.rdb_key_save_delay, 0, INTEGER_CONFIG, NULL, NULL), - createIntConfig("key-load-delay", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, INT_MIN, INT_MAX, server.key_load_delay, 0, INTEGER_CONFIG, NULL, NULL), - createIntConfig("active-expire-effort", NULL, MODIFIABLE_CONFIG, 1, 10, server.active_expire_effort, 1, INTEGER_CONFIG, NULL, NULL), /* From 1 to 10. */ - createIntConfig("hz", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.config_hz, CONFIG_DEFAULT_HZ, INTEGER_CONFIG, NULL, updateHZ), - createIntConfig("min-replicas-to-write", "min-slaves-to-write", MODIFIABLE_CONFIG, 0, INT_MAX, server.repl_min_slaves_to_write, 0, INTEGER_CONFIG, NULL, updateGoodSlaves), - createIntConfig("min-replicas-max-lag", "min-slaves-max-lag", MODIFIABLE_CONFIG, 0, INT_MAX, server.repl_min_slaves_max_lag, 10, INTEGER_CONFIG, NULL, updateGoodSlaves), - createIntConfig("watchdog-period", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, 0, INT_MAX, server.watchdog_period, 0, INTEGER_CONFIG, NULL, updateWatchdogPeriod), - createIntConfig("shutdown-timeout", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.shutdown_timeout, 10, INTEGER_CONFIG, NULL, NULL), - createIntConfig("repl-diskless-sync-max-replicas", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.repl_diskless_sync_max_replicas, 0, INTEGER_CONFIG, NULL, NULL), + createIntConfig("port", NULL, MODIFIABLE_CONFIG, 0, 65535, server.port, 6379, INTEGER_CONFIG, NULL, + updatePort), /* TCP port. */ + createIntConfig("io-threads", NULL, DEBUG_CONFIG | IMMUTABLE_CONFIG, 1, 128, server.io_threads_num, 1, + INTEGER_CONFIG, NULL, NULL), /* Single threaded by default */ + createIntConfig("auto-aof-rewrite-percentage", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.aof_rewrite_perc, 100, + INTEGER_CONFIG, NULL, NULL), + createIntConfig("cluster-replica-validity-factor", "cluster-slave-validity-factor", MODIFIABLE_CONFIG, 0, INT_MAX, + server.cluster_slave_validity_factor, 10, INTEGER_CONFIG, NULL, + NULL), /* Slave max data age factor. */ + createIntConfig("list-max-listpack-size", "list-max-ziplist-size", MODIFIABLE_CONFIG, INT_MIN, INT_MAX, + server.list_max_listpack_size, -2, INTEGER_CONFIG, NULL, NULL), + createIntConfig("tcp-keepalive", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.tcpkeepalive, 300, INTEGER_CONFIG, + NULL, NULL), + createIntConfig("cluster-migration-barrier", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.cluster_migration_barrier, + 1, INTEGER_CONFIG, NULL, NULL), + createIntConfig("active-defrag-cycle-min", NULL, MODIFIABLE_CONFIG, 1, 99, server.active_defrag_cycle_min, 1, + INTEGER_CONFIG, NULL, updateDefragConfiguration), /* Default: 1% CPU min (at lower threshold) */ + createIntConfig("active-defrag-cycle-max", NULL, MODIFIABLE_CONFIG, 1, 99, server.active_defrag_cycle_max, 25, + INTEGER_CONFIG, NULL, updateDefragConfiguration), /* Default: 25% CPU max (at upper threshold) */ + createIntConfig("active-defrag-threshold-lower", NULL, MODIFIABLE_CONFIG, 0, 1000, + server.active_defrag_threshold_lower, 10, INTEGER_CONFIG, NULL, + NULL), /* Default: don't defrag when fragmentation is below 10% */ + createIntConfig("active-defrag-threshold-upper", NULL, MODIFIABLE_CONFIG, 0, 1000, + server.active_defrag_threshold_upper, 100, INTEGER_CONFIG, NULL, + updateDefragConfiguration), /* Default: maximum defrag force at 100% fragmentation */ + createIntConfig("lfu-log-factor", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.lfu_log_factor, 10, INTEGER_CONFIG, + NULL, NULL), + createIntConfig("lfu-decay-time", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.lfu_decay_time, 1, INTEGER_CONFIG, + NULL, NULL), + createIntConfig("replica-priority", "slave-priority", MODIFIABLE_CONFIG, 0, INT_MAX, server.slave_priority, 100, + INTEGER_CONFIG, NULL, NULL), + createIntConfig("repl-diskless-sync-delay", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.repl_diskless_sync_delay, 5, + INTEGER_CONFIG, NULL, NULL), + createIntConfig("maxmemory-samples", NULL, MODIFIABLE_CONFIG, 1, 64, server.maxmemory_samples, 5, INTEGER_CONFIG, + NULL, NULL), + createIntConfig("maxmemory-eviction-tenacity", NULL, MODIFIABLE_CONFIG, 0, 100, server.maxmemory_eviction_tenacity, + 10, INTEGER_CONFIG, NULL, NULL), + createIntConfig("timeout", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.maxidletime, 0, INTEGER_CONFIG, NULL, + NULL), /* Default client timeout: infinite */ + createIntConfig("replica-announce-port", "slave-announce-port", MODIFIABLE_CONFIG, 0, 65535, + server.slave_announce_port, 0, INTEGER_CONFIG, NULL, NULL), + createIntConfig("tcp-backlog", NULL, IMMUTABLE_CONFIG, 0, INT_MAX, server.tcp_backlog, 511, INTEGER_CONFIG, NULL, + NULL), /* TCP listen backlog. */ + createIntConfig("cluster-port", NULL, IMMUTABLE_CONFIG, 0, 65535, server.cluster_port, 0, INTEGER_CONFIG, NULL, + NULL), + createIntConfig("cluster-announce-bus-port", NULL, MODIFIABLE_CONFIG, 0, 65535, server.cluster_announce_bus_port, 0, + INTEGER_CONFIG, NULL, updateClusterAnnouncedPort), /* Default: Use +10000 offset. */ + createIntConfig("cluster-announce-port", NULL, MODIFIABLE_CONFIG, 0, 65535, server.cluster_announce_port, 0, + INTEGER_CONFIG, NULL, updateClusterAnnouncedPort), /* Use server.port */ + createIntConfig("cluster-announce-tls-port", NULL, MODIFIABLE_CONFIG, 0, 65535, server.cluster_announce_tls_port, 0, + INTEGER_CONFIG, NULL, updateClusterAnnouncedPort), /* Use server.tls_port */ + createIntConfig("repl-timeout", NULL, MODIFIABLE_CONFIG, 1, INT_MAX, server.repl_timeout, 60, INTEGER_CONFIG, NULL, + NULL), + createIntConfig("repl-ping-replica-period", "repl-ping-slave-period", MODIFIABLE_CONFIG, 1, INT_MAX, + server.repl_ping_slave_period, 10, INTEGER_CONFIG, NULL, NULL), + createIntConfig("list-compress-depth", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, 0, INT_MAX, + server.list_compress_depth, 0, INTEGER_CONFIG, NULL, NULL), + createIntConfig("rdb-key-save-delay", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, INT_MIN, INT_MAX, + server.rdb_key_save_delay, 0, INTEGER_CONFIG, NULL, NULL), + createIntConfig("key-load-delay", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, INT_MIN, INT_MAX, server.key_load_delay, + 0, INTEGER_CONFIG, NULL, NULL), + createIntConfig("active-expire-effort", NULL, MODIFIABLE_CONFIG, 1, 10, server.active_expire_effort, 1, + INTEGER_CONFIG, NULL, NULL), /* From 1 to 10. */ + createIntConfig("hz", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.config_hz, CONFIG_DEFAULT_HZ, INTEGER_CONFIG, + NULL, updateHZ), + createIntConfig("min-replicas-to-write", "min-slaves-to-write", MODIFIABLE_CONFIG, 0, INT_MAX, + server.repl_min_slaves_to_write, 0, INTEGER_CONFIG, NULL, updateGoodSlaves), + createIntConfig("min-replicas-max-lag", "min-slaves-max-lag", MODIFIABLE_CONFIG, 0, INT_MAX, + server.repl_min_slaves_max_lag, 10, INTEGER_CONFIG, NULL, updateGoodSlaves), + createIntConfig("watchdog-period", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, 0, INT_MAX, server.watchdog_period, 0, + INTEGER_CONFIG, NULL, updateWatchdogPeriod), + createIntConfig("shutdown-timeout", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.shutdown_timeout, 10, + INTEGER_CONFIG, NULL, NULL), + createIntConfig("repl-diskless-sync-max-replicas", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, + server.repl_diskless_sync_max_replicas, 0, INTEGER_CONFIG, NULL, NULL), /* Unsigned int configs */ - createUIntConfig("maxclients", NULL, MODIFIABLE_CONFIG, 1, UINT_MAX, server.maxclients, 10000, INTEGER_CONFIG, NULL, updateMaxclients), - createUIntConfig("unixsocketperm", NULL, IMMUTABLE_CONFIG, 0, 0777, server.unixsocketperm, 0, OCTAL_CONFIG, NULL, NULL), - createUIntConfig("socket-mark-id", NULL, IMMUTABLE_CONFIG, 0, UINT_MAX, server.socket_mark_id, 0, INTEGER_CONFIG, NULL, NULL), - createUIntConfig("max-new-connections-per-cycle", NULL, MODIFIABLE_CONFIG, 1, 1000, server.max_new_conns_per_cycle, 10, INTEGER_CONFIG, NULL, NULL), - createUIntConfig("max-new-tls-connections-per-cycle", NULL, MODIFIABLE_CONFIG, 1, 1000, server.max_new_tls_conns_per_cycle, 1, INTEGER_CONFIG, NULL, NULL), + createUIntConfig("maxclients", NULL, MODIFIABLE_CONFIG, 1, UINT_MAX, server.maxclients, 10000, INTEGER_CONFIG, NULL, + updateMaxclients), + createUIntConfig("unixsocketperm", NULL, IMMUTABLE_CONFIG, 0, 0777, server.unixsocketperm, 0, OCTAL_CONFIG, NULL, + NULL), + createUIntConfig("socket-mark-id", NULL, IMMUTABLE_CONFIG, 0, UINT_MAX, server.socket_mark_id, 0, INTEGER_CONFIG, + NULL, NULL), + createUIntConfig("max-new-connections-per-cycle", NULL, MODIFIABLE_CONFIG, 1, 1000, server.max_new_conns_per_cycle, + 10, INTEGER_CONFIG, NULL, NULL), + createUIntConfig("max-new-tls-connections-per-cycle", NULL, MODIFIABLE_CONFIG, 1, 1000, + server.max_new_tls_conns_per_cycle, 1, INTEGER_CONFIG, NULL, NULL), #ifdef LOG_REQ_RES - createUIntConfig("client-default-resp", NULL, IMMUTABLE_CONFIG | HIDDEN_CONFIG, 2, 3, server.client_default_resp, 2, INTEGER_CONFIG, NULL, NULL), + createUIntConfig("client-default-resp", NULL, IMMUTABLE_CONFIG | HIDDEN_CONFIG, 2, 3, server.client_default_resp, 2, + INTEGER_CONFIG, NULL, NULL), #endif /* Unsigned Long configs */ - createULongConfig("active-defrag-max-scan-fields", NULL, MODIFIABLE_CONFIG, 1, LONG_MAX, server.active_defrag_max_scan_fields, 1000, INTEGER_CONFIG, NULL, NULL), /* Default: keys with more than 1000 fields will be processed separately */ - createULongConfig("slowlog-max-len", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.slowlog_max_len, 128, INTEGER_CONFIG, NULL, NULL), - createULongConfig("acllog-max-len", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.acllog_max_len, 128, INTEGER_CONFIG, NULL, NULL), + createULongConfig("active-defrag-max-scan-fields", NULL, MODIFIABLE_CONFIG, 1, LONG_MAX, + server.active_defrag_max_scan_fields, 1000, INTEGER_CONFIG, NULL, + NULL), /* Default: keys with more than 1000 fields will be processed separately */ + createULongConfig("slowlog-max-len", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.slowlog_max_len, 128, + INTEGER_CONFIG, NULL, NULL), + createULongConfig("acllog-max-len", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.acllog_max_len, 128, + INTEGER_CONFIG, NULL, NULL), /* Long Long configs */ - createLongLongConfig("busy-reply-threshold", "lua-time-limit", MODIFIABLE_CONFIG, 0, LONG_MAX, server.busy_reply_threshold, 5000, INTEGER_CONFIG, NULL, NULL),/* milliseconds */ - createLongLongConfig("cluster-node-timeout", NULL, MODIFIABLE_CONFIG, 0, LLONG_MAX, server.cluster_node_timeout, 15000, INTEGER_CONFIG, NULL, NULL), - createLongLongConfig("cluster-ping-interval", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, 0, LLONG_MAX, server.cluster_ping_interval, 0, INTEGER_CONFIG, NULL, NULL), - createLongLongConfig("slowlog-log-slower-than", NULL, MODIFIABLE_CONFIG, -1, LLONG_MAX, server.slowlog_log_slower_than, 10000, INTEGER_CONFIG, NULL, NULL), - createLongLongConfig("latency-monitor-threshold", NULL, MODIFIABLE_CONFIG, 0, LLONG_MAX, server.latency_monitor_threshold, 0, INTEGER_CONFIG, NULL, NULL), - createLongLongConfig("proto-max-bulk-len", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, 1024*1024, LONG_MAX, server.proto_max_bulk_len, 512ll*1024*1024, MEMORY_CONFIG, NULL, NULL), /* Bulk request max size */ - createLongLongConfig("stream-node-max-entries", NULL, MODIFIABLE_CONFIG, 0, LLONG_MAX, server.stream_node_max_entries, 100, INTEGER_CONFIG, NULL, NULL), - createLongLongConfig("repl-backlog-size", NULL, MODIFIABLE_CONFIG, 1, LLONG_MAX, server.repl_backlog_size, 1024*1024, MEMORY_CONFIG, NULL, updateReplBacklogSize), /* Default: 1mb */ + createLongLongConfig("busy-reply-threshold", "lua-time-limit", MODIFIABLE_CONFIG, 0, LONG_MAX, + server.busy_reply_threshold, 5000, INTEGER_CONFIG, NULL, NULL), /* milliseconds */ + createLongLongConfig("cluster-node-timeout", NULL, MODIFIABLE_CONFIG, 0, LLONG_MAX, server.cluster_node_timeout, + 15000, INTEGER_CONFIG, NULL, NULL), + createLongLongConfig("cluster-ping-interval", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, 0, LLONG_MAX, + server.cluster_ping_interval, 0, INTEGER_CONFIG, NULL, NULL), + createLongLongConfig("slowlog-log-slower-than", NULL, MODIFIABLE_CONFIG, -1, LLONG_MAX, + server.slowlog_log_slower_than, 10000, INTEGER_CONFIG, NULL, NULL), + createLongLongConfig("latency-monitor-threshold", NULL, MODIFIABLE_CONFIG, 0, LLONG_MAX, + server.latency_monitor_threshold, 0, INTEGER_CONFIG, NULL, NULL), + createLongLongConfig("proto-max-bulk-len", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, 1024 * 1024, LONG_MAX, + server.proto_max_bulk_len, 512ll * 1024 * 1024, MEMORY_CONFIG, NULL, + NULL), /* Bulk request max size */ + createLongLongConfig("stream-node-max-entries", NULL, MODIFIABLE_CONFIG, 0, LLONG_MAX, + server.stream_node_max_entries, 100, INTEGER_CONFIG, NULL, NULL), + createLongLongConfig("repl-backlog-size", NULL, MODIFIABLE_CONFIG, 1, LLONG_MAX, server.repl_backlog_size, + 1024 * 1024, MEMORY_CONFIG, NULL, updateReplBacklogSize), /* Default: 1mb */ /* Unsigned Long Long configs */ - createULongLongConfig("maxmemory", NULL, MODIFIABLE_CONFIG, 0, ULLONG_MAX, server.maxmemory, 0, MEMORY_CONFIG, NULL, updateMaxmemory), - createULongLongConfig("cluster-link-sendbuf-limit", NULL, MODIFIABLE_CONFIG, 0, ULLONG_MAX, server.cluster_link_msg_queue_limit_bytes, 0, MEMORY_CONFIG, NULL, NULL), + createULongLongConfig("maxmemory", NULL, MODIFIABLE_CONFIG, 0, ULLONG_MAX, server.maxmemory, 0, MEMORY_CONFIG, NULL, + updateMaxmemory), + createULongLongConfig("cluster-link-sendbuf-limit", NULL, MODIFIABLE_CONFIG, 0, ULLONG_MAX, + server.cluster_link_msg_queue_limit_bytes, 0, MEMORY_CONFIG, NULL, NULL), /* Size_t configs */ - createSizeTConfig("hash-max-listpack-entries", "hash-max-ziplist-entries", MODIFIABLE_CONFIG, 0, LONG_MAX, server.hash_max_listpack_entries, 512, INTEGER_CONFIG, NULL, NULL), - createSizeTConfig("set-max-intset-entries", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.set_max_intset_entries, 512, INTEGER_CONFIG, NULL, NULL), - createSizeTConfig("set-max-listpack-entries", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.set_max_listpack_entries, 128, INTEGER_CONFIG, NULL, NULL), - createSizeTConfig("set-max-listpack-value", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.set_max_listpack_value, 64, INTEGER_CONFIG, NULL, NULL), - createSizeTConfig("zset-max-listpack-entries", "zset-max-ziplist-entries", MODIFIABLE_CONFIG, 0, LONG_MAX, server.zset_max_listpack_entries, 128, INTEGER_CONFIG, NULL, NULL), - createSizeTConfig("active-defrag-ignore-bytes", NULL, MODIFIABLE_CONFIG, 1, LLONG_MAX, server.active_defrag_ignore_bytes, 100<<20, MEMORY_CONFIG, NULL, NULL), /* Default: don't defrag if frag overhead is below 100mb */ - createSizeTConfig("hash-max-listpack-value", "hash-max-ziplist-value", MODIFIABLE_CONFIG, 0, LONG_MAX, server.hash_max_listpack_value, 64, MEMORY_CONFIG, NULL, NULL), - createSizeTConfig("stream-node-max-bytes", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.stream_node_max_bytes, 4096, MEMORY_CONFIG, NULL, NULL), - createSizeTConfig("zset-max-listpack-value", "zset-max-ziplist-value", MODIFIABLE_CONFIG, 0, LONG_MAX, server.zset_max_listpack_value, 64, MEMORY_CONFIG, NULL, NULL), - createSizeTConfig("hll-sparse-max-bytes", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.hll_sparse_max_bytes, 3000, MEMORY_CONFIG, NULL, NULL), - createSizeTConfig("tracking-table-max-keys", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.tracking_table_max_keys, 1000000, INTEGER_CONFIG, NULL, NULL), /* Default: 1 million keys max. */ - createSizeTConfig("client-query-buffer-limit", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, 1024*1024, LONG_MAX, server.client_max_querybuf_len, 1024*1024*1024, MEMORY_CONFIG, NULL, NULL), /* Default: 1GB max query buffer. */ - createSSizeTConfig("maxmemory-clients", NULL, MODIFIABLE_CONFIG, -100, SSIZE_MAX, server.maxmemory_clients, 0, MEMORY_CONFIG | PERCENT_CONFIG, NULL, applyClientMaxMemoryUsage), + createSizeTConfig("hash-max-listpack-entries", "hash-max-ziplist-entries", MODIFIABLE_CONFIG, 0, LONG_MAX, + server.hash_max_listpack_entries, 512, INTEGER_CONFIG, NULL, NULL), + createSizeTConfig("set-max-intset-entries", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.set_max_intset_entries, + 512, INTEGER_CONFIG, NULL, NULL), + createSizeTConfig("set-max-listpack-entries", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.set_max_listpack_entries, + 128, INTEGER_CONFIG, NULL, NULL), + createSizeTConfig("set-max-listpack-value", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.set_max_listpack_value, 64, + INTEGER_CONFIG, NULL, NULL), + createSizeTConfig("zset-max-listpack-entries", "zset-max-ziplist-entries", MODIFIABLE_CONFIG, 0, LONG_MAX, + server.zset_max_listpack_entries, 128, INTEGER_CONFIG, NULL, NULL), + createSizeTConfig("active-defrag-ignore-bytes", NULL, MODIFIABLE_CONFIG, 1, LLONG_MAX, + server.active_defrag_ignore_bytes, 100 << 20, MEMORY_CONFIG, NULL, + NULL), /* Default: don't defrag if frag overhead is below 100mb */ + createSizeTConfig("hash-max-listpack-value", "hash-max-ziplist-value", MODIFIABLE_CONFIG, 0, LONG_MAX, + server.hash_max_listpack_value, 64, MEMORY_CONFIG, NULL, NULL), + createSizeTConfig("stream-node-max-bytes", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.stream_node_max_bytes, 4096, + MEMORY_CONFIG, NULL, NULL), + createSizeTConfig("zset-max-listpack-value", "zset-max-ziplist-value", MODIFIABLE_CONFIG, 0, LONG_MAX, + server.zset_max_listpack_value, 64, MEMORY_CONFIG, NULL, NULL), + createSizeTConfig("hll-sparse-max-bytes", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.hll_sparse_max_bytes, 3000, + MEMORY_CONFIG, NULL, NULL), + createSizeTConfig("tracking-table-max-keys", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.tracking_table_max_keys, + 1000000, INTEGER_CONFIG, NULL, NULL), /* Default: 1 million keys max. */ + createSizeTConfig("client-query-buffer-limit", NULL, DEBUG_CONFIG | MODIFIABLE_CONFIG, 1024 * 1024, LONG_MAX, + server.client_max_querybuf_len, 1024 * 1024 * 1024, MEMORY_CONFIG, NULL, + NULL), /* Default: 1GB max query buffer. */ + createSSizeTConfig("maxmemory-clients", NULL, MODIFIABLE_CONFIG, -100, SSIZE_MAX, server.maxmemory_clients, 0, + MEMORY_CONFIG | PERCENT_CONFIG, NULL, applyClientMaxMemoryUsage), /* Other configs */ - createTimeTConfig("repl-backlog-ttl", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.repl_backlog_time_limit, 60*60, INTEGER_CONFIG, NULL, NULL), /* Default: 1 hour */ - createOffTConfig("auto-aof-rewrite-min-size", NULL, MODIFIABLE_CONFIG, 0, LLONG_MAX, server.aof_rewrite_min_size, 64*1024*1024, MEMORY_CONFIG, NULL, NULL), - createOffTConfig("loading-process-events-interval-bytes", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, 1024, INT_MAX, server.loading_process_events_interval_bytes, 1024*1024*2, INTEGER_CONFIG, NULL, NULL), - - createIntConfig("tls-port", NULL, MODIFIABLE_CONFIG, 0, 65535, server.tls_port, 0, INTEGER_CONFIG, NULL, applyTLSPort), /* TCP port. */ - createIntConfig("tls-session-cache-size", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.tls_ctx_config.session_cache_size, 20*1024, INTEGER_CONFIG, NULL, applyTlsCfg), - createIntConfig("tls-session-cache-timeout", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.tls_ctx_config.session_cache_timeout, 300, INTEGER_CONFIG, NULL, applyTlsCfg), + createTimeTConfig("repl-backlog-ttl", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX, server.repl_backlog_time_limit, 60 * 60, + INTEGER_CONFIG, NULL, NULL), /* Default: 1 hour */ + createOffTConfig("auto-aof-rewrite-min-size", NULL, MODIFIABLE_CONFIG, 0, LLONG_MAX, server.aof_rewrite_min_size, + 64 * 1024 * 1024, MEMORY_CONFIG, NULL, NULL), + createOffTConfig("loading-process-events-interval-bytes", NULL, MODIFIABLE_CONFIG | HIDDEN_CONFIG, 1024, INT_MAX, + server.loading_process_events_interval_bytes, 1024 * 1024 * 2, INTEGER_CONFIG, NULL, NULL), + + createIntConfig("tls-port", NULL, MODIFIABLE_CONFIG, 0, 65535, server.tls_port, 0, INTEGER_CONFIG, NULL, + applyTLSPort), /* TCP port. */ + createIntConfig("tls-session-cache-size", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, + server.tls_ctx_config.session_cache_size, 20 * 1024, INTEGER_CONFIG, NULL, applyTlsCfg), + createIntConfig("tls-session-cache-timeout", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, + server.tls_ctx_config.session_cache_timeout, 300, INTEGER_CONFIG, NULL, applyTlsCfg), createBoolConfig("tls-cluster", NULL, MODIFIABLE_CONFIG, server.tls_cluster, 0, NULL, applyTlsCfg), createBoolConfig("tls-replication", NULL, MODIFIABLE_CONFIG, server.tls_replication, 0, NULL, applyTlsCfg), - createEnumConfig("tls-auth-clients", NULL, MODIFIABLE_CONFIG, tls_auth_clients_enum, server.tls_auth_clients, TLS_CLIENT_AUTH_YES, NULL, NULL), - createBoolConfig("tls-prefer-server-ciphers", NULL, MODIFIABLE_CONFIG, server.tls_ctx_config.prefer_server_ciphers, 0, NULL, applyTlsCfg), - createBoolConfig("tls-session-caching", NULL, MODIFIABLE_CONFIG, server.tls_ctx_config.session_caching, 1, NULL, applyTlsCfg), - createStringConfig("tls-cert-file", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.cert_file, NULL, NULL, applyTlsCfg), - createStringConfig("tls-key-file", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.key_file, NULL, NULL, applyTlsCfg), - createStringConfig("tls-key-file-pass", NULL, MODIFIABLE_CONFIG | SENSITIVE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.key_file_pass, NULL, NULL, applyTlsCfg), - createStringConfig("tls-client-cert-file", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.client_cert_file, NULL, NULL, applyTlsCfg), - createStringConfig("tls-client-key-file", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.client_key_file, NULL, NULL, applyTlsCfg), - createStringConfig("tls-client-key-file-pass", NULL, MODIFIABLE_CONFIG | SENSITIVE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.client_key_file_pass, NULL, NULL, applyTlsCfg), - createStringConfig("tls-dh-params-file", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.dh_params_file, NULL, NULL, applyTlsCfg), - createStringConfig("tls-ca-cert-file", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.ca_cert_file, NULL, NULL, applyTlsCfg), - createStringConfig("tls-ca-cert-dir", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.ca_cert_dir, NULL, NULL, applyTlsCfg), - createStringConfig("tls-protocols", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.protocols, NULL, NULL, applyTlsCfg), - createStringConfig("tls-ciphers", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.ciphers, NULL, NULL, applyTlsCfg), - createStringConfig("tls-ciphersuites", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.ciphersuites, NULL, NULL, applyTlsCfg), + createEnumConfig("tls-auth-clients", NULL, MODIFIABLE_CONFIG, tls_auth_clients_enum, server.tls_auth_clients, + TLS_CLIENT_AUTH_YES, NULL, NULL), + createBoolConfig("tls-prefer-server-ciphers", NULL, MODIFIABLE_CONFIG, server.tls_ctx_config.prefer_server_ciphers, + 0, NULL, applyTlsCfg), + createBoolConfig("tls-session-caching", NULL, MODIFIABLE_CONFIG, server.tls_ctx_config.session_caching, 1, NULL, + applyTlsCfg), + createStringConfig("tls-cert-file", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.tls_ctx_config.cert_file, NULL, NULL, applyTlsCfg), + createStringConfig("tls-key-file", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.tls_ctx_config.key_file, NULL, NULL, applyTlsCfg), + createStringConfig("tls-key-file-pass", NULL, MODIFIABLE_CONFIG | SENSITIVE_CONFIG, EMPTY_STRING_IS_NULL, + server.tls_ctx_config.key_file_pass, NULL, NULL, applyTlsCfg), + createStringConfig("tls-client-cert-file", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.tls_ctx_config.client_cert_file, NULL, NULL, applyTlsCfg), + createStringConfig("tls-client-key-file", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.tls_ctx_config.client_key_file, NULL, NULL, applyTlsCfg), + createStringConfig("tls-client-key-file-pass", NULL, MODIFIABLE_CONFIG | SENSITIVE_CONFIG, EMPTY_STRING_IS_NULL, + server.tls_ctx_config.client_key_file_pass, NULL, NULL, applyTlsCfg), + createStringConfig("tls-dh-params-file", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.tls_ctx_config.dh_params_file, NULL, NULL, applyTlsCfg), + createStringConfig("tls-ca-cert-file", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.tls_ctx_config.ca_cert_file, NULL, NULL, applyTlsCfg), + createStringConfig("tls-ca-cert-dir", NULL, VOLATILE_CONFIG | MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.tls_ctx_config.ca_cert_dir, NULL, NULL, applyTlsCfg), + createStringConfig("tls-protocols", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.protocols, + NULL, NULL, applyTlsCfg), + createStringConfig("tls-ciphers", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.ciphers, + NULL, NULL, applyTlsCfg), + createStringConfig("tls-ciphersuites", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, + server.tls_ctx_config.ciphersuites, NULL, NULL, applyTlsCfg), /* Special configs */ - createSpecialConfig("dir", NULL, MODIFIABLE_CONFIG | PROTECTED_CONFIG | DENY_LOADING_CONFIG, setConfigDirOption, getConfigDirOption, rewriteConfigDirOption, NULL), - createSpecialConfig("save", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, setConfigSaveOption, getConfigSaveOption, rewriteConfigSaveOption, NULL), - createSpecialConfig("client-output-buffer-limit", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, setConfigClientOutputBufferLimitOption, getConfigClientOutputBufferLimitOption, rewriteConfigClientOutputBufferLimitOption, NULL), - createSpecialConfig("oom-score-adj-values", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, setConfigOOMScoreAdjValuesOption, getConfigOOMScoreAdjValuesOption, rewriteConfigOOMScoreAdjValuesOption, updateOOMScoreAdj), - createSpecialConfig("notify-keyspace-events", NULL, MODIFIABLE_CONFIG, setConfigNotifyKeyspaceEventsOption, getConfigNotifyKeyspaceEventsOption, rewriteConfigNotifyKeyspaceEventsOption, NULL), - createSpecialConfig("bind", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, setConfigBindOption, getConfigBindOption, rewriteConfigBindOption, applyBind), - createSpecialConfig("replicaof", "slaveof", IMMUTABLE_CONFIG | MULTI_ARG_CONFIG, setConfigReplicaOfOption, getConfigReplicaOfOption, rewriteConfigReplicaOfOption, NULL), - createSpecialConfig("latency-tracking-info-percentiles", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, setConfigLatencyTrackingInfoPercentilesOutputOption, getConfigLatencyTrackingInfoPercentilesOutputOption, rewriteConfigLatencyTrackingInfoPercentilesOutputOption, NULL), + createSpecialConfig("dir", NULL, MODIFIABLE_CONFIG | PROTECTED_CONFIG | DENY_LOADING_CONFIG, setConfigDirOption, + getConfigDirOption, rewriteConfigDirOption, NULL), + createSpecialConfig("save", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, setConfigSaveOption, getConfigSaveOption, + rewriteConfigSaveOption, NULL), + createSpecialConfig("client-output-buffer-limit", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, + setConfigClientOutputBufferLimitOption, getConfigClientOutputBufferLimitOption, + rewriteConfigClientOutputBufferLimitOption, NULL), + createSpecialConfig("oom-score-adj-values", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, + setConfigOOMScoreAdjValuesOption, getConfigOOMScoreAdjValuesOption, + rewriteConfigOOMScoreAdjValuesOption, updateOOMScoreAdj), + createSpecialConfig("notify-keyspace-events", NULL, MODIFIABLE_CONFIG, setConfigNotifyKeyspaceEventsOption, + getConfigNotifyKeyspaceEventsOption, rewriteConfigNotifyKeyspaceEventsOption, NULL), + createSpecialConfig("bind", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, setConfigBindOption, getConfigBindOption, + rewriteConfigBindOption, applyBind), + createSpecialConfig("replicaof", "slaveof", IMMUTABLE_CONFIG | MULTI_ARG_CONFIG, setConfigReplicaOfOption, + getConfigReplicaOfOption, rewriteConfigReplicaOfOption, NULL), + createSpecialConfig("latency-tracking-info-percentiles", NULL, MODIFIABLE_CONFIG | MULTI_ARG_CONFIG, + setConfigLatencyTrackingInfoPercentilesOutputOption, + getConfigLatencyTrackingInfoPercentilesOutputOption, + rewriteConfigLatencyTrackingInfoPercentilesOutputOption, NULL), /* NULL Terminator, this is dropped when we convert to the runtime array. */ - {NULL} -}; + {NULL}}; /* Create a new config by copying the passed in config. Returns 1 on success * or 0 when their was already a config with the same name.. */ @@ -3304,13 +3547,15 @@ int registerConfigValue(const char *name, const standardConfig *config, int alia return dictAdd(configs, sdsnew(name), new) == DICT_OK; } -/* Initialize configs to their default values and create and populate the +/* Initialize configs to their default values and create and populate the * runtime configuration dictionary. */ void initConfigValues(void) { configs = dictCreate(&sdsHashDictType); dictExpand(configs, sizeof(static_configs) / sizeof(standardConfig)); for (standardConfig *config = static_configs; config->name != NULL; config++) { - if (config->interface.init) config->interface.init(config); + if (config->interface.init) { + config->interface.init(config); + } /* Add the primary config to the dictionary. */ int ret = registerConfigValue(config->name, config, 0); serverAssert(ret); @@ -3327,18 +3572,22 @@ void initConfigValues(void) { /* Remove a config by name from the configs dict. */ void removeConfig(sds name) { standardConfig *config = lookupConfig(name); - if (!config) return; + if (!config) { + return; + } if (config->flags & MODULE_CONFIG) { - sdsfree((sds) config->name); + sdsfree((sds)config->name); if (config->type == ENUM_CONFIG) { configEnum *enumNode = config->data.enumd.enum_value; - while(enumNode->name != NULL) { + while (enumNode->name != NULL) { zfree(enumNode->name); enumNode++; } zfree(config->data.enumd.enum_value); } else if (config->type == SDS_CONFIG) { - if (config->data.sds.default_value) sdsfree((sds)config->data.sds.default_value); + if (config->data.sds.default_value) { + sdsfree((sds)config->data.sds.default_value); + } } } dictDelete(configs, name); @@ -3352,7 +3601,8 @@ void removeConfig(sds name) { void addModuleBoolConfig(const char *module_name, const char *name, int flags, void *privdata, int default_val) { sds config_name = sdscatfmt(sdsempty(), "%s.%s", module_name, name); int config_dummy_address; - standardConfig module_config = createBoolConfig(config_name, NULL, flags | MODULE_CONFIG, config_dummy_address, default_val, NULL, NULL); + standardConfig module_config = + createBoolConfig(config_name, NULL, flags | MODULE_CONFIG, config_dummy_address, default_val, NULL, NULL); module_config.data.yesno.config = NULL; module_config.privdata = privdata; registerConfigValue(config_name, &module_config, 0); @@ -3361,25 +3611,30 @@ void addModuleBoolConfig(const char *module_name, const char *name, int flags, v void addModuleStringConfig(const char *module_name, const char *name, int flags, void *privdata, sds default_val) { sds config_name = sdscatfmt(sdsempty(), "%s.%s", module_name, name); sds config_dummy_address; - standardConfig module_config = createSDSConfig(config_name, NULL, flags | MODULE_CONFIG, 0, config_dummy_address, default_val, NULL, NULL); + standardConfig module_config = + createSDSConfig(config_name, NULL, flags | MODULE_CONFIG, 0, config_dummy_address, default_val, NULL, NULL); module_config.data.sds.config = NULL; module_config.privdata = privdata; registerConfigValue(config_name, &module_config, 0); } -void addModuleEnumConfig(const char *module_name, const char *name, int flags, void *privdata, int default_val, configEnum *enum_vals) { +void addModuleEnumConfig(const char *module_name, const char *name, int flags, void *privdata, int default_val, + configEnum *enum_vals) { sds config_name = sdscatfmt(sdsempty(), "%s.%s", module_name, name); int config_dummy_address; - standardConfig module_config = createEnumConfig(config_name, NULL, flags | MODULE_CONFIG, enum_vals, config_dummy_address, default_val, NULL, NULL); + standardConfig module_config = createEnumConfig(config_name, NULL, flags | MODULE_CONFIG, enum_vals, + config_dummy_address, default_val, NULL, NULL); module_config.data.enumd.config = NULL; module_config.privdata = privdata; registerConfigValue(config_name, &module_config, 0); } -void addModuleNumericConfig(const char *module_name, const char *name, int flags, void *privdata, long long default_val, int conf_flags, long long lower, long long upper) { +void addModuleNumericConfig(const char *module_name, const char *name, int flags, void *privdata, long long default_val, + int conf_flags, long long lower, long long upper) { sds config_name = sdscatfmt(sdsempty(), "%s.%s", module_name, name); long long config_dummy_address; - standardConfig module_config = createLongLongConfig(config_name, NULL, flags | MODULE_CONFIG, lower, upper, config_dummy_address, default_val, conf_flags, NULL, NULL); + standardConfig module_config = createLongLongConfig(config_name, NULL, flags | MODULE_CONFIG, lower, upper, + config_dummy_address, default_val, conf_flags, NULL, NULL); module_config.data.numeric.config.ll = NULL; module_config.privdata = privdata; registerConfigValue(config_name, &module_config, 0); @@ -3390,17 +3645,15 @@ void addModuleNumericConfig(const char *module_name, const char *name, int flags *----------------------------------------------------------------------------*/ void configHelpCommand(client *c) { - const char *help[] = { -"GET ", -" Return parameters matching the glob-like and their values.", -"SET ", -" Set the configuration to .", -"RESETSTAT", -" Reset statistics reported by the INFO command.", -"REWRITE", -" Rewrite the configuration file.", -NULL - }; + const char *help[] = {"GET ", + " Return parameters matching the glob-like and their values.", + "SET ", + " Set the configuration to .", + "RESETSTAT", + " Reset statistics reported by the INFO command.", + "REWRITE", + " Rewrite the configuration file.", + NULL}; addReplyHelp(c, help); } @@ -3413,7 +3666,7 @@ void configResetStatCommand(client *c) { resetServerStats(); resetCommandTableStats(server.commands); resetErrorTableStats(); - addReply(c,shared.ok); + addReply(c, shared.ok); } /*----------------------------------------------------------------------------- @@ -3422,16 +3675,16 @@ void configResetStatCommand(client *c) { void configRewriteCommand(client *c) { if (server.configfile == NULL) { - addReplyError(c,"The server is running without a config file"); + addReplyError(c, "The server is running without a config file"); return; } if (rewriteConfig(server.configfile, 0) == -1) { /* save errno in case of being tainted. */ int err = errno; - serverLog(LL_WARNING,"CONFIG REWRITE failed: %s", strerror(err)); - addReplyErrorFormat(c,"Rewriting config file: %s", strerror(err)); + serverLog(LL_WARNING, "CONFIG REWRITE failed: %s", strerror(err)); + addReplyErrorFormat(c, "Rewriting config file: %s", strerror(err)); } else { - serverLog(LL_NOTICE,"CONFIG REWRITE executed with success."); - addReply(c,shared.ok); + serverLog(LL_NOTICE, "CONFIG REWRITE executed with success."); + addReply(c, shared.ok); } } diff --git a/src/config.h b/src/config.h index 4646f653e..8ff6a7d2d 100644 --- a/src/config.h +++ b/src/config.h @@ -77,9 +77,9 @@ #endif /* Test for backtrace() */ -#if defined(__APPLE__) || (defined(__linux__) && defined(__GLIBC__)) || \ - defined(__FreeBSD__) || ((defined(__OpenBSD__) || defined(__NetBSD__) || defined(__sun)) && defined(USE_BACKTRACE))\ - || defined(__DragonFly__) || (defined(__UCLIBC__) && defined(__UCLIBC_HAS_BACKTRACE__)) +#if defined(__APPLE__) || (defined(__linux__) && defined(__GLIBC__)) || defined(__FreeBSD__) || \ + ((defined(__OpenBSD__) || defined(__NetBSD__) || defined(__sun)) && defined(USE_BACKTRACE)) || \ + defined(__DragonFly__) || (defined(__UCLIBC__) && defined(__UCLIBC_HAS_BACKTRACE__)) #define HAVE_BACKTRACE 1 #endif @@ -98,15 +98,14 @@ #endif /* Test for accept4() */ -#if defined(__linux__) || \ - defined(__FreeBSD__) || \ - defined(OpenBSD5_7) || \ - (defined(__DragonFly__) && __DragonFly_version >= 400305) || \ +#if defined(__linux__) || defined(__FreeBSD__) || defined(OpenBSD5_7) || \ + (defined(__DragonFly__) && __DragonFly_version >= 400305) || \ (defined(__NetBSD__) && (defined(NetBSD8_0) || __NetBSD_Version__ >= 800000000)) #define HAVE_ACCEPT4 1 #endif -#if (defined(__APPLE__) && defined(MAC_OS_10_6_DETECTED)) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__) +#if (defined(__APPLE__) && defined(MAC_OS_10_6_DETECTED)) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ + defined(__NetBSD__) #define HAVE_KQUEUE 1 #endif @@ -169,11 +168,12 @@ * the plain fsync() call. */ #if (defined(__linux__) && defined(SYNC_FILE_RANGE_WAIT_BEFORE)) #define HAVE_SYNC_FILE_RANGE 1 -#define rdb_fsync_range(fd,off,size) sync_file_range(fd,off,size,SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE) +#define rdb_fsync_range(fd, off, size) \ + sync_file_range(fd, off, size, SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE) #elif defined(__APPLE__) -#define rdb_fsync_range(fd,off,size) fcntl(fd, F_FULLFSYNC) +#define rdb_fsync_range(fd, off, size) fcntl(fd, F_FULLFSYNC) #else -#define rdb_fsync_range(fd,off,size) fsync(fd) +#define rdb_fsync_range(fd, off, size) fsync(fd) #endif /* Check if we can use setproctitle(). @@ -199,31 +199,27 @@ void setproctitle(const char *fmt, ...); #ifndef BYTE_ORDER #if (BSD >= 199103) -# include +#include #else #if defined(linux) || defined(__linux__) -# include +#include #else -#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */ -#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ -#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/ - -#if defined(__i386__) || defined(__x86_64__) || defined(__amd64__) || \ - defined(vax) || defined(ns32000) || defined(sun386) || \ - defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \ - defined(__alpha__) || defined(__alpha) -#define BYTE_ORDER LITTLE_ENDIAN -#endif - -#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \ - defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \ - defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) || \ - defined(apollo) || defined(__convex__) || defined(_CRAY) || \ - defined(__hppa) || defined(__hp9000) || \ - defined(__hp9000s300) || defined(__hp9000s700) || \ - defined (BIT_ZERO_ON_LEFT) || defined(m68k) || defined(__sparc) || \ - (defined(__APPLE__) && defined(__POWERPC__)) -#define BYTE_ORDER BIG_ENDIAN +#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */ +#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ +#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/ + +#if defined(__i386__) || defined(__x86_64__) || defined(__amd64__) || defined(vax) || defined(ns32000) || \ + defined(sun386) || defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || defined(__alpha__) || \ + defined(__alpha) +#define BYTE_ORDER LITTLE_ENDIAN +#endif + +#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || defined(is68k) || defined(tahoe) || \ + defined(ibm032) || defined(ibm370) || defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) || \ + defined(apollo) || defined(__convex__) || defined(_CRAY) || defined(__hppa) || defined(__hp9000) || \ + defined(__hp9000s300) || defined(__hp9000s700) || defined(BIT_ZERO_ON_LEFT) || defined(m68k) || \ + defined(__sparc) || (defined(__APPLE__) && defined(__POWERPC__)) +#define BYTE_ORDER BIG_ENDIAN #endif #endif /* linux */ #endif /* BSD */ @@ -251,13 +247,12 @@ void setproctitle(const char *fmt, ...); #endif #endif -#if !defined(BYTE_ORDER) || \ - (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN) - /* you must determine what the correct bit order is for - * your compiler - the next line is an intentional error - * which will force your compiles to bomb until you fix - * the above macros. - */ +#if !defined(BYTE_ORDER) || (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN) +/* you must determine what the correct bit order is for + * your compiler - the next line is an intentional error + * which will force your compiles to bomb until you fix + * the above macros. + */ #error "Undefined or invalid BYTE_ORDER" #endif @@ -278,7 +273,7 @@ void setproctitle(const char *fmt, ...); #if defined(__arm) && !defined(__arm__) #define __arm__ #endif -#if defined (__aarch64__) && !defined(__arm64__) +#if defined(__aarch64__) && !defined(__arm64__) #define __arm64__ #endif diff --git a/src/connection.c b/src/connection.c index fd9d5d17a..338ca96d4 100644 --- a/src/connection.c +++ b/src/connection.c @@ -37,8 +37,9 @@ int connTypeRegister(ConnectionType *ct) { /* find an empty slot to store the new connection type */ for (type = 0; type < CONN_TYPE_MAX; type++) { tmpct = connTypes[type]; - if (!tmpct) + if (!tmpct) { break; + } /* ignore case, we really don't care "tls"/"TLS" */ if (!strcasecmp(typename, tmpct->get_type(NULL))) { @@ -75,11 +76,13 @@ ConnectionType *connectionByType(const char *typename) { for (int type = 0; type < CONN_TYPE_MAX; type++) { ct = connTypes[type]; - if (!ct) + if (!ct) { break; + } - if (!strcasecmp(typename, ct->get_type(NULL))) + if (!strcasecmp(typename, ct->get_type(NULL))) { return ct; + } } serverLog(LL_WARNING, "Missing implement of connection type %s", typename); @@ -91,8 +94,9 @@ ConnectionType *connectionByType(const char *typename) { ConnectionType *connectionTypeTcp(void) { static ConnectionType *ct_tcp = NULL; - if (ct_tcp != NULL) + if (ct_tcp != NULL) { return ct_tcp; + } ct_tcp = connectionByType(CONN_TYPE_SOCKET); serverAssert(ct_tcp != NULL); @@ -119,8 +123,9 @@ ConnectionType *connectionTypeTls(void) { ConnectionType *connectionTypeUnix(void) { static ConnectionType *ct_unix = NULL; - if (ct_unix != NULL) + if (ct_unix != NULL) { return ct_unix; + } ct_unix = connectionByType(CONN_TYPE_UNIX); return ct_unix; @@ -131,11 +136,13 @@ int connectionIndexByType(const char *typename) { for (int type = 0; type < CONN_TYPE_MAX; type++) { ct = connTypes[type]; - if (!ct) + if (!ct) { break; + } - if (!strcasecmp(typename, ct->get_type(NULL))) + if (!strcasecmp(typename, ct->get_type(NULL))) { return type; + } } return -1; @@ -147,11 +154,13 @@ void connTypeCleanupAll(void) { for (type = 0; type < CONN_TYPE_MAX; type++) { ct = connTypes[type]; - if (!ct) + if (!ct) { break; + } - if (ct->cleanup) + if (ct->cleanup) { ct->cleanup(); + } } } @@ -190,16 +199,18 @@ int connTypeProcessPendingData(void) { sds getListensInfoString(sds info) { for (int j = 0; j < CONN_TYPE_MAX; j++) { connListener *listener = &server.listeners[j]; - if (listener->ct == NULL) + if (listener->ct == NULL) { continue; + } info = sdscatfmt(info, "listener%i:name=%s", j, listener->ct->get_type(NULL)); for (int i = 0; i < listener->count; i++) { info = sdscatfmt(info, ",bind=%s", listener->bindaddr[i]); } - if (listener->port) + if (listener->port) { info = sdscatfmt(info, ",port=%i", listener->port); + } info = sdscatfmt(info, "\r\n"); } diff --git a/src/connection.h b/src/connection.h index f50cd89d1..c97346127 100644 --- a/src/connection.h +++ b/src/connection.h @@ -38,7 +38,7 @@ #include "ae.h" -#define CONN_INFO_LEN 32 +#define CONN_INFO_LEN 32 #define CONN_ADDR_STR_LEN 128 /* Similar to INET6_ADDRSTRLEN, hoping to handle other protocols. */ struct aeEventLoop; @@ -54,13 +54,13 @@ typedef enum { CONN_STATE_ERROR } ConnectionState; -#define CONN_FLAG_CLOSE_SCHEDULED (1<<0) /* Closed scheduled by a handler */ -#define CONN_FLAG_WRITE_BARRIER (1<<1) /* Write barrier requested */ +#define CONN_FLAG_CLOSE_SCHEDULED (1 << 0) /* Closed scheduled by a handler */ +#define CONN_FLAG_WRITE_BARRIER (1 << 1) /* Write barrier requested */ -#define CONN_TYPE_SOCKET "tcp" -#define CONN_TYPE_UNIX "unix" -#define CONN_TYPE_TLS "tls" -#define CONN_TYPE_MAX 8 /* 8 is enough to be extendable */ +#define CONN_TYPE_SOCKET "tcp" +#define CONN_TYPE_UNIX "unix" +#define CONN_TYPE_TLS "tls" +#define CONN_TYPE_MAX 8 /* 8 is enough to be extendable */ typedef void (*ConnectionCallbackFunc)(struct connection *conn); @@ -81,13 +81,14 @@ typedef struct ConnectionType { int (*listen)(connListener *listener); /* create/shutdown/close connection */ - connection* (*conn_create)(void); - connection* (*conn_create_accepted)(int fd, void *priv); + connection *(*conn_create)(void); + connection *(*conn_create_accepted)(int fd, void *priv); void (*shutdown)(struct connection *conn); void (*close)(struct connection *conn); /* connect & accept */ - int (*connect)(struct connection *conn, const char *addr, int port, const char *source_addr, ConnectionCallbackFunc connect_handler); + int (*connect)(struct connection *conn, const char *addr, int port, const char *source_addr, + ConnectionCallbackFunc connect_handler); int (*blocking_connect)(struct connection *conn, const char *addr, int port, long long timeout); int (*accept)(struct connection *conn, ConnectionCallbackFunc accept_handler); @@ -169,7 +170,7 @@ static inline int connAccept(connection *conn, ConnectionCallbackFunc accept_han * not be expected. */ static inline int connConnect(connection *conn, const char *addr, int port, const char *src_addr, - ConnectionCallbackFunc connect_handler) { + ConnectionCallbackFunc connect_handler) { return conn->type->connect(conn, addr, port, src_addr, connect_handler); } @@ -207,7 +208,7 @@ static inline int connWritev(connection *conn, const struct iovec *iov, int iovc } /* Read from the connection, behaves the same as read(2). - * + * * Like read(2), a short read is possible. A return value of 0 will indicate the * connection was closed, and -1 will indicate an error. * @@ -292,12 +293,10 @@ static inline int connAddr(connection *conn, char *ip, size_t ip_len, int *port, * (matches for ":"), the ip is surrounded by []. IP and port are just * separated by colons. This the standard to display addresses within the server. */ static inline int formatAddr(char *buf, size_t buf_len, char *ip, int port) { - return snprintf(buf, buf_len, strchr(ip,':') ? - "[%s]:%d" : "%s:%d", ip, port); + return snprintf(buf, buf_len, strchr(ip, ':') ? "[%s]:%d" : "%s:%d", ip, port); } -static inline int connFormatAddr(connection *conn, char *buf, size_t buf_len, int remote) -{ +static inline int connFormatAddr(connection *conn, char *buf, size_t buf_len, int remote) { char ip[CONN_ADDR_STR_LEN]; int port; @@ -356,7 +355,7 @@ static inline void *connGetPrivateData(connection *conn) { * For sockets, we always return "fd=" to maintain compatibility. */ static inline const char *connGetInfo(connection *conn, char *buf, size_t buf_len) { - snprintf(buf, buf_len-1, "fd=%i", conn == NULL ? -1 : conn->fd); + snprintf(buf, buf_len - 1, "fd=%i", conn == NULL ? -1 : conn->fd); return buf; } @@ -433,8 +432,9 @@ static inline int connListen(connListener *listener) { /* Get accept_handler of a connection type */ static inline aeFileProc *connAcceptHandler(ConnectionType *ct) { - if (ct) + if (ct) { return ct->accept_handler; + } return NULL; } @@ -450,4 +450,4 @@ static inline int connIsTLS(connection *conn) { return conn && conn->type == connectionTypeTls(); } -#endif /* __REDIS_CONNECTION_H */ +#endif /* __REDIS_CONNECTION_H */ diff --git a/src/connhelpers.h b/src/connhelpers.h index 28be1109b..fc8b1392c 100644 --- a/src/connhelpers.h +++ b/src/connhelpers.h @@ -76,13 +76,17 @@ static inline int connHasRefs(connection *conn) { */ static inline int callHandler(connection *conn, ConnectionCallbackFunc handler) { connIncrRefs(conn); - if (handler) handler(conn); + if (handler) { + handler(conn); + } connDecrRefs(conn); if (conn->flags & CONN_FLAG_CLOSE_SCHEDULED) { - if (!connHasRefs(conn)) connClose(conn); + if (!connHasRefs(conn)) { + connClose(conn); + } return 0; } return 1; } -#endif /* VALKEY_CONNHELPERS_H */ +#endif /* VALKEY_CONNHELPERS_H */ diff --git a/src/crc16.c b/src/crc16.c index 7b8c1dad0..2b77989ad 100644 --- a/src/crc16.c +++ b/src/crc16.c @@ -44,45 +44,32 @@ * Output for "123456789" : 31C3 */ -static const uint16_t crc16tab[256]= { - 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, - 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, - 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, - 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, - 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, - 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, - 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, - 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, - 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, - 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, - 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, - 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, - 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, - 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, - 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, - 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, - 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, - 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, - 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, - 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, - 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, - 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, - 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, - 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, - 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, - 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, - 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, - 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, - 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, - 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, - 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, - 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 -}; +static const uint16_t crc16tab[256] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, + 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, + 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, + 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, + 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, + 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, + 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, + 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, + 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, + 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, + 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, + 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, + 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, + 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, + 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; uint16_t crc16(const char *buf, int len) { int counter; uint16_t crc = 0; - for (counter = 0; counter < len; counter++) - crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *buf++)&0x00FF]; + for (counter = 0; counter < len; counter++) { + crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ *buf++) & 0x00FF]; + } return crc; } diff --git a/src/crc16_slottable.h b/src/crc16_slottable.h index 84e2aa028..770c35887 100644 --- a/src/crc16_slottable.h +++ b/src/crc16_slottable.h @@ -3,834 +3,1037 @@ /* A table of the shortest possible alphanumeric string that is mapped by crc16 * to any given cluster slot. - * + * * The array indexes are slot numbers, so that given a desired slot, this string is guaranteed * to make the cluster route a request to the shard holding this slot */ typedef char crc16_alphastring[4]; const crc16_alphastring crc16_slot_table[] = { -"06S", "Qi", "5L5", "4Iu", "4gY", "460", "1Y7", "1LV", "0QG", "ru", "7Ok", "4ji", "4DE", "65n", "2JH", "I8", "F9", "SX", "7nF", "4KD", -"4eh", "6PK", "2ke", "1Ng", "0Sv", "4L", "491", "4hX", "4Ft", "5C4", "2Hy", "09R", "021", "0cX", "4Xv", "6mU", "6Cy", "42R", "0Mt", "nF", -"cv", "1Pe", "5kK", "6NI", "74L", "4UF", "0nh", "MZ", "2TJ", "0ai", "4ZG", "6od", "6AH", "40c", "0OE", "lw", "aG", "0Bu", "5iz", "6Lx", -"5R7", "4Ww", "0lY", "Ok", "5n3", "4ks", "8YE", "7g", "2KR", "1nP", "714", "64t", "69D", "4Ho", "07I", "Ps", "2hN", "1ML", "4fC", "7CA", -"avs", "4iB", "0Rl", "5V", "2Ic", "08H", "4Gn", "66E", "aUo", "b4e", "05x", "RB", "8f", "8VD", "4dr", "5a2", "4zp", "6OS", "bl", "355", -"0or", "1j2", "75V", "bno", "4Yl", "6lO", "Ap", "0bB", "0Ln", "2yM", "6Bc", "43H", "4xA", "6Mb", "22D", "14", "0mC", "Nq", "6cN", "4Vm", -"ban", "aDl", "CA", "14Z", "8GG", "mm", "549", "41y", "53t", "464", "1Y3", "1LR", "06W", "Qm", "5L1", "4Iq", "4DA", "65j", "2JL", "1oN", -"0QC", "6y", "7Oo", "4jm", "4el", "6PO", "9x", "1Nc", "04f", "2EM", "7nB", "bqs", "4Fp", "5C0", "d6F", "09V", "0Sr", "4H", "495", "bRo", -"aio", "42V", "0Mp", "nB", "025", "17u", "4Xr", "6mQ", "74H", "4UB", "0nl", "3Kn", "cr", "1Pa", "5kO", "6NM", "6AL", "40g", "0OA", "ls", -"2TN", "0am", "4ZC", "aEr", "5R3", "4Ws", "18t", "Oo", "aC", "0Bq", "bCl", "afn", "2KV", "1nT", "5Uz", "64p", "5n7", "4kw", "0PY", "7c", -"2hJ", "1MH", "4fG", "6Sd", "7mi", "4Hk", "07M", "Pw", "2Ig", "08L", "4Gj", "66A", "7LD", "4iF", "0Rh", "5R", "8b", "1Oy", "4dv", "5a6", -"7oX", "4JZ", "0qt", "RF", "0ov", "LD", "4A9", "4TX", "4zt", "6OW", "bh", "0AZ", "z9", "oX", "6Bg", "43L", "4Yh", "6lK", "At", "0bF", -"0mG", "Nu", "6cJ", "4Vi", "4xE", "6Mf", "2vH", "10", "8GC", "mi", "5p5", "4uu", "5Kx", "4N8", "CE", "1pV", "0QO", "6u", "7Oc", "4ja", -"4DM", "65f", "3Za", "I0", "0rS", "Qa", "68V", "b7F", "4gQ", "468", "dSo", "285", "274", "4D", "499", "4hP", "b8G", "67W", "0h3", "09Z", -"F1", "SP", "7nN", "4KL", "51I", "6PC", "9t", "1No", "21g", "1Pm", "5kC", "6NA", "74D", "4UN", "X3", "MR", "029", "0cP", "bbM", "79t", -"4c3", "42Z", "8Dd", "nN", "aO", "8Ke", "4yS", "4l2", "76u", "635", "0lQ", "Oc", "BS", "W2", "4ZO", "6ol", "7Qa", "40k", "0OM", "2zn", -"69L", "4Hg", "07A", "2Fj", "2hF", "k6", "4fK", "6Sh", "7Ny", "6K9", "0PU", "7o", "2KZ", "1nX", "4EW", "4P6", "7oT", "4JV", "05p", "RJ", -"8n", "1Ou", "4dz", "6QY", "7LH", "4iJ", "d7", "qV", "2Ik", "1li", "4Gf", "66M", "4Yd", "6lG", "Ax", "0bJ", "z5", "oT", "6Bk", "4wH", -"4zx", "aeI", "bd", "0AV", "0oz", "LH", "4A5", "4TT", "5Kt", "4N4", "CI", "14R", "0NW", "me", "541", "41q", "4xI", "6Mj", "22L", "u4", -"0mK", "Ny", "6cF", "4Ve", "4DI", "65b", "2JD", "I4", "0QK", "6q", "7Og", "4je", "4gU", "4r4", "2iX", "1LZ", "0rW", "Qe", "5L9", "4Iy", -"4Fx", "5C8", "0h7", "1mw", "0Sz", "pH", "7MV", "4hT", "4ed", "6PG", "9p", "1Nk", "F5", "ST", "7nJ", "4KH", "7pH", "4UJ", "X7", "MV", -"cz", "1Pi", "5kG", "6NE", "4c7", "4vV", "0Mx", "nJ", "0v5", "0cT", "4Xz", "6mY", "6bX", "5GZ", "0lU", "Og", "aK", "0By", "4yW", "4l6", -"6AD", "40o", "0OI", "2zj", "BW", "W6", "4ZK", "6oh", "2hB", "k2", "4fO", "6Sl", "69H", "4Hc", "07E", "2Fn", "d5e", "83m", "4ES", "4P2", -"a0F", "bQL", "0PQ", "7k", "8j", "1Oq", "50W", "hbv", "7oP", "4JR", "05t", "RN", "2Io", "08D", "4Gb", "66I", "7LL", "4iN", "d3", "5Z", -"z1", "oP", "6Bo", "43D", "5IA", "6lC", "2Wm", "0bN", "8ff", "LL", "4A1", "4TP", "cPn", "aeM", "0T3", "0AR", "0NS", "ma", "545", "41u", -"5Kp", "4N0", "CM", "14V", "0mO", "2Xl", "6cB", "4Va", "4xM", "6Mn", "22H", "18", "04s", "SI", "7nW", "4KU", "4ey", "6PZ", "9m", "1Nv", -"e4", "pU", "7MK", "4hI", "4Fe", "67N", "2Hh", "09C", "06B", "Qx", "68O", "4Id", "4gH", "6Rk", "2iE", "j5", "0QV", "6l", "5o8", "4jx", -"4DT", "4Q5", "2JY", "82j", "BJ", "0ax", "4ZV", "4O7", "552", "40r", "0OT", "lf", "aV", "t7", "4yJ", "6Li", "6bE", "4Wf", "0lH", "Oz", -"2Vj", "0cI", "4Xg", "6mD", "6Ch", "42C", "0Me", "nW", "cg", "1Pt", "5kZ", "6NX", "7pU", "4UW", "0ny", "MK", "7LQ", "4iS", "267", "5G", -"0i0", "08Y", "b9D", "66T", "7oM", "4JO", "G2", "RS", "8w", "1Ol", "4dc", "7Aa", "atS", "4kb", "0PL", "7v", "2KC", "H3", "4EN", "64e", -"69U", "b6E", "07X", "Pb", "dRl", "296", "4fR", "4s3", "4xP", "4m1", "22U", "8Jf", "0mR", "0x3", "77v", "626", "5Km", "6no", "CP", "V1", -"0NN", "3kL", "7Pb", "41h", "4za", "6OB", "20d", "0AO", "Y0", "LQ", "6an", "4TM", "bcN", "78w", "Aa", "0bS", "8Eg", "oM", "4b0", "43Y", -"51T", "azL", "9i", "1Nr", "04w", "SM", "7nS", "4KQ", "4Fa", "67J", "2Hl", "09G", "e0", "4Y", "7MO", "4hM", "4gL", "6Ro", "2iA", "j1", -"06F", "2Gm", "68K", "5YA", "4DP", "4Q1", "d4f", "82n", "0QR", "6h", "a1E", "bPO", "556", "40v", "0OP", "lb", "BN", "15U", "4ZR", "4O3", -"6bA", "4Wb", "0lL", "2Yo", "aR", "t3", "4yN", "6Lm", "6Cl", "42G", "0Ma", "nS", "2Vn", "0cM", "4Xc", "79i", "74Y", "4US", "8ge", "MO", -"cc", "1Pp", "bAL", "adN", "0i4", "1lt", "5WZ", "66P", "7LU", "4iW", "0Ry", "5C", "8s", "1Oh", "4dg", "6QD", "7oI", "4JK", "G6", "RW", -"2KG", "H7", "4EJ", "64a", "7Nd", "4kf", "0PH", "7r", "1X8", "1MY", "4fV", "4s7", "69Q", "4Hz", "0sT", "Pf", "0mV", "Nd", "5S8", "4Vx", -"4xT", "4m5", "22Q", "0Cz", "0NJ", "mx", "7Pf", "41l", "5Ki", "6nk", "CT", "V5", "Y4", "LU", "6aj", "4TI", "4ze", "6OF", "by", "0AK", -"2l9", "oI", "4b4", "4wU", "4Yy", "6lZ", "Ae", "0bW", "0So", "4U", "7MC", "4hA", "4Fm", "67F", "3XA", "09K", "0ps", "SA", "aTl", "b5f", -"4eq", "6PR", "9e", "8WG", "8XF", "6d", "5o0", "4jp", "707", "65w", "1z2", "1oS", "06J", "Qp", "68G", "4Il", "53i", "6Rc", "2iM", "1LO", -"23G", "07", "4yB", "6La", "6bM", "4Wn", "18i", "Or", "BB", "0ap", "c4D", "aEo", "5q2", "40z", "8FD", "ln", "co", "346", "5kR", "6NP", -"74U", "bol", "0nq", "MC", "2Vb", "0cA", "4Xo", "6mL", "7SA", "42K", "0Mm", "2xN", "7oE", "4JG", "05a", "2DJ", "2jf", "1Od", "4dk", "6QH", -"482", "5yz", "0Ru", "5O", "0i8", "08Q", "4Gw", "5B7", "5M6", "4Hv", "07P", "Pj", "1X4", "1MU", "4fZ", "473", "7Nh", "4kj", "0PD", "sv", -"2KK", "1nI", "4EF", "64m", "5Ke", "6ng", "CX", "V9", "0NF", "mt", "7Pj", "4uh", "4xX", "4m9", "1F6", "0Cv", "0mZ", "Nh", "5S4", "4Vt", -"4Yu", "6lV", "Ai", "16r", "0Lw", "oE", "4b8", "43Q", "4zi", "6OJ", "bu", "0AG", "Y8", "LY", "6af", "4TE", "4Fi", "67B", "2Hd", "09O", -"e8", "4Q", "7MG", "4hE", "4eu", "6PV", "9a", "1Nz", "0pw", "SE", "aTh", "4KY", "4DX", "4Q9", "1z6", "1oW", "0QZ", "rh", "5o4", "4jt", -"4gD", "6Rg", "2iI", "j9", "06N", "Qt", "68C", "4Ih", "6bI", "4Wj", "0lD", "Ov", "aZ", "03", "4yF", "6Le", "5q6", "4tv", "0OX", "lj", -"BF", "0at", "4ZZ", "6oy", "74Q", "5Ez", "0nu", "MG", "ck", "1Px", "5kV", "6NT", "6Cd", "42O", "0Mi", "2xJ", "2Vf", "0cE", "4Xk", "6mH", -"2jb", "8VY", "4do", "6QL", "7oA", "4JC", "05e", "2DN", "d7E", "08U", "4Gs", "5B3", "486", "bSl", "0Rq", "5K", "1X0", "1MQ", "52w", "477", -"5M2", "4Hr", "07T", "Pn", "2KO", "1nM", "4EB", "64i", "7Nl", "4kn", "8YX", "7z", "0NB", "mp", "7Pn", "41d", "5Ka", "6nc", "2UM", "14G", -"19w", "Nl", "5S0", "4Vp", "bBo", "agm", "1F2", "0Cr", "0Ls", "oA", "ahl", "43U", "4Yq", "6lR", "Am", "16v", "0oo", "2ZL", "6ab", "4TA", -"4zm", "6ON", "bq", "0AC", "2VY", "0cz", "4XT", "4M5", "570", "42p", "0MV", "nd", "cT", "v5", "5ki", "6Nk", "74n", "4Ud", "0nJ", "Mx", -"By", "0aK", "4Ze", "6oF", "6Aj", "40A", "y4", "lU", "ae", "0BW", "4yy", "581", "4B4", "4WU", "18R", "OI", "06q", "QK", "7lU", "4IW", -"53R", "6RX", "0I4", "1Lt", "g6", "rW", "7OI", "4jK", "4Dg", "65L", "2Jj", "1oh", "0pH", "Sz", "7nd", "4Kf", "4eJ", "6Pi", "2kG", "h7", -"0ST", "4n", "7Mx", "4hz", "4FV", "4S7", "1x8", "09p", "4zR", "4o3", "bN", "8Hd", "0oP", "Lb", "75t", "604", "4YN", "6lm", "AR", "T3", -"0LL", "2yo", "6BA", "43j", "4xc", "agR", "22f", "0CM", "0ma", "NS", "6cl", "4VO", "baL", "aDN", "Cc", "14x", "8Ge", "mO", "7PQ", "4uS", -"7NS", "4kQ", "245", "7E", "0k2", "1nr", "coo", "64V", "69f", "4HM", "E0", "PQ", "2hl", "1Mn", "4fa", "6SB", "7Lb", "5yA", "0RN", "5t", -"2IA", "J1", "4GL", "66g", "aUM", "b4G", "05Z", "0d3", "8D", "8Vf", "4dP", "459", "574", "42t", "0MR", "0X3", "dln", "17W", "4XP", "4M1", -"74j", "5EA", "0nN", "3KL", "cP", "29", "5km", "6No", "6An", "40E", "y0", "lQ", "2Tl", "0aO", "4Za", "6oB", "4B0", "4WQ", "18V", "OM", -"aa", "0BS", "bCN", "585", "53V", "axN", "0I0", "1Lp", "06u", "QO", "68x", "4IS", "4Dc", "65H", "2Jn", "1ol", "g2", "rS", "7OM", "4jO", -"4eN", "6Pm", "9Z", "h3", "04D", "2Eo", "aTS", "4Kb", "4FR", "4S3", "d6d", "09t", "0SP", "4j", "a3G", "bRM", "0oT", "Lf", "6aY", "4Tz", -"4zV", "4o7", "bJ", "0Ax", "0LH", "oz", "6BE", "43n", "4YJ", "6li", "AV", "T7", "0me", "NW", "6ch", "4VK", "4xg", "6MD", "22b", "0CI", -"0Ny", "mK", "7PU", "4uW", "5KZ", "6nX", "Cg", "1pt", "0k6", "1nv", "4Ey", "64R", "7NW", "4kU", "241", "7A", "2hh", "1Mj", "4fe", "6SF", -"69b", "4HI", "E4", "PU", "2IE", "J5", "4GH", "66c", "7Lf", "4id", "0RJ", "5p", "2jY", "8Vb", "4dT", "4q5", "5O8", "4Jx", "0qV", "Rd", -"21E", "25", "5ka", "6Nc", "74f", "4Ul", "0nB", "Mp", "1f2", "0cr", "bbo", "79V", "578", "42x", "395", "nl", "am", "364", "4yq", "589", -"76W", "bmn", "0ls", "OA", "Bq", "0aC", "4Zm", "6oN", "6Ab", "40I", "0Oo", "2zL", "0Qm", "6W", "7OA", "4jC", "4Do", "65D", "2Jb", "82Q", -"06y", "QC", "68t", "b7d", "4gs", "5b3", "dSM", "8UE", "8ZD", "4f", "5m2", "4hr", "725", "67u", "1x0", "09x", "04H", "Sr", "7nl", "4Kn", -"4eB", "6Pa", "9V", "1NM", "4YF", "6le", "AZ", "0bh", "0LD", "ov", "6BI", "43b", "4zZ", "6Oy", "bF", "0At", "0oX", "Lj", "5Q6", "4Tv", -"5KV", "6nT", "Ck", "14p", "0Nu", "mG", "7PY", "41S", "4xk", "6MH", "22n", "0CE", "0mi", "2XJ", "6cd", "4VG", "69n", "4HE", "E8", "PY", -"2hd", "1Mf", "4fi", "6SJ", "ath", "4kY", "0Pw", "7M", "2Kx", "1nz", "4Eu", "6pV", "5O4", "4Jt", "05R", "Rh", "8L", "1OW", "4dX", "451", -"7Lj", "4ih", "0RF", "qt", "2II", "J9", "4GD", "66o", "74b", "4Uh", "0nF", "Mt", "cX", "21", "5ke", "6Ng", "5s4", "4vt", "0MZ", "nh", -"1f6", "0cv", "4XX", "4M9", "4B8", "4WY", "0lw", "OE", "ai", "1Rz", "4yu", "6LV", "6Af", "40M", "y8", "lY", "Bu", "0aG", "4Zi", "6oJ", -"4Dk", "6qH", "2Jf", "1od", "0Qi", "6S", "7OE", "4jG", "4gw", "5b7", "0I8", "1Lx", "0ru", "QG", "68p", "5Yz", "4FZ", "67q", "1x4", "1mU", -"0SX", "4b", "5m6", "4hv", "4eF", "6Pe", "9R", "1NI", "04L", "Sv", "7nh", "4Kj", "8EX", "or", "6BM", "43f", "4YB", "6la", "2WO", "0bl", -"8fD", "Ln", "5Q2", "4Tr", "cPL", "aeo", "bB", "0Ap", "0Nq", "mC", "ajn", "41W", "5KR", "6nP", "Co", "14t", "0mm", "2XN", "77I", "4VC", -"4xo", "6ML", "22j", "0CA", "3xA", "1Mb", "4fm", "6SN", "69j", "4HA", "07g", "2FL", "d5G", "83O", "4Eq", "64Z", "a0d", "bQn", "0Ps", "7I", -"8H", "1OS", "50u", "455", "5O0", "4Jp", "05V", "Rl", "2IM", "08f", "5Wa", "66k", "7Ln", "4il", "0RB", "5x", "Bh", "0aZ", "4Zt", "6oW", -"4a9", "40P", "0Ov", "lD", "at", "0BF", "4yh", "6LK", "6bg", "4WD", "Z9", "OX", "2VH", "U8", "4XE", "6mf", "6CJ", "42a", "0MG", "nu", -"cE", "1PV", "5kx", "4n8", "5P5", "4Uu", "8gC", "Mi", "04Q", "Sk", "5N7", "4Kw", "51r", "442", "9O", "1NT", "0SE", "pw", "7Mi", "4hk", -"4FG", "67l", "2HJ", "09a", "3", "QZ", "68m", "4IF", "4gj", "6RI", "2ig", "1Le", "0Qt", "6N", "7OX", "4jZ", "4Dv", "5A6", "0j9", "1oy", -"4xr", "6MQ", "22w", "377", "0mp", "NB", "77T", "blm", "5KO", "6nM", "Cr", "14i", "0Nl", "3kn", "ajs", "41J", "4zC", "aer", "20F", "36", -"0oA", "Ls", "6aL", "4To", "bcl", "78U", "AC", "0bq", "386", "oo", "5r3", "4ws", "5l1", "4iq", "9Kf", "5e", "1y3", "1lR", "736", "66v", -"7oo", "4Jm", "05K", "Rq", "8U", "1ON", "4dA", "6Qb", "7NB", "bQs", "0Pn", "7T", "2Ka", "1nc", "4El", "64G", "69w", "b6g", "07z", "1v2", -"dRN", "8TF", "4fp", "5c0", "akm", "40T", "0Or", "1J2", "Bl", "15w", "4Zp", "6oS", "6bc", "5Ga", "0ln", "2YM", "ap", "0BB", "4yl", "6LO", -"6CN", "42e", "0MC", "nq", "2VL", "0co", "4XA", "6mb", "5P1", "4Uq", "8gG", "Mm", "cA", "1PR", "bAn", "adl", "51v", "446", "9K", "1NP", -"04U", "So", "5N3", "4Ks", "4FC", "67h", "2HN", "09e", "0SA", "ps", "7Mm", "4ho", "4gn", "6RM", "2ic", "1La", "7", "2GO", "68i", "4IB", -"4Dr", "5A2", "d4D", "82L", "0Qp", "6J", "a1g", "bPm", "0mt", "NF", "6cy", "4VZ", "4xv", "6MU", "0V9", "0CX", "0Nh", "mZ", "7PD", "41N", -"5KK", "6nI", "Cv", "14m", "0oE", "Lw", "6aH", "4Tk", "4zG", "6Od", "20B", "32", "0LY", "ok", "5r7", "4ww", "5Iz", "6lx", "AG", "0bu", -"1y7", "1lV", "4GY", "4R8", "5l5", "4iu", "1Bz", "5a", "8Q", "i8", "4dE", "6Qf", "7ok", "4Ji", "05O", "Ru", "2Ke", "1ng", "4Eh", "64C", -"7NF", "4kD", "f9", "7P", "2hy", "3m9", "4ft", "5c4", "69s", "4HX", "0sv", "PD", "23e", "0BN", "5iA", "6LC", "6bo", "4WL", "Z1", "OP", -"0t3", "0aR", "c4f", "aEM", "4a1", "40X", "8Ff", "lL", "cM", "8Ig", "5kp", "4n0", "74w", "617", "0nS", "Ma", "3Fa", "U0", "4XM", "6mn", -"6CB", "42i", "0MO", "2xl", "0SM", "4w", "7Ma", "4hc", "4FO", "67d", "2HB", "K2", "04Y", "Sc", "aTN", "b5D", "4eS", "4p2", "9G", "8We", -"256", "6F", "7OP", "4jR", "cnl", "65U", "0j1", "1oq", "D3", "QR", "68e", "4IN", "4gb", "6RA", "2io", "1Lm", "5KG", "6nE", "Cz", "14a", -"x7", "mV", "7PH", "41B", "4xz", "592", "0V5", "0CT", "0mx", "NJ", "4C7", "4VV", "4YW", "4L6", "AK", "0by", "0LU", "og", "563", "43s", -"4zK", "6Oh", "bW", "w6", "0oI", "2Zj", "6aD", "4Tg", "7og", "4Je", "05C", "Ry", "2jD", "i4", "4dI", "6Qj", "5l9", "4iy", "0RW", "5m", -"2IX", "08s", "4GU", "4R4", "7mV", "4HT", "07r", "PH", "0H7", "1Mw", "4fx", "5c8", "7NJ", "4kH", "f5", "sT", "2Ki", "1nk", "4Ed", "64O", -"6bk", "4WH", "Z5", "OT", "ax", "0BJ", "4yd", "6LG", "4a5", "4tT", "0Oz", "lH", "Bd", "0aV", "4Zx", "aEI", "5P9", "4Uy", "0nW", "Me", -"cI", "1PZ", "5kt", "4n4", "6CF", "42m", "0MK", "ny", "2VD", "U4", "4XI", "6mj", "4FK", "6sh", "2HF", "K6", "0SI", "4s", "7Me", "4hg", -"4eW", "4p6", "9C", "1NX", "0pU", "Sg", "7ny", "6k9", "4Dz", "65Q", "0j5", "1ou", "0Qx", "6B", "7OT", "4jV", "4gf", "6RE", "2ik", "1Li", -"D7", "QV", "68a", "4IJ", "x3", "mR", "7PL", "41F", "5KC", "6nA", "2Uo", "14e", "19U", "NN", "4C3", "4VR", "bBM", "596", "0V1", "0CP", -"0LQ", "oc", "567", "43w", "4YS", "4L2", "AO", "16T", "0oM", "2Zn", "75i", "4Tc", "4zO", "6Ol", "bS", "w2", "8Y", "i0", "4dM", "6Qn", -"7oc", "4Ja", "05G", "2Dl", "d7g", "08w", "4GQ", "4R0", "a2D", "bSN", "0RS", "5i", "0H3", "1Ms", "52U", "ayM", "7mR", "4HP", "07v", "PL", -"2Km", "1no", "5UA", "64K", "7NN", "4kL", "f1", "7X", "5nw", "4k7", "fJ", "0Ex", "0kT", "Hf", "6eY", "4Pz", "5Mk", "6hi", "EV", "P7", -"0HH", "kz", "6FE", "47n", "48o", "6ID", "26b", "0GI", "0ie", "JW", "6gh", "4RK", "5OZ", "6jX", "Gg", "0dU", "0Jy", "iK", "4d6", "4qW", -"4z4", "4oU", "1DZ", "3A", "Ye", "0zW", "4Ay", "5D9", "6yj", "4LI", "A4", "TU", "zy", "0YK", "4be", "6WF", "6XG", "4md", "0VJ", "1p", -"2ME", "N5", "4CH", "62c", "5K8", "4Nx", "0uV", "Vd", "xH", "8Rb", "5pu", "4u5", "D", "13W", "5Lq", "4I1", "534", "46t", "0IR", "28y", -"gP", "69", "5om", "6Jo", "6dC", "5AA", "0jN", "3OL", "2Pl", "0eO", "aT1", "6kB", "6En", "44E", "98", "hQ", "ea", "0FS", "49u", "abL", -"4F0", "4SQ", "8ag", "KM", "02u", "UO", "4X2", "4MS", "57V", "a8F", "0M0", "0XQ", "c2", "vS", "7KM", "4nO", "5PB", "61H", "2Nn", "1kl", -"00D", "2Ao", "6zA", "4Ob", "4aN", "6Tm", "yR", "l3", "0WP", "0j", "a7G", "58W", "4BR", "4W3", "ZN", "84l", "0kP", "Hb", "71t", "644", -"5ns", "4k3", "fN", "8Ld", "0HL", "29g", "6FA", "47j", "5Mo", "6hm", "ER", "P3", "0ia", "JS", "6gl", "4RO", "48k", "7Ya", "26f", "0GM", -"8Ce", "iO", "4d2", "4qS", "beL", "hYw", "Gc", "0dQ", "Ya", "0zS", "cko", "60V", "4z0", "4oQ", "205", "3E", "2ll", "0YO", "4ba", "6WB", -"6yn", "4LM", "A0", "TQ", "2MA", "N1", "4CL", "62g", "6XC", "59I", "0VN", "1t", "xL", "8Rf", "54y", "419", "aQM", "b0G", "01Z", "3PP", -"530", "46p", "0IV", "jd", "DH", "0gz", "5Lu", "4I5", "6dG", "4Qd", "0jJ", "Ix", "gT", "r5", "5oi", "6Jk", "6Ej", "44A", "0Kg", "hU", -"Fy", "0eK", "5ND", "6kF", "4F4", "4SU", "1xZ", "KI", "ee", "0FW", "49q", "5x9", "57R", "6VX", "0M4", "0XU", "02q", "UK", "4X6", "4MW", -"5PF", "61L", "2Nj", "1kh", "c6", "vW", "7KI", "4nK", "4aJ", "6Ti", "yV", "l7", "0tH", "Wz", "6zE", "4Of", "4BV", "4W7", "ZJ", "0yx", -"0WT", "0n", "6YY", "4lz", "5Mc", "6ha", "2SO", "0fl", "1Xa", "kr", "6FM", "47f", "bDm", "aao", "fB", "0Ep", "8bD", "Hn", "5U2", "4Pr", -"5OR", "5Z3", "Go", "10t", "0Jq", "iC", "ann", "45W", "48g", "6IL", "ds", "0GA", "0im", "3Lo", "73I", "4RC", "6yb", "4LA", "03g", "2BL", -"zq", "0YC", "4bm", "6WN", "a4d", "bUn", "0Ts", "3I", "Ym", "87O", "4Aq", "5D1", "5K0", "4Np", "01V", "Vl", "2nQ", "1KS", "54u", "415", -"6XO", "4ml", "0VB", "1x", "2MM", "0xn", "5Sa", "62k", "gX", "61", "5oe", "6Jg", "6dK", "4Qh", "0jF", "It", "L", "0gv", "5Ly", "4I9", -"5w4", "4rt", "0IZ", "jh", "ei", "1Vz", "5mT", "5x5", "4F8", "4SY", "0hw", "KE", "Fu", "0eG", "5NH", "6kJ", "6Ef", "44M", "90", "hY", -"0Ui", "2S", "7KE", "4nG", "5PJ", "6uH", "Xw", "1kd", "0vu", "UG", "6xx", "790", "4cw", "5f7", "0M8", "0XY", "0WX", "0b", "5i6", "4lv", -"4BZ", "63q", "ZF", "0yt", "00L", "Wv", "6zI", "4Oj", "4aF", "6Te", "yZ", "0Zh", "0HD", "kv", "6FI", "47b", "5Mg", "6he", "EZ", "0fh", -"0kX", "Hj", "5U6", "4Pv", "7N9", "6Ky", "fF", "0Et", "0Ju", "iG", "6Dx", "45S", "5OV", "5Z7", "Gk", "0dY", "0ii", "3Lk", "6gd", "4RG", -"48c", "6IH", "dw", "0GE", "zu", "0YG", "4bi", "6WJ", "6yf", "4LE", "A8", "TY", "Yi", "1jz", "4Au", "5D5", "4z8", "4oY", "0Tw", "3M", -"xD", "1KW", "54q", "411", "5K4", "4Nt", "01R", "Vh", "2MI", "N9", "4CD", "62o", "6XK", "4mh", "0VF", "ut", "6dO", "4Ql", "0jB", "Ip", -"25E", "65", "5oa", "6Jc", "538", "46x", "9Pg", "jl", "H", "0gr", "bfo", "aCm", "72W", "bin", "0hs", "KA", "em", "324", "49y", "5x1", -"6Eb", "44I", "94", "3nm", "Fq", "0eC", "5NL", "6kN", "5PN", "61D", "Xs", "86Q", "0Um", "2W", "7KA", "4nC", "4cs", "5f3", "39W", "8QE", -"02y", "UC", "aRn", "794", "765", "63u", "ZB", "0yp", "9Ne", "0f", "5i2", "4lr", "4aB", "6Ta", "2oO", "0Zl", "00H", "Wr", "6zM", "4On", -"5lW", "5y6", "dj", "0GX", "0it", "JF", "6gy", "4RZ", "5OK", "6jI", "Gv", "0dD", "83", "iZ", "6De", "45N", "5nf", "6Kd", "24B", "72", -"0kE", "Hw", "6eH", "4Pk", "5Mz", "6hx", "EG", "0fu", "0HY", "kk", "5v7", "4sw", "5h5", "4mu", "1Fz", "1a", "2MT", "0xw", "4CY", "4V8", -"7kk", "4Ni", "01O", "Vu", "xY", "m8", "54l", "6Uf", "6Zg", "4oD", "b9", "3P", "Yt", "0zF", "4Ah", "60C", "4Y9", "4LX", "0wv", "TD", -"zh", "0YZ", "4bt", "5g4", "Fl", "11w", "5NQ", "6kS", "aom", "44T", "0Kr", "1N2", "ep", "0FB", "49d", "6HO", "6fc", "5Ca", "0hn", "3Ml", -"U", "0go", "bfr", "6ib", "6GN", "46e", "0IC", "jq", "gA", "0Ds", "bEn", "hyU", "5T1", "4Qq", "8cG", "Im", "00U", "Wo", "5J3", "4Os", -"55v", "406", "yC", "0Zq", "0WA", "ts", "6YL", "4lo", "4BC", "63h", "2LN", "0ym", "02d", "2CO", "6xa", "4MB", "4cn", "6VM", "2mc", "1Ha", -"0Up", "2J", "a5g", "bTm", "5PS", "5E2", "Xn", "86L", "0ip", "JB", "73T", "bhm", "48z", "5y2", "dn", "337", "87", "3on", "6Da", "45J", -"5OO", "6jM", "Gr", "10i", "0kA", "Hs", "6eL", "4Po", "5nb", "aar", "24F", "76", "8AE", "ko", "5v3", "4ss", "bgl", "aBn", "EC", "0fq", -"2MP", "0xs", "776", "62v", "5h1", "4mq", "9Of", "1e", "2nL", "1KN", "54h", "6Ub", "7ko", "4Nm", "01K", "Vq", "Yp", "0zB", "4Al", "60G", -"6Zc", "bUs", "0Tn", "3T", "zl", "8PF", "4bp", "5g0", "aSm", "787", "03z", "1r2", "4e9", "44P", "0Kv", "hD", "Fh", "0eZ", "5NU", "6kW", -"6fg", "4SD", "0hj", "KX", "et", "0FF", "5mI", "6HK", "6GJ", "46a", "0IG", "ju", "Q", "Q8", "5Ld", "6if", "5T5", "4Qu", "1zz", "Ii", -"gE", "0Dw", "5ox", "4j8", "55r", "402", "yG", "0Zu", "00Q", "Wk", "5J7", "4Ow", "4BG", "63l", "2LJ", "0yi", "0WE", "tw", "6YH", "4lk", -"4cj", "6VI", "2mg", "0XD", "0vh", "UZ", "6xe", "4MF", "5PW", "5E6", "Xj", "1ky", "0Ut", "2N", "7KX", "4nZ", "5OC", "6jA", "2Qo", "0dL", -"1ZA", "iR", "6Dm", "45F", "48v", "acO", "db", "0GP", "94M", "JN", "4G3", "4RR", "5Mr", "4H2", "EO", "12T", "0HQ", "kc", "527", "47w", -"5nn", "6Kl", "fS", "s2", "0kM", "3NO", "71i", "4Pc", "7kc", "4Na", "01G", "3PM", "xQ", "m0", "54d", "6Un", "a6D", "59T", "0VS", "1i", -"197", "85o", "4CQ", "4V0", "4Y1", "4LP", "03v", "TL", "0L3", "0YR", "56U", "a9E", "6Zo", "4oL", "b1", "3X", "2Om", "0zN", "5QA", "60K", -"ex", "0FJ", "49l", "6HG", "6fk", "4SH", "0hf", "KT", "Fd", "0eV", "5NY", "aAI", "4e5", "4pT", "0Kz", "hH", "gI", "1TZ", "5ot", "4j4", -"5T9", "4Qy", "0jW", "Ie", "DU", "Q4", "5Lh", "6ij", "6GF", "46m", "0IK", "jy", "0WI", "0s", "6YD", "4lg", "4BK", "6wh", "ZW", "O6", -"0tU", "Wg", "6zX", "6o9", "4aW", "4t6", "yK", "0Zy", "0Ux", "2B", "7KT", "4nV", "bzI", "61Q", "Xf", "1ku", "02l", "UV", "6xi", "4MJ", -"4cf", "6VE", "2mk", "0XH", "0Jd", "iV", "6Di", "45B", "5OG", "6jE", "Gz", "0dH", "0ix", "JJ", "4G7", "4RV", "48r", "6IY", "df", "0GT", -"0HU", "kg", "523", "47s", "5Mv", "4H6", "EK", "0fy", "0kI", "3NK", "6eD", "4Pg", "5nj", "6Kh", "fW", "s6", "xU", "m4", "5ph", "6Uj", -"7kg", "4Ne", "01C", "Vy", "193", "1hZ", "4CU", "4V4", "5h9", "4my", "0VW", "1m", "zd", "0YV", "4bx", "5g8", "4Y5", "4LT", "03r", "TH", -"Yx", "0zJ", "4Ad", "60O", "6Zk", "4oH", "b5", "wT", "6fo", "4SL", "0hb", "KP", "27e", "0FN", "49h", "6HC", "4e1", "44X", "8Bf", "hL", -"0p3", "0eR", "bdO", "aAM", "70w", "657", "0jS", "Ia", "gM", "8Mg", "5op", "4j0", "6GB", "46i", "0IO", "28d", "Y", "Q0", "5Ll", "6in", -"4BO", "63d", "ZS", "O2", "0WM", "0w", "7Ia", "4lc", "4aS", "4t2", "yO", "8Se", "00Y", "Wc", "aPN", "b1D", "bzM", "61U", "Xb", "1kq", -"216", "2F", "7KP", "4nR", "4cb", "6VA", "2mo", "0XL", "02h", "UR", "6xm", "4MN", "5j7", "4ow", "0TY", "3c", "YG", "0zu", "5Qz", "60p", -"6yH", "4Lk", "03M", "Tw", "2lJ", "0Yi", "4bG", "6Wd", "6Xe", "4mF", "0Vh", "1R", "2Mg", "0xD", "4Cj", "62A", "7kX", "4NZ", "0ut", "VF", -"xj", "1Ky", "5pW", "5e6", "5nU", "6KW", "fh", "0EZ", "0kv", "HD", "4E9", "4PX", "5MI", "6hK", "Et", "0fF", "0Hj", "kX", "6Fg", "47L", -"48M", "6If", "dY", "50", "0iG", "Ju", "6gJ", "4Ri", "5Ox", "4J8", "GE", "0dw", "1Zz", "ii", "5t5", "4qu", "02W", "Um", "5H1", "4Mq", -"57t", "424", "2mP", "0Xs", "0UC", "2y", "7Ko", "4nm", "bzr", "61j", "2NL", "1kN", "00f", "2AM", "6zc", "bus", "4al", "6TO", "yp", "0ZB", -"0Wr", "0H", "a7e", "58u", "4Bp", "5G0", "Zl", "84N", "f", "13u", "5LS", "5Y2", "amo", "46V", "0Ip", "jB", "gr", "1Ta", "5oO", "6JM", -"6da", "4QB", "0jl", "3On", "2PN", "0em", "5Nb", "aAr", "6EL", "44g", "0KA", "hs", "eC", "0Fq", "49W", "abn", "5V3", "4Ss", "8aE", "Ko", -"YC", "0zq", "754", "60t", "5j3", "4os", "9Md", "3g", "2lN", "0Ym", "4bC", "7GA", "6yL", "4Lo", "03I", "Ts", "2Mc", "1ha", "4Cn", "62E", -"6Xa", "4mB", "0Vl", "1V", "xn", "8RD", "5pS", "5e2", "aQo", "b0e", "01x", "VB", "0kr", "1n2", "71V", "bjo", "5nQ", "6KS", "fl", "315", -"0Hn", "29E", "6Fc", "47H", "5MM", "6hO", "Ep", "0fB", "0iC", "Jq", "6gN", "4Rm", "48I", "6Ib", "26D", "54", "8CG", "im", "509", "45y", -"ben", "hYU", "GA", "0ds", "4cY", "420", "2mT", "0Xw", "02S", "Ui", "5H5", "4Mu", "5Pd", "61n", "XY", "M8", "0UG", "vu", "7Kk", "4ni", -"4ah", "6TK", "yt", "0ZF", "B9", "WX", "6zg", "4OD", "4Bt", "5G4", "Zh", "0yZ", "0Wv", "0L", "4y9", "4lX", "6Gy", "46R", "0It", "jF", -"b", "0gX", "5LW", "5Y6", "6de", "4QF", "0jh", "IZ", "gv", "0DD", "5oK", "6JI", "6EH", "44c", "0KE", "hw", "2PJ", "0ei", "5Nf", "6kd", -"5V7", "4Sw", "0hY", "Kk", "eG", "0Fu", "49S", "6Hx", "7ia", "4Lc", "03E", "2Bn", "zS", "o2", "4bO", "6Wl", "a4F", "bUL", "0TQ", "3k", -"YO", "87m", "4AS", "4T2", "7kP", "4NR", "01t", "VN", "xb", "1Kq", "54W", "hfv", "6Xm", "4mN", "1FA", "1Z", "2Mo", "0xL", "4Cb", "62I", -"5MA", "6hC", "2Sm", "0fN", "0Hb", "kP", "6Fo", "47D", "bDO", "aaM", "0P3", "0ER", "8bf", "HL", "4E1", "4PP", "5Op", "4J0", "GM", "10V", -"0JS", "ia", "505", "45u", "48E", "6In", "dQ", "58", "0iO", "3LM", "6gB", "4Ra", "0UK", "2q", "7Kg", "4ne", "5Ph", "61b", "XU", "M4", -"0vW", "Ue", "5H9", "4My", "4cU", "4v4", "2mX", "1HZ", "0Wz", "tH", "4y5", "4lT", "4Bx", "5G8", "Zd", "0yV", "B5", "WT", "6zk", "4OH", -"4ad", "6TG", "yx", "0ZJ", "gz", "0DH", "5oG", "6JE", "6di", "4QJ", "0jd", "IV", "n", "0gT", "680", "6iY", "4g7", "4rV", "0Ix", "jJ", -"eK", "0Fy", "5mv", "4h6", "6fX", "5CZ", "0hU", "Kg", "FW", "S6", "5Nj", "6kh", "6ED", "44o", "0KI", "3nK", "zW", "o6", "4bK", "6Wh", -"6yD", "4Lg", "03A", "2Bj", "YK", "0zy", "4AW", "4T6", "6ZX", "6O9", "0TU", "3o", "xf", "1Ku", "54S", "6UY", "7kT", "4NV", "01p", "VJ", -"2Mk", "0xH", "4Cf", "62M", "6Xi", "4mJ", "0Vd", "uV", "0Hf", "kT", "6Fk", "4sH", "5ME", "6hG", "Ex", "0fJ", "0kz", "HH", "4E5", "4PT", -"5nY", "aaI", "fd", "0EV", "0JW", "ie", "501", "45q", "5Ot", "4J4", "GI", "10R", "0iK", "Jy", "6gF", "4Re", "48A", "6Ij", "dU", "q4", -"5Pl", "61f", "XQ", "M0", "0UO", "2u", "7Kc", "4na", "4cQ", "428", "39u", "8Qg", "0vS", "Ua", "aRL", "b3F", "bxO", "63W", "0l3", "0yR", -"234", "0D", "4y1", "4lP", "55I", "6TC", "2om", "0ZN", "B1", "WP", "6zo", "4OL", "6dm", "4QN", "1zA", "IR", "25g", "0DL", "5oC", "6JA", -"4g3", "46Z", "9PE", "jN", "j", "0gP", "684", "aCO", "72u", "675", "0hQ", "Kc", "eO", "8Oe", "5mr", "4h2", "7Ua", "44k", "0KM", "3nO", -"FS", "S2", "5Nn", "6kl", "4x6", "4mW", "0Vy", "1C", "0m4", "0xU", "5SZ", "62P", "7kI", "4NK", "C6", "VW", "2nj", "1Kh", "54N", "6UD", -"6ZE", "4of", "0TH", "3r", "YV", "L7", "4AJ", "60a", "6yY", "4Lz", "0wT", "Tf", "zJ", "0Yx", "4bV", "4w7", "5lu", "4i5", "dH", "0Gz", -"0iV", "Jd", "5W8", "4Rx", "5Oi", "6jk", "GT", "R5", "0JJ", "ix", "6DG", "45l", "5nD", "6KF", "fy", "0EK", "0kg", "HU", "6ej", "4PI", -"5MX", "5X9", "Ee", "0fW", "1XZ", "kI", "4f4", "4sU", "00w", "WM", "4Z0", "4OQ", "55T", "hgu", "ya", "0ZS", "a0", "0Y", "6Yn", "4lM", -"4Ba", "63J", "2Ll", "0yO", "02F", "2Cm", "6xC", "aG0", "4cL", "6Vo", "2mA", "n1", "0UR", "2h", "a5E", "bTO", "5Pq", "4U1", "XL", "86n", -"FN", "11U", "5Ns", "4K3", "516", "44v", "0KP", "hb", "eR", "p3", "49F", "6Hm", "6fA", "4Sb", "0hL", "3MN", "w", "0gM", "5LB", "7ya", -"6Gl", "46G", "0Ia", "jS", "gc", "0DQ", "bEL", "hyw", "4D2", "4QS", "8ce", "IO", "0m0", "0xQ", "byL", "62T", "4x2", "4mS", "227", "1G", -"2nn", "1Kl", "54J", "7Ea", "7kM", "4NO", "C2", "VS", "YR", "L3", "4AN", "60e", "6ZA", "4ob", "0TL", "3v", "zN", "8Pd", "4bR", "4w3", -"aSO", "b2E", "03X", "Tb", "0iR", "3LP", "73v", "666", "48X", "4i1", "dL", "8Nf", "0JN", "3oL", "6DC", "45h", "5Om", "6jo", "GP", "R1", -"0kc", "HQ", "6en", "4PM", "a09", "6KB", "24d", "0EO", "8Ag", "kM", "4f0", "47Y", "697", "aBL", "Ea", "0fS", "4ay", "5d9", "ye", "0ZW", -"00s", "WI", "4Z4", "4OU", "4Be", "63N", "Zy", "0yK", "a4", "tU", "6Yj", "4lI", "4cH", "6Vk", "2mE", "n5", "02B", "Ux", "6xG", "4Md", -"5Pu", "4U5", "XH", "86j", "0UV", "2l", "5k8", "4nx", "512", "44r", "0KT", "hf", "FJ", "0ex", "5Nw", "4K7", "6fE", "4Sf", "0hH", "Kz", -"eV", "p7", "49B", "6Hi", "6Gh", "46C", "0Ie", "jW", "s", "0gI", "5LF", "6iD", "4D6", "4QW", "0jy", "IK", "gg", "0DU", "5oZ", "6JX", -"7kA", "4NC", "01e", "3Po", "xs", "8RY", "54F", "6UL", "a6f", "59v", "0Vq", "1K", "d3E", "85M", "4Cs", "5F3", "5I2", "4Lr", "03T", "Tn", -"zB", "0Yp", "56w", "437", "6ZM", "4on", "1Da", "3z", "2OO", "0zl", "4AB", "60i", "5Oa", "6jc", "2QM", "0dn", "0JB", "ip", "6DO", "45d", -"48T", "acm", "1B2", "0Gr", "94o", "Jl", "5W0", "4Rp", "5MP", "5X1", "Em", "12v", "0Hs", "kA", "all", "47U", "5nL", "6KN", "fq", "0EC", -"0ko", "3Nm", "6eb", "4PA", "a8", "0Q", "6Yf", "4lE", "4Bi", "63B", "Zu", "0yG", "0tw", "WE", "4Z8", "4OY", "4au", "5d5", "yi", "1Jz", -"0UZ", "vh", "5k4", "4nt", "5Py", "4U9", "XD", "1kW", "02N", "Ut", "6xK", "4Mh", "4cD", "6Vg", "2mI", "n9", "eZ", "43", "49N", "6He", -"6fI", "4Sj", "0hD", "Kv", "FF", "0et", "7n9", "6ky", "5u6", "4pv", "0KX", "hj", "gk", "0DY", "5oV", "5z7", "6dx", "5Az", "0ju", "IG", -"Dw", "0gE", "5LJ", "6iH", "6Gd", "46O", "0Ii", "28B", "xw", "1Kd", "54B", "6UH", "7kE", "4NG", "01a", "3Pk", "0m8", "0xY", "4Cw", "5F7", -"6Xx", "59r", "0Vu", "1O", "zF", "0Yt", "4bZ", "433", "5I6", "4Lv", "03P", "Tj", "YZ", "0zh", "4AF", "60m", "6ZI", "4oj", "0TD", "wv", -"0JF", "it", "6DK", "4qh", "5Oe", "6jg", "GX", "R9", "0iZ", "Jh", "5W4", "4Rt", "48P", "4i9", "dD", "0Gv", "0Hw", "kE", "4f8", "47Q", -"5MT", "5X5", "Ei", "12r", "0kk", "HY", "6ef", "4PE", "5nH", "6KJ", "fu", "0EG", "4Bm", "63F", "Zq", "0yC", "0Wo", "0U", "6Yb", "4lA", -"4aq", "5d1", "ym", "8SG", "0ts", "WA", "aPl", "b1f", "747", "61w", "2NQ", "1kS", "9Lg", "2d", "5k0", "4np", "57i", "6Vc", "2mM", "0Xn", -"02J", "Up", "6xO", "4Ml", "6fM", "4Sn", "1xa", "Kr", "27G", "47", "49J", "6Ha", "5u2", "44z", "8BD", "hn", "FB", "0ep", "bdm", "aAo", -"70U", "bkl", "0jq", "IC", "go", "306", "5oR", "5z3", "7WA", "46K", "0Im", "28F", "Ds", "0gA", "5LN", "6iL", "0cY", "020", "6mT", "4Xw", -"42S", "6Cx", "nG", "0Mu", "1Pd", "cw", "6NH", "5kJ", "4UG", "74M", "3Kk", "0ni", "0ah", "BZ", "6oe", "4ZF", "40b", "6AI", "lv", "0OD", -"0Bt", "aF", "6Ly", "4yZ", "4Wv", "5R6", "Oj", "0lX", "Qh", "06R", "4It", "5L4", "461", "4gX", "1LW", "1Y6", "rt", "0QF", "4jh", "7Oj", -"65o", "4DD", "I9", "2JI", "SY", "F8", "4KE", "7nG", "6PJ", "4ei", "1Nf", "2kd", "4M", "0Sw", "4hY", "490", "5C5", "4Fu", "09S", "2Hx", -"6OR", "4zq", "354", "bm", "LA", "0os", "bnn", "75W", "6lN", "4Ym", "0bC", "Aq", "2yL", "0Lo", "43I", "6Bb", "6Mc", "5ha", "15", "22E", -"Np", "0mB", "4Vl", "6cO", "aDm", "bao", "1pS", "1e2", "ml", "8GF", "41x", "548", "4kr", "5n2", "7f", "8YD", "1nQ", "2KS", "64u", "715", -"4Hn", "69E", "Pr", "07H", "1MM", "2hO", "6Sa", "4fB", "4iC", "7LA", "5W", "0Rm", "08I", "2Ib", "66D", "4Go", "b4d", "aUn", "RC", "05y", -"8VE", "8g", "5a3", "4ds", "42W", "ain", "nC", "0Mq", "17t", "024", "6mP", "4Xs", "4UC", "74I", "3Ko", "0nm", "8IY", "cs", "6NL", "5kN", -"40f", "6AM", "lr", "8FX", "0al", "2TO", "6oa", "4ZB", "4Wr", "5R2", "On", "18u", "0Bp", "aB", "afo", "bCm", "465", "53u", "1LS", "1Y2", -"Ql", "06V", "4Ip", "5L0", "65k", "5Ta", "1oO", "2JM", "6x", "0QB", "4jl", "7On", "6PN", "4em", "1Nb", "9y", "2EL", "04g", "4KA", "7nC", -"5C1", "4Fq", "09W", "d6G", "4I", "0Ss", "bRn", "494", "LE", "0ow", "4TY", "4A8", "6OV", "4zu", "1Qz", "bi", "oY", "z8", "43M", "6Bf", -"6lJ", "4Yi", "0bG", "Au", "Nt", "0mF", "4Vh", "6cK", "6Mg", "4xD", "11", "22A", "mh", "0NZ", "4ut", "5p4", "4N9", "5Ky", "1pW", "CD", -"1nU", "2KW", "64q", "4EZ", "4kv", "5n6", "7b", "0PX", "1MI", "2hK", "6Se", "4fF", "4Hj", "69A", "Pv", "07L", "08M", "2If", "6rH", "4Gk", -"4iG", "7LE", "5S", "0Ri", "1Ox", "8c", "5a7", "4dw", "5Zz", "7oY", "RG", "0qu", "1Pl", "21f", "adR", "5kB", "4UO", "74E", "MS", "X2", -"0cQ", "028", "79u", "bbL", "4vS", "4c2", "nO", "8De", "8Kd", "aN", "4l3", "4yR", "634", "76t", "Ob", "0lP", "W3", "BR", "6om", "4ZN", -"40j", "6AA", "2zo", "0OL", "6t", "0QN", "5zA", "7Ob", "65g", "4DL", "I1", "2JA", "0g3", "06Z", "b7G", "68W", "469", "4gP", "284", "dSn", -"4E", "275", "4hQ", "498", "67V", "b8F", "1mr", "0h2", "SQ", "F0", "4KM", "7nO", "6PB", "4ea", "1Nn", "9u", "6lF", "4Ye", "0bK", "Ay", -"oU", "z4", "43A", "6Bj", "6OZ", "4zy", "0AW", "be", "LI", "2O9", "4TU", "4A4", "4N5", "5Ku", "14S", "CH", "md", "0NV", "41p", "540", -"6Mk", "4xH", "u5", "22M", "Nx", "0mJ", "4Vd", "6cG", "4Hf", "69M", "Pz", "0sH", "k7", "2hG", "6Si", "4fJ", "4kz", "7Nx", "7n", "0PT", -"1nY", "dqh", "4P7", "4EV", "4JW", "7oU", "RK", "05q", "1Ot", "8o", "6QX", "50R", "4iK", "7LI", "qW", "d6", "08A", "2Ij", "66L", "4Gg", -"4UK", "74A", "MW", "X6", "1Ph", "21b", "6ND", "5kF", "4vW", "4c6", "nK", "0My", "0cU", "0v4", "6mX", "5HZ", "4Wz", "6bY", "Of", "0lT", -"0Bx", "aJ", "4l7", "4yV", "40n", "6AE", "lz", "0OH", "W7", "BV", "6oi", "4ZJ", "65c", "4DH", "I5", "2JE", "6p", "0QJ", "4jd", "7Of", -"4r5", "4gT", "280", "2iY", "Qd", "0rV", "4Ix", "5L8", "5C9", "4Fy", "1mv", "0h6", "4A", "1CZ", "4hU", "7MW", "6PF", "4ee", "1Nj", "9q", -"SU", "F4", "4KI", "7nK", "oQ", "z0", "43E", "6Bn", "6lB", "4Ya", "0bO", "2Wl", "LM", "8fg", "4TQ", "4A0", "aeL", "cPo", "0AS", "ba", -"3kP", "0NR", "41t", "544", "4N1", "5Kq", "14W", "CL", "2Xm", "0mN", "5FA", "6cC", "6Mo", "4xL", "19", "22I", "k3", "2hC", "6Sm", "4fN", -"4Hb", "69I", "2Fo", "07D", "83l", "d5d", "4P3", "4ER", "bQM", "a0G", "7j", "0PP", "1Op", "8k", "hbw", "50V", "4JS", "7oQ", "RO", "05u", -"08E", "2In", "66H", "4Gc", "4iO", "7LM", "qS", "d2", "0ay", "BK", "4O6", "4ZW", "40s", "553", "lg", "0OU", "t6", "aW", "6Lh", "4yK", -"4Wg", "6bD", "2Yj", "0lI", "0cH", "2Vk", "6mE", "4Xf", "42B", "6Ci", "nV", "0Md", "1Pu", "cf", "6NY", "bAI", "4UV", "7pT", "MJ", "0nx", -"SH", "04r", "4KT", "7nV", "azI", "4ex", "1Nw", "9l", "pT", "e5", "4hH", "7MJ", "67O", "4Fd", "09B", "2Hi", "Qy", "06C", "4Ie", "68N", -"6Rj", "4gI", "j4", "2iD", "6m", "0QW", "4jy", "5o9", "4Q4", "4DU", "1oZ", "2JX", "4m0", "4xQ", "8Jg", "22T", "Na", "0mS", "627", "77w", -"6nn", "5Kl", "V0", "CQ", "3kM", "0NO", "41i", "7Pc", "6OC", "5jA", "0AN", "20e", "LP", "Y1", "4TL", "6ao", "78v", "bcO", "0bR", "0w3", -"oL", "8Ef", "43X", "4b1", "4iR", "7LP", "5F", "266", "08X", "0i1", "66U", "b9E", "4JN", "7oL", "RR", "G3", "1Om", "8v", "6QA", "4db", -"4kc", "7Na", "7w", "0PM", "H2", "2KB", "64d", "4EO", "b6D", "69T", "Pc", "07Y", "297", "dRm", "4s2", "4fS", "40w", "557", "lc", "0OQ", -"15T", "BO", "4O2", "4ZS", "4Wc", "76i", "2Yn", "0lM", "t2", "aS", "6Ll", "4yO", "42F", "6Cm", "nR", "8Dx", "0cL", "2Vo", "6mA", "4Xb", -"4UR", "74X", "MN", "8gd", "1Pq", "cb", "adO", "bAM", "azM", "51U", "1Ns", "9h", "SL", "04v", "4KP", "7nR", "67K", "5VA", "09F", "2Hm", -"4X", "e1", "4hL", "7MN", "6Rn", "4gM", "j0", "3ya", "2Gl", "06G", "4Ia", "68J", "4Q0", "4DQ", "82o", "d4g", "6i", "0QS", "bPN", "a1D", -"Ne", "0mW", "4Vy", "5S9", "4m4", "4xU", "1SZ", "22P", "my", "0NK", "41m", "7Pg", "6nj", "5Kh", "V4", "CU", "LT", "Y5", "4TH", "6ak", -"6OG", "4zd", "0AJ", "bx", "oH", "0Lz", "4wT", "4b5", "78r", "4Yx", "0bV", "Ad", "1lu", "0i5", "66Q", "4Gz", "4iV", "7LT", "5B", "0Rx", -"1Oi", "8r", "6QE", "4df", "4JJ", "7oH", "RV", "G7", "H6", "2KF", "6ph", "4EK", "4kg", "7Ne", "7s", "0PI", "1MX", "1X9", "4s6", "4fW", -"5XZ", "69P", "Pg", "0sU", "06", "23F", "afr", "4yC", "4Wo", "6bL", "Os", "0lA", "0aq", "BC", "aEn", "c4E", "4ts", "5q3", "lo", "8FE", -"347", "cn", "6NQ", "5kS", "bom", "74T", "MB", "0np", "17i", "2Vc", "6mM", "4Xn", "42J", "6Ca", "2xO", "0Ml", "4T", "0Sn", "5xa", "7MB", -"67G", "4Fl", "09J", "2Ha", "1u2", "04z", "b5g", "aTm", "6PS", "4ep", "8WF", "9d", "6e", "8XG", "4jq", "5o1", "65v", "706", "1oR", "1z3", -"Qq", "06K", "4Im", "68F", "6Rb", "4gA", "1LN", "2iL", "6nf", "5Kd", "V8", "CY", "mu", "0NG", "41a", "7Pk", "4m8", "4xY", "0Cw", "1F7", -"Ni", "19r", "4Vu", "5S5", "6lW", "4Yt", "0bZ", "Ah", "oD", "0Lv", "43P", "4b9", "6OK", "4zh", "0AF", "bt", "LX", "Y9", "4TD", "6ag", -"4JF", "7oD", "RZ", "0qh", "1Oe", "2jg", "6QI", "4dj", "4iZ", "483", "5N", "0Rt", "08P", "0i9", "5B6", "4Gv", "4Hw", "5M7", "Pk", "07Q", -"1MT", "1X5", "472", "52r", "4kk", "7Ni", "sw", "0PE", "1nH", "2KJ", "64l", "4EG", "4Wk", "6bH", "Ow", "0lE", "02", "23B", "6Ld", "4yG", -"4tw", "5q7", "lk", "0OY", "0au", "BG", "6ox", "5Jz", "4UZ", "74P", "MF", "0nt", "1Py", "cj", "6NU", "5kW", "42N", "6Ce", "nZ", "0Mh", -"0cD", "2Vg", "6mI", "4Xj", "67C", "4Fh", "09N", "2He", "4P", "e9", "4hD", "7MF", "6PW", "4et", "3n9", "2ky", "SD", "0pv", "4KX", "7nZ", -"4Q8", "4DY", "1oV", "1z7", "6a", "1Az", "4ju", "5o5", "6Rf", "4gE", "j8", "2iH", "Qu", "06O", "4Ii", "68B", "mq", "0NC", "41e", "7Po", -"6nb", "bar", "14F", "2UL", "Nm", "19v", "4Vq", "5S1", "agl", "bBn", "0Cs", "1F3", "1I2", "0Lr", "43T", "ahm", "6lS", "4Yp", "16w", "Al", -"2ZM", "0on", "5Da", "6ac", "6OO", "4zl", "0AB", "bp", "1Oa", "8z", "6QM", "4dn", "4JB", "aUs", "2DO", "05d", "08T", "d7D", "5B2", "4Gr", -"bSm", "487", "5J", "0Rp", "1MP", "1X1", "476", "52v", "4Hs", "5M3", "Po", "07U", "1nL", "2KN", "64h", "4EC", "4ko", "7Nm", "ss", "0PA", -"QJ", "06p", "4IV", "7lT", "6RY", "4gz", "1Lu", "0I5", "rV", "g7", "4jJ", "7OH", "65M", "4Df", "1oi", "2Jk", "2Ej", "04A", "4Kg", "7ne", -"6Ph", "4eK", "h6", "2kF", "4o", "0SU", "5xZ", "7My", "4S6", "4FW", "09q", "1x9", "17R", "2VX", "4M4", "4XU", "42q", "571", "ne", "0MW", -"v4", "cU", "6Nj", "5kh", "4Ue", "74o", "My", "0nK", "0aJ", "Bx", "6oG", "4Zd", "4tH", "6Ak", "lT", "y5", "0BV", "ad", "580", "4yx", -"4WT", "4B5", "OH", "0lz", "4kP", "7NR", "7D", "244", "1ns", "0k3", "64W", "con", "4HL", "69g", "PP", "E1", "1Mo", "2hm", "6SC", "52I", -"4ia", "7Lc", "5u", "0RO", "J0", "3Ya", "66f", "4GM", "b4F", "aUL", "Ra", "0qS", "8Vg", "8E", "458", "4dQ", "4o2", "4zS", "8He", "bO", -"Lc", "0oQ", "605", "75u", "6ll", "4YO", "T2", "AS", "2yn", "0LM", "43k", "7Ra", "6MA", "4xb", "0CL", "22g", "NR", "19I", "4VN", "6cm", -"aDO", "baM", "14y", "Cb", "mN", "8Gd", "41Z", "7PP", "axO", "53W", "1Lq", "0I1", "QN", "06t", "4IR", "68y", "65I", "4Db", "1om", "2Jo", -"6Z", "g3", "4jN", "7OL", "6Pl", "4eO", "h2", "2kB", "2En", "04E", "4Kc", "7na", "4S2", "4FS", "09u", "d6e", "4k", "0SQ", "bRL", "a3F", -"42u", "575", "na", "0MS", "17V", "dlo", "4M0", "4XQ", "4Ua", "74k", "3KM", "0nO", "28", "cQ", "6Nn", "5kl", "40D", "6Ao", "lP", "y1", -"0aN", "2Tm", "6oC", "5JA", "4WP", "4B1", "OL", "18W", "0BR", "0W3", "584", "bCO", "1nw", "0k7", "64S", "4Ex", "4kT", "7NV", "sH", "0Pz", -"1Mk", "2hi", "6SG", "4fd", "4HH", "69c", "PT", "E5", "J4", "2ID", "66b", "4GI", "4ie", "7Lg", "5q", "0RK", "1OZ", "8A", "4q4", "4dU", -"4Jy", "5O9", "Re", "0qW", "Lg", "0oU", "5DZ", "6aX", "4o6", "4zW", "0Ay", "bK", "2yj", "0LI", "43o", "6BD", "6lh", "4YK", "T6", "AW", -"NV", "0md", "4VJ", "6ci", "6ME", "4xf", "0CH", "22c", "mJ", "0Nx", "4uV", "7PT", "6nY", "baI", "1pu", "Cf", "6V", "0Ql", "4jB", "aus", -"65E", "4Dn", "1oa", "2Jc", "QB", "06x", "b7e", "68u", "5b2", "4gr", "8UD", "dSL", "4g", "8ZE", "4hs", "5m3", "67t", "724", "09y", "1x1", -"Ss", "04I", "4Ko", "7nm", "azr", "4eC", "1NL", "9W", "24", "21D", "6Nb", "bAr", "4Um", "74g", "Mq", "0nC", "0cs", "1f3", "79W", "bbn", -"42y", "579", "nm", "394", "365", "al", "588", "4yp", "bmo", "76V", "1i2", "0lr", "0aB", "Bp", "6oO", "4Zl", "40H", "6Ac", "2zM", "0On", -"4HD", "69o", "PX", "E9", "1Mg", "2he", "6SK", "4fh", "4kX", "7NZ", "7L", "0Pv", "3N9", "2Ky", "6pW", "4Et", "4Ju", "5O5", "Ri", "05S", -"1OV", "8M", "450", "4dY", "4ii", "7Lk", "qu", "0RG", "J8", "2IH", "66n", "4GE", "6ld", "4YG", "0bi", "2WJ", "ow", "0LE", "43c", "6BH", -"6Ox", "5jz", "0Au", "bG", "Lk", "0oY", "4Tw", "5Q7", "6nU", "5KW", "14q", "Cj", "mF", "0Nt", "41R", "7PX", "6MI", "4xj", "0CD", "22o", -"NZ", "0mh", "4VF", "6ce", "65A", "4Dj", "1oe", "2Jg", "6R", "0Qh", "4jF", "7OD", "5b6", "4gv", "1Ly", "0I9", "QF", "0rt", "4IZ", "68q", -"67p", "5Vz", "1mT", "1x5", "4c", "0SY", "4hw", "5m7", "6Pd", "4eG", "1NH", "9S", "Sw", "04M", "4Kk", "7ni", "4Ui", "74c", "Mu", "0nG", -"20", "cY", "6Nf", "5kd", "4vu", "5s5", "ni", "390", "0cw", "1f7", "4M8", "4XY", "4WX", "4B9", "OD", "0lv", "0BZ", "ah", "6LW", "4yt", -"40L", "6Ag", "lX", "y9", "0aF", "Bt", "6oK", "4Zh", "1Mc", "2ha", "6SO", "4fl", "5Xa", "69k", "2FM", "07f", "83N", "d5F", "6pS", "4Ep", -"bQo", "a0e", "7H", "0Pr", "1OR", "8I", "454", "50t", "4Jq", "5O1", "Rm", "05W", "08g", "2IL", "66j", "4GA", "4im", "7Lo", "5y", "0RC", -"os", "0LA", "43g", "6BL", "78I", "4YC", "0bm", "2WN", "Lo", "8fE", "4Ts", "5Q3", "aen", "cPM", "0Aq", "bC", "mB", "0Np", "41V", "ajo", -"6nQ", "5KS", "14u", "Cn", "2XO", "0ml", "4VB", "6ca", "6MM", "4xn", "1Sa", "22k", "Sj", "04P", "4Kv", "5N6", "443", "4eZ", "1NU", "9N", -"pv", "0SD", "4hj", "7Mh", "67m", "4FF", "1mI", "2HK", "2GJ", "2", "4IG", "68l", "6RH", "4gk", "1Ld", "2if", "6O", "0Qu", "5zz", "7OY", -"5A7", "4Dw", "1ox", "0j8", "15r", "Bi", "6oV", "4Zu", "40Q", "4a8", "lE", "0Ow", "0BG", "au", "6LJ", "4yi", "4WE", "6bf", "OY", "Z8", -"U9", "2VI", "6mg", "4XD", "4vh", "6CK", "nt", "0MF", "1PW", "cD", "4n9", "5ky", "4Ut", "5P4", "Mh", "0nZ", "4ip", "5l0", "5d", "9Kg", -"08z", "1y2", "66w", "737", "4Jl", "7on", "Rp", "05J", "1OO", "8T", "6Qc", "50i", "4kA", "7NC", "7U", "0Po", "1nb", "dqS", "64F", "4Em", -"b6f", "69v", "PA", "0ss", "8TG", "dRO", "5c1", "4fq", "6MP", "4xs", "376", "22v", "NC", "0mq", "bll", "77U", "6nL", "5KN", "14h", "Cs", -"3ko", "0Nm", "41K", "7PA", "6Oa", "4zB", "37", "20G", "Lr", "8fX", "4Tn", "6aM", "78T", "bcm", "0bp", "AB", "on", "387", "43z", "5r2", -"447", "51w", "1NQ", "9J", "Sn", "04T", "4Kr", "5N2", "67i", "4FB", "09d", "2HO", "4z", "1Ca", "4hn", "7Ml", "6RL", "4go", "8UY", "2ib", -"2GN", "6", "4IC", "68h", "5A3", "4Ds", "82M", "d4E", "6K", "0Qq", "bPl", "a1f", "40U", "akl", "lA", "0Os", "15v", "Bm", "6oR", "4Zq", -"4WA", "6bb", "2YL", "0lo", "0BC", "aq", "6LN", "4ym", "42d", "6CO", "np", "0MB", "0cn", "2VM", "6mc", "5Ha", "4Up", "5P0", "Ml", "8gF", -"1PS", "1E2", "adm", "bAo", "1lW", "1y6", "4R9", "4GX", "4it", "5l4", "qh", "0RZ", "i9", "8P", "6Qg", "4dD", "4Jh", "7oj", "Rt", "05N", -"1nf", "2Kd", "64B", "4Ei", "4kE", "7NG", "7Q", "f8", "1Mz", "2hx", "5c5", "4fu", "4HY", "69r", "PE", "0sw", "NG", "0mu", "5Fz", "6cx", -"6MT", "4xw", "0CY", "0V8", "3kk", "0Ni", "41O", "7PE", "6nH", "5KJ", "14l", "Cw", "Lv", "0oD", "4Tj", "6aI", "6Oe", "4zF", "33", "bZ", -"oj", "0LX", "4wv", "5r6", "6ly", "4YZ", "0bt", "AF", "4v", "0SL", "4hb", "awS", "67e", "4FN", "K3", "2HC", "Sb", "04X", "b5E", "aTO", -"4p3", "4eR", "8Wd", "9F", "6G", "257", "4jS", "7OQ", "65T", "cnm", "1op", "0j0", "QS", "D2", "4IO", "68d", "7Ba", "4gc", "1Ll", "2in", -"0BO", "23d", "6LB", "4ya", "4WM", "6bn", "OQ", "Z0", "0aS", "Ba", "aEL", "c4g", "40Y", "4a0", "lM", "8Fg", "8If", "cL", "4n1", "5kq", -"616", "74v", "3KP", "0nR", "U1", "2VA", "6mo", "4XL", "42h", "6CC", "2xm", "0MN", "4Jd", "7of", "Rx", "05B", "i5", "2jE", "6Qk", "4dH", -"4ix", "5l8", "5l", "0RV", "08r", "2IY", "4R5", "4GT", "4HU", "7mW", "PI", "07s", "1Mv", "0H6", "5c9", "4fy", "4kI", "7NK", "sU", "f4", -"1nj", "2Kh", "64N", "4Ee", "6nD", "5KF", "1ph", "2Uj", "mW", "x6", "41C", "7PI", "593", "5hZ", "0CU", "0V4", "NK", "0my", "4VW", "4C6", -"4L7", "4YV", "0bx", "AJ", "of", "0LT", "43r", "562", "6Oi", "4zJ", "w7", "bV", "Lz", "0oH", "4Tf", "6aE", "67a", "4FJ", "K7", "2HG", -"4r", "0SH", "4hf", "7Md", "4p7", "4eV", "1NY", "9B", "Sf", "0pT", "4Kz", "7nx", "65P", "5TZ", "1ot", "0j4", "6C", "0Qy", "4jW", "7OU", -"6RD", "4gg", "1Lh", "2ij", "QW", "D6", "4IK", "7lI", "4WI", "6bj", "OU", "Z4", "0BK", "ay", "6LF", "4ye", "4tU", "4a4", "lI", "2o9", -"0aW", "Be", "6oZ", "4Zy", "4Ux", "5P8", "Md", "0nV", "8Ib", "cH", "4n5", "5ku", "42l", "6CG", "nx", "0MJ", "U5", "2VE", "6mk", "4XH", -"i1", "8X", "6Qo", "4dL", "5ZA", "7ob", "2Dm", "05F", "08v", "d7f", "4R1", "4GP", "bSO", "a2E", "5h", "0RR", "1Mr", "0H2", "ayL", "52T", -"4HQ", "69z", "PM", "07w", "1nn", "2Kl", "64J", "4Ea", "4kM", "7NO", "7Y", "f0", "mS", "x2", "41G", "7PM", "aDR", "5KB", "14d", "2Un", -"NO", "19T", "4VS", "4C2", "597", "bBL", "0CQ", "0V0", "ob", "0LP", "43v", "566", "4L3", "4YR", "16U", "AN", "2Zo", "0oL", "4Tb", "6aA", -"6Om", "4zN", "w3", "bR", "4oT", "4z5", "wH", "0Tz", "0zV", "Yd", "5D8", "4Ax", "4LH", "6yk", "TT", "A5", "0YJ", "zx", "6WG", "4bd", -"4me", "6XF", "1q", "0VK", "N4", "2MD", "62b", "4CI", "4Ny", "5K9", "Ve", "0uW", "1KZ", "xI", "4u4", "5pt", "4k6", "5nv", "0Ey", "fK", -"Hg", "0kU", "641", "6eX", "6hh", "5Mj", "P6", "EW", "29b", "0HI", "47o", "6FD", "6IE", "48n", "0GH", "dz", "JV", "0id", "4RJ", "6gi", -"6jY", "beI", "0dT", "Gf", "iJ", "0Jx", "4qV", "4d7", "UN", "02t", "4MR", "4X3", "a8G", "57W", "0XP", "0M1", "2Z", "c3", "4nN", "7KL", -"61I", "5PC", "1km", "2No", "2An", "00E", "4Oc", "7ja", "6Tl", "4aO", "l2", "yS", "0k", "0WQ", "58V", "a7F", "4W2", "4BS", "84m", "ZO", -"13V", "E", "4I0", "5Lp", "46u", "535", "ja", "0IS", "68", "gQ", "6Jn", "5ol", "4Qa", "6dB", "3OM", "0jO", "0eN", "2Pm", "6kC", "5NA", -"44D", "6Eo", "hP", "99", "0FR", "0S3", "abM", "49t", "4SP", "4F1", "KL", "8af", "0zR", "0o3", "60W", "ckn", "4oP", "4z1", "3D", "204", -"0YN", "2lm", "6WC", "56I", "4LL", "6yo", "TP", "A1", "N0", "903", "62f", "4CM", "4ma", "6XB", "1u", "0VO", "8Rg", "xM", "418", "54x", -"b0F", "aQL", "Va", "0uS", "Hc", "0kQ", "645", "71u", "4k2", "5nr", "8Le", "fO", "29f", "0HM", "47k", "7Va", "6hl", "5Mn", "P2", "ES", -"JR", "1yA", "4RN", "6gm", "6IA", "48j", "0GL", "26g", "iN", "8Cd", "45Z", "4d3", "hYv", "beM", "0dP", "Gb", "6VY", "4cz", "0XT", "0M5", -"UJ", "02p", "4MV", "4X7", "61M", "5PG", "1ki", "Xz", "vV", "c7", "4nJ", "7KH", "6Th", "4aK", "l6", "yW", "2Aj", "00A", "4Og", "6zD", -"4W6", "4BW", "0yy", "ZK", "0o", "0WU", "58R", "6YX", "46q", "531", "je", "0IW", "13R", "A", "4I4", "5Lt", "4Qe", "6dF", "Iy", "0jK", -"r4", "gU", "6Jj", "5oh", "4pH", "6Ek", "hT", "0Kf", "0eJ", "Fx", "6kG", "5NE", "4ST", "4F5", "KH", "0hz", "0FV", "ed", "5x8", "49p", -"bvs", "6yc", "2BM", "03f", "0YB", "zp", "6WO", "4bl", "bUo", "a4e", "3H", "0Tr", "87N", "Yl", "5D0", "4Ap", "4Nq", "5K1", "Vm", "01W", -"1KR", "xA", "414", "54t", "4mm", "6XN", "1y", "0VC", "0xo", "2ML", "62j", "4CA", "7xA", "5Mb", "0fm", "2SN", "ks", "0HA", "47g", "6FL", -"aan", "bDl", "0Eq", "fC", "Ho", "8bE", "4Ps", "5U3", "5Z2", "5OS", "10u", "Gn", "iB", "0Jp", "45V", "ano", "6IM", "48f", "1Wa", "dr", -"3Ln", "0il", "4RB", "6ga", "2R", "0Uh", "4nF", "7KD", "61A", "5PK", "1ke", "Xv", "UF", "0vt", "4MZ", "6xy", "5f6", "4cv", "0XX", "0M9", -"0c", "0WY", "4lw", "5i7", "63p", "5Rz", "0yu", "ZG", "Ww", "00M", "4Ok", "6zH", "6Td", "4aG", "0Zi", "2oJ", "60", "gY", "6Jf", "5od", -"4Qi", "6dJ", "Iu", "0jG", "0gw", "M", "4I8", "5Lx", "4ru", "5w5", "ji", "1Yz", "0FZ", "eh", "5x4", "5mU", "4SX", "4F9", "KD", "0hv", -"0eF", "Ft", "6kK", "5NI", "44L", "6Eg", "hX", "91", "0YF", "zt", "6WK", "4bh", "4LD", "6yg", "TX", "A9", "0zZ", "Yh", "5D4", "4At", -"4oX", "4z9", "3L", "0Tv", "1KV", "xE", "410", "54p", "4Nu", "5K5", "Vi", "01S", "N8", "2MH", "62n", "4CE", "4mi", "6XJ", "uu", "0VG", -"kw", "0HE", "47c", "6FH", "6hd", "5Mf", "0fi", "2SJ", "Hk", "0kY", "4Pw", "5U7", "6Kx", "5nz", "0Eu", "fG", "iF", "0Jt", "45R", "6Dy", -"5Z6", "5OW", "0dX", "Gj", "JZ", "0ih", "4RF", "6ge", "6II", "48b", "0GD", "dv", "61E", "5PO", "1ka", "Xr", "2V", "0Ul", "4nB", "aqs", -"5f2", "4cr", "8QD", "39V", "UB", "02x", "795", "aRo", "63t", "764", "0yq", "ZC", "0g", "9Nd", "4ls", "5i3", "7DA", "4aC", "0Zm", "2oN", -"Ws", "00I", "4Oo", "6zL", "4Qm", "6dN", "Iq", "0jC", "64", "25D", "6Jb", "bEr", "46y", "539", "jm", "9Pf", "0gs", "I", "aCl", "bfn", -"bio", "72V", "1m2", "0hr", "325", "el", "5x0", "49x", "44H", "6Ec", "3nl", "95", "0eB", "Fp", "6kO", "5NM", "4mt", "5h4", "uh", "0VZ", -"0xv", "2MU", "4V9", "4CX", "4Nh", "7kj", "Vt", "01N", "m9", "xX", "6Ug", "54m", "4oE", "6Zf", "3Q", "b8", "0zG", "Yu", "60B", "4Ai", -"4LY", "4Y8", "TE", "0ww", "1Iz", "zi", "5g5", "4bu", "5y7", "5lV", "0GY", "dk", "JG", "0iu", "5Bz", "6gx", "6jH", "5OJ", "0dE", "Gw", -"3ok", "82", "45O", "6Dd", "6Ke", "5ng", "73", "fZ", "Hv", "0kD", "4Pj", "6eI", "6hy", "7m9", "0ft", "EF", "kj", "0HX", "4sv", "5v6", -"Wn", "00T", "4Or", "5J2", "407", "55w", "0Zp", "yB", "0z", "1Ga", "4ln", "6YM", "63i", "4BB", "0yl", "2LO", "2CN", "02e", "4MC", "7hA", -"6VL", "4co", "0XA", "2mb", "2K", "0Uq", "bTl", "a5f", "5E3", "5PR", "86M", "Xo", "11v", "Fm", "6kR", "5NP", "44U", "aol", "hA", "0Ks", -"0FC", "eq", "6HN", "49e", "4SA", "6fb", "3Mm", "0ho", "0gn", "T", "6ic", "5La", "46d", "6GO", "jp", "0IB", "0Dr", "1A2", "hyT", "bEo", -"4Qp", "5T0", "Il", "8cF", "0xr", "2MQ", "62w", "777", "4mp", "5h0", "1d", "9Og", "1KO", "2nM", "6Uc", "54i", "4Nl", "7kn", "Vp", "01J", -"0zC", "Yq", "60F", "4Am", "4oA", "6Zb", "3U", "0To", "8PG", "zm", "5g1", "4bq", "786", "aSl", "TA", "0ws", "JC", "0iq", "bhl", "73U", -"5y3", "5lR", "336", "do", "3oo", "86", "45K", "7TA", "6jL", "5ON", "0dA", "Gs", "Hr", "8bX", "4Pn", "6eM", "6Ka", "5nc", "77", "24G", -"kn", "8AD", "47z", "5v2", "aBo", "bgm", "0fp", "EB", "403", "4aZ", "0Zt", "yF", "Wj", "00P", "4Ov", "5J6", "63m", "4BF", "0yh", "ZZ", -"tv", "0WD", "4lj", "6YI", "6VH", "4ck", "0XE", "2mf", "2CJ", "02a", "4MG", "6xd", "5E7", "5PV", "1kx", "Xk", "2O", "0Uu", "bTh", "7KY", -"44Q", "4e8", "hE", "0Kw", "11r", "Fi", "6kV", "5NT", "4SE", "6ff", "KY", "0hk", "0FG", "eu", "6HJ", "49a", "4rh", "6GK", "jt", "0IF", -"Q9", "P", "6ig", "5Le", "4Qt", "5T4", "Ih", "0jZ", "0Dv", "gD", "4j9", "5oy", "aD0", "7kb", "3PL", "01F", "m1", "xP", "6Uo", "54e", -"59U", "a6E", "1h", "0VR", "85n", "196", "4V1", "4CP", "4LQ", "4Y0", "TM", "03w", "0YS", "za", "a9D", "56T", "4oM", "6Zn", "3Y", "b0", -"0zO", "2Ol", "60J", "4Aa", "7za", "5OB", "0dM", "2Qn", "iS", "0Ja", "45G", "6Dl", "acN", "48w", "0GQ", "dc", "JO", "94L", "4RS", "4G2", -"4H3", "5Ms", "12U", "EN", "kb", "0HP", "47v", "526", "6Km", "5no", "s3", "fR", "3NN", "0kL", "4Pb", "6eA", "0r", "0WH", "4lf", "6YE", -"63a", "4BJ", "O7", "ZV", "Wf", "0tT", "4Oz", "6zY", "4t7", "4aV", "0Zx", "yJ", "2C", "0Uy", "4nW", "7KU", "61P", "5PZ", "1kt", "Xg", -"UW", "02m", "4MK", "6xh", "6VD", "4cg", "0XI", "2mj", "0FK", "ey", "6HF", "49m", "4SI", "6fj", "KU", "0hg", "0eW", "Fe", "6kZ", "5NX", -"4pU", "4e4", "hI", "2k9", "0Dz", "gH", "4j5", "5ou", "4Qx", "5T8", "Id", "0jV", "Q5", "DT", "6ik", "5Li", "46l", "6GG", "jx", "0IJ", -"m5", "xT", "6Uk", "54a", "4Nd", "7kf", "Vx", "01B", "0xz", "192", "4V5", "4CT", "4mx", "5h8", "1l", "0VV", "0YW", "ze", "5g9", "4by", -"4LU", "4Y4", "TI", "03s", "0zK", "Yy", "60N", "4Ae", "4oI", "6Zj", "wU", "b4", "iW", "0Je", "45C", "6Dh", "6jD", "5OF", "0dI", "2Qj", -"JK", "0iy", "4RW", "4G6", "6IX", "48s", "0GU", "dg", "kf", "0HT", "47r", "522", "4H7", "5Mw", "0fx", "EJ", "Hz", "0kH", "4Pf", "6eE", -"6Ki", "5nk", "s7", "fV", "63e", "4BN", "O3", "ZR", "0v", "0WL", "4lb", "6YA", "4t3", "4aR", "8Sd", "yN", "Wb", "00X", "b1E", "aPO", -"61T", "bzL", "1kp", "Xc", "2G", "217", "4nS", "7KQ", "7Fa", "4cc", "0XM", "2mn", "US", "02i", "4MO", "6xl", "4SM", "6fn", "KQ", "0hc", -"0FO", "27d", "6HB", "49i", "44Y", "4e0", "hM", "8Bg", "0eS", "Fa", "aAL", "bdN", "656", "70v", "3OP", "0jR", "8Mf", "gL", "4j1", "5oq", -"46h", "6GC", "28e", "0IN", "Q1", "X", "6io", "5Lm", "6KV", "5nT", "1Uz", "fi", "HE", "0kw", "4PY", "4E8", "6hJ", "5MH", "0fG", "Eu", -"kY", "0Hk", "47M", "6Ff", "6Ig", "48L", "51", "dX", "Jt", "0iF", "4Rh", "6gK", "4J9", "5Oy", "0dv", "GD", "ih", "0JZ", "4qt", "5t4", -"4ov", "5j6", "3b", "0TX", "0zt", "YF", "60q", "4AZ", "4Lj", "6yI", "Tv", "03L", "0Yh", "zZ", "6We", "4bF", "4mG", "6Xd", "1S", "0Vi", -"0xE", "2Mf", "6vH", "4Ck", "bth", "7kY", "VG", "0uu", "1Kx", "xk", "5e7", "5pV", "13t", "g", "5Y3", "5LR", "46W", "amn", "jC", "0Iq", -"0DA", "gs", "6JL", "5oN", "4QC", "70I", "3Oo", "0jm", "0el", "2PO", "6ka", "5Nc", "44f", "6EM", "hr", "8BX", "0Fp", "eB", "abo", "49V", -"4Sr", "5V2", "Kn", "8aD", "Ul", "02V", "4Mp", "5H0", "425", "57u", "0Xr", "2mQ", "2x", "0UB", "4nl", "7Kn", "61k", "5Pa", "1kO", "2NM", -"2AL", "00g", "4OA", "6zb", "6TN", "4am", "0ZC", "yq", "0I", "0Ws", "58t", "a7d", "5G1", "4Bq", "84O", "Zm", "HA", "0ks", "bjn", "71W", -"6KR", "5nP", "314", "fm", "29D", "0Ho", "47I", "6Fb", "6hN", "5ML", "0fC", "Eq", "Jp", "0iB", "4Rl", "6gO", "6Ic", "48H", "55", "26E", -"il", "8CF", "45x", "508", "hYT", "beo", "0dr", "1a2", "0zp", "YB", "60u", "755", "4or", "5j2", "3f", "9Me", "0Yl", "2lO", "6Wa", "4bB", -"4Ln", "6yM", "Tr", "03H", "0xA", "2Mb", "62D", "4Co", "4mC", "7HA", "1W", "0Vm", "8RE", "xo", "5e3", "54Z", "b0d", "aQn", "VC", "01y", -"46S", "6Gx", "jG", "0Iu", "0gY", "c", "5Y7", "5LV", "4QG", "6dd", "3Ok", "0ji", "0DE", "gw", "6JH", "5oJ", "44b", "6EI", "hv", "0KD", -"0eh", "FZ", "6ke", "5Ng", "4Sv", "5V6", "Kj", "0hX", "0Ft", "eF", "6Hy", "49R", "421", "4cX", "0Xv", "2mU", "Uh", "02R", "4Mt", "5H4", -"61o", "5Pe", "M9", "XX", "vt", "0UF", "4nh", "7Kj", "6TJ", "4ai", "0ZG", "yu", "WY", "B8", "4OE", "6zf", "5G5", "4Bu", "1iz", "Zi", -"0M", "0Ww", "4lY", "4y8", "6hB", "aW1", "0fO", "2Sl", "kQ", "0Hc", "47E", "6Fn", "aaL", "bDN", "0ES", "fa", "HM", "8bg", "4PQ", "4E0", -"4J1", "5Oq", "10W", "GL", "3oP", "0JR", "45t", "504", "6Io", "48D", "59", "dP", "3LL", "0iN", "5BA", "6gC", "4Lb", "6yA", "2Bo", "03D", -"o3", "zR", "6Wm", "4bN", "bUM", "a4G", "3j", "0TP", "87l", "YN", "4T3", "4AR", "4NS", "7kQ", "VO", "01u", "1Kp", "xc", "hfw", "54V", -"4mO", "6Xl", "uS", "0Va", "0xM", "2Mn", "62H", "4Cc", "0DI", "25b", "6JD", "5oF", "4QK", "6dh", "IW", "0je", "0gU", "o", "6iX", "5LZ", -"4rW", "4g6", "jK", "0Iy", "0Fx", "eJ", "4h7", "5mw", "4Sz", "6fY", "Kf", "0hT", "S7", "FV", "6ki", "5Nk", "44n", "6EE", "hz", "0KH", -"2p", "0UJ", "4nd", "7Kf", "61c", "5Pi", "M5", "XT", "Ud", "0vV", "4Mx", "5H8", "4v5", "4cT", "0Xz", "2mY", "0A", "1GZ", "4lU", "4y4", -"5G9", "4By", "0yW", "Ze", "WU", "B4", "4OI", "6zj", "6TF", "4ae", "0ZK", "yy", "kU", "0Hg", "47A", "6Fj", "6hF", "5MD", "0fK", "Ey", -"HI", "2K9", "4PU", "4E4", "6KZ", "5nX", "0EW", "fe", "id", "0JV", "45p", "500", "4J5", "5Ou", "0dz", "GH", "Jx", "0iJ", "4Rd", "6gG", -"6Ik", "5li", "q5", "dT", "o7", "zV", "6Wi", "4bJ", "4Lf", "6yE", "Tz", "0wH", "0zx", "YJ", "4T7", "4AV", "4oz", "6ZY", "3n", "0TT", -"1Kt", "xg", "6UX", "54R", "4NW", "7kU", "VK", "01q", "0xI", "2Mj", "62L", "4Cg", "4mK", "6Xh", "uW", "0Ve", "4QO", "6dl", "IS", "0ja", -"0DM", "25f", "7Za", "5oB", "4rS", "4g2", "jO", "9PD", "0gQ", "k", "aCN", "685", "674", "72t", "Kb", "0hP", "8Od", "eN", "4h3", "49Z", -"44j", "6EA", "3nN", "0KL", "S3", "FR", "6km", "5No", "61g", "5Pm", "M1", "XP", "2t", "0UN", "ad0", "7Kb", "429", "4cP", "8Qf", "39t", -"0c3", "02Z", "b3G", "aRM", "63V", "bxN", "0yS", "Za", "0E", "235", "4lQ", "4y0", "6TB", "4aa", "0ZO", "2ol", "WQ", "B0", "4OM", "6zn", -"4i4", "5lt", "1WZ", "dI", "Je", "0iW", "4Ry", "5W9", "6jj", "5Oh", "R4", "GU", "iy", "0JK", "45m", "6DF", "6KG", "5nE", "0EJ", "fx", -"HT", "0kf", "4PH", "6ek", "5X8", "5MY", "0fV", "Ed", "kH", "0Hz", "4sT", "4f5", "4mV", "4x7", "1B", "0Vx", "0xT", "0m5", "62Q", "4Cz", -"4NJ", "7kH", "VV", "C7", "1Ki", "xz", "6UE", "54O", "4og", "6ZD", "3s", "0TI", "L6", "YW", "6th", "4AK", "6l9", "6yX", "Tg", "0wU", -"0Yy", "zK", "4w6", "4bW", "11T", "FO", "4K2", "5Nr", "44w", "517", "hc", "0KQ", "p2", "eS", "6Hl", "49G", "4Sc", "72i", "3MO", "0hM", -"0gL", "v", "6iA", "5LC", "46F", "6Gm", "jR", "1YA", "0DP", "gb", "hyv", "bEM", "4QR", "4D3", "IN", "8cd", "WL", "00v", "4OP", "4Z1", -"hgt", "55U", "0ZR", "0O3", "0X", "a1", "4lL", "6Yo", "63K", "5RA", "0yN", "2Lm", "2Cl", "02G", "4Ma", "6xB", "6Vn", "4cM", "n0", "39i", -"2i", "0US", "bTN", "a5D", "4U0", "5Pp", "86o", "XM", "Ja", "0iS", "667", "73w", "4i0", "48Y", "8Ng", "dM", "3oM", "0JO", "45i", "6DB", -"6jn", "5Ol", "R0", "GQ", "HP", "0kb", "4PL", "6eo", "6KC", "5nA", "0EN", "24e", "kL", "8Af", "47X", "4f1", "aBM", "696", "0fR", "0s3", -"0xP", "0m1", "62U", "byM", "4mR", "4x3", "1F", "226", "1Km", "2no", "6UA", "54K", "4NN", "7kL", "VR", "C3", "L2", "YS", "60d", "4AO", -"4oc", "7Ja", "3w", "0TM", "8Pe", "zO", "4w2", "4bS", "b2D", "aSN", "Tc", "03Y", "44s", "513", "hg", "0KU", "0ey", "FK", "4K6", "5Nv", -"4Sg", "6fD", "3MK", "0hI", "p6", "eW", "6Hh", "49C", "46B", "6Gi", "jV", "0Id", "0gH", "r", "6iE", "5LG", "4QV", "4D7", "IJ", "0jx", -"0DT", "gf", "6JY", "bEI", "5d8", "4ax", "0ZV", "yd", "WH", "00r", "4OT", "4Z5", "63O", "4Bd", "0yJ", "Zx", "tT", "a5", "4lH", "6Yk", -"6Vj", "4cI", "n4", "2mD", "Uy", "02C", "4Me", "6xF", "4U4", "5Pt", "1kZ", "XI", "2m", "0UW", "4ny", "5k9", "6jb", "ber", "0do", "2QL", -"iq", "0JC", "45e", "6DN", "acl", "48U", "0Gs", "dA", "Jm", "94n", "4Rq", "5W1", "5X0", "5MQ", "12w", "El", "1M2", "0Hr", "47T", "alm", -"6KO", "5nM", "0EB", "fp", "3Nl", "0kn", "bjs", "6ec", "4NB", "aQs", "3Pn", "01d", "1Ka", "xr", "6UM", "54G", "59w", "a6g", "1J", "0Vp", -"85L", "d3D", "5F2", "4Cr", "4Ls", "5I3", "To", "03U", "0Yq", "zC", "436", "56v", "4oo", "6ZL", "ws", "0TA", "0zm", "2ON", "60h", "4AC", -"42", "27B", "6Hd", "49O", "4Sk", "6fH", "Kw", "0hE", "0eu", "FG", "6kx", "5Nz", "4pw", "5u7", "hk", "0KY", "0DX", "gj", "5z6", "5oW", -"4QZ", "6dy", "IF", "0jt", "0gD", "Dv", "6iI", "5LK", "46N", "6Ge", "jZ", "0Ih", "0P", "a9", "4lD", "6Yg", "63C", "4Bh", "0yF", "Zt", -"WD", "0tv", "4OX", "4Z9", "5d4", "4at", "0ZZ", "yh", "2a", "1Ez", "4nu", "5k5", "4U8", "5Px", "1kV", "XE", "Uu", "02O", "4Mi", "6xJ", -"6Vf", "4cE", "n8", "2mH", "iu", "0JG", "45a", "6DJ", "6jf", "5Od", "R8", "GY", "Ji", "1yz", "4Ru", "5W5", "4i8", "48Q", "0Gw", "dE", -"kD", "0Hv", "47P", "4f9", "5X4", "5MU", "0fZ", "Eh", "HX", "0kj", "4PD", "6eg", "6KK", "5nI", "0EF", "ft", "1Ke", "xv", "6UI", "54C", -"4NF", "7kD", "VZ", "0uh", "0xX", "0m9", "5F6", "4Cv", "4mZ", "6Xy", "1N", "0Vt", "0Yu", "zG", "432", "56r", "4Lw", "5I7", "Tk", "03Q", -"0zi", "2OJ", "60l", "4AG", "4ok", "6ZH", "ww", "0TE", "4So", "6fL", "Ks", "0hA", "46", "27F", "7XA", "49K", "4ps", "5u3", "ho", "8BE", -"0eq", "FC", "aAn", "bdl", "bkm", "70T", "IB", "0jp", "307", "gn", "5z2", "5oS", "46J", "6Ga", "28G", "0Il", "13i", "z", "6iM", "5LO", -"63G", "4Bl", "0yB", "Zp", "0T", "0Wn", "58i", "6Yc", "5d0", "4ap", "8SF", "yl", "1q2", "00z", "b1g", "aPm", "61v", "746", "1kR", "XA", -"2e", "9Lf", "4nq", "5k1", "6Vb", "4cA", "0Xo", "2mL", "Uq", "02K", "4Mm", "6xN", "8YG", "7e", "5n1", "4kq", "716", "64v", "2KP", "1nR", -"07K", "Pq", "69F", "4Hm", "4fA", "6Sb", "2hL", "1MN", "0Rn", "5T", "7LB", "5ya", "4Gl", "66G", "2Ia", "08J", "05z", "1t2", "aUm", "b4g", -"4dp", "5a0", "8d", "8VF", "bn", "357", "4zr", "6OQ", "75T", "bnm", "0op", "LB", "Ar", "16i", "4Yn", "6lM", "6Ba", "43J", "0Ll", "2yO", -"22F", "16", "4xC", "agr", "6cL", "4Vo", "0mA", "Ns", "CC", "14X", "bal", "aDn", "5p3", "4us", "8GE", "mo", "5L7", "4Iw", "06Q", "Qk", -"1Y5", "1LT", "53r", "462", "7Oi", "4jk", "0QE", "rw", "2JJ", "1oH", "4DG", "65l", "7nD", "4KF", "0ph", "SZ", "2kg", "1Ne", "4ej", "6PI", -"493", "4hZ", "0St", "4N", "0h9", "09P", "4Fv", "5C6", "4Xt", "6mW", "023", "0cZ", "0Mv", "nD", "4c9", "42P", "5kI", "6NK", "ct", "1Pg", -"X9", "MX", "74N", "4UD", "4ZE", "6of", "BY", "W8", "0OG", "lu", "6AJ", "40a", "4yY", "4l8", "aE", "0Bw", "18r", "Oi", "5R5", "4Wu", -"4EY", "4P8", "2KT", "1nV", "8YC", "7a", "5n5", "4ku", "4fE", "6Sf", "2hH", "k8", "07O", "Pu", "69B", "4Hi", "4Gh", "66C", "2Ie", "08N", -"d9", "5P", "7LF", "4iD", "4dt", "5a4", "2jy", "3o9", "0qv", "RD", "7oZ", "4JX", "6ay", "4TZ", "0ot", "LF", "bj", "0AX", "4zv", "6OU", -"6Be", "43N", "0Lh", "oZ", "Av", "0bD", "4Yj", "6lI", "6cH", "4Vk", "0mE", "Nw", "22B", "12", "4xG", "6Md", "5p7", "4uw", "0NY", "mk", -"CG", "1pT", "5Kz", "6nx", "1Y1", "1LP", "53v", "466", "5L3", "4Is", "06U", "Qo", "2JN", "1oL", "4DC", "65h", "7Om", "4jo", "0QA", "rs", -"9z", "1Na", "4en", "6PM", "aTs", "4KB", "04d", "2EO", "d6D", "09T", "4Fr", "5C2", "497", "bRm", "0Sp", "4J", "0Mr", "1H2", "aim", "42T", -"4Xp", "6mS", "027", "17w", "0nn", "3Kl", "74J", "5Ea", "5kM", "6NO", "cp", "1Pc", "0OC", "lq", "6AN", "40e", "4ZA", "6ob", "2TL", "0ao", -"18v", "Om", "5R1", "4Wq", "bCn", "afl", "aA", "0Bs", "07C", "Py", "69N", "4He", "4fI", "6Sj", "2hD", "k4", "0PW", "7m", "5n9", "4ky", -"4EU", "4P4", "2KX", "1nZ", "05r", "RH", "7oV", "4JT", "4dx", "5a8", "8l", "1Ow", "d5", "qT", "7LJ", "4iH", "4Gd", "66O", "2Ii", "08B", -"Az", "0bH", "4Yf", "6lE", "6Bi", "43B", "z7", "oV", "bf", "0AT", "4zz", "6OY", "4A7", "4TV", "0ox", "LJ", "CK", "14P", "5Kv", "4N6", -"543", "41s", "0NU", "mg", "22N", "u6", "4xK", "6Mh", "6cD", "4Vg", "0mI", "2Xj", "7Oa", "4jc", "0QM", "6w", "2JB", "I2", "4DO", "65d", -"68T", "b7D", "06Y", "Qc", "dSm", "287", "4gS", "4r2", "7MP", "4hR", "276", "4F", "0h1", "09X", "b8E", "67U", "7nL", "4KN", "F3", "SR", -"9v", "1Nm", "4eb", "6PA", "5kA", "6NC", "21e", "1Po", "X1", "MP", "74F", "4UL", "bbO", "79v", "0v3", "0cR", "8Df", "nL", "4c1", "42X", -"4yQ", "4l0", "aM", "8Kg", "0lS", "Oa", "76w", "637", "4ZM", "6on", "BQ", "W0", "0OO", "2zl", "6AB", "40i", "4fM", "6Sn", "3xa", "k0", -"07G", "2Fl", "69J", "4Ha", "4EQ", "4P0", "d5g", "83o", "0PS", "7i", "a0D", "bQN", "50U", "hbt", "8h", "1Os", "05v", "RL", "7oR", "4JP", -"5WA", "66K", "2Im", "08F", "d1", "5X", "7LN", "4iL", "6Bm", "43F", "z3", "oR", "2Wo", "0bL", "4Yb", "6lA", "4A3", "4TR", "8fd", "LN", -"bb", "0AP", "cPl", "aeO", "547", "41w", "0NQ", "mc", "CO", "14T", "5Kr", "4N2", "77i", "4Vc", "0mM", "2Xn", "22J", "u2", "4xO", "6Ml", -"2JF", "I6", "4DK", "6qh", "7Oe", "4jg", "0QI", "6s", "1Y9", "1LX", "4gW", "4r6", "68P", "5YZ", "0rU", "Qg", "0h5", "1mu", "4Fz", "67Q", -"7MT", "4hV", "0Sx", "4B", "9r", "1Ni", "4ef", "6PE", "7nH", "4KJ", "F7", "SV", "X5", "MT", "74B", "4UH", "5kE", "6NG", "cx", "1Pk", -"0Mz", "nH", "4c5", "4vT", "4Xx", "79r", "0v7", "0cV", "0lW", "Oe", "5R9", "4Wy", "4yU", "4l4", "aI", "1RZ", "0OK", "ly", "6AF", "40m", -"4ZI", "6oj", "BU", "W4", "265", "5E", "488", "4iQ", "b9F", "66V", "0i2", "1lr", "G0", "RQ", "7oO", "4JM", "4da", "6QB", "8u", "1On", -"0PN", "7t", "7Nb", "aa0", "4EL", "64g", "2KA", "H1", "07Z", "0f3", "69W", "b6G", "4fP", "479", "dRn", "294", "22W", "8Jd", "4xR", "4m3", -"77t", "624", "0mP", "Nb", "CR", "V3", "5Ko", "6nm", "ajS", "41j", "0NL", "3kN", "20f", "0AM", "4zc", "aeR", "6al", "4TO", "Y2", "LS", -"Ac", "0bQ", "bcL", "78u", "4b2", "4wS", "8Ee", "oO", "7nU", "4KW", "04q", "SK", "9o", "1Nt", "51R", "6PX", "7MI", "4hK", "e6", "pW", -"2Hj", "09A", "4Fg", "67L", "68M", "4If", "0rH", "Qz", "2iG", "j7", "4gJ", "6Ri", "7Ox", "4jz", "0QT", "6n", "1z8", "1oY", "4DV", "4Q7", -"4ZT", "4O5", "BH", "0az", "0OV", "ld", "550", "40p", "4yH", "6Lk", "aT", "t5", "0lJ", "Ox", "6bG", "4Wd", "4Xe", "6mF", "2Vh", "0cK", -"0Mg", "nU", "6Cj", "42A", "5kX", "6NZ", "ce", "1Pv", "2N9", "MI", "7pW", "4UU", "4Gy", "5B9", "0i6", "1lv", "1BZ", "5A", "7LW", "4iU", -"4de", "6QF", "8q", "1Oj", "G4", "RU", "7oK", "4JI", "4EH", "64c", "2KE", "H5", "0PJ", "7p", "7Nf", "4kd", "4fT", "4s5", "2hY", "290", -"0sV", "Pd", "5M8", "4Hx", "6cY", "4Vz", "0mT", "Nf", "1F8", "0Cx", "4xV", "4m7", "7Pd", "41n", "0NH", "mz", "CV", "V7", "5Kk", "6ni", -"6ah", "4TK", "Y6", "LW", "20b", "0AI", "4zg", "6OD", "4b6", "4wW", "0Ly", "oK", "Ag", "0bU", "5IZ", "6lX", "9k", "1Np", "51V", "azN", -"7nQ", "4KS", "04u", "SO", "2Hn", "09E", "4Fc", "67H", "7MM", "4hO", "e2", "pS", "2iC", "j3", "4gN", "6Rm", "68I", "4Ib", "06D", "2Go", -"d4d", "82l", "4DR", "4Q3", "a1G", "bPM", "0QP", "6j", "0OR", "0Z3", "554", "40t", "4ZP", "4O1", "BL", "15W", "0lN", "2Ym", "6bC", "5GA", -"4yL", "6Lo", "aP", "09", "0Mc", "nQ", "6Cn", "42E", "4Xa", "6mB", "2Vl", "0cO", "8gg", "MM", "7pS", "4UQ", "bAN", "adL", "ca", "1Pr", -"G8", "RY", "7oG", "4JE", "4di", "6QJ", "2jd", "1Of", "0Rw", "5M", "480", "4iY", "4Gu", "5B5", "2Ix", "08S", "07R", "Ph", "5M4", "4Ht", -"4fX", "471", "1X6", "1MW", "0PF", "st", "7Nj", "4kh", "4ED", "64o", "2KI", "H9", "CZ", "14A", "5Kg", "6ne", "7Ph", "41b", "0ND", "mv", -"1F4", "0Ct", "4xZ", "6My", "5S6", "4Vv", "0mX", "Nj", "Ak", "0bY", "4Yw", "6lT", "6Bx", "43S", "0Lu", "oG", "bw", "0AE", "4zk", "6OH", -"6ad", "4TG", "0oi", "2ZJ", "7MA", "4hC", "0Sm", "4W", "2Hb", "09I", "4Fo", "67D", "aTn", "b5d", "04y", "SC", "9g", "8WE", "4es", "6PP", -"5o2", "4jr", "8XD", "6f", "1z0", "1oQ", "705", "65u", "68E", "4In", "06H", "Qr", "2iO", "1LM", "4gB", "6Ra", "5ia", "6Lc", "23E", "05", -"0lB", "Op", "6bO", "4Wl", "c4F", "aEm", "1d2", "0ar", "8FF", "ll", "558", "40x", "5kP", "6NR", "cm", "344", "0ns", "MA", "74W", "bon", -"4Xm", "6mN", "3FA", "0cC", "0Mo", "2xL", "6Cb", "42I", "4dm", "6QN", "8y", "1Ob", "05g", "2DL", "7oC", "4JA", "4Gq", "5B1", "d7G", "08W", -"0Rs", "5I", "484", "bSn", "52u", "475", "1X2", "1MS", "07V", "Pl", "5M0", "4Hp", "5Ua", "64k", "2KM", "1nO", "0PB", "7x", "7Nn", "4kl", -"7Pl", "41f", "8GX", "mr", "2UO", "14E", "5Kc", "6na", "5S2", "4Vr", "19u", "Nn", "1F0", "0Cp", "bBm", "ago", "ahn", "43W", "0Lq", "oC", -"Ao", "16t", "4Ys", "6lP", "75I", "4TC", "0om", "2ZN", "bs", "0AA", "4zo", "6OL", "2Hf", "09M", "4Fk", "6sH", "7ME", "4hG", "0Si", "4S", -"9c", "1Nx", "4ew", "6PT", "7nY", "bqh", "0pu", "SG", "1z4", "1oU", "4DZ", "65q", "5o6", "4jv", "0QX", "6b", "2iK", "1LI", "4gF", "6Re", -"68A", "4Ij", "06L", "Qv", "0lF", "Ot", "6bK", "4Wh", "4yD", "6Lg", "aX", "01", "0OZ", "lh", "5q4", "4tt", "4ZX", "4O9", "BD", "0av", -"0nw", "ME", "74S", "4UY", "5kT", "6NV", "ci", "1Pz", "0Mk", "nY", "6Cf", "42M", "4Xi", "6mJ", "2Vd", "0cG", "bL", "8Hf", "4zP", "4o1", -"75v", "606", "0oR", "0z3", "AP", "T1", "4YL", "6lo", "6BC", "43h", "0LN", "2ym", "22d", "0CO", "4xa", "6MB", "6cn", "4VM", "0mc", "NQ", -"Ca", "14z", "baN", "aDL", "7PS", "41Y", "8Gg", "mM", "247", "7G", "7NQ", "4kS", "com", "64T", "0k0", "1np", "E2", "PS", "69d", "4HO", -"4fc", "7Ca", "2hn", "1Ml", "0RL", "5v", "avS", "4ib", "4GN", "66e", "2IC", "J3", "05X", "Rb", "aUO", "b4E", "4dR", "4q3", "8F", "8Vd", -"4XV", "4M7", "1f8", "0cx", "0MT", "nf", "572", "42r", "5kk", "6Ni", "cV", "v7", "0nH", "Mz", "74l", "4Uf", "4Zg", "6oD", "2Tj", "0aI", -"y6", "lW", "6Ah", "40C", "5iZ", "583", "ag", "0BU", "0ly", "OK", "4B6", "4WW", "7lW", "4IU", "06s", "QI", "0I6", "1Lv", "4gy", "5b9", -"7OK", "4jI", "g4", "rU", "2Jh", "1oj", "4De", "65N", "7nf", "4Kd", "04B", "Sx", "2kE", "h5", "4eH", "6Pk", "5m8", "4hx", "0SV", "4l", -"2HY", "09r", "4FT", "4S5", "5Q8", "4Tx", "0oV", "Ld", "bH", "0Az", "4zT", "4o5", "6BG", "43l", "0LJ", "ox", "AT", "T5", "4YH", "6lk", -"6cj", "4VI", "0mg", "NU", "2vh", "0CK", "4xe", "6MF", "7PW", "4uU", "2n9", "mI", "Ce", "1pv", "5KX", "6nZ", "5UZ", "64P", "0k4", "1nt", -"0Py", "7C", "7NU", "4kW", "4fg", "6SD", "2hj", "1Mh", "E6", "PW", "7mI", "4HK", "4GJ", "66a", "2IG", "J7", "0RH", "5r", "7Ld", "4if", -"4dV", "4q7", "8B", "1OY", "0qT", "Rf", "7ox", "4Jz", "0MP", "nb", "576", "42v", "4XR", "4M3", "dll", "17U", "0nL", "3KN", "74h", "4Ub", -"5ko", "6Nm", "cR", "v3", "y2", "lS", "6Al", "40G", "4Zc", "aER", "2Tn", "0aM", "18T", "OO", "4B2", "4WS", "bCL", "587", "ac", "0BQ", -"0I2", "1Lr", "53T", "axL", "68z", "4IQ", "06w", "QM", "2Jl", "1on", "4Da", "65J", "7OO", "4jM", "g0", "6Y", "9X", "h1", "4eL", "6Po", -"7nb", "aA0", "04F", "2Em", "d6f", "09v", "4FP", "4S1", "a3E", "bRO", "0SR", "4h", "AX", "T9", "4YD", "6lg", "6BK", "4wh", "0LF", "ot", -"bD", "0Av", "4zX", "4o9", "5Q4", "4Tt", "0oZ", "Lh", "Ci", "14r", "5KT", "6nV", "ajh", "41Q", "0Nw", "mE", "22l", "0CG", "4xi", "6MJ", -"6cf", "4VE", "0mk", "NY", "07a", "2FJ", "69l", "4HG", "4fk", "6SH", "2hf", "1Md", "0Pu", "7O", "7NY", "bQh", "4Ew", "6pT", "0k8", "1nx", -"05P", "Rj", "5O6", "4Jv", "4dZ", "453", "8N", "1OU", "0RD", "qv", "7Lh", "4ij", "4GF", "66m", "2IK", "1lI", "5kc", "6Na", "21G", "27", -"8gX", "Mr", "74d", "4Un", "bbm", "79T", "1f0", "0cp", "397", "nn", "5s2", "42z", "4ys", "6LP", "ao", "366", "0lq", "OC", "76U", "bml", -"4Zo", "6oL", "Bs", "0aA", "0Om", "2zN", "7QA", "40K", "7OC", "4jA", "0Qo", "6U", "3ZA", "1ob", "4Dm", "65F", "68v", "b7f", "0rs", "QA", -"dSO", "8UG", "4gq", "5b1", "5m0", "4hp", "8ZF", "4d", "1x2", "09z", "727", "67w", "7nn", "4Kl", "04J", "Sp", "9T", "1NO", "51i", "6Pc", -"6BO", "43d", "0LB", "op", "2WM", "0bn", "5Ia", "6lc", "5Q0", "4Tp", "8fF", "Ll", "1D2", "0Ar", "cPN", "aem", "ajl", "41U", "0Ns", "mA", -"Cm", "14v", "5KP", "6nR", "6cb", "4VA", "0mo", "2XL", "22h", "0CC", "4xm", "6MN", "4fo", "6SL", "2hb", "8TY", "07e", "2FN", "69h", "4HC", -"4Es", "64X", "d5E", "83M", "0Pq", "7K", "a0f", "bQl", "50w", "457", "8J", "1OQ", "05T", "Rn", "5O2", "4Jr", "4GB", "66i", "2IO", "08d", -"1Ba", "5z", "7Ll", "4in", "0nD", "Mv", "7ph", "4Uj", "5kg", "6Ne", "cZ", "23", "0MX", "nj", "5s6", "4vv", "4XZ", "6my", "1f4", "0ct", -"0lu", "OG", "6bx", "5Gz", "4yw", "6LT", "ak", "0BY", "0Oi", "2zJ", "6Ad", "40O", "4Zk", "6oH", "Bw", "0aE", "2Jd", "1of", "4Di", "65B", -"7OG", "4jE", "g8", "6Q", "2ix", "1Lz", "4gu", "5b5", "68r", "4IY", "0rw", "QE", "1x6", "1mW", "4FX", "4S9", "5m4", "4ht", "0SZ", "ph", -"9P", "h9", "4eD", "6Pg", "7nj", "4Kh", "04N", "St", "22u", "375", "4xp", "598", "77V", "blo", "0mr", "1h2", "Cp", "14k", "5KM", "6nO", -"7PB", "41H", "0Nn", "3kl", "20D", "34", "4zA", "6Ob", "6aN", "4Tm", "0oC", "Lq", "AA", "0bs", "bcn", "78W", "569", "43y", "384", "om", -"9Kd", "5g", "5l3", "4is", "734", "66t", "1y1", "08y", "05I", "Rs", "7om", "4Jo", "4dC", "7AA", "8W", "1OL", "0Pl", "7V", "ats", "4kB", -"4En", "64E", "2Kc", "1na", "07x", "PB", "69u", "b6e", "4fr", "5c2", "dRL", "8TD", "4Zv", "6oU", "Bj", "0aX", "0Ot", "lF", "6Ay", "40R", -"4yj", "6LI", "av", "0BD", "0lh", "OZ", "6be", "4WF", "4XG", "6md", "2VJ", "0ci", "0ME", "nw", "6CH", "42c", "5kz", "6Nx", "cG", "1PT", -"0nY", "Mk", "5P7", "4Uw", "5N5", "4Ku", "04S", "Si", "9M", "1NV", "4eY", "440", "7Mk", "4hi", "0SG", "pu", "2HH", "K8", "4FE", "67n", -"68o", "4ID", "1", "QX", "2ie", "1Lg", "4gh", "6RK", "7OZ", "4jX", "0Qv", "6L", "2Jy", "3O9", "4Dt", "5A4", "4C9", "4VX", "0mv", "ND", -"22q", "0CZ", "4xt", "6MW", "7PF", "41L", "x9", "mX", "Ct", "14o", "5KI", "6nK", "6aJ", "4Ti", "0oG", "Lu", "bY", "30", "4zE", "6Of", -"5r5", "4wu", "380", "oi", "AE", "0bw", "4YY", "4L8", "5Wz", "66p", "1y5", "1lT", "0RY", "5c", "5l7", "4iw", "4dG", "6Qd", "8S", "1OH", -"05M", "Rw", "7oi", "4Jk", "4Ej", "64A", "2Kg", "1ne", "0Ph", "7R", "7ND", "4kF", "4fv", "5c6", "0H9", "1My", "0st", "PF", "69q", "4HZ", -"0Op", "lB", "ako", "40V", "4Zr", "6oQ", "Bn", "15u", "0ll", "2YO", "6ba", "4WB", "4yn", "6LM", "ar", "1Ra", "0MA", "ns", "6CL", "42g", -"4XC", "79I", "2VN", "0cm", "8gE", "Mo", "5P3", "4Us", "bAl", "adn", "cC", "1PP", "9I", "1NR", "51t", "444", "5N1", "4Kq", "04W", "Sm", -"2HL", "09g", "4FA", "67j", "7Mo", "4hm", "0SC", "4y", "2ia", "1Lc", "4gl", "6RO", "68k", "5Ya", "5", "2GM", "d4F", "82N", "4Dp", "5A0", -"a1e", "bPo", "0Qr", "6H", "Cx", "14c", "5KE", "6nG", "7PJ", "4uH", "x5", "mT", "0V7", "0CV", "4xx", "590", "4C5", "4VT", "0mz", "NH", -"AI", "16R", "4YU", "4L4", "561", "43q", "0LW", "oe", "bU", "w4", "4zI", "6Oj", "6aF", "4Te", "0oK", "Ly", "05A", "2Dj", "7oe", "4Jg", -"4dK", "6Qh", "2jF", "i6", "0RU", "5o", "7Ly", "5yZ", "4GW", "4R6", "1y9", "08q", "07p", "PJ", "7mT", "4HV", "4fz", "6SY", "0H5", "1Mu", -"f7", "sV", "7NH", "4kJ", "4Ef", "64M", "2Kk", "1ni", "4yb", "6LA", "23g", "0BL", "Z3", "OR", "6bm", "4WN", "c4d", "aEO", "Bb", "0aP", -"8Fd", "lN", "4a3", "40Z", "5kr", "4n2", "cO", "8Ie", "0nQ", "Mc", "74u", "615", "4XO", "6ml", "2VB", "U2", "0MM", "2xn", "7Sa", "42k", -"7Mc", "4ha", "0SO", "4u", "3Xa", "K0", "4FM", "67f", "aTL", "b5F", "0pS", "Sa", "9E", "8Wg", "4eQ", "448", "7OR", "4jP", "254", "6D", -"0j3", "1os", "cnn", "65W", "68g", "4IL", "9", "QP", "2im", "1Lo", "53I", "6RC", "7PN", "41D", "x1", "mP", "2Um", "14g", "5KA", "6nC", -"4C1", "4VP", "19W", "NL", "0V3", "0CR", "bBO", "594", "565", "43u", "0LS", "oa", "AM", "16V", "4YQ", "4L0", "6aB", "4Ta", "0oO", "2Zl", -"bQ", "38", "4zM", "6On", "4dO", "6Ql", "2jB", "i2", "05E", "2Dn", "7oa", "4Jc", "4GS", "4R2", "d7e", "08u", "0RQ", "5k", "a2F", "bSL", -"52W", "ayO", "0H1", "1Mq", "07t", "PN", "69y", "4HR", "4Eb", "64I", "2Ko", "1nm", "f3", "7Z", "7NL", "4kN", "Z7", "OV", "6bi", "4WJ", -"4yf", "6LE", "az", "0BH", "0Ox", "lJ", "4a7", "4tV", "4Zz", "6oY", "Bf", "0aT", "0nU", "Mg", "74q", "5EZ", "5kv", "4n6", "cK", "1PX", -"0MI", "2xj", "6CD", "42o", "4XK", "6mh", "2VF", "U6", "2HD", "K4", "4FI", "67b", "7Mg", "4he", "0SK", "4q", "9A", "1NZ", "4eU", "4p4", -"5N9", "4Ky", "0pW", "Se", "0j7", "1ow", "4Dx", "5A8", "7OV", "4jT", "0Qz", "rH", "2ii", "1Lk", "4gd", "6RG", "68c", "4IH", "D5", "QT", -"5Ls", "4I3", "F", "13U", "0IP", "jb", "536", "46v", "5oo", "6Jm", "gR", "r3", "0jL", "3ON", "6dA", "4Qb", "5NB", "aAR", "2Pn", "0eM", -"0Ka", "hS", "6El", "44G", "49w", "abN", "ec", "0FQ", "8ae", "KO", "4F2", "4SS", "4X0", "4MQ", "02w", "UM", "0M2", "0XS", "57T", "a8D", -"7KO", "4nM", "c0", "2Y", "2Nl", "1kn", "aJ1", "61J", "6zC", "aE0", "00F", "2Am", "yP", "l1", "4aL", "6To", "a7E", "58U", "0WR", "0h", -"ZL", "84n", "4BP", "4W1", "fH", "0Ez", "5nu", "4k5", "5U8", "4Px", "0kV", "Hd", "ET", "P5", "5Mi", "6hk", "6FG", "47l", "0HJ", "kx", -"dy", "0GK", "48m", "6IF", "6gj", "4RI", "0ig", "JU", "Ge", "0dW", "5OX", "5Z9", "4d4", "4qU", "1ZZ", "iI", "0Ty", "3C", "4z6", "4oW", -"5QZ", "60P", "Yg", "0zU", "A6", "TW", "6yh", "4LK", "4bg", "6WD", "2lj", "0YI", "0VH", "1r", "6XE", "4mf", "4CJ", "62a", "2MG", "N7", -"0uT", "Vf", "7kx", "4Nz", "5pw", "4u7", "xJ", "1KY", "0IT", "jf", "532", "46r", "5Lw", "4I7", "B", "0gx", "0jH", "Iz", "6dE", "4Qf", -"5ok", "6Ji", "gV", "r7", "0Ke", "hW", "6Eh", "44C", "5NF", "6kD", "2Pj", "0eI", "0hy", "KK", "4F6", "4SW", "49s", "6HX", "eg", "0FU", -"0M6", "0XW", "4cy", "5f9", "4X4", "4MU", "02s", "UI", "Xy", "1kj", "5PD", "61N", "7KK", "4nI", "c4", "vU", "yT", "l5", "4aH", "6Tk", -"6zG", "4Od", "00B", "Wx", "ZH", "0yz", "4BT", "4W5", "5i8", "4lx", "0WV", "0l", "71v", "646", "0kR", "3NP", "fL", "8Lf", "5nq", "4k1", -"6FC", "47h", "0HN", "29e", "EP", "P1", "5Mm", "6ho", "6gn", "4RM", "0ic", "JQ", "26d", "0GO", "48i", "6IB", "4d0", "45Y", "8Cg", "iM", -"Ga", "0dS", "beN", "hYu", "ckm", "60T", "Yc", "0zQ", "207", "3G", "4z2", "4oS", "4bc", "7Ga", "2ln", "0YM", "A2", "TS", "6yl", "4LO", -"4CN", "62e", "2MC", "N3", "0VL", "1v", "6XA", "4mb", "5ps", "4u3", "xN", "8Rd", "01X", "Vb", "aQO", "b0E", "5og", "6Je", "gZ", "63", -"0jD", "Iv", "6dI", "4Qj", "7l9", "6iy", "N", "0gt", "0IX", "jj", "5w6", "4rv", "5mV", "5x7", "ek", "0FY", "0hu", "KG", "6fx", "5Cz", -"5NJ", "6kH", "Fw", "0eE", "92", "3nk", "6Ed", "44O", "7KG", "4nE", "c8", "2Q", "Xu", "1kf", "5PH", "61B", "4X8", "4MY", "0vw", "UE", -"2mx", "1Hz", "4cu", "5f5", "5i4", "4lt", "0WZ", "th", "ZD", "0yv", "4BX", "4W9", "6zK", "4Oh", "00N", "Wt", "yX", "l9", "4aD", "6Tg", -"2SM", "0fn", "5Ma", "6hc", "6FO", "47d", "0HB", "kp", "24Y", "0Er", "bDo", "aam", "5U0", "4Pp", "8bF", "Hl", "Gm", "10v", "5OP", "5Z1", -"anl", "45U", "0Js", "iA", "dq", "0GC", "48e", "6IN", "6gb", "4RA", "0io", "3Lm", "03e", "2BN", "7iA", "4LC", "4bo", "6WL", "zs", "0YA", -"0Tq", "3K", "a4f", "bUl", "4As", "5D3", "Yo", "87M", "01T", "Vn", "5K2", "4Nr", "54w", "417", "xB", "1KQ", "1Fa", "1z", "6XM", "4mn", -"4CB", "62i", "2MO", "0xl", "1za", "Ir", "6dM", "4Qn", "5oc", "6Ja", "25G", "67", "9Pe", "jn", "5w2", "46z", "bfm", "aCo", "J", "0gp", -"0hq", "KC", "72U", "bil", "5mR", "5x3", "eo", "326", "96", "3no", "7UA", "44K", "5NN", "6kL", "Fs", "0eA", "Xq", "1kb", "5PL", "61F", -"7KC", "4nA", "0Uo", "2U", "39U", "8QG", "4cq", "5f1", "aRl", "796", "0vs", "UA", "2LQ", "0yr", "767", "63w", "5i0", "4lp", "9Ng", "0d", -"2oM", "0Zn", "55i", "6Tc", "6zO", "4Ol", "00J", "Wp", "6FK", "4sh", "0HF", "kt", "EX", "P9", "5Me", "6hg", "5U4", "4Pt", "0kZ", "Hh", -"fD", "0Ev", "5ny", "4k9", "4d8", "45Q", "0Jw", "iE", "Gi", "10r", "5OT", "5Z5", "6gf", "4RE", "0ik", "JY", "du", "0GG", "48a", "6IJ", -"4bk", "6WH", "zw", "0YE", "03a", "2BJ", "6yd", "4LG", "4Aw", "5D7", "Yk", "0zY", "0Tu", "3O", "6Zx", "bUh", "54s", "413", "xF", "1KU", -"01P", "Vj", "5K6", "4Nv", "4CF", "62m", "2MK", "0xh", "0VD", "uv", "6XI", "4mj", "5NS", "6kQ", "Fn", "11u", "0Kp", "hB", "aoo", "44V", -"49f", "6HM", "er", "1Va", "0hl", "3Mn", "6fa", "4SB", "5Lb", "7yA", "W", "0gm", "0IA", "js", "6GL", "46g", "bEl", "hyW", "gC", "0Dq", -"8cE", "Io", "5T3", "4Qs", "5J1", "4Oq", "00W", "Wm", "yA", "0Zs", "55t", "404", "6YN", "4lm", "0WC", "0y", "2LL", "0yo", "4BA", "63j", -"6xc", "bws", "02f", "2CM", "2ma", "0XB", "4cl", "6VO", "a5e", "bTo", "0Ur", "2H", "Xl", "86N", "5PQ", "5E0", "dh", "0GZ", "5lU", "5y4", -"4G9", "4RX", "0iv", "JD", "Gt", "0dF", "5OI", "6jK", "6Dg", "45L", "81", "iX", "fY", "70", "5nd", "6Kf", "6eJ", "4Pi", "0kG", "Hu", -"EE", "0fw", "5Mx", "4H8", "5v5", "4su", "1Xz", "ki", "0VY", "1c", "5h7", "4mw", "5Sz", "62p", "2MV", "0xu", "01M", "Vw", "7ki", "4Nk", -"54n", "6Ud", "2nJ", "1KH", "0Th", "3R", "6Ze", "4oF", "4Aj", "60A", "Yv", "0zD", "0wt", "TF", "6yy", "4LZ", "4bv", "5g6", "zj", "0YX", -"0Kt", "hF", "6Ey", "44R", "5NW", "6kU", "Fj", "0eX", "0hh", "KZ", "6fe", "4SF", "49b", "6HI", "ev", "0FD", "0IE", "jw", "6GH", "46c", -"5Lf", "6id", "S", "0gi", "0jY", "Ik", "5T7", "4Qw", "5oz", "6Jx", "gG", "0Du", "yE", "0Zw", "4aY", "400", "5J5", "4Ou", "00S", "Wi", -"ZY", "O8", "4BE", "63n", "6YJ", "4li", "0WG", "tu", "2me", "0XF", "4ch", "6VK", "6xg", "4MD", "02b", "UX", "Xh", "3K9", "5PU", "5E4", -"7KZ", "4nX", "0Uv", "2L", "73V", "bho", "0ir", "1l2", "dl", "335", "48x", "5y0", "6Dc", "45H", "85", "3ol", "Gp", "0dB", "5OM", "6jO", -"6eN", "4Pm", "0kC", "Hq", "24D", "74", "bDr", "6Kb", "529", "47y", "8AG", "km", "EA", "0fs", "bgn", "aBl", "774", "62t", "199", "0xq", -"9Od", "1g", "5h3", "4ms", "54j", "7EA", "2nN", "1KL", "01I", "Vs", "7km", "4No", "4An", "60E", "Yr", "1ja", "0Tl", "3V", "6Za", "4oB", -"4br", "5g2", "zn", "8PD", "03x", "TB", "aSo", "785", "49n", "6HE", "ez", "0FH", "0hd", "KV", "6fi", "4SJ", "bdI", "6kY", "Ff", "0eT", -"0Kx", "hJ", "4e7", "4pV", "5ov", "4j6", "gK", "0Dy", "0jU", "Ig", "6dX", "5AZ", "5Lj", "6ih", "DW", "Q6", "0II", "28b", "6GD", "46o", -"6YF", "4le", "0WK", "0q", "ZU", "O4", "4BI", "63b", "5J9", "4Oy", "0tW", "We", "yI", "1JZ", "4aU", "4t4", "7KV", "4nT", "0Uz", "vH", -"Xd", "1kw", "5PY", "5E8", "6xk", "4MH", "02n", "UT", "2mi", "0XJ", "4cd", "6VG", "2Qm", "0dN", "5OA", "6jC", "6Do", "45D", "89", "iP", -"0R3", "0GR", "48t", "acM", "4G1", "4RP", "94O", "JL", "EM", "12V", "5Mp", "4H0", "525", "47u", "0HS", "ka", "fQ", "78", "5nl", "6Kn", -"6eB", "4Pa", "0kO", "3NM", "01E", "3PO", "7ka", "4Nc", "54f", "6Ul", "xS", "m2", "0VQ", "1k", "a6F", "59V", "4CS", "4V2", "195", "85m", -"03t", "TN", "4Y3", "4LR", "56W", "a9G", "zb", "0YP", "b3", "3Z", "6Zm", "4oN", "4Ab", "60I", "2Oo", "0zL", "1xA", "KR", "6fm", "4SN", -"49j", "6HA", "27g", "0FL", "8Bd", "hN", "4e3", "44Z", "bdM", "aAO", "Fb", "0eP", "0jQ", "Ic", "70u", "655", "5or", "4j2", "gO", "8Me", -"0IM", "28f", "7Wa", "46k", "5Ln", "6il", "DS", "Q2", "ZQ", "O0", "4BM", "63f", "6YB", "4la", "0WO", "0u", "yM", "8Sg", "4aQ", "408", -"aPL", "b1F", "0tS", "Wa", "0n3", "1ks", "bzO", "61W", "7KR", "4nP", "214", "2D", "2mm", "0XN", "57I", "6VC", "6xo", "4ML", "02j", "UP", -"6Dk", "4qH", "0Jf", "iT", "Gx", "0dJ", "5OE", "6jG", "4G5", "4RT", "0iz", "JH", "dd", "0GV", "48p", "5y8", "521", "47q", "0HW", "ke", -"EI", "12R", "5Mt", "4H4", "6eF", "4Pe", "0kK", "Hy", "fU", "s4", "5nh", "6Kj", "54b", "6Uh", "xW", "m6", "01A", "3PK", "7ke", "4Ng", -"4CW", "4V6", "191", "0xy", "0VU", "1o", "6XX", "59R", "4bz", "6WY", "zf", "0YT", "03p", "TJ", "4Y7", "4LV", "4Af", "60M", "Yz", "0zH", -"b7", "wV", "6Zi", "4oJ", "5H3", "4Ms", "02U", "Uo", "2mR", "0Xq", "57v", "426", "7Km", "4no", "0UA", "vs", "2NN", "1kL", "5Pb", "61h", -"6za", "4OB", "00d", "2AO", "yr", "1Ja", "4an", "6TM", "a7g", "58w", "0Wp", "0J", "Zn", "84L", "4Br", "5G2", "5LQ", "5Y0", "d", "13w", -"0Ir", "1L2", "amm", "46T", "5oM", "6JO", "gp", "0DB", "0jn", "3Ol", "6dc", "5Aa", "bdr", "6kb", "2PL", "0eo", "0KC", "hq", "6EN", "44e", -"49U", "abl", "eA", "0Fs", "8aG", "Km", "5V1", "4Sq", "1Dz", "3a", "5j5", "4ou", "4AY", "4T8", "YE", "0zw", "03O", "Tu", "6yJ", "4Li", -"4bE", "6Wf", "zY", "o8", "0Vj", "1P", "6Xg", "4mD", "4Ch", "62C", "2Me", "0xF", "0uv", "VD", "7kZ", "4NX", "5pU", "5e4", "xh", "3k9", -"fj", "0EX", "5nW", "6KU", "6ey", "4PZ", "0kt", "HF", "Ev", "0fD", "5MK", "6hI", "6Fe", "47N", "0Hh", "kZ", "26B", "52", "48O", "6Id", -"6gH", "4Rk", "0iE", "Jw", "GG", "0du", "5Oz", "6jx", "5t7", "4qw", "0JY", "ik", "2mV", "0Xu", "57r", "422", "5H7", "4Mw", "02Q", "Uk", -"2NJ", "1kH", "5Pf", "61l", "7Ki", "4nk", "0UE", "vw", "yv", "0ZD", "4aj", "6TI", "6ze", "4OF", "0th", "WZ", "Zj", "0yX", "4Bv", "5G6", -"6Yy", "4lZ", "0Wt", "0N", "0Iv", "jD", "4g9", "46P", "5LU", "5Y4", "Dh", "0gZ", "0jj", "IX", "6dg", "4QD", "5oI", "6JK", "gt", "0DF", -"0KG", "hu", "6EJ", "44a", "5Nd", "6kf", "FY", "S8", "1xz", "Ki", "5V5", "4Su", "49Q", "4h8", "eE", "0Fw", "756", "60v", "YA", "0zs", -"9Mf", "3e", "5j1", "4oq", "4bA", "6Wb", "2lL", "0Yo", "03K", "Tq", "6yN", "4Lm", "4Cl", "62G", "2Ma", "0xB", "0Vn", "1T", "6Xc", "59i", -"54Y", "5e0", "xl", "8RF", "01z", "1p2", "aQm", "b0g", "71T", "bjm", "0kp", "HB", "fn", "317", "5nS", "6KQ", "6Fa", "47J", "0Hl", "29G", -"Er", "12i", "5MO", "6hM", "6gL", "4Ro", "0iA", "Js", "26F", "56", "48K", "7YA", "5t3", "4qs", "8CE", "io", "GC", "0dq", "bel", "hYW", -"7Ke", "4ng", "0UI", "2s", "XW", "M6", "5Pj", "6uh", "6xX", "6m9", "0vU", "Ug", "2mZ", "0Xy", "4cW", "4v6", "4y7", "4lV", "0Wx", "0B", -"Zf", "0yT", "4Bz", "63Q", "6zi", "4OJ", "B7", "WV", "yz", "0ZH", "4af", "6TE", "5oE", "6JG", "gx", "0DJ", "0jf", "IT", "6dk", "4QH", -"5LY", "5Y8", "l", "0gV", "0Iz", "jH", "4g5", "4rT", "5mt", "4h4", "eI", "1VZ", "0hW", "Ke", "5V9", "4Sy", "5Nh", "6kj", "FU", "S4", -"0KK", "hy", "6EF", "44m", "03G", "2Bl", "6yB", "4La", "4bM", "6Wn", "zQ", "o0", "0TS", "3i", "a4D", "bUN", "4AQ", "4T0", "YM", "87o", -"01v", "VL", "7kR", "4NP", "54U", "hft", "0N3", "1Ks", "0Vb", "1X", "6Xo", "4mL", "5SA", "62K", "2Mm", "0xN", "2So", "0fL", "5MC", "6hA", -"6Fm", "47F", "1XA", "kR", "fb", "0EP", "bDM", "aaO", "4E3", "4PR", "8bd", "HN", "GO", "10T", "5Or", "4J2", "507", "45w", "0JQ", "ic", -"dS", "q2", "48G", "6Il", "73i", "4Rc", "0iM", "3LO", "XS", "M2", "5Pn", "61d", "7Ka", "4nc", "0UM", "2w", "39w", "8Qe", "4cS", "4v2", -"aRN", "b3D", "02Y", "Uc", "Zb", "0yP", "bxM", "63U", "4y3", "4lR", "236", "0F", "2oo", "0ZL", "4ab", "6TA", "6zm", "4ON", "B3", "WR", -"0jb", "IP", "6do", "4QL", "5oA", "6JC", "25e", "0DN", "9PG", "jL", "4g1", "46X", "686", "aCM", "h", "0gR", "0hS", "Ka", "72w", "677", -"49Y", "4h0", "eM", "8Og", "0KO", "3nM", "6EB", "44i", "5Nl", "6kn", "FQ", "S0", "4bI", "6Wj", "zU", "o4", "03C", "Ty", "6yF", "4Le", -"4AU", "4T4", "YI", "1jZ", "0TW", "3m", "5j9", "4oy", "54Q", "5e8", "xd", "1Kw", "01r", "VH", "7kV", "4NT", "4Cd", "62O", "2Mi", "0xJ", -"0Vf", "uT", "6Xk", "4mH", "6Fi", "47B", "0Hd", "kV", "Ez", "0fH", "5MG", "6hE", "4E7", "4PV", "0kx", "HJ", "ff", "0ET", "bDI", "6KY", -"503", "45s", "0JU", "ig", "GK", "0dy", "5Ov", "4J6", "6gD", "4Rg", "0iI", "3LK", "dW", "q6", "48C", "6Ih", "4Z2", "4OS", "00u", "WO", -"yc", "0ZQ", "55V", "hgw", "6Yl", "4lO", "a2", "tS", "2Ln", "0yM", "4Bc", "63H", "6xA", "4Mb", "02D", "2Co", "2mC", "n3", "4cN", "6Vm", -"a5G", "bTM", "0UP", "2j", "XN", "86l", "5Ps", "4U3", "5Nq", "4K1", "FL", "11W", "0KR", "3nP", "514", "44t", "49D", "6Ho", "eP", "49", -"0hN", "3ML", "6fC", "5CA", "aV1", "6iB", "u", "0gO", "0Ic", "jQ", "6Gn", "46E", "bEN", "hyu", "ga", "0DS", "8cg", "IM", "4D0", "4QQ", -"1FZ", "1A", "4x4", "4mU", "4Cy", "5F9", "0m6", "0xW", "C4", "VU", "7kK", "4NI", "54L", "6UF", "xy", "1Kj", "0TJ", "3p", "6ZG", "4od", -"4AH", "60c", "YT", "L5", "0wV", "Td", "5I8", "4Lx", "4bT", "4w5", "zH", "0Yz", "dJ", "0Gx", "5lw", "4i7", "6gY", "4Rz", "0iT", "Jf", -"GV", "R7", "5Ok", "6ji", "6DE", "45n", "0JH", "iz", "24b", "0EI", "5nF", "6KD", "6eh", "4PK", "0ke", "HW", "Eg", "0fU", "5MZ", "6hX", -"4f6", "4sW", "0Hy", "kK", "yg", "0ZU", "55R", "6TX", "4Z6", "4OW", "00q", "WK", "2Lj", "0yI", "4Bg", "63L", "6Yh", "4lK", "a6", "tW", -"2mG", "n7", "4cJ", "6Vi", "6xE", "4Mf", "0vH", "Uz", "XJ", "1kY", "5Pw", "4U7", "7Kx", "4nz", "0UT", "2n", "0KV", "hd", "510", "44p", -"5Nu", "4K5", "FH", "0ez", "0hJ", "Kx", "6fG", "4Sd", "5mi", "6Hk", "eT", "p5", "0Ig", "jU", "6Gj", "46A", "5LD", "6iF", "q", "0gK", -"1zZ", "II", "4D4", "4QU", "5oX", "5z9", "ge", "0DW", "byN", "62V", "0m2", "0xS", "225", "1E", "4x0", "4mQ", "54H", "6UB", "2nl", "1Kn", -"C0", "VQ", "7kO", "4NM", "4AL", "60g", "YP", "L1", "0TN", "3t", "6ZC", "ae0", "4bP", "439", "zL", "8Pf", "03Z", "0b3", "aSM", "b2G", -"73t", "664", "0iP", "Jb", "dN", "8Nd", "48Z", "4i3", "6DA", "45j", "0JL", "3oN", "GR", "R3", "5Oo", "6jm", "6el", "4PO", "0ka", "HS", -"24f", "0EM", "5nB", "aaR", "4f2", "4sS", "8Ae", "kO", "Ec", "0fQ", "695", "aBN", "6Yd", "4lG", "0Wi", "0S", "Zw", "0yE", "4Bk", "6wH", -"6zx", "buh", "0tu", "WG", "yk", "0ZY", "4aw", "5d7", "5k6", "4nv", "0UX", "2b", "XF", "1kU", "741", "61q", "6xI", "4Mj", "02L", "Uv", -"2mK", "0Xh", "4cF", "6Ve", "49L", "6Hg", "eX", "41", "0hF", "Kt", "6fK", "4Sh", "5Ny", "4K9", "FD", "0ev", "0KZ", "hh", "5u4", "4pt", -"5oT", "5z5", "gi", "1Tz", "0jw", "IE", "4D8", "4QY", "5LH", "6iJ", "Du", "0gG", "0Ik", "jY", "6Gf", "46M", "01g", "3Pm", "7kC", "4NA", -"54D", "6UN", "xq", "1Kb", "0Vs", "1I", "a6d", "59t", "4Cq", "5F1", "d3G", "85O", "03V", "Tl", "5I0", "4Lp", "56u", "435", "2lQ", "0Yr", -"0TB", "3x", "6ZO", "4ol", "5Qa", "60k", "2OM", "0zn", "2QO", "0dl", "5Oc", "6ja", "6DM", "45f", "1Za", "ir", "dB", "0Gp", "48V", "aco", -"5W2", "4Rr", "94m", "Jn", "Eo", "12t", "5MR", "5X3", "aln", "47W", "0Hq", "kC", "fs", "0EA", "5nN", "6KL", "71I", "4PC", "0km", "3No", -"Zs", "0yA", "4Bo", "63D", "7IA", "4lC", "0Wm", "0W", "yo", "8SE", "4as", "5d3", "aPn", "b1d", "00y", "WC", "XB", "1kQ", "745", "61u", -"5k2", "4nr", "9Le", "2f", "2mO", "0Xl", "4cB", "6Va", "6xM", "4Mn", "02H", "Ur", "0hB", "Kp", "6fO", "4Sl", "49H", "6Hc", "27E", "45", -"8BF", "hl", "518", "44x", "bdo", "aAm", "2PQ", "0er", "0js", "IA", "70W", "bkn", "5oP", "5z1", "gm", "304", "0Io", "28D", "6Gb", "46I", -"5LL", "6iN", "y", "0gC", "5pH", "6UJ", "xu", "1Kf", "C8", "VY", "7kG", "4NE", "4Cu", "5F5", "2Mx", "1hz", "0Vw", "1M", "4x8", "4mY", -"4bX", "431", "zD", "0Yv", "03R", "Th", "5I4", "4Lt", "4AD", "60o", "YX", "L9", "0TF", "wt", "6ZK", "4oh", "6DI", "45b", "0JD", "iv", -"GZ", "0dh", "5Og", "6je", "5W6", "4Rv", "0iX", "Jj", "dF", "0Gt", "48R", "6Iy", "6Fx", "47S", "0Hu", "kG", "Ek", "0fY", "5MV", "5X7", -"6ed", "4PG", "0ki", "3Nk", "fw", "0EE", "5nJ", "6KH", "356", "bo", "6OP", "4zs", "bnl", "75U", "LC", "0oq", "0bA", "As", "6lL", "4Yo", -"43K", "7RA", "2yN", "0Lm", "17", "22G", "6Ma", "4xB", "4Vn", "6cM", "Nr", "19i", "14Y", "CB", "aDo", "bam", "41z", "5p2", "mn", "8GD", -"7d", "8YF", "4kp", "5n0", "64w", "717", "1nS", "2KQ", "Pp", "07J", "4Hl", "69G", "6Sc", "52i", "1MO", "2hM", "5U", "0Ro", "4iA", "7LC", -"66F", "4Gm", "08K", "3YA", "RA", "0qs", "b4f", "aUl", "5a1", "4dq", "8VG", "8e", "6mV", "4Xu", "17r", "022", "nE", "0Mw", "42Q", "4c8", -"6NJ", "5kH", "1Pf", "cu", "MY", "X8", "4UE", "74O", "6og", "4ZD", "W9", "BX", "lt", "0OF", "4th", "6AK", "4l9", "4yX", "0Bv", "aD", -"Oh", "0lZ", "4Wt", "5R4", "4Iv", "5L6", "Qj", "06P", "1LU", "1Y4", "463", "4gZ", "4jj", "7Oh", "rv", "0QD", "1oI", "2JK", "65m", "4DF", -"4KG", "7nE", "2EJ", "04a", "1Nd", "2kf", "6PH", "4ek", "5xz", "492", "4O", "0Su", "09Q", "0h8", "5C7", "4Fw", "5Dz", "6ax", "LG", "0ou", -"0AY", "bk", "6OT", "4zw", "43O", "6Bd", "2yJ", "0Li", "0bE", "Aw", "6lH", "4Yk", "4Vj", "6cI", "Nv", "0mD", "13", "22C", "6Me", "4xF", -"4uv", "5p6", "mj", "0NX", "1pU", "CF", "6ny", "7k9", "4P9", "4EX", "1nW", "2KU", "sh", "0PZ", "4kt", "5n4", "6Sg", "4fD", "k9", "2hI", -"Pt", "07N", "4Hh", "69C", "66B", "4Gi", "08O", "2Id", "5Q", "d8", "4iE", "7LG", "5a5", "4du", "1Oz", "8a", "RE", "0qw", "4JY", "aUh", -"nA", "0Ms", "42U", "ail", "6mR", "4Xq", "17v", "026", "3Km", "0no", "4UA", "74K", "6NN", "5kL", "1Pb", "cq", "lp", "0OB", "40d", "6AO", -"6oc", "5Ja", "0an", "2TM", "Ol", "18w", "4Wp", "5R0", "afm", "bCo", "0Br", "1G2", "1LQ", "1Y0", "467", "53w", "4Ir", "5L2", "Qn", "06T", -"1oM", "2JO", "65i", "4DB", "4jn", "7Ol", "6z", "1Aa", "8WY", "2kb", "6PL", "4eo", "4KC", "7nA", "2EN", "04e", "09U", "d6E", "5C3", "4Fs", -"bRl", "496", "4K", "0Sq", "0bI", "2Wj", "6lD", "4Yg", "43C", "6Bh", "oW", "z6", "0AU", "bg", "6OX", "5jZ", "4TW", "4A6", "LK", "0oy", -"14Q", "CJ", "4N7", "5Kw", "41r", "542", "mf", "0NT", "u7", "22O", "6Mi", "4xJ", "4Vf", "6cE", "Nz", "0mH", "Px", "07B", "4Hd", "69O", -"6Sk", "4fH", "k5", "2hE", "7l", "0PV", "4kx", "5n8", "4P5", "4ET", "83j", "2KY", "RI", "05s", "4JU", "7oW", "5a9", "4dy", "1Ov", "8m", -"qU", "d4", "4iI", "7LK", "66N", "4Ge", "08C", "2Ih", "6NB", "a59", "1Pn", "21d", "MQ", "X0", "4UM", "74G", "79w", "bbN", "0cS", "0v2", -"nM", "8Dg", "42Y", "4c0", "4l1", "4yP", "8Kf", "aL", "0y3", "0lR", "636", "76v", "6oo", "4ZL", "W1", "BP", "2zm", "0ON", "40h", "6AC", -"4jb", "auS", "6v", "0QL", "I3", "2JC", "65e", "4DN", "b7E", "68U", "Qb", "06X", "286", "dSl", "4r3", "4gR", "4hS", "7MQ", "4G", "277", -"09Y", "0h0", "67T", "b8D", "4KO", "7nM", "SS", "F2", "1Nl", "9w", "azR", "4ec", "43G", "6Bl", "oS", "z2", "0bM", "2Wn", "78i", "4Yc", -"4TS", "4A2", "LO", "8fe", "0AQ", "bc", "aeN", "cPm", "41v", "546", "mb", "0NP", "14U", "CN", "4N3", "5Ks", "4Vb", "6cA", "2Xo", "0mL", -"u3", "22K", "6Mm", "4xN", "6So", "4fL", "k1", "2hA", "2Fm", "07F", "5XA", "69K", "4P1", "4EP", "83n", "d5f", "7h", "0PR", "bQO", "a0E", -"hbu", "50T", "1Or", "8i", "RM", "05w", "4JQ", "7oS", "66J", "4Ga", "08G", "2Il", "5Y", "d0", "4iM", "7LO", "MU", "X4", "4UI", "74C", -"6NF", "5kD", "1Pj", "cy", "nI", "2m9", "4vU", "4c4", "6mZ", "4Xy", "0cW", "0v6", "Od", "0lV", "4Wx", "5R8", "4l5", "4yT", "0Bz", "aH", -"lx", "0OJ", "40l", "6AG", "6ok", "4ZH", "W5", "BT", "I7", "2JG", "65a", "4DJ", "4jf", "7Od", "6r", "0QH", "1LY", "1Y8", "4r7", "4gV", -"4Iz", "68Q", "Qf", "0rT", "1mt", "0h4", "67P", "5VZ", "4hW", "7MU", "4C", "0Sy", "1Nh", "9s", "6PD", "4eg", "4KK", "7nI", "SW", "F6", -"8Je", "22V", "4m2", "4xS", "625", "77u", "Nc", "0mQ", "V2", "CS", "6nl", "5Kn", "41k", "7Pa", "3kO", "0NM", "0AL", "20g", "6OA", "4zb", -"4TN", "6am", "LR", "Y3", "0bP", "Ab", "78t", "bcM", "43Z", "4b3", "oN", "8Ed", "5D", "264", "4iP", "489", "66W", "b9G", "08Z", "0i3", -"RP", "G1", "4JL", "7oN", "6QC", "50I", "1Oo", "8t", "7u", "0PO", "4ka", "7Nc", "64f", "4EM", "H0", "963", "Pa", "0sS", "b6F", "69V", -"478", "4fQ", "295", "dRo", "4O4", "4ZU", "15R", "BI", "le", "0OW", "40q", "551", "6Lj", "4yI", "t4", "aU", "Oy", "0lK", "4We", "6bF", -"6mG", "4Xd", "0cJ", "2Vi", "nT", "0Mf", "4vH", "6Ck", "adI", "5kY", "1Pw", "cd", "MH", "0nz", "4UT", "7pV", "4KV", "7nT", "SJ", "04p", -"1Nu", "9n", "6PY", "4ez", "4hJ", "7MH", "pV", "e7", "1mi", "2Hk", "67M", "4Ff", "4Ig", "68L", "2Gj", "06A", "j6", "2iF", "6Rh", "4gK", -"5zZ", "7Oy", "6o", "0QU", "1oX", "1z9", "4Q6", "4DW", "5FZ", "6cX", "Ng", "0mU", "0Cy", "1F9", "4m6", "4xW", "41o", "7Pe", "3kK", "0NI", -"V6", "CW", "6nh", "5Kj", "4TJ", "6ai", "LV", "Y7", "0AH", "bz", "6OE", "4zf", "4wV", "4b7", "oJ", "0Lx", "0bT", "Af", "6lY", "4Yz", -"5B8", "4Gx", "1lw", "0i7", "qH", "0Rz", "4iT", "7LV", "6QG", "4dd", "1Ok", "8p", "RT", "G5", "4JH", "7oJ", "64b", "4EI", "H4", "2KD", -"7q", "0PK", "4ke", "7Ng", "4s4", "4fU", "1MZ", "2hX", "Pe", "0sW", "4Hy", "5M9", "la", "0OS", "40u", "555", "4O0", "4ZQ", "15V", "BM", -"2Yl", "0lO", "4Wa", "6bB", "6Ln", "4yM", "08", "aQ", "nP", "0Mb", "42D", "6Co", "6mC", "5HA", "0cN", "2Vm", "ML", "8gf", "4UP", "74Z", -"adM", "bAO", "1Ps", "0U3", "1Nq", "9j", "azO", "51W", "4KR", "7nP", "SN", "04t", "09D", "2Ho", "67I", "4Fb", "4hN", "7ML", "4Z", "e3", -"j2", "2iB", "6Rl", "4gO", "4Ic", "68H", "2Gn", "06E", "82m", "d4e", "4Q2", "4DS", "bPL", "a1F", "6k", "0QQ", "1pH", "2UJ", "6nd", "5Kf", -"41c", "7Pi", "mw", "0NE", "0Cu", "1F5", "6Mx", "5hz", "4Vw", "5S7", "Nk", "0mY", "0bX", "Aj", "6lU", "4Yv", "43R", "6By", "oF", "0Lt", -"0AD", "bv", "6OI", "4zj", "4TF", "6ae", "LZ", "0oh", "RX", "G9", "4JD", "7oF", "6QK", "4dh", "1Og", "2je", "5L", "0Rv", "4iX", "481", -"5B4", "4Gt", "08R", "2Iy", "Pi", "07S", "4Hu", "5M5", "470", "4fY", "1MV", "1X7", "su", "0PG", "4ki", "7Nk", "64n", "4EE", "H8", "2KH", -"6Lb", "4yA", "04", "23D", "Oq", "0lC", "4Wm", "6bN", "aEl", "c4G", "0as", "BA", "lm", "8FG", "40y", "559", "6NS", "5kQ", "345", "cl", -"1k2", "0nr", "boo", "74V", "6mO", "4Xl", "0cB", "2Va", "2xM", "0Mn", "42H", "6Cc", "4hB", "aws", "4V", "0Sl", "09H", "2Hc", "67E", "4Fn", -"b5e", "aTo", "SB", "04x", "8WD", "9f", "6PQ", "4er", "4js", "5o3", "6g", "8XE", "1oP", "1z1", "65t", "704", "4Io", "68D", "Qs", "06I", -"1LL", "2iN", "7BA", "4gC", "41g", "7Pm", "ms", "0NA", "14D", "2UN", "aDr", "5Kb", "4Vs", "5S3", "No", "19t", "0Cq", "1F1", "agn", "bBl", -"43V", "aho", "oB", "0Lp", "16u", "An", "6lQ", "4Yr", "4TB", "6aa", "2ZO", "0ol", "1Qa", "br", "6OM", "4zn", "6QO", "4dl", "1Oc", "8x", -"2DM", "05f", "5Za", "7oB", "5B0", "4Gp", "08V", "d7F", "5H", "0Rr", "bSo", "485", "474", "52t", "1MR", "1X3", "Pm", "07W", "4Hq", "5M1", -"64j", "4EA", "1nN", "2KL", "7y", "0PC", "4km", "7No", "Ou", "0lG", "4Wi", "6bJ", "6Lf", "4yE", "00", "aY", "li", "8FC", "4tu", "5q5", -"4O8", "4ZY", "0aw", "BE", "MD", "0nv", "4UX", "74R", "6NW", "5kU", "341", "ch", "nX", "0Mj", "42L", "6Cg", "6mK", "4Xh", "0cF", "2Ve", -"09L", "2Hg", "67A", "4Fj", "4hF", "7MD", "4R", "0Sh", "1Ny", "9b", "6PU", "4ev", "4KZ", "7nX", "SF", "0pt", "1oT", "1z5", "65p", "5Tz", -"4jw", "5o7", "6c", "0QY", "1LH", "2iJ", "6Rd", "4gG", "4Ik", "7li", "Qw", "06M", "7F", "246", "4kR", "7NP", "64U", "col", "1nq", "0k1", -"PR", "E3", "4HN", "69e", "6SA", "4fb", "1Mm", "2ho", "5w", "0RM", "4ic", "7La", "66d", "4GO", "J2", "2IB", "Rc", "05Y", "b4D", "aUN", -"4q2", "4dS", "8Ve", "8G", "8Hg", "bM", "4o0", "4zQ", "607", "75w", "La", "0oS", "T0", "AQ", "6ln", "4YM", "43i", "6BB", "2yl", "0LO", -"0CN", "22e", "6MC", "5hA", "4VL", "6co", "NP", "0mb", "1ps", "0u3", "aDM", "baO", "41X", "7PR", "mL", "8Gf", "4IT", "7lV", "QH", "06r", -"1Lw", "0I7", "5b8", "4gx", "4jH", "7OJ", "rT", "g5", "1ok", "2Ji", "65O", "4Dd", "4Ke", "7ng", "Sy", "04C", "h4", "2kD", "6Pj", "4eI", -"4hy", "5m9", "4m", "0SW", "09s", "2HX", "4S4", "4FU", "4M6", "4XW", "0cy", "1f9", "ng", "0MU", "42s", "573", "6Nh", "5kj", "v6", "cW", -"3KK", "0nI", "4Ug", "74m", "6oE", "4Zf", "0aH", "Bz", "lV", "y7", "40B", "6Ai", "582", "4yz", "0BT", "af", "OJ", "0lx", "4WV", "4B7", -"64Q", "4Ez", "1nu", "0k5", "7B", "0Px", "4kV", "7NT", "6SE", "4ff", "1Mi", "2hk", "PV", "E7", "4HJ", "69a", "6rh", "4GK", "J6", "2IF", -"5s", "0RI", "4ig", "7Le", "4q6", "4dW", "1OX", "8C", "Rg", "0qU", "5ZZ", "7oy", "4Ty", "5Q9", "Le", "0oW", "1QZ", "bI", "4o4", "4zU", -"43m", "6BF", "oy", "0LK", "T4", "AU", "6lj", "4YI", "4VH", "6ck", "NT", "0mf", "0CJ", "22a", "6MG", "4xd", "4uT", "7PV", "mH", "0Nz", -"1pw", "Cd", "aDI", "5KY", "1Ls", "0I3", "axM", "53U", "4IP", "7lR", "QL", "06v", "1oo", "2Jm", "65K", "5TA", "4jL", "7ON", "6X", "g1", -"h0", "9Y", "6Pn", "4eM", "4Ka", "7nc", "2El", "04G", "09w", "d6g", "4S0", "4FQ", "bRN", "a3D", "4i", "0SS", "nc", "0MQ", "42w", "577", -"4M2", "4XS", "17T", "dlm", "3KO", "0nM", "4Uc", "74i", "6Nl", "5kn", "v2", "cS", "lR", "y3", "40F", "6Am", "6oA", "4Zb", "0aL", "2To", -"ON", "18U", "4WR", "4B3", "586", "bCM", "0BP", "ab", "PZ", "0sh", "4HF", "69m", "6SI", "4fj", "1Me", "2hg", "7N", "0Pt", "4kZ", "7NX", -"6pU", "4Ev", "1ny", "0k9", "Rk", "05Q", "4Jw", "5O7", "452", "50r", "1OT", "8O", "qw", "0RE", "4ik", "7Li", "66l", "4GG", "08a", "2IJ", -"T8", "AY", "6lf", "4YE", "43a", "6BJ", "ou", "0LG", "0Aw", "bE", "4o8", "4zY", "4Tu", "5Q5", "Li", "8fC", "14s", "Ch", "6nW", "5KU", -"41P", "7PZ", "mD", "0Nv", "0CF", "22m", "6MK", "4xh", "4VD", "6cg", "NX", "0mj", "5za", "7OB", "6T", "0Qn", "1oc", "2Ja", "65G", "4Dl", -"b7g", "68w", "1w2", "06z", "8UF", "dSN", "5b0", "4gp", "4hq", "5m1", "4e", "8ZG", "1mR", "1x3", "67v", "726", "4Km", "7no", "Sq", "04K", -"1NN", "9U", "6Pb", "4eA", "adr", "5kb", "26", "21F", "Ms", "0nA", "4Uo", "74e", "79U", "bbl", "0cq", "1f1", "no", "396", "4vs", "5s3", -"6LQ", "4yr", "367", "an", "OB", "0lp", "bmm", "76T", "6oM", "4Zn", "15i", "Br", "2zO", "0Ol", "40J", "6Aa", "6SM", "4fn", "1Ma", "2hc", -"2FO", "07d", "4HB", "69i", "64Y", "4Er", "83L", "d5D", "7J", "0Pp", "bQm", "a0g", "456", "50v", "1OP", "8K", "Ro", "05U", "4Js", "5O3", -"66h", "4GC", "08e", "2IN", "qs", "0RA", "4io", "7Lm", "43e", "6BN", "oq", "0LC", "0bo", "2WL", "6lb", "4YA", "4Tq", "5Q1", "Lm", "8fG", -"0As", "bA", "ael", "cPO", "41T", "ajm", "1K2", "0Nr", "14w", "Cl", "6nS", "5KQ", "5Fa", "6cc", "2XM", "0mn", "0CB", "22i", "6MO", "4xl", -"1og", "2Je", "65C", "4Dh", "4jD", "7OF", "6P", "g9", "3l9", "2iy", "5b4", "4gt", "4IX", "68s", "QD", "0rv", "1mV", "1x7", "4S8", "4FY", -"4hu", "5m5", "4a", "1Cz", "h8", "9Q", "6Pf", "4eE", "4Ki", "7nk", "Su", "04O", "Mw", "0nE", "4Uk", "74a", "6Nd", "5kf", "22", "21B", -"nk", "0MY", "4vw", "5s7", "6mx", "5Hz", "0cu", "1f5", "OF", "0lt", "4WZ", "6by", "6LU", "4yv", "0BX", "aj", "lZ", "0Oh", "40N", "6Ae", -"6oI", "4Zj", "0aD", "Bv", "5f", "9Ke", "4ir", "5l2", "66u", "735", "08x", "1y0", "Rr", "05H", "4Jn", "7ol", "6Qa", "4dB", "1OM", "8V", -"7W", "0Pm", "4kC", "7NA", "64D", "4Eo", "83Q", "2Kb", "PC", "07y", "b6d", "69t", "5c3", "4fs", "8TE", "dRM", "374", "22t", "599", "4xq", -"bln", "77W", "NA", "0ms", "14j", "Cq", "6nN", "5KL", "41I", "7PC", "3km", "0No", "35", "20E", "6Oc", "5ja", "4Tl", "6aO", "Lp", "0oB", -"0br", "1g2", "78V", "bco", "43x", "568", "ol", "385", "4Kt", "5N4", "Sh", "04R", "1NW", "9L", "441", "4eX", "4hh", "7Mj", "pt", "0SF", -"K9", "2HI", "67o", "4FD", "4IE", "68n", "QY", "0", "1Lf", "2id", "6RJ", "4gi", "4jY", "auh", "6M", "0Qw", "1oz", "2Jx", "5A5", "4Du", -"6oT", "4Zw", "0aY", "Bk", "lG", "0Ou", "40S", "6Ax", "6LH", "4yk", "0BE", "aw", "2YJ", "0li", "4WG", "6bd", "6me", "4XF", "0ch", "2VK", -"nv", "0MD", "42b", "6CI", "6Ny", "7K9", "1PU", "cF", "Mj", "0nX", "4Uv", "5P6", "66q", "4GZ", "1lU", "1y4", "5b", "0RX", "4iv", "5l6", -"6Qe", "4dF", "1OI", "8R", "Rv", "05L", "4Jj", "7oh", "6pH", "4Ek", "1nd", "2Kf", "7S", "0Pi", "4kG", "7NE", "5c7", "4fw", "1Mx", "0H8", -"PG", "0su", "5Xz", "69p", "4VY", "4C8", "NE", "0mw", "1Sz", "22p", "6MV", "4xu", "41M", "7PG", "mY", "x8", "14n", "Cu", "6nJ", "5KH", -"4Th", "6aK", "Lt", "0oF", "31", "bX", "6Og", "4zD", "4wt", "5r4", "oh", "0LZ", "0bv", "AD", "4L9", "4YX", "1NS", "9H", "445", "51u", -"4Kp", "5N0", "Sl", "04V", "09f", "2HM", "67k", "5Va", "4hl", "7Mn", "4x", "0SB", "1Lb", "3yA", "6RN", "4gm", "4IA", "68j", "2GL", "4", -"82O", "d4G", "5A1", "4Dq", "bPn", "a1d", "6I", "0Qs", "lC", "0Oq", "40W", "akn", "6oP", "4Zs", "15t", "Bo", "2YN", "0lm", "4WC", "76I", -"6LL", "4yo", "0BA", "as", "nr", "8DX", "42f", "6CM", "6ma", "4XB", "0cl", "2VO", "Mn", "8gD", "4Ur", "5P2", "ado", "bAm", "1PQ", "cB", -"Rz", "0qH", "4Jf", "7od", "6Qi", "4dJ", "i7", "2jG", "5n", "0RT", "4iz", "7Lx", "4R7", "4GV", "08p", "1y8", "PK", "07q", "4HW", "7mU", -"6SX", "52R", "1Mt", "0H4", "sW", "f6", "4kK", "7NI", "64L", "4Eg", "1nh", "2Kj", "14b", "Cy", "6nF", "5KD", "41A", "7PK", "mU", "x4", -"0CW", "0V6", "591", "4xy", "4VU", "4C4", "NI", "19R", "0bz", "AH", "4L5", "4YT", "43p", "560", "od", "0LV", "w5", "bT", "6Ok", "4zH", -"4Td", "6aG", "Lx", "0oJ", "5xA", "7Mb", "4t", "0SN", "K1", "2HA", "67g", "4FL", "b5G", "aTM", "0e3", "04Z", "8Wf", "9D", "449", "4eP", -"4jQ", "7OS", "6E", "255", "1or", "0j2", "65V", "cno", "4IM", "68f", "QQ", "8", "1Ln", "2il", "6RB", "4ga", "afR", "4yc", "0BM", "23f", -"OS", "Z2", "4WO", "6bl", "aEN", "c4e", "0aQ", "Bc", "lO", "8Fe", "4tS", "4a2", "4n3", "5ks", "8Id", "cN", "Mb", "0nP", "614", "74t", -"6mm", "4XN", "U3", "2VC", "2xo", "0ML", "42j", "6CA", "6Qm", "4dN", "i3", "8Z", "2Do", "05D", "4Jb", "aUS", "4R3", "4GR", "08t", "d7d", -"5j", "0RP", "bSM", "a2G", "ayN", "52V", "1Mp", "0H0", "PO", "07u", "4HS", "69x", "64H", "4Ec", "1nl", "2Kn", "sS", "f2", "4kO", "7NM", -"41E", "7PO", "mQ", "x0", "14f", "2Ul", "6nB", "aQ1", "4VQ", "4C0", "NM", "19V", "0CS", "0V2", "595", "bBN", "43t", "564", "0Y3", "0LR", -"16W", "AL", "4L1", "4YP", "5DA", "6aC", "2Zm", "0oN", "39", "bP", "6Oo", "4zL", "K5", "2HE", "67c", "4FH", "4hd", "7Mf", "4p", "0SJ", -"8Wb", "2kY", "4p5", "4eT", "4Kx", "5N8", "Sd", "0pV", "1ov", "0j6", "5A9", "4Dy", "4jU", "7OW", "6A", "1AZ", "1Lj", "2ih", "6RF", "4ge", -"4II", "68b", "QU", "D4", "OW", "Z6", "4WK", "6bh", "6LD", "4yg", "0BI", "23b", "lK", "0Oy", "4tW", "4a6", "6oX", "5JZ", "0aU", "Bg", -"Mf", "0nT", "4Uz", "74p", "4n7", "5kw", "1PY", "cJ", "nz", "0MH", "42n", "6CE", "6mi", "4XJ", "U7", "2VG", "4MP", "4X1", "UL", "02v", -"0XR", "0M3", "a8E", "57U", "4nL", "7KN", "2X", "c1", "1ko", "2Nm", "61K", "5PA", "4Oa", "6zB", "2Al", "00G", "l0", "yQ", "6Tn", "4aM", -"58T", "a7D", "0i", "0WS", "84o", "ZM", "4W0", "4BQ", "4I2", "5Lr", "13T", "G", "jc", "0IQ", "46w", "537", "6Jl", "5on", "r2", "gS", -"3OO", "0jM", "4Qc", "70i", "6kA", "5NC", "0eL", "2Po", "hR", "8Bx", "44F", "6Em", "abO", "49v", "0FP", "eb", "KN", "8ad", "4SR", "4F3", -"3B", "0Tx", "4oV", "4z7", "60Q", "4Az", "0zT", "Yf", "TV", "A7", "4LJ", "6yi", "6WE", "4bf", "0YH", "zz", "1s", "0VI", "4mg", "6XD", -"6vh", "4CK", "N6", "2MF", "Vg", "0uU", "6n9", "7ky", "4u6", "5pv", "1KX", "xK", "1UZ", "fI", "4k4", "5nt", "4Py", "5U9", "He", "0kW", -"P4", "EU", "6hj", "5Mh", "47m", "6FF", "ky", "0HK", "0GJ", "dx", "6IG", "48l", "4RH", "6gk", "JT", "0if", "0dV", "Gd", "5Z8", "5OY", -"4qT", "4d5", "iH", "0Jz", "0XV", "0M7", "5f8", "4cx", "4MT", "4X5", "UH", "02r", "1kk", "Xx", "61O", "5PE", "4nH", "7KJ", "vT", "c5", -"l4", "yU", "6Tj", "4aI", "4Oe", "6zF", "Wy", "00C", "1iZ", "ZI", "4W4", "4BU", "4ly", "5i9", "0m", "0WW", "jg", "0IU", "46s", "533", -"4I6", "5Lv", "0gy", "C", "3OK", "0jI", "4Qg", "6dD", "6Jh", "5oj", "r6", "gW", "hV", "0Kd", "44B", "6Ei", "6kE", "5NG", "0eH", "Fz", -"KJ", "0hx", "4SV", "4F7", "6HY", "49r", "0FT", "ef", "60U", "ckl", "0zP", "Yb", "3F", "206", "4oR", "4z3", "6WA", "4bb", "0YL", "2lo", -"TR", "A3", "4LN", "6ym", "62d", "4CO", "N2", "2MB", "1w", "0VM", "4mc", "7Ha", "4u2", "54z", "8Re", "xO", "Vc", "01Y", "b0D", "aQN", -"647", "71w", "Ha", "0kS", "8Lg", "fM", "4k0", "5np", "47i", "6FB", "29d", "0HO", "P0", "EQ", "6hn", "5Ml", "4RL", "6go", "JP", "0ib", -"0GN", "26e", "6IC", "48h", "45X", "4d1", "iL", "8Cf", "0dR", "0q3", "hYt", "beO", "4nD", "7KF", "2P", "c9", "1kg", "Xt", "61C", "5PI", -"4MX", "4X9", "UD", "0vv", "0XZ", "2my", "5f4", "4ct", "4lu", "5i5", "0a", "1Gz", "0yw", "ZE", "4W8", "4BY", "4Oi", "6zJ", "Wu", "00O", -"l8", "yY", "6Tf", "4aE", "6Jd", "5of", "62", "25B", "Iw", "0jE", "4Qk", "6dH", "6ix", "5Lz", "0gu", "O", "jk", "0IY", "4rw", "5w7", -"5x6", "5mW", "0FX", "ej", "KF", "0ht", "4SZ", "6fy", "6kI", "5NK", "0eD", "Fv", "hZ", "93", "44N", "6Ee", "2BO", "03d", "4LB", "6ya", -"6WM", "4bn", "1Ia", "zr", "3J", "0Tp", "bUm", "a4g", "5D2", "4Ar", "87L", "Yn", "Vo", "01U", "4Ns", "5K3", "416", "54v", "1KP", "xC", -"us", "0VA", "4mo", "6XL", "62h", "4CC", "0xm", "2MN", "0fo", "2SL", "6hb", "bgr", "47e", "6FN", "kq", "0HC", "0Es", "fA", "aal", "bDn", -"4Pq", "5U1", "Hm", "8bG", "10w", "Gl", "5Z0", "5OQ", "45T", "anm", "1O2", "0Jr", "0GB", "dp", "6IO", "48d", "5Ba", "6gc", "3Ll", "0in", -"1kc", "Xp", "61G", "5PM", "bTs", "7KB", "2T", "0Un", "8QF", "39T", "5f0", "4cp", "797", "aRm", "1s2", "02z", "0ys", "ZA", "63v", "766", -"4lq", "5i1", "0e", "9Nf", "0Zo", "2oL", "6Tb", "4aA", "4Om", "6zN", "Wq", "00K", "Is", "0jA", "4Qo", "6dL", "7ZA", "5ob", "66", "25F", -"jo", "9Pd", "4rs", "5w3", "aCn", "bfl", "0gq", "K", "KB", "0hp", "bim", "72T", "5x2", "49z", "327", "en", "3nn", "97", "44J", "6Ea", -"6kM", "5NO", "11i", "Fr", "6WI", "4bj", "0YD", "zv", "TZ", "0wh", "4LF", "6ye", "5D6", "4Av", "0zX", "Yj", "3N", "0Tt", "4oZ", "6Zy", -"412", "54r", "1KT", "xG", "Vk", "01Q", "4Nw", "5K7", "62l", "4CG", "0xi", "2MJ", "uw", "0VE", "4mk", "6XH", "47a", "6FJ", "ku", "0HG", -"P8", "EY", "6hf", "5Md", "4Pu", "5U5", "Hi", "8bC", "0Ew", "fE", "4k8", "5nx", "45P", "4d9", "iD", "0Jv", "0dZ", "Gh", "5Z4", "5OU", -"4RD", "6gg", "JX", "0ij", "0GF", "dt", "6IK", "5lI", "4Op", "5J0", "Wl", "00V", "0Zr", "2oQ", "405", "55u", "4ll", "6YO", "0x", "0WB", -"0yn", "2LM", "63k", "5Ra", "4MA", "6xb", "2CL", "02g", "0XC", "39I", "6VN", "4cm", "bTn", "a5d", "2I", "0Us", "86O", "Xm", "5E1", "5PP", -"6kP", "5NR", "11t", "Fo", "hC", "0Kq", "44W", "aon", "6HL", "49g", "0FA", "es", "3Mo", "0hm", "4SC", "72I", "6ia", "5Lc", "0gl", "V", -"jr", "1Ya", "46f", "6GM", "hyV", "bEm", "0Dp", "gB", "In", "8cD", "4Qr", "5T2", "1b", "0VX", "4mv", "5h6", "62q", "4CZ", "0xt", "2MW", -"Vv", "01L", "4Nj", "7kh", "6Ue", "54o", "1KI", "xZ", "3S", "0Ti", "4oG", "6Zd", "6tH", "4Ak", "0zE", "Yw", "TG", "0wu", "780", "6yx", -"5g7", "4bw", "0YY", "zk", "1Wz", "di", "5y5", "5lT", "4RY", "4G8", "JE", "0iw", "0dG", "Gu", "6jJ", "5OH", "45M", "6Df", "iY", "80", -"71", "fX", "6Kg", "5ne", "4Ph", "6eK", "Ht", "0kF", "0fv", "ED", "4H9", "5My", "4st", "5v4", "kh", "0HZ", "0Zv", "yD", "401", "4aX", -"4Ot", "5J4", "Wh", "00R", "O9", "ZX", "63o", "4BD", "4lh", "6YK", "tt", "0WF", "0XG", "2md", "6VJ", "4ci", "4ME", "6xf", "UY", "02c", -"1kz", "Xi", "5E5", "5PT", "4nY", "aqh", "2M", "0Uw", "hG", "0Ku", "44S", "6Ex", "6kT", "5NV", "0eY", "Fk", "3Mk", "0hi", "4SG", "6fd", -"6HH", "49c", "0FE", "ew", "jv", "0ID", "46b", "6GI", "6ie", "5Lg", "0gh", "R", "Ij", "0jX", "4Qv", "5T6", "6Jy", "7O9", "0Dt", "gF", -"62u", "775", "0xp", "198", "1f", "9Oe", "4mr", "5h2", "6Ua", "54k", "1KM", "2nO", "Vr", "01H", "4Nn", "7kl", "60D", "4Ao", "0zA", "Ys", -"3W", "0Tm", "4oC", "7JA", "5g3", "4bs", "8PE", "zo", "TC", "03y", "784", "aSn", "bhn", "73W", "JA", "0is", "334", "dm", "5y1", "48y", -"45I", "6Db", "3om", "84", "0dC", "Gq", "6jN", "5OL", "4Pl", "6eO", "Hp", "0kB", "75", "24E", "6Kc", "5na", "47x", "528", "kl", "8AF", -"0fr", "1c2", "aBm", "bgo", "4ld", "6YG", "0p", "0WJ", "O5", "ZT", "63c", "4BH", "4Ox", "5J8", "Wd", "0tV", "0Zz", "yH", "4t5", "4aT", -"4nU", "7KW", "2A", "1EZ", "1kv", "Xe", "5E9", "5PX", "4MI", "6xj", "UU", "02o", "0XK", "2mh", "6VF", "4ce", "6HD", "49o", "0FI", "27b", -"KW", "0he", "4SK", "6fh", "6kX", "5NZ", "0eU", "Fg", "hK", "0Ky", "4pW", "4e6", "4j7", "5ow", "0Dx", "gJ", "If", "0jT", "4Qz", "6dY", -"6ii", "5Lk", "Q7", "DV", "jz", "0IH", "46n", "6GE", "3PN", "01D", "4Nb", "aQS", "6Um", "54g", "m3", "xR", "1j", "0VP", "59W", "a6G", -"4V3", "4CR", "85l", "194", "TO", "03u", "4LS", "4Y2", "a9F", "56V", "0YQ", "zc", "wS", "b2", "4oO", "6Zl", "60H", "4Ac", "0zM", "2On", -"0dO", "2Ql", "6jB", "aU1", "45E", "6Dn", "iQ", "88", "0GS", "da", "acL", "48u", "4RQ", "4G0", "JM", "94N", "12W", "EL", "4H1", "5Mq", -"47t", "524", "29y", "0HR", "79", "fP", "6Ko", "5nm", "aZ0", "6eC", "3NL", "0kN", "O1", "ZP", "63g", "4BL", "58I", "6YC", "0t", "0WN", -"8Sf", "yL", "409", "4aP", "b1G", "aPM", "0a3", "00Z", "1kr", "Xa", "61V", "bzN", "4nQ", "7KS", "2E", "215", "0XO", "2ml", "6VB", "4ca", -"4MM", "6xn", "UQ", "02k", "KS", "0ha", "4SO", "6fl", "7Xa", "49k", "0FM", "27f", "hO", "8Be", "4pS", "4e2", "aAN", "bdL", "0eQ", "Fc", -"Ib", "0jP", "654", "70t", "4j3", "5os", "8Md", "gN", "28g", "0IL", "46j", "6GA", "6im", "5Lo", "Q3", "Z", "6Ui", "54c", "m7", "xV", -"Vz", "0uH", "4Nf", "7kd", "4V7", "4CV", "0xx", "190", "1n", "0VT", "4mz", "6XY", "6WX", "56R", "0YU", "zg", "TK", "03q", "4LW", "4Y6", -"60L", "4Ag", "0zI", "2Oj", "wW", "b6", "4oK", "6Zh", "45A", "6Dj", "iU", "0Jg", "0dK", "Gy", "6jF", "5OD", "4RU", "4G4", "JI", "1yZ", -"0GW", "de", "5y9", "48q", "47p", "520", "kd", "0HV", "0fz", "EH", "4H5", "5Mu", "4Pd", "6eG", "Hx", "0kJ", "s5", "fT", "6Kk", "5ni", -"5Y1", "5LP", "13v", "e", "jA", "0Is", "46U", "aml", "6JN", "5oL", "0DC", "gq", "3Om", "0jo", "4QA", "6db", "6kc", "5Na", "0en", "2PM", -"hp", "0KB", "44d", "6EO", "abm", "49T", "0Fr", "1C2", "Kl", "8aF", "4Sp", "5V0", "4Mr", "5H2", "Un", "02T", "0Xp", "2mS", "427", "57w", -"4nn", "7Kl", "2z", "1Ea", "1kM", "2NO", "61i", "5Pc", "4OC", "7jA", "2AN", "00e", "0ZA", "ys", "6TL", "4ao", "58v", "a7f", "0K", "0Wq", -"84M", "Zo", "5G3", "4Bs", "0EY", "fk", "6KT", "5nV", "bjh", "6ex", "HG", "0ku", "0fE", "Ew", "6hH", "5MJ", "47O", "6Fd", "29B", "0Hi", -"53", "dZ", "6Ie", "48N", "4Rj", "6gI", "Jv", "0iD", "0dt", "GF", "6jy", "7o9", "4qv", "5t6", "ij", "0JX", "wh", "0TZ", "4ot", "5j4", -"4T9", "4AX", "0zv", "YD", "Tt", "03N", "4Lh", "6yK", "6Wg", "4bD", "o9", "zX", "1Q", "0Vk", "4mE", "6Xf", "62B", "4Ci", "0xG", "2Md", -"VE", "0uw", "4NY", "aQh", "5e5", "5pT", "1Kz", "xi", "jE", "0Iw", "46Q", "4g8", "5Y5", "5LT", "13r", "a", "IY", "0jk", "4QE", "6df", -"6JJ", "5oH", "0DG", "gu", "ht", "0KF", "4ph", "6EK", "6kg", "5Ne", "S9", "FX", "Kh", "0hZ", "4St", "5V4", "4h9", "49P", "0Fv", "eD", -"0Xt", "2mW", "423", "4cZ", "4Mv", "5H6", "Uj", "02P", "1kI", "XZ", "61m", "5Pg", "4nj", "7Kh", "vv", "0UD", "0ZE", "yw", "6TH", "4ak", -"4OG", "6zd", "2AJ", "00a", "0yY", "Zk", "5G7", "4Bw", "58r", "6Yx", "0O", "0Wu", "bjl", "71U", "HC", "0kq", "316", "fo", "6KP", "5nR", -"47K", "7VA", "29F", "0Hm", "0fA", "Es", "6hL", "5MN", "4Rn", "6gM", "Jr", "1ya", "57", "26G", "6Ia", "48J", "45z", "5t2", "in", "8CD", -"0dp", "GB", "hYV", "bem", "60w", "757", "0zr", "2OQ", "3d", "9Mg", "4op", "5j0", "6Wc", "56i", "0Yn", "2lM", "Tp", "03J", "4Ll", "6yO", -"62F", "4Cm", "0xC", "dwS", "1U", "0Vo", "4mA", "6Xb", "5e1", "54X", "8RG", "xm", "VA", "0us", "b0f", "aQl", "6JF", "5oD", "0DK", "gy", -"IU", "0jg", "4QI", "6dj", "5Y9", "5LX", "0gW", "m", "jI", "1YZ", "4rU", "4g4", "4h5", "5mu", "0Fz", "eH", "Kd", "0hV", "4Sx", "5V8", -"6kk", "5Ni", "S5", "FT", "hx", "0KJ", "44l", "6EG", "4nf", "7Kd", "2r", "0UH", "M7", "XV", "61a", "5Pk", "4Mz", "6xY", "Uf", "0vT", -"0Xx", "39r", "4v7", "4cV", "4lW", "4y6", "0C", "0Wy", "0yU", "Zg", "63P", "5RZ", "4OK", "6zh", "WW", "B6", "0ZI", "2oj", "6TD", "4ag", -"0fM", "2Sn", "7xa", "5MB", "47G", "6Fl", "kS", "0Ha", "0EQ", "fc", "aaN", "bDL", "4PS", "4E2", "HO", "8be", "10U", "GN", "4J3", "5Os", -"45v", "506", "ib", "0JP", "q3", "dR", "6Im", "48F", "4Rb", "6gA", "3LN", "0iL", "2Bm", "03F", "aF0", "6yC", "6Wo", "4bL", "o1", "zP", -"3h", "0TR", "bUO", "a4E", "4T1", "4AP", "87n", "YL", "VM", "01w", "4NQ", "7kS", "hfu", "54T", "1Kr", "xa", "1Y", "0Vc", "4mM", "6Xn", -"62J", "4Ca", "0xO", "2Ml", "IQ", "0jc", "4QM", "6dn", "6JB", "a19", "0DO", "25d", "jM", "9PF", "46Y", "4g0", "aCL", "687", "0gS", "i", -"3MP", "0hR", "676", "72v", "4h1", "49X", "8Of", "eL", "3nL", "0KN", "44h", "6EC", "6ko", "5Nm", "S1", "FP", "M3", "XR", "61e", "5Po", -"4nb", "aqS", "2v", "0UL", "8Qd", "39v", "4v3", "4cR", "b3E", "aRO", "Ub", "02X", "0yQ", "Zc", "63T", "bxL", "4lS", "4y2", "0G", "237", -"0ZM", "2on", "7Da", "4ac", "4OO", "6zl", "WS", "B2", "47C", "6Fh", "kW", "0He", "0fI", "2Sj", "6hD", "5MF", "4PW", "4E6", "HK", "0ky", -"0EU", "fg", "6KX", "5nZ", "45r", "502", "if", "0JT", "0dx", "GJ", "4J7", "5Ow", "4Rf", "6gE", "Jz", "0iH", "q7", "dV", "6Ii", "48B", -"6Wk", "4bH", "o5", "zT", "Tx", "03B", "4Ld", "6yG", "4T5", "4AT", "0zz", "YH", "3l", "0TV", "4ox", "5j8", "5e9", "54P", "1Kv", "xe", -"VI", "01s", "4NU", "7kW", "62N", "4Ce", "0xK", "2Mh", "uU", "0Vg", "4mI", "6Xj", "4K0", "5Np", "11V", "FM", "ha", "0KS", "44u", "515", -"6Hn", "49E", "48", "eQ", "3MM", "0hO", "4Sa", "6fB", "6iC", "5LA", "0gN", "t", "jP", "0Ib", "46D", "6Go", "hyt", "bEO", "0DR", "0Q3", -"IL", "8cf", "4QP", "4D1", "4OR", "4Z3", "WN", "00t", "0ZP", "yb", "hgv", "55W", "4lN", "6Ym", "0Z", "a3", "0yL", "2Lo", "63I", "4Bb", -"4Mc", "7ha", "2Cn", "02E", "n2", "2mB", "6Vl", "4cO", "bTL", "a5F", "2k", "0UQ", "86m", "XO", "4U2", "5Pr", "0Gy", "dK", "4i6", "5lv", -"5BZ", "6gX", "Jg", "0iU", "R6", "GW", "6jh", "5Oj", "45o", "6DD", "3oK", "0JI", "0EH", "fz", "6KE", "5nG", "4PJ", "6ei", "HV", "0kd", -"0fT", "Ef", "6hY", "690", "4sV", "4f7", "kJ", "0Hx", "uH", "0Vz", "4mT", "4x5", "5F8", "4Cx", "0xV", "0m7", "VT", "C5", "4NH", "7kJ", -"6UG", "54M", "1Kk", "xx", "3q", "0TK", "4oe", "6ZF", "60b", "4AI", "L4", "YU", "Te", "0wW", "4Ly", "5I9", "4w4", "4bU", "1IZ", "zI", -"he", "0KW", "44q", "511", "4K4", "5Nt", "11R", "FI", "Ky", "0hK", "4Se", "6fF", "6Hj", "49A", "p4", "eU", "jT", "0If", "4rH", "6Gk", -"6iG", "5LE", "0gJ", "p", "IH", "0jz", "4QT", "4D5", "5z8", "5oY", "0DV", "gd", "0ZT", "yf", "6TY", "4az", "4OV", "4Z7", "WJ", "00p", -"0yH", "Zz", "63M", "4Bf", "4lJ", "6Yi", "tV", "a7", "n6", "2mF", "6Vh", "4cK", "4Mg", "6xD", "2Cj", "02A", "1kX", "XK", "4U6", "5Pv", -"6N9", "7Ky", "2o", "0UU", "665", "73u", "Jc", "0iQ", "8Ne", "dO", "4i2", "5lr", "45k", "7Ta", "3oO", "0JM", "R2", "GS", "6jl", "5On", -"4PN", "6em", "HR", "8bx", "0EL", "24g", "6KA", "5nC", "47Z", "4f3", "kN", "8Ad", "0fP", "Eb", "aBO", "694", "62W", "byO", "0xR", "0m3", -"1D", "224", "4mP", "4x1", "6UC", "54I", "1Ko", "2nm", "VP", "C1", "4NL", "7kN", "60f", "4AM", "L0", "YQ", "3u", "0TO", "4oa", "6ZB", -"438", "4bQ", "8Pg", "zM", "Ta", "0wS", "b2F", "aSL", "6Hf", "49M", "40", "eY", "Ku", "0hG", "4Si", "6fJ", "4K8", "5Nx", "0ew", "FE", -"hi", "8BC", "4pu", "5u5", "5z4", "5oU", "0DZ", "gh", "ID", "0jv", "4QX", "4D9", "6iK", "5LI", "0gF", "Dt", "jX", "0Ij", "46L", "6Gg", -"4lF", "6Ye", "0R", "0Wh", "0yD", "Zv", "63A", "4Bj", "4OZ", "6zy", "WF", "0tt", "0ZX", "yj", "5d6", "4av", "4nw", "5k7", "2c", "0UY", -"1kT", "XG", "61p", "5Pz", "4Mk", "6xH", "Uw", "02M", "0Xi", "2mJ", "6Vd", "4cG", "0dm", "2QN", "7zA", "5Ob", "45g", "6DL", "is", "0JA", -"0Gq", "dC", "acn", "48W", "4Rs", "5W3", "Jo", "94l", "12u", "En", "5X2", "5MS", "47V", "alo", "kB", "0Hp", "1Ua", "fr", "6KM", "5nO", -"4PB", "6ea", "3Nn", "0kl", "3Pl", "01f", "bts", "7kB", "6UO", "54E", "1Kc", "xp", "1H", "0Vr", "59u", "a6e", "5F0", "4Cp", "85N", "d3F", -"Tm", "03W", "4Lq", "5I1", "434", "56t", "0Ys", "zA", "3y", "0TC", "4om", "6ZN", "60j", "4AA", "0zo", "2OL", "Kq", "0hC", "4Sm", "6fN", -"6Hb", "49I", "44", "27D", "hm", "8BG", "44y", "519", "aAl", "bdn", "0es", "FA", "1o2", "0jr", "bko", "70V", "5z0", "5oQ", "305", "gl", -"28E", "0In", "46H", "6Gc", "6iO", "5LM", "0gB", "x", "1ia", "Zr", "63E", "4Bn", "4lB", "6Ya", "0V", "0Wl", "8SD", "yn", "5d2", "4ar", -"b1e", "aPo", "WB", "00x", "1kP", "XC", "61t", "744", "4ns", "5k3", "2g", "9Ld", "0Xm", "2mN", "7FA", "4cC", "4Mo", "6xL", "Us", "02I", -"45c", "6DH", "iw", "0JE", "0di", "2QJ", "6jd", "5Of", "4Rw", "5W7", "Jk", "0iY", "0Gu", "dG", "6Ix", "48S", "47R", "6Fy", "kF", "0Ht", -"0fX", "Ej", "5X6", "5MW", "4PF", "6ee", "HZ", "0kh", "0ED", "fv", "6KI", "5nK", "6UK", "54A", "1Kg", "xt", "VX", "C9", "4ND", "7kF", -"5F4", "4Ct", "0xZ", "2My", "1L", "0Vv", "4mX", "4x9", "430", "4bY", "0Yw", "zE", "Ti", "03S", "4Lu", "5I5", "60n", "4AE", "L8", "YY", -"wu", "0TG", "4oi", "6ZJ" }; + "06S", "Qi", "5L5", "4Iu", "4gY", "460", "1Y7", "1LV", "0QG", "ru", "7Ok", "4ji", "4DE", "65n", "2JH", "I8", + "F9", "SX", "7nF", "4KD", "4eh", "6PK", "2ke", "1Ng", "0Sv", "4L", "491", "4hX", "4Ft", "5C4", "2Hy", "09R", + "021", "0cX", "4Xv", "6mU", "6Cy", "42R", "0Mt", "nF", "cv", "1Pe", "5kK", "6NI", "74L", "4UF", "0nh", "MZ", + "2TJ", "0ai", "4ZG", "6od", "6AH", "40c", "0OE", "lw", "aG", "0Bu", "5iz", "6Lx", "5R7", "4Ww", "0lY", "Ok", + "5n3", "4ks", "8YE", "7g", "2KR", "1nP", "714", "64t", "69D", "4Ho", "07I", "Ps", "2hN", "1ML", "4fC", "7CA", + "avs", "4iB", "0Rl", "5V", "2Ic", "08H", "4Gn", "66E", "aUo", "b4e", "05x", "RB", "8f", "8VD", "4dr", "5a2", + "4zp", "6OS", "bl", "355", "0or", "1j2", "75V", "bno", "4Yl", "6lO", "Ap", "0bB", "0Ln", "2yM", "6Bc", "43H", + "4xA", "6Mb", "22D", "14", "0mC", "Nq", "6cN", "4Vm", "ban", "aDl", "CA", "14Z", "8GG", "mm", "549", "41y", + "53t", "464", "1Y3", "1LR", "06W", "Qm", "5L1", "4Iq", "4DA", "65j", "2JL", "1oN", "0QC", "6y", "7Oo", "4jm", + "4el", "6PO", "9x", "1Nc", "04f", "2EM", "7nB", "bqs", "4Fp", "5C0", "d6F", "09V", "0Sr", "4H", "495", "bRo", + "aio", "42V", "0Mp", "nB", "025", "17u", "4Xr", "6mQ", "74H", "4UB", "0nl", "3Kn", "cr", "1Pa", "5kO", "6NM", + "6AL", "40g", "0OA", "ls", "2TN", "0am", "4ZC", "aEr", "5R3", "4Ws", "18t", "Oo", "aC", "0Bq", "bCl", "afn", + "2KV", "1nT", "5Uz", "64p", "5n7", "4kw", "0PY", "7c", "2hJ", "1MH", "4fG", "6Sd", "7mi", "4Hk", "07M", "Pw", + "2Ig", "08L", "4Gj", "66A", "7LD", "4iF", "0Rh", "5R", "8b", "1Oy", "4dv", "5a6", "7oX", "4JZ", "0qt", "RF", + "0ov", "LD", "4A9", "4TX", "4zt", "6OW", "bh", "0AZ", "z9", "oX", "6Bg", "43L", "4Yh", "6lK", "At", "0bF", + "0mG", "Nu", "6cJ", "4Vi", "4xE", "6Mf", "2vH", "10", "8GC", "mi", "5p5", "4uu", "5Kx", "4N8", "CE", "1pV", + "0QO", "6u", "7Oc", "4ja", "4DM", "65f", "3Za", "I0", "0rS", "Qa", "68V", "b7F", "4gQ", "468", "dSo", "285", + "274", "4D", "499", "4hP", "b8G", "67W", "0h3", "09Z", "F1", "SP", "7nN", "4KL", "51I", "6PC", "9t", "1No", + "21g", "1Pm", "5kC", "6NA", "74D", "4UN", "X3", "MR", "029", "0cP", "bbM", "79t", "4c3", "42Z", "8Dd", "nN", + "aO", "8Ke", "4yS", "4l2", "76u", "635", "0lQ", "Oc", "BS", "W2", "4ZO", "6ol", "7Qa", "40k", "0OM", "2zn", + "69L", "4Hg", "07A", "2Fj", "2hF", "k6", "4fK", "6Sh", "7Ny", "6K9", "0PU", "7o", "2KZ", "1nX", "4EW", "4P6", + "7oT", "4JV", "05p", "RJ", "8n", "1Ou", "4dz", "6QY", "7LH", "4iJ", "d7", "qV", "2Ik", "1li", "4Gf", "66M", + "4Yd", "6lG", "Ax", "0bJ", "z5", "oT", "6Bk", "4wH", "4zx", "aeI", "bd", "0AV", "0oz", "LH", "4A5", "4TT", + "5Kt", "4N4", "CI", "14R", "0NW", "me", "541", "41q", "4xI", "6Mj", "22L", "u4", "0mK", "Ny", "6cF", "4Ve", + "4DI", "65b", "2JD", "I4", "0QK", "6q", "7Og", "4je", "4gU", "4r4", "2iX", "1LZ", "0rW", "Qe", "5L9", "4Iy", + "4Fx", "5C8", "0h7", "1mw", "0Sz", "pH", "7MV", "4hT", "4ed", "6PG", "9p", "1Nk", "F5", "ST", "7nJ", "4KH", + "7pH", "4UJ", "X7", "MV", "cz", "1Pi", "5kG", "6NE", "4c7", "4vV", "0Mx", "nJ", "0v5", "0cT", "4Xz", "6mY", + "6bX", "5GZ", "0lU", "Og", "aK", "0By", "4yW", "4l6", "6AD", "40o", "0OI", "2zj", "BW", "W6", "4ZK", "6oh", + "2hB", "k2", "4fO", "6Sl", "69H", "4Hc", "07E", "2Fn", "d5e", "83m", "4ES", "4P2", "a0F", "bQL", "0PQ", "7k", + "8j", "1Oq", "50W", "hbv", "7oP", "4JR", "05t", "RN", "2Io", "08D", "4Gb", "66I", "7LL", "4iN", "d3", "5Z", + "z1", "oP", "6Bo", "43D", "5IA", "6lC", "2Wm", "0bN", "8ff", "LL", "4A1", "4TP", "cPn", "aeM", "0T3", "0AR", + "0NS", "ma", "545", "41u", "5Kp", "4N0", "CM", "14V", "0mO", "2Xl", "6cB", "4Va", "4xM", "6Mn", "22H", "18", + "04s", "SI", "7nW", "4KU", "4ey", "6PZ", "9m", "1Nv", "e4", "pU", "7MK", "4hI", "4Fe", "67N", "2Hh", "09C", + "06B", "Qx", "68O", "4Id", "4gH", "6Rk", "2iE", "j5", "0QV", "6l", "5o8", "4jx", "4DT", "4Q5", "2JY", "82j", + "BJ", "0ax", "4ZV", "4O7", "552", "40r", "0OT", "lf", "aV", "t7", "4yJ", "6Li", "6bE", "4Wf", "0lH", "Oz", + "2Vj", "0cI", "4Xg", "6mD", "6Ch", "42C", "0Me", "nW", "cg", "1Pt", "5kZ", "6NX", "7pU", "4UW", "0ny", "MK", + "7LQ", "4iS", "267", "5G", "0i0", "08Y", "b9D", "66T", "7oM", "4JO", "G2", "RS", "8w", "1Ol", "4dc", "7Aa", + "atS", "4kb", "0PL", "7v", "2KC", "H3", "4EN", "64e", "69U", "b6E", "07X", "Pb", "dRl", "296", "4fR", "4s3", + "4xP", "4m1", "22U", "8Jf", "0mR", "0x3", "77v", "626", "5Km", "6no", "CP", "V1", "0NN", "3kL", "7Pb", "41h", + "4za", "6OB", "20d", "0AO", "Y0", "LQ", "6an", "4TM", "bcN", "78w", "Aa", "0bS", "8Eg", "oM", "4b0", "43Y", + "51T", "azL", "9i", "1Nr", "04w", "SM", "7nS", "4KQ", "4Fa", "67J", "2Hl", "09G", "e0", "4Y", "7MO", "4hM", + "4gL", "6Ro", "2iA", "j1", "06F", "2Gm", "68K", "5YA", "4DP", "4Q1", "d4f", "82n", "0QR", "6h", "a1E", "bPO", + "556", "40v", "0OP", "lb", "BN", "15U", "4ZR", "4O3", "6bA", "4Wb", "0lL", "2Yo", "aR", "t3", "4yN", "6Lm", + "6Cl", "42G", "0Ma", "nS", "2Vn", "0cM", "4Xc", "79i", "74Y", "4US", "8ge", "MO", "cc", "1Pp", "bAL", "adN", + "0i4", "1lt", "5WZ", "66P", "7LU", "4iW", "0Ry", "5C", "8s", "1Oh", "4dg", "6QD", "7oI", "4JK", "G6", "RW", + "2KG", "H7", "4EJ", "64a", "7Nd", "4kf", "0PH", "7r", "1X8", "1MY", "4fV", "4s7", "69Q", "4Hz", "0sT", "Pf", + "0mV", "Nd", "5S8", "4Vx", "4xT", "4m5", "22Q", "0Cz", "0NJ", "mx", "7Pf", "41l", "5Ki", "6nk", "CT", "V5", + "Y4", "LU", "6aj", "4TI", "4ze", "6OF", "by", "0AK", "2l9", "oI", "4b4", "4wU", "4Yy", "6lZ", "Ae", "0bW", + "0So", "4U", "7MC", "4hA", "4Fm", "67F", "3XA", "09K", "0ps", "SA", "aTl", "b5f", "4eq", "6PR", "9e", "8WG", + "8XF", "6d", "5o0", "4jp", "707", "65w", "1z2", "1oS", "06J", "Qp", "68G", "4Il", "53i", "6Rc", "2iM", "1LO", + "23G", "07", "4yB", "6La", "6bM", "4Wn", "18i", "Or", "BB", "0ap", "c4D", "aEo", "5q2", "40z", "8FD", "ln", + "co", "346", "5kR", "6NP", "74U", "bol", "0nq", "MC", "2Vb", "0cA", "4Xo", "6mL", "7SA", "42K", "0Mm", "2xN", + "7oE", "4JG", "05a", "2DJ", "2jf", "1Od", "4dk", "6QH", "482", "5yz", "0Ru", "5O", "0i8", "08Q", "4Gw", "5B7", + "5M6", "4Hv", "07P", "Pj", "1X4", "1MU", "4fZ", "473", "7Nh", "4kj", "0PD", "sv", "2KK", "1nI", "4EF", "64m", + "5Ke", "6ng", "CX", "V9", "0NF", "mt", "7Pj", "4uh", "4xX", "4m9", "1F6", "0Cv", "0mZ", "Nh", "5S4", "4Vt", + "4Yu", "6lV", "Ai", "16r", "0Lw", "oE", "4b8", "43Q", "4zi", "6OJ", "bu", "0AG", "Y8", "LY", "6af", "4TE", + "4Fi", "67B", "2Hd", "09O", "e8", "4Q", "7MG", "4hE", "4eu", "6PV", "9a", "1Nz", "0pw", "SE", "aTh", "4KY", + "4DX", "4Q9", "1z6", "1oW", "0QZ", "rh", "5o4", "4jt", "4gD", "6Rg", "2iI", "j9", "06N", "Qt", "68C", "4Ih", + "6bI", "4Wj", "0lD", "Ov", "aZ", "03", "4yF", "6Le", "5q6", "4tv", "0OX", "lj", "BF", "0at", "4ZZ", "6oy", + "74Q", "5Ez", "0nu", "MG", "ck", "1Px", "5kV", "6NT", "6Cd", "42O", "0Mi", "2xJ", "2Vf", "0cE", "4Xk", "6mH", + "2jb", "8VY", "4do", "6QL", "7oA", "4JC", "05e", "2DN", "d7E", "08U", "4Gs", "5B3", "486", "bSl", "0Rq", "5K", + "1X0", "1MQ", "52w", "477", "5M2", "4Hr", "07T", "Pn", "2KO", "1nM", "4EB", "64i", "7Nl", "4kn", "8YX", "7z", + "0NB", "mp", "7Pn", "41d", "5Ka", "6nc", "2UM", "14G", "19w", "Nl", "5S0", "4Vp", "bBo", "agm", "1F2", "0Cr", + "0Ls", "oA", "ahl", "43U", "4Yq", "6lR", "Am", "16v", "0oo", "2ZL", "6ab", "4TA", "4zm", "6ON", "bq", "0AC", + "2VY", "0cz", "4XT", "4M5", "570", "42p", "0MV", "nd", "cT", "v5", "5ki", "6Nk", "74n", "4Ud", "0nJ", "Mx", + "By", "0aK", "4Ze", "6oF", "6Aj", "40A", "y4", "lU", "ae", "0BW", "4yy", "581", "4B4", "4WU", "18R", "OI", + "06q", "QK", "7lU", "4IW", "53R", "6RX", "0I4", "1Lt", "g6", "rW", "7OI", "4jK", "4Dg", "65L", "2Jj", "1oh", + "0pH", "Sz", "7nd", "4Kf", "4eJ", "6Pi", "2kG", "h7", "0ST", "4n", "7Mx", "4hz", "4FV", "4S7", "1x8", "09p", + "4zR", "4o3", "bN", "8Hd", "0oP", "Lb", "75t", "604", "4YN", "6lm", "AR", "T3", "0LL", "2yo", "6BA", "43j", + "4xc", "agR", "22f", "0CM", "0ma", "NS", "6cl", "4VO", "baL", "aDN", "Cc", "14x", "8Ge", "mO", "7PQ", "4uS", + "7NS", "4kQ", "245", "7E", "0k2", "1nr", "coo", "64V", "69f", "4HM", "E0", "PQ", "2hl", "1Mn", "4fa", "6SB", + "7Lb", "5yA", "0RN", "5t", "2IA", "J1", "4GL", "66g", "aUM", "b4G", "05Z", "0d3", "8D", "8Vf", "4dP", "459", + "574", "42t", "0MR", "0X3", "dln", "17W", "4XP", "4M1", "74j", "5EA", "0nN", "3KL", "cP", "29", "5km", "6No", + "6An", "40E", "y0", "lQ", "2Tl", "0aO", "4Za", "6oB", "4B0", "4WQ", "18V", "OM", "aa", "0BS", "bCN", "585", + "53V", "axN", "0I0", "1Lp", "06u", "QO", "68x", "4IS", "4Dc", "65H", "2Jn", "1ol", "g2", "rS", "7OM", "4jO", + "4eN", "6Pm", "9Z", "h3", "04D", "2Eo", "aTS", "4Kb", "4FR", "4S3", "d6d", "09t", "0SP", "4j", "a3G", "bRM", + "0oT", "Lf", "6aY", "4Tz", "4zV", "4o7", "bJ", "0Ax", "0LH", "oz", "6BE", "43n", "4YJ", "6li", "AV", "T7", + "0me", "NW", "6ch", "4VK", "4xg", "6MD", "22b", "0CI", "0Ny", "mK", "7PU", "4uW", "5KZ", "6nX", "Cg", "1pt", + "0k6", "1nv", "4Ey", "64R", "7NW", "4kU", "241", "7A", "2hh", "1Mj", "4fe", "6SF", "69b", "4HI", "E4", "PU", + "2IE", "J5", "4GH", "66c", "7Lf", "4id", "0RJ", "5p", "2jY", "8Vb", "4dT", "4q5", "5O8", "4Jx", "0qV", "Rd", + "21E", "25", "5ka", "6Nc", "74f", "4Ul", "0nB", "Mp", "1f2", "0cr", "bbo", "79V", "578", "42x", "395", "nl", + "am", "364", "4yq", "589", "76W", "bmn", "0ls", "OA", "Bq", "0aC", "4Zm", "6oN", "6Ab", "40I", "0Oo", "2zL", + "0Qm", "6W", "7OA", "4jC", "4Do", "65D", "2Jb", "82Q", "06y", "QC", "68t", "b7d", "4gs", "5b3", "dSM", "8UE", + "8ZD", "4f", "5m2", "4hr", "725", "67u", "1x0", "09x", "04H", "Sr", "7nl", "4Kn", "4eB", "6Pa", "9V", "1NM", + "4YF", "6le", "AZ", "0bh", "0LD", "ov", "6BI", "43b", "4zZ", "6Oy", "bF", "0At", "0oX", "Lj", "5Q6", "4Tv", + "5KV", "6nT", "Ck", "14p", "0Nu", "mG", "7PY", "41S", "4xk", "6MH", "22n", "0CE", "0mi", "2XJ", "6cd", "4VG", + "69n", "4HE", "E8", "PY", "2hd", "1Mf", "4fi", "6SJ", "ath", "4kY", "0Pw", "7M", "2Kx", "1nz", "4Eu", "6pV", + "5O4", "4Jt", "05R", "Rh", "8L", "1OW", "4dX", "451", "7Lj", "4ih", "0RF", "qt", "2II", "J9", "4GD", "66o", + "74b", "4Uh", "0nF", "Mt", "cX", "21", "5ke", "6Ng", "5s4", "4vt", "0MZ", "nh", "1f6", "0cv", "4XX", "4M9", + "4B8", "4WY", "0lw", "OE", "ai", "1Rz", "4yu", "6LV", "6Af", "40M", "y8", "lY", "Bu", "0aG", "4Zi", "6oJ", + "4Dk", "6qH", "2Jf", "1od", "0Qi", "6S", "7OE", "4jG", "4gw", "5b7", "0I8", "1Lx", "0ru", "QG", "68p", "5Yz", + "4FZ", "67q", "1x4", "1mU", "0SX", "4b", "5m6", "4hv", "4eF", "6Pe", "9R", "1NI", "04L", "Sv", "7nh", "4Kj", + "8EX", "or", "6BM", "43f", "4YB", "6la", "2WO", "0bl", "8fD", "Ln", "5Q2", "4Tr", "cPL", "aeo", "bB", "0Ap", + "0Nq", "mC", "ajn", "41W", "5KR", "6nP", "Co", "14t", "0mm", "2XN", "77I", "4VC", "4xo", "6ML", "22j", "0CA", + "3xA", "1Mb", "4fm", "6SN", "69j", "4HA", "07g", "2FL", "d5G", "83O", "4Eq", "64Z", "a0d", "bQn", "0Ps", "7I", + "8H", "1OS", "50u", "455", "5O0", "4Jp", "05V", "Rl", "2IM", "08f", "5Wa", "66k", "7Ln", "4il", "0RB", "5x", + "Bh", "0aZ", "4Zt", "6oW", "4a9", "40P", "0Ov", "lD", "at", "0BF", "4yh", "6LK", "6bg", "4WD", "Z9", "OX", + "2VH", "U8", "4XE", "6mf", "6CJ", "42a", "0MG", "nu", "cE", "1PV", "5kx", "4n8", "5P5", "4Uu", "8gC", "Mi", + "04Q", "Sk", "5N7", "4Kw", "51r", "442", "9O", "1NT", "0SE", "pw", "7Mi", "4hk", "4FG", "67l", "2HJ", "09a", + "3", "QZ", "68m", "4IF", "4gj", "6RI", "2ig", "1Le", "0Qt", "6N", "7OX", "4jZ", "4Dv", "5A6", "0j9", "1oy", + "4xr", "6MQ", "22w", "377", "0mp", "NB", "77T", "blm", "5KO", "6nM", "Cr", "14i", "0Nl", "3kn", "ajs", "41J", + "4zC", "aer", "20F", "36", "0oA", "Ls", "6aL", "4To", "bcl", "78U", "AC", "0bq", "386", "oo", "5r3", "4ws", + "5l1", "4iq", "9Kf", "5e", "1y3", "1lR", "736", "66v", "7oo", "4Jm", "05K", "Rq", "8U", "1ON", "4dA", "6Qb", + "7NB", "bQs", "0Pn", "7T", "2Ka", "1nc", "4El", "64G", "69w", "b6g", "07z", "1v2", "dRN", "8TF", "4fp", "5c0", + "akm", "40T", "0Or", "1J2", "Bl", "15w", "4Zp", "6oS", "6bc", "5Ga", "0ln", "2YM", "ap", "0BB", "4yl", "6LO", + "6CN", "42e", "0MC", "nq", "2VL", "0co", "4XA", "6mb", "5P1", "4Uq", "8gG", "Mm", "cA", "1PR", "bAn", "adl", + "51v", "446", "9K", "1NP", "04U", "So", "5N3", "4Ks", "4FC", "67h", "2HN", "09e", "0SA", "ps", "7Mm", "4ho", + "4gn", "6RM", "2ic", "1La", "7", "2GO", "68i", "4IB", "4Dr", "5A2", "d4D", "82L", "0Qp", "6J", "a1g", "bPm", + "0mt", "NF", "6cy", "4VZ", "4xv", "6MU", "0V9", "0CX", "0Nh", "mZ", "7PD", "41N", "5KK", "6nI", "Cv", "14m", + "0oE", "Lw", "6aH", "4Tk", "4zG", "6Od", "20B", "32", "0LY", "ok", "5r7", "4ww", "5Iz", "6lx", "AG", "0bu", + "1y7", "1lV", "4GY", "4R8", "5l5", "4iu", "1Bz", "5a", "8Q", "i8", "4dE", "6Qf", "7ok", "4Ji", "05O", "Ru", + "2Ke", "1ng", "4Eh", "64C", "7NF", "4kD", "f9", "7P", "2hy", "3m9", "4ft", "5c4", "69s", "4HX", "0sv", "PD", + "23e", "0BN", "5iA", "6LC", "6bo", "4WL", "Z1", "OP", "0t3", "0aR", "c4f", "aEM", "4a1", "40X", "8Ff", "lL", + "cM", "8Ig", "5kp", "4n0", "74w", "617", "0nS", "Ma", "3Fa", "U0", "4XM", "6mn", "6CB", "42i", "0MO", "2xl", + "0SM", "4w", "7Ma", "4hc", "4FO", "67d", "2HB", "K2", "04Y", "Sc", "aTN", "b5D", "4eS", "4p2", "9G", "8We", + "256", "6F", "7OP", "4jR", "cnl", "65U", "0j1", "1oq", "D3", "QR", "68e", "4IN", "4gb", "6RA", "2io", "1Lm", + "5KG", "6nE", "Cz", "14a", "x7", "mV", "7PH", "41B", "4xz", "592", "0V5", "0CT", "0mx", "NJ", "4C7", "4VV", + "4YW", "4L6", "AK", "0by", "0LU", "og", "563", "43s", "4zK", "6Oh", "bW", "w6", "0oI", "2Zj", "6aD", "4Tg", + "7og", "4Je", "05C", "Ry", "2jD", "i4", "4dI", "6Qj", "5l9", "4iy", "0RW", "5m", "2IX", "08s", "4GU", "4R4", + "7mV", "4HT", "07r", "PH", "0H7", "1Mw", "4fx", "5c8", "7NJ", "4kH", "f5", "sT", "2Ki", "1nk", "4Ed", "64O", + "6bk", "4WH", "Z5", "OT", "ax", "0BJ", "4yd", "6LG", "4a5", "4tT", "0Oz", "lH", "Bd", "0aV", "4Zx", "aEI", + "5P9", "4Uy", "0nW", "Me", "cI", "1PZ", "5kt", "4n4", "6CF", "42m", "0MK", "ny", "2VD", "U4", "4XI", "6mj", + "4FK", "6sh", "2HF", "K6", "0SI", "4s", "7Me", "4hg", "4eW", "4p6", "9C", "1NX", "0pU", "Sg", "7ny", "6k9", + "4Dz", "65Q", "0j5", "1ou", "0Qx", "6B", "7OT", "4jV", "4gf", "6RE", "2ik", "1Li", "D7", "QV", "68a", "4IJ", + "x3", "mR", "7PL", "41F", "5KC", "6nA", "2Uo", "14e", "19U", "NN", "4C3", "4VR", "bBM", "596", "0V1", "0CP", + "0LQ", "oc", "567", "43w", "4YS", "4L2", "AO", "16T", "0oM", "2Zn", "75i", "4Tc", "4zO", "6Ol", "bS", "w2", + "8Y", "i0", "4dM", "6Qn", "7oc", "4Ja", "05G", "2Dl", "d7g", "08w", "4GQ", "4R0", "a2D", "bSN", "0RS", "5i", + "0H3", "1Ms", "52U", "ayM", "7mR", "4HP", "07v", "PL", "2Km", "1no", "5UA", "64K", "7NN", "4kL", "f1", "7X", + "5nw", "4k7", "fJ", "0Ex", "0kT", "Hf", "6eY", "4Pz", "5Mk", "6hi", "EV", "P7", "0HH", "kz", "6FE", "47n", + "48o", "6ID", "26b", "0GI", "0ie", "JW", "6gh", "4RK", "5OZ", "6jX", "Gg", "0dU", "0Jy", "iK", "4d6", "4qW", + "4z4", "4oU", "1DZ", "3A", "Ye", "0zW", "4Ay", "5D9", "6yj", "4LI", "A4", "TU", "zy", "0YK", "4be", "6WF", + "6XG", "4md", "0VJ", "1p", "2ME", "N5", "4CH", "62c", "5K8", "4Nx", "0uV", "Vd", "xH", "8Rb", "5pu", "4u5", + "D", "13W", "5Lq", "4I1", "534", "46t", "0IR", "28y", "gP", "69", "5om", "6Jo", "6dC", "5AA", "0jN", "3OL", + "2Pl", "0eO", "aT1", "6kB", "6En", "44E", "98", "hQ", "ea", "0FS", "49u", "abL", "4F0", "4SQ", "8ag", "KM", + "02u", "UO", "4X2", "4MS", "57V", "a8F", "0M0", "0XQ", "c2", "vS", "7KM", "4nO", "5PB", "61H", "2Nn", "1kl", + "00D", "2Ao", "6zA", "4Ob", "4aN", "6Tm", "yR", "l3", "0WP", "0j", "a7G", "58W", "4BR", "4W3", "ZN", "84l", + "0kP", "Hb", "71t", "644", "5ns", "4k3", "fN", "8Ld", "0HL", "29g", "6FA", "47j", "5Mo", "6hm", "ER", "P3", + "0ia", "JS", "6gl", "4RO", "48k", "7Ya", "26f", "0GM", "8Ce", "iO", "4d2", "4qS", "beL", "hYw", "Gc", "0dQ", + "Ya", "0zS", "cko", "60V", "4z0", "4oQ", "205", "3E", "2ll", "0YO", "4ba", "6WB", "6yn", "4LM", "A0", "TQ", + "2MA", "N1", "4CL", "62g", "6XC", "59I", "0VN", "1t", "xL", "8Rf", "54y", "419", "aQM", "b0G", "01Z", "3PP", + "530", "46p", "0IV", "jd", "DH", "0gz", "5Lu", "4I5", "6dG", "4Qd", "0jJ", "Ix", "gT", "r5", "5oi", "6Jk", + "6Ej", "44A", "0Kg", "hU", "Fy", "0eK", "5ND", "6kF", "4F4", "4SU", "1xZ", "KI", "ee", "0FW", "49q", "5x9", + "57R", "6VX", "0M4", "0XU", "02q", "UK", "4X6", "4MW", "5PF", "61L", "2Nj", "1kh", "c6", "vW", "7KI", "4nK", + "4aJ", "6Ti", "yV", "l7", "0tH", "Wz", "6zE", "4Of", "4BV", "4W7", "ZJ", "0yx", "0WT", "0n", "6YY", "4lz", + "5Mc", "6ha", "2SO", "0fl", "1Xa", "kr", "6FM", "47f", "bDm", "aao", "fB", "0Ep", "8bD", "Hn", "5U2", "4Pr", + "5OR", "5Z3", "Go", "10t", "0Jq", "iC", "ann", "45W", "48g", "6IL", "ds", "0GA", "0im", "3Lo", "73I", "4RC", + "6yb", "4LA", "03g", "2BL", "zq", "0YC", "4bm", "6WN", "a4d", "bUn", "0Ts", "3I", "Ym", "87O", "4Aq", "5D1", + "5K0", "4Np", "01V", "Vl", "2nQ", "1KS", "54u", "415", "6XO", "4ml", "0VB", "1x", "2MM", "0xn", "5Sa", "62k", + "gX", "61", "5oe", "6Jg", "6dK", "4Qh", "0jF", "It", "L", "0gv", "5Ly", "4I9", "5w4", "4rt", "0IZ", "jh", + "ei", "1Vz", "5mT", "5x5", "4F8", "4SY", "0hw", "KE", "Fu", "0eG", "5NH", "6kJ", "6Ef", "44M", "90", "hY", + "0Ui", "2S", "7KE", "4nG", "5PJ", "6uH", "Xw", "1kd", "0vu", "UG", "6xx", "790", "4cw", "5f7", "0M8", "0XY", + "0WX", "0b", "5i6", "4lv", "4BZ", "63q", "ZF", "0yt", "00L", "Wv", "6zI", "4Oj", "4aF", "6Te", "yZ", "0Zh", + "0HD", "kv", "6FI", "47b", "5Mg", "6he", "EZ", "0fh", "0kX", "Hj", "5U6", "4Pv", "7N9", "6Ky", "fF", "0Et", + "0Ju", "iG", "6Dx", "45S", "5OV", "5Z7", "Gk", "0dY", "0ii", "3Lk", "6gd", "4RG", "48c", "6IH", "dw", "0GE", + "zu", "0YG", "4bi", "6WJ", "6yf", "4LE", "A8", "TY", "Yi", "1jz", "4Au", "5D5", "4z8", "4oY", "0Tw", "3M", + "xD", "1KW", "54q", "411", "5K4", "4Nt", "01R", "Vh", "2MI", "N9", "4CD", "62o", "6XK", "4mh", "0VF", "ut", + "6dO", "4Ql", "0jB", "Ip", "25E", "65", "5oa", "6Jc", "538", "46x", "9Pg", "jl", "H", "0gr", "bfo", "aCm", + "72W", "bin", "0hs", "KA", "em", "324", "49y", "5x1", "6Eb", "44I", "94", "3nm", "Fq", "0eC", "5NL", "6kN", + "5PN", "61D", "Xs", "86Q", "0Um", "2W", "7KA", "4nC", "4cs", "5f3", "39W", "8QE", "02y", "UC", "aRn", "794", + "765", "63u", "ZB", "0yp", "9Ne", "0f", "5i2", "4lr", "4aB", "6Ta", "2oO", "0Zl", "00H", "Wr", "6zM", "4On", + "5lW", "5y6", "dj", "0GX", "0it", "JF", "6gy", "4RZ", "5OK", "6jI", "Gv", "0dD", "83", "iZ", "6De", "45N", + "5nf", "6Kd", "24B", "72", "0kE", "Hw", "6eH", "4Pk", "5Mz", "6hx", "EG", "0fu", "0HY", "kk", "5v7", "4sw", + "5h5", "4mu", "1Fz", "1a", "2MT", "0xw", "4CY", "4V8", "7kk", "4Ni", "01O", "Vu", "xY", "m8", "54l", "6Uf", + "6Zg", "4oD", "b9", "3P", "Yt", "0zF", "4Ah", "60C", "4Y9", "4LX", "0wv", "TD", "zh", "0YZ", "4bt", "5g4", + "Fl", "11w", "5NQ", "6kS", "aom", "44T", "0Kr", "1N2", "ep", "0FB", "49d", "6HO", "6fc", "5Ca", "0hn", "3Ml", + "U", "0go", "bfr", "6ib", "6GN", "46e", "0IC", "jq", "gA", "0Ds", "bEn", "hyU", "5T1", "4Qq", "8cG", "Im", + "00U", "Wo", "5J3", "4Os", "55v", "406", "yC", "0Zq", "0WA", "ts", "6YL", "4lo", "4BC", "63h", "2LN", "0ym", + "02d", "2CO", "6xa", "4MB", "4cn", "6VM", "2mc", "1Ha", "0Up", "2J", "a5g", "bTm", "5PS", "5E2", "Xn", "86L", + "0ip", "JB", "73T", "bhm", "48z", "5y2", "dn", "337", "87", "3on", "6Da", "45J", "5OO", "6jM", "Gr", "10i", + "0kA", "Hs", "6eL", "4Po", "5nb", "aar", "24F", "76", "8AE", "ko", "5v3", "4ss", "bgl", "aBn", "EC", "0fq", + "2MP", "0xs", "776", "62v", "5h1", "4mq", "9Of", "1e", "2nL", "1KN", "54h", "6Ub", "7ko", "4Nm", "01K", "Vq", + "Yp", "0zB", "4Al", "60G", "6Zc", "bUs", "0Tn", "3T", "zl", "8PF", "4bp", "5g0", "aSm", "787", "03z", "1r2", + "4e9", "44P", "0Kv", "hD", "Fh", "0eZ", "5NU", "6kW", "6fg", "4SD", "0hj", "KX", "et", "0FF", "5mI", "6HK", + "6GJ", "46a", "0IG", "ju", "Q", "Q8", "5Ld", "6if", "5T5", "4Qu", "1zz", "Ii", "gE", "0Dw", "5ox", "4j8", + "55r", "402", "yG", "0Zu", "00Q", "Wk", "5J7", "4Ow", "4BG", "63l", "2LJ", "0yi", "0WE", "tw", "6YH", "4lk", + "4cj", "6VI", "2mg", "0XD", "0vh", "UZ", "6xe", "4MF", "5PW", "5E6", "Xj", "1ky", "0Ut", "2N", "7KX", "4nZ", + "5OC", "6jA", "2Qo", "0dL", "1ZA", "iR", "6Dm", "45F", "48v", "acO", "db", "0GP", "94M", "JN", "4G3", "4RR", + "5Mr", "4H2", "EO", "12T", "0HQ", "kc", "527", "47w", "5nn", "6Kl", "fS", "s2", "0kM", "3NO", "71i", "4Pc", + "7kc", "4Na", "01G", "3PM", "xQ", "m0", "54d", "6Un", "a6D", "59T", "0VS", "1i", "197", "85o", "4CQ", "4V0", + "4Y1", "4LP", "03v", "TL", "0L3", "0YR", "56U", "a9E", "6Zo", "4oL", "b1", "3X", "2Om", "0zN", "5QA", "60K", + "ex", "0FJ", "49l", "6HG", "6fk", "4SH", "0hf", "KT", "Fd", "0eV", "5NY", "aAI", "4e5", "4pT", "0Kz", "hH", + "gI", "1TZ", "5ot", "4j4", "5T9", "4Qy", "0jW", "Ie", "DU", "Q4", "5Lh", "6ij", "6GF", "46m", "0IK", "jy", + "0WI", "0s", "6YD", "4lg", "4BK", "6wh", "ZW", "O6", "0tU", "Wg", "6zX", "6o9", "4aW", "4t6", "yK", "0Zy", + "0Ux", "2B", "7KT", "4nV", "bzI", "61Q", "Xf", "1ku", "02l", "UV", "6xi", "4MJ", "4cf", "6VE", "2mk", "0XH", + "0Jd", "iV", "6Di", "45B", "5OG", "6jE", "Gz", "0dH", "0ix", "JJ", "4G7", "4RV", "48r", "6IY", "df", "0GT", + "0HU", "kg", "523", "47s", "5Mv", "4H6", "EK", "0fy", "0kI", "3NK", "6eD", "4Pg", "5nj", "6Kh", "fW", "s6", + "xU", "m4", "5ph", "6Uj", "7kg", "4Ne", "01C", "Vy", "193", "1hZ", "4CU", "4V4", "5h9", "4my", "0VW", "1m", + "zd", "0YV", "4bx", "5g8", "4Y5", "4LT", "03r", "TH", "Yx", "0zJ", "4Ad", "60O", "6Zk", "4oH", "b5", "wT", + "6fo", "4SL", "0hb", "KP", "27e", "0FN", "49h", "6HC", "4e1", "44X", "8Bf", "hL", "0p3", "0eR", "bdO", "aAM", + "70w", "657", "0jS", "Ia", "gM", "8Mg", "5op", "4j0", "6GB", "46i", "0IO", "28d", "Y", "Q0", "5Ll", "6in", + "4BO", "63d", "ZS", "O2", "0WM", "0w", "7Ia", "4lc", "4aS", "4t2", "yO", "8Se", "00Y", "Wc", "aPN", "b1D", + "bzM", "61U", "Xb", "1kq", "216", "2F", "7KP", "4nR", "4cb", "6VA", "2mo", "0XL", "02h", "UR", "6xm", "4MN", + "5j7", "4ow", "0TY", "3c", "YG", "0zu", "5Qz", "60p", "6yH", "4Lk", "03M", "Tw", "2lJ", "0Yi", "4bG", "6Wd", + "6Xe", "4mF", "0Vh", "1R", "2Mg", "0xD", "4Cj", "62A", "7kX", "4NZ", "0ut", "VF", "xj", "1Ky", "5pW", "5e6", + "5nU", "6KW", "fh", "0EZ", "0kv", "HD", "4E9", "4PX", "5MI", "6hK", "Et", "0fF", "0Hj", "kX", "6Fg", "47L", + "48M", "6If", "dY", "50", "0iG", "Ju", "6gJ", "4Ri", "5Ox", "4J8", "GE", "0dw", "1Zz", "ii", "5t5", "4qu", + "02W", "Um", "5H1", "4Mq", "57t", "424", "2mP", "0Xs", "0UC", "2y", "7Ko", "4nm", "bzr", "61j", "2NL", "1kN", + "00f", "2AM", "6zc", "bus", "4al", "6TO", "yp", "0ZB", "0Wr", "0H", "a7e", "58u", "4Bp", "5G0", "Zl", "84N", + "f", "13u", "5LS", "5Y2", "amo", "46V", "0Ip", "jB", "gr", "1Ta", "5oO", "6JM", "6da", "4QB", "0jl", "3On", + "2PN", "0em", "5Nb", "aAr", "6EL", "44g", "0KA", "hs", "eC", "0Fq", "49W", "abn", "5V3", "4Ss", "8aE", "Ko", + "YC", "0zq", "754", "60t", "5j3", "4os", "9Md", "3g", "2lN", "0Ym", "4bC", "7GA", "6yL", "4Lo", "03I", "Ts", + "2Mc", "1ha", "4Cn", "62E", "6Xa", "4mB", "0Vl", "1V", "xn", "8RD", "5pS", "5e2", "aQo", "b0e", "01x", "VB", + "0kr", "1n2", "71V", "bjo", "5nQ", "6KS", "fl", "315", "0Hn", "29E", "6Fc", "47H", "5MM", "6hO", "Ep", "0fB", + "0iC", "Jq", "6gN", "4Rm", "48I", "6Ib", "26D", "54", "8CG", "im", "509", "45y", "ben", "hYU", "GA", "0ds", + "4cY", "420", "2mT", "0Xw", "02S", "Ui", "5H5", "4Mu", "5Pd", "61n", "XY", "M8", "0UG", "vu", "7Kk", "4ni", + "4ah", "6TK", "yt", "0ZF", "B9", "WX", "6zg", "4OD", "4Bt", "5G4", "Zh", "0yZ", "0Wv", "0L", "4y9", "4lX", + "6Gy", "46R", "0It", "jF", "b", "0gX", "5LW", "5Y6", "6de", "4QF", "0jh", "IZ", "gv", "0DD", "5oK", "6JI", + "6EH", "44c", "0KE", "hw", "2PJ", "0ei", "5Nf", "6kd", "5V7", "4Sw", "0hY", "Kk", "eG", "0Fu", "49S", "6Hx", + "7ia", "4Lc", "03E", "2Bn", "zS", "o2", "4bO", "6Wl", "a4F", "bUL", "0TQ", "3k", "YO", "87m", "4AS", "4T2", + "7kP", "4NR", "01t", "VN", "xb", "1Kq", "54W", "hfv", "6Xm", "4mN", "1FA", "1Z", "2Mo", "0xL", "4Cb", "62I", + "5MA", "6hC", "2Sm", "0fN", "0Hb", "kP", "6Fo", "47D", "bDO", "aaM", "0P3", "0ER", "8bf", "HL", "4E1", "4PP", + "5Op", "4J0", "GM", "10V", "0JS", "ia", "505", "45u", "48E", "6In", "dQ", "58", "0iO", "3LM", "6gB", "4Ra", + "0UK", "2q", "7Kg", "4ne", "5Ph", "61b", "XU", "M4", "0vW", "Ue", "5H9", "4My", "4cU", "4v4", "2mX", "1HZ", + "0Wz", "tH", "4y5", "4lT", "4Bx", "5G8", "Zd", "0yV", "B5", "WT", "6zk", "4OH", "4ad", "6TG", "yx", "0ZJ", + "gz", "0DH", "5oG", "6JE", "6di", "4QJ", "0jd", "IV", "n", "0gT", "680", "6iY", "4g7", "4rV", "0Ix", "jJ", + "eK", "0Fy", "5mv", "4h6", "6fX", "5CZ", "0hU", "Kg", "FW", "S6", "5Nj", "6kh", "6ED", "44o", "0KI", "3nK", + "zW", "o6", "4bK", "6Wh", "6yD", "4Lg", "03A", "2Bj", "YK", "0zy", "4AW", "4T6", "6ZX", "6O9", "0TU", "3o", + "xf", "1Ku", "54S", "6UY", "7kT", "4NV", "01p", "VJ", "2Mk", "0xH", "4Cf", "62M", "6Xi", "4mJ", "0Vd", "uV", + "0Hf", "kT", "6Fk", "4sH", "5ME", "6hG", "Ex", "0fJ", "0kz", "HH", "4E5", "4PT", "5nY", "aaI", "fd", "0EV", + "0JW", "ie", "501", "45q", "5Ot", "4J4", "GI", "10R", "0iK", "Jy", "6gF", "4Re", "48A", "6Ij", "dU", "q4", + "5Pl", "61f", "XQ", "M0", "0UO", "2u", "7Kc", "4na", "4cQ", "428", "39u", "8Qg", "0vS", "Ua", "aRL", "b3F", + "bxO", "63W", "0l3", "0yR", "234", "0D", "4y1", "4lP", "55I", "6TC", "2om", "0ZN", "B1", "WP", "6zo", "4OL", + "6dm", "4QN", "1zA", "IR", "25g", "0DL", "5oC", "6JA", "4g3", "46Z", "9PE", "jN", "j", "0gP", "684", "aCO", + "72u", "675", "0hQ", "Kc", "eO", "8Oe", "5mr", "4h2", "7Ua", "44k", "0KM", "3nO", "FS", "S2", "5Nn", "6kl", + "4x6", "4mW", "0Vy", "1C", "0m4", "0xU", "5SZ", "62P", "7kI", "4NK", "C6", "VW", "2nj", "1Kh", "54N", "6UD", + "6ZE", "4of", "0TH", "3r", "YV", "L7", "4AJ", "60a", "6yY", "4Lz", "0wT", "Tf", "zJ", "0Yx", "4bV", "4w7", + "5lu", "4i5", "dH", "0Gz", "0iV", "Jd", "5W8", "4Rx", "5Oi", "6jk", "GT", "R5", "0JJ", "ix", "6DG", "45l", + "5nD", "6KF", "fy", "0EK", "0kg", "HU", "6ej", "4PI", "5MX", "5X9", "Ee", "0fW", "1XZ", "kI", "4f4", "4sU", + "00w", "WM", "4Z0", "4OQ", "55T", "hgu", "ya", "0ZS", "a0", "0Y", "6Yn", "4lM", "4Ba", "63J", "2Ll", "0yO", + "02F", "2Cm", "6xC", "aG0", "4cL", "6Vo", "2mA", "n1", "0UR", "2h", "a5E", "bTO", "5Pq", "4U1", "XL", "86n", + "FN", "11U", "5Ns", "4K3", "516", "44v", "0KP", "hb", "eR", "p3", "49F", "6Hm", "6fA", "4Sb", "0hL", "3MN", + "w", "0gM", "5LB", "7ya", "6Gl", "46G", "0Ia", "jS", "gc", "0DQ", "bEL", "hyw", "4D2", "4QS", "8ce", "IO", + "0m0", "0xQ", "byL", "62T", "4x2", "4mS", "227", "1G", "2nn", "1Kl", "54J", "7Ea", "7kM", "4NO", "C2", "VS", + "YR", "L3", "4AN", "60e", "6ZA", "4ob", "0TL", "3v", "zN", "8Pd", "4bR", "4w3", "aSO", "b2E", "03X", "Tb", + "0iR", "3LP", "73v", "666", "48X", "4i1", "dL", "8Nf", "0JN", "3oL", "6DC", "45h", "5Om", "6jo", "GP", "R1", + "0kc", "HQ", "6en", "4PM", "a09", "6KB", "24d", "0EO", "8Ag", "kM", "4f0", "47Y", "697", "aBL", "Ea", "0fS", + "4ay", "5d9", "ye", "0ZW", "00s", "WI", "4Z4", "4OU", "4Be", "63N", "Zy", "0yK", "a4", "tU", "6Yj", "4lI", + "4cH", "6Vk", "2mE", "n5", "02B", "Ux", "6xG", "4Md", "5Pu", "4U5", "XH", "86j", "0UV", "2l", "5k8", "4nx", + "512", "44r", "0KT", "hf", "FJ", "0ex", "5Nw", "4K7", "6fE", "4Sf", "0hH", "Kz", "eV", "p7", "49B", "6Hi", + "6Gh", "46C", "0Ie", "jW", "s", "0gI", "5LF", "6iD", "4D6", "4QW", "0jy", "IK", "gg", "0DU", "5oZ", "6JX", + "7kA", "4NC", "01e", "3Po", "xs", "8RY", "54F", "6UL", "a6f", "59v", "0Vq", "1K", "d3E", "85M", "4Cs", "5F3", + "5I2", "4Lr", "03T", "Tn", "zB", "0Yp", "56w", "437", "6ZM", "4on", "1Da", "3z", "2OO", "0zl", "4AB", "60i", + "5Oa", "6jc", "2QM", "0dn", "0JB", "ip", "6DO", "45d", "48T", "acm", "1B2", "0Gr", "94o", "Jl", "5W0", "4Rp", + "5MP", "5X1", "Em", "12v", "0Hs", "kA", "all", "47U", "5nL", "6KN", "fq", "0EC", "0ko", "3Nm", "6eb", "4PA", + "a8", "0Q", "6Yf", "4lE", "4Bi", "63B", "Zu", "0yG", "0tw", "WE", "4Z8", "4OY", "4au", "5d5", "yi", "1Jz", + "0UZ", "vh", "5k4", "4nt", "5Py", "4U9", "XD", "1kW", "02N", "Ut", "6xK", "4Mh", "4cD", "6Vg", "2mI", "n9", + "eZ", "43", "49N", "6He", "6fI", "4Sj", "0hD", "Kv", "FF", "0et", "7n9", "6ky", "5u6", "4pv", "0KX", "hj", + "gk", "0DY", "5oV", "5z7", "6dx", "5Az", "0ju", "IG", "Dw", "0gE", "5LJ", "6iH", "6Gd", "46O", "0Ii", "28B", + "xw", "1Kd", "54B", "6UH", "7kE", "4NG", "01a", "3Pk", "0m8", "0xY", "4Cw", "5F7", "6Xx", "59r", "0Vu", "1O", + "zF", "0Yt", "4bZ", "433", "5I6", "4Lv", "03P", "Tj", "YZ", "0zh", "4AF", "60m", "6ZI", "4oj", "0TD", "wv", + "0JF", "it", "6DK", "4qh", "5Oe", "6jg", "GX", "R9", "0iZ", "Jh", "5W4", "4Rt", "48P", "4i9", "dD", "0Gv", + "0Hw", "kE", "4f8", "47Q", "5MT", "5X5", "Ei", "12r", "0kk", "HY", "6ef", "4PE", "5nH", "6KJ", "fu", "0EG", + "4Bm", "63F", "Zq", "0yC", "0Wo", "0U", "6Yb", "4lA", "4aq", "5d1", "ym", "8SG", "0ts", "WA", "aPl", "b1f", + "747", "61w", "2NQ", "1kS", "9Lg", "2d", "5k0", "4np", "57i", "6Vc", "2mM", "0Xn", "02J", "Up", "6xO", "4Ml", + "6fM", "4Sn", "1xa", "Kr", "27G", "47", "49J", "6Ha", "5u2", "44z", "8BD", "hn", "FB", "0ep", "bdm", "aAo", + "70U", "bkl", "0jq", "IC", "go", "306", "5oR", "5z3", "7WA", "46K", "0Im", "28F", "Ds", "0gA", "5LN", "6iL", + "0cY", "020", "6mT", "4Xw", "42S", "6Cx", "nG", "0Mu", "1Pd", "cw", "6NH", "5kJ", "4UG", "74M", "3Kk", "0ni", + "0ah", "BZ", "6oe", "4ZF", "40b", "6AI", "lv", "0OD", "0Bt", "aF", "6Ly", "4yZ", "4Wv", "5R6", "Oj", "0lX", + "Qh", "06R", "4It", "5L4", "461", "4gX", "1LW", "1Y6", "rt", "0QF", "4jh", "7Oj", "65o", "4DD", "I9", "2JI", + "SY", "F8", "4KE", "7nG", "6PJ", "4ei", "1Nf", "2kd", "4M", "0Sw", "4hY", "490", "5C5", "4Fu", "09S", "2Hx", + "6OR", "4zq", "354", "bm", "LA", "0os", "bnn", "75W", "6lN", "4Ym", "0bC", "Aq", "2yL", "0Lo", "43I", "6Bb", + "6Mc", "5ha", "15", "22E", "Np", "0mB", "4Vl", "6cO", "aDm", "bao", "1pS", "1e2", "ml", "8GF", "41x", "548", + "4kr", "5n2", "7f", "8YD", "1nQ", "2KS", "64u", "715", "4Hn", "69E", "Pr", "07H", "1MM", "2hO", "6Sa", "4fB", + "4iC", "7LA", "5W", "0Rm", "08I", "2Ib", "66D", "4Go", "b4d", "aUn", "RC", "05y", "8VE", "8g", "5a3", "4ds", + "42W", "ain", "nC", "0Mq", "17t", "024", "6mP", "4Xs", "4UC", "74I", "3Ko", "0nm", "8IY", "cs", "6NL", "5kN", + "40f", "6AM", "lr", "8FX", "0al", "2TO", "6oa", "4ZB", "4Wr", "5R2", "On", "18u", "0Bp", "aB", "afo", "bCm", + "465", "53u", "1LS", "1Y2", "Ql", "06V", "4Ip", "5L0", "65k", "5Ta", "1oO", "2JM", "6x", "0QB", "4jl", "7On", + "6PN", "4em", "1Nb", "9y", "2EL", "04g", "4KA", "7nC", "5C1", "4Fq", "09W", "d6G", "4I", "0Ss", "bRn", "494", + "LE", "0ow", "4TY", "4A8", "6OV", "4zu", "1Qz", "bi", "oY", "z8", "43M", "6Bf", "6lJ", "4Yi", "0bG", "Au", + "Nt", "0mF", "4Vh", "6cK", "6Mg", "4xD", "11", "22A", "mh", "0NZ", "4ut", "5p4", "4N9", "5Ky", "1pW", "CD", + "1nU", "2KW", "64q", "4EZ", "4kv", "5n6", "7b", "0PX", "1MI", "2hK", "6Se", "4fF", "4Hj", "69A", "Pv", "07L", + "08M", "2If", "6rH", "4Gk", "4iG", "7LE", "5S", "0Ri", "1Ox", "8c", "5a7", "4dw", "5Zz", "7oY", "RG", "0qu", + "1Pl", "21f", "adR", "5kB", "4UO", "74E", "MS", "X2", "0cQ", "028", "79u", "bbL", "4vS", "4c2", "nO", "8De", + "8Kd", "aN", "4l3", "4yR", "634", "76t", "Ob", "0lP", "W3", "BR", "6om", "4ZN", "40j", "6AA", "2zo", "0OL", + "6t", "0QN", "5zA", "7Ob", "65g", "4DL", "I1", "2JA", "0g3", "06Z", "b7G", "68W", "469", "4gP", "284", "dSn", + "4E", "275", "4hQ", "498", "67V", "b8F", "1mr", "0h2", "SQ", "F0", "4KM", "7nO", "6PB", "4ea", "1Nn", "9u", + "6lF", "4Ye", "0bK", "Ay", "oU", "z4", "43A", "6Bj", "6OZ", "4zy", "0AW", "be", "LI", "2O9", "4TU", "4A4", + "4N5", "5Ku", "14S", "CH", "md", "0NV", "41p", "540", "6Mk", "4xH", "u5", "22M", "Nx", "0mJ", "4Vd", "6cG", + "4Hf", "69M", "Pz", "0sH", "k7", "2hG", "6Si", "4fJ", "4kz", "7Nx", "7n", "0PT", "1nY", "dqh", "4P7", "4EV", + "4JW", "7oU", "RK", "05q", "1Ot", "8o", "6QX", "50R", "4iK", "7LI", "qW", "d6", "08A", "2Ij", "66L", "4Gg", + "4UK", "74A", "MW", "X6", "1Ph", "21b", "6ND", "5kF", "4vW", "4c6", "nK", "0My", "0cU", "0v4", "6mX", "5HZ", + "4Wz", "6bY", "Of", "0lT", "0Bx", "aJ", "4l7", "4yV", "40n", "6AE", "lz", "0OH", "W7", "BV", "6oi", "4ZJ", + "65c", "4DH", "I5", "2JE", "6p", "0QJ", "4jd", "7Of", "4r5", "4gT", "280", "2iY", "Qd", "0rV", "4Ix", "5L8", + "5C9", "4Fy", "1mv", "0h6", "4A", "1CZ", "4hU", "7MW", "6PF", "4ee", "1Nj", "9q", "SU", "F4", "4KI", "7nK", + "oQ", "z0", "43E", "6Bn", "6lB", "4Ya", "0bO", "2Wl", "LM", "8fg", "4TQ", "4A0", "aeL", "cPo", "0AS", "ba", + "3kP", "0NR", "41t", "544", "4N1", "5Kq", "14W", "CL", "2Xm", "0mN", "5FA", "6cC", "6Mo", "4xL", "19", "22I", + "k3", "2hC", "6Sm", "4fN", "4Hb", "69I", "2Fo", "07D", "83l", "d5d", "4P3", "4ER", "bQM", "a0G", "7j", "0PP", + "1Op", "8k", "hbw", "50V", "4JS", "7oQ", "RO", "05u", "08E", "2In", "66H", "4Gc", "4iO", "7LM", "qS", "d2", + "0ay", "BK", "4O6", "4ZW", "40s", "553", "lg", "0OU", "t6", "aW", "6Lh", "4yK", "4Wg", "6bD", "2Yj", "0lI", + "0cH", "2Vk", "6mE", "4Xf", "42B", "6Ci", "nV", "0Md", "1Pu", "cf", "6NY", "bAI", "4UV", "7pT", "MJ", "0nx", + "SH", "04r", "4KT", "7nV", "azI", "4ex", "1Nw", "9l", "pT", "e5", "4hH", "7MJ", "67O", "4Fd", "09B", "2Hi", + "Qy", "06C", "4Ie", "68N", "6Rj", "4gI", "j4", "2iD", "6m", "0QW", "4jy", "5o9", "4Q4", "4DU", "1oZ", "2JX", + "4m0", "4xQ", "8Jg", "22T", "Na", "0mS", "627", "77w", "6nn", "5Kl", "V0", "CQ", "3kM", "0NO", "41i", "7Pc", + "6OC", "5jA", "0AN", "20e", "LP", "Y1", "4TL", "6ao", "78v", "bcO", "0bR", "0w3", "oL", "8Ef", "43X", "4b1", + "4iR", "7LP", "5F", "266", "08X", "0i1", "66U", "b9E", "4JN", "7oL", "RR", "G3", "1Om", "8v", "6QA", "4db", + "4kc", "7Na", "7w", "0PM", "H2", "2KB", "64d", "4EO", "b6D", "69T", "Pc", "07Y", "297", "dRm", "4s2", "4fS", + "40w", "557", "lc", "0OQ", "15T", "BO", "4O2", "4ZS", "4Wc", "76i", "2Yn", "0lM", "t2", "aS", "6Ll", "4yO", + "42F", "6Cm", "nR", "8Dx", "0cL", "2Vo", "6mA", "4Xb", "4UR", "74X", "MN", "8gd", "1Pq", "cb", "adO", "bAM", + "azM", "51U", "1Ns", "9h", "SL", "04v", "4KP", "7nR", "67K", "5VA", "09F", "2Hm", "4X", "e1", "4hL", "7MN", + "6Rn", "4gM", "j0", "3ya", "2Gl", "06G", "4Ia", "68J", "4Q0", "4DQ", "82o", "d4g", "6i", "0QS", "bPN", "a1D", + "Ne", "0mW", "4Vy", "5S9", "4m4", "4xU", "1SZ", "22P", "my", "0NK", "41m", "7Pg", "6nj", "5Kh", "V4", "CU", + "LT", "Y5", "4TH", "6ak", "6OG", "4zd", "0AJ", "bx", "oH", "0Lz", "4wT", "4b5", "78r", "4Yx", "0bV", "Ad", + "1lu", "0i5", "66Q", "4Gz", "4iV", "7LT", "5B", "0Rx", "1Oi", "8r", "6QE", "4df", "4JJ", "7oH", "RV", "G7", + "H6", "2KF", "6ph", "4EK", "4kg", "7Ne", "7s", "0PI", "1MX", "1X9", "4s6", "4fW", "5XZ", "69P", "Pg", "0sU", + "06", "23F", "afr", "4yC", "4Wo", "6bL", "Os", "0lA", "0aq", "BC", "aEn", "c4E", "4ts", "5q3", "lo", "8FE", + "347", "cn", "6NQ", "5kS", "bom", "74T", "MB", "0np", "17i", "2Vc", "6mM", "4Xn", "42J", "6Ca", "2xO", "0Ml", + "4T", "0Sn", "5xa", "7MB", "67G", "4Fl", "09J", "2Ha", "1u2", "04z", "b5g", "aTm", "6PS", "4ep", "8WF", "9d", + "6e", "8XG", "4jq", "5o1", "65v", "706", "1oR", "1z3", "Qq", "06K", "4Im", "68F", "6Rb", "4gA", "1LN", "2iL", + "6nf", "5Kd", "V8", "CY", "mu", "0NG", "41a", "7Pk", "4m8", "4xY", "0Cw", "1F7", "Ni", "19r", "4Vu", "5S5", + "6lW", "4Yt", "0bZ", "Ah", "oD", "0Lv", "43P", "4b9", "6OK", "4zh", "0AF", "bt", "LX", "Y9", "4TD", "6ag", + "4JF", "7oD", "RZ", "0qh", "1Oe", "2jg", "6QI", "4dj", "4iZ", "483", "5N", "0Rt", "08P", "0i9", "5B6", "4Gv", + "4Hw", "5M7", "Pk", "07Q", "1MT", "1X5", "472", "52r", "4kk", "7Ni", "sw", "0PE", "1nH", "2KJ", "64l", "4EG", + "4Wk", "6bH", "Ow", "0lE", "02", "23B", "6Ld", "4yG", "4tw", "5q7", "lk", "0OY", "0au", "BG", "6ox", "5Jz", + "4UZ", "74P", "MF", "0nt", "1Py", "cj", "6NU", "5kW", "42N", "6Ce", "nZ", "0Mh", "0cD", "2Vg", "6mI", "4Xj", + "67C", "4Fh", "09N", "2He", "4P", "e9", "4hD", "7MF", "6PW", "4et", "3n9", "2ky", "SD", "0pv", "4KX", "7nZ", + "4Q8", "4DY", "1oV", "1z7", "6a", "1Az", "4ju", "5o5", "6Rf", "4gE", "j8", "2iH", "Qu", "06O", "4Ii", "68B", + "mq", "0NC", "41e", "7Po", "6nb", "bar", "14F", "2UL", "Nm", "19v", "4Vq", "5S1", "agl", "bBn", "0Cs", "1F3", + "1I2", "0Lr", "43T", "ahm", "6lS", "4Yp", "16w", "Al", "2ZM", "0on", "5Da", "6ac", "6OO", "4zl", "0AB", "bp", + "1Oa", "8z", "6QM", "4dn", "4JB", "aUs", "2DO", "05d", "08T", "d7D", "5B2", "4Gr", "bSm", "487", "5J", "0Rp", + "1MP", "1X1", "476", "52v", "4Hs", "5M3", "Po", "07U", "1nL", "2KN", "64h", "4EC", "4ko", "7Nm", "ss", "0PA", + "QJ", "06p", "4IV", "7lT", "6RY", "4gz", "1Lu", "0I5", "rV", "g7", "4jJ", "7OH", "65M", "4Df", "1oi", "2Jk", + "2Ej", "04A", "4Kg", "7ne", "6Ph", "4eK", "h6", "2kF", "4o", "0SU", "5xZ", "7My", "4S6", "4FW", "09q", "1x9", + "17R", "2VX", "4M4", "4XU", "42q", "571", "ne", "0MW", "v4", "cU", "6Nj", "5kh", "4Ue", "74o", "My", "0nK", + "0aJ", "Bx", "6oG", "4Zd", "4tH", "6Ak", "lT", "y5", "0BV", "ad", "580", "4yx", "4WT", "4B5", "OH", "0lz", + "4kP", "7NR", "7D", "244", "1ns", "0k3", "64W", "con", "4HL", "69g", "PP", "E1", "1Mo", "2hm", "6SC", "52I", + "4ia", "7Lc", "5u", "0RO", "J0", "3Ya", "66f", "4GM", "b4F", "aUL", "Ra", "0qS", "8Vg", "8E", "458", "4dQ", + "4o2", "4zS", "8He", "bO", "Lc", "0oQ", "605", "75u", "6ll", "4YO", "T2", "AS", "2yn", "0LM", "43k", "7Ra", + "6MA", "4xb", "0CL", "22g", "NR", "19I", "4VN", "6cm", "aDO", "baM", "14y", "Cb", "mN", "8Gd", "41Z", "7PP", + "axO", "53W", "1Lq", "0I1", "QN", "06t", "4IR", "68y", "65I", "4Db", "1om", "2Jo", "6Z", "g3", "4jN", "7OL", + "6Pl", "4eO", "h2", "2kB", "2En", "04E", "4Kc", "7na", "4S2", "4FS", "09u", "d6e", "4k", "0SQ", "bRL", "a3F", + "42u", "575", "na", "0MS", "17V", "dlo", "4M0", "4XQ", "4Ua", "74k", "3KM", "0nO", "28", "cQ", "6Nn", "5kl", + "40D", "6Ao", "lP", "y1", "0aN", "2Tm", "6oC", "5JA", "4WP", "4B1", "OL", "18W", "0BR", "0W3", "584", "bCO", + "1nw", "0k7", "64S", "4Ex", "4kT", "7NV", "sH", "0Pz", "1Mk", "2hi", "6SG", "4fd", "4HH", "69c", "PT", "E5", + "J4", "2ID", "66b", "4GI", "4ie", "7Lg", "5q", "0RK", "1OZ", "8A", "4q4", "4dU", "4Jy", "5O9", "Re", "0qW", + "Lg", "0oU", "5DZ", "6aX", "4o6", "4zW", "0Ay", "bK", "2yj", "0LI", "43o", "6BD", "6lh", "4YK", "T6", "AW", + "NV", "0md", "4VJ", "6ci", "6ME", "4xf", "0CH", "22c", "mJ", "0Nx", "4uV", "7PT", "6nY", "baI", "1pu", "Cf", + "6V", "0Ql", "4jB", "aus", "65E", "4Dn", "1oa", "2Jc", "QB", "06x", "b7e", "68u", "5b2", "4gr", "8UD", "dSL", + "4g", "8ZE", "4hs", "5m3", "67t", "724", "09y", "1x1", "Ss", "04I", "4Ko", "7nm", "azr", "4eC", "1NL", "9W", + "24", "21D", "6Nb", "bAr", "4Um", "74g", "Mq", "0nC", "0cs", "1f3", "79W", "bbn", "42y", "579", "nm", "394", + "365", "al", "588", "4yp", "bmo", "76V", "1i2", "0lr", "0aB", "Bp", "6oO", "4Zl", "40H", "6Ac", "2zM", "0On", + "4HD", "69o", "PX", "E9", "1Mg", "2he", "6SK", "4fh", "4kX", "7NZ", "7L", "0Pv", "3N9", "2Ky", "6pW", "4Et", + "4Ju", "5O5", "Ri", "05S", "1OV", "8M", "450", "4dY", "4ii", "7Lk", "qu", "0RG", "J8", "2IH", "66n", "4GE", + "6ld", "4YG", "0bi", "2WJ", "ow", "0LE", "43c", "6BH", "6Ox", "5jz", "0Au", "bG", "Lk", "0oY", "4Tw", "5Q7", + "6nU", "5KW", "14q", "Cj", "mF", "0Nt", "41R", "7PX", "6MI", "4xj", "0CD", "22o", "NZ", "0mh", "4VF", "6ce", + "65A", "4Dj", "1oe", "2Jg", "6R", "0Qh", "4jF", "7OD", "5b6", "4gv", "1Ly", "0I9", "QF", "0rt", "4IZ", "68q", + "67p", "5Vz", "1mT", "1x5", "4c", "0SY", "4hw", "5m7", "6Pd", "4eG", "1NH", "9S", "Sw", "04M", "4Kk", "7ni", + "4Ui", "74c", "Mu", "0nG", "20", "cY", "6Nf", "5kd", "4vu", "5s5", "ni", "390", "0cw", "1f7", "4M8", "4XY", + "4WX", "4B9", "OD", "0lv", "0BZ", "ah", "6LW", "4yt", "40L", "6Ag", "lX", "y9", "0aF", "Bt", "6oK", "4Zh", + "1Mc", "2ha", "6SO", "4fl", "5Xa", "69k", "2FM", "07f", "83N", "d5F", "6pS", "4Ep", "bQo", "a0e", "7H", "0Pr", + "1OR", "8I", "454", "50t", "4Jq", "5O1", "Rm", "05W", "08g", "2IL", "66j", "4GA", "4im", "7Lo", "5y", "0RC", + "os", "0LA", "43g", "6BL", "78I", "4YC", "0bm", "2WN", "Lo", "8fE", "4Ts", "5Q3", "aen", "cPM", "0Aq", "bC", + "mB", "0Np", "41V", "ajo", "6nQ", "5KS", "14u", "Cn", "2XO", "0ml", "4VB", "6ca", "6MM", "4xn", "1Sa", "22k", + "Sj", "04P", "4Kv", "5N6", "443", "4eZ", "1NU", "9N", "pv", "0SD", "4hj", "7Mh", "67m", "4FF", "1mI", "2HK", + "2GJ", "2", "4IG", "68l", "6RH", "4gk", "1Ld", "2if", "6O", "0Qu", "5zz", "7OY", "5A7", "4Dw", "1ox", "0j8", + "15r", "Bi", "6oV", "4Zu", "40Q", "4a8", "lE", "0Ow", "0BG", "au", "6LJ", "4yi", "4WE", "6bf", "OY", "Z8", + "U9", "2VI", "6mg", "4XD", "4vh", "6CK", "nt", "0MF", "1PW", "cD", "4n9", "5ky", "4Ut", "5P4", "Mh", "0nZ", + "4ip", "5l0", "5d", "9Kg", "08z", "1y2", "66w", "737", "4Jl", "7on", "Rp", "05J", "1OO", "8T", "6Qc", "50i", + "4kA", "7NC", "7U", "0Po", "1nb", "dqS", "64F", "4Em", "b6f", "69v", "PA", "0ss", "8TG", "dRO", "5c1", "4fq", + "6MP", "4xs", "376", "22v", "NC", "0mq", "bll", "77U", "6nL", "5KN", "14h", "Cs", "3ko", "0Nm", "41K", "7PA", + "6Oa", "4zB", "37", "20G", "Lr", "8fX", "4Tn", "6aM", "78T", "bcm", "0bp", "AB", "on", "387", "43z", "5r2", + "447", "51w", "1NQ", "9J", "Sn", "04T", "4Kr", "5N2", "67i", "4FB", "09d", "2HO", "4z", "1Ca", "4hn", "7Ml", + "6RL", "4go", "8UY", "2ib", "2GN", "6", "4IC", "68h", "5A3", "4Ds", "82M", "d4E", "6K", "0Qq", "bPl", "a1f", + "40U", "akl", "lA", "0Os", "15v", "Bm", "6oR", "4Zq", "4WA", "6bb", "2YL", "0lo", "0BC", "aq", "6LN", "4ym", + "42d", "6CO", "np", "0MB", "0cn", "2VM", "6mc", "5Ha", "4Up", "5P0", "Ml", "8gF", "1PS", "1E2", "adm", "bAo", + "1lW", "1y6", "4R9", "4GX", "4it", "5l4", "qh", "0RZ", "i9", "8P", "6Qg", "4dD", "4Jh", "7oj", "Rt", "05N", + "1nf", "2Kd", "64B", "4Ei", "4kE", "7NG", "7Q", "f8", "1Mz", "2hx", "5c5", "4fu", "4HY", "69r", "PE", "0sw", + "NG", "0mu", "5Fz", "6cx", "6MT", "4xw", "0CY", "0V8", "3kk", "0Ni", "41O", "7PE", "6nH", "5KJ", "14l", "Cw", + "Lv", "0oD", "4Tj", "6aI", "6Oe", "4zF", "33", "bZ", "oj", "0LX", "4wv", "5r6", "6ly", "4YZ", "0bt", "AF", + "4v", "0SL", "4hb", "awS", "67e", "4FN", "K3", "2HC", "Sb", "04X", "b5E", "aTO", "4p3", "4eR", "8Wd", "9F", + "6G", "257", "4jS", "7OQ", "65T", "cnm", "1op", "0j0", "QS", "D2", "4IO", "68d", "7Ba", "4gc", "1Ll", "2in", + "0BO", "23d", "6LB", "4ya", "4WM", "6bn", "OQ", "Z0", "0aS", "Ba", "aEL", "c4g", "40Y", "4a0", "lM", "8Fg", + "8If", "cL", "4n1", "5kq", "616", "74v", "3KP", "0nR", "U1", "2VA", "6mo", "4XL", "42h", "6CC", "2xm", "0MN", + "4Jd", "7of", "Rx", "05B", "i5", "2jE", "6Qk", "4dH", "4ix", "5l8", "5l", "0RV", "08r", "2IY", "4R5", "4GT", + "4HU", "7mW", "PI", "07s", "1Mv", "0H6", "5c9", "4fy", "4kI", "7NK", "sU", "f4", "1nj", "2Kh", "64N", "4Ee", + "6nD", "5KF", "1ph", "2Uj", "mW", "x6", "41C", "7PI", "593", "5hZ", "0CU", "0V4", "NK", "0my", "4VW", "4C6", + "4L7", "4YV", "0bx", "AJ", "of", "0LT", "43r", "562", "6Oi", "4zJ", "w7", "bV", "Lz", "0oH", "4Tf", "6aE", + "67a", "4FJ", "K7", "2HG", "4r", "0SH", "4hf", "7Md", "4p7", "4eV", "1NY", "9B", "Sf", "0pT", "4Kz", "7nx", + "65P", "5TZ", "1ot", "0j4", "6C", "0Qy", "4jW", "7OU", "6RD", "4gg", "1Lh", "2ij", "QW", "D6", "4IK", "7lI", + "4WI", "6bj", "OU", "Z4", "0BK", "ay", "6LF", "4ye", "4tU", "4a4", "lI", "2o9", "0aW", "Be", "6oZ", "4Zy", + "4Ux", "5P8", "Md", "0nV", "8Ib", "cH", "4n5", "5ku", "42l", "6CG", "nx", "0MJ", "U5", "2VE", "6mk", "4XH", + "i1", "8X", "6Qo", "4dL", "5ZA", "7ob", "2Dm", "05F", "08v", "d7f", "4R1", "4GP", "bSO", "a2E", "5h", "0RR", + "1Mr", "0H2", "ayL", "52T", "4HQ", "69z", "PM", "07w", "1nn", "2Kl", "64J", "4Ea", "4kM", "7NO", "7Y", "f0", + "mS", "x2", "41G", "7PM", "aDR", "5KB", "14d", "2Un", "NO", "19T", "4VS", "4C2", "597", "bBL", "0CQ", "0V0", + "ob", "0LP", "43v", "566", "4L3", "4YR", "16U", "AN", "2Zo", "0oL", "4Tb", "6aA", "6Om", "4zN", "w3", "bR", + "4oT", "4z5", "wH", "0Tz", "0zV", "Yd", "5D8", "4Ax", "4LH", "6yk", "TT", "A5", "0YJ", "zx", "6WG", "4bd", + "4me", "6XF", "1q", "0VK", "N4", "2MD", "62b", "4CI", "4Ny", "5K9", "Ve", "0uW", "1KZ", "xI", "4u4", "5pt", + "4k6", "5nv", "0Ey", "fK", "Hg", "0kU", "641", "6eX", "6hh", "5Mj", "P6", "EW", "29b", "0HI", "47o", "6FD", + "6IE", "48n", "0GH", "dz", "JV", "0id", "4RJ", "6gi", "6jY", "beI", "0dT", "Gf", "iJ", "0Jx", "4qV", "4d7", + "UN", "02t", "4MR", "4X3", "a8G", "57W", "0XP", "0M1", "2Z", "c3", "4nN", "7KL", "61I", "5PC", "1km", "2No", + "2An", "00E", "4Oc", "7ja", "6Tl", "4aO", "l2", "yS", "0k", "0WQ", "58V", "a7F", "4W2", "4BS", "84m", "ZO", + "13V", "E", "4I0", "5Lp", "46u", "535", "ja", "0IS", "68", "gQ", "6Jn", "5ol", "4Qa", "6dB", "3OM", "0jO", + "0eN", "2Pm", "6kC", "5NA", "44D", "6Eo", "hP", "99", "0FR", "0S3", "abM", "49t", "4SP", "4F1", "KL", "8af", + "0zR", "0o3", "60W", "ckn", "4oP", "4z1", "3D", "204", "0YN", "2lm", "6WC", "56I", "4LL", "6yo", "TP", "A1", + "N0", "903", "62f", "4CM", "4ma", "6XB", "1u", "0VO", "8Rg", "xM", "418", "54x", "b0F", "aQL", "Va", "0uS", + "Hc", "0kQ", "645", "71u", "4k2", "5nr", "8Le", "fO", "29f", "0HM", "47k", "7Va", "6hl", "5Mn", "P2", "ES", + "JR", "1yA", "4RN", "6gm", "6IA", "48j", "0GL", "26g", "iN", "8Cd", "45Z", "4d3", "hYv", "beM", "0dP", "Gb", + "6VY", "4cz", "0XT", "0M5", "UJ", "02p", "4MV", "4X7", "61M", "5PG", "1ki", "Xz", "vV", "c7", "4nJ", "7KH", + "6Th", "4aK", "l6", "yW", "2Aj", "00A", "4Og", "6zD", "4W6", "4BW", "0yy", "ZK", "0o", "0WU", "58R", "6YX", + "46q", "531", "je", "0IW", "13R", "A", "4I4", "5Lt", "4Qe", "6dF", "Iy", "0jK", "r4", "gU", "6Jj", "5oh", + "4pH", "6Ek", "hT", "0Kf", "0eJ", "Fx", "6kG", "5NE", "4ST", "4F5", "KH", "0hz", "0FV", "ed", "5x8", "49p", + "bvs", "6yc", "2BM", "03f", "0YB", "zp", "6WO", "4bl", "bUo", "a4e", "3H", "0Tr", "87N", "Yl", "5D0", "4Ap", + "4Nq", "5K1", "Vm", "01W", "1KR", "xA", "414", "54t", "4mm", "6XN", "1y", "0VC", "0xo", "2ML", "62j", "4CA", + "7xA", "5Mb", "0fm", "2SN", "ks", "0HA", "47g", "6FL", "aan", "bDl", "0Eq", "fC", "Ho", "8bE", "4Ps", "5U3", + "5Z2", "5OS", "10u", "Gn", "iB", "0Jp", "45V", "ano", "6IM", "48f", "1Wa", "dr", "3Ln", "0il", "4RB", "6ga", + "2R", "0Uh", "4nF", "7KD", "61A", "5PK", "1ke", "Xv", "UF", "0vt", "4MZ", "6xy", "5f6", "4cv", "0XX", "0M9", + "0c", "0WY", "4lw", "5i7", "63p", "5Rz", "0yu", "ZG", "Ww", "00M", "4Ok", "6zH", "6Td", "4aG", "0Zi", "2oJ", + "60", "gY", "6Jf", "5od", "4Qi", "6dJ", "Iu", "0jG", "0gw", "M", "4I8", "5Lx", "4ru", "5w5", "ji", "1Yz", + "0FZ", "eh", "5x4", "5mU", "4SX", "4F9", "KD", "0hv", "0eF", "Ft", "6kK", "5NI", "44L", "6Eg", "hX", "91", + "0YF", "zt", "6WK", "4bh", "4LD", "6yg", "TX", "A9", "0zZ", "Yh", "5D4", "4At", "4oX", "4z9", "3L", "0Tv", + "1KV", "xE", "410", "54p", "4Nu", "5K5", "Vi", "01S", "N8", "2MH", "62n", "4CE", "4mi", "6XJ", "uu", "0VG", + "kw", "0HE", "47c", "6FH", "6hd", "5Mf", "0fi", "2SJ", "Hk", "0kY", "4Pw", "5U7", "6Kx", "5nz", "0Eu", "fG", + "iF", "0Jt", "45R", "6Dy", "5Z6", "5OW", "0dX", "Gj", "JZ", "0ih", "4RF", "6ge", "6II", "48b", "0GD", "dv", + "61E", "5PO", "1ka", "Xr", "2V", "0Ul", "4nB", "aqs", "5f2", "4cr", "8QD", "39V", "UB", "02x", "795", "aRo", + "63t", "764", "0yq", "ZC", "0g", "9Nd", "4ls", "5i3", "7DA", "4aC", "0Zm", "2oN", "Ws", "00I", "4Oo", "6zL", + "4Qm", "6dN", "Iq", "0jC", "64", "25D", "6Jb", "bEr", "46y", "539", "jm", "9Pf", "0gs", "I", "aCl", "bfn", + "bio", "72V", "1m2", "0hr", "325", "el", "5x0", "49x", "44H", "6Ec", "3nl", "95", "0eB", "Fp", "6kO", "5NM", + "4mt", "5h4", "uh", "0VZ", "0xv", "2MU", "4V9", "4CX", "4Nh", "7kj", "Vt", "01N", "m9", "xX", "6Ug", "54m", + "4oE", "6Zf", "3Q", "b8", "0zG", "Yu", "60B", "4Ai", "4LY", "4Y8", "TE", "0ww", "1Iz", "zi", "5g5", "4bu", + "5y7", "5lV", "0GY", "dk", "JG", "0iu", "5Bz", "6gx", "6jH", "5OJ", "0dE", "Gw", "3ok", "82", "45O", "6Dd", + "6Ke", "5ng", "73", "fZ", "Hv", "0kD", "4Pj", "6eI", "6hy", "7m9", "0ft", "EF", "kj", "0HX", "4sv", "5v6", + "Wn", "00T", "4Or", "5J2", "407", "55w", "0Zp", "yB", "0z", "1Ga", "4ln", "6YM", "63i", "4BB", "0yl", "2LO", + "2CN", "02e", "4MC", "7hA", "6VL", "4co", "0XA", "2mb", "2K", "0Uq", "bTl", "a5f", "5E3", "5PR", "86M", "Xo", + "11v", "Fm", "6kR", "5NP", "44U", "aol", "hA", "0Ks", "0FC", "eq", "6HN", "49e", "4SA", "6fb", "3Mm", "0ho", + "0gn", "T", "6ic", "5La", "46d", "6GO", "jp", "0IB", "0Dr", "1A2", "hyT", "bEo", "4Qp", "5T0", "Il", "8cF", + "0xr", "2MQ", "62w", "777", "4mp", "5h0", "1d", "9Og", "1KO", "2nM", "6Uc", "54i", "4Nl", "7kn", "Vp", "01J", + "0zC", "Yq", "60F", "4Am", "4oA", "6Zb", "3U", "0To", "8PG", "zm", "5g1", "4bq", "786", "aSl", "TA", "0ws", + "JC", "0iq", "bhl", "73U", "5y3", "5lR", "336", "do", "3oo", "86", "45K", "7TA", "6jL", "5ON", "0dA", "Gs", + "Hr", "8bX", "4Pn", "6eM", "6Ka", "5nc", "77", "24G", "kn", "8AD", "47z", "5v2", "aBo", "bgm", "0fp", "EB", + "403", "4aZ", "0Zt", "yF", "Wj", "00P", "4Ov", "5J6", "63m", "4BF", "0yh", "ZZ", "tv", "0WD", "4lj", "6YI", + "6VH", "4ck", "0XE", "2mf", "2CJ", "02a", "4MG", "6xd", "5E7", "5PV", "1kx", "Xk", "2O", "0Uu", "bTh", "7KY", + "44Q", "4e8", "hE", "0Kw", "11r", "Fi", "6kV", "5NT", "4SE", "6ff", "KY", "0hk", "0FG", "eu", "6HJ", "49a", + "4rh", "6GK", "jt", "0IF", "Q9", "P", "6ig", "5Le", "4Qt", "5T4", "Ih", "0jZ", "0Dv", "gD", "4j9", "5oy", + "aD0", "7kb", "3PL", "01F", "m1", "xP", "6Uo", "54e", "59U", "a6E", "1h", "0VR", "85n", "196", "4V1", "4CP", + "4LQ", "4Y0", "TM", "03w", "0YS", "za", "a9D", "56T", "4oM", "6Zn", "3Y", "b0", "0zO", "2Ol", "60J", "4Aa", + "7za", "5OB", "0dM", "2Qn", "iS", "0Ja", "45G", "6Dl", "acN", "48w", "0GQ", "dc", "JO", "94L", "4RS", "4G2", + "4H3", "5Ms", "12U", "EN", "kb", "0HP", "47v", "526", "6Km", "5no", "s3", "fR", "3NN", "0kL", "4Pb", "6eA", + "0r", "0WH", "4lf", "6YE", "63a", "4BJ", "O7", "ZV", "Wf", "0tT", "4Oz", "6zY", "4t7", "4aV", "0Zx", "yJ", + "2C", "0Uy", "4nW", "7KU", "61P", "5PZ", "1kt", "Xg", "UW", "02m", "4MK", "6xh", "6VD", "4cg", "0XI", "2mj", + "0FK", "ey", "6HF", "49m", "4SI", "6fj", "KU", "0hg", "0eW", "Fe", "6kZ", "5NX", "4pU", "4e4", "hI", "2k9", + "0Dz", "gH", "4j5", "5ou", "4Qx", "5T8", "Id", "0jV", "Q5", "DT", "6ik", "5Li", "46l", "6GG", "jx", "0IJ", + "m5", "xT", "6Uk", "54a", "4Nd", "7kf", "Vx", "01B", "0xz", "192", "4V5", "4CT", "4mx", "5h8", "1l", "0VV", + "0YW", "ze", "5g9", "4by", "4LU", "4Y4", "TI", "03s", "0zK", "Yy", "60N", "4Ae", "4oI", "6Zj", "wU", "b4", + "iW", "0Je", "45C", "6Dh", "6jD", "5OF", "0dI", "2Qj", "JK", "0iy", "4RW", "4G6", "6IX", "48s", "0GU", "dg", + "kf", "0HT", "47r", "522", "4H7", "5Mw", "0fx", "EJ", "Hz", "0kH", "4Pf", "6eE", "6Ki", "5nk", "s7", "fV", + "63e", "4BN", "O3", "ZR", "0v", "0WL", "4lb", "6YA", "4t3", "4aR", "8Sd", "yN", "Wb", "00X", "b1E", "aPO", + "61T", "bzL", "1kp", "Xc", "2G", "217", "4nS", "7KQ", "7Fa", "4cc", "0XM", "2mn", "US", "02i", "4MO", "6xl", + "4SM", "6fn", "KQ", "0hc", "0FO", "27d", "6HB", "49i", "44Y", "4e0", "hM", "8Bg", "0eS", "Fa", "aAL", "bdN", + "656", "70v", "3OP", "0jR", "8Mf", "gL", "4j1", "5oq", "46h", "6GC", "28e", "0IN", "Q1", "X", "6io", "5Lm", + "6KV", "5nT", "1Uz", "fi", "HE", "0kw", "4PY", "4E8", "6hJ", "5MH", "0fG", "Eu", "kY", "0Hk", "47M", "6Ff", + "6Ig", "48L", "51", "dX", "Jt", "0iF", "4Rh", "6gK", "4J9", "5Oy", "0dv", "GD", "ih", "0JZ", "4qt", "5t4", + "4ov", "5j6", "3b", "0TX", "0zt", "YF", "60q", "4AZ", "4Lj", "6yI", "Tv", "03L", "0Yh", "zZ", "6We", "4bF", + "4mG", "6Xd", "1S", "0Vi", "0xE", "2Mf", "6vH", "4Ck", "bth", "7kY", "VG", "0uu", "1Kx", "xk", "5e7", "5pV", + "13t", "g", "5Y3", "5LR", "46W", "amn", "jC", "0Iq", "0DA", "gs", "6JL", "5oN", "4QC", "70I", "3Oo", "0jm", + "0el", "2PO", "6ka", "5Nc", "44f", "6EM", "hr", "8BX", "0Fp", "eB", "abo", "49V", "4Sr", "5V2", "Kn", "8aD", + "Ul", "02V", "4Mp", "5H0", "425", "57u", "0Xr", "2mQ", "2x", "0UB", "4nl", "7Kn", "61k", "5Pa", "1kO", "2NM", + "2AL", "00g", "4OA", "6zb", "6TN", "4am", "0ZC", "yq", "0I", "0Ws", "58t", "a7d", "5G1", "4Bq", "84O", "Zm", + "HA", "0ks", "bjn", "71W", "6KR", "5nP", "314", "fm", "29D", "0Ho", "47I", "6Fb", "6hN", "5ML", "0fC", "Eq", + "Jp", "0iB", "4Rl", "6gO", "6Ic", "48H", "55", "26E", "il", "8CF", "45x", "508", "hYT", "beo", "0dr", "1a2", + "0zp", "YB", "60u", "755", "4or", "5j2", "3f", "9Me", "0Yl", "2lO", "6Wa", "4bB", "4Ln", "6yM", "Tr", "03H", + "0xA", "2Mb", "62D", "4Co", "4mC", "7HA", "1W", "0Vm", "8RE", "xo", "5e3", "54Z", "b0d", "aQn", "VC", "01y", + "46S", "6Gx", "jG", "0Iu", "0gY", "c", "5Y7", "5LV", "4QG", "6dd", "3Ok", "0ji", "0DE", "gw", "6JH", "5oJ", + "44b", "6EI", "hv", "0KD", "0eh", "FZ", "6ke", "5Ng", "4Sv", "5V6", "Kj", "0hX", "0Ft", "eF", "6Hy", "49R", + "421", "4cX", "0Xv", "2mU", "Uh", "02R", "4Mt", "5H4", "61o", "5Pe", "M9", "XX", "vt", "0UF", "4nh", "7Kj", + "6TJ", "4ai", "0ZG", "yu", "WY", "B8", "4OE", "6zf", "5G5", "4Bu", "1iz", "Zi", "0M", "0Ww", "4lY", "4y8", + "6hB", "aW1", "0fO", "2Sl", "kQ", "0Hc", "47E", "6Fn", "aaL", "bDN", "0ES", "fa", "HM", "8bg", "4PQ", "4E0", + "4J1", "5Oq", "10W", "GL", "3oP", "0JR", "45t", "504", "6Io", "48D", "59", "dP", "3LL", "0iN", "5BA", "6gC", + "4Lb", "6yA", "2Bo", "03D", "o3", "zR", "6Wm", "4bN", "bUM", "a4G", "3j", "0TP", "87l", "YN", "4T3", "4AR", + "4NS", "7kQ", "VO", "01u", "1Kp", "xc", "hfw", "54V", "4mO", "6Xl", "uS", "0Va", "0xM", "2Mn", "62H", "4Cc", + "0DI", "25b", "6JD", "5oF", "4QK", "6dh", "IW", "0je", "0gU", "o", "6iX", "5LZ", "4rW", "4g6", "jK", "0Iy", + "0Fx", "eJ", "4h7", "5mw", "4Sz", "6fY", "Kf", "0hT", "S7", "FV", "6ki", "5Nk", "44n", "6EE", "hz", "0KH", + "2p", "0UJ", "4nd", "7Kf", "61c", "5Pi", "M5", "XT", "Ud", "0vV", "4Mx", "5H8", "4v5", "4cT", "0Xz", "2mY", + "0A", "1GZ", "4lU", "4y4", "5G9", "4By", "0yW", "Ze", "WU", "B4", "4OI", "6zj", "6TF", "4ae", "0ZK", "yy", + "kU", "0Hg", "47A", "6Fj", "6hF", "5MD", "0fK", "Ey", "HI", "2K9", "4PU", "4E4", "6KZ", "5nX", "0EW", "fe", + "id", "0JV", "45p", "500", "4J5", "5Ou", "0dz", "GH", "Jx", "0iJ", "4Rd", "6gG", "6Ik", "5li", "q5", "dT", + "o7", "zV", "6Wi", "4bJ", "4Lf", "6yE", "Tz", "0wH", "0zx", "YJ", "4T7", "4AV", "4oz", "6ZY", "3n", "0TT", + "1Kt", "xg", "6UX", "54R", "4NW", "7kU", "VK", "01q", "0xI", "2Mj", "62L", "4Cg", "4mK", "6Xh", "uW", "0Ve", + "4QO", "6dl", "IS", "0ja", "0DM", "25f", "7Za", "5oB", "4rS", "4g2", "jO", "9PD", "0gQ", "k", "aCN", "685", + "674", "72t", "Kb", "0hP", "8Od", "eN", "4h3", "49Z", "44j", "6EA", "3nN", "0KL", "S3", "FR", "6km", "5No", + "61g", "5Pm", "M1", "XP", "2t", "0UN", "ad0", "7Kb", "429", "4cP", "8Qf", "39t", "0c3", "02Z", "b3G", "aRM", + "63V", "bxN", "0yS", "Za", "0E", "235", "4lQ", "4y0", "6TB", "4aa", "0ZO", "2ol", "WQ", "B0", "4OM", "6zn", + "4i4", "5lt", "1WZ", "dI", "Je", "0iW", "4Ry", "5W9", "6jj", "5Oh", "R4", "GU", "iy", "0JK", "45m", "6DF", + "6KG", "5nE", "0EJ", "fx", "HT", "0kf", "4PH", "6ek", "5X8", "5MY", "0fV", "Ed", "kH", "0Hz", "4sT", "4f5", + "4mV", "4x7", "1B", "0Vx", "0xT", "0m5", "62Q", "4Cz", "4NJ", "7kH", "VV", "C7", "1Ki", "xz", "6UE", "54O", + "4og", "6ZD", "3s", "0TI", "L6", "YW", "6th", "4AK", "6l9", "6yX", "Tg", "0wU", "0Yy", "zK", "4w6", "4bW", + "11T", "FO", "4K2", "5Nr", "44w", "517", "hc", "0KQ", "p2", "eS", "6Hl", "49G", "4Sc", "72i", "3MO", "0hM", + "0gL", "v", "6iA", "5LC", "46F", "6Gm", "jR", "1YA", "0DP", "gb", "hyv", "bEM", "4QR", "4D3", "IN", "8cd", + "WL", "00v", "4OP", "4Z1", "hgt", "55U", "0ZR", "0O3", "0X", "a1", "4lL", "6Yo", "63K", "5RA", "0yN", "2Lm", + "2Cl", "02G", "4Ma", "6xB", "6Vn", "4cM", "n0", "39i", "2i", "0US", "bTN", "a5D", "4U0", "5Pp", "86o", "XM", + "Ja", "0iS", "667", "73w", "4i0", "48Y", "8Ng", "dM", "3oM", "0JO", "45i", "6DB", "6jn", "5Ol", "R0", "GQ", + "HP", "0kb", "4PL", "6eo", "6KC", "5nA", "0EN", "24e", "kL", "8Af", "47X", "4f1", "aBM", "696", "0fR", "0s3", + "0xP", "0m1", "62U", "byM", "4mR", "4x3", "1F", "226", "1Km", "2no", "6UA", "54K", "4NN", "7kL", "VR", "C3", + "L2", "YS", "60d", "4AO", "4oc", "7Ja", "3w", "0TM", "8Pe", "zO", "4w2", "4bS", "b2D", "aSN", "Tc", "03Y", + "44s", "513", "hg", "0KU", "0ey", "FK", "4K6", "5Nv", "4Sg", "6fD", "3MK", "0hI", "p6", "eW", "6Hh", "49C", + "46B", "6Gi", "jV", "0Id", "0gH", "r", "6iE", "5LG", "4QV", "4D7", "IJ", "0jx", "0DT", "gf", "6JY", "bEI", + "5d8", "4ax", "0ZV", "yd", "WH", "00r", "4OT", "4Z5", "63O", "4Bd", "0yJ", "Zx", "tT", "a5", "4lH", "6Yk", + "6Vj", "4cI", "n4", "2mD", "Uy", "02C", "4Me", "6xF", "4U4", "5Pt", "1kZ", "XI", "2m", "0UW", "4ny", "5k9", + "6jb", "ber", "0do", "2QL", "iq", "0JC", "45e", "6DN", "acl", "48U", "0Gs", "dA", "Jm", "94n", "4Rq", "5W1", + "5X0", "5MQ", "12w", "El", "1M2", "0Hr", "47T", "alm", "6KO", "5nM", "0EB", "fp", "3Nl", "0kn", "bjs", "6ec", + "4NB", "aQs", "3Pn", "01d", "1Ka", "xr", "6UM", "54G", "59w", "a6g", "1J", "0Vp", "85L", "d3D", "5F2", "4Cr", + "4Ls", "5I3", "To", "03U", "0Yq", "zC", "436", "56v", "4oo", "6ZL", "ws", "0TA", "0zm", "2ON", "60h", "4AC", + "42", "27B", "6Hd", "49O", "4Sk", "6fH", "Kw", "0hE", "0eu", "FG", "6kx", "5Nz", "4pw", "5u7", "hk", "0KY", + "0DX", "gj", "5z6", "5oW", "4QZ", "6dy", "IF", "0jt", "0gD", "Dv", "6iI", "5LK", "46N", "6Ge", "jZ", "0Ih", + "0P", "a9", "4lD", "6Yg", "63C", "4Bh", "0yF", "Zt", "WD", "0tv", "4OX", "4Z9", "5d4", "4at", "0ZZ", "yh", + "2a", "1Ez", "4nu", "5k5", "4U8", "5Px", "1kV", "XE", "Uu", "02O", "4Mi", "6xJ", "6Vf", "4cE", "n8", "2mH", + "iu", "0JG", "45a", "6DJ", "6jf", "5Od", "R8", "GY", "Ji", "1yz", "4Ru", "5W5", "4i8", "48Q", "0Gw", "dE", + "kD", "0Hv", "47P", "4f9", "5X4", "5MU", "0fZ", "Eh", "HX", "0kj", "4PD", "6eg", "6KK", "5nI", "0EF", "ft", + "1Ke", "xv", "6UI", "54C", "4NF", "7kD", "VZ", "0uh", "0xX", "0m9", "5F6", "4Cv", "4mZ", "6Xy", "1N", "0Vt", + "0Yu", "zG", "432", "56r", "4Lw", "5I7", "Tk", "03Q", "0zi", "2OJ", "60l", "4AG", "4ok", "6ZH", "ww", "0TE", + "4So", "6fL", "Ks", "0hA", "46", "27F", "7XA", "49K", "4ps", "5u3", "ho", "8BE", "0eq", "FC", "aAn", "bdl", + "bkm", "70T", "IB", "0jp", "307", "gn", "5z2", "5oS", "46J", "6Ga", "28G", "0Il", "13i", "z", "6iM", "5LO", + "63G", "4Bl", "0yB", "Zp", "0T", "0Wn", "58i", "6Yc", "5d0", "4ap", "8SF", "yl", "1q2", "00z", "b1g", "aPm", + "61v", "746", "1kR", "XA", "2e", "9Lf", "4nq", "5k1", "6Vb", "4cA", "0Xo", "2mL", "Uq", "02K", "4Mm", "6xN", + "8YG", "7e", "5n1", "4kq", "716", "64v", "2KP", "1nR", "07K", "Pq", "69F", "4Hm", "4fA", "6Sb", "2hL", "1MN", + "0Rn", "5T", "7LB", "5ya", "4Gl", "66G", "2Ia", "08J", "05z", "1t2", "aUm", "b4g", "4dp", "5a0", "8d", "8VF", + "bn", "357", "4zr", "6OQ", "75T", "bnm", "0op", "LB", "Ar", "16i", "4Yn", "6lM", "6Ba", "43J", "0Ll", "2yO", + "22F", "16", "4xC", "agr", "6cL", "4Vo", "0mA", "Ns", "CC", "14X", "bal", "aDn", "5p3", "4us", "8GE", "mo", + "5L7", "4Iw", "06Q", "Qk", "1Y5", "1LT", "53r", "462", "7Oi", "4jk", "0QE", "rw", "2JJ", "1oH", "4DG", "65l", + "7nD", "4KF", "0ph", "SZ", "2kg", "1Ne", "4ej", "6PI", "493", "4hZ", "0St", "4N", "0h9", "09P", "4Fv", "5C6", + "4Xt", "6mW", "023", "0cZ", "0Mv", "nD", "4c9", "42P", "5kI", "6NK", "ct", "1Pg", "X9", "MX", "74N", "4UD", + "4ZE", "6of", "BY", "W8", "0OG", "lu", "6AJ", "40a", "4yY", "4l8", "aE", "0Bw", "18r", "Oi", "5R5", "4Wu", + "4EY", "4P8", "2KT", "1nV", "8YC", "7a", "5n5", "4ku", "4fE", "6Sf", "2hH", "k8", "07O", "Pu", "69B", "4Hi", + "4Gh", "66C", "2Ie", "08N", "d9", "5P", "7LF", "4iD", "4dt", "5a4", "2jy", "3o9", "0qv", "RD", "7oZ", "4JX", + "6ay", "4TZ", "0ot", "LF", "bj", "0AX", "4zv", "6OU", "6Be", "43N", "0Lh", "oZ", "Av", "0bD", "4Yj", "6lI", + "6cH", "4Vk", "0mE", "Nw", "22B", "12", "4xG", "6Md", "5p7", "4uw", "0NY", "mk", "CG", "1pT", "5Kz", "6nx", + "1Y1", "1LP", "53v", "466", "5L3", "4Is", "06U", "Qo", "2JN", "1oL", "4DC", "65h", "7Om", "4jo", "0QA", "rs", + "9z", "1Na", "4en", "6PM", "aTs", "4KB", "04d", "2EO", "d6D", "09T", "4Fr", "5C2", "497", "bRm", "0Sp", "4J", + "0Mr", "1H2", "aim", "42T", "4Xp", "6mS", "027", "17w", "0nn", "3Kl", "74J", "5Ea", "5kM", "6NO", "cp", "1Pc", + "0OC", "lq", "6AN", "40e", "4ZA", "6ob", "2TL", "0ao", "18v", "Om", "5R1", "4Wq", "bCn", "afl", "aA", "0Bs", + "07C", "Py", "69N", "4He", "4fI", "6Sj", "2hD", "k4", "0PW", "7m", "5n9", "4ky", "4EU", "4P4", "2KX", "1nZ", + "05r", "RH", "7oV", "4JT", "4dx", "5a8", "8l", "1Ow", "d5", "qT", "7LJ", "4iH", "4Gd", "66O", "2Ii", "08B", + "Az", "0bH", "4Yf", "6lE", "6Bi", "43B", "z7", "oV", "bf", "0AT", "4zz", "6OY", "4A7", "4TV", "0ox", "LJ", + "CK", "14P", "5Kv", "4N6", "543", "41s", "0NU", "mg", "22N", "u6", "4xK", "6Mh", "6cD", "4Vg", "0mI", "2Xj", + "7Oa", "4jc", "0QM", "6w", "2JB", "I2", "4DO", "65d", "68T", "b7D", "06Y", "Qc", "dSm", "287", "4gS", "4r2", + "7MP", "4hR", "276", "4F", "0h1", "09X", "b8E", "67U", "7nL", "4KN", "F3", "SR", "9v", "1Nm", "4eb", "6PA", + "5kA", "6NC", "21e", "1Po", "X1", "MP", "74F", "4UL", "bbO", "79v", "0v3", "0cR", "8Df", "nL", "4c1", "42X", + "4yQ", "4l0", "aM", "8Kg", "0lS", "Oa", "76w", "637", "4ZM", "6on", "BQ", "W0", "0OO", "2zl", "6AB", "40i", + "4fM", "6Sn", "3xa", "k0", "07G", "2Fl", "69J", "4Ha", "4EQ", "4P0", "d5g", "83o", "0PS", "7i", "a0D", "bQN", + "50U", "hbt", "8h", "1Os", "05v", "RL", "7oR", "4JP", "5WA", "66K", "2Im", "08F", "d1", "5X", "7LN", "4iL", + "6Bm", "43F", "z3", "oR", "2Wo", "0bL", "4Yb", "6lA", "4A3", "4TR", "8fd", "LN", "bb", "0AP", "cPl", "aeO", + "547", "41w", "0NQ", "mc", "CO", "14T", "5Kr", "4N2", "77i", "4Vc", "0mM", "2Xn", "22J", "u2", "4xO", "6Ml", + "2JF", "I6", "4DK", "6qh", "7Oe", "4jg", "0QI", "6s", "1Y9", "1LX", "4gW", "4r6", "68P", "5YZ", "0rU", "Qg", + "0h5", "1mu", "4Fz", "67Q", "7MT", "4hV", "0Sx", "4B", "9r", "1Ni", "4ef", "6PE", "7nH", "4KJ", "F7", "SV", + "X5", "MT", "74B", "4UH", "5kE", "6NG", "cx", "1Pk", "0Mz", "nH", "4c5", "4vT", "4Xx", "79r", "0v7", "0cV", + "0lW", "Oe", "5R9", "4Wy", "4yU", "4l4", "aI", "1RZ", "0OK", "ly", "6AF", "40m", "4ZI", "6oj", "BU", "W4", + "265", "5E", "488", "4iQ", "b9F", "66V", "0i2", "1lr", "G0", "RQ", "7oO", "4JM", "4da", "6QB", "8u", "1On", + "0PN", "7t", "7Nb", "aa0", "4EL", "64g", "2KA", "H1", "07Z", "0f3", "69W", "b6G", "4fP", "479", "dRn", "294", + "22W", "8Jd", "4xR", "4m3", "77t", "624", "0mP", "Nb", "CR", "V3", "5Ko", "6nm", "ajS", "41j", "0NL", "3kN", + "20f", "0AM", "4zc", "aeR", "6al", "4TO", "Y2", "LS", "Ac", "0bQ", "bcL", "78u", "4b2", "4wS", "8Ee", "oO", + "7nU", "4KW", "04q", "SK", "9o", "1Nt", "51R", "6PX", "7MI", "4hK", "e6", "pW", "2Hj", "09A", "4Fg", "67L", + "68M", "4If", "0rH", "Qz", "2iG", "j7", "4gJ", "6Ri", "7Ox", "4jz", "0QT", "6n", "1z8", "1oY", "4DV", "4Q7", + "4ZT", "4O5", "BH", "0az", "0OV", "ld", "550", "40p", "4yH", "6Lk", "aT", "t5", "0lJ", "Ox", "6bG", "4Wd", + "4Xe", "6mF", "2Vh", "0cK", "0Mg", "nU", "6Cj", "42A", "5kX", "6NZ", "ce", "1Pv", "2N9", "MI", "7pW", "4UU", + "4Gy", "5B9", "0i6", "1lv", "1BZ", "5A", "7LW", "4iU", "4de", "6QF", "8q", "1Oj", "G4", "RU", "7oK", "4JI", + "4EH", "64c", "2KE", "H5", "0PJ", "7p", "7Nf", "4kd", "4fT", "4s5", "2hY", "290", "0sV", "Pd", "5M8", "4Hx", + "6cY", "4Vz", "0mT", "Nf", "1F8", "0Cx", "4xV", "4m7", "7Pd", "41n", "0NH", "mz", "CV", "V7", "5Kk", "6ni", + "6ah", "4TK", "Y6", "LW", "20b", "0AI", "4zg", "6OD", "4b6", "4wW", "0Ly", "oK", "Ag", "0bU", "5IZ", "6lX", + "9k", "1Np", "51V", "azN", "7nQ", "4KS", "04u", "SO", "2Hn", "09E", "4Fc", "67H", "7MM", "4hO", "e2", "pS", + "2iC", "j3", "4gN", "6Rm", "68I", "4Ib", "06D", "2Go", "d4d", "82l", "4DR", "4Q3", "a1G", "bPM", "0QP", "6j", + "0OR", "0Z3", "554", "40t", "4ZP", "4O1", "BL", "15W", "0lN", "2Ym", "6bC", "5GA", "4yL", "6Lo", "aP", "09", + "0Mc", "nQ", "6Cn", "42E", "4Xa", "6mB", "2Vl", "0cO", "8gg", "MM", "7pS", "4UQ", "bAN", "adL", "ca", "1Pr", + "G8", "RY", "7oG", "4JE", "4di", "6QJ", "2jd", "1Of", "0Rw", "5M", "480", "4iY", "4Gu", "5B5", "2Ix", "08S", + "07R", "Ph", "5M4", "4Ht", "4fX", "471", "1X6", "1MW", "0PF", "st", "7Nj", "4kh", "4ED", "64o", "2KI", "H9", + "CZ", "14A", "5Kg", "6ne", "7Ph", "41b", "0ND", "mv", "1F4", "0Ct", "4xZ", "6My", "5S6", "4Vv", "0mX", "Nj", + "Ak", "0bY", "4Yw", "6lT", "6Bx", "43S", "0Lu", "oG", "bw", "0AE", "4zk", "6OH", "6ad", "4TG", "0oi", "2ZJ", + "7MA", "4hC", "0Sm", "4W", "2Hb", "09I", "4Fo", "67D", "aTn", "b5d", "04y", "SC", "9g", "8WE", "4es", "6PP", + "5o2", "4jr", "8XD", "6f", "1z0", "1oQ", "705", "65u", "68E", "4In", "06H", "Qr", "2iO", "1LM", "4gB", "6Ra", + "5ia", "6Lc", "23E", "05", "0lB", "Op", "6bO", "4Wl", "c4F", "aEm", "1d2", "0ar", "8FF", "ll", "558", "40x", + "5kP", "6NR", "cm", "344", "0ns", "MA", "74W", "bon", "4Xm", "6mN", "3FA", "0cC", "0Mo", "2xL", "6Cb", "42I", + "4dm", "6QN", "8y", "1Ob", "05g", "2DL", "7oC", "4JA", "4Gq", "5B1", "d7G", "08W", "0Rs", "5I", "484", "bSn", + "52u", "475", "1X2", "1MS", "07V", "Pl", "5M0", "4Hp", "5Ua", "64k", "2KM", "1nO", "0PB", "7x", "7Nn", "4kl", + "7Pl", "41f", "8GX", "mr", "2UO", "14E", "5Kc", "6na", "5S2", "4Vr", "19u", "Nn", "1F0", "0Cp", "bBm", "ago", + "ahn", "43W", "0Lq", "oC", "Ao", "16t", "4Ys", "6lP", "75I", "4TC", "0om", "2ZN", "bs", "0AA", "4zo", "6OL", + "2Hf", "09M", "4Fk", "6sH", "7ME", "4hG", "0Si", "4S", "9c", "1Nx", "4ew", "6PT", "7nY", "bqh", "0pu", "SG", + "1z4", "1oU", "4DZ", "65q", "5o6", "4jv", "0QX", "6b", "2iK", "1LI", "4gF", "6Re", "68A", "4Ij", "06L", "Qv", + "0lF", "Ot", "6bK", "4Wh", "4yD", "6Lg", "aX", "01", "0OZ", "lh", "5q4", "4tt", "4ZX", "4O9", "BD", "0av", + "0nw", "ME", "74S", "4UY", "5kT", "6NV", "ci", "1Pz", "0Mk", "nY", "6Cf", "42M", "4Xi", "6mJ", "2Vd", "0cG", + "bL", "8Hf", "4zP", "4o1", "75v", "606", "0oR", "0z3", "AP", "T1", "4YL", "6lo", "6BC", "43h", "0LN", "2ym", + "22d", "0CO", "4xa", "6MB", "6cn", "4VM", "0mc", "NQ", "Ca", "14z", "baN", "aDL", "7PS", "41Y", "8Gg", "mM", + "247", "7G", "7NQ", "4kS", "com", "64T", "0k0", "1np", "E2", "PS", "69d", "4HO", "4fc", "7Ca", "2hn", "1Ml", + "0RL", "5v", "avS", "4ib", "4GN", "66e", "2IC", "J3", "05X", "Rb", "aUO", "b4E", "4dR", "4q3", "8F", "8Vd", + "4XV", "4M7", "1f8", "0cx", "0MT", "nf", "572", "42r", "5kk", "6Ni", "cV", "v7", "0nH", "Mz", "74l", "4Uf", + "4Zg", "6oD", "2Tj", "0aI", "y6", "lW", "6Ah", "40C", "5iZ", "583", "ag", "0BU", "0ly", "OK", "4B6", "4WW", + "7lW", "4IU", "06s", "QI", "0I6", "1Lv", "4gy", "5b9", "7OK", "4jI", "g4", "rU", "2Jh", "1oj", "4De", "65N", + "7nf", "4Kd", "04B", "Sx", "2kE", "h5", "4eH", "6Pk", "5m8", "4hx", "0SV", "4l", "2HY", "09r", "4FT", "4S5", + "5Q8", "4Tx", "0oV", "Ld", "bH", "0Az", "4zT", "4o5", "6BG", "43l", "0LJ", "ox", "AT", "T5", "4YH", "6lk", + "6cj", "4VI", "0mg", "NU", "2vh", "0CK", "4xe", "6MF", "7PW", "4uU", "2n9", "mI", "Ce", "1pv", "5KX", "6nZ", + "5UZ", "64P", "0k4", "1nt", "0Py", "7C", "7NU", "4kW", "4fg", "6SD", "2hj", "1Mh", "E6", "PW", "7mI", "4HK", + "4GJ", "66a", "2IG", "J7", "0RH", "5r", "7Ld", "4if", "4dV", "4q7", "8B", "1OY", "0qT", "Rf", "7ox", "4Jz", + "0MP", "nb", "576", "42v", "4XR", "4M3", "dll", "17U", "0nL", "3KN", "74h", "4Ub", "5ko", "6Nm", "cR", "v3", + "y2", "lS", "6Al", "40G", "4Zc", "aER", "2Tn", "0aM", "18T", "OO", "4B2", "4WS", "bCL", "587", "ac", "0BQ", + "0I2", "1Lr", "53T", "axL", "68z", "4IQ", "06w", "QM", "2Jl", "1on", "4Da", "65J", "7OO", "4jM", "g0", "6Y", + "9X", "h1", "4eL", "6Po", "7nb", "aA0", "04F", "2Em", "d6f", "09v", "4FP", "4S1", "a3E", "bRO", "0SR", "4h", + "AX", "T9", "4YD", "6lg", "6BK", "4wh", "0LF", "ot", "bD", "0Av", "4zX", "4o9", "5Q4", "4Tt", "0oZ", "Lh", + "Ci", "14r", "5KT", "6nV", "ajh", "41Q", "0Nw", "mE", "22l", "0CG", "4xi", "6MJ", "6cf", "4VE", "0mk", "NY", + "07a", "2FJ", "69l", "4HG", "4fk", "6SH", "2hf", "1Md", "0Pu", "7O", "7NY", "bQh", "4Ew", "6pT", "0k8", "1nx", + "05P", "Rj", "5O6", "4Jv", "4dZ", "453", "8N", "1OU", "0RD", "qv", "7Lh", "4ij", "4GF", "66m", "2IK", "1lI", + "5kc", "6Na", "21G", "27", "8gX", "Mr", "74d", "4Un", "bbm", "79T", "1f0", "0cp", "397", "nn", "5s2", "42z", + "4ys", "6LP", "ao", "366", "0lq", "OC", "76U", "bml", "4Zo", "6oL", "Bs", "0aA", "0Om", "2zN", "7QA", "40K", + "7OC", "4jA", "0Qo", "6U", "3ZA", "1ob", "4Dm", "65F", "68v", "b7f", "0rs", "QA", "dSO", "8UG", "4gq", "5b1", + "5m0", "4hp", "8ZF", "4d", "1x2", "09z", "727", "67w", "7nn", "4Kl", "04J", "Sp", "9T", "1NO", "51i", "6Pc", + "6BO", "43d", "0LB", "op", "2WM", "0bn", "5Ia", "6lc", "5Q0", "4Tp", "8fF", "Ll", "1D2", "0Ar", "cPN", "aem", + "ajl", "41U", "0Ns", "mA", "Cm", "14v", "5KP", "6nR", "6cb", "4VA", "0mo", "2XL", "22h", "0CC", "4xm", "6MN", + "4fo", "6SL", "2hb", "8TY", "07e", "2FN", "69h", "4HC", "4Es", "64X", "d5E", "83M", "0Pq", "7K", "a0f", "bQl", + "50w", "457", "8J", "1OQ", "05T", "Rn", "5O2", "4Jr", "4GB", "66i", "2IO", "08d", "1Ba", "5z", "7Ll", "4in", + "0nD", "Mv", "7ph", "4Uj", "5kg", "6Ne", "cZ", "23", "0MX", "nj", "5s6", "4vv", "4XZ", "6my", "1f4", "0ct", + "0lu", "OG", "6bx", "5Gz", "4yw", "6LT", "ak", "0BY", "0Oi", "2zJ", "6Ad", "40O", "4Zk", "6oH", "Bw", "0aE", + "2Jd", "1of", "4Di", "65B", "7OG", "4jE", "g8", "6Q", "2ix", "1Lz", "4gu", "5b5", "68r", "4IY", "0rw", "QE", + "1x6", "1mW", "4FX", "4S9", "5m4", "4ht", "0SZ", "ph", "9P", "h9", "4eD", "6Pg", "7nj", "4Kh", "04N", "St", + "22u", "375", "4xp", "598", "77V", "blo", "0mr", "1h2", "Cp", "14k", "5KM", "6nO", "7PB", "41H", "0Nn", "3kl", + "20D", "34", "4zA", "6Ob", "6aN", "4Tm", "0oC", "Lq", "AA", "0bs", "bcn", "78W", "569", "43y", "384", "om", + "9Kd", "5g", "5l3", "4is", "734", "66t", "1y1", "08y", "05I", "Rs", "7om", "4Jo", "4dC", "7AA", "8W", "1OL", + "0Pl", "7V", "ats", "4kB", "4En", "64E", "2Kc", "1na", "07x", "PB", "69u", "b6e", "4fr", "5c2", "dRL", "8TD", + "4Zv", "6oU", "Bj", "0aX", "0Ot", "lF", "6Ay", "40R", "4yj", "6LI", "av", "0BD", "0lh", "OZ", "6be", "4WF", + "4XG", "6md", "2VJ", "0ci", "0ME", "nw", "6CH", "42c", "5kz", "6Nx", "cG", "1PT", "0nY", "Mk", "5P7", "4Uw", + "5N5", "4Ku", "04S", "Si", "9M", "1NV", "4eY", "440", "7Mk", "4hi", "0SG", "pu", "2HH", "K8", "4FE", "67n", + "68o", "4ID", "1", "QX", "2ie", "1Lg", "4gh", "6RK", "7OZ", "4jX", "0Qv", "6L", "2Jy", "3O9", "4Dt", "5A4", + "4C9", "4VX", "0mv", "ND", "22q", "0CZ", "4xt", "6MW", "7PF", "41L", "x9", "mX", "Ct", "14o", "5KI", "6nK", + "6aJ", "4Ti", "0oG", "Lu", "bY", "30", "4zE", "6Of", "5r5", "4wu", "380", "oi", "AE", "0bw", "4YY", "4L8", + "5Wz", "66p", "1y5", "1lT", "0RY", "5c", "5l7", "4iw", "4dG", "6Qd", "8S", "1OH", "05M", "Rw", "7oi", "4Jk", + "4Ej", "64A", "2Kg", "1ne", "0Ph", "7R", "7ND", "4kF", "4fv", "5c6", "0H9", "1My", "0st", "PF", "69q", "4HZ", + "0Op", "lB", "ako", "40V", "4Zr", "6oQ", "Bn", "15u", "0ll", "2YO", "6ba", "4WB", "4yn", "6LM", "ar", "1Ra", + "0MA", "ns", "6CL", "42g", "4XC", "79I", "2VN", "0cm", "8gE", "Mo", "5P3", "4Us", "bAl", "adn", "cC", "1PP", + "9I", "1NR", "51t", "444", "5N1", "4Kq", "04W", "Sm", "2HL", "09g", "4FA", "67j", "7Mo", "4hm", "0SC", "4y", + "2ia", "1Lc", "4gl", "6RO", "68k", "5Ya", "5", "2GM", "d4F", "82N", "4Dp", "5A0", "a1e", "bPo", "0Qr", "6H", + "Cx", "14c", "5KE", "6nG", "7PJ", "4uH", "x5", "mT", "0V7", "0CV", "4xx", "590", "4C5", "4VT", "0mz", "NH", + "AI", "16R", "4YU", "4L4", "561", "43q", "0LW", "oe", "bU", "w4", "4zI", "6Oj", "6aF", "4Te", "0oK", "Ly", + "05A", "2Dj", "7oe", "4Jg", "4dK", "6Qh", "2jF", "i6", "0RU", "5o", "7Ly", "5yZ", "4GW", "4R6", "1y9", "08q", + "07p", "PJ", "7mT", "4HV", "4fz", "6SY", "0H5", "1Mu", "f7", "sV", "7NH", "4kJ", "4Ef", "64M", "2Kk", "1ni", + "4yb", "6LA", "23g", "0BL", "Z3", "OR", "6bm", "4WN", "c4d", "aEO", "Bb", "0aP", "8Fd", "lN", "4a3", "40Z", + "5kr", "4n2", "cO", "8Ie", "0nQ", "Mc", "74u", "615", "4XO", "6ml", "2VB", "U2", "0MM", "2xn", "7Sa", "42k", + "7Mc", "4ha", "0SO", "4u", "3Xa", "K0", "4FM", "67f", "aTL", "b5F", "0pS", "Sa", "9E", "8Wg", "4eQ", "448", + "7OR", "4jP", "254", "6D", "0j3", "1os", "cnn", "65W", "68g", "4IL", "9", "QP", "2im", "1Lo", "53I", "6RC", + "7PN", "41D", "x1", "mP", "2Um", "14g", "5KA", "6nC", "4C1", "4VP", "19W", "NL", "0V3", "0CR", "bBO", "594", + "565", "43u", "0LS", "oa", "AM", "16V", "4YQ", "4L0", "6aB", "4Ta", "0oO", "2Zl", "bQ", "38", "4zM", "6On", + "4dO", "6Ql", "2jB", "i2", "05E", "2Dn", "7oa", "4Jc", "4GS", "4R2", "d7e", "08u", "0RQ", "5k", "a2F", "bSL", + "52W", "ayO", "0H1", "1Mq", "07t", "PN", "69y", "4HR", "4Eb", "64I", "2Ko", "1nm", "f3", "7Z", "7NL", "4kN", + "Z7", "OV", "6bi", "4WJ", "4yf", "6LE", "az", "0BH", "0Ox", "lJ", "4a7", "4tV", "4Zz", "6oY", "Bf", "0aT", + "0nU", "Mg", "74q", "5EZ", "5kv", "4n6", "cK", "1PX", "0MI", "2xj", "6CD", "42o", "4XK", "6mh", "2VF", "U6", + "2HD", "K4", "4FI", "67b", "7Mg", "4he", "0SK", "4q", "9A", "1NZ", "4eU", "4p4", "5N9", "4Ky", "0pW", "Se", + "0j7", "1ow", "4Dx", "5A8", "7OV", "4jT", "0Qz", "rH", "2ii", "1Lk", "4gd", "6RG", "68c", "4IH", "D5", "QT", + "5Ls", "4I3", "F", "13U", "0IP", "jb", "536", "46v", "5oo", "6Jm", "gR", "r3", "0jL", "3ON", "6dA", "4Qb", + "5NB", "aAR", "2Pn", "0eM", "0Ka", "hS", "6El", "44G", "49w", "abN", "ec", "0FQ", "8ae", "KO", "4F2", "4SS", + "4X0", "4MQ", "02w", "UM", "0M2", "0XS", "57T", "a8D", "7KO", "4nM", "c0", "2Y", "2Nl", "1kn", "aJ1", "61J", + "6zC", "aE0", "00F", "2Am", "yP", "l1", "4aL", "6To", "a7E", "58U", "0WR", "0h", "ZL", "84n", "4BP", "4W1", + "fH", "0Ez", "5nu", "4k5", "5U8", "4Px", "0kV", "Hd", "ET", "P5", "5Mi", "6hk", "6FG", "47l", "0HJ", "kx", + "dy", "0GK", "48m", "6IF", "6gj", "4RI", "0ig", "JU", "Ge", "0dW", "5OX", "5Z9", "4d4", "4qU", "1ZZ", "iI", + "0Ty", "3C", "4z6", "4oW", "5QZ", "60P", "Yg", "0zU", "A6", "TW", "6yh", "4LK", "4bg", "6WD", "2lj", "0YI", + "0VH", "1r", "6XE", "4mf", "4CJ", "62a", "2MG", "N7", "0uT", "Vf", "7kx", "4Nz", "5pw", "4u7", "xJ", "1KY", + "0IT", "jf", "532", "46r", "5Lw", "4I7", "B", "0gx", "0jH", "Iz", "6dE", "4Qf", "5ok", "6Ji", "gV", "r7", + "0Ke", "hW", "6Eh", "44C", "5NF", "6kD", "2Pj", "0eI", "0hy", "KK", "4F6", "4SW", "49s", "6HX", "eg", "0FU", + "0M6", "0XW", "4cy", "5f9", "4X4", "4MU", "02s", "UI", "Xy", "1kj", "5PD", "61N", "7KK", "4nI", "c4", "vU", + "yT", "l5", "4aH", "6Tk", "6zG", "4Od", "00B", "Wx", "ZH", "0yz", "4BT", "4W5", "5i8", "4lx", "0WV", "0l", + "71v", "646", "0kR", "3NP", "fL", "8Lf", "5nq", "4k1", "6FC", "47h", "0HN", "29e", "EP", "P1", "5Mm", "6ho", + "6gn", "4RM", "0ic", "JQ", "26d", "0GO", "48i", "6IB", "4d0", "45Y", "8Cg", "iM", "Ga", "0dS", "beN", "hYu", + "ckm", "60T", "Yc", "0zQ", "207", "3G", "4z2", "4oS", "4bc", "7Ga", "2ln", "0YM", "A2", "TS", "6yl", "4LO", + "4CN", "62e", "2MC", "N3", "0VL", "1v", "6XA", "4mb", "5ps", "4u3", "xN", "8Rd", "01X", "Vb", "aQO", "b0E", + "5og", "6Je", "gZ", "63", "0jD", "Iv", "6dI", "4Qj", "7l9", "6iy", "N", "0gt", "0IX", "jj", "5w6", "4rv", + "5mV", "5x7", "ek", "0FY", "0hu", "KG", "6fx", "5Cz", "5NJ", "6kH", "Fw", "0eE", "92", "3nk", "6Ed", "44O", + "7KG", "4nE", "c8", "2Q", "Xu", "1kf", "5PH", "61B", "4X8", "4MY", "0vw", "UE", "2mx", "1Hz", "4cu", "5f5", + "5i4", "4lt", "0WZ", "th", "ZD", "0yv", "4BX", "4W9", "6zK", "4Oh", "00N", "Wt", "yX", "l9", "4aD", "6Tg", + "2SM", "0fn", "5Ma", "6hc", "6FO", "47d", "0HB", "kp", "24Y", "0Er", "bDo", "aam", "5U0", "4Pp", "8bF", "Hl", + "Gm", "10v", "5OP", "5Z1", "anl", "45U", "0Js", "iA", "dq", "0GC", "48e", "6IN", "6gb", "4RA", "0io", "3Lm", + "03e", "2BN", "7iA", "4LC", "4bo", "6WL", "zs", "0YA", "0Tq", "3K", "a4f", "bUl", "4As", "5D3", "Yo", "87M", + "01T", "Vn", "5K2", "4Nr", "54w", "417", "xB", "1KQ", "1Fa", "1z", "6XM", "4mn", "4CB", "62i", "2MO", "0xl", + "1za", "Ir", "6dM", "4Qn", "5oc", "6Ja", "25G", "67", "9Pe", "jn", "5w2", "46z", "bfm", "aCo", "J", "0gp", + "0hq", "KC", "72U", "bil", "5mR", "5x3", "eo", "326", "96", "3no", "7UA", "44K", "5NN", "6kL", "Fs", "0eA", + "Xq", "1kb", "5PL", "61F", "7KC", "4nA", "0Uo", "2U", "39U", "8QG", "4cq", "5f1", "aRl", "796", "0vs", "UA", + "2LQ", "0yr", "767", "63w", "5i0", "4lp", "9Ng", "0d", "2oM", "0Zn", "55i", "6Tc", "6zO", "4Ol", "00J", "Wp", + "6FK", "4sh", "0HF", "kt", "EX", "P9", "5Me", "6hg", "5U4", "4Pt", "0kZ", "Hh", "fD", "0Ev", "5ny", "4k9", + "4d8", "45Q", "0Jw", "iE", "Gi", "10r", "5OT", "5Z5", "6gf", "4RE", "0ik", "JY", "du", "0GG", "48a", "6IJ", + "4bk", "6WH", "zw", "0YE", "03a", "2BJ", "6yd", "4LG", "4Aw", "5D7", "Yk", "0zY", "0Tu", "3O", "6Zx", "bUh", + "54s", "413", "xF", "1KU", "01P", "Vj", "5K6", "4Nv", "4CF", "62m", "2MK", "0xh", "0VD", "uv", "6XI", "4mj", + "5NS", "6kQ", "Fn", "11u", "0Kp", "hB", "aoo", "44V", "49f", "6HM", "er", "1Va", "0hl", "3Mn", "6fa", "4SB", + "5Lb", "7yA", "W", "0gm", "0IA", "js", "6GL", "46g", "bEl", "hyW", "gC", "0Dq", "8cE", "Io", "5T3", "4Qs", + "5J1", "4Oq", "00W", "Wm", "yA", "0Zs", "55t", "404", "6YN", "4lm", "0WC", "0y", "2LL", "0yo", "4BA", "63j", + "6xc", "bws", "02f", "2CM", "2ma", "0XB", "4cl", "6VO", "a5e", "bTo", "0Ur", "2H", "Xl", "86N", "5PQ", "5E0", + "dh", "0GZ", "5lU", "5y4", "4G9", "4RX", "0iv", "JD", "Gt", "0dF", "5OI", "6jK", "6Dg", "45L", "81", "iX", + "fY", "70", "5nd", "6Kf", "6eJ", "4Pi", "0kG", "Hu", "EE", "0fw", "5Mx", "4H8", "5v5", "4su", "1Xz", "ki", + "0VY", "1c", "5h7", "4mw", "5Sz", "62p", "2MV", "0xu", "01M", "Vw", "7ki", "4Nk", "54n", "6Ud", "2nJ", "1KH", + "0Th", "3R", "6Ze", "4oF", "4Aj", "60A", "Yv", "0zD", "0wt", "TF", "6yy", "4LZ", "4bv", "5g6", "zj", "0YX", + "0Kt", "hF", "6Ey", "44R", "5NW", "6kU", "Fj", "0eX", "0hh", "KZ", "6fe", "4SF", "49b", "6HI", "ev", "0FD", + "0IE", "jw", "6GH", "46c", "5Lf", "6id", "S", "0gi", "0jY", "Ik", "5T7", "4Qw", "5oz", "6Jx", "gG", "0Du", + "yE", "0Zw", "4aY", "400", "5J5", "4Ou", "00S", "Wi", "ZY", "O8", "4BE", "63n", "6YJ", "4li", "0WG", "tu", + "2me", "0XF", "4ch", "6VK", "6xg", "4MD", "02b", "UX", "Xh", "3K9", "5PU", "5E4", "7KZ", "4nX", "0Uv", "2L", + "73V", "bho", "0ir", "1l2", "dl", "335", "48x", "5y0", "6Dc", "45H", "85", "3ol", "Gp", "0dB", "5OM", "6jO", + "6eN", "4Pm", "0kC", "Hq", "24D", "74", "bDr", "6Kb", "529", "47y", "8AG", "km", "EA", "0fs", "bgn", "aBl", + "774", "62t", "199", "0xq", "9Od", "1g", "5h3", "4ms", "54j", "7EA", "2nN", "1KL", "01I", "Vs", "7km", "4No", + "4An", "60E", "Yr", "1ja", "0Tl", "3V", "6Za", "4oB", "4br", "5g2", "zn", "8PD", "03x", "TB", "aSo", "785", + "49n", "6HE", "ez", "0FH", "0hd", "KV", "6fi", "4SJ", "bdI", "6kY", "Ff", "0eT", "0Kx", "hJ", "4e7", "4pV", + "5ov", "4j6", "gK", "0Dy", "0jU", "Ig", "6dX", "5AZ", "5Lj", "6ih", "DW", "Q6", "0II", "28b", "6GD", "46o", + "6YF", "4le", "0WK", "0q", "ZU", "O4", "4BI", "63b", "5J9", "4Oy", "0tW", "We", "yI", "1JZ", "4aU", "4t4", + "7KV", "4nT", "0Uz", "vH", "Xd", "1kw", "5PY", "5E8", "6xk", "4MH", "02n", "UT", "2mi", "0XJ", "4cd", "6VG", + "2Qm", "0dN", "5OA", "6jC", "6Do", "45D", "89", "iP", "0R3", "0GR", "48t", "acM", "4G1", "4RP", "94O", "JL", + "EM", "12V", "5Mp", "4H0", "525", "47u", "0HS", "ka", "fQ", "78", "5nl", "6Kn", "6eB", "4Pa", "0kO", "3NM", + "01E", "3PO", "7ka", "4Nc", "54f", "6Ul", "xS", "m2", "0VQ", "1k", "a6F", "59V", "4CS", "4V2", "195", "85m", + "03t", "TN", "4Y3", "4LR", "56W", "a9G", "zb", "0YP", "b3", "3Z", "6Zm", "4oN", "4Ab", "60I", "2Oo", "0zL", + "1xA", "KR", "6fm", "4SN", "49j", "6HA", "27g", "0FL", "8Bd", "hN", "4e3", "44Z", "bdM", "aAO", "Fb", "0eP", + "0jQ", "Ic", "70u", "655", "5or", "4j2", "gO", "8Me", "0IM", "28f", "7Wa", "46k", "5Ln", "6il", "DS", "Q2", + "ZQ", "O0", "4BM", "63f", "6YB", "4la", "0WO", "0u", "yM", "8Sg", "4aQ", "408", "aPL", "b1F", "0tS", "Wa", + "0n3", "1ks", "bzO", "61W", "7KR", "4nP", "214", "2D", "2mm", "0XN", "57I", "6VC", "6xo", "4ML", "02j", "UP", + "6Dk", "4qH", "0Jf", "iT", "Gx", "0dJ", "5OE", "6jG", "4G5", "4RT", "0iz", "JH", "dd", "0GV", "48p", "5y8", + "521", "47q", "0HW", "ke", "EI", "12R", "5Mt", "4H4", "6eF", "4Pe", "0kK", "Hy", "fU", "s4", "5nh", "6Kj", + "54b", "6Uh", "xW", "m6", "01A", "3PK", "7ke", "4Ng", "4CW", "4V6", "191", "0xy", "0VU", "1o", "6XX", "59R", + "4bz", "6WY", "zf", "0YT", "03p", "TJ", "4Y7", "4LV", "4Af", "60M", "Yz", "0zH", "b7", "wV", "6Zi", "4oJ", + "5H3", "4Ms", "02U", "Uo", "2mR", "0Xq", "57v", "426", "7Km", "4no", "0UA", "vs", "2NN", "1kL", "5Pb", "61h", + "6za", "4OB", "00d", "2AO", "yr", "1Ja", "4an", "6TM", "a7g", "58w", "0Wp", "0J", "Zn", "84L", "4Br", "5G2", + "5LQ", "5Y0", "d", "13w", "0Ir", "1L2", "amm", "46T", "5oM", "6JO", "gp", "0DB", "0jn", "3Ol", "6dc", "5Aa", + "bdr", "6kb", "2PL", "0eo", "0KC", "hq", "6EN", "44e", "49U", "abl", "eA", "0Fs", "8aG", "Km", "5V1", "4Sq", + "1Dz", "3a", "5j5", "4ou", "4AY", "4T8", "YE", "0zw", "03O", "Tu", "6yJ", "4Li", "4bE", "6Wf", "zY", "o8", + "0Vj", "1P", "6Xg", "4mD", "4Ch", "62C", "2Me", "0xF", "0uv", "VD", "7kZ", "4NX", "5pU", "5e4", "xh", "3k9", + "fj", "0EX", "5nW", "6KU", "6ey", "4PZ", "0kt", "HF", "Ev", "0fD", "5MK", "6hI", "6Fe", "47N", "0Hh", "kZ", + "26B", "52", "48O", "6Id", "6gH", "4Rk", "0iE", "Jw", "GG", "0du", "5Oz", "6jx", "5t7", "4qw", "0JY", "ik", + "2mV", "0Xu", "57r", "422", "5H7", "4Mw", "02Q", "Uk", "2NJ", "1kH", "5Pf", "61l", "7Ki", "4nk", "0UE", "vw", + "yv", "0ZD", "4aj", "6TI", "6ze", "4OF", "0th", "WZ", "Zj", "0yX", "4Bv", "5G6", "6Yy", "4lZ", "0Wt", "0N", + "0Iv", "jD", "4g9", "46P", "5LU", "5Y4", "Dh", "0gZ", "0jj", "IX", "6dg", "4QD", "5oI", "6JK", "gt", "0DF", + "0KG", "hu", "6EJ", "44a", "5Nd", "6kf", "FY", "S8", "1xz", "Ki", "5V5", "4Su", "49Q", "4h8", "eE", "0Fw", + "756", "60v", "YA", "0zs", "9Mf", "3e", "5j1", "4oq", "4bA", "6Wb", "2lL", "0Yo", "03K", "Tq", "6yN", "4Lm", + "4Cl", "62G", "2Ma", "0xB", "0Vn", "1T", "6Xc", "59i", "54Y", "5e0", "xl", "8RF", "01z", "1p2", "aQm", "b0g", + "71T", "bjm", "0kp", "HB", "fn", "317", "5nS", "6KQ", "6Fa", "47J", "0Hl", "29G", "Er", "12i", "5MO", "6hM", + "6gL", "4Ro", "0iA", "Js", "26F", "56", "48K", "7YA", "5t3", "4qs", "8CE", "io", "GC", "0dq", "bel", "hYW", + "7Ke", "4ng", "0UI", "2s", "XW", "M6", "5Pj", "6uh", "6xX", "6m9", "0vU", "Ug", "2mZ", "0Xy", "4cW", "4v6", + "4y7", "4lV", "0Wx", "0B", "Zf", "0yT", "4Bz", "63Q", "6zi", "4OJ", "B7", "WV", "yz", "0ZH", "4af", "6TE", + "5oE", "6JG", "gx", "0DJ", "0jf", "IT", "6dk", "4QH", "5LY", "5Y8", "l", "0gV", "0Iz", "jH", "4g5", "4rT", + "5mt", "4h4", "eI", "1VZ", "0hW", "Ke", "5V9", "4Sy", "5Nh", "6kj", "FU", "S4", "0KK", "hy", "6EF", "44m", + "03G", "2Bl", "6yB", "4La", "4bM", "6Wn", "zQ", "o0", "0TS", "3i", "a4D", "bUN", "4AQ", "4T0", "YM", "87o", + "01v", "VL", "7kR", "4NP", "54U", "hft", "0N3", "1Ks", "0Vb", "1X", "6Xo", "4mL", "5SA", "62K", "2Mm", "0xN", + "2So", "0fL", "5MC", "6hA", "6Fm", "47F", "1XA", "kR", "fb", "0EP", "bDM", "aaO", "4E3", "4PR", "8bd", "HN", + "GO", "10T", "5Or", "4J2", "507", "45w", "0JQ", "ic", "dS", "q2", "48G", "6Il", "73i", "4Rc", "0iM", "3LO", + "XS", "M2", "5Pn", "61d", "7Ka", "4nc", "0UM", "2w", "39w", "8Qe", "4cS", "4v2", "aRN", "b3D", "02Y", "Uc", + "Zb", "0yP", "bxM", "63U", "4y3", "4lR", "236", "0F", "2oo", "0ZL", "4ab", "6TA", "6zm", "4ON", "B3", "WR", + "0jb", "IP", "6do", "4QL", "5oA", "6JC", "25e", "0DN", "9PG", "jL", "4g1", "46X", "686", "aCM", "h", "0gR", + "0hS", "Ka", "72w", "677", "49Y", "4h0", "eM", "8Og", "0KO", "3nM", "6EB", "44i", "5Nl", "6kn", "FQ", "S0", + "4bI", "6Wj", "zU", "o4", "03C", "Ty", "6yF", "4Le", "4AU", "4T4", "YI", "1jZ", "0TW", "3m", "5j9", "4oy", + "54Q", "5e8", "xd", "1Kw", "01r", "VH", "7kV", "4NT", "4Cd", "62O", "2Mi", "0xJ", "0Vf", "uT", "6Xk", "4mH", + "6Fi", "47B", "0Hd", "kV", "Ez", "0fH", "5MG", "6hE", "4E7", "4PV", "0kx", "HJ", "ff", "0ET", "bDI", "6KY", + "503", "45s", "0JU", "ig", "GK", "0dy", "5Ov", "4J6", "6gD", "4Rg", "0iI", "3LK", "dW", "q6", "48C", "6Ih", + "4Z2", "4OS", "00u", "WO", "yc", "0ZQ", "55V", "hgw", "6Yl", "4lO", "a2", "tS", "2Ln", "0yM", "4Bc", "63H", + "6xA", "4Mb", "02D", "2Co", "2mC", "n3", "4cN", "6Vm", "a5G", "bTM", "0UP", "2j", "XN", "86l", "5Ps", "4U3", + "5Nq", "4K1", "FL", "11W", "0KR", "3nP", "514", "44t", "49D", "6Ho", "eP", "49", "0hN", "3ML", "6fC", "5CA", + "aV1", "6iB", "u", "0gO", "0Ic", "jQ", "6Gn", "46E", "bEN", "hyu", "ga", "0DS", "8cg", "IM", "4D0", "4QQ", + "1FZ", "1A", "4x4", "4mU", "4Cy", "5F9", "0m6", "0xW", "C4", "VU", "7kK", "4NI", "54L", "6UF", "xy", "1Kj", + "0TJ", "3p", "6ZG", "4od", "4AH", "60c", "YT", "L5", "0wV", "Td", "5I8", "4Lx", "4bT", "4w5", "zH", "0Yz", + "dJ", "0Gx", "5lw", "4i7", "6gY", "4Rz", "0iT", "Jf", "GV", "R7", "5Ok", "6ji", "6DE", "45n", "0JH", "iz", + "24b", "0EI", "5nF", "6KD", "6eh", "4PK", "0ke", "HW", "Eg", "0fU", "5MZ", "6hX", "4f6", "4sW", "0Hy", "kK", + "yg", "0ZU", "55R", "6TX", "4Z6", "4OW", "00q", "WK", "2Lj", "0yI", "4Bg", "63L", "6Yh", "4lK", "a6", "tW", + "2mG", "n7", "4cJ", "6Vi", "6xE", "4Mf", "0vH", "Uz", "XJ", "1kY", "5Pw", "4U7", "7Kx", "4nz", "0UT", "2n", + "0KV", "hd", "510", "44p", "5Nu", "4K5", "FH", "0ez", "0hJ", "Kx", "6fG", "4Sd", "5mi", "6Hk", "eT", "p5", + "0Ig", "jU", "6Gj", "46A", "5LD", "6iF", "q", "0gK", "1zZ", "II", "4D4", "4QU", "5oX", "5z9", "ge", "0DW", + "byN", "62V", "0m2", "0xS", "225", "1E", "4x0", "4mQ", "54H", "6UB", "2nl", "1Kn", "C0", "VQ", "7kO", "4NM", + "4AL", "60g", "YP", "L1", "0TN", "3t", "6ZC", "ae0", "4bP", "439", "zL", "8Pf", "03Z", "0b3", "aSM", "b2G", + "73t", "664", "0iP", "Jb", "dN", "8Nd", "48Z", "4i3", "6DA", "45j", "0JL", "3oN", "GR", "R3", "5Oo", "6jm", + "6el", "4PO", "0ka", "HS", "24f", "0EM", "5nB", "aaR", "4f2", "4sS", "8Ae", "kO", "Ec", "0fQ", "695", "aBN", + "6Yd", "4lG", "0Wi", "0S", "Zw", "0yE", "4Bk", "6wH", "6zx", "buh", "0tu", "WG", "yk", "0ZY", "4aw", "5d7", + "5k6", "4nv", "0UX", "2b", "XF", "1kU", "741", "61q", "6xI", "4Mj", "02L", "Uv", "2mK", "0Xh", "4cF", "6Ve", + "49L", "6Hg", "eX", "41", "0hF", "Kt", "6fK", "4Sh", "5Ny", "4K9", "FD", "0ev", "0KZ", "hh", "5u4", "4pt", + "5oT", "5z5", "gi", "1Tz", "0jw", "IE", "4D8", "4QY", "5LH", "6iJ", "Du", "0gG", "0Ik", "jY", "6Gf", "46M", + "01g", "3Pm", "7kC", "4NA", "54D", "6UN", "xq", "1Kb", "0Vs", "1I", "a6d", "59t", "4Cq", "5F1", "d3G", "85O", + "03V", "Tl", "5I0", "4Lp", "56u", "435", "2lQ", "0Yr", "0TB", "3x", "6ZO", "4ol", "5Qa", "60k", "2OM", "0zn", + "2QO", "0dl", "5Oc", "6ja", "6DM", "45f", "1Za", "ir", "dB", "0Gp", "48V", "aco", "5W2", "4Rr", "94m", "Jn", + "Eo", "12t", "5MR", "5X3", "aln", "47W", "0Hq", "kC", "fs", "0EA", "5nN", "6KL", "71I", "4PC", "0km", "3No", + "Zs", "0yA", "4Bo", "63D", "7IA", "4lC", "0Wm", "0W", "yo", "8SE", "4as", "5d3", "aPn", "b1d", "00y", "WC", + "XB", "1kQ", "745", "61u", "5k2", "4nr", "9Le", "2f", "2mO", "0Xl", "4cB", "6Va", "6xM", "4Mn", "02H", "Ur", + "0hB", "Kp", "6fO", "4Sl", "49H", "6Hc", "27E", "45", "8BF", "hl", "518", "44x", "bdo", "aAm", "2PQ", "0er", + "0js", "IA", "70W", "bkn", "5oP", "5z1", "gm", "304", "0Io", "28D", "6Gb", "46I", "5LL", "6iN", "y", "0gC", + "5pH", "6UJ", "xu", "1Kf", "C8", "VY", "7kG", "4NE", "4Cu", "5F5", "2Mx", "1hz", "0Vw", "1M", "4x8", "4mY", + "4bX", "431", "zD", "0Yv", "03R", "Th", "5I4", "4Lt", "4AD", "60o", "YX", "L9", "0TF", "wt", "6ZK", "4oh", + "6DI", "45b", "0JD", "iv", "GZ", "0dh", "5Og", "6je", "5W6", "4Rv", "0iX", "Jj", "dF", "0Gt", "48R", "6Iy", + "6Fx", "47S", "0Hu", "kG", "Ek", "0fY", "5MV", "5X7", "6ed", "4PG", "0ki", "3Nk", "fw", "0EE", "5nJ", "6KH", + "356", "bo", "6OP", "4zs", "bnl", "75U", "LC", "0oq", "0bA", "As", "6lL", "4Yo", "43K", "7RA", "2yN", "0Lm", + "17", "22G", "6Ma", "4xB", "4Vn", "6cM", "Nr", "19i", "14Y", "CB", "aDo", "bam", "41z", "5p2", "mn", "8GD", + "7d", "8YF", "4kp", "5n0", "64w", "717", "1nS", "2KQ", "Pp", "07J", "4Hl", "69G", "6Sc", "52i", "1MO", "2hM", + "5U", "0Ro", "4iA", "7LC", "66F", "4Gm", "08K", "3YA", "RA", "0qs", "b4f", "aUl", "5a1", "4dq", "8VG", "8e", + "6mV", "4Xu", "17r", "022", "nE", "0Mw", "42Q", "4c8", "6NJ", "5kH", "1Pf", "cu", "MY", "X8", "4UE", "74O", + "6og", "4ZD", "W9", "BX", "lt", "0OF", "4th", "6AK", "4l9", "4yX", "0Bv", "aD", "Oh", "0lZ", "4Wt", "5R4", + "4Iv", "5L6", "Qj", "06P", "1LU", "1Y4", "463", "4gZ", "4jj", "7Oh", "rv", "0QD", "1oI", "2JK", "65m", "4DF", + "4KG", "7nE", "2EJ", "04a", "1Nd", "2kf", "6PH", "4ek", "5xz", "492", "4O", "0Su", "09Q", "0h8", "5C7", "4Fw", + "5Dz", "6ax", "LG", "0ou", "0AY", "bk", "6OT", "4zw", "43O", "6Bd", "2yJ", "0Li", "0bE", "Aw", "6lH", "4Yk", + "4Vj", "6cI", "Nv", "0mD", "13", "22C", "6Me", "4xF", "4uv", "5p6", "mj", "0NX", "1pU", "CF", "6ny", "7k9", + "4P9", "4EX", "1nW", "2KU", "sh", "0PZ", "4kt", "5n4", "6Sg", "4fD", "k9", "2hI", "Pt", "07N", "4Hh", "69C", + "66B", "4Gi", "08O", "2Id", "5Q", "d8", "4iE", "7LG", "5a5", "4du", "1Oz", "8a", "RE", "0qw", "4JY", "aUh", + "nA", "0Ms", "42U", "ail", "6mR", "4Xq", "17v", "026", "3Km", "0no", "4UA", "74K", "6NN", "5kL", "1Pb", "cq", + "lp", "0OB", "40d", "6AO", "6oc", "5Ja", "0an", "2TM", "Ol", "18w", "4Wp", "5R0", "afm", "bCo", "0Br", "1G2", + "1LQ", "1Y0", "467", "53w", "4Ir", "5L2", "Qn", "06T", "1oM", "2JO", "65i", "4DB", "4jn", "7Ol", "6z", "1Aa", + "8WY", "2kb", "6PL", "4eo", "4KC", "7nA", "2EN", "04e", "09U", "d6E", "5C3", "4Fs", "bRl", "496", "4K", "0Sq", + "0bI", "2Wj", "6lD", "4Yg", "43C", "6Bh", "oW", "z6", "0AU", "bg", "6OX", "5jZ", "4TW", "4A6", "LK", "0oy", + "14Q", "CJ", "4N7", "5Kw", "41r", "542", "mf", "0NT", "u7", "22O", "6Mi", "4xJ", "4Vf", "6cE", "Nz", "0mH", + "Px", "07B", "4Hd", "69O", "6Sk", "4fH", "k5", "2hE", "7l", "0PV", "4kx", "5n8", "4P5", "4ET", "83j", "2KY", + "RI", "05s", "4JU", "7oW", "5a9", "4dy", "1Ov", "8m", "qU", "d4", "4iI", "7LK", "66N", "4Ge", "08C", "2Ih", + "6NB", "a59", "1Pn", "21d", "MQ", "X0", "4UM", "74G", "79w", "bbN", "0cS", "0v2", "nM", "8Dg", "42Y", "4c0", + "4l1", "4yP", "8Kf", "aL", "0y3", "0lR", "636", "76v", "6oo", "4ZL", "W1", "BP", "2zm", "0ON", "40h", "6AC", + "4jb", "auS", "6v", "0QL", "I3", "2JC", "65e", "4DN", "b7E", "68U", "Qb", "06X", "286", "dSl", "4r3", "4gR", + "4hS", "7MQ", "4G", "277", "09Y", "0h0", "67T", "b8D", "4KO", "7nM", "SS", "F2", "1Nl", "9w", "azR", "4ec", + "43G", "6Bl", "oS", "z2", "0bM", "2Wn", "78i", "4Yc", "4TS", "4A2", "LO", "8fe", "0AQ", "bc", "aeN", "cPm", + "41v", "546", "mb", "0NP", "14U", "CN", "4N3", "5Ks", "4Vb", "6cA", "2Xo", "0mL", "u3", "22K", "6Mm", "4xN", + "6So", "4fL", "k1", "2hA", "2Fm", "07F", "5XA", "69K", "4P1", "4EP", "83n", "d5f", "7h", "0PR", "bQO", "a0E", + "hbu", "50T", "1Or", "8i", "RM", "05w", "4JQ", "7oS", "66J", "4Ga", "08G", "2Il", "5Y", "d0", "4iM", "7LO", + "MU", "X4", "4UI", "74C", "6NF", "5kD", "1Pj", "cy", "nI", "2m9", "4vU", "4c4", "6mZ", "4Xy", "0cW", "0v6", + "Od", "0lV", "4Wx", "5R8", "4l5", "4yT", "0Bz", "aH", "lx", "0OJ", "40l", "6AG", "6ok", "4ZH", "W5", "BT", + "I7", "2JG", "65a", "4DJ", "4jf", "7Od", "6r", "0QH", "1LY", "1Y8", "4r7", "4gV", "4Iz", "68Q", "Qf", "0rT", + "1mt", "0h4", "67P", "5VZ", "4hW", "7MU", "4C", "0Sy", "1Nh", "9s", "6PD", "4eg", "4KK", "7nI", "SW", "F6", + "8Je", "22V", "4m2", "4xS", "625", "77u", "Nc", "0mQ", "V2", "CS", "6nl", "5Kn", "41k", "7Pa", "3kO", "0NM", + "0AL", "20g", "6OA", "4zb", "4TN", "6am", "LR", "Y3", "0bP", "Ab", "78t", "bcM", "43Z", "4b3", "oN", "8Ed", + "5D", "264", "4iP", "489", "66W", "b9G", "08Z", "0i3", "RP", "G1", "4JL", "7oN", "6QC", "50I", "1Oo", "8t", + "7u", "0PO", "4ka", "7Nc", "64f", "4EM", "H0", "963", "Pa", "0sS", "b6F", "69V", "478", "4fQ", "295", "dRo", + "4O4", "4ZU", "15R", "BI", "le", "0OW", "40q", "551", "6Lj", "4yI", "t4", "aU", "Oy", "0lK", "4We", "6bF", + "6mG", "4Xd", "0cJ", "2Vi", "nT", "0Mf", "4vH", "6Ck", "adI", "5kY", "1Pw", "cd", "MH", "0nz", "4UT", "7pV", + "4KV", "7nT", "SJ", "04p", "1Nu", "9n", "6PY", "4ez", "4hJ", "7MH", "pV", "e7", "1mi", "2Hk", "67M", "4Ff", + "4Ig", "68L", "2Gj", "06A", "j6", "2iF", "6Rh", "4gK", "5zZ", "7Oy", "6o", "0QU", "1oX", "1z9", "4Q6", "4DW", + "5FZ", "6cX", "Ng", "0mU", "0Cy", "1F9", "4m6", "4xW", "41o", "7Pe", "3kK", "0NI", "V6", "CW", "6nh", "5Kj", + "4TJ", "6ai", "LV", "Y7", "0AH", "bz", "6OE", "4zf", "4wV", "4b7", "oJ", "0Lx", "0bT", "Af", "6lY", "4Yz", + "5B8", "4Gx", "1lw", "0i7", "qH", "0Rz", "4iT", "7LV", "6QG", "4dd", "1Ok", "8p", "RT", "G5", "4JH", "7oJ", + "64b", "4EI", "H4", "2KD", "7q", "0PK", "4ke", "7Ng", "4s4", "4fU", "1MZ", "2hX", "Pe", "0sW", "4Hy", "5M9", + "la", "0OS", "40u", "555", "4O0", "4ZQ", "15V", "BM", "2Yl", "0lO", "4Wa", "6bB", "6Ln", "4yM", "08", "aQ", + "nP", "0Mb", "42D", "6Co", "6mC", "5HA", "0cN", "2Vm", "ML", "8gf", "4UP", "74Z", "adM", "bAO", "1Ps", "0U3", + "1Nq", "9j", "azO", "51W", "4KR", "7nP", "SN", "04t", "09D", "2Ho", "67I", "4Fb", "4hN", "7ML", "4Z", "e3", + "j2", "2iB", "6Rl", "4gO", "4Ic", "68H", "2Gn", "06E", "82m", "d4e", "4Q2", "4DS", "bPL", "a1F", "6k", "0QQ", + "1pH", "2UJ", "6nd", "5Kf", "41c", "7Pi", "mw", "0NE", "0Cu", "1F5", "6Mx", "5hz", "4Vw", "5S7", "Nk", "0mY", + "0bX", "Aj", "6lU", "4Yv", "43R", "6By", "oF", "0Lt", "0AD", "bv", "6OI", "4zj", "4TF", "6ae", "LZ", "0oh", + "RX", "G9", "4JD", "7oF", "6QK", "4dh", "1Og", "2je", "5L", "0Rv", "4iX", "481", "5B4", "4Gt", "08R", "2Iy", + "Pi", "07S", "4Hu", "5M5", "470", "4fY", "1MV", "1X7", "su", "0PG", "4ki", "7Nk", "64n", "4EE", "H8", "2KH", + "6Lb", "4yA", "04", "23D", "Oq", "0lC", "4Wm", "6bN", "aEl", "c4G", "0as", "BA", "lm", "8FG", "40y", "559", + "6NS", "5kQ", "345", "cl", "1k2", "0nr", "boo", "74V", "6mO", "4Xl", "0cB", "2Va", "2xM", "0Mn", "42H", "6Cc", + "4hB", "aws", "4V", "0Sl", "09H", "2Hc", "67E", "4Fn", "b5e", "aTo", "SB", "04x", "8WD", "9f", "6PQ", "4er", + "4js", "5o3", "6g", "8XE", "1oP", "1z1", "65t", "704", "4Io", "68D", "Qs", "06I", "1LL", "2iN", "7BA", "4gC", + "41g", "7Pm", "ms", "0NA", "14D", "2UN", "aDr", "5Kb", "4Vs", "5S3", "No", "19t", "0Cq", "1F1", "agn", "bBl", + "43V", "aho", "oB", "0Lp", "16u", "An", "6lQ", "4Yr", "4TB", "6aa", "2ZO", "0ol", "1Qa", "br", "6OM", "4zn", + "6QO", "4dl", "1Oc", "8x", "2DM", "05f", "5Za", "7oB", "5B0", "4Gp", "08V", "d7F", "5H", "0Rr", "bSo", "485", + "474", "52t", "1MR", "1X3", "Pm", "07W", "4Hq", "5M1", "64j", "4EA", "1nN", "2KL", "7y", "0PC", "4km", "7No", + "Ou", "0lG", "4Wi", "6bJ", "6Lf", "4yE", "00", "aY", "li", "8FC", "4tu", "5q5", "4O8", "4ZY", "0aw", "BE", + "MD", "0nv", "4UX", "74R", "6NW", "5kU", "341", "ch", "nX", "0Mj", "42L", "6Cg", "6mK", "4Xh", "0cF", "2Ve", + "09L", "2Hg", "67A", "4Fj", "4hF", "7MD", "4R", "0Sh", "1Ny", "9b", "6PU", "4ev", "4KZ", "7nX", "SF", "0pt", + "1oT", "1z5", "65p", "5Tz", "4jw", "5o7", "6c", "0QY", "1LH", "2iJ", "6Rd", "4gG", "4Ik", "7li", "Qw", "06M", + "7F", "246", "4kR", "7NP", "64U", "col", "1nq", "0k1", "PR", "E3", "4HN", "69e", "6SA", "4fb", "1Mm", "2ho", + "5w", "0RM", "4ic", "7La", "66d", "4GO", "J2", "2IB", "Rc", "05Y", "b4D", "aUN", "4q2", "4dS", "8Ve", "8G", + "8Hg", "bM", "4o0", "4zQ", "607", "75w", "La", "0oS", "T0", "AQ", "6ln", "4YM", "43i", "6BB", "2yl", "0LO", + "0CN", "22e", "6MC", "5hA", "4VL", "6co", "NP", "0mb", "1ps", "0u3", "aDM", "baO", "41X", "7PR", "mL", "8Gf", + "4IT", "7lV", "QH", "06r", "1Lw", "0I7", "5b8", "4gx", "4jH", "7OJ", "rT", "g5", "1ok", "2Ji", "65O", "4Dd", + "4Ke", "7ng", "Sy", "04C", "h4", "2kD", "6Pj", "4eI", "4hy", "5m9", "4m", "0SW", "09s", "2HX", "4S4", "4FU", + "4M6", "4XW", "0cy", "1f9", "ng", "0MU", "42s", "573", "6Nh", "5kj", "v6", "cW", "3KK", "0nI", "4Ug", "74m", + "6oE", "4Zf", "0aH", "Bz", "lV", "y7", "40B", "6Ai", "582", "4yz", "0BT", "af", "OJ", "0lx", "4WV", "4B7", + "64Q", "4Ez", "1nu", "0k5", "7B", "0Px", "4kV", "7NT", "6SE", "4ff", "1Mi", "2hk", "PV", "E7", "4HJ", "69a", + "6rh", "4GK", "J6", "2IF", "5s", "0RI", "4ig", "7Le", "4q6", "4dW", "1OX", "8C", "Rg", "0qU", "5ZZ", "7oy", + "4Ty", "5Q9", "Le", "0oW", "1QZ", "bI", "4o4", "4zU", "43m", "6BF", "oy", "0LK", "T4", "AU", "6lj", "4YI", + "4VH", "6ck", "NT", "0mf", "0CJ", "22a", "6MG", "4xd", "4uT", "7PV", "mH", "0Nz", "1pw", "Cd", "aDI", "5KY", + "1Ls", "0I3", "axM", "53U", "4IP", "7lR", "QL", "06v", "1oo", "2Jm", "65K", "5TA", "4jL", "7ON", "6X", "g1", + "h0", "9Y", "6Pn", "4eM", "4Ka", "7nc", "2El", "04G", "09w", "d6g", "4S0", "4FQ", "bRN", "a3D", "4i", "0SS", + "nc", "0MQ", "42w", "577", "4M2", "4XS", "17T", "dlm", "3KO", "0nM", "4Uc", "74i", "6Nl", "5kn", "v2", "cS", + "lR", "y3", "40F", "6Am", "6oA", "4Zb", "0aL", "2To", "ON", "18U", "4WR", "4B3", "586", "bCM", "0BP", "ab", + "PZ", "0sh", "4HF", "69m", "6SI", "4fj", "1Me", "2hg", "7N", "0Pt", "4kZ", "7NX", "6pU", "4Ev", "1ny", "0k9", + "Rk", "05Q", "4Jw", "5O7", "452", "50r", "1OT", "8O", "qw", "0RE", "4ik", "7Li", "66l", "4GG", "08a", "2IJ", + "T8", "AY", "6lf", "4YE", "43a", "6BJ", "ou", "0LG", "0Aw", "bE", "4o8", "4zY", "4Tu", "5Q5", "Li", "8fC", + "14s", "Ch", "6nW", "5KU", "41P", "7PZ", "mD", "0Nv", "0CF", "22m", "6MK", "4xh", "4VD", "6cg", "NX", "0mj", + "5za", "7OB", "6T", "0Qn", "1oc", "2Ja", "65G", "4Dl", "b7g", "68w", "1w2", "06z", "8UF", "dSN", "5b0", "4gp", + "4hq", "5m1", "4e", "8ZG", "1mR", "1x3", "67v", "726", "4Km", "7no", "Sq", "04K", "1NN", "9U", "6Pb", "4eA", + "adr", "5kb", "26", "21F", "Ms", "0nA", "4Uo", "74e", "79U", "bbl", "0cq", "1f1", "no", "396", "4vs", "5s3", + "6LQ", "4yr", "367", "an", "OB", "0lp", "bmm", "76T", "6oM", "4Zn", "15i", "Br", "2zO", "0Ol", "40J", "6Aa", + "6SM", "4fn", "1Ma", "2hc", "2FO", "07d", "4HB", "69i", "64Y", "4Er", "83L", "d5D", "7J", "0Pp", "bQm", "a0g", + "456", "50v", "1OP", "8K", "Ro", "05U", "4Js", "5O3", "66h", "4GC", "08e", "2IN", "qs", "0RA", "4io", "7Lm", + "43e", "6BN", "oq", "0LC", "0bo", "2WL", "6lb", "4YA", "4Tq", "5Q1", "Lm", "8fG", "0As", "bA", "ael", "cPO", + "41T", "ajm", "1K2", "0Nr", "14w", "Cl", "6nS", "5KQ", "5Fa", "6cc", "2XM", "0mn", "0CB", "22i", "6MO", "4xl", + "1og", "2Je", "65C", "4Dh", "4jD", "7OF", "6P", "g9", "3l9", "2iy", "5b4", "4gt", "4IX", "68s", "QD", "0rv", + "1mV", "1x7", "4S8", "4FY", "4hu", "5m5", "4a", "1Cz", "h8", "9Q", "6Pf", "4eE", "4Ki", "7nk", "Su", "04O", + "Mw", "0nE", "4Uk", "74a", "6Nd", "5kf", "22", "21B", "nk", "0MY", "4vw", "5s7", "6mx", "5Hz", "0cu", "1f5", + "OF", "0lt", "4WZ", "6by", "6LU", "4yv", "0BX", "aj", "lZ", "0Oh", "40N", "6Ae", "6oI", "4Zj", "0aD", "Bv", + "5f", "9Ke", "4ir", "5l2", "66u", "735", "08x", "1y0", "Rr", "05H", "4Jn", "7ol", "6Qa", "4dB", "1OM", "8V", + "7W", "0Pm", "4kC", "7NA", "64D", "4Eo", "83Q", "2Kb", "PC", "07y", "b6d", "69t", "5c3", "4fs", "8TE", "dRM", + "374", "22t", "599", "4xq", "bln", "77W", "NA", "0ms", "14j", "Cq", "6nN", "5KL", "41I", "7PC", "3km", "0No", + "35", "20E", "6Oc", "5ja", "4Tl", "6aO", "Lp", "0oB", "0br", "1g2", "78V", "bco", "43x", "568", "ol", "385", + "4Kt", "5N4", "Sh", "04R", "1NW", "9L", "441", "4eX", "4hh", "7Mj", "pt", "0SF", "K9", "2HI", "67o", "4FD", + "4IE", "68n", "QY", "0", "1Lf", "2id", "6RJ", "4gi", "4jY", "auh", "6M", "0Qw", "1oz", "2Jx", "5A5", "4Du", + "6oT", "4Zw", "0aY", "Bk", "lG", "0Ou", "40S", "6Ax", "6LH", "4yk", "0BE", "aw", "2YJ", "0li", "4WG", "6bd", + "6me", "4XF", "0ch", "2VK", "nv", "0MD", "42b", "6CI", "6Ny", "7K9", "1PU", "cF", "Mj", "0nX", "4Uv", "5P6", + "66q", "4GZ", "1lU", "1y4", "5b", "0RX", "4iv", "5l6", "6Qe", "4dF", "1OI", "8R", "Rv", "05L", "4Jj", "7oh", + "6pH", "4Ek", "1nd", "2Kf", "7S", "0Pi", "4kG", "7NE", "5c7", "4fw", "1Mx", "0H8", "PG", "0su", "5Xz", "69p", + "4VY", "4C8", "NE", "0mw", "1Sz", "22p", "6MV", "4xu", "41M", "7PG", "mY", "x8", "14n", "Cu", "6nJ", "5KH", + "4Th", "6aK", "Lt", "0oF", "31", "bX", "6Og", "4zD", "4wt", "5r4", "oh", "0LZ", "0bv", "AD", "4L9", "4YX", + "1NS", "9H", "445", "51u", "4Kp", "5N0", "Sl", "04V", "09f", "2HM", "67k", "5Va", "4hl", "7Mn", "4x", "0SB", + "1Lb", "3yA", "6RN", "4gm", "4IA", "68j", "2GL", "4", "82O", "d4G", "5A1", "4Dq", "bPn", "a1d", "6I", "0Qs", + "lC", "0Oq", "40W", "akn", "6oP", "4Zs", "15t", "Bo", "2YN", "0lm", "4WC", "76I", "6LL", "4yo", "0BA", "as", + "nr", "8DX", "42f", "6CM", "6ma", "4XB", "0cl", "2VO", "Mn", "8gD", "4Ur", "5P2", "ado", "bAm", "1PQ", "cB", + "Rz", "0qH", "4Jf", "7od", "6Qi", "4dJ", "i7", "2jG", "5n", "0RT", "4iz", "7Lx", "4R7", "4GV", "08p", "1y8", + "PK", "07q", "4HW", "7mU", "6SX", "52R", "1Mt", "0H4", "sW", "f6", "4kK", "7NI", "64L", "4Eg", "1nh", "2Kj", + "14b", "Cy", "6nF", "5KD", "41A", "7PK", "mU", "x4", "0CW", "0V6", "591", "4xy", "4VU", "4C4", "NI", "19R", + "0bz", "AH", "4L5", "4YT", "43p", "560", "od", "0LV", "w5", "bT", "6Ok", "4zH", "4Td", "6aG", "Lx", "0oJ", + "5xA", "7Mb", "4t", "0SN", "K1", "2HA", "67g", "4FL", "b5G", "aTM", "0e3", "04Z", "8Wf", "9D", "449", "4eP", + "4jQ", "7OS", "6E", "255", "1or", "0j2", "65V", "cno", "4IM", "68f", "QQ", "8", "1Ln", "2il", "6RB", "4ga", + "afR", "4yc", "0BM", "23f", "OS", "Z2", "4WO", "6bl", "aEN", "c4e", "0aQ", "Bc", "lO", "8Fe", "4tS", "4a2", + "4n3", "5ks", "8Id", "cN", "Mb", "0nP", "614", "74t", "6mm", "4XN", "U3", "2VC", "2xo", "0ML", "42j", "6CA", + "6Qm", "4dN", "i3", "8Z", "2Do", "05D", "4Jb", "aUS", "4R3", "4GR", "08t", "d7d", "5j", "0RP", "bSM", "a2G", + "ayN", "52V", "1Mp", "0H0", "PO", "07u", "4HS", "69x", "64H", "4Ec", "1nl", "2Kn", "sS", "f2", "4kO", "7NM", + "41E", "7PO", "mQ", "x0", "14f", "2Ul", "6nB", "aQ1", "4VQ", "4C0", "NM", "19V", "0CS", "0V2", "595", "bBN", + "43t", "564", "0Y3", "0LR", "16W", "AL", "4L1", "4YP", "5DA", "6aC", "2Zm", "0oN", "39", "bP", "6Oo", "4zL", + "K5", "2HE", "67c", "4FH", "4hd", "7Mf", "4p", "0SJ", "8Wb", "2kY", "4p5", "4eT", "4Kx", "5N8", "Sd", "0pV", + "1ov", "0j6", "5A9", "4Dy", "4jU", "7OW", "6A", "1AZ", "1Lj", "2ih", "6RF", "4ge", "4II", "68b", "QU", "D4", + "OW", "Z6", "4WK", "6bh", "6LD", "4yg", "0BI", "23b", "lK", "0Oy", "4tW", "4a6", "6oX", "5JZ", "0aU", "Bg", + "Mf", "0nT", "4Uz", "74p", "4n7", "5kw", "1PY", "cJ", "nz", "0MH", "42n", "6CE", "6mi", "4XJ", "U7", "2VG", + "4MP", "4X1", "UL", "02v", "0XR", "0M3", "a8E", "57U", "4nL", "7KN", "2X", "c1", "1ko", "2Nm", "61K", "5PA", + "4Oa", "6zB", "2Al", "00G", "l0", "yQ", "6Tn", "4aM", "58T", "a7D", "0i", "0WS", "84o", "ZM", "4W0", "4BQ", + "4I2", "5Lr", "13T", "G", "jc", "0IQ", "46w", "537", "6Jl", "5on", "r2", "gS", "3OO", "0jM", "4Qc", "70i", + "6kA", "5NC", "0eL", "2Po", "hR", "8Bx", "44F", "6Em", "abO", "49v", "0FP", "eb", "KN", "8ad", "4SR", "4F3", + "3B", "0Tx", "4oV", "4z7", "60Q", "4Az", "0zT", "Yf", "TV", "A7", "4LJ", "6yi", "6WE", "4bf", "0YH", "zz", + "1s", "0VI", "4mg", "6XD", "6vh", "4CK", "N6", "2MF", "Vg", "0uU", "6n9", "7ky", "4u6", "5pv", "1KX", "xK", + "1UZ", "fI", "4k4", "5nt", "4Py", "5U9", "He", "0kW", "P4", "EU", "6hj", "5Mh", "47m", "6FF", "ky", "0HK", + "0GJ", "dx", "6IG", "48l", "4RH", "6gk", "JT", "0if", "0dV", "Gd", "5Z8", "5OY", "4qT", "4d5", "iH", "0Jz", + "0XV", "0M7", "5f8", "4cx", "4MT", "4X5", "UH", "02r", "1kk", "Xx", "61O", "5PE", "4nH", "7KJ", "vT", "c5", + "l4", "yU", "6Tj", "4aI", "4Oe", "6zF", "Wy", "00C", "1iZ", "ZI", "4W4", "4BU", "4ly", "5i9", "0m", "0WW", + "jg", "0IU", "46s", "533", "4I6", "5Lv", "0gy", "C", "3OK", "0jI", "4Qg", "6dD", "6Jh", "5oj", "r6", "gW", + "hV", "0Kd", "44B", "6Ei", "6kE", "5NG", "0eH", "Fz", "KJ", "0hx", "4SV", "4F7", "6HY", "49r", "0FT", "ef", + "60U", "ckl", "0zP", "Yb", "3F", "206", "4oR", "4z3", "6WA", "4bb", "0YL", "2lo", "TR", "A3", "4LN", "6ym", + "62d", "4CO", "N2", "2MB", "1w", "0VM", "4mc", "7Ha", "4u2", "54z", "8Re", "xO", "Vc", "01Y", "b0D", "aQN", + "647", "71w", "Ha", "0kS", "8Lg", "fM", "4k0", "5np", "47i", "6FB", "29d", "0HO", "P0", "EQ", "6hn", "5Ml", + "4RL", "6go", "JP", "0ib", "0GN", "26e", "6IC", "48h", "45X", "4d1", "iL", "8Cf", "0dR", "0q3", "hYt", "beO", + "4nD", "7KF", "2P", "c9", "1kg", "Xt", "61C", "5PI", "4MX", "4X9", "UD", "0vv", "0XZ", "2my", "5f4", "4ct", + "4lu", "5i5", "0a", "1Gz", "0yw", "ZE", "4W8", "4BY", "4Oi", "6zJ", "Wu", "00O", "l8", "yY", "6Tf", "4aE", + "6Jd", "5of", "62", "25B", "Iw", "0jE", "4Qk", "6dH", "6ix", "5Lz", "0gu", "O", "jk", "0IY", "4rw", "5w7", + "5x6", "5mW", "0FX", "ej", "KF", "0ht", "4SZ", "6fy", "6kI", "5NK", "0eD", "Fv", "hZ", "93", "44N", "6Ee", + "2BO", "03d", "4LB", "6ya", "6WM", "4bn", "1Ia", "zr", "3J", "0Tp", "bUm", "a4g", "5D2", "4Ar", "87L", "Yn", + "Vo", "01U", "4Ns", "5K3", "416", "54v", "1KP", "xC", "us", "0VA", "4mo", "6XL", "62h", "4CC", "0xm", "2MN", + "0fo", "2SL", "6hb", "bgr", "47e", "6FN", "kq", "0HC", "0Es", "fA", "aal", "bDn", "4Pq", "5U1", "Hm", "8bG", + "10w", "Gl", "5Z0", "5OQ", "45T", "anm", "1O2", "0Jr", "0GB", "dp", "6IO", "48d", "5Ba", "6gc", "3Ll", "0in", + "1kc", "Xp", "61G", "5PM", "bTs", "7KB", "2T", "0Un", "8QF", "39T", "5f0", "4cp", "797", "aRm", "1s2", "02z", + "0ys", "ZA", "63v", "766", "4lq", "5i1", "0e", "9Nf", "0Zo", "2oL", "6Tb", "4aA", "4Om", "6zN", "Wq", "00K", + "Is", "0jA", "4Qo", "6dL", "7ZA", "5ob", "66", "25F", "jo", "9Pd", "4rs", "5w3", "aCn", "bfl", "0gq", "K", + "KB", "0hp", "bim", "72T", "5x2", "49z", "327", "en", "3nn", "97", "44J", "6Ea", "6kM", "5NO", "11i", "Fr", + "6WI", "4bj", "0YD", "zv", "TZ", "0wh", "4LF", "6ye", "5D6", "4Av", "0zX", "Yj", "3N", "0Tt", "4oZ", "6Zy", + "412", "54r", "1KT", "xG", "Vk", "01Q", "4Nw", "5K7", "62l", "4CG", "0xi", "2MJ", "uw", "0VE", "4mk", "6XH", + "47a", "6FJ", "ku", "0HG", "P8", "EY", "6hf", "5Md", "4Pu", "5U5", "Hi", "8bC", "0Ew", "fE", "4k8", "5nx", + "45P", "4d9", "iD", "0Jv", "0dZ", "Gh", "5Z4", "5OU", "4RD", "6gg", "JX", "0ij", "0GF", "dt", "6IK", "5lI", + "4Op", "5J0", "Wl", "00V", "0Zr", "2oQ", "405", "55u", "4ll", "6YO", "0x", "0WB", "0yn", "2LM", "63k", "5Ra", + "4MA", "6xb", "2CL", "02g", "0XC", "39I", "6VN", "4cm", "bTn", "a5d", "2I", "0Us", "86O", "Xm", "5E1", "5PP", + "6kP", "5NR", "11t", "Fo", "hC", "0Kq", "44W", "aon", "6HL", "49g", "0FA", "es", "3Mo", "0hm", "4SC", "72I", + "6ia", "5Lc", "0gl", "V", "jr", "1Ya", "46f", "6GM", "hyV", "bEm", "0Dp", "gB", "In", "8cD", "4Qr", "5T2", + "1b", "0VX", "4mv", "5h6", "62q", "4CZ", "0xt", "2MW", "Vv", "01L", "4Nj", "7kh", "6Ue", "54o", "1KI", "xZ", + "3S", "0Ti", "4oG", "6Zd", "6tH", "4Ak", "0zE", "Yw", "TG", "0wu", "780", "6yx", "5g7", "4bw", "0YY", "zk", + "1Wz", "di", "5y5", "5lT", "4RY", "4G8", "JE", "0iw", "0dG", "Gu", "6jJ", "5OH", "45M", "6Df", "iY", "80", + "71", "fX", "6Kg", "5ne", "4Ph", "6eK", "Ht", "0kF", "0fv", "ED", "4H9", "5My", "4st", "5v4", "kh", "0HZ", + "0Zv", "yD", "401", "4aX", "4Ot", "5J4", "Wh", "00R", "O9", "ZX", "63o", "4BD", "4lh", "6YK", "tt", "0WF", + "0XG", "2md", "6VJ", "4ci", "4ME", "6xf", "UY", "02c", "1kz", "Xi", "5E5", "5PT", "4nY", "aqh", "2M", "0Uw", + "hG", "0Ku", "44S", "6Ex", "6kT", "5NV", "0eY", "Fk", "3Mk", "0hi", "4SG", "6fd", "6HH", "49c", "0FE", "ew", + "jv", "0ID", "46b", "6GI", "6ie", "5Lg", "0gh", "R", "Ij", "0jX", "4Qv", "5T6", "6Jy", "7O9", "0Dt", "gF", + "62u", "775", "0xp", "198", "1f", "9Oe", "4mr", "5h2", "6Ua", "54k", "1KM", "2nO", "Vr", "01H", "4Nn", "7kl", + "60D", "4Ao", "0zA", "Ys", "3W", "0Tm", "4oC", "7JA", "5g3", "4bs", "8PE", "zo", "TC", "03y", "784", "aSn", + "bhn", "73W", "JA", "0is", "334", "dm", "5y1", "48y", "45I", "6Db", "3om", "84", "0dC", "Gq", "6jN", "5OL", + "4Pl", "6eO", "Hp", "0kB", "75", "24E", "6Kc", "5na", "47x", "528", "kl", "8AF", "0fr", "1c2", "aBm", "bgo", + "4ld", "6YG", "0p", "0WJ", "O5", "ZT", "63c", "4BH", "4Ox", "5J8", "Wd", "0tV", "0Zz", "yH", "4t5", "4aT", + "4nU", "7KW", "2A", "1EZ", "1kv", "Xe", "5E9", "5PX", "4MI", "6xj", "UU", "02o", "0XK", "2mh", "6VF", "4ce", + "6HD", "49o", "0FI", "27b", "KW", "0he", "4SK", "6fh", "6kX", "5NZ", "0eU", "Fg", "hK", "0Ky", "4pW", "4e6", + "4j7", "5ow", "0Dx", "gJ", "If", "0jT", "4Qz", "6dY", "6ii", "5Lk", "Q7", "DV", "jz", "0IH", "46n", "6GE", + "3PN", "01D", "4Nb", "aQS", "6Um", "54g", "m3", "xR", "1j", "0VP", "59W", "a6G", "4V3", "4CR", "85l", "194", + "TO", "03u", "4LS", "4Y2", "a9F", "56V", "0YQ", "zc", "wS", "b2", "4oO", "6Zl", "60H", "4Ac", "0zM", "2On", + "0dO", "2Ql", "6jB", "aU1", "45E", "6Dn", "iQ", "88", "0GS", "da", "acL", "48u", "4RQ", "4G0", "JM", "94N", + "12W", "EL", "4H1", "5Mq", "47t", "524", "29y", "0HR", "79", "fP", "6Ko", "5nm", "aZ0", "6eC", "3NL", "0kN", + "O1", "ZP", "63g", "4BL", "58I", "6YC", "0t", "0WN", "8Sf", "yL", "409", "4aP", "b1G", "aPM", "0a3", "00Z", + "1kr", "Xa", "61V", "bzN", "4nQ", "7KS", "2E", "215", "0XO", "2ml", "6VB", "4ca", "4MM", "6xn", "UQ", "02k", + "KS", "0ha", "4SO", "6fl", "7Xa", "49k", "0FM", "27f", "hO", "8Be", "4pS", "4e2", "aAN", "bdL", "0eQ", "Fc", + "Ib", "0jP", "654", "70t", "4j3", "5os", "8Md", "gN", "28g", "0IL", "46j", "6GA", "6im", "5Lo", "Q3", "Z", + "6Ui", "54c", "m7", "xV", "Vz", "0uH", "4Nf", "7kd", "4V7", "4CV", "0xx", "190", "1n", "0VT", "4mz", "6XY", + "6WX", "56R", "0YU", "zg", "TK", "03q", "4LW", "4Y6", "60L", "4Ag", "0zI", "2Oj", "wW", "b6", "4oK", "6Zh", + "45A", "6Dj", "iU", "0Jg", "0dK", "Gy", "6jF", "5OD", "4RU", "4G4", "JI", "1yZ", "0GW", "de", "5y9", "48q", + "47p", "520", "kd", "0HV", "0fz", "EH", "4H5", "5Mu", "4Pd", "6eG", "Hx", "0kJ", "s5", "fT", "6Kk", "5ni", + "5Y1", "5LP", "13v", "e", "jA", "0Is", "46U", "aml", "6JN", "5oL", "0DC", "gq", "3Om", "0jo", "4QA", "6db", + "6kc", "5Na", "0en", "2PM", "hp", "0KB", "44d", "6EO", "abm", "49T", "0Fr", "1C2", "Kl", "8aF", "4Sp", "5V0", + "4Mr", "5H2", "Un", "02T", "0Xp", "2mS", "427", "57w", "4nn", "7Kl", "2z", "1Ea", "1kM", "2NO", "61i", "5Pc", + "4OC", "7jA", "2AN", "00e", "0ZA", "ys", "6TL", "4ao", "58v", "a7f", "0K", "0Wq", "84M", "Zo", "5G3", "4Bs", + "0EY", "fk", "6KT", "5nV", "bjh", "6ex", "HG", "0ku", "0fE", "Ew", "6hH", "5MJ", "47O", "6Fd", "29B", "0Hi", + "53", "dZ", "6Ie", "48N", "4Rj", "6gI", "Jv", "0iD", "0dt", "GF", "6jy", "7o9", "4qv", "5t6", "ij", "0JX", + "wh", "0TZ", "4ot", "5j4", "4T9", "4AX", "0zv", "YD", "Tt", "03N", "4Lh", "6yK", "6Wg", "4bD", "o9", "zX", + "1Q", "0Vk", "4mE", "6Xf", "62B", "4Ci", "0xG", "2Md", "VE", "0uw", "4NY", "aQh", "5e5", "5pT", "1Kz", "xi", + "jE", "0Iw", "46Q", "4g8", "5Y5", "5LT", "13r", "a", "IY", "0jk", "4QE", "6df", "6JJ", "5oH", "0DG", "gu", + "ht", "0KF", "4ph", "6EK", "6kg", "5Ne", "S9", "FX", "Kh", "0hZ", "4St", "5V4", "4h9", "49P", "0Fv", "eD", + "0Xt", "2mW", "423", "4cZ", "4Mv", "5H6", "Uj", "02P", "1kI", "XZ", "61m", "5Pg", "4nj", "7Kh", "vv", "0UD", + "0ZE", "yw", "6TH", "4ak", "4OG", "6zd", "2AJ", "00a", "0yY", "Zk", "5G7", "4Bw", "58r", "6Yx", "0O", "0Wu", + "bjl", "71U", "HC", "0kq", "316", "fo", "6KP", "5nR", "47K", "7VA", "29F", "0Hm", "0fA", "Es", "6hL", "5MN", + "4Rn", "6gM", "Jr", "1ya", "57", "26G", "6Ia", "48J", "45z", "5t2", "in", "8CD", "0dp", "GB", "hYV", "bem", + "60w", "757", "0zr", "2OQ", "3d", "9Mg", "4op", "5j0", "6Wc", "56i", "0Yn", "2lM", "Tp", "03J", "4Ll", "6yO", + "62F", "4Cm", "0xC", "dwS", "1U", "0Vo", "4mA", "6Xb", "5e1", "54X", "8RG", "xm", "VA", "0us", "b0f", "aQl", + "6JF", "5oD", "0DK", "gy", "IU", "0jg", "4QI", "6dj", "5Y9", "5LX", "0gW", "m", "jI", "1YZ", "4rU", "4g4", + "4h5", "5mu", "0Fz", "eH", "Kd", "0hV", "4Sx", "5V8", "6kk", "5Ni", "S5", "FT", "hx", "0KJ", "44l", "6EG", + "4nf", "7Kd", "2r", "0UH", "M7", "XV", "61a", "5Pk", "4Mz", "6xY", "Uf", "0vT", "0Xx", "39r", "4v7", "4cV", + "4lW", "4y6", "0C", "0Wy", "0yU", "Zg", "63P", "5RZ", "4OK", "6zh", "WW", "B6", "0ZI", "2oj", "6TD", "4ag", + "0fM", "2Sn", "7xa", "5MB", "47G", "6Fl", "kS", "0Ha", "0EQ", "fc", "aaN", "bDL", "4PS", "4E2", "HO", "8be", + "10U", "GN", "4J3", "5Os", "45v", "506", "ib", "0JP", "q3", "dR", "6Im", "48F", "4Rb", "6gA", "3LN", "0iL", + "2Bm", "03F", "aF0", "6yC", "6Wo", "4bL", "o1", "zP", "3h", "0TR", "bUO", "a4E", "4T1", "4AP", "87n", "YL", + "VM", "01w", "4NQ", "7kS", "hfu", "54T", "1Kr", "xa", "1Y", "0Vc", "4mM", "6Xn", "62J", "4Ca", "0xO", "2Ml", + "IQ", "0jc", "4QM", "6dn", "6JB", "a19", "0DO", "25d", "jM", "9PF", "46Y", "4g0", "aCL", "687", "0gS", "i", + "3MP", "0hR", "676", "72v", "4h1", "49X", "8Of", "eL", "3nL", "0KN", "44h", "6EC", "6ko", "5Nm", "S1", "FP", + "M3", "XR", "61e", "5Po", "4nb", "aqS", "2v", "0UL", "8Qd", "39v", "4v3", "4cR", "b3E", "aRO", "Ub", "02X", + "0yQ", "Zc", "63T", "bxL", "4lS", "4y2", "0G", "237", "0ZM", "2on", "7Da", "4ac", "4OO", "6zl", "WS", "B2", + "47C", "6Fh", "kW", "0He", "0fI", "2Sj", "6hD", "5MF", "4PW", "4E6", "HK", "0ky", "0EU", "fg", "6KX", "5nZ", + "45r", "502", "if", "0JT", "0dx", "GJ", "4J7", "5Ow", "4Rf", "6gE", "Jz", "0iH", "q7", "dV", "6Ii", "48B", + "6Wk", "4bH", "o5", "zT", "Tx", "03B", "4Ld", "6yG", "4T5", "4AT", "0zz", "YH", "3l", "0TV", "4ox", "5j8", + "5e9", "54P", "1Kv", "xe", "VI", "01s", "4NU", "7kW", "62N", "4Ce", "0xK", "2Mh", "uU", "0Vg", "4mI", "6Xj", + "4K0", "5Np", "11V", "FM", "ha", "0KS", "44u", "515", "6Hn", "49E", "48", "eQ", "3MM", "0hO", "4Sa", "6fB", + "6iC", "5LA", "0gN", "t", "jP", "0Ib", "46D", "6Go", "hyt", "bEO", "0DR", "0Q3", "IL", "8cf", "4QP", "4D1", + "4OR", "4Z3", "WN", "00t", "0ZP", "yb", "hgv", "55W", "4lN", "6Ym", "0Z", "a3", "0yL", "2Lo", "63I", "4Bb", + "4Mc", "7ha", "2Cn", "02E", "n2", "2mB", "6Vl", "4cO", "bTL", "a5F", "2k", "0UQ", "86m", "XO", "4U2", "5Pr", + "0Gy", "dK", "4i6", "5lv", "5BZ", "6gX", "Jg", "0iU", "R6", "GW", "6jh", "5Oj", "45o", "6DD", "3oK", "0JI", + "0EH", "fz", "6KE", "5nG", "4PJ", "6ei", "HV", "0kd", "0fT", "Ef", "6hY", "690", "4sV", "4f7", "kJ", "0Hx", + "uH", "0Vz", "4mT", "4x5", "5F8", "4Cx", "0xV", "0m7", "VT", "C5", "4NH", "7kJ", "6UG", "54M", "1Kk", "xx", + "3q", "0TK", "4oe", "6ZF", "60b", "4AI", "L4", "YU", "Te", "0wW", "4Ly", "5I9", "4w4", "4bU", "1IZ", "zI", + "he", "0KW", "44q", "511", "4K4", "5Nt", "11R", "FI", "Ky", "0hK", "4Se", "6fF", "6Hj", "49A", "p4", "eU", + "jT", "0If", "4rH", "6Gk", "6iG", "5LE", "0gJ", "p", "IH", "0jz", "4QT", "4D5", "5z8", "5oY", "0DV", "gd", + "0ZT", "yf", "6TY", "4az", "4OV", "4Z7", "WJ", "00p", "0yH", "Zz", "63M", "4Bf", "4lJ", "6Yi", "tV", "a7", + "n6", "2mF", "6Vh", "4cK", "4Mg", "6xD", "2Cj", "02A", "1kX", "XK", "4U6", "5Pv", "6N9", "7Ky", "2o", "0UU", + "665", "73u", "Jc", "0iQ", "8Ne", "dO", "4i2", "5lr", "45k", "7Ta", "3oO", "0JM", "R2", "GS", "6jl", "5On", + "4PN", "6em", "HR", "8bx", "0EL", "24g", "6KA", "5nC", "47Z", "4f3", "kN", "8Ad", "0fP", "Eb", "aBO", "694", + "62W", "byO", "0xR", "0m3", "1D", "224", "4mP", "4x1", "6UC", "54I", "1Ko", "2nm", "VP", "C1", "4NL", "7kN", + "60f", "4AM", "L0", "YQ", "3u", "0TO", "4oa", "6ZB", "438", "4bQ", "8Pg", "zM", "Ta", "0wS", "b2F", "aSL", + "6Hf", "49M", "40", "eY", "Ku", "0hG", "4Si", "6fJ", "4K8", "5Nx", "0ew", "FE", "hi", "8BC", "4pu", "5u5", + "5z4", "5oU", "0DZ", "gh", "ID", "0jv", "4QX", "4D9", "6iK", "5LI", "0gF", "Dt", "jX", "0Ij", "46L", "6Gg", + "4lF", "6Ye", "0R", "0Wh", "0yD", "Zv", "63A", "4Bj", "4OZ", "6zy", "WF", "0tt", "0ZX", "yj", "5d6", "4av", + "4nw", "5k7", "2c", "0UY", "1kT", "XG", "61p", "5Pz", "4Mk", "6xH", "Uw", "02M", "0Xi", "2mJ", "6Vd", "4cG", + "0dm", "2QN", "7zA", "5Ob", "45g", "6DL", "is", "0JA", "0Gq", "dC", "acn", "48W", "4Rs", "5W3", "Jo", "94l", + "12u", "En", "5X2", "5MS", "47V", "alo", "kB", "0Hp", "1Ua", "fr", "6KM", "5nO", "4PB", "6ea", "3Nn", "0kl", + "3Pl", "01f", "bts", "7kB", "6UO", "54E", "1Kc", "xp", "1H", "0Vr", "59u", "a6e", "5F0", "4Cp", "85N", "d3F", + "Tm", "03W", "4Lq", "5I1", "434", "56t", "0Ys", "zA", "3y", "0TC", "4om", "6ZN", "60j", "4AA", "0zo", "2OL", + "Kq", "0hC", "4Sm", "6fN", "6Hb", "49I", "44", "27D", "hm", "8BG", "44y", "519", "aAl", "bdn", "0es", "FA", + "1o2", "0jr", "bko", "70V", "5z0", "5oQ", "305", "gl", "28E", "0In", "46H", "6Gc", "6iO", "5LM", "0gB", "x", + "1ia", "Zr", "63E", "4Bn", "4lB", "6Ya", "0V", "0Wl", "8SD", "yn", "5d2", "4ar", "b1e", "aPo", "WB", "00x", + "1kP", "XC", "61t", "744", "4ns", "5k3", "2g", "9Ld", "0Xm", "2mN", "7FA", "4cC", "4Mo", "6xL", "Us", "02I", + "45c", "6DH", "iw", "0JE", "0di", "2QJ", "6jd", "5Of", "4Rw", "5W7", "Jk", "0iY", "0Gu", "dG", "6Ix", "48S", + "47R", "6Fy", "kF", "0Ht", "0fX", "Ej", "5X6", "5MW", "4PF", "6ee", "HZ", "0kh", "0ED", "fv", "6KI", "5nK", + "6UK", "54A", "1Kg", "xt", "VX", "C9", "4ND", "7kF", "5F4", "4Ct", "0xZ", "2My", "1L", "0Vv", "4mX", "4x9", + "430", "4bY", "0Yw", "zE", "Ti", "03S", "4Lu", "5I5", "60n", "4AE", "L8", "YY", "wu", "0TG", "4oi", "6ZJ"}; #endif - diff --git a/src/crc64.c b/src/crc64.c index 97b28250a..1e73027b9 100644 --- a/src/crc64.c +++ b/src/crc64.c @@ -89,9 +89,9 @@ static inline uint_fast64_t crc_reflect(uint_fast64_t data, size_t data_len) { /* swap bytes */ data = ((data >> 8) & 0x00FF00FF00FF00FFULL) | ((data & 0x00FF00FF00FF00FFULL) << 8); /* swap 2-byte long pairs */ - data = ( data >> 16 & 0xFFFF0000FFFFULL) | ((data & 0xFFFF0000FFFFULL) << 16); + data = (data >> 16 & 0xFFFF0000FFFFULL) | ((data & 0xFFFF0000FFFFULL) << 16); /* swap 4-byte quads */ - data = ( data >> 32 & 0xFFFFFFFFULL) | ((data & 0xFFFFFFFFULL) << 32); + data = (data >> 32 & 0xFFFFFFFFULL) | ((data & 0xFFFFFFFFULL) << 32); #endif /* adjust for non-64-bit reversals */ return data >> (64 - data_len); @@ -139,5 +139,5 @@ void crc64_init(void) { /* Compute crc64 */ uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l) { - return crcspeed64native(crc64_table, crc, (void *) s, l); + return crcspeed64native(crc64_table, crc, (void *)s, l); } diff --git a/src/crccombine.c b/src/crccombine.c index 4d9a18c65..1eb79f166 100644 --- a/src/crccombine.c +++ b/src/crccombine.c @@ -27,88 +27,92 @@ freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. + misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Mark Adler madler@alumni.caltech.edu */ -#define STATIC_ASSERT(VVV) do {int test = 1 / (VVV);test++;} while (0) +#define STATIC_ASSERT(VVV) \ + do { \ + int test = 1 / (VVV); \ + test++; \ + } while (0) #if !((defined(__i386__) || defined(__X86_64__))) /* This cuts 40% of the time vs bit-by-bit. */ uint64_t gf2_matrix_times_switch(uint64_t *mat, uint64_t vec) { - /* - * Without using any vector math, this handles 4 bits at a time, - * and saves 40+% of the time compared to the bit-by-bit version. Use if you - * have no vector compile option available to you. With cache, we see: - * E5-2670 ~1-2us to extend ~1 meg 64 bit hash - */ - uint64_t sum; - - sum = 0; - while (vec) { - /* reversing the case order is ~10% slower on Xeon E5-2670 */ - switch (vec & 15) { - case 15: - sum ^= *mat ^ *(mat+1) ^ *(mat+2) ^ *(mat+3); - break; - case 14: - sum ^= *(mat+1) ^ *(mat+2) ^ *(mat+3); - break; - case 13: - sum ^= *mat ^ *(mat+2) ^ *(mat+3); - break; - case 12: - sum ^= *(mat+2) ^ *(mat+3); - break; - case 11: - sum ^= *mat ^ *(mat+1) ^ *(mat+3); - break; - case 10: - sum ^= *(mat+1) ^ *(mat+3); - break; - case 9: - sum ^= *mat ^ *(mat+3); - break; - case 8: - sum ^= *(mat+3); - break; - case 7: - sum ^= *mat ^ *(mat+1) ^ *(mat+2); - break; - case 6: - sum ^= *(mat+1) ^ *(mat+2); - break; - case 5: - sum ^= *mat ^ *(mat+2); - break; - case 4: - sum ^= *(mat+2); - break; - case 3: - sum ^= *mat ^ *(mat+1); - break; - case 2: - sum ^= *(mat+1); - break; - case 1: - sum ^= *mat; - break; - default: - break; - } - vec >>= 4; - mat += 4; - } - return sum; + /* + * Without using any vector math, this handles 4 bits at a time, + * and saves 40+% of the time compared to the bit-by-bit version. Use if you + * have no vector compile option available to you. With cache, we see: + * E5-2670 ~1-2us to extend ~1 meg 64 bit hash + */ + uint64_t sum; + + sum = 0; + while (vec) { + /* reversing the case order is ~10% slower on Xeon E5-2670 */ + switch (vec & 15) { + case 15: + sum ^= *mat ^ *(mat + 1) ^ *(mat + 2) ^ *(mat + 3); + break; + case 14: + sum ^= *(mat + 1) ^ *(mat + 2) ^ *(mat + 3); + break; + case 13: + sum ^= *mat ^ *(mat + 2) ^ *(mat + 3); + break; + case 12: + sum ^= *(mat + 2) ^ *(mat + 3); + break; + case 11: + sum ^= *mat ^ *(mat + 1) ^ *(mat + 3); + break; + case 10: + sum ^= *(mat + 1) ^ *(mat + 3); + break; + case 9: + sum ^= *mat ^ *(mat + 3); + break; + case 8: + sum ^= *(mat + 3); + break; + case 7: + sum ^= *mat ^ *(mat + 1) ^ *(mat + 2); + break; + case 6: + sum ^= *(mat + 1) ^ *(mat + 2); + break; + case 5: + sum ^= *mat ^ *(mat + 2); + break; + case 4: + sum ^= *(mat + 2); + break; + case 3: + sum ^= *mat ^ *(mat + 1); + break; + case 2: + sum ^= *(mat + 1); + break; + case 1: + sum ^= *mat; + break; + default: + break; + } + vec >>= 4; + mat += 4; + } + return sum; } #define CRC_MULTIPLY gf2_matrix_times_switch @@ -116,51 +120,50 @@ uint64_t gf2_matrix_times_switch(uint64_t *mat, uint64_t vec) { #else /* - Warning: here there be dragons involving vector math, and macros to save us - from repeating the same information over and over. + Warning: here there be dragons involving vector math, and macros to save us + from repeating the same information over and over. */ uint64_t gf2_matrix_times_vec2(uint64_t *mat, uint64_t vec) { - /* - * Uses xmm registers on x86, works basically everywhere fast, doing - * cycles of movqda, mov, shr, pand, and, pxor, at least on gcc 8. - * Is 9-11x faster than original. - * E5-2670 ~29us to extend ~1 meg 64 bit hash - * i3-8130U ~22us to extend ~1 meg 64 bit hash - */ - v2uq sum = {0, 0}, - *mv2 = (v2uq*)mat; - /* this table allows us to eliminate conditions during gf2_matrix_times_vec2() */ - static v2uq masks2[4] = { - {0,0}, - {-1,0}, - {0,-1}, - {-1,-1}, - }; - - /* Almost as beautiful as gf2_matrix_times_vec, but only half as many - * bits per step, so we need 2 per chunk4 operation. Faster in my tests. */ - -#define DO_CHUNK4() \ - sum ^= (*mv2++) & masks2[vec & 3]; \ - vec >>= 2; \ - sum ^= (*mv2++) & masks2[vec & 3]; \ - vec >>= 2 - -#define DO_CHUNK16() \ - DO_CHUNK4(); \ - DO_CHUNK4(); \ - DO_CHUNK4(); \ - DO_CHUNK4() - - DO_CHUNK16(); - DO_CHUNK16(); - DO_CHUNK16(); - DO_CHUNK16(); - - STATIC_ASSERT(sizeof(uint64_t) == 8); - STATIC_ASSERT(sizeof(long long unsigned int) == 8); - return sum[0] ^ sum[1]; + /* + * Uses xmm registers on x86, works basically everywhere fast, doing + * cycles of movqda, mov, shr, pand, and, pxor, at least on gcc 8. + * Is 9-11x faster than original. + * E5-2670 ~29us to extend ~1 meg 64 bit hash + * i3-8130U ~22us to extend ~1 meg 64 bit hash + */ + v2uq sum = {0, 0}, *mv2 = (v2uq *)mat; + /* this table allows us to eliminate conditions during gf2_matrix_times_vec2() */ + static v2uq masks2[4] = { + {0, 0}, + {-1, 0}, + {0, -1}, + {-1, -1}, + }; + + /* Almost as beautiful as gf2_matrix_times_vec, but only half as many + * bits per step, so we need 2 per chunk4 operation. Faster in my tests. */ + +#define DO_CHUNK4() \ + sum ^= (*mv2++) & masks2[vec & 3]; \ + vec >>= 2; \ + sum ^= (*mv2++) & masks2[vec & 3]; \ + vec >>= 2 + +#define DO_CHUNK16() \ + DO_CHUNK4(); \ + DO_CHUNK4(); \ + DO_CHUNK4(); \ + DO_CHUNK4() + + DO_CHUNK16(); + DO_CHUNK16(); + DO_CHUNK16(); + DO_CHUNK16(); + + STATIC_ASSERT(sizeof(uint64_t) == 8); + STATIC_ASSERT(sizeof(long long unsigned int) == 8); + return sum[0] ^ sum[1]; } #undef DO_CHUNK16 @@ -170,10 +173,11 @@ uint64_t gf2_matrix_times_vec2(uint64_t *mat, uint64_t vec) { #endif static void gf2_matrix_square(uint64_t *square, uint64_t *mat, uint8_t dim) { - unsigned n; + unsigned n; - for (n = 0; n < dim; n++) - square[n] = CRC_MULTIPLY(mat, mat[n]); + for (n = 0; n < dim; n++) { + square[n] = CRC_MULTIPLY(mat, mat[n]); + } } /* Turns out our Redis / Jones CRC cycles at this point, so we can support @@ -190,25 +194,24 @@ static uint64_t combine_cache[64][64]; */ void init_combine_cache(uint64_t poly, uint8_t dim) { - unsigned n, cache_num = 0; - combine_cache[1][0] = poly; - int prev = 1; - uint64_t row = 1; - for (n = 1; n < dim; n++) - { - combine_cache[1][n] = row; - row <<= 1; - } - - gf2_matrix_square(combine_cache[0], combine_cache[1], dim); - gf2_matrix_square(combine_cache[1], combine_cache[0], dim); - - /* do/while to overwrite the first two layers, they are not used, but are - * re-generated in the last two layers for the Redis polynomial */ - do { - gf2_matrix_square(combine_cache[cache_num], combine_cache[cache_num + prev], dim); - prev = -1; - } while (++cache_num < 64); + unsigned n, cache_num = 0; + combine_cache[1][0] = poly; + int prev = 1; + uint64_t row = 1; + for (n = 1; n < dim; n++) { + combine_cache[1][n] = row; + row <<= 1; + } + + gf2_matrix_square(combine_cache[0], combine_cache[1], dim); + gf2_matrix_square(combine_cache[1], combine_cache[0], dim); + + /* do/while to overwrite the first two layers, they are not used, but are + * re-generated in the last two layers for the Redis polynomial */ + do { + gf2_matrix_square(combine_cache[cache_num], combine_cache[cache_num + prev], dim); + prev = -1; + } while (++cache_num < 64); } /* Return the CRC-64 of two sequential blocks, where crc1 is the CRC-64 of the @@ -224,30 +227,31 @@ void init_combine_cache(uint64_t poly, uint8_t dim) { */ uint64_t crc64_combine(uint64_t crc1, uint64_t crc2, uintmax_t len2, uint64_t poly, uint8_t dim) { - /* degenerate case */ - if (len2 == 0) - return crc1; - - unsigned cache_num = 0; - if (combine_cache[0][0] == 0) { - init_combine_cache(poly, dim); - } - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do - { - /* apply zeros operator for this bit of len2 */ - if (len2 & 1) - crc1 = CRC_MULTIPLY(combine_cache[cache_num], crc1); - len2 >>= 1; - cache_num = (cache_num + 1) & 63; - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; + /* degenerate case */ + if (len2 == 0) { + return crc1; + } + + unsigned cache_num = 0; + if (combine_cache[0][0] == 0) { + init_combine_cache(poly, dim); + } + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + if (len2 & 1) { + crc1 = CRC_MULTIPLY(combine_cache[cache_num], crc1); + } + len2 >>= 1; + cache_num = (cache_num + 1) & 63; + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; } #undef CRC_MULTIPLY diff --git a/src/crccombine.h b/src/crccombine.h index 8da7c5fe6..451dca856 100644 --- a/src/crccombine.h +++ b/src/crccombine.h @@ -3,7 +3,7 @@ /* mask types */ -typedef unsigned long long v2uq __attribute__ ((vector_size (16))); +typedef unsigned long long v2uq __attribute__((vector_size(16))); uint64_t gf2_matrix_times_vec2(uint64_t *mat, uint64_t vec); void init_combine_cache(uint64_t poly, uint8_t dim); diff --git a/src/crcspeed.c b/src/crcspeed.c index c7073cba2..655db29b8 100644 --- a/src/crcspeed.c +++ b/src/crcspeed.c @@ -127,30 +127,25 @@ void crcspeed16big_init(crcfn16 fn, uint16_t big_table[8][256]) { * macros separate. */ -#define DO_8_1(crc, next) \ - crc ^= *(uint64_t *)next; \ +#define DO_8_1(crc, next) \ + crc ^= *(uint64_t *)next; \ next += 8 -#define DO_8_2(crc) \ - crc = little_table[7][(uint8_t)crc] ^ \ - little_table[6][(uint8_t)(crc >> 8)] ^ \ - little_table[5][(uint8_t)(crc >> 16)] ^ \ - little_table[4][(uint8_t)(crc >> 24)] ^ \ - little_table[3][(uint8_t)(crc >> 32)] ^ \ - little_table[2][(uint8_t)(crc >> 40)] ^ \ - little_table[1][(uint8_t)(crc >> 48)] ^ \ - little_table[0][crc >> 56] - -#define CRC64_SPLIT(div) \ - olen = len; \ - next2 = next1 + ((len / div) & CRC64_LEN_MASK); \ +#define DO_8_2(crc) \ + crc = little_table[7][(uint8_t)crc] ^ little_table[6][(uint8_t)(crc >> 8)] ^ \ + little_table[5][(uint8_t)(crc >> 16)] ^ little_table[4][(uint8_t)(crc >> 24)] ^ \ + little_table[3][(uint8_t)(crc >> 32)] ^ little_table[2][(uint8_t)(crc >> 40)] ^ \ + little_table[1][(uint8_t)(crc >> 48)] ^ little_table[0][crc >> 56] + +#define CRC64_SPLIT(div) \ + olen = len; \ + next2 = next1 + ((len / div) & CRC64_LEN_MASK); \ len = (next2 - next1) -#define MERGE_CRC(crcn) \ - crc1 = crc64_combine(crc1, crcn, next2 - next1, CRC64_REVERSED_POLY, 64) +#define MERGE_CRC(crcn) crc1 = crc64_combine(crc1, crcn, next2 - next1, CRC64_REVERSED_POLY, 64) -#define MERGE_END(last, DIV) \ - len = olen - ((next2 - next1) * DIV); \ +#define MERGE_END(last, DIV) \ + len = olen - ((next2 - next1) * DIV); \ next1 = last /* Variables so we can change for benchmarking; these seem to be fairly @@ -158,10 +153,10 @@ void crcspeed16big_init(crcfn16 fn, uint16_t big_table[8][256]) { * or when your CPU has more load / execute units. We've written benchmark code * to help you tune your platform, see crc64Test. */ #if defined(__i386__) || defined(__X86_64__) -static size_t CRC64_TRI_CUTOFF = (2*1024); +static size_t CRC64_TRI_CUTOFF = (2 * 1024); static size_t CRC64_DUAL_CUTOFF = (128); #else -static size_t CRC64_TRI_CUTOFF = (16*1024); +static size_t CRC64_TRI_CUTOFF = (16 * 1024); static size_t CRC64_DUAL_CUTOFF = (1024); #endif @@ -176,8 +171,7 @@ void set_crc64_cutoffs(size_t dual_cutoff, size_t tri_cutoff) { * *after* calling. * 64 bit crc = process 8/16/24 bytes at once; */ -uint64_t crcspeed64little(uint64_t little_table[8][256], uint64_t crc1, - void *buf, size_t len) { +uint64_t crcspeed64little(uint64_t little_table[8][256], uint64_t crc1, void *buf, size_t len) { unsigned char *next1 = buf; if (CRC64_DUAL_CUTOFF < 1) { @@ -190,10 +184,10 @@ uint64_t crcspeed64little(uint64_t little_table[8][256], uint64_t crc1, len--; } - if (len > CRC64_TRI_CUTOFF) { + if (len > CRC64_TRI_CUTOFF) { /* 24 bytes per loop, doing 3 parallel 8 byte chunks at a time */ unsigned char *next2, *next3; - uint64_t olen, crc2=0, crc3=0; + uint64_t olen, crc2 = 0, crc3 = 0; CRC64_SPLIT(3); /* len is now the length of the first segment, the 3rd segment possibly * having extra bytes to clean up at the end @@ -216,7 +210,7 @@ uint64_t crcspeed64little(uint64_t little_table[8][256], uint64_t crc1, } else if (len > CRC64_DUAL_CUTOFF) { /* 16 bytes per loop, doing 2 parallel 8 byte chunks at a time */ unsigned char *next2; - uint64_t olen, crc2=0; + uint64_t olen, crc2 = 0; CRC64_SPLIT(2); /* len is now the length of the first segment, the 2nd segment possibly * having extra bytes to clean up at the end @@ -267,8 +261,7 @@ uint64_t crcspeed64little(uint64_t little_table[8][256], uint64_t crc1, * normally used to shard keys; not hash / verify data, so is used on shorter * data that doesn't warrant such changes. */ -uint16_t crcspeed16little(uint16_t little_table[8][256], uint16_t crc, - void *buf, size_t len) { +uint16_t crcspeed16little(uint16_t little_table[8][256], uint16_t crc, void *buf, size_t len) { unsigned char *next = buf; /* process individual bytes until we reach an 8-byte aligned pointer */ @@ -280,14 +273,10 @@ uint16_t crcspeed16little(uint16_t little_table[8][256], uint16_t crc, /* fast middle processing, 8 bytes (aligned!) per loop */ while (len >= 8) { uint64_t n = *(uint64_t *)next; - crc = little_table[7][(n & 0xff) ^ ((crc >> 8) & 0xff)] ^ - little_table[6][((n >> 8) & 0xff) ^ (crc & 0xff)] ^ - little_table[5][(n >> 16) & 0xff] ^ - little_table[4][(n >> 24) & 0xff] ^ - little_table[3][(n >> 32) & 0xff] ^ - little_table[2][(n >> 40) & 0xff] ^ - little_table[1][(n >> 48) & 0xff] ^ - little_table[0][n >> 56]; + crc = little_table[7][(n & 0xff) ^ ((crc >> 8) & 0xff)] ^ little_table[6][((n >> 8) & 0xff) ^ (crc & 0xff)] ^ + little_table[5][(n >> 16) & 0xff] ^ little_table[4][(n >> 24) & 0xff] ^ + little_table[3][(n >> 32) & 0xff] ^ little_table[2][(n >> 40) & 0xff] ^ + little_table[1][(n >> 48) & 0xff] ^ little_table[0][n >> 56]; next += 8; len -= 8; } @@ -304,8 +293,7 @@ uint16_t crcspeed16little(uint16_t little_table[8][256], uint16_t crc, /* Calculate a non-inverted CRC eight bytes at a time on a big-endian * architecture. */ -uint64_t crcspeed64big(uint64_t big_table[8][256], uint64_t crc, void *buf, - size_t len) { +uint64_t crcspeed64big(uint64_t big_table[8][256], uint64_t crc, void *buf, size_t len) { unsigned char *next = buf; crc = rev8(crc); @@ -320,14 +308,9 @@ uint64_t crcspeed64big(uint64_t big_table[8][256], uint64_t crc, void *buf, while (len >= 8) { crc ^= *(uint64_t *)next; - crc = big_table[0][crc & 0xff] ^ - big_table[1][(crc >> 8) & 0xff] ^ - big_table[2][(crc >> 16) & 0xff] ^ - big_table[3][(crc >> 24) & 0xff] ^ - big_table[4][(crc >> 32) & 0xff] ^ - big_table[5][(crc >> 40) & 0xff] ^ - big_table[6][(crc >> 48) & 0xff] ^ - big_table[7][crc >> 56]; + crc = big_table[0][crc & 0xff] ^ big_table[1][(crc >> 8) & 0xff] ^ big_table[2][(crc >> 16) & 0xff] ^ + big_table[3][(crc >> 24) & 0xff] ^ big_table[4][(crc >> 32) & 0xff] ^ big_table[5][(crc >> 40) & 0xff] ^ + big_table[6][(crc >> 48) & 0xff] ^ big_table[7][crc >> 56]; next += 8; len -= 8; } @@ -341,8 +324,7 @@ uint64_t crcspeed64big(uint64_t big_table[8][256], uint64_t crc, void *buf, } /* WARNING: Completely untested on big endian architecture. Possibly broken. */ -uint16_t crcspeed16big(uint16_t big_table[8][256], uint16_t crc_in, void *buf, - size_t len) { +uint16_t crcspeed16big(uint16_t big_table[8][256], uint16_t crc_in, void *buf, size_t len) { unsigned char *next = buf; uint64_t crc = crc_in; @@ -354,14 +336,9 @@ uint16_t crcspeed16big(uint16_t big_table[8][256], uint16_t crc_in, void *buf, while (len >= 8) { uint64_t n = *(uint64_t *)next; - crc = big_table[0][(n & 0xff) ^ ((crc >> (56 - 8)) & 0xff)] ^ - big_table[1][((n >> 8) & 0xff) ^ (crc & 0xff)] ^ - big_table[2][(n >> 16) & 0xff] ^ - big_table[3][(n >> 24) & 0xff] ^ - big_table[4][(n >> 32) & 0xff] ^ - big_table[5][(n >> 40) & 0xff] ^ - big_table[6][(n >> 48) & 0xff] ^ - big_table[7][n >> 56]; + crc = big_table[0][(n & 0xff) ^ ((crc >> (56 - 8)) & 0xff)] ^ big_table[1][((n >> 8) & 0xff) ^ (crc & 0xff)] ^ + big_table[2][(n >> 16) & 0xff] ^ big_table[3][(n >> 24) & 0xff] ^ big_table[4][(n >> 32) & 0xff] ^ + big_table[5][(n >> 40) & 0xff] ^ big_table[6][(n >> 48) & 0xff] ^ big_table[7][n >> 56]; next += 8; len -= 8; } @@ -378,33 +355,27 @@ uint16_t crcspeed16big(uint16_t big_table[8][256], uint16_t crc_in, void *buf, at a time using passed-in lookup table. This selects one of two routines depending on the endianness of the architecture. */ -uint64_t crcspeed64native(uint64_t table[8][256], uint64_t crc, void *buf, - size_t len) { +uint64_t crcspeed64native(uint64_t table[8][256], uint64_t crc, void *buf, size_t len) { uint64_t n = 1; - return *(char *)&n ? crcspeed64little(table, crc, buf, len) - : crcspeed64big(table, crc, buf, len); + return *(char *)&n ? crcspeed64little(table, crc, buf, len) : crcspeed64big(table, crc, buf, len); } -uint16_t crcspeed16native(uint16_t table[8][256], uint16_t crc, void *buf, - size_t len) { +uint16_t crcspeed16native(uint16_t table[8][256], uint16_t crc, void *buf, size_t len) { uint64_t n = 1; - return *(char *)&n ? crcspeed16little(table, crc, buf, len) - : crcspeed16big(table, crc, buf, len); + return *(char *)&n ? crcspeed16little(table, crc, buf, len) : crcspeed16big(table, crc, buf, len); } /* Initialize CRC lookup table in architecture-dependent manner. */ void crcspeed64native_init(crcfn64 fn, uint64_t table[8][256]) { uint64_t n = 1; - *(char *)&n ? crcspeed64little_init(fn, table) - : crcspeed64big_init(fn, table); + *(char *)&n ? crcspeed64little_init(fn, table) : crcspeed64big_init(fn, table); } void crcspeed16native_init(crcfn16 fn, uint16_t table[8][256]) { uint64_t n = 1; - *(char *)&n ? crcspeed16little_init(fn, table) - : crcspeed16big_init(fn, table); + *(char *)&n ? crcspeed16little_init(fn, table) : crcspeed16big_init(fn, table); } diff --git a/src/crcspeed.h b/src/crcspeed.h index c29f236bc..7eed39bad 100644 --- a/src/crcspeed.h +++ b/src/crcspeed.h @@ -41,22 +41,16 @@ void crcspeed64little_init(crcfn64 fn, uint64_t table[8][256]); void crcspeed64big_init(crcfn64 fn, uint64_t table[8][256]); void crcspeed64native_init(crcfn64 fn, uint64_t table[8][256]); -uint64_t crcspeed64little(uint64_t table[8][256], uint64_t crc, void *buf, - size_t len); -uint64_t crcspeed64big(uint64_t table[8][256], uint64_t crc, void *buf, - size_t len); -uint64_t crcspeed64native(uint64_t table[8][256], uint64_t crc, void *buf, - size_t len); +uint64_t crcspeed64little(uint64_t table[8][256], uint64_t crc, void *buf, size_t len); +uint64_t crcspeed64big(uint64_t table[8][256], uint64_t crc, void *buf, size_t len); +uint64_t crcspeed64native(uint64_t table[8][256], uint64_t crc, void *buf, size_t len); /* CRC-16 */ void crcspeed16little_init(crcfn16 fn, uint16_t table[8][256]); void crcspeed16big_init(crcfn16 fn, uint16_t table[8][256]); void crcspeed16native_init(crcfn16 fn, uint16_t table[8][256]); -uint16_t crcspeed16little(uint16_t table[8][256], uint16_t crc, void *buf, - size_t len); -uint16_t crcspeed16big(uint16_t table[8][256], uint16_t crc, void *buf, - size_t len); -uint16_t crcspeed16native(uint16_t table[8][256], uint16_t crc, void *buf, - size_t len); +uint16_t crcspeed16little(uint16_t table[8][256], uint16_t crc, void *buf, size_t len); +uint16_t crcspeed16big(uint16_t table[8][256], uint16_t crc, void *buf, size_t len); +uint16_t crcspeed16native(uint16_t table[8][256], uint16_t crc, void *buf, size_t len); #endif diff --git a/src/db.c b/src/db.c index d49d09db2..a86cbf8b6 100644 --- a/src/db.c +++ b/src/db.c @@ -48,8 +48,8 @@ /* Return values for expireIfNeeded */ typedef enum { KEY_VALID = 0, /* Could be volatile and not yet expired, non-volatile, or even non-existing key. */ - KEY_EXPIRED, /* Logically expired but not yet deleted. */ - KEY_DELETED /* The key was deleted now. */ + KEY_EXPIRED, /* Logically expired but not yet deleted. */ + KEY_DELETED /* The key was deleted now. */ } keyStatus; keyStatus expireIfNeeded(serverDb *db, robj *key, int flags); @@ -62,7 +62,7 @@ static void dbSetValue(serverDb *db, robj *key, robj *val, int overwrite, dictEn void updateLFU(robj *val) { unsigned long counter = LFUDecrAndReturn(val); counter = LFULogIncr(counter); - val->lru = (LFUGetTimeInMinutes()<<8) | counter; + val->lru = (LFUGetTimeInMinutes() << 8) | counter; } /* Lookup a key for read or write operations, or return NULL if the key is not @@ -107,10 +107,12 @@ robj *lookupKey(serverDb *db, robj *key, int flags) { * perform additional writes. */ int is_ro_replica = server.masterhost && server.repl_slave_ro; int expire_flags = 0; - if (flags & LOOKUP_WRITE && !is_ro_replica) + if (flags & LOOKUP_WRITE && !is_ro_replica) { expire_flags |= EXPIRE_FORCE_DELETE_EXPIRED; - if (flags & LOOKUP_NOEXPIRE) + } + if (flags & LOOKUP_NOEXPIRE) { expire_flags |= EXPIRE_AVOID_DELETE_EXPIRED; + } if (expireIfNeeded(db, key, expire_flags) != KEY_VALID) { /* The key is no longer valid. */ val = NULL; @@ -122,9 +124,10 @@ robj *lookupKey(serverDb *db, robj *key, int flags) { * Don't do it if we have a saving child, as this will trigger * a copy on write madness. */ if (server.current_client && server.current_client->flags & CLIENT_NO_TOUCH && - server.current_client->cmd->proc != touchCommand) + server.current_client->cmd->proc != touchCommand) { flags |= LOOKUP_NOTOUCH; - if (!hasActiveChildProcess() && !(flags & LOOKUP_NOTOUCH)){ + } + if (!hasActiveChildProcess() && !(flags & LOOKUP_NOTOUCH)) { if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) { updateLFU(val); } else { @@ -132,14 +135,17 @@ robj *lookupKey(serverDb *db, robj *key, int flags) { } } - if (!(flags & (LOOKUP_NOSTATS | LOOKUP_WRITE))) + if (!(flags & (LOOKUP_NOSTATS | LOOKUP_WRITE))) { server.stat_keyspace_hits++; + } /* TODO: Use separate hits stats for WRITE */ } else { - if (!(flags & (LOOKUP_NONOTIFY | LOOKUP_WRITE))) + if (!(flags & (LOOKUP_NONOTIFY | LOOKUP_WRITE))) { notifyKeyspaceEvent(NOTIFY_KEY_MISS, "keymiss", key, db->id); - if (!(flags & (LOOKUP_NOSTATS | LOOKUP_WRITE))) + } + if (!(flags & (LOOKUP_NOSTATS | LOOKUP_WRITE))) { server.stat_keyspace_misses++; + } /* TODO: Use separate misses stats and notify event for WRITE */ } @@ -163,7 +169,7 @@ robj *lookupKeyReadWithFlags(serverDb *db, robj *key, int flags) { /* Like lookupKeyReadWithFlags(), but does not use any flag, which is the * common case. */ robj *lookupKeyRead(serverDb *db, robj *key) { - return lookupKeyReadWithFlags(db,key,LOOKUP_NONE); + return lookupKeyReadWithFlags(db, key, LOOKUP_NONE); } /* Lookup a key for write operations, and as a side effect, if needed, expires @@ -182,13 +188,17 @@ robj *lookupKeyWrite(serverDb *db, robj *key) { robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply) { robj *o = lookupKeyRead(c->db, key); - if (!o) addReplyOrErrorObject(c, reply); + if (!o) { + addReplyOrErrorObject(c, reply); + } return o; } robj *lookupKeyWriteOrReply(client *c, robj *key, robj *reply) { robj *o = lookupKeyWrite(c->db, key); - if (!o) addReplyOrErrorObject(c, reply); + if (!o) { + addReplyOrErrorObject(c, reply); + } return o; } @@ -210,7 +220,7 @@ static void dbAddInternal(serverDb *db, robj *key, robj *val, int update_if_exis initObjectLRUOrLFU(val); kvstoreDictSetVal(db->keys, slot, de, val); signalKeyAsReady(db, key, val->type); - notifyKeyspaceEvent(NOTIFY_NEW,"new",key,db->id); + notifyKeyspaceEvent(NOTIFY_NEW, "new", key, db->id); } void dbAdd(serverDb *db, robj *key, robj *val) { @@ -218,11 +228,11 @@ void dbAdd(serverDb *db, robj *key, robj *val) { } /* Returns key's hash slot when cluster mode is enabled, or 0 when disabled. - * The only difference between this function and getKeySlot, is that it's not using cached key slot from the current_client - * and always calculates CRC hash. - * This is useful when slot needs to be calculated for a key that user didn't request for, such as in case of eviction. */ + * The only difference between this function and getKeySlot, is that it's not using cached key slot from the + * current_client and always calculates CRC hash. This is useful when slot needs to be calculated for a key that user + * didn't request for, such as in case of eviction. */ int calculateKeySlot(sds key) { - return server.cluster_enabled ? keyHashSlot(key, (int) sdslen(key)) : 0; + return server.cluster_enabled ? keyHashSlot(key, (int)sdslen(key)) : 0; } /* Return slot-specific dictionary for key based on key's hash slot when cluster mode is enabled, else 0.*/ @@ -233,8 +243,9 @@ int getKeySlot(sds key) { * It only gets set during the execution of command under `call` method. Other flows requesting * the key slot would fallback to calculateKeySlot. */ - if (server.current_client && server.current_client->slot >= 0 && server.current_client->flags & CLIENT_EXECUTING_COMMAND) { - debugServerAssertWithInfo(server.current_client, NULL, calculateKeySlot(key)==server.current_client->slot); + if (server.current_client && server.current_client->slot >= 0 && + server.current_client->flags & CLIENT_EXECUTING_COMMAND) { + debugServerAssertWithInfo(server.current_client, NULL, calculateKeySlot(key) == server.current_client->slot); return server.current_client->slot; } return calculateKeySlot(key); @@ -254,7 +265,9 @@ int getKeySlot(sds key) { int dbAddRDBLoad(serverDb *db, sds key, robj *val) { int slot = getKeySlot(key); dictEntry *de = kvstoreDictAddRaw(db->keys, slot, key, NULL); - if (de == NULL) return 0; + if (de == NULL) { + return 0; + } initObjectLRUOrLFU(val); kvstoreDictSetVal(db->keys, slot, de, val); return 1; @@ -274,8 +287,10 @@ int dbAddRDBLoad(serverDb *db, sds key, robj *val) { * The program is aborted if the key was not already present. */ static void dbSetValue(serverDb *db, robj *key, robj *val, int overwrite, dictEntry *de) { int slot = getKeySlot(key->ptr); - if (!de) de = kvstoreDictFind(db->keys, slot, key->ptr); - serverAssertWithInfo(NULL,key,de != NULL); + if (!de) { + de = kvstoreDictFind(db->keys, slot, key->ptr); + } + serverAssertWithInfo(NULL, key, de != NULL); robj *old = dictGetVal(de); val->lru = old->lru; @@ -287,16 +302,16 @@ static void dbSetValue(serverDb *db, robj *key, robj *val, int overwrite, dictEn /* Although the key is not really deleted from the database, we regard * overwrite as two steps of unlink+add, so we still need to call the unlink * callback of the module. */ - moduleNotifyKeyUnlink(key,old,db->id,DB_FLAG_KEY_OVERWRITE); + moduleNotifyKeyUnlink(key, old, db->id, DB_FLAG_KEY_OVERWRITE); /* We want to try to unblock any module clients or clients using a blocking XREADGROUP */ - signalDeletedKeyAsReady(db,key,old->type); + signalDeletedKeyAsReady(db, key, old->type); decrRefCount(old); /* Because of RM_StringDMA, old may be changed, so we need get old again */ old = dictGetVal(de); } kvstoreDictSetVal(db->keys, slot, de, val); if (server.lazyfree_lazy_server_del) { - freeObjAsync(key,old,db->id); + freeObjAsync(key, old, db->id); } else { decrRefCount(old); } @@ -324,23 +339,28 @@ void dbReplaceValue(serverDb *db, robj *key, robj *val) { void setKey(client *c, serverDb *db, robj *key, robj *val, int flags) { int keyfound = 0; - if (flags & SETKEY_ALREADY_EXIST) + if (flags & SETKEY_ALREADY_EXIST) { keyfound = 1; - else if (flags & SETKEY_ADD_OR_UPDATE) + } else if (flags & SETKEY_ADD_OR_UPDATE) { keyfound = -1; - else if (!(flags & SETKEY_DOESNT_EXIST)) - keyfound = (lookupKeyWrite(db,key) != NULL); + } else if (!(flags & SETKEY_DOESNT_EXIST)) { + keyfound = (lookupKeyWrite(db, key) != NULL); + } if (!keyfound) { - dbAdd(db,key,val); - } else if (keyfound<0) { - dbAddInternal(db,key,val,1); + dbAdd(db, key, val); + } else if (keyfound < 0) { + dbAddInternal(db, key, val, 1); } else { - dbSetValue(db,key,val,1,NULL); + dbSetValue(db, key, val, 1, NULL); } incrRefCount(val); - if (!(flags & SETKEY_KEEPTTL)) removeExpire(db,key); - if (!(flags & SETKEY_NO_SIGNAL)) signalModifiedKey(c,db,key); + if (!(flags & SETKEY_KEEPTTL)) { + removeExpire(db, key); + } + if (!(flags & SETKEY_NO_SIGNAL)) { + signalModifiedKey(c, db, key); + } } /* Return a random key, in form of an Object. @@ -352,15 +372,17 @@ robj *dbRandomKey(serverDb *db) { int maxtries = 100; int allvolatile = kvstoreSize(db->keys) == kvstoreSize(db->expires); - while(1) { + while (1) { sds key; robj *keyobj; int randomSlot = kvstoreGetFairRandomDictIndex(db->keys); de = kvstoreDictGetFairRandomKey(db->keys, randomSlot); - if (de == NULL) return NULL; + if (de == NULL) { + return NULL; + } key = dictGetKey(de); - keyobj = createStringObject(key,sdslen(key)); + keyobj = createStringObject(key, sdslen(key)); if (dbFindExpires(db, key)) { if (allvolatile && server.masterhost && --maxtries == 0) { /* If the DB is composed only of keys with an expire set, @@ -373,7 +395,7 @@ robj *dbRandomKey(serverDb *db) { * return a key name that may be already expired. */ return keyobj; } - if (expireIfNeeded(db,keyobj,0) != KEY_VALID) { + if (expireIfNeeded(db, keyobj, 0) != KEY_VALID) { decrRefCount(keyobj); continue; /* search for another key. This expired. */ } @@ -394,9 +416,9 @@ int dbGenericDelete(serverDb *db, robj *key, int async, int flags) { * need to incr to retain val */ incrRefCount(val); /* Tells the module that the key has been unlinked from the database. */ - moduleNotifyKeyUnlink(key,val,db->id,flags); + moduleNotifyKeyUnlink(key, val, db->id, flags); /* We want to try to unblock any module clients or clients using a blocking XREADGROUP */ - signalDeletedKeyAsReady(db,key,val->type); + signalDeletedKeyAsReady(db, key, val->type); /* We should call decr before freeObjAsync. If not, the refcount may be * greater than 1, so freeObjAsync doesn't work */ decrRefCount(val); @@ -466,7 +488,7 @@ robj *dbUnshareStringValue(serverDb *db, robj *key, robj *o) { robj *decoded = getDecodedObject(o); o = createRawStringObject(decoded->ptr, sdslen(decoded->ptr)); decrRefCount(decoded); - dbReplaceValue(db,key,o); + dbReplaceValue(db, key, o); } return o; } @@ -477,15 +499,13 @@ robj *dbUnshareStringValue(serverDb *db, robj *key, robj *o) { * The dbnum can be -1 if all the DBs should be emptied, or the specified * DB index if we want to empty only a single database. * The function returns the number of keys removed from the database(s). */ -long long emptyDbStructure(serverDb *dbarray, int dbnum, int async, - void(callback)(dict*)) -{ +long long emptyDbStructure(serverDb *dbarray, int dbnum, int async, void(callback)(dict *)) { long long removed = 0; int startdb, enddb; if (dbnum == -1) { startdb = 0; - enddb = server.dbnum-1; + enddb = server.dbnum - 1; } else { startdb = enddb = dbnum; } @@ -521,10 +541,10 @@ long long emptyDbStructure(serverDb *dbarray, int dbnum, int async, * On success the function returns the number of keys removed from the * database(s). Otherwise -1 is returned in the specific case the * DB number is out of range, and errno is set to EINVAL. */ -long long emptyData(int dbnum, int flags, void(callback)(dict*)) { +long long emptyData(int dbnum, int flags, void(callback)(dict *)) { int async = (flags & EMPTYDB_ASYNC); int with_functions = !(flags & EMPTYDB_NOFUNCTIONS); - ValkeyModuleFlushInfoV1 fi = {VALKEYMODULE_FLUSHINFO_VERSION,!async,dbnum}; + ValkeyModuleFlushInfoV1 fi = {VALKEYMODULE_FLUSHINFO_VERSION, !async, dbnum}; long long removed = 0; if (dbnum < -1 || dbnum >= server.dbnum) { @@ -533,9 +553,7 @@ long long emptyData(int dbnum, int flags, void(callback)(dict*)) { } /* Fire the flushdb modules event. */ - moduleFireServerEvent(VALKEYMODULE_EVENT_FLUSHDB, - VALKEYMODULE_SUBEVENT_FLUSHDB_START, - &fi); + moduleFireServerEvent(VALKEYMODULE_EVENT_FLUSHDB, VALKEYMODULE_SUBEVENT_FLUSHDB_START, &fi); /* Make sure the WATCHed keys are affected by the FLUSH* commands. * Note that we need to call the function while the keys are still @@ -545,7 +563,9 @@ long long emptyData(int dbnum, int flags, void(callback)(dict*)) { /* Empty the database structure. */ removed = emptyDbStructure(server.db, dbnum, async, callback); - if (dbnum == -1) flushSlaveKeysWithExpireList(); + if (dbnum == -1) { + flushSlaveKeysWithExpireList(); + } if (with_functions) { serverAssert(dbnum == -1); @@ -554,9 +574,7 @@ long long emptyData(int dbnum, int flags, void(callback)(dict*)) { /* Also fire the end event. Note that this event will fire almost * immediately after the start event if the flush is asynchronous. */ - moduleFireServerEvent(VALKEYMODULE_EVENT_FLUSHDB, - VALKEYMODULE_SUBEVENT_FLUSHDB_END, - &fi); + moduleFireServerEvent(VALKEYMODULE_EVENT_FLUSHDB, VALKEYMODULE_SUBEVENT_FLUSHDB_END, &fi); return removed; } @@ -569,8 +587,8 @@ serverDb *initTempDb(void) { slot_count_bits = CLUSTER_SLOT_MASK_BITS; flags |= KVSTORE_FREE_EMPTY_DICTS; } - serverDb *tempDb = zcalloc(sizeof(serverDb)*server.dbnum); - for (int i=0; i= server.dbnum) + if (id < 0 || id >= server.dbnum) { return C_ERR; + } c->db = &server.db[id]; return C_OK; } @@ -621,15 +640,15 @@ long long dbTotalServerKeyCount(void) { /* Note that the 'c' argument may be NULL if the key was modified out of * a context of a client. */ void signalModifiedKey(client *c, serverDb *db, robj *key) { - touchWatchedKey(db,key); - trackingInvalidateKey(c,key,1); + touchWatchedKey(db, key); + trackingInvalidateKey(c, key, 1); } void signalFlushedDb(int dbid, int async) { int startdb, enddb; if (dbid == -1) { startdb = 0; - enddb = server.dbnum-1; + enddb = server.dbnum - 1; } else { startdb = enddb = dbid; } @@ -661,14 +680,14 @@ void signalFlushedDb(int dbid, int async) { * C_ERR is returned and the function sends an error to the client. */ int getFlushCommandFlags(client *c, int *flags) { /* Parse the optional ASYNC option. */ - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"sync")) { + if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "sync")) { *flags = EMPTYDB_NO_FLAGS; - } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"async")) { + } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "async")) { *flags = EMPTYDB_ASYNC; } else if (c->argc == 1) { *flags = server.lazyfree_lazy_user_flush ? EMPTYDB_ASYNC : EMPTYDB_NO_FLAGS; } else { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return C_ERR; } return C_OK; @@ -676,20 +695,23 @@ int getFlushCommandFlags(client *c, int *flags) { /* Flushes the whole server data set. */ void flushAllDataAndResetRDB(int flags) { - server.dirty += emptyData(-1,flags,NULL); - if (server.child_type == CHILD_TYPE_RDB) killRDBChild(); + server.dirty += emptyData(-1, flags, NULL); + if (server.child_type == CHILD_TYPE_RDB) { + killRDBChild(); + } if (server.saveparamslen > 0) { rdbSaveInfo rsi, *rsiptr; rsiptr = rdbPopulateSaveInfo(&rsi); - rdbSave(SLAVE_REQ_NONE,server.rdb_filename,rsiptr,RDBFLAGS_NONE); + rdbSave(SLAVE_REQ_NONE, server.rdb_filename, rsiptr, RDBFLAGS_NONE); } #if defined(USE_JEMALLOC) /* jemalloc 5 doesn't release pages back to the OS when there's no traffic. * for large databases, flushdb blocks for long anyway, so a bit more won't * harm and this way the flush and purge will be synchronous. */ - if (!(flags & EMPTYDB_ASYNC)) + if (!(flags & EMPTYDB_ASYNC)) { jemalloc_purge(); + } #endif } @@ -699,22 +721,25 @@ void flushAllDataAndResetRDB(int flags) { void flushdbCommand(client *c) { int flags; - if (getFlushCommandFlags(c,&flags) == C_ERR) return; + if (getFlushCommandFlags(c, &flags) == C_ERR) { + return; + } /* flushdb should not flush the functions */ - server.dirty += emptyData(c->db->id,flags | EMPTYDB_NOFUNCTIONS,NULL); + server.dirty += emptyData(c->db->id, flags | EMPTYDB_NOFUNCTIONS, NULL); /* Without the forceCommandPropagation, when DB was already empty, * FLUSHDB will not be replicated nor put into the AOF. */ forceCommandPropagation(c, PROPAGATE_REPL | PROPAGATE_AOF); - addReply(c,shared.ok); + addReply(c, shared.ok); #if defined(USE_JEMALLOC) /* jemalloc 5 doesn't release pages back to the OS when there's no traffic. * for large databases, flushdb blocks for long anyway, so a bit more won't * harm and this way the flush and purge will be synchronous. */ - if (!(flags & EMPTYDB_ASYNC)) + if (!(flags & EMPTYDB_ASYNC)) { jemalloc_purge(); + } #endif } @@ -723,7 +748,9 @@ void flushdbCommand(client *c) { * Flushes the whole server data set. */ void flushallCommand(client *c) { int flags; - if (getFlushCommandFlags(c,&flags) == C_ERR) return; + if (getFlushCommandFlags(c, &flags) == C_ERR) { + return; + } /* flushall should not flush the functions */ flushAllDataAndResetRDB(flags | EMPTYDB_NOFUNCTIONS); @@ -731,7 +758,7 @@ void flushallCommand(client *c) { * FLUSHALL will not be replicated nor put into the AOF. */ forceCommandPropagation(c, PROPAGATE_REPL | PROPAGATE_AOF); - addReply(c,shared.ok); + addReply(c, shared.ok); } /* This command implements DEL and UNLINK. */ @@ -739,27 +766,26 @@ void delGenericCommand(client *c, int lazy) { int numdel = 0, j; for (j = 1; j < c->argc; j++) { - if (expireIfNeeded(c->db,c->argv[j],0) == KEY_DELETED) + if (expireIfNeeded(c->db, c->argv[j], 0) == KEY_DELETED) { continue; - int deleted = lazy ? dbAsyncDelete(c->db,c->argv[j]) : - dbSyncDelete(c->db,c->argv[j]); + } + int deleted = lazy ? dbAsyncDelete(c->db, c->argv[j]) : dbSyncDelete(c->db, c->argv[j]); if (deleted) { - signalModifiedKey(c,c->db,c->argv[j]); - notifyKeyspaceEvent(NOTIFY_GENERIC, - "del",c->argv[j],c->db->id); + signalModifiedKey(c, c->db, c->argv[j]); + notifyKeyspaceEvent(NOTIFY_GENERIC, "del", c->argv[j], c->db->id); server.dirty++; numdel++; } } - addReplyLongLong(c,numdel); + addReplyLongLong(c, numdel); } void delCommand(client *c) { - delGenericCommand(c,server.lazyfree_lazy_user_del); + delGenericCommand(c, server.lazyfree_lazy_user_del); } void unlinkCommand(client *c) { - delGenericCommand(c,1); + delGenericCommand(c, 1); } /* EXISTS key1 key2 ... key_N. @@ -769,25 +795,28 @@ void existsCommand(client *c) { int j; for (j = 1; j < c->argc; j++) { - if (lookupKeyReadWithFlags(c->db,c->argv[j],LOOKUP_NOTOUCH)) count++; + if (lookupKeyReadWithFlags(c->db, c->argv[j], LOOKUP_NOTOUCH)) { + count++; + } } - addReplyLongLong(c,count); + addReplyLongLong(c, count); } void selectCommand(client *c) { int id; - if (getIntFromObjectOrReply(c, c->argv[1], &id, NULL) != C_OK) + if (getIntFromObjectOrReply(c, c->argv[1], &id, NULL) != C_OK) { return; + } if (server.cluster_enabled && id != 0) { - addReplyError(c,"SELECT is not allowed in cluster mode"); + addReplyError(c, "SELECT is not allowed in cluster mode"); return; } - if (selectDb(c,id) == C_ERR) { - addReplyError(c,"DB index is out of range"); + if (selectDb(c, id) == C_ERR) { + addReplyError(c, "DB index is out of range"); } else { - addReply(c,shared.ok); + addReply(c, shared.ok); } } @@ -799,7 +828,7 @@ void randomkeyCommand(client *c) { return; } - addReplyBulk(c,key); + addReplyBulk(c, key); decrRefCount(key); } @@ -818,7 +847,7 @@ void keysCommand(client *c) { if (pslot != -1) { if (!kvstoreDictSize(c->db->keys, pslot)) { /* Requested slot is empty */ - setDeferredArrayLen(c,replylen,0); + setDeferredArrayLen(c, replylen, 0); return; } kvs_di = kvstoreGetDictSafeIterator(c->db->keys, pslot); @@ -829,47 +858,52 @@ void keysCommand(client *c) { while ((de = kvs_di ? kvstoreDictIteratorNext(kvs_di) : kvstoreIteratorNext(kvs_it)) != NULL) { sds key = dictGetKey(de); - if (allkeys || stringmatchlen(pattern,plen,key,sdslen(key),0)) { + if (allkeys || stringmatchlen(pattern, plen, key, sdslen(key), 0)) { initStaticStringObject(keyobj, key); if (!keyIsExpired(c->db, &keyobj)) { addReplyBulkCBuffer(c, key, sdslen(key)); numkeys++; } } - if (c->flags & CLIENT_CLOSE_ASAP) + if (c->flags & CLIENT_CLOSE_ASAP) { break; + } } - if (kvs_di) + if (kvs_di) { kvstoreReleaseDictIterator(kvs_di); - if (kvs_it) + } + if (kvs_it) { kvstoreIteratorRelease(kvs_it); - setDeferredArrayLen(c,replylen,numkeys); + } + setDeferredArrayLen(c, replylen, numkeys); } /* Data used by the dict scan callback. */ typedef struct { - list *keys; /* elements that collect from dict */ - robj *o; /* o must be a hash/set/zset object, NULL means current db */ + list *keys; /* elements that collect from dict */ + robj *o; /* o must be a hash/set/zset object, NULL means current db */ long long type; /* the particular type when scan the db */ - sds pattern; /* pattern string, NULL means no pattern */ - long sampled; /* cumulative number of keys sampled */ - int only_keys; /* set to 1 means to return keys only */ + sds pattern; /* pattern string, NULL means no pattern */ + long sampled; /* cumulative number of keys sampled */ + int only_keys; /* set to 1 means to return keys only */ } scanData; /* Helper function to compare key type in scan commands */ int objectTypeCompare(robj *o, long long target) { if (o->type != OBJ_MODULE) { - if (o->type != target) + if (o->type != target) { return 0; - else + } else { return 1; + } } /* module type compare */ long long mt = (long long)VALKEYMODULE_TYPE_SIGN(((moduleValue *)o->ptr)->type->id); - if (target != -mt) + if (target != -mt) { return 0; - else + } else { return 1; + } } /* This callback is used by scanGenericCommand in order to collect elements * returned by the dictionary iterator into a list. */ @@ -920,7 +954,9 @@ void scanCallback(void *privdata, const dictEntry *de) { } listAddNodeTail(keys, key); - if (val) listAddNodeTail(keys, val); + if (val) { + listAddNodeTail(keys, val); + } } /* Try to parse a SCAN cursor stored at object 'o': @@ -935,19 +971,11 @@ int parseScanCursorOrReply(client *c, robj *o, unsigned long long *cursor) { return C_OK; } -char *obj_type_name[OBJ_TYPE_MAX] = { - "string", - "list", - "set", - "zset", - "hash", - NULL, /* module type is special */ - "stream" -}; +char *obj_type_name[OBJ_TYPE_MAX] = {"string", "list", "set", "zset", "hash", NULL, /* module type is special */ + "stream"}; /* Helper function to get type from a string in scan commands */ long long getObjectTypeByName(char *name) { - for (long long i = 0; i < OBJ_TYPE_MAX; i++) { if (obj_type_name[i] && !strcasecmp(name, obj_type_name[i])) { return i; @@ -955,7 +983,9 @@ long long getObjectTypeByName(char *name) { } moduleType *mt = moduleTypeLookupModuleByNameIgnoreCase(name); - if (mt != NULL) return -(VALKEYMODULE_TYPE_SIGN(mt->id)); + if (mt != NULL) { + return -(VALKEYMODULE_TYPE_SIGN(mt->id)); + } return LLONG_MAX; } @@ -998,8 +1028,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { /* Object must be NULL (to iterate keys names), or the type of the object * must be Set, Sorted Set, or Hash. */ - serverAssert(o == NULL || o->type == OBJ_SET || o->type == OBJ_HASH || - o->type == OBJ_ZSET); + serverAssert(o == NULL || o->type == OBJ_SET || o->type == OBJ_HASH || o->type == OBJ_ZSET); /* Set i to the first option argument. The previous one is the cursor. */ i = (o == NULL) ? 2 : 3; /* Skip the key argument if needed. */ @@ -1008,20 +1037,18 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { while (i < c->argc) { j = c->argc - i; if (!strcasecmp(c->argv[i]->ptr, "count") && j >= 2) { - if (getLongFromObjectOrReply(c, c->argv[i+1], &count, NULL) - != C_OK) - { + if (getLongFromObjectOrReply(c, c->argv[i + 1], &count, NULL) != C_OK) { return; } if (count < 1) { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } i += 2; } else if (!strcasecmp(c->argv[i]->ptr, "match") && j >= 2) { - pat = c->argv[i+1]->ptr; + pat = c->argv[i + 1]->ptr; patlen = sdslen(pat); /* The pattern always matches if it is exactly "*", so it is @@ -1031,14 +1058,14 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { i += 2; } else if (!strcasecmp(c->argv[i]->ptr, "type") && o == NULL && j >= 2) { /* SCAN for a particular type only applies to the db dict */ - typename = c->argv[i+1]->ptr; + typename = c->argv[i + 1]->ptr; type = getObjectTypeByName(typename); if (type == LLONG_MAX) { /* TODO: uncomment in version 8.0 addReplyErrorFormat(c, "unknown type name '%s'", typename); return; */ } - i+= 2; + i += 2; } else if (!strcasecmp(c->argv[i]->ptr, "novalues")) { if (!o || o->type != OBJ_HASH) { addReplyError(c, "NOVALUES option can only be used in HSCAN"); @@ -1054,7 +1081,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { only_keys = 1; i++; } else { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } } @@ -1090,7 +1117,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { * The exception to the above is ZSET, where we do allocate temporary * strings even when scanning a dict. */ if (o && (!ht || o->type == OBJ_ZSET)) { - listSetFreeMethod(keys, (void (*)(void*))sdsfree); + listSetFreeMethod(keys, (void (*)(void *))sdsfree); } /* For main dictionary scan or data structure using hashtable. */ @@ -1099,7 +1126,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { * COUNT, so if the hash table is in a pathological state (very * sparsely populated) we avoid to block too much time at the cost * of returning no or very few elements. */ - long maxiterations = count*10; + long maxiterations = count * 10; /* We pass scanData which have three pointers to the callback: * 1. data.keys: the list to which it will add new elements; @@ -1112,7 +1139,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { * working on an empty dict, one with a lot of empty buckets, and * for the buckets are not empty, we need to limit the spampled number * to prevent a long hang time caused by filtering too many keys; - * 6. data.only_keys: to control whether values will be returned or + * 6. data.only_keys: to control whether values will be returned or * only keys are returned. */ scanData data = { .keys = keys, @@ -1155,15 +1182,13 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { } setTypeReleaseIterator(si); cursor = 0; - } else if ((o->type == OBJ_HASH || o->type == OBJ_ZSET) && - o->encoding == OBJ_ENCODING_LISTPACK) - { + } else if ((o->type == OBJ_HASH || o->type == OBJ_ZSET) && o->encoding == OBJ_ENCODING_LISTPACK) { unsigned char *p = lpFirst(o->ptr); unsigned char *str; int64_t len; unsigned char intbuf[LP_INTBUF_SIZE]; - while(p) { + while (p) { str = lpGet(p, &len, intbuf); /* point to the value */ p = lpNext(o->ptr, p); @@ -1198,7 +1223,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { /* Filter an element if it isn't the type we want. */ /* TODO: remove this in version 8.0 */ if (typename) { - robj* typecheck = lookupKeyReadWithFlags(c->db, &kobj, LOOKUP_NOTOUCH|LOOKUP_NONOTIFY); + robj *typecheck = lookupKeyReadWithFlags(c->db, &kobj, LOOKUP_NOTOUCH | LOOKUP_NONOTIFY); if (!typecheck || !objectTypeCompare(typecheck, type)) { listDelNode(keys, ln); } @@ -1212,7 +1237,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { /* Step 4: Reply to the client. */ addReplyArrayLen(c, 2); - addReplyBulkLongLong(c,cursor); + addReplyBulkLongLong(c, cursor); addReplyArrayLen(c, listLength(keys)); while ((node = listFirst(keys)) != NULL) { @@ -1227,21 +1252,23 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { /* The SCAN command completely relies on scanGenericCommand. */ void scanCommand(client *c) { unsigned long long cursor; - if (parseScanCursorOrReply(c,c->argv[1],&cursor) == C_ERR) return; - scanGenericCommand(c,NULL,cursor); + if (parseScanCursorOrReply(c, c->argv[1], &cursor) == C_ERR) { + return; + } + scanGenericCommand(c, NULL, cursor); } void dbsizeCommand(client *c) { - addReplyLongLong(c,kvstoreSize(c->db->keys)); + addReplyLongLong(c, kvstoreSize(c->db->keys)); } void lastsaveCommand(client *c) { - addReplyLongLong(c,server.lastsave); + addReplyLongLong(c, server.lastsave); } void typeCommand(client *c) { robj *o; - o = lookupKeyReadWithFlags(c->db,c->argv[1],LOOKUP_NOTOUCH); + o = lookupKeyReadWithFlags(c->db, c->argv[1], LOOKUP_NOTOUCH); addReplyStatus(c, getObjectTypeName(o)); } @@ -1250,9 +1277,9 @@ void shutdownCommand(client *c) { int flags = SHUTDOWN_NOFLAGS; int abort = 0; for (int i = 1; i < c->argc; i++) { - if (!strcasecmp(c->argv[i]->ptr,"nosave")) { + if (!strcasecmp(c->argv[i]->ptr, "nosave")) { flags |= SHUTDOWN_NOSAVE; - } else if (!strcasecmp(c->argv[i]->ptr,"save")) { + } else if (!strcasecmp(c->argv[i]->ptr, "save")) { flags |= SHUTDOWN_SAVE; } else if (!strcasecmp(c->argv[i]->ptr, "now")) { flags |= SHUTDOWN_NOW; @@ -1261,23 +1288,22 @@ void shutdownCommand(client *c) { } else if (!strcasecmp(c->argv[i]->ptr, "abort")) { abort = 1; } else { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } } - if ((abort && flags != SHUTDOWN_NOFLAGS) || - (flags & SHUTDOWN_NOSAVE && flags & SHUTDOWN_SAVE)) - { + if ((abort && flags != SHUTDOWN_NOFLAGS) || (flags & SHUTDOWN_NOSAVE && flags & SHUTDOWN_SAVE)) { /* Illegal combo. */ - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } if (abort) { - if (abortShutdown() == C_OK) + if (abortShutdown() == C_OK) { addReply(c, shared.ok); - else + } else { addReplyError(c, "No shutdown in progress."); + } return; } @@ -1302,7 +1328,9 @@ void shutdownCommand(client *c) { } blockClientShutdown(c); - if (prepareForShutdown(flags) == C_OK) exit(0); + if (prepareForShutdown(flags) == C_OK) { + exit(0); + } /* If we're here, then shutdown is ongoing (the client is still blocked) or * failed (the client has received an error). */ } @@ -1314,47 +1342,50 @@ void renameGenericCommand(client *c, int nx) { /* When source and dest key is the same, no operation is performed, * if the key exists, however we still return an error on unexisting key. */ - if (sdscmp(c->argv[1]->ptr,c->argv[2]->ptr) == 0) samekey = 1; + if (sdscmp(c->argv[1]->ptr, c->argv[2]->ptr) == 0) { + samekey = 1; + } - if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr)) == NULL) + if ((o = lookupKeyWriteOrReply(c, c->argv[1], shared.nokeyerr)) == NULL) { return; + } if (samekey) { - addReply(c,nx ? shared.czero : shared.ok); + addReply(c, nx ? shared.czero : shared.ok); return; } incrRefCount(o); - expire = getExpire(c->db,c->argv[1]); - if (lookupKeyWrite(c->db,c->argv[2]) != NULL) { + expire = getExpire(c->db, c->argv[1]); + if (lookupKeyWrite(c->db, c->argv[2]) != NULL) { if (nx) { decrRefCount(o); - addReply(c,shared.czero); + addReply(c, shared.czero); return; } /* Overwrite: delete the old key before creating the new one * with the same name. */ - dbDelete(c->db,c->argv[2]); - } - dbAdd(c->db,c->argv[2],o); - if (expire != -1) setExpire(c,c->db,c->argv[2],expire); - dbDelete(c->db,c->argv[1]); - signalModifiedKey(c,c->db,c->argv[1]); - signalModifiedKey(c,c->db,c->argv[2]); - notifyKeyspaceEvent(NOTIFY_GENERIC,"rename_from", - c->argv[1],c->db->id); - notifyKeyspaceEvent(NOTIFY_GENERIC,"rename_to", - c->argv[2],c->db->id); + dbDelete(c->db, c->argv[2]); + } + dbAdd(c->db, c->argv[2], o); + if (expire != -1) { + setExpire(c, c->db, c->argv[2], expire); + } + dbDelete(c->db, c->argv[1]); + signalModifiedKey(c, c->db, c->argv[1]); + signalModifiedKey(c, c->db, c->argv[2]); + notifyKeyspaceEvent(NOTIFY_GENERIC, "rename_from", c->argv[1], c->db->id); + notifyKeyspaceEvent(NOTIFY_GENERIC, "rename_to", c->argv[2], c->db->id); server.dirty++; - addReply(c,nx ? shared.cone : shared.ok); + addReply(c, nx ? shared.cone : shared.ok); } void renameCommand(client *c) { - renameGenericCommand(c,0); + renameGenericCommand(c, 0); } void renamenxCommand(client *c) { - renameGenericCommand(c,1); + renameGenericCommand(c, 1); } void moveCommand(client *c) { @@ -1364,7 +1395,7 @@ void moveCommand(client *c) { long long expire; if (server.cluster_enabled) { - addReplyError(c,"MOVE is not allowed in cluster mode"); + addReplyError(c, "MOVE is not allowed in cluster mode"); return; } @@ -1372,51 +1403,52 @@ void moveCommand(client *c) { src = c->db; srcid = c->db->id; - if (getIntFromObjectOrReply(c, c->argv[2], &dbid, NULL) != C_OK) + if (getIntFromObjectOrReply(c, c->argv[2], &dbid, NULL) != C_OK) { return; + } - if (selectDb(c,dbid) == C_ERR) { - addReplyError(c,"DB index is out of range"); + if (selectDb(c, dbid) == C_ERR) { + addReplyError(c, "DB index is out of range"); return; } dst = c->db; - selectDb(c,srcid); /* Back to the source DB */ + selectDb(c, srcid); /* Back to the source DB */ /* If the user is moving using as target the same * DB as the source DB it is probably an error. */ if (src == dst) { - addReplyErrorObject(c,shared.sameobjecterr); + addReplyErrorObject(c, shared.sameobjecterr); return; } /* Check if the element exists and get a reference */ - o = lookupKeyWrite(c->db,c->argv[1]); + o = lookupKeyWrite(c->db, c->argv[1]); if (!o) { - addReply(c,shared.czero); + addReply(c, shared.czero); return; } - expire = getExpire(c->db,c->argv[1]); + expire = getExpire(c->db, c->argv[1]); /* Return zero if the key already exists in the target DB */ - if (lookupKeyWrite(dst,c->argv[1]) != NULL) { - addReply(c,shared.czero); + if (lookupKeyWrite(dst, c->argv[1]) != NULL) { + addReply(c, shared.czero); return; } - dbAdd(dst,c->argv[1],o); - if (expire != -1) setExpire(c,dst,c->argv[1],expire); + dbAdd(dst, c->argv[1], o); + if (expire != -1) { + setExpire(c, dst, c->argv[1], expire); + } incrRefCount(o); /* OK! key moved, free the entry in the source DB */ - dbDelete(src,c->argv[1]); - signalModifiedKey(c,src,c->argv[1]); - signalModifiedKey(c,dst,c->argv[1]); - notifyKeyspaceEvent(NOTIFY_GENERIC, - "move_from",c->argv[1],src->id); - notifyKeyspaceEvent(NOTIFY_GENERIC, - "move_to",c->argv[1],dst->id); + dbDelete(src, c->argv[1]); + signalModifiedKey(c, src, c->argv[1]); + signalModifiedKey(c, dst, c->argv[1]); + notifyKeyspaceEvent(NOTIFY_GENERIC, "move_from", c->argv[1], src->id); + notifyKeyspaceEvent(NOTIFY_GENERIC, "move_to", c->argv[1], dst->id); server.dirty++; - addReply(c,shared.cone); + addReply(c, shared.cone); } void copyCommand(client *c) { @@ -1426,8 +1458,8 @@ void copyCommand(client *c) { long long expire; int j, replace = 0, delete = 0; - /* Obtain source and target DB pointers - * Default target DB is the same as the source DB + /* Obtain source and target DB pointers + * Default target DB is the same as the source DB * Parse the REPLACE option and targetDB option. */ src = c->db; dst = c->db; @@ -1435,27 +1467,28 @@ void copyCommand(client *c) { dbid = c->db->id; for (j = 3; j < c->argc; j++) { int additional = c->argc - j - 1; - if (!strcasecmp(c->argv[j]->ptr,"replace")) { + if (!strcasecmp(c->argv[j]->ptr, "replace")) { replace = 1; } else if (!strcasecmp(c->argv[j]->ptr, "db") && additional >= 1) { - if (getIntFromObjectOrReply(c, c->argv[j+1], &dbid, NULL) != C_OK) + if (getIntFromObjectOrReply(c, c->argv[j + 1], &dbid, NULL) != C_OK) { return; + } if (selectDb(c, dbid) == C_ERR) { - addReplyError(c,"DB index is out of range"); + addReplyError(c, "DB index is out of range"); return; } dst = c->db; - selectDb(c,srcid); /* Back to the source DB */ - j++; /* Consume additional arg. */ + selectDb(c, srcid); /* Back to the source DB */ + j++; /* Consume additional arg. */ } else { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } } if ((server.cluster_enabled == 1) && (srcid != 0 || dbid != 0)) { - addReplyError(c,"Copying to another database is not allowed in cluster mode"); + addReplyError(c, "Copying to another database is not allowed in cluster mode"); return; } @@ -1465,60 +1498,76 @@ void copyCommand(client *c) { robj *key = c->argv[1]; robj *newkey = c->argv[2]; if (src == dst && (sdscmp(key->ptr, newkey->ptr) == 0)) { - addReplyErrorObject(c,shared.sameobjecterr); + addReplyErrorObject(c, shared.sameobjecterr); return; } /* Check if the element exists and get a reference */ o = lookupKeyRead(c->db, key); if (!o) { - addReply(c,shared.czero); + addReply(c, shared.czero); return; } - expire = getExpire(c->db,key); + expire = getExpire(c->db, key); - /* Return zero if the key already exists in the target DB. + /* Return zero if the key already exists in the target DB. * If REPLACE option is selected, delete newkey from targetDB. */ - if (lookupKeyWrite(dst,newkey) != NULL) { + if (lookupKeyWrite(dst, newkey) != NULL) { if (replace) { delete = 1; } else { - addReply(c,shared.czero); + addReply(c, shared.czero); return; } } /* Duplicate object according to object's type. */ robj *newobj; - switch(o->type) { - case OBJ_STRING: newobj = dupStringObject(o); break; - case OBJ_LIST: newobj = listTypeDup(o); break; - case OBJ_SET: newobj = setTypeDup(o); break; - case OBJ_ZSET: newobj = zsetDup(o); break; - case OBJ_HASH: newobj = hashTypeDup(o); break; - case OBJ_STREAM: newobj = streamDup(o); break; - case OBJ_MODULE: - newobj = moduleTypeDupOrReply(c, key, newkey, dst->id, o); - if (!newobj) return; - break; - default: - addReplyError(c, "unknown type object"); + switch (o->type) { + case OBJ_STRING: + newobj = dupStringObject(o); + break; + case OBJ_LIST: + newobj = listTypeDup(o); + break; + case OBJ_SET: + newobj = setTypeDup(o); + break; + case OBJ_ZSET: + newobj = zsetDup(o); + break; + case OBJ_HASH: + newobj = hashTypeDup(o); + break; + case OBJ_STREAM: + newobj = streamDup(o); + break; + case OBJ_MODULE: + newobj = moduleTypeDupOrReply(c, key, newkey, dst->id, o); + if (!newobj) { return; + } + break; + default: + addReplyError(c, "unknown type object"); + return; } if (delete) { - dbDelete(dst,newkey); + dbDelete(dst, newkey); } - dbAdd(dst,newkey,newobj); - if (expire != -1) setExpire(c, dst, newkey, expire); + dbAdd(dst, newkey, newobj); + if (expire != -1) { + setExpire(c, dst, newkey, expire); + } /* OK! key copied */ - signalModifiedKey(c,dst,c->argv[2]); - notifyKeyspaceEvent(NOTIFY_GENERIC,"copy_to",c->argv[2],dst->id); + signalModifiedKey(c, dst, c->argv[2]); + notifyKeyspaceEvent(NOTIFY_GENERIC, "copy_to", c->argv[2], dst->id); server.dirty++; - addReply(c,shared.cone); + addReply(c, shared.cone); } /* Helper function for dbSwapDatabases(): scans the list of keys that have @@ -1528,7 +1577,7 @@ void copyCommand(client *c) { void scanDatabaseForReadyKeys(serverDb *db) { dictEntry *de; dictIterator *di = dictGetSafeIterator(db->blocking_keys); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { robj *key = dictGetKey(de); dictEntry *kde = dbFind(db, key->ptr); if (kde) { @@ -1545,7 +1594,7 @@ void scanDatabaseForReadyKeys(serverDb *db) { void scanDatabaseForDeletedKeys(serverDb *emptied, serverDb *replaced_with) { dictEntry *de; dictIterator *di = dictGetSafeIterator(emptied->blocking_keys); - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { robj *key = dictGetKey(de); int existed = 0, exists = 0; int original_type = -1, curr_type = -1; @@ -1566,8 +1615,9 @@ void scanDatabaseForDeletedKeys(serverDb *emptied, serverDb *replaced_with) { } } /* We want to try to unblock any client using a blocking XREADGROUP */ - if ((existed && !exists) || original_type != curr_type) + if ((existed && !exists) || original_type != curr_type) { signalDeletedKeyAsReady(emptied, key, original_type); + } } dictReleaseIterator(di); } @@ -1581,9 +1631,12 @@ void scanDatabaseForDeletedKeys(serverDb *emptied, serverDb *replaced_with) { * Returns C_ERR if at least one of the DB ids are out of range, otherwise * C_OK is returned. */ int dbSwapDatabases(int id1, int id2) { - if (id1 < 0 || id1 >= server.dbnum || - id2 < 0 || id2 >= server.dbnum) return C_ERR; - if (id1 == id2) return C_OK; + if (id1 < 0 || id1 >= server.dbnum || id2 < 0 || id2 >= server.dbnum) { + return C_ERR; + } + if (id1 == id2) { + return C_OK; + } serverDb aux = server.db[id1]; serverDb *db1 = &server.db[id1], *db2 = &server.db[id2]; @@ -1627,7 +1680,7 @@ int dbSwapDatabases(int id1, int id2) { * database (temp) as the main (active) database, the actual freeing of old database * (which will now be placed in the temp one) is done later. */ void swapMainDbWithTempDb(serverDb *tempDb) { - for (int i=0; ikeys = newdb->keys; activedb->expires = newdb->expires; @@ -1673,28 +1726,28 @@ void swapdbCommand(client *c) { /* Not allowed in cluster mode: we have just DB 0 there. */ if (server.cluster_enabled) { - addReplyError(c,"SWAPDB is not allowed in cluster mode"); + addReplyError(c, "SWAPDB is not allowed in cluster mode"); return; } /* Get the two DBs indexes. */ - if (getIntFromObjectOrReply(c, c->argv[1], &id1, - "invalid first DB index") != C_OK) + if (getIntFromObjectOrReply(c, c->argv[1], &id1, "invalid first DB index") != C_OK) { return; + } - if (getIntFromObjectOrReply(c, c->argv[2], &id2, - "invalid second DB index") != C_OK) + if (getIntFromObjectOrReply(c, c->argv[2], &id2, "invalid second DB index") != C_OK) { return; + } /* Swap... */ - if (dbSwapDatabases(id1,id2) == C_ERR) { - addReplyError(c,"DB index is out of range"); + if (dbSwapDatabases(id1, id2) == C_ERR) { + addReplyError(c, "DB index is out of range"); return; } else { - ValkeyModuleSwapDbInfo si = {VALKEYMODULE_SWAPDBINFO_VERSION,id1,id2}; - moduleFireServerEvent(VALKEYMODULE_EVENT_SWAPDB,0,&si); + ValkeyModuleSwapDbInfo si = {VALKEYMODULE_SWAPDBINFO_VERSION, id1, id2}; + moduleFireServerEvent(VALKEYMODULE_EVENT_SWAPDB, 0, &si); server.dirty++; - addReply(c,shared.ok); + addReply(c, shared.ok); } } @@ -1716,7 +1769,7 @@ void setExpire(client *c, serverDb *db, robj *key, long long when) { /* Reuse the sds from the main dict in the expire dict */ int slot = getKeySlot(key->ptr); kde = kvstoreDictFind(db->keys, slot, key->ptr); - serverAssertWithInfo(NULL,key,kde != NULL); + serverAssertWithInfo(NULL, key, kde != NULL); de = kvstoreDictAddRaw(db->expires, slot, dictGetKey(kde), &existing); if (existing) { dictSetSignedIntegerVal(existing, when); @@ -1725,8 +1778,9 @@ void setExpire(client *c, serverDb *db, robj *key, long long when) { } int writable_slave = server.masterhost && server.repl_slave_ro == 0; - if (c && writable_slave && !(c->flags & CLIENT_MASTER)) - rememberSlaveKeyWithExpire(db,key); + if (c && writable_slave && !(c->flags & CLIENT_MASTER)) { + rememberSlaveKeyWithExpire(db, key); + } } /* Return the expire time of the specified key, or -1 if no expire @@ -1734,8 +1788,9 @@ void setExpire(client *c, serverDb *db, robj *key, long long when) { long long getExpire(serverDb *db, robj *key) { dictEntry *de; - if ((de = dbFindExpires(db, key->ptr)) == NULL) + if ((de = dbFindExpires(db, key->ptr)) == NULL) { return -1; + } return dictGetSignedIntegerVal(de); } @@ -1744,12 +1799,12 @@ long long getExpire(serverDb *db, robj *key) { void deleteExpiredKeyAndPropagate(serverDb *db, robj *keyobj) { mstime_t expire_latency; latencyStartMonitor(expire_latency); - dbGenericDelete(db,keyobj,server.lazyfree_lazy_expire,DB_FLAG_KEY_EXPIRED); + dbGenericDelete(db, keyobj, server.lazyfree_lazy_expire, DB_FLAG_KEY_EXPIRED); latencyEndMonitor(expire_latency); - latencyAddSampleIfNeeded("expire-del",expire_latency); - notifyKeyspaceEvent(NOTIFY_EXPIRED,"expired",keyobj,db->id); + latencyAddSampleIfNeeded("expire-del", expire_latency); + notifyKeyspaceEvent(NOTIFY_EXPIRED, "expired", keyobj, db->id); signalModifiedKey(NULL, db, keyobj); - propagateDeletion(db,keyobj,server.lazyfree_lazy_expire); + propagateDeletion(db, keyobj, server.lazyfree_lazy_expire); server.stat_expiredkeys++; } @@ -1784,7 +1839,7 @@ void propagateDeletion(serverDb *db, robj *key, int lazy) { * Even if module executed a command without asking for propagation. */ int prev_replication_allowed = server.replication_allowed; server.replication_allowed = 1; - alsoPropagate(db->id,argv,2,PROPAGATE_AOF|PROPAGATE_REPL); + alsoPropagate(db->id, argv, 2, PROPAGATE_AOF | PROPAGATE_REPL); server.replication_allowed = prev_replication_allowed; decrRefCount(argv[0]); @@ -1794,12 +1849,16 @@ void propagateDeletion(serverDb *db, robj *key, int lazy) { /* Check if the key is expired. */ int keyIsExpired(serverDb *db, robj *key) { /* Don't expire anything while loading. It will be done later. */ - if (server.loading) return 0; + if (server.loading) { + return 0; + } - mstime_t when = getExpire(db,key); + mstime_t when = getExpire(db, key); mstime_t now; - if (when < 0) return 0; /* No expire for this key */ + if (when < 0) { + return 0; /* No expire for this key */ + } now = commandTimeSnapshot(); @@ -1836,11 +1895,15 @@ int keyIsExpired(serverDb *db, robj *key) { * EXPIRE_AVOID_DELETE_EXPIRED flag. * * The return value of the function is KEY_VALID if the key is still valid. - * The function returns KEY_EXPIRED if the key is expired BUT not deleted, + * The function returns KEY_EXPIRED if the key is expired BUT not deleted, * or returns KEY_DELETED if the key is expired and deleted. */ keyStatus expireIfNeeded(serverDb *db, robj *key, int flags) { - if (server.lazy_expire_disabled) return KEY_VALID; - if (!keyIsExpired(db,key)) return KEY_VALID; + if (server.lazy_expire_disabled) { + return KEY_VALID; + } + if (!keyIsExpired(db, key)) { + return KEY_VALID; + } /* If we are running in the context of a replica, instead of * evicting the expired key from the database, we return ASAP: @@ -1850,25 +1913,32 @@ keyStatus expireIfNeeded(serverDb *db, robj *key, int flags) { * replicas. * * Still we try to return the right information to the caller, - * that is, KEY_VALID if we think the key should still be valid, + * that is, KEY_VALID if we think the key should still be valid, * KEY_EXPIRED if we think the key is expired but don't want to delete it at this time. * * When replicating commands from the master, keys are never considered * expired. */ if (server.masterhost != NULL) { - if (server.current_client && (server.current_client->flags & CLIENT_MASTER)) return KEY_VALID; - if (!(flags & EXPIRE_FORCE_DELETE_EXPIRED)) return KEY_EXPIRED; + if (server.current_client && (server.current_client->flags & CLIENT_MASTER)) { + return KEY_VALID; + } + if (!(flags & EXPIRE_FORCE_DELETE_EXPIRED)) { + return KEY_EXPIRED; + } } /* In some cases we're explicitly instructed to return an indication of a * missing key without actually deleting it, even on masters. */ - if (flags & EXPIRE_AVOID_DELETE_EXPIRED) + if (flags & EXPIRE_AVOID_DELETE_EXPIRED) { return KEY_EXPIRED; + } /* If 'expire' action is paused, for whatever reason, then don't expire any key. * Typically, at the end of the pause we will properly expire the key OR we * will have failed over and the new primary will send us the expire. */ - if (isPausedActionsWithUpdate(PAUSE_ACTION_EXPIRE)) return KEY_EXPIRED; + if (isPausedActionsWithUpdate(PAUSE_ACTION_EXPIRE)) { + return KEY_EXPIRED; + } /* The key needs to be converted from static to heap before deleted */ int static_key = key->refcount == OBJ_STATIC_REFCOUNT; @@ -1876,7 +1946,7 @@ keyStatus expireIfNeeded(serverDb *db, robj *key, int flags) { key = createStringObject(key->ptr, sdslen(key->ptr)); } /* Delete the key */ - deleteExpiredKeyAndPropagate(db,key); + deleteExpiredKeyAndPropagate(db, key); if (static_key) { decrRefCount(key); } @@ -1906,14 +1976,16 @@ static int dbExpandGeneric(kvstore *kvs, uint64_t db_size, int try_expand) { /* We don't know exact number of keys that would fall into each slot, but we can * approximate it, assuming even distribution, divide it by the number of slots. */ int slots = getMyShardSlotCount(); - if (slots == 0) return C_OK; + if (slots == 0) { + return C_OK; + } db_size = db_size / slots; ret = kvstoreExpand(kvs, db_size, try_expand, dbExpandSkipSlot); } else { ret = kvstoreExpand(kvs, db_size, try_expand, NULL); } - return ret? C_OK : C_ERR; + return ret ? C_OK : C_ERR; } int dbExpand(serverDb *db, uint64_t db_size, int try_expand) { @@ -1970,8 +2042,9 @@ keyReference *getKeysPrepareResult(getKeysResult *result, int numkeys) { } else { /* We are using a static buffer, copy its contents */ result->keys = zmalloc(numkeys * sizeof(keyReference)); - if (result->numkeys) + if (result->numkeys) { memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference)); + } } result->size = numkeys; } @@ -1985,17 +2058,17 @@ int64_t getAllKeySpecsFlags(struct serverCommand *cmd, int inv) { int64_t flags = 0; for (int j = 0; j < cmd->key_specs_num; j++) { keySpec *spec = cmd->key_specs + j; - flags |= inv? ~spec->flags : spec->flags; + flags |= inv ? ~spec->flags : spec->flags; } return flags; } /* Fetch the keys based of the provided key specs. Returns the number of keys found, or -1 on error. * There are several flags that can be used to modify how this function finds keys in a command. - * + * * GET_KEYSPEC_INCLUDE_NOT_KEYS: Return 'fake' keys as if they were keys. * GET_KEYSPEC_RETURN_PARTIAL: Skips invalid and incomplete keyspecs but returns the keys - * found in other valid keyspecs. + * found in other valid keyspecs. */ int getKeysUsingKeySpecs(struct serverCommand *cmd, robj **argv, int argc, int search_flags, getKeysResult *result) { int j, i, last, first, step; @@ -2014,13 +2087,15 @@ int getKeysUsingKeySpecs(struct serverCommand *cmd, robj **argv, int argc, int s if (spec->begin_search_type == KSPEC_BS_INDEX) { first = spec->bs.index.pos; } else if (spec->begin_search_type == KSPEC_BS_KEYWORD) { - int start_index = spec->bs.keyword.startfrom > 0 ? spec->bs.keyword.startfrom : argc+spec->bs.keyword.startfrom; - int end_index = spec->bs.keyword.startfrom > 0 ? argc-1: 1; + int start_index = + spec->bs.keyword.startfrom > 0 ? spec->bs.keyword.startfrom : argc + spec->bs.keyword.startfrom; + int end_index = spec->bs.keyword.startfrom > 0 ? argc - 1 : 1; for (i = start_index; i != end_index; i = start_index <= end_index ? i + 1 : i - 1) { - if (i >= argc || i < 1) + if (i >= argc || i < 1) { break; - if (!strcasecmp((char*)argv[i]->ptr,spec->bs.keyword.keyword)) { - first = i+1; + } + if (!strcasecmp((char *)argv[i]->ptr, spec->bs.keyword.keyword)) { + first = i + 1; break; } } @@ -2042,29 +2117,30 @@ int getKeysUsingKeySpecs(struct serverCommand *cmd, robj **argv, int argc, int s last = argc + spec->fk.range.lastkey; } else { serverAssert(spec->fk.range.lastkey == -1); - last = first + ((argc-first)/spec->fk.range.limit + spec->fk.range.lastkey); + last = first + ((argc - first) / spec->fk.range.limit + spec->fk.range.lastkey); } } } else if (spec->find_keys_type == KSPEC_FK_KEYNUM) { step = spec->fk.keynum.keystep; long long numkeys; - if (spec->fk.keynum.keynumidx >= argc) + if (spec->fk.keynum.keynumidx >= argc) { goto invalid_spec; + } sds keynum_str = argv[first + spec->fk.keynum.keynumidx]->ptr; - if (!string2ll(keynum_str,sdslen(keynum_str),&numkeys) || numkeys < 0) { + if (!string2ll(keynum_str, sdslen(keynum_str), &numkeys) || numkeys < 0) { /* Unable to parse the numkeys argument or it was invalid */ goto invalid_spec; } first += spec->fk.keynum.firstkey; - last = first + (int)numkeys-1; + last = first + (int)numkeys - 1; } else { /* unknown spec */ goto invalid_spec; } - int count = ((last - first)+1); + int count = ((last - first) + 1); keys = getKeysPrepareResult(result, result->numkeys + count); /* First or last is out of bounds, which indicates a syntax error */ @@ -2100,7 +2176,7 @@ int getKeysUsingKeySpecs(struct serverCommand *cmd, robj **argv, int argc, int s /* Done with this spec */ continue; -invalid_spec: + invalid_spec: if (search_flags & GET_KEYSPEC_RETURN_PARTIAL) { continue; } else { @@ -2112,19 +2188,20 @@ int getKeysUsingKeySpecs(struct serverCommand *cmd, robj **argv, int argc, int s return result->numkeys; } -/* Return all the arguments that are keys in the command passed via argc / argv. +/* Return all the arguments that are keys in the command passed via argc / argv. * This function will eventually replace getKeysFromCommand. * * The command returns the positions of all the key arguments inside the array, * so the actual return value is a heap allocated array of integers. The * length of the array is returned by reference into *numkeys. - * + * * Along with the position, this command also returns the flags that are * associated with how the server will access the key. * * 'cmd' must be point to the corresponding entry into the serverCommand * table, according to the command name in argv[0]. */ -int getKeysFromCommandWithSpecs(struct serverCommand *cmd, robj **argv, int argc, int search_flags, getKeysResult *result) { +int getKeysFromCommandWithSpecs(struct serverCommand *cmd, robj **argv, int argc, int search_flags, + getKeysResult *result) { /* The command has at least one key-spec not marked as NOT_KEY */ int has_keyspec = (getAllKeySpecsFlags(cmd, 1) & CMD_KEY_NOT_KEY); /* The command has at least one key-spec marked as VARIABLE_FLAGS */ @@ -2132,39 +2209,42 @@ int getKeysFromCommandWithSpecs(struct serverCommand *cmd, robj **argv, int argc /* We prefer key-specs if there are any, and their flags are reliable. */ if (has_keyspec && !has_varflags) { - int ret = getKeysUsingKeySpecs(cmd,argv,argc,search_flags,result); - if (ret >= 0) + int ret = getKeysUsingKeySpecs(cmd, argv, argc, search_flags, result); + if (ret >= 0) { return ret; + } /* If the specs returned with an error (probably an INVALID or INCOMPLETE spec), * fallback to the callback method. */ } /* Resort to getkeys callback methods. */ - if (cmd->flags & CMD_MODULE_GETKEYS) - return moduleGetCommandKeysViaAPI(cmd,argv,argc,result); + if (cmd->flags & CMD_MODULE_GETKEYS) { + return moduleGetCommandKeysViaAPI(cmd, argv, argc, result); + } /* We use native getkeys as a last resort, since not all these native getkeys provide * flags properly (only the ones that correspond to INVALID, INCOMPLETE or VARIABLE_FLAGS do.*/ - if (cmd->getkeys_proc) - return cmd->getkeys_proc(cmd,argv,argc,result); + if (cmd->getkeys_proc) { + return cmd->getkeys_proc(cmd, argv, argc, result); + } return 0; } /* This function returns a sanity check if the command may have keys. */ int doesCommandHaveKeys(struct serverCommand *cmd) { - return cmd->getkeys_proc || /* has getkeys_proc (non modules) */ - (cmd->flags & CMD_MODULE_GETKEYS) || /* module with GETKEYS */ - (getAllKeySpecsFlags(cmd, 1) & CMD_KEY_NOT_KEY); /* has at least one key-spec not marked as NOT_KEY */ + return cmd->getkeys_proc || /* has getkeys_proc (non modules) */ + (cmd->flags & CMD_MODULE_GETKEYS) || /* module with GETKEYS */ + (getAllKeySpecsFlags(cmd, 1) & CMD_KEY_NOT_KEY); /* has at least one key-spec not marked as NOT_KEY */ } /* A simplified channel spec table that contains all of the commands * and which channels they have and how they are accessed. */ typedef struct ChannelSpecs { serverCommandProc *proc; /* Command procedure to match against */ - uint64_t flags; /* CMD_CHANNEL_* flags for this command */ - int start; /* The initial position of the first channel */ - int count; /* The number of channels, or -1 if all remaining - * arguments are channels. */ + uint64_t flags; /* CMD_CHANNEL_* flags for this command */ + int start; /* The initial position of the first channel */ + int count; /* The number of channels, or -1 if all remaining + * arguments are channels. */ } ChannelSpecs; ChannelSpecs commands_with_channels[] = { @@ -2176,7 +2256,7 @@ ChannelSpecs commands_with_channels[] = { {punsubscribeCommand, CMD_CHANNEL_PATTERN | CMD_CHANNEL_UNSUBSCRIBE, 1, -1}, {publishCommand, CMD_CHANNEL_PUBLISH, 1, 1}, {spublishCommand, CMD_CHANNEL_PUBLISH, 1, 1}, - {NULL,0} /* Terminator. */ + {NULL, 0} /* Terminator. */ }; /* Returns 1 if the command may access any channels matched by the flags @@ -2195,14 +2275,14 @@ int doesCommandHaveChannelsWithFlags(struct serverCommand *cmd, int flags) { return 0; } -/* Return all the arguments that are channels in the command passed via argc / argv. - * This function behaves similar to getKeysFromCommandWithSpecs, but with channels +/* Return all the arguments that are channels in the command passed via argc / argv. + * This function behaves similar to getKeysFromCommandWithSpecs, but with channels * instead of keys. - * + * * The command returns the positions of all the channel arguments inside the array, * so the actual return value is a heap allocated array of integers. The * length of the array is returned by reference into *numkeys. - * + * * Along with the position, this command also returns the flags that are * associated with how the server will access the channel. * @@ -2219,10 +2299,12 @@ int getChannelsFromCommand(struct serverCommand *cmd, robj **argv, int argc, get if (cmd->proc == spec->proc) { int start = spec->start; int stop = (spec->count == -1) ? argc : start + spec->count; - if (stop > argc) stop = argc; + if (stop > argc) { + stop = argc; + } int count = 0; keys = getKeysPrepareResult(result, stop - start); - for (int i = start; i < stop; i++ ) { + for (int i = start; i < stop; i++) { keys[count].pos = i; keys[count++].flags = spec->flags; } @@ -2236,12 +2318,12 @@ int getChannelsFromCommand(struct serverCommand *cmd, robj **argv, int argc, get /* The base case is to use the keys position as given in the command table * (firstkey, lastkey, step). * This function works only on command with the legacy_range_key_spec, - * all other commands should be handled by getkeys_proc. - * + * all other commands should be handled by getkeys_proc. + * * If the commands keyspec is incomplete, no keys will be returned, and the provided * keys function should be called instead. - * - * NOTE: This function does not guarantee populating the flags for + * + * NOTE: This function does not guarantee populating the flags for * the keys, in order to get flags you should use getKeysUsingKeySpecs. */ int getKeysUsingLegacyRangeSpec(struct serverCommand *cmd, robj **argv, int argc, getKeysResult *result) { int j, i = 0, last, first, step; @@ -2255,13 +2337,16 @@ int getKeysUsingLegacyRangeSpec(struct serverCommand *cmd, robj **argv, int argc first = cmd->legacy_range_key_spec.bs.index.pos; last = cmd->legacy_range_key_spec.fk.range.lastkey; - if (last >= 0) + if (last >= 0) { last += first; + } step = cmd->legacy_range_key_spec.fk.range.keystep; - if (last < 0) last = argc+last; + if (last < 0) { + last = argc + last; + } - int count = ((last - first)+1); + int count = ((last - first) + 1); keys = getKeysPrepareResult(result, count); for (j = first; j <= last; j += step) { @@ -2300,18 +2385,19 @@ int getKeysUsingLegacyRangeSpec(struct serverCommand *cmd, robj **argv, int argc * is not required, otherwise it calls the command-specific function. */ int getKeysFromCommand(struct serverCommand *cmd, robj **argv, int argc, getKeysResult *result) { if (cmd->flags & CMD_MODULE_GETKEYS) { - return moduleGetCommandKeysViaAPI(cmd,argv,argc,result); + return moduleGetCommandKeysViaAPI(cmd, argv, argc, result); } else if (cmd->getkeys_proc) { - return cmd->getkeys_proc(cmd,argv,argc,result); + return cmd->getkeys_proc(cmd, argv, argc, result); } else { - return getKeysUsingLegacyRangeSpec(cmd,argv,argc,result); + return getKeysUsingLegacyRangeSpec(cmd, argv, argc, result); } } /* Free the result of getKeysFromCommand. */ void getKeysFreeResult(getKeysResult *result) { - if (result && result->keys != result->keysbuf) + if (result && result->keys != result->keysbuf) { zfree(result->keys); + } } /* Helper function to extract keys from following commands: @@ -2325,17 +2411,17 @@ void getKeysFreeResult(getKeysResult *result) { * 'keyCountOfs': num-keys index. * 'firstKeyOfs': firstkey index. * 'keyStep': the interval of each key, usually this value is 1. - * + * * The commands using this function have a fully defined keyspec, so returning flags isn't needed. */ -int genericGetKeys(int storeKeyOfs, int keyCountOfs, int firstKeyOfs, int keyStep, - robj **argv, int argc, getKeysResult *result) { +int genericGetKeys(int storeKeyOfs, int keyCountOfs, int firstKeyOfs, int keyStep, robj **argv, int argc, + getKeysResult *result) { int i, num; keyReference *keys; num = atoi(argv[keyCountOfs]->ptr); /* Sanity check. Don't return any key if the command is going to * reply with syntax error. (no input keys). */ - if (num < 1 || num > (argc - firstKeyOfs)/keyStep) { + if (num < 1 || num > (argc - firstKeyOfs) / keyStep) { result->numkeys = 0; return 0; } @@ -2346,14 +2432,14 @@ int genericGetKeys(int storeKeyOfs, int keyCountOfs, int firstKeyOfs, int keySte /* Add all key positions for argv[firstKeyOfs...n] to keys[] */ for (i = 0; i < num; i++) { - keys[i].pos = firstKeyOfs+(i*keyStep); + keys[i].pos = firstKeyOfs + (i * keyStep); keys[i].flags = 0; - } + } if (storeKeyOfs) { keys[num].pos = storeKeyOfs; keys[num].flags = 0; - } + } return result->numkeys; } @@ -2431,8 +2517,8 @@ int sortROGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResul * * The first argument of SORT is always a key, however a list of options * follow in SQL-alike style. Here we parse just the minimum in order to - * correctly identify keys in the "STORE" option. - * + * correctly identify keys in the "STORE" option. + * * This command declares incomplete keys, so the flags are correctly set for this function */ int sortGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResult *result) { int i, j, num, found_store = 0; @@ -2441,7 +2527,7 @@ int sortGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResult num = 0; keys = getKeysPrepareResult(result, 2); /* Alloc 2 places for the worst case. */ - keys[num].pos = 1; /* is always present. */ + keys[num].pos = 1; /* is always present. */ keys[num++].flags = CMD_KEY_RO | CMD_KEY_ACCESS; /* Search for STORE option. By default we consider options to don't @@ -2452,23 +2538,20 @@ int sortGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResult char *name; int skip; } skiplist[] = { - {"limit", 2}, - {"get", 1}, - {"by", 1}, - {NULL, 0} /* End of elements. */ + {"limit", 2}, {"get", 1}, {"by", 1}, {NULL, 0} /* End of elements. */ }; for (i = 2; i < argc; i++) { for (j = 0; skiplist[j].name != NULL; j++) { - if (!strcasecmp(argv[i]->ptr,skiplist[j].name)) { + if (!strcasecmp(argv[i]->ptr, skiplist[j].name)) { i += skiplist[j].skip; break; - } else if (!strcasecmp(argv[i]->ptr,"store") && i+1 < argc) { + } else if (!strcasecmp(argv[i]->ptr, "store") && i + 1 < argc) { /* Note: we don't increment "num" here and continue the loop * to be sure to process the *last* "STORE" option if multiple * ones are provided. This is same behavior as SORT. */ found_store = 1; - keys[num].pos = i+1; /* */ + keys[num].pos = i + 1; /* */ keys[num].flags = CMD_KEY_OW | CMD_KEY_UPDATE; break; } @@ -2490,22 +2573,16 @@ int migrateGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResu /* But check for the extended one with the KEYS option. */ struct { - char* name; + char *name; int skip; - } skip_keywords[] = { - {"copy", 0}, - {"replace", 0}, - {"auth", 1}, - {"auth2", 2}, - {NULL, 0} - }; + } skip_keywords[] = {{"copy", 0}, {"replace", 0}, {"auth", 1}, {"auth2", 2}, {NULL, 0}}; if (argc > 6) { for (i = 6; i < argc; i++) { if (!strcasecmp(argv[i]->ptr, "keys")) { if (sdslen(argv[3]->ptr) > 0) { /* This is a syntax error. So ignore the keys and leave * the syntax error to be handled by migrateCommand. */ - num = 0; + num = 0; } else { first = i + 1; num = argc - first; @@ -2523,9 +2600,9 @@ int migrateGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResu keys = getKeysPrepareResult(result, num); for (i = 0; i < num; i++) { - keys[i].pos = first+i; + keys[i].pos = first + i; keys[i].flags = CMD_KEY_RW | CMD_KEY_ACCESS | CMD_KEY_DELETE; - } + } result->numkeys = num; return num; } @@ -2534,7 +2611,7 @@ int migrateGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResu * GEORADIUS key x y radius unit [WITHDIST] [WITHHASH] [WITHCOORD] [ASC|DESC] * [COUNT count] [STORE key|STOREDIST key] * GEORADIUSBYMEMBER key member radius unit ... options ... - * + * * This command has a fully defined keyspec, so returning flags isn't needed. */ int georadiusGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResult *result) { int i, num; @@ -2549,8 +2626,8 @@ int georadiusGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysRe * second key specified would override the first key. This behavior is kept * the same as in georadiusCommand method. */ - if ((!strcasecmp(arg, "store") || !strcasecmp(arg, "storedist")) && ((i+1) < argc)) { - stored_key = i+1; + if ((!strcasecmp(arg, "store") || !strcasecmp(arg, "storedist")) && ((i + 1) < argc)) { + stored_key = i + 1; i++; } } @@ -2565,9 +2642,9 @@ int georadiusGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysRe /* Add all key positions to keys[] */ keys[0].pos = 1; keys[0].flags = 0; - if(num > 1) { - keys[1].pos = stored_key; - keys[1].flags = 0; + if (num > 1) { + keys[1].pos = stored_key; + keys[1].flags = 0; } result->numkeys = num; return num; @@ -2604,7 +2681,9 @@ int xreadGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResult break; /* Syntax error. */ } } - if (streams_pos != -1) num = argc - streams_pos - 1; + if (streams_pos != -1) { + num = argc - streams_pos - 1; + } /* Syntax error. */ if (streams_pos == -1 || num == 0 || num % 2 != 0) { @@ -2615,10 +2694,10 @@ int xreadGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResult there are also the IDs, one per key. */ keys = getKeysPrepareResult(result, num); - for (i = streams_pos+1; i < argc-num; i++) { - keys[i-streams_pos-1].pos = i; - keys[i-streams_pos-1].flags = 0; - } + for (i = streams_pos + 1; i < argc - num; i++) { + keys[i - streams_pos - 1].pos = i; + keys[i - streams_pos - 1].flags = 0; + } result->numkeys = num; return num; } @@ -2635,10 +2714,8 @@ int setGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResult * for (int i = 3; i < argc; i++) { char *arg = argv[i]->ptr; - if ((arg[0] == 'g' || arg[0] == 'G') && - (arg[1] == 'e' || arg[1] == 'E') && - (arg[2] == 't' || arg[2] == 'T') && arg[3] == '\0') - { + if ((arg[0] == 'g' || arg[0] == 'G') && (arg[1] == 'e' || arg[1] == 'E') && (arg[2] == 't' || arg[2] == 'T') && + arg[3] == '\0') { keys[0].flags = CMD_KEY_RW | CMD_KEY_ACCESS | CMD_KEY_UPDATE; return 1; } diff --git a/src/debug.c b/src/debug.c index 5327a231a..1072edf83 100644 --- a/src/debug.c +++ b/src/debug.c @@ -30,7 +30,7 @@ #include "server.h" #include "util.h" -#include "sha1.h" /* SHA1 is used for DEBUG DIGEST */ +#include "sha1.h" /* SHA1 is used for DEBUG DIGEST */ #include "crc64.h" #include "bio.h" #include "quicklist.h" @@ -92,16 +92,17 @@ void xorDigest(unsigned char *digest, const void *ptr, size_t len) { int j; SHA1Init(&ctx); - SHA1Update(&ctx,ptr,len); - SHA1Final(hash,&ctx); + SHA1Update(&ctx, ptr, len); + SHA1Final(hash, &ctx); - for (j = 0; j < 20; j++) + for (j = 0; j < 20; j++) { digest[j] ^= hash[j]; + } } void xorStringObjectDigest(unsigned char *digest, robj *o) { o = getDecodedObject(o); - xorDigest(digest,o->ptr,sdslen(o->ptr)); + xorDigest(digest, o->ptr, sdslen(o->ptr)); decrRefCount(o); } @@ -122,15 +123,15 @@ void xorStringObjectDigest(unsigned char *digest, robj *o) { void mixDigest(unsigned char *digest, const void *ptr, size_t len) { SHA1_CTX ctx; - xorDigest(digest,ptr,len); + xorDigest(digest, ptr, len); SHA1Init(&ctx); - SHA1Update(&ctx,digest,20); - SHA1Final(digest,&ctx); + SHA1Update(&ctx, digest, 20); + SHA1Final(digest, &ctx); } void mixStringObjectDigest(unsigned char *digest, robj *o) { o = getDecodedObject(o); - mixDigest(digest,o->ptr,sdslen(o->ptr)); + mixDigest(digest, o->ptr, sdslen(o->ptr)); decrRefCount(o); } @@ -144,27 +145,27 @@ void mixStringObjectDigest(unsigned char *digest, robj *o) { * present. */ void xorObjectDigest(serverDb *db, robj *keyobj, unsigned char *digest, robj *o) { uint32_t aux = htonl(o->type); - mixDigest(digest,&aux,sizeof(aux)); - long long expiretime = getExpire(db,keyobj); + mixDigest(digest, &aux, sizeof(aux)); + long long expiretime = getExpire(db, keyobj); char buf[128]; /* Save the key and associated value */ if (o->type == OBJ_STRING) { - mixStringObjectDigest(digest,o); + mixStringObjectDigest(digest, o); } else if (o->type == OBJ_LIST) { - listTypeIterator *li = listTypeInitIterator(o,0,LIST_TAIL); + listTypeIterator *li = listTypeInitIterator(o, 0, LIST_TAIL); listTypeEntry entry; - while(listTypeNext(li,&entry)) { + while (listTypeNext(li, &entry)) { robj *eleobj = listTypeGet(&entry); - mixStringObjectDigest(digest,eleobj); + mixStringObjectDigest(digest, eleobj); decrRefCount(eleobj); } listTypeReleaseIterator(li); } else if (o->type == OBJ_SET) { setTypeIterator *si = setTypeInitIterator(o); sds sdsele; - while((sdsele = setTypeNextObject(si)) != NULL) { - xorDigest(digest,sdsele,sdslen(sdsele)); + while ((sdsele = setTypeNextObject(si)) != NULL) { + xorDigest(digest, sdsele, sdslen(sdsele)); sdsfree(sdsele); } setTypeReleaseIterator(si); @@ -179,42 +180,42 @@ void xorObjectDigest(serverDb *db, robj *keyobj, unsigned char *digest, robj *o) long long vll; double score; - eptr = lpSeek(zl,0); + eptr = lpSeek(zl, 0); serverAssert(eptr != NULL); - sptr = lpNext(zl,eptr); + sptr = lpNext(zl, eptr); serverAssert(sptr != NULL); while (eptr != NULL) { - vstr = lpGetValue(eptr,&vlen,&vll); + vstr = lpGetValue(eptr, &vlen, &vll); score = zzlGetScore(sptr); - memset(eledigest,0,20); + memset(eledigest, 0, 20); if (vstr != NULL) { - mixDigest(eledigest,vstr,vlen); + mixDigest(eledigest, vstr, vlen); } else { - ll2string(buf,sizeof(buf),vll); - mixDigest(eledigest,buf,strlen(buf)); + ll2string(buf, sizeof(buf), vll); + mixDigest(eledigest, buf, strlen(buf)); } const int len = fpconv_dtoa(score, buf); buf[len] = '\0'; - mixDigest(eledigest,buf,strlen(buf)); - xorDigest(digest,eledigest,20); - zzlNext(zl,&eptr,&sptr); + mixDigest(eledigest, buf, strlen(buf)); + xorDigest(digest, eledigest, 20); + zzlNext(zl, &eptr, &sptr); } } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { zset *zs = o->ptr; dictIterator *di = dictGetIterator(zs->dict); dictEntry *de; - while((de = dictNext(di)) != NULL) { + while ((de = dictNext(di)) != NULL) { sds sdsele = dictGetKey(de); double *score = dictGetVal(de); const int len = fpconv_dtoa(*score, buf); buf[len] = '\0'; - memset(eledigest,0,20); - mixDigest(eledigest,sdsele,sdslen(sdsele)); - mixDigest(eledigest,buf,strlen(buf)); - xorDigest(digest,eledigest,20); + memset(eledigest, 0, 20); + mixDigest(eledigest, sdsele, sdslen(sdsele)); + mixDigest(eledigest, buf, strlen(buf)); + xorDigest(digest, eledigest, 20); } dictReleaseIterator(di); } else { @@ -226,51 +227,52 @@ void xorObjectDigest(serverDb *db, robj *keyobj, unsigned char *digest, robj *o) unsigned char eledigest[20]; sds sdsele; - memset(eledigest,0,20); - sdsele = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_KEY); - mixDigest(eledigest,sdsele,sdslen(sdsele)); + memset(eledigest, 0, 20); + sdsele = hashTypeCurrentObjectNewSds(hi, OBJ_HASH_KEY); + mixDigest(eledigest, sdsele, sdslen(sdsele)); sdsfree(sdsele); - sdsele = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_VALUE); - mixDigest(eledigest,sdsele,sdslen(sdsele)); + sdsele = hashTypeCurrentObjectNewSds(hi, OBJ_HASH_VALUE); + mixDigest(eledigest, sdsele, sdslen(sdsele)); sdsfree(sdsele); - xorDigest(digest,eledigest,20); + xorDigest(digest, eledigest, 20); } hashTypeReleaseIterator(hi); } else if (o->type == OBJ_STREAM) { streamIterator si; - streamIteratorStart(&si,o->ptr,NULL,NULL,0); + streamIteratorStart(&si, o->ptr, NULL, NULL, 0); streamID id; int64_t numfields; - while(streamIteratorGetID(&si,&id,&numfields)) { - sds itemid = sdscatfmt(sdsempty(),"%U.%U",id.ms,id.seq); - mixDigest(digest,itemid,sdslen(itemid)); + while (streamIteratorGetID(&si, &id, &numfields)) { + sds itemid = sdscatfmt(sdsempty(), "%U.%U", id.ms, id.seq); + mixDigest(digest, itemid, sdslen(itemid)); sdsfree(itemid); - while(numfields--) { + while (numfields--) { unsigned char *field, *value; int64_t field_len, value_len; - streamIteratorGetField(&si,&field,&value, - &field_len,&value_len); - mixDigest(digest,field,field_len); - mixDigest(digest,value,value_len); + streamIteratorGetField(&si, &field, &value, &field_len, &value_len); + mixDigest(digest, field, field_len); + mixDigest(digest, value, value_len); } } streamIteratorStop(&si); } else if (o->type == OBJ_MODULE) { - ValkeyModuleDigest md = {{0},{0},keyobj,db->id}; + ValkeyModuleDigest md = {{0}, {0}, keyobj, db->id}; moduleValue *mv = o->ptr; moduleType *mt = mv->type; moduleInitDigestContext(md); if (mt->digest) { - mt->digest(&md,mv->value); - xorDigest(digest,md.x,sizeof(md.x)); + mt->digest(&md, mv->value); + xorDigest(digest, md.x, sizeof(md.x)); } } else { serverPanic("Unknown object type"); } /* If the key has an expire, add it to the mix */ - if (expiretime != -1) xorDigest(digest,"!!expire!!",10); + if (expiretime != -1) { + xorDigest(digest, "!!expire!!", 10); + } } /* Compute the dataset digest. Since keys, sets elements, hashes elements @@ -285,34 +287,35 @@ void computeDatasetDigest(unsigned char *final) { int j; uint32_t aux; - memset(final,0,20); /* Start with a clean result */ + memset(final, 0, 20); /* Start with a clean result */ for (j = 0; j < server.dbnum; j++) { - serverDb *db = server.db+j; - if (kvstoreSize(db->keys) == 0) + serverDb *db = server.db + j; + if (kvstoreSize(db->keys) == 0) { continue; + } kvstoreIterator *kvs_it = kvstoreIteratorInit(db->keys); /* hash the DB id, so the same dataset moved in a different DB will lead to a different digest */ aux = htonl(j); - mixDigest(final,&aux,sizeof(aux)); + mixDigest(final, &aux, sizeof(aux)); /* Iterate this DB writing every entry */ - while((de = kvstoreIteratorNext(kvs_it)) != NULL) { + while ((de = kvstoreIteratorNext(kvs_it)) != NULL) { sds key; robj *keyobj, *o; - memset(digest,0,20); /* This key-val digest */ + memset(digest, 0, 20); /* This key-val digest */ key = dictGetKey(de); - keyobj = createStringObject(key,sdslen(key)); + keyobj = createStringObject(key, sdslen(key)); - mixDigest(digest,key,sdslen(key)); + mixDigest(digest, key, sdslen(key)); o = dictGetVal(de); - xorObjectDigest(db,keyobj,digest,o); + xorObjectDigest(db, keyobj, digest, o); /* We can finally xor the key-val digest to the final digest */ - xorDigest(final,digest,20); + xorDigest(final, digest, 20); decrRefCount(keyobj); } kvstoreIteratorRelease(kvs_it); @@ -326,40 +329,41 @@ void mallctl_int(client *c, robj **argv, int argc) { int64_t old = 0, val; if (argc > 1) { long long ll; - if (getLongLongFromObjectOrReply(c, argv[1], &ll, NULL) != C_OK) + if (getLongLongFromObjectOrReply(c, argv[1], &ll, NULL) != C_OK) { return; + } val = ll; } size_t sz = sizeof(old); while (sz > 0) { size_t zz = sz; - if ((ret=je_mallctl(argv[0]->ptr, &old, &zz, argc > 1? &val: NULL, argc > 1?sz: 0))) { + if ((ret = je_mallctl(argv[0]->ptr, &old, &zz, argc > 1 ? &val : NULL, argc > 1 ? sz : 0))) { if (ret == EPERM && argc > 1) { /* if this option is write only, try just writing to it. */ - if (!(ret=je_mallctl(argv[0]->ptr, NULL, 0, &val, sz))) { + if (!(ret = je_mallctl(argv[0]->ptr, NULL, 0, &val, sz))) { addReply(c, shared.ok); return; } } - if (ret==EINVAL) { + if (ret == EINVAL) { /* size might be wrong, try a smaller one */ sz /= 2; #if BYTE_ORDER == BIG_ENDIAN - val <<= 8*sz; + val <<= 8 * sz; #endif continue; } - addReplyErrorFormat(c,"%s", strerror(ret)); + addReplyErrorFormat(c, "%s", strerror(ret)); return; } else { #if BYTE_ORDER == BIG_ENDIAN - old >>= 64 - 8*sz; + old >>= 64 - 8 * sz; #endif addReplyLongLong(c, old); return; } } - addReplyErrorFormat(c,"%s", strerror(EINVAL)); + addReplyErrorFormat(c, "%s", strerror(EINVAL)); } void mallctl_string(client *c, robj **argv, int argc) { @@ -367,175 +371,177 @@ void mallctl_string(client *c, robj **argv, int argc) { char *old; size_t sz = sizeof(old); /* for strings, it seems we need to first get the old value, before overriding it. */ - if ((rret=je_mallctl(argv[0]->ptr, &old, &sz, NULL, 0))) { + if ((rret = je_mallctl(argv[0]->ptr, &old, &sz, NULL, 0))) { /* return error unless this option is write only. */ if (!(rret == EPERM && argc > 1)) { - addReplyErrorFormat(c,"%s", strerror(rret)); + addReplyErrorFormat(c, "%s", strerror(rret)); return; } } - if(argc > 1) { + if (argc > 1) { char *val = argv[1]->ptr; char **valref = &val; - if ((!strcmp(val,"VOID"))) + if ((!strcmp(val, "VOID"))) { valref = NULL, sz = 0; + } wret = je_mallctl(argv[0]->ptr, NULL, 0, valref, sz); } - if (!rret) + if (!rret) { addReplyBulkCString(c, old); - else if (wret) - addReplyErrorFormat(c,"%s", strerror(wret)); - else + } else if (wret) { + addReplyErrorFormat(c, "%s", strerror(wret)); + } else { addReply(c, shared.ok); + } } #endif void debugCommand(client *c) { - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"help")) { + if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "help")) { const char *help[] = { -"AOF-FLUSH-SLEEP ", -" Server will sleep before flushing the AOF, this is used for testing.", -"ASSERT", -" Crash by assertion failed.", -"CHANGE-REPL-ID", -" Change the replication IDs of the instance.", -" Dangerous: should be used only for testing the replication subsystem.", -"CONFIG-REWRITE-FORCE-ALL", -" Like CONFIG REWRITE but writes all configuration options, including", -" keywords not listed in original configuration file or default values.", -"CRASH-AND-RECOVER []", -" Hard crash and restart after a delay (default 0).", -"DIGEST", -" Output a hex signature representing the current DB content.", -"DIGEST-VALUE [ ...]", -" Output a hex signature of the values of all the specified keys.", -"ERROR ", -" Return a RESP protocol error with as message. Useful for clients", -" unit tests to simulate error replies.", -"LEAK ", -" Create a memory leak of the input string.", -"LOG ", -" Write to the server log.", -"HTSTATS [full]", -" Return hash table statistics of the specified database.", -"HTSTATS-KEY [full]", -" Like HTSTATS but for the hash table stored at 's value.", -"LOADAOF", -" Flush the AOF buffers on disk and reload the AOF in memory.", -"REPLICATE ", -" Replicates the provided string to replicas, allowing data divergence.", + "AOF-FLUSH-SLEEP ", + " Server will sleep before flushing the AOF, this is used for testing.", + "ASSERT", + " Crash by assertion failed.", + "CHANGE-REPL-ID", + " Change the replication IDs of the instance.", + " Dangerous: should be used only for testing the replication subsystem.", + "CONFIG-REWRITE-FORCE-ALL", + " Like CONFIG REWRITE but writes all configuration options, including", + " keywords not listed in original configuration file or default values.", + "CRASH-AND-RECOVER []", + " Hard crash and restart after a delay (default 0).", + "DIGEST", + " Output a hex signature representing the current DB content.", + "DIGEST-VALUE [ ...]", + " Output a hex signature of the values of all the specified keys.", + "ERROR ", + " Return a RESP protocol error with as message. Useful for clients", + " unit tests to simulate error replies.", + "LEAK ", + " Create a memory leak of the input string.", + "LOG ", + " Write to the server log.", + "HTSTATS [full]", + " Return hash table statistics of the specified database.", + "HTSTATS-KEY [full]", + " Like HTSTATS but for the hash table stored at 's value.", + "LOADAOF", + " Flush the AOF buffers on disk and reload the AOF in memory.", + "REPLICATE ", + " Replicates the provided string to replicas, allowing data divergence.", #ifdef USE_JEMALLOC -"MALLCTL []", -" Get or set a malloc tuning integer.", -"MALLCTL-STR []", -" Get or set a malloc tuning string.", + "MALLCTL []", + " Get or set a malloc tuning integer.", + "MALLCTL-STR []", + " Get or set a malloc tuning string.", #endif -"OBJECT ", -" Show low level info about `key` and associated value.", -"DROP-CLUSTER-PACKET-FILTER ", -" Drop all packets that match the filtered type. Set to -1 allow all packets.", -"OOM", -" Crash the server simulating an out-of-memory error.", -"PANIC", -" Crash the server simulating a panic.", -"POPULATE [] []", -" Create string keys named key:. If is specified then", -" it is used instead of the 'key' prefix. These are not propagated to", -" replicas. Cluster slots are not respected so keys not belonging to the", -" current node can be created in cluster mode.", -"PROTOCOL ", -" Reply with a test value of the specified type. can be: string,", -" integer, double, bignum, null, array, set, map, attrib, push, verbatim,", -" true, false.", -"RELOAD [option ...]", -" Save the RDB on disk and reload it back to memory. Valid