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

taosdata / TDengine / #4950

06 Feb 2026 07:29AM UTC coverage: 66.849% (-0.1%) from 66.973%
#4950

push

travis-ci

web-flow
merge: from main to 3.0 #34521

759 of 1081 new or added lines in 28 files covered. (70.21%)

1144 existing lines in 130 files now uncovered.

205692 of 307696 relevant lines covered (66.85%)

127112954.87 hits per line

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

58.29
/source/dnode/mnode/impl/src/mndXnode.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 "mndDef.h"
19
#include "tdatablock.h"
20
#include "types.h"
21
#ifndef WINDOWS
22
#include <curl/curl.h>
23
#include <openssl/bio.h>
24
#include <openssl/buffer.h>
25
#include <openssl/err.h>
26
#include <openssl/evp.h>
27
#include <openssl/hmac.h>
28
#endif
29
#include "audit.h"
30
#include "mndDnode.h"
31
#include "mndPrivilege.h"
32
#include "mndShow.h"
33
#include "mndTrans.h"
34
#include "mndUser.h"
35
#include "mndXnode.h"
36
#include "sdb.h"
37
#include "taoserror.h"
38
#include "tjson.h"
39
#include "xnode.h"
40

41
#define TSDB_XNODE_RESERVE_SIZE 64
42
#define XNODED_PIPE_SOCKET_URL "http://localhost"
43
typedef enum {
44
  HTTP_TYPE_GET = 0,
45
  HTTP_TYPE_POST,
46
  HTTP_TYPE_DELETE,
47
} EHttpType;
48
typedef struct {
49
  char   *data;
50
  int64_t dataLen;
51
} SCurlResp;
52

53
const int32_t defaultTimeout = 1000;
54

55
/** xnodes systable actions */
56
SSdbRaw *mndXnodeActionEncode(SXnodeObj *pObj);
57
SSdbRow *mndXnodeActionDecode(SSdbRaw *pRaw);
58
int32_t  mndXnodeActionInsert(SSdb *pSdb, SXnodeObj *pObj);
59
int32_t  mndXnodeActionUpdate(SSdb *pSdb, SXnodeObj *pOld, SXnodeObj *pNew);
60
int32_t  mndXnodeActionDelete(SSdb *pSdb, SXnodeObj *pObj);
61

62
/** @section xnodes request handlers */
63
static int32_t mndProcessCreateXnodeReq(SRpcMsg *pReq);
64
static int32_t mndProcessUpdateXnodeReq(SRpcMsg *pReq);
65
static int32_t mndProcessDropXnodeReq(SRpcMsg *pReq);
66
static int32_t mndProcessDrainXnodeReq(SRpcMsg *pReq);
67
static int32_t mndRetrieveXnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
68
static void    mndCancelGetNextXnode(SMnode *pMnode, void *pIter);
69

70
/** @section xnode task handlers */
71
SSdbRaw *mndXnodeTaskActionEncode(SXnodeTaskObj *pObj);
72
SSdbRow *mndXnodeTaskActionDecode(SSdbRaw *pRaw);
73
int32_t  mndXnodeTaskActionInsert(SSdb *pSdb, SXnodeTaskObj *pObj);
74
int32_t  mndXnodeTaskActionUpdate(SSdb *pSdb, SXnodeTaskObj *pOld, SXnodeTaskObj *pNew);
75
int32_t  mndXnodeTaskActionDelete(SSdb *pSdb, SXnodeTaskObj *pObj);
76

77
static int32_t mndProcessCreateXnodeTaskReq(SRpcMsg *pReq);
78
static int32_t mndProcessStartXnodeTaskReq(SRpcMsg *pReq);
79
static int32_t mndProcessStopXnodeTaskReq(SRpcMsg *pReq);
80
static int32_t mndProcessUpdateXnodeTaskReq(SRpcMsg *pReq);
81
static int32_t mndProcessDropXnodeTaskReq(SRpcMsg *pReq);
82
static int32_t mndRetrieveXnodeTasks(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
83
static void    mndCancelGetNextXnodeTask(SMnode *pMnode, void *pIter);
84

85
/** @section xnode task job handlers */
86
SSdbRaw *mndXnodeJobActionEncode(SXnodeJobObj *pObj);
87
SSdbRow *mndXnodeJobActionDecode(SSdbRaw *pRaw);
88
int32_t  mndXnodeJobActionInsert(SSdb *pSdb, SXnodeJobObj *pObj);
89
int32_t  mndXnodeJobActionUpdate(SSdb *pSdb, SXnodeJobObj *pOld, SXnodeJobObj *pNew);
90
int32_t  mndXnodeJobActionDelete(SSdb *pSdb, SXnodeJobObj *pObj);
91

92
static int32_t mndProcessCreateXnodeJobReq(SRpcMsg *pReq);
93
static int32_t mndProcessUpdateXnodeJobReq(SRpcMsg *pReq);
94
static int32_t mndProcessRebalanceXnodeJobReq(SRpcMsg *pReq);
95
static int32_t mndProcessRebalanceXnodeJobsWhereReq(SRpcMsg *pReq);
96
static int32_t mndProcessDropXnodeJobReq(SRpcMsg *pReq);
97
static int32_t mndRetrieveXnodeJobs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
98
static void    mndCancelGetNextXnodeJob(SMnode *pMnode, void *pIter);
99

100
/** @section xnode user pass handlers */
101
SSdbRaw *mndXnodeUserPassActionEncode(SXnodeUserPassObj *pObj);
102
SSdbRow *mndXnodeUserPassActionDecode(SSdbRaw *pRaw);
103
int32_t  mndXnodeUserPassActionInsert(SSdb *pSdb, SXnodeUserPassObj *pObj);
104
int32_t  mndXnodeUserPassActionUpdate(SSdb *pSdb, SXnodeUserPassObj *pOld, SXnodeUserPassObj *pNew);
105
int32_t  mndXnodeUserPassActionDelete(SSdb *pSdb, SXnodeUserPassObj *pObj);
106

107
/** @section xnode agent handlers */
108
SSdbRaw *mndXnodeAgentActionEncode(SXnodeAgentObj *pObj);
109
SSdbRow *mndXnodeAgentActionDecode(SSdbRaw *pRaw);
110
int32_t  mndXnodeAgentActionInsert(SSdb *pSdb, SXnodeAgentObj *pObj);
111
int32_t  mndXnodeAgentActionUpdate(SSdb *pSdb, SXnodeAgentObj *pOld, SXnodeAgentObj *pNew);
112
int32_t  mndXnodeAgentActionDelete(SSdb *pSdb, SXnodeAgentObj *pObj);
113

114
static int32_t mndProcessCreateXnodeAgentReq(SRpcMsg *pReq);
115
static int32_t mndProcessUpdateXnodeAgentReq(SRpcMsg *pReq);
116
static int32_t mndProcessDropXnodeAgentReq(SRpcMsg *pReq);
117
static int32_t mndRetrieveXnodeAgents(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
118
static void    mndCancelGetNextXnodeAgent(SMnode *pMnode, void *pIter);
119

120
/** @section xnoded mgmt */
121
void mndStartXnoded(SMnode *pMnode, const char *user, const char *pass, const char *token);
122
void mndRestartXnoded(SMnode *pMnode);
123

124
/** @section others */
125
static int32_t mndGetXnodeStatus(SXnodeObj *pObj, char *status, int32_t statusLen);
126
SXnodeTaskObj *mndAcquireXnodeTask(SMnode *pMnode, int32_t tid);
127
SJson         *mndSendReqRetJson(const char *url, EHttpType type, int64_t timeout, const char *buf, int64_t bufLen);
128
static int32_t mndSetDropXnodeJobInfoToTrans(STrans *pTrans, SXnodeJobObj *pObj, bool force);
129
void           mndReleaseXnodeJob(SMnode *pMnode, SXnodeJobObj *pObj);
130

131
int32_t mndInitXnode(SMnode *pMnode) {
410,347✔
132
  SSdbTable table = {
410,347✔
133
      .sdbType = SDB_XNODE,
134
      .keyType = SDB_KEY_INT32,
135
      .encodeFp = (SdbEncodeFp)mndXnodeActionEncode,
136
      .decodeFp = (SdbDecodeFp)mndXnodeActionDecode,
137
      .insertFp = (SdbInsertFp)mndXnodeActionInsert,
138
      .updateFp = (SdbUpdateFp)mndXnodeActionUpdate,
139
      .deleteFp = (SdbDeleteFp)mndXnodeActionDelete,
140
  };
141

142
  int32_t code = sdbSetTable(pMnode->pSdb, table);
410,347✔
143
  if (code != 0) {
410,347✔
144
    return code;
×
145
  }
146

147
  SSdbTable tasks = {
410,347✔
148
      .sdbType = SDB_XNODE_TASK,
149
      .keyType = SDB_KEY_INT32,
150
      .encodeFp = (SdbEncodeFp)mndXnodeTaskActionEncode,
151
      .decodeFp = (SdbDecodeFp)mndXnodeTaskActionDecode,
152
      .insertFp = (SdbInsertFp)mndXnodeTaskActionInsert,
153
      .updateFp = (SdbUpdateFp)mndXnodeTaskActionUpdate,
154
      .deleteFp = (SdbDeleteFp)mndXnodeTaskActionDelete,
155
  };
156

157
  code = sdbSetTable(pMnode->pSdb, tasks);
410,347✔
158
  if (code != 0) {
410,347✔
159
    return code;
×
160
  }
161

162
  SSdbTable jobs = {
410,347✔
163
      .sdbType = SDB_XNODE_JOB,
164
      .keyType = SDB_KEY_INT32,
165
      .encodeFp = (SdbEncodeFp)mndXnodeJobActionEncode,
166
      .decodeFp = (SdbDecodeFp)mndXnodeJobActionDecode,
167
      .insertFp = (SdbInsertFp)mndXnodeJobActionInsert,
168
      .updateFp = (SdbUpdateFp)mndXnodeJobActionUpdate,
169
      .deleteFp = (SdbDeleteFp)mndXnodeJobActionDelete,
170
  };
171

172
  code = sdbSetTable(pMnode->pSdb, jobs);
410,347✔
173
  if (code != 0) {
410,347✔
174
    return code;
×
175
  }
176

177
  SSdbTable agents = {
410,347✔
178
      .sdbType = SDB_XNODE_AGENT,
179
      .keyType = SDB_KEY_INT32,
180
      .encodeFp = (SdbEncodeFp)mndXnodeAgentActionEncode,
181
      .decodeFp = (SdbDecodeFp)mndXnodeAgentActionDecode,
182
      .insertFp = (SdbInsertFp)mndXnodeAgentActionInsert,
183
      .updateFp = (SdbUpdateFp)mndXnodeAgentActionUpdate,
184
      .deleteFp = (SdbDeleteFp)mndXnodeAgentActionDelete,
185
  };
186

187
  code = sdbSetTable(pMnode->pSdb, agents);
410,347✔
188
  if (code != 0) {
410,347✔
189
    return code;
×
190
  }
191

192
  SSdbTable userPass = {
410,347✔
193
      .sdbType = SDB_XNODE_USER_PASS,
194
      .keyType = SDB_KEY_INT32,
195
      .encodeFp = (SdbEncodeFp)mndXnodeUserPassActionEncode,
196
      .decodeFp = (SdbDecodeFp)mndXnodeUserPassActionDecode,
197
      .insertFp = (SdbInsertFp)mndXnodeUserPassActionInsert,
198
      .updateFp = (SdbUpdateFp)mndXnodeUserPassActionUpdate,
199
      .deleteFp = (SdbDeleteFp)mndXnodeUserPassActionDelete,
200
  };
201

202
  code = sdbSetTable(pMnode->pSdb, userPass);
410,347✔
203
  if (code != 0) {
410,347✔
204
    return code;
×
205
  }
206

207
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_XNODE, mndProcessCreateXnodeReq);
410,347✔
208
  mndSetMsgHandle(pMnode, TDMT_MND_UPDATE_XNODE, mndProcessUpdateXnodeReq);
410,347✔
209
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_XNODE, mndProcessDropXnodeReq);
410,347✔
210
  mndSetMsgHandle(pMnode, TDMT_MND_DRAIN_XNODE, mndProcessDrainXnodeReq);
410,347✔
211
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_XNODES, mndRetrieveXnodes);
410,347✔
212
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_XNODES, mndCancelGetNextXnode);
410,347✔
213

214
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_XNODE_TASK, mndProcessCreateXnodeTaskReq);
410,347✔
215
  mndSetMsgHandle(pMnode, TDMT_MND_START_XNODE_TASK, mndProcessStartXnodeTaskReq);
410,347✔
216
  mndSetMsgHandle(pMnode, TDMT_MND_STOP_XNODE_TASK, mndProcessStopXnodeTaskReq);
410,347✔
217
  mndSetMsgHandle(pMnode, TDMT_MND_UPDATE_XNODE_TASK, mndProcessUpdateXnodeTaskReq);
410,347✔
218
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_XNODE_TASK, mndProcessDropXnodeTaskReq);
410,347✔
219
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_XNODE_TASKS, mndRetrieveXnodeTasks);
410,347✔
220
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_XNODE_TASKS, mndCancelGetNextXnodeTask);
410,347✔
221

222
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_XNODE_JOB, mndProcessCreateXnodeJobReq);
410,347✔
223
  mndSetMsgHandle(pMnode, TDMT_MND_UPDATE_XNODE_JOB, mndProcessUpdateXnodeJobReq);
410,347✔
224
  mndSetMsgHandle(pMnode, TDMT_MND_REBALANCE_XNODE_JOB, mndProcessRebalanceXnodeJobReq);
410,347✔
225
  mndSetMsgHandle(pMnode, TDMT_MND_REBALANCE_XNODE_JOBS_WHERE, mndProcessRebalanceXnodeJobsWhereReq);
410,347✔
226
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_XNODE_JOB, mndProcessDropXnodeJobReq);
410,347✔
227
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_XNODE_JOBS, mndRetrieveXnodeJobs);
410,347✔
228
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_XNODE_JOBS, mndCancelGetNextXnodeJob);
410,347✔
229

230
  mndSetMsgHandle(pMnode, TDMT_MND_CREATE_XNODE_AGENT, mndProcessCreateXnodeAgentReq);
410,347✔
231
  mndSetMsgHandle(pMnode, TDMT_MND_UPDATE_XNODE_AGENT, mndProcessUpdateXnodeAgentReq);
410,347✔
232
  mndSetMsgHandle(pMnode, TDMT_MND_DROP_XNODE_AGENT, mndProcessDropXnodeAgentReq);
410,347✔
233
  mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_XNODE_AGENTS, mndRetrieveXnodeAgents);
410,347✔
234
  mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_XNODE_AGENTS, mndCancelGetNextXnodeAgent);
410,347✔
235

236
  return 0;
410,347✔
237
}
238

239
/** tools section **/
240

241
int32_t xnodeCheckPasswordFmt(const char *pwd) {
111✔
242
  if (strcmp(pwd, "taosdata") == 0) {
111✔
UNCOV
243
    return 0;
×
244
  }
245

246
  if (tsEnableStrongPassword == 0) {
111✔
247
    for (char c = *pwd; c != 0; c = *(++pwd)) {
×
248
      if (c == ' ' || c == '\'' || c == '\"' || c == '`' || c == '\\') {
×
249
        return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
250
      }
251
    }
252
    return 0;
×
253
  }
254

255
  int32_t len = strlen(pwd);
111✔
256
  if (len < TSDB_PASSWORD_MIN_LEN) {
111✔
257
    return TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY;
×
258
  }
259

260
  if (len > TSDB_PASSWORD_MAX_LEN) {
111✔
261
    return TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG;
×
262
  }
263

264
  if (taosIsComplexString(pwd)) {
111✔
265
    return 0;
111✔
266
  }
267

268
  return TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
269
}
270

271
static void swapFields(int32_t *newLen, char **ppNewStr, int32_t *oldLen, char **ppOldStr) {
23,121✔
272
  if (*newLen > 0) {
23,121✔
273
    int32_t tempLen = *newLen;
13,689✔
274
    *newLen = *oldLen;
13,689✔
275
    *oldLen = tempLen;
13,689✔
276

277
    char *tempStr = *ppNewStr;
13,689✔
278
    *ppNewStr = *ppOldStr;
13,689✔
279
    *ppOldStr = tempStr;
13,689✔
280
  }
281
}
23,121✔
282

283
/** xnode section **/
284

285
void mndCleanupXnode(SMnode *pMnode) {}
410,290✔
286

287
SXnodeObj *mndAcquireXnode(SMnode *pMnode, int32_t xnodeId) {
5,460✔
288
  SXnodeObj *pObj = sdbAcquire(pMnode->pSdb, SDB_XNODE, &xnodeId);
5,460✔
289
  if (pObj == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
5,460✔
290
    terrno = TSDB_CODE_MND_XNODE_NOT_EXIST;
5,460✔
291
  }
292
  return pObj;
5,460✔
293
}
294

295
void mndReleaseXnode(SMnode *pMnode, SXnodeObj *pObj) {
7,092✔
296
  SSdb *pSdb = pMnode->pSdb;
7,092✔
297
  sdbRelease(pSdb, pObj);
7,092✔
298
}
7,092✔
299

300
SSdbRaw *mndXnodeActionEncode(SXnodeObj *pObj) {
6,912✔
301
  int32_t code = 0;
6,912✔
302
  int32_t lino = 0;
6,912✔
303
  terrno = TSDB_CODE_OUT_OF_MEMORY;
6,912✔
304

305
  if (NULL == pObj) {
6,912✔
306
    terrno = TSDB_CODE_INVALID_PARA;
×
307
    return NULL;
×
308
  }
309

310
  int32_t rawDataLen = sizeof(SXnodeObj) + TSDB_XNODE_RESERVE_SIZE + pObj->urlLen + pObj->statusLen;
6,912✔
311

312
  SSdbRaw *pRaw = sdbAllocRaw(SDB_XNODE, TSDB_XNODE_VER_NUMBER, rawDataLen);
6,912✔
313
  if (pRaw == NULL) goto _OVER;
6,912✔
314

315
  int32_t dataPos = 0;
6,912✔
316
  SDB_SET_INT32(pRaw, dataPos, pObj->id, _OVER)
6,912✔
317
  SDB_SET_INT32(pRaw, dataPos, pObj->urlLen, _OVER)
6,912✔
318
  SDB_SET_BINARY(pRaw, dataPos, pObj->url, pObj->urlLen, _OVER)
6,912✔
319
  SDB_SET_INT32(pRaw, dataPos, pObj->statusLen, _OVER)
6,912✔
320
  SDB_SET_BINARY(pRaw, dataPos, pObj->status, pObj->statusLen, _OVER)
6,912✔
321
  SDB_SET_INT64(pRaw, dataPos, pObj->createTime, _OVER)
6,912✔
322
  SDB_SET_INT64(pRaw, dataPos, pObj->updateTime, _OVER)
6,912✔
323

324
  SDB_SET_RESERVE(pRaw, dataPos, TSDB_XNODE_RESERVE_SIZE, _OVER)
6,912✔
325

326
  terrno = 0;
6,912✔
327

328
_OVER:
6,912✔
329
  if (terrno != 0) {
6,912✔
330
    mError("xnode:%d, failed to encode to raw:%p since %s", pObj->id, pRaw, terrstr());
×
331
    sdbFreeRaw(pRaw);
×
332
    return NULL;
×
333
  }
334

335
  mTrace("xnode:%d, encode to raw:%p, row:%p", pObj->id, pRaw, pObj);
6,912✔
336
  return pRaw;
6,912✔
337
}
338

339
SSdbRow *mndXnodeActionDecode(SSdbRaw *pRaw) {
4,932✔
340
  int32_t code = 0;
4,932✔
341
  int32_t lino = 0;
4,932✔
342
  terrno = TSDB_CODE_OUT_OF_MEMORY;
4,932✔
343
  SSdbRow   *pRow = NULL;
4,932✔
344
  SXnodeObj *pObj = NULL;
4,932✔
345

346
  if (NULL == pRaw) {
4,932✔
347
    terrno = TSDB_CODE_INVALID_PARA;
×
348
    return NULL;
×
349
  }
350

351
  int8_t sver = 0;
4,932✔
352
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
4,932✔
353

354
  if (sver != TSDB_XNODE_VER_NUMBER) {
4,932✔
355
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
356
    goto _OVER;
×
357
  }
358

359
  pRow = sdbAllocRow(sizeof(SXnodeObj));
4,932✔
360
  if (pRow == NULL) goto _OVER;
4,932✔
361

362
  pObj = sdbGetRowObj(pRow);
4,932✔
363
  if (pObj == NULL) goto _OVER;
4,932✔
364

365
  int32_t dataPos = 0;
4,932✔
366
  SDB_GET_INT32(pRaw, dataPos, &pObj->id, _OVER)
4,932✔
367
  SDB_GET_INT32(pRaw, dataPos, &pObj->urlLen, _OVER)
4,932✔
368
  if (pObj->urlLen > 0) {
4,932✔
369
    pObj->url = taosMemoryCalloc(1, pObj->urlLen + 1);
4,932✔
370
    if (pObj->url == NULL) goto _OVER;
4,932✔
371
    SDB_GET_BINARY(pRaw, dataPos, pObj->url, pObj->urlLen, _OVER)
4,932✔
372
  } else {
373
    pObj->url = NULL;
×
374
  }
375
  SDB_GET_INT32(pRaw, dataPos, &pObj->statusLen, _OVER)
4,932✔
376
  if (pObj->statusLen > 0) {
4,932✔
NEW
377
    pObj->status = taosMemoryCalloc(1, pObj->statusLen + 1);
×
378
    if (pObj->status == NULL) goto _OVER;
×
379
    SDB_GET_BINARY(pRaw, dataPos, pObj->status, pObj->statusLen, _OVER)
×
380
  } else {
381
    pObj->status = NULL;
4,932✔
382
  }
383
  SDB_GET_INT64(pRaw, dataPos, &pObj->createTime, _OVER)
4,932✔
384
  SDB_GET_INT64(pRaw, dataPos, &pObj->updateTime, _OVER)
4,932✔
385

386
  SDB_GET_RESERVE(pRaw, dataPos, TSDB_XNODE_RESERVE_SIZE, _OVER)
4,932✔
387

388
  terrno = 0;
4,932✔
389

390
_OVER:
4,932✔
391
  if (terrno != 0) {
4,932✔
392
    mError("xnode:%d, failed to decode from raw:%p since %s", pObj == NULL ? 0 : pObj->id, pRaw, terrstr());
×
393
    if (pObj != NULL) {
×
394
      taosMemoryFreeClear(pObj->url);
×
395
    }
396
    taosMemoryFreeClear(pRow);
×
397
    return NULL;
×
398
  }
399

400
  mTrace("xnode:%d, decode from raw:%p, row:%p", pObj->id, pRaw, pObj);
4,932✔
401
  return pRow;
4,932✔
402
}
403

404
static void mndFreeXnode(SXnodeObj *pObj) {
6,387✔
405
  if (pObj == NULL) return;
6,387✔
406
  if (pObj->url != NULL) {
6,387✔
407
    taosMemoryFreeClear(pObj->url);
6,387✔
408
  }
409
  if (pObj->status != NULL) {
6,387✔
410
    taosMemoryFreeClear(pObj->status);
×
411
  }
412
}
413

414
int32_t mndXnodeActionInsert(SSdb *pSdb, SXnodeObj *pObj) {
1,455✔
415
  mDebug("xnode:%d, perform insert action, row:%p", pObj->id, pObj);
1,455✔
416
  return 0;
1,455✔
417
}
418

419
int32_t mndXnodeActionDelete(SSdb *pSdb, SXnodeObj *pObj) {
4,932✔
420
  mDebug("xnode:%d, perform delete action, row:%p", pObj->id, pObj);
4,932✔
421
  mndFreeXnode(pObj);
4,932✔
422
  return 0;
4,932✔
423
}
424

425
int32_t mndXnodeActionUpdate(SSdb *pSdb, SXnodeObj *pOld, SXnodeObj *pNew) {
2,466✔
426
  mDebug("xnode:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew);
2,466✔
427

428
  taosWLockLatch(&pOld->lock);
2,466✔
429
  swapFields(&pNew->statusLen, &pNew->status, &pOld->statusLen, &pOld->status);
2,466✔
430
  if (pNew->updateTime > pOld->updateTime) {
2,466✔
431
    pOld->updateTime = pNew->updateTime;
×
432
  }
433
  taosWUnLockLatch(&pOld->lock);
2,466✔
434
  return 0;
2,466✔
435
}
436

437
void mndReleaseXnodeUserPass(SMnode *pMnode, SXnodeUserPassObj *pObj) {
486✔
438
  SSdb *pSdb = pMnode->pSdb;
486✔
439
  sdbRelease(pSdb, pObj);
486✔
440
}
486✔
441

442
SXnodeUserPassObj *mndAcquireFirstXnodeUserPass(SMnode *pMnode) {
378,543✔
443
  SSdb *pSdb = pMnode->pSdb;
378,543✔
444

445
  void *pIter = NULL;
378,543✔
446
  while (1) {
×
447
    SXnodeUserPassObj *pObj = NULL;
378,543✔
448
    pIter = sdbFetch(pSdb, SDB_XNODE_USER_PASS, pIter, (void **)&pObj);
378,543✔
449
    if (pIter == NULL) break;
378,543✔
450

451
    if (pObj != NULL) {
486✔
452
      sdbCancelFetch(pSdb, pIter);
486✔
453
      return pObj;
486✔
454
    }
455

456
    sdbRelease(pSdb, pObj);
×
457
  }
458
  terrno = TSDB_CODE_MND_XNODE_USER_PASS_NOT_EXIST;
378,057✔
459
  return NULL;
378,057✔
460
}
461

462
static int32_t mndSetCreateXnodeUserPassRedoLogs(STrans *pTrans, SXnodeUserPassObj *pObj) {
192✔
463
  int32_t  code = 0;
192✔
464
  SSdbRaw *pRedoRaw = mndXnodeUserPassActionEncode(pObj);
192✔
465
  if (pRedoRaw == NULL) {
192✔
466
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
467
    if (terrno != 0) code = terrno;
×
468
    TAOS_RETURN(code);
×
469
  }
470
  TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
192✔
471
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING));
192✔
472
  TAOS_RETURN(code);
192✔
473
}
474

475
static int32_t mndSetCreateXnodeUserPassCommitLogs(STrans *pTrans, SXnodeUserPassObj *pObj) {
678✔
476
  int32_t  code = 0;
678✔
477
  SSdbRaw *pCommitRaw = mndXnodeUserPassActionEncode(pObj);
678✔
478
  if (pCommitRaw == NULL) {
678✔
479
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
480
    if (terrno != 0) code = terrno;
×
481
    TAOS_RETURN(code);
×
482
  }
483
  TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
678✔
484
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
678✔
485
  TAOS_RETURN(code);
678✔
486
}
487

488
static int32_t mndSetCreateXnodeRedoLogs(STrans *pTrans, SXnodeObj *pObj) {
1,455✔
489
  int32_t  code = 0;
1,455✔
490
  SSdbRaw *pRedoRaw = mndXnodeActionEncode(pObj);
1,455✔
491
  if (pRedoRaw == NULL) {
1,455✔
492
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
493
    if (terrno != 0) code = terrno;
×
494
    TAOS_RETURN(code);
×
495
  }
496
  TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
1,455✔
497
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING));
1,455✔
498
  TAOS_RETURN(code);
1,455✔
499
}
500

501
static int32_t mndSetCreateXnodeUndoLogs(STrans *pTrans, SXnodeObj *pObj) {
1,455✔
502
  int32_t  code = 0;
1,455✔
503
  SSdbRaw *pUndoRaw = mndXnodeActionEncode(pObj);
1,455✔
504
  if (pUndoRaw == NULL) {
1,455✔
505
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
506
    if (terrno != 0) code = terrno;
×
507
    TAOS_RETURN(code);
×
508
  }
509
  TAOS_CHECK_RETURN(mndTransAppendUndolog(pTrans, pUndoRaw));
1,455✔
510
  TAOS_CHECK_RETURN(sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED));
1,455✔
511
  TAOS_RETURN(code);
1,455✔
512
}
513

514
static int32_t mndSetCreateXnodeCommitLogs(STrans *pTrans, SXnodeObj *pObj) {
1,455✔
515
  int32_t  code = 0;
1,455✔
516
  SSdbRaw *pCommitRaw = mndXnodeActionEncode(pObj);
1,455✔
517
  if (pCommitRaw == NULL) {
1,455✔
518
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
519
    if (terrno != 0) code = terrno;
×
520
    TAOS_RETURN(code);
×
521
  }
522
  TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
1,455✔
523
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
1,455✔
524
  TAOS_RETURN(code);
1,455✔
525
}
526

527
static int32_t mndCreateXnode(SMnode *pMnode, SRpcMsg *pReq, SMCreateXnodeReq *pCreate) {
1,455✔
528
  int32_t code = 0, lino = 0;
1,455✔
529
  STrans *pTrans = NULL;
1,455✔
530

531
  SXnodeObj xnodeObj = {0};
1,455✔
532
  xnodeObj.id = sdbGetMaxId(pMnode->pSdb, SDB_XNODE);
1,455✔
533

534
  xnodeObj.urlLen = pCreate->urlLen;
1,455✔
535
  if (xnodeObj.urlLen > TSDB_XNODE_URL_LEN) {
1,455✔
536
    code = TSDB_CODE_MND_XNODE_TOO_LONG_URL;
×
NEW
537
    lino = __LINE__;
×
UNCOV
538
    goto _OVER;
×
539
  }
540
  xnodeObj.url = taosMemoryCalloc(1, pCreate->urlLen);
1,455✔
541
  if (xnodeObj.url == NULL) goto _OVER;
1,455✔
542
  (void)memcpy(xnodeObj.url, pCreate->url, pCreate->urlLen);
1,455✔
543

544
  xnodeObj.createTime = taosGetTimestampMs();
1,455✔
545
  xnodeObj.updateTime = xnodeObj.createTime;
1,455✔
546
  mInfo("create xnode, xnode.id:%d, xnode.url: %s, xnode.time:%" PRId64, xnodeObj.id, xnodeObj.url,
1,455✔
547
        xnodeObj.createTime);
548

549
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-xnode");
1,455✔
550
  if (pTrans == NULL) {
1,455✔
551
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
552
    if (terrno != 0) code = terrno;
×
553
    mInfo("failed to create transaction for xnode:%s, code:0x%x:%s", pCreate->url, code, tstrerror(code));
×
NEW
554
    lino = __LINE__;
×
UNCOV
555
    goto _OVER;
×
556
  }
557
  mndTransSetSerial(pTrans);
1,455✔
558

559
  mInfo("trans:%d, used to create xnode:%s as xnode:%d", pTrans->id, pCreate->url, xnodeObj.id);
1,455✔
560

561
  TAOS_CHECK_GOTO(mndSetCreateXnodeRedoLogs(pTrans, &xnodeObj), NULL, _OVER);
1,455✔
562
  TAOS_CHECK_GOTO(mndSetCreateXnodeUndoLogs(pTrans, &xnodeObj), NULL, _OVER);
1,455✔
563
  TAOS_CHECK_GOTO(mndSetCreateXnodeCommitLogs(pTrans, &xnodeObj), NULL, _OVER);
1,455✔
564
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
1,455✔
565
  code = TSDB_CODE_ACTION_IN_PROGRESS;
1,455✔
566

567
_OVER:
1,455✔
568
  if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,455✔
NEW
569
    mError("xnode:failed create xnode since %s, line:%d", tstrerror(code), lino);
×
570
  }
571
  mndFreeXnode(&xnodeObj);
1,455✔
572
  mndTransDrop(pTrans);
1,455✔
573
  TAOS_RETURN(code);
1,455✔
574
}
575

576
static SXnodeObj *mndAcquireXnodeByURL(SMnode *pMnode, char *url) {
9,171✔
577
  SSdb *pSdb = pMnode->pSdb;
9,171✔
578

579
  void *pIter = NULL;
9,171✔
580
  while (1) {
17,652✔
581
    SXnodeObj *pXnode = NULL;
26,823✔
582
    pIter = sdbFetch(pSdb, SDB_XNODE, pIter, (void **)&pXnode);
26,823✔
583
    if (pIter == NULL) break;
26,823✔
584

585
    if (strcasecmp(url, pXnode->url) == 0) {
22,338✔
586
      sdbCancelFetch(pSdb, pIter);
4,686✔
587
      return pXnode;
4,686✔
588
    }
589

590
    sdbRelease(pSdb, pXnode);
17,652✔
591
  }
592

593
  mError("xnode:%s, not found", url);
4,485✔
594
  terrno = TSDB_CODE_MND_XNODE_NOT_EXIST;
4,485✔
595
  return NULL;
4,485✔
596
}
597

