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

taosdata / TDengine / #5036

28 Apr 2026 02:11PM UTC coverage: 73.055% (-0.005%) from 73.06%
#5036

push

travis-ci

web-flow
func/regexp_extract: new scalar func and test cases (#35191)

46 of 59 new or added lines in 1 file covered. (77.97%)

5784 existing lines in 151 files now uncovered.

276105 of 377940 relevant lines covered (73.06%)

133708549.2 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 "tutil.h"
26
#include "tcompare.h"
27

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

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

38
extern SConfig *tsCfg;
39

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

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

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

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

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

85
  return sdbSetTable(pMnode->pSdb, table);
485,919✔
86
}
87

88
SSdbRaw *mnCfgActionEncode(SConfigObj *obj) {
148,668,260✔
89
  int32_t  code = 0;
148,668,260✔
90
  int32_t  lino = 0;
148,668,260✔
91
  void    *buf = NULL;
148,668,260✔
92
  SSdbRaw *pRaw = NULL;
148,668,260✔
93

94
  SEncoder encoder;
148,615,319✔
95
  tEncoderInit(&encoder, NULL, 0);
148,668,260✔
96
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
148,668,260✔
97
    tEncoderClear(&encoder);
×
98
    TSDB_CHECK_CODE(code, lino, _over);
×
99
  }
100

101
  int32_t tlen = encoder.pos;
148,668,260✔
102
  tEncoderClear(&encoder);
148,668,260✔
103

104
  int32_t size = sizeof(int32_t) + tlen;
148,668,260✔
105
  pRaw = sdbAllocRaw(SDB_CFG, CFG_VER_NUMBER, size);
148,668,260✔
106
  TSDB_CHECK_NULL(pRaw, code, lino, _over, terrno);
148,668,260✔
107

108
  buf = taosMemoryMalloc(tlen);
148,668,260✔
109
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
148,668,260✔
110

111
  tEncoderInit(&encoder, buf, tlen);
148,668,260✔
112
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
148,668,260✔
113
    tEncoderClear(&encoder);
×
114
    TSDB_CHECK_CODE(code, lino, _over);
×
115
  }
116

117
  tEncoderClear(&encoder);
148,668,260✔
118

119
  int32_t dataPos = 0;
148,668,260✔
120
  SDB_SET_INT32(pRaw, dataPos, tlen, _over);
148,668,260✔
121
  SDB_SET_BINARY(pRaw, dataPos, buf, tlen, _over);
148,668,260✔
122
  SDB_SET_DATALEN(pRaw, dataPos, _over);
148,668,260✔
123

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

133
  terrno = 0;
148,668,260✔
134
  mTrace("cfg:%s, encode to raw:%p, row:%p", obj->name, pRaw, obj);
148,668,260✔
135
  return pRaw;
148,668,260✔
136
}
137

