• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */