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