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

taosdata / TDengine / #5049

11 May 2026 06:30AM UTC coverage: 73.313% (+0.09%) from 73.222%
#5049

push

travis-ci

web-flow
feat: refactor taosdump code to improve backup speed and compression ratio (#35292)

6625 of 8435 new or added lines in 28 files covered. (78.54%)

2491 existing lines in 142 files now uncovered.

281233 of 383605 relevant lines covered (73.31%)

132489999.79 hits per line

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

59.42
/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 "tcompare.h"
26
#include "tunit.h"
27
#include "tutil.h"
28

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

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

39
extern SConfig *tsCfg;
40

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

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

63
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *obj);
64
int32_t mndSetDeleteConfigCommitLogs(STrans *pTrans, SConfigObj *item);
65
int32_t mndSetCreateConfigPrepareLogs(STrans *pTrans, SConfigObj *obj);
66

67
int32_t mndInitConfig(SMnode *pMnode) {
543,647✔
68
  int32_t   code = 0;
543,647✔
69
  SSdbTable table = {.sdbType = SDB_CFG,
543,647✔
70
                     .keyType = SDB_KEY_BINARY,
71
                     .encodeFp = (SdbEncodeFp)mnCfgActionEncode,
72
                     .decodeFp = (SdbDecodeFp)mndCfgActionDecode,
73
                     .insertFp = (SdbInsertFp)mndCfgActionInsert,
74
                     .updateFp = (SdbUpdateFp)mndCfgActionUpdate,
75
                     .deleteFp = (SdbDeleteFp)mndCfgActionDelete,
76
                     .deployFp = (SdbDeployFp)mndCfgActionDeploy,
77
                     .afterRestoredFp = (SdbAfterRestoredFp)mndCfgActionAfterRestored};
78

79
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG, mndProcessConfigReq);
543,647✔
80
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeReq);
543,647✔
81
  mndSetMsgHandle(pMnode, TDMT_DND_CONFIG_DNODE_RSP, mndTransProcessRsp);
543,647✔
82
  mndSetMsgHandle(pMnode, TDMT_MND_SHOW_VARIABLES, mndProcessShowVariablesReq);
543,647✔
83
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB, mndTryRebuildConfigSdb);
543,647✔
84
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB_RSP, mndTryRebuildConfigSdbRsp);
543,647✔
85

86
  return sdbSetTable(pMnode->pSdb, table);
543,647✔
87
}
88

89
SSdbRaw *mnCfgActionEncode(SConfigObj *obj) {
175,334,891✔
90
  int32_t  code = 0;
175,334,891✔
91
  int32_t  lino = 0;
175,334,891✔
92
  void    *buf = NULL;
175,334,891✔
93
  SSdbRaw *pRaw = NULL;
175,334,891✔
94

95
  SEncoder encoder;
175,271,487✔
96
  tEncoderInit(&encoder, NULL, 0);
175,334,891✔
97
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
175,334,891✔
98
    tEncoderClear(&encoder);
×
UNCOV
99
    TSDB_CHECK_CODE(code, lino, _over);
×
100
  }
101

102
  int32_t tlen = encoder.pos;
175,334,891✔
103
  tEncoderClear(&encoder);
175,334,891✔
104

105
  int32_t size = sizeof(int32_t) + tlen;
175,334,891✔
106
  pRaw = sdbAllocRaw(SDB_CFG, CFG_VER_NUMBER, size);
175,334,891✔
107
  TSDB_CHECK_NULL(pRaw, code, lino, _over, terrno);
175,334,891✔
108

109
  buf = taosMemoryMalloc(tlen);
175,334,891✔
110
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
175,334,891✔
111

112
  tEncoderInit(&encoder, buf, tlen);
175,334,891✔
113
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
175,334,891✔
114
    tEncoderClear(&encoder);
×
UNCOV
115
    TSDB_CHECK_CODE(code, lino, _over);
×
116
  }
117

118
  tEncoderClear(&encoder);
175,334,891✔
119

120
  int32_t dataPos = 0;
175,334,891✔
121
  SDB_SET_INT32(pRaw, dataPos, tlen, _over);
175,334,891✔
122
  SDB_SET_BINARY(pRaw, dataPos, buf, tlen, _over);
175,334,891✔
123
  SDB_SET_DATALEN(pRaw, dataPos, _over);
175,334,891✔
124

125
_over:
175,334,891✔
126
  taosMemoryFreeClear(buf);
175,334,891✔
127
  if (code != TSDB_CODE_SUCCESS) {
175,334,891✔
128
    mError("cfg:%s, failed to encode to raw:%p at line:%d since %s", obj->name, pRaw, lino, tstrerror(code));
×
129
    sdbFreeRaw(pRaw);
×
130
    terrno = code;
×
UNCOV
131
    return NULL;
×
132
  }
133

134
  terrno = 0;
175,334,891✔
135
  mTrace("cfg:%s, encode to raw:%p, row:%p", obj->name, pRaw, obj);
175,334,891✔
136
  return pRaw;
175,334,891✔
137
}
138

139
SSdbRow *mndCfgActionDecode(SSdbRaw *pRaw) {
67,381,812✔
140
  int32_t     code = 0;
67,381,812✔
141
  int32_t     lino = 0;
67,381,812✔
142
  SSdbRow    *pRow = NULL;
67,381,812✔
143
  SConfigObj *pObj = NULL;
67,381,812✔
144
  void       *buf = NULL;
67,381,812✔
145
  int8_t      sver = 0;
67,381,812✔
146
  int32_t     tlen;
67,351,956✔
147
  int32_t     dataPos = 0;
67,381,812✔
148

149
  code = sdbGetRawSoftVer(pRaw, &sver);
67,381,812✔
150
  TSDB_CHECK_CODE(code, lino, _over);
67,381,812✔
151

152
  if (sver != CFG_VER_NUMBER) {
67,381,812✔
153
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
UNCOV
154
    goto _over;
×
155
  }
156

157
  pRow = sdbAllocRow(sizeof(SConfigObj));
67,381,812✔
158
  TSDB_CHECK_NULL(pRow, code, lino, _over, terrno);
67,381,812✔
159

160
  pObj = sdbGetRowObj(pRow);
67,381,812✔
161
  TSDB_CHECK_NULL(pObj, code, lino, _over, terrno);
67,381,812✔
162

163
  SDB_GET_INT32(pRaw, dataPos, &tlen, _over);
67,381,812✔
164

165
  buf = taosMemoryMalloc(tlen + 1);
67,381,812✔
166
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
67,381,812✔
167

168
  SDB_GET_BINARY(pRaw, dataPos, buf, tlen, _over);
67,381,812✔
169

170
  SDecoder decoder;
67,351,956✔
171
  tDecoderInit(&decoder, buf, tlen + 1);
67,381,812✔
172
  code = tDecodeSConfigObj(&decoder, pObj);
67,381,812✔
173
  tDecoderClear(&decoder);
67,381,812✔
174

175
  if (code < 0) {
67,381,812✔
UNCOV
176
    tFreeSConfigObj(pObj);
×
177
  }
178

179
_over:
67,381,812✔
180
  taosMemoryFreeClear(buf);
67,381,812✔
181

182
  if (code != TSDB_CODE_SUCCESS) {
67,381,812✔
183
    mError("cfg:%s, failed to decode from raw:%p since %s at:%d", pObj->name, pRaw, tstrerror(code), lino);
×
184
    taosMemoryFreeClear(pRow);
×
185
    terrno = code;
×
UNCOV
186
    return NULL;
×
187
  } else {
188
    mTrace("config:%s, decode from raw:%p, row:%p", pObj->name, pRaw, pObj);
67,381,812✔
189
    terrno = 0;
67,381,812✔
190
    return pRow;
67,381,812✔
191
  }
192
}
193

194
static int32_t mndCfgActionInsert(SSdb *pSdb, SConfigObj *obj) {
67,216,051✔
195
  mTrace("cfg:%s, perform insert action, row:%p", obj->name, obj);
67,216,051✔
196
  return 0;
67,216,051✔
197
}
198

199
static int32_t mndCfgActionDelete(SSdb *pSdb, SConfigObj *obj) {
67,375,116✔
200
  mTrace("cfg:%s, perform delete action, row:%p", obj->name, obj);
67,375,116✔
201
  tFreeSConfigObj(obj);
67,375,116✔
202
  return 0;
67,375,116✔
203
}
204

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

238
static int32_t mndCfgActionDeploy(SMnode *pMnode) { return mndInitWriteCfg(pMnode); }
388,715✔
239

240
static int32_t mndCfgActionAfterRestored(SMnode *pMnode) { return mndSendRebuildReq(pMnode); }
258,001✔
241

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

254
  SConfigObj *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
750,471✔
255
  if (vObj == NULL) {
750,471✔
256
    mInfo("failed to acquire mnd config version, since %s", terrstr());
×
UNCOV
257
    goto _OVER;
×
258
  }
