diff --git a/src/.clang-format b/src/.clang-format new file mode 100644 index 000000000..dceaa4b02 --- /dev/null +++ b/src/.clang-format @@ -0,0 +1,32 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +ColumnLimit: 120 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 100 +PenaltyExcessCharacter: 100 +MaxEmptyLinesToKeep: 2 +BreakBeforeBraces: Attach +AllowShortCaseLabelsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AllowShortFunctionsOnASingleLine: false +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignTrailingComments: true +PointerAlignment: Right +KeepEmptyLinesAtTheStartOfBlocks: false +SpaceBeforeParens: ControlStatements +SpacesInParentheses: false +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpaceAfterCStyleCast: false +SpacesInSquareBrackets: false +ReflowComments: true +CommentPragmas: '^\\s*\\*' +SortIncludes: false +AllowAllParametersOfDeclarationOnNextLine: false +BinPackParameters: false +AlignAfterOpenBracket: Align diff --git a/src/.clang-format-ignore b/src/.clang-format-ignore index 4c3cac422..b5519ddfc 100644 --- a/src/.clang-format-ignore +++ b/src/.clang-format-ignore @@ -1,7 +1,11 @@ # Don't format files copied from other sources. lzf* crccombine.* +crc16.c +crc16_slottable.h +crc64.c crcspeed.* +fmtargs.h mt19937-64.* pqsort.* setcpuaffinity.c diff --git a/src/acl.c b/src/acl.c index 3b2178448..46ed85baf 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 the server - 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 the server + 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. @@ -108,12 +109,12 @@ static size_t nextCommandCategory = 0; /* Index of the next command category to int ACLAddCommandCategory(const char *name, uint64_t flag) { 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 +247,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; @@ -275,7 +276,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 +294,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 +310,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 +331,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 +341,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 +349,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 +370,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,8 +397,7 @@ 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) { @@ -413,7 +413,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 +426,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 +437,26 @@ 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 +466,11 @@ 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)); + 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); + int retval = raxRemove(Users, (unsigned char *)username, strlen(username), NULL); serverAssert(retval != 0); return fakeuser; } @@ -496,7 +495,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) { @@ -561,7 +560,7 @@ 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 +568,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 +578,7 @@ 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 +588,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 +597,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; @@ -651,14 +650,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 +675,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 +685,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,7 +719,6 @@ void ACLRecomputeCommandBitsFromCommandRulesAllUsers(void) { } } raxStop(&ri); - } int ACLSetSelectorCategory(aclSelector *selector, const char *category, int allow) { @@ -734,13 +732,17 @@ 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 (*off)++; @@ -756,9 +758,7 @@ void ACLCountCategoryBitsForCommands(dict *commands, aclSelector *selector, unsi * in the subset of commands flagged with the specified category name. * 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) -{ +int ACLCountCategoryBitsForSelector(aclSelector *selector, unsigned long *on, unsigned long *off, const char *category) { uint64_t cflag = ACLGetCommandCategoryFlagByName(category); if (!cflag) return C_ERR; @@ -788,11 +788,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 +800,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 +810,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 +830,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 +878,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 +920,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 +929,7 @@ 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++) - sdsfree(selector->allowed_firstargs[id][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; } @@ -948,8 +942,7 @@ void ACLResetFirstArgs(aclSelector *selector) { 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++) - sdsfree(selector->allowed_firstargs[j][i]); + for (int i = 0; selector->allowed_firstargs[j][i]; i++) sdsfree(selector->allowed_firstargs[j][i]); zfree(selector->allowed_firstargs[j]); } } @@ -963,7 +956,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 +965,22 @@ 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)) - return; + 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 +1043,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 +1091,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 +1110,31 @@ 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); + 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 +1165,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 +1247,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. * @@ -1302,58 +1288,58 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) { if (oplen == -1) oplen = strlen(op); if (oplen == 0) return C_OK; /* Empty string is a no-operation. */ - if (!strcasecmp(op,"on")) { + 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); + 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 +1352,26 @@ 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); + } 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); + 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) { @@ -1429,12 +1415,12 @@ const char *ACLSetUserStringError(void) { /* 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 +1441,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; @@ -1474,9 +1460,9 @@ int ACLCheckUserCredentials(robj *username, robj *password) { /* 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); @@ -1507,13 +1493,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; } } @@ -1548,12 +1535,11 @@ unsigned long ACLGetCommandID(sds cmdname) { sdstolower(lowername); 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,7 +1552,7 @@ 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; } @@ -1580,7 +1566,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; } @@ -1598,7 +1584,7 @@ static int ACLSelectorCheckKey(aclSelector *selector, const char *key, int keyle listIter li; listNode *ln; - listRewind(selector->patterns,&li); + listRewind(selector->patterns, &li); int key_flags = 0; /* clang-format off */ @@ -1609,20 +1595,18 @@ static int ACLSelectorCheckKey(aclSelector *selector, const char *key, int keyle /* clang-format on */ /* 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) - continue; + if ((pattern->flags & key_flags) != key_flags) continue; size_t plen = sdslen(pattern->pattern); - if (stringmatchlen(pattern->pattern,plen,key,keylen,0)) - return ACL_OK; + 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) { @@ -1631,7 +1615,7 @@ static int ACLSelectorHasUnrestrictedKeyAccess(aclSelector *selector, int flags) listIter li; listNode *ln; - listRewind(selector->patterns,&li); + listRewind(selector->patterns, &li); int access_flags = 0; /* clang-format off */ @@ -1642,22 +1626,21 @@ static int ACLSelectorHasUnrestrictedKeyAccess(aclSelector *selector, int flags) /* clang-format on */ /* 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) - continue; - if (!strcmp(pattern->pattern,"*")) { - return 1; - } + if ((pattern->flags & access_flags) != access_flags) continue; + 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). */ @@ -1666,14 +1649,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; } } @@ -1703,27 +1685,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) - return ACL_DENIED_CMD; + 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++; } @@ -1734,7 +1717,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; } @@ -1754,14 +1737,15 @@ 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; 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; getKeysFreeResult(&channels); @@ -1787,9 +1771,9 @@ int ACLUserCheckKeyPerm(user *u, const char *key, int keylen, int flags) { 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; } @@ -1798,9 +1782,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) { @@ -1817,9 +1801,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); @@ -1843,9 +1827,9 @@ int ACLUserCheckChannelPerm(user *u, sds channel, int is_pattern) { 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; @@ -1881,17 +1865,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; } @@ -1914,9 +1896,9 @@ 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); + listRewind(new->selectors, &li); + while ((ln = listNext(&li))) { + aclSelector *s = (aclSelector *)listNodeValue(ln); if (s->flags & SELECTOR_FLAG_ALLCHANNELS) return NULL; } @@ -1926,19 +1908,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. */ @@ -1947,7 +1929,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; @@ -2015,13 +1997,11 @@ 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) - return; + 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) - return; + if (!channels) return; listIter li; listNode *ln; @@ -2029,13 +2009,11 @@ 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) - continue; - if (ACLShouldKillPubsubClient(c, channels)) - freeClient(c); + if (c->user != original) continue; + if (ACLShouldKillPubsubClient(c, channels)) freeClient(c); } listRelease(channels); @@ -2047,28 +2025,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; @@ -2078,7 +2055,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; @@ -2115,7 +2092,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 @@ -2128,11 +2106,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; } } @@ -2145,7 +2121,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); @@ -2180,7 +2156,7 @@ 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 < 2 || strcasecmp(argv[0], "user")) { if (argc_err) *argc_err = 0; return C_ERR; } @@ -2188,7 +2164,7 @@ int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err) { if (listSearchKey(UsersToLoad, argv[1])) { if (argc_err) *argc_err = 1; errno = EALREADY; - return C_ERR; + return C_ERR; } /* Merged selectors before trying to process */ @@ -2204,7 +2180,7 @@ 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; @@ -2216,11 +2192,11 @@ 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]); zfree(acl_args); @@ -2233,31 +2209,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; } } @@ -2265,9 +2242,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]); } } @@ -2302,23 +2280,20 @@ 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, @@ -2331,53 +2306,50 @@ 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; /* 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; } @@ -2388,28 +2360,24 @@ 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; } } @@ -2422,29 +2390,29 @@ sds ACLLoadFromFile(const char *filename) { * 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; @@ -2455,19 +2423,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 (!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; @@ -2475,15 +2444,15 @@ 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; } } @@ -2500,64 +2469,60 @@ 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)); + 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: @@ -2576,25 +2541,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); } @@ -2609,15 +2573,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; @@ -2630,8 +2594,8 @@ int ACLLogMatchEntry(ACLLogEntry *a, ACLLogEntry *b) { 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 (sdscmp(a->object, b->object) != 0) return 0; + if (sdscmp(a->username, b->username) != 0) return 0; return 1; } @@ -2645,7 +2609,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) { @@ -2660,11 +2624,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); } } @@ -2674,7 +2638,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. * @@ -2686,12 +2650,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; @@ -2716,9 +2680,9 @@ void addACLLogEntry(client *c, int reason, int context, int argpos, sds username } /* 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 @@ -2726,14 +2690,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; } } @@ -2763,19 +2727,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"); } @@ -2808,8 +2778,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. */ @@ -2818,19 +2788,19 @@ 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); + 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); } @@ -2838,13 +2808,13 @@ int aclAddReplySelectorDescription(client *c, aclSelector *s) { } /* 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, " "); dsl = sdscatfmt(dsl, "&%S", thispat); @@ -2870,7 +2840,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++) { @@ -2879,25 +2849,25 @@ 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); @@ -2905,8 +2875,8 @@ void aclCommand(client *c) { 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; } } @@ -2914,20 +2884,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; @@ -2937,164 +2904,158 @@ 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; } /* Fix the count according to the number of entries we got. */ - if ((size_t)count > listLength(ACLLog)) - 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; /* clang-format off */ switch(le->reason) { @@ -3105,9 +3066,9 @@ void aclCommand(client *c) { default: reasonstr="unknown"; } /* clang-format on */ - addReplyBulkCString(c,reasonstr); + addReplyBulkCString(c, reasonstr); - addReplyBulkCString(c,"context"); + addReplyBulkCString(c, "context"); char *ctxstr; /* clang-format off */ switch(le->context) { @@ -3118,17 +3079,17 @@ void aclCommand(client *c) { default: ctxstr="unknown"; } /* clang-format on */ - 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"); @@ -3136,9 +3097,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; @@ -3149,23 +3110,21 @@ 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")) { /* clang-format off */ const char *help[] = { "CAT []", @@ -3197,7 +3156,7 @@ void aclCommand(client *c) { NULL }; /* clang-format on */ - addReplyHelp(c,help); + addReplyHelp(c, help); } else { addReplySubcommandSyntaxError(c); } @@ -3223,7 +3182,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 */ @@ -3236,13 +3195,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]; @@ -3263,12 +3222,12 @@ void authCommand(client *c) { /* 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..05f7eccb6 100644 --- a/src/adlist.c +++ b/src/adlist.c @@ -39,12 +39,10 @@ * 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) - return NULL; + if ((list = zmalloc(sizeof(*list))) == NULL) return NULL; list->head = list->tail = NULL; list->len = 0; list->dup = NULL; @@ -54,14 +52,13 @@ 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); zfree(current); @@ -74,10 +71,8 @@ void listEmpty(list *list) /* Free the whole list. * * This function can't fail. */ -void listRelease(list *list) -{ - if (!list) - return; +void listRelease(list *list) { + if (!list) return; listEmpty(list); zfree(list); } @@ -88,12 +83,10 @@ 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) - return NULL; + if ((node = zmalloc(sizeof(*node))) == NULL) return NULL; node->value = value; listLinkNodeHead(list, node); return list; @@ -102,7 +95,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 +114,10 @@ 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) - return NULL; + if ((node = zmalloc(sizeof(*node))) == NULL) return NULL; node->value = value; listLinkNodeTail(list, node); return list; @@ -151,8 +142,7 @@ 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) - return NULL; + if ((node = zmalloc(sizeof(*node))) == NULL) return NULL; node->value = value; if (after) { node->prev = old_node; @@ -181,8 +171,7 @@ 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); zfree(node); @@ -211,8 +200,7 @@ 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; @@ -254,8 +242,7 @@ void listRewindTail(list *list, listIter *li) { * } * * */ -listNode *listNext(listIter *iter) -{ +listNode *listNext(listIter *iter) { listNode *current = iter->next; if (current != NULL) { @@ -275,19 +262,17 @@ 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) - return 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,7 +284,7 @@ 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); @@ -320,13 +305,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,12 +333,12 @@ 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; } 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..62031cbee 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,11 +68,11 @@ 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); + 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; @@ -85,8 +85,7 @@ aeEventLoop *aeCreateEventLoop(int setsize) { 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++) - eventLoop->events[i].mask = AE_NONE; + for (i = 0; i < setsize; i++) eventLoop->events[i].mask = AE_NONE; return eventLoop; err: @@ -127,16 +126,15 @@ int aeResizeSetSize(aeEventLoop *eventLoop, int setsize) { if (setsize == eventLoop->setsize) return AE_OK; if (eventLoop->maxfd >= setsize) return AE_ERR; - if (aeApiResize(eventLoop,setsize) == -1) 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++) - eventLoop->events[i].mask = AE_NONE; + for (i = eventLoop->maxfd + 1; i < setsize; i++) eventLoop->events[i].mask = AE_NONE; return AE_OK; } @@ -149,8 +147,7 @@ void aeDeleteEventLoop(aeEventLoop *eventLoop) { aeTimeEvent *next_te, *te = eventLoop->timeEventHead; while (te) { next_te = te->next; - if (te->finalizerProc) - te->finalizerProc(eventLoop, te->clientData); + if (te->finalizerProc) te->finalizerProc(eventLoop, te->clientData); zfree(te); te = next_te; } @@ -161,28 +158,23 @@ 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) - return AE_ERR; + 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; fe->clientData = clientData; - if (fd > eventLoop->maxfd) - eventLoop->maxfd = fd; + if (fd > eventLoop->maxfd) eventLoop->maxfd = fd; return AE_OK; } -void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) -{ +void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) { if (fd >= eventLoop->setsize) return; aeFileEvent *fe = &eventLoop->events[fd]; if (fe->mask == AE_NONE) return; @@ -197,7 +189,7 @@ void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) /* Update the max fd */ int j; - for (j = eventLoop->maxfd-1; j >= 0; j--) + for (j = eventLoop->maxfd - 1; j >= 0; j--) if (eventLoop->events[j].mask != AE_NONE) break; eventLoop->maxfd = j; } @@ -218,10 +210,11 @@ int aeGetFileEvents(aeEventLoop *eventLoop, int 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; @@ -235,16 +228,14 @@ long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, te->prev = NULL; te->next = eventLoop->timeEventHead; te->refcount = 0; - if (te->next) - te->next->prev = te; + 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; @@ -269,8 +260,7 @@ static int64_t usUntilEarliestTimer(aeEventLoop *eventLoop) { aeTimeEvent *earliest = NULL; while (te) { - if ((!earliest || te->when < earliest->when) && te->id != AE_DELETED_EVENT_ID) - earliest = te; + if ((!earliest || te->when < earliest->when) && te->id != AE_DELETED_EVENT_ID) earliest = te; te = te->next; } @@ -285,9 +275,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. */ @@ -304,8 +294,7 @@ static int processTimeEvents(aeEventLoop *eventLoop) { te->prev->next = te->next; else eventLoop->timeEventHead = te->next; - if (te->next) - te->next->prev = te->prev; + if (te->next) te->next->prev = te->prev; if (te->finalizerProc) { te->finalizerProc(eventLoop, te->clientData); now = getMonotonicUs(); @@ -360,8 +349,7 @@ 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 */ @@ -371,14 +359,12 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags) * 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)) - eventLoop->beforesleep(eventLoop); + 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 +392,7 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags) } /* After sleep callback. */ - if (eventLoop->aftersleep != NULL && flags & AE_CALL_AFTER_SLEEP) - eventLoop->aftersleep(eventLoop); + 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 +420,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 +428,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 +437,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 +447,7 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags) } } /* Check time events */ - if (flags & AE_TIME_EVENTS) - processed += processTimeEvents(eventLoop); + if (flags & AE_TIME_EVENTS) processed += processTimeEvents(eventLoop); return processed; /* return the number of processed file/time events */ } @@ -481,7 +463,7 @@ int aeWait(int fd, int mask, long long milliseconds) { if (mask & AE_READABLE) pfd.events |= POLLIN; if (mask & AE_WRITABLE) pfd.events |= POLLOUT; - if ((retval = poll(&pfd, 1, milliseconds))== 1) { + 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; @@ -495,9 +477,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..a6dcbce50 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,15 @@ 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..78820b99b 100644 --- a/src/ae_epoll.c +++ b/src/ae_epoll.c @@ -40,7 +40,7 @@ static int aeApiCreate(aeEventLoop *eventLoop) { aeApiState *state = zmalloc(sizeof(aeApiState)); if (!state) return -1; - state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize); + state->events = zmalloc(sizeof(struct epoll_event) * eventLoop->setsize); if (!state->events) { zfree(state); return -1; @@ -59,7 +59,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 +76,14 @@ 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; 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; } @@ -98,11 +97,11 @@ static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) { 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 +109,20 @@ 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; + 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; + 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..e27c8c48f 100644 --- a/src/ae_evport.c +++ b/src/ae_evport.c @@ -65,10 +65,10 @@ 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) { @@ -95,8 +95,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 +112,7 @@ static int aeApiLookupPending(aeApiState *state, int fd) { uint_t i; for (i = 0; i < state->npending; i++) { - if (state->pending_fds[i] == fd) - return (i); + if (state->pending_fds[i] == fd) return (i); } return (-1); @@ -126,26 +125,20 @@ static int aeApiAssociate(const char *where, int portfd, int fd, int mask) { int events = 0; int rv, err; - if (mask & AE_READABLE) - events |= POLLIN; - if (mask & AE_WRITABLE) - events |= POLLOUT; + if (mask & AE_READABLE) events |= POLLIN; + if (mask & AE_WRITABLE) events |= POLLOUT; - if (evport_debug) - fprintf(stderr, "%s: port_associate(%d, 0x%x) = ", where, fd, events); + 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) - fprintf(stderr, "%d (%s)\n", rv, rv == 0 ? "no error" : strerror(err)); + 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) - fprintf(stderr, "aeApiAssociate: event port limit exceeded."); + if (err == EAGAIN) fprintf(stderr, "aeApiAssociate: event port limit exceeded."); } return rv; @@ -155,8 +148,7 @@ static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { aeApiState *state = eventLoop->apidata; int fullmask, pfd; - if (evport_debug) - fprintf(stderr, "aeApiAddEvent: fd %d mask 0x%x\n", fd, mask); + 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 +165,7 @@ 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) - fprintf(stderr, "aeApiAddEvent: adding to pending fd %d\n", fd); + if (evport_debug) fprintf(stderr, "aeApiAddEvent: adding to pending fd %d\n", fd); state->pending_masks[pfd] |= fullmask; return 0; } @@ -186,14 +177,12 @@ static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) { aeApiState *state = eventLoop->apidata; int fullmask, pfd; - if (evport_debug) - fprintf(stderr, "del fd %d mask 0x%x\n", fd, mask); + if (evport_debug) fprintf(stderr, "del fd %d mask 0x%x\n", fd, mask); pfd = aeApiLookupPending(state, fd); if (pfd != -1) { - if (evport_debug) - fprintf(stderr, "deleting event from pending fd %d\n", fd); + 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 +191,7 @@ static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) { */ state->pending_masks[pfd] &= ~mask; - if (state->pending_masks[pfd] == AE_NONE) - state->pending_fds[pfd] = -1; + if (state->pending_masks[pfd] == AE_NONE) state->pending_fds[pfd] = -1; return; } @@ -222,15 +210,13 @@ 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) - fprintf(stderr, "aeApiDelEvent: port_dissociate(%d)\n", fd); + 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 +241,10 @@ 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) - /* This fd has since been deleted. */ + 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 +268,8 @@ 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) - return 0; + 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 +278,17 @@ 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..3cb6fbae4 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,22 @@ 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); + state->events = zmalloc(sizeof(struct kevent) * eventLoop->setsize); if (!state->events) { zfree(state); return -1; @@ -84,7 +84,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; @@ -136,11 +136,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 +146,20 @@ 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 +167,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..08ed381ab 100644 --- a/src/ae_select.c +++ b/src/ae_select.c @@ -63,37 +63,34 @@ 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)) - mask |= AE_READABLE; - if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds)) - mask |= AE_WRITABLE; + if (fe->mask & AE_READABLE && FD_ISSET(j, &state->_rfds)) mask |= AE_READABLE; + 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 49334aa8e..d0547b776 100644 --- a/src/anet.c +++ b/src/anet.c @@ -52,8 +52,7 @@ #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; @@ -66,8 +65,7 @@ int anetGetError(int fd) { int sockerr = 0; socklen_t errlen = sizeof(sockerr); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &errlen) == -1) - sockerr = errno; + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &errlen) == -1) sockerr = errno; return sockerr; } @@ -84,8 +82,7 @@ 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) - return ANET_OK; + if (!!(flags & O_NONBLOCK) == !!non_block) return ANET_OK; if (non_block) flags |= O_NONBLOCK; @@ -100,11 +97,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 +115,7 @@ int anetCloexec(int fd) { r = fcntl(fd, F_GETFD); } while (r == -1 && errno == EINTR); - if (r == -1 || (r & FD_CLOEXEC)) - return r; + if (r == -1 || (r & FD_CLOEXEC)) return r; flags = r | FD_CLOEXEC; @@ -132,11 +128,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 +143,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,32 +161,33 @@ 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. */ + /* `TCP_KEEPIDLE`, `TCP_KEEPINTVL`, and `TCP_KEEPCNT` were not available on Solaris + * until version 11.4, but let's take a chance here. */ #if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) && defined(TCP_KEEPCNT) if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle))) { anetSetError(err, "setsockopt TCP_KEEPIDLE: %s\n", strerror(errno)); return ANET_ERR; } - intvl = idle/3; + 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)); @@ -207,7 +201,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,7 +247,7 @@ 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; + 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)); @@ -273,23 +268,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 +289,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 +303,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,13 +322,11 @@ 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)); + 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)) { @@ -345,7 +334,7 @@ int anetResolve(char *err, char *host, char *ipbuf, size_t ipbuf_len, } 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 +382,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 +409,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 +420,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; } @@ -457,18 +444,16 @@ static int anetTcpGenericConnect(char *err, const char *addr, int port, */ 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) - continue; + 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 +464,10 @@ 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) - goto end; + if (errno == EINPROGRESS && flags & ANET_CONNECT_NONBLOCK) goto end; close(s); s = ANET_ERR; continue; @@ -493,8 +477,7 @@ 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) - anetSetError(err, "creating socket: %s", strerror(errno)); + if (p == NULL) anetSetError(err, "creating socket: %s", strerror(errno)); error: if (s != ANET_ERR) { @@ -508,33 +491,28 @@ 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 +524,36 @@ 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)) - bindaddr = NULL; - if (af == AF_INET6 && bindaddr && !strcmp("::*", bindaddr)) - bindaddr = NULL; + hints.ai_flags = AI_PASSIVE; /* No effect if bindaddr != NULL */ + if (bindaddr && !strcmp("*", bindaddr)) bindaddr = NULL; + 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) - continue; + 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) { @@ -595,36 +569,31 @@ static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backl 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; - if ((s = anetCreateSocket(err,AF_LOCAL,type,0,flags)) == ANET_ERR) - return 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) - return 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 +605,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,16 +634,15 @@ 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) - return 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 (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 (ip) inet_ntop(AF_INET6, (void *)&(s->sin6_addr), ip, ip_len); if (port) *port = ntohs(s->sin6_port); } return fd; @@ -686,8 +654,7 @@ 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) - return ANET_ERR; + if ((fd = anetGenericAccept(err, s, (struct sockaddr *)&sa, &salen)) == ANET_ERR) return ANET_ERR; return fd; } @@ -705,21 +672,19 @@ int anetFdToString(int fd, char *ip, size_t ip_len, int *port, int remote) { 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) - goto error; + if (inet_ntop(AF_INET, (void *)&(s->sin_addr), ip, ip_len) == NULL) goto error; } 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) - goto error; + if (inet_ntop(AF_INET6, (void *)&(s->sin6_addr), ip, ip_len) == NULL) goto error; } 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; } else { @@ -751,13 +716,11 @@ 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) - return -1; + 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)) - return 0; + 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 +729,22 @@ 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)) - return -1; + 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)) - goto error; + if (fcntl(fds[0], F_SETFD, FD_CLOEXEC)) goto error; if (write_flags & O_CLOEXEC) - if (fcntl(fds[1], F_SETFD, FD_CLOEXEC)) - goto error; + 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)) - goto error; + 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)) - goto error; + if (fcntl(fds[1], F_SETFL, write_flags)) goto error; return 0; @@ -806,7 +764,7 @@ 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 } 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 2f2255deb..a2ed139f8 100644 --- a/src/aof.c +++ b/src/aof.c @@ -82,17 +82,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) { @@ -122,13 +122,11 @@ aofInfo *aofInfoDup(aofInfo *orig) { sds aofInfoFormat(sds buf, aofInfo *ai) { sds filename_repr = NULL; - if (sdsneedsrepr(ai->file_name)) - filename_repr = sdscatrepr(sdsempty(), ai->file_name, sdslen(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; @@ -166,13 +164,11 @@ void aofManifestFree(aofManifest *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. @@ -206,14 +202,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); } @@ -261,12 +257,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; @@ -275,7 +273,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"; @@ -315,15 +313,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)) {} */ } @@ -433,12 +431,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; @@ -456,8 +453,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; @@ -466,8 +463,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. */ @@ -510,7 +506,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); @@ -533,24 +529,23 @@ 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; - 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; @@ -561,17 +556,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; @@ -579,8 +572,7 @@ 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; @@ -623,8 +615,7 @@ 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); } @@ -646,18 +637,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 @@ -667,10 +655,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; } @@ -679,7 +665,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); @@ -719,8 +705,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); } @@ -733,8 +718,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 @@ -743,11 +727,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); } @@ -782,9 +765,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) { @@ -806,11 +789,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; } @@ -821,8 +803,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` @@ -872,8 +853,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; @@ -902,7 +883,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,10 +918,9 @@ void killAppendOnlyChild(void) { /* No AOFRW child? 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(); @@ -952,7 +933,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; } @@ -979,22 +960,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; } } @@ -1003,14 +988,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; @@ -1026,7 +1010,7 @@ 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) { @@ -1072,19 +1056,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. @@ -1098,8 +1079,7 @@ void flushAppendOnlyFile(int force) { } } - if (server.aof_fsync == AOF_FSYNC_EVERYSEC) - sync_in_progress = aofFsyncInProgress(); + 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. @@ -1119,7 +1099,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 @@ -1133,7 +1114,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 @@ -1141,13 +1122,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; @@ -1165,25 +1146,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 @@ -1200,7 +1182,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 @@ -1213,7 +1196,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... */ } @@ -1221,8 +1204,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; } } @@ -1231,7 +1213,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); @@ -1241,8 +1223,7 @@ 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()) - return; + if (server.aof_no_fsync_on_rewrite && hasActiveChildProcess()) return; /* Perform the fsync if needed. */ if (server.aof_fsync == AOF_FSYNC_ALWAYS) { @@ -1253,17 +1234,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; @@ -1278,20 +1260,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; @@ -1343,22 +1325,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)); } @@ -1404,7 +1383,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; @@ -1414,11 +1393,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; } @@ -1440,26 +1420,27 @@ 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) serverLog(LL_NOTICE, "Reading RDB preamble from AOF file..."); - else - serverLog(LL_NOTICE, "Reading RDB base file on AOF loading..."); + 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 (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); + 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); @@ -1473,7 +1454,7 @@ int loadSingleAppendOnlyFile(char *filename) { } /* Read the actual AOF file, in REPL format, command by command. */ - while(1) { + while (1) { int argc, j; unsigned long len; robj **argv; @@ -1489,7 +1470,7 @@ 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 { @@ -1499,20 +1480,20 @@ int loadSingleAppendOnlyFile(char *filename) { if (buf[0] == '#') continue; /* Skip annotations */ if (buf[0] != '*') goto fmterr; if (buf[1] == '\0') goto readerr; - argc = atoi(buf+1); + argc = atoi(buf + 1); if (argc < 1) goto fmterr; - if ((size_t)argc > SIZE_MAX / sizeof(robj*)) 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); @@ -1521,32 +1502,31 @@ int loadSingleAppendOnlyFile(char *filename) { 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; @@ -1556,9 +1536,7 @@ int loadSingleAppendOnlyFile(char *filename) { /* 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.*/ @@ -1568,8 +1546,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); @@ -1578,8 +1555,7 @@ int loadSingleAppendOnlyFile(char *filename) { * 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) - debugDelay(server.key_load_delay); + if (server.key_load_delay) debugDelay(server.key_load_delay); } /* This point can only be reached when EOF is reached without errors. @@ -1587,8 +1563,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; } @@ -1600,46 +1575,48 @@ 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. */ @@ -1671,11 +1648,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); } } @@ -1704,15 +1679,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. */ @@ -1733,16 +1708,16 @@ 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), @@ -1788,9 +1763,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"); } @@ -1801,16 +1776,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; } @@ -1819,14 +1791,14 @@ 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; } @@ -1848,18 +1820,14 @@ 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; @@ -1884,33 +1852,30 @@ 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); + zzlNext(zl, &eptr, &sptr); if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0; items--; } @@ -1919,25 +1884,20 @@ 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; } @@ -1965,7 +1925,7 @@ static int rioWriteHashIteratorCursor(rio *r, hashTypeIterator *hi, int what) { hashTypeCurrentFromListpack(hi, what, &vstr, &vlen, &vll); if (vstr) - return rioWriteBulkString(r, (char*)vstr, vlen); + return rioWriteBulkString(r, (char *)vstr, vlen); else return rioWriteBulkLongLong(r, vll); } else if (hi->encoding == OBJ_ENCODING_HT) { @@ -1986,23 +1946,18 @@ 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; items--; @@ -2015,11 +1970,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; } @@ -2028,11 +1983,17 @@ 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); + streamDecodeID(rawid, &id); /* clang-format off */ if (rioWriteBulkCount(r,'*',12) == 0) return 0; if (rioWriteBulkString(r,"XCLAIM",6) == 0) return 0; @@ -2054,7 +2015,11 @@ int rioWriteStreamPendingEntry(rio *r, robj *key, const char *groupname, size_t /* 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 */ /* clang-format off */ if (rioWriteBulkCount(r,'*',5) == 0) return 0; @@ -2072,34 +2037,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; } } } @@ -2107,54 +2068,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; @@ -2164,15 +2110,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); @@ -2183,14 +2127,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); @@ -2216,8 +2158,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); @@ -2254,7 +2196,10 @@ 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); } @@ -2266,12 +2211,12 @@ int rewriteAppendOnlyFileRio(rio *aof) { 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; @@ -2279,30 +2224,30 @@ 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"); } @@ -2315,10 +2260,10 @@ int rewriteAppendOnlyFileRio(rio *aof) { /* 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). @@ -2333,8 +2278,7 @@ int rewriteAppendOnlyFileRio(rio *aof) { } /* Delay before next key if required (for testing) */ - if (server.rdb_key_save_delay) - debugDelay(server.rdb_key_save_delay); + if (server.rdb_key_save_delay) debugDelay(server.rdb_key_save_delay); } kvstoreIteratorRelease(kvs_it); } @@ -2359,25 +2303,25 @@ 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; } @@ -2390,15 +2334,18 @@ int rewriteAppendOnlyFile(char *filename) { 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; @@ -2408,7 +2355,7 @@ int rewriteAppendOnlyFile(char *filename) { return C_OK; werr: - serverLog(LL_WARNING,"Write error writing append only file on disk: %s", strerror(errno)); + serverLog(LL_WARNING, "Write error writing append only file on disk: %s", strerror(errno)); if (fp) fclose(fp); unlink(tmpfile); stopSaving(0); @@ -2438,8 +2385,7 @@ int rewriteAppendOnlyFileBackground(void) { 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; } @@ -2473,16 +2419,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 { @@ -2492,13 +2437,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; @@ -2508,28 +2450,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); } @@ -2545,8 +2487,7 @@ off_t getAppendOnlyFileSize(sds filename, int *status) { 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)); + serverLog(LL_WARNING, "Unable to obtain the AOF file %s length. stat: %s", filename, strerror(errno)); size = 0; } else { if (status) *status = AOF_OK; @@ -2575,7 +2516,7 @@ off_t getBaseAndIncrAppendOnlyFilesSize(aofManifest *am, int *status) { 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; @@ -2602,11 +2543,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); @@ -2622,11 +2561,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; @@ -2635,8 +2571,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) { @@ -2648,11 +2583,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); @@ -2665,8 +2597,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); } @@ -2720,14 +2652,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. */ @@ -2736,8 +2666,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: @@ -2748,9 +2677,8 @@ 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) - server.aof_rewrite_scheduled = 1; + if (server.aof_state == AOF_WAIT_REWRITE) server.aof_rewrite_scheduled = 1; } diff --git a/src/atomicvar.h b/src/atomicvar.h index 17d1c15a6..d79cf4c9d 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,93 @@ #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..4d1d268e6 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,14 +124,14 @@ 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); + 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); @@ -140,8 +140,8 @@ void bioInit(void) { * 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 +153,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 +204,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. */ @@ -222,10 +222,9 @@ void *bioProcessBackgroundJobs(void *arg) { 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)); + 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 +243,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 +256,25 @@ 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) - close(job->fd_args.fd); + 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 { @@ -332,13 +324,10 @@ void bioKillThreads(void) { for (j = 0; j < BIO_WORKER_NUM; j++) { 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..db975e4df 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,16 @@ 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 +123,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 +136,14 @@ 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; l++; count -= sizeof(*l); - pos += sizeof(*l)*8; + pos += sizeof(*l) * 8; } } @@ -148,7 +154,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) { @@ -173,7 +179,7 @@ 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) { + while (one) { if (((one & word) != 0) == bit) return pos; pos++; one >>= 1; @@ -210,7 +216,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 +229,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 +240,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 +248,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 +260,13 @@ 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)))) - value |= ((uint64_t)-1) << bits; + if (bits < 64 && (value & ((uint64_t)1 << (bits - 1)))) value |= ((uint64_t)-1) << bits; return value; } @@ -286,8 +294,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 +319,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 +361,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 +389,7 @@ void printBits(unsigned char *p, unsigned long count) { for (j = 0; j < count; j++) { byte = p[j]; - for (i = 0x80; i > 0; i /= 2) - printf("%c", (byte & i) ? '1' : '0'); + for (i = 0x80; i > 0; i /= 2) printf("%c", (byte & i) ? '1' : '0'); printf("|"); } printf("\n"); @@ -395,10 +399,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 @@ -421,8 +425,8 @@ int getBitOffsetFromArgument(client *c, robj *o, uint64_t *offset, int hash, int /* Handle # form. */ 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; } @@ -430,9 +434,8 @@ int getBitOffsetFromArgument(client *c, robj *o, uint64_t *offset, int hash, int 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 +460,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,18 +480,18 @@ 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; + 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); + 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); + o->ptr = sdsgrowzero(o->ptr, byte + 1); if (dirty && oldlen != sdslen(o->ptr)) *dirty = 1; } return o; @@ -517,10 +517,10 @@ 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; + p = (unsigned char *)o->ptr; if (len) *len = sdslen(o->ptr); } else { if (len) *len = 0; @@ -537,24 +537,22 @@ void setbitCommand(client *c) { int byteval, bitval; long on; - if (getBitOffsetFromArgument(c,c->argv[2],&bitoffset,0,0) != C_OK) - return; + if (getBitOffsetFromArgument(c, c->argv[2], &bitoffset, 0, 0) != C_OK) return; - if (getLongFromObjectOrReply(c,c->argv[3],&on,err) != C_OK) - return; + 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 +563,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 +581,16 @@ void getbitCommand(client *c) { size_t byte, bit; size_t bitval = 0; - if (getBitOffsetFromArgument(c,c->argv[2],&bitoffset,0,0) != C_OK) - return; + 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)) - bitval = llbuf[byte] & (1 << bit); + 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 +602,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); + 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 +645,10 @@ 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]) - decrRefCount(objects[i]); + if (objects[i]) decrRefCount(objects[i]); } zfree(src); zfree(len); @@ -671,7 +664,7 @@ void bitopCommand(client *c) { /* 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,67 +674,67 @@ 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++) { @@ -750,7 +743,7 @@ void bitopCommand(client *c) { 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); @@ -770,8 +763,7 @@ void bitopCommand(client *c) { } } for (j = 0; j < numkeys; j++) { - if (objects[j]) - decrRefCount(objects[j]); + if (objects[j]) decrRefCount(objects[j]); } zfree(src); zfree(len); @@ -779,17 +771,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 +796,22 @@ 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) - return; - if (getLongLongFromObjectOrReply(c,c->argv[3],&end,NULL) != C_OK) - return; + if (getLongLongFromObjectOrReply(c, c->argv[2], &start, NULL) != C_OK) return; + 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; + if (!strcasecmp(c->argv[4]->ptr, "bit")) + isbit = 1; + else if (!strcasecmp(c->argv[4]->ptr, "byte")) + isbit = 0; else { - addReplyErrorObject(c,shared.syntaxerr); + 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); + p = getObjectReadOnlyString(o, &strlen, llbuf); long long totlen = strlen; /* Make sure we will not overflow */ @@ -827,20 +819,20 @@ 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 = 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 (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; } @@ -848,13 +840,13 @@ void bitcountCommand(client *c) { /* Lookup, check for type. */ o = lookupKeyRead(c->db, c->argv[1]); if (checkType(c, o, OBJ_STRING)) return; - p = getObjectReadOnlyString(o,&strlen,llbuf); + 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 +859,20 @@ 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. */ + * 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); + count -= serverPopcount(firstlast, 2); } - addReplyLongLong(c,count); + addReplyLongLong(c, count); } } @@ -896,8 +888,7 @@ 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) - return; + 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,19 +896,19 @@ 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) - return; + 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; + if (!strcasecmp(c->argv[5]->ptr, "bit")) + isbit = 1; + else if (!strcasecmp(c->argv[5]->ptr, "byte")) + isbit = 0; else { - addReplyErrorObject(c,shared.syntaxerr); + addReplyErrorObject(c, shared.syntaxerr); return; } } if (c->argc >= 5) { - if (getLongLongFromObjectOrReply(c,c->argv[4],&end,NULL) != C_OK) - return; + if (getLongLongFromObjectOrReply(c, c->argv[4], &end, NULL) != C_OK) return; end_given = 1; } @@ -931,37 +922,39 @@ 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; /* Convert negative indexes */ - if (start < 0) start = totlen+start; - if (end < 0) end = totlen+end; + 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 (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,18 +971,22 @@ 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; start++; @@ -998,15 +995,17 @@ void bitposCommand(client *c) { /* 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 +1015,12 @@ 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 +1034,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 +1054,68 @@ 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"); + 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) - 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 +1130,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 +1144,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,18 +1169,15 @@ 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); + overflow = checkSignedBitfieldOverflow(newval, 0, thisop->bits, thisop->owtype, &wrapped); if (overflow) newval = wrapped; retval = oldval; } @@ -1193,46 +1185,40 @@ void bitfieldGeneric(client *c, int flags) { /* 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)) - changes++; + 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); + 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); + 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)) - changes++; + if (dirty || (oldval != newval)) changes++; } else { addReplyNull(c); } @@ -1244,38 +1230,35 @@ 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..0291505cb 100644 --- a/src/blocked.c +++ b/src/blocked.c @@ -87,13 +87,12 @@ 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 +102,20 @@ 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) - c->lastcmd->failed_calls++; + if (had_errors) c->lastcmd->failed_calls++; if (server.latency_tracking_enabled) - updateCommandLatencyHistogram(&(c->lastcmd->latency_histogram), total_cmd_duration*1000); + 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 +129,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,16 +174,14 @@ 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) { @@ -194,7 +190,7 @@ void unblockClient(client *c, int queue_for_reprocessing) { 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,7 +213,8 @@ 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; @@ -230,17 +227,15 @@ void unblockClient(client *c, int queue_for_reprocessing) { * 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) { @@ -257,7 +252,7 @@ void replyToClientsBlockedOnShutdown(void) { 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 +272,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 +281,10 @@ 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) - continue; + 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 +311,10 @@ 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) - return; + 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 +324,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 +334,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 +374,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 +390,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 +409,8 @@ 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) - c->flags |= CLIENT_PENDING_COMMAND; - blockClient(c,btype); + if (btype != BLOCKED_MODULE) c->flags |= CLIENT_PENDING_COMMAND; + blockClient(c, btype); } /* Helper function to unblock a client that's waiting in a blocking operation such as BLPOP. @@ -429,12 +419,11 @@ static void unblockClientWaitingData(client *c) { dictEntry *de; dictIterator *di; - if (dictSize(c->bstate.keys) == 0) - return; + 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 +432,11 @@ 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 +456,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 +466,11 @@ 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) - return; + 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) - return; + if (dictFind(db->blocking_keys, key) == NULL) return; } dictEntry *de, *existing; @@ -504,7 +490,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 +514,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 +525,17 @@ 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) - dictDelete(c->bstate.keys, key); + if (remove_key) dictDelete(c->bstate.keys, key); } void signalKeyAsReady(serverDb *db, robj *key, int type) { @@ -565,16 +550,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,9 +574,7 @@ 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)) - { + (o != NULL && (receiver->bstate.btype == BLOCKED_MODULE)) || (receiver->bstate.unblock_on_nokey)) { if (receiver->bstate.btype != BLOCKED_MODULE) unblockClientOnKey(receiver, rl->key); else @@ -633,7 +615,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 +639,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 */ @@ -723,19 +704,16 @@ void unblockClientOnTimeout(client *c) { if (c->bstate.btype == BLOCKED_MODULE && isModuleClientUnblocked(c)) return; replyToBlockedClientTimedOut(c); - if (c->flags & CLIENT_PENDING_COMMAND) - 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) - addReplyError(c, err_str); + if (err_str) addReplyError(c, err_str); updateStatsOnUnblock(c, 0, 0, 1); - if (c->flags & CLIENT_PENDING_COMMAND) - c->flags &= ~CLIENT_PENDING_COMMAND; + if (c->flags & CLIENT_PENDING_COMMAND) c->flags &= ~CLIENT_PENDING_COMMAND; unblockClient(c, 1); } @@ -745,8 +723,7 @@ void blockedBeforeSleep(void) { /* Unblock all the clients blocked for synchronous replication * in WAIT or WAITAOF. */ - if (listLength(server.clients_waiting_acks)) - processClientsWaitingReplicas(); + if (listLength(server.clients_waiting_acks)) processClientsWaitingReplicas(); /* Try to process blocked clients every once in while. * @@ -758,10 +735,8 @@ void blockedBeforeSleep(void) { /* Check if there are clients unblocked by modules that implement * blocking commands. */ - if (moduleCount()) - moduleHandleBlockedClients(); + if (moduleCount()) moduleHandleBlockedClients(); /* Try to process pending commands for clients that were just unblocked. */ - if (listLength(server.unblocked_clients)) - processUnblockedClients(); + if (listLength(server.unblocked_clients)) processUnblockedClients(); } diff --git a/src/call_reply.c b/src/call_reply.c index 9e910f50c..dcb05cc85 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,12 @@ 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 +145,15 @@ 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 +215,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 +250,7 @@ void freeCallReply(CallReply *rep) { freeCallReplyInternal(rep); } sdsfree(rep->original_proto); - if (rep->deferred_error_list) - listRelease(rep->deferred_error_list); + if (rep->deferred_error_list) listRelease(rep->deferred_error_list); zfree(rep); } @@ -308,8 +316,7 @@ 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 (rep->type != VALKEYMODULE_REPLY_STRING && rep->type != VALKEYMODULE_REPLY_ERROR) return NULL; if (len) *len = rep->len; return rep->val.str; } @@ -351,22 +358,20 @@ 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; + return rep->val.array + idx; } /* Return a reply array element at a given index. Applicable to: @@ -476,7 +481,7 @@ 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; *len = rep->len; @@ -554,7 +559,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..19a5fa045 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; @@ -84,10 +82,8 @@ 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; @@ -98,8 +94,8 @@ void sendChildInfoGeneric(childInfoType info_type, size_t keys, double progress, 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,7 +109,7 @@ 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); } } @@ -137,10 +133,10 @@ 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); @@ -148,7 +144,8 @@ int readChildInfo(childInfoType *information_type, size_t *cow, monotime *cow_up /* Do not overlap */ 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; } 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..24d796de6 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,14 +150,13 @@ 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)) - errno = EAGAIN; + 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)); + sdsrange(c->obuf, 0, -(buf_len + 1)); else sdsclear(c->obuf); @@ -182,7 +180,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 +194,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 +208,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; + 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,7 +229,7 @@ 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++) { @@ -262,8 +260,7 @@ sds unquoteCString(char *str) { unquoted[0] = NULL; } - if (unquoted) - sdsfreesplitres(unquoted, count); + if (unquoted) sdsfreesplitres(unquoted, count); return res; } @@ -311,7 +308,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 +334,21 @@ 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; /* 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; @@ -370,7 +366,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; @@ -391,7 +387,7 @@ void parseRedisUri(const char *uri, const char* tool_name, cliConnInfo *connInfo connInfo->input_dbnum = atoi(curr); } -void freeCliConnInfo(cliConnInfo connInfo){ +void freeCliConnInfo(cliConnInfo connInfo) { if (connInfo.hostip) sdsfree(connInfo.hostip); if (connInfo.auth) sdsfree(connInfo.auth); if (connInfo.user) sdsfree(connInfo.user); @@ -400,36 +396,32 @@ void freeCliConnInfo(cliConnInfo connInfo){ /* * 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); - 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); + case '"': 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; + default: 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)) - version = sdscatprintf(version, "-dirty"); + 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 d8c5d7486..d30d7e19b 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -55,18 +55,18 @@ unsigned int keyHashSlot(char *key, int keylen) { 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++) + 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 +119,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 +133,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 @@ -154,7 +153,7 @@ int verifyDumpPayload(unsigned char *p, size_t len, uint16_t *rdbver_ptr) { /* At least 2 bytes of RDB version and 8 of CRC64 should be present. */ if (len < 10) return C_ERR; - footer = p+(len-10); + footer = p + (len - 10); /* Set and verify RDB version. */ rdbver = (footer[1] << 8) | footer[0]; @@ -163,13 +162,12 @@ int verifyDumpPayload(unsigned char *p, size_t len, uint16_t *rdbver_ptr) { } if (rdbver > RDB_VERSION) return C_ERR; - if (server.skip_checksum_validation) - return C_OK; + 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 +178,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 +200,71 @@ 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 +273,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 +297,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 +316,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 +339,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 +358,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 +367,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 +378,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 +386,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 +412,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,48 +426,46 @@ 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; @@ -489,54 +475,54 @@ void migrateCommand(client *c) { * 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,10 +533,10 @@ 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; } @@ -563,31 +549,25 @@ 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)); + 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)); + 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 +580,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 +596,10 @@ 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) - goto socket_err; + 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) - goto socket_err; + if (select && connSyncReadLine(cs->conn, buf1, sizeof(buf1), timeout) <= 0) goto socket_err; /* Read the RESTORE replies. */ int error_from_target = 0; @@ -632,35 +610,34 @@ 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 +650,23 @@ 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 +691,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 +715,7 @@ 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 +727,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; } @@ -783,7 +760,7 @@ 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"); } @@ -796,7 +773,7 @@ int clusterNodeIsMyself(clusterNode *n) { 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 +799,96 @@ 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) - return; + 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) - return; - if (getLongLongFromObjectOrReply(c,c->argv[3],&maxkeys,NULL) - != C_OK) - return; + if (getLongLongFromObjectOrReply(c, c->argv[2], &slot, NULL) != C_OK) return; + 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 +899,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 +907,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 +920,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,19 +961,18 @@ 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) - return myself; + 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; @@ -1031,10 +1001,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 +1019,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 +1039,7 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i * error to the client. */ if (n == NULL) { getKeysFreeResult(&result); - if (error_code) - *error_code = CLUSTER_REDIR_DOWN_UNBOUND; + if (error_code) *error_code = CLUSTER_REDIR_DOWN_UNBOUND; return NULL; } @@ -1080,9 +1048,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 +1059,10 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i if (slot != thisslot) { /* Error: multiple keys from different slots. */ getKeysFreeResult(&result); - if (error_code) - *error_code = CLUSTER_REDIR_CROSS_SLOT; + 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 +1076,11 @@ 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); @@ -1154,8 +1120,7 @@ clusterNode *getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, i /* 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) - return myself; + 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. */ @@ -1174,9 +1139,7 @@ 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; return NULL; @@ -1188,13 +1151,10 @@ 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) && - clusterNodeGetMaster(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) && + clusterNodeGetMaster(myself) == n) { return myself; } @@ -1213,27 +1173,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 +1209,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 +1219,36 @@ 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)) - return 0; + 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) && clusterNodeGetMaster(myself) == node) - { + if ((c->flags & CLIENT_READONLY) && !(c->lastcmd->flags & CMD_WRITE) && clusterNodeIsSlave(myself) && + clusterNodeGetMaster(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; @@ -1313,7 +1260,7 @@ int clusterRedirectBlockedClientIfNeeded(client *c) { } 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)); @@ -1341,9 +1288,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); @@ -1353,9 +1299,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--; @@ -1430,7 +1375,7 @@ sds generateClusterSlotResponse(void) { /* Add cluster slots info when occur different node with start * or end of slot. */ if (i == CLUSTER_SLOTS || n != getNodeBySlot(i)) { - addNodeReplyForClusterSlot(recording_client, n, start, i-1); + addNodeReplyForClusterSlot(recording_client, n, start, i - 1); num_masters++; if (i == CLUSTER_SLOTS) break; n = getNodeBySlot(i); @@ -1447,7 +1392,8 @@ int verifyCachedClusterSlotsResponse(sds cached_response) { sds generated_response = generateClusterSlotResponse(); int is_equal = !sdscmp(generated_response, cached_response); /* Here, we use LL_WARNING so this gets printed when debug assertions are enabled and the system is about to crash. */ - if (!is_equal) serverLog(LL_WARNING,"\ngenerated_response:\n%s\n\ncached_response:\n%s", generated_response, cached_response); + if (!is_equal) + serverLog(LL_WARNING, "\ngenerated_response:\n%s\n\ncached_response:\n%s", generated_response, cached_response); sdsfree(generated_response); return is_equal; } @@ -1488,11 +1434,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. @@ -1500,19 +1446,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 dc54e0705..de5848644 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 +142,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 +185,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 +273,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 +292,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 +324,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 +333,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 +356,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; @@ -371,33 +370,29 @@ int clusterLoadConfig(char *filename) { if (line[0] == '\n' || line[0] == '\0') continue; /* Split the line into arguments for processing. */ - argv = sdssplitargs(line,&argc); + 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 (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 +403,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 +411,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; } @@ -442,17 +437,17 @@ int clusterLoadConfig(char *filename) { /* Invalid aux field format */ 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 +467,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 +476,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 +521,34 @@ int clusterLoadConfig(char *filename) { /* Parse flags */ p = s = argv[2]; - while(p) { - p = strchr(s,','); + while (p) { + p = strchr(s, ','); if (p) *p = '\0'; - if (!strcasecmp(s,"myself")) { + 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 +560,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 +570,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 @@ -598,7 +592,7 @@ int clusterLoadConfig(char *filename) { /* 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 +604,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 +623,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,23 +632,21 @@ 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; @@ -662,7 +654,7 @@ int clusterLoadConfig(char *filename) { 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,8 +665,7 @@ 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); exit(1); @@ -693,8 +684,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 +695,24 @@ 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)); + serverLog(LL_WARNING, "Failed after writing (%zd) bytes to tmp cluster config file: %s", offset, + strerror(errno)); goto cleanup; } offset += written_bytes; @@ -731,19 +721,19 @@ 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; } } @@ -759,7 +749,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); } clearCachedClusterSlotsResponse(); @@ -783,24 +773,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; @@ -823,13 +811,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; @@ -847,36 +832,37 @@ void deriveAnnouncedPorts(int *announced_tcp_port, int *announced_tls_port, void clusterUpdateMyselfFlags(void) { 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); + 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; 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); @@ -884,10 +870,10 @@ void clusterUpdateMyselfIp(void) { 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. */ } @@ -917,7 +903,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) { @@ -941,7 +927,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); } } } @@ -976,8 +962,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; @@ -993,7 +978,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)); @@ -1001,17 +986,14 @@ 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) - exit(1); + 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; @@ -1022,11 +1004,13 @@ void clusterInit(void) { * 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) { @@ -1052,7 +1036,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); } @@ -1063,12 +1048,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."); } @@ -1092,7 +1077,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. */ @@ -1107,7 +1092,7 @@ void clusterReset(int hard) { /* 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; @@ -1130,21 +1115,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); } /* ----------------------------------------------------------------------------- @@ -1156,12 +1139,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) { @@ -1198,7 +1181,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); @@ -1225,8 +1208,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); @@ -1238,8 +1221,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; } @@ -1271,12 +1253,10 @@ void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) { * UPDATE messages may interact with the database content. */ 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; } @@ -1284,26 +1264,23 @@ 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)); + serverLog(LL_VERBOSE, "Error accepting cluster node connection: %s", connGetLastError(conn)); connClose(conn); return; } @@ -1316,8 +1293,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; } /* ----------------------------------------------------------------------------- @@ -1342,7 +1318,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { 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; @@ -1355,7 +1331,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; @@ -1366,7 +1342,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); node->is_node_healthy = 0; return node; } @@ -1389,7 +1365,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) { @@ -1402,7 +1378,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; } @@ -1416,14 +1392,13 @@ 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); } } @@ -1445,7 +1420,7 @@ 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; @@ -1453,7 +1428,7 @@ int clusterNodeDelFailureReport(clusterNode *node, clusterNode *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; } @@ -1475,14 +1450,12 @@ 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) - master->flags &= ~CLUSTER_NODE_MIGRATE_TO; + if (master->numslaves == 0) master->flags &= ~CLUSTER_NODE_MIGRATE_TO; return C_OK; } } @@ -1495,8 +1468,7 @@ int clusterNodeAddSlave(clusterNode *master, clusterNode *slave) { /* 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)); + 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); @@ -1519,15 +1491,14 @@ 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++) - n->slaves[j]->slaveof = NULL; + 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); @@ -1544,8 +1515,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); } @@ -1568,21 +1538,18 @@ void clusterDelNode(clusterNode *delnode) { /* 1) Mark slots as unassigned. */ for (j = 0; j < CLUSTER_SLOTS; j++) { - if (server.cluster->importing_slots_from[j] == delnode) - server.cluster->importing_slots_from[j] = NULL; - if (server.cluster->migrating_slots_to[j] == delnode) - server.cluster->migrating_slots_to[j] = NULL; - if (server.cluster->slots[j] == delnode) - clusterDelSlot(j); + if (server.cluster->importing_slots_from[j] == delnode) server.cluster->importing_slots_from[j] = NULL; + if (server.cluster->migrating_slots_to[j] == delnode) server.cluster->migrating_slots_to[j] = NULL; + 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); + clusterNodeDelFailureReport(node, delnode); } dictReleaseIterator(di); @@ -1611,7 +1578,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; } @@ -1624,10 +1591,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); @@ -1638,7 +1602,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); @@ -1680,7 +1644,7 @@ 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; } @@ -1721,16 +1685,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; @@ -1785,19 +1744,18 @@ 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); } /* ----------------------------------------------------------------------------- @@ -1822,7 +1780,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 @@ -1836,11 +1794,10 @@ 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); } @@ -1848,16 +1805,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); } @@ -1865,11 +1822,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; } @@ -1904,15 +1861,14 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { int needed_quorum = (server.cluster->size / 2) + 1; if (!nodeTimedOut(node)) return; /* We can reach it. */ - if (nodeFailed(node)) return; /* Already FAILing. */ + 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. */ - 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; @@ -1925,7 +1881,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 @@ -1939,12 +1895,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... @@ -1952,14 +1906,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); } } @@ -1971,13 +1924,11 @@ 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 (!strcasecmp(node->ip, ip) && getNodeDefaultClientPort(node) == port && node->cport == cport) break; } dictReleaseIterator(di); return de != NULL; @@ -1996,13 +1947,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; @@ -2017,17 +1964,13 @@ 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); + 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); + 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); + inet_ntop(AF_INET6, (void *)&(((struct sockaddr_in6 *)&sa)->sin6_addr), norm_ip, NET_IP_STR_LEN); - if (clusterHandshakeInProgress(norm_ip,port,cport)) { + if (clusterHandshakeInProgress(norm_ip, port, cport)) { errno = EAGAIN; return 0; } @@ -2035,8 +1978,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 { @@ -2072,14 +2015,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; } @@ -2108,7 +2051,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 @@ -2116,26 +2059,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); } @@ -2150,18 +2089,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); } } } @@ -2170,10 +2107,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. */ @@ -2181,9 +2116,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; } } @@ -2193,16 +2126,14 @@ 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))) - { + node->cport != ntohs(g->cport))) { if (node->link) freeClusterLink(node->link); - 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); @@ -2218,13 +2149,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); @@ -2243,13 +2171,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; @@ -2268,9 +2196,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; @@ -2287,20 +2213,20 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, /* 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); 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. */ @@ -2316,7 +2242,7 @@ void clusterSetNodeAsMaster(clusterNode *n) { if (clusterNodeIsMaster(n)) return; if (n->slaveof) { - clusterNodeRemoveSlave(n->slaveof,n); + clusterNodeRemoveSlave(n->slaveof, n); if (n != myself) n->flags |= CLUSTER_NODE_MIGRATE_TO; } n->flags &= ~CLUSTER_NODE_SLAVE; @@ -2324,8 +2250,7 @@ void clusterSetNodeAsMaster(clusterNode *n) { 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 @@ -2364,12 +2289,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. */ @@ -2381,30 +2306,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++; } @@ -2422,113 +2336,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) { @@ -2545,10 +2437,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); } } @@ -2558,20 +2449,14 @@ 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) - return; + 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; } @@ -2594,32 +2479,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 @@ -2630,13 +2507,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]); } } @@ -2647,7 +2519,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) ] */ @@ -2660,20 +2532,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); } @@ -2706,7 +2577,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; @@ -2715,7 +2586,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; @@ -2728,7 +2599,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 */ @@ -2742,9 +2614,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); } @@ -2762,7 +2635,8 @@ uint32_t writePingExt(clusterMsg *hdr, int gossipcount) { uint64_t expire = dictGetUnsignedIntegerVal(de); 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); @@ -2807,10 +2681,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); @@ -2821,11 +2696,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. */ @@ -2876,16 +2750,14 @@ 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]++; - 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. */ @@ -2903,14 +2775,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. */ @@ -2920,13 +2790,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; @@ -2934,26 +2805,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; @@ -2961,7 +2827,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; } @@ -2978,11 +2844,10 @@ 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; - clusterMsg *hdr = (clusterMsg*) link->rcvbuf; + clusterMsg *hdr = (clusterMsg *)link->rcvbuf; uint16_t type = ntohs(hdr->type); mstime_t now = mstime(); @@ -3004,32 +2869,26 @@ int clusterProcessPacket(clusterLink *link) { /* 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) - server.cluster->currentEpoch = senderCurrentEpoch; + 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); } } @@ -3046,17 +2905,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); } } @@ -3068,8 +2922,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); @@ -3079,32 +2933,27 @@ 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. */ @@ -3115,24 +2964,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; @@ -3157,12 +3001,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 */ @@ -3178,8 +3019,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); } @@ -3187,9 +3027,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); @@ -3206,64 +3044,48 @@ 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 @@ -3286,7 +3108,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; @@ -3303,8 +3125,7 @@ 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) - clusterUpdateSlotsConfigWith(sender_master, senderConfigEpoch, hdr->myslots); + if (sender_master && dirty_slots) clusterUpdateSlotsConfigWith(sender_master, senderConfigEpoch, hdr->myslots); /* Explicitly check for a replication loop before attempting the replication * chain folding logic. @@ -3340,20 +3161,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 @@ -3378,18 +3193,14 @@ 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 @@ -3403,73 +3214,60 @@ 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. */ @@ -3484,11 +3282,9 @@ int clusterProcessPacket(clusterLink *link) { 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 @@ -3497,12 +3293,11 @@ 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) 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. */ @@ -3510,24 +3305,22 @@ int clusterProcessPacket(clusterLink *link) { /* 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; } @@ -3550,15 +3343,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; } @@ -3580,8 +3373,7 @@ void clusterWriteHandler(connection *conn) { totwritten += nwritten; } - if (listLength(link->send_msg_queue) == 0) - connSetWriteHandler(link->conn, NULL); + if (listLength(link->send_msg_queue) == 0) connSetWriteHandler(link->conn, NULL); } /* A connect handler that gets called when a connection to another node @@ -3593,9 +3385,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; } @@ -3610,8 +3401,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 @@ -3625,8 +3415,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 @@ -3639,7 +3428,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 @@ -3647,23 +3436,21 @@ 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; @@ -3673,13 +3460,13 @@ void clusterReadHandler(connection *conn) { if (readlen > sizeof(buf)) readlen = sizeof(buf); } - nread = connRead(conn,buf,readlen); + 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 { @@ -3689,13 +3476,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; } @@ -3737,8 +3524,7 @@ void clusterSendMessage(clusterLink *link, clusterMsgSendBlock *msgblock) { /* Populate sent messages stats. */ uint16_t type = ntohs(msgblock->msg.type); - if (type < CLUSTERMSG_TYPE_COUNT) - server.cluster->stats_bus_messages_sent[type]++; + 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 @@ -3752,12 +3538,11 @@ 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)) - continue; - clusterSendMessage(node->link,msgblock); + if (node->flags & (CLUSTER_NODE_MYSELF | CLUSTER_NODE_HANDSHAKE)) continue; + clusterSendMessage(node->link, msgblock); } dictReleaseIterator(di); } @@ -3772,8 +3557,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'; @@ -3781,24 +3565,23 @@ 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); @@ -3822,8 +3605,7 @@ static void clusterBuildMessageHdr(clusterMsg *hdr, int type, size_t msglen) { hdr->offset = htonu64(offset); /* Set the message flags. */ - if (clusterNodeIsMaster(myself) && server.cluster->mf_end) - hdr->mflags[0] |= CLUSTERMSG_FLAG0_PAUSED; + if (clusterNodeIsMaster(myself) && server.cluster->mf_end) hdr->mflags[0] |= CLUSTERMSG_FLAG0_PAUSED; hdr->totlen = htonl(msglen); } @@ -3833,10 +3615,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); @@ -3855,13 +3637,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? @@ -3889,7 +3671,7 @@ 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); + wanted = floor(dictSize(server.cluster->nodes) / 10); if (wanted < 3) wanted = 3; if (wanted > freshnodes) wanted = freshnodes; @@ -3901,7 +3683,7 @@ 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); } @@ -3911,12 +3693,11 @@ void clusterSendPing(clusterLink *link, int type) { clusterMsgSendBlock *msgblock = createClusterMsgSendBlock(type, estlen); clusterMsg *hdr = &msgblock->msg; - if (!link->inbound && type == CLUSTERMSG_TYPE_PING) - link->node->ping_sent = mstime(); + 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); @@ -3934,9 +3715,8 @@ void clusterSendPing(clusterLink *link, int type) { * 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; } @@ -3945,7 +3725,7 @@ void clusterSendPing(clusterLink *link, int type) { 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++; @@ -3957,12 +3737,12 @@ 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); + 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 @@ -3981,13 +3761,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); } @@ -4012,18 +3792,17 @@ 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 (target == CLUSTER_BROADCAST_LOCAL_SLAVES) { int local_slave = - nodeIsSlave(node) && node->slaveof && - (node->slaveof == myself || node->slaveof == myself->slaveof); + 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); } @@ -4036,7 +3815,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); @@ -4044,20 +3822,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; } @@ -4067,12 +3844,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); @@ -4084,29 +3860,28 @@ void clusterSendFail(char *nodename) { void clusterSendUpdate(clusterLink *link, clusterNode *node) { 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); @@ -4114,10 +3889,10 @@ 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); + clusterSendMessage(link, msgblock); else clusterBroadcastMessage(msgblock); @@ -4130,7 +3905,11 @@ 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) { @@ -4138,8 +3917,7 @@ int clusterSendModuleMessageToTarget(const char *target, uint64_t module_id, uin 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; } @@ -4169,11 +3947,10 @@ 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)) - continue; - clusterSendMessage(node->link,msgblock); + if (node->flags & (CLUSTER_NODE_MYSELF | CLUSTER_NODE_HANDSHAKE)) continue; + clusterSendMessage(node->link, msgblock); } clusterMsgSendBlockDecrRefCount(msgblock); } @@ -4189,7 +3966,7 @@ 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; @@ -4205,10 +3982,10 @@ void clusterRequestFailoverAuth(void) { void clusterSendFailoverAuth(clusterNode *node) { 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); } @@ -4216,10 +3993,10 @@ void clusterSendFailoverAuth(clusterNode *node) { void clusterSendMFStart(clusterNode *node) { 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); } @@ -4243,41 +4020,32 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * 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; } @@ -4285,14 +4053,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; } @@ -4301,30 +4067,27 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * 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 (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 @@ -4350,9 +4113,9 @@ int clusterGetSlaveRank(void) { 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++; + if (master->slaves[j] != myself && !nodeCantFailover(master->slaves[j]) && + master->slaves[j]->repl_offset > myoffset) + rank++; return rank; } @@ -4385,7 +4148,7 @@ 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; @@ -4393,38 +4156,29 @@ void clusterLogCantFailover(int 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 " "option."; break; - case CLUSTER_CANT_FAILOVER_WAITING_DELAY: - msg = "Waiting the delay before I can start a new failover."; - break; - case CLUSTER_CANT_FAILOVER_EXPIRED: - msg = "Failover attempt expired."; - break; - case CLUSTER_CANT_FAILOVER_WAITING_VOTES: - msg = "Waiting for votes, but majority still not reached."; - break; - default: - msg = "Unknown reason code."; - break; + case CLUSTER_CANT_FAILOVER_WAITING_DELAY: msg = "Waiting the delay before I can start a new failover."; break; + case CLUSTER_CANT_FAILOVER_EXPIRED: msg = "Failover attempt expired."; break; + case CLUSTER_CANT_FAILOVER_WAITING_VOTES: msg = "Waiting for votes, but majority still not reached."; break; + default: msg = "Unknown reason code."; 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, @@ -4447,7 +4201,7 @@ void clusterFailoverReplaceYourMaster(void) { for (j = 0; j < CLUSTER_SLOTS; j++) { if (clusterNodeCoversSlot(oldmaster, j)) { clusterDelSlot(j); - clusterAddSlot(myself,j); + clusterAddSlot(myself, j); } } @@ -4475,8 +4229,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; @@ -4488,9 +4241,9 @@ void clusterHandleSlaveFailover(void) { * Timeout is MAX(NODE_TIMEOUT*2,2000) milliseconds. * Retry is two times the Timeout. */ - auth_timeout = server.cluster_node_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; + 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: @@ -4498,11 +4251,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; @@ -4512,8 +4262,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; } @@ -4521,18 +4270,15 @@ 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) - 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; @@ -4543,16 +4289,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(); @@ -4560,11 +4305,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. */ @@ -4577,18 +4321,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); } } @@ -4608,13 +4348,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. */ } @@ -4622,15 +4360,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. */ @@ -4680,8 +4416,7 @@ void clusterHandleSlaveMigration(int max_slaves) { * '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 (!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 @@ -4696,7 +4431,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; @@ -4726,10 +4461,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]; } } @@ -4742,14 +4474,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); } } @@ -4803,7 +4531,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(); } } @@ -4824,9 +4552,8 @@ void clusterHandleManualFailover(void) { /* 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; } @@ -4843,10 +4570,9 @@ 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) - server.cluster->stats_pfail_nodes++; + 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. */ @@ -4859,17 +4585,18 @@ 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); + serverLog(LL_DEBUG, + "Unable to connect to " + "Cluster Node [%s]:%d -> %s", + node->ip, node->cport, server.neterr); freeClusterLink(link); return 0; @@ -4885,9 +4612,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++; } @@ -4905,8 +4633,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; @@ -4927,7 +4655,7 @@ void clusterCron(void) { 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. */ @@ -4935,9 +4663,9 @@ 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. */ @@ -4952,15 +4680,14 @@ void clusterCron(void) { /* 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)) - 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); } } @@ -4975,13 +4702,11 @@ 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. */ @@ -4991,14 +4716,11 @@ 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) - this_slaves = okslaves; + if (myself->slaveof == node) this_slaves = okslaves; } /* If we are not receiving any data for more than half the cluster @@ -5006,15 +4728,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); } @@ -5023,23 +4743,16 @@ 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; } @@ -5055,19 +4768,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); } } } @@ -5077,11 +4789,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)); } @@ -5090,20 +4798,17 @@ void clusterCron(void) { if (nodeIsSlave(myself)) { clusterHandleManualFailover(); - if (!(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) - clusterHandleSlaveFailover(); + 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) + if (orphaned_masters && max_slaves >= 2 && this_slaves == max_slaves && server.cluster_allow_replica_migration) clusterHandleSlaveMigration(max_slaves); } - if (update_state || server.cluster->state == CLUSTER_FAIL) - clusterUpdateState(); + if (update_state || server.cluster->state == CLUSTER_FAIL) clusterUpdateState(); } /* This function is called before the event handler returns to sleep for @@ -5123,8 +4828,7 @@ void clusterBeforeSleep(void) { * as it was handled only in clusterCron */ if (nodeIsSlave(myself)) { clusterHandleManualFailover(); - if (!(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) - clusterHandleSlaveFailover(); + 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 @@ -5133,8 +4837,7 @@ void clusterBeforeSleep(void) { } /* Update the cluster state. */ - if (flags & CLUSTER_TODO_UPDATE_STATE) - clusterUpdateState(); + if (flags & CLUSTER_TODO_UPDATE_STATE) clusterUpdateState(); /* Save the config, possibly using fsync. */ if (flags & CLUSTER_TODO_SAVE_CONFIG) { @@ -5154,23 +4857,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; @@ -5192,9 +4895,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 @@ -5209,17 +4912,16 @@ 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()) - n->flags |= CLUSTER_NODE_MIGRATE_TO; + 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; @@ -5227,7 +4929,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 @@ -5236,7 +4938,7 @@ int clusterNodeCoversSlot(clusterNode *n, int slot) { * an error and C_ERR is returned. */ int clusterAddSlot(clusterNode *n, int slot) { if (server.cluster->slots[slot]) return C_ERR; - clusterNodeSetSlotBit(n,slot); + clusterNodeSetSlotBit(n, slot); server.cluster->slots[slot] = n; bitmapClearBit(server.cluster->owner_not_claiming_slot, slot); return C_OK; @@ -5253,7 +4955,7 @@ int clusterDelSlot(int slot) { /* 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); @@ -5277,10 +4979,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)); } /* ----------------------------------------------------------------------------- @@ -5310,9 +5010,9 @@ void clusterUpdateState(void) { * 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 (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. */ @@ -5321,9 +5021,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; } @@ -5341,13 +5039,12 @@ 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) - reachable_masters++; + if ((node->flags & (CLUSTER_NODE_FAIL | CLUSTER_NODE_PFAIL)) == 0) reachable_masters++; } } dictReleaseIterator(di); @@ -5372,22 +5069,16 @@ 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) - rejoin_delay = CLUSTER_MAX_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 (rejoin_delay > CLUSTER_MAX_REJOIN_DELAY) rejoin_delay = CLUSTER_MAX_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) { 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; } } @@ -5415,8 +5106,7 @@ 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) - return C_OK; + 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. */ @@ -5434,8 +5124,7 @@ int verifyClusterConfigWithData(void) { /* 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 @@ -5444,23 +5133,25 @@ 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); } @@ -5491,16 +5182,15 @@ 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(); myself->slaveof = n; updateShardId(myself, n->shard_id); - clusterNodeAddSlave(n,myself); + clusterNodeAddSlave(n, myself); replicationSetMaster(n->ip, getNodeDefaultReplicationPort(n)); removeAllNotOwnedShardChannelSubscriptions(); resetManualFailover(); @@ -5516,28 +5206,23 @@ 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 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; } @@ -5545,9 +5230,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 { @@ -5567,21 +5252,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; } @@ -5593,23 +5275,19 @@ 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); + ci = sdscatlen(ci, " ", 1); if (node->slaveof) - ci = sdscatlen(ci,node->slaveof->name,CLUSTER_NAMELEN); + ci = sdscatlen(ci, node->slaveof->name, CLUSTER_NAMELEN); else - ci = sdscatlen(ci,"-",1); + 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. */ @@ -5623,13 +5301,13 @@ sds clusterGenNodeDescription(client *c, clusterNode *node, int tls_primary) { if ((bit = clusterNodeCoversSlot(node, j)) != 0) { 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; } @@ -5642,11 +5320,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); } } } @@ -5679,7 +5355,7 @@ 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; n = server.cluster->slots[i]; @@ -5703,7 +5379,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 @@ -5718,14 +5394,14 @@ 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; 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); @@ -5782,7 +5458,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++; @@ -5803,7 +5479,7 @@ void addReplyClusterLinksDescription(client *c) { * -------------------------------------------------------------------------- */ const char *clusterGetMessageTypeString(int type) { - switch(type) { + switch (type) { case CLUSTERMSG_TYPE_PING: return "ping"; case CLUSTERMSG_TYPE_PONG: return "pong"; case CLUSTERMSG_TYPE_MEET: return "meet"; @@ -5822,27 +5498,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; } } @@ -5854,15 +5528,13 @@ 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]) - server.cluster->importing_slots_from[j] = NULL; + 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); } } } @@ -5947,8 +5619,7 @@ 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++) - addReplyLongLong(c, (unsigned long)n->slot_info_pairs[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); @@ -5973,7 +5644,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); @@ -5981,7 +5652,7 @@ 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; @@ -6000,25 +5671,18 @@ 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; @@ -6027,28 +5691,21 @@ sds genClusterInfoString(void) { for (int i = 0; i < CLUSTERMSG_TYPE_COUNT; i++) { 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; 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; } @@ -6063,15 +5720,14 @@ 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)) - return 0; + 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)); @@ -6122,15 +5778,15 @@ 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; @@ -6145,9 +5801,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; } @@ -6159,7 +5813,7 @@ 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; } @@ -6172,7 +5826,7 @@ int handleDebugClusterCommand(client *c) { 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); @@ -6180,7 +5834,7 @@ int handleDebugClusterCommand(client *c) { } int clusterNodePending(clusterNode *node) { - return node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE); + return node->flags & (CLUSTER_NODE_NOADDR | CLUSTER_NODE_HANDSHAKE); } char *clusterNodeIp(clusterNode *node) { @@ -6213,11 +5867,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 +5885,69 @@ 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 (!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[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 +5955,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; } @@ -6370,39 +6022,28 @@ void clusterCommandSetSlot(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 +6058,13 @@ void clusterCommandSetSlot(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 +6084,7 @@ void clusterCommandSetSlot(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 +6093,62 @@ void clusterCommandSetSlot(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 +6156,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 +6168,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 +6195,120 @@ 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 */ clusterCommandSetSlot(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); + 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) { + 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); + addReply(c, shared.ok); else - addReplyErrorFormat(c,"Unknown node %s", (char*)c->argv[2]->ptr); + 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 +6319,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 +6343,39 @@ 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) - return 1; + 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) - server.cluster->currentEpoch = 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 +6383,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 +6434,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 +6474,9 @@ 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 +6485,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; } @@ -6896,7 +6500,7 @@ int detectAndUpdateCachedNodeHealth(void) { dictEntry *de; clusterNode *node; int overall_health_changed = 0; - while((de = dictNext(&di)) != NULL) { + while ((de = dictNext(&di)) != NULL) { node = dictGetVal(de); int present_is_node_healthy = isNodeAvailable(node); if (present_is_node_healthy != node->is_node_healthy) { @@ -6913,7 +6517,7 @@ 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; diff --git a/src/cluster_legacy.h b/src/cluster_legacy.h index 2a2255706..cc02f30a8 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,92 +267,94 @@ 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 */ - int is_node_healthy; /* Boolean indicating the cached node health. - Update with updateAndCountChangedNodeHealth(). */ + 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 */ + int is_node_healthy; /* Boolean indicating the cached node health. + Update with updateAndCountChangedNodeHealth(). */ }; 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 @@ -361,4 +365,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 92816a30d..646a5ea63 100644 --- a/src/config.c +++ b/src/config.c @@ -50,129 +50,86 @@ 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 aof_fsync_enum[] = { - {"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 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} -}; - -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 sanitize_dump_payload_enum[] = { - {"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 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 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}}; + +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 tls_auth_clients_enum[] = {{"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 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}}; + +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 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 +140,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 +200,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 +236,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 */ @@ -303,7 +265,7 @@ int configEnumGetValue(configEnum *ce, sds *argv, int argc, int bitflags) { 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; } @@ -317,7 +279,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 +302,7 @@ 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) - return ce->name; + if (server.maxmemory_policy == ce->val) return ce->name; } serverPanic("unknown eviction policy"); } @@ -351,13 +312,16 @@ 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 +338,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 +362,9 @@ 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 +374,19 @@ 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; } @@ -459,17 +424,17 @@ 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; /* 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 +442,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 +466,39 @@ 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 +519,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 +540,9 @@ void loadServerConfigFromString(char *config) { } sds name = sdsdup(argv[0]); sds val = sdsdup(argv[1]); - for (int i = 2; i < argc; i++) - val = sdscatfmt(val, " %S", argv[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")) { + } 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 +550,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 +565,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,7 +581,8 @@ 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; } @@ -628,12 +590,12 @@ void loadServerConfigFromString(char *config) { 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 +615,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 +638,13 @@ 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 +654,25 @@ 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,7 +685,7 @@ 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; } @@ -760,21 +714,20 @@ 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 */ @@ -822,41 +775,41 @@ 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 */ + /* 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 +826,26 @@ 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; /* Backup old values before setting new ones */ - for (i = 0; i < config_count; i++) - old_values[i] = set_configs[i]->interface.get(set_configs[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 +873,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 +891,25 @@ 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++) - sdsfree(old_values[i]); + for (i = 0; i < config_count; i++) sdsfree(old_values[i]); zfree(old_values); zfree(apply_fns); zfree(config_map_fns); @@ -973,7 +927,7 @@ 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 @@ -990,7 +944,7 @@ 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) */ @@ -1002,11 +956,11 @@ void configGetCommand(client *c) { } 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 +984,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 +1018,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 +1038,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 +1060,7 @@ 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,7 +1069,7 @@ 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"); + FILE *fp = fopen(path, "r"); if (fp == NULL && errno != ENOENT) return NULL; struct valkey_stat sb; @@ -1134,11 +1088,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 +1100,42 @@ 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)) - state->needs_signature = 0; - rewriteConfigAppendLine(state,line); + if (state->needs_signature && !strcmp(line, CONFIG_REWRITE_SIGNATURE)) state->needs_signature = 0; + 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); + aux = sdscatsds(aux, line); if (argv) sdsfreesplitres(argv, argc); sdsfree(line); - rewriteConfigAppendLine(state,aux); + rewriteConfigAppendLine(state, aux); continue; } @@ -1194,7 +1143,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 +1152,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 +1188,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 +1201,21 @@ 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,47 +1224,52 @@ 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. */ @@ -1327,18 +1280,18 @@ void rewriteConfigStringOption(struct rewriteConfigState *state, const char *opt /* 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. */ @@ -1364,19 +1317,25 @@ 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 +1343,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 +1359,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 +1367,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 +1386,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 +1394,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 +1417,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 +1436,14 @@ 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 +1453,31 @@ 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 +1491,12 @@ 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]) - force = 1; + 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) - line = sdscatlen(line, " ", 1); + 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,13 +1519,13 @@ 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," "); + addresses = sdsjoin(server.bindaddr, server.bindaddr_count, " "); else addresses = sdsnew("\"\""); line = sdsnew(name); @@ -1578,7 +1533,7 @@ void rewriteConfigBindOption(standardConfig *config, const char *name, struct re line = sdscatsds(line, addresses); sdsfree(addresses); - rewriteConfigRewriteLine(state,name,line,force); + rewriteConfigRewriteLine(state, name, line, force); } /* Rewrite the loadmodule option. */ @@ -1595,11 +1550,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 @@ -1616,8 +1571,8 @@ sds rewriteConfigGetContentFromState(struct rewriteConfigState *state) { } 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 +1589,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,10 +1616,10 @@ 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; @@ -1713,13 +1668,13 @@ 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)) @@ -1790,7 +1745,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 +1758,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 +1788,7 @@ 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)) - return 0; + 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 +1812,28 @@ 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)) - return 0; + 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 +1849,19 @@ 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)) - return 0; + 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]; @@ -1952,29 +1902,31 @@ static void sdsConfigRewrite(standardConfig *config, const char *name, struct re #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 +1941,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 +1954,10 @@ 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)) - return 0; + 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) - return setModuleEnumConfig(config->privdata, enumval, err); + if (config->flags & MODULE_CONFIG) return setModuleEnumConfig(config->privdata, enumval, err); *(config->data.enumd.config) = enumval; return 1; } @@ -2018,7 +1967,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 +1975,75 @@ 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) 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 +2061,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 +2074,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 +2082,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 +2096,15 @@ 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) - return 1; + 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,18 +2112,15 @@ static int numericParseString(standardConfig *config, sds value, const char **er char *endptr; errno = 0; *res = strtoll(value, &endptr, 8); - if (errno == 0 && *endptr == '\0') - return 1; /* No overflow or invalid characters */ + 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)) - return 1; + 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" ; + 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) @@ -2194,14 +2134,11 @@ 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)) - return 0; + if (!numericParseString(config, argv[0], err, &ll)) return 0; - if (!numericBoundaryCheck(config, ll, err)) - return 0; + if (!numericBoundaryCheck(config, ll, err)) return 0; - if (config->data.numeric.is_valid_fn && !config->data.numeric.is_valid_fn(ll, err)) - return 0; + 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 +2157,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 +2184,102 @@ 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 +2339,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 +2349,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 +2358,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++]; @@ -2498,9 +2441,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(); } @@ -2560,16 +2507,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; } @@ -2625,8 +2570,7 @@ 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) - closeListener(tls_listener); /* failed with TLS together */ + if (tls_listener) closeListener(tls_listener); /* failed with TLS together */ return 0; } @@ -2681,8 +2625,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; } @@ -2727,8 +2671,7 @@ static sds getConfigDirOption(standardConfig *config) { UNUSED(config); char buf[1024]; - if (getcwd(buf,sizeof(buf)) == NULL) - buf[0] = '\0'; + if (getcwd(buf, sizeof(buf)) == NULL) buf[0] = '\0'; return sdsnew(buf); } @@ -2738,14 +2681,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; @@ -2755,9 +2698,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; } @@ -2780,8 +2721,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); } @@ -2794,11 +2735,8 @@ 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; @@ -2814,13 +2752,10 @@ 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; } @@ -2856,11 +2791,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++) { @@ -2879,9 +2812,8 @@ 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; @@ -2907,7 +2839,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; @@ -2923,14 +2855,13 @@ static int setConfigBindOption(standardConfig *config, sds* argv, int argc, cons for (j = 0; j < server.bindaddr_count; j++) { zfree(server.bindaddr[j]); } - for (j = 0; j < argc; j++) - server.bindaddr[j] = zstrdup(argv[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) { @@ -2956,15 +2887,14 @@ 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); + snprintf(buf, sizeof(buf), "%s %d", server.masterhost, server.masterport); else buf[0] = '\0'; return sdsnew(buf); @@ -2976,7 +2906,8 @@ 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; @@ -2986,7 +2917,7 @@ static int setConfigLatencyTrackingInfoPercentilesOutputOption(standardConfig *c if (argc == 1 && sdslen(argv[0]) == 0) server.latency_tracking_info_percentiles_len = 0; else - server.latency_tracking_info_percentiles = zmalloc(sizeof(double)*argc); + server.latency_tracking_info_percentiles = zmalloc(sizeof(double) * argc); for (int j = 0; j < server.latency_tracking_info_percentiles_len; j++) { double percentile; @@ -3017,14 +2948,15 @@ 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, @@ -3032,7 +2964,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]; @@ -3041,7 +2973,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) { @@ -3051,10 +2983,8 @@ 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) - return 1; - if (server.maxmemory_clients != 0) - initServerClientMemUsageBuckets(); + if (server.maxmemory_clients != 0 && server.client_mem_usage_buckets) return 1; + if (server.maxmemory_clients != 0) initServerClientMemUsageBuckets(); /* When client eviction is enabled update memory buckets for all clients. * When disabled, clear that data structure. */ @@ -3070,8 +3000,7 @@ static int applyClientMaxMemoryUsage(const char **err) { } } - if (server.maxmemory_clients == 0) - freeServerClientMemUsageBuckets(); + if (server.maxmemory_clients == 0) freeServerClientMemUsageBuckets(); return 1; } @@ -3079,223 +3008,1451 @@ 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("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("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("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, invalidateClusterSlotsResp), - 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, + invalidateClusterSlotsResp), + 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.. */ @@ -3311,7 +4468,7 @@ 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); @@ -3336,10 +4493,10 @@ void removeConfig(sds name) { standardConfig *config = lookupConfig(name); 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++; } @@ -3359,7 +4516,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); @@ -3368,25 +4526,40 @@ 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); @@ -3397,17 +4570,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); } @@ -3420,7 +4591,7 @@ void configResetStatCommand(client *c) { resetServerStats(); resetCommandTableStats(server.commands); resetErrorTableStats(); - addReply(c,shared.ok); + addReply(c, shared.ok); } /*----------------------------------------------------------------------------- @@ -3429,16 +4600,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 a899ba8b9..e5adb785a 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,29 +98,22 @@ #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 /* Detect for pipe2() */ -#if defined(__linux__) || \ - defined(__FreeBSD__) || \ - defined(OpenBSD5_7) || \ - (defined(__DragonFly__) && __DragonFly_version >= 400106) || \ +#if defined(__linux__) || defined(__FreeBSD__) || defined(OpenBSD5_7) || \ + (defined(__DragonFly__) && __DragonFly_version >= 400106) || \ (defined(__NetBSD__) && (defined(NetBSD6_0) || __NetBSD_Version__ >= 600000000)) #define HAVE_PIPE2 1 #endif /* Detect for kqueue */ -#if (defined(__APPLE__) && defined(MAC_OS_10_6_DETECTED)) || \ - defined(__DragonFly__) || \ - defined(__FreeBSD__) || \ - defined(__OpenBSD__) || \ - defined (__NetBSD__) +#if (defined(__APPLE__) && defined(MAC_OS_10_6_DETECTED)) || defined(__DragonFly__) || defined(__FreeBSD__) || \ + defined(__OpenBSD__) || defined(__NetBSD__) #define HAVE_KQUEUE 1 #endif @@ -183,11 +176,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(). @@ -213,31 +207,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 */ @@ -265,13 +255,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 @@ -292,7 +281,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..f0c1c2d36 100644 --- a/src/connection.c +++ b/src/connection.c @@ -37,8 +37,7 @@ 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) - break; + if (!tmpct) break; /* ignore case, we really don't care "tls"/"TLS" */ if (!strcasecmp(typename, tmpct->get_type(NULL))) { @@ -75,11 +74,9 @@ ConnectionType *connectionByType(const char *typename) { for (int type = 0; type < CONN_TYPE_MAX; type++) { ct = connTypes[type]; - if (!ct) - break; + if (!ct) break; - if (!strcasecmp(typename, ct->get_type(NULL))) - return ct; + if (!strcasecmp(typename, ct->get_type(NULL))) return ct; } serverLog(LL_WARNING, "Missing implement of connection type %s", typename); @@ -91,8 +88,7 @@ ConnectionType *connectionByType(const char *typename) { ConnectionType *connectionTypeTcp(void) { static ConnectionType *ct_tcp = NULL; - if (ct_tcp != NULL) - return ct_tcp; + if (ct_tcp != NULL) return ct_tcp; ct_tcp = connectionByType(CONN_TYPE_SOCKET); serverAssert(ct_tcp != NULL); @@ -119,8 +115,7 @@ ConnectionType *connectionTypeTls(void) { ConnectionType *connectionTypeUnix(void) { static ConnectionType *ct_unix = NULL; - if (ct_unix != NULL) - return ct_unix; + if (ct_unix != NULL) return ct_unix; ct_unix = connectionByType(CONN_TYPE_UNIX); return ct_unix; @@ -131,11 +126,9 @@ int connectionIndexByType(const char *typename) { for (int type = 0; type < CONN_TYPE_MAX; type++) { ct = connTypes[type]; - if (!ct) - break; + if (!ct) break; - if (!strcasecmp(typename, ct->get_type(NULL))) - return type; + if (!strcasecmp(typename, ct->get_type(NULL))) return type; } return -1; @@ -147,11 +140,9 @@ void connTypeCleanupAll(void) { for (type = 0; type < CONN_TYPE_MAX; type++) { ct = connTypes[type]; - if (!ct) - break; + if (!ct) break; - if (ct->cleanup) - ct->cleanup(); + if (ct->cleanup) ct->cleanup(); } } @@ -190,16 +181,14 @@ 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) - continue; + 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) - info = sdscatfmt(info, ",port=%i", 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 b44ef0778..3de581b41 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,19 +54,15 @@ 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 enum connTypeForCaching { - CACHE_CONN_TCP, - CACHE_CONN_TLS, - CACHE_CONN_TYPE_MAX -} connTypeForCaching; +typedef enum connTypeForCaching { CACHE_CONN_TCP, CACHE_CONN_TLS, CACHE_CONN_TYPE_MAX } connTypeForCaching; typedef void (*ConnectionCallbackFunc)(struct connection *conn); @@ -87,13 +83,17 @@ 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); @@ -174,8 +174,11 @@ static inline int connAccept(connection *conn, ConnectionCallbackFunc accept_han * If C_ERR is returned, the operation failed and the connection handler shall * not be expected. */ -static inline int connConnect(connection *conn, const char *addr, int port, const char *src_addr, - ConnectionCallbackFunc connect_handler) { +static inline int connConnect(connection *conn, + const char *addr, + int port, + const char *src_addr, + ConnectionCallbackFunc connect_handler) { return conn->type->connect(conn, addr, port, src_addr, connect_handler); } @@ -213,7 +216,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. * @@ -298,12 +301,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; @@ -362,7 +363,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; } @@ -439,8 +440,7 @@ static inline int connListen(connListener *listener) { /* Get accept_handler of a connection type */ static inline aeFileProc *connAcceptHandler(ConnectionType *ct) { - if (ct) - return ct->accept_handler; + if (ct) return ct->accept_handler; return NULL; } @@ -456,4 +456,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..b543f2ed2 100644 --- a/src/connhelpers.h +++ b/src/connhelpers.h @@ -85,4 +85,4 @@ static inline int callHandler(connection *conn, ConnectionCallbackFunc handler) return 1; } -#endif /* VALKEY_CONNHELPERS_H */ +#endif /* VALKEY_CONNHELPERS_H */ diff --git a/src/db.c b/src/db.c index a3fec5d1d..fa07deeb4 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,8 @@ 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) - expire_flags |= EXPIRE_FORCE_DELETE_EXPIRED; - if (flags & LOOKUP_NOEXPIRE) - expire_flags |= EXPIRE_AVOID_DELETE_EXPIRED; + if (flags & LOOKUP_WRITE && !is_ro_replica) expire_flags |= EXPIRE_FORCE_DELETE_EXPIRED; + 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; @@ -124,7 +122,7 @@ robj *lookupKey(serverDb *db, robj *key, int flags) { if (server.current_client && server.current_client->flags & CLIENT_NO_TOUCH && 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 +130,11 @@ robj *lookupKey(serverDb *db, robj *key, int flags) { } } - if (!(flags & (LOOKUP_NOSTATS | LOOKUP_WRITE))) - server.stat_keyspace_hits++; + if (!(flags & (LOOKUP_NOSTATS | LOOKUP_WRITE))) server.stat_keyspace_hits++; /* TODO: Use separate hits stats for WRITE */ } else { - if (!(flags & (LOOKUP_NONOTIFY | LOOKUP_WRITE))) - notifyKeyspaceEvent(NOTIFY_KEY_MISS, "keymiss", key, db->id); - if (!(flags & (LOOKUP_NOSTATS | LOOKUP_WRITE))) - server.stat_keyspace_misses++; + if (!(flags & (LOOKUP_NONOTIFY | LOOKUP_WRITE))) notifyKeyspaceEvent(NOTIFY_KEY_MISS, "keymiss", key, db->id); + if (!(flags & (LOOKUP_NOSTATS | LOOKUP_WRITE))) server.stat_keyspace_misses++; /* TODO: Use separate misses stats and notify event for WRITE */ } @@ -163,7 +158,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 @@ -210,7 +205,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 +213,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 +228,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); @@ -275,7 +271,7 @@ int dbAddRDBLoad(serverDb *db, sds key, robj *val) { 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); + serverAssertWithInfo(NULL, key, de != NULL); robj *old = dictGetVal(de); val->lru = old->lru; @@ -287,16 +283,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); } @@ -329,18 +325,18 @@ void setKey(client *c, serverDb *db, robj *key, robj *val, int flags) { else if (flags & SETKEY_ADD_OR_UPDATE) keyfound = -1; else if (!(flags & SETKEY_DOESNT_EXIST)) - keyfound = (lookupKeyWrite(db,key) != NULL); + 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,7 +348,7 @@ 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); @@ -360,7 +356,7 @@ robj *dbRandomKey(serverDb *db) { 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 +369,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 +390,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 +462,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 +473,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 +515,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 +527,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 @@ -554,9 +546,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 +559,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) - return C_ERR; + if (id < 0 || id >= server.dbnum) return C_ERR; c->db = &server.db[id]; return C_OK; } @@ -621,15 +610,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 +650,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 +665,19 @@ int getFlushCommandFlags(client *c, int *flags) { /* Flushes the whole server data set. */ void flushAllDataAndResetRDB(int flags) { - server.dirty += emptyData(-1,flags,NULL); + 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)) - jemalloc_purge(); + if (!(flags & EMPTYDB_ASYNC)) jemalloc_purge(); #endif } @@ -699,22 +687,21 @@ 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)) - jemalloc_purge(); + if (!(flags & EMPTYDB_ASYNC)) jemalloc_purge(); #endif } @@ -723,7 +710,7 @@ 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 +718,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 +726,24 @@ 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) - continue; - int deleted = lazy ? dbAsyncDelete(c->db,c->argv[j]) : - dbSyncDelete(c->db,c->argv[j]); + 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]); 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 +753,24 @@ 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) - return; + 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 +782,7 @@ void randomkeyCommand(client *c) { return; } - addReplyBulk(c,key); + addReplyBulk(c, key); decrRefCount(key); } @@ -818,7 +801,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,46 +812,43 @@ 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) - break; + if (c->flags & CLIENT_CLOSE_ASAP) break; } - if (kvs_di) - kvstoreReleaseDictIterator(kvs_di); - if (kvs_it) - kvstoreIteratorRelease(kvs_it); - setDeferredArrayLen(c,replylen,numkeys); + if (kvs_di) kvstoreReleaseDictIterator(kvs_di); + if (kvs_it) kvstoreIteratorRelease(kvs_it); + 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) return 0; - else + else return 1; } /* This callback is used by scanGenericCommand in order to collect elements @@ -934,19 +914,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; @@ -997,8 +969,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. */ @@ -1007,20 +978,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 @@ -1030,13 +999,13 @@ 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) { 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"); @@ -1052,7 +1021,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; } } @@ -1088,7 +1057,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. */ @@ -1097,7 +1066,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; @@ -1110,7 +1079,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, @@ -1153,15 +1122,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); @@ -1201,7 +1168,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) { @@ -1216,21 +1183,21 @@ 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)); } @@ -1239,9 +1206,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; @@ -1250,15 +1217,13 @@ 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; } @@ -1303,47 +1268,44 @@ 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) - return; + 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) { @@ -1353,7 +1315,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; } @@ -1361,51 +1323,48 @@ void moveCommand(client *c) { src = c->db; srcid = c->db->id; - if (getIntFromObjectOrReply(c, c->argv[2], &dbid, NULL) != C_OK) - return; + 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) { @@ -1415,8 +1374,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; @@ -1424,27 +1383,26 @@ 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) - return; + 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; } @@ -1454,60 +1412,58 @@ 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"); - return; + 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); + 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 @@ -1517,7 +1473,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) { @@ -1534,7 +1490,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; @@ -1555,8 +1511,7 @@ 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) - signalDeletedKeyAsReady(emptied, key, original_type); + if ((existed && !exists) || original_type != curr_type) signalDeletedKeyAsReady(emptied, key, original_type); } dictReleaseIterator(di); } @@ -1570,8 +1525,7 @@ 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 < 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]; @@ -1616,7 +1570,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; @@ -1662,28 +1616,24 @@ 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) - return; + 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) - return; + 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); } } @@ -1705,7 +1655,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); @@ -1714,8 +1664,7 @@ 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 @@ -1723,8 +1672,7 @@ 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) - return -1; + if ((de = dbFindExpires(db, key->ptr)) == NULL) return -1; return dictGetSignedIntegerVal(de); } @@ -1733,12 +1681,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++; } @@ -1773,7 +1721,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]); @@ -1785,7 +1733,7 @@ int keyIsExpired(serverDb *db, robj *key) { /* Don't expire anything while loading. It will be done later. */ 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 */ @@ -1825,11 +1773,11 @@ 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 (!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: @@ -1839,7 +1787,7 @@ 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 @@ -1851,8 +1799,7 @@ keyStatus expireIfNeeded(serverDb *db, robj *key, int flags) { /* 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) - return KEY_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 @@ -1865,7 +1812,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); } @@ -1902,7 +1849,7 @@ static int dbExpandGeneric(kvstore *kvs, uint64_t db_size, int try_expand) { 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) { @@ -1959,8 +1906,7 @@ 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) - memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference)); + if (result->numkeys) memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference)); } result->size = numkeys; } @@ -1974,17 +1920,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; @@ -2003,13 +1949,13 @@ 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) - break; - if (!strcasecmp((char*)argv[i]->ptr,spec->bs.keyword.keyword)) { - first = i+1; + if (i >= argc || i < 1) break; + if (!strcasecmp((char *)argv[i]->ptr, spec->bs.keyword.keyword)) { + first = i + 1; break; } } @@ -2031,29 +1977,28 @@ 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) - goto invalid_spec; + 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 */ @@ -2073,8 +2018,8 @@ int getKeysUsingKeySpecs(struct serverCommand *cmd, robj **argv, int argc, int s continue; } else { serverPanic("%s built-in command declared keys positions" - " not matching the arity requirements.", - server.extended_redis_compat ? "Redis" : "Valkey"); + " not matching the arity requirements.", + server.extended_redis_compat ? "Redis" : "Valkey"); } } keys[result->numkeys].pos = i; @@ -2091,7 +2036,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 { @@ -2103,19 +2048,23 @@ 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 */ @@ -2123,39 +2072,36 @@ 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) - return ret; + 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[] = { @@ -2167,7 +2113,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 @@ -2186,14 +2132,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. * @@ -2213,7 +2159,7 @@ int getChannelsFromCommand(struct serverCommand *cmd, robj **argv, int argc, get 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; } @@ -2227,12 +2173,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; @@ -2246,13 +2192,12 @@ 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) - last += first; + 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) { @@ -2268,8 +2213,8 @@ int getKeysUsingLegacyRangeSpec(struct serverCommand *cmd, robj **argv, int argc return 0; } else { serverPanic("%s built-in command declared keys positions" - " not matching the arity requirements.", - server.extended_redis_compat ? "Redis" : "Valkey"); + " not matching the arity requirements.", + server.extended_redis_compat ? "Redis" : "Valkey"); } } keys[i].pos = j; @@ -2293,18 +2238,17 @@ 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) - zfree(result->keys); + if (result && result->keys != result->keysbuf) zfree(result->keys); } /* Helper function to extract keys from following commands: @@ -2318,17 +2262,22 @@ 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; } @@ -2339,14 +2288,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; } @@ -2424,8 +2373,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; @@ -2434,7 +2383,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 @@ -2445,23 +2394,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; } @@ -2483,22 +2429,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; @@ -2516,9 +2456,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; } @@ -2527,7 +2467,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; @@ -2542,8 +2482,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++; } } @@ -2558,9 +2498,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; @@ -2608,10 +2548,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; } @@ -2628,10 +2568,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 314238917..51e9c6e9f 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,15 @@ 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++) - digest[j] ^= hash[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 +121,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 +143,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 +178,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 +225,50 @@ 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 +283,33 @@ 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) - continue; + 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 +323,39 @@ 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) - return; + 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 +363,170 @@ 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"))) - valref = NULL, sz = 0; + if ((!strcmp(val, "VOID"))) valref = NULL, sz = 0; wret = je_mallctl(argv[0]->ptr, NULL, 0, valref, sz); } if (!rret) addReplyBulkCString(c, old); else if (wret) - addReplyErrorFormat(c,"%s", strerror(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