598
static int32_t mndStoreXnodeUserPassToken(SMnode *pMnode, SRpcMsg *pReq, SMCreateXnodeReq *pCreate) {
192✔
599
  int32_t code = 0, lino = 0;
192✔
600
  STrans *pTrans = NULL;
192✔
601

602
  SXnodeUserPassObj upObj = {0};
192✔
603
  upObj.id = sdbGetMaxId(pMnode->pSdb, SDB_XNODE_USER_PASS);
192✔
604

605
  if (pCreate->user) {
192✔
606
    upObj.userLen = pCreate->userLen;
111✔
607
    if (upObj.userLen > TSDB_USER_LEN) {
111✔
NEW
608
      code = TSDB_CODE_MND_USER_NOT_AVAILABLE;
×
NEW
609
      lino = __LINE__;
×
NEW
610
      goto _OVER;
×
611
    }
612
    upObj.user = taosMemoryCalloc(1, pCreate->userLen);
111✔
613
    if (upObj.user == NULL) goto _OVER;
111✔
614
    (void)memcpy(upObj.user, pCreate->user, pCreate->userLen);
111✔
615
  }
616
  if (pCreate->pass) {
192✔
617
    upObj.passLen = pCreate->passLen;
111✔
618
    if (upObj.passLen > TSDB_USER_PASSWORD_LONGLEN) {
111✔
NEW
619
      code = TSDB_CODE_MND_INVALID_PASS_FORMAT;
×
NEW
620
      lino = __LINE__;
×
NEW
621
      goto _OVER;
×
622
    }
623
    upObj.pass = taosMemoryCalloc(1, pCreate->passLen);
111✔
624
    if (upObj.pass == NULL) goto _OVER;
111✔
625
    (void)memcpy(upObj.pass, pCreate->pass, pCreate->passLen);
111✔
626
  }
627

628
  if (pCreate->token.ptr) {
192✔
629
    upObj.tokenLen = pCreate->token.len + 1;
81✔
630
    upObj.token = taosMemoryCalloc(1, upObj.tokenLen);
81✔
631
    if (upObj.token == NULL) goto _OVER;
81✔
632
    (void)memcpy(upObj.token, pCreate->token.ptr, pCreate->token.len);
81✔
633
  }
634

635
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-userpass");
192✔
636
  if (pTrans == NULL) {
192✔
637
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
638
    if (terrno != 0) code = terrno;
×
639
    mInfo("failed to create transaction for xnode:%s, code:0x%x:%s", pCreate->url, code, tstrerror(code));
×
NEW
640
    lino = __LINE__;
×
UNCOV
641
    goto _OVER;
×
642
  }
643
  mndTransSetSerial(pTrans);
192✔
644

645
  mInfo("trans:%d, used to create xnode:%s as xnode:%d", pTrans->id, pCreate->url, upObj.id);
192✔
646

647
  TAOS_CHECK_GOTO(mndSetCreateXnodeUserPassRedoLogs(pTrans, &upObj), NULL, _OVER);
192✔
648
  TAOS_CHECK_GOTO(mndSetCreateXnodeUserPassCommitLogs(pTrans, &upObj), NULL, _OVER);
192✔
649
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
192✔
650
  code = TSDB_CODE_ACTION_IN_PROGRESS;
192✔
651

652
_OVER:
192✔
653
  if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_ACTION_IN_PROGRESS) {
192✔
NEW
654
    mError("xnode failed to store userpass since %s, line:%d", tstrerror(code), lino);
×
655
  }
656
  taosMemoryFreeClear(upObj.user);
192✔
657
  taosMemoryFreeClear(upObj.pass);
192✔
658
  taosMemoryFreeClear(upObj.token);
192✔
659
  mndTransDrop(pTrans);
192✔
660
  TAOS_RETURN(code);
192✔
661
}
662

663
#ifndef TD_ENTERPRISE
664

665
int32_t mndXnodeCreateDefaultToken(SRpcMsg* pReq, char** ppToken) {
666
  return TSDB_CODE_OPS_NOT_SUPPORT;
667
}
668

669
#endif
670

671
static int32_t httpCreateXnode(SXnodeObj *pObj) {
1,455✔
672
  int32_t code = 0;
1,455✔
673
  SJson  *pJson = NULL;
1,455✔
674
  SJson  *postContent = NULL;
1,455✔
675
  char   *pContStr = NULL;
1,455✔
676

677
  char xnodeUrl[TSDB_XNODE_URL_LEN + 1] = {0};
1,455✔
678
  snprintf(xnodeUrl, TSDB_XNODE_URL_LEN + 1, "%s/xnode", XNODED_PIPE_SOCKET_URL);
1,455✔
679
  postContent = tjsonCreateObject();
1,455✔
680
  if (postContent == NULL) {
1,455✔
681
    code = terrno;
×
682
    goto _OVER;
×
683
  }
684
  TAOS_CHECK_GOTO(tjsonAddDoubleToObject(postContent, "id", (double)pObj->id), NULL, _OVER);
1,455✔
685
  TAOS_CHECK_GOTO(tjsonAddStringToObject(postContent, "url", pObj->url), NULL, _OVER);
1,455✔
686
  pContStr = tjsonToUnformattedString(postContent);
1,455✔
687
  if (pContStr == NULL) {
1,455✔
688
    code = terrno;
×
689
    goto _OVER;
×
690
  }
691
  pJson = mndSendReqRetJson(xnodeUrl, HTTP_TYPE_POST, defaultTimeout, pContStr, strlen(pContStr));
1,455✔
692

693
_OVER:
1,455✔
694
  if (postContent != NULL) {
1,455✔
695
    tjsonDelete(postContent);
1,455✔
696
  }
697
  if (pContStr != NULL) {
1,455✔
698
    taosMemFree(pContStr);
1,455✔
699
  }
700
  if (pJson != NULL) {
1,455✔
701
    tjsonDelete(pJson);
×
702
  }
703
  TAOS_RETURN(code);
1,455✔
704
}
705

706
static int32_t mndProcessCreateXnodeReq(SRpcMsg *pReq) {
3,675✔
707
  SMnode          *pMnode = pReq->info.node;
3,675✔
708
  int32_t          code = 0, lino = 0;
3,675✔
709
  SXnodeObj       *pObj = NULL;
3,675✔
710
  SMCreateXnodeReq createReq = {0};
3,675✔
711
  char            *pToken = NULL;
3,675✔
712

713
  if ((code = grantCheck(TSDB_GRANT_XNODE)) != TSDB_CODE_SUCCESS) {
3,675✔
714
    mError("failed to create xnode, code:%s", tstrerror(code));
×
715
    goto _OVER;
×
716
  }
717

718
  TAOS_CHECK_GOTO(tDeserializeSMCreateXnodeReq(pReq->pCont, pReq->contLen, &createReq), &lino, _OVER);
3,675✔
719

720
  mDebug("xnode:%s, start to create", createReq.url);
3,675✔
721
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_CREATE_XNODE), &lino, _OVER);
3,675✔
722

723
  pObj = mndAcquireXnodeByURL(pMnode, createReq.url);
3,675✔
724
  if (pObj != NULL) {
3,675✔
725
    code = TSDB_CODE_MND_XNODE_ALREADY_EXIST;
2,220✔
726
    goto _OVER;
2,220✔
727
  }
728

729
  int32_t numOfRows = sdbGetSize(pMnode->pSdb, SDB_XNODE_USER_PASS);
1,455✔
730
  if (numOfRows <= 0) {
1,455✔
731
    if (createReq.token.ptr != NULL) {
192✔
NEW
732
      (void)mndCreateXnode(pMnode, NULL, &createReq);
×
NEW
733
      code = mndStoreXnodeUserPassToken(pMnode, pReq, &createReq);
×
NEW
734
      if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
×
NEW
735
        lino = __LINE__;
×
NEW
736
        goto _OVER;
×
737
      }
NEW
738
      mndStartXnoded(pMnode, NULL, NULL, createReq.token.ptr);
×
739
    } else if (createReq.user != NULL) {
192✔
740
      TAOS_CHECK_GOTO(xnodeCheckPasswordFmt(createReq.pass), &lino, _OVER);
111✔
741
      (void)mndCreateXnode(pMnode, NULL, &createReq);
111✔
742
      code = mndStoreXnodeUserPassToken(pMnode, pReq, &createReq);
111✔
743
      if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
111✔
NEW
744
        lino = __LINE__;
×
NEW
745
        goto _OVER;
×
746
      }
747
      mndStartXnoded(pMnode, createReq.user, createReq.pass, NULL);
111✔
748
    } else {
749
      code = mndXnodeCreateDefaultToken(pReq, &pToken);
81✔
750
      if (code == TSDB_CODE_MND_TOKEN_ALREADY_EXIST) {
81✔
NEW
751
        code = 0;
×
752
      }
753
      if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
81✔
NEW
754
        lino = __LINE__;
×
NEW
755
        goto _OVER;
×
756
      }
757
      (void)mndCreateXnode(pMnode, NULL, &createReq);
81✔
758
      createReq.token = xCreateCowStr(strlen(pToken), pToken, false);
81✔
759
      (void)mndStoreXnodeUserPassToken(pMnode, NULL, &createReq);
81✔
760
      mndStartXnoded(pMnode, NULL, NULL, createReq.token.ptr);
81✔
761
    }
762
  } else {
763
    code = mndCreateXnode(pMnode, pReq, &createReq);
1,263✔
764
    if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,263✔
NEW
765
      lino = __LINE__;
×
UNCOV
766
      goto _OVER;
×
767
    }
768
  }
769

770
  taosMsleep(defaultTimeout);
1,455✔
771
  pObj = mndAcquireXnodeByURL(pMnode, createReq.url);
1,455✔
772
  if (pObj == NULL) {
1,455✔
773
    code = TSDB_CODE_MND_XNODE_NOT_EXIST;
×
774
    goto _OVER;
×
775
  }
776
  // send request
777
  (void)httpCreateXnode(pObj);
1,455✔
778

779
_OVER:
3,675✔
780
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
3,675✔
781
    mError("xnode:%s, failed to create since %s, line:%d", createReq.url, tstrerror(code), lino);
2,220✔
782
  }
783
  taosMemoryFreeClear(pToken);
3,675✔
784
  mndReleaseXnode(pMnode, pObj);
3,675✔
785
  tFreeSMCreateXnodeReq(&createReq);
3,675✔
786
  TAOS_RETURN(code);
3,675✔
787
}
788

789
static int32_t mndUpdateXnode(SMnode *pMnode, SXnodeObj *pXnode, SRpcMsg *pReq) {
×
790
  mInfo("xnode:%d, start to update", pXnode->id);
×
791
  int32_t   code = -1;
×
792
  STrans   *pTrans = NULL;
×
793
  SXnodeObj xnodeObj = {0};
×
794
  xnodeObj.id = pXnode->id;
×
795
  xnodeObj.updateTime = taosGetTimestampMs();
×
796

797
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "update-xnode");
×
798
  if (pTrans == NULL) {
×
799
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
800
    if (terrno != 0) code = terrno;
×
801
    goto _OVER;
×
802
  }
803
  mInfo("trans:%d, used to update xnode:%d", pTrans->id, xnodeObj.id);
×
804

805
  TAOS_CHECK_GOTO(mndSetCreateXnodeCommitLogs(pTrans, &xnodeObj), NULL, _OVER);
×
806
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
×
807
  code = 0;
×
808

809
_OVER:
×
810
  mndFreeXnode(&xnodeObj);
×
811
  mndTransDrop(pTrans);
×
812
  TAOS_RETURN(code);
×
813
}
814

815
static int32_t mndUpdateXnodeUserPassToken(SMnode *pMnode, SRpcMsg *pReq, SMUpdateXnodeReq *pUpdate) {
486✔
816
  int32_t           code = 0, lino = 0;
486✔
817
  STrans           *pTrans = NULL;
486✔
818
  SXnodeUserPassObj upObj = {0};
486✔
819
  upObj.id = pUpdate->id;
486✔
820
  upObj.updateTime = taosGetTimestampMs();
486✔
821

822
  if (pUpdate->user.ptr != NULL) {
486✔
823
    upObj.userLen = pUpdate->user.len + 1;
324✔
824
    upObj.user = taosMemoryCalloc(1, upObj.userLen);
324✔
825
    if (upObj.user == NULL) goto _OVER;
324✔
826
    (void)memcpy(upObj.user, pUpdate->user.ptr, pUpdate->user.len);
324✔
827
  }
828
  if (pUpdate->pass.ptr != NULL) {
486✔
829
    upObj.passLen = pUpdate->pass.len + 1;
324✔
830
    upObj.pass = taosMemoryCalloc(1, upObj.passLen);
324✔
831
    if (upObj.pass == NULL) goto _OVER;
324✔
832
    (void)memcpy(upObj.pass, pUpdate->pass.ptr, pUpdate->pass.len);
324✔
833
  }
834
  if (pUpdate->token.ptr != NULL) {
486✔
835
    upObj.tokenLen = pUpdate->token.len + 1;
162✔
836
    upObj.token = taosMemoryCalloc(1, upObj.tokenLen);
162✔
837
    if (upObj.token == NULL) goto _OVER;
162✔
838
    (void)memcpy(upObj.token, pUpdate->token.ptr, pUpdate->token.len);
162✔
839
  }
840

841
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "update-xnode-userpass");
486✔
842
  if (pTrans == NULL) {
486✔
NEW
843
    code = terrno;
×
NEW
844
    lino = __LINE__;
×
NEW
845
    goto _OVER;
×
846
  }
847
  mDebug("trans:%d, used to update xnode userpass or token:%d", pTrans->id, upObj.id);
486✔
848

849
  TAOS_CHECK_GOTO(mndSetCreateXnodeUserPassCommitLogs(pTrans, &upObj), NULL, _OVER);
486✔
850
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
486✔
851
  code = TSDB_CODE_ACTION_IN_PROGRESS;
486✔
852

853
_OVER:
486✔
854
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
486✔
NEW
855
    mError("xnode:failed to update xnode %d since %s, line:%d", upObj.id, tstrerror(code), lino);
×
856
  }
857
  taosMemoryFreeClear(upObj.user);
486✔
858
  taosMemoryFreeClear(upObj.pass);
486✔
859
  taosMemoryFreeClear(upObj.token);
486✔
860
  mndTransDrop(pTrans);
486✔
861
  TAOS_RETURN(code);
486✔
862
}
863

864
static int32_t mndProcessUpdateXnodeReq(SRpcMsg *pReq) {
486✔
865
  SMnode          *pMnode = pReq->info.node;
486✔
866
  int32_t          code = 0;
486✔
867
  SXnodeObj       *pObj = NULL;
486✔
868
  SMUpdateXnodeReq updateReq = {0};
486✔
869

870
  TAOS_CHECK_GOTO(tDeserializeSMUpdateXnodeReq(pReq->pCont, pReq->contLen, &updateReq), NULL, _OVER);
486✔
871
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_UPDATE_XNODE), NULL, _OVER);
486✔
872

873
  if (updateReq.token.ptr != NULL || (updateReq.user.ptr != NULL && updateReq.pass.ptr != NULL)) {
486✔
874
    code = mndUpdateXnodeUserPassToken(pMnode, pReq, &updateReq);
486✔
875
    if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
486✔
UNCOV
876
      goto _OVER;
×
877
    }
878
    mndRestartXnoded(pMnode);
486✔
879
  }
880

881
_OVER:
486✔
882
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
486✔
NEW
883
    mError("xnode:%d, failed to update since %s", updateReq.id, tstrerror(code));
×
884
  }
885
  mndReleaseXnode(pMnode, pObj);
486✔
886
  tFreeSMUpdateXnodeReq(&updateReq);
486✔
887
  TAOS_RETURN(code);
486✔
888
}
889

890
static int32_t mndSetDropXnodeRedoLogs(STrans *pTrans, SXnodeObj *pObj) {
1,011✔
891
  int32_t  code = 0;
1,011✔
892
  SSdbRaw *pRedoRaw = mndXnodeActionEncode(pObj);
1,011✔
893
  if (pRedoRaw == NULL) {
1,011✔
894
    code = terrno;
×
895
    TAOS_RETURN(code);
×
896
  }
897

898
  TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
1,011✔
899
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING));
1,011✔
900
  TAOS_RETURN(code);
1,011✔
901
}
902

903
static int32_t mndSetDropXnodeCommitLogs(STrans *pTrans, SXnodeObj *pObj) {
1,011✔
904
  int32_t  code = 0;
1,011✔
905
  SSdbRaw *pCommitRaw = mndXnodeActionEncode(pObj);
1,011✔
906
  if (pCommitRaw == NULL) {
1,011✔
907
    code = terrno;
×
908
    TAOS_RETURN(code);
×
909
  }
910

911
  TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
1,011✔
912
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED));
1,011✔
913
  TAOS_RETURN(code);
1,011✔
914
}
915

916
static int32_t mndSetDropXnodeInfoToTrans(SMnode *pMnode, STrans *pTrans, SXnodeObj *pObj, bool force) {
1,011✔
917
  if (pObj == NULL) return 0;
1,011✔
918
  TAOS_CHECK_RETURN(mndSetDropXnodeRedoLogs(pTrans, pObj));
1,011✔
919
  TAOS_CHECK_RETURN(mndSetDropXnodeCommitLogs(pTrans, pObj));
1,011✔
920
  return 0;
1,011✔
921
}
922

923
static int32_t mndDropXnode(SMnode *pMnode, SRpcMsg *pReq, SXnodeObj *pObj) {
1,011✔
924
  int32_t code = 0;
1,011✔
925
  int32_t lino = 0;
1,011✔
926

927
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq, "drop-xnode");
1,011✔
928
  TSDB_CHECK_NULL(pTrans, code, lino, _OVER, terrno);
1,011✔
929

930
  mndTransSetSerial(pTrans);
1,011✔
931
  mDebug("trans:%d, to drop xnode:%d", pTrans->id, pObj->id);
1,011✔
932

933
  code = mndSetDropXnodeInfoToTrans(pMnode, pTrans, pObj, false);
1,011✔
934
  TSDB_CHECK_CODE(code, lino, _OVER);
1,011✔
935

936
  code = mndTransPrepare(pMnode, pTrans);
1,011✔
937

938
_OVER:
1,011✔
939
  mndTransDrop(pTrans);
1,011✔
940
  TAOS_RETURN(code);
1,011✔
941
}
942

943
static int32_t mndDrainXnode(SMnode *pMnode, SRpcMsg *pReq, SXnodeObj *pObj) {
×
944
  int32_t code = 0;
×
945
  int32_t lino = 0;
×
946

947
  SXnodeObj xnodeObj = {0};
×
948
  xnodeObj.id = pObj->id;
×
949
  xnodeObj.status = "drain";
×
950
  xnodeObj.statusLen = strlen(xnodeObj.status) + 1;
×
951
  xnodeObj.updateTime = taosGetTimestampMs();
×
952

953
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq, "drain-xnode");
×
954
  TSDB_CHECK_NULL(pTrans, code, lino, _OVER, terrno);
×
955

956
  mndTransSetSerial(pTrans);
×
957
  mDebug("trans:%d, to drain xnode:%d", pTrans->id, xnodeObj.id);
×
958

959
  TAOS_CHECK_GOTO(mndSetCreateXnodeCommitLogs(pTrans, &xnodeObj), NULL, _OVER);
×
960
  code = mndTransPrepare(pMnode, pTrans);
×
961

962
_OVER:
×
NEW
963
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
×
NEW
964
    mError("xnode:%d, failed to drain since %s", xnodeObj.id, tstrerror(code));
×
965
  }
966
  mndTransDrop(pTrans);
×
967
  TAOS_RETURN(code);
×
968
}
969

970
static int32_t mndProcessDropXnodeReq(SRpcMsg *pReq) {
7,581✔
971
  SMnode        *pMnode = pReq->info.node;
7,581✔
972
  int32_t        code = -1;
7,581✔
973
  SXnodeObj     *pObj = NULL;
7,581✔
974
  SMDropXnodeReq dropReq = {0};
7,581✔
975
  SJson         *pJson = NULL;
7,581✔
976

977
  TAOS_CHECK_GOTO(tDeserializeSMDropXnodeReq(pReq->pCont, pReq->contLen, &dropReq), NULL, _OVER);
7,581✔
978

979
  mDebug("xnode:%d, start to drop", dropReq.xnodeId);
7,581✔
980
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_DROP_XNODE), NULL, _OVER);
7,581✔
981

982
  if (dropReq.xnodeId <= 0 && (dropReq.url == NULL || strlen(dropReq.url) <= 0)) {
7,581✔
983
    code = TSDB_CODE_MND_XNODE_INVALID_MSG;
×
984
    goto _OVER;
×
985
  }
986

987
  if (dropReq.url != NULL && strlen(dropReq.url) > 0) {
7,581✔
988
    pObj = mndAcquireXnodeByURL(pMnode, dropReq.url);
4,041✔
989
    if (pObj == NULL) {
4,041✔
990
      code = terrno;
3,030✔
991
      goto _OVER;
3,030✔
992
    }
993
  } else {
994
    pObj = mndAcquireXnode(pMnode, dropReq.xnodeId);
3,540✔
995
    if (pObj == NULL) {
3,540✔
996
      code = terrno;
3,540✔
997
      goto _OVER;
3,540✔
998
    }
999
  }
1000

1001
  // send request
1002
  char xnodeUrl[TSDB_XNODE_URL_LEN] = {0};
1,011✔
1003
  snprintf(xnodeUrl, TSDB_XNODE_URL_LEN, "%s/xnode/%d?force=%s", XNODED_PIPE_SOCKET_URL, pObj->id,
1,011✔
1004
           dropReq.force ? "true" : "false");
1,011✔
1005
  pJson = mndSendReqRetJson(xnodeUrl, HTTP_TYPE_DELETE, defaultTimeout, NULL, 0);
1,011✔
1006

1007
  code = mndDropXnode(pMnode, pReq, pObj);
1,011✔
1008
  if (code == 0) {
1,011✔
1009
    code = TSDB_CODE_ACTION_IN_PROGRESS;
1,011✔
1010
  }
1011

1012
_OVER:
7,581✔
1013
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
7,581✔
1014
    mError("xnode:%d, failed to drop since %s", dropReq.xnodeId, tstrerror(code));
6,570✔
1015
  }
1016
  if (pJson != NULL) {
7,581✔
1017
    tjsonDelete(pJson);
×
1018
  }
1019
  if (pObj != NULL) {
7,581✔
1020
    mndReleaseXnode(pMnode, pObj);
1,011✔
1021
  }
1022
  tFreeSMDropXnodeReq(&dropReq);
7,581✔
1023
  TAOS_RETURN(code);
7,581✔
1024
}
1025

1026
static int32_t mndProcessDrainXnodeReq(SRpcMsg *pReq) {
1,920✔
1027
  SMnode         *pMnode = pReq->info.node;
1,920✔
1028
  int32_t         code = 0;
1,920✔
1029
  SXnodeObj      *pObj = NULL;
1,920✔
1030
  SMDrainXnodeReq drainReq = {0};
1,920✔
1031
  SJson          *pJson = NULL;
1,920✔
1032
  SJson          *postContent = NULL;
1,920✔
1033
  char           *pContStr = NULL;
1,920✔
1034

1035
  TAOS_CHECK_GOTO(tDeserializeSMDrainXnodeReq(pReq->pCont, pReq->contLen, &drainReq), NULL, _OVER);
1,920✔
1036

1037
  mDebug("xnode:%d, start to drain", drainReq.xnodeId);
1,920✔
1038
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_DRAIN_XNODE), NULL, _OVER);
1,920✔
1039

1040
  if (drainReq.xnodeId <= 0) {
1,920✔
1041
    code = TSDB_CODE_MND_XNODE_INVALID_MSG;
×
1042
    goto _OVER;
×
1043
  }
1044

1045
  pObj = mndAcquireXnode(pMnode, drainReq.xnodeId);
1,920✔
1046
  if (pObj == NULL) {
1,920✔
1047
    code = TSDB_CODE_MND_XNODE_NOT_EXIST;
1,920✔
1048
    goto _OVER;
1,920✔
1049
  }
1050

1051
  // send request
1052
  char xnodeUrl[TSDB_XNODE_URL_LEN + 1] = {0};
×
NEW
1053
  snprintf(xnodeUrl, TSDB_XNODE_URL_LEN + 1, "%s/xnode/drain/%d", XNODED_PIPE_SOCKET_URL, pObj->id);
×
1054
  postContent = tjsonCreateObject();
×
1055
  if (postContent == NULL) {
×
1056
    code = terrno;
×
1057
    goto _OVER;
×
1058
  }
1059
  TAOS_CHECK_GOTO(tjsonAddStringToObject(postContent, "xnode", pObj->url), NULL, _OVER);
×
1060
  pContStr = tjsonToString(postContent);
×
1061
  if (pContStr == NULL) {
×
1062
    code = terrno;
×
1063
    goto _OVER;
×
1064
  }
NEW
1065
  pJson = mndSendReqRetJson(xnodeUrl, HTTP_TYPE_POST, defaultTimeout, pContStr, strlen(pContStr));
×
1066

1067
  code = mndDrainXnode(pMnode, pReq, pObj);
×
1068
  if (code == 0) {
×
1069
    code = TSDB_CODE_ACTION_IN_PROGRESS;
×
1070
    goto _OVER;
×
1071
  }
1072

1073
_OVER:
1,920✔
1074
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,920✔
1075
    mError("xnode:%d, failed to drain since %s", drainReq.xnodeId, tstrerror(code));
1,920✔
1076
  }
1077

1078
  if (postContent != NULL) {
1,920✔
1079
    tjsonDelete(postContent);
×
1080
  }
1081
  if (pContStr != NULL) {
1,920✔
1082
    taosMemoryFree(pContStr);
×
1083
  }
1084
  if (pJson != NULL) {
1,920✔
1085
    tjsonDelete(pJson);
×
1086
  }
1087
  mndReleaseXnode(pMnode, pObj);
1,920✔
1088
  tFreeSMDrainXnodeReq(&drainReq);
1,920✔
1089
  TAOS_RETURN(code);
1,920✔
1090
}
1091

1092
static int32_t mndRetrieveXnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
1,801✔
1093
  SMnode    *pMnode = pReq->info.node;
1,801✔
1094
  SSdb      *pSdb = pMnode->pSdb;
1,801✔
1095
  int32_t    numOfRows = 0;
1,801✔
1096
  int32_t    cols = 0;
1,801✔
1097
  SXnodeObj *pObj = NULL;
1,801✔
1098
  char       buf[TSDB_XNODE_URL_LEN + VARSTR_HEADER_SIZE] = {0};
1,801✔
1099
  char       status[TSDB_XNODE_STATUS_LEN] = {0};
1,801✔
1100
  int32_t    code = 0;
1,801✔
1101
  mDebug("show.type:%d, %s:%d: retrieve xnodes with rows: %d", pShow->type, __FILE__, __LINE__, rows);
1,801✔
1102

1103
  while (numOfRows < rows) {
4,258✔
1104
    pShow->pIter = sdbFetch(pSdb, SDB_XNODE, pShow->pIter, (void **)&pObj);
4,258✔
1105
    if (pShow->pIter == NULL) break;
4,258✔
1106

1107
    cols = 0;
2,457✔
1108
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,457✔
1109
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->id, false);
2,457✔
1110
    if (code != 0) goto _end;
2,457✔
1111

1112
    STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->url, pShow->pMeta->pSchemas[cols].bytes);
2,457✔
1113
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,457✔
1114
    code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
2,457✔
1115
    if (code != 0) goto _end;
2,457✔
1116

1117
    if (mndGetXnodeStatus(pObj, status, TSDB_XNODE_STATUS_LEN) == 0) {
2,457✔
1118
      STR_TO_VARSTR(buf, status);
×
1119
    } else {
1120
      mDebug("xnode:%d, status request err: %s", pObj->id, tstrerror(terrno));
2,457✔
1121
      STR_TO_VARSTR(buf, "offline");
2,457✔
1122
    }
1123
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,457✔
1124
    code = colDataSetVal(pColInfo, numOfRows, buf, false);
2,457✔
1125
    if (code != 0) goto _end;
2,457✔
1126

1127
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,457✔
1128
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->createTime, false);
2,457✔
1129
    if (code != 0) goto _end;
2,457✔
1130

1131
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,457✔
1132
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->updateTime, false);
2,457✔
1133
    if (code != 0) goto _end;
2,457✔
1134

1135
    numOfRows++;
2,457✔
1136
    sdbRelease(pSdb, pObj);
2,457✔
1137
  }
1138

1139
_end:
1,801✔
1140
  if (code != 0) sdbRelease(pSdb, pObj);
1,801✔
1141

1142
  pShow->numOfRows += numOfRows;
1,801✔
1143
  return numOfRows;
1,801✔
1144
}
1145

1146
static void mndCancelGetNextXnode(SMnode *pMnode, void *pIter) {
×
1147
  SSdb *pSdb = pMnode->pSdb;
×
1148
  sdbCancelFetchByType(pSdb, pIter, SDB_XNODE);
×
1149
}
×
1150

1151
/** xnode task section **/
1152

1153
static SXnodeTaskObj *mndAcquireXnodeTaskById(SMnode *pMnode, int32_t tid) {
3,240✔
1154
  SSdb *pSdb = pMnode->pSdb;
3,240✔
1155

1156
  void *pIter = NULL;
3,240✔
1157
  while (1) {
×
1158
    SXnodeTaskObj *pTask = NULL;
3,240✔
1159
    pIter = sdbFetch(pSdb, SDB_XNODE_TASK, pIter, (void **)&pTask);
3,240✔
1160
    if (pIter == NULL) break;
3,240✔
1161

1162
    if (pTask->id == tid) {
×
1163
      sdbCancelFetch(pSdb, pIter);
×
1164
      return pTask;
×
1165
    }
1166

1167
    sdbRelease(pSdb, pTask);
×
1168
  }
1169

1170
  mDebug("xnode task:%d, not found", tid);
3,240✔
1171
  terrno = TSDB_CODE_MND_XNODE_TASK_NOT_EXIST;
3,240✔
1172
  return NULL;
3,240✔
1173
}
1174
static SXnodeTaskObj *mndAcquireXnodeTaskByName(SMnode *pMnode, const char *name) {
25,920✔
1175
  SSdb *pSdb = pMnode->pSdb;
25,920✔
1176

1177
  void *pIter = NULL;
25,920✔
1178
  while (1) {
×
1179
    SXnodeTaskObj *pTask = NULL;
25,920✔
1180
    pIter = sdbFetch(pSdb, SDB_XNODE_TASK, pIter, (void **)&pTask);
25,920✔
1181
    if (pIter == NULL) break;
25,920✔
1182
    if (pTask->name == NULL) {
×
1183
      continue;
×
1184
    }
1185

1186
    if (strcasecmp(name, pTask->name) == 0) {
×
1187
      sdbCancelFetch(pSdb, pIter);
×
1188
      return pTask;
×
1189
    }
1190

1191
    sdbRelease(pSdb, pTask);
×
1192
  }
1193

1194
  mDebug("xnode task:%s, not found", name);
25,920✔
1195
  terrno = TSDB_CODE_MND_XNODE_TASK_NOT_EXIST;
25,920✔
1196
  return NULL;
25,920✔
1197
}
1198

1199
static void mndFreeXnodeTask(SXnodeTaskObj *pObj) {
×
1200
  taosMemoryFreeClear(pObj->name);
×
1201
  taosMemoryFreeClear(pObj->sourceDsn);
×
1202
  taosMemoryFreeClear(pObj->sinkDsn);
×
1203
  taosMemoryFreeClear(pObj->parser);
×
1204
  taosMemoryFreeClear(pObj->reason);
×
1205
  taosMemoryFreeClear(pObj->status);
×
1206
  taosMemoryFreeClear(pObj->createdBy);
×
1207
  taosMemoryFreeClear(pObj->labels);
×
1208
}
×
1209

1210
SSdbRaw *mndXnodeTaskActionEncode(SXnodeTaskObj *pObj) {
×
1211
  int32_t code = 0;
×
1212
  int32_t lino = 0;
×
1213
  terrno = TSDB_CODE_OUT_OF_MEMORY;
×
1214
  if (NULL == pObj) {
×
1215
    terrno = TSDB_CODE_INVALID_PARA;
×
1216
    return NULL;
×
1217
  }
1218

1219
  int32_t totalStrLen =
×
1220
      pObj->nameLen + pObj->sourceDsnLen + pObj->sinkDsnLen + pObj->parserLen + pObj->reasonLen + pObj->statusLen;
×
1221
  int32_t rawDataLen = sizeof(SXnodeTaskObj) + TSDB_XNODE_RESERVE_SIZE + totalStrLen;
×
1222

1223
  SSdbRaw *pRaw = sdbAllocRaw(SDB_XNODE_TASK, TSDB_XNODE_VER_NUMBER, rawDataLen);
×
1224
  if (pRaw == NULL) goto _OVER;
×
1225

1226
  int32_t dataPos = 0;
×
1227
  SDB_SET_INT32(pRaw, dataPos, pObj->id, _OVER)
×
1228
  SDB_SET_INT64(pRaw, dataPos, pObj->createTime, _OVER)
×
1229
  SDB_SET_INT64(pRaw, dataPos, pObj->updateTime, _OVER)
×
1230
  SDB_SET_INT32(pRaw, dataPos, pObj->statusLen, _OVER)
×
1231
  SDB_SET_BINARY(pRaw, dataPos, pObj->status, pObj->statusLen, _OVER)
×
1232
  SDB_SET_INT32(pRaw, dataPos, pObj->via, _OVER)
×
1233
  SDB_SET_INT32(pRaw, dataPos, pObj->xnodeId, _OVER)
×
1234
  SDB_SET_INT32(pRaw, dataPos, pObj->nameLen, _OVER)
×
1235
  SDB_SET_BINARY(pRaw, dataPos, pObj->name, pObj->nameLen, _OVER)
×
1236
  SDB_SET_INT32(pRaw, dataPos, pObj->sourceType, _OVER)
×
1237
  SDB_SET_INT32(pRaw, dataPos, pObj->sourceDsnLen, _OVER)
×
1238
  SDB_SET_BINARY(pRaw, dataPos, pObj->sourceDsn, pObj->sourceDsnLen, _OVER)
×
1239
  SDB_SET_INT32(pRaw, dataPos, pObj->sinkType, _OVER)
×
1240
  SDB_SET_INT32(pRaw, dataPos, pObj->sinkDsnLen, _OVER)
×
1241
  SDB_SET_BINARY(pRaw, dataPos, pObj->sinkDsn, pObj->sinkDsnLen, _OVER)
×
1242
  SDB_SET_INT32(pRaw, dataPos, pObj->parserLen, _OVER)
×
1243
  SDB_SET_BINARY(pRaw, dataPos, pObj->parser, pObj->parserLen, _OVER)
×
1244
  SDB_SET_INT32(pRaw, dataPos, pObj->reasonLen, _OVER)
×
1245
  SDB_SET_BINARY(pRaw, dataPos, pObj->reason, pObj->reasonLen, _OVER)
×
1246
  SDB_SET_INT32(pRaw, dataPos, pObj->createdByLen, _OVER)
×
1247
  SDB_SET_BINARY(pRaw, dataPos, pObj->createdBy, pObj->createdByLen, _OVER)
×
1248
  SDB_SET_INT32(pRaw, dataPos, pObj->labelsLen, _OVER)
×
1249
  SDB_SET_BINARY(pRaw, dataPos, pObj->labels, pObj->labelsLen, _OVER)
×
1250

1251
  SDB_SET_RESERVE(pRaw, dataPos, TSDB_XNODE_RESERVE_SIZE, _OVER)
×
1252

1253
  terrno = 0;
×
1254

1255
_OVER:
×
1256
  if (terrno != 0) {
×
1257
    mError("xnode task:%d, failed to encode to raw:%p since %s", pObj->id, pRaw, terrstr());
×
1258
    sdbFreeRaw(pRaw);
×
1259
    return NULL;
×
1260
  }
1261

1262
  mTrace("xnode task:%d, encode to raw:%p, row:%p", pObj->id, pRaw, pObj);
×
1263
  return pRaw;
×
1264
}
1265

