fix(util): fix race condition.

This commit is contained in:
Haojun Liao 2024-04-25 13:58:02 +08:00
parent b698b8be96
commit c7806ebca2
10 changed files with 221 additions and 198 deletions

View File

@ -15,7 +15,7 @@
#ifndef _TD_COMMON_DEF_H_ #ifndef _TD_COMMON_DEF_H_
#define _TD_COMMON_DEF_H_ #define _TD_COMMON_DEF_H_
// #include "taosdef.h"
#include "tarray.h" #include "tarray.h"
#include "tmsg.h" #include "tmsg.h"
#include "tvariant.h" #include "tvariant.h"
@ -412,6 +412,7 @@ typedef struct STUidTagInfo {
#define UD_TAG_COLUMN_INDEX 2 #define UD_TAG_COLUMN_INDEX 2
int32_t taosGenCrashJsonMsg(int signum, char** pMsg, int64_t clusterId, int64_t startTime); int32_t taosGenCrashJsonMsg(int signum, char** pMsg, int64_t clusterId, int64_t startTime);
int32_t dumpConfToDataBlock(SSDataBlock* pBlock, int32_t startCol);
#define TSMA_RES_STB_POSTFIX "_tsma_res_stb_" #define TSMA_RES_STB_POSTFIX "_tsma_res_stb_"
#define MD5_OUTPUT_LEN 32 #define MD5_OUTPUT_LEN 32

View File

@ -260,7 +260,7 @@ int32_t taosInitCfg(const char *cfgDir, const char **envCmd, const char *envFile
bool tsc); bool tsc);
void taosCleanupCfg(); void taosCleanupCfg();
int32_t taosCfgDynamicOptions(SConfig *pCfg, char *name, bool forServer); int32_t taosCfgDynamicOptions(SConfig *pCfg, const char *name, bool forServer);
struct SConfig *taosGetCfg(); struct SConfig *taosGetCfg();

View File

@ -98,34 +98,32 @@ typedef struct {
const char *value; const char *value;
} SConfigPair; } SConfigPair;
typedef struct SConfig { typedef struct SConfig SConfig;
ECfgSrcType stype; typedef struct SConfigIter SConfigIter;
SArray *array;
} SConfig;
SConfig *cfgInit(); SConfig *cfgInit();
int32_t cfgLoad(SConfig *pCfg, ECfgSrcType cfgType, const void *sourceStr); 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 *name);
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);
SConfigItem *cfgNextIter(SConfigIter *pIter);
void cfgDestroyIter(SConfigIter *pIter);
// 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);
int32_t cfgAddInt32(SConfig *pCfg, const char *name, int32_t defaultVal, int64_t minval, int64_t maxval, int8_t scope, int32_t cfgAddInt32(SConfig *pCfg, const char *name, int32_t defaultVal, int64_t minval, int64_t maxval, int8_t scope, int8_t dynScope);
int8_t dynScope); int32_t cfgAddInt64(SConfig *pCfg, const char *name, int64_t defaultVal, int64_t minval, int64_t maxval, int8_t scope, int8_t dynScope);
int32_t cfgAddInt64(SConfig *pCfg, const char *name, int64_t defaultVal, int64_t minval, int64_t maxval, int8_t scope, int32_t cfgAddFloat(SConfig *pCfg, const char *name, float defaultVal, float minval, float maxval, int8_t scope, int8_t dynScope);
int8_t dynScope);
int32_t cfgAddFloat(SConfig *pCfg, const char *name, float defaultVal, float minval, float maxval, int8_t scope,
int8_t dynScope);
int32_t cfgAddString(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope); int32_t cfgAddString(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope);
int32_t cfgAddDir(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope); int32_t cfgAddDir(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope);
int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope); int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope);
int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope); int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope);
int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope); int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope);
// clang-format on
const char *cfgStypeStr(ECfgSrcType type); const char *cfgStypeStr(ECfgSrcType type);
const char *cfgDtypeStr(ECfgDataType type); const char *cfgDtypeStr(ECfgDataType type);

