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

taosdata / TDengine / #3568

27 Dec 2024 02:27PM UTC coverage: 63.286% (+0.6%) from 62.733%
#3568

push

travis-ci

web-flow
Merge pull request #29378 from taosdata/revert-29377-revert-29165-enh/TD-29974-improve-trans

Revert "Revert "Enh:[td 29974]improve trans""

139941 of 284289 branches covered (49.22%)

Branch coverage included in aggregate %.

105 of 355 new or added lines in 12 files covered. (29.58%)

4077 existing lines in 132 files now uncovered.

218122 of 281494 relevant lines covered (77.49%)

19355607.91 hits per line

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

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

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

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

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

41
static int32_t mndConfigUpdateTrans(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
42
                                    int32_t tsmmConfigVersion);
43

44
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *obj);
45

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

58
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG, mndProcessConfigReq);
1,721✔
59
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeReq);
1,721✔
60
  mndSetMsgHandle(pMnode, TDMT_DND_CONFIG_DNODE_RSP, mndProcessConfigDnodeRsp);
1,721✔
61
  mndSetMsgHandle(pMnode, TDMT_MND_SHOW_VARIABLES, mndProcessShowVariablesReq);
1,721✔
62

63
  return sdbSetTable(pMnode->pSdb, table);
1,721✔
64
}
65

66
SSdbRaw *mnCfgActionEncode(SConfigObj *obj) {
403,042✔
67
  int32_t  code = 0;
403,042✔
68
  int32_t  lino = 0;
403,042✔
69
  void    *buf = NULL;
403,042✔
70
  SSdbRaw *pRaw = NULL;
403,042✔
71

72
  SEncoder encoder;
73
  tEncoderInit(&encoder, NULL, 0);
403,042✔
74
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
403,042!
75
    tEncoderClear(&encoder);
×
76
    TSDB_CHECK_CODE(code, lino, _over);
×
77
  }
78

79
  int32_t tlen = encoder.pos;
403,042✔
80
  tEncoderClear(&encoder);
403,042✔
81

82
  int32_t size = sizeof(int32_t) + tlen;
403,042✔
83
  pRaw = sdbAllocRaw(SDB_CFG, CFG_VER_NUMBER, size);
403,042✔
84
  TSDB_CHECK_NULL(pRaw, code, lino, _over, terrno);
403,042!
85

86
  buf = taosMemoryMalloc(tlen);
403,042!
87
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
403,042!
88

89
  tEncoderInit(&encoder, buf, tlen);
403,042✔
90
  if ((code = tEncodeSConfigObj(&encoder, obj)) < 0) {
403,042!
91
    tEncoderClear(&encoder);
×
92
    TSDB_CHECK_CODE(code, lino, _over);
×
93
  }
94

95
  tEncoderClear(&encoder);
403,042✔
96

97
  int32_t dataPos = 0;
403,042✔
98
  SDB_SET_INT32(pRaw, dataPos, tlen, _over);
403,042!
99
  SDB_SET_BINARY(pRaw, dataPos, buf, tlen, _over);
403,042!
100
  SDB_SET_DATALEN(pRaw, dataPos, _over);
403,042!
101

102
_over:
403,042✔
103
  taosMemoryFreeClear(buf);
403,042!
104
  if (code != TSDB_CODE_SUCCESS) {
403,042!
105
    mError("cfg:%s, failed to encode to raw:%p at line:%d since %s", obj->name, pRaw, lino, tstrerror(code));
×
106
    sdbFreeRaw(pRaw);
×
107
    terrno = code;
×
108
    return NULL;
×
109
  }
110

111
  terrno = 0;
403,042✔
112
  mTrace("cfg:%s, encode to raw:%p, row:%p", obj->name, pRaw, obj);
403,042✔
113
  return pRaw;
403,042✔
114
}
115