1266
SSdbRow *mndXnodeTaskActionDecode(SSdbRaw *pRaw) {
×
1267
  int32_t code = 0;
×
1268
  int32_t lino = 0;
×
1269
  terrno = TSDB_CODE_OUT_OF_MEMORY;
×
1270
  SSdbRow       *pRow = NULL;
×
1271
  SXnodeTaskObj *pObj = NULL;
×
1272

1273
  if (NULL == pRaw) {
×
1274
    terrno = TSDB_CODE_INVALID_PARA;
×
1275
    return NULL;
×
1276
  }
1277

1278
  int8_t sver = 0;
×
1279
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
×
1280

1281
  if (sver != TSDB_XNODE_VER_NUMBER) {
×
1282
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
1283
    goto _OVER;
×
1284
  }
1285

1286
  pRow = sdbAllocRow(sizeof(SXnodeTaskObj));
×
1287
  if (pRow == NULL) goto _OVER;
×
1288

1289
  pObj = sdbGetRowObj(pRow);
×
1290
  if (pObj == NULL) goto _OVER;
×
1291

1292
  int32_t dataPos = 0;
×
1293
  SDB_GET_INT32(pRaw, dataPos, &pObj->id, _OVER)
×
1294
  SDB_GET_INT64(pRaw, dataPos, &pObj->createTime, _OVER)
×
1295
  SDB_GET_INT64(pRaw, dataPos, &pObj->updateTime, _OVER)
×
1296
  SDB_GET_INT32(pRaw, dataPos, &pObj->statusLen, _OVER)
×
1297
  if (pObj->statusLen > 0) {
×
1298
    pObj->status = taosMemoryCalloc(pObj->statusLen + 1, 1);
×
1299
    if (pObj->status == NULL) goto _OVER;
×
1300
    SDB_GET_BINARY(pRaw, dataPos, pObj->status, pObj->statusLen, _OVER)
×
1301
  }
1302

1303
  SDB_GET_INT32(pRaw, dataPos, &pObj->via, _OVER)
×
1304
  SDB_GET_INT32(pRaw, dataPos, &pObj->xnodeId, _OVER)
×
1305

1306
  SDB_GET_INT32(pRaw, dataPos, &pObj->nameLen, _OVER)
×
1307
  if (pObj->nameLen > 0) {
×
1308
    pObj->name = taosMemoryCalloc(pObj->nameLen + 1, 1);
×
1309
    if (pObj->name == NULL) goto _OVER;
×
1310
    SDB_GET_BINARY(pRaw, dataPos, pObj->name, pObj->nameLen, _OVER)
×
1311
  }
1312

1313
  SDB_GET_INT32(pRaw, dataPos, &pObj->sourceType, _OVER)
×
1314
  SDB_GET_INT32(pRaw, dataPos, &pObj->sourceDsnLen, _OVER)
×
1315
  if (pObj->sourceDsnLen > 0) {
×
1316
    pObj->sourceDsn = taosMemoryCalloc(pObj->sourceDsnLen + 1, 1);
×
1317
    if (pObj->sourceDsn == NULL) goto _OVER;
×
1318
    SDB_GET_BINARY(pRaw, dataPos, pObj->sourceDsn, pObj->sourceDsnLen, _OVER)
×
1319
  }
1320

1321
  SDB_GET_INT32(pRaw, dataPos, &pObj->sinkType, _OVER)
×
1322
  SDB_GET_INT32(pRaw, dataPos, &pObj->sinkDsnLen, _OVER)
×
1323
  if (pObj->sinkDsnLen > 0) {
×
1324
    pObj->sinkDsn = taosMemoryCalloc(pObj->sinkDsnLen + 1, 1);
×
1325
    if (pObj->sinkDsn == NULL) goto _OVER;
×
1326
    SDB_GET_BINARY(pRaw, dataPos, pObj->sinkDsn, pObj->sinkDsnLen, _OVER)
×
1327
  }
1328

1329
  SDB_GET_INT32(pRaw, dataPos, &pObj->parserLen, _OVER)
×
1330
  if (pObj->parserLen > 0) {
×
1331
    pObj->parser = taosMemoryCalloc(pObj->parserLen + 1, 1);
×
1332
    if (pObj->parser == NULL) goto _OVER;
×
1333
    SDB_GET_BINARY(pRaw, dataPos, pObj->parser, pObj->parserLen, _OVER)
×
1334
  }
1335

1336
  SDB_GET_INT32(pRaw, dataPos, &pObj->reasonLen, _OVER)
×
1337
  if (pObj->reasonLen > 0) {
×
1338
    pObj->reason = taosMemoryCalloc(pObj->reasonLen + 1, 1);
×
1339
    if (pObj->reason == NULL) goto _OVER;
×
1340
    SDB_GET_BINARY(pRaw, dataPos, pObj->reason, pObj->reasonLen, _OVER)
×
1341
  }
1342

1343
  SDB_GET_INT32(pRaw, dataPos, &pObj->createdByLen, _OVER)
×
1344
  if (pObj->createdByLen > 0) {
×
1345
    pObj->createdBy = taosMemoryCalloc(pObj->createdByLen + 1, 1);
×
1346
    if (pObj->createdBy == NULL) goto _OVER;
×
1347
    SDB_GET_BINARY(pRaw, dataPos, pObj->createdBy, pObj->createdByLen, _OVER)
×
1348
  }
1349

1350
  SDB_GET_INT32(pRaw, dataPos, &pObj->labelsLen, _OVER)
×
1351
  if (pObj->labelsLen > 0) {
×
1352
    pObj->labels = taosMemoryCalloc(pObj->labelsLen + 1, 1);
×
1353
    if (pObj->labels == NULL) goto _OVER;
×
1354
    SDB_GET_BINARY(pRaw, dataPos, pObj->labels, pObj->labelsLen, _OVER)
×
1355
  }
1356

1357
  SDB_GET_RESERVE(pRaw, dataPos, TSDB_XNODE_RESERVE_SIZE, _OVER)
×
1358

1359
  terrno = 0;
×
1360

1361
_OVER:
×
1362
  if (terrno != 0) {
×
1363
    mError("xnode task:%d, failed to decode from raw:%p since %s", pObj == NULL ? 0 : pObj->id, pRaw, terrstr());
×
1364
    if (pObj != NULL) {
×
1365
      taosMemoryFreeClear(pObj->name);
×
1366
      taosMemoryFreeClear(pObj->sourceDsn);
×
1367
      taosMemoryFreeClear(pObj->sinkDsn);
×
1368
      taosMemoryFreeClear(pObj->parser);
×
1369
      taosMemoryFreeClear(pObj->reason);
×
1370
      taosMemoryFreeClear(pObj->status);
×
1371
    }
1372
    taosMemoryFreeClear(pRow);
×
1373
    return NULL;
×
1374
  }
1375

1376
  mTrace("xnode:%d, decode from raw:%p, row:%p", pObj->id, pRaw, pObj);
×
1377
  return pRow;
×
1378
}
1379

1380
int32_t mndXnodeTaskActionInsert(SSdb *pSdb, SXnodeTaskObj *pObj) {
×
1381
  mDebug("xtask:%d, perform insert action, row:%p", pObj->id, pObj);
×
1382
  return 0;
×
1383
}
1384

1385
int32_t mndXnodeTaskActionDelete(SSdb *pSdb, SXnodeTaskObj *pObj) {
×
1386
  mDebug("xtask:%d, perform delete action, row:%p", pObj->id, pObj);
×
1387
  mndFreeXnodeTask(pObj);
×
1388
  return 0;
×
1389
}
1390

1391
int32_t mndXnodeTaskActionUpdate(SSdb *pSdb, SXnodeTaskObj *pOld, SXnodeTaskObj *pNew) {
×
1392
  mDebug("xtask:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew);
×
1393

1394
  taosWLockLatch(&pOld->lock);
×
1395
  pOld->via = pNew->via;
×
1396
  pOld->xnodeId = pNew->xnodeId;
×
1397
  swapFields(&pNew->statusLen, &pNew->status, &pOld->statusLen, &pOld->status);
×
1398
  swapFields(&pNew->nameLen, &pNew->name, &pOld->nameLen, &pOld->name);
×
1399
  swapFields(&pNew->sourceDsnLen, &pNew->sourceDsn, &pOld->sourceDsnLen, &pOld->sourceDsn);
×
1400
  swapFields(&pNew->sinkDsnLen, &pNew->sinkDsn, &pOld->sinkDsnLen, &pOld->sinkDsn);
×
1401
  swapFields(&pNew->parserLen, &pNew->parser, &pOld->parserLen, &pOld->parser);
×
1402
  swapFields(&pNew->reasonLen, &pNew->reason, &pOld->reasonLen, &pOld->reason);
×
1403
  swapFields(&pNew->labelsLen, &pNew->labels, &pOld->labelsLen, &pOld->labels);
×
1404
  if (pNew->updateTime > pOld->updateTime) {
×
1405
    pOld->updateTime = pNew->updateTime;
×
1406
  }
1407
  taosWUnLockLatch(&pOld->lock);
×
1408
  return 0;
×
1409
}
1410

1411
static int32_t mndSetCreateXnodeTaskRedoLogs(STrans *pTrans, SXnodeTaskObj *pObj) {
×
1412
  int32_t  code = 0;
×
1413
  SSdbRaw *pRedoRaw = mndXnodeTaskActionEncode(pObj);
×
1414
  if (pRedoRaw == NULL) {
×
1415
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1416
    if (terrno != 0) code = terrno;
×
1417
    TAOS_RETURN(code);
×
1418
  }
1419
  TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
×
1420
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING));
×
1421
  TAOS_RETURN(code);
×
1422
}
1423

1424
static int32_t mndSetCreateXnodeTaskUndoLogs(STrans *pTrans, SXnodeTaskObj *pObj) {
×
1425
  int32_t  code = 0;
×
1426
  SSdbRaw *pUndoRaw = mndXnodeTaskActionEncode(pObj);
×
1427
  if (pUndoRaw == NULL) {
×
1428
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1429
    if (terrno != 0) code = terrno;
×
1430
    TAOS_RETURN(code);
×
1431
  }
1432
  TAOS_CHECK_RETURN(mndTransAppendUndolog(pTrans, pUndoRaw));
×
1433
  TAOS_CHECK_RETURN(sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED));
×
1434
  TAOS_RETURN(code);
×
1435
}
1436

1437
static int32_t mndSetCreateXnodeTaskCommitLogs(STrans *pTrans, SXnodeTaskObj *pObj) {
×
1438
  int32_t  code = 0;
×
1439
  SSdbRaw *pCommitRaw = mndXnodeTaskActionEncode(pObj);
×
1440
  if (pCommitRaw == NULL) {
×
1441
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1442
    if (terrno != 0) code = terrno;
×
1443
    TAOS_RETURN(code);
×
1444
  }
1445
  TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
×
1446
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
×
1447
  TAOS_RETURN(code);
×
1448
}
1449
void mndReleaseXnodeTask(SMnode *pMnode, SXnodeTaskObj *pObj) {
3,240✔
1450
  SSdb *pSdb = pMnode->pSdb;
3,240✔
1451
  sdbRelease(pSdb, pObj);
3,240✔
1452
}
3,240✔
1453

1454
static const char *getXTaskOptionByName(xTaskOptions *pOptions, const char *name) {
486✔
1455
  if (pOptions == NULL || name == NULL) return NULL;
486✔
1456
  for (int32_t i = 0; i < pOptions->optionsNum; ++i) {
1,134✔
1457
    CowStr option = pOptions->options[i];
810✔
1458
    if (option.ptr != NULL && strncasecmp(option.ptr, name, strlen(name)) == 0 && option.ptr[strlen(name)] == '=') {
810✔
1459
      return option.ptr + strlen(name) + 1;
162✔
1460
    }
1461
  }
1462
  return NULL;
324✔
1463
}
1464

1465
static int32_t mndCreateXnodeTask(SMnode *pMnode, SRpcMsg *pReq, SMCreateXnodeTaskReq *pCreate) {
×
1466
  int32_t code = -1;
×
1467
  STrans *pTrans = NULL;
×
1468

1469
  SXnodeTaskObj xnodeObj = {0};
×
1470
  xnodeObj.id = sdbGetMaxId(pMnode->pSdb, SDB_XNODE_TASK);
×
1471
  xnodeObj.createTime = taosGetTimestampMs();
×
1472
  xnodeObj.updateTime = xnodeObj.createTime;
×
1473
  xnodeObj.via = pCreate->options.via;
×
1474
  xnodeObj.xnodeId = pCreate->xnodeId;
×
1475

1476
  xnodeObj.nameLen = pCreate->name.len + 1;
×
1477
  xnodeObj.name = taosMemoryCalloc(1, xnodeObj.nameLen);
×
1478
  if (xnodeObj.name == NULL) goto _OVER;
×
1479
  (void)memcpy(xnodeObj.name, pCreate->name.ptr, pCreate->name.len);
×
1480

1481
  xnodeObj.sourceType = pCreate->source.type;
×
1482
  xnodeObj.sourceDsnLen = pCreate->source.cstr.len + 1;
×
1483
  xnodeObj.sourceDsn = taosMemoryCalloc(1, xnodeObj.sourceDsnLen);
×
1484
  if (xnodeObj.sourceDsn == NULL) goto _OVER;
×
1485
  (void)memcpy(xnodeObj.sourceDsn, pCreate->source.cstr.ptr, pCreate->source.cstr.len);
×
1486

1487
  xnodeObj.sinkType = pCreate->sink.type;
×
1488
  xnodeObj.sinkDsnLen = pCreate->sink.cstr.len + 1;
×
1489
  xnodeObj.sinkDsn = taosMemoryCalloc(1, xnodeObj.sinkDsnLen);
×
1490
  if (xnodeObj.sinkDsn == NULL) goto _OVER;
×
1491
  (void)memcpy(xnodeObj.sinkDsn, pCreate->sink.cstr.ptr, pCreate->sink.cstr.len);
×
1492

1493
  xnodeObj.parserLen = pCreate->options.parser.len + 1;
×
1494
  if (pCreate->options.parser.ptr != NULL) {
×
1495
    xnodeObj.parser = taosMemoryCalloc(1, xnodeObj.parserLen);
×
1496
    if (xnodeObj.parser == NULL) goto _OVER;
×
1497
    (void)memcpy(xnodeObj.parser, pCreate->options.parser.ptr, pCreate->options.parser.len);
×
1498
  }
1499

1500
  const char *status = getXTaskOptionByName(&pCreate->options, "status");
×
1501
  if (status != NULL) {
×
1502
    xnodeObj.statusLen = strlen(status) + 1;
×
1503
    xnodeObj.status = taosMemoryCalloc(1, xnodeObj.statusLen);
×
1504
    if (xnodeObj.status == NULL) goto _OVER;
×
1505
    (void)memcpy(xnodeObj.status, status, xnodeObj.statusLen - 1);
×
1506
  }
1507

1508
  xnodeObj.createdByLen = strlen(pReq->info.conn.user) + 1;
×
1509
  xnodeObj.createdBy = taosMemoryCalloc(1, xnodeObj.createdByLen);
×
1510
  if (xnodeObj.createdBy == NULL) goto _OVER;
×
1511
  (void)memcpy(xnodeObj.createdBy, pReq->info.conn.user, xnodeObj.createdByLen - 1);
×
1512

1513
  const char *labels = getXTaskOptionByName(&pCreate->options, "labels");
×
1514
  if (labels != NULL) {
×
1515
    xnodeObj.labelsLen = strlen(labels) + 1;
×
1516
    xnodeObj.labels = taosMemoryCalloc(1, xnodeObj.labelsLen);
×
1517
    if (xnodeObj.labels == NULL) goto _OVER;
×
1518
    (void)memcpy(xnodeObj.labels, labels, xnodeObj.labelsLen - 1);
×
1519
  }
1520

1521
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-xnode-task");
×
1522
  if (pTrans == NULL) {
×
1523
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1524
    if (terrno != 0) {
×
1525
      code = terrno;
×
1526
    }
1527
    mError("failed to create transaction for xnode-task:%s, code:0x%x:%s", pCreate->name.ptr, code, tstrerror(code));
×
1528
    goto _OVER;
×
1529
  }
1530
  mndTransSetSerial(pTrans);
×
1531

1532
  mDebug("trans:%d, used to create xnode task:%s as task:%d", pTrans->id, pCreate->name.ptr, xnodeObj.id);
×
1533

1534
  TAOS_CHECK_GOTO(mndSetCreateXnodeTaskRedoLogs(pTrans, &xnodeObj), NULL, _OVER);
×
1535
  TAOS_CHECK_GOTO(mndSetCreateXnodeTaskUndoLogs(pTrans, &xnodeObj), NULL, _OVER);
×
1536
  TAOS_CHECK_GOTO(mndSetCreateXnodeTaskCommitLogs(pTrans, &xnodeObj), NULL, _OVER);
×
1537
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
×
1538

1539
  code = 0;
×
1540

1541
_OVER:
×
1542
  mndFreeXnodeTask(&xnodeObj);
×
1543
  mndTransDrop(pTrans);
×
1544
  TAOS_RETURN(code);
×
1545
}
1546

1547
// Helper function to validate grant and permissions
1548
static int32_t mndValidateXnodeTaskPermissions(SMnode *pMnode, SRpcMsg *pReq) {
13,770✔
1549
  int32_t code = grantCheck(TSDB_GRANT_XNODE);
13,770✔
1550
  if (code != TSDB_CODE_SUCCESS) {
13,770✔
1551
    mError("failed to create xnode, code:%s", tstrerror(code));
×
1552
    return code;
×
1553
  }
1554

1555
  return mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_CREATE_XNODE);
13,770✔
1556
}
1557

1558
// Helper function to parse and validate the request
1559
static int32_t mndValidateCreateXnodeTaskReq(SRpcMsg *pReq, SMCreateXnodeTaskReq *pCreateReq) {
13,770✔
1560
  int32_t code = 0;
13,770✔
1561
  SJson  *pJson = NULL;
13,770✔
1562
  SJson  *postContent = NULL;
13,770✔
1563
  char   *srcDsn = NULL;
13,770✔
1564
  char   *sinkDsn = NULL;
13,770✔
1565
  char   *parser = NULL;
13,770✔
1566
  char   *pContStr = NULL;
13,770✔
1567

1568
  // from, to, parser check
1569
  char xnodeUrl[TSDB_XNODE_URL_LEN] = {0};
13,770✔
1570
  snprintf(xnodeUrl, TSDB_XNODE_URL_LEN, "%s/task/check", XNODED_PIPE_SOCKET_URL);
13,770✔
1571
  postContent = tjsonCreateObject();
13,770✔
1572
  if (postContent == NULL) {
13,770✔
1573
    code = terrno;
×
1574
    goto _OVER;
×
1575
  }
1576
  srcDsn = taosStrndupi(pCreateReq->source.cstr.ptr, (int64_t)pCreateReq->source.cstr.len);
13,770✔
1577
  if (srcDsn == NULL) {
13,770✔
1578
    code = terrno;
×
1579
    goto _OVER;
×
1580
  }
1581
  TAOS_CHECK_GOTO(tjsonAddStringToObject(postContent, "from", srcDsn), NULL, _OVER);
13,770✔
1582

1583
  sinkDsn = taosStrndupi(pCreateReq->sink.cstr.ptr, (int64_t)pCreateReq->sink.cstr.len);
13,770✔
1584
  if (sinkDsn == NULL) {
13,770✔
1585
    code = terrno;
×
1586
    goto _OVER;
×
1587
  }
1588
  TAOS_CHECK_GOTO(tjsonAddStringToObject(postContent, "to", sinkDsn), NULL, _OVER);
13,770✔
1589

1590
  if (pCreateReq->options.parser.len > 0 && pCreateReq->options.parser.ptr != NULL) {
13,770✔
1591
    parser = taosStrndupi(pCreateReq->options.parser.ptr, (int64_t)pCreateReq->options.parser.len);
8,910✔
1592
    if (parser == NULL) {
8,910✔
1593
      code = terrno;
×
1594
      goto _OVER;
×
1595
    }
1596
    TAOS_CHECK_GOTO(tjsonAddStringToObject(postContent, "parser", parser), NULL, _OVER);
8,910✔
1597
  }
1598

1599
  if (pCreateReq->xnodeId > 0) {
13,770✔
1600
    TAOS_CHECK_GOTO(tjsonAddDoubleToObject(postContent, "xnode_id", (double)pCreateReq->xnodeId), NULL, _OVER);
×
1601
  }
1602

1603
  pContStr = tjsonToUnformattedString(postContent);
13,770✔
1604
  if (pContStr == NULL) {
13,770✔
1605
    code = terrno;
×
1606
    goto _OVER;
×
1607
  }
1608

1609
  pJson = mndSendReqRetJson(xnodeUrl, HTTP_TYPE_POST, 60000, pContStr, strlen(pContStr));
13,770✔
1610
  if (pJson == NULL) {
13,770✔
1611
    code = terrno;
13,770✔
1612
    goto _OVER;
13,770✔
1613
  }
1614

1615
  // todo: only4test
1616
  // (void)mndSendReqRetJson(xnodeUrl, HTTP_TYPE_POST, 60000, pContStr, strlen(pContStr));
1617
  // code = TSDB_CODE_SUCCESS;
1618

1619
_OVER:
13,770✔
1620
  if (srcDsn != NULL) taosMemoryFreeClear(srcDsn);
13,770✔
1621
  if (sinkDsn != NULL) taosMemoryFreeClear(sinkDsn);
13,770✔
1622
  if (parser != NULL) taosMemoryFreeClear(parser);
13,770✔
1623
  if (pContStr != NULL) taosMemoryFreeClear(pContStr);
13,770✔
1624
  if (postContent != NULL) tjsonDelete(postContent);
13,770✔
1625
  if (pJson != NULL) tjsonDelete(pJson);
13,770✔
1626

1627
  TAOS_RETURN(code);
13,770✔
1628
}
1629

1630
// Helper function to check if xnode task already exists
1631
static int32_t mndCheckXnodeTaskExists(SMnode *pMnode, const char *name) {
13,770✔
1632
  SXnodeTaskObj *pObj = mndAcquireXnodeTaskByName(pMnode, name);
13,770✔
1633
  if (pObj != NULL) {
13,770✔
1634
    mError("xnode task:%s already exists", name);
×
1635
    mndReleaseXnodeTask(pMnode, pObj);
×
1636
    return TSDB_CODE_MND_XNODE_TASK_ALREADY_EXIST;
×
1637
  }
1638
  return TSDB_CODE_SUCCESS;
13,770✔
1639
}
1640

1641
// Helper function to handle the creation result
1642
static int32_t mndHandleCreateXnodeTaskResult(int32_t createCode) {
×
1643
  if (createCode == 0) {
×
1644
    return TSDB_CODE_ACTION_IN_PROGRESS;
×
1645
  }
1646
  return createCode;
×
1647
}
1648

1649
static int32_t mndProcessCreateXnodeTaskReq(SRpcMsg *pReq) {
13,770✔
1650
  mDebug("xnode create task request received, contLen:%d\n", pReq->contLen);
13,770✔
1651
  SMnode              *pMnode = pReq->info.node;
13,770✔
1652
  int32_t              code = -1;
13,770✔
1653
  SMCreateXnodeTaskReq createReq = {0};
13,770✔
1654

1655
  // Step 1: Validate permissions
1656
  code = mndValidateXnodeTaskPermissions(pMnode, pReq);
13,770✔
1657
  if (code != TSDB_CODE_SUCCESS) {
13,770✔
1658
    goto _OVER;
×
1659
  }
1660

1661
  code = tDeserializeSMCreateXnodeTaskReq(pReq->pCont, pReq->contLen, &createReq);
13,770✔
1662
  if (code != 0) {
13,770✔
1663
    mError("failed to deserialize create xnode task request, code:%s", tstrerror(code));
×
1664
    TAOS_RETURN(code);
×
1665
  }
1666

1667
  // Step 2: Check if task already exists
1668
  TAOS_CHECK_GOTO(mndCheckXnodeTaskExists(pMnode, createReq.name.ptr), NULL, _OVER);
13,770✔
1669

1670
  // Step 3: Parse and validate request
1671
  TAOS_CHECK_GOTO(mndValidateCreateXnodeTaskReq(pReq, &createReq), NULL, _OVER);
13,770✔
1672

1673
  // Step 4: Create the xnode task
1674
  TAOS_CHECK_GOTO(mndCreateXnodeTask(pMnode, pReq, &createReq), NULL, _OVER);
×
1675
  TAOS_CHECK_GOTO(mndHandleCreateXnodeTaskResult(code), NULL, _OVER);
×
1676

1677
_OVER:
13,770✔
1678
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
13,770✔
1679
    mError("xnode task:%s, failed to create since %s", createReq.name.ptr ? createReq.name.ptr : "unknown",
13,770✔
1680
           tstrerror(code));
1681
  }
1682
  tFreeSMCreateXnodeTaskReq(&createReq);
13,770✔
1683
  TAOS_RETURN(code);
13,770✔
1684
}
1685

1686
static int32_t httpStartXnodeTask(SXnodeTaskObj *pObj) {
×
1687
  int32_t code = 0;
×
1688
  struct {
1689
    char   xnodeUrl[TSDB_XNODE_URL_LEN + 1];
1690
    SJson *postContent;
1691
    SJson *pJson;
1692
    char  *pContStr;
1693
    char  *srcDsn;
1694
    char  *sinkDsn;
1695
    char  *parser;
1696
  } req = {0};
×
1697

NEW
1698
  snprintf(req.xnodeUrl, TSDB_XNODE_URL_LEN + 1, "%s/task/%d", XNODED_PIPE_SOCKET_URL, pObj->id);
×
1699
  req.postContent = tjsonCreateObject();
×
1700
  if (req.postContent == NULL) {
×
1701
    code = terrno;
×
1702
    goto _OVER;
×
1703
  }
1704
  req.srcDsn = taosStrndupi(pObj->sourceDsn, (int64_t)pObj->sourceDsnLen);
×
1705
  if (req.srcDsn == NULL) {
×
1706
    code = terrno;
×
1707
    goto _OVER;
×
1708
  }
1709
  TAOS_CHECK_GOTO(tjsonAddStringToObject(req.postContent, "from", req.srcDsn), NULL, _OVER);
×
1710

1711
  req.sinkDsn = taosStrndupi(pObj->sinkDsn, (int64_t)pObj->sinkDsnLen);
×
1712
  if (req.sinkDsn == NULL) {
×
1713
    code = terrno;
×
1714
    goto _OVER;
×
1715
  }
1716
  TAOS_CHECK_GOTO(tjsonAddStringToObject(req.postContent, "to", req.sinkDsn), NULL, _OVER);
×
1717

1718
  if (pObj->parserLen > 0) {
×
1719
    req.parser = taosStrndupi(pObj->parser, (int64_t)pObj->parserLen);
×
1720
    if (req.parser == NULL) {
×
1721
      code = terrno;
×
1722
      goto _OVER;
×
1723
    }
1724
    TAOS_CHECK_GOTO(tjsonAddStringToObject(req.postContent, "parser", req.parser), NULL, _OVER);
×
1725
  }
1726

1727
  if (pObj->xnodeId > 0) {
×
1728
    TAOS_CHECK_GOTO(tjsonAddDoubleToObject(req.postContent, "xnode_id", (double)pObj->xnodeId), NULL, _OVER);
×
1729
  }
1730

1731
  if (pObj->via > 0) {
×
1732
    TAOS_CHECK_GOTO(tjsonAddDoubleToObject(req.postContent, "via", (double)pObj->via), NULL, _OVER);
×
1733
  }
1734

1735
  if (pObj->createdBy != NULL) {
×
1736
    TAOS_CHECK_GOTO(tjsonAddStringToObject(req.postContent, "created_by", pObj->createdBy), NULL, _OVER);
×
1737
  }
1738

1739
  if (pObj->labels != NULL) {
×
1740
    TAOS_CHECK_GOTO(tjsonAddStringToObject(req.postContent, "labels", pObj->labels), NULL, _OVER);
×
1741
  }
1742

1743
  req.pContStr = tjsonToUnformattedString(req.postContent);
×
1744
  if (req.pContStr == NULL) {
×
1745
    code = terrno;
×
1746
    goto _OVER;
×
1747
  }
1748
  mDebug("start xnode post content:%s", req.pContStr);
×
NEW
1749
  req.pJson = mndSendReqRetJson(req.xnodeUrl, HTTP_TYPE_POST, defaultTimeout, req.pContStr, strlen(req.pContStr));
×
1750

1751
_OVER:
×
1752
  if (req.pContStr != NULL) taosMemoryFreeClear(req.pContStr);
×
1753
  if (req.postContent != NULL) tjsonDelete(req.postContent);
×
1754
  if (req.pJson != NULL) tjsonDelete(req.pJson);
×
1755
  if (req.srcDsn != NULL) taosMemoryFreeClear(req.srcDsn);
×
1756
  if (req.sinkDsn != NULL) taosMemoryFreeClear(req.sinkDsn);
×
1757
  if (req.parser != NULL) taosMemoryFreeClear(req.parser);
×
1758
  TAOS_RETURN(code);
×
1759
}
1760

1761
static int32_t mndProcessStartXnodeTaskReq(SRpcMsg *pReq) {
810✔
1762
  SMnode             *pMnode = pReq->info.node;
810✔
1763
  int32_t             code = 0;
810✔
1764
  SXnodeTaskObj      *pObj = NULL;
810✔
1765
  SMStartXnodeTaskReq startReq = {0};
810✔
1766
  SXnodeTaskObj      *pObjClone = NULL;
810✔
1767

1768
  TAOS_CHECK_GOTO(tDeserializeSMStartXnodeTaskReq(pReq->pCont, pReq->contLen, &startReq), NULL, _OVER);
810✔
1769

1770
  mDebug("xnode start xnode task with tid:%d", startReq.tid);
810✔
1771
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_START_XNODE_TASK), NULL, _OVER);
810✔
1772

1773
  if (startReq.tid <= 0 && (startReq.name.len <= 0 || startReq.name.ptr == NULL)) {
810✔
1774
    code = TSDB_CODE_MND_XNODE_INVALID_MSG;
×
1775
    goto _OVER;
×
1776
  }
1777

1778
  if (startReq.tid > 0) {
810✔
1779
    pObj = mndAcquireXnodeTask(pMnode, startReq.tid);
810✔
1780
  } else {
1781
    pObj = mndAcquireXnodeTaskByName(pMnode, startReq.name.ptr);
×
1782
  }
1783
  if (pObj == NULL) {
810✔
1784
    code = terrno;
810✔
1785
    goto _OVER;
810✔
1786
  }
1787
  (void)httpStartXnodeTask(pObj);
×
1788

1789
_OVER:
810✔
1790
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
810✔
1791
    mError("xnode task:%d, failed to start since %s", startReq.tid, tstrerror(code));
810✔
1792
  }
1793
  tFreeSMStartXnodeTaskReq(&startReq);
810✔
1794
  if (pObj != NULL) {
810✔
1795
    mndReleaseXnodeTask(pMnode, pObj);
×
1796
  }
1797
  if (pObjClone != NULL) {
810✔
1798
    mndFreeXnodeTask(pObjClone);
×
1799
    taosMemFree(pObjClone);
×
1800
  }
1801
  TAOS_RETURN(code);
810✔
1802
}
1803

1804
static int32_t mndProcessStopXnodeTaskReq(SRpcMsg *pReq) {
810✔
1805
  SMnode            *pMnode = pReq->info.node;
810✔
1806
  int32_t            code = -1;
810✔
1807
  SXnodeTaskObj     *pObj = NULL;
810✔
1808
  SMStopXnodeTaskReq stopReq = {0};
810✔
1809
  SJson             *pJson = NULL;
810✔
1810

1811
  TAOS_CHECK_GOTO(tDeserializeSMStopXnodeTaskReq(pReq->pCont, pReq->contLen, &stopReq), NULL, _OVER);
810✔
1812

1813
  mDebug("Stop xnode task with tid:%d", stopReq.tid);
810✔
1814
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_STOP_XNODE_TASK), NULL, _OVER);
810✔
1815
  if (stopReq.tid <= 0 && (stopReq.name.len <= 0 || stopReq.name.ptr == NULL)) {
810✔
1816
    code = TSDB_CODE_MND_XNODE_INVALID_MSG;
×
1817
    goto _OVER;
×
1818
  }
1819

1820
  if (stopReq.tid > 0) {
810✔
1821
    pObj = mndAcquireXnodeTask(pMnode, stopReq.tid);
810✔
1822
  } else {
1823
    pObj = mndAcquireXnodeTaskByName(pMnode, stopReq.name.ptr);
×
1824
  }
1825
  if (pObj == NULL) {
810✔
1826
    code = terrno;
810✔
1827
    goto _OVER;
810✔
1828
  }
1829

1830
  // send request
1831
  char xnodeUrl[TSDB_XNODE_URL_LEN + 1] = {0};
×
NEW
1832
  snprintf(xnodeUrl, TSDB_XNODE_URL_LEN + 1, "%s/task/%d", XNODED_PIPE_SOCKET_URL, pObj->id);
×
NEW
1833
  pJson = mndSendReqRetJson(xnodeUrl, HTTP_TYPE_DELETE, defaultTimeout, NULL, 0);
×
1834

1835
_OVER:
810✔
1836
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
810✔
1837
    mError("xnode task:%d, failed to stop since %s", stopReq.tid, tstrerror(code));
810✔
1838
  }
1839
  if (pJson != NULL) {
810✔
1840
    tjsonDelete(pJson);
×
1841
  }
1842
  tFreeSMStopXnodeTaskReq(&stopReq);
810✔
1843
  TAOS_RETURN(code);
810✔
1844
}
1845

