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

taosdata / TDengine / #5055

17 May 2026 01:15AM UTC coverage: 73.355% (-0.003%) from 73.358%
#5055

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)

281532 of 383795 relevant lines covered (73.35%)

135557734.7 hits per line

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

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

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

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

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

39
extern SConfig *tsCfg;
40

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

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

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

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

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

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

95
  SEncoder encoder;
171,364,929✔
96
  tEncoderInit(&encoder, NULL, 0);
171,424,121✔
97
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
171,424,121✔
98
    tEncoderClear(&encoder);
×
99
    TSDB_CHECK_CODE(code, lino, _over);
×
100
  }
101

102
  int32_t tlen = encoder.pos;
171,424,121✔
103
  tEncoderClear(&encoder);
171,424,121✔
104

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

109
  buf = taosMemoryMalloc(tlen);
171,424,121✔
110
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
171,424,121✔
111

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

118
  tEncoderClear(&encoder);
171,424,121✔
119

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

125
_over:
171,424,121✔
126
  taosMemoryFreeClear(buf);
171,424,121✔
127
  if (code != TSDB_CODE_SUCCESS) {
171,424,121✔
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;
171,424,121✔
135
  mTrace("cfg:%s, encode to raw:%p, row:%p", obj->name, pRaw, obj);
171,424,121✔
136
  return pRaw;
171,424,121✔
137
}
138

139
SSdbRow *mndCfgActionDecode(SSdbRaw *pRaw) {
65,991,420✔
140
  int32_t     code = 0;
65,991,420✔
141
  int32_t     lino = 0;
65,991,420✔
142
  SSdbRow    *pRow = NULL;
65,991,420✔
143
  SConfigObj *pObj = NULL;
65,991,420✔
144
  void       *buf = NULL;
65,991,420✔
145
  int8_t      sver = 0;
65,991,420✔
146
  int32_t     tlen;
65,964,084✔
147
  int32_t     dataPos = 0;
65,991,420✔
148

149
  code = sdbGetRawSoftVer(pRaw, &sver);
65,991,420✔
150
  TSDB_CHECK_CODE(code, lino, _over);
65,991,420✔
151

152
  if (sver != CFG_VER_NUMBER) {
65,991,420✔
153
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
154
    goto _over;
×
155
  }
156

157
  pRow = sdbAllocRow(sizeof(SConfigObj));
65,991,420✔
158
  TSDB_CHECK_NULL(pRow, code, lino, _over, terrno);
65,991,420✔
159

160
  pObj = sdbGetRowObj(pRow);
65,991,420✔
161
  TSDB_CHECK_NULL(pObj, code, lino, _over, terrno);
65,991,420✔
162

163
  SDB_GET_INT32(pRaw, dataPos, &tlen, _over);
65,991,420✔
164

165
  buf = taosMemoryMalloc(tlen + 1);
65,991,420✔
166
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
65,991,420✔
167

168
  SDB_GET_BINARY(pRaw, dataPos, buf, tlen, _over);
65,991,420✔
169

170
  SDecoder decoder;
65,964,084✔
171
  tDecoderInit(&decoder, buf, tlen + 1);
65,991,420✔
172
  code = tDecodeSConfigObj(&decoder, pObj);
65,991,420✔
173
  tDecoderClear(&decoder);
65,991,420✔
174

175
  if (code < 0) {
65,991,420✔
176
    tFreeSConfigObj(pObj);
×
177
  }
178

179
_over:
65,991,420✔
180
  taosMemoryFreeClear(buf);
65,991,420✔
181

182
  if (code != TSDB_CODE_SUCCESS) {
65,991,420✔
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);
65,991,420✔
189
    terrno = 0;
65,991,420✔
190
    return pRow;
65,991,420✔
191
  }
192
}
193

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

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

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

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

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

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

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

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

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

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

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

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

312
  mInfo("init write cfg to sdb");
