Fix pkg_upgrade tool 33/170333/5
authorJunghyun Yeon <jungh.yeon@samsung.com>
Mon, 19 Feb 2018 07:47:26 +0000 (16:47 +0900)
committerJunghyun Yeon <jungh.yeon@samsung.com>
Wed, 28 Feb 2018 00:50:51 +0000 (09:50 +0900)
- Change filter to get preload pkg to retrieve readonlyupdate pkgs.
- When pkg is readonlyupdated but not included at image,
  set its db attribute properly to treat as normal pkg.(TODO)
- When pkg is readnolyupdated and update image has same version,
  readonlyupdate should be uninstalled except its rwdata.

Related changes:
[pkgmgr-info] : https://review.tizen.org/gerrit/#/c/170323/

Change-Id: I9ae7f5567034a5c44c0eb8cd62a0b138e6626d27
Signed-off-by: Junghyun Yeon <jungh.yeon@samsung.com>
src/pkg_upgrade.c
src/pkg_upgrade.h

index 6ff2bf0..6ca29db 100644 (file)
@@ -50,6 +50,7 @@
 #define PKGID_LIST_FROM_XML_FILE \
        tzplatform_mkpath(TZ_SYS_GLOBALUSER_DATA, \
        "pkgmgr/fota/pkgid_list_from_xml.txt")
+#define DBPATH tzplatform_mkpath(TZ_SYS_DB, "/.pkgmgr_parser.db")
 
 #define PRELOAD_RW_TPK_PATH \
        tzplatform_mkpath(TZ_SYS_RO_APP, ".preload-rw-tpk")
@@ -176,9 +177,9 @@ static int __remove_pkgid_list()
 }
 
 static int __make_pkgid_list(const char *file_path, char *pkgid,
-               char *version, char *type)
+               char *version, char *type, bool is_update)
 {
-       FILE *fp;\
+       FILE *fp;
 
        if (NULL == pkgid)
                return 0;
@@ -187,10 +188,13 @@ static int __make_pkgid_list(const char *file_path, char *pkgid,
        if (NULL == fp)
                return -1;
 
-       fprintf(fp, "%s\"%s\"   %s\"%s\"   %s\"%s\":\n", TOKEN_PKGID_STR,
-               pkgid, TOKEN_VERSION_STR, version, TOKEN_TYPE_STR, type);
+       fprintf(fp, "%s\"%s\"   %s\"%s\"   %s\"%s\"   %s\"%s\":\n",
+                       TOKEN_PKGID_STR, pkgid,
+                       TOKEN_VERSION_STR, version,
+                       TOKEN_TYPE_STR, type,
+                       TOKEN_UPDATE_STR, (is_update) ? "true" : "false");
 
-       fclose(fp);\
+       fclose(fp);
 
        return 0;
 }
@@ -201,6 +205,7 @@ static int __pkgid_list_cb(const pkgmgrinfo_pkginfo_h handle, void *user_data)
        char *pkgid = NULL;
        char *version = NULL;
        char *type = NULL;
+       bool is_update = false;
 
        ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
        err_if(ret < 0, "pkgmgrinfo_pkginfo_get_pkgid failed");
@@ -211,7 +216,11 @@ static int __pkgid_list_cb(const pkgmgrinfo_pkginfo_h handle, void *user_data)
        ret = pkgmgrinfo_pkginfo_get_type(handle, &type);
        err_if(ret < 0, "pkgmgrinfo_pkginfo_get_type failed");
 
-       ret = __make_pkgid_list((char *)user_data, pkgid, version, type);
+       ret = pkgmgrinfo_pkginfo_is_update(handle, &is_update);
+       err_if(ret < 0, "pkgmgrinfo_pkginfo_is_update failed");
+
+       ret = __make_pkgid_list((char *)user_data, pkgid,
+                       version, type, is_update);
        return ret;
 }
 
