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

taosdata / TDengine / #5071

17 May 2026 01:15AM UTC coverage: 63.054% (-10.3%) from 73.326%
#5071

push

travis-ci

web-flow
feat (TDgpt): Dynamic Model Synchronization Enhancements (#35344)

* refactor: do some internal refactor.

* fix: fix multiprocess sync issue.

* feat: add dynamic anomaly detection and forecasting services

* fix: log error message for undeploying model in exception handling

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: handle undeploy when model exists only on disk

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/286aafa0-c3ce-4c27-b803-2707571e9dc1

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: guard dynamic registry concurrent access

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/5e4db858-6458-40f4-ac28-d1b1b7f97c18

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: tighten service list locking scope

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/5e4db858-6458-40f4-ac28-d1b1b7f97c18

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: restore prophet support and update tests per review feedback

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/92298ae1-7da6-4d07-b20e-101c7cd0b26b

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: improve test name and move copy inside lock scope

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/92298ae1-7da6-4d07-b20e-101c7cd0b26b

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* Potential fix for pull request finding

Co-au... (continued)

238317 of 377957 relevant lines covered (63.05%)

130539817.12 hits per line

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

56.62
/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) {
404,624✔
68
  int32_t   code = 0;
404,624✔
69
  SSdbTable table = {.sdbType = SDB_CFG,
404,624✔
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);
404,624✔
80
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeReq);
404,624✔
81
  mndSetMsgHandle(pMnode, TDMT_DND_CONFIG_DNODE_RSP, mndTransProcessRsp);
404,624✔
82
  mndSetMsgHandle(pMnode, TDMT_MND_SHOW_VARIABLES, mndProcessShowVariablesReq);
404,624✔
83
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB, mndTryRebuildConfigSdb);
404,624✔
84
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB_RSP, mndTryRebuildConfigSdbRsp);
404,624✔
85

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

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

95
  SEncoder encoder;
136,059,777✔
96
  tEncoderInit(&encoder, NULL, 0);
136,062,201✔
97
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
136,062,201✔
98
    tEncoderClear(&encoder);
×
99
    TSDB_CHECK_CODE(code, lino, _over);
×
100
  }
101

102
  int32_t tlen = encoder.pos;
136,062,201✔
103
  tEncoderClear(&encoder);
136,062,201✔
104

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

109
  buf = taosMemoryMalloc(tlen);
136,062,201✔
110
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
136,062,201✔
111

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

118
  tEncoderClear(&encoder);
136,062,201✔
119

120
  int32_t dataPos = 0;
136,062,201✔
121
  SDB_SET_INT32(pRaw, dataPos, tlen, _over);
136,062,201✔
122
  SDB_SET_BINARY(pRaw, dataPos, buf, tlen, _over);
136,062,201✔
123
  SDB_SET_DATALEN(pRaw, dataPos, _over);
136,062,201✔
124

125
_over:
136,062,201✔
126
  taosMemoryFreeClear(buf);
136,062,201✔
127
  if (code != TSDB_CODE_SUCCESS) {
136,062,201✔
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;
×
131
    return NULL;
×
132
  }
133

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

139
SSdbRow *mndCfgActionDecode(SSdbRaw *pRaw) {
50,118,652✔
140
  int32_t     code = 0;
50,118,652✔
141
  int32_t     lino = 0;
50,118,652✔
142
  SSdbRow    *pRow = NULL;
50,118,652✔
143
  SConfigObj *pObj = NULL;
50,118,652✔
144
  void       *buf = NULL;
50,118,652✔
145
  int8_t      sver = 0;
50,118,652✔
146
  int32_t     tlen;
50,117,844✔
147
  int32_t     dataPos = 0;
50,118,652✔
148

149
  code = sdbGetRawSoftVer(pRaw, &sver);
50,118,652✔
150
  TSDB_CHECK_CODE(code, lino, _over);
50,118,652✔
151

152
  if (sver != CFG_VER_NUMBER) {
50,118,652✔
153
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
154
    goto _over;
×
155
  }
156

157
  pRow = sdbAllocRow(sizeof(SConfigObj));
50,118,652✔
158
  TSDB_CHECK_NULL(pRow, code, lino, _over, terrno);
50,118,652✔
159

160
  pObj = sdbGetRowObj(pRow);
50,118,652✔
161
  TSDB_CHECK_NULL(pObj, code, lino, _over, terrno);
50,118,652✔
162

163
  SDB_GET_INT32(pRaw, dataPos, &tlen, _over);
50,118,652✔
164

165
  buf = taosMemoryMalloc(tlen + 1);
50,118,652✔
166
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
50,118,652✔
167

168
  SDB_GET_BINARY(pRaw, dataPos, buf, tlen, _over);
50,118,652✔
169

170
  SDecoder decoder;
50,117,844✔
171
  tDecoderInit(&decoder, buf, tlen + 1);
50,118,652✔
172
  code = tDecodeSConfigObj(&decoder, pObj);
50,118,652✔
173
  tDecoderClear(&decoder);
50,118,652✔
174

175
  if (code < 0) {
50,118,652✔
176
    tFreeSConfigObj(pObj);
×
177
  }
178

179
_over:
50,118,652✔
180
  taosMemoryFreeClear(buf);
50,118,652✔
181

182
  if (code != TSDB_CODE_SUCCESS) {
50,118,652✔
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;
×
186
    return NULL;
×
187
  } else {
188
    mTrace("config:%s, decode from raw:%p, row:%p", pObj->name, pRaw, pObj);
50,118,652✔
189
    terrno = 0;
50,118,652✔
190
    return pRow;
50,118,652✔
191
  }
192
}
193

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

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

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

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

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

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

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

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

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

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

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

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

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

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

329
  for (int i = 0; i < sz; ++i) {
38,458,540✔
330
    SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
38,147,589✔
331
    SConfigObj   obj;
38,147,589✔
332
    if ((code = mndInitConfigObj(item, &obj)) != 0) {
38,147,589✔
333
      goto _OVER;
×
334
    }
335
    if ((code = mndSetCreateConfigCommitLogs(pTrans, &obj)) != 0) {
38,147,589✔
336
      mError("failed to init mnd config:%s, since %s", item->name, tstrerror(code));
×
337
      tFreeSConfigObj(&obj);
×
338
      goto _OVER;
×
339
    }
340
    tFreeSConfigObj(&obj);
38,147,589✔
341
  }
342
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
310,951✔
343

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

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

355
  SRpcMsg rpcMsg = {.pCont = NULL,
174,129✔
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};
174,129✔
364

365
  mndGetMnodeEpSet(pMnode, &epSet);
174,129✔
366

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

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

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

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

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

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

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

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

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

430
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *item) {
38,480,870✔
431
  int32_t  code = 0;
38,480,870✔
432
  SSdbRaw *pCommitRaw = mnCfgActionEncode(item);
38,480,870✔
433
  if (pCommitRaw == NULL) {
38,480,870✔
434
    code = terrno;
×
435
    TAOS_RETURN(code);
×
436
  }
437
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
38,480,870✔
438
    taosMemoryFree(pCommitRaw);
×
439
    TAOS_RETURN(code);
×
440
  }
441
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY)) != 0) TAOS_RETURN(code);
38,480,870✔
442
  return TSDB_CODE_SUCCESS;
38,480,870✔
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;
×
450
    TAOS_RETURN(code);
×
451
  }
452
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
453
    taosMemoryFree(pCommitRaw);
×
454
    TAOS_RETURN(code);
×
455
  }
456
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED)) != 0) TAOS_RETURN(code);
×
457
  return TSDB_CODE_SUCCESS;
×
458
}
459

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

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

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

497
  TAOS_RETURN(TSDB_CODE_SUCCESS);
174,125✔
498
}
499

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

507
  while (1) {
21,591,500✔
508
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
21,765,625✔
509
    if (pIter == NULL) break;
21,765,625✔
510
    if (obj == NULL) {
21,591,500✔
511
      code = TSDB_CODE_OUT_OF_MEMORY;
×
512
      sdbCancelFetch(pSdb, pIter);
×
513
      TAOS_RETURN(code);
×
514
    }
515

516
    // Skip the version config
517
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
21,591,500✔
518
      sdbRelease(pSdb, obj);
174,125✔
519
      continue;
174,125✔
520
    }
