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

taosdata / TDengine / #4788

14 Oct 2025 11:21AM UTC coverage: 60.992% (-2.3%) from 63.264%
#4788

push

travis-ci

web-flow
Merge 7ca9b50f9 into 19574fe21

154868 of 324306 branches covered (47.75%)

Branch coverage included in aggregate %.

207304 of 269498 relevant lines covered (76.92%)

125773493.22 hits per line

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

46.04
/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
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pInMCfgReq, int32_t optLen, int32_t *pOutValue);
33
static int32_t mndProcessShowVariablesReq(SRpcMsg *pReq);
34
static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq);
35
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp);
36
static int32_t mndProcessConfigReq(SRpcMsg *pReq);
37
static int32_t mndInitWriteCfg(SMnode *pMnode);
38
static int32_t mndSendRebuildReq(SMnode *pMnode);
39
static int32_t mndTryRebuildConfigSdbRsp(SRpcMsg *pRsp);
40
static int32_t initConfigArrayFromSdb(SMnode *pMnode, SArray *array);
41
static int32_t mndTryRebuildConfigSdb(SRpcMsg *pReq);
42
static void    cfgArrayCleanUp(SArray *array);
43
static void    cfgObjArrayCleanUp(SArray *array);
44
int32_t        compareSConfigItemArrays(SMnode *pMnode, const SArray *dArray, SArray *diffArray);
45

46
static int32_t mndConfigUpdateTrans(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
47
                                    int32_t tsmmConfigVersion);
48
static int32_t mndFindConfigsToAdd(SMnode *pMnode, SArray *addArray);
49
static int32_t mndFindConfigsToDelete(SMnode *pMnode, SArray *deleteArray);
50
static int32_t mndExecuteConfigSyncTrans(SMnode *pMnode, SArray *addArray, SArray *deleteArray);
51

52
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *obj);
53
int32_t mndSetDeleteConfigCommitLogs(STrans *pTrans, SConfigObj *item);
54

55
int32_t mndInitConfig(SMnode *pMnode) {
550,964✔
56
  int32_t   code = 0;
550,964✔
57
  SSdbTable table = {.sdbType = SDB_CFG,
550,964✔
58
                     .keyType = SDB_KEY_BINARY,
59
                     .encodeFp = (SdbEncodeFp)mnCfgActionEncode,
60
                     .decodeFp = (SdbDecodeFp)mndCfgActionDecode,
61
                     .insertFp = (SdbInsertFp)mndCfgActionInsert,
62
                     .updateFp = (SdbUpdateFp)mndCfgActionUpdate,
63
                     .deleteFp = (SdbDeleteFp)mndCfgActionDelete,
64
                     .deployFp = (SdbDeployFp)mndCfgActionDeploy,
65
                     .afterRestoredFp = (SdbAfterRestoredFp)mndCfgActionAfterRestored};
66

67
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG, mndProcessConfigReq);
550,964✔
68
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeReq);
550,964✔
69
  mndSetMsgHandle(pMnode, TDMT_DND_CONFIG_DNODE_RSP, mndProcessConfigDnodeRsp);
550,964✔
70
  mndSetMsgHandle(pMnode, TDMT_MND_SHOW_VARIABLES, mndProcessShowVariablesReq);
550,964✔
71
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB, mndTryRebuildConfigSdb);
550,964✔
72
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB_RSP, mndTryRebuildConfigSdbRsp);
550,964✔
73

74
  return sdbSetTable(pMnode->pSdb, table);
550,964✔
75
}
76

77
SSdbRaw *mnCfgActionEncode(SConfigObj *obj) {
141,597,983✔
78
  int32_t  code = 0;
141,597,983✔
79
  int32_t  lino = 0;
141,597,983✔
80
  void    *buf = NULL;
141,597,983✔
81
  SSdbRaw *pRaw = NULL;
141,597,983✔
82

83
  SEncoder encoder;
141,344,808✔
84
  tEncoderInit(&encoder, NULL, 0);
141,597,983✔
85
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
141,597,983!
86
    tEncoderClear(&encoder);
×
87
    TSDB_CHECK_CODE(code, lino, _over);
×
88
  }
89

90
  int32_t tlen = encoder.pos;
141,597,983✔
91
  tEncoderClear(&encoder);
141,597,983✔
92

93
  int32_t size = sizeof(int32_t) + tlen;
141,597,983✔
94
  pRaw = sdbAllocRaw(SDB_CFG, CFG_VER_NUMBER, size);
141,597,983✔
95
  TSDB_CHECK_NULL(pRaw, code, lino, _over, terrno);
141,597,983!
96

97
  buf = taosMemoryMalloc(tlen);
141,597,983!
98
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
141,597,983!
99

100
  tEncoderInit(&encoder, buf, tlen);
141,597,983✔
101
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
141,597,983!
102
    tEncoderClear(&encoder);
×
103
    TSDB_CHECK_CODE(code, lino, _over);
×
104
  }
105

106
  tEncoderClear(&encoder);
141,597,983✔
107

108
  int32_t dataPos = 0;
141,597,983✔
109
  SDB_SET_INT32(pRaw, dataPos, tlen, _over);
141,597,983!
110
  SDB_SET_BINARY(pRaw, dataPos, buf, tlen, _over);
141,597,983!
111
  SDB_SET_DATALEN(pRaw, dataPos, _over);
141,597,983!
112

113
_over:
141,597,983✔
114
  taosMemoryFreeClear(buf);
141,597,983!
115
  if (code != TSDB_CODE_SUCCESS) {
141,597,983!
116
    mError("cfg:%s, failed to encode to raw:%p at line:%d since %s", obj->name, pRaw, lino, tstrerror(code));
×
117
    sdbFreeRaw(pRaw);
×
118
    terrno = code;
×
119
    return NULL;
×
120
  }
121

122
  terrno = 0;
141,597,983✔
123
  mTrace("cfg:%s, encode to raw:%p, row:%p", obj->name, pRaw, obj);
141,597,983✔
124
  return pRaw;
141,597,983✔
125
}
126

127
SSdbRow *mndCfgActionDecode(SSdbRaw *pRaw) {
56,988,883✔
128
  int32_t     code = 0;
56,988,883✔
129
  int32_t     lino = 0;
56,988,883✔
130
  SSdbRow    *pRow = NULL;
56,988,883✔
131
  SConfigObj *pObj = NULL;
56,988,883✔
132
  void       *buf = NULL;
56,988,883✔
133
  int8_t      sver = 0;
56,988,883✔
134
  int32_t     tlen;
56,846,362✔
135
  int32_t     dataPos = 0;
56,988,883✔
136

137
  code = sdbGetRawSoftVer(pRaw, &sver);
56,988,883✔
138
  TSDB_CHECK_CODE(code, lino, _over);
56,988,883!
139

140
  if (sver != CFG_VER_NUMBER) {
56,988,883!
141
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
142
    goto _over;
×
143
  }
144

145
  pRow = sdbAllocRow(sizeof(SConfigObj));
56,988,883✔
146
  TSDB_CHECK_NULL(pRow, code, lino, _over, terrno);
56,988,883!
147

148
  pObj = sdbGetRowObj(pRow);
56,988,883✔
149
  TSDB_CHECK_NULL(pObj, code, lino, _over, terrno);
56,988,883!
150

151
  SDB_GET_INT32(pRaw, dataPos, &tlen, _over);
56,988,883!
152

153
  buf = taosMemoryMalloc(tlen + 1);
56,988,883!
154
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
56,988,883!
155

156
  SDB_GET_BINARY(pRaw, dataPos, buf, tlen, _over);
56,988,883!
157

158
  SDecoder decoder;
56,846,362✔
159
  tDecoderInit(&decoder, buf, tlen + 1);
56,988,883✔
160
  code = tDecodeSConfigObj(&decoder, pObj);
56,988,883✔
161
  tDecoderClear(&decoder);
56,988,883✔
162

163
  if (code < 0) {
56,988,883!
164
    tFreeSConfigObj(pObj);
×
165
  }
166

167
_over:
56,988,883✔
168
  taosMemoryFreeClear(buf);
56,988,883!
169

170
  if (code != TSDB_CODE_SUCCESS) {
56,988,883!
171
    mError("cfg:%s, failed to decode from raw:%p since %s at:%d", pObj->name, pRaw, tstrerror(code), lino);
×
172
    taosMemoryFreeClear(pRow);
×
173
    terrno = code;
×
174
    return NULL;
×
175
  } else {
176
    mTrace("config:%s, decode from raw:%p, row:%p", pObj->name, pRaw, pObj);
56,988,883✔
177
    terrno = 0;
56,988,883✔
178
    return pRow;
56,988,883✔
179
  }
180
}
181

