[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/fs_check/mtd.c b/ap/app/fs_check/mtd.c
new file mode 100755
index 0000000..9a60714
--- /dev/null
+++ b/ap/app/fs_check/mtd.c
@@ -0,0 +1,840 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/vfs.h>
+
+
+#include <mtd/mtd-abi.h>
+#include <errno.h>
+
+#include <sys/ioctl.h>
+#include "fs_check.h"
+#include "cfg_api.h"
+#include "pub_debug_info.h"
+
+/*******************************************************************************
+ * Macro definitions *
+ ******************************************************************************/
+#define MOUNTS_INFO_FILE "/proc/mounts"
+
+#define NV_FS_FAC_MAIN_PATH "/mnt/imagefs/nvrwall.bin"
+#define NV_FS_RW_HASH_FAC_PATH "/mnt/imagefs/nvrwall.hash"
+#define NV_FS_RW_TOP_PATH "/etc_rw/psnv"
+#define NV_FS_RW_HASH_WORK_PATH "/etc_rw/psnv/nvrwall.hash"
+#define NV_FS_RW_MAIN_PATH "/etc_rw/psnv/rw_work"
+#define NV_FS_RW_BACKUP_PATH "/etc_rw/psnv/rw_backup"
+#define NV_FS_FAC_SYMBOL_PATH "/etc_rw/psnv/fac_flag"
+#define NV_FS_RW_MAIN_SYMBOL_PATH "/etc_rw/psnv/work_flag"
+#define NV_FS_RW_BACKUP_SYMBOL_PATH "/etc_rw/psnv/backup_flag"
+
+#define NV_FS_RW_AP_NV_MAIN_PATH "/etc_rw/nv/main/cfg"
+#define NV_FS_RW_AP_NV_BACKUP_PATH "/etc_rw/nv/backup/cfg"
+
+#define MOUNTS_LINE_LEN (256)
+#define MOUNTS_LINE_ELEMENT_LEN (64)
+#define MAX_PATH (256)
+#define BUF_MAX_LEN (32)
+#define UBI_DEV_MAX_NUM (10)
+#define SYSTEM_EXEC_FAIL (0)
+#define SYSTEM_EXEC_SUCC (1)
+#define USERDATA_RESET_FREE_BLOCK_LEVEL (2)
+#define USERDATA_FREE_DATA_SIZE (128)
+
+typedef enum {
+ DEVICE_MTD = 0,
+ DEVICE_ZFTL = 1,
+ DEVICE_MTD_BLOCK,
+} device_type_t;
+
+char *g_path_prefix = "";
+
+static int check_mount_result(const char *parti_mp)
+{
+ char *line_p, *temp_p;
+ char line[MOUNTS_LINE_LEN] = {0};
+ char line_element[MOUNTS_LINE_ELEMENT_LEN] = {0};
+ int found;
+ FILE *fp = NULL;
+ int mp_str_len;
+ if (parti_mp == NULL)
+ return -1;
+ if ((fp = fopen(MOUNTS_INFO_FILE, "r")) == NULL) {
+ printf("fs_check fopen %s failed, error:%s\n", MOUNTS_INFO_FILE, strerror(errno));
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check fopen %s failed, error:%s\n", MOUNTS_INFO_FILE, strerror(errno));
+ goto error;
+ }
+
+ found = 0;
+ while (1) {
+ memset(line, 0, sizeof(line));
+ if (NULL == fgets(line, sizeof(line), fp)) {
+ break;
+ }
+ //upi_log("line: %s", line);
+ line_p = line;
+ while (*line_p != '\0' && *line_p != ' ') { // first element
+ line_p++;
+ }
+ line_p++;
+ memset(line_element, 0, sizeof(line_element));
+ temp_p = line_element;
+ while (*line_p != '\0' && *line_p != ' ') { // second element, this is what we need
+ *temp_p = *line_p;
+ temp_p++;
+
+ line_p++;
+ }
+ //upi_log("line_element: %s", line_element);
+ mp_str_len = strlen(parti_mp);
+ if (mp_str_len <= strlen(line_element)) {
+ if (strncmp(line_element + strlen(line_element) - mp_str_len, parti_mp, mp_str_len) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ }
+ if (found == 0) {
+ printf("fs_check did not find any mount info about %s\n", parti_mp);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check did not find any mount info about %s\n", parti_mp);
+ goto error;
+ }
+ if (NULL != fp)
+ fclose(fp);
+ return 0;
+error:
+ if (fp != NULL)
+ fclose(fp);
+ return -1;
+}
+
+int mtd_find(const char *i_parti_name, char *o_mtd_path, device_type_t device_type, unsigned int o_mtd_path_len)
+{
+ FILE *fd_mtd = 0;
+ char buf[128];
+ char *line_str;
+
+ if (!o_mtd_path_len)
+ return -1;
+
+ fd_mtd = fopen("/proc/mtd", "r+");
+ if (NULL == fd_mtd) {
+ printf("fs_check open file error:%s", strerror(errno));
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check open file error:%s", strerror(errno));
+ goto error0;
+ }
+ //printf("fs_check partition name:%s\n", i_parti_name);
+
+ while (1) {
+ int matches = 0;
+ char mtdname[64] = {0};
+ int mtdnum = 0;
+ unsigned int mtdsize, mtderasesize;
+ memset(buf, 0x00, sizeof(buf));
+ line_str = fgets(buf, sizeof(buf), fd_mtd);
+
+ if (NULL == line_str) {
+ printf("fs_check get info from mtd error:%s\n", strerror(errno));
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get info from mtd error:%s\n", strerror(errno));
+ goto error1;
+ }
+ //mtd5: 00100000 00020000 "fotaflag"
+ matches = sscanf(buf, "mtd%d: %x %x \"%63[^\"]",
+ &mtdnum, &mtdsize, &mtderasesize, mtdname);
+ mtdname[63] = '\0';
+
+ if ((matches == 4) && (strcmp(mtdname, i_parti_name) == 0)) {
+ memset(o_mtd_path, 0x00, o_mtd_path_len);
+ if (device_type == DEVICE_MTD_BLOCK) {
+ snprintf(o_mtd_path, o_mtd_path_len, "/dev/mtdblock%d", mtdnum);
+ } else if (device_type == DEVICE_MTD) {
+ snprintf(o_mtd_path, o_mtd_path_len, "/dev/mtd%d", mtdnum);
+ } else if (device_type == DEVICE_ZFTL) {
+ snprintf(o_mtd_path, o_mtd_path_len, "/dev/zftl%d", mtdnum);
+ } else {
+ printf("fs_check unknown device type %d\n", device_type);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check unknown device type %d\n", device_type);
+ goto error1;
+ }
+ //printf("fs_check o_mtd_path=[%s]\n", o_mtd_path);
+ break;
+ }
+
+ }
+ fclose(fd_mtd);
+ return 0;
+
+error1:
+ fclose(fd_mtd);
+error0:
+ return -1;
+}
+
+int system_exec_status(int status)
+{
+ if (-1 == status)
+ return SYSTEM_EXEC_FAIL;
+
+ if (!WIFEXITED(status))
+ return SYSTEM_EXEC_FAIL;
+
+ if (WEXITSTATUS(status))
+ return SYSTEM_EXEC_FAIL;
+
+ return SYSTEM_EXEC_SUCC;
+}
+
+int get_ubifs_device_num(int recv_mtdnum)
+{
+ int vol_num = -1;
+ int fd_ubi = -1;
+ int ret = -1;
+ int mytmp = 0;
+ int add_len = 10;
+
+ struct stat st = {0};
+
+ unsigned char read_buf[BUF_MAX_LEN] = {0};
+ unsigned char ubidev_path[MAX_PATH] = {0};
+
+ for (; mytmp < UBI_DEV_MAX_NUM; mytmp++)
+ {
+ snprintf(ubidev_path, sizeof(ubidev_path), "/sys/devices/virtual/ubi/ubi%d", mytmp);
+ ret = stat(ubidev_path, &st);
+ if (ret < 0) {
+ printf("fs_check get stat info from error:%s\n", strerror(errno));
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get stat info from error:%s\n", strerror(errno));
+ break;
+ }
+ if (S_ISDIR(st.st_mode)) {
+ strncat(ubidev_path, "/mtd_num", add_len);
+ fd_ubi = open(ubidev_path, O_RDONLY);
+ if (fd_ubi < 0) {
+ printf("fs_check open file error:%s", strerror(errno));
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check open file error:%s", strerror(errno));
+ break;
+ }
+ memset(read_buf, 0, sizeof(read_buf));
+ ret = read(fd_ubi, read_buf, sizeof(read_buf));
+ if (ret < 0) {
+ printf("fs_check get info from ubi error:%s\n", strerror(errno));
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get info from ubi error:%s\n", strerror(errno));
+ close(fd_ubi);
+ break;
+ }
+ if (atoi(read_buf) == recv_mtdnum) {
+ vol_num = mytmp;
+ close(fd_ubi);
+ break;
+ }
+ close(fd_ubi);
+ }
+ }
+
+ return vol_num;
+}
+
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º read_file
+* ¹¦ÄÜÃèÊö£º ¶ÁÈ¡Îļþ
+* ²ÎÊý˵Ã÷£º (IN)
+* p_file: Îļþ
+* len: ³¤¶È
+* (OUT)
+* ·µ »Ø Öµ£º³É¹¦·µ»Ø¶ÁÈ¡µÄÎļþ, ·ñÔò·µ»Ø0
+* ÆäËü˵Ã÷£º·µ»ØÖµµ÷ÓÃÕßÊÍ·Å
+**************************************************************************/
+static unsigned char *read_file(const char *p_file, unsigned int *len)
+{
+ FILE * fd = 0;
+ struct stat buf = {0};
+ unsigned char * p_buf = NULL;
+
+ if(p_file == NULL)
+ return NULL;
+
+ if(stat(p_file, &buf) < 0)
+ {
+ printf("read_file stat %s failed\n", p_file);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "read_file stat %s failed\n", p_file);
+ return NULL;
+ }
+
+ fd = fopen(p_file, "ro");
+ if(!fd)
+ {
+ printf("read_file open %s fail\n", p_file);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "read_file open %s fail\n", p_file);
+ return NULL;
+ }
+
+ p_buf = (char *)malloc(buf.st_size);
+ if (p_buf == NULL)
+ {
+ printf("read_file malloc fail\n");
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "read_file malloc fail\n");
+ fclose(fd);
+ return NULL;
+ }
+
+ if(fread(p_buf,1, buf.st_size,fd) < 1)
+ {
+ printf("read_file fread %s fail\n", p_file);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "read_file fread %s fail\n", p_file);
+ fclose(fd);
+ free(p_buf);
+ return NULL;
+ }
+ fclose(fd);
+ *len = buf.st_size;
+
+ return p_buf;
+}
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º compare_file
+* ¹¦ÄÜÃèÊö£º ±È½ÏÄ¿±êÎļþºÍÔ´ÎļþÊÇ·ñÒ»Ñù
+* ²ÎÊý˵Ã÷£º (IN)
+* p_dst_file: Ä¿±êÎļþ
+* p_src_file: Ô´Îļþ
+* (OUT)
+* ·µ »Ø Öµ£ºÎļþÒ»Ñù·µ»Ø0, ·ñÔò·µ»Ø-1
+* ÆäËü˵Ã÷£º
+**************************************************************************/
+static int compare_file(const char *p_dst_file, const char *p_src_file)
+{
+ unsigned char *p_dst;
+ unsigned char *p_src;
+ unsigned int dst_len;
+ unsigned int src_len;
+
+ if(p_dst_file == NULL || p_src_file == NULL)
+ return -1;
+
+ p_dst = read_file(p_dst_file, &dst_len);
+ if(!p_dst)
+ return -1;
+
+ p_src = read_file(p_src_file, &src_len);
+ if(!p_src)
+ {
+ free(p_dst);
+ return -1;
+ }
+
+ if(dst_len != src_len)
+ {
+ free(p_src);
+ free(p_dst);
+
+ printf("compare_file size dstbuf = %d, srcbuf = %d\n", dst_len, src_len);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "compare_file size dstbuf = %d, srcbuf = %d\n", dst_len, src_len);
+ return -1;
+ }
+
+ if(memcmp(p_src, p_dst, src_len) != 0)
+ {
+ free(p_src);
+ free(p_dst);
+ printf("compare_file memcmp not same\n");
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "compare_file memcmp not same\n");
+ return -1;
+ }
+
+ free(p_src);
+ free(p_dst);
+
+ return 0;
+}
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º check_files_access
+* ¹¦ÄÜÃèÊö£º ¼ì²éuserdataÎļþϵͳϵÄÎļþÊÇ·ñ´æÔÚÇÒÓжÁдȨÏÞ
+* ²ÎÊý˵Ã÷£º ÎÞ
+* ·µ »Ø Öµ£º¼ì²éÕý³£·µ»Ø0, ·ñÔò·µ»Ø-1£¬½øÐÐuserdata·ÖÇøµÄ²Á³ý
+* ÆäËü˵Ã÷£º
+**************************************************************************/
+static int check_files_access()
+{
+ if(access(NV_FS_RW_MAIN_PATH,W_OK | R_OK) < 0)
+ {
+ printf("fs_check file: %s permission loss \n",NV_FS_RW_MAIN_PATH);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_RW_MAIN_PATH);
+ return -1;//²é¿´rw_workÎļþÊÇ·ñ¿É¶Áд
+ }
+ if(access(NV_FS_RW_BACKUP_PATH, W_OK | R_OK) < 0)
+ {
+ printf("fs_check file: %s permission loss \n",NV_FS_RW_BACKUP_PATH);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_RW_BACKUP_PATH);
+ return -1;//²é¿´rw_backupÎļþÊÇ·ñ¿É¶Áд
+ }
+ if(access(NV_FS_FAC_SYMBOL_PATH, W_OK | R_OK) < 0)
+ {
+ printf("fs_check file: %s permission loss \n",NV_FS_FAC_SYMBOL_PATH);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_FAC_SYMBOL_PATH);
+ return -1;//²é¿´fac_flagÎļþÊÇ·ñ¿É¶Áд
+ }
+ if(access(NV_FS_RW_MAIN_SYMBOL_PATH, W_OK | R_OK) < 0)
+ {
+ printf("fs_check file: %s permission loss \n",NV_FS_RW_MAIN_SYMBOL_PATH);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_RW_MAIN_SYMBOL_PATH);
+ return -1;//²é¿´work_flagÎļþÊÇ·ñ¿É¶Áд
+ }
+ if(access(NV_FS_RW_BACKUP_SYMBOL_PATH, W_OK | R_OK) < 0)
+ {
+ printf("fs_check file: %s permission loss \n",NV_FS_RW_BACKUP_SYMBOL_PATH);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_RW_BACKUP_SYMBOL_PATH);
+ return -1;//²é¿´backup_flagÎļþÊÇ·ñ¿É¶Áд
+ }
+ if(access(NV_FS_RW_AP_NV_MAIN_PATH, W_OK | R_OK) < 0)
+ {
+ printf("fs_check file: %s permission loss \n",NV_FS_RW_AP_NV_MAIN_PATH);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_RW_AP_NV_MAIN_PATH);
+ return -1;//²é¿´apϹ¤×÷nvÎļþÊÇ·ñ¿É¶Áд
+ }
+ if(access(NV_FS_RW_AP_NV_BACKUP_PATH, W_OK | R_OK) < 0)
+ {
+ printf("fs_check file: %s permission loss \n",NV_FS_RW_AP_NV_BACKUP_PATH);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check file: %s permission loss \n",NV_FS_RW_AP_NV_BACKUP_PATH);
+ return -1;//²é¿´apϱ¸·ÝnvÎļþÊÇ·ñ¿É¶Áд
+ }
+ return 0;
+}
+/**************************************************************************
+* º¯ÊýÃû³Æ£º check_userdata_is_space_enough
+* ¹¦ÄÜÃèÊö£º ¼ì²éuserdata·ÖÇøÏÂÃæµÄ¿Õ¼äÊÇ·ñ×ã¹»£¬²»×ãʱÐèÒªÖØÐ»ָ´userdata·ÖÇø
+* ²ÎÊý˵Ã÷£º (IN)
+* (OUT)
+* ·µ »Ø Öµ£º¼ì²é¿Õ¼ä×ã¹»·µ»Ø0, ¿Õ¼ä²»×㣬ÐèÒªÖØÐ»ָ´·ÖÇø·µ»Ø-1
+* ÆäËü˵Ã÷£º
+**************************************************************************/
+int check_userdata_space_enough()
+{
+ int fd = 0;
+ char fsckname[] = "/etc_rw/fscheck";
+ char buf[] = "filesystem checking";
+ int len = strlen(buf);
+ char *ptr = buf;
+ int res = 0;
+ int ret = 0;
+
+#if 0
+ struct statfs diskinfo;
+ statfs("/mnt/userdata", &diskinfo);
+
+ //printf("fs_check f_bsize = %d, f_blocks = %d, f_bfree = %d, f_bavail = %d, f_files = %d, , f_ffree = %d\n", \
+ // diskinfo.f_bsize, diskinfo.f_blocks, diskinfo.f_bfree, diskinfo.f_bavail, diskinfo.f_files, diskinfo.f_ffree);
+
+ //»ñȡʣÓà¿Õ¼äÊÇ·ñ´óÓÚµÈÓÚÁ½¸öblock
+ if ((diskinfo.f_bsize * diskinfo.f_bfree < CONFIG_BLOCK_SIZE * USERDATA_RESET_FREE_BLOCK_LEVEL) ||
+ (diskinfo.f_bsize * diskinfo.f_bavail < CONFIG_BLOCK_SIZE * USERDATA_RESET_FREE_BLOCK_LEVEL))
+ return -1;
+#endif
+
+ fd = open(fsckname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (fd < 0)
+ {
+ printf("open %s failed errno %d\n", fsckname, errno);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "open %s failed errno %d\n", fsckname, errno);
+ return -1;
+ }
+ while (len > 0)
+ {
+ res = write(fd, ptr, len);
+ if (res < 0)
+ {
+ if (errno == EINTR)
+ {
+ res = 0;
+ }
+ else
+ {
+ printf("write %s failed errno %d\n", fsckname, errno);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "write %s failed errno %d\n", fsckname, errno);
+ ret = -1;
+ break;
+ }
+ }
+ ptr += res;
+ len -= res;
+ }
+
+
+ if (close(fd) < 0)
+ {
+ printf("close %s failed errno %d\n", fsckname, errno);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "close %s failed errno %d\n", fsckname, errno);
+ return -1;
+ }
+ return ret;
+}
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º check_userdata_is_normal
+* ¹¦ÄÜÃèÊö£º ¼ì²éuserdata·ÖÇøÏÂÃæµÄÎļþÊÇ·ñÕý³££¬Èç¹û´æÔÚÒì³££¬ÔòÐèÒªÖØÐ»ָ´userdata·ÖÇø
+* ²ÎÊý˵Ã÷£º (IN)
+* dst_file: Ä¿±êÎļþ
+* src_file: Ô´Îļþ
+* (OUT)
+* ·µ »Ø Öµ£º¼ì²éÕý³£·µ»Ø0, ÐèÒªÖØÐ»ָ´·ÖÇø·µ»Ø-1
+* ÆäËü˵Ã÷£º
+**************************************************************************/
+int check_userdata_is_normal()
+{
+ struct stat fac_nv_buf = {0};
+ struct stat work_buf = {0};
+ struct stat backup_buf = {0};
+
+ if (check_userdata_space_enough() < 0)
+ return -1;
+ if (access(NV_FS_RW_TOP_PATH, F_OK) != 0)
+ {
+ if (mkdir(NV_FS_RW_TOP_PATH, 0755) != 0)
+ {
+ printf("fs_check access and mkdir %s failed\n", NV_FS_RW_TOP_PATH);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check access and mkdir %s failed\n", NV_FS_RW_TOP_PATH);
+ return -1;
+ }
+ }
+ /*userdata·ÖÇøÊÇ·ñ¼ì²éÐèÒªÂú×ãÒÔÏÂÁ½¸öÌõ¼þ£º
+ *1)²é¿´userdata·ÖÇøÏÂÃæµÄnvrwall.hashÊÇ·ñ´æÔÚ£¬²»´æÔÚ±íʾÊǸÕÉÕÍê°æ±¾£¬Õâʱºò²»¼ì²é
+ *2)imageϵÄhashºÍpsnvĿ¼ÏÂÃæµÄnvrwall.hashÊÇ·ñÒ»Ö£¬Èç¹ûÒ»Ö½øÐмì²é£¬·ñÔò²»½øÐмì²é£¨¹ýÂËfotaÉý¼¶£©
+ */
+ if(access(NV_FS_RW_HASH_WORK_PATH, F_OK) < 0)
+ return 0;
+
+ if(compare_file(NV_FS_RW_HASH_FAC_PATH, NV_FS_RW_HASH_WORK_PATH) == 0)
+ {
+ if(check_files_access() < 0)
+ {
+ return -1;//userdata·ÖÇøÏµÄÎļþ·ÃÎÊȨÏÞÒì³£ÐèÒª»Ö¸´
+ }
+ if(stat(NV_FS_FAC_MAIN_PATH, &fac_nv_buf) < 0)
+ {
+ return 0;
+ }
+
+ if(stat(NV_FS_RW_MAIN_PATH, &work_buf) < 0)
+ {
+ printf("fs_check stat %s failed\n",NV_FS_RW_MAIN_PATH);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check stat %s failed\n",NV_FS_RW_MAIN_PATH);
+ return -1;
+ }
+ if(stat(NV_FS_RW_BACKUP_PATH, &backup_buf) < 0)
+ {
+ printf("fs_check stat %s failed\n",NV_FS_RW_BACKUP_PATH);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check stat %s failed\n",NV_FS_RW_BACKUP_PATH);
+ return -1;
+ }
+ if(work_buf.st_size < fac_nv_buf.st_size || backup_buf.st_size < fac_nv_buf.st_size)
+ {
+ printf("fs_check rw_backup or rw_work file corrupted\n");
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check rw_backup or rw_work file corrupted\n");
+ return -1;//userdata·ÖÇøÏµĹ¤×÷ÇønvºÍ±¸·ÝÇønv±È³ö³§ÇønvС£¬ÐèÒª»Ö¸´
+ }
+ }
+
+ return 0;
+
+}
+
+int mount_fs_partition(struct mtd_fs *p_fs)
+{
+ int ret = -1;
+ int ubi_num = 0;
+ int mtd_blk_num = 0;
+ char mount_cmd[MAX_PATH] = {0};
+ char mtd_path[MAX_PATH] = {0};
+ char attach_cmd[MAX_PATH] = {0};
+
+ if (NULL == p_fs->patition_name || NULL == p_fs->mount_point || NULL == p_fs->fs_type)
+ return -1;
+
+ //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);
+
+ if (strcmp(p_fs->patition_name, "cpfs") == 0) {
+ ret = mtd_find(p_fs->patition_name, mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
+ if (ret < 0) {
+ printf("fs_check partition name is not find\n");
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check partition name is not find\n");
+ return -1;
+ }
+ 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);
+ } else if (strcmp(p_fs->fs_type, "jffs2") == 0) {
+ ret = mtd_find(p_fs->patition_name, mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
+ if (ret < 0) {
+ printf("fs_check partition name is not find\n");
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check partition name is not find\n");
+ return -1;
+ }
+ 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);
+ } else if (strcmp(p_fs->fs_type, "ubifs") == 0) {
+ ret = mtd_find(p_fs->patition_name, mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
+ if (ret < 0) {
+ printf("fs_check partition name is not find\n");
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check partition name is not find\n");
+ return -1;
+ }
+ sscanf(mtd_path, "/dev/mtdblock%d", &mtd_blk_num);
+ snprintf(attach_cmd, sizeof(attach_cmd), "%s/usr/sbin/ubiattach /dev/ubi_ctrl -m %d", g_path_prefix,mtd_blk_num);
+
+ ret = system_exec_status(zxic_system(attach_cmd));
+ if (ret == SYSTEM_EXEC_FAIL) {
+ printf("fs_check: %s fail\n",attach_cmd);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check: %s fail\n",attach_cmd);
+ return -1;
+ }
+
+ ubi_num = get_ubifs_device_num(mtd_blk_num);
+ if (ubi_num < 0) {
+ printf("fs_check ubi_num not match\n");
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check ubi_num not match\n");
+ return -1;
+ }
+ 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);
+ } else {
+ printf("fs_check unknown mount type: %s\n", p_fs->fs_type);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check unknown mount type: %s\n", p_fs->fs_type);
+ return -1;
+ }
+
+ ret = zxic_system(mount_cmd);
+
+ if (check_mount_result(p_fs->mount_point) < 0) {
+ printf("fs_check : %s fail\n", mount_cmd);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check : %s fail\n", mount_cmd);
+ return -1;
+ }
+ return 0;
+}
+
+int unmount_fs_partition(struct mtd_fs *p_fs)
+{
+ int ret = -1;
+ int ubi_num = 0;
+ int mtd_blk_num = 0;
+ char umount_cmd[MAX_PATH] = {0};
+ char mtd_path[MAX_PATH] = {0};
+ char detach_cmd[MAX_PATH] = {0};
+
+ if (NULL == p_fs->patition_name || NULL == p_fs->mount_point || NULL == p_fs->fs_type)
+ return -1;
+
+ if (strcmp(p_fs->patition_name, "cpfs") == 0) {
+ snprintf(umount_cmd, sizeof(umount_cmd), "%s/bin/umount -f %s ", g_path_prefix,p_fs->mount_point);
+ } else if (strcmp(p_fs->fs_type, "jffs2") == 0) {
+ snprintf(umount_cmd, sizeof(umount_cmd), "%s/bin/umount -f %s", g_path_prefix,p_fs->mount_point);
+ } else if (strcmp(p_fs->fs_type, "ubifs") == 0) {
+
+ snprintf(umount_cmd, sizeof(umount_cmd), "%s/bin/umount -f %s", g_path_prefix,p_fs->mount_point);
+ zxic_system(umount_cmd);
+ printf("fs_check umount : %s\n", umount_cmd);
+
+ ret = mtd_find(p_fs->patition_name, mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
+ if (ret < 0) {
+ printf("fs_check partition name is not find\n");
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check partition name is not find\n");
+ return -1;
+ }
+ sscanf(mtd_path, "/dev/mtdblock%d", &mtd_blk_num);
+
+ ubi_num = get_ubifs_device_num(mtd_blk_num);
+
+ snprintf(detach_cmd, sizeof(detach_cmd), "%s/usr/sbin/ubidetach /dev/ubi_ctrl -d %d", g_path_prefix,ubi_num);
+
+ ret = system_exec_status(zxic_system(detach_cmd));
+ if (ret == SYSTEM_EXEC_FAIL) {
+ printf("fs_check: %s fail\n",detach_cmd);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check: %s fail\n",detach_cmd);
+ return -1;
+ }
+
+ return 0;
+ } else {
+ printf("fs_check unknown umount type: %s\n", p_fs->fs_type);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check unknown umount type: %s\n", p_fs->fs_type);
+ return -1;
+ }
+ printf("fs_check umount : %s\n", umount_cmd);
+ ret = zxic_system(umount_cmd);
+
+ return 0;
+}
+
+int mtd_erase_partition(const char* partition_name)
+{
+ int ret = 0;
+ char mtd_path[MAX_PATH] = {0};
+ int fd_mtd = -1;
+
+ struct mtd_info_user meminfo = {0};
+ struct erase_info_user64 erase_info = {0};
+
+ if (NULL == partition_name) {
+ return -1;
+ }
+ ret = mtd_find(partition_name, mtd_path, DEVICE_MTD, MAX_PATH);
+ if (ret < 0) {
+ printf("fs_check mtd_find %s failed\n", partition_name);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd_find %s failed\n", partition_name);
+ ret = -1;
+ goto out;
+ }
+ fd_mtd = open(mtd_path, O_RDWR);
+ if (fd_mtd < 0) {
+ printf("fs_check open %s error, %s\n", partition_name, strerror(errno));
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check open %s error, %s\n", partition_name, strerror(errno));
+ ret = -1;
+ goto out;
+ }
+ if (ioctl(fd_mtd, MEMGETINFO, &meminfo) != 0) {
+ printf("fs_check get %s info error, %s\n", partition_name, strerror(errno));
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get %s info error, %s\n", partition_name, strerror(errno));
+ ret = -1;
+ goto out;
+ }
+ erase_info.length = meminfo.erasesize;
+ for (erase_info.start = 0; erase_info.start < meminfo.size; erase_info.start += meminfo.erasesize) {
+ if (ioctl(fd_mtd, MEMGETBADBLOCK, &(erase_info.start)) > 0) {
+ printf("fs_check mtd, not erasing bad block at 0x%llx\n", erase_info.start);
+ continue;
+ }
+ if (ioctl(fd_mtd, MEMERASE64, &erase_info) < 0) {
+ printf("fs_check mtd, erasing failure at 0x%llx\n", erase_info.start);
+ }
+ }
+ ret = 0;
+out:
+ if (fd_mtd >= 0) {
+ close(fd_mtd);
+ }
+ return ret;
+}
+
+int mtd_write_partition(const char* partition_name, const char* image_file)
+{
+ int ret = 0;
+ char mtd_path[MAX_PATH] = {0};
+ int fd_mtd = -1;
+ struct mtd_info_user meminfo = {0};
+
+ long long index = 0;
+ int len = 0;
+ FILE * fp = NULL;
+ char * buf = NULL;
+ struct stat statbuff = {0};
+
+ if (NULL == partition_name || NULL == image_file)
+ return -1;
+
+ ret = mtd_find(partition_name, mtd_path, DEVICE_MTD, MAX_PATH);
+ if (ret < 0) {
+ printf("fs_check mtd_find %s failed\n", partition_name);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd_find %s failed\n", partition_name);
+ ret = -1;
+ goto out;
+ }
+ fd_mtd = open(mtd_path, O_RDWR);
+ if (fd_mtd < 0) {
+ printf("fs_check open %s error, %s\n", partition_name, strerror(errno));
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check open %s error, %s\n", partition_name, strerror(errno));
+ ret = -1;
+ goto out;
+ }
+ if (ioctl(fd_mtd, MEMGETINFO, &meminfo) != 0) {
+ printf("fs_check get %s info error, %s\n", partition_name, strerror(errno));
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get %s info error, %s\n", partition_name, strerror(errno));
+ ret = -1;
+ goto out;
+ }
+
+ if(stat(image_file, &statbuff) < 0)
+ {
+ printf("fs_check stat %s failed\n", image_file);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check stat %s failed\n", image_file);
+ ret = -1;
+ goto out;
+ }
+
+ fp = fopen(image_file, "ro");
+ if (!fp)
+ {
+ printf("fs_check fopen %s failed\n", image_file);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check fopen %s failed\n", image_file);
+ ret = -1;
+ goto out;
+ }
+
+ buf = (char *)malloc(meminfo.erasesize);
+ if(!buf)
+ {
+ printf("fs_check malloc failed\n");
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check malloc failed\n");
+ ret = -1;
+ goto out;
+ }
+
+ for (index = 0; index < meminfo.size && len < statbuff.st_size; index += meminfo.erasesize)
+ {
+ if (ioctl(fd_mtd, MEMGETBADBLOCK, &index) > 0)
+ {
+ printf("fs_check mtd, not erasing bad block at %lld\n", index);
+ continue;
+ }
+
+ ret = fread(buf, 1, meminfo.erasesize, fp);
+ if(ret < 0)
+ {
+ printf("fs_check mtd, fread error = %d!\n", ret);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd, fread error = %d!\n", ret);
+ ret = -1;
+ goto out;
+ }
+
+ ret = lseek(fd_mtd, (long)index, SEEK_SET);
+ if(ret < 0)
+ {
+ printf("fs_check mtd, lseek error = %s!\n", strerror(errno));
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd, lseek error = %s!\n", strerror(errno));
+ ret = -1;
+ goto out;
+ }
+ ret = write(fd_mtd, buf, meminfo.erasesize);
+ if (ret != meminfo.erasesize)
+ {
+ printf("fs_check mtd, write error = %d!\n", ret);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd, write error = %d!\n", ret);
+ ret = -1;
+ goto out;
+ }
+ len += meminfo.erasesize;
+ }
+ if (len < statbuff.st_size)
+ {
+ printf("fs_check mtd, No space left,writelen=%d, filesize=%d\n",len,statbuff.st_size);
+ sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd, No space left,writelen=%d, filesize=%d\n",len,statbuff.st_size);
+ }
+
+ ret = 0;
+out:
+ if (fd_mtd >= 0)
+ close(fd_mtd);
+
+ if (buf != NULL) {
+ memset(buf, 0, meminfo.erasesize);
+ free(buf);
+ }
+
+ if (fp != NULL)
+ fclose(fp);
+
+ return ret;
+}
+
+
+