diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-07-27 16:04:34 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-07-27 16:04:34 +0100 |
commit | aad1e3622aeea65651a7c58ce78a75603506b9c8 (patch) | |
tree | 0258f443d6978518a08c6607e7dfe51f1a4c417f | |
parent | f7f82c92b2fe906f3fb6337a54ffb04165e18350 (diff) | |
download | rspamd-aad1e3622aeea65651a7c58ce78a75603506b9c8.tar.gz rspamd-aad1e3622aeea65651a7c58ce78a75603506b9c8.zip |
Try to fix reindexing of statfiles.
-rw-r--r-- | src/libstat/backends/mmaped_file.c | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/src/libstat/backends/mmaped_file.c b/src/libstat/backends/mmaped_file.c index bbd106187..341a6140b 100644 --- a/src/libstat/backends/mmaped_file.c +++ b/src/libstat/backends/mmaped_file.c @@ -428,12 +428,12 @@ rspamd_mmaped_file_reindex (rspamd_mmaped_file_ctx * pool, size_t size, struct rspamd_statfile_config *stcf) { - gchar *backup; - gint fd; + gchar *backup, *lock; + gint fd, lock_fd; rspamd_mmaped_file_t *new; u_char *map, *pos; struct stat_file_block *block; - struct stat_file_header *header; + struct stat_file_header *header, *nh; if (size < sizeof (struct stat_file_header) + sizeof (struct stat_file_section) + @@ -444,11 +444,43 @@ rspamd_mmaped_file_reindex (rspamd_mmaped_file_ctx * pool, return NULL; } + lock = g_strconcat (filename, ".lock", NULL); + lock_fd = open (lock, O_WRONLY|O_CREAT|O_EXCL, 00600); + + if (lock_fd == -1) { + /* Wait for lock */ + lock_fd = open (lock, O_RDONLY, 00600); + if (lock_fd != -1) { + if (!rspamd_file_lock (lock_fd, FALSE)) { + g_free (lock); + + return rspamd_mmaped_file_open (pool, filename, size, stcf); + } + } + else { + return rspamd_mmaped_file_open (pool, filename, size, stcf); + } + } + + if (!rspamd_file_lock (lock_fd, FALSE)) { + close (lock_fd); + unlink (lock); + g_free (lock); + + return rspamd_mmaped_file_open (pool, filename, size, stcf); + } + + backup = g_strconcat (filename, ".old", NULL); if (rename (filename, backup) == -1) { msg_err ("cannot rename %s to %s: %s", filename, backup, strerror ( errno)); g_free (backup); + unlink (lock); + g_free (lock); + rspamd_file_unlock (lock_fd, FALSE); + close (lock_fd); + return NULL; } @@ -456,6 +488,11 @@ rspamd_mmaped_file_reindex (rspamd_mmaped_file_ctx * pool, if (rspamd_mmaped_file_create (pool, filename, size, stcf, pool->pool) != 0) { msg_err ("cannot create new file"); g_free (backup); + unlink (lock); + g_free (lock); + rspamd_file_unlock (lock_fd, FALSE); + close (lock_fd); + return NULL; } /* Now open new file and start copying */ @@ -468,15 +505,25 @@ rspamd_mmaped_file_reindex (rspamd_mmaped_file_ctx * pool, } msg_err ("cannot open file: %s", strerror (errno)); + unlink (lock); + g_free (lock); + rspamd_file_unlock (lock_fd, FALSE); + close (lock_fd); g_free (backup); return NULL; } + + /* Now start reading blocks from old statfile */ if ((map = mmap (NULL, old_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { msg_err ("cannot mmap file: %s", strerror (errno)); close (fd); + unlink (lock); + g_free (lock); + rspamd_file_unlock (lock_fd, FALSE); + close (lock_fd); g_free (backup); return NULL; } @@ -496,11 +543,21 @@ rspamd_mmaped_file_reindex (rspamd_mmaped_file_ctx * pool, header = (struct stat_file_header *)map; rspamd_mmaped_file_set_revision (new, header->revision, header->rev_time); + nh = new->map; + /* Copy tokenizer configuration */ + memcpy (nh->unused, header->unused, sizeof (header->unused)); + nh->tokenizer_conf_len = header->tokenizer_conf_len; munmap (map, old_size); close (fd); unlink (backup); g_free (backup); + unlink (lock); + g_free (lock); + rspamd_file_unlock (lock_fd, FALSE); + close (lock_fd); + + rspamd_file_unlock (new->fd, FALSE); return new; |