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

taosdata / TDengine / #3844

10 Apr 2025 08:48AM UTC coverage: 43.852% (-19.2%) from 63.077%
#3844

push

travis-ci

web-flow
fix: the REPLICA parameter supports plural forms when used to create and alter a database (#30732)

104394 of 310659 branches covered (33.6%)

Branch coverage included in aggregate %.

167442 of 309240 relevant lines covered (54.15%)

3866624.94 hits per line

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

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

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

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

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

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

49
int32_t mndSetCreateConfigCommitLogs(STrans *pTrans, SConfigObj *obj);
50

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

63
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG, mndProcessConfigReq);
20✔
64
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeReq);
20✔
65
  mndSetMsgHandle(pMnode, TDMT_DND_CONFIG_DNODE_RSP, mndProcessConfigDnodeRsp);
20✔
66
  mndSetMsgHandle(pMnode, TDMT_MND_SHOW_VARIABLES, mndProcessShowVariablesReq);
20✔
67
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB, mndTryRebuildConfigSdb);
20✔
68
  mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB_RSP, mndTryRebuildConfigSdbRsp);
20✔
69

70
  return sdbSetTable(pMnode->pSdb, table);
20✔
71
}
72

73
SSdbRaw *mnCfgActionEncode(SConfigObj *obj) {
768✔
74
  int32_t  code = 0;
768✔
75
  int32_t  lino = 0;
768✔
76
  void    *buf = NULL;
768✔
77
  SSdbRaw *pRaw = NULL;
768✔
78

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

86
  int32_t tlen = encoder.pos;
768✔
87
  tEncoderClear(&encoder);
768✔
88

89
  int32_t size = sizeof(int32_t) + tlen;
768✔
90
  pRaw = sdbAllocRaw(SDB_CFG, CFG_VER_NUMBER, size);
768✔
91
  TSDB_CHECK_NULL(pRaw, code, lino, _over, terrno);
768!
92

93
  buf = taosMemoryMalloc(tlen);
768!
94
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
768!
95

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

102
  tEncoderClear(&encoder);
768✔
103

104
  int32_t dataPos = 0;
768✔
105
  SDB_SET_INT32(pRaw, dataPos, tlen, _over);
768!
106
  SDB_SET_BINARY(pRaw, dataPos, buf, tlen, _over);
768!
107
  SDB_SET_DATALEN(pRaw, dataPos, _over);
768!
108

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

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

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

133
  code = sdbGetRawSoftVer(pRaw, &sver);
376✔
134
  TSDB_CHECK_CODE(code, lino, _over);
376!
135

136
  if (sver != CFG_VER_NUMBER) {
376!
137
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
138
    goto _over;
×
139
  }
140

141
  pRow = sdbAllocRow(sizeof(SConfigObj));
376✔
142
  TSDB_CHECK_NULL(pRow, code, lino, _over, terrno);
376!
143

144
  pObj = sdbGetRowObj(pRow);
376✔
145
  TSDB_CHECK_NULL(pObj, code, lino, _over, terrno);
376!
146

147
  SDB_GET_INT32(pRaw, dataPos, &tlen, _over);
376!
148

149
  buf = taosMemoryMalloc(tlen + 1);
376!
150
  TSDB_CHECK_NULL(buf, code, lino, _over, terrno);
376!
151

152
  SDB_GET_BINARY(pRaw, dataPos, buf, tlen, _over);
376!
153

154
  SDecoder decoder;
155
  tDecoderInit(&decoder, buf, tlen + 1);
376✔
156
  code = tDecodeSConfigObj(&decoder, pObj);
376✔
157
  tDecoderClear(&decoder);
376✔
158

159
  if (code < 0) {
376!
160
    tFreeSConfigObj(pObj);
×
161
  }
162

163
_over:
376✔
164
  taosMemoryFreeClear(buf);
376!
165

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

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

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

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

222
static int32_t mndCfgActionDeploy(SMnode *pMnode) { return mndInitWriteCfg(pMnode); }
18✔
223

224
static int32_t mndCfgActionAfterRestored(SMnode *pMnode) { return mndSendRebuildReq(pMnode); }
4✔
225

226
static int32_t mndProcessConfigReq(SRpcMsg *pReq) {
44✔
227
  SMnode    *pMnode = pReq->info.node;
44✔
228
  SConfigReq configReq = {0};
44✔
229
  int32_t    code = TSDB_CODE_SUCCESS;
44✔
230
  SArray    *array = NULL;
44✔
231
  bool       needFree = false;
44✔
232
  code = tDeserializeSConfigReq(pReq->pCont, pReq->contLen, &configReq);
44✔
233
  if (code != 0) {
44!
234
    mError("failed to deserialize config req, since %s", terrstr());
×
235
    goto _OVER;
×
236
  }
237

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

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

252
  configRsp.cver = vObj->i32;
44✔
253
  if (configRsp.forceReadConfig) {
44!
254
    // compare config array from configReq with current config array
255
    code = compareSConfigItemArrays(pMnode, configReq.array, array);
×
256
    if (code != TSDB_CODE_SUCCESS) {
×
257
      mError("failed to compare config array, since %s", tstrerror(code));
×
258
      goto _OVER;
×
259
    }
260
    if (taosArrayGetSize(array) > 0) {
×
261
      configRsp.array = array;
×
262
    } else {
263
      configRsp.isConifgVerified = 1;
×
264
    }
265
  } else {
266
    if (configReq.cver == vObj->i32) {
44✔
267
      configRsp.isVersionVerified = 1;
2✔
268
    } else {
269
      needFree = true;
42✔
270
      code = initConfigArrayFromSdb(pMnode, array);
42✔
271
      if (code != 0) {
42!
272
        mError("failed to init config array from sdb, since %s", terrstr());
×
273
        goto _OVER;
×
274
      }
275
      configRsp.array = array;
42✔
276
    }
277
  }
278

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

298
_OVER:
44✔
299
  if (code != 0) {
44!
300
    mError("failed to process config req, since %s", tstrerror(code));
×
301
  }
302
  sdbRelease(pMnode->pSdb, vObj);
44✔
303
  cfgArrayCleanUp(array, needFree);
44✔
304

305
  tFreeSConfigReq(&configReq);
44✔
306
  return code;
44✔
307
}
308

309
int32_t mndInitWriteCfg(SMnode *pMnode) {
18✔
310
  int    code = 0;
18✔
311
  size_t sz = 0;
18✔
312

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

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

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

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

353
int32_t mndSendRebuildReq(SMnode *pMnode) {
4✔
354
  int32_t code = 0;
4✔
355

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

366
  mndGetMnodeEpSet(pMnode, &epSet);
4✔
367

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

375
static int32_t mndTryRebuildConfigSdb(SRpcMsg *pReq) {
4✔
376
  SMnode *pMnode = pReq->info.node;
4✔
377
  if (!mndIsLeader(pMnode)) {
4!
378
    return TSDB_CODE_SUCCESS;
×
379
  }
380
  int32_t     code = 0;
4✔
381
  int32_t     sz = -1;
4✔
382
  STrans     *pTrans = NULL;
4✔
383
  SConfigObj *vObj = NULL;
4✔
384
  SArray     *addArray = NULL;
4✔
385

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

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

445
static int32_t mndMCfg2DCfg(SMCfgDnodeReq *pMCfgReq, SDCfgDnodeReq *pDCfgReq) {
×
446
  int32_t code = 0;
×
447
  char   *p = pMCfgReq->config;
×
448
  while (*p) {
×
449
    if (*p == ' ') {
×
450
      break;
×
451
    }
452
    p++;
×
453
  }
454

455
  size_t optLen = p - pMCfgReq->config;
×
456
  tstrncpy(pDCfgReq->config, pMCfgReq->config, sizeof(pDCfgReq->config));
×
457
  pDCfgReq->config[optLen] = 0;
×
458

459
  if (' ' == pMCfgReq->config[optLen]) {
×
460
    // 'key value'
461
    if (strlen(pMCfgReq->value) != 0) goto _err;
×
462
    tstrncpy(pDCfgReq->value, p + 1, sizeof(pDCfgReq->value));
×
463
  } else {
464
    // 'key' 'value'
465
    if (strlen(pMCfgReq->value) == 0) goto _err;
×
466
    tstrncpy(pDCfgReq->value, pMCfgReq->value, sizeof(pDCfgReq->value));
×
467
  }
468

469
  TAOS_RETURN(code);
×
470

471
_err:
×
472
  mError("dnode:%d, failed to config since invalid conf:%s", pMCfgReq->dnodeId, pMCfgReq->config);
×
473
  code = TSDB_CODE_INVALID_CFG;
×
474
  TAOS_RETURN(code);
×
475
}
476

477
static int32_t mndSendCfgDnodeReq(SMnode *pMnode, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
×
478
  int32_t code = -1;
×
479
  SSdb   *pSdb = pMnode->pSdb;
×
480
  void   *pIter = NULL;
×
481

482
  int64_t curMs = taosGetTimestampMs();
×
483

484
  while (1) {
×
485
    SDnodeObj *pDnode = NULL;
×
486
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
×
487
    if (pIter == NULL) break;
×
488

489
    if (pDnode->id == dnodeId || dnodeId == -1 || dnodeId == 0) {
×
490
      bool online = mndIsDnodeOnline(pDnode, curMs);
×
491
      if (!online) {
×
492
        mWarn("dnode:%d, is offline, skip to send config req", pDnode->id);
×
493
        continue;
×
494
      }
495
      SEpSet  epSet = mndGetDnodeEpset(pDnode);
×
496
      int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, pDcfgReq);
×
497
      void   *pBuf = rpcMallocCont(bufLen);
×
498

499
      if (pBuf == NULL) {
×
500
        sdbCancelFetch(pMnode->pSdb, pIter);
×
501
        sdbRelease(pMnode->pSdb, pDnode);
×
502
        code = TSDB_CODE_OUT_OF_MEMORY;
×
503
        return code;
×
504
      }
505

506
      if ((bufLen = tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq)) <= 0) {
×
507
        sdbCancelFetch(pMnode->pSdb, pIter);
×
508
        sdbRelease(pMnode->pSdb, pDnode);
×
509
        code = bufLen;
×
510
        rpcFreeCont(pBuf);
×
511
        return code;
×
512
      }
513

514
      mInfo("dnode:%d, send config req to dnode, config:%s value:%s", pDnode->id, pDcfgReq->config, pDcfgReq->value);
×
515
      SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pBuf, .contLen = bufLen};
×
516
      SRpcMsg rpcRsp = {0};
×
517

518
      code = rpcSendRecvWithTimeout(pMnode->msgCb.statusRpc, &epSet, &rpcMsg, &rpcRsp, NULL, CFG_ALTER_TIMEOUT);
×
519
      if (code != 0) {
×
520
        mError("failed to send config req to dnode:%d, since %s", pDnode->id, tstrerror(code));
×
521
        sdbCancelFetch(pMnode->pSdb, pIter);
×
522
        sdbRelease(pMnode->pSdb, pDnode);
×
523
        return code;
×
524
      }
525

526
      code = rpcRsp.code;
×
527
      if (code != 0) {
×
528
        mError("failed to alter config %s,on dnode:%d, since %s", pDcfgReq->config, pDnode->id, tstrerror(code));
×
529
        sdbCancelFetch(pMnode->pSdb, pIter);
×
530
        sdbRelease(pMnode->pSdb, pDnode);
×
531
        return code;
×
532
      }
533
      rpcFreeCont(rpcRsp.pCont);
×
534
    }
535
    sdbRelease(pSdb, pDnode);
×
536
  }
537

538
  if (code == -1) {
×
539
    code = TSDB_CODE_MND_DNODE_NOT_EXIST;
×
540
  }
541
  TAOS_RETURN(code);
×
542
}
543

544
static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
×
545
  int32_t       code = 0;
×
546
  int32_t       lino = -1;
×
547
  SMnode       *pMnode = pReq->info.node;
×
548
  SMCfgDnodeReq cfgReq = {0};
×
549
  SConfigObj   *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
×
550
  if (vObj == NULL) {
×
551
    code = TSDB_CODE_SDB_OBJ_NOT_THERE;
×
552
    mInfo("failed to acquire mnd config version, since %s", tstrerror(code));
×
553
    goto _err_out;
×
554
  }
555

556
  TAOS_CHECK_RETURN(tDeserializeSMCfgDnodeReq(pReq->pCont, pReq->contLen, &cfgReq));
×
557
  int8_t updateIpWhiteList = 0;
×
558
  mInfo("dnode:%d, start to config, option:%s, value:%s", cfgReq.dnodeId, cfgReq.config, cfgReq.value);
×
559
  if ((code = mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONFIG_DNODE)) != 0) {
×
560
    goto _err_out;
×
561
  }
