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