Check if db recovery was aborted 53/207953/10
authorSangyoon Jang <jeremy.jang@samsung.com>
Fri, 14 Jun 2019 07:06:12 +0000 (16:06 +0900)
committerJunghyun Yeon <jungh.yeon@samsung.com>
Mon, 23 Sep 2019 06:10:35 +0000 (06:10 +0000)
If db recovery was aborted and not corrupted, db will be remained
incomplete.

Change-Id: I6ba27f5459dfd9b9075f7cfb0f093f1b806f7007
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
tool/pkg-db-recovery.c

index ac3c2c2..3aae1af 100644 (file)
@@ -58,6 +58,9 @@
 
 #define PKGMGR_PARSER_DB_FILE tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_parser.db")
 #define PKGMGR_CERT_DB_FILE tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_cert.db")
+#define NEED_RECOVERY_FILE tzplatform_mkpath(TZ_SYS_DB, ".need_pkg_recovery")
+
+#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
 
 typedef struct user_info {
        uid_t uid;
@@ -94,6 +97,42 @@ static int __db_busy_handler(void *data, int count)
        }
 }
 
+static bool __check_aborted(uid_t uid)
+{
+       char buf[BUFSIZE];
+
+       snprintf(buf, sizeof(buf), "%s_%d", NEED_RECOVERY_FILE, uid);
+       if (access(buf, F_OK) == 0) {
+               return true;
+       } else {
+               if (errno != ENOENT)
+                       LOGE("failed to access %s, errno: %d", buf, errno);
+               return false;
+       }
+}
+
+static void __create_need_to_recovery_file(uid_t uid)
+{
+       int fd;
+       char buf[BUFSIZE];
+
+       snprintf(buf, sizeof(buf), "%s_%d", NEED_RECOVERY_FILE, uid);
+       fd = open(buf, O_CREAT | O_WRONLY, S_IRWXU);
+       if (fd == -1)
+               LOGE("failed to create file: %s, errno: %d", buf, errno);
+       else
+               close(fd);
+}
+
+static void __remove_need_to_recovery_file(uid_t uid)
+{
+       char buf[BUFSIZE];
+
+       snprintf(buf, sizeof(buf), "%s_%d", NEED_RECOVERY_FILE, uid);
+       if (unlink(buf))
+               LOGE("failed to remove file: %s, errno: %d", buf, errno);
+}
+
 static bool __integrity_check(const char *db_path)
 {
        int ret = -1;
@@ -325,17 +364,19 @@ static void __initdb(uid_t uid)
        const char *initdb_ro[] =  { "/usr/bin/pkg_initdb",
                        "--recover-db", "--keep-db", NULL};
 
+       __create_need_to_recovery_file(uid);
        __create_db(uid);
        __change_permission(uid);
        snprintf(uid_string, sizeof(uid_string), "%d", (int)uid);
        _xsystem((uid > REGULAR_USER) ? initdb_rw : initdb_ro);
+       __remove_need_to_recovery_file(uid);
 }
 
 static void __initdb_all()
 {
        GList *tmp_list = NULL;
        user_info *tmp_info;
-       __initdb(getuid());
+       __initdb(GLOBAL_USER);
 
        for (tmp_list = user_info_list;
                        tmp_list != NULL; tmp_list = g_list_next(tmp_list)) {
@@ -350,6 +391,7 @@ static void __check_user_db()
 {
        GList *tmp_list = NULL;
        user_info *tmp_info;
+       bool need_recovery = false;
 
        for (tmp_list = user_info_list;
                        tmp_list != NULL; tmp_list = g_list_next(tmp_list)) {
@@ -358,8 +400,13 @@ static void __check_user_db()
                        continue;
                if (!__integrity_check(tmp_info->db_path)) {
                        LOGE("User db for %d has corrupted", (int)tmp_info->uid);
-                       __initdb(tmp_info->uid);
+                       need_recovery = true;
+               } else if (__check_aborted(tmp_info->uid)) {
+                       need_recovery = true;
                }
+
+               if (need_recovery)
+                       __initdb(tmp_info->uid);
        }
 }
 
@@ -425,12 +472,20 @@ static void _get_user_list()
 
 static void _check_db()
 {
+       int need_recovery = false;
+
        if (!__integrity_check(PKGMGR_CERT_DB_FILE)) {
                LOGE("Cert db corrupted. restore entire pkgmgr db");
-               __initdb_all();
-               return;
+               need_recovery = true;
        } else if (!__integrity_check(PKGMGR_PARSER_DB_FILE)) {
                LOGE("Global parser db corrupted. restore entire pkgmgr db");
+               need_recovery = true;
+       } else if (__check_aborted(GLOBAL_USER)) {
+               LOGE("Previous recovery was aborted. restore entire pkgmgr db");
+               need_recovery = true;
+       }
+
+       if (need_recovery) {
                __initdb_all();
                return;
        }