182
static int32_t mndCfgActionInsert(SSdb *pSdb, SConfigObj *obj) {
56,739,167✔
183
  mTrace("cfg:%s, perform insert action, row:%p", obj->name, obj);
56,739,167✔
184
  return 0;
56,739,167✔
185
}
186

187
static int32_t mndCfgActionDelete(SSdb *pSdb, SConfigObj *obj) {
56,968,592✔
188
  mTrace("cfg:%s, perform delete action, row:%p", obj->name, obj);
56,968,592✔
189
  tFreeSConfigObj(obj);
56,968,592✔
190
  return 0;
56,968,592✔
191
}
192

193
static int32_t mndCfgActionUpdate(SSdb *pSdb, SConfigObj *pOld, SConfigObj *pNew) {
249,716✔
194
  mTrace("cfg:%s, perform update action, old row:%p new row:%p", pOld->name, pOld, pNew);
249,716!
195
  switch (pNew->dtype) {
249,716!
196
    case CFG_DTYPE_NONE:
×
197
      break;
×
198
    case CFG_DTYPE_BOOL:
27,193✔
199
      pOld->bval = pNew->bval;
27,193!
200
      break;
27,193✔
201
    case CFG_DTYPE_INT32:
202,997✔
202
      pOld->i32 = pNew->i32;
202,997✔
203
      break;
202,997✔
204
    case CFG_DTYPE_INT64:
9,865✔
205
      pOld->i64 = pNew->i64;
9,865✔
206
      break;
9,865✔
207
    case CFG_DTYPE_FLOAT:
3,676✔
208
    case CFG_DTYPE_DOUBLE:
209
      pOld->fval = pNew->fval;
3,676✔
210
      break;
3,676✔
211
    case CFG_DTYPE_STRING:
5,985✔
212
    case CFG_DTYPE_DIR:
213
    case CFG_DTYPE_LOCALE:
214
    case CFG_DTYPE_CHARSET:
215
    case CFG_DTYPE_TIMEZONE:
216
      taosMemoryFree(pOld->str);
5,985!
217
      pOld->str = taosStrdup(pNew->str);
5,985!
218
      if (pOld->str == NULL) {
5,985!
219
        return terrno;
×
220
      }
221
      break;
5,985✔
222
  }
223
  return TSDB_CODE_SUCCESS;
249,716✔
224
}
225

226
static int32_t mndCfgActionDeploy(SMnode *pMnode) { return mndInitWriteCfg(pMnode); }
389,041✔
227

228
static int32_t mndCfgActionAfterRestored(SMnode *pMnode) { return mndSendRebuildReq(pMnode); }
262,518✔
229

230
static int32_t mndProcessConfigReq(SRpcMsg *pReq) {
749,825✔
231
  SMnode    *pMnode = pReq->info.node;
749,825✔
232
  SConfigReq configReq = {0};
749,825✔
233
  int32_t    code = TSDB_CODE_SUCCESS;
749,825✔
234
  SArray    *array = NULL;
749,825✔
235
  bool       needFree = false;
749,825✔
236
  code = tDeserializeSConfigReq(pReq->pCont, pReq->contLen, &configReq);
749,825✔
237
  if (code != 0) {
749,825!
238
    mError("failed to deserialize config req, since %s", terrstr());
×
239
    goto _OVER;
×
240
  }
241

242
  SConfigObj *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
749,825✔
243
  if (vObj == NULL) {
749,825!
244
    mInfo("failed to acquire mnd config version, since %s", terrstr());
×
245
    goto _OVER;
×
246
  }
247

248
  array = taosArrayInit(16, sizeof(SConfigItem));
749,825✔
249
  if (array == NULL) {
749,825!
250
    code = TSDB_CODE_OUT_OF_MEMORY;
×
251
    goto _OVER;
×
252
  }
253
  SConfigRsp configRsp = {0};
749,825✔
254
  configRsp.cver = vObj->i32;
749,825✔
255

256
  if (configReq.cver == vObj->i32) {
749,825✔
257
    configRsp.isVersionVerified = 1;
175,289✔
258
  } else {
259
    code = initConfigArrayFromSdb(pMnode, array);
574,536✔
260
    if (code != 0) {
574,536!
261
      mError("failed to init config array from sdb, since %s", tstrerror(code));
×
262
      goto _OVER;
×
263
    }
264
    configRsp.array = array;
574,536✔
265
  }
266

267
  int32_t contLen = tSerializeSConfigRsp(NULL, 0, &configRsp);
749,825✔
268
  if (contLen < 0) {
749,825!
269
    code = contLen;
×
270
    goto _OVER;
×
271
  }
272
  void *pHead = rpcMallocCont(contLen);
749,825✔
273
  if (pHead == NULL) {
749,825!
274
    code = TSDB_CODE_OUT_OF_MEMORY;
×
275
    goto _OVER;
×
276
  }
277
  contLen = tSerializeSConfigRsp(pHead, contLen, &configRsp);
749,825✔
278
  if (contLen < 0) {
749,825!
279
    rpcFreeCont(pHead);
×
280
    code = contLen;
×
281
    goto _OVER;
×
282
  }
283
  pReq->info.rspLen = contLen;
749,825✔
284
  pReq->info.rsp = pHead;
749,825✔
285

286
_OVER:
749,825✔
287
  if (code != 0) {
749,825!
288
    mError("failed to process config req, since %s", tstrerror(code));
×
289
  }
290
  sdbRelease(pMnode->pSdb, vObj);
749,825✔
291
  cfgArrayCleanUp(array);
749,825✔
292
  tFreeSConfigReq(&configReq);
749,825✔
293
  return code;
749,825✔
294
}
295

296
int32_t mndInitWriteCfg(SMnode *pMnode) {
389,041✔
297
  int    code = 0;
389,041✔
298
  size_t sz = 0;
389,041✔
299

300
  mInfo("init write cfg to sdb");
389,041!
301
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "init-write-config");
389,041✔
302
  if (pTrans == NULL) {
389,041!
303
    mError("failed to init write cfg in create trans, since %s", terrstr());
×
304
    goto _OVER;
×
305
  }
306

307
  // encode mnd config version
308
  SConfigObj versionObj = mndInitConfigVersion();
389,041✔
309
  if ((code = mndSetCreateConfigCommitLogs(pTrans, &versionObj)) != 0) {
389,041!
310
    mError("failed to init mnd config version, since %s", tstrerror(code));
×
311
    tFreeSConfigObj(&versionObj);
×
312
    goto _OVER;
×
313
  }
314
  tFreeSConfigObj(&versionObj);
389,041✔
315
  sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
389,041✔
316

