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

taosdata / TDengine / #3559

18 Dec 2024 12:59AM UTC coverage: 59.805% (+0.03%) from 59.778%
#3559

push

travis-ci

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

merge: main to 3.0 branch

132705 of 287544 branches covered (46.15%)

Branch coverage included in aggregate %.

87 of 95 new or added lines in 19 files covered. (91.58%)

1132 existing lines in 133 files now uncovered.

209591 of 284807 relevant lines covered (73.59%)

8125235.78 hits per line

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

62.47
/source/dnode/mnode/impl/src/mndDnode.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 <stdio.h>
18
#include "audit.h"
19
#include "mndCluster.h"
20
#include "mndDb.h"
21
#include "mndDnode.h"
22
#include "mndMnode.h"
23
#include "mndPrivilege.h"
24
#include "mndQnode.h"
25
#include "mndShow.h"
26
#include "mndSnode.h"
27
#include "mndTrans.h"
28
#include "mndUser.h"
29
#include "mndVgroup.h"
30
#include "taos_monitor.h"
31
#include "tconfig.h"
32
#include "tjson.h"
33
#include "tmisce.h"
34
#include "tunit.h"
35

36
#define TSDB_DNODE_VER_NUMBER   2
37
#define TSDB_DNODE_RESERVE_SIZE 40
38

39
static const char *offlineReason[] = {
40
    "",
41
    "status msg timeout",
42
    "status not received",
43
    "version not match",
44
    "dnodeId not match",
45
    "clusterId not match",
46
    "statusInterval not match",
47
    "timezone not match",
48
    "locale not match",
49
    "charset not match",
50
    "ttlChangeOnWrite not match",
51
    "enableWhiteList not match",
52
    "encryptionKey not match",
53
    "monitor not match",
54
    "monitor switch not match",
55
    "monitor interval not match",
56
    "monitor slow log threshold not match",
57
    "monitor slow log sql max len not match",
58
    "monitor slow log scope not match",
59
    "unknown",
60
};
61

62
enum {
63
  DND_ACTIVE_CODE,
64
  DND_CONN_ACTIVE_CODE,
65
};
66

67
enum {
68
  DND_CREATE,
69
  DND_ADD,
70
  DND_DROP,
71
};
72

73
static int32_t  mndCreateDefaultDnode(SMnode *pMnode);
74
static SSdbRaw *mndDnodeActionEncode(SDnodeObj *pDnode);
75
static SSdbRow *mndDnodeActionDecode(SSdbRaw *pRaw);
76
static int32_t  mndDnodeActionInsert(SSdb *pSdb, SDnodeObj *pDnode);
77
static int32_t  mndDnodeActionDelete(SSdb *pSdb, SDnodeObj *pDnode);
78
static int32_t  mndDnodeActionUpdate(SSdb *pSdb, SDnodeObj *pOld, SDnodeObj *pNew);
79
static int32_t  mndProcessDnodeListReq(SRpcMsg *pReq);
80

81
static int32_t mndProcessCreateDnodeReq(SRpcMsg *pReq);
82
static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq);
83
static int32_t mndProcessStatusReq(SRpcMsg *pReq);
84
static int32_t mndProcessNotifyReq(SRpcMsg *pReq);
85
static int32_t mndProcessRestoreDnodeReq(SRpcMsg *pReq);
86
static int32_t mndProcessStatisReq(SRpcMsg *pReq);
87
static int32_t mndProcessAuditReq(SRpcMsg *pReq);
88
static int32_t mndProcessUpdateDnodeInfoReq(SRpcMsg *pReq);
89
static int32_t mndProcessCreateEncryptKeyReq(SRpcMsg *pRsp);
90
static int32_t mndProcessCreateEncryptKeyRsp(SRpcMsg *pRsp);
91

92
static int32_t mndRetrieveConfigs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
93
static void    mndCancelGetNextConfig(SMnode *pMnode, void *pIter);
94
static int32_t mndRetrieveDnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
95
static void    mndCancelGetNextDnode(SMnode *pMnode, void *pIter);
96

97
#ifdef _GRANT
98
int32_t mndUpdClusterInfo(SRpcMsg *pReq);
99
#else
100
static int32_t mndUpdClusterInfo(SRpcMsg *pReq) { return 0; }
101
#endif
102

103
int32_t mndInitDnode(SMnode *pMnode) {
1,518✔
104
  SSdbTable table = {
1,518✔
105
      .sdbType = SDB_DNODE,
106
      .keyType = SDB_KEY_INT32,
107
      .deployFp = (SdbDeployFp)mndCreateDefaultDnode,
108
      .encodeFp = (SdbEncodeFp)mndDnodeActionEncode,
109
      .decodeFp = (SdbDecodeFp)mndDnodeActionDecode,
110
      .insertFp = (SdbInsertFp)mndDnodeActionInsert,
111
      .updateFp = (SdbUpdateFp)mndDnodeActionUpdate,
112
      .deleteFp = (SdbDeleteFp)mndDnodeActionDelete,
113
  };
114

115
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_DNODE, mndProcessCreateDnodeReq);
1,518✔
116
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_DNODE, mndProcessDropDnodeReq);
1,518✔
117
  mndSetMsgHandle(pMnode, TDMT_MND_STATUS, mndProcessStatusReq);
1,518✔
118
  mndSetMsgHandle(pMnode, TDMT_MND_NOTIFY, mndProcessNotifyReq);
1,518✔
119
  mndSetMsgHandle(pMnode, TDMT_MND_DNODE_LIST, mndProcessDnodeListReq);
1,518✔
120
  mndSetMsgHandle(pMnode, TDMT_MND_RESTORE_DNODE, mndProcessRestoreDnodeReq);
1,518✔
121
  mndSetMsgHandle(pMnode, TDMT_MND_STATIS, mndProcessStatisReq);
1,518✔
122
  mndSetMsgHandle(pMnode, TDMT_MND_AUDIT, mndProcessAuditReq);
1,518✔
123
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_ENCRYPT_KEY, mndProcessCreateEncryptKeyReq);
1,518✔
124
  mndSetMsgHandle(pMnode, TDMT_DND_CREATE_ENCRYPT_KEY_RSP, mndProcessCreateEncryptKeyRsp);
1,518✔
125
  mndSetMsgHandle(pMnode, TDMT_MND_UPDATE_DNODE_INFO, mndProcessUpdateDnodeInfoReq);
1,518✔
126

127
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_CONFIGS, mndRetrieveConfigs);
1,518✔
128
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_CONFIGS, mndCancelGetNextConfig);
1,518✔
129
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_DNODE, mndRetrieveDnodes);
1,518✔
130
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_DNODE, mndCancelGetNextDnode);
1,518✔
131

132
  return sdbSetTable(pMnode->pSdb, table);
1,518✔
133
}
134

135
SIpWhiteList *mndCreateIpWhiteOfDnode(SMnode *pMnode);
136
SIpWhiteList *mndAddIpWhiteOfDnode(SIpWhiteList *pIpWhiteList, char *fqdn);
137
SIpWhiteList *mndRmIpWhiteOfDnode(SIpWhiteList *pIpWhiteList, char *fqdn);
138
void          mndCleanupDnode(SMnode *pMnode) {}
1,517✔
139

140
static int32_t mndCreateDefaultDnode(SMnode *pMnode) {
1,128✔
141
  int32_t  code = -1;
1,128✔
142
  SSdbRaw *pRaw = NULL;
1,128✔
143
  STrans  *pTrans = NULL;
1,128✔
144

145
  SDnodeObj dnodeObj = {0};
1,128✔
146
  dnodeObj.id = 1;
1,128✔
147
  dnodeObj.createdTime = taosGetTimestampMs();
1,128✔
148
  dnodeObj.updateTime = dnodeObj.createdTime;
1,128✔
149
  dnodeObj.port = tsServerPort;
1,128✔
150
  tstrncpy(dnodeObj.fqdn, tsLocalFqdn, TSDB_FQDN_LEN);
1,128✔
151
  dnodeObj.fqdn[TSDB_FQDN_LEN - 1] = 0;
1,128✔
152
  (void)snprintf(dnodeObj.ep, TSDB_EP_LEN - 1, "%s:%u", tsLocalFqdn, tsServerPort);
1,128✔
153
  char *machineId = NULL;
1,128✔
154
  code = tGetMachineId(&machineId);
1,128✔
155
  if (machineId) {
1,128!
156
    (void)memcpy(dnodeObj.machineId, machineId, TSDB_MACHINE_ID_LEN);
1,128✔
157
    taosMemoryFreeClear(machineId);
1,128!
158
  } else {
159
#if defined(TD_ENTERPRISE) && !defined(GRANTS_CFG)
160
    terrno = TSDB_CODE_DNODE_NO_MACHINE_CODE;
×
161
    goto _OVER;
×
162
#endif
163
  }
164

165
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, NULL, "create-dnode");
1,128✔
166
  if (pTrans == NULL) {
1,128!
167
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
168
    if (terrno != 0) code = terrno;
×
169
    goto _OVER;
×
170
  }
171
  mInfo("trans:%d, used to create dnode:%s on first deploy", pTrans->id, dnodeObj.ep);
1,128!
172

173
  pRaw = mndDnodeActionEncode(&dnodeObj);
1,128✔
174
  if (pRaw == NULL) {
1,128!
175
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
176
    if (terrno != 0) code = terrno;
×
177
    goto _OVER;
×
178
  }
179
  TAOS_CHECK_GOTO(mndTransAppendCommitlog(pTrans, pRaw), NULL, _OVER);
1,128!
180
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), NULL, _OVER);
1,128!
181
  pRaw = NULL;
1,128✔
182

183
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
1,128!
184
  code = 0;
1,128✔
185
  (void)mndUpdateIpWhiteForAllUser(pMnode, TSDB_DEFAULT_USER, dnodeObj.fqdn, IP_WHITE_ADD,
1,128✔
186
                                   1);  // TODO: check the return value
187

188
_OVER:
1,128✔
189
  mndTransDrop(pTrans);
1,128✔
190
  sdbFreeRaw(pRaw);
1,128✔
191
  return code;
1,128✔
192
}
193

194
static SSdbRaw *mndDnodeActionEncode(SDnodeObj *pDnode) {
5,902✔
195
  int32_t code = 0;
5,902✔
196
  int32_t lino = 0;
5,902✔
197
  terrno = TSDB_CODE_OUT_OF_MEMORY;
5,902✔
198

199
  SSdbRaw *pRaw = sdbAllocRaw(SDB_DNODE, TSDB_DNODE_VER_NUMBER, sizeof(SDnodeObj) + TSDB_DNODE_RESERVE_SIZE);
5,902✔
200
  if (pRaw == NULL) goto _OVER;
5,902!
201

202
  int32_t dataPos = 0;
5,902✔
203
  SDB_SET_INT32(pRaw, dataPos, pDnode->id, _OVER)
5,902!
204
  SDB_SET_INT64(pRaw, dataPos, pDnode->createdTime, _OVER)
5,902!
205
  SDB_SET_INT64(pRaw, dataPos, pDnode->updateTime, _OVER)
5,902!
206
  SDB_SET_INT16(pRaw, dataPos, pDnode->port, _OVER)
5,902!
207
  SDB_SET_BINARY(pRaw, dataPos, pDnode->fqdn, TSDB_FQDN_LEN, _OVER)
5,902!
208
  SDB_SET_BINARY(pRaw, dataPos, pDnode->machineId, TSDB_MACHINE_ID_LEN, _OVER)
5,902!
209
  SDB_SET_RESERVE(pRaw, dataPos, TSDB_DNODE_RESERVE_SIZE, _OVER)
5,902!
210
  SDB_SET_INT16(pRaw, dataPos, 0, _OVER)  // forward/backward compatible
5,902!
211
  SDB_SET_INT16(pRaw, dataPos, 0, _OVER)  // forward/backward compatible
5,902!
212
  SDB_SET_DATALEN(pRaw, dataPos, _OVER);
5,902!
213

214
  terrno = 0;
5,902✔
215

216
_OVER:
5,902✔
217
  if (terrno != 0) {
5,902!
218
    mError("dnode:%d, failed to encode to raw:%p since %s", pDnode->id, pRaw, terrstr());
×
219
    sdbFreeRaw(pRaw);
×
220
    return NULL;
×
221
  }
222

223
  mTrace("dnode:%d, encode to raw:%p, row:%p", pDnode->id, pRaw, pDnode);
5,902✔
224
  return pRaw;
5,902✔
225
}
226

