diff --git a/src/cm_adapter/cm_etcdapi/cm_etcdapi.cpp b/src/cm_adapter/cm_etcdapi/cm_etcdapi.cpp index 468af5956a888f5ed4487fbbecc613ddd5e09322..f3d1fd5f4d28a03aaabce92c2bba857c3264714c 100644 --- a/src/cm_adapter/cm_etcdapi/cm_etcdapi.cpp +++ b/src/cm_adapter/cm_etcdapi/cm_etcdapi.cpp @@ -30,9 +30,13 @@ #include "cm_etcdapi.h" #define ETCD_SERVER_SEPARATOR "\n\r\t ,;" -#define IP_PATTERN \ +#define IP_PATTERN\ "([0-9]|[1-9][0-9]|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]).([0-9]|[1-9][0-9]|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]).([0-9]|[1-" \ - "9][0-9]|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]).([0-9]|[1-9][0-9]|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])" + "9][0-9]|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]).([0-9]|[1-9][0-9]|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])"\ + "|(^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$)"\ + "|(^([0-9a-fA-F]{1,4}:){1,7}:$)"\ + "|(^([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$)" + #define PORT_PATTERN "([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])" #define URL_PATTERN "^(" IP_PATTERN ":" PORT_PATTERN "([" ETCD_SERVER_SEPARATOR "]" IP_PATTERN ":" PORT_PATTERN ")*)$" const int DECIMAL_BASE = 10; diff --git a/src/cm_agent/client_adpts/libpq/cma_datanode_check.cpp b/src/cm_agent/client_adpts/libpq/cma_datanode_check.cpp index 276f1457f41e82733ae31e0b438c1782a10c0718..21491c51cc569ab28194ea5205daeb9d048fa4bb 100644 --- a/src/cm_agent/client_adpts/libpq/cma_datanode_check.cpp +++ b/src/cm_agent/client_adpts/libpq/cma_datanode_check.cpp @@ -24,6 +24,7 @@ #include "cm_text.h" #include "cm_misc.h" #include "cm_elog.h" +#include "cm_ip.h" #include "cm_config.h" @@ -31,6 +32,7 @@ #include "cma_global_params.h" #include "cma_common.h" +#include "cm_util.h" #include "cma_libpq_com.h" #include "cma_network_check.h" #include "cma_datanode_utils.h" @@ -68,9 +70,11 @@ static THR_LOCAL DnIpText g_curDnIpText = {0}; static const char *const LISTEN_ADDRESSES = "listen_addresses"; static const char *const MATCH_POINT = "="; static const char MATCH_POINT_CHAR = '='; -static const char *const ALL_LISTEN_ADDRESSES = "0.0.0.0"; -static const char *const ALL_LISTEN_ADDRESSES_ARRAY[] = {ALL_LISTEN_ADDRESSES, "*"}; -static const char *const LOCAL_HOST_ARRAY[] = {"localhost", "127.0.0.1"}; +static const char *const IPV4_ALL_LISTEN_ADDRESSES = "0.0.0.0"; +static const char *const IPV4_ALL_LISTEN_ADDRESSES_ARRAY[] = {IPV4_ALL_LISTEN_ADDRESSES, "*"}; +static const char *const IPV6_ALL_LISTEN_ADDRESSES = "::"; +static const char *const IPV6_ALL_LISTEN_ADDRESSES_ARRAY[] = {IPV6_ALL_LISTEN_ADDRESSES, "*"}; +static const char *const LOCAL_HOST = {"localhost"}; static const char INPUT_END_ARRAY[] = {'\n'}; static const char SEPARATOR_ARRAY[] = {',', '\0'}; @@ -375,18 +379,27 @@ static bool8 IsCurIpAllListenAddress(const char *ip) if (CM_IS_EMPTY_STR(ip)) { return CM_FALSE; } - uint32 len = ELEMENT_COUNT(ALL_LISTEN_ADDRESSES_ARRAY); - for (uint32 i = 0; i < len; ++i) { - if (cm_str_equal(ip, ALL_LISTEN_ADDRESSES_ARRAY[i])) { + uint32 len = ELEMENT_COUNT(IPV4_ALL_LISTEN_ADDRESSES_ARRAY); + uint32 i; + for (i = 0; i < len; ++i) { + if (cm_str_equal(ip, IPV4_ALL_LISTEN_ADDRESSES_ARRAY[i])) { return CM_TRUE; } } + + len = ELEMENT_COUNT(IPV6_ALL_LISTEN_ADDRESSES_ARRAY); + for (i = 0; i < len; ++i) { + if (cm_str_equal(ip, IPV6_ALL_LISTEN_ADDRESSES_ARRAY[i])) { + return CM_TRUE; + } + } + return CM_FALSE; } static bool8 IsIpSkipCheck(const char *ip) { - if (cm_str_equal(ip, LOCAL_HOST_ARRAY[0])) { + if (cm_str_equal(ip, LOCAL_HOST)) { return CM_TRUE; } if (IsCurIpAllListenAddress(ip)) { @@ -449,28 +462,6 @@ static status_t ParseDnText(DnResultText *dnText, uint32 instId) return CM_SUCCESS; } -static bool8 IsLocalHostIp(const char *ip) -{ - uint32 len = ELEMENT_COUNT(LOCAL_HOST_ARRAY); - for (uint32 i = 0; i < len; ++i) { - if (cm_str_equal(ip, LOCAL_HOST_ARRAY[i])) { - return CM_TRUE; - } - } - return CM_FALSE; -} - -static bool8 IsSameIp(const char *srcIp, const char *dstIp) -{ - if (cm_str_equal(srcIp, dstIp)) { - return CM_TRUE; - } - if (IsLocalHostIp(srcIp) && IsLocalHostIp(dstIp)) { - return CM_TRUE; - } - return CM_FALSE; -} - static bool8 IsFindVipInDnText(const DnResultText *dnText, const char *ip, bool8 isDel, bool8 *isAllListen) { if (CM_IS_EMPTY_STR(dnText->result) || CM_IS_EMPTY_STR(ip)) { @@ -490,7 +481,7 @@ static bool8 IsFindVipInDnText(const DnResultText *dnText, const char *ip, bool8 return CM_FALSE; } curIp = dnText->result + curPoint; - if (IsSameIp(ip, curIp)) { + if (IsEqualIp(ip, curIp)) { return CM_TRUE; } if (!isDel && IsCurIpAllListenAddress(curIp)) { @@ -524,7 +515,7 @@ static status_t GetDnListenAddressesFromFile(DnIpText *dnIpText, uint32 dnIdx) CM_RETURN_IFERR(GetDnText(dnIpText, INIT_DN_IP_LEN + dnFloatIp->dnFloatIpCount * CM_IP_LENGTH)); char cmd[MAX_PATH_LEN] = {0}; errno_t rc = snprintf_s(cmd, MAX_PATH_LEN, MAX_PATH_LEN - 1, "gs_guc check -Z datanode -D %s -c \"%s\" 2>&1 " - "| grep \"gs_guc check\" | awk -F ':' '{print $3}'", GetCurDnDataPath(dnIdx), LISTEN_ADDRESSES); + "| grep \"gs_guc check\" | awk -F ': ' '{print $3}'", GetCurDnDataPath(dnIdx), LISTEN_ADDRESSES); securec_check_intval(rc, (void)rc); uint32 instId = GetCurDnInstId(dnIdx); FILE *cmdFd = popen(cmd, "r"); @@ -568,7 +559,7 @@ static status_t GetDnListenAddressesFromFile(DnIpText *dnIpText, uint32 dnIdx) static int32 CheckFloatIpListen(const char *ip, uint32 dnIdx) { char cmd[INIT_DN_CMD_LEN] = {0}; - errno_t rc = snprintf_s(cmd, INIT_DN_CMD_LEN, INIT_DN_CMD_LEN - 1, "netstat -anop 2>&1 |grep \"" + errno_t rc = snprintf_s(cmd, INIT_DN_CMD_LEN, INIT_DN_CMD_LEN - 1, "netstat -anopW 2>&1 |grep \"" "$(ps -ux |grep -w \"%s/%s\"|grep -w \"%s\" |grep -v grep | awk '{print $2}')/%s\" " "| grep -w \"LISTEN\" | awk '{print $4}'| grep -w \"%s\"", g_binPath, GetDnProcessName(), GetCurDnDataPath(dnIdx), GetDnProcessName(), ip); @@ -603,12 +594,13 @@ static void GetAllFloatIpNetState(DnStatus *dnStatus, const DnFloatIp *dnFloatIp return; } - listenRet = CheckFloatIpListen(ALL_LISTEN_ADDRESSES, dnIdx); - if (listenRet == (int32)NETWORK_STATE_DOWN) { - return; - } - for (uint32 i = 0; i < dnFloatIp->dnFloatIpCount; ++i) { + listenRet = CheckFloatIpListen(GetIpVersion( + dnFloatIp->dnFloatIp[i]) == AF_INET6 ? IPV6_ALL_LISTEN_ADDRESSES : IPV4_ALL_LISTEN_ADDRESSES, + dnIdx); + if (listenRet == (int32)NETWORK_STATE_DOWN) { + continue; + } floatIpInfo->dnNetState[i] = listenRet; if (listenRet == (int32)NETWORK_STATE_UP) { floatIpInfo->dnNetState[i] = @@ -744,7 +736,7 @@ static status_t GetDnFloatIpCmd(const char *floatIp, DnIpText *dnIpText, Network curIp = dnText->result + curPoint; tmpFindCurIp = CM_FALSE; - if (IsSameIp(floatIp, curIp)) { + if (IsEqualIp(floatIp, curIp)) { isFindCurIp = CM_TRUE; tmpFindCurIp = CM_TRUE; } else { @@ -965,6 +957,83 @@ static void ClearFloatIpConn(DnIpText *dnIpText, const DnStatus *dnStatus, bool8 } } +void ReportPingDnFloatIpFailToCms(uint32 instanceId, char failedDnFloatIp[MAX_FLOAT_IP_COUNT][CM_IP_LENGTH], + uint32 failedCount) +{ + CmSendPingDnFloatIpFail reportMsg = {0}; + BaseInstInfo *baseInfo = &reportMsg.baseInfo; + baseInfo->msgType = (int)MSG_CMA_PING_DN_FLOAT_IP_FAIL; + baseInfo->node = g_currentNode->node; + baseInfo->instId = instanceId; + baseInfo->instType = INSTANCE_TYPE_DATANODE; + reportMsg.failedCount = failedCount; + + if (failedCount > MAX_FLOAT_IP_COUNT) { + write_runlog(ERROR, "[%s] failed float ip count %u more tahn max float ip count %u.\n", + __FUNCTION__, + failedCount, + MAX_FLOAT_IP_COUNT); + return; + } + errno_t rc; + for (uint32 i = 0; i < failedCount; ++i) { + rc = strcpy_s(reportMsg.failedDnFloatIp[i], CM_IP_LENGTH, failedDnFloatIp[i]); + securec_check_errno(rc, (void)rc); + } + PushMsgToCmsSendQue((char *)&reportMsg, (uint32)sizeof(CmSendPingDnFloatIpFail), "ping dn float ip fail"); +} + +bool8 CanPingDnFloatIp() +{ + static uint64 last = 0; + const long oneMinute = 60; + if ((GetMonotonicTimeS() - last) > oneMinute) { + last = GetMonotonicTimeS(); + write_runlog(LOG, "[%s] floatIp ping successful.\n", __FUNCTION__); + return CM_TRUE; + } + write_runlog(ERROR, "[%s] floatIp ping failed.\n", __FUNCTION__); + return CM_FALSE; +} + +void PingDnFloatIp(const DnStatus *dnstatus, uint32 dnIdx, bool8 isRuning) +{ + if (dnstatus->reportMsg.local_status.local_role == INSTANCE_ROLE_PRIMARY || !isRuning) { + return; + } + + DnFloatIp *dnFloatIp = GetDnFloatIpByDnIdx(dnIdx); + if (dnFloatIp == NULL) { + return; + } + + if (!CanPingDnFloatIp()) { + return; + } + + uint32 instanceId = g_currentNode->datanode[dnIdx].datanodeId; + char failedDnFloatIp[MAX_FLOAT_IP_COUNT][CM_IP_LENGTH] = {0}; + uint32 failedCount = 0; + errno_t rc; + for (uint32 i = 0; i < dnFloatIp->dnFloatIpCount; i++) { + if (IsLocalHostIp(dnFloatIp->dnFloatIp[i])) { + continue; + } + if (GetIpVersion(dnFloatIp->dnFloatIp[i]) != AF_INET6) { + continue; + } + + if (CheckPeerIp(dnFloatIp->dnFloatIp[i], "[PingFloatIp]", NULL, 1, AF_INET6) != PROCESS_STATUS_SUCCESS) { + rc = strcpy_s(failedDnFloatIp[failedCount], CM_IP_LENGTH, dnFloatIp->dnFloatIp[i]); + securec_check_errno(rc, (void)rc); + failedCount++; + } + } + if (failedCount > 0) { + ReportPingDnFloatIpFailToCms(instanceId, failedDnFloatIp, failedCount); + } +} + void DnCheckFloatIp(DnStatus *dnStatus, uint32 dnIdx, bool8 isRunning) { if (!IsNeedCheckFloatIp() || (agent_backup_open != CLUSTER_PRIMARY)) { @@ -984,6 +1053,7 @@ void DnCheckFloatIp(DnStatus *dnStatus, uint32 dnIdx, bool8 isRunning) DoFloatIpOper(dnIpText, dnStatus, dnIdx, isRunning); CheckDownFloatIp(dnIpText, dnStatus, dnIdx, isRunning); ClearFloatIpConn(dnIpText, dnStatus, isRunning, dnIdx); + PingDnFloatIp(dnStatus, dnIdx, isRunning); return; } diff --git a/src/cm_agent/client_adpts/libpq/cma_datanode_utils.cpp b/src/cm_agent/client_adpts/libpq/cma_datanode_utils.cpp index d40d25ceacb6e01e54bca15bfb9004a109c5e109..25f2a2d3063aab27fc1c1f41a011b085ba4845ee 100644 --- a/src/cm_agent/client_adpts/libpq/cma_datanode_utils.cpp +++ b/src/cm_agent/client_adpts/libpq/cma_datanode_utils.cpp @@ -602,31 +602,58 @@ int check_datanode_status_by_SQL3(agent_to_cm_datanode_status_report* report_msg return 0; } +static int ParseIpAndPort(char *addrStr, char *ipStr, uint32 *port) +{ + char *lastColon = strrchr(addrStr, ':'); + if (lastColon != NULL) { + // Calculate the position of the colon + size_t colonPos = lastColon - addrStr; + + // Copy the IP portion + errno_t rc = strncpy_s(ipStr, CM_IP_LENGTH, addrStr, colonPos); + securec_check_errno(rc, (void)rc); + ipStr[colonPos] = '\0'; // Ensure the string terminator + + // Copy the port portion + *port = (uint32)atoi(lastColon + 1); + return 0; // Success + } else { + return -1; + } +} + static void GetLpInfoByStr(char *channel, DnLocalPeer *lpInfo, uint32 instId) { - char *outerPtr = NULL; - char *token = strtok_r(channel, ":", &outerPtr); - errno_t rc = strcpy_s(lpInfo->localIp, CM_IP_LENGTH, token); - securec_check_errno(rc, (void)rc); - if (outerPtr == NULL) { - write_runlog(ERROR, "[GetLpInfoByStr] line: %d, instId is %u, channel is %s.\n", __LINE__, instId, channel); + char localIpStr[CM_IP_LENGTH]; + char peerIpStr[CM_IP_LENGTH]; + char *peerStr = NULL; + char *localStr = strtok_r(channel, "<--", &peerStr); + errno_t rc; + if (localStr == NULL) { + write_runlog(ERROR, "[GetLpInfoByStr] line: %d, instance ID is %u, channel is %s.\n", + __LINE__, instId, channel); return; } - token = strtok_r(NULL, "<", &outerPtr); - lpInfo->localPort = (uint32)CmAtoi(token, 0); - if (outerPtr == NULL) { - write_runlog(ERROR, "[GetLpInfoByStr] line: %d, instId is %u, channel is %s.\n", __LINE__, instId, channel); + + if (ParseIpAndPort(localStr, localIpStr, &lpInfo->localPort) == 0) { + rc = strcpy_s(lpInfo->localIp, CM_IP_LENGTH, localIpStr); + securec_check_errno(rc, (void)rc); + } else { + write_runlog(ERROR, "[GetLpInfoByStr] line: %d, instance ID is %u, channel is %s.\n", + __LINE__, instId, channel); return; } - outerPtr = outerPtr + strlen("--"); - if (outerPtr == NULL) { - write_runlog(ERROR, "[GetLpInfoByStr] line: %d, instId is %u, channel is %s.\n", __LINE__, instId, channel); + + // Parse peer IP and port + if (ParseIpAndPort(peerStr, peerIpStr, &lpInfo->peerPort) == 0) { + rc = strcpy_s(lpInfo->peerIp, CM_IP_LENGTH, peerIpStr); + securec_check_errno(rc, (void)rc); + } else { + write_runlog(ERROR, "[GetLpInfoByStr] line: %d, instance ID is %u, channel is %s.\n", + __LINE__, instId, channel); return; } - token = strtok_r(NULL, ":", &outerPtr); - rc = strcpy_s(lpInfo->peerIp, CM_IP_LENGTH, token); - securec_check_errno(rc, (void)rc); - lpInfo->peerPort = (uint32)CmAtoi(outerPtr, 0); + write_runlog(DEBUG1, "%u, channel is %s:%u<--%s:%u.\n", instId, lpInfo->localIp, lpInfo->localPort, lpInfo->peerIp, lpInfo->peerPort); } @@ -865,21 +892,23 @@ int check_datanode_status_by_SQL6(agent_to_cm_datanode_status_report* report_msg } report_msg->local_status.disconn_mode = datanode_lockmode_string_to_int(Getvalue(node_result, 0, 0)); - errno_t rc = memset_s(report_msg->local_status.disconn_host, HOST_LENGTH, 0, HOST_LENGTH); + errno_t rc = memset_s(report_msg->local_status.disconn_host, CM_IP_LENGTH, 0, CM_IP_LENGTH); securec_check_errno(rc, (void)rc); char *tmp_result = Getvalue(node_result, 0, 1); if (tmp_result != NULL && (strlen(tmp_result) > 0)) { - rc = snprintf_s(report_msg->local_status.disconn_host, HOST_LENGTH, HOST_LENGTH - 1, "%s", tmp_result); + rc = snprintf_s(report_msg->local_status.disconn_host, + CM_IP_LENGTH, CM_IP_LENGTH - 1, "%s", tmp_result); securec_check_intval(rc, (void)rc); } rc = sscanf_s(Getvalue(node_result, 0, 2), "%u", &(report_msg->local_status.disconn_port)); check_sscanf_s_result(rc, 1); securec_check_intval(rc, (void)rc); - rc = memset_s(report_msg->local_status.local_host, HOST_LENGTH, 0, HOST_LENGTH); + rc = memset_s(report_msg->local_status.local_host, CM_IP_LENGTH, 0, CM_IP_LENGTH); securec_check_errno(rc, (void)rc); tmp_result = Getvalue(node_result, 0, 3); if (tmp_result != NULL && (strlen(tmp_result) > 0)) { - rc = snprintf_s(report_msg->local_status.local_host, HOST_LENGTH, HOST_LENGTH - 1, "%s", tmp_result); + rc = snprintf_s(report_msg->local_status.local_host, + CM_IP_LENGTH, CM_IP_LENGTH - 1, "%s", tmp_result); securec_check_intval(rc, (void)rc); } rc = sscanf_s(Getvalue(node_result, 0, 4), "%u", &(report_msg->local_status.local_port)); diff --git a/src/cm_agent/cma_global_params.cpp b/src/cm_agent/cma_global_params.cpp index bf0926650966e8b3858b8079f2fd94f1512fca06..16ea31369ddd86c2369b4f1e050a9e6e41828fa1 100644 --- a/src/cm_agent/cma_global_params.cpp +++ b/src/cm_agent/cma_global_params.cpp @@ -226,6 +226,8 @@ char g_enableMesSsl[BOOL_STR_MAX_LEN] = {0}; uint32 g_sslCertExpireCheckInterval = SECONDS_PER_DAY; uint32 g_cmaRhbItvl = 1000; CmResConfList g_resConf[CM_MAX_RES_INST_COUNT] = {{{0}}}; +IpType g_ipType = IP_TYPE_INIT; +bool g_supportIpV6 = false; #ifndef ENABLE_MULTIPLE_NODES char g_dbServiceVip[CM_IP_LENGTH] = {0}; char g_enableFenceDn[10] = {0}; @@ -242,6 +244,16 @@ bool &GetIsSharedStorageMode() return g_isSharedStorageMode; } +bool GetEnvSupportIpV6() +{ + return g_supportIpV6; +} + +void SetEnvSupportIpV6(bool val) +{ + g_supportIpV6 = val; +} + #ifdef __aarch64__ /* * 0 indicates we do NOT bind cpu, diff --git a/src/cm_agent/cma_main.cpp b/src/cm_agent/cma_main.cpp index fc8726cda09983c003d3af8324d449740a77760e..333ec06899a1f7403ac896b88d5a1864e5a6ed78 100644 --- a/src/cm_agent/cma_main.cpp +++ b/src/cm_agent/cma_main.cpp @@ -30,6 +30,7 @@ #include "alarm/alarm_log.h" #include "cm/pqsignal.h" #include "cm_json_config.h" +#include "cm_ip.h" #include "cma_global_params.h" #include "cma_common.h" #include "cma_threads.h" @@ -549,6 +550,11 @@ int read_config_file_check(void) g_cnDnPairsCount = countCnAndDn(); initialize_cm_server_node_index(); + int family = GetIpVersion(g_currentNode->sshChannel[0]); + if (family != AF_INET && family != AF_INET6) { + (void)fprintf(stderr, "ip(%s) is invalid, nodeId=%u.\n", g_currentNode->sshChannel[0], g_nodeHeader.node); + return -1; + } rc = snprintf_s(g_cmAgentLogPath, MAX_PATH_LEN, MAX_PATH_LEN - 1, @@ -1652,6 +1658,7 @@ int main(int argc, char** argv) (void)fprintf(stderr, "can not get current user name.\n"); return -1; } + SetEnvSupportIpV6(CheckSupportIpV6()); status = CmSSlConfigInit(true); if (status < 0) { diff --git a/src/cm_agent/cma_network_check.cpp b/src/cm_agent/cma_network_check.cpp index 1ea75da50819ff89faa65fac13646c4d1483caa2..6810d232bd0570f1c7d01c466265922a7305758b 100644 --- a/src/cm_agent/cma_network_check.cpp +++ b/src/cm_agent/cma_network_check.cpp @@ -31,6 +31,7 @@ #include "cm_text.h" #include "cm_json_config.h" #include "cm_json_parse_floatIp.h" +#include "cm_ip.h" #include "cma_global_params.h" #include "cma_common.h" @@ -60,6 +61,7 @@ typedef struct NetworkInfoT { bool networkRes; NetworkType type; NetworkOper oper; + NetworkOper lasterOper; uint32 port; uint32 cnt; uint32 checkCnt; @@ -102,6 +104,8 @@ typedef struct NetworkStateStringMapT { static bool GetNicstatusByAddrs(const struct ifaddrs *ifList, NetworkInfo *netInfo, int32 logLevel = WARNING, NetworkQuest quest = NETWORK_QUEST_CHECK); static void GetNicDownCmd(char *cmd, uint32 cmdLen, const NetworkInfo *netInfo, uint32 index); +static void GetNicUpCmd(char *cmd, uint32 cmdLen, const NetworkInfo *netInfo, uint32 index, uint32 instId); +bool CheckNeedResetFloatIpExist(const char *ip, const DnFloatIp *dnFloatIp); static CmNetworkInfo *g_cmNetWorkInfo = NULL; static uint32 g_instCnt = 0; @@ -114,10 +118,12 @@ static NetworkStateOperMap g_stateOperMap[] = {{NETWORK_STATE_UNKNOWN, NETWORK_O {NETWORK_STATE_CEIL, NETWORK_OPER_CEIL}}; static const char *g_ifconfigCmd = "ifconfig"; +static const char *g_ipCmd = "ip"; static const char *const IFCONFIG_CMD_DEFAULT = "ifconfig"; static const char *const IFCONFIG_CMD_SUSE = "/sbin/ifconfig"; static const char *const IFCONFIG_CMD_EULER = "/usr/sbin/ifconfig"; static const char *const ARPING_CMD = "arping -w 1 -A -I"; +static const char *const NDISC6_CMD = "ndisc6"; static const char *const SHOW_IPV6_CMD = "ip addr show | grep"; static const char *const IPV6_TENTATIVE_FLAG = "tentative"; static const char *const IPV6_DADFAILED_FLAG = "dadfailed"; @@ -368,7 +374,7 @@ static bool8 IsCurIpInIpPool(const char **ipPool, uint32 cnt, const char *ip) if (ipPool[i] == NULL) { continue; } - if (cm_str_equal(ipPool[i], ip)) { + if (IsEqualIp(ipPool[i], ip)) { return CM_TRUE; } } @@ -841,42 +847,86 @@ static bool GetNetworkAddr(NetworkInfo *netInfo, const char *str) return ret; } -static bool SetDownIpV6Nic(const NetworkInfo *netInfo, uint32 index, const char *str) +status_t SetDownIpV6Nic(const NetworkInfo *netInfo, uint32 index, uint32 instId) { char cmd[CM_MAX_COMMAND_LONG_LEN] = {0}; GetNicDownCmd(cmd, CM_MAX_COMMAND_LONG_LEN, netInfo, index); if (cmd[0] == '\0') { - return false; + return CM_ERROR; } write_runlog(LOG, "%s Ip: %s oper=[%d: %s], state=[%d: %s], GetNicCmd(%s).\n", - str, netInfo->ips[index], (int32)netInfo->oper, GetOperMapString(netInfo->oper), + __FUNCTION__, netInfo->ips[index], (int32)netInfo->oper, GetOperMapString(netInfo->oper), (int32)netInfo->stateRecord[index], GetStateMapString(netInfo->stateRecord[index]), cmd); int32 res = ExecuteSystemCmd(cmd); if (res != 0) { - write_runlog(ERROR, "%s failed to execute the cmd(%s), res=%d, errno is %d.\n", str, cmd, res, errno); - return false; + write_runlog(ERROR, "%s failed to execute the cmd(%s), res=%d, errno is %d.\n", __FUNCTION__, cmd, res, errno); + return CM_ERROR; } else { - write_runlog(LOG, "%s successfully to execute the cmd(%s).\n", str, cmd); - return true; + netInfo->stateRecord[index] = NETWORK_STATE_DOWN; + write_runlog(LOG, "[%s] successfully to execute the cmd (%s).\n", + __FUNCTION__, cmd); + return CM_SUCCESS; } } -static bool CheckIpV6Valid(const NetworkInfo *netInfo, uint32 index, const char *str, int32 logLevel) +status_t SetUpIpV6Nic(const NetworkInfo *netInfo, uint32 index, uint32 instId) { char cmd[CM_MAX_COMMAND_LONG_LEN] = {0}; - errno_t rc = snprintf_s(cmd, CM_MAX_COMMAND_LONG_LEN, CM_MAX_COMMAND_LONG_LEN - 1, "%s %s |grep %s |grep %s", - SHOW_IPV6_CMD, netInfo->ips[index], IPV6_DADFAILED_FLAG, IPV6_TENTATIVE_FLAG); + GetNicUpCmd(cmd, CM_MAX_COMMAND_LONG_LEN, netInfo, index, instId); + if (cmd[0] == '\0') { + return CM_ERROR; + } + write_runlog(LOG, + "%s ip=%s; oper=[%d:%s], state=[%d:%s], GetNicCmd(%s).\n", + __FUNCTION__, + netInfo->ips[index], + (int32)netInfo->oper, + GetOperMapString(netInfo->oper), + (int32)netInfo->stateRecord[index], + GetStateMapString(netInfo->stateRecord[index]), + cmd); + int32 res = ExecuteSystemCmd(cmd); + if (res != 0) { + write_runlog(ERROR, "[%s] failed to execute the cmd (%s), res=%d, errno is %d.\n", + __FUNCTION__, cmd, res, errno); + return CM_ERROR; + } else { + netInfo->stateRecord[index] = NETWORK_STATE_UP; + write_runlog(LOG, "[%s] successfully to execute the cmd (%s).\n", + __FUNCTION__, cmd); + return CM_SUCCESS; + } +} + +bool CheckAndRemoveInvaildIpV6FloatIp(const NetworkInfo *netInfo, uint32 index, + const char *str, int32 logLevel, uint32 instId) +{ + char osFormatIp[CM_IP_LENGTH] = {0}; + if (!(ChangeIpV6ToOsFormat(netInfo->ips[index], osFormatIp, CM_IP_LENGTH))) { + write_runlog(ERROR, "[%s] failed to change IpV6(%s) to os format.\n", + str, netInfo->ips[index]); + return false; + } + char cmd[CM_MAX_COMMAND_LONG_LEN] = {0}; + errno_t rc = snprintf_s(cmd, + CM_MAX_COMMAND_LONG_LEN, + CM_MAX_COMMAND_LONG_LEN - 1, + "%s %s | grep %s | grep %s", + SHOW_IPV6_CMD, + osFormatIp, + IPV6_DADFAILED_FLAG, + IPV6_TENTATIVE_FLAG); securec_check_intval(rc, (void)rc); - write_runlog(logLevel, "%s it will check ipV6 nic, and cmd is %s.\n", str, cmd); - int32 ret = ExecuteSystemCmd(cmd); + write_runlog(logLevel, "%s it will check ipv6 nic, and cmd is %s.\n", str, cmd); + int32 ret = ExecuteSystemCmd(cmd, DEBUG1); if (ret == 0) { - write_runlog(logLevel, "%s ipV6(%s) nic may be faulty.\n", str, netInfo->ips[index]); - return SetDownIpV6Nic(netInfo, index, str); + write_runlog(logLevel, "%s IPV6(%s) nic may be faulty\n", str, osFormatIp); + return SetDownIpV6Nic(netInfo, index, instId) == CM_SUCCESS; } return true; } -static void GetNicUpCmd(char *cmd, uint32 cmdLen, const NetworkInfo *netInfo, uint32 index) +static void GetNicUpCmd(char *cmd, uint32 cmdLen, const NetworkInfo *netInfo, uint32 index, uint32 instId) { const NetWorkAddr *netAddr = &(netInfo->netAddr[index]); if (netInfo->netAddr[index].netMask[0] == '\0' || netInfo->netAddr[index].netName[0] == '\0') { @@ -889,12 +939,14 @@ static void GetNicUpCmd(char *cmd, uint32 cmdLen, const NetworkInfo *netInfo, ui TIMEOUT_MECHA, DEFAULT_CMD_TIMEOUT, g_sudoPermCmd, g_ifconfigCmd, netAddr->netName, netInfo->port, netInfo->ips[index], netAddr->netMask); } else if (netInfo->netAddr[index].family == AF_INET6) { - if (!CheckIpV6Valid(netInfo, index, "[GetNicUpCmd]", LOG)) { + if (!CheckAndRemoveInvaildIpV6FloatIp(netInfo, index, "[GetNicUpCmd]", LOG, instId)) { return; } - rc = snprintf_s(cmd, cmdLen, cmdLen - 1, "%s %us %s %s %s inet6 add %s/%s", - TIMEOUT_MECHA, DEFAULT_CMD_TIMEOUT, g_sudoPermCmd, g_ifconfigCmd, - netAddr->netName, netInfo->ips[index], netAddr->netMask); + rc = snprintf_s(cmd, cmdLen, cmdLen - 1, + "%s %us %s %s -6 addr add %s/64 dev %s preferred_lft 0 nodad", + TIMEOUT_MECHA, DEFAULT_CMD_TIMEOUT, SUDO_PERM_CMD, g_ipCmd, + netInfo->ips[index], netAddr->netName); + write_runlog(LOG, "IpV6AddCmd is %s \n", cmd); } securec_check_intval(rc, (void)rc); } @@ -911,9 +963,10 @@ static void GetNicDownCmd(char *cmd, uint32 cmdLen, const NetworkInfo *netInfo, TIMEOUT_MECHA, DEFAULT_CMD_TIMEOUT, g_sudoPermCmd, g_ifconfigCmd, netAddr->netName, netInfo->port); } else { - rc = snprintf_s(cmd, cmdLen, cmdLen - 1, "%s %us %s %s %s inet6 del %s/%s", - TIMEOUT_MECHA, DEFAULT_CMD_TIMEOUT, g_sudoPermCmd, g_ifconfigCmd, - netAddr->netName, netInfo->ips[index], netAddr->netMask); + rc = snprintf_s(cmd, cmdLen, cmdLen - 1, "%s %us %s %s -6 addr del %s/64 dev %s", + TIMEOUT_MECHA, DEFAULT_CMD_TIMEOUT, SUDO_PERM_CMD, g_ipCmd, + netInfo->ips[index], netAddr->netName); + write_runlog(LOG, "IpV6DelCmd is %s \n", cmd); } securec_check_intval(rc, (void)rc); } @@ -968,17 +1021,24 @@ static void GenArpingCmd(NetworkInfo *netInfo, uint32 index, bool8 *isExeArping) if (netInfo->oper != NETWORK_OPER_UP) { return; } + if (netInfo->netAddr[index].family == AF_INET6) { + return; + } errno_t rc = memset_s(netInfo->arpingCmd[index].cmd, CM_MAX_COMMAND_LONG_LEN, 0, CM_MAX_COMMAND_LONG_LEN); securec_check_errno(rc, (void)rc); if (netInfo->netAddr[index].family == AF_INET) { rc = snprintf_s(netInfo->arpingCmd[index].cmd, CM_MAX_COMMAND_LONG_LEN, CM_MAX_COMMAND_LONG_LEN - 1, "%s %s %s", ARPING_CMD, netInfo->netAddr[index].netName, netInfo->ips[index]); securec_check_intval(rc, (void)rc); + } else if (netInfo->netAddr[index].family == AF_INET6) { + rc = snprintf_s(netInfo->arpingCmd[index].cmd, CM_MAX_COMMAND_LONG_LEN, CM_MAX_COMMAND_LONG_LEN - 1, + "%s %s %s", NDISC6_CMD, netInfo->netAddr[index].netName, netInfo->ips[index]); + securec_check_intval(rc, (void)rc); } *isExeArping = CM_TRUE; } -static void DoUpOrDownNetworkOper(NetworkInfo *netInfo, bool8 *isExeArping) +static void DoUpOrDownNetworkOper(NetworkInfo *netInfo, bool8 *isExeArping, uint32 instId) { if (CheckNicStatusMeetsExpect(netInfo, isExeArping)) { return; @@ -995,7 +1055,7 @@ static void DoUpOrDownNetworkOper(NetworkInfo *netInfo, bool8 *isExeArping) rc = memset_s(cmd, CM_MAX_COMMAND_LONG_LEN, 0, CM_MAX_COMMAND_LONG_LEN); securec_check_errno(rc, (void)rc); if (netInfo->oper == NETWORK_OPER_UP && netInfo->stateRecord[i] != NETWORK_STATE_UP) { - GetNicUpCmd(cmd, CM_MAX_COMMAND_LONG_LEN, netInfo, i); + GetNicUpCmd(cmd, CM_MAX_COMMAND_LONG_LEN, netInfo, i, instId); } else if (netInfo->oper == NETWORK_OPER_DOWN && netInfo->stateRecord[i] == NETWORK_STATE_UP) { GetNicDownCmd(cmd, CM_MAX_COMMAND_LONG_LEN, netInfo, i); } @@ -1028,6 +1088,150 @@ static void CheckAndExecuteArpingCmd() for (uint32 i = 0; i < g_instCnt; ++i) { manaIp = &(g_cmNetWorkInfo[i].manaIp[NETWORK_TYPE_FLOATIP]); CheckArpingCmdRes(manaIp); + manaIp->lasterOper = manaIp->oper; + } +} + +bool CheckEnableIpV6AutoNotify() +{ + const char *cmd = "sysctl -n net.ipv6.conf.all.ndisc_notify"; + FILE *fp = popen(cmd, "r"); + if (fp == NULL) { + write_runlog(ERROR, + "[%s] popen failed, cmd=[%s], error is %d.\n", __FUNCTION__, cmd, errno); + return false; + } + + char buf[CM_MAX_NUMBER_LENGTH] = {0}; + if (fgets(buf, CM_MAX_NUMBER_LENGTH - 1, fp) != NULL) { + text_t text; + text.str = buf; + text.len = sizeof(buf); + CmTrimText(&text); + uint16 value; + if (CmText2Uint16(&text, &value) == CM_SUCCESS && value == 1) { + return true; + } + } + (void)pclose(fp); + write_runlog(DEBUG1, "[%s] exec cmd=[%s].\n", __FUNCTION__, cmd); + return false; +} + +bool CheckIpNicStatusUp(struct ifaddrs *ifList, const char *destIp) +{ + if (CM_IS_EMPTY_STR(destIp)) { + return false; + } + char host[NI_MAXHOST] = {0}; + for (const struct ifaddrs *ifa = ifList; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) { + continue; + } + + int32 family = ifa->ifa_addr->sa_family; + if (family != AF_INET && family != AF_INET6) { + continue; + } + size_t saLen = (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); + if (getnameinfo(ifa->ifa_addr, saLen, host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0) { + write_runlog(WARNING, "[%s] failed to get name info.\n", __FUNCTION__); + return false; + } + if (IsEqualIp(destIp, host) && IsNicAvailable(ifa, host, WARNING)) { + return true; + } + } + write_runlog(WARNING, "[%s] can't find nic related with %s.\n", __FUNCTION__, destIp); + return false; +} + +bool CheckIpNicExisting(const char *destIp) +{ + struct ifaddrs *ifList = NULL; + if (getifaddrs(&ifList) < 0) { + write_runlog(WARNING, "[%s] failed to get ifList.\n", __FUNCTION__); + return false; + } + + bool ret = CheckIpNicStatusUp(ifList, destIp); + freeifaddrs(ifList); + return ret; +} + +void ClearOneNeedResetFloatIp(const char *ip, DnFloatIp *dnFloatIp) +{ + for (uint32 i = 0; i < dnFloatIp->needResetFloatIpCnt; i++) { + if (IsEqualIp(ip, dnFloatIp->needResetFloatIp[i])) { + (void)pthread_rwlock_wrlock(&dnFloatIp->rwlock); + errno_t rc = memset_s(dnFloatIp->needResetFloatIp[i], CM_IP_LENGTH, 0, CM_IP_LENGTH); + securec_check_errno(rc, (void)rc); + dnFloatIp->needResetFloatIpCnt--; + (void)pthread_rwlock_unlock(&dnFloatIp->rwlock); + return; + } + } +} + +void ResetFloatIpV6(NetworkInfo *netInfo, DnFloatIp *dnFloatIp, uint32 instId) +{ + /* If the interface does not support NDISC, don't try reset. */ + if (!CheckEnableIpV6AutoNotify()) { + return; // Exit early if IPv6 auto notify is not enabled + } + + // Iterate through the network information + for (uint32 i = 0; i < netInfo->cnt; i++) { + // Skip network entries based on several conditions + if (netInfo->stateRecord[i] != NETWORK_STATE_UP || + netInfo->lasterOper == NETWORK_OPER_DOWN || + netInfo->netAddr[i].netMask[0] == '\0' || + netInfo->netAddr[i].netName[0] == '\0' || + netInfo->netAddr[i].family != AF_INET6) { + continue; + } + + // Skip if NIC doesn't exist or doesn't need resetting + if (!CheckIpNicExisting(netInfo->ips[i]) || + !CheckNeedResetFloatIpExist(netInfo->ips[i], dnFloatIp)) { + continue; + } + + if (SetDownIpV6Nic(netInfo, i, instId) != CM_SUCCESS) { + write_runlog(ERROR, + "[%s] set down float up(%s) failed, error is %d.\n", + __FUNCTION__, + netInfo->ips[i], + errno); + continue; + } + if (SetUpIpV6Nic(netInfo, i, instId) != CM_SUCCESS) { + write_runlog(ERROR, + "[%s] set up float up(%s) failed, error is %d.\n", + __FUNCTION__, + netInfo->ips[i], + errno); + continue; + } + ClearOneNeedResetFloatIp(netInfo->ips[i], dnFloatIp); + write_runlog(LOG, "[%s] reset float up(%s) success.\n", __FUNCTION__, netInfo->ips[i]); + } +} + +void CheckAndResetFloatIpV6() +{ + NetworkInfo *manaIp = NULL; + DnFloatIp *floatIp = NULL; + uint32 dnIdx = 0; + for (uint32 i = 0; i < g_instCnt; ++i) { + manaIp = &(g_cmNetWorkInfo[i].manaIp[NETWORK_TYPE_FLOATIP]); + if (manaIp->cnt == 0 || + !FindDnIdxInCurNode(g_cmNetWorkInfo[i].instId, &dnIdx, "[CheckAndResetFloatIpV6]") || + GetDnFloatIpByDnIdx(dnIdx) == NULL) { + continue; + } + ResetFloatIpV6(manaIp, floatIp, g_cmNetWorkInfo[i].instId); + manaIp->lasterOper = manaIp->oper; } } @@ -1045,11 +1249,10 @@ static void DoNetworkOper() if (manaIp->oper == NETWORK_OPER_UNKNOWN) { continue; } - DoUpOrDownNetworkOper(manaIp, &isExeArping); - } - if (isExeArping) { - CheckAndExecuteArpingCmd(); + DoUpOrDownNetworkOper(manaIp, &isExeArping, g_cmNetWorkInfo[i].instId); } + CheckAndExecuteArpingCmd(); + CheckAndResetFloatIpV6(); } static void ReleaseSource() @@ -1120,3 +1323,134 @@ void *CmaCheckNetWorkMain(void *arg) ReleaseSource(); return NULL; } + +void ClearAllNeedResetFloatIp(DnFloatIp *dnFloatIp) +{ + errno_t rc = + memset_s(dnFloatIp->needResetFloatIp, MAX_FLOAT_IP_COUNT * CM_IP_LENGTH, 0, + MAX_FLOAT_IP_COUNT * CM_IP_LENGTH); + securec_check_errno(rc, (void)rc); + dnFloatIp->needResetFloatIpCnt = 0; +} + +bool CheckFloatIpExist(const char *ip, DnFloatIp *dnFloatIp) +{ + for (uint32 i = 0; i < dnFloatIp->dnFloatIpCount; ++i) { + if (IsEqualIp(ip, dnFloatIp->dnFloatIp[i])) { + return true; + } + } + write_runlog(LOG, + "[%s] instId(%u) floatIp(%s) not existed.\n", + __FUNCTION__, + dnFloatIp->instId, + ip); + return false; +} + +bool CheckNeedResetFloatIpExist(const char *ip, const DnFloatIp *dnFloatIp) +{ + for (uint32 i = 0; i < dnFloatIp->needResetFloatIpCnt; i++) { + if (IsEqualIp(ip, dnFloatIp->needResetFloatIp[i])) { + return true; + } + } + write_runlog(DEBUG1, + "[%s] instId(%u) floatIp(%s) not existed in dn need reset floatIp.\n", + __FUNCTION__, + dnFloatIp->instId, + ip); + return false; +} + +void SetNeedResetFloatIp(const CmSendPingDnFloatIpFail *recvMsg, uint32 dnIdx) +{ + if (dnIdx >= CM_MAX_DATANODE_PER_NODE) { + return; + } + DnFloatIp *floatIp = GetDnFloatIpByDnIdx(dnIdx); + if (floatIp == NULL) { + return; + } + if (recvMsg->failedCount == 0 || recvMsg->failedCount > floatIp->dnFloatIpCount) { + write_runlog(WARNING, + "[%s] need reset floatIp count %u more than dn floatIp count %u or is zero.\n", + __FUNCTION__, + recvMsg->failedCount, + floatIp->dnFloatIpCount); + return; + } + write_runlog(LOG, + "[%s] instId(%u) recv failed sount %u, cur need reset count %u, total count %u.\n", + __FUNCTION__, + g_floatIpMap.floatIp[dnIdx].instId, + recvMsg->failedCount, + floatIp->needResetFloatIpCnt, + floatIp->dnFloatIpCount); + + (void)pthread_rwlock_wrlock(&floatIp->rwlock); + if (floatIp->needResetFloatIpCnt >= floatIp->dnFloatIpCount) { + ClearAllNeedResetFloatIp(floatIp); + } + + errno_t rc; + for (uint32 i = 0; i < recvMsg->failedCount; i++) { + if (floatIp->needResetFloatIpCnt >= floatIp->dnFloatIpCount) { + break; + } + if (!CheckFloatIpExist(recvMsg->failedDnFloatIp[i], floatIp)) { + continue; + } + if (CheckNeedResetFloatIpExist(recvMsg->failedDnFloatIp[i], floatIp)) { + continue; + } + rc = strcpy_s(floatIp->needResetFloatIp[floatIp->needResetFloatIpCnt], + CM_IP_LENGTH, recvMsg->failedDnFloatIp[i]); + securec_check_errno(rc, (void)rc); + write_runlog(LOG, "[%s] instIs(%u) need reset floatIp %s.\n", + __FUNCTION__, + g_floatIpMap.floatIp[dnIdx].instId, + floatIp->needResetFloatIp[floatIp->needResetFloatIpCnt]); + floatIp->needResetFloatIpCnt++; + } + (void)pthread_rwlock_unlock(&floatIp->rwlock); + write_runlog(LOG, + "[%s] instIs(%u) recv failed count %u, need resest floatIp total count %u.\n", + __FUNCTION__, + g_floatIpMap.floatIp[dnIdx].instId, + recvMsg->failedCount, + floatIp->needResetFloatIpCnt); +} + +bool CheckSupportIpV6() +{ + char cmd[CM_MAX_COMMAND_LONG_LEN] = {0}; + errno_t rc = snprintf_s(cmd, + CM_MAX_COMMAND_LONG_LEN, + CM_MAX_COMMAND_LONG_LEN - 1, + "%s a | grep 'int6 ::1' | wc -l", + g_ipCmd); + securec_check_intval(rc, (void)rc); + FILE *fp = popen(cmd, "r"); + if (fp == NULL) { + write_runlog(ERROR, "[%s] popen faild, cmd=[%s], errno=%d.\n", __FUNCTION__, cmd, errno); + return false; + } + + bool support = false; + char buf[CM_MAX_NUMBER_LENGTH] = {0}; + if (fgets(buf, CM_MAX_NUMBER_LENGTH - 1, fp) != NULL) { + text_t text; + text.str = buf; + text.len = sizeof(buf); + CmTrimText(&text); + uint16 value; + if (CmText2Uint16(&text, &value) == CM_SUCCESS && value >= 1) { + support = true; + } + } + (void)pclose(fp); + write_runlog(LOG, "[%s] exec command:%s, support:%u.\n", __FUNCTION__, cmd, support); + + return support; +} \ No newline at end of file diff --git a/src/cm_agent/cma_process_messages.cpp b/src/cm_agent/cma_process_messages.cpp index 7312a3e1c40634af1b44e10a5eea416ef3b975bd..5c3458337900f6e60d8c394d843577858f0f66df 100644 --- a/src/cm_agent/cma_process_messages.cpp +++ b/src/cm_agent/cma_process_messages.cpp @@ -23,7 +23,8 @@ */ #include "securec.h" #include "cm/cm_elog.h" -#include "cm/cm_msg.h" +#include "cm_msg_version_convert.h" +#include "cm_ip.h" #include "cm/cm_util.h" #include "cma_common.h" #include "cma_global_params.h" @@ -1702,14 +1703,28 @@ static void MsgCmAgentLockNoPrimary(const AgentMsgPkg *msg, char *dataPath, cons static void MsgCmAgentLockChosenPrimary(const AgentMsgPkg *msg, char *dataPath, const cm_msg_type *msgTypePtr) { int ret; - const cm_to_agent_lock2 *msgTypeLock2Ptr = - (const cm_to_agent_lock2 *)CmGetMsgBytesPtr(msg, sizeof(cm_to_agent_lock2)); - if (msgTypeLock2Ptr == NULL) { - return; + errno_t rc; + cm_to_agent_lock2 msgTypeLock = {0}; + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + const cm_to_agent_lock2_ipv4 *msgTypeLock2PtrIpv4 = + (const cm_to_agent_lock2_ipv4 *)CmGetMsgBytesPtr(msg, sizeof(cm_to_agent_lock2_ipv4)); + if (msgTypeLock2PtrIpv4 == NULL) { + return; + } + CmToAgentLock2V1ToV2(msgTypeLock2PtrIpv4, &msgTypeLock); + } else { + const cm_to_agent_lock2 *msgTypeLock2Ptr = + (const cm_to_agent_lock2 *)CmGetMsgBytesPtr(msg, sizeof(cm_to_agent_lock2)); + if (msgTypeLock2Ptr == NULL) { + return; + } + rc = memcpy_s(&msgTypeLock, sizeof(cm_to_agent_lock2), msgTypeLock2Ptr, sizeof(cm_to_agent_lock2)); + securec_check_errno(rc, (void)rc); } - ret = ProcessLockChosenPrimaryCmd(msgTypeLock2Ptr); + + ret = ProcessLockChosenPrimaryCmd(&msgTypeLock); if (ret != 0) { - write_runlog(ERROR, "set lock2 to instance %u failed.\n", msgTypeLock2Ptr->instanceId); + write_runlog(ERROR, "set lock2 to instance %u failed.\n", msgTypeLock.instanceId); } } @@ -1879,6 +1894,44 @@ static void MsgCmAgentIsregCheckListChanged(const AgentMsgPkg *msg, char *dataPa ProcessIsregCheckListChanged(recvMsg); } +void ProcessResetFloatIpFromCms(const CmSendPingDnFloatIpFail *recvMsg) +{ + write_runlog(LOG, + "[%s] nodeId(%u) instId(%u) receive floatIp from cms, count %u.\n", + __FUNCTION__, + recvMsg->baseInfo.node, + recvMsg->baseInfo.instId, + recvMsg->failedCount); + + uint32 dnIdx = 0; + bool ret = FindDnIdxInCurNode(recvMsg->baseInfo.instId, &dnIdx, "[ProcessResetFloatIpFromCms]"); + if (!ret) { + write_runlog(ERROR, + "[%s] cannot do the network oper in instId(%u), because it cannot be found in current node.\n", + __FUNCTION__, + recvMsg->baseInfo.instId); + return; + } + SetNeedResetFloatIp(recvMsg, dnIdx); +} + +void MsgCmAgentResetFloatIpAck(const AgentMsgPkg *msg, char *dataPath, const cm_msg_type *msgTypePtr) +{ + const CmSendPingDnFloatIpFail *recvMsg = + (const CmSendPingDnFloatIpFail *)CmGetMsgBytesPtr(msg, sizeof(CmSendPingDnFloatIpFail)); + if (recvMsg == NULL) { + return; + } + if (!IsNeedCheckFloatIp() || (agent_backup_open != CLUSTER_PRIMARY)) { + write_runlog(DEBUG1, + "[%s] agent_backup_open=%d, cannot reset floatIp oper.\n", + __FUNCTION__, + (int32)agent_backup_open); + return; + } + ProcessResetFloatIpFromCms(recvMsg); +} + #ifdef ENABLE_MULTIPLE_NODES static void MsgCmAgentNotifyCn(const AgentMsgPkg* msg, char *dataPath, const cm_msg_type* msgTypePtr) { @@ -2031,6 +2084,7 @@ void CmServerCmdProcessorInit(void) g_cmsCmdProcessor[MSG_CM_RES_REG] = MsgCmAgentResArbitrate; g_cmsCmdProcessor[MSG_CM_AGENT_FLOAT_IP_ACK] = MsgCmAgentFloatIpAck; g_cmsCmdProcessor[MSG_CM_AGENT_ISREG_CHECK_LIST_CHANGED] = MsgCmAgentIsregCheckListChanged; + g_cmsCmdProcessor[MSG_CMS_NOTIFY_PRIMARY_DN_RESET_FLOAT_IP] = MsgCmAgentResetFloatIpAck; #ifdef ENABLE_MULTIPLE_NODES g_cmsCmdProcessor[MSG_CM_AGENT_NOTIFY_CN] = MsgCmAgentNotifyCn; g_cmsCmdProcessor[MSG_CM_AGENT_NOTIFY_CN_CENTRAL_NODE] = MsgCmAgentNotifyCnCentralNode; diff --git a/src/cm_agent/cma_status_check.cpp b/src/cm_agent/cma_status_check.cpp index 2d0f8850f5ec992f1526dfa1229252f0df72c45c..72bd3e19c716a10fa662f25847c99a862512bcec 100644 --- a/src/cm_agent/cma_status_check.cpp +++ b/src/cm_agent/cma_status_check.cpp @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "cma_connect.h" #include "cma_global_params.h" #include "cma_common.h" @@ -38,6 +40,8 @@ #include "cma_coordinator.h" #endif #include "cma_status_check.h" +#include "cm_ip.h" +#include "cm_msg_version_convert.h" /* * dilatation status. If the cluster in dilatation status, we query coordinate and report status for every loop. Or, @@ -770,13 +774,19 @@ void kerberos_status_check_and_report() static void SendDnReportMsg(const DnStatus *pkgDnStatus, uint32 datanodeId) { - agent_to_cm_datanode_status_report reportMsg = {0}; - errno_t rc = memcpy_s(&reportMsg, sizeof(agent_to_cm_datanode_status_report), - &pkgDnStatus->reportMsg, sizeof(agent_to_cm_datanode_status_report)); - securec_check_errno(rc, (void)rc); - - write_runlog(DEBUG5, "dn(%u) reportMsg will send to cms.\n", datanodeId); - PushMsgToCmsSendQue((char *)&reportMsg, (uint32)sizeof(agent_to_cm_datanode_status_report), "dn report"); + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + agent_to_cm_datanode_status_report_ipv4 reportMsg = {0}; + AgentToCmDatanodeStatusReportV2ToV1(&pkgDnStatus->reportMsg, &reportMsg); + write_runlog(DEBUG5, "dn(%u) reportMsg will send to cms.\n", datanodeId); + PushMsgToCmsSendQue((char *)&reportMsg, (uint32)sizeof(agent_to_cm_datanode_status_report_ipv4), "dn report"); + } else { + agent_to_cm_datanode_status_report reportMsg = {0}; + errno_t rc = memcpy_s(&reportMsg, sizeof(agent_to_cm_datanode_status_report), + &pkgDnStatus->reportMsg, sizeof(agent_to_cm_datanode_status_report)); + securec_check_errno(rc, (void)rc); + write_runlog(DEBUG5, "dn(%u) reportMsg will send to cms.\n", datanodeId); + PushMsgToCmsSendQue((char *)&reportMsg, (uint32)sizeof(agent_to_cm_datanode_status_report), "dn report"); + } } static void SendBarrierMsg(const DnStatus *pkgDnStatus, uint32 datanodeId) @@ -1486,11 +1496,13 @@ static void PingPeerIP(int* count, const char localIP[CM_IP_LENGTH], const char { char command[MAXPGPATH] = {0}; char buf[MAXPGPATH]; + int rc; uint32 tryTimes = 3; - int rc = snprintf_s(command, MAXPGPATH, MAXPGPATH - 1, - "ping -c 1 -w 1 -I %s %s > /dev/null;if [ $? == 0 ];then echo success;else echo fail;fi;", - localIP, peerIP); + const char *pingStr = GetPingStr(GetIpVersion(peerIP)); + rc = snprintf_s(command, MAXPGPATH, MAXPGPATH - 1, + "%s -c 1 -w 1 -I %s %s > /dev/null;if [ $? == 0 ];then echo success;else echo fail;fi;", + pingStr, localIP, peerIP); securec_check_intval(rc, (void)rc); write_runlog(DEBUG1, "ping command is: %s.\n", command); diff --git a/src/cm_common/cm_ip.cpp b/src/cm_common/cm_ip.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb11a46cd1ef99773e2d244c6e8686db539b8fd1 --- /dev/null +++ b/src/cm_common/cm_ip.cpp @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2024 Huawei Technologies Co.,Ltd. + * + * CM is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * ------------------------------------------------------------------------- + * + *cm_ip.cpp + * + * + * IDENTIFICATION + * src/cm_common/cm_ip.cpp + * + * ------------------------------------------------------------------------- + */ +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#include +#else +#include +#endif + +#include "cm_msg_common.h" +#include "cm_misc_base.h" +#include "cm_elog.h" +#include "cm_text.h" +#include "cm_ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static const char *const IPV4_LOCAL_HOST_ARRAY[] = {"localhost", "127.0.0.1"}; +static const char *const IPV6_LOCAL_HOST_ARRAY[] = {"::1"}; + +/* This is used to get the type of the ip address*/ +int32 GetIpVersion(const char *ip_address) +{ + if (ip_address == NULL) { + return -1; + } + + struct in_addr ipv4_addr; + struct in6_addr ipv6_addr; + + if (inet_pton(AF_INET, ip_address, &ipv4_addr) == 1) { + return AF_INET; + } + + if (inet_pton(AF_INET6, ip_address, &ipv6_addr) == 1) { + return AF_INET6; + } + write_runlog(ERROR, "[%s] invalid, get ip %s version faild", __FUNCTION__, ip_address); + return -1; +} + +char *GetPingStr(int32 family) +{ + if (family == AF_INET6) { + return "ping6"; + } else { + return "ping"; + } +} + +status_t BuildSockAddrIpV4(const char *host, int port, sock_addr_t *sockAddr) +{ + struct sockaddr_in *in4 = NULL; + sockAddr->salen = (socklen_t)sizeof(struct sockaddr_in); + in4 = SOCKADDR_IN4(sockAddr); + + errno_t rc = memset_s(in4, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in)); + securec_check_errno(rc, (void)rc); + + in4->sin_family = AF_INET; + in4->sin_port = htons((uint16)port); +#ifndef WIN32 + in4->sin_addr.s_addr = inet_addr(host); + if (in4->sin_addr.s_addr == (in_addr_t)(-1) || (inet_pton(AF_INET, host, &in4-> +sin_addr.s_addr) != 1)) { +#else + if (InetPton(AF_INET, host, &in4->sin_addr.s_addr) != 1) { +#endif + write_runlog(ERROR, "[%s] ip(%s) is invalid.\n", __FUNCTION__, host); + return CM_ERROR; + } + return CM_SUCCESS; +} + +char *IpV6LocalLink(const char *host, char *ip, uint32 ipLen) +{ + errno_t errcode; + size_t hostLen; + int i = 0; + + while (host[i] && host[i] != '%') { + i++; + } + + if (host[i] == '\0') { + return NULL; + } else { + hostLen = (uint32)strlen(host); + errcode = strncpy_s(ip, (size_t)ipLen, host, (size_t)hostLen); + if (SECUREC_UNLIKELY(errcode != EOK)) { + write_runlog(ERROR, "[%s] strncpy_s failed, error code %d.\n", __FUNCTION__, errcode); + return NULL; + } + + ip[i] = '\0'; + return ip + i + 1; + } +} + +status_t BuildSockAddrIpV6(const char *host, int port, sock_addr_t *sockAddr) +{ + struct sockaddr_in6 *in6 = NULL; +#ifndef WIN32 + char ip[CM_IP_LENGTH]; + char *scope = NULL; +#endif + + sockAddr->salen = (socklen_t)sizeof(struct sockaddr_in6); + in6 = SOCKADDR_IN6(sockAddr); + + errno_t rc = memset_s(in6, sizeof(struct sockaddr_in6), 0, sizeof(struct sockaddr_in6)); + securec_check_errno(rc, (void)rc); + + in6->sin6_family = AF_INET6; + in6->sin6_port = htons((uint16)port); + +#ifndef WIN32 + scope = IpV6LocalLink(host, ip, CM_IP_LENGTH); + if (scope != NULL) { + in6->sin6_scope_id = if_nametoindex(scope); + if (in6->sin6_scope_id == 0) { + write_runlog(ERROR, "[%s] invalid local link (%s).\n", __FUNCTION__, scope); + return CM_ERROR; + } + + host = ip; + } + if (inet_pton(AF_INET6, host, &in6->sin6_addr) != 1) { +#else + if (InetPton(AF_INET6, host, &in6->sin6_addr) != 1) { +#endif + write_runlog(ERROR, "[%s] ip(%s) invalid.\n", __FUNCTION__, host); + return CM_ERROR; + } + return CM_SUCCESS; +} + +status_t BuildSockAddr(const char *host, int port, sock_addr_t *sockAddr) +{ + int family = GetIpVersion(host); + switch (family) { + case AF_INET: + return BuildSockAddrIpV4(host, port, sockAddr); + case AF_INET6: + return BuildSockAddrIpV6(host, port, sockAddr); + default: + write_runlog(ERROR, "[%s] ip(%s) invalid.\n", __FUNCTION__, host); + return CM_ERROR; + } +} + +status_t IpToSockAddr(const char *host, sock_addr_t *sockAddr) +{ +#define CM_INVALID_IP_PORT 0 + return BuildSockAddr(host, CM_INVALID_IP_PORT, sockAddr); +} + +bool CheckIpValid(const char *ip) +{ + if (CM_IS_EMPTY_STR(ip)) { + return false; + } + char tempIp[CM_IP_LENGTH] = {0}; + if (NeedAndRemoveSquareBracketsForIpV6(ip, tempIp, CM_IP_LENGTH)) { + write_runlog(ERROR, "[%s] ip (%s) is invalid.\n", __FUNCTION__, ip); + return false; + } + + if (IsLocalHostIp(tempIp)) { + return true; + } + + sock_addr_t sockAddr; + if (IpToSockAddr(tempIp, &sockAddr) != CM_SUCCESS) { + write_runlog(ERROR, "[%s] ip(%s) is invalid.\n", __FUNCTION__, ip); + return false; + } + + return true; +} + +bool IsEqualIp(const char *clientIp, const char *localIp) +{ + if (IsLocalHostIp(clientIp) && IsLocalHostIp(localIp)) { + return true; + } + + sock_addr_t clientSockAddr = {0}; + sock_addr_t localSockAddr = {0}; + if (IpToSockAddr(localIp, &localSockAddr) != CM_SUCCESS || + IpToSockAddr(clientIp, &clientSockAddr) != CM_SUCCESS) { + return false; + } + + if (memcmp(&localSockAddr, &clientSockAddr, sizeof(sock_addr_t)) == 0) { + return true; + } + return false; +} + +bool8 IsLocalHostIp(const char *ip) +{ + if (CM_IS_EMPTY_STR(ip)) { + return CM_FALSE; + } + + char tempIp[CM_IP_LENGTH] = {0}; + if (NeedAndRemoveSquareBracketsForIpV6(ip, tempIp, CM_IP_LENGTH) != CM_SUCCESS) { + return false; + } + + uint32 len = ELEMENT_COUNT(IPV4_LOCAL_HOST_ARRAY); + uint32 i; + for (i = 0; i < len; ++i) { + if (cm_str_equal(tempIp, IPV4_LOCAL_HOST_ARRAY[i])) { + return CM_TRUE; + } + } + len = ELEMENT_COUNT(IPV6_LOCAL_HOST_ARRAY); + for (i = 0; i < len; ++i) { + if (cm_str_equal(tempIp, IPV6_LOCAL_HOST_ARRAY[i])) { + return CM_TRUE; + } + } + return CM_FALSE; +} + +bool ChangeIpV6ToOsFormat(const char *sourceIp, char *destIp, uint32 destSize) +{ + if (CM_IS_EMPTY_STR(sourceIp)) { + return false; + } + if (GetIpVersion(sourceIp) != AF_INET6) { + return false; + } + struct in6_addr sin6Addr; + errno_t rc = memset_s(&sin6Addr, sizeof(sin6Addr), 0, sizeof(sin6Addr)); + securec_check_errno(rc, (void)rc); + if (inet_pton(AF_INET6, sourceIp, &sin6Addr) != 1) { + return false; + } + if (inet_ntop(AF_INET6, &sin6Addr, destIp, destSize) == NULL) { + return false; + } + return true; +} + +status_t NeedAndRemoveSquareBracketsForIpV6(const char *sourceIp, char *destIp, uint32 size) +{ + if (sourceIp == NULL) { + return CM_ERROR; + } + text_t text; + CmStr2Text((char *)sourceIp, &text); + CmRemoveSquareBrackets(&text); + return CmText2Str(&text, destIp, size); +} + +ProcessStatus GetPopenCmdResult(const char *cmd, const char *str, int32 tryTimes) +{ + if (CM_IS_EMPTY_STR(cmd)) { + write_runlog(ERROR, "%s cmd is NULL, cannot popen cmd.\n", str); + return PROCESS_STATUS_UNKNOWN; + } + char buf[MAX_PATH_LEN + MAX_PATH_LEN]; + FILE *fp; + errno_t rc; + ProcessStatus pSt = PROCESS_STATUS_INIT; + do { + rc = memset_s(buf, sizeof(buf), 0, sizeof(buf)); + securec_check_intval(rc, (void)rc); + fp = popen(cmd, "re"); + if (fp == NULL) { + write_runlog(ERROR, "%s popen failed, cmd is %s, error is %d.\n", str, cmd, errno); + return PROCESS_STATUS_UNKNOWN; + } + while (fgets(buf, sizeof(buf), fp) != NULL) { + if (strstr(buf, "success") != NULL) { + (void)pclose(fp); + return PROCESS_STATUS_SUCCESS; + } else if (strstr(buf, "unknown") != NULL) { + pSt = PROCESS_STATUS_UNKNOWN; + } else if (pSt == PROCESS_STATUS_INIT && strstr(buf, "fail") != NULL) { + pSt = PROCESS_STATUS_FAIL; + } + } + (void)pclose(fp); + --tryTimes; + if (tryTimes > 0) { + cm_sleep(1); + } + } while (tryTimes > 0); + if (pSt != PROCESS_STATUS_SUCCESS) { + write_runlog(ERROR, "%s failed to popen: %s, cmd is %s.\n", str, buf, cmd); + } + return pSt; +} + +ProcessStatus CheckPeerIp(const char *peerIp, const char *str, const char *localIp, + int32 tryTimes, int32 family) +{ + if (CM_IS_EMPTY_STR(peerIp)) { + write_runlog(ERROR, "%s failed to check peer ip, because peerIp is NULL.\n", str); + return PROCESS_STATUS_UNKNOWN; + } + + char tempPeerIp[CM_IP_LENGTH] = {0}; + if (NeedAndRemoveSquareBracketsForIpV6(peerIp, tempPeerIp, CM_IP_LENGTH) != CM_SUCCESS) { + write_runlog(ERROR, "%s peer ip %s invalid.\n", __FUNCTION__, peerIp); + return PROCESS_STATUS_UNKNOWN; + } + const char *pingStr = GetPingStr(family); + + char cmd[MAX_PATH_LEN + MAX_PATH_LEN] = {0}; + errno_t rc; + if (CM_IS_EMPTY_STR(localIp)) { + rc = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "tmp0=$(%s -c 1 -w 1 %s);", pingStr, tempPeerIp); + } else { + char tempLocalIp[CM_IP_LENGTH] = {0}; + if (NeedAndRemoveSquareBracketsForIpV6(localIp, tempLocalIp, CM_IP_LENGTH) != CM_SUCCESS) { + write_runlog(ERROR, "%s local ip %s invalid.\n", __FUNCTION__, localIp); + return PROCESS_STATUS_UNKNOWN; + } + rc = snprintf_s(cmd, + sizeof(cmd), + sizeof(cmd) - 1, + "tmp0=$(%s -c 1 w 1 -I %s %s);", + pingStr, + tempLocalIp, + tempPeerIp); + } + securec_check_intval(rc, (void)rc); + + uint32 len = (uint32)strlen(cmd); + const char *temp1 = family == AF_INET ? "ping -c 1 -w 1 127.0.0.1 2>&1" : "ping6 -w 1 ::1 2>&1"; + rc = snprintf_s(cmd +len, + sizeof(cmd) - len, + (sizeof(cmd) - len) -1, + "if [ $? == 0]; then echo \"%s\"; " + "else tmp1=$(%s)" + "if [ $? == 0 ]; then echo \"%s ${tmp0}\"|tr '\\n' '|'; " + "else echo \"%s ${tmp0} || ${tmp1}\"|tr '\\n' '|'; fi; fi", + PING_SUCCESS, + temp1, + PING_FAIL, + PING_UNKNOWN); + securec_check_intval(rc, (void)rc); + write_runlog(DEBUG1, "%s ping command is %s.\n", str, cmd); + + return GetPopenCmdResult(cmd, str, tryTimes); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/cm_common/cm_json_parse_floatIp.cpp b/src/cm_common/cm_json_parse_floatIp.cpp index ab98130ae998103becad5021cb077d6eaa86b008..99a8443da065f961de0a6563e5dc7830e29c4ac3 100644 --- a/src/cm_common/cm_json_parse_floatIp.cpp +++ b/src/cm_common/cm_json_parse_floatIp.cpp @@ -27,6 +27,7 @@ #include "cm_elog.h" #include "cm_misc.h" #include "cm_json_config.h" +#include "cm_ip.h" static const ParseFloatIpFunc *g_parseFuc = NULL; @@ -45,11 +46,11 @@ static bool IsBaseIpInDnFloatIp(const char *baseIp, const char *floatIp, uint32 return true; } for (uint32 i = 0; i < dnFloatIp->dnFloatIpCount; ++i) { - if (strcmp(baseIp, dnFloatIp->baseIp[i]) == 0) { + if (IsEqualIp(baseIp, dnFloatIp->baseIp[i])) { write_runlog(LOG, "instId(%u) baseIp(%s) may be existed in floatIp.\n", dnFloatIp->instId, baseIp); return true; } - if (strcmp(floatIp, dnFloatIp->dnFloatIp[i]) == 0) { + if (IsEqualIp(floatIp, dnFloatIp->dnFloatIp[i])) { write_runlog(LOG, "instId(%u) floatIp(%s) may be existed in floatIp.\n", dnFloatIp->instId, floatIp); return true; } @@ -120,12 +121,12 @@ static void CheckDnInstInItem(const VipCusResConfJson *vipConf, const char *floa continue; } if (CM_IS_EMPTY_STR(vipConf->baseIpList.conf[i].baseIp) || - CheckIpValid(vipConf->baseIpList.conf[i].baseIp) == CM_FALSE) { + !CheckIpValid(vipConf->baseIpList.conf[i].baseIp)) { continue; } baseIp = vipConf->baseIpList.conf[i].baseIp; check_input_for_security(baseIp); - if (strcmp(baseIp, floatIp) == 0) { + if (IsEqualIp(baseIp, floatIp)) { continue; } GenDnFloat(nodeIdx, dnIdx, baseIp, floatIp, floatIpName); @@ -147,7 +148,7 @@ void ParseVipConf(int32 logLevel) continue; } if (CM_IS_EMPTY_STR(g_confJson->resource.conf[i].vipResConf.floatIp) || - CheckIpValid(g_confJson->resource.conf[i].vipResConf.floatIp) == CM_FALSE) { + !CheckIpValid(g_confJson->resource.conf[i].vipResConf.floatIp)) { continue; } rc = memset_s(floatIp, MAX_PATH_LEN, 0, MAX_PATH_LEN); diff --git a/src/cm_common/cm_misc.cpp b/src/cm_common/cm_misc.cpp index 8aa382d9e32ffb6aaf512ca1ce3a38d154b81bee..d06117943a3298572ee943550c0cf9320afb4045 100644 --- a/src/cm_common/cm_misc.cpp +++ b/src/cm_common/cm_misc.cpp @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include "openssl/x509.h" #include "openssl/hmac.h" #include "openssl/rand.h" @@ -46,7 +48,8 @@ #include "common/config/cm_config.h" #include "cm/cm_cipher.h" #include "cm/cm_misc.h" -#include +#include "cm/cm_ip.h" + /* * ssh connect does not exit automatically when the network is fault, * this will cause cm_ctl hang for several hours, @@ -834,6 +837,8 @@ cluster_msg_string cluster_msg_map_string[] = { {"MSG_CTL_CM_FLOAT_IP_REQ", (int32)MSG_CTL_CM_FLOAT_IP_REQ}, {"MSG_CM_AGENT_FLOAT_IP_ACK", (int32)MSG_CM_AGENT_FLOAT_IP_ACK}, {"MSG_AGENT_CM_ISREG_REPORT", (int32)MSG_AGENT_CM_ISREG_REPORT}, + {"MSG_CMA_PING_DN_FLOAT_IP_FAIL", (int32)MSG_CMA_PING_DN_FLOAT_IP_FAIL}, + {"MSG_CMS_NOTIFY_PRIMARY_DN_RESET_FLOAT_IP", (int32)MSG_CMS_NOTIFY_PRIMARY_DN_RESET_FLOAT_IP}, {"MSG_CM_AGENT_ISREG_CHECK_LIST_CHANGED", (int32)MSG_CM_AGENT_ISREG_CHECK_LIST_CHANGED}, {NULL, MSG_TYPE_BUTT}, }; @@ -1339,7 +1344,9 @@ status_t IsReachableIP(char *ip) return CM_ERROR; } char cmd[MAXPGPATH] = {0}; - int rc = snprintf_s(cmd, MAXPGPATH, MAXPGPATH - 1, "timeout 2 ping -c 2 %s > /dev/null 2>&1", ip); + int rc; + const char *pingStr = GetPingStr(GetIpVersion(ip)); + rc = snprintf_s(cmd, MAXPGPATH, MAXPGPATH - 1, "timeout 2 %s -c 2 %s > /dev/null 2>&1", pingStr, ip); securec_check_intval(rc, (void)rc); rc = system(cmd); return rc == 0 ? CM_SUCCESS : CM_ERROR; diff --git a/src/cm_common/cm_misc_res.cpp b/src/cm_common/cm_misc_res.cpp index 225346383cc48c5accc198f0cde4d706f464da9f..d2035f5db65fbaba788e28e13e0ffa6e0888d106 100644 --- a/src/cm_common/cm_misc_res.cpp +++ b/src/cm_common/cm_misc_res.cpp @@ -34,15 +34,6 @@ static uint32 g_resCount = 0; static uint32 g_resNode[CM_MAX_RES_NODE_COUNT] = {0}; static uint32 g_resNodeCount = 0; -typedef enum IpTypeEn { - IP_TYPE_INIT = 0, - IP_TYPE_UNKNOWN = 1, - IP_TYPE_IPV4, - IP_TYPE_IPV6, - IP_TYPE_NEITHER, - IP_TYPE_CEIL, -} IpType; - typedef struct ResConfRangeSt { const char *param; int min; @@ -506,107 +497,6 @@ status_t GetResNameByCmInstId(uint32 instId, char *resName, uint32 nameLen) return CM_ERROR; } -static IpType GetIpType(const char *ip) -{ - if (CM_IS_EMPTY_STR(ip)) { - return IP_TYPE_NEITHER; - } - int32 ip4Cnt = 0; - int32 ip6Cnt = 0; - const int32 ip4CntTotal = 3; - const int32 ip6CntMax = 7; - const int32 ip6CntMin = 2; - uint32 ipLen = (uint32)strlen(ip); - for (uint32 i = 0; i < ipLen; ++i) { - if (ip[i] == '.') { - ++ip4Cnt; - } else if (ip[i] == ':') { - ++ip6Cnt; - } - } - if (ip6Cnt == 0 && ip4Cnt == ip4CntTotal) { - return IP_TYPE_IPV4; - } - if (ip4Cnt == 0 && (ip6Cnt >= ip6CntMin && ip6Cnt <= ip6CntMax)) { - return IP_TYPE_IPV6; - } - write_runlog(ERROR, "ip(%s) is invalid, and ip4Cnt=%d, ip6Cnd=%d.\n", ip, ip4Cnt, ip6Cnt); - return IP_TYPE_NEITHER; -} - -static uint8 CheckIpV4PartlyValid(const char *ipPart) -{ - if (CM_is_str_all_digit(ipPart) != 0) { - write_runlog(ERROR, "ip(%s) is not digital.\n", ipPart); - return CM_FALSE; - } - const uint32 maxLen = 3; - uint32 ipLen = (uint32)strlen(ipPart); - if (ipLen > maxLen) { - return CM_FALSE; - } - if (ipPart[0] == '0' && ipLen > 1) { - write_runlog(ERROR, "ip(%s) first is 0.\n", ipPart); - return CM_FALSE; - } - const int32 maxValue = 255; - int32 value = (int32)CmAtoi(ipPart, 0); - if (value < 0 || value > maxValue) { - write_runlog(ERROR, "ip(%s) value(%d) is not in [%d: %d].\n", ipPart, value, 0, maxValue); - return CM_FALSE; - } - return CM_TRUE; -} - -static uint8 CheckIpV4Valid(char *ip, uint32 ipLen) -{ - if (CM_IS_EMPTY_STR(ip)) { - return CM_FALSE; - } - char baseIp[CM_IP_LENGTH] = {0}; - errno_t rc = strncpy_s(baseIp, CM_IP_LENGTH, ip, ipLen); - securec_check_errno(rc, (void)rc); - - const char *ipPoint = "."; - char *savePtr = NULL; - // first - char *subStr = strtok_r(ip, ipPoint, &savePtr); - CM_RETFALSE_IFNOT(CheckIpV4PartlyValid(subStr)); - - int cnt = 1; - while (!CM_IS_EMPTY_STR(savePtr)) { - subStr = strtok_r(NULL, ipPoint, &savePtr); - CM_RETFALSE_IFNOT(CheckIpV4PartlyValid(subStr)); - ++cnt; - } - const int maxIpv4Part = 4; - if (cnt != maxIpv4Part) { - write_runlog(ERROR, "ip(%s) is invalid, cnt=%d.\n", baseIp, cnt); - return CM_FALSE; - } - - return CM_TRUE; -} - -uint8 CheckIpValid(const char *ip) -{ - char tempIp[CM_IP_LENGTH] = {0}; - errno_t rc = strcpy_s(tempIp, CM_IP_LENGTH, ip); - securec_check_errno(rc, (void)rc); - - if (GetIpType(tempIp) != IP_TYPE_IPV4) { - write_runlog(ERROR, "ip(%s) is invalid, not ipV4.\n", ip); - return CM_FALSE; - } - - if (CheckIpV4Valid(tempIp, CM_IP_LENGTH) == CM_FALSE) { - write_runlog(ERROR, "ipV4(%s) is invalid.\n", ip); - return CM_FALSE; - } - - return CM_TRUE; -} - uint32 CusResCount() { return g_resCount; diff --git a/src/cm_common/cm_msg_version_convert.cpp b/src/cm_common/cm_msg_version_convert.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4586b8be9ffcc0b92365ebb11e4c137de28903ae --- /dev/null +++ b/src/cm_common/cm_msg_version_convert.cpp @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2024 Huawei Technologies Co.,Ltd. + * + * CM is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * ------------------------------------------------------------------------- + * + *cm_msg_version_convert.cpp + * + * + * IDENTIFICATION + * src/cm_common/cm_msg_version_convert.cpp + * + * ------------------------------------------------------------------------- + */ + +#include "cm_msg_version_convert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void CmToAgentLock2V1ToV2(const cm_to_agent_lock2_ipv4 *v1, cm_to_agent_lock2 *v2) +{ + v2->instanceId = v1->instanceId; + v2->msg_type = v1->msg_type; + v2->node = v1->node; + errno_t rc = snprintf_s(v2->disconn_host, + CM_IP_LENGTH, (int)strlen(v1->disconn_host), + "%s", + v1->disconn_host); + securec_check_intval(rc, (void)rc); + v2->disconn_port = v1->disconn_port; +} + +void CmToAgentLock2V2ToV1(const cm_to_agent_lock2 *v2, cm_to_agent_lock2_ipv4 *v1) +{ + v1->instanceId = v2->instanceId; + v1->msg_type = v2->msg_type; + v1->node = v2->node; + errno_t rc = strncpy_s(v1->disconn_host, HOST_LENGTH, v2->disconn_host, HOST_LENGTH - 1); + securec_check_errno(rc, (void)rc); + v1->disconn_port = v2->disconn_port; +} + +void CmLocalReplconninfoV1ToV2(const cm_local_replconninfo_ipv4 *v1, cm_local_replconninfo *v2) +{ + v2->buildReason = v1->buildReason; + v2->db_state = v1->db_state; + errno_t rc = snprintf_s(v2->disconn_host, CM_IP_LENGTH, (int)strlen(v1->disconn_host), "%s", v1->disconn_host); + securec_check_intval(rc, (void)rc); + v2->disconn_mode = v1->disconn_mode; + v2->disconn_port = v1->disconn_port; + v2->last_flush_lsn = v1->last_flush_lsn; + rc = snprintf_s(v2->local_host, CM_IP_LENGTH, (int)strlen(v1->local_host), "%s", v1->local_host); + securec_check_intval(rc, (void)rc); + v2->local_port = v1->local_port; + v2->local_role = v1->local_role; + v2->redo_finished = v1->redo_finished; + v2->static_connections = v1->static_connections; + v2->term = v1->term; +} + +void CmLocalReplconninfoV2ToV1(const cm_local_replconninfo *v2, cm_local_replconninfo_ipv4 *v1) +{ + v1->buildReason = v2->buildReason; + v1->db_state = v2->db_state; + errno_t rc = strncpy_s(v1->disconn_host, HOST_LENGTH, v2->disconn_host, HOST_LENGTH - 1); + securec_check_errno(rc, (void)rc); + v1->disconn_mode = v2->disconn_mode; + v1->disconn_port = v2->disconn_port; + v1->last_flush_lsn = v2->last_flush_lsn; + rc = strncpy_s(v1->local_host, HOST_LENGTH, v2->local_host, HOST_LENGTH - 1); + securec_check_errno(rc, (void)rc); + v1->local_port = v2->local_port; + v1->local_role = v2->local_role; + v1->redo_finished = v2->redo_finished; + v1->static_connections = v2->static_connections; + v1->term = v2->term; +} + +void AgentToCmDatanodeStatusReportV1ToV2(const agent_to_cm_datanode_status_report_ipv4 *v1, + agent_to_cm_datanode_status_report *v2) +{ + errno_t rc = memcpy_s((void *)&(v2->build_info), + sizeof(BuildState), + (void *const)&(v1->build_info), + sizeof(BuildState)); + securec_check_intval(rc, (void)rc); + v2->connectStatus = v1->connectStatus; + v2->dn_restart_counts = v1->dn_restart_counts; + v2->dn_restart_counts_in_hour = v1->dn_restart_counts_in_hour; + v2->dnVipStatus = v1->dnVipStatus; + v2->instanceId = v1->instanceId; + v2->instanceType = v1->instanceType; + rc = memcpy_s((void *)&(v2->local_redo_stats), + sizeof(cm_redo_stats), + (void *const)&(v1->local_redo_stats), + sizeof(cm_redo_stats)); + securec_check_intval(rc, (void)rc); + CmLocalReplconninfoV1ToV2(&v1->local_status, &v2->local_status); + v2->msg_type = v1->msg_type; + v2->node = v1->node; + rc = memcpy_s((void *)&(v2->parallel_redo_status), + sizeof(RedoStatsData), + (void *const)&(v1->parallel_redo_status), + sizeof(RedoStatsData)); + securec_check_intval(rc, (void)rc); + v2->phony_dead_times = v1->phony_dead_times; + v2->processStatus = v1->processStatus; + rc = memcpy_s((void *)&(v2->receive_status), + sizeof(cm_receiver_replconninfo), + (void *const)&(v1->receive_status), + sizeof(cm_receiver_replconninfo)); + securec_check_intval(rc, (void)rc); + rc = memcpy_s((void *)&(v2->sender_status[0]), + CM_MAX_SENDER_NUM * sizeof(cm_sender_replconninfo), + (void *const)v1->sender_status, + CM_MAX_SENDER_NUM * sizeof(cm_sender_replconninfo)); + securec_check_intval(rc, (void)rc); +} + +void AgentToCmDatanodeStatusReportV2ToV1(const agent_to_cm_datanode_status_report *v2, + agent_to_cm_datanode_status_report_ipv4 *v1) +{ + errno_t rc = memcpy_s((void *)&(v1->build_info), + sizeof(BuildState), + (void *const)&(v2->build_info), + sizeof(BuildState)); + securec_check_intval(rc, (void)rc); + v1->connectStatus = v2->connectStatus; + v1->dn_restart_counts = v2->dn_restart_counts; + v1->dn_restart_counts_in_hour = v2->dn_restart_counts_in_hour; + v1->dnVipStatus = v2->dnVipStatus; + v1->instanceId = v2->instanceId; + v1->instanceType = v2->instanceType; + rc = memcpy_s((void *)&(v1->local_redo_stats), + sizeof(cm_redo_stats), + (void *const)&(v2->local_redo_stats), + sizeof(cm_redo_stats)); + securec_check_intval(rc, (void)rc); + CmLocalReplconninfoV2ToV1(&v2->local_status, &v1->local_status); + v1->msg_type = v2->msg_type; + v1->node = v2->node; + rc = memcpy_s((void *)&(v1->parallel_redo_status), + sizeof(RedoStatsData), + (void *const)&(v2->parallel_redo_status), + sizeof(RedoStatsData)); + securec_check_intval(rc, (void)rc); + v1->phony_dead_times = v2->phony_dead_times; + v1->processStatus = v2->processStatus; + rc = memcpy_s((void *)&(v1->receive_status), + sizeof(cm_receiver_replconninfo), + (void *const)&(v2->receive_status), + sizeof(cm_receiver_replconninfo)); + securec_check_intval(rc, (void)rc); + rc = memcpy_s((void *)&(v1->sender_status[0]), + CM_MAX_SENDER_NUM * sizeof(cm_sender_replconninfo), + (void *const)v2->sender_status, + CM_MAX_SENDER_NUM * sizeof(cm_sender_replconninfo)); + securec_check_intval(rc, (void)rc); +} + +void CmDnReportStatusMsgV1ToV2(const CmDnReportStatusMsg_ipv4 *v1, CmDnReportStatusMsg *v2) +{ + v2->arbiTime = v1->arbiTime; + v2->arbitrateFlag = v1->arbitrateFlag; + v2->archive_LSN = v1->archive_LSN; + errno_t rc = snprintf_s(v2->barrierID, BARRIERLEN, BARRIERLEN-1, "%s", v1->barrierID); + securec_check_intval(rc, (void)rc); + v2->barrierLSN = v1->barrierLSN; + rc = memcpy_s((void *)&(v2->build_info), sizeof(BuildState), (void *const)&(v1->build_info), sizeof(BuildState)); + securec_check_intval(rc, (void)rc); + v2->ckpt_redo_point = v1->ckpt_redo_point; + v2->dn_restart_counts = v1->dn_restart_counts; + v2->dn_restart_counts_in_hour = v1->dn_restart_counts_in_hour; + rc = memcpy_s((void *)&(v2->dnLp), sizeof(DatanodelocalPeer), (void *const)&(v1->dnLp), sizeof(DatanodelocalPeer)); + securec_check_intval(rc, (void)rc); + rc = memcpy_s((void *)&(v2->dnSyncList), sizeof(DatanodeSyncList), (void *const)&(v1->dnSyncList), + sizeof(DatanodeSyncList)); + securec_check_intval(rc, (void)rc); + v2->failoverStep = v1->failoverStep; + v2->failoverTimeout = v1->failoverTimeout; + v2->flush_LSN = v1->flush_LSN; + v2->is_barrier_exist = v1->is_barrier_exist; + v2->is_finish_redo_cmd_sent = v1->is_finish_redo_cmd_sent; + rc = memcpy_s((void *)&(v2->local_redo_stats), sizeof(cm_redo_stats), (void *const)&(v1->local_redo_stats), + sizeof(cm_redo_stats)); + securec_check_intval(rc, (void)rc); + CmLocalReplconninfoV1ToV2(&v1->local_status, &v2->local_status); + rc = memcpy_s((void *)&(v2->parallel_redo_status), sizeof(RedoStatsData), (void *const)&(v1->parallel_redo_status), + sizeof(RedoStatsData)); + securec_check_intval(rc, (void)rc); + v2->phony_dead_interval = v1->phony_dead_interval; + v2->phony_dead_times = v1->phony_dead_times; + v2->printBegin = v1->printBegin; + rc = memcpy_s((void *)&(v2->printBegin), sizeof(cmTime_t), (void *const)&(v1->printBegin), sizeof(cmTime_t)); + securec_check_intval(rc, (void)rc); + rc = snprintf_s(v2->query_barrierId, BARRIERLEN, BARRIERLEN-1, "%s", v1->query_barrierId); + securec_check_intval(rc, (void)rc); + rc = memcpy_s((void *)&(v2->receive_status), sizeof(cm_receiver_replconninfo), (void *const)&(v1->receive_status), + sizeof(cm_receiver_replconninfo)); + securec_check_intval(rc, (void)rc); + v2->send_gs_guc_time = v1->send_gs_guc_time; + v2->sender_count = v1->sender_count; + rc = memcpy_s((void *)&(v2->sender_status[0]), CM_MAX_SENDER_NUM * sizeof(cm_sender_replconninfo), + (void *const)v1->sender_status, CM_MAX_SENDER_NUM * sizeof(cm_sender_replconninfo)); + securec_check_intval(rc, (void)rc); + v2->sendFailoverTimes = v1->sendFailoverTimes; + v2->sync_standby_mode = v1->sync_standby_mode; + v2->syncDone = v1->syncDone; +} + +void CmDnReportStatusMsgV2ToV1(const CmDnReportStatusMsg *v2, CmDnReportStatusMsg_ipv4 *v1) +{ + v1->arbiTime = v2->arbiTime; + v1->arbitrateFlag = v2->arbitrateFlag; + v1->archive_LSN = v2->archive_LSN; + errno_t rc = snprintf_s(v1->barrierID, BARRIERLEN, BARRIERLEN-1, "%s", v2->barrierID); + securec_check_intval(rc, (void)rc); + v1->barrierLSN = v2->barrierLSN; + rc = memcpy_s((void *)&(v1->build_info), sizeof(BuildState), (void *const)&(v2->build_info), sizeof(BuildState)); + securec_check_intval(rc, (void)rc); + v1->ckpt_redo_point = v2->ckpt_redo_point; + v1->dn_restart_counts = v2->dn_restart_counts; + v1->dn_restart_counts_in_hour = v2->dn_restart_counts_in_hour; + rc = memcpy_s((void *)&(v1->dnLp), sizeof(DatanodelocalPeer), (void *const)&(v2->dnLp), sizeof(DatanodelocalPeer)); + securec_check_intval(rc, (void)rc); + rc = memcpy_s((void *)&(v1->dnSyncList), sizeof(DatanodeSyncList), (void *const)&(v2->dnSyncList), + sizeof(DatanodeSyncList)); + securec_check_intval(rc, (void)rc); + v1->failoverStep = v2->failoverStep; + v1->failoverTimeout = v2->failoverTimeout; + v1->flush_LSN = v2->flush_LSN; + v1->is_barrier_exist = v2->is_barrier_exist; + v1->is_finish_redo_cmd_sent = v2->is_finish_redo_cmd_sent; + rc = memcpy_s((void *)&(v1->local_redo_stats), sizeof(cm_redo_stats), (void *const)&(v2->local_redo_stats), + sizeof(cm_redo_stats)); + securec_check_intval(rc, (void)rc); + CmLocalReplconninfoV2ToV1(&v2->local_status, &v1->local_status); + rc = memcpy_s((void *)&(v1->parallel_redo_status), sizeof(RedoStatsData), (void *const)&(v2->parallel_redo_status), + sizeof(RedoStatsData)); + securec_check_intval(rc, (void)rc); + v1->phony_dead_interval = v2->phony_dead_interval; + v1->phony_dead_times = v2->phony_dead_times; + v1->printBegin = v2->printBegin; + rc = memcpy_s((void *)&(v1->printBegin), sizeof(cmTime_t), (void *const)&(v2->printBegin), sizeof(cmTime_t)); + securec_check_intval(rc, (void)rc); + rc = snprintf_s(v1->query_barrierId, BARRIERLEN, BARRIERLEN-1, "%s", v2->query_barrierId); + securec_check_intval(rc, (void)rc); + rc = memcpy_s((void *)&(v1->receive_status), sizeof(cm_receiver_replconninfo), (void *const)&(v2->receive_status), + sizeof(cm_receiver_replconninfo)); + securec_check_intval(rc, (void)rc); + v1->send_gs_guc_time = v2->send_gs_guc_time; + v1->sender_count = v2->sender_count; + rc = memcpy_s((void *)&(v1->sender_status[0]), CM_MAX_SENDER_NUM * sizeof(cm_sender_replconninfo), + (void *const)v2->sender_status, CM_MAX_SENDER_NUM * sizeof(cm_sender_replconninfo)); + securec_check_intval(rc, (void)rc); + v1->sendFailoverTimes = v2->sendFailoverTimes; + v1->sync_standby_mode = v2->sync_standby_mode; + v1->syncDone = v2->syncDone; +} + +void CmToCtlGetDatanodeRelationAckV1ToV2(const cm_to_ctl_get_datanode_relation_ack_ipv4 *v1, + cm_to_ctl_get_datanode_relation_ack *v2) +{ + v2->command_result = v1->command_result; + for (uint32 i = 0; i < CM_PRIMARY_STANDBY_MAX_NUM; ++i) { + CmDnReportStatusMsgV1ToV2(&v1->data_node_member[i], &v2->data_node_member[i]); + } + errno_t rc = memcpy_s((void *)&(v2->gtm_member[0]), + CM_PRIMARY_STANDBY_NUM * sizeof(cm_instance_gtm_report_status), + (void *const)v1->gtm_member, + CM_PRIMARY_STANDBY_NUM * sizeof(cm_instance_gtm_report_status)); + securec_check_intval(rc, (void)rc); + rc = memcpy_s((void *)&(v2->instanceMember[0]), + CM_PRIMARY_STANDBY_MAX_NUM * sizeof(CM_PRIMARY_STANDBY_MAX_NUM), + (void *const)v1->instanceMember, + CM_PRIMARY_STANDBY_MAX_NUM * sizeof(cm_instance_role_status)); + securec_check_intval(rc, (void)rc); + v2->member_index = v1->member_index; +} + +void CmToCtlGetDatanodeRelationAckV2ToV1(const cm_to_ctl_get_datanode_relation_ack *v2, + cm_to_ctl_get_datanode_relation_ack_ipv4 *v1) +{ + v1->command_result = v2->command_result; + for (uint32 i = 0; i < CM_PRIMARY_STANDBY_MAX_NUM; ++i) { + CmDnReportStatusMsgV2ToV1(&v2->data_node_member[i], &v1->data_node_member[i]); + } + errno_t rc = memcpy_s((void *)&(v1->gtm_member[0]), + CM_PRIMARY_STANDBY_NUM * sizeof(cm_instance_gtm_report_status), + (void *const)v2->gtm_member, + CM_PRIMARY_STANDBY_NUM * sizeof(cm_instance_gtm_report_status)); + securec_check_intval(rc, (void)rc); + rc = memcpy_s((void *)&(v1->instanceMember[0]), + CM_PRIMARY_STANDBY_MAX_NUM * sizeof(CM_PRIMARY_STANDBY_MAX_NUM), + (void *const)v2->instanceMember, + CM_PRIMARY_STANDBY_MAX_NUM * sizeof(cm_instance_role_status)); + securec_check_intval(rc, (void)rc); + v1->member_index = v2->member_index; +} + +void CmToCtlInstanceDatanodeStatusV1ToV2(const cm_to_ctl_instance_datanode_status_ipv4 *v1, + cm_to_ctl_instance_datanode_status *v2) +{ + errno_t rc = memcpy_s((void *)&(v2->build_info), + sizeof(BuildState), + (void *const)&(v1->build_info), + sizeof(BuildState)); + securec_check_intval(rc, (void)rc); + rc = memcpy_s((void *)&(v2->local_redo_stats), + sizeof(cm_redo_stats), + (void *const)&(v1->local_redo_stats), + sizeof(cm_redo_stats)); + securec_check_intval(rc, (void)rc); + CmLocalReplconninfoV1ToV2(&v1->local_status, &v2->local_status); + rc = memcpy_s((void *)&(v2->parallel_redo_status), + sizeof(RedoStatsData), + (void *const)&(v1->parallel_redo_status), + sizeof(RedoStatsData)); + securec_check_intval(rc, (void)rc); + rc = memcpy_s((void *)&(v2->receive_status), + sizeof(cm_receiver_replconninfo), + (void *const)&(v1->receive_status), + sizeof(cm_receiver_replconninfo)); + securec_check_intval(rc, (void)rc); + v2->send_gs_guc_time = v1->send_gs_guc_time; + v2->sender_count = v1->sender_count; + rc = memcpy_s((void *)&(v2->sender_status[0]), + CM_MAX_SENDER_NUM * sizeof(cm_sender_replconninfo), + (void *const)v1->sender_status, + CM_MAX_SENDER_NUM * sizeof(cm_sender_replconninfo)); + securec_check_intval(rc, (void)rc); + v2->sync_standby_mode = v1->sync_standby_mode; +} + +void CmToCtlInstanceDatanodeStatusV2ToV1(const cm_to_ctl_instance_datanode_status *v2, + cm_to_ctl_instance_datanode_status_ipv4 *v1) +{ + errno_t rc = memcpy_s((void *)&(v1->build_info), + sizeof(BuildState), + (void *const)&(v2->build_info), + sizeof(BuildState)); + securec_check_intval(rc, (void)rc); + rc = memcpy_s((void *)&(v1->local_redo_stats), + sizeof(cm_redo_stats), + (void *const)&(v2->local_redo_stats), + sizeof(cm_redo_stats)); + securec_check_intval(rc, (void)rc); + CmLocalReplconninfoV2ToV1(&v2->local_status, &v1->local_status); + rc = memcpy_s((void *)&(v1->parallel_redo_status), + sizeof(RedoStatsData), + (void *const)&(v2->parallel_redo_status), + sizeof(RedoStatsData)); + securec_check_intval(rc, (void)rc); + rc = memcpy_s((void *)&(v1->receive_status), + sizeof(cm_receiver_replconninfo), + (void *const)&(v2->receive_status), + sizeof(cm_receiver_replconninfo)); + securec_check_intval(rc, (void)rc); + v1->send_gs_guc_time = v2->send_gs_guc_time; + v1->sender_count = v2->sender_count; + rc = memcpy_s((void *)&(v1->sender_status[0]), + CM_MAX_SENDER_NUM * sizeof(cm_sender_replconninfo), + (void *const)v2->sender_status, + CM_MAX_SENDER_NUM * sizeof(cm_sender_replconninfo)); + securec_check_intval(rc, (void)rc); + v1->sync_standby_mode = v2->sync_standby_mode; +} + +void CmToCtlInstanceStatusV1ToV2(const cm_to_ctl_instance_status_ipv4 *v1, cm_to_ctl_instance_status *v2) +{ + v2->coordinatemember = v1->coordinatemember; + errno_t rc = memcpy_s((void *)&(v2->coordinatemember), + sizeof(cm_to_ctl_instance_coordinate_status), + (void *const)&(v1->coordinatemember), + sizeof(cm_to_ctl_instance_coordinate_status)); + securec_check_intval(rc, (void)rc); + CmToCtlInstanceDatanodeStatusV1ToV2(&v1->data_node_member, &v2->data_node_member); + v2->fenced_UDF_status = v1->fenced_UDF_status; + rc = memcpy_s((void *)&(v2->gtm_member), + sizeof(cm_to_ctl_instance_gtm_status), + (void *const)&(v1->gtm_member), + sizeof(cm_to_ctl_instance_gtm_status)); + securec_check_intval(rc, (void)rc); + v2->instance_type = v1->instance_type; + v2->instanceId = v1->instanceId; + v2->is_central = v1->is_central; + v2->member_index = v1->member_index; + v2->msg_type = v1->msg_type; + v2->node = v1->node; +} + +void CmToCtlInstanceStatusV2ToV1(const cm_to_ctl_instance_status *v2, cm_to_ctl_instance_status_ipv4 *v1) +{ + v1->coordinatemember = v2->coordinatemember; + errno_t rc = memcpy_s((void *)&(v1->coordinatemember), + sizeof(cm_to_ctl_instance_coordinate_status), + (void *const)&(v2->coordinatemember), + sizeof(cm_to_ctl_instance_coordinate_status)); + securec_check_intval(rc, (void)rc); + CmToCtlInstanceDatanodeStatusV2ToV1(&v2->data_node_member, &v1->data_node_member); + v1->fenced_UDF_status = v2->fenced_UDF_status; + rc = memcpy_s((void *)&(v1->gtm_member), + sizeof(cm_to_ctl_instance_gtm_status), + (void *const)&(v2->gtm_member), + sizeof(cm_to_ctl_instance_gtm_status)); + securec_check_intval(rc, (void)rc); + v1->instance_type = v2->instance_type; + v1->instanceId = v2->instanceId; + v1->is_central = v2->is_central; + v1->member_index = v2->member_index; + v1->msg_type = v2->msg_type; + v1->node = v2->node; +} + +void GetCtlInstanceStatusFromRecvMsg(char *receiveMsg, cm_to_ctl_instance_status *ctlInstanceStatusPtr) +{ + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + cm_to_ctl_instance_status_ipv4 *statusPtrIpv4 = (cm_to_ctl_instance_status_ipv4 *)receiveMsg; + CmToCtlInstanceStatusV1ToV2(statusPtrIpv4, ctlInstanceStatusPtr); + } else { + errno_t rc = memcpy_s(ctlInstanceStatusPtr, + sizeof(cm_to_ctl_instance_status), + receiveMsg, + sizeof(cm_to_ctl_instance_status)); + securec_check_intval(rc, (void)rc); + } +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/cm_common/cm_text.cpp b/src/cm_common/cm_text.cpp index 282abd7c12fe585014f29eaf2f35c39736218dda..9f6f302d8a06e618abdd967f0d66a0c933d5ffe0 100644 --- a/src/cm_common/cm_text.cpp +++ b/src/cm_common/cm_text.cpp @@ -21,12 +21,15 @@ * ------------------------------------------------------------------------- */ #include +#include #include "cm_text.h" #include "securec.h" #include "cm_debug.h" +#include "cm_error.h" #include "cm_elog.h" +#include "cm_config.h" bool8 IsCmBracketText(const text_t *text) { @@ -65,6 +68,43 @@ bool8 IsCmBracketText(const text_t *text) return CM_FALSE; } +bool8 IsCmSquareBracketText(const text_t *text) +{ + bool8 inString = CM_FALSE; + uint32 depth; + const int minLen = 2; + + if (text->len < minLen) { + return CM_FALSE; + } + + bool8 flag = (bool8)(CM_TEXT_BEGIN(text) != '[' || CM_TEXT_END(text) != ']'); + if (flag) { + return CM_FALSE; + } + + depth = 1; + for (uint32 i = 1; i < text->len; i++) { + if (text->str[i] == '\'') { + inString = (bool8)(!inString); + continue; + } + + if (inString) { + continue; + } else if (text->str[i] == '[') { + depth++; + } else if (text->str[i] == ']') { + depth--; + if (depth == 0) { + return (bool8)(i == text->len - 1); + } + } + } + + return CM_FALSE; +} + void CmRtrimText(text_t *text) { int32 index; @@ -169,6 +209,16 @@ void CmRemoveBrackets(text_t *text) } } +void CmRemoveSquareBrackets(text_t *text) +{ + const int lenReduce = 2; + while (IsCmSquareBracketText(text)) { + text->str++; + text->len -= lenReduce; + CmTrimText(text); + } +} + void CmSplitText(const text_t *text, char splitChar, char encloseChar, text_t *left, text_t *right) { uint32 i; @@ -265,3 +315,80 @@ status_t CmText2Str(const text_t *text, char *buf, uint32 bufSize) buf[copy_size] = '\0'; return CM_SUCCESS; } + +status_t CmText2Uint16(const text_t *textSrc, uint16 *value) +{ + char buf[CM_MAX_NUMBER_LENGTH + 1] = {0}; + text_t text = *textSrc; + + CmTrimText(&text); + + if (text.len > CM_MAX_NUMBER_LENGTH) { + write_runlog(ERROR, + "[%s] Convert uint16 failed,the length of text %u can't be larger than %u.\n", + __FUNCTION__, + text.len, + CM_MAX_NUMBER_LENGTH); + return CM_ERROR; + } + CM_RETURN_IFERR(CmText2Str(&text, buf, CM_MAX_NUMBER_LENGTH + 1)); + + return CmStr2Uint16(buf, value); +} + +status_t CmStr2Uint16(const char *str, uint16 *value) +{ + char *err = NULL; + int ret = CmCheckIsNumber(str); + if (ret != CM_SUCCESS) { + write_runlog(ERROR, + "[%s] Convert uint16 failed, the text is not number, text = %s.\n", __FUNCTION__, str); + return CM_ERROR; + } + + int64_t valInt64 = strtol(str, &err, CM_DEFAULT_DIGIT_RADIX); + if (CmIsErr(err)) { + write_runlog(ERROR, "[%s] Convert uint32 failed, text = %s.\n", __FUNCTION__, str); + return CM_ERROR; + } + + if (valInt64 > UINT_MAX || valInt64 < 0) { + write_runlog(ERROR, + "[%s] Convert uint32 failed, the text is not in the range of uint32, text = %s.\n", + __FUNCTION__, str); + return CM_ERROR; + } + + *value = (uint32)valInt64; + return CM_SUCCESS; +} + +status_t CmCheckIsNumber(const char *str) +{ + size_t len = strlen(str); + if (len == 0) { + return CM_ERROR; + } + + for (size_t i = 0; i < len; i++) { + if (!CM_IS_DIGITAL_LETER(str[i])) { + return CM_ERROR; + } + } + return CM_SUCCESS; +} + +bool CmIsErr(const char *err) +{ + if (err == NULL) { + return false; + } + + while (*err != '\0') { + if (*err != ' ') { + return true; + } + err++; + } + return false; +} diff --git a/src/cm_common/cm_util.cpp b/src/cm_common/cm_util.cpp index a4b800a56c9872ff35c935b28eb8049a60dcfab1..5a8a76e021acd3a45736c668ab9edd8ffd02e801 100644 --- a/src/cm_common/cm_util.cpp +++ b/src/cm_common/cm_util.cpp @@ -94,6 +94,13 @@ uint64 GetMonotonicTimeMs() return (uint64)ts.tv_sec * CM_MS_COUNT_PER_SEC + (uint64)ts.tv_nsec / CM_NSEC_COUNT_PER_MS; } +uint64 GetMonotonicTimeS() +{ + struct timespec ts; + (void)clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64)ts.tv_sec; +} + void CMFairMutexInit(CMFairMutex &mutex) { (void)pthread_mutex_init(&mutex.lock, NULL); diff --git a/src/cm_communication/cm_feconnect/fe-connect.cpp b/src/cm_communication/cm_feconnect/fe-connect.cpp index ee4032d4c43dd7eb2937a50b3b4ef38e6798633f..f421d960ab6717a22aa5c214100b281a3e2bc994 100644 --- a/src/cm_communication/cm_feconnect/fe-connect.cpp +++ b/src/cm_communication/cm_feconnect/fe-connect.cpp @@ -530,17 +530,31 @@ keep_going: /* We will come back to here until there is appendCMPQExpBuffer(&conn->errorMessage, "could not found localhost, localhost is null \n"); break; } + + if (addr_cur->ai_family == AF_INET) { + struct sockaddr_in localaddr; + + rc = memset_s(&localaddr, sizeof(sockaddr_in), 0, sizeof(sockaddr_in)); + securec_check_errno(rc, (void)rc); + localaddr.sin_family = AF_INET; + localaddr.sin_addr.s_addr = inet_addr(conn->pglocalhost); + /* Any local port will do. */ + localaddr.sin_port = 0; + + rc = bind(conn->sock, (struct sockaddr*)&localaddr, sizeof(localaddr)); + } else if (addr_cur->ai_family == AF_INET6) { + struct sockaddr_in6 localaddr; + + rc = memset_s(&localaddr, sizeof(sockaddr_in6), 0, sizeof(sockaddr_in6)); + securec_check_errno(rc, (void)rc); + localaddr.sin6_family = AF_INET6; + (void)inet_pton(AF_INET6, conn->pglocalhost, &(localaddr.sin6_addr)); + /* Any local port will do. */ + localaddr.sin6_port = 0; // Any local port will do. + + rc = bind(conn->sock, (struct sockaddr*)&localaddr, sizeof(localaddr)); + } - struct sockaddr_in localaddr; - - rc = memset_s(&localaddr, sizeof(sockaddr_in), 0, sizeof(sockaddr_in)); - securec_check_errno(rc, (void)rc); - localaddr.sin_family = AF_INET; - localaddr.sin_addr.s_addr = inet_addr(conn->pglocalhost); - /* Any local port will do. */ - localaddr.sin_port = 0; - - rc = bind(conn->sock, (struct sockaddr*)&localaddr, sizeof(localaddr)); if (rc != 0) { appendCMPQExpBuffer( &conn->errorMessage, "could not bind localhost:%s, result is %d \n", conn->pglocalhost, rc); diff --git a/src/cm_ctl/ctl_common.cpp b/src/cm_ctl/ctl_common.cpp index af73d1f6926c00679788fc0ec7fd9d99f0f81a2a..7ca1821a0378d3c85a839fea6f5f76d0eab629a9 100644 --- a/src/cm_ctl/ctl_common.cpp +++ b/src/cm_ctl/ctl_common.cpp @@ -25,7 +25,7 @@ #include "common/config/cm_config.h" #include "cm/libpq-fe.h" #include "cm/cm_misc.h" -#include "cm/cm_msg.h" +#include "cm_msg_version_convert.h" #include "cm/libpq-int.h" #include "cs_ssl.h" #include "cm_json_config.h" @@ -1492,7 +1492,8 @@ int GetDatanodeRelationInfo(uint32 nodeId, const char *cmData, cm_to_ctl_get_dat int i = 0; int timePass = 0; char* receiveMsg = NULL; - cm_to_ctl_get_datanode_relation_ack* getInstanceMsgPtr = NULL; + cm_to_ctl_get_datanode_relation_ack *getInstanceMsgPtr = NULL; + cm_to_ctl_get_datanode_relation_ack_ipv4 *getInstanceMsgPtrIpv4 = NULL; ctl_to_cm_datanode_relation_info cmDatanodeRelationInfoContent = {0}; ret = FindInstanceIdAndType(nodeId, cmData, &instanceId, &instanceType); @@ -1529,7 +1530,12 @@ int GetDatanodeRelationInfo(uint32 nodeId, const char *cmData, cm_to_ctl_get_dat receiveMsg = recv_cm_server_cmd(CmServer_conn); } if (receiveMsg != NULL) { - getInstanceMsgPtr = (cm_to_ctl_get_datanode_relation_ack*)receiveMsg; + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + getInstanceMsgPtrIpv4 = (cm_to_ctl_get_datanode_relation_ack_ipv4 *)receiveMsg; + CmToCtlGetDatanodeRelationAckV1ToV2(getInstanceMsgPtrIpv4, getInstanceMsg); + break; + } + getInstanceMsgPtr = (cm_to_ctl_get_datanode_relation_ack *)receiveMsg; getInstanceMsg->command_result = getInstanceMsgPtr->command_result; getInstanceMsg->member_index = getInstanceMsgPtr->member_index; for (i = 0; i < CM_PRIMARY_STANDBY_MAX_NUM; i++) { diff --git a/src/cm_ctl/ctl_guc.cpp b/src/cm_ctl/ctl_guc.cpp index de8bb4f8adf14177d6a9bf9c4e4dded72ff2bcbe..376b61a20a7602b37180da1ab071ca616a811b4a 100644 --- a/src/cm_ctl/ctl_guc.cpp +++ b/src/cm_ctl/ctl_guc.cpp @@ -760,7 +760,6 @@ static status_t ListRemoteConfMain(staticNodeConfig *node, const char *cmd) return CM_SUCCESS; } } - return CM_ERROR; } diff --git a/src/cm_ctl/ctl_misc.cpp b/src/cm_ctl/ctl_misc.cpp index 8c479348457d53e762c2c737b528bd3b5d2b7cb0..5fbc5121a62b98446587c4686f399238da7a93bd 100644 --- a/src/cm_ctl/ctl_misc.cpp +++ b/src/cm_ctl/ctl_misc.cpp @@ -33,7 +33,7 @@ #include "cm/cm_misc.h" #include "ctl_common.h" #include "ctl_process_message.h" -#include "cm/cm_msg.h" +#include "cm_msg_version_convert.h" #include "cm/libpq-int.h" #include "cm/cm_agent/cma_main.h" @@ -708,6 +708,7 @@ int do_disable_cn() ctl_to_cm_disable_cn ctl_to_cm_disable_cn_content = {0}; ctl_to_cm_disable_cn_ack* ctl_to_cm_disable_cn_ack_ptr = NULL; cm_to_ctl_instance_status* cm_to_ctl_instance_status_ptr = NULL; + cm_to_ctl_instance_status_ipv4* cm_to_ctl_instance_status_ptr_ipv4 = NULL; ctl_to_cm_query cm_ctl_cm_query_content = {0}; int wait_time = DEFAULT_WAIT; int sendQueryCount = 0; @@ -781,9 +782,16 @@ int do_disable_cn() break; case MSG_CM_CTL_DATA: getQueryCount++; - cm_to_ctl_instance_status_ptr = (cm_to_ctl_instance_status*)receive_msg; - if (cm_to_ctl_instance_status_ptr->coordinatemember.status == INSTANCE_ROLE_DELETED) { - success = true; + if (undocumentedVersion !=0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + cm_to_ctl_instance_status_ptr_ipv4 = (cm_to_ctl_instance_status_ipv4*)receive_msg; + if (cm_to_ctl_instance_status_ptr_ipv4->coordinatemember.status == INSTANCE_ROLE_DELETED) { + success = true; + } + } else { + cm_to_ctl_instance_status_ptr = (cm_to_ctl_instance_status*)receive_msg; + if (cm_to_ctl_instance_status_ptr->coordinatemember.status == INSTANCE_ROLE_DELETED) { + success = true; + } } break; default: @@ -1028,7 +1036,9 @@ int DoBuild(const CtlOption *ctx) cm_msg_type *msgType = NULL; ctl_to_cm_build buildMsg = {0}; cm_to_ctl_command_ack *commandAckPtr = NULL; - cm_to_ctl_instance_status *instStatusPtr = NULL; + cm_to_ctl_instance_status instStatusPtr = {0}; + cm_to_ctl_instance_status_ipv4 *instStatusPtrIpv4 = NULL; + errno_t rc; do_conn_cmserver(false, 0); if (CmServer_conn == NULL) { @@ -1106,34 +1116,43 @@ int DoBuild(const CtlOption *ctx) case MSG_CM_CTL_DATA: getQueryCount++; - instStatusPtr = (cm_to_ctl_instance_status*)receiveMsg; - if (instStatusPtr->instance_type == INSTANCE_TYPE_GTM) { - if (instStatusPtr->gtm_member.local_status.local_role == INSTANCE_ROLE_STANDBY) { + if (undocumentedVersion !=0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + instStatusPtrIpv4 = (cm_to_ctl_instance_status_ipv4*)receiveMsg; + CmToCtlInstanceStatusV1ToV2(instStatusPtrIpv4, &instStatusPtr); + } else { + rc = memcpy_s(&instStatusPtr, + sizeof(cm_to_ctl_instance_status), + receiveMsg, + sizeof(cm_to_ctl_instance_status)); + securec_check_errno(rc, (void)rc); + } + if (instStatusPtr.instance_type == INSTANCE_TYPE_GTM) { + if (instStatusPtr.gtm_member.local_status.local_role == INSTANCE_ROLE_STANDBY) { success = true; } - } else if (instStatusPtr->instance_type == INSTANCE_TYPE_DATANODE) { - if ((CheckBuildCond(instStatusPtr->data_node_member.local_status.local_role)) && - (instStatusPtr->data_node_member.local_status.db_state == INSTANCE_HA_STATE_NORMAL)) { + } else if (instStatusPtr.instance_type == INSTANCE_TYPE_DATANODE) { + if ((CheckBuildCond(instStatusPtr.data_node_member.local_status.local_role)) && + (instStatusPtr.data_node_member.local_status.db_state == INSTANCE_HA_STATE_NORMAL)) { success = true; } - if ((instStatusPtr->data_node_member.local_status.local_role == INSTANCE_ROLE_UNKNOWN) && - (instStatusPtr->data_node_member.local_status.db_state == INSTANCE_HA_STATE_BUILD_FAILED)) { + if ((instStatusPtr.data_node_member.local_status.local_role == INSTANCE_ROLE_UNKNOWN) && + (instStatusPtr.data_node_member.local_status.db_state == INSTANCE_HA_STATE_BUILD_FAILED)) { write_runlog(ERROR, "build failed, please refer to the log of cm_agent(nodeid:%u) for detailed reasons.\n", ctx->comm.nodeId); FINISH_CONNECTION(); } - if (!CheckBuildCond(instStatusPtr->data_node_member.local_status.local_role) && - instStatusPtr->data_node_member.local_status.db_state != INSTANCE_HA_STATE_BUILDING) { + if (!CheckBuildCond(instStatusPtr.data_node_member.local_status.local_role) && + instStatusPtr.data_node_member.local_status.db_state != INSTANCE_HA_STATE_BUILDING) { dnRoleAbnormal++; } else { dnRoleAbnormal = 0; } if (dnRoleAbnormal > MAX_INSTANCE_ROLE_ABNORMAL_TIMES) { - if (instStatusPtr->data_node_member.local_status.db_state == + if (instStatusPtr.data_node_member.local_status.db_state == INSTANCE_HA_STATE_MANUAL_STOPPED) { write_runlog(ERROR, "build failed, instance is stopped.\n"); } else { @@ -1496,9 +1515,9 @@ int CalcDcfVoterNum(const cm_to_ctl_instance_status* cmToCtlInstanceStatusPtr, i int ProcessRecvMsg(int *voterNum) { - char* receiveMsg = NULL; - cm_msg_type* cmMsgTypePtr = NULL; - cm_to_ctl_instance_status* cmToCtlInstanceStatusPtr = NULL; + char *receiveMsg = NULL; + cm_msg_type *cmMsgTypePtr = NULL; + cm_to_ctl_instance_status cmToCtlInstanceStatusPtr = {0}; const int microSecond = 1000; int voterDnNum = 0; int ret; @@ -1512,14 +1531,14 @@ int ProcessRecvMsg(int *voterNum) } receiveMsg = recv_cm_server_cmd(CmServer_conn); while (receiveMsg != NULL) { - cmMsgTypePtr = (cm_msg_type*)receiveMsg; + cmMsgTypePtr = (cm_msg_type *)receiveMsg; switch (cmMsgTypePtr->msg_type) { case MSG_CM_CTL_DATA_BEGIN: case MSG_CM_CTL_NODE_END: break; case MSG_CM_CTL_DATA: - cmToCtlInstanceStatusPtr = (cm_to_ctl_instance_status*)receiveMsg; - if (CalcDcfVoterNum(cmToCtlInstanceStatusPtr, &voterDnNum) != 0) { + GetCtlInstanceStatusFromRecvMsg(receiveMsg, &cmToCtlInstanceStatusPtr); + if (CalcDcfVoterNum(&cmToCtlInstanceStatusPtr, &voterDnNum) != 0) { return -1; } break; diff --git a/src/cm_ctl/ctl_pause.cpp b/src/cm_ctl/ctl_pause.cpp index 5420c9a4f2fd368f80ef34347c899fa65881cb13..f2ecdc06c73e2f6dc7685edb0f15c92b95ca69bd 100644 --- a/src/cm_ctl/ctl_pause.cpp +++ b/src/cm_ctl/ctl_pause.cpp @@ -66,9 +66,9 @@ bool CheckTrustAndNet() int ret = snprintf_s(command, MAXPGPATH, MAXPGPATH - 1, SYSTEMQUOTE "source /etc/profile;pssh -i -t 10 -h %s " "\"pwd > /dev/null\" > /dev/null;" SYSTEMQUOTE, hosts_path); + securec_check_intval(ret, (void)ret); write_runlog(DEBUG1, "Check trust command: %s\n", command); - ret = system(command); if (ret != 0) { return false; diff --git a/src/cm_ctl/ctl_query.cpp b/src/cm_ctl/ctl_query.cpp index 8926d8546657048398623ca9a84f5402856e5db3..13f27eb6c563b36c3f1a49786843024c70f61c47 100644 --- a/src/cm_ctl/ctl_query.cpp +++ b/src/cm_ctl/ctl_query.cpp @@ -27,20 +27,24 @@ #include "cm/libpq-fe.h" #include "cm/cm_misc.h" #include "ctl_common.h" -#include "cm/cm_msg.h" +#include "cm_ip.h" #include "ctl_query_base.h" +#include "cm_msg_version_convert.h" +static uint32 GetCmsIpMaxLen(); +static uint32 GetResIpMaxLen(const OneResStatList *stat); static void query_cmserver_and_etcd_status(void); const char* query_etcd(uint32 node_id); static void query_kerberos(void); static void query_kerberos_status(); -static void do_query_cmserver(uint32 node_id, const char* state); +static void do_query_cmserver(uint32 node_id, const char* state, uint32 ip_len); static const char* query_cm_server(uint32 node_id); static const char* query_cm_server_directory(uint32 node_id); static status_t PrintResult(uint32 *pre_node, cm_to_ctl_instance_status *cm_to_ctl_instance_status_ptr); static void PrintParallelRedoResult(cm_to_ctl_instance_status *cm_to_ctl_instance_status_ptr); static void PrintSimpleResult(cm_to_ctl_instance_status *cm_to_ctl_instance_status_ptr); -static void print_simple_DN_result(uint32 node_index, cm_to_ctl_instance_status *cm_to_ctl_instance_status_ptr); +static void print_simple_DN_result(uint32 node_index, cm_to_ctl_instance_status + *cm_to_ctl_instance_status_ptr, uint32 ip_len); static status_t QueryResourceStatus(CM_Conn *pCmsCon); static bool hasFindEtcdL = false; @@ -75,6 +79,30 @@ extern FILE* g_logFilePtr; bool g_isPauseArbitration = false; extern char manual_pause_file[MAXPGPATH]; +static uint32 GetCmsIpMaxLen() +{ + uint32 maxLen = MAX_IPV4_LEN; + for (uint32 i = 0; i < g_cm_server_num; ++i) { + uint32 cmsIndex = g_nodeIndexForCmServer[i]; + uint32 curIpLen = (uint32)strlen(g_node[cmsIndex].cmServer[0]); + maxLen = (maxLen > curIpLen) ? maxLen : curIpLen; + } + return (maxLen + SPACE_LEN); +} + +static uint32 GetResIpMaxLen(const OneResStatList *stat) +{ + uint32 maxLen = MAX_IPV4_LEN; + for (uint32 i = 0; i < CusResCount(); ++i) { + for (uint32 j = 0; j < stat[i].instanceCount; ++j) { + uint32 resIndex = get_node_index(stat[i].resStat[j].nodeId); + uint32 curIpLen = (uint32)strlen(g_node[resIndex].sshChannel[0]); + maxLen = (maxLen > curIpLen) ? maxLen : curIpLen; + } + } + return (maxLen + SPACE_LEN); +} + int do_global_barrier_query(void) { ctl_to_cm_global_barrier_query cm_ctl_cm_query_content; @@ -214,6 +242,9 @@ status_t QueryEtcdAndCms(void) int DoProcessQueryMsg(char *receiveMsg, bool *recDataEnd, uint32 *pre_node) { int ret = 0; + cm_to_ctl_instance_status instStatus = {0}; + cm_to_ctl_instance_status_ipv4 *instStatusIpv4 = NULL; + errno_t rc; cm_msg_type *cm_msg_type_ptr = (cm_msg_type *)receiveMsg; switch (cm_msg_type_ptr->msg_type) { @@ -222,13 +253,20 @@ int DoProcessQueryMsg(char *receiveMsg, bool *recDataEnd, uint32 *pre_node) break; } case MSG_CM_CTL_DATA: { - cm_to_ctl_instance_status *cm_to_ctl_instance_status_ptr = (cm_to_ctl_instance_status *)receiveMsg; + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + instStatusIpv4 = (cm_to_ctl_instance_status_ipv4 *)receiveMsg; + CmToCtlInstanceStatusV1ToV2(instStatusIpv4, &instStatus); + } else { + rc = memcpy_s(&instStatus, sizeof(cm_to_ctl_instance_status), receiveMsg, + sizeof(cm_to_ctl_instance_status)); + securec_check_errno(rc, (void)rc); + } if (g_coupleQuery) { - PrintSimpleResult(cm_to_ctl_instance_status_ptr); + PrintSimpleResult(&instStatus); } else if (g_paralleRedoState) { - PrintParallelRedoResult(cm_to_ctl_instance_status_ptr); + PrintParallelRedoResult(&instStatus); } else { - ret = (int)PrintResult(pre_node, cm_to_ctl_instance_status_ptr); + ret = (int)PrintResult(pre_node, &instStatus); } break; } @@ -345,6 +383,7 @@ static void query_cmserver_and_etcd_status(void) /* query cm_server */ uint32 node_len = MAX_NODE_ID_LEN + SPACE_LEN + max_node_name_len + SPACE_LEN; uint32 instance_len = INSTANCE_ID_LEN + SPACE_LEN + (g_dataPathQuery ? (max_cmpath_len + 11) : 4); + uint32 cmsIpLen = GetCmsIpMaxLen(); bool query_cmserver = false; if (g_availabilityZoneCommand) { @@ -353,19 +392,12 @@ static void query_cmserver_and_etcd_status(void) (void)fprintf(g_logFilePtr, "[ CMServer State ]\n\n"); if (g_ipQuery) { - (void)fprintf(g_logFilePtr, - "%-*s%-*s%-*s%s\n", - node_len, - "node", - MAX_IP_LEN + 1, - "node_ip", - instance_len, - "instance", - "state"); + (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%s\n", node_len, "node", cmsIpLen, "node_ip", instance_len, + "instance", "state"); } else { (void)fprintf(g_logFilePtr, "%-*s%-*s%s\n", node_len, "node", instance_len, "instance", "state"); } - for (i = 0; i < node_len + instance_len + INSTANCE_DYNAMIC_ROLE_LEN + (g_ipQuery ? (MAX_IP_LEN + 1) : 0); i++) { + for (i = 0; i < node_len + instance_len + INSTANCE_DYNAMIC_ROLE_LEN + (g_ipQuery ? cmsIpLen : 0); i++) { (void)fprintf(g_logFilePtr, "-"); } (void)fprintf(g_logFilePtr, "\n"); @@ -405,7 +437,7 @@ static void query_cmserver_and_etcd_status(void) if (findAbnormal || !g_abnormalQuery) { for (uint32 kk = 0; kk < g_cm_server_num; kk++) { uint32 cm_server_node_index = g_nodeIndexForCmServer[kk]; - do_query_cmserver(cm_server_node_index, g_cmServerState[kk]); + do_query_cmserver(cm_server_node_index, g_cmServerState[kk], cmsIpLen); } } } @@ -422,7 +454,7 @@ static void query_cmserver_and_etcd_status(void) "%-*s%-*s%-*s%s\n", node_len, "node", - MAX_IP_LEN + 1, + (MAX_IPV6_LEN + 1), "node_ip", instance_len, "instance", @@ -430,7 +462,7 @@ static void query_cmserver_and_etcd_status(void) } else { (void)fprintf(g_logFilePtr, "%-*s%-*s%s\n", node_len, "node", instance_len, "instance", "state"); } - for (i = 0; i < node_len + instance_len + ETCD_DYNAMIC_ROLE_LEN + (g_ipQuery ? (MAX_IP_LEN + 1) : 0); i++) { + for (i = 0; i < node_len + instance_len + ETCD_DYNAMIC_ROLE_LEN + (g_ipQuery ? (MAX_IPV6_LEN + 1) : 0); i++) { (void)fprintf(g_logFilePtr, "-"); } (void)fprintf(g_logFilePtr, "\n"); @@ -647,26 +679,26 @@ const char* query_etcd(uint32 node_id) static uint32 GetResNameMaxLen() { - uint32 minLen = (uint32)strlen("res_name") + SPACE_LEN; + uint32 maxLen = (uint32)strlen("res_name") + SPACE_LEN; for (uint32 i = 0; i < CusResCount(); ++i) { uint32 curNameLen = (uint32)strlen(g_resStatus[i].status.resName) + SPACE_LEN; - minLen = (minLen > curNameLen) ? minLen : curNameLen; + maxLen = (maxLen > curNameLen) ? maxLen : curNameLen; } - return minLen; + return maxLen; } -static inline void PrintResHeaderLine(uint32 nodeLen, uint32 resLen, uint32 instLen, uint32 statLen) +static inline void PrintResHeaderLine(uint32 ipLen, uint32 nodeLen, uint32 resLen, uint32 instLen, uint32 statLen) { (void)fprintf(g_logFilePtr, "\n[ Defined Resource State ]\n\n"); if (g_ipQuery) { - (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s%-*s\n", - nodeLen, "node", MAX_IP_LEN + 1, "node_ip", resLen, "res_name", instLen, "instance", statLen, "state"); + (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s%-*s\n", nodeLen, "node", ipLen, "node_ip", resLen, + "res_name", instLen, "instance", statLen, "state"); } else { - (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s\n", - nodeLen, "node", resLen, "res_name", instLen, "instance", statLen, "state"); + (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s\n", nodeLen, "node", resLen, "res_name", instLen, + "instance", statLen, "state"); } - uint32 tmp = nodeLen + resLen + instLen + statLen + (g_ipQuery ? (MAX_IP_LEN + 1) : 0); + uint32 tmp = nodeLen + resLen + instLen + statLen + (g_ipQuery ? ipLen : 0); for (uint32 i = 0; i < tmp; i++) { (void)fprintf(g_logFilePtr, "-"); } @@ -700,7 +732,7 @@ static const char *ResStatIntToStr(uint32 status, uint32 isWork) return "Unknown"; } -static void PrintOneResLine(const OneResStatList *stat, uint32 resLen, uint32 instLen, uint32 statLen) +static void PrintOneResLine(const OneResStatList *stat, uint32 ipLen, uint32 resLen, uint32 instLen, uint32 statLen) { for (uint32 i = 0; i < stat->instanceCount; ++i) { const char *status = ResStatIntToStr(stat->resStat[i].status, stat->resStat[i].isWorkMember); @@ -719,7 +751,7 @@ static void PrintOneResLine(const OneResStatList *stat, uint32 resLen, uint32 in (void)fprintf(g_logFilePtr, "%-*u%-*s%-*s%-*s%-*u%-*s\n", (MAX_NODE_ID_LEN + SPACE_LEN), stat->resStat[i].nodeId, (max_node_name_len + SPACE_LEN), g_node[resIndex].nodeName, - MAX_IP_LEN + 1, g_node[resIndex].sshChannel[0], + ipLen, g_node[resIndex].sshChannel[0], resLen, stat->resName, instLen, stat->resStat[i].cmInstanceId, statLen, status); @@ -743,13 +775,14 @@ static int ProcessResQueryMsgCore(char *recvMsg, uint32 nodeLen, uint32 resLen, static bool isFirstPrint = true; CmsToCtlGroupResStatus *queryMsg = (CmsToCtlGroupResStatus *)recvMsg; + uint32 ipLen = GetResIpMaxLen(&queryMsg->oneResStat); switch (queryMsg->msgStep) { case QUERY_RES_STATUS_STEP_ACK: if (isFirstPrint) { - PrintResHeaderLine(nodeLen, resLen, instLen, statLen); + PrintResHeaderLine(ipLen, nodeLen, resLen, instLen, statLen); isFirstPrint = false; } - PrintOneResLine(&queryMsg->oneResStat, resLen, instLen, statLen); + PrintOneResLine(&queryMsg->oneResStat, ipLen, resLen, instLen, statLen); break; case QUERY_RES_STATUS_STEP_ACK_END: return CYCLE_RETURN; @@ -823,9 +856,9 @@ static void query_kerberos(void) node_len += (int)(max_az_name_len + SPACE_LEN); } (void)fprintf(g_logFilePtr, "[ Kerberos State ]\n\n"); - (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s\n", node_len, "node", MAX_IP_LEN + 1, + (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s\n", node_len, "node", MAX_IPV6_LEN + 1, "kerberos_ip", kerberos_len, "port", kerberos_len, "state"); - for (int i = 0; i < MAX_IP_LEN + kerberos_len + kerberos_len + node_len; i++) { + for (int i = 0; i < MAX_IPV6_LEN + kerberos_len + kerberos_len + node_len; i++) { (void)fprintf(g_logFilePtr, "-"); } (void)fprintf(g_logFilePtr, "\n"); @@ -846,6 +879,7 @@ static void query_kerberos_status() errno_t rc; bool sortFlag = false; uint32 node_index = 0; + char tempIp[CM_IP_LENGTH] = {0}; do_conn_cmserver(false, 0); if (CmServer_conn == NULL) { write_runlog(DEBUG1, @@ -892,7 +926,9 @@ static void query_kerberos_status() } (void)fprintf(g_logFilePtr, "%-2u ", kerberos_status_ptr->node[node_index]); (void)fprintf(g_logFilePtr, "%-*s ", max_node_name_len, kerberos_status_ptr->nodeName[node_index]); - (void)fprintf(g_logFilePtr, "%-15s ", kerberos_status_ptr->kerberos_ip[node_index]); + (void)NeedAndRemoveSquareBracketsForIpV6(kerberos_status_ptr->kerberos_ip[node_index], tempIp, + CM_IP_LENGTH); + (void)fprintf(g_logFilePtr, "%-*s ", (int)(MAX_IPV6_LEN + SPACE_LEN), tempIp); (void)fprintf(g_logFilePtr, "%-9u ", kerberos_status_ptr->port[node_index]); (void)fprintf(g_logFilePtr, "%-7s\n", state); } @@ -914,7 +950,7 @@ static void query_kerberos_status() * * @Description: print the state info of cm_server specified by node id. */ -static void do_query_cmserver(uint32 node_id, const char *state) +static void do_query_cmserver(uint32 node_id, const char *state, uint32 ipLen) { int ret; char data_path[MAXPGPATH] = {0}; @@ -925,7 +961,7 @@ static void do_query_cmserver(uint32 node_id, const char *state) (void)fprintf(g_logFilePtr, "%-2u ", g_node[node_id].node); (void)fprintf(g_logFilePtr, "%-*s ", max_node_name_len, g_node[node_id].nodeName); if (g_ipQuery) { - (void)fprintf(g_logFilePtr, "%-15s ", g_node[node_id].cmServer[0]); + (void)fprintf(g_logFilePtr, "%-*s ", ipLen, g_node[node_id].cmServer[0]); } (void)fprintf(g_logFilePtr, "%-4u ", g_node[node_id].cmServerId); if (g_dataPathQuery) { @@ -1705,7 +1741,8 @@ static void PrintSimpleCnResult(uint32 nodeIndex, const cm_to_ctl_instance_statu (void)fprintf(g_logFilePtr, "%-2u ", g_node[nodeIndex].node); (void)fprintf(g_logFilePtr, "%-*s ", max_node_name_len, g_node[nodeIndex].nodeName); if (g_ipQuery) { - (void)fprintf(g_logFilePtr, "%-15s ", g_node[nodeIndex].coordinateListenIP[0]); + uint32 ipLen = GetCnIpMaxLen(); + (void)fprintf(g_logFilePtr, "%-*s ", ipLen, g_node[nodeIndex].coordinateListenIP[0]); } (void)fprintf(g_logFilePtr, "%u ", cmToCtlInstanceStatusPtr->instanceId); if (g_portQuery) { @@ -1729,6 +1766,7 @@ static void PrintSimpleResult(cm_to_ctl_instance_status *cm_to_ctl_instance_stat { uint32 i; uint32 node_index = 0; + uint32 ip_len = GetDnIpMaxLen(); for (i = 0; i < g_node_num; i++) { if (g_node[i].node == cm_to_ctl_instance_status_ptr->node) { @@ -1772,7 +1810,8 @@ static void PrintSimpleResult(cm_to_ctl_instance_status *cm_to_ctl_instance_stat (void)fprintf(g_logFilePtr, "%-2u ", g_node[node_index].node); (void)fprintf(g_logFilePtr, "%-*s ", max_node_name_len, g_node[node_index].nodeName); if (g_ipQuery) { - (void)fprintf(g_logFilePtr, "%-15s ", g_node[node_index].gtmLocalListenIP[0]); + uint32 gtmIpLen = GetGtmIpMaxLen(); + (void)fprintf(g_logFilePtr, "%-*s ", gtmIpLen, g_node[node_index].gtmLocalListenIP[0]); } (void)fprintf(g_logFilePtr, "%u ", cm_to_ctl_instance_status_ptr->instanceId); if (g_dataPathQuery) { @@ -1797,7 +1836,7 @@ static void PrintSimpleResult(cm_to_ctl_instance_status *cm_to_ctl_instance_stat } if (cm_to_ctl_instance_status_ptr->instance_type == INSTANCE_TYPE_DATANODE && !g_startStatusQuery) { - print_simple_DN_result(node_index, cm_to_ctl_instance_status_ptr); + print_simple_DN_result(node_index, cm_to_ctl_instance_status_ptr, ip_len); } if (g_fencedUdfQuery && cm_to_ctl_instance_status_ptr->instance_type == INSTANCE_TYPE_FENCED_UDF && @@ -1805,14 +1844,16 @@ static void PrintSimpleResult(cm_to_ctl_instance_status *cm_to_ctl_instance_stat (void)fprintf(g_logFilePtr, "%-2u ", g_node[node_index].node); (void)fprintf(g_logFilePtr, "%-*s ", max_node_name_len, g_node[node_index].nodeName); if (g_ipQuery) { - (void)fprintf(g_logFilePtr, "%-15s ", g_node[node_index].sshChannel[0]); + uint32 dnIpLen = GetDnIpMaxLen(); + (void)fprintf(g_logFilePtr, "%-*s ", dnIpLen, g_node[node_index].sshChannel[0]); } (void)fprintf(g_logFilePtr, "%s\n", datanode_role_int_to_string(cm_to_ctl_instance_status_ptr->fenced_UDF_status)); } } -static void print_simple_DN_result(uint32 node_index, cm_to_ctl_instance_status *cm_to_ctl_instance_status_ptr) +static void print_simple_DN_result(uint32 node_index, + cm_to_ctl_instance_status *cm_to_ctl_instance_status_ptr, uint32 ip_len) { uint32 j; uint32 instance_index = 0; @@ -1854,7 +1895,8 @@ static void print_simple_DN_result(uint32 node_index, cm_to_ctl_instance_status (void)fprintf(g_logFilePtr, "%-2u ", g_node[node_index].node); (void)fprintf(g_logFilePtr, "%-*s ", max_node_name_len, g_node[node_index].nodeName); if (g_ipQuery) { - (void)fprintf(g_logFilePtr, "%-15s ", g_node[node_index].datanode[instance_index].datanodeListenIP[0]); + (void)fprintf(g_logFilePtr, "%-*s ", ip_len, + g_node[node_index].datanode[instance_index].datanodeListenIP[0]); } (void)fprintf(g_logFilePtr, "%u ", cm_to_ctl_instance_status_ptr->instanceId); if (g_portQuery && g_node[node_index].datanode[instance_index].datanodeRole != DUMMY_STANDBY_DN) { diff --git a/src/cm_ctl/ctl_query_base.cpp b/src/cm_ctl/ctl_query_base.cpp index 0a0ceb5d02bc21f72038d3328e5d929137d2a01d..926aa812dfd4f614d74011b603cac2aebf3b83e3 100644 --- a/src/cm_ctl/ctl_query_base.cpp +++ b/src/cm_ctl/ctl_query_base.cpp @@ -25,7 +25,7 @@ #include "cm/libpq-fe.h" #include "cm/cm_misc.h" #include "ctl_common.h" -#include "cm/cm_msg.h" +#include "cm_msg_ipv4.h" #include "ctl_query_base.h" extern bool g_detailQuery; @@ -203,7 +203,7 @@ status_t SetCmQueryContent(ctl_to_cm_query *cmQueryContent) return CM_SUCCESS; } -void PrintCnHeaderLine(uint32 nodeLen, uint32 instanceLen) +void PrintCnHeaderLine(uint32 nodeLen, uint32 instanceLen, uint32 ipLen) { (void)fprintf(g_logFilePtr, "\n[ Coordinator State ]\n\n"); uint32 tmpInstanceLen = instanceLen; @@ -211,19 +211,42 @@ void PrintCnHeaderLine(uint32 nodeLen, uint32 instanceLen) tmpInstanceLen = tmpInstanceLen + INSTANCE_LEN; } if (g_ipQuery) { - (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%s\n", nodeLen, "node", MAX_IP_LEN + 1, "node_ip", - tmpInstanceLen, "instance", "state"); + (void)fprintf(g_logFilePtr, + "%-*s%-*s%-*s%s\n", + nodeLen, + "node", + ipLen, + "node_ip", + tmpInstanceLen, + "instance", + "state"); } else { (void)fprintf( - g_logFilePtr, "%-*s%-*s%s\n", nodeLen, "node", tmpInstanceLen, "instance", "state"); - } - uint32 maxLen = nodeLen + instanceLen + INSTANCE_DYNAMIC_ROLE_LEN + (g_ipQuery ? (MAX_IP_LEN + 1) : 0); + g_logFilePtr, + "%-*s%-*s%s\n", nodeLen, + "node", + tmpInstanceLen, + "instance", + "state"); + } + uint32 maxLen = nodeLen + instanceLen + INSTANCE_DYNAMIC_ROLE_LEN + (g_ipQuery ? ipLen : 0); for (uint32 i = 0; i < maxLen; i++) { (void)fprintf(g_logFilePtr, "-"); } (void)fprintf(g_logFilePtr, "\n"); } +uint32 GetCnIpMaxLen() +{ + uint32 maxLen = MAX_IPV4_LEN; + uint32 curIpLen; + for (uint32 i = 0; i < g_node_num; ++i) { + curIpLen = (uint32)strlen(g_node[i].coordinateListenIP[0]); + maxLen = (maxLen > curIpLen) ? maxLen : curIpLen; + } + return (maxLen + SPACE_LEN); +} + int ProcessCoupleDetailQuery(const char *receiveMsg) { int ret; @@ -253,7 +276,8 @@ int ProcessCoupleDetailQuery(const char *receiveMsg) if (g_only_dn_cluster) { return 0; } - PrintCnHeaderLine(nodeLen, instanceLen); + uint32 ipLen = GetCnIpMaxLen(); + PrintCnHeaderLine(nodeLen, instanceLen, ipLen); return 0; } @@ -322,6 +346,7 @@ static void PrintCentralNodeDetail(FILE* file) uint32 nodeLen = MAX_NODE_ID_LEN + SPACE_LEN + max_node_name_len + SPACE_LEN; const uint32 instanceLen = INSTANCE_ID_LEN + SPACE_LEN + (g_dataPathQuery ? (max_cnpath_len + 1) : DEFAULT_PATH_LEN); + uint32 ipLen = GetCnIpMaxLen(); if (g_availabilityZoneCommand) { nodeLen += max_az_name_len + SPACE_LEN; @@ -332,13 +357,12 @@ static void PrintCentralNodeDetail(FILE* file) /* show ip */ if (g_ipQuery) { - (void)fprintf( - file, "%-*s%-*s%-*s%s\n", nodeLen, "node", MAX_IP_LEN + 1, "node_ip", instanceLen, "instance", "state"); + (void)fprintf(file, "%-*s%-*s%-*s%s\n", nodeLen, "node", ipLen, "node_ip", instanceLen, "instance", "state"); } else { (void)fprintf(file, "%-*s%-*s%s\n", nodeLen, "node", instanceLen, "instance", "state"); } - for (uint32 i = 0; i < nodeLen + instanceLen + INSTANCE_DYNAMIC_ROLE_LEN + (g_ipQuery ? (MAX_IP_LEN + 1) : 0); + for (uint32 i = 0; i < nodeLen + instanceLen + INSTANCE_DYNAMIC_ROLE_LEN + (g_ipQuery ? ipLen : 0); ++i) { (void)fprintf(file, "-"); } @@ -359,7 +383,7 @@ static void PrintCentralNodeDetail(FILE* file) (void)fprintf(file, "%-*s ", max_node_name_len, g_node[nodeIndex].nodeName); if (g_ipQuery) { - (void)fprintf(file, "%-15s ", g_node[nodeIndex].coordinateListenIP[0]); + (void)fprintf(file, "%-*s ", ipLen, g_node[nodeIndex].coordinateListenIP[0]); } (void)fprintf(file, "%u ", g_centralNode.instanceId); @@ -381,6 +405,17 @@ static void PrintCentralNodeDetail(FILE* file) } } +uint32 GetGtmIpMaxLen() +{ + uint32 maxLen = MAX_IPV4_LEN; + uint32 curIpLen; + for (uint32 i = 0; i < g_node_num; ++i) { + curIpLen = (uint32)strlen(g_node[i].gtmLocalListenIP[0]); + maxLen = (maxLen > curIpLen) ? maxLen : curIpLen; + } + return (maxLen + SPACE_LEN); +} + void PrintGtmHeaderLine() { uint32 nodeLen; @@ -388,6 +423,7 @@ void PrintGtmHeaderLine() uint32 stateLen; CalcGtmHeaderSize(&nodeLen, &instanceLen, &stateLen); + uint32 ipLen = GetGtmIpMaxLen(); if (g_only_dn_cluster) { return; @@ -405,10 +441,10 @@ void PrintGtmHeaderLine() if (g_ipQuery) { if (g_single_node_cluster) { - (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s\n", nodeLen, "node", MAX_IP_LEN + 1, "node_ip", + (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s\n", nodeLen, "node", ipLen, "node_ip", instanceLen, "instance", stateLen, "state"); } else { - (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s%s\n", nodeLen, "node", MAX_IP_LEN + 1, "node_ip", + (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s%s\n", nodeLen, "node", ipLen, "node_ip", instanceLen, "instance", stateLen, "state", "sync_state"); } } else { @@ -421,14 +457,26 @@ void PrintGtmHeaderLine() } for (uint32 i = 0; i < nodeLen + instanceLen + stateLen + (g_single_node_cluster ? 0 : MAX_GTM_SYNC_STATE_LEN) + - (g_ipQuery ? (MAX_IP_LEN + 1) : 0); + (g_ipQuery ? ipLen : 0); i++) { (void)fprintf(g_logFilePtr, "-"); } (void)fprintf(g_logFilePtr, "\n"); } -void CalcDnHeaderSize(uint32 *nodeLen, uint32 *instanceLen, uint32 *stateLen) +uint32 GetDnIpMaxLen() +{ + uint32 maxLen = MAX_IPV4_LEN; + for (uint32 i = 0; i < g_node_num; ++i) { + for (uint32 j = 0; j < g_node[i].datanodeCount; ++j) { + uint32 curIpLen = (uint32)strlen(g_node[i].datanode[j].datanodeListenIP[0]); + maxLen = (maxLen > curIpLen) ? maxLen : curIpLen; + } + } + return (maxLen + SPACE_LEN); +} + +void CalcDnHeaderSize(uint32 *nodeLen, uint32 *ipLen, uint32 *instanceLen, uint32 *stateLen) { uint32 nameLen; uint32 nodeLength; @@ -449,50 +497,62 @@ void CalcDnHeaderSize(uint32 *nodeLen, uint32 *instanceLen, uint32 *stateLen) (void)fprintf(g_logFilePtr, "%-*s| ", nameLen, "logiccluster_name"); } *nodeLen = nodeLength; + *ipLen = GetDnIpMaxLen(); } -void PrintDnHeaderLine(uint32 nodeLen, uint32 instanceLen, uint32 tmpInstanceLen, uint32 stateLen) +void PrintDnHeaderLine(uint32 nodeLen, uint32 ipLen, uint32 instanceLen, uint32 tmpInstanceLen, uint32 stateLen) { if (g_formatQuery) { if (g_ipQuery) { - (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%s\n", nodeLen, "node", MAX_IP_LEN + 1, - "node_ip", tmpInstanceLen, "instance", "state"); + (void)fprintf(g_logFilePtr, + "%-*s%-*s%-*s%s\n", + nodeLen, + "node", + ipLen, + "node_ip", + tmpInstanceLen, + "instance", + "state"); } else { (void)fprintf(g_logFilePtr, "%-*s%-*s%s\n", nodeLen, "node", - g_single_node_cluster ? tmpInstanceLen : instanceLen, - "instance", "state"); + g_single_node_cluster ? tmpInstanceLen : instanceLen, "instance", "state"); } } else { if (g_ipQuery) { if (g_multi_az_cluster) { for (uint32 jj = 0; jj < g_dn_replication_num - 1; jj++) { - (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s| ", - nodeLen, "node", MAX_IP_LEN + 1, "node_ip", - tmpInstanceLen, "instance", stateLen, "state"); + (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s| ", nodeLen, "node", ipLen, "node_ip", + tmpInstanceLen, "instance", stateLen, "state"); } } else if (!g_single_node_cluster) { - (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s| ", nodeLen, "node", MAX_IP_LEN + 1, - "node_ip", tmpInstanceLen, "instance", stateLen, "state"); - (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s| ", nodeLen, "node", MAX_IP_LEN + 1, - "node_ip", tmpInstanceLen, "instance", stateLen, "state"); + (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s| ", nodeLen, "node", ipLen, "node_ip", + tmpInstanceLen, "instance", stateLen, "state"); + (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%-*s| ", nodeLen, "node", ipLen, "node_ip", + tmpInstanceLen, "instance", stateLen, "state"); } - (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s%s\n", nodeLen, "node", MAX_IP_LEN + 1, - "node_ip", tmpInstanceLen, "instance", "state"); + (void)fprintf(g_logFilePtr, + "%-*s%-*s%-*s%s\n", + nodeLen, + "node", + ipLen, + "node_ip", + tmpInstanceLen, + "instance", + "state"); } else { if (g_multi_az_cluster) { for (uint32 jj = 0; jj < g_dn_replication_num - 1; jj++) { (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s| ", nodeLen, "node", - tmpInstanceLen, "instance", stateLen, "state"); + tmpInstanceLen, "instance", stateLen, "state"); } } else if (!g_single_node_cluster) { (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s| ", nodeLen, "node", - tmpInstanceLen, "instance", stateLen, "state"); + tmpInstanceLen, "instance", stateLen, "state"); (void)fprintf(g_logFilePtr, "%-*s%-*s%-*s| ", - nodeLen, "node", tmpInstanceLen, "instance", stateLen, "state"); + nodeLen, "node", tmpInstanceLen, "instance", stateLen, "state"); } (void)fprintf(g_logFilePtr, "%-*s%-*s%s\n", nodeLen, "node", - g_single_node_cluster ? tmpInstanceLen : instanceLen, - "instance", "state"); + g_single_node_cluster ? tmpInstanceLen : instanceLen, "instance", "state"); } } } @@ -500,10 +560,11 @@ void PrintDnHeaderLine(uint32 nodeLen, uint32 instanceLen, uint32 tmpInstanceLen void PrintDnStatusLine() { uint32 nodeLen; + uint32 ipLen; uint32 instanceLen; uint32 stateLen; - CalcDnHeaderSize(&nodeLen, &instanceLen, &stateLen); + CalcDnHeaderSize(&nodeLen, &ipLen, &instanceLen, &stateLen); uint32 tmpInstanceLen = instanceLen; if (g_portQuery) { tmpInstanceLen = tmpInstanceLen + INSTANCE_LEN; @@ -511,28 +572,27 @@ void PrintDnStatusLine() (void)fprintf(g_logFilePtr, "\n[ Datanode State ]\n\n"); - PrintDnHeaderLine(nodeLen, instanceLen, tmpInstanceLen, stateLen); + PrintDnHeaderLine(nodeLen, ipLen, instanceLen, tmpInstanceLen, stateLen); uint32 maxLen; uint32 secondryStateLen = INSTANCE_STATIC_ROLE_LEN + SPACE_LEN + - SECONDARY_DYNAMIC_ROLE_LEN + SPACE_LEN + - INSTANCE_DB_STATE_LEN; + SECONDARY_DYNAMIC_ROLE_LEN + SPACE_LEN + INSTANCE_DB_STATE_LEN; if (g_multi_az_cluster || g_single_node_cluster) { if (g_formatQuery) { - maxLen = (nodeLen + tmpInstanceLen + (g_ipQuery ? (MAX_IP_LEN + 1) : 0)) + - (stateLen + SEPERATOR_LEN + SPACE_LEN); + maxLen = (nodeLen + tmpInstanceLen + (g_ipQuery ? ipLen : 0)) + + (stateLen + SEPERATOR_LEN + SPACE_LEN); } else { maxLen = g_dn_replication_num * - (nodeLen + tmpInstanceLen + (g_ipQuery ? (MAX_IP_LEN + 1) : 0)) + - g_dn_replication_num * (stateLen + SEPERATOR_LEN + SPACE_LEN); + (nodeLen + tmpInstanceLen + (g_ipQuery ? ipLen : 0)) + + g_dn_replication_num * (stateLen + SEPERATOR_LEN + SPACE_LEN); } } else { if (g_formatQuery) { - maxLen = (nodeLen + tmpInstanceLen + (g_ipQuery ? (MAX_IP_LEN + 1) : 0)) + - (stateLen + SEPERATOR_LEN + SPACE_LEN) + secondryStateLen; + maxLen = (nodeLen + tmpInstanceLen + (g_ipQuery ? ipLen : 0)) + + (stateLen + SEPERATOR_LEN + SPACE_LEN) + secondryStateLen; } else { - maxLen = NODE_NUM * (nodeLen + tmpInstanceLen + (g_ipQuery ? (MAX_IP_LEN + 1) : 0)) + - SPACE_NUM * (stateLen + SEPERATOR_LEN + SPACE_LEN) + secondryStateLen; + maxLen = NODE_NUM * (nodeLen + tmpInstanceLen + (g_ipQuery ? ipLen : 0)) + + SPACE_NUM * (stateLen + SEPERATOR_LEN + SPACE_LEN) + secondryStateLen; } } for (uint32 i = 0; i < maxLen; i++) { @@ -544,19 +604,18 @@ void PrintDnStatusLine() void PrintFenceHeaderLine() { const uint32 nodeLen = MAX_NODE_ID_LEN + SPACE_LEN + max_node_name_len + SPACE_LEN; + uint32 ipLen = GetDnIpMaxLen(); if (g_balanceQuery && g_datanodesBalance) { (void)fprintf(g_logFilePtr, "(no need to switchover datanodes)\n"); } if (g_fencedUdfQuery && !g_balanceQuery) { (void)fprintf(g_logFilePtr, "\n[ Fenced UDF State ]\n\n"); if (g_ipQuery) { - (void)fprintf(g_logFilePtr, "%-*s%-*s%s\n", nodeLen, "node", MAX_IP_LEN + 1, - "node_ip", "state"); + (void)fprintf(g_logFilePtr, "%-*s%-*s%s\n", nodeLen, "node", ipLen, "node_ip", "state"); } else { (void)fprintf(g_logFilePtr, "%-*s%s\n", nodeLen, "node", "state"); } - for (uint32 i = 0; i < nodeLen + INSTANCE_DYNAMIC_ROLE_LEN + (g_ipQuery ? (MAX_IP_LEN + 1) : 0); - i++) { + for (uint32 i = 0; i < nodeLen + INSTANCE_DYNAMIC_ROLE_LEN + (g_ipQuery ? ipLen : 0); i++) { (void)fprintf(g_logFilePtr, "-"); } (void)fprintf(g_logFilePtr, "\n"); @@ -565,15 +624,22 @@ void PrintFenceHeaderLine() void DoProcessNodeEndMsg(const char *receiveMsg) { - cm_to_ctl_instance_status *instanceStatusPtr = (cm_to_ctl_instance_status*)receiveMsg; + int instanceType; + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + cm_to_ctl_instance_status_ipv4 *instanceStatusPtrIpv4 = (cm_to_ctl_instance_status_ipv4 *)receiveMsg; + instanceType = instanceStatusPtrIpv4->instance_type; + } else { + cm_to_ctl_instance_status *instanceStatusPtr = (cm_to_ctl_instance_status *)receiveMsg; + instanceType = instanceStatusPtr->instance_type; + } if (g_coupleQuery && !g_startStatusQuery) { - if (instanceStatusPtr->instance_type == INSTANCE_TYPE_COORDINATE) { + if (instanceType == INSTANCE_TYPE_COORDINATE) { PrintGtmHeaderLine(); } - if (instanceStatusPtr->instance_type == INSTANCE_TYPE_GTM) { + if (instanceType == INSTANCE_TYPE_GTM) { PrintDnStatusLine(); } - if (instanceStatusPtr->instance_type == INSTANCE_TYPE_DATANODE) { + if (instanceType == INSTANCE_TYPE_DATANODE) { PrintFenceHeaderLine(); } } else { diff --git a/src/cm_ctl/ctl_res.cpp b/src/cm_ctl/ctl_res.cpp index df74abe5bdefa5ff39c7a0974a6ad51393d798eb..57e7da5eeae90c74bb63d81f770bedf342fbaf73 100644 --- a/src/cm_ctl/ctl_res.cpp +++ b/src/cm_ctl/ctl_res.cpp @@ -970,12 +970,12 @@ static status_t EditStringToJson( (void)cJSON_AddStringToObject(root, key, value); } else { uint32 index = 0; - if (cm_str_equal(key, RES_NAME) && !CheckResNameForEdit(value)){ + if (cm_str_equal(key, RES_NAME) && !CheckResNameForEdit(value)) { write_runlog(ERROR, "%s%s Res(%s) fails to edit new name to json.\n", GetResOperStr(resCtx->mode), GetInstOperStr(resCtx->inst.mode), resCtx->resName); return CM_ERROR; } - if (cm_str_equal(key, RESOURCE_TYPE) && !CompareResType(value, &index)){ + if (cm_str_equal(key, RESOURCE_TYPE) && !CompareResType(value, &index)) { write_runlog(ERROR, "%s%s Res(%s) fails to edit new resource_type to json.\n", GetResOperStr(resCtx->mode), GetInstOperStr(resCtx->inst.mode), resCtx->resName); return CM_ERROR; @@ -1315,7 +1315,7 @@ void CheckAndWriteJson(const cJSON *root, ResOpMode mode) if (mode == RES_OP_ADD || mode == RES_OP_DEL || mode == RES_OP_EDIT) { if (WriteJsonFile(root, g_jsonFile) != CM_SUCCESS) { write_runlog(ERROR, "failed to write json file(%s).\n", g_jsonFile); - } + } } } diff --git a/src/cm_ctl/ctl_res_check.cpp b/src/cm_ctl/ctl_res_check.cpp index 1ca9b808045832b7599961f1d473c76bb859b889..87a9cb31ffa9c28983bf3fc9f6408d62d61d566f 100644 --- a/src/cm_ctl/ctl_res_check.cpp +++ b/src/cm_ctl/ctl_res_check.cpp @@ -25,6 +25,7 @@ #include "cjson/cJSON.h" #include "cm_text.h" +#include "cm_ip.h" #include "ctl_res.h" #include "ctl_common.h" @@ -340,7 +341,7 @@ static status_t GetExpIpFromJson(cJSON *resItem, const char *key, const char *re static status_t CheckIpValidInJson(cJSON *resItem, const char *key, const char *resName, char *ip, uint32 ipLen) { CM_RETURN_IFERR(GetExpIpFromJson(resItem, key, resName, ip, ipLen)); - if (CheckIpValid(ip) == CM_FALSE) { + if (!CheckIpValid(ip)) { PrintCheckJsonInfo(ERROR, "resource(%s)'s %s is an invalid ip.\n", resName, key); return CM_ERROR; } @@ -383,7 +384,7 @@ static status_t CheckFloatIPResInfo( // base_ip for (int32 i = 0; i < point; ++i) { - if (strcmp(curInfo->ip, info[i].ip) == 0) { + if (IsEqualIp(curInfo->ip, info[i].ip)) { PrintCheckJsonInfo(ERROR, "resource(%s)'s FloatIp base_ip_list base_ip(%s) may be repeated.\n", resName, curInfo->ip); return CM_ERROR; diff --git a/src/cm_ctl/ctl_start.cpp b/src/cm_ctl/ctl_start.cpp index 459a347c20dab62387622e2ba45c4429630591b1..278fd565326d1ff8cdfff625a95c1ef7d7eef761 100644 --- a/src/cm_ctl/ctl_start.cpp +++ b/src/cm_ctl/ctl_start.cpp @@ -23,14 +23,19 @@ * ------------------------------------------------------------------------- */ #include +#include +#include +#include +#include #include "common/config/cm_config.h" #include "cm/libpq-fe.h" #include "cm/cm_misc.h" #include "ctl_common.h" -#include "cm/cm_msg.h" +#include "cm_msg_version_convert.h" #include "cm/libpq-int.h" #include "cm_ddb_adapter.h" #include "ctl_common_res.h" +#include "cm_ip.h" #define EXPECTED_CLUSTER_START_TIME 120 #define ETCD_START_WAIT 90 @@ -731,12 +736,13 @@ static bool CheckLibosKniIsOk() write_runlog(DEBUG1, "%s cheack failed by exec command:%s.\n", checkItem[idx++], checkIpCmd); return false; } - + const char *ping_ip = *g_currentNode->cmAgentIP; + const char *pingStr = GetPingStr(GetIpVersion(ping_ip)); rc = snprintf_s(checPingCmd, MAXPGPATH, MAXPGPATH - 1, - "ping -c 1 -w 1 %s > /dev/null;if [ $? == 0 ];then echo success;else echo fail;fi;", - g_currentNode->cmAgentIP); + "%s -c 1 -w 1 %s > /dev/null;if [ $? == 0 ];then echo success;else echo fail;fi;", + pingStr, ping_ip); securec_check_intval(rc, (void)rc); write_runlog(DEBUG1, "cheak_libnet ping command is %s.\n", checPingCmd); cmdCount = strlen(checPingCmd); @@ -1830,11 +1836,24 @@ static int start_check_cluster() // The cluster status is degrade, not normal, whether a cn is deleted and all other instances are // normal. if (cluster_status == CM_STATUS_DEGRADE) { - cm_to_ctl_instance_status* cm_to_ctl_instance_status_ptr = NULL; - cm_to_ctl_instance_status_ptr = (cm_to_ctl_instance_status*)receive_msg; + cm_to_ctl_instance_status cm_to_ctl_instance_status_ptr = {0}; + cm_to_ctl_instance_status_ipv4 *cm_to_ctl_instance_status_ptr_ipv4 = NULL; + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + cm_to_ctl_instance_status_ptr_ipv4 = (cm_to_ctl_instance_status_ipv4 *)receive_msg; + CmToCtlInstanceStatusV1ToV2( + cm_to_ctl_instance_status_ptr_ipv4, + &cm_to_ctl_instance_status_ptr); + } else { + errno_t rc = memcpy_s( + &cm_to_ctl_instance_status_ptr, + sizeof(cm_to_ctl_instance_status_ptr), + receive_msg, + sizeof(cm_to_ctl_instance_status_ptr)); + securec_check_errno(rc, (void)rc); + } - if (cm_to_ctl_instance_status_ptr->instance_type == INSTANCE_TYPE_COORDINATE) { - int status = cm_to_ctl_instance_status_ptr->coordinatemember.status; + if (cm_to_ctl_instance_status_ptr.instance_type == INSTANCE_TYPE_COORDINATE) { + int status = cm_to_ctl_instance_status_ptr.coordinatemember.status; if (status == INSTANCE_ROLE_DELETED) { cnt_deleted++; @@ -1843,14 +1862,14 @@ static int start_check_cluster() if (status != INSTANCE_ROLE_NORMAL && status != INSTANCE_ROLE_DELETED) { cnt_abnormal++; } - } else if (cm_to_ctl_instance_status_ptr->instance_type == INSTANCE_TYPE_GTM) { - int local_role = cm_to_ctl_instance_status_ptr->gtm_member.local_status.local_role; + } else if (cm_to_ctl_instance_status_ptr.instance_type == INSTANCE_TYPE_GTM) { + int local_role = cm_to_ctl_instance_status_ptr.gtm_member.local_status.local_role; if (local_role != INSTANCE_ROLE_PRIMARY && local_role != INSTANCE_ROLE_STANDBY) { cnt_abnormal++; } - } else if (cm_to_ctl_instance_status_ptr->instance_type == INSTANCE_TYPE_DATANODE) { - int local_role = cm_to_ctl_instance_status_ptr->data_node_member.local_status.local_role; + } else if (cm_to_ctl_instance_status_ptr.instance_type == INSTANCE_TYPE_DATANODE) { + int local_role = cm_to_ctl_instance_status_ptr.data_node_member.local_status.local_role; if (local_role != INSTANCE_ROLE_PRIMARY && local_role != INSTANCE_ROLE_STANDBY && local_role != INSTANCE_ROLE_DUMMY_STANDBY) { cnt_abnormal++; @@ -1986,16 +2005,29 @@ static int start_check_node(uint32 node_id_check) receive_msg = recv_cm_server_cmd(CmServer_conn); while (receive_msg != NULL) { - cm_msg_type_ptr = (cm_msg_type*)receive_msg; + cm_msg_type_ptr = (cm_msg_type *)receive_msg; switch (cm_msg_type_ptr->msg_type) { case MSG_CM_CTL_DATA_BEGIN: break; case MSG_CM_CTL_DATA: { - cm_to_ctl_instance_status *cm_to_ctl_instance_status_ptr = - (cm_to_ctl_instance_status *)receive_msg; - if (cm_to_ctl_instance_status_ptr->instance_type == INSTANCE_TYPE_COORDINATE && - g_node[node_id_check].node == cm_to_ctl_instance_status_ptr->node && - cm_to_ctl_instance_status_ptr->coordinatemember.status == INSTANCE_ROLE_DELETED) { + cm_to_ctl_instance_status cm_to_ctl_instance_status_ptr = {0}; + cm_to_ctl_instance_status_ipv4 *cm_to_ctl_instance_status_ptr_ipv4 = NULL; + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + cm_to_ctl_instance_status_ptr_ipv4 = (cm_to_ctl_instance_status_ipv4 *)receive_msg; + CmToCtlInstanceStatusV1ToV2( + cm_to_ctl_instance_status_ptr_ipv4, + &cm_to_ctl_instance_status_ptr); + } else { + errno_t rc = memcpy_s( + &cm_to_ctl_instance_status_ptr, + sizeof(cm_to_ctl_instance_status_ptr), + receive_msg, + sizeof(cm_to_ctl_instance_status_ptr)); + securec_check_errno(rc, (void)rc); + } + if (cm_to_ctl_instance_status_ptr.instance_type == INSTANCE_TYPE_COORDINATE && + g_node[node_id_check].node == cm_to_ctl_instance_status_ptr.node && + cm_to_ctl_instance_status_ptr.coordinatemember.status == INSTANCE_ROLE_DELETED) { cnt_deleted++; } rec_data_end = true; diff --git a/src/cm_ctl/ctl_switchover.cpp b/src/cm_ctl/ctl_switchover.cpp index 319bd7d56eae643f7679a68d8c4ffb5c4b321864..a750b27556f435fc8b60fe8338096c38f08cf7a3 100644 --- a/src/cm_ctl/ctl_switchover.cpp +++ b/src/cm_ctl/ctl_switchover.cpp @@ -29,7 +29,7 @@ #include "cm/libpq-int.h" #include "cm/cm_agent/cma_main.h" #include "cm_elog.h" -#include "cm_msg.h" +#include "cm_msg_version_convert.h" /* If DN switch take long time and do not complete, it will timeout, pending_command will be clear in server_main.cpp CM_ThreadMonitorMain(), the default g_wait_seconds is 180s, we need to increase the g_wait_seconds to 1200s. */ @@ -107,7 +107,7 @@ static int DoSwitchoverBase(const CtlOption *ctx) ctl_to_cm_query queryMsg; ctl_to_cm_switchover switchoverMsg; cm_to_ctl_command_ack *ackMsg = NULL; - cm_to_ctl_instance_status *instStatusPtr = NULL; + cm_to_ctl_instance_status instStatusPtr = {0}; cm_switchover_incomplete_msg *switchoverIncompletePtr = NULL; SwitchoverOper oper; if (g_ssDoubleClusterMode == SS_DOUBLE_STANDBY) { @@ -176,27 +176,27 @@ static int DoSwitchoverBase(const CtlOption *ctx) break; case MSG_CM_CTL_DATA: - instStatusPtr = (cm_to_ctl_instance_status*)receiveMsg; - if (instStatusPtr->instance_type == INSTANCE_TYPE_GTM) { - if ((instStatusPtr->gtm_member.local_status.local_role == oper.localRole) && - (instStatusPtr->gtm_member.local_status.connect_status == CON_OK) && - (instStatusPtr->gtm_member.local_status.sync_mode == INSTANCE_DATA_REPLICATION_SYNC)) { + GetCtlInstanceStatusFromRecvMsg(receiveMsg, &instStatusPtr); + if (instStatusPtr.instance_type == INSTANCE_TYPE_GTM) { + if ((instStatusPtr.gtm_member.local_status.local_role == oper.localRole) && + (instStatusPtr.gtm_member.local_status.connect_status == CON_OK) && + (instStatusPtr.gtm_member.local_status.sync_mode == INSTANCE_DATA_REPLICATION_SYNC)) { success = true; } - } else if (instStatusPtr->instance_type == INSTANCE_TYPE_DATANODE) { - if ((instStatusPtr->data_node_member.local_status.local_role == oper.localRole) && - (instStatusPtr->data_node_member.sender_status[0].peer_role == oper.peerRole || - instStatusPtr->data_node_member.sender_status[0].peer_role == INSTANCE_ROLE_INIT)) { + } else if (instStatusPtr.instance_type == INSTANCE_TYPE_DATANODE) { + if ((instStatusPtr.data_node_member.local_status.local_role == oper.localRole) && + (instStatusPtr.data_node_member.sender_status[0].peer_role == oper.peerRole || + instStatusPtr.data_node_member.sender_status[0].peer_role == INSTANCE_ROLE_INIT)) { success = true; } - if ((instStatusPtr->data_node_member.local_status.local_role == INSTANCE_ROLE_PENDING) || - (instStatusPtr->data_node_member.sender_status[0].peer_role == INSTANCE_ROLE_PENDING)) { + if ((instStatusPtr.data_node_member.local_status.local_role == INSTANCE_ROLE_PENDING) || + (instStatusPtr.data_node_member.sender_status[0].peer_role == INSTANCE_ROLE_PENDING)) { write_runlog(ERROR, "can not do switchover at current role.\n"); FINISH_CONNECTION(); } - if ((instStatusPtr->data_node_member.local_status.db_state != INSTANCE_HA_STATE_PROMOTING) && - (instStatusPtr->data_node_member.local_status.db_state != INSTANCE_HA_STATE_WAITING) && - (instStatusPtr->data_node_member.local_status.local_role == INSTANCE_ROLE_STANDBY)) { + if ((instStatusPtr.data_node_member.local_status.db_state != INSTANCE_HA_STATE_PROMOTING) && + (instStatusPtr.data_node_member.local_status.db_state != INSTANCE_HA_STATE_WAITING) && + (instStatusPtr.data_node_member.local_status.local_role == INSTANCE_ROLE_STANDBY)) { unExpectedTime++; } else { unExpectedTime = 0; @@ -1187,8 +1187,8 @@ static int QueryNeedQuickSwitchInstances(int* need_quick_switchover_instance, int wait_time; char* receiveMsg = NULL; cm_msg_type *msgType = NULL; - cm_to_ctl_instance_status* cm_to_ctl_instance_status_ptr = NULL; - cm_to_ctl_cluster_status* cm_to_ctl_cluster_status_ptr = NULL; + cm_to_ctl_instance_status cm_to_ctl_instance_status_ptr = {0}; + cm_to_ctl_cluster_status *cm_to_ctl_cluster_status_ptr = NULL; int ret; /* return conn to cm_server */ @@ -1227,7 +1227,7 @@ static int QueryNeedQuickSwitchInstances(int* need_quick_switchover_instance, msgType = (cm_msg_type*)receiveMsg; switch (msgType->msg_type) { case MSG_CM_CTL_DATA_BEGIN: - cm_to_ctl_cluster_status_ptr = (cm_to_ctl_cluster_status*)receiveMsg; + cm_to_ctl_cluster_status_ptr = (cm_to_ctl_cluster_status *)receiveMsg; if (switchover_query_second) { if (cm_to_ctl_cluster_status_ptr->switchedCount == 0) { *is_cluster_balance = true; @@ -1242,12 +1242,11 @@ static int QueryNeedQuickSwitchInstances(int* need_quick_switchover_instance, } break; case MSG_CM_CTL_DATA: - cm_to_ctl_instance_status_ptr = (cm_to_ctl_instance_status*)receiveMsg; + GetCtlInstanceStatusFromRecvMsg(receiveMsg, &cm_to_ctl_instance_status_ptr); GetNeedQuickSwitchInstances( - cm_to_ctl_instance_status_ptr, need_quick_switchover_instance, needQuickSwitchoverInstance); + &cm_to_ctl_instance_status_ptr, need_quick_switchover_instance, needQuickSwitchoverInstance); break; case MSG_CM_CTL_NODE_END: - cm_to_ctl_instance_status_ptr = (cm_to_ctl_instance_status*)receiveMsg; break; case MSG_CM_CTL_DATA_END: rec_data_end = true; diff --git a/src/cm_server/cms_arbitrate_datanode_pms.cpp b/src/cm_server/cms_arbitrate_datanode_pms.cpp index 1ab3f6414374bf98da60db04a7ae86a6d5ea182a..4eef85e0bb7b51f8a3d33072e8dc142ab3076d97 100644 --- a/src/cm_server/cms_arbitrate_datanode_pms.cpp +++ b/src/cm_server/cms_arbitrate_datanode_pms.cpp @@ -29,6 +29,8 @@ #include "cms_common.h" #include "cms_disk_check.h" #include "cms_alarm.h" +#include "cm_ip.h" +#include "cm_msg_version_convert.h" #ifdef ENABLE_MULTIPLE_NODES #include "cms_arbitrate_gtm.h" #endif @@ -106,7 +108,7 @@ static void SendLock1Message(const DnArbCtx *ctx) static void SendLock2Messange(const DnArbCtx *ctx, const char *dhost, int dlen, uint32 dport, uint32 primaryTerm) { - cm_to_agent_lock2 lock2MsgPtr; + cm_to_agent_lock2 lock2MsgPtr = {0}; lock2MsgPtr.msg_type = (int)MSG_CM_AGENT_LOCK_CHOSEN_PRIMARY; if (g_clusterType == V3SingleInstCluster) { lock2MsgPtr.node = primaryTerm; @@ -114,12 +116,18 @@ static void SendLock2Messange(const DnArbCtx *ctx, const char *dhost, int dlen, lock2MsgPtr.node = ctx->node; } lock2MsgPtr.instanceId = ctx->instId; - errno_t rc = snprintf_s(lock2MsgPtr.disconn_host, (size_t)HOST_LENGTH, dlen, "%s", dhost); + errno_t rc = snprintf_s(lock2MsgPtr.disconn_host, (size_t)CM_IP_LENGTH, dlen, "%s", dhost); securec_check_intval(rc, (void)rc); lock2MsgPtr.disconn_port = dport; write_runlog(LOG, "send lock2 message to instance(%u: %u), dhost=%s, dport=%u.\n", ctx->instId, GetInstanceIdInGroup(ctx->groupIdx, ctx->cond.vaildPrimIdx), dhost, dport); - (void)RespondMsg(ctx->recvMsgInfo, 'S', (char *)&lock2MsgPtr, sizeof(cm_to_agent_lock2)); + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + cm_to_agent_lock2_ipv4 lock2MsgPtrIpv4; + CmToAgentLock2V2ToV1(&lock2MsgPtr, &lock2MsgPtrIpv4); + (void)RespondMsg(ctx->recvMsgInfo, 'S', (char *)&lock2MsgPtrIpv4, sizeof(cm_to_agent_lock2_ipv4)); + } else { + (void)RespondMsg(ctx->recvMsgInfo, 'S', (char *)&lock2MsgPtr, sizeof(cm_to_agent_lock2)); + } } static void copy_cm_to_agent_failover_msg(cm_to_agent_failover* failover_msg_ptr, diff --git a/src/cm_server/cms_az.cpp b/src/cm_server/cms_az.cpp index 02bd3ad1c6aa97976131c8f961fce47ae29f2467..5425d6a92697ef0cfc68da8f1f53c2ae0357efb5 100644 --- a/src/cm_server/cms_az.cpp +++ b/src/cm_server/cms_az.cpp @@ -27,6 +27,7 @@ #include "cms_process_messages.h" #include "cms_common.h" #include "cms_az.h" +#include "cm_ip.h" static uint32 GetCurrentAZnodeNum(const char *azName); static void StartOrStopInstanceByCommand(OperateType operateType, uint32 node, const char *instanceDataPath, @@ -260,13 +261,14 @@ bool doPingAzNodes(const char *sshIp, AZRole azRole) do { for (i = 0; i < g_node_num; i++) { if (isAZPrioritySatisfyAZRole(g_node[i].azPriority, azRole)) { + const char *pingStr = GetPingStr(GetIpVersion(g_node[i].cmAgentIP[0])); if (sshIp != NULL) { rc = snprintf_s(pingCommand, CM_MAX_COMMAND_LEN, CM_MAX_COMMAND_LEN - 1, - "pssh %s -s -H %s \"ping %s %s\" ", - PSSH_TIMEOUT, sshIp, g_node[i].cmAgentIP[0], PING_TIMEOUT_OPTION); + "pssh %s -s -H %s \"%s %s %s\" ", + PSSH_TIMEOUT, sshIp, pingStr, g_node[i].cmAgentIP[0], PING_TIMEOUT_OPTION); } else { rc = snprintf_s(pingCommand, CM_MAX_COMMAND_LEN, CM_MAX_COMMAND_LEN - 1, - "ping %s %s", g_node[i].cmAgentIP[0], PING_TIMEOUT_OPTION); + "%s %s %s", pingStr, g_node[i].cmAgentIP[0], PING_TIMEOUT_OPTION); } securec_check_intval(rc, (void)rc); rc = system(pingCommand); @@ -301,13 +303,16 @@ bool doCheckAzStatus(const char *sshIp, AZRole azRole) char checkStartFile[CM_MAX_COMMAND_LONG_LEN] = {0}; for (uint32 i = 0; i < g_node_num; i++) { + const char *ping_ip = g_node[i].cmAgentIP[0]; + const char *pingStr = GetPingStr(GetIpVersion(ping_ip)); if (isAZPrioritySatisfyAZRole(g_node[i].azPriority, azRole)) { if (sshIp == NULL) { rc = snprintf_s(checkStartFile, CM_MAX_COMMAND_LONG_LEN, CM_MAX_COMMAND_LONG_LEN - 1, - "ping %s %s;if [ $? == 0 ];then pssh %s -s -H %s \"ls %s \";fi;", - g_node[i].cmAgentIP[0], + "%s %s %s;if [ $? == 0 ];then pssh %s -s -H %s \"ls %s \";fi;", + pingStr, + ping_ip, PING_TIMEOUT_OPTION, PSSH_TIMEOUT, g_node[i].sshChannel[0], @@ -316,17 +321,19 @@ bool doCheckAzStatus(const char *sshIp, AZRole azRole) rc = snprintf_s(checkStartFile, CM_MAX_COMMAND_LONG_LEN, CM_MAX_COMMAND_LONG_LEN - 1, - "ping %s %s;" - "if [ $? == 0 ];then pssh %s -s -H %s \" " - " echo 'ping %s %s;if [ $\"\"? -eq 0 ];then touch %s/azIpcheck.flag;fi;' > %s/azIpcheck.sh;" + "%s %s %s;" + "if [ $? == 0 ];then pssh %s -s -H [%s] \" " + " echo '%s %s %s;if [ $\"\"? -eq 0 ];then touch %s/azIpcheck.flag;fi;' > %s/azIpcheck.sh;" " sh %s/azIpcheck.sh;rm -f %s/azIpcheck.sh;" " if test -e %s/azIpcheck.flag;then rm -f %s/azIpcheck.flag;pssh %s -s -H %s \"ls %s \";fi;" "\";fi;", + pingStr, sshIp, PING_TIMEOUT_OPTION, PSSH_TIMEOUT, sshIp, - g_node[i].cmAgentIP[0], + pingStr, + ping_ip, PING_TIMEOUT_OPTION, sys_log_path, sys_log_path, @@ -483,19 +490,27 @@ static void *PingIpThrdFuncMain(void *arg) char command[MAXPGPATH] = {0}; char buf[MAXPGPATH]; PingCheckThreadParmInfo *info = (PingCheckThreadParmInfo *)arg; + + if (info == NULL) { + write_runlog(ERROR, "PingIpThrdFuncMain: invalid argument (info is NULL)\n"); + return NULL; + } + uint32 threadIndex = info->threadIdx; uint32 nodeIndex = 0; int ret = find_node_index_by_nodeid(info->azNode, &nodeIndex); + int rc; if (ret != 0) { write_runlog(ERROR, "PingIpThrdFuncMain: get node index failed!\n"); return NULL; } - - int rc = snprintf_s(command, + + const char *pingStr = GetPingStr(GetIpVersion(g_node[nodeIndex].cmAgentIP[0])); + rc = snprintf_s(command, MAXPGPATH, MAXPGPATH - 1, - "ping -c 1 -w 1 %s > /dev/null;if [ $? == 0 ];then echo success;else echo fail;fi;", - g_node[nodeIndex].cmAgentIP[0]); + "%s -c 1 -w 1 %s > /dev/null;if [ $? == 0 ];then echo success;else echo fail;fi;", + pingStr, g_node[nodeIndex].cmAgentIP[0]); securec_check_intval(rc, (void)rc); write_runlog(DEBUG1, "ping command is %s.\n", command); diff --git a/src/cm_server/cms_common.cpp b/src/cm_server/cms_common.cpp index 3b2d07829bc7d1e647a0fe629d2dade52d40df9b..7580cef0036283bdaea43ecb9c83b779c517b244 100644 --- a/src/cm_server/cms_common.cpp +++ b/src/cm_server/cms_common.cpp @@ -23,6 +23,8 @@ */ #include #include +#include +#include #include #include "cms_global_params.h" #include "sys/epoll.h" @@ -30,6 +32,7 @@ #include "cms_common.h" static const int CMS_NETWORK_ISOLATION_TIMES = 20; static const int BOOL_STR_MAX_LEN = 10; + void ExecSystemSsh(uint32 remoteNodeid, const char *cmd, int *result, const char *resultPath) { int rc; @@ -234,16 +237,24 @@ bool is_valid_host(const CM_Connection* con, int remote_type) return false; } - struct sockaddr_in peerAddr = {0}; - socklen_t sockLen = sizeof(sockaddr_in); + struct sockaddr_storage peerAddr; + socklen_t sockLen = sizeof(peerAddr); int ret = getpeername(con->port->sock, (struct sockaddr*)&peerAddr, &sockLen); if (ret < 0) { write_runlog(ERROR, "getpeername failed, sockfd=%d, remote_type=%d.\n", con->port->sock, remote_type); return false; } - char* peerIP = inet_ntoa(peerAddr.sin_addr); - if (peerIP == NULL) { - write_runlog(ERROR, "inet_ntoa failed, sockfd=%d, remote_type=%d.\n", con->port->sock, remote_type); + + char peerIP[INET6_ADDRSTRLEN]; // INET6_ADDRSTRLEN is sufficient for both IPv4 and IPv6 + if (peerAddr.ss_family == AF_INET) { + struct sockaddr_in *ipv4 = (struct sockaddr_in*)&peerAddr; + inet_ntop(AF_INET, &(ipv4->sin_addr), peerIP, INET_ADDRSTRLEN); + } else if (peerAddr.ss_family == AF_INET6) { + struct sockaddr_in6 *ipv6 = (struct sockaddr_in6*)&peerAddr; + inet_ntop(AF_INET6, &(ipv6->sin6_addr), peerIP, INET6_ADDRSTRLEN); + } else { + write_runlog(ERROR, "Unknown address family for peer, sockfd=%d, remote_type=%d.\n", + con->port->sock, remote_type); return false; } @@ -251,7 +262,7 @@ bool is_valid_host(const CM_Connection* con, int remote_type) case CM_AGENT: for (i = 0; i < g_node_num; i++) { for (j = 0; j < g_node[i].cmAgentListenCount; j++) { - if (strncmp(g_node[i].cmAgentIP[j], peerIP, SP_HOST) == 0) { + if (strcmp(g_node[i].cmAgentIP[j], peerIP) == 0) { return true; } } @@ -261,7 +272,7 @@ bool is_valid_host(const CM_Connection* con, int remote_type) case CM_CTL: for (i = 0; i < g_node_num; i++) { for (j = 0; j < g_node[i].cmAgentListenCount; j++) { - if (strncmp(g_node[i].cmAgentIP[j], peerIP, SP_HOST) == 0) { + if (strcmp(g_node[i].cmAgentIP[j], peerIP) == 0) { return true; } } @@ -270,12 +281,11 @@ bool is_valid_host(const CM_Connection* con, int remote_type) case CM_SERVER: for (i = 0; i < g_currentNode->cmServerPeerHAListenCount; i++) { - if (strncmp(g_currentNode->cmServerPeerHAIP[i], peerIP, SP_HOST) == 0) { + if (strcmp(g_currentNode->cmServerPeerHAIP[i], peerIP) == 0) { return true; } } break; - default: break; } diff --git a/src/cm_server/cms_cus_res.cpp b/src/cm_server/cms_cus_res.cpp index 33542916dd2238c3a3a054232cc6fbbe4fea29d0..714c190790c641380ee205c14613e466cda3887c 100644 --- a/src/cm_server/cms_cus_res.cpp +++ b/src/cm_server/cms_cus_res.cpp @@ -94,6 +94,7 @@ void *UpdateResStatusListMain(void *arg) if (g_HA_status->local_role == CM_SERVER_PRIMARY) { if (g_resStatListStatus == THREAD_PROCESS_READY) { GetResStatAndSetThreadStat(THREAD_PROCESS_RUNNING, oldResVersion); + CleanAllResStatusReportInter(); } if (g_resStatListStatus == THREAD_PROCESS_RUNNING) { SaveLatestResStat(oldResVersion); diff --git a/src/cm_server/cms_monitor_main.cpp b/src/cm_server/cms_monitor_main.cpp index 0e4e3391e3d510602c614d2517b7c342335711a8..c0bf3dd81b51cd8f5124c50f25efc89c3096f2a4 100644 --- a/src/cm_server/cms_monitor_main.cpp +++ b/src/cm_server/cms_monitor_main.cpp @@ -21,6 +21,8 @@ * * ------------------------------------------------------------------------- */ +#include +#include #include "cm/cm_elog.h" #include "cms_alarm.h" #include "cms_ddb.h" @@ -906,45 +908,67 @@ static status_t IsPeerCmsReachableOn2Nodes() return CM_ERROR; } - // create socket - int socketFd = socket(AF_INET, SOCK_STREAM, 0); - if (socketFd == -1) { - write_runlog(ERROR, "could not create socket.\n"); - return CM_ERROR; - } - + int socketFd = -1; + struct addrinfo hints; + struct addrinfo *result; + struct addrinfo *rp; struct timeval tv = { 0, 0 }; - tv.tv_sec = CM_TCP_TIMEOUT; - (void)setsockopt(socketFd, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv)); - (void)setsockopt(socketFd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)); + status_t ret = CM_ERROR; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6 + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; - struct sockaddr_in sockAddr; - status_t ret = CM_SUCCESS; for (uint32 i = 0; i < g_cm_server_num; i++) { if (g_node[i].cmServerId == g_currentNode->cmServerId) { continue; } - // got peer cms info - sockAddr.sin_addr.s_addr = inet_addr(g_node[i].cmServerLocalHAIP[0]); - sockAddr.sin_family = AF_INET; - sockAddr.sin_port = htons(g_node[i].cmServerLocalHAPort); + // Resolve peer cms hostname to IP addresses + int addrStatus = getaddrinfo(g_node[i].cmServerLocalHAIP[0], NULL, &hints, &result); + if (addrStatus != 0) { + write_runlog(ERROR, "getaddrinfo: %s\n", gai_strerror(addrStatus)); + continue; + } - // Connect to peer cms dcc ip:port - if (connect(socketFd , (struct sockaddr *)&sockAddr , sizeof(sockAddr)) < 0) { - write_runlog(LOG, "could not connect to peer cms %s:%d.\n", - g_node[i].cmServerLocalHAIP[0], g_node[i].cmServerLocalHAPort); - ret = CM_ERROR; - } else { - write_runlog(DEBUG1, "connect to peer cms %s:%d successfuly.\n", - g_node[i].cmServerLocalHAIP[0], g_node[i].cmServerLocalHAPort); + for (rp = result; rp != NULL; rp = rp->ai_next) { + socketFd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (socketFd == -1) { + write_runlog(ERROR, "could not create socket.\n"); + continue; + } + + tv.tv_sec = CM_TCP_TIMEOUT; + setsockopt(socketFd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + setsockopt(socketFd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + + if (connect(socketFd, rp->ai_addr, rp->ai_addrlen) == -1) { + write_runlog(LOG, "could not connect to peer cms.\n"); + ret = CM_ERROR; + } + char addrStr[INET6_ADDRSTRLEN]; + void *addr; + if (rp->ai_family == AF_INET) { + struct sockaddr_in *ipv4 = (struct sockaddr_in *)rp->ai_addr; + addr = &(ipv4->sin_addr); + } else { // AF_INET6 + struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)rp->ai_addr; + addr = &(ipv6->sin6_addr); + } + inet_ntop(rp->ai_family, addr, addrStr, sizeof(addrStr)); + write_runlog(DEBUG1, "connect to peer cms %s successfuly.\n", addrStr); ret = CM_SUCCESS; + close(socketFd); + break; // Connected successfully, break out of loop } - break; + freeaddrinfo(result); + if (ret == CM_SUCCESS) { + break; // Connected successfully, break out of loop + } } - close(socketFd); return ret; } diff --git a/src/cm_server/cms_process_messages.cpp b/src/cm_server/cms_process_messages.cpp index 99a62f0b25668f2bfd8812aee5e69a8179e96bd6..420a8dda5eea842a4780e3d8217e6607438e309c 100644 --- a/src/cm_server/cms_process_messages.cpp +++ b/src/cm_server/cms_process_messages.cpp @@ -40,7 +40,7 @@ const int DOUBLE_REPLICATION = 2; -#define PROCESS_MSG_BY_TYPE_WITHOUT_CONN(struct_name, strunct_ptr, function_name) \ +#define PROCESS_MSG_BY_TYPE_WITHOUT_CONN(struct_name, strunct_ptr, function_name) \ do { \ (strunct_ptr) = (struct_name *)CmGetmsgbytes((CM_StringInfo)&recvMsgInfo->msg, sizeof(struct_name)); \ if ((strunct_ptr) != NULL) { \ @@ -1262,32 +1262,37 @@ static void MsgRelationDatanode(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgPro { ctl_to_cm_datanode_relation_info *ctlToCmDatanodeRelationInfoPtr; PROCESS_MSG_BY_TYPE( - ctl_to_cm_datanode_relation_info, ctlToCmDatanodeRelationInfoPtr, process_ctl_to_cm_get_datanode_relation_msg); + ctl_to_cm_datanode_relation_info, ctlToCmDatanodeRelationInfoPtr, process_ctl_to_cm_get_datanode_relation_msg, + recvMsgInfo, msgType); } static void MsgSwitchover(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { ctl_to_cm_switchover *ctlToCmSwithoverPtr; - PROCESS_MSG_BY_TYPE(ctl_to_cm_switchover, ctlToCmSwithoverPtr, ProcessCtlToCmSwitchoverMsg); + PROCESS_MSG_BY_TYPE(ctl_to_cm_switchover, ctlToCmSwithoverPtr, ProcessCtlToCmSwitchoverMsg, + recvMsgInfo, msgType); } static void MsgSwitchoverFast(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { ctl_to_cm_switchover *ctlToCmSwithoverPtr; msgProc->doSwitchover = true; - PROCESS_MSG_BY_TYPE(ctl_to_cm_switchover, ctlToCmSwithoverPtr, ProcessCtlToCmSwitchoverMsg); + PROCESS_MSG_BY_TYPE(ctl_to_cm_switchover, ctlToCmSwithoverPtr, ProcessCtlToCmSwitchoverMsg, + recvMsgInfo, msgType); } static void MsgSwitchoverAll(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { ctl_to_cm_switchover *ctlToCmSwithoverPtr; - PROCESS_MSG_BY_TYPE(ctl_to_cm_switchover, ctlToCmSwithoverPtr, ProcessCtlToCmSwitchoverAllMsg); + PROCESS_MSG_BY_TYPE(ctl_to_cm_switchover, ctlToCmSwithoverPtr, ProcessCtlToCmSwitchoverAllMsg, + recvMsgInfo, msgType); } static void MsgSwitchoverFull(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { ctl_to_cm_switchover *ctlToCmSwithoverPtr; - PROCESS_MSG_BY_TYPE(ctl_to_cm_switchover, ctlToCmSwithoverPtr, process_ctl_to_cm_switchover_full_msg); + PROCESS_MSG_BY_TYPE(ctl_to_cm_switchover, ctlToCmSwithoverPtr, process_ctl_to_cm_switchover_full_msg, + recvMsgInfo, msgType); } static void MsgSwitchoverFullCheck(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) @@ -1303,7 +1308,8 @@ static void MsgSwitchoverFullTimeout(MsgRecvInfo* recvMsgInfo, int msgType, CmdM static void MsgSwitchoverAz(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { ctl_to_cm_switchover *ctlToCmSwithoverPtr; - PROCESS_MSG_BY_TYPE(ctl_to_cm_switchover, ctlToCmSwithoverPtr, ProcessCtlToCmSwitchoverAzMsg); + PROCESS_MSG_BY_TYPE(ctl_to_cm_switchover, ctlToCmSwithoverPtr, ProcessCtlToCmSwitchoverAzMsg, + recvMsgInfo, msgType); } static void MsgSwitchoverAzTimeout(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) @@ -1334,7 +1340,8 @@ static void MsgSetMode(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgPro static void MsgBuild(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { ctl_to_cm_build* ctlToCmBuildPtr; - PROCESS_MSG_BY_TYPE(ctl_to_cm_build, ctlToCmBuildPtr, ProcessCtlToCmBuildMsg); + PROCESS_MSG_BY_TYPE(ctl_to_cm_build, ctlToCmBuildPtr, ProcessCtlToCmBuildMsg, + recvMsgInfo, msgType); } static void MsgSync(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) @@ -1370,13 +1377,15 @@ static void MsgNotify(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc static void MsgQuery(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { ctl_to_cm_query *ctlToCmQueryPtr; - PROCESS_MSG_BY_TYPE(ctl_to_cm_query, ctlToCmQueryPtr, ProcessCtlToCmQueryMsg); + PROCESS_MSG_BY_TYPE(ctl_to_cm_query, ctlToCmQueryPtr, ProcessCtlToCmQueryMsg, + recvMsgInfo, msgType); } static void MsgCtlResourceStatus(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { CmsToCtlGroupResStatus *queryStatusPtr; - PROCESS_MSG_BY_TYPE(CmsToCtlGroupResStatus, queryStatusPtr, ProcessResInstanceStatusMsg); + PROCESS_MSG_BY_TYPE(CmsToCtlGroupResStatus, queryStatusPtr, ProcessResInstanceStatusMsg, + recvMsgInfo, msgType); } static void MsgQueryCmserver(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) @@ -1387,7 +1396,8 @@ static void MsgQueryCmserver(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc * static void MsgSet(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { ctl_to_cm_set *ctl_to_cm_set_ptr; - PROCESS_MSG_BY_TYPE(ctl_to_cm_set, ctl_to_cm_set_ptr, ProcessCtlToCmSetMsg); + PROCESS_MSG_BY_TYPE(ctl_to_cm_set, ctl_to_cm_set_ptr, ProcessCtlToCmSetMsg, + recvMsgInfo, msgType); } static void MsgGet(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) @@ -1410,7 +1420,8 @@ static void MsgFencedUdf(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgP static void MsgHeatbeat(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { agent_to_cm_heartbeat *agentToCmHeartbeatPtr; - PROCESS_MSG_BY_TYPE(agent_to_cm_heartbeat, agentToCmHeartbeatPtr, process_agent_to_cm_heartbeat_msg); + PROCESS_MSG_BY_TYPE(agent_to_cm_heartbeat, agentToCmHeartbeatPtr, process_agent_to_cm_heartbeat_msg, + recvMsgInfo, msgType); } static void MsgGsGucAck(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) @@ -1429,13 +1440,14 @@ static void MsgEtcdCurrentTime(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc static void MsgQueryInstanceStatus(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { cm_query_instance_status *cmQueryInstanceStatusPtr; - PROCESS_MSG_BY_TYPE(cm_query_instance_status, cmQueryInstanceStatusPtr, process_to_query_instance_status_msg); + PROCESS_MSG_BY_TYPE(cm_query_instance_status, cmQueryInstanceStatusPtr, process_to_query_instance_status_msg, + recvMsgInfo, msgType); } static void MsgHotpatch(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { cm_hotpatch_msg *cmHotpatchMsgPtr; - PROCESS_MSG_BY_TYPE(cm_hotpatch_msg, cmHotpatchMsgPtr, ProcessHotpatchMessage); + PROCESS_MSG_BY_TYPE(cm_hotpatch_msg, cmHotpatchMsgPtr, ProcessHotpatchMessage, recvMsgInfo, msgType); } static void MsgStopArbitration(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) @@ -1506,13 +1518,13 @@ static void MsgDnSyncList(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msg static void MsgDnMostAvailable(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { AgentToCmserverDnSyncAvailable *availableMsg; - PROCESS_MSG_BY_TYPE(AgentToCmserverDnSyncAvailable, availableMsg, ProcessDnMostAvailableMsg); + PROCESS_MSG_BY_TYPE(AgentToCmserverDnSyncAvailable, availableMsg, ProcessDnMostAvailableMsg, recvMsgInfo, msgType); } static void MsgDnLocalPeer(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { AgentCmDnLocalPeer *dnLocalPeer; - PROCESS_MSG_BY_TYPE(AgentCmDnLocalPeer, dnLocalPeer, ProcessDnLocalPeerMsg); + PROCESS_MSG_BY_TYPE(AgentCmDnLocalPeer, dnLocalPeer, ProcessDnLocalPeerMsg, recvMsgInfo, msgType); } static void MsgReload(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) @@ -1523,13 +1535,15 @@ static void MsgReload(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc static void MsgDdbCmd(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { ExecDdbCmdMsg *execDccCmdMsg; - PROCESS_MSG_BY_TYPE(ExecDdbCmdMsg, execDccCmdMsg, ProcessCtlToCmExecDccCmdMsg); + PROCESS_MSG_BY_TYPE(ExecDdbCmdMsg, execDccCmdMsg, ProcessCtlToCmExecDccCmdMsg, + recvMsgInfo, msgType); } static void MsgSwitchCmd(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { CtlToCmsSwitch *switchMsg; - PROCESS_MSG_BY_TYPE(CtlToCmsSwitch, switchMsg, ProcessCtlToCmsSwitchMsg); + PROCESS_MSG_BY_TYPE(CtlToCmsSwitch, switchMsg, ProcessCtlToCmsSwitchMsg, + recvMsgInfo, msgType); } static void MsgRequestResStatusList(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) @@ -1554,7 +1568,8 @@ static void MsgLatestResStatusList(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsg return; } RequestLatestStatList *recvMsg; - PROCESS_MSG_BY_TYPE(RequestLatestStatList, recvMsg, ProcessRequestLatestResStatusListMsg); + PROCESS_MSG_BY_TYPE(RequestLatestStatList, recvMsg, ProcessRequestLatestResStatusListMsg, + recvMsgInfo, msgType); } static void MsgGetSharedStorageInfo(MsgRecvInfo *recvMsgInfo, int msgType, CmdMsgProc *msgProc) @@ -1565,13 +1580,15 @@ static void MsgGetSharedStorageInfo(MsgRecvInfo *recvMsgInfo, int msgType, CmdMs static void MsgDdbOper(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { CltSendDdbOper *cltSendOper; - PROCESS_MSG_BY_TYPE(CltSendDdbOper, cltSendOper, ProcessCltSendOper); + PROCESS_MSG_BY_TYPE(CltSendDdbOper, cltSendOper, ProcessCltSendOper, + recvMsgInfo, msgType); } static void MsgSslConnRequest(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { AgentToCmConnectRequest *connMsgReq; - PROCESS_MSG_BY_TYPE(AgentToCmConnectRequest, connMsgReq, ProcessSslConnRequest); + PROCESS_MSG_BY_TYPE(AgentToCmConnectRequest, connMsgReq, ProcessSslConnRequest, + recvMsgInfo, msgType); } static void MsgCmResLock(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) @@ -1580,19 +1597,22 @@ static void MsgCmResLock(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgP return; } CmaToCmsResLock *lockMsg = NULL; - PROCESS_MSG_BY_TYPE(CmaToCmsResLock, lockMsg, ProcessCmResLock); + PROCESS_MSG_BY_TYPE(CmaToCmsResLock, lockMsg, ProcessCmResLock, + recvMsgInfo, msgType); } static void MsgCmQueryOneResInst(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { QueryOneResInstStat *queryMsg = NULL; - PROCESS_MSG_BY_TYPE(QueryOneResInstStat, queryMsg, ProcessQueryOneResInst); + PROCESS_MSG_BY_TYPE(QueryOneResInstStat, queryMsg, ProcessQueryOneResInst, + recvMsgInfo, msgType); } void MsgCmQueryDnInfo(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { QueryOneResInstStat *queryMsg = NULL; - PROCESS_MSG_BY_TYPE(QueryOneResInstStat, queryMsg, ProcessQueryDnStatusAndRole); + PROCESS_MSG_BY_TYPE(QueryOneResInstStat, queryMsg, ProcessQueryDnStatusAndRole, + recvMsgInfo, msgType); } void ProcessCmRhbMsg(MsgRecvInfo *recvMsgInfo, const CmRhbMsg *rhbMsg) @@ -1604,7 +1624,7 @@ void ProcessCmRhbMsg(MsgRecvInfo *recvMsgInfo, const CmRhbMsg *rhbMsg) static void MsgCmRhb(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msgProc) { CmRhbMsg *hbMsg = NULL; - PROCESS_MSG_BY_TYPE(CmRhbMsg, hbMsg, ProcessCmRhbMsg); + PROCESS_MSG_BY_TYPE(CmRhbMsg, hbMsg, ProcessCmRhbMsg, recvMsgInfo, msgType); } void ProcessRhbStatReq(MsgRecvInfo *recvMsgInfo, const CmShowStatReq *req) @@ -1645,13 +1665,13 @@ static void MsgShowStatus(MsgRecvInfo* recvMsgInfo, int msgType, CmdMsgProc *msg CmShowStatReq *req = NULL; switch (msgType) { case MSG_CTL_CM_RHB_STATUS_REQ: - PROCESS_MSG_BY_TYPE(CmShowStatReq, req, ProcessRhbStatReq); + PROCESS_MSG_BY_TYPE(CmShowStatReq, req, ProcessRhbStatReq, recvMsgInfo, msgType); break; case MSG_CTL_CM_NODE_DISK_STATUS_REQ: - PROCESS_MSG_BY_TYPE(CmShowStatReq, req, ProcessNodeDiskStatReq); + PROCESS_MSG_BY_TYPE(CmShowStatReq, req, ProcessNodeDiskStatReq, recvMsgInfo, msgType); break; case MSG_CTL_CM_FLOAT_IP_REQ: - PROCESS_MSG_BY_TYPE(CmShowStatReq, req, ProcessFloatIpReq); + PROCESS_MSG_BY_TYPE(CmShowStatReq, req, ProcessFloatIpReq, recvMsgInfo, msgType); break; default: write_runlog(ERROR, "[MsgShowStatus] unknown request(%d)\n", msgType); @@ -1665,7 +1685,7 @@ static void MsgGetFloatIpInfo(MsgRecvInfo *recvMsgInfo, int msgType, CmdMsgProc return; } CmaDnFloatIpInfo *floatIpInfo; - PROCESS_MSG_BY_TYPE(CmaDnFloatIpInfo, floatIpInfo, ProcessDnFloatIpMsg); + PROCESS_MSG_BY_TYPE(CmaDnFloatIpInfo, floatIpInfo, ProcessDnFloatIpMsg, recvMsgInfo, msgType); } static void MsgResIsreg(MsgRecvInfo *recvMsgInfo, int msgType, CmdMsgProc *msgProc) @@ -1674,7 +1694,17 @@ static void MsgResIsreg(MsgRecvInfo *recvMsgInfo, int msgType, CmdMsgProc *msgPr return; } CmaToCmsIsregMsg *isregMsg; - PROCESS_MSG_BY_TYPE(CmaToCmsIsregMsg, isregMsg, ProcessResIsregMsg); + PROCESS_MSG_BY_TYPE(CmaToCmsIsregMsg, isregMsg, ProcessResIsregMsg, recvMsgInfo, msgType); +} + +void MsgGetPingDnFloatIpFailedInfo(MsgRecvInfo *recvMsgInfo, int msgType, CmdMsgProc *msgProc) +{ + if (!IsNeedCheckFloatIp() || (backup_open != CLUSTER_PRIMARY)) { + return; + } + CmSendPingDnFloatIpFail *failedFloatIpInfo; + PROCESS_MSG_BY_TYPE( + CmSendPingDnFloatIpFail, failedFloatIpInfo, ProcessPingDnFloatIpFailedMsg, recvMsgInfo, msgType); } static void InitCmCtlCmdProc() @@ -1742,6 +1772,8 @@ static void InitCmAgentCmdProc() g_cmdProc[MSG_AGENT_CM_RESOURCE_STATUS] = MsgAgentResourceStatus; g_cmdProc[MSG_AGENT_CM_GET_LATEST_STATUS_LIST] = MsgLatestResStatusList; g_cmdProc[MSG_AGENT_CM_REQUEST_RES_STATUS_LIST] = MsgRequestResStatusList; + + g_cmdProc[MSG_CMA_PING_DN_FLOAT_IP_FAIL] = MsgGetPingDnFloatIpFailedInfo; } static void InitCmClientCmdProc() diff --git a/src/cm_server/cms_process_messages_agent.cpp b/src/cm_server/cms_process_messages_agent.cpp index d709eb92b1f49c5a3e2646bc1f320f79a4ea3b36..420dd3215470e70014990c0b138b5b4d39231a34 100644 --- a/src/cm_server/cms_process_messages_agent.cpp +++ b/src/cm_server/cms_process_messages_agent.cpp @@ -1309,3 +1309,60 @@ void GetFloatIpSet(CmFloatIpStatAck *ack, size_t maxMsgLen, size_t *curMsgLen) } } } + +void NotifyPrimaryDnToResetFailedFloatIp( + MsgRecvInfo *recvMsgInfo, const CmSendPingDnFloatIpFail *failedFloatIpInfo, uint32 groupIdx) +{ + int32 memIdx = -1; + if (FindAvaliableFloatIpPrimary(groupIdx, &memIdx) != CM_SUCCESS) { + return; + } + cm_instance_role_status *roleStatus = &g_instance_role_group_ptr[groupIdx].instanceMember[memIdx]; + CmSendPingDnFloatIpFail ack; + errno_t rc = memcpy_s(&(ack), sizeof(CmSendPingDnFloatIpFail), failedFloatIpInfo, sizeof(CmSendPingDnFloatIpFail)); + securec_check_errno(rc, (void)rc); + ack.baseInfo.msgType = (int32)MSG_CMS_NOTIFY_PRIMARY_DN_RESET_FLOAT_IP; + ack.baseInfo.node = roleStatus->node; + ack.baseInfo.instId = roleStatus->instanceId; + write_runlog(LOG, + "[%s] primary dn nodeId:%u, instId:%u.\n", __FUNCTION__, roleStatus->node, roleStatus->instanceId); + (void)SendToAgentMsg(roleStatus->node, 'S', (const char *)(&ack), sizeof(CmSendPingDnFloatIpFail)); +} + +void ProcessPingDnFloatIpFailedMsg(MsgRecvInfo *recvMsgInfo, CmSendPingDnFloatIpFail *failedFloatIpInfo) +{ + if (failedFloatIpInfo->failedCount > MAX_FLOAT_IP_COUNT) { + write_runlog(ERROR, + "[%s] cms get ping float ip failed count (%u) is invalid.\n", + __FUNCTION__, + failedFloatIpInfo->failedCount); + return; + } + const BaseInstInfo *baseInst = &(failedFloatIpInfo->baseInfo); + if (baseInst->instType != INSTANCE_TYPE_DATANODE) { + write_runlog(ERROR, + "[%s] cms get instance(%u) is not dn, this type is %d.\n", + __FUNCTION__, + baseInst->instId, + baseInst->instType); + return; + } + uint32 groupIdx = 0; + int32 memIdx = 0; + uint32 node = baseInst->node; + uint32 instId = baseInst->instId; + int32 ret = find_node_in_dynamic_configure(node, instId, &groupIdx, &memIdx); + if (ret != 0) { + write_runlog(LOG, + "[%s] can't find the instance(node=%u instanceId=%u).\n", __FUNCTION__, node, instId); + return; + } + write_runlog(LOG, + "[%s] cms receive pingDnFloatIpFailedMsg, and group[%u: %d], node[%u], instId[%u].\n", + __FUNCTION__, + groupIdx, + memIdx, + node, + instId); + NotifyPrimaryDnToResetFailedFloatIp(recvMsgInfo, failedFloatIpInfo, groupIdx); +} \ No newline at end of file diff --git a/src/cm_server/cms_process_messages_clt.cpp b/src/cm_server/cms_process_messages_clt.cpp index 9384a647dffe42add908c96061b7039f877a4632..982616a12789a2267fcb016b56934fb51123f2b5 100644 --- a/src/cm_server/cms_process_messages_clt.cpp +++ b/src/cm_server/cms_process_messages_clt.cpp @@ -29,6 +29,10 @@ #include "cms_arbitrate_datanode.h" #include "cms_arbitrate_datanode_pms.h" #include "cms_az.h" +#include +#include +#include "cm_ip.h" +#include "cm_msg_version_convert.h" const int KV_POS = 2; @@ -1057,27 +1061,58 @@ void FlushCmToAgentMsg(MsgRecvInfo* recvMsgInfo, int msgType) CmToAgentMsg(recvMsgInfo, msgType); } +status_t GetAgentDataReportMsg(CM_StringInfo inBuffer, agent_to_cm_datanode_status_report *agentToCmDatanodeStatusPtr) +{ + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + const agent_to_cm_datanode_status_report_ipv4 *agent_to_cm_datanode_status_ptr_ipv4 = + (const agent_to_cm_datanode_status_report_ipv4 *)CmGetmsgbytes(inBuffer, + sizeof(agent_to_cm_datanode_status_report_ipv4)); + if (agent_to_cm_datanode_status_ptr_ipv4 == NULL) { + write_runlog(ERROR, "MSG_AGENT_CM_DATA_INSTANCE_REPORT_STATUS is null. inBuffer->qtype: %d \n", + inBuffer->qtype); + return CM_ERROR; + } + AgentToCmDatanodeStatusReportV1ToV2(agent_to_cm_datanode_status_ptr_ipv4, agentToCmDatanodeStatusPtr); + } else { + const agent_to_cm_datanode_status_report *agent_to_cm_datanode_status_ptr = + (const agent_to_cm_datanode_status_report *)CmGetmsgbytes(inBuffer, + sizeof(agent_to_cm_datanode_status_report)); + if (agent_to_cm_datanode_status_ptr == NULL) { + write_runlog(ERROR, + "MSG_AGENT_CM_DATA_INSTANCE_REPORT_STATUS is null. inBuffer->qtype: %d \n", inBuffer->qtype); + return CM_ERROR; + } + errno_t rc = memcpy_s(agentToCmDatanodeStatusPtr, + sizeof(agent_to_cm_datanode_status_report), + agent_to_cm_datanode_status_ptr, + sizeof(agent_to_cm_datanode_status_report)); + securec_check_errno(rc, (void)rc); + } + return CM_SUCCESS; +} + void SetAgentDataReportMsg(MsgRecvInfo* recvMsgInfo, CM_StringInfo inBuffer) { - const agent_to_cm_datanode_status_report *agent_to_cm_datanode_status_ptr = - (const agent_to_cm_datanode_status_report *)CmGetmsgbytes(inBuffer, sizeof(agent_to_cm_datanode_status_report)); - if (agent_to_cm_datanode_status_ptr == NULL) { - write_runlog( - ERROR, "MSG_AGENT_CM_DATA_INSTANCE_REPORT_STATUS is null. inBuffer->qtype: %d \n", inBuffer->qtype); + agent_to_cm_datanode_status_report agent_to_cm_datanode_status_ptr = {0}; + if (GetAgentDataReportMsg(inBuffer, &agent_to_cm_datanode_status_ptr) != CM_SUCCESS) { return; } + + agent_to_cm_datanode_status_ptr.local_status.disconn_host[CM_IP_LENGTH - 1] = '\0'; + agent_to_cm_datanode_status_ptr.local_status.local_host[CM_IP_LENGTH - 1] = '\0'; + if (!g_inReload) { - if (agent_to_cm_datanode_status_ptr->instanceType != INSTANCE_TYPE_DATANODE) { + if (agent_to_cm_datanode_status_ptr.instanceType != INSTANCE_TYPE_DATANODE) { write_runlog(ERROR, "Instance type %d not equal INSTANCE_TYPE_DATANODE(%d) ! Maybe the msg_type send by remote " "cm_agent not match with local cm_server." "Check whether the version of cm_agent and cm_server on node %u is the same as localhost. " "msg_type=%d, node=%u, instanceId=%u, instanceType=%d, connectStatus=%d, processStatus=%d \n", - agent_to_cm_datanode_status_ptr->instanceType, - INSTANCE_TYPE_DATANODE, agent_to_cm_datanode_status_ptr->node, - agent_to_cm_datanode_status_ptr->msg_type, agent_to_cm_datanode_status_ptr->node, - agent_to_cm_datanode_status_ptr->instanceId, agent_to_cm_datanode_status_ptr->instanceType, - agent_to_cm_datanode_status_ptr->connectStatus, agent_to_cm_datanode_status_ptr->processStatus); + agent_to_cm_datanode_status_ptr.instanceType, + INSTANCE_TYPE_DATANODE, agent_to_cm_datanode_status_ptr.node, + agent_to_cm_datanode_status_ptr.msg_type, agent_to_cm_datanode_status_ptr.node, + agent_to_cm_datanode_status_ptr.instanceId, agent_to_cm_datanode_status_ptr.instanceType, + agent_to_cm_datanode_status_ptr.connectStatus, agent_to_cm_datanode_status_ptr.processStatus); return; } g_loopState.execStatus[0] = 0; @@ -1085,12 +1120,12 @@ void SetAgentDataReportMsg(MsgRecvInfo* recvMsgInfo, CM_StringInfo inBuffer) struct timeval checkEnd = {0, 0}; (void)gettimeofday(&checkBegin, NULL); if (g_single_node_cluster) { - datanode_instance_arbitrate_single(recvMsgInfo, agent_to_cm_datanode_status_ptr); + datanode_instance_arbitrate_single(recvMsgInfo, &agent_to_cm_datanode_status_ptr); } else if (g_multi_az_cluster) { - DatanodeInstanceArbitrate(recvMsgInfo, agent_to_cm_datanode_status_ptr); + DatanodeInstanceArbitrate(recvMsgInfo, &agent_to_cm_datanode_status_ptr); } else { /* datanode instances arbitrate for primary-standby-dummy cluster */ - datanode_instance_arbitrate_for_psd(recvMsgInfo, agent_to_cm_datanode_status_ptr); + datanode_instance_arbitrate_for_psd(recvMsgInfo, &agent_to_cm_datanode_status_ptr); } (void)gettimeofday(&checkEnd, NULL); @@ -1216,15 +1251,15 @@ static status_t SendMaintainFileToAllCms(const char *maintainFile) if (g_node[g_nodeIndexForCmServer[i]].node == g_currentNode->node) { continue; } - ret = snprintf_s(cmd, - CM_PATH_LENGTH, - CM_PATH_LENGTH - 1, - "scp %s %s@%s:%s", - maintainFile, - pw->pw_name, - g_node[g_nodeIndexForCmServer[i]].sshChannel[0], - maintainFile); - securec_check_intval(ret, (void)ret); + if (GetIpVersion(g_node[g_nodeIndexForCmServer[i]].sshChannel[0]) == AF_INET6) { + ret = snprintf_s(cmd, CM_PATH_LENGTH, CM_PATH_LENGTH - 1, "scp %s %s@[%s]:%s", maintainFile, pw->pw_name, + g_node[g_nodeIndexForCmServer[i]].sshChannel[0], maintainFile); + securec_check_intval(ret, (void)ret); + } else { + ret = snprintf_s(cmd, CM_PATH_LENGTH, CM_PATH_LENGTH - 1, "scp %s %s@%s:%s", maintainFile, pw->pw_name, + g_node[g_nodeIndexForCmServer[i]].sshChannel[0], maintainFile); + securec_check_intval(ret, (void)ret); + } ret = system(cmd); if (ret != -1 && WEXITSTATUS(ret) == 0) { write_runlog(LOG, "[switch] exec cmd(%s) success\n", cmd); @@ -1438,15 +1473,15 @@ static status_t GetMaintainFromOtherCms(const char *kvFile) } ret = memset_s(cmd, sizeof(cmd), 0, sizeof(cmd)); securec_check_errno(ret, (void)ret); - ret = snprintf_s(cmd, - CM_PATH_LENGTH, - CM_PATH_LENGTH - 1, - "scp %s@%s:%s %s > /dev/null 2>&1", - pw->pw_name, - g_node[index].sshChannel[0], - kvFile, - kvFile); - securec_check_intval(ret, (void)ret); + if (GetIpVersion(g_node[index].sshChannel[0]) == AF_INET6) { + ret = snprintf_s(cmd, CM_PATH_LENGTH, CM_PATH_LENGTH - 1, "scp %s@[%s]:%s %s > /dev/null 2>&1", + pw->pw_name, g_node[index].sshChannel[0], kvFile, kvFile); + securec_check_intval(ret, (void)ret); + } else { + ret = snprintf_s(cmd, CM_PATH_LENGTH, CM_PATH_LENGTH - 1, "scp %s@%s:%s %s > /dev/null 2>&1", + pw->pw_name, g_node[index].sshChannel[0], kvFile, kvFile); + securec_check_intval(ret, (void)ret); + } ret = system(cmd); if (ret != -1 && WEXITSTATUS(ret) == 0) { write_runlog(LOG, "[switch] exec cmd(%s) success.\n", cmd); diff --git a/src/cm_server/cms_process_messages_ctl.cpp b/src/cm_server/cms_process_messages_ctl.cpp index 1405cd7afc2d240c9b7ccb2b4c0fd581d1b59ee5..3eae9dae67c19af462b5ccd8f606e31dcc1bd8ee 100644 --- a/src/cm_server/cms_process_messages_ctl.cpp +++ b/src/cm_server/cms_process_messages_ctl.cpp @@ -26,7 +26,8 @@ #include "cms_disk_check.h" #include "cms_ddb_adapter.h" #include "cms_common.h" - +#include "cm_ip.h" +#include "cm_msg_version_convert.h" /** * @brief @@ -213,12 +214,28 @@ static status_t ExeScpCommand(uint32 index) int ret; errno_t rc; char command[MAX_PATH_LEN] = { 0 }; - for (uint32 i = 0; i < g_node[index].sshCount; ++i) { - rc = snprintf_s(command, MAX_PATH_LEN, MAX_PATH_LEN - 1, "scp -r %s/gstor/data %s@%s:%s/gstor", - g_currentNode->cmDataPath, pw->pw_name, g_node[index].sshChannel[i], g_node[index].cmDataPath); - securec_check_intval(rc, (void)rc); - + if (GetIpVersion(g_node[index].sshChannel[i]) == AF_INET6) { + rc = snprintf_s(command, + MAX_PATH_LEN, + MAX_PATH_LEN - 1, + "scp -r %s/gstor/data %s@[%s]:%s/gstor", + g_currentNode->cmDataPath, + pw->pw_name, + g_node[index].sshChannel[i], + g_node[index].cmDataPath); + securec_check_intval(rc, (void)rc); + } else { + rc = snprintf_s(command, + MAX_PATH_LEN, + MAX_PATH_LEN - 1, + "scp -r %s/gstor/data %s@%s:%s/gstor", + g_currentNode->cmDataPath, + pw->pw_name, + g_node[index].sshChannel[i], + g_node[index].cmDataPath); + securec_check_intval(rc, (void)rc); + } ret = system(command); if (ret != -1 && WEXITSTATUS(ret) == 0) { write_runlog(LOG, "exec cmd(%s) success\n", command); @@ -1287,6 +1304,7 @@ static void FillCm2CtlRsp4DnGroup(uint32 ii, uint32 jj, cm_to_ctl_instance_statu static status_t FillCm2CtlRsp4InstGroup(MsgRecvInfo* recvMsgInfo, const ctl_to_cm_query *ctlToCmQry, uint32 ii, int type, uint32 group_index, cm_to_ctl_instance_status *cmToCtlStatusContent) { + cm_to_ctl_instance_status_ipv4 cmToCtlStatusContentIpv4 = {0}; for (int jj = 0; jj < g_instance_role_group_ptr[ii].count; jj++) { if (g_instance_role_group_ptr[ii].instanceMember[jj].instanceType != type) { break; @@ -1316,15 +1334,22 @@ static status_t FillCm2CtlRsp4InstGroup(MsgRecvInfo* recvMsgInfo, const ctl_to_c write_runlog(DEBUG5, "send the instance query result (node =%u instanceid =%u)\n", g_instance_role_group_ptr[ii].instanceMember[jj].node, g_instance_role_group_ptr[ii].instanceMember[jj].instanceId); - (void)RespondMsg( - recvMsgInfo, 'S', (char *)cmToCtlStatusContent, sizeof(cm_to_ctl_instance_status)); // XXXX:DEBUG5 + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + CmToCtlInstanceStatusV2ToV1(cmToCtlStatusContent, &cmToCtlStatusContentIpv4); + (void)RespondMsg( + recvMsgInfo, 'S', (char *)&(cmToCtlStatusContentIpv4), sizeof(cm_to_ctl_instance_status_ipv4)); + } else { + (void)RespondMsg( + recvMsgInfo, 'S', (char *)cmToCtlStatusContent, sizeof(cm_to_ctl_instance_status)); + } } return CM_SUCCESS; } static void ProcessCtlToCmOneTypeQryMsg(MsgRecvInfo* recvMsgInfo, const ctl_to_cm_query *ctlToCmQry, int type) { - cm_to_ctl_instance_status cmToCtlStatusContent; + cm_to_ctl_instance_status cmToCtlStatusContent = {0}; + cm_to_ctl_instance_status_ipv4 cmToCtlStatusContentIpv4 = {0}; uint32 ii; int jj; uint32 group_index = 0; @@ -1377,6 +1402,12 @@ static void ProcessCtlToCmOneTypeQryMsg(MsgRecvInfo* recvMsgInfo, const ctl_to_c cmToCtlStatusContent.msg_type = MSG_CM_CTL_NODE_END; cmToCtlStatusContent.instance_type = type; + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + CmToCtlInstanceStatusV2ToV1(&cmToCtlStatusContent, &cmToCtlStatusContentIpv4); + (void)RespondMsg( + recvMsgInfo, 'S', (char *)&(cmToCtlStatusContentIpv4), sizeof(cm_to_ctl_instance_status_ipv4), DEBUG5); + return; + } (void)RespondMsg(recvMsgInfo, 'S', (char *)&(cmToCtlStatusContent), sizeof(cm_to_ctl_instance_status), DEBUG5); } @@ -1393,7 +1424,7 @@ static void ProcessCtlToCmOneInstanceQueryMsg( { uint32 groupIndex = 0; int memberIndex = 0; - cm_to_ctl_instance_status statusMsg; + cm_to_ctl_instance_status statusMsg = {0}; errno_t rc; if (find_node_in_dynamic_configure(node, instanceId, &groupIndex, &memberIndex) != 0) { @@ -1485,8 +1516,13 @@ static void ProcessCtlToCmOneInstanceQueryMsg( } write_runlog(DEBUG5, "send the instance query result (node=%u, instanceId=%u)\n", node, instanceId); - (void)RespondMsg(recvMsgInfo, 'S', (char *)(&statusMsg), sizeof(statusMsg)); // XXXX:DEBUG5 - + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + cm_to_ctl_instance_status_ipv4 statusIpv4 = {0}; + CmToCtlInstanceStatusV2ToV1(&statusMsg, &statusIpv4); + (void)RespondMsg(recvMsgInfo, 'S', (char *)(&statusIpv4), sizeof(statusIpv4)); // XXXX:DEBUG5 + } else { + (void)RespondMsg(recvMsgInfo, 'S', (char *)(&statusMsg), sizeof(statusMsg)); // XXXX:DEBUG5 + } return; } @@ -1803,7 +1839,13 @@ static void HdlCtlToCmStartStatQry(MsgRecvInfo* recvMsgInfo, const ctl_to_cm_que } /* Send CN status information in end message. */ instStat->msg_type = MSG_CM_CTL_DATA_END; - (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + cm_to_ctl_instance_status_ipv4 instStatIpv4 = {0}; + CmToCtlInstanceStatusV2ToV1(instStat, &instStatIpv4); + (void)RespondMsg(recvMsgInfo, 'S', (char *)(&instStatIpv4), sizeof(cm_to_ctl_instance_status_ipv4)); + } else { + (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); + } } static void HdlCtlToCmLogicCpleDetStatQry(MsgRecvInfo* recvMsgInfo, cm_to_ctl_instance_status *instStat, @@ -1932,15 +1974,89 @@ static void HdlCtlToCmNonBalOrLgcCpleDetStatQry(MsgRecvInfo* recvMsgInfo, const (void)RespondMsg(recvMsgInfo, 'S', (char *)clusterStat, sizeof(cm_to_ctl_cluster_status)); if (clusterStat->inReloading) { instStat->msg_type = MSG_CM_CTL_DATA_END; - (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + cm_to_ctl_instance_status_ipv4 instStatIpv4 = {0}; + CmToCtlInstanceStatusV2ToV1(instStat, &instStatIpv4); + (void)RespondMsg(recvMsgInfo, 'S', (char *)(&instStatIpv4), sizeof(cm_to_ctl_instance_status_ipv4)); + } else { + (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); + } *isQryDone = true; return; } } -static status_t HdlCtlToCmClusDetStatQry(MsgRecvInfo* recvMsgInfo, const ctl_to_cm_query *ctlToCmQry, +status_t HdlCtlToCmClusDetstatQryForRelation(MsgRecvInfo* recvMsgInfo, const ctl_to_cm_query *ctlToCmQry, + cm_to_ctl_instance_status *instStat, cm_to_ctl_instance_status_ipv4 *instStatIpv4) +{ + uint32 group_index_in = 0; + uint32 group_index = 0; + int member_index = 0; + int ret = find_node_in_dynamic_configure( + ctlToCmQry->node, + ctlToCmQry->instanceId, + &group_index_in, + &member_index); + if (ret != 0) { + write_runlog(LOG, "can't find the instance(nodeId=%u, instanceId=%u)\n", ctlToCmQry->node, + ctlToCmQry->instanceId); + return CM_ERROR; + } + for (uint32 i = 0; i < g_node_num; i++) { + bool find = false; + ret = find_node_in_dynamic_configure(ctlToCmQry->node, + ctlToCmQry->instanceId, + &group_index, + &member_index); + if (ret != 0) { + write_runlog(LOG, "can't find the instance(nodeId=%u, instanceId=%u)\n", ctlToCmQry->node, + ctlToCmQry->instanceId); + return CM_ERROR; + } + uint32 node_id = g_node[i].node; + for (uint32 j = 0; j < g_node[i].datanodeCount; j++) { + uint32 datanode_id = g_node[i].datanode[j].datanodeId; + ret = find_node_in_dynamic_configure(node_id, datanode_id, &group_index, &member_index); + if (ret != 0) { + write_runlog(LOG, "can't find the instance(nodeId=%u, instanceId=%u)\n", node_id, datanode_id); + return CM_ERROR; + } + if (group_index == group_index_in) { + ProcessCtlToCmOneInstanceQueryMsg(recvMsgInfo, node_id, datanode_id, INSTANCE_TYPE_DATANODE); + find = true; + break; + } + } + if (!find) { + continue; + } + instStat->msg_type = MSG_CM_CTL_DATA; + instStat->node = node_id; + instStat->instanceId = 0; + instStat->instance_type = INSTANCE_TYPE_FENCED_UDF; + instStat->member_index = 0; + instStat->is_central = 0; + instStat->fenced_UDF_status = g_fenced_UDF_report_status_ptr[i].status; + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + CmToCtlInstanceStatusV2ToV1(instStat, instStatIpv4); + (void)RespondMsg(recvMsgInfo, 'S', (char *)instStatIpv4, sizeof(cm_to_ctl_instance_status_ipv4)); + + instStatIpv4->msg_type = MSG_CM_CTL_NODE_END; + (void)RespondMsg(recvMsgInfo, 'S', (char *)instStatIpv4, sizeof(cm_to_ctl_instance_status_ipv4)); + } else { + (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); // XXXX:DEBUG5 + + instStat->msg_type = MSG_CM_CTL_NODE_END; + (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); // XXXX:DEBUG5 + } + } + return CM_SUCCESS; +} + +status_t HdlCtlToCmClusDetStatQry(MsgRecvInfo* recvMsgInfo, const ctl_to_cm_query *ctlToCmQry, cm_to_ctl_instance_status *instStat) { + cm_to_ctl_instance_status_ipv4 instStatIpv4 = {0}; for (uint32 i = 0; i < g_node_num && ctlToCmQry->relation == 0; i++) { if ((ctlToCmQry->node != 0) && (ctlToCmQry->node != INVALID_NODE_NUM) && (ctlToCmQry->node != (i + 1))) { continue; @@ -1968,59 +2084,26 @@ static status_t HdlCtlToCmClusDetStatQry(MsgRecvInfo* recvMsgInfo, const ctl_to_ instStat->member_index = 0; instStat->is_central = 0; instStat->fenced_UDF_status = g_fenced_UDF_report_status_ptr[i].status; - (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); // XXXX:DEBUG5 - } - instStat->msg_type = MSG_CM_CTL_NODE_END; - (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); // XXXX:DEBUG5 - } - - if (ctlToCmQry->relation == 1) { - uint32 group_index_in = 0; - uint32 group_index = 0; - int member_index = 0; - int ret = find_node_in_dynamic_configure(ctlToCmQry->node, ctlToCmQry->instanceId, - &group_index_in, &member_index); - if (ret != 0) { - write_runlog(LOG, "can't find the instance(nodeId=%u, instanceId=%u)\n", ctlToCmQry->node, - ctlToCmQry->instanceId); - return CM_ERROR; - } - for (uint32 i = 0; i < g_node_num; i++) { - bool find = false; - ret = find_node_in_dynamic_configure(ctlToCmQry->node, ctlToCmQry->instanceId, &group_index, &member_index); - for (uint32 j = 0; j < g_node[i].datanodeCount; j++) { - ret = find_node_in_dynamic_configure( - g_node[i].node, g_node[i].datanode[j].datanodeId, &group_index, &member_index); - if (ret != 0) { - write_runlog(LOG, "can't find the instance(nodeId=%u, instanceId=%u)\n", g_node[i].node, - g_node[i].datanode[j].datanodeId); - return CM_ERROR; - } - if (group_index != group_index_in) { - continue; - } - ProcessCtlToCmOneInstanceQueryMsg(recvMsgInfo, g_node[i].node, g_node[i].datanode[j].datanodeId, - INSTANCE_TYPE_DATANODE); - find = true; - break; - } - if (!find) { - continue; + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + CmToCtlInstanceStatusV2ToV1(instStat, &instStatIpv4); + (void)RespondMsg(recvMsgInfo, 'S', (char *)(&instStatIpv4), sizeof(cm_to_ctl_instance_status_ipv4)); + } else { + (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); // XXXX:DEBUG5 } - instStat->msg_type = MSG_CM_CTL_DATA; - instStat->node = g_node[i].node; - instStat->instanceId = 0; - instStat->instance_type = INSTANCE_TYPE_FENCED_UDF; - instStat->member_index = 0; - instStat->is_central = 0; - instStat->fenced_UDF_status = g_fenced_UDF_report_status_ptr[i].status; - (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); // XXXX:DEBUG5 + } + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + instStatIpv4.msg_type = MSG_CM_CTL_NODE_END; + (void)RespondMsg(recvMsgInfo, 'S', (char *)(&instStatIpv4), sizeof(cm_to_ctl_instance_status_ipv4)); + } else { instStat->msg_type = MSG_CM_CTL_NODE_END; (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); // XXXX:DEBUG5 } } + if (ctlToCmQry->relation == 1) { + return HdlCtlToCmClusDetstatQryForRelation(recvMsgInfo, ctlToCmQry, instStat, &instStatIpv4); + } return CM_SUCCESS; } @@ -2038,7 +2121,13 @@ static void HdlCtlToCmClusRestStatQry(MsgRecvInfo* recvMsgInfo, const ctl_to_cm_ instStat->member_index = 0; instStat->is_central = 0; instStat->fenced_UDF_status = g_fenced_UDF_report_status_ptr[i].status; - (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); // XXXX:DEBUG5 + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + cm_to_ctl_instance_status_ipv4 instStatIpv4 = {0}; + CmToCtlInstanceStatusV2ToV1(instStat, &instStatIpv4); + (void)RespondMsg(recvMsgInfo, 'S', (char *)(&instStatIpv4), sizeof(cm_to_ctl_instance_status_ipv4)); + } else { + (void)RespondMsg(recvMsgInfo, 'S', (char *)instStat, sizeof(cm_to_ctl_instance_status)); + } } } @@ -2050,7 +2139,7 @@ static void HdlCtlToCmClusRestStatQry(MsgRecvInfo* recvMsgInfo, const ctl_to_cm_ */ void ProcessCtlToCmQueryMsg(MsgRecvInfo* recvMsgInfo, const ctl_to_cm_query *ctlToCmQry) { - cm_to_ctl_instance_status instStat; + cm_to_ctl_instance_status instStat = {0}; cm_to_ctl_cluster_status clusterStat; bool isQryDone = false; @@ -2097,7 +2186,13 @@ void ProcessCtlToCmQueryMsg(MsgRecvInfo* recvMsgInfo, const ctl_to_cm_query *ctl } instStat.msg_type = MSG_CM_CTL_DATA_END; - (void)RespondMsg(recvMsgInfo, 'S', (char*)&(instStat), sizeof(cm_to_ctl_instance_status)); + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + cm_to_ctl_instance_status_ipv4 instStatIpv4 = {0}; + CmToCtlInstanceStatusV2ToV1(&instStat, &instStatIpv4); + (void)RespondMsg(recvMsgInfo, 'S', (char *)(&instStatIpv4), sizeof(cm_to_ctl_instance_status_ipv4)); + } else { + (void)RespondMsg(recvMsgInfo, 'S', (char *)&(instStat), sizeof(cm_to_ctl_instance_status)); + } return; } @@ -2283,7 +2378,7 @@ void process_ctl_to_cm_get_datanode_relation_msg( int member_index = 0; int instanceType; int ret; - cm_to_ctl_get_datanode_relation_ack ack; + cm_to_ctl_get_datanode_relation_ack ack = {0}; ret = find_node_in_dynamic_configure(info_ptr->node, info_ptr->instanceId, &group_index, &member_index); @@ -2340,7 +2435,13 @@ void process_ctl_to_cm_get_datanode_relation_msg( g_instance_group_report_status_ptr[group_index].instance_status.gtm_member[i]; } - (void)RespondMsg(recvMsgInfo, 'S', (char *)(&ack), sizeof(ack)); + if (undocumentedVersion != 0 && undocumentedVersion < SUPPORT_IPV6_VERSION) { + cm_to_ctl_get_datanode_relation_ack_ipv4 ackIpv4; + CmToCtlGetDatanodeRelationAckV2ToV1(&ack, &ackIpv4); + (void)RespondMsg(recvMsgInfo, 'S', (char *)(&ackIpv4), sizeof(ackIpv4)); + } else { + (void)RespondMsg(recvMsgInfo, 'S', (char *)(&ack), sizeof(ack)); + } return; } diff --git a/src/cm_server/cms_process_messages_res.cpp b/src/cm_server/cms_process_messages_res.cpp index 773a38c39a98db28fb9f6262a32aa2bce41c69b2..7705eac8f4a6fc443ad26697d03b2c379d0fdf5d 100644 --- a/src/cm_server/cms_process_messages_res.cpp +++ b/src/cm_server/cms_process_messages_res.cpp @@ -157,6 +157,16 @@ static void CleanResReportInter(const CmResourceStatus *resStat) } } +void CleanAllResStatusReportInter() +{ + write_runlog(LOG, "cms will clean res status report.\n"); + for (uint32 i = 0; i < CusResCount(); ++i) { + for (uint32 j = 0; j < g_resInstReport[i].instCount; ++j) { + g_resInstReport[i].resReport[j].statReportInter = 0; + } + } +} + static bool8 IsNodeCriticalResReportTimeout(uint32 nodeId) { for (uint32 i = 0; i < CusResCount(); ++i) { diff --git a/src/include/cm/cm_agent/cma_global_params.h b/src/include/cm/cm_agent/cma_global_params.h index 363d4e498459b64f540eb2dbfa8b8dd8a29e76a0..1eb6adfe207974f1ae573692ae0c9ee27dec6981 100644 --- a/src/include/cm/cm_agent/cma_global_params.h +++ b/src/include/cm/cm_agent/cma_global_params.h @@ -296,11 +296,15 @@ extern char g_enableMesSsl[BOOL_STR_MAX_LEN]; extern uint32 g_sslCertExpireCheckInterval; extern uint32 g_cmaRhbItvl; extern CmResConfList g_resConf[CM_MAX_RES_INST_COUNT]; +extern IpType g_ipType; bool &GetIsSharedStorageMode(); #define FENCE_TIMEOUT (agent_connect_retries * (agent_connect_timeout + agent_report_interval)) +bool GetEnvSupportIpV6(); +void SetEnvSupportIpV6(bool val); + #ifdef __aarch64__ extern uint32 agent_process_cpu_affinity; extern uint32 g_datanode_primary_and_standby_num; diff --git a/src/include/cm/cm_agent/cma_network_check.h b/src/include/cm/cm_agent/cma_network_check.h index fa75dfe5c7d8cf39f76663de1cc25448ebbb09bd..88f713c53ee402c10de58e2841894e68fee98b7b 100644 --- a/src/include/cm/cm_agent/cma_network_check.h +++ b/src/include/cm/cm_agent/cma_network_check.h @@ -65,5 +65,7 @@ NetworkOper GetFloatIpOper(uint32 dnIdx); DnFloatIp *GetDnFloatIpByDnIdx(uint32 dnIdx); const char *GetOperMapString(NetworkOper oper); bool8 CheckNetworkStatusByIps(const char (*ips)[CM_IP_LENGTH], uint32 cnt); +void SetNeedResetFloatIp(const CmSendPingDnFloatIpFail *recvMsg, uint32 dnIdx); +bool CheckSupportIpV6(); #endif diff --git a/src/include/cm/cm_ctl/ctl_query_base.h b/src/include/cm/cm_ctl/ctl_query_base.h index 568180fd0530746494ca17d5bc005e8445395fb0..8cf4e6cab3334f0322bedc3b292ba039f353559e 100644 --- a/src/include/cm/cm_ctl/ctl_query_base.h +++ b/src/include/cm/cm_ctl/ctl_query_base.h @@ -28,7 +28,8 @@ #define ELASTICGROUP "elastic_group" #define DELAY_THRESHOLD (8 * 1024 * 1014) -#define MAX_IP_LEN (15) +#define MAX_IPV4_LEN (15) +#define MAX_IPV6_LEN (45) #define INSTANCE_ID_LEN (4) #define INSTANCE_DYNAMIC_ROLE_LEN (7) #define ETCD_DYNAMIC_ROLE_LEN (13) @@ -57,6 +58,8 @@ int ProcessDataBeginMsg(const char *receiveMsg, bool *recDataEnd); void DoProcessNodeEndMsg(const char *receiveMsg); status_t SetCmQueryContent(ctl_to_cm_query *cmQueryContent); - +uint32 GetDnIpMaxLen(); +uint32 GetCnIpMaxLen(); +uint32 GetGtmIpMaxLen(); #endif diff --git a/src/include/cm/cm_ip.h b/src/include/cm/cm_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..4ab21dba508cccd69764b8fc44410449e151db38 --- /dev/null +++ b/src/include/cm/cm_ip.h @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2024 Huawei Technologies Co.,Ltd. +* +* CM is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* +* http://license.coscl.org.cn/MulanPSL2 +* +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +* ------------------------------------------------------------------------- +* +* cm_ip.h +* +* +* IDENTIFICATION +* include/cm/cm_ip.h +* +* ------------------------------------------------------------------------- +*/ + +#ifndef CM_IP_H +#define CM_IP_H + +#include +#include "cm_ssl_base.h" +#include "cm_msg_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CM_IP_LENGTH +#define CM_IP_LENGTH 128 +#endif + +#define SOCKADDR(sa) ((struct sockaddr *)&(sa)->addr) +#define SOCKADDR_IN4(sa) ((struct sockaddr_in *)&(sa)->addr) +#define SOCKADDR_IN6(sa) ((struct sockaddr_in6 *)&(sa)->addr) +#define SOCKADDR_FAMILY(sa) (SOCKADDR(sa)->sa_family) +#define SOCKADDR_PORT(sa) (SOCKADDR_FAMILY(sa) == AF_INET ? SOCKADDR_IN4(sa)->sin_port : \ +SOCKADDR_IN6(sa)->sin6_port) + +#define PING_SUCCESS ((const char *)"success") +#define PING_FAIL ((const char *)"fail") +#define PING_UNKNOWN ((const char *)"unknown") + +int32 GetIpVersion(const char *ipstr); +char *GetPingStr(int32 family); +bool CheckIpValid(const char *ip); +bool IsEqualIp(const char *clientIp, const char *localIp); +bool8 IsLocalHostIp(const char *ip); +bool ChangeIpV6ToOsFormat(const char *sourceIp, char *destIp, uint32 destSize); +status_t NeedAndRemoveSquareBracketsForIpV6(const char *sourceIp, char *destIp, uint32 size); +ProcessStatus CheckPeerIp(const char *peerIp, const char *str, const char *localIp, int32 tryTimes, int32 family); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/src/include/cm/cm_json_parse_floatIp.h b/src/include/cm/cm_json_parse_floatIp.h index 845405be44416a7faf0ebaca8077f83aa45a20cd..2bafe4d3120418d4f74e751d9cbda6fddae35da5 100644 --- a/src/include/cm/cm_json_parse_floatIp.h +++ b/src/include/cm/cm_json_parse_floatIp.h @@ -29,6 +29,7 @@ #include "cm_misc_res.h" typedef struct DnFloatIpT { + pthread_rwlock_t rwlock; uint32 instId; const char *dataPath; // float ip and manage ip @@ -37,6 +38,8 @@ typedef struct DnFloatIpT { char dnFloatIp[MAX_FLOAT_IP_COUNT][CM_IP_LENGTH]; char floatIpName[MAX_FLOAT_IP_COUNT][CM_MAX_RES_NAME]; uint32 dnFloatIpPort; + uint32 needResetFloatIpCnt; + char needResetFloatIp[MAX_FLOAT_IP_COUNT][CM_IP_LENGTH]; } DnFloatIp; typedef bool8 (*findNodeInfoByNodeIdx)(uint32 instId, uint32 *nodeIdx, uint32 *dnIdx, const char *str); diff --git a/src/include/cm/cm_misc_res.h b/src/include/cm/cm_misc_res.h index 1119204cb68bceeec05c6b234f04f7d57dd3189c..6119472559ab892be6ed8aa444812e62a63e9b0b 100644 --- a/src/include/cm/cm_misc_res.h +++ b/src/include/cm/cm_misc_res.h @@ -63,6 +63,15 @@ const uint32 CM_MAX_VIP_COUNT = 16; #define CM_DOMAIN_SOCKET "agent.socket" +typedef enum IpTypeEn { + IP_TYPE_INIT = 0, + IP_TYPE_UNKNOWN = 1, + IP_TYPE_IPV4, + IP_TYPE_IPV6, + IP_TYPE_NEITHER, + IP_TYPE_CEIL, +} IpType; + typedef enum { CM_RES_ISREG_INIT = 0, CM_RES_ISREG_REG = 1, @@ -111,7 +120,6 @@ bool IsOneResInstWork(const char *resName, uint32 cmInstId); bool IsReadConfJsonSuccess(int ret); const char *ReadConfJsonFailStr(int ret); status_t GetResNameByCmInstId(uint32 instId, char *resName, uint32 nameLen); -uint8 CheckIpValid(const char *ip); uint32 CusResCount(); bool IsCusResExist(); const char *GetIsregStatus(int isreg); diff --git a/src/include/cm/cm_msg.h b/src/include/cm/cm_msg.h index 56446c1b19fabdde5854bfd9f0ffa8917a453600..7b861cca80e90e51521109a8dde5dc8edf8e8150 100644 --- a/src/include/cm/cm_msg.h +++ b/src/include/cm/cm_msg.h @@ -269,8 +269,10 @@ typedef enum CM_MessageType_st { MSG_CTL_CM_FLOAT_IP_ACK = 182, MSG_CM_AGENT_MODIFY_MOST_AVAILABLE = 183, MSG_AGENT_CM_DN_MOST_AVAILABLE = 184, - MSG_CTL_CM_QUERY_DN_INFO = 185, - MSG_CTL_CM_QUERY_DN_ACK = 186, + MSG_CMA_PING_DN_FLOAT_IP_FAIL = 185, + MSG_CMS_NOTIFY_PRIMARY_DN_RESET_FLOAT_IP = 186, + MSG_CTL_CM_QUERY_DN_INFO = 187, + MSG_CTL_CM_QUERY_DN_ACK = 188, MSG_CM_TYPE_CEIL, // new message types should be added before this. } CM_MessageType; @@ -714,7 +716,7 @@ typedef struct cm_to_agent_lock2_st { int msg_type; uint32 node; uint32 instanceId; - char disconn_host[HOST_LENGTH]; + char disconn_host[CM_IP_LENGTH]; uint32 disconn_port; } cm_to_agent_lock2; @@ -1059,9 +1061,9 @@ typedef struct cm_local_replconninfo_st { int buildReason; uint32 term; uint32 disconn_mode; - char disconn_host[HOST_LENGTH]; + char disconn_host[CM_IP_LENGTH]; uint32 disconn_port; - char local_host[HOST_LENGTH]; + char local_host[CM_IP_LENGTH]; uint32 local_port; bool redo_finished; bool realtime_build_status; @@ -2229,6 +2231,12 @@ typedef struct CmFloatIpStatInfoT { int32 nicNetState[MAX_FLOAT_IP_COUNT]; } CmFloatIpStatInfo; +typedef struct CmSendPingDnFloatIpFailSt { + BaseInstInfo baseInfo; + uint32 failedCount; + char failedDnFloatIp[MAX_FLOAT_IP_COUNT][CM_IP_LENGTH]; +} CmSendPingDnFloatIpFail; + typedef struct CmFloatIpStatAckT { int32 msgType; bool8 canShow; diff --git a/src/include/cm/cm_msg_common.h b/src/include/cm/cm_msg_common.h index d275397e65bbdb6a8a2d7ae1263ae2e1af869cf2..a46b32ded87af9598af9dfd86a90bd3b149da432 100644 --- a/src/include/cm/cm_msg_common.h +++ b/src/include/cm/cm_msg_common.h @@ -39,4 +39,12 @@ typedef enum NetworkStateE { NETWORK_STATE_CEIL // it must be end } NetworkState; +typedef enum ProcessStatusE { + PROCESS_STATUS_INIT = 0, + PROCESS_STATUS_UNKNOWN, + PROCESS_STATUS_SUCCESS, + PROCESS_STATUS_FAIL, + PROCESS_STATUS_CEIL // it must be end +} ProcessStatus; + #endif diff --git a/src/include/cm/cm_msg_ipv4.h b/src/include/cm/cm_msg_ipv4.h new file mode 100644 index 0000000000000000000000000000000000000000..0c3d7fbfd7985e35e34c96195c145ae29158d50a --- /dev/null +++ b/src/include/cm/cm_msg_ipv4.h @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2024 Huawei Technologies Co.,Ltd. + * + * CM is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * ------------------------------------------------------------------------- + * + * cm_msg_ipv4.h + * + * + * IDENTIFICATION + * include/cm/cm_msg_ipv4.h + * + * ------------------------------------------------------------------------- + */ +#ifndef CM_MSG_IPV4_H +#define CM_MSG_IPV4_H + +#include "cm_msg.h" + +typedef struct cm_to_agent_lock2_ipv4_st { + int msg_type; + uint32 node; + uint32 instanceId; + char disconn_host[HOST_LENGTH]; + uint32 disconn_port; +} cm_to_agent_lock2_ipv4; + +typedef struct cm_local_replconninfo_ipv4_st { + int local_role; + int static_connections; + int db_state; + XLogRecPtr last_flush_lsn; + int buildReason; + uint32 term; + uint32 disconn_mode; + char disconn_host[HOST_LENGTH]; + uint32 disconn_port; + char local_host[HOST_LENGTH]; + uint32 local_port; + bool redo_finished; +} cm_local_replconninfo_ipv4; + +typedef struct agent_to_cm_datanode_status_report_ipv4_st { + int msg_type; + uint32 node; + uint32 instanceId; + int instanceType; + int connectStatus; + int processStatus; + cm_local_replconninfo_ipv4 local_status; + BuildState build_info; + cm_sender_replconninfo sender_status[CM_MAX_SENDER_NUM]; + cm_receiver_replconninfo receive_status; + RedoStatsData parallel_redo_status; + cm_redo_stats local_redo_stats; + int dn_restart_counts; + int phony_dead_times; + int dn_restart_counts_in_hour; + int dnVipStatus; +} agent_to_cm_datanode_status_report_ipv4; + +typedef struct DnStatus_ipv4_t { + CM_MessageType barrierMsgType; + agent_to_cm_datanode_status_report_ipv4 reportMsg; + union { + AgentToCmBarrierStatusReport barrierMsg; + Agent2CmBarrierStatusReport barrierMsgNew; + }; + AgentCmDnLocalPeer lpInfo; + AgentToCmDiskUsageStatusReport diskUsageMsg; + CmaDnFloatIpInfo floatIpInfo; +} DnStatus_ipv4; + +typedef struct datanode_status_info_ipv4_st { + pthread_rwlock_t lk_lock; + DnStatus_ipv4 dnStatus; +} datanode_status_info_ipv4; + +typedef struct CmDnReportStatusMsgT_ipv4 { + cm_local_replconninfo_ipv4 local_status; + int sender_count; + BuildState build_info; + cm_sender_replconninfo sender_status[CM_MAX_SENDER_NUM]; + cm_receiver_replconninfo receive_status; + RedoStatsData parallel_redo_status; + cm_redo_stats local_redo_stats; + synchronous_standby_mode sync_standby_mode; + int send_gs_guc_time; + int dn_restart_counts; + bool arbitrateFlag; + int failoverStep; + int failoverTimeout; + int phony_dead_times; + int phony_dead_interval; + int dn_restart_counts_in_hour; + bool is_finish_redo_cmd_sent; + uint64 ckpt_redo_point; + char barrierID[BARRIERLEN]; + char query_barrierId[BARRIERLEN]; + uint64 barrierLSN; + uint64 archive_LSN; + uint64 flush_LSN; + DatanodeSyncList dnSyncList; + int32 syncDone; + uint32 arbiTime; + uint32 sendFailoverTimes; + bool is_barrier_exist; + cmTime_t printBegin; // print synclist time + DatanodelocalPeer dnLp; +} CmDnReportStatusMsg_ipv4; + +// need to keep consist with cm_to_ctl_instance_datanode_status +typedef struct cm_instance_datanode_report_status_ipv4_st { + cm_local_replconninfo_ipv4 local_status; + int sender_count; + BuildState build_info; + cm_sender_replconninfo sender_status[CM_MAX_SENDER_NUM]; + cm_receiver_replconninfo receive_status; + RedoStatsData parallel_redo_status; + cm_redo_stats local_redo_stats; + synchronous_standby_mode sync_standby_mode; + int send_gs_guc_time; + int dn_restart_counts; + bool arbitrateFlag; + int failoverStep; + int failoverTimeout; + int phony_dead_times; + int phony_dead_interval; + int dn_restart_counts_in_hour; + int dnVipStatus; + bool is_finish_redo_cmd_sent; + uint64 ckpt_redo_point; + char barrierID[BARRIERLEN]; + char query_barrierId[BARRIERLEN]; + uint64 barrierLSN; + uint64 archive_LSN; + uint64 flush_LSN; + DatanodeSyncList dnSyncList; + int32 syncDone; + uint32 arbiTime; + uint32 sendFailoverTimes; + bool is_barrier_exist; + cmTime_t printBegin; // print synclist time + DatanodelocalPeer dnLp; + DnFloatIpInfo floatIp; +} cm_instance_datanode_report_status_ipv4; + +typedef struct cm_to_cm_report_sync_ipv4_st { + int msg_type; + uint32 node[CM_PRIMARY_STANDBY_NUM]; + uint32 instanceId[CM_PRIMARY_STANDBY_NUM]; + int instance_type[CM_PRIMARY_STANDBY_NUM]; + cm_instance_command_status command_member[CM_PRIMARY_STANDBY_NUM]; + cm_instance_datanode_report_status_ipv4 data_node_member[CM_PRIMARY_STANDBY_NUM]; + cm_instance_gtm_report_status gtm_member[CM_PRIMARY_STANDBY_NUM]; + cm_instance_coordinate_report_status coordinatemember; + cm_instance_arbitrate_status arbitrate_status_member[CM_PRIMARY_STANDBY_NUM]; +} cm_to_cm_report_sync_ipv4; + +typedef struct cm_to_ctl_get_datanode_relation_ack_ipv4_st { + int command_result; + int member_index; + cm_instance_role_status instanceMember[CM_PRIMARY_STANDBY_MAX_NUM]; + cm_instance_gtm_report_status gtm_member[CM_PRIMARY_STANDBY_NUM]; + CmDnReportStatusMsg_ipv4 data_node_member[CM_PRIMARY_STANDBY_MAX_NUM]; +} cm_to_ctl_get_datanode_relation_ack_ipv4; + +// need to keep consist with the struct cm_instance_datanode_report_status +typedef struct cm_to_ctl_instance_datanode_status_ipv4_st { + cm_local_replconninfo_ipv4 local_status; + int sender_count; + BuildState build_info; + cm_sender_replconninfo sender_status[CM_MAX_SENDER_NUM]; + cm_receiver_replconninfo receive_status; + RedoStatsData parallel_redo_status; + cm_redo_stats local_redo_stats; + synchronous_standby_mode sync_standby_mode; + int send_gs_guc_time; +} cm_to_ctl_instance_datanode_status_ipv4; + +typedef struct cm_to_ctl_instance_status_ipv4_st { + int msg_type; + uint32 node; + uint32 instanceId; + int instance_type; + int member_index; + int is_central; + int fenced_UDF_status; + cm_to_ctl_instance_datanode_status_ipv4 data_node_member; + cm_to_ctl_instance_gtm_status gtm_member; + cm_to_ctl_instance_coordinate_status coordinatemember; +} cm_to_ctl_instance_status_ipv4; + +#endif diff --git a/src/include/cm/cm_msg_version_convert.h b/src/include/cm/cm_msg_version_convert.h new file mode 100644 index 0000000000000000000000000000000000000000..2780021c856fb46cce3340ff94dfe677b210c0fd --- /dev/null +++ b/src/include/cm/cm_msg_version_convert.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Huawei Technologies Co.,Ltd. + * + * CM is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * ------------------------------------------------------------------------- + * + * cm_msg_version_convert.h + * + * + * IDENTIFICATION + * include/cm/cm_msg_version_convert.h + * + * ------------------------------------------------------------------------- + */ +#ifndef CM_MSG_VERSION_CONVERT +#define CM_MSG_VERSION_CONVERT + +#include "cm_msg_ipv4.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void CmToAgentLock2V1ToV2(const cm_to_agent_lock2_ipv4 *v1, cm_to_agent_lock2 *v2); +void CmToAgentLock2V2ToV1(const cm_to_agent_lock2 *v2, cm_to_agent_lock2_ipv4 *v1); +void CmLocalReplconninfoV1ToV2(const cm_local_replconninfo_ipv4 *v1, cm_local_replconninfo *v2); +void CmLocalReplconninfoV2ToV1(const cm_local_replconninfo *v2, cm_local_replconninfo_ipv4 *v1); +void AgentToCmDatanodeStatusReportV1ToV2(const agent_to_cm_datanode_status_report_ipv4 *v1, + agent_to_cm_datanode_status_report *v2); +void AgentToCmDatanodeStatusReportV2ToV1(const agent_to_cm_datanode_status_report *v2, + agent_to_cm_datanode_status_report_ipv4 *v1); +void CmDnReportStatusMsgV1ToV2(const CmDnReportStatusMsg_ipv4 *v1, CmDnReportStatusMsg *v2); +void CmDnReportStatusMsgV2ToV1(const CmDnReportStatusMsg *v2, CmDnReportStatusMsg_ipv4 *v1); +void CmToCtlGetDatanodeRelationAckV1ToV2(const cm_to_ctl_get_datanode_relation_ack_ipv4 *v1, + cm_to_ctl_get_datanode_relation_ack *v2); +void CmToCtlGetDatanodeRelationAckV2ToV1(const cm_to_ctl_get_datanode_relation_ack *v2, + cm_to_ctl_get_datanode_relation_ack_ipv4 *v1); +void CmToCtlInstanceDatanodeStatusV1ToV2(const cm_to_ctl_instance_datanode_status_ipv4 *v1, + cm_to_ctl_instance_datanode_status *v2); +void CmToCtlInstanceDatanodeStatusV2ToV1(const cm_to_ctl_instance_datanode_status *v2, + cm_to_ctl_instance_datanode_status_ipv4 *v1); +void CmToCtlInstanceStatusV1ToV2(const cm_to_ctl_instance_status_ipv4 *v1, cm_to_ctl_instance_status *v2); +void CmToCtlInstanceStatusV2ToV1(const cm_to_ctl_instance_status *v2, cm_to_ctl_instance_status_ipv4 *v1); +void GetCtlInstanceStatusFromRecvMsg(char *receiveMsg, cm_to_ctl_instance_status *ctlInstanceStatusPtr); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/src/include/cm/cm_server/cms_common_res.h b/src/include/cm/cm_server/cms_common_res.h index 95844f7659cdc3b5de088b5a97408152480c9ed5..0de64b45503bb2f8c425cfe3fb7c625d23ef7b68 100644 --- a/src/include/cm/cm_server/cms_common_res.h +++ b/src/include/cm/cm_server/cms_common_res.h @@ -40,6 +40,7 @@ void UpdateResIsregStatusList(uint32 nodeId, ResInstIsreg *isregList, uint32 isr bool IsCmInstIdInCheckList(uint32 nodeId, uint32 cmInstId); bool IsRecvCheckListMiss(uint32 nodeId, uint32 *checkList, uint32 checkCount); bool IsRecvIsregStatValid(int stat); +void CleanAllResStatusReportInter(); status_t SaveOneResStatusToDdb(const OneResStatList *oneResStat); status_t GetOneResStatusFromDdb(OneResStatList *resStat); diff --git a/src/include/cm/cm_server/cms_process_messages.h b/src/include/cm/cm_server/cms_process_messages.h index 5ac318ccec6a03d3c42c4e9f1aadec62459bc5bd..c29ff74bfcdea313271adda6068087716e5ca759 100644 --- a/src/include/cm/cm_server/cms_process_messages.h +++ b/src/include/cm/cm_server/cms_process_messages.h @@ -34,15 +34,15 @@ #define ETCD_CLOCK_THRESHOLD 3 #define SWITCHOVER_SEND_CHECK_RATE 30 -#define PROCESS_MSG_BY_TYPE(struct_name, strunct_ptr, function_name) \ - do { \ - (strunct_ptr) = reinterpret_cast( \ +#define PROCESS_MSG_BY_TYPE(struct_name, strunct_ptr, function_name, recvMsgInfo, msgType) \ + do { \ + (strunct_ptr) = reinterpret_cast( \ reinterpret_cast(const_cast(CmGetmsgbytes(&recvMsgInfo->msg, sizeof(struct_name))))); \ - if ((strunct_ptr) != NULL) { \ - (function_name)(recvMsgInfo, (strunct_ptr)); \ - } else { \ - write_runlog(ERROR, "CmGetmsgbytes failed, msg_type=%d.\n", msgType); \ - } \ + if ((strunct_ptr) != NULL) { \ + (function_name)(recvMsgInfo, (strunct_ptr)); \ + } else { \ + write_runlog(ERROR, "CmGetmsgbytes failed, msg_type=%d.\n", msgType); \ + } \ } while (0) typedef struct CmdMsgProc_t { @@ -164,6 +164,7 @@ void ReleaseResLockOwner(const char *resName, uint32 instId); void ResetResNodeStat(); void ProcessDnFloatIpMsg(MsgRecvInfo *recvMsgInfo, CmaDnFloatIpInfo *floatIp); void GetFloatIpSet(CmFloatIpStatAck *ack, size_t maxMsgLen, size_t *curMsgLen); +void ProcessPingDnFloatIpFailedMsg(MsgRecvInfo *recvMsgInfo, CmSendPingDnFloatIpFail *failedFloatIpInfo); #ifdef ENABLE_MULTIPLE_NODES void SetCmdStautus(int32 ret); diff --git a/src/include/cm/cm_text.h b/src/include/cm/cm_text.h index d7d603fda63274eae4498d21096a298740033ac4..4aee10e9c29676af1a9e1e57c6f12e2c1bdb04c5 100644 --- a/src/include/cm/cm_text.h +++ b/src/include/cm/cm_text.h @@ -53,6 +53,7 @@ typedef struct CmConstTextT { #define CM_IS_EMPTY(text) (((text)->str == NULL) || ((text)->len == 0)) #define CM_IS_QUOTE_CHAR(c1) ((c1) == '\'' || (c1) == '"' || (c1) == '`') #define CM_IS_QUOTE_STRING(c1, c2) ((c1) == (c2) && CM_IS_QUOTE_CHAR(c1)) +#define CM_IS_DIGITAL_LETER(c) ((c) >= '0' && ((c) <= '9')) #define CM_TEXT_CLEAR(text) ((text)->len = 0) @@ -116,11 +117,16 @@ bool8 CmTextStrEqualIns(const text_t *text, const char *str); bool8 CmFetchText(text_t *text, char splitChar, char encloseChar, text_t *sub); void CmSplitText(const text_t *text, char splitChar, char encloseChar, text_t *left, text_t *right); void CmRemoveBrackets(text_t *text); +void CmRemoveSquareBrackets(text_t *text); void CmTrimText(text_t *text); void CmLtrimText(text_t *text); void CmRtrimText(text_t *text); bool8 IsCmBracketText(const text_t *text); status_t CmText2Str(const text_t *text, char *buf, uint32 bufSize); void CmTrimStr(char *str); +status_t CmText2Uint16(const text_t *textSrc, uint16 *value); +status_t CmStr2Uint16(const char *str, uint16 *value); +status_t CmCheckIsNumber(const char *str); +bool CmIsErr(const char *err); #endif diff --git a/src/include/cm/cm_util.h b/src/include/cm/cm_util.h index cea1cd4de9aec71f5f79c2079b087e3df91ea2e7..858105672a71970ac40bc9d5848d61009460bcd2 100644 --- a/src/include/cm/cm_util.h +++ b/src/include/cm/cm_util.h @@ -34,6 +34,7 @@ const int CM_MS_COUNT_PER_SEC = 1000; int CmMkdirP(char *path, unsigned int omode); char *gs_getenv_r(const char *name); uint64 GetMonotonicTimeMs(); +uint64 GetMonotonicTimeS(); enum class CMFairMutexType { CM_MUTEX_NODE, diff --git a/src/include/opengauss/cm/elog.h b/src/include/opengauss/cm/elog.h index 077b8448f02383dd8dd9e4242923ee31d96b6e59..09f84f4c218158ec943b6970de2db230837920f5 100644 --- a/src/include/opengauss/cm/elog.h +++ b/src/include/opengauss/cm/elog.h @@ -186,6 +186,7 @@ extern const char* prefix_name; extern volatile uint32 undocumentedVersion; #define INPLACE_UPGRADE_PRECOMMIT_VERSION 1 #define DORADO_UPGRADE_VERSION (92574) +#define SUPPORT_IPV6_VERSION ((uint32)94502) #define FAILOVER_STAPRI_VERSION (94503) template diff --git a/src/include/opengauss/common/config/cm_config.h b/src/include/opengauss/common/config/cm_config.h index 4e690cd53043b7306ba958229bf704e5930a95b1..2c8ca79509a07216d989d95d8c5ebb6b1967c009 100644 --- a/src/include/opengauss/common/config/cm_config.h +++ b/src/include/opengauss/common/config/cm_config.h @@ -38,6 +38,8 @@ #define GTM_IP_PORT 64 #define CM_IP_LENGTH 128 #define CM_IP_ALL_NUM_LENGTH (CM_IP_NUM * CM_IP_LENGTH) +#define CM_MAX_NUMBER_LENGTH (uint32)128 +#define CM_DEFAULT_DIGIT_RADIX 10 #define CM_PATH_LENGTH 1024 #define CM_NODE_MAXNUM 1024 #define CM_MAX_DATANODE_PER_NODE 160 diff --git a/tool/cm_tool/InstallImpl.py b/tool/cm_tool/InstallImpl.py index 30d6c85b91df15f31a2ab4707dae6f50da633002..cff2532b100c645bf5cfd2e0f0f31740e11eb4f3 100755 --- a/tool/cm_tool/InstallImpl.py +++ b/tool/cm_tool/InstallImpl.py @@ -83,6 +83,8 @@ class InstallImpl: if host == self.localhostName: continue # copy cm pacakage to other hosts + if ":" in host: + host = "[" + host + "]" scpCmd = "scp %s %s:%s" % (self.cmpkg, host, self.toolPath) status, output = subprocess.getstatusoutput(scpCmd) if status != 0: @@ -206,6 +208,8 @@ class InstallImpl: if host == self.localhostName: continue # copy cronContentTmpFile to other host + if ":" in host: + host = "[" + host + "]" scpCmd = "scp %s %s:%s" % (cronContentTmpFile, host, self.tmpPath) status, output = subprocess.getstatusoutput(scpCmd) if status != 0: @@ -423,7 +427,14 @@ class InstallImpl: errorDetail = "\nCommand: %s\nStatus: %s\nOutput: %s" % (createCertPathCmd, status, output) self.logger.debug(errorDetail) self.logger.logExit("Failed to create path of CA for CM on host %s." % host) - scpCmd = "scp {certPath}/* {host}:{certPath}".format(certPath=certPath, host=host) + # Determine if the host is an IPv6 address and format accordingly + if ":" in host: + formatted_host = "[{}]".format(host) + else: + formatted_host = host + + # Create the scp command with the formatted host + scpCmd = "scp {certPath}/* {host}:{certPath}".format(certPath=certPath, host=formatted_host) status, output = subprocess.getstatusoutput(scpCmd) if status != 0: errorDetail = "\nCommand: %s\nStatus: %s\nOutput: %s" % (scpCmd, status, output)