ADD file via upload

This commit is contained in:
makqmlwy5 2023-10-04 20:14:46 +08:00
parent 6e3d6f09d4
commit a75168ec6f
1 changed files with 533 additions and 0 deletions

View File

@ -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);
}