116
SSdbRow *mndCfgActionDecode(SSdbRaw *pRaw) {
165,088✔
117
  int32_t     code = 0;
165,088✔
118
  int32_t     lino = 0;
165,088✔
119
  SSdbRow    *pRow = NULL;
165,088✔
120
  SConfigObj *pObj = NULL;
165,088✔
121
  void       *buf = NULL;
165,088✔
122
  int8_t      sver = 0;
165,088✔
123
  int32_t     tlen;
124
  int32_t     dataPos = 0;
165,088✔
125

126
  code = sdbGetRawSoftVer(pRaw, &sver);
165,088✔
127
  TSDB_CHECK_CODE(code, lino, _over);
165,088!
128

129
  if (sver != CFG_VER_NUMBER) {
165,088!
130
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
131
    goto _over;
×
132
  }
133

134
  pRow = sdbAllocRow(sizeof(SConfigObj));
165,088✔
135
  TSDB_CHECK_NULL(pRow, code, lino, _over, terrno);
165,088!
136

137
  pObj = sdbGetRowObj(pRow);
165,088✔
138
  TSDB_CHECK_NULL(pObj, code, lino, _over, terrno);
165,088!
139

140
  SDB_GET_INT32(pRaw, dataPos, &tlen, _over);
165,088!
141

142
  buf = taosMemoryMalloc(tlen + 1);
165,088!
143
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
165,088!
144

145
  SDB_GET_BINARY(pRaw, dataPos, buf, tlen, _over);
165,088!
146

147
  SDecoder decoder;
148
  tDecoderInit(&decoder, buf, tlen + 1);
165,088✔
149
  code = tDecodeSConfigObj(&decoder, pObj);
165,088✔
150
  tDecoderClear(&decoder);
165,088✔
151

152
  if (code < 0) {
165,088!
153
    tFreeSConfigObj(pObj);
×
154
  }
155

156
_over:
165,088✔
157
  taosMemoryFreeClear(buf);
165,088!
158

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

171
static int32_t mndCfgActionInsert(SSdb *pSdb, SConfigObj *obj) {
162,745✔
172
  mTrace("cfg:%s, perform insert action, row:%p", obj->name, obj);
162,745✔
173
  return 0;
162,745✔
174
}
175

176
static int32_t mndCfgActionDelete(SSdb *pSdb, SConfigObj *obj) {
164,993✔
177
  mTrace("cfg:%s, perform delete action, row:%p", obj->name, obj);
164,993✔
178
  tFreeSConfigObj(obj);
164,993✔
179
  return 0;
164,993✔
180
}
181

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

215
static int32_t mndCfgActionDeploy(SMnode *pMnode) { return mndInitWriteCfg(pMnode); }
1,236✔
216

217
static int32_t mndCfgActionAfterRestored(SMnode *pMnode) { return mndTryRebuildCfg(pMnode); }
516✔
218

219
static int32_t mndProcessConfigReq(SRpcMsg *pReq) {
2,068✔
220
  SMnode    *pMnode = pReq->info.node;
2,068✔
221
  SConfigReq configReq = {0};
2,068✔
222
  int32_t    code = TSDB_CODE_SUCCESS;
2,068✔
223
  SArray    *array = NULL;
2,068✔
224

225
  code = tDeserializeSConfigReq(pReq->pCont, pReq->contLen, &configReq);
2,068✔
226
  if (code != 0) {
2,068!
227
    mError("failed to deserialize config req, since %s", terrstr());
×
228
    goto _OVER;
×
229
  }
230

231
  SConfigObj *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
2,068✔
232
  if (vObj == NULL) {
2,068!
233
    mInfo("failed to acquire mnd config version, since %s", terrstr());
×
234
    goto _OVER;
×
235
  }
236

237
  array = taosArrayInit(16, sizeof(SConfigItem));
2,068✔
238
  if (array == NULL) {
2,068!
239
    code = TSDB_CODE_OUT_OF_MEMORY;
×
240
    goto _OVER;
×
241
  }
242
  SConfigRsp configRsp = {0};
2,068✔
243
  configRsp.forceReadConfig = configReq.forceReadConfig;
2,068✔
244

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

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

285
_OVER:
2,068✔
286
  if (code != 0) {
2,068!
287
    mError("failed to process config req, since %s", tstrerror(code));
×
288
  }
289
  sdbRelease(pMnode->pSdb, vObj);
2,068✔
290
  cfgArrayCleanUp(array);
2,068✔
291
  return TSDB_CODE_SUCCESS;
2,068✔
292
}
293

294
int32_t mndInitWriteCfg(SMnode *pMnode) {
1,236✔
295
  int    code = 0;
1,236✔
296
  size_t sz = 0;
1,236✔
297

298
  mInfo("init write cfg to sdb");
1,236!
299
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "init-write-config");
1,236✔
300
  if (pTrans == NULL) {
1,236!
301
    mError("failed to init write cfg in create trans, since %s", terrstr());
×
302
    goto _OVER;
×
303
  }
304

305
  // encode mnd config version
306
  SConfigObj *versionObj = mndInitConfigVersion();
1,236✔
307
  if ((code = mndSetCreateConfigCommitLogs(pTrans, versionObj)) != 0) {
1,236!
308
    mError("failed to init mnd config version, since %s", tstrerror(code));
×
309
    tFreeSConfigObj(versionObj);
×
310
    taosMemoryFree(versionObj);
×
311
    goto _OVER;
×
312
  }
313
  tFreeSConfigObj(versionObj);
1,236✔
314
  taosMemoryFree(versionObj);
1,236!
315
  sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
1,236✔
316

317
  for (int i = 0; i < sz; ++i) {
116,668✔
318
    SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
115,432✔
319
    SConfigObj  *obj = mndInitConfigObj(item);
115,432✔
320
    if (obj == NULL) {
115,432!
321
      code = terrno;
×
322
      goto _OVER;
×
323
    }
324
    if ((code = mndSetCreateConfigCommitLogs(pTrans, obj)) != 0) {
115,432!
325
      mError("failed to init mnd config:%s, since %s", item->name, tstrerror(code));
×
326
      tFreeSConfigObj(obj);
×
327
      taosMemoryFree(obj);
×
328
      goto _OVER;
×
329
    }
330
    tFreeSConfigObj(obj);
115,432✔
331
    taosMemoryFree(obj);
115,432!
332
  }
333
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
1,236!
334

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

343
int32_t mndTryRebuildCfg(SMnode *pMnode) {
516✔
344
  if (!mndIsLeader(pMnode)) {
516!
345
    return TSDB_CODE_SUCCESS;
516✔
346
  }
347
  int32_t   code = 0;
×
348
  int32_t   sz = -1;
×
349
  STrans   *pTrans = NULL;
×
350
  SAcctObj *vObj = NULL, *obj = NULL;
×
351
  SArray   *addArray = NULL;
×
352

353
  vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
×
354
  if (vObj == NULL) {
×
355
    if ((code = mndInitWriteCfg(pMnode)) < 0) goto _exit;
×
356
    mInfo("failed to acquire mnd config version, try to rebuild config in sdb.");
×
357
  } else {
358
    sz = taosArrayGetSize(taosGetGlobalCfg(tsCfg));
×
359
    addArray = taosArrayInit(4, sizeof(SConfigObj));
×
360
    for (int i = 0; i < sz; ++i) {
×
361
      SConfigItem *item = taosArrayGet(taosGetGlobalCfg(tsCfg), i);
×
362
      obj = sdbAcquire(pMnode->pSdb, SDB_CFG, item->name);
×
363
      if (obj == NULL) {
×
364
        SConfigObj *newObj = mndInitConfigObj(item);
×
365
        if (newObj == NULL) {
×
366
          code = terrno;
×
367
          goto _exit;
×
368
        }
369
        if (NULL == taosArrayPush(addArray, newObj)) {
×
370
          code = terrno;
×
371
          goto _exit;
×
372
        }
373
      } else {
374
        sdbRelease(pMnode->pSdb, obj);
×
375
      }
376
    }
377
    int32_t addSize = taosArrayGetSize(addArray);
×
378
    if (addSize > 0) {
×
379
      pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL, "add-config");
×
380
      if (pTrans == NULL) {
×
381
        code = terrno;
×
382
        goto _exit;
×
383
      }
384
      for (int i = 0; i < addSize; ++i) {
×
385
        SConfigObj *AddObj = taosArrayGet(addArray, i);
×
386
        if ((code = mndSetCreateConfigCommitLogs(pTrans, AddObj)) != 0) goto _exit;
×
387
      }
388
      if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _exit;
×
389
      mInfo("add new config to sdb, nums:%d", addSize);
×
390
    }
391
  }
392
_exit:
×
393
  if (code != 0) {
×
394
    mError("failed to try rebuild config in sdb, since %s", tstrerror(code));
×
395
  }
396
  sdbRelease(pMnode->pSdb, vObj);
×
397
  sdbRelease(pMnode->pSdb, obj);
×
398
  cfgObjArrayCleanUp(addArray);
×
399
  mndTransDrop(pTrans);
×
400
  TAOS_RETURN(code);
×
401
}
402

