In case of MOVES, added code to check validation. 44/171944/2
authorsanghyuk Ko <sanghyuk.ko@samsung.com>
Thu, 7 Dec 2017 05:56:19 +0000 (14:56 +0900)
committerSunmin Lee <sunm.lee@samsung.com>
Fri, 9 Mar 2018 05:46:42 +0000 (05:46 +0000)
In addition, Remove duplicated code.

Change-Id: I5162a65001dce5fbef899b5021367edb358cca84

packaging/libtota.spec
ss_engine/SS_UPI.c
ss_engine/SS_UPI.h
ss_engine/fota_common.h

index e6218ef..3a8408c 100755 (executable)
@@ -1,6 +1,6 @@
 Name:          libtota
 Summary:       fota update library
-Version:       1.2.0
+Version:       1.2.1
 Release:       0
 Group:         System
 License:       Apache-2.0 and BSD-2-Clause and BSD-3-Clause and PD
index 9eca8a8..82072b7 100755 (executable)
@@ -135,6 +135,88 @@ int file_exist(char *filename)
        return (ret >= 0) ? (1) : (0);
 }
 
+#ifdef POWER_FAIL_TEST
+
+static int SS_Get_power_fail_flag(void)
+{
+       int fd;
+       char buf[256];
+       char *ptr = NULL;
+       int result = 0;
+       int ret_val = 0;
+
+       if (file_exist(SS_POWER_FAIL_TEST_FLAG) == 0) {
+               LOGE("No exist file!!\n");
+               return -1;
+       }
+
+       fd = open(SS_POWER_FAIL_TEST_FLAG, O_RDWR, S_IRWXU);
+       if (fd == -1) {
+               LOGE("Could not open status file!!\n");
+               return -1;
+       }
+
+       result = SS_ReadFile(fd, 0, buf, sizeof(buf));
+       if (result != 0) {
+               LOGE("SS_ReadFile failed!!\n");
+               return -1;
+       }
+
+       ret_val = atoi(buf);
+
+       result = SS_CloseFile(fd);
+       if (result != 0)
+               LOGE("SS_CloseFile failed!!\n");
+
+       return ret_val;
+}
+
+static void SS_Set_power_fail_flag(int del_type)
+{
+       int fd;
+       int result = 0;
+       char num_str[16];
+       LOG("del_type:[%d]\n", del_type);
+
+       fd = open(SS_POWER_FAIL_TEST_FLAG, O_RDWR | O_CREAT, S_IRWXU);
+       if (fd == -1) {
+               LOGE("Could not open status file!!\n");
+               return;
+       }
+
+       sprintf(num_str, "%d", del_type);
+       result = SS_WriteFile(fd, 0, num_str, strlen(num_str));
+       if (result != 0)
+               LOGE("SS_WriteFile failed!!\n");
+
+       result = SS_CloseFile(fd);
+       if (result != 0)
+               LOGE("SS_CloseFile failed!!\n");
+
+       sync();
+
+}
+
+int SS_Do_Power_fail_test(int del_type)
+{
+       int ret = -1;
+       char cmd[1024] = { 0, };
+
+       SS_Set_power_fail_flag(del_type);
+
+       snprintf(cmd, sizeof(cmd) - 1, "%s", "/usr/sbin/reboot fota");
+       ret = _system_cmd_nowait(cmd);
+       sleep(1);
+       LOG("ret for SS_Do_Power_fail_test cmd is %d\n", ret);
+       if (ret == 0) {
+               return S_SS_SUCCESS;
+       } else {
+               LOGE("Could not start Memory Profiling\n");
+               return E_SS_FAILURE;
+       }
+}
+#endif
+
 long SS_GetUPIVersion(unsigned char *ver_str)
 {
        if (ver_str) {
@@ -318,122 +400,72 @@ int SS_GetUpgradeState()
        return FS_UpgradeState;
 }
 
-int SS_Get_last_update_del_type(void)
-{
-       int fd;
-       unsigned char buf[256];
-       char *ptr = NULL;
-       int status = -1;
-       int del_type = 0;
-       int result = 0;
-
-       if (file_exist(SS_UPDATE_STATUR_PATH) == 0) {
-               LOG("No exist file!!\n");
-               return 0;
-       }
-
-       fd = open(SS_UPDATE_STATUR_PATH, O_RDWR, S_IRWXU);
-       if (fd == -1) {
-               LOG("Could not open status file!!\n");
-               return 0;
-       }
-
-       result = SS_ReadFile(fd, 0, buf, sizeof(buf));
-       if (result != 0) {
-               LOG("SS_ReadFile failed!!\n");
-               return 0;
-       }
-
-       ptr = strtok((char *)buf, " ");
-
-       if (ptr != NULL) {
-               status = atoi(ptr);
-               ptr = strtok(NULL, " ");
-       }
-
-       if (ptr != NULL) {
-               del_type = atoi(ptr);
-       }
-
-       result = SS_CloseFile(fd);
-       if (result != 0)
-               LOG("SS_CloseFile failed!!\n");
-
-       LOG("del_type:[%d] (status: [%d])\n", del_type, status);
-
-       return del_type;
-}
-
-int SS_Get_last_update_status(void)
+int SS_Get_last_update_status(int* last_update_status, int* del_type)
 {
        int fd;
        unsigned char buf[256];
        char *ptr = NULL;
-       int status = -1;
-       int del_type = 0;
        int result = 0;
 
        if (file_exist(SS_UPDATE_STATUR_PATH) == 0) {
-               LOG("No exist file!!\n");
-               return 0;
+               LOG("No exist file!! - File_path:[%s]\n", SS_UPDATE_STATUR_PATH);
+               return -1;
        }
 
        fd = open(SS_UPDATE_STATUR_PATH, O_RDWR, S_IRWXU);
        if (fd == -1) {
-               LOG("Could not open status file!!\n");
-               return 0;
+               LOGE("Could not open status file!!, File_path:[%s]\n", SS_UPDATE_STATUR_PATH);
+               return -1;
        }
 
        result = SS_ReadFile(fd, 0, buf, sizeof(buf));
        if (result != 0) {
-               LOG("SS_ReadFile failed!!\n");
-               return 0;
+               LOGE("SS_ReadFile failed!!\n");
+               result = SS_CloseFile(fd);
+               if (result != 0)
+                       LOGE("SS_CloseFile failed!!\n");
+               return -1;
        }
 
-       LOG("buf:[%s]\n", buf);
-
        ptr = strtok((char *)buf, " ");
 
        if (ptr != NULL) {
-               status = atoi(ptr);
+               *last_update_status = atoi(ptr);
                ptr = strtok(NULL, " ");
        }
 
        if (ptr != NULL) {
-               del_type = atoi(ptr);
+               *del_type = atoi(ptr);
        }
 
        result = SS_CloseFile(fd);
        if (result != 0)
-               LOG("SS_CloseFile failed!!\n");
-
-       LOG("status:[%d] (del_type: [%d])\n", status, del_type);
+               LOGE("SS_CloseFile failed!!\n");
 
-       return status;
+       return 0;
 }
 
-
-void SS_Set_last_update_status(int status, int del_type)
+void SS_Set_last_update_status(int last_update_status, int del_type)
 {
        int fd;
        int result = 0;
        char num_str[16];
-       LOG("status:[%d], del_type:[%d]\n", status, del_type);
+       LOG("last_update_status:[%d], del_type:[%d]\n", last_update_status, del_type);
 
        fd = open(SS_UPDATE_STATUR_PATH, O_RDWR | O_CREAT, S_IRWXU);
        if (fd == -1) {
-               LOG("Could not open status file!!\n");
+               LOGE("Could not open status file!!, File_path:[%s]\n", SS_UPDATE_STATUR_PATH);
                return;
        }
 
-       sprintf(num_str, "%d %d", status, del_type);
+       sprintf(num_str, "%d %d", last_update_status, del_type);
        result = SS_WriteFile(fd, 0, (unsigned char *)num_str, strlen(num_str));
        if (result != 0)
-               LOG("SS_WriteFile failed!!\n");
+               LOGE("SS_WriteFile failed!!\n");
 
        result = SS_CloseFile(fd);
        if (result != 0)
-               LOG("SS_CloseFile failed!!\n");
+               LOGE("SS_CloseFile failed!!\n");
 
        sync();
 
@@ -1264,15 +1296,19 @@ int SS_FSSetAttributes(ua_dataSS_t * ua_dataSS)
        if (read_data <= 0) {
                LOGE("read_data failed!!\n");
                SS_SetUpgradeState(E_SS_FSBADDELTA);
-               if (item_data != NULL)
+               if (item_data != NULL) {
                        SS_Free(item_data);
+                       item_data = NULL;
+               }
                return E_SS_FAILURE;
        }
        pline = strtok_r(item_data, "\n", &psaveptr);
        if (pline == NULL) {
                LOGL(LOG_SSENGINE, "No Attributes to SET as no lines in file\n");
-               if (item_data != NULL)
+               if (item_data != NULL) {
                        SS_Free(item_data);
+                       item_data = NULL;
+               }
                return E_SS_FAILURE;
        }
 
@@ -1299,21 +1335,28 @@ int SS_FSSetAttributes(ua_dataSS_t * ua_dataSS)
                        if (result != S_SS_SUCCESS) {
                                LOGE("\n Failed to set Attributes %s", pfilePath);
                                SS_SetUpgradeState(E_SS_FSBADATTRIBUTES);
-                               if (item_data)
+                               if (item_data) {
                                        SS_Free(item_data);
+                                       item_data = NULL;
+                               }
                                fail_cnt++;
                        }
                } else {
                        LOGE("\n Failed to Parse Attributes - LINE %s", pline);
                        SS_SetUpgradeState(E_SS_FSBADATTRIBUTES);
-                       if (item_data)
+                       if (item_data) {
                                SS_Free(item_data);
+                               item_data = NULL;
+                       }
                        fail_cnt++;
                }
                pline = strtok_r(NULL, SS_TOKEN_NEWLINE, &psaveptr);
        }
 
-       SS_Free(item_data);
+       if (item_data != NULL) {
+               SS_Free(item_data);
+               item_data = NULL;
+       }
 
        if (fail_cnt > 0)
                result = E_SS_FAILURE;
@@ -1348,6 +1391,9 @@ int SS_FSUpdateFile(int ubFileType, ua_dataSS_t * ua_dataSS, int ulPatchCount, f
        };
        int ulReadCnt = 0;
        int ulResult = S_SS_SUCCESS;
+       FileInfo source_file;
+       FileInfo target_file;
+       uint8_t target_sha1[SHA_DIGEST_SIZE] = { 0, };
 
        if (!patch_path) {
                LOGE("Bad patch_path name\n");
@@ -1416,19 +1462,80 @@ int SS_FSUpdateFile(int ubFileType, ua_dataSS_t * ua_dataSS, int ulPatchCount, f
 #endif
                        while (pFsNode) {
                                LOGL(LOG_SSENGINE, "MOVES update Index: [%d] \n", ulFileIndex++);
-                               ulResult = SS_MoveFile(pFsNode->file_old_path, pFsNode->file_new_path);
-                               if (ulResult != S_SS_SUCCESS) {
-                                       LOGE("Move Failed for [%s] to [%s]\n", pFsNode->file_old_path, pFsNode->file_new_path);
-                                       SS_SetUpgradeState(ulResult);
+                               int skip_flag = 0;
+                               if (SS_LoadFile(pFsNode->file_old_path, &source_file) == 0) {
+                                       LOGL(LOG_SSENGINE, "Patch Can be applied\n");
+                                       if (source_file.data)
+                                               SS_Free(source_file.data);
+                               } else if (SS_LoadFile(pFsNode->file_new_path, &target_file) == 0) {
+                                       LOGL(LOG_SSENGINE, "source deleted!!, file_old_path: [%s]\n", pFsNode->file_old_path);
+                                       if (ParseSha1(pFsNode->sha1src, target_sha1) != 0) {
+                                               LOGE("failed to parse sha1 \"%s\"\n", pFsNode->sha1src);
+                                               ulResult = E_SS_FAILURE;
+                                               SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
+                                               if (target_file.data)
+                                                       SS_Free(target_file.data);
+                                               break;
+                                       }
+                                       if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
+                                               LOGL(LOG_SSENGINE, "Patch already applied\n");
+                                               skip_flag = 1;
+                                               if (target_file.data)
+                                                       SS_Free(target_file.data);
+                                       } else {
+                                               LOGL(LOG_SSENGINE, "target_sha1 diff!!: [%s]\n", target_sha1);
+                                               ulResult = E_SS_FAILURE;
+                                               SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
+                                               if (target_file.data)
+                                                       SS_Free(target_file.data);
+                                               break;
+                                       }
+                               } else {
+                                       LOGE("No exist files. - file_old_path: [%s] file_new_path: [%s]\n", pFsNode->file_old_path, pFsNode->file_new_path);
+                                       ulResult = E_SS_FAILURE;
+                                       SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
                                        break;
                                }
+
+                               if (skip_flag == 0) {
+                                       ulResult = SS_MoveFile(pFsNode->file_old_path, pFsNode->file_new_path);
+                                       if (ulResult != S_SS_SUCCESS) {
+                                               LOGE("Move Failed for [%s] to [%s]\n", pFsNode->file_old_path, pFsNode->file_new_path);
+                                               SS_SetUpgradeState(ulResult);
+                                               break;
+                                       } else {
+                                               // Verification
+                                               if (SS_LoadFile(pFsNode->file_new_path, &target_file) == 0) {
+                                                       if (ParseSha1(pFsNode->sha1src, target_sha1) != 0) {
+                                                               LOGE("failed to parse sha1 \"%s\"\n", pFsNode->sha1src);
+                                                               ulResult = E_SS_FAILURE;
+                                                               SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
+                                                               if (target_file.data)
+                                                                       SS_Free(target_file.data);
+                                                               break;
+                                                       }
+                                                       if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
+                                                               LOGL(LOG_SSENGINE, "Patch success!!\n");
+                                                               if (target_file.data)
+                                                                       SS_Free(target_file.data);
+                                                       } else {
+                                                               LOGL(LOG_SSENGINE, "target_sha1 diff!!: [%s]\n", target_sha1);
+                                                               ulResult = E_SS_FAILURE;
+                                                               SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
+                                                               if (target_file.data)
+                                                                       SS_Free(target_file.data);
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
                                SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
                                pFsNode = pFsNode->nextnode;
                        }
 #ifdef TIME_PROFILING
                        get_time_stamp1();  //total time capturing
                        t2 = atoi(ts1);
-                       LOG("Shirsh time for DELETES - [%d] \n", (t2 - t1));
+                       LOG("Shirsh time for MOVES - [%d] \n", (t2 - t1));
 #endif
                }
                break;
@@ -1527,10 +1634,14 @@ int SS_FSUpdateFile(int ubFileType, ua_dataSS_t * ua_dataSS, int ulPatchCount, f
                                LOGL(LOG_SSENGINE, "SYMDIFFS update Index: [%d] \n", ulFileIndex++);
                                //LOG("Sym Diff file paths: [Linkname - %s] [reference file name- %s][]\n", pFsNode->file_path,pFsNode->patch_name);
                                ulResult = SS_Unlink(pFsNode->file_old_path);
-                               if (ulResult == S_SS_SUCCESS)
+                               if (ulResult == S_SS_SUCCESS) {
                                        ulResult = SS_Link(NULL, pFsNode->file_new_path, pFsNode->patch_name);
-                               else {
-                                       LOGE("Unlink Failed\n");
+                                       if (ulResult != S_SS_SUCCESS) {
+                                               LOGE("SS_Link Failed, Linkname:[%s], reference file name:[%s]\n",
+                                               pFsNode->file_new_path, pFsNode->patch_name);
+                                       }
+                               } else {
+                                       LOGE("SS_Unlink Failed\n");
                                        SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
                                        break;
                                }
@@ -1620,6 +1731,7 @@ extern int cur_mem;
 int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
 {
        int ulResult = S_SS_SUCCESS;
+       int last_update_status = 0;
        int del_type = 0;
        fs_list *head_ptr_node = NULL;
        char new_patch_path[SS_MAX_FILE_PATH] = {
@@ -1642,8 +1754,16 @@ int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
 
        LOGL(LOG_SSENGINE, "FS Update Entry PartIndex: [%d]\n", part_idx);
 
-       del_type = SS_Get_last_update_del_type();
-       LOGL(LOG_SSENGINE, "del_type: [%d]\n", del_type);
+#ifdef POWER_FAIL_TEST
+       int fail_test_flag = 0;
+       fail_test_flag = SS_Get_power_fail_flag();
+       LOGL(LOG_SSENGINE, "fail_test_flag: [%d]\n", fail_test_flag);
+#endif
+
+       if(SS_Get_last_update_status(&last_update_status, &del_type) == -1)
+               LOGE("SS_Get_last_update_status failed!!\n");
+
+       LOGL(LOG_SSENGINE, "last_update_status: [%d], del_type: [%d]\n", last_update_status, del_type);
 
        if (head_ptr_node->del_ref == NULL) {
                LOGL(LOG_SSENGINE, "No DEL header\n");
@@ -1653,6 +1773,14 @@ int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
                                        ua_dataSS->update_delta->ua_patch_path);
                        if (ulResult == S_SS_SUCCESS) {
                                LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETES success!!\n");
+
+#ifdef POWER_FAIL_TEST
+                               if (fail_test_flag < DELETES) {
+                                       if (SS_Do_Power_fail_test(DELETES) == E_SS_FAILURE) {
+                                               LOGE("SS_Do_Power_fail_test failed!!\n");
+                                       }
+                               }
+#endif
                                SS_Set_last_update_status(part_idx, DELETES);
                        }
                } else {
@@ -1668,6 +1796,13 @@ int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
                                                        ua_dataSS->update_delta->ua_patch_path);
                if (ulResult == S_SS_SUCCESS) {
                        LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DIFFS success!!\n");
+#ifdef POWER_FAIL_TEST
+                       if (fail_test_flag < DIFFS) {
+                               if (SS_Do_Power_fail_test(DIFFS) == E_SS_FAILURE) {
+                                       LOGE("SS_Do_Power_fail_test failed!!\n");
+                               }
+                       }
+#endif
                }
        }
 
@@ -1680,6 +1815,13 @@ int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
                                                        ua_dataSS->update_delta->ua_patch_path);
                        if (ulResult == S_SS_SUCCESS) {
                                LOGL(LOG_SSENGINE, "SS_FSUpdateFile - MOVES success!!\n");
+#ifdef POWER_FAIL_TEST
+                               if (fail_test_flag < MOVES) {
+                                       if (SS_Do_Power_fail_test(MOVES) == E_SS_FAILURE) {
+                                               LOGE("SS_Do_Power_fail_test failed!!\n");
+                                       }
+                               }
+#endif
                                SS_Set_last_update_status(part_idx, MOVES);
                        }
                } else {
@@ -1695,6 +1837,13 @@ int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
                                        ua_dataSS->update_delta->ua_patch_path);
                        if (ulResult == S_SS_SUCCESS) {
                                LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETE_END success!!\n");
+#ifdef POWER_FAIL_TEST
+                               if (fail_test_flag < DELETE_END) {
+                                       if (SS_Do_Power_fail_test(DELETE_END) == E_SS_FAILURE) {
+                                               LOGE("SS_Do_Power_fail_test failed!!\n");
+                                       }
+                               }
+#endif
                                SS_Set_last_update_status(part_idx, DELETE_END);
                        }
                } else {
@@ -1722,6 +1871,13 @@ int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
                                                        ua_dataSS->update_delta->ua_patch_path);
                if (ulResult == S_SS_SUCCESS) {
                        LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMDIFFS success!!\n");
+#ifdef POWER_FAIL_TEST
+                       if (fail_test_flag < SYMDIFFS) {
+                               if (SS_Do_Power_fail_test(SYMDIFFS) == E_SS_FAILURE) {
+                                       LOGE("SS_Do_Power_fail_test failed!!\n");
+                               }
+                       }
+#endif
                }
        }
 
@@ -1733,6 +1889,13 @@ int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
                                                        ua_dataSS->update_delta->ua_patch_path);
                if (ulResult == S_SS_SUCCESS) {
                        LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMNEWFILES success!!\n");
+#ifdef POWER_FAIL_TEST
+                       if (fail_test_flag < SYMNEWFILES) {
+                               if (SS_Do_Power_fail_test(SYMNEWFILES) == E_SS_FAILURE) {
+                                       LOGE("SS_Do_Power_fail_test failed!!\n");
+                               }
+                       }
+#endif
                }
        }
 