562

563
  SDCfgDnodeReq dcfgReq = {0};
×
564
  if (strcasecmp(cfgReq.config, "resetlog") == 0) {
×
565
    tstrncpy(dcfgReq.config, "resetlog", 9);
×
566
    goto _send_req;
×
567
#ifdef TD_ENTERPRISE
568
  } else if (strncasecmp(cfgReq.config, "s3blocksize", 12) == 0) {
×
569
    int32_t optLen = strlen("s3blocksize");
×
570
    int32_t flag = -1;
×
571
    int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag);
×
572
    if (code < 0) {
×
573
      goto _err_out;
×
574
    }
575

576
    if (flag > 1024 * 1024 || (flag > -1 && flag < 1024) || flag < -1) {
×
577
      mError("dnode:%d, failed to config s3blocksize since value:%d. Valid range: -1 or [1024, 1024 * 1024]",
×
578
             cfgReq.dnodeId, flag);
579
      code = TSDB_CODE_INVALID_CFG;
×
580
      goto _err_out;
×
581
    }
582

583
    tstrncpy(dcfgReq.config, "s3blocksize", 12);
×
584
    snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
×
585
#endif
586
  } else {
587
    TAOS_CHECK_GOTO(mndMCfg2DCfg(&cfgReq, &dcfgReq), &lino, _err_out);
×
588
    if (strlen(dcfgReq.config) > TSDB_DNODE_CONFIG_LEN) {
×
589
      mError("dnode:%d, failed to config since config is too long", cfgReq.dnodeId);
×
590
      code = TSDB_CODE_INVALID_CFG;
×
591
      goto _err_out;
×
592
    }
593
    if (strncasecmp(dcfgReq.config, "enableWhiteList", strlen("enableWhiteList")) == 0) {
×
594
      updateIpWhiteList = 1;
×
595
    }
596

597
    CfgAlterType alterType = (cfgReq.dnodeId == 0 || cfgReq.dnodeId == -1) ? CFG_ALTER_ALL_DNODES : CFG_ALTER_DNODE;
×
598
    TAOS_CHECK_GOTO(cfgCheckRangeForDynUpdate(taosGetCfg(), dcfgReq.config, dcfgReq.value, true, alterType), &lino,
×
599
                    _err_out);
600
  }
