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

taosdata / TDengine / #3664

20 Mar 2025 09:19AM UTC coverage: 35.63%. First build
#3664

push

travis-ci

web-flow
Merge 8112ba125 into 9b7434d0a

72910 of 278358 branches covered (26.19%)

Branch coverage included in aggregate %.

195 of 257 new or added lines in 17 files covered. (75.88%)

125571 of 278710 relevant lines covered (45.05%)

1012723.65 hits per line

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

41.53
/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 "mndDnode.h"
18
#include <stdio.h>
19
#include "audit.h"
20
#include "mndCluster.h"
21
#include "mndDb.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 "mndXnode.h"
31
#include "taos_monitor.h"
32
#include "tconfig.h"
33
#include "tjson.h"
34
#include "tmisce.h"
35
#include "tunit.h"
36

37
#define TSDB_DNODE_VER_NUMBER   2
38
#define TSDB_DNODE_RESERVE_SIZE 40
39

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

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

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

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

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

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

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

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

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

18✔
128
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_CONFIGS, mndRetrieveConfigs);
18✔
129
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_CONFIGS, mndCancelGetNextConfig);
18✔
130
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_DNODE, mndRetrieveDnodes);
18✔
131
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_DNODE, mndCancelGetNextDnode);
132

18✔
133
  return sdbSetTable(pMnode->pSdb, table);
134
}
135

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

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

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

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

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

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

17✔
189
_OVER:
17✔
190
  mndTransDrop(pTrans);
17✔
191
  sdbFreeRaw(pRaw);
17✔
192
  return code;
193
}
194

73✔
195
static SSdbRaw *mndDnodeActionEncode(SDnodeObj *pDnode) {
73✔
196
  int32_t code = 0;
73✔
197
  int32_t lino = 0;
73✔
198
  terrno = TSDB_CODE_OUT_OF_MEMORY;
199

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

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

73✔
215
  terrno = 0;
216

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

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

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

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

40✔
242
  pRow = sdbAllocRow(sizeof(SDnodeObj));
40!
243
  if (pRow == NULL) goto _OVER;
244

40✔
245
  pDnode = sdbGetRowObj(pRow);
40!
246
  if (pDnode == NULL) goto _OVER;
247

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

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

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

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

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

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

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

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

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

2,108✔
320
  return pDnode;
321
}
322

2,140✔
323
void mndReleaseDnode(SMnode *pMnode, SDnodeObj *pDnode) {
2,140✔
324
  SSdb *pSdb = pMnode->pSdb;
2,140✔
325
  sdbRelease(pSdb, pDnode);
2,140✔
326
}
327

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

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

×
339
  epSet = mndGetDnodeEpset(pDnode);
340

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

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

32✔
348
  void *pIter = NULL;
21✔
349
  while (1) {
53✔
350
    SDnodeObj *pDnode = NULL;
53✔
351
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
53✔
352
    if (pIter == NULL) break;
353

44✔
354
    if (taosStrncasecmp(pEpStr, pDnode->ep, TSDB_EP_LEN) == 0) {
23✔
355
      sdbCancelFetch(pSdb, pIter);
23✔
356
      return pDnode;
357
    }
358

21✔
359
    sdbRelease(pSdb, pDnode);
360
  }
361

9✔
362
  terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
9✔
363
  return NULL;
364
}
365

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

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

×
376
    if (taosStrncasecmp(pEpStr, pDnode->ep, TSDB_EP_LEN) == 0) {
×
377
      sdbCancelFetch(pSdb, pIter);
×
378
      return pDnode;
379
    }
380

×
381
    sdbRelease(pSdb, pDnode);
382
  }
383

×
384
  return NULL;
385
}
386

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

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

1,981✔
397
bool mndIsDnodeOnline(SDnodeObj *pDnode, int64_t curMs) {
1,981✔
398
  int64_t interval = TABS(pDnode->lastAccessTime - curMs);
1,981✔
399
  if (interval > 5000 * (int64_t)tsStatusInterval) {
31✔
400
    if (pDnode->rebootTime > 0 && pDnode->offlineReason == DND_REASON_ONLINE) {
1✔
401
      pDnode->offlineReason = DND_REASON_STATUS_MSG_TIMEOUT;
402
    }
31✔
403
    return false;
404
  }
1,950✔
405
  return true;
406
}
407

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

46✔
411
  int32_t numOfEps = 0;
46✔
412
  void   *pIter = NULL;
97✔
413
  while (1) {
143✔
414
    SDnodeObj *pDnode = NULL;
143✔
415
    ESdbStatus objStatus = 0;
143✔
416
    pIter = sdbFetchAll(pSdb, SDB_DNODE, pIter, (void **)&pDnode, &objStatus, true);
143✔
417
    if (pIter == NULL) break;
418

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

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

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

445✔
439
  int32_t numOfEps = 0;
445✔
440
  void   *pIter = NULL;
1,696✔
441
  while (1) {
2,141✔
442
    SDnodeObj *pDnode = NULL;
2,141✔
443
    ESdbStatus objStatus = 0;
2,141✔
444
    pIter = sdbFetchAll(pSdb, SDB_DNODE, pIter, (void **)&pDnode, &objStatus, true);
2,141✔
445
    if (pIter == NULL) break;
446

447
    SDnodeInfo dInfo;
1,696✔
448
    dInfo.id = pDnode->id;
1,696✔
449
    dInfo.ep.port = pDnode->port;
1,696✔
450
    dInfo.offlineReason = pDnode->offlineReason;
1,696✔
451
    tstrncpy(dInfo.ep.fqdn, pDnode->fqdn, TSDB_FQDN_LEN);
1,696✔
452
    sdbRelease(pSdb, pDnode);
1,696✔
453
    if (mndIsMnode(pMnode, pDnode->id)) {
445✔
454
      dInfo.isMnode = 1;
455
    } else {
1,251✔
456
      dInfo.isMnode = 0;
457
    }
458

1,696!
459
    if (taosArrayPush(pDnodeInfo, &dInfo) == NULL) {
×
460
      code = terrno;
×
461
      sdbCancelFetch(pSdb, pIter);
×
462
      break;
463
    }
464
  }
445✔
465
  TAOS_RETURN(code);
466
}
467

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

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

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

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

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

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

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

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

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

46✔
536
  return DND_REASON_ONLINE;
537
}
538

1✔
539
double calcAppliedRate(int64_t currentCount, int64_t lastCount, int64_t currentTimeMs, int64_t lastTimeMs) {
1!
540
  if ((currentTimeMs <= lastTimeMs) || (currentCount <= lastCount)) {
×
541
    return 0.0;
542
  }
543

1✔
544
  int64_t deltaCount = currentCount - lastCount;
1✔
545
  int64_t deltaMs = currentTimeMs - lastTimeMs;
1✔
546
  double  rate = (double)deltaCount / (double)deltaMs;
1✔
547
  return rate;
548
}
549

1,500✔
550
static bool mndUpdateVnodeState(int32_t vgId, SVnodeGid *pGid, SVnodeLoad *pVload) {
1,500✔
551
  bool stateChanged = false;
4,498✔
552
  bool roleChanged = pGid->syncState != pVload->syncState ||
2,967!
553
                     (pVload->syncTerm != -1 && pGid->syncTerm != pVload->syncTerm) ||
1,467!
554
                     pGid->roleTimeMs != pVload->roleTimeMs;
555

1,500✔
556
  if (pVload->syncCommitIndex > pVload->syncAppliedIndex) {
3✔
557
    if (pGid->lastSyncAppliedIndexUpdateTime == 0) {
2✔
558
      pGid->lastSyncAppliedIndexUpdateTime = taosGetTimestampMs();
1!
559
    } else if (pGid->syncAppliedIndex != pVload->syncAppliedIndex) {
1✔
560
      int64_t currentTimeMs = taosGetTimestampMs();
1✔
561
      pGid->appliedRate = calcAppliedRate(pVload->syncAppliedIndex, pGid->syncAppliedIndex, currentTimeMs,
562
                                          pGid->lastSyncAppliedIndexUpdateTime);
563

1✔
564
      pGid->lastSyncAppliedIndexUpdateTime = currentTimeMs;
565
    }
566
  }
567

1,500✔
568
  pGid->syncAppliedIndex = pVload->syncAppliedIndex;
1,500✔
569
  pGid->syncCommitIndex = pVload->syncCommitIndex;
1,500!
570
  if (roleChanged || pGid->syncRestore != pVload->syncRestore || pGid->syncCanRead != pVload->syncCanRead ||
1,466!
571
      pGid->startTimeMs != pVload->startTimeMs) {
34!
572
    mInfo(
573
        "vgId:%d, state changed by status msg, old state:%s restored:%d canRead:%d new state:%s restored:%d "
574
        "canRead:%d, dnode:%d",
575
        vgId, syncStr(pGid->syncState), pGid->syncRestore, pGid->syncCanRead, syncStr(pVload->syncState),
576
        pVload->syncRestore, pVload->syncCanRead, pGid->dnodeId);
34✔
577
    pGid->syncState = pVload->syncState;
34✔
578
    pGid->syncTerm = pVload->syncTerm;
34✔
579
    pGid->syncRestore = pVload->syncRestore;
34✔
580
    pGid->syncCanRead = pVload->syncCanRead;
34✔
581
    pGid->startTimeMs = pVload->startTimeMs;
34✔
582
    pGid->roleTimeMs = pVload->roleTimeMs;
34✔
583
    stateChanged = true;
584
  }
1,500✔
585
  return stateChanged;
586
}
587

