• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #4824

27 Oct 2025 05:39AM UTC coverage: 61.409% (+0.2%) from 61.242%
#4824

push

travis-ci

web-flow
Merge pull request #33376 from taosdata/3.0

merge 3.0

156919 of 324854 branches covered (48.3%)

Branch coverage included in aggregate %.

371 of 493 new or added lines in 25 files covered. (75.25%)

2822 existing lines in 108 files now uncovered.

208404 of 270043 relevant lines covered (77.17%)

229356519.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

45.37
/source/dnode/mnode/impl/src/mndConfig.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#define _DEFAULT_SOURCE
17
#include "audit.h"
18
#include "mndConfig.h"
19
#include "mndDnode.h"
20
#include "mndMnode.h"
21
#include "mndPrivilege.h"
22
#include "mndSync.h"
23
#include "mndTrans.h"
24
#include "mndUser.h"
25
#include "tutil.h"
26
#include "tcompare.h"
27

28
#define CFG_VER_NUMBER    1
29
#define CFG_RESERVE_SIZE  63
30
#define CFG_ALTER_TIMEOUT 3 * 1000
31

32
// Sync timeout ratio constants
33
#define SYNC_TIMEOUT_DIVISOR       4
34
#define SYNC_TIMEOUT_ELECT_DIVISOR 2
35
#define SYNC_TIMEOUT_SR_DIVISOR    4
36
#define SYNC_TIMEOUT_HB_DIVISOR    8
37

38
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pInMCfgReq, int32_t optLen, int32_t *pOutValue);
39
static int32_t mndProcessShowVariablesReq(SRpcMsg *pReq);
40
static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq);
41
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp);
42
static int32_t mndProcessConfigReq(SRpcMsg *pReq);
43
static int32_t mndInitWriteCfg(SMnode *pMnode);
44
static int32_t mndSendRebuildReq(SMnode *pMnode);
45
static int32_t mndTryRebuildConfigSdbRsp(SRpcMsg *pRsp);
46
static int32_t initConfigArrayFromSdb(SMnode *pMnode, SArray *array);
47
static int32_t mndTryRebuildConfigSdb(SRpcMsg *pReq);
48
static void    cfgArrayCleanUp(SArray *array);
49
static void    cfgObjArrayCleanUp(SArray *array);
50
int32_t        compareSConfigItemArrays(SMnode *pMnode, const SArray *dArray, SArray *diffArray);
51

52
static int32_t mndConfigUpdateTrans(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
53
                                    int32_t tsmmConfigVersion);
54
static int32_t mndConfigUpdateTransWithDnode(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
55
                                             int32_t tsmmConfigVersion, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq);
56
static int32_t mndFindConfigsToAdd(SMnode *pMnode, SArray *addArray);
57
static int32_t mndFindConfigsToDelete(SMnode *pMnode, SArray *deleteArray);
58
static int32_t mndExecuteConfigSyncTrans(SMnode *pMnode, SArray *addArray, SArray *deleteArray);
59

60
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *obj);
61
int32_t mndSetDeleteConfigCommitLogs(STrans *pTrans, SConfigObj *item);
62

63
int32_t mndInitConfig(SMnode *pMnode) {
1,531,066✔
64
  int32_t   code = 0;
1,531,066✔
65
  SSdbTable table = {.sdbType = SDB_CFG,
1,531,066✔
66
                     .keyType = SDB_KEY_BINARY,
67
                     .encodeFp = (SdbEncodeFp)mnCfgActionEncode,
68
                     .decodeFp = (SdbDecodeFp)mndCfgActionDecode,
69
                     .insertFp = (SdbInsertFp)mndCfgActionInsert,
70
                     .updateFp = (SdbUpdateFp)mndCfgActionUpdate,
71
                     .deleteFp = (SdbDeleteFp)mndCfgActionDelete,
72
                     .deployFp = (SdbDeployFp)mndCfgActionDeploy,
73
                     .afterRestoredFp = (SdbAfterRestoredFp)mndCfgActionAfterRestored};
74

75
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG, mndProcessConfigReq);
1,531,066✔
76
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeReq);
1,531,066✔
77
  mndSetMsgHandle(pMnode, TDMT_DND_CONFIG_DNODE_RSP, mndProcessConfigDnodeRsp);
1,531,066✔
78
  mndSetMsgHandle(pMnode, TDMT_MND_SHOW_VARIABLES, mndProcessShowVariablesReq);
1,531,066✔
79
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB, mndTryRebuildConfigSdb);
1,531,066✔
80
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB_RSP, mndTryRebuildConfigSdbRsp);
1,531,066✔
81

82
  return sdbSetTable(pMnode->pSdb, table);
1,531,066✔
83
}
84

85
SSdbRaw *mnCfgActionEncode(SConfigObj *obj) {
395,602,664✔
86
  int32_t  code = 0;
395,602,664✔
87
  int32_t  lino = 0;
395,602,664✔
88
  void    *buf = NULL;
395,602,664✔
89
  SSdbRaw *pRaw = NULL;
395,602,664✔
90

91
  SEncoder encoder;
395,256,369✔
92
  tEncoderInit(&encoder, NULL, 0);
395,602,664✔
93
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
395,602,664!
94
    tEncoderClear(&encoder);
×
95
    TSDB_CHECK_CODE(code, lino, _over);
×
96
  }
97

98
  int32_t tlen = encoder.pos;
395,602,664✔
99
  tEncoderClear(&encoder);
395,602,664✔
100

101
  int32_t size = sizeof(int32_t) + tlen;
395,602,664✔
102
  pRaw = sdbAllocRaw(SDB_CFG, CFG_VER_NUMBER, size);
395,602,664✔
103
  TSDB_CHECK_NULL(pRaw, code, lino, _over, terrno);
395,602,664!
104

105
  buf = taosMemoryMalloc(tlen);
395,602,664!
106
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
395,602,664!
107

108
  tEncoderInit(&encoder, buf, tlen);
395,602,664✔
109
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
395,602,664!
110
    tEncoderClear(&encoder);
×
111
    TSDB_CHECK_CODE(code, lino, _over);
×
112
  }
113

114
  tEncoderClear(&encoder);
395,602,664✔
115

116
  int32_t dataPos = 0;
395,602,664✔
117
  SDB_SET_INT32(pRaw, dataPos, tlen, _over);
395,602,664!
118
  SDB_SET_BINARY(pRaw, dataPos, buf, tlen, _over);
395,602,664!
119
  SDB_SET_DATALEN(pRaw, dataPos, _over);
395,602,664!
120

121
_over:
395,602,664✔
122
  taosMemoryFreeClear(buf);
395,602,664!
123
  if (code != TSDB_CODE_SUCCESS) {
395,602,664!
124
    mError("cfg:%s, failed to encode to raw:%p at line:%d since %s", obj->name, pRaw, lino, tstrerror(code));
×
125
    sdbFreeRaw(pRaw);
×
126
    terrno = code;
×
127
    return NULL;
×
128
  }
129

130
  terrno = 0;
395,602,664✔
131
  mTrace("cfg:%s, encode to raw:%p, row:%p", obj->name, pRaw, obj);
395,602,664✔
132
  return pRaw;
395,602,664✔
133
}
134

135
SSdbRow *mndCfgActionDecode(SSdbRaw *pRaw) {
157,662,206✔
136
  int32_t     code = 0;
157,662,206✔
137
  int32_t     lino = 0;
157,662,206✔
138
  SSdbRow    *pRow = NULL;
157,662,206✔
139
  SConfigObj *pObj = NULL;
157,662,206✔
140
  void       *buf = NULL;
157,662,206✔
141
  int8_t      sver = 0;
157,662,206✔
142
  int32_t     tlen;
157,464,340✔
143
  int32_t     dataPos = 0;
157,662,206✔
144

145
  code = sdbGetRawSoftVer(pRaw, &sver);
157,662,206✔
146
  TSDB_CHECK_CODE(code, lino, _over);
157,662,206!
147

148
  if (sver != CFG_VER_NUMBER) {
157,662,206!
149
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
150
    goto _over;
×
151
  }
152

153
  pRow = sdbAllocRow(sizeof(SConfigObj));
157,662,206✔
154
  TSDB_CHECK_NULL(pRow, code, lino, _over, terrno);
157,662,206!
155

156
  pObj = sdbGetRowObj(pRow);
157,662,206✔
157
  TSDB_CHECK_NULL(pObj, code, lino, _over, terrno);
157,662,206!
158

159
  SDB_GET_INT32(pRaw, dataPos, &tlen, _over);
157,662,206!
160

161
  buf = taosMemoryMalloc(tlen + 1);
157,662,206!
162
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
157,662,206!
163

164
  SDB_GET_BINARY(pRaw, dataPos, buf, tlen, _over);
157,662,206!
165

166
  SDecoder decoder;
157,464,340✔
167
  tDecoderInit(&decoder, buf, tlen + 1);
157,662,206✔
168
  code = tDecodeSConfigObj(&decoder, pObj);
157,662,206✔
169
  tDecoderClear(&decoder);
157,662,206✔
170

171
  if (code < 0) {
157,662,206!
172
    tFreeSConfigObj(pObj);
×
173
  }
174

175
_over:
157,662,206✔
176
  taosMemoryFreeClear(buf);
157,662,206!
177

178
  if (code != TSDB_CODE_SUCCESS) {
157,662,206!
179
    mError("cfg:%s, failed to decode from raw:%p since %s at:%d", pObj->name, pRaw, tstrerror(code), lino);
×
180
    taosMemoryFreeClear(pRow);
×
181
    terrno = code;
×
182
    return NULL;
×
183
  } else {
184
    mTrace("config:%s, decode from raw:%p, row:%p", pObj->name, pRaw, pObj);
157,662,206✔
185
    terrno = 0;
157,662,206✔
186
    return pRow;
157,662,206✔
187
  }
188
}
189

