From 9a5b648ce367d93407bed4890c27c94eff88f2b4 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Mon, 10 Sep 2018 17:17:37 +0900 Subject: [PATCH] Add checking processes which hold db lock Change-Id: I0ffbbfa83c57c127fd3c447a4270ab5ce58a6b5b Signed-off-by: Sangyoon Jang --- parser/src/pkgmgr_parser_db.c | 54 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/parser/src/pkgmgr_parser_db.c b/parser/src/pkgmgr_parser_db.c index 4346cc2..93d2e1a 100644 --- a/parser/src/pkgmgr_parser_db.c +++ b/parser/src/pkgmgr_parser_db.c @@ -460,6 +460,57 @@ API int pkgmgr_parser_create_and_initialize_db(uid_t uid) return PM_PARSER_R_OK; } +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); + } + + fclose(fp); +} + #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) @@ -469,6 +520,7 @@ static int __db_busy_handler(void *data, int count) return 1; } else { /* sqlite3_prepare_v2 will return SQLITE_BUSY */ + __check_db_lock((const char *)data); return 0; } } @@ -487,7 +539,7 @@ static int __open_db(uid_t uid, const char *path, sqlite3 **db, int flags) 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)); -- 2.7.4