From: Ilho Kim Date: Thu, 23 May 2019 12:20:14 +0000 (+0900) Subject: Handle preload-rw package deleted by user when OTA X-Git-Tag: accepted/tizen/unified/20190717.115204~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F14%2F206714%2F26;p=platform%2Fcore%2Fappfw%2Fpkgmgr-tool.git Handle preload-rw package deleted by user when OTA Create a file to store preload-rw-packages that has been installed, this file is used to identify whether the preload-rw-package currently installing is a new package or a deleted package by user Change-Id: If9436067b39db7e808b762fbb0db9624a07d751e Signed-off-by: Ilho Kim --- diff --git a/src/install_preload_pkg.c b/src/install_preload_pkg.c index 51752ff..2218344 100644 --- a/src/install_preload_pkg.c +++ b/src/install_preload_pkg.c @@ -28,9 +28,13 @@ #include #include #include +#include #include +#include "package-manager.h" +#include "package-manager-types.h" + #define OWNER_ROOT 0 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) #define BUFSZE 4096 @@ -53,6 +57,37 @@ #define WGT_DIR tzplatform_mkpath(TZ_SYS_RO_APP, ".preload-wgt") #define TPK_RW_DIR tzplatform_mkpath(TZ_SYS_RO_APP, ".preload-rw-tpk") #define WGT_RW_DIR tzplatform_mkpath(TZ_SYS_RO_APP, ".preload-rw-wgt") +#define ALL_PRELOAD_RW_PKG_LIST "/opt/usr/share/.all_preload_rw_list" + +static void __make_preload_rw_list(GList *pkg_list) +{ + FILE *file; + char pkg_info[BUFSZE]; + + if (pkg_list == NULL) + return; + + file = fopen(ALL_PRELOAD_RW_PKG_LIST, "a"); + if (file == NULL) { + _E("can not open [%s]: %s\n", ALL_PRELOAD_RW_PKG_LIST, + strerror(errno)); + return; + } + + for (; pkg_list != NULL; pkg_list = pkg_list->next) { + char *pkgid = pkg_list->data; + if (pkgid == NULL) { + _E("pkgid is null\n"); + continue; + } + + _D("Add [%s] to preload-rw list", pkgid); + snprintf(pkg_info, BUFSZE, "package=\"%s\":\n", pkgid); + fwrite(pkg_info, 1, strlen(pkg_info), file); + } + + fclose(file); +} static int _install_preload_pkg(const char *backend, const char *directory, bool readonly, bool skip_check_reference) @@ -62,6 +97,9 @@ static int _install_preload_pkg(const char *backend, const char *directory, int ret; char file_path[BUFSZE]; char err_buf[BUFSZE]; + GList *preload_rw_pkg_list = NULL; + package_manager_pkg_detail_info_t *pkg_info; + char *pkgid; dir = opendir(directory); if (!dir) { @@ -114,13 +152,28 @@ static int _install_preload_pkg(const char *backend, const char *directory, file_path, strerror_r(errno, err_buf, sizeof(err_buf))); closedir(dir); + g_list_free_full(preload_rw_pkg_list, free); return -1; } + } else { + // make the preload-rw list + pkg_info = pkgmgr_client_check_pkginfo_from_file(file_path); + if (pkg_info == NULL) { + _E("can not get pkg_info from [%s]\n", file_path); + continue; + } + + pkgid = strdup(pkg_info->pkgid); + preload_rw_pkg_list = g_list_append(preload_rw_pkg_list, pkgid); + pkgmgr_client_free_pkginfo(pkg_info); + pkg_info = NULL; } } closedir(dir); + __make_preload_rw_list(preload_rw_pkg_list); + g_list_free_full(preload_rw_pkg_list, free); return 0; } diff --git a/src/pkg_upgrade.c b/src/pkg_upgrade.c index e5d0782..4ecacee 100644 --- a/src/pkg_upgrade.c +++ b/src/pkg_upgrade.c @@ -56,6 +56,7 @@ ".preload_rw_pkg_list") #define DBPATH tzplatform_mkpath(TZ_SYS_DB, "/.pkgmgr_parser.db") #define OPT_ZIP_FILE "/usr/system/RestoreDir/opt.zip" +#define ALL_PRELOAD_RW_PKG_LIST "/opt/usr/share/.all_preload_rw_list" static char *unzip_path[BUF_SIZE] = { "opt/usr/globalapps", @@ -135,6 +136,47 @@ int remove_directory(const char *path) return ret; } +static void __iter_cb(gpointer key, gpointer value, gpointer user_data) +{ + + FILE *file; + char *pkgid; + char pkg_info[BUF_SIZE]; + + if (user_data == NULL || key == NULL) + return; + + file = user_data; + pkgid = key; + snprintf(pkg_info, BUF_SIZE, "package=\"%s\":\n", pkgid); + fwrite(pkg_info, 1, strlen(pkg_info), file); +} + +static void __make_preload_rw_list(GHashTable *preload_rw_table) +{ + if (preload_rw_table == NULL) { + _LOG("preload_rw_table is null\n"); + return; + } + FILE *file = NULL; + + char tmp_path[BUF_SIZE]; + snprintf(tmp_path, BUF_SIZE, "%s.tmp", ALL_PRELOAD_RW_PKG_LIST); + + rename(ALL_PRELOAD_RW_PKG_LIST, tmp_path); + + file = fopen(ALL_PRELOAD_RW_PKG_LIST, "w"); + if (file == NULL) { + _LOG("can not open [%s]: %s\n", + ALL_PRELOAD_RW_PKG_LIST, strerror(errno)); + return; + } + g_hash_table_foreach(preload_rw_table, __iter_cb, file); + fsync(fileno(file)); + fclose(file); + remove(tmp_path); +} + static int __is_dir(const char *dirname) { struct stat stFileInfo; @@ -404,6 +446,14 @@ static int __compare_pkgid(char *file_path, char *fota_pkgid, return ret; } +static bool __check_deleted_pkg(GHashTable *preload_rw_table, + const char *fota_pkgid) +{ + if (g_hash_table_contains(preload_rw_table, fota_pkgid)) + return true; + return false; +} + char *__manifest_to_package(const char *manifest) { char *package; @@ -814,7 +864,15 @@ static int __unzip_files(char *dest_path) return ret; } -static int __install_preload_rw(const char *pkgid, const char *pkgtype) +static int __insert_preload_rw_table(GHashTable *preload_rw_table, + const char *pkgid) +{ + g_hash_table_insert(preload_rw_table, strdup(pkgid), NULL); + return 0; +} + +static int __install_preload_rw(const char *pkgid, const char *pkgtype, + GHashTable *preload_rw_table) { if (pkgid == NULL || pkgtype == NULL) return -1; @@ -854,11 +912,15 @@ static int __install_preload_rw(const char *pkgid, const char *pkgtype) } } + ret = __insert_preload_rw_table(preload_rw_table, pkgid); + retvm_if(ret < 0, -1, "__insert_preload_rw_table fail\n"); + __send_args_to_backend(pkgid, pkgtype, PKG_NEED_PRELOADRW_INSTALL); return ret; } -static void __convert_preload_to_rw(const char *pkgid, const char *pkgtype) +static void __convert_preload_to_rw(const char *pkgid, const char *pkgtype, + GHashTable *preload_rw_table) { if (pkgid == NULL || pkgtype == NULL) return; @@ -873,7 +935,7 @@ static void __convert_preload_to_rw(const char *pkgid, const char *pkgtype) if (ret != 0) _LOG("Failed to remove directory[%s]\n", buf); - ret = __install_preload_rw(pkgid, pkgtype); + ret = __install_preload_rw(pkgid, pkgtype, preload_rw_table); if (ret != 0) { _LOG("Failed install preload rw pkg[%s]\n", pkgid); return; @@ -881,7 +943,7 @@ static void __convert_preload_to_rw(const char *pkgid, const char *pkgtype) } static int __find_deleted_pkgid_from_list(const char *source_file, - const char *target_file) + const char *target_file, GHashTable *preload_rw_table) { retvm_if(source_file == NULL, -1, "source_file is NULL.\n"); retvm_if(target_file == NULL, -1, "target_file is NULL.\n"); @@ -933,7 +995,9 @@ static int __find_deleted_pkgid_from_list(const char *source_file, if (!strncmp(update, "false", strlen("false"))) { if (is_preload_rw_pkg) { - __convert_preload_to_rw(pkgid, pkgtype); + __convert_preload_to_rw(pkgid, + pkgtype, + preload_rw_table); modified_pkg_cnt++; } else { __send_args_to_backend(pkgid, pkgtype, @@ -947,7 +1011,9 @@ static int __find_deleted_pkgid_from_list(const char *source_file, if (is_preload_rw_pkg) { __send_args_to_backend(pkgid, pkgtype, PKG_NEED_RWUNINSTALL); - __install_preload_rw(pkgid, pkgtype); + __install_preload_rw(pkgid, + pkgtype, + preload_rw_table); } } } @@ -996,7 +1062,7 @@ static int __get_pkgid_list_from_db_and_xml() return 0; } -static int __process_ro_fota() +static int __process_ro_fota(GHashTable *preload_rw_table) { int ret; long starttime; @@ -1010,7 +1076,7 @@ static int __process_ro_fota() /* find deleted pkgid */ ret = __find_deleted_pkgid_from_list(PKGID_LIST_FROM_DB_FILE, - PKGID_LIST_FROM_XML_FILE); + PKGID_LIST_FROM_XML_FILE, preload_rw_table); err_if(ret < 0, "__find_deleted_pkgid_from_list fail.\n"); /* find updated, inserted pkgid */ @@ -1030,7 +1096,7 @@ static int __process_ro_fota() return 0; } -static int __process_rw_fota() +static int __process_rw_fota(GHashTable *preload_rw_table) { FILE *fp = NULL; char buf[BUF_SIZE] = {0}; @@ -1046,6 +1112,7 @@ static int __process_rw_fota() long starttime; long endtime; struct timeval tv; + bool is_deleted_pkg; _LOG("=======================================================\n"); _LOG("RW preload package fota\n"); @@ -1077,6 +1144,7 @@ static int __process_rw_fota() if (ret != PMINFO_R_OK) { _LOG("can not compare pkg version[%s]\n", pkgid); pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + handle = NULL; FREE_AND_NULL(pkgid); FREE_AND_NULL(list_version); continue; @@ -1086,6 +1154,7 @@ static int __process_rw_fota() /* package version is not update on FOTA. */ _LOG("pkg is not updated\n"); pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + handle = NULL; gettimeofday(&tv, NULL); endtime = tv.tv_sec * 1000l + @@ -1093,6 +1162,14 @@ static int __process_rw_fota() total_time += (int)(endtime - starttime); _LOG("finish request [time : %d ms]\n", (int)(endtime - starttime)); + ret = __insert_preload_rw_table(preload_rw_table, pkgid); + if (ret < 0) { + _LOG("__insert_preload_rw_table fail\n"); + free(pkgid); + free(list_version); + fclose(fp); + return -1; + } FREE_AND_NULL(pkgid); FREE_AND_NULL(list_version); continue; @@ -1100,12 +1177,20 @@ static int __process_rw_fota() _LOG("pkg is updated, need to upgrade\n"); } else { + is_deleted_pkg = __check_deleted_pkg(preload_rw_table, pkgid); + if (is_deleted_pkg) { + _LOG("pkgid[%s] is deleted pkg\n", pkgid); + FREE_AND_NULL(pkgid); + continue; + } _LOG("pkgid[%s] is new\n", pkgid); } pkgtype = __getvalue(buf, TOKEN_TYPE_STR, 1); - __install_preload_rw(pkgid, pkgtype); - free(pkgtype); + __install_preload_rw(pkgid, pkgtype, preload_rw_table); + + FREE_AND_NULL(pkgid); + FREE_AND_NULL(pkgtype); if (handle) pkgmgrinfo_pkginfo_destroy_pkginfo(handle); @@ -1116,15 +1201,54 @@ static int __process_rw_fota() _LOG("finish request [time : %d ms]\n", (int)(endtime - starttime)); } + fclose(fp); - if (fp != NULL) - fclose(fp); + return 0; +} + +static int __check_tmp_all_preload_rw_pkg_list() +{ + char tmp_path[BUF_SIZE]; + snprintf(tmp_path, BUF_SIZE, "%s.tmp", ALL_PRELOAD_RW_PKG_LIST); + if (access(tmp_path, F_OK) == 0) { + if (rename(tmp_path, ALL_PRELOAD_RW_PKG_LIST)) { + _LOG("rename tmp all preload rw pkg list fail : %s\n", + strerror(errno)); + return -1; + } + } + return 0; +} + +static int __fill_preload_rw_table(GHashTable *preload_rw_table) +{ + FILE *fp; + char buf[BUF_SIZE]; + char *pkgid; + + fp = fopen(ALL_PRELOAD_RW_PKG_LIST, "r"); + retvm_if(fp == NULL, -1, "Fail get : %s\n", ALL_PRELOAD_RW_PKG_LIST); + + while (fgets(buf, BUF_SIZE, fp) != NULL) { + __str_trim(buf); + + pkgid = __getvalue(buf, TOKEN_PKGID_STR, 1); + if (pkgid == NULL) { + _LOG("pkgid is null\n"); + continue; + } + + __insert_preload_rw_table(preload_rw_table, pkgid); + FREE_AND_NULL(pkgid); + } + fclose(fp); return 0; } int main(int argc, char *argv[]) { + GHashTable *preload_rw_table; int ret = 0; /* check pkgmgr-fota dir, if it is not, then exit */ @@ -1141,26 +1265,48 @@ int main(int argc, char *argv[]) //__get_pkginfo_from_opt(); - if (argc == 1) { - ret = __process_ro_fota(); - retvm_if(ret < 0, EXIT_FAILURE, - "__process_ro_fota is failed.\n"); - ret = __process_rw_fota(); - retvm_if(ret < 0, EXIT_FAILURE, - "__process_rw_fota is failed.\n"); - return EXIT_SUCCESS; - } + ret = __check_tmp_all_preload_rw_pkg_list(); + retvm_if(ret < 0, -1, + "__check_tmp_all_preload_rw_pkg_list is failed.\n"); + + preload_rw_table = g_hash_table_new_full( + g_str_hash, g_str_equal, free, NULL); + ret = __fill_preload_rw_table(preload_rw_table); + retvm_if(ret < 0, -1, "__fill_preload_rw_table is failed.\n"); - if (strcmp(argv[1], "-rof") == 0) { - ret = __process_ro_fota(); - retvm_if(ret < 0, EXIT_FAILURE, - "__process_ro_fota is failed.\n"); - } else if (strcmp(argv[1], "-rwf") == 0) { - ret = __process_rw_fota(); - retvm_if(ret < 0, EXIT_FAILURE, - "__process_rw_fota is failed.\n"); + if (argc == 1) { + ret = __process_ro_fota(preload_rw_table); + if (ret < 0) { + g_hash_table_destroy(preload_rw_table); + _LOGE("__process_ro_fota is failed.\n"); + return EXIT_FAILURE; + } + ret = __process_rw_fota(preload_rw_table); + if (ret < 0) { + g_hash_table_destroy(preload_rw_table); + _LOGE("__process_ro_fota is failed.\n"); + return EXIT_FAILURE; + } } else { - fprintf(stderr, "not supported operand\n"); + if (strcmp(argv[1], "-rof") == 0) { + ret = __process_ro_fota(preload_rw_table); + if (ret < 0) { + g_hash_table_destroy(preload_rw_table); + _LOGE("__process_ro_fota is failed.\n"); + return EXIT_FAILURE; + } + } else if (strcmp(argv[1], "-rwf") == 0) { + ret = __process_rw_fota(preload_rw_table); + if (ret < 0) { + g_hash_table_destroy(preload_rw_table); + _LOGE("__process_ro_fota is failed.\n"); + return EXIT_FAILURE; + } + } else { + fprintf(stderr, "not supported operand\n"); + } } + __make_preload_rw_list(preload_rw_table); + g_hash_table_destroy(preload_rw_table); return EXIT_SUCCESS; }