From 4db0f70846f8345c1b28bf95a123f4d0b4ff9a51 Mon Sep 17 00:00:00 2001 From: sanghyuk Ko Date: Mon, 4 Dec 2017 21:53:57 +0900 Subject: [PATCH] Tried to update the applied file when second update 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 | 5 ++ ss_engine/SS_PatchDelta.c | 52 +++++++++--- ss_engine/SS_UPI.c | 201 +++++++++++++++++++++++++++++++++++++++++++--- ss_engine/SS_UPI.h | 6 +- ss_engine/fota_common.h | 2 + 5 files changed, 239 insertions(+), 27 deletions(-) diff --git a/packaging/libtota.spec b/packaging/libtota.spec index 48c629a..e6218ef 100755 --- a/packaging/libtota.spec +++ b/packaging/libtota.spec @@ -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,-) diff --git a/ss_engine/SS_PatchDelta.c b/ss_engine/SS_PatchDelta.c index d0f5eab..cc55fea 100755 --- a/ss_engine/SS_PatchDelta.c +++ b/ss_engine/SS_PatchDelta.c @@ -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 ".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) { diff --git a/ss_engine/SS_UPI.c b/ss_engine/SS_UPI.c index 290ba58..9eca8a8 100755 --- a/ss_engine/SS_UPI.c +++ b/ss_engine/SS_UPI.c @@ -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 diff --git a/ss_engine/SS_UPI.h b/ss_engine/SS_UPI.h index ce91f70..4c9edc8 100755 --- a/ss_engine/SS_UPI.h +++ b/ss_engine/SS_UPI.h @@ -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_ diff --git a/ss_engine/fota_common.h b/ss_engine/fota_common.h index 0d2720d..6b538eb 100755 --- a/ss_engine/fota_common.h +++ b/ss_engine/fota_common.h @@ -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" -- 2.7.4