Files
openGauss-server/src/lib/config/cm_config.cpp
cchen676 2e4d3aad96 fix issue
当配置synchronous_standby_names参数的值为和主节点不在一个AZ内的备节点时,
会报错,这个是因为guc参数检查导致,修改内核中guc相关代码去掉该检查
2021-05-20 16:48:17 +08:00

1648 lines
63 KiB
C++

/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss 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_config.cpp
*
*
* IDENTIFICATION
* src/lib/config/cm_config.cpp
*
* ---------------------------------------------------------------------------------------
*/
#include "common/config/cm_config.h"
#include "securec.h"
#include "securec_check.h"
#include <map>
#include <algorithm>
#include <string>
using namespace std;
/* This macro was used to replace the "goto" statement of the function "read_logic_config_file". */
#define READ_LOGICAL_CONFIG_FAILED \
do { \
if (NULL != LCStaticConfig->logicClusterNode) { \
free(LCStaticConfig->logicClusterNode); \
LCStaticConfig->logicClusterNode = NULL; \
} \
fclose(fd); \
*err_no = errno; \
return READ_FILE_ERROR; \
} while (0);
staticConfigHeader g_nodeHeader;
staticNodeConfig* g_node = NULL;
uint32 g_az_master = PG_UINT32_MAX;
uint32 g_az_slave = PG_UINT32_MAX;
uint32 g_az_arbiter = PG_UINT32_MAX;
logicClusterStaticConfig g_logicClusterStaticConfig[LOGIC_CLUSTER_NUMBER] = {0};
uint32 g_logic_cluster_count = 0;
uint32 max_logic_cluster_state_len = 20;
uint32 max_logic_cluster_name_len = 0;
bool logic_cluster_query = false;
bool logic_cluster_restart = false;
staticNodeConfig* g_currentNode = NULL;
bool g_single_node_cluster = false;
bool g_multi_az_cluster = false;
bool g_one_master_multi_slave = false;
bool g_only_dn_cluster = false;
uint32 g_node_num = 0;
uint32 g_cluster_total_instance_group_num = 0;
uint32 g_coordinator_num = 0;
uint32 g_etcd_num = 0;
uint32 g_cm_server_num = 0;
uint32 g_dn_replication_num = 0;
uint32 g_gtm_num = 0;
uint32 max_node_name_len = 0;
uint32 max_az_name_len = 0;
uint32 max_datapath_len = 0;
uint32 max_cnpath_len = 0;
uint32 max_gtmpath_len = 0;
uint32 max_etcdpath_len = 0;
uint32 max_cmpath_len = 0;
/* the local node name and idx */
uint32 g_local_node_idx = 0;
char* g_local_node_name = NULL;
// the logical cluster name
char* g_lcname = NULL;
/* for datanode alarm */
uint32 g_datanodeid = 0;
char *g_logicClusterName = NULL;
bool g_isCmRead = false;
#define FREAD(ptr, nitems, size, stream) \
do { \
if (fread(ptr, size, nitems, stream) != nitems) \
goto read_failed; \
} while (0)
static int read_all_logic_config_file(logicClusterList lcList, int* err_no);
static int read_logic_config_file(logicClusterInfo lcInfo, int* err_no);
void check_input_for_security(char* input)
{
const char* danger_character_list[] = {"|",
";",
"&",
"$",
"<",
">",
"`",
"\\",
"'",
"\"",
"{",
"}",
"(",
")",
"[",
"]",
"~",
"*",
"?",
"!",
"\n",
NULL};
int i = 0;
for (i = 0; danger_character_list[i] != NULL; i++) {
if (strstr(input, danger_character_list[i]) != NULL) {
fprintf(stderr, "invalid token \"%s\" in input_value: (%s)\n", danger_character_list[i], input);
exit(1);
}
}
}
int cmconfig_getenv(const char* env_var, char* output_env_value, uint32 env_value_len)
{
char* env_value = NULL;
int rc = 0;
if (env_var == NULL) {
fprintf(stderr, "cmconfig_getenv: invalid env_var !\n");
return -1;
}
env_value = getenv(env_var);
if (env_value == NULL || env_value[0] == '\0') {
fprintf(stderr,
"cmconfig_getenv: failed to get environment variable:%s. Please check and make sure it is configured!\n",
env_var);
return -1;
}
check_input_for_security(env_value);
rc = strcpy_s(output_env_value, env_value_len, env_value);
if (rc != EOK) {
fprintf(stderr,
"cmconfig_getenv: failed to get environment variable:%s, variable length:%lu.\n",
env_var,
strlen(env_value));
return -1;
}
return EOK;
}
/*
* qsort comparison function for server node index
*/
int node_index_Comparator(const void* arg1, const void* arg2)
{
uint32 index1 = *(const uint32*)arg1;
uint32 index2 = *(const uint32*)arg2;
if (index1 > index2) {
return 1;
} else if (index1 < index2) {
return -1;
} else {
return 0;
}
}
int find_node_index_by_nodeid(uint32 nodeId, uint32* node_index)
{
for (uint32 i = 0; i < g_node_num; i++) {
if (g_node[i].node == nodeId) {
*node_index = i;
return 0;
}
}
return -1;
}
int find_current_node_by_nodeid(uint32 nodeId)
{
uint32 node_index = 0;
int ret = find_node_index_by_nodeid(g_nodeHeader.node, &node_index);
if (ret != 0) {
return -1;
}
g_currentNode = &g_node[node_index];
return 0;
}
/* read config file to get azPriority for each AZ
* rule 1: the priority value in different AZ must satisfy: AZ3 > AZ2 > AZ1
* rule 2: the priority value can be different unsigned integer among a AZ, such as 1, 3, etc
* rule 3: the priority of a AZ is the smallest priority value
* */
void setAZPriority()
{
map<string, uint32> nameAndPriority;
map<string, uint32>::iterator it;
const int azNumber = 3;
int zeroIndex = 0;
uint32 priorities[azNumber] = {PG_UINT32_MAX, PG_UINT32_MAX, PG_UINT32_MAX};
for (uint32 i = 0; i < g_node_num; i++) {
if (!g_multi_az_cluster) {
break;
}
string azName = g_node[i].azName;
uint32 azPriority = g_node[i].azPriority;
it = nameAndPriority.find(azName);
if (it != nameAndPriority.end() && it->second > azPriority) {
it->second = azPriority;
} else {
nameAndPriority.insert(pair<string, uint32>(azName, azPriority));
}
}
uint32 num;
for (it = nameAndPriority.begin(), num = 0; it != nameAndPriority.end() && num < azNumber; it++, num++) {
priorities[num] = it->second;
}
sort(priorities, priorities + azNumber);
g_az_master = priorities[zeroIndex];
g_az_slave = priorities[++zeroIndex];
g_az_arbiter = priorities[++zeroIndex];
}
int read_config_file(const char* file_path, int* err_no)
{
FILE* fd = NULL;
uint32 ii = 0;
uint32 header_size = 0;
uint32 header_aglinment_size = 0;
long current_pos = 0;
bool datanodeMirrorIDInit = false;
uint32 datanodeMirrorID = 0;
int rcs = 0;
char configFilePath[MAX_PATH_LEN];
header_size = sizeof(staticConfigHeader);
header_aglinment_size =
(header_size / AGLINMENT_SIZE + ((header_size % AGLINMENT_SIZE) == 0 ? 0 : 1)) * AGLINMENT_SIZE;
rcs = strncpy_s(configFilePath, MAX_PATH_LEN, file_path, MAX_PATH_LEN - 1);
securec_check_c(rcs, "\0", "\0");
canonicalize_path(configFilePath);
fd = fopen(configFilePath, "r");
if (fd == NULL) {
*err_no = errno;
return OPEN_FILE_ERROR;
}
/********************************************************************************
* DISCLAIMER: Any Change in file format need to update the Version Number *
* Version Number Offset should not be changed *
********************************************************************************/
rcs = memset_s(&g_nodeHeader, sizeof(staticConfigHeader), 0, sizeof(staticConfigHeader));
securec_check_c(rcs, "\0", "\0");
// read head info
FREAD(&g_nodeHeader.crc, 1, sizeof(uint32), fd);
FREAD(&g_nodeHeader.len, 1, sizeof(uint32), fd);
FREAD(&g_nodeHeader.version, 1, sizeof(uint32), fd);
// version in [101, 200] means single node cluster.
if ((101 <= g_nodeHeader.version) && (g_nodeHeader.version <= 200)) {
g_single_node_cluster = true;
} else if ((201 <= g_nodeHeader.version) && (g_nodeHeader.version <= 300)) {
g_multi_az_cluster = true;
g_one_master_multi_slave = true;
} else if ((301 <= g_nodeHeader.version) && (g_nodeHeader.version <= 400)) {
g_only_dn_cluster = true;
//only dn is a subset for multi az
g_multi_az_cluster = true;
g_one_master_multi_slave = true;
}
FREAD(&g_nodeHeader.time, 1, sizeof(int64), fd);
FREAD(&g_nodeHeader.nodeCount, 1, sizeof(uint32), fd);
FREAD(&g_nodeHeader.node, 1, sizeof(uint32), fd);
if (g_node != NULL) {
free(g_node);
g_node = NULL;
}
g_node_num = g_nodeHeader.nodeCount;
if (g_node_num > CM_NODE_MAXNUM) {
fclose(fd);
return READ_FILE_ERROR;
}
if (fseek(fd, (off_t)(header_aglinment_size), SEEK_SET) != 0)
goto read_failed;
g_node = (staticNodeConfig*)malloc(sizeof(staticNodeConfig) * g_node_num);
if (g_node == NULL) {
fclose(fd);
return OUT_OF_MEMORY;
}
/* g_node size may be larger than SECUREC_STRING_MAX_LEN in large cluster.*/
rcs = memset_s(g_node, sizeof(staticNodeConfig) * g_node_num, 0, sizeof(staticNodeConfig) * g_node_num);
if (rcs != EOK && rcs != ERANGE) {
printf("ERROR at %s : %d : Initialize is failed, error num is: %d.\n", __FILE__, __LINE__, rcs);
exit(1);
}
for (ii = 0; ii < g_node_num; ii++) {
uint32 jj = 0;
uint32 kk = 0;
uint32 body_aglinment_size = 0;
/* read node info */
FREAD(&g_node[ii].crc, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].node, 1, sizeof(uint32), fd);
FREAD(g_node[ii].nodeName, 1, (CM_NODE_NAME - 1), fd);
g_node[ii].nodeName[CM_NODE_NAME - 1] = '\0';
check_input_for_security(g_node[ii].nodeName);
max_node_name_len =
(max_node_name_len < strlen(g_node[ii].nodeName)) ? strlen(g_node[ii].nodeName) : max_node_name_len;
if (g_multi_az_cluster) {
/* read az info */
FREAD(g_node[ii].azName, 1, (CM_AZ_NAME - 1), fd);
g_node[ii].azName[CM_AZ_NAME - 1] = '\0';
check_input_for_security(g_node[ii].azName);
FREAD(&g_node[ii].azPriority, 1, sizeof(uint32), fd);
max_az_name_len = (max_az_name_len < (uint32)strlen(g_node[ii].azName)) ? (uint32)strlen(g_node[ii].azName)
: max_az_name_len;
}
FREAD(&g_node[ii].backIpCount, 1, sizeof(uint32), fd);
if (g_node[ii].backIpCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].backIps[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].backIps[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].backIps[jj]);
}
FREAD(&g_node[ii].sshCount, 1, sizeof(uint32), fd);
if (g_node[ii].sshCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].sshChannel[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].sshChannel[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].sshChannel[jj]);
}
/* read CMServer info */
FREAD(&g_node[ii].cmServerId, 1, sizeof(uint32), fd);
if (g_node[ii].cmServerId != 0) {
g_cm_server_num++;
}
FREAD(&g_node[ii].cmServerMirrorId, 1, sizeof(uint32), fd);
FREAD(g_node[ii].cmDataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].cmDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].cmDataPath);
max_cmpath_len =
(max_cmpath_len < strlen(g_node[ii].cmDataPath)) ? strlen(g_node[ii].cmDataPath) : max_cmpath_len;
FREAD(&g_node[ii].cmServerLevel, 1, sizeof(uint32), fd);
FREAD(g_node[ii].cmServerFloatIP, 1, CM_IP_LENGTH, fd);
g_node[ii].cmServerFloatIP[CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].cmServerFloatIP);
FREAD(&g_node[ii].cmServerListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].cmServerListenCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].cmServer[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].cmServer[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].cmServer[jj]);
}
FREAD(&g_node[ii].port, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].cmServerLocalHAListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].cmServerLocalHAListenCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].cmServerLocalHAIP[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].cmServerLocalHAIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].cmServerLocalHAIP[jj]);
}
FREAD(&g_node[ii].cmServerLocalHAPort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].cmServerRole, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].cmServerPeerHAListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].cmServerPeerHAListenCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].cmServerPeerHAIP[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].cmServerPeerHAIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].cmServerPeerHAIP[jj]);
}
FREAD(&g_node[ii].cmServerPeerHAPort, 1, sizeof(uint32), fd);
/* read GTM info */
FREAD(&g_node[ii].gtmAgentId, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].cmAgentMirrorId, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].cmAgentListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].cmAgentListenCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].cmAgentIP[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].cmAgentIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].cmAgentIP[jj]);
}
FREAD(&g_node[ii].gtmId, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].gtmMirrorId, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].gtm, 1, sizeof(uint32), fd);
if (g_node[ii].gtm == 1) {
g_gtm_num++;
}
/* g_cluster_total_instance_group_num: current total instance number in cluster includeing cn dn and gtm */
/* calculate gtm group number */
if (g_node[ii].gtm == 1 && g_node[ii].gtmRole == PRIMARY_GTM) {
g_cluster_total_instance_group_num++;
}
FREAD(g_node[ii].gtmLocalDataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].gtmLocalDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].gtmLocalDataPath);
max_gtmpath_len = (max_gtmpath_len < strlen(g_node[ii].gtmLocalDataPath)) ? strlen(g_node[ii].gtmLocalDataPath)
: max_gtmpath_len;
FREAD(&g_node[ii].gtmLocalListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].gtmLocalListenCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].gtmLocalListenIP[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].gtmLocalListenIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].gtmLocalListenIP[jj]);
}
FREAD(&g_node[ii].gtmLocalport, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].gtmRole, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].gtmLocalHAListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].gtmLocalHAListenCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].gtmLocalHAIP[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].gtmLocalHAIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].gtmLocalHAIP[jj]);
}
FREAD(&g_node[ii].gtmLocalHAPort, 1, sizeof(uint32), fd);
FREAD(g_node[ii].gtmPeerDataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].gtmPeerDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].gtmPeerDataPath);
FREAD(&g_node[ii].gtmPeerHAListenCount, 1, sizeof(uint32), fd);
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].gtmPeerHAIP[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].gtmPeerHAIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].gtmPeerHAIP[jj]);
}
FREAD(&g_node[ii].gtmPeerHAPort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].gtmProxyId, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].gtmProxyMirrorId, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].gtmProxy, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].gtmProxyListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].gtmProxyListenCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].gtmProxyListenIP[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].gtmProxyListenIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].gtmProxyListenIP[jj]);
}
FREAD(&g_node[ii].gtmProxyPort, 1, sizeof(uint32), fd);
/* read CN info */
FREAD(&g_node[ii].coordinateId, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].coordinateMirrorId, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].coordinate, 1, sizeof(uint32), fd);
FREAD(g_node[ii].DataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].DataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].DataPath);
FREAD(g_node[ii].SSDDataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].SSDDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].SSDDataPath);
max_cnpath_len = (max_cnpath_len < strlen(g_node[ii].DataPath)) ? strlen(g_node[ii].DataPath) : max_cnpath_len;
FREAD(&g_node[ii].coordinateListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].coordinateListenCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].coordinateListenIP[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].coordinateListenIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].coordinateListenIP[jj]);
}
FREAD(&g_node[ii].coordinatePort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].coordinateHAPort, 1, sizeof(uint32), fd);
/* read DNs info */
FREAD(&g_node[ii].datanodeCount, 1, sizeof(uint32), fd);
/* check datacodeCount not overflow */
if (g_node[ii].datanodeCount > CM_MAX_DATANODE_PER_NODE) {
goto read_failed;
}
for (kk = 0; kk < g_node[ii].datanodeCount; kk++) {
uint32 nn = 0;
/* calculate datanode group number */
if (g_node[ii].datanode[kk].datanodeRole == PRIMARY_DN) {
g_cluster_total_instance_group_num++;
}
FREAD(&g_node[ii].datanode[kk].datanodeId, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].datanode[kk].datanodeMirrorId, 1, sizeof(uint32), fd);
if (!datanodeMirrorIDInit) {
datanodeMirrorIDInit = true;
datanodeMirrorID = g_node[ii].datanode[kk].datanodeMirrorId;
g_dn_replication_num++;
} else if (datanodeMirrorID == g_node[ii].datanode[kk].datanodeMirrorId) {
g_dn_replication_num++;
}
FREAD(g_node[ii].datanode[kk].datanodeLocalDataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].datanode[kk].datanodeLocalDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodeLocalDataPath);
FREAD(g_node[ii].datanode[kk].datanodeXlogPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].datanode[kk].datanodeXlogPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodeXlogPath);
FREAD(g_node[ii].datanode[kk].datanodeSSDDataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].datanode[kk].datanodeSSDDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodeSSDDataPath);
max_datapath_len = (max_datapath_len < strlen(g_node[ii].datanode[kk].datanodeLocalDataPath))
? strlen(g_node[ii].datanode[kk].datanodeLocalDataPath)
: max_datapath_len;
FREAD(&g_node[ii].datanode[kk].datanodeListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].datanode[kk].datanodeListenCount > CM_IP_NUM) {
goto read_failed;
}
for (nn = 0; nn < CM_IP_NUM; nn++) {
FREAD(g_node[ii].datanode[kk].datanodeListenIP[nn], 1, CM_IP_LENGTH, fd);
g_node[ii].datanode[kk].datanodeListenIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodeListenIP[nn]);
}
FREAD(&g_node[ii].datanode[kk].datanodePort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].datanode[kk].datanodeRole, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].datanode[kk].datanodeLocalHAListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].datanode[kk].datanodeLocalHAListenCount > CM_IP_NUM) {
goto read_failed;
}
for (nn = 0; nn < CM_IP_NUM; nn++) {
FREAD(g_node[ii].datanode[kk].datanodeLocalHAIP[nn], 1, CM_IP_LENGTH, fd);
g_node[ii].datanode[kk].datanodeLocalHAIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodeLocalHAIP[nn]);
}
FREAD(&g_node[ii].datanode[kk].datanodeLocalHAPort, 1, sizeof(uint32), fd);
if (g_multi_az_cluster) {
for (uint32 dnId = 0; dnId < CM_MAX_DATANODE_STANDBY_NUM; dnId++) {
FREAD(g_node[ii].datanode[kk].peerDatanodes[dnId].datanodePeerDataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].datanode[kk].peerDatanodes[dnId].datanodePeerDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].peerDatanodes[dnId].datanodePeerDataPath);
FREAD(&g_node[ii].datanode[kk].peerDatanodes[dnId].datanodePeerHAListenCount,
1, sizeof(uint32), fd);
if (g_node[ii].datanode[kk].peerDatanodes[dnId].datanodePeerHAListenCount > CM_IP_NUM) {
goto read_failed;
}
for (nn = 0; nn < CM_IP_NUM; nn++) {
FREAD(g_node[ii].datanode[kk].peerDatanodes[dnId].datanodePeerHAIP[nn], 1, CM_IP_LENGTH, fd);
g_node[ii].datanode[kk].peerDatanodes[dnId].datanodePeerHAIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].peerDatanodes[dnId].datanodePeerHAIP[nn]);
}
FREAD(&g_node[ii].datanode[kk].peerDatanodes[dnId].datanodePeerHAPort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].datanode[kk].peerDatanodes[dnId].datanodePeerRole, 1, sizeof(uint32), fd);
}
} else {
/* former cluster: single primary, single standby and single dummy standby */
FREAD(g_node[ii].datanode[kk].datanodePeerDataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].datanode[kk].datanodePeerDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodePeerDataPath);
FREAD(&g_node[ii].datanode[kk].datanodePeerHAListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].datanode[kk].datanodePeerHAListenCount > CM_IP_NUM) {
goto read_failed;
}
for (nn = 0; nn < CM_IP_NUM; nn++) {
FREAD(g_node[ii].datanode[kk].datanodePeerHAIP[nn], 1, CM_IP_LENGTH, fd);
g_node[ii].datanode[kk].datanodePeerHAIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodePeerHAIP[nn]);
}
FREAD(&g_node[ii].datanode[kk].datanodePeerHAPort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].datanode[kk].datanodePeerRole, 1, sizeof(uint32), fd);
FREAD(g_node[ii].datanode[kk].datanodePeer2DataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].datanode[kk].datanodePeer2DataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodePeer2DataPath);
FREAD(&g_node[ii].datanode[kk].datanodePeer2HAListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].datanode[kk].datanodePeer2HAListenCount > CM_IP_NUM) {
goto read_failed;
}
for (nn = 0; nn < CM_IP_NUM; nn++) {
FREAD(g_node[ii].datanode[kk].datanodePeer2HAIP[nn], 1, CM_IP_LENGTH, fd);
g_node[ii].datanode[kk].datanodePeer2HAIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodePeer2HAIP[nn]);
}
FREAD(&g_node[ii].datanode[kk].datanodePeer2HAPort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].datanode[kk].datanodePeer2Role, 1, sizeof(uint32), fd);
}
}
FREAD(&g_node[ii].etcd, 1, sizeof(uint32), fd);
if (g_node[ii].etcd == 1) {
g_etcd_num++;
}
/* calculate coordinate group number */
if (g_node[ii].coordinate == 1) {
g_coordinator_num++;
g_cluster_total_instance_group_num++;
}
FREAD(&g_node[ii].etcdId, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].etcdMirrorId, 1, sizeof(uint32), fd);
FREAD(g_node[ii].etcdName, 1, (CM_NODE_NAME - 1), fd);
g_node[ii].etcdName[CM_NODE_NAME - 1] = '\0';
check_input_for_security(g_node[ii].etcdName);
FREAD(g_node[ii].etcdDataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].etcdDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].etcdDataPath);
max_etcdpath_len =
(max_etcdpath_len < strlen(g_node[ii].etcdDataPath)) ? strlen(g_node[ii].etcdDataPath) : max_etcdpath_len;
FREAD(&g_node[ii].etcdClientListenIPCount, 1, sizeof(uint32), fd);
if (g_node[ii].etcdClientListenIPCount > CM_IP_NUM) {
goto read_failed;
}
for (kk = 0; kk < CM_IP_NUM; kk++) {
FREAD(g_node[ii].etcdClientListenIPs[kk], 1, CM_IP_LENGTH, fd);
g_node[ii].etcdClientListenIPs[kk][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].etcdClientListenIPs[kk]);
}
FREAD(&g_node[ii].etcdClientListenPort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].etcdHAListenIPCount, 1, sizeof(uint32), fd);
if (g_node[ii].etcdHAListenIPCount > CM_IP_NUM) {
goto read_failed;
}
for (kk = 0; kk < CM_IP_NUM; kk++) {
FREAD(g_node[ii].etcdHAListenIPs[kk], 1, CM_IP_LENGTH, fd);
g_node[ii].etcdHAListenIPs[kk][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].etcdHAListenIPs[kk]);
}
FREAD(&g_node[ii].etcdHAListenPort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].sctpBeginPort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].sctpEndPort, 1, sizeof(uint32), fd);
current_pos = ftell(fd);
if (current_pos == -1L) {
goto read_failed;
}
body_aglinment_size =
(current_pos / AGLINMENT_SIZE + ((current_pos % AGLINMENT_SIZE == 0) ? 0 : 1)) * AGLINMENT_SIZE;
if (fseek(fd, (off_t)body_aglinment_size, SEEK_SET)) {
goto read_failed;
}
}
setAZPriority();
fclose(fd);
return 0;
read_failed:
if (g_node != NULL) {
free(g_node);
g_node = NULL;
}
fclose(fd);
g_node_num = 0;
g_etcd_num = 0;
g_cm_server_num = 0;
g_dn_replication_num = 0;
g_gtm_num = 0;
*err_no = errno;
/* test only dn cluster */
g_multi_az_cluster = false;
g_one_master_multi_slave = false;
return READ_FILE_ERROR;
}
void set_para_for_cm_read(logicClusterList lcList)
{
int rcs = 0;
char *lcName = NULL;
max_logic_cluster_name_len = 0;
rcs = memset_s(g_logicClusterStaticConfig,
sizeof(logicClusterStaticConfig) * LOGIC_CLUSTER_NUMBER,
0,
sizeof(logicClusterStaticConfig) * LOGIC_CLUSTER_NUMBER);
securec_check_c(rcs, "\0", "\0");
g_logic_cluster_count = lcList.logicClusterCount;
for (uint32 i = 0; i < g_logic_cluster_count; ++i) {
lcName = lcList.lcInfoArray[i].logicClusterName;
rcs = strcpy_s(g_logicClusterStaticConfig[i].LogicClusterName, CM_LOGIC_CLUSTER_NAME_LEN, lcName);
securec_check_c(rcs, "\0", "\0");
if (strlen(lcName) > max_logic_cluster_name_len) {
max_logic_cluster_name_len = (uint32)strlen(lcName);
}
}
}
int read_logic_cluster_config_files(const char* file_path, int* err_no)
{
int status = 0;
logicClusterList lcList;
int rcs = memset_s(&lcList, sizeof(logicClusterList), 0, sizeof(logicClusterList));
securec_check_c(rcs, "\0", "\0");
/* g_node not null means cm read */
if (g_node != NULL)
g_isCmRead = true;
status = read_logic_cluster_name(file_path, lcList, err_no);
if (status == 0) {
status = read_all_logic_config_file(lcList, err_no);
}
return status;
}
int read_lc_config_file(const char* file_path, int* err_no)
{
FILE *fd = NULL;
uint32 ii = 0;
uint32 header_size = 0;
uint32 header_aglinment_size = 0;
long current_pos = 0;
header_size = sizeof(staticConfigHeader);
header_aglinment_size =
(header_size / AGLINMENT_SIZE + ((header_size % AGLINMENT_SIZE) == 0 ? 0 : 1)) * AGLINMENT_SIZE;
fd = fopen(file_path, "r");
if (fd == NULL) {
*err_no = errno;
return OPEN_FILE_ERROR;
}
/********************************************************************************
* DISCLAIMER: Any Change in file format need to update the Version Number *
* Version Number Offset should not be changed *
********************************************************************************/
// read head info
FREAD(&g_nodeHeader.crc, 1, sizeof(uint32), fd);
FREAD(&g_nodeHeader.len, 1, sizeof(uint32), fd);
FREAD(&g_nodeHeader.version, 1, sizeof(uint32), fd);
FREAD(&g_nodeHeader.time, 1, sizeof(int64), fd);
FREAD(&g_nodeHeader.nodeCount, 1, sizeof(uint32), fd);
FREAD(&g_nodeHeader.node, 1, sizeof(uint32), fd);
if (fseek(fd, (off_t)(header_aglinment_size), SEEK_SET) != 0) {
goto read_failed;
}
/* The cluster must be primary_standby_salve */
g_node_num = g_nodeHeader.nodeCount;
if (g_node_num > CM_NODE_MAXNUM) {
fclose(fd);
return READ_FILE_ERROR;
}
if (g_node != NULL) {
free(g_node);
g_node = NULL;
}
g_node = (staticNodeConfig*)malloc(sizeof(staticNodeConfig) * g_node_num);
if (g_node == NULL) {
fclose(fd);
return OUT_OF_MEMORY;
}
for (ii = 0; ii < g_node_num; ii++) {
uint32 jj = 0;
uint32 kk = 0;
long body_aglinment_size = 0;
/* read node info */
FREAD(&g_node[ii].crc, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].node, 1, sizeof(uint32), fd);
FREAD(g_node[ii].nodeName, 1, (CM_NODE_NAME - 1), fd);
g_node[ii].nodeName[CM_NODE_NAME - 1] = '\0';
check_input_for_security(g_node[ii].nodeName);
max_node_name_len =
(max_node_name_len < strlen(g_node[ii].nodeName)) ? (uint32)strlen(g_node[ii].nodeName) : max_node_name_len;
FREAD(&g_node[ii].backIpCount, 1, sizeof(uint32), fd);
if (g_node[ii].backIpCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].backIps[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].backIps[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].backIps[jj]);
}
FREAD(&g_node[ii].sshCount, 1, sizeof(uint32), fd);
if (g_node[ii].sshCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(g_node[ii].sshChannel[jj], 1, CM_IP_LENGTH, fd);
g_node[ii].sshChannel[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].sshChannel[jj]);
}
/* read DNs info */
FREAD(&g_node[ii].datanodeCount, 1, sizeof(uint32), fd);
if (g_node[ii].datanodeCount > CM_MAX_DATANODE_PER_NODE) {
goto read_failed;
}
for (kk = 0; kk < g_node[ii].datanodeCount; kk++) {
uint32 nn = 0;
FREAD(&g_node[ii].datanode[kk].datanodeId, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].datanode[kk].datanodeMirrorId, 1, sizeof(uint32), fd);
FREAD(g_node[ii].datanode[kk].datanodeLocalDataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].datanode[kk].datanodeLocalDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodeLocalDataPath);
FREAD(g_node[ii].datanode[kk].datanodeSSDDataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].datanode[kk].datanodeSSDDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodeSSDDataPath);
max_datapath_len = (max_datapath_len < strlen(g_node[ii].datanode[kk].datanodeLocalDataPath))
? (uint32)strlen(g_node[ii].datanode[kk].datanodeLocalDataPath)
: max_datapath_len;
FREAD(&g_node[ii].datanode[kk].datanodeListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].datanode[kk].datanodeListenCount > CM_IP_NUM) {
goto read_failed;
}
for (nn = 0; nn < CM_IP_NUM; nn++) {
FREAD(g_node[ii].datanode[kk].datanodeListenIP[nn], 1, CM_IP_LENGTH, fd);
g_node[ii].datanode[kk].datanodeListenIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodeListenIP[nn]);
}
FREAD(&g_node[ii].datanode[kk].datanodePort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].datanode[kk].datanodeRole, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].datanode[kk].datanodeLocalHAListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].datanode[kk].datanodeLocalHAListenCount > CM_IP_NUM) {
goto read_failed;
}
for (nn = 0; nn < CM_IP_NUM; nn++) {
FREAD(g_node[ii].datanode[kk].datanodeLocalHAIP[nn], 1, CM_IP_LENGTH, fd);
g_node[ii].datanode[kk].datanodeLocalHAIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodeLocalHAIP[nn]);
}
FREAD(&g_node[ii].datanode[kk].datanodeLocalHAPort, 1, sizeof(uint32), fd);
FREAD(g_node[ii].datanode[kk].datanodePeerDataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].datanode[kk].datanodePeerDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodePeerDataPath);
FREAD(&g_node[ii].datanode[kk].datanodePeerHAListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].datanode[kk].datanodePeerHAListenCount > CM_IP_NUM) {
goto read_failed;
}
for (nn = 0; nn < CM_IP_NUM; nn++) {
FREAD(g_node[ii].datanode[kk].datanodePeerHAIP[nn], 1, CM_IP_LENGTH, fd);
g_node[ii].datanode[kk].datanodePeerHAIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodePeerHAIP[nn]);
}
FREAD(&g_node[ii].datanode[kk].datanodePeerHAPort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].datanode[kk].datanodeRole, 1, sizeof(uint32), fd);
FREAD(g_node[ii].datanode[kk].datanodePeer2DataPath, 1, CM_PATH_LENGTH, fd);
g_node[ii].datanode[kk].datanodePeer2DataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodePeer2DataPath);
FREAD(&g_node[ii].datanode[kk].datanodePeer2HAListenCount, 1, sizeof(uint32), fd);
if (g_node[ii].datanode[kk].datanodePeer2HAListenCount > CM_IP_NUM) {
goto read_failed;
}
for (nn = 0; nn < CM_IP_NUM; nn++) {
FREAD(g_node[ii].datanode[kk].datanodePeer2HAIP[nn], 1, CM_IP_LENGTH, fd);
g_node[ii].datanode[kk].datanodePeer2HAIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[ii].datanode[kk].datanodePeer2HAIP[nn]);
}
FREAD(&g_node[ii].datanode[kk].datanodePeer2HAPort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].datanode[kk].datanodePeer2Role, 1, sizeof(uint32), fd);
}
FREAD(&g_node[ii].sctpBeginPort, 1, sizeof(uint32), fd);
FREAD(&g_node[ii].sctpEndPort, 1, sizeof(uint32), fd);
current_pos = ftell(fd);
if (current_pos == -1L) {
goto read_failed;
}
body_aglinment_size =
(current_pos / AGLINMENT_SIZE + ((current_pos % AGLINMENT_SIZE == 0) ? 0 : 1)) * AGLINMENT_SIZE;
if (fseek(fd, (off_t)body_aglinment_size, SEEK_SET))
goto read_failed;
}
fclose(fd);
return 0;
read_failed:
if (g_node != NULL) {
free(g_node);
g_node = NULL;
}
fclose(fd);
g_node_num = 0;
*err_no = errno;
return READ_FILE_ERROR;
}
/* g_isCmRead means whether need save data in global var */
void set_cm_read_flag(bool falg)
{
g_isCmRead = falg;
}
/* read the logic_cluster_name.txt file */
int read_logic_cluster_name(const char* file_path, logicClusterList& lcList, int* err_no)
{
FILE* fd = NULL;
uint32 logic_cluster_Index = 0;
fd = fopen(file_path, "r");
if (fd == NULL) {
*err_no = errno;
return OPEN_FILE_ERROR;
}
while (logic_cluster_Index < LOGIC_CLUSTER_NUMBER && !feof(fd)) {
if (fscanf_s(fd, "%s\n", lcList.lcInfoArray[logic_cluster_Index].logicClusterName, CM_LOGIC_CLUSTER_NAME_LEN) <
0) {
fclose(fd);
*err_no = errno;
return READ_FILE_ERROR;
}
if (strlen(lcList.lcInfoArray[logic_cluster_Index].logicClusterName) != 0) {
lcList.lcInfoArray[logic_cluster_Index].logicClusterId = logic_cluster_Index;
logic_cluster_Index++;
}
}
lcList.logicClusterCount = logic_cluster_Index;
if (g_isCmRead) {
set_para_for_cm_read(lcList);
}
fclose(fd);
return 0;
}
static int read_all_logic_config_file(logicClusterList lcList, int* err_no)
{
uint32 logic_cluster_index = 0;
int status = 0;
for (logic_cluster_index = 0; logic_cluster_index < lcList.logicClusterCount; logic_cluster_index++) {
status = read_logic_config_file(lcList.lcInfoArray[logic_cluster_index], err_no);
/* means has found dn's logicCluster */
if (!g_isCmRead && g_logicClusterName[0] != '\0') {
return 0;
}
if (status == 0 && g_logicClusterStaticConfig[logic_cluster_index].logicClusterNodeHeader.node == 0) {
*err_no = errno;
return READ_FILE_ERROR;
} else if (status != 0) {
return status;
}
}
return 0;
}
static int read_logic_config_file(logicClusterInfo lcInfo, int* err_no)
{
FILE* fd = NULL;
int rcs = 0;
uint32 ii = 0;
uint32 header_size = 0;
uint32 node_index = 0;
uint32 logicClusterNodeNum = 0;
uint32 header_aglinment_size = 0;
long current_pos = 0;
uint32 datanodeCount = 0;
uint32 datanodeId = 0;
char file_path[MAX_PATH_LEN] = {0};
char exec_path[MAX_PATH_LEN] = {0};
errno_t rc = 0;
logicClusterStaticConfig* LCStaticConfig = &g_logicClusterStaticConfig[lcInfo.logicClusterId];
rcs = cmconfig_getenv("GAUSSHOME", exec_path, sizeof(exec_path));
if (rcs != EOK) {
fprintf(stderr, "Get GAUSSHOME failed, please check.\n");
return -1;
} else {
rc = snprintf_s(file_path,
MAX_PATH_LEN,
MAX_PATH_LEN - 1,
"%s/bin/%s.cluster_static_config",
exec_path,
lcInfo.logicClusterName);
securec_check_ss_c(rc, "\0", "\0");
}
canonicalize_path(file_path);
fd = fopen(file_path, "r");
if (fd == NULL) {
*err_no = errno;
return OPEN_FILE_ERROR;
}
/********************************************************************************
* DISCLAIMER: Any Change in file format need to update the Version Number *
* Version Number Offset should not be changed *
********************************************************************************/
// read head info
FREAD(&LCStaticConfig->logicClusterNodeHeader.crc, 1, sizeof(uint32), fd);
FREAD(&LCStaticConfig->logicClusterNodeHeader.len, 1, sizeof(uint32), fd);
FREAD(&LCStaticConfig->logicClusterNodeHeader.version, 1, sizeof(uint32), fd);
FREAD(&LCStaticConfig->logicClusterNodeHeader.time, 1, sizeof(int64), fd);
FREAD(&LCStaticConfig->logicClusterNodeHeader.nodeCount, 1, sizeof(uint32), fd);
FREAD(&LCStaticConfig->logicClusterNodeHeader.node, 1, sizeof(uint32), fd);
header_size = sizeof(staticConfigHeader);
header_aglinment_size =
(header_size / AGLINMENT_SIZE + ((header_size % AGLINMENT_SIZE) == 0 ? 0 : 1)) * AGLINMENT_SIZE;
if (fseek(fd, (off_t)(header_aglinment_size), SEEK_SET) != 0)
READ_LOGICAL_CONFIG_FAILED;
logicClusterNodeNum = LCStaticConfig->logicClusterNodeHeader.nodeCount;
/*
* Check whether the number of logic cluster nodes read from the configuration file is greater
* than the maximum number limit of logic cluster nodes.
*/
if (logicClusterNodeNum == 0 || logicClusterNodeNum > CM_NODE_MAXNUM) {
fprintf(stderr,
"The logic cluster node number [count=%u] is greater than the max node number [max_num=%d].\n",
logicClusterNodeNum,
CM_NODE_MAXNUM);
fclose(fd);
return -1;
}
if (g_isCmRead) {
/* initialize logic cluster node ptr to reread the node info */
if (LCStaticConfig->logicClusterNode != NULL) {
free(LCStaticConfig->logicClusterNode);
LCStaticConfig->logicClusterNode = NULL;
}
LCStaticConfig->logicClusterNode =
(staticLogicNodeConfig*)malloc(sizeof(staticLogicNodeConfig) * logicClusterNodeNum);
if (LCStaticConfig->logicClusterNode == NULL) {
fclose(fd);
return OUT_OF_MEMORY;
} else {
rcs = memset_s(LCStaticConfig->logicClusterNode,
sizeof(staticLogicNodeConfig) * logicClusterNodeNum,
0,
sizeof(staticLogicNodeConfig) * logicClusterNodeNum);
securec_check_c(rcs, "\0", "\0");
}
}
for (ii = 0; ii < logicClusterNodeNum; ii++) {
uint32 jj = 0;
uint32 kk = 0;
long body_aglinment_size = 0;
uint32 datanode_index = 0;
/* read node header info */
if (g_isCmRead) {
FREAD(&LCStaticConfig->logicClusterNode[ii].crc, 1, sizeof(uint32), fd);
FREAD(&LCStaticConfig->logicClusterNode[ii].node, 1, sizeof(uint32), fd);
FREAD(LCStaticConfig->logicClusterNode[ii].nodeName, 1, (CM_NODE_NAME - 1), fd);
LCStaticConfig->logicClusterNode[ii].nodeName[CM_NODE_NAME - 1] = '\0';
check_input_for_security(LCStaticConfig->logicClusterNode[ii].nodeName);
FREAD(&LCStaticConfig->logicClusterNode[ii].backIpCount, 1, sizeof(uint32), fd);
if (LCStaticConfig->logicClusterNode[ii].backIpCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(LCStaticConfig->logicClusterNode[ii].backIps[jj], 1, CM_IP_LENGTH, fd);
LCStaticConfig->logicClusterNode[ii].backIps[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(LCStaticConfig->logicClusterNode[ii].backIps[jj]);
}
FREAD(&LCStaticConfig->logicClusterNode[ii].sshCount, 1, sizeof(uint32), fd);
if (LCStaticConfig->logicClusterNode[ii].sshCount > CM_IP_NUM) {
goto read_failed;
}
for (jj = 0; jj < CM_IP_NUM; jj++) {
FREAD(LCStaticConfig->logicClusterNode[ii].sshChannel[jj], 1, CM_IP_LENGTH, fd);
LCStaticConfig->logicClusterNode[ii].sshChannel[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(LCStaticConfig->logicClusterNode[ii].sshChannel[jj]);
}
/* find the correspond node in g_node */
for (node_index = 0; node_index < g_nodeHeader.nodeCount; node_index++) {
if (g_node[node_index].node == LCStaticConfig->logicClusterNode[ii].node) {
break;
}
}
} else {
/* seek to datanodeInfo */
current_pos = ftell(fd);
int node_head_size = sizeof(uint32) * 4 + (CM_NODE_NAME - 1) + (CM_IP_NUM * CM_IP_LENGTH * 2);
body_aglinment_size = current_pos + (long)node_head_size;
if (fseek(fd, (off_t)body_aglinment_size, SEEK_SET)) {
READ_LOGICAL_CONFIG_FAILED;
}
}
/* read DNs info, the datanodeCount is the num of datanode in logic cluster */
FREAD(&datanodeCount, 1, sizeof(uint32), fd);
/*
* Check whether the number of data nodes read from the configuration file is greater
* than the maximum data node limit of a single node.
*/
if (datanodeCount > CM_MAX_DATANODE_PER_NODE) {
fprintf(stderr,
"The logic cluster data node number [count=%u] is greater than the max data node number per node "
"[max_num=%d].\n",
datanodeCount,
CM_MAX_DATANODE_PER_NODE);
fclose(fd);
return -1;
}
if (g_isCmRead) {
LCStaticConfig->logicClusterNode[ii].datanodeCount = datanodeCount;
}
for (kk = 0; kk < datanodeCount; kk++) {
FREAD(&datanodeId, 1, sizeof(uint32), fd);
if (g_isCmRead) {
LCStaticConfig->logicClusterNode[ii].datanodeId[kk] = datanodeId;
/* Traverse all nodes and find the corresponding datanodeid and assignment for LogicClusterName */
for (datanode_index = 0; datanode_index < g_node[node_index].datanodeCount; datanode_index++) {
if (g_node[node_index].datanode[datanode_index].datanodeId ==
LCStaticConfig->logicClusterNode[ii].datanodeId[kk]) {
rc = strcpy_s(g_node[node_index].datanode[datanode_index].LogicClusterName,
CM_LOGIC_CLUSTER_NAME_LEN,
g_logicClusterStaticConfig[lcInfo.logicClusterId].LogicClusterName);
securec_check_c(rc, "\0", "\0");
break;
}
}
} else if (datanodeId == g_datanodeid) {
rc = strcpy_s(g_logicClusterName, CM_LOGIC_CLUSTER_NAME_LEN, lcInfo.logicClusterName);
securec_check_c(rc, "\0", "\0");
fclose(fd);
return 0;
}
/* seek to next datanode */
current_pos = ftell(fd);
body_aglinment_size = current_pos + sizeof(dataNodeInfo) - sizeof(uint32) -
sizeof(peerDatanodeInfo) * CM_MAX_DATANODE_STANDBY_NUM - CM_LOGIC_CLUSTER_NAME_LEN;
if (fseek(fd, (off_t)body_aglinment_size, SEEK_SET)) {
READ_LOGICAL_CONFIG_FAILED;
}
}
/* seek to next node */
current_pos = ftell(fd) + (long)(sizeof(uint32) * 2);
body_aglinment_size =
(current_pos / AGLINMENT_SIZE + ((current_pos % AGLINMENT_SIZE == 0) ? 0 : 1)) * AGLINMENT_SIZE;
if (fseek(fd, (off_t)body_aglinment_size, SEEK_SET)) {
READ_LOGICAL_CONFIG_FAILED;
}
}
/* means not found dn's logicCluster */
if (!g_isCmRead) {
g_logicClusterName[0] = '\0';
}
fclose(fd);
return 0;
read_failed:
READ_LOGICAL_CONFIG_FAILED;
}
char* getAZNamebyPriority(uint32 azPriority)
{
for (uint32 i = 0; i < g_node_num; i++) {
if (azPriority == g_node[i].azPriority) {
return g_node[i].azName;
}
}
return NULL;
}
bool read_single_file_local(uint32 node_index)
{
int ret = 0;
bool find = false;
bool isLocal = false;
for(uint32 i = 0; i < g_node_num; i++) {
find = false;
if (node_index >= CM_MAX_DATANODE_PER_NODE) {
break;
}
for(uint32 j = 0; j < g_node[i].datanodeCount; j++) {
if(strcmp(g_node[node_index].datanode[node_index].datanodeLocalDataPath,
g_node[i].datanode[j].datanodeLocalDataPath) == 0) {
if(g_nodeHeader.node == g_node[i].node) {
isLocal = true;
}
find = true;
g_node[i].datanodeCount = 1;
if(j > 0) {
ret = memcpy_s((void *)(&(g_node[i].datanode[0])),
sizeof(dataNodeInfo),
(void*)(&(g_node[i].datanode[j])),
sizeof(dataNodeInfo));
securec_check_c(ret,"\0", "\0");
}
}
for(uint32 m = 0; (m < g_dn_replication_num - 1) && !find; m++) {
if (m >= CM_MAX_DATANODE_STANDBY_NUM) {
break;
}
if(strcmp(g_node[node_index].datanode[node_index].peerDatanodes[m].datanodePeerDataPath,
g_node[i].datanode[j].datanodeLocalDataPath) == 0
&& strcmp(g_node[node_index].datanode[node_index].peerDatanodes[m].datanodePeerHAIP[0],
g_node[i].datanode[j].datanodeListenIP[0]) == 0) {
if(g_nodeHeader.node == g_node[i].node) {
isLocal = false;
}
find = true;
g_node[i].datanodeCount = 1;
if(j > 0) {
ret = memcpy_s((void *)(&(g_node[i].datanode[0])),
sizeof(dataNodeInfo),
(void *)(&(g_node[i].datanode[j])),
sizeof(dataNodeInfo));
securec_check_c(ret,"\0", "\0");
}
break;
}
}
if(find) {
break;
}
}
if(!find) {
g_node[i].datanodeCount = 0;
}
}
return isLocal;
}
int read_single_file(const char *file_path, int *err_no, uint32 nodeId, const char *dataPath)
{
int ret = 0;
ret = read_config_file(file_path, err_no);
if(ret != 0) {
return ret;
}
uint32 node_index = 0;
bool find = false;
bool isLocal = false;
for(uint32 i = 0; i < g_node_num; i++) {
if(g_node[i].datanodeCount > CM_MAX_DATANODE_PER_NODE) {
break;
}
if(g_node[i].node == nodeId) {
for(uint32 j = 0; j < g_node[i].datanodeCount; j++) {
if(0 == strcmp(dataPath, g_node[i].datanode[j].datanodeLocalDataPath) ) {
node_index = i;
find = true;
}
}
}
}
if(!find) {
return -1;
}
isLocal = read_single_file_local(node_index);
if(!isLocal) {
return -2;
}
return 0;
}
int get_dynamic_dn_role(void)
{
char path[MAXPGPATH];
int nRet = 0;
FILE* fp = NULL;
char line_info[MAXPGPATH] = {0};
char* node_name = NULL;
char* dn_role = NULL;
uint32 nodeidx = 0;
struct stat statbuf;
char* gausshome = gs_getenv_r("GAUSSHOME");
check_input_for_security(gausshome);
nRet = snprintf_s(path, MAXPGPATH, MAXPGPATH - 1, "%s/bin/%s", gausshome, DYNAMIC_DNROLE_FILE);
securec_check_ss_c(nRet, "\0", "\0");
if (lstat(path, &statbuf) != 0) {
return 0;
}
fp = fopen(path, "r");
if (fp == NULL) {
return OPEN_FILE_ERROR;
}
while ((fgets(line_info, 1023 - 1, fp)) != NULL) {
line_info[(int)strlen(line_info) - 1] = '\0';
node_name = strtok_r(line_info, "=", &dn_role);
for (nodeidx = 0; node_name && (nodeidx < g_node_num); nodeidx++) {
if (strncmp(g_node[nodeidx].nodeName, node_name, strlen(node_name)) == 0){
g_node[nodeidx].datanode[0].datanodeRole = (uint32)atoi(dn_role);
break;
}
}
}
(void)fclose(fp);
return 0;
}
/*
******************************************************************************
Function : get_nodename_list_by_AZ
Description : get node name list by azName, don't include local node
Input : AZName -
Output : nodename list
Return : None
******************************************************************************
*/
int get_nodename_list_by_AZ(const char* AZName, const char* data_dir, char** nodeNameList)
{
uint32 nodeidx = 0;
uint32 count = 0;
uint32 len = 0;
uint32 i = 0;
uint32 j = 0;
AZList* azList = NULL;
uint32 tmpAZPriority = 0;
char* tmpNodeName = NULL;
size_t buflen = 1;
char* buffer = NULL;
int nRet = 0;
size_t curlen = 0;
// get the node number which in azName
for (nodeidx = 0; nodeidx < g_node_num; nodeidx++) {
if (strcmp(g_node[nodeidx].azName, AZName) == 0) {
count++;
}
}
// maybe the AZName is incorrect, so return null
if (count < 1) {
return 0;
}
// init azList, i must less than count
azList = (AZList*)malloc(sizeof(AZList) * count);
if (NULL == azList) {
return OUT_OF_MEMORY;
}
dataNodeInfo* dni = NULL;
{
uint32 idx = 0;
for (idx = 0; idx < g_currentNode->datanodeCount; idx++) {
dataNodeInfo* dni_tmp = &(g_currentNode->datanode[idx]);
if (strcmp(dni_tmp->datanodeLocalDataPath, data_dir) == 0) {
dni = dni_tmp;
break;
}
}
}
if (dni == NULL) {
free(azList);
azList = NULL;
return OPEN_FILE_ERROR;
}
for (nodeidx = 0, i = 0; nodeidx < g_node_num; nodeidx++) {
staticNodeConfig* dest = &(g_node[nodeidx]);
bool get_dn_in_same_shard = false;
if (nodeidx != g_local_node_idx && strcmp(dest->azName, AZName) == 0) {
uint32 l = 0;
for (l = 0; l < dest->datanodeCount && !get_dn_in_same_shard; l++) {
dataNodeInfo* dn = &(dest->datanode[l]);
int n = 0;
if (dn->datanodeId == 0)
continue;
if (dn->datanodeRole == CASCADE_STANDBY_TYPE)
continue;
for (n = 0; n < CM_MAX_DATANODE_STANDBY_NUM && !get_dn_in_same_shard; n++) {
peerDatanodeInfo* peer_datanode = &(dn->peerDatanodes[n]);
if (strlen(peer_datanode->datanodePeerHAIP[0]) == 0)
continue;
if (strcmp(peer_datanode->datanodePeerHAIP[0], dni->datanodeLocalHAIP[0]) == 0 &&
peer_datanode->datanodePeerHAPort == dni->datanodeLocalHAPort) {
char dn_instance_id[64] = {0};
int nRet = snprintf_s(dn_instance_id,
sizeof(dn_instance_id) / sizeof(char),
sizeof(dn_instance_id) / sizeof(char) - 1,
"dn_%4u",
dn->datanodeId);
securec_check_ss_c(nRet, "\0", "\0");
azList[i].nodeName = strdup(dn_instance_id);
azList[i].azPriority = dest->azPriority;
buflen += strlen(azList[i].nodeName) + 1;
i++;
get_dn_in_same_shard = true;
break;
}
}
}
}
}
// the real node name number
len = i;
// sort by azPriority asc
for (i = 0; len > 0 && i < len - 1; i++) {
for (j = 0; len > 0 && j < len - i - 1; j++) {
if (azList[j].azPriority > azList[j + 1].azPriority) {
// swap azPriority
tmpAZPriority = azList[j].azPriority;
azList[j].azPriority = azList[j + 1].azPriority;
azList[j + 1].azPriority = tmpAZPriority;
// swap nodename
tmpNodeName = strdup(azList[j].nodeName);
free(azList[j].nodeName);
azList[j].nodeName = NULL;
azList[j].nodeName = strdup(azList[j + 1].nodeName);
free(azList[j + 1].nodeName);
azList[j + 1].nodeName = NULL;
azList[j + 1].nodeName = strdup(tmpNodeName);
free(tmpNodeName);
tmpNodeName = NULL;
}
}
}
// Exclude the local node name and output the remaining information
buffer = (char*)malloc(sizeof(char) * (buflen + 1));
if (NULL == buffer) {
// free AZList
for (i = 0; i < len; i++) {
if (azList[i].nodeName != NULL) {
free(azList[i].nodeName);
azList[i].nodeName = NULL;
}
}
free(azList);
azList = NULL;
return OUT_OF_MEMORY;
}
nRet = memset_s(buffer, buflen + 1, 0, buflen + 1);
securec_check_c(nRet, buffer, "\0");
for (i = 0; i < len; i++) {
if (strcmp(g_local_node_name, azList[i].nodeName) == 0) {
continue;
}
// the type like this: node1,node2,
nRet = snprintf_s(buffer + curlen, (buflen + 1 - curlen), (buflen - curlen), "%s,", azList[i].nodeName);
securec_check_ss_c(nRet, buffer, "\0");
curlen = curlen + nRet;
}
// skip the last character ','
if (strlen(buffer) >= 1) {
buffer[strlen(buffer) - 1] = '\0';
}
// free AZList
for (i = 0; i < len; i++) {
if (azList[i].nodeName != NULL) {
free(azList[i].nodeName);
azList[i].nodeName = NULL;
}
}
free(azList);
azList = NULL;
*nodeNameList = buffer;
return 0;
}
/*
******************************************************************************
Function : checkPath
Description :
Input : fileName
Output : None
Return : None
******************************************************************************
*/
int checkPath(const char* fileName)
{
char* retVal = NULL;
char realFileName[MAX_REALPATH_LEN + 1] = {0};
retVal = realpath(fileName, realFileName);
if (NULL == retVal) {
return -1;
}
return 0;
}
bool has_static_config()
{
char path[MAXPGPATH];
int nRet = 0;
struct stat statbuf;
char* gausshome = gs_getenv_r("GAUSSHOME");
check_input_for_security(gausshome);
if (NULL != g_lcname) {
nRet = snprintf_s(path, MAXPGPATH, MAXPGPATH - 1, "%s/bin/%s.%s", gausshome, g_lcname, STATIC_CONFIG_FILE);
} else {
nRet = snprintf_s(path, MAXPGPATH, MAXPGPATH - 1, "%s/bin/%s", gausshome, STATIC_CONFIG_FILE);
}
securec_check_ss_c(nRet, "\0", "\0");
if (checkPath(path) != 0) {
return false;
}
if (lstat(path, &statbuf) == 0) {
return true;
}
return false;
}
/*
******************************************************************************
******************************************************************************
Function : check_datanodename_value
Description : check the input datanode Name.
Input :nodeName data node name
return :true input datanode name is correct
false input datanode name is incorrect
******************************************************************************
*/
bool CheckDataNameValue(const char *datanodeName, const char *dataDir)
{
int nRet;
uint32 nodeIdx = 0;
uint32 datanodeIdx = 0;
int dnIdMaxLen = 64;
char dnId[dnIdMaxLen];
if ((datanodeName == NULL) || (*datanodeName == '\0')) {
return false;
}
dataNodeInfo *dnI = NULL;
for (datanodeIdx = 0; datanodeIdx < g_currentNode->datanodeCount; datanodeIdx++) {
dataNodeInfo *dniTmp = &(g_currentNode->datanode[datanodeIdx]);
if (strcmp(dniTmp->datanodeLocalDataPath, dataDir) == 0) {
dnI = dniTmp;
break;
}
}
if (dnI == NULL) {
fprintf(stderr, "Failed: cannot find the expected data dir\n");
return false;
}
for (nodeIdx = 0; nodeIdx < g_node_num; ++nodeIdx) {
staticNodeConfig *dest = &(g_node[nodeIdx]);
for (datanodeIdx = 0; datanodeIdx < dest->datanodeCount; ++datanodeIdx) {
dataNodeInfo *dn = &(dest->datanode[datanodeIdx]);
if (dn->datanodeId == 0 || dn->datanodeId == dnI->datanodeId) {
continue;
}
nRet = memset_s(dnId, sizeof(dnId), '\0', sizeof(dnId));
securec_check_c(nRet, "\0", "\0");
nRet = snprintf_s(
dnId, sizeof(dnId) / sizeof(char), sizeof(dnId) / sizeof(char) - 1, "dn_%4d", dn->datanodeId);
securec_check_ss_c(nRet, "\0", "\0");
if (strncmp(dnId, datanodeName,
((strlen(dnId) > strlen(datanodeName)) ? strlen(dnId) : strlen(datanodeName))) != 0) {
continue;
}
for (int peerIndex = 0; peerIndex < CM_MAX_DATANODE_STANDBY_NUM; ++peerIndex) {
peerDatanodeInfo *peerDatanode = &(dnI->peerDatanodes[peerIndex]);
if (strlen(peerDatanode->datanodePeerHAIP[0]) == 0) {
continue;
}
if (strcmp(peerDatanode->datanodePeerHAIP[0], dn->datanodeLocalHAIP[0]) == 0 &&
peerDatanode->datanodePeerHAPort == dn->datanodeLocalHAPort) {
return true;
}
}
}
}
return false;
}