Handle preload-rw package deleted by user when OTA 14/206714/26
authorIlho Kim <ilho159.kim@samsung.com>
Thu, 23 May 2019 12:20:14 +0000 (21:20 +0900)
committerilho kim <ilho159.kim@samsung.com>
Fri, 12 Jul 2019 06:42:15 +0000 (06:42 +0000)
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 <ilho159.kim@samsung.com>
src/install_preload_pkg.c
src/pkg_upgrade.c

index 51752ff..2218344 100644 (file)
 #include <sys/wait.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <glib.h>
 
 #include <tzplatform_config.h>
 
+#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
 #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;
 }
 
index e5d0782..4ecacee 100644 (file)
@@ -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;
 }