259

260
  array = taosArrayInit(16, sizeof(SConfigItem));
750,471✔
261
  if (array == NULL) {
750,471✔
262
    code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
263
    goto _OVER;
×
264
  }
265
  SConfigRsp configRsp = {0};
750,471✔
266
  configRsp.cver = vObj->i32;
750,471✔
267

268
  if (configReq.cver == vObj->i32) {
750,471✔
269
    configRsp.isVersionVerified = 1;
166,753✔
270
  } else {
271
    code = initConfigArrayFromSdb(pMnode, array);
583,718✔
272
    if (code != 0) {
583,718✔
273
      mError("failed to init config array from sdb, since %s", tstrerror(code));
×
UNCOV
274
      goto _OVER;
×
275
    }
276
    configRsp.array = array;
583,718✔
277
  }
278

279
  int32_t contLen = tSerializeSConfigRsp(NULL, 0, &configRsp);
750,471✔
280
  if (contLen < 0) {
750,471✔
281
    code = contLen;
×
UNCOV
282
    goto _OVER;
×
283
  }
284
  void *pHead = rpcMallocCont(contLen);
750,471✔
285
  if (pHead == NULL) {
750,471✔
286
    code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
287
    goto _OVER;
×
288
  }
289
  contLen = tSerializeSConfigRsp(pHead, contLen, &configRsp);
750,471✔
290
  if (contLen < 0) {
750,471✔
291
    rpcFreeCont(pHead);
×
292
    code = contLen;
×
UNCOV
293
    goto _OVER;
×
294
  }
295
  pReq->info.rspLen = contLen;
750,471✔
296
  pReq->info.rsp = pHead;
750,471✔
297

298
_OVER:
750,471✔
299
  if (code != 0) {
750,471✔
UNCOV
300
    mError("failed to process config req, since %s", tstrerror(code));
×
301
  }
302
  sdbRelease(pMnode->pSdb, vObj);
750,471✔
303
  cfgArrayCleanUp(array);
750,471✔
304
  tFreeSConfigReq(&configReq);
750,471✔
305
  return code;
750,471✔
306
}
307

308
int32_t mndInitWriteCfg(SMnode *pMnode) {
388,715✔
309
  int    code = 0;
388,715✔
310
  size_t sz = 0;
388,715✔
311

312
  mInfo("init write cfg to sdb");
388,715✔
313
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "init-write-config");
388,715✔
314
  if (pTrans == NULL) {
388,715✔
315
    mError("failed to init write cfg in create trans, since %s", terrstr());
×
UNCOV
316
    goto _OVER;
×
317
  }
318

319
  // encode mnd config version
320
  SConfigObj versionObj = mndInitConfigVersion();
388,715✔
321
  if ((code = mndSetCreateConfigCommitLogs(pTrans, &versionObj)) != 0) {
388,715✔
322
    mError("failed to init mnd config version, since %s", tstrerror(code));
×
323
    tFreeSConfigObj(&versionObj);
×
UNCOV
324
    goto _OVER;
×
325
  }
326
  tFreeSConfigObj(&versionObj);
388,715✔
327
  sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
388,715✔
328

329
  for (int i = 0; i < sz; ++i) {
48,005,828✔
330
    SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
47,617,113✔
331
    SConfigObj   obj;
47,599,893✔
332
    if ((code = mndInitConfigObj(item, &obj)) != 0) {
47,617,113✔
UNCOV
333
      goto _OVER;
×
334
    }
335
    if ((code = mndSetCreateConfigCommitLogs(pTrans, &obj)) != 0) {
47,617,113✔
336
      mError("failed to init mnd config:%s, since %s", item->name, tstrerror(code));
×
337
      tFreeSConfigObj(&obj);
×
UNCOV
338
      goto _OVER;
×
339
    }
340
    tFreeSConfigObj(&obj);
47,617,113✔
341
  }
342
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
388,715✔
343

344
_OVER:
388,715✔
345
  if (code != 0) {
388,715✔
UNCOV
346
    mError("failed to init write cfg, since %s", tstrerror(code));
×
347
  }
348
  mndTransDrop(pTrans);
388,715✔
349
  return code;
388,715✔
350
}
351

352
int32_t mndSendRebuildReq(SMnode *pMnode) {
258,001✔
353
  int32_t code = 0;
258,001✔
354

355
  SRpcMsg rpcMsg = {.pCont = NULL,
258,001✔
356
                    .contLen = 0,
357
                    .msgType = TDMT_MND_CONFIG_SDB,
358
                    .info.ahandle = 0,
359
                    .info.notFreeAhandle = 1,
360
                    .info.refId = 0,
361
                    .info.noResp = 0,
362
                    .info.handle = 0};
363
  SEpSet  epSet = {0};
258,001✔
364

365
  mndGetMnodeEpSet(pMnode, &epSet);
258,001✔
366

367
  code = tmsgSendReq(&epSet, &rpcMsg);
258,001✔
368
  if (code != 0) {
258,001✔
UNCOV
369
    mError("failed to send rebuild config req, since %s", tstrerror(code));
×
370
  }
371
  return code;
258,001✔
372
}
373

374
static int32_t mndTryRebuildConfigSdb(SRpcMsg *pReq) {
257,884✔
375
  SMnode *pMnode = pReq->info.node;
257,884✔
376
  if (!mndIsLeader(pMnode)) {
257,884✔
UNCOV
377
    return TSDB_CODE_SUCCESS;
×
378
  }
379

380
  int32_t     code = 0;
257,884✔
381
  SConfigObj *vObj = NULL;
257,884✔
382
  SArray     *addArray = NULL;
257,884✔
383
  SArray     *deleteArray = NULL;
257,884✔
384

385
  vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
257,884✔
386
  if (vObj == NULL) {
257,884✔
387
    code = mndInitWriteCfg(pMnode);
×
388
    if (code < 0) {
×
UNCOV
389
      mError("failed to init write cfg, since %s", tstrerror(code));
×
390
    } else {
UNCOV
391
      mInfo("failed to acquire mnd config version, try to rebuild config in sdb.");
×
392
    }
UNCOV
393
    goto _exit;
×
394
  }
395

396
  addArray = taosArrayInit(4, sizeof(SConfigObj));
257,884✔
397
  deleteArray = taosArrayInit(4, sizeof(SConfigObj));
257,884✔
398
  if (addArray == NULL || deleteArray == NULL) {
257,884✔
399
    code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
400
    goto _exit;
×
401
  }
402

403
  // Find configs to add and delete
404
  if ((code = mndFindConfigsToAdd(pMnode, addArray)) != 0) {
257,884✔
405
    mError("failed to find configs to add, since %s", tstrerror(code));
×
UNCOV
406
    goto _exit;
×
407
  }
408

409
  if ((code = mndFindConfigsToDelete(pMnode, deleteArray)) != 0) {
257,884✔
410
    mError("failed to find configs to delete, since %s", tstrerror(code));
×
UNCOV
411
    goto _exit;
×
412
  }
413

414
  // Execute the sync transaction
415
  if ((code = mndExecuteConfigSyncTrans(pMnode, addArray, deleteArray)) != 0) {
257,884✔
416
    mError("failed to execute config sync transaction, since %s", tstrerror(code));
×
UNCOV
417
    goto _exit;
×
418
  }
419

420
_exit:
257,884✔
421
  if (code != 0) {
257,884✔
UNCOV
422
    mError("failed to try rebuild config in sdb, since %s", tstrerror(code));
×
423
  }
424
  sdbRelease(pMnode->pSdb, vObj);
257,884✔
425
  cfgObjArrayCleanUp(addArray);
257,884✔
426
  cfgObjArrayCleanUp(deleteArray);
257,884✔
427
  TAOS_RETURN(code);
257,884✔
428
}
429

430
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *item) {
48,039,468✔
431
  int32_t  code = 0;
48,039,468✔
432
  SSdbRaw *pCommitRaw = mnCfgActionEncode(item);
48,039,468✔
433
  if (pCommitRaw == NULL) {
48,039,468✔
434
    code = terrno;
×
UNCOV
435
    TAOS_RETURN(code);
×
436
  }
437
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
48,039,468✔
438
    taosMemoryFree(pCommitRaw);
×
UNCOV
439
    TAOS_RETURN(code);
×
440
  }
441
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY)) != 0) TAOS_RETURN(code);
48,039,468✔
442
  return TSDB_CODE_SUCCESS;
48,039,468✔
443
}
444

445
int32_t mndSetDeleteConfigCommitLogs(STrans *pTrans, SConfigObj *item) {
×
446
  int32_t  code = 0;
×
447
  SSdbRaw *pCommitRaw = mnCfgActionEncode(item);
×
448
  if (pCommitRaw == NULL) {
×
449
    code = terrno;
×
UNCOV
450
    TAOS_RETURN(code);
×
451
  }
452
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
453
    taosMemoryFree(pCommitRaw);
×
UNCOV
454
    TAOS_RETURN(code);
×
455
  }
456
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED)) != 0) TAOS_RETURN(code);
×
UNCOV
457
  return TSDB_CODE_SUCCESS;
×
458
}
459

460
int32_t mndSetCreateConfigPrepareLogs(STrans *pTrans, SConfigObj *item) {
33,640✔
461
  int32_t  code = 0;
33,640✔
462
  SSdbRaw *pPrepareRaw = mnCfgActionEncode(item);
33,640✔
463
  if (pPrepareRaw == NULL) {
33,640✔
464
    code = terrno;
×
UNCOV
465
    TAOS_RETURN(code);
×
466
  }
467
  if ((code = mndTransAppendPrepareLog(pTrans, pPrepareRaw)) != 0) {
33,640✔
468
    taosMemoryFree(pPrepareRaw);
×
UNCOV
469
    TAOS_RETURN(code);
×
470
  }
471
  if ((code = sdbSetRawStatus(pPrepareRaw, SDB_STATUS_READY)) != 0) TAOS_RETURN(code);
33,640✔
472
  return TSDB_CODE_SUCCESS;
33,640✔
473
}
474

475
static int32_t mndFindConfigsToAdd(SMnode *pMnode, SArray *addArray) {
257,884✔
476
  int32_t code = 0;
257,884✔
477
  int32_t sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
257,884✔
478

479
  for (int i = 0; i < sz; ++i) {
31,977,616✔
480
    SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
31,719,732✔
481
    SConfigObj  *obj = sdbAcquire(pMnode->pSdb, SDB_CFG, item->name);
31,719,732✔
482
    if (obj == NULL) {
31,719,732✔
483
      mInfo("config:%s, not exist in sdb, will add it", item->name);
×
484
      SConfigObj newObj;
×
485
      if ((code = mndInitConfigObj(item, &newObj)) != 0) {
×
UNCOV
486
        TAOS_RETURN(code);
×
487
      }
488
      if (NULL == taosArrayPush(addArray, &newObj)) {
×
489
        tFreeSConfigObj(&newObj);
×
UNCOV
490
        TAOS_RETURN(terrno);
×
491
      }
492
    } else {
493
      sdbRelease(pMnode->pSdb, obj);
31,719,732✔
494
    }
495
  }
496

497
  TAOS_RETURN(TSDB_CODE_SUCCESS);
257,884✔
498
}
499

500
static int32_t mndFindConfigsToDelete(SMnode *pMnode, SArray *deleteArray) {
257,884✔
501
  int32_t     code = 0;
257,884✔
502
  int32_t     sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
257,884✔
503
  SSdb       *pSdb = pMnode->pSdb;
257,884✔
504
  void       *pIter = NULL;
257,884✔
505
  SConfigObj *obj = NULL;
257,884✔
506

507
  while (1) {
31,977,616✔
508
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
32,235,500✔
509
    if (pIter == NULL) break;
32,235,500✔
510
    if (obj == NULL) {
31,977,616✔
511
      code = TSDB_CODE_OUT_OF_MEMORY;
×
512
      sdbCancelFetch(pSdb, pIter);
×
UNCOV
513
      TAOS_RETURN(code);
×
514
    }
515

516
    // Skip the version config
517
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
31,977,616✔
518
      sdbRelease(pSdb, obj);
257,884✔
519
      continue;
257,884✔
520
    }
521

522
    // Check if this config exists in global config
523
    bool existsInGlobal = false;
31,719,732✔
524
    for (int i = 0; i < sz; ++i) {
1,966,623,384✔
525
      SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
1,966,623,384✔
526
      if (strcasecmp(obj->name, item->name) == 0) {
1,966,623,384✔
527
        existsInGlobal = true;
31,719,732✔
528
        break;
31,719,732✔
529
      }
530
    }
531

532
    if (!existsInGlobal) {
31,719,732✔
533
      mInfo("config:%s, not exist in global config, will delete it from sdb", obj->name);
×
534
      SConfigObj deleteObj = {0};
×
535
      tstrncpy(deleteObj.name, obj->name, CFG_NAME_MAX_LEN);
×
UNCOV
536
      deleteObj.dtype = obj->dtype;
×
537

538
      // Copy the value based on type
539
      switch (obj->dtype) {
×
540
        case CFG_DTYPE_BOOL:
×
541
          deleteObj.bval = obj->bval;
×
542
          break;
×
543
        case CFG_DTYPE_INT32:
×
544
          deleteObj.i32 = obj->i32;
×
545
          break;
×
546
        case CFG_DTYPE_INT64:
×
547
          deleteObj.i64 = obj->i64;
×
548
          break;
×
UNCOV
549
        case CFG_DTYPE_FLOAT:
×
550
        case CFG_DTYPE_DOUBLE:
551
          deleteObj.fval = obj->fval;
×
552
          break;
×
UNCOV
553
        case CFG_DTYPE_STRING:
×
554
        case CFG_DTYPE_DIR:
555
        case CFG_DTYPE_LOCALE:
556
        case CFG_DTYPE_CHARSET:
557
        case CFG_DTYPE_TIMEZONE:
558
          deleteObj.str = taosStrdup(obj->str);
×
559
          if (deleteObj.str == NULL) {
×
560
            sdbCancelFetch(pSdb, pIter);
×
561
            sdbRelease(pSdb, obj);
×
UNCOV
562
            TAOS_RETURN(terrno);
×
563
          }
564
          break;
×
565
        default:
×
UNCOV
566
          break;
×
567
      }
568

569
      if (NULL == taosArrayPush(deleteArray, &deleteObj)) {
×
570
        tFreeSConfigObj(&deleteObj);
×
571
        sdbCancelFetch(pSdb, pIter);
×
572
        sdbRelease(pSdb, obj);
×
UNCOV
573
        TAOS_RETURN(terrno);
×
574
      }
575
    }
576

577
    sdbRelease(pSdb, obj);
31,719,732✔
578
  }
579

580
  TAOS_RETURN(TSDB_CODE_SUCCESS);
257,884✔
581
}
582

583
static int32_t mndExecuteConfigSyncTrans(SMnode *pMnode, SArray *addArray, SArray *deleteArray) {
257,884✔
584
  int32_t addSize = taosArrayGetSize(addArray);
257,884✔
585
  int32_t deleteSize = taosArrayGetSize(deleteArray);
257,884✔
586

587
  if (addSize == 0 && deleteSize == 0) {
257,884✔
588
    return TSDB_CODE_SUCCESS;
257,884✔
589
  }
590

591
  const char *transName = "sync-config";
×
592
  if (addSize > 0 && deleteSize > 0) {
×
593
    transName = "sync-config";
×
594
  } else if (addSize > 0) {
×
UNCOV
595
    transName = "add-config";
×
596
  } else {
UNCOV
597
    transName = "delete-config";
×
598
  }
599

600
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, transName);
×
601
  if (pTrans == NULL) {
×
UNCOV
602
    TAOS_RETURN(terrno);
×
603
  }
604

UNCOV
605
  int32_t code = 0;
×
606

607
  // Add new configs
608
  for (int i = 0; i < addSize; ++i) {
×
609
    SConfigObj *AddObj = taosArrayGet(addArray, i);
×
610
    if ((code = mndSetCreateConfigCommitLogs(pTrans, AddObj)) != 0) {
×
611
      mndTransDrop(pTrans);
×
UNCOV
612
      TAOS_RETURN(code);
×
613
    }
614
  }
615

616
  // Delete obsolete configs
617
  for (int i = 0; i < deleteSize; ++i) {
×
618
    SConfigObj *DelObj = taosArrayGet(deleteArray, i);
×
619
    if ((code = mndSetDeleteConfigCommitLogs(pTrans, DelObj)) != 0) {
×
620
      mndTransDrop(pTrans);
×
UNCOV
621
      TAOS_RETURN(code);
×
622
    }
623
  }
624

625
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) {
×
626
    mndTransDrop(pTrans);
×
UNCOV
627
    TAOS_RETURN(code);
×
628
  }
629

630
  mInfo("sync config to sdb, add nums:%d, delete nums:%d", addSize, deleteSize);
×
631
  mndTransDrop(pTrans);
×
UNCOV
632
  TAOS_RETURN(TSDB_CODE_SUCCESS);
×
633
}
634

