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

taosdata / TDengine / #3578

11 Jan 2025 11:19AM UTC coverage: 63.183% (-0.03%) from 63.211%
#3578

push

travis-ci

web-flow
Merge pull request #29546 from taosdata/merge/mainto3.0

merge: from main to 3.0 branch

139873 of 284461 branches covered (49.17%)

Branch coverage included in aggregate %.

20 of 26 new or added lines in 2 files covered. (76.92%)

717 existing lines in 102 files now uncovered.

217827 of 281671 relevant lines covered (77.33%)

19620733.66 hits per line

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

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

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

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

31
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pInMCfgReq, int32_t optLen, int32_t *pOutValue);
32
static int32_t mndProcessShowVariablesReq(SRpcMsg *pReq);
33
static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq);
34
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp);
35
static int32_t mndProcessConfigReq(SRpcMsg *pReq);
36
static int32_t mndInitWriteCfg(SMnode *pMnode);
37
static int32_t mndSendRebuildReq(SMnode *pMnode);
38
static int32_t mndTryRebuildConfigSdbRsp(SRpcMsg *pRsp);
39
static int32_t initConfigArrayFromSdb(SMnode *pMnode, SArray *array);
40
static int32_t mndTryRebuildConfigSdb(SRpcMsg *pReq);
41
static void    cfgArrayCleanUp(SArray *array);
42
static void    cfgObjArrayCleanUp(SArray *array);
43

44
static int32_t mndConfigUpdateTrans(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
45
                                    int32_t tsmmConfigVersion);
46

47
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *obj);
48

49
int32_t mndInitConfig(SMnode *pMnode) {
1,730✔
50
  int32_t   code = 0;
1,730✔
51
  SSdbTable table = {.sdbType = SDB_CFG,
1,730✔
52
                     .keyType = SDB_KEY_BINARY,
53
                     .encodeFp = (SdbEncodeFp)mnCfgActionEncode,
54
                     .decodeFp = (SdbDecodeFp)mndCfgActionDecode,
55
                     .insertFp = (SdbInsertFp)mndCfgActionInsert,
56
                     .updateFp = (SdbUpdateFp)mndCfgActionUpdate,
57
                     .deleteFp = (SdbDeleteFp)mndCfgActionDelete,
58
                     .deployFp = (SdbDeployFp)mndCfgActionDeploy,
59
                     .afterRestoredFp = (SdbAfterRestoredFp)mndCfgActionAfterRestored};
60

61
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG, mndProcessConfigReq);
1,730✔
62
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeReq);
1,730✔
63
  mndSetMsgHandle(pMnode, TDMT_DND_CONFIG_DNODE_RSP, mndProcessConfigDnodeRsp);
1,730✔
64
  mndSetMsgHandle(pMnode, TDMT_MND_SHOW_VARIABLES, mndProcessShowVariablesReq);
1,730✔
65
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB, mndTryRebuildConfigSdb);
1,730✔
66
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB_RSP, mndTryRebuildConfigSdbRsp);
1,730✔
67

68
  return sdbSetTable(pMnode->pSdb, table);
1,730✔
69
}
70

71
SSdbRaw *mnCfgActionEncode(SConfigObj *obj) {
401,089✔
72
  int32_t  code = 0;
401,089✔
73
  int32_t  lino = 0;
401,089✔
74
  void    *buf = NULL;
401,089✔
75
  SSdbRaw *pRaw = NULL;
401,089✔
76

77
  SEncoder encoder;
78
  tEncoderInit(&encoder, NULL, 0);
401,089✔
79
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
401,089!
80
    tEncoderClear(&encoder);
×
81
    TSDB_CHECK_CODE(code, lino, _over);
×
82
  }
83

84
  int32_t tlen = encoder.pos;
401,089✔
85
  tEncoderClear(&encoder);
401,089✔
86

87
  int32_t size = sizeof(int32_t) + tlen;
401,089✔
88
  pRaw = sdbAllocRaw(SDB_CFG, CFG_VER_NUMBER, size);
401,089✔
89
  TSDB_CHECK_NULL(pRaw, code, lino, _over, terrno);
401,089!
90

91
  buf = taosMemoryMalloc(tlen);
401,089!
92
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
401,089!
93

94
  tEncoderInit(&encoder, buf, tlen);
401,089✔
95
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
401,089!
96
    tEncoderClear(&encoder);
×
97
    TSDB_CHECK_CODE(code, lino, _over);
×
98
  }
99

100
  tEncoderClear(&encoder);
401,089✔
101

102
  int32_t dataPos = 0;
401,089✔
103
  SDB_SET_INT32(pRaw, dataPos, tlen, _over);
401,089!
104
  SDB_SET_BINARY(pRaw, dataPos, buf, tlen, _over);
401,089!
105
  SDB_SET_DATALEN(pRaw, dataPos, _over);
401,089!
106

107
_over:
401,089✔
108
  taosMemoryFreeClear(buf);
401,089!
109
  if (code != TSDB_CODE_SUCCESS) {
401,089!
110
    mError("cfg:%s, failed to encode to raw:%p at line:%d since %s", obj->name, pRaw, lino, tstrerror(code));
×
111
    sdbFreeRaw(pRaw);
×
112
    terrno = code;
×
113
    return NULL;
×
114
  }
115

116
  terrno = 0;