190
static int32_t mndCfgActionInsert(SSdb *pSdb, SConfigObj *obj) {
157,662,206✔
191
  mTrace("cfg:%s, perform insert action, row:%p", obj->name, obj);
157,662,206✔
192
  return 0;
157,662,206✔
193
}
194

195
static int32_t mndCfgActionDelete(SSdb *pSdb, SConfigObj *obj) {
157,636,868✔
196
  mTrace("cfg:%s, perform delete action, row:%p", obj->name, obj);
157,636,868✔
197
  tFreeSConfigObj(obj);
157,636,868✔
198
  return 0;
157,636,868✔
199
}
200

UNCOV
201
static int32_t mndCfgActionUpdate(SSdb *pSdb, SConfigObj *pOld, SConfigObj *pNew) {
×
UNCOV
202
  mTrace("cfg:%s, perform update action, old row:%p new row:%p", pOld->name, pOld, pNew);
×
UNCOV
203
  switch (pNew->dtype) {
×
204
    case CFG_DTYPE_NONE:
×
205
      break;
×
UNCOV
206
    case CFG_DTYPE_BOOL:
×
UNCOV
207
      pOld->bval = pNew->bval;
×
UNCOV
208
      break;
×
UNCOV
209
    case CFG_DTYPE_INT32:
×
UNCOV
210
      pOld->i32 = pNew->i32;
×
UNCOV
211
      break;
×
UNCOV
212
    case CFG_DTYPE_INT64:
×
UNCOV
213
      pOld->i64 = pNew->i64;
×
UNCOV
214
      break;
×
UNCOV
215
    case CFG_DTYPE_FLOAT:
×
216
    case CFG_DTYPE_DOUBLE:
UNCOV
217
      pOld->fval = pNew->fval;
×
UNCOV
218
      break;
×
UNCOV
219
    case CFG_DTYPE_STRING:
×
220
    case CFG_DTYPE_DIR:
221
    case CFG_DTYPE_LOCALE:
222
    case CFG_DTYPE_CHARSET:
223
    case CFG_DTYPE_TIMEZONE:
UNCOV
224
      taosMemoryFree(pOld->str);
×
UNCOV
225
      pOld->str = taosStrdup(pNew->str);
×
UNCOV
226
      if (pOld->str == NULL) {
×
227
        return terrno;
×
228
      }
UNCOV
229
      break;
×
230
  }
UNCOV
231
  return TSDB_CODE_SUCCESS;
×
232
}
233

234
static int32_t mndCfgActionDeploy(SMnode *pMnode) { return mndInitWriteCfg(pMnode); }
1,069,404✔
235

236
static int32_t mndCfgActionAfterRestored(SMnode *pMnode) { return mndSendRebuildReq(pMnode); }
720,283✔
237

238
static int32_t mndProcessConfigReq(SRpcMsg *pReq) {
2,017,632✔
239
  SMnode    *pMnode = pReq->info.node;
2,017,632✔
240
  SConfigReq configReq = {0};
2,017,632✔
241
  int32_t    code = TSDB_CODE_SUCCESS;
2,017,632✔
242
  SArray    *array = NULL;
2,017,632✔
243
  bool       needFree = false;
2,017,632✔
244
  code = tDeserializeSConfigReq(pReq->pCont, pReq->contLen, &configReq);
2,017,632✔
245
  if (code != 0) {
2,017,632!
246
    mError("failed to deserialize config req, since %s", terrstr());
×
247
    goto _OVER;
×
248
  }
249

250
  SConfigObj *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
2,017,632✔
251
  if (vObj == NULL) {
2,017,632!
252
    mInfo("failed to acquire mnd config version, since %s", terrstr());
×
253
    goto _OVER;
×
254
  }
255

256
  array = taosArrayInit(16, sizeof(SConfigItem));
2,017,632✔
257
  if (array == NULL) {
2,017,632!
258
    code = TSDB_CODE_OUT_OF_MEMORY;
×
259
    goto _OVER;
×
260
  }
261
  SConfigRsp configRsp = {0};
2,017,632✔
262
  configRsp.cver = vObj->i32;
2,017,632✔
263

264
  if (configReq.cver == vObj->i32) {
2,017,632✔
265
    configRsp.isVersionVerified = 1;
441,761✔
266
  } else {
267
    code = initConfigArrayFromSdb(pMnode, array);
1,575,871✔
268
    if (code != 0) {
1,575,871!
269
      mError("failed to init config array from sdb, since %s", tstrerror(code));
×
270
      goto _OVER;
×
271
    }
272
    configRsp.array = array;
1,575,871✔
273
  }
274

275
  int32_t contLen = tSerializeSConfigRsp(NULL, 0, &configRsp);
2,017,632✔
276
  if (contLen < 0) {
2,017,632!
277
    code = contLen;
×
278
    goto _OVER;
×
279
  }
280
  void *pHead = rpcMallocCont(contLen);
2,017,632✔
281
  if (pHead == NULL) {
2,017,632!
282
    code = TSDB_CODE_OUT_OF_MEMORY;
×
283
    goto _OVER;
×
284
  }
285
  contLen = tSerializeSConfigRsp(pHead, contLen, &configRsp);
2,017,632✔
286
  if (contLen < 0) {
2,017,632!
287
    rpcFreeCont(pHead);
×
288
    code = contLen;
×
289
    goto _OVER;
×
290
  }
291
  pReq->info.rspLen = contLen;
2,017,632✔
292
  pReq->info.rsp = pHead;
2,017,632✔
293

294
_OVER:
2,017,632✔
295
  if (code != 0) {
2,017,632!
296
    mError("failed to process config req, since %s", tstrerror(code));
×
297
  }
298
  sdbRelease(pMnode->pSdb, vObj);
2,017,632✔
299
  cfgArrayCleanUp(array);
2,017,632✔
300
  tFreeSConfigReq(&configReq);
2,017,632✔
301
  return code;
2,017,632✔
302
}
303

304
int32_t mndInitWriteCfg(SMnode *pMnode) {
1,069,404✔
305
  int    code = 0;
1,069,404✔
306
  size_t sz = 0;
1,069,404✔
307

308
  mInfo("init write cfg to sdb");
1,069,404!
309
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "init-write-config");
1,069,404✔
310
  if (pTrans == NULL) {
1,069,404!
311
    mError("failed to init write cfg in create trans, since %s", terrstr());
×
312
    goto _OVER;
×
313
  }
314

315
  // encode mnd config version
316
  SConfigObj versionObj = mndInitConfigVersion();
1,069,404✔
317
  if ((code = mndSetCreateConfigCommitLogs(pTrans, &versionObj)) != 0) {
1,069,404!
318
    mError("failed to init mnd config version, since %s", tstrerror(code));
×
319
    tFreeSConfigObj(&versionObj);
×
320
    goto _OVER;
×
321
  }
322
  tFreeSConfigObj(&versionObj);
1,069,404✔
323
  sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
1,069,404✔
324

325
  for (int i = 0; i < sz; ++i) {
110,116,788✔
326
    SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
109,047,384✔
327
    SConfigObj   obj;
108,959,052✔
328
    if ((code = mndInitConfigObj(item, &obj)) != 0) {
109,047,384!
329
      goto _OVER;
×
330
    }
331
    if ((code = mndSetCreateConfigCommitLogs(pTrans, &obj)) != 0) {
109,047,384!
332
      mError("failed to init mnd config:%s, since %s", item->name, tstrerror(code));
×
333
      tFreeSConfigObj(&obj);
×
334
      goto _OVER;
×
335
    }
336
    tFreeSConfigObj(&obj);
109,047,384✔
337
  }
