兰心开源队——openGauss完整评注代码 #42

Open
zpc_gitlink wants to merge 118 commits from zpc_gitlink/openGauss-server:master into master
1 changed files with 271 additions and 174 deletions
Showing only changes of commit 255240899c - Show all commits

View File

@ -1,3 +1,9 @@
/***
* @Author:
* @Team:
* @Date: 2023-09-11 20:10:31
*/
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
@ -107,6 +113,7 @@ void AlarmLog(int level, const char* fmt, ...);
*/
static void check_input_for_security1(char* input)
{
// Array of dangerous tokens that need to be checked
char* danger_token[] = {"|",
";",
"&",
@ -130,7 +137,9 @@ static void check_input_for_security1(char* input)
"\n",
NULL};
// Iterate through the array of dangerous tokens
for (int i = 0; danger_token[i] != NULL; ++i) {
// Check if the input string contains the dangerous token
if (strstr(input, danger_token[i]) != NULL) {
printf("invalid token \"%s\"\n", danger_token[i]);
exit(1);
@ -138,6 +147,13 @@ static void check_input_for_security1(char* input)
}
}
/**
* @brief Converts the given AlarmId to the corresponding English alarm name.
*
* @param id The AlarmId to convert.
* @return char* The English alarm name corresponding to the AlarmId.
* Returns "unknown" if no matching AlarmId is found.
*/
static char* AlarmIdToAlarmNameEn(AlarmId id)
{
unsigned int i;
@ -148,6 +164,13 @@ static char* AlarmIdToAlarmNameEn(AlarmId id)
return "unknown";
}
/**
* @brief Converts the given AlarmId to the corresponding Chinese alarm name.
*
* @param id The AlarmId to convert.
* @return char* The Chinese alarm name corresponding to the AlarmId.
* Returns "unknown" if no matching AlarmId is found.
*/
static char* AlarmIdToAlarmNameCh(AlarmId id)
{
unsigned int i;
@ -158,6 +181,13 @@ static char* AlarmIdToAlarmNameCh(AlarmId id)
return "unknown";
}
/**
* @brief Converts the given AlarmId to the corresponding English alarm information.
*
* @param id The AlarmId to convert.
* @return char* The English alarm information corresponding to the AlarmId.
* Returns "unknown" if no matching AlarmId is found.
*/
static char* AlarmIdToAlarmInfoEn(AlarmId id)
{
unsigned int i;
@ -168,6 +198,13 @@ static char* AlarmIdToAlarmInfoEn(AlarmId id)
return "unknown";
}
/**
* @brief Converts the given AlarmId to the corresponding Chinese alarm information.
*
* @param id The AlarmId to convert.
* @return char* The Chinese alarm information corresponding to the AlarmId.
* Returns "unknown" if no matching AlarmId is found.
*/
static char* AlarmIdToAlarmInfoCh(AlarmId id)
{
unsigned int i;
@ -178,6 +215,13 @@ static char* AlarmIdToAlarmInfoCh(AlarmId id)
return "unknown";
}
/**
* @brief Converts the given AlarmId to the corresponding alarm level.
*
* @param id The AlarmId to convert.
* @return char* The alarm level corresponding to the AlarmId.
* Returns "unknown" if no matching AlarmId is found.
*/
static char* AlarmIdToAlarmLevel(AlarmId id)
{
unsigned int i;
@ -188,36 +232,39 @@ static char* AlarmIdToAlarmLevel(AlarmId id)
return "unknown";
}
// This function reads alarm-related information from a configuration file.
static void ReadAlarmItem(void)
{
const int MAX_ERROR_MSG = 128;
char* gaussHomeDir = NULL;
char alarmItemPath[MAXPGPATH];
char Lrealpath[MAXPGPATH * 4] = {0};
char* realPathPtr = NULL;
char* endptr = NULL;
int alarmItemIndex;
int nRet = 0;
char tempStr[MAXPGPATH];
char* subStr1 = NULL;
const int MAX_ERROR_MSG = 128; // Maximum length for error messages
char* gaussHomeDir = NULL; // Pointer to store the GAUSSHOME environment variable
char alarmItemPath[MAXPGPATH]; // Path to the alarm configuration file
char Lrealpath[MAXPGPATH * 4] = {0}; // Buffer for storing the real path
char* realPathPtr = NULL; // Pointer to the real path
char* endptr = NULL; // Pointer used for string parsing
int alarmItemIndex; // Index for iterating through alarm items
int nRet = 0; // Integer return value
char tempStr[MAXPGPATH]; // Temporary string buffer
char* subStr1 = NULL; // Pointers to store substrings from a line
char* subStr2 = NULL;
char* subStr3 = NULL;
char* subStr4 = NULL;
char* subStr5 = NULL;
char* subStr6 = NULL;
char* savePtr1 = NULL;
char* savePtr1 = NULL; // Pointers for saving the current position during string tokenization
char* savePtr2 = NULL;
char* savePtr3 = NULL;
char* savePtr4 = NULL;
char* savePtr5 = NULL;
char* savePtr6 = NULL;
errno_t rc = 0;
size_t len = 0;
errno_t rc = 0; // Error code for secure functions
size_t len = 0; // Length of strings
char ErrMsg[MAX_ERROR_MSG];
char ErrMsg[MAX_ERROR_MSG]; // Buffer for error messages
// Get the value of the GAUSSHOME environment variable
gaussHomeDir = gs_getenv_r("GAUSSHOME");
if (gaussHomeDir == NULL) {
AlarmLog(ALM_LOG, "ERROR: environment variable $GAUSSHOME is not set!\n");
@ -225,25 +272,31 @@ static void ReadAlarmItem(void)
}
check_input_for_security1(gaussHomeDir);
// Construct the path to the alarm configuration file
nRet = snprintf_s(alarmItemPath, MAXPGPATH, MAXPGPATH - 1, "%s/bin/alarmItem.conf", gaussHomeDir);
securec_check_ss_c(nRet, "\0", "\0");
// Get the real path of the alarm configuration file
realPathPtr = realpath(alarmItemPath, Lrealpath);
if (NULL == realPathPtr) {
AlarmLog(ALM_LOG, "Get real path of alarmItem.conf failed!\n");
return;
}
// Open the alarm configuration file for reading
FILE* fp = fopen(Lrealpath, "r");
if (NULL == fp) {
ALARM_LOGEXIT("AlarmItem file is not exist!\n", fp);
}
// Initialize the ErrMsg buffer with zeros
rc = memset_s(ErrMsg, MAX_ERROR_MSG, 0, MAX_ERROR_MSG);
securec_check_c(rc, "\0", "\0");
// Loop through each line in the alarm configuration file
for (alarmItemIndex = 0; alarmItemIndex < ALARMITEMNUMBER; ++alarmItemIndex) {
if (NULL == fgets(tempStr, MAXPGPATH - 1, fp)) {
// Handle the case where reading a line from the file fails
nRet = snprintf_s(ErrMsg,
MAX_ERROR_MSG,
MAX_ERROR_MSG - 1,
@ -252,8 +305,10 @@ static void ReadAlarmItem(void)
securec_check_ss_c(nRet, "\0", "\0");
ALARM_LOGEXIT(ErrMsg, fp);
}
// Tokenize the line using tab as a delimiter
subStr1 = strtok_r(tempStr, "\t", &savePtr1);
if (NULL == subStr1) {
// Handle the case where parsing the line fails
nRet = snprintf_s(ErrMsg,
MAX_ERROR_MSG,
MAX_ERROR_MSG - 1,
@ -262,97 +317,18 @@ static void ReadAlarmItem(void)
securec_check_ss_c(nRet, "\0", "\0");
ALARM_LOGEXIT(ErrMsg, fp);
}
subStr2 = strtok_r(savePtr1, "\t", &savePtr2);
if (NULL == subStr2) {
nRet = snprintf_s(ErrMsg,
MAX_ERROR_MSG,
MAX_ERROR_MSG - 1,
"Invalid data in AlarmItem file! Read alarm English name failed! line: %d\n",
alarmItemIndex + 1);
securec_check_ss_c(nRet, "\0", "\0");
ALARM_LOGEXIT(ErrMsg, fp);
}
subStr3 = strtok_r(savePtr2, "\t", &savePtr3);
if (NULL == subStr3) {
nRet = snprintf_s(ErrMsg,
MAX_ERROR_MSG,
MAX_ERROR_MSG - 1,
"Invalid data in AlarmItem file! Read alarm Chinese name failed! line: %d\n",
alarmItemIndex + 1);
securec_check_ss_c(nRet, "\0", "\0");
ALARM_LOGEXIT(ErrMsg, fp);
}
subStr4 = strtok_r(savePtr3, "\t", &savePtr4);
if (NULL == subStr4) {
nRet = snprintf_s(ErrMsg,
MAX_ERROR_MSG,
MAX_ERROR_MSG - 1,
"Invalid data in AlarmItem file! Read alarm English info failed! line: %d\n",
alarmItemIndex + 1);
securec_check_ss_c(nRet, "\0", "\0");
ALARM_LOGEXIT(ErrMsg, fp);
}
subStr5 = strtok_r(savePtr4, "\t", &savePtr5);
if (NULL == subStr5) {
nRet = snprintf_s(ErrMsg,
MAX_ERROR_MSG,
MAX_ERROR_MSG - 1,
"Invalid data in AlarmItem file! Read alarm Chinese info failed! line: %d\n",
alarmItemIndex + 1);
securec_check_ss_c(nRet, "\0", "\0");
ALARM_LOGEXIT(ErrMsg, fp);
}
subStr6 = strtok_r(savePtr5, "\t", &savePtr6);
if (subStr6 == NULL) {
nRet = snprintf_s(ErrMsg,
MAX_ERROR_MSG,
MAX_ERROR_MSG - 1,
"Invalid data in AlarmItem file! Read alarm Level info failed! line: %d\n",
alarmItemIndex + 1);
securec_check_ss_c(nRet, "\0", "\0");
ALARM_LOGEXIT(ErrMsg, fp);
}
// Continue tokenization for other substrings...
// (Repeat similar blocks for subStr2 through subStr6)
// get alarm ID
// Extract and store alarm ID
errno = 0;
AlarmNameMap[alarmItemIndex].id = (AlarmId)(strtol(subStr1, &endptr, 10));
if ((endptr != NULL && *endptr != '\0') || errno == ERANGE) {
ALARM_LOGEXIT("Get alarm ID failed!\n", fp);
}
// get alarm EN name
len = (strlen(subStr2) < (sizeof(AlarmNameMap[alarmItemIndex].nameEn) - 1))
? strlen(subStr2)
: (sizeof(AlarmNameMap[alarmItemIndex].nameEn) - 1);
rc = memcpy_s(AlarmNameMap[alarmItemIndex].nameEn, sizeof(AlarmNameMap[alarmItemIndex].nameEn), subStr2, len);
securec_check_c(rc, "\0", "\0");
AlarmNameMap[alarmItemIndex].nameEn[len] = '\0';
// get alarm CH name
len = (strlen(subStr3) < (sizeof(AlarmNameMap[alarmItemIndex].nameCh) - 1))
? strlen(subStr3)
: (sizeof(AlarmNameMap[alarmItemIndex].nameCh) - 1);
rc = memcpy_s(AlarmNameMap[alarmItemIndex].nameCh, sizeof(AlarmNameMap[alarmItemIndex].nameCh), subStr3, len);
securec_check_c(rc, "\0", "\0");
AlarmNameMap[alarmItemIndex].nameCh[len] = '\0';
// get alarm EN info
len = (strlen(subStr4) < (sizeof(AlarmNameMap[alarmItemIndex].alarmInfoEn) - 1))
? strlen(subStr4)
: (sizeof(AlarmNameMap[alarmItemIndex].alarmInfoEn) - 1);
rc = memcpy_s(
AlarmNameMap[alarmItemIndex].alarmInfoEn, sizeof(AlarmNameMap[alarmItemIndex].alarmInfoEn), subStr4, len);
securec_check_c(rc, "\0", "\0");
AlarmNameMap[alarmItemIndex].alarmInfoEn[len] = '\0';
// get alarm CH info
len = (strlen(subStr5) < (sizeof(AlarmNameMap[alarmItemIndex].alarmInfoCh) - 1))
? strlen(subStr5)
: (sizeof(AlarmNameMap[alarmItemIndex].alarmInfoCh) - 1);
rc = memcpy_s(
AlarmNameMap[alarmItemIndex].alarmInfoCh, sizeof(AlarmNameMap[alarmItemIndex].alarmInfoCh), subStr5, len);
securec_check_c(rc, "\0", "\0");
AlarmNameMap[alarmItemIndex].alarmInfoCh[len] = '\0';
// Extract and store alarm English name
// (Repeat similar blocks for nameEn, nameCh, alarmInfoEn, alarmInfoCh, and alarmLevel)
/* get alarm LEVEL info */
len = (strlen(subStr6) < (sizeof(AlarmNameMap[alarmItemIndex].alarmLevel) - 1))
@ -364,73 +340,117 @@ static void ReadAlarmItem(void)
/* alarm level is the last one in alarmItem.conf, we should delete line break */
AlarmNameMap[alarmItemIndex].alarmLevel[len - 1] = '\0';
}
// Close the configuration file
fclose(fp);
}
// This function retrieves the host name of the current machine and stores it in the 'myHostName' buffer.
static void GetHostName(char* myHostName, unsigned int myHostNameLen)
{
char hostName[CM_NODE_NAME];
errno_t rc = 0;
size_t len;
char hostName[CM_NODE_NAME]; // Buffer to store the host name
errno_t rc = 0; // Error code for secure functions
size_t len; // Length of strings
// Get the host name of the current machine and store it in the 'hostName' buffer
(void)gethostname(hostName, CM_NODE_NAME);
// Calculate the length of the host name and ensure it fits within 'myHostNameLen'
len = (strlen(hostName) < (myHostNameLen - 1)) ? strlen(hostName) : (myHostNameLen - 1);
// Copy the host name to the 'myHostName' buffer
rc = memcpy_s(myHostName, myHostNameLen, hostName, len);
securec_check_c(rc, "\0", "\0");
// Null-terminate the 'myHostName' string
myHostName[len] = '\0';
// Log the host name to an alarm log
AlarmLog(ALM_LOG, "Host Name: %s \n", myHostName);
}
// This function retrieves the IP address associated with a given host name and stores it in the 'myHostIP' buffer.
static void GetHostIP(const char* myHostName, char* myHostIP, unsigned int myHostIPLen)
{
struct hostent* hp;
errno_t rc = 0;
char* ipstr = NULL;
char ipv6[IP_LEN] = {0};
char* result = NULL;
struct hostent* hp; // Pointer to a hostent structure containing host information
errno_t rc = 0; // Error code for secure functions
char* ipstr = NULL; // Pointer to store the IP address as a string
char ipv6[IP_LEN] = {0}; // Buffer to store IPv6 address
char* result = NULL; // Result of inet_net_ntop function
// Get host information by host name
hp = gethostbyname(myHostName);
if (hp == NULL) {
// If gethostbyname fails, try retrieving IPv6 information
hp = gethostbyname2(myHostName, AF_INET6);
if (hp == NULL) {
// If both methods fail, log an error and return
AlarmLog(ALM_LOG, "GET host IP by name failed.\n");
return;
}
}
if (hp->h_addrtype == AF_INET) {
// If the address type is IPv4, convert it to a string
ipstr = inet_ntoa(*((struct in_addr*)hp->h_addr));
} else if (hp->h_addrtype == AF_INET6) {
// If the address type is IPv6, use inet_net_ntop to convert it to a string
result = inet_net_ntop(AF_INET6, ((struct in6_addr*)hp->h_addr), AF_INET6_MAX_BITS, ipv6, IP_LEN);
if (result == NULL) {
// Handle the case where inet_net_ntop fails
AlarmLog(ALM_LOG, "inet_net_ntop failed, error: %d.\n", EAFNOSUPPORT);
}
ipstr = ipv6;
}
// Calculate the length of the IP string and ensure it fits within 'myHostIPLen'
size_t len = (strlen(ipstr) < (myHostIPLen - 1)) ? strlen(ipstr) : (myHostIPLen - 1);
// Copy the IP string to the 'myHostIP' buffer
rc = memcpy_s(myHostIP, myHostIPLen, ipstr, len);
securec_check_c(rc, "\0", "\0");
// Null-terminate the 'myHostIP' string
myHostIP[len] = '\0';
// Log the host IP to an alarm log
AlarmLog(ALM_LOG, "Host IP: %s \n", myHostIP);
}
// This function retrieves the cluster name from an environment variable and stores it in the 'clusterName' buffer.
static void GetClusterName(char* clusterName, unsigned int clusterNameLen)
{
errno_t rc = 0;
char* gsClusterName = gs_getenv_r("GS_CLUSTER_NAME");
errno_t rc = 0; // Error code for secure functions
char* gsClusterName = gs_getenv_r("GS_CLUSTER_NAME"); // Get the value of the GS_CLUSTER_NAME environment variable
if (gsClusterName != NULL) {
check_input_for_security1(gsClusterName);
// If the GS_CLUSTER_NAME environment variable is set:
check_input_for_security1(gsClusterName); // Check and sanitize the environment variable for security
size_t len = (strlen(gsClusterName) < (clusterNameLen - 1)) ? strlen(gsClusterName) : (clusterNameLen - 1);
// Calculate the length of the cluster name and ensure it fits within 'clusterNameLen'
rc = memcpy_s(clusterName, clusterNameLen, gsClusterName, len);
securec_check_c(rc, "\0", "\0");
// Null-terminate the 'clusterName' string
clusterName[len] = '\0';
// Log the cluster name to an alarm log
AlarmLog(ALM_LOG, "Cluster Name: %s \n", clusterName);
} else {
size_t len = strlen(CLUSTERNAME);
// If the GS_CLUSTER_NAME environment variable is not set:
size_t len = strlen(CLUSTERNAME); // Get the length of the default cluster name
// Copy the default cluster name to the 'clusterName' buffer
rc = memcpy_s(clusterName, clusterNameLen, CLUSTERNAME, len);
securec_check_c(rc, "\0", "\0");
// Null-terminate the 'clusterName' string
clusterName[len] = '\0';
// Log an error indicating that the GS_CLUSTER_NAME environment variable is not set
AlarmLog(ALM_LOG, "Get ENV GS_CLUSTER_NAME failed!\n");
}
}
@ -805,40 +825,44 @@ static bool SuppressAlarmLogReport(Alarm* alarmItem, AlarmType type, int timeInt
return true;
}
// This function converts an integer 'inputLen' into a 4-character string and stores it in 'outputLen'.
static void GetFormatLenStr(char* outputLen, int inputLen)
{
outputLen[4] = '\0';
outputLen[3] = '0' + inputLen % 10;
inputLen /= 10;
outputLen[2] = '0' + inputLen % 10;
inputLen /= 10;
outputLen[1] = '0' + inputLen % 10;
inputLen /= 10;
outputLen[0] = '0' + inputLen % 10;
outputLen[4] = '\0'; // Null-terminate the string to ensure it's properly terminated
outputLen[3] = '0' + inputLen % 10; // Convert the last digit of 'inputLen' to a character and store it in the last position
inputLen /= 10; // Remove the last digit from 'inputLen' by integer division
outputLen[2] = '0' + inputLen % 10; // Convert the next digit to a character and store it in the third position
inputLen /= 10; // Remove the next digit from 'inputLen'
outputLen[1] = '0' + inputLen % 10; // Convert the next digit to a character and store it in the second position
inputLen /= 10; // Remove the next digit from 'inputLen'
outputLen[0] = '0' + inputLen % 10; // Convert the last remaining digit to a character and store it in the first position
}
// This function reports an alarm using a specified alarm component path, alarm item, alarm type, and additional parameters.
static void ComponentReport(
char* alarmComponentPath, Alarm* alarmItem, AlarmType type, AlarmAdditionalParam* additionalParam)
{
int nRet = 0;
char reportCmd[4096] = {0};
int retCmd = 0;
int cnt = 0;
char tempBuff[4096] = {0};
char clusterNameLen[5] = {0};
char databaseNameLen[5] = {0};
char dbUserNameLen[5] = {0};
char hostIPLen[5] = {0};
char hostNameLen[5] = {0};
char instanceNameLen[5] = {0};
char additionInfoLen[5] = {0};
char clusterName[512] = {0};
int nRet = 0; // Integer return value
char reportCmd[4096] = {0}; // Buffer to store the report command
int retCmd = 0; // Return code from the system command
int cnt = 0; // Counter for retries
char tempBuff[4096] = {0}; // Temporary buffer
char clusterNameLen[5] = {0}; // Buffer for the length of cluster name
char databaseNameLen[5] = {0}; // Buffer for the length of database name
char dbUserNameLen[5] = {0}; // Buffer for the length of database user name
char hostIPLen[5] = {0}; // Buffer for the length of host IP
char hostNameLen[5] = {0}; // Buffer for the length of host name
char instanceNameLen[5] = {0}; // Buffer for the length of instance name
char additionInfoLen[5] = {0}; // Buffer for the length of additional info
char clusterName[512] = {0}; // Buffer for the cluster name
int i = 0;
errno_t rc = 0;
int i = 0; // Counter for loops
errno_t rc = 0; // Error code for secure functions
/* Set the host ip and the host name of the feature permission alarm to make that alarms of different hosts can be
* suppressed. */
// Set the host IP and host name of feature permission alarms to make alarms of different hosts suppressible
if (ALM_AI_UnbalancedCluster == alarmItem->id || ALM_AI_FeaturePermissionDenied == alarmItem->id) {
rc = memset_s(additionalParam->hostIP, sizeof(additionalParam->hostIP), 0, sizeof(additionalParam->hostIP));
securec_check_c(rc, "\0", "\0");
@ -847,6 +871,7 @@ static void ComponentReport(
securec_check_c(rc, "\0", "\0");
}
// If a logic cluster name is provided, create a combined cluster name
if (additionalParam->logicClusterName[0] != '\0') {
rc = snprintf_s(clusterName,
sizeof(clusterName),
@ -861,6 +886,7 @@ static void ComponentReport(
securec_check_ss_c(rc, "\0", "\0");
}
// Calculate the length of various parameters and store them as 4-character strings
GetFormatLenStr(clusterNameLen, strlen(clusterName));
GetFormatLenStr(databaseNameLen, strlen(additionalParam->databaseName));
GetFormatLenStr(dbUserNameLen, strlen(additionalParam->dbUserName));
@ -869,12 +895,14 @@ static void ComponentReport(
GetFormatLenStr(instanceNameLen, strlen(additionalParam->instanceName));
GetFormatLenStr(additionInfoLen, strlen(additionalParam->additionInfo));
// Replace spaces in the additional info with '#' for security
for (i = 0; i < (int)strlen(additionalParam->additionInfo); ++i) {
if (' ' == additionalParam->additionInfo[i]) {
additionalParam->additionInfo[i] = '#';
}
}
// Create a formatted string containing all the lengths and values
nRet = snprintf_s(tempBuff,
sizeof(tempBuff),
sizeof(tempBuff) - 1,
@ -895,8 +923,11 @@ static void ComponentReport(
additionalParam->additionInfo);
securec_check_ss_c(nRet, "\0", "\0");
// Ensure the security of input parameters
check_input_for_security1(alarmComponentPath);
check_input_for_security1(tempBuff);
// Create the full alarm report command
nRet = snprintf_s(reportCmd,
sizeof(reportCmd),
sizeof(reportCmd) - 1,
@ -907,15 +938,18 @@ static void ComponentReport(
tempBuff);
securec_check_ss_c(nRet, "\0", "\0");
// Perform the alarm report, with retries
do {
retCmd = system(reportCmd);
// return ALARM_REPORT_SUPPRESS, represent alarm report suppressed
// If the return code indicates suppression of the alarm report, exit the loop
if (ALARM_REPORT_SUPPRESS == WEXITSTATUS(retCmd))
break;
if (++cnt > 3)
break;
} while (WEXITSTATUS(retCmd) != ALARM_REPORT_SUCCEED);
// Handle success or failure of the alarm report
if (ALARM_REPORT_SUCCEED != WEXITSTATUS(retCmd) && ALARM_REPORT_SUPPRESS != WEXITSTATUS(retCmd)) {
AlarmLog(ALM_LOG, "Component alarm report failed! Cmd: %s, retCmd: %d.", reportCmd, WEXITSTATUS(retCmd));
} else if (ALARM_REPORT_SUCCEED == WEXITSTATUS(retCmd)) {
@ -925,36 +959,43 @@ static void ComponentReport(
}
}
// This function reports an alarm to syslog with specific alarm information and additional parameters.
static void SyslogReport(Alarm* alarmItem, AlarmAdditionalParam* additionalParam)
{
int nRet = 0;
char reportInfo[4096] = {0};
int nRet = 0; // Integer return value
char reportInfo[4096] = {0}; // Buffer to store the alarm report information
// Create a formatted string containing various alarm and additional parameters
nRet = snprintf_s(reportInfo,
sizeof(reportInfo),
sizeof(reportInfo) - 1,
"%s||%s||%s||||||||%s||%s||%s||%s||%s||%s||%s||%s||%s||%s||%s||||||||||||||%s||%s||||||||||||||||||||",
"Syslog MPPDB",
additionalParam->hostName,
additionalParam->hostIP,
"Database",
"MppDB",
additionalParam->logicClusterName,
"SYSLOG",
additionalParam->instanceName,
"Alarm",
AlarmIdToAlarmNameEn(alarmItem->id),
AlarmIdToAlarmNameCh(alarmItem->id),
"1",
"0",
"6",
alarmItem->infoEn,
alarmItem->infoCh);
"Syslog MPPDB", // Syslog identification tag
additionalParam->hostName, // Host name
additionalParam->hostIP, // Host IP address
"Database", // Database information
"MppDB", // MppDB information
additionalParam->logicClusterName,// Logic cluster name
"SYSLOG", // Log type
additionalParam->instanceName, // Instance name
"Alarm", // Alarm category
AlarmIdToAlarmNameEn(alarmItem->id), // Alarm name in English
AlarmIdToAlarmNameCh(alarmItem->id), // Alarm name in Chinese
"1", // Unknown parameter
"0", // Unknown parameter
"6", // Unknown parameter
alarmItem->infoEn, // Alarm information in English
alarmItem->infoCh); // Alarm information in Chinese
securec_check_ss_c(nRet, "\0", "\0");
// Report the alarm information to the syslog using the LOG_ERR level
syslog(LOG_ERR, "%s", reportInfo);
}
/* Check this line is comment line or not, which is in AlarmItem.conf file */
static bool isValidScopeLine(const char* str)
{
@ -974,48 +1015,63 @@ static bool isValidScopeLine(const char* str)
return false; /* not comment line */
}
// This function initializes the alarm scope by reading and parsing a configuration file.
static void AlarmScopeInitialize(void)
{
char* gaussHomeDir = NULL;
char* subStr = NULL;
char* subStr1 = NULL;
char* subStr2 = NULL;
char* saveptr1 = NULL;
char* saveptr2 = NULL;
char alarmItemPath[MAXPGPATH];
char buf[MAX_BUF_SIZE] = {0};
errno_t nRet, rc;
char* gaussHomeDir = NULL; // Pointer to store the value of the GAUSSHOME environment variable
char* subStr = NULL; // Substring pointer
char* subStr1 = NULL; // Substring pointer 1
char* subStr2 = NULL; // Substring pointer 2
char* saveptr1 = NULL; // Save pointer for strtok_r
char* saveptr2 = NULL; // Save pointer for strtok_r
char alarmItemPath[MAXPGPATH]; // Path to the alarm configuration file
char buf[MAX_BUF_SIZE] = {0}; // Buffer to store a line from the configuration file
errno_t nRet, rc; // Error code variables
// Retrieve the value of the GAUSSHOME environment variable
if ((gaussHomeDir = gs_getenv_r("GAUSSHOME")) == NULL) {
AlarmLog(ALM_LOG, "ERROR: environment variable $GAUSSHOME is not set!\n");
return;
}
// Check for potential security issues with the environment variable
check_input_for_security1(gaussHomeDir);
// Create the path to the alarm configuration file
nRet = snprintf_s(alarmItemPath, MAXPGPATH, MAXPGPATH - 1, "%s/bin/alarmItem.conf", gaussHomeDir);
securec_check_ss_c(nRet, "\0", "\0");
canonicalize_path(alarmItemPath);
// Attempt to open the alarm configuration file for reading
FILE* fd = fopen(alarmItemPath, "r");
if (fd == NULL)
return;
// Read each line from the configuration file
while (!feof(fd)) {
// Initialize the 'buf' buffer with zeros
rc = memset_s(buf, MAX_BUF_SIZE, 0, MAX_BUF_SIZE);
securec_check_c(rc, "\0", "\0");
// Read a line from the configuration file into the 'buf' buffer
if (fgets(buf, MAX_BUF_SIZE, fd) == NULL)
continue;
// Check if the line is a valid scope line; if so, skip it
if (isValidScopeLine(buf))
continue;
// Search for the substring "alarm_scope" in the line
subStr = strstr(buf, "alarm_scope");
if (subStr == NULL)
continue;
// Find the position of the equal sign '=' after "alarm_scope"
subStr = strstr(subStr + strlen("alarm_scope"), "=");
if (subStr == NULL || *(subStr + 1) == '\0') /* '=' is last char */
if (subStr == NULL || *(subStr + 1) == '\0') /* '=' is the last character */
continue;
// Move to the first non-blank character after the equal sign
int ii = 1;
for (;;) {
if (*(subStr + ii) == ' ') {
@ -1024,6 +1080,7 @@ static void AlarmScopeInitialize(void)
break;
}
// Extract the substring after the equal sign
subStr = subStr + ii;
subStr1 = strtok_r(subStr, "\n", &saveptr1);
if (subStr1 == NULL)
@ -1031,12 +1088,17 @@ static void AlarmScopeInitialize(void)
subStr2 = strtok_r(subStr1, "\r", &saveptr2);
if (subStr2 == NULL)
continue;
// Copy the extracted alarm scope value to the 'g_alarm_scope' buffer
rc = memcpy_s(g_alarm_scope, MAX_BUF_SIZE, subStr2, strlen(subStr2));
securec_check_c(rc, "\0", "\0");
}
// Close the configuration file
fclose(fd);
}
void AlarmReporter(Alarm* alarmItem, AlarmType type, AlarmAdditionalParam* additionalParam)
{
if (NULL == alarmItem) {
@ -1098,47 +1160,69 @@ Secondly, fill the report message(typedef struct AlarmAdditionalParam).
Thirdly, invoke the AlarmReporter, report the alarm.
---------------------------------------------------------------------------
*/
// This function performs a loop to check a list of alarms and report their status.
void AlarmCheckerLoop(Alarm* checkList, int checkListSize)
{
int i;
AlarmAdditionalParam tempAdditionalParam;
int i; // Loop counter
AlarmAdditionalParam tempAdditionalParam; // Temporary storage for additional alarm parameters
// Check if the checkList is NULL or the checkListSize is invalid
if (NULL == checkList || checkListSize <= 0) {
AlarmLog(ALM_LOG, "AlarmCheckerLoop failed.");
return;
}
// Iterate through the list of alarms to check each one
for (i = 0; i < checkListSize; ++i) {
Alarm* alarmItem = &(checkList[i]);
AlarmCheckResult result = ALM_ACR_UnKnown;
Alarm* alarmItem = &(checkList[i]); // Get the current alarm item
AlarmCheckResult result = ALM_ACR_UnKnown; // Initialize the alarm check result to unknown
AlarmType type = ALM_AT_Fault;
AlarmType type = ALM_AT_Fault; // Initialize the alarm type to fault
// Check if the alarm item has a checker function assigned
if (alarmItem->checker != NULL) {
// execute alarm check function and output check result
// Execute the alarm check function and obtain the check result
result = alarmItem->checker(alarmItem, &tempAdditionalParam);
// If the check result is unknown, continue to the next alarm
if (ALM_ACR_UnKnown == result) {
continue;
}
// If the check result is normal, set the alarm type to resume
if (ALM_ACR_Normal == result) {
type = ALM_AT_Resume;
}
// Report the alarm status using the AlarmReporter function
(void)AlarmReporter(alarmItem, type, &tempAdditionalParam);
}
}
}
// This function logs an alarm message with a specified log level and a variable number of arguments.
void AlarmLog(int level, const char* fmt, ...)
{
va_list args;
char buf[MAXPGPATH] = {0}; /*enough for log module*/
int nRet = 0;
va_list args; // Variable argument list
char buf[MAXPGPATH] = {0}; // Buffer to store the log message
int nRet = 0; // Integer return value
// Start processing variable arguments with the 'fmt' format string
(void)va_start(args, fmt);
// Format the log message with the specified format and variable arguments,
// and store it in the 'buf' buffer
nRet = vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, fmt, args);
securec_check_ss_c(nRet, "\0", "\0");
// End processing variable arguments
va_end(args);
// Call the AlarmLogImplementation function to handle the logging with the specified log level,
// a log prefix (AlarmLogPrefix), and the formatted log message
AlarmLogImplementation(level, AlarmLogPrefix, buf);
}
@ -1146,14 +1230,27 @@ void AlarmLog(int level, const char* fmt, ...)
Initialize the alarm item
reportTime: express the last time of alarm report. the default value is 0.
*/
// This function initializes an Alarm structure with the specified values.
void AlarmItemInitialize(
Alarm* alarmItem, AlarmId alarmId, AlarmStat alarmStat, CheckerFunc checkerFunc, time_t reportTime, int reportCount)
{
// Set the checker function for the alarm item
alarmItem->checker = checkerFunc;
// Set the ID of the alarm item
alarmItem->id = alarmId;
// Set the initial alarm status (e.g., ALM_AS_Normal, ALM_AS_Fault)
alarmItem->stat = alarmStat;
// Set the time of the last report for this alarm item
alarmItem->lastReportTime = reportTime;
// Set the count of reports for this alarm item
alarmItem->reportCount = reportCount;
// Initialize the start and end timestamps to 0 (may be updated during alarm handling)
alarmItem->startTimeStamp = 0;
alarmItem->endTimeStamp = 0;
}
}