#include <pwd.h>
#include <glib.h>
+#include <gio/gio.h>
#include <sqlite3.h>
#include <tzplatform_config.h>
#define __BEGIN_TRANSACTION(db) \
do { \
- if (sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL) != \
+ if (sqlite3_exec(db, "BEGIN DEFERRED", NULL, NULL, NULL) != \
SQLITE_OK) { \
_LOGE("begin transaction failed: %s", sqlite3_errmsg(db)); \
sqlite3_close_v2(db); \
QUERY_CREATE_TABLE_PACKAGE_APP_INFO_FOR_UID,
QUERY_CREATE_TRIGGER_UPDATE_PACKAGE_APP_INFO_FOR_UID,
QUERY_CREATE_TABLE_PACKAGE_APP_SPLASH_SCREEN,
+ QUERY_CREATE_TABLE_PACKAGE_DEPENDENCY_INFO,
NULL,
};
NULL
};
-static int __initialize_db(sqlite3 *db, const char *dbpath, uid_t uid)
+static int __create_tables(sqlite3 *db, const char **queries)
{
int ret;
- const char **queries;
int i;
+ for (i = 0; queries[i] != NULL; i++) {
+ ret = sqlite3_exec(db, queries[i], NULL, NULL, NULL);
+ if (ret != SQLITE_OK) {
+ _LOGE("exec failed: %s", sqlite3_errmsg(db));
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int __initialize_db(sqlite3 *db, const char *dbpath, uid_t uid)
+{
+ const char **queries;
if (__set_db_version(db))
return -1;
return -1;
}
- for (i = 0; queries[i] != NULL; i++) {
- ret = sqlite3_exec(db, queries[i], NULL, NULL, NULL);
- if (ret != SQLITE_OK) {
- _LOGE("exec failed: %s", sqlite3_errmsg(db));
- return -1;
- }
- }
+ __BEGIN_TRANSACTION(db);
+ __DO_TRANSACTION(db, __create_tables(db, queries));
+ __END_TRANSACTION(db);
if (__set_db_permission(dbpath, uid))
_LOGE("failed to set db permission");
return 0;
}
+#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"
+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;
+ int pid;
+ unsigned int maj;
+ unsigned int min;
+ ino_t 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 %*s %d %x:%x:%lu %*s %*s",
+ &pid, &maj, &min, &ino) != EOF) {
+ if (maj != major(sb.st_dev) || min != minor(sb.st_dev) ||
+ ino != sb.st_ino || pid == getpid())
+ 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);
+}
+
+#define BUSY_WAITING_USEC (1000000 / 10 / 2) /* 0.05 sec */
+#define BUSY_WAITING_MAX 40 /* wait for max 2 sec */
+static int __db_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;
+ }
+}
+
API int pkgmgr_parser_initialize_parser_db(uid_t uid)
{
int ret;
return PM_PARSER_R_ERROR;
}
+ 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;
+ }
+
if (__initialize_db(db, dbpath, uid)) {
sqlite3_close_v2(db);
return PM_PARSER_R_ERROR;
return PM_PARSER_R_ERROR;
}
+ 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;
+ }
+
if (__initialize_db(db, dbpath, GLOBAL_USER)) {
sqlite3_close_v2(db);
return PM_PARSER_R_ERROR;
if (pkgmgr_parser_initialize_parser_db(uid))
return PM_PARSER_R_ERROR;
- if (pkgmgr_parser_initialize_cert_db())
- return PM_PARSER_R_ERROR;
+ if (uid == OWNER_ROOT || uid == GLOBAL_USER)
+ if (pkgmgr_parser_initialize_cert_db())
+ return PM_PARSER_R_ERROR;
return PM_PARSER_R_OK;
}
-#define BUSY_WAITING_USEC (1000000 / 10 / 2) /* 0.05 sec */
-#define BUSY_WAITING_MAX 20 /* wait for max 1 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 int __open_db(uid_t uid, const char *path, sqlite3 **db, int flags)
{
int ret;
if (ret != SQLITE_OK)
return ret;
- ret = sqlite3_busy_handler(*db, __db_busy_handler, NULL);
+ ret = sqlite3_busy_handler(*db, __db_busy_handler, (void *)path);
if (ret != SQLITE_OK) {
_LOGE("failed to register busy handler: %s",
sqlite3_errmsg(*db));
static int __insert_appcontrol_info(sqlite3 *db, application_x *app)
{
static const char query[] =
- "INSERT INTO package_app_app_control (app_id, app_control) "
- "VALUES (?, ?)";
+ "INSERT INTO package_app_app_control (app_id, app_control,"
+ " visibility, app_control_id) "
+ "VALUES (?, ?, ?, ?)";
int ret;
sqlite3_stmt *stmt;
int idx;
ac->mime : "NULL") : "NULL");
__BIND_TEXT(db, stmt, idx++, app->appid);
__BIND_TEXT(db, stmt, idx++, app_control);
+ __BIND_TEXT(db, stmt, idx++, ac->visibility);
+ __BIND_TEXT(db, stmt, idx++, ac->id);
ret = sqlite3_step(stmt);
if (ret != SQLITE_DONE) {
return 0;
}
+static int __insert_package_dependency_info(sqlite3 *db, manifest_x *mfx)
+{
+ static const char query[] =
+ "INSERT INTO package_dependency_info"
+ " (package, depends_on, type, required_version) "
+ "VALUES (?, ?, ?, ?)";
+ int ret;
+ sqlite3_stmt *stmt;
+ int idx;
+ GList *tmp;
+ dependency_x *dep;
+
+ ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+ return -1;
+ }
+
+ for (tmp = mfx->dependencies; tmp; tmp = tmp->next) {
+ dep = (dependency_x *)tmp->data;
+ if (dep == NULL)
+ continue;
+
+ idx = 1;
+ __BIND_TEXT(db, stmt, idx++, mfx->package);
+ __BIND_TEXT(db, stmt, idx++, dep->depends_on);
+ __BIND_TEXT(db, stmt, idx++, dep->type);
+ __BIND_TEXT(db, stmt, idx++, dep->required_version);
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_DONE) {
+ _LOGE("step failed: %s", sqlite3_errmsg(db));
+ sqlite3_finalize(stmt);
+ return -1;
+ }
+ sqlite3_reset(stmt);
+ }
+
+ sqlite3_finalize(stmt);
+
+ return 0;
+}
+
/* _PRODUCT_LAUNCHING_ENHANCED_
* app->indicatordisplay, app->portraitimg, app->landscapeimg,
* app->guestmode_appstatus
return -1;
if (__insert_package_appdefined_privilege_info(db, mfx))
return -1;
+ if (__insert_package_dependency_info(db, mfx))
+ return -1;
return 0;
}