338
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
1,069,404!
339

340
_OVER:
1,069,404✔
341
  if (code != 0) {
1,069,404!
342
    mError("failed to init write cfg, since %s", tstrerror(code));
×
343
  }
344
  mndTransDrop(pTrans);
1,069,404✔
345
  return code;
1,069,404✔
346
}
347

348
int32_t mndSendRebuildReq(SMnode *pMnode) {
720,283✔
349
  int32_t code = 0;
720,283✔
350

351
  SRpcMsg rpcMsg = {.pCont = NULL,
720,283✔
352
                    .contLen = 0,
353
                    .msgType = TDMT_MND_CONFIG_SDB,
354
                    .info.ahandle = 0,
355
                    .info.notFreeAhandle = 1,
356
                    .info.refId = 0,
357
                    .info.noResp = 0,
358
                    .info.handle = 0};
359
  SEpSet  epSet = {0};
720,283✔
360

361
  mndGetMnodeEpSet(pMnode, &epSet);
720,283✔
362

363
  code = tmsgSendReq(&epSet, &rpcMsg);
720,283✔
364
  if (code != 0) {
720,283!
365
    mError("failed to send rebuild config req, since %s", tstrerror(code));
×
366
  }
367
  return code;
720,283✔
368
}
369

370
static int32_t mndTryRebuildConfigSdb(SRpcMsg *pReq) {
718,170✔
371
  SMnode *pMnode = pReq->info.node;
718,170✔
372
  if (!mndIsLeader(pMnode)) {
718,170!
373
    return TSDB_CODE_SUCCESS;
×
374
  }
375

376
  int32_t     code = 0;
718,170✔
377
  SConfigObj *vObj = NULL;
718,170✔
378
  SArray     *addArray = NULL;
718,170✔
379
  SArray     *deleteArray = NULL;
718,170✔
380

381
  vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
718,170✔
382
  if (vObj == NULL) {
718,170!
383
    code = mndInitWriteCfg(pMnode);
×
384
    if (code < 0) {
×
385
      mError("failed to init write cfg, since %s", tstrerror(code));
×
386
    } else {
387
      mInfo("failed to acquire mnd config version, try to rebuild config in sdb.");
×
388
    }
389
    goto _exit;
×
390
  }
391

392
  addArray = taosArrayInit(4, sizeof(SConfigObj));
718,170✔
393
  deleteArray = taosArrayInit(4, sizeof(SConfigObj));
718,170✔
394
  if (addArray == NULL || deleteArray == NULL) {
718,170!
395
    code = TSDB_CODE_OUT_OF_MEMORY;
×
396
    goto _exit;
×
397
  }
398

399
  // Find configs to add and delete
400
  if ((code = mndFindConfigsToAdd(pMnode, addArray)) != 0) {
718,170!
401
    mError("failed to find configs to add, since %s", tstrerror(code));
×
402
    goto _exit;
×
403
  }
404

405
  if ((code = mndFindConfigsToDelete(pMnode, deleteArray)) != 0) {
718,170!
406
    mError("failed to find configs to delete, since %s", tstrerror(code));
×
407
    goto _exit;
×
408
  }
409

410
  // Execute the sync transaction
411
  if ((code = mndExecuteConfigSyncTrans(pMnode, addArray, deleteArray)) != 0) {
718,170!
412
    mError("failed to execute config sync transaction, since %s", tstrerror(code));
×
413
    goto _exit;
×
414
  }
415

416
_exit:
718,170✔
417
  if (code != 0) {
718,170!
418
    mError("failed to try rebuild config in sdb, since %s", tstrerror(code));
×
419
  }
420
  sdbRelease(pMnode->pSdb, vObj);
718,170✔
421
  cfgObjArrayCleanUp(addArray);
718,170✔
422
  cfgObjArrayCleanUp(deleteArray);
718,170✔
423
  TAOS_RETURN(code);
718,170✔
424
}
425

426
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *item) {
110,199,958✔
427
  int32_t  code = 0;
110,199,958✔
428
  SSdbRaw *pCommitRaw = mnCfgActionEncode(item);
110,199,958✔
429
  if (pCommitRaw == NULL) {
110,199,958!
430
    code = terrno;
×
431
    TAOS_RETURN(code);
×
432
  }
433
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw) != 0)) TAOS_RETURN(code);
110,199,958!
434
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY)) != 0) TAOS_RETURN(code);
110,199,958!
435
  return TSDB_CODE_SUCCESS;
110,199,958✔
436
}
437

438
int32_t mndSetDeleteConfigCommitLogs(STrans *pTrans, SConfigObj *item) {
×
439
  int32_t  code = 0;
×
440
  SSdbRaw *pCommitRaw = mnCfgActionEncode(item);
×
441
  if (pCommitRaw == NULL) {
×
442
    code = terrno;
×
443
    TAOS_RETURN(code);
×
444
  }
445
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw) != 0)) TAOS_RETURN(code);
×
446
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED)) != 0) TAOS_RETURN(code);
×
447
  return TSDB_CODE_SUCCESS;
×
448
}
449

450
static int32_t mndFindConfigsToAdd(SMnode *pMnode, SArray *addArray) {
718,170✔
451
  int32_t code = 0;
718,170✔
452
  int32_t sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
718,170✔
453

454
  for (int i = 0; i < sz; ++i) {
73,971,510✔
455
    SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
73,253,340✔
456
    SConfigObj  *obj = sdbAcquire(pMnode->pSdb, SDB_CFG, item->name);
73,253,340✔
457
    if (obj == NULL) {
73,253,340!
458
      mInfo("config:%s, not exist in sdb, will add it", item->name);
×
459
      SConfigObj newObj;
×
460
      if ((code = mndInitConfigObj(item, &newObj)) != 0) {
×
461
        TAOS_RETURN(code);
×
462
      }
463
      if (NULL == taosArrayPush(addArray, &newObj)) {
×
464
        tFreeSConfigObj(&newObj);
×
465
        TAOS_RETURN(terrno);
×
466
      }
467
    } else {
468
      sdbRelease(pMnode->pSdb, obj);
73,253,340✔
469
    }
470
  }
471

472
  TAOS_RETURN(TSDB_CODE_SUCCESS);
718,170✔
473
}
474

475
static int32_t mndFindConfigsToDelete(SMnode *pMnode, SArray *deleteArray) {
718,170✔
476
  int32_t     code = 0;
718,170✔
477
  int32_t     sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
718,170✔
478
  SSdb       *pSdb = pMnode->pSdb;
718,170✔
479
  void       *pIter = NULL;
718,170✔
480
  SConfigObj *obj = NULL;
718,170✔
481

482
  while (1) {
73,971,510✔
483
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
74,689,680✔
484
    if (pIter == NULL) break;
74,689,680✔
485
    if (obj == NULL) {
73,971,510!
486
      code = TSDB_CODE_OUT_OF_MEMORY;
×
487
      sdbCancelFetch(pSdb, pIter);
×
488
      TAOS_RETURN(code);
×
489
    }
490

491
    // Skip the version config
492
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
73,971,510✔
493
      sdbRelease(pSdb, obj);
718,170✔
494
      continue;
718,170✔
495
    }
496

497
    // Check if this config exists in global config
498
    bool existsInGlobal = false;
73,253,340✔
499
    for (int i = 0; i < sz; ++i) {
2,147,483,647!
500
      SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
2,147,483,647✔
501
      if (strcasecmp(obj->name, item->name) == 0) {
2,147,483,647!
502
        existsInGlobal = true;
73,253,340✔
503
        break;
73,253,340✔
504
      }
505
    }
506

507
    if (!existsInGlobal) {
73,253,340!
508
      mInfo("config:%s, not exist in global config, will delete it from sdb", obj->name);
×
509
      SConfigObj deleteObj = {0};
×
510
      tstrncpy(deleteObj.name, obj->name, CFG_NAME_MAX_LEN);
×
511
      deleteObj.dtype = obj->dtype;
×
512

513
      // Copy the value based on type
514
      switch (obj->dtype) {
×
515
        case CFG_DTYPE_BOOL:
×
516
          deleteObj.bval = obj->bval;
×
517
          break;
×
518
        case CFG_DTYPE_INT32:
×
519
          deleteObj.i32 = obj->i32;
×
520
          break;
×
521
        case CFG_DTYPE_INT64:
×
522
          deleteObj.i64 = obj->i64;
×
523
          break;
×
524
        case CFG_DTYPE_FLOAT:
×
525
        case CFG_DTYPE_DOUBLE:
526
          deleteObj.fval = obj->fval;
×
527
          break;
×
528
        case CFG_DTYPE_STRING:
×
529
        case CFG_DTYPE_DIR:
530
        case CFG_DTYPE_LOCALE:
531
        case CFG_DTYPE_CHARSET:
532
        case CFG_DTYPE_TIMEZONE:
533
          deleteObj.str = taosStrdup(obj->str);
×
534
          if (deleteObj.str == NULL) {
×
535
            sdbCancelFetch(pSdb, pIter);
×
536
            sdbRelease(pSdb, obj);
×
537
            TAOS_RETURN(terrno);
×
538
          }
539
          break;
×
540
        default:
×
541
          break;
×
542
      }
543

544
      if (NULL == taosArrayPush(deleteArray, &deleteObj)) {
×
545
        tFreeSConfigObj(&deleteObj);
×
546
        sdbCancelFetch(pSdb, pIter);
×
547
        sdbRelease(pSdb, obj);
×
548
        TAOS_RETURN(terrno);
×
549
      }
550
    }
551

552
    sdbRelease(pSdb, obj);
73,253,340✔
553
  }