601
  SConfigItem *pItem = cfgGetItem(taosGetCfg(), dcfgReq.config);
×
602
  // Update config in sdb.
603
  if (pItem == NULL) {
×
604
    mError("failed to find config:%s while process config dnode req", cfgReq.config);
×
605
    code = TSDB_CODE_CFG_NOT_FOUND;
×
606
    goto _err_out;
×
607
  }
608
  if (pItem->category == CFG_CATEGORY_GLOBAL) {
×
609
    TAOS_CHECK_GOTO(mndConfigUpdateTrans(pMnode, dcfgReq.config, dcfgReq.value, pItem->dtype, ++vObj->i32), &lino,
×
610
                    _err_out);
611
  }
612
_send_req :
×
613

614
{  // audit
615
  char obj[50] = {0};
×
616
  (void)tsnprintf(obj, sizeof(obj), "%d", cfgReq.dnodeId);
×
617

618
  auditRecord(pReq, pMnode->clusterId, "alterDnode", obj, "", cfgReq.sql, cfgReq.sqlLen);
×
619
}
620
  dcfgReq.version = vObj->i32;
×
621
  code = mndSendCfgDnodeReq(pMnode, cfgReq.dnodeId, &dcfgReq);
×
622
  if (code != 0) {
×
623
    mError("failed to send config req to dnode:%d, since %s", cfgReq.dnodeId, tstrerror(code));
×
624
    goto _err_out;
×
625
  }
