[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;

+}

+

+

+