* Copyright (c) 2021 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_config.cpp
* functions to read cluster static config file
*
* IDENTIFICATION
* src/lib/config/cm_config.cpp
*
* -------------------------------------------------------------------------
*/
#include <map>
#include <algorithm>
#include <string>
#include "securec.h"
#include "securec_check.h"
#include "common/config/cm_config.h"
using namespace std;
#define READ_LOGICAL_CONFIG_FAILED(fd) \
do { \
if (NULL != LCStaticConfig->logicClusterNode) { \
free(LCStaticConfig->logicClusterNode); \
LCStaticConfig->logicClusterNode = NULL; \
} \
(void)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;
ClusterType g_clusterType = InvalidCluster;
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;
uint32 g_local_node_idx = 0;
char *g_local_node_name = NULL;
char *g_lcname = NULL;
uint32 g_datanodeid = 0;
char *g_logicClusterName = NULL;
bool g_isCmRead = false;
#define FREAD1(ptr, nitems, size, stream) \
do { \
if (fread((ptr), (size), (nitems), (stream)) != (nitems)) \
return READ_FILE_ERROR; \
} while (0)
#define FREAD(ptr, nitems, size, stream) \
do { \
if (fread((ptr), (size), (nitems), (stream)) != (nitems)) \
goto read_failed; \
} while (0)
#define RETURN_IFERR(ret) \
do { \
if ((ret) != 0) { \
return (ret); \
} \
} while (0)
static int read_all_logic_config_file(const logicClusterList lcList, int *err_no);
static int read_logic_config_file(const logicClusterInfo lcInfo, int *err_no);
static bool is_valid_logic_cluster_name(const char *name);
static bool is_path_under_directory(const char *path, const char *dir);
void check_input_for_security(const char *input)
{
const char *danger_character_list[] = {"|", ";", "&", "$", "<", ">", "`", "\\", "'", "\"", "{", "}",
"(", ")", "[", "]", "~", "*", "?", "!", "\n", NULL};
for (int32 i = 0; danger_character_list[i] != NULL; i++) {
if (strstr(input, danger_character_list[i]) != NULL) {
(void)fprintf(stderr, "FATAL 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)
{
if (env_var == NULL) {
(void)fprintf(stderr, "cmconfig_getenv: invalid env_var !\n");
return -1;
}
char *env_value = getenv(env_var);
if (env_value == NULL || env_value[0] == '\0') {
(void)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);
int32 rc = strcpy_s(output_env_value, env_value_len, env_value);
if (rc != EOK) {
(void)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 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;
}
* 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 {
(void)nameAndPriority.emplace(pair<string, uint32>(azName, azPriority));
}
}
it = nameAndPriority.begin();
for (uint32 i = 0; i < azNumber; ++i) {
if (it == nameAndPriority.end()) {
break;
}
priorities[i] = it->second;
(void)(it++);
}
sort(priorities, priorities + azNumber);
g_az_master = priorities[zeroIndex];
g_az_slave = priorities[++zeroIndex];
g_az_arbiter = priorities[++zeroIndex];
}
using ReadConfigContext = struct StReadConfigContext {
uint32 cmServerNum;
uint32 gtmNum;
uint32 dnReplicationNum;
uint32 etcdNum;
uint32 cnNum;
uint32 datanodeMirrorID;
bool datanodeMirrorIDInit;
};
static FILE *open_config_file(const char *file_path, int *err_no)
{
char configFilePath[MAX_PATH_LEN];
int32 rcs = strncpy_s(configFilePath, MAX_PATH_LEN, file_path, MAX_PATH_LEN - 1);
securec_check_c(rcs, "", "");
canonicalize_path(configFilePath);
FILE *fd = fopen(configFilePath, "r");
if (fd == NULL) {
*err_no = errno;
return NULL;
}
return fd;
}
static int read_config_header(FILE *fd)
{
const uint32 v3SingleInstClusterVersionBegin = 9301;
const uint32 v3SingleInstClusterVersionEnd = 10301;
const uint32 headerVersion1 = 100;
const uint32 headerVersion2 = 200;
const uint32 headerVersion3 = 300;
const uint32 headerVersion4 = 400;
const uint32 headerVersion5 = 500;
* DISCLAIMER: Any Change in file format need to update the Version Number *
* Version Number Offset should not be changed *
********************************************************************************/
int32 rcs = memset_s(&g_nodeHeader, sizeof(staticConfigHeader), 0, sizeof(staticConfigHeader));
securec_check_c(rcs, "", "");
FREAD1(&g_nodeHeader.crc, 1, sizeof(uint32), fd);
FREAD1(&g_nodeHeader.len, 1, sizeof(uint32), fd);
FREAD1(&g_nodeHeader.version, 1, sizeof(uint32), fd);
if (g_nodeHeader.version <= headerVersion1) {
g_single_node_cluster = false;
g_multi_az_cluster = false;
g_clusterType = MasterStandbyDummyCluster;
} else if ((g_nodeHeader.version > headerVersion1) && (g_nodeHeader.version <= headerVersion2)) {
g_single_node_cluster = true;
g_multi_az_cluster = false;
g_clusterType = SingleCluster;
} else if ((g_nodeHeader.version > headerVersion2) && (g_nodeHeader.version <= headerVersion3)) {
g_multi_az_cluster = true;
g_one_master_multi_slave = true;
g_clusterType = SinglePrimaryMultiStandbyCluster;
} else if ((g_nodeHeader.version > headerVersion3) && (g_nodeHeader.version <= headerVersion4)) {
g_only_dn_cluster = true;
g_multi_az_cluster = true;
g_one_master_multi_slave = true;
g_clusterType = SingleInstCluster;
} else if ((g_nodeHeader.version >= headerVersion4) && (g_nodeHeader.version <= headerVersion5)) {
g_single_node_cluster = true;
g_only_dn_cluster = true;
g_multi_az_cluster = false;
g_clusterType = SingleInstClusterCent;
} else if ((g_nodeHeader.version >= v3SingleInstClusterVersionBegin) &&
(g_nodeHeader.version <= v3SingleInstClusterVersionEnd)) {
g_only_dn_cluster = true;
g_multi_az_cluster = true;
g_one_master_multi_slave = true;
g_clusterType = V3SingleInstCluster;
}
FREAD1(&g_nodeHeader.time, 1, sizeof(int64), fd);
FREAD1(&g_nodeHeader.nodeCount, 1, sizeof(uint32), fd);
FREAD1(&g_nodeHeader.node, 1, sizeof(uint32), fd);
if (g_nodeHeader.nodeCount > CM_NODE_MAXNUM || g_nodeHeader.nodeCount == 0) {
return READ_FILE_ERROR;
}
return 0;
}
static int alloc_node_buffer(bool inReload)
{
int rcs = 0;
if (inReload) {
return 0;
}
if (g_node == NULL) {
g_node = (staticNodeConfig *)malloc(sizeof(staticNodeConfig) * CM_NODE_MAXNUM);
if (g_node == NULL) {
return OUT_OF_MEMORY;
}
}
rcs = memset_s(g_node, sizeof(staticNodeConfig) * CM_NODE_MAXNUM,
0, sizeof(staticNodeConfig) * CM_NODE_MAXNUM);
if (rcs != EOK && rcs != ERANGE) {
(void)printf("FATAL at %s : %d : Initialize is failed, error num is: %d.\n", __FUNCTION__, __LINE__, rcs);
free(g_node);
g_node = NULL;
exit(1);
}
return 0;
}
static int ReadNodeInfo(FILE *fd, uint32 nodeId)
{
FREAD1(&g_node[nodeId].crc, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].node, 1, sizeof(uint32), fd);
FREAD1(g_node[nodeId].nodeName, 1, (CM_NODE_NAME - 1), fd);
g_node[nodeId].nodeName[CM_NODE_NAME - 1] = '\0';
check_input_for_security(g_node[nodeId].nodeName);
max_node_name_len = (max_node_name_len < (uint32)strlen(g_node[nodeId].nodeName)) ?
(uint32)strlen(g_node[nodeId].nodeName) : max_node_name_len;
if (g_clusterType >= SinglePrimaryMultiStandbyCluster && g_clusterType <= V3SingleInstCluster) {
FREAD1(g_node[nodeId].azName, 1, (CM_AZ_NAME - 1), fd);
g_node[nodeId].azName[CM_AZ_NAME - 1] = '\0';
check_input_for_security(g_node[nodeId].azName);
FREAD1(&g_node[nodeId].azPriority, 1, sizeof(uint32), fd);
max_az_name_len = (max_az_name_len < (uint32)strlen(g_node[nodeId].azName)) ?
(uint32)strlen(g_node[nodeId].azName) : max_az_name_len;
}
return 0;
}
static int ReadNodeBackIp(FILE *fd, uint32 nodeId)
{
FREAD1(&g_node[nodeId].backIpCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].backIpCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int jj = 0; jj < CM_IP_NUM; jj++) {
FREAD1(g_node[nodeId].backIps[jj], 1, CM_IP_LENGTH, fd);
g_node[nodeId].backIps[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].backIps[jj]);
}
return 0;
}
static int ReadNodeSsh(FILE *fd, uint32 nodeId)
{
FREAD1(&g_node[nodeId].sshCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].sshCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int jj = 0; jj < CM_IP_NUM; jj++) {
FREAD1(g_node[nodeId].sshChannel[jj], 1, CM_IP_LENGTH, fd);
g_node[nodeId].sshChannel[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].sshChannel[jj]);
}
return 0;
}
static int ReadNodeCmserver(FILE *fd, uint32 nodeId, ReadConfigContext *ctx)
{
FREAD1(&g_node[nodeId].cmServerId, 1, sizeof(uint32), fd);
if (g_node[nodeId].cmServerId != 0) {
ctx->cmServerNum++;
}
FREAD1(&g_node[nodeId].cmServerMirrorId, 1, sizeof(uint32), fd);
FREAD1(g_node[nodeId].cmDataPath, 1, CM_PATH_LENGTH, fd);
g_node[nodeId].cmDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].cmDataPath);
max_cmpath_len = (max_cmpath_len < (uint32)strlen(g_node[nodeId].cmDataPath)) ?
(uint32)strlen(g_node[nodeId].cmDataPath) : max_cmpath_len;
FREAD1(&g_node[nodeId].cmServerLevel, 1, sizeof(uint32), fd);
FREAD1(g_node[nodeId].cmServerFloatIP, 1, CM_IP_LENGTH, fd);
g_node[nodeId].cmServerFloatIP[CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].cmServerFloatIP);
FREAD1(&g_node[nodeId].cmServerListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].cmServerListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int jj = 0; jj < CM_IP_NUM; jj++) {
FREAD1(g_node[nodeId].cmServer[jj], 1, CM_IP_LENGTH, fd);
g_node[nodeId].cmServer[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].cmServer[jj]);
}
FREAD1(&g_node[nodeId].port, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].cmServerLocalHAListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].cmServerLocalHAListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int jj = 0; jj < CM_IP_NUM; jj++) {
FREAD1(g_node[nodeId].cmServerLocalHAIP[jj], 1, CM_IP_LENGTH, fd);
g_node[nodeId].cmServerLocalHAIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].cmServerLocalHAIP[jj]);
}
FREAD1(&g_node[nodeId].cmServerLocalHAPort, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].cmServerRole, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].cmServerPeerHAListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].cmServerPeerHAListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int jj = 0; jj < CM_IP_NUM; jj++) {
FREAD1(g_node[nodeId].cmServerPeerHAIP[jj], 1, CM_IP_LENGTH, fd);
g_node[nodeId].cmServerPeerHAIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].cmServerPeerHAIP[jj]);
}
FREAD1(&g_node[nodeId].cmServerPeerHAPort, 1, sizeof(uint32), fd);
return 0;
}
static int ReadNodeGtm(FILE *fd, uint32 nodeId, ReadConfigContext *ctx)
{
FREAD1(&g_node[nodeId].cmAgentId, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].cmAgentMirrorId, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].cmAgentListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].cmAgentListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int jj = 0; jj < CM_IP_NUM; jj++) {
FREAD1(g_node[nodeId].cmAgentIP[jj], 1, CM_IP_LENGTH, fd);
g_node[nodeId].cmAgentIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].cmAgentIP[jj]);
}
FREAD1(&g_node[nodeId].gtmId, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].gtmMirrorId, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].gtm, 1, sizeof(uint32), fd);
if (g_node[nodeId].gtm == 1) {
ctx->gtmNum++;
}
if (g_node[nodeId].gtm == 1 && g_node[nodeId].gtmRole == PRIMARY_GTM) {
g_cluster_total_instance_group_num++;
}
FREAD1(g_node[nodeId].gtmLocalDataPath, 1, CM_PATH_LENGTH, fd);
g_node[nodeId].gtmLocalDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].gtmLocalDataPath);
max_gtmpath_len = (max_gtmpath_len < (uint32)strlen(g_node[nodeId].gtmLocalDataPath)) ?
(uint32)strlen(g_node[nodeId].gtmLocalDataPath) : max_gtmpath_len;
FREAD1(&g_node[nodeId].gtmLocalListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].gtmLocalListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int jj = 0; jj < CM_IP_NUM; jj++) {
FREAD1(g_node[nodeId].gtmLocalListenIP[jj], 1, CM_IP_LENGTH, fd);
g_node[nodeId].gtmLocalListenIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].gtmLocalListenIP[jj]);
}
FREAD1(&g_node[nodeId].gtmLocalport, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].gtmRole, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].gtmLocalHAListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].gtmLocalHAListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int jj = 0; jj < CM_IP_NUM; jj++) {
FREAD1(g_node[nodeId].gtmLocalHAIP[jj], 1, CM_IP_LENGTH, fd);
g_node[nodeId].gtmLocalHAIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].gtmLocalHAIP[jj]);
}
FREAD1(&g_node[nodeId].gtmLocalHAPort, 1, sizeof(uint32), fd);
FREAD1(g_node[nodeId].gtmPeerDataPath, 1, CM_PATH_LENGTH, fd);
g_node[nodeId].gtmPeerDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].gtmPeerDataPath);
FREAD1(&g_node[nodeId].gtmPeerHAListenCount, 1, sizeof(uint32), fd);
for (int jj = 0; jj < CM_IP_NUM; jj++) {
FREAD1(g_node[nodeId].gtmPeerHAIP[jj], 1, CM_IP_LENGTH, fd);
g_node[nodeId].gtmPeerHAIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].gtmPeerHAIP[jj]);
}
FREAD1(&g_node[nodeId].gtmPeerHAPort, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].gtmProxyId, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].gtmProxyMirrorId, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].gtmProxy, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].gtmProxyListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].gtmProxyListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int jj = 0; jj < CM_IP_NUM; jj++) {
FREAD1(g_node[nodeId].gtmProxyListenIP[jj], 1, CM_IP_LENGTH, fd);
g_node[nodeId].gtmProxyListenIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].gtmProxyListenIP[jj]);
}
FREAD1(&g_node[nodeId].gtmProxyPort, 1, sizeof(uint32), fd);
return 0;
}
static int ReadNodeCn(FILE *fd, uint32 nodeId)
{
FREAD1(&g_node[nodeId].coordinateId, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].coordinateMirrorId, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].coordinate, 1, sizeof(uint32), fd);
FREAD1(g_node[nodeId].DataPath, 1, CM_PATH_LENGTH, fd);
g_node[nodeId].DataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].DataPath);
FREAD1(g_node[nodeId].SSDDataPath, 1, CM_PATH_LENGTH, fd);
g_node[nodeId].SSDDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].SSDDataPath);
max_cnpath_len = (max_cnpath_len < (uint32)strlen(g_node[nodeId].DataPath)) ?
(uint32)strlen(g_node[nodeId].DataPath) : max_cnpath_len;
FREAD1(&g_node[nodeId].coordinateListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].coordinateListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int jj = 0; jj < CM_IP_NUM; jj++) {
FREAD1(g_node[nodeId].coordinateListenIP[jj], 1, CM_IP_LENGTH, fd);
g_node[nodeId].coordinateListenIP[jj][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].coordinateListenIP[jj]);
}
FREAD1(&g_node[nodeId].coordinatePort, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].coordinateHAPort, 1, sizeof(uint32), fd);
return 0;
}
static int ReadNodeOneDnListenIp(FILE *fd, uint32 nodeId, uint32 dnId)
{
FREAD1(&g_node[nodeId].datanode[dnId].datanodeListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].datanode[dnId].datanodeListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int nn = 0; nn < CM_IP_NUM; nn++) {
FREAD1(g_node[nodeId].datanode[dnId].datanodeListenIP[nn], 1, CM_IP_LENGTH, fd);
g_node[nodeId].datanode[dnId].datanodeListenIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].datanode[dnId].datanodeListenIP[nn]);
}
return 0;
}
static int ReadNodeOneDnListenHaip(FILE *fd, uint32 nodeId, uint32 dnId)
{
FREAD1(&g_node[nodeId].datanode[dnId].datanodeLocalHAListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].datanode[dnId].datanodeLocalHAListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int nn = 0; nn < CM_IP_NUM; nn++) {
FREAD1(g_node[nodeId].datanode[dnId].datanodeLocalHAIP[nn], 1, CM_IP_LENGTH, fd);
g_node[nodeId].datanode[dnId].datanodeLocalHAIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].datanode[dnId].datanodeLocalHAIP[nn]);
}
FREAD1(&g_node[nodeId].datanode[dnId].datanodeLocalHAPort, 1, sizeof(uint32), fd);
return 0;
}
static int ReadNodeOneDnPeerDataNode(FILE *fd, uint32 nodeId, uint32 dnId)
{
for (uint32 peerdnId = 0; peerdnId < CM_MAX_DATANODE_STANDBY_NUM; peerdnId++) {
FREAD1(g_node[nodeId].datanode[dnId].peerDatanodes[peerdnId].datanodePeerDataPath, 1, CM_PATH_LENGTH, fd);
g_node[nodeId].datanode[dnId].peerDatanodes[peerdnId].datanodePeerDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].datanode[dnId].peerDatanodes[peerdnId].datanodePeerDataPath);
FREAD1(&g_node[nodeId].datanode[dnId].peerDatanodes[peerdnId].datanodePeerHAListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].datanode[dnId].peerDatanodes[peerdnId].datanodePeerHAListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int nn = 0; nn < CM_IP_NUM; nn++) {
FREAD1(g_node[nodeId].datanode[dnId].peerDatanodes[peerdnId].datanodePeerHAIP[nn], 1, CM_IP_LENGTH, fd);
g_node[nodeId].datanode[dnId].peerDatanodes[peerdnId].datanodePeerHAIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].datanode[dnId].peerDatanodes[peerdnId].datanodePeerHAIP[nn]);
}
FREAD1(&g_node[nodeId].datanode[dnId].peerDatanodes[peerdnId].datanodePeerHAPort, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].datanode[dnId].peerDatanodes[peerdnId].datanodePeerRole, 1, sizeof(uint32), fd);
}
return 0;
}
static int ReadNodeOneDnPeerDataNode1(FILE *fd, uint32 nodeId, uint32 dnId)
{
FREAD1(g_node[nodeId].datanode[dnId].datanodePeerDataPath, 1, CM_PATH_LENGTH, fd);
g_node[nodeId].datanode[dnId].datanodePeerDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].datanode[dnId].datanodePeerDataPath);
FREAD1(&g_node[nodeId].datanode[dnId].datanodePeerHAListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].datanode[dnId].datanodePeerHAListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int nn = 0; nn < CM_IP_NUM; nn++) {
FREAD1(g_node[nodeId].datanode[dnId].datanodePeerHAIP[nn], 1, CM_IP_LENGTH, fd);
g_node[nodeId].datanode[dnId].datanodePeerHAIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].datanode[dnId].datanodePeerHAIP[nn]);
}
FREAD1(&g_node[nodeId].datanode[dnId].datanodePeerHAPort, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].datanode[dnId].datanodePeerRole, 1, sizeof(uint32), fd);
FREAD1(g_node[nodeId].datanode[dnId].datanodePeer2DataPath, 1, CM_PATH_LENGTH, fd);
g_node[nodeId].datanode[dnId].datanodePeer2DataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].datanode[dnId].datanodePeer2DataPath);
FREAD1(&g_node[nodeId].datanode[dnId].datanodePeer2HAListenCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].datanode[dnId].datanodePeer2HAListenCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int nn = 0; nn < CM_IP_NUM; nn++) {
FREAD1(g_node[nodeId].datanode[dnId].datanodePeer2HAIP[nn], 1, CM_IP_LENGTH, fd);
g_node[nodeId].datanode[dnId].datanodePeer2HAIP[nn][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].datanode[dnId].datanodePeer2HAIP[nn]);
}
FREAD1(&g_node[nodeId].datanode[dnId].datanodePeer2HAPort, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].datanode[dnId].datanodePeer2Role, 1, sizeof(uint32), fd);
return 0;
}
static int ReadNodeOneDn(FILE *fd, uint32 nodeId, uint32 dnId, ReadConfigContext *ctx)
{
if (g_node[nodeId].datanode[dnId].datanodeRole == PRIMARY_DN) {
g_cluster_total_instance_group_num++;
}
FREAD1(&g_node[nodeId].datanode[dnId].datanodeId, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].datanode[dnId].datanodeMirrorId, 1, sizeof(uint32), fd);
if (!ctx->datanodeMirrorIDInit) {
ctx->datanodeMirrorIDInit = true;
ctx->datanodeMirrorID = g_node[nodeId].datanode[dnId].datanodeMirrorId;
ctx->dnReplicationNum++;
} else if (ctx->datanodeMirrorID == g_node[nodeId].datanode[dnId].datanodeMirrorId) {
ctx->dnReplicationNum++;
}
FREAD1(g_node[nodeId].datanode[dnId].datanodeLocalDataPath, 1, CM_PATH_LENGTH, fd);
g_node[nodeId].datanode[dnId].datanodeLocalDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].datanode[dnId].datanodeLocalDataPath);
FREAD1(g_node[nodeId].datanode[dnId].datanodeXlogPath, 1, CM_PATH_LENGTH, fd);
g_node[nodeId].datanode[dnId].datanodeXlogPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].datanode[dnId].datanodeXlogPath);
FREAD1(g_node[nodeId].datanode[dnId].datanodeSSDDataPath, 1, CM_PATH_LENGTH, fd);
g_node[nodeId].datanode[dnId].datanodeSSDDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].datanode[dnId].datanodeSSDDataPath);
max_datapath_len = (max_datapath_len < (uint32)strlen(g_node[nodeId].datanode[dnId].datanodeLocalDataPath)) ?
(uint32)strlen(g_node[nodeId].datanode[dnId].datanodeLocalDataPath) : max_datapath_len;
int32 ret = ReadNodeOneDnListenIp(fd, nodeId, dnId);
RETURN_IFERR(ret);
FREAD1(&g_node[nodeId].datanode[dnId].datanodePort, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].datanode[dnId].datanodeRole, 1, sizeof(uint32), fd);
ret = ReadNodeOneDnListenHaip(fd, nodeId, dnId);
RETURN_IFERR(ret);
if (g_clusterType >= SinglePrimaryMultiStandbyCluster && g_clusterType <= V3SingleInstCluster) {
ret = ReadNodeOneDnPeerDataNode(fd, nodeId, dnId);
RETURN_IFERR(ret);
} else {
ret = ReadNodeOneDnPeerDataNode1(fd, nodeId, dnId);
RETURN_IFERR(ret);
}
return 0;
}
static int ReadNodeAllDn(FILE *fd, uint32 nodeId, ReadConfigContext *ctx)
{
int ret = 0;
FREAD1(&g_node[nodeId].datanodeCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].datanodeCount > CM_MAX_DATANODE_PER_NODE) {
return READ_FILE_ERROR;
}
for (uint32 dnId = 0; dnId < g_node[nodeId].datanodeCount; dnId++) {
ret = ReadNodeOneDn(fd, nodeId, dnId, ctx);
RETURN_IFERR(ret);
}
return 0;
}
static int ReadNodeEtcd(FILE *fd, uint32 nodeId, ReadConfigContext *ctx)
{
FREAD1(&g_node[nodeId].etcd, 1, sizeof(uint32), fd);
if (g_node[nodeId].etcd == 1) {
ctx->etcdNum++;
}
FREAD1(&g_node[nodeId].etcdId, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].etcdMirrorId, 1, sizeof(uint32), fd);
FREAD1(g_node[nodeId].etcdName, 1, (CM_NODE_NAME - 1), fd);
g_node[nodeId].etcdName[CM_NODE_NAME - 1] = '\0';
check_input_for_security(g_node[nodeId].etcdName);
FREAD1(g_node[nodeId].etcdDataPath, 1, CM_PATH_LENGTH, fd);
g_node[nodeId].etcdDataPath[CM_PATH_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].etcdDataPath);
max_etcdpath_len = (max_etcdpath_len < (uint32)strlen(g_node[nodeId].etcdDataPath)) ?
(uint32)strlen(g_node[nodeId].etcdDataPath) : max_etcdpath_len;
FREAD1(&g_node[nodeId].etcdClientListenIPCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].etcdClientListenIPCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int kk = 0; kk < CM_IP_NUM; kk++) {
FREAD1(g_node[nodeId].etcdClientListenIPs[kk], 1, CM_IP_LENGTH, fd);
g_node[nodeId].etcdClientListenIPs[kk][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].etcdClientListenIPs[kk]);
}
FREAD1(&g_node[nodeId].etcdClientListenPort, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].etcdHAListenIPCount, 1, sizeof(uint32), fd);
if (g_node[nodeId].etcdHAListenIPCount > CM_IP_NUM) {
return READ_FILE_ERROR;
}
for (int kk = 0; kk < CM_IP_NUM; kk++) {
FREAD1(g_node[nodeId].etcdHAListenIPs[kk], 1, CM_IP_LENGTH, fd);
g_node[nodeId].etcdHAListenIPs[kk][CM_IP_LENGTH - 1] = '\0';
check_input_for_security(g_node[nodeId].etcdHAListenIPs[kk]);
}
FREAD1(&g_node[nodeId].etcdHAListenPort, 1, sizeof(uint32), fd);
return 0;
}
static int ReadOneNode(FILE *fd, uint32 nodeId, ReadConfigContext *ctx)
{
int ret = ReadNodeInfo(fd, nodeId);
RETURN_IFERR(ret);
ret = ReadNodeBackIp(fd, nodeId);
RETURN_IFERR(ret);
ret = ReadNodeSsh(fd, nodeId);
RETURN_IFERR(ret);
ret = ReadNodeCmserver(fd, nodeId, ctx);
RETURN_IFERR(ret);
ret = ReadNodeGtm(fd, nodeId, ctx);
RETURN_IFERR(ret);
ret = ReadNodeCn(fd, nodeId);
RETURN_IFERR(ret);
if (g_node[nodeId].coordinate == 1) {
ctx->cnNum++;
g_cluster_total_instance_group_num++;
}
ret = ReadNodeAllDn(fd, nodeId, ctx);
RETURN_IFERR(ret);
ret = ReadNodeEtcd(fd, nodeId, ctx);
RETURN_IFERR(ret);
FREAD1(&g_node[nodeId].sctpBeginPort, 1, sizeof(uint32), fd);
FREAD1(&g_node[nodeId].sctpEndPort, 1, sizeof(uint32), fd);
return 0;
}
static int ReadAllNodes(FILE *fd, ReadConfigContext *ctx)
{
int ret = 0;
uint32 header_size = sizeof(staticConfigHeader);
uint32 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) {
return READ_FILE_ERROR;
}
for (uint32 nodeId = 0; nodeId < g_nodeHeader.nodeCount; nodeId++) {
ret = ReadOneNode(fd, nodeId, ctx);
RETURN_IFERR(ret);
long current_pos = ftell(fd);
if (current_pos == -1L) {
return READ_FILE_ERROR;
}
long 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)) {
return READ_FILE_ERROR;
}
}
return ret;
}
static int ReadConfigContent(FILE *fd, bool inReload, ReadConfigContext *ctx)
{
int ret = read_config_header(fd);
RETURN_IFERR(ret);
ret = alloc_node_buffer(inReload);
RETURN_IFERR(ret);
ret = ReadAllNodes(fd, ctx);
RETURN_IFERR(ret);
return ret;
}
int read_config_file(const char *file_path, int *err_no, bool inReload)
{
ReadConfigContext ctx;
ctx.datanodeMirrorIDInit = false;
ctx.datanodeMirrorID = 0;
ctx.cmServerNum = 0;
ctx.gtmNum = 0;
ctx.dnReplicationNum = 0;
ctx.etcdNum = 0;
ctx.cnNum = 0;
FILE *fd = open_config_file(file_path, err_no);
if (fd == NULL) {
return OPEN_FILE_ERROR;
}
int32 rcs = ReadConfigContent(fd, inReload, &ctx);
if (rcs != 0) {
(void)fclose(fd);
fd = NULL;
*err_no = errno;
if (inReload) {
return rcs;
}
if (g_node != NULL) {
free(g_node);
g_node = NULL;
}
g_multi_az_cluster = false;
g_one_master_multi_slave = false;
return rcs;
}
g_node_num = g_nodeHeader.nodeCount;
g_cm_server_num = ctx.cmServerNum;
g_gtm_num = ctx.gtmNum;
g_dn_replication_num = ctx.dnReplicationNum;
g_etcd_num = ctx.etcdNum;
g_coordinator_num = ctx.cnNum;
setAZPriority();
(void)fclose(fd);
fd = 0;
return 0;
}
void set_para_for_cm_read(const logicClusterList lcList)
{
const char *lcName = NULL;
max_logic_cluster_name_len = 0;
int rcs = memset_s(g_logicClusterStaticConfig,
sizeof(logicClusterStaticConfig) * LOGIC_CLUSTER_NUMBER,
0,
sizeof(logicClusterStaticConfig) * LOGIC_CLUSTER_NUMBER);
securec_check_c(rcs, "", "");
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, "", "");
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)
{
logicClusterList lcList;
int rcs = memset_s(&lcList, sizeof(logicClusterList), 0, sizeof(logicClusterList));
securec_check_c(rcs, "", "");
if (g_node != NULL) {
g_isCmRead = true;
}
int32 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)
{
uint32 ii = 0;
long current_pos = 0;
uint32 header_size = sizeof(staticConfigHeader);
uint32 header_aglinment_size =
(header_size / AGLINMENT_SIZE + ((header_size % AGLINMENT_SIZE) == 0 ? 0 : 1)) * AGLINMENT_SIZE;
FILE *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 *
********************************************************************************/
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;
}
g_node_num = g_nodeHeader.nodeCount;
if (g_node_num > CM_NODE_MAXNUM) {
(void)fclose(fd);
return READ_FILE_ERROR;
}
if (g_node == NULL) {
g_node = (staticNodeConfig *)malloc(sizeof(staticNodeConfig) * CM_NODE_MAXNUM);
if (g_node == NULL) {
(void)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;
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]);
}
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;
}
}
(void)fclose(fd);
return 0;
read_failed:
if (g_node != NULL) {
free(g_node);
g_node = NULL;
}
(void)fclose(fd);
g_node_num = 0;
*err_no = errno;
return READ_FILE_ERROR;
}
void set_cm_read_flag(bool falg)
{
g_isCmRead = falg;
}
static bool is_valid_logic_cluster_name(const char *name)
{
if (name == NULL || name[0] == '\0') {
return false;
}
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
return false;
}
for (const char *p = name; *p != '\0'; p++) {
char c = *p;
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' ||
c == '-')) {
return false;
}
}
return true;
}
static bool is_path_under_directory(const char *path, const char *dir)
{
size_t dir_len = strlen(dir);
if (strncmp(path, dir, dir_len) != 0) {
return false;
}
if (path[dir_len] != '\0' && path[dir_len] != '/') {
return false;
}
return true;
}
int read_logic_cluster_name(const char *file_path, logicClusterList &lcList, int *err_no)
{
uint32 logic_cluster_Index = 0;
FILE *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) {
(void)fclose(fd);
*err_no = errno;
return READ_FILE_ERROR;
}
if (strlen(lcList.lcInfoArray[logic_cluster_Index].logicClusterName) != 0) {
if (!is_valid_logic_cluster_name(lcList.lcInfoArray[logic_cluster_Index].logicClusterName)) {
(void)fprintf(stderr,
"Invalid logic cluster name in %s: %s\n",
file_path,
lcList.lcInfoArray[logic_cluster_Index].logicClusterName);
(void)fclose(fd);
*err_no = EINVAL;
return READ_FILE_ERROR;
}
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);
}
(void)fclose(fd);
return 0;
}
static int read_all_logic_config_file(const logicClusterList lcList, int *err_no)
{
int status = 0;
for (uint32 logic_cluster_index = 0; logic_cluster_index < lcList.logicClusterCount; logic_cluster_index++) {
status = read_logic_config_file(lcList.lcInfoArray[logic_cluster_index], err_no);
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 FILE *OpenLogicConfigFile(const char *logicClusterName, int *err_no)
{
char bin_dir[MAX_PATH_LEN] = {0};
char file_path[MAX_PATH_LEN] = {0};
char exec_path[MAX_PATH_LEN] = {0};
if (!is_valid_logic_cluster_name(logicClusterName)) {
(void)fprintf(stderr,
"Invalid logic cluster name: %s\n",
logicClusterName != NULL ? logicClusterName : "(null)");
*err_no = EINVAL;
return NULL;
}
int rcs = cmconfig_getenv("GAUSSHOME", exec_path, sizeof(exec_path));
if (rcs != EOK) {
(void)fprintf(stderr, "Get GAUSSHOME failed, please check.\n");
return NULL;
}
errno_t rc = snprintf_s(bin_dir, MAX_PATH_LEN, MAX_PATH_LEN - 1, "%s/bin", exec_path);
securec_check_ss_c(rc, "", "");
canonicalize_path(bin_dir);
rc = snprintf_s(file_path, MAX_PATH_LEN, MAX_PATH_LEN - 1, "%s/%s.cluster_static_config",
bin_dir, logicClusterName);
securec_check_ss_c(rc, "", "");
canonicalize_path(file_path);
if (!is_path_under_directory(file_path, bin_dir)) {
(void)fprintf(stderr, "Logic cluster config path escapes GAUSSHOME/bin: %s\n", file_path);
*err_no = EINVAL;
return NULL;
}
FILE *fd = fopen(file_path, "r");
if (fd == NULL) {
*err_no = errno;
return NULL;
}
return fd;
}
static int read_logic_config_file(const logicClusterInfo lcInfo, int *err_no)
{
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;
errno_t rc = 0;
logicClusterStaticConfig *LCStaticConfig = &g_logicClusterStaticConfig[lcInfo.logicClusterId];
FILE *fd = OpenLogicConfigFile(lcInfo.logicClusterName, err_no);
if (fd == NULL) {
return OPEN_FILE_ERROR;
}
* DISCLAIMER: Any Change in file format need to update the Version Number *
* Version Number Offset should not be changed *
********************************************************************************/
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(fd);
}
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) {
(void)fprintf(stderr,
"The logic cluster node number [count=%u] is greater than the max node number [max_num=%d].\n",
logicClusterNodeNum,
CM_NODE_MAXNUM);
(void)fclose(fd);
return -1;
}
if (g_isCmRead) {
if (LCStaticConfig->logicClusterNode != NULL) {
free(LCStaticConfig->logicClusterNode);
LCStaticConfig->logicClusterNode = NULL;
}
LCStaticConfig->logicClusterNode =
(staticLogicNodeConfig *)malloc(sizeof(staticLogicNodeConfig) * logicClusterNodeNum);
if (LCStaticConfig->logicClusterNode == NULL) {
(void)fclose(fd);
return OUT_OF_MEMORY;
} else {
rcs = memset_s(LCStaticConfig->logicClusterNode,
sizeof(staticLogicNodeConfig) * logicClusterNodeNum,
0,
sizeof(staticLogicNodeConfig) * logicClusterNodeNum);
securec_check_c(rcs, "", "");
}
}
for (ii = 0; ii < logicClusterNodeNum; ii++) {
uint32 jj = 0;
uint32 kk = 0;
long body_aglinment_size = 0;
uint32 datanode_index = 0;
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]);
}
for (node_index = 0; node_index < g_nodeHeader.nodeCount; node_index++) {
if (g_node[node_index].node == LCStaticConfig->logicClusterNode[ii].node) {
break;
}
}
} else {
current_pos = ftell(fd);
long node_head_size = (long)sizeof(uint32) * 4 + (CM_NODE_NAME - 1) + (CM_IP_NUM * CM_IP_LENGTH * 2);
body_aglinment_size = current_pos + node_head_size;
if (fseek(fd, (off_t)body_aglinment_size, SEEK_SET)) {
READ_LOGICAL_CONFIG_FAILED(fd);
}
}
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) {
(void)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);
(void)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;
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, "", "");
break;
}
}
} else if (datanodeId == g_datanodeid) {
rc = strcpy_s(g_logicClusterName, CM_LOGIC_CLUSTER_NAME_LEN, lcInfo.logicClusterName);
securec_check_c(rc, "", "");
(void)fclose(fd);
return 0;
}
current_pos = ftell(fd);
body_aglinment_size = current_pos + (long)sizeof(dataNodeInfo) - (long)sizeof(uint32) -
(long)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(fd);
}
}
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(fd);
}
}
if (!g_isCmRead) {
g_logicClusterName[0] = '\0';
}
(void)fclose(fd);
return 0;
read_failed:
READ_LOGICAL_CONFIG_FAILED(fd);
}
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, "", "");
}
}
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, "", "");
}
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 = read_config_file(file_path, err_no);
if (ret != 0) {
return ret;
}
uint32 node_index = 0;
bool find = 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 (strcmp(dataPath, g_node[i].datanode[j].datanodeLocalDataPath) == 0) {
node_index = i;
find = true;
break;
}
}
}
}
if (!find) {
return -1;
}
bool isLocal = read_single_file_local(node_index);
if (!isLocal) {
return -2;
}
return 0;
}
int get_dynamic_dn_role(void)
{
char path[MAXPGPATH];
char line_info[MAXPGPATH] = {0};
char *node_name = NULL;
char *dn_role = NULL;
struct stat statbuf;
char *gausshome = gs_getenv_r("GAUSSHOME");
check_input_for_security(gausshome);
int nRet = snprintf_s(path, MAXPGPATH, MAXPGPATH - 1, "%s/bin/%s", gausshome, DYNAMIC_DNROLE_FILE);
securec_check_ss_c(nRet, "", "");
if (lstat(path, &statbuf) != 0) {
return 0;
}
FILE *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 (uint32 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;
uint32 count = 0;
uint32 j = 0;
uint32 tmpAZPriority = 0;
char *tmpNodeName = NULL;
size_t buflen = 1;
size_t curlen = 0;
for (nodeidx = 0; nodeidx < g_node_num; nodeidx++) {
if (strcmp(g_node[nodeidx].azName, AZName) == 0) {
count++;
}
}
if (count < 1) {
return 0;
}
AZList *azList = (AZList *)malloc(sizeof(AZList) * count);
if (azList == NULL) {
return OUT_OF_MEMORY;
}
dataNodeInfo *dni = NULL;
{
for (uint32 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;
}
uint32 i = 0;
for (nodeidx = 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) {
for (uint32 l = 0; l < dest->datanodeCount && !get_dn_in_same_shard; l++) {
dataNodeInfo *dn = &(dest->datanode[l]);
if (dn->datanodeId == 0) {
continue;
}
if (dn->datanodeRole == CASCADE_STANDBY_TYPE) {
continue;
}
for (int32 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 nRc = 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(nRc, "", "");
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;
}
}
}
}
}
uint32 len = i;
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) {
tmpAZPriority = azList[j].azPriority;
azList[j].azPriority = azList[j + 1].azPriority;
azList[j + 1].azPriority = tmpAZPriority;
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;
}
}
}
char *buffer = (char *)malloc(sizeof(char) * (buflen + 1));
if (buffer == NULL) {
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;
}
int32 nRet = memset_s(buffer, buflen + 1, 0, buflen + 1);
securec_check_c(nRet, buffer, "");
for (i = 0; i < len; i++) {
if (strcmp(g_local_node_name, azList[i].nodeName) == 0) {
continue;
}
nRet = snprintf_s(buffer + curlen, (buflen + 1 - curlen), (buflen - curlen), "%s,", azList[i].nodeName);
securec_check_ss_c(nRet, buffer, "");
curlen = curlen + (size_t)nRet;
}
if (strlen(buffer) >= 1) {
buffer[strlen(buffer) - 1] = '\0';
}
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
Input : fileName
Output : None
Return : None
******************************************************************************
*/
int checkPath(const char *fileName)
{
char realFileName[MAX_REALPATH_LEN + 1] = {0};
char *retVal = realpath(fileName, realFileName);
if (retVal == NULL) {
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);
char bin_dir[MAXPGPATH] = {0};
nRet = snprintf_s(bin_dir, MAXPGPATH, MAXPGPATH - 1, "%s/bin", gausshome);
securec_check_ss_c(nRet, "", "");
canonicalize_path(bin_dir);
if (g_lcname != NULL) {
if (!is_valid_logic_cluster_name(g_lcname)) {
return false;
}
nRet = snprintf_s(path, MAXPGPATH, MAXPGPATH - 1, "%s/%s.%s", bin_dir, g_lcname, STATIC_CONFIG_FILE);
} else {
nRet = snprintf_s(path, MAXPGPATH, MAXPGPATH - 1, "%s/%s", bin_dir, STATIC_CONFIG_FILE);
}
securec_check_ss_c(nRet, "", "");
canonicalize_path(path);
if (!is_path_under_directory(path, bin_dir)) {
return false;
}
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;
int dnIdMaxLen = 64;
char dnId[dnIdMaxLen];
if ((datanodeName == NULL) || (*datanodeName == '\0')) {
return false;
}
dataNodeInfo *dnI = NULL;
for (uint32 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) {
(void)fprintf(stderr, "Failed: cannot find the expected data dir\n");
return false;
}
for (uint32 nodeIdx = 0; nodeIdx < g_node_num; ++nodeIdx) {
staticNodeConfig *dest = &(g_node[nodeIdx]);
for (uint32 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, "", "");
nRet = snprintf_s(
dnId, sizeof(dnId) / sizeof(char), sizeof(dnId) / sizeof(char) - 1, "dn_%4u", dn->datanodeId);
securec_check_ss_c(nRet, "", "");
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;
}