401,089✔
117
  mTrace("cfg:%s, encode to raw:%p, row:%p", obj->name, pRaw, obj);
401,089✔
118
  return pRaw;
401,089✔
119
}
120

121
SSdbRow *mndCfgActionDecode(SSdbRaw *pRaw) {
164,225✔
122
  int32_t     code = 0;
164,225✔
123
  int32_t     lino = 0;
164,225✔
124
  SSdbRow    *pRow = NULL;
164,225✔
125
  SConfigObj *pObj = NULL;
164,225✔
126
  void       *buf = NULL;
164,225✔
127
  int8_t      sver = 0;
164,225✔
128
  int32_t     tlen;
129
  int32_t     dataPos = 0;
164,225✔
130

131
  code = sdbGetRawSoftVer(pRaw, &sver);
164,225✔
132
  TSDB_CHECK_CODE(code, lino, _over);
164,225!
133

134
  if (sver != CFG_VER_NUMBER) {
164,225!
135
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
136
    goto _over;
×
137
  }
138

139
  pRow = sdbAllocRow(sizeof(SConfigObj));
164,225✔
140
  TSDB_CHECK_NULL(pRow, code, lino, _over, terrno);
164,225!
141

142
  pObj = sdbGetRowObj(pRow);
164,225✔
143
  TSDB_CHECK_NULL(pObj, code, lino, _over, terrno);
164,225!
144

145
  SDB_GET_INT32(pRaw, dataPos, &tlen, _over);
164,225!
146

147
  buf = taosMemoryMalloc(tlen + 1);
164,225!
148
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
164,225!
149

150
  SDB_GET_BINARY(pRaw, dataPos, buf, tlen, _over);
164,225!
151

152
  SDecoder decoder;
153
  tDecoderInit(&decoder, buf, tlen + 1);
164,225✔
154
  code = tDecodeSConfigObj(&decoder, pObj);
164,225✔
155
  tDecoderClear(&decoder);
164,225✔
156

157
  if (code < 0) {
164,225!
158
    tFreeSConfigObj(pObj);
×
159
  }
160

161
_over:
164,225✔
162
  taosMemoryFreeClear(buf);
164,225!
163

164
  if (code != TSDB_CODE_SUCCESS) {
164,225!
165
    mError("cfg:%s, failed to decode from raw:%p since %s at:%d", pObj->name, pRaw, tstrerror(code), lino);
×
166
    taosMemoryFreeClear(pRow);
×
167
    terrno = code;
×
168
    return NULL;
×
169
  } else {
170
    mTrace("config:%s, decode from raw:%p, row:%p", pObj->name, pRaw, pObj);
164,225✔
171
    terrno = 0;
164,225✔
172
    return pRow;
164,225✔
173
  }
174
}
175

176
static int32_t mndCfgActionInsert(SSdb *pSdb, SConfigObj *obj) {
161,878✔
177
  mTrace("cfg:%s, perform insert action, row:%p", obj->name, obj);
161,878✔
178
  return 0;
161,878✔
179
}
180

181
static int32_t mndCfgActionDelete(SSdb *pSdb, SConfigObj *obj) {
164,131✔
182
  mTrace("cfg:%s, perform delete action, row:%p", obj->name, obj);
164,131✔
183
  tFreeSConfigObj(obj);
164,131✔
184
  return 0;
164,131✔
185
}
186

187
static int32_t mndCfgActionUpdate(SSdb *pSdb, SConfigObj *pOld, SConfigObj *pNew) {
2,347✔
188
  mTrace("cfg:%s, perform update action, old row:%p new row:%p", pOld->name, pOld, pNew);
2,347!
189
  switch (pNew->dtype) {
2,347!
190
    case CFG_DTYPE_NONE:
×
191
      break;
×
192
    case CFG_DTYPE_BOOL:
64✔
193
      pOld->bval = pNew->bval;
64✔
194
      break;
64✔
195
    case CFG_DTYPE_INT32:
1,495✔
196
      pOld->i32 = pNew->i32;
1,495✔
197
      break;
1,495✔
198
    case CFG_DTYPE_INT64:
28✔
199
      pOld->i64 = pNew->i64;
28✔
200
      break;
28✔
201
    case CFG_DTYPE_FLOAT:
8✔
202
    case CFG_DTYPE_DOUBLE:
203
      pOld->fval = pNew->fval;
8✔
204
      break;
8✔
205
    case CFG_DTYPE_STRING:
752✔
206
    case CFG_DTYPE_DIR:
207
    case CFG_DTYPE_LOCALE:
208
    case CFG_DTYPE_CHARSET:
209
    case CFG_DTYPE_TIMEZONE:
210
      taosMemoryFree(pOld->str);
752!
211
      pOld->str = taosStrdup(pNew->str);
752!
212
      if (pOld->str == NULL) {
752!
213
        return terrno;
×
214
      }
215
      break;
752✔
216
  }
217
  return TSDB_CODE_SUCCESS;
2,347✔
218
}
219

220
static int32_t mndCfgActionDeploy(SMnode *pMnode) { return mndInitWriteCfg(pMnode); }
1,240✔
221

222
static int32_t mndCfgActionAfterRestored(SMnode *pMnode) { return mndSendRebuildReq(pMnode); }
518✔
223