381,638✔
313
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "init-write-config");
381,638✔
314
  if (pTrans == NULL) {
381,638✔
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();
381,638✔
321
  if ((code = mndSetCreateConfigCommitLogs(pTrans, &versionObj)) != 0) {
381,638✔
322
    mError("failed to init mnd config version, since %s", tstrerror(code));
×
323
    tFreeSConfigObj(&versionObj);
×
324
    goto _OVER;
×
325
  }
326
  tFreeSConfigObj(&versionObj);
381,638✔
327
  sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
381,638✔
328

329
  for (int i = 0; i < sz; ++i) {
47,224,712✔
330
    SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
46,843,074✔
331
    SConfigObj   obj;
46,826,346✔
332
    if ((code = mndInitConfigObj(item, &obj)) != 0) {
46,843,074✔
333
      goto _OVER;
×
334
    }
335
    if ((code = mndSetCreateConfigCommitLogs(pTrans, &obj)) != 0) {
46,843,074✔
336
      mError("failed to init mnd config:%s, since %s", item->name, tstrerror(code));
×
337
      tFreeSConfigObj(&obj);
×
338
      goto _OVER;
×
339
    }
340
    tFreeSConfigObj(&obj);
46,843,074✔
341
  }
342
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
381,638✔
343

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

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

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

365
  mndGetMnodeEpSet(pMnode, &epSet);
248,278✔
366

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

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

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

385
  vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
248,225✔
386
  if (vObj == NULL) {
248,225✔
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));
248,225✔
397
  deleteArray = taosArrayInit(4, sizeof(SConfigObj));
248,225✔
398
  if (addArray == NULL || deleteArray == NULL) {
248,225✔
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) {
248,225✔
405
    mError("failed to find configs to add, since %s", tstrerror(code));
×
406
    goto _exit;
×
407
  }
408

409
  if ((code = mndFindConfigsToDelete(pMnode, deleteArray)) != 0) {
248,225✔
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) {
248,225✔
416
    mError("failed to execute config sync transaction, since %s", tstrerror(code));
×
417
    goto _exit;
×
418
  }
419

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

430
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *item) {
47,257,210✔
431
  int32_t  code = 0;
47,257,210✔
432
  SSdbRaw *pCommitRaw = mnCfgActionEncode(item);
47,257,210✔
433
  if (pCommitRaw == NULL) {
47,257,210✔
434
    code = terrno;
×
435
    TAOS_RETURN(code);
×
436
  }
437
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
47,257,210✔
438
    taosMemoryFree(pCommitRaw);
×
439
    TAOS_RETURN(code);
×
440
  }
441
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY)) != 0) TAOS_RETURN(code);
47,257,210✔
442
  return TSDB_CODE_SUCCESS;
47,257,210✔
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) {
32,498✔
461
  int32_t  code = 0;
32,498✔
462
  SSdbRaw *pPrepareRaw = mnCfgActionEncode(item);
32,498✔
463
  if (pPrepareRaw == NULL) {
32,498✔
464
    code = terrno;
×
465
    TAOS_RETURN(code);
×
466
  }
467
  if ((code = mndTransAppendPrepareLog(pTrans, pPrepareRaw)) != 0) {
32,498✔
468
    taosMemoryFree(pPrepareRaw);
×
469
    TAOS_RETURN(code);
×
470
  }
471
  if ((code = sdbSetRawStatus(pPrepareRaw, SDB_STATUS_READY)) != 0) TAOS_RETURN(code);
32,498✔
472
  return TSDB_CODE_SUCCESS;
32,498✔
473
}
474

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

479
  for (int i = 0; i < sz; ++i) {
30,779,900✔
480
    SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
30,531,675✔
481
    SConfigObj  *obj = sdbAcquire(pMnode->pSdb, SDB_CFG, item->name);
30,531,675✔
482
    if (obj == NULL) {
30,531,675✔
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);
30,531,675✔
494
    }
495
  }
496

497
  TAOS_RETURN(TSDB_CODE_SUCCESS);
248,225✔
498
}
499

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

507
  while (1) {
30,779,900✔
508
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
31,028,125✔
509
    if (pIter == NULL) break;
31,028,125✔
510
    if (obj == NULL) {
30,779,900✔
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) {
30,779,900✔
518
      sdbRelease(pSdb, obj);
248,225✔
519
      continue;
248,225✔
520
    }
521

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

532
    if (!existsInGlobal) {
30,531,675✔
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);
30,531,675✔
578
  }
579

580
  TAOS_RETURN(TSDB_CODE_SUCCESS);
248,225✔
581
}
582

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