554

555
  TAOS_RETURN(TSDB_CODE_SUCCESS);
718,170✔
556
}
557

558
static int32_t mndExecuteConfigSyncTrans(SMnode *pMnode, SArray *addArray, SArray *deleteArray) {
718,170✔
559
  int32_t addSize = taosArrayGetSize(addArray);
718,170✔
560
  int32_t deleteSize = taosArrayGetSize(deleteArray);
718,170✔
561

562
  if (addSize == 0 && deleteSize == 0) {
718,170!
563
    return TSDB_CODE_SUCCESS;
718,170✔
564
  }
565

566
  const char *transName = "sync-config";
×
567
  if (addSize > 0 && deleteSize > 0) {
×
568
    transName = "sync-config";
×
569
  } else if (addSize > 0) {
×
570
    transName = "add-config";
×
571
  } else {
572
    transName = "delete-config";
×
573
  }
574

575
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, transName);
×
576
  if (pTrans == NULL) {
×
577
    TAOS_RETURN(terrno);
×
578
  }
579

580
  int32_t code = 0;
×
581

582
  // Add new configs
583
  for (int i = 0; i < addSize; ++i) {
×
584
    SConfigObj *AddObj = taosArrayGet(addArray, i);
×
585
    if ((code = mndSetCreateConfigCommitLogs(pTrans, AddObj)) != 0) {
×
586
      mndTransDrop(pTrans);
×
587
      TAOS_RETURN(code);
×
588
    }
589
  }
590

591
  // Delete obsolete configs
592
  for (int i = 0; i < deleteSize; ++i) {
×
593
    SConfigObj *DelObj = taosArrayGet(deleteArray, i);
×
594
    if ((code = mndSetDeleteConfigCommitLogs(pTrans, DelObj)) != 0) {
×
595
      mndTransDrop(pTrans);
×
596
      TAOS_RETURN(code);
×
597
    }
598
  }
599

600
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) {
×
601
    mndTransDrop(pTrans);
×
602
    TAOS_RETURN(code);
×
603
  }
604

605
  mInfo("sync config to sdb, add nums:%d, delete nums:%d", addSize, deleteSize);
×
606
  mndTransDrop(pTrans);
×
607
  TAOS_RETURN(TSDB_CODE_SUCCESS);
×
608
}
609

610
static int32_t mndMCfg2DCfg(SMCfgDnodeReq *pMCfgReq, SDCfgDnodeReq *pDCfgReq) {
297,944✔
611
  int32_t code = 0;
297,944✔
612
  char   *p = pMCfgReq->config;
297,944✔
613
  while (*p) {
4,453,346✔
614
    if (*p == ' ') {
4,319,813✔
615
      break;
164,411✔
616
    }
617
    p++;
4,155,402✔
618
  }
619

620
  size_t optLen = p - pMCfgReq->config;
297,944✔
621
  tstrncpy(pDCfgReq->config, pMCfgReq->config, sizeof(pDCfgReq->config));
297,944!
622
  pDCfgReq->config[optLen] = 0;
297,944✔
623

624
  if (' ' == pMCfgReq->config[optLen]) {
297,944✔
625
    // 'key value'
626
    if (strlen(pMCfgReq->value) != 0) goto _err;
164,411!
627
    tstrncpy(pDCfgReq->value, p + 1, sizeof(pDCfgReq->value));
164,411!
628
  } else {
629
    // 'key' 'value'
630
    if (strlen(pMCfgReq->value) == 0) goto _err;
133,533✔
631
    tstrncpy(pDCfgReq->value, pMCfgReq->value, sizeof(pDCfgReq->value));
131,294!
632
  }
633

634
  TAOS_RETURN(code);
295,705✔
635

636
_err:
2,239✔
637
  mError("dnode:%d, failed to config since invalid conf:%s", pMCfgReq->dnodeId, pMCfgReq->config);
2,239!
638
  code = TSDB_CODE_INVALID_CFG;
2,239✔
639
  TAOS_RETURN(code);
2,239✔
640
}
641

642
static int32_t mndBuildCfgDnodeRedoAction(STrans *pTrans, SDnodeObj *pDnode, SDCfgDnodeReq *pDcfgReq) {
48,255✔
643
  int32_t code = 0;
48,255✔
644
  SEpSet  epSet = mndGetDnodeEpset(pDnode);
48,255✔
645
  int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, pDcfgReq);
48,255✔
646
  void   *pBuf = taosMemoryMalloc(bufLen);
48,255!
647

648
  if (pBuf == NULL) {
48,255!
NEW
649
    code = terrno;
×
NEW
650
    return code;
×
651
  }
652

653
  if ((bufLen = tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq)) <= 0) {
48,255!
NEW
654
    code = bufLen;
×
NEW
655
    taosMemoryFree(pBuf);
×
NEW
656
    return code;
×
657
  }
658

659
  STransAction action = {
48,255✔
660
      .epSet = epSet,
661
      .pCont = pBuf,
662
      .contLen = bufLen,
663
      .msgType = TDMT_DND_CONFIG_DNODE,
664
      .acceptableCode = 0,
665
      .groupId = -1,
666
  };
667

668
  mInfo("dnode:%d, append redo action to trans, config:%s value:%s", pDnode->id, pDcfgReq->config, pDcfgReq->value);
48,255!
669

670
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
48,255!
NEW
671
    taosMemoryFree(pBuf);
×
NEW
672
    return code;
×
673
  }
674

675
  return code;
48,255✔
676
}
677

678
static int32_t mndSendCfgDnodeReq(SMnode *pMnode, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
175,690✔
679
  int32_t code = -1;
175,690✔
680
  SSdb   *pSdb = pMnode->pSdb;
175,690✔
681
  void   *pIter = NULL;
175,690✔
682

683
  int64_t curMs = taosGetTimestampMs();
175,690✔
684

685
  while (1) {
429,513✔
686
    SDnodeObj *pDnode = NULL;
605,203✔
687
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
605,203✔
688
    if (pIter == NULL) break;
605,203✔
689

690
    if (pDnode->id == dnodeId || dnodeId == -1 || dnodeId == 0) {
431,853!
691
      bool online = mndIsDnodeOnline(pDnode, curMs);
184,424✔
692
      if (!online) {
184,424!
693
        mWarn("dnode:%d, is offline, skip to send config req", pDnode->id);
×
694
        continue;
×
695
      }
696
      SEpSet  epSet = mndGetDnodeEpset(pDnode);
184,424✔
697
      int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, pDcfgReq);
184,424✔
698
      void   *pBuf = rpcMallocCont(bufLen);
184,424✔
699

700
      if (pBuf == NULL) {
184,424!
701
        sdbCancelFetch(pMnode->pSdb, pIter);
×
702
        sdbRelease(pMnode->pSdb, pDnode);
×
703
        code = TSDB_CODE_OUT_OF_MEMORY;
×
704
        return code;
×
705
      }
706

707
      if ((bufLen = tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq)) <= 0) {
184,424!
708
        sdbCancelFetch(pMnode->pSdb, pIter);
×
709
        sdbRelease(pMnode->pSdb, pDnode);
×
710
        code = bufLen;
×
711
        rpcFreeCont(pBuf);
×
712
        return code;
×
713
      }
714

715
      mInfo("dnode:%d, send config req to dnode, config:%s value:%s", pDnode->id, pDcfgReq->config, pDcfgReq->value);
184,424!
716
      SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pBuf, .contLen = bufLen};