626
  // dont care suss or succ;
627
  if (updateIpWhiteList) mndRefreshUserIpWhiteList(pMnode);
×
628
  tFreeSMCfgDnodeReq(&cfgReq);
×
629
  sdbRelease(pMnode->pSdb, vObj);
×
630
  TAOS_RETURN(code);
×
631

632
_err_out:
×
633
  mError("failed to process config dnode req, since %s", tstrerror(code));
×
634
  tFreeSMCfgDnodeReq(&cfgReq);
×
635
  sdbRelease(pMnode->pSdb, vObj);
×
636
  TAOS_RETURN(code);
×
637
}
638

639
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) {
×
640
  mInfo("config rsp from dnode");
×
641
  return 0;
×
642
}
643

644
static int32_t mndTryRebuildConfigSdbRsp(SRpcMsg *pRsp) {
4✔
645
  mInfo("rebuild config sdb rsp");
4!
646
  return 0;
4✔
647
}
648

649
// get int32_t value from 'SMCfgDnodeReq'
650
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pMCfgReq, int32_t optLen, int32_t *pOutValue) {
×
651
  int32_t code = 0;
×
652
  if (' ' != pMCfgReq->config[optLen] && 0 != pMCfgReq->config[optLen]) {
×
653
    goto _err;
×
654
  }
655

656
  if (' ' == pMCfgReq->config[optLen]) {
×
657
    // 'key value'
658
    if (strlen(pMCfgReq->value) != 0) goto _err;
×
659
    *pOutValue = taosStr2Int32(pMCfgReq->config + optLen + 1, NULL, 10);
×
660
  } else {
661
    // 'key' 'value'
662
    if (strlen(pMCfgReq->value) == 0) goto _err;
×
663
    *pOutValue = taosStr2Int32(pMCfgReq->value, NULL, 10);
×
664
  }
665

666
  TAOS_RETURN(code);
×
667

668
_err:
×
669
  mError(" failed to set config since:%s", tstrerror(code));
×
670
  TAOS_RETURN(code);
×
671
}
672