227
static SSdbRow *mndDnodeActionDecode(SSdbRaw *pRaw) {
3,488✔
228
  int32_t code = 0;
3,488✔
229
  int32_t lino = 0;
3,488✔
230
  terrno = TSDB_CODE_OUT_OF_MEMORY;
3,488✔
231
  SSdbRow   *pRow = NULL;
3,488✔
232
  SDnodeObj *pDnode = NULL;
3,488✔
233

234
  int8_t sver = 0;
3,488✔
235
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
3,488!
236
  if (sver < 1 || sver > TSDB_DNODE_VER_NUMBER) {
3,488!
237
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
238
    goto _OVER;
×
239
  }
240

241
  pRow = sdbAllocRow(sizeof(SDnodeObj));
3,488✔
242
  if (pRow == NULL) goto _OVER;
3,488!
243

244
  pDnode = sdbGetRowObj(pRow);
3,488✔
245
  if (pDnode == NULL) goto _OVER;
3,488!
246

247
  int32_t dataPos = 0;
3,488✔
248
  SDB_GET_INT32(pRaw, dataPos, &pDnode->id, _OVER)
3,488!
249
  SDB_GET_INT64(pRaw, dataPos, &pDnode->createdTime, _OVER)
3,488!
250
  SDB_GET_INT64(pRaw, dataPos, &pDnode->updateTime, _OVER)
3,488!
251
  SDB_GET_INT16(pRaw, dataPos, &pDnode->port, _OVER)
3,488!
252
  SDB_GET_BINARY(pRaw, dataPos, pDnode->fqdn, TSDB_FQDN_LEN, _OVER)
3,488!
253
  SDB_GET_BINARY(pRaw, dataPos, pDnode->machineId, TSDB_MACHINE_ID_LEN, _OVER)
3,488!
254
  SDB_GET_RESERVE(pRaw, dataPos, TSDB_DNODE_RESERVE_SIZE, _OVER)
3,488!
255
  if (sver > 1) {
3,488!
256
    int16_t keyLen = 0;
3,488✔
257
    SDB_GET_INT16(pRaw, dataPos, &keyLen, _OVER)
3,488!
258
    SDB_GET_BINARY(pRaw, dataPos, NULL, keyLen, _OVER)
3,488!
259
    SDB_GET_INT16(pRaw, dataPos, &keyLen, _OVER)
3,488!
260
    SDB_GET_BINARY(pRaw, dataPos, NULL, keyLen, _OVER)
3,488!
261
  }
262

263
  terrno = 0;
3,488✔
264
  if (tmsgUpdateDnodeInfo(&pDnode->id, NULL, pDnode->fqdn, &pDnode->port)) {
3,488!
265
    mInfo("dnode:%d, endpoint changed", pDnode->id);
×
266
  }
267

268
_OVER:
3,488✔
269
  if (terrno != 0) {
3,488!
270
    mError("dnode:%d, failed to decode from raw:%p since %s", pDnode == NULL ? 0 : pDnode->id, pRaw, terrstr());
×
271
    taosMemoryFreeClear(pRow);
×
272
    return NULL;
×
273
  }
274

275
  mTrace("dnode:%d, decode from raw:%p, row:%p ep:%s:%u", pDnode->id, pRaw, pDnode, pDnode->fqdn, pDnode->port);
3,488✔
276
  return pRow;
3,488✔
277
}
278

279
static int32_t mndDnodeActionInsert(SSdb *pSdb, SDnodeObj *pDnode) {
2,763✔
280
  mTrace("dnode:%d, perform insert action, row:%p", pDnode->id, pDnode);
2,763✔
281
  pDnode->offlineReason = DND_REASON_STATUS_NOT_RECEIVED;
2,763✔
282

283
  char ep[TSDB_EP_LEN] = {0};
2,763✔
284
  (void)snprintf(ep, TSDB_EP_LEN - 1, "%s:%u", pDnode->fqdn, pDnode->port);
2,763✔
285
  tstrncpy(pDnode->ep, ep, TSDB_EP_LEN);
2,763✔
286
  return 0;
2,763✔
287
}
288

289
static int32_t mndDnodeActionDelete(SSdb *pSdb, SDnodeObj *pDnode) {
3,487✔
290
  mTrace("dnode:%d, perform delete action, row:%p", pDnode->id, pDnode);
3,487✔
291
  return 0;
3,487✔
292
}
293

