summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-07-27 16:04:34 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-07-27 16:04:34 +0100
commitaad1e3622aeea65651a7c58ce78a75603506b9c8 (patch)
tree0258f443d6978518a08c6607e7dfe51f1a4c417f
parentf7f82c92b2fe906f3fb6337a54ffb04165e18350 (diff)
downloadrspamd-aad1e3622aeea65651a7c58ce78a75603506b9c8.tar.gz
rspamd-aad1e3622aeea65651a7c58ce78a75603506b9c8.zip
Try to fix reindexing of statfiles.
-rw-r--r--src/libstat/backends/mmaped_file.c63
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;