mirror of
https://github.com/taosdata/TDengine
synced 2026-05-24 10:09:01 +00:00
* feat: add xnode syntax * refactor(xnode): reduce function complexity * chore: add lost xnode.h file * feat(xnode): create xnode task * chore: fix double free error * add xnoded * start xnoded as subprocess * complete xnode task feature * complete show xnode jobs feature * complete with option feature * complete alter xnode job feature * complete alter xnode task feature * complete user pass feature * clean code * modify status type as char * fix leader ep null * fix start task req null * fix pass id for status * support timeout msg * drop xnode task relative jobs * clean code * wip * chore: add test cases for xnode * chore: fix 3.0 merge changes * fix drain core dump and create task core dump * add password check * retrieve xnode status from xnoded * pass integer as double to cjson * add some debug log * add some job log * fix start task lock * do not handle http response * fix coredump drop xnode task by name * support start/stop/drop task by name * remove mock xnoded * support unix socket * kill pre-xnoded before start * support dnode close xnoded * test(xnode): add unit test cases for xnode * rebalance support where clause * fix some test issue * unformat http post content json string * add xnode zh doc * modify drain description * remove job create/stop/drop operation * support rebalance all without where condition * support alter task by name * add NULL param for mndCheckOperPrivilege * add xnode txnode module for libmnode.a * code clean * change parser len to 4096 * clean code * chore: try to fix gtest/gtest.h not found * chore: fix markdown files * chore: fix markdown in zh * chore: fix enum issue and add ci * chore: fix test case problem * chore: fix pKeyVal overflow * chore: rename to 排空节点 * chore: external cmake remove parallel * chore: add DEP_ext_gtest for xnode test * chore: fix gtest errors * chore: remove gtest pthread lib * chore: fix data type not match * chore: fix some lint errors * chore: fix void unlink * chore: fix return with null pointer check * chore: fix pointer double free and xnodeMemoryTest strncpy null * chore: fix xnode encode action invalid datelen * chore: remove TD_LINUX condition * chore: use PRIu64 denote long long * chore: fix task parser NULL and allow no with clause * fix(xnode): fix windows build error * chore: fix windows curl error * chore: fix test case ins_tables relative error * chore: fix memory leak * docs: update taosx docs * chore: update taosx docs * chore: add role priviledge table * chore: fix error code doc * chore: fix test_xnode.py * chore: fix doc typo * fix: ci error while run test_user_privilege_sysinfo.py --------- Co-authored-by: Linhe Huo <linhehuo@gmail.com> Co-authored-by: huohong <sallyhuo@taosdata.com> Co-authored-by: Simon Guan <guanshengliang@qq.com>
271 lines
7.2 KiB
C
271 lines
7.2 KiB
C
/*
|
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
|
*
|
|
* This program is free software: you can use, redistribute, and/or modify
|
|
* it under the terms of the GNU Affero General Public License, version 3
|
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http:www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#define _DEFAULT_SOURCE
|
|
#include "tjson.h"
|
|
#include "xmInt.h"
|
|
|
|
static int32_t xmRequire(const SMgmtInputOpt *pInput, bool *required) {
|
|
xndInfo("xnode require call path:%s, name:%s", pInput->path, pInput->name);
|
|
*required = true;
|
|
return TSDB_CODE_SUCCESS;
|
|
}
|
|
|
|
static void xmInitOption(SXnodeMgmt *pMgmt, SXnodeOpt *pOption) {
|
|
pOption->msgCb = pMgmt->msgCb;
|
|
pOption->dnodeId = pMgmt->pData->dnodeId;
|
|
pOption->clusterId = pMgmt->pData->clusterId;
|
|
(void)memmove(pOption->machineId, pMgmt->pData->machineId, TSDB_MACHINE_ID_LEN + 1);
|
|
}
|
|
|
|
static void xmClose(SXnodeMgmt *pMgmt) {
|
|
if (pMgmt->pXnode != NULL) {
|
|
xndClose(pMgmt->pXnode);
|
|
pMgmt->pXnode = NULL;
|
|
}
|
|
taosMemoryFree(pMgmt);
|
|
}
|
|
|
|
static int32_t xndOpenWrapper(SXnodeOpt *pOption, SXnode **pXnode) {
|
|
int32_t code = xndOpen(pOption, pXnode);
|
|
return code;
|
|
}
|
|
|
|
// int32_t xmPutMsgToQueue(SXnodeMgmt *pMgmt, EQueueType qtype, SRpcMsg *pRpc) {
|
|
// int32_t code;
|
|
// SRpcMsg *pMsg;
|
|
|
|
// code = taosAllocateQitem(sizeof(SRpcMsg), RPC_QITEM, pRpc->contLen, (void **)&pMsg);
|
|
// if (code) {
|
|
// rpcFreeCont(pRpc->pCont);
|
|
// pRpc->pCont = NULL;
|
|
// return code = terrno;
|
|
// }
|
|
|
|
// SBnode *pBnode = pMgmt->pBnode;
|
|
// if (pBnode == NULL) {
|
|
// code = terrno;
|
|
// dError("msg:%p failed to put into bnode queue since %s, type:%s qtype:%d len:%d", pMsg, tstrerror(code),
|
|
// TMSG_INFO(pMsg->msgType), qtype, pRpc->contLen);
|
|
// taosFreeQitem(pMsg);
|
|
// rpcFreeCont(pRpc->pCont);
|
|
// pRpc->pCont = NULL;
|
|
// return code;
|
|
// }
|
|
|
|
// SMsgHead *pHead = pRpc->pCont;
|
|
// pHead->contLen = htonl(pHead->contLen);
|
|
// pHead->vgId = SNODE_HANDLE;
|
|
// memcpy(pMsg, pRpc, sizeof(SRpcMsg));
|
|
// pRpc->pCont = NULL;
|
|
|
|
// switch (qtype) {
|
|
// case WRITE_QUEUE:
|
|
// // code = bmPutNodeMsgToWriteQueue(pMgmt, pMsg);
|
|
// // break;
|
|
// default:
|
|
// code = TSDB_CODE_INVALID_PARA;
|
|
// rpcFreeCont(pMsg->pCont);
|
|
// taosFreeQitem(pMsg);
|
|
// return code;
|
|
// }
|
|
// return code;
|
|
// }
|
|
|
|
static int32_t xmOpen(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) {
|
|
int32_t code = 0;
|
|
SXnodeMgmt *pMgmt = taosMemoryCalloc(1, sizeof(SXnodeMgmt));
|
|
if (pMgmt == NULL) {
|
|
return terrno;
|
|
}
|
|
pMgmt->pData = pInput->pData;
|
|
pMgmt->path = pInput->path;
|
|
pMgmt->name = pInput->name;
|
|
pMgmt->msgCb = pInput->msgCb;
|
|
// pMgmt->msgCb.putToQueueFp = (PutToQueueFp)xmPutMsgToQueue;
|
|
pMgmt->msgCb.mgmt = pMgmt;
|
|
|
|
SXnodeOpt option = {0};
|
|
xmInitOption(pMgmt, &option);
|
|
|
|
code = xndOpenWrapper(&option, &pMgmt->pXnode);
|
|
if (code != 0) {
|
|
dError("failed to open xnode since %s", tstrerror(code));
|
|
xmClose(pMgmt);
|
|
return code;
|
|
}
|
|
|
|
pOutput->pMgmt = pMgmt;
|
|
return code;
|
|
}
|
|
|
|
static int32_t xmEncodeFile(SJson *pJson, bool deployed, int32_t proto) {
|
|
if (tjsonAddDoubleToObject(pJson, "deployed", deployed) < 0) {
|
|
return TSDB_CODE_INVALID_JSON_FORMAT;
|
|
}
|
|
|
|
if (tjsonAddIntegerToObject(pJson, "proto", proto) < 0) {
|
|
return TSDB_CODE_INVALID_JSON_FORMAT;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int32_t xmWriteFile(const char *path, const char *name, bool deployed, int32_t proto) {
|
|
int32_t code = -1;
|
|
char *buffer = NULL;
|
|
SJson *pJson = NULL;
|
|
TdFilePtr pFile = NULL;
|
|
char file[PATH_MAX] = {0};
|
|
char realfile[PATH_MAX] = {0};
|
|
|
|
int32_t nBytes = snprintf(file, sizeof(file), "%s%s%s.json", path, TD_DIRSEP, name);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
code = TSDB_CODE_OUT_OF_BUFFER;
|
|
goto _OVER;
|
|
}
|
|
|
|
nBytes = snprintf(realfile, sizeof(realfile), "%s%s%s.json", path, TD_DIRSEP, name);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
code = TSDB_CODE_OUT_OF_BUFFER;
|
|
goto _OVER;
|
|
}
|
|
|
|
pJson = tjsonCreateObject();
|
|
if (pJson == NULL) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
if ((code = xmEncodeFile(pJson, deployed, proto)) != 0) goto _OVER;
|
|
|
|
buffer = tjsonToString(pJson);
|
|
if (buffer == NULL) {
|
|
code = TSDB_CODE_INVALID_JSON_FORMAT;
|
|
goto _OVER;
|
|
}
|
|
|
|
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
|
if (pFile == NULL) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
int32_t len = strlen(buffer);
|
|
if (taosWriteFile(pFile, buffer, len) <= 0) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
if (taosFsyncFile(pFile) < 0) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosCloseFile(&pFile) != 0) {
|
|
code = TAOS_SYSTEM_ERROR(ERRNO);
|
|
goto _OVER;
|
|
}
|
|
TAOS_CHECK_GOTO(taosRenameFile(file, realfile), NULL, _OVER);
|
|
|
|
dInfo("succeed to write file:%s, deloyed:%d", realfile, deployed);
|
|
|
|
_OVER:
|
|
if (pJson != NULL) tjsonDelete(pJson);
|
|
if (buffer != NULL) taosMemoryFree(buffer);
|
|
if (pFile != NULL) taosCloseFile(&pFile);
|
|
|
|
if (code != 0) {
|
|
dError("failed to write file:%s since %s, deloyed:%d", realfile, tstrerror(code), deployed);
|
|
}
|
|
return code;
|
|
}
|
|
|
|
int32_t xmProcessCreateReq(const SMgmtInputOpt *pInput, SRpcMsg *pMsg) {
|
|
int32_t code = 0;
|
|
SDCreateXnodeReq createReq = {0};
|
|
if (tDeserializeSMCreateXnodeReq(pMsg->pCont, pMsg->contLen, &createReq) != 0) {
|
|
code = TSDB_CODE_INVALID_MSG;
|
|
return code;
|
|
}
|
|
|
|
bool deployed = true;
|
|
if ((code = xmWriteFile(pInput->path, pInput->name, deployed, 1)) != 0) {
|
|
dError("failed to write xnode file since %s", tstrerror(code));
|
|
|
|
tFreeSMCreateXnodeReq(&createReq);
|
|
return code;
|
|
}
|
|
|
|
tFreeSMCreateXnodeReq(&createReq);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t xmProcessDropReq(const SMgmtInputOpt *pInput, SRpcMsg *pMsg) {
|
|
int32_t code = 0;
|
|
SDDropXnodeReq dropReq = {0};
|
|
if (tDeserializeSMDropXnodeReq(pMsg->pCont, pMsg->contLen, &dropReq) != 0) {
|
|
code = TSDB_CODE_INVALID_MSG;
|
|
|
|
return code;
|
|
}
|
|
|
|
// if (pInput->pData->dnodeId != 0 && dropReq.dnodeId != pInput->pData->dnodeId) {
|
|
// code = TSDB_CODE_INVALID_OPTION;
|
|
// dError("failed to drop bnode since %s", tstrerror(code));
|
|
|
|
// tFreeSMDropBnodeReq(&dropReq);
|
|
// return code;
|
|
// }
|
|
|
|
bool deployed = false;
|
|
if ((code = dmWriteFile(pInput->path, pInput->name, deployed)) != 0) {
|
|
dError("failed to write bnode file since %s", tstrerror(code));
|
|
|
|
tFreeSMDropXnodeReq(&dropReq);
|
|
return code;
|
|
}
|
|
|
|
tFreeSMDropXnodeReq(&dropReq);
|
|
|
|
return 0;
|
|
}
|
|
|
|
SArray *xmGetMsgHandles() {
|
|
int32_t code = -1;
|
|
SArray *pArray = taosArrayInit(4, sizeof(SMgmtHandle));
|
|
if (pArray == NULL) goto _OVER;
|
|
|
|
code = 0;
|
|
_OVER:
|
|
if (code != 0) {
|
|
taosArrayDestroy(pArray);
|
|
return NULL;
|
|
} else {
|
|
return pArray;
|
|
}
|
|
}
|
|
|
|
SMgmtFunc xmGetMgmtFunc() {
|
|
SMgmtFunc mgmtFunc = {0};
|
|
mgmtFunc.openFp = xmOpen;
|
|
mgmtFunc.closeFp = (NodeCloseFp)xmClose;
|
|
mgmtFunc.createFp = (NodeCreateFp)xmProcessCreateReq;
|
|
mgmtFunc.dropFp = (NodeDropFp)xmProcessDropReq;
|
|
mgmtFunc.requiredFp = xmRequire;
|
|
mgmtFunc.getHandlesFp = xmGetMsgHandles;
|
|
|
|
return mgmtFunc;
|
|
}
|