Move __open_db to AbstractDbHandler
authorIlho Kim <ilho159.kim@samsung.com>
Sun, 28 Feb 2021 02:34:43 +0000 (11:34 +0900)
committer김일호/Tizen Platform Lab(SR)/Engineer/삼성전자 <ilho159.kim@samsung.com>
Wed, 3 Mar 2021 10:27:40 +0000 (19:27 +0900)
Signed-off-by: Ilho Kim <ilho159.kim@samsung.com>
parser/src/pkgmgr_parser_db.c
src/common/database/abstract_db_handler.cc
src/pkgmgrinfo_db.c
src/pkgmgrinfo_pkginfo.c
src/pkgmgrinfo_private.c
src/pkgmgrinfo_private.h

index 37b6002..a85e01d 100644 (file)
@@ -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;
index 4fc87dd..70d7bd2 100644 (file)
 
 #include "abstract_db_handler.hh"
 
+#include <gio/gio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/sysmacros.h>
 #include <stdlib.h>
 #include <tzplatform_config.h>
 
 #include <string>
 
 #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;
index 32134b8..e313037 100644 (file)
@@ -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);
index 32a1fa7..a43d7c0 100644 (file)
@@ -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);
index 2c85c4d..2d51515 100644 (file)
@@ -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;
index e4fa4dd..be1bbf9 100644 (file)
@@ -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);