1846
static int32_t mndUpdateXnodeTask(SMnode *pMnode, SRpcMsg *pReq, const SXnodeTaskObj *pOld,
×
1847
                                  SMUpdateXnodeTaskReq *pUpdate) {
1848
  mDebug("xnode task:%d, start to update", pUpdate->tid);
×
1849
  int32_t      code = -1;
×
1850
  STrans       *pTrans = NULL;
×
1851
  SXnodeTaskObj taskObj = *pOld;
×
1852
  struct {
1853
    bool status;
1854
    bool name;
1855
    bool source;
1856
    bool sink;
1857
    bool parser;
1858
    bool reason;
1859
    bool labels;
1860
  } isChange = {0};
×
1861

1862
  if (pUpdate->via > 0) {
×
1863
    taskObj.via = pUpdate->via;
×
1864
  }
1865
  if (pUpdate->xnodeId > 0) {
×
1866
    taskObj.xnodeId = pUpdate->xnodeId;
×
1867
  }
1868
  if (pUpdate->status.ptr != NULL) {
×
1869
    taskObj.statusLen = pUpdate->status.len + 1;
×
1870
    taskObj.status = taosMemoryCalloc(1, taskObj.statusLen);
×
1871
    if (taskObj.status == NULL) {
×
1872
      code = terrno;
×
1873
      goto _OVER;
×
1874
    }
1875
    (void)memcpy(taskObj.status, pUpdate->status.ptr, pUpdate->status.len);
×
1876
    isChange.status = true;
×
1877
  }
1878
  if (pUpdate->updateName.ptr != NULL) {
×
1879
    taskObj.nameLen = pUpdate->updateName.len + 1;
×
1880
    taskObj.name = taosMemoryCalloc(1, taskObj.nameLen);
×
1881
    if (taskObj.name == NULL) {
×
1882
      code = terrno;
×
1883
      goto _OVER;
×
1884
    }
1885
    (void)memcpy(taskObj.name, pUpdate->updateName.ptr, pUpdate->updateName.len);
×
1886
    isChange.name = true;
×
1887
  }
1888
  if (pUpdate->source.cstr.ptr != NULL) {
×
1889
    taskObj.sourceType = pUpdate->source.type;
×
1890
    taskObj.sourceDsnLen = pUpdate->source.cstr.len + 1;
×
1891
    taskObj.sourceDsn = taosMemoryCalloc(1, taskObj.sourceDsnLen);
×
1892
    if (taskObj.sourceDsn == NULL) {
×
1893
      code = terrno;
×
1894
      goto _OVER;
×
1895
    }
1896
    (void)memcpy(taskObj.sourceDsn, pUpdate->source.cstr.ptr, pUpdate->source.cstr.len);
×
1897
    isChange.source = true;
×
1898
  }
1899
  if (pUpdate->sink.cstr.ptr != NULL) {
×
1900
    taskObj.sinkType = pUpdate->sink.type;
×
1901
    taskObj.sinkDsnLen = pUpdate->sink.cstr.len + 1;
×
1902
    taskObj.sinkDsn = taosMemoryCalloc(1, taskObj.sinkDsnLen);
×
1903
    if (taskObj.sinkDsn == NULL) {
×
1904
      code = terrno;
×
1905
      goto _OVER;
×
1906
    }
1907
    (void)memcpy(taskObj.sinkDsn, pUpdate->sink.cstr.ptr, pUpdate->sink.cstr.len);
×
1908
    isChange.sink = true;
×
1909
  }
1910
  if (pUpdate->parser.ptr != NULL) {
×
1911
    taskObj.parserLen = pUpdate->parser.len + 1;
×
1912
    taskObj.parser = taosMemoryCalloc(1, taskObj.parserLen);
×
1913
    if (taskObj.parser == NULL) {
×
1914
      code = terrno;
×
1915
      goto _OVER;
×
1916
    }
1917
    (void)memcpy(taskObj.parser, pUpdate->parser.ptr, pUpdate->parser.len);
×
1918
    isChange.parser = true;
×
1919
  }
1920
  if (pUpdate->reason.ptr != NULL) {
×
1921
    taskObj.reasonLen = pUpdate->reason.len + 1;
×
1922
    taskObj.reason = taosMemoryCalloc(1, taskObj.reasonLen);
×
1923
    if (taskObj.reason == NULL) {
×
1924
      code = terrno;
×
1925
      goto _OVER;
×
1926
    }
1927
    (void)memcpy(taskObj.reason, pUpdate->reason.ptr, pUpdate->reason.len);
×
1928
    isChange.reason = true;
×
1929
  }
1930
  if (pUpdate->labels.ptr != NULL) {
×
1931
    taskObj.labelsLen = pUpdate->labels.len + 1;
×
1932
    taskObj.labels = taosMemoryCalloc(1, taskObj.labelsLen);
×
1933
    if (taskObj.labels == NULL) {
×
1934
      code = terrno;
×
1935
      goto _OVER;
×
1936
    }
1937
    (void)memcpy(taskObj.labels, pUpdate->labels.ptr, pUpdate->labels.len);
×
1938
    isChange.labels = true;
×
1939
  }
1940
  taskObj.updateTime = taosGetTimestampMs();
×
1941

1942
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "update-xnode-task");
×
1943
  if (pTrans == NULL) {
×
1944
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
1945
    if (terrno != 0) code = terrno;
×
1946
    goto _OVER;
×
1947
  }
1948
  mInfo("trans:%d, used to update xnode task:%d", pTrans->id, taskObj.id);
×
1949

1950
  TAOS_CHECK_GOTO(mndSetCreateXnodeTaskCommitLogs(pTrans, &taskObj), NULL, _OVER);
×
1951
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
×
1952
  code = 0;
×
1953

1954
_OVER:
×
1955
  if (NULL != taskObj.name && isChange.name) {
×
1956
    taosMemoryFree(taskObj.name);
×
1957
  }
1958
  if (NULL != taskObj.status && isChange.status) {
×
1959
    taosMemoryFree(taskObj.status);
×
1960
  }
1961
  if (NULL != taskObj.sourceDsn && isChange.source) {
×
1962
    taosMemoryFree(taskObj.sourceDsn);
×
1963
  }
1964
  if (NULL != taskObj.sinkDsn && isChange.sink) {
×
1965
    taosMemoryFree(taskObj.sinkDsn);
×
1966
  }
1967
  if (NULL != taskObj.parser && isChange.parser) {
×
1968
    taosMemoryFree(taskObj.parser);
×
1969
  }
1970
  if (NULL != taskObj.reason && isChange.reason) {
×
1971
    taosMemoryFree(taskObj.reason);
×
1972
  }
1973
  if (NULL != taskObj.labels && isChange.labels) {
×
1974
    taosMemoryFree(taskObj.labels);
×
1975
  }
1976
  mndTransDrop(pTrans);
×
1977
  TAOS_RETURN(code);
×
1978
}
1979

1980
static int32_t mndProcessUpdateXnodeTaskReq(SRpcMsg *pReq) {
3,240✔
1981
  SMnode             *pMnode = pReq->info.node;
3,240✔
1982
  int32_t             code = -1;
3,240✔
1983
  SXnodeTaskObj       *pObj = NULL;
3,240✔
1984
  SMUpdateXnodeTaskReq updateReq = {0};
3,240✔
1985

1986
  if ((code = grantCheck(TSDB_GRANT_TD_GPT)) != TSDB_CODE_SUCCESS) {
3,240✔
1987
    mError("failed to create xnode, code:%s", tstrerror(code));
×
1988
    goto _OVER;
×
1989
  }
1990

1991
  TAOS_CHECK_GOTO(tDeserializeSMUpdateXnodeTaskReq(pReq->pCont, pReq->contLen, &updateReq), NULL, _OVER);
3,240✔
1992

1993
  if (updateReq.tid > 0) {
3,240✔
1994
    pObj = mndAcquireXnodeTaskById(pMnode, updateReq.tid);
3,240✔
1995
  } else {
1996
    pObj = mndAcquireXnodeTaskByName(pMnode, updateReq.name.ptr);
×
1997
  }
1998
  if (pObj == NULL) {
3,240✔
1999
    code = terrno;
3,240✔
2000
    goto _OVER;
3,240✔
2001
  }
2002

2003
  if (updateReq.updateName.len > 0) {
×
2004
    SXnodeTaskObj *tmpObj = mndAcquireXnodeTaskByName(pMnode, updateReq.updateName.ptr);
×
2005
    if (tmpObj != NULL) {
×
2006
      mndReleaseXnodeTask(pMnode, tmpObj);
×
2007
      code = TSDB_CODE_MND_XNODE_NAME_DUPLICATE;
×
2008
      goto _OVER;
×
2009
    }
2010
  }
2011

2012
  code = mndUpdateXnodeTask(pMnode, pReq, pObj, &updateReq);
×
2013
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
×
2014

2015
_OVER:
3,240✔
2016
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
3,240✔
2017
    mError("xnode task:%d, failed to update since %s", updateReq.tid, tstrerror(code));
3,240✔
2018
  }
2019

2020
  mndReleaseXnodeTask(pMnode, pObj);
3,240✔
2021
  tFreeSMUpdateXnodeTaskReq(&updateReq);
3,240✔
2022
  TAOS_RETURN(code);
3,240✔
2023
  return 0;
2024
}
2025

2026
SXnodeTaskObj *mndAcquireXnodeTask(SMnode *pMnode, int32_t tid) {
2,430✔
2027
  SXnodeTaskObj *pObj = sdbAcquire(pMnode->pSdb, SDB_XNODE_TASK, &tid);
2,430✔
2028
  if (pObj == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
2,430✔
2029
    terrno = TSDB_CODE_MND_XNODE_TASK_NOT_EXIST;
2,430✔
2030
  }
2031
  return pObj;
2,430✔
2032
}
2033

2034
static int32_t mndSetDropXnodeTaskRedoLogs(STrans *pTrans, SXnodeTaskObj *pObj) {
×
2035
  int32_t  code = 0;
×
2036
  SSdbRaw *pRedoRaw = mndXnodeTaskActionEncode(pObj);
×
2037
  if (pRedoRaw == NULL) {
×
2038
    code = terrno;
×
2039
    return code;
×
2040
  }
2041

2042
  TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
×
2043
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING));
×
2044

2045
  TAOS_RETURN(code);
×
2046
}
2047

2048
static int32_t mndSetDropXnodeTaskCommitLogs(STrans *pTrans, SXnodeTaskObj *pObj) {
×
2049
  int32_t  code = 0;
×
2050
  SSdbRaw *pCommitRaw = mndXnodeTaskActionEncode(pObj);
×
2051
  if (pCommitRaw == NULL) {
×
2052
    code = terrno;
×
2053
    return code;
×
2054
  }
2055

2056
  TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
×
2057
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED));
×
2058
  TAOS_RETURN(code);
×
2059
}
2060
static int32_t mndSetDropXnodeTaskInfoToTrans(SMnode *pMnode, STrans *pTrans, SXnodeTaskObj *pObj, bool force) {
×
2061
  if (pObj == NULL) {
×
2062
    return 0;
×
2063
  }
2064
  TAOS_CHECK_RETURN(mndSetDropXnodeTaskRedoLogs(pTrans, pObj));
×
2065
  TAOS_CHECK_RETURN(mndSetDropXnodeTaskCommitLogs(pTrans, pObj));
×
2066
  return 0;
×
2067
}
2068

2069
static int32_t mndDropXnodeTask(SMnode *pMnode, SRpcMsg *pReq, SXnodeTaskObj *pTask) {
×
2070
  int32_t code = 0;
×
2071
  int32_t lino = 0;
×
2072
  SArray *pArray = NULL;
×
2073

2074
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq, "drop-xnode-task");
×
2075
  TSDB_CHECK_NULL(pTrans, code, lino, _OVER, terrno);
×
2076

2077
  mndTransSetSerial(pTrans);
×
2078
  mDebug("trans:%d, to drop xnode:%d", pTrans->id, pTask->id);
×
2079

UNCOV
2080
  code = mndSetDropXnodeTaskInfoToTrans(pMnode, pTrans, pTask, false);
×
UNCOV
2081
  mndReleaseXnodeTask(pMnode, pTask);
×
2082

2083
  TSDB_CHECK_CODE(code, lino, _OVER);
×
2084

2085
  code = mndTransPrepare(pMnode, pTrans);
×
2086

2087
_OVER:
×
2088
  if (pArray != NULL) {
×
2089
    for (int i = 0; i < pArray->size; i++) {
×
2090
      SXnodeJobObj *pJob = taosArrayGet(pArray, i);
×
2091
      if (pJob == NULL) continue;
×
2092
      mndReleaseXnodeJob(pMnode, pJob);
×
2093
    }
2094
  }
2095
  mndTransDrop(pTrans);
×
2096
  TAOS_RETURN(code);
×
2097
}
2098

2099
static int32_t mndProcessDropXnodeTaskReq(SRpcMsg *pReq) {
12,960✔
2100
  SMnode            *pMnode = pReq->info.node;
12,960✔
2101
  int32_t            code = -1;
12,960✔
2102
  SXnodeTaskObj     *pObj = NULL;
12,960✔
2103
  SMDropXnodeTaskReq dropReq = {0};
12,960✔
2104
  SJson             *pJson = NULL;
12,960✔
2105

2106
  TAOS_CHECK_GOTO(tDeserializeSMDropXnodeTaskReq(pReq->pCont, pReq->contLen, &dropReq), NULL, _OVER);
12,960✔
2107

2108
  mDebug("DropXnodeTask with tid:%d, start to drop", dropReq.id);
12,960✔
2109
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_DROP_XNODE_TASK), NULL, _OVER);
12,960✔
2110

2111
  if (dropReq.id <= 0 && (dropReq.name.len <= 0 || dropReq.name.ptr == NULL)) {
12,960✔
2112
    code = TSDB_CODE_MND_XNODE_INVALID_MSG;
×
2113
    goto _OVER;
×
2114
  }
2115

2116
  if (dropReq.name.len > 0 && dropReq.name.ptr != NULL) {
12,960✔
2117
    pObj = mndAcquireXnodeTaskByName(pMnode, dropReq.name.ptr);
12,150✔
2118
  } else {
2119
    pObj = mndAcquireXnodeTask(pMnode, dropReq.id);
810✔
2120
  }
2121
  if (pObj == NULL) {
12,960✔
2122
    code = terrno;
12,960✔
2123
    goto _OVER;
12,960✔
2124
  }
2125

2126
  // send request to drop xnode task
2127
  char xnodeUrl[TSDB_XNODE_URL_LEN + 1] = {0};
×
NEW
2128
  snprintf(xnodeUrl, TSDB_XNODE_URL_LEN + 1, "%s/task/drop/%d", XNODED_PIPE_SOCKET_URL, pObj->id);
×
NEW
2129
  pJson = mndSendReqRetJson(xnodeUrl, HTTP_TYPE_DELETE, defaultTimeout, NULL, 0);
×
2130

2131
  code = mndDropXnodeTask(pMnode, pReq, pObj);
×
2132
  if (code == 0) {
×
2133
    code = TSDB_CODE_ACTION_IN_PROGRESS;
×
2134
  }
2135

2136
_OVER:
12,960✔
2137
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
12,960✔
2138
    mError("xnode task:%d, failed to drop since %s", dropReq.id, tstrerror(code));
12,960✔
2139
  }
2140
  if (pJson != NULL) {
12,960✔
2141
    tjsonDelete(pJson);
×
2142
  }
2143
  tFreeSMDropXnodeTaskReq(&dropReq);
12,960✔
2144
  TAOS_RETURN(code);
12,960✔
2145
}
2146
static int32_t mndRetrieveXnodeTasks(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
3,374✔
2147
  SMnode        *pMnode = pReq->info.node;
3,374✔
2148
  SSdb          *pSdb = pMnode->pSdb;
3,374✔
2149
  int32_t        numOfRows = 0;
3,374✔
2150
  int32_t        cols = 0;
3,374✔
2151
  SXnodeTaskObj *pObj = NULL;
3,374✔
2152
  char           buf[VARSTR_HEADER_SIZE +
×
2153
           TMAX(TSDB_XNODE_TASK_NAME_LEN,
3,374✔
2154
                          TMAX(TSDB_XNODE_TASK_SOURCE_LEN, TMAX(TSDB_XNODE_TASK_SINK_LEN, TSDB_XNODE_TASK_PARSER_LEN)))];
2155
  int32_t        code = 0;
3,374✔
2156
  mDebug("show.type:%d, %s:%d: retrieve xnode tasks with rows: %d", pShow->type, __FILE__, __LINE__, rows);
3,374✔
2157

2158
  while (numOfRows < rows) {
3,374✔
2159
    pShow->pIter = sdbFetch(pSdb, SDB_XNODE_TASK, pShow->pIter, (void **)&pObj);
3,374✔
2160
    if (pShow->pIter == NULL) break;
3,374✔
2161

2162
    cols = 0;
×
2163
    // id
2164
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2165
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->id, false);
×
2166
    if (code != 0) goto _end;
×
2167

2168
    // name
2169
    buf[0] = 0;
×
2170
    STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
×
2171
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2172
    code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
×
2173
    if (code != 0) goto _end;
×
2174

2175
    // from
2176
    buf[0] = 0;
×
2177
    STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->sourceDsn, pShow->pMeta->pSchemas[cols].bytes);
×
2178
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2179
    code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
×
2180
    if (code != 0) goto _end;
×
2181

2182
    // to
2183
    buf[0] = 0;
×
2184
    STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->sinkDsn, pShow->pMeta->pSchemas[cols].bytes);
×
2185
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2186
    code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
×
2187
    if (code != 0) goto _end;
×
2188

2189
    // parser
2190
    if (pObj->parserLen > 0 && pObj->parser != NULL) {
×
2191
      buf[0] = 0;
×
2192
      STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->parser, pShow->pMeta->pSchemas[cols].bytes);
×
2193
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2194
      code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
×
2195
      if (code != 0) goto _end;
×
2196
    } else {
2197
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2198
      colDataSetNULL(pColInfo, numOfRows);
×
2199
    }
2200

2201
    // via
2202
    if (pObj->via != 0) {
×
2203
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2204
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->via, false);
×
2205
      if (code != 0) goto _end;
×
2206
    } else {
2207
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2208
      colDataSetNULL(pColInfo, numOfRows);
×
2209
    }
2210

2211
    // xnode_id
2212
    if (pObj->xnodeId != 0) {
×
2213
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2214
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->xnodeId, false);
×
2215
      if (code != 0) goto _end;
×
2216
    } else {
2217
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2218
      colDataSetNULL(pColInfo, numOfRows);
×
2219
    }
2220

2221
    // status
2222
    if (pObj->statusLen > 0) {
×
2223
      buf[0] = 0;
×
2224
      STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->status, pShow->pMeta->pSchemas[cols].bytes);
×
2225
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2226
      code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
×
2227
      if (code != 0) goto _end;
×
2228
    } else {
2229
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2230
      colDataSetNULL(pColInfo, numOfRows);
×
2231
    }
2232

2233
    // reason
2234
    if (pObj->reasonLen > 0) {
×
2235
      buf[0] = 0;
×
2236
      STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->reason, pShow->pMeta->pSchemas[cols].bytes);
×
2237
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2238
      code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
×
2239
      if (code != 0) goto _end;
×
2240
    } else {
2241
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2242
      colDataSetNULL(pColInfo, numOfRows);
×
2243
    }
2244

2245
    // create_by
2246
    if (pObj->createdByLen > 0) {
×
2247
      buf[0] = 0;
×
2248
      STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->createdBy, pShow->pMeta->pSchemas[cols].bytes);
×
2249
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2250
      code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
×
2251
      if (code != 0) goto _end;
×
2252
    } else {
2253
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2254
      colDataSetNULL(pColInfo, numOfRows);
×
2255
    }
2256

2257
    // labels
2258
    if (pObj->labelsLen > 0) {
×
2259
      buf[0] = 0;
×
2260
      STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->labels, pShow->pMeta->pSchemas[cols].bytes);
×
2261
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2262
      code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
×
2263
      if (code != 0) goto _end;
×
2264
    } else {
2265
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2266
      colDataSetNULL(pColInfo, numOfRows);
×
2267
    }
2268

2269
    // create_time
2270
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2271
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->createTime, false);
×
2272
    if (code != 0) goto _end;
×
2273

2274
    // update_time
2275
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
2276
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->updateTime, false);
×
2277
    if (code != 0) goto _end;
×
2278

2279
    numOfRows++;
×
2280
    sdbRelease(pSdb, pObj);
×
2281
  }
2282

2283
_end:
3,374✔
2284
  if (code != 0 && pObj != NULL) sdbRelease(pSdb, pObj);
3,374✔
2285

2286
  pShow->numOfRows += numOfRows;
3,374✔
2287
  return numOfRows;
3,374✔
2288
}
2289

2290
static void mndCancelGetNextXnodeTask(SMnode *pMnode, void *pIter) {
×
2291
  SSdb *pSdb = pMnode->pSdb;
×
2292
  sdbCancelFetchByType(pSdb, pIter, SDB_XNODE_TASK);
×
2293
}
×
2294

2295
/** xnode job section **/
2296

2297
static int32_t mndAcquireXnodeJobsByTaskId(SMnode *pMnode, int32_t tid, SArray **ppArray) {
×
2298
  int32_t code = 0;
×
2299
  SSdb   *pSdb = pMnode->pSdb;
×
2300

2301
  *ppArray = taosArrayInit(16, sizeof(SXnodeJobObj));
×
2302
  if (ppArray == NULL) {
×
2303
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2304
    if (terrno != 0) code = terrno;
×
2305
    goto _exit;
×
2306
  }
2307

2308
  int32_t idx = 0;
×
2309
  void   *pIter = NULL;
×
2310
  while (1) {
×
2311
    SXnodeJobObj *pJob = NULL;
×
2312
    pIter = sdbFetch(pSdb, SDB_XNODE_JOB, pIter, (void **)&pJob);
×
2313
    if (pIter == NULL) break;
×
2314

2315
    if (pJob->taskId == tid) {
×
2316
      if (NULL == taosArrayInsert(*ppArray, idx++, pJob)) {
×
2317
        code = terrno;
×
2318
        sdbRelease(pSdb, pJob);
×
2319
        goto _exit;
×
2320
      }
2321
    }
2322

2323
    sdbRelease(pSdb, pJob);
×
2324
  }
2325
  sdbCancelFetch(pSdb, pIter);
×
2326

2327
_exit:
×
2328
  TAOS_RETURN(code);
×
2329
}
2330

2331
static int32_t mndAcquireXnodeJobsAll(SMnode *pMnode, SArray **ppArray) {
15,147✔
2332
  int32_t code = 0;
15,147✔
2333
  SSdb   *pSdb = pMnode->pSdb;
15,147✔
2334

2335
  *ppArray = taosArrayInit(64, sizeof(SXnodeJobObj));
15,147✔
2336
  if (ppArray == NULL) {
15,147✔
2337
    code = terrno;
×
2338
    goto _exit;
×
2339
  }
2340

2341
  int32_t idx = 0;
15,147✔
2342
  void   *pIter = NULL;
15,147✔
2343
  while (1) {
11,745✔
2344
    SXnodeJobObj *pJob = NULL;
26,892✔
2345
    pIter = sdbFetch(pSdb, SDB_XNODE_JOB, pIter, (void **)&pJob);
26,892✔
2346
    if (pIter == NULL) break;
26,892✔
2347
    if (NULL == taosArrayInsert(*ppArray, idx++, pJob)) {
11,745✔
2348
      code = terrno;
×
2349
      goto _exit;
×
2350
    }
2351
    sdbRelease(pSdb, pJob);
11,745✔
2352
  }
2353
  sdbCancelFetch(pSdb, pIter);
15,147✔
2354

2355
_exit:
15,147✔
2356
  TAOS_RETURN(code);
15,147✔
2357
}
2358

2359
static void mndFreeXnodeJob(SXnodeJobObj *pObj) {
13,851✔
2360
  if (NULL == pObj) {
13,851✔
2361
    return;
×
2362
  }
2363
  if (NULL != pObj->config) {
13,851✔
2364
    taosMemoryFreeClear(pObj->config);
13,851✔
2365
  }
2366
  if (NULL != pObj->reason) {
13,851✔
2367
    taosMemoryFreeClear(pObj->reason);
×
2368
  }
2369
  if (NULL != pObj->status) {
13,851✔
2370
    taosMemoryFreeClear(pObj->status);
10,935✔
2371
  }
2372
}
2373

2374
SSdbRaw *mndXnodeJobActionEncode(SXnodeJobObj *pObj) {
14,985✔
2375
  int32_t code = 0;
14,985✔
2376
  int32_t lino = 0;
14,985✔
2377
  terrno = TSDB_CODE_OUT_OF_MEMORY;
14,985✔
2378

2379
  if (NULL == pObj) {
14,985✔
2380
    terrno = TSDB_CODE_INVALID_PARA;
×
2381
    return NULL;
×
2382
  }
2383

2384
  mDebug("xnode tid:%d, jid:%d, start to encode to raw, row:%p", pObj->taskId, pObj->id, pObj);
14,985✔
2385

2386
  int32_t rawDataLen = sizeof(SXnodeJobObj) + TSDB_XNODE_RESERVE_SIZE + pObj->configLen + pObj->reasonLen;
14,985✔
2387

2388
  SSdbRaw *pRaw = sdbAllocRaw(SDB_XNODE_JOB, TSDB_XNODE_VER_NUMBER, rawDataLen);
14,985✔
2389
  if (pRaw == NULL) goto _OVER;
14,985✔
2390

2391
  int32_t dataPos = 0;
14,985✔
2392
  SDB_SET_INT32(pRaw, dataPos, pObj->id, _OVER)
14,985✔
2393
  SDB_SET_INT32(pRaw, dataPos, pObj->taskId, _OVER)
14,985✔
2394
  SDB_SET_INT32(pRaw, dataPos, pObj->configLen, _OVER)
14,985✔
2395
  SDB_SET_BINARY(pRaw, dataPos, pObj->config, pObj->configLen, _OVER)
14,985✔
2396
  SDB_SET_INT32(pRaw, dataPos, pObj->via, _OVER)
14,985✔
2397
  SDB_SET_INT32(pRaw, dataPos, pObj->xnodeId, _OVER)
14,985✔
2398
  SDB_SET_INT32(pRaw, dataPos, pObj->statusLen, _OVER)
14,985✔
2399
  SDB_SET_BINARY(pRaw, dataPos, pObj->status, pObj->statusLen, _OVER)
14,985✔
2400
  SDB_SET_INT32(pRaw, dataPos, pObj->reasonLen, _OVER)
14,985✔
2401
  SDB_SET_BINARY(pRaw, dataPos, pObj->reason, pObj->reasonLen, _OVER)
14,985✔
2402
  SDB_SET_INT64(pRaw, dataPos, pObj->createTime, _OVER)
14,985✔
2403
  SDB_SET_INT64(pRaw, dataPos, pObj->updateTime, _OVER)
14,985✔
2404

2405
  SDB_SET_RESERVE(pRaw, dataPos, TSDB_XNODE_RESERVE_SIZE, _OVER)
14,985✔
2406

2407
  terrno = 0;
14,985✔
2408

2409
_OVER:
14,985✔
2410
  if (terrno != 0) {
14,985✔
2411
    mError("xnode tid:%d, jid:%d, failed to encode to raw:%p since %s", pObj->taskId, pObj->id, pRaw, terrstr());
×
2412
    sdbFreeRaw(pRaw);
×
2413
    return NULL;
×
2414
  }
2415

2416
  mTrace("xnode tid:%d, jid:%d, encode to raw:%p, row:%p", pObj->taskId, pObj->id, pRaw, pObj);
14,985✔
2417
  return pRaw;
14,985✔
2418
}
2419

2420
SSdbRow *mndXnodeJobActionDecode(SSdbRaw *pRaw) {
11,016✔
2421
  mInfo("xnode, start to decode from raw:%p", pRaw);
11,016✔
2422
  int32_t code = 0;
11,016✔
2423
  int32_t lino = 0;
11,016✔
2424
  terrno = TSDB_CODE_OUT_OF_MEMORY;
11,016✔
2425
  SSdbRow      *pRow = NULL;
11,016✔
2426
  SXnodeJobObj *pObj = NULL;
11,016✔
2427

2428
  if (NULL == pRaw) {
11,016✔
2429
    terrno = TSDB_CODE_INVALID_PARA;
×
2430
    return NULL;
×
2431
  }
2432

2433
  int8_t sver = 0;
11,016✔
2434
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
11,016✔
2435

2436
  if (sver != TSDB_XNODE_VER_NUMBER) {
11,016✔
2437
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
2438
    goto _OVER;
×
2439
  }
2440

2441
  pRow = sdbAllocRow(sizeof(SXnodeJobObj));
11,016✔
2442
  if (pRow == NULL) goto _OVER;
11,016✔
2443

2444
  pObj = sdbGetRowObj(pRow);
11,016✔
2445
  if (pObj == NULL) goto _OVER;
11,016✔
2446

2447
  int32_t dataPos = 0;
11,016✔
2448
  SDB_GET_INT32(pRaw, dataPos, &pObj->id, _OVER)
11,016✔
2449
  SDB_GET_INT32(pRaw, dataPos, &pObj->taskId, _OVER)
11,016✔
2450

2451
  SDB_GET_INT32(pRaw, dataPos, &pObj->configLen, _OVER)
11,016✔
2452
  if (pObj->configLen > 0) {
11,016✔
2453
    pObj->config = taosMemoryCalloc(pObj->configLen, 1);
11,016✔
2454
    if (pObj->config == NULL) goto _OVER;
11,016✔
2455
    SDB_GET_BINARY(pRaw, dataPos, pObj->config, pObj->configLen, _OVER)
11,016✔
2456
  }
2457

2458
  SDB_GET_INT32(pRaw, dataPos, &pObj->via, _OVER)
11,016✔
2459
  SDB_GET_INT32(pRaw, dataPos, &pObj->xnodeId, _OVER)
11,016✔
2460
  SDB_GET_INT32(pRaw, dataPos, &pObj->statusLen, _OVER)
11,016✔
2461
  if (pObj->statusLen > 0) {
11,016✔
2462
    pObj->status = taosMemoryCalloc(pObj->statusLen, 1);
8,748✔
2463
    if (pObj->status == NULL) goto _OVER;
8,748✔
2464
    SDB_GET_BINARY(pRaw, dataPos, pObj->status, pObj->statusLen, _OVER)
8,748✔
2465
  }
2466

2467
  SDB_GET_INT32(pRaw, dataPos, &pObj->reasonLen, _OVER)
11,016✔
2468
  if (pObj->reasonLen > 0) {
11,016✔
2469
    pObj->reason = taosMemoryCalloc(pObj->reasonLen, 1);
×
2470
    if (pObj->reason == NULL) goto _OVER;
×
2471
    SDB_GET_BINARY(pRaw, dataPos, pObj->reason, pObj->reasonLen, _OVER)
×
2472
  }
2473

2474
  SDB_GET_INT64(pRaw, dataPos, &pObj->createTime, _OVER)
11,016✔
2475
  SDB_GET_INT64(pRaw, dataPos, &pObj->updateTime, _OVER)
11,016✔
2476

2477
  SDB_GET_RESERVE(pRaw, dataPos, TSDB_XNODE_RESERVE_SIZE, _OVER)
11,016✔
2478

2479
  terrno = 0;
11,016✔
2480

2481
_OVER:
11,016✔
2482
  if (terrno != 0) {
11,016✔
2483
    mError("xnode tid:%d, jid:%d, failed to decode from raw:%p since %s", pObj == NULL ? 0 : pObj->taskId,
×
2484
           pObj == NULL ? 0 : pObj->id, pRaw, terrstr());
2485
    if (pObj != NULL) {
×
2486
      taosMemoryFreeClear(pObj->config);
×
2487
      taosMemoryFreeClear(pObj->reason);
×
2488
      taosMemoryFreeClear(pObj->status);
×
2489
    }
2490
    taosMemoryFreeClear(pRow);
×
2491
    return NULL;
×
2492
  }
2493

2494
  mTrace("xnode:%d, decode from raw:%p, row:%p", pObj->id, pRaw, pObj);
11,016✔
2495
  return pRow;
11,016✔
2496
}
2497

2498
int32_t mndXnodeJobActionInsert(SSdb *pSdb, SXnodeJobObj *pObj) {
2,835✔
2499
  mInfo("xnode tid:%d, jid:%d, perform insert action, row:%p", pObj->taskId, pObj->id, pObj);
2,835✔
2500
  return 0;
2,835✔
2501
}
2502

2503
int32_t mndXnodeJobActionDelete(SSdb *pSdb, SXnodeJobObj *pObj) {
11,016✔
2504
  mDebug("xnode tid:%d, jid:%d, perform delete action, row:%p", pObj->taskId, pObj->id, pObj);
11,016✔
2505
  mndFreeXnodeJob(pObj);
11,016✔
2506
  return 0;
11,016✔
2507
}
2508

2509
int32_t mndXnodeJobActionUpdate(SSdb *pSdb, SXnodeJobObj *pOld, SXnodeJobObj *pNew) {
5,508✔
2510
  mDebug("xnode tid:%d, jid:%d, perform update action, old row:%p new row:%p", pOld->taskId, pOld->id, pOld, pNew);
5,508✔
2511

2512
  taosWLockLatch(&pOld->lock);
5,508✔
2513
  pOld->via = pNew->via;
5,508✔
2514
  pOld->xnodeId = pNew->xnodeId;
5,508✔
2515
  swapFields(&pNew->statusLen, &pNew->status, &pOld->statusLen, &pOld->status);
5,508✔
2516
  swapFields(&pNew->configLen, &pNew->config, &pOld->configLen, &pOld->config);
5,508✔
2517
  swapFields(&pNew->reasonLen, &pNew->reason, &pOld->reasonLen, &pOld->reason);
5,508✔
2518
  if (pNew->updateTime > pOld->updateTime) {
5,508✔
2519
    pOld->updateTime = pNew->updateTime;
×
2520
  }
2521
  taosWUnLockLatch(&pOld->lock);
5,508✔
2522
  return 0;
5,508✔
2523
}
2524