224
static int32_t mndProcessConfigReq(SRpcMsg *pReq) {
2,089✔
225
  SMnode    *pMnode = pReq->info.node;
2,089✔
226
  SConfigReq configReq = {0};
2,089✔
227
  int32_t    code = TSDB_CODE_SUCCESS;
2,089✔
228
  SArray    *array = NULL;
2,089✔
229

230
  code = tDeserializeSConfigReq(pReq->pCont, pReq->contLen, &configReq);
2,089✔
231
  if (code != 0) {
2,089!
232
    mError("failed to deserialize config req, since %s", terrstr());
×
233
    goto _OVER;
×
234
  }
235

236
  SConfigObj *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
2,089✔
237
  if (vObj == NULL) {
2,089!
238
    mInfo("failed to acquire mnd config version, since %s", terrstr());
×
239
    goto _OVER;
×
240
  }
241

242
  array = taosArrayInit(16, sizeof(SConfigItem));
2,089✔
243
  if (array == NULL) {
2,089!
244
    code = TSDB_CODE_OUT_OF_MEMORY;
×
245
    goto _OVER;
×
246
  }
247
  SConfigRsp configRsp = {0};
2,089✔
248
  configRsp.forceReadConfig = configReq.forceReadConfig;
2,089✔
249

250
  configRsp.cver = vObj->i32;
2,089✔
251
  if (configRsp.forceReadConfig) {
2,089!
252
    // compare config array from configReq with current config array
253
    if (compareSConfigItemArrays(taosGetGlobalCfg(tsCfg), configReq.array, array)) {
×
254
      configRsp.array = array;
×
255
    } else {
256
      configRsp.isConifgVerified = 1;
×
257
    }
258
  } else {
259
    if (configReq.cver == vObj->i32) {
2,089✔
260
      configRsp.isVersionVerified = 1;
386✔
261
    } else {
262
      code = initConfigArrayFromSdb(pMnode, array);
1,703✔
263
      if (code != 0) {
1,703!
264
        mError("failed to init config array from sdb, since %s", terrstr());
×
265
        goto _OVER;
×
266
      }
267
      configRsp.array = array;
1,703✔
268
    }
269
  }
270

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

290
_OVER:
2,089✔
291
  if (code != 0) {
2,089!
292
    mError("failed to process config req, since %s", tstrerror(code));
×
293
  }
294
  sdbRelease(pMnode->pSdb, vObj);
2,089✔
295
  cfgArrayCleanUp(array);
2,089✔
296
  return TSDB_CODE_SUCCESS;
2,089✔
297
}
298

299
int32_t mndInitWriteCfg(SMnode *pMnode) {
1,240✔
300
  int    code = 0;
1,240✔
301
  size_t sz = 0;
1,240✔
302

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

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

320
  for (int i = 0; i < sz; ++i) {
115,816✔
321
    SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
114,576✔
322
    SConfigObj   obj;
323
    if ((code = mndInitConfigObj(item, &obj)) != 0) {
114,576!
UNCOV
324
      goto _OVER;
×
325
    }
326
    if ((code = mndSetCreateConfigCommitLogs(pTrans, &obj)) != 0) {
114,576!
327
      mError("failed to init mnd config:%s, since %s", item->name, tstrerror(code));
×
NEW
328
      tFreeSConfigObj(&obj);
×
329
      goto _OVER;
×
330
    }
331
    tFreeSConfigObj(&obj);
114,576✔
332
  }
333
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
1,240!
334

335
_OVER:
1,240✔
336
  if (code != 0) {
1,240!
337
    mError("failed to init write cfg, since %s", tstrerror(code));
×
338
  }
339
  mndTransDrop(pTrans);
1,240✔
340
  return code;
1,240✔
341
}
342

343
int32_t mndSendRebuildReq(SMnode *pMnode) {
518✔
344
  int32_t code = 0;
518✔
345

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

356
  mndGetMnodeEpSet(pMnode, &epSet);
518✔
357

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

365
static int32_t mndTryRebuildConfigSdb(SRpcMsg *pReq) {
520✔
366
  SMnode *pMnode = pReq->info.node;
520✔
367
  if (!mndIsLeader(pMnode)) {
520!
368
    return TSDB_CODE_SUCCESS;
×
369
  }
370
  int32_t     code = 0;
520✔
371
  int32_t     sz = -1;
520✔
372
  STrans     *pTrans = NULL;
520✔
373
  SConfigObj *vObj = NULL;
520✔
374
  SArray     *addArray = NULL;
520✔
375

376
  vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
520✔
377
  if (vObj == NULL) {
520!
378
    if ((code = mndInitWriteCfg(pMnode)) < 0) goto _exit;
×
379
    mInfo("failed to acquire mnd config version, try to rebuild config in sdb.");
×
380
  } else {
381
    sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
520✔
382
    addArray = taosArrayInit(4, sizeof(SConfigObj));
520✔
383
    for (int i = 0; i < sz; ++i) {
48,880✔
384
      SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
48,360✔
385
      SConfigObj  *obj = sdbAcquire(pMnode->pSdb, SDB_CFG, item->name);
48,360✔
386
      if (obj == NULL) {
48,360!
NEW
387
        mInfo("config:%s, not exist in sdb, try to add it", item->name);
×
388
        SConfigObj newObj;
NEW
389
        if ((code = mndInitConfigObj(item, &newObj)) != 0) goto _exit;
×
NEW
390
        if (NULL == taosArrayPush(addArray, &newObj)) {
×
391
          code = terrno;
×
392
          goto _exit;
×
393
        }
394
      } else {
395
        sdbRelease(pMnode->pSdb, obj);
48,360✔
396
      }
397
    }
398
    int32_t addSize = taosArrayGetSize(addArray);
520✔
399
    if (addSize > 0) {
520!
400
      pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "add-config");
×
401
      if (pTrans == NULL) {
×
402
        code = terrno;
×
403
        goto _exit;
×
404
      }
405
      for (int i = 0; i < addSize; ++i) {
×
406
        SConfigObj *AddObj = taosArrayGet(addArray, i);
×
407
        if ((code = mndSetCreateConfigCommitLogs(pTrans, AddObj)) != 0) goto _exit;
×
408
      }
409
      if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _exit;
×
410
      mInfo("add new config to sdb, nums:%d", addSize);
×
411
    }
412
  }
413
_exit:
520✔
414
  if (code != 0) {
520!
415
    mError("failed to try rebuild config in sdb, since %s", tstrerror(code));
×
416
  }
417
  sdbRelease(pMnode->pSdb, vObj);
520✔
418
  cfgObjArrayCleanUp(addArray);
520✔
419
  mndTransDrop(pTrans);
520✔
420
  TAOS_RETURN(code);
520✔
421
}
422