587
  if (addSize == 0 && deleteSize == 0) {
248,225✔
588
    return TSDB_CODE_SUCCESS;
248,225✔
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) {
117,225✔
636
  int32_t code = 0;
117,225✔
637
  char   *p = pMCfgReq->config;
117,225✔
638
  while (*p) {
1,601,113✔
639
    if (*p == ' ') {
1,545,152✔
640
      break;
61,264✔
641
    }
642
    p++;
1,483,888✔
643
  }
644

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

649
  if (' ' == pMCfgReq->config[optLen]) {
117,225✔
650
    // 'key value'
651
    if (strlen(pMCfgReq->value) != 0) goto _err;
61,264✔
652
    tstrncpy(pDCfgReq->value, p + 1, sizeof(pDCfgReq->value));
61,264✔
653
  } else {
654
    // 'key' 'value'
655
    if (strlen(pMCfgReq->value) == 0) goto _err;
55,961✔
656
    tstrncpy(pDCfgReq->value, pMCfgReq->value, sizeof(pDCfgReq->value));
55,153✔
657
  }
658

659
  TAOS_RETURN(code);
116,417✔
660

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

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

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

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

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

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

700
  return code;
17,821✔
701
}
702

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

708
  int64_t curMs = taosGetTimestampMs();
86,230✔
709

710
  while (1) {
213,126✔
711
    SDnodeObj *pDnode = NULL;
299,356✔
712
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
299,356✔
713
    if (pIter == NULL) break;
299,356✔
714

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

725
      if (pBuf == NULL) {
88,312✔
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) {
88,312✔
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);
88,312✔
741
      SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pBuf, .contLen = bufLen};
88,312✔
742
      SRpcMsg rpcRsp = {0};
88,312✔
743

744
      code = rpcSendRecvWithTimeout(pMnode->msgCb.statusRpc, &epSet, &rpcMsg, &rpcRsp, NULL, CFG_ALTER_TIMEOUT);
88,312✔
745
      if (code != 0) {
88,312✔
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;
88,312✔
753
      if (code != 0) {
88,312✔
754
        mError("failed to alter config %s,on dnode:%d, since %s", pDcfgReq->config, pDnode->id, tstrerror(code));
2,316✔
755
        sdbCancelFetch(pMnode->pSdb, pIter);
2,316✔
756
        sdbRelease(pMnode->pSdb, pDnode);
2,316✔
757
        return code;
2,316✔
758
      }
759
      rpcFreeCont(rpcRsp.pCont);
85,996✔
760
    }
761
    sdbRelease(pSdb, pDnode);
213,096✔
762
  }
763

764
  if (code == -1) {
83,914✔
765
    code = TSDB_CODE_MND_DNODE_NOT_EXIST;
822✔
766
  }
767
  TAOS_RETURN(code);
83,914✔
768
}
769

770
static int32_t  mndProcessConfigDnodeReq(SRpcMsg *pReq) {
120,298✔
771
  int32_t       code = 0;
120,298✔
772
  int32_t       lino = -1;
120,298✔
773
  SMnode       *pMnode = pReq->info.node;
120,298✔
774
  SMCfgDnodeReq cfgReq = {0};
120,298✔
775
  SUserObj     *pOperUser = NULL;
120,298✔
776
  int64_t       tss = taosGetTimestampMs();
120,298✔
777
  SConfigObj   *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
120,298✔
778
  if (vObj == NULL) {
120,298✔
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));
120,298✔
785
  int8_t updateWhiteList = 0;
120,298✔
786
  mInfo("dnode:%d, start to config, option:%s, value:%s", cfgReq.dnodeId, cfgReq.config, cfgReq.value);
120,298✔
787

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

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

803
  SDCfgDnodeReq dcfgReq = {0};
117,503✔
804
  if (strcasecmp(cfgReq.config, "resetlog") == 0) {
117,503✔
805
    tstrncpy(dcfgReq.config, "resetlog", 9);
278✔
806
    goto _send_req;
278✔
807
#ifdef TD_ENTERPRISE
808
  } else if (strncasecmp(cfgReq.config, "ssblocksize", 12) == 0) {
117,225✔
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);
117,225✔
828
    if (strlen(dcfgReq.config) > TSDB_DNODE_CONFIG_LEN) {
116,417✔
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) {
116,417✔
834
      updateWhiteList = 1;
320✔
835
    }
836

837
    CfgAlterType alterType = (cfgReq.dnodeId == 0 || cfgReq.dnodeId == -1) ? CFG_ALTER_ALL_DNODES : CFG_ALTER_DNODE;
116,417✔
838
    TAOS_CHECK_GOTO(cfgCheckRangeForDynUpdate(taosGetCfg(), dcfgReq.config, dcfgReq.value, true, alterType), &lino,
116,417✔
839
                    _err_out);
840
  }
841
  SConfigItem *pItem = cfgGetItem(taosGetCfg(), dcfgReq.config);
102,201✔
842
  // Update config in sdb.
843
  if (pItem == NULL) {
102,201✔
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) {
102,201✔
851
    char obj[50] = {0};
102,201✔
852
    (void)snprintf(obj, sizeof(obj), "%d", cfgReq.dnodeId);
102,201✔
853
    int64_t tse = taosGetTimestampMs();
102,201✔
854
    double  duration = (double)(tse - tss);
102,201✔
855
    duration = duration / 1000;
102,201✔
856
    auditRecord(pReq, pMnode->clusterId, "alterDnode", obj, "", cfgReq.sql, cfgReq.sqlLen, duration, 0);
102,201✔
857
  }
858

859
  dcfgReq.version = vObj->i32 + 1;
102,201✔
860

861
  if (pItem->category == CFG_CATEGORY_GLOBAL) {
102,201✔
862
    // Use transaction to update SDB and send to dnode atomically
863
    TAOS_CHECK_GOTO(mndConfigUpdateTransWithDnode(pMnode, dcfgReq.config, dcfgReq.value, pItem->dtype, dcfgReq.version,
16,249✔
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;
85,952✔
869
  }
870

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

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

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

895
_err_out:
20,957✔
896
  mError("failed to process config dnode req, since %s", tstrerror(code));
20,957✔
897
  tFreeSMCfgDnodeReq(&cfgReq);
20,957✔
898
  sdbRelease(pMnode->pSdb, vObj);
20,957✔
899
  mndReleaseUser(pMnode, pOperUser);
20,957✔
900
  TAOS_RETURN(code);
20,957✔
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) {
248,042✔
909
  mInfo("rebuild config sdb rsp");
248,042✔
910
  return 0;
248,042✔
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,
16,249✔
1057
                                             int32_t tsmmConfigVersion, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
1058
  int32_t     code = -1;
16,249✔
1059
  int32_t     lino = -1;
16,249✔
1060
  SConfigObj *pVersion = taosMemoryMalloc(sizeof(SConfigObj)), *pObj = taosMemoryMalloc(sizeof(SConfigObj));
16,249✔
1061
  if (pVersion == NULL || pObj == NULL) {
16,249✔
1062
    code = terrno;
×
1063
    goto _OVER;
×
1064
  }
1065
  tstrncpy(pVersion->name, "tsmmConfigVersion", CFG_NAME_MAX_LEN);
16,249✔
1066
  pVersion->dtype = CFG_DTYPE_INT32;
16,249✔
1067
  pVersion->i32 = tsmmConfigVersion;
16,249✔
1068

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

1072
  TAOS_CHECK_GOTO(mndUpdateObj(pObj, name, pValue), &lino, _OVER);
16,249✔
1073
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "update-config-with-dnode");
16,249✔
1074
  if (pTrans == NULL) {
16,249✔
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);
16,249✔
1079

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

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

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

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

1097
  while (1) {
17,821✔
1098
    SDnodeObj *pDnode = NULL;
34,070✔
1099
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
34,070✔
1100
    if (pIter == NULL) break;
34,070✔
1101

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

1108
      code = mndBuildCfgDnodeRedoAction(pTrans, pDnode, pDcfgReq);
17,821✔
1109
      if (code != 0) {
17,821✔
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);
17,821✔
1117
  }
1118

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

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

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

1140
  while (1) {
70,535,108✔
1141
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
71,105,725✔
1142
    if (pIter == NULL) break;
71,105,725✔
1143
    if (obj == NULL) {
70,535,108✔
1144
      code = TSDB_CODE_OUT_OF_MEMORY;
×
1145
      goto _exit;
×
1146
    }
1147
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
70,535,108✔
1148
      sdbRelease(pSdb, obj);
570,617✔
1149
      continue;
570,617✔
1150
    }
1151
    SConfigItem item = {0};
69,964,491✔
1152
    item.dtype = obj->dtype;
69,964,491✔
1153
    item.name = taosStrdup(obj->name);
69,964,491✔
1154
    if (item.name == NULL) {
69,964,491✔
1155
      code = terrno;
×
1156
      sdbCancelFetch(pSdb, pIter);
×
1157
      sdbRelease(pSdb, obj);
×
1158
      goto _exit;
×
1159
    }
1160
    switch (obj->dtype) {
69,964,491✔
1161
      case CFG_DTYPE_NONE:
×
1162
        break;
×
1163
      case CFG_DTYPE_BOOL:
17,064,510✔
1164
        item.bval = obj->bval;
17,064,510✔
1165
        break;
17,064,510✔
1166
      case CFG_DTYPE_INT32:
34,129,020✔
1167
        item.i32 = obj->i32;
34,129,020✔
1168
        break;
34,129,020✔
1169
      case CFG_DTYPE_INT64:
3,981,719✔
1170
        item.i64 = obj->i64;
3,981,719✔
1171
        break;
3,981,719✔
1172
      case CFG_DTYPE_FLOAT:
1,137,634✔
1173
      case CFG_DTYPE_DOUBLE:
1174
        item.fval = obj->fval;
1,137,634✔
1175
        break;
1,137,634✔
1176
      case CFG_DTYPE_STRING:
13,651,608✔
1177
      case CFG_DTYPE_DIR:
1178
      case CFG_DTYPE_LOCALE:
1179
      case CFG_DTYPE_CHARSET:
1180
      case CFG_DTYPE_TIMEZONE:
1181
        item.str = taosStrdup(obj->str);
13,651,608✔
1182
        if (item.str == NULL) {
13,651,608✔
1183
          sdbCancelFetch(pSdb, pIter);
×
1184
          sdbRelease(pSdb, obj);
×
1185
          code = terrno;
×
1186
          goto _exit;
×
1187
        }
1188
        break;
13,651,608✔
1189
    }
1190
    if (taosArrayPush(array, &item) == NULL) {
69,964,491✔
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);
69,964,491✔
1198
  }
1199
_exit:
570,617✔
1200
  if (code != 0) {
570,617✔
1201
    mError("failed to init config array from sdb, since %s", tstrerror(code));
×
1202
  }
1203
  return code;
570,617✔
1204
}
1205

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

1211
  int32_t sz = taosArrayGetSize(array);
733,552✔
1212
  for (int32_t i = 0; i < sz; ++i) {
70,698,043✔
1213
    SConfigItem *item = taosArrayGet(array, i);
69,964,491✔
1214
    if (item->dtype == CFG_DTYPE_STRING || item->dtype == CFG_DTYPE_DIR || item->dtype == CFG_DTYPE_LOCALE ||
69,964,491✔
1215
        item->dtype == CFG_DTYPE_CHARSET || item->dtype == CFG_DTYPE_TIMEZONE) {
57,450,517✔
1216
      taosMemoryFreeClear(item->str);
13,651,608✔
1217
    }
1218
    taosMemoryFreeClear(item->name);
69,964,491✔
1219
  }
1220

1221
  taosArrayDestroy(array);
733,552✔
1222
}
1223

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

1236
#ifdef TD_ENTERPRISE
1237
static bool mndShowVarPrivAllowed(uint8_t showPrivMask, int8_t cfgPrivType) {
471,232✔
1238
  switch (cfgPrivType) {
471,232✔
1239
    case CFG_PRIV_SYSTEM:
368,719✔
1240
      return (showPrivMask & SHOW_VAR_PRIV_SYSTEM) != 0;
368,719✔
1241
    case CFG_PRIV_SECURITY:
49,377✔
1242
      return (showPrivMask & SHOW_VAR_PRIV_SECURITY) != 0;
49,377✔
1243
    case CFG_PRIV_AUDIT:
38,100✔
1244
      return (showPrivMask & SHOW_VAR_PRIV_AUDIT) != 0;
38,100✔
1245
    case CFG_PRIV_DEBUG:
15,036✔
1246
      return (showPrivMask & SHOW_VAR_PRIV_DEBUG) != 0;
15,036✔
1247
    default:
×
1248
      return false;
×
1249
  }
1250
}
1251

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

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

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

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

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