294
static int32_t mndDnodeActionUpdate(SSdb *pSdb, SDnodeObj *pOld, SDnodeObj *pNew) {
700✔
295
  mTrace("dnode:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew);
700!
296
  pOld->updateTime = pNew->updateTime;
700✔
297
#ifdef TD_ENTERPRISE
298
  tstrncpy(pOld->machineId, pNew->machineId, TSDB_MACHINE_ID_LEN + 1);
700✔
299
#endif
300
  return 0;
700✔
301
}
302

303
SDnodeObj *mndAcquireDnode(SMnode *pMnode, int32_t dnodeId) {
423,837✔
304
  SSdb      *pSdb = pMnode->pSdb;
423,837✔
305
  SDnodeObj *pDnode = sdbAcquire(pSdb, SDB_DNODE, &dnodeId);
423,837✔
306
  if (pDnode == NULL) {
423,836✔
307
    if (terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
655✔
308
      terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
51✔
309
    } else if (terrno == TSDB_CODE_SDB_OBJ_CREATING) {
604!
310
      terrno = TSDB_CODE_MND_DNODE_IN_CREATING;
×
311
    } else if (terrno == TSDB_CODE_SDB_OBJ_DROPPING) {
604!
312
      terrno = TSDB_CODE_MND_DNODE_IN_DROPPING;
604✔
313
    } else {
314
      terrno = TSDB_CODE_APP_ERROR;
×
315
      mFatal("dnode:%d, failed to acquire db since %s", dnodeId, terrstr());
×
316
    }
317
  }
318

319
  return pDnode;
423,832✔
320
}
321

322
void mndReleaseDnode(SMnode *pMnode, SDnodeObj *pDnode) {
425,773✔
323
  SSdb *pSdb = pMnode->pSdb;
425,773✔
324
  sdbRelease(pSdb, pDnode);
425,773✔
325
}
425,776✔
326

327
SEpSet mndGetDnodeEpset(SDnodeObj *pDnode) {
22,587✔
328
  SEpSet epSet = {0};
22,587✔
329
  terrno = addEpIntoEpSet(&epSet, pDnode->fqdn, pDnode->port);
22,587✔
330
  return epSet;
22,587✔
331
}
332

333
SEpSet mndGetDnodeEpsetById(SMnode *pMnode, int32_t dnodeId) {
×
334
  SEpSet     epSet = {0};
×
335
  SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
×
336
  if (!pDnode) return epSet;
×
337

338
  epSet = mndGetDnodeEpset(pDnode);
×
339

340
  mndReleaseDnode(pMnode, pDnode);
×
341
  return epSet;
×
342
}
343

344
static SDnodeObj *mndAcquireDnodeByEp(SMnode *pMnode, char *pEpStr) {
2,591✔
345
  SSdb *pSdb = pMnode->pSdb;
2,591✔
346

347
  void *pIter = NULL;
2,591✔
348
  while (1) {
3,992✔
349
    SDnodeObj *pDnode = NULL;
6,583✔
350
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
6,583✔
351
    if (pIter == NULL) break;
6,583✔
352

353
    if (strncasecmp(pEpStr, pDnode->ep, TSDB_EP_LEN) == 0) {
5,506✔
354
      sdbCancelFetch(pSdb, pIter);
1,514✔
355
      return pDnode;
1,514✔
356
    }
357

358
    sdbRelease(pSdb, pDnode);
3,992✔
359
  }
360

361
  terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
1,077✔
362
  return NULL;
1,077✔
363
}
364

365
static SDnodeObj *mndAcquireDnodeAllStatusByEp(SMnode *pMnode, char *pEpStr) {
362✔
366
  SSdb *pSdb = pMnode->pSdb;
362✔
367

368
  void *pIter = NULL;
362✔
369
  while (1) {
362✔
370
    SDnodeObj *pDnode = NULL;
724✔
371
    ESdbStatus objStatus = 0;
724✔
372
    pIter = sdbFetchAll(pSdb, SDB_DNODE, pIter, (void **)&pDnode, &objStatus, true);
724✔
373
    if (pIter == NULL) break;
724!
374

375
    if (strncasecmp(pEpStr, pDnode->ep, TSDB_EP_LEN) == 0) {
724✔
376
      sdbCancelFetch(pSdb, pIter);
362✔
377
      return pDnode;
362✔
378
    }
379

380
    sdbRelease(pSdb, pDnode);
362✔
381
  }
382

383
  return NULL;
×
384
}
385

386
int32_t mndGetDnodeSize(SMnode *pMnode) {
146,603✔
387
  SSdb *pSdb = pMnode->pSdb;
146,603✔
388
  return sdbGetSize(pSdb, SDB_DNODE);
146,603✔
389
}
390

391
int32_t mndGetDbSize(SMnode *pMnode) {
×
392
  SSdb *pSdb = pMnode->pSdb;
×
393
  return sdbGetSize(pSdb, SDB_DB);
×
394
}
395

396
bool mndIsDnodeOnline(SDnodeObj *pDnode, int64_t curMs) {
188,048✔
397
  int64_t interval = TABS(pDnode->lastAccessTime - curMs);
188,048✔
398
  if (interval > 5000 * (int64_t)tsStatusInterval) {
188,048✔
399
    if (pDnode->rebootTime > 0 && pDnode->offlineReason == DND_REASON_ONLINE) {
7,999✔
400
      pDnode->offlineReason = DND_REASON_STATUS_MSG_TIMEOUT;
50✔
401
    }
402
    return false;
7,999✔
403
  }
404
  return true;
180,049✔
405
}
406

407
static void mndGetDnodeEps(SMnode *pMnode, SArray *pDnodeEps) {
3,191✔
408
  SSdb *pSdb = pMnode->pSdb;
3,191✔
409

410
  int32_t numOfEps = 0;
3,191✔
411
  void   *pIter = NULL;
3,191✔
412
  while (1) {
10,649✔
413
    SDnodeObj *pDnode = NULL;
13,840✔
414
    ESdbStatus objStatus = 0;
13,840✔
415
    pIter = sdbFetchAll(pSdb, SDB_DNODE, pIter, (void **)&pDnode, &objStatus, true);
13,840✔
416
    if (pIter == NULL) break;
13,840✔
417

418
    SDnodeEp dnodeEp = {0};
10,649✔
419
    dnodeEp.id = pDnode->id;
10,649✔
420
    dnodeEp.ep.port = pDnode->port;
10,649✔
421
    tstrncpy(dnodeEp.ep.fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
10,649✔
422
    sdbRelease(pSdb, pDnode);
10,649✔
423

424
    dnodeEp.isMnode = 0;
10,649✔
425
    if (mndIsMnode(pMnode, pDnode->id)) {
10,649✔
426
      dnodeEp.isMnode = 1;
4,304✔
427
    }
428
    if (taosArrayPush(pDnodeEps, &dnodeEp) == NULL) {
10,649!
429
      mError("failed to put ep into array, but continue at this call");
×
430
    }
431
  }
432
}
3,191✔
433

434
int32_t mndGetDnodeData(SMnode *pMnode, SArray *pDnodeInfo) {
53,493✔
435
  SSdb   *pSdb = pMnode->pSdb;
53,493✔
436
  int32_t code = 0;
53,493✔
437

438
  int32_t numOfEps = 0;
53,493✔
439
  void   *pIter = NULL;
53,493✔
440
  while (1) {
242,024✔
441
    SDnodeObj *pDnode = NULL;
295,517✔
442
    ESdbStatus objStatus = 0;
295,517✔
443
    pIter = sdbFetchAll(pSdb, SDB_DNODE, pIter, (void **)&pDnode, &objStatus, true);
295,517✔
444
    if (pIter == NULL) break;
295,518✔
445

446
    SDnodeInfo dInfo;
447
    dInfo.id = pDnode->id;
242,025✔
448
    dInfo.ep.port = pDnode->port;
242,025✔
449
    dInfo.offlineReason = pDnode->offlineReason;
242,025✔
450
    tstrncpy(dInfo.ep.fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
242,025✔
451
    sdbRelease(pSdb, pDnode);
242,025✔
452
    if (mndIsMnode(pMnode, pDnode->id)) {
242,025✔
453
      dInfo.isMnode = 1;
65,963✔
454
    } else {
455
      dInfo.isMnode = 0;
176,061✔
456
    }
457

458
    if (taosArrayPush(pDnodeInfo, &dInfo) == NULL) {
242,024!
459
      code = terrno;
×
460
      sdbCancelFetch(pSdb, pIter);
×
461
      break;
×
462
    }
463
  }
464
  TAOS_RETURN(code);
53,493✔
465
}
466

467
#define CHECK_MONITOR_PARA(para, err)                                                                    \
468
  if (pCfg->monitorParas.para != para) {                                                                 \
469
    mError("dnode:%d, para:%d inconsistent with cluster:%d", pDnode->id, pCfg->monitorParas.para, para); \
470
    terrno = err;                                                                                        \
471
    return err;                                                                                          \
472
  }
473

474
static int32_t mndCheckClusterCfgPara(SMnode *pMnode, SDnodeObj *pDnode, const SClusterCfg *pCfg) {
3,191✔
475
  CHECK_MONITOR_PARA(tsEnableMonitor, DND_REASON_STATUS_MONITOR_SWITCH_NOT_MATCH);
3,191!
476
  CHECK_MONITOR_PARA(tsMonitorInterval, DND_REASON_STATUS_MONITOR_INTERVAL_NOT_MATCH);
3,191!
477
  CHECK_MONITOR_PARA(tsSlowLogThreshold, DND_REASON_STATUS_MONITOR_SLOW_LOG_THRESHOLD_NOT_MATCH);
3,191!
478
  CHECK_MONITOR_PARA(tsSlowLogMaxLen, DND_REASON_STATUS_MONITOR_SLOW_LOG_SQL_MAX_LEN_NOT_MATCH);
3,191!
479
  CHECK_MONITOR_PARA(tsSlowLogScope, DND_REASON_STATUS_MONITOR_SLOW_LOG_SCOPE_NOT_MATCH);
3,191!
480

481
  if (0 != strcasecmp(pCfg->monitorParas.tsSlowLogExceptDb, tsSlowLogExceptDb)) {
3,191!
482
    mError("dnode:%d, tsSlowLogExceptDb:%s inconsistent with cluster:%s", pDnode->id,
×
483
           pCfg->monitorParas.tsSlowLogExceptDb, tsSlowLogExceptDb);
484
    terrno = TSDB_CODE_DNODE_INVALID_MONITOR_PARAS;
×
485
    return DND_REASON_STATUS_MONITOR_NOT_MATCH;
×
486
  }
487

488
  if (pCfg->statusInterval != tsStatusInterval) {
3,191!
489
    mError("dnode:%d, statusInterval:%d inconsistent with cluster:%d", pDnode->id, pCfg->statusInterval,
×
490
           tsStatusInterval);
491
    terrno = TSDB_CODE_DNODE_INVALID_STATUS_INTERVAL;
×
492
    return DND_REASON_STATUS_INTERVAL_NOT_MATCH;
×
493
  }
494

495
  if ((0 != strcasecmp(pCfg->timezone, tsTimezoneStr)) && (pMnode->checkTime != pCfg->checkTime)) {
3,191!
496
    mError("dnode:%d, timezone:%s checkTime:%" PRId64 " inconsistent with cluster %s %" PRId64, pDnode->id,
×
497
           pCfg->timezone, pCfg->checkTime, tsTimezoneStr, pMnode->checkTime);
498
    terrno = TSDB_CODE_DNODE_INVALID_TIMEZONE;
×
499
    return DND_REASON_TIME_ZONE_NOT_MATCH;
×
500
  }
501

502
  if (0 != strcasecmp(pCfg->locale, tsLocale)) {
3,191!
503
    mError("dnode:%d, locale:%s inconsistent with cluster:%s", pDnode->id, pCfg->locale, tsLocale);
×
504
    terrno = TSDB_CODE_DNODE_INVALID_LOCALE;
×
505
    return DND_REASON_LOCALE_NOT_MATCH;
×
506
  }
507

508
  if (0 != strcasecmp(pCfg->charset, tsCharset)) {
3,191!
509
    mError("dnode:%d, charset:%s inconsistent with cluster:%s", pDnode->id, pCfg->charset, tsCharset);
×
510
    terrno = TSDB_CODE_DNODE_INVALID_CHARSET;
×
511
    return DND_REASON_CHARSET_NOT_MATCH;
×
512
  }
513

514
  if (pCfg->ttlChangeOnWrite != tsTtlChangeOnWrite) {
3,191!
515
    mError("dnode:%d, ttlChangeOnWrite:%d inconsistent with cluster:%d", pDnode->id, pCfg->ttlChangeOnWrite,
×
516
           tsTtlChangeOnWrite);
517
    terrno = TSDB_CODE_DNODE_INVALID_TTL_CHG_ON_WR;
×
518
    return DND_REASON_TTL_CHANGE_ON_WRITE_NOT_MATCH;
×
519
  }
520
  int8_t enable = tsEnableWhiteList ? 1 : 0;
3,191✔
521
  if (pCfg->enableWhiteList != enable) {
3,191!
522
    mError("dnode:%d, enableWhiteList:%d inconsistent with cluster:%d", pDnode->id, pCfg->enableWhiteList, enable);
×
523
    terrno = TSDB_CODE_DNODE_INVALID_EN_WHITELIST;
×
524
    return DND_REASON_ENABLE_WHITELIST_NOT_MATCH;
×
525
  }
526

527
  if (!atomic_load_8(&pMnode->encryptMgmt.encrypting) &&
3,191!
528
      (pCfg->encryptionKeyStat != tsEncryptionKeyStat || pCfg->encryptionKeyChksum != tsEncryptionKeyChksum)) {
3,191!
529
    mError("dnode:%d, encryptionKey:%" PRIi8 "-%u inconsistent with cluster:%" PRIi8 "-%u", pDnode->id,
×
530
           pCfg->encryptionKeyStat, pCfg->encryptionKeyChksum, tsEncryptionKeyStat, tsEncryptionKeyChksum);
531
    terrno = pCfg->encryptionKeyChksum ? TSDB_CODE_DNODE_INVALID_ENCRYPTKEY : TSDB_CODE_DNODE_NO_ENCRYPT_KEY;
×
532
    return DND_REASON_ENCRYPTION_KEY_NOT_MATCH;
×
533
  }
534

535
  return DND_REASON_ONLINE;
3,191✔
536
}
537

538
static bool mndUpdateVnodeState(int32_t vgId, SVnodeGid *pGid, SVnodeLoad *pVload) {
187,937✔
539
  bool stateChanged = false;
187,937✔
540
  bool roleChanged = pGid->syncState != pVload->syncState ||
561,150✔
541
                     (pVload->syncTerm != -1 && pGid->syncTerm != pVload->syncTerm) ||
365,243!
542
                     pGid->roleTimeMs != pVload->roleTimeMs;
177,306✔
543
  if (roleChanged || pGid->syncRestore != pVload->syncRestore || pGid->syncCanRead != pVload->syncCanRead ||
187,937✔
544
      pGid->startTimeMs != pVload->startTimeMs) {
176,733✔
545
    mInfo(
11,209!
546
        "vgId:%d, state changed by status msg, old state:%s restored:%d canRead:%d new state:%s restored:%d "
547
        "canRead:%d, dnode:%d",
548
        vgId, syncStr(pGid->syncState), pGid->syncRestore, pGid->syncCanRead, syncStr(pVload->syncState),
549
        pVload->syncRestore, pVload->syncCanRead, pGid->dnodeId);
550
    pGid->syncState = pVload->syncState;
11,210✔
551
    pGid->syncTerm = pVload->syncTerm;
11,210✔
552
    pGid->syncRestore = pVload->syncRestore;
11,210✔
553
    pGid->syncCanRead = pVload->syncCanRead;
11,210✔
554
    pGid->startTimeMs = pVload->startTimeMs;
11,210✔
555
    pGid->roleTimeMs = pVload->roleTimeMs;
11,210✔
556
    stateChanged = true;
11,210✔
557
  }
558
  return stateChanged;
187,938✔
559
}
560

561
static bool mndUpdateMnodeState(SMnodeObj *pObj, SMnodeLoad *pMload) {
44,842✔
562
  bool stateChanged = false;
44,842✔
563
  bool roleChanged = pObj->syncState != pMload->syncState ||
133,062✔
564
                     (pMload->syncTerm != -1 && pObj->syncTerm != pMload->syncTerm) ||
88,177!
565
                     pObj->roleTimeMs != pMload->roleTimeMs;
43,335✔
566
  if (roleChanged || pObj->syncRestore != pMload->syncRestore) {
44,842✔
567
    mInfo("dnode:%d, mnode syncState from %s to %s, restoreState from %d to %d, syncTerm from %" PRId64 " to %" PRId64,
1,528!
568
          pObj->id, syncStr(pObj->syncState), syncStr(pMload->syncState), pObj->syncRestore, pMload->syncRestore,
569
          pObj->syncTerm, pMload->syncTerm);
570
    pObj->syncState = pMload->syncState;
1,528✔
571
    pObj->syncTerm = pMload->syncTerm;
1,528✔
572
    pObj->syncRestore = pMload->syncRestore;
1,528✔
573
    pObj->roleTimeMs = pMload->roleTimeMs;
1,528✔
574
    stateChanged = true;
1,528✔
575
  }
576
  return stateChanged;
44,842✔
577
}
578

579
extern char   *tsMonFwUri;
580
extern char   *tsMonSlowLogUri;
581
static int32_t mndProcessStatisReq(SRpcMsg *pReq) {
534✔
582
  SMnode    *pMnode = pReq->info.node;
534✔
583
  SStatisReq statisReq = {0};
534✔
584
  int32_t    code = -1;
534✔
585

586
  TAOS_CHECK_RETURN(tDeserializeSStatisReq(pReq->pCont, pReq->contLen, &statisReq));
534!
587

588
  if (tsMonitorLogProtocol) {
534!
589
    mInfo("process statis req,\n %s", statisReq.pCont);
×
590
  }
591

592
  if (statisReq.type == MONITOR_TYPE_COUNTER) {
534✔
593
    monSendContent(statisReq.pCont, tsMonFwUri);
486✔
594
  } else if (statisReq.type == MONITOR_TYPE_SLOW_LOG) {
48!
595
    monSendContent(statisReq.pCont, tsMonSlowLogUri);
48✔
596
  }
597

598
  tFreeSStatisReq(&statisReq);
534✔
599
  return 0;
534✔
600
}
601

602
static int32_t mndProcessAuditReq(SRpcMsg *pReq) {
21,222✔
603
  mTrace("process audit req:%p", pReq);
21,222✔
604
  if (tsEnableAudit && tsEnableAuditDelete) {
21,223!
605
    SMnode   *pMnode = pReq->info.node;
21,223✔
606
    SAuditReq auditReq = {0};
21,223✔
607

608
    TAOS_CHECK_RETURN(tDeserializeSAuditReq(pReq->pCont, pReq->contLen, &auditReq));
21,223!
609

610
    mDebug("received audit req:%s, %s, %s, %s", auditReq.operation, auditReq.db, auditReq.table, auditReq.pSql);
21,222✔
611

612
    auditAddRecord(pReq, pMnode->clusterId, auditReq.operation, auditReq.db, auditReq.table, auditReq.pSql,
21,222✔
613
                   auditReq.sqlLen);
614

615
    tFreeSAuditReq(&auditReq);
21,223✔
616
  }
617
  return 0;
21,223✔
618
}
619

620
static int32_t mndUpdateDnodeObj(SMnode *pMnode, SDnodeObj *pDnode) {
386✔
621
  int32_t       code = 0, lino = 0;
386✔
622
  SDnodeInfoReq infoReq = {0};
386✔
623
  int32_t       contLen = 0;
386✔
624
  void         *pReq = NULL;
386✔
625

626
  infoReq.dnodeId = pDnode->id;
386✔
627
  tstrncpy(infoReq.machineId, pDnode->machineId, TSDB_MACHINE_ID_LEN + 1);
386✔
628

629
  if ((contLen = tSerializeSDnodeInfoReq(NULL, 0, &infoReq)) <= 0) {
386!
630
    TAOS_RETURN(contLen ? contLen : TSDB_CODE_OUT_OF_MEMORY);
×
631
  }
632
  pReq = rpcMallocCont(contLen);
386✔
633
  if (pReq == NULL) {
386!
634
    TAOS_RETURN(terrno);
×
635
  }
636

637
  if ((contLen = tSerializeSDnodeInfoReq(pReq, contLen, &infoReq)) <= 0) {
386!
638
    code = contLen;
×
639
    goto _exit;
×
640
  }
641

642
  SRpcMsg rpcMsg = {.msgType = TDMT_MND_UPDATE_DNODE_INFO, .pCont = pReq, .contLen = contLen};
386✔
643
  TAOS_CHECK_EXIT(tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg));
386!
644
_exit:
386✔
645
  if (code < 0) {
386!
646
    mError("dnode:%d, failed to update dnode info since %s", pDnode->id, tstrerror(code));
×
647
  }
648
  TAOS_RETURN(code);
386✔
649
}
650

651
static int32_t mndProcessUpdateDnodeInfoReq(SRpcMsg *pReq) {
386✔
652
  int32_t       code = 0, lino = 0;
386✔
653
  SMnode       *pMnode = pReq->info.node;
386✔
654
  SDnodeInfoReq infoReq = {0};
386✔
655
  SDnodeObj    *pDnode = NULL;
386✔
656
  STrans       *pTrans = NULL;
386✔
657
  SSdbRaw      *pCommitRaw = NULL;
386✔
658

659
  TAOS_CHECK_EXIT(tDeserializeSDnodeInfoReq(pReq->pCont, pReq->contLen, &infoReq));
386!
660

661
  pDnode = mndAcquireDnode(pMnode, infoReq.dnodeId);
386✔
662
  if (pDnode == NULL) {
386!
663
    TAOS_CHECK_EXIT(terrno);
×
664
  }
665

666
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, NULL, "update-dnode-obj");
386✔
667
  if (pTrans == NULL) {
386!
668
    TAOS_CHECK_EXIT(terrno);
×
669
  }
670

671
  pDnode->updateTime = taosGetTimestampMs();
386✔
672

673
  if ((pCommitRaw = mndDnodeActionEncode(pDnode)) == NULL) {
386!
674
    TAOS_CHECK_EXIT(terrno);
×
675
  }
676
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
386!
677
    mError("trans:%d, failed to append commit log since %s", pTrans->id, tstrerror(code));
×
678
    TAOS_CHECK_EXIT(code);
×
679
  }
680
  TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
386!
681
  pCommitRaw = NULL;
386✔
682

683
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) {
386!
684
    mError("trans:%d, failed to prepare since %s", pTrans->id, tstrerror(code));
×
685
    TAOS_CHECK_EXIT(code);
×
686
  }
