niobe/base/hiviewdfx/hiview_lite/hiview_file.c

336 lines
10 KiB
C

/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "hiview_config.h"
#include "hiview_def.h"
#include "hiview_file.h"
#include "hiview_util.h"
#include "ohos_types.h"
#include "securec.h"
static uint16 GetReadCursor(HiviewFile *fp);
static uint32 GetDefineFileVersion(uint8 type)
{
switch (type) {
case HIVIEW_UE_EVENT_FILE:
return HIVIEW_UE_EVENT_VER;
case HIVIEW_STAT_EVENT_FILE:
return HIVIEW_STATIC_EVENT_VER;
case HIVIEW_FAULT_EVENT_FILE:
return HIVIEW_FAULT_EVENT_VER;
default:
// non-event file
return 0;
}
}
boolean InitHiviewFile(HiviewFile *fp, HiviewFileType type, uint32 size)
{
if (fp == NULL || fp->path == NULL) {
return FALSE;
}
fp->fhandle = HIVIEW_FileOpen(fp->path);
if (fp->fhandle < 0) {
return FALSE;
}
HiviewFileHeader *pHeader = &(fp->header);
FileHeaderCommon *pCommon = &(pHeader->common);
pCommon->type = (uint8)type;
pHeader->size = size + sizeof(HiviewFileHeader);
// Create file for the first time
if (ReadFileHeader(fp) == FALSE) {
switch (pCommon->type) {
case HIVIEW_LOG_TEXT_FILE:
pCommon->prefix = HIVIEW_FILE_HEADER_PREFIX_TEXT;
break;
case HIVIEW_LOG_BIN_FILE:
pCommon->prefix = HIVIEW_FILE_HEADER_PREFIX_LOG;
break;
case HIVIEW_FAULT_EVENT_FILE:
case HIVIEW_UE_EVENT_FILE:
case HIVIEW_STAT_EVENT_FILE:
pCommon->prefix = HIVIEW_FILE_HEADER_PREFIX_EVENT;
break;
default:
break;
}
pCommon->codeMainVersion = HIVIEW_FILE_HEADER_MAIN_VERSION;
pCommon->codeSubVersion = HIVIEW_FILE_HEADER_SUB_VERSION;
pCommon->defineFileVersion = GetDefineFileVersion(pCommon->type);
pHeader->createTime = (uint32)(HIVIEW_GetCurrentTime() / MS_PER_SECOND);
pHeader->rCursor = sizeof(HiviewFileHeader);
pHeader->wCursor = sizeof(HiviewFileHeader);
if (WriteFileHeader(fp) == FALSE) {
return FALSE;
}
} else {
// Version number may change after system upgrade
pCommon->codeMainVersion = HIVIEW_FILE_HEADER_MAIN_VERSION;
pCommon->codeSubVersion = HIVIEW_FILE_HEADER_SUB_VERSION;
pCommon->defineFileVersion = GetDefineFileVersion(pCommon->type);
}
return TRUE;
}
boolean WriteFileHeader(HiviewFile *fp)
{
if (fp == NULL || fp->fhandle < 0) {
return FALSE;
}
int32 ret;
if (HIVIEW_FileSeek(fp->fhandle, 0, HIVIEW_SEEK_SET) >= 0) {
HiviewFileHeader tmpHeader = fp->header;
#if LITTLE_ENDIAN_SYSTEM
tmpHeader.common.prefix = Change32Endian(tmpHeader.common.prefix);
tmpHeader.common.defineFileVersion = Change32Endian(tmpHeader.common.defineFileVersion);
tmpHeader.createTime = Change32Endian(tmpHeader.createTime);
#endif
ret = HIVIEW_FileWrite(fp->fhandle, (uint8 *)&(tmpHeader), sizeof(HiviewFileHeader));
if (ret == sizeof(HiviewFileHeader)) {
return TRUE;
}
}
return FALSE;
}
boolean ReadFileHeader(HiviewFile *fp)
{
HiviewFileHeader h = { 0 };
if (fp == NULL || fp->fhandle < 0) {
return FALSE;
}
int32 ret;
uint32 t = (uint32)(HIVIEW_GetCurrentTime() / MS_PER_SECOND);
if (HIVIEW_FileSeek(fp->fhandle, 0, HIVIEW_SEEK_SET) < 0) {
return FALSE;
}
ret = HIVIEW_FileRead(fp->fhandle, (uint8 *)&h, sizeof(HiviewFileHeader));
#if LITTLE_ENDIAN_SYSTEM
h.common.prefix = Change32Endian(h.common.prefix);
h.common.defineFileVersion = Change32Endian(h.common.defineFileVersion);
h.createTime = Change32Endian(h.createTime);
#endif
if ((ret == sizeof(HiviewFileHeader)) && (h.createTime < t) &&
((h.common.prefix & 0xFFFFFF00) == HIVIEW_FILE_HEADER_PREFIX_MASK)) {
memcpy_s(&(fp->header), sizeof(HiviewFileHeader), (void *)&h, sizeof(HiviewFileHeader));
return TRUE;
} else {
return FALSE;
}
}
int32 WriteToFile(HiviewFile *fp, const uint8 *data, uint32 len)
{
if (fp == NULL || fp->fhandle < 0 || len == 0) {
return 0;
}
int32 wLen = 0;
HiviewFileHeader *h = &(fp->header);
// overflow
if (h->wCursor + len > h->size) {
ProcFile(fp, fp->outPath, HIVIEW_FILE_RENAME);
if (fp->pFunc != NULL) {
fp->pFunc(fp->outPath, h->common.type, HIVIEW_FILE_FULL);
}
}
if (HIVIEW_FileSeek(fp->fhandle, h->wCursor, HIVIEW_SEEK_SET) < 0) {
return 0;
}
if ((int32)len == HIVIEW_FileWrite(fp->fhandle, data, len)) {
h->wCursor += len;
wLen += len;
}
if (WriteFileHeader(fp) == FALSE) {
return 0;
}
return wLen;
}
int32 ReadFromFile(HiviewFile *fp, uint8 *data, uint32 readLen)
{
if (fp == NULL || data == NULL || fp->fhandle < 0 || readLen == 0) {
return 0;
}
HiviewFileHeader* h = &(fp->header);
uint32 wCursor = h->wCursor;
uint32 rCursor = h->rCursor;
if (wCursor < readLen) {
return 0;
}
int32 rLen = (readLen <= (wCursor - rCursor)) ? readLen : (wCursor - rCursor);
if (HIVIEW_FileSeek(fp->fhandle, rCursor, HIVIEW_SEEK_SET) < 0) {
return 0;
}
if ((int32)rLen == HIVIEW_FileRead(fp->fhandle, data, rLen)) {
h->rCursor += rLen;
} else {
rLen = 0;
}
if (WriteFileHeader(fp) == FALSE) {
return 0;
}
return rLen;
}
uint32 GetFileUsedSize(HiviewFile *fp)
{
if (fp == NULL || fp->fhandle < 0) {
return 0;
}
return fp->header.wCursor;
}
uint32 GetFileFreeSize(HiviewFile *fp)
{
if (fp == NULL || fp->fhandle < 0) {
return 0;
}
return (fp->header.size - fp->header.wCursor);
}
int32 CloseHiviewFile(HiviewFile *fp)
{
if (fp != NULL && fp->fhandle > 0) {
if (WriteFileHeader(fp) == FALSE) {
return -1;
}
if (strcmp(fp->outPath, HIVIEW_FILE_OUT_PATH_LOG) != 0) {
HIVIEW_MemFree(MEM_POOL_HIVIEW_ID, fp->outPath);
fp->outPath = HIVIEW_FILE_OUT_PATH_LOG;
} else if (strcmp(fp->outPath, HIVIEW_FILE_OUT_PATH_UE_EVENT) != 0) {
HIVIEW_MemFree(MEM_POOL_HIVIEW_ID, fp->outPath);
fp->outPath = HIVIEW_FILE_OUT_PATH_UE_EVENT;
} else if (strcmp(fp->outPath, HIVIEW_FILE_OUT_PATH_FAULT_EVENT) != 0) {
HIVIEW_MemFree(MEM_POOL_HIVIEW_ID, fp->outPath);
fp->outPath = HIVIEW_FILE_OUT_PATH_FAULT_EVENT;
} else if (strcmp(fp->outPath, HIVIEW_FILE_OUT_PATH_STAT_EVENT) != 0) {
HIVIEW_MemFree(MEM_POOL_HIVIEW_ID, fp->outPath);
fp->outPath = HIVIEW_FILE_OUT_PATH_STAT_EVENT;
}
return HIVIEW_FileClose(fp->fhandle);
}
return -1;
}
int8 ProcFile(HiviewFile *fp, const char *dest, FileProcMode mode)
{
if (fp == NULL || fp->fhandle < 0 || HIVIEW_FileClose(fp->fhandle) != 0) {
return -1;
}
HIVIEW_MutexLockOrWait(fp->mutex, OUT_PATH_WAIT_TIMEOUT);
switch (mode) {
case HIVIEW_FILE_COPY:{
int32 ret = HIVIEW_FileCopy(fp->path, dest);
fp->fhandle = HIVIEW_FileOpen(fp->path);
if (ret != 0 || fp->fhandle < 0) {
HIVIEW_MutexUnlock(fp->mutex);
HIVIEW_UartPrint("Procfile failed, type : HIVIEW_FILE_COPY");
return -1;
}
break;
}
case HIVIEW_FILE_RENAME: {
uint8 type = fp->header.common.type;
uint32 size = fp->header.size - sizeof(HiviewFileHeader);
int32 ret = HIVIEW_FileMove(fp->path, dest);
if (InitHiviewFile(fp, type, size) == FALSE || ret != 0) {
HIVIEW_MutexUnlock(fp->mutex);
HIVIEW_UartPrint("Procfile failed, type : HIVIEW_FILE_RENAME");
return -1;
}
break;
}
default:
HIVIEW_MutexUnlock(fp->mutex);
HIVIEW_UartPrint("Procfile failed, type : Unknown type");
return -1;
}
HIVIEW_MutexUnlock(fp->mutex);
return 0;
}
int IsValidPath(const char *path)
{
if (strcmp(path, HIVIEW_FILE_PATH_LOG) == 0 ||
strcmp(path, HIVIEW_FILE_PATH_UE_EVENT) == 0 ||
strcmp(path, HIVIEW_FILE_PATH_FAULT_EVENT) == 0 ||
strcmp(path, HIVIEW_FILE_PATH_STAT_EVENT) == 0 ||
strcmp(path, HIVIEW_FILE_OUT_PATH_LOG) == 0 ||
strcmp(path, HIVIEW_FILE_OUT_PATH_UE_EVENT) == 0 ||
strcmp(path, HIVIEW_FILE_OUT_PATH_FAULT_EVENT) == 0 ||
strcmp(path, HIVIEW_FILE_OUT_PATH_STAT_EVENT) == 0) {
return -1;
}
return 0;
}
void RegisterFileWatcher(HiviewFile *fp, FileProc func, const char *path)
{
if (fp == NULL) {
return;
}
fp->pFunc = func;
if (path == NULL || IsValidPath(path) != 0) {
return;
}
int len = strlen(path) + 1;
char* tmp = (char*)HIVIEW_MemAlloc(MEM_POOL_HIVIEW_ID, len);
if (tmp == NULL) {
return;
}
if (strcpy_s(tmp, len, path) != EOK) {
HIVIEW_MemFree(MEM_POOL_HIVIEW_ID, tmp);
return;
}
fp->outPath = tmp;
}
void UnRegisterFileWatcher(HiviewFile *fp, FileProc func)
{
(void)func;
fp->pFunc = NULL;
if (IsValidPath(fp->outPath) == 0) {
HIVIEW_MemFree(MEM_POOL_HIVIEW_ID, fp->outPath);
}
switch (fp->header.common.type) {
case HIVIEW_FAULT_EVENT_FILE:
fp->outPath = HIVIEW_FILE_OUT_PATH_FAULT_EVENT;
break;
case HIVIEW_UE_EVENT_FILE:
fp->outPath = HIVIEW_FILE_OUT_PATH_UE_EVENT;
break;
case HIVIEW_STAT_EVENT_FILE:
fp->outPath = HIVIEW_FILE_OUT_PATH_STAT_EVENT;
break;
case HIVIEW_LOG_TEXT_FILE:
case HIVIEW_LOG_BIN_FILE:
fp->outPath = HIVIEW_FILE_OUT_PATH_LOG;
break;
default:
break;
}
}