423
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *item) {
117,884✔
424
  int32_t  code = 0;
117,884✔
425
  SSdbRaw *pCommitRaw = mnCfgActionEncode(item);
117,884✔
426
  if (pCommitRaw == NULL) {
117,884!
427
    code = terrno;
×
428
    TAOS_RETURN(code);
×
429
  }
430
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw) != 0)) TAOS_RETURN(code);
117,884!
431
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY)) != 0) TAOS_RETURN(code);
117,884!
432
  return TSDB_CODE_SUCCESS;
117,884✔
433
}
434

435
static int32_t mndMCfg2DCfg(SMCfgDnodeReq *pMCfgReq, SDCfgDnodeReq *pDCfgReq) {
1,116✔
436
  int32_t code = 0;
1,116✔
437
  char   *p = pMCfgReq->config;
1,116✔
438
  while (*p) {
15,467✔
439
    if (*p == ' ') {
14,540✔
440
      break;
189✔
441
    }
442
    p++;
14,351✔
443
  }
444

445
  size_t optLen = p - pMCfgReq->config;
1,116✔
446
  tstrncpy(pDCfgReq->config, pMCfgReq->config, sizeof(pDCfgReq->config));
1,116✔
447
  pDCfgReq->config[optLen] = 0;
1,116✔
448

449
  if (' ' == pMCfgReq->config[optLen]) {
1,116✔
450
    // 'key value'
451
    if (strlen(pMCfgReq->value) != 0) goto _err;
189!
452
    tstrncpy(pDCfgReq->value, p + 1, sizeof(pDCfgReq->value));
189✔
453
  } else {
454
    // 'key' 'value'
455
    if (strlen(pMCfgReq->value) == 0) goto _err;
927✔
456
    tstrncpy(pDCfgReq->value, pMCfgReq->value, sizeof(pDCfgReq->value));
926✔
457
  }
458

459
  TAOS_RETURN(code);
1,115✔
460

461
_err:
1✔
462
  mError("dnode:%d, failed to config since invalid conf:%s", pMCfgReq->dnodeId, pMCfgReq->config);
1!
463
  code = TSDB_CODE_INVALID_CFG;
1✔
464
  TAOS_RETURN(code);
1✔
465
}
466

467
static int32_t mndSendCfgDnodeReq(SMnode *pMnode, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
1,104✔
468
  int32_t code = -1;
1,104✔
469
  SSdb   *pSdb = pMnode->pSdb;
1,104✔
470
  void   *pIter = NULL;
1,104✔
471

472
  int64_t curMs = taosGetTimestampMs();
1,104✔
473

474
  while (1) {
1,425✔
475
    SDnodeObj *pDnode = NULL;
2,529✔
476
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
2,529✔
477
    if (pIter == NULL) break;
2,529✔
478

479
    if (pDnode->id == dnodeId || dnodeId == -1 || dnodeId == 0) {
1,425!
480
      bool online = mndIsDnodeOnline(pDnode, curMs);
1,404✔
481
      if (!online) {
1,404✔
482
        mWarn("dnode:%d, is offline, skip to send config req", pDnode->id);
1!
483
        continue;
1✔
484
      }
485
      SEpSet  epSet = mndGetDnodeEpset(pDnode);
1,403✔
486
      int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, pDcfgReq);
1,403✔
487
      void   *pBuf = rpcMallocCont(bufLen);
1,403✔
488

489
      if (pBuf == NULL) {
1,403!
490
        sdbCancelFetch(pMnode->pSdb, pIter);
×
491
        sdbRelease(pMnode->pSdb, pDnode);
×
492
        code = TSDB_CODE_OUT_OF_MEMORY;
×
493
        return code;
×
494
      }
495

496
      if ((bufLen = tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq)) <= 0) {
1,403!
497
        sdbCancelFetch(pMnode->pSdb, pIter);
×
498
        sdbRelease(pMnode->pSdb, pDnode);
×
499
        code = bufLen;
×
500
        rpcFreeCont(pBuf);
×
501
        return code;
×
502
      }
503

504
      mInfo("dnode:%d, send config req to dnode, config:%s value:%s", pDnode->id, pDcfgReq->config, pDcfgReq->value);
1,403!
505
      SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pBuf, .contLen = bufLen};