521

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

532
    if (!existsInGlobal) {
21,417,375✔
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);
×
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;
×
549
        case CFG_DTYPE_FLOAT:
×
550
        case CFG_DTYPE_DOUBLE:
551
          deleteObj.fval = obj->fval;
×
552
          break;
×
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);
×
562
            TAOS_RETURN(terrno);
×
563
          }
564
          break;
×
565
        default:
×
566
          break;
×
567
      }
568

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

577
    sdbRelease(pSdb, obj);
21,417,375✔
578
  }
579

580
  TAOS_RETURN(TSDB_CODE_SUCCESS);
174,125✔
581
}
582

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

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

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

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

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);
×
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);
×
621
      TAOS_RETURN(code);
×
622
    }
623
  }
624

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

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

635
static int32_t mndMCfg2DCfg(SMCfgDnodeReq *pMCfgReq, SDCfgDnodeReq *pDCfgReq) {
77,003✔
636
  int32_t code = 0;
77,003✔
637
  char   *p = pMCfgReq->config;
77,003✔
638
  while (*p) {
1,052,400✔
639
    if (*p == ' ') {
1,011,063✔
640
      break;
35,666✔
641
    }
642
    p++;
975,397✔
643
  }
644

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

649
  if (' ' == pMCfgReq->config[optLen]) {
77,003✔
650
    // 'key value'
651
    if (strlen(pMCfgReq->value) != 0) goto _err;
35,666✔
652
    tstrncpy(pDCfgReq->value, p + 1, sizeof(pDCfgReq->value));
35,666✔
653
  } else {
654
    // 'key' 'value'
655
    if (strlen(pMCfgReq->value) == 0) goto _err;
41,337✔
656
    tstrncpy(pDCfgReq->value, pMCfgReq->value, sizeof(pDCfgReq->value));
41,337✔
657
  }
658

659
  TAOS_RETURN(code);
77,003✔
660

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

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

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

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

684
  STransAction action = {
11,165✔
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);
11,165✔
694

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

700
  return code;
11,165✔
701
}
702

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

708
  int64_t curMs = taosGetTimestampMs();
65,056✔
709

710
  while (1) {
184,933✔
711
    SDnodeObj *pDnode = NULL;
249,989✔
712
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
249,989✔
713
    if (pIter == NULL) break;
249,989✔
714

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

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

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

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

744
      code = rpcSendRecvWithTimeout(pMnode->msgCb.statusRpc, &epSet, &rpcMsg, &rpcRsp, NULL, CFG_ALTER_TIMEOUT);
65,056✔
745
      if (code != 0) {
65,056✔
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);
×
749
        return code;
×
750
      }
751

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

764
  if (code == -1) {
62,752✔
765
    code = TSDB_CODE_MND_DNODE_NOT_EXIST;
×
766
  }
767
  TAOS_RETURN(code);
62,752✔
768
}
769

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

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

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

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

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

816
    if (flag > 1024 * 1024 || (flag > -1 && flag < 1024) || flag < -1) {
×
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;
×
820
      goto _err_out;
×
821
    }
822

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

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

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

859
  dcfgReq.version = vObj->i32 + 1;
76,221✔
860

861
  if (pItem->category == CFG_CATEGORY_GLOBAL) {
76,221✔
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,
11,165✔
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;
65,056✔
869
  }
870

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

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

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

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

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

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

913
// Helper function to create and commit a config object
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;
×
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);
×
929
    return code;
×
930
  }
931

932
  code = mndSetCreateConfigCommitLogs(pTrans, pTmp);
×
933
  tFreeSConfigObj(pTmp);
×
934
  taosMemoryFree(pTmp);
×
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;
×
942
  char    tmp[10] = {0};
×
943

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

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

950
  // arbSetAssignedTimeoutMs = syncTimeout
951
  snprintf(tmp, sizeof(tmp), "%d", syncTimeout);
