dovecot-2.0: virtual: If another session adds a new mailbox to i...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Jul 27 02:51:55 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/1858d2fe330b
changeset: 9666:1858d2fe330b
user: Timo Sirainen <tss at iki.fi>
date: Sun Jul 26 19:51:37 2009 -0400
description:
virtual: If another session adds a new mailbox to index, handle it without crashing.
For now we'll just disconnect the session.
diffstat:
3 files changed, 60 insertions(+), 16 deletions(-)
src/plugins/virtual/virtual-storage.c | 12 +++++-
src/plugins/virtual/virtual-storage.h | 1
src/plugins/virtual/virtual-sync.c | 63 +++++++++++++++++++++++++--------
diffs (208 lines):
diff -r 3816c5011c53 -r 1858d2fe330b src/plugins/virtual/virtual-storage.c
--- a/src/plugins/virtual/virtual-storage.c Sun Jul 26 19:39:35 2009 -0400
+++ b/src/plugins/virtual/virtual-storage.c Sun Jul 26 19:51:37 2009 -0400
@@ -530,6 +530,16 @@ virtual_get_virtual_box_patterns(struct
array_append_array(includes, &mbox->list_include_patterns);
array_append_array(excludes, &mbox->list_exclude_patterns);
+}
+
+static bool virtual_is_inconsistent(struct mailbox *box)
+{
+ struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
+
+ if (mbox->inconsistent)
+ return TRUE;
+
+ return index_storage_is_inconsistent(box);
}
static void virtual_class_init(void)
@@ -626,6 +636,6 @@ struct mailbox virtual_mailbox = {
virtual_save_finish,
virtual_save_cancel,
mail_storage_copy,
- index_storage_is_inconsistent
+ virtual_is_inconsistent
}
};
diff -r 3816c5011c53 -r 1858d2fe330b src/plugins/virtual/virtual-storage.h
--- a/src/plugins/virtual/virtual-storage.h Sun Jul 26 19:39:35 2009 -0400
+++ b/src/plugins/virtual/virtual-storage.h Sun Jul 26 19:51:37 2009 -0400
@@ -123,6 +123,7 @@ struct virtual_mailbox {
unsigned int uids_mapped:1;
unsigned int sync_initialized:1;
+ unsigned int inconsistent:1;
};
extern MODULE_CONTEXT_DEFINE(virtual_storage_module,
diff -r 3816c5011c53 -r 1858d2fe330b src/plugins/virtual/virtual-sync.c
--- a/src/plugins/virtual/virtual-sync.c Sun Jul 26 19:39:35 2009 -0400
+++ b/src/plugins/virtual/virtual-sync.c Sun Jul 26 19:51:37 2009 -0400
@@ -129,7 +129,24 @@ static int bbox_mailbox_id_cmp(struct vi
return 0;
}
-static bool virtual_sync_ext_header_read(struct virtual_sync_context *ctx)
+static int
+virtual_sync_get_backend_box(struct virtual_sync_context *ctx, const char *name,
+ struct virtual_backend_box **bbox_r)
+{
+ *bbox_r = virtual_backend_box_lookup_name(ctx->mbox, name);
+ if (*bbox_r != NULL || !ctx->mbox->sync_initialized)
+ return 0;
+
+ /* another process just added a new mailbox.
+ we can't handle this currently. */
+ ctx->mbox->inconsistent = TRUE;
+ mail_storage_set_error(ctx->mbox->ibox.box.storage, MAIL_ERROR_TEMP,
+ "Backend mailbox added by another session. "
+ "Reopen the virtual mailbox.");
+ return -1;
+}
+
+static int virtual_sync_ext_header_read(struct virtual_sync_context *ctx)
{
const struct virtual_mail_index_header *ext_hdr;
const struct mail_index_header *hdr;
@@ -139,7 +156,7 @@ static bool virtual_sync_ext_header_read
size_t ext_size;
unsigned int i, count, ext_name_offset, ext_mailbox_count;
uint32_t prev_mailbox_id;
- bool ret = TRUE;
+ int ret = 1;
hdr = mail_index_get_header(ctx->sync_view);
mail_index_get_header_ext(ctx->sync_view, ctx->mbox->virtual_ext_id,
@@ -153,7 +170,6 @@ static bool virtual_sync_ext_header_read
return TRUE;
}
- ctx->mbox->sync_initialized = TRUE;
ctx->mbox->prev_uid_validity = hdr->uid_validity;
if (ext_hdr == NULL ||
ctx->mbox->search_args_crc32 != ext_hdr->search_args_crc32) {
@@ -171,7 +187,7 @@ static bool virtual_sync_ext_header_read
ctx->mbox->ibox.box.path);
ctx->index_broken = TRUE;
ext_mailbox_count = 0;
- ret = FALSE;
+ ret = 0;
} else {
ext_mailbox_count = ext_hdr->mailbox_count;
}
@@ -203,11 +219,15 @@ static bool virtual_sync_ext_header_read
nameptr = CONST_PTR_OFFSET(ext_data, ext_name_offset);
name = t_strndup(nameptr, mailboxes[i].name_len);
- bbox = virtual_backend_box_lookup_name(ctx->mbox, name);
+ if (virtual_sync_get_backend_box(ctx, name, &bbox) < 0)
+ ret = -1;
} T_END;
+
if (bbox == NULL) {
- /* mailbox no longer exists */
- ret = FALSE;
+ if (ret < 0)
+ return -1;
+ /* mailbox no longer exists. */
+ ret = 0;
} else {
bbox->mailbox_id = mailboxes[i].id;
bbox->sync_uid_validity = mailboxes[i].uid_validity;
@@ -220,17 +240,18 @@ static bool virtual_sync_ext_header_read
}
if (i < ext_mailbox_count) {
ctx->index_broken = TRUE;
- ret = FALSE;
+ ret = 0;
}
ctx->mbox->highest_mailbox_id = ext_hdr == NULL ? 0 :
ext_hdr->highest_mailbox_id;
+ ctx->mbox->sync_initialized = TRUE;
/* assign new mailbox IDs if any are missing */
bboxes = array_get_modifiable(&ctx->mbox->backend_boxes, &count);
for (i = 0; i < count; i++) {
if (bboxes[i]->mailbox_id == 0) {
bboxes[i]->mailbox_id = ++ctx->mbox->highest_mailbox_id;
- ret = FALSE;
+ ret = 0;
}
}
/* sort the backend mailboxes by mailbox_id. */
@@ -1251,7 +1272,7 @@ static void virtual_sync_backend_add_new
ctx->mbox->sync_virtual_next_uid = first_uid + i;
}
-static void
+static int
virtual_sync_apply_existing_appends(struct virtual_sync_context *ctx)
{
uint32_t virtual_ext_id = ctx->mbox->virtual_ext_id;
@@ -1264,18 +1285,18 @@ virtual_sync_apply_existing_appends(stru
uint32_t seq, seq2;
if (!ctx->mbox->uids_mapped)
- return;
+ return 0;
hdr = mail_index_get_header(ctx->sync_view);
if (ctx->mbox->sync_virtual_next_uid >= hdr->next_uid)
- return;
+ return 0;
/* another process added messages to virtual index. get backend boxes'
uid lists up-to-date by adding the new messages there. */
if (!mail_index_lookup_seq_range(ctx->sync_view,
ctx->mbox->sync_virtual_next_uid,
(uint32_t)-1, &seq, &seq2))
- return;
+ return 0;
memset(&uidmap, 0, sizeof(uidmap));
for (; seq <= seq2; seq++) {
@@ -1288,12 +1309,20 @@ virtual_sync_apply_existing_appends(stru
if (bbox == NULL || bbox->mailbox_id != vrec->mailbox_id) {
bbox = virtual_backend_box_lookup(ctx->mbox,
vrec->mailbox_id);
+ if (bbox == NULL) {
+ mail_storage_set_critical(
+ ctx->mbox->ibox.box.storage,
+ "Mailbox ID %u unexpectedly lost",
+ vrec->mailbox_id);
+ return -1;
+ }
}
array_append(&bbox->uids, &uidmap, 1);
bbox->uids_nonsorted = TRUE;
}
virtual_sync_backend_boxes_sort_uids(ctx->mbox);
+ return 0;
}
static void
@@ -1335,7 +1364,8 @@ static int virtual_sync_backend_boxes(st
struct virtual_backend_box *const *bboxes;
unsigned int i, count;
- virtual_sync_apply_existing_appends(ctx);
+ if (virtual_sync_apply_existing_appends(ctx) < 0)
+ return -1;
i_array_init(&ctx->all_adds, 128);
bboxes = array_get(&ctx->mbox->backend_boxes, &count);
@@ -1428,7 +1458,10 @@ static int virtual_sync(struct virtual_m
return ret;
}
- if (!virtual_sync_ext_header_read(ctx))
+ ret = virtual_sync_ext_header_read(ctx);
+ if (ret < 0)
+ return virtual_sync_finish(ctx, FALSE);
+ if (ret == 0)
ctx->ext_header_rewrite = TRUE;
/* apply changes from virtual index to backend mailboxes */
virtual_sync_index_changes(ctx);
More information about the dovecot-cvs
mailing list