138
SSdbRow *mndCfgActionDecode(SSdbRaw *pRaw) {
56,303,192✔
139
  int32_t     code = 0;
56,303,192✔
140
  int32_t     lino = 0;
56,303,192✔
141
  SSdbRow    *pRow = NULL;
56,303,192✔
142
  SConfigObj *pObj = NULL;
56,303,192✔
143
  void       *buf = NULL;
56,303,192✔
144
  int8_t      sver = 0;
56,303,192✔
145
  int32_t     tlen;
56,277,496✔
146
  int32_t     dataPos = 0;
56,303,192✔
147

148
  code = sdbGetRawSoftVer(pRaw, &sver);
56,303,192✔
149
  TSDB_CHECK_CODE(code, lino, _over);
56,303,192✔
150

151
  if (sver != CFG_VER_NUMBER) {
56,303,192✔
152
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
153
    goto _over;
×
154
  }
155

156
  pRow = sdbAllocRow(sizeof(SConfigObj));
56,303,192✔
157
  TSDB_CHECK_NULL(pRow, code, lino, _over, terrno);
56,303,192✔
158

159
  pObj = sdbGetRowObj(pRow);
56,303,192✔
160
  TSDB_CHECK_NULL(pObj, code, lino, _over, terrno);
56,303,192✔
161

162
  SDB_GET_INT32(pRaw, dataPos, &tlen, _over);
56,303,192✔
163

164
  buf = taosMemoryMalloc(tlen + 1);
56,303,192✔
165
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
56,303,192✔
166

167
  SDB_GET_BINARY(pRaw, dataPos, buf, tlen, _over);
56,303,192✔
168

169
  SDecoder decoder;
56,277,496✔
170
  tDecoderInit(&decoder, buf, tlen + 1);
56,303,192✔
171
  code = tDecodeSConfigObj(&decoder, pObj);
56,303,192✔
172
  tDecoderClear(&decoder);
56,303,192✔
173

174
  if (code < 0) {
56,303,192✔
175
    tFreeSConfigObj(pObj);
×
176
  }
177

178
_over:
56,303,192✔
179
  taosMemoryFreeClear(buf);
56,303,192✔
180

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

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

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

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

237
static int32_t mndCfgActionDeploy(SMnode *pMnode) { return mndInitWriteCfg(pMnode); }
351,476✔
238

239
static int32_t mndCfgActionAfterRestored(SMnode *pMnode) { return mndSendRebuildReq(pMnode); }
223,417✔
240

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

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

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

267
  if (configReq.cver == vObj->i32) {
668,146✔
268
    configRsp.isVersionVerified = 1;
147,953✔
269
  } else {
270
    code = initConfigArrayFromSdb(pMnode, array);
520,193✔
271
    if (code != 0) {
520,193✔
272
      mError("failed to init config array from sdb, since %s", tstrerror(code));
×
273
      goto _OVER;
×
274
    }
275
    configRsp.array = array;
520,193✔
276
  }
277

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

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

307
int32_t mndInitWriteCfg(SMnode *pMnode) {
351,476✔
308
  int    code = 0;
351,476✔
309
  size_t sz = 0;
351,476✔
310

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

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

328
  for (int i = 0; i < sz; ++i) {
40,590,896✔
329
    SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
40,239,420✔
330
    SConfigObj   obj;
40,224,240✔
331
    if ((code = mndInitConfigObj(item, &obj)) != 0) {
40,239,420✔
332
      goto _OVER;
×
333
    }
334
    if ((code = mndSetCreateConfigCommitLogs(pTrans, &obj)) != 0) {
40,239,420✔
335
      mError("failed to init mnd config:%s, since %s", item->name, tstrerror(code));
×
336
      tFreeSConfigObj(&obj);
×
337
      goto _OVER;
×
338
    }
339
    tFreeSConfigObj(&obj);
40,239,420✔
340
  }
341
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
351,476✔
342

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

351
int32_t mndSendRebuildReq(SMnode *pMnode) {
223,417✔
352
  int32_t code = 0;
223,417✔
353

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

364
  mndGetMnodeEpSet(pMnode, &epSet);
223,417✔
365

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

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

379
  int32_t     code = 0;
223,256✔
380
  SConfigObj *vObj = NULL;
223,256✔
381
  SArray     *addArray = NULL;
223,256✔
382
  SArray     *deleteArray = NULL;
223,256✔
383

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

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

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

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

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

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

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

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

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

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

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

496
  TAOS_RETURN(TSDB_CODE_SUCCESS);
223,256✔
497
}
498

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

506
  while (1) {
25,897,696✔
507
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
26,120,952✔
508
    if (pIter == NULL) break;
26,120,952✔
509
    if (obj == NULL) {
25,897,696✔
510
      code = TSDB_CODE_OUT_OF_MEMORY;
×
511
      sdbCancelFetch(pSdb, pIter);
×
512
      TAOS_RETURN(code);
×
513
    }
514

515
    // Skip the version config
516
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
25,897,696✔
517
      sdbRelease(pSdb, obj);
223,256✔
518
      continue;
223,256✔
519
    }
520

521
    // Check if this config exists in global config
522
    bool existsInGlobal = false;
25,674,440✔
523
    for (int i = 0; i < sz; ++i) {
1,489,117,520✔
524
      SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
1,489,117,520✔
525
      if (strcasecmp(obj->name, item->name) == 0) {
1,489,117,520✔
526
        existsInGlobal = true;
25,674,440✔
527
        break;
25,674,440✔
528
      }
529
    }
530

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

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

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

576
    sdbRelease(pSdb, obj);
25,674,440✔
577
  }
578

579
  TAOS_RETURN(TSDB_CODE_SUCCESS);
223,256✔
580
}
581