517✔
588
static bool mndUpdateMnodeState(SMnodeObj *pObj, SMnodeLoad *pMload) {
517✔
589
  bool stateChanged = false;
1,536✔
590
  bool roleChanged = pObj->syncState != pMload->syncState ||
1,019!
591
                     (pMload->syncTerm != -1 && pObj->syncTerm != pMload->syncTerm) ||
502!
592
                     pObj->roleTimeMs != pMload->roleTimeMs;
517!
593
  if (roleChanged || pObj->syncRestore != pMload->syncRestore) {
15!
594
    mInfo("dnode:%d, mnode syncState from %s to %s, restoreState from %d to %d, syncTerm from %" PRId64 " to %" PRId64,
595
          pObj->id, syncStr(pObj->syncState), syncStr(pMload->syncState), pObj->syncRestore, pMload->syncRestore,
596
          pObj->syncTerm, pMload->syncTerm);
15✔
597
    pObj->syncState = pMload->syncState;
15✔
598
    pObj->syncTerm = pMload->syncTerm;
15✔
599
    pObj->syncRestore = pMload->syncRestore;
15✔
600
    pObj->roleTimeMs = pMload->roleTimeMs;
15✔
601
    stateChanged = true;
602
  }
517✔
603
  return stateChanged;
604
}
605

606
extern char   *tsMonFwUri;
607
extern char   *tsMonSlowLogUri;
×
608
static int32_t mndProcessStatisReq(SRpcMsg *pReq) {
×
609
  SMnode    *pMnode = pReq->info.node;
×
610
  SStatisReq statisReq = {0};
×
611
  int32_t    code = -1;
612

×
613
  TAOS_CHECK_RETURN(tDeserializeSStatisReq(pReq->pCont, pReq->contLen, &statisReq));
614

×
615
  if (tsMonitorLogProtocol) {
×
616
    mInfo("process statis req,\n %s", statisReq.pCont);
617
  }
618

×
619
  if (statisReq.type == MONITOR_TYPE_COUNTER) {
×
620
    monSendContent(statisReq.pCont, tsMonFwUri);
×
621
  } else if (statisReq.type == MONITOR_TYPE_SLOW_LOG) {
×
622
    monSendContent(statisReq.pCont, tsMonSlowLogUri);
623
  }
624

×
625
  tFreeSStatisReq(&statisReq);
×
626
  return 0;
627
}
628

×
629
static int32_t mndProcessAuditReq(SRpcMsg *pReq) {
×
630
  mTrace("process audit req:%p", pReq);
×
631
  if (tsEnableAudit && tsEnableAuditDelete) {
×
632
    SMnode   *pMnode = pReq->info.node;
×
633
    SAuditReq auditReq = {0};
634

×
635
    TAOS_CHECK_RETURN(tDeserializeSAuditReq(pReq->pCont, pReq->contLen, &auditReq));
636

×
637
    mDebug("received audit req:%s, %s, %s, %s", auditReq.operation, auditReq.db, auditReq.table, auditReq.pSql);
638

×
639
    auditAddRecord(pReq, pMnode->clusterId, auditReq.operation, auditReq.db, auditReq.table, auditReq.pSql,
640
                   auditReq.sqlLen);
641

×
642
    tFreeSAuditReq(&auditReq);
643
  }
×
644
  return 0;
645
}
646

19✔
647
static int32_t mndUpdateDnodeObj(SMnode *pMnode, SDnodeObj *pDnode) {
19✔
648
  int32_t       code = 0, lino = 0;
19✔
649
  SDnodeInfoReq infoReq = {0};
19✔
650
  int32_t       contLen = 0;
19✔
651
  void         *pReq = NULL;
652

19✔
653
  infoReq.dnodeId = pDnode->id;
19✔
654
  tstrncpy(infoReq.machineId, pDnode->machineId, TSDB_MACHINE_ID_LEN + 1);
655

19!
656
  if ((contLen = tSerializeSDnodeInfoReq(NULL, 0, &infoReq)) <= 0) {
×
657
    TAOS_RETURN(contLen ? contLen : TSDB_CODE_OUT_OF_MEMORY);
658
  }
19✔
659
  pReq = rpcMallocCont(contLen);
19!
660
  if (pReq == NULL) {
×
661
    TAOS_RETURN(terrno);
662
  }
663

19!
664
  if ((contLen = tSerializeSDnodeInfoReq(pReq, contLen, &infoReq)) <= 0) {
×
665
    code = contLen;
×
666
    goto _exit;
667
  }
668

19✔
669
  SRpcMsg rpcMsg = {.msgType = TDMT_MND_UPDATE_DNODE_INFO, .pCont = pReq, .contLen = contLen};
19!
670
  TAOS_CHECK_EXIT(tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg));
19✔
671
_exit:
19!
672
  if (code < 0) {
×
673
    mError("dnode:%d, failed to update dnode info since %s", pDnode->id, tstrerror(code));
674
  }
19✔
675
  TAOS_RETURN(code);
676
}
677

19✔
678
static int32_t mndProcessUpdateDnodeInfoReq(SRpcMsg *pReq) {
19✔
679
  int32_t       code = 0, lino = 0;
19✔
680
  SMnode       *pMnode = pReq->info.node;
19✔
681
  SDnodeInfoReq infoReq = {0};
19✔
682
  SDnodeObj    *pDnode = NULL;
19✔
683
  STrans       *pTrans = NULL;
19✔
684
  SSdbRaw      *pCommitRaw = NULL;
685

19!
686
  TAOS_CHECK_EXIT(tDeserializeSDnodeInfoReq(pReq->pCont, pReq->contLen, &infoReq));
687

19✔
688
  pDnode = mndAcquireDnode(pMnode, infoReq.dnodeId);
19!
689
  if (pDnode == NULL) {
×
690
    TAOS_CHECK_EXIT(terrno);
691
  }
692

19✔
693
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, NULL, "update-dnode-obj");
19!
694
  if (pTrans == NULL) {
×
695
    TAOS_CHECK_EXIT(terrno);
696
  }
697

19✔
698
  pDnode->updateTime = taosGetTimestampMs();
699

19!
700
  if ((pCommitRaw = mndDnodeActionEncode(pDnode)) == NULL) {
×
701
    TAOS_CHECK_EXIT(terrno);
702
  }
19!
703
  if ((code = mndTransAppendCommitlog(pTrans, pCommitRaw)) != 0) {
×
704
    mError("trans:%d, failed to append commit log since %s", pTrans->id, tstrerror(code));
×
705
    TAOS_CHECK_EXIT(code);
706
  }
19!
707
  TAOS_CHECK_EXIT(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
19✔
708
  pCommitRaw = NULL;
709

19!
710
  if ((code = mndTransPrepare(pMnode, pTrans)) != 0) {
×
711
    mError("trans:%d, failed to prepare since %s", pTrans->id, tstrerror(code));
×
712
    TAOS_CHECK_EXIT(code);
713
  }
714

19✔
715
_exit:
19✔
716
  mndReleaseDnode(pMnode, pDnode);
19!
717
  if (code != 0) {
×
718
    mError("dnode:%d, failed to update dnode info at line %d since %s", infoReq.dnodeId, lino, tstrerror(code));
719
  }
19✔
720
  mndTransDrop(pTrans);
19✔
721
  sdbFreeRaw(pCommitRaw);
19✔
722
  TAOS_RETURN(code);
723
}
724

830✔
725
static int32_t mndProcessStatusReq(SRpcMsg *pReq) {
830✔
726
  SMnode    *pMnode = pReq->info.node;
830✔
727
  SStatusReq statusReq = {0};
830✔
728
  SDnodeObj *pDnode = NULL;
830✔
729
  int32_t    code = -1;
730

830!
731
  TAOS_CHECK_GOTO(tDeserializeSStatusReq(pReq->pCont, pReq->contLen, &statusReq), NULL, _OVER);
732

830✔
733
  int64_t clusterid = mndGetClusterId(pMnode);
830!
734
  if (statusReq.clusterId != 0 && statusReq.clusterId != clusterid) {
×
735
    code = TSDB_CODE_MND_DNODE_DIFF_CLUSTER;
×
736
    mWarn("dnode:%d, %s, its clusterid:%" PRId64 " differ from current clusterid:%" PRId64 ", code:0x%x",
737
          statusReq.dnodeId, statusReq.dnodeEp, statusReq.clusterId, clusterid, code);
×
738
    goto _OVER;
739
  }
740

830✔
741
  if (statusReq.dnodeId == 0) {
29✔
742
    pDnode = mndAcquireDnodeByEp(pMnode, statusReq.dnodeEp);
29✔
743
    if (pDnode == NULL) {
6!
744
      mInfo("dnode:%s, not created yet", statusReq.dnodeEp);
6✔
745
      code = TSDB_CODE_MND_RETURN_VALUE_NULL;
6!
746
      if (terrno != 0) code = terrno;
6✔
747
      goto _OVER;
748
    }
749
  } else {
801✔
750
    pDnode = mndAcquireDnode(pMnode, statusReq.dnodeId);
801!
751
    if (pDnode == NULL) {
×
752
      int32_t err = terrno;
×
753
      pDnode = mndAcquireDnodeByEp(pMnode, statusReq.dnodeEp);
×
754
      if (pDnode != NULL) {
×
755
        pDnode->offlineReason = DND_REASON_DNODE_ID_NOT_MATCH;
×
756
        terrno = err;
×
757
        goto _OVER;
758
      }
759

×
760
      mError("dnode:%d, %s not exist, code:0x%x", statusReq.dnodeId, statusReq.dnodeEp, err);
×
761
      if (err == TSDB_CODE_MND_DNODE_NOT_EXIST) {
×
762
        terrno = err;
×
763
        goto _OVER;
764
      } else {
×
765
        pDnode = mndAcquireDnodeAllStatusByEp(pMnode, statusReq.dnodeEp);
×
766
        if (pDnode == NULL) goto _OVER;
767
      }
768
    }
769
  }
770

824✔
771
  pMnode->ipWhiteVer = mndGetIpWhiteVer(pMnode);
772

824✔
773
  int64_t analVer = sdbGetTableVer(pMnode->pSdb, SDB_ANODE);
824✔
774
  int64_t dnodeVer = sdbGetTableVer(pMnode->pSdb, SDB_DNODE) + sdbGetTableVer(pMnode->pSdb, SDB_MNODE);
824✔
775
  int64_t curMs = taosGetTimestampMs();
824✔
776
  bool    online = mndIsDnodeOnline(pDnode, curMs);
824✔
777
  bool    dnodeChanged = (statusReq.dnodeVer == 0) || (statusReq.dnodeVer != dnodeVer);
824✔
778
  bool    reboot = (pDnode->rebootTime != statusReq.rebootTime);
824✔
779
  bool    supportVnodesChanged = pDnode->numOfSupportVnodes != statusReq.numOfSupportVnodes;
824✔
780
  bool    encryptKeyChanged = pDnode->encryptionKeyChksum != statusReq.clusterCfg.encryptionKeyChksum;
824✔
781
  bool    enableWhiteListChanged = statusReq.clusterCfg.enableWhiteList != (tsEnableWhiteList ? 1 : 0);
824✔
782
  bool    analVerChanged = (analVer != statusReq.analVer);
803!
783
  bool    needCheck = !online || dnodeChanged || reboot || supportVnodesChanged || analVerChanged ||
1,627!
784
                   pMnode->ipWhiteVer != statusReq.ipWhiteVer || encryptKeyChanged || enableWhiteListChanged;
824✔
785
  const STraceId *trace = &pReq->info.traceId;
824✔
786
  char            timestamp[TD_TIME_STR_LEN] = {0};
824✔
787
  if (mDebugFlag & DEBUG_TRACE) (void)formatTimestampLocal(timestamp, statusReq.timestamp, TSDB_TIME_PRECISION_MILLI);
824!
788
  mGTrace(
789
      "dnode:%d, status received, accessTimes:%d check:%d online:%d reboot:%d changed:%d statusSeq:%d "
790
      "timestamp:%s",
791
      pDnode->id, pDnode->accessTimes, needCheck, online, reboot, dnodeChanged, statusReq.statusSeq, timestamp);
792

824✔
793
  if (reboot) {
20✔
794
    tsGrantHBInterval = GRANT_HEART_BEAT_MIN;
795
  }
796

2,324✔
797
  for (int32_t v = 0; v < taosArrayGetSize(statusReq.pVloads); ++v) {
1,500✔
798
    SVnodeLoad *pVload = taosArrayGet(statusReq.pVloads, v);
799

1,500✔
800
    SVgObj *pVgroup = mndAcquireVgroup(pMnode, pVload->vgId);
1,500!
801
    if (pVgroup != NULL) {
1,500!
802
      if (pVload->syncState == TAOS_SYNC_STATE_LEADER || pVload->syncState == TAOS_SYNC_STATE_ASSIGNED_LEADER) {
1,499✔
803
        pVgroup->cacheUsage = pVload->cacheUsage;
1,499✔
804
        pVgroup->numOfCachedTables = pVload->numOfCachedTables;
1,499✔
805
        pVgroup->numOfTables = pVload->numOfTables;
1,499✔
806
        pVgroup->numOfTimeSeries = pVload->numOfTimeSeries;
1,499✔
807
        pVgroup->totalStorage = pVload->totalStorage;
1,499✔
808
        pVgroup->compStorage = pVload->compStorage;
1,499✔
809
        pVgroup->pointsWritten = pVload->pointsWritten;
810
      }
1,500✔
811
      bool stateChanged = false;
1,500!
812
      for (int32_t vg = 0; vg < pVgroup->replica; ++vg) {
1,500✔
813
        SVnodeGid *pGid = &pVgroup->vnodeGid[vg];
1,500!
814
        if (pGid->dnodeId == statusReq.dnodeId) {
1,500!
815
          if (pVload->startTimeMs == 0) {
×
816
            pVload->startTimeMs = statusReq.rebootTime;
817
          }
1,500!
818
          if (pVload->roleTimeMs == 0) {
×
819
            pVload->roleTimeMs = statusReq.rebootTime;
820
          }
1,500✔
821
          stateChanged = mndUpdateVnodeState(pVgroup->vgId, pGid, pVload);
1,500✔
822
          break;
823
        }
824
      }
1,500✔
825
      if (stateChanged) {
34✔
826
        SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName);
34✔
827
        if (pDb != NULL && pDb->stateTs != curMs) {
17!
828
          mInfo("db:%s, stateTs changed by status msg, old stateTs:%" PRId64 " new stateTs:%" PRId64, pDb->name,
829
                pDb->stateTs, curMs);
17✔
830
          pDb->stateTs = curMs;
831
        }
34✔
832
        mndReleaseDb(pMnode, pDb);
833
      }
834
    }
835

1,500✔
836
    mndReleaseVgroup(pMnode, pVgroup);
837
  }
838

824✔
839
  SMnodeObj *pObj = mndAcquireMnode(pMnode, pDnode->id);
824✔
840
  if (pObj != NULL) {
517✔
841
    if (statusReq.mload.roleTimeMs == 0) {
8✔
842
      statusReq.mload.roleTimeMs = statusReq.rebootTime;
843
    }
517✔
844
    (void)mndUpdateMnodeState(pObj, &statusReq.mload);
517✔
845
    mndReleaseMnode(pMnode, pObj);
846
  }
847

824✔
848
  SQnodeObj *pQnode = mndAcquireQnode(pMnode, statusReq.qload.dnodeId);
824!
849
  if (pQnode != NULL) {
×
850
    pQnode->load = statusReq.qload;
×
851
    mndReleaseQnode(pMnode, pQnode);
852
  }
853