687

688
_exit:
386✔
689
  mndReleaseDnode(pMnode, pDnode);
386✔
690
  if (code != 0) {
386!
691
    mError("dnode:%d, failed to update dnode info at line %d since %s", infoReq.dnodeId, lino, tstrerror(code));
×
692
  }
693
  mndTransDrop(pTrans);
386✔
694
  sdbFreeRaw(pCommitRaw);
386✔
695
  TAOS_RETURN(code);
386✔
696
}
697

698
static int32_t mndProcessStatusReq(SRpcMsg *pReq) {
80,865✔
699
  SMnode    *pMnode = pReq->info.node;
80,865✔
700
  SStatusReq statusReq = {0};
80,865✔
701
  SDnodeObj *pDnode = NULL;
80,865✔
702
  int32_t    code = -1;
80,865✔
703

704
  TAOS_CHECK_GOTO(tDeserializeSStatusReq(pReq->pCont, pReq->contLen, &statusReq), NULL, _OVER);
80,865!
705

706
  int64_t clusterid = mndGetClusterId(pMnode);
80,858✔
707
  if (statusReq.clusterId != 0 && statusReq.clusterId != clusterid) {
80,867✔
708
    code = TSDB_CODE_MND_DNODE_DIFF_CLUSTER;
32✔
709
    mWarn("dnode:%d, %s, its clusterid:%" PRId64 " differ from current clusterid:%" PRId64 ", code:0x%x",
32!
710
          statusReq.dnodeId, statusReq.dnodeEp, statusReq.clusterId, clusterid, code);
711
    goto _OVER;
32✔
712
  }
713

714
  if (statusReq.dnodeId == 0) {
80,835✔
715
    pDnode = mndAcquireDnodeByEp(pMnode, statusReq.dnodeEp);
1,802✔
716
    if (pDnode == NULL) {
1,802✔
717
      mInfo("dnode:%s, not created yet", statusReq.dnodeEp);
291!
718
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
291✔
719
      if (terrno != 0) code = terrno;
291!
720
      goto _OVER;
291✔
721
    }
722
  } else {
723
    pDnode = mndAcquireDnode(pMnode, statusReq.dnodeId);
79,033✔
724
    if (pDnode == NULL) {
79,031✔
725
      int32_t err = terrno;
399✔
726
      pDnode = mndAcquireDnodeByEp(pMnode, statusReq.dnodeEp);
399✔
727
      if (pDnode != NULL) {
399✔
728
        pDnode->offlineReason = DND_REASON_DNODE_ID_NOT_MATCH;
3✔
729
        terrno = err;
3✔
730
        goto _OVER;
3✔
731
      }
732

733
      mError("dnode:%d, %s not exist, code:0x%x", statusReq.dnodeId, statusReq.dnodeEp, err);
396!
734
      if (err == TSDB_CODE_MND_DNODE_NOT_EXIST) {
396✔
735
        terrno = err;
34✔
736
        goto _OVER;
34✔
737
      } else {
738
        pDnode = mndAcquireDnodeAllStatusByEp(pMnode, statusReq.dnodeEp);
362✔
739
        if (pDnode == NULL) goto _OVER;
362!
740
      }
741
    }
742
  }
743

744
  pMnode->ipWhiteVer = mndGetIpWhiteVer(pMnode);
80,505✔
745

746
  int64_t analVer = sdbGetTableVer(pMnode->pSdb, SDB_ANODE);
80,506✔
747
  int64_t dnodeVer = sdbGetTableVer(pMnode->pSdb, SDB_DNODE) + sdbGetTableVer(pMnode->pSdb, SDB_MNODE);
80,504✔
748
  int64_t curMs = taosGetTimestampMs();
80,504✔
749
  bool    online = mndIsDnodeOnline(pDnode, curMs);
80,504✔
750
  bool    dnodeChanged = (statusReq.dnodeVer == 0) || (statusReq.dnodeVer != dnodeVer);
80,506✔
751
  bool    reboot = (pDnode->rebootTime != statusReq.rebootTime);
80,506✔
752
  bool    supportVnodesChanged = pDnode->numOfSupportVnodes != statusReq.numOfSupportVnodes;
80,506✔
753
  bool    encryptKeyChanged = pDnode->encryptionKeyChksum != statusReq.clusterCfg.encryptionKeyChksum;
80,506✔
754
  bool    enableWhiteListChanged = statusReq.clusterCfg.enableWhiteList != (tsEnableWhiteList ? 1 : 0);
80,506✔
755
  bool    analVerChanged = (analVer != statusReq.analVer);
80,506✔
756
  bool    needCheck = !online || dnodeChanged || reboot || supportVnodesChanged || analVerChanged ||
78,604!
757
                   pMnode->ipWhiteVer != statusReq.ipWhiteVer || encryptKeyChanged || enableWhiteListChanged;
159,110!
758
  const STraceId *trace = &pReq->info.traceId;
80,506✔
759
  mGTrace("dnode:%d, status received, accessTimes:%d check:%d online:%d reboot:%d changed:%d statusSeq:%d", pDnode->id,
80,506!
760
          pDnode->accessTimes, needCheck, online, reboot, dnodeChanged, statusReq.statusSeq);
761

762
  if (reboot) {
80,506✔
763
    tsGrantHBInterval = GRANT_HEART_BEAT_MIN;
1,952✔
764
  }
765

766
  for (int32_t v = 0; v < taosArrayGetSize(statusReq.pVloads); ++v) {
268,511✔
767
    SVnodeLoad *pVload = taosArrayGet(statusReq.pVloads, v);
188,002✔
768

769
    SVgObj *pVgroup = mndAcquireVgroup(pMnode, pVload->vgId);
187,999✔
770
    if (pVgroup != NULL) {
188,003✔
771
      if (pVload->syncState == TAOS_SYNC_STATE_LEADER || pVload->syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
187,972✔
772
        pVgroup->cacheUsage = pVload->cacheUsage;
152,142✔
773
        pVgroup->numOfCachedTables = pVload->numOfCachedTables;
152,142✔
774
        pVgroup->numOfTables = pVload->numOfTables;
152,142✔
775
        pVgroup->numOfTimeSeries = pVload->numOfTimeSeries;
152,142✔
776
        pVgroup->totalStorage = pVload->totalStorage;
152,142✔
777
        pVgroup->compStorage = pVload->compStorage;
152,142✔
778
        pVgroup->pointsWritten = pVload->pointsWritten;
152,142✔
779
      }
780
      bool stateChanged = false;
187,972✔
781
      for (int32_t vg = 0; vg < pVgroup->replica; ++vg) {
236,894✔
782
        SVnodeGid *pGid = &pVgroup->vnodeGid[vg];
236,867✔
783
        if (pGid->dnodeId == statusReq.dnodeId) {
236,867✔
784
          if (pVload->startTimeMs == 0) {
187,945!
785
            pVload->startTimeMs = statusReq.rebootTime;
×
786
          }
787
          if (pVload->roleTimeMs == 0) {
187,945!
788
            pVload->roleTimeMs = statusReq.rebootTime;
×
789
          }
790
          stateChanged = mndUpdateVnodeState(pVgroup->vgId, pGid, pVload);
187,945✔
791
          break;
187,937✔
792
        }
793
      }
794
      if (stateChanged) {
187,964✔
795
        SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName);
11,210✔
796
        if (pDb != NULL && pDb->stateTs != curMs) {
11,210✔
797
          mInfo("db:%s, stateTs changed by status msg, old stateTs:%" PRId64 " new stateTs:%" PRId64, pDb->name,
6,890!
798
                pDb->stateTs, curMs);
799
          pDb->stateTs = curMs;
6,890✔
800
        }
801
        mndReleaseDb(pMnode, pDb);
11,210✔
802
      }
803
    }
804

805
    mndReleaseVgroup(pMnode, pVgroup);
187,995✔
806
  }