2525
/* xnode user pass actions */
2526
SSdbRaw *mndXnodeUserPassActionEncode(SXnodeUserPassObj *pObj) {
1,224✔
2527
  int32_t code = 0;
1,224✔
2528
  int32_t lino = 0;
1,224✔
2529
  terrno = TSDB_CODE_OUT_OF_MEMORY;
1,224✔
2530

2531
  if (NULL == pObj) {
1,224✔
2532
    terrno = TSDB_CODE_INVALID_PARA;
×
2533
    return NULL;
×
2534
  }
2535

2536
  int32_t rawDataLen =
1,224✔
2537
      sizeof(SXnodeUserPassObj) + TSDB_XNODE_RESERVE_SIZE + pObj->userLen + pObj->passLen + pObj->tokenLen;
1,224✔
2538

2539
  SSdbRaw *pRaw = sdbAllocRaw(SDB_XNODE_USER_PASS, TSDB_XNODE_VER_NUMBER, rawDataLen);
1,224✔
2540
  if (pRaw == NULL) goto _OVER;
1,224✔
2541

2542
  int32_t dataPos = 0;
1,224✔
2543
  SDB_SET_INT32(pRaw, dataPos, pObj->id, _OVER)
1,224✔
2544
  SDB_SET_INT32(pRaw, dataPos, pObj->userLen, _OVER)
1,224✔
2545
  SDB_SET_BINARY(pRaw, dataPos, pObj->user, pObj->userLen, _OVER)
1,224✔
2546
  SDB_SET_INT32(pRaw, dataPos, pObj->passLen, _OVER)
1,224✔
2547
  SDB_SET_BINARY(pRaw, dataPos, pObj->pass, pObj->passLen, _OVER)
1,224✔
2548
  SDB_SET_INT32(pRaw, dataPos, pObj->tokenLen, _OVER)
1,224✔
2549
  SDB_SET_BINARY(pRaw, dataPos, pObj->token, pObj->tokenLen, _OVER)
1,224✔
2550
  SDB_SET_INT64(pRaw, dataPos, pObj->createTime, _OVER)
1,224✔
2551
  SDB_SET_INT64(pRaw, dataPos, pObj->updateTime, _OVER)
1,224✔
2552

2553
  SDB_SET_RESERVE(pRaw, dataPos, TSDB_XNODE_RESERVE_SIZE, _OVER)
1,224✔
2554

2555
  terrno = 0;
1,224✔
2556

2557
_OVER:
1,224✔
2558
  if (terrno != 0) {
1,224✔
2559
    mError("xnode user pass:%d, failed to encode to raw:%p since %s", pObj->id, pRaw, terrstr());
×
2560
    sdbFreeRaw(pRaw);
×
2561
    return NULL;
×
2562
  }
2563

2564
  mTrace("xnode user pass:%d, encode to raw:%p, row:%p", pObj->id, pRaw, pObj);
1,224✔
2565
  return pRaw;
1,224✔
2566
}
2567
SSdbRow *mndXnodeUserPassActionDecode(SSdbRaw *pRaw) {
870✔
2568
  int32_t code = 0;
870✔
2569
  int32_t lino = 0;
870✔
2570
  terrno = TSDB_CODE_OUT_OF_MEMORY;
870✔
2571
  SSdbRow           *pRow = NULL;
870✔
2572
  SXnodeUserPassObj *pObj = NULL;
870✔
2573

2574
  if (NULL == pRaw) {
870✔
2575
    terrno = TSDB_CODE_INVALID_PARA;
×
2576
    return NULL;
×
2577
  }
2578

2579
  int8_t sver = 0;
870✔
2580
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
870✔
2581

2582
  if (sver != TSDB_XNODE_VER_NUMBER) {
870✔
2583
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
2584
    goto _OVER;
×
2585
  }
2586

2587
  pRow = sdbAllocRow(sizeof(SXnodeUserPassObj));
870✔
2588
  if (pRow == NULL) goto _OVER;
870✔
2589

2590
  pObj = sdbGetRowObj(pRow);
870✔
2591
  if (pObj == NULL) goto _OVER;
870✔
2592

2593
  int32_t dataPos = 0;
870✔
2594
  SDB_GET_INT32(pRaw, dataPos, &pObj->id, _OVER)
870✔
2595
  SDB_GET_INT32(pRaw, dataPos, &pObj->userLen, _OVER)
870✔
2596
  if (pObj->userLen > 0) {
870✔
2597
    pObj->user = taosMemoryCalloc(1, pObj->userLen + 1);
546✔
2598
    if (pObj->user == NULL) goto _OVER;
546✔
2599
    SDB_GET_BINARY(pRaw, dataPos, pObj->user, pObj->userLen, _OVER)
546✔
2600
  }
2601
  SDB_GET_INT32(pRaw, dataPos, &pObj->passLen, _OVER)
870✔
2602
  if (pObj->passLen > 0) {
870✔
2603
    pObj->pass = taosMemoryCalloc(1, pObj->passLen + 1);
546✔
2604
    if (pObj->pass == NULL) goto _OVER;
546✔
2605
    SDB_GET_BINARY(pRaw, dataPos, pObj->pass, pObj->passLen, _OVER)
546✔
2606
  }
2607
  SDB_GET_INT32(pRaw, dataPos, &pObj->tokenLen, _OVER)
870✔
2608
  if (pObj->tokenLen > 0) {
870✔
2609
    pObj->token = taosMemoryCalloc(1, pObj->tokenLen + 1);
324✔
2610
    if (pObj->token == NULL) goto _OVER;
324✔
2611
    SDB_GET_BINARY(pRaw, dataPos, pObj->token, pObj->tokenLen, _OVER)
324✔
2612
  }
2613
  SDB_GET_INT64(pRaw, dataPos, &pObj->createTime, _OVER)
870✔
2614
  SDB_GET_INT64(pRaw, dataPos, &pObj->updateTime, _OVER)
870✔
2615

2616
  SDB_GET_RESERVE(pRaw, dataPos, TSDB_XNODE_RESERVE_SIZE, _OVER)
870✔
2617

2618
  terrno = 0;
870✔
2619

2620
_OVER:
870✔
2621
  if (terrno != 0) {
870✔
2622
    mError("xnode user pass:%d, failed to decode from raw:%p since %s", pObj == NULL ? 0 : pObj->id, pRaw, terrstr());
×
2623
    if (pObj != NULL) {
×
2624
      if (pObj->user != NULL) {
×
2625
        taosMemoryFreeClear(pObj->user);
×
2626
      }
2627
      if (pObj->pass != NULL) {
×
2628
        taosMemoryFreeClear(pObj->pass);
×
2629
      }
2630
    }
2631
    taosMemoryFreeClear(pRow);
×
2632
    return NULL;
×
2633
  }
2634

2635
  mTrace("xnode user pass:%d, decode from raw:%p, row:%p", pObj->id, pRaw, pObj);
870✔
2636
  return pRow;
870✔
2637
}
2638
int32_t mndXnodeUserPassActionInsert(SSdb *pSdb, SXnodeUserPassObj *pObj) {
273✔
2639
  mDebug("xnode user pass:%d, perform insert action, row:%p", pObj->id, pObj);
273✔
2640
  return 0;
273✔
2641
}
2642
int32_t mndXnodeUserPassActionUpdate(SSdb *pSdb, SXnodeUserPassObj *pOld, SXnodeUserPassObj *pNew) {
597✔
2643
  mDebug("xnode user pass:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew);
597✔
2644
  taosWLockLatch(&pOld->lock);
597✔
2645
  if (pNew->updateTime > pOld->updateTime) {
597✔
2646
    pOld->updateTime = pNew->updateTime;
405✔
2647
  }
2648
  char* tmp = NULL;
597✔
2649
  pOld->userLen = pNew->userLen;
597✔
2650
  tmp = pOld->user;
597✔
2651
  pOld->user = pNew->user;
597✔
2652
  pNew->user = tmp;
597✔
2653

2654
  pOld->passLen = pNew->passLen;
597✔
2655
  tmp = pOld->pass;
597✔
2656
  pOld->pass = pNew->pass;
597✔
2657
  pNew->pass = tmp;
597✔
2658

2659
  pOld->tokenLen = pNew->tokenLen;
597✔
2660
  tmp = pOld->token;
597✔
2661
  pOld->token = pNew->token;
597✔
2662
  pNew->token = tmp;
597✔
2663
  
2664
  // swapFields(&pNew->userLen, &pNew->user, &pOld->userLen, &pOld->user);
2665
  // swapFields(&pNew->passLen, &pNew->pass, &pOld->passLen, &pOld->pass);
2666
  // swapFields(&pNew->tokenLen, &pNew->token, &pOld->tokenLen, &pOld->token);
2667
  // SXnodeUserPassObj* tmp = pNew;
2668
  // pNew = pOld;
2669
  // pOld = tmp;
2670
  
2671
  taosWUnLockLatch(&pOld->lock);
597✔
2672
  return 0;
597✔
2673
}
2674
int32_t mndXnodeUserPassActionDelete(SSdb *pSdb, SXnodeUserPassObj *pObj) {
870✔
2675
  mDebug("xnode:%d, perform delete action, row:%p", pObj->id, pObj);
870✔
2676
  taosMemoryFreeClear(pObj->user);
870✔
2677
  taosMemoryFreeClear(pObj->pass);
870✔
2678
  taosMemoryFreeClear(pObj->token);
870✔
2679
  return 0;
870✔
2680
}
2681

2682
static int32_t mndSetCreateXnodeJobRedoLogs(STrans *pTrans, SXnodeJobObj *pObj) {
2,835✔
2683
  int32_t  code = 0;
2,835✔
2684
  SSdbRaw *pRedoRaw = mndXnodeJobActionEncode(pObj);
2,835✔
2685
  if (pRedoRaw == NULL) {
2,835✔
2686
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2687
    if (terrno != 0) code = terrno;
×
2688
    TAOS_RETURN(code);
×
2689
  }
2690
  TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
2,835✔
2691
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING));
2,835✔
2692
  TAOS_RETURN(code);
2,835✔
2693
}
2694

2695
static int32_t mndSetCreateXnodeJobUndoLogs(STrans *pTrans, SXnodeJobObj *pObj) {
2,835✔
2696
  int32_t  code = 0;
2,835✔
2697
  SSdbRaw *pUndoRaw = mndXnodeJobActionEncode(pObj);
2,835✔
2698
  if (pUndoRaw == NULL) {
2,835✔
2699
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2700
    if (terrno != 0) code = terrno;
×
2701
    TAOS_RETURN(code);
×
2702
  }
2703
  TAOS_CHECK_RETURN(mndTransAppendUndolog(pTrans, pUndoRaw));
2,835✔
2704
  TAOS_CHECK_RETURN(sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED));
2,835✔
2705
  TAOS_RETURN(code);
2,835✔
2706
}
2707

2708
static int32_t mndSetCreateXnodeJobCommitLogs(STrans *pTrans, SXnodeJobObj *pObj) {
2,835✔
2709
  int32_t  code = 0;
2,835✔
2710
  SSdbRaw *pCommitRaw = mndXnodeJobActionEncode(pObj);
2,835✔
2711
  if (pCommitRaw == NULL) {
2,835✔
2712
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2713
    if (terrno != 0) code = terrno;
×
2714
    TAOS_RETURN(code);
×
2715
  }
2716
  TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
2,835✔
2717
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
2,835✔
2718
  TAOS_RETURN(code);
2,835✔
2719
}
2720

2721
static int32_t mndCreateXnodeJob(SMnode *pMnode, SRpcMsg *pReq, SMCreateXnodeJobReq *pCreate) {
2,835✔
2722
  int32_t code = -1;
2,835✔
2723
  STrans *pTrans = NULL;
2,835✔
2724

2725
  SXnodeJobObj jobObj = {0};
2,835✔
2726
  jobObj.id = sdbGetMaxId(pMnode->pSdb, SDB_XNODE_JOB);
2,835✔
2727
  jobObj.taskId = pCreate->tid;
2,835✔
2728

2729
  jobObj.configLen = pCreate->config.len + 1;
2,835✔
2730
  if (jobObj.configLen > TSDB_XNODE_TASK_JOB_CONFIG_LEN + 1) {
2,835✔
2731
    code = TSDB_CODE_MND_XNODE_TASK_JOB_CONFIG_TOO_LONG;
×
2732
    goto _OVER;
×
2733
  }
2734
  jobObj.config = taosMemoryCalloc(1, jobObj.configLen);
2,835✔
2735
  if (jobObj.config == NULL) goto _OVER;
2,835✔
2736
  (void)memcpy(jobObj.config, pCreate->config.ptr, pCreate->config.len);
2,835✔
2737

2738
  jobObj.via = pCreate->via;
2,835✔
2739
  jobObj.xnodeId = pCreate->xnodeId;
2,835✔
2740

2741
  if (pCreate->status.ptr != NULL) {
2,835✔
2742
    jobObj.statusLen = pCreate->status.len + 1;
2,187✔
2743
    jobObj.status = taosMemoryCalloc(1, jobObj.statusLen);
2,187✔
2744
    if (jobObj.status == NULL) goto _OVER;
2,187✔
2745
    (void)memmove(jobObj.status, pCreate->status.ptr, pCreate->status.len);
2,187✔
2746
  }
2747

2748
  if (jobObj.reason != NULL) {
2,835✔
2749
    jobObj.reasonLen = pCreate->reason.len + 1;
×
NEW
2750
    if (jobObj.reasonLen > TSDB_XNODE_TASK_REASON_LEN + 1) {
×
2751
      code = TSDB_CODE_MND_XNODE_TASK_REASON_TOO_LONG;
×
2752
      goto _OVER;
×
2753
    }
2754
    jobObj.reason = taosMemoryCalloc(1, jobObj.reasonLen);
×
2755
    if (jobObj.reason == NULL) goto _OVER;
×
2756
    (void)memcpy(jobObj.reason, pCreate->reason.ptr, pCreate->reason.len);
×
2757
  }
2758

2759
  jobObj.createTime = taosGetTimestampMs();
2,835✔
2760
  jobObj.updateTime = jobObj.createTime;
2,835✔
2761

2762
  mDebug("create xnode job, id:%d, tid:%d, config:%s, time:%" PRId64, jobObj.id, jobObj.taskId, jobObj.config,
2,835✔
2763
         jobObj.createTime);
2764

2765
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-xnode-job");
2,835✔
2766
  if (pTrans == NULL) {
2,835✔
2767
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
2768
    if (terrno != 0) code = terrno;
×
2769
    mInfo("failed to create transaction for xnode-job:%d, code:0x%x:%s", pCreate->tid, code, tstrerror(code));
×
2770
    goto _OVER;
×
2771
  }
2772
  mndTransSetSerial(pTrans);
2,835✔
2773

2774
  mInfo("trans:%d, used to create xnode job on %d as jid:%d", pTrans->id, pCreate->tid, jobObj.id);
2,835✔
2775

2776
  TAOS_CHECK_GOTO(mndSetCreateXnodeJobRedoLogs(pTrans, &jobObj), NULL, _OVER);
2,835✔
2777
  TAOS_CHECK_GOTO(mndSetCreateXnodeJobUndoLogs(pTrans, &jobObj), NULL, _OVER);
2,835✔
2778
  TAOS_CHECK_GOTO(mndSetCreateXnodeJobCommitLogs(pTrans, &jobObj), NULL, _OVER);
2,835✔
2779
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
2,835✔
2780

2781
  code = 0;
2,835✔
2782

2783
_OVER:
2,835✔
2784
  mndFreeXnodeJob(&jobObj);
2,835✔
2785
  mndTransDrop(pTrans);
2,835✔
2786
  TAOS_RETURN(code);
2,835✔
2787
}
2788

2789
static int32_t mndUpdateXnodeJob(SMnode *pMnode, SRpcMsg *pReq, SXnodeJobObj *pOld, SMUpdateXnodeJobReq *pUpdate) {
×
2790
  mInfo("xnode job:%d, start to update", pUpdate->jid);
×
2791
  int32_t      code = -1;
×
2792
  STrans      *pTrans = NULL;
×
2793
  SXnodeJobObj jobObj = *pOld;
×
2794
  struct {
2795
    bool status;
2796
    bool config;
2797
    bool reason;
2798
  } isChange = {0};
×
2799

2800
  jobObj.id = pUpdate->jid;
×
2801
  if (pUpdate->via > 0) {
×
2802
    jobObj.via = pUpdate->via;
×
2803
  }
2804
  if (pUpdate->xnodeId > 0) {
×
2805
    jobObj.xnodeId = pUpdate->xnodeId;
×
2806
  }
2807
  if (pUpdate->status.ptr != NULL) {
×
2808
    jobObj.statusLen = pUpdate->status.len + 1;
×
2809
    jobObj.status = taosMemoryCalloc(1, jobObj.statusLen);
×
2810
    if (jobObj.status == NULL) goto _OVER;
×
2811
    (void)memcpy(jobObj.status, pUpdate->status.ptr, pUpdate->status.len);
×
2812
    isChange.status = true;
×
2813
  }
2814
  if (pUpdate->config != NULL) {
×
2815
    jobObj.configLen = pUpdate->configLen + 1;
×
2816
    jobObj.config = taosMemoryCalloc(1, jobObj.configLen);
×
2817
    if (jobObj.config == NULL) goto _OVER;
×
2818
    (void)memcpy(jobObj.config, pUpdate->config, pUpdate->configLen);
×
2819
    isChange.config = true;
×
2820
  }
2821
  if (pUpdate->reason != NULL) {
×
2822
    jobObj.reasonLen = pUpdate->reasonLen + 1;
×
2823
    jobObj.reason = taosMemoryCalloc(1, jobObj.reasonLen);
×
2824
    if (jobObj.reason == NULL) goto _OVER;
×
2825
    (void)memcpy(jobObj.reason, pUpdate->reason, pUpdate->reasonLen);
×
2826
    isChange.reason = true;
×
2827
  }
2828
  jobObj.updateTime = taosGetTimestampMs();
×
2829

2830
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "update-xnode");
×
2831
  if (pTrans == NULL) {
×
NEW
2832
    code = terrno;
×
2833
    goto _OVER;
×
2834
  }
2835
  mInfo("trans:%d, used to update xnode job:%d", pTrans->id, jobObj.id);
×
2836

2837
  TAOS_CHECK_GOTO(mndSetCreateXnodeJobCommitLogs(pTrans, &jobObj), NULL, _OVER);
×
2838
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
×
2839
  code = 0;
×
2840

2841
_OVER:
×
2842
  if (NULL != jobObj.status && isChange.status) {
×
2843
    taosMemoryFree(jobObj.status);
×
2844
  }
2845
  if (NULL != jobObj.config && isChange.config) {
×
2846
    taosMemoryFree(jobObj.config);
×
2847
  }
2848
  if (NULL != jobObj.reason && isChange.reason) {
×
2849
    taosMemoryFree(jobObj.reason);
×
2850
  }
2851
  mndTransDrop(pTrans);
×
2852
  TAOS_RETURN(code);
×
2853
}
2854

2855
void mndReleaseXnodeTaskJob(SMnode *pMnode, SXnodeJobObj *pObj) {
×
2856
  SSdb *pSdb = pMnode->pSdb;
×
2857
  sdbRelease(pSdb, pObj);
×
2858
}
×
2859

2860
SXnodeJobObj *mndAcquireXnodeJob(SMnode *pMnode, int32_t jid) {
2,673✔
2861
  SXnodeJobObj *pObj = sdbAcquire(pMnode->pSdb, SDB_XNODE_JOB, &jid);
2,673✔
2862
  if (pObj == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
2,673✔
2863
    terrno = TSDB_CODE_MND_XNODE_JOB_NOT_EXIST;
2,430✔
2864
  }
2865
  return pObj;
2,673✔
2866
}
2867
void mndReleaseXnodeJob(SMnode *pMnode, SXnodeJobObj *pObj) {
2,673✔
2868
  SSdb *pSdb = pMnode->pSdb;
2,673✔
2869
  sdbRelease(pSdb, pObj);
2,673✔
2870
}
2,673✔
2871

2872
static int32_t mndSetDropXnodeJobRedoLogs(STrans *pTrans, SXnodeJobObj *pObj) {
2,673✔
2873
  int32_t  code = 0;
2,673✔
2874
  SSdbRaw *pRedoRaw = mndXnodeJobActionEncode(pObj);
2,673✔
2875
  if (pRedoRaw == NULL) {
2,673✔
2876
    code = terrno;
×
2877
    return code;
×
2878
  }
2879

2880
  TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
2,673✔
2881
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING));
2,673✔
2882

2883
  return code;
2,673✔
2884
}
2885

2886
static int32_t mndSetDropXnodeJobCommitLogs(STrans *pTrans, SXnodeJobObj *pObj) {
2,673✔
2887
  int32_t  code = 0;
2,673✔
2888
  SSdbRaw *pCommitRaw = mndXnodeJobActionEncode(pObj);
2,673✔
2889
  if (pCommitRaw == NULL) {
2,673✔
2890
    code = terrno;
×
2891
    return code;
×
2892
  }
2893

2894
  TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
2,673✔
2895
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED));
2,673✔
2896
  TAOS_RETURN(code);
2,673✔
2897
}
2898
static int32_t mndSetDropXnodeJobInfoToTrans(STrans *pTrans, SXnodeJobObj *pObj, bool force) {
2,673✔
2899
  if (pObj == NULL) {
2,673✔
2900
    return 0;
×
2901
  }
2902
  TAOS_CHECK_RETURN(mndSetDropXnodeJobRedoLogs(pTrans, pObj));
2,673✔
2903
  TAOS_CHECK_RETURN(mndSetDropXnodeJobCommitLogs(pTrans, pObj));
2,673✔
2904
  return 0;
2,673✔
2905
}
2906

2907
static int32_t mndDropXnodeJob(SMnode *pMnode, SRpcMsg *pReq, SXnodeJobObj *pObj) {
2,673✔
2908
  int32_t code = 0;
2,673✔
2909
  int32_t lino = 0;
2,673✔
2910

2911
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq, "drop-xnode-job");
2,673✔
2912
  TSDB_CHECK_NULL(pTrans, code, lino, _OVER, terrno);
2,673✔
2913

2914
  mndTransSetSerial(pTrans);
2,673✔
2915
  mInfo("trans:%d, to drop xnode:%d", pTrans->id, pObj->id);
2,673✔
2916

2917
  code = mndSetDropXnodeJobInfoToTrans(pTrans, pObj, false);
2,673✔
2918

2919
  TSDB_CHECK_CODE(code, lino, _OVER);
2,673✔
2920

2921
  code = mndTransPrepare(pMnode, pTrans);
2,673✔
2922

2923
_OVER:
2,673✔
2924
  mndTransDrop(pTrans);
2,673✔
2925
  return code;
2,673✔
2926
}
2927
static int32_t mndProcessCreateXnodeJobReq(SRpcMsg *pReq) {
2,835✔
2928
  mDebug("create xnode job req, content len:%d", pReq->contLen);
2,835✔
2929
  SMnode             *pMnode = pReq->info.node;
2,835✔
2930
  int32_t             code = -1;
2,835✔
2931
  SMCreateXnodeJobReq createReq = {0};
2,835✔
2932

2933
  if ((code = grantCheck(TSDB_GRANT_XNODE)) != TSDB_CODE_SUCCESS) {
2,835✔
2934
    mError("failed to create xnode, code:%s", tstrerror(code));
×
2935
    goto _OVER;
×
2936
  }
2937

2938
  TAOS_CHECK_GOTO(tDeserializeSMCreateXnodeJobReq(pReq->pCont, pReq->contLen, &createReq), NULL, _OVER);
2,835✔
2939

2940
  mDebug("xnode create job on xnode:%d", createReq.xnodeId);
2,835✔
2941
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_CREATE_XNODE_JOB), NULL, _OVER);
2,835✔
2942

2943
  code = mndCreateXnodeJob(pMnode, pReq, &createReq);
2,835✔
2944
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
2,835✔
2945

2946
_OVER:
2,835✔
2947
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
2,835✔
2948
    mError("xnode task job on task id:%d, failed to create since %s", createReq.tid, tstrerror(code));
×
2949
  }
2950

2951
  tFreeSMCreateXnodeJobReq(&createReq);
2,835✔
2952
  TAOS_RETURN(code);
2,835✔
2953
}
2954

2955
static int32_t mndProcessUpdateXnodeJobReq(SRpcMsg *pReq) {
×
2956
  SMnode             *pMnode = pReq->info.node;
×
2957
  int32_t             code = -1;
×
2958
  SXnodeJobObj       *pObj = NULL;
×
2959
  SMUpdateXnodeJobReq updateReq = {0};
×
2960

2961
  if ((code = grantCheck(TSDB_GRANT_TD_GPT)) != TSDB_CODE_SUCCESS) {
×
2962
    mError("failed to create xnode, code:%s", tstrerror(code));
×
2963
    goto _OVER;
×
2964
  }
2965

2966
  TAOS_CHECK_GOTO(tDeserializeSMUpdateXnodeJobReq(pReq->pCont, pReq->contLen, &updateReq), NULL, _OVER);
×
2967

2968
  pObj = mndAcquireXnodeJob(pMnode, updateReq.jid);
×
2969
  if (pObj == NULL) {
×
2970
    code = terrno;
×
2971
    goto _OVER;
×
2972
  }
2973

2974
  code = mndUpdateXnodeJob(pMnode, pReq, pObj, &updateReq);
×
2975
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
×
2976

2977
_OVER:
×
2978
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
×
2979
    mError("xnode task job on jid:%d, failed to update since %s", updateReq.jid, tstrerror(code));
×
2980
  }
2981

2982
  mndReleaseXnodeJob(pMnode, pObj);
×
2983
  tFreeSMUpdateXnodeJobReq(&updateReq);
×
2984
  TAOS_RETURN(code);
×
2985

2986
  return 0;
2987
}
2988

2989
static int32_t mndProcessRebalanceXnodeJobReq(SRpcMsg *pReq) {
1,620✔
2990
  SMnode                *pMnode = pReq->info.node;
1,620✔
2991
  int32_t                code = -1;
1,620✔
2992
  SXnodeJobObj          *pObj = NULL;
1,620✔
2993
  SMRebalanceXnodeJobReq rebalanceReq = {0};
1,620✔
2994
  SJson                 *pJson = NULL;
1,620✔
2995

2996
  TAOS_CHECK_GOTO(tDeserializeSMRebalanceXnodeJobReq(pReq->pCont, pReq->contLen, &rebalanceReq), NULL, _OVER);
1,620✔
2997

2998
  mDebug("RebalanceXnodeJob with jid:%d, xnode_id:%d, start to rebalance", rebalanceReq.jid, rebalanceReq.xnodeId);
1,620✔
2999
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_REBALANCE_XNODE_JOB), NULL, _OVER);
1,620✔
3000

3001
  if (rebalanceReq.jid <= 0) {
1,620✔
3002
    code = TSDB_CODE_INVALID_MSG;
×
3003
    goto _OVER;
×
3004
  }
3005

3006
  pObj = mndAcquireXnodeJob(pMnode, rebalanceReq.jid);
1,620✔
3007
  if (pObj == NULL) {
1,620✔
3008
    code = terrno;
1,620✔
3009
    goto _OVER;
1,620✔
3010
  }
3011

3012
  // send request
3013
  char xnodeUrl[TSDB_XNODE_URL_LEN + 1] = {0};
×
NEW
3014
  snprintf(xnodeUrl, TSDB_XNODE_URL_LEN + 1, "%s/rebalance/manual/%d/%d/%d", XNODED_PIPE_SOCKET_URL, pObj->taskId, pObj->id,
×
3015
           rebalanceReq.xnodeId);
NEW
3016
  pJson = mndSendReqRetJson(xnodeUrl, HTTP_TYPE_POST, defaultTimeout, NULL, 0);
×
3017

3018
_OVER:
1,620✔
3019
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,620✔
3020
    mError("xnode:%d, failed to rebalance xnode job since %s", rebalanceReq.jid, tstrerror(code));
1,620✔
3021
  }
3022
  if (pJson != NULL) {
1,620✔
3023
    tjsonDelete(pJson);
×
3024
  }
3025
  mndReleaseXnodeJob(pMnode, pObj);
1,620✔
3026
  tFreeSMRebalanceXnodeJobReq(&rebalanceReq);
1,620✔
3027
  TAOS_RETURN(code);
1,620✔
3028
}
3029

3030
typedef struct {
3031
  SValueNode nd;
3032
  bool       shouldFree;
3033
} SXndRefValueNode;
3034

3035
static void freeSXndRefValueNode(void *pNode) {
137,376✔
3036
  if (pNode == NULL) return;
137,376✔
3037

3038
  SXndRefValueNode *pRefNode = (SXndRefValueNode *)pNode;
137,376✔
3039
  if (pRefNode->shouldFree) {
137,376✔
3040
    taosMemoryFreeClear(pRefNode->nd.datum.p);
43,821✔
3041
  }
3042
}
3043

3044
typedef struct {
3045
  SArray   *stack;
3046
  SHashObj *pMap;
3047
  int32_t   code;
3048
} SXndWhereContext;
3049

3050
void freeSXndWhereContext(SXndWhereContext *pCtx) {
11,745✔
3051
  if (pCtx == NULL) return;
11,745✔
3052

3053
  if (pCtx->pMap != NULL) {
11,745✔
3054
    taosHashCleanup(pCtx->pMap);
11,745✔
3055
    pCtx->pMap = NULL;
11,745✔
3056
  }
3057
  if (pCtx->stack != NULL) {
11,745✔
3058
    for (int32_t i = 0; i < pCtx->stack->size; i++) {
21,870✔
3059
      SXndRefValueNode *pRefNode = (SXndRefValueNode *)taosArrayGet(pCtx->stack, i);
10,125✔
3060
      if (pRefNode != NULL) {
10,125✔
3061
        freeSXndRefValueNode(pRefNode);
10,125✔
3062
      }
3063
    }
3064
    taosArrayDestroy(pCtx->stack);
11,745✔
3065
    pCtx->stack = NULL;
11,745✔
3066
  }
3067
}
3068