403
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *item) {
118,728✔
404
  int32_t  code = 0;
118,728✔
405
  SSdbRaw *pCommitRaw = mnCfgActionEncode(item);
118,728✔
406
  if (pCommitRaw == NULL) {
118,728!
407
    code = terrno;
×
408
    TAOS_RETURN(code);
×
409
  }
410
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw) != 0)) TAOS_RETURN(code);
118,728!
411
  if ((code = sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY)) != 0) TAOS_RETURN(code);
118,728!
412
  return TSDB_CODE_SUCCESS;
118,728✔
413
}
414

415
static int32_t mndMCfg2DCfg(SMCfgDnodeReq *pMCfgReq, SDCfgDnodeReq *pDCfgReq) {
1,112✔
416
  int32_t code = 0;
1,112✔
417
  char   *p = pMCfgReq->config;
1,112✔
418
  while (*p) {
15,427✔
419
    if (*p == ' ') {
14,506✔
420
      break;
191✔
421
    }
422
    p++;
14,315✔
423
  }
424

425
  size_t optLen = p - pMCfgReq->config;
1,112✔
426
  tstrncpy(pDCfgReq->config, pMCfgReq->config, sizeof(pDCfgReq->config));
1,112✔
427
  pDCfgReq->config[optLen] = 0;
1,112✔
428

429
  if (' ' == pMCfgReq->config[optLen]) {
1,112✔
430
    // 'key value'
431
    if (strlen(pMCfgReq->value) != 0) goto _err;
191!
432
    tstrncpy(pDCfgReq->value, p + 1, sizeof(pDCfgReq->value));
191✔
433
  } else {
434
    // 'key' 'value'
435
    if (strlen(pMCfgReq->value) == 0) goto _err;
921✔
436
    tstrncpy(pDCfgReq->value, pMCfgReq->value, sizeof(pDCfgReq->value));
920✔
437
  }
438

439
  TAOS_RETURN(code);
1,111✔
440

441
_err:
1✔
442
  mError("dnode:%d, failed to config since invalid conf:%s", pMCfgReq->dnodeId, pMCfgReq->config);
1!
443
  code = TSDB_CODE_INVALID_CFG;
1✔
444
  TAOS_RETURN(code);
1✔
445
}
446