824✔
854
  if (needCheck) {
46!
855
    if (statusReq.sver != tsVersion) {
×
856
      if (pDnode != NULL) {
×
857
        pDnode->offlineReason = DND_REASON_VERSION_NOT_MATCH;
858
      }
×
859
      mError("dnode:%d, status msg version:%d not match cluster:%d", statusReq.dnodeId, statusReq.sver, tsVersion);
×
860
      terrno = TSDB_CODE_VERSION_NOT_COMPATIBLE;
×
861
      goto _OVER;
862
    }
863

46✔
864
    if (statusReq.dnodeId == 0) {
23!
865
      mInfo("dnode:%d, %s first access, clusterId:%" PRId64, pDnode->id, pDnode->ep, pMnode->clusterId);
866
    } else {
23!
867
      if (statusReq.clusterId != pMnode->clusterId) {
×
868
        if (pDnode != NULL) {
×
869
          pDnode->offlineReason = DND_REASON_CLUSTER_ID_NOT_MATCH;
870
        }
×
871
        mError("dnode:%d, clusterId %" PRId64 " not match exist %" PRId64, pDnode->id, statusReq.clusterId,
872
               pMnode->clusterId);
×
873
        terrno = TSDB_CODE_MND_INVALID_CLUSTER_ID;
×
874
        goto _OVER;
875
      }
876
    }
877

878
    // Verify whether the cluster parameters are consistent when status change from offline to ready
46✔
879
    pDnode->offlineReason = mndCheckClusterCfgPara(pMnode, pDnode, &statusReq.clusterCfg);
46!
880
    if (pDnode->offlineReason != 0) {
×
881
      mError("dnode:%d, cluster cfg inconsistent since:%s", pDnode->id, offlineReason[pDnode->offlineReason]);
×
882
      if (terrno == 0) terrno = TSDB_CODE_MND_INVALID_CLUSTER_CFG;
×
883
      goto _OVER;
884
    }
885

46✔
886
    if (!online) {
21!
887
      mInfo("dnode:%d, from offline to online, memory avail:%" PRId64 " total:%" PRId64 " cores:%.2f", pDnode->id,
888
            statusReq.memAvail, statusReq.memTotal, statusReq.numOfCores);
889
    } else {
25!
890
      mInfo("dnode:%d, send dnode epset, online:%d dnodeVer:%" PRId64 ":%" PRId64 " reboot:%d", pDnode->id, online,
891
            statusReq.dnodeVer, dnodeVer, reboot);
892
    }
893

46✔
894
    pDnode->rebootTime = statusReq.rebootTime;
46✔
895
    pDnode->numOfCores = statusReq.numOfCores;
46✔
896
    pDnode->numOfSupportVnodes = statusReq.numOfSupportVnodes;
46✔
897
    pDnode->numOfDiskCfg = statusReq.numOfDiskCfg;
46✔
898
    pDnode->memAvail = statusReq.memAvail;
46✔
899
    pDnode->memTotal = statusReq.memTotal;
46✔
900
    pDnode->encryptionKeyStat = statusReq.clusterCfg.encryptionKeyStat;
46✔
901
    pDnode->encryptionKeyChksum = statusReq.clusterCfg.encryptionKeyChksum;
46✔
902
    if (memcmp(pDnode->machineId, statusReq.machineId, TSDB_MACHINE_ID_LEN) != 0) {
19✔
903
      tstrncpy(pDnode->machineId, statusReq.machineId, TSDB_MACHINE_ID_LEN + 1);
19!
904
      if ((terrno = mndUpdateDnodeObj(pMnode, pDnode)) != 0) {
×
905
        goto _OVER;
906
      }
907
    }
908

46✔
909
    SStatusRsp statusRsp = {0};
46✔
910
    statusRsp.statusSeq++;
46✔
911
    statusRsp.analVer = analVer;
46✔
912
    statusRsp.dnodeVer = dnodeVer;
46✔
913
    statusRsp.dnodeCfg.dnodeId = pDnode->id;
46✔
914
    statusRsp.dnodeCfg.clusterId = pMnode->clusterId;
46✔
915
    statusRsp.pDnodeEps = taosArrayInit(mndGetDnodeSize(pMnode), sizeof(SDnodeEp));
46!
916
    if (statusRsp.pDnodeEps == NULL) {
×
917
      terrno = TSDB_CODE_OUT_OF_MEMORY;
×
918
      goto _OVER;
919
    }
920

46✔
921
    mndGetDnodeEps(pMnode, statusRsp.pDnodeEps);
46✔
922
    statusRsp.ipWhiteVer = pMnode->ipWhiteVer;
923

46✔
924
    int32_t contLen = tSerializeSStatusRsp(NULL, 0, &statusRsp);
46✔
925
    void   *pHead = rpcMallocCont(contLen);
46✔
926
    contLen = tSerializeSStatusRsp(pHead, contLen, &statusRsp);
46✔
927
    taosArrayDestroy(statusRsp.pDnodeEps);
46!
928
    if (contLen < 0) {
×
929
      code = contLen;
×
930
      goto _OVER;
931
    }
932

46✔
933
    pReq->info.rspLen = contLen;
46✔
934
    pReq->info.rsp = pHead;
935
  }
936

824✔
937
  pDnode->accessTimes++;
824✔
938
  pDnode->lastAccessTime = curMs;
824✔
939
  code = 0;
940

830✔
941
_OVER:
830✔
942
  mndReleaseDnode(pMnode, pDnode);
830✔
943
  taosArrayDestroy(statusReq.pVloads);
830✔
944
  return mndUpdClusterInfo(pReq);
945
}
946

×
947
static int32_t mndProcessNotifyReq(SRpcMsg *pReq) {
×
948
  SMnode    *pMnode = pReq->info.node;
×
949
  SNotifyReq notifyReq = {0};
×
950
  int32_t    code = 0;
951

×
952
  if ((code = tDeserializeSNotifyReq(pReq->pCont, pReq->contLen, &notifyReq)) != 0) {
×
953
    terrno = code;
×
954
    goto _OVER;
955
  }
956

×
957
  int64_t clusterid = mndGetClusterId(pMnode);
×
958
  if (notifyReq.clusterId != 0 && notifyReq.clusterId != clusterid) {
×
959
    code = TSDB_CODE_MND_DNODE_DIFF_CLUSTER;
×
960
    mWarn("dnode:%d, its clusterid:%" PRId64 " differ from current cluster:%" PRId64 " since %s", notifyReq.dnodeId,
961
          notifyReq.clusterId, clusterid, tstrerror(code));
×
962
    goto _OVER;
963
  }
964

×
965
  int32_t nVgroup = taosArrayGetSize(notifyReq.pVloads);
×
966
  for (int32_t v = 0; v < nVgroup; ++v) {
×
967
    SVnodeLoadLite *pVload = taosArrayGet(notifyReq.pVloads, v);
968

×
969
    SVgObj *pVgroup = mndAcquireVgroup(pMnode, pVload->vgId);
×
970
    if (pVgroup != NULL) {
×
971
      pVgroup->numOfTimeSeries = pVload->nTimeSeries;
×
972
      mndReleaseVgroup(pMnode, pVgroup);
973
    }
974
  }
×
975
  code = mndUpdClusterInfo(pReq);
×
976
_OVER:
×
977
  tFreeSNotifyReq(&notifyReq);
×
978
  return code;
979
}
980

3✔
981
static int32_t mndCreateDnode(SMnode *pMnode, SRpcMsg *pReq, SCreateDnodeReq *pCreate) {
3✔
982
  int32_t  code = -1;
3✔
983
  SSdbRaw *pRaw = NULL;
3✔
984
  STrans  *pTrans = NULL;
985

3✔
986
  SDnodeObj dnodeObj = {0};
3✔
987
  dnodeObj.id = sdbGetMaxId(pMnode->pSdb, SDB_DNODE);
3✔
988
  dnodeObj.createdTime = taosGetTimestampMs();
3✔
989
  dnodeObj.updateTime = dnodeObj.createdTime;
3✔
990
  dnodeObj.port = pCreate->port;
3✔
991
  tstrncpy(dnodeObj.fqdn, pCreate->fqdn, TSDB_FQDN_LEN);
3✔
992
  (void)snprintf(dnodeObj.ep, TSDB_EP_LEN - 1, "%s:%u", pCreate->fqdn, pCreate->port);
993

3✔
994
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_GLOBAL, pReq, "create-dnode");
3!
995
  if (pTrans == NULL) {
×
996
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
997
    if (terrno != 0) code = terrno;
×
998
    goto _OVER;
999
  }
3!
1000
  mInfo("trans:%d, used to create dnode:%s", pTrans->id, dnodeObj.ep);
3!
1001
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
1002

3✔
1003
  pRaw = mndDnodeActionEncode(&dnodeObj);
3!
1004
  if (pRaw == NULL) {
×
1005
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1006
    if (terrno != 0) code = terrno;
×
1007
    goto _OVER;
1008
  }
3!
1009
  TAOS_CHECK_GOTO(mndTransAppendCommitlog(pTrans, pRaw), NULL, _OVER);
3!
1010
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_READY), NULL, _OVER);
3✔
1011
  pRaw = NULL;
1012

3!
1013
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
3✔
1014
  code = 0;
1015

3✔
1016
  (void)mndUpdateIpWhiteForAllUser(pMnode, TSDB_DEFAULT_USER, dnodeObj.fqdn, IP_WHITE_ADD,
1017
                                   1);  // TODO: check the return value
3✔
1018
_OVER:
3✔
1019
  mndTransDrop(pTrans);
3✔
1020
  sdbFreeRaw(pRaw);
3✔
1021
  return code;
1022
}
1023

×
1024
static int32_t mndProcessDnodeListReq(SRpcMsg *pReq) {
×
1025
  SMnode       *pMnode = pReq->info.node;
×
1026
  SSdb         *pSdb = pMnode->pSdb;
×
1027
  SDnodeObj    *pObj = NULL;
×
1028
  void         *pIter = NULL;
×
1029
  SDnodeListRsp rsp = {0};
×
1030
  int32_t       code = -1;
1031

×
1032
  rsp.dnodeList = taosArrayInit(5, sizeof(SEpSet));
×
1033
  if (NULL == rsp.dnodeList) {
×
1034
    mError("failed to alloc epSet while process dnode list req");
×
1035
    code = terrno;
×
1036
    goto _OVER;
1037
  }
1038

×
1039
  while (1) {
×
1040
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pObj);
×
1041
    if (pIter == NULL) break;
1042

×
1043
    SEpSet epSet = {0};
×
1044
    epSet.numOfEps = 1;
×
1045
    tstrncpy(epSet.eps[0].fqdn, pObj->fqdn, TSDB_FQDN_LEN);
×
1046
    epSet.eps[0].port = pObj->port;
1047

×
1048
    if (taosArrayPush(rsp.dnodeList, &epSet) == NULL) {
×
1049
      if (terrno != 0) code = terrno;
×
1050
      sdbRelease(pSdb, pObj);
×
1051
      sdbCancelFetch(pSdb, pIter);
×
1052
      goto _OVER;
1053
    }
1054

×
1055
    sdbRelease(pSdb, pObj);
1056
  }
1057

×
1058
  int32_t rspLen = tSerializeSDnodeListRsp(NULL, 0, &rsp);
×
1059
  void   *pRsp = rpcMallocCont(rspLen);
×
1060
  if (pRsp == NULL) {
×
1061
    code = terrno;
×
1062
    goto _OVER;
1063
  }
1064

×
1065
  if ((rspLen = tSerializeSDnodeListRsp(pRsp, rspLen, &rsp)) <= 0) {
×
1066
    code = rspLen;
×
1067
    goto _OVER;
1068
  }
1069

×
1070
  pReq->info.rspLen = rspLen;
×
1071
  pReq->info.rsp = pRsp;
×
1072
  code = 0;
1073

×
1074
_OVER:
1075

×
1076
  if (code != 0) {
×
1077
    mError("failed to get dnode list since %s", tstrerror(code));
1078
  }
1079

×
1080
  tFreeSDnodeListRsp(&rsp);
1081

×
1082
  TAOS_RETURN(code);
1083
}
1084

×
1085
void getSlowLogScopeString(int32_t scope, char *result) {
×
1086
  if (scope == SLOW_LOG_TYPE_NULL) {
×
1087
    (void)strncat(result, "NONE", 64);
×
1088
    return;
1089
  }
×
1090
  while (scope > 0) {
×
1091
    if (scope & SLOW_LOG_TYPE_QUERY) {
×
1092
      (void)strncat(result, "QUERY", 64);
×
1093
      scope &= ~SLOW_LOG_TYPE_QUERY;
×
1094
    } else if (scope & SLOW_LOG_TYPE_INSERT) {
×
1095
      (void)strncat(result, "INSERT", 64);
×
1096
      scope &= ~SLOW_LOG_TYPE_INSERT;
×
1097
    } else if (scope & SLOW_LOG_TYPE_OTHERS) {
×
1098
      (void)strncat(result, "OTHERS", 64);
×
1099
      scope &= ~SLOW_LOG_TYPE_OTHERS;
1100
    } else {
×
1101
      (void)printf("invalid slow log scope:%d", scope);
×
1102
      return;
1103
    }
1104

×
1105
    if (scope > 0) {
×
1106
      (void)strncat(result, "|", 64);
1107
    }
1108
  }
1109
}
1110

3✔
1111
static int32_t mndProcessCreateDnodeReq(SRpcMsg *pReq) {
3✔
1112
  SMnode         *pMnode = pReq->info.node;
3✔
1113
  int32_t         code = -1;
3✔
1114
  SDnodeObj      *pDnode = NULL;
3✔
1115
  SCreateDnodeReq createReq = {0};
1116

3!
1117
  if ((code = grantCheck(TSDB_GRANT_DNODE)) != 0 || (code = grantCheck(TSDB_GRANT_CPU_CORES)) != 0) {
×
1118
    goto _OVER;
1119
  }
1120

3!
1121
  TAOS_CHECK_GOTO(tDeserializeSCreateDnodeReq(pReq->pCont, pReq->contLen, &createReq), NULL, _OVER);
1122

3!
1123
  mInfo("dnode:%s:%d, start to create", createReq.fqdn, createReq.port);
3!
1124
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_DNODE), NULL, _OVER);
1125

3!
1126
  if (createReq.fqdn[0] == 0 || createReq.port <= 0 || createReq.port > UINT16_MAX) {
×
1127
    code = TSDB_CODE_MND_INVALID_DNODE_EP;
×
1128
    goto _OVER;
1129
  }
1130

1131
  char ep[TSDB_EP_LEN];
3✔
1132
  (void)snprintf(ep, TSDB_EP_LEN, "%s:%d", createReq.fqdn, createReq.port);
3✔
1133
  pDnode = mndAcquireDnodeByEp(pMnode, ep);
3!
1134
  if (pDnode != NULL) {
×
1135
    code = TSDB_CODE_MND_DNODE_ALREADY_EXIST;
×
1136
    goto _OVER;
1137
  }
1138

3✔
1139
  code = mndCreateDnode(pMnode, pReq, &createReq);
3!
1140
  if (code == 0) {
3✔
1141
    code = TSDB_CODE_ACTION_IN_PROGRESS;
3✔
1142
    tsGrantHBInterval = 5;
1143
  }
1144

3✔
1145
  char obj[200] = {0};
3✔
1146
  (void)tsnprintf(obj, sizeof(obj), "%s:%d", createReq.fqdn, createReq.port);
1147

3✔
1148
  auditRecord(pReq, pMnode->clusterId, "createDnode", "", obj, createReq.sql, createReq.sqlLen);
1149

3✔
1150
_OVER:
3!
1151
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
×
1152
    mError("dnode:%s:%d, failed to create since %s", createReq.fqdn, createReq.port, tstrerror(code));
1153
  }
1154

3✔
1155
  mndReleaseDnode(pMnode, pDnode);
3✔
1156
  tFreeSCreateDnodeReq(&createReq);
3✔
1157
  TAOS_RETURN(code);
1158
}
1159

1160
extern int32_t mndProcessRestoreDnodeReqImpl(SRpcMsg *pReq);
1161

×
1162
int32_t mndProcessRestoreDnodeReq(SRpcMsg *pReq) { return mndProcessRestoreDnodeReqImpl(pReq); }
1163

1164
#ifndef TD_ENTERPRISE
1165
int32_t mndProcessRestoreDnodeReqImpl(SRpcMsg *pReq) { return 0; }
1166
#endif
1167

×
1168
static int32_t mndDropDnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode, SMnodeObj *pMObj, SQnodeObj *pQObj,
NEW
1169
                            SSnodeObj *pSObj, SXnodeObj *pXObj, int32_t numOfVnodes, bool force, bool unsafe) {
×
1170
  int32_t  code = -1;
×
1171
  SSdbRaw *pRaw = NULL;
×
1172
  STrans  *pTrans = NULL;
1173

×
1174
  pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "drop-dnode");
×
1175
  if (pTrans == NULL) {
×
1176
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1177
    if (terrno != 0) code = terrno;
×
1178
    goto _OVER;
1179
  }
