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