#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;
}
}
+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;
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)) {
{
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)) {
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);
}
}
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;
}