635
static int32_t mndMCfg2DCfg(SMCfgDnodeReq *pMCfgReq, SDCfgDnodeReq *pDCfgReq) {
120,189✔
636
  int32_t code = 0;
120,189✔
637
  char   *p = pMCfgReq->config;
120,189✔
638
  while (*p) {
1,643,330✔
639
    if (*p == ' ') {
1,586,280✔
640
      break;
63,139✔
641
    }
642
    p++;
1,523,141✔
643
  }
644

645
  size_t optLen = p - pMCfgReq->config;
120,189✔
646
  tstrncpy(pDCfgReq->config, pMCfgReq->config, sizeof(pDCfgReq->config));
120,189✔
647
  pDCfgReq->config[optLen] = 0;
120,189✔
648

649
  if (' ' == pMCfgReq->config[optLen]) {
120,189✔
650
    // 'key value'
651
    if (strlen(pMCfgReq->value) != 0) goto _err;
63,139✔
652
    tstrncpy(pDCfgReq->value, p + 1, sizeof(pDCfgReq->value));
63,139✔
653
  } else {
654
    // 'key' 'value'
655
    if (strlen(pMCfgReq->value) == 0) goto _err;
57,050✔
656
    tstrncpy(pDCfgReq->value, pMCfgReq->value, sizeof(pDCfgReq->value));
56,201✔
657
  }
658

659
  TAOS_RETURN(code);
119,340✔
660

661
_err:
849✔
662
  mError("dnode:%d, failed to config since invalid conf:%s", pMCfgReq->dnodeId, pMCfgReq->config);
849✔
663
  code = TSDB_CODE_INVALID_CFG;
849✔
664
  TAOS_RETURN(code);
849✔
665
}
666

667
static int32_t mndBuildCfgDnodeRedoAction(STrans *pTrans, SDnodeObj *pDnode, SDCfgDnodeReq *pDcfgReq) {
18,480✔
668
  int32_t code = 0;
18,480✔
669
  SEpSet  epSet = mndGetDnodeEpset(pDnode);
18,480✔
670
  int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, pDcfgReq);
18,480✔
671
  void   *pBuf = taosMemoryMalloc(bufLen);
18,480✔
672

673
  if (pBuf == NULL) {
18,480✔
674
    code = terrno;
×
UNCOV
675
    return code;
×
676
  }
677

678
  if ((bufLen = tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq)) <= 0) {
18,480✔
679
    code = bufLen;
×
680
    taosMemoryFree(pBuf);
×
UNCOV
681
    return code;
×
682
  }
683

684
  STransAction action = {
18,480✔
685
      .epSet = epSet,
686
      .pCont = pBuf,
687
      .contLen = bufLen,
688
      .msgType = TDMT_DND_CONFIG_DNODE,
689
      .acceptableCode = 0,
690
      .groupId = -1,
691
  };
692

693
  mInfo("dnode:%d, append redo action to trans, config:%s value:%s", pDnode->id, pDcfgReq->config, pDcfgReq->value);
18,480✔
694

695
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
18,480✔
696
    taosMemoryFree(pBuf);
×
UNCOV
697
    return code;
×
698
  }
699

700
  return code;
18,480✔
701
}
702

703
static int32_t mndSendCfgDnodeReq(SMnode *pMnode, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
87,744✔
704
  int32_t code = -1;
87,744✔
705
  SSdb   *pSdb = pMnode->pSdb;
87,744✔
706
  void   *pIter = NULL;
87,744✔
707

708
  int64_t curMs = taosGetTimestampMs();
87,744✔
709

710
  while (1) {
214,520✔
711
    SDnodeObj *pDnode = NULL;
302,264✔
712
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
302,264✔
713
    if (pIter == NULL) break;
302,264✔
714

715
    if (pDnode->id == dnodeId || dnodeId == -1 || dnodeId == 0) {
216,839✔
716
      bool online = mndIsDnodeOnline(pDnode, curMs);
88,498✔
717
      if (!online) {
88,498✔
718
        mWarn("dnode:%d, is offline, skip to send config req", pDnode->id);
34✔
719
        continue;
34✔
720
      }
721
      SEpSet  epSet = mndGetDnodeEpset(pDnode);
88,464✔
722
      int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, pDcfgReq);
88,464✔
723
      void   *pBuf = rpcMallocCont(bufLen);
88,464✔
724

725
      if (pBuf == NULL) {
88,464✔
726
        sdbCancelFetch(pMnode->pSdb, pIter);
×
727
        sdbRelease(pMnode->pSdb, pDnode);
×
728
        code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
729
        return code;
×
730
      }
731

732
      if ((bufLen = tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq)) <= 0) {
88,464✔
733
        sdbCancelFetch(pMnode->pSdb, pIter);
×
734
        sdbRelease(pMnode->pSdb, pDnode);
×
735
        code = bufLen;
×
736
        rpcFreeCont(pBuf);
×
UNCOV
737
        return code;
×
738
      }
739

740
      mInfo("dnode:%d, send config req to dnode, config:%s value:%s", pDnode->id, pDcfgReq->config, pDcfgReq->value);
88,464✔
741
      SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pBuf, .contLen = bufLen};
88,464✔
742
      SRpcMsg rpcRsp = {0};
88,464✔
743

744
      code = rpcSendRecvWithTimeout(pMnode->msgCb.statusRpc, &epSet, &rpcMsg, &rpcRsp, NULL, CFG_ALTER_TIMEOUT);
88,464✔
745
      if (code != 0) {
88,464✔
746
        mError("failed to send config req to dnode:%d, since %s", pDnode->id, tstrerror(code));
×
747
        sdbCancelFetch(pMnode->pSdb, pIter);
×
748
        sdbRelease(pMnode->pSdb, pDnode);
×
UNCOV
749
        return code;
×
750
      }
751

752
      code = rpcRsp.code;
88,464✔
753
      if (code != 0) {
88,464✔
754
        mError("failed to alter config %s,on dnode:%d, since %s", pDcfgReq->config, pDnode->id, tstrerror(code));
2,319✔
755
        sdbCancelFetch(pMnode->pSdb, pIter);
2,319✔
756
        sdbRelease(pMnode->pSdb, pDnode);
2,319✔
757
        return code;
2,319✔
758
      }
759
      rpcFreeCont(rpcRsp.pCont);
86,145✔
760
    }
761
    sdbRelease(pSdb, pDnode);
214,486✔
762
  }
763

764
  if (code == -1) {
85,425✔
765
    code = TSDB_CODE_MND_DNODE_NOT_EXIST;
866✔
766
  }
767
  TAOS_RETURN(code);
85,425✔
768
}
769