807

808
  SMnodeObj *pObj = mndAcquireMnode(pMnode, pDnode->id);
80,505✔
809
  if (pObj != NULL) {
80,507✔
810
    if (statusReq.mload.roleTimeMs == 0) {
44,842✔
811
      statusReq.mload.roleTimeMs = statusReq.rebootTime;
8✔
812
    }
813
    (void)mndUpdateMnodeState(pObj, &statusReq.mload);
44,842✔
814
    mndReleaseMnode(pMnode, pObj);
44,842✔
815
  }
816

817
  SQnodeObj *pQnode = mndAcquireQnode(pMnode, statusReq.qload.dnodeId);
80,507✔
818
  if (pQnode != NULL) {
80,507✔
819
    pQnode->load = statusReq.qload;
28,690✔
820
    mndReleaseQnode(pMnode, pQnode);
28,690✔
821
  }
822

823
  if (needCheck) {
80,506✔
824
    if (statusReq.sver != tsVersion) {
3,191!
825
      if (pDnode != NULL) {
×
826
        pDnode->offlineReason = DND_REASON_VERSION_NOT_MATCH;
×
827
      }
828
      mError("dnode:%d, status msg version:%d not match cluster:%d", statusReq.dnodeId, statusReq.sver, tsVersion);
×
829
      terrno = TSDB_CODE_VERSION_NOT_COMPATIBLE;
×
830
      goto _OVER;
×
831
    }
832

833
    if (statusReq.dnodeId == 0) {
3,191✔
834
      mInfo("dnode:%d, %s first access, clusterId:%" PRId64, pDnode->id, pDnode->ep, pMnode->clusterId);
1,511!
835
    } else {
836
      if (statusReq.clusterId != pMnode->clusterId) {
1,680!
837
        if (pDnode != NULL) {
×
838
          pDnode->offlineReason = DND_REASON_CLUSTER_ID_NOT_MATCH;
×
839
        }
840
        mError("dnode:%d, clusterId %" PRId64 " not match exist %" PRId64, pDnode->id, statusReq.clusterId,
×
841
               pMnode->clusterId);
842
        terrno = TSDB_CODE_MND_INVALID_CLUSTER_ID;
×
843
        goto _OVER;
×
844
      }
845
    }
846

847
    // Verify whether the cluster parameters are consistent when status change from offline to ready
848
    pDnode->offlineReason = mndCheckClusterCfgPara(pMnode, pDnode, &statusReq.clusterCfg);
3,191✔
849
    if (pDnode->offlineReason != 0) {
3,191!
850
      mError("dnode:%d, cluster cfg inconsistent since:%s", pDnode->id, offlineReason[pDnode->offlineReason]);
×
851
      if (terrno == 0) terrno = TSDB_CODE_MND_INVALID_CLUSTER_CFG;
×
852
      goto _OVER;
×
853
    }
854

855
    if (!online) {
3,191✔
856
      mInfo("dnode:%d, from offline to online, memory avail:%" PRId64 " total:%" PRId64 " cores:%.2f", pDnode->id,
1,902!
857
            statusReq.memAvail, statusReq.memTotal, statusReq.numOfCores);
858
    } else {
859
      mInfo("dnode:%d, send dnode epset, online:%d dnodeVer:%" PRId64 ":%" PRId64 " reboot:%d", pDnode->id, online,
1,289!
860
            statusReq.dnodeVer, dnodeVer, reboot);
861
    }
862

863
    pDnode->rebootTime = statusReq.rebootTime;
3,191✔
864
    pDnode->numOfCores = statusReq.numOfCores;
3,191✔
865
    pDnode->numOfSupportVnodes = statusReq.numOfSupportVnodes;
3,191✔
866
    pDnode->numOfDiskCfg = statusReq.numOfDiskCfg;
3,191✔
867
    pDnode->memAvail = statusReq.memAvail;
3,191✔
868
    pDnode->memTotal = statusReq.memTotal;
3,191✔
869
    pDnode->encryptionKeyStat = statusReq.clusterCfg.encryptionKeyStat;
3,191✔
870
    pDnode->encryptionKeyChksum = statusReq.clusterCfg.encryptionKeyChksum;
3,191✔
871
    if (memcmp(pDnode->machineId, statusReq.machineId, TSDB_MACHINE_ID_LEN) != 0) {
3,191✔
872
      tstrncpy(pDnode->machineId, statusReq.machineId, TSDB_MACHINE_ID_LEN + 1);
386✔
873
      if ((terrno = mndUpdateDnodeObj(pMnode, pDnode)) != 0) {
386!
874
        goto _OVER;
×
875
      }
876
    }
877

878
    SStatusRsp statusRsp = {0};
3,191✔
879
    statusRsp.statusSeq++;
3,191✔
880
    statusRsp.analVer = analVer;
3,191✔
881
    statusRsp.dnodeVer = dnodeVer;
3,191✔
882
    statusRsp.dnodeCfg.dnodeId = pDnode->id;
3,191✔
883
    statusRsp.dnodeCfg.clusterId = pMnode->clusterId;
3,191✔
884
    statusRsp.pDnodeEps = taosArrayInit(mndGetDnodeSize(pMnode), sizeof(SDnodeEp));
3,191✔
885
    if (statusRsp.pDnodeEps == NULL) {
3,191!
886
      terrno = TSDB_CODE_OUT_OF_MEMORY;
×
887
      goto _OVER;
×
888
    }
889

890
    mndGetDnodeEps(pMnode, statusRsp.pDnodeEps);
3,191✔
891
    statusRsp.ipWhiteVer = pMnode->ipWhiteVer;
3,191✔
892

893
    int32_t contLen = tSerializeSStatusRsp(NULL, 0, &statusRsp);
3,191✔
894
    void   *pHead = rpcMallocCont(contLen);
3,191✔
895
    contLen = tSerializeSStatusRsp(pHead, contLen, &statusRsp);
3,191✔
896
    taosArrayDestroy(statusRsp.pDnodeEps);
3,191✔
897
    if (contLen < 0) {
3,191!
898
      code = contLen;
×
899
      goto _OVER;
×
900
    }
901

902
    pReq->info.rspLen = contLen;
3,191✔
903
    pReq->info.rsp = pHead;
3,191✔
904
  }
905

906
  pDnode->accessTimes++;
80,506✔
907
  pDnode->lastAccessTime = curMs;
80,506✔
908
  code = 0;
80,506✔
909

910
_OVER:
80,866✔
911
  mndReleaseDnode(pMnode, pDnode);
80,866✔
912
  taosArrayDestroy(statusReq.pVloads);
80,867✔
913
  return mndUpdClusterInfo(pReq);
80,867✔
914
}
915

916
static int32_t mndProcessNotifyReq(SRpcMsg *pReq) {
×
917
  SMnode    *pMnode = pReq->info.node;
×
918
  SNotifyReq notifyReq = {0};
×
919
  int32_t    code = 0;
×
920

921
  if ((code = tDeserializeSNotifyReq(pReq->pCont, pReq->contLen, &notifyReq)) != 0) {
×
922
    terrno = code;
×
923
    goto _OVER;
×
924
  }
925

926
  int64_t clusterid = mndGetClusterId(pMnode);
×
927
  if (notifyReq.clusterId != 0 && notifyReq.clusterId != clusterid) {
×
928
    code = TSDB_CODE_MND_DNODE_DIFF_CLUSTER;
×
929
    mWarn("dnode:%d, its clusterid:%" PRId64 " differ from current cluster:%" PRId64 " since %s", notifyReq.dnodeId,
×
930
          notifyReq.clusterId, clusterid, tstrerror(code));
931
    goto _OVER;
×
932
  }
933

934
  int32_t nVgroup = taosArrayGetSize(notifyReq.pVloads);
×
935
  for (int32_t v = 0; v < nVgroup; ++v) {
×
936
    SVnodeLoadLite *pVload = taosArrayGet(notifyReq.pVloads, v);
×
937

938
    SVgObj *pVgroup = mndAcquireVgroup(pMnode, pVload->vgId);
×
939
    if (pVgroup != NULL) {
×
940
      pVgroup->numOfTimeSeries = pVload->nTimeSeries;
×
941
      mndReleaseVgroup(pMnode, pVgroup);
×
942
    }
943
  }
944
  code = mndUpdClusterInfo(pReq);
×
945
_OVER:
×
946
  tFreeSNotifyReq(&notifyReq);
×
947
  return code;
×
948
}
949

950
static int32_t mndCreateDnode(SMnode *pMnode, SRpcMsg *pReq, SCreateDnodeReq *pCreate) {
389✔
951
  int32_t  code = -1;
389✔
952
  SSdbRaw *pRaw = NULL;
389✔
953
  STrans  *pTrans = NULL;
389✔
954

955
  SDnodeObj dnodeObj = {0};
389✔
956
  dnodeObj.id = sdbGetMaxId(pMnode->pSdb, SDB_DNODE);
389✔
957
  dnodeObj.createdTime = taosGetTimestampMs();
389✔
958
  dnodeObj.updateTime = dnodeObj.createdTime;
389✔
959
  dnodeObj.port = pCreate->port;
389✔
960
  tstrncpy(dnodeObj.fqdn, pCreate->fqdn, TSDB_FQDN_LEN);
389✔
961
  (void)snprintf(dnodeObj.ep, TSDB_EP_LEN - 1, "%s:%u", pCreate->fqdn, pCreate->port);
389✔
962

963
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_GLOBAL, pReq, "create-dnode");
389✔
964
  if (pTrans == NULL) {
389!
965
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
966
    if (terrno != 0) code = terrno;
×
967
    goto _OVER;
×
968
  }
969
  mInfo("trans:%d, used to create dnode:%s", pTrans->id, dnodeObj.ep);
389!
970
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
389✔
971