184,424✔
717
      SRpcMsg rpcRsp = {0};
184,424✔
718

719
      code = rpcSendRecvWithTimeout(pMnode->msgCb.statusRpc, &epSet, &rpcMsg, &rpcRsp, NULL, CFG_ALTER_TIMEOUT);
184,424✔
720
      if (code != 0) {
184,424!
721
        mError("failed to send config req to dnode:%d, since %s", pDnode->id, tstrerror(code));
×
722
        sdbCancelFetch(pMnode->pSdb, pIter);
×
723
        sdbRelease(pMnode->pSdb, pDnode);
×
724
        return code;
×
725
      }
726

727
      code = rpcRsp.code;
184,424✔
728
      if (code != 0) {
184,424✔
729
        mError("failed to alter config %s,on dnode:%d, since %s", pDcfgReq->config, pDnode->id, tstrerror(code));
2,340!
730
        sdbCancelFetch(pMnode->pSdb, pIter);
2,340✔
731
        sdbRelease(pMnode->pSdb, pDnode);
2,340✔
732
        return code;
2,340✔
733
      }
734
      rpcFreeCont(rpcRsp.pCont);
182,084✔
735
    }
736
    sdbRelease(pSdb, pDnode);
429,513✔
737
  }
738

739
  if (code == -1) {
173,350✔
740
    code = TSDB_CODE_MND_DNODE_NOT_EXIST;
4,456✔
741
  }
742
  TAOS_RETURN(code);
173,350✔
743
}
744

745
static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
307,684✔
746
  int32_t       code = 0;
307,684✔
747
  int32_t       lino = -1;
307,684✔
748
  SMnode       *pMnode = pReq->info.node;
307,684✔
749
  SMCfgDnodeReq cfgReq = {0};
307,684✔
750
  SConfigObj   *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
307,684✔
751
  if (vObj == NULL) {
307,684!
752
    code = TSDB_CODE_SDB_OBJ_NOT_THERE;
×
753
    mInfo("failed to acquire mnd config version, since %s", tstrerror(code));
×
754
    goto _err_out;
×
755
  }
756

757
  TAOS_CHECK_RETURN(tDeserializeSMCfgDnodeReq(pReq->pCont, pReq->contLen, &cfgReq));
307,684!
758
  int8_t updateIpWhiteList = 0;
307,684✔
759
  mInfo("dnode:%d, start to config, option:%s, value:%s", cfgReq.dnodeId, cfgReq.config, cfgReq.value);
307,684!
760
  if ((code = mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONFIG_DNODE)) != 0) {
307,684✔
761
    goto _err_out;
7,861✔
762
  }
763

764
  SDCfgDnodeReq dcfgReq = {0};
299,823✔
765
  if (strcasecmp(cfgReq.config, "resetlog") == 0) {
299,823✔
766
    tstrncpy(dcfgReq.config, "resetlog", 9);
1,879✔
767
    goto _send_req;
1,879✔
768
#ifdef TD_ENTERPRISE
769
  } else if (strncasecmp(cfgReq.config, "ssblocksize", 12) == 0) {
297,944!
770
    int32_t optLen = strlen("ssblocksize");
×
771
    int32_t flag = -1;
×
772
    int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
×
773
    if (code < 0) {
×
774
      goto _err_out;
×
775
    }
776

777
    if (flag > 1024 * 1024 || (flag > -1 && flag < 1024) || flag < -1) {
×
778
      mError("dnode:%d, failed to config ssblocksize since value:%d. Valid range: -1 or [1024, 1024 * 1024]",
×
779
             cfgReq.dnodeId, flag);
780
      code = TSDB_CODE_INVALID_CFG;
×
781
      goto _err_out;
×
782
    }
783

784
    tstrncpy(dcfgReq.config, "ssblocksize", 12);
×
785
    snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
×
786
#endif
787
  } else {
788
    TAOS_CHECK_GOTO(mndMCfg2DCfg(&cfgReq, &dcfgReq), &lino, _err_out);
297,944✔
789
    if (strlen(dcfgReq.config) > TSDB_DNODE_CONFIG_LEN) {
295,705!
790
      mError("dnode:%d, failed to config since config is too long", cfgReq.dnodeId);
×
791
      code = TSDB_CODE_INVALID_CFG;
×
792
      goto _err_out;
×
793
    }
794
    if (strncasecmp(dcfgReq.config, "enableWhiteList", strlen("enableWhiteList")) == 0) {
295,705✔
795
      updateIpWhiteList = 1;
3,060✔
796
    }
797

798
    CfgAlterType alterType = (cfgReq.dnodeId == 0 || cfgReq.dnodeId == -1) ? CFG_ALTER_ALL_DNODES : CFG_ALTER_DNODE;
295,705!
799
    TAOS_CHECK_GOTO(cfgCheckRangeForDynUpdate(taosGetCfg(), dcfgReq.config, dcfgReq.value, true, alterType), &lino,
295,705✔
800
                    _err_out);
801
  }
802
  SConfigItem *pItem = cfgGetItem(taosGetCfg(), dcfgReq.config);
215,396✔
803
  // Update config in sdb.
804
  if (pItem == NULL) {
215,396!
805
    mError("failed to find config:%s while process config dnode req", cfgReq.config);
×
806
    code = TSDB_CODE_CFG_NOT_FOUND;
×
807
    goto _err_out;
×
808
  }
809

810
  // Audit log
811
  {
812
    char obj[50] = {0};
215,396✔
813
    (void)tsnprintf(obj, sizeof(obj), "%d", cfgReq.dnodeId);
215,396✔
814
    auditRecord(pReq, pMnode->clusterId, "alterDnode", obj, "", cfgReq.sql, cfgReq.sqlLen);
215,396✔
815
  }
816

817
  dcfgReq.version = vObj->i32 + 1;
215,396✔
818

819
  if (pItem->category == CFG_CATEGORY_GLOBAL) {
215,396✔
820
    // Use transaction to update SDB and send to dnode atomically
821
    TAOS_CHECK_GOTO(mndConfigUpdateTransWithDnode(pMnode, dcfgReq.config, dcfgReq.value, pItem->dtype, dcfgReq.version,
41,585!
822
                                                  cfgReq.dnodeId, &dcfgReq),
823
                    &lino, _err_out);
824
  } else {
825
    // For local config, still use the old method (only send to dnode)
826
    goto _send_req;
173,811✔
827
  }
828

829
  // For global config, transaction has handled everything, go to success
830
  goto _success;
41,585✔
831

832
_send_req:
175,690✔
833
  dcfgReq.version = vObj->i32;
175,690✔
834
  code = mndSendCfgDnodeReq(pMnode, cfgReq.dnodeId, &dcfgReq);
175,690✔
835
  if (code != 0) {
175,690✔
836
    mError("failed to send config req to dnode:%d, since %s", cfgReq.dnodeId, tstrerror(code));
6,796!
837
    goto _err_out;
6,796✔
838
  }
839

840
_success:
210,479✔
841
  // dont care suss or succ;
842
  if (updateIpWhiteList) mndRefreshUserIpWhiteList(pMnode);
210,479✔
843
  tFreeSMCfgDnodeReq(&cfgReq);
210,479✔
844
  sdbRelease(pMnode->pSdb, vObj);
210,479✔
845
  TAOS_RETURN(code);
210,479✔
846

847
_err_out:
97,205✔
848
  mError("failed to process config dnode req, since %s", tstrerror(code));
97,205!
849
  tFreeSMCfgDnodeReq(&cfgReq);
97,205✔
850
  sdbRelease(pMnode->pSdb, vObj);
97,205✔
851
  TAOS_RETURN(code);
97,205✔
852
}
853

854
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) {
454,533✔
855
  mInfo("config rsp from dnode");
454,533!
856
  return 0;
454,533✔
857
}
858

859
static int32_t mndTryRebuildConfigSdbRsp(SRpcMsg *pRsp) {
719,449✔
860
  mInfo("rebuild config sdb rsp");
719,449!
861
  return 0;
719,449✔
862
}
863