770
static int32_t  mndProcessConfigDnodeReq(SRpcMsg *pReq) {
123,510✔
771
  int32_t       code = 0;
123,510✔
772
  int32_t       lino = -1;
123,510✔
773
  SMnode       *pMnode = pReq->info.node;
123,510✔
774
  SMCfgDnodeReq cfgReq = {0};
123,510✔
775
  SUserObj     *pOperUser = NULL;
123,510✔
776
  int64_t       tss = taosGetTimestampMs();
123,510✔
777
  SConfigObj   *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
123,510✔
778
  if (vObj == NULL) {
123,510✔
779
    code = TSDB_CODE_SDB_OBJ_NOT_THERE;
×
780
    mInfo("failed to acquire mnd config version, since %s", tstrerror(code));
×
UNCOV
781
    goto _err_out;
×
782
  }
783

784
  TAOS_CHECK_RETURN(tDeserializeSMCfgDnodeReq(pReq->pCont, pReq->contLen, &cfgReq));
123,510✔
785
  int8_t updateWhiteList = 0;
123,510✔
786
  mInfo("dnode:%d, start to config, option:%s, value:%s", cfgReq.dnodeId, cfgReq.config, cfgReq.value);
123,510✔
787

788
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
123,510✔
789
  if (pOperUser == NULL) {
123,510✔
790
    code = TSDB_CODE_MND_NO_USER_FROM_CONN;
×
UNCOV
791
    goto _err_out;
×
792
  }
793

794
  char configName[TSDB_DNODE_CONFIG_LEN] = {0};
123,510✔
795
  tstrncpy(configName, cfgReq.config, sizeof(configName));
123,510✔
796
  const char *p = strstr(configName, " ");
123,510✔
797
  if (p) *(char *)p = 0;
123,510✔
798
  EPrivType privType = cfgGetPrivType(tsCfg, configName, 0);
123,510✔
799
  if ((code = mndCheckSysObjPrivilege(pMnode, pOperUser, RPC_MSG_TOKEN(pReq), privType, 0, 0, NULL, NULL))) {
123,510✔
800
    goto _err_out;
3,021✔
801
  }
802

803
  SDCfgDnodeReq dcfgReq = {0};
120,489✔
804
  if (strcasecmp(cfgReq.config, "resetlog") == 0) {
120,489✔
805
    tstrncpy(dcfgReq.config, "resetlog", 9);
300✔
806
    goto _send_req;
300✔
807
#ifdef TD_ENTERPRISE
808
  } else if (strncasecmp(cfgReq.config, "ssblocksize", 12) == 0) {
120,189✔
809
    int32_t optLen = strlen("ssblocksize");
×
810
    int32_t flag = -1;
×
811
    int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
×
812
    if (code < 0) {
×
UNCOV
813
      goto _err_out;
×
814
    }
815

816
    if (flag > 1024 * 1024 || (flag > -1 && flag < 1024) || flag < -1) {
×
UNCOV
817
      mError("dnode:%d, failed to config ssblocksize since value:%d. Valid range: -1 or [1024, 1024 * 1024]",
×
818
             cfgReq.dnodeId, flag);
819
      code = TSDB_CODE_INVALID_CFG;
×
UNCOV
820
      goto _err_out;
×
821
    }
822

823
    tstrncpy(dcfgReq.config, "ssblocksize", 12);
×
UNCOV
824
    snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
×
825
#endif
826
  } else {
827
    TAOS_CHECK_GOTO(mndMCfg2DCfg(&cfgReq, &dcfgReq), &lino, _err_out);
120,189✔
828
    if (strlen(dcfgReq.config) > TSDB_DNODE_CONFIG_LEN) {
119,340✔
829
      mError("dnode:%d, failed to config since config is too long", cfgReq.dnodeId);
×
830
      code = TSDB_CODE_INVALID_CFG;
×
UNCOV
831
      goto _err_out;
×
832
    }
833
    if (strncasecmp(dcfgReq.config, "enableWhiteList", strlen("enableWhiteList")) == 0) {
119,340✔
834
      updateWhiteList = 1;
368✔
835
    }
836

837
    CfgAlterType alterType = (cfgReq.dnodeId == 0 || cfgReq.dnodeId == -1) ? CFG_ALTER_ALL_DNODES : CFG_ALTER_DNODE;
119,340✔
838
    TAOS_CHECK_GOTO(cfgCheckRangeForDynUpdate(taosGetCfg(), dcfgReq.config, dcfgReq.value, true, alterType), &lino,
119,340✔
839
                    _err_out);
840
  }
841
  SConfigItem *pItem = cfgGetItem(taosGetCfg(), dcfgReq.config);
104,264✔
842
  // Update config in sdb.
843
  if (pItem == NULL) {
104,264✔
844
    mError("failed to find config:%s while process config dnode req", cfgReq.config);
×
845
    code = TSDB_CODE_CFG_NOT_FOUND;
×
UNCOV
846
    goto _err_out;
×
847
  }
848

849
  // Audit log
850
  if (tsAuditLevel >= AUDIT_LEVEL_SYSTEM) {
104,264✔
851
    char obj[50] = {0};
104,264✔
852
    (void)snprintf(obj, sizeof(obj), "%d", cfgReq.dnodeId);
104,264✔
853
    int64_t tse = taosGetTimestampMs();
104,264✔
854
    double  duration = (double)(tse - tss);
104,264✔
855
    duration = duration / 1000;
104,264✔
856
    auditRecord(pReq, pMnode->clusterId, "alterDnode", obj, "", cfgReq.sql, cfgReq.sqlLen, duration, 0);
104,264✔
857
  }
858

859
  dcfgReq.version = vObj->i32 + 1;
104,264✔
860

861
  if (pItem->category == CFG_CATEGORY_GLOBAL) {
104,264✔
862
    // Use transaction to update SDB and send to dnode atomically
863
    TAOS_CHECK_GOTO(mndConfigUpdateTransWithDnode(pMnode, dcfgReq.config, dcfgReq.value, pItem->dtype, dcfgReq.version,
16,820✔
864
                                                  cfgReq.dnodeId, &dcfgReq),
865
                    &lino, _err_out);
866
  } else {
867
    // For local config, still use the old method (only send to dnode)
868
    goto _send_req;
87,444✔
869
  }
870

871
  // For global config, transaction has handled everything, go to success
872
  goto _success;
16,820✔
873

874
_send_req:
87,744✔
875
  dcfgReq.version = vObj->i32;
87,744✔
876
  code = mndSendCfgDnodeReq(pMnode, cfgReq.dnodeId, &dcfgReq);
87,744✔
877
  if (code != 0) {
87,744✔
878
    mError("failed to send config req to dnode:%d, since %s", cfgReq.dnodeId, tstrerror(code));
3,185✔
879
    goto _err_out;
3,185✔
880
  }
881

882
_success:
101,379✔
883
  // dont care suss or succ;
884
  if (updateWhiteList) {
101,379✔
885
    int32_t dummy1 = mndRefreshUserIpWhiteList(pMnode);
184✔
886
    int32_t dummy2 = mndRefreshUserDateTimeWhiteList(pMnode);
184✔
887
    (void)dummy1;
888
    (void)dummy2;
889
  }
890
  tFreeSMCfgDnodeReq(&cfgReq);
101,379✔
891
  sdbRelease(pMnode->pSdb, vObj);
101,379✔
892
  mndReleaseUser(pMnode, pOperUser);
101,379✔
893
  TAOS_RETURN(code);
101,379✔
894

895
_err_out:
22,131✔
896
  mError("failed to process config dnode req, since %s", tstrerror(code));
22,131✔
897
  tFreeSMCfgDnodeReq(&cfgReq);
22,131✔
898
  sdbRelease(pMnode->pSdb, vObj);
22,131✔
899
  mndReleaseUser(pMnode, pOperUser);
22,131✔
900
  TAOS_RETURN(code);
22,131✔
901
}
902

903
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) {
×
904
  mInfo("config rsp from dnode");
×
UNCOV
905
  return 0;
×
906
}
907

908
static int32_t mndTryRebuildConfigSdbRsp(SRpcMsg *pRsp) {
257,862✔
909
  mInfo("rebuild config sdb rsp");
257,862✔
910
  return 0;
257,862✔
911
}
912

913
// Helper function to create and commit a config object
UNCOV
914
static int32_t mndCreateAndCommitConfigObj(STrans *pTrans, const char *srcName, const char *cfgName, char *value,
×
915
                                           int32_t *lino) {
916
  int32_t     code = 0;
×
917
  SConfigObj *pTmp = taosMemoryMalloc(sizeof(SConfigObj));
×
918
  if (pTmp == NULL) {
×
919
    code = terrno;
×
UNCOV
920
    return code;
×
921
  }
922

923
  pTmp->dtype = CFG_DTYPE_INT32;
×
924
  tstrncpy(pTmp->name, cfgName, CFG_NAME_MAX_LEN);
×
925
  code = mndUpdateObj(pTmp, srcName, value);
×
926
  if (code != 0) {
×
927
    tFreeSConfigObj(pTmp);
×
928
    taosMemoryFree(pTmp);
×
UNCOV
929
    return code;
×
930
  }
931

932
  code = mndSetCreateConfigCommitLogs(pTrans, pTmp);
×
933
  tFreeSConfigObj(pTmp);
×
934
  taosMemoryFree(pTmp);
×
UNCOV
935
  return code;
×
936
}
937

938
// Helper function to handle syncTimeout related config updates
939
static int32_t mndHandleSyncTimeoutConfigs(STrans *pTrans, const char *srcName, const char *pValue, int32_t *lino) {
×
940
  int32_t code = 0;
×
941
  int32_t syncTimeout = 0;
×
UNCOV
942
  char    tmp[10] = {0};
×
943

944
  if (sscanf(pValue, "%d", &syncTimeout) != 1) {
×
UNCOV
945
    syncTimeout = 0;
×
946
  }
947

UNCOV
948
  int32_t baseTimeout = syncTimeout - syncTimeout / SYNC_TIMEOUT_DIVISOR;
×
949

950
  // arbSetAssignedTimeoutMs = syncTimeout
951
  snprintf(tmp, sizeof(tmp), "%d", syncTimeout);
×
UNCOV
952
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "arbSetAssignedTimeoutMs", tmp, lino), lino, _OVER);
×
953

954
  // arbHeartBeatIntervalMs = syncTimeout / 4
955
  snprintf(tmp, sizeof(tmp), "%d", syncTimeout / SYNC_TIMEOUT_DIVISOR);
×
UNCOV
956
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "arbHeartBeatIntervalMs", tmp, lino), lino, _OVER);
×
957

958
  // arbCheckSyncIntervalMs = syncTimeout / 4
UNCOV
959
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "arbCheckSyncIntervalMs", tmp, lino), lino, _OVER);
×
960

961
  // syncVnodeElectIntervalMs = (syncTimeout - syncTimeout / 4) / 2
962
  snprintf(tmp, sizeof(tmp), "%d", baseTimeout / SYNC_TIMEOUT_ELECT_DIVISOR);
×
UNCOV
963
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "syncVnodeElectIntervalMs", tmp, lino), lino, _OVER);
×
964

965
  // syncMnodeElectIntervalMs = (syncTimeout - syncTimeout / 4) / 2
UNCOV
966
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "syncMnodeElectIntervalMs", tmp, lino), lino, _OVER);
×
967

968
  // statusTimeoutMs = (syncTimeout - syncTimeout / 4) / 2
UNCOV
969
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "statusTimeoutMs", tmp, lino), lino, _OVER);
×
970

971
  // statusSRTimeoutMs = (syncTimeout - syncTimeout / 4) / 4
972
  snprintf(tmp, sizeof(tmp), "%d", baseTimeout / SYNC_TIMEOUT_SR_DIVISOR);
