• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hiview_config.h"
17 #include "hiview_def.h"
18 #include "hiview_event.h"
19 #include "hiview_file.h"
20 #include "hiview_log.h"
21 #include "hiview_util.h"
22 #include "ohos_types.h"
23 #include "securec.h"
24 
GetDefineFileVersion(uint8 type)25 static uint32 GetDefineFileVersion(uint8 type)
26 {
27     switch (type) {
28         case HIVIEW_UE_EVENT_FILE:
29             return HIVIEW_UE_EVENT_VER;
30         case HIVIEW_STAT_EVENT_FILE:
31             return HIVIEW_STATIC_EVENT_VER;
32         case HIVIEW_FAULT_EVENT_FILE:
33             return HIVIEW_FAULT_EVENT_VER;
34         default:
35             // non-event file
36             return 0;
37     }
38 }
39 
InitHiviewFile(HiviewFile * fp,HiviewFileType type,uint32 size)40 boolean InitHiviewFile(HiviewFile *fp, HiviewFileType type, uint32 size)
41 {
42     if (fp == NULL || fp->path == NULL) {
43         return FALSE;
44     }
45 
46     fp->fhandle = HIVIEW_FileOpen(fp->path);
47     if (fp->fhandle < 0) {
48         int32 errnoRecord = (int32)errno;
49         HILOG_ERROR(HILOG_MODULE_HIVIEW, "HIVIEW_FileOpen failed type %d, errno %d", (int32)type, errnoRecord);
50         uint16 hieventID = 1;
51         HiEvent *hievent = HIEVENT_CREATE(HIEVENT_FAULT, hieventID, 2); // 2 params
52         HIEVENT_PUT_INT_VALUE(hievent, 0, (int32)type);
53         HIEVENT_PUT_INT_VALUE(hievent, 1, errnoRecord);
54         HIEVENT_REPORT(hievent);
55         return FALSE;
56     }
57 
58     HiviewFileHeader *pHeader = &(fp->header);
59     FileHeaderCommon *pCommon = &(pHeader->common);
60     pCommon->type = (uint8)type;
61     pHeader->size = size + sizeof(HiviewFileHeader);
62     fp->configSize = size;
63     // Create file for the first time
64     if (ReadFileHeader(fp) == FALSE) {
65         switch (pCommon->type) {
66             case HIVIEW_LOG_TEXT_FILE:
67                 pCommon->prefix = HIVIEW_FILE_HEADER_PREFIX_TEXT;
68                 break;
69             case HIVIEW_LOG_BIN_FILE:
70                 pCommon->prefix = HIVIEW_FILE_HEADER_PREFIX_LOG;
71                 break;
72             case HIVIEW_FAULT_EVENT_FILE:
73             case HIVIEW_UE_EVENT_FILE:
74             case HIVIEW_STAT_EVENT_FILE:
75                 pCommon->prefix = HIVIEW_FILE_HEADER_PREFIX_EVENT;
76                 break;
77             default:
78                 break;
79         }
80         pCommon->codeMainVersion = HIVIEW_FILE_HEADER_MAIN_VERSION;
81         pCommon->codeSubVersion = HIVIEW_FILE_HEADER_SUB_VERSION;
82         pCommon->defineFileVersion = GetDefineFileVersion(pCommon->type);
83         pHeader->createTime = (uint32)(HIVIEW_GetCurrentTime() / MS_PER_SECOND);
84         pHeader->rCursor = sizeof(HiviewFileHeader);
85         pHeader->wCursor = sizeof(HiviewFileHeader);
86         if (WriteFileHeader(fp) == FALSE) {
87             HILOG_ERROR(HILOG_MODULE_HIVIEW, "WriteFileHeader failed type %d, errno %d", (int32)type, (int32)errno);
88             return FALSE;
89         }
90     } else {
91         // Version number may change after system upgrade
92         pCommon->codeMainVersion = HIVIEW_FILE_HEADER_MAIN_VERSION;
93         pCommon->codeSubVersion = HIVIEW_FILE_HEADER_SUB_VERSION;
94         pCommon->defineFileVersion = GetDefineFileVersion(pCommon->type);
95     }
96     HILOG_INFO(HILOG_MODULE_HIVIEW, "InitHiviewFile for type %d success", (int32)type);
97     return TRUE;
98 }
99 
WriteFileHeader(HiviewFile * fp)100 boolean WriteFileHeader(HiviewFile *fp)
101 {
102     if (fp == NULL || fp->fhandle < 0) {
103         return FALSE;
104     }
105 
106     int32 ret;
107     if (HIVIEW_FileSeek(fp->fhandle, 0, HIVIEW_SEEK_SET) >= 0) {
108         HiviewFileHeader tmpHeader = fp->header;
109 #if LITTLE_ENDIAN_SYSTEM
110         tmpHeader.common.prefix = Change32Endian(tmpHeader.common.prefix);
111         tmpHeader.common.defineFileVersion = Change32Endian(tmpHeader.common.defineFileVersion);
112         tmpHeader.createTime = Change32Endian(tmpHeader.createTime);
113 #endif
114         ret = HIVIEW_FileWrite(fp->fhandle, (uint8 *)&(tmpHeader), sizeof(HiviewFileHeader));
115         if (ret == sizeof(HiviewFileHeader)) {
116             return TRUE;
117         }
118     }
119 
120     return FALSE;
121 }
122 
ReadFileHeader(HiviewFile * fp)123 boolean ReadFileHeader(HiviewFile *fp)
124 {
125     HiviewFileHeader h = { 0 };
126 
127     if (fp == NULL || fp->fhandle < 0) {
128         return FALSE;
129     }
130 
131     int32 ret;
132     if (HIVIEW_FileSeek(fp->fhandle, 0, HIVIEW_SEEK_SET) < 0) {
133         return FALSE;
134     }
135     ret = HIVIEW_FileRead(fp->fhandle, (uint8 *)&h, sizeof(HiviewFileHeader));
136 #if LITTLE_ENDIAN_SYSTEM
137     h.common.prefix = Change32Endian(h.common.prefix);
138     h.common.defineFileVersion = Change32Endian(h.common.defineFileVersion);
139     h.createTime = Change32Endian(h.createTime);
140 #endif
141     h.wCursor = HIVIEW_FileSize(fp->fhandle);
142     h.rCursor = sizeof(HiviewFileHeader);
143     if ((ret == sizeof(HiviewFileHeader)) &&
144         ((h.common.prefix & 0xFFFFFF00) == HIVIEW_FILE_HEADER_PREFIX_MASK) &&
145         (h.wCursor >= sizeof(HiviewFileHeader))) {
146         (void)memcpy_s(&(fp->header), sizeof(HiviewFileHeader), (void *)&h, sizeof(HiviewFileHeader));
147         return TRUE;
148     } else {
149         return FALSE;
150     }
151 }
152 
WriteToFile(HiviewFile * fp,const uint8 * data,uint32 len)153 int32 WriteToFile(HiviewFile *fp, const uint8 *data, uint32 len)
154 {
155     if (fp == NULL || fp->fhandle < 0 || len == 0) {
156         return 0;
157     }
158     int32 wLen = 0;
159     HiviewFileHeader *h = &(fp->header);
160     // overflow
161     if (h->wCursor + len > h->size) {
162         ProcFile(fp, fp->outPath, HIVIEW_FILE_RENAME);
163         if (fp->pFunc != NULL) {
164             fp->pFunc(fp->outPath, h->common.type, HIVIEW_FILE_FULL);
165         }
166     }
167     if (HIVIEW_FileSeek(fp->fhandle, h->wCursor, HIVIEW_SEEK_SET) < 0) {
168         return 0;
169     }
170     if ((int32)len == HIVIEW_FileWrite(fp->fhandle, data, len)) {
171         h->wCursor += len;
172         wLen += len;
173     }
174     return wLen;
175 }
176 
ReadFromFile(HiviewFile * fp,uint8 * data,uint32 readLen)177 int32 ReadFromFile(HiviewFile *fp, uint8 *data, uint32 readLen)
178 {
179     if (fp == NULL || data == NULL || fp->fhandle < 0 || readLen == 0) {
180         return 0;
181     }
182 
183     HiviewFileHeader* h = &(fp->header);
184     uint32 wCursor = h->wCursor;
185     uint32 rCursor = h->rCursor;
186     if (wCursor < readLen) {
187         return 0;
188     }
189     int32 rLen = (readLen <= (wCursor - rCursor)) ? readLen : (wCursor - rCursor);
190     if (HIVIEW_FileSeek(fp->fhandle, rCursor, HIVIEW_SEEK_SET) < 0) {
191         return 0;
192     }
193     if ((int32)rLen == HIVIEW_FileRead(fp->fhandle, data, rLen)) {
194         h->rCursor += rLen;
195     } else {
196         rLen = 0;
197     }
198     return rLen;
199 }
200 
GetFileUsedSize(HiviewFile * fp)201 uint32 GetFileUsedSize(HiviewFile *fp)
202 {
203     if (fp == NULL || fp->fhandle < 0) {
204         return 0;
205     }
206     return fp->header.wCursor;
207 }
208 
GetFileFreeSize(HiviewFile * fp)209 uint32 GetFileFreeSize(HiviewFile *fp)
210 {
211     if (fp == NULL || fp->fhandle < 0) {
212         return 0;
213     }
214 
215     return (fp->header.size - fp->header.wCursor);
216 }
217 
CloseHiviewFile(HiviewFile * fp)218 int32 CloseHiviewFile(HiviewFile *fp)
219 {
220     if (fp != NULL && fp->fhandle > 0) {
221         int32 ret = HIVIEW_FileClose(fp->fhandle);
222         fp->fhandle = -1;
223         UnRegisterFileWatcher(fp, NULL);
224         return ret;
225     }
226     return -1;
227 }
228 
ProcFile(HiviewFile * fp,const char * dest,FileProcMode mode)229 int8 ProcFile(HiviewFile *fp, const char *dest, FileProcMode mode)
230 {
231     if (fp == NULL || fp->fhandle < 0) {
232         return -1;
233     }
234 
235     if (HIVIEW_MutexLockOrWait(fp->mutex, OUT_PATH_WAIT_TIMEOUT) != 0) {
236         HIVIEW_UartPrint("Procfile failed, get lock fail");
237         return -1;
238     }
239     switch (mode) {
240         case HIVIEW_FILE_COPY: {
241             HIVIEW_FileClose(fp->fhandle);
242             int32 ret = HIVIEW_FileCopy(fp->path, dest);
243             fp->fhandle = HIVIEW_FileOpen(fp->path);
244             if (ret != 0 || fp->fhandle < 0) {
245                 int32 errnoRecord = (int32)errno;
246                 HIVIEW_MutexUnlock(fp->mutex);
247                 uint16 hieventID = 1;
248                 HiEvent *hievent = HIEVENT_CREATE(HIEVENT_FAULT, hieventID, 2); // 2 params
249                 HIEVENT_PUT_INT_VALUE(hievent, 0, (int32)fp->header.common.type);
250                 HIEVENT_PUT_INT_VALUE(hievent, 1, errnoRecord);
251                 HIEVENT_REPORT(hievent);
252                 HIVIEW_UartPrint("Procfile failed, type : HIVIEW_FILE_COPY");
253                 return -1;
254             }
255             break;
256         }
257         case HIVIEW_FILE_RENAME: {
258             HIVIEW_FileClose(fp->fhandle);
259             uint8 type = fp->header.common.type;
260             uint32 size = fp->configSize;
261             int32 ret = HIVIEW_FileMove(fp->path, dest);
262             if (InitHiviewFile(fp, (HiviewFileType)type, size) == FALSE || ret != 0) {
263                 HIVIEW_MutexUnlock(fp->mutex);
264                 HIVIEW_UartPrint("Procfile failed, type : HIVIEW_FILE_RENAME");
265                 return -1;
266             }
267             break;
268         }
269         default:
270             HIVIEW_MutexUnlock(fp->mutex);
271             HIVIEW_UartPrint("Procfile failed, type : Unknown type");
272             return -1;
273     }
274     HIVIEW_MutexUnlock(fp->mutex);
275     return 0;
276 }
277 
IsValidPath(const char * path)278 int IsValidPath(const char *path)
279 {
280     if (strcmp(path, HIVIEW_FILE_PATH_LOG) == 0 ||
281         strcmp(path, HIVIEW_FILE_PATH_UE_EVENT) == 0 ||
282         strcmp(path, HIVIEW_FILE_PATH_FAULT_EVENT) == 0 ||
283         strcmp(path, HIVIEW_FILE_PATH_STAT_EVENT) == 0 ||
284         strcmp(path, HIVIEW_FILE_OUT_PATH_LOG) == 0 ||
285         strcmp(path, HIVIEW_FILE_OUT_PATH_UE_EVENT) == 0 ||
286         strcmp(path, HIVIEW_FILE_OUT_PATH_FAULT_EVENT) == 0 ||
287         strcmp(path, HIVIEW_FILE_OUT_PATH_STAT_EVENT) == 0) {
288             return -1;
289     }
290     return 0;
291 }
292 
RegisterFileWatcher(HiviewFile * fp,FileProc func,const char * path)293 void RegisterFileWatcher(HiviewFile *fp, FileProc func, const char *path)
294 {
295     if (fp == NULL || func == NULL) {
296         return;
297     }
298     fp->pFunc = func;
299     if (path == NULL || IsValidPath(path) != 0) {
300         return;
301     }
302 
303     int len = strlen(path) + 1;
304     char* tmp = (char*)HIVIEW_MemAlloc(MEM_POOL_HIVIEW_ID, len);
305     if (tmp == NULL) {
306         return;
307     }
308     if (strcpy_s(tmp, len, path) != EOK) {
309         HIVIEW_MemFree(MEM_POOL_HIVIEW_ID, tmp);
310         return;
311     }
312     fp->outPath = tmp;
313 }
314 
UnRegisterFileWatcher(HiviewFile * fp,FileProc func)315 void UnRegisterFileWatcher(HiviewFile *fp, FileProc func)
316 {
317     (void)func;
318     fp->pFunc = NULL;
319     if (IsValidPath(fp->outPath) == 0) {
320         HIVIEW_MemFree(MEM_POOL_HIVIEW_ID, fp->outPath);
321     }
322     switch (fp->header.common.type) {
323         case HIVIEW_FAULT_EVENT_FILE:
324             fp->outPath = HIVIEW_FILE_OUT_PATH_FAULT_EVENT;
325             break;
326         case HIVIEW_UE_EVENT_FILE:
327             fp->outPath = HIVIEW_FILE_OUT_PATH_UE_EVENT;
328             break;
329         case HIVIEW_STAT_EVENT_FILE:
330             fp->outPath = HIVIEW_FILE_OUT_PATH_STAT_EVENT;
331             break;
332         case HIVIEW_LOG_TEXT_FILE:
333         case HIVIEW_LOG_BIN_FILE:
334             fp->outPath = HIVIEW_FILE_OUT_PATH_LOG;
335             break;
336         default:
337             break;
338     }
339 }
340