447
static int32_t mndSendCfgDnodeReq(SMnode *pMnode, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
1,100✔
448
  int32_t code = -1;
1,100✔
449
  SSdb   *pSdb = pMnode->pSdb;
1,100✔
450
  void   *pIter = NULL;
1,100✔
451

452
  int64_t curMs = taosGetTimestampMs();
1,100✔
453

454
  while (1) {
1,425✔
455
    SDnodeObj *pDnode = NULL;
2,525✔
456
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
2,525✔
457
    if (pIter == NULL) break;
2,525✔
458

459
    if (pDnode->id == dnodeId || dnodeId == -1 || dnodeId == 0) {
1,425!
460
      bool online = mndIsDnodeOnline(pDnode, curMs);
1,404✔
461
      if (!online) {
1,404✔
462
        mWarn("dnode:%d, is offline, skip to send config req", pDnode->id);
1!
463
        continue;
1✔
464
      }
465
      SEpSet  epSet = mndGetDnodeEpset(pDnode);
1,403✔
466
      int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, pDcfgReq);
1,403✔
467
      void   *pBuf = rpcMallocCont(bufLen);
1,403✔
468

469
      if (pBuf == NULL) {
1,403!
470
        sdbCancelFetch(pMnode->pSdb, pIter);
×
471
        sdbRelease(pMnode->pSdb, pDnode);
×
472
        code = TSDB_CODE_OUT_OF_MEMORY;
×
473
        return code;
×
474
      }
475

476
      if ((bufLen = tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq)) <= 0) {
1,403!
477
        sdbCancelFetch(pMnode->pSdb, pIter);
×
478
        sdbRelease(pMnode->pSdb, pDnode);
×
479
        code = bufLen;
×
480
        rpcFreeCont(pBuf);
×
481
        return code;
×
482
      }
483

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

488
      code = rpcSendRecvWithTimeout(pMnode->msgCb.statusRpc, &epSet, &rpcMsg, &rpcRsp, NULL, CFG_ALTER_TIMEOUT);
1,403✔
489
      if (code != 0) {
1,403!
490
        mError("failed to send config req to dnode:%d, since %s", pDnode->id, tstrerror(code));
×
491
        sdbCancelFetch(pMnode->pSdb, pIter);
×
492
        sdbRelease(pMnode->pSdb, pDnode);
×
493
        return code;
×
494
      }
495

496
      code = rpcRsp.code;
1,403✔
497
      if (code != 0) {
1,403!
498
        mError("failed to alter config %s,on dnode:%d, since %s", pDcfgReq->config, pDnode->id, tstrerror(code));
×
499
        sdbCancelFetch(pMnode->pSdb, pIter);
×
500
        sdbRelease(pMnode->pSdb, pDnode);
×
501
        return code;
×
502
      }
503
      rpcFreeCont(rpcRsp.pCont);
1,403✔
504
    }
505
    sdbRelease(pSdb, pDnode);
1,424✔
506
  }
507

508
  if (code == -1) {
1,100✔
509
    code = TSDB_CODE_MND_DNODE_NOT_EXIST;
5✔
510
  }
511
  TAOS_RETURN(code);
1,100✔
512
}
513

514
static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
1,121✔
515
  int32_t       code = 0;
1,121✔
516
  int32_t       lino = -1;
1,121✔
517
  SMnode       *pMnode = pReq->info.node;
1,121✔
518
  SMCfgDnodeReq cfgReq = {0};
1,121✔
519
  SConfigObj   *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