864
// Helper function to create and commit a config object
NEW
865
static int32_t mndCreateAndCommitConfigObj(STrans *pTrans, const char *srcName, const char *cfgName, char *value,
×
866
                                           int32_t *lino) {
NEW
867
  int32_t     code = 0;
×
NEW
868
  SConfigObj *pTmp = taosMemoryMalloc(sizeof(SConfigObj));
×
NEW
869
  if (pTmp == NULL) {
×
NEW
870
    code = terrno;
×
NEW
871
    return code;
×
872
  }
873

NEW
874
  pTmp->dtype = CFG_DTYPE_INT32;
×
NEW
875
  tstrncpy(pTmp->name, cfgName, CFG_NAME_MAX_LEN);
×
NEW
876
  code = mndUpdateObj(pTmp, srcName, value);
×
NEW
877
  if (code != 0) {
×
NEW
878
    tFreeSConfigObj(pTmp);
×
NEW
879
    taosMemoryFree(pTmp);
×
NEW
880
    return code;
×
881
  }
882

NEW
883
  code = mndSetCreateConfigCommitLogs(pTrans, pTmp);
×
NEW
884
  tFreeSConfigObj(pTmp);
×
NEW
885
  taosMemoryFree(pTmp);
×
NEW
886
  return code;
×
887
}
888

889
// Helper function to handle syncTimeout related config updates
NEW
890
static int32_t mndHandleSyncTimeoutConfigs(STrans *pTrans, const char *srcName, const char *pValue, int32_t *lino) {
×
NEW
891
  int32_t code = 0;
×
NEW
892
  int32_t syncTimeout = 0;
×
NEW
893
  char    tmp[10] = {0};
×
894

NEW
895
  if (sscanf(pValue, "%d", &syncTimeout) != 1) {
×
NEW
896
    syncTimeout = 0;
×
897
  }
898

NEW
899
  int32_t baseTimeout = syncTimeout - syncTimeout / SYNC_TIMEOUT_DIVISOR;
×
900

901
  // arbSetAssignedTimeoutMs = syncTimeout
NEW
902
  sprintf(tmp, "%d", syncTimeout);
×
NEW
903
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "arbSetAssignedTimeoutMs", tmp, lino), lino, _OVER);
×
904

905
  // arbHeartBeatIntervalMs = syncTimeout / 4
NEW
906
  sprintf(tmp, "%d", syncTimeout / SYNC_TIMEOUT_DIVISOR);
×
NEW
907
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "arbHeartBeatIntervalMs", tmp, lino), lino, _OVER);
×
908

909
  // arbCheckSyncIntervalMs = syncTimeout / 4
NEW
910
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "arbCheckSyncIntervalMs", tmp, lino), lino, _OVER);
×
911

912
  // syncVnodeElectIntervalMs = (syncTimeout - syncTimeout / 4) / 2
NEW
913
  sprintf(tmp, "%d", baseTimeout / SYNC_TIMEOUT_ELECT_DIVISOR);
×
NEW
914
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "syncVnodeElectIntervalMs", tmp, lino), lino, _OVER);
×
915

916
  // syncMnodeElectIntervalMs = (syncTimeout - syncTimeout / 4) / 2
NEW
917
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "syncMnodeElectIntervalMs", tmp, lino), lino, _OVER);
×
918

919
  // statusTimeoutMs = (syncTimeout - syncTimeout / 4) / 2
NEW
920
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "statusTimeoutMs", tmp, lino), lino, _OVER);
×
921

922
  // statusSRTimeoutMs = (syncTimeout - syncTimeout / 4) / 4
NEW
923
  sprintf(tmp, "%d", baseTimeout / SYNC_TIMEOUT_SR_DIVISOR);
×
NEW
924
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "statusSRTimeoutMs", tmp, lino), lino, _OVER);
×
925

926
  // syncVnodeHeartbeatIntervalMs = (syncTimeout - syncTimeout / 4) / 8
NEW
927
  sprintf(tmp, "%d", baseTimeout / SYNC_TIMEOUT_HB_DIVISOR);
×
NEW
928
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "syncVnodeHeartbeatIntervalMs", tmp, lino), lino, _OVER);
×
929

930
  // syncMnodeHeartbeatIntervalMs = (syncTimeout - syncTimeout / 4) / 8
NEW
931
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "syncMnodeHeartbeatIntervalMs", tmp, lino), lino, _OVER);
×
932

933
  // statusIntervalMs = (syncTimeout - syncTimeout / 4) / 8
NEW
934
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "statusIntervalMs", tmp, lino), lino, _OVER);
×
935

NEW
936
_OVER:
×
NEW
937
  return code;
×
938
}
939

940
// get int32_t value from 'SMCfgDnodeReq'
941
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pMCfgReq, int32_t optLen, int32_t *pOutValue) {
×
942
  int32_t code = 0;
×
943
  if (' ' != pMCfgReq->config[optLen] && 0 != pMCfgReq->config[optLen]) {
×
944
    goto _err;
×
945
  }
946

947
  if (' ' == pMCfgReq->config[optLen]) {
×
948
    // 'key value'
949
    if (strlen(pMCfgReq->value) != 0) goto _err;
×
950
    *pOutValue = taosStr2Int32(pMCfgReq->config + optLen + 1, NULL, 10);
×
951
  } else {
952
    // 'key' 'value'
953
    if (strlen(pMCfgReq->value) == 0) goto _err;
×
954
    *pOutValue = taosStr2Int32(pMCfgReq->value, NULL, 10);
×
955
  }
956

957
  TAOS_RETURN(code);
×
958

959
_err:
×
960
  mError(" failed to set config since:%s", tstrerror(code));
×
961
  TAOS_RETURN(code);
×
962
}
963

UNCOV
964
static int32_t mndConfigUpdateTrans(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
×
965
                                    int32_t tsmmConfigVersion) {
UNCOV
966
  int32_t     code = -1;
×
UNCOV
967
  int32_t     lino = -1;
×
UNCOV
968
  SConfigObj *pVersion = taosMemoryMalloc(sizeof(SConfigObj)), *pObj = taosMemoryMalloc(sizeof(SConfigObj));
×
UNCOV
969
  if (pVersion == NULL || pObj == NULL) {
×
970
    code = terrno;
×
971
    goto _OVER;
×
972
  }
UNCOV
973
  tstrncpy(pVersion->name, "tsmmConfigVersion", CFG_NAME_MAX_LEN);
×
UNCOV
974
  pVersion->dtype = CFG_DTYPE_INT32;
×
UNCOV
975
  pVersion->i32 = tsmmConfigVersion;
×
976

UNCOV
977
  pObj->dtype = dtype;
×
UNCOV
978
  tstrncpy(pObj->name, name, CFG_NAME_MAX_LEN);
×
979

UNCOV
980
  TAOS_CHECK_GOTO(mndUpdateObj(pObj, name, pValue), &lino, _OVER);
×
UNCOV
981
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, NULL, "update-config");
×
UNCOV
982
  if (pTrans == NULL) {
×
983
    code = terrno;
×
984
    goto _OVER;
×
985
  }
UNCOV
986
  mInfo("trans:%d, used to update config:%s to value:%s", pTrans->id, name, pValue);
×
UNCOV
987
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pVersion), &lino, _OVER);
×
UNCOV
988
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pObj), &lino, _OVER);
×
989

UNCOV
990
  if (taosStrncasecmp(name, "syncTimeout", CFG_NAME_MAX_LEN) == 0) {
×
NEW
991
    TAOS_CHECK_GOTO(mndHandleSyncTimeoutConfigs(pTrans, name, pValue, &lino), &lino, _OVER);
×
992
  }
NEW
993
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
×
NEW
994
  code = 0;
×
NEW
995
_OVER:
×
NEW
996
  if (code != 0) {
×
NEW
997
    mError("failed to update config:%s to value:%s, since %s", name, pValue, tstrerror(code));
×
998
  }
NEW
999
  mndTransDrop(pTrans);
×
NEW
1000
  tFreeSConfigObj(pVersion);
×
NEW
1001
  taosMemoryFree(pVersion);
×
NEW
1002
  tFreeSConfigObj(pObj);
×
NEW
1003
  taosMemoryFree(pObj);
×
NEW
1004
  return code;
×
1005
}
1006

1007
static int32_t mndConfigUpdateTransWithDnode(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
41,585✔
1008
                                             int32_t tsmmConfigVersion, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
1009
  int32_t     code = -1;
41,585✔
1010
  int32_t     lino = -1;
41,585✔
1011
  SConfigObj *pVersion = taosMemoryMalloc(sizeof(SConfigObj)), *pObj = taosMemoryMalloc(sizeof(SConfigObj));
41,585!
1012
  if (pVersion == NULL || pObj == NULL) {
41,585!
NEW
1013
    code = terrno;
×
NEW
1014
    goto _OVER;
×
1015
  }
1016
  tstrncpy(pVersion->name, "tsmmConfigVersion", CFG_NAME_MAX_LEN);
41,585!
1017
  pVersion->dtype = CFG_DTYPE_INT32;
41,585✔
1018
  pVersion->i32 = tsmmConfigVersion;
41,585✔
1019

1020
  pObj->dtype = dtype;
41,585✔
1021
  tstrncpy(pObj->name, name, CFG_NAME_MAX_LEN);
41,585!
1022

1023
  TAOS_CHECK_GOTO(mndUpdateObj(pObj, name, pValue), &lino, _OVER);
41,585!
1024
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "update-config-with-dnode");
41,585✔
1025
  if (pTrans == NULL) {
41,585!
NEW
1026
    code = terrno;
×
NEW
1027
    goto _OVER;
×
1028
  }