×
UNCOV
973
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "statusSRTimeoutMs", tmp, lino), lino, _OVER);
×
974

975
  // syncVnodeHeartbeatIntervalMs = (syncTimeout - syncTimeout / 4) / 8
976
  snprintf(tmp, sizeof(tmp), "%d", baseTimeout / SYNC_TIMEOUT_HB_DIVISOR);
×
UNCOV
977
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "syncVnodeHeartbeatIntervalMs", tmp, lino), lino, _OVER);
×
978

979
  // syncMnodeHeartbeatIntervalMs = (syncTimeout - syncTimeout / 4) / 8
UNCOV
980
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "syncMnodeHeartbeatIntervalMs", tmp, lino), lino, _OVER);
×
981

982
  // statusIntervalMs = (syncTimeout - syncTimeout / 4) / 8
UNCOV
983
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "statusIntervalMs", tmp, lino), lino, _OVER);
×
984

985
_OVER:
×
UNCOV
986
  return code;
×
987
}
988

989
// get int32_t value from 'SMCfgDnodeReq'
990
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pMCfgReq, int32_t optLen, int32_t *pOutValue) {
×
991
  int32_t code = 0;
×
992
  if (' ' != pMCfgReq->config[optLen] && 0 != pMCfgReq->config[optLen]) {
×
UNCOV
993
    goto _err;
×
994
  }
995

UNCOV
996
  if (' ' == pMCfgReq->config[optLen]) {
×
997
    // 'key value'
998
    if (strlen(pMCfgReq->value) != 0) goto _err;
×
UNCOV
999
    *pOutValue = taosStr2Int32(pMCfgReq->config + optLen + 1, NULL, 10);
×
1000
  } else {
1001
    // 'key' 'value'
1002
    if (strlen(pMCfgReq->value) == 0) goto _err;
×
UNCOV
1003
    *pOutValue = taosStr2Int32(pMCfgReq->value, NULL, 10);
×
1004
  }
1005

UNCOV
1006
  TAOS_RETURN(code);
×
1007

1008
_err:
×
1009
  mError(" failed to set config since:%s", tstrerror(code));
×
UNCOV
1010
  TAOS_RETURN(code);
×
1011
}
1012

UNCOV
1013
static int32_t mndConfigUpdateTrans(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
×
1014
                                    int32_t tsmmConfigVersion) {
1015
  int32_t     code = -1;
×
1016
  int32_t     lino = -1;
×
1017
  SConfigObj *pVersion = taosMemoryMalloc(sizeof(SConfigObj)), *pObj = taosMemoryMalloc(sizeof(SConfigObj));
×
1018
  if (pVersion == NULL || pObj == NULL) {
×
1019
    code = terrno;
×
UNCOV
1020
    goto _OVER;
×
1021
  }
1022
  tstrncpy(pVersion->name, "tsmmConfigVersion", CFG_NAME_MAX_LEN);
×
1023
  pVersion->dtype = CFG_DTYPE_INT32;
×
UNCOV
1024
  pVersion->i32 = tsmmConfigVersion;
×
1025

1026
  pObj->dtype = dtype;
×
UNCOV
1027
  tstrncpy(pObj->name, name, CFG_NAME_MAX_LEN);
×
1028

1029
  TAOS_CHECK_GOTO(mndUpdateObj(pObj, name, pValue), &lino, _OVER);
×
1030
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, NULL, "update-config");
×
1031
  if (pTrans == NULL) {
×
1032
    code = terrno;
×
UNCOV
1033
    goto _OVER;
×
1034
  }
1035
  mInfo("trans:%d, used to update config:%s to value:%s", pTrans->id, name, pValue);
×
1036
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pVersion), &lino, _OVER);
×
UNCOV
1037
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pObj), &lino, _OVER);
×
1038

1039
  if (taosStrncasecmp(name, "syncTimeout", CFG_NAME_MAX_LEN) == 0) {
×
UNCOV
1040
    TAOS_CHECK_GOTO(mndHandleSyncTimeoutConfigs(pTrans, name, pValue, &lino), &lino, _OVER);
×
1041
  }
1042
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
×
1043
  code = 0;
×
1044
_OVER:
×
1045
  if (code != 0) {
×
UNCOV
1046
    mError("failed to update config:%s to value:%s, since %s", name, pValue, tstrerror(code));
×
1047
  }
1048
  mndTransDrop(pTrans);
×
1049
  tFreeSConfigObj(pVersion);
×
1050
  taosMemoryFree(pVersion);
×
1051
  tFreeSConfigObj(pObj);
×
1052
  taosMemoryFree(pObj);
×
UNCOV
1053
  return code;
×
1054
}
1055

1056
static int32_t mndConfigUpdateTransWithDnode(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
16,820✔
1057
                                             int32_t tsmmConfigVersion, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
1058
  int32_t     code = -1;
16,820✔
1059
  int32_t     lino = -1;
16,820✔
1060
  SConfigObj *pVersion = taosMemoryMalloc(sizeof(SConfigObj)), *pObj = taosMemoryMalloc(sizeof(SConfigObj));
16,820✔
1061
  if (pVersion == NULL || pObj == NULL) {
16,820✔
1062
    code = terrno;
×
UNCOV
1063
    goto _OVER;
×
1064
  }
1065
  tstrncpy(pVersion->name, "tsmmConfigVersion", CFG_NAME_MAX_LEN);
16,820✔
1066
  pVersion->dtype = CFG_DTYPE_INT32;
16,820✔
1067
  pVersion->i32 = tsmmConfigVersion;
16,820✔
1068

1069
  pObj->dtype = dtype;
16,820✔
1070
  tstrncpy(pObj->name, name, CFG_NAME_MAX_LEN);
16,820✔
1071

1072
  TAOS_CHECK_GOTO(mndUpdateObj(pObj, name, pValue), &lino, _OVER);
16,820✔
1073
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "update-config-with-dnode");
16,820✔
1074
  if (pTrans == NULL) {
16,820✔
1075
    code = terrno;
×
UNCOV
1076
    goto _OVER;
×
1077
  }
1078
  mInfo("trans:%d, used to update config:%s to value:%s and send to dnode", pTrans->id, name, pValue);
16,820✔
1079

1080
  // Add prepare logs for SDB config updates (execute in PREPARE stage, before redo actions)
1081
  TAOS_CHECK_GOTO(mndSetCreateConfigPrepareLogs(pTrans, pVersion), &lino, _OVER);
16,820✔
1082
  TAOS_CHECK_GOTO(mndSetCreateConfigPrepareLogs(pTrans, pObj), &lino, _OVER);
16,820✔
1083

1084
  // Add commit logs for transaction persistence
1085
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pVersion), &lino, _OVER);
16,820✔
1086
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pObj), &lino, _OVER);
16,820✔
1087

1088
  if (taosStrncasecmp(name, "syncTimeout", CFG_NAME_MAX_LEN) == 0) {
16,820✔
UNCOV
1089
    TAOS_CHECK_GOTO(mndHandleSyncTimeoutConfigs(pTrans, name, pValue, &lino), &lino, _OVER);
×
1090
  }
1091

1092
  // Add redo actions to send config to dnodes
1093
  SSdb   *pSdb = pMnode->pSdb;
16,820✔
1094
  void   *pIter = NULL;
16,820✔
1095
  int64_t curMs = taosGetTimestampMs();
16,820✔
1096

1097
  while (1) {
18,480✔
1098
    SDnodeObj *pDnode = NULL;
35,300✔
1099
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
35,300✔
1100
    if (pIter == NULL) break;
35,300✔
1101

1102
    if (pDnode->id == dnodeId || dnodeId == -1 || dnodeId == 0) {
18,480✔
1103
      bool online = mndIsDnodeOnline(pDnode, curMs);
18,480✔
1104
      if (!online) {
18,480✔
1105
        mWarn("dnode:%d, is offline, still add to trans for retry", pDnode->id);
441✔
1106
      }
1107

1108
      code = mndBuildCfgDnodeRedoAction(pTrans, pDnode, pDcfgReq);
18,480✔
1109
      if (code != 0) {
18,480✔
1110
        mError("failed to build config redo action for dnode:%d, since %s", pDnode->id, tstrerror(code));
×
1111
        sdbCancelFetch(pMnode->pSdb, pIter);
×
1112
        sdbRelease(pMnode->pSdb, pDnode);
×
UNCOV
1113
        goto _OVER;
×
1114
      }
1115
    }
1116
    sdbRelease(pSdb, pDnode);
18,480✔
1117
  }
1118

1119
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
16,820✔
1120
  code = 0;
16,820✔
1121

1122
_OVER:
16,820✔
1123
  if (code != 0) {
16,820✔
UNCOV
1124
    mError("failed to update config:%s to value:%s and send to dnode, since %s", name, pValue, tstrerror(code));
×
1125
  }
1126
  mndTransDrop(pTrans);
16,820✔
1127
  tFreeSConfigObj(pVersion);