673
static int32_t mndConfigUpdateTrans(SMnode *pMnode, const char *name, char *pValue, ECfgDataType dtype,
×
674
                                    int32_t tsmmConfigVersion) {
675
  int32_t     code = -1;
×
676
  int32_t     lino = -1;
×
677
  SConfigObj *pVersion = taosMemoryMalloc(sizeof(SConfigObj)), *pObj = taosMemoryMalloc(sizeof(SConfigObj));
×
678
  if (pVersion == NULL || pObj == NULL) {
×
679
    code = terrno;
×
680
    goto _OVER;
×
681
  }
682
  tstrncpy(pVersion->name, "tsmmConfigVersion", CFG_NAME_MAX_LEN);
×
683
  pVersion->dtype = CFG_DTYPE_INT32;
×
684
  pVersion->i32 = tsmmConfigVersion;
×
685

686
  pObj->dtype = dtype;
×
687
  tstrncpy(pObj->name, name, CFG_NAME_MAX_LEN);
×
688

689
  TAOS_CHECK_GOTO(mndUpdateObj(pObj, name, pValue), &lino, _OVER);
×
690
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, NULL, "update-config");
×
691
  if (pTrans == NULL) {
×
692
    code = terrno;
×
693
    goto _OVER;
×
694
  }
695
  mInfo("trans:%d, used to update config:%s to value:%s", pTrans->id, name, pValue);
×
696
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pVersion), &lino, _OVER);
×
697
  TAOS_CHECK_GOTO(mndSetCreateConfigCommitLogs(pTrans, pObj), &lino, _OVER);
×
698
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) goto _OVER;
×
699
  code = 0;
×
700
_OVER:
×
701
  if (code != 0) {
×
702
    mError("failed to update config:%s to value:%s, since %s", name, pValue, tstrerror(code));
×
703
  }
704
  mndTransDrop(pTrans);
×
705
  tFreeSConfigObj(pVersion);
×
706
  taosMemoryFree(pVersion);
×
707
  tFreeSConfigObj(pObj);
×
708
  taosMemoryFree(pObj);
×
709
  return code;
×
710
}
711

