* Copyright (c) 2022 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.
* -------------------------------------------------------------------------
*
* cms_rhb.cpp
*
*
* IDENTIFICATION
* src/cm_server/cms_rhb.cpp
*
* -------------------------------------------------------------------------
*/
#include "cm_elog.h"
#include "cm_rhb.h"
#include "cm_config.h"
#include "cms_rhb.h"
#include "cms_global_params.h"
typedef struct DbResNodeIdxInfo_t {
uint32 hwl;
uint32 idxLists[MAX_RHB_NUM];
} DbResNodeIdxInfo;
static time_t g_hbs[MAX_RHB_NUM][MAX_RHB_NUM] = {0};
static time_t g_hbs_bak[MAX_RHB_NUM][MAX_RHB_NUM] = {0};
static DbResNodeIdxInfo g_dbResNodeIdxInfo = { 0 };
bool g_hbsFlags = false;
time_t startWaitTime = 0;
int delayTime = 2;
void InitDbListsByStaticConfig()
{
char buf[MAX_LOG_BUFF_LEN] = {0};
const uint32 maxInfoLen = 64;
char info[maxInfoLen] = {0};
int rcs;
for (uint32 i = 0; i < g_node_num; i++) {
if (g_node[i].datanodeCount > 0) {
if (g_dbResNodeIdxInfo.hwl >= MAX_RHB_NUM) {
write_runlog(ERROR, "[InitDbListsByStaticConfig] we supported res count less than %d", MAX_RHB_NUM);
return;
}
g_dbResNodeIdxInfo.idxLists[g_dbResNodeIdxInfo.hwl] = i;
rcs = snprintf_s(info, maxInfoLen, maxInfoLen - 1, " %u:[%u-%u]",
g_dbResNodeIdxInfo.hwl, i, g_node[i].node);
securec_check_intval(rcs, (void)rcs);
rcs = strncat_s(buf, MAX_LOG_BUFF_LEN, info, strlen(info));
securec_check_errno(rcs, (void)rcs);
g_dbResNodeIdxInfo.hwl++;
}
}
write_runlog(LOG, "[InitDbListsByStaticConfig] hwl:%u, detail:%s\n", g_dbResNodeIdxInfo.hwl, buf);
}
static status_t FindResIdxByNodeId(uint32 nodeId, uint32 *resIdx)
{
for (uint32 i = 0; i < g_dbResNodeIdxInfo.hwl; i++) {
uint32 curNodeIdx = g_dbResNodeIdxInfo.idxLists[i];
if (g_node[curNodeIdx].node == nodeId) {
*resIdx = i;
return CM_SUCCESS;
}
}
write_runlog(ERROR, "[FindResIdxByNodeId] can't find nodeId(%u), hwl(%u)\n", nodeId, g_dbResNodeIdxInfo.hwl);
return CM_ERROR;
}
void RefreshNodeRhbInfo(unsigned int nodeId, const time_t *hbs, unsigned int hwl)
{
uint32 resIdx;
errno_t rc;
if (hwl != g_dbResNodeIdxInfo.hwl) {
write_runlog(
ERROR, "[RefreshNodeRhbInfo] node[%u] rhb hwl(%u) must equal %u\n", nodeId, hwl, g_dbResNodeIdxInfo.hwl);
return;
}
CM_RETVOID_IFERR(FindResIdxByNodeId(nodeId, &resIdx));
if (g_hbsFlags == true && difftime(time(NULL), startWaitTime) >= delayTime) {
rc = memcpy_s(g_hbs, sizeof(time_t) * MAX_RHB_NUM * MAX_RHB_NUM,
g_hbs_bak, sizeof(time_t) * MAX_RHB_NUM * MAX_RHB_NUM);
securec_check_errno(rc, (void)rc);
g_hbsFlags = false;
}
for (int i = 0; i < MAX_RHB_NUM; i++) {
if (hbs[i] - g_hbs[resIdx][i] > g_agentNetworkTimeout) {
if (g_hbsFlags == false) {
startWaitTime = time(NULL);
rc = memcpy_s(g_hbs_bak, sizeof(time_t) * MAX_RHB_NUM * MAX_RHB_NUM,
g_hbs, sizeof(time_t) * MAX_RHB_NUM * MAX_RHB_NUM);
securec_check_errno(rc, (void)rc);
g_hbsFlags = true;
}
rc = memcpy_s(g_hbs_bak[resIdx], sizeof(time_t) * MAX_RHB_NUM, hbs, sizeof(time_t) * hwl);
securec_check_errno(rc, (void)rc);
return;
}
}
startWaitTime = 0;
rc = memcpy_s(g_hbs[resIdx], sizeof(time_t) * MAX_RHB_NUM, hbs, sizeof(time_t) * hwl);
securec_check_errno(rc, (void)rc);
}
void GetRhbStat(time_t hbs[MAX_RHB_NUM][MAX_RHB_NUM], unsigned int *hwl)
{
*hwl = g_dbResNodeIdxInfo.hwl;
const size_t hbsSize = sizeof(time_t) * MAX_RHB_NUM * MAX_RHB_NUM;
errno_t rc = memcpy_s(hbs, hbsSize, g_hbs, hbsSize);
securec_check_errno(rc, (void)rc);
}
void ResetNodeConnStat()
{
errno_t rc = memset_s(g_hbs, sizeof(g_hbs), 0, sizeof(g_hbs));
securec_check_errno(rc, (void)rc);
}
static void PrintOneHbInfo(int resIdx1, uint32 nodeId1, int resIdx2, uint32 nodeId2, int logLevel)
{
struct tm result;
GetLocalTime(&g_hbs[resIdx1][resIdx2], &result);
const uint32 timeBufMaxLen = 128;
char timeBuf[timeBufMaxLen] = {0};
(void)strftime(timeBuf, timeBufMaxLen, "%Y-%m-%d %H:%M:%S", &result);
write_runlog(logLevel, "(index=%d,nodeId=%u)->(index=%d,nodeId=%u) hb info: %s.\n",
resIdx1, nodeId1, resIdx1, nodeId2, timeBuf);
}
void PrintHbsInfo(int resIdx1, uint32 nodeId1, int resIdx2, uint32 nodeId2, int logLevel)
{
PrintOneHbInfo(resIdx1, nodeId1, resIdx2, nodeId2, logLevel);
PrintOneHbInfo(resIdx2, nodeId2, resIdx1, nodeId1, logLevel);
}
void GetTimeStr(time_t baseTime, char *timeStr, uint32 strLen)
{
struct tm result;
GetLocalTime(&baseTime, &result);
(void)strftime(timeStr, strLen, "%Y-%m-%d %H:%M:%S", &result);
}