972
  pRaw = mndDnodeActionEncode(&dnodeObj);
388✔
973
  if (pRaw == NULL) {
388!
974
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
975
    if (terrno != 0) code = terrno;
×
976
    goto _OVER;
×
977
  }
978
  TAOS_CHECK_GOTO(mndTransAppendCommitlog(pTrans, pRaw), NULL, _OVER);
388!
979
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), NULL, _OVER);
388!
980
  pRaw = NULL;
388✔
981

982
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
388!
983
  code = 0;
388✔
984

985
  (void)mndUpdateIpWhiteForAllUser(pMnode, TSDB_DEFAULT_USER, dnodeObj.fqdn, IP_WHITE_ADD,
388✔
986
                                   1);  // TODO: check the return value
987
_OVER:
389✔
988
  mndTransDrop(pTrans);
389✔
989
  sdbFreeRaw(pRaw);
389✔
990
  return code;
389✔
991
}
992

993
static int32_t mndProcessDnodeListReq(SRpcMsg *pReq) {
181✔
994
  SMnode       *pMnode = pReq->info.node;
181✔
995
  SSdb         *pSdb = pMnode->pSdb;
181✔
996
  SDnodeObj    *pObj = NULL;
181✔
997
  void         *pIter = NULL;
181✔
998
  SDnodeListRsp rsp = {0};
181✔
999
  int32_t       code = -1;
181✔
1000

1001
  rsp.dnodeList = taosArrayInit(5, sizeof(SEpSet));
181✔
1002
  if (NULL == rsp.dnodeList) {
181!
1003
    mError("failed to alloc epSet while process dnode list req");
×
1004
    code = terrno;
×
1005
    goto _OVER;
×
1006
  }
1007

1008
  while (1) {
502✔
1009
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pObj);
683✔
1010
    if (pIter == NULL) break;
683✔
1011

1012
    SEpSet epSet = {0};
502✔
1013
    epSet.numOfEps = 1;
502✔
1014
    tstrncpy(epSet.eps[0].fqdn, pObj->fqdn, TSDB_FQDN_LEN);
502✔
1015
    epSet.eps[0].port = pObj->port;
502✔
1016

1017
    if (taosArrayPush(rsp.dnodeList, &epSet) == NULL) {
1,004!
1018
      if (terrno != 0) code = terrno;
×
1019
      sdbRelease(pSdb, pObj);
×
1020
      sdbCancelFetch(pSdb, pIter);
×
1021
      goto _OVER;
×
1022
    }
1023

1024
    sdbRelease(pSdb, pObj);
502✔
1025
  }
1026

1027
  int32_t rspLen = tSerializeSDnodeListRsp(NULL, 0, &rsp);
181✔
1028
  void   *pRsp = rpcMallocCont(rspLen);
181✔
1029
  if (pRsp == NULL) {
181!
1030
    code = terrno;
×
1031
    goto _OVER;
×
1032
  }
1033

1034
  if ((rspLen = tSerializeSDnodeListRsp(pRsp, rspLen, &rsp)) <= 0) {
181!
1035
    code = rspLen;
×
1036
    goto _OVER;
×
1037
  }
1038

1039
  pReq->info.rspLen = rspLen;
181✔
1040
  pReq->info.rsp = pRsp;
181✔
1041
  code = 0;
181✔
1042

1043
_OVER:
181✔
1044

1045
  if (code != 0) {
181!
1046
    mError("failed to get dnode list since %s", tstrerror(code));
×
1047
  }
1048

1049
  tFreeSDnodeListRsp(&rsp);
181✔
1050

1051
  TAOS_RETURN(code);
181✔
1052
}
1053

1054
void getSlowLogScopeString(int32_t scope, char *result) {
7✔
1055
  if (scope == SLOW_LOG_TYPE_NULL) {
7!
UNCOV
1056
    (void)strncat(result, "NONE", 64);
×
UNCOV
1057
    return;
×
1058
  }
1059
  while (scope > 0) {
14✔
1060
    if (scope & SLOW_LOG_TYPE_QUERY) {
7!
1061
      (void)strncat(result, "QUERY", 64);
7✔
1062
      scope &= ~SLOW_LOG_TYPE_QUERY;
7✔
1063
    } else if (scope & SLOW_LOG_TYPE_INSERT) {
×
1064
      (void)strncat(result, "INSERT", 64);
×
1065
      scope &= ~SLOW_LOG_TYPE_INSERT;
×
1066
    } else if (scope & SLOW_LOG_TYPE_OTHERS) {
×
1067
      (void)strncat(result, "OTHERS", 64);
×
1068
      scope &= ~SLOW_LOG_TYPE_OTHERS;
×
1069
    } else {
1070
      (void)printf("invalid slow log scope:%d", scope);
×
1071
      return;
×
1072
    }
1073

1074
    if (scope > 0) {
7!
1075
      (void)strncat(result, "|", 64);
×
1076
    }
1077
  }
1078
}
1079

1080
static int32_t mndProcessCreateDnodeReq(SRpcMsg *pReq) {
390✔
1081
  SMnode         *pMnode = pReq->info.node;
390✔
1082
  int32_t         code = -1;
390✔
1083
  SDnodeObj      *pDnode = NULL;
390✔
1084
  SCreateDnodeReq createReq = {0};
390✔
1085

1086
  if ((code = grantCheck(TSDB_GRANT_DNODE)) != 0 || (code = grantCheck(TSDB_GRANT_CPU_CORES)) != 0) {
390!
1087
    goto _OVER;
×
1088
  }
1089

1090
  TAOS_CHECK_GOTO(tDeserializeSCreateDnodeReq(pReq->pCont, pReq->contLen, &createReq), NULL, _OVER);
390!
1091

1092
  mInfo("dnode:%s:%d, start to create", createReq.fqdn, createReq.port);
390!
1093
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_DNODE), NULL, _OVER);
390✔
1094

1095
  if (createReq.fqdn[0] == 0 || createReq.port <= 0 || createReq.port > UINT16_MAX) {
389!
1096
    code = TSDB_CODE_MND_INVALID_DNODE_EP;
×
1097
    goto _OVER;
×
1098
  }
1099

1100
  char ep[TSDB_EP_LEN];
1101
  (void)snprintf(ep, TSDB_EP_LEN, "%s:%d", createReq.fqdn, createReq.port);
389✔
1102
  pDnode = mndAcquireDnodeByEp(pMnode, ep);
389✔
1103
  if (pDnode != NULL) {
389!
1104
    code = TSDB_CODE_MND_DNODE_ALREADY_EXIST;
×
1105
    goto _OVER;
×
1106
  }
1107

1108
  code = mndCreateDnode(pMnode, pReq, &createReq);
389✔
1109
  if (code == 0) {
389✔
1110
    code = TSDB_CODE_ACTION_IN_PROGRESS;
388✔
1111
    tsGrantHBInterval = 5;
388✔
1112
  }
1113

1114
  char obj[200] = {0};
389✔
1115
  (void)tsnprintf(obj, sizeof(obj), "%s:%d", createReq.fqdn, createReq.port);
389✔
1116

1117
  auditRecord(pReq, pMnode->clusterId, "createDnode", "", obj, createReq.sql, createReq.sqlLen);
389✔
1118

1119
_OVER:
390✔
1120
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
390!
1121
    mError("dnode:%s:%d, failed to create since %s", createReq.fqdn, createReq.port, tstrerror(code));
2!
1122
  }
1123

1124
  mndReleaseDnode(pMnode, pDnode);
390✔
1125
  tFreeSCreateDnodeReq(&createReq);
390✔
1126
  TAOS_RETURN(code);
390✔
1127
}
1128

1129
extern int32_t mndProcessRestoreDnodeReqImpl(SRpcMsg *pReq);
1130

1131
int32_t mndProcessRestoreDnodeReq(SRpcMsg *pReq) { return mndProcessRestoreDnodeReqImpl(pReq); }
6✔
1132

1133
#ifndef TD_ENTERPRISE
1134
int32_t mndProcessRestoreDnodeReqImpl(SRpcMsg *pReq) { return 0; }
1135
#endif
1136

1137
static int32_t mndDropDnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode, SMnodeObj *pMObj, SQnodeObj *pQObj,
22✔
1138
                            SSnodeObj *pSObj, int32_t numOfVnodes, bool force, bool unsafe) {
1139
  int32_t  code = -1;
22✔
1140
  SSdbRaw *pRaw = NULL;
22✔
1141
  STrans  *pTrans = NULL;
22✔
1142

1143
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "drop-dnode");
22✔
1144
  if (pTrans == NULL) {
22!
1145
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1146
    if (terrno != 0) code = terrno;
×
1147
    goto _OVER;
×
1148
  }
1149
  mndTransSetSerial(pTrans);
22✔
1150
  mInfo("trans:%d, used to drop dnode:%d, force:%d", pTrans->id, pDnode->id, force);
22!
1151
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
22!
1152

1153
  pRaw = mndDnodeActionEncode(pDnode);
22✔
1154
  if (pRaw == NULL) {
22!
1155
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1156
    if (terrno != 0) code = terrno;
×
1157
    goto _OVER;
×
1158
  }
1159
  TAOS_CHECK_GOTO(mndTransAppendRedolog(pTrans, pRaw), NULL, _OVER);
22!
1160
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_DROPPING), NULL, _OVER);
22!
1161
  pRaw = NULL;
22✔
1162

1163
  pRaw = mndDnodeActionEncode(pDnode);
22✔
1164
  if (pRaw == NULL) {
22!
1165
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1166
    if (terrno != 0) code = terrno;
×
1167
    goto _OVER;
×
1168
  }
1169
  TAOS_CHECK_GOTO(mndTransAppendCommitlog(pTrans, pRaw), NULL, _OVER);
22!
1170
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_DROPPED), NULL, _OVER);
22!
1171
  pRaw = NULL;
22✔
1172

1173
  if (pMObj != NULL) {
22✔
1174
    mInfo("trans:%d, mnode on dnode:%d will be dropped", pTrans->id, pDnode->id);
4!
1175
    TAOS_CHECK_GOTO(mndSetDropMnodeInfoToTrans(pMnode, pTrans, pMObj, force), NULL, _OVER);
4!
1176
  }
1177

1178
  if (pQObj != NULL) {
22✔
1179
    mInfo("trans:%d, qnode on dnode:%d will be dropped", pTrans->id, pDnode->id);
3!
1180
    TAOS_CHECK_GOTO(mndSetDropQnodeInfoToTrans(pMnode, pTrans, pQObj, force), NULL, _OVER);
3!
1181
  }
1182

1183
  if (pSObj != NULL) {
22✔
1184
    mInfo("trans:%d, snode on dnode:%d will be dropped", pTrans->id, pDnode->id);
3!
1185
    TAOS_CHECK_GOTO(mndSetDropSnodeInfoToTrans(pMnode, pTrans, pSObj, force), NULL, _OVER);
3!
1186
  }
1187

1188
  if (numOfVnodes > 0) {
22✔
1189
    mInfo("trans:%d, %d vnodes on dnode:%d will be dropped", pTrans->id, numOfVnodes, pDnode->id);
16!
1190
    TAOS_CHECK_GOTO(mndSetMoveVgroupsInfoToTrans(pMnode, pTrans, pDnode->id, force, unsafe), NULL, _OVER);
16✔
1191
  }
1192

1193
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
20!
1194

1195
  (void)mndUpdateIpWhiteForAllUser(pMnode, TSDB_DEFAULT_USER, pDnode->fqdn, IP_WHITE_DROP,
20✔
1196
                                   1);  // TODO: check the return value