712
static int32_t initConfigArrayFromSdb(SMnode *pMnode, SArray *array) {
42✔
713
  int32_t     code = 0;
42✔
714
  SSdb       *pSdb = pMnode->pSdb;
42✔
715
  void       *pIter = NULL;
42✔
716
  SConfigObj *obj = NULL;
42✔
717

718
  while (1) {
398✔
719
    pIter = sdbFetch(pSdb, SDB_CFG, pIter, (void **)&obj);
440✔
720
    if (pIter == NULL) break;
440✔
721
    if (obj == NULL) {
398!
722
      code = TSDB_CODE_OUT_OF_MEMORY;
×
723
      goto _exit;
×
724
    }
725
    if (strcasecmp(obj->name, "tsmmConfigVersion") == 0) {
398✔
726
      sdbRelease(pSdb, obj);
42✔
727
      continue;
42✔
728
    }
729
    SConfigItem item = {0};
356✔
730
    item.dtype = obj->dtype;
356✔
731
    item.name = taosStrdup(obj->name);
356!
732
    if (item.name == NULL) {
356!
733
      code = terrno;
×
734
      sdbCancelFetch(pSdb, pIter);
×
735
      sdbRelease(pSdb, obj);
×
736
      goto _exit;
×
737
    }
738
    switch (obj->dtype) {
356!
739
      case CFG_DTYPE_NONE:
×
740
        break;
×
741
      case CFG_DTYPE_BOOL:
76✔
742
        item.bval = obj->bval;
76✔
743
        break;
76✔
744
      case CFG_DTYPE_INT32:
184✔
745
        item.i32 = obj->i32;
184✔
746
        break;
184✔
747
      case CFG_DTYPE_INT64:
32✔
748
        item.i64 = obj->i64;
32✔
749
        break;
32✔
750
      case CFG_DTYPE_FLOAT:
12✔
751
      case CFG_DTYPE_DOUBLE:
752
        item.fval = obj->fval;
12✔
753
        break;
12✔
754
      case CFG_DTYPE_STRING:
52✔
755
      case CFG_DTYPE_DIR:
756
      case CFG_DTYPE_LOCALE:
757
      case CFG_DTYPE_CHARSET:
758
      case CFG_DTYPE_TIMEZONE:
759
        item.str = taosStrdup(obj->str);
52!
760
        if (item.str == NULL) {
52!
761
          sdbCancelFetch(pSdb, pIter);
×
762
          sdbRelease(pSdb, obj);
×
763
          code = terrno;
×
764
          goto _exit;
×
765
        }
766
        break;
52✔
767
    }
768
    if (taosArrayPush(array, &item) == NULL) {
356!
769
      sdbCancelFetch(pSdb, pIter);
×
770
      sdbRelease(pSdb, obj);
×
771
      code = TSDB_CODE_OUT_OF_MEMORY;
×
772
      goto _exit;
×
773
      break;
774
    }
775
    sdbRelease(pSdb, obj);
356✔
776
  }
777
_exit:
42✔
778
  if (code != 0) {
42!
779
    mError("failed to init config array from sdb, since %s", tstrerror(code));
×
780
  }
781
  return code;
42✔
782
}
783

784
static void cfgArrayCleanUp(SArray *array, bool needFree) {
44✔
785
  if (array == NULL) {
44!
786
    return;
×
787
  }
788

789
  int32_t sz = taosArrayGetSize(array);
44✔
790
  for (int32_t i = 0; i < sz; ++i) {
400✔
791
    SConfigItem *item = taosArrayGet(array, i);
356✔
792
    if (item->dtype == CFG_DTYPE_STRING || item->dtype == CFG_DTYPE_DIR || item->dtype == CFG_DTYPE_LOCALE ||
356!
793
        item->dtype == CFG_DTYPE_CHARSET || item->dtype == CFG_DTYPE_TIMEZONE) {
312✔
794
      taosMemoryFreeClear(item->str);
52!
795
    }
796
    if (needFree) {
356!
797
      taosMemoryFreeClear(item->name);
356!
798
    }
799
  }
800

801
  taosArrayDestroy(array);
44✔
802
}
803

804
static void cfgObjArrayCleanUp(SArray *array) {
4✔
805
  if (array == NULL) {
4!
806
    return;
×
807
  }
808
  int32_t sz = taosArrayGetSize(array);
4✔
809
  for (int32_t i = 0; i < sz; ++i) {
4!
810
    SConfigObj *obj = taosArrayGet(array, i);
×
811
    tFreeSConfigObj(obj);
×
812
  }
813
  taosArrayDestroy(array);
4✔
814
}
815