317
  for (int i = 0; i < sz; ++i) {
40,063,879✔
318
    SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
39,674,838✔
319
    SConfigObj   obj;
39,608,844✔
320
    if ((code = mndInitConfigObj(item, &obj)) != 0) {
39,674,838!
321
      goto _OVER;
×
322
    }
323
    if ((code = mndSetCreateConfigCommitLogs(pTrans, &obj)) != 0) {
39,674,838!
324
      mError("failed to init mnd config:%s, since %s", item->name, tstrerror(code));
×
325
      tFreeSConfigObj(&obj);
×
326
      goto _OVER;
×
327
    }
328
    tFreeSConfigObj(&obj);
39,674,838✔
329
  }
330
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
389,041!
331

332
_OVER:
389,041✔
333
  if (code != 0) {
389,041!
334
    mError("failed to init write cfg, since %s", tstrerror(code));
×
335
  }
336
  mndTransDrop(pTrans);
389,041✔
337
  return code;
389,041✔
338
}
339

340
int32_t mndSendRebuildReq(SMnode *pMnode) {
262,518✔
341
  int32_t code = 0;
262,518✔
342

343
  SRpcMsg rpcMsg = {.pCont = NULL,
262,518✔
344
                    .contLen = 0,
345
                    .msgType = TDMT_MND_CONFIG_SDB,
346
                    .info.ahandle = 0,
347
                    .info.notFreeAhandle = 1,
348
                    .info.refId = 0,
349
                    .info.noResp = 0,
350
                    .info.handle = 0};
351
  SEpSet  epSet = {0};
262,518✔
352

353
  mndGetMnodeEpSet(pMnode, &epSet);
262,518✔
354

355
  code = tmsgSendReq(&epSet, &rpcMsg);
262,518✔
356
  if (code != 0) {
262,518!
357
    mError("failed to send rebuild config req, since %s", tstrerror(code));
×
358
  }
359
  return code;
262,518✔
360
}
361

362
static int32_t mndTryRebuildConfigSdb(SRpcMsg *pReq) {
261,722✔
363
  SMnode *pMnode = pReq->info.node;
261,722✔
364
  if (!mndIsLeader(pMnode)) {
261,722!
365
    return TSDB_CODE_SUCCESS;
×
366
  }
367

368
  int32_t     code = 0;
261,722✔
369
  SConfigObj *vObj = NULL;
261,722✔
370
  SArray     *addArray = NULL;
261,722✔
371
  SArray     *deleteArray = NULL;
261,722✔
372

373
  vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
261,722✔
374
  if (vObj == NULL) {
261,722!
375
    code = mndInitWriteCfg(pMnode);
×
376
    if (code < 0) {
×
377
      mError("failed to init write cfg, since %s", tstrerror(code));
×
378
    } else {
379
      mInfo("failed to acquire mnd config version, try to rebuild config in sdb.");
×
380
    }
381
    goto _exit;
×
382
  }
383

384
  addArray = taosArrayInit(4, sizeof(SConfigObj));
261,722✔
385
  deleteArray = taosArrayInit(4, sizeof(SConfigObj));
261,722✔
386
  if (addArray == NULL || deleteArray == NULL) {
261,722!
387
    code = TSDB_CODE_OUT_OF_MEMORY;
×
388
    goto _exit;
×
389
  }
390

391
  // Find configs to add and delete
392
  if ((code = mndFindConfigsToAdd(pMnode, addArray)) != 0) {
261,722!
393
    mError("failed to find configs to add, since %s", tstrerror(code));
×
394
    goto _exit;
×
395
  }
396

397
  if ((code = mndFindConfigsToDelete(pMnode, deleteArray)) != 0) {
261,722!
398
    mError("failed to find configs to delete, since %s", tstrerror(code));
×
399
    goto _exit;
×
400
  }
401

402
  // Execute the sync transaction
403
  if ((code = mndExecuteConfigSyncTrans(pMnode, addArray, deleteArray)) != 0) {
261,722!
404
    mError("failed to execute config sync transaction, since %s", tstrerror(code));
×
405
    goto _exit;
×
406
  }
407

408
_exit:
261,722✔
409
  if (code != 0) {
261,722!
410
    mError("failed to try rebuild config in sdb, since %s", tstrerror(code));
×
411
  }
412
  sdbRelease(pMnode->pSdb, vObj);
261,722✔
413
  cfgObjArrayCleanUp(addArray);
261,722✔
414
  cfgObjArrayCleanUp(deleteArray);
261,722✔
415
  TAOS_RETURN(code);
261,722✔
416
}
417

418
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *item) {
40,085,683✔
419
  int32_t  code = 0;
40,085,683✔
420
  SSdbRaw *pCommitRaw = mnCfgActionEncode(item);
40,085,683✔
421
  if (pCommitRaw == NULL) {
40,085,683!
422
    code = terrno;
×
423
    TAOS_RETURN(code);
×
424
  }
425
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw) != 0)) TAOS_RETURN(code);
40,085,683!
426
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY)) != 0) TAOS_RETURN(code);
40,085,683!
427
  return TSDB_CODE_SUCCESS;
40,085,683✔
428
}
429

430
int32_t mndSetDeleteConfigCommitLogs(STrans *pTrans, SConfigObj *item) {
×
431
  int32_t  code = 0;
×
432
  SSdbRaw *pCommitRaw = mnCfgActionEncode(item);
×
433
  if (pCommitRaw == NULL) {
×
434
    code = terrno;
×
435
    TAOS_RETURN(code);
×
436
  }
437
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw) != 0)) TAOS_RETURN(code);
×
438
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED)) != 0) TAOS_RETURN(code);
×
439
  return TSDB_CODE_SUCCESS;
×
440
}
441

442
static int32_t mndFindConfigsToAdd(SMnode *pMnode, SArray *addArray) {
261,722✔
443
  int32_t code = 0;
261,722✔
444
  int32_t sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
261,722✔
445

446
  for (int i = 0; i < sz; ++i) {
26,957,366✔
447
    SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
26,695,644✔
448
    SConfigObj  *obj = sdbAcquire(pMnode->pSdb, SDB_CFG, item->name);
26,695,644✔
449
    if (obj == NULL) {
26,695,644!
450
      mInfo("config:%s, not exist in sdb, will add it", item->name);
×
451
      SConfigObj newObj;
×
452
      if ((code = mndInitConfigObj(item, &newObj)) != 0) {
×
453
        TAOS_RETURN(code);
×
454
      }
455
      if (NULL == taosArrayPush(addArray, &newObj)) {
×
456
        tFreeSConfigObj(&newObj);
×
457
        TAOS_RETURN(terrno);
×
458
      }
459
    } else {
460
      sdbRelease(pMnode->pSdb, obj);
26,695,644✔
461
    }
462
  }
463

464
  TAOS_RETURN(TSDB_CODE_SUCCESS);
261,722✔
465
}
466