@@ -268,7 +277,7 @@ static char *__getvalue(const char *pBuf, const char *pKey, int depth)
 }
 
 static int __compare_pkgid(char *file_path, char *fota_pkgid,
-               char *fota_version)
+               char *fota_version, bool *is_updated)
 {
        retvm_if(file_path == NULL, -1, "file_path is null.\n");
        retvm_if(fota_pkgid == NULL, -1, "fota_pkgid is null.\n");
@@ -279,6 +288,7 @@ static int __compare_pkgid(char *file_path, char *fota_pkgid,
        char buf[BUF_SIZE] = {0};
        char *pkgid = NULL;
        char *version = NULL;
+       char *update = NULL;
        int compare = PMINFO_VERSION_SAME;
 
        fp = fopen(file_path, "r");
@@ -294,13 +304,24 @@ static int __compare_pkgid(char *file_path, char *fota_pkgid,
                }
 
                version = __getvalue(buf, TOKEN_VERSION_STR, 1);
-
                if (version == NULL) {
                        FREE_AND_NULL(pkgid);
                        _LOG("compare_data is null\n");
                        continue;
                }
 
+               update = __getvalue(buf, TOKEN_UPDATE_STR, 1);
+               if (update == NULL) {
+                       FREE_AND_NULL(pkgid);
+                       FREE_AND_NULL(version);
+                       _LOG("compare_data is null\n");
+                       continue;
+               }
+               if (!strncmp(update, "true", strlen("true")))
+                       *is_updated = true;
+               else
+                       *is_updated = false;
+
                if (strcmp(pkgid, fota_pkgid) == 0) {
                        ret = pkgmgrinfo_compare_package_version(version,
                                fota_version, &compare);
@@ -313,17 +334,20 @@ static int __compare_pkgid(char *file_path, char *fota_pkgid,
                                ret = PKG_IS_UPDATED;
                                FREE_AND_NULL(pkgid);
                                FREE_AND_NULL(version);
+                               FREE_AND_NULL(update);
                                break;
                        }
 
                        FREE_AND_NULL(pkgid);
                        FREE_AND_NULL(version);
+                       FREE_AND_NULL(update);
                        ret =  PKG_IS_SAME;
                        break;
                }
 
                FREE_AND_NULL(pkgid);
                FREE_AND_NULL(version);
+               FREE_AND_NULL(update);
                memset(buf, 0x00, BUF_SIZE);
        }
 
@@ -348,7 +372,7 @@ static int __compare_builtin_removable_pkgid(const char *pkgid)
        while (fgets(buf, BUF_SIZE, fp) != NULL) {
                __str_trim(buf);
 
-               if (strcmp(buf + strlen("/opt/usr/apps/"), pkgid) == 0) {
+               if (strstr(buf, pkgid) != NULL) {
                        _LOG("pkgid[%s] will be processed by builtin cmd.\n",
                                pkgid);
                        ret = -1;
@@ -384,33 +408,7 @@ char *__manifest_to_package(const char *manifest)
        return package;
 }
 
-static int __verify_uninstall_operation(char *pkgid)
-{
-       int ret = 0;
-       bool update = false;
-       bool system = false;
-       pkgmgrinfo_pkginfo_h handle = NULL;
-
-       ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
-       retvm_if(ret < 0, 0, "Failed to get handle\n");
-
-       ret = pkgmgrinfo_pkginfo_is_update(handle, &update);
-       tryvm_if(ret < 0, ret = 0, "Failed to get update\n");
-
-       ret = pkgmgrinfo_pkginfo_is_system(handle, &system);
-       tryvm_if(ret < 0, ret = 0, "Failed to get system\n");
-
-       if (system && update)
-               ret = -1;
-       else
-               ret = 0;
-
-catch:
-       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-       return ret;
-}
-
-static void __send_args_to_backend(char *pkgid, int compare_result)
+static void __send_args_to_backend(char *pkgid, int operation)
 {
        int ret = 0;
 
@@ -419,35 +417,47 @@ static void __send_args_to_backend(char *pkgid, int compare_result)
        struct timeval tv;
        gettimeofday(&tv, NULL);
        starttime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
+       char buf[BUF_SIZE];
 
        const char *install_ro[] = { "/usr/bin/tpk-backend", "-y", pkgid,
                                "--preload", "--partial-rw", NULL };
        const char *uninstall_ro[] = { "/usr/bin/tpk-backend", "-d", pkgid,
-                               "--preload", "--force-remove", "--partial-rw", NULL };
-
-       if (compare_result == PKG_IS_SAME)
+                               "--preload", "--force-remove",
+                               "--partial-rw", NULL };
+       const char *uninstall_ro_update[] = { "/usr/bin/tpk-backend", "-d",
+                               pkgid, "--keep-rwdata", NULL };
+       const char *db_update_to_normal_pkg[] = {"/usr/bin/sqlite3",
+                               NULL, NULL, NULL};
+
+       if (operation == PKG_NEED_NOTHING)
                return;
 
        if (__compare_builtin_removable_pkgid(pkgid) < 0)
                return;
 
-       switch (compare_result) {
-       case PKG_IS_INSERTED:
-       case PKG_IS_UPDATED:
+       switch (operation) {
+       case PKG_NEED_INSTALL:
+       case PKG_NEED_ROUPDATE:
                ret = __xsystem(install_ro);
                break;
-
-       case PKG_IS_NOT_EXIST:
-               ret = __verify_uninstall_operation(pkgid);
-               if (ret < 0) {
-                       _LOG("pkgid[%s] is updated system, "
-                               "Do not uninstall it\n", pkgid);
-                       return;
-               }
-
+       case PKG_NEED_UNINSTALL:
                ret = __xsystem(uninstall_ro);
                break;
-       default:
+       case PKG_NEED_UPDATE_TO_RW:
+               snprintf(buf, sizeof(buf),
+                               "UPDATE package_info SET " \
+                               "package_preload='false', " \
+                               "package_system='false' "\
+                               "WHERE package='%s'", pkgid);
+               db_update_to_normal_pkg[1] = strdup(DBPATH);
+               db_update_to_normal_pkg[2] = strdup(buf);
+               ret = __xsystem(db_update_to_normal_pkg);
+               FREE_AND_NULL(db_update_to_normal_pkg[1]);
+               FREE_AND_NULL(db_update_to_normal_pkg[2]);
+               break;
+       case PKG_NEED_RWUNINSTALL:
+       case PKG_NEED_UPDATE_TO_RO:
+               ret = __xsystem(uninstall_ro_update);
                break;
        }
 
@@ -585,7 +595,7 @@ static int __find_preload_pkgid_from_xml(const char *file_path,
                        type = strdup("tpk");
 
                ret = __make_pkgid_list((char *)file_path, pkgid,
-                       version, type);
+                       version, type, false);
                if (ret < 0)
                        _LOG("Make file Fail : %s => %s, %s\n",
                                buf, pkgid, version);
@@ -618,9 +628,9 @@ static int __find_preload_pkgid_from_db(const char *file_path)
                "(PMINFO_PKGINFO_PROP_PACKAGE_PRELOAD) failed\n");
 
        ret = pkgmgrinfo_pkginfo_filter_add_bool(handle,
-               PMINFO_PKGINFO_PROP_PACKAGE_READONLY, 1);
+               PMINFO_PKGINFO_PROP_PACKAGE_SYSTEM, 1);
        tryvm_if(ret < 0, ret = -1, "pkgmgrinfo_pkginfo_filter_add_bool"
-               "(PMINFO_PKGINFO_PROP_PACKAGE_READONLY) failed\n");
+               "(PMINFO_PKGINFO_PROP_PACKAGE_SYSTEM) failed\n");
 
        ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(handle,
                __pkgid_list_cb, (void *)file_path);
@@ -649,6 +659,9 @@ static int __find_matched_pkgid_from_list(const char *source_file,
        int total_pkg_cnt = 0;
 
        int compare_result = 0;
+       int operation = PKG_NEED_NOTHING;
+
+       bool db_update;
 
        fp = fopen(source_file, "r");
        retvm_if(fp == NULL, -1, "Fail get : %s\n", source_file);
@@ -665,19 +678,30 @@ static int __find_matched_pkgid_from_list(const char *source_file,
                version = __getvalue(buf, TOKEN_VERSION_STR, 1);
 
                compare_result = __compare_pkgid((char *)target_file, pkgid,
-                                               version);
+                                               version, &db_update);
                if (compare_result == PKG_IS_NOT_EXIST) {
                        _LOG("pkgid[%s] is installed, Start install\n", pkgid);
-                       compare_result = PKG_IS_INSERTED;
+                       operation = PKG_NEED_INSTALL;
                        insert_pkg_cnt++;
                } else if (compare_result == PKG_IS_SAME) {
-                       same_pkg_cnt++;
+                       if (db_update) {
+                               operation = PKG_NEED_RWUNINSTALL;
+                               update_pkg_cnt++;
+                       } else {
+                               operation = PKG_NEED_NOTHING;
+                               same_pkg_cnt++;
+                       }
                } else if (compare_result == PKG_IS_UPDATED) {
+                       if (db_update) {
+                               operation = PKG_NEED_UPDATE_TO_RO;
+                       } else {
+                               operation = PKG_NEED_ROUPDATE;
+                       }
                        update_pkg_cnt++;
                }
 
                total_pkg_cnt++;
-               __send_args_to_backend(pkgid, compare_result);
+               __send_args_to_backend(pkgid, operation);
 
                memset(buf, 0x00, BUF_SIZE);
                FREE_AND_NULL(pkgid);
@@ -706,8 +730,10 @@ static int __find_deleted_pkgid_from_list(const char *source_file,
        char buf[BUF_SIZE] = {0};
        char *pkgid = NULL;
        char *version = NULL;
-
+       char *update = NULL;
+       bool xml_update;
        int deleted_pkg_cnt = 0;
+       int modified_pkg_cnt = 0;
        int total_pkg_cnt = 0;
 
        int compare_result = 0;
@@ -727,24 +753,35 @@ static int __find_deleted_pkgid_from_list(const char *source_file,
                version = __getvalue(buf, TOKEN_VERSION_STR, 1);
 
                compare_result = __compare_pkgid((char *)target_file, pkgid,
-                                               version);
+                                               version, &xml_update);
                if (compare_result == PKG_IS_NOT_EXIST) {
-                       _LOG("pkgid[%s] is uninstall, Start uninstall\n",
-                               pkgid);
-                       __send_args_to_backend(pkgid, compare_result);
-
-                       deleted_pkg_cnt++;
+                       update = __getvalue(buf, TOKEN_UPDATE_STR, 1);
+                       if (update == NULL) {
+                               FREE_AND_NULL(pkgid);
+                               FREE_AND_NULL(version);
+                               continue;
+                       }
+                       if (!strncmp(update, "false", strlen("false"))) {
+                               __send_args_to_backend(pkgid,
+                                               PKG_NEED_UNINSTALL);
+                               deleted_pkg_cnt++;
+                       } else {
+                               __send_args_to_backend(pkgid,
+                                               PKG_NEED_UPDATE_TO_RW);
+                               modified_pkg_cnt++;
+                       }
                }
                total_pkg_cnt++;
 
                memset(buf, 0x00, BUF_SIZE);
                FREE_AND_NULL(pkgid);
                FREE_AND_NULL(version);
+               FREE_AND_NULL(update);
        }
 
        _LOG("-------------------------------------------------------\n");
-       _LOG("[Total pkg=%d, deleted package=%d]\n",
-               total_pkg_cnt, deleted_pkg_cnt);
+       _LOG("[Total pkg=%d, deleted package=%d, modified package=%d]\n",
+               total_pkg_cnt, deleted_pkg_cnt, modified_pkg_cnt);
        _LOG("-------------------------------------------------------\n");
 
        if (fp != NULL)
index 49dd981..e8d0e2f 100644 (file)
@@ -25,6 +25,7 @@
 #define TOKEN_PATH_STR         "path="
 #define TOKEN_OPERATION_STR    "op="
 #define TOKEN_REMOVE_STR       "removable="
+#define TOKEN_UPDATE_STR       "update="
 
 #define SEPERATOR_END          '"'
 #define SEPERATOR_MID          ':'
@@ -95,6 +96,16 @@ typedef enum {
        PKG_IS_INSERTED
 } COMPARE_RESULT;
 
+typedef enum {
+       PKG_NEED_NOTHING = 0,
+       PKG_NEED_INSTALL,
+       PKG_NEED_UNINSTALL,
+       PKG_NEED_ROUPDATE,
+       PKG_NEED_UPDATE_TO_RW,
+       PKG_NEED_RWUNINSTALL,
+       PKG_NEED_UPDATE_TO_RO
+} UPGRADE_OPRATION;
+
 enum rpm_request_type {
        INSTALL_REQ,
        UNINSTALL_REQ,