diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-02-21 11:43:51 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-02-21 11:43:51 +0000 |
commit | 742feb0c89cb6d0cb0d61612ade2cca00c3dc362 (patch) | |
tree | 95f6c1156e33a7728c942ff85317a00ef6939e93 | |
parent | 8ab5dd791fd53b7d88182cf264bc68221f814e89 (diff) | |
download | rspamd-742feb0c89cb6d0cb0d61612ade2cca00c3dc362.tar.gz rspamd-742feb0c89cb6d0cb0d61612ade2cca00c3dc362.zip |
[Minor] Do a more clever sqlite locking
-rw-r--r-- | src/libutil/sqlite_utils.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/libutil/sqlite_utils.c b/src/libutil/sqlite_utils.c index 7da003fa5..d4c5e9e20 100644 --- a/src/libutil/sqlite_utils.c +++ b/src/libutil/sqlite_utils.c @@ -207,6 +207,8 @@ static gboolean rspamd_sqlite3_wait (rspamd_mempool_t *pool, const gchar *lock) { gint fd; + pid_t pid; + gssize r; struct timespec sleep_ts = { .tv_sec = 0, .tv_nsec = 1000000 @@ -219,6 +221,46 @@ rspamd_sqlite3_wait (rspamd_mempool_t *pool, const gchar *lock) return FALSE; } + + fd = open (lock, O_RDONLY); + + if (fd == -1) { + msg_err_pool_check ("cannot open lock file %s: %s", lock, + strerror (errno)); + + return FALSE; + } + + r = read (fd, &pid, sizeof (pid)); + + if (r != sizeof (pid)) { + msg_warn_pool_check ("stale lock file %s, removing", lock); + unlink (lock); + close (fd); + + return TRUE; + } + + /* Now check for process existence */ + if (pid == getpid ()) { + msg_warn_pool_check ("lock file %s, belongs to me, removing", lock); + unlink (lock); + close (fd); + + return TRUE; + } + else if (kill (pid, 0) == -1) { + if (errno == ESRCH) { + /* Process is already dead */ + msg_warn_pool_check ("stale lock file %s from pid: %P, removing", + lock, pid); + unlink (lock); + close (fd); + + return TRUE; + } + } + if (nanosleep (&sleep_ts, NULL) == -1 && errno != EINTR) { msg_err_pool_check ("cannot sleep open lock file %s: %s", lock, strerror (errno)); @@ -308,7 +350,9 @@ rspamd_sqlite3_open_or_create (rspamd_mempool_t *pool, const gchar *path, const has_lock = FALSE; } else { + pid_t myself = getpid (); msg_debug_pool_check ("locking %s to block other processes", lock_path); + (void)write (lock_fd, &myself, sizeof (myself)); g_assert (rspamd_file_lock (lock_fd, FALSE)); has_lock = TRUE; |