diff --git a/include/dnode/mgmt/dnode.h b/include/dnode/mgmt/dnode.h index 50886932ce25a45f2a927c1ca4ae3e9ecaa0f5fa..540a501f3a8f8b03d7ca55cfeade21e30a8387c2 100644 --- a/include/dnode/mgmt/dnode.h +++ b/include/dnode/mgmt/dnode.h @@ -31,6 +31,7 @@ typedef struct { int16_t numOfSupportMnodes; int16_t numOfSupportVnodes; int16_t numOfSupportQnodes; + int8_t enableTelem; int32_t statusInterval; int32_t mnodeEqualVnodeNum; float numOfThreadsPerCore; @@ -45,6 +46,8 @@ typedef struct { char timezone[TSDB_TIMEZONE_LEN]; char locale[TSDB_LOCALE_LEN]; char charset[TSDB_LOCALE_LEN]; + char buildinfo[64]; + char gitinfo[48]; } SDnodeOpt; /* ------------------------ SDnode ------------------------ */ diff --git a/include/dnode/mnode/mnode.h b/include/dnode/mnode/mnode.h index 0a897b93f887daf0f588e5f7df2ea9d026ca4bb3..8a8346fbc0eca5ba2fc978a71666a4497b2dac49 100644 --- a/include/dnode/mnode/mnode.h +++ b/include/dnode/mnode/mnode.h @@ -43,24 +43,31 @@ typedef struct SMnodeLoad { int64_t compStorage; } SMnodeLoad; +typedef struct SMnodeCfg { + int32_t sver; + int8_t enableTelem; + int32_t statusInterval; + int32_t mnodeEqualVnodeNum; + int32_t shellActivityTimer; + char *timezone; + char *locale; + char *charset; + char *buildinfo; + char *gitinfo; +} SMnodeCfg; + typedef struct { int32_t dnodeId; int32_t clusterId; int8_t replica; int8_t selfIndex; SReplica replicas[TSDB_MAX_REPLICA]; + SMnodeCfg cfg; SDnode *pDnode; PutMsgToMnodeQFp putMsgToApplyMsgFp; SendMsgToDnodeFp sendMsgToDnodeFp; SendMsgToMnodeFp sendMsgToMnodeFp; SendRedirectMsgFp sendRedirectMsgFp; - int32_t sver; - int32_t statusInterval; - int32_t mnodeEqualVnodeNum; - int32_t shellActivityTimer; - char *timezone; - char *locale; - char *charset; } SMnodeOpt; /* ------------------------ SMnode ------------------------ */ diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 413c84fe315d04ea66c06fffe00025d4c3833342..f6cefa96df9c1021843c3da8d697b207e1c96912 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -76,6 +76,10 @@ int32_t* taosGetErrno(); #define TSDB_CODE_REF_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0114) #define TSDB_CODE_REF_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0115) +#define TSDB_CODE_INVALID_VERSION_NUMBER TAOS_DEF_ERROR_CODE(0, 0x0120) +#define TSDB_CODE_INVALID_VERSION_STRING TAOS_DEF_ERROR_CODE(0, 0x0121) +#define TSDB_CODE_VERSION_NOT_COMPATIBLE TAOS_DEF_ERROR_CODE(0, 0x0122) + //client #define TSDB_CODE_TSC_INVALID_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0200) //"Invalid Operation") #define TSDB_CODE_TSC_INVALID_QHANDLE TAOS_DEF_ERROR_CODE(0, 0x0201) //"Invalid qhandle") diff --git a/include/util/tversion.h b/include/util/tversion.h new file mode 100644 index 0000000000000000000000000000000000000000..3d7a7e1b665f219eee4d9f94a7dd56bc1d0d5bcc --- /dev/null +++ b/include/util/tversion.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_UTIL_VERSION_H +#define _TD_UTIL_VERSION_H + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t taosVersionStrToInt(const char *vstr, int32_t *vint); +int32_t taosVersionIntToStr(int32_t vint, char *vstr, int32_t len); +int32_t taosCheckVersionCompatible(int32_t clientVer, int32_t serverVer, int32_t comparedSegments); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_UTIL_VERSION_H*/ diff --git a/source/common/src/versionUtil.c b/source/common/src/versionUtil.c deleted file mode 100644 index 22c50fa5cf5cab0a4c94e09cf38f600909d9bf63..0000000000000000000000000000000000000000 --- a/source/common/src/versionUtil.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "os.h" -#include "tdef.h" -#include "ulog.h" -#include "taoserror.h" - -bool taosGetVersionNumber(char *versionStr, int *versionNubmer) { - if (versionStr == NULL || versionNubmer == NULL) { - return false; - } - - int versionNumberPos[5] = {0}; - int len = (int)strlen(versionStr); - int dot = 0; - for (int pos = 0; pos < len && dot < 4; ++pos) { - if (versionStr[pos] == '.') { - versionStr[pos] = 0; - versionNumberPos[++dot] = pos + 1; - } - } - - if (dot != 3) { - return false; - } - - for (int pos = 0; pos < 4; ++pos) { - versionNubmer[pos] = atoi(versionStr + versionNumberPos[pos]); - } - versionStr[versionNumberPos[1] - 1] = '.'; - versionStr[versionNumberPos[2] - 1] = '.'; - versionStr[versionNumberPos[3] - 1] = '.'; - - return true; -} - -int taosCheckVersion(char *input_client_version, char *input_server_version, int comparedSegments) { - char client_version[TSDB_VERSION_LEN] = {0}; - char server_version[TSDB_VERSION_LEN] = {0}; - int clientVersionNumber[4] = {0}; - int serverVersionNumber[4] = {0}; - - tstrncpy(client_version, input_client_version, sizeof(client_version)); - tstrncpy(server_version, input_server_version, sizeof(server_version)); - - if (!taosGetVersionNumber(client_version, clientVersionNumber)) { - uError("invalid client version:%s", client_version); - return TSDB_CODE_TSC_INVALID_VERSION; - } - - if (!taosGetVersionNumber(server_version, serverVersionNumber)) { - uError("invalid server version:%s", server_version); - return TSDB_CODE_TSC_INVALID_VERSION; - } - - for(int32_t i = 0; i < comparedSegments; ++i) { - if (clientVersionNumber[i] != serverVersionNumber[i]) { - uError("the %d-th number of server version:%s not matched with client version:%s", i, server_version, - client_version); - return TSDB_CODE_TSC_INVALID_VERSION; - } - } - - return 0; -} diff --git a/source/dnode/mgmt/daemon/src/daemon.c b/source/dnode/mgmt/daemon/src/daemon.c index 08624f20f40f3e615fbefba42f9d5b85cd372100..cf9a9600622aa2b5f479f239e3a24553a44ab1be 100644 --- a/source/dnode/mgmt/daemon/src/daemon.c +++ b/source/dnode/mgmt/daemon/src/daemon.c @@ -136,7 +136,7 @@ void dmnWaitSignal() { } void dmnInitOption(SDnodeOpt *pOption) { - pOption->sver = tsVersion; + pOption->sver = 30000000; //3.0.0.0 pOption->numOfCores = tsNumOfCores; pOption->numOfSupportMnodes = 1; pOption->numOfSupportVnodes = 1; @@ -155,6 +155,8 @@ void dmnInitOption(SDnodeOpt *pOption) { tstrncpy(pOption->timezone, tsTimezone, TSDB_TIMEZONE_LEN); tstrncpy(pOption->locale, tsLocale, TSDB_LOCALE_LEN); tstrncpy(pOption->charset, tsCharset, TSDB_LOCALE_LEN); + tstrncpy(pOption->buildinfo, buildinfo, 64); + tstrncpy(pOption->gitinfo, gitinfo, 48); } int dmnRunDnode() { diff --git a/source/dnode/mgmt/impl/src/dndMnode.c b/source/dnode/mgmt/impl/src/dndMnode.c index 4afce4655dbf2a82cdcaef82515e87ee95f8001a..374a2f2b2c833adc1bc0dca7451c0c70d7c595ea 100644 --- a/source/dnode/mgmt/impl/src/dndMnode.c +++ b/source/dnode/mgmt/impl/src/dndMnode.c @@ -331,13 +331,16 @@ static void dndInitMnodeOption(SDnode *pDnode, SMnodeOpt *pOption) { pOption->putMsgToApplyMsgFp = dndPutMsgIntoMnodeApplyQueue; pOption->dnodeId = dndGetDnodeId(pDnode); pOption->clusterId = dndGetClusterId(pDnode); - pOption->sver = pDnode->opt.sver; - pOption->statusInterval = pDnode->opt.statusInterval; - pOption->mnodeEqualVnodeNum = pDnode->opt.mnodeEqualVnodeNum; - pOption->shellActivityTimer = pDnode->opt.shellActivityTimer; - pOption->timezone = pDnode->opt.timezone; - pOption->charset = pDnode->opt.charset; - pOption->locale = pDnode->opt.locale; + pOption->cfg.sver = pDnode->opt.sver; + pOption->cfg.enableTelem = pDnode->opt.enableTelem; + pOption->cfg.statusInterval = pDnode->opt.statusInterval; + pOption->cfg.mnodeEqualVnodeNum = pDnode->opt.mnodeEqualVnodeNum; + pOption->cfg.shellActivityTimer = pDnode->opt.shellActivityTimer; + pOption->cfg.timezone = pDnode->opt.timezone; + pOption->cfg.charset = pDnode->opt.charset; + pOption->cfg.locale = pDnode->opt.locale; + pOption->cfg.gitinfo = pDnode->opt.gitinfo; + pOption->cfg.buildinfo = pDnode->opt.buildinfo; } static void dndBuildMnodeDeployOption(SDnode *pDnode, SMnodeOpt *pOption) { diff --git a/source/dnode/mnode/impl/inc/mndCluster.h b/source/dnode/mnode/impl/inc/mndCluster.h index efc1ada67d88523465cde0b0347cd2eff4922efa..0206695b8814ee83832aeddeed86b4738649b3b7 100644 --- a/source/dnode/mnode/impl/inc/mndCluster.h +++ b/source/dnode/mnode/impl/inc/mndCluster.h @@ -24,6 +24,7 @@ extern "C" { int32_t mndInitCluster(SMnode *pMnode); void mndCleanupCluster(SMnode *pMnode); +int32_t mndGetClusterName(SMnode *pMnode, char *clusterName, int32_t len); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/inc/mndInt.h b/source/dnode/mnode/impl/inc/mndInt.h index dbca6ad057dc376aa36ecc70eb51926e53297440..8d20356e392dd115b12867207bffc017b981241e 100644 --- a/source/dnode/mnode/impl/inc/mndInt.h +++ b/source/dnode/mnode/impl/inc/mndInt.h @@ -51,6 +51,15 @@ typedef struct { SCacheObj *cache; } SProfileMgmt; +typedef struct { + int8_t enable; + pthread_mutex_t lock; + pthread_cond_t cond; + volatile int32_t exit; + pthread_t thread; + char email[TSDB_FQDN_LEN]; +} STelemMgmt; + typedef struct SMnode { int32_t dnodeId; int32_t clusterId; @@ -59,23 +68,18 @@ typedef struct SMnode { SReplica replicas[TSDB_MAX_REPLICA]; tmr_h timer; char *path; + SMnodeCfg cfg; SSdb *pSdb; SDnode *pDnode; SArray *pSteps; SShowMgmt showMgmt; SProfileMgmt profileMgmt; + STelemMgmt telemMgmt; MndMsgFp msgFp[TSDB_MSG_TYPE_MAX]; SendMsgToDnodeFp sendMsgToDnodeFp; SendMsgToMnodeFp sendMsgToMnodeFp; SendRedirectMsgFp sendRedirectMsgFp; PutMsgToMnodeQFp putMsgToApplyMsgFp; - int32_t sver; - int32_t statusInterval; - int32_t mnodeEqualVnodeNum; - int32_t shellActivityTimer; - char *timezone; - char *locale; - char *charset; } SMnode; void mndSendMsgToDnode(SMnode *pMnode, SEpSet *pEpSet, SRpcMsg *rpcMsg); diff --git a/source/dnode/mnode/impl/src/mndCluster.c b/source/dnode/mnode/impl/src/mndCluster.c index c9ef7ce87dd5421e25383cec17f21b476bd77d33..9fa7a066306308af24db8f31e7371349cf596696 100644 --- a/source/dnode/mnode/impl/src/mndCluster.c +++ b/source/dnode/mnode/impl/src/mndCluster.c @@ -48,6 +48,19 @@ int32_t mndInitCluster(SMnode *pMnode) { void mndCleanupCluster(SMnode *pMnode) {} +int32_t mndGetClusterName(SMnode *pMnode, char *clusterName, int32_t len) { + SSdb *pSdb = pMnode->pSdb; + + SClusterObj *pCluster = sdbAcquire(pSdb, SDB_CLUSTER, &pMnode->clusterId); + if (pCluster = NULL) { + return -1; + } + + tstrncpy(clusterName, pCluster->name, len); + sdbRelease(pSdb, pCluster); + return 0; +} + static SSdbRaw *mndClusterActionEncode(SClusterObj *pCluster) { SSdbRaw *pRaw = sdbAllocRaw(SDB_CLUSTER, SDB_CLUSTER_VER, sizeof(SClusterObj)); if (pRaw == NULL) return NULL; @@ -198,4 +211,4 @@ static int32_t mndRetrieveClusters(SMnodeMsg *pMsg, SShowObj *pShow, char *data, static void mndCancelGetNextCluster(SMnode *pMnode, void *pIter) { SSdb *pSdb = pMnode->pSdb; sdbCancelFetch(pSdb, pIter); -} \ No newline at end of file +} diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index 24e6113161b1e3ae8668a7aabd25929b4a5976f8..241b006293000a47eaf5650b52a692910e550540 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -179,32 +179,33 @@ static void mndGetDnodeData(SMnode *pMnode, SDnodeEps *pEps, int32_t numOfEps) { } static int32_t mndCheckClusterCfgPara(SMnode *pMnode, const SClusterCfg *pCfg) { - if (pCfg->mnodeEqualVnodeNum != pMnode->mnodeEqualVnodeNum) { - mError("\"mnodeEqualVnodeNum\"[%d - %d] cfg inconsistent", pCfg->mnodeEqualVnodeNum, pMnode->mnodeEqualVnodeNum); + if (pCfg->mnodeEqualVnodeNum != pMnode->cfg.mnodeEqualVnodeNum) { + mError("\"mnodeEqualVnodeNum\"[%d - %d] cfg inconsistent", pCfg->mnodeEqualVnodeNum, + pMnode->cfg.mnodeEqualVnodeNum); return DND_REASON_MN_EQUAL_VN_NOT_MATCH; } - if (pCfg->statusInterval != pMnode->statusInterval) { - mError("\"statusInterval\"[%d - %d] cfg inconsistent", pCfg->statusInterval, pMnode->statusInterval); + if (pCfg->statusInterval != pMnode->cfg.statusInterval) { + mError("\"statusInterval\"[%d - %d] cfg inconsistent", pCfg->statusInterval, pMnode->cfg.statusInterval); return DND_REASON_STATUS_INTERVAL_NOT_MATCH; } int64_t checkTime = 0; char timestr[32] = "1970-01-01 00:00:00.00"; (void)taosParseTime(timestr, &checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0); - if ((0 != strcasecmp(pCfg->timezone, pMnode->timezone)) && (checkTime != pCfg->checkTime)) { - mError("\"timezone\"[%s - %s] [%" PRId64 " - %" PRId64 "] cfg inconsistent", pCfg->timezone, tsTimezone, + if ((0 != strcasecmp(pCfg->timezone, pMnode->cfg.timezone)) && (checkTime != pCfg->checkTime)) { + mError("\"timezone\"[%s - %s] [%" PRId64 " - %" PRId64 "] cfg inconsistent", pCfg->timezone, pMnode->cfg.timezone, pCfg->checkTime, checkTime); return DND_REASON_TIME_ZONE_NOT_MATCH; } - if (0 != strcasecmp(pCfg->locale, pMnode->locale)) { - mError("\"locale\"[%s - %s] cfg parameters inconsistent", pCfg->locale, pMnode->locale); + if (0 != strcasecmp(pCfg->locale, pMnode->cfg.locale)) { + mError("\"locale\"[%s - %s] cfg parameters inconsistent", pCfg->locale, pMnode->cfg.locale); return DND_REASON_LOCALE_NOT_MATCH; } - if (0 != strcasecmp(pCfg->charset, pMnode->charset)) { - mError("\"charset\"[%s - %s] cfg parameters inconsistent.", pCfg->charset, pMnode->charset); + if (0 != strcasecmp(pCfg->charset, pMnode->cfg.charset)) { + mError("\"charset\"[%s - %s] cfg parameters inconsistent.", pCfg->charset, pMnode->cfg.charset); return DND_REASON_CHARSET_NOT_MATCH; } @@ -251,12 +252,12 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) { } } - if (pStatus->sver != pMnode->sver) { + if (pStatus->sver != pMnode->cfg.sver) { if (pDnode != NULL && pDnode->status != DND_STATUS_READY) { pDnode->offlineReason = DND_REASON_VERSION_NOT_MATCH; } mndReleaseDnode(pMnode, pDnode); - mError("dnode:%d, status msg version:%d not match cluster:%d", pStatus->dnodeId, pStatus->sver, pMnode->sver); + mError("dnode:%d, status msg version:%d not match cluster:%d", pStatus->dnodeId, pStatus->sver, pMnode->cfg.sver); return TSDB_CODE_MND_INVALID_MSG_VERSION; } diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index 8f51b1a0be1a997cd7ae8c34d70c840ca52a18e0..ad7a6322bb9c8e506664d6b703a77bdf84ec7f4c 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -67,7 +67,7 @@ static void mndCancelGetNextStream(SMnode *pMnode, void *pIter); int32_t mndInitProfile(SMnode *pMnode) { SProfileMgmt *pMgmt = &pMnode->profileMgmt; - int32_t connCheckTime = pMnode->shellActivityTimer * 2; + int32_t connCheckTime = pMnode->cfg.shellActivityTimer * 2; pMgmt->cache = taosCacheInit(TSDB_DATA_TYPE_INT, connCheckTime, true, (__cache_free_fn_t)mndFreeConn, "conn"); if (pMgmt->cache == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -126,7 +126,7 @@ static SConnObj *mndCreateConn(SMnode *pMnode, char *user, uint32_t ip, uint16_t tstrncpy(connObj.user, user, TSDB_USER_LEN); tstrncpy(connObj.app, app, TSDB_APP_NAME_LEN); - int32_t keepTime = pMnode->shellActivityTimer * 3; + int32_t keepTime = pMnode->cfg.shellActivityTimer * 3; SConnObj *pConn = taosCachePut(pMgmt->cache, &connId, sizeof(int32_t), &connObj, sizeof(connObj), keepTime * 1000); if (pConn == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -153,7 +153,7 @@ static SConnObj *mndAcquireConn(SMnode *pMnode, int32_t connId) { return NULL; } - int32_t keepTime = pMnode->shellActivityTimer * 3; + int32_t keepTime = pMnode->cfg.shellActivityTimer * 3; pConn->lastAccess = keepTime * 1000 + (uint64_t)taosGetTimestampMs(); mTrace("conn:%d, data:%p acquired from cache", pConn->id, pConn); diff --git a/source/dnode/mnode/impl/src/mndShow.c b/source/dnode/mnode/impl/src/mndShow.c index ca0d9b9d504e48264b93e9872ff5db7e9480ad48..747ea3923784e3927594cf8a846d799261c5b5ee 100644 --- a/source/dnode/mnode/impl/src/mndShow.c +++ b/source/dnode/mnode/impl/src/mndShow.c @@ -69,7 +69,7 @@ static SShowObj *mndCreateShowObj(SMnode *pMnode, SShowMsg *pMsg) { return NULL; } - int32_t keepTime = pMnode->shellActivityTimer * 6 * 1000; + int32_t keepTime = pMnode->cfg.shellActivityTimer * 6 * 1000; SShowObj *pShowRet = taosCachePut(pMgmt->cache, &showId, sizeof(int32_t), pShow, size, keepTime); free(pShow); if (pShowRet == NULL) { diff --git a/source/dnode/mnode/impl/src/mndTelem.c b/source/dnode/mnode/impl/src/mndTelem.c index f9f349aad8610933ab414d152d73d29b750ce4cc..663ae76506c39a459f856f8479e0dc252083b8dd 100644 --- a/source/dnode/mnode/impl/src/mndTelem.c +++ b/source/dnode/mnode/impl/src/mndTelem.c @@ -15,27 +15,15 @@ #define _DEFAULT_SOURCE #include "mndTelem.h" -#include "tbuffer.h" -#include "tglobal.h" +#include "mndCluster.h" #include "mndSync.h" +#include "tbuffer.h" +#include "tversion.h" #define TELEMETRY_SERVER "telemetry.taosdata.com" #define TELEMETRY_PORT 80 #define REPORT_INTERVAL 86400 -/* - * sem_timedwait is NOT implemented on MacOSX - * thus we use pthread_mutex_t/pthread_cond_t to simulate - */ -static struct { - bool enable; - pthread_mutex_t lock; - pthread_cond_t cond; - volatile int32_t exit; - pthread_t thread; - char email[TSDB_FQDN_LEN]; -} tsTelem; - static void mndBeginObject(SBufferWriter* bw) { tbufWriteChar(bw, '{'); } static void mndCloseObject(SBufferWriter* bw) { @@ -86,7 +74,7 @@ static void mndAddStringField(SBufferWriter* bw, const char* k, const char* v) { tbufWriteChar(bw, ','); } -static void mndAddCpuInfo(SBufferWriter* bw) { +static void mndAddCpuInfo(SMnode* pMnode, SBufferWriter* bw) { char* line = NULL; size_t size = 0; int32_t done = 0; @@ -116,7 +104,7 @@ static void mndAddCpuInfo(SBufferWriter* bw) { fclose(fp); } -static void mndAddOsInfo(SBufferWriter* bw) { +static void mndAddOsInfo(SMnode* pMnode, SBufferWriter* bw) { char* line = NULL; size_t size = 0; @@ -142,7 +130,7 @@ static void mndAddOsInfo(SBufferWriter* bw) { fclose(fp); } -static void mndAddMemoryInfo(SBufferWriter* bw) { +static void mndAddMemoryInfo(SMnode* pMnode, SBufferWriter* bw) { char* line = NULL; size_t size = 0; @@ -165,16 +153,21 @@ static void mndAddMemoryInfo(SBufferWriter* bw) { fclose(fp); } -static void mndAddVersionInfo(SBufferWriter* bw) { - mndAddStringField(bw, "version", version); - mndAddStringField(bw, "buildInfo", buildinfo); - mndAddStringField(bw, "gitInfo", gitinfo); - mndAddStringField(bw, "email", tsTelem.email); +static void mndAddVersionInfo(SMnode* pMnode, SBufferWriter* bw) { + STelemMgmt* pMgmt = &pMnode->telemMgmt; + + char vstr[32] = {0}; + taosVersionIntToStr(pMnode->cfg.sver, vstr, 32); + + mndAddStringField(bw, "version", vstr); + mndAddStringField(bw, "buildInfo", pMnode->cfg.buildinfo); + mndAddStringField(bw, "gitInfo", pMnode->cfg.gitinfo); + mndAddStringField(bw, "email", pMgmt->email); } -static void mndAddRuntimeInfo(SBufferWriter* bw) { +static void mndAddRuntimeInfo(SMnode* pMnode, SBufferWriter* bw) { SMnodeLoad load = {0}; - if (mndGetLoad(NULL, &load) != 0) { + if (mndGetLoad(pMnode, &load) != 0) { return; } @@ -190,11 +183,13 @@ static void mndAddRuntimeInfo(SBufferWriter* bw) { mndAddIntField(bw, "compStorage", load.compStorage); } -static void mndSendTelemetryReport() { +static void mndSendTelemetryReport(SMnode* pMnode) { + STelemMgmt* pMgmt = &pMnode->telemMgmt; + char buf[128] = {0}; uint32_t ip = taosGetIpv4FromFqdn(TELEMETRY_SERVER); if (ip == 0xffffffff) { - mTrace("failed to get IP address of " TELEMETRY_SERVER ", reason:%s", strerror(errno)); + mTrace("failed to get IP address of " TELEMETRY_SERVER " since :%s", strerror(errno)); return; } SOCKET fd = taosOpenTcpClientSocket(ip, TELEMETRY_PORT, 0); @@ -203,19 +198,18 @@ static void mndSendTelemetryReport() { return; } - int32_t clusterId = 0; - char clusterIdStr[20] = {0}; - snprintf(clusterIdStr, sizeof(clusterIdStr), "%d", clusterId); + char clusterName[64] = {0}; + mndGetClusterName(pMnode, clusterName, sizeof(clusterName)); SBufferWriter bw = tbufInitWriter(NULL, false); mndBeginObject(&bw); - mndAddStringField(&bw, "instanceId", clusterIdStr); + mndAddStringField(&bw, "instanceId", clusterName); mndAddIntField(&bw, "reportVersion", 1); - mndAddOsInfo(&bw); - mndAddCpuInfo(&bw); - mndAddMemoryInfo(&bw); - mndAddVersionInfo(&bw); - mndAddRuntimeInfo(&bw); + mndAddOsInfo(pMnode, &bw); + mndAddCpuInfo(pMnode, &bw); + mndAddMemoryInfo(pMnode, &bw); + mndAddVersionInfo(pMnode, &bw); + mndAddRuntimeInfo(pMnode, &bw); mndCloseObject(&bw); const char* header = @@ -241,23 +235,26 @@ static void mndSendTelemetryReport() { } static void* mndTelemThreadFp(void* param) { + SMnode* pMnode = param; + STelemMgmt* pMgmt = &pMnode->telemMgmt; + struct timespec end = {0}; clock_gettime(CLOCK_REALTIME, &end); end.tv_sec += 300; // wait 5 minutes before send first report setThreadName("mnd-telem"); - while (!tsTelem.exit) { + while (!pMgmt->exit) { int32_t r = 0; struct timespec ts = end; - pthread_mutex_lock(&tsTelem.lock); - r = pthread_cond_timedwait(&tsTelem.cond, &tsTelem.lock, &ts); - pthread_mutex_unlock(&tsTelem.lock); + pthread_mutex_lock(&pMgmt->lock); + r = pthread_cond_timedwait(&pMgmt->cond, &pMgmt->lock, &ts); + pthread_mutex_unlock(&pMgmt->lock); if (r == 0) break; if (r != ETIMEDOUT) continue; - if (mndIsMaster(NULL)) { - mndSendTelemetryReport(); + if (mndIsMaster(pMnode)) { + mndSendTelemetryReport(pMnode); } end.tv_sec += REPORT_INTERVAL; } @@ -265,35 +262,39 @@ static void* mndTelemThreadFp(void* param) { return NULL; } -static void mndGetEmail(char* filepath) { +static void mndGetEmail(SMnode* pMnode, char* filepath) { + STelemMgmt* pMgmt = &pMnode->telemMgmt; + int32_t fd = taosOpenFileRead(filepath); if (fd < 0) { return; } - if (taosReadFile(fd, (void*)tsTelem.email, TSDB_FQDN_LEN) < 0) { + if (taosReadFile(fd, (void*)pMgmt->email, TSDB_FQDN_LEN) < 0) { mError("failed to read %d bytes from file %s since %s", TSDB_FQDN_LEN, filepath, strerror(errno)); } taosCloseFile(fd); } -int32_t mndInitTelem(SMnode *pMnode) { - tsTelem.enable = tsEnableTelemetryReporting; - if (!tsTelem.enable) return 0; +int32_t mndInitTelem(SMnode* pMnode) { + STelemMgmt* pMgmt = &pMnode->telemMgmt; + pMgmt->enable = pMnode->cfg.enableTelem; + + if (!pMgmt->enable) return 0; - tsTelem.exit = 0; - pthread_mutex_init(&tsTelem.lock, NULL); - pthread_cond_init(&tsTelem.cond, NULL); - tsTelem.email[0] = 0; + pMgmt->exit = 0; + pthread_mutex_init(&pMgmt->lock, NULL); + pthread_cond_init(&pMgmt->cond, NULL); + pMgmt->email[0] = 0; - mndGetEmail("/usr/local/taos/email"); + mndGetEmail(pMnode, "/usr/local/taos/email"); pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - int32_t code = pthread_create(&tsTelem.thread, &attr, mndTelemThreadFp, NULL); + int32_t code = pthread_create(&pMgmt->thread, &attr, mndTelemThreadFp, pMnode); pthread_attr_destroy(&attr); if (code != 0) { mTrace("failed to create telemetry thread since :%s", strerror(code)); @@ -303,18 +304,19 @@ int32_t mndInitTelem(SMnode *pMnode) { return 0; } -void mndCleanupTelem(SMnode *pMnode) { - if (!tsTelem.enable) return; +void mndCleanupTelem(SMnode* pMnode) { + STelemMgmt* pMgmt = &pMnode->telemMgmt; + if (!pMgmt->enable) return; - if (taosCheckPthreadValid(tsTelem.thread)) { - pthread_mutex_lock(&tsTelem.lock); - tsTelem.exit = 1; - pthread_cond_signal(&tsTelem.cond); - pthread_mutex_unlock(&tsTelem.lock); + if (taosCheckPthreadValid(pMgmt->thread)) { + pthread_mutex_lock(&pMgmt->lock); + pMgmt->exit = 1; + pthread_cond_signal(&pMgmt->cond); + pthread_mutex_unlock(&pMgmt->lock); - pthread_join(tsTelem.thread, NULL); + pthread_join(pMgmt->thread, NULL); } - pthread_mutex_destroy(&tsTelem.lock); - pthread_cond_destroy(&tsTelem.cond); + pthread_mutex_destroy(&pMgmt->lock); + pthread_cond_destroy(&pMgmt->cond); } diff --git a/source/dnode/mnode/impl/src/mnode.c b/source/dnode/mnode/impl/src/mnode.c index b99de4a019cf4286074b69035ce37dc82f040b1d..2fa0838ee802b788d0172662a208651c1db931e9 100644 --- a/source/dnode/mnode/impl/src/mnode.c +++ b/source/dnode/mnode/impl/src/mnode.c @@ -203,22 +203,25 @@ static int32_t mndSetOptions(SMnode *pMnode, const SMnodeOpt *pOption) { pMnode->sendMsgToDnodeFp = pOption->sendMsgToDnodeFp; pMnode->sendMsgToMnodeFp = pOption->sendMsgToMnodeFp; pMnode->sendRedirectMsgFp = pOption->sendRedirectMsgFp; - pMnode->sver = pOption->sver; - pMnode->statusInterval = pOption->statusInterval; - pMnode->mnodeEqualVnodeNum = pOption->mnodeEqualVnodeNum; - pMnode->shellActivityTimer = pOption->shellActivityTimer; - pMnode->timezone = strdup(pOption->timezone); - pMnode->locale = strdup(pOption->locale); - pMnode->charset = strdup(pOption->charset); + pMnode->cfg.sver = pOption->cfg.sver; + pMnode->cfg.enableTelem = pOption->cfg.enableTelem; + pMnode->cfg.statusInterval = pOption->cfg.statusInterval; + pMnode->cfg.mnodeEqualVnodeNum = pOption->cfg.mnodeEqualVnodeNum; + pMnode->cfg.shellActivityTimer = pOption->cfg.shellActivityTimer; + pMnode->cfg.timezone = strdup(pOption->cfg.timezone); + pMnode->cfg.locale = strdup(pOption->cfg.locale); + pMnode->cfg.charset = strdup(pOption->cfg.charset); + pMnode->cfg.gitinfo = strdup(pOption->cfg.gitinfo); + pMnode->cfg.buildinfo = strdup(pOption->cfg.buildinfo); if (pMnode->sendMsgToDnodeFp == NULL || pMnode->sendMsgToMnodeFp == NULL || pMnode->sendRedirectMsgFp == NULL || pMnode->putMsgToApplyMsgFp == NULL || pMnode->dnodeId < 0 || pMnode->clusterId < 0 || - pMnode->statusInterval < 1 || pOption->mnodeEqualVnodeNum < 0) { + pMnode->cfg.statusInterval < 1 || pOption->cfg.mnodeEqualVnodeNum < 0) { terrno = TSDB_CODE_MND_INVALID_OPTIONS; return -1; } - if (pMnode->timezone == NULL || pMnode->locale == NULL || pMnode->charset == NULL) { + if (pMnode->cfg.timezone == NULL || pMnode->cfg.locale == NULL || pMnode->cfg.charset == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } @@ -289,9 +292,11 @@ void mndClose(SMnode *pMnode) { mDebug("start to close mnode"); mndCleanupSteps(pMnode, -1); tfree(pMnode->path); - tfree(pMnode->charset); - tfree(pMnode->locale); - tfree(pMnode->timezone); + tfree(pMnode->cfg.charset); + tfree(pMnode->cfg.locale); + tfree(pMnode->cfg.timezone); + tfree(pMnode->cfg.gitinfo); + tfree(pMnode->cfg.buildinfo); tfree(pMnode); mDebug("mnode is closed"); } diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 11b40f61f65d6dc6ed89f32ca286b4eae8e81ca1..3a36ad9b420382815fe3f892e16b844645943536 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -86,6 +86,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_REF_INVALID_ID, "Invalid Ref ID") TAOS_DEFINE_ERROR(TSDB_CODE_REF_ALREADY_EXIST, "Ref is already there") TAOS_DEFINE_ERROR(TSDB_CODE_REF_NOT_EXIST, "Ref is not there") +TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_VERSION_NUMBER, "Invalid version number") +TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_VERSION_STRING, "Invalid version string") +TAOS_DEFINE_ERROR(TSDB_CODE_VERSION_NOT_COMPATIBLE, "Version not compatible") //client TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_OPERATION, "Invalid operation") diff --git a/source/util/src/tversion.c b/source/util/src/tversion.c new file mode 100644 index 0000000000000000000000000000000000000000..3944bd51327a8516dcf87e65e8fa1b0ae74fe90a --- /dev/null +++ b/source/util/src/tversion.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#define _DEFAULT_SOURCE +#include "os.h" +#include "taoserror.h" +#include "tdef.h" +#include "ulog.h" + +int32_t taosVersionStrToInt(const char *vstr, int32_t *vint) { + if (vstr == NULL) { + terrno = TSDB_CODE_INVALID_VERSION_STRING; + return -1; + } + + int32_t vnum[4] = {0}; + int32_t len = strlen(vstr); + char tmp[16] = {0}; + + for (int32_t spos = 0, tpos = 0, vpos = 0; spos < len && vpos < 4; ++spos) { + if (vstr[spos] != '.') { + tmp[spos - tpos] = vstr[spos]; + } else { + vnum[vpos] = atoi(tmp); + memset(tmp, 0, sizeof(tmp)); + vpos++; + tpos = spos + 1; + } + } + + if (vnum[0] <= 0) { + terrno = TSDB_CODE_INVALID_VERSION_STRING; + return -1; + } + + *vint = vnum[0] * 1000000 + vnum[1] * 10000 + vnum[2] * 100 + vnum[3]; + return 0; +} + +int32_t taosVersionIntToStr(int32_t vint, char *vstr, int32_t len) { + int32_t s1 = (vint % 100000000) / 1000000; + int32_t s2 = (vint % 1000000) / 10000; + int32_t s3 = (vint % 10000) / 100; + int32_t s4 = vint % 100; + if (s1 <= 0) { + terrno = TSDB_CODE_INVALID_VERSION_NUMBER; + return -1; + } + + snprintf(vstr, len, "%02d.%02d.%02d.%02d", s1, s2, s3, s4); + return 0; +} + +int32_t taosCheckVersionCompatible(int32_t clientVer, int32_t serverVer, int32_t comparedSegments) { + switch (comparedSegments) { + case 4: + break; + case 3: + clientVer %= 100; + serverVer %= 100; + break; + case 2: + clientVer %= 10000; + serverVer %= 10000; + break; + case 1: + clientVer %= 1000000; + serverVer %= 1000000; + break; + default: + terrno = TSDB_CODE_INVALID_VERSION_NUMBER; + return -1; + } + + if (clientVer == serverVer) { + return 0; + } else { + terrno = TSDB_CODE_VERSION_NOT_COMPATIBLE; + return -1; + } +}