1,403✔
506
      SRpcMsg rpcRsp = {0};
1,403✔
507

508
      code = rpcSendRecvWithTimeout(pMnode->msgCb.statusRpc, &epSet, &rpcMsg, &rpcRsp, NULL, CFG_ALTER_TIMEOUT);
1,403✔
509
      if (code != 0) {
1,403!
510
        mError("failed to send config req to dnode:%d, since %s", pDnode->id, tstrerror(code));
×
511
        sdbCancelFetch(pMnode->pSdb, pIter);
×
512
        sdbRelease(pMnode->pSdb, pDnode);
×
513
        return code;
×
514
      }
515

516
      code = rpcRsp.code;
1,403✔
517
      if (code != 0) {
1,403!
518
        mError("failed to alter config %s,on dnode:%d, since %s", pDcfgReq->config, pDnode->id, tstrerror(code));
×
519
        sdbCancelFetch(pMnode->pSdb, pIter);
×
520
        sdbRelease(pMnode->pSdb, pDnode);
×
521
        return code;
×
522
      }
523
      rpcFreeCont(rpcRsp.pCont);
1,403✔
524
    }
525
    sdbRelease(pSdb, pDnode);
1,424✔
526
  }
527

528
  if (code == -1) {
1,104✔
529
    code = TSDB_CODE_MND_DNODE_NOT_EXIST;
5✔
530
  }
531
  TAOS_RETURN(code);
1,104✔
532
}
533

534
static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
1,125✔
535
  int32_t       code = 0;
1,125✔
536
  int32_t       lino = -1;
1,125✔
537
  SMnode       *pMnode = pReq->info.node;
1,125✔
538
  SMCfgDnodeReq cfgReq = {0};
1,125✔
539
  SConfigObj   *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
1,125✔
540
  if (vObj == NULL) {
1,125!
541
    code = TSDB_CODE_SDB_OBJ_NOT_THERE;
×
542
    mInfo("failed to acquire mnd config version, since %s", tstrerror(code));
×
543
    goto _err_out;
×
544
  }
545

546
  TAOS_CHECK_RETURN(tDeserializeSMCfgDnodeReq(pReq->pCont, pReq->contLen, &cfgReq));
1,125!
547
  int8_t updateIpWhiteList = 0;
1,125✔
548
  mInfo("dnode:%d, start to config, option:%s, value:%s", cfgReq.dnodeId, cfgReq.config, cfgReq.value);
1,125!
549
  if ((code = mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONFIG_DNODE)) != 0) {
1,125✔
550
    goto _err_out;
7✔
551
  }
552

553
  SDCfgDnodeReq dcfgReq = {0};
1,118✔
554
  if (strcasecmp(cfgReq.config, "resetlog") == 0) {
1,118✔
555
    tstrncpy(dcfgReq.config, "resetlog", 9);
2✔
556
    goto _send_req;
2✔
557
#ifdef TD_ENTERPRISE
558
  } else if (strncasecmp(cfgReq.config, "s3blocksize", 12) == 0) {
1,116!
559
    int32_t optLen = strlen("s3blocksize");
×
560
    int32_t flag = -1;
×
561
    int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
×
562
    if (code < 0) {
×
563
      goto _err_out;
×
564
    }
565

566
    if (flag > 1024 * 1024 || (flag > -1 && flag < 1024) || flag < -1) {
×
567
      mError("dnode:%d, failed to config s3blocksize since value:%d. Valid range: -1 or [1024, 1024 * 1024]",
×
568
             cfgReq.dnodeId, flag);
569
      code = TSDB_CODE_INVALID_CFG;
×
570
      goto _err_out;
×
571
    }
572

573
    tstrncpy(dcfgReq.config, "s3blocksize", 12);
×
574
    snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
×
575
#endif
576
  } else {
577
    TAOS_CHECK_GOTO(mndMCfg2DCfg(&cfgReq, &dcfgReq), &lino, _err_out);
1,116✔
578
    if (strlen(dcfgReq.config) > TSDB_DNODE_CONFIG_LEN) {
1,115!
579
      mError("dnode:%d, failed to config since config is too long", cfgReq.dnodeId);
×
580
      code = TSDB_CODE_INVALID_CFG;
×
581
      goto _err_out;
×
582
    }
583
    if (strncasecmp(dcfgReq.config, "enableWhiteList", strlen("enableWhiteList")) == 0) {
1,115✔
584
      updateIpWhiteList = 1;
2✔
585
    }
586

587
    CfgAlterType alterType = (cfgReq.dnodeId == 0 || cfgReq.dnodeId == -1) ? CFG_ALTER_ALL_DNODES : CFG_ALTER_DNODE;
1,115!
588
    TAOS_CHECK_GOTO(cfgCheckRangeForDynUpdate(taosGetCfg(), dcfgReq.config, dcfgReq.value, true, alterType), &lino,
1,115✔
589
                    _err_out);
590
  }