@@ -1756,6 +1919,9 @@ int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
 #ifdef  MEM_PROFILING
        LOGL(LOG_SSENGINE, "Stats are : Cur Max : [%d] Global Max : [%d]\n", cur_mem, max_mem);
 #endif
+#ifdef POWER_FAIL_TEST
+       unlink(SS_POWER_FAIL_TEST_FLAG);
+#endif
        if (ulResult == S_SS_SUCCESS)
                return ulResult;
        else
index 4c9edc8..d82c8e6 100755 (executable)
@@ -83,8 +83,7 @@ extern int _7zdecompress(char *path);
 extern void tar_free_cfg_table(tar_Data_t ** delta_tar);
 extern long SS_GetFileType(char *pLinkName, enumFileType * fileType);
 
-extern int SS_Get_last_update_del_type(void);
-extern int SS_Get_last_update_status(void);
-extern void SS_Set_last_update_status(int status, int del_type);
+extern int SS_Get_last_update_status(int* last_update_status, int* del_type);
+extern void SS_Set_last_update_status(int last_update_status, int del_type);
 
 #endif                                           //_SS_UPI_H_
index 6b538eb..8213546 100755 (executable)
@@ -52,6 +52,9 @@ typedef unsigned long long u64;
 #ifndef MEM_PROFILING
        //#define MEM_PROFILING
 #endif
+#ifndef POWER_FAIL_TEST
+       //#define POWER_FAIL_TEST
+#endif
 
 #define UNUSED(x) (void)(x)
 
@@ -118,6 +121,10 @@ typedef unsigned long long u64;
 #define SS_MEMORY_PROFILING_SCRIPT     SS_COMMON_WORKSPACE "/mem_use.sh"
 #endif
 
+#ifdef POWER_FAIL_TEST
+#define SS_POWER_FAIL_TEST_FLAG                SS_COMMON_WORKSPACE "/power_fail_test_flag"
+#endif
+
 struct tar_Data {
        int itemSize;
        int itemOffset;