467
static int32_t mndFindConfigsToDelete(SMnode *pMnode, SArray *deleteArray) {
261,722✔
468
  int32_t     code = 0;
261,722✔
469
  int32_t     sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
261,722✔
470
  SSdb       *pSdb = pMnode->pSdb;
261,722✔
471
  void       *pIter = NULL;
261,722✔
472
  SConfigObj *obj = NULL;
261,722✔
473

474
  while (1) {
26,957,366✔
475
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
27,219,088✔
476
    if (pIter == NULL) break;
27,219,088✔
477
    if (obj == NULL) {
26,957,366!
478
      code = TSDB_CODE_OUT_OF_MEMORY;
×
479
      sdbCancelFetch(pSdb, pIter);
×
480
      TAOS_RETURN(code);
×
481
    }
482

483
    // Skip the version config
484
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
26,957,366✔
485
      sdbRelease(pSdb, obj);
261,722✔
486
      continue;
261,722✔
487
    }
488

489
    // Check if this config exists in global config
490
    bool existsInGlobal = false;
26,695,644✔
491
    for (int i = 0; i < sz; ++i) {
1,374,825,666!
492
      SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
1,374,825,666✔
493
      if (strcasecmp(obj->name, item->name) == 0) {
1,374,825,666!
494
        existsInGlobal = true;
26,695,644✔
495
        break;
26,695,644✔
496
      }
497
    }
498

499
    if (!existsInGlobal) {
26,695,644!
500
      mInfo("config:%s, not exist in global config, will delete it from sdb", obj->name);
×
501
      SConfigObj deleteObj = {0};
×
502
      tstrncpy(deleteObj.name, obj->name, CFG_NAME_MAX_LEN);
×
503
      deleteObj.dtype = obj->dtype;
×
504

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

536
      if (NULL == taosArrayPush(deleteArray, &deleteObj)) {
×
537
        tFreeSConfigObj(&deleteObj);
×
538
        sdbCancelFetch(pSdb, pIter);
×
539
        sdbRelease(pSdb, obj);
×
540
        TAOS_RETURN(terrno);
×
541
      }
542
    }
543

544
    sdbRelease(pSdb, obj);
26,695,644✔
545
  }
546

547
  TAOS_RETURN(TSDB_CODE_SUCCESS);
261,722✔
548
}
549

550
static int32_t mndExecuteConfigSyncTrans(SMnode *pMnode, SArray *addArray, SArray *deleteArray) {
261,722✔
551
  int32_t addSize = taosArrayGetSize(addArray);
261,722✔
552
  int32_t deleteSize = taosArrayGetSize(deleteArray);
261,722✔
553

554
  if (addSize == 0 && deleteSize == 0) {
261,722!
555
    return TSDB_CODE_SUCCESS;
261,722✔
556
  }
557

558
  const char *transName = "sync-config";
×
559
  if (addSize > 0 && deleteSize > 0) {
×
560
    transName = "sync-config";
×
561
  } else if (addSize > 0) {
×
562
    transName = "add-config";
×
563
  } else {
564
    transName = "delete-config";
×
565
  }
566

567
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, transName);
×
568
  if (pTrans == NULL) {
×
569
    TAOS_RETURN(terrno);
×
570
  }
571

572
  int32_t code = 0;
×
573

574
  // Add new configs
575
  for (int i = 0; i < addSize; ++i) {
×
576
    SConfigObj *AddObj = taosArrayGet(addArray, i);
×
577
    if ((code = mndSetCreateConfigCommitLogs(pTrans, AddObj)) != 0) {
×
578
      mndTransDrop(pTrans);
×
579
      TAOS_RETURN(code);
×
580
    }
581
  }
582

583
  // Delete obsolete configs
584
  for (int i = 0; i < deleteSize; ++i) {
×
585
    SConfigObj *DelObj = taosArrayGet(deleteArray, i);
×
586
    if ((code = mndSetDeleteConfigCommitLogs(pTrans, DelObj)) != 0) {
×
587
      mndTransDrop(pTrans);
×
588
      TAOS_RETURN(code);
×
589
    }
590
  }
591

592
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) {
×
593
    mndTransDrop(pTrans);
×
594
    TAOS_RETURN(code);
×
595
  }
596

597
  mInfo("sync config to sdb, add nums:%d, delete nums:%d", addSize, deleteSize);
×
598
  mndTransDrop(pTrans);
×
599
  TAOS_RETURN(TSDB_CODE_SUCCESS);
×
600
}
601

602
static int32_t mndMCfg2DCfg(SMCfgDnodeReq *pMCfgReq, SDCfgDnodeReq *pDCfgReq) {
122,386✔
603
  int32_t code = 0;
122,386✔
604
  char   *p = pMCfgReq->config;
122,386✔
605
  while (*p) {
1,783,326✔
606
    if (*p == ' ') {
1,719,154✔
607
      break;
58,214✔
608
    }
609
    p++;
1,660,940✔
610
  }
611

612
  size_t optLen = p - pMCfgReq->config;
122,386✔
613
  tstrncpy(pDCfgReq->config, pMCfgReq->config, sizeof(pDCfgReq->config));
122,386!
614
  pDCfgReq->config[optLen] = 0;
122,386✔
615

616
  if (' ' == pMCfgReq->config[optLen]) {
122,386✔
617
    // 'key value'
618
    if (strlen(pMCfgReq->value) != 0) goto _err;
58,214!
619
    tstrncpy(pDCfgReq->value, p + 1, sizeof(pDCfgReq->value));
58,214!
620
  } else {
621
    // 'key' 'value'
622
    if (strlen(pMCfgReq->value) == 0) goto _err;
64,172✔
623
    tstrncpy(pDCfgReq->value, pMCfgReq->value, sizeof(pDCfgReq->value));
63,292!
624
  }
625

626
  TAOS_RETURN(code);
121,506✔
627

628
_err:
880✔
629
  mError("dnode:%d, failed to config since invalid conf:%s", pMCfgReq->dnodeId, pMCfgReq->config);
880!
630
  code = TSDB_CODE_INVALID_CFG;
880✔
631
  TAOS_RETURN(code);
880✔
632
}
633

634
static int32_t mndSendCfgDnodeReq(SMnode *pMnode, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
94,026✔
635
  int32_t code = -1;
94,026✔
636
  SSdb   *pSdb = pMnode->pSdb;
94,026✔
637
  void   *pIter = NULL;
94,026✔
638

639
  int64_t curMs = taosGetTimestampMs();
94,026✔
640

641
  while (1) {
232,317✔
642
    SDnodeObj *pDnode = NULL;
326,343✔
643
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
326,343✔
644
    if (pIter == NULL) break;
326,343✔
645

646
    if (pDnode->id == dnodeId || dnodeId == -1 || dnodeId == 0) {
232,716!
647
      bool online = mndIsDnodeOnline(pDnode, curMs);
98,064✔
648
      if (!online) {
98,064!
649
        mWarn("dnode:%d, is offline, skip to send config req", pDnode->id);
×
650
        continue;
×
651
      }
652
      SEpSet  epSet = mndGetDnodeEpset(pDnode);
98,064✔
653
      int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, pDcfgReq);
98,064✔
654
      void   *pBuf = rpcMallocCont(bufLen);
98,064✔
655

656
      if (pBuf == NULL) {
98,064!
657
        sdbCancelFetch(pMnode->pSdb, pIter);
×
658
        sdbRelease(pMnode->pSdb, pDnode);
×
659
        code = TSDB_CODE_OUT_OF_MEMORY;
×
660
        return code;
×
661
      }
662

663
      if ((bufLen = tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq)) <= 0) {
98,064!
664
        sdbCancelFetch(pMnode->pSdb, pIter);
×
665
        sdbRelease(pMnode->pSdb, pDnode);
×
666
        code = bufLen;
×
667
        rpcFreeCont(pBuf);
×
668
        return code;
×
669
      }
670

671
      mInfo("dnode:%d, send config req to dnode, config:%s value:%s", pDnode->id, pDcfgReq->config, pDcfgReq->value);
98,064!
672
      SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pBuf, .contLen = bufLen};
98,064✔
673
      SRpcMsg rpcRsp = {0};
98,064✔
674

675
      code = rpcSendRecvWithTimeout(pMnode->msgCb.statusRpc, &epSet, &rpcMsg, &rpcRsp, NULL, CFG_ALTER_TIMEOUT);