16,820✔
1128
  taosMemoryFree(pVersion);
16,820✔
1129
  tFreeSConfigObj(pObj);
16,820✔
1130
  taosMemoryFree(pObj);
16,820✔
1131
  return code;
16,820✔
1132
}
1133

1134
static int32_t initConfigArrayFromSdb(SMnode *pMnode, SArray *array) {
583,718✔
1135
  int32_t     code = 0;
583,718✔
1136
  SSdb       *pSdb = pMnode->pSdb;
583,718✔
1137
  void       *pIter = NULL;
583,718✔
1138
  SConfigObj *obj = NULL;
583,718✔
1139

1140
  while (1) {
71,510,930✔
1141
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
72,094,648✔
1142
    if (pIter == NULL) break;
72,094,648✔
1143
    if (obj == NULL) {
71,510,930✔
1144
      code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
1145
      goto _exit;
×
1146
    }
1147
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
71,510,930✔
1148
      sdbRelease(pSdb, obj);
583,718✔
1149
      continue;
583,718✔
1150
    }
1151
    SConfigItem item = {0};
70,927,212✔
1152
    item.dtype = obj->dtype;
70,927,212✔
1153
    item.name = taosStrdup(obj->name);
70,927,212✔
1154
    if (item.name == NULL) {
70,927,212✔
1155
      code = terrno;
×
1156
      sdbCancelFetch(pSdb, pIter);
×
1157
      sdbRelease(pSdb, obj);
×
UNCOV
1158
      goto _exit;
×
1159
    }
1160
    switch (obj->dtype) {
70,927,212✔
1161
      case CFG_DTYPE_NONE:
×
UNCOV
1162
        break;
×
1163
      case CFG_DTYPE_BOOL:
17,299,320✔
1164
        item.bval = obj->bval;
17,299,320✔
1165
        break;
17,299,320✔
1166
      case CFG_DTYPE_INT32:
34,598,640✔
1167
        item.i32 = obj->i32;
34,598,640✔
1168
        break;
34,598,640✔
1169
      case CFG_DTYPE_INT64:
4,036,508✔
1170
        item.i64 = obj->i64;
4,036,508✔
1171
        break;
4,036,508✔
1172
      case CFG_DTYPE_FLOAT:
1,153,288✔
1173
      case CFG_DTYPE_DOUBLE:
1174
        item.fval = obj->fval;
1,153,288✔
1175
        break;
1,153,288✔
1176
      case CFG_DTYPE_STRING:
13,839,456✔
1177
      case CFG_DTYPE_DIR:
1178
      case CFG_DTYPE_LOCALE:
1179
      case CFG_DTYPE_CHARSET:
1180
      case CFG_DTYPE_TIMEZONE:
1181
        item.str = taosStrdup(obj->str);
13,839,456✔
1182
        if (item.str == NULL) {
13,839,456✔
1183
          sdbCancelFetch(pSdb, pIter);
×
1184
          sdbRelease(pSdb, obj);
×
1185
          code = terrno;
×
UNCOV
1186
          goto _exit;
×
1187
        }
1188
        break;
13,839,456✔
1189
    }
1190
    if (taosArrayPush(array, &item) == NULL) {
70,927,212✔
1191
      sdbCancelFetch(pSdb, pIter);
×
1192
      sdbRelease(pSdb, obj);
×
1193
      code = TSDB_CODE_OUT_OF_MEMORY;
×
UNCOV
1194
      goto _exit;
×
1195
      break;
1196
    }
1197
    sdbRelease(pSdb, obj);
70,927,212✔
1198
  }
1199
_exit:
583,718✔
1200
  if (code != 0) {
583,718✔
UNCOV
1201
    mError("failed to init config array from sdb, since %s", tstrerror(code));
×
1202
  }
1203
  return code;
583,718✔
1204
}
1205

1206
static void cfgArrayCleanUp(SArray *array) {
750,471✔
1207
  if (array == NULL) {
750,471✔
UNCOV
1208
    return;
×
1209
  }
1210

1211
  int32_t sz = taosArrayGetSize(array);
750,471✔
1212
  for (int32_t i = 0; i < sz; ++i) {
71,677,683✔
1213
    SConfigItem *item = taosArrayGet(array, i);
70,927,212✔
1214
    if (item->dtype == CFG_DTYPE_STRING || item->dtype == CFG_DTYPE_DIR || item->dtype == CFG_DTYPE_LOCALE ||
70,927,212✔
1215
        item->dtype == CFG_DTYPE_CHARSET || item->dtype == CFG_DTYPE_TIMEZONE) {
58,241,044✔
1216
      taosMemoryFreeClear(item->str);
13,839,456✔
1217
    }
1218
    taosMemoryFreeClear(item->name);
70,927,212✔
1219
  }
1220

1221
  taosArrayDestroy(array);
750,471✔
1222
}
1223

1224
static void cfgObjArrayCleanUp(SArray *array) {
515,768✔
1225
  if (array == NULL) {
515,768✔
UNCOV
1226
    return;
×
1227
  }
1228
  int32_t sz = taosArrayGetSize(array);
515,768✔
1229
  for (int32_t i = 0; i < sz; ++i) {
515,768✔
1230
    SConfigObj *obj = taosArrayGet(array, i);
×
UNCOV
1231
    tFreeSConfigObj(obj);
×
1232
  }
1233
  taosArrayDestroy(array);
515,768✔
1234
}
1235

1236
#ifdef TD_ENTERPRISE
1237
static bool mndShowVarPrivAllowed(uint8_t showPrivMask, int8_t cfgPrivType) {
501,634✔
1238
  switch (cfgPrivType) {
501,634✔
1239
    case CFG_PRIV_SYSTEM:
392,545✔
1240
      return (showPrivMask & SHOW_VAR_PRIV_SYSTEM) != 0;
392,545✔
1241
    case CFG_PRIV_SECURITY:
52,545✔
1242
      return (showPrivMask & SHOW_VAR_PRIV_SECURITY) != 0;
52,545✔
1243
    case CFG_PRIV_AUDIT:
40,548✔
1244
      return (showPrivMask & SHOW_VAR_PRIV_AUDIT) != 0;
40,548✔
1245
    case CFG_PRIV_DEBUG:
15,996✔
1246
      return (showPrivMask & SHOW_VAR_PRIV_DEBUG) != 0;
15,996✔
1247
    default:
×
UNCOV
1248
      return false;
×
1249
  }
1250
}
1251

1252
static uint8_t mndBuildShowVarPrivMask(SMnode *pMnode, SUserObj *pUser, const char *token) {
8,844✔
1253
  static const EPrivType kShowVarPrivTypes[] = {
1254
      PRIV_VAR_SYSTEM_SHOW,
1255
      PRIV_VAR_SECURITY_SHOW,
1256
      PRIV_VAR_AUDIT_SHOW,
1257
      PRIV_VAR_DEBUG_SHOW,
1258
  };
1259

1260
  uint64_t rawMask =
1261
      mndBuildSysPrivBatchMask(pMnode, pUser, token, kShowVarPrivTypes, (int32_t)ARRAY_SIZE(kShowVarPrivTypes));
8,844✔
1262

1263
  uint8_t mask = 0;
8,844✔
1264
  if (rawMask & (1ULL << 0)) mask |= SHOW_VAR_PRIV_SYSTEM;
8,844✔
1265
  if (rawMask & (1ULL << 1)) mask |= SHOW_VAR_PRIV_SECURITY;
8,844✔
1266
  if (rawMask & (1ULL << 2)) mask |= SHOW_VAR_PRIV_AUDIT;
8,844✔
1267
  if (rawMask & (1ULL << 3)) mask |= SHOW_VAR_PRIV_DEBUG;
8,844✔
1268
  return mask;
8,844✔
1269
}
1270
#endif
1271