1,121✔
520
  if (vObj == NULL) {
1,121!
521
    goto _err_out;
×
522
  }
523

524
  TAOS_CHECK_RETURN(tDeserializeSMCfgDnodeReq(pReq->pCont, pReq->contLen, &cfgReq));
1,121!
525
  int8_t updateIpWhiteList = 0;
1,121✔
526
  mInfo("dnode:%d, start to config, option:%s, value:%s", cfgReq.dnodeId, cfgReq.config, cfgReq.value);
1,121!
527
  if ((code = mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONFIG_DNODE)) != 0) {
1,121✔
528
    goto _err_out;
7✔
529
  }
530

531
  SDCfgDnodeReq dcfgReq = {0};
1,114✔
532
  if (strcasecmp(cfgReq.config, "resetlog") == 0) {
1,114✔
533
    tstrncpy(dcfgReq.config, "resetlog", 9);
2✔
534
    goto _send_req;
2✔
535
#ifdef TD_ENTERPRISE
536
  } else if (strncasecmp(cfgReq.config, "s3blocksize", 12) == 0) {
1,112!
537
    int32_t optLen = strlen("s3blocksize");
×
538
    int32_t flag = -1;
×
539
    int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
×
540
    if (code < 0) {
×
541
      goto _err_out;
×
542
    }
543

544
    if (flag > 1024 * 1024 || (flag > -1 && flag < 1024) || flag < -1) {
×
545
      mError("dnode:%d, failed to config s3blocksize since value:%d. Valid range: -1 or [1024, 1024 * 1024]",
×
546
             cfgReq.dnodeId, flag);
547
      code = TSDB_CODE_INVALID_CFG;
×
548
      goto _err_out;
×
549
    }
550

551
    tstrncpy(dcfgReq.config, "s3blocksize", 12);
×
552
    snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
×
553
#endif
554
  } else {
555
    TAOS_CHECK_GOTO(mndMCfg2DCfg(&cfgReq, &dcfgReq), &lino, _err_out);
1,112✔
556
    if (strlen(dcfgReq.config) > TSDB_DNODE_CONFIG_LEN) {
1,111!
557
      mError("dnode:%d, failed to config since config is too long", cfgReq.dnodeId);
×
558
      code = TSDB_CODE_INVALID_CFG;
×
559
      goto _err_out;
×
560
    }
561
    if (strncasecmp(dcfgReq.config, "enableWhiteList", strlen("enableWhiteList")) == 0) {
1,111✔
562
      updateIpWhiteList = 1;
2✔
563
    }
564

565
    CfgAlterType alterType = (cfgReq.dnodeId == 0 || cfgReq.dnodeId == -1) ? CFG_ALTER_ALL_DNODES : CFG_ALTER_DNODE;
1,111!
566
    TAOS_CHECK_GOTO(cfgCheckRangeForDynUpdate(taosGetCfg(), dcfgReq.config, dcfgReq.value, true, alterType), &lino,
1,111✔
567
                    _err_out);
568
  }
569
  SConfigItem *pItem = cfgGetItem(taosGetCfg(), dcfgReq.config);
1,098✔
570
  // Update config in sdb.
571
  if (pItem == NULL) {
1,098!
572
    mError("failed to find config:%s while process config dnode req", cfgReq.config);
×
573
    code = TSDB_CODE_CFG_NOT_FOUND;
×
574
    goto _err_out;
×
575
  }
576
  if (pItem->category == CFG_CATEGORY_GLOBAL) {
1,098✔
577
    TAOS_CHECK_GOTO(mndConfigUpdateTrans(pMnode, dcfgReq.config, dcfgReq.value, pItem->dtype, ++vObj->i32), &lino,
1,030!
578
                    _err_out);
579
  }
580
_send_req :
1,098✔
581

582
{  // audit
583
  char obj[50] = {0};
1,100✔
584
  (void)tsnprintf(obj, sizeof(obj), "%d", cfgReq.dnodeId);
1,100✔
585

586
  auditRecord(pReq, pMnode->clusterId, "alterDnode", obj, "", cfgReq.sql, cfgReq.sqlLen);
1,100✔
587
}
588
  dcfgReq.version = vObj->i32;
1,100✔
589
  code = mndSendCfgDnodeReq(pMnode, cfgReq.dnodeId, &dcfgReq);
1,100✔
590
  if (code != 0) {
1,100✔
591
    mError("failed to send config req to dnode:%d, since %s", cfgReq.dnodeId, tstrerror(code));
5!
592
    goto _err_out;
5✔
593
  }
594
  // dont care suss or succ;
595
  if (updateIpWhiteList) mndRefreshUserIpWhiteList(pMnode);