591
  SConfigItem *pItem = cfgGetItem(taosGetCfg(), dcfgReq.config);
1,102✔
592
  // Update config in sdb.
593
  if (pItem == NULL) {
1,102!
594
    mError("failed to find config:%s while process config dnode req", cfgReq.config);
×
595
    code = TSDB_CODE_CFG_NOT_FOUND;
×
596
    goto _err_out;
×
597
  }
598
  if (pItem->category == CFG_CATEGORY_GLOBAL) {
1,102✔
599
    TAOS_CHECK_GOTO(mndConfigUpdateTrans(pMnode, dcfgReq.config, dcfgReq.value, pItem->dtype, ++vObj->i32), &lino,
1,034!
600
                    _err_out);
601
  }
602
_send_req :
1,102✔
603

604
{  // audit
605
  char obj[50] = {0};
1,104✔
606
  (void)tsnprintf(obj, sizeof(obj), "%d", cfgReq.dnodeId);
1,104✔
607

608
  auditRecord(pReq, pMnode->clusterId, "alterDnode", obj, "", cfgReq.sql, cfgReq.sqlLen);
1,104✔
609
}
610
  dcfgReq.version = vObj->i32;
1,104✔
611
  code = mndSendCfgDnodeReq(pMnode, cfgReq.dnodeId, &dcfgReq);
1,104✔
612
  if (code != 0) {
1,104✔
613
    mError("failed to send config req to dnode:%d, since %s", cfgReq.dnodeId, tstrerror(code));
5!
614
    goto _err_out;
5✔
615
  }
616
  // dont care suss or succ;
617
  if (updateIpWhiteList) mndRefreshUserIpWhiteList(pMnode);
1,099✔
618
  tFreeSMCfgDnodeReq(&cfgReq);
1,099✔
619
  sdbRelease(pMnode->pSdb, vObj);
1,099✔
620
  TAOS_RETURN(code);
1,099✔
621

622
_err_out:
26✔
623
  mError("failed to process config dnode req, since %s", tstrerror(code));
26!
624
  tFreeSMCfgDnodeReq(&cfgReq);
26✔
625
  sdbRelease(pMnode->pSdb, vObj);
26✔
626
  TAOS_RETURN(code);
26✔
627
}
628

629
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) {
×
630
  mInfo("config rsp from dnode");
×
631
  return 0;
×
632
}
633

634
static int32_t mndTryRebuildConfigSdbRsp(SRpcMsg *pRsp) {
517✔
635
  mInfo("rebuild config sdb rsp");
517!
636
  return 0;
517✔
637
}
638

639
// get int32_t value from 'SMCfgDnodeReq'
640
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pMCfgReq, int32_t optLen, int32_t *pOutValue) {
×
641
  int32_t code = 0;
×
642
  if (' ' != pMCfgReq->config[optLen] && 0 != pMCfgReq->config[optLen]) {
×
643
    goto _err;
×
644
  }
645

646
  if (' ' == pMCfgReq->config[optLen]) {
×
647
    // 'key value'
648
    if (strlen(pMCfgReq->value) != 0) goto _err;
×
649
    *pOutValue = taosStr2Int32(pMCfgReq->config + optLen + 1, NULL, 10);
×
650
  } else {
651
    // 'key' 'value'
652
    if (strlen(pMCfgReq->value) == 0) goto _err;
×
653
    *pOutValue = taosStr2Int32(pMCfgReq->value, NULL, 10);
×
654
  }
655

656
  TAOS_RETURN(code);
×
657

658
_err:
×
659
  mError(" failed to set config since:%s", tstrerror(code));
×
660
  TAOS_RETURN(code);
×
661
}
662

663
static int32_t mndConfigUpdateTrans(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
1,034✔
664
                                    int32_t tsmmConfigVersion) {
665
  int32_t     code = -1;
1,034✔
666
  int32_t     lino = -1;
1,034✔
667
  SConfigObj *pVersion = taosMemoryMalloc(sizeof(SConfigObj)), *pObj = taosMemoryMalloc(sizeof(SConfigObj));
1,034!
668
  if (pVersion == NULL || pObj == NULL) {
1,034!
669
    code = terrno;
×
670
    goto _OVER;
×
671
  }
672
  tstrncpy(pVersion->name, "tsmmConfigVersion", CFG_NAME_MAX_LEN);
1,034✔
673
  pVersion->dtype = CFG_DTYPE_INT32;
1,034✔
674
  pVersion->i32 = tsmmConfigVersion;
1,034✔
675

676
  pObj->dtype = dtype;
1,034✔
677
  tstrncpy(pObj->name, name, CFG_NAME_MAX_LEN);
1,034✔
678

679
  TAOS_CHECK_GOTO(mndUpdateObj(pObj, name, pValue), &lino, _OVER);
1,034!
680
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, NULL, "update-config");
1,034✔
681
  if (pTrans == NULL) {
1,034!
682
    code = terrno;
×
683
    goto _OVER;
×
684
  }
685
  mInfo("trans:%d, used to update config:%s to value:%s", pTrans->id, name, pValue);
1,034!
686
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pVersion), &lino, _OVER);
1,034!
687
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pObj), &lino, _OVER);
1,034!
688
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
1,034!
689
  code = 0;