98,064✔
676
      if (code != 0) {
98,064!
677
        mError("failed to send config req to dnode:%d, since %s", pDnode->id, tstrerror(code));
×
678
        sdbCancelFetch(pMnode->pSdb, pIter);
×
679
        sdbRelease(pMnode->pSdb, pDnode);
×
680
        return code;
×
681
      }
682

683
      code = rpcRsp.code;
98,064✔
684
      if (code != 0) {
98,064✔
685
        mError("failed to alter config %s,on dnode:%d, since %s", pDcfgReq->config, pDnode->id, tstrerror(code));
399!
686
        sdbCancelFetch(pMnode->pSdb, pIter);
399✔
687
        sdbRelease(pMnode->pSdb, pDnode);
399✔
688
        return code;
399✔
689
      }
690
      rpcFreeCont(rpcRsp.pCont);
97,665✔
691
    }
692
    sdbRelease(pSdb, pDnode);
232,317✔
693
  }
694

695
  if (code == -1) {
93,627✔
696
    code = TSDB_CODE_MND_DNODE_NOT_EXIST;
2,012✔
697
  }
698
  TAOS_RETURN(code);
93,627✔
699
}
700

701
static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
126,556✔
702
  int32_t       code = 0;
126,556✔
703
  int32_t       lino = -1;
126,556✔
704
  SMnode       *pMnode = pReq->info.node;
126,556✔
705
  SMCfgDnodeReq cfgReq = {0};
126,556✔
706
  SConfigObj   *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
126,556✔
707
  if (vObj == NULL) {
126,556!
708
    code = TSDB_CODE_SDB_OBJ_NOT_THERE;
×
709
    mInfo("failed to acquire mnd config version, since %s", tstrerror(code));
×
710
    goto _err_out;
×
711
  }
712

713
  TAOS_CHECK_RETURN(tDeserializeSMCfgDnodeReq(pReq->pCont, pReq->contLen, &cfgReq));
126,556!
714
  int8_t updateIpWhiteList = 0;
126,556✔
715
  mInfo("dnode:%d, start to config, option:%s, value:%s", cfgReq.dnodeId, cfgReq.config, cfgReq.value);
126,556!
716
  if ((code = mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONFIG_DNODE)) != 0) {
126,556✔
717
    goto _err_out;
3,528✔
718
  }
719

720
  SDCfgDnodeReq dcfgReq = {0};
123,028✔
721
  if (strcasecmp(cfgReq.config, "resetlog") == 0) {
123,028✔
722
    tstrncpy(dcfgReq.config, "resetlog", 9);
642✔
723
    goto _send_req;
642✔
724
#ifdef TD_ENTERPRISE
725
  } else if (strncasecmp(cfgReq.config, "ssblocksize", 12) == 0) {
122,386!
726
    int32_t optLen = strlen("ssblocksize");
×
727
    int32_t flag = -1;
×
728
    int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
×
729
    if (code < 0) {
×
730
      goto _err_out;
×
731
    }
732

733
    if (flag > 1024 * 1024 || (flag > -1 && flag < 1024) || flag < -1) {
×
734
      mError("dnode:%d, failed to config ssblocksize since value:%d. Valid range: -1 or [1024, 1024 * 1024]",
×
735
             cfgReq.dnodeId, flag);
736
      code = TSDB_CODE_INVALID_CFG;
×
737
      goto _err_out;
×
738
    }
739

740
    tstrncpy(dcfgReq.config, "ssblocksize", 12);
×
741
    snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
×
742
#endif
743
  } else {
744
    TAOS_CHECK_GOTO(mndMCfg2DCfg(&cfgReq, &dcfgReq), &lino, _err_out);
122,386✔
745
    if (strlen(dcfgReq.config) > TSDB_DNODE_CONFIG_LEN) {
121,506!
746
      mError("dnode:%d, failed to config since config is too long", cfgReq.dnodeId);
×
747
      code = TSDB_CODE_INVALID_CFG;
×
748
      goto _err_out;
×
749
    }
750
    if (strncasecmp(dcfgReq.config, "enableWhiteList", strlen("enableWhiteList")) == 0) {
121,506✔
751
      updateIpWhiteList = 1;
556✔
752
    }
753

754
    CfgAlterType alterType = (cfgReq.dnodeId == 0 || cfgReq.dnodeId == -1) ? CFG_ALTER_ALL_DNODES : CFG_ALTER_DNODE;
121,506!
755
    TAOS_CHECK_GOTO(cfgCheckRangeForDynUpdate(taosGetCfg(), dcfgReq.config, dcfgReq.value, true, alterType), &lino,
121,506✔
756
                    _err_out);
757
  }
758
  SConfigItem *pItem = cfgGetItem(taosGetCfg(), dcfgReq.config);
93,384✔
759
  // Update config in sdb.
760
  if (pItem == NULL) {
93,384!
761
    mError("failed to find config:%s while process config dnode req", cfgReq.config);
×
762
    code = TSDB_CODE_CFG_NOT_FOUND;
×
763
    goto _err_out;
×
764
  }
765
  if (pItem->category == CFG_CATEGORY_GLOBAL) {
93,384✔
766
    TAOS_CHECK_GOTO(mndConfigUpdateTrans(pMnode, dcfgReq.config, dcfgReq.value, pItem->dtype, ++vObj->i32), &lino,
10,902!
767
                    _err_out);
768
  }
769
_send_req :
94,026✔
770

771
{  // audit
772
  char obj[50] = {0};
94,026✔
773
  (void)tsnprintf(obj, sizeof(obj), "%d", cfgReq.dnodeId);
94,026✔
774

775
  auditRecord(pReq, pMnode->clusterId, "alterDnode", obj, "", cfgReq.sql, cfgReq.sqlLen);
94,026✔
776
}
777
  dcfgReq.version = vObj->i32;
94,026✔
778
  code = mndSendCfgDnodeReq(pMnode, cfgReq.dnodeId, &dcfgReq);
94,026✔
779
  if (code != 0) {
94,026✔
780
    mError("failed to send config req to dnode:%d, since %s", cfgReq.dnodeId, tstrerror(code));
2,411!
781
    goto _err_out;
2,411✔
782
  }
783
  // dont care suss or succ;
784
  if (updateIpWhiteList) mndRefreshUserIpWhiteList(pMnode);
91,615✔
785
  tFreeSMCfgDnodeReq(&cfgReq);
91,615✔
786
  sdbRelease(pMnode->pSdb, vObj);
91,615✔
787
  TAOS_RETURN(code);
91,615✔
788

789
_err_out:
34,941✔
790
  mError("failed to process config dnode req, since %s", tstrerror(code));
34,941!
791
  tFreeSMCfgDnodeReq(&cfgReq);
34,941✔
792
  sdbRelease(pMnode->pSdb, vObj);
34,941✔
793
  TAOS_RETURN(code);
34,941✔
794
}
795

796
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) {
×
797
  mInfo("config rsp from dnode");
×
798
  return 0;
×
799
}
800

801
static int32_t mndTryRebuildConfigSdbRsp(SRpcMsg *pRsp) {
262,142✔
802
  mInfo("rebuild config sdb rsp");
262,142!
803
  return 0;
262,142✔
804
}
805

806
// get int32_t value from 'SMCfgDnodeReq'
807
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pMCfgReq, int32_t optLen, int32_t *pOutValue) {
×
808
  int32_t code = 0;
×
809
  if (' ' != pMCfgReq->config[optLen] && 0 != pMCfgReq->config[optLen]) {
×
810
    goto _err;
×
811
  }
812

813
  if (' ' == pMCfgReq->config[optLen]) {
×
814
    // 'key value'
815
    if (strlen(pMCfgReq->value) != 0) goto _err;
×
816
    *pOutValue = taosStr2Int32(pMCfgReq->config + optLen + 1, NULL, 10);
×
817
  } else {
818
    // 'key' 'value'
819
    if (strlen(pMCfgReq->value) == 0) goto _err;
×
820
    *pOutValue = taosStr2Int32(pMCfgReq->value, NULL, 10);
×
821
  }
822

823
  TAOS_RETURN(code);
×
824

825
_err:
×
826
  mError(" failed to set config since:%s", tstrerror(code));
×
827
  TAOS_RETURN(code);
×
828
}
829

830
static int32_t mndConfigUpdateTrans(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
10,902✔
831
                                    int32_t tsmmConfigVersion) {
832
  int32_t     code = -1;
10,902✔
833
  int32_t     lino = -1;
10,902✔
834
  SConfigObj *pVersion = taosMemoryMalloc(sizeof(SConfigObj)), *pObj = taosMemoryMalloc(sizeof(SConfigObj));
10,902!
835
  if (pVersion == NULL || pObj == NULL) {
10,902!
836
    code = terrno;
×
837
    goto _OVER;
×
838
  }
839
  tstrncpy(pVersion->name, "tsmmConfigVersion", CFG_NAME_MAX_LEN);
10,902!
840
  pVersion->dtype = CFG_DTYPE_INT32;
10,902✔
841
  pVersion->i32 = tsmmConfigVersion;
10,902✔
842

843
  pObj->dtype = dtype;
10,902✔
844
  tstrncpy(pObj->name, name, CFG_NAME_MAX_LEN);
10,902!
845

846
  TAOS_CHECK_GOTO(mndUpdateObj(pObj, name, pValue), &lino, _OVER);
10,902!
847
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, NULL, "update-config");
10,902✔
848
  if (pTrans == NULL) {
10,902!
849
    code = terrno;
×
850
    goto _OVER;
×
851
  }
852
  mInfo("trans:%d, used to update config:%s to value:%s", pTrans->id, name, pValue);
10,902!
853
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pVersion), &lino, _OVER);
10,902!
854
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pObj), &lino, _OVER);
10,902!
855

856
  if (taosStrncasecmp(name, "syncTimeout", CFG_NAME_MAX_LEN) == 0) {
10,902!
857
    SConfigObj *pTmp = NULL;
×
858
    int32_t     syncTimeout = 0;
×
859
    char        tmp[10] = {0};
×
860
    sscanf(pValue, "%d", &syncTimeout);
×
861

862
    sprintf(tmp, "%d", syncTimeout);
×
863

864
    pTmp = taosMemoryMalloc(sizeof(SConfigObj));
×
865
    pTmp->dtype = CFG_DTYPE_INT32;
×
866
    tstrncpy(pTmp->name, "arbSetAssignedTimeoutMs", CFG_NAME_MAX_LEN);
×
867
    TAOS_CHECK_GOTO(mndUpdateObj(pTmp, name, tmp), &lino, _OVER);
×
868
    TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pTmp), &lino, _OVER);
×
869
    tFreeSConfigObj(pTmp);
×
870
    taosMemoryFree(pTmp);
×
871

872
    sprintf(tmp, "%d", syncTimeout / 4);
×
873

874
    pTmp = taosMemoryMalloc(sizeof(SConfigObj));
×
875
    pTmp->dtype = CFG_DTYPE_INT32;
×
876
    tstrncpy(pTmp->name, "arbHeartBeatIntervalMs", CFG_NAME_MAX_LEN);
×
877
    TAOS_CHECK_GOTO(mndUpdateObj(pTmp, name, tmp), &lino, _OVER);
×
878
    TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pTmp), &lino, _OVER);
×
879
    tFreeSConfigObj(pTmp);
×
880
    taosMemoryFree(pTmp);
×
881

882
    pTmp = taosMemoryMalloc(sizeof(SConfigObj));
×
883
    pTmp->dtype = CFG_DTYPE_INT32;
×
884
    tstrncpy(pTmp->name, "arbCheckSyncIntervalMs", CFG_NAME_MAX_LEN);
×
885
    TAOS_CHECK_GOTO(mndUpdateObj(pTmp, name, tmp), &lino, _OVER);
×
886
    TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pTmp), &lino, _OVER);
×
887
    tFreeSConfigObj(pTmp);
×
888
    taosMemoryFree(pTmp);
×
889

890
    sprintf(tmp, "%d", (syncTimeout - syncTimeout / 4) / 2);
×
891

892
    pTmp = taosMemoryMalloc(sizeof(SConfigObj));
×
893
    pTmp->dtype = CFG_DTYPE_INT32;
×
894
    tstrncpy(pTmp->name, "syncVnodeElectIntervalMs", CFG_NAME_MAX_LEN);
×
895
    TAOS_CHECK_GOTO(mndUpdateObj(pTmp, name, tmp), &lino, _OVER);
×
896
    TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pTmp), &lino, _OVER);
×
897
    tFreeSConfigObj(pTmp);
×
898
    taosMemoryFree(pTmp);
×
899

900
    pTmp = taosMemoryMalloc(sizeof(SConfigObj));
×
901
    pTmp->dtype = CFG_DTYPE_INT32;
×
902
    tstrncpy(pTmp->name, "syncMnodeElectIntervalMs", CFG_NAME_MAX_LEN);
×
903
    TAOS_CHECK_GOTO(mndUpdateObj(pTmp, name, tmp), &lino, _OVER);
×
904
    TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pTmp), &lino, _OVER);
×
905
    tFreeSConfigObj(pTmp);
×
906
    taosMemoryFree(pTmp);
×
907

908
    pTmp = taosMemoryMalloc(sizeof(SConfigObj));
×
909
    pTmp->dtype = CFG_DTYPE_INT32;
×
910
    tstrncpy(pTmp->name, "statusTimeoutMs", CFG_NAME_MAX_LEN);
×
911
    TAOS_CHECK_GOTO(mndUpdateObj(pTmp, name, tmp), &lino, _OVER);
×
912
    TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pTmp), &lino, _OVER);
×
913
    tFreeSConfigObj(pTmp);
×
914
    taosMemoryFree(pTmp);
×
915

916
    sprintf(tmp, "%d", (syncTimeout - syncTimeout / 4) / 4);
×
917

918
    pTmp = taosMemoryMalloc(sizeof(SConfigObj));
×
919
    pTmp->dtype = CFG_DTYPE_INT32;
×
920
    tstrncpy(pTmp->name, "statusSRTimeoutMs", CFG_NAME_MAX_LEN);
×
921
    TAOS_CHECK_GOTO(mndUpdateObj(pTmp, name, tmp), &lino, _OVER);
×
922
    TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pTmp), &lino, _OVER);
×
923
    tFreeSConfigObj(pTmp);
×
924
    taosMemoryFree(pTmp);
×
925

926
    sprintf(tmp, "%d", (syncTimeout - syncTimeout / 4) / 8);
×
927

928
    pTmp = taosMemoryMalloc(sizeof(SConfigObj));
×
929
    pTmp->dtype = CFG_DTYPE_INT32;
×
930
    tstrncpy(pTmp->name, "syncVnodeHeartbeatIntervalMs", CFG_NAME_MAX_LEN);
×
931
    TAOS_CHECK_GOTO(mndUpdateObj(pTmp, name, tmp), &lino, _OVER);
×
932
    TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pTmp), &lino, _OVER);
×
933
    tFreeSConfigObj(pTmp);
×
934
    taosMemoryFree(pTmp);
×
935

936
    pTmp = taosMemoryMalloc(sizeof(SConfigObj));
×
937
    pTmp->dtype = CFG_DTYPE_INT32;