3069
static SHashObj *convertJob2Map(const SXnodeJobObj *pJob) {
11,745✔
3070
  SHashObj *pMap = taosHashInit(256, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
11,745✔
3071
  if (pMap == NULL) {
11,745✔
3072
    return NULL;
×
3073
  }
3074
  taosHashSetFreeFp(pMap, freeSXndRefValueNode);
11,745✔
3075
  // id
3076
  SXndRefValueNode id = {0};
11,745✔
3077
  id.nd.node.type = QUERY_NODE_VALUE;
11,745✔
3078
  id.nd.node.resType.type = TSDB_DATA_TYPE_UBIGINT;
11,745✔
3079
  id.nd.datum.u = pJob->id;
11,745✔
3080
  int32_t code = taosHashPut(pMap, "id", strlen("id") + 1, &id, sizeof(SXndRefValueNode));
11,745✔
3081
  if (code != 0) {
11,745✔
3082
    taosHashCleanup(pMap);
×
3083
    return NULL;
×
3084
  }
3085
  // task id
3086
  SXndRefValueNode taskId = {0};
11,745✔
3087
  taskId.nd.node.type = QUERY_NODE_VALUE;
11,745✔
3088
  taskId.nd.node.resType.type = TSDB_DATA_TYPE_UBIGINT;
11,745✔
3089
  taskId.nd.datum.u = pJob->taskId;
11,745✔
3090
  if (pJob->taskId == 0) {
11,745✔
3091
    taskId.nd.isNull = true;
×
3092
  }
3093
  code = taosHashPut(pMap, "task_id", strlen("task_id") + 1, &taskId, sizeof(SXndRefValueNode));
11,745✔
3094
  if (code != 0) {
11,745✔
3095
    taosHashCleanup(pMap);
×
3096
    return NULL;
×
3097
  }
3098
  // via
3099
  SXndRefValueNode via = {0};
11,745✔
3100
  via.nd.node.type = QUERY_NODE_VALUE;
11,745✔
3101
  via.nd.node.resType.type = TSDB_DATA_TYPE_UBIGINT;
11,745✔
3102
  via.nd.datum.u = pJob->via;
11,745✔
3103
  if (pJob->via == 0) {
11,745✔
3104
    via.nd.isNull = true;
11,745✔
3105
  }
3106
  code = taosHashPut(pMap, "via", strlen("via") + 1, &via, sizeof(SXndRefValueNode));
11,745✔
3107
  if (code != 0) {
11,745✔
3108
    taosHashCleanup(pMap);
×
3109
    return NULL;
×
3110
  }
3111
  // xnode id
3112
  SXndRefValueNode xnodeId = {0};
11,745✔
3113
  xnodeId.nd.node.type = QUERY_NODE_VALUE;
11,745✔
3114
  xnodeId.nd.node.resType.type = TSDB_DATA_TYPE_UBIGINT;
11,745✔
3115
  xnodeId.nd.datum.u = pJob->xnodeId;
11,745✔
3116
  if (pJob->xnodeId == 0) {
11,745✔
3117
    xnodeId.nd.isNull = true;
11,745✔
3118
  }
3119
  code = taosHashPut(pMap, "xnode_id", strlen("xnode_id") + 1, &xnodeId, sizeof(SXndRefValueNode));
11,745✔
3120
  if (code != 0) {
11,745✔
3121
    taosHashCleanup(pMap);
×
3122
    return NULL;
×
3123
  }
3124
  // config
3125
  SXndRefValueNode config = {0};
11,745✔
3126
  config.nd.node.type = QUERY_NODE_VALUE;
11,745✔
3127
  if (pJob->configLen > 0) {
11,745✔
3128
    config.nd.node.resType.type = TSDB_DATA_TYPE_BINARY;
11,745✔
3129
    config.nd.datum.p = taosStrndupi(pJob->config, strlen(pJob->config) + 1);
11,745✔
3130
    config.shouldFree = true;
11,745✔
3131
    code = taosHashPut(pMap, "config", strlen("config") + 1, &config, sizeof(SXndRefValueNode));
11,745✔
3132
  } else {
3133
    config.nd.node.resType.type = TSDB_DATA_TYPE_BINARY;
×
3134
    config.nd.datum.p = NULL;
×
3135
    config.nd.isNull = true;
×
3136
    code = taosHashPut(pMap, "config", strlen("config") + 1, &config, sizeof(SXndRefValueNode));
×
3137
  }
3138
  if (code != 0) {
11,745✔
3139
    taosHashCleanup(pMap);
×
3140
    return NULL;
×
3141
  }
3142
  // status
3143
  SXndRefValueNode status = {0};
11,745✔
3144
  status.nd.node.type = QUERY_NODE_VALUE;
11,745✔
3145
  if (pJob->statusLen > 0) {
11,745✔
3146
    status.nd.node.resType.type = TSDB_DATA_TYPE_BINARY;
8,586✔
3147
    status.nd.datum.p = taosStrndupi(pJob->status, strlen(pJob->status) + 1);
8,586✔
3148
    status.shouldFree = true;
8,586✔
3149
    code = taosHashPut(pMap, "status", strlen("status") + 1, &status, sizeof(SXndRefValueNode));
8,586✔
3150
  } else {
3151
    status.nd.node.resType.type = TSDB_DATA_TYPE_BINARY;
3,159✔
3152
    status.nd.datum.p = NULL;
3,159✔
3153
    status.nd.isNull = true;
3,159✔
3154
    code = taosHashPut(pMap, "status", strlen("status") + 1, &status, sizeof(SXndRefValueNode));
3,159✔
3155
  }
3156
  if (code != 0) {
11,745✔
3157
    taosHashCleanup(pMap);
×
3158
    return NULL;
×
3159
  }
3160
  // reason
3161
  SXndRefValueNode reason = {0};
11,745✔
3162
  reason.nd.node.type = QUERY_NODE_VALUE;
11,745✔
3163
  if (pJob->reasonLen > 0) {
11,745✔
3164
    reason.nd.node.resType.type = TSDB_DATA_TYPE_BINARY;
×
3165
    reason.nd.datum.p = taosStrndupi(pJob->reason, strlen(pJob->reason) + 1);
×
3166
    reason.shouldFree = true;
×
3167
    code = taosHashPut(pMap, "reason", strlen("reason") + 1, &reason, sizeof(SXndRefValueNode));
×
3168
  } else {
3169
    reason.nd.node.resType.type = TSDB_DATA_TYPE_BINARY;
11,745✔
3170
    reason.nd.datum.p = NULL;
11,745✔
3171
    reason.nd.isNull = true;
11,745✔
3172
    code = taosHashPut(pMap, "reason", strlen("reason") + 1, &reason, sizeof(SXndRefValueNode));
11,745✔
3173
  }
3174
  if (code != 0) {
11,745✔
3175
    taosHashCleanup(pMap);
×
3176
    return NULL;
×
3177
  }
3178
  // create time
3179
  SXndRefValueNode createTime = {0};
11,745✔
3180
  createTime.nd.node.type = QUERY_NODE_VALUE;
11,745✔
3181
  createTime.nd.node.resType.type = TSDB_DATA_TYPE_BINARY;
11,745✔
3182
  createTime.nd.datum.p = taosMemoryCalloc(1, TD_TIME_STR_LEN);
11,745✔
3183
  createTime.nd.datum.p = formatTimestampLocal(createTime.nd.datum.p, pJob->createTime, TSDB_TIME_PRECISION_MILLI);
11,745✔
3184
  createTime.shouldFree = true;
11,745✔
3185
  code = taosHashPut(pMap, "create_time", strlen("create_time") + 1, &createTime, sizeof(SXndRefValueNode));
11,745✔
3186
  if (code != 0) {
11,745✔
3187
    taosHashCleanup(pMap);
×
3188
    return NULL;
×
3189
  }
3190
  // update time
3191
  SXndRefValueNode updateTime = {0};
11,745✔
3192
  updateTime.nd.node.type = QUERY_NODE_VALUE;
11,745✔
3193
  updateTime.nd.node.resType.type = TSDB_DATA_TYPE_BINARY;
11,745✔
3194
  updateTime.nd.datum.p = taosMemoryCalloc(1, TD_TIME_STR_LEN);
11,745✔
3195
  updateTime.nd.datum.p = formatTimestampLocal(updateTime.nd.datum.p, pJob->updateTime, TSDB_TIME_PRECISION_MILLI);
11,745✔
3196
  updateTime.shouldFree = true;
11,745✔
3197
  code = taosHashPut(pMap, "update_time", strlen("update_time") + 1, &updateTime, sizeof(SXndRefValueNode));
11,745✔
3198
  return pMap;
11,745✔
3199
}
3200

3201
typedef bool (*FOpCmp)(SValueNode *pval1, SValueNode *pval2);
3202

3203
#define XNODE_DEF_OP_FUNC(NAME, OP)                             \
3204
  static bool NAME(SValueNode *pval1, SValueNode *pval2) {      \
3205
    switch (pval1->node.resType.type) {                         \
3206
      case TSDB_DATA_TYPE_BOOL:                                 \
3207
        return pval1->datum.b OP pval2->datum.b;                \
3208
      case TSDB_DATA_TYPE_UBIGINT:                              \
3209
        return pval1->datum.u OP pval2->datum.u;                \
3210
      case TSDB_DATA_TYPE_BIGINT:                               \
3211
        return pval1->datum.i OP pval2->datum.i;                \
3212
      case TSDB_DATA_TYPE_FLOAT:                                \
3213
        return pval1->datum.d OP pval2->datum.d;                \
3214
      case TSDB_DATA_TYPE_BINARY: {                             \
3215
        if (pval1->datum.p == NULL || pval2->datum.p == NULL) { \
3216
          return pval1->datum.p OP pval2->datum.p;              \
3217
        }                                                       \
3218
        return strcmp(pval1->datum.p, pval2->datum.p) OP 0;     \
3219
      }                                                         \
3220
      default:                                                  \
3221
        return false;                                           \
3222
    }                                                           \
3223
  }
3224

3225
XNODE_DEF_OP_FUNC(op_greater_than, >)
648✔
3226
XNODE_DEF_OP_FUNC(op_greater_equal, >=)
2,106✔
3227
XNODE_DEF_OP_FUNC(op_lower_than, <)
486✔
3228
XNODE_DEF_OP_FUNC(op_lower_equal, <=)
×
3229
XNODE_DEF_OP_FUNC(op_equal, ==)
7,209✔
3230
XNODE_DEF_OP_FUNC(op_not_equal, !=)
×
3231

3232
static int32_t call_op_cmp(SXndWhereContext *pctx, FOpCmp opFn) {
10,449✔
3233
  int32_t     code = 0;
10,449✔
3234
  SValueNode *pval2 = (SValueNode *)taosArrayPop(pctx->stack);
10,449✔
3235
  SValueNode *pval1 = (SValueNode *)taosArrayPop(pctx->stack);
10,449✔
3236
  bool        ret = false;
10,449✔
3237

3238
  if (pval1->node.type != pval2->node.type) {
10,449✔
3239
    code = TSDB_CODE_MND_XNODE_WHERE_COL_TYPE_DIFF;
×
3240
    mError("xnode type not same, v1 type: %d, v2 type: %d", pval1->node.type, pval2->node.type);
×
3241
    goto _OVER;
×
3242
  } else {
3243
    mDebug("xnode type v1:%d, is null: %d, UB: %" PRIu64 ", v2 type: %d, is null: %d, UB: %" PRIu64, pval1->node.type,
10,449✔
3244
           pval1->isNull, pval1->datum.u, pval2->node.type, pval2->isNull, pval2->datum.u);
3245

3246
    ret = (*opFn)(pval1, pval2);
10,449✔
3247
  }
3248
  SXndRefValueNode pval = {0};
10,449✔
3249
  pval.nd.node.type = QUERY_NODE_VALUE;
10,449✔
3250
  pval.nd.node.resType.type = TSDB_DATA_TYPE_BOOL;
10,449✔
3251
  pval.nd.datum.b = ret;
10,449✔
3252
  if (NULL == taosArrayPush(pctx->stack, &pval)) {
20,898✔
3253
    mError("xnode evaluate walker array push error: %s", tstrerror(terrno));
×
3254
    code = terrno;
×
3255
    goto _OVER;
×
3256
  }
3257

3258
_OVER:
10,449✔
3259
  if (pval1 != NULL) freeSXndRefValueNode((SXndRefValueNode *)pval1);
10,449✔
3260
  if (pval2 != NULL) freeSXndRefValueNode((SXndRefValueNode *)pval2);
10,449✔
3261
  TAOS_RETURN(code);
10,449✔
3262
}
3263

3264
#define XND_WALKER_CHECK_GOTO(CMD, LABEL)    \
3265
  do {                                       \
3266
    pctx->code = (CMD);                      \
3267
    if ((pctx->code != TSDB_CODE_SUCCESS)) { \
3268
      goto LABEL;                            \
3269
    }                                        \
3270
  } while (0);
3271

3272
static EDealRes evaluateWaker(SNode *pNode, void *pWhereCtx) {
33,291✔
3273
  int32_t           code = 0;
33,291✔
3274
  SXndWhereContext *pctx = (SXndWhereContext *)pWhereCtx;
33,291✔
3275

3276
  if (nodeType(pNode) == QUERY_NODE_COLUMN) {
33,291✔
3277
    SColumnNode *colNode = (SColumnNode *)pNode;
12,069✔
3278
    SXndRefValueNode *pval =
3279
        (SXndRefValueNode *)taosHashGet(pctx->pMap, colNode->colName, strlen(colNode->colName) + 1);
12,069✔
3280
    if (pval == NULL) {
12,069✔
3281
      mError("xnode evaluateWhereCond hash get error: %s", tstrerror(terrno));
1,620✔
3282
      pctx->code = TSDB_CODE_MND_XNODE_WHERE_COL_NOT_EXIST;
1,620✔
3283
      return DEAL_RES_END;
1,620✔
3284
    }
3285
    if (NULL == taosArrayPush(pctx->stack, pval)) {
20,898✔
3286
      mError("xnode evaluate walker array push error: %s", tstrerror(terrno));
×
3287
      pctx->code = TSDB_CODE_FAILED;
×
3288
      return DEAL_RES_END;
×
3289
    }
3290
    return DEAL_RES_CONTINUE;
10,449✔
3291
  }
3292
  if (nodeType(pNode) == QUERY_NODE_VALUE) {
21,222✔
3293
    SValueNode *pval = (SValueNode *)pNode;
10,449✔
3294
    if (pval->node.resType.type == TSDB_DATA_TYPE_UBIGINT) {
10,449✔
3295
      pval->datum.u = taosStr2Int64(pval->literal, NULL, 10);
6,480✔
3296
    }
3297
    if (pval->node.resType.type == TSDB_DATA_TYPE_BINARY) {
10,449✔
3298
      if (pval->datum.p == NULL) {
3,969✔
3299
        pval->datum.p = taosStrndupi(pval->literal, strlen(pval->literal) + 1);
486✔
3300
      }
3301
    }
3302
    if (pval->node.resType.type == TSDB_DATA_TYPE_NULL) {
10,449✔
3303
      pval->isNull = true;
×
3304
      pval->datum.p = NULL;
×
3305
    }
3306
    if (pval->node.resType.type == TSDB_DATA_TYPE_BOOL) {
10,449✔
3307
      pval->datum.b = pval->literal[0] == 't' || pval->literal[0] == 'T';
×
3308
    }
3309
    SXndRefValueNode refVal = {0};
10,449✔
3310
    refVal.nd = *pval;
10,449✔
3311
    refVal.shouldFree = false;
10,449✔
3312
    if (NULL == taosArrayPush(pctx->stack, &refVal)) {
20,898✔
3313
      mError("xnode evaluate walker array push error: %s", tstrerror(terrno));
×
3314
      pctx->code = TSDB_CODE_FAILED;
×
3315
      return DEAL_RES_END;
×
3316
    }
3317
    return DEAL_RES_CONTINUE;
10,449✔
3318
  }
3319

3320
  if (nodeType(pNode) == QUERY_NODE_OPERATOR) {
10,773✔
3321
    SOperatorNode *opNode = (SOperatorNode *)pNode;
10,449✔
3322
    switch (opNode->opType) {
10,449✔
3323
      case OP_TYPE_GREATER_THAN: {
648✔
3324
        XND_WALKER_CHECK_GOTO(call_op_cmp(pctx, op_greater_than), _exit);
648✔
3325
        break;
648✔
3326
      }
3327
      case OP_TYPE_GREATER_EQUAL: {
2,106✔
3328
        XND_WALKER_CHECK_GOTO(call_op_cmp(pctx, op_greater_equal), _exit);
2,106✔
3329
        break;
2,106✔
3330
      }
3331
      case OP_TYPE_LOWER_THAN: {
486✔
3332
        XND_WALKER_CHECK_GOTO(call_op_cmp(pctx, op_lower_than), _exit);
486✔
3333
        break;
486✔
3334
      }
3335
      case OP_TYPE_LOWER_EQUAL: {
×
3336
        XND_WALKER_CHECK_GOTO(call_op_cmp(pctx, op_lower_equal), _exit);
×
3337
        break;
×
3338
      }
3339
      case OP_TYPE_EQUAL: {
7,209✔
3340
        XND_WALKER_CHECK_GOTO(call_op_cmp(pctx, op_equal), _exit);
7,209✔
3341
        break;
7,209✔
3342
      }
3343
      case OP_TYPE_NOT_EQUAL: {
×
3344
        XND_WALKER_CHECK_GOTO(call_op_cmp(pctx, op_not_equal), _exit);
×
3345
        break;
×
3346
      }
3347
      default:
×
3348
        pctx->code = TSDB_CODE_MND_XNODE_WHERE_OP_NOT_SUPPORT;
×
3349
        return DEAL_RES_CONTINUE;
×
3350
    }
3351
    return DEAL_RES_CONTINUE;
10,449✔
3352
  }
3353

3354
  if (nodeType(pNode) == QUERY_NODE_LOGIC_CONDITION) {
324✔
3355
    SLogicConditionNode *logicNode = (SLogicConditionNode *)pNode;
324✔
3356
    SXndRefValueNode     pval = {0};
324✔
3357
    pval.nd.node.type = QUERY_NODE_VALUE;
324✔
3358
    pval.nd.node.resType.type = TSDB_DATA_TYPE_BOOL;
324✔
3359

3360
    switch (logicNode->condType) {
324✔
3361
      case LOGIC_COND_TYPE_AND: {
324✔
3362
        SValueNode *pval2 = (SValueNode *)taosArrayPop(pctx->stack);
324✔
3363
        SValueNode *pval1 = (SValueNode *)taosArrayPop(pctx->stack);
324✔
3364

3365
        pval.nd.datum.b = pval1->datum.b && pval2->datum.b;
324✔
3366
        if (NULL == taosArrayPush(pctx->stack, &pval)) {
648✔
3367
          mError("xnode walker AND array push err: %s", tstrerror(terrno));
×
3368
          pctx->code = TSDB_CODE_FAILED;
×
3369
          return DEAL_RES_END;
×
3370
        }
3371

3372
        freeSXndRefValueNode((SXndRefValueNode *)pval1);
324✔
3373
        freeSXndRefValueNode((SXndRefValueNode *)pval2);
324✔
3374
        break;
324✔
3375
      }
3376
      case LOGIC_COND_TYPE_OR: {
×
3377
        SValueNode *pval2 = (SValueNode *)taosArrayPop(pctx->stack);
×
3378
        SValueNode *pval1 = (SValueNode *)taosArrayPop(pctx->stack);
×
3379

3380
        pval.nd.datum.b = pval1->datum.b || pval2->datum.b;
×
3381
        if (NULL == taosArrayPush(pctx->stack, &pval)) {
×
3382
          mError("xnode walker OR array push err: %s", tstrerror(terrno));
×
3383
          pctx->code = TSDB_CODE_FAILED;
×
3384
          return DEAL_RES_END;
×
3385
        }
3386

3387
        freeSXndRefValueNode((SXndRefValueNode *)pval1);
×
3388
        freeSXndRefValueNode((SXndRefValueNode *)pval2);
×
3389
        break;
×
3390
      }
3391
      case LOGIC_COND_TYPE_NOT: {
×
3392
        SValueNode *pval1 = (SValueNode *)taosArrayPop(pctx->stack);
×
3393

3394
        pval.nd.datum.b = !pval1->datum.b;
×
3395
        if (NULL == taosArrayPush(pctx->stack, &pval)) {
×
3396
          mError("xnode walker NOT array push err: %s", tstrerror(terrno));
×
3397
          pctx->code = TSDB_CODE_FAILED;
×
3398
          return DEAL_RES_END;
×
3399
        }
3400

3401
        freeSXndRefValueNode((SXndRefValueNode *)pval1);
×
3402
        break;
×
3403
      }
3404
      default:
×
3405
        break;
×
3406
    }
3407
    return DEAL_RES_CONTINUE;
324✔
3408
  }
3409

3410
  pctx->code = TSDB_CODE_MND_XNODE_INVALID_MSG;
×
3411

3412
_exit:
×
3413
  return DEAL_RES_END;
×
3414
}
3415

3416
static bool evaluateWhereCond(SNode *pWhere, SHashObj *pDataMap, int32_t *code) {
11,745✔
3417
  bool             ret = false;
11,745✔
3418
  SXndWhereContext ctx = {0};
11,745✔
3419

3420
  ctx.stack = taosArrayInit(64, sizeof(SXndRefValueNode));
11,745✔
3421
  if (ctx.stack == NULL) {
11,745✔
3422
    mError("xnode evaluateWhereCond error: %s", tstrerror(terrno));
×
3423
    *code = terrno;
×
3424
    goto _exit;
×
3425
  }
3426
  ctx.pMap = pDataMap;
11,745✔
3427

3428
  // walkexpr pnode
3429
  nodesWalkExprPostOrder(pWhere, evaluateWaker, &ctx);
11,745✔
3430
  if (ctx.code != TSDB_CODE_SUCCESS) {
11,745✔
3431
    *code = ctx.code;
1,620✔
3432
    mError("xnode walkExpr error: %s", tstrerror(ctx.code));
1,620✔
3433
    goto _exit;
1,620✔
3434
  }
3435
  SValueNode *pval = taosArrayGetLast(ctx.stack);
10,125✔
3436
  if (pval == NULL) {
10,125✔
3437
    *code = terrno;
×
3438
    mError("xnode evaluateWhereCond error: %s", tstrerror(terrno));
×
3439
    goto _exit;
×
3440
  }
3441
  mDebug("xnode ctx stack size:%lu, last nd type:%d, bool:%d", ctx.stack->size, pval->node.type, pval->datum.b);
10,125✔
3442
  ret = pval->datum.b;
10,125✔
3443

3444
_exit:
11,745✔
3445
  freeSXndWhereContext(&ctx);
11,745✔
3446
  return ret;
11,745✔
3447
}
3448

3449
static int32_t filterJobsByWhereCond(SNode *pWhere, SArray *pArray, SArray **ppResult) {
15,147✔
3450
  int32_t code = 0;
15,147✔
3451

3452
  *ppResult = taosArrayInit(64, sizeof(SXnodeJobObj));
15,147✔
3453
  if (*ppResult == NULL) {
15,147✔
3454
    code = terrno;
×
3455
    goto _exit;
×
3456
  }
3457
  for (int32_t i = 0; i < pArray->size; i++) {
25,272✔
3458
    SXnodeJobObj *pJob = taosArrayGet(pArray, i);
11,745✔
3459

3460
    SHashObj *pDataMap = NULL;
11,745✔
3461
    if ((pDataMap = convertJob2Map(pJob)) == NULL) {
11,745✔
3462
      mError("xnode evaluate convertJow2Map error: %s", tstrerror(terrno));
×
3463
      goto _exit;
×
3464
    }
3465
    if (evaluateWhereCond(pWhere, pDataMap, &code)) {
11,745✔
3466
      if (NULL == taosArrayPush(*ppResult, pJob)) {
17,820✔
3467
        mError("xnode filterJobsByWhereCond array push err: %s", tstrerror(terrno));
×
3468
        code = TSDB_CODE_FAILED;
×
3469
        goto _exit;
×
3470
      }
3471
    }
3472
    if (code != TSDB_CODE_SUCCESS) {
11,745✔
3473
      goto _exit;
1,620✔
3474
    }
3475
  }
3476

3477
_exit:
15,147✔
3478
  TAOS_RETURN(code);
15,147✔
3479
}
3480

3481
#define XND_LOG_END(code, lino)                                                                 \
3482
  do {                                                                                          \
3483
    if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_ACTION_IN_PROGRESS) {                    \
3484
      mError("xnode:%s failed at line %d code: %d, since %s", __func__, lino, code, tstrerror(code)); \
3485
    }                                                                                           \
3486
  } while (0)
3487

3488
void httpRebalanceAuto(SArray *pResult) {
405✔
3489
  int32_t code = 0;
405✔
3490
  int32_t lino = 0;
405✔
3491
  SJson *pJsonArr = NULL;
405✔
3492
  char  *pContStr = NULL;
405✔
3493
  // convert pResult to [(tid, jid)*]
3494
  pJsonArr = tjsonCreateArray();
405✔
3495
  if (pJsonArr == NULL) {
405✔
3496
    code = terrno;
×
3497
    mError("xnode json array error: %s", tstrerror(code));
×
3498
    goto _OVER;
×
3499
  }
3500
  for (int32_t i = 0; i < pResult->size; i++) {
6,885✔
3501
    SXnodeJobObj *pJob = taosArrayGet(pResult, i);
6,480✔
3502
    SJson        *pJsonObj = tjsonCreateObject();
6,480✔
3503
    if (pJsonObj == NULL) {
6,480✔
3504
      code = terrno;
×
3505
      mError("xnode json object error: %s", tstrerror(code));
×
3506
      goto _OVER;
×
3507
    }
3508
    TAOS_CHECK_GOTO(tjsonAddDoubleToObject(pJsonObj, "tid", pJob->taskId), &lino, _OVER);
6,480✔
3509
    TAOS_CHECK_GOTO(tjsonAddDoubleToObject(pJsonObj, "jid", pJob->id), &lino, _OVER);
6,480✔
3510
    TAOS_CHECK_GOTO(tjsonAddItemToArray(pJsonArr, pJsonObj), &lino, _OVER);
6,480✔
3511
  }
3512

3513
  pContStr = tjsonToUnformattedString(pJsonArr);
405✔
3514
  if (pContStr == NULL) {
405✔
3515
    mError("xnode to json string error: %s", tstrerror(terrno));
×
3516
    goto _OVER;
×
3517
  }
3518
  char xnodeUrl[TSDB_XNODE_URL_LEN + 1] = {0};
405✔
3519
  snprintf(xnodeUrl, TSDB_XNODE_URL_LEN + 1, "%s/rebalance/auto", XNODED_PIPE_SOCKET_URL);
405✔
3520
  SJson* pJson = mndSendReqRetJson(xnodeUrl, HTTP_TYPE_POST, defaultTimeout, pContStr, strlen(pContStr));
405✔
3521
  if (pJson) {
405✔
NEW
3522
    tjsonDelete(pJson);
×
3523
  }
3524

3525
_OVER:
405✔
3526
  if (pJsonArr != NULL) tjsonDelete(pJsonArr);
405✔
3527
  if (pContStr != NULL) taosMemoryFree(pContStr);
405✔
3528
  XND_LOG_END(code, lino);
405✔
3529
  return;
405✔
3530
}
3531

3532
static int32_t mndProcessRebalanceXnodeJobsWhereReq(SRpcMsg *pReq) {
1,215✔
3533
  mDebug("xnode reblance xnode jobs where req, content len:%d", pReq->contLen);
1,215✔
3534
  int32_t                      code = 0;
1,215✔
3535
  SMnode                      *pMnode = pReq->info.node;
1,215✔
3536
  SMRebalanceXnodeJobsWhereReq rebalanceReq = {0};
1,215✔
3537
  SNode                       *pWhere = NULL;
1,215✔
3538
  SArray                      *pArray = NULL;
1,215✔
3539
  SArray                      *pResult = NULL;
1,215✔
3540

3541
  TAOS_CHECK_GOTO(tDeserializeSMRebalanceXnodeJobsWhereReq(pReq->pCont, pReq->contLen, &rebalanceReq), NULL, _OVER);
1,215✔
3542
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_REBALANCE_XNODE_JOB), NULL, _OVER);
1,215✔
3543

3544
  TAOS_CHECK_GOTO(mndAcquireXnodeJobsAll(pMnode, &pArray), NULL, _OVER);
1,215✔
3545
  if (NULL != rebalanceReq.ast.ptr) {
1,215✔
3546
    TAOS_CHECK_GOTO(nodesStringToNode(rebalanceReq.ast.ptr, &pWhere), NULL, _OVER);
1,215✔
3547

3548
    TAOS_CHECK_GOTO(filterJobsByWhereCond(pWhere, pArray, &pResult), NULL, _OVER);
1,215✔
3549
    httpRebalanceAuto(pResult);
405✔
3550
  } else {
3551
    httpRebalanceAuto(pArray);
×
3552
  }
3553

3554
_OVER:
1,215✔
3555
  if (pWhere != NULL) {
1,215✔
3556
    nodesDestroyNode(pWhere);
1,215✔
3557
  }
3558
  if (pArray != NULL) {
1,215✔
3559
    taosArrayDestroy(pArray);
1,215✔
3560
  }
3561
  if (pResult != NULL) {
1,215✔
3562
    taosArrayDestroy(pResult);
1,215✔
3563
  }
3564
  tFreeSMRebalanceXnodeJobsWhereReq(&rebalanceReq);
1,215✔
3565
  TAOS_RETURN(code);
1,215✔
3566
}
3567

3568
static int32_t dropXnodeJobById(SMnode *pMnode, SRpcMsg *pReq, int32_t jid) {
1,053✔
3569
  int32_t       code = 0;
1,053✔
3570
  int32_t       lino = 0;
1,053✔
3571
  SXnodeJobObj *pObj = NULL;
1,053✔
3572

3573
  pObj = mndAcquireXnodeJob(pMnode, jid);
1,053✔
3574
  if (pObj == NULL) {
1,053✔
3575
    code = terrno;
810✔
3576
    lino = __LINE__;
810✔
3577
    goto _OVER;
810✔
3578
  }
3579
  code = mndDropXnodeJob(pMnode, pReq, pObj);
243✔
3580

3581
_OVER:
1,053✔
3582
  XND_LOG_END(code, lino);
1,053✔
3583
  mndReleaseXnodeJob(pMnode, pObj);
1,053✔
3584
  return code;
1,053✔
3585
}
3586

3587
static int32_t dropXnodeJobByWhereCond(SMnode *pMnode, SRpcMsg *pReq, SMDropXnodeJobReq *dropReq) {
13,932✔
3588
  int32_t       code = 0;
13,932✔
3589
  int32_t       lino = 0;
13,932✔
3590
  SXnodeJobObj *pObj = NULL;
13,932✔
3591
  SNode        *pWhere = NULL;
13,932✔
3592
  SArray       *pArray = NULL;
13,932✔
3593
  SArray       *pResult = NULL;
13,932✔
3594

3595
  if (NULL != dropReq->ast.ptr) {
13,932✔
3596
    TAOS_CHECK_GOTO(mndAcquireXnodeJobsAll(pMnode, &pArray), &lino, _OVER);
13,932✔
3597
    TAOS_CHECK_GOTO(nodesStringToNode(dropReq->ast.ptr, &pWhere), &lino, _OVER);
13,932✔
3598
    TAOS_CHECK_GOTO(filterJobsByWhereCond(pWhere, pArray, &pResult), &lino, _OVER);
13,932✔
3599

3600
    for (int32_t i = 0; i < pResult->size; i++) {
15,552✔
3601
      pObj = taosArrayGet(pResult, i);
2,430✔
3602
      TAOS_CHECK_GOTO(mndDropXnodeJob(pMnode, NULL, pObj), &lino, _OVER);
2,430✔
3603
    }
3604
  }
3605

3606
_OVER:
13,932✔
3607
  XND_LOG_END(code, lino);
13,932✔
3608
  if (pResult != NULL) {
13,932✔
3609
    taosArrayDestroy(pResult);
13,932✔
3610
  }
3611
  if (pWhere != NULL) {
13,932✔
3612
    nodesDestroyNode(pWhere);
13,932✔
3613
  }
3614
  if (pArray != NULL) {
13,932✔
3615
    taosArrayDestroy(pArray);
13,932✔
3616
  }
3617
  return code;
13,932✔
3618
}
3619

3620
static int32_t mndProcessDropXnodeJobReq(SRpcMsg *pReq) {
14,985✔
3621
  mDebug("drop xnode job req, content len:%d", pReq->contLen);
14,985✔
3622
  SMnode           *pMnode = pReq->info.node;
14,985✔
3623
  int32_t           code = -1;
14,985✔
3624
  SMDropXnodeJobReq dropReq = {0};
14,985✔
3625

3626
  TAOS_CHECK_GOTO(tDeserializeSMDropXnodeJobReq(pReq->pCont, pReq->contLen, &dropReq), NULL, _OVER);
14,985✔
3627

3628
  mDebug("Xnode drop job with jid:%d", dropReq.jid);
14,985✔
3629
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_DROP_XNODE_JOB), NULL, _OVER);
14,985✔
3630

3631
  if (dropReq.jid <= 0 && dropReq.ast.ptr == NULL) {
14,985✔
3632
    code = TSDB_CODE_MND_XNODE_INVALID_MSG;
×
3633
    goto _OVER;
×
3634
  }
3635
  if (dropReq.jid > 0) {
14,985✔
3636
    code = dropXnodeJobById(pMnode, pReq, dropReq.jid);
1,053✔
3637
    if (code == 0) {
1,053✔
3638
      code = TSDB_CODE_ACTION_IN_PROGRESS;
243✔
3639
    } else {
3640
      goto _OVER;
810✔
3641
    }
3642
  } else {
3643
    TAOS_CHECK_GOTO(dropXnodeJobByWhereCond(pMnode, pReq, &dropReq), NULL, _OVER);
13,932✔
3644
  }
3645

3646
_OVER:
14,985✔
3647
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
14,985✔
3648
    mError("xnode:%d, failed to drop since %s", dropReq.jid, tstrerror(code));
1,620✔
3649
  }
3650
  tFreeSMDropXnodeJobReq(&dropReq);
14,985✔
3651
  TAOS_RETURN(code);
14,985✔
3652
}
3653

3654
/**
3655
 * @brief Mapping the columns of show xnode jobs
3656
 *
3657
 * See [xnodeTaskJobSchema] in systable.h.
3658
 *
3659
 *  {.name = "jid", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
3660
    {.name = "tid", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
3661
    {.name = "config", .bytes = TSDB_XNODE_NAME_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo =
3662
 false},
3663
    {.name = "status", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
3664
    // {.name = "reason", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
3665
    {.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
3666
    {.name = "update_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
3667
 * @param pReq
3668
 * @param pShow
3669
 * @param pBlock
3670
 * @param rows
3671
 * @return int32_t
3672
 */
3673
static int32_t mndRetrieveXnodeJobs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
3,040✔
3674
  SMnode       *pMnode = pReq->info.node;
3,040✔
3675
  SSdb         *pSdb = pMnode->pSdb;
3,040✔
3676
  int32_t       numOfRows = 0;
3,040✔
3677
  int32_t       cols = 0;
3,040✔
3678
  SXnodeJobObj *pObj = NULL;
3,040✔
3679
  char          buf[VARSTR_HEADER_SIZE + TMAX(TSDB_XNODE_TASK_JOB_CONFIG_LEN, TSDB_XNODE_TASK_REASON_LEN)];
3,040✔
3680
  char          status[64] = {0};
3,040✔
3681
  int32_t       code = 0;
3,040✔
3682
  mDebug("show.type:%d, %s:%d: retrieve xnode jobs with rows: %d", pShow->type, __FILE__, __LINE__, rows);
3,040✔
3683

3684
  while (numOfRows < rows) {
7,657✔
3685
    pShow->pIter = sdbFetch(pSdb, SDB_XNODE_JOB, pShow->pIter, (void **)&pObj);
7,657✔
3686
    if (pShow->pIter == NULL) break;
7,657✔
3687

3688
    cols = 0;
4,617✔
3689
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,617✔
3690
    // id
3691
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->id, false);
4,617✔
3692
    if (code != 0) goto _end;
4,617✔
3693
    // tid
3694
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,617✔
3695
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->taskId, false);
4,617✔
3696
    if (code != 0) goto _end;
4,617✔
3697

3698
    // config
3699
    buf[0] = 0;
4,617✔
3700
    STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->config, pShow->pMeta->pSchemas[cols].bytes);
4,617✔
3701
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,617✔
3702
    code = colDataSetVal(pColInfo, numOfRows, buf, false);
4,617✔
3703
    if (code != 0) goto _end;
4,617✔
3704

3705
    // via
3706
    if (pObj->via != 0) {
4,617✔
3707
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
3708
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->via, false);
×
3709
      if (code != 0) goto _end;
×
3710
    } else {
3711
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,617✔
3712
      colDataSetNULL(pColInfo, numOfRows);
4,617✔
3713
    }
3714

3715
    // xnode_id
3716
    if (pObj->xnodeId != 0) {
4,617✔
3717
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
3718
      code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->xnodeId, false);
×
3719
      if (code != 0) goto _end;
×
3720
    } else {
3721
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,617✔
3722
      colDataSetNULL(pColInfo, numOfRows);
4,617✔
3723
    }
3724

3725
    // status
3726
    if (pObj->statusLen > 0) {
4,617✔
3727
      buf[0] = 0;
2,187✔
3728
      STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->status, pShow->pMeta->pSchemas[cols].bytes);
2,187✔
3729
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,187✔
3730
      code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
2,187✔
3731
      if (code != 0) goto _end;
2,187✔
3732
    } else {
3733
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,430✔
3734
      colDataSetNULL(pColInfo, numOfRows);
2,430✔
3735
    }
3736

3737
    // reason
3738
    if (pObj->reasonLen > 0) {
4,617✔
3739
      buf[0] = 0;
×
3740
      STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->reason, pShow->pMeta->pSchemas[cols].bytes);
×
3741
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
3742
      code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
×
3743
      if (code != 0) goto _end;
×
3744
    } else {
3745
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,617✔
3746
      colDataSetNULL(pColInfo, numOfRows);
4,617✔
3747
    }
3748

3749
    // create_time
3750
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,617✔
3751
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->createTime, false);
4,617✔
3752
    if (code != 0) goto _end;
4,617✔
3753

3754
    // update_time
3755
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
4,617✔
3756
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->updateTime, false);
4,617✔
3757
    if (code != 0) goto _end;
4,617✔
3758

3759
    numOfRows++;
4,617✔
3760
    sdbRelease(pSdb, pObj);
4,617✔
3761
  }
3762

3763
_end:
3,040✔
3764
  if (code != 0) sdbRelease(pSdb, pObj);
3,040✔
3765

3766
  pShow->numOfRows += numOfRows;
3,040✔
3767
  return numOfRows;
3,040✔
3768
}
3769
static void mndCancelGetNextXnodeJob(SMnode *pMnode, void *pIter) {
×
3770
  SSdb *pSdb = pMnode->pSdb;
×
3771
  sdbCancelFetchByType(pSdb, pIter, SDB_XNODE_JOB);
×
3772
}
×
3773

