fix(util): fix race condition.

This commit is contained in:
Haojun Liao 2024-04-26 19:12:19 +08:00
parent 2d1e9ba631
commit faa87e13b0
3 changed files with 80 additions and 29 deletions

View File

@ -106,12 +106,15 @@ int32_t cfgLoad(SConfig *pCfg, ECfgSrcType cfgType, const void *sourceStr);
int32_t cfgLoadFromArray(SConfig *pCfg, SArray *pArgs); // SConfigPair int32_t cfgLoadFromArray(SConfig *pCfg, SArray *pArgs); // SConfigPair
void cfgCleanup(SConfig *pCfg); void cfgCleanup(SConfig *pCfg);
int32_t cfgGetSize(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 cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype);
int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer); int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer);
SConfigIter *cfgCreateIter(SConfig *pConf); SConfigIter *cfgCreateIter(SConfig *pConf);
SConfigItem *cfgNextIter(SConfigIter *pIter); SConfigItem *cfgNextIter(SConfigIter *pIter);
void cfgDestroyIter(SConfigIter *pIter); void cfgDestroyIter(SConfigIter *pIter);
void cfgLock(SConfig *pCfg);
void cfgUnLock(SConfig *pCfg);
// clang-format off // clang-format off
int32_t cfgAddBool(SConfig *pCfg, const char *name, bool defaultVal, int8_t scope, int8_t dynScope); int32_t cfgAddBool(SConfig *pCfg, const char *name, bool defaultVal, int8_t scope, int8_t dynScope);

View File

