Tried to update the applied file when second update 43/171943/1
authorsanghyuk Ko <sanghyuk.ko@samsung.com>
Mon, 4 Dec 2017 12:53:57 +0000 (21:53 +0900)
committerSunmin Lee <sunm.lee@samsung.com>
Thu, 8 Mar 2018 04:10:25 +0000 (13:10 +0900)
Files that are applied the patch during the update are skipped during the second udpate.
Files that are deleted during the update are skipped during the second udpate.

Change-Id: Id7366ce042d361dad4913c0a31aa22fe1b440778

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

index 48c629a..e6218ef 100755 (executable)
@@ -42,6 +42,11 @@ cd cmake_tmp
 cp libtota.a %{buildroot}%{_libdir}/libtota.a
 %post
 
+%posttrans
+if [ ! -e /opt/data/recovery ]; then
+       ln -sf /opt/data/update /opt/data/recovery
+fi
+
 
 %files
 %defattr(-,root,root,-)
index d0f5eab..cc55fea 100755 (executable)
@@ -236,7 +236,8 @@ extern void create_dir(char *pathname, int mode);
 int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
                                         const char *source_sha1_str, const char *target_sha1_str, int patch_data_size)
 {
-       uint8_t target_sha1[SHA_DIGEST_SIZE];
+       uint8_t target_sha1[SHA_DIGEST_SIZE] = { 0, };
+       uint8_t source_sha1[SHA_DIGEST_SIZE] = { 0, };
        sha1_ctx_t ctx1;
        int output;
        int retry = 1;
@@ -246,7 +247,7 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
        int result = 0;
        char buf[256];
        FileInfo source_file;
-       uint8_t source_sha1[SHA_DIGEST_SIZE] = { 0, };
+       FileInfo target_file;
 
        if (ParseSha1(target_sha1_str, target_sha1) != 0) {
                LOGE("failed to parse tgt-sha1 \"%s\"\n", target_sha1_str);
@@ -264,11 +265,11 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
                }
                if (SS_LoadFile(source_filename, &source_file) == 0) {
                        if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) {
-                               LOGL(LOG_SSENGINE, "SS_UpdateDeltaFS - Patch Can be applied\n");
+                               LOGL(LOG_SSENGINE, "Patch Can be applied\n");
                                if (source_file.data)
                                        SS_Free(source_file.data);
                        } else if (memcmp(source_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
-                               LOGL(LOG_SSENGINE, "SS_UpdateDeltaFS - Patch Already applied\n");
+                               LOGL(LOG_SSENGINE, "Patch Already applied\n");
                                if (source_file.data)
                                        SS_Free(source_file.data);
                                return S_SS_SUCCESS;
@@ -276,7 +277,17 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
                                //Check for backup file SHA
                                SS_Free(source_file.data);
                                source_file.data = NULL;
-                               LOGL(LOG_SSENGINE, "SS_UpdateDeltaFS - Source was currupted, Try loading from backup source\n");
+                               LOGL(LOG_SSENGINE, "Source was currupted, Try loading from backup source\n");
+
+                               if (SS_LoadFile(target_filename, &target_file) == 0) {
+                                       if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
+                                               LOGL(LOG_SSENGINE, "Patch Already applied\n");
+                                               if (target_file.data)
+                                                       SS_Free(target_file.data);
+                                               return S_SS_SUCCESS;
+                                       }
+                               }
+
                                if (SS_LoadFile(SS_BACKUP_SOURCE, &source_file) == 0) {
                                        if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) {
                                                if (SS_CopyFile(SS_BACKUP_SOURCE, source_filename) != S_SS_SUCCESS) {
@@ -288,7 +299,7 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
                                                        return E_SS_FAILURE;
                                                }
                                                LOGL(LOG_SSENGINE,
-                                                        "SS_UpdateDeltaFS - Patch Can be applied from using backup file as source\n");
+                                                        "Patch Can be applied from using backup file as source\n");
                                        } else {
                                                SS_SetUpgradeState(E_SS_FSSRCCURRUPTED);
                                                if (source_file.data)
@@ -303,11 +314,21 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
                                }
                        }
                } else {
-                       LOGL(LOG_SSENGINE, "SS_UpdateDeltaFS - Source was deleted, Try loading from backup source\n");
+                       LOGL(LOG_SSENGINE, "Source was deleted!!\n");
+                       if (SS_LoadFile(target_filename, &target_file) == 0) {
+                               if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
+                                       LOGL(LOG_SSENGINE, "Patch Already applied\n");
+                                       if (target_file.data)
+                                               SS_Free(target_file.data);
+                                       return S_SS_SUCCESS;
+                               }
+                       }
+
+                       LOGL(LOG_SSENGINE, "Try loading from backup source\n");
                        if (SS_LoadFile(SS_BACKUP_SOURCE, &source_file) == 0) {
                                if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) {
                                        use_backup = 1;
-                                       LOGL(LOG_SSENGINE, "SS_UpdateDeltaFS - Patch Can be applied from using backup file as source\n");
+                                       LOGL(LOG_SSENGINE, "Patch Can be applied from using backup file as source\n");
                                } else {
                                        SS_SetUpgradeState(E_SS_FSSRCCURRUPTED);
                                        if (source_file.data)
@@ -315,6 +336,7 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
                                        return E_SS_FAILURE;
                                }
                        } else {
+                               LOGE(" SS_LoadFile from backup source failed!!\n");
                                SS_SetUpgradeState(E_SS_FSSRCCURRUPTED);
                                if (source_file.data)
                                        SS_Free(source_file.data);
@@ -370,10 +392,12 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
                        // We write the decoded output to "<tgt-file>.patch".
                        //allocate some extra space to allow for concatinating ".patch" with the name
                        outname = (char *)SS_Malloc(strlen(target_filename) + 10);
-                       if (outname == NULL)
-                               return -1;
-               snprintf(outname, strlen(target_filename) + 10,
-                               "%s.patch", target_filename);
+                       if (outname == NULL) {
+                               LOGE("SS_Malloc failed!!\n");
+                               return E_SS_FAILURE;
+                       }
+                       snprintf(outname, strlen(target_filename) + 10,
+                                       "%s.patch", target_filename);
 
                        output = open(outname, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
                        if (output < 0) {
@@ -406,7 +430,7 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
                        close(output);
                }
 
-               if (result != 0) {
+               if (result != S_SS_SUCCESS) {
                        if (retry == 0) {
                                LOGE("applying patch failed result : [%d]\n", result);
                                SS_Free(outname);//wgid: 20739
@@ -421,6 +445,7 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
                        break;
                }
        } while (retry-- > 0);
+
        const uint8_t current_target_sha1[SHA_DIGEST_SIZE] = { 0, };
        sha1_final(&ctx1, (uint32_t *) & current_target_sha1);
        if (memcmp(current_target_sha1, target_sha1, SHA_DIGEST_SIZE) != 0) {
@@ -430,6 +455,7 @@ int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename,
                        SS_Free(outname);
                return E_SS_FAILURE;
        }
+
        // Finally, rename the .patch file to replace the target file.
 #ifdef ENHANCED_BSDIFF
        if (SS_rename1(outname, target_filename) != 0) {
index 290ba58..9eca8a8 100755 (executable)
@@ -318,6 +318,127 @@ 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 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;
+       }
+
+       LOG("buf:[%s]\n", buf);
+
+       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("status:[%d] (del_type: [%d])\n", status, del_type);
+
+       return status;
+}
+
+
+void SS_Set_last_update_status(int status, int del_type)
+{
+       int fd;
+       int result = 0;
+       char num_str[16];
+       LOG("status:[%d], del_type:[%d]\n", 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");
+               return;
+       }
+
+       sprintf(num_str, "%d %d", status, del_type);
+       result = SS_WriteFile(fd, 0, (unsigned char *)num_str, strlen(num_str));
+       if (result != 0)
+               LOG("SS_WriteFile failed!!\n");
+
+       result = SS_CloseFile(fd);
+       if (result != 0)
+               LOG("SS_CloseFile failed!!\n");
+
+       sync();
+
+}
+
 int SS_rename(const char *old_file_name, const char *new_file_name)
 {
        if (link(old_file_name, new_file_name) < 0) {
@@ -1116,6 +1237,7 @@ int SS_FSSetAttributes(ua_dataSS_t * ua_dataSS)
        char *pattribs = NULL;
        int ulAttribSize = 0;
        int result = S_SS_SUCCESS;
+       int fail_cnt = 0;
 
        if (!(ua_dataSS && ua_dataSS->update_delta && ua_dataSS->update_data->ua_delta_path)) {
                LOGE("Bad params for SS_FSSetAttributes\n");
@@ -1132,6 +1254,7 @@ int SS_FSSetAttributes(ua_dataSS_t * ua_dataSS)
        }
        char *item_data = SS_Malloc(item_size + 1);
        if (item_data == NULL) {
+               LOGE("SS_Malloc failed!! - item_data\n");
                SS_SetUpgradeState(E_SS_MALLOC_ERROR);
                return E_SS_FAILURE;
        }
@@ -1139,6 +1262,7 @@ int SS_FSSetAttributes(ua_dataSS_t * ua_dataSS)
                tar_get_cfg_data(ua_dataSS->update_data->ua_delta_path, ua_dataSS->update_delta->ua_attrib_path, item_data,
                                                 item_size);
        if (read_data <= 0) {
+               LOGE("read_data failed!!\n");
                SS_SetUpgradeState(E_SS_FSBADDELTA);
                if (item_data != NULL)
                        SS_Free(item_data);
@@ -1177,20 +1301,26 @@ int SS_FSSetAttributes(ua_dataSS_t * ua_dataSS)
                                SS_SetUpgradeState(E_SS_FSBADATTRIBUTES);
                                if (item_data)
                                        SS_Free(item_data);
-                               return E_SS_FAILURE;
+                               fail_cnt++;
                        }
                } else {
                        LOGE("\n Failed to Parse Attributes - LINE %s", pline);
                        SS_SetUpgradeState(E_SS_FSBADATTRIBUTES);
                        if (item_data)
                                SS_Free(item_data);
-                       return E_SS_FAILURE;
+                       fail_cnt++;
                }
                pline = strtok_r(NULL, SS_TOKEN_NEWLINE, &psaveptr);
        }
+
        SS_Free(item_data);
 
-       return S_SS_SUCCESS;
+       if (fail_cnt > 0)
+               result = E_SS_FAILURE;
+       else
+               result = S_SS_SUCCESS;
+
+       return result;
 }
 
 /*!
@@ -1342,7 +1472,7 @@ int SS_FSUpdateFile(int ubFileType, ua_dataSS_t * ua_dataSS, int ulPatchCount, f
 #endif
                        while (pFsNode) {
                                if (pFsNode->type == DELETE_END) {
-                                       LOGL(LOG_SSENGINE, "DELETES update Index: [%d] \n", ulFileIndex++);
+                                       LOGL(LOG_SSENGINE, "DELETE_END update Index: [%d] \n", ulFileIndex++);
                                        SS_GetFileType(pFsNode->file_old_path, (enumFileType *) & ulFiletype);
                                        if (ulFiletype == 2)            //FT_FOLDER
                                                ulResult = SS_DeleteFolder(pFsNode->file_old_path);
@@ -1359,7 +1489,7 @@ int SS_FSUpdateFile(int ubFileType, ua_dataSS_t * ua_dataSS, int ulPatchCount, f
 #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 DELETE_END - [%d] \n", (t2 - t1));
 #endif
                }
                break;
@@ -1490,6 +1620,7 @@ extern int cur_mem;
 int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
 {
        int ulResult = S_SS_SUCCESS;
+       int del_type = 0;
        fs_list *head_ptr_node = NULL;
        char new_patch_path[SS_MAX_FILE_PATH] = {
                0
@@ -1511,12 +1642,22 @@ 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);
+
        if (head_ptr_node->del_ref == NULL) {
                LOGL(LOG_SSENGINE, "No DEL header\n");
        } else if (ulResult == S_SS_SUCCESS) {
-               ulResult =
-                       SS_FSUpdateFile(DELETES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->del_ref,
-                                                       ua_dataSS->update_delta->ua_patch_path);
+               if (del_type < DELETES) {
+                       ulResult = SS_FSUpdateFile(DELETES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->del_ref,
+                                       ua_dataSS->update_delta->ua_patch_path);
+                       if (ulResult == S_SS_SUCCESS) {
+                               LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETES success!!\n");
+                               SS_Set_last_update_status(part_idx, DELETES);
+                       }
+               } else {
+                       LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETES already applied!!\n");
+               }
        }
 
        if (head_ptr_node->dif_ref == NULL) {
@@ -1525,22 +1666,40 @@ int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
                ulResult =
                        SS_FSUpdateFile(DIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->dif_ref,
                                                        ua_dataSS->update_delta->ua_patch_path);
+               if (ulResult == S_SS_SUCCESS) {
+                       LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DIFFS success!!\n");
+               }
        }
 
        if (head_ptr_node->move_ref == NULL) {
                LOGL(LOG_SSENGINE, "No MOVE header\n");
        } else if (ulResult == S_SS_SUCCESS) {
+               if (del_type < MOVES) {
                ulResult =
                        SS_FSUpdateFile(MOVES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->move_ref,
                                                        ua_dataSS->update_delta->ua_patch_path);
+                       if (ulResult == S_SS_SUCCESS) {
+                               LOGL(LOG_SSENGINE, "SS_FSUpdateFile - MOVES success!!\n");
+                               SS_Set_last_update_status(part_idx, MOVES);
+                       }
+               } else {
+                       LOGL(LOG_SSENGINE, "SS_FSUpdateFile - MOVES already applied!!\n");
+               }
        }
 
        if (head_ptr_node->del_ref == NULL) {
                LOGL(LOG_SSENGINE, "No DEL header\n");
        } else if (ulResult == S_SS_SUCCESS) {
-               ulResult =
-                       SS_FSUpdateFile(DELETE_END, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->del_ref,
-                                                       ua_dataSS->update_delta->ua_patch_path);
+               if (del_type < DELETE_END) {
+                       ulResult = SS_FSUpdateFile(DELETE_END, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->del_ref,
+                                       ua_dataSS->update_delta->ua_patch_path);
+                       if (ulResult == S_SS_SUCCESS) {
+                               LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETE_END success!!\n");
+                               SS_Set_last_update_status(part_idx, DELETE_END);
+                       }
+               } else {
+                       LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETE_END already applied!!\n");
+               }
        }
 
         if (ulResult == S_SS_SUCCESS) {
@@ -1550,6 +1709,9 @@ int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
                ulResult =
                        SS_FSUpdateFile(NEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->new_ref, new_patch_path);
                //new file extraction end
+               if (ulResult == S_SS_SUCCESS) {
+                       LOGL(LOG_SSENGINE, "SS_FSUpdateFile - NEWFILES success!!\n");
+               }
        }
 
        if (head_ptr_node->sym_difref == NULL) {
@@ -1558,6 +1720,9 @@ int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
                ulResult =
                        SS_FSUpdateFile(SYMDIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->sym_difref,
                                                        ua_dataSS->update_delta->ua_patch_path);
+               if (ulResult == S_SS_SUCCESS) {
+                       LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMDIFFS success!!\n");
+               }
        }
 
        if (head_ptr_node->sym_newref == NULL) {
@@ -1566,16 +1731,26 @@ int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
                ulResult =
                        SS_FSUpdateFile(SYMNEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->sym_newref,
                                                        ua_dataSS->update_delta->ua_patch_path);
+               if (ulResult == S_SS_SUCCESS) {
+                       LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMNEWFILES success!!\n");
+               }
        }
 
-       if (ulResult == S_SS_SUCCESS)
+
+       if (ulResult == S_SS_SUCCESS) {
                ulResult = SS_FSSetAttributes(ua_dataSS);
+       } else {
+               SS_FSSetAttributes(ua_dataSS);  // To prevent boot failures by smack.
+       }
+
        sync();
        sleep(1);
        SS_FSClearNodes(part_idx);
 
-       if (ulResult == S_SS_SUCCESS)
+       if (ulResult == S_SS_SUCCESS) {
                SS_UpdateUIProgress(ua_dataSS, 0, 1);   //fix WGID : 51963, When all updates are done to FS , patchcount is not needed, passing 1 to 3rd arg is enough
+               SS_Set_last_update_status(part_idx, DEL_TYPE_MAX);
+       }
 
        LOGL(LOG_SSENGINE, "FS update Complete PartIndex: [%d]\n", part_idx);
 #ifdef  MEM_PROFILING
index ce91f70..4c9edc8 100755 (executable)
@@ -30,7 +30,7 @@ struct details {
        int symnews;
 };
 
-enum DEL_TYPE { DIFFS, MOVES, NEWFILES, DELETES, SYMDIFFS, SYMNEWFILES, DELETE_END };
+enum DEL_TYPE { DELETES = 1, DIFFS, MOVES, DELETE_END, NEWFILES, SYMDIFFS, SYMNEWFILES, DEL_TYPE_MAX };
 struct fs_params {                       // Use Macros
        char file_old_path[512];
        char file_new_path[512];
@@ -83,4 +83,8 @@ 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);
+
 #endif                                           //_SS_UPI_H_
index 0d2720d..6b538eb 100755 (executable)
@@ -72,6 +72,8 @@ typedef unsigned long long u64;
 #define SS_GZIP_TARGET                 SS_KERNEL_WORKSPACE "/gzip"
 #define SS_STAT_TARGET                 SS_KERNEL_WORKSPACE "/stat"
 #define SS_DD_TARGET                   SS_KERNEL_WORKSPACE "/dd"
+//#define SS_UPDATE_STATUR_PATH                SS_COMMON_WORKSPACE "/UP.STATUS"
+#define SS_UPDATE_STATUR_PATH          "/system/opt/data/recovery/UP.STATUS"
 
 #define SS_GZIP_SOURCE                 "system/bin/gzip"
 #define SS_STAT_SOURCE                 "system/usr/bin/stat"