ADD file via upload
This commit is contained in:
parent
6e3d6f09d4
commit
a75168ec6f
|
|
@ -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);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue