1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 * Description: offline log file saved to the storage
15 */
16
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include "log_file.h"
20 #include "uapi_crc.h"
21 #include "fcntl.h"
22 #include "errcode.h"
23 #include "securec.h"
24 #include "stdbool.h"
25 #include "dirent.h"
26 #include "soc_osal.h"
27 #include "common_def.h"
28 #include "dfx_adapt_layer.h"
29 #include "sys/stat.h"
30 #include "debug_print.h"
31 #include "log_file_common.h"
32 #include "log_file_file.h"
33
34 #if (CONFIG_DFX_SUPPORT_OFFLINE_LOG_FILE == YES)
35 #if (CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES)
36
37 #define NOT_SPACE_NUM_MAX 5
38 STATIC uint8_t g_not_space_nums = 0;
39 STATIC uint8_t g_full_path[MAX_FILE_PATH_LEN] = {0};
40
logfile_get_next_record(store_file_info_t * file_info,uint32_t start_pos,uint32_t * next_pos)41 STATIC errcode_t logfile_get_next_record(store_file_info_t *file_info, uint32_t start_pos, uint32_t *next_pos)
42 {
43 store_record_info_t record_info;
44 uint32_t record_pos = start_pos;
45 uint32_t next_record_pos;
46 uint32_t loop_count = 0;
47
48 do {
49 int32_t tmp_len = (int32_t)file_info->file_head.file_size - (int32_t)record_pos;
50
51 (void)memset_s(&record_info, sizeof(record_info), 0, sizeof(record_info));
52
53 lseek(file_info->fd, record_pos, SEEK_SET);
54
55 if (tmp_len >= (int32_t)sizeof(store_record_info_t)) {
56 (void)read(file_info->fd, &record_info, sizeof(record_info));
57 if (tmp_len > record_info.len) {
58 next_record_pos = record_pos + record_info.len;
59 } else {
60 next_record_pos = (uint32_t)(file_info->file_head.offset + record_info.len - tmp_len);
61 }
62 } else if (tmp_len < (int32_t)sizeof(store_record_info_t)) {
63 (void)read(file_info->fd, &record_info, (uint32_t)tmp_len);
64 lseek(file_info->fd, file_info->file_head.offset, SEEK_SET);
65 (void)read(file_info->fd, ((uint8_t *)&record_info) + tmp_len, sizeof(record_info) - (uint32_t)tmp_len);
66 next_record_pos = (uint32_t)(file_info->file_head.offset + record_info.len - tmp_len);
67 } else {
68 return ERRCODE_DFX_LOGFILE_INTERAL_FAIL;
69 }
70
71 if (logfile_check_record_head_valid(&record_info) == true) {
72 *next_pos = next_record_pos;
73 return ERRCODE_SUCC;
74 }
75
76 if (record_pos >= file_info->file_head.file_size) {
77 record_pos = file_info->file_head.offset;
78 } else {
79 record_pos++;
80 }
81 loop_count++;
82 } while (loop_count < file_info->file_head.file_size);
83
84 return ERRCODE_DFX_LOGFILE_RECORD_INVALID;
85 }
86
logfile_discard_older_records(store_file_info_t * file_info,uint16_t record_len,uint32_t space_left)87 STATIC errcode_t logfile_discard_older_records(store_file_info_t *file_info, uint16_t record_len, uint32_t space_left)
88 {
89 uint32_t next_pos = 0;
90 uint32_t space_temp = space_left;
91 errcode_t ret;
92 while (space_temp < record_len) {
93 /* 获取下一个记录的位置 */
94 ret = logfile_get_next_record(file_info, file_info->file_head.first_record_pos, &next_pos);
95 if (ret != ERRCODE_SUCC) {
96 return ret;
97 }
98
99 space_temp = space_temp + next_pos - file_info->file_head.first_record_pos;
100
101 file_info->file_head.first_record_pos = next_pos;
102 file_info->file_head.records--;
103 }
104
105 return ERRCODE_SUCC;
106 }
107
logfile_save_data_err(int32_t error_no,int32_t num)108 STATIC errcode_t logfile_save_data_err(int32_t error_no, int32_t num)
109 {
110 if (error_no != ENOSPC) {
111 dfx_log_err("logfile save data failed. errno is %d, num is %d\r\n", error_no, num);
112 return ERRCODE_DFX_LOGFILE_WRITE_FAIL;
113 }
114
115 if (g_not_space_nums < NOT_SPACE_NUM_MAX) {
116 g_not_space_nums++;
117 dfx_log_err("logfile save data failed. errno is %d, num is %d\r\n", error_no, num);
118 }
119
120 return ERRCODE_DFX_LOGFILE_NOT_ENOUGH_SPACE;
121 }
122
logfile_save_data(store_file_info_t * file_info,uint8_t * data,uint32_t data_len)123 STATIC errcode_t logfile_save_data(store_file_info_t *file_info, uint8_t *data, uint32_t data_len)
124 {
125 int32_t write_byte;
126
127 /* 判断数据是否需要翻转至文件头存储 */
128 if ((file_info->file_head.file_size - file_info->file_head.cur_pos) >= data_len) {
129 write_byte = (int32_t)write(file_info->fd, data, data_len);
130 if (write_byte != (int32_t)data_len) {
131 return logfile_save_data_err(get_errno(), 0);
132 }
133
134 g_not_space_nums = 0;
135 file_info->file_head.cur_pos += data_len;
136 } else {
137 uint32_t record_len_written = file_info->file_head.file_size - file_info->file_head.cur_pos;
138 uint32_t record_len_remained = data_len - record_len_written;
139 write_byte = write(file_info->fd, data, record_len_written);
140 if (write_byte != (int32_t)record_len_written) {
141 return logfile_save_data_err(get_errno(), 1); /* 1 : 1st log */
142 }
143 g_not_space_nums = 0;
144
145 lseek(file_info->fd, file_info->file_head.offset, SEEK_SET);
146 write_byte = write(file_info->fd, data + record_len_written, record_len_remained);
147 if (write_byte != (int32_t)record_len_remained) {
148 return logfile_save_data_err(get_errno(), 2); /* 2 : 2nd log */
149 }
150
151 file_info->file_head.cur_pos = file_info->file_head.offset + record_len_remained;
152 }
153 return ERRCODE_SUCC;
154 }
155
logfile_single_file_write(store_file_info_t * file_info,uint8_t * data,uint32_t data_len)156 errcode_t logfile_single_file_write(store_file_info_t *file_info, uint8_t *data, uint32_t data_len)
157 {
158 store_record_info_t record_info;
159 record_info.magic = RECORD_HEAD_MAGIC;
160 record_info.type = file_info->type;
161 record_info.len = (uint16_t)(sizeof(record_info) + data_len);
162 record_info.rev = 1;
163 record_info.crc = uapi_crc16(0, (uint8_t *)&record_info, sizeof(store_record_info_t) - sizeof(uint16_t));
164
165 uint32_t space_left;
166
167 if (file_info->file_head.cur_pos >= file_info->file_head.first_record_pos) {
168 /* 当前记录位置在第一个记录后面 */
169 space_left = file_info->file_head.file_size - file_info->file_head.cur_pos +
170 file_info->file_head.first_record_pos - file_info->file_head.offset;
171 } else {
172 /* 当前记录位置在第一个记录的前面 */
173 space_left = file_info->file_head.first_record_pos - file_info->file_head.cur_pos;
174 }
175
176 /* 废弃最旧的记录以腾出空间 */
177 logfile_discard_older_records(file_info, record_info.len, space_left);
178
179 lseek(file_info->fd, file_info->file_head.cur_pos, SEEK_SET);
180
181 /* 写入记录头 */
182 logfile_save_data(file_info, (uint8_t *)&record_info, (uint32_t)sizeof(record_info));
183
184 /* 写入Data */
185 logfile_save_data(file_info, data, data_len);
186
187 file_info->file_head.records += 1;
188
189 /* 更新文件头 */
190 file_info->file_head.crc =
191 uapi_crc16(0, (uint8_t *)&(file_info->file_head), sizeof(store_file_head_t) - sizeof(uint16_t));
192 lseek(file_info->fd, 0, SEEK_SET);
193 write(file_info->fd, &(file_info->file_head), sizeof(store_file_head_t));
194
195 return ERRCODE_SUCC;
196 }
197
logfile_load_multi_files_info(store_file_info_t * file_info)198 STATIC void logfile_load_multi_files_info(store_file_info_t *file_info)
199 {
200 uint32_t path_len = (uint32_t)strlen(file_info->file_cfg.path);
201
202 (void)memset_s((char *)g_full_path, MAX_FILE_PATH_LEN, 0, MAX_FILE_PATH_LEN);
203 if (strncpy_s((char *)g_full_path, MAX_FILE_PATH_LEN, file_info->file_cfg.path, path_len) != EOK) {
204 return;
205 }
206 if (strcat_s((char *)g_full_path, MAX_FILE_PATH_LEN, file_info->file_cfg.name) != EOK) {
207 return;
208 }
209 if (strcat_s((char *)g_full_path, MAX_FILE_PATH_LEN, ".idx") != EOK) {
210 return;
211 }
212
213 file_info->idx_fd = open((const char *)g_full_path, O_RDWR | O_CREAT, 0664); /* 0664打开方式 */
214 if (file_info->idx_fd <= 0) {
215 dfx_log_err("logfile open file %s failed\r\n", g_full_path);
216 return;
217 }
218
219 lseek(file_info->idx_fd, 0, SEEK_SET);
220 uint32_t read_byte = (uint32_t)read(file_info->idx_fd, &file_info->muti_file_idx,
221 (uint32_t)sizeof(store_muti_file_idx_t));
222 if (read_byte != sizeof(store_muti_file_idx_t)) {
223 file_info->muti_file_idx.file_count = 0;
224 file_info->muti_file_idx.cur_file_idx = 0;
225 file_info->muti_file_idx.oldest_file_idx = 0;
226 lseek(file_info->idx_fd, 0, SEEK_SET);
227 write(file_info->idx_fd, &(file_info->muti_file_idx), sizeof(store_muti_file_idx_t));
228 fsync(file_info->idx_fd);
229 }
230 }
231
logfile_delete_oldest_file(store_file_info_t * file_info,uint8_t * suffix,uint32_t suffix_length)232 STATIC errcode_t logfile_delete_oldest_file(store_file_info_t *file_info, uint8_t *suffix, uint32_t suffix_length)
233 {
234 if (strcpy_s((char *)g_full_path, MAX_FILE_PATH_LEN, file_info->file_cfg.path) != EOK) {
235 return ERRCODE_FAIL;
236 }
237 if (strcat_s((char *)g_full_path, MAX_FILE_PATH_LEN, file_info->file_cfg.name) != EOK) {
238 return ERRCODE_FAIL;
239 }
240
241 (void)sprintf_s((char *)suffix, suffix_length, ".%04u", file_info->muti_file_idx.oldest_file_idx);
242 if (strcat_s((char *)g_full_path, MAX_FILE_PATH_LEN, (char *)suffix) != EOK) {
243 return ERRCODE_FAIL;
244 }
245
246 if (remove((char *)g_full_path) != 0) {
247 dfx_log_debug("logfile remove file [%d] failed. errno is %d \r\n",
248 file_info->muti_file_idx.oldest_file_idx, get_errno());
249 }
250
251 if (file_info->muti_file_idx.oldest_file_idx == MAX_MUTIFILE_NAME_NUM) {
252 file_info->muti_file_idx.oldest_file_idx = 1;
253 } else {
254 file_info->muti_file_idx.oldest_file_idx++;
255 }
256 return ERRCODE_SUCC;
257 }
258
logfile_open_next_file(store_file_info_t * file_info)259 STATIC errcode_t logfile_open_next_file(store_file_info_t *file_info)
260 {
261 uint8_t suffix[MAX_SUFFIX_LEN] = {0};
262
263 (void)memset_s((char *)g_full_path, MAX_FILE_PATH_LEN, 0, MAX_FILE_PATH_LEN);
264 /* 关闭当前文件 */
265 close(file_info->fd);
266
267 if (file_info->muti_file_idx.file_count >= file_info->file_cfg.mult_files) {
268 /* 如果文件已满,删除最旧的文件 */
269 (void)logfile_delete_oldest_file(file_info, suffix, sizeof(suffix));
270 }
271
272 /* 打开下一个文件 */
273 if (file_info->muti_file_idx.cur_file_idx == MAX_MUTIFILE_NAME_NUM) {
274 file_info->muti_file_idx.cur_file_idx = 1;
275 } else {
276 file_info->muti_file_idx.cur_file_idx++;
277 }
278
279 (void)memset_s(g_full_path, MAX_FILE_PATH_LEN, 0, MAX_FILE_PATH_LEN);
280 if (strcpy_s((char *)g_full_path, MAX_FILE_PATH_LEN, file_info->file_cfg.path) != EOK) {
281 return ERRCODE_FAIL;
282 }
283 if (strcat_s((char *)g_full_path, MAX_FILE_PATH_LEN, file_info->file_cfg.name) != EOK) {
284 return ERRCODE_FAIL;
285 }
286
287 (void)memset_s(suffix, MAX_SUFFIX_LEN, 0, MAX_SUFFIX_LEN);
288 (void)sprintf_s((char *)suffix, MAX_SUFFIX_LEN, ".%04u", file_info->muti_file_idx.cur_file_idx);
289 if (strcat_s((char *)g_full_path, MAX_FILE_PATH_LEN, (char *)suffix) != EOK) {
290 return ERRCODE_FAIL;
291 }
292
293 file_info->fd = open((const char *)g_full_path, O_RDWR | O_CREAT, 0664); /* 0664 是以写的方式打开 */
294 if (file_info->fd == 0) {
295 dfx_log_err("logfile open next file %s failed\r\n", g_full_path);
296 return ERRCODE_DFX_LOGFILE_OPEN_FAIL;
297 }
298
299 if (file_info->muti_file_idx.file_count < file_info->file_cfg.mult_files) {
300 file_info->muti_file_idx.file_count++;
301 }
302
303 /* 重置idx文件信息 */
304 lseek(file_info->idx_fd, 0, SEEK_SET);
305 write(file_info->idx_fd, &(file_info->muti_file_idx), sizeof(store_muti_file_idx_t));
306 fsync(file_info->idx_fd);
307
308 /* 重置文件头信息 */
309 logfile_init_file_head(file_info);
310 return ERRCODE_SUCC;
311 }
312
logfile_multi_file_write(store_file_info_t * file_info,uint8_t * data,uint32_t data_len)313 errcode_t logfile_multi_file_write(store_file_info_t *file_info, uint8_t *data, uint32_t data_len)
314 {
315 store_record_info_t record_info;
316 errcode_t ret_val;
317 record_info.magic = RECORD_HEAD_MAGIC;
318 record_info.type = file_info->file_head.service_type;
319 record_info.len = (uint16_t)(sizeof(record_info) + data_len);
320 record_info.rev = 1;
321 record_info.crc = uapi_crc16(0, (uint8_t *)&record_info, sizeof(store_record_info_t) - sizeof(uint16_t));
322
323 int32_t tmp_len = (int32_t)file_info->file_head.file_size - (int32_t)file_info->file_head.cur_pos;
324
325 if (tmp_len < record_info.len) {
326 /* 如果本文件空间不足, 打开下一个文件 */
327 logfile_open_next_file(file_info);
328 }
329
330 lseek(file_info->fd, file_info->file_head.cur_pos, SEEK_SET);
331
332 /* 写入记录头 */
333 ret_val = logfile_save_data(file_info, (uint8_t *)&record_info, (uint32_t)sizeof(record_info));
334 if (ret_val != ERRCODE_SUCC) {
335 if (ret_val != ERRCODE_DFX_LOGFILE_NOT_ENOUGH_SPACE) {
336 dfx_log_err("logfile save record head failed, ret = 0x%x\r\n", ret_val);
337 }
338 return ret_val;
339 }
340
341 /* 写入Data */
342 ret_val = logfile_save_data(file_info, data, data_len);
343 if (ret_val != ERRCODE_SUCC) {
344 if (ret_val != ERRCODE_DFX_LOGFILE_NOT_ENOUGH_SPACE) {
345 dfx_log_err("logfile save record data failed, ret = 0x%x\r\n", ret_val);
346 }
347 return ret_val;
348 }
349
350 file_info->file_head.records += 1;
351
352 /* 更新文件头 */
353 file_info->file_head.crc =
354 uapi_crc16(0, (uint8_t *)&(file_info->file_head), sizeof(store_file_head_t) - sizeof(uint16_t));
355
356 lseek(file_info->fd, 0, SEEK_SET);
357 write(file_info->fd, &(file_info->file_head), sizeof(store_file_head_t));
358 return ERRCODE_SUCC;
359 }
360
write_cache_to_single_file(store_file_info_t * file_info,uint8_t * data,uint32_t data_len)361 STATIC errcode_t write_cache_to_single_file(store_file_info_t *file_info, uint8_t *data, uint32_t data_len)
362 {
363 uint32_t space_left;
364
365 if (file_info->file_head.cur_pos >= file_info->file_head.first_record_pos) {
366 space_left = file_info->file_head.file_size - file_info->file_head.cur_pos +
367 file_info->file_head.first_record_pos - file_info->file_head.offset;
368 } else {
369 space_left = file_info->file_head.first_record_pos - file_info->file_head.cur_pos;
370 }
371
372 logfile_discard_older_records(file_info, (uint16_t)data_len, space_left);
373
374 lseek(file_info->fd, file_info->file_head.cur_pos, SEEK_SET);
375
376 logfile_save_data(file_info, data, data_len);
377
378 file_info->file_head.crc =
379 uapi_crc16(0, (uint8_t *)&(file_info->file_head), sizeof(store_file_head_t) - sizeof(uint16_t));
380 lseek(file_info->fd, 0, SEEK_SET);
381 write(file_info->fd, &(file_info->file_head), sizeof(store_file_head_t));
382
383 return ERRCODE_SUCC;
384 }
385
write_cache_to_multi_file(store_file_info_t * file_info,uint8_t * data,uint32_t data_len)386 STATIC errcode_t write_cache_to_multi_file(store_file_info_t *file_info, uint8_t *data, uint32_t data_len)
387 {
388 int32_t tmp_len = (int32_t)file_info->file_head.file_size - (int32_t)file_info->file_head.cur_pos;
389
390 if (tmp_len < (int32_t)data_len) {
391 logfile_open_next_file(file_info);
392 }
393
394 lseek(file_info->fd, file_info->file_head.cur_pos, SEEK_SET);
395
396 logfile_save_data(file_info, data, data_len);
397
398 file_info->file_head.crc =
399 uapi_crc16(0, (uint8_t *)&(file_info->file_head), sizeof(store_file_head_t) - sizeof(uint16_t));
400
401 lseek(file_info->fd, 0, SEEK_SET);
402 write(file_info->fd, &(file_info->file_head), sizeof(store_file_head_t));
403
404 return ERRCODE_SUCC;
405 }
406
logfile_write_cache_to_file(store_file_info_t * file_info)407 errcode_t logfile_write_cache_to_file(store_file_info_t *file_info)
408 {
409 store_cache_t *cache = file_info->cache;
410 uint8_t *read_data;
411 int32_t read_len;
412 int32_t tmp_pos = 0;
413
414 /* 读取 cache_write_pos 的瞬时值 */
415 tmp_pos = (int32_t)cache->cache_write_pos;
416
417 read_data = (uint8_t *)cache->data + cache->cache_read_pos;
418 osal_mutex_lock(&(logfile_get_manage()->file_write_mutex));
419 if (tmp_pos > (int32_t)cache->cache_read_pos) {
420 read_len = tmp_pos - (int32_t)cache->cache_read_pos;
421 if (file_info->file_cfg.mult_files == 1) {
422 write_cache_to_single_file(file_info, read_data, (uint32_t)read_len);
423 } else {
424 write_cache_to_multi_file(file_info, read_data, (uint32_t)read_len);
425 }
426 } else {
427 read_len = (int32_t)cache->cache_size - (int32_t)cache->cache_read_pos;
428 if (file_info->file_cfg.mult_files == 1) {
429 write_cache_to_single_file(file_info, read_data, (uint32_t)read_len);
430 write_cache_to_single_file(file_info, (uint8_t *)cache->data, (uint32_t)tmp_pos);
431 } else {
432 write_cache_to_multi_file(file_info, read_data, (uint32_t)read_len);
433 write_cache_to_multi_file(file_info, (uint8_t *)cache->data, (uint32_t)tmp_pos);
434 }
435 }
436
437 cache->cache_read_pos = (uint32_t)tmp_pos;
438 osal_mutex_unlock(&(logfile_get_manage()->file_write_mutex));
439
440 return ERRCODE_SUCC;
441 }
442
logfile_create_path(store_file_cfg_t * cfg)443 errcode_t logfile_create_path(store_file_cfg_t *cfg)
444 {
445 int32_t ret;
446 if (access(cfg->path, 0) != 0) {
447 ret = mkdir(cfg->path, S_IREAD | S_IWRITE);
448 if (ret == 0) {
449 return ERRCODE_SUCC;
450 } else {
451 dfx_log_err("mkdir %s failed, ret \r\n", cfg->path);
452 return ERRCODE_DFX_LOGFILE_MKDIR_FATAL;
453 }
454 } else {
455 return ERRCODE_SUCC;
456 }
457 }
458
logfile_remove_files(store_service_t service_type,store_file_cfg_t * cfg)459 errcode_t logfile_remove_files(store_service_t service_type, store_file_cfg_t *cfg)
460 {
461 unused(service_type);
462 uint8_t full_path_tmp[MAX_FILE_PATH_LEN] = {0};
463 struct dirent *pdirent = NULL;
464 DIR *d = NULL;
465 uint32_t ret = ERRCODE_SUCC;
466
467 d = opendir(cfg->path);
468 /* 目录不存在直接返回 */
469 if (d == NULL) {
470 return ERRCODE_SUCC;
471 }
472
473 do {
474 pdirent = readdir(d);
475 if (pdirent == NULL) {
476 break;
477 }
478
479 if (strncpy_s((char *)full_path_tmp, MAX_FILE_PATH_LEN, cfg->path, strlen(cfg->path)) != EOK) {
480 ret = ERRCODE_FAIL;
481 break;
482 }
483 if (strcat_s((char *)full_path_tmp, MAX_FILE_PATH_LEN, pdirent->d_name) != EOK) {
484 ret = ERRCODE_FAIL;
485 break;
486 }
487 if (remove((char *)full_path_tmp) != 0) {
488 dfx_log_err("remove %s failed!\r\n", full_path_tmp);
489 ret = ERRCODE_FAIL;
490 break;
491 }
492 } while (pdirent != NULL);
493
494 (void)closedir(d);
495 return ret;
496 }
497
logfile_prepare_file_fd(store_file_info_t * file_info,store_file_cfg_t * cfg)498 errcode_t logfile_prepare_file_fd(store_file_info_t *file_info, store_file_cfg_t *cfg)
499 {
500 errcode_t ret = ERRCODE_SUCC;
501 uint8_t suffix[MAX_SUFFIX_LEN];
502 uint32_t cur_file_idx = 0;
503
504 if (cfg->mult_files > 1) {
505 logfile_load_multi_files_info(file_info);
506 cur_file_idx = (file_info->muti_file_idx.file_count == 0) ? 1 : file_info->muti_file_idx.cur_file_idx;
507 }
508
509 (void)memset_s((char *)g_full_path, MAX_FILE_PATH_LEN, 0, MAX_FILE_PATH_LEN);
510 ret = (errcode_t)strcpy_s((char *)g_full_path, MAX_FILE_PATH_LEN, cfg->path);
511 ret = (errcode_t)strcat_s((char *)g_full_path, MAX_FILE_PATH_LEN, cfg->name);
512 if (cfg->mult_files > 1) {
513 (void)sprintf_s((char *)suffix, MAX_SUFFIX_LEN, ".%04u", cur_file_idx);
514 ret = (errcode_t)strcat_s((char *)g_full_path, MAX_FILE_PATH_LEN, (char *)suffix);
515 }
516
517 file_info->fd = open((const char *)g_full_path, O_RDWR | O_CREAT, 0664); /* 0664打开方式 */
518 if (file_info->fd <= 0) {
519 dfx_log_err("logfile open file failed\r\n");
520 ret = ERRCODE_DFX_LOGFILE_OPEN_FAIL;
521 }
522
523 if (ret != ERRCODE_SUCC) {
524 return ret;
525 }
526
527 if (cfg->mult_files > 1 && file_info->muti_file_idx.file_count == 0) {
528 file_info->muti_file_idx.cur_file_idx = 1;
529 file_info->muti_file_idx.oldest_file_idx = 1;
530 file_info->muti_file_idx.file_count = 1;
531 lseek(file_info->idx_fd, 0, SEEK_SET);
532 write(file_info->idx_fd, &(file_info->muti_file_idx), sizeof(store_muti_file_idx_t));
533 fsync(file_info->idx_fd);
534 }
535
536 int32_t read_byte = read(file_info->fd, &file_info->file_head, sizeof(store_file_head_t));
537 /* 先把文件头读到file_info->file_head */
538 /* 判断是否是新文件 */
539 if ((read_byte != sizeof(store_file_head_t) || file_info->file_head.start_flag != FILE_HEAD_START_FLAG)) {
540 /* 初始化文件头信息 */
541 logfile_init_file_head(file_info);
542 }
543 return ret;
544 }
545
546 #endif /* CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES */
547 #endif /* CONFIG_DFX_SUPPORT_OFFLINE_LOG_FILE */