×
1180
  mndTransSetSerial(pTrans);
×
1181
  mInfo("trans:%d, used to drop dnode:%d, force:%d", pTrans->id, pDnode->id, force);
×
1182
  TAOS_CHECK_GOTO(mndTransCheckConflict(pMnode, pTrans), NULL, _OVER);
1183

×
1184
  pRaw = mndDnodeActionEncode(pDnode);
×
1185
  if (pRaw == NULL) {
×
1186
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1187
    if (terrno != 0) code = terrno;
×
1188
    goto _OVER;
1189
  }
×
1190
  TAOS_CHECK_GOTO(mndTransAppendRedolog(pTrans, pRaw), NULL, _OVER);
×
1191
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_DROPPING), NULL, _OVER);
×
1192
  pRaw = NULL;
1193

×
1194
  pRaw = mndDnodeActionEncode(pDnode);
×
1195
  if (pRaw == NULL) {
×
1196
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1197
    if (terrno != 0) code = terrno;
×
1198
    goto _OVER;
1199
  }
×
1200
  TAOS_CHECK_GOTO(mndTransAppendCommitlog(pTrans, pRaw), NULL, _OVER);
×
1201
  TAOS_CHECK_GOTO(sdbSetRawStatus(pRaw, SDB_STATUS_DROPPED), NULL, _OVER);
×
1202
  pRaw = NULL;
1203

×
1204
  if (pMObj != NULL) {
×
1205
    mInfo("trans:%d, mnode on dnode:%d will be dropped", pTrans->id, pDnode->id);
×
1206
    TAOS_CHECK_GOTO(mndSetDropMnodeInfoToTrans(pMnode, pTrans, pMObj, force), NULL, _OVER);
1207
  }
1208

×
1209
  if (pQObj != NULL) {
×
1210
    mInfo("trans:%d, qnode on dnode:%d will be dropped", pTrans->id, pDnode->id);
×
1211
    TAOS_CHECK_GOTO(mndSetDropQnodeInfoToTrans(pMnode, pTrans, pQObj, force), NULL, _OVER);
1212
  }
1213

×
1214
  if (pSObj != NULL) {
×
1215
    mInfo("trans:%d, snode on dnode:%d will be dropped", pTrans->id, pDnode->id);
×
1216
    TAOS_CHECK_GOTO(mndSetDropSnodeInfoToTrans(pMnode, pTrans, pSObj, force), NULL, _OVER);
1217
  }
1218

×
NEW
1219
  if (pXObj != NULL) {
×
NEW
1220
    mInfo("trans:%d, snode on dnode:%d will be dropped", pTrans->id, pDnode->id);
×
1221
    TAOS_CHECK_GOTO(mndSetDropXnodeInfoToTrans(pMnode, pTrans, pXObj, force), NULL, _OVER);
1222
  }
NEW
1223

×
1224
  if (numOfVnodes > 0) {
1225
    mInfo("trans:%d, %d vnodes on dnode:%d will be dropped", pTrans->id, numOfVnodes, pDnode->id);
×
1226
    TAOS_CHECK_GOTO(mndSetMoveVgroupsInfoToTrans(pMnode, pTrans, pDnode->id, force, unsafe), NULL, _OVER);
1227
  }
×
1228

1229
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
×
1230

×
1231
  (void)mndUpdateIpWhiteForAllUser(pMnode, TSDB_DEFAULT_USER, pDnode->fqdn, IP_WHITE_DROP,
×
1232
                                   1);  // TODO: check the return value
×
1233
  code = 0;
1234

1235
_OVER:
×
1236
  mndTransDrop(pTrans);
×
1237
  sdbFreeRaw(pRaw);
×
1238
  TAOS_RETURN(code);
×
1239
}
×
1240

1241
static bool mndIsEmptyDnode(SMnode *pMnode, int32_t dnodeId) {
×
1242
  bool       isEmpty = false;
×
1243
  SMnodeObj *pMObj = NULL;
1244
  SQnodeObj *pQObj = NULL;
×
1245
  SSnodeObj *pSObj = NULL;
×
1246

1247
  pQObj = mndAcquireQnode(pMnode, dnodeId);
×
1248
  if (pQObj) goto _OVER;
×
1249

1250
  pSObj = mndAcquireSnode(pMnode, dnodeId);
×
1251
  if (pSObj) goto _OVER;
×
1252

1253
  pMObj = mndAcquireMnode(pMnode, dnodeId);
×
1254
  if (pMObj) goto _OVER;
×
1255

×
1256
  int32_t numOfVnodes = mndGetVnodesNum(pMnode, dnodeId);
×
1257
  if (numOfVnodes > 0) goto _OVER;
×
1258

×
1259
  isEmpty = true;
1260
_OVER:
1261
  mndReleaseMnode(pMnode, pMObj);
×
1262
  mndReleaseQnode(pMnode, pQObj);
×
1263
  mndReleaseSnode(pMnode, pSObj);
×
1264
  return isEmpty;
×
1265
}
×
1266

×
1267
static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) {
×
1268
  SMnode       *pMnode = pReq->info.node;
×
1269
  int32_t       code = -1;
1270
  SDnodeObj    *pDnode = NULL;
×
1271
  SMnodeObj    *pMObj = NULL;
1272
  SQnodeObj    *pQObj = NULL;
×
1273
  SSnodeObj    *pSObj = NULL;
NEW
1274
  SXnodeObj    *pXObj = NULL;
×
1275
  SDropDnodeReq dropReq = {0};
1276

×
1277
  TAOS_CHECK_GOTO(tDeserializeSDropDnodeReq(pReq->pCont, pReq->contLen, &dropReq), NULL, _OVER);
×
1278

×
1279
  mInfo("dnode:%d, start to drop, ep:%s:%d, force:%s, unsafe:%s", dropReq.dnodeId, dropReq.fqdn, dropReq.port,
1280
        dropReq.force ? "true" : "false", dropReq.unsafe ? "true" : "false");
1281
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_MNODE), NULL, _OVER);
×
1282

×
1283
  bool force = dropReq.force;
×
1284
  if (dropReq.unsafe) {
×
1285
    force = true;
×
1286
  }
×
1287

×
1288
  pDnode = mndAcquireDnode(pMnode, dropReq.dnodeId);
×
1289
  if (pDnode == NULL) {
×
1290
    int32_t err = terrno;
1291
    char    ep[TSDB_EP_LEN + 1] = {0};
1292
    (void)snprintf(ep, sizeof(ep), dropReq.fqdn, dropReq.port);
1293
    pDnode = mndAcquireDnodeByEp(pMnode, ep);
×
1294
    if (pDnode == NULL) {
×
1295
      code = err;
×
1296
      goto _OVER;
×
1297
    }
×
1298
  }
×
1299

×
1300
  pQObj = mndAcquireQnode(pMnode, dropReq.dnodeId);
1301
  pSObj = mndAcquireSnode(pMnode, dropReq.dnodeId);
×
NEW
1302
  pXObj = mndAcquireXnode(pMnode, dropReq.dnodeId);
×
1303
  pMObj = mndAcquireMnode(pMnode, dropReq.dnodeId);
×
1304
  if (pMObj != NULL) {
1305
    if (sdbGetSize(pMnode->pSdb, SDB_MNODE) <= 1) {
1306
      code = TSDB_CODE_MND_TOO_FEW_MNODES;
1307
      goto _OVER;
×
1308
    }
×
1309
    if (pMnode->selfDnodeId == dropReq.dnodeId) {
1310
      code = TSDB_CODE_MND_CANT_DROP_LEADER;
×
1311
      goto _OVER;
×
1312
    }
×
1313
  }
1314

×
1315
  int32_t numOfVnodes = mndGetVnodesNum(pMnode, pDnode->id);
1316
  bool    isonline = mndIsDnodeOnline(pDnode, taosGetTimestampMs());
1317

×
1318
  if (isonline && force) {
×
1319
    code = TSDB_CODE_DNODE_ONLY_USE_WHEN_OFFLINE;
×
NEW
1320
    mError("dnode:%d, failed to drop since %s, vnodes:%d mnode:%d qnode:%d snode:%d xnode:%d", pDnode->id,
×
1321
           tstrerror(code), numOfVnodes, pMObj != NULL, pQObj != NULL, pSObj != NULL, pXObj != NULL);
1322
    goto _OVER;
×
1323
  }
1324

1325
  bool isEmpty = mndIsEmptyDnode(pMnode, pDnode->id);
