blob: 9a60714cf97361516b213f0fab2b05d938229b87 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001#define _GNU_SOURCE
2#include <stdio.h>
3#include <stdlib.h>
4#include <unistd.h>
5#include <string.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <fcntl.h>
9#include <sys/vfs.h>
10
11
12#include <mtd/mtd-abi.h>
13#include <errno.h>
14
15#include <sys/ioctl.h>
16#include "fs_check.h"
17#include "cfg_api.h"
18#include "pub_debug_info.h"
19
20/*******************************************************************************
21 * Macro definitions *
22 ******************************************************************************/
23#define MOUNTS_INFO_FILE "/proc/mounts"
24
25#define NV_FS_FAC_MAIN_PATH "/mnt/imagefs/nvrwall.bin"
26#define NV_FS_RW_HASH_FAC_PATH "/mnt/imagefs/nvrwall.hash"
27#define NV_FS_RW_TOP_PATH "/etc_rw/psnv"
28#define NV_FS_RW_HASH_WORK_PATH "/etc_rw/psnv/nvrwall.hash"
29#define NV_FS_RW_MAIN_PATH "/etc_rw/psnv/rw_work"
30#define NV_FS_RW_BACKUP_PATH "/etc_rw/psnv/rw_backup"
31#define NV_FS_FAC_SYMBOL_PATH "/etc_rw/psnv/fac_flag"
32#define NV_FS_RW_MAIN_SYMBOL_PATH "/etc_rw/psnv/work_flag"
33#define NV_FS_RW_BACKUP_SYMBOL_PATH "/etc_rw/psnv/backup_flag"
34
35#define NV_FS_RW_AP_NV_MAIN_PATH "/etc_rw/nv/main/cfg"
36#define NV_FS_RW_AP_NV_BACKUP_PATH "/etc_rw/nv/backup/cfg"
37
38#define MOUNTS_LINE_LEN (256)
39#define MOUNTS_LINE_ELEMENT_LEN (64)
40#define MAX_PATH (256)
41#define BUF_MAX_LEN (32)
42#define UBI_DEV_MAX_NUM (10)
43#define SYSTEM_EXEC_FAIL (0)
44#define SYSTEM_EXEC_SUCC (1)
45#define USERDATA_RESET_FREE_BLOCK_LEVEL (2)
46#define USERDATA_FREE_DATA_SIZE (128)
47
48typedef enum {
49 DEVICE_MTD = 0,
50 DEVICE_ZFTL = 1,
51 DEVICE_MTD_BLOCK,
52} device_type_t;
53
54char *g_path_prefix = "";
55
56static int check_mount_result(const char *parti_mp)
57{
58 char *line_p, *temp_p;
59 char line[MOUNTS_LINE_LEN] = {0};
60 char line_element[MOUNTS_LINE_ELEMENT_LEN] = {0};
61 int found;
62 FILE *fp = NULL;
63 int mp_str_len;
64 if (parti_mp == NULL)
65 return -1;
66 if ((fp = fopen(MOUNTS_INFO_FILE, "r")) == NULL) {
67 printf("fs_check fopen %s failed, error:%s\n", MOUNTS_INFO_FILE, strerror(errno));
68 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check fopen %s failed, error:%s\n", MOUNTS_INFO_FILE, strerror(errno));
69 goto error;
70 }
71
72 found = 0;
73 while (1) {
74 memset(line, 0, sizeof(line));
75 if (NULL == fgets(line, sizeof(line), fp)) {
76 break;
77 }
78 //upi_log("line: %s", line);
79 line_p = line;
80 while (*line_p != '\0' && *line_p != ' ') { // first element
81 line_p++;
82 }
83 line_p++;
84 memset(line_element, 0, sizeof(line_element));
85 temp_p = line_element;
86 while (*line_p != '\0' && *line_p != ' ') { // second element, this is what we need
87 *temp_p = *line_p;
88 temp_p++;
89
90 line_p++;
91 }
92 //upi_log("line_element: %s", line_element);
93 mp_str_len = strlen(parti_mp);
94 if (mp_str_len <= strlen(line_element)) {
95 if (strncmp(line_element + strlen(line_element) - mp_str_len, parti_mp, mp_str_len) == 0) {
96 found = 1;
97 break;
98 }
99 }
100 }
101 if (found == 0) {
102 printf("fs_check did not find any mount info about %s\n", parti_mp);
103 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check did not find any mount info about %s\n", parti_mp);
104 goto error;
105 }
106 if (NULL != fp)
107 fclose(fp);
108 return 0;
109error:
110 if (fp != NULL)
111 fclose(fp);
112 return -1;
113}
114
115int mtd_find(const char *i_parti_name, char *o_mtd_path, device_type_t device_type, unsigned int o_mtd_path_len)
116{
117 FILE *fd_mtd = 0;
118 char buf[128];
119 char *line_str;
120
121 if (!o_mtd_path_len)
122 return -1;
123
124 fd_mtd = fopen("/proc/mtd", "r+");
125 if (NULL == fd_mtd) {
126 printf("fs_check open file error:%s", strerror(errno));
127 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check open file error:%s", strerror(errno));
128 goto error0;
129 }
130 //printf("fs_check partition name:%s\n", i_parti_name);
131
132 while (1) {
133 int matches = 0;
134 char mtdname[64] = {0};
135 int mtdnum = 0;
136 unsigned int mtdsize, mtderasesize;
137 memset(buf, 0x00, sizeof(buf));
138 line_str = fgets(buf, sizeof(buf), fd_mtd);
139
140 if (NULL == line_str) {
141 printf("fs_check get info from mtd error:%s\n", strerror(errno));
142 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get info from mtd error:%s\n", strerror(errno));
143 goto error1;
144 }
145 //mtd5: 00100000 00020000 "fotaflag"
146 matches = sscanf(buf, "mtd%d: %x %x \"%63[^\"]",
147 &mtdnum, &mtdsize, &mtderasesize, mtdname);
148 mtdname[63] = '\0';
149
150 if ((matches == 4) && (strcmp(mtdname, i_parti_name) == 0)) {
151 memset(o_mtd_path, 0x00, o_mtd_path_len);
152 if (device_type == DEVICE_MTD_BLOCK) {
153 snprintf(o_mtd_path, o_mtd_path_len, "/dev/mtdblock%d", mtdnum);
154 } else if (device_type == DEVICE_MTD) {
155 snprintf(o_mtd_path, o_mtd_path_len, "/dev/mtd%d", mtdnum);
156 } else if (device_type == DEVICE_ZFTL) {
157 snprintf(o_mtd_path, o_mtd_path_len, "/dev/zftl%d", mtdnum);
158 } else {
159 printf("fs_check unknown device type %d\n", device_type);
160 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check unknown device type %d\n", device_type);
161 goto error1;
162 }
163 //printf("fs_check o_mtd_path=[%s]\n", o_mtd_path);
164 break;
165 }
166
167 }
168 fclose(fd_mtd);
169 return 0;
170
171error1:
172 fclose(fd_mtd);
173error0:
174 return -1;
175}
176
177int system_exec_status(int status)
178{
179 if (-1 == status)
180 return SYSTEM_EXEC_FAIL;
181
182 if (!WIFEXITED(status))
183 return SYSTEM_EXEC_FAIL;
184
185 if (WEXITSTATUS(status))
186 return SYSTEM_EXEC_FAIL;
187
188 return SYSTEM_EXEC_SUCC;
189}
190
191int get_ubifs_device_num(int recv_mtdnum)
192{
193 int vol_num = -1;
194 int fd_ubi = -1;
195 int ret = -1;
196 int mytmp = 0;
197 int add_len = 10;
198
199 struct stat st = {0};
200
201 unsigned char read_buf[BUF_MAX_LEN] = {0};
202 unsigned char ubidev_path[MAX_PATH] = {0};
203
204 for (; mytmp < UBI_DEV_MAX_NUM; mytmp++)
205 {
206 snprintf(ubidev_path, sizeof(ubidev_path), "/sys/devices/virtual/ubi/ubi%d", mytmp);
207 ret = stat(ubidev_path, &st);
208 if (ret < 0) {
209 printf("fs_check get stat info from error:%s\n", strerror(errno));
210 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get stat info from error:%s\n", strerror(errno));
211 break;
212 }
213 if (S_ISDIR(st.st_mode)) {
214 strncat(ubidev_path, "/mtd_num", add_len);
215 fd_ubi = open(ubidev_path, O_RDONLY);
216 if (fd_ubi < 0) {
217 printf("fs_check open file error:%s", strerror(errno));
218 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check open file error:%s", strerror(errno));
219 break;
220 }
221 memset(read_buf, 0, sizeof(read_buf));
222 ret = read(fd_ubi, read_buf, sizeof(read_buf));
223 if (ret < 0) {
224 printf("fs_check get info from ubi error:%s\n", strerror(errno));
225 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get info from ubi error:%s\n", strerror(errno));
226 close(fd_ubi);
227 break;
228 }
229 if (atoi(read_buf) == recv_mtdnum) {
230 vol_num = mytmp;
231 close(fd_ubi);
232 break;
233 }
234 close(fd_ubi);
235 }
236 }
237
238 return vol_num;
239}
240
241
242/**************************************************************************
243* º¯ÊýÃû³Æ£º read_file
244* ¹¦ÄÜÃèÊö£º ¶ÁÈ¡Îļþ
245* ²ÎÊý˵Ã÷£º (IN)
246* p_file: Îļþ
247* len: ³¤¶È
248* (OUT)
249* ·µ »Ø Öµ£º³É¹¦·µ»Ø¶ÁÈ¡µÄÎļþ, ·ñÔò·µ»Ø0
250* ÆäËü˵Ã÷£º·µ»ØÖµµ÷ÓÃÕßÊÍ·Å
251**************************************************************************/
252static unsigned char *read_file(const char *p_file, unsigned int *len)
253{
254 FILE * fd = 0;
255 struct stat buf = {0};
256 unsigned char * p_buf = NULL;
257
258 if(p_file == NULL)
259 return NULL;
260
261 if(stat(p_file, &buf) < 0)
262 {
263 printf("read_file stat %s failed\n", p_file);
264 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "read_file stat %s failed\n", p_file);
265 return NULL;
266 }
267
268 fd = fopen(p_file, "ro");
269 if(!fd)
270 {
271 printf("read_file open %s fail\n", p_file);
272 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "read_file open %s fail\n", p_file);
273 return NULL;
274 }
275
276 p_buf = (char *)malloc(buf.st_size);
277 if (p_buf == NULL)
278 {
279 printf("read_file malloc fail\n");
280 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "read_file malloc fail\n");
281 fclose(fd);
282 return NULL;
283 }
284
285 if(fread(p_buf,1, buf.st_size,fd) < 1)
286 {
287 printf("read_file fread %s fail\n", p_file);
288 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "read_file fread %s fail\n", p_file);
289 fclose(fd);
290 free(p_buf);
291 return NULL;
292 }
293 fclose(fd);
294 *len = buf.st_size;
295
296 return p_buf;
297}
298
299/**************************************************************************
300* º¯ÊýÃû³Æ£º compare_file
301* ¹¦ÄÜÃèÊö£º ±È½ÏÄ¿±êÎļþºÍÔ´ÎļþÊÇ·ñÒ»Ñù
302* ²ÎÊý˵Ã÷£º (IN)
303* p_dst_file: Ä¿±êÎļþ
304* p_src_file: Ô´Îļþ
305* (OUT)
306* ·µ »Ø Öµ£ºÎļþÒ»Ñù·µ»Ø0, ·ñÔò·µ»Ø-1
307* ÆäËü˵Ã÷£º
308**************************************************************************/
309static int compare_file(const char *p_dst_file, const char *p_src_file)
310{
311 unsigned char *p_dst;
312 unsigned char *p_src;
313 unsigned int dst_len;
314 unsigned int src_len;
315
316 if(p_dst_file == NULL || p_src_file == NULL)
317 return -1;
318
319 p_dst = read_file(p_dst_file, &dst_len);
320 if(!p_dst)
321 return -1;
322
323 p_src = read_file(p_src_file, &src_len);
324 if(!p_src)
325 {
326 free(p_dst);
327 return -1;
328 }
329
330 if(dst_len != src_len)
331 {
332 free(p_src);
333 free(p_dst);
334
335 printf("compare_file size dstbuf = %d, srcbuf = %d\n", dst_len, src_len);
336 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "compare_file size dstbuf = %d, srcbuf = %d\n", dst_len, src_len);
337 return -1;
338 }
339
340 if(memcmp(p_src, p_dst, src_len) != 0)
341 {
342 free(p_src);
343 free(p_dst);
344 printf("compare_file memcmp not same\n");
345 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "compare_file memcmp not same\n");
346 return -1;
347 }
348
349 free(p_src);
350 free(p_dst);
351
352 return 0;
353}
354
355/**************************************************************************
356* º¯ÊýÃû³Æ£º check_files_access
357* ¹¦ÄÜÃèÊö£º ¼ì²éuserdataÎļþϵͳϵÄÎļþÊÇ·ñ´æÔÚÇÒÓжÁдȨÏÞ
358* ²ÎÊý˵Ã÷£º ÎÞ
359* ·µ »Ø Öµ£º¼ì²éÕý³£·µ»Ø0, ·ñÔò·µ»Ø-1£¬½øÐÐuserdata·ÖÇøµÄ²Á³ý
360* ÆäËü˵Ã÷£º
361**************************************************************************/
362static int check_files_access()
363{
364 if(access(NV_FS_RW_MAIN_PATH,W_OK | R_OK) < 0)
365 {
366 printf("fs_check file: %s permission loss \n",NV_FS_RW_MAIN_PATH);
367 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_RW_MAIN_PATH);
368 return -1;//²é¿´rw_workÎļþÊÇ·ñ¿É¶Áд
369 }
370 if(access(NV_FS_RW_BACKUP_PATH, W_OK | R_OK) < 0)
371 {
372 printf("fs_check file: %s permission loss \n",NV_FS_RW_BACKUP_PATH);
373 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_RW_BACKUP_PATH);
374 return -1;//²é¿´rw_backupÎļþÊÇ·ñ¿É¶Áд
375 }
376 if(access(NV_FS_FAC_SYMBOL_PATH, W_OK | R_OK) < 0)
377 {
378 printf("fs_check file: %s permission loss \n",NV_FS_FAC_SYMBOL_PATH);
379 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_FAC_SYMBOL_PATH);
380 return -1;//²é¿´fac_flagÎļþÊÇ·ñ¿É¶Áд
381 }
382 if(access(NV_FS_RW_MAIN_SYMBOL_PATH, W_OK | R_OK) < 0)
383 {
384 printf("fs_check file: %s permission loss \n",NV_FS_RW_MAIN_SYMBOL_PATH);
385 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_RW_MAIN_SYMBOL_PATH);
386 return -1;//²é¿´work_flagÎļþÊÇ·ñ¿É¶Áд
387 }
388 if(access(NV_FS_RW_BACKUP_SYMBOL_PATH, W_OK | R_OK) < 0)
389 {
390 printf("fs_check file: %s permission loss \n",NV_FS_RW_BACKUP_SYMBOL_PATH);
391 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_RW_BACKUP_SYMBOL_PATH);
392 return -1;//²é¿´backup_flagÎļþÊÇ·ñ¿É¶Áд
393 }
394 if(access(NV_FS_RW_AP_NV_MAIN_PATH, W_OK | R_OK) < 0)
395 {
396 printf("fs_check file: %s permission loss \n",NV_FS_RW_AP_NV_MAIN_PATH);
397 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_RW_AP_NV_MAIN_PATH);
398 return -1;//²é¿´apϹ¤×÷nvÎļþÊÇ·ñ¿É¶Áд
399 }
400 if(access(NV_FS_RW_AP_NV_BACKUP_PATH, W_OK | R_OK) < 0)
401 {
402 printf("fs_check file: %s permission loss \n",NV_FS_RW_AP_NV_BACKUP_PATH);
403 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_RW_AP_NV_BACKUP_PATH);
404 return -1;//²é¿´apϱ¸·ÝnvÎļþÊÇ·ñ¿É¶Áд
405 }
406 return 0;
407}
408/**************************************************************************
409* º¯ÊýÃû³Æ£º check_userdata_is_space_enough
410* ¹¦ÄÜÃèÊö£º ¼ì²éuserdata·ÖÇøÏÂÃæµÄ¿Õ¼äÊÇ·ñ×ã¹»£¬²»×ãʱÐèÒªÖØÐ»ָ´userdata·ÖÇø
411* ²ÎÊý˵Ã÷£º (IN)
412* (OUT)
413* ·µ »Ø Öµ£º¼ì²é¿Õ¼ä×ã¹»·µ»Ø0, ¿Õ¼ä²»×㣬ÐèÒªÖØÐ»ָ´·ÖÇø·µ»Ø-1
414* ÆäËü˵Ã÷£º
415**************************************************************************/
416int check_userdata_space_enough()
417{
418 int fd = 0;
419 char fsckname[] = "/etc_rw/fscheck";
420 char buf[] = "filesystem checking";
421 int len = strlen(buf);
422 char *ptr = buf;
423 int res = 0;
424 int ret = 0;
425
426#if 0
427 struct statfs diskinfo;
428 statfs("/mnt/userdata", &diskinfo);
429
430 //printf("fs_check f_bsize = %d, f_blocks = %d, f_bfree = %d, f_bavail = %d, f_files = %d, , f_ffree = %d\n", \
431 // diskinfo.f_bsize, diskinfo.f_blocks, diskinfo.f_bfree, diskinfo.f_bavail, diskinfo.f_files, diskinfo.f_ffree);
432
433 //»ñȡʣÓà¿Õ¼äÊÇ·ñ´óÓÚµÈÓÚÁ½¸öblock
434 if ((diskinfo.f_bsize * diskinfo.f_bfree < CONFIG_BLOCK_SIZE * USERDATA_RESET_FREE_BLOCK_LEVEL) ||
435 (diskinfo.f_bsize * diskinfo.f_bavail < CONFIG_BLOCK_SIZE * USERDATA_RESET_FREE_BLOCK_LEVEL))
436 return -1;
437#endif
438
439 fd = open(fsckname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
440 if (fd < 0)
441 {
442 printf("open %s failed errno %d\n", fsckname, errno);
443 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "open %s failed errno %d\n", fsckname, errno);
444 return -1;
445 }
446 while (len > 0)
447 {
448 res = write(fd, ptr, len);
449 if (res < 0)
450 {
451 if (errno == EINTR)
452 {
453 res = 0;
454 }
455 else
456 {
457 printf("write %s failed errno %d\n", fsckname, errno);
458 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "write %s failed errno %d\n", fsckname, errno);
459 ret = -1;
460 break;
461 }
462 }
463 ptr += res;
464 len -= res;
465 }
466
467
468 if (close(fd) < 0)
469 {
470 printf("close %s failed errno %d\n", fsckname, errno);
471 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "close %s failed errno %d\n", fsckname, errno);
472 return -1;
473 }
474 return ret;
475}
476
477/**************************************************************************
478* º¯ÊýÃû³Æ£º check_userdata_is_normal
479* ¹¦ÄÜÃèÊö£º ¼ì²éuserdata·ÖÇøÏÂÃæµÄÎļþÊÇ·ñÕý³££¬Èç¹û´æÔÚÒì³££¬ÔòÐèÒªÖØÐ»ָ´userdata·ÖÇø
480* ²ÎÊý˵Ã÷£º (IN)
481* dst_file: Ä¿±êÎļþ
482* src_file: Ô´Îļþ
483* (OUT)
484* ·µ »Ø Öµ£º¼ì²éÕý³£·µ»Ø0, ÐèÒªÖØÐ»ָ´·ÖÇø·µ»Ø-1
485* ÆäËü˵Ã÷£º
486**************************************************************************/
487int check_userdata_is_normal()
488{
489 struct stat fac_nv_buf = {0};
490 struct stat work_buf = {0};
491 struct stat backup_buf = {0};
492
493 if (check_userdata_space_enough() < 0)
494 return -1;
495 if (access(NV_FS_RW_TOP_PATH, F_OK) != 0)
496 {
497 if (mkdir(NV_FS_RW_TOP_PATH, 0755) != 0)
498 {
499 printf("fs_check access and mkdir %s failed\n", NV_FS_RW_TOP_PATH);
500 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check access and mkdir %s failed\n", NV_FS_RW_TOP_PATH);
501 return -1;
502 }
503 }
504 /*userdata·ÖÇøÊÇ·ñ¼ì²éÐèÒªÂú×ãÒÔÏÂÁ½¸öÌõ¼þ£º
505 *1)²é¿´userdata·ÖÇøÏÂÃæµÄnvrwall.hashÊÇ·ñ´æÔÚ£¬²»´æÔÚ±íʾÊǸÕÉÕÍê°æ±¾£¬Õâʱºò²»¼ì²é
506 *2)imageϵÄhashºÍpsnvĿ¼ÏÂÃæµÄnvrwall.hashÊÇ·ñÒ»Ö£¬Èç¹ûÒ»Ö½øÐмì²é£¬·ñÔò²»½øÐмì²é£¨¹ýÂËfotaÉý¼¶£©
507 */
508 if(access(NV_FS_RW_HASH_WORK_PATH, F_OK) < 0)
509 return 0;
510
511 if(compare_file(NV_FS_RW_HASH_FAC_PATH, NV_FS_RW_HASH_WORK_PATH) == 0)
512 {
513 if(check_files_access() < 0)
514 {
515 return -1;//userdata·ÖÇøÏµÄÎļþ·ÃÎÊȨÏÞÒì³£ÐèÒª»Ö¸´
516 }
517 if(stat(NV_FS_FAC_MAIN_PATH, &fac_nv_buf) < 0)
518 {
519 return 0;
520 }
521
522 if(stat(NV_FS_RW_MAIN_PATH, &work_buf) < 0)
523 {
524 printf("fs_check stat %s failed\n",NV_FS_RW_MAIN_PATH);
525 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check stat %s failed\n",NV_FS_RW_MAIN_PATH);
526 return -1;
527 }
528 if(stat(NV_FS_RW_BACKUP_PATH, &backup_buf) < 0)
529 {
530 printf("fs_check stat %s failed\n",NV_FS_RW_BACKUP_PATH);
531 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check stat %s failed\n",NV_FS_RW_BACKUP_PATH);
532 return -1;
533 }
534 if(work_buf.st_size < fac_nv_buf.st_size || backup_buf.st_size < fac_nv_buf.st_size)
535 {
536 printf("fs_check rw_backup or rw_work file corrupted\n");
537 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check rw_backup or rw_work file corrupted\n");
538 return -1;//userdata·ÖÇøÏµĹ¤×÷ÇønvºÍ±¸·ÝÇønv±È³ö³§ÇønvС£¬ÐèÒª»Ö¸´
539 }
540 }
541
542 return 0;
543
544}
545
546int mount_fs_partition(struct mtd_fs *p_fs)
547{
548 int ret = -1;
549 int ubi_num = 0;
550 int mtd_blk_num = 0;
551 char mount_cmd[MAX_PATH] = {0};
552 char mtd_path[MAX_PATH] = {0};
553 char attach_cmd[MAX_PATH] = {0};
554
555 if (NULL == p_fs->patition_name || NULL == p_fs->mount_point || NULL == p_fs->fs_type)
556 return -1;
557
558 //printf("fs_check i_parti_name=%s, parti_mp=%s, parti_mt=%s\n", p_fs->patition_name, p_fs->mount_point, p_fs->fs_type);
559
560 if (strcmp(p_fs->patition_name, "cpfs") == 0) {
561 ret = mtd_find(p_fs->patition_name, mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
562 if (ret < 0) {
563 printf("fs_check partition name is not find\n");
564 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check partition name is not find\n");
565 return -1;
566 }
567 snprintf(mount_cmd, sizeof(mount_cmd), "%s/bin/mount -t yaffs2 -o \"inband-tags\" %s %s", g_path_prefix,mtd_path, p_fs->mount_point);
568 } else if (strcmp(p_fs->fs_type, "jffs2") == 0) {
569 ret = mtd_find(p_fs->patition_name, mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
570 if (ret < 0) {
571 printf("fs_check partition name is not find\n");
572 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check partition name is not find\n");
573 return -1;
574 }
575 snprintf(mount_cmd, sizeof(mount_cmd), "%s/bin/mount -t jffs2 %s %s %s", g_path_prefix,p_fs->mount_opt ,mtd_path, p_fs->mount_point);
576 } else if (strcmp(p_fs->fs_type, "ubifs") == 0) {
577 ret = mtd_find(p_fs->patition_name, mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
578 if (ret < 0) {
579 printf("fs_check partition name is not find\n");
580 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check partition name is not find\n");
581 return -1;
582 }
583 sscanf(mtd_path, "/dev/mtdblock%d", &mtd_blk_num);
584 snprintf(attach_cmd, sizeof(attach_cmd), "%s/usr/sbin/ubiattach /dev/ubi_ctrl -m %d", g_path_prefix,mtd_blk_num);
585
586 ret = system_exec_status(zxic_system(attach_cmd));
587 if (ret == SYSTEM_EXEC_FAIL) {
588 printf("fs_check: %s fail\n",attach_cmd);
589 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check: %s fail\n",attach_cmd);
590 return -1;
591 }
592
593 ubi_num = get_ubifs_device_num(mtd_blk_num);
594 if (ubi_num < 0) {
595 printf("fs_check ubi_num not match\n");
596 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check ubi_num not match\n");
597 return -1;
598 }
599 snprintf(mount_cmd, sizeof(mount_cmd), "%s/bin/mount -t ubifs -o rw ubi%d_0 %s", g_path_prefix,ubi_num, p_fs->mount_point);
600 } else {
601 printf("fs_check unknown mount type: %s\n", p_fs->fs_type);
602 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check unknown mount type: %s\n", p_fs->fs_type);
603 return -1;
604 }
605
606 ret = zxic_system(mount_cmd);
607
608 if (check_mount_result(p_fs->mount_point) < 0) {
609 printf("fs_check : %s fail\n", mount_cmd);
610 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check : %s fail\n", mount_cmd);
611 return -1;
612 }
613 return 0;
614}
615
616int unmount_fs_partition(struct mtd_fs *p_fs)
617{
618 int ret = -1;
619 int ubi_num = 0;
620 int mtd_blk_num = 0;
621 char umount_cmd[MAX_PATH] = {0};
622 char mtd_path[MAX_PATH] = {0};
623 char detach_cmd[MAX_PATH] = {0};
624
625 if (NULL == p_fs->patition_name || NULL == p_fs->mount_point || NULL == p_fs->fs_type)
626 return -1;
627
628 if (strcmp(p_fs->patition_name, "cpfs") == 0) {
629 snprintf(umount_cmd, sizeof(umount_cmd), "%s/bin/umount -f %s ", g_path_prefix,p_fs->mount_point);
630 } else if (strcmp(p_fs->fs_type, "jffs2") == 0) {
631 snprintf(umount_cmd, sizeof(umount_cmd), "%s/bin/umount -f %s", g_path_prefix,p_fs->mount_point);
632 } else if (strcmp(p_fs->fs_type, "ubifs") == 0) {
633
634 snprintf(umount_cmd, sizeof(umount_cmd), "%s/bin/umount -f %s", g_path_prefix,p_fs->mount_point);
635 zxic_system(umount_cmd);
636 printf("fs_check umount : %s\n", umount_cmd);
637
638 ret = mtd_find(p_fs->patition_name, mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
639 if (ret < 0) {
640 printf("fs_check partition name is not find\n");
641 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check partition name is not find\n");
642 return -1;
643 }
644 sscanf(mtd_path, "/dev/mtdblock%d", &mtd_blk_num);
645
646 ubi_num = get_ubifs_device_num(mtd_blk_num);
647
648 snprintf(detach_cmd, sizeof(detach_cmd), "%s/usr/sbin/ubidetach /dev/ubi_ctrl -d %d", g_path_prefix,ubi_num);
649
650 ret = system_exec_status(zxic_system(detach_cmd));
651 if (ret == SYSTEM_EXEC_FAIL) {
652 printf("fs_check: %s fail\n",detach_cmd);
653 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check: %s fail\n",detach_cmd);
654 return -1;
655 }
656
657 return 0;
658 } else {
659 printf("fs_check unknown umount type: %s\n", p_fs->fs_type);
660 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check unknown umount type: %s\n", p_fs->fs_type);
661 return -1;
662 }
663 printf("fs_check umount : %s\n", umount_cmd);
664 ret = zxic_system(umount_cmd);
665
666 return 0;
667}
668
669int mtd_erase_partition(const char* partition_name)
670{
671 int ret = 0;
672 char mtd_path[MAX_PATH] = {0};
673 int fd_mtd = -1;
674
675 struct mtd_info_user meminfo = {0};
676 struct erase_info_user64 erase_info = {0};
677
678 if (NULL == partition_name) {
679 return -1;
680 }
681 ret = mtd_find(partition_name, mtd_path, DEVICE_MTD, MAX_PATH);
682 if (ret < 0) {
683 printf("fs_check mtd_find %s failed\n", partition_name);
684 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd_find %s failed\n", partition_name);
685 ret = -1;
686 goto out;
687 }
688 fd_mtd = open(mtd_path, O_RDWR);
689 if (fd_mtd < 0) {
690 printf("fs_check open %s error, %s\n", partition_name, strerror(errno));
691 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check open %s error, %s\n", partition_name, strerror(errno));
692 ret = -1;
693 goto out;
694 }
695 if (ioctl(fd_mtd, MEMGETINFO, &meminfo) != 0) {
696 printf("fs_check get %s info error, %s\n", partition_name, strerror(errno));
697 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get %s info error, %s\n", partition_name, strerror(errno));
698 ret = -1;
699 goto out;
700 }
701 erase_info.length = meminfo.erasesize;
702 for (erase_info.start = 0; erase_info.start < meminfo.size; erase_info.start += meminfo.erasesize) {
703 if (ioctl(fd_mtd, MEMGETBADBLOCK, &(erase_info.start)) > 0) {
704 printf("fs_check mtd, not erasing bad block at 0x%llx\n", erase_info.start);
705 continue;
706 }
707 if (ioctl(fd_mtd, MEMERASE64, &erase_info) < 0) {
708 printf("fs_check mtd, erasing failure at 0x%llx\n", erase_info.start);
709 }
710 }
711 ret = 0;
712out:
713 if (fd_mtd >= 0) {
714 close(fd_mtd);
715 }
716 return ret;
717}
718
719int mtd_write_partition(const char* partition_name, const char* image_file)
720{
721 int ret = 0;
722 char mtd_path[MAX_PATH] = {0};
723 int fd_mtd = -1;
724 struct mtd_info_user meminfo = {0};
725
726 long long index = 0;
727 int len = 0;
728 FILE * fp = NULL;
729 char * buf = NULL;
730 struct stat statbuff = {0};
731
732 if (NULL == partition_name || NULL == image_file)
733 return -1;
734
735 ret = mtd_find(partition_name, mtd_path, DEVICE_MTD, MAX_PATH);
736 if (ret < 0) {
737 printf("fs_check mtd_find %s failed\n", partition_name);
738 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd_find %s failed\n", partition_name);
739 ret = -1;
740 goto out;
741 }
742 fd_mtd = open(mtd_path, O_RDWR);
743 if (fd_mtd < 0) {
744 printf("fs_check open %s error, %s\n", partition_name, strerror(errno));
745 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check open %s error, %s\n", partition_name, strerror(errno));
746 ret = -1;
747 goto out;
748 }
749 if (ioctl(fd_mtd, MEMGETINFO, &meminfo) != 0) {
750 printf("fs_check get %s info error, %s\n", partition_name, strerror(errno));
751 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get %s info error, %s\n", partition_name, strerror(errno));
752 ret = -1;
753 goto out;
754 }
755
756 if(stat(image_file, &statbuff) < 0)
757 {
758 printf("fs_check stat %s failed\n", image_file);
759 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check stat %s failed\n", image_file);
760 ret = -1;
761 goto out;
762 }
763
764 fp = fopen(image_file, "ro");
765 if (!fp)
766 {
767 printf("fs_check fopen %s failed\n", image_file);
768 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check fopen %s failed\n", image_file);
769 ret = -1;
770 goto out;
771 }
772
773 buf = (char *)malloc(meminfo.erasesize);
774 if(!buf)
775 {
776 printf("fs_check malloc failed\n");
777 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check malloc failed\n");
778 ret = -1;
779 goto out;
780 }
781
782 for (index = 0; index < meminfo.size && len < statbuff.st_size; index += meminfo.erasesize)
783 {
784 if (ioctl(fd_mtd, MEMGETBADBLOCK, &index) > 0)
785 {
786 printf("fs_check mtd, not erasing bad block at %lld\n", index);
787 continue;
788 }
789
790 ret = fread(buf, 1, meminfo.erasesize, fp);
791 if(ret < 0)
792 {
793 printf("fs_check mtd, fread error = %d!\n", ret);
794 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd, fread error = %d!\n", ret);
795 ret = -1;
796 goto out;
797 }
798
799 ret = lseek(fd_mtd, (long)index, SEEK_SET);
800 if(ret < 0)
801 {
802 printf("fs_check mtd, lseek error = %s!\n", strerror(errno));
803 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd, lseek error = %s!\n", strerror(errno));
804 ret = -1;
805 goto out;
806 }
807 ret = write(fd_mtd, buf, meminfo.erasesize);
808 if (ret != meminfo.erasesize)
809 {
810 printf("fs_check mtd, write error = %d!\n", ret);
811 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd, write error = %d!\n", ret);
812 ret = -1;
813 goto out;
814 }
815 len += meminfo.erasesize;
816 }
817 if (len < statbuff.st_size)
818 {
819 printf("fs_check mtd, No space left,writelen=%d, filesize=%d\n",len,statbuff.st_size);
820 sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd, No space left,writelen=%d, filesize=%d\n",len,statbuff.st_size);
821 }
822
823 ret = 0;
824out:
825 if (fd_mtd >= 0)
826 close(fd_mtd);
827
828 if (buf != NULL) {
829 memset(buf, 0, meminfo.erasesize);
830 free(buf);
831 }
832
833 if (fp != NULL)
834 fclose(fp);
835
836 return ret;
837}
838
839
840