1,034✔
690
_OVER:
1,034✔
691
  if (code != 0) {
1,034!
692
    mError("failed to update config:%s to value:%s, since %s", name, pValue, tstrerror(code));
×
693
  }
694
  mndTransDrop(pTrans);
1,034✔
695
  tFreeSConfigObj(pVersion);
1,034✔
696
  taosMemoryFree(pVersion);
1,034!
697
  tFreeSConfigObj(pObj);
1,034✔
698
  taosMemoryFree(pObj);
1,034!
699
  return code;
1,034✔
700
}
701

702
static int32_t initConfigArrayFromSdb(SMnode *pMnode, SArray *array) {
1,703✔
703
  int32_t     code = 0;
1,703✔
704
  SSdb       *pSdb = pMnode->pSdb;
1,703✔
705
  void       *pIter = NULL;
1,703✔
706
  SConfigObj *obj = NULL;
1,703✔
707

708
  while (1) {
158,501✔
709
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
160,204✔
710
    if (pIter == NULL) break;
160,204✔
711
    if (obj == NULL) {
158,501!
712
      code = TSDB_CODE_OUT_OF_MEMORY;
×
713
      goto _exit;
×
714
    }
715
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
158,501✔
716
      sdbRelease(pSdb, obj);
1,703✔
717
      continue;
1,703✔
718
    }
719
    SConfigItem item = {0};
156,798✔
720
    item.dtype = obj->dtype;
156,798✔
721
    item.name = taosStrdup(obj->name);
156,798!
722
    if (item.name == NULL) {
156,798!
723
      code = terrno;
×
724
      sdbCancelFetch(pSdb, pIter);
×
725
      sdbRelease(pSdb, obj);
×
726
      goto _exit;
×
727
    }
728
    switch (obj->dtype) {
156,798!
729
      case CFG_DTYPE_NONE:
×
730
        break;
×
731
      case CFG_DTYPE_BOOL:
30,348✔
732
        item.bval = obj->bval;
30,348✔
733
        break;
30,348✔
734
      case CFG_DTYPE_INT32:
82,614✔
735
        item.i32 = obj->i32;
82,614✔
736
        break;
82,614✔
737
      case CFG_DTYPE_INT64:
15,174✔
738
        item.i64 = obj->i64;
15,174✔
739
        break;
15,174✔
740
      case CFG_DTYPE_FLOAT:
5,058✔
741
      case CFG_DTYPE_DOUBLE:
742
        item.fval = obj->fval;
5,058✔
743
        break;
5,058✔
744
      case CFG_DTYPE_STRING:
23,604✔
745
      case CFG_DTYPE_DIR:
746
      case CFG_DTYPE_LOCALE:
747
      case CFG_DTYPE_CHARSET:
748
      case CFG_DTYPE_TIMEZONE:
749
        item.str = taosStrdup(obj->str);
23,604!
750
        if (item.str == NULL) {
23,604!
751
          sdbCancelFetch(pSdb, pIter);
×
752
          sdbRelease(pSdb, obj);
×
753
          code = terrno;
×
754
          goto _exit;
×
755
        }
756
        break;
23,604✔
757
    }
758
    if (taosArrayPush(array, &item) == NULL) {
156,798!
759
      sdbCancelFetch(pSdb, pIter);
×
760
      sdbRelease(pSdb, obj);
×
761
      code = TSDB_CODE_OUT_OF_MEMORY;
×
762
      goto _exit;
×
763
      break;
764
    }
765
    sdbRelease(pSdb, obj);
156,798✔
766
  }
767
_exit:
1,703✔
768
  if (code != 0) {
1,703!
769
    mError("failed to init config array from sdb, since %s", tstrerror(code));
×
770
  }
771
  return code;
1,703✔
772
}
773

774
static void cfgArrayCleanUp(SArray *array) {
2,089✔
775
  if (array == NULL) {
2,089!
776
    return;
×
777
  }
778

779
  int32_t sz = taosArrayGetSize(array);
2,089✔
780
  for (int32_t i = 0; i < sz; ++i) {
158,887✔
781
    SConfigItem *item = taosArrayGet(array, i);
156,798✔
782
    if (item->dtype == CFG_DTYPE_STRING || item->dtype == CFG_DTYPE_DIR || item->dtype == CFG_DTYPE_LOCALE ||
156,798!
783
        item->dtype == CFG_DTYPE_CHARSET || item->dtype == CFG_DTYPE_TIMEZONE) {
136,566✔
784
      taosMemoryFreeClear(item->str);
23,604!
785
    }
786
    taosMemoryFreeClear(item->name);
156,798!
787
  }
788

789
  taosArrayDestroy(array);
2,089✔
790
}
791

792
static void cfgObjArrayCleanUp(SArray *array) {
520✔
793
  if (array == NULL) {
520!
794
    return;
×
795
  }
796
  int32_t sz = taosArrayGetSize(array);
520✔
797
  for (int32_t i = 0; i < sz; ++i) {
520!
798
    SConfigObj *obj = taosArrayGet(array, i);
×
799
    tFreeSConfigObj(obj);
×
800
  }
801
  taosArrayDestroy(array);
520✔
802
}
803