582
static int32_t mndExecuteConfigSyncTrans(SMnode *pMnode, SArray *addArray, SArray *deleteArray) {
223,256✔
583
  int32_t addSize = taosArrayGetSize(addArray);
223,256✔
584
  int32_t deleteSize = taosArrayGetSize(deleteArray);
223,256✔
585

586
  if (addSize == 0 && deleteSize == 0) {
223,256✔
587
    return TSDB_CODE_SUCCESS;
223,256✔
588
  }
589

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

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

604
  int32_t code = 0;
×
605

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

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

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

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

634
static int32_t mndMCfg2DCfg(SMCfgDnodeReq *pMCfgReq, SDCfgDnodeReq *pDCfgReq) {
107,366✔
635
  int32_t code = 0;
107,366✔
636
  char   *p = pMCfgReq->config;
107,366✔
637
  while (*p) {
1,461,803✔
638
    if (*p == ' ') {
1,409,757✔
639
      break;
55,320✔
640
    }
641
    p++;
1,354,437✔
642
  }
643

644
  size_t optLen = p - pMCfgReq->config;
107,366✔
645
  tstrncpy(pDCfgReq->config, pMCfgReq->config, sizeof(pDCfgReq->config));
107,366✔
646
  pDCfgReq->config[optLen] = 0;
107,366✔
647

648
  if (' ' == pMCfgReq->config[optLen]) {
107,366✔
649
    // 'key value'
650
    if (strlen(pMCfgReq->value) != 0) goto _err;
55,320✔
651
    tstrncpy(pDCfgReq->value, p + 1, sizeof(pDCfgReq->value));
55,320✔
652
  } else {
653
    // 'key' 'value'
654
    if (strlen(pMCfgReq->value) == 0) goto _err;
52,046✔
655
    tstrncpy(pDCfgReq->value, pMCfgReq->value, sizeof(pDCfgReq->value));
51,329✔
656
  }
657

658
  TAOS_RETURN(code);
106,649✔
659

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

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

672
  if (pBuf == NULL) {
15,865✔
673
    code = terrno;
×
674
    return code;
×
675
  }
676

677
  if ((bufLen = tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq)) <= 0) {
15,865✔
678
    code = bufLen;
×
679
    taosMemoryFree(pBuf);
×
680
    return code;
×
681
  }
682

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

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

694
  if ((code = mndTransAppendRedoAction(pTrans, &action)) != 0) {
15,865✔
695
    taosMemoryFree(pBuf);
×
696
    return code;
×
697
  }
698

699
  return code;
15,865✔
700
}
701

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

707
  int64_t curMs = taosGetTimestampMs();
80,279✔
708

709
  while (1) {
200,535✔
710
    SDnodeObj *pDnode = NULL;
280,814✔
711
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
280,814✔
712
    if (pIter == NULL) break;
280,814✔
713

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

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

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

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

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

751
      code = rpcRsp.code;
82,059✔
752
      if (code != 0) {
82,059✔
753
        mError("failed to alter config %s,on dnode:%d, since %s", pDcfgReq->config, pDnode->id, tstrerror(code));
2,202✔
754
        sdbCancelFetch(pMnode->pSdb, pIter);
2,202✔
755
        sdbRelease(pMnode->pSdb, pDnode);
2,202✔
756
        return code;
2,202✔
757
      }
758
      rpcFreeCont(rpcRsp.pCont);
79,857✔
759
    }
760
    sdbRelease(pSdb, pDnode);
200,505✔
761
  }
762

763
  if (code == -1) {
78,077✔
764
    code = TSDB_CODE_MND_DNODE_NOT_EXIST;
694✔
765
  }
766
  TAOS_RETURN(code);
78,077✔
767
}
768

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

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

787
  code = mndAcquireUser(pMnode, RPC_MSG_USER(pReq), &pOperUser);
110,000✔
788
  if (pOperUser == NULL) {
110,000✔
789
    code = TSDB_CODE_MND_NO_USER_FROM_CONN;
×
790
    goto _err_out;
×
791
  }
792

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

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

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

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

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

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

858
  dcfgReq.version = vObj->i32 + 1;
94,570✔
859

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

870
  // For global config, transaction has handled everything, go to success
871
  goto _success;
14,511✔
872

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

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

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

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

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

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

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

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

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

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

947
  int32_t baseTimeout = syncTimeout - syncTimeout / SYNC_TIMEOUT_DIVISOR;
×
948

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

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

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

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

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

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

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

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

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

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

984
_OVER:
×
985
  return code;
×
986
}
987

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

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

1005
  TAOS_RETURN(code);
×
1006

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

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

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

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

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

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

1068
  pObj->dtype = dtype;
14,511✔
1069
  tstrncpy(pObj->name, name, CFG_NAME_MAX_LEN);
14,511✔
1070

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

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

1083
  // Add commit logs for transaction persistence