1197
  code = 0;
20✔
1198

1199
_OVER:
22✔
1200
  mndTransDrop(pTrans);
22✔
1201
  sdbFreeRaw(pRaw);
22✔
1202
  TAOS_RETURN(code);
22✔
1203
}
1204

1205
static bool mndIsEmptyDnode(SMnode *pMnode, int32_t dnodeId) {
24✔
1206
  bool       isEmpty = false;
24✔
1207
  SMnodeObj *pMObj = NULL;
24✔
1208
  SQnodeObj *pQObj = NULL;
24✔
1209
  SSnodeObj *pSObj = NULL;
24✔
1210

1211
  pQObj = mndAcquireQnode(pMnode, dnodeId);
24✔
1212
  if (pQObj) goto _OVER;
24✔
1213

1214
  pSObj = mndAcquireSnode(pMnode, dnodeId);
20✔
1215
  if (pSObj) goto _OVER;
20!
1216

1217
  pMObj = mndAcquireMnode(pMnode, dnodeId);
20✔
1218
  if (pMObj) goto _OVER;
20✔
1219

1220
  int32_t numOfVnodes = mndGetVnodesNum(pMnode, dnodeId);
18✔
1221
  if (numOfVnodes > 0) goto _OVER;
18✔
1222

1223
  isEmpty = true;
3✔
1224
_OVER:
24✔
1225
  mndReleaseMnode(pMnode, pMObj);
24✔
1226
  mndReleaseQnode(pMnode, pQObj);
24✔
1227
  mndReleaseSnode(pMnode, pSObj);
24✔
1228
  return isEmpty;
24✔
1229
}
1230

1231
static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) {
30✔
1232
  SMnode       *pMnode = pReq->info.node;
30✔
1233
  int32_t       code = -1;
30✔
1234
  SDnodeObj    *pDnode = NULL;
30✔
1235
  SMnodeObj    *pMObj = NULL;
30✔
1236
  SQnodeObj    *pQObj = NULL;
30✔
1237
  SSnodeObj    *pSObj = NULL;
30✔
1238
  SDropDnodeReq dropReq = {0};
30✔
1239

1240
  TAOS_CHECK_GOTO(tDeserializeSDropDnodeReq(pReq->pCont, pReq->contLen, &dropReq), NULL, _OVER);
30!
1241

1242
  mInfo("dnode:%d, start to drop, ep:%s:%d, force:%s, unsafe:%s", dropReq.dnodeId, dropReq.fqdn, dropReq.port,
30!
1243
        dropReq.force ? "true" : "false", dropReq.unsafe ? "true" : "false");
1244
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_MNODE), NULL, _OVER);
30✔
1245

1246
  bool force = dropReq.force;
29✔
1247
  if (dropReq.unsafe) {
29✔
1248
    force = true;
1✔
1249
  }
1250

1251
  pDnode = mndAcquireDnode(pMnode, dropReq.dnodeId);
29✔
1252
  if (pDnode == NULL) {
29✔
1253
    int32_t err = terrno;
1✔
1254
    char    ep[TSDB_EP_LEN + 1] = {0};
1✔
1255
    (void)snprintf(ep, sizeof(ep), dropReq.fqdn, dropReq.port);
1✔
1256
    pDnode = mndAcquireDnodeByEp(pMnode, ep);
1✔
1257
    if (pDnode == NULL) {
1!
1258
      code = err;
1✔
1259
      goto _OVER;
1✔
1260
    }
1261
  }
1262

1263
  pQObj = mndAcquireQnode(pMnode, dropReq.dnodeId);
28✔
1264
  pSObj = mndAcquireSnode(pMnode, dropReq.dnodeId);
28✔
1265
  pMObj = mndAcquireMnode(pMnode, dropReq.dnodeId);
28✔
1266
  if (pMObj != NULL) {
28✔
1267
    if (sdbGetSize(pMnode->pSdb, SDB_MNODE) <= 1) {
9✔
1268
      code = TSDB_CODE_MND_TOO_FEW_MNODES;
2✔
1269
      goto _OVER;
2✔
1270
    }
1271
    if (pMnode->selfDnodeId == dropReq.dnodeId) {
7✔
1272
      code = TSDB_CODE_MND_CANT_DROP_LEADER;
2✔
1273
      goto _OVER;
2✔
1274
    }
1275
  }
1276

1277
  int32_t numOfVnodes = mndGetVnodesNum(pMnode, pDnode->id);
24✔
1278
  bool    isonline = mndIsDnodeOnline(pDnode, taosGetTimestampMs());
24✔
1279

1280
  if (isonline && force) {
24!
1281
    code = TSDB_CODE_DNODE_ONLY_USE_WHEN_OFFLINE;
×
1282
    mError("dnode:%d, failed to drop since %s, vnodes:%d mnode:%d qnode:%d snode:%d", pDnode->id, tstrerror(code),
×
1283
           numOfVnodes, pMObj != NULL, pQObj != NULL, pSObj != NULL);
1284
    goto _OVER;
×
1285
  }
1286

1287
  bool isEmpty = mndIsEmptyDnode(pMnode, pDnode->id);
24✔
1288
  if (!isonline && !force && !isEmpty) {
24!
1289
    code = TSDB_CODE_DNODE_OFFLINE;
2✔
1290
    mError("dnode:%d, failed to drop since %s, vnodes:%d mnode:%d qnode:%d snode:%d", pDnode->id, tstrerror(code),
2!
1291
           numOfVnodes, pMObj != NULL, pQObj != NULL, pSObj != NULL);
1292
    goto _OVER;
2✔
1293
  }
1294

1295
  code = mndDropDnode(pMnode, pReq, pDnode, pMObj, pQObj, pSObj, numOfVnodes, force, dropReq.unsafe);
22✔
1296
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
22✔
1297

1298
  char obj1[30] = {0};
22✔
1299
  (void)tsnprintf(obj1, sizeof(obj1), "%d", dropReq.dnodeId);
22✔
1300

1301
  auditRecord(pReq, pMnode->clusterId, "dropDnode", "", obj1, dropReq.sql, dropReq.sqlLen);
22✔
1302

1303
_OVER:
30✔
1304
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
30!
1305
    mError("dnode:%d, failed to drop since %s", dropReq.dnodeId, tstrerror(code));
10!
1306
  }
1307

1308
  mndReleaseDnode(pMnode, pDnode);
30✔
1309
  mndReleaseMnode(pMnode, pMObj);
30✔
1310
  mndReleaseQnode(pMnode, pQObj);
30✔
1311
  mndReleaseSnode(pMnode, pSObj);
30✔
1312
  tFreeSDropDnodeReq(&dropReq);
30✔
1313
  TAOS_RETURN(code);
30✔
1314
}
1315

1316
static int32_t mndProcessCreateEncryptKeyReqImpl(SRpcMsg *pReq, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
×
1317
  int32_t code = 0;
×
1318
  SMnode *pMnode = pReq->info.node;
×
1319
  SSdb   *pSdb = pMnode->pSdb;
×
1320
  void   *pIter = NULL;
×
1321
  int8_t  encrypting = 0;
×
1322

1323
  const STraceId *trace = &pReq->info.traceId;
×
1324

1325
  int32_t klen = strlen(pDcfgReq->value);
×
1326
  if (klen > ENCRYPT_KEY_LEN || klen < ENCRYPT_KEY_LEN_MIN) {
×
1327
    code = TSDB_CODE_DNODE_INVALID_ENCRYPT_KLEN;
×
1328
    mGError("msg:%p, failed to create encrypt_key since invalid key length:%d, valid range:[%d, %d]", pReq, klen,
×
1329
            ENCRYPT_KEY_LEN_MIN, ENCRYPT_KEY_LEN);
1330
    goto _exit;
×
1331
  }
1332

1333
  if (0 != (encrypting = atomic_val_compare_exchange_8(&pMnode->encryptMgmt.encrypting, 0, 1))) {
×
1334
    code = TSDB_CODE_QRY_DUPLICATED_OPERATION;
×
1335
    mGWarn("msg:%p, failed to create encrypt key since %s, encrypting:%" PRIi8, pReq, tstrerror(code), encrypting);
×
1336
    goto _exit;
×
1337
  }
1338

1339
  if (tsEncryptionKeyStat == ENCRYPT_KEY_STAT_SET || tsEncryptionKeyStat == ENCRYPT_KEY_STAT_LOADED) {
×
1340
    atomic_store_8(&pMnode->encryptMgmt.encrypting, 0);
×
1341
    code = TSDB_CODE_QRY_DUPLICATED_OPERATION;
×
1342
    mGWarn("msg:%p, failed to create encrypt key since %s, stat:%" PRIi8 ", checksum:%u", pReq, tstrerror(code),
×
1343
           tsEncryptionKeyStat, tsEncryptionKeyChksum);
1344
    goto _exit;
×
1345
  }
1346

1347
  atomic_store_16(&pMnode->encryptMgmt.nEncrypt, 0);
×
1348
  atomic_store_16(&pMnode->encryptMgmt.nSuccess, 0);
×
1349
  atomic_store_16(&pMnode->encryptMgmt.nFailed, 0);
×
1350

1351
  while (1) {
×
1352
    SDnodeObj *pDnode = NULL;
×
1353
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
×
1354
    if (pIter == NULL) break;
×
1355
    if (pDnode->offlineReason != DND_REASON_ONLINE) {
×
1356
      mGWarn("msg:%p, don't send create encrypt_key req since dnode:%d in offline state:%s", pReq, pDnode->id,
×
1357
             offlineReason[pDnode->offlineReason]);
1358
      sdbRelease(pSdb, pDnode);
×
1359
      continue;
×
1360
    }
1361

1362
    if (dnodeId == -1 || pDnode->id == dnodeId || dnodeId == 0) {
×
1363
      SEpSet  epSet = mndGetDnodeEpset(pDnode);
×
1364
      int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, pDcfgReq);
×
1365
      void   *pBuf = rpcMallocCont(bufLen);
×
1366

1367
      if (pBuf != NULL) {
×
1368
        if ((bufLen = tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq)) <= 0) {
×
1369
          code = bufLen;
×
1370
          sdbRelease(pSdb, pDnode);
×
1371
          goto _exit;
×
1372
        }
1373
        SRpcMsg rpcMsg = {.msgType = TDMT_DND_CREATE_ENCRYPT_KEY, .pCont = pBuf, .contLen = bufLen};
×
1374
        if (0 == tmsgSendReq(&epSet, &rpcMsg)) {
×
1375
          (void)atomic_add_fetch_16(&pMnode->encryptMgmt.nEncrypt, 1);
×
1376
        }
1377
      }
1378
    }
1379

1380
    sdbRelease(pSdb, pDnode);
×
1381
  }
1382

1383
  if (atomic_load_16(&pMnode->encryptMgmt.nEncrypt) <= 0) {
×
1384
    atomic_store_8(&pMnode->encryptMgmt.encrypting, 0);
×
1385
  }
1386

1387
_exit:
×
1388
  if (code != 0) {
×
1389
    if (terrno == 0) terrno = code;
×
1390
  }
1391
  return code;
×
1392
}
1393

1394
static int32_t mndProcessCreateEncryptKeyReq(SRpcMsg *pReq) {
×
1395
  int32_t code = 0;
×
1396

1397
#ifdef TD_ENTERPRISE
1398
  SMnode       *pMnode = pReq->info.node;
×
1399
  SMCfgDnodeReq cfgReq = {0};
×
1400
  TAOS_CHECK_RETURN(tDeserializeSMCfgDnodeReq(pReq->pCont, pReq->contLen, &cfgReq));
×
1401

1402
  if ((code = mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONFIG_DNODE)) != 0) {
×
1403
    tFreeSMCfgDnodeReq(&cfgReq);
×
1404
    TAOS_RETURN(code);
×
1405
  }
1406
  const STraceId *trace = &pReq->info.traceId;
×
1407
  SDCfgDnodeReq   dcfgReq = {0};
×
1408
  if (strncasecmp(cfgReq.config, "encrypt_key", 12) == 0) {
×
1409
    tstrncpy(dcfgReq.config, cfgReq.config, sizeof(dcfgReq.config));
×
1410
    tstrncpy(dcfgReq.value, cfgReq.value, sizeof(dcfgReq.value));
×
1411
    tFreeSMCfgDnodeReq(&cfgReq);
×
1412
    return mndProcessCreateEncryptKeyReqImpl(pReq, cfgReq.dnodeId, &dcfgReq);
×
1413
  } else {
1414
    code = TSDB_CODE_PAR_INTERNAL_ERROR;
×
1415
    tFreeSMCfgDnodeReq(&cfgReq);
×
1416
    TAOS_RETURN(code);
×
1417
  }
1418

1419
#else
1420
  TAOS_RETURN(code);
1421
#endif
1422
}
1423

1424
static int32_t mndProcessCreateEncryptKeyRsp(SRpcMsg *pRsp) {
×
1425
  SMnode *pMnode = pRsp->info.node;
×
1426
  int16_t nSuccess = 0;
×
1427
  int16_t nFailed = 0;
×
1428

1429
  if (0 == pRsp->code) {
×
1430
    nSuccess = atomic_add_fetch_16(&pMnode->encryptMgmt.nSuccess, 1);
×
1431
  } else {
1432
    nFailed = atomic_add_fetch_16(&pMnode->encryptMgmt.nFailed, 1);
×
1433
  }
1434

1435
  int16_t nReq = atomic_load_16(&pMnode->encryptMgmt.nEncrypt);
×
1436
  bool    finished = nSuccess + nFailed >= nReq;
×
1437

1438
  if (finished) {
×
1439
    atomic_store_8(&pMnode->encryptMgmt.encrypting, 0);
×
1440
  }
1441

1442
  const STraceId *trace = &pRsp->info.traceId;
×
1443
  mGInfo("msg:%p, create encrypt key rsp, nReq:%" PRIi16 ", nSucess:%" PRIi16 ", nFailed:%" PRIi16 ", %s", pRsp, nReq,
×
1444
         nSuccess, nFailed, finished ? "encrypt done" : "in encrypting");
1445

1446
  return 0;
×
1447
}
1448

1449
static int32_t mndRetrieveConfigs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
7✔
1450
  SMnode *pMnode = pReq->info.node;
7✔
1451
  int32_t totalRows = 0;
7✔
1452
  int32_t numOfRows = 0;
7✔
1453
  char   *cfgOpts[TSDB_CONFIG_NUMBER] = {0};
7✔
1454
  char    cfgVals[TSDB_CONFIG_NUMBER][TSDB_CONFIG_VALUE_LEN + 1] = {0};
7✔
1455
  char   *pWrite = NULL;
7✔
1456
  int32_t cols = 0;
7✔
1457
  int32_t code = 0;
7✔
1458
  int32_t lino = 0;
7✔
1459

1460
  cfgOpts[totalRows] = "statusInterval";
7✔
1461
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%d", tsStatusInterval);
7✔
1462
  totalRows++;
7✔
1463

1464
  cfgOpts[totalRows] = "timezone";
7✔
1465
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", tsTimezoneStr);
7✔
1466
  totalRows++;
7✔
1467

1468
  cfgOpts[totalRows] = "locale";
7✔
1469
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", tsLocale);
7✔
1470
  totalRows++;
7✔
1471

1472
  cfgOpts[totalRows] = "charset";
7✔
1473
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", tsCharset);
7✔
1474
  totalRows++;
7✔
1475

1476
  cfgOpts[totalRows] = "monitor";
7✔
1477
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%d", tsEnableMonitor);
7✔
1478
  totalRows++;
7✔
1479

1480
  cfgOpts[totalRows] = "monitorInterval";
7✔
1481
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%d", tsMonitorInterval);
7✔
1482
  totalRows++;
7✔
1483

1484
  cfgOpts[totalRows] = "slowLogThreshold";
7✔
1485
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%d", tsSlowLogThreshold);
7✔
1486
  totalRows++;
7✔
1487

1488
  cfgOpts[totalRows] = "slowLogMaxLen";
7✔
1489
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%d", tsSlowLogMaxLen);
7✔
1490
  totalRows++;
7✔
1491

1492
  char scopeStr[64] = {0};
7✔
1493
  getSlowLogScopeString(tsSlowLogScope, scopeStr);
7✔
1494
  cfgOpts[totalRows] = "slowLogScope";
7✔
1495
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", scopeStr);
7✔
1496
  totalRows++;
7✔
1497

1498
  char buf[TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE] = {0};
7✔
1499
  char bufVal[TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE] = {0};
7✔
1500

1501
  for (int32_t i = 0; i < totalRows; i++) {
70✔
1502
    cols = 0;
63✔
1503

1504
    STR_WITH_MAXSIZE_TO_VARSTR(buf, cfgOpts[i], TSDB_CONFIG_OPTION_LEN);
63✔
1505
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
63✔
1506
    TAOS_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)buf, false), &lino, _OVER);
63!
1507

1508
    STR_WITH_MAXSIZE_TO_VARSTR(bufVal, cfgVals[i], TSDB_CONFIG_VALUE_LEN);
63✔
1509
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
63✔
1510
    TAOS_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)bufVal, false), &lino, _OVER);
63!
1511

1512
    numOfRows++;
63✔
1513
  }
1514

1515
_OVER:
7✔
1516
  if (code != 0) mError("failed to retrieve configs at line:%d since %s", lino, tstrerror(code));
7!
1517
  pShow->numOfRows += numOfRows;
7✔
1518
  return numOfRows;
7✔
1519
}
1520

1521
static void mndCancelGetNextConfig(SMnode *pMnode, void *pIter) {}
×
1522

1523
static int32_t mndRetrieveDnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
676✔
1524
  SMnode    *pMnode = pReq->info.node;
676✔
1525
  SSdb      *pSdb = pMnode->pSdb;
676✔
1526
  int32_t    numOfRows = 0;
676✔
1527
  int32_t    cols = 0;
676✔
1528
  ESdbStatus objStatus = 0;
676✔
1529
  SDnodeObj *pDnode = NULL;
676✔
1530
  int64_t    curMs = taosGetTimestampMs();
676✔
1531
  char       buf[TSDB_EP_LEN + VARSTR_HEADER_SIZE];
1532
  int32_t    code = 0;
676✔
1533
  int32_t    lino = 0;
676✔
1534

1535
  while (numOfRows < rows) {
3,114!
1536
    pShow->pIter = sdbFetchAll(pSdb, SDB_DNODE, pShow->pIter, (void **)&pDnode, &objStatus, true);
3,114✔
1537
    if (pShow->pIter == NULL) break;
3,114✔
1538
    bool online = mndIsDnodeOnline(pDnode, curMs);
2,438✔
1539

1540
    cols = 0;
2,438✔
1541

1542
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,438✔
1543
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->id, false), pDnode, &lino, _OVER);
2,438!
1544

1545
    STR_WITH_MAXSIZE_TO_VARSTR(buf, pDnode->ep, pShow->pMeta->pSchemas[cols].bytes);
2,438✔
1546

1547
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,438✔
1548
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, buf, false), pDnode, &lino, _OVER);
2,438!
1549

1550
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,438✔
1551
    int16_t id = mndGetVnodesNum(pMnode, pDnode->id);
2,438✔
1552
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&id, false), pDnode, &lino, _OVER);
2,438!
1553

1554
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,438✔
1555
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->numOfSupportVnodes, false), pDnode,
2,438!
1556
                        &lino, _OVER);
1557

1558
    const char *status = "ready";
2,438✔
1559
    if (objStatus == SDB_STATUS_CREATING) status = "creating";
2,438!
1560
    if (objStatus == SDB_STATUS_DROPPING) status = "dropping";
2,438!
1561
    if (!online) {
2,438✔
1562
      if (objStatus == SDB_STATUS_CREATING)
392!
1563
        status = "creating*";
×
1564
      else if (objStatus == SDB_STATUS_DROPPING)
392!
1565
        status = "dropping*";
×
1566
      else
1567
        status = "offline";
392✔
1568
    }
1569

1570
    STR_TO_VARSTR(buf, status);
2,438✔
1571
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,438✔
1572
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, buf, false), pDnode, &lino, _OVER);
2,438!
1573

1574
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,438✔
1575
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->createdTime, false), pDnode, &lino,
2,438!
1576
                        _OVER);
1577

1578
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,438✔
1579
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->rebootTime, false), pDnode, &lino,
2,438!
1580
                        _OVER);
1581

1582
    char *b = taosMemoryCalloc(VARSTR_HEADER_SIZE + strlen(offlineReason[pDnode->offlineReason]) + 1, 1);
2,438!
1583
    STR_TO_VARSTR(b, online ? "" : offlineReason[pDnode->offlineReason]);
2,438✔
1584

1585
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,438✔
1586
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, b, false), pDnode, &lino, _OVER);
2,438!
1587
    taosMemoryFreeClear(b);
2,438!
1588

1589
#ifdef TD_ENTERPRISE
1590
    STR_TO_VARSTR(buf, pDnode->machineId);
2,438✔
1591
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,438✔
1592
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, buf, false), pDnode, &lino, _OVER);
2,438!
1593
#endif
1594

1595
    numOfRows++;
2,438✔
1596
    sdbRelease(pSdb, pDnode);
2,438✔
1597
  }
1598

UNCOV
1599
_OVER:
×
1600
  if (code != 0) mError("failed to retrieve dnodes at line:%d since %s", lino, tstrerror(code));
676!
1601

1602
  pShow->numOfRows += numOfRows;
676✔
1603
  return numOfRows;
676✔
1604
}
1605

1606
static void mndCancelGetNextDnode(SMnode *pMnode, void *pIter) {
×
1607
  SSdb *pSdb = pMnode->pSdb;
×
1608
  sdbCancelFetchByType(pSdb, pIter, SDB_DNODE);
×
1609
}
×
1610

1611
SArray *mndGetAllDnodeFqdns(SMnode *pMnode) {
1,866✔
1612
  SDnodeObj *pObj = NULL;
1,866✔
1613
  void      *pIter = NULL;
1,866✔
1614
  SSdb      *pSdb = pMnode->pSdb;
1,866✔
1615
  SArray    *fqdns = taosArrayInit(4, sizeof(void *));
1,866✔
1616
  while (1) {
1,564✔
1617
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pObj);
3,430✔
1618
    if (pIter == NULL) break;
3,430✔
1619

1620
    char *fqdn = taosStrdup(pObj->fqdn);
1,564!
1621
    if (taosArrayPush(fqdns, &fqdn) == NULL) {
1,564!
1622
      mError("failed to fqdn into array, but continue at this time");
×
1623
    }
1624
    sdbRelease(pSdb, pObj);
1,564✔
1625
  }
1626
  return fqdns;
1,866✔
1627
}
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