Merge pull request #23513 from taosdata/feat/TS-4094
feat: add dynamic configuration
This commit is contained in:
commit
9a342efd85
|
@ -44,10 +44,6 @@ extern int32_t tsNumOfSupportVnodes;
|
|||
extern int32_t tsMaxShellConns;
|
||||
extern int32_t tsShellActivityTimer;
|
||||
extern int32_t tsCompressMsgSize;
|
||||
extern int32_t tsCompressColData;
|
||||
extern int32_t tsMaxNumOfDistinctResults;
|
||||
extern int32_t tsCompatibleModel;
|
||||
extern bool tsPrintAuth;
|
||||
extern int64_t tsTickPerMin[3];
|
||||
extern int64_t tsTickPerHour[3];
|
||||
extern int32_t tsCountAlwaysReturnValue;
|
||||
|
@ -79,9 +75,6 @@ extern int32_t tsElectInterval;
|
|||
extern int32_t tsHeartbeatInterval;
|
||||
extern int32_t tsHeartbeatTimeout;
|
||||
|
||||
// vnode
|
||||
extern int64_t tsVndCommitMaxIntervalMs;
|
||||
|
||||
// mnode
|
||||
extern int64_t tsMndSdbWriteDelta;
|
||||
extern int64_t tsMndLogRetention;
|
||||
|
@ -105,8 +98,6 @@ extern bool tsMonitorComp;
|
|||
|
||||
// audit
|
||||
extern bool tsEnableAudit;
|
||||
extern char tsAuditFqdn[];
|
||||
extern uint16_t tsAuditPort;
|
||||
extern bool tsEnableAuditCreateTable;
|
||||
|
||||
// telem
|
||||
|
|
|
@ -57,10 +57,27 @@ typedef enum {
|
|||
CFG_SCOPE_BOTH
|
||||
} ECfgScopeType;
|
||||
|
||||
typedef enum {
|
||||
CFG_DYN_NONE = 0,
|
||||
CFG_DYN_SERVER = 1,
|
||||
CFG_DYN_CLIENT = 2,
|
||||
CFG_DYN_BOTH = 3,
|
||||
#ifdef TD_ENTERPRISE
|
||||
CFG_DYN_ENT_SERVER = CFG_DYN_SERVER,
|
||||
CFG_DYN_ENT_CLIENT = CFG_DYN_CLIENT,
|
||||
CFG_DYN_ENT_BOTH = CFG_DYN_BOTH,
|
||||
#else
|
||||
CFG_DYN_ENT_SERVER = CFG_DYN_NONE,
|
||||
CFG_DYN_ENT_CLIENT = CFG_DYN_NONE,
|
||||
CFG_DYN_ENT_BOTH = CFG_DYN_NONE,
|
||||
#endif
|
||||
} ECfgDynType;
|
||||
|
||||
typedef struct SConfigItem {
|
||||
ECfgSrcType stype;
|
||||
ECfgDataType dtype;
|
||||
int8_t scope;
|
||||
int8_t dynScope;
|
||||
char *name;
|
||||
union {
|
||||
bool bval;
|
||||
|
@ -99,15 +116,20 @@ int32_t cfgGetSize(SConfig *pCfg);
|
|||
SConfigItem *cfgGetItem(SConfig *pCfg, const char *name);
|
||||
int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype);
|
||||
|
||||
int32_t cfgAddBool(SConfig *pCfg, const char *name, bool defaultVal, int8_t scope);
|
||||
int32_t cfgAddInt32(SConfig *pCfg, const char *name, int32_t defaultVal, int64_t minval, int64_t maxval, int8_t scope);
|
||||
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);
|
||||
int32_t cfgAddString(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope);
|
||||
int32_t cfgAddDir(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope);
|
||||
int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope);
|
||||
int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope);
|
||||
int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope);
|
||||
int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer);
|
||||
|
||||
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,
|
||||
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 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 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 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);
|
||||
|
||||
const char *cfgStypeStr(ECfgSrcType type);
|
||||
const char *cfgDtypeStr(ECfgDataType type);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -79,7 +79,7 @@ static void mndCancelGetNextConfig(SMnode *pMnode, void *pIter);
|
|||
static int32_t mndRetrieveDnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
|
||||
static void mndCancelGetNextDnode(SMnode *pMnode, void *pIter);
|
||||
|
||||
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pInMCfgReq, int32_t opLen, int32_t *pOutValue);
|
||||
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pInMCfgReq, int32_t optLen, int32_t *pOutValue);
|
||||
|
||||
#ifdef _GRANT
|
||||
int32_t mndUpdClusterInfo(SRpcMsg *pReq);
|
||||
|
@ -1182,15 +1182,72 @@ _OVER:
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t mndMCfg2DCfg(SMCfgDnodeReq *pMCfgReq, SDCfgDnodeReq *pDCfgReq) {
|
||||
terrno = 0;
|
||||
char *p = pMCfgReq->config;
|
||||
while (*p) {
|
||||
if (*p == ' ') {
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
size_t optLen = p - pMCfgReq->config;
|
||||
strncpy(pDCfgReq->config, pMCfgReq->config, optLen);
|
||||
pDCfgReq->config[optLen] = 0;
|
||||
|
||||
if (' ' == pMCfgReq->config[optLen]) {
|
||||
// 'key value'
|
||||
if (strlen(pMCfgReq->value) != 0) goto _err;
|
||||
strcpy(pDCfgReq->value, p + 1);
|
||||
} else {
|
||||
// 'key' 'value'
|
||||
if (strlen(pMCfgReq->value) == 0) goto _err;
|
||||
strcpy(pDCfgReq->value, pMCfgReq->value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
mError("dnode:%d, failed to config since invalid conf:%s", pMCfgReq->dnodeId, pMCfgReq->config);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t mndSendCfgDnodeReq(SMnode *pMnode, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
|
||||
int32_t code = -1;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
SDnodeObj *pDnode = NULL;
|
||||
pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
|
||||
if (pIter == NULL) break;
|
||||
|
||||
if (pDnode->id == dnodeId || dnodeId == -1 || dnodeId == 0) {
|
||||
SEpSet epSet = mndGetDnodeEpset(pDnode);
|
||||
int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, pDcfgReq);
|
||||
void *pBuf = rpcMallocCont(bufLen);
|
||||
|
||||
if (pBuf != NULL) {
|
||||
tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq);
|
||||
mInfo("dnode:%d, send config req to dnode, config:%s value:%s", dnodeId, pDcfgReq->config, pDcfgReq->value);
|
||||
SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pBuf, .contLen = bufLen};
|
||||
tmsgSendReq(&epSet, &rpcMsg);
|
||||
code = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sdbRelease(pSdb, pDnode);
|
||||
}
|
||||
|
||||
if (code == -1) {
|
||||
terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
const char *options[] = {
|
||||
"debugFlag", "dDebugFlag", "vDebugFlag", "mDebugFlag", "wDebugFlag", "sDebugFlag", "tsdbDebugFlag",
|
||||
"tqDebugFlag", "fsDebugFlag", "udfDebugFlag", "smaDebugFlag", "idxDebugFlag", "tdbDebugFlag", "tmrDebugFlag",
|
||||
"uDebugFlag", "smaDebugFlag", "rpcDebugFlag", "qDebugFlag", "metaDebugFlag", "stDebugFlag",
|
||||
};
|
||||
int32_t optionSize = tListLen(options);
|
||||
|
||||
SMCfgDnodeReq cfgReq = {0};
|
||||
if (tDeserializeSMCfgDnodeReq(pReq->pCont, pReq->contLen, &cfgReq) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
|
@ -1206,139 +1263,6 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
|||
SDCfgDnodeReq dcfgReq = {0};
|
||||
if (strcasecmp(cfgReq.config, "resetlog") == 0) {
|
||||
strcpy(dcfgReq.config, "resetlog");
|
||||
} else if (strncasecmp(cfgReq.config, "monitor", 7) == 0) {
|
||||
if (' ' != cfgReq.config[7] && 0 != cfgReq.config[7]) {
|
||||
mError("dnode:%d, failed to config monitor since invalid conf:%s", cfgReq.dnodeId, cfgReq.config);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *value = cfgReq.value;
|
||||
int32_t flag = atoi(value);
|
||||
if (flag <= 0) {
|
||||
flag = atoi(cfgReq.config + 8);
|
||||
}
|
||||
if (flag < 0 || flag > 2) {
|
||||
mError("dnode:%d, failed to config monitor since value:%d", cfgReq.dnodeId, flag);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(dcfgReq.config, "monitor");
|
||||
snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
|
||||
} else if (strncasecmp(cfgReq.config, "s3blocksize", 11) == 0) {
|
||||
int32_t optLen = strlen("s3blocksize");
|
||||
int32_t flag = -1;
|
||||
int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
|
||||
if (code < 0) return code;
|
||||
|
||||
if (flag > 1024 * 1024) {
|
||||
mError("dnode:%d, failed to config s3blocksize since value:%d. Valid range: [4, 1024 * 1024]", cfgReq.dnodeId,
|
||||
flag);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(dcfgReq.config, "s3blocksize");
|
||||
snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
|
||||
} else if (strncasecmp(cfgReq.config, "s3blockcachesize", 16) == 0) {
|
||||
int32_t optLen = strlen("s3blockcachesize");
|
||||
int32_t flag = -1;
|
||||
int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
|
||||
if (code < 0) return code;
|
||||
|
||||
if (flag < 4 || flag > 1024 * 1024) {
|
||||
mError("dnode:%d, failed to config s3BlockCacheSize since value:%d. Valid range: [4, 1024 * 1024]",
|
||||
cfgReq.dnodeId, flag);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(dcfgReq.config, "s3blockcachesize");
|
||||
snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
|
||||
} else if (strncasecmp(cfgReq.config, "s3pagecachesize", 16) == 0) {
|
||||
int32_t optLen = strlen("s3pagecachesize");
|
||||
int32_t flag = -1;
|
||||
int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
|
||||
if (code < 0) return code;
|
||||
|
||||
if (flag < 4 || flag > 1024 * 1024 * 1024) {
|
||||
mError("dnode:%d, failed to config s3PageCacheSize since value:%d. Valid range: [4, 1024 * 1024]", cfgReq.dnodeId,
|
||||
flag);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(dcfgReq.config, "s3pagecachesize");
|
||||
snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
|
||||
} else if (strncasecmp(cfgReq.config, "s3uploaddelaysec", 16) == 0) {
|
||||
int32_t optLen = strlen("s3uploaddelaysec");
|
||||
int32_t flag = -1;
|
||||
int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
|
||||
if (code < 0) return code;
|
||||
|
||||
if (flag < 600 || flag > 60 * 60 * 24 * 30) {
|
||||
mError("dnode:%d, failed to config s3UploadDelaySec since value:%d. Valid range: [600, 60 * 60 * 24 * 30]",
|
||||
cfgReq.dnodeId, flag);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(dcfgReq.config, "s3uploaddelaysec");
|
||||
snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
|
||||
} else if (strncasecmp(cfgReq.config, "ttlpushinterval", 14) == 0) {
|
||||
int32_t optLen = strlen("ttlpushinterval");
|
||||
int32_t flag = -1;
|
||||
int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
|
||||
if (code < 0) return code;
|
||||
|
||||
if (flag < 0 || flag > 100000) {
|
||||
mError("dnode:%d, failed to config ttlPushInterval since value:%d. Valid range: [0, 100000]", cfgReq.dnodeId,
|
||||
flag);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(dcfgReq.config, "ttlpushinterval");
|
||||
snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
|
||||
} else if (strncasecmp(cfgReq.config, "ttlbatchdropnum", 15) == 0) {
|
||||
int32_t optLen = strlen("ttlbatchdropnum");
|
||||
int32_t flag = -1;
|
||||
int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
|
||||
if (code < 0) return code;
|
||||
|
||||
if (flag < 0) {
|
||||
mError("dnode:%d, failed to config ttlBatchDropNum since value:%d. Valid range: [0, %d]", cfgReq.dnodeId, flag,
|
||||
INT32_MAX);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(dcfgReq.config, "ttlbatchdropnum");
|
||||
snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
|
||||
} else if (strncasecmp(cfgReq.config, "asynclog", 8) == 0) {
|
||||
int32_t optLen = strlen("asynclog");
|
||||
int32_t flag = -1;
|
||||
int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
|
||||
if (code < 0) return code;
|
||||
|
||||
if (flag < 0 || flag > 1) {
|
||||
mError("dnode:%d, failed to config asynclog since value:%d. Valid range: [0, 1]", cfgReq.dnodeId, flag);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(dcfgReq.config, "asynclog");
|
||||
snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
|
||||
#ifdef TD_ENTERPRISE
|
||||
} else if (strncasecmp(cfgReq.config, "supportvnodes", 13) == 0) {
|
||||
int32_t optLen = strlen("supportvnodes");
|
||||
|
@ -1348,9 +1272,8 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
|||
|
||||
if (flag < 0 || flag > 4096) {
|
||||
mError("dnode:%d, failed to config supportVnodes since value:%d. Valid range: [0, 4096]", cfgReq.dnodeId, flag);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||
goto _err_out;
|
||||
}
|
||||
if (flag == 0) {
|
||||
flag = tsNumOfCores * 2;
|
||||
|
@ -1365,8 +1288,7 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
|||
if (' ' != cfgReq.config[index] && 0 != cfgReq.config[index]) {
|
||||
mError("dnode:%d, failed to config activeCode since invalid conf:%s", cfgReq.dnodeId, cfgReq.config);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
goto _err_out;
|
||||
}
|
||||
int32_t vlen = strlen(cfgReq.value);
|
||||
if (vlen > 0 && ((opt == DND_ACTIVE_CODE && vlen != (TSDB_ACTIVE_KEY_LEN - 1)) ||
|
||||
|
@ -1374,9 +1296,8 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
|||
(vlen > (TSDB_CONN_ACTIVE_KEY_LEN - 1) || vlen < (TSDB_ACTIVE_KEY_LEN - 1))))) {
|
||||
mError("dnode:%d, failed to config activeCode since invalid vlen:%d. conf:%s, val:%s", cfgReq.dnodeId, vlen,
|
||||
cfgReq.config, cfgReq.value);
|
||||
terrno = TSDB_CODE_INVALID_OPTION;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
goto _err_out;
|
||||
}
|
||||
|
||||
strcpy(dcfgReq.config, opt == DND_ACTIVE_CODE ? "activeCode" : "cActiveCode");
|
||||
|
@ -1384,88 +1305,37 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
|||
|
||||
if (mndConfigDnode(pMnode, pReq, &cfgReq, opt) != 0) {
|
||||
mError("dnode:%d, failed to config activeCode since %s", cfgReq.dnodeId, terrstr());
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
goto _err_out;
|
||||
}
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
bool findOpt = false;
|
||||
for (int32_t d = 0; d < optionSize; ++d) {
|
||||
const char *optName = options[d];
|
||||
int32_t optLen = strlen(optName);
|
||||
if (strncasecmp(cfgReq.config, optName, optLen) != 0) continue;
|
||||
|
||||
if (' ' != cfgReq.config[optLen] && 0 != cfgReq.config[optLen]) {
|
||||
mError("dnode:%d, failed to config since invalid conf:%s", cfgReq.dnodeId, cfgReq.config);
|
||||
mndMCfg2DCfg(&cfgReq, &dcfgReq);
|
||||
if (strlen(dcfgReq.config) > TSDB_DNODE_CONFIG_LEN) {
|
||||
mError("dnode:%d, failed to config since config is too long", cfgReq.dnodeId);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
goto _err_out;
|
||||
}
|
||||
|
||||
const char *value = cfgReq.value;
|
||||
int32_t flag = atoi(value);
|
||||
if (flag <= 0) {
|
||||
flag = atoi(cfgReq.config + optLen + 1);
|
||||
}
|
||||
if (flag < 0 || flag > 255) {
|
||||
mError("dnode:%d, failed to config %s since value:%d", cfgReq.dnodeId, optName, flag);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tstrncpy(dcfgReq.config, optName, optLen + 1);
|
||||
snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
|
||||
findOpt = true;
|
||||
}
|
||||
|
||||
if (!findOpt) {
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
mError("dnode:%d, failed to config since %s", cfgReq.dnodeId, terrstr());
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
}
|
||||
if (cfgCheckRangeForDynUpdate(taosGetCfg(), dcfgReq.config, dcfgReq.value, true) != 0) goto _err_out;
|
||||
}
|
||||
|
||||
{ // audit
|
||||
char obj[50] = {0};
|
||||
sprintf(obj, "%d", cfgReq.dnodeId);
|
||||
|
||||
auditRecord(pReq, pMnode->clusterId, "alterDnode", "", obj, cfgReq.sql, cfgReq.sqlLen);
|
||||
auditRecord(pReq, pMnode->clusterId, "alterDnode", obj, "", cfgReq.sql, cfgReq.sqlLen);
|
||||
}
|
||||
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
|
||||
int32_t code = -1;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
SDnodeObj *pDnode = NULL;
|
||||
pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
|
||||
if (pIter == NULL) break;
|
||||
return mndSendCfgDnodeReq(pMnode, cfgReq.dnodeId, &dcfgReq);
|
||||
|
||||
if (pDnode->id == cfgReq.dnodeId || cfgReq.dnodeId == -1 || cfgReq.dnodeId == 0) {
|
||||
SEpSet epSet = mndGetDnodeEpset(pDnode);
|
||||
int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, &dcfgReq);
|
||||
void *pBuf = rpcMallocCont(bufLen);
|
||||
|
||||
if (pBuf != NULL) {
|
||||
tSerializeSDCfgDnodeReq(pBuf, bufLen, &dcfgReq);
|
||||
mInfo("dnode:%d, send config req to dnode, app:%p config:%s value:%s", cfgReq.dnodeId, pReq->info.ahandle,
|
||||
dcfgReq.config, dcfgReq.value);
|
||||
SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pBuf, .contLen = bufLen};
|
||||
tmsgSendReq(&epSet, &rpcMsg);
|
||||
code = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sdbRelease(pSdb, pDnode);
|
||||
}
|
||||
|
||||
if (code == -1) {
|
||||
terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
}
|
||||
return code;
|
||||
_err_out:
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) {
|
||||
|
@ -1606,16 +1476,16 @@ static void mndCancelGetNextDnode(SMnode *pMnode, void *pIter) {
|
|||
}
|
||||
|
||||
// get int32_t value from 'SMCfgDnodeReq'
|
||||
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pMCfgReq, int32_t opLen, int32_t *pOutValue) {
|
||||
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pMCfgReq, int32_t optLen, int32_t *pOutValue) {
|
||||
terrno = 0;
|
||||
if (' ' != pMCfgReq->config[opLen] && 0 != pMCfgReq->config[opLen]) {
|
||||
if (' ' != pMCfgReq->config[optLen] && 0 != pMCfgReq->config[optLen]) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
if (' ' == pMCfgReq->config[opLen]) {
|
||||
if (' ' == pMCfgReq->config[optLen]) {
|
||||
// 'key value'
|
||||
if (strlen(pMCfgReq->value) != 0) goto _err;
|
||||
*pOutValue = atoi(pMCfgReq->config + opLen + 1);
|
||||
*pOutValue = atoi(pMCfgReq->config + optLen + 1);
|
||||
} else {
|
||||
// 'key' 'value'
|
||||
if (strlen(pMCfgReq->value) == 0) goto _err;
|
||||
|
|
|
@ -112,7 +112,6 @@ extern "C" {
|
|||
#define COMMAND_CATALOG_DEBUG "catalogDebug"
|
||||
#define COMMAND_ENABLE_MEM_DEBUG "enableMemDebug"
|
||||
#define COMMAND_DISABLE_MEM_DEBUG "disableMemDebug"
|
||||
#define COMMAND_ASYNCLOG "asynclog"
|
||||
|
||||
typedef struct SExplainGroup {
|
||||
int32_t nodeNum;
|
||||
|
|
|
@ -808,16 +808,6 @@ static int32_t execAlterCmd(char* cmd, char* value, bool* processed) {
|
|||
return code;
|
||||
}
|
||||
qInfo("memory dbg disabled");
|
||||
} else if (0 == strcasecmp(cmd, COMMAND_ASYNCLOG)) {
|
||||
int newAsyncLogValue = (strlen(value) == 0) ? 1 : atoi(value);
|
||||
if (newAsyncLogValue != 0 && newAsyncLogValue != 1) {
|
||||
code = TSDB_CODE_INVALID_CFG_VALUE;
|
||||
qError("failed to alter asynclog, error:%s", tstrerror(code));
|
||||
goto _return;
|
||||
}
|
||||
|
||||
code = TSDB_CODE_SUCCESS;
|
||||
tsAsyncLog = newAsyncLogValue;
|
||||
} else {
|
||||
goto _return;
|
||||
}
|
||||
|
@ -844,10 +834,7 @@ static int32_t execAlterLocal(SAlterLocalStmt* pStmt) {
|
|||
goto _return;
|
||||
}
|
||||
|
||||
bool forbidden = false;
|
||||
taosLocalCfgForbiddenToChange(pStmt->config, &forbidden);
|
||||
if (forbidden) {
|
||||
terrno = TSDB_CODE_OPS_NOT_SUPPORT;
|
||||
if (cfgCheckRangeForDynUpdate(tsCfg, pStmt->config, pStmt->value, false)) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
|
|
|
@ -310,6 +310,7 @@ int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcTy
|
|||
GRANT_CFG_SET;
|
||||
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
||||
if (pItem == NULL) {
|
||||
terrno = TSDB_CODE_CFG_NOT_FOUND;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -338,6 +339,7 @@ int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcTy
|
|||
break;
|
||||
}
|
||||
|
||||
_err_out:
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
return -1;
|
||||
}
|
||||
|
@ -357,6 +359,50 @@ SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer) {
|
||||
ECfgDynType dynType = isServer ? CFG_DYN_SERVER : CFG_DYN_CLIENT;
|
||||
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
||||
if (!pItem || (pItem->dynScope & dynType) == 0) {
|
||||
uError("failed to config:%s, not support", name);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (pItem->dtype) {
|
||||
case CFG_DTYPE_INT32: {
|
||||
int32_t ival = (int32_t)atoi(pVal);
|
||||
if (ival < pItem->imin || ival > pItem->imax) {
|
||||
uError("cfg:%s, type:%s value:%d out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
|
||||
cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax);
|
||||
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
case CFG_DTYPE_INT64: {
|
||||
int64_t ival = (int64_t)atoll(pVal);
|
||||
if (ival < pItem->imin || ival > pItem->imax) {
|
||||
uError("cfg:%s, type:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
|
||||
cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax);
|
||||
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
case CFG_DTYPE_FLOAT:
|
||||
case CFG_DTYPE_DOUBLE: {
|
||||
float fval = (float)atof(pVal);
|
||||
if (fval < pItem->fmin || fval > pItem->fmax) {
|
||||
uError("cfg:%s, type:%s value:%f out of range[%f, %f]", pItem->name, cfgDtypeStr(pItem->dtype), fval,
|
||||
pItem->fmin, pItem->fmax);
|
||||
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t cfgAddItem(SConfig *pCfg, SConfigItem *pItem, const char *name) {
|
||||
pItem->stype = CFG_STYPE_DEFAULT;
|
||||
pItem->name = taosStrdup(name);
|
||||
|
@ -381,43 +427,61 @@ static int32_t cfgAddItem(SConfig *pCfg, SConfigItem *pItem, const char *name) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t cfgAddBool(SConfig *pCfg, const char *name, bool defaultVal, int8_t scope) {
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_BOOL, .bval = defaultVal, .scope = scope};
|
||||
int32_t cfgAddBool(SConfig *pCfg, const char *name, bool defaultVal, int8_t scope, int8_t dynScope) {
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_BOOL, .bval = defaultVal, .scope = scope, .dynScope = dynScope};
|
||||
return cfgAddItem(pCfg, &item, name);
|
||||
}
|
||||
|
||||
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) {
|
||||
if (defaultVal < minval || defaultVal > maxval) {
|
||||
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_INT32, .i32 = defaultVal, .imin = minval, .imax = maxval, .scope = scope};
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_INT32,
|
||||
.i32 = defaultVal,
|
||||
.imin = minval,
|
||||
.imax = maxval,
|
||||
.scope = scope,
|
||||
.dynScope = dynScope};
|
||||
return cfgAddItem(pCfg, &item, name);
|
||||
}
|
||||
|
||||
int32_t cfgAddInt64(SConfig *pCfg, const char *name, int64_t defaultVal, int64_t minval, int64_t maxval, int8_t scope) {
|
||||
int32_t cfgAddInt64(SConfig *pCfg, const char *name, int64_t defaultVal, int64_t minval, int64_t maxval, int8_t scope,
|
||||
int8_t dynScope) {
|
||||
if (defaultVal < minval || defaultVal > maxval) {
|
||||
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_INT64, .i64 = defaultVal, .imin = minval, .imax = maxval, .scope = scope};
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_INT64,
|
||||
.i64 = defaultVal,
|
||||
.imin = minval,
|
||||
.imax = maxval,
|
||||
.scope = scope,
|
||||
.dynScope = dynScope};
|
||||
return cfgAddItem(pCfg, &item, name);
|
||||
}
|
||||
|
||||
int32_t cfgAddFloat(SConfig *pCfg, const char *name, float defaultVal, float minval, float maxval, int8_t scope) {
|
||||
int32_t cfgAddFloat(SConfig *pCfg, const char *name, float defaultVal, float minval, float maxval, int8_t scope,
|
||||
int8_t dynScope) {
|
||||
if (defaultVal < minval || defaultVal > maxval) {
|
||||
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_FLOAT, .fval = defaultVal, .fmin = minval, .fmax = maxval, .scope = scope};
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_FLOAT,
|
||||
.fval = defaultVal,
|
||||
.fmin = minval,
|
||||
.fmax = maxval,
|
||||
.scope = scope,
|
||||
.dynScope = dynScope};
|
||||
return cfgAddItem(pCfg, &item, name);
|
||||
}
|
||||
|
||||
int32_t cfgAddString(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope) {
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_STRING, .scope = scope};
|
||||
int32_t cfgAddString(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope) {
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_STRING, .scope = scope, .dynScope = dynScope};
|
||||
item.str = taosStrdup(defaultVal);
|
||||
if (item.str == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -426,8 +490,8 @@ int32_t cfgAddString(SConfig *pCfg, const char *name, const char *defaultVal, in
|
|||
return cfgAddItem(pCfg, &item, name);
|
||||
}
|
||||
|
||||
int32_t cfgAddDir(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope) {
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_DIR, .scope = scope};
|
||||
int32_t cfgAddDir(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope) {
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_DIR, .scope = scope, .dynScope = dynScope};
|
||||
if (cfgCheckAndSetDir(&item, defaultVal) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -435,8 +499,8 @@ int32_t cfgAddDir(SConfig *pCfg, const char *name, const char *defaultVal, int8_
|
|||
return cfgAddItem(pCfg, &item, name);
|
||||
}
|
||||
|
||||
int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope) {
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_LOCALE, .scope = scope};
|
||||
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};
|
||||
if (cfgCheckAndSetLocale(&item, defaultVal) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -444,8 +508,8 @@ int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal, in
|
|||
return cfgAddItem(pCfg, &item, name);
|
||||
}
|
||||
|
||||
int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope) {
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_CHARSET, .scope = scope};
|
||||
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};
|
||||
if (cfgCheckAndSetCharset(&item, defaultVal) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -453,8 +517,8 @@ int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal, i
|
|||
return cfgAddItem(pCfg, &item, name);
|
||||
}
|
||||
|
||||
int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope) {
|
||||
SConfigItem item = {.dtype = CFG_DTYPE_TIMEZONE, .scope = scope};
|
||||
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};
|
||||
if (cfgCheckAndSetTimezone(&item, defaultVal) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,6 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
int32_t fileNum;
|
||||
int32_t maxLines;
|
||||
int32_t lines;
|
||||
int32_t flag;
|
||||
int32_t openInProgress;
|
||||
|
@ -122,7 +121,7 @@ static void *taosAsyncOutputLog(void *param);
|
|||
static int32_t taosPushLogBuffer(SLogBuff *pLogBuf, const char *msg, int32_t msgLen);
|
||||
static SLogBuff *taosLogBuffNew(int32_t bufSize);
|
||||
static void taosCloseLogByFd(TdFilePtr pFile);
|
||||
static int32_t taosOpenLogFile(char *fn, int32_t maxLines, int32_t maxFileNum);
|
||||
static int32_t taosOpenLogFile(char *fn, int32_t maxFileNum);
|
||||
|
||||
static FORCE_INLINE void taosUpdateDaylight() {
|
||||
struct tm Tm, *ptm;
|
||||
|
@ -186,7 +185,7 @@ int32_t taosInitLog(const char *logName, int32_t maxFiles) {
|
|||
|
||||
tsLogObj.logHandle = taosLogBuffNew(LOG_DEFAULT_BUF_SIZE);
|
||||
if (tsLogObj.logHandle == NULL) return -1;
|
||||
if (taosOpenLogFile(fullName, tsNumOfLogLines, maxFiles) < 0) return -1;
|
||||
if (taosOpenLogFile(fullName, maxFiles) < 0) return -1;
|
||||
|
||||
if (taosInitSlowLog() < 0) return -1;
|
||||
if (taosStartLog() < 0) return -1;
|
||||
|
@ -283,7 +282,7 @@ static void *taosThreadToOpenNewFile(void *param) {
|
|||
TdFilePtr pFile = taosOpenFile(name, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
if (pFile == NULL) {
|
||||
tsLogObj.openInProgress = 0;
|
||||
tsLogObj.lines = tsLogObj.maxLines - 1000;
|
||||
tsLogObj.lines = tsNumOfLogLines - 1000;
|
||||
uError("open new log file fail! reason:%s, reuse lastlog", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
@ -308,7 +307,7 @@ static void *taosThreadToOpenNewFile(void *param) {
|
|||
static int32_t taosOpenNewLogFile() {
|
||||
taosThreadMutexLock(&tsLogObj.logMutex);
|
||||
|
||||
if (tsLogObj.lines > tsLogObj.maxLines && tsLogObj.openInProgress == 0) {
|
||||
if (tsLogObj.lines > tsNumOfLogLines && tsLogObj.openInProgress == 0) {
|
||||
tsLogObj.openInProgress = 1;
|
||||
|
||||
uInfo("open new log file ......");
|
||||
|
@ -331,7 +330,7 @@ void taosResetLog() {
|
|||
sprintf(lastName, "%s.%d", tsLogObj.logName, tsLogObj.flag);
|
||||
|
||||
// force create a new log file
|
||||
tsLogObj.lines = tsLogObj.maxLines + 10;
|
||||
tsLogObj.lines = tsNumOfLogLines + 10;
|
||||
|
||||
taosOpenNewLogFile();
|
||||
(void)taosRemoveFile(lastName);
|
||||
|
@ -384,7 +383,7 @@ static void taosGetLogFileName(char *fn) {
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t taosOpenLogFile(char *fn, int32_t maxLines, int32_t maxFileNum) {
|
||||
static int32_t taosOpenLogFile(char *fn, int32_t maxFileNum) {
|
||||
#ifdef WINDOWS_STASH
|
||||
/*
|
||||
* always set maxFileNum to 1
|
||||
|
@ -396,7 +395,6 @@ static int32_t taosOpenLogFile(char *fn, int32_t maxLines, int32_t maxFileNum) {
|
|||
char name[LOG_FILE_NAME_LEN + 50] = "\0";
|
||||
int32_t logstat0_mtime, logstat1_mtime;
|
||||
|
||||
tsLogObj.maxLines = maxLines;
|
||||
tsLogObj.fileNum = maxFileNum;
|
||||
taosGetLogFileName(fn);
|
||||
|
||||
|
@ -497,9 +495,9 @@ static inline void taosPrintLogImp(ELogLevel level, int32_t dflag, const char *b
|
|||
taosWriteFile(tsLogObj.logHandle->pFile, buffer, len);
|
||||
}
|
||||
|
||||
if (tsLogObj.maxLines > 0) {
|
||||
if (tsNumOfLogLines > 0) {
|
||||
atomic_add_fetch_32(&tsLogObj.lines, 1);
|
||||
if ((tsLogObj.lines > tsLogObj.maxLines) && (tsLogObj.openInProgress == 0)) {
|
||||
if ((tsLogObj.lines > tsNumOfLogLines) && (tsLogObj.openInProgress == 0)) {
|
||||
taosOpenNewLogFile();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,12 +54,12 @@ TEST_F(CfgTest, 02_Basic) {
|
|||
SConfig *pConfig = cfgInit();
|
||||
ASSERT_NE(pConfig, nullptr);
|
||||
|
||||
EXPECT_EQ(cfgAddBool(pConfig, "test_bool", 0, 0), 0);
|
||||
EXPECT_EQ(cfgAddInt32(pConfig, "test_int32", 1, 0, 16, 0), 0);
|
||||
EXPECT_EQ(cfgAddInt64(pConfig, "test_int64", 2, 0, 16, 0), 0);
|
||||
EXPECT_EQ(cfgAddFloat(pConfig, "test_float", 3, 0, 16, 0), 0);
|
||||
EXPECT_EQ(cfgAddString(pConfig, "test_string", "4", 0), 0);
|
||||
EXPECT_EQ(cfgAddDir(pConfig, "test_dir", TD_TMP_DIR_PATH, 0), 0);
|
||||
EXPECT_EQ(cfgAddBool(pConfig, "test_bool", 0, 0, 0), 0);
|
||||
EXPECT_EQ(cfgAddInt32(pConfig, "test_int32", 1, 0, 16, 0, 0), 0);
|
||||
EXPECT_EQ(cfgAddInt64(pConfig, "test_int64", 2, 0, 16, 0, 0), 0);
|
||||
EXPECT_EQ(cfgAddFloat(pConfig, "test_float", 3, 0, 16, 0, 0), 0);
|
||||
EXPECT_EQ(cfgAddString(pConfig, "test_string", "4", 0, 0), 0);
|
||||
EXPECT_EQ(cfgAddDir(pConfig, "test_dir", TD_TMP_DIR_PATH, 0, 0), 0);
|
||||
|
||||
EXPECT_EQ(cfgGetSize(pConfig), 6);
|
||||
|
||||
|
|
Loading…
Reference in New Issue