From b2280aa76ba825de25ea726614a25be31f7e05cb Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Thu, 28 Feb 2019 17:25:01 +0900 Subject: [PATCH] Supplement db recovery tool - Change printf to dlog. - Add busy handler to prevent drop db when failed to check integrity check. Change-Id: Ida824ae32e2a55b7ad17cac3e95f9063ec0f6748 Signed-off-by: Junghyun Yeon --- tool/CMakeLists.txt | 4 +-- tool/pkg-db-creator.c | 29 +++++++++++-------- tool/pkg-db-recovery.c | 76 ++++++++++++++++++++++++++++++++++---------------- 3 files changed, 72 insertions(+), 37 deletions(-) diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt index b040a1b..6920722 100644 --- a/tool/CMakeLists.txt +++ b/tool/CMakeLists.txt @@ -6,10 +6,10 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) ### Get required CFLAGS, LDFLAGS from pkg-config -SET(PKG_DB_RECOVERY pkg-db-recovery) +SET(PKG_DB_RECOVERY "pkg-db-recovery") SET(PKG_DB_CREATOR "pkg-db-creator") include(FindPkgConfig) -pkg_check_modules(TOOL_DEPS REQUIRED glib-2.0 sqlite3 libtzplatform-config) +pkg_check_modules(TOOL_DEPS REQUIRED glib-2.0 sqlite3 libtzplatform-config dlog) FOREACH(FLAG ${TOOL_DEPS_CFLAGS}) SET(${CMAKE_C_FLAGS} "${CMAKE_C_FLAGS} ${FLAG}") diff --git a/tool/pkg-db-creator.c b/tool/pkg-db-creator.c index ba2026d..b5bfb95 100644 --- a/tool/pkg-db-creator.c +++ b/tool/pkg-db-creator.c @@ -24,11 +24,18 @@ #include #include +#include #include #include "pkgmgr-info.h" #include "pkgmgr_parser_db.h" +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "PKG_DB_CREATOR" + #ifndef OWNER_ROOT #define OWNER_ROOT 0 #endif @@ -55,12 +62,12 @@ static int _remove_db(uid_t uid) parser_db = getUserPkgParserDBPathUID(uid); if (!parser_db) { - printf("Failed to get parser db path\n"); + LOGE("Failed to get parser db path"); return -1; } if (_remove_file(parser_db) != 0) { - printf("Failed to remove parser db[%s]\n", parser_db); + LOGE("Failed to remove parser db[%s]", parser_db); free(parser_db); return -1; } @@ -68,7 +75,7 @@ static int _remove_db(uid_t uid) snprintf(journal_path, sizeof(journal_path), "%s-journal", parser_db); free(parser_db); if (_remove_file(journal_path) != 0) { - printf("Failed to remove journal[%s]\n", journal_path); + LOGE("Failed to remove journal[%s]", journal_path); return -1; } @@ -77,12 +84,12 @@ static int _remove_db(uid_t uid) cert_db = getUserPkgCertDBPath(); if (!cert_db) { - printf("Failed to get cet db path\n"); + LOGE("Failed to get cet db path"); return -1; } if (_remove_file(cert_db) != 0) { - printf("Failed to remove parser db[%s]\n", cert_db); + LOGE("Failed to remove parser db[%s]", cert_db); free(cert_db); return -1; } @@ -90,7 +97,7 @@ static int _remove_db(uid_t uid) snprintf(journal_path, sizeof(journal_path), "%s-journal", cert_db); free(cert_db); if (_remove_file(journal_path) != 0) { - printf("Failed to remove journal[%s]\n", journal_path); + LOGE("Failed to remove journal[%s]", journal_path); return -1; } @@ -103,23 +110,23 @@ int main(int argc, char *argv[]) int ret = 0; if ((int)getuid() > OWNER_ROOT) { - printf("This cmd is not allowed for regular user\n"); + LOGE("This cmd is not allowed for regular user"); return -1; } if (argc == 1) { - printf("argument should be provided\n"); + LOGE("argument should be provided"); return -1; } uid = atoi(argv[1]); ret = _remove_db((uid_t)uid); if (ret != 0) - printf("failed to remove database for uid[%d]\n", uid); + LOGE("failed to remove database for uid[%d]", uid); ret = pkgmgr_parser_initialize_parser_db((uid_t)uid); if (ret != 0) { - printf("failed to create parser db for uid [%d], err[%d]\n", uid, ret); + LOGE("failed to create parser db for uid [%d], err[%d]", uid, ret); return -1; } @@ -127,7 +134,7 @@ int main(int argc, char *argv[]) if (uid == 0) { ret = pkgmgr_parser_initialize_cert_db(); if (ret != 0) { - printf("failed to create cert db for uid [%d], err[%d]\n", uid, ret); + LOGE("failed to create cert db for uid [%d], err[%d]", uid, ret); return -1; } } diff --git a/tool/pkg-db-recovery.c b/tool/pkg-db-recovery.c index 00b2063..e4475f1 100644 --- a/tool/pkg-db-recovery.c +++ b/tool/pkg-db-recovery.c @@ -34,11 +34,18 @@ #include #include +#include #include #include #include +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "PKG_DB_RECOVERY" + #ifndef APPFW_USER #define APPFW_USER "app_fw" #endif @@ -66,7 +73,7 @@ static char *__get_dbpath(uid_t uid) db_path = tzplatform_getenv(TZ_SYS_DB); if (db_path == NULL) { - printf("Failed to get TZ_SYS_DB path"); + LOGE("Failed to get TZ_SYS_DB path"); return NULL; } @@ -74,6 +81,19 @@ static char *__get_dbpath(uid_t uid) return strdup(path); } +#define BUSY_WAITING_USEC (1000000 / 10 / 2) /* 0.05 sec */ +#define BUSY_WAITING_MAX 100 /* wait for max 5 sec */ +static int __db_busy_handler(void *data, int count) +{ + if (count < BUSY_WAITING_MAX) { + usleep(BUSY_WAITING_USEC); + return 1; + } else { + /* sqlite3_prepare_v2 will return SQLITE_BUSY */ + return 0; + } +} + static bool __integrity_check(const char *db_path) { int ret = -1; @@ -86,31 +106,39 @@ static bool __integrity_check(const char *db_path) ret = sqlite3_open_v2(db_path, &db, SQLITE_OPEN_READWRITE, NULL); if (ret != SQLITE_OK) { - printf("Failed to open db\n"); + LOGE("Failed to open db"); return false; } + ret = sqlite3_busy_handler(db, __db_busy_handler, NULL); + if (ret != SQLITE_OK) { + LOGE("failed to register busy handler: %s", + sqlite3_errmsg(db)); + sqlite3_close_v2(db); + return ret; + } + ret = sqlite3_prepare_v2(db, integrity_check_query, strlen(integrity_check_query), &stmt, NULL); if (ret != SQLITE_OK) { - printf("Failed to check integrity_check : %s\n", sqlite3_errmsg(db)); + LOGE("Failed to check integrity_check : %s", sqlite3_errmsg(db)); goto err; } ret = sqlite3_step(stmt); if (ret != SQLITE_ROW) { - printf("Failed to check integrity db :%s\n", sqlite3_errmsg(db)); + LOGE("Failed to check integrity db :%s", sqlite3_errmsg(db)); goto err; } check_result = (const char *)sqlite3_column_text(stmt, 0); if (!check_result) { - printf("Failed to check integrity db :%s\n", sqlite3_errmsg(db)); + LOGE("Failed to check integrity db :%s", sqlite3_errmsg(db)); goto err; } if (strcasecmp(check_result, "ok") != 0) { - printf("db corrupted :%s\n", db_path); + LOGE("db corrupted :%s", db_path); goto err; } @@ -139,9 +167,9 @@ static bool __change_owner(const char *files[2], uid_t uid) ret = getpwnam_r(APPFW_USER, &pwd, buf, sizeof(buf), &result); if (result == NULL) { if (ret == 0) - printf("no such user: %d\n", uid); + LOGE("no such user: %d", uid); else - printf("getpwnam_r failed: %d", errno); + LOGE("getpwnam_r failed: %d", errno); return false; } uid = pwd.pw_uid; @@ -150,32 +178,32 @@ static bool __change_owner(const char *files[2], uid_t uid) ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result); if (result == NULL) { if (ret == 0) - printf("no such user: %d\n", uid); + LOGE("no such user: %d", uid); else - printf("getpwuid_r failed: %d\n", errno); + LOGE("getpwuid_r failed: %d", errno); return false; } for (i = 0; i < 2; i++) { fd = open(files[i], O_RDONLY); if (fd == -1) { - printf("open %s failed: %d\n", files[i], errno); + LOGE("open %s failed: %d", files[i], errno); return false; } ret = fstat(fd, &sb); if (ret == -1) { - printf("stat %s failed: %d\n", files[i], errno); + LOGE("stat %s failed: %d", files[i], errno); close(fd); return false; } if (S_ISLNK(sb.st_mode)) { - printf("%s is symlink!\n", files[i]); + LOGE("%s is symlink!", files[i]); close(fd); return false; } ret = fchown(fd, uid, pwd.pw_gid); if (ret == -1) { - printf("fchown %s failed: %d\n", files[i], errno); + LOGE("fchown %s failed: %d", files[i], errno); close(fd); return false; } @@ -185,7 +213,7 @@ static bool __change_owner(const char *files[2], uid_t uid) mode |= S_IWOTH; ret = fchmod(fd, mode); if (ret == -1) { - printf("fchmod %s failed: %d\n", files[i], errno); + LOGE("fchmod %s failed: %d", files[i], errno); close(fd); return false;; } @@ -210,7 +238,7 @@ static void __change_permission(uid_t uid) files[1] = journal_file; if (!__change_owner(files, uid)) { - printf("Failed to change ownership\n"); + LOGE("Failed to change ownership"); return; } @@ -219,7 +247,7 @@ static void __change_permission(uid_t uid) "%s-journal", PKGMGR_CERT_DB_FILE); files[1] = journal_file; if (!__change_owner(files, uid)) { - printf("Failed to change ownership\n"); + LOGE("Failed to change ownership"); return; } } else { @@ -240,7 +268,7 @@ static void __change_permission(uid_t uid) files[1] = journal_file; if (!__change_owner(files, uid)) { - printf("Failed to change ownership\n"); + LOGE("Failed to change ownership"); return; } } @@ -328,7 +356,7 @@ static void __check_user_db() if (!tmp_info) continue; if (!__integrity_check(tmp_info->db_path)) { - printf("User db for %d has corrupted\n", (int)tmp_info->uid); + LOGE("User db for %d has corrupted", (int)tmp_info->uid); __initdb(tmp_info->uid); } } @@ -355,7 +383,7 @@ static void _get_user_list() db_path = tzplatform_getenv(TZ_SYS_DB); if (db_path == NULL) { - printf("Failed to get TZ_SYS_DB path"); + LOGE("Failed to get TZ_SYS_DB path"); return; } @@ -368,7 +396,7 @@ static void _get_user_list() ret = stat(abs_dirname, &stats); if (ret != 0) { - printf("failed to stat: %d (%s)", errno, abs_dirname); + LOGE("failed to stat: %d (%s)", errno, abs_dirname); continue; } @@ -397,11 +425,11 @@ static void _get_user_list() static void _check_db() { if (!__integrity_check(PKGMGR_CERT_DB_FILE)) { - printf("Cert db corrupted. restore entire pkgmgr db\n"); + LOGE("Cert db corrupted. restore entire pkgmgr db"); __initdb_all(); return; } else if (!__integrity_check(PKGMGR_PARSER_DB_FILE)) { - printf("Global parser db corrupted. restore entire pkgmgr db\n"); + LOGE("Global parser db corrupted. restore entire pkgmgr db"); __initdb_all(); return; } @@ -412,7 +440,7 @@ static void _check_db() int main(int argc, char *argv[]) { if ((int)getuid() > REGULAR_USER) { - printf("This cmd is not allowed for regular user\n"); + LOGE("This cmd is not allowed for regular user"); return -1; } -- 2.7.4