dovecot-2.0: dsync: Fixed syncing \noselect mailboxes.
dovecot at dovecot.org
dovecot at dovecot.org
Sat Jun 12 00:36:45 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/c955d4789553
changeset: 11524:c955d4789553
user: Timo Sirainen <tss at iki.fi>
date: Fri Jun 11 22:36:38 2010 +0100
description:
dsync: Fixed syncing \noselect mailboxes.
diffstat:
src/dsync/dsync-brain.c | 73 ++++++++++++++++++++++++++++++++++++-
src/dsync/dsync-data.c | 17 ++++++--
src/dsync/dsync-data.h | 8 ++--
src/dsync/dsync-proxy-client.c | 20 ++++++++++
src/dsync/dsync-proxy-server-cmd.c | 16 ++++++++
src/dsync/dsync-worker-local.c | 38 ++++++++++++++++---
src/dsync/dsync-worker-private.h | 2 +
src/dsync/dsync-worker.c | 8 ++++
src/dsync/dsync-worker.h | 3 +
src/dsync/test-dsync-worker.c | 15 +++++++
src/dsync/test-dsync-worker.h | 1 +
11 files changed, 185 insertions(+), 16 deletions(-)
diffs (truncated from 386 to 300 lines):
diff -r b135e13f42b2 -r c955d4789553 src/dsync/dsync-brain.c
--- a/src/dsync/dsync-brain.c Fri Jun 11 21:45:51 2010 +0100
+++ b/src/dsync/dsync-brain.c Fri Jun 11 22:36:38 2010 +0100
@@ -102,7 +102,7 @@
if (dsync_worker_mailbox_iter_deinit(&list->iter) < 0)
dsync_brain_fail(list->brain);
array_sort(&list->mailboxes, dsync_mailbox_p_guid_cmp);
- array_sort(&list->dirs, dsync_mailbox_p_name_cmp);
+ array_sort(&list->dirs, dsync_mailbox_p_name_sha1_cmp);
dsync_brain_mailbox_list_finished(list->brain);
}
}
@@ -313,6 +313,76 @@
}
}
+static void dsync_brain_sync_dirs(struct dsync_brain *brain)
+{
+ struct dsync_mailbox *const *src_boxes, *const *dest_boxes, new_box;
+ unsigned int src, dest, src_count, dest_count;
+ bool src_deleted, dest_deleted;
+ int ret;
+
+ memset(&new_box, 0, sizeof(new_box));
+
+ /* create/delete missing directories. */
+ src_boxes = array_get(&brain->src_mailbox_list->dirs, &src_count);
+ dest_boxes = array_get(&brain->dest_mailbox_list->dirs, &dest_count);
+ for (src = dest = 0; src < src_count && dest < dest_count; ) {
+ src_deleted = (src_boxes[src]->flags &
+ DSYNC_MAILBOX_FLAG_DELETED_DIR) != 0;
+ dest_deleted = (dest_boxes[dest]->flags &
+ DSYNC_MAILBOX_FLAG_DELETED_DIR) != 0;
+ ret = memcmp(src_boxes[src]->name_sha1.guid,
+ dest_boxes[dest]->name_sha1.guid,
+ sizeof(src_boxes[src]->name_sha1.guid));
+ if (ret < 0) {
+ /* exists only in source */
+ if (!src_deleted) {
+ new_box = *src_boxes[src];
+ dsync_worker_create_mailbox(brain->dest_worker,
+ &new_box);
+ }
+ src++;
+ } else if (ret > 0) {
+ /* exists only in dest */
+ if (!dest_deleted) {
+ new_box = *dest_boxes[dest];
+ dsync_worker_create_mailbox(brain->src_worker,
+ &new_box);
+ }
+ dest++;
+ } else if (src_deleted) {
+ /* delete from dest too */
+ if (!dest_deleted) {
+ dsync_worker_delete_dir(brain->dest_worker,
+ dest_boxes[dest]);
+ }
+ src++; dest++;
+ } else if (dest_deleted) {
+ /* delete from src too */
+ dsync_worker_delete_dir(brain->src_worker,
+ src_boxes[src]);
+ src++; dest++;
+ } else {
+ src++; dest++;
+ }
+ }
+ for (; src < src_count; src++) {
+ if ((src_boxes[src]->flags &
+ DSYNC_MAILBOX_FLAG_DELETED_DIR) != 0)
+ continue;
+
+ new_box = *src_boxes[src];
+ dsync_worker_create_mailbox(brain->dest_worker, &new_box);
+ }
+ for (; dest < dest_count; dest++) {
+ if ((dest_boxes[dest]->flags &
+ DSYNC_MAILBOX_FLAG_DELETED_DIR) != 0)
+ continue;
+
+ new_box = *dest_boxes[dest];
+ dsync_worker_create_mailbox(brain->src_worker, &new_box);
+ }
+}
+
static bool
dsync_brain_is_unsubscribed(struct dsync_brain_subs_list *list,
const struct dsync_worker_subscription *subs,
@@ -612,6 +682,7 @@
break;
case DSYNC_STATE_SYNC_MAILBOXES:
dsync_brain_sync_mailboxes(brain);
+ dsync_brain_sync_dirs(brain);
brain->state++;
/* fall through */
case DSYNC_STATE_SYNC_SUBSCRIPTIONS:
diff -r b135e13f42b2 -r c955d4789553 src/dsync/dsync-data.c
--- a/src/dsync/dsync-data.c Fri Jun 11 21:45:51 2010 +0100
+++ b/src/dsync/dsync-data.c Fri Jun 11 22:36:38 2010 +0100
@@ -62,16 +62,23 @@
return dsync_mailbox_guid_cmp(*box1, *box2);
}
-int dsync_mailbox_name_cmp(const struct dsync_mailbox *box1,
- const struct dsync_mailbox *box2)
+int dsync_mailbox_name_sha1_cmp(const struct dsync_mailbox *box1,
+ const struct dsync_mailbox *box2)
{
+ int ret;
+
+ ret = memcmp(box1->name_sha1.guid, box2->name_sha1.guid,
+ sizeof(box1->name_sha1.guid));
+ if (ret != 0)
+ return ret;
+
return strcmp(box1->name, box2->name);
}
-int dsync_mailbox_p_name_cmp(struct dsync_mailbox *const *box1,
- struct dsync_mailbox *const *box2)
+int dsync_mailbox_p_name_sha1_cmp(struct dsync_mailbox *const *box1,
+ struct dsync_mailbox *const *box2)
{
- return dsync_mailbox_name_cmp(*box1, *box2);
+ return dsync_mailbox_name_sha1_cmp(*box1, *box2);
}
bool dsync_keyword_list_equals(const char *const *k1, const char *const *k2)
diff -r b135e13f42b2 -r c955d4789553 src/dsync/dsync-data.h
--- a/src/dsync/dsync-data.h Fri Jun 11 21:45:51 2010 +0100
+++ b/src/dsync/dsync-data.h Fri Jun 11 22:36:38 2010 +0100
@@ -66,10 +66,10 @@
int dsync_mailbox_p_guid_cmp(struct dsync_mailbox *const *box1,
struct dsync_mailbox *const *box2);
-int dsync_mailbox_name_cmp(const struct dsync_mailbox *box1,
- const struct dsync_mailbox *box2);
-int dsync_mailbox_p_name_cmp(struct dsync_mailbox *const *box1,
- struct dsync_mailbox *const *box2);
+int dsync_mailbox_name_sha1_cmp(const struct dsync_mailbox *box1,
+ const struct dsync_mailbox *box2);
+int dsync_mailbox_p_name_sha1_cmp(struct dsync_mailbox *const *box1,
+ struct dsync_mailbox *const *box2);
bool dsync_keyword_list_equals(const char *const *k1, const char *const *k2);
diff -r b135e13f42b2 -r c955d4789553 src/dsync/dsync-proxy-client.c
--- a/src/dsync/dsync-proxy-client.c Fri Jun 11 21:45:51 2010 +0100
+++ b/src/dsync/dsync-proxy-client.c Fri Jun 11 22:36:38 2010 +0100
@@ -727,6 +727,25 @@
}
static void
+proxy_client_worker_delete_dir(struct dsync_worker *_worker,
+ const struct dsync_mailbox *dsync_box)
+{
+ struct proxy_client_dsync_worker *worker =
+ (struct proxy_client_dsync_worker *)_worker;
+
+ i_assert(worker->save_input == NULL);
+
+ T_BEGIN {
+ string_t *str = t_str_new(128);
+
+ str_append(str, "DIR-DELETE\t");
+ str_tabescape_write(str, dsync_box->name);
+ str_printfa(str, "\t%s\n", dec2str(dsync_box->last_change));
+ o_stream_send(worker->output, str_data(str), str_len(str));
+ } T_END;
+}
+
+static void
proxy_client_worker_rename_mailbox(struct dsync_worker *_worker,
const mailbox_guid_t *mailbox,
const struct dsync_mailbox *dsync_box)
@@ -1037,6 +1056,7 @@
proxy_client_worker_create_mailbox,
proxy_client_worker_delete_mailbox,
+ proxy_client_worker_delete_dir,
proxy_client_worker_rename_mailbox,
proxy_client_worker_update_mailbox,
diff -r b135e13f42b2 -r c955d4789553 src/dsync/dsync-proxy-server-cmd.c
--- a/src/dsync/dsync-proxy-server-cmd.c Fri Jun 11 21:45:51 2010 +0100
+++ b/src/dsync/dsync-proxy-server-cmd.c Fri Jun 11 22:36:38 2010 +0100
@@ -262,6 +262,21 @@
}
static int
+cmd_dir_delete(struct dsync_proxy_server *server, const char *const *args)
+{
+ struct dsync_mailbox dsync_box;
+
+ if (str_array_length(args) < 2)
+ return -1;
+
+ memset(&dsync_box, 0, sizeof(dsync_box));
+ dsync_box.name = str_tabunescape(t_strdup_noconst(args[0]));
+ dsync_box.last_change = strtoul(args[1], NULL, 10);
+ dsync_worker_delete_dir(server->worker, &dsync_box);
+ return 1;
+}
+
+static int
cmd_box_rename(struct dsync_proxy_server *server, const char *const *args)
{
mailbox_guid_t guid;
@@ -552,6 +567,7 @@
{ "MSG-LIST", cmd_msg_list },
{ "BOX-CREATE", cmd_box_create },
{ "BOX-DELETE", cmd_box_delete },
+ { "DIR-DELETE", cmd_dir_delete },
{ "BOX-RENAME", cmd_box_rename },
{ "BOX-UPDATE", cmd_box_update },
{ "BOX-SELECT", cmd_box_select },
diff -r b135e13f42b2 -r c955d4789553 src/dsync/dsync-worker-local.c
--- a/src/dsync/dsync-worker-local.c Fri Jun 11 21:45:51 2010 +0100
+++ b/src/dsync/dsync-worker-local.c Fri Jun 11 22:36:38 2010 +0100
@@ -454,7 +454,8 @@
dsync_box_r->name = "";
dsync_box_r->name_sha1 = change->name_sha1;
dsync_box_r->last_change = change->last_delete;
- dsync_box_r->flags |= DSYNC_MAILBOX_FLAG_DELETED_DIR;
+ dsync_box_r->flags |= DSYNC_MAILBOX_FLAG_NOSELECT |
+ DSYNC_MAILBOX_FLAG_DELETED_DIR;
return 1;
}
}
@@ -478,7 +479,7 @@
struct mailbox_status status;
uint8_t mailbox_guid[MAIL_GUID_128_SIZE];
struct local_dsync_mailbox_change *change;
- struct local_dsync_dir_change *dir_change;
+ struct local_dsync_dir_change *dir_change, change_lookup;
const char *const *fields;
unsigned int i, field_count;
@@ -491,17 +492,20 @@
dsync_box_r->name = info->name;
dsync_box_r->name_sep = info->ns->sep;
+ storage_name = mail_namespace_get_storage_name(info->ns, info->name);
+ dsync_str_sha_to_guid(storage_name, &dsync_box_r->name_sha1);
+
/* get last change timestamp */
- dsync_str_sha_to_guid(info->name, &dsync_box_r->name_sha1);
- dir_change = hash_table_lookup(worker->mailbox_changes_hash,
- dsync_box_r->name_sha1.guid);
+ change_lookup.list = info->ns->list;
+ change_lookup.name_sha1 = dsync_box_r->name_sha1;
+ dir_change = hash_table_lookup(worker->dir_changes_hash,
+ &change_lookup);
if (dir_change != NULL) {
/* it shouldn't be marked as deleted, but drop it to be sure */
dir_change->deleted_dir = FALSE;
dsync_box_r->last_change = dir_change->last_rename;
}
- storage_name = mail_namespace_get_storage_name(info->ns, info->name);
if ((info->flags & MAILBOX_NOSELECT) != 0) {
dsync_box_r->flags |= DSYNC_MAILBOX_FLAG_NOSELECT;
local_dsync_worker_add_mailbox(worker, info->ns, storage_name,
@@ -1136,6 +1140,27 @@
}
static void
+local_worker_delete_dir(struct dsync_worker *_worker,
+ const struct dsync_mailbox *dsync_box)
+{
+ struct local_dsync_worker *worker =
+ (struct local_dsync_worker *)_worker;
+ struct mail_namespace *ns;
+ const char *storage_name;
+
+ storage_name = dsync_box->name;
+ ns = mail_namespace_find(worker->user->namespaces, &storage_name);
+
+ mailbox_list_set_changelog_timestamp(ns->list, dsync_box->last_change);
+ if (mailbox_list_delete_dir(ns->list, storage_name) < 0) {
+ i_error("Can't delete mailbox directory %s: %s",
+ dsync_box->name,
+ mailbox_list_get_last_error(ns->list, NULL));
+ }
+ mailbox_list_set_changelog_timestamp(ns->list, (time_t)-1);
+}
+
+static void
local_worker_rename_mailbox(struct dsync_worker *_worker,
const mailbox_guid_t *mailbox,
const struct dsync_mailbox *dsync_box)
@@ -1632,6 +1657,7 @@
local_worker_create_mailbox,
local_worker_delete_mailbox,
+ local_worker_delete_dir,
local_worker_rename_mailbox,
local_worker_update_mailbox,
More information about the dovecot-cvs
mailing list