add daemon lib
This commit is contained in:
parent
2f1bb2815f
commit
fa0d64f14b
|
@ -672,16 +672,16 @@ typedef struct {
|
||||||
} SDnodeCfg;
|
} SDnodeCfg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t dnodeId;
|
int32_t id;
|
||||||
int8_t isMnode;
|
int8_t isMnode;
|
||||||
int8_t reserved;
|
int8_t reserved;
|
||||||
uint16_t dnodePort;
|
uint16_t port;
|
||||||
char dnodeFqdn[TSDB_FQDN_LEN];
|
char fqdn[TSDB_FQDN_LEN];
|
||||||
} SDnodeEp;
|
} SDnodeEp;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t dnodeNum;
|
int32_t num;
|
||||||
SDnodeEp dnodeEps[];
|
SDnodeEp eps[];
|
||||||
} SDnodeEps;
|
} SDnodeEps;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -820,9 +820,9 @@ typedef struct {
|
||||||
} SCreateDnodeMsg, SDropDnodeMsg;
|
} SCreateDnodeMsg, SDropDnodeMsg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t dnodeId;
|
int32_t dnodeId;
|
||||||
int8_t replica;
|
int8_t replica;
|
||||||
int8_t reserved[3];
|
int8_t reserved[3];
|
||||||
SReplica replicas[TSDB_MAX_REPLICA];
|
SReplica replicas[TSDB_MAX_REPLICA];
|
||||||
} SCreateMnodeMsg, SAlterMnodeMsg, SDropMnodeMsg;
|
} SCreateMnodeMsg, SAlterMnodeMsg, SDropMnodeMsg;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#ifndef _TD_DNODE_H_
|
#ifndef _TD_DNODE_H_
|
||||||
#define _TD_DNODE_H_
|
#define _TD_DNODE_H_
|
||||||
|
|
||||||
|
#include "tdef.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,6 +25,24 @@ extern "C" {
|
||||||
/* ------------------------ TYPES EXPOSED ------------------------ */
|
/* ------------------------ TYPES EXPOSED ------------------------ */
|
||||||
typedef struct SDnode SDnode;
|
typedef struct SDnode SDnode;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t sver;
|
||||||
|
int32_t numOfCores;
|
||||||
|
float numOfThreadsPerCore;
|
||||||
|
float ratioOfQueryCores;
|
||||||
|
int32_t maxShellConns;
|
||||||
|
int32_t shellActivityTimer;
|
||||||
|
int32_t statusInterval;
|
||||||
|
uint16_t serverPort;
|
||||||
|
char dataDir[PATH_MAX];
|
||||||
|
char localEp[TSDB_EP_LEN];
|
||||||
|
char localFqdn[TSDB_FQDN_LEN];
|
||||||
|
char firstEp[TSDB_EP_LEN];
|
||||||
|
char timezone[TSDB_TIMEZONE_LEN];
|
||||||
|
char locale[TSDB_LOCALE_LEN];
|
||||||
|
char charset[TSDB_LOCALE_LEN];
|
||||||
|
} SDnodeOpt;
|
||||||
|
|
||||||
/* ------------------------ SDnode ------------------------ */
|
/* ------------------------ SDnode ------------------------ */
|
||||||
/**
|
/**
|
||||||
* @brief Initialize and start the dnode.
|
* @brief Initialize and start the dnode.
|
||||||
|
@ -30,14 +50,14 @@ typedef struct SDnode SDnode;
|
||||||
* @param cfgPath Config file path.
|
* @param cfgPath Config file path.
|
||||||
* @return SDnode* The dnode object.
|
* @return SDnode* The dnode object.
|
||||||
*/
|
*/
|
||||||
SDnode *dnodeInit(const char *cfgPath);
|
SDnode *dndInit(SDnodeOpt *pOptions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Stop and cleanup dnode.
|
* @brief Stop and cleanup dnode.
|
||||||
*
|
*
|
||||||
* @param pDnode The dnode object to close.
|
* @param pDnd The dnode object to close.
|
||||||
*/
|
*/
|
||||||
void dnodeCleanup(SDnode *pDnode);
|
void dndCleanup(SDnode *pDnd);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,10 @@ extern "C" {
|
||||||
typedef struct SDnode SDnode;
|
typedef struct SDnode SDnode;
|
||||||
typedef struct SMnode SMnode;
|
typedef struct SMnode SMnode;
|
||||||
typedef struct SMnodeMsg SMnodeMsg;
|
typedef struct SMnodeMsg SMnodeMsg;
|
||||||
typedef void (*SendMsgToDnodeFp)(SDnode *pDnode, struct SEpSet *epSet, struct SRpcMsg *rpcMsg);
|
typedef void (*SendMsgToDnodeFp)(SDnode *pDnd, struct SEpSet *epSet, struct SRpcMsg *rpcMsg);
|
||||||
typedef void (*SendMsgToMnodeFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg);
|
typedef void (*SendMsgToMnodeFp)(SDnode *pDnd, struct SRpcMsg *rpcMsg);
|
||||||
typedef void (*SendRedirectMsgFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg, bool forShell);
|
typedef void (*SendRedirectMsgFp)(SDnode *pDnd, struct SRpcMsg *rpcMsg, bool forShell);
|
||||||
typedef int32_t (*PutMsgToMnodeQFp)(SDnode *pDnode, SMnodeMsg *pMsg);
|
typedef int32_t (*PutMsgToMnodeQFp)(SDnode *pDnd, SMnodeMsg *pMsg);
|
||||||
|
|
||||||
typedef struct SMnodeLoad {
|
typedef struct SMnodeLoad {
|
||||||
int64_t numOfDnode;
|
int64_t numOfDnode;
|
||||||
|
@ -48,7 +48,7 @@ typedef struct {
|
||||||
int8_t replica;
|
int8_t replica;
|
||||||
int8_t selfIndex;
|
int8_t selfIndex;
|
||||||
SReplica replicas[TSDB_MAX_REPLICA];
|
SReplica replicas[TSDB_MAX_REPLICA];
|
||||||
struct SServer *pServer;
|
struct SDnode *pDnode;
|
||||||
PutMsgToMnodeQFp putMsgToApplyMsgFp;
|
PutMsgToMnodeQFp putMsgToApplyMsgFp;
|
||||||
SendMsgToDnodeFp sendMsgToDnodeFp;
|
SendMsgToDnodeFp sendMsgToDnodeFp;
|
||||||
SendMsgToMnodeFp sendMsgToMnodeFp;
|
SendMsgToMnodeFp sendMsgToMnodeFp;
|
||||||
|
@ -122,10 +122,17 @@ SMnodeMsg *mnodeInitMsg(SMnode *pMnode, SRpcMsg *pRpcMsg);
|
||||||
/**
|
/**
|
||||||
* @brief Cleanup mnode msg
|
* @brief Cleanup mnode msg
|
||||||
*
|
*
|
||||||
* @param pMnode The mnode object
|
|
||||||
* @param pMsg The request msg
|
* @param pMsg The request msg
|
||||||
*/
|
*/
|
||||||
void mnodeCleanupMsg(SMnode *pMnode, SMnodeMsg *pMsg);
|
void mnodeCleanupMsg(SMnodeMsg *pMsg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Cleanup mnode msg
|
||||||
|
*
|
||||||
|
* @param pMsg The request msg
|
||||||
|
* @param code The error code
|
||||||
|
*/
|
||||||
|
void mnodeSendRsp(SMnodeMsg *pMsg, int32_t code);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Process the read request
|
* @brief Process the read request
|
||||||
|
|
|
@ -185,10 +185,10 @@ typedef struct {
|
||||||
} SVnodeMsg;
|
} SVnodeMsg;
|
||||||
|
|
||||||
typedef struct SDnode SDnode;
|
typedef struct SDnode SDnode;
|
||||||
typedef void (*SendMsgToDnodeFp)(SDnode *pDnode, struct SEpSet *epSet, struct SRpcMsg *rpcMsg);
|
typedef void (*SendMsgToDnodeFp)(SDnode *pDnd, struct SEpSet *epSet, struct SRpcMsg *rpcMsg);
|
||||||
typedef void (*SendMsgToMnodeFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg);
|
typedef void (*SendMsgToMnodeFp)(SDnode *pDnd, struct SRpcMsg *rpcMsg);
|
||||||
typedef void (*SendRedirectMsgFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg, bool forShell);
|
typedef void (*SendRedirectMsgFp)(SDnode *pDnd, struct SRpcMsg *rpcMsg, bool forShell);
|
||||||
typedef int32_t (*PutMsgToVnodeQFp)(SDnode *pDnode, int32_t vgId, SVnodeMsg *pMsg);
|
typedef int32_t (*PutMsgToVnodeQFp)(SDnode *pDnd, int32_t vgId, SVnodeMsg *pMsg);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PutMsgToVnodeQFp putMsgToApplyQueueFp;
|
PutMsgToVnodeQFp putMsgToApplyQueueFp;
|
||||||
|
|
|
@ -51,7 +51,7 @@ typedef struct SRpcMsg {
|
||||||
} SRpcMsg;
|
} SRpcMsg;
|
||||||
|
|
||||||
typedef struct SRpcInit {
|
typedef struct SRpcInit {
|
||||||
uint16_t localPort; // local port
|
uint16_t localPort; // local port
|
||||||
char *label; // for debug purpose
|
char *label; // for debug purpose
|
||||||
int numOfThreads; // number of threads to handle connections
|
int numOfThreads; // number of threads to handle connections
|
||||||
int sessions; // number of sessions allowed
|
int sessions; // number of sessions allowed
|
||||||
|
@ -66,10 +66,12 @@ typedef struct SRpcInit {
|
||||||
char *ckey; // ciphering key
|
char *ckey; // ciphering key
|
||||||
|
|
||||||
// call back to process incoming msg, code shall be ignored by server app
|
// call back to process incoming msg, code shall be ignored by server app
|
||||||
void (*cfp)(SRpcMsg *, SEpSet *);
|
void (*cfp)(void *parent, SRpcMsg *, SEpSet *);
|
||||||
|
|
||||||
// call back to retrieve the client auth info, for server app only
|
// call back to retrieve the client auth info, for server app only
|
||||||
int (*afp)(char *tableId, char *spi, char *encrypt, char *secret, char *ckey);
|
int (*afp)(void *parent, char *tableId, char *spi, char *encrypt, char *secret, char *ckey);
|
||||||
|
|
||||||
|
void *parent;
|
||||||
} SRpcInit;
|
} SRpcInit;
|
||||||
|
|
||||||
int32_t rpcInit();
|
int32_t rpcInit();
|
||||||
|
|
|
@ -68,12 +68,13 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_FILE_CORRUPTED TAOS_DEF_ERROR_CODE(0, 0x0106)
|
#define TSDB_CODE_FILE_CORRUPTED TAOS_DEF_ERROR_CODE(0, 0x0106)
|
||||||
#define TSDB_CODE_CHECKSUM_ERROR TAOS_DEF_ERROR_CODE(0, 0x0107)
|
#define TSDB_CODE_CHECKSUM_ERROR TAOS_DEF_ERROR_CODE(0, 0x0107)
|
||||||
#define TSDB_CODE_INVALID_MSG TAOS_DEF_ERROR_CODE(0, 0x0108)
|
#define TSDB_CODE_INVALID_MSG TAOS_DEF_ERROR_CODE(0, 0x0108)
|
||||||
#define TSDB_CODE_REF_NO_MEMORY TAOS_DEF_ERROR_CODE(0, 0x0109)
|
#define TSDB_CODE_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0109)
|
||||||
#define TSDB_CODE_REF_FULL TAOS_DEF_ERROR_CODE(0, 0x010A)
|
#define TSDB_CODE_REF_NO_MEMORY TAOS_DEF_ERROR_CODE(0, 0x0110)
|
||||||
#define TSDB_CODE_REF_ID_REMOVED TAOS_DEF_ERROR_CODE(0, 0x010B)
|
#define TSDB_CODE_REF_FULL TAOS_DEF_ERROR_CODE(0, 0x0111)
|
||||||
#define TSDB_CODE_REF_INVALID_ID TAOS_DEF_ERROR_CODE(0, 0x010C)
|
#define TSDB_CODE_REF_ID_REMOVED TAOS_DEF_ERROR_CODE(0, 0x0112)
|
||||||
#define TSDB_CODE_REF_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x010D)
|
#define TSDB_CODE_REF_INVALID_ID TAOS_DEF_ERROR_CODE(0, 0x0113)
|
||||||
#define TSDB_CODE_REF_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x010E)
|
#define TSDB_CODE_REF_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0114)
|
||||||
|
#define TSDB_CODE_REF_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0115)
|
||||||
|
|
||||||
//client
|
//client
|
||||||
#define TSDB_CODE_TSC_INVALID_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0200) //"Invalid Operation")
|
#define TSDB_CODE_TSC_INVALID_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0200) //"Invalid Operation")
|
||||||
|
@ -223,20 +224,20 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_MND_TOPIC_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0395) //"Topic already exists)
|
#define TSDB_CODE_MND_TOPIC_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0395) //"Topic already exists)
|
||||||
|
|
||||||
// dnode
|
// dnode
|
||||||
#define TSDB_CODE_DND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0400) //"Message not processed")
|
#define TSDB_CODE_DND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0400)
|
||||||
#define TSDB_CODE_DND_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x0401) //"Dnode out of memory")
|
#define TSDB_CODE_DND_EXITING TAOS_DEF_ERROR_CODE(0, 0x0401)
|
||||||
#define TSDB_CODE_DND_MNODE_ID_NOT_MATCH_DNODE TAOS_DEF_ERROR_CODE(0, 0x0402) //"Mnode Id not match Dnode")
|
#define TSDB_CODE_DND_INVALID_MSG_LEN TAOS_DEF_ERROR_CODE(0, 0x0402)
|
||||||
#define TSDB_CODE_DND_MNODE_ALREADY_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0403) //"Mnode already deployed")
|
#define TSDB_CODE_DND_DNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0410)
|
||||||
#define TSDB_CODE_DND_MNODE_NOT_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0404) //"Mnode not deployed")
|
#define TSDB_CODE_DND_DNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0411)
|
||||||
#define TSDB_CODE_DND_READ_MNODE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0405) //"Read mnode.json error")
|
#define TSDB_CODE_DND_MNODE_ALREADY_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0420)
|
||||||
#define TSDB_CODE_DND_WRITE_MNODE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0406) //"Write mnode.json error")
|
#define TSDB_CODE_DND_MNODE_NOT_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0421)
|
||||||
#define TSDB_CODE_DND_NO_WRITE_ACCESS TAOS_DEF_ERROR_CODE(0, 0x0407) //"No permission for disk files in dnode")
|
#define TSDB_CODE_DND_MNODE_ID_INVALID TAOS_DEF_ERROR_CODE(0, 0x0422)
|
||||||
#define TSDB_CODE_DND_INVALID_MSG_LEN TAOS_DEF_ERROR_CODE(0, 0x0408) //"Invalid message length")
|
#define TSDB_CODE_DND_MNODE_ID_NOT_FOUND TAOS_DEF_ERROR_CODE(0, 0x0423)
|
||||||
#define TSDB_CODE_DND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0409) //"Action in progress")
|
#define TSDB_CODE_DND_MNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0424)
|
||||||
#define TSDB_CODE_DND_TOO_MANY_VNODES TAOS_DEF_ERROR_CODE(0, 0x040A) //"Too many vnode directories")
|
#define TSDB_CODE_DND_MNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0425)
|
||||||
#define TSDB_CODE_DND_EXITING TAOS_DEF_ERROR_CODE(0, 0x040B) //"Dnode is exiting"
|
#define TSDB_CODE_DND_VNODE_TOO_MANY_VNODES TAOS_DEF_ERROR_CODE(0, 0x0430)
|
||||||
#define TSDB_CODE_DND_PARSE_VNODE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x040C) //"Parse vnodes.json error")
|
#define TSDB_CODE_DND_VNODE_READ_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0431)
|
||||||
#define TSDB_CODE_DND_PARSE_DNODE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x040D) //"Parse dnodes.json error")
|
#define TSDB_CODE_DND_VNODE_WRITE_FILE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0432)
|
||||||
|
|
||||||
// vnode
|
// vnode
|
||||||
#define TSDB_CODE_VND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0500) //"Action in progress")
|
#define TSDB_CODE_VND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0500) //"Action in progress")
|
||||||
|
|
|
@ -16,38 +16,173 @@
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "dnode.h"
|
#include "dnode.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
#include "tglobal.h"
|
||||||
#include "ulog.h"
|
#include "ulog.h"
|
||||||
|
|
||||||
static bool stop = false;
|
static struct {
|
||||||
|
bool stop;
|
||||||
|
bool dumpConfig;
|
||||||
|
bool generateGrant;
|
||||||
|
bool printAuth;
|
||||||
|
bool printVersion;
|
||||||
|
char configDir[PATH_MAX];
|
||||||
|
} global = {0};
|
||||||
|
|
||||||
static void sigintHandler(int32_t signum, void *info, void *ctx) { stop = true; }
|
void dmnSigintHandle(int signum, void *info, void *ctx) { global.stop = true; }
|
||||||
|
|
||||||
static void setSignalHandler() {
|
void dmnSetSignalHandle() {
|
||||||
taosSetSignal(SIGTERM, sigintHandler);
|
taosSetSignal(SIGTERM, dmnSigintHandle);
|
||||||
taosSetSignal(SIGHUP, sigintHandler);
|
taosSetSignal(SIGHUP, dmnSigintHandle);
|
||||||
taosSetSignal(SIGINT, sigintHandler);
|
taosSetSignal(SIGINT, dmnSigintHandle);
|
||||||
taosSetSignal(SIGABRT, sigintHandler);
|
taosSetSignal(SIGABRT, dmnSigintHandle);
|
||||||
taosSetSignal(SIGBREAK, sigintHandler);
|
taosSetSignal(SIGBREAK, dmnSigintHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char const *argv[]) {
|
int dmnParseOpts(int argc, char const *argv[]) {
|
||||||
const char *path = "/etc/taos";
|
tstrncpy(global.configDir, "/etc/taos", PATH_MAX);
|
||||||
|
|
||||||
SDnode *pDnode = dnodeInit(path);
|
for (int i = 1; i < argc; ++i) {
|
||||||
if (pDnode == NULL) {
|
if (strcmp(argv[i], "-c") == 0) {
|
||||||
uInfo("Failed to start TDengine, please check the log at %s", tsLogDir);
|
if (i < argc - 1) {
|
||||||
exit(EXIT_FAILURE);
|
if (strlen(argv[++i]) >= PATH_MAX) {
|
||||||
|
printf("config file path overflow");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tstrncpy(global.configDir, argv[i], PATH_MAX);
|
||||||
|
} else {
|
||||||
|
printf("'-c' requires a parameter, default:%s\n", configDir);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (strcmp(argv[i], "-C") == 0) {
|
||||||
|
global.dumpConfig = true;
|
||||||
|
} else if (strcmp(argv[i], "-k") == 0) {
|
||||||
|
global.generateGrant = true;
|
||||||
|
} else if (strcmp(argv[i], "-A") == 0) {
|
||||||
|
global.printAuth = true;
|
||||||
|
} else if (strcmp(argv[i], "-V") == 0) {
|
||||||
|
global.printVersion = true;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uInfo("Started TDengine service successfully.");
|
|
||||||
|
|
||||||
setSignalHandler();
|
|
||||||
while (!stop) {
|
|
||||||
taosMsleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
uInfo("TDengine is shut down!");
|
|
||||||
dnodeCleanup(pDnode);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dmnGenerateGrant() { grantParseParameter(); }
|
||||||
|
|
||||||
|
void dmnPrintVersion() {
|
||||||
|
#ifdef TD_ENTERPRISE
|
||||||
|
char *versionStr = "enterprise";
|
||||||
|
#else
|
||||||
|
char *versionStr = "community";
|
||||||
|
#endif
|
||||||
|
printf("%s version: %s compatible_version: %s\n", versionStr, version, compatible_version);
|
||||||
|
printf("gitinfo: %s\n", gitinfo);
|
||||||
|
printf("gitinfoI: %s\n", gitinfoOfInternal);
|
||||||
|
printf("builuInfo: %s\n", buildinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmnReadConfig(const char *path) {
|
||||||
|
taosIgnSIGPIPE();
|
||||||
|
taosBlockSIGPIPE();
|
||||||
|
taosResolveCRC();
|
||||||
|
taosInitGlobalCfg();
|
||||||
|
taosReadGlobalLogCfg();
|
||||||
|
|
||||||
|
if (taosMkDir(tsLogDir) != 0) {
|
||||||
|
printf("failed to create dir: %s, reason: %s\n", tsLogDir, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char temp[PATH_MAX];
|
||||||
|
snprintf(temp, PATH_MAX, "%s/taosdlog", tsLogDir);
|
||||||
|
if (taosInitLog(temp, tsNumOfLogLines, 1) != 0) {
|
||||||
|
printf("failed to init log file\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taosInitNotes() != 0) {
|
||||||
|
printf("failed to init log file\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taosReadGlobalCfg() != 0) {
|
||||||
|
uError("failed to read global config");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taosCheckGlobalCfg() != 0) {
|
||||||
|
uError("failed to check global config");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosSetCoreDump(tsEnableCoreFile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dmnDumpConfig() { taosDumpGlobalCfg(); }
|
||||||
|
|
||||||
|
void dmnWaitSignal() {
|
||||||
|
dmnSetSignalHandle();
|
||||||
|
while (!global.stop) {
|
||||||
|
taosMsleep(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dmnInitOption(SDnodeOpt *pOpt) {
|
||||||
|
pOpt->sver = tsVersion;
|
||||||
|
pOpt->numOfCores = tsNumOfCores;
|
||||||
|
pOpt->statusInterval = tsStatusInterval;
|
||||||
|
pOpt->serverPort = tsServerPort;
|
||||||
|
tstrncpy(pOpt->localEp, tsLocalEp, TSDB_EP_LEN);
|
||||||
|
tstrncpy(pOpt->localFqdn, tsLocalEp, TSDB_FQDN_LEN);
|
||||||
|
tstrncpy(pOpt->timezone, tsLocalEp, TSDB_TIMEZONE_LEN);
|
||||||
|
tstrncpy(pOpt->locale, tsLocalEp, TSDB_LOCALE_LEN);
|
||||||
|
tstrncpy(pOpt->charset, tsLocalEp, TSDB_LOCALE_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmnRunDnode() {
|
||||||
|
SDnodeOpt opt = {0};
|
||||||
|
dmnInitOption(&opt);
|
||||||
|
|
||||||
|
SDnode *pDnd = dndInit(&opt);
|
||||||
|
if (pDnd == NULL) {
|
||||||
|
uInfo("Failed to start TDengine, please check the log at %s", tsLogDir);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uInfo("Started TDengine service successfully.");
|
||||||
|
dmnWaitSignal();
|
||||||
|
uInfo("TDengine is shut down!");
|
||||||
|
|
||||||
|
dndCleanup(pDnd);
|
||||||
|
taosCloseLog();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char const *argv[]) {
|
||||||
|
if (dmnParseOpts(argc, argv) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global.generateGrant) {
|
||||||
|
dmnGenerateGrant();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global.printVersion) {
|
||||||
|
dmnPrintVersion();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmnReadConfig(global.configDir) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global.dumpConfig) {
|
||||||
|
dmnDumpConfig();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dmnRunDnode();
|
||||||
|
}
|
||||||
|
|
|
@ -13,26 +13,27 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TD_DNODE_VNODES_H_
|
#ifndef _TD_DND_DNODE_H_
|
||||||
#define _TD_DNODE_VNODES_H_
|
#define _TD_DND_DNODE_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#include "dnodeInt.h"
|
#include "dndInt.h"
|
||||||
|
|
||||||
int32_t dnodeInitVnodes();
|
int32_t dndInitDnode(SDnode *pDnd);
|
||||||
void dnodeCleanupVnodes();
|
void dndCleanupDnode(SDnode *pDnd);
|
||||||
void dnodeGetVnodeLoads(SVnodeLoads *pVloads);
|
void dndProcessDnodeReq(SDnode *pDnd, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
|
void dndProcessDnodeRsp(SDnode *pDnd, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
|
|
||||||
void dnodeProcessVnodeMgmtMsg(SRpcMsg *pMsg, SEpSet *pEpSet);
|
int32_t dndGetDnodeId(SDnode *pDnd);
|
||||||
void dnodeProcessVnodeWriteMsg(SRpcMsg *pMsg, SEpSet *pEpSet);
|
int64_t dndGetClusterId(SDnode *pDnd);
|
||||||
void dnodeProcessVnodeSyncMsg(SRpcMsg *pMsg, SEpSet *pEpSet);
|
void dndGetDnodeEp(SDnode *pDnd, int32_t dnodeId, char *pEp, char *pFqdn, uint16_t *pPort);
|
||||||
void dnodeProcessVnodeQueryMsg(SRpcMsg *pMsg, SEpSet *pEpSet);
|
void dndGetMnodeEpSet(SDnode *pDnd, SEpSet *pEpSet);
|
||||||
void dnodeProcessVnodeFetchMsg(SRpcMsg *pMsg, SEpSet *pEpSet);
|
void dndSendRedirectMsg(SDnode *pDnd, SRpcMsg *pMsg, bool forShell);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /*_TD_DNODE_VNODES_H_*/
|
#endif /*_TD_DND_DNODE_H_*/
|
|
@ -13,20 +13,27 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TD_DNODE_INT_H_
|
#ifndef _TD_DND_INT_H_
|
||||||
#define _TD_DNODE_INT_H_
|
#define _TD_DND_INT_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "cJSON.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tglobal.h"
|
|
||||||
#include "thash.h"
|
#include "thash.h"
|
||||||
|
#include "tlockfree.h"
|
||||||
#include "tlog.h"
|
#include "tlog.h"
|
||||||
|
#include "tqueue.h"
|
||||||
#include "trpc.h"
|
#include "trpc.h"
|
||||||
#include "tthread.h"
|
#include "tthread.h"
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
|
#include "tworker.h"
|
||||||
|
#include "mnode.h"
|
||||||
|
#include "vnode.h"
|
||||||
|
#include "dnode.h"
|
||||||
|
|
||||||
extern int32_t dDebugFlag;
|
extern int32_t dDebugFlag;
|
||||||
|
|
||||||
|
@ -37,8 +44,8 @@ extern int32_t dDebugFlag;
|
||||||
#define dDebug(...) { if (dDebugFlag & DEBUG_DEBUG) { taosPrintLog("SRV ", dDebugFlag, __VA_ARGS__); }}
|
#define dDebug(...) { if (dDebugFlag & DEBUG_DEBUG) { taosPrintLog("SRV ", dDebugFlag, __VA_ARGS__); }}
|
||||||
#define dTrace(...) { if (dDebugFlag & DEBUG_TRACE) { taosPrintLog("SRV ", dDebugFlag, __VA_ARGS__); }}
|
#define dTrace(...) { if (dDebugFlag & DEBUG_TRACE) { taosPrintLog("SRV ", dDebugFlag, __VA_ARGS__); }}
|
||||||
|
|
||||||
typedef enum { DN_STAT_INIT, DN_STAT_RUNNING, DN_STAT_STOPPED } EStat;
|
typedef enum { DND_STAT_INIT, DND_STAT_RUNNING, DND_STAT_STOPPED } EStat;
|
||||||
typedef void (*MsgFp)(SRpcMsg *pMsg, SEpSet *pEpSet);
|
typedef void (*DndMsgFp)(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEps);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *dnode;
|
char *dnode;
|
||||||
|
@ -48,50 +55,75 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t dnodeId;
|
int32_t dnodeId;
|
||||||
int64_t clusterId;
|
|
||||||
SDnodeEps *dnodeEps;
|
|
||||||
SHashObj *dnodeHash;
|
|
||||||
SEpSet mnodeEpSetForShell;
|
|
||||||
SEpSet mnodeEpSetForPeer;
|
|
||||||
char *file;
|
|
||||||
uint32_t rebootTime;
|
uint32_t rebootTime;
|
||||||
int8_t dropped;
|
int32_t dropped;
|
||||||
int8_t threadStop;
|
int64_t clusterId;
|
||||||
|
SEpSet shellEpSet;
|
||||||
|
SEpSet peerEpSet;
|
||||||
|
char *file;
|
||||||
|
SHashObj *dnodeHash;
|
||||||
|
SDnodeEps *dnodeEps;
|
||||||
pthread_t *threadId;
|
pthread_t *threadId;
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
} SDnodeDnode;
|
} SDnodeMgmt;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
} SDnodeMnode;
|
int32_t refCount;
|
||||||
|
int8_t deployed;
|
||||||
|
int8_t dropped;
|
||||||
|
SWorkerPool mgmtPool;
|
||||||
|
SWorkerPool readPool;
|
||||||
|
SWorkerPool writePool;
|
||||||
|
SWorkerPool syncPool;
|
||||||
|
taos_queue pReadQ;
|
||||||
|
taos_queue pWriteQ;
|
||||||
|
taos_queue pApplyQ;
|
||||||
|
taos_queue pSyncQ;
|
||||||
|
taos_queue pMgmtQ;
|
||||||
|
char *file;
|
||||||
|
SMnode *pMnode;
|
||||||
|
SRWLatch latch;
|
||||||
|
} SMnodeMgmt;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
} SDnodeVnodes;
|
SHashObj *hash;
|
||||||
|
SWorkerPool mgmtPool;
|
||||||
|
SWorkerPool queryPool;
|
||||||
|
SWorkerPool fetchPool;
|
||||||
|
SMWorkerPool syncPool;
|
||||||
|
SMWorkerPool writePool;
|
||||||
|
taos_queue pMgmtQ;
|
||||||
|
int32_t openVnodes;
|
||||||
|
int32_t totalVnodes;
|
||||||
|
SRWLatch latch;
|
||||||
|
} SVnodesMgmt;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *peerRpc;
|
void *serverRpc;
|
||||||
void *shellRpc;
|
void *clientRpc;
|
||||||
void *clientRpc;
|
DndMsgFp msgFp[TSDB_MSG_TYPE_MAX];
|
||||||
} SDnodeTrans;
|
} STransMgmt;
|
||||||
|
|
||||||
typedef struct SDnode {
|
typedef struct SDnode {
|
||||||
EStat stat;
|
EStat stat;
|
||||||
SDnodeDir dir;
|
SDnodeOpt opt;
|
||||||
SDnodeDnode dnode;
|
SDnodeDir dir;
|
||||||
SDnodeVnodes vnodes;
|
SDnodeMgmt d;
|
||||||
SDnodeMnode mnode;
|
SMnodeMgmt m;
|
||||||
SDnodeTrans trans;
|
SVnodesMgmt vmgmt;
|
||||||
SStartupMsg startup;
|
STransMgmt t;
|
||||||
|
SStartupMsg startup;
|
||||||
} SDnode;
|
} SDnode;
|
||||||
|
|
||||||
EStat dnodeGetStat(SDnode *pDnode);
|
EStat dndGetStat(SDnode *pDnode);
|
||||||
void dnodeSetStat(SDnode *pDnode, EStat stat);
|
void dndSetStat(SDnode *pDnode, EStat stat);
|
||||||
char *dnodeStatStr(EStat stat);
|
char *dndStatStr(EStat stat);
|
||||||
|
|
||||||
void dnodeReportStartup(SDnode *pDnode, char *name, char *desc);
|
void dndReportStartup(SDnode *pDnode, char *name, char *desc);
|
||||||
void dnodeGetStartup(SDnode *pDnode, SStartupMsg *pStartup);
|
void dndGetStartup(SDnode *pDnode, SStartupMsg *pStartup);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /*_TD_DNODE_INT_H_*/
|
#endif /*_TD_DND_INT_H_*/
|
|
@ -13,27 +13,24 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TD_DNODE_DNODE_H_
|
#ifndef _TD_DND_MNODE_H_
|
||||||
#define _TD_DNODE_DNODE_H_
|
#define _TD_DND_MNODE_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#include "dnodeInt.h"
|
#include "dndInt.h"
|
||||||
|
|
||||||
int32_t dnodeInitDnode(SDnode *pDnode);
|
int32_t dndInitMnode(SDnode *pDnode);
|
||||||
void dnodeCleanupDnode(SDnode *pDnode);
|
void dndCleanupMnode(SDnode *pDnode);
|
||||||
void dnodeProcessDnodeMsg(SRpcMsg *pMsg, SEpSet *pEpSet);
|
int32_t dndGetUserAuthFromMnode(SDnode *pDnode, char *user, char *spi, char *encrypt, char *secret, char *ckey);
|
||||||
|
void dndProcessMnodeMgmtMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
int32_t dnodeGetDnodeId();
|
void dndProcessMnodeReadMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
int64_t dnodeGetClusterId();
|
void dndProcessMnodeWriteMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
void dnodeGetDnodeEp(int32_t dnodeId, char *epstr, char *fqdn, uint16_t *port);
|
void dndProcessMnodeSyncMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
void dnodeGetMnodeEpSetForPeer(SEpSet *epSet);
|
|
||||||
void dnodeGetMnodeEpSetForShell(SEpSet *epSet);
|
|
||||||
void dnodeSendRedirectMsg(SDnode *pDnode, SRpcMsg *rpcMsg, bool forShell);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /*_TD_DNODE_DNODE_H_*/
|
#endif /*_TD_DND_MNODE_H_*/
|
|
@ -13,21 +13,21 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TD_DNODE_TRANSPORT_H_
|
#ifndef _TD_DND_TRANSPORT_H_
|
||||||
#define _TD_DNODE_TRANSPORT_H_
|
#define _TD_DND_TRANSPORT_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#include "dnodeInt.h"
|
#include "dndInt.h"
|
||||||
|
|
||||||
int32_t dnodeInitTrans();
|
int32_t dndInitTrans(SDnode *pDnode);
|
||||||
void dnodeCleanupTrans();
|
void dndCleanupTrans(SDnode *pDnode);
|
||||||
void dnodeSendMsgToMnode(SDnode *pDnode, SRpcMsg *rpcMsg);
|
void dndSendMsgToMnode(SDnode *pDnode, SRpcMsg *pRpcMsg);
|
||||||
void dnodeSendMsgToDnode(SDnode *pDnode, SEpSet *epSet, SRpcMsg *rpcMsg);
|
void dndSendMsgToDnode(SDnode *pDnode, SEpSet *pEpSet, SRpcMsg *pRpcMsg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /*_TD_DNODE_TRANSPORT_H_*/
|
#endif /*_TD_DND_TRANSPORT_H_*/
|
|
@ -13,25 +13,25 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TD_DNODE_MNODE_H_
|
#ifndef _TD_DND_VNODES_H_
|
||||||
#define _TD_DNODE_MNODE_H_
|
#define _TD_DND_VNODES_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#include "dnodeInt.h"
|
#include "dndInt.h"
|
||||||
|
|
||||||
int32_t dnodeInitMnode();
|
int32_t dndInitVnodes(SDnode *pDnode);
|
||||||
void dnodeCleanupMnode();
|
void dndCleanupVnodes(SDnode *pDnode);
|
||||||
int32_t dnodeGetUserAuthFromMnode(char *user, char *spi, char *encrypt, char *secret, char *ckey);
|
void dndGetVnodeLoads(SDnode *pDnode, SVnodeLoads *pVloads);
|
||||||
|
void dndProcessVnodeMgmtMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
void dnodeProcessMnodeMgmtMsg(SRpcMsg *pMsg, SEpSet *pEpSet);
|
void dndProcessVnodeWriteMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
void dnodeProcessMnodeReadMsg(SRpcMsg *pMsg, SEpSet *pEpSet);
|
void dndProcessVnodeSyncMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
void dnodeProcessMnodeWriteMsg(SRpcMsg *pMsg, SEpSet *pEpSet);
|
void dndProcessVnodeQueryMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
void dnodeProcessMnodeSyncMsg(SRpcMsg *pMsg, SEpSet *pEpSet);
|
void dndProcessVnodeFetchMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /*_TD_DNODE_MNODE_H_*/
|
#endif /*_TD_DND_VNODES_H_*/
|
|
@ -14,69 +14,76 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "dnodeDnode.h"
|
#include "dndDnode.h"
|
||||||
#include "dnodeTransport.h"
|
#include "dndTransport.h"
|
||||||
#include "dnodeVnodes.h"
|
#include "dndVnodes.h"
|
||||||
#include "cJSON.h"
|
|
||||||
|
|
||||||
int32_t dnodeGetDnodeId() {
|
static inline void dndLockDnode(SDnode *pDnd) { pthread_mutex_lock(&pDnd->d.mutex); }
|
||||||
int32_t dnodeId = 0;
|
|
||||||
pthread_mutex_lock(&pDnode->mutex);
|
static inline void dndUnLockDnode(SDnode *pDnd) { pthread_mutex_unlock(&pDnd->d.mutex); }
|
||||||
dnodeId = pDnode->dnodeId;
|
|
||||||
pthread_mutex_unlock(&pDnode->mutex);
|
int32_t dndGetDnodeId(SDnode *pDnd) {
|
||||||
|
dndLockDnode(pDnd);
|
||||||
|
int32_t dnodeId = pDnd->d.dnodeId;
|
||||||
|
dndUnLockDnode(pDnd);
|
||||||
return dnodeId;
|
return dnodeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t dnodeGetClusterId() {
|
int64_t dndGetClusterId(SDnode *pDnd) {
|
||||||
int64_t clusterId = 0;
|
dndLockDnode(pDnd);
|
||||||
pthread_mutex_lock(&pDnode->mutex);
|
int64_t clusterId = pDnd->d.clusterId;
|
||||||
clusterId = pDnode->clusterId;
|
dndUnLockDnode(pDnd);
|
||||||
pthread_mutex_unlock(&pDnode->mutex);
|
|
||||||
return clusterId;
|
return clusterId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeGetDnodeEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port) {
|
void dndGetDnodeEp(SDnode *pDnd, int32_t dnodeId, char *pEp, char *pFqdn, uint16_t *pPort) {
|
||||||
pthread_mutex_lock(&pDnode->mutex);
|
dndLockDnode(pDnd);
|
||||||
|
|
||||||
SDnodeEp *pEp = taosHashGet(pDnode->dnodeHash, &dnodeId, sizeof(int32_t));
|
SDnodeEp *pDnodeEp = taosHashGet(pDnd->d.dnodeHash, &dnodeId, sizeof(int32_t));
|
||||||
if (pEp != NULL) {
|
if (pDnodeEp != NULL) {
|
||||||
if (port) *port = pEp->dnodePort;
|
if (pPort != NULL) {
|
||||||
if (fqdn) tstrncpy(fqdn, pEp->dnodeFqdn, TSDB_FQDN_LEN);
|
*pPort = pDnodeEp->port;
|
||||||
if (ep) snprintf(ep, TSDB_EP_LEN, "%s:%u", pEp->dnodeFqdn, pEp->dnodePort);
|
}
|
||||||
|
if (pFqdn != NULL) {
|
||||||
|
tstrncpy(pFqdn, pDnodeEp->fqdn, TSDB_FQDN_LEN);
|
||||||
|
}
|
||||||
|
if (pEp != NULL) {
|
||||||
|
snprintf(pEp, TSDB_EP_LEN, "%s:%u", pDnodeEp->fqdn, pDnodeEp->port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&pDnode->mutex);
|
dndUnLockDnode(pDnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeGetMnodeEpSetForPeer(SEpSet *pEpSet) {
|
void dndGetMnodeEpSet(SDnode *pDnd, SEpSet *pEpSet) {
|
||||||
pthread_mutex_lock(&pDnode->mutex);
|
dndLockDnode(pDnd);
|
||||||
*pEpSet = pDnode->mnodeEpSetForPeer;
|
*pEpSet = pDnd->d.peerEpSet;
|
||||||
pthread_mutex_unlock(&pDnode->mutex);
|
dndUnLockDnode(pDnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeGetMnodeEpSetForShell(SEpSet *pEpSet) {
|
void dndGetShellEpSet(SDnode *pDnd, SEpSet *pEpSet) {
|
||||||
pthread_mutex_lock(&pDnode->mutex);
|
dndLockDnode(pDnd);
|
||||||
*pEpSet = pDnode->mnodeEpSetForShell;
|
*pEpSet = pDnd->d.shellEpSet;
|
||||||
pthread_mutex_unlock(&pDnode->mutex);
|
dndUnLockDnode(pDnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeSendRedirectMsg(SDnode *pDnode, SRpcMsg *pMsg, bool forShell) {
|
void dndSendRedirectMsg(SDnode *pDnd, SRpcMsg *pMsg, bool forShell) {
|
||||||
int32_t msgType = pMsg->msgType;
|
int32_t msgType = pMsg->msgType;
|
||||||
|
|
||||||
SEpSet epSet = {0};
|
SEpSet epSet = {0};
|
||||||
if (forShell) {
|
if (forShell) {
|
||||||
dnodeGetMnodeEpSetForShell(&epSet);
|
dndGetShellEpSet(pDnd, &epSet);
|
||||||
} else {
|
} else {
|
||||||
dnodeGetMnodeEpSetForPeer(&epSet);
|
dndGetMnodeEpSet(pDnd, &epSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
dDebug("RPC %p, msg:%s is redirected, num:%d use:%d", pMsg->handle, taosMsg[msgType], epSet.numOfEps, epSet.inUse);
|
dDebug("RPC %p, msg:%s is redirected, num:%d use:%d", pMsg->handle, taosMsg[msgType], epSet.numOfEps, epSet.inUse);
|
||||||
|
|
||||||
for (int32_t i = 0; i < epSet.numOfEps; ++i) {
|
for (int32_t i = 0; i < epSet.numOfEps; ++i) {
|
||||||
dDebug("mnode index:%d %s:%u", i, epSet.fqdn[i], epSet.port[i]);
|
dDebug("mnode index:%d %s:%u", i, epSet.fqdn[i], epSet.port[i]);
|
||||||
if (strcmp(epSet.fqdn[i], tsLocalFqdn) == 0) {
|
if (strcmp(epSet.fqdn[i], pDnd->opt.localFqdn) == 0) {
|
||||||
if ((epSet.port[i] == tsServerPort + TSDB_PORT_DNODEDNODE && !forShell) ||
|
if ((epSet.port[i] == pDnd->opt.serverPort + TSDB_PORT_DNODEDNODE && !forShell) ||
|
||||||
(epSet.port[i] == tsServerPort && forShell)) {
|
(epSet.port[i] == pDnd->opt.serverPort && forShell)) {
|
||||||
epSet.inUse = (i + 1) % epSet.numOfEps;
|
epSet.inUse = (i + 1) % epSet.numOfEps;
|
||||||
dDebug("mnode index:%d %s:%d set inUse to %d", i, epSet.fqdn[i], epSet.port[i], epSet.inUse);
|
dDebug("mnode index:%d %s:%d set inUse to %d", i, epSet.fqdn[i], epSet.port[i], epSet.inUse);
|
||||||
}
|
}
|
||||||
|
@ -88,39 +95,37 @@ void dnodeSendRedirectMsg(SDnode *pDnode, SRpcMsg *pMsg, bool forShell) {
|
||||||
rpcSendRedirectRsp(pMsg->handle, &epSet);
|
rpcSendRedirectRsp(pMsg->handle, &epSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodeUpdateMnodeEpSet(SDnodeDnode *pDnode, SEpSet *pEpSet) {
|
static void dndUpdateMnodeEpSet(SDnode *pDnd, SEpSet *pEpSet) {
|
||||||
if (pEpSet == NULL || pEpSet->numOfEps <= 0) {
|
dInfo("mnode is changed, num:%d use:%d", pEpSet->numOfEps, pEpSet->inUse);
|
||||||
dError("mnode is changed, but content is invalid, discard it");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
dInfo("mnode is changed, num:%d use:%d", pEpSet->numOfEps, pEpSet->inUse);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_lock(&pDnode->mutex);
|
dndLockDnode(pDnd);
|
||||||
|
|
||||||
pDnode->mnodeEpSetForPeer = *pEpSet;
|
pDnd->d.peerEpSet = *pEpSet;
|
||||||
for (int32_t i = 0; i < pEpSet->numOfEps; ++i) {
|
for (int32_t i = 0; i < pEpSet->numOfEps; ++i) {
|
||||||
pEpSet->port[i] -= TSDB_PORT_DNODEDNODE;
|
pEpSet->port[i] -= TSDB_PORT_DNODEDNODE;
|
||||||
dInfo("mnode index:%d %s:%u", i, pEpSet->fqdn[i], pEpSet->port[i]);
|
dInfo("mnode index:%d %s:%u", i, pEpSet->fqdn[i], pEpSet->port[i]);
|
||||||
}
|
}
|
||||||
pDnode->mnodeEpSetForShell = *pEpSet;
|
pDnd->d.shellEpSet = *pEpSet;
|
||||||
|
|
||||||
pthread_mutex_unlock(&pDnode->mutex);
|
dndUnLockDnode(pDnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodePrintDnodes() {
|
static void dndPrintDnodes(SDnode *pDnd) {
|
||||||
dDebug("print dnode endpoint list, num:%d", pDnode->dnodeEps->dnodeNum);
|
SDnodeMgmt *pDnode = &pDnd->d;
|
||||||
for (int32_t i = 0; i < pDnode->dnodeEps->dnodeNum; i++) {
|
|
||||||
SDnodeEp *ep = &pDnode->dnodeEps->dnodeEps[i];
|
dDebug("print dnode endpoint list, num:%d", pDnode->dnodeEps->num);
|
||||||
dDebug("dnode:%d, fqdn:%s port:%u isMnode:%d", ep->dnodeId, ep->dnodeFqdn, ep->dnodePort, ep->isMnode);
|
for (int32_t i = 0; i < pDnode->dnodeEps->num; i++) {
|
||||||
|
SDnodeEp *pEp = &pDnode->dnodeEps->eps[i];
|
||||||
|
dDebug("dnode:%d, fqdn:%s port:%u isMnode:%d", pEp->id, pEp->fqdn, pEp->port, pEp->isMnode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodeResetDnodes(SDnodeEps *pEps) {
|
static void dndResetDnodes(SDnode *pDnd, SDnodeEps *pDnodeEps) {
|
||||||
assert(pEps != NULL);
|
SDnodeMgmt *pDnode = &pDnd->d;
|
||||||
int32_t size = sizeof(SDnodeEps) + pEps->dnodeNum * sizeof(SDnodeEp);
|
|
||||||
|
|
||||||
if (pEps->dnodeNum > pDnode->dnodeEps->dnodeNum) {
|
int32_t size = sizeof(SDnodeEps) + pDnodeEps->num * sizeof(SDnodeEp);
|
||||||
|
|
||||||
|
if (pDnodeEps->num > pDnode->dnodeEps->num) {
|
||||||
SDnodeEps *tmp = calloc(1, size);
|
SDnodeEps *tmp = calloc(1, size);
|
||||||
if (tmp == NULL) return;
|
if (tmp == NULL) return;
|
||||||
|
|
||||||
|
@ -128,49 +133,51 @@ static void dnodeResetDnodes(SDnodeEps *pEps) {
|
||||||
pDnode->dnodeEps = tmp;
|
pDnode->dnodeEps = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDnode->dnodeEps != pEps) {
|
if (pDnode->dnodeEps != pDnodeEps) {
|
||||||
memcpy(pDnode->dnodeEps, pEps, size);
|
memcpy(pDnode->dnodeEps, pDnodeEps, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pDnode->mnodeEpSetForPeer.inUse = 0;
|
pDnode->peerEpSet.inUse = 0;
|
||||||
pDnode->mnodeEpSetForShell.inUse = 0;
|
pDnode->shellEpSet.inUse = 0;
|
||||||
|
|
||||||
int32_t mIndex = 0;
|
int32_t mIndex = 0;
|
||||||
for (int32_t i = 0; i < pDnode->dnodeEps->dnodeNum; i++) {
|
for (int32_t i = 0; i < pDnode->dnodeEps->num; i++) {
|
||||||
SDnodeEp *ep = &pDnode->dnodeEps->dnodeEps[i];
|
SDnodeEp *pDnodeEp = &pDnode->dnodeEps->eps[i];
|
||||||
if (!ep->isMnode) continue;
|
if (!pDnodeEp->isMnode) continue;
|
||||||
if (mIndex >= TSDB_MAX_REPLICA) continue;
|
if (mIndex >= TSDB_MAX_REPLICA) continue;
|
||||||
strcpy(pDnode->mnodeEpSetForShell.fqdn[mIndex], ep->dnodeFqdn);
|
strcpy(pDnode->shellEpSet.fqdn[mIndex], pDnodeEp->fqdn);
|
||||||
strcpy(pDnode->mnodeEpSetForPeer.fqdn[mIndex], ep->dnodeFqdn);
|
strcpy(pDnode->peerEpSet.fqdn[mIndex], pDnodeEp->fqdn);
|
||||||
pDnode->mnodeEpSetForShell.port[mIndex] = ep->dnodePort;
|
pDnode->shellEpSet.port[mIndex] = pDnodeEp->port;
|
||||||
pDnode->mnodeEpSetForShell.port[mIndex] = ep->dnodePort + tsDnodeDnodePort;
|
pDnode->shellEpSet.port[mIndex] = pDnodeEp->port + TSDB_PORT_DNODEDNODE;
|
||||||
mIndex++;
|
mIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < pDnode->dnodeEps->dnodeNum; ++i) {
|
for (int32_t i = 0; i < pDnode->dnodeEps->num; ++i) {
|
||||||
SDnodeEp *ep = &pDnode->dnodeEps->dnodeEps[i];
|
SDnodeEp *pDnodeEp = &pDnode->dnodeEps->eps[i];
|
||||||
taosHashPut(pDnode->dnodeHash, &ep->dnodeId, sizeof(int32_t), ep, sizeof(SDnodeEp));
|
taosHashPut(pDnode->dnodeHash, &pDnodeEp->id, sizeof(int32_t), pDnodeEp, sizeof(SDnodeEp));
|
||||||
}
|
}
|
||||||
|
|
||||||
dnodePrintDnodes();
|
dndPrintDnodes(pDnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dnodeIsEpChanged(int32_t dnodeId, char *epStr) {
|
static bool dndIsEpChanged(SDnode *pDnd, int32_t dnodeId) {
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
pthread_mutex_lock(&pDnode->mutex);
|
dndLockDnode(pDnd);
|
||||||
|
|
||||||
SDnodeEp *pEp = taosHashGet(pDnode->dnodeHash, &dnodeId, sizeof(int32_t));
|
SDnodeEp *pDnodeEp = taosHashGet(pDnd->d.dnodeHash, &dnodeId, sizeof(int32_t));
|
||||||
if (pEp != NULL) {
|
if (pDnodeEp != NULL) {
|
||||||
char epSaved[TSDB_EP_LEN + 1];
|
char epstr[TSDB_EP_LEN + 1];
|
||||||
snprintf(epSaved, TSDB_EP_LEN, "%s:%u", pEp->dnodeFqdn, pEp->dnodePort);
|
snprintf(epstr, TSDB_EP_LEN, "%s:%u", pDnodeEp->fqdn, pDnodeEp->port);
|
||||||
changed = strcmp(epStr, epSaved) != 0;
|
changed = strcmp(pDnd->opt.localEp, epstr) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&pDnode->mutex);
|
dndUnLockDnode(pDnd);
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t dnodeReadDnodes() {
|
static int32_t dndReadDnodes(SDnode *pDnd) {
|
||||||
|
SDnodeMgmt *pDnode = &pDnd->d;
|
||||||
|
|
||||||
int32_t len = 0;
|
int32_t len = 0;
|
||||||
int32_t maxLen = 30000;
|
int32_t maxLen = 30000;
|
||||||
char *content = calloc(1, maxLen + 1);
|
char *content = calloc(1, maxLen + 1);
|
||||||
|
@ -234,70 +241,72 @@ static int32_t dnodeReadDnodes() {
|
||||||
dError("failed to calloc dnodeEpList since %s", strerror(errno));
|
dError("failed to calloc dnodeEpList since %s", strerror(errno));
|
||||||
goto PRASE_DNODE_OVER;
|
goto PRASE_DNODE_OVER;
|
||||||
}
|
}
|
||||||
pDnode->dnodeEps->dnodeNum = dnodeInfosSize;
|
pDnode->dnodeEps->num = dnodeInfosSize;
|
||||||
|
|
||||||
for (int32_t i = 0; i < dnodeInfosSize; ++i) {
|
for (int32_t i = 0; i < dnodeInfosSize; ++i) {
|
||||||
cJSON *dnodeInfo = cJSON_GetArrayItem(dnodeInfos, i);
|
cJSON *dnodeInfo = cJSON_GetArrayItem(dnodeInfos, i);
|
||||||
if (dnodeInfo == NULL) break;
|
if (dnodeInfo == NULL) break;
|
||||||
|
|
||||||
SDnodeEp *pEp = &pDnode->dnodeEps->dnodeEps[i];
|
SDnodeEp *pDnodeEp = &pDnode->dnodeEps->eps[i];
|
||||||
|
|
||||||
cJSON *dnodeId = cJSON_GetObjectItem(dnodeInfo, "dnodeId");
|
cJSON *dnodeId = cJSON_GetObjectItem(dnodeInfo, "dnodeId");
|
||||||
if (!dnodeId || dnodeId->type != cJSON_String) {
|
if (!dnodeId || dnodeId->type != cJSON_String) {
|
||||||
dError("failed to read %s, dnodeId not found", pDnode->file);
|
dError("failed to read %s, dnodeId not found", pDnode->file);
|
||||||
goto PRASE_DNODE_OVER;
|
goto PRASE_DNODE_OVER;
|
||||||
}
|
}
|
||||||
pEp->dnodeId = atoi(dnodeId->valuestring);
|
pDnodeEp->id = atoi(dnodeId->valuestring);
|
||||||
|
|
||||||
cJSON *isMnode = cJSON_GetObjectItem(dnodeInfo, "isMnode");
|
cJSON *isMnode = cJSON_GetObjectItem(dnodeInfo, "isMnode");
|
||||||
if (!isMnode || isMnode->type != cJSON_String) {
|
if (!isMnode || isMnode->type != cJSON_String) {
|
||||||
dError("failed to read %s, isMnode not found", pDnode->file);
|
dError("failed to read %s, isMnode not found", pDnode->file);
|
||||||
goto PRASE_DNODE_OVER;
|
goto PRASE_DNODE_OVER;
|
||||||
}
|
}
|
||||||
pEp->isMnode = atoi(isMnode->valuestring);
|
pDnodeEp->isMnode = atoi(isMnode->valuestring);
|
||||||
|
|
||||||
cJSON *dnodeFqdn = cJSON_GetObjectItem(dnodeInfo, "dnodeFqdn");
|
cJSON *dnodeFqdn = cJSON_GetObjectItem(dnodeInfo, "dnodeFqdn");
|
||||||
if (!dnodeFqdn || dnodeFqdn->type != cJSON_String || dnodeFqdn->valuestring == NULL) {
|
if (!dnodeFqdn || dnodeFqdn->type != cJSON_String || dnodeFqdn->valuestring == NULL) {
|
||||||
dError("failed to read %s, dnodeFqdn not found", pDnode->file);
|
dError("failed to read %s, dnodeFqdn not found", pDnode->file);
|
||||||
goto PRASE_DNODE_OVER;
|
goto PRASE_DNODE_OVER;
|
||||||
}
|
}
|
||||||
tstrncpy(pEp->dnodeFqdn, dnodeFqdn->valuestring, TSDB_FQDN_LEN);
|
tstrncpy(pDnodeEp->fqdn, dnodeFqdn->valuestring, TSDB_FQDN_LEN);
|
||||||
|
|
||||||
cJSON *dnodePort = cJSON_GetObjectItem(dnodeInfo, "dnodePort");
|
cJSON *dnodePort = cJSON_GetObjectItem(dnodeInfo, "dnodePort");
|
||||||
if (!dnodePort || dnodePort->type != cJSON_String) {
|
if (!dnodePort || dnodePort->type != cJSON_String) {
|
||||||
dError("failed to read %s, dnodePort not found", pDnode->file);
|
dError("failed to read %s, dnodePort not found", pDnode->file);
|
||||||
goto PRASE_DNODE_OVER;
|
goto PRASE_DNODE_OVER;
|
||||||
}
|
}
|
||||||
pEp->dnodePort = atoi(dnodePort->valuestring);
|
pDnodeEp->port = atoi(dnodePort->valuestring);
|
||||||
}
|
}
|
||||||
|
|
||||||
dInfo("succcessed to read file %s", pDnode->file);
|
dInfo("succcessed to read file %s", pDnode->file);
|
||||||
dnodePrintDnodes();
|
dndPrintDnodes(pDnd);
|
||||||
|
|
||||||
PRASE_DNODE_OVER:
|
PRASE_DNODE_OVER:
|
||||||
if (content != NULL) free(content);
|
if (content != NULL) free(content);
|
||||||
if (root != NULL) cJSON_Delete(root);
|
if (root != NULL) cJSON_Delete(root);
|
||||||
if (fp != NULL) fclose(fp);
|
if (fp != NULL) fclose(fp);
|
||||||
|
|
||||||
if (dnodeIsEpChanged(pDnode->dnodeId, tsLocalEp)) {
|
if (dndIsEpChanged(pDnd, pDnode->dnodeId)) {
|
||||||
dError("localEp %s different with %s and need reconfigured", tsLocalEp, pDnode->file);
|
dError("localEp %s different with %s and need reconfigured", pDnd->opt.localEp, pDnode->file);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDnode->dnodeEps == NULL) {
|
if (pDnode->dnodeEps == NULL) {
|
||||||
pDnode->dnodeEps = calloc(1, sizeof(SDnodeEps) + sizeof(SDnodeEp));
|
pDnode->dnodeEps = calloc(1, sizeof(SDnodeEps) + sizeof(SDnodeEp));
|
||||||
pDnode->dnodeEps->dnodeNum = 1;
|
pDnode->dnodeEps->num = 1;
|
||||||
pDnode->dnodeEps->dnodeEps[0].dnodePort = tsServerPort;
|
pDnode->dnodeEps->eps[0].port = pDnd->opt.serverPort;
|
||||||
tstrncpy(pDnode->dnodeEps->dnodeEps[0].dnodeFqdn, tsLocalFqdn, TSDB_FQDN_LEN);
|
tstrncpy(pDnode->dnodeEps->eps[0].fqdn, pDnd->opt.localFqdn, TSDB_FQDN_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
dnodeResetDnodes(pDnode->dnodeEps);
|
dndResetDnodes(pDnd, pDnode->dnodeEps);
|
||||||
|
|
||||||
terrno = 0;
|
terrno = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t dnodeWriteDnodes() {
|
static int32_t dndWriteDnodes(SDnode *pDnd) {
|
||||||
|
SDnodeMgmt *pDnode = &pDnd->d;
|
||||||
|
|
||||||
FILE *fp = fopen(pDnode->file, "w");
|
FILE *fp = fopen(pDnode->file, "w");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
dError("failed to write %s since %s", pDnode->file, strerror(errno));
|
dError("failed to write %s since %s", pDnode->file, strerror(errno));
|
||||||
|
@ -313,13 +322,13 @@ static int32_t dnodeWriteDnodes() {
|
||||||
len += snprintf(content + len, maxLen - len, " \"clusterId\": \"%" PRId64 "\",\n", pDnode->clusterId);
|
len += snprintf(content + len, maxLen - len, " \"clusterId\": \"%" PRId64 "\",\n", pDnode->clusterId);
|
||||||
len += snprintf(content + len, maxLen - len, " \"dropped\": \"%d\",\n", pDnode->dropped);
|
len += snprintf(content + len, maxLen - len, " \"dropped\": \"%d\",\n", pDnode->dropped);
|
||||||
len += snprintf(content + len, maxLen - len, " \"dnodeInfos\": [{\n");
|
len += snprintf(content + len, maxLen - len, " \"dnodeInfos\": [{\n");
|
||||||
for (int32_t i = 0; i < pDnode->dnodeEps->dnodeNum; ++i) {
|
for (int32_t i = 0; i < pDnode->dnodeEps->num; ++i) {
|
||||||
SDnodeEp *ep = &pDnode->dnodeEps->dnodeEps[i];
|
SDnodeEp *pDnodeEp = &pDnode->dnodeEps->eps[i];
|
||||||
len += snprintf(content + len, maxLen - len, " \"dnodeId\": \"%d\",\n", ep->dnodeId);
|
len += snprintf(content + len, maxLen - len, " \"dnodeId\": \"%d\",\n", pDnodeEp->id);
|
||||||
len += snprintf(content + len, maxLen - len, " \"isMnode\": \"%d\",\n", ep->isMnode);
|
len += snprintf(content + len, maxLen - len, " \"isMnode\": \"%d\",\n", pDnodeEp->isMnode);
|
||||||
len += snprintf(content + len, maxLen - len, " \"dnodeFqdn\": \"%s\",\n", ep->dnodeFqdn);
|
len += snprintf(content + len, maxLen - len, " \"dnodeFqdn\": \"%s\",\n", pDnodeEp->fqdn);
|
||||||
len += snprintf(content + len, maxLen - len, " \"dnodePort\": \"%u\"\n", ep->dnodePort);
|
len += snprintf(content + len, maxLen - len, " \"dnodePort\": \"%u\"\n", pDnodeEp->port);
|
||||||
if (i < pDnode->dnodeEps->dnodeNum - 1) {
|
if (i < pDnode->dnodeEps->num - 1) {
|
||||||
len += snprintf(content + len, maxLen - len, " },{\n");
|
len += snprintf(content + len, maxLen - len, " },{\n");
|
||||||
} else {
|
} else {
|
||||||
len += snprintf(content + len, maxLen - len, " }]\n");
|
len += snprintf(content + len, maxLen - len, " }]\n");
|
||||||
|
@ -337,107 +346,114 @@ static int32_t dnodeWriteDnodes() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodeSendStatusMsg() {
|
static void dndSendStatusMsg(SDnode *pDnd) {
|
||||||
int32_t contLen = sizeof(SStatusMsg) + TSDB_MAX_VNODES * sizeof(SVnodeLoad);
|
int32_t contLen = sizeof(SStatusMsg) + TSDB_MAX_VNODES * sizeof(SVnodeLoad);
|
||||||
|
|
||||||
SStatusMsg *pStatus = rpcMallocCont(contLen);
|
SStatusMsg *pStatus = rpcMallocCont(contLen);
|
||||||
if (pStatus == NULL) {
|
if (pStatus == NULL) {
|
||||||
dError("failed to malloc status message");
|
dError("failed to malloc status message");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pStatus->sversion = htonl(tsVersion);
|
dndLockDnode(pDnd);
|
||||||
pStatus->dnodeId = htonl(dnodeGetDnodeId());
|
pStatus->sversion = htonl(pDnd->opt.sver);
|
||||||
pStatus->clusterId = htobe64(dnodeGetClusterId());
|
pStatus->dnodeId = htonl(pDnd->d.dnodeId);
|
||||||
pStatus->rebootTime = htonl(pDnode->rebootTime);
|
pStatus->clusterId = htobe64(pDnd->d.clusterId);
|
||||||
pStatus->numOfCores = htonl(tsNumOfCores);
|
pStatus->rebootTime = htonl(pDnd->d.rebootTime);
|
||||||
tstrncpy(pStatus->dnodeEp, tsLocalEp, TSDB_EP_LEN);
|
pStatus->numOfCores = htonl(pDnd->opt.numOfCores);
|
||||||
|
tstrncpy(pStatus->dnodeEp, pDnd->opt.localEp, TSDB_EP_LEN);
|
||||||
pStatus->clusterCfg.statusInterval = htonl(tsStatusInterval);
|
pStatus->clusterCfg.statusInterval = htonl(pDnd->opt.statusInterval);
|
||||||
|
tstrncpy(pStatus->clusterCfg.timezone, pDnd->opt.timezone, TSDB_TIMEZONE_LEN);
|
||||||
|
tstrncpy(pStatus->clusterCfg.locale, pDnd->opt.locale, TSDB_LOCALE_LEN);
|
||||||
|
tstrncpy(pStatus->clusterCfg.charset, pDnd->opt.charset, TSDB_LOCALE_LEN);
|
||||||
pStatus->clusterCfg.checkTime = 0;
|
pStatus->clusterCfg.checkTime = 0;
|
||||||
tstrncpy(pStatus->clusterCfg.timezone, tsTimezone, TSDB_TIMEZONE_LEN);
|
|
||||||
tstrncpy(pStatus->clusterCfg.locale, tsLocale, TSDB_LOCALE_LEN);
|
|
||||||
tstrncpy(pStatus->clusterCfg.charset, tsCharset, TSDB_LOCALE_LEN);
|
|
||||||
char timestr[32] = "1970-01-01 00:00:00.00";
|
char timestr[32] = "1970-01-01 00:00:00.00";
|
||||||
(void)taosParseTime(timestr, &pStatus->clusterCfg.checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0);
|
(void)taosParseTime(timestr, &pStatus->clusterCfg.checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
|
dndUnLockDnode(pDnd);
|
||||||
|
|
||||||
dnodeGetVnodeLoads(&pStatus->vnodeLoads);
|
dndGetVnodeLoads(pDnd, &pStatus->vnodeLoads);
|
||||||
contLen = sizeof(SStatusMsg) + pStatus->vnodeLoads.num * sizeof(SVnodeLoad);
|
contLen = sizeof(SStatusMsg) + pStatus->vnodeLoads.num * sizeof(SVnodeLoad);
|
||||||
|
|
||||||
SRpcMsg rpcMsg = {.pCont = pStatus, .contLen = contLen, .msgType = TSDB_MSG_TYPE_STATUS};
|
SRpcMsg rpcMsg = {.pCont = pStatus, .contLen = contLen, .msgType = TSDB_MSG_TYPE_STATUS};
|
||||||
dnodeSendMsgToMnode(NULL, &rpcMsg);
|
dndSendMsgToMnode(pDnd, &rpcMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodeUpdateCfg(SDnodeCfg *pCfg) {
|
static void dndUpdateDnodeCfg(SDnode *pDnd, SDnodeCfg *pCfg) {
|
||||||
if (pDnode->dnodeId == 0) return;
|
SDnodeMgmt *pDnode = &pDnd->d;
|
||||||
if (pDnode->dropped) return;
|
if (pDnode->dnodeId != 0 && pDnode->dropped != pCfg->dropped) return;
|
||||||
|
|
||||||
pthread_mutex_lock(&pDnode->mutex);
|
dndLockDnode(pDnd);
|
||||||
|
|
||||||
pDnode->dnodeId = pCfg->dnodeId;
|
pDnode->dnodeId = pCfg->dnodeId;
|
||||||
pDnode->clusterId = pCfg->clusterId;
|
pDnode->clusterId = pCfg->clusterId;
|
||||||
pDnode->dropped = pCfg->dropped;
|
pDnode->dropped = pCfg->dropped;
|
||||||
dInfo("dnodeId is set to %d, clusterId is set to %" PRId64, pCfg->dnodeId, pCfg->clusterId);
|
dInfo("set dnodeId:%d clusterId:%" PRId64 " dropped:%d", pCfg->dnodeId, pCfg->clusterId, pCfg->dropped);
|
||||||
|
|
||||||
dnodeWriteDnodes();
|
dndWriteDnodes(pDnd);
|
||||||
pthread_mutex_unlock(&pDnode->mutex);
|
dndUnLockDnode(pDnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodeUpdateDnodeEps(SDnodeEps *pEps) {
|
static void dndUpdateDnodeEps(SDnode *pDnd, SDnodeEps *pDnodeEps) {
|
||||||
if (pEps == NULL || pEps->dnodeNum <= 0) return;
|
if (pDnodeEps == NULL || pDnodeEps->num <= 0) return;
|
||||||
|
|
||||||
pthread_mutex_lock(&pDnode->mutex);
|
dndLockDnode(pDnd);
|
||||||
|
|
||||||
if (pEps->dnodeNum != pDnode->dnodeEps->dnodeNum) {
|
if (pDnodeEps->num != pDnd->d.dnodeEps->num) {
|
||||||
dnodeResetDnodes(pEps);
|
dndResetDnodes(pDnd, pDnodeEps);
|
||||||
dnodeWriteDnodes();
|
dndWriteDnodes(pDnd);
|
||||||
} else {
|
} else {
|
||||||
int32_t size = pEps->dnodeNum * sizeof(SDnodeEp) + sizeof(SDnodeEps);
|
int32_t size = pDnodeEps->num * sizeof(SDnodeEp) + sizeof(SDnodeEps);
|
||||||
if (memcmp(pDnode->dnodeEps, pEps, size) != 0) {
|
if (memcmp(pDnd->d.dnodeEps, pDnodeEps, size) != 0) {
|
||||||
dnodeResetDnodes(pEps);
|
dndResetDnodes(pDnd, pDnodeEps);
|
||||||
dnodeWriteDnodes();
|
dndWriteDnodes(pDnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&pDnode->mutex);
|
dndUnLockDnode(pDnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
|
static void dndProcessStatusRsp(SDnode *pDnd, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||||
|
if (pEpSet && pEpSet->numOfEps > 0) {
|
||||||
|
dndUpdateMnodeEpSet(pDnd, pEpSet);
|
||||||
|
}
|
||||||
|
|
||||||
if (pMsg->code != TSDB_CODE_SUCCESS) return;
|
if (pMsg->code != TSDB_CODE_SUCCESS) return;
|
||||||
|
|
||||||
SStatusRsp *pStatusRsp = pMsg->pCont;
|
SStatusRsp *pStatusRsp = pMsg->pCont;
|
||||||
|
SDnodeCfg *pCfg = &pStatusRsp->dnodeCfg;
|
||||||
SDnodeCfg *pCfg = &pStatusRsp->dnodeCfg;
|
|
||||||
pCfg->dnodeId = htonl(pCfg->dnodeId);
|
pCfg->dnodeId = htonl(pCfg->dnodeId);
|
||||||
pCfg->clusterId = htobe64(pCfg->clusterId);
|
pCfg->clusterId = htobe64(pCfg->clusterId);
|
||||||
dnodeUpdateCfg(pCfg);
|
dndUpdateDnodeCfg(pDnd, pCfg);
|
||||||
|
|
||||||
if (pCfg->dropped) return;
|
if (pCfg->dropped) return;
|
||||||
|
|
||||||
SDnodeEps *pEps = &pStatusRsp->dnodeEps;
|
SDnodeEps *pDnodeEps = &pStatusRsp->dnodeEps;
|
||||||
pEps->dnodeNum = htonl(pEps->dnodeNum);
|
pDnodeEps->num = htonl(pDnodeEps->num);
|
||||||
for (int32_t i = 0; i < pEps->dnodeNum; ++i) {
|
for (int32_t i = 0; i < pDnodeEps->num; ++i) {
|
||||||
pEps->dnodeEps[i].dnodeId = htonl(pEps->dnodeEps[i].dnodeId);
|
pDnodeEps->eps[i].id = htonl(pDnodeEps->eps[i].id);
|
||||||
pEps->dnodeEps[i].dnodePort = htons(pEps->dnodeEps[i].dnodePort);
|
pDnodeEps->eps[i].port = htons(pDnodeEps->eps[i].port);
|
||||||
}
|
}
|
||||||
|
|
||||||
dnodeUpdateDnodeEps(pEps);
|
dndUpdateDnodeEps(pDnd, pDnodeEps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodeProcessConfigDnodeReq(SRpcMsg *pMsg) {
|
static void dndProcessAuthRsp(SDnode *pDnd, SRpcMsg *pMsg, SEpSet *pEpSet) { assert(1); }
|
||||||
|
|
||||||
|
static void dndProcessGrantRsp(SDnode *pDnd, SRpcMsg *pMsg, SEpSet *pEpSet) { assert(1); }
|
||||||
|
|
||||||
|
static void dndProcessConfigDnodeReq(SDnode *pDnd, SRpcMsg *pMsg) {
|
||||||
SCfgDnodeMsg *pCfg = pMsg->pCont;
|
SCfgDnodeMsg *pCfg = pMsg->pCont;
|
||||||
|
|
||||||
int32_t code = taosCfgDynamicOptions(pCfg->config);
|
int32_t code = TSDB_CODE_OPS_NOT_SUPPORT;
|
||||||
SRpcMsg rspMsg = {.handle = pMsg->handle, .pCont = NULL, .contLen = 0, .code = code};
|
SRpcMsg rspMsg = {.handle = pMsg->handle, .pCont = NULL, .contLen = 0, .code = code};
|
||||||
rpcSendResponse(&rspMsg);
|
rpcSendResponse(&rspMsg);
|
||||||
rpcFreeCont(pMsg->pCont);
|
rpcFreeCont(pMsg->pCont);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodeProcessStartupReq(SRpcMsg *pMsg) {
|
static void dndProcessStartupReq(SDnode *pDnd, SRpcMsg *pMsg) {
|
||||||
dInfo("startup msg is received, cont:%s", (char *)pMsg->pCont);
|
dInfo("startup msg is received");
|
||||||
|
|
||||||
SStartupMsg *pStartup = rpcMallocCont(sizeof(SStartupMsg));
|
SStartupMsg *pStartup = rpcMallocCont(sizeof(SStartupMsg));
|
||||||
dnodeGetStartup(NULL, pStartup);
|
dndGetStartup(pDnd, pStartup);
|
||||||
|
|
||||||
dInfo("startup msg is sent, step:%s desc:%s finished:%d", pStartup->name, pStartup->desc, pStartup->finished);
|
dInfo("startup msg is sent, step:%s desc:%s finished:%d", pStartup->name, pStartup->desc, pStartup->finished);
|
||||||
|
|
||||||
|
@ -447,108 +463,120 @@ static void dnodeProcessStartupReq(SRpcMsg *pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *dnodeThreadRoutine(void *param) {
|
static void *dnodeThreadRoutine(void *param) {
|
||||||
int32_t ms = tsStatusInterval * 1000;
|
SDnode *pDnd = param;
|
||||||
|
int32_t ms = pDnd->opt.statusInterval * 1000;
|
||||||
|
|
||||||
while (!pDnode->threadStop) {
|
while (true) {
|
||||||
if (dnodeGetStat() != DN_STAT_RUNNING) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
dnodeSendStatusMsg();
|
|
||||||
}
|
|
||||||
taosMsleep(ms);
|
taosMsleep(ms);
|
||||||
|
if (dndGetStat(pDnd) != DND_STAT_RUNNING) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_testcancel();
|
||||||
|
dndSendStatusMsg(pDnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t dnodeInitDnode(SDnode *pServer) {
|
int32_t dndInitDnode(SDnode *pDnd) {
|
||||||
SDnodeDnode *pDnode = &pServer->dnode;
|
SDnodeMgmt *pDnode = &pDnd->d;
|
||||||
|
|
||||||
|
pDnode->dnodeId = 0;
|
||||||
|
pDnode->rebootTime = taosGetTimestampSec();
|
||||||
|
pDnode->dropped = 0;
|
||||||
|
pDnode->clusterId = 0;
|
||||||
|
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
snprintf(path, PATH_MAX, "%s/dnode.json", pServer->dir.dnode);
|
snprintf(path, PATH_MAX, "%s/dnode.json", pDnd->dir.dnode);
|
||||||
pDnode->file = strdup(path);
|
pDnode->file = strdup(path);
|
||||||
if (pDnode->file == NULL) {
|
if (pDnode->file == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pDnode->dnodeId = 0;
|
|
||||||
pDnode->clusterId = 0;
|
|
||||||
pDnode->dnodeEps = NULL;
|
|
||||||
|
|
||||||
pDnode->rebootTime = taosGetTimestampSec();
|
|
||||||
pDnode->dropped = 0;
|
|
||||||
pthread_mutex_init(&pDnode->mutex, NULL);
|
|
||||||
pDnode->threadStop = false;
|
|
||||||
|
|
||||||
pDnode->dnodeHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
pDnode->dnodeHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
||||||
if (pDnode->dnodeHash == NULL) {
|
if (pDnode->dnodeHash == NULL) {
|
||||||
dError("failed to init dnode hash");
|
dError("failed to init dnode hash");
|
||||||
return TSDB_CODE_DND_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pDnode->threadId = taosCreateThread(dnodeThreadRoutine, NULL);
|
if (dndReadDnodes(pDnd) != 0) {
|
||||||
|
dError("failed to read file:%s since %s", pDnode->file, terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_init(&pDnode->mutex, NULL);
|
||||||
|
|
||||||
|
pDnode->threadId = taosCreateThread(dnodeThreadRoutine, pDnd);
|
||||||
if (pDnode->threadId == NULL) {
|
if (pDnode->threadId == NULL) {
|
||||||
dError("failed to init dnode thread");
|
dError("failed to init dnode thread");
|
||||||
return TSDB_CODE_DND_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = dnodeReadDnodes();
|
dInfo("dnd-dnode is initialized");
|
||||||
if (code != 0) {
|
|
||||||
dError("failed to read file:%s since %s", pDnode->file, tstrerror(code));
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
dInfo("dnode-dnode is initialized");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeCleanupDnode(SDnode *pServer) {
|
void dndCleanupDnode(SDnode *pDnd) {
|
||||||
SDnodeDnode *pDnode = &pServer->dnode;
|
SDnodeMgmt *pDnode = &pDnd->d;
|
||||||
|
|
||||||
if (pDnode->threadId != NULL) {
|
if (pDnode->threadId != NULL) {
|
||||||
pDnode->threadStop = true;
|
|
||||||
taosDestoryThread(pDnode->threadId);
|
taosDestoryThread(pDnode->threadId);
|
||||||
pDnode->threadId = NULL;
|
pDnode->threadId = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&pDnode->mutex);
|
dndLockDnode(pDnd);
|
||||||
|
|
||||||
if (pDnode->dnodeEps != NULL) {
|
if (pDnode->dnodeEps != NULL) {
|
||||||
free(pDnode->dnodeEps);
|
free(pDnode->dnodeEps);
|
||||||
pDnode->dnodeEps = NULL;
|
pDnode->dnodeEps = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDnode->dnodeHash) {
|
if (pDnode->dnodeHash != NULL) {
|
||||||
taosHashCleanup(pDnode->dnodeHash);
|
taosHashCleanup(pDnode->dnodeHash);
|
||||||
pDnode->dnodeHash = NULL;
|
pDnode->dnodeHash = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&pDnode->mutex);
|
if (pDnode->file != NULL) {
|
||||||
pthread_mutex_destroy(&pDnode->mutex);
|
free(pDnode->file);
|
||||||
|
pDnode->file = NULL;
|
||||||
dInfo("dnode-dnode is cleaned up");
|
|
||||||
}
|
|
||||||
|
|
||||||
void dnodeProcessDnodeMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|
||||||
int32_t msgType = pMsg->msgType;
|
|
||||||
|
|
||||||
if (msgType == TSDB_MSG_TYPE_STATUS_RSP && pEpSet) {
|
|
||||||
dnodeUpdateMnodeEpSet(&pDnode->dnode, pEpSet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (msgType) {
|
dndUnLockDnode(pDnd);
|
||||||
|
pthread_mutex_destroy(&pDnode->mutex);
|
||||||
|
|
||||||
|
dInfo("dnd-dnode is cleaned up");
|
||||||
|
}
|
||||||
|
|
||||||
|
void dndProcessDnodeReq(SDnode *pDnd, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||||
|
switch (pMsg->msgType) {
|
||||||
case TSDB_MSG_TYPE_NETWORK_TEST:
|
case TSDB_MSG_TYPE_NETWORK_TEST:
|
||||||
dnodeProcessStartupReq(pMsg);
|
dndProcessStartupReq(pDnd, pMsg);
|
||||||
break;
|
break;
|
||||||
case TSDB_MSG_TYPE_CONFIG_DNODE_IN:
|
case TSDB_MSG_TYPE_CONFIG_DNODE_IN:
|
||||||
dnodeProcessConfigDnodeReq(pMsg);
|
dndProcessConfigDnodeReq(pDnd, pMsg);
|
||||||
break;
|
|
||||||
case TSDB_MSG_TYPE_STATUS_RSP:
|
|
||||||
dnodeProcessStatusRsp(pMsg);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dError("RPC %p, %s not processed", pMsg->handle, taosMsg[msgType]);
|
dError("RPC %p, dnode req:%s not processed", pMsg->handle, taosMsg[pMsg->msgType]);
|
||||||
SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_DND_MSG_NOT_PROCESSED};
|
SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_MSG_NOT_PROCESSED};
|
||||||
rpcSendResponse(&rspMsg);
|
rpcSendResponse(&rspMsg);
|
||||||
rpcFreeCont(pMsg->pCont);
|
rpcFreeCont(pMsg->pCont);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dndProcessDnodeRsp(SDnode *pDnd, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||||
|
switch (pMsg->msgType) {
|
||||||
|
case TSDB_MSG_TYPE_STATUS_RSP:
|
||||||
|
dndProcessStatusRsp(pDnd, pMsg, pEpSet);
|
||||||
|
break;
|
||||||
|
case TSDB_MSG_TYPE_AUTH_RSP:
|
||||||
|
dndProcessAuthRsp(pDnd, pMsg, pEpSet);
|
||||||
|
break;
|
||||||
|
case TSDB_MSG_TYPE_GRANT_RSP:
|
||||||
|
dndProcessGrantRsp(pDnd, pMsg, pEpSet);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dError("RPC %p, dnode rsp:%s not processed", pMsg->handle, taosMsg[pMsg->msgType]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,50 +14,47 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "dnodeDnode.h"
|
#include "dndDnode.h"
|
||||||
#include "dnodeMnode.h"
|
#include "dndMnode.h"
|
||||||
#include "dnodeTransport.h"
|
#include "dndTransport.h"
|
||||||
#include "dnodeVnodes.h"
|
#include "dndVnodes.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "tcache.h"
|
#include "tcache.h"
|
||||||
#include "tconfig.h"
|
|
||||||
#include "tnote.h"
|
|
||||||
#include "tstep.h"
|
|
||||||
#include "wal.h"
|
#include "wal.h"
|
||||||
|
|
||||||
EStat dnodeGetStat(SDnode *pDnode) { return pDnode->stat; }
|
EStat dndGetStat(SDnode *pDnode) { return pDnode->stat; }
|
||||||
|
|
||||||
void dnodeSetStat(SDnode *pDnode, EStat stat) {
|
void dndSetStat(SDnode *pDnode, EStat stat) {
|
||||||
dDebug("dnode stat set from %s to %s", dnodeStatStr(pDnode->stat), dnodeStatStr(stat));
|
dDebug("dnode stat set from %s to %s", dndStatStr(pDnode->stat), dndStatStr(stat));
|
||||||
pDnode->stat = stat;
|
pDnode->stat = stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *dnodeStatStr(EStat stat) {
|
char *dndStatStr(EStat stat) {
|
||||||
switch (stat) {
|
switch (stat) {
|
||||||
case DN_STAT_INIT:
|
case DND_STAT_INIT:
|
||||||
return "init";
|
return "init";
|
||||||
case DN_STAT_RUNNING:
|
case DND_STAT_RUNNING:
|
||||||
return "running";
|
return "running";
|
||||||
case DN_STAT_STOPPED:
|
case DND_STAT_STOPPED:
|
||||||
return "stopped";
|
return "stopped";
|
||||||
default:
|
default:
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeReportStartup(SDnode *pDnode, char *name, char *desc) {
|
void dndReportStartup(SDnode *pDnode, char *name, char *desc) {
|
||||||
SStartupMsg *pStartup = &pDnode->startup;
|
SStartupMsg *pStartup = &pDnode->startup;
|
||||||
tstrncpy(pStartup->name, name, strlen(pStartup->name));
|
tstrncpy(pStartup->name, name, strlen(pStartup->name));
|
||||||
tstrncpy(pStartup->desc, desc, strlen(pStartup->desc));
|
tstrncpy(pStartup->desc, desc, strlen(pStartup->desc));
|
||||||
pStartup->finished = 0;
|
pStartup->finished = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeGetStartup(SDnode *pDnode, SStartupMsg *pStartup) {
|
void dndGetStartup(SDnode *pDnode, SStartupMsg *pStartup) {
|
||||||
memcpy(pStartup, &pDnode->startup, sizeof(SStartupMsg);
|
memcpy(pStartup, &pDnode->startup, sizeof(SStartupMsg));
|
||||||
pStartup->finished = (dnodeGetStat(pDnode) == DN_STAT_RUNNING);
|
pStartup->finished = (dndGetStat(pDnode) == DND_STAT_RUNNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t dnodeCheckRunning(char *dataDir) {
|
static int32_t dndCheckRunning(char *dataDir) {
|
||||||
char filepath[PATH_MAX] = {0};
|
char filepath[PATH_MAX] = {0};
|
||||||
snprintf(filepath, sizeof(filepath), "%s/.running", dataDir);
|
snprintf(filepath, sizeof(filepath), "%s/.running", dataDir);
|
||||||
|
|
||||||
|
@ -79,15 +76,19 @@ static int32_t dnodeCheckRunning(char *dataDir) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t dnodeInitDisk(SDnode *pDnode, char *dataDir) {
|
static int32_t dndInitEnv(SDnode *pDnode, SDnodeOpt *pOptions) {
|
||||||
char path[PATH_MAX];
|
if (dndCheckRunning(pOptions->dataDir) != 0) {
|
||||||
snprintf(path, PATH_MAX, "%s/mnode", dataDir);
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char path[PATH_MAX + 100];
|
||||||
|
snprintf(path, sizeof(path), "%s%smnode", pOptions->dataDir, TD_DIRSEP);
|
||||||
pDnode->dir.mnode = strdup(path);
|
pDnode->dir.mnode = strdup(path);
|
||||||
|
|
||||||
sprintf(path, PATH_MAX, "%s/vnode", dataDir);
|
snprintf(path, sizeof(path), "%s%svnode", pOptions->dataDir, TD_DIRSEP);
|
||||||
pDnode->dir.vnodes = strdup(path);
|
pDnode->dir.vnodes = strdup(path);
|
||||||
|
|
||||||
sprintf(path, PATH_MAX, "%s/dnode", dataDir);
|
snprintf(path, sizeof(path), "%s%sdnode", pOptions->dataDir, TD_DIRSEP);
|
||||||
pDnode->dir.dnode = strdup(path);
|
pDnode->dir.dnode = strdup(path);
|
||||||
|
|
||||||
if (pDnode->dir.mnode == NULL || pDnode->dir.vnodes == NULL || pDnode->dir.dnode == NULL) {
|
if (pDnode->dir.mnode == NULL || pDnode->dir.vnodes == NULL || pDnode->dir.dnode == NULL) {
|
||||||
|
@ -114,55 +115,10 @@ static int32_t dnodeInitDisk(SDnode *pDnode, char *dataDir) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dnodeCheckRunning(dataDir) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t dnodeInitEnv(SDnode *pDnode, const char *cfgPath) {
|
static void dndCleanupEnv(SDnode *pDnode) {
|
||||||
taosIgnSIGPIPE();
|
|
||||||
taosBlockSIGPIPE();
|
|
||||||
taosResolveCRC();
|
|
||||||
taosInitGlobalCfg();
|
|
||||||
taosReadGlobalLogCfg();
|
|
||||||
taosSetCoreDump(tsEnableCoreFile);
|
|
||||||
|
|
||||||
if (!taosMkDir(tsLogDir)) {
|
|
||||||
printf("failed to create dir: %s, reason: %s\n", tsLogDir, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char temp[TSDB_FILENAME_LEN];
|
|
||||||
sprintf(temp, "%s/taosdlog", tsLogDir);
|
|
||||||
if (taosInitLog(temp, tsNumOfLogLines, 1) < 0) {
|
|
||||||
dError("failed to init log file\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!taosReadGlobalCfg()) {
|
|
||||||
taosPrintGlobalCfg();
|
|
||||||
dError("TDengine read global config failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
taosInitNotes();
|
|
||||||
|
|
||||||
if (taosCheckGlobalCfg() != 0) {
|
|
||||||
dError("TDengine check global config failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dnodeInitDisk(pDnode, tsDataDir) != 0) {
|
|
||||||
dError("TDengine failed to init directory");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeCleanupEnv(SDnode *pDnode) {
|
|
||||||
if (pDnode->dir.mnode != NULL) {
|
if (pDnode->dir.mnode != NULL) {
|
||||||
tfree(pDnode->dir.mnode);
|
tfree(pDnode->dir.mnode);
|
||||||
}
|
}
|
||||||
|
@ -175,11 +131,10 @@ static void dnodeCleanupEnv(SDnode *pDnode) {
|
||||||
tfree(pDnode->dir.dnode);
|
tfree(pDnode->dir.dnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosCloseLog();
|
|
||||||
taosStopCacheRefreshWorker();
|
taosStopCacheRefreshWorker();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDnode *dnodeInit(const char *cfgPath) {
|
SDnode *dndInit(SDnodeOpt *pOptions) {
|
||||||
SDnode *pDnode = calloc(1, sizeof(pDnode));
|
SDnode *pDnode = calloc(1, sizeof(pDnode));
|
||||||
if (pDnode == NULL) {
|
if (pDnode == NULL) {
|
||||||
dError("failed to create dnode object");
|
dError("failed to create dnode object");
|
||||||
|
@ -188,73 +143,73 @@ SDnode *dnodeInit(const char *cfgPath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dInfo("start to initialize TDengine");
|
dInfo("start to initialize TDengine");
|
||||||
dnodeSetStat(pDnode, DN_STAT_INIT);
|
dndSetStat(pDnode, DND_STAT_INIT);
|
||||||
|
|
||||||
if (dnodeInitEnv(pDnode, cfgPath) != 0) {
|
if (dndInitEnv(pDnode, pOptions) != 0) {
|
||||||
dError("failed to init env");
|
dError("failed to init env");
|
||||||
dnodeCleanup(pDnode);
|
dndCleanup(pDnode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rpcInit() != 0) {
|
if (rpcInit() != 0) {
|
||||||
dError("failed to init rpc env");
|
dError("failed to init rpc env");
|
||||||
dnodeCleanup(pDnode);
|
dndCleanup(pDnode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (walInit() != 0) {
|
if (walInit() != 0) {
|
||||||
dError("failed to init wal env");
|
dError("failed to init wal env");
|
||||||
dnodeCleanup(pDnode);
|
dndCleanup(pDnode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dnodeInitDnode(pDnode) != 0) {
|
if (dndInitDnode(pDnode) != 0) {
|
||||||
dError("failed to init dnode");
|
dError("failed to init dnode");
|
||||||
dnodeCleanup(pDnode);
|
dndCleanup(pDnode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dnodeInitVnodes(pDnode) != 0) {
|
if (dndInitVnodes(pDnode) != 0) {
|
||||||
dError("failed to init vnodes");
|
dError("failed to init vnodes");
|
||||||
dnodeCleanup(pDnode);
|
dndCleanup(pDnode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dnodeInitMnode(pDnode) != 0) {
|
if (dndInitMnode(pDnode) != 0) {
|
||||||
dError("failed to init mnode");
|
dError("failed to init mnode");
|
||||||
dnodeCleanup(pDnode);
|
dndCleanup(pDnode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dnodeInitTrans(pDnode) != 0) {
|
if (dndInitTrans(pDnode) != 0) {
|
||||||
dError("failed to init transport");
|
dError("failed to init transport");
|
||||||
dnodeCleanup(pDnode);
|
dndCleanup(pDnode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dnodeSetStat(pDnode, DN_STAT_RUNNING);
|
dndSetStat(pDnode, DND_STAT_RUNNING);
|
||||||
dnodeReportStartup(pDnode, "TDengine", "initialized successfully");
|
dndReportStartup(pDnode, "TDengine", "initialized successfully");
|
||||||
dInfo("TDengine is initialized successfully");
|
dInfo("TDengine is initialized successfully");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeCleanup(SDnode *pDnode) {
|
void dndCleanup(SDnode *pDnode) {
|
||||||
if (dnodeGetStat(pDnode) == DN_STAT_STOPPED) {
|
if (dndGetStat(pDnode) == DND_STAT_STOPPED) {
|
||||||
dError("dnode is shutting down");
|
dError("dnode is shutting down");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dInfo("start to cleanup TDengine");
|
dInfo("start to cleanup TDengine");
|
||||||
dnodeSetStat(pDnode, DN_STAT_STOPPED);
|
dndSetStat(pDnode, DND_STAT_STOPPED);
|
||||||
dnodeCleanupTrans(pDnode);
|
dndCleanupTrans(pDnode);
|
||||||
dnodeCleanupMnode(pDnode);
|
dndCleanupMnode(pDnode);
|
||||||
dnodeCleanupVnodes(pDnode);
|
dndCleanupVnodes(pDnode);
|
||||||
dnodeCleanupDnode(pDnode);
|
dndCleanupDnode(pDnode);
|
||||||
walCleanUp();
|
walCleanUp();
|
||||||
rpcCleanup();
|
rpcCleanup();
|
||||||
|
|
||||||
dInfo("TDengine is cleaned up successfully");
|
dInfo("TDengine is cleaned up successfully");
|
||||||
dnodeCleanupEnv(pDnode);
|
dndCleanupEnv(pDnode);
|
||||||
free(pDnode);
|
free(pDnode);
|
||||||
}
|
}
|
|
@ -0,0 +1,816 @@
|
||||||
|
/*
|
||||||
|
* 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 "dndMnode.h"
|
||||||
|
#include "dndDnode.h"
|
||||||
|
#include "dndTransport.h"
|
||||||
|
|
||||||
|
static int32_t dndInitMnodeReadWorker(SDnode *pDnode);
|
||||||
|
static int32_t dndInitMnodeWriteWorker(SDnode *pDnode);
|
||||||
|
static int32_t dndInitMnodeSyncWorker(SDnode *pDnode);
|
||||||
|
static int32_t dndInitMnodeMgmtWorker(SDnode *pDnode);
|
||||||
|
static void dndCleanupMnodeReadWorker(SDnode *pDnode);
|
||||||
|
static void dndCleanupMnodeWriteWorker(SDnode *pDnode);
|
||||||
|
static void dndCleanupMnodeSyncWorker(SDnode *pDnode);
|
||||||
|
static void dndCleanupMnodeMgmtWorker(SDnode *pDnode);
|
||||||
|
static int32_t dndAllocMnodeReadQueue(SDnode *pDnode);
|
||||||
|
static int32_t dndAllocMnodeWriteQueue(SDnode *pDnode);
|
||||||
|
static int32_t dndAllocMnodeApplyQueue(SDnode *pDnode);
|
||||||
|
static int32_t dndAllocMnodeSyncQueue(SDnode *pDnode);
|
||||||
|
static int32_t dndAllocMnodeMgmtQueue(SDnode *pDnode);
|
||||||
|
static void dndFreeMnodeReadQueue(SDnode *pDnode);
|
||||||
|
static void dndFreeMnodeWriteQueue(SDnode *pDnode);
|
||||||
|
static void dndFreeMnodeApplyQueue(SDnode *pDnode);
|
||||||
|
static void dndFreeMnodeSyncQueue(SDnode *pDnode);
|
||||||
|
static void dndFreeMnodeMgmtQueue(SDnode *pDnode);
|
||||||
|
|
||||||
|
static void dndProcessMnodeReadQueue(SDnode *pDnode, SMnodeMsg *pMsg);
|
||||||
|
static void dndProcessMnodeWriteQueue(SDnode *pDnode, SMnodeMsg *pMsg);
|
||||||
|
static void dndProcessMnodeApplyQueue(SDnode *pDnode, SMnodeMsg *pMsg);
|
||||||
|
static void dndProcessMnodeSyncQueue(SDnode *pDnode, SMnodeMsg *pMsg);
|
||||||
|
static void dndProcessMnodeMgmtQueue(SDnode *pDnode, SRpcMsg *pMsg);
|
||||||
|
static int32_t dndWriteMnodeMsgToQueue(SMnode *pMnode, taos_queue pQueue, SRpcMsg *pRpcMsg);
|
||||||
|
void dndProcessMnodeReadMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
|
void dndProcessMnodeWriteMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
|
void dndProcessMnodeSyncMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
|
void dndProcessMnodeMgmtMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||||
|
static int32_t dndPutMsgIntoMnodeApplyQueue(SDnode *pDnode, SMnodeMsg *pMsg);
|
||||||
|
|
||||||
|
static int32_t dndStartMnodeWorker(SDnode *pDnode);
|
||||||
|
static void dndStopMnodeWorker(SDnode *pDnode);
|
||||||
|
|
||||||
|
static SMnode *dndAcquireMnode(SDnode *pDnode);
|
||||||
|
static void dndReleaseMnode(SDnode *pDnode, SMnode *pMnode);
|
||||||
|
|
||||||
|
static int32_t dndReadMnodeFile(SDnode *pDnode);
|
||||||
|
static int32_t dndWriteMnodeFile(SDnode *pDnode);
|
||||||
|
|
||||||
|
static int32_t dndOpenMnode(SDnode *pDnode, SMnodeOptions *pOptions);
|
||||||
|
static int32_t dndAlterMnode(SDnode *pDnode, SMnodeOptions *pOptions);
|
||||||
|
static int32_t dndDropMnode(SDnode *pDnode);
|
||||||
|
|
||||||
|
static int32_t dndProcessCreateMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg);
|
||||||
|
static int32_t dndProcessAlterMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg);
|
||||||
|
static int32_t dndProcessDropMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg);
|
||||||
|
|
||||||
|
static SMnode *dndAcquireMnode(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
SMnode *pMnode = NULL;
|
||||||
|
int32_t refCount = 0;
|
||||||
|
|
||||||
|
taosRLockLatch(&pMgmt->latch);
|
||||||
|
if (pMgmt->deployed && !pMgmt->dropped) {
|
||||||
|
refCount = atomic_add_fetch_32(&pMgmt->refCount, 1);
|
||||||
|
pMnode = pMgmt->pMnode;
|
||||||
|
} else {
|
||||||
|
terrno = TSDB_CODE_DND_MNODE_NOT_DEPLOYED;
|
||||||
|
}
|
||||||
|
taosRUnLockLatch(&pMgmt->latch);
|
||||||
|
|
||||||
|
dTrace("acquire mnode, refCount:%d", refCount);
|
||||||
|
return pMnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndReleaseMnode(SDnode *pDnode, SMnode *pMnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
int32_t refCount = 0;
|
||||||
|
|
||||||
|
taosRLockLatch(&pMgmt->latch);
|
||||||
|
if (pMnode != NULL) {
|
||||||
|
refCount = atomic_sub_fetch_32(&pMgmt->refCount, 1);
|
||||||
|
}
|
||||||
|
taosRUnLockLatch(&pMgmt->latch);
|
||||||
|
|
||||||
|
dTrace("release mnode, refCount:%d", refCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndReadMnodeFile(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
int32_t code = TSDB_CODE_DND_MNODE_READ_FILE_ERROR;
|
||||||
|
int32_t len = 0;
|
||||||
|
int32_t maxLen = 300;
|
||||||
|
char *content = calloc(1, maxLen + 1);
|
||||||
|
cJSON *root = NULL;
|
||||||
|
|
||||||
|
FILE *fp = fopen(pMgmt->file, "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
dDebug("file %s not exist", pMgmt->file);
|
||||||
|
code = 0;
|
||||||
|
goto PRASE_MNODE_OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (int32_t)fread(content, 1, maxLen, fp);
|
||||||
|
if (len <= 0) {
|
||||||
|
dError("failed to read %s since content is null", pMgmt->file);
|
||||||
|
goto PRASE_MNODE_OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
content[len] = 0;
|
||||||
|
root = cJSON_Parse(content);
|
||||||
|
if (root == NULL) {
|
||||||
|
dError("failed to read %s since invalid json format", pMgmt->file);
|
||||||
|
goto PRASE_MNODE_OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON *deployed = cJSON_GetObjectItem(root, "deployed");
|
||||||
|
if (!deployed || deployed->type != cJSON_String) {
|
||||||
|
dError("failed to read %s since deployed not found", pMgmt->file);
|
||||||
|
goto PRASE_MNODE_OVER;
|
||||||
|
}
|
||||||
|
pMgmt->deployed = atoi(deployed->valuestring);
|
||||||
|
|
||||||
|
cJSON *dropped = cJSON_GetObjectItem(root, "dropped");
|
||||||
|
if (!dropped || dropped->type != cJSON_String) {
|
||||||
|
dError("failed to read %s since dropped not found", pMgmt->file);
|
||||||
|
goto PRASE_MNODE_OVER;
|
||||||
|
}
|
||||||
|
pMgmt->dropped = atoi(dropped->valuestring);
|
||||||
|
|
||||||
|
code = 0;
|
||||||
|
dInfo("succcessed to read file %s", pMgmt->file);
|
||||||
|
|
||||||
|
PRASE_MNODE_OVER:
|
||||||
|
if (content != NULL) free(content);
|
||||||
|
if (root != NULL) cJSON_Delete(root);
|
||||||
|
if (fp != NULL) fclose(fp);
|
||||||
|
|
||||||
|
terrno = code;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndWriteMnodeFile(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
char file[PATH_MAX + 20] = {0};
|
||||||
|
snprintf(file, sizeof(file), "%s.bak", pMgmt->file);
|
||||||
|
|
||||||
|
FILE *fp = fopen(file, "w");
|
||||||
|
if (fp != NULL) {
|
||||||
|
terrno = TSDB_CODE_DND_MNODE_WRITE_FILE_ERROR;
|
||||||
|
dError("failed to write %s since %s", file, terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t len = 0;
|
||||||
|
int32_t maxLen = 300;
|
||||||
|
char *content = calloc(1, maxLen + 1);
|
||||||
|
|
||||||
|
len += snprintf(content + len, maxLen - len, "{\n");
|
||||||
|
len += snprintf(content + len, maxLen - len, " \"deployed\": \"%d\",\n", pMgmt->deployed);
|
||||||
|
len += snprintf(content + len, maxLen - len, " \"dropped\": \"%d\"\n", pMgmt->dropped);
|
||||||
|
len += snprintf(content + len, maxLen - len, "}\n");
|
||||||
|
|
||||||
|
fwrite(content, 1, len, fp);
|
||||||
|
taosFsyncFile(fileno(fp));
|
||||||
|
fclose(fp);
|
||||||
|
free(content);
|
||||||
|
|
||||||
|
if (taosRenameFile(file, pMgmt->file) != 0) {
|
||||||
|
terrno = TSDB_CODE_DND_MNODE_WRITE_FILE_ERROR;
|
||||||
|
dError("failed to rename %s since %s", pMgmt->file, terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dInfo("successed to write %s", pMgmt->file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndStartMnodeWorker(SDnode *pDnode) {
|
||||||
|
if (dndAllocMnodeReadQueue(pDnode) != 0) {
|
||||||
|
dError("failed to alloc mnode read queue since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dndAllocMnodeWriteQueue(pDnode) != 0) {
|
||||||
|
dError("failed to alloc mnode write queue since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dndAllocMnodeApplyQueue(pDnode) != 0) {
|
||||||
|
dError("failed to alloc mnode apply queue since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dndAllocMnodeSyncQueue(pDnode) != 0) {
|
||||||
|
dError("failed to alloc mnode sync queue since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndStopMnodeWorker(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
|
||||||
|
taosWLockLatch(&pMgmt->latch);
|
||||||
|
pMgmt->deployed = 0;
|
||||||
|
pMgmt->pMnode = NULL;
|
||||||
|
taosWUnLockLatch(&pMgmt->latch);
|
||||||
|
|
||||||
|
while (pMgmt->refCount > 1) taosMsleep(10);
|
||||||
|
while (!taosQueueEmpty(pMgmt->pReadQ)) taosMsleep(10);
|
||||||
|
while (!taosQueueEmpty(pMgmt->pApplyQ)) taosMsleep(10);
|
||||||
|
while (!taosQueueEmpty(pMgmt->pWriteQ)) taosMsleep(10);
|
||||||
|
while (!taosQueueEmpty(pMgmt->pSyncQ)) taosMsleep(10);
|
||||||
|
|
||||||
|
dndFreeMnodeReadQueue(pDnode);
|
||||||
|
dndFreeMnodeWriteQueue(pDnode);
|
||||||
|
dndFreeMnodeApplyQueue(pDnode);
|
||||||
|
dndFreeMnodeSyncQueue(pDnode);
|
||||||
|
|
||||||
|
dndCleanupMnodeReadWorker(pDnode);
|
||||||
|
dndCleanupMnodeWriteWorker(pDnode);
|
||||||
|
dndCleanupMnodeSyncWorker(pDnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool dndNeedDeployMnode(SDnode *pDnode) {
|
||||||
|
if (dndGetDnodeId(pDnode) > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dndGetClusterId(pDnode) > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (strcmp(pDnode->opt.localEp, pDnode->opt.firstEp) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndInitMnodeOptions(SDnode *pDnode, SMnodeOptions *pOptions) {
|
||||||
|
pOptions->pDnode = pDnode;
|
||||||
|
pOptions->sendMsgToDnodeFp = dndSendMsgToDnode;
|
||||||
|
pOptions->sendMsgToMnodeFp = dndSendMsgToMnode;
|
||||||
|
pOptions->sendRedirectMsgFp = dndSendRedirectMsg;
|
||||||
|
pOptions->putMsgToApplyMsgFp = dndPutMsgIntoMnodeApplyQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndBuildMnodeOptions(SDnode *pDnode, SMnodeOptions *pOptions, SCreateMnodeMsg *pMsg) {
|
||||||
|
dndInitMnodeOptions(pDnode, pOptions);
|
||||||
|
|
||||||
|
if (pMsg == NULL) {
|
||||||
|
pOptions->dnodeId = 1;
|
||||||
|
pOptions->clusterId = 1234;
|
||||||
|
pOptions->replica = 1;
|
||||||
|
pOptions->selfIndex = 0;
|
||||||
|
SReplica *pReplica = &pOptions->replicas[0];
|
||||||
|
pReplica->id = 1;
|
||||||
|
pReplica->port = pDnode->opt.serverPort;
|
||||||
|
tstrncpy(pReplica->fqdn, pDnode->opt.localFqdn, TSDB_FQDN_LEN);
|
||||||
|
} else {
|
||||||
|
pOptions->dnodeId = dndGetDnodeId(pDnode);
|
||||||
|
pOptions->clusterId = dndGetClusterId(pDnode);
|
||||||
|
pOptions->selfIndex = -1;
|
||||||
|
pOptions->replica = pMsg->replica;
|
||||||
|
for (int32_t index = 0; index < pMsg->replica; ++index) {
|
||||||
|
SReplica *pReplica = &pOptions->replicas[index];
|
||||||
|
pReplica->id = pMsg->replicas[index].id;
|
||||||
|
pReplica->port = pMsg->replicas[index].port;
|
||||||
|
tstrncpy(pReplica->fqdn, pMsg->replicas[index].fqdn, TSDB_FQDN_LEN);
|
||||||
|
if (pReplica->id == pOptions->dnodeId) {
|
||||||
|
pOptions->selfIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pOptions->selfIndex == -1) {
|
||||||
|
terrno = TSDB_CODE_DND_MNODE_ID_NOT_FOUND;
|
||||||
|
dError("failed to build mnode options since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndOpenMnode(SDnode *pDnode, SMnodeOptions *pOptions) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
|
||||||
|
int32_t code = dndStartMnodeWorker(pDnode);
|
||||||
|
if (code != 0) {
|
||||||
|
dError("failed to start mnode worker since %s", terrstr());
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
SMnode *pMnode = mnodeOpen(pDnode->dir.mnode, pOptions);
|
||||||
|
if (pMnode == NULL) {
|
||||||
|
dError("failed to open mnode since %s", terrstr());
|
||||||
|
code = terrno;
|
||||||
|
dndStopMnodeWorker(pDnode);
|
||||||
|
terrno = code;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dndWriteMnodeFile(pDnode) != 0) {
|
||||||
|
dError("failed to write mnode file since %s", terrstr());
|
||||||
|
code = terrno;
|
||||||
|
dndStopMnodeWorker(pDnode);
|
||||||
|
mnodeClose(pMnode);
|
||||||
|
mnodeDestroy(pDnode->dir.mnode);
|
||||||
|
terrno = code;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosWLockLatch(&pMgmt->latch);
|
||||||
|
pMgmt->pMnode = pMnode;
|
||||||
|
pMgmt->deployed = 1;
|
||||||
|
taosWUnLockLatch(&pMgmt->latch);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndAlterMnode(SDnode *pDnode, SMnodeOptions *pOptions) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
|
||||||
|
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||||
|
if (pMnode == NULL) {
|
||||||
|
dError("failed to alter mnode since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mnodeAlter(pMnode, pOptions) != 0) {
|
||||||
|
dError("failed to alter mnode since %s", terrstr());
|
||||||
|
dndReleaseMnode(pDnode, pMnode);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dndReleaseMnode(pDnode, pMnode);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndDropMnode(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
|
||||||
|
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||||
|
if (pMnode == NULL) {
|
||||||
|
dError("failed to drop mnode since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosRLockLatch(&pMgmt->latch);
|
||||||
|
pMgmt->dropped = 1;
|
||||||
|
taosRUnLockLatch(&pMgmt->latch);
|
||||||
|
|
||||||
|
if (dndWriteMnodeFile(pDnode) != 0) {
|
||||||
|
taosRLockLatch(&pMgmt->latch);
|
||||||
|
pMgmt->dropped = 0;
|
||||||
|
taosRUnLockLatch(&pMgmt->latch);
|
||||||
|
|
||||||
|
dndReleaseMnode(pDnode, pMnode);
|
||||||
|
dError("failed to drop mnode since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dndStopMnodeWorker(pDnode);
|
||||||
|
dndWriteMnodeFile(pDnode);
|
||||||
|
mnodeClose(pMnode);
|
||||||
|
mnodeDestroy(pDnode->dir.mnode);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SCreateMnodeMsg *dndParseCreateMnodeMsg(SRpcMsg *pRpcMsg) {
|
||||||
|
SCreateMnodeMsg *pMsg = pRpcMsg->pCont;
|
||||||
|
pMsg->dnodeId = htonl(pMsg->dnodeId);
|
||||||
|
for (int32_t i = 0; i < pMsg->replica; ++i) {
|
||||||
|
pMsg->replicas[i].id = htonl(pMsg->replicas[i].id);
|
||||||
|
pMsg->replicas[i].port = htons(pMsg->replicas[i].port);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndProcessCreateMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) {
|
||||||
|
SCreateMnodeMsg *pMsg = dndParseCreateMnodeMsg(pRpcMsg->pCont);
|
||||||
|
|
||||||
|
if (pMsg->dnodeId != dndGetDnodeId(pDnode)) {
|
||||||
|
terrno = TSDB_CODE_DND_MNODE_ID_INVALID;
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
SMnodeOptions option = {0};
|
||||||
|
if (dndBuildMnodeOptions(pDnode, &option, pMsg) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return dndOpenMnode(pDnode, &option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndProcessAlterMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) {
|
||||||
|
SAlterMnodeMsg *pMsg = dndParseCreateMnodeMsg(pRpcMsg->pCont);
|
||||||
|
|
||||||
|
if (pMsg->dnodeId != dndGetDnodeId(pDnode)) {
|
||||||
|
terrno = TSDB_CODE_DND_MNODE_ID_INVALID;
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
SMnodeOptions option = {0};
|
||||||
|
if (dndBuildMnodeOptions(pDnode, &option, pMsg) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return dndAlterMnode(pDnode, &option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndProcessDropMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) {
|
||||||
|
SDropMnodeMsg *pMsg = dndParseCreateMnodeMsg(pRpcMsg->pCont);
|
||||||
|
|
||||||
|
if (pMsg->dnodeId != dndGetDnodeId(pDnode)) {
|
||||||
|
terrno = TSDB_CODE_DND_MNODE_ID_INVALID;
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return dndDropMnode(pDnode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndProcessMnodeMgmtQueue(SDnode *pDnode, SRpcMsg *pMsg) {
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
|
switch (pMsg->msgType) {
|
||||||
|
case TSDB_MSG_TYPE_CREATE_MNODE_IN:
|
||||||
|
code = dndProcessCreateMnodeReq(pDnode, pMsg);
|
||||||
|
break;
|
||||||
|
case TSDB_MSG_TYPE_ALTER_MNODE_IN:
|
||||||
|
code = dndProcessAlterMnodeReq(pDnode, pMsg);
|
||||||
|
break;
|
||||||
|
case TSDB_MSG_TYPE_DROP_MNODE_IN:
|
||||||
|
code = dndProcessDropMnodeReq(pDnode, pMsg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
code = TSDB_CODE_MSG_NOT_PROCESSED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRpcMsg rsp = {.code = code, .handle = pMsg->handle};
|
||||||
|
rpcSendResponse(&rsp);
|
||||||
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
taosFreeQitem(pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndProcessMnodeReadQueue(SDnode *pDnode, SMnodeMsg *pMsg) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
|
||||||
|
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||||
|
if (pMnode != NULL) {
|
||||||
|
mnodeProcessReadMsg(pMnode, pMsg);
|
||||||
|
dndReleaseMnode(pDnode, pMnode);
|
||||||
|
} else {
|
||||||
|
mnodeSendRsp(pMsg, terrno);
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeCleanupMsg(pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndProcessMnodeWriteQueue(SDnode *pDnode, SMnodeMsg *pMsg) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
|
||||||
|
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||||
|
if (pMnode != NULL) {
|
||||||
|
mnodeProcessWriteMsg(pMnode, pMsg);
|
||||||
|
dndReleaseMnode(pDnode, pMnode);
|
||||||
|
} else {
|
||||||
|
mnodeSendRsp(pMsg, terrno);
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeCleanupMsg(pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndProcessMnodeApplyQueue(SDnode *pDnode, SMnodeMsg *pMsg) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
|
||||||
|
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||||
|
if (pMnode != NULL) {
|
||||||
|
mnodeProcessApplyMsg(pMnode, pMsg);
|
||||||
|
dndReleaseMnode(pDnode, pMnode);
|
||||||
|
} else {
|
||||||
|
mnodeSendRsp(pMsg, terrno);
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeCleanupMsg(pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndProcessMnodeSyncQueue(SDnode *pDnode, SMnodeMsg *pMsg) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
|
||||||
|
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||||
|
if (pMnode != NULL) {
|
||||||
|
mnodeProcessSyncMsg(pMnode, pMsg);
|
||||||
|
dndReleaseMnode(pDnode, pMnode);
|
||||||
|
} else {
|
||||||
|
mnodeSendRsp(pMsg, terrno);
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeCleanupMsg(pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndWriteMnodeMsgToQueue(SMnode *pMnode, taos_queue pQueue, SRpcMsg *pRpcMsg) {
|
||||||
|
assert(pQueue);
|
||||||
|
|
||||||
|
SMnodeMsg *pMsg = mnodeInitMsg(pMnode, pRpcMsg);
|
||||||
|
if (pMsg == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taosWriteQitem(pQueue, pMsg) != 0) {
|
||||||
|
mnodeCleanupMsg(pMsg);
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dndProcessMnodeMgmtMsg(SDnode *pDnode, SRpcMsg *pRpcMsg, SEpSet *pEpSet) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||||
|
|
||||||
|
SRpcMsg *pMsg = taosAllocateQitem(sizeof(SRpcMsg));
|
||||||
|
if (pMsg == NULL || taosWriteQitem(pMgmt->pMgmtQ, pMsg) != 0) {
|
||||||
|
SRpcMsg rsp = {.handle = pRpcMsg->handle, .code = TSDB_CODE_OUT_OF_MEMORY};
|
||||||
|
rpcSendResponse(&rsp);
|
||||||
|
rpcFreeCont(pRpcMsg->pCont);
|
||||||
|
taosFreeQitem(pMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dndProcessMnodeWriteMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||||
|
if (pMnode == NULL || dndWriteMnodeMsgToQueue(pMnode, pMgmt->pWriteQ, pMsg) != 0) {
|
||||||
|
SRpcMsg rsp = {.handle = pMsg->handle, .code = terrno};
|
||||||
|
rpcSendResponse(&rsp);
|
||||||
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
}
|
||||||
|
|
||||||
|
dndReleaseMnode(pDnode, pMnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dndProcessMnodeSyncMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||||
|
if (pMnode == NULL || dndWriteMnodeMsgToQueue(pMnode, pMgmt->pSyncQ, pMsg) != 0) {
|
||||||
|
SRpcMsg rsp = {.handle = pMsg->handle, .code = terrno};
|
||||||
|
rpcSendResponse(&rsp);
|
||||||
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
}
|
||||||
|
|
||||||
|
dndReleaseMnode(pDnode, pMnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dndProcessMnodeReadMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||||
|
if (pMnode == NULL || dndWriteMnodeMsgToQueue(pMnode, pMgmt->pSyncQ, pMsg) != 0) {
|
||||||
|
SRpcMsg rsp = {.handle = pMsg->handle, .code = terrno};
|
||||||
|
rpcSendResponse(&rsp);
|
||||||
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
}
|
||||||
|
|
||||||
|
dndReleaseMnode(pDnode, pMnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndPutMsgIntoMnodeApplyQueue(SDnode *pDnode, SMnodeMsg *pMsg) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
|
||||||
|
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||||
|
if (pMnode == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = taosWriteQitem(pMgmt->pApplyQ, pMsg);
|
||||||
|
dndReleaseMnode(pDnode, pMnode);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndAllocMnodeMgmtQueue(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
pMgmt->pMgmtQ = tWorkerAllocQueue(&pMgmt->mgmtPool, NULL, (FProcessItem)dndProcessMnodeMgmtQueue);
|
||||||
|
if (pMgmt->pMgmtQ == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndFreeMnodeMgmtQueue(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
tWorkerFreeQueue(&pMgmt->mgmtPool, pMgmt->pMgmtQ);
|
||||||
|
pMgmt->pMgmtQ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndInitMnodeMgmtWorker(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
SWorkerPool *pPool = &pMgmt->mgmtPool;
|
||||||
|
pPool->name = "mnode-mgmt";
|
||||||
|
pPool->min = 1;
|
||||||
|
pPool->max = 1;
|
||||||
|
if (tWorkerInit(pPool) != 0) {
|
||||||
|
terrno = TSDB_CODE_VND_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndCleanupMnodeMgmtWorker(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
;
|
||||||
|
tWorkerCleanup(&pMgmt->mgmtPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndAllocMnodeReadQueue(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
pMgmt->pReadQ = tWorkerAllocQueue(&pMgmt->readPool, NULL, (FProcessItem)dndProcessMnodeReadQueue);
|
||||||
|
if (pMgmt->pReadQ == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndFreeMnodeReadQueue(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
tWorkerFreeQueue(&pMgmt->readPool, pMgmt->pReadQ);
|
||||||
|
pMgmt->pReadQ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndInitMnodeReadWorker(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
SWorkerPool *pPool = &pMgmt->readPool;
|
||||||
|
pPool->name = "mnode-read";
|
||||||
|
pPool->min = 0;
|
||||||
|
pPool->max = 1;
|
||||||
|
if (tWorkerInit(pPool) != 0) {
|
||||||
|
terrno = TSDB_CODE_VND_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndCleanupMnodeReadWorker(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
tWorkerCleanup(&pMgmt->readPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndAllocMnodeWriteQueue(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
pMgmt->pWriteQ = tWorkerAllocQueue(&pMgmt->writePool, NULL, (FProcessItem)dndProcessMnodeWriteQueue);
|
||||||
|
if (pMgmt->pWriteQ == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndFreeMnodeWriteQueue(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
tWorkerFreeQueue(&pMgmt->writePool, pMgmt->pWriteQ);
|
||||||
|
pMgmt->pWriteQ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndAllocMnodeApplyQueue(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
pMgmt->pApplyQ = tWorkerAllocQueue(&pMgmt->writePool, NULL, (FProcessItem)dndProcessMnodeApplyQueue);
|
||||||
|
if (pMgmt->pApplyQ == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndFreeMnodeApplyQueue(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
tWorkerFreeQueue(&pMgmt->writePool, pMgmt->pApplyQ);
|
||||||
|
pMgmt->pApplyQ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndInitMnodeWriteWorker(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
SWorkerPool *pPool = &pMgmt->writePool;
|
||||||
|
pPool->name = "mnode-write";
|
||||||
|
pPool->min = 0;
|
||||||
|
pPool->max = 1;
|
||||||
|
if (tWorkerInit(pPool) != 0) {
|
||||||
|
terrno = TSDB_CODE_VND_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndCleanupMnodeWriteWorker(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
tWorkerCleanup(&pMgmt->writePool);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndAllocMnodeSyncQueue(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
pMgmt->pSyncQ = tWorkerAllocQueue(&pMgmt->syncPool, NULL, (FProcessItem)dndProcessMnodeSyncQueue);
|
||||||
|
if (pMgmt->pSyncQ == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndFreeMnodeSyncQueue(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
tWorkerFreeQueue(&pMgmt->syncPool, pMgmt->pSyncQ);
|
||||||
|
pMgmt->pSyncQ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndInitMnodeSyncWorker(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
SWorkerPool *pPool = &pMgmt->syncPool;
|
||||||
|
pPool->name = "mnode-sync";
|
||||||
|
pPool->min = 0;
|
||||||
|
pPool->max = 1;
|
||||||
|
return tWorkerInit(pPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndCleanupMnodeSyncWorker(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
tWorkerCleanup(&pMgmt->syncPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t dndInitMnode(SDnode *pDnode) {
|
||||||
|
dInfo("dnode-mnode start to init");
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
taosInitRWLatch(&pMgmt->latch);
|
||||||
|
|
||||||
|
if (dndInitMnodeMgmtWorker(pDnode) != 0) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char path[PATH_MAX];
|
||||||
|
snprintf(path, PATH_MAX, "%s/mnode.json", pDnode->dir.dnode);
|
||||||
|
pMgmt->file = strdup(path);
|
||||||
|
if (pMgmt->file == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dndReadMnodeFile(pDnode) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMgmt->dropped) {
|
||||||
|
dInfo("mnode has been deployed and needs to be deleted");
|
||||||
|
mnodeDestroy(pDnode->dir.mnode);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pMgmt->deployed) {
|
||||||
|
bool needDeploy = dndNeedDeployMnode(pDnode);
|
||||||
|
if (!needDeploy) {
|
||||||
|
dDebug("mnode does not need to be deployed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dInfo("start to deploy mnode");
|
||||||
|
} else {
|
||||||
|
dInfo("start to open mnode");
|
||||||
|
}
|
||||||
|
|
||||||
|
SMnodeOptions option = {0};
|
||||||
|
dndInitMnodeOptions(pDnode, &option);
|
||||||
|
return dndOpenMnode(pDnode, &option);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dndCleanupMnode(SDnode *pDnode) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
|
||||||
|
dInfo("dnode-mnode start to clean up");
|
||||||
|
dndStopMnodeWorker(pDnode);
|
||||||
|
dndCleanupMnodeMgmtWorker(pDnode);
|
||||||
|
tfree(pMgmt->file);
|
||||||
|
dInfo("dnode-mnode is cleaned up");
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t dndGetUserAuthFromMnode(SDnode *pDnode, char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
||||||
|
SMnodeMgmt *pMgmt = &pDnode->m;
|
||||||
|
|
||||||
|
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||||
|
if (pMnode == NULL) {
|
||||||
|
terrno = TSDB_CODE_APP_NOT_READY;
|
||||||
|
dTrace("failed to get user auth since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = mnodeRetriveAuth(pMnode, user, spi, encrypt, secret, ckey);
|
||||||
|
dndReleaseMnode(pDnode, pMnode);
|
||||||
|
return code;
|
||||||
|
}
|
|
@ -0,0 +1,328 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* this file is mainly responsible for the communication between DNODEs. Each
|
||||||
|
* dnode works as both server and client. Dnode may send status, grant, config
|
||||||
|
* messages to mnode, mnode may send create/alter/drop table/vnode messages
|
||||||
|
* to dnode. All theses messages are handled from here
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
|
#include "dndTransport.h"
|
||||||
|
#include "dndDnode.h"
|
||||||
|
#include "dndMnode.h"
|
||||||
|
#include "dndVnodes.h"
|
||||||
|
|
||||||
|
static void dndInitMsgFp(STransMgmt *pMgmt) {
|
||||||
|
// msg from client to dnode
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_SUBMIT] = dndProcessVnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_QUERY] = dndProcessVnodeQueryMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_FETCH] = dndProcessVnodeFetchMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_TABLE] = dndProcessVnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_TABLE] = dndProcessVnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_TABLE] = dndProcessVnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_UPDATE_TAG_VAL] = dndProcessVnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_TABLE_META] = dndProcessVnodeQueryMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_TABLES_META] = dndProcessVnodeQueryMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_MQ_QUERY] = dndProcessVnodeQueryMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_MQ_CONSUME] = dndProcessVnodeQueryMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_MQ_CONNECT] = dndProcessVnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_MQ_DISCONNECT] = dndProcessVnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_MQ_ACK] = dndProcessVnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_MQ_RESET] = dndProcessVnodeWriteMsg;
|
||||||
|
|
||||||
|
// msg from client to mnode
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CONNECT] = dndProcessMnodeReadMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_ACCT] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_ACCT] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_ACCT] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_USER] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_USER] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_USER] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_DNODE] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CONFIG_DNODE] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_DNODE] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_DB] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_DB] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_USE_DB] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_DB] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_SYNC_DB] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_TOPIC] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_TOPIC] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_TOPIC] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_FUNCTION] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_FUNCTION] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_FUNCTION] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_STABLE] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_STABLE] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_STABLE] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_STABLE_VGROUP] = dndProcessMnodeReadMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_KILL_QUERY] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_KILL_CONN] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_HEARTBEAT] = dndProcessMnodeReadMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_SHOW] = dndProcessMnodeReadMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_SHOW_RETRIEVE] = dndProcessMnodeReadMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_SHOW_RETRIEVE_FUNC] = dndProcessMnodeReadMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_COMPACT_VNODE] = dndProcessMnodeWriteMsg;
|
||||||
|
|
||||||
|
// message from client to dnode
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_NETWORK_TEST] = dndProcessDnodeReq;
|
||||||
|
|
||||||
|
// message from mnode to vnode
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_STABLE_IN] = dndProcessVnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_STABLE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_STABLE_IN] = dndProcessVnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_STABLE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_STABLE_IN] = dndProcessVnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_STABLE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
|
||||||
|
// message from mnode to dnode
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_VNODE_IN] = dndProcessVnodeMgmtMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_VNODE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_VNODE_IN] = dndProcessVnodeMgmtMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_VNODE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_VNODE_IN] = dndProcessVnodeMgmtMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_VNODE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_SYNC_VNODE_IN] = dndProcessVnodeMgmtMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_SYNC_VNODE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_AUTH_VNODE_IN] = dndProcessVnodeMgmtMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_AUTH_VNODE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_COMPACT_VNODE_IN] = dndProcessVnodeMgmtMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_COMPACT_VNODE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_MNODE_IN] = dndProcessMnodeMgmtMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_MNODE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_MNODE_IN] = dndProcessMnodeMgmtMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_MNODE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_MNODE_IN] = dndProcessMnodeMgmtMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_MNODE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CONFIG_DNODE_IN] = dndProcessDnodeReq;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_CONFIG_DNODE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||||
|
|
||||||
|
// message from dnode to mnode
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_AUTH] = dndProcessMnodeReadMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_AUTH_RSP] = dndProcessDnodeRsp;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_GRANT] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_GRANT_RSP] = dndProcessDnodeRsp;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_STATUS] = dndProcessMnodeWriteMsg;
|
||||||
|
pMgmt->msgFp[TSDB_MSG_TYPE_STATUS_RSP] = dndProcessDnodeRsp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndProcessResponse(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||||
|
SDnode *pDnode = parent;
|
||||||
|
STransMgmt *pMgmt = &pDnode->t;
|
||||||
|
|
||||||
|
int32_t msgType = pMsg->msgType;
|
||||||
|
|
||||||
|
if (dndGetStat(pDnode) == DND_STAT_STOPPED) {
|
||||||
|
if (pMsg == NULL || pMsg->pCont == NULL) return;
|
||||||
|
dTrace("RPC %p, rsp:%s is ignored since dnode is stopping", pMsg->handle, taosMsg[msgType]);
|
||||||
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DndMsgFp fp = pMgmt->msgFp[msgType];
|
||||||
|
if (fp != NULL) {
|
||||||
|
dTrace("RPC %p, rsp:%s will be processed, code:%s", pMsg->handle, taosMsg[msgType], tstrerror(pMsg->code));
|
||||||
|
(*fp)(pDnode, pMsg, pEpSet);
|
||||||
|
} else {
|
||||||
|
dError("RPC %p, rsp:%s not processed", pMsg->handle, taosMsg[msgType]);
|
||||||
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndInitClient(SDnode *pDnode) {
|
||||||
|
STransMgmt *pMgmt = &pDnode->t;
|
||||||
|
|
||||||
|
SRpcInit rpcInit;
|
||||||
|
memset(&rpcInit, 0, sizeof(rpcInit));
|
||||||
|
rpcInit.label = "DND-C";
|
||||||
|
rpcInit.numOfThreads = 1;
|
||||||
|
rpcInit.cfp = dndProcessResponse;
|
||||||
|
rpcInit.sessions = TSDB_MAX_VNODES << 4;
|
||||||
|
rpcInit.connType = TAOS_CONN_CLIENT;
|
||||||
|
rpcInit.idleTime = pDnode->opt.shellActivityTimer * 1000;
|
||||||
|
rpcInit.user = "-internal";
|
||||||
|
rpcInit.ckey = "-key";
|
||||||
|
rpcInit.secret = "-secret";
|
||||||
|
|
||||||
|
pMgmt->clientRpc = rpcOpen(&rpcInit);
|
||||||
|
if (pMgmt->clientRpc == NULL) {
|
||||||
|
dError("failed to init rpc client");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndCleanupClient(SDnode *pDnode) {
|
||||||
|
STransMgmt *pMgmt = &pDnode->t;
|
||||||
|
if (pMgmt->clientRpc) {
|
||||||
|
rpcClose(pMgmt->clientRpc);
|
||||||
|
pMgmt->clientRpc = NULL;
|
||||||
|
dInfo("dnode peer rpc client is closed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndProcessRequest(void *param, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||||
|
SDnode *pDnode = param;
|
||||||
|
STransMgmt *pMgmt = &pDnode->t;
|
||||||
|
|
||||||
|
int32_t msgType = pMsg->msgType;
|
||||||
|
if (msgType == TSDB_MSG_TYPE_NETWORK_TEST) {
|
||||||
|
dndProcessDnodeReq(pDnode, pMsg, pEpSet);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dndGetStat(pDnode) == DND_STAT_STOPPED) {
|
||||||
|
dError("RPC %p, req:%s is ignored since dnode exiting", pMsg->handle, taosMsg[msgType]);
|
||||||
|
SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_DND_EXITING};
|
||||||
|
rpcSendResponse(&rspMsg);
|
||||||
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
return;
|
||||||
|
} else if (dndGetStat(pDnode) != DND_STAT_RUNNING) {
|
||||||
|
dError("RPC %p, req:%s is ignored since dnode not running", pMsg->handle, taosMsg[msgType]);
|
||||||
|
SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_APP_NOT_READY};
|
||||||
|
rpcSendResponse(&rspMsg);
|
||||||
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMsg->pCont == NULL) {
|
||||||
|
SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_DND_INVALID_MSG_LEN};
|
||||||
|
rpcSendResponse(&rspMsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DndMsgFp fp = pMgmt->msgFp[msgType];
|
||||||
|
if (fp != NULL) {
|
||||||
|
dTrace("RPC %p, req:%s will be processed", pMsg->handle, taosMsg[msgType]);
|
||||||
|
(*fp)(pDnode, pMsg, pEpSet);
|
||||||
|
} else {
|
||||||
|
dError("RPC %p, req:%s is not processed", pMsg->handle, taosMsg[msgType]);
|
||||||
|
SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_MSG_NOT_PROCESSED};
|
||||||
|
rpcSendResponse(&rspMsg);
|
||||||
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndSendMsgToMnodeRecv(SDnode *pDnode, SRpcMsg *pRpcMsg, SRpcMsg *pRpcRsp) {
|
||||||
|
STransMgmt *pMgmt = &pDnode->t;
|
||||||
|
|
||||||
|
SEpSet epSet = {0};
|
||||||
|
dndGetMnodeEpSet(pDnode, &epSet);
|
||||||
|
rpcSendRecv(pMgmt->clientRpc, &epSet, pRpcMsg, pRpcRsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndRetrieveUserAuthInfo(void *parent, char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
||||||
|
SDnode *pDnode = parent;
|
||||||
|
|
||||||
|
if (dndGetUserAuthFromMnode(pDnode, user, spi, encrypt, secret, ckey) != 0) {
|
||||||
|
if (terrno != TSDB_CODE_APP_NOT_READY) {
|
||||||
|
dTrace("failed to get user auth from mnode since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dDebug("user:%s, send auth msg to mnodes", user);
|
||||||
|
|
||||||
|
SAuthMsg *pMsg = rpcMallocCont(sizeof(SAuthMsg));
|
||||||
|
tstrncpy(pMsg->user, user, TSDB_USER_LEN);
|
||||||
|
|
||||||
|
SRpcMsg rpcMsg = {.pCont = pMsg, .contLen = sizeof(SAuthMsg), .msgType = TSDB_MSG_TYPE_AUTH};
|
||||||
|
SRpcMsg rpcRsp = {0};
|
||||||
|
dndSendMsgToMnodeRecv(pDnode, &rpcMsg, &rpcRsp);
|
||||||
|
|
||||||
|
if (rpcRsp.code != 0) {
|
||||||
|
terrno = rpcRsp.code;
|
||||||
|
dError("user:%s, failed to get user auth from mnodes since %s", user, terrstr());
|
||||||
|
} else {
|
||||||
|
SAuthRsp *pRsp = rpcRsp.pCont;
|
||||||
|
memcpy(secret, pRsp->secret, TSDB_KEY_LEN);
|
||||||
|
memcpy(ckey, pRsp->ckey, TSDB_KEY_LEN);
|
||||||
|
*spi = pRsp->spi;
|
||||||
|
*encrypt = pRsp->encrypt;
|
||||||
|
dDebug("user:%s, success to get user auth from mnodes", user);
|
||||||
|
}
|
||||||
|
|
||||||
|
rpcFreeCont(rpcRsp.pCont);
|
||||||
|
return rpcRsp.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndInitServer(SDnode *pDnode) {
|
||||||
|
STransMgmt *pMgmt = &pDnode->t;
|
||||||
|
dndInitMsgFp(pMgmt);
|
||||||
|
|
||||||
|
int32_t numOfThreads = (int32_t)((pDnode->opt.numOfCores * pDnode->opt.numOfThreadsPerCore) / 2.0);
|
||||||
|
if (numOfThreads < 1) {
|
||||||
|
numOfThreads = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRpcInit rpcInit;
|
||||||
|
memset(&rpcInit, 0, sizeof(rpcInit));
|
||||||
|
rpcInit.localPort = pDnode->opt.serverPort;
|
||||||
|
rpcInit.label = "DND-S";
|
||||||
|
rpcInit.numOfThreads = numOfThreads;
|
||||||
|
rpcInit.cfp = dndProcessRequest;
|
||||||
|
rpcInit.sessions = pDnode->opt.maxShellConns;
|
||||||
|
rpcInit.connType = TAOS_CONN_SERVER;
|
||||||
|
rpcInit.idleTime = pDnode->opt.shellActivityTimer * 1000;
|
||||||
|
rpcInit.afp = dndRetrieveUserAuthInfo;
|
||||||
|
|
||||||
|
pMgmt->serverRpc = rpcOpen(&rpcInit);
|
||||||
|
if (pMgmt->serverRpc == NULL) {
|
||||||
|
dError("failed to init rpc server");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndCleanupServer(SDnode *pDnode) {
|
||||||
|
STransMgmt *pMgmt = &pDnode->t;
|
||||||
|
if (pMgmt->serverRpc) {
|
||||||
|
rpcClose(pMgmt->serverRpc);
|
||||||
|
pMgmt->serverRpc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t dndInitTrans(SDnode *pDnode) {
|
||||||
|
if (dndInitClient(pDnode) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dndInitServer(pDnode) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dInfo("dnode-transport is initialized");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dndCleanupTrans(SDnode *pDnode) {
|
||||||
|
dndCleanupServer(pDnode);
|
||||||
|
dndCleanupClient(pDnode);
|
||||||
|
dInfo("dnode-transport is cleaned up");
|
||||||
|
}
|
||||||
|
|
||||||
|
void dndSendMsgToDnode(SDnode *pDnode, SEpSet *pEpSet, SRpcMsg *pMsg) {
|
||||||
|
STransMgmt *pMgmt = &pDnode->t;
|
||||||
|
rpcSendRequest(pMgmt->clientRpc, pEpSet, pMsg, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dndSendMsgToMnode(SDnode *pDnode, SRpcMsg *pMsg) {
|
||||||
|
SEpSet epSet = {0};
|
||||||
|
dndGetMnodeEpSet(pDnode, &epSet);
|
||||||
|
dndSendMsgToDnode(pDnode, &epSet, pMsg);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,608 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 "dnodeMnode.h"
|
|
||||||
#include "cJSON.h"
|
|
||||||
#include "dnodeDnode.h"
|
|
||||||
#include "dnodeTransport.h"
|
|
||||||
#include "mnode.h"
|
|
||||||
#include "tlockfree.h"
|
|
||||||
#include "tqueue.h"
|
|
||||||
#include "tstep.h"
|
|
||||||
#include "tworker.h"
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
int32_t refCount;
|
|
||||||
int8_t deployed;
|
|
||||||
int8_t dropped;
|
|
||||||
SWorkerPool mgmtPool;
|
|
||||||
SWorkerPool readPool;
|
|
||||||
SWorkerPool writePool;
|
|
||||||
SWorkerPool syncPool;
|
|
||||||
taos_queue pReadQ;
|
|
||||||
taos_queue pWriteQ;
|
|
||||||
taos_queue pApplyQ;
|
|
||||||
taos_queue pSyncQ;
|
|
||||||
taos_queue pMgmtQ;
|
|
||||||
SSteps *pSteps;
|
|
||||||
SMnode *pMnode;
|
|
||||||
SRWLatch latch;
|
|
||||||
} tsMnode = {0};
|
|
||||||
|
|
||||||
static int32_t dnodeAllocMnodeReadQueue();
|
|
||||||
static void dnodeFreeMnodeReadQueue();
|
|
||||||
static int32_t dnodeAllocMnodeWriteQueue();
|
|
||||||
static void dnodeFreeMnodeWriteQueue();
|
|
||||||
static int32_t dnodeAllocMnodeApplyQueue();
|
|
||||||
static void dnodeFreeMnodeApplyQueue();
|
|
||||||
static int32_t dnodeAllocMnodeSyncQueue();
|
|
||||||
static void dnodeFreeMnodeSyncQueue();
|
|
||||||
|
|
||||||
static SMnode *dnodeAcquireMnode() {
|
|
||||||
SMnode *pMnode = NULL;
|
|
||||||
taosRLockLatch(&tsMnode.latch);
|
|
||||||
|
|
||||||
if (tsMnode.deployed) {
|
|
||||||
atomic_add_fetch_32(&tsMnode.refCount, 1);
|
|
||||||
pMnode = tsMnode.pMnode;
|
|
||||||
}
|
|
||||||
|
|
||||||
taosRUnLockLatch(&tsMnode.latch);
|
|
||||||
return pMnode;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeReleaseMnode(SMnode *pMnode) {
|
|
||||||
taosRLockLatch(&tsMnode.latch);
|
|
||||||
atomic_sub_fetch_32(&tsMnode.refCount, 1);
|
|
||||||
taosRUnLockLatch(&tsMnode.latch);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeReadMnodeFile() {
|
|
||||||
int32_t code = TSDB_CODE_DND_READ_MNODE_FILE_ERROR;
|
|
||||||
int32_t len = 0;
|
|
||||||
int32_t maxLen = 300;
|
|
||||||
char *content = calloc(1, maxLen + 1);
|
|
||||||
cJSON *root = NULL;
|
|
||||||
FILE *fp = NULL;
|
|
||||||
char file[PATH_MAX + 20] = {0};
|
|
||||||
|
|
||||||
snprintf(file, sizeof(file), "%s/mnode.json", tsDnodeDir);
|
|
||||||
fp = fopen(file, "r");
|
|
||||||
if (!fp) {
|
|
||||||
dDebug("file %s not exist", file);
|
|
||||||
code = 0;
|
|
||||||
goto PRASE_MNODE_OVER;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = (int32_t)fread(content, 1, maxLen, fp);
|
|
||||||
if (len <= 0) {
|
|
||||||
dError("failed to read %s since content is null", file);
|
|
||||||
goto PRASE_MNODE_OVER;
|
|
||||||
}
|
|
||||||
|
|
||||||
content[len] = 0;
|
|
||||||
root = cJSON_Parse(content);
|
|
||||||
if (root == NULL) {
|
|
||||||
dError("failed to read %s since invalid json format", file);
|
|
||||||
goto PRASE_MNODE_OVER;
|
|
||||||
}
|
|
||||||
|
|
||||||
cJSON *deployed = cJSON_GetObjectItem(root, "deployed");
|
|
||||||
if (!deployed || deployed->type != cJSON_String) {
|
|
||||||
dError("failed to read %s since deployed not found", file);
|
|
||||||
goto PRASE_MNODE_OVER;
|
|
||||||
}
|
|
||||||
tsMnode.deployed = atoi(deployed->valuestring);
|
|
||||||
|
|
||||||
cJSON *dropped = cJSON_GetObjectItem(root, "dropped");
|
|
||||||
if (!dropped || dropped->type != cJSON_String) {
|
|
||||||
dError("failed to read %s since dropped not found", file);
|
|
||||||
goto PRASE_MNODE_OVER;
|
|
||||||
}
|
|
||||||
tsMnode.dropped = atoi(dropped->valuestring);
|
|
||||||
|
|
||||||
code = 0;
|
|
||||||
dInfo("succcessed to read file %s", file);
|
|
||||||
|
|
||||||
PRASE_MNODE_OVER:
|
|
||||||
if (content != NULL) free(content);
|
|
||||||
if (root != NULL) cJSON_Delete(root);
|
|
||||||
if (fp != NULL) fclose(fp);
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeWriteMnodeFile() {
|
|
||||||
char file[PATH_MAX + 20] = {0};
|
|
||||||
char realfile[PATH_MAX + 20] = {0};
|
|
||||||
snprintf(file, sizeof(file), "%s/mnode.json.bak", tsDnodeDir);
|
|
||||||
snprintf(realfile, sizeof(realfile), "%s/mnode.json", tsDnodeDir);
|
|
||||||
|
|
||||||
FILE *fp = fopen(file, "w");
|
|
||||||
if (!fp) {
|
|
||||||
dError("failed to write %s since %s", file, strerror(errno));
|
|
||||||
return TSDB_CODE_DND_WRITE_MNODE_FILE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t len = 0;
|
|
||||||
int32_t maxLen = 300;
|
|
||||||
char *content = calloc(1, maxLen + 1);
|
|
||||||
|
|
||||||
len += snprintf(content + len, maxLen - len, "{\n");
|
|
||||||
len += snprintf(content + len, maxLen - len, " \"deployed\": \"%d\",\n", tsMnode.deployed);
|
|
||||||
len += snprintf(content + len, maxLen - len, " \"dropped\": \"%d\"\n", tsMnode.dropped);
|
|
||||||
len += snprintf(content + len, maxLen - len, "}\n");
|
|
||||||
|
|
||||||
fwrite(content, 1, len, fp);
|
|
||||||
taosFsyncFile(fileno(fp));
|
|
||||||
fclose(fp);
|
|
||||||
free(content);
|
|
||||||
|
|
||||||
int32_t code = taosRenameFile(file, realfile);
|
|
||||||
if (code != 0) {
|
|
||||||
dError("failed to rename %s since %s", file, tstrerror(code));
|
|
||||||
return TSDB_CODE_DND_WRITE_MNODE_FILE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
dInfo("successed to write %s", realfile);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeStartMnode() {
|
|
||||||
int32_t code = dnodeAllocMnodeReadQueue();
|
|
||||||
if (code != 0) {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
code = dnodeAllocMnodeWriteQueue();
|
|
||||||
if (code != 0) {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
code = dnodeAllocMnodeApplyQueue();
|
|
||||||
if (code != 0) {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
code = dnodeAllocMnodeSyncQueue();
|
|
||||||
if (code != 0) {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
taosWLockLatch(&tsMnode.latch);
|
|
||||||
tsMnode.deployed = 1;
|
|
||||||
taosWUnLockLatch(&tsMnode.latch);
|
|
||||||
|
|
||||||
return mnodeStart(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeStopMnode() {
|
|
||||||
taosWLockLatch(&tsMnode.latch);
|
|
||||||
tsMnode.deployed = 0;
|
|
||||||
taosWUnLockLatch(&tsMnode.latch);
|
|
||||||
|
|
||||||
dnodeReleaseMnode();
|
|
||||||
|
|
||||||
while (tsMnode.refCount > 0) taosMsleep(10);
|
|
||||||
while (!taosQueueEmpty(tsMnode.pReadQ)) taosMsleep(10);
|
|
||||||
while (!taosQueueEmpty(tsMnode.pApplyQ)) taosMsleep(10);
|
|
||||||
while (!taosQueueEmpty(tsMnode.pWriteQ)) taosMsleep(10);
|
|
||||||
while (!taosQueueEmpty(tsMnode.pSyncQ)) taosMsleep(10);
|
|
||||||
|
|
||||||
dnodeFreeMnodeReadQueue();
|
|
||||||
dnodeFreeMnodeWriteQueue();
|
|
||||||
dnodeFreeMnodeApplyQueue();
|
|
||||||
dnodeFreeMnodeSyncQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeUnDeployMnode() {
|
|
||||||
tsMnode.dropped = 1;
|
|
||||||
int32_t code = dnodeWriteMnodeFile();
|
|
||||||
if (code != 0) {
|
|
||||||
tsMnode.dropped = 0;
|
|
||||||
dError("failed to undeploy mnode since %s", tstrerror(code));
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
dnodeStopMnode();
|
|
||||||
mnodeUnDeploy();
|
|
||||||
dnodeWriteMnodeFile();
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeDeployMnode(SMnodeCfg *pCfg) {
|
|
||||||
int32_t code = mnodeDeploy(pCfg);
|
|
||||||
if (code != 0) {
|
|
||||||
dError("failed to deploy mnode since %s", tstrerror(code));
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
code = dnodeStartMnode();
|
|
||||||
if (code != 0) {
|
|
||||||
dnodeUnDeployMnode();
|
|
||||||
dError("failed to deploy mnode since %s", tstrerror(code));
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
code = dnodeWriteMnodeFile();
|
|
||||||
if (code != 0) {
|
|
||||||
dnodeUnDeployMnode();
|
|
||||||
dError("failed to deploy mnode since %s", tstrerror(code));
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
dInfo("deploy mnode success");
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeAlterMnode(SMnodeCfg *pCfg) {
|
|
||||||
int32_t code = dnodeAcquireMnode();
|
|
||||||
if (code == 0) {
|
|
||||||
code = mnodeAlter(pCfg);
|
|
||||||
dnodeReleaseMnode();
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SCreateMnodeMsg *dnodeParseCreateMnodeMsg(SRpcMsg *pRpcMsg) {
|
|
||||||
SCreateMnodeMsg *pMsg = pRpcMsg->pCont;
|
|
||||||
pMsg->dnodeId = htonl(pMsg->dnodeId);
|
|
||||||
for (int32_t i = 0; i < pMsg->replica; ++i) {
|
|
||||||
pMsg->replicas[i].port = htons(pMsg->replicas[i].port);
|
|
||||||
}
|
|
||||||
return pMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeProcessCreateMnodeReq(SRpcMsg *pRpcMsg) {
|
|
||||||
SAlterMnodeMsg *pMsg = (SAlterMnodeMsg *)dnodeParseCreateMnodeMsg(pRpcMsg->pCont);
|
|
||||||
|
|
||||||
if (pMsg->dnodeId != dnodeGetDnodeId()) {
|
|
||||||
return TSDB_CODE_DND_MNODE_ID_NOT_MATCH_DNODE;
|
|
||||||
} else {
|
|
||||||
SMnodeCfg cfg = {0};
|
|
||||||
cfg.replica = pMsg->replica;
|
|
||||||
memcpy(cfg.replicas, pMsg->replicas, sizeof(SReplica) * sizeof(TSDB_MAX_REPLICA));
|
|
||||||
return dnodeDeployMnode(&cfg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeProcessAlterMnodeReq(SRpcMsg *pRpcMsg) {
|
|
||||||
SAlterMnodeMsg *pMsg = (SAlterMnodeMsg *)dnodeParseCreateMnodeMsg(pRpcMsg->pCont);
|
|
||||||
if (pMsg->dnodeId != dnodeGetDnodeId()) {
|
|
||||||
return TSDB_CODE_DND_MNODE_ID_NOT_MATCH_DNODE;
|
|
||||||
} else {
|
|
||||||
SMnodeCfg cfg = {0};
|
|
||||||
cfg.replica = pMsg->replica;
|
|
||||||
memcpy(cfg.replicas, pMsg->replicas, sizeof(SReplica) * sizeof(TSDB_MAX_REPLICA));
|
|
||||||
return dnodeAlterMnode(&cfg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeProcessDropMnodeReq(SRpcMsg *pMsg) {
|
|
||||||
SAlterMnodeMsg *pCfg = pMsg->pCont;
|
|
||||||
pCfg->dnodeId = htonl(pCfg->dnodeId);
|
|
||||||
|
|
||||||
if (pCfg->dnodeId != dnodeGetDnodeId()) {
|
|
||||||
return TSDB_CODE_DND_MNODE_ID_NOT_MATCH_DNODE;
|
|
||||||
} else {
|
|
||||||
return dnodeUnDeployMnode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeProcessMnodeMgmtQueue(void *unused, SRpcMsg *pMsg) {
|
|
||||||
int32_t code = 0;
|
|
||||||
|
|
||||||
switch (pMsg->msgType) {
|
|
||||||
case TSDB_MSG_TYPE_CREATE_MNODE_IN:
|
|
||||||
code = dnodeProcessCreateMnodeReq(pMsg);
|
|
||||||
break;
|
|
||||||
case TSDB_MSG_TYPE_ALTER_MNODE_IN:
|
|
||||||
code = dnodeProcessAlterMnodeReq(pMsg);
|
|
||||||
break;
|
|
||||||
case TSDB_MSG_TYPE_DROP_MNODE_IN:
|
|
||||||
code = dnodeProcessDropMnodeReq(pMsg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
code = TSDB_CODE_DND_MSG_NOT_PROCESSED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SRpcMsg rsp = {.code = code, .handle = pMsg->handle};
|
|
||||||
rpcSendResponse(&rsp);
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
|
||||||
taosFreeQitem(pMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeProcessMnodeReadQueue(void *unused, SMnodeMsg *pMsg) { mnodeProcessMsg(pMsg, MN_MSG_TYPE_READ); }
|
|
||||||
|
|
||||||
static void dnodeProcessMnodeWriteQueue(void *unused, SMnodeMsg *pMsg) { mnodeProcessMsg(pMsg, MN_MSG_TYPE_WRITE); }
|
|
||||||
|
|
||||||
static void dnodeProcessMnodeApplyQueue(void *unused, SMnodeMsg *pMsg) { mnodeProcessMsg(pMsg, MN_MSG_TYPE_APPLY); }
|
|
||||||
|
|
||||||
static void dnodeProcessMnodeSyncQueue(void *unused, SMnodeMsg *pMsg) { mnodeProcessMsg(pMsg, MN_MSG_TYPE_SYNC); }
|
|
||||||
|
|
||||||
static int32_t dnodeWriteMnodeMsgToQueue(taos_queue pQueue, SRpcMsg *pRpcMsg) {
|
|
||||||
int32_t code = 0;
|
|
||||||
SMnodeMsg *pMsg = NULL;
|
|
||||||
|
|
||||||
if (pQueue == NULL) {
|
|
||||||
code = TSDB_CODE_DND_MSG_NOT_PROCESSED;
|
|
||||||
} else {
|
|
||||||
pMsg = mnodeInitMsg(pRpcMsg);
|
|
||||||
if (pMsg == NULL) {
|
|
||||||
code = terrno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (code == 0) {
|
|
||||||
code = taosWriteQitem(pQueue, pMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
|
||||||
SRpcMsg rsp = {.handle = pRpcMsg->handle, .code = code};
|
|
||||||
rpcSendResponse(&rsp);
|
|
||||||
rpcFreeCont(pRpcMsg->pCont);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dnodeProcessMnodeMgmtMsg(SRpcMsg *pMsg, SEpSet *pEpSet) { dnodeWriteMnodeMsgToQueue(tsMnode.pMgmtQ, pMsg); }
|
|
||||||
|
|
||||||
void dnodeProcessMnodeWriteMsg(SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|
||||||
if (dnodeAcquireMnode() == 0) {
|
|
||||||
dnodeWriteMnodeMsgToQueue(tsMnode.pWriteQ, pMsg);
|
|
||||||
dnodeReleaseMnode();
|
|
||||||
} else {
|
|
||||||
dnodeSendRedirectMsg(NULL, pMsg, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dnodeProcessMnodeSyncMsg(SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|
||||||
int32_t code = dnodeAcquireMnode();
|
|
||||||
if (code == 0) {
|
|
||||||
dnodeWriteMnodeMsgToQueue(tsMnode.pSyncQ, pMsg);
|
|
||||||
dnodeReleaseMnode();
|
|
||||||
} else {
|
|
||||||
SRpcMsg rsp = {.handle = pMsg->handle, .code = code};
|
|
||||||
rpcSendResponse(&rsp);
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dnodeProcessMnodeReadMsg(SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|
||||||
if (dnodeAcquireMnode() == 0) {
|
|
||||||
dnodeWriteMnodeMsgToQueue(tsMnode.pReadQ, pMsg);
|
|
||||||
dnodeReleaseMnode();
|
|
||||||
} else {
|
|
||||||
dnodeSendRedirectMsg(NULL, pMsg, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodePutMsgIntoMnodeApplyQueue(SMnodeMsg *pMsg) {
|
|
||||||
int32_t code = dnodeAcquireMnode();
|
|
||||||
if (code != 0) return code;
|
|
||||||
|
|
||||||
code = taosWriteQitem(tsMnode.pApplyQ, pMsg);
|
|
||||||
dnodeReleaseMnode();
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeAllocMnodeMgmtQueue() {
|
|
||||||
tsMnode.pMgmtQ = tWorkerAllocQueue(&tsMnode.mgmtPool, NULL, (FProcessItem)dnodeProcessMnodeMgmtQueue);
|
|
||||||
if (tsMnode.pMgmtQ == NULL) {
|
|
||||||
return TSDB_CODE_DND_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeFreeMnodeMgmtQueue() {
|
|
||||||
tWorkerFreeQueue(&tsMnode.mgmtPool, tsMnode.pMgmtQ);
|
|
||||||
tsMnode.pMgmtQ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeInitMnodeMgmtWorker() {
|
|
||||||
SWorkerPool *pPool = &tsMnode.mgmtPool;
|
|
||||||
pPool->name = "mnode-mgmt";
|
|
||||||
pPool->min = 1;
|
|
||||||
pPool->max = 1;
|
|
||||||
return tWorkerInit(pPool);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeCleanupMnodeMgmtWorker() { tWorkerCleanup(&tsMnode.mgmtPool); }
|
|
||||||
|
|
||||||
static int32_t dnodeAllocMnodeReadQueue() {
|
|
||||||
tsMnode.pReadQ = tWorkerAllocQueue(&tsMnode.readPool, NULL, (FProcessItem)dnodeProcessMnodeReadQueue);
|
|
||||||
if (tsMnode.pReadQ == NULL) {
|
|
||||||
return TSDB_CODE_DND_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeFreeMnodeReadQueue() {
|
|
||||||
tWorkerFreeQueue(&tsMnode.readPool, tsMnode.pReadQ);
|
|
||||||
tsMnode.pReadQ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeInitMnodeReadWorker() {
|
|
||||||
SWorkerPool *pPool = &tsMnode.readPool;
|
|
||||||
pPool->name = "mnode-read";
|
|
||||||
pPool->min = 0;
|
|
||||||
pPool->max = 1;
|
|
||||||
return tWorkerInit(pPool);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeCleanupMnodeReadWorker() { tWorkerCleanup(&tsMnode.readPool); }
|
|
||||||
|
|
||||||
static int32_t dnodeAllocMnodeWriteQueue() {
|
|
||||||
tsMnode.pWriteQ = tWorkerAllocQueue(&tsMnode.writePool, NULL, (FProcessItem)dnodeProcessMnodeWriteQueue);
|
|
||||||
if (tsMnode.pWriteQ == NULL) {
|
|
||||||
return TSDB_CODE_DND_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeFreeMnodeWriteQueue() {
|
|
||||||
tWorkerFreeQueue(&tsMnode.writePool, tsMnode.pWriteQ);
|
|
||||||
tsMnode.pWriteQ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeAllocMnodeApplyQueue() {
|
|
||||||
tsMnode.pApplyQ = tWorkerAllocQueue(&tsMnode.writePool, NULL, (FProcessItem)dnodeProcessMnodeApplyQueue);
|
|
||||||
if (tsMnode.pApplyQ == NULL) {
|
|
||||||
return TSDB_CODE_DND_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeFreeMnodeApplyQueue() {
|
|
||||||
tWorkerFreeQueue(&tsMnode.writePool, tsMnode.pApplyQ);
|
|
||||||
tsMnode.pApplyQ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeInitMnodeWriteWorker() {
|
|
||||||
SWorkerPool *pPool = &tsMnode.writePool;
|
|
||||||
pPool->name = "mnode-write";
|
|
||||||
pPool->min = 0;
|
|
||||||
pPool->max = 1;
|
|
||||||
return tWorkerInit(pPool);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeCleanupMnodeWriteWorker() { tWorkerCleanup(&tsMnode.writePool); }
|
|
||||||
|
|
||||||
static int32_t dnodeAllocMnodeSyncQueue() {
|
|
||||||
tsMnode.pSyncQ = tWorkerAllocQueue(&tsMnode.syncPool, NULL, (FProcessItem)dnodeProcessMnodeSyncQueue);
|
|
||||||
if (tsMnode.pSyncQ == NULL) {
|
|
||||||
return TSDB_CODE_DND_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeFreeMnodeSyncQueue() {
|
|
||||||
tWorkerFreeQueue(&tsMnode.syncPool, tsMnode.pSyncQ);
|
|
||||||
tsMnode.pSyncQ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeInitMnodeSyncWorker() {
|
|
||||||
SWorkerPool *pPool = &tsMnode.syncPool;
|
|
||||||
pPool->name = "mnode-sync";
|
|
||||||
pPool->min = 0;
|
|
||||||
pPool->max = 1;
|
|
||||||
return tWorkerInit(pPool);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeCleanupMnodeSyncWorker() { tWorkerCleanup(&tsMnode.syncPool); }
|
|
||||||
|
|
||||||
static int32_t dnodeInitMnodeModule() {
|
|
||||||
taosInitRWLatch(&tsMnode.latch);
|
|
||||||
|
|
||||||
SMnodeOptions para;
|
|
||||||
para.dnodeId = dnodeGetDnodeId();
|
|
||||||
para.clusterId = dnodeGetClusterId();
|
|
||||||
para.sendMsgToDnodeFp = dnodeSendMsgToDnode;
|
|
||||||
para.sendMsgToMnodeFp = dnodeSendMsgToMnode;
|
|
||||||
para.sendRedirectMsgFp = dnodeSendRedirectMsg;
|
|
||||||
|
|
||||||
tsMnode.pMnode = mnodeCreate(para);
|
|
||||||
if (tsMnode.pMnode != NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeCleanupMnodeModule() { mnodeDrop(NULL); }
|
|
||||||
|
|
||||||
static bool dnodeNeedDeployMnode() {
|
|
||||||
if (dnodeGetDnodeId() > 0) return false;
|
|
||||||
if (dnodeGetClusterId() > 0) return false;
|
|
||||||
if (strcmp(tsFirst, tsLocalEp) != 0) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeOpenMnode() {
|
|
||||||
int32_t code = dnodeReadMnodeFile();
|
|
||||||
if (code != 0) {
|
|
||||||
dError("failed to read open mnode since %s", tstrerror(code));
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tsMnode.dropped) {
|
|
||||||
dInfo("mnode already dropped, undeploy it");
|
|
||||||
return dnodeUnDeployMnode();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tsMnode.deployed) {
|
|
||||||
bool needDeploy = dnodeNeedDeployMnode();
|
|
||||||
if (!needDeploy) return 0;
|
|
||||||
|
|
||||||
dInfo("start to deploy mnode");
|
|
||||||
SMnodeCfg cfg = {.replica = 1};
|
|
||||||
cfg.replicas[0].port = tsServerPort;
|
|
||||||
tstrncpy(cfg.replicas[0].fqdn, tsLocalFqdn, TSDB_FQDN_LEN);
|
|
||||||
code = dnodeDeployMnode(&cfg);
|
|
||||||
} else {
|
|
||||||
dInfo("start to open mnode");
|
|
||||||
return dnodeStartMnode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeCloseMnode() {
|
|
||||||
if (dnodeAcquireMnode() == 0) {
|
|
||||||
dnodeStopMnode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t dnodeInitMnode() {
|
|
||||||
dInfo("dnode-mnode start to init");
|
|
||||||
|
|
||||||
SSteps *pSteps = taosStepInit(6, dnodeReportStartup);
|
|
||||||
taosStepAdd(pSteps, "dnode-mnode-env", dnodeInitMnodeModule, dnodeCleanupMnodeModule);
|
|
||||||
taosStepAdd(pSteps, "dnode-mnode-mgmt", dnodeInitMnodeMgmtWorker, dnodeCleanupMnodeMgmtWorker);
|
|
||||||
taosStepAdd(pSteps, "dnode-mnode-read", dnodeInitMnodeReadWorker, dnodeCleanupMnodeReadWorker);
|
|
||||||
taosStepAdd(pSteps, "dnode-mnode-write", dnodeInitMnodeWriteWorker, dnodeCleanupMnodeWriteWorker);
|
|
||||||
taosStepAdd(pSteps, "dnode-mnode-sync", dnodeInitMnodeSyncWorker, dnodeCleanupMnodeSyncWorker);
|
|
||||||
taosStepAdd(pSteps, "dnode-mnode", dnodeOpenMnode, dnodeCloseMnode);
|
|
||||||
|
|
||||||
tsMnode.pSteps = pSteps;
|
|
||||||
int32_t code = taosStepExec(pSteps);
|
|
||||||
|
|
||||||
if (code != 0) {
|
|
||||||
dError("dnode-mnode init failed since %s", tstrerror(code));
|
|
||||||
} else {
|
|
||||||
dInfo("dnode-mnode is initialized");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dnodeCleanupMnode() {
|
|
||||||
if (tsMnode.pSteps == NULL) {
|
|
||||||
dInfo("dnode-mnode start to clean up");
|
|
||||||
taosStepCleanup(tsMnode.pSteps);
|
|
||||||
tsMnode.pSteps = NULL;
|
|
||||||
dInfo("dnode-mnode is cleaned up");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t dnodeGetUserAuthFromMnode(char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
|
||||||
SMnode *pMnode = dnodeAcquireMnode();
|
|
||||||
if (pMnode == NULL) {
|
|
||||||
dTrace("failed to get user auth since mnode not deployed");
|
|
||||||
terrno = TSDB_CODE_DND_MNODE_NOT_DEPLOYED;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t code = mnodeRetriveAuth(pMnode, user, spi, encrypt, secret, ckey);
|
|
||||||
dnodeReleaseMnode(pMnode);
|
|
||||||
return code;
|
|
||||||
}
|
|
|
@ -1,395 +0,0 @@
|
||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* this file is mainly responsible for the communication between DNODEs. Each
|
|
||||||
* dnode works as both server and client. Dnode may send status, grant, config
|
|
||||||
* messages to mnode, mnode may send create/alter/drop table/vnode messages
|
|
||||||
* to dnode. All theses messages are handled from here
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
|
||||||
#include "dnodeTransport.h"
|
|
||||||
#include "dnodeDnode.h"
|
|
||||||
#include "dnodeMnode.h"
|
|
||||||
#include "dnodeVnodes.h"
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
void *peerRpc;
|
|
||||||
void *shellRpc;
|
|
||||||
void *clientRpc;
|
|
||||||
MsgFp msgFp[TSDB_MSG_TYPE_MAX];
|
|
||||||
} tsTrans;
|
|
||||||
|
|
||||||
static void dnodeInitMsgFp() {
|
|
||||||
// msg from client to dnode
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_SUBMIT] = dnodeProcessVnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_QUERY] = dnodeProcessVnodeQueryMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_FETCH] = dnodeProcessVnodeFetchMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_TABLE] = dnodeProcessVnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_TABLE] = dnodeProcessVnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_TABLE] = dnodeProcessVnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_UPDATE_TAG_VAL] = dnodeProcessVnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_TABLE_META] = dnodeProcessVnodeQueryMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_TABLES_META] = dnodeProcessVnodeQueryMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_MQ_QUERY] = dnodeProcessVnodeQueryMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_MQ_CONSUME] = dnodeProcessVnodeQueryMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_MQ_CONNECT] = dnodeProcessVnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_MQ_DISCONNECT] = dnodeProcessVnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_MQ_ACK] = dnodeProcessVnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_MQ_RESET] = dnodeProcessVnodeWriteMsg;
|
|
||||||
|
|
||||||
// msg from client to mnode
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CONNECT] = dnodeProcessMnodeReadMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_ACCT] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_ACCT] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_ACCT] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_USER] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_USER] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_USER] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_DNODE] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CONFIG_DNODE] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_DNODE] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_DB] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_DB] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_USE_DB] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_DB] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_SYNC_DB] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_TOPIC] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_TOPIC] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_TOPIC] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_FUNCTION] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_FUNCTION] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_FUNCTION] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_STABLE] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_STABLE] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_STABLE] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_STABLE_VGROUP] = dnodeProcessMnodeReadMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_KILL_QUERY] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_KILL_CONN] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_HEARTBEAT] = dnodeProcessMnodeReadMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_SHOW] = dnodeProcessMnodeReadMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_SHOW_RETRIEVE] = dnodeProcessMnodeReadMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_SHOW_RETRIEVE_FUNC] = dnodeProcessMnodeReadMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_COMPACT_VNODE] = dnodeProcessMnodeWriteMsg;
|
|
||||||
|
|
||||||
// message from client to dnode
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_NETWORK_TEST] = dnodeProcessDnodeMsg;
|
|
||||||
|
|
||||||
// message from mnode to vnode
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_STABLE_IN] = dnodeProcessVnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_STABLE_IN_RSP] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_STABLE_IN] = dnodeProcessVnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_STABLE_IN_RSP] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_STABLE_IN] = dnodeProcessVnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_STABLE_IN] = dnodeProcessMnodeWriteMsg;
|
|
||||||
|
|
||||||
// message from mnode to dnode
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_VNODE_IN] = dnodeProcessVnodeMgmtMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_VNODE_IN_RSP] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_VNODE_IN] = dnodeProcessVnodeMgmtMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_VNODE_IN_RSP] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_VNODE_IN] = dnodeProcessVnodeMgmtMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_VNODE_IN_RSP] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_SYNC_VNODE_IN] = dnodeProcessVnodeMgmtMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_SYNC_VNODE_IN_RSP] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_AUTH_VNODE_IN] = dnodeProcessVnodeMgmtMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_AUTH_VNODE_IN_RSP] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_COMPACT_VNODE_IN] = dnodeProcessVnodeMgmtMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_COMPACT_VNODE_IN_RSP] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_MNODE_IN] = dnodeProcessMnodeMgmtMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CREATE_MNODE_IN_RSP] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_MNODE_IN] = dnodeProcessMnodeMgmtMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_ALTER_MNODE_IN_RSP] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_MNODE_IN] = dnodeProcessMnodeMgmtMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_DROP_MNODE_IN_RSP] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CONFIG_DNODE_IN] = dnodeProcessDnodeMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_CONFIG_DNODE_IN_RSP] = dnodeProcessMnodeWriteMsg;
|
|
||||||
|
|
||||||
// message from dnode to mnode
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_AUTH] = dnodeProcessMnodeReadMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_AUTH_RSP] = dnodeProcessDnodeMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_GRANT] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_GRANT_RSP] = dnodeProcessDnodeMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_STATUS] = dnodeProcessMnodeWriteMsg;
|
|
||||||
tsTrans.msgFp[TSDB_MSG_TYPE_STATUS_RSP] = dnodeProcessDnodeMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeProcessPeerReq(SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|
||||||
SRpcMsg rspMsg = {.handle = pMsg->handle};
|
|
||||||
int32_t msgType = pMsg->msgType;
|
|
||||||
|
|
||||||
if (msgType == TSDB_MSG_TYPE_NETWORK_TEST) {
|
|
||||||
dnodeProcessDnodeMsg(pMsg, pEpSet);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dnodeGetStat() != DN_STAT_RUNNING) {
|
|
||||||
rspMsg.code = TSDB_CODE_APP_NOT_READY;
|
|
||||||
rpcSendResponse(&rspMsg);
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
|
||||||
dTrace("RPC %p, peer req:%s is ignored since dnode not running", pMsg->handle, taosMsg[msgType]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pMsg->pCont == NULL) {
|
|
||||||
rspMsg.code = TSDB_CODE_DND_INVALID_MSG_LEN;
|
|
||||||
rpcSendResponse(&rspMsg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MsgFp fp = tsTrans.msgFp[msgType];
|
|
||||||
if (fp != NULL) {
|
|
||||||
dTrace("RPC %p, peer req:%s will be processed", pMsg->handle, taosMsg[msgType]);
|
|
||||||
(*fp)(pMsg, pEpSet);
|
|
||||||
} else {
|
|
||||||
dError("RPC %p, peer req:%s not processed", pMsg->handle, taosMsg[msgType]);
|
|
||||||
rspMsg.code = TSDB_CODE_DND_MSG_NOT_PROCESSED;
|
|
||||||
rpcSendResponse(&rspMsg);
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeInitPeerServer() {
|
|
||||||
SRpcInit rpcInit;
|
|
||||||
memset(&rpcInit, 0, sizeof(rpcInit));
|
|
||||||
rpcInit.localPort = tsDnodeDnodePort;
|
|
||||||
rpcInit.label = "DND-S";
|
|
||||||
rpcInit.numOfThreads = 1;
|
|
||||||
rpcInit.cfp = dnodeProcessPeerReq;
|
|
||||||
rpcInit.sessions = TSDB_MAX_VNODES << 4;
|
|
||||||
rpcInit.connType = TAOS_CONN_SERVER;
|
|
||||||
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
|
||||||
|
|
||||||
tsTrans.peerRpc = rpcOpen(&rpcInit);
|
|
||||||
if (tsTrans.peerRpc == NULL) {
|
|
||||||
dError("failed to init peer rpc server");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dInfo("dnode peer rpc server is initialized");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeCleanupPeerServer() {
|
|
||||||
if (tsTrans.peerRpc) {
|
|
||||||
rpcClose(tsTrans.peerRpc);
|
|
||||||
tsTrans.peerRpc = NULL;
|
|
||||||
dInfo("dnode peer server is closed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeProcessPeerRsp(SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|
||||||
int32_t msgType = pMsg->msgType;
|
|
||||||
|
|
||||||
if (dnodeGetStat() == DN_STAT_STOPPED) {
|
|
||||||
if (pMsg == NULL || pMsg->pCont == NULL) return;
|
|
||||||
dTrace("RPC %p, peer rsp:%s is ignored since dnode is stopping", pMsg->handle, taosMsg[msgType]);
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MsgFp fp = tsTrans.msgFp[msgType];
|
|
||||||
if (fp != NULL) {
|
|
||||||
dTrace("RPC %p, peer rsp:%s will be processed, code:%s", pMsg->handle, taosMsg[msgType], tstrerror(pMsg->code));
|
|
||||||
(*fp)(pMsg, pEpSet);
|
|
||||||
} else {
|
|
||||||
dDebug("RPC %p, peer rsp:%s not processed", pMsg->handle, taosMsg[msgType]);
|
|
||||||
}
|
|
||||||
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeInitClient() {
|
|
||||||
char secret[TSDB_KEY_LEN] = "secret";
|
|
||||||
|
|
||||||
SRpcInit rpcInit;
|
|
||||||
memset(&rpcInit, 0, sizeof(rpcInit));
|
|
||||||
rpcInit.label = "DND-C";
|
|
||||||
rpcInit.numOfThreads = 1;
|
|
||||||
rpcInit.cfp = dnodeProcessPeerRsp;
|
|
||||||
rpcInit.sessions = TSDB_MAX_VNODES << 4;
|
|
||||||
rpcInit.connType = TAOS_CONN_CLIENT;
|
|
||||||
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
|
||||||
rpcInit.user = "t";
|
|
||||||
rpcInit.ckey = "key";
|
|
||||||
rpcInit.secret = secret;
|
|
||||||
|
|
||||||
tsTrans.clientRpc = rpcOpen(&rpcInit);
|
|
||||||
if (tsTrans.clientRpc == NULL) {
|
|
||||||
dError("failed to init peer rpc client");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dInfo("dnode peer rpc client is initialized");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeCleanupClient() {
|
|
||||||
if (tsTrans.clientRpc) {
|
|
||||||
rpcClose(tsTrans.clientRpc);
|
|
||||||
tsTrans.clientRpc = NULL;
|
|
||||||
dInfo("dnode peer rpc client is closed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeProcessShellReq(SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|
||||||
SRpcMsg rspMsg = {.handle = pMsg->handle};
|
|
||||||
int32_t msgType = pMsg->msgType;
|
|
||||||
|
|
||||||
if (dnodeGetStat() == DN_STAT_STOPPED) {
|
|
||||||
dError("RPC %p, shell req:%s is ignored since dnode exiting", pMsg->handle, taosMsg[msgType]);
|
|
||||||
rspMsg.code = TSDB_CODE_DND_EXITING;
|
|
||||||
rpcSendResponse(&rspMsg);
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
|
||||||
return;
|
|
||||||
} else if (dnodeGetStat() != DN_STAT_RUNNING) {
|
|
||||||
dError("RPC %p, shell req:%s is ignored since dnode not running", pMsg->handle, taosMsg[msgType]);
|
|
||||||
rspMsg.code = TSDB_CODE_APP_NOT_READY;
|
|
||||||
rpcSendResponse(&rspMsg);
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pMsg->pCont == NULL) {
|
|
||||||
rspMsg.code = TSDB_CODE_DND_INVALID_MSG_LEN;
|
|
||||||
rpcSendResponse(&rspMsg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MsgFp fp = tsTrans.msgFp[msgType];
|
|
||||||
if (fp != NULL) {
|
|
||||||
dTrace("RPC %p, shell req:%s will be processed", pMsg->handle, taosMsg[msgType]);
|
|
||||||
(*fp)(pMsg, pEpSet);
|
|
||||||
} else {
|
|
||||||
dError("RPC %p, shell req:%s is not processed", pMsg->handle, taosMsg[msgType]);
|
|
||||||
rspMsg.code = TSDB_CODE_DND_MSG_NOT_PROCESSED;
|
|
||||||
rpcSendResponse(&rspMsg);
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeSendMsgToMnodeRecv(SRpcMsg *rpcMsg, SRpcMsg *rpcRsp) {
|
|
||||||
SEpSet epSet = {0};
|
|
||||||
dnodeGetMnodeEpSetForPeer(&epSet);
|
|
||||||
rpcSendRecv(tsTrans.clientRpc, &epSet, rpcMsg, rpcRsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeRetrieveUserAuthInfo(char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
|
||||||
int32_t code = dnodeGetUserAuthFromMnode(user, spi, encrypt, secret, ckey);
|
|
||||||
if (code != TSDB_CODE_APP_NOT_READY) return code;
|
|
||||||
|
|
||||||
SAuthMsg *pMsg = rpcMallocCont(sizeof(SAuthMsg));
|
|
||||||
tstrncpy(pMsg->user, user, sizeof(pMsg->user));
|
|
||||||
|
|
||||||
dDebug("user:%s, send auth msg to mnodes", user);
|
|
||||||
SRpcMsg rpcMsg = {.pCont = pMsg, .contLen = sizeof(SAuthMsg), .msgType = TSDB_MSG_TYPE_AUTH};
|
|
||||||
SRpcMsg rpcRsp = {0};
|
|
||||||
dnodeSendMsgToMnodeRecv(&rpcMsg, &rpcRsp);
|
|
||||||
|
|
||||||
if (rpcRsp.code != 0) {
|
|
||||||
dError("user:%s, auth msg received from mnodes, error:%s", user, tstrerror(rpcRsp.code));
|
|
||||||
} else {
|
|
||||||
dDebug("user:%s, auth msg received from mnodes", user);
|
|
||||||
SAuthRsp *pRsp = rpcRsp.pCont;
|
|
||||||
memcpy(secret, pRsp->secret, TSDB_KEY_LEN);
|
|
||||||
memcpy(ckey, pRsp->ckey, TSDB_KEY_LEN);
|
|
||||||
*spi = pRsp->spi;
|
|
||||||
*encrypt = pRsp->encrypt;
|
|
||||||
}
|
|
||||||
|
|
||||||
rpcFreeCont(rpcRsp.pCont);
|
|
||||||
return rpcRsp.code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dnodeInitShellServer() {
|
|
||||||
dnodeInitMsgFp();
|
|
||||||
|
|
||||||
int32_t numOfThreads = (int32_t)((tsNumOfCores * tsNumOfThreadsPerCore) / 2.0);
|
|
||||||
if (numOfThreads < 1) {
|
|
||||||
numOfThreads = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SRpcInit rpcInit;
|
|
||||||
memset(&rpcInit, 0, sizeof(rpcInit));
|
|
||||||
rpcInit.localPort = tsDnodeShellPort;
|
|
||||||
rpcInit.label = "SHELL";
|
|
||||||
rpcInit.numOfThreads = numOfThreads;
|
|
||||||
rpcInit.cfp = dnodeProcessShellReq;
|
|
||||||
rpcInit.sessions = tsMaxShellConns;
|
|
||||||
rpcInit.connType = TAOS_CONN_SERVER;
|
|
||||||
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
|
||||||
rpcInit.afp = dnodeRetrieveUserAuthInfo;
|
|
||||||
|
|
||||||
tsTrans.shellRpc = rpcOpen(&rpcInit);
|
|
||||||
if (tsTrans.shellRpc == NULL) {
|
|
||||||
dError("failed to init shell rpc server");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
SRpcMsg rpcMsg = {0};
|
|
||||||
rpcMsg.msgType = TSDB_MSG_TYPE_CREATE_USER;
|
|
||||||
rpcMsg.contLen = sizeof(SCreateUserMsg);
|
|
||||||
rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen);
|
|
||||||
SCreateUserMsg *pMsg = (SCreateUserMsg*)rpcMsg.pCont;
|
|
||||||
strcpy(pMsg->user, "u1");
|
|
||||||
strcpy(pMsg->pass, "up1");
|
|
||||||
dnodeProcessShellReq(&rpcMsg, NULL);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
dInfo("dnode shell rpc server is initialized");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnodeCleanupShellServer() {
|
|
||||||
if (tsTrans.shellRpc) {
|
|
||||||
rpcClose(tsTrans.shellRpc);
|
|
||||||
tsTrans.shellRpc = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t dnodeInitTrans() {
|
|
||||||
if (dnodeInitClient() != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dnodeInitPeerServer() != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dnodeInitShellServer() != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dnodeCleanupTrans() {
|
|
||||||
dnodeCleanupShellServer();
|
|
||||||
dnodeCleanupPeerServer();
|
|
||||||
dnodeCleanupClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
void dnodeSendMsgToDnode(SDnode *pDnode, SEpSet *epSet, SRpcMsg *rpcMsg) {
|
|
||||||
#if 0
|
|
||||||
rpcSendRequest(tsTrans.clientRpc, epSet, rpcMsg, NULL);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void dnodeSendMsgToMnode(SDnode *pDnode, SRpcMsg *rpcMsg) {
|
|
||||||
SEpSet epSet = {0};
|
|
||||||
dnodeGetMnodeEpSetForPeer(&epSet);
|
|
||||||
dnodeSendMsgToDnode(NULL, &epSet, rpcMsg);
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -131,7 +131,7 @@ typedef struct SMnodeObj {
|
||||||
int64_t roleTime;
|
int64_t roleTime;
|
||||||
int64_t createdTime;
|
int64_t createdTime;
|
||||||
int64_t updateTime;
|
int64_t updateTime;
|
||||||
SDnodeObj *pDnode;
|
SDnodeObj *pDnd;
|
||||||
} SMnodeObj;
|
} SMnodeObj;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -215,7 +215,7 @@ typedef struct SDbObj {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t dnodeId;
|
int32_t dnodeId;
|
||||||
int8_t role;
|
int8_t role;
|
||||||
SDnodeObj *pDnode;
|
SDnodeObj *pDnd;
|
||||||
} SVnodeGid;
|
} SVnodeGid;
|
||||||
|
|
||||||
typedef struct SVgObj {
|
typedef struct SVgObj {
|
||||||
|
|
|
@ -83,7 +83,7 @@ static int32_t mnodeSetOptions(SMnode *pMnode, const SMnodeOptions *pOptions) {
|
||||||
pMnode->replica = pOptions->replica;
|
pMnode->replica = pOptions->replica;
|
||||||
pMnode->selfIndex = pOptions->selfIndex;
|
pMnode->selfIndex = pOptions->selfIndex;
|
||||||
memcpy(&pMnode->replicas, pOptions->replicas, sizeof(SReplica) * TSDB_MAX_REPLICA);
|
memcpy(&pMnode->replicas, pOptions->replicas, sizeof(SReplica) * TSDB_MAX_REPLICA);
|
||||||
pMnode->pServer = pOptions->pServer;
|
pMnode->pServer = pOptions->pDnode;
|
||||||
pMnode->putMsgToApplyMsgFp = pOptions->putMsgToApplyMsgFp;
|
pMnode->putMsgToApplyMsgFp = pOptions->putMsgToApplyMsgFp;
|
||||||
pMnode->sendMsgToDnodeFp = pOptions->sendMsgToDnodeFp;
|
pMnode->sendMsgToDnodeFp = pOptions->sendMsgToDnodeFp;
|
||||||
pMnode->sendMsgToMnodeFp = pOptions->sendMsgToMnodeFp;
|
pMnode->sendMsgToMnodeFp = pOptions->sendMsgToMnodeFp;
|
||||||
|
@ -187,7 +187,7 @@ SMnodeMsg *mnodeInitMsg(SMnode *pMnode, SRpcMsg *pRpcMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rpcGetConnInfo(pRpcMsg->handle, &pMsg->conn) != 0) {
|
if (rpcGetConnInfo(pRpcMsg->handle, &pMsg->conn) != 0) {
|
||||||
mnodeCleanupMsg(pMnode, pMsg);
|
mnodeCleanupMsg(pMsg);
|
||||||
mError("can not get user from conn:%p", pMsg->rpcMsg.handle);
|
mError("can not get user from conn:%p", pMsg->rpcMsg.handle);
|
||||||
terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
|
terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -199,7 +199,7 @@ SMnodeMsg *mnodeInitMsg(SMnode *pMnode, SRpcMsg *pRpcMsg) {
|
||||||
return pMsg;
|
return pMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mnodeCleanupMsg(SMnode *pMnode, SMnodeMsg *pMsg) {
|
void mnodeCleanupMsg(SMnodeMsg *pMsg) {
|
||||||
if (pMsg->pUser != NULL) {
|
if (pMsg->pUser != NULL) {
|
||||||
sdbRelease(pMsg->pUser);
|
sdbRelease(pMsg->pUser);
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ void mnodeCleanupMsg(SMnode *pMnode, SMnodeMsg *pMsg) {
|
||||||
static void mnodeProcessRpcMsg(SMnodeMsg *pMsg) {
|
static void mnodeProcessRpcMsg(SMnodeMsg *pMsg) {
|
||||||
if (!mnodeIsMaster()) {
|
if (!mnodeIsMaster()) {
|
||||||
mnodeSendRedirectMsg(NULL, &pMsg->rpcMsg, true);
|
mnodeSendRedirectMsg(NULL, &pMsg->rpcMsg, true);
|
||||||
mnodeCleanupMsg(NULL, pMsg);
|
mnodeCleanupMsg(pMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,10 +54,11 @@ typedef struct {
|
||||||
char secret[TSDB_KEY_LEN]; // secret for the link
|
char secret[TSDB_KEY_LEN]; // secret for the link
|
||||||
char ckey[TSDB_KEY_LEN]; // ciphering key
|
char ckey[TSDB_KEY_LEN]; // ciphering key
|
||||||
|
|
||||||
void (*cfp)(SRpcMsg *, SEpSet *);
|
void (*cfp)(void *parent, SRpcMsg *, SEpSet *);
|
||||||
int (*afp)(char *user, char *spi, char *encrypt, char *secret, char *ckey);
|
int (*afp)(void *parent, char *user, char *spi, char *encrypt, char *secret, char *ckey);
|
||||||
|
|
||||||
int32_t refCount;
|
int32_t refCount;
|
||||||
|
void *parent;
|
||||||
void *idPool; // handle to ID pool
|
void *idPool; // handle to ID pool
|
||||||
void *tmrCtrl; // handle to timer
|
void *tmrCtrl; // handle to timer
|
||||||
SHashObj *hash; // handle returned by hash utility
|
SHashObj *hash; // handle returned by hash utility
|
||||||
|
@ -260,6 +261,7 @@ void *rpcOpen(const SRpcInit *pInit) {
|
||||||
pRpc->spi = pInit->spi;
|
pRpc->spi = pInit->spi;
|
||||||
pRpc->cfp = pInit->cfp;
|
pRpc->cfp = pInit->cfp;
|
||||||
pRpc->afp = pInit->afp;
|
pRpc->afp = pInit->afp;
|
||||||
|
pRpc->parent = pInit->parent;
|
||||||
pRpc->refCount = 1;
|
pRpc->refCount = 1;
|
||||||
|
|
||||||
atomic_add_fetch_32(&tsRpcNum, 1);
|
atomic_add_fetch_32(&tsRpcNum, 1);
|
||||||
|
@ -744,7 +746,7 @@ static SRpcConn *rpcAllocateServerConn(SRpcInfo *pRpc, SRecvInfo *pRecv) {
|
||||||
if (pConn->user[0] == 0) {
|
if (pConn->user[0] == 0) {
|
||||||
terrno = TSDB_CODE_RPC_AUTH_REQUIRED;
|
terrno = TSDB_CODE_RPC_AUTH_REQUIRED;
|
||||||
} else {
|
} else {
|
||||||
terrno = (*pRpc->afp)(pConn->user, &pConn->spi, &pConn->encrypt, pConn->secret, pConn->ckey);
|
terrno = (*pRpc->afp)(pRpc->parent, pConn->user, &pConn->spi, &pConn->encrypt, pConn->secret, pConn->ckey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (terrno != 0) {
|
if (terrno != 0) {
|
||||||
|
@ -1024,8 +1026,8 @@ static void doRpcReportBrokenLinkToServer(void *param, void *id) {
|
||||||
SRpcMsg *pRpcMsg = (SRpcMsg *)(param);
|
SRpcMsg *pRpcMsg = (SRpcMsg *)(param);
|
||||||
SRpcConn *pConn = (SRpcConn *)(pRpcMsg->handle);
|
SRpcConn *pConn = (SRpcConn *)(pRpcMsg->handle);
|
||||||
SRpcInfo *pRpc = pConn->pRpc;
|
SRpcInfo *pRpc = pConn->pRpc;
|
||||||
(*(pRpc->cfp))(pRpcMsg, NULL);
|
(*(pRpc->cfp))(pRpc->parent, pRpcMsg, NULL);
|
||||||
free(pRpcMsg);
|
free(pRpcMsg);
|
||||||
}
|
}
|
||||||
static void rpcReportBrokenLinkToServer(SRpcConn *pConn) {
|
static void rpcReportBrokenLinkToServer(SRpcConn *pConn) {
|
||||||
SRpcInfo *pRpc = pConn->pRpc;
|
SRpcInfo *pRpc = pConn->pRpc;
|
||||||
|
@ -1137,9 +1139,9 @@ static void rpcNotifyClient(SRpcReqContext *pContext, SRpcMsg *pMsg) {
|
||||||
// for asynchronous API
|
// for asynchronous API
|
||||||
SEpSet *pEpSet = NULL;
|
SEpSet *pEpSet = NULL;
|
||||||
if (pContext->epSet.inUse != pContext->oldInUse || pContext->redirect)
|
if (pContext->epSet.inUse != pContext->oldInUse || pContext->redirect)
|
||||||
pEpSet = &pContext->epSet;
|
pEpSet = &pContext->epSet;
|
||||||
|
|
||||||
(*pRpc->cfp)(pMsg, pEpSet);
|
(*pRpc->cfp)(pRpc->parent, pMsg, pEpSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
// free the request message
|
// free the request message
|
||||||
|
@ -1155,15 +1157,15 @@ static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead, SRpcReqConte
|
||||||
rpcMsg.contLen = rpcContLenFromMsg(pHead->msgLen);
|
rpcMsg.contLen = rpcContLenFromMsg(pHead->msgLen);
|
||||||
rpcMsg.pCont = pHead->content;
|
rpcMsg.pCont = pHead->content;
|
||||||
rpcMsg.msgType = pHead->msgType;
|
rpcMsg.msgType = pHead->msgType;
|
||||||
rpcMsg.code = pHead->code;
|
rpcMsg.code = pHead->code;
|
||||||
|
|
||||||
if ( rpcIsReq(pHead->msgType) ) {
|
if (rpcIsReq(pHead->msgType)) {
|
||||||
rpcMsg.ahandle = pConn->ahandle;
|
rpcMsg.ahandle = pConn->ahandle;
|
||||||
rpcMsg.handle = pConn;
|
rpcMsg.handle = pConn;
|
||||||
rpcAddRef(pRpc); // add the refCount for requests
|
rpcAddRef(pRpc); // add the refCount for requests
|
||||||
|
|
||||||
// notify the server app
|
// notify the server app
|
||||||
(*(pRpc->cfp))(&rpcMsg, NULL);
|
(*(pRpc->cfp))(pRpc->parent, &rpcMsg, NULL);
|
||||||
} else {
|
} else {
|
||||||
// it's a response
|
// it's a response
|
||||||
rpcMsg.handle = pContext;
|
rpcMsg.handle = pContext;
|
||||||
|
|
|
@ -78,6 +78,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MEMORY_CORRUPTED, "Memory corrupted")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_FILE_CORRUPTED, "Data file corrupted")
|
TAOS_DEFINE_ERROR(TSDB_CODE_FILE_CORRUPTED, "Data file corrupted")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_CHECKSUM_ERROR, "Checksum error")
|
TAOS_DEFINE_ERROR(TSDB_CODE_CHECKSUM_ERROR, "Checksum error")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_MSG, "Invalid config message")
|
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_MSG, "Invalid config message")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MSG_NOT_PROCESSED, "Message not processed")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_REF_NO_MEMORY, "Ref out of memory")
|
TAOS_DEFINE_ERROR(TSDB_CODE_REF_NO_MEMORY, "Ref out of memory")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_REF_FULL, "too many Ref Objs")
|
TAOS_DEFINE_ERROR(TSDB_CODE_REF_FULL, "too many Ref Objs")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_REF_ID_REMOVED, "Ref ID is removed")
|
TAOS_DEFINE_ERROR(TSDB_CODE_REF_ID_REMOVED, "Ref ID is removed")
|
||||||
|
@ -235,20 +236,20 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_TOPIC_PARTITONS, "Invalid topic partito
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOPIC_ALREADY_EXIST, "Topic already exists")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOPIC_ALREADY_EXIST, "Topic already exists")
|
||||||
|
|
||||||
// dnode
|
// dnode
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MSG_NOT_PROCESSED, "Message not processed")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_ACTION_IN_PROGRESS, "Action in progress")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_OUT_OF_MEMORY, "Dnode out of memory")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_EXITING, "Dnode is exiting")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_ID_NOT_MATCH_DNODE, "Mnode Id not match Dnode")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_INVALID_MSG_LEN, "Invalid message length")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_DNODE_READ_FILE_ERROR, "Read dnode.json error")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_DNODE_WRITE_FILE_ERROR, "Write dnode.json error")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_ALREADY_DEPLOYED, "Mnode already deployed")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_ALREADY_DEPLOYED, "Mnode already deployed")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_NOT_DEPLOYED, "Mnode not deployed")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_NOT_DEPLOYED, "Mnode not deployed")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_READ_MNODE_FILE_ERROR, "Read mnode.json error")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_ID_INVALID, "Mnode Id invalid")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_WRITE_MNODE_FILE_ERROR, "Write mnode.json error")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_ID_NOT_FOUND, "Mnode Id not found")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_NO_WRITE_ACCESS, "No permission for disk files in dnode")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_READ_FILE_ERROR, "Read mnode.json error")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_INVALID_MSG_LEN, "Invalid message length")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MNODE_WRITE_FILE_ERROR, "Write mnode.json error")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_ACTION_IN_PROGRESS, "Action in progress")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_VNODE_TOO_MANY_VNODES, "Too many vnode directories")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_TOO_MANY_VNODES, "Too many vnode directories")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_VNODE_READ_FILE_ERROR, "Read vnodes.json error")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_EXITING, "Dnode is exiting")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_VNODE_WRITE_FILE_ERROR, "Write vnodes.json error")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_PARSE_VNODE_FILE_ERROR, "Parse vnodes.json error")
|
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_PARSE_DNODE_FILE_ERROR, "Parse dnodes.json error")
|
|
||||||
|
|
||||||
// vnode
|
// vnode
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_ACTION_IN_PROGRESS, "Action in progress")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_ACTION_IN_PROGRESS, "Action in progress")
|
||||||
|
|
Loading…
Reference in New Issue