1084
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pVersion), &lino, _OVER);
14,511✔
1085
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pObj), &lino, _OVER);
14,511✔
1086

1087
  if (taosStrncasecmp(name, "syncTimeout", CFG_NAME_MAX_LEN) == 0) {
14,511✔
1088
    TAOS_CHECK_GOTO(mndHandleSyncTimeoutConfigs(pTrans, name, pValue, &lino), &lino, _OVER);
×
1089
  }
1090

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

1096
  while (1) {
15,865✔
1097
    SDnodeObj *pDnode = NULL;
30,376✔
1098
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
30,376✔
1099
    if (pIter == NULL) break;
30,376✔
1100

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

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

1118
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
14,511✔
1119
  code = 0;
14,511✔
1120

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

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

1139
  while (1) {
60,037,983✔
1140
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
60,558,176✔
1141
    if (pIter == NULL) break;
60,558,176✔
1142
    if (obj == NULL) {
60,037,983✔
1143
      code = TSDB_CODE_OUT_OF_MEMORY;
×
1144
      goto _exit;
×
1145
    }
1146
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
60,037,983✔
1147
      sdbRelease(pSdb, obj);
520,193✔
1148
      continue;
520,193✔
1149
    }
1150
    SConfigItem item = {0};
59,517,790✔
1151
    item.dtype = obj->dtype;
59,517,790✔
1152
    item.name = taosStrdup(obj->name);
59,517,790✔
1153
    if (item.name == NULL) {
59,517,790✔
1154
      code = terrno;
×
1155
      sdbCancelFetch(pSdb, pIter);
×
1156
      sdbRelease(pSdb, obj);
×
1157
      goto _exit;
×
1158
    }
1159
    switch (obj->dtype) {
59,517,790✔
1160
      case CFG_DTYPE_NONE:
×
1161
        break;
×
1162
      case CFG_DTYPE_BOOL:
15,008,834✔
1163
        item.bval = obj->bval;
15,008,834✔
1164
        break;
15,008,834✔
1165
      case CFG_DTYPE_INT32:
30,535,214✔
1166
        item.i32 = obj->i32;
30,535,214✔
1167
        break;
30,535,214✔
1168
      case CFG_DTYPE_INT64:
3,622,822✔
1169
        item.i64 = obj->i64;
3,622,822✔
1170
        break;
3,622,822✔
1171
      case CFG_DTYPE_FLOAT:
1,035,092✔
1172
      case CFG_DTYPE_DOUBLE:
1173
        item.fval = obj->fval;
1,035,092✔
1174
        break;
1,035,092✔
1175
      case CFG_DTYPE_STRING:
9,315,828✔
1176
      case CFG_DTYPE_DIR:
1177
      case CFG_DTYPE_LOCALE:
1178
      case CFG_DTYPE_CHARSET:
1179
      case CFG_DTYPE_TIMEZONE:
1180
        item.str = taosStrdup(obj->str);
9,315,828✔
1181
        if (item.str == NULL) {
9,315,828✔
1182
          sdbCancelFetch(pSdb, pIter);
×
1183
          sdbRelease(pSdb, obj);
×
1184
          code = terrno;
×
1185
          goto _exit;
×
1186
        }
1187
        break;
9,315,828✔
1188
    }
1189
    if (taosArrayPush(array, &item) == NULL) {
59,517,790✔
1190
      sdbCancelFetch(pSdb, pIter);
×
1191
      sdbRelease(pSdb, obj);
×
1192
      code = TSDB_CODE_OUT_OF_MEMORY;
×
1193
      goto _exit;
×
1194
      break;
1195
    }
1196
    sdbRelease(pSdb, obj);
59,517,790✔
1197
  }
1198
_exit:
520,193✔
1199
  if (code != 0) {
520,193✔
1200
    mError("failed to init config array from sdb, since %s", tstrerror(code));
×
1201
  }
1202
  return code;
520,193✔
1203
}
1204

1205
static void cfgArrayCleanUp(SArray *array) {
668,146✔
1206
  if (array == NULL) {
668,146✔
1207
    return;
×
1208
  }
1209

1210
  int32_t sz = taosArrayGetSize(array);
668,146✔
1211
  for (int32_t i = 0; i < sz; ++i) {
60,185,936✔
1212
    SConfigItem *item = taosArrayGet(array, i);
59,517,790✔
1213
    if (item->dtype == CFG_DTYPE_STRING || item->dtype == CFG_DTYPE_DIR || item->dtype == CFG_DTYPE_LOCALE ||
59,517,790✔
1214
        item->dtype == CFG_DTYPE_CHARSET || item->dtype == CFG_DTYPE_TIMEZONE) {
51,237,054✔
1215
      taosMemoryFreeClear(item->str);
9,315,828✔
1216
    }
1217
    taosMemoryFreeClear(item->name);
59,517,790✔
1218
  }
1219

1220
  taosArrayDestroy(array);
668,146✔
1221
}
1222

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