View File

@ -770,6 +770,32 @@ int taos_init() {
return tscInitRes; return tscInitRes;
} }
const char* getCfgName(TSDB_OPTION option) {
const char* name = NULL;
switch (option) {
case TSDB_OPTION_SHELL_ACTIVITY_TIMER:
name = "shellActivityTimer";
break;
case TSDB_OPTION_LOCALE:
name = "locale";
break;
case TSDB_OPTION_CHARSET:
name = "charset";
break;
case TSDB_OPTION_TIMEZONE:
name = "timezone";
break;
case TSDB_OPTION_USE_ADAPTER:
name = "useAdapter";
break;
default:
break;
}
return name;
}
int taos_options_imp(TSDB_OPTION option, const char *str) { int taos_options_imp(TSDB_OPTION option, const char *str) {
if (option == TSDB_OPTION_CONFIGDIR) { if (option == TSDB_OPTION_CONFIGDIR) {
#ifndef WINDOWS #ifndef WINDOWS
@ -799,39 +825,26 @@ int taos_options_imp(TSDB_OPTION option, const char *str) {
SConfig *pCfg = taosGetCfg(); SConfig *pCfg = taosGetCfg();
SConfigItem *pItem = NULL; SConfigItem *pItem = NULL;
const char *name = getCfgName(option);
switch (option) { if (name == NULL) {
case TSDB_OPTION_SHELL_ACTIVITY_TIMER: tscError("Invalid option %d", option);
pItem = cfgGetItem(pCfg, "shellActivityTimer"); return -1;
break;
case TSDB_OPTION_LOCALE:
pItem = cfgGetItem(pCfg, "locale");
break;
case TSDB_OPTION_CHARSET:
pItem = cfgGetItem(pCfg, "charset");
break;
case TSDB_OPTION_TIMEZONE:
pItem = cfgGetItem(pCfg, "timezone");
break;
case TSDB_OPTION_USE_ADAPTER:
pItem = cfgGetItem(pCfg, "useAdapter");
break;
default:
break;
} }
pItem = cfgGetItem(pCfg, name);
if (pItem == NULL) { if (pItem == NULL) {
tscError("Invalid option %d", option); tscError("Invalid option %d", option);
return -1; return -1;
} }
int code = cfgSetItem(pCfg, pItem->name, str, CFG_STYPE_TAOS_OPTIONS); int code = cfgSetItem(pCfg, name, str, CFG_STYPE_TAOS_OPTIONS);
if (code != 0) { if (code != 0) {
tscError("failed to set cfg:%s to %s since %s", pItem->name, str, terrstr()); tscError("failed to set cfg:%s to %s since %s", name, str, terrstr());
} else { } else {
tscInfo("set cfg:%s to %s", pItem->name, str); tscInfo("set cfg:%s to %s", name, str);
if (TSDB_OPTION_SHELL_ACTIVITY_TIMER == option || TSDB_OPTION_USE_ADAPTER == option) { if (TSDB_OPTION_SHELL_ACTIVITY_TIMER == option || TSDB_OPTION_USE_ADAPTER == option) {
code = taosCfgDynamicOptions(pCfg, pItem->name, false); code = taosCfgDynamicOptions(pCfg, name, false);
} }
} }

View File

@ -827,10 +827,14 @@ TEST(clientCase, projection_query_tables) {
// } // }
// taos_free_result(pRes); // taos_free_result(pRes);
TAOS_RES* pRes = taos_query(pConn, "use test"); TAOS_RES* pRes = taos_query(pConn, "use cache_1");
taos_free_result(pRes); taos_free_result(pRes);
pRes = taos_query(pConn, "create table st2 (ts timestamp, k int primary key, j varchar(1000)) tags(a int)"); pRes = taos_query(pConn, "select last(ts), ts from cache_1.t1");
// pRes = taos_query(pConn, "select last(ts), ts from cache_1.no_pk_t1");
if (taos_errno(pRes) != 0) {
printf("failed to exec query, %s\n", taos_errstr(pRes));
}
taos_free_result(pRes); taos_free_result(pRes);
// pRes = taos_query(pConn, "create stream stream_1 trigger at_once fill_history 1 ignore expired 0 into str_res1 as select _wstart as ts, count(*) from stable_1 interval(10s);"); // pRes = taos_query(pConn, "create stream stream_1 trigger at_once fill_history 1 ignore expired 0 into str_res1 as select _wstart as ts, count(*) from stable_1 interval(10s);");

View File

@ -1032,7 +1032,7 @@ static void taosSetServerLogCfg(SConfig *pCfg) {
sndDebugFlag = cfgGetItem(pCfg, "sndDebugFlag")->i32; sndDebugFlag = cfgGetItem(pCfg, "sndDebugFlag")->i32;
} }
static int32_t taosSetSlowLogScope(char *pScope) { static int32_t taosSetSlowLogScope(const char *pScope) {
if (NULL == pScope || 0 == strlen(pScope)) { if (NULL == pScope || 0 == strlen(pScope)) {
tsSlowLogScope = SLOW_LOG_TYPE_ALL; tsSlowLogScope = SLOW_LOG_TYPE_ALL;
return 0; return 0;
@ -1505,7 +1505,7 @@ static int32_t taosCfgSetOption(OptionNameAndVar *pOptions, int32_t optionSize,
return terrno == TSDB_CODE_SUCCESS ? 0 : -1; return terrno == TSDB_CODE_SUCCESS ? 0 : -1;
} }
static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, char *name) { static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, const char *name) {
terrno = TSDB_CODE_SUCCESS; terrno = TSDB_CODE_SUCCESS;
if (strcasecmp(name, "resetlog") == 0) { if (strcasecmp(name, "resetlog") == 0) {
@ -1583,11 +1583,12 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, char *name) {
return terrno == TSDB_CODE_SUCCESS ? 0 : -1; return terrno == TSDB_CODE_SUCCESS ? 0 : -1;
} }
static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, char *name) { // 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; terrno = TSDB_CODE_SUCCESS;
SConfigItem *pItem = cfgGetItem(pCfg, name); SConfigItem *pItem = cfgGetItem(pCfg, name);
if (!pItem || (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;
return -1; return -1;
@ -1598,6 +1599,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, char *name) {
int32_t len = strlen(name); int32_t len = strlen(name);
char lowcaseName[CFG_NAME_MAX_LEN + 1] = {0}; char lowcaseName[CFG_NAME_MAX_LEN + 1] = {0};
strntolower(lowcaseName, name, TMIN(CFG_NAME_MAX_LEN, len)); strntolower(lowcaseName, name, TMIN(CFG_NAME_MAX_LEN, len));
switch (lowcaseName[0]) { switch (lowcaseName[0]) {
case 'd': { case 'd': {
if (strcasecmp("debugFlag", name) == 0) { if (strcasecmp("debugFlag", name) == 0) {
@ -1803,9 +1805,12 @@ _out:
return terrno == TSDB_CODE_SUCCESS ? 0 : -1; return terrno == TSDB_CODE_SUCCESS ? 0 : -1;
} }
int32_t taosCfgDynamicOptions(SConfig *pCfg, char *name, bool forServer) { int32_t taosCfgDynamicOptions(SConfig *pCfg, const char *name, bool forServer) {
if (forServer) return taosCfgDynamicOptionsForServer(pCfg, name); if (forServer) {
return taosCfgDynamicOptionsForServer(pCfg, name);
} else {
return taosCfgDynamicOptionsForClient(pCfg, name); return taosCfgDynamicOptionsForClient(pCfg, name);
}
} }
void taosSetDebugFlag(int32_t *pFlagPtr, const char *flagName, int32_t flagVal) { void taosSetDebugFlag(int32_t *pFlagPtr, const char *flagName, int32_t flagVal) {

View File

@ -17,6 +17,8 @@
#include "tmisce.h" #include "tmisce.h"
#include "tglobal.h" #include "tglobal.h"
#include "tjson.h" #include "tjson.h"
#include "tdatablock.h"
int32_t taosGetFqdnPortFromEp(const char* ep, SEp* pEp) { int32_t taosGetFqdnPortFromEp(const char* ep, SEp* pEp) {
pEp->port = 0; pEp->port = 0;
memset(pEp->fqdn, 0, TSDB_FQDN_LEN); memset(pEp->fqdn, 0, TSDB_FQDN_LEN);
@ -97,10 +99,10 @@ void epsetSort(SEpSet* pDst) {
SEp* s = &pDst->eps[j + 1]; SEp* s = &pDst->eps[j + 1];
int cmp = strncmp(f->fqdn, s->fqdn, sizeof(f->fqdn)); int cmp = strncmp(f->fqdn, s->fqdn, sizeof(f->fqdn));
if (cmp > 0 || (cmp == 0 && f->port > s->port)) { if (cmp > 0 || (cmp == 0 && f->port > s->port)) {
SEp ep = {0}; SEp ep1 = {0};
epAssign(&ep, f); epAssign(&ep1, f);
epAssign(f, s); epAssign(f, s);
epAssign(s, &ep); epAssign(s, &ep1);
} }
} }
} }
@ -216,3 +218,43 @@ int32_t taosGenCrashJsonMsg(int signum, char** pMsg, int64_t clusterId, int64_t
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t dumpConfToDataBlock(SSDataBlock* pBlock, int32_t startCol) {
SConfig* pConf = taosGetCfg();
int32_t numOfRows = 0;
int32_t col = startCol;
SConfigItem* pItem = NULL;
blockDataEnsureCapacity(pBlock, cfgGetSize(pConf));
SConfigIter* pIter = cfgCreateIter(pConf);
while ((pItem = cfgNextIter(pIter)) != NULL) {
col = startCol;
// GRANT_CFG_SKIP;
char name[TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE] = {0};
STR_WITH_MAXSIZE_TO_VARSTR(name, pItem->name, TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE);
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, col++);
colDataSetVal(pColInfo, numOfRows, name, false);
char value[TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE] = {0};
int32_t valueLen = 0;
cfgDumpItemValue(pItem, &value[VARSTR_HEADER_SIZE], TSDB_CONFIG_VALUE_LEN, &valueLen);
varDataSetLen(value, valueLen);
pColInfo = taosArrayGet(pBlock->pDataBlock, col++);
colDataSetVal(pColInfo, numOfRows, value, false);
char scope[TSDB_CONFIG_SCOPE_LEN + VARSTR_HEADER_SIZE] = {0};
cfgDumpItemScope(pItem, &scope[VARSTR_HEADER_SIZE], TSDB_CONFIG_SCOPE_LEN, &valueLen);
varDataSetLen(scope, valueLen);
pColInfo = taosArrayGet(pBlock->pDataBlock, col++);
colDataSetVal(pColInfo, numOfRows, scope, false);
numOfRows++;
}
pBlock->info.rows = numOfRows;
cfgDestroyIter(pIter);
return TSDB_CODE_SUCCESS;
}

View File

@ -333,39 +333,10 @@ SSDataBlock *dmBuildVariablesBlock(void) {
} }
int32_t dmAppendVariablesToBlock(SSDataBlock *pBlock, int32_t dnodeId) { int32_t dmAppendVariablesToBlock(SSDataBlock *pBlock, int32_t dnodeId) {
int32_t numOfCfg = taosArrayGetSize(tsCfg->array); /*int32_t code = */dumpConfToDataBlock(pBlock, 1);
int32_t numOfRows = 0;
blockDataEnsureCapacity(pBlock, numOfCfg);
for (int32_t i = 0, c = 0; i < numOfCfg; ++i, c = 0) { SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, 0);
SConfigItem *pItem = taosArrayGet(tsCfg->array, i); colDataSetNItems(pColInfo, 0, (const char *)&dnodeId, pBlock->info.rows, false);
// GRANT_CFG_SKIP;
SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
colDataSetVal(pColInfo, i, (const char *)&dnodeId, false);
char name[TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE] = {0};
STR_WITH_MAXSIZE_TO_VARSTR(name, pItem->name, TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE);
pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
colDataSetVal(pColInfo, i, name, false);
char value[TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE] = {0};
int32_t valueLen = 0;
cfgDumpItemValue(pItem, &value[VARSTR_HEADER_SIZE], TSDB_CONFIG_VALUE_LEN, &valueLen);
varDataSetLen(value, valueLen);
pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
colDataSetVal(pColInfo, i, value, false);
char scope[TSDB_CONFIG_SCOPE_LEN + VARSTR_HEADER_SIZE] = {0};
cfgDumpItemScope(pItem, &scope[VARSTR_HEADER_SIZE], TSDB_CONFIG_SCOPE_LEN, &valueLen);
varDataSetLen(scope, valueLen);
pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
colDataSetVal(pColInfo, i, scope, false);
numOfRows++;
}
pBlock->info.rows = numOfRows;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }

View File

@ -955,46 +955,11 @@ static int32_t buildLocalVariablesResultDataBlock(SSDataBlock** pOutput) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t setLocalVariablesResultIntoDataBlock(SSDataBlock* pBlock) {
int32_t numOfCfg = taosArrayGetSize(tsCfg->array);
int32_t numOfRows = 0;
blockDataEnsureCapacity(pBlock, numOfCfg);
for (int32_t i = 0, c = 0; i < numOfCfg; ++i, c = 0) {
SConfigItem* pItem = taosArrayGet(tsCfg->array, i);
// GRANT_CFG_SKIP;
char name[TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE] = {0};
STR_WITH_MAXSIZE_TO_VARSTR(name, pItem->name, TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE);
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
colDataSetVal(pColInfo, i, name, false);
char value[TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE] = {0};
int32_t valueLen = 0;
cfgDumpItemValue(pItem, &value[VARSTR_HEADER_SIZE], TSDB_CONFIG_VALUE_LEN, &valueLen);
varDataSetLen(value, valueLen);
pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
colDataSetVal(pColInfo, i, value, false);
char scope[TSDB_CONFIG_SCOPE_LEN + VARSTR_HEADER_SIZE] = {0};
cfgDumpItemScope(pItem, &scope[VARSTR_HEADER_SIZE], TSDB_CONFIG_SCOPE_LEN, &valueLen);
varDataSetLen(scope, valueLen);
pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
colDataSetVal(pColInfo, i, scope, false);
numOfRows++;
}
pBlock->info.rows = numOfRows;
return TSDB_CODE_SUCCESS;
}
static int32_t execShowLocalVariables(SRetrieveTableRsp** pRsp) { static int32_t execShowLocalVariables(SRetrieveTableRsp** pRsp) {
SSDataBlock* pBlock = NULL; SSDataBlock* pBlock = NULL;
int32_t code = buildLocalVariablesResultDataBlock(&pBlock); int32_t code = buildLocalVariablesResultDataBlock(&pBlock);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = setLocalVariablesResultIntoDataBlock(pBlock); code = dumpConfToDataBlock(pBlock, 0);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = buildRetrieveTableRsp(pBlock, SHOW_LOCAL_VARIABLES_RESULT_COLS, pRsp); code = buildRetrieveTableRsp(pBlock, SHOW_LOCAL_VARIABLES_RESULT_COLS, pRsp);

View File

@ -27,12 +27,17 @@
#define CFG_NAME_PRINT_LEN 24 #define CFG_NAME_PRINT_LEN 24
#define CFG_SRC_PRINT_LEN 12 #define CFG_SRC_PRINT_LEN 12
struct SConfig {
ECfgSrcType stype;
SArray *array;
TdThreadMutex lock;
};
int32_t cfgLoadFromCfgFile(SConfig *pConfig, const char *filepath); int32_t cfgLoadFromCfgFile(SConfig *pConfig, const char *filepath);
int32_t cfgLoadFromEnvFile(SConfig *pConfig, const char *filepath); int32_t cfgLoadFromEnvFile(SConfig *pConfig, const char *envFile);
int32_t cfgLoadFromEnvVar(SConfig *pConfig); int32_t cfgLoadFromEnvVar(SConfig *pConfig);
int32_t cfgLoadFromEnvCmd(SConfig *pConfig, const char **envCmd); int32_t cfgLoadFromEnvCmd(SConfig *pConfig, const char **envCmd);
int32_t cfgLoadFromApollUrl(SConfig *pConfig, const char *url); int32_t cfgLoadFromApollUrl(SConfig *pConfig, const char *url);
int32_t cfgSetItem(SConfig *pConfig, const char *name, const char *value, ECfgSrcType stype);
extern char **environ; extern char **environ;
@ -50,6 +55,7 @@ SConfig *cfgInit() {
return NULL; return NULL;
} }
taosThreadMutexInit(&pCfg->lock, NULL);
return pCfg; return pCfg;
} }
@ -87,9 +93,9 @@ static void cfgFreeItem(SConfigItem *pItem) {
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);
} }
if (pItem->array) { if (pItem->array) {
taosArrayDestroy(pItem->array); pItem->array = taosArrayDestroy(pItem->array);
pItem->array = NULL;
} }
} }
@ -102,37 +108,18 @@ void cfgCleanup(SConfig *pCfg) {
taosMemoryFreeClear(pItem->name); taosMemoryFreeClear(pItem->name);
} }
taosArrayDestroy(pCfg->array); taosArrayDestroy(pCfg->array);
taosThreadMutexDestroy(&pCfg->lock);
taosMemoryFree(pCfg); taosMemoryFree(pCfg);
} }
} }
int32_t cfgGetSize(SConfig *pCfg) { return taosArrayGetSize(pCfg->array); } int32_t cfgGetSize(SConfig *pCfg) { return taosArrayGetSize(pCfg->array); }
static int32_t cfgCheckAndSetTimezone(SConfigItem *pItem, const char *timezone) { static int32_t cfgCheckAndSetConf(SConfigItem *pItem, const char *conf) {
cfgFreeItem(pItem); cfgFreeItem(pItem);
pItem->str = taosStrdup(timezone); ASSERT(pItem->str == NULL);
if (pItem->str == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return -1;
}
return 0; pItem->str = taosStrdup(conf);
}
static int32_t cfgCheckAndSetCharset(SConfigItem *pItem, const char *charset) {
cfgFreeItem(pItem);
pItem->str = taosStrdup(charset);
if (pItem->str == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return -1;
}
return 0;
}
static int32_t cfgCheckAndSetLocale(SConfigItem *pItem, const char *locale) {
cfgFreeItem(pItem);
pItem->str = taosStrdup(locale);
if (pItem->str == NULL) { if (pItem->str == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY; terrno = TSDB_CODE_OUT_OF_MEMORY;
return -1; return -1;
@ -229,7 +216,7 @@ static int32_t cfgSetString(SConfigItem *pItem, const char *value, ECfgSrcType s
return -1; return -1;
} }
taosMemoryFree(pItem->str); taosMemoryFreeClear(pItem->str);
pItem->str = tmp; pItem->str = tmp;
pItem->stype = stype; pItem->stype = stype;
return 0; return 0;
@ -246,20 +233,8 @@ static int32_t cfgSetDir(SConfigItem *pItem, const char *value, ECfgSrcType styp
return 0; return 0;
} }
static int32_t cfgSetLocale(SConfigItem *pItem, const char *value, ECfgSrcType stype) { static int32_t doSetConf(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
if (cfgCheckAndSetLocale(pItem, value) != 0) { if (cfgCheckAndSetConf(pItem, value) != 0) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s", pItem->name, cfgDtypeStr(pItem->dtype),
cfgStypeStr(stype), value, terrstr());
return -1;
}
pItem->stype = stype;
return 0;
}
static int32_t cfgSetCharset(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
if (cfgCheckAndSetCharset(pItem, value) != 0) {
terrno = TSDB_CODE_OUT_OF_MEMORY; terrno = TSDB_CODE_OUT_OF_MEMORY;
uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s", pItem->name, cfgDtypeStr(pItem->dtype), uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s", pItem->name, cfgDtypeStr(pItem->dtype),
cfgStypeStr(stype), value, terrstr()); cfgStypeStr(stype), value, terrstr());
@ -271,18 +246,13 @@ static int32_t cfgSetCharset(SConfigItem *pItem, const char *value, ECfgSrcType
} }
static int32_t cfgSetTimezone(SConfigItem *pItem, const char *value, ECfgSrcType stype) { static int32_t cfgSetTimezone(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
if (cfgCheckAndSetTimezone(pItem, value) != 0) { int32_t code = doSetConf(pItem, value, stype);
terrno = TSDB_CODE_OUT_OF_MEMORY; if (code != TSDB_CODE_SUCCESS) {
uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s", pItem->name, cfgDtypeStr(pItem->dtype), return code;
cfgStypeStr(stype), value, terrstr());
return -1;
} }
pItem->stype = stype;
// apply new timezone
osSetTimezone(value); osSetTimezone(value);
return code;
return 0;
} }
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,
@ -342,40 +312,62 @@ 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;
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;
return -1; return -1;
} }
taosThreadMutexLock(&pCfg->lock);
switch (pItem->dtype) { switch (pItem->dtype) {
case CFG_DTYPE_BOOL: case CFG_DTYPE_BOOL: {
return cfgSetBool(pItem, value, stype); code = cfgSetBool(pItem, value, stype);
case CFG_DTYPE_INT32: break;
return cfgSetInt32(pItem, value, stype); }
case CFG_DTYPE_INT64: case CFG_DTYPE_INT32: {
return cfgSetInt64(pItem, value, stype); code = cfgSetInt32(pItem, value, stype);
break;
}
case CFG_DTYPE_INT64: {
code = cfgSetInt64(pItem, value, stype);
break;
}
case CFG_DTYPE_FLOAT: case CFG_DTYPE_FLOAT:
case CFG_DTYPE_DOUBLE: case CFG_DTYPE_DOUBLE: {
return cfgSetFloat(pItem, value, stype); code = cfgSetFloat(pItem, value, stype);
case CFG_DTYPE_STRING: break;
return cfgSetString(pItem, value, stype); }
case CFG_DTYPE_DIR: case CFG_DTYPE_STRING: {
return cfgSetDir(pItem, value, stype); code = cfgSetString(pItem, value, stype);
case CFG_DTYPE_TIMEZONE: break;
return cfgSetTimezone(pItem, value, stype); }
case CFG_DTYPE_CHARSET: case CFG_DTYPE_DIR: {
return cfgSetCharset(pItem, value, stype); code = cfgSetDir(pItem, value, stype);
case CFG_DTYPE_LOCALE: break;
return cfgSetLocale(pItem, value, stype); }
case CFG_DTYPE_TIMEZONE: {
code = cfgSetTimezone(pItem, value, stype);
break;
}
case CFG_DTYPE_CHARSET: {
code = doSetConf(pItem, value, stype);
break;
}
case CFG_DTYPE_LOCALE: {
code = doSetConf(pItem, value, stype);
break;
}
case CFG_DTYPE_NONE: case CFG_DTYPE_NONE:
default: default:
break; break;
} }
_err_out: taosThreadMutexUnlock(&pCfg->lock);
terrno = TSDB_CODE_INVALID_CFG; terrno = TSDB_CODE_INVALID_CFG;
return -1; return code;
} }
SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) { SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) {
@ -388,16 +380,16 @@ SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) {
} }
} }
// uError("name:%s, cfg not found", name);
terrno = TSDB_CODE_CFG_NOT_FOUND; terrno = TSDB_CODE_CFG_NOT_FOUND;
return NULL; return NULL;
} }
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;
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", name); uError("failed to config:%s, not support update this config", name);
terrno = TSDB_CODE_INVALID_CFG; terrno = TSDB_CODE_INVALID_CFG;
return -1; return -1;
} }
@ -459,7 +451,7 @@ static int32_t cfgAddItem(SConfig *pCfg, SConfigItem *pItem, const char *name) {
return -1; return -1;
} }
int size = pCfg->array->size; int32_t size = taosArrayGetSize(pCfg->array);
for (int32_t i = 0; i < size; ++i) { for (int32_t i = 0; i < size; ++i) {
SConfigItem *existItem = taosArrayGet(pCfg->array, i); SConfigItem *existItem = taosArrayGet(pCfg->array, i);
if (existItem != NULL && strcmp(existItem->name, pItem->name) == 0) { if (existItem != NULL && strcmp(existItem->name, pItem->name) == 0) {
@ -559,7 +551,7 @@ int32_t cfgAddDir(SConfig *pCfg, const char *name, const char *defaultVal, int8_
int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope) { int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope) {
SConfigItem item = {.dtype = CFG_DTYPE_LOCALE, .scope = scope, .dynScope = dynScope}; SConfigItem item = {.dtype = CFG_DTYPE_LOCALE, .scope = scope, .dynScope = dynScope};
if (cfgCheckAndSetLocale(&item, defaultVal) != 0) { if (cfgCheckAndSetConf(&item, defaultVal) != 0) {
return -1; return -1;
} }
@ -568,7 +560,7 @@ int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal, in
int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope) { int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope) {
SConfigItem item = {.dtype = CFG_DTYPE_CHARSET, .scope = scope, .dynScope = dynScope}; SConfigItem item = {.dtype = CFG_DTYPE_CHARSET, .scope = scope, .dynScope = dynScope};
if (cfgCheckAndSetCharset(&item, defaultVal) != 0) { if (cfgCheckAndSetConf(&item, defaultVal) != 0) {
return -1; return -1;
} }
@ -577,7 +569,7 @@ int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal, i
int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope) { int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope) {
SConfigItem item = {.dtype = CFG_DTYPE_TIMEZONE, .scope = scope, .dynScope = dynScope}; SConfigItem item = {.dtype = CFG_DTYPE_TIMEZONE, .scope = scope, .dynScope = dynScope};
if (cfgCheckAndSetTimezone(&item, defaultVal) != 0) { if (cfgCheckAndSetConf(&item, defaultVal) != 0) {
return -1; return -1;
} }
@ -1356,3 +1348,35 @@ int32_t cfgGetApollUrl(const char **envCmd, const char *envFile, char *apolloUrl
uInfo("fail get apollo url from cmd env file"); uInfo("fail get apollo url from cmd env file");
return -1; return -1;
} }
struct SConfigIter {
int32_t index;
SConfig *pConf;
};
SConfigIter *cfgCreateIter(SConfig *pConf) {
SConfigIter* pIter = taosMemoryCalloc(1, sizeof(SConfigIter));
if (pIter == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
pIter->pConf = pConf;
return pIter;
}
SConfigItem *cfgNextIter(SConfigIter* pIter) {
if (pIter->index < cfgGetSize(pIter->pConf)) {
return taosArrayGet(pIter->pConf->array, pIter->index++);
}
return NULL;
}
void cfgDestroyIter(SConfigIter *pIter) {
if (pIter == NULL) {
return;
}
taosMemoryFree(pIter);
}