1279
  SArray *pInfos = taosArrayInit(sz, sizeof(SVariablesInfo));
8,170✔
1280
  if (pInfos == NULL) {
8,170✔
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) {
1,013,080✔
1285
    SConfigItem   *pItem = taosArrayGet(pItems, i);
1,004,910✔
1286
    SVariablesInfo info = {0};
1,004,910✔
1287
    tstrncpy(info.name, pItem->name, sizeof(info.name));
1,004,910✔
1288
    if (likePattern != NULL && rawStrPatternMatch(pItem->name, likePattern) != TSDB_PATTERN_MATCH) {
1,004,910✔
1289
      continue;
533,678✔
1290
    }
1291
#ifdef TD_ENTERPRISE
1292
    if (!mndShowVarPrivAllowed(showPrivMask, pItem->privType)) {
471,232✔
1293
      continue;
19,880✔
1294
    }
1295
#endif
1296

1297
    // init info value
1298
    switch (pItem->dtype) {
451,352✔
1299
      case CFG_DTYPE_NONE:
×
1300
        break;
×
1301
      case CFG_DTYPE_BOOL:
102,358✔
1302
        snprintf(info.value, sizeof(info.value), "%d", pItem->bval);
102,358✔
1303
        break;
102,358✔
1304
      case CFG_DTYPE_INT32:
230,038✔
1305
        snprintf(info.value, sizeof(info.value), "%d", pItem->i32);
230,038✔
1306
        break;
230,038✔
1307
      case CFG_DTYPE_INT64:
26,313✔
1308
        snprintf(info.value, sizeof(info.value), "%" PRId64, pItem->i64);
26,313✔
1309
        break;
26,313✔
1310
      case CFG_DTYPE_FLOAT:
7,518✔
1311
      case CFG_DTYPE_DOUBLE:
1312
        snprintf(info.value, sizeof(info.value), "%f", pItem->fval);
7,518✔
1313
        break;
7,518✔
1314
      case CFG_DTYPE_STRING:
85,125✔
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);
85,125✔
1320
        break;
85,125✔
1321
    }
1322

1323
    // init info scope
1324
    switch (pItem->scope) {
451,352✔
1325
      case CFG_SCOPE_SERVER:
374,303✔
1326
        tstrncpy(info.scope, "server", sizeof(info.scope));
374,303✔
1327
        break;
374,303✔
1328
      case CFG_SCOPE_CLIENT:
×
1329
        tstrncpy(info.scope, "client", sizeof(info.scope));
×
1330
        break;
×
1331
      case CFG_SCOPE_BOTH:
77,049✔
1332
        tstrncpy(info.scope, "both", sizeof(info.scope));
77,049✔
1333
        break;
77,049✔
1334
      default:
×
1335
        tstrncpy(info.scope, "unknown", sizeof(info.scope));
×
1336
        break;
×
1337
    }
1338
    // init info category
1339
    switch (pItem->category) {
451,352✔
1340
      case CFG_CATEGORY_GLOBAL:
451,352✔
1341
        tstrncpy(info.category, "global", sizeof(info.category));
451,352✔
1342
        break;
451,352✔
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)) {
451,352✔
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;
8,170✔
1358
}
1359

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

1368
  code = tDeserializeSShowVariablesReq(pReq->pCont, pReq->contLen, &req);
8,170✔
1369
  if (code != 0) {
8,170✔
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) {
8,170✔
1375
    goto _OVER;
×
1376
  }
1377

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

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

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

1408
_OVER:
8,170✔
1409

1410
  if (code != 0) {
8,170✔
1411
    mError("failed to get show variables info since %s", tstrerror(code));
×
1412
  }
1413
  mndReleaseUser(pMnode, pUser);
8,170✔
1414
  tFreeSShowVariablesReq(&req);
8,170✔
1415
  tFreeSShowVariablesRsp(&rsp);
8,170✔
1416
  TAOS_RETURN(code);
8,170✔
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