From a75168ec6fa5e82fc7644d882728e35d6ed631dc Mon Sep 17 00:00:00 2001 From: makqmlwy5 Date: Wed, 4 Oct 2023 20:14:46 +0800 Subject: [PATCH] ADD file via upload --- src/gausskernel/cbb/bbox/bbox_create.cpp | 533 +++++++++++++++++++++++ 1 file changed, 533 insertions(+) create mode 100644 src/gausskernel/cbb/bbox/bbox_create.cpp diff --git a/src/gausskernel/cbb/bbox/bbox_create.cpp b/src/gausskernel/cbb/bbox/bbox_create.cpp new file mode 100644 index 000000000..54ccf182d --- /dev/null +++ b/src/gausskernel/cbb/bbox/bbox_create.cpp @@ -0,0 +1,533 @@ +/* + * 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. + * ------------------------------------------------------------------------- + * + * bbox_create.cpp + * + * IDENTIFICATION + * src/gausskernel/cbb/bbox/bbox_create.cpp + * + * ------------------------------------------------------------------------- + */ +#include "bbox_elf_dump_base.h" +#include "bbox_create.h" +#include "bbox.h" +#include "../../src/include/securec.h" +#include "../../src/include/securec_check.h" + +/* Core path of the bbox process */ +char g_szBboxCorePath[BBOX_NAME_PATH_LEN] = "./"; + +/* count of the BBOX process */ +s32 g_iBBoxCoreFileCount = 30; + +/* the max core file size of bbox process */ +s32 g_iBBoxCoreFileSize = 50; + +long int g_iCoreDumpBeginTime = 0; +long int g_iCoreDumpEndTime = 0; + +char g_acDateTime[BBOX_TINE_LEN]; + +/* + * get system date time. + * return 0 if sucess else err code. + */ +int BBOX_GetSysDateTime(void) +{ + int iCommandFD = -1; + int iReadSize = 0; + + // 打开一个管道,并执行指定的日期时间命令 + BBOX_NOINTR(iCommandFD = sys_popen(BBOX_DATE_TIME_CMD, "r")); + if (iCommandFD < 0) { + bbox_print(PRINT_ERR, "sys_popen is failed, errno = %d.\n", errno); + return RET_ERR; + } + + // 读取sys_read命令的结果 + BBOX_NOINTR(iReadSize = sys_read(iCommandFD, g_acDateTime, BBOX_TINE_LEN)); + if (iReadSize <= 0) { + (void)sys_pclose(iCommandFD); + bbox_print(PRINT_ERR, "sys_read is failed, iReadSize = %d.\n", iReadSize); + return RET_ERR; + } + + (void)sys_pclose(iCommandFD); + + if (iReadSize > 0) { + g_acDateTime[iReadSize - 1] = '\0'; /* 移除'\n'字符 */ + } + + bbox_print(PRINT_LOG, "Get system time %s.\n", g_acDateTime); + + return RET_OK; +} + +/* + * get default core file name + * return 0 if sucess else err code. + */ +s32 BBOX_GetDefaultCoreName(char* szFileName, s32 iSize, const char* szAddText) +{ + if (szFileName == NULL) { + return RET_ERR; + } + + if (szAddText == NULL) { + szAddText = ""; + } + + struct kernel_timeval stProgramCoreDumpTime = {0}; + sys_gettimeofday(&stProgramCoreDumpTime, NULL); + + s32 ret = bbox_snprintf(szFileName, + iSize, + "%s/core-%s-%d-%s-%s.lz4", + g_szBboxCorePath, + progname, + sys_getpid(), + g_acDateTime, + szAddText); + + return (ret > 0) ? RET_OK : RET_ERR; +} + +/* + * get temp core file name + * return 0 if sucess else err code. + */ +s32 BBOX_GetTmpCoreName(char* szFileName, s32 iSize) +{ + if (szFileName == NULL) { + return RET_ERR; + } + + struct kernel_timeval stProgramCoreDumpTime = {0}; + sys_gettimeofday(&stProgramCoreDumpTime, NULL); + + g_iCoreDumpBeginTime = stProgramCoreDumpTime.tv_sec; + bbox_print(PRINT_TIP, "coredump begin at %ld\n", stProgramCoreDumpTime.tv_sec); + + s32 ret = bbox_snprintf(szFileName, + iSize, + "%s/%s-%d-%s-%s", + g_szBboxCorePath, + progname, + sys_getpid(), + g_acDateTime, + BBOX_TMP_FILE_ADD_NAME); + + return (ret > 0) ? RET_OK : RET_ERR; +} + +/* + * get core file count of bbox process. + * return 0 if sucess else err code. + */ +s32 BBOX_GetBBoxFileCount(const char* pszPath, const char* pszName, void* pArgs) +{ + s32* pIFileCount = NULL; + + pIFileCount = (s32*)pArgs; + if (pIFileCount == NULL) { + bbox_print(PRINT_ERR, "Invalid argument pstArgs\n"); + return RET_ERR; + } + + /* ignore path "." and ".." */ + if ((0 == bbox_strcmp(pszName, ".")) || (0 == bbox_strcmp(pszName, ".."))) { + return RET_OK; + } + + /* ignore the file which not belong to bbox */ + if ((0 == bbox_strstr(pszName, BBOX_SNAP_FILE_ADD_NAME ".lz4")) && + (0 == bbox_strstr(pszName, BBOX_CORE_FILE_ADD_NAME ".lz4"))) { + return RET_OK; + } + + /* ignore the file which not created by this process. */ + if (bbox_strstr(pszName, progname) == 0) { + return RET_OK; + } + + /* file count ++ */ + *pIFileCount = *pIFileCount + 1; + + return RET_OK; +} + +/* + * get bbox ildiest name. + * return 0 if sucess else err code. + */ +s32 BBOX_GetBBoxOldiestName(const char* pszPath, const char* pszName, void* pArgs) +{ + struct BBOX_ListDirParam* pstArgs = NULL; + struct kernel_stat* pstOldiestState = NULL; + char* pszOldName = NULL; + struct kernel_stat stCurrState = {0}; + char szFileName[BBOX_NAME_PATH_LEN]; + + // 检查参数 + pstArgs = (struct BBOX_ListDirParam*)pArgs; + if (pstArgs == NULL) { + bbox_print(PRINT_ERR, "Invalid argument pstArgs\n"); + return RET_ERR; + } + + pstOldiestState = (struct kernel_stat*)pstArgs->pArg1; + pszOldName = (char*)pstArgs->pArg2; + + // 忽略路径"."和".." + if ((0 == bbox_strcmp(pszName, ".")) || (0 == bbox_strcmp(pszName, ".."))) { + return RET_OK; + } + + // 忽略不属于bbox的文件 + if ((0 == bbox_strstr(pszName, BBOX_SNAP_FILE_ADD_NAME ".lz4")) && + (0 == bbox_strstr(pszName, BBOX_CORE_FILE_ADD_NAME ".lz4"))) { + return RET_OK; + } + + // 忽略不是由该进程创建的文件 + if (bbox_strstr(pszName, progname) == 0) { + return RET_OK; + } + + // 拼接文件路径 + if (bbox_snprintf(szFileName, sizeof(szFileName), "%s/%s", pszPath, pszName) <= 0) { + bbox_print(PRINT_ERR, "bbox_snprintf is failed, errno = %d.\n", errno); + return RET_ERR; + } + + // 获取文件信息 + if (sys_stat(szFileName, &stCurrState) < 0) { + bbox_print(PRINT_ERR, "Get stat of '%s' failed, errno = %d\n", szFileName, errno); + return RET_ERR; + } + + // 比较并判断是否为最早创建的文件 + if (stCurrState.st_mtime_ < pstOldiestState->st_mtime_) { + // 记录最早的文件信息 + *pstOldiestState = stCurrState; + if (bbox_snprintf(pszOldName, BBOX_NAME_PATH_LEN, "%s/%s", pszPath, pszName) <= 0) { + bbox_print(PRINT_ERR, "bbox_snprintf is failed, errno = %d.\n", errno); + return RET_ERR; + } + } + + return RET_OK; +} + +/* + * remove the oldiest bbox file. + */ +void BBOX_RemoveOldiestBBoxFile(void) +{ + s32 iRet = 0; + struct kernel_stat stOldiestState; + struct BBOX_ListDirParam stArgs = {0}; + char szFileName[BBOX_NAME_PATH_LEN]; + errno_t rc = EOK; + + /* set the file modified time to the max value acquiescently. */ + rc = memset_s(&stOldiestState, sizeof(stOldiestState), 0xFF, sizeof(stOldiestState)); + securec_check_c(rc, "\0", "\0"); + + stOldiestState.st_size = -1; + + stArgs.pArg1 = &stOldiestState; + stArgs.pArg2 = szFileName; + + /* search the oldiest file. */ + iRet = bbox_listdir(g_szBboxCorePath, BBOX_GetBBoxOldiestName, &stArgs); + if (iRet != RET_OK) { + return; + } + + /* remove it if found. */ + if (-1 != stOldiestState.st_size) { + sys_unlink(szFileName); + } +} + +/* + * remove the old bbox file + */ +void BBOX_RemoveOldBBoxFile(void) +{ + s32 iFileCount = 0; + s32 iRet = 0; + s32 i; + + iRet = bbox_listdir(g_szBboxCorePath, BBOX_GetBBoxFileCount, &iFileCount); + if (iRet != RET_OK) { + bbox_print(PRINT_ERR, "Get bbox file count failed.\n"); + return; + } + + /* remove redundant file */ + for (i = 0; i < (iFileCount - g_iBBoxCoreFileCount + 1); i++) { + /* remove the oldiest bbox file. */ + BBOX_RemoveOldiestBBoxFile(); + } +} + +/* + * remove bbox temp file. + */ +s32 BBOX_DoRemoveTempBBoxFile(const char* pszPath, const char* pszName, void* pArgs) +{ + struct kernel_stat stCurrState = {0}; + struct kernel_timeval stCurrTime = {0}; + char szFileName[BBOX_NAME_PATH_LEN]; + + /* ignore path "." and ".." */ + if ((0 == bbox_strcmp(pszName, ".")) || (0 == bbox_strcmp(pszName, ".."))) { + return RET_OK; + } + + /* ignore the file which not belong to bbox */ + if (0 == bbox_strstr(pszName, BBOX_TMP_FILE_ADD_NAME)) { + return RET_OK; + } + + /* ignore the file which not created by this process. */ + if (0 != bbox_strncmp(pszName, progname, bbox_strlen(progname))) { + return RET_OK; + } + + if (bbox_snprintf(szFileName, sizeof(szFileName), "%s/%s", pszPath, pszName) <= 0) { + bbox_print(PRINT_ERR, "bbox_snprintf is failed, errno = %d.\n", errno); + return RET_ERR; + } + + if (sys_stat(szFileName, &stCurrState) < 0) { + bbox_print(PRINT_ERR, "Get stat of '%s' failed, errno = %d\n", szFileName, errno); + return RET_ERR; + } + + /* get current time */ + sys_gettimeofday(&stCurrTime, NULL); + + /* remove temp file before BBOX_TMP_DEL_TIME_INTERVAL */ + if (stCurrState.st_mtime_ < (unsigned long)(stCurrTime.tv_sec - BBOX_TMP_DEL_TIME_INTERVAL)) { + /* rm file */ + bbox_print(PRINT_ERR, "Delete bad bbox core file %s \n", szFileName); + sys_unlink(szFileName); + } + + return RET_OK; +} + +/* + * remove temp bbox file + */ +void BBOX_RemoveTempBBoxFile(void) +{ + s32 iRet = 0; + + iRet = bbox_listdir(g_szBboxCorePath, BBOX_DoRemoveTempBBoxFile, NULL); + if (iRet != RET_OK) { + bbox_print(PRINT_ERR, "Get bbox file count failed.\n"); + return; + } +} + +/* + finish core dump file. + in : args defined by user and it is file name here. + +*/ +void BBOX_FinishDumpFile(void* args) +{ + // 声明所需的变量 + char* pszNewName = NULL; + char* pszOldName = NULL; + struct kernel_timeval stProgramCoreDumpTime = {0}; + struct BBOX_ListDirParam* pstArgs = (struct BBOX_ListDirParam*)args; + + // 检查参数是否为NULL + if (args == NULL) { + bbox_print(PRINT_ERR, "BBOX_FinishDumpFile args is null.\n"); + return; + } + + // 获取程序核心转储完成的时间 + sys_gettimeofday(&stProgramCoreDumpTime, NULL); + + // 将程序核心转储完成的时间赋值给全局变量 + g_iCoreDumpEndTime = stProgramCoreDumpTime.tv_sec; + bbox_print(PRINT_TIP, "coredump End at %ld\n", stProgramCoreDumpTime.tv_sec); + + // 打印程序核心转储所用的时间 + bbox_print(PRINT_TIP, "coredump used time: %ld sec\n", g_iCoreDumpEndTime - g_iCoreDumpBeginTime); + + // 移除最旧的文件 + BBOX_RemoveOldBBoxFile(); + + // 获取新文件名和旧文件名 + pszNewName = (char*)pstArgs->pArg1; + pszOldName = (char*)pstArgs->pArg2; + + // 将旧文件的访问权限设置为0600 + if (sys_chmod(pszOldName, 0600)) { + bbox_print(PRINT_ERR, "set %s mode to 0600 failed, errno = %d\n", pszOldName, errno); + } + + // 重命名文件 + if (pszNewName != NULL && pszOldName != NULL) { + if (sys_rename(pszOldName, pszNewName) < 0) { + bbox_print(PRINT_ERR, "rename file %s to %s failed, errno = %d.\n", pszOldName, pszNewName, errno); + } + } + + // 移除临时核心转储文件 + BBOX_RemoveTempBBoxFile(); +} + +/* + * create core dump file. + * return 0 if success else err code. + */ +s32 BBOX_CreateCoredump(char* file_name) +{ + s32 iRet = 0; + char szFileName[BBOX_NAME_PATH_LEN]; + char szTmpName[BBOX_NAME_PATH_LEN]; + struct BBOX_ListDirParam stArgs = {0}; + char* file_tmp = file_name; + FRAME(frame); + + bbox_initlog(0); + + // 打印日志头 + bbox_print(PRINT_TIP, "\nBBOX LOG\n-------------------------------\n"); + + // 获取系统当前时间 + iRet = BBOX_GetSysDateTime(); + if (iRet != RET_OK) { + return RET_ERR; + } + + // 创建核心文件保存路径 + if (bbox_mkdir(g_szBboxCorePath) < 0) { + bbox_print(PRINT_ERR, "bbox_mkdir is failed, errno = %d.\n", errno); + return RET_ERR; + } + + // 若file_name为NULL,则使用默认名称创建核心文件 + if (file_name == NULL) { + if (BBOX_GetDefaultCoreName(szFileName, BBOX_NAME_PATH_LEN, BBOX_CORE_FILE_ADD_NAME) == RET_OK) { + file_name = szFileName; + } else { + bbox_print(PRINT_ERR, "BBOX_GetDefaultCoreName is failed, errno = %d.\n", errno); + return RET_ERR; + } + } + + // 打印核心文件路径 + bbox_print(PRINT_TIP, "core file path is %s\n", file_name); + + // 获取临时核心文件名 + if (BBOX_GetTmpCoreName(szTmpName, BBOX_NAME_PATH_LEN) == RET_OK) { + file_tmp = szTmpName; + } else { + bbox_print(PRINT_ERR, "BBOX_GetTmpCoreName is failed, errno = %d.\n", errno); + return RET_ERR; + } + + // 设置参数并调用相关函数 + stArgs.pArg1 = file_name; + stArgs.pArg2 = file_tmp; + + iRet = BBOX_GetAllThreads(GET_TYPE_DUMP, BBOX_FinishDumpFile, &stArgs, BBOX_DoDumpElfCore, &frame, file_tmp); + + return iRet; +} + +/* + * set core dump path + * return 0 if success else err code. + */ +s32 BBOX_SetCoredumpPath(const char* pszPath) +{ + if (NULL != pszPath) { + if (bbox_snprintf(g_szBboxCorePath, sizeof(g_szBboxCorePath), "%s", pszPath) <= 0) { + bbox_print(PRINT_ERR, "bbox_snprintf is failed, errno = %d.\n", errno); + return RET_ERR; + } + } else { + return RET_ERR; + } + + if (0 == bbox_strlen(g_szBboxCorePath)) { + return RET_ERR; + } + + if (bbox_mkdir(g_szBboxCorePath) < 0) { + bbox_print(PRINT_ERR, "bbox_mkdir is failed, errno = %d.\n", errno); + return RET_ERR; + } + + return RET_OK; +} + +/* + * set core file count + * return 0 if success else err code. + */ +s32 BBOX_SetCoreFileCount(s32 iCount) +{ + if (iCount < 0) { + return RET_ERR; + } + + g_iBBoxCoreFileCount = iCount; + + return RET_OK; +} + +/* + * add an blacklist item to exclude it from core file. + * void *pAddress : the head address of excluded memory + * u64 uilen : memory size + * return RET_OK if success else RET_ERR. + */ +s32 BBOX_AddBlackListAddress(void* pAddress, u64 uiLen) +{ + if (pAddress == NULL || uiLen == 0) { + bbox_print(PRINT_ERR, "parameter pAddress(******) uiLen(%llu) is invaild.\n", uiLen); + return RET_ERR; + } + + return _BBOX_AddBlackListAddress(pAddress, uiLen); +} + +/* + * remove an blacklist item. + * void *pAddress : the head address of excluded memory + * return RET_OK if success else RET_ERR. + */ +s32 BBOX_RmvBlackListAddress(void* pAddress) +{ + if (pAddress == NULL) { + bbox_print(PRINT_ERR, "parameter pAddress(******) is invaild.\n"); + return RET_ERR; + } + + return _BBOX_RmvBlackListAddress(pAddress); +} +