3774
static size_t taosCurlWriteData(char *pCont, size_t contLen, size_t nmemb, void *userdata) {
×
3775
  SCurlResp *pRsp = userdata;
×
3776
  if (contLen == 0 || nmemb == 0 || pCont == NULL) {
×
3777
    pRsp->dataLen = 0;
×
3778
    pRsp->data = NULL;
×
3779
    uError("curl response is received, len:%" PRId64, pRsp->dataLen);
×
3780
    return 0;
×
3781
  }
3782

3783
  int64_t newDataSize = (int64_t)contLen * nmemb;
×
3784
  int64_t size = pRsp->dataLen + newDataSize;
×
3785

3786
  if (pRsp->data == NULL) {
×
3787
    pRsp->data = taosMemoryMalloc(size + 1);
×
3788
    if (pRsp->data == NULL) {
×
3789
      uError("failed to prepare recv buffer for post rsp, len:%d, code:%s", (int32_t)size + 1, tstrerror(terrno));
×
3790
      return 0;  // return the recv length, if failed, return 0
×
3791
    }
3792
  } else {
3793
    char *p = taosMemoryRealloc(pRsp->data, size + 1);
×
3794
    if (p == NULL) {
×
3795
      uError("failed to prepare recv buffer for post rsp, len:%d, code:%s", (int32_t)size + 1, tstrerror(terrno));
×
3796
      return 0;  // return the recv length, if failed, return 0
×
3797
    }
3798

3799
    pRsp->data = p;
×
3800
  }
3801

3802
  if (pRsp->data != NULL) {
×
3803
    (void)memcpy(pRsp->data + pRsp->dataLen, pCont, newDataSize);
×
3804

3805
    pRsp->dataLen = size;
×
3806
    pRsp->data[size] = 0;
×
3807

3808
    uDebugL("curl response is received, len:%" PRId64 ", content:%s", size, pRsp->data);
×
3809
    return newDataSize;
×
3810
  } else {
3811
    pRsp->dataLen = 0;
×
3812
    uError("failed to malloc curl response");
×
3813
    return 0;
×
3814
  }
3815
}
3816

3817
#ifndef WINDOWS
UNCOV
3818
static int32_t taosCurlGetRequest(const char *url, SCurlResp *pRsp, int32_t timeout, const char *socketPath) {
×
UNCOV
3819
  CURL   *curl = NULL;
×
UNCOV
3820
  int32_t code = 0;
×
UNCOV
3821
  int32_t lino = 0;
×
3822

UNCOV
3823
  curl = curl_easy_init();
×
UNCOV
3824
  if (curl == NULL) {
×
3825
    uError("failed to create curl handle");
×
3826
    return -1;
×
3827
  }
3828

UNCOV
3829
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, socketPath), &lino, _OVER);
×
UNCOV
3830
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_URL, url), &lino, _OVER);
×
UNCOV
3831
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, taosCurlWriteData), &lino, _OVER);
×
UNCOV
3832
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_WRITEDATA, pRsp), &lino, _OVER);
×
UNCOV
3833
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, timeout), &lino, _OVER);
×
3834

UNCOV
3835
  uDebug("curl get request will sent, url:%s", url);
×
UNCOV
3836
  CURLcode curlCode = curl_easy_perform(curl);
×
UNCOV
3837
  if (curlCode != CURLE_OK) {
×
UNCOV
3838
    if (curlCode == CURLE_OPERATION_TIMEDOUT) {
×
3839
      mError("xnode failed to perform curl action, code:%d", curlCode);
×
3840
      code = TSDB_CODE_MND_XNODE_URL_RESP_TIMEOUT;
×
3841
      goto _OVER;
×
3842
    }
UNCOV
3843
    uError("failed to perform curl action, code:%d", curlCode);
×
UNCOV
3844
    code = TSDB_CODE_MND_XNODE_URL_CANT_ACCESS;
×
UNCOV
3845
    goto _OVER;
×
3846
  }
3847

3848
  long http_code = 0;
×
3849
  TAOS_CHECK_GOTO(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code), &lino, _OVER);
×
3850
  if (http_code != 200) {
×
3851
    code = TSDB_CODE_MND_XNODE_HTTP_CODE_ERROR;
×
3852
  }
3853

UNCOV
3854
_OVER:
×
UNCOV
3855
  if (curl != NULL) curl_easy_cleanup(curl);
×
UNCOV
3856
  XND_LOG_END(code, lino);
×
UNCOV
3857
  return code;
×
3858
}
3859

UNCOV
3860
static int32_t taosCurlPostRequest(const char *url, SCurlResp *pRsp, const char *buf, int32_t bufLen, int32_t timeout,
×
3861
                                   const char *socketPath) {
UNCOV
3862
  struct curl_slist *headers = NULL;
×
UNCOV
3863
  CURL              *curl = NULL;
×
UNCOV
3864
  int32_t            code = 0;
×
UNCOV
3865
  int32_t            lino = 0;
×
3866

UNCOV
3867
  curl = curl_easy_init();
×
UNCOV
3868
  if (curl == NULL) {
×
3869
    mError("xnode failed to create curl handle");
×
3870
    return -1;
×
3871
  }
3872

UNCOV
3873
  headers = curl_slist_append(headers, "Content-Type:application/json;charset=UTF-8");
×
UNCOV
3874
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, socketPath), &lino, _OVER);
×
UNCOV
3875
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers), &lino, _OVER);
×
UNCOV
3876
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_URL, url), &lino, _OVER);
×
UNCOV
3877
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, taosCurlWriteData), &lino, _OVER);
×
UNCOV
3878
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_WRITEDATA, pRsp), &lino, _OVER);
×
UNCOV
3879
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, timeout), &lino, _OVER);
×
UNCOV
3880
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_POST, 1), &lino, _OVER);
×
UNCOV
3881
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, bufLen), &lino, _OVER);
×
UNCOV
3882
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_POSTFIELDS, buf), &lino, _OVER);
×
UNCOV
3883
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L), &lino, _OVER);
×
UNCOV
3884
  TAOS_CHECK_GOTO(curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L), &lino, _OVER);
×
3885

UNCOV
3886
  mDebug("xnode curl post request will sent, url:%s len:%d content:%s", url, bufLen, buf);
×
UNCOV
3887
  CURLcode curlCode = curl_easy_perform(curl);
×
3888

UNCOV
3889
  if (curlCode != CURLE_OK) {
×
UNCOV
3890
    if (curlCode == CURLE_OPERATION_TIMEDOUT) {
×
3891
      mError("xnode failed to perform curl action, code:%d", curlCode);
×
3892
      code = TSDB_CODE_MND_XNODE_URL_RESP_TIMEOUT;
×
3893
      goto _OVER;
×
3894
    }
UNCOV
3895
    uError("xnode failed to perform curl action, code:%d", curlCode);
×
UNCOV
3896
    code = TSDB_CODE_MND_XNODE_URL_CANT_ACCESS;
×
UNCOV
3897
    goto _OVER;
×
3898
  }
3899

3900
  long http_code = 0;
×
3901
  TAOS_CHECK_GOTO(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code), &lino, _OVER);
×
3902
  if (http_code != 200) {
×
3903
    mError("xnode failed to perform curl action, http code:%ld", http_code);
×
3904
    code = TSDB_CODE_MND_XNODE_HTTP_CODE_ERROR;
×
3905
  }
3906

UNCOV
3907
_OVER:
×
UNCOV
3908
  if (curl != NULL) {
×
UNCOV
3909
    curl_slist_free_all(headers);
×
UNCOV
3910
    curl_easy_cleanup(curl);
×
3911
  }
UNCOV
3912
  XND_LOG_END(code, lino);
×
UNCOV
3913
  return code;
×
3914
}
3915

UNCOV
3916
static int32_t taosCurlDeleteRequest(const char *url, SCurlResp *pRsp, int32_t timeout, const char *socketPath) {
×
UNCOV
3917
  CURL   *curl = NULL;
×
UNCOV
3918
  int32_t code = 0;
×
UNCOV
3919
  int32_t lino = 0;
×
3920

UNCOV
3921
  curl = curl_easy_init();
×
UNCOV
3922
  if (curl == NULL) {
×
3923
    uError("xnode failed to create curl handle");
×
3924
    return -1;
×
3925
  }
3926

UNCOV
3927
  if (curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, socketPath)) goto _OVER;
×
UNCOV
3928
  if (curl_easy_setopt(curl, CURLOPT_URL, url) != 0) goto _OVER;
×
UNCOV
3929
  if (curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE") != 0) goto _OVER;
×
UNCOV
3930
  if (curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, taosCurlWriteData) != 0) goto _OVER;
×
UNCOV
3931
  if (curl_easy_setopt(curl, CURLOPT_WRITEDATA, pRsp) != 0) goto _OVER;
×
UNCOV
3932
  if (curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, timeout) != 0) goto _OVER;
×
3933

UNCOV
3934
  uDebug("xnode curl get request will sent, url:%s", url);
×
UNCOV
3935
  CURLcode curlCode = curl_easy_perform(curl);
×
UNCOV
3936
  if (curlCode != CURLE_OK) {
×
UNCOV
3937
    uError("xnode failed to perform curl action, curl code:%d", curlCode);
×
UNCOV
3938
    if (curlCode == CURLE_OPERATION_TIMEDOUT) {
×
3939
      code = TSDB_CODE_MND_XNODE_URL_RESP_TIMEOUT;
×
3940
      goto _OVER;
×
3941
    }
UNCOV
3942
    code = TSDB_CODE_MND_XNODE_URL_CANT_ACCESS;
×
UNCOV
3943
    goto _OVER;
×
3944
  }
3945

3946
  long http_code = 0;
×
3947
  TAOS_CHECK_GOTO(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code), &lino, _OVER);
×
3948
  if (http_code != 200 && http_code != 204) {
×
3949
    uError("xnode curl request response http code:%ld", http_code);
×
3950
    code = TSDB_CODE_MND_XNODE_HTTP_CODE_ERROR;
×
3951
  }
3952

UNCOV
3953
_OVER:
×
UNCOV
3954
  if (curl != NULL) curl_easy_cleanup(curl);
×
UNCOV
3955
  XND_LOG_END(code, lino);
×
UNCOV
3956
  return code;
×
3957
}
3958
#else
3959
static int32_t taosCurlGetRequest(const char *url, SCurlResp *pRsp, int32_t timeout, const char *socketPath) { return 0; }
3960
static int32_t taosCurlPostRequest(const char *url, SCurlResp *pRsp, const char *buf, int32_t bufLen, int32_t timeout,
3961
                                   const char *socketPath) {
3962
  return 0;
3963
}
3964
static int32_t taosCurlDeleteRequest(const char *url, SCurlResp *pRsp, int32_t timeout, const char *socketPath) { return 0; }
3965
#endif
3966
SJson *mndSendReqRetJson(const char *url, EHttpType type, int64_t timeout, const char *buf, int64_t bufLen) {
20,313✔
3967
  SJson    *pJson = NULL;
20,313✔
3968
  SCurlResp curlRsp = {0};
20,313✔
3969
  char      socketPath[PATH_MAX] = {0};
20,313✔
3970

3971
  getXnodedPipeName(socketPath, sizeof(socketPath));
20,313✔
3972
  if (!taosCheckExistFile(socketPath)) {
20,313✔
3973
    uError("xnode failed to send request, socket path:%s not exist", socketPath);
20,313✔
3974
    terrno = TSDB_CODE_MND_XNODE_URL_CANT_ACCESS;
20,313✔
3975
    goto _OVER;
20,313✔
3976
  }
UNCOV
3977
  if (type == HTTP_TYPE_GET) {
×
UNCOV
3978
    if ((terrno = taosCurlGetRequest(url, &curlRsp, timeout, socketPath)) != 0) {
×
UNCOV
3979
      goto _OVER;
×
3980
    }
UNCOV
3981
  } else if (type == HTTP_TYPE_POST) {
×
UNCOV
3982
    if ((terrno = taosCurlPostRequest(url, &curlRsp, buf, bufLen, timeout, socketPath)) != 0) {
×
UNCOV
3983
      goto _OVER;
×
3984
    }
UNCOV
3985
  } else if (type == HTTP_TYPE_DELETE) {
×
UNCOV
3986
    if ((terrno = taosCurlDeleteRequest(url, &curlRsp, timeout, socketPath)) != 0) {
×
UNCOV
3987
      goto _OVER;
×
3988
    }
3989
  } else {
3990
    uError("xnode invalid http type:%d", type);
×
3991
    terrno = TSDB_CODE_MND_XNODE_INVALID_MSG;
×
3992
    goto _OVER;
×
3993
  }
3994

3995
  if (curlRsp.data == NULL || curlRsp.dataLen == 0) {
×
3996
    pJson = tjsonCreateObject();
×
3997
    goto _OVER;
×
3998
  }
3999

4000
  pJson = tjsonParse(curlRsp.data);
×
4001
  if (pJson == NULL) {
×
4002
    terrno = TSDB_CODE_INVALID_JSON_FORMAT;
×
4003
    goto _OVER;
×
4004
  }
4005

4006
_OVER:
20,313✔
4007
  if (curlRsp.data != NULL) taosMemoryFreeClear(curlRsp.data);
20,313✔
4008
  if (terrno != TSDB_CODE_SUCCESS) {
20,313✔
4009
    mError("xnode failed to send request, url: %s, since:%s", url, tstrerror(terrno));
20,313✔
4010
  }
4011
  return pJson;
20,313✔
4012
}
4013

4014
static int32_t mndGetXnodeStatus(SXnodeObj *pObj, char *status, int32_t statusLen) {
2,457✔
4015
  int32_t code = 0;
2,457✔
4016
  SJson  *pJson = NULL;
2,457✔
4017

4018
  char xnodeUrl[TSDB_XNODE_URL_LEN + 1] = {0};
2,457✔
4019
  snprintf(xnodeUrl, TSDB_XNODE_URL_LEN + 1, "%s/xnode/%d", XNODED_PIPE_SOCKET_URL, pObj->id);
2,457✔
4020
  pJson = mndSendReqRetJson(xnodeUrl, HTTP_TYPE_GET, defaultTimeout, NULL, 0);
2,457✔
4021
  if (pJson == NULL) {
2,457✔
4022
    code = terrno;
2,457✔
4023
    goto _OVER;
2,457✔
4024
  }
4025

4026
  code = tjsonGetStringValue2(pJson, "status", status, statusLen);
×
4027
  if (code < 0) {
×
4028
    code = TSDB_CODE_INVALID_JSON_FORMAT;
×
4029
    goto _OVER;
×
4030
  }
4031
  if (strlen(status) == 0) {
×
4032
    code = TSDB_CODE_MND_XNODE_INVALID_MSG;
×
4033
    goto _OVER;
×
4034
  }
4035

4036
_OVER:
2,457✔
4037
  if (pJson != NULL) tjsonDelete(pJson);
2,457✔
4038
  TAOS_RETURN(code);
2,457✔
4039
}
4040

4041
/** xnode agent section **/
4042

4043
SSdbRaw *mndXnodeAgentActionEncode(SXnodeAgentObj *pObj) {
3,402✔
4044
  int32_t code = 0;
3,402✔
4045
  int32_t lino = 0;
3,402✔
4046
  terrno = TSDB_CODE_OUT_OF_MEMORY;
3,402✔
4047

4048
  if (NULL == pObj) {
3,402✔
4049
    terrno = TSDB_CODE_INVALID_PARA;
×
4050
    return NULL;
×
4051
  }
4052

4053
  int32_t rawDataLen =
3,402✔
4054
      sizeof(SXnodeAgentObj) + TSDB_XNODE_RESERVE_SIZE + pObj->nameLen + pObj->tokenLen + pObj->statusLen;
3,402✔
4055

4056
  SSdbRaw *pRaw = sdbAllocRaw(SDB_XNODE_AGENT, TSDB_XNODE_VER_NUMBER, rawDataLen);
3,402✔
4057
  if (pRaw == NULL) goto _OVER;
3,402✔
4058

4059
  int32_t dataPos = 0;
3,402✔
4060
  SDB_SET_INT32(pRaw, dataPos, pObj->id, _OVER)
3,402✔
4061
  SDB_SET_INT32(pRaw, dataPos, pObj->nameLen, _OVER)
3,402✔
4062
  SDB_SET_BINARY(pRaw, dataPos, pObj->name, pObj->nameLen, _OVER)
3,402✔
4063
  SDB_SET_INT32(pRaw, dataPos, pObj->tokenLen, _OVER)
3,402✔
4064
  SDB_SET_BINARY(pRaw, dataPos, pObj->token, pObj->tokenLen, _OVER)
3,402✔
4065
  SDB_SET_INT32(pRaw, dataPos, pObj->statusLen, _OVER)
3,402✔
4066
  SDB_SET_BINARY(pRaw, dataPos, pObj->status, pObj->statusLen, _OVER)
3,402✔
4067
  SDB_SET_INT64(pRaw, dataPos, pObj->createTime, _OVER)
3,402✔
4068
  SDB_SET_INT64(pRaw, dataPos, pObj->updateTime, _OVER)
3,402✔
4069

4070
  SDB_SET_RESERVE(pRaw, dataPos, TSDB_XNODE_RESERVE_SIZE, _OVER)
3,402✔
4071

4072
  terrno = 0;
3,402✔
4073

4074
_OVER:
3,402✔
4075
  if (terrno != 0) {
3,402✔
4076
    mError("xnode agent:%d, failed to encode to raw:%p since %s", pObj->id, pRaw, terrstr());
×
4077
    sdbFreeRaw(pRaw);
×
4078
    return NULL;
×
4079
  }
4080

4081
  mTrace("xnode agent:%d, encode to raw:%p, row:%p", pObj->id, pRaw, pObj);
3,402✔
4082
  return pRaw;
3,402✔
4083
}
4084

4085
SSdbRow *mndXnodeAgentActionDecode(SSdbRaw *pRaw) {
2,592✔
4086
  int32_t code = 0;
2,592✔
4087
  int32_t lino = 0;
2,592✔
4088
  terrno = TSDB_CODE_OUT_OF_MEMORY;
2,592✔
4089
  SSdbRow        *pRow = NULL;
2,592✔
4090
  SXnodeAgentObj *pObj = NULL;
2,592✔
4091

4092
  if (NULL == pRaw) {
2,592✔
4093
    terrno = TSDB_CODE_INVALID_PARA;
×
4094
    return NULL;
×
4095
  }
4096

4097
  int8_t sver = 0;
2,592✔
4098
  if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
2,592✔
4099

4100
  if (sver != TSDB_XNODE_VER_NUMBER) {
2,592✔
4101
    terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
×
4102
    goto _OVER;
×
4103
  }
4104

4105
  pRow = sdbAllocRow(sizeof(SXnodeAgentObj));
2,592✔
4106
  if (pRow == NULL) goto _OVER;
2,592✔
4107

4108
  pObj = sdbGetRowObj(pRow);
2,592✔
4109
  if (pObj == NULL) goto _OVER;
2,592✔
4110

4111
  int32_t dataPos = 0;
2,592✔
4112
  SDB_GET_INT32(pRaw, dataPos, &pObj->id, _OVER)
2,592✔
4113
  SDB_GET_INT32(pRaw, dataPos, &pObj->nameLen, _OVER)
2,592✔
4114
  if (pObj->nameLen > 0) {
2,592✔
4115
    pObj->name = taosMemoryCalloc(pObj->nameLen, 1);
2,592✔
4116
    if (pObj->name == NULL) goto _OVER;
2,592✔
4117
    SDB_GET_BINARY(pRaw, dataPos, pObj->name, pObj->nameLen, _OVER)
2,592✔
4118
  } else {
4119
    pObj->name = NULL;
×
4120
  }
4121
  SDB_GET_INT32(pRaw, dataPos, &pObj->tokenLen, _OVER)
2,592✔
4122
  if (pObj->tokenLen > 0) {
2,592✔
4123
    pObj->token = taosMemoryCalloc(pObj->tokenLen, 1);
2,592✔
4124
    if (pObj->token == NULL) goto _OVER;
2,592✔
4125
    SDB_GET_BINARY(pRaw, dataPos, pObj->token, pObj->tokenLen, _OVER)
2,592✔
4126
  } else {
4127
    pObj->token = NULL;
×
4128
  }
4129
  SDB_GET_INT32(pRaw, dataPos, &pObj->statusLen, _OVER)
2,592✔
4130
  if (pObj->statusLen > 0) {
2,592✔
4131
    pObj->status = taosMemoryCalloc(pObj->statusLen, 1);
1,944✔
4132
    if (pObj->status == NULL) goto _OVER;
1,944✔
4133
    SDB_GET_BINARY(pRaw, dataPos, pObj->status, pObj->statusLen, _OVER)
1,944✔
4134
  } else {
4135
    pObj->status = NULL;
648✔
4136
  }
4137
  SDB_GET_INT64(pRaw, dataPos, &pObj->createTime, _OVER)
2,592✔
4138
  SDB_GET_INT64(pRaw, dataPos, &pObj->updateTime, _OVER)
2,592✔
4139

4140
  SDB_GET_RESERVE(pRaw, dataPos, TSDB_XNODE_RESERVE_SIZE, _OVER)
2,592✔
4141

4142
  terrno = 0;
2,592✔
4143

4144
_OVER:
2,592✔
4145
  if (terrno != 0) {
2,592✔
4146
    mError("xnode agent:%d, failed to decode from raw:%p since %s", pObj == NULL ? 0 : pObj->id, pRaw, terrstr());
×
4147
    if (pObj != NULL) {
×
4148
      taosMemoryFreeClear(pObj->name);
×
4149
      taosMemoryFreeClear(pObj->token);
×
4150
      taosMemoryFreeClear(pObj->status);
×
4151
    }
4152
    taosMemoryFreeClear(pRow);
×
4153
    return NULL;
×
4154
  }
4155

4156
  mTrace("xnode agent:%d, decode from raw:%p, row:%p", pObj->id, pRaw, pObj);
2,592✔
4157
  return pRow;
2,592✔
4158
}
4159

4160
int32_t mndXnodeAgentActionInsert(SSdb *pSdb, SXnodeAgentObj *pObj) {
648✔
4161
  mDebug("xnode agent:%d, perform insert action, row:%p", pObj->id, pObj);
648✔
4162
  return 0;
648✔
4163
}
4164

4165
int32_t mndXnodeAgentActionUpdate(SSdb *pSdb, SXnodeAgentObj *pOld, SXnodeAgentObj *pNew) {
1,377✔
4166
  mDebug("xnode agent:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew);
1,377✔
4167

4168
  taosWLockLatch(&pOld->lock);
1,377✔
4169
  swapFields(&pNew->nameLen, &pNew->name, &pOld->nameLen, &pOld->name);
1,377✔
4170
  swapFields(&pNew->tokenLen, &pNew->token, &pOld->tokenLen, &pOld->token);
1,377✔
4171
  swapFields(&pNew->statusLen, &pNew->status, &pOld->statusLen, &pOld->status);
1,377✔
4172
  if (pNew->updateTime > pOld->updateTime) {
1,377✔
4173
    pOld->updateTime = pNew->updateTime;
162✔
4174
  }
4175
  taosWUnLockLatch(&pOld->lock);
1,377✔
4176
  return 0;
1,377✔
4177
}
4178

4179
static void mndFreeXnodeAgent(SXnodeAgentObj *pObj) {
3,240✔
4180
  if (pObj == NULL) return;
3,240✔
4181
  if (pObj->name != NULL) {
3,240✔
4182
    taosMemoryFreeClear(pObj->name);
3,240✔
4183
  }
4184
  if (pObj->token != NULL) {
3,240✔
4185
    taosMemoryFreeClear(pObj->token);
3,240✔
4186
  }
4187
  if (pObj->status != NULL) {
3,240✔
4188
    taosMemoryFreeClear(pObj->status);
2,349✔
4189
  }
4190
}
4191

4192
int32_t mndXnodeAgentActionDelete(SSdb *pSdb, SXnodeAgentObj *pObj) {
2,592✔
4193
  mDebug("xnode agent:%d, perform delete action, row:%p", pObj->id, pObj);
2,592✔
4194
  mndFreeXnodeAgent(pObj);
2,592✔
4195
  return 0;
2,592✔
4196
}
4197

4198
static int32_t mndSetCreateXnodeAgentRedoLogs(STrans *pTrans, SXnodeAgentObj *pObj) {
648✔
4199
  int32_t  code = 0;
648✔
4200
  SSdbRaw *pRedoRaw = mndXnodeAgentActionEncode(pObj);
648✔
4201
  if (pRedoRaw == NULL) {
648✔
4202
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4203
    if (terrno != 0) code = terrno;
×
4204
    TAOS_RETURN(code);
×
4205
  }
4206
  TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
648✔
4207
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING));
648✔
4208
  TAOS_RETURN(code);
648✔
4209
}
4210

4211
static int32_t mndSetCreateXnodeAgentUndoLogs(STrans *pTrans, SXnodeAgentObj *pObj) {
648✔
4212
  int32_t  code = 0;
648✔
4213
  SSdbRaw *pUndoRaw = mndXnodeAgentActionEncode(pObj);
648✔
4214
  if (pUndoRaw == NULL) {
648✔
4215
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4216
    if (terrno != 0) code = terrno;
×
4217
    TAOS_RETURN(code);
×
4218
  }
4219
  TAOS_CHECK_RETURN(mndTransAppendUndolog(pTrans, pUndoRaw));
648✔
4220
  TAOS_CHECK_RETURN(sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED));
648✔
4221
  TAOS_RETURN(code);
648✔
4222
}
4223

4224
static int32_t mndSetCreateXnodeAgentCommitLogs(STrans *pTrans, SXnodeAgentObj *pObj) {
810✔
4225
  int32_t  code = 0;
810✔
4226
  SSdbRaw *pCommitRaw = mndXnodeAgentActionEncode(pObj);
810✔
4227
  if (pCommitRaw == NULL) {
810✔
4228
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4229
    if (terrno != 0) code = terrno;
×
4230
    TAOS_RETURN(code);
×
4231
  }
4232
  TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
810✔
4233
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
810✔
4234
  TAOS_RETURN(code);
810✔
4235
}
4236

4237
void mndReleaseXnodeAgent(SMnode *pMnode, SXnodeAgentObj *pObj) {
1,539✔
4238
  SSdb *pSdb = pMnode->pSdb;
1,539✔
4239
  sdbRelease(pSdb, pObj);
1,539✔
4240
}
1,539✔
4241

4242
static int32_t mndValidateXnodePermissions(SMnode *pMnode, SRpcMsg *pReq, EOperType oper) {
648✔
4243
  int32_t code = grantCheck(TSDB_GRANT_XNODE);
648✔
4244
  if (code != TSDB_CODE_SUCCESS) {
648✔
4245
    mError("failed to create xnode, code:%s", tstrerror(code));
×
4246
    return code;
×
4247
  }
4248

4249
  return mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, oper);
648✔
4250
}
4251

4252
SXnodeAgentObj *mndAcquireXnodeAgentById(SMnode *pMnode, int32_t id) {
×
4253
  SXnodeAgentObj *pObj = sdbAcquire(pMnode->pSdb, SDB_XNODE_AGENT, &id);
×
4254
  if (pObj == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
×
4255
    terrno = TSDB_CODE_MND_XNODE_AGENT_NOT_EXIST;
×
4256
  }
4257
  return pObj;
×
4258
}
4259

4260
static SXnodeAgentObj *mndAcquireXnodeAgentByName(SMnode *pMnode, const char *name) {
2,187✔
4261
  SSdb *pSdb = pMnode->pSdb;
2,187✔
4262

4263
  void *pIter = NULL;
2,187✔
4264
  while (1) {
1,539✔
4265
    SXnodeAgentObj *pAgent = NULL;
3,726✔
4266
    pIter = sdbFetch(pSdb, SDB_XNODE_AGENT, pIter, (void **)&pAgent);
3,726✔
4267
    if (pIter == NULL) break;
3,726✔
4268
    if (pAgent->name == NULL) {
2,268✔
4269
      continue;
×
4270
    }
4271

4272
    if (strcasecmp(name, pAgent->name) == 0) {
2,268✔
4273
      sdbCancelFetch(pSdb, pIter);
729✔
4274
      return pAgent;
729✔
4275
    }
4276

4277
    sdbRelease(pSdb, pAgent);
1,539✔
4278
  }
4279

4280
  mDebug("xnode agent:%s, not found", name);
1,458✔
4281
  terrno = TSDB_CODE_MND_XNODE_AGENT_NOT_EXIST;
1,458✔
4282
  return NULL;
1,458✔
4283
}
4284

4285
static int32_t mndCheckXnodeAgentExists(SMnode *pMnode, const char *name) {
648✔
4286
  SXnodeAgentObj *pObj = mndAcquireXnodeAgentByName(pMnode, name);
648✔
4287
  if (pObj != NULL) {
648✔
4288
    mError("xnode agent:%s already exists", name);
×
4289
    mndReleaseXnodeAgent(pMnode, pObj);
×
4290
    return TSDB_CODE_MND_XNODE_AGENT_ALREADY_EXIST;
×
4291
  }
4292
  terrno = TSDB_CODE_SUCCESS;
648✔
4293
  return TSDB_CODE_SUCCESS;
648✔
4294
}
4295

4296
#ifndef WINDOWS
4297
typedef struct {
4298
  int64_t sub;  // agent ID
4299
  int64_t iat;  // issued at time
4300
} agentTokenField;
4301

4302
const unsigned char MNDXNODE_DEFAULT_SECRET[] = {126, 222, 130, 137, 43,  122, 41,  173, 144, 146, 116,
4303
                                                 138, 153, 244, 251, 99,  50,  55,  140, 238, 218, 232,
4304
                                                 15,  161, 226, 54,  130, 40,  211, 234, 111, 171};
4305

4306
agentTokenField mndXnodeCreateAgentTokenField(long agent_id, time_t issued_at) {
×
4307
  agentTokenField field = {0};
×
4308
  field.sub = agent_id;
×
4309
  field.iat = issued_at;
×
4310
  return field;
×
4311
}
4312

4313
static char *mndXnodeBase64UrlEncodeOpenssl(const unsigned char *input, size_t input_len) {
1,944✔
4314
  __uint64_t code = 0;
1,944✔
4315
  int32_t lino = 0;
1,944✔
4316
  BIO     *bio = NULL, *b64 = NULL;
1,944✔
4317
  BUF_MEM *bufferPtr = NULL;
1,944✔
4318
  char    *base64_str = NULL;
1,944✔
4319

4320
  b64 = BIO_new(BIO_f_base64());
1,944✔
4321
  if (!b64) {
1,944✔
4322
    lino = __LINE__;
×
4323
    code = ERR_get_error();
×
4324
    goto _err;
×
4325
  }
4326

4327
  bio = BIO_new(BIO_s_mem());
1,944✔
4328
  if (!bio) {
1,944✔
4329
    lino = __LINE__;
×
4330
    code = ERR_get_error();
×
4331
    goto _err;
×
4332
  }
4333

4334
  // BIO chain:b64 → bio
4335
  bio = BIO_push(b64, bio);
1,944✔
4336
  if (!bio) {
1,944✔
4337
    lino = __LINE__;
×
4338
    code = ERR_get_error();
×
4339
    goto _err;
×
4340
  }
4341
  BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
1,944✔
4342

4343
  int32_t write_ret = BIO_write(bio, input, input_len);
1,944✔
4344
  if (write_ret <= 0 || (size_t)write_ret != input_len) {
1,944✔
4345
    lino = __LINE__;
×
4346
    code = ERR_get_error();
×
4347
    goto _err;
×
4348
  }
4349
  int32_t flush_ret = BIO_flush(bio);
1,944✔
4350
  if (flush_ret != 1) {
1,944✔
4351
    lino = __LINE__;
×
4352
    code = ERR_get_error();
×
4353
    goto _err;
×
4354
  }
4355
  int64_t ret = BIO_get_mem_ptr(bio, &bufferPtr);
1,944✔
4356
  if (ret <= 0) {
1,944✔
4357
    lino = __LINE__;
×
4358
    code = ERR_get_error();
×
4359
    goto _err;
×
4360
}
4361
  if (!bufferPtr || !bufferPtr->data || bufferPtr->length == 0) {
1,944✔
4362
    lino = __LINE__;
×
4363
    code = ERR_get_error();
×
4364
    goto _err;
×
4365
  }
4366
  base64_str = taosMemoryMalloc(bufferPtr->length + 1);
1,944✔
4367
  if (!base64_str) {
1,944✔
4368
    lino = __LINE__;
×
4369
    code = ERR_get_error();
×
4370
    goto _err;
×
4371
  }
4372
  memcpy(base64_str, bufferPtr->data, bufferPtr->length);
1,944✔
4373
  base64_str[bufferPtr->length] = '\0';
1,944✔
4374
  // url safe
4375
  for (size_t i = 0; i < bufferPtr->length; i++) {
79,704✔
4376
    if (base64_str[i] == '+') {
77,760✔
4377
      base64_str[i] = '-';
243✔
4378
    } else if (base64_str[i] == '/') {
77,517✔
4379
      base64_str[i] = '_';
648✔
4380
    }
4381
  }
4382
  // remove padding char '='
4383
  size_t len = strlen(base64_str);
1,944✔
4384
  while (len > 0 && base64_str[len - 1] == '=') {
3,240✔
4385
    base64_str[len - 1] = '\0';
1,296✔
4386
    len--;
1,296✔
4387
  }
4388
  goto _exit;
1,944✔
4389

4390
_err:
×
4391
  if (code != TSDB_CODE_SUCCESS) {
×
4392
    mError("xnode agent: line: %d failed to encode base64 since %s", lino, ERR_error_string(code, NULL));
×
4393
  }
4394
  if (base64_str) {
×
4395
    taosMemoryFree(base64_str);
×
4396
    base64_str = NULL;
×
4397
  }
4398

4399
_exit:
1,944✔
4400
  if (bio) {
1,944✔
4401
    BIO_free_all(bio);  // will release b64 and bio
1,944✔
4402
  } else if (b64) {
×
4403
    int32_t ret = BIO_free(b64);
×
4404
    if (ret != 1) {
×
4405
      lino = __LINE__;
×
4406
      code = ERR_get_error();
×
4407
      mError("xnode agent: line: %d BIO failed to free since %s", lino, ERR_error_string(code, NULL));
×
4408
    }
4409
  }
4410

4411
  return base64_str;
1,944✔
4412
}
4413