816
static SArray *initVariablesFromItems(SArray *pItems, const char* likePattern) {
×
817
  if (pItems == NULL) {
×
818
    return NULL;
×
819
  }
820

821
  int32_t sz = taosArrayGetSize(pItems);
×
822

823
  SArray *pInfos = taosArrayInit(sz, sizeof(SVariablesInfo));
×
824
  if (pInfos == NULL) {
×
825
    mError("failed to init array while init variables from items, since %s", tstrerror(terrno));
×
826
    return NULL;
×
827
  }
828
  for (int32_t i = 0; i < sz; ++i) {
×
829
    SConfigItem   *pItem = taosArrayGet(pItems, i);
×
830
    SVariablesInfo info = {0};
×
831
    tstrncpy(info.name, pItem->name, sizeof(info.name));
×
832
    if (likePattern != NULL && rawStrPatternMatch(pItem->name, likePattern) != TSDB_PATTERN_MATCH) {
×
833
      continue;
×
834
    }
835

836
    // init info value
837
    switch (pItem->dtype) {
×
838
      case CFG_DTYPE_NONE:
×
839
        break;
×
840
      case CFG_DTYPE_BOOL:
×
841
        tsnprintf(info.value, sizeof(info.value), "%d", pItem->bval);
×
842
        break;
×
843
      case CFG_DTYPE_INT32:
×
844
        tsnprintf(info.value, sizeof(info.value), "%d", pItem->i32);
×
845
        break;
×
846
      case CFG_DTYPE_INT64:
×
847
        tsnprintf(info.value, sizeof(info.value), "%" PRId64, pItem->i64);
×
848
        break;
×
849
      case CFG_DTYPE_FLOAT:
×
850
      case CFG_DTYPE_DOUBLE:
851
        tsnprintf(info.value, sizeof(info.value), "%f", pItem->fval);
×
852
        break;
×
853
      case CFG_DTYPE_STRING:
×
854
      case CFG_DTYPE_DIR:
855
      case CFG_DTYPE_LOCALE:
856
      case CFG_DTYPE_CHARSET:
857
      case CFG_DTYPE_TIMEZONE:
858
        tsnprintf(info.value, sizeof(info.value), "%s", pItem->str);
×
859
        break;
×
860
    }
861

862
    // init info scope
863
    switch (pItem->scope) {
×
864
      case CFG_SCOPE_SERVER:
×
865
        tstrncpy(info.scope, "server", sizeof(info.scope));
×
866
        break;
×
867
      case CFG_SCOPE_CLIENT:
×
868
        tstrncpy(info.scope, "client", sizeof(info.scope));
×
869
        break;
×
870
      case CFG_SCOPE_BOTH:
×
871
        tstrncpy(info.scope, "both", sizeof(info.scope));
×
872
        break;
×
873
      default:
×
874
        tstrncpy(info.scope, "unknown", sizeof(info.scope));
×
875
        break;
×
876
    }
877
    // init info category
878
    switch (pItem->category) {
×
879
      case CFG_CATEGORY_GLOBAL:
×
880
        tstrncpy(info.category, "global", sizeof(info.category));
×
881
        break;
×
882
      case CFG_CATEGORY_LOCAL:
×
883
        tstrncpy(info.category, "local", sizeof(info.category));
×
884
        break;
×
885
      default:
×
886
        tstrncpy(info.category, "unknown", sizeof(info.category));
×
887
        break;
×
888
    }
889
    if (NULL == taosArrayPush(pInfos, &info)) {
×
890
      mError("failed to push info to array while init variables from items,since %s", tstrerror(terrno));
×
891
      taosArrayDestroy(pInfos);
×
892
      return NULL;
×
893
    }
894
  }
895

896
  return pInfos;
×
897
}
898

899
static int32_t mndProcessShowVariablesReq(SRpcMsg *pReq) {
×
900
  SShowVariablesRsp rsp = {0};
×
901
  int32_t           code = TSDB_CODE_SUCCESS;
×
902
  SShowVariablesReq req = {0};
×
903
  SArray           *array = NULL;
×
904

905
  code = tDeserializeSShowVariablesReq(pReq->pCont, pReq->contLen, &req);
×
906
  if (code != 0) {
×
907
    mError("failed to deserialize config req, since %s", terrstr());
×
908
    goto _OVER;
×
909
  }
910

911
  if ((code = mndCheckOperPrivilege(pReq->info.node, pReq->info.conn.user, MND_OPER_SHOW_VARIABLES)) != 0) {
×
912
    goto _OVER;
×
913
  }
914

915
  SVariablesInfo info = {0};
×
916
  char          *likePattern = req.opType == OP_TYPE_LIKE ? req.val : NULL;
×
917
  rsp.variables = initVariablesFromItems(taosGetGlobalCfg(tsCfg), likePattern);
×
918
  if (rsp.variables == NULL) {
×
919
    code = terrno;
×
920
    goto _OVER;
×
921
  }
922
  int32_t rspLen = tSerializeSShowVariablesRsp(NULL, 0, &rsp);
×
923
  void   *pRsp = rpcMallocCont(rspLen);
×
924
  if (pRsp == NULL) {
×
925
    code = terrno;
×
926
    goto _OVER;
×
927
  }
928

929
  if ((rspLen = tSerializeSShowVariablesRsp(pRsp, rspLen, &rsp)) <= 0) {
×
930
    rpcFreeCont(pRsp);
×
931
    code = rspLen;
×
932
    goto _OVER;
×
933
  }
934

935
  pReq->info.rspLen = rspLen;
×
936
  pReq->info.rsp = pRsp;
×
937
  code = 0;
×
938

939
_OVER:
×
940

941
  if (code != 0) {
×
942
    mError("failed to get show variables info since %s", tstrerror(code));
×
943
  }
944
  tFreeSShowVariablesReq(&req);
×
945
  tFreeSShowVariablesRsp(&rsp);
×
946
  TAOS_RETURN(code);
×
947
}
948

