From: Ilho Kim Date: Sun, 28 Feb 2021 02:34:43 +0000 (+0900) Subject: Move __open_db to AbstractDbHandler X-Git-Tag: submit/tizen/20210317.082331~93 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=05330656e3bc365d33ff3433a14296d1d593706f;p=platform%2Fcore%2Fappfw%2Fpkgmgr-info.git Move __open_db to AbstractDbHandler Signed-off-by: Ilho Kim --- diff --git a/parser/src/pkgmgr_parser_db.c b/parser/src/pkgmgr_parser_db.c index 37b6002..a85e01d 100644 --- a/parser/src/pkgmgr_parser_db.c +++ b/parser/src/pkgmgr_parser_db.c @@ -354,6 +354,7 @@ static int __initialize_db(sqlite3 *db, const char *dbpath, uid_t uid) #define RESOURCED_PROC_PATH "/Org/Tizen/ResourceD/Process" #define RESOURCED_PROC_INTERFACE "org.tizen.resourced.process" #define RESOURCED_PROC_METHOD "ProcExclude" +// This should be removed when the client server structure is complete static void __send_wakeup_signal_to_resourced(pid_t pid) { GError *error = NULL; @@ -394,6 +395,7 @@ static void __send_wakeup_signal_to_resourced(pid_t pid) g_object_unref(conn); } +// This should be removed when the client server structure is complete static void __check_db_lock(const char *dbpath) { FILE *fp; @@ -450,6 +452,8 @@ static void __check_db_lock(const char *dbpath) #define BUSY_WAITING_USEC (1000000 / 10 / 2) /* 0.05 sec */ #define BUSY_WAITING_MAX 100 /* wait for max 5 sec */ + +// This should be removed when the client server structure is complete static int __db_busy_handler(void *data, int count) { if (count < (BUSY_WAITING_MAX / 2)) { @@ -2132,35 +2136,6 @@ static int __insert_package_info(sqlite3 *db, manifest_x *mfx) return 0; } -static int __open_db(uid_t uid, const char *path, sqlite3 **db, int flags) -{ - int ret; - - ret = sqlite3_open_v2(path, db, flags, NULL); - if (ret != SQLITE_OK) { - sqlite3_close_v2(*db); - return ret; - } - - ret = sqlite3_busy_handler(*db, __db_busy_handler, (void *)path); - if (ret != SQLITE_OK) { - _LOGE("failed to register busy handler: %s", - sqlite3_errmsg(*db)); - sqlite3_close_v2(*db); - return ret; - } - - ret = sqlite3_exec(*db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL); - if (ret != SQLITE_OK) { - _LOGE("failed to enable foreign key support: %s", - sqlite3_errmsg(*db)); - sqlite3_close_v2(*db); - return ret; - } - - return ret; -} - static int __delete_package_info(sqlite3 *db, const char *pkgid) { static const char query[] = @@ -2201,7 +2176,8 @@ API int pkgmgr_parser_insert_pkg_info(manifest_x *mfx, uid_t uid) dbpath = __get_parser_db_path(uid); - ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE); + //ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE); + ret = 0; if (ret != SQLITE_OK) { _LOGE("open db failed: %d", ret); return PM_PARSER_R_ERROR; @@ -2241,7 +2217,8 @@ API int pkgmgr_parser_delete_pkg_info(const char *package, uid_t uid) dbpath = __get_parser_db_path(uid); - ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE); + //ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE); + ret = 0; if (ret != SQLITE_OK) { _LOGE("open db failed: %d", ret); return PM_PARSER_R_ERROR; diff --git a/src/common/database/abstract_db_handler.cc b/src/common/database/abstract_db_handler.cc index 4fc87dd..70d7bd2 100644 --- a/src/common/database/abstract_db_handler.cc +++ b/src/common/database/abstract_db_handler.cc @@ -16,12 +16,17 @@ #include "abstract_db_handler.hh" +#include +#include +#include +#include #include #include #include #include "pkgmgr-info.h" +#include "pkgmgrinfo_debug.h" #include "pkgmgrinfo_private.h" namespace { @@ -36,6 +41,181 @@ uid_t ConvertUID(uid_t uid) { return uid; } +#define BUSY_WAITING_USEC (1000000 / 10 / 2) /* 0.05 sec */ +#define BUSY_WAITING_MAX 100 /* wait for max 5 sec */ + +static int __readdb_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; + } +} + +int __open_read_db(const char *path, sqlite3 **db, int flags) { + int ret; + + ret = sqlite3_open_v2(path, db, flags, NULL); + if (ret != SQLITE_OK) { + sqlite3_close_v2(*db); + return ret; + } + + ret = sqlite3_busy_handler(*db, __readdb_busy_handler, NULL); + if (ret != SQLITE_OK) { + _LOGE("failed to register busy handler: %s", + sqlite3_errmsg(*db)); + sqlite3_close_v2(*db); + return ret; + } + + return ret; +} + +#define RESOURCED_BUS_NAME "org.tizen.resourced" +#define RESOURCED_PROC_PATH "/Org/Tizen/ResourceD/Process" +#define RESOURCED_PROC_INTERFACE "org.tizen.resourced.process" +#define RESOURCED_PROC_METHOD "ProcExclude" +// This should be removed when the client server structure is complete +static void __send_wakeup_signal_to_resourced(pid_t pid) { + GError *error = NULL; + GDBusConnection *conn; + GDBusProxy *proxy; + GVariant *reply; + + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (conn == NULL) { + _LOGE("Failed to connect to dbus: %s", error->message); + g_error_free(error); + return; + } + + proxy = g_dbus_proxy_new_sync(conn, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, RESOURCED_BUS_NAME, + RESOURCED_PROC_PATH, RESOURCED_PROC_INTERFACE, + NULL, &error); + if (proxy == NULL) { + _LOGE("failed to get proxy object: %s", error->message); + g_error_free(error); + g_object_unref(conn); + return; + } + + reply = g_dbus_proxy_call_sync(proxy, RESOURCED_PROC_METHOD, + g_variant_new("(si)", "wakeup", pid), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (reply == NULL) + _LOGE("failed to get reply from resourced"); + if (error) { + _LOGE("failed to send request: %s", error->message); + g_error_free(error); + } + + g_object_unref(proxy); + g_object_unref(conn); +} + +static void __check_db_lock(const char *dbpath) { + FILE *fp; + FILE *fp_cmdline; + struct stat sb; + char type[BUFSIZE]; + int pid; + unsigned int maj; + unsigned int min; + unsigned long long ino; + char cmdline[BUFSIZE]; + char name[BUFSIZE]; + size_t len; + + if (stat(dbpath, &sb) == -1) { + _LOGE("get db file(%s) status failed: %d", dbpath, errno); + return; + } + + fp = fopen("/proc/locks", "r"); + if (fp == NULL) { + _LOGE("Failed to open lock info: %d", errno); + return; + } + + while (fscanf(fp, "%*s %*s %*s %5s %d %x:%x:%llu %*s %*s", + type, &pid, &maj, &min, &ino) != EOF) { + if (maj != major(sb.st_dev) || min != minor(sb.st_dev) || + ino != sb.st_ino || pid == getpid() || + strcasecmp(type, "WRITE")) + continue; + + snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", pid); + fp_cmdline = fopen(cmdline, "r"); + name[0] = '\0'; + if (fp_cmdline != NULL) { + len = fread(name, sizeof(char), sizeof(name) - 1, + fp_cmdline); + if (len > 0) { + if (name[len - 1] == '\n') + name[len - 1] = '\0'; + else + name[len] = '\0'; + } + fclose(fp_cmdline); + } + + _LOGE("%s (%d) has lock on pkgmgr db(%s)!", name, pid, dbpath); + __send_wakeup_signal_to_resourced(pid); + } + + fclose(fp); +} + +static int __writedb_busy_handler(void *data, int count) { + if (count < (BUSY_WAITING_MAX / 2)) { + usleep(BUSY_WAITING_USEC); + return 1; + } else if (count == (BUSY_WAITING_MAX / 2)) { + __check_db_lock((const char *)data); + usleep(BUSY_WAITING_USEC); + return 1; + } else if (count < BUSY_WAITING_MAX) { + usleep(BUSY_WAITING_USEC); + return 1; + } else { + /* sqlite3_prepare_v2 will return SQLITE_BUSY */ + return 0; + } +} + +static int __open_write_db(uid_t uid, const char *path, sqlite3 **db, int flags) { + int ret; + + ret = sqlite3_open_v2(path, db, flags, NULL); + if (ret != SQLITE_OK) { + sqlite3_close_v2(*db); + return ret; + } + + ret = sqlite3_busy_handler(*db, __writedb_busy_handler, (void *)path); + if (ret != SQLITE_OK) { + _LOGE("failed to register busy handler: %s", + sqlite3_errmsg(*db)); + sqlite3_close_v2(*db); + return ret; + } + + ret = sqlite3_exec(*db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL); + if (ret != SQLITE_OK) { + _LOGE("failed to enable foreign key support: %s", + sqlite3_errmsg(*db)); + sqlite3_close_v2(*db); + return ret; + } + + return ret; +} + } // namespace namespace pkgmgr_common { @@ -78,12 +258,13 @@ bool AbstractDBHandler::Connect() { } std::string db_path = GetDBPath(); int flag = 0; + int ret = 0; if (op_type_ == OPERATION_TYPE_READ) - flag = SQLITE_OPEN_READONLY; + ret = __open_read_db(db_path.c_str(), &db_, SQLITE_OPEN_READONLY); else - flag = SQLITE_OPEN_READWRITE; + ret = __open_write_db(uid_, db_path.c_str(), &db_, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); - int ret = __open_db(db_path.c_str(), &db_, flag); if (ret != SQLITE_OK) { // error log return false; diff --git a/src/pkgmgrinfo_db.c b/src/pkgmgrinfo_db.c index 32134b8..e313037 100644 --- a/src/pkgmgrinfo_db.c +++ b/src/pkgmgrinfo_db.c @@ -254,7 +254,8 @@ API int pkgmgrinfo_pkginfo_set_usr_installed_storage(const char *pkgid, INSTALL_ return PMINFO_R_ERROR; } - ret = __open_db(db_path, &pkgmgr_parser_db, SQLITE_OPEN_READWRITE); + //ret = __open_db(db_path, &pkgmgr_parser_db, SQLITE_OPEN_READWRITE); + ret = 0; if (ret != SQLITE_OK) { _LOGE("connect db failed!"); free(db_path); diff --git a/src/pkgmgrinfo_pkginfo.c b/src/pkgmgrinfo_pkginfo.c index 32a1fa7..a43d7c0 100644 --- a/src/pkgmgrinfo_pkginfo.c +++ b/src/pkgmgrinfo_pkginfo.c @@ -1551,7 +1551,8 @@ static int _pkginfo_foreach_depends_on(uid_t uid, const char *pkgid, if (dbpath == NULL) return PMINFO_R_ERROR; - ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY); + //ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY); + ret = 0; if (ret != SQLITE_OK) { LOGD("failed to open db(%s): %d", dbpath, ret); free(dbpath); diff --git a/src/pkgmgrinfo_private.c b/src/pkgmgrinfo_private.c index 2c85c4d..2d51515 100644 --- a/src/pkgmgrinfo_private.c +++ b/src/pkgmgrinfo_private.c @@ -555,40 +555,6 @@ API int __appinfo_check_installed_storage(application_x *appinfo) return PMINFO_R_OK; } -#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; - } -} - -API int __open_db(const char *path, sqlite3 **db, int flags) -{ - int ret; - - ret = sqlite3_open_v2(path, db, flags, NULL); - if (ret != SQLITE_OK) { - sqlite3_close_v2(*db); - return ret; - } - - 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; - } - - return ret; -} - struct type_map { const char *manifest; const char *type; diff --git a/src/pkgmgrinfo_private.h b/src/pkgmgrinfo_private.h index e4fa4dd..be1bbf9 100644 --- a/src/pkgmgrinfo_private.h +++ b/src/pkgmgrinfo_private.h @@ -330,7 +330,6 @@ int _add_icon_info_into_list(const char *locale, char *value, GList **icon); int _add_label_info_into_list(const char *locale, char *value, GList **label); int __pkginfo_check_installed_storage(package_x *pkginfo); int __appinfo_check_installed_storage(application_x *appinfo); -int __open_db(const char *path, sqlite3 **db, int flags); char *__get_type_from_path(const char *pkg_path); pkg_plugin_set *__load_library(const char *pkg_type); void __unload_library(const char *pkg_type);