×
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);
×
956
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "arbHeartBeatIntervalMs", tmp, lino), lino, _OVER);
×
957

958
  // arbCheckSyncIntervalMs = syncTimeout / 4
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);
×
963
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "syncVnodeElectIntervalMs", tmp, lino), lino, _OVER);
×
964

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

968
  // statusTimeoutMs = (syncTimeout - syncTimeout / 4) / 2
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);
×
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);
×
977
  TAOS_CHECK_GOTO(mndCreateAndCommitConfigObj(pTrans, srcName, "syncVnodeHeartbeatIntervalMs", tmp, lino), lino, _OVER);
×
978

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

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

985
_OVER:
×
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]) {
×
993
    goto _err;
×
994
  }
995

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

1006
  TAOS_RETURN(code);
×
1007

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

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;
×
1020
    goto _OVER;
×
1021
  }
1022
  tstrncpy(pVersion->name, "tsmmConfigVersion", CFG_NAME_MAX_LEN);
×
1023
  pVersion->dtype = CFG_DTYPE_INT32;
×
1024
  pVersion->i32 = tsmmConfigVersion;
×
1025

1026
  pObj->dtype = dtype;
×
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;
×
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);
×
1037
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pObj), &lino, _OVER);
×
1038

1039
  if (taosStrncasecmp(name, "syncTimeout", CFG_NAME_MAX_LEN) == 0) {
×
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) {
×
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);
×
1053
  return code;
×
1054
}
1055

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

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

1072
  TAOS_CHECK_GOTO(mndUpdateObj(pObj, name, pValue), &lino, _OVER);
11,165✔
1073
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "update-config-with-dnode");
11,165✔
1074
  if (pTrans == NULL) {
11,165✔
1075
    code = terrno;
×
1076
    goto _OVER;
×
1077
  }
1078
  mInfo("trans:%d, used to update config:%s to value:%s and send to dnode", pTrans->id, name, pValue);
11,165✔
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);
11,165✔
1082
  TAOS_CHECK_GOTO(mndSetCreateConfigPrepareLogs(pTrans, pObj), &lino, _OVER);
11,165✔
1083

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

1088
  if (taosStrncasecmp(name, "syncTimeout", CFG_NAME_MAX_LEN) == 0) {
11,165✔
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;
11,165✔
1094
  void   *pIter = NULL;
11,165✔
1095
  int64_t curMs = taosGetTimestampMs();
11,165✔
1096

1097
  while (1) {
11,165✔
1098
    SDnodeObj *pDnode = NULL;
22,330✔
1099
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
22,330✔
1100
    if (pIter == NULL) break;
22,330✔
1101

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

1108
      code = mndBuildCfgDnodeRedoAction(pTrans, pDnode, pDcfgReq);
11,165✔
1109
      if (code != 0) {
11,165✔
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);
×
1113
        goto _OVER;
×
1114
      }
1115
    }
1116
    sdbRelease(pSdb, pDnode);
11,165✔
1117
  }
1118

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

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

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

1140
  while (1) {
52,030,542✔
1141
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
52,451,145✔
1142
    if (pIter == NULL) break;
52,451,145✔
1143
    if (obj == NULL) {
52,030,542✔
1144
      code = TSDB_CODE_OUT_OF_MEMORY;
×
1145
      goto _exit;
×
1146
    }
1147
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
52,030,542✔
1148
      sdbRelease(pSdb, obj);
420,603✔
1149
      continue;
420,603✔
1150
    }
1151
    SConfigItem item = {0};
51,609,939✔
1152
    item.dtype = obj->dtype;
51,609,939✔
1153
    item.name = taosStrdup(obj->name);
51,609,939✔
1154
    if (item.name == NULL) {
51,609,939✔
1155
      code = terrno;
×
1156
      sdbCancelFetch(pSdb, pIter);
×
1157
      sdbRelease(pSdb, obj);
×
1158
      goto _exit;
×
1159
    }
1160
    switch (obj->dtype) {
51,609,939✔
1161
      case CFG_DTYPE_NONE:
×
1162
        break;
×
1163
      case CFG_DTYPE_BOOL:
12,587,790✔
1164
        item.bval = obj->bval;
12,587,790✔
1165
        break;
12,587,790✔
1166
      case CFG_DTYPE_INT32:
25,175,580✔
1167
        item.i32 = obj->i32;
25,175,580✔
1168
        break;
25,175,580✔
1169
      case CFG_DTYPE_INT64:
2,937,151✔
1170
        item.i64 = obj->i64;
2,937,151✔
1171
        break;
2,937,151✔
1172
      case CFG_DTYPE_FLOAT:
839,186✔
1173
      case CFG_DTYPE_DOUBLE:
1174
        item.fval = obj->fval;
839,186✔
1175
        break;
839,186✔
1176
      case CFG_DTYPE_STRING:
10,070,232✔
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);
10,070,232✔
1182
        if (item.str == NULL) {
10,070,232✔
1183
          sdbCancelFetch(pSdb, pIter);
×
1184
          sdbRelease(pSdb, obj);
×
1185
          code = terrno;
×
1186
          goto _exit;
×
1187
        }
1188
        break;
10,070,232✔
1189
    }
1190
    if (taosArrayPush(array, &item) == NULL) {
51,609,939✔
1191
      sdbCancelFetch(pSdb, pIter);
×
1192
      sdbRelease(pSdb, obj);
×
1193
      code = TSDB_CODE_OUT_OF_MEMORY;
×
1194
      goto _exit;
×
1195
      break;
1196
    }
1197
    sdbRelease(pSdb, obj);
51,609,939✔
1198
  }
1199
_exit:
420,603✔
1200
  if (code != 0) {
420,603✔
1201
    mError("failed to init config array from sdb, since %s", tstrerror(code));
×
1202
  }
1203
  return code;
420,603✔
1204
}
1205

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

1211
  int32_t sz = taosArrayGetSize(array);
536,474✔
1212
  for (int32_t i = 0; i < sz; ++i) {
52,146,413✔
1213
    SConfigItem *item = taosArrayGet(array, i);
51,609,939✔
1214
    if (item->dtype == CFG_DTYPE_STRING || item->dtype == CFG_DTYPE_DIR || item->dtype == CFG_DTYPE_LOCALE ||
51,609,939✔
1215
        item->dtype == CFG_DTYPE_CHARSET || item->dtype == CFG_DTYPE_TIMEZONE) {
42,378,893✔
1216
      taosMemoryFreeClear(item->str);
10,070,232✔
1217
    }
1218
    taosMemoryFreeClear(item->name);
51,609,939✔
1219
  }
1220

1221
  taosArrayDestroy(array);
536,474✔
1222
}
1223

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

1236
#ifdef TD_ENTERPRISE
1237
static bool mndShowVarPrivAllowed(uint8_t showPrivMask, int8_t cfgPrivType) {
101,598✔
1238
  switch (cfgPrivType) {
101,598✔
1239
    case CFG_PRIV_SYSTEM:
79,296✔
1240
      return (showPrivMask & SHOW_VAR_PRIV_SYSTEM) != 0;
79,296✔
1241
    case CFG_PRIV_SECURITY:
10,738✔
1242
      return (showPrivMask & SHOW_VAR_PRIV_SECURITY) != 0;
10,738✔
1243
    case CFG_PRIV_AUDIT:
8,260✔
1244
      return (showPrivMask & SHOW_VAR_PRIV_AUDIT) != 0;
8,260✔
1245
    case CFG_PRIV_DEBUG:
3,304✔
1246
      return (showPrivMask & SHOW_VAR_PRIV_DEBUG) != 0;
3,304✔
1247
    default:
×
1248
      return false;
×
1249
  }
1250
}
1251

1252
static uint8_t mndBuildShowVarPrivMask(SMnode *pMnode, SUserObj *pUser, const char *token) {
826✔
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));
826✔
1262

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

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

1277
  int32_t sz = taosArrayGetSize(pItems);
826✔
1278

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

1297
    // init info value
1298
    switch (pItem->dtype) {
101,598✔
1299
      case CFG_DTYPE_NONE:
×
1300
        break;
×
1301
      case CFG_DTYPE_BOOL:
24,780✔
1302
        snprintf(info.value, sizeof(info.value), "%d", pItem->bval);
24,780✔
1303
        break;
24,780✔
1304
      case CFG_DTYPE_INT32:
49,560✔
1305
        snprintf(info.value, sizeof(info.value), "%d", pItem->i32);
49,560✔
1306
        break;
49,560✔
1307
      case CFG_DTYPE_INT64:
5,782✔
1308
        snprintf(info.value, sizeof(info.value), "%" PRId64, pItem->i64);
5,782✔
1309
        break;
5,782✔
1310
      case CFG_DTYPE_FLOAT:
1,652✔
1311
      case CFG_DTYPE_DOUBLE:
1312
        snprintf(info.value, sizeof(info.value), "%f", pItem->fval);
1,652✔
1313
        break;
1,652✔
1314
      case CFG_DTYPE_STRING:
19,824✔
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);
19,824✔
1320
        break;
19,824✔
1321
    }
1322

1323
    // init info scope
1324
    switch (pItem->scope) {
101,598✔
1325
      case CFG_SCOPE_SERVER:
83,426✔
1326
        tstrncpy(info.scope, "server", sizeof(info.scope));
83,426✔
1327
        break;
83,426✔
1328
      case CFG_SCOPE_CLIENT:
×
1329
        tstrncpy(info.scope, "client", sizeof(info.scope));
×
1330
        break;
×
1331
      case CFG_SCOPE_BOTH:
18,172✔
1332
        tstrncpy(info.scope, "both", sizeof(info.scope));
18,172✔
1333
        break;
18,172✔
1334
      default:
×
1335
        tstrncpy(info.scope, "unknown", sizeof(info.scope));
×
1336
        break;
×
1337
    }
1338
    // init info category
1339
    switch (pItem->category) {
101,598✔
1340
      case CFG_CATEGORY_GLOBAL:
101,598✔
1341
        tstrncpy(info.category, "global", sizeof(info.category));
101,598✔
1342
        break;
101,598✔
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));
×
1348
        break;
×
1349
    }
1350
    if (NULL == taosArrayPush(pInfos, &info)) {
101,598✔
1351
      mError("failed to push info to array while init variables from items,since %s", tstrerror(terrno));
×
1352
      taosArrayDestroy(pInfos);
×
1353
      return NULL;
×
1354
    }
1355
  }
1356

1357
  return pInfos;
826✔
1358
}
1359

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

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

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

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

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

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

1408
_OVER:
826✔
1409

1410
  if (code != 0) {
826✔
1411
    mError("failed to get show variables info since %s", tstrerror(code));
×
1412
  }
1413
  mndReleaseUser(pMnode, pUser);
826✔
1414
  tFreeSShowVariablesReq(&req);
826✔
1415
  tFreeSShowVariablesRsp(&rsp);
826✔
1416
  TAOS_RETURN(code);
826✔
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;
×
1425
        *compare = false;
×
1426
      }
1427
      break;
×
1428
    case CFG_DTYPE_FLOAT:
×
1429
      if (item1->fval != item2->fval) {
×
1430
        item2->fval = item1->fval;
×
1431
        *compare = false;
×
1432
      }
1433
      break;
×
1434
    case CFG_DTYPE_INT32:
×
1435
      if (item1->i32 != item2->i32) {
×
1436
        item2->i32 = item1->i32;
×
1437
        *compare = false;
×
1438
      }
1439
      break;
×
1440
    case CFG_DTYPE_INT64:
×
1441
      if (item1->i64 != item2->i64) {
×
1442
        item2->i64 = item1->i64;
×
1443
        *compare = false;
×
1444
      }
1445
      break;
×
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) {
×
1454
          return TSDB_CODE_OUT_OF_MEMORY;
×
1455
        }
1456
        *compare = false;
×
1457
      }
1458
      break;
×
1459
    default:
×
1460
      *compare = false;
×
1461
      return TSDB_CODE_INVALID_CFG;
×
1462
  }
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