×
938
    tstrncpy(pTmp->name, "syncMnodeHeartbeatIntervalMs", CFG_NAME_MAX_LEN);
×
939
    TAOS_CHECK_GOTO(mndUpdateObj(pTmp, name, tmp), &lino, _OVER);
×
940
    TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pTmp), &lino, _OVER);
×
941
    tFreeSConfigObj(pTmp);
×
942
    taosMemoryFree(pTmp);
×
943

944
    pTmp = taosMemoryMalloc(sizeof(SConfigObj));
×
945
    pTmp->dtype = CFG_DTYPE_INT32;
×
946
    tstrncpy(pTmp->name, "statusIntervalMs", CFG_NAME_MAX_LEN);
×
947
    TAOS_CHECK_GOTO(mndUpdateObj(pTmp, name, tmp), &lino, _OVER);
×
948
    TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pTmp), &lino, _OVER);
×
949
    tFreeSConfigObj(pTmp);
×
950
    taosMemoryFree(pTmp);
×
951
  }
952
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
10,902!
953
  code = 0;
10,902✔
954
_OVER:
10,902✔
955
  if (code != 0) {
10,902!
956
    mError("failed to update config:%s to value:%s, since %s", name, pValue, tstrerror(code));
×
957
  }
958
  mndTransDrop(pTrans);
10,902✔
959
  tFreeSConfigObj(pVersion);
10,902✔
960
  taosMemoryFree(pVersion);
10,902!
961
  tFreeSConfigObj(pObj);
10,902✔
962
  taosMemoryFree(pObj);
10,902!
963
  return code;
10,902✔
964
}
965

966
static int32_t initConfigArrayFromSdb(SMnode *pMnode, SArray *array) {
574,536✔
967
  int32_t     code = 0;
574,536✔
968
  SSdb       *pSdb = pMnode->pSdb;
574,536✔
969
  void       *pIter = NULL;
574,536✔
970
  SConfigObj *obj = NULL;
574,536✔
971

972
  while (1) {
59,168,028✔
973
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
59,742,564✔
974
    if (pIter == NULL) break;
59,742,564✔
975
    if (obj == NULL) {
59,168,028!
976
      code = TSDB_CODE_OUT_OF_MEMORY;
×
977
      goto _exit;
×
978
    }
979
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
59,168,028✔
980
      sdbRelease(pSdb, obj);
574,536✔
981
      continue;
574,536✔
982
    }
983
    SConfigItem item = {0};
58,593,492✔
984
    item.dtype = obj->dtype;
58,593,492✔
985
    item.name = taosStrdup(obj->name);
58,593,492!
986
    if (item.name == NULL) {
58,593,492!
987
      code = terrno;
×
988
      sdbCancelFetch(pSdb, pIter);
×
989
      sdbRelease(pSdb, obj);
×
990
      goto _exit;
×
991
    }
992
    switch (obj->dtype) {
58,593,492!
993
      case CFG_DTYPE_NONE:
×
994
        break;
×
995
      case CFG_DTYPE_BOOL:
10,914,474✔
996
        item.bval = obj->bval;
10,914,474!
997
        break;
10,914,474✔
998
      case CFG_DTYPE_INT32:
32,743,422✔
999
        item.i32 = obj->i32;
32,743,422✔
1000
        break;
32,743,422✔
1001
      case CFG_DTYPE_INT64:
3,446,676✔
1002
        item.i64 = obj->i64;
3,446,676✔
1003
        break;
3,446,676✔
1004
      case CFG_DTYPE_FLOAT:
1,148,892✔
1005
      case CFG_DTYPE_DOUBLE:
1006
        item.fval = obj->fval;
1,148,892✔
1007
        break;
1,148,892✔
1008
      case CFG_DTYPE_STRING:
10,340,028✔
1009
      case CFG_DTYPE_DIR:
1010
      case CFG_DTYPE_LOCALE:
1011
      case CFG_DTYPE_CHARSET:
1012
      case CFG_DTYPE_TIMEZONE:
1013
        item.str = taosStrdup(obj->str);
10,340,028!
1014
        if (item.str == NULL) {
10,340,028!
1015
          sdbCancelFetch(pSdb, pIter);
×
1016
          sdbRelease(pSdb, obj);
×
1017
          code = terrno;
×
1018
          goto _exit;
×
1019
        }
1020
        break;
10,340,028✔
1021
    }
1022
    if (taosArrayPush(array, &item) == NULL) {
58,593,492!
1023
      sdbCancelFetch(pSdb, pIter);
×
1024
      sdbRelease(pSdb, obj);
×
1025
      code = TSDB_CODE_OUT_OF_MEMORY;
×
1026
      goto _exit;
×
1027
      break;
1028
    }
1029
    sdbRelease(pSdb, obj);
58,593,492✔
1030
  }
1031
_exit:
574,536✔
1032
  if (code != 0) {
574,536!
1033
    mError("failed to init config array from sdb, since %s", tstrerror(code));
×
1034
  }
1035
  return code;
574,536✔
1036
}
1037

1038
static void cfgArrayCleanUp(SArray *array) {
749,825✔
1039
  if (array == NULL) {
749,825!
1040
    return;
×
1041
  }
1042

1043
  int32_t sz = taosArrayGetSize(array);
749,825✔
1044
  for (int32_t i = 0; i < sz; ++i) {
59,343,317✔
1045
    SConfigItem *item = taosArrayGet(array, i);
58,593,492✔
1046
    if (item->dtype == CFG_DTYPE_STRING || item->dtype == CFG_DTYPE_DIR || item->dtype == CFG_DTYPE_LOCALE ||
58,593,492!
1047
        item->dtype == CFG_DTYPE_CHARSET || item->dtype == CFG_DTYPE_TIMEZONE) {
49,402,356✔
1048
      taosMemoryFreeClear(item->str);
10,340,028!
1049
    }
1050
    taosMemoryFreeClear(item->name);
58,593,492!
1051
  }
1052

1053
  taosArrayDestroy(array);
749,825✔
1054
}
1055

1056
static void cfgObjArrayCleanUp(SArray *array) {
523,444✔
1057
  if (array == NULL) {
523,444!
1058
    return;
×
1059
  }
1060
  int32_t sz = taosArrayGetSize(array);
523,444✔
1061
  for (int32_t i = 0; i < sz; ++i) {
523,444!
1062
    SConfigObj *obj = taosArrayGet(array, i);
×
1063
    tFreeSConfigObj(obj);
×
1064
  }
1065
  taosArrayDestroy(array);
523,444✔
1066
}
1067