949
int32_t compareSConfigItem(const SConfigObj *item1, SConfigItem *item2, bool *compare) {
×
950
  *compare = true;
×
951
  switch (item1->dtype) {
×
952
    case CFG_DTYPE_BOOL:
×
953
      if (item1->bval != item2->bval) {
×
954
        item2->bval = item1->bval;
×
955
        *compare = false;
×
956
      }
957
      break;
×
958
    case CFG_DTYPE_FLOAT:
×
959
      if (item1->fval != item2->fval) {
×
960
        item2->fval = item1->fval;
×
961
        *compare = false;
×
962
      }
963
      break;
×
964
    case CFG_DTYPE_INT32:
×
965
      if (item1->i32 != item2->i32) {
×
966
        item2->i32 = item1->i32;
×
967
        *compare = false;
×
968
      }
969
      break;
×
970
    case CFG_DTYPE_INT64:
×
971
      if (item1->i64 != item2->i64) {
×
972
        item2->i64 = item1->i64;
×
973
        *compare = false;
×
974
      }
975
      break;
×
976
    case CFG_DTYPE_STRING:
×
977
    case CFG_DTYPE_DIR:
978
    case CFG_DTYPE_LOCALE:
979
    case CFG_DTYPE_CHARSET:
980
    case CFG_DTYPE_TIMEZONE:
981
      if (strcmp(item1->str, item2->str) != 0) {
×
982
        item2->str = taosStrdup(item1->str);
×
983
        if (item2->str == NULL) {
×
984
          return TSDB_CODE_OUT_OF_MEMORY;
×
985
        }
986
        *compare = false;
×
987
      }
988
      break;
×
989
    default:
×
990
      *compare = false;
×
991
      return TSDB_CODE_INVALID_CFG;
×
992
  }
993
  return TSDB_CODE_SUCCESS;
×
994
}
995

996
int32_t compareSConfigItemArrays(SMnode *pMnode, const SArray *dArray, SArray *diffArray) {
×
997
  int32_t code = 0;
×
998
  int32_t dsz = taosArrayGetSize(dArray);
×
999
  bool    compare = false;
×
1000

1001
  for (int i = 0; i < dsz; i++) {
×
1002
    SConfigItem *dItem = (SConfigItem *)taosArrayGet(dArray, i);
×
1003
    SConfigObj  *mObj = sdbAcquire(pMnode->pSdb, SDB_CFG, dItem->name);
×
1004
    if (mObj == NULL) {
×
1005
      mError("failed to acquire config:%s from sdb, since %s", dItem->name, tstrerror(code));
×
1006
      continue;
×
1007
    }
1008

1009
    code = compareSConfigItem(mObj, dItem, &compare);
×
1010
    if (code != TSDB_CODE_SUCCESS) {
×
1011
      sdbRelease(pMnode->pSdb, mObj);
×
1012
      return code;
×
1013
    }
1014

1015
    if (!compare) {
×
1016
      if (taosArrayPush(diffArray, dItem) == NULL) {
×
1017
        sdbRelease(pMnode->pSdb, mObj);
×
1018
        return terrno;
×
1019
      }
1020
    }
1021

1022
    sdbRelease(pMnode->pSdb, mObj);
×
1023
  }
1024

1025
  return code;
×
1026
}
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