804
SArray *initVariablesFromItems(SArray *pItems) {
10✔
805
  if (pItems == NULL) {
10!
806
    return NULL;
×
807
  }
808

809
  int32_t sz = taosArrayGetSize(pItems);
10✔
810

811
  SArray *pInfos = taosArrayInit(sz, sizeof(SVariablesInfo));
10✔
812
  if (pInfos == NULL) {
10!
813
    mError("failed to init array while init variables from items, since %s", tstrerror(terrno));
×
814
    return NULL;
×
815
  }
816
  for (int32_t i = 0; i < sz; ++i) {
940✔
817
    SConfigItem   *pItem = taosArrayGet(pItems, i);
930✔
818
    SVariablesInfo info = {0};
930✔
819
    tstrncpy(info.name, pItem->name, sizeof(info.name));
930✔
820

821
    // init info value
822
    switch (pItem->dtype) {
930!
823
      case CFG_DTYPE_NONE:
×
824
        break;
×
825
      case CFG_DTYPE_BOOL:
180✔
826
        tsnprintf(info.value, sizeof(info.value), "%d", pItem->bval);
180✔
827
        break;
180✔
828
      case CFG_DTYPE_INT32:
490✔
829
        tsnprintf(info.value, sizeof(info.value), "%d", pItem->i32);
490✔
830
        break;
490✔
831
      case CFG_DTYPE_INT64:
90✔
832
        tsnprintf(info.value, sizeof(info.value), "%" PRId64, pItem->i64);
90✔
833
        break;
90✔
834
      case CFG_DTYPE_FLOAT:
30✔
835
      case CFG_DTYPE_DOUBLE:
836
        tsnprintf(info.value, sizeof(info.value), "%f", pItem->fval);
30✔
837
        break;
30✔
838
      case CFG_DTYPE_STRING:
140✔
839
      case CFG_DTYPE_DIR:
840
      case CFG_DTYPE_LOCALE:
841
      case CFG_DTYPE_CHARSET:
842
      case CFG_DTYPE_TIMEZONE:
843
        tsnprintf(info.value, sizeof(info.value), "%s", pItem->str);
140✔
844
        break;
140✔
845
    }
846

847
    // init info scope
848
    switch (pItem->scope) {
930!
849
      case CFG_SCOPE_SERVER:
750✔
850
        tstrncpy(info.scope, "server", sizeof(info.scope));
750✔
851
        break;
750✔
852
      case CFG_SCOPE_CLIENT:
10✔
853
        tstrncpy(info.scope, "client", sizeof(info.scope));
10✔
854
        break;
10✔
855
      case CFG_SCOPE_BOTH:
170✔
856
        tstrncpy(info.scope, "both", sizeof(info.scope));
170✔
857
        break;
170✔
858
      default:
×
859
        tstrncpy(info.scope, "unknown", sizeof(info.scope));
×
860
        break;
×
861
    }
862
    // init info category
863
    switch (pItem->category) {
930!
864
      case CFG_CATEGORY_GLOBAL:
930✔
865
        tstrncpy(info.category, "global", sizeof(info.category));
930✔
866
        break;
930✔
867
      case CFG_CATEGORY_LOCAL:
×
868
        tstrncpy(info.category, "local", sizeof(info.category));
×
869
        break;
×
870
      default:
×
871
        tstrncpy(info.category, "unknown", sizeof(info.category));
×
872
        break;
×
873
    }
874
    if (NULL == taosArrayPush(pInfos, &info)) {
930!
875
      mError("failed to push info to array while init variables from items,since %s", tstrerror(terrno));
×
876
      taosArrayDestroy(pInfos);
×
877
      return NULL;
×
878
    }
879
  }
880

881
  return pInfos;
10✔
882
}
883

884
static int32_t mndProcessShowVariablesReq(SRpcMsg *pReq) {
10✔
885
  SShowVariablesRsp rsp = {0};
10✔
886
  int32_t           code = -1;
10✔
887

888
  if ((code = mndCheckOperPrivilege(pReq->info.node, pReq->info.conn.user, MND_OPER_SHOW_VARIABLES)) != 0) {
10!
889
    goto _OVER;
×
890
  }
891

892
  SVariablesInfo info = {0};
10✔
893

894
  rsp.variables = initVariablesFromItems(taosGetGlobalCfg(tsCfg));
10✔
895
  if (rsp.variables == NULL) {
10!
896
    code = terrno;
×
897
    goto _OVER;
×
898
  }
899
  int32_t rspLen = tSerializeSShowVariablesRsp(NULL, 0, &rsp);
10✔
900
  void   *pRsp = rpcMallocCont(rspLen);
10✔
901
  if (pRsp == NULL) {
10!
902
    code = terrno;
×
903
    goto _OVER;
×
904
  }
905

906
  if ((rspLen = tSerializeSShowVariablesRsp(pRsp, rspLen, &rsp)) <= 0) {
10!
907
    rpcFreeCont(pRsp);
×
908
    code = rspLen;
×
909
    goto _OVER;
×
910
  }
911

912
  pReq->info.rspLen = rspLen;
10✔
913
  pReq->info.rsp = pRsp;
10✔
914
  code = 0;
10✔
915

916
_OVER:
10✔
917

918
  if (code != 0) {
10!
919
    mError("failed to get show variables info since %s", tstrerror(code));
×
920
  }
921

922
  tFreeSShowVariablesRsp(&rsp);
10✔
923
  TAOS_RETURN(code);
10✔
924
}
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