×
1326
  if (!isonline && !force && !isEmpty) {
×
1327
    code = TSDB_CODE_DNODE_OFFLINE;
NEW
1328
    mError("dnode:%d, failed to drop since %s, vnodes:%d mnode:%d qnode:%d snode:%d xnode:%d", pDnode->id,
×
NEW
1329
           tstrerror(code), numOfVnodes, pMObj != NULL, pQObj != NULL, pSObj != NULL, pXObj != NULL);
×
1330
    goto _OVER;
1331
  }
×
1332

NEW
1333
  code = mndDropDnode(pMnode, pReq, pDnode, pMObj, pQObj, pSObj, pXObj, numOfVnodes, force, dropReq.unsafe);
×
1334
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
×
1335

×
1336
  char obj1[30] = {0};
1337
  (void)tsnprintf(obj1, sizeof(obj1), "%d", dropReq.dnodeId);
1338

×
1339
  auditRecord(pReq, pMnode->clusterId, "dropDnode", "", obj1, dropReq.sql, dropReq.sqlLen);
×
1340

×
1341
_OVER:
×
1342
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
×
1343
    mError("dnode:%d, failed to drop since %s", dropReq.dnodeId, tstrerror(code));
×
1344
  }
1345

1346
  mndReleaseDnode(pMnode, pDnode);
×
1347
  mndReleaseMnode(pMnode, pMObj);
×
1348
  mndReleaseQnode(pMnode, pQObj);
×
1349
  mndReleaseSnode(pMnode, pSObj);
×
1350
  tFreeSDropDnodeReq(&dropReq);
×
1351
  TAOS_RETURN(code);
×
1352
}
1353

×
1354
static int32_t mndProcessCreateEncryptKeyReqImpl(SRpcMsg *pReq, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
1355
  int32_t code = 0;
×
1356
  SMnode *pMnode = pReq->info.node;
×
1357
  SSdb   *pSdb = pMnode->pSdb;
×
1358
  void   *pIter = NULL;
×
1359
  int8_t  encrypting = 0;
1360

×
1361
  const STraceId *trace = &pReq->info.traceId;
1362

1363
  int32_t klen = strlen(pDcfgReq->value);
×
1364
  if (klen > ENCRYPT_KEY_LEN || klen < ENCRYPT_KEY_LEN_MIN) {
×
1365
    code = TSDB_CODE_DNODE_INVALID_ENCRYPT_KLEN;
×
1366
    mGError("msg:%p, failed to create encrypt_key since invalid key length:%d, valid range:[%d, %d]", pReq, klen,
×
1367
            ENCRYPT_KEY_LEN_MIN, ENCRYPT_KEY_LEN);
1368
    goto _exit;
1369
  }
×
1370

×
1371
  if (0 != (encrypting = atomic_val_compare_exchange_8(&pMnode->encryptMgmt.encrypting, 0, 1))) {
×
1372
    code = TSDB_CODE_QRY_DUPLICATED_OPERATION;
×
1373
    mGWarn("msg:%p, failed to create encrypt key since %s, encrypting:%" PRIi8, pReq, tstrerror(code), encrypting);
1374
    goto _exit;
×
1375
  }
1376

1377
  if (tsEncryptionKeyStat == ENCRYPT_KEY_STAT_SET || tsEncryptionKeyStat == ENCRYPT_KEY_STAT_LOADED) {
×
1378
    atomic_store_8(&pMnode->encryptMgmt.encrypting, 0);
×
1379
    code = TSDB_CODE_QRY_DUPLICATED_OPERATION;
×
1380
    mGWarn("msg:%p, failed to create encrypt key since %s, stat:%" PRIi8 ", checksum:%u", pReq, tstrerror(code),
1381
           tsEncryptionKeyStat, tsEncryptionKeyChksum);
×
1382
    goto _exit;
×
1383
  }
×
1384

×
1385
  atomic_store_16(&pMnode->encryptMgmt.nEncrypt, 0);
×
1386
  atomic_store_16(&pMnode->encryptMgmt.nSuccess, 0);
×
1387
  atomic_store_16(&pMnode->encryptMgmt.nFailed, 0);
1388

×
1389
  while (1) {
×
1390
    SDnodeObj *pDnode = NULL;
1391
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
1392
    if (pIter == NULL) break;
×
1393
    if (pDnode->offlineReason != DND_REASON_ONLINE) {
×
1394
      mGWarn("msg:%p, don't send create encrypt_key req since dnode:%d in offline state:%s", pReq, pDnode->id,
×
1395
             offlineReason[pDnode->offlineReason]);
×
1396
      sdbRelease(pSdb, pDnode);
1397
      continue;
×
1398
    }
×
1399

×
1400
    if (dnodeId == -1 || pDnode->id == dnodeId || dnodeId == 0) {
×
1401
      SEpSet  epSet = mndGetDnodeEpset(pDnode);
×
1402
      int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, pDcfgReq);
1403
      void   *pBuf = rpcMallocCont(bufLen);
×
1404

×
1405
      if (pBuf != NULL) {
×
1406
        if ((bufLen = tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq)) <= 0) {
1407
          code = bufLen;
1408
          sdbRelease(pSdb, pDnode);
1409
          goto _exit;
1410
        }
×
1411
        SRpcMsg rpcMsg = {.msgType = TDMT_DND_CREATE_ENCRYPT_KEY, .pCont = pBuf, .contLen = bufLen};
1412
        if (0 == tmsgSendReq(&epSet, &rpcMsg)) {
1413
          (void)atomic_add_fetch_16(&pMnode->encryptMgmt.nEncrypt, 1);
×
1414
        }
×
1415
      }
1416
    }
1417

×
1418
    sdbRelease(pSdb, pDnode);
×
1419
  }
×
1420

1421
  if (atomic_load_16(&pMnode->encryptMgmt.nEncrypt) <= 0) {
×
1422
    atomic_store_8(&pMnode->encryptMgmt.encrypting, 0);
1423
  }
1424

×
1425
_exit:
×
1426
  if (code != 0) {
1427
    if (terrno == 0) terrno = code;
1428
  }
×
1429
  return code;
×
1430
}
×
1431

1432
static int32_t mndProcessCreateEncryptKeyReq(SRpcMsg *pReq) {
×
1433
  int32_t code = 0;
×
1434

×
1435
#if defined(TD_ENTERPRISE) || defined(TD_ASTRA_TODO)
1436
  SMnode       *pMnode = pReq->info.node;
×
1437
  SMCfgDnodeReq cfgReq = {0};
×
1438
  TAOS_CHECK_RETURN(tDeserializeSMCfgDnodeReq(pReq->pCont, pReq->contLen, &cfgReq));
×
1439

×
1440
  if ((code = mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONFIG_DNODE)) != 0) {
×
1441
    tFreeSMCfgDnodeReq(&cfgReq);
×
1442
    TAOS_RETURN(code);
×
1443
  }
1444
  const STraceId *trace = &pReq->info.traceId;
×
1445
  SDCfgDnodeReq   dcfgReq = {0};
×
1446
  if (strncasecmp(cfgReq.config, "encrypt_key", 12) == 0) {
×
1447
    tstrncpy(dcfgReq.config, cfgReq.config, sizeof(dcfgReq.config));
1448
    tstrncpy(dcfgReq.value, cfgReq.value, sizeof(dcfgReq.value));
1449
    tFreeSMCfgDnodeReq(&cfgReq);
1450
    return mndProcessCreateEncryptKeyReqImpl(pReq, cfgReq.dnodeId, &dcfgReq);
1451
  } else {
1452
    code = TSDB_CODE_PAR_INTERNAL_ERROR;
1453
    tFreeSMCfgDnodeReq(&cfgReq);
1454
    TAOS_RETURN(code);
×
1455
  }
×
1456

×
1457
#else
×
1458
  TAOS_RETURN(code);
1459
#endif
×
1460
}
×
1461

1462
static int32_t mndProcessCreateEncryptKeyRsp(SRpcMsg *pRsp) {
×
1463
  SMnode *pMnode = pRsp->info.node;
1464
  int16_t nSuccess = 0;
1465
  int16_t nFailed = 0;
×
1466

×
1467
  if (0 == pRsp->code) {
1468
    nSuccess = atomic_add_fetch_16(&pMnode->encryptMgmt.nSuccess, 1);
×
1469
  } else {
×
1470
    nFailed = atomic_add_fetch_16(&pMnode->encryptMgmt.nFailed, 1);
1471
  }
1472

×
1473
  int16_t nReq = atomic_load_16(&pMnode->encryptMgmt.nEncrypt);
×
1474
  bool    finished = nSuccess + nFailed >= nReq;
1475

1476
  if (finished) {
×
1477
    atomic_store_8(&pMnode->encryptMgmt.encrypting, 0);
1478
  }
1479

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

×
1484
  return 0;
×
1485
}
×
1486

×
1487
static int32_t mndRetrieveConfigs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
×
1488
  SMnode *pMnode = pReq->info.node;
×
1489
  int32_t totalRows = 0;
1490
  int32_t numOfRows = 0;
×
1491
  char   *cfgOpts[TSDB_CONFIG_NUMBER] = {0};
×
1492
  char    cfgVals[TSDB_CONFIG_NUMBER][TSDB_CONFIG_VALUE_LEN + 1] = {0};
×
1493
  char   *pWrite = NULL;
1494
  int32_t cols = 0;
×
1495
  int32_t code = 0;
×
1496
  int32_t lino = 0;
×
1497

1498
  cfgOpts[totalRows] = "statusInterval";
×
1499
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%d", tsStatusInterval);
×
1500
  totalRows++;
×
1501

1502
  cfgOpts[totalRows] = "timezone";
×
1503
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", tsTimezoneStr);
×
1504
  totalRows++;
×
1505

1506
  cfgOpts[totalRows] = "locale";
×
1507
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", tsLocale);
×
1508
  totalRows++;
×
1509

1510
  cfgOpts[totalRows] = "charset";
×
1511
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", tsCharset);
×
1512
  totalRows++;
×
1513

1514
  cfgOpts[totalRows] = "monitor";
×
1515
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%d", tsEnableMonitor);
×
1516
  totalRows++;
×
1517

1518
  cfgOpts[totalRows] = "monitorInterval";
×
1519
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%d", tsMonitorInterval);
×
1520
  totalRows++;
×
1521

1522
  cfgOpts[totalRows] = "slowLogThreshold";
×
1523
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%d", tsSlowLogThreshold);
×
1524
  totalRows++;
×
1525

×
1526
  cfgOpts[totalRows] = "slowLogMaxLen";
×
1527
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%d", tsSlowLogMaxLen);
1528
  totalRows++;
×
1529

×
1530
  char scopeStr[64] = {0};
1531
  getSlowLogScopeString(tsSlowLogScope, scopeStr);
×
1532
  cfgOpts[totalRows] = "slowLogScope";
×
1533
  (void)snprintf(cfgVals[totalRows], TSDB_CONFIG_VALUE_LEN, "%s", scopeStr);
1534
  totalRows++;
×
1535

×
1536
  char buf[TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE] = {0};
×
1537
  char bufVal[TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE] = {0};
1538

×
1539
  for (int32_t i = 0; i < totalRows; i++) {
×
1540
    cols = 0;
×
1541

1542
    STR_WITH_MAXSIZE_TO_VARSTR(buf, cfgOpts[i], TSDB_CONFIG_OPTION_LEN);
×
1543
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1544
    TAOS_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)buf, false), &lino, _OVER);
1545

×
1546
    STR_WITH_MAXSIZE_TO_VARSTR(bufVal, cfgVals[i], TSDB_CONFIG_VALUE_LEN);
×
1547
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
1548
    TAOS_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)bufVal, false), &lino, _OVER);
×
1549

1550
    numOfRows++;
1551
  }
×
1552

1553
_OVER:
2✔
1554
  if (code != 0) mError("failed to retrieve configs at line:%d since %s", lino, tstrerror(code));
2✔
1555
  pShow->numOfRows += numOfRows;
2✔
1556
  return numOfRows;
2✔
1557
}
2✔
1558

2✔
1559
static void mndCancelGetNextConfig(SMnode *pMnode, void *pIter) {}
2✔
1560

2✔
1561
static int32_t mndRetrieveDnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
1562
  SMnode    *pMnode = pReq->info.node;
2✔
1563
  SSdb      *pSdb = pMnode->pSdb;
2✔
1564
  int32_t    numOfRows = 0;
1565
  int32_t    cols = 0;
10!
1566
  ESdbStatus objStatus = 0;
10✔
1567
  SDnodeObj *pDnode = NULL;
10✔
1568
  int64_t    curMs = taosGetTimestampMs();
8✔
1569
  char       buf[TSDB_EP_LEN + VARSTR_HEADER_SIZE];
1570
  int32_t    code = 0;
8✔
1571
  int32_t    lino = 0;
1572

8✔
1573
  while (numOfRows < rows) {
8!
1574
    pShow->pIter = sdbFetchAll(pSdb, SDB_DNODE, pShow->pIter, (void **)&pDnode, &objStatus, true);
1575
    if (pShow->pIter == NULL) break;
8✔
1576
    bool online = mndIsDnodeOnline(pDnode, curMs);
1577

8✔
1578
    cols = 0;
8!
1579

1580
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
1581
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->id, false), pDnode, &lino, _OVER);
8✔
1582

8!
1583
    STR_WITH_MAXSIZE_TO_VARSTR(buf, pDnode->ep, pShow->pMeta->pSchemas[cols].bytes);
1584

8✔
1585
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8!
1586
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, buf, false), pDnode, &lino, _OVER);
1587

1588
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8✔
1589
    int16_t id = mndGetVnodesNum(pMnode, pDnode->id);
8!
1590
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&id, false), pDnode, &lino, _OVER);
8!
1591

8✔
1592
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
3!
1593
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->numOfSupportVnodes, false), pDnode,
×
1594
                        &lino, _OVER);
3!
1595

×
1596
    const char *status = "ready";
1597
    if (objStatus == SDB_STATUS_CREATING) status = "creating";
3✔
1598
    if (objStatus == SDB_STATUS_DROPPING) status = "dropping";
1599
    if (!online) {
1600
      if (objStatus == SDB_STATUS_CREATING)
8✔
1601
        status = "creating*";
8✔
1602
      else if (objStatus == SDB_STATUS_DROPPING)
8!
1603
        status = "dropping*";
1604
      else
8✔
1605
        status = "offline";
8!
1606
    }
1607

1608
    STR_TO_VARSTR(buf, status);
8✔
1609
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8!
1610
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, buf, false), pDnode, &lino, _OVER);
1611

1612
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8!
1613
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->createdTime, false), pDnode, &lino,
8✔
1614
                        _OVER);
1615

8✔
1616
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
8!
1617
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->rebootTime, false), pDnode, &lino,
8!
1618
                        _OVER);
1619

1620
    char *b = taosMemoryCalloc(VARSTR_HEADER_SIZE + strlen(offlineReason[pDnode->offlineReason]) + 1, 1);
8✔
1621
    STR_TO_VARSTR(b, online ? "" : offlineReason[pDnode->offlineReason]);
8✔
1622

8!
1623
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
1624
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, b, false), pDnode, &lino, _OVER);
1625
    taosMemoryFreeClear(b);
8✔
1626

8✔
1627
#ifdef TD_ENTERPRISE
1628
    STR_TO_VARSTR(buf, pDnode->machineId);
1629
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
1630
    RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, buf, false), pDnode, &lino, _OVER);
2!
1631
#endif
1632

2✔
1633
    numOfRows++;
2✔
1634
    sdbRelease(pSdb, pDnode);
1635
  }
1636

×
1637
_OVER:
×
1638
  if (code != 0) mError("failed to retrieve dnodes at line:%d since %s", lino, tstrerror(code));
×
1639

×
1640
  pShow->numOfRows += numOfRows;
1641
  return numOfRows;
17✔
1642
}
17✔
1643

17✔
1644
static void mndCancelGetNextDnode(SMnode *pMnode, void *pIter) {
17✔
1645
  SSdb *pSdb = pMnode->pSdb;
17✔
1646
  sdbCancelFetchByType(pSdb, pIter, SDB_DNODE);
×
1647
}
17✔
1648

17!
1649
SArray *mndGetAllDnodeFqdns(SMnode *pMnode) {
1650
  SDnodeObj *pObj = NULL;
×
1651
  void      *pIter = NULL;
×
1652
  SSdb      *pSdb = pMnode->pSdb;
×
1653
  SArray    *fqdns = taosArrayInit(4, sizeof(void *));
1654
  while (1) {
×
1655
    pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pObj);
1656
    if (pIter == NULL) break;
17✔
1657

1658
    char *fqdn = taosStrdup(pObj->fqdn);
1659
    if (taosArrayPush(fqdns, &fqdn) == NULL) {
1660
      mError("failed to fqdn into array, but continue at this time");
1661
    }
1662
    sdbRelease(pSdb, pObj);
1663
  }
1664
  return fqdns;
1665
}
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