1272
static SArray *initVariablesFromItems(SArray *pItems, const char* likePattern, uint8_t showPrivMask) {
8,844✔
1273
  if (pItems == NULL) {
8,844✔
UNCOV
1274
    return NULL;
×
1275
  }
1276

1277
  int32_t sz = taosArrayGetSize(pItems);
8,844✔
1278

1279
  SArray *pInfos = taosArrayInit(sz, sizeof(SVariablesInfo));
8,844✔
1280
  if (pInfos == NULL) {
8,844✔
1281
    mError("failed to init array while init variables from items, since %s", tstrerror(terrno));
×
UNCOV
1282
    return NULL;
×
1283
  }
1284
  for (int32_t i = 0; i < sz; ++i) {
1,096,656✔
1285
    SConfigItem   *pItem = taosArrayGet(pItems, i);
1,087,812✔
1286
    SVariablesInfo info = {0};
1,087,812✔
1287
    tstrncpy(info.name, pItem->name, sizeof(info.name));
1,087,812✔
1288
    if (likePattern != NULL && rawStrPatternMatch(pItem->name, likePattern) != TSDB_PATTERN_MATCH) {
1,087,812✔
1289
      continue;
586,178✔
1290
    }
1291
#ifdef TD_ENTERPRISE
1292
    if (!mndShowVarPrivAllowed(showPrivMask, pItem->privType)) {
501,634✔
1293
      continue;
21,264✔
1294
    }
1295
#endif
1296

1297
    // init info value
1298
    switch (pItem->dtype) {
480,370✔
1299
      case CFG_DTYPE_NONE:
×
UNCOV
1300
        break;
×
1301
      case CFG_DTYPE_BOOL:
108,878✔
1302
        snprintf(info.value, sizeof(info.value), "%d", pItem->bval);
108,878✔
1303
        break;
108,878✔
1304
      case CFG_DTYPE_INT32:
244,942✔
1305
        snprintf(info.value, sizeof(info.value), "%d", pItem->i32);
244,942✔
1306
        break;
244,942✔
1307
      case CFG_DTYPE_INT64:
27,993✔
1308
        snprintf(info.value, sizeof(info.value), "%" PRId64, pItem->i64);
27,993✔
1309
        break;
27,993✔
1310
      case CFG_DTYPE_FLOAT:
7,998✔
1311
      case CFG_DTYPE_DOUBLE:
1312
        snprintf(info.value, sizeof(info.value), "%f", pItem->fval);
7,998✔
1313
        break;
7,998✔
1314
      case CFG_DTYPE_STRING:
90,559✔
1315
      case CFG_DTYPE_DIR:
1316
      case CFG_DTYPE_LOCALE:
1317
      case CFG_DTYPE_CHARSET:
1318
      case CFG_DTYPE_TIMEZONE:
1319
        snprintf(info.value, sizeof(info.value), "%s", pItem->str);
90,559✔
1320
        break;
90,559✔
1321
    }
1322

1323
    // init info scope
1324
    switch (pItem->scope) {
480,370✔
1325
      case CFG_SCOPE_SERVER:
398,423✔
1326
        tstrncpy(info.scope, "server", sizeof(info.scope));
398,423✔
1327
        break;
398,423✔
1328
      case CFG_SCOPE_CLIENT:
×
1329
        tstrncpy(info.scope, "client", sizeof(info.scope));
×
UNCOV
1330
        break;
×
1331
      case CFG_SCOPE_BOTH:
81,947✔
1332
        tstrncpy(info.scope, "both", sizeof(info.scope));
81,947✔
1333
        break;
81,947✔
1334
      default:
×
1335
        tstrncpy(info.scope, "unknown", sizeof(info.scope));
×
UNCOV
1336
        break;
×
1337
    }
1338
    // init info category
1339
    switch (pItem->category) {
480,370✔
1340
      case CFG_CATEGORY_GLOBAL:
480,370✔
1341
        tstrncpy(info.category, "global", sizeof(info.category));
480,370✔
1342
        break;
480,370✔
1343
      case CFG_CATEGORY_LOCAL:
×
1344
        tstrncpy(info.category, "local", sizeof(info.category));
×
1345
        break;
×
1346
      default:
×
1347
        tstrncpy(info.category, "unknown", sizeof(info.category));
×
UNCOV
1348
        break;
×
1349
    }
1350
    if (NULL == taosArrayPush(pInfos, &info)) {
480,370✔
1351
      mError("failed to push info to array while init variables from items,since %s", tstrerror(terrno));
×
1352
      taosArrayDestroy(pInfos);
×
UNCOV
1353
      return NULL;
×
1354
    }
1355
  }
1356

1357
  return pInfos;
8,844✔
1358
}
1359

1360
static int32_t mndProcessShowVariablesReq(SRpcMsg *pReq) {
8,844✔
1361
  SShowVariablesRsp rsp = {0};
8,844✔
1362
  int32_t           code = TSDB_CODE_SUCCESS;
8,844✔
1363
  SShowVariablesReq req = {0};
8,844✔
1364
  SUserObj         *pUser = NULL;
8,844✔
1365
  uint8_t           showPrivMask = 0;
8,844✔
1366
  SMnode           *pMnode = pReq->info.node;
8,844✔
1367

1368
  code = tDeserializeSShowVariablesReq(pReq->pCont, pReq->contLen, &req);
8,844✔
1369
  if (code != 0) {
8,844✔
1370
    mError("failed to deserialize config req, since %s", terrstr());
×
UNCOV
1371
    goto _OVER;
×
1372
  }
1373

1374
  if ((code = mndCheckOperPrivilege(pMnode, RPC_MSG_USER(pReq), RPC_MSG_TOKEN(pReq), MND_OPER_SHOW_VARIABLES)) != 0) {
8,844✔
UNCOV
1375
    goto _OVER;
×
1376
  }
1377

1378
  if ((code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pUser)) != 0) {
8,844✔
UNCOV
1379
    goto _OVER;
×
1380
  }
1381
#ifdef TD_ENTERPRISE
1382
  showPrivMask = mndBuildShowVarPrivMask(pMnode, pUser, RPC_MSG_TOKEN(pReq));
8,844✔
1383
#endif
1384
  SVariablesInfo info = {0};
8,844✔
1385
  char          *likePattern = req.opType == OP_TYPE_LIKE ? req.val : NULL;
8,844✔
1386
  rsp.variables = initVariablesFromItems(taosGetGlobalCfg(tsCfg), likePattern, showPrivMask);
8,844✔
1387
  if (rsp.variables == NULL) {
8,844✔
1388
    code = terrno;
×
UNCOV
1389
    goto _OVER;
×
1390
  }
1391
  int32_t rspLen = tSerializeSShowVariablesRsp(NULL, 0, &rsp);
8,844✔
1392
  void   *pRsp = rpcMallocCont(rspLen);
8,844✔
1393
  if (pRsp == NULL) {
8,844✔
1394
    code = terrno;
×
UNCOV
1395
    goto _OVER;
×
1396
  }
1397

1398
  if ((rspLen = tSerializeSShowVariablesRsp(pRsp, rspLen, &rsp)) <= 0) {
8,844✔
1399
    rpcFreeCont(pRsp);
×
1400
    code = rspLen;
×
UNCOV
1401
    goto _OVER;
×
1402
  }
1403

1404
  pReq->info.rspLen = rspLen;
8,844✔
1405
  pReq->info.rsp = pRsp;
8,844✔
1406
  code = 0;
8,844✔
1407

1408
_OVER:
8,844✔
1409

1410
  if (code != 0) {
8,844✔
UNCOV
1411
    mError("failed to get show variables info since %s", tstrerror(code));
×
1412
  }
1413
  mndReleaseUser(pMnode, pUser);
8,844✔
1414
  tFreeSShowVariablesReq(&req);
8,844✔
1415
  tFreeSShowVariablesRsp(&rsp);
8,844✔
1416
  TAOS_RETURN(code);
8,844✔
1417
}
1418

1419
int32_t compareSConfigItem(const SConfigObj *item1, SConfigItem *item2, bool *compare) {
×
1420
  *compare = true;
×
1421
  switch (item1->dtype) {
×
1422
    case CFG_DTYPE_BOOL:
×
1423
      if (item1->bval != item2->bval) {
×
1424
        item2->bval = item1->bval;
×
UNCOV
1425
        *compare = false;
×
1426
      }
1427
      break;
×
1428
    case CFG_DTYPE_FLOAT:
×
1429
      if (item1->fval != item2->fval) {
×
1430
        item2->fval = item1->fval;
×
UNCOV
1431
        *compare = false;
×
1432
      }
1433
      break;
×
1434
    case CFG_DTYPE_INT32:
×
1435
      if (item1->i32 != item2->i32) {
×
1436
        item2->i32 = item1->i32;
×
UNCOV
1437
        *compare = false;
×
1438
      }
1439
      break;
×
1440
    case CFG_DTYPE_INT64:
×
1441
      if (item1->i64 != item2->i64) {
×
1442
        item2->i64 = item1->i64;
×
UNCOV
1443
        *compare = false;
×
1444
      }
1445
      break;
×
UNCOV
1446
    case CFG_DTYPE_STRING:
×
1447
    case CFG_DTYPE_DIR:
1448
    case CFG_DTYPE_LOCALE:
1449
    case CFG_DTYPE_CHARSET:
1450
    case CFG_DTYPE_TIMEZONE:
1451
      if (strcmp(item1->str, item2->str) != 0) {
×
1452
        item2->str = taosStrdup(item1->str);
×
1453
        if (item2->str == NULL) {
×
UNCOV
1454
          return TSDB_CODE_OUT_OF_MEMORY;
×
1455
        }
UNCOV
1456
        *compare = false;
×
1457
      }
1458
      break;
×
1459
    default:
×
1460
      *compare = false;
×
UNCOV
1461
      return TSDB_CODE_INVALID_CFG;
×
1462
  }
UNCOV
1463
  return TSDB_CODE_SUCCESS;
×
1464
}
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