diff --git a/include/util/tconfig.h b/include/util/tconfig.h index 2095601e14..4c16ed0ea6 100644 --- a/include/util/tconfig.h +++ b/include/util/tconfig.h @@ -106,12 +106,15 @@ int32_t cfgLoad(SConfig *pCfg, ECfgSrcType cfgType, const void *sourceStr); int32_t cfgLoadFromArray(SConfig *pCfg, SArray *pArgs); // SConfigPair void cfgCleanup(SConfig *pCfg); int32_t cfgGetSize(SConfig *pCfg); -SConfigItem *cfgGetItem(SConfig *pCfg, const char *name); +SConfigItem *cfgGetItem(SConfig *pCfg, const char *pName); int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype); int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer); + SConfigIter *cfgCreateIter(SConfig *pConf); SConfigItem *cfgNextIter(SConfigIter *pIter); void cfgDestroyIter(SConfigIter *pIter); +void cfgLock(SConfig *pCfg); +void cfgUnLock(SConfig *pCfg); // clang-format off int32_t cfgAddBool(SConfig *pCfg, const char *name, bool defaultVal, int8_t scope, int8_t dynScope); diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index ba96dc0adf..74c5b923f3 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -1515,15 +1515,20 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, const char *name) { return 0; } + cfgLock(pCfg); + SConfigItem *pItem = cfgGetItem(pCfg, name); if (!pItem || (pItem->dynScope & CFG_DYN_SERVER) == 0) { uError("failed to config:%s, not support", name); terrno = TSDB_CODE_INVALID_CFG; + + cfgUnLock(pCfg); return -1; } if (strncasecmp(name, "debugFlag", 9) == 0) { taosSetAllDebugFlag(pCfg, pItem->i32); + cfgUnLock(pCfg); return 0; } @@ -1580,17 +1585,21 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, const char *name) { } } + cfgUnLock(pCfg); return terrno == TSDB_CODE_SUCCESS ? 0 : -1; } -// todo fix race condition caused by update of config, pItem->str may be removed static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) { terrno = TSDB_CODE_SUCCESS; + cfgLock(pCfg); + SConfigItem *pItem = cfgGetItem(pCfg, name); if ((pItem == NULL) || (pItem->dynScope & CFG_DYN_CLIENT) == 0) { uError("failed to config:%s, not support", name); terrno = TSDB_CODE_INVALID_CFG; + + cfgUnLock(pCfg); return -1; } @@ -1728,6 +1737,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) { matched = true; } else if (strcasecmp("slowLogScope", name) == 0) { if (taosSetSlowLogScope(pItem->str)) { + cfgUnLock(pCfg); return -1; } uInfo("%s set to %s", name, pItem->str); @@ -1747,6 +1757,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) { taosExpandDir(tsTempDir, tsTempDir, PATH_MAX); if (taosMulMkDir(tsTempDir) != 0) { uError("failed to create tempDir:%s since %s", tsTempDir, terrstr()); + cfgUnLock(pCfg); return -1; } matched = true; @@ -1802,6 +1813,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) { } _out: + cfgUnLock(pCfg); return terrno == TSDB_CODE_SUCCESS ? 0 : -1; } @@ -1844,6 +1856,8 @@ static void taosSetAllDebugFlag(SConfig *pCfg, int32_t flag) { return; } + cfgLock(pCfg); + SArray *noNeedToSetVars = NULL; SConfigItem *pItem = cfgGetItem(pCfg, "debugFlag"); if (pItem != NULL) { @@ -1878,7 +1892,11 @@ static void taosSetAllDebugFlag(SConfig *pCfg, int32_t flag) { taosArrayClear(noNeedToSetVars); // reset array uInfo("all debug flag are set to %d", flag); - if (terrno == TSDB_CODE_CFG_NOT_FOUND) terrno = TSDB_CODE_SUCCESS; // ignore not exist + if (terrno == TSDB_CODE_CFG_NOT_FOUND) { + terrno = TSDB_CODE_SUCCESS; // ignore not exist + } + + cfgUnLock(pCfg); } int8_t taosGranted(int8_t type) { diff --git a/source/util/src/tconfig.c b/source/util/src/tconfig.c index b1d9403a9d..1461861f35 100644 --- a/source/util/src/tconfig.c +++ b/source/util/src/tconfig.c @@ -88,7 +88,7 @@ int32_t cfgLoadFromArray(SConfig *pCfg, SArray *pArgs) { return 0; } -static void cfgFreeItem(SConfigItem *pItem) { +void cfgItemFreeVal(SConfigItem *pItem) { if (pItem->dtype == CFG_DTYPE_STRING || pItem->dtype == CFG_DTYPE_DIR || pItem->dtype == CFG_DTYPE_LOCALE || pItem->dtype == CFG_DTYPE_CHARSET || pItem->dtype == CFG_DTYPE_TIMEZONE) { taosMemoryFreeClear(pItem->str); @@ -100,23 +100,26 @@ static void cfgFreeItem(SConfigItem *pItem) { } void cfgCleanup(SConfig *pCfg) { - if (pCfg != NULL) { - int32_t size = taosArrayGetSize(pCfg->array); - for (int32_t i = 0; i < size; ++i) { - SConfigItem *pItem = taosArrayGet(pCfg->array, i); - cfgFreeItem(pItem); - taosMemoryFreeClear(pItem->name); - } - taosArrayDestroy(pCfg->array); - taosThreadMutexDestroy(&pCfg->lock); - taosMemoryFree(pCfg); + if (pCfg == NULL) { + return; } + + int32_t size = taosArrayGetSize(pCfg->array); + for (int32_t i = 0; i < size; ++i) { + SConfigItem *pItem = taosArrayGet(pCfg->array, i); + cfgItemFreeVal(pItem); + taosMemoryFreeClear(pItem->name); + } + + taosArrayDestroy(pCfg->array); + taosThreadMutexDestroy(&pCfg->lock); + taosMemoryFree(pCfg); } int32_t cfgGetSize(SConfig *pCfg) { return taosArrayGetSize(pCfg->array); } static int32_t cfgCheckAndSetConf(SConfigItem *pItem, const char *conf) { - cfgFreeItem(pItem); + cfgItemFreeVal(pItem); ASSERT(pItem->str == NULL); pItem->str = taosStrdup(conf); @@ -257,13 +260,21 @@ static int32_t cfgSetTimezone(SConfigItem *pItem, const char *value, ECfgSrcType static int32_t cfgSetTfsItem(SConfig *pCfg, const char *name, const char *value, const char *level, const char *primary, ECfgSrcType stype) { + taosThreadMutexLock(&pCfg->lock); + SConfigItem *pItem = cfgGetItem(pCfg, name); - if (pItem == NULL) return -1; + if (pItem == NULL) { + taosThreadMutexUnlock(&pCfg->lock); + + return -1; + } if (pItem->array == NULL) { pItem->array = taosArrayInit(16, sizeof(SDiskCfg)); if (pItem->array == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; + taosThreadMutexUnlock(&pCfg->lock); + return -1; } } @@ -275,10 +286,14 @@ static int32_t cfgSetTfsItem(SConfig *pCfg, const char *name, const char *value, void *ret = taosArrayPush(pItem->array, &cfg); if (ret == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; + taosThreadMutexUnlock(&pCfg->lock); + return -1; } pItem->stype = stype; + taosThreadMutexUnlock(&pCfg->lock); + return 0; } @@ -312,15 +327,16 @@ static int32_t cfgUpdateDebugFlagItem(SConfig *pCfg, const char *name, bool rese int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype) { // GRANT_CFG_SET; - int32_t code = 0; + int32_t code = 0; + taosThreadMutexLock(&pCfg->lock); + SConfigItem *pItem = cfgGetItem(pCfg, name); if (pItem == NULL) { terrno = TSDB_CODE_CFG_NOT_FOUND; + taosThreadMutexUnlock(&pCfg->lock); return -1; } - taosThreadMutexLock(&pCfg->lock); - switch (pItem->dtype) { case CFG_DTYPE_BOOL: { code = cfgSetBool(pItem, value, stype); @@ -369,12 +385,12 @@ int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcTy return code; } -SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) { +SConfigItem *cfgGetItem(SConfig *pCfg, const char *pName) { if (pCfg == NULL) return NULL; int32_t size = taosArrayGetSize(pCfg->array); for (int32_t i = 0; i < size; ++i) { SConfigItem *pItem = taosArrayGet(pCfg->array, i); - if (strcasecmp(pItem->name, name) == 0) { + if (strcasecmp(pItem->name, pName) == 0) { return pItem; } } @@ -383,9 +399,23 @@ SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) { return NULL; } +void cfgLock(SConfig *pCfg) { + if (pCfg == NULL) { + return; + } + + taosThreadMutexLock(&pCfg->lock); +} + +void cfgUnLock(SConfig *pCfg) { + taosThreadMutexUnlock(&pCfg->lock); +} + int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer) { ECfgDynType dynType = isServer ? CFG_DYN_SERVER : CFG_DYN_CLIENT; + cfgLock(pCfg); + SConfigItem *pItem = cfgGetItem(pCfg, name); if (!pItem || (pItem->dynScope & dynType) == 0) { uError("failed to config:%s, not support update this config", name); @@ -439,6 +469,7 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p default: break; } + return 0; } @@ -1037,18 +1068,18 @@ int32_t cfgLoadFromCfgFile(SConfig *pConfig, const char *filepath) { paGetToken(name + olen + 1, &value, &vlen); if (vlen == 0) continue; value[vlen] = 0; - + if (strcasecmp(name, "encryptScope") == 0) { - char* tmp = NULL; + char *tmp = NULL; int32_t len = 0; - char newValue[1024] = {0}; + char newValue[1024] = {0}; strcpy(newValue, value); - + int32_t count = 1; - while(vlen < 1024){ + while (vlen < 1024) { paGetToken(value + vlen + 1 * count, &tmp, &len); - if(len == 0) break; + if (len == 0) break; tmp[len] = 0; strcpy(newValue + vlen, tmp); vlen += len; @@ -1057,8 +1088,7 @@ int32_t cfgLoadFromCfgFile(SConfig *pConfig, const char *filepath) { code = cfgSetItem(pConfig, name, newValue, CFG_STYPE_CFG_FILE); if (code != 0 && terrno != TSDB_CODE_CFG_NOT_FOUND) break; - } - else{ + } else { paGetToken(value + vlen + 1, &value2, &vlen2); if (vlen2 != 0) { value2[vlen2] = 0;