1029
  mInfo("trans:%d, used to update config:%s to value:%s and send to dnode", pTrans->id, name, pValue);
41,585!
1030

1031
  // Add commit logs for SDB config updates
1032
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pVersion), &lino, _OVER);
41,585!
1033
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pObj), &lino, _OVER);
41,585!
1034

1035
  if (taosStrncasecmp(name, "syncTimeout", CFG_NAME_MAX_LEN) == 0) {
41,585!
NEW
1036
    TAOS_CHECK_GOTO(mndHandleSyncTimeoutConfigs(pTrans, name, pValue, &lino), &lino, _OVER);
×
1037
  }
1038

1039
  // Add redo actions to send config to dnodes
1040
  SSdb   *pSdb = pMnode->pSdb;
41,585✔
1041
  void   *pIter = NULL;
41,585✔
1042
  int64_t curMs = taosGetTimestampMs();
41,585✔
1043

1044
  while (1) {
48,255✔
1045
    SDnodeObj *pDnode = NULL;
89,840✔
1046
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
89,840✔
1047
    if (pIter == NULL) break;
89,840✔
1048

1049
    if (pDnode->id == dnodeId || dnodeId == -1 || dnodeId == 0) {
48,255!
1050
      bool online = mndIsDnodeOnline(pDnode, curMs);
48,255✔
1051
      if (!online) {
48,255!
NEW
1052
        mWarn("dnode:%d, is offline, still add to trans for retry", pDnode->id);
×
1053
      }
1054

1055
      code = mndBuildCfgDnodeRedoAction(pTrans, pDnode, pDcfgReq);
48,255✔
1056
      if (code != 0) {
48,255!
NEW
1057
        mError("failed to build config redo action for dnode:%d, since %s", pDnode->id, tstrerror(code));
×
NEW
1058
        sdbCancelFetch(pMnode->pSdb, pIter);
×
NEW
1059
        sdbRelease(pMnode->pSdb, pDnode);
×
NEW
1060
        goto _OVER;
×
1061
      }
1062
    }
1063
    sdbRelease(pSdb, pDnode);
48,255✔
1064
  }
1065

1066
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
41,585!
1067
  code = 0;
41,585✔
1068

1069
_OVER:
41,585✔
1070
  if (code != 0) {
41,585!
NEW
1071
    mError("failed to update config:%s to value:%s and send to dnode, since %s", name, pValue, tstrerror(code));
×
1072
  }
1073
  mndTransDrop(pTrans);
41,585✔
1074
  tFreeSConfigObj(pVersion);
41,585✔
1075
  taosMemoryFree(pVersion);
41,585!
1076
  tFreeSConfigObj(pObj);
41,585✔
1077
  taosMemoryFree(pObj);
41,585!
1078
  return code;
41,585✔
1079
}
1080

1081
static int32_t initConfigArrayFromSdb(SMnode *pMnode, SArray *array) {
1,575,871✔
1082
  int32_t     code = 0;
1,575,871✔
1083
  SSdb       *pSdb = pMnode->pSdb;
1,575,871✔
1084
  void       *pIter = NULL;
1,575,871✔
1085
  SConfigObj *obj = NULL;
1,575,871✔
1086

1087
  while (1) {
162,255,043✔
1088
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
163,830,914✔
1089
    if (pIter == NULL) break;
163,830,914✔
1090
    if (obj == NULL) {
162,255,043!
1091
      code = TSDB_CODE_OUT_OF_MEMORY;
×
1092
      goto _exit;
×
1093
    }
1094
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
162,255,043✔
1095
      sdbRelease(pSdb, obj);
1,575,871✔
1096
      continue;
1,575,871✔
1097
    }
1098
    SConfigItem item = {0};
160,679,172✔
1099
    item.dtype = obj->dtype;
160,679,172✔
1100
    item.name = taosStrdup(obj->name);
160,679,172!
1101
    if (item.name == NULL) {
160,679,172!
1102
      code = terrno;
×
1103
      sdbCancelFetch(pSdb, pIter);
×
1104
      sdbRelease(pSdb, obj);
×
1105
      goto _exit;
×
1106
    }
1107
    switch (obj->dtype) {
160,679,172!
1108
      case CFG_DTYPE_NONE:
×
1109
        break;
×
1110
      case CFG_DTYPE_BOOL:
29,930,434✔
1111
        item.bval = obj->bval;
29,930,434!
1112
        break;
29,930,434✔
1113
      case CFG_DTYPE_INT32:
89,791,302✔
1114
        item.i32 = obj->i32;
89,791,302✔
1115
        break;
89,791,302✔
1116
      case CFG_DTYPE_INT64:
9,451,716✔
1117
        item.i64 = obj->i64;
9,451,716✔
1118
        break;
9,451,716✔
1119
      case CFG_DTYPE_FLOAT:
3,150,572✔
1120
      case CFG_DTYPE_DOUBLE:
1121
        item.fval = obj->fval;
3,150,572✔
1122
        break;
3,150,572✔
1123
      case CFG_DTYPE_STRING:
28,355,148✔
1124
      case CFG_DTYPE_DIR:
1125
      case CFG_DTYPE_LOCALE:
1126
      case CFG_DTYPE_CHARSET:
1127
      case CFG_DTYPE_TIMEZONE:
1128
        item.str = taosStrdup(obj->str);
28,355,148!
1129
        if (item.str == NULL) {
28,355,148!
1130
          sdbCancelFetch(pSdb, pIter);
×
1131
          sdbRelease(pSdb, obj);
×
1132
          code = terrno;
×
1133
          goto _exit;
×
1134
        }
1135
        break;
28,355,148✔
1136
    }
1137
    if (taosArrayPush(array, &item) == NULL) {
160,679,172!
1138
      sdbCancelFetch(pSdb, pIter);
×
1139
      sdbRelease(pSdb, obj);
×
1140
      code = TSDB_CODE_OUT_OF_MEMORY;
×
1141
      goto _exit;
×
1142
      break;
1143
    }
1144
    sdbRelease(pSdb, obj);
160,679,172✔
1145
  }
1146
_exit:
1,575,871✔
1147
  if (code != 0) {
1,575,871!
1148
    mError("failed to init config array from sdb, since %s", tstrerror(code));
×
1149
  }
1150
  return code;
1,575,871✔
1151
}
1152

1153
static void cfgArrayCleanUp(SArray *array) {
2,017,632✔
1154
  if (array == NULL) {
2,017,632!
1155
    return;
×
1156
  }
1157

1158
  int32_t sz = taosArrayGetSize(array);
2,017,632✔
1159
  for (int32_t i = 0; i < sz; ++i) {
162,696,804✔
1160
    SConfigItem *item = taosArrayGet(array, i);
160,679,172✔
1161
    if (item->dtype == CFG_DTYPE_STRING || item->dtype == CFG_DTYPE_DIR || item->dtype == CFG_DTYPE_LOCALE ||
160,679,172!
1162
        item->dtype == CFG_DTYPE_CHARSET || item->dtype == CFG_DTYPE_TIMEZONE) {
135,474,596✔
1163
      taosMemoryFreeClear(item->str);
28,355,148!
1164
    }
1165
    taosMemoryFreeClear(item->name);
160,679,172!
1166
  }
1167

1168
  taosArrayDestroy(array);
2,017,632✔
1169
}
1170

1171
static void cfgObjArrayCleanUp(SArray *array) {
1,436,340✔
1172
  if (array == NULL) {
1,436,340!
1173
    return;
×
1174
  }
1175
  int32_t sz = taosArrayGetSize(array);
1,436,340✔
1176
  for (int32_t i = 0; i < sz; ++i) {
1,436,340!
1177
    SConfigObj *obj = taosArrayGet(array, i);
×
1178
    tFreeSConfigObj(obj);
×
1179
  }
1180
  taosArrayDestroy(array);
1,436,340✔
1181
}
1182