1,095✔
596
  tFreeSMCfgDnodeReq(&cfgReq);
1,095✔
597
  sdbRelease(pMnode->pSdb, vObj);
1,095✔
598
  TAOS_RETURN(code);
1,095✔
599

600
_err_out:
26✔
601
  mError("failed to process config dnode req, since %s", tstrerror(code));
26!
602
  tFreeSMCfgDnodeReq(&cfgReq);
26✔
603
  sdbRelease(pMnode->pSdb, vObj);
26✔
604
  TAOS_RETURN(code);
26✔
605
}
606

607
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) {
×
608
  mInfo("config rsp from dnode");
×
609
  return 0;
×
610
}
611

612
// get int32_t value from 'SMCfgDnodeReq'
613
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pMCfgReq, int32_t optLen, int32_t *pOutValue) {
×
614
  int32_t code = 0;
×
615
  if (' ' != pMCfgReq->config[optLen] && 0 != pMCfgReq->config[optLen]) {
×
616
    goto _err;
×
617
  }
618

619
  if (' ' == pMCfgReq->config[optLen]) {
×
620
    // 'key value'
621
    if (strlen(pMCfgReq->value) != 0) goto _err;
×
622
    *pOutValue = taosStr2Int32(pMCfgReq->config + optLen + 1, NULL, 10);
×
623
  } else {
624
    // 'key' 'value'
625
    if (strlen(pMCfgReq->value) == 0) goto _err;
×
626
    *pOutValue = taosStr2Int32(pMCfgReq->value, NULL, 10);
×
627
  }
628

629
  TAOS_RETURN(code);
×
630

631
_err:
×
632
  mError(" failed to set config since:%s", tstrerror(code));
×
633
  TAOS_RETURN(code);
×
634
}
635

636
static int32_t mndConfigUpdateTrans(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
1,030✔
637
                                    int32_t tsmmConfigVersion) {
638
  int32_t     code = -1;
1,030✔
639
  int32_t     lino = -1;
1,030✔
640
  SConfigObj *pVersion = taosMemoryMalloc(sizeof(SConfigObj)), *pObj = taosMemoryMalloc(sizeof(SConfigObj));
1,030!
641
  if (pVersion == NULL || pObj == NULL) {
1,030!
642
    code = terrno;
×
643
    goto _OVER;
×
644
  }
645
  tstrncpy(pVersion->name, "tsmmConfigVersion", CFG_NAME_MAX_LEN);
1,030✔
646
  pVersion->dtype = CFG_DTYPE_INT32;
1,030✔
647
  pVersion->i32 = tsmmConfigVersion;
1,030✔
648

649
  pObj->dtype = dtype;
1,030✔
650
  tstrncpy(pObj->name, name, CFG_NAME_MAX_LEN);
1,030✔
651

652
  TAOS_CHECK_GOTO(mndUpdateObj(pObj, name, pValue), &lino, _OVER);
1,030!
653
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, NULL, "update-config");
1,030✔
654
  if (pTrans == NULL) {
1,030!
655
    code = terrno;
×
656
    goto _OVER;
×
657
  }
658
  mInfo("trans:%d, used to update config:%s to value:%s", pTrans->id, name, pValue);
1,030!
659
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pVersion), &lino, _OVER);
1,030!
660
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pObj), &lino, _OVER);
1,030!
661
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
1,030!
662
  code = 0;
1,030✔
663
_OVER:
1,030✔
664
  if (code != 0) {
1,030!
UNCOV
665
    mError("failed to update config:%s to value:%s, since %s", name, pValue, tstrerror(code));
×
666
  }
667
  mndTransDrop(pTrans);
1,030✔
668
  tFreeSConfigObj(pVersion);
1,030✔
669
  taosMemoryFree(pVersion);
1,030!
670
  tFreeSConfigObj(pObj);
1,030✔
671
  taosMemoryFree(pObj);
1,030!
672
  return code;
1,030✔
673
}
674

675
static int32_t initConfigArrayFromSdb(SMnode *pMnode, SArray *array) {
1,696✔
676
  int32_t     code = 0;
1,696✔
677
  SSdb       *pSdb = pMnode->pSdb;
1,696✔
678
  void       *pIter = NULL;
1,696✔
679
  SConfigObj *obj = NULL;
1,696✔
680

681
  while (1) {
159,616✔
682
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
161,312✔
683
    if (pIter == NULL) break;
161,312✔
684
    if (obj == NULL) {
159,616!
685
      code = TSDB_CODE_OUT_OF_MEMORY;
×
686
      goto _exit;
×
687
    }
688
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
159,616✔
689
      sdbRelease(pSdb, obj);
1,696✔
690
      continue;
1,696✔
691
    }
692
    SConfigItem item = {0};
157,920✔
693
    item.dtype = obj->dtype;
157,920✔
694
    item.name = taosStrdup(obj->name);
157,920!
695
    if (item.name == NULL) {
157,920!
696
      code = terrno;
×
697
      sdbCancelFetch(pSdb, pIter);
×
698
      sdbRelease(pSdb, obj);
×
699
      goto _exit;
×
700
    }
701
    switch (obj->dtype) {
157,920!
702
      case CFG_DTYPE_NONE:
×
703
        break;
×
704
      case CFG_DTYPE_BOOL:
30,240✔
705
        item.bval = obj->bval;
30,240✔
706
        break;
30,240✔
707
      case CFG_DTYPE_INT32:
84,000✔
708
        item.i32 = obj->i32;
84,000✔
709
        break;
84,000✔
710
      case CFG_DTYPE_INT64:
15,120✔
711
        item.i64 = obj->i64;
15,120✔
712
        break;
15,120✔
713
      case CFG_DTYPE_FLOAT:
5,040✔
714
      case CFG_DTYPE_DOUBLE:
715
        item.fval = obj->fval;
5,040✔
716
        break;
5,040✔
717
      case CFG_DTYPE_STRING:
23,520✔
718
      case CFG_DTYPE_DIR:
719
      case CFG_DTYPE_LOCALE:
720
      case CFG_DTYPE_CHARSET:
721
      case CFG_DTYPE_TIMEZONE:
722
        item.str = taosStrdup(obj->str);
23,520!
723
        if (item.str == NULL) {
23,520!
724
          sdbCancelFetch(pSdb, pIter);
×
725
          sdbRelease(pSdb, obj);
×
726
          code = terrno;
×
727
          goto _exit;
×
728
        }
729
        break;
23,520✔
730
    }
731
    if (taosArrayPush(array, &item) == NULL) {
157,920!
732
      sdbCancelFetch(pSdb, pIter);
×
733
      sdbRelease(pSdb, obj);
×
734
      code = TSDB_CODE_OUT_OF_MEMORY;
×
735
      goto _exit;
×
736
      break;
737
    }
738
    sdbRelease(pSdb, obj);
157,920✔
739
  }
740
_exit:
1,696✔
741
  if (code != 0) {
1,696!
742
    mError("failed to init config array from sdb, since %s", tstrerror(code));
×
743
  }
744
  return code;
1,696✔
745
}
746

747
static void cfgArrayCleanUp(SArray *array) {
2,068✔
748
  if (array == NULL) {
2,068!
749
    return;
×
750
  }
751

752
  int32_t sz = taosArrayGetSize(array);
2,068✔
753
  for (int32_t i = 0; i < sz; ++i) {
159,988✔
754
    SConfigItem *item = taosArrayGet(array, i);
157,920✔
755
    if (item->dtype == CFG_DTYPE_STRING || item->dtype == CFG_DTYPE_DIR || item->dtype == CFG_DTYPE_LOCALE ||
157,920!
756
        item->dtype == CFG_DTYPE_CHARSET || item->dtype == CFG_DTYPE_TIMEZONE) {
137,760✔
757
      taosMemoryFreeClear(item->str);
23,520!
758
    }
759
    taosMemoryFreeClear(item->name);
157,920!
760
  }
761

762
  taosArrayDestroy(array);
2,068✔
763
}
764

765
static void cfgObjArrayCleanUp(SArray *array) {
×
766
  if (array == NULL) {
×
767
    return;
×
768
  }
769
  int32_t sz = taosArrayGetSize(array);
×
770
  for (int32_t i = 0; i < sz; ++i) {
×
771
    SConfigObj *obj = taosArrayGet(array, i);
×
772
    tFreeSConfigObj(obj);
×
773
    taosMemoryFree(obj);
×
774
  }
775
  taosArrayDestroy(array);
×
776
}
777

778
SArray *initVariablesFromItems(SArray *pItems) {
10✔
779
  if (pItems == NULL) {
10!
780
    return NULL;
×
781
  }
782

783
  int32_t sz = taosArrayGetSize(pItems);
10✔
784

785
  SArray *pInfos = taosArrayInit(sz, sizeof(SVariablesInfo));
10✔
786
  if (pInfos == NULL) {
10!
787
    mError("failed to init array while init variables from items, since %s", tstrerror(terrno));
×
788
    return NULL;
×
789
  }
790
  for (int32_t i = 0; i < sz; ++i) {
950✔
791
    SConfigItem   *pItem = taosArrayGet(pItems, i);
940✔
792
    SVariablesInfo info = {0};
940✔
793
    tstrncpy(info.name, pItem->name, sizeof(info.name));
940✔
794

795
    // init info value
796
    switch (pItem->dtype) {
940!
797
      case CFG_DTYPE_NONE:
×
798
        break;
×
799
      case CFG_DTYPE_BOOL:
180✔
800
        tsnprintf(info.value, sizeof(info.value), "%d", pItem->bval);
180✔
801
        break;
180✔
802
      case CFG_DTYPE_INT32:
500✔
803
        tsnprintf(info.value, sizeof(info.value), "%d", pItem->i32);
500✔
804
        break;
500✔
805
      case CFG_DTYPE_INT64:
90✔
806
        tsnprintf(info.value, sizeof(info.value), "%" PRId64, pItem->i64);
90✔
807
        break;
90✔
808
      case CFG_DTYPE_FLOAT:
30✔
809
      case CFG_DTYPE_DOUBLE:
810
        tsnprintf(info.value, sizeof(info.value), "%f", pItem->fval);
30✔
811
        break;
30✔
812
      case CFG_DTYPE_STRING:
140✔
813
      case CFG_DTYPE_DIR:
814
      case CFG_DTYPE_LOCALE:
815
      case CFG_DTYPE_CHARSET:
816
      case CFG_DTYPE_TIMEZONE:
817
        tsnprintf(info.value, sizeof(info.value), "%s", pItem->str);
140✔
818
        break;
140✔
819
    }
820

821
    // init info scope
822
    switch (pItem->scope) {
940!
823
      case CFG_SCOPE_SERVER:
760✔
824
        tstrncpy(info.scope, "server", sizeof(info.scope));
760✔
825
        break;
760✔
826
      case CFG_SCOPE_CLIENT:
10✔
827
        tstrncpy(info.scope, "client", sizeof(info.scope));
10✔
828
        break;
10✔
829
      case CFG_SCOPE_BOTH:
170✔
830
        tstrncpy(info.scope, "both", sizeof(info.scope));
170✔
831
        break;
170✔
832
      default:
×
833
        tstrncpy(info.scope, "unknown", sizeof(info.scope));
×
834
        break;
×
835
    }
836
    // init info category
837
    switch (pItem->category) {
940!
838
      case CFG_CATEGORY_GLOBAL:
940✔
839
        tstrncpy(info.category, "global", sizeof(info.category));
940✔
840
        break;
940✔
841
      case CFG_CATEGORY_LOCAL:
×
842
        tstrncpy(info.category, "local", sizeof(info.category));
×
843
        break;
×
844
      default:
×
845
        tstrncpy(info.category, "unknown", sizeof(info.category));
×
846
        break;
×
847
    }
848
    if (NULL == taosArrayPush(pInfos, &info)) {
940!
849
      mError("failed to push info to array while init variables from items,since %s", tstrerror(terrno));
×
850
      taosArrayDestroy(pInfos);
×
851
      return NULL;
×
852
    }
853
  }
854

855
  return pInfos;
10✔
856
}
857

858
static int32_t mndProcessShowVariablesReq(SRpcMsg *pReq) {
10✔
859
  SShowVariablesRsp rsp = {0};
10✔
860
  int32_t           code = -1;
10✔
861

862
  if ((code = mndCheckOperPrivilege(pReq->info.node, pReq->info.conn.user, MND_OPER_SHOW_VARIABLES)) != 0) {
10!
863
    goto _OVER;
×
864
  }
865

866
  SVariablesInfo info = {0};
10✔
867

868
  rsp.variables = initVariablesFromItems(taosGetGlobalCfg(tsCfg));
10✔
869
  if (rsp.variables == NULL) {
10!
870
    code = terrno;
×
871
    goto _OVER;
×
872
  }
873
  int32_t rspLen = tSerializeSShowVariablesRsp(NULL, 0, &rsp);
10✔
874
  void   *pRsp = rpcMallocCont(rspLen);
10✔
875
  if (pRsp == NULL) {
10!
876
    code = terrno;
×
877
    goto _OVER;
×
878
  }
879

880
  if ((rspLen = tSerializeSShowVariablesRsp(pRsp, rspLen, &rsp)) <= 0) {
10!
881
    rpcFreeCont(pRsp);
×
882
    code = rspLen;
×
883
    goto _OVER;
×
884
  }
885

886
  pReq->info.rspLen = rspLen;
10✔
887
  pReq->info.rsp = pRsp;
10✔
888
  code = 0;
10✔
889

890
_OVER:
10✔
891

892
  if (code != 0) {
10!
893
    mError("failed to get show variables info since %s", tstrerror(code));
×
894
  }
895

896
  tFreeSShowVariablesRsp(&rsp);
10✔
897
  TAOS_RETURN(code);
10✔
898
}
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