From d08949abc44e2ab981a696615021beb1f221aef5 Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Tue, 5 Jul 2016 21:57:43 +0900 Subject: [PATCH] fix pkg move behavior kill apps and umount image when sdcard is removed Change-Id: I120edd133e3c349ae1e4dfce512975436e6c48ad Signed-off-by: jongmyeongko --- inc/app2ext_interface.h | 1 + packaging/app2sd.spec | 1 + plugin/app2sd/CMakeLists.txt | 2 +- plugin/app2sd/inc/app2sd_internals.h | 4 + plugin/app2sd/src/app2sd_client_interface.c | 28 ++++ plugin/app2sd/src/app2sd_interface.c | 179 +++++++++++++------------- plugin/app2sd/src/app2sd_internals.c | 30 +++-- plugin/app2sd/src/app2sd_internals_registry.c | 42 ++++++ src/app2ext_interface.c | 3 + 9 files changed, 191 insertions(+), 99 deletions(-) diff --git a/inc/app2ext_interface.h b/inc/app2ext_interface.h index 45743ce..7bcf819 100644 --- a/inc/app2ext_interface.h +++ b/inc/app2ext_interface.h @@ -156,6 +156,7 @@ typedef enum app2ext_error_t { APP2EXT_ERROR_OPERATION_NOT_PERMITTED, APP2EXT_ERROR_SAME_LOOPBACK_DEVICE_EXISTS, APP2EXT_ERROR_PKGMGR_ERROR, + APP2EXT_ERROR_KILLAPP_ERROR, #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE, APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE, diff --git a/packaging/app2sd.spec b/packaging/app2sd.spec index 61e8bde..6d7826e 100644 --- a/packaging/app2sd.spec +++ b/packaging/app2sd.spec @@ -15,6 +15,7 @@ BuildRequires: pkgconfig(minizip) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(gio-2.0) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(aul) BuildRequires: cmake %description diff --git a/plugin/app2sd/CMakeLists.txt b/plugin/app2sd/CMakeLists.txt index 1545c32..0adce49 100644 --- a/plugin/app2sd/CMakeLists.txt +++ b/plugin/app2sd/CMakeLists.txt @@ -3,7 +3,7 @@ PROJECT(app2sd C) ### Required packages INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED libssl dlog openssl pkgmgr-info libtzplatform-config gio-2.0 glib-2.0 minizip) +pkg_check_modules(pkgs REQUIRED libssl dlog openssl pkgmgr-info libtzplatform-config gio-2.0 glib-2.0 minizip aul) FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/plugin/app2sd/inc/app2sd_internals.h b/plugin/app2sd/inc/app2sd_internals.h index 9da353c..7fbf09f 100644 --- a/plugin/app2sd/inc/app2sd_internals.h +++ b/plugin/app2sd/inc/app2sd_internals.h @@ -171,6 +171,10 @@ int _app2sd_set_info_in_db(const char *pkgid, const char *passwd, int _app2sd_get_info_from_db(const char *filename, char **pkgid, uid_t *uid); +typedef int (*app2sd_info_cb)(const char *pkgid, uid_t uid); + +int _app2sd_get_foreach_info_from_db(app2sd_info_cb cb_func); + int _app2sd_force_clean(const char *pkgid, const char *application_path, const char *loopback_device, uid_t uid); diff --git a/plugin/app2sd/src/app2sd_client_interface.c b/plugin/app2sd/src/app2sd_client_interface.c index 852e6fe..c861215 100644 --- a/plugin/app2sd/src/app2sd_client_interface.c +++ b/plugin/app2sd/src/app2sd_client_interface.c @@ -27,6 +27,8 @@ #include #include +#include + #include "app2sd_client_interface.h" #include "app2ext_utils.h" @@ -503,6 +505,8 @@ int app2sd_client_usr_pre_move_installed_app(const char *pkgid, GList *dir_list, GVariantBuilder *builder = NULL; GVariant *param = NULL; app2sd_cmd cmd = APP2SD_MOVE_APP_TO_PHONE; + pkgmgrinfo_pkginfo_h info_handle = NULL; + pkgmgrinfo_installed_storage storage = PMINFO_INTERNAL_STORAGE; /* validate the function parameter recieved */ if (pkgid == NULL || dir_list == NULL @@ -512,6 +516,30 @@ int app2sd_client_usr_pre_move_installed_app(const char *pkgid, GList *dir_list, return APP2EXT_ERROR_INVALID_ARGUMENTS; } + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &info_handle); + if (ret < 0) { + _E("failed to get pkginfo for pkg(%s), uid(%d), ret(%d)", + pkgid, uid, ret); + return APP2EXT_ERROR_PKGMGR_ERROR; + } + ret = pkgmgrinfo_pkginfo_get_installed_storage(info_handle, &storage); + if (ret < 0) { + _E("failed to get installed storage for pkg(%s) of uid(%d), ret(%d)", + pkgid, uid, ret); + pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle); + return APP2EXT_ERROR_PKGMGR_ERROR; + } + + if ((move_type == APP2EXT_MOVE_TO_EXT && storage == PMINFO_EXTERNAL_STORAGE) + || (move_type == APP2EXT_MOVE_TO_PHONE && storage == PMINFO_INTERNAL_STORAGE)) { + _E("PKG_EXISTS in [%d] STORAGE", storage); + pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle); + return APP2EXT_ERROR_PKG_EXISTS; + } else { + _D("pkgid[%s] move to STORAGE [%d]", pkgid, storage); + } + pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle); + if (move_type == APP2EXT_MOVE_TO_EXT) cmd = APP2SD_MOVE_APP_TO_MMC; diff --git a/plugin/app2sd/src/app2sd_interface.c b/plugin/app2sd/src/app2sd_interface.c index d7144fd..2991b8b 100644 --- a/plugin/app2sd/src/app2sd_interface.c +++ b/plugin/app2sd/src/app2sd_interface.c @@ -22,6 +22,7 @@ */ #include +#include #include "app2sd_internals.h" @@ -449,6 +450,67 @@ int app2sd_usr_on_demand_setup_init(const char *pkgid, uid_t uid) return ret; } +static int _app2sd_application_handler(const pkgmgrinfo_appinfo_h handle, void *data) +{ + int ret = 0; + int pid = 0; + char *appid = NULL; + uid_t uid = *(uid_t *)data; + + ret = pkgmgrinfo_appinfo_get_appid(handle, &appid); + if (ret < 0) { + _E("failed to get appid"); + return APP2EXT_ERROR_PKGMGR_ERROR; + } + + _D("appid(%s), uid(%d)", appid, uid); + + ret = aul_app_is_running_for_uid(appid, uid); + if (ret == 0) + return APP2EXT_SUCCESS; + + pid = aul_app_get_pid_for_uid(appid, uid); + if (pid < 0) { + _E("failed to get pid"); + return APP2EXT_ERROR_KILLAPP_ERROR; + } + + ret = aul_terminate_pid_sync_for_uid(pid, uid); + if (ret != AUL_R_OK) { + _E("failed to kill app"); + return APP2EXT_ERROR_KILLAPP_ERROR; + } + + return APP2EXT_SUCCESS; +} + +static int _app2sd_kill_running_app(const char *pkgid, uid_t uid) +{ + int ret = 0; + pkgmgrinfo_pkginfo_h handle; + + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle); + if (ret < 0) { + _E("failed to get pkginfo"); + return APP2EXT_ERROR_PKGMGR_ERROR; + } + + ret = pkgmgrinfo_appinfo_get_usr_list(handle, + PMINFO_ALL_APP, _app2sd_application_handler, &uid, uid); + if (ret < 0) { + _E("failed to get appinfo"); + return APP2EXT_ERROR_PKGMGR_ERROR; + } + + ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + if (ret < 0) { + _E("failed to destroy pkginfo"); + return APP2EXT_ERROR_PKGMGR_ERROR; + } + + return APP2EXT_SUCCESS; +} + int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid) { int ret = APP2EXT_SUCCESS; @@ -456,6 +518,7 @@ int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid) char loopback_device[FILENAME_MAX] = { 0, }; char *encoded_id = NULL; FILE *fp = NULL; + int mmc_present = 1; /* validate the function parameter recieved */ if (pkgid == NULL) { @@ -463,11 +526,13 @@ int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid) return APP2EXT_ERROR_INVALID_ARGUMENTS; } + _app2sd_kill_running_app(pkgid, uid); + /* check whether MMC is present or not */ ret = _app2sd_check_mmc_status(); if (ret) { - _E("MMC not preset OR Not ready (%d)", ret); - return APP2EXT_ERROR_MMC_STATUS; + _W("MMC not preset OR Not ready (%d)", ret); + mmc_present = 0; } encoded_id = _app2sd_get_encoded_name(pkgid, uid); @@ -490,12 +555,14 @@ int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid) } free(encoded_id); - fp = fopen(loopback_device, "r+"); - if (fp == NULL) { - _E("app entry is not present in SD Card"); - return APP2EXT_ERROR_INVALID_PACKAGE; + if (mmc_present) { + fp = fopen(loopback_device, "r+"); + if (fp == NULL) { + _E("app entry is not present in SD Card"); + return APP2EXT_ERROR_INVALID_PACKAGE; + } + fclose(fp); } - fclose(fp); ret = _app2sd_unmount_app_content(application_path); if (ret) { @@ -748,32 +815,6 @@ int app2sd_usr_pre_move_installed_app(const char *pkgid, return APP2EXT_ERROR_INVALID_ARGUMENTS; } - pkgmgrinfo_pkginfo_h info_handle = NULL; - pkgmgrinfo_installed_storage storage = PMINFO_INTERNAL_STORAGE; - pkgmgr_ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &info_handle); - if (pkgmgr_ret < 0) { - _E("failed to get pkginfo for pkg(%s), uid(%d), pkgmgr_ret(%d)", - pkgid, uid, pkgmgr_ret); - return APP2EXT_ERROR_PKGMGR_ERROR; - } - pkgmgr_ret = pkgmgrinfo_pkginfo_get_installed_storage(info_handle, &storage); - if (pkgmgr_ret < 0) { - _E("failed to get installed storage for pkg(%s) of uid(%d), pkgmgr_ret(%d)", - pkgid, uid, pkgmgr_ret); - pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle); - return APP2EXT_ERROR_PKGMGR_ERROR; - } - - if ((move_type == APP2EXT_MOVE_TO_EXT && storage == PMINFO_EXTERNAL_STORAGE) - || (move_type == APP2EXT_MOVE_TO_PHONE && storage == PMINFO_INTERNAL_STORAGE)) { - _E("PKG_EXISTS in [%d] STORAGE", storage); - pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle); - return APP2EXT_ERROR_PKG_EXISTS; - } else { - _D("pkgid[%s] move to STORAGE [%d]", pkgid, storage); - } - pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle); - ret = __app2sd_create_app2sd_directories(uid); if (ret) { _E("failed to create app2sd dirs"); @@ -1230,8 +1271,8 @@ int app2sd_enable_full_pkg(void) dir = opendir(APP2SD_PATH); if (!dir) { - if (strerror_r(errno, buf, sizeof(buf)) == 0) - _E("failed to opendir (%s)", buf); + strerror_r(errno, buf, sizeof(buf)); + _E("failed to opendir (%s)", buf); return APP2EXT_ERROR_OPEN_DIR; } @@ -1256,15 +1297,13 @@ int app2sd_enable_full_pkg(void) _E("failed to get info from db"); break;; } - if (pkgid && uid > 0) { + if (pkgid) { _D("pkgid(%s), uid(%d)", pkgid, uid); ret = app2sd_usr_on_demand_setup_init(pkgid, uid); if (ret) { _E("error(%d)", ret); break; } - } - if (pkgid) { free(pkgid); pkgid = NULL; } @@ -1279,65 +1318,33 @@ int app2sd_enable_full_pkg(void) return ret; } -int app2sd_disable_full_pkg(void) +static int _app2sd_info_cb_func(const char *pkgid, uid_t uid) { int ret = APP2EXT_SUCCESS; - int rc = 0; - char buf[FILENAME_MAX] = { 0, }; - char loopback_device[FILENAME_MAX] = { 0, }; - DIR *dir = NULL; - struct dirent entry; - struct dirent *result = NULL; - char *pkgid = NULL; - uid_t uid = 0; - dir = opendir(APP2SD_PATH); - if (!dir) { - if (strerror_r(errno, buf, sizeof(buf)) == 0) - _E("failed to opendir (%s)", buf); - return APP2EXT_ERROR_OPEN_DIR; + if (pkgid) { + _D("pkgid(%s), uid(%d)", pkgid, uid); + ret = app2sd_usr_on_demand_setup_exit(pkgid, uid); + if (ret) + _E("error(%d)", ret); } + return ret; +} + +int app2sd_disable_full_pkg(void) +{ + int ret = APP2EXT_SUCCESS; + ret = _app2sd_initialize_db(); if (ret) { _E("app2sd db initialize failed"); - closedir(dir); return APP2EXT_ERROR_SQLITE_REGISTRY; } - for (rc = readdir_r(dir, &entry, &result); - rc == 0 && result != NULL; - rc = readdir_r(dir, &entry, &result)) { - if (strcmp(entry.d_name, ".") == 0 || - strcmp(entry.d_name, "..") == 0) - continue; - snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s", - APP2SD_PATH, entry.d_name); - ret = _app2sd_get_info_from_db(loopback_device, - &pkgid, &uid); - if (ret) { - _E("failed to get info from db"); - break; - } - if (pkgid && uid > 0) { - _D("pkgid(%s), uid(%d)", pkgid, uid); - ret = app2sd_usr_on_demand_setup_exit(pkgid, uid); - if (ret) { - _E("error(%d)", ret); - break; - } - } - if (pkgid) { - free(pkgid); - pkgid = NULL; - } - } - - if (pkgid) { - free(pkgid); - pkgid = NULL; - } - closedir(dir); + ret = _app2sd_get_foreach_info_from_db((app2sd_info_cb)_app2sd_info_cb_func); + if (ret) + _E("disable full pkg error(%d)", ret); return ret; } diff --git a/plugin/app2sd/src/app2sd_internals.c b/plugin/app2sd/src/app2sd_internals.c index 58f6f67..9b336cc 100644 --- a/plugin/app2sd/src/app2sd_internals.c +++ b/plugin/app2sd/src/app2sd_internals.c @@ -789,24 +789,21 @@ int _app2sd_mount_app_content(const char *application_path, const char *pkgid, break; } - if (cmd == APP2SD_PRE_UNINSTALL || cmd == APP2SD_MOVE_APP_TO_PHONE || - cmd == APP2SD_PRE_UPGRADE) { - /* delete lost+found dir */ - snprintf(temp_path, FILENAME_MAX - 1, "%s/lost+found", - application_mmc_path); - ret = _app2sd_delete_directory(temp_path); - if (ret) { - _E("unable to delete (%s)", temp_path); - return APP2EXT_ERROR_DELETE_DIRECTORY; - } - } - if (cmd == APP2SD_PRE_INSTALL || cmd == APP2SD_MOVE_APP_TO_MMC || cmd == APP2SD_PRE_UPGRADE) { ret = _app2sd_create_directory_entry(application_path, pkgid, dir_list, uid); } + /* change lost+found permission */ + snprintf(temp_path, FILENAME_MAX - 1, "%s/lost+found", + application_mmc_path); + ret = _app2sd_make_directory(temp_path, uid); + if (ret) { + _E("create directory(%s) failed", temp_path); + return APP2EXT_ERROR_CREATE_DIRECTORY; + } + return ret; } @@ -910,6 +907,15 @@ int _app2sd_move_app_to_external(const char *pkgid, GList *dir_list, uid_t uid) snprintf(application_archive_path, FILENAME_MAX - 1, "%s/.archive", application_path); + ret = mkdir(application_mmc_path, mode); + if (ret) { + if (errno != EEXIST) { + _E("unable to create directory for archiving," \ + " error(%d)", errno); + return APP2EXT_ERROR_CREATE_DIRECTORY; + } + } + ret = mkdir(application_archive_path, mode); if (ret) { if (errno != EEXIST) { diff --git a/plugin/app2sd/src/app2sd_internals_registry.c b/plugin/app2sd/src/app2sd_internals_registry.c index 14e1c02..c235889 100644 --- a/plugin/app2sd/src/app2sd_internals_registry.c +++ b/plugin/app2sd/src/app2sd_internals_registry.c @@ -236,6 +236,48 @@ FINISH_OFF: return ret; } +int _app2sd_get_foreach_info_from_db(app2sd_info_cb cb_func) +{ + char *query = NULL; + sqlite3_stmt *stmt = NULL; + const char *pkgid = NULL; + int uid = 0; + int ret = 0; + + query = sqlite3_mprintf("select * from app2sd_info"); + if (query == NULL) { + _E("failed to make a query"); + return APP2EXT_ERROR_SQLITE_REGISTRY; + } + + ret = sqlite3_prepare_v2(app2sd_db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + _E("prepare failed (%s)", sqlite3_errmsg(app2sd_db)); + sqlite3_free(query); + return APP2EXT_ERROR_SQLITE_REGISTRY; + } + + ret = APP2EXT_SUCCESS; + while (sqlite3_step(stmt) == SQLITE_ROW) { + pkgid = (const char *)sqlite3_column_text(stmt, 0); + uid = sqlite3_column_int(stmt, 3); + + ret = cb_func(pkgid, (uid_t)uid); + if (ret) { + _E("app2sd info callback error"); + break; + } + } + + if (SQLITE_OK != sqlite3_finalize(stmt)) { + _E("error : sqlite3_finalize"); + ret = APP2EXT_ERROR_SQLITE_REGISTRY; + } + sqlite3_free(query); + + return ret; +} + char *_app2sd_get_password_from_db(const char *pkgid, uid_t uid) { char *query = NULL; diff --git a/src/app2ext_interface.c b/src/app2ext_interface.c index e16289a..4776f87 100644 --- a/src/app2ext_interface.c +++ b/src/app2ext_interface.c @@ -105,6 +105,9 @@ int app2ext_deinit(app2ext_handle *handle) return 0; } +/* use this api only to check external related file existing, + * such as .mmc directory and image file under /sdcard/app2sd. + */ int app2ext_usr_get_app_location(const char *pkgid, uid_t uid) { FILE *fp = NULL; -- 2.7.4