dovecot-2.0: dsync: Write mailbox changelog records using origin...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Dec 21 22:17:25 EET 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/eba3e50fef36
changeset: 10519:eba3e50fef36
user: Timo Sirainen <tss at iki.fi>
date: Mon Dec 21 15:17:08 2009 -0500
description:
dsync: Write mailbox changelog records using original timestamps.
diffstat:
15 files changed, 121 insertions(+), 75 deletions(-)
src/dsync/dsync-brain.c | 36 +++++++++++++++---------
src/dsync/dsync-data.h | 2 -
src/dsync/dsync-proxy-client.c | 12 ++++----
src/dsync/dsync-proxy-server-cmd.c | 18 ++++++++----
src/dsync/dsync-proxy.c | 4 +-
src/dsync/dsync-worker-local.c | 46 ++++++++++++++++++++-----------
src/dsync/dsync-worker-private.h | 4 +-
src/dsync/dsync-worker.c | 14 ++++-----
src/dsync/dsync-worker.h | 5 ++-
src/dsync/test-dsync-brain.c | 3 +-
src/dsync/test-dsync-proxy-server-cmd.c | 16 ++++++----
src/dsync/test-dsync-worker.c | 8 ++---
src/lib-storage/mailbox-list-private.h | 3 --
src/lib-storage/mailbox-list.c | 18 ++++++++----
src/lib-storage/mailbox-list.h | 7 +++-
diffs (truncated from 685 to 300 lines):
diff -r cf20258a44ed -r eba3e50fef36 src/dsync/dsync-brain.c
--- a/src/dsync/dsync-brain.c Fri Dec 18 15:00:09 2009 -0500
+++ b/src/dsync/dsync-brain.c Mon Dec 21 15:17:08 2009 -0500
@@ -279,13 +279,13 @@ static void dsync_brain_sync_mailboxes(s
/* delete from dest too */
if (!dest_deleted) {
dsync_worker_delete_mailbox(brain->dest_worker,
- &dest_boxes[dest]->mailbox_guid);
+ src_boxes[src]);
}
src++; dest++;
} else if (dest_deleted) {
/* delete from src too */
dsync_worker_delete_mailbox(brain->src_worker,
- &src_boxes[src]->mailbox_guid);
+ dest_boxes[dest]);
src++; dest++;
} else {
src++; dest++;
@@ -315,7 +315,8 @@ static void dsync_brain_sync_mailboxes(s
static bool
dsync_brain_is_unsubscribed(struct dsync_brain_subs_list *list,
- const struct dsync_worker_subscription *subs)
+ const struct dsync_worker_subscription *subs,
+ time_t *last_change_r)
{
const struct dsync_worker_unsubscription *unsubs;
struct dsync_worker_unsubscription lookup;
@@ -324,16 +325,23 @@ dsync_brain_is_unsubscribed(struct dsync
dsync_str_sha_to_guid(subs->storage_name, &lookup.name_sha1);
unsubs = array_bsearch(&list->unsubscriptions, &lookup,
dsync_worker_unsubscription_cmp);
- if (unsubs == NULL)
+ if (unsubs == NULL) {
+ *last_change_r = 0;
return FALSE;
- else
- return unsubs->last_change > subs->last_change;
+ } else if (unsubs->last_change <= subs->last_change) {
+ *last_change_r = subs->last_change;
+ return FALSE;
+ } else {
+ *last_change_r = unsubs->last_change;
+ return TRUE;
+ }
}
static void dsync_brain_sync_subscriptions(struct dsync_brain *brain)
{
const struct dsync_worker_subscription *src_subs, *dest_subs;
unsigned int src, dest, src_count, dest_count;
+ time_t last_change;
int ret;
/* subscriptions are sorted by name. */
@@ -358,27 +366,29 @@ static void dsync_brain_sync_subscriptio
if (ret < 0) {
/* subscribed only in source */
if (dsync_brain_is_unsubscribed(brain->dest_subs_list,
- &src_subs[src])) {
+ &src_subs[src],
+ &last_change)) {
dsync_worker_set_subscribed(brain->src_worker,
src_subs[src].vname,
- FALSE);
+ last_change, FALSE);
} else {
dsync_worker_set_subscribed(brain->dest_worker,
src_subs[src].vname,
- TRUE);
+ last_change, TRUE);
}
src++;
} else {
/* subscribed only in dest */
if (dsync_brain_is_unsubscribed(brain->src_subs_list,
- &dest_subs[dest])) {
+ &dest_subs[dest],
+ &last_change)) {
dsync_worker_set_subscribed(brain->dest_worker,
dest_subs[dest].vname,
- FALSE);
+ last_change, FALSE);
} else {
dsync_worker_set_subscribed(brain->src_worker,
dest_subs[dest].vname,
- TRUE);
+ last_change, TRUE);
}
dest++;
}
@@ -532,7 +542,7 @@ dsync_brain_sync_rename_mailbox(struct d
dsync_brain_sync_rename_mailbox(struct dsync_brain *brain,
const struct dsync_brain_mailbox *mailbox)
{
- if (mailbox->src->last_renamed > mailbox->dest->last_renamed) {
+ if (mailbox->src->last_changed > mailbox->dest->last_changed) {
dsync_worker_rename_mailbox(brain->dest_worker,
&mailbox->box.mailbox_guid,
mailbox->src);
diff -r cf20258a44ed -r eba3e50fef36 src/dsync/dsync-data.h
--- a/src/dsync/dsync-data.h Fri Dec 18 15:00:09 2009 -0500
+++ b/src/dsync/dsync-data.h Mon Dec 21 15:17:08 2009 -0500
@@ -24,7 +24,7 @@ struct dsync_mailbox {
uint32_t uid_validity, uid_next;
uint64_t highest_modseq;
- time_t last_renamed;
+ time_t last_changed;
enum dsync_mailbox_flags flags;
ARRAY_TYPE(const_string) cache_fields;
};
diff -r cf20258a44ed -r eba3e50fef36 src/dsync/dsync-proxy-client.c
--- a/src/dsync/dsync-proxy-client.c Fri Dec 18 15:00:09 2009 -0500
+++ b/src/dsync/dsync-proxy-client.c Mon Dec 21 15:17:08 2009 -0500
@@ -545,7 +545,8 @@ proxy_client_worker_subs_iter_deinit(str
static void
proxy_client_worker_set_subscribed(struct dsync_worker *_worker,
- const char *name, bool set)
+ const char *name, time_t last_change,
+ bool set)
{
struct proxy_client_dsync_worker *worker =
(struct proxy_client_dsync_worker *)_worker;
@@ -555,7 +556,8 @@ proxy_client_worker_set_subscribed(struc
str_append(str, "SUBS-SET\t");
str_tabescape_write(str, name);
- str_printfa(str, "\t%d\n", set ? 1 : 0);
+ str_printfa(str, "\t%s\t%d\n", dec2str(last_change),
+ set ? 1 : 0);
o_stream_send(worker->output, str_data(str), str_len(str));
} T_END;
}
@@ -678,7 +680,7 @@ proxy_client_worker_create_mailbox(struc
static void
proxy_client_worker_delete_mailbox(struct dsync_worker *_worker,
- const mailbox_guid_t *mailbox)
+ const struct dsync_mailbox *dsync_box)
{
struct proxy_client_dsync_worker *worker =
(struct proxy_client_dsync_worker *)_worker;
@@ -689,8 +691,8 @@ proxy_client_worker_delete_mailbox(struc
string_t *str = t_str_new(128);
str_append(str, "BOX-DELETE\t");
- dsync_proxy_mailbox_guid_export(str, mailbox);
- str_append_c(str, '\n');
+ dsync_proxy_mailbox_guid_export(str, &dsync_box->mailbox_guid);
+ str_printfa(str, "\t%s\n", dec2str(dsync_box->last_changed));
o_stream_send(worker->output, str_data(str), str_len(str));
} T_END;
}
diff -r cf20258a44ed -r eba3e50fef36 src/dsync/dsync-proxy-server-cmd.c
--- a/src/dsync/dsync-proxy-server-cmd.c Fri Dec 18 15:00:09 2009 -0500
+++ b/src/dsync/dsync-proxy-server-cmd.c Mon Dec 21 15:17:08 2009 -0500
@@ -151,13 +151,14 @@ static int
static int
cmd_subs_set(struct dsync_proxy_server *server, const char *const *args)
{
- if (args[0] == NULL || args[1] == NULL) {
+ if (str_array_length(args) < 3) {
i_error("subs-set: Missing parameters");
return -1;
}
dsync_worker_set_subscribed(server->worker, args[0],
- strcmp(args[1], "1") == 0);
+ strtoul(args[1], NULL, 10),
+ strcmp(args[2], "1") == 0);
return 1;
}
@@ -244,14 +245,19 @@ cmd_box_delete(struct dsync_proxy_server
cmd_box_delete(struct dsync_proxy_server *server, const char *const *args)
{
mailbox_guid_t guid;
-
- if (args[0] == NULL ||
- dsync_proxy_mailbox_guid_import(args[0], &guid) < 0) {
+ struct dsync_mailbox dsync_box;
+
+ if (str_array_length(args) < 2)
+ return -1;
+ if (dsync_proxy_mailbox_guid_import(args[0], &guid) < 0) {
i_error("box-delete: Invalid mailbox GUID '%s'", args[0]);
return -1;
}
- dsync_worker_delete_mailbox(server->worker, &guid);
+ memset(&dsync_box, 0, sizeof(dsync_box));
+ dsync_box.mailbox_guid = guid;
+ dsync_box.last_changed = strtoul(args[1], NULL, 10);
+ dsync_worker_delete_mailbox(server->worker, &dsync_box);
return 1;
}
diff -r cf20258a44ed -r eba3e50fef36 src/dsync/dsync-proxy.c
--- a/src/dsync/dsync-proxy.c Fri Dec 18 15:00:09 2009 -0500
+++ b/src/dsync/dsync-proxy.c Mon Dec 21 15:17:08 2009 -0500
@@ -163,7 +163,7 @@ void dsync_proxy_mailbox_export(string_t
str_tabescape_write(str, s);
str_append_c(str, '\t');
dsync_proxy_mailbox_guid_export(str, &box->dir_guid);
- str_printfa(str, "\t%lu\t%u", (unsigned long)box->last_renamed,
+ str_printfa(str, "\t%lu\t%u", (unsigned long)box->last_changed,
box->flags);
if (mail_guid_128_is_empty(box->mailbox_guid.guid)) {
@@ -207,7 +207,7 @@ int dsync_proxy_mailbox_import_unescaped
*error_r = "Invalid dir GUID";
return -1;
}
- box_r->last_renamed = strtoul(args[i++], &p, 10);
+ box_r->last_changed = strtoul(args[i++], &p, 10);
if (*p != '\0') {
*error_r = "Invalid mailbox last_renamed";
return -1;
diff -r cf20258a44ed -r eba3e50fef36 src/dsync/dsync-worker-local.c
--- a/src/dsync/dsync-worker-local.c Fri Dec 18 15:00:09 2009 -0500
+++ b/src/dsync/dsync-worker-local.c Mon Dec 21 15:17:08 2009 -0500
@@ -51,6 +51,7 @@ struct local_dsync_mailbox_change {
struct local_dsync_mailbox_change {
mailbox_guid_t guid;
time_t last_renamed;
+ time_t last_deleted;
unsigned int deleted_mailbox:1;
unsigned int deleted_dir:1;
};
@@ -126,14 +127,7 @@ dsync_worker_init_local(struct mail_user
dsync_worker_init_local(struct mail_user *user, char alt_char)
{
struct local_dsync_worker *worker;
- struct mail_namespace *ns;
pool_t pool;
-
- /* whatever we do, we do it because we're trying to sync,
- not because of a user action. don't log these mailbox list changes
- so we don't do wrong decisions on future syncs. */
- for (ns = user->namespaces; ns != NULL; ns = ns->next)
- mailbox_list_set_changelog_writable(ns->list, FALSE);
pool = pool_alloconly_create("local dsync worker", 10240);
worker = p_new(pool, struct local_dsync_worker, 1);
@@ -181,6 +175,7 @@ dsync_worker_save_mailbox_change(struct
const struct mailbox_log_record *rec)
{
struct local_dsync_mailbox_change *change;
+ time_t stamp;
change = hash_table_lookup(worker->mailbox_changes_hash,
rec->mailbox_guid);
@@ -191,16 +186,20 @@ dsync_worker_save_mailbox_change(struct
hash_table_insert(worker->mailbox_changes_hash,
change->guid.guid, change);
}
+
+ stamp = mailbox_log_record_get_timestamp(rec);
switch (rec->type) {
case MAILBOX_LOG_RECORD_DELETE_MAILBOX:
change->deleted_mailbox = TRUE;
+ if (change->last_deleted < stamp)
+ change->last_deleted = stamp;
break;
case MAILBOX_LOG_RECORD_DELETE_DIR:
change->deleted_dir = TRUE;
break;
case MAILBOX_LOG_RECORD_RENAME:
- change->last_renamed =
- mailbox_log_record_get_timestamp(rec);
+ if (change->last_renamed < stamp)
+ change->last_renamed = stamp;
break;
case MAILBOX_LOG_RECORD_SUBSCRIBE:
case MAILBOX_LOG_RECORD_UNSUBSCRIBE:
@@ -220,12 +219,14 @@ dsync_worker_save_subscription_change(st
const struct mailbox_log_record *rec)
{
struct local_dsync_subscription_change *change, new_change;
+ time_t stamp;
memset(&new_change, 0, sizeof(new_change));
new_change.list = list;
memcpy(new_change.name_sha1.guid, rec->mailbox_guid,
sizeof(new_change.name_sha1.guid));
+ stamp = mailbox_log_record_get_timestamp(rec);
change = hash_table_lookup(worker->subscription_changes_hash,
&new_change);
if (change == NULL) {
@@ -233,7 +234,13 @@ dsync_worker_save_subscription_change(st
*change = new_change;
hash_table_insert(worker->subscription_changes_hash,
change, change);
- }
+ } else if (change->last_change > stamp) {
+ /* we've already seen a newer subscriptions state. this is
More information about the dovecot-cvs
mailing list