@ -1515,15 +1515,20 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, const char *name) {
return 0; return 0;
} }
cfgLock(pCfg);
SConfigItem *pItem = cfgGetItem(pCfg, name); SConfigItem *pItem = cfgGetItem(pCfg, name);
if (!pItem || (pItem->dynScope & CFG_DYN_SERVER) == 0) { if (!pItem || (pItem->dynScope & CFG_DYN_SERVER) == 0) {
uError("failed to config:%s, not support", name); uError("failed to config:%s, not support", name);
terrno = TSDB_CODE_INVALID_CFG; terrno = TSDB_CODE_INVALID_CFG;
cfgUnLock(pCfg);
return -1; return -1;
} }
if (strncasecmp(name, "debugFlag", 9) == 0) { if (strncasecmp(name, "debugFlag", 9) == 0) {
taosSetAllDebugFlag(pCfg, pItem->i32); taosSetAllDebugFlag(pCfg, pItem->i32);
cfgUnLock(pCfg);
return 0; return 0;
} }
@ -1580,17 +1585,21 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, const char *name) {
} }
} }
cfgUnLock(pCfg);
return terrno == TSDB_CODE_SUCCESS ? 0 : -1; 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) { static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
terrno = TSDB_CODE_SUCCESS; terrno = TSDB_CODE_SUCCESS;
cfgLock(pCfg);
SConfigItem *pItem = cfgGetItem(pCfg, name); SConfigItem *pItem = cfgGetItem(pCfg, name);
if ((pItem == NULL) || (pItem->dynScope & CFG_DYN_CLIENT) == 0) { if ((pItem == NULL) || (pItem->dynScope & CFG_DYN_CLIENT) == 0) {
uError("failed to config:%s, not support", name); uError("failed to config:%s, not support", name);
terrno = TSDB_CODE_INVALID_CFG; terrno = TSDB_CODE_INVALID_CFG;
cfgUnLock(pCfg);
return -1; return -1;
} }
@ -1728,6 +1737,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
matched = true; matched = true;
} else if (strcasecmp("slowLogScope", name) == 0) { } else if (strcasecmp("slowLogScope", name) == 0) {
if (taosSetSlowLogScope(pItem->str)) { if (taosSetSlowLogScope(pItem->str)) {
cfgUnLock(pCfg);
return -1; return -1;
} }
uInfo("%s set to %s", name, pItem->str); 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); taosExpandDir(tsTempDir, tsTempDir, PATH_MAX);
if (taosMulMkDir(tsTempDir) != 0) { if (taosMulMkDir(tsTempDir) != 0) {
uError("failed to create tempDir:%s since %s", tsTempDir, terrstr()); uError("failed to create tempDir:%s since %s", tsTempDir, terrstr());
cfgUnLock(pCfg);
return -1; return -1;
} }
matched = true; matched = true;
@ -1802,6 +1813,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
} }
_out: _out:
cfgUnLock(pCfg);
return terrno == TSDB_CODE_SUCCESS ? 0 : -1; return terrno == TSDB_CODE_SUCCESS ? 0 : -1;
} }
@ -1844,6 +1856,8 @@ static void taosSetAllDebugFlag(SConfig *pCfg, int32_t flag) {
return; return;
} }
cfgLock(pCfg);
SArray *noNeedToSetVars = NULL; SArray *noNeedToSetVars = NULL;
SConfigItem *pItem = cfgGetItem(pCfg, "debugFlag"); SConfigItem *pItem = cfgGetItem(pCfg, "debugFlag");
if (pItem != NULL) { if (pItem != NULL) {
@ -1878,7 +1892,11 @@ static void taosSetAllDebugFlag(SConfig *pCfg, int32_t flag) {
taosArrayClear(noNeedToSetVars); // reset array taosArrayClear(noNeedToSetVars); // reset array
uInfo("all debug flag are set to %d", flag); 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) { int8_t taosGranted(int8_t type) {

View File

@ -88,7 +88,7 @@ int32_t cfgLoadFromArray(SConfig *pCfg, SArray *pArgs) {
return 0; 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 || 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) { pItem->dtype == CFG_DTYPE_CHARSET || pItem->dtype == CFG_DTYPE_TIMEZONE) {
taosMemoryFreeClear(pItem->str); taosMemoryFreeClear(pItem->str);
@ -100,23 +100,26 @@ static void cfgFreeItem(SConfigItem *pItem) {
} }
void cfgCleanup(SConfig *pCfg) { void cfgCleanup(SConfig *pCfg) {
if (pCfg != NULL) { if (pCfg == NULL) {
int32_t size = taosArrayGetSize(pCfg->array); return;
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);
} }
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); } int32_t cfgGetSize(SConfig *pCfg) { return taosArrayGetSize(pCfg->array); }
static int32_t cfgCheckAndSetConf(SConfigItem *pItem, const char *conf) { static int32_t cfgCheckAndSetConf(SConfigItem *pItem, const char *conf) {
cfgFreeItem(pItem); cfgItemFreeVal(pItem);
ASSERT(pItem->str == NULL); ASSERT(pItem->str == NULL);
pItem->str = taosStrdup(conf); 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, static int32_t cfgSetTfsItem(SConfig *pCfg, const char *name, const char *value, const char *level, const char *primary,
ECfgSrcType stype) { ECfgSrcType stype) {
taosThreadMutexLock(&pCfg->lock);
SConfigItem *pItem = cfgGetItem(pCfg, name); SConfigItem *pItem = cfgGetItem(pCfg, name);
if (pItem == NULL) return -1; if (pItem == NULL) {
taosThreadMutexUnlock(&pCfg->lock);
return -1;
}
if (pItem->array == NULL) { if (pItem->array == NULL) {
pItem->array = taosArrayInit(16, sizeof(SDiskCfg)); pItem->array = taosArrayInit(16, sizeof(SDiskCfg));
if (pItem->array == NULL) { if (pItem->array == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY; terrno = TSDB_CODE_OUT_OF_MEMORY;
taosThreadMutexUnlock(&pCfg->lock);
return -1; return -1;
} }
} }
@ -275,10 +286,14 @@ static int32_t cfgSetTfsItem(SConfig *pCfg, const char *name, const char *value,
void *ret = taosArrayPush(pItem->array, &cfg); void *ret = taosArrayPush(pItem->array, &cfg);
if (ret == NULL) { if (ret == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY; terrno = TSDB_CODE_OUT_OF_MEMORY;
taosThreadMutexUnlock(&pCfg->lock);
return -1; return -1;
} }
pItem->stype = stype; pItem->stype = stype;
taosThreadMutexUnlock(&pCfg->lock);
return 0; 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) { int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype) {
// GRANT_CFG_SET; // GRANT_CFG_SET;
int32_t code = 0; int32_t code = 0;
taosThreadMutexLock(&pCfg->lock);
SConfigItem *pItem = cfgGetItem(pCfg, name); SConfigItem *pItem = cfgGetItem(pCfg, name);
if (pItem == NULL) { if (pItem == NULL) {
terrno = TSDB_CODE_CFG_NOT_FOUND; terrno = TSDB_CODE_CFG_NOT_FOUND;
taosThreadMutexUnlock(&pCfg->lock);
return -1; return -1;
} }
taosThreadMutexLock(&pCfg->lock);
switch (pItem->dtype) { switch (pItem->dtype) {
case CFG_DTYPE_BOOL: { case CFG_DTYPE_BOOL: {
code = cfgSetBool(pItem, value, stype); code = cfgSetBool(pItem, value, stype);
@ -369,12 +385,12 @@ int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcTy
return code; return code;
} }
SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) { SConfigItem *cfgGetItem(SConfig *pCfg, const char *pName) {
if (pCfg == NULL) return NULL; if (pCfg == NULL) return NULL;
int32_t size = taosArrayGetSize(pCfg->array); int32_t size = taosArrayGetSize(pCfg->array);
for (int32_t i = 0; i < size; ++i) { for (int32_t i = 0; i < size; ++i) {
SConfigItem *pItem = taosArrayGet(pCfg->array, i); SConfigItem *pItem = taosArrayGet(pCfg->array, i);
if (strcasecmp(pItem->name, name) == 0) { if (strcasecmp(pItem->name, pName) == 0) {
return pItem; return pItem;
} }
} }
@ -383,9 +399,23 @@ SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) {
return NULL; 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) { int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer) {
ECfgDynType dynType = isServer ? CFG_DYN_SERVER : CFG_DYN_CLIENT; ECfgDynType dynType = isServer ? CFG_DYN_SERVER : CFG_DYN_CLIENT;
cfgLock(pCfg);
SConfigItem *pItem = cfgGetItem(pCfg, name); SConfigItem *pItem = cfgGetItem(pCfg, name);
if (!pItem || (pItem->dynScope & dynType) == 0) { if (!pItem || (pItem->dynScope & dynType) == 0) {
uError("failed to config:%s, not support update this config", name); 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: default:
break; break;
} }
return 0; return 0;
} }
@ -1039,16 +1070,16 @@ int32_t cfgLoadFromCfgFile(SConfig *pConfig, const char *filepath) {
value[vlen] = 0; value[vlen] = 0;
if (strcasecmp(name, "encryptScope") == 0) { if (strcasecmp(name, "encryptScope") == 0) {
char* tmp = NULL; char *tmp = NULL;
int32_t len = 0; int32_t len = 0;
char newValue[1024] = {0}; char newValue[1024] = {0};
strcpy(newValue, value); strcpy(newValue, value);
int32_t count = 1; int32_t count = 1;
while(vlen < 1024){ while (vlen < 1024) {
paGetToken(value + vlen + 1 * count, &tmp, &len); paGetToken(value + vlen + 1 * count, &tmp, &len);
if(len == 0) break; if (len == 0) break;
tmp[len] = 0; tmp[len] = 0;
strcpy(newValue + vlen, tmp); strcpy(newValue + vlen, tmp);
vlen += len; vlen += len;
@ -1057,8 +1088,7 @@ int32_t cfgLoadFromCfgFile(SConfig *pConfig, const char *filepath) {
code = cfgSetItem(pConfig, name, newValue, CFG_STYPE_CFG_FILE); code = cfgSetItem(pConfig, name, newValue, CFG_STYPE_CFG_FILE);
if (code != 0 && terrno != TSDB_CODE_CFG_NOT_FOUND) break; if (code != 0 && terrno != TSDB_CODE_CFG_NOT_FOUND) break;
} } else {
else{
paGetToken(value + vlen + 1, &value2, &vlen2); paGetToken(value + vlen + 1, &value2, &vlen2);
if (vlen2 != 0) { if (vlen2 != 0) {
value2[vlen2] = 0; value2[vlen2] = 0;