1068
static SArray *initVariablesFromItems(SArray *pItems, const char* likePattern) {
47,194✔
1069
  if (pItems == NULL) {
47,194!
1070
    return NULL;
×
1071
  }
1072

1073
  int32_t sz = taosArrayGetSize(pItems);
47,194✔
1074

1075
  SArray *pInfos = taosArrayInit(sz, sizeof(SVariablesInfo));
47,194✔
1076
  if (pInfos == NULL) {
47,194!
1077
    mError("failed to init array while init variables from items, since %s", tstrerror(terrno));
×
1078
    return NULL;
×
1079
  }
1080
  for (int32_t i = 0; i < sz; ++i) {
4,860,982✔
1081
    SConfigItem   *pItem = taosArrayGet(pItems, i);
4,813,788✔
1082
    SVariablesInfo info = {0};
4,813,788✔
1083
    tstrncpy(info.name, pItem->name, sizeof(info.name));
4,813,788!
1084
    if (likePattern != NULL && rawStrPatternMatch(pItem->name, likePattern) != TSDB_PATTERN_MATCH) {
4,813,788✔
1085
      continue;
598,247✔
1086
    }
1087

1088
    // init info value
1089
    switch (pItem->dtype) {
4,215,541!
1090
      case CFG_DTYPE_NONE:
×
1091
        break;
×
1092
      case CFG_DTYPE_BOOL:
783,585✔
1093
        tsnprintf(info.value, sizeof(info.value), "%d", pItem->bval);
783,585!
1094
        break;
783,585✔
1095
      case CFG_DTYPE_INT32:
2,359,619✔
1096
        tsnprintf(info.value, sizeof(info.value), "%d", pItem->i32);
2,359,619✔
1097
        break;
2,359,619✔
1098
      case CFG_DTYPE_INT64:
247,098✔
1099
        tsnprintf(info.value, sizeof(info.value), "%" PRId64, pItem->i64);
247,098✔
1100
        break;
247,098✔
1101
      case CFG_DTYPE_FLOAT:
82,366✔
1102
      case CFG_DTYPE_DOUBLE:
1103
        tsnprintf(info.value, sizeof(info.value), "%f", pItem->fval);
82,366✔
1104
        break;
82,366✔
1105
      case CFG_DTYPE_STRING:
742,873✔
1106
      case CFG_DTYPE_DIR:
1107
      case CFG_DTYPE_LOCALE:
1108
      case CFG_DTYPE_CHARSET:
1109
      case CFG_DTYPE_TIMEZONE:
1110
        tsnprintf(info.value, sizeof(info.value), "%s", pItem->str);
742,873✔
1111
        break;
742,873✔
1112
    }
1113

1114
    // init info scope
1115
    switch (pItem->scope) {
4,215,541!
1116
      case CFG_SCOPE_SERVER:
3,350,227✔
1117
        tstrncpy(info.scope, "server", sizeof(info.scope));
3,350,227✔
1118
        break;
3,350,227✔
1119
      case CFG_SCOPE_CLIENT:
×
1120
        tstrncpy(info.scope, "client", sizeof(info.scope));
×
1121
        break;
×
1122
      case CFG_SCOPE_BOTH:
865,314✔
1123
        tstrncpy(info.scope, "both", sizeof(info.scope));
865,314✔
1124
        break;
865,314✔
1125
      default:
×
1126
        tstrncpy(info.scope, "unknown", sizeof(info.scope));
×
1127
        break;
×
1128
    }
1129
    // init info category
1130
    switch (pItem->category) {
4,215,541!
1131
      case CFG_CATEGORY_GLOBAL:
4,215,541✔
1132
        tstrncpy(info.category, "global", sizeof(info.category));
4,215,541✔
1133
        break;
4,215,541✔
1134
      case CFG_CATEGORY_LOCAL:
×
1135
        tstrncpy(info.category, "local", sizeof(info.category));
×
1136
        break;
×
1137
      default:
×
1138
        tstrncpy(info.category, "unknown", sizeof(info.category));
×
1139
        break;
×
1140
    }
1141
    if (NULL == taosArrayPush(pInfos, &info)) {
4,215,541!
1142
      mError("failed to push info to array while init variables from items,since %s", tstrerror(terrno));
×
1143
      taosArrayDestroy(pInfos);
×
1144
      return NULL;
×
1145
    }
1146
  }
1147

1148
  return pInfos;
47,194✔
1149
}
1150

1151
static int32_t mndProcessShowVariablesReq(SRpcMsg *pReq) {
47,194✔
1152
  SShowVariablesRsp rsp = {0};
47,194✔
1153
  int32_t           code = TSDB_CODE_SUCCESS;
47,194✔
1154
  SShowVariablesReq req = {0};
47,194✔
1155
  SArray           *array = NULL;
47,194✔
1156

1157
  code = tDeserializeSShowVariablesReq(pReq->pCont, pReq->contLen, &req);
47,194✔
1158
  if (code != 0) {
47,194!
1159
    mError("failed to deserialize config req, since %s", terrstr());
×
1160
    goto _OVER;
×
1161
  }
1162

1163
  if ((code = mndCheckOperPrivilege(pReq->info.node, pReq->info.conn.user, MND_OPER_SHOW_VARIABLES)) != 0) {
47,194!
1164
    goto _OVER;
×
1165
  }
1166

1167
  SVariablesInfo info = {0};
47,194✔
1168
  char          *likePattern = req.opType == OP_TYPE_LIKE ? req.val : NULL;
47,194✔
1169
  rsp.variables = initVariablesFromItems(taosGetGlobalCfg(tsCfg), likePattern);
47,194✔
1170
  if (rsp.variables == NULL) {
47,194!
1171
    code = terrno;
×
1172
    goto _OVER;
×
1173
  }
1174
  int32_t rspLen = tSerializeSShowVariablesRsp(NULL, 0, &rsp);
47,194✔
1175
  void   *pRsp = rpcMallocCont(rspLen);
47,194✔
1176
  if (pRsp == NULL) {
47,194!
1177
    code = terrno;
×
1178
    goto _OVER;
×
1179
  }
1180

1181
  if ((rspLen = tSerializeSShowVariablesRsp(pRsp, rspLen, &rsp)) <= 0) {
47,194!
1182
    rpcFreeCont(pRsp);
×
1183
    code = rspLen;
×
1184
    goto _OVER;
×
1185
  }
1186

1187
  pReq->info.rspLen = rspLen;
47,194✔
1188
  pReq->info.rsp = pRsp;
47,194✔
1189
  code = 0;
47,194✔
1190

1191
_OVER:
47,194✔
1192

1193
  if (code != 0) {
47,194!
1194
    mError("failed to get show variables info since %s", tstrerror(code));
×
1195
  }
1196
  tFreeSShowVariablesReq(&req);
47,194✔
1197
  tFreeSShowVariablesRsp(&rsp);
47,194✔
1198
  TAOS_RETURN(code);
47,194✔
1199
}
1200

1201
int32_t compareSConfigItem(const SConfigObj *item1, SConfigItem *item2, bool *compare) {
×
1202
  *compare = true;
×
1203
  switch (item1->dtype) {
×
1204
    case CFG_DTYPE_BOOL:
×
1205
      if (item1->bval != item2->bval) {
×
1206
        item2->bval = item1->bval;
×
1207
        *compare = false;
×
1208
      }
1209
      break;
×
1210
    case CFG_DTYPE_FLOAT:
×
1211
      if (item1->fval != item2->fval) {
×
1212
        item2->fval = item1->fval;
×
1213
        *compare = false;
×
1214
      }
1215
      break;
×
1216
    case CFG_DTYPE_INT32:
×
1217
      if (item1->i32 != item2->i32) {
×
1218
        item2->i32 = item1->i32;
×
1219
        *compare = false;
×
1220
      }
1221
      break;
×
1222
    case CFG_DTYPE_INT64:
×
1223
      if (item1->i64 != item2->i64) {
×
1224
        item2->i64 = item1->i64;
×
1225
        *compare = false;
×
1226
      }
1227
      break;
×
1228
    case CFG_DTYPE_STRING:
×
1229
    case CFG_DTYPE_DIR:
1230
    case CFG_DTYPE_LOCALE:
1231
    case CFG_DTYPE_CHARSET:
1232
    case CFG_DTYPE_TIMEZONE:
1233
      if (strcmp(item1->str, item2->str) != 0) {
×
1234
        item2->str = taosStrdup(item1->str);
×
1235
        if (item2->str == NULL) {
×
1236
          return TSDB_CODE_OUT_OF_MEMORY;
×
1237
        }
1238
        *compare = false;
×
1239
      }
1240
      break;
×
1241
    default:
×
1242
      *compare = false;
×
1243
      return TSDB_CODE_INVALID_CFG;
×
1244
  }
1245
  return TSDB_CODE_SUCCESS;
×
1246
}
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