4414
static char *mndXnodeCreateTokenHeader() {
648✔
4415
  int32_t code = 0, lino = 0;
648✔
4416
  cJSON  *headerJson = NULL;
648✔
4417
  char   *headerJsonStr = NULL;
648✔
4418
  char   *encoded = NULL;
648✔
4419

4420
  headerJson = tjsonCreateObject();
648✔
4421
  if (!headerJson) {
648✔
4422
    code = terrno;
×
4423
    goto _exit;
×
4424
  }
4425

4426
  TAOS_CHECK_EXIT(tjsonAddStringToObject(headerJson, "alg", "HS256"));
648✔
4427
  TAOS_CHECK_EXIT(tjsonAddStringToObject(headerJson, "typ", "JWT"));
648✔
4428

4429
  headerJsonStr = tjsonToUnformattedString(headerJson);
648✔
4430
  if (!headerJsonStr) {
648✔
4431
    code = terrno;
×
4432
    goto _exit;
×
4433
  }
4434
  encoded = mndXnodeBase64UrlEncodeOpenssl((const unsigned char *)headerJsonStr, strlen(headerJsonStr));
648✔
4435
  if (!encoded) {
648✔
4436
    code = terrno;
×
4437
    goto _exit;
×
4438
  }
4439

4440
_exit:
648✔
4441
  if (code != TSDB_CODE_SUCCESS) {
648✔
4442
    mError("xnode agent: line: %d failed to create header since %s", lino, tstrerror(code));
×
4443
    taosMemoryFree(encoded);
×
4444
    encoded = NULL;
×
4445
  }
4446

4447
  if (headerJsonStr) {
648✔
4448
    taosMemoryFree(headerJsonStr);
648✔
4449
  }
4450
  if (headerJson) {
648✔
4451
    tjsonDelete(headerJson);
648✔
4452
  }
4453

4454
  return encoded;
648✔
4455
}
4456

4457
static char *mndXnodeCreateTokenPayload(const agentTokenField *claims) {
648✔
4458
  int32_t code = 0, lino = 0;
648✔
4459
  cJSON  *payloadJson = NULL;
648✔
4460
  char   *payloadStr = NULL;
648✔
4461
  char   *encoded = NULL;
648✔
4462

4463
  if (!claims) {
648✔
4464
    code = TSDB_CODE_INVALID_PARA;
×
4465
    terrno = code;
×
4466
    return NULL;
×
4467
  }
4468

4469
  payloadJson = tjsonCreateObject();
648✔
4470
  if (!payloadJson) {
648✔
4471
    code = terrno;
×
4472
    goto _exit;
×
4473
  }
4474

4475
  TAOS_CHECK_EXIT(tjsonAddDoubleToObject(payloadJson, "iat", claims->iat));
648✔
4476
  TAOS_CHECK_EXIT(tjsonAddDoubleToObject(payloadJson, "sub", claims->sub));
648✔
4477

4478
  payloadStr = tjsonToUnformattedString(payloadJson);
648✔
4479
  if (!payloadStr) {
648✔
4480
    code = terrno;
×
4481
    goto _exit;
×
4482
  }
4483
  encoded = mndXnodeBase64UrlEncodeOpenssl((const unsigned char *)payloadStr, strlen(payloadStr));
648✔
4484
  if (!encoded) {
648✔
4485
    code = terrno;
×
4486
    goto _exit;
×
4487
  }
4488

4489
_exit:
648✔
4490
  if (code != TSDB_CODE_SUCCESS) {
648✔
4491
    mError("xnode agent line: %d failed to create payload since %s", lino, tstrerror(code));
×
4492
    taosMemoryFree(encoded);
×
4493
    encoded = NULL;
×
4494
  }
4495
  if (payloadStr) {
648✔
4496
    taosMemoryFree(payloadStr);
648✔
4497
  }
4498
  if (payloadJson) {
648✔
4499
    tjsonDelete(payloadJson);
648✔
4500
  }
4501
  return encoded;
648✔
4502
}
4503

4504
static char *mndXnodeCreateTokenSignature(const char *header_payload, const unsigned char *secret, size_t secret_len) {
648✔
4505
  int32_t       code = 0, lino = 0;
648✔
4506
  unsigned char hash[EVP_MAX_MD_SIZE] = {0};
648✔
4507
  unsigned int  hash_len = 0;
648✔
4508
  char         *encoded = NULL;
648✔
4509

4510
  // HMAC-SHA256
4511
  if (!HMAC(EVP_sha256(), secret, secret_len, (const unsigned char *)header_payload, strlen(header_payload), hash,
648✔
4512
            &hash_len)) {
4513
    code = terrno;
×
4514
    goto _exit;
×
4515
  }
4516

4517
  encoded = mndXnodeBase64UrlEncodeOpenssl(hash, hash_len);
648✔
4518
  if (!encoded) {
648✔
4519
    code = terrno;
×
4520
    goto _exit;
×
4521
  }
4522

4523
_exit:
648✔
4524
  if (code != TSDB_CODE_SUCCESS) {
648✔
4525
    mError("xnode agent line: %d failed create signature since %s", lino, tstrerror(code));
×
4526
    taosMemoryFree(encoded);
×
4527
    encoded = NULL;
×
4528
  }
4529
  return encoded;
648✔
4530
}
4531

4532
char *mndXnodeCreateAgentToken(const agentTokenField *claims, const unsigned char *secret, size_t secret_len) {
648✔
4533
  int32_t code = 0, lino = 0;
648✔
4534
  char   *header = NULL, *payload = NULL;
648✔
4535
  char   *headerPayload = NULL;
648✔
4536
  char   *signature = NULL;
648✔
4537
  char   *token = NULL;
648✔
4538

4539
  if (!claims) {
648✔
4540
    code = TSDB_CODE_INVALID_PARA;
×
4541
    goto _exit;
×
4542
  }
4543

4544
  if (!secret || secret_len == 0) {
648✔
4545
    secret = MNDXNODE_DEFAULT_SECRET;
×
4546
    secret_len = sizeof(MNDXNODE_DEFAULT_SECRET);
×
4547
  }
4548

4549
  header = mndXnodeCreateTokenHeader();
648✔
4550
  if (!header) {
648✔
4551
    code = terrno;
×
4552
    goto _exit;
×
4553
  }
4554

4555
  payload = mndXnodeCreateTokenPayload(claims);
648✔
4556
  if (!payload) {
648✔
4557
    code = terrno;
×
4558
    goto _exit;
×
4559
  }
4560

4561
  size_t header_payload_len = strlen(header) + strlen(payload) + 2;
648✔
4562
  headerPayload = taosMemoryMalloc(header_payload_len);
648✔
4563
  if (!headerPayload) {
648✔
4564
    code = terrno;
×
4565
    goto _exit;
×
4566
  }
4567
  snprintf(headerPayload, header_payload_len, "%s.%s", header, payload);
648✔
4568

4569
  signature = mndXnodeCreateTokenSignature(headerPayload, secret, secret_len);
648✔
4570
  if (!signature) {
648✔
4571
    code = terrno;
×
4572
    goto _exit;
×
4573
  }
4574

4575
  size_t token_len = strlen(headerPayload) + strlen(signature) + 2;
648✔
4576
  token = taosMemoryCalloc(1, token_len);
648✔
4577
  if (!token) {
648✔
4578
    code = terrno;
×
4579
    goto _exit;
×
4580
  }
4581

4582
  snprintf(token, token_len, "%s.%s", headerPayload, signature);
648✔
4583

4584
_exit:
648✔
4585
  if (code != TSDB_CODE_SUCCESS) {
648✔
4586
    mError("xnode agent line: %d failed create token since %s", lino, tstrerror(code));
×
4587
    taosMemoryFree(token);
×
4588
    token = NULL;
×
4589
  }
4590
  taosMemoryFree(signature);
648✔
4591
  taosMemoryFree(headerPayload);
648✔
4592
  taosMemoryFree(payload);
648✔
4593
  taosMemoryFree(header);
648✔
4594

4595
  return token;
648✔
4596
}
4597
#endif
4598

4599
int32_t mndXnodeGenAgentToken(const SXnodeAgentObj *pAgent, char *pTokenBuf) {
648✔
4600
  int32_t code = 0, lino = 0;
648✔
4601
  #ifndef WINDOWS
4602
  // char *token =
4603
  //     "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3Njc1OTc3NzIsInN1YiI6MTIzNDV9.i7HvYf_S-yWGEExDzQESPUwVX23Ok_"
4604
  //     "7Fxo93aqgKrtw";
4605
  agentTokenField claims = {
648✔
4606
      .iat = pAgent->createTime,
648✔
4607
      .sub = pAgent->id,
648✔
4608
  };
4609
  char *token = mndXnodeCreateAgentToken(&claims, MNDXNODE_DEFAULT_SECRET, sizeof(MNDXNODE_DEFAULT_SECRET));
648✔
4610
  if (!token) {
648✔
4611
    code = terrno;
×
4612
    lino = __LINE__;
×
4613
    goto _exit;
×
4614
  }
4615
  (void)memcpy(pTokenBuf, token, TMIN(strlen(token) + 1, TSDB_XNODE_AGENT_TOKEN_LEN));
648✔
4616

4617
_exit:
648✔
4618
  if (code != TSDB_CODE_SUCCESS) {
648✔
4619
    mError("xnode agent line: %d failed gen token since %s", lino, tstrerror(code));
×
4620
  }
4621
  taosMemoryFree(token);
648✔
4622
  #endif
4623
  TAOS_RETURN(code);
648✔
4624
}
4625

4626
static int32_t mndCreateXnodeAgent(SMnode *pMnode, SRpcMsg *pReq, SMCreateXnodeAgentReq *pCreate,
648✔
4627
                                   SXnodeAgentObj **ppObj) {
4628
  int32_t code = -1;
648✔
4629
  STrans *pTrans = NULL;
648✔
4630

4631
  if ((*ppObj) == NULL) {
648✔
4632
    *ppObj = taosMemoryCalloc(1, sizeof(SXnodeAgentObj));
648✔
4633
    if (*ppObj == NULL) {
648✔
4634
      code = terrno;
×
4635
      goto _OVER;
×
4636
    }
4637
  }
4638
  SXnodeAgentObj *pAgentObj = *ppObj;
648✔
4639

4640
  pAgentObj->id = sdbGetMaxId(pMnode->pSdb, SDB_XNODE_AGENT);
648✔
4641
  pAgentObj->createTime = taosGetTimestampMs();
648✔
4642
  pAgentObj->updateTime = pAgentObj->createTime;
648✔
4643

4644
  pAgentObj->nameLen = pCreate->name.len + 1;
648✔
4645
  pAgentObj->name = taosMemoryCalloc(1, pAgentObj->nameLen);
648✔
4646
  if (pAgentObj->name == NULL) goto _OVER;
648✔
4647
  (void)memcpy(pAgentObj->name, pCreate->name.ptr, pCreate->name.len);
648✔
4648

4649
  if (pCreate->status.ptr != NULL) {
648✔
4650
    pAgentObj->statusLen = pCreate->status.len + 1;
405✔
4651
    pAgentObj->status = taosMemoryCalloc(1, pAgentObj->statusLen);
405✔
4652
    if (pAgentObj->status == NULL) goto _OVER;
405✔
4653
    (void)memcpy(pAgentObj->status, pCreate->status.ptr, pCreate->status.len);
405✔
4654
  }
4655
  // gen token
4656
  char token[TSDB_XNODE_AGENT_TOKEN_LEN] = {0};
648✔
4657
  TAOS_CHECK_GOTO(mndXnodeGenAgentToken(pAgentObj, token), NULL, _OVER);
648✔
4658
  pAgentObj->tokenLen = strlen(token) + 1;
648✔
4659
  pAgentObj->token = taosMemoryCalloc(1, pAgentObj->tokenLen);
648✔
4660
  if (pAgentObj->token == NULL) goto _OVER;
648✔
4661
  (void)memcpy(pAgentObj->token, token, pAgentObj->tokenLen - 1);
648✔
4662

4663
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-xnode-agent");
648✔
4664
  if (pTrans == NULL) {
648✔
4665
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4666
    if (terrno != 0) {
×
4667
      code = terrno;
×
4668
    }
4669
    mError("failed to create transaction for xnode-agent:%s, code:0x%x:%s", pCreate->name.ptr, code, tstrerror(code));
×
4670
    goto _OVER;
×
4671
  }
4672
  mndTransSetSerial(pTrans);
648✔
4673

4674
  mDebug("trans:%d, used to create xnode agent:%s as agent:%d", pTrans->id, pCreate->name.ptr, pAgentObj->id);
648✔
4675
  TAOS_CHECK_GOTO(mndSetCreateXnodeAgentRedoLogs(pTrans, pAgentObj), NULL, _OVER);
648✔
4676
  TAOS_CHECK_GOTO(mndSetCreateXnodeAgentUndoLogs(pTrans, pAgentObj), NULL, _OVER);
648✔
4677
  TAOS_CHECK_GOTO(mndSetCreateXnodeAgentCommitLogs(pTrans, pAgentObj), NULL, _OVER);
648✔
4678
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
648✔
4679

4680
  code = 0;
648✔
4681

4682
_OVER:
648✔
4683
  mndTransDrop(pTrans);
648✔
4684
  TAOS_RETURN(code);
648✔
4685
}
4686

4687
static int32_t httpCreateAgent(SXnodeAgentObj *pObj) {
648✔
4688
  int32_t code = 0;
648✔
4689
  SJson  *pJson = NULL;
648✔
4690
  SJson  *postContent = NULL;
648✔
4691
  char   *pContStr = NULL;
648✔
4692

4693
  char xnodeUrl[TSDB_XNODE_URL_LEN + 1] = {0};
648✔
4694
  snprintf(xnodeUrl, TSDB_XNODE_URL_LEN + 1, "%s/agent", XNODED_PIPE_SOCKET_URL);
648✔
4695
  postContent = tjsonCreateObject();
648✔
4696
  if (postContent == NULL) {
648✔
4697
    code = terrno;
×
4698
    goto _OVER;
×
4699
  }
4700
  TAOS_CHECK_GOTO(tjsonAddStringToObject(postContent, "token", pObj->token), NULL, _OVER);
648✔
4701
  pContStr = tjsonToUnformattedString(postContent);
648✔
4702
  if (pContStr == NULL) {
648✔
4703
    code = terrno;
×
4704
    goto _OVER;
×
4705
  }
4706
  pJson = mndSendReqRetJson(xnodeUrl, HTTP_TYPE_POST, defaultTimeout, pContStr, strlen(pContStr));
648✔
4707

4708
_OVER:
648✔
4709
  if (postContent != NULL) {
648✔
4710
    tjsonDelete(postContent);
648✔
4711
  }
4712
  if (pContStr != NULL) {
648✔
4713
    taosMemFree(pContStr);
648✔
4714
  }
4715
  if (pJson != NULL) {
648✔
4716
    tjsonDelete(pJson);
×
4717
  }
4718
  TAOS_RETURN(code);
648✔
4719
}
4720

4721
static int32_t mndProcessCreateXnodeAgentReq(SRpcMsg *pReq) {
648✔
4722
  SMnode               *pMnode = pReq->info.node;
648✔
4723
  int32_t               code = 0;
648✔
4724
  SXnodeAgentObj       *pObj = NULL;
648✔
4725
  SMCreateXnodeAgentReq createReq = {0};
648✔
4726

4727
  code = mndValidateXnodePermissions(pMnode, pReq, MND_OPER_CREATE_XNODE_AGENT);
648✔
4728
  if (code != TSDB_CODE_SUCCESS) {
648✔
4729
    goto _OVER;
×
4730
  }
4731

4732
  code = tDeserializeSMCreateXnodeAgentReq(pReq->pCont, pReq->contLen, &createReq);
648✔
4733
  if (code != 0) {
648✔
4734
    mError("failed to deserialize create xnode agent request, code:%s", tstrerror(code));
×
4735
    TAOS_RETURN(code);
×
4736
  }
4737

4738
  TAOS_CHECK_GOTO(mndCheckXnodeAgentExists(pMnode, createReq.name.ptr), NULL, _OVER);
648✔
4739

4740
  TAOS_CHECK_GOTO(mndCreateXnodeAgent(pMnode, pReq, &createReq, &pObj), NULL, _OVER);
648✔
4741
  code = TSDB_CODE_ACTION_IN_PROGRESS;
648✔
4742

4743
  (void)httpCreateAgent(pObj);
648✔
4744

4745
_OVER:
648✔
4746
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
648✔
4747
    mError("xnode agent:%s, failed to create since %s", createReq.name.ptr ? createReq.name.ptr : "unknown",
×
4748
           tstrerror(code));
4749
  }
4750
  if (pObj != NULL) {
648✔
4751
    mndFreeXnodeAgent(pObj);
648✔
4752
    taosMemoryFree(pObj);
648✔
4753
  }
4754
  tFreeSMCreateXnodeAgentReq(&createReq);
648✔
4755
  TAOS_RETURN(code);
648✔
4756
}
4757

4758
static int32_t mndUpdateXnodeAgent(SMnode *pMnode, SRpcMsg *pReq, const SXnodeAgentObj *pOld,
162✔
4759
                                   SMUpdateXnodeAgentReq *pUpdate) {
4760
  mDebug("xnode agent:%d, start to update", pUpdate->id);
162✔
4761
  int32_t        code = -1;
162✔
4762
  STrans        *pTrans = NULL;
162✔
4763
  struct {
4764
    bool status;
4765
    bool name;
4766
  } isChange = {0};
162✔
4767
  SXnodeAgentObj agentObjRef = *pOld;
162✔
4768

4769
  const char *status = getXTaskOptionByName(&pUpdate->options, "status");
162✔
4770
  if (status != NULL) {
162✔
4771
    isChange.status = true;
162✔
4772
    agentObjRef.statusLen = strlen(status) + 1;
162✔
4773
    agentObjRef.status = taosMemoryCalloc(1, agentObjRef.statusLen);
162✔
4774
    if (agentObjRef.status == NULL) goto _OVER;
162✔
4775
    (void)memcpy(agentObjRef.status, status, agentObjRef.statusLen);
162✔
4776
  }
4777
  const char *name = getXTaskOptionByName(&pUpdate->options, "name");
162✔
4778
  if (name != NULL) {
162✔
4779
    isChange.name = true;
×
4780
    agentObjRef.nameLen = strlen(name) + 1;
×
4781
    agentObjRef.name = taosMemoryCalloc(1, agentObjRef.nameLen);
×
4782
    if (agentObjRef.name == NULL) goto _OVER;
×
4783
    (void)memcpy(agentObjRef.name, name, agentObjRef.nameLen);
×
4784
  }
4785
  agentObjRef.updateTime = taosGetTimestampMs();
162✔
4786

4787
  pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "update-xnode-agent");
162✔
4788
  if (pTrans == NULL) {
162✔
4789
    code = TSDB_CODE_MND_RETURN_VALUE_NULL;
×
4790
    if (terrno != 0) code = terrno;
×
4791
    goto _OVER;
×
4792
  }
4793
  mInfo("trans:%d, used to update xnode agent:%d", pTrans->id, agentObjRef.id);
162✔
4794

4795
  TAOS_CHECK_GOTO(mndSetCreateXnodeAgentCommitLogs(pTrans, &agentObjRef), NULL, _OVER);
162✔
4796
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
162✔
4797
  code = 0;
162✔
4798

4799
_OVER:
162✔
4800
  if (isChange.status) {
162✔
4801
    taosMemoryFree(agentObjRef.status);
162✔
4802
  }
4803
  if (isChange.name) {
162✔
4804
    taosMemoryFree(agentObjRef.name);
×
4805
  }
4806
  mndTransDrop(pTrans);
162✔
4807
  TAOS_RETURN(code);
162✔
4808
}
4809

4810
static int32_t mndProcessUpdateXnodeAgentReq(SRpcMsg *pReq) {
162✔
4811
  SMnode               *pMnode = pReq->info.node;
162✔
4812
  int32_t               code = -1;
162✔
4813
  SXnodeAgentObj       *pObj = NULL;
162✔
4814
  SMUpdateXnodeAgentReq updateReq = {0};
162✔
4815

4816
  if ((code = grantCheck(TSDB_GRANT_XNODE)) != TSDB_CODE_SUCCESS) {
162✔
4817
    mError("failed grant update xnode agent, code:%s", tstrerror(code));
×
4818
    goto _OVER;
×
4819
  }
4820

4821
  TAOS_CHECK_GOTO(tDeserializeSMUpdateXnodeAgentReq(pReq->pCont, pReq->contLen, &updateReq), NULL, _OVER);
162✔
4822
  mDebug("xnode update agent request id:%d, nameLen:%d\n", updateReq.id, updateReq.name.len);
162✔
4823

4824
  if (updateReq.id <= 0 && (updateReq.name.len <= 0 || updateReq.name.ptr == NULL)) {
162✔
4825
    code = TSDB_CODE_MND_XNODE_INVALID_MSG;
×
4826
    goto _OVER;
×
4827
  }
4828

4829
  if (updateReq.id > 0) {
162✔
4830
    pObj = mndAcquireXnodeAgentById(pMnode, updateReq.id);
×
4831
  } else {
4832
    pObj = mndAcquireXnodeAgentByName(pMnode, updateReq.name.ptr);
162✔
4833
  }
4834
  if (pObj == NULL) {
162✔
4835
    code = terrno;
×
4836
    goto _OVER;
×
4837
  }
4838
  const char *nameRef = getXTaskOptionByName(&updateReq.options, "name");
162✔
4839
  if (nameRef != NULL) {
162✔
4840
    SXnodeAgentObj* tmpObj = mndAcquireXnodeAgentByName(pMnode, nameRef);
×
4841
    if (tmpObj != NULL) {
×
4842
      mndReleaseXnodeAgent(pMnode, tmpObj);
×
4843
      code = TSDB_CODE_MND_XNODE_NAME_DUPLICATE;
×
4844
      goto _OVER;
×
4845
    }
4846
  }
4847

4848
  code = mndUpdateXnodeAgent(pMnode, pReq, pObj, &updateReq);
162✔
4849
  if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
162✔
4850

4851
_OVER:
162✔
4852
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
162✔
4853
    mError("xnode agent:%d, failed to update since %s", updateReq.id, tstrerror(code));
×
4854
  }
4855

4856
  mndReleaseXnodeAgent(pMnode, pObj);
162✔
4857
  tFreeSMUpdateXnodeAgentReq(&updateReq);
162✔
4858
  TAOS_RETURN(code);
162✔
4859
}
4860

4861
static int32_t mndSetDropXnodeAgentRedoLogs(STrans *pTrans, SXnodeAgentObj *pObj) {
567✔
4862
  int32_t  code = 0;
567✔
4863
  SSdbRaw *pRedoRaw = mndXnodeAgentActionEncode(pObj);
567✔
4864
  if (pRedoRaw == NULL) {
567✔
4865
    code = terrno;
×
4866
    return code;
×
4867
  }
4868

4869
  TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
567✔
4870
  TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING));
567✔
4871

4872
  TAOS_RETURN(code);
567✔
4873
}
4874

4875
static int32_t mndSetDropXnodeAgentCommitLogs(STrans *pTrans, SXnodeAgentObj *pObj) {
567✔
4876
  int32_t  code = 0;
567✔
4877
  SSdbRaw *pCommitRaw = mndXnodeAgentActionEncode(pObj);
567✔
4878
  if (pCommitRaw == NULL) {
567✔
4879
    code = terrno;
×
4880
    return code;
×
4881
  }
4882

4883
  TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
567✔
4884
  TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED));
567✔
4885
  TAOS_RETURN(code);
567✔
4886
}
4887

4888
static int32_t mndDropXnodeAgent(SMnode *pMnode, SRpcMsg *pReq, SXnodeAgentObj *pAgent) {
567✔
4889
  int32_t code = 0;
567✔
4890
  int32_t lino = 0;
567✔
4891

4892
  if (pAgent == NULL) {
567✔
4893
    mError("xnode agent fail to drop since pAgent is NULL");
×
4894
    code = TSDB_CODE_INVALID_PARA;
×
4895
    return code;
×
4896
  }
4897
  STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq, "drop-xnode-agent");
567✔
4898
  TSDB_CHECK_NULL(pTrans, code, lino, _OVER, terrno);
567✔
4899
  mndTransSetSerial(pTrans);
567✔
4900
  mDebug("trans:%d, to drop xnode agent:%d", pTrans->id, pAgent->id);
567✔
4901

4902
  TAOS_CHECK_GOTO(mndSetDropXnodeAgentRedoLogs(pTrans, pAgent), NULL, _OVER);
567✔
4903
  TAOS_CHECK_GOTO(mndSetDropXnodeAgentCommitLogs(pTrans, pAgent), NULL, _OVER);
567✔
4904
  TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
567✔
4905

4906
_OVER:
567✔
4907
  mndTransDrop(pTrans);
567✔
4908
  TAOS_RETURN(code);
567✔
4909
}
4910

4911
static int32_t mndProcessDropXnodeAgentReq(SRpcMsg *pReq) {
1,377✔
4912
  SMnode             *pMnode = pReq->info.node;
1,377✔
4913
  int32_t             code = -1;
1,377✔
4914
  SXnodeAgentObj     *pObj = NULL;
1,377✔
4915
  SMDropXnodeAgentReq dropReq = {0};
1,377✔
4916

4917
  TAOS_CHECK_GOTO(tDeserializeSMDropXnodeAgentReq(pReq->pCont, pReq->contLen, &dropReq), NULL, _OVER);
1,377✔
4918
  mDebug("xnode drop agent with id:%d, start to drop", dropReq.id);
1,377✔
4919

4920
  TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, NULL, MND_OPER_DROP_XNODE_AGENT), NULL, _OVER);
1,377✔
4921

4922
  if (dropReq.id <= 0 && (dropReq.name.len <= 0 || dropReq.name.ptr == NULL)) {
1,377✔
4923
    code = TSDB_CODE_MND_XNODE_INVALID_MSG;
×
4924
    goto _OVER;
×
4925
  }
4926

4927
  if (dropReq.name.len > 0 && dropReq.name.ptr != NULL) {
1,377✔
4928
    pObj = mndAcquireXnodeAgentByName(pMnode, dropReq.name.ptr);
1,377✔
4929
  } else {
4930
    pObj = mndAcquireXnodeAgentById(pMnode, dropReq.id);
×
4931
  }
4932
  if (pObj == NULL) {
1,377✔
4933
    code = terrno;
810✔
4934
    goto _OVER;
810✔
4935
  }
4936

4937
  // send request to drop xnode task
4938
  char xnodeUrl[TSDB_XNODE_URL_LEN + 1] = {0};
567✔
4939
  snprintf(xnodeUrl, TSDB_XNODE_URL_LEN + 1, "%s/agent/%d", XNODED_PIPE_SOCKET_URL, pObj->id);
567✔
4940
  SJson *pJson = mndSendReqRetJson(xnodeUrl, HTTP_TYPE_DELETE, defaultTimeout, NULL, 0);
567✔
4941
  if (pJson) {
567✔
NEW
4942
    tjsonDelete(pJson);
×
4943
  }
4944

4945
  code = mndDropXnodeAgent(pMnode, pReq, pObj);
567✔
4946
  if (code == 0) {
567✔
4947
    code = TSDB_CODE_ACTION_IN_PROGRESS;
567✔
4948
  }
4949

4950
_OVER:
1,377✔
4951
  if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
1,377✔
4952
    mError("xnode task:%d, failed to drop since %s", dropReq.id, tstrerror(code));
810✔
4953
  }
4954
  mndReleaseXnodeAgent(pMnode, pObj);
1,377✔
4955
  tFreeSMDropXnodeAgentReq(&dropReq);
1,377✔
4956
  TAOS_RETURN(code);
1,377✔
4957
}
4958

4959
static int32_t mndRetrieveXnodeAgents(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
2,149✔
4960
  int32_t         code = 0;
2,149✔
4961
  SMnode         *pMnode = pReq->info.node;
2,149✔
4962
  SSdb           *pSdb = pMnode->pSdb;
2,149✔
4963
  int32_t         numOfRows = 0;
2,149✔
4964
  int32_t         cols = 0;
2,149✔
4965
  char            buf[VARSTR_HEADER_SIZE + TSDB_XNODE_AGENT_TOKEN_LEN];
2,149✔
4966
  SXnodeAgentObj *pObj = NULL;
2,149✔
4967

4968
  while (numOfRows < rows) {
7,819✔
4969
    pShow->pIter = sdbFetch(pSdb, SDB_XNODE_AGENT, pShow->pIter, (void **)&pObj);
7,819✔
4970
    if (pShow->pIter == NULL) break;
7,819✔
4971

4972
    cols = 0;
5,670✔
4973
    SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5,670✔
4974
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->id, false);
5,670✔
4975
    if (code != 0) goto _end;
5,670✔
4976

4977
    STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->name, pShow->pMeta->pSchemas[cols].bytes);
5,670✔
4978
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5,670✔
4979
    code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
5,670✔
4980
    if (code != 0) goto _end;
5,670✔
4981

4982
    if (pObj->tokenLen > 0) {
5,670✔
4983
      buf[0] = 0;
5,670✔
4984
      STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->token, pShow->pMeta->pSchemas[cols].bytes);
5,670✔
4985
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5,670✔
4986
      code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
5,670✔
4987
      if (code != 0) goto _end;
5,670✔
4988
    } else {
4989
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
×
4990
      colDataSetNULL(pColInfo, numOfRows);
×
4991
    }
4992

4993
    if (pObj->statusLen > 0) {
5,670✔
4994
      buf[0] = 0;
2,673✔
4995
      STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->status, pShow->pMeta->pSchemas[cols].bytes);
2,673✔
4996
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,673✔
4997
      code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
2,673✔
4998
      if (code != 0) goto _end;
2,673✔
4999
    } else {
5000
      pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
2,997✔
5001
      colDataSetNULL(pColInfo, numOfRows);
2,997✔
5002
    }
5003

5004
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5,670✔
5005
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->createTime, false);
5,670✔
5006
    if (code != 0) goto _end;
5,670✔
5007

5008
    pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
5,670✔
5009
    code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->updateTime, false);
5,670✔
5010
    if (code != 0) goto _end;
5,670✔
5011

5012
    numOfRows++;
5,670✔
5013
    sdbRelease(pSdb, pObj);
5,670✔
5014
  }
5015

5016
_end:
2,149✔
5017
  if (code != 0) sdbRelease(pSdb, pObj);
2,149✔
5018

5019
  pShow->numOfRows += numOfRows;
2,149✔
5020
  return numOfRows;
2,149✔
5021
}
5022

5023
static void mndCancelGetNextXnodeAgent(SMnode *pMnode, void *pIter) {
×
5024
  SSdb *pSdb = pMnode->pSdb;
×
5025
  sdbCancelFetchByType(pSdb, pIter, SDB_XNODE_AGENT);
×
5026
}
×
5027

5028
/** xnoded mgmt section **/
5029

5030
void mndStartXnoded(SMnode *pMnode, const char *user, const char *pass, const char *token) {
678✔
5031
  int32_t   code = 0;
678✔
5032
  SXnodeOpt pOption = {0};
678✔
5033

5034
  if ((user == NULL || pass == NULL) && token == NULL) {
678✔
NEW
5035
    mError("xnode failed to start xnoded, dnode:%d", pMnode->selfDnodeId);
×
NEW
5036
    return;
×
5037
  }
5038

5039
  pOption.dnodeId = pMnode->selfDnodeId;
678✔
5040
  pOption.clusterId = pMnode->clusterId;
678✔
5041

5042
  SEpSet epset = mndGetDnodeEpsetById(pMnode, pMnode->selfDnodeId);
678✔
5043
  if (epset.numOfEps == 0) {
678✔
5044
    mError("xnode failed to start xnoded, dnode:%d", pMnode->selfDnodeId);
×
5045
    return;
×
5046
  }
5047
  pOption.ep = epset.eps[0];
678✔
5048
  // add user password
5049
  if (user != NULL && pass != NULL) {
678✔
5050
    pOption.upLen = strlen(user) + strlen(pass) + 1;
435✔
5051
    snprintf(pOption.userPass, XNODE_USER_PASS_LEN, "%s:%s", user, pass);
435✔
5052
  }
5053
  // add token
5054
  if (token != NULL) {
678✔
5055
    snprintf(pOption.token, sizeof(pOption.token), "%s", token);
243✔
5056
  }
5057
  if ((code = mndOpenXnd(&pOption)) != 0) {
678✔
5058
    mError("xnode failed to open xnd since %s, dnodeId:%d", tstrerror(code), pOption.dnodeId);
192✔
5059
    return;
192✔
5060
  }
5061
}
5062

5063
void mndXnodeHandleBecomeLeader(SMnode *pMnode) {
378,057✔
5064
  mInfo("mndxnode start to process mnode become leader");
378,057✔
5065
  SXnodeUserPassObj *pObj = mndAcquireFirstXnodeUserPass(pMnode);
378,057✔
5066
  if (pObj == NULL) {
378,057✔
5067
    mInfo("mndXnode become leader found no xnoded user pass");
378,057✔
5068
    return;
378,057✔
5069
  }
5070

NEW
5071
  mndStartXnoded(pMnode, pObj->user, pObj->pass, pObj->token);
×
NEW
5072
  mndReleaseXnodeUserPass(pMnode, pObj);
×
5073
}
5074

5075
void mndXnodeHandleBecomeNotLeader() {
53,792✔
5076
  mInfo("mndxnode handle mnode become not leader");
53,792✔
5077
  mndCloseXnd();
53,792✔
5078
}
53,792✔
5079

5080
void mndRestartXnoded(SMnode *pMnode) {
486✔
5081
  mInfo("mndxnode restart xnoded");
486✔
5082
  mndCloseXnd();
486✔
5083

5084
  taosMsleep(200);
486✔
5085
  SXnodeUserPassObj *pObj = mndAcquireFirstXnodeUserPass(pMnode);
486✔
5086
  if (pObj == NULL) {
486✔
NEW
5087
    mInfo("mndXnode restart found no xnoded user pass");
×
NEW
5088
    return;
×
5089
  }
5090
  mndStartXnoded(pMnode, pObj->user, pObj->pass, pObj->token);
486✔
5091
  mndReleaseXnodeUserPass(pMnode, pObj);
486✔
5092
  mInfo("mndxnode xnoded restarted");
486✔
5093
  return;
486✔
5094
}
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