1235
#ifdef TD_ENTERPRISE
1236
static bool mndShowVarPrivAllowed(uint8_t showPrivMask, int8_t cfgPrivType) {
580,652✔
1237
  switch (cfgPrivType) {
580,652✔
1238
    case CFG_PRIV_SYSTEM:
445,208✔
1239
      return (showPrivMask & SHOW_VAR_PRIV_SYSTEM) != 0;
445,208✔
1240
    case CFG_PRIV_SECURITY:
65,230✔
1241
      return (showPrivMask & SHOW_VAR_PRIV_SECURITY) != 0;
65,230✔
1242
    case CFG_PRIV_AUDIT:
50,278✔
1243
      return (showPrivMask & SHOW_VAR_PRIV_AUDIT) != 0;
50,278✔
1244
    case CFG_PRIV_DEBUG:
19,936✔
1245
      return (showPrivMask & SHOW_VAR_PRIV_DEBUG) != 0;
19,936✔
UNCOV
1246
    default:
×
UNCOV
1247
      return false;
×
1248
  }
1249
}
1250

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

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

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

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

1276
  int32_t sz = taosArrayGetSize(pItems);
8,716✔
1277

1278
  SArray *pInfos = taosArrayInit(sz, sizeof(SVariablesInfo));
8,716✔
1279
  if (pInfos == NULL) {
8,716✔
UNCOV
1280
    mError("failed to init array while init variables from items, since %s", tstrerror(terrno));
×
UNCOV
1281
    return NULL;
×
1282
  }
1283
  for (int32_t i = 0; i < sz; ++i) {
1,011,056✔
1284
    SConfigItem   *pItem = taosArrayGet(pItems, i);
1,002,340✔
1285
    SVariablesInfo info = {0};
1,002,340✔
1286
    tstrncpy(info.name, pItem->name, sizeof(info.name));
1,002,340✔
1287
    if (likePattern != NULL && rawStrPatternMatch(pItem->name, likePattern) != TSDB_PATTERN_MATCH) {
1,002,340✔
1288
      continue;
421,688✔
1289
    }
1290
#ifdef TD_ENTERPRISE
1291
    if (!mndShowVarPrivAllowed(showPrivMask, pItem->privType)) {
580,652✔
1292
      continue;
17,252✔
1293
    }
1294
#endif
1295

1296
    // init info value
1297
    switch (pItem->dtype) {
563,400✔
UNCOV
1298
      case CFG_DTYPE_NONE:
×
UNCOV
1299
        break;
×
1300
      case CFG_DTYPE_BOOL:
135,476✔
1301
        snprintf(info.value, sizeof(info.value), "%d", pItem->bval);
135,476✔
1302
        break;
135,476✔
1303
      case CFG_DTYPE_INT32:
297,802✔
1304
        snprintf(info.value, sizeof(info.value), "%d", pItem->i32);
297,802✔
1305
        break;
297,802✔
1306
      case CFG_DTYPE_INT64:
34,888✔
1307
        snprintf(info.value, sizeof(info.value), "%" PRId64, pItem->i64);
34,888✔
1308
        break;
34,888✔
1309
      case CFG_DTYPE_FLOAT:
9,968✔
1310
      case CFG_DTYPE_DOUBLE:
1311
        snprintf(info.value, sizeof(info.value), "%f", pItem->fval);
9,968✔
1312
        break;
9,968✔
1313
      case CFG_DTYPE_STRING:
85,266✔
1314
      case CFG_DTYPE_DIR:
1315
      case CFG_DTYPE_LOCALE:
1316
      case CFG_DTYPE_CHARSET:
1317
      case CFG_DTYPE_TIMEZONE:
1318
        snprintf(info.value, sizeof(info.value), "%s", pItem->str);
85,266✔
1319
        break;
85,266✔
1320
    }
1321

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

1356
  return pInfos;
8,716✔
1357
}
1358

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

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

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

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

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

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

1407
_OVER:
8,716✔
1408

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

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