1183
static SArray *initVariablesFromItems(SArray *pItems, const char* likePattern) {
149,213✔
1184
  if (pItems == NULL) {
149,213!
1185
    return NULL;
×
1186
  }
1187

1188
  int32_t sz = taosArrayGetSize(pItems);
149,213✔
1189

1190
  SArray *pInfos = taosArrayInit(sz, sizeof(SVariablesInfo));
149,213✔
1191
  if (pInfos == NULL) {
149,213!
1192
    mError("failed to init array while init variables from items, since %s", tstrerror(terrno));
×
1193
    return NULL;
×
1194
  }
1195
  for (int32_t i = 0; i < sz; ++i) {
15,368,939✔
1196
    SConfigItem   *pItem = taosArrayGet(pItems, i);
15,219,726✔
1197
    SVariablesInfo info = {0};
15,219,726✔
1198
    tstrncpy(info.name, pItem->name, sizeof(info.name));
15,219,726!
1199
    if (likePattern != NULL && rawStrPatternMatch(pItem->name, likePattern) != TSDB_PATTERN_MATCH) {
15,219,726✔
1200
      continue;
2,815,253✔
1201
    }
1202

1203
    // init info value
1204
    switch (pItem->dtype) {
12,404,473!
1205
      case CFG_DTYPE_NONE:
×
1206
        break;
×
1207
      case CFG_DTYPE_BOOL:
2,302,696✔
1208
        tsnprintf(info.value, sizeof(info.value), "%d", pItem->bval);
2,302,696!
1209
        break;
2,302,696✔
1210
      case CFG_DTYPE_INT32:
6,951,640✔
1211
        tsnprintf(info.value, sizeof(info.value), "%d", pItem->i32);
6,951,640✔
1212
        break;
6,951,640✔
1213
      case CFG_DTYPE_INT64:
725,448✔
1214
        tsnprintf(info.value, sizeof(info.value), "%" PRId64, pItem->i64);
725,448✔
1215
        break;
725,448✔
1216
      case CFG_DTYPE_FLOAT:
241,816✔
1217
      case CFG_DTYPE_DOUBLE:
1218
        tsnprintf(info.value, sizeof(info.value), "%f", pItem->fval);
241,816✔
1219
        break;
241,816✔
1220
      case CFG_DTYPE_STRING:
2,182,873✔
1221
      case CFG_DTYPE_DIR:
1222
      case CFG_DTYPE_LOCALE:
1223
      case CFG_DTYPE_CHARSET:
1224
      case CFG_DTYPE_TIMEZONE:
1225
        tsnprintf(info.value, sizeof(info.value), "%s", pItem->str);
2,182,873✔
1226
        break;
2,182,873✔
1227
    }
1228

1229
    // init info scope
1230
    switch (pItem->scope) {
12,404,473!
1231
      case CFG_SCOPE_SERVER:
9,864,320✔
1232
        tstrncpy(info.scope, "server", sizeof(info.scope));
9,864,320✔
1233
        break;
9,864,320✔
1234
      case CFG_SCOPE_CLIENT:
×
1235
        tstrncpy(info.scope, "client", sizeof(info.scope));
×
1236
        break;
×
1237
      case CFG_SCOPE_BOTH:
2,540,153✔
1238
        tstrncpy(info.scope, "both", sizeof(info.scope));
2,540,153✔
1239
        break;
2,540,153✔
1240
      default:
×
1241
        tstrncpy(info.scope, "unknown", sizeof(info.scope));
×
1242
        break;
×
1243
    }
1244
    // init info category
1245
    switch (pItem->category) {
12,404,473!
1246
      case CFG_CATEGORY_GLOBAL:
12,404,473✔
1247
        tstrncpy(info.category, "global", sizeof(info.category));
12,404,473✔
1248
        break;
12,404,473✔
1249
      case CFG_CATEGORY_LOCAL:
×
1250
        tstrncpy(info.category, "local", sizeof(info.category));
×
1251
        break;
×
1252
      default:
×
1253
        tstrncpy(info.category, "unknown", sizeof(info.category));
×
1254
        break;
×
1255
    }
1256
    if (NULL == taosArrayPush(pInfos, &info)) {
12,404,473!
1257
      mError("failed to push info to array while init variables from items,since %s", tstrerror(terrno));
×
1258
      taosArrayDestroy(pInfos);
×
1259
      return NULL;
×
1260
    }
1261
  }
1262

1263
  return pInfos;
149,213✔
1264
}
1265

1266
static int32_t mndProcessShowVariablesReq(SRpcMsg *pReq) {
149,213✔
1267
  SShowVariablesRsp rsp = {0};
149,213✔
1268
  int32_t           code = TSDB_CODE_SUCCESS;
149,213✔
1269
  SShowVariablesReq req = {0};
149,213✔
1270
  SArray           *array = NULL;
149,213✔
1271

1272
  code = tDeserializeSShowVariablesReq(pReq->pCont, pReq->contLen, &req);
149,213✔
1273
  if (code != 0) {
149,213!
1274
    mError("failed to deserialize config req, since %s", terrstr());
×
1275
    goto _OVER;
×
1276
  }
1277

1278
  if ((code = mndCheckOperPrivilege(pReq->info.node, pReq->info.conn.user, MND_OPER_SHOW_VARIABLES)) != 0) {
149,213!
1279
    goto _OVER;
×
1280
  }
1281

1282
  SVariablesInfo info = {0};
149,213✔
1283
  char          *likePattern = req.opType == OP_TYPE_LIKE ? req.val : NULL;
149,213✔
1284
  rsp.variables = initVariablesFromItems(taosGetGlobalCfg(tsCfg), likePattern);
149,213✔
1285
  if (rsp.variables == NULL) {
149,213!
1286
    code = terrno;
×
1287
    goto _OVER;
×
1288
  }
1289
  int32_t rspLen = tSerializeSShowVariablesRsp(NULL, 0, &rsp);
149,213✔
1290
  void   *pRsp = rpcMallocCont(rspLen);
149,213✔
1291
  if (pRsp == NULL) {
149,213!
1292
    code = terrno;
×
1293
    goto _OVER;
×
1294
  }
1295

1296
  if ((rspLen = tSerializeSShowVariablesRsp(pRsp, rspLen, &rsp)) <= 0) {
149,213!
1297
    rpcFreeCont(pRsp);
×
1298
    code = rspLen;
×
1299
    goto _OVER;
×
1300
  }
1301

1302
  pReq->info.rspLen = rspLen;
149,213✔
1303
  pReq->info.rsp = pRsp;
149,213✔
1304
  code = 0;
149,213✔
1305

1306
_OVER:
149,213✔
1307

1308
  if (code != 0) {
149,213!
1309
    mError("failed to get show variables info since %s", tstrerror(code));
×
1310
  }
1311
  tFreeSShowVariablesReq(&req);
149,213✔
1312
  tFreeSShowVariablesRsp(&rsp);
149,213✔
1313
  TAOS_RETURN(code);
149,213✔
1314
}
1315

1316
int32_t compareSConfigItem(const SConfigObj *item1, SConfigItem *item2, bool *compare) {
×
1317
  *compare = true;
×
1318
  switch (item1->dtype) {
×
1319
    case CFG_DTYPE_BOOL:
×
1320
      if (item1->bval != item2->bval) {
×
1321
        item2->bval = item1->bval;
×
1322
        *compare = false;
×
1323
      }
1324
      break;
×
1325
    case CFG_DTYPE_FLOAT:
×
1326
      if (item1->fval != item2->fval) {
×
1327
        item2->fval = item1->fval;
×
1328
        *compare = false;
×
1329
      }
1330
      break;
×
1331
    case CFG_DTYPE_INT32:
×
1332
      if (item1->i32 != item2->i32) {
×
1333
        item2->i32 = item1->i32;
×
1334
        *compare = false;
×
1335
      }
1336
      break;
×
1337
    case CFG_DTYPE_INT64:
×
1338
      if (item1->i64 != item2->i64) {
×
1339
        item2->i64 = item1->i64;
×
1340
        *compare = false;
×
1341
      }
1342
      break;
×
1343
    case CFG_DTYPE_STRING:
×
1344
    case CFG_DTYPE_DIR:
1345
    case CFG_DTYPE_LOCALE:
1346
    case CFG_DTYPE_CHARSET:
1347
    case CFG_DTYPE_TIMEZONE:
1348
      if (strcmp(item1->str, item2->str) != 0) {
×
1349
        item2->str = taosStrdup(item1->str);
×
1350
        if (item2->str == NULL) {
×
1351
          return TSDB_CODE_OUT_OF_MEMORY;
×
1352
        }
1353
        *compare = false;
×
1354
      }
1355
      break;
×
1356
    default:
×
1357
      *compare = false;
×
1358
      return TSDB_CODE_INVALID_CFG;
×
1359
  }
1360
  return TSDB_CODE_SUCCESS;
×
1361
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc