• 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         uint16 hieventID = 1;
50         HiEvent *hievent = HIEVENT_CREATE(HIEVENT_FAULT, hieventID, 2); // 2 params
51         HIEVENT_PUT_INT_VALUE(hievent, 0, (int32)type);
52         HIEVENT_PUT_INT_VALUE(hievent, 1, errnoRecord);
53         HIEVENT_REPORT(hievent);
54         return FALSE;
55     }
56 
57     HiviewFileHeader *pHeader = &(fp->header);
58     FileHeaderCommon *pCommon = &(pHeader->common);
59     pCommon->type = (uint8)type;
60     pHeader->size = size + sizeof(HiviewFileHeader);
61     fp->configSize = size;
62     // Create file for the first time
63     if (ReadFileHeader(fp) == FALSE) {
64         switch (pCommon->type) {
65             case HIVIEW_LOG_TEXT_FILE:
66                 pCommon->prefix = HIVIEW_FILE_HEADER_PREFIX_TEXT;
67                 break;
68             case HIVIEW_LOG_BIN_FILE:
69                 pCommon->prefix = HIVIEW_FILE_HEADER_PREFIX_LOG;
70                 break;
71             case HIVIEW_FAULT_EVENT_FILE:
72             case HIVIEW_UE_EVENT_FILE:
73             case HIVIEW_STAT_EVENT_FILE:
74                 pCommon->prefix = HIVIEW_FILE_HEADER_PREFIX_EVENT;
75                 break;
76             default:
77                 break;
78         }
79         pCommon->codeMainVersion = HIVIEW_FILE_HEADER_MAIN_VERSION;
80         pCommon->codeSubVersion = HIVIEW_FILE_HEADER_SUB_VERSION;
81         pCommon->defineFileVersion = GetDefineFileVersion(pCommon->type);
82         pHeader->createTime = (uint32)(HIVIEW_GetCurrentTime() / MS_PER_SECOND);
83         pHeader->rCursor = sizeof(HiviewFileHeader);
84         pHeader->wCursor = sizeof(HiviewFileHeader);
85         if (WriteFileHeader(fp) == FALSE) {
86             return FALSE;
87         }
88     } else {
89         // Version number may change after system upgrade
90         pCommon->codeMainVersion = HIVIEW_FILE_HEADER_MAIN_VERSION;
91         pCommon->codeSubVersion = HIVIEW_FILE_HEADER_SUB_VERSION;
92         pCommon->defineFileVersion = GetDefineFileVersion(pCommon->type);
93     }
94     HILOG_INFO(HILOG_MODULE_HIVIEW, "InitHiviewFile for type %d success", (int32)type);
95     return TRUE;
96 }
97 
WriteFileHeader(HiviewFile * fp)98 boolean WriteFileHeader(HiviewFile *fp)
99 {
100     if (fp == NULL || fp->fhandle < 0) {
101         return FALSE;
102     }
103 
104     int32 ret;
105     if (HIVIEW_FileSeek(fp->fhandle, 0, HIVIEW_SEEK_SET) >= 0) {
106         HiviewFileHeader tmpHeader = fp->header;
107 #if LITTLE_ENDIAN_SYSTEM
108         tmpHeader.common.prefix = Change32Endian(tmpHeader.common.prefix);
109         tmpHeader.common.defineFileVersion = Change32Endian(tmpHeader.common.defineFileVersion);
110         tmpHeader.createTime = Change32Endian(tmpHeader.createTime);
111 #endif
112         ret = HIVIEW_FileWrite(fp->fhandle, (uint8 *)&(tmpHeader), sizeof(HiviewFileHeader));
113         if (ret == sizeof(HiviewFileHeader)) {
114             return TRUE;
115         }
116     }
117 
118     return FALSE;
119 }
120 
ReadFileHeader(HiviewFile * fp)121 boolean ReadFileHeader(HiviewFile *fp)
122 {
123     HiviewFileHeader h = { 0 };
124 
125     if (fp == NULL || fp->fhandle < 0) {
126         return FALSE;
127     }
128 
129     int32 ret;
130     if (HIVIEW_FileSeek(fp->fhandle, 0, HIVIEW_SEEK_SET) < 0) {
131         return FALSE;
132     }
133     ret = HIVIEW_FileRead(fp->fhandle, (uint8 *)&h, sizeof(HiviewFileHeader));
134 #if LITTLE_ENDIAN_SYSTEM
135     h.common.prefix = Change32Endian(h.common.prefix);
136     h.common.defineFileVersion = Change32Endian(h.common.defineFileVersion);
137     h.createTime = Change32Endian(h.createTime);
138 #endif
139     h.wCursor = HIVIEW_FileSize(fp->fhandle);
140     h.rCursor = sizeof(HiviewFileHeader);
141     if ((ret == sizeof(HiviewFileHeader)) &&
142         ((h.common.prefix & 0xFFFFFF00) == HIVIEW_FILE_HEADER_PREFIX_MASK) &&
143         (h.wCursor >= sizeof(HiviewFileHeader))) {
144         (void)memcpy_s(&(fp->header), sizeof(HiviewFileHeader), (void *)&h, sizeof(HiviewFileHeader));
145         return TRUE;
146     } else {
147         return FALSE;
148     }
149 }
150 
WriteToFile(HiviewFile * fp,const uint8 * data,uint32 len)151 int32 WriteToFile(HiviewFile *fp, const uint8 *data, uint32 len)
152 {
153     if (fp == NULL || fp->fhandle < 0 || len == 0) {
154         return 0;
155     }
156     int32 wLen = 0;
157     HiviewFileHeader *h = &(fp->header);
158     // overflow
159     if (h->wCursor + len > h->size) {
160         ProcFile(fp, fp->outPath, HIVIEW_FILE_RENAME);
161         if (fp->pFunc != NULL) {
162             fp->pFunc(fp->outPath, h->common.type, HIVIEW_FILE_FULL);
163         }
164     }
165     if (HIVIEW_FileSeek(fp->fhandle, h->wCursor, HIVIEW_SEEK_SET) < 0) {
166         return 0;
167     }
168     if ((int32)len == HIVIEW_FileWrite(fp->fhandle, data, len)) {
169         h->wCursor += len;
170         wLen += len;
171     }
172     return wLen;
173 }
174 
ReadFromFile(HiviewFile * fp,uint8 * data,uint32 readLen)175 int32 ReadFromFile(HiviewFile *fp, uint8 *data, uint32 readLen)
176 {
177     if (fp == NULL || data == NULL || fp->fhandle < 0 || readLen == 0) {
178         return 0;
179     }
180 
181     HiviewFileHeader* h = &(fp->header);
182     uint32 wCursor = h->wCursor;
183     uint32 rCursor = h->rCursor;
184     if (wCursor < readLen) {
185         return 0;
186     }
187     int32 rLen = (readLen <= (wCursor - rCursor)) ? readLen : (wCursor - rCursor);
188     if (HIVIEW_FileSeek(fp->fhandle, rCursor, HIVIEW_SEEK_SET) < 0) {
189         return 0;
190     }
191     if ((int32)rLen == HIVIEW_FileRead(fp->fhandle, data, rLen)) {
192         h->rCursor += rLen;
193     } else {
194         rLen = 0;
195     }
196     return rLen;
197 }
198 
GetFileUsedSize(HiviewFile * fp)199 uint32 GetFileUsedSize(HiviewFile *fp)
200 {
201     if (fp == NULL || fp->fhandle < 0) {
202         return 0;
203     }
204     return fp->header.wCursor;
205 }
206 
GetFileFreeSize(HiviewFile * fp)207 uint32 GetFileFreeSize(HiviewFile *fp)
208 {
209     if (fp == NULL || fp->fhandle < 0) {
210         return 0;
211     }
212 
213     return (fp->header.size - fp->header.wCursor);
214 }
215 
CloseHiviewFile(HiviewFile * fp)216 int32 CloseHiviewFile(HiviewFile *fp)
217 {
218     if (fp != NULL && fp->fhandle > 0) {
219         int32 ret = HIVIEW_FileClose(fp->fhandle);
220         fp->fhandle = -1;
221         UnRegisterFileWatcher(fp, NULL);
222         return ret;
223     }
224     return -1;
225 }
226 
ProcFile(HiviewFile * fp,const char * dest,FileProcMode mode)227 int8 ProcFile(HiviewFile *fp, const char *dest, FileProcMode mode)
228 {
229     if (fp == NULL || fp->fhandle < 0) {
230         return -1;
231     }
232 
233     if (HIVIEW_MutexLockOrWait(fp->mutex, OUT_PATH_WAIT_TIMEOUT) != 0) {
234         HIVIEW_UartPrint("Procfile failed, get lock fail");
235         return -1;
236     }
237     switch (mode) {
238         case HIVIEW_FILE_COPY: {
239             HIVIEW_FileClose(fp->fhandle);
240             int32 ret = HIVIEW_FileCopy(fp->path, dest);
241             fp->fhandle = HIVIEW_FileOpen(fp->path);
242             if (ret != 0 || fp->fhandle < 0) {
243                 int32 errnoRecord = (int32)errno;
244                 HIVIEW_MutexUnlock(fp->mutex);
245                 uint16 hieventID = 1;
246                 HiEvent *hievent = HIEVENT_CREATE(HIEVENT_FAULT, hieventID, 2); // 2 params
247                 HIEVENT_PUT_INT_VALUE(hievent, 0, (int32)fp->header.common.type);
248                 HIEVENT_PUT_INT_VALUE(hievent, 1, errnoRecord);
249                 HIEVENT_REPORT(hievent);
250                 HIVIEW_UartPrint("Procfile failed, type : HIVIEW_FILE_COPY");
251                 return -1;
252             }
253             break;
254         }
255         case HIVIEW_FILE_RENAME: {
256             HIVIEW_FileClose(fp->fhandle);
257             uint8 type = fp->header.common.type;
258             uint32 size = fp->configSize;
259             int32 ret = HIVIEW_FileMove(fp->path, dest);
260             if (InitHiviewFile(fp, (HiviewFileType)type, size) == FALSE || ret != 0) {
261                 HIVIEW_MutexUnlock(fp->mutex);
262                 HIVIEW_UartPrint("Procfile failed, type : HIVIEW_FILE_RENAME");
263                 return -1;
264             }
265             break;
266         }
267         default:
268             HIVIEW_MutexUnlock(fp->mutex);
269             HIVIEW_UartPrint("Procfile failed, type : Unknown type");
270             return -1;
271     }
272     HIVIEW_MutexUnlock(fp->mutex);
273     return 0;
274 }
275 
IsValidPath(const char * path)276 int IsValidPath(const char *path)
277 {
278     if (strcmp(path, HIVIEW_FILE_PATH_LOG) == 0 ||
279         strcmp(path, HIVIEW_FILE_PATH_UE_EVENT) == 0 ||
280         strcmp(path, HIVIEW_FILE_PATH_FAULT_EVENT) == 0 ||
281         strcmp(path, HIVIEW_FILE_PATH_STAT_EVENT) == 0 ||
282         strcmp(path, HIVIEW_FILE_OUT_PATH_LOG) == 0 ||
283         strcmp(path, HIVIEW_FILE_OUT_PATH_UE_EVENT) == 0 ||
284         strcmp(path, HIVIEW_FILE_OUT_PATH_FAULT_EVENT) == 0 ||
285         strcmp(path, HIVIEW_FILE_OUT_PATH_STAT_EVENT) == 0) {
286             return -1;
287     }
288     return 0;
289 }
290 
RegisterFileWatcher(HiviewFile * fp,FileProc func,const char * path)291 void RegisterFileWatcher(HiviewFile *fp, FileProc func, const char *path)
292 {
293     if (fp == NULL || func == NULL) {
294         return;
295     }
296     fp->pFunc = func;
297     if (path == NULL || IsValidPath(path) != 0) {
298         return;
299     }
300 
301     int len = strlen(path) + 1;
302     char* tmp = (char*)HIVIEW_MemAlloc(MEM_POOL_HIVIEW_ID, len);
303     if (tmp == NULL) {
304         return;
305     }
306     if (strcpy_s(tmp, len, path) != EOK) {
307         HIVIEW_MemFree(MEM_POOL_HIVIEW_ID, tmp);
308         return;
309     }
310     fp->outPath = tmp;
311 }
312 
UnRegisterFileWatcher(HiviewFile * fp,FileProc func)313 void UnRegisterFileWatcher(HiviewFile *fp, FileProc func)
314 {
315     (void)func;
316     fp->pFunc = NULL;
317     if (IsValidPath(fp->outPath) == 0) {
318         HIVIEW_MemFree(MEM_POOL_HIVIEW_ID, fp->outPath);
319     }
320     switch (fp->header.common.type) {
321         case HIVIEW_FAULT_EVENT_FILE:
322             fp->outPath = HIVIEW_FILE_OUT_PATH_FAULT_EVENT;
323             break;
324         case HIVIEW_UE_EVENT_FILE:
325             fp->outPath = HIVIEW_FILE_OUT_PATH_UE_EVENT;
326             break;
327         case HIVIEW_STAT_EVENT_FILE:
328             fp->outPath = HIVIEW_FILE_OUT_PATH_STAT_EVENT;
329             break;
330         case HIVIEW_LOG_TEXT_FILE:
331         case HIVIEW_LOG_BIN_FILE:
332             fp->outPath = HIVIEW_FILE_OUT_PATH_LOG;
333             break;
334         default:
335             break;
336     }
337 }
338