dovecot-2.1: dsync: Update cache fields' decision and last_used ...

dovecot at dovecot.org dovecot at dovecot.org
Sat Dec 10 08:46:19 EET 2011


details:   http://hg.dovecot.org/dovecot-2.1/rev/3830d5a57fd4
changeset: 13844:3830d5a57fd4
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Dec 10 08:44:33 2011 +0200
description:
dsync: Update cache fields' decision and last_used fields explicitly.
This makes v2.1's dsync incompatible with v2.0's when used in different
servers.

diffstat:

 src/dsync/dsync-data.c                            |   8 +-
 src/dsync/dsync-data.h                            |   2 +-
 src/dsync/dsync-proxy-client.c                    |   4 +-
 src/dsync/dsync-proxy-server-cmd.c                |  11 +-
 src/dsync/dsync-proxy.c                           |  99 ++++++++++++++++++++--
 src/dsync/dsync-proxy.h                           |  11 +-
 src/dsync/dsync-worker-local.c                    |  31 +++---
 src/dsync/dsync-worker-private.h                  |   2 +-
 src/dsync/test-dsync-common.c                     |   6 +-
 src/dsync/test-dsync-proxy.c                      |   7 +-
 src/dsync/test-dsync-worker.c                     |   2 +-
 src/dsync/test-dsync-worker.h                     |   2 +-
 src/lib-storage/index/dbox-multi/mdbox-storage.c  |   4 +-
 src/lib-storage/index/dbox-single/sdbox-storage.c |   4 +-
 src/lib-storage/index/index-status.c              |  13 ++-
 src/lib-storage/index/index-storage.c             |  34 +++---
 src/lib-storage/index/index-storage.h             |   4 +-
 src/lib-storage/mail-storage.h                    |  14 ++-
 18 files changed, 180 insertions(+), 78 deletions(-)

diffs (truncated from 596 to 300 lines):

diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-data.c
--- a/src/dsync/dsync-data.c	Sat Dec 10 08:43:09 2011 +0200
+++ b/src/dsync/dsync-data.c	Sat Dec 10 08:44:33 2011 +0200
@@ -10,7 +10,8 @@
 dsync_mailbox_dup(pool_t pool, const struct dsync_mailbox *box)
 {
 	struct dsync_mailbox *dest;
-	const char *const *cache_fields = NULL, *dup;
+	const struct mailbox_cache_field *cache_fields = NULL;
+	struct mailbox_cache_field *dup;
 	unsigned int i, count = 0;
 
 	dest = p_new(pool, struct dsync_mailbox, 1);
@@ -24,8 +25,9 @@
 	else {
 		p_array_init(&dest->cache_fields, pool, count);
 		for (i = 0; i < count; i++) {
-			dup = p_strdup(pool, cache_fields[i]);
-			array_append(&dest->cache_fields, &dup, 1);
+			dup = array_append_space(&dest->cache_fields);
+			*dup = cache_fields[i];
+			dup->name = p_strdup(pool, dup->name);
 		}
 	}
 	return dest;
diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-data.h
--- a/src/dsync/dsync-data.h	Sat Dec 10 08:43:09 2011 +0200
+++ b/src/dsync/dsync-data.h	Sat Dec 10 08:44:33 2011 +0200
@@ -28,7 +28,7 @@
 	   otherwise it's the last rename timestamp. */
 	time_t last_change;
 	enum dsync_mailbox_flags flags;
-	ARRAY_TYPE(const_string) cache_fields;
+	ARRAY_TYPE(mailbox_cache_field) cache_fields;
 };
 ARRAY_DEFINE_TYPE(dsync_mailbox, struct dsync_mailbox *);
 #define dsync_mailbox_is_noselect(dsync_box) \
diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-proxy-client.c
--- a/src/dsync/dsync-proxy-client.c	Sat Dec 10 08:43:09 2011 +0200
+++ b/src/dsync/dsync-proxy-client.c	Sat Dec 10 08:44:33 2011 +0200
@@ -893,7 +893,7 @@
 static void
 proxy_client_worker_select_mailbox(struct dsync_worker *_worker,
 				   const mailbox_guid_t *mailbox,
-				   const ARRAY_TYPE(const_string) *cache_fields)
+				   const ARRAY_TYPE(mailbox_cache_field) *cache_fields)
 {
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
@@ -908,7 +908,7 @@
 		str_append(str, "BOX-SELECT\t");
 		dsync_proxy_mailbox_guid_export(str, mailbox);
 		if (cache_fields != NULL)
-			dsync_proxy_strings_export(str, cache_fields);
+			dsync_proxy_cache_fields_export(str, cache_fields);
 		str_append_c(str, '\n');
 		proxy_client_worker_cmd(worker, str);
 	} T_END;
diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-proxy-server-cmd.c
--- a/src/dsync/dsync-proxy-server-cmd.c	Sat Dec 10 08:43:09 2011 +0200
+++ b/src/dsync/dsync-proxy-server-cmd.c	Sat Dec 10 08:44:33 2011 +0200
@@ -315,7 +315,7 @@
 cmd_box_select(struct dsync_proxy_server *server, const char *const *args)
 {
 	struct dsync_mailbox box;
-	unsigned int i, count;
+	const char *error;
 
 	memset(&box, 0, sizeof(box));
 	if (args[0] == NULL ||
@@ -325,10 +325,11 @@
 	}
 	args++;
 
-	count = str_array_length(args);
-	t_array_init(&box.cache_fields, count + 1);
-	for (i = 0; i < count; i++)
-		array_append(&box.cache_fields, &args[i], 1);
+	if (dsync_proxy_cache_fields_import(args, pool_datastack_create(),
+					    &box.cache_fields, &error) < 0) {
+		i_error("box-select: %s", error);
+		return -1;
+	}
 	dsync_worker_select_mailbox(server->worker, &box);
 	return 1;
 }
diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-proxy.c
--- a/src/dsync/dsync-proxy.c	Sat Dec 10 08:43:09 2011 +0200
+++ b/src/dsync/dsync-proxy.c	Sat Dec 10 08:44:33 2011 +0200
@@ -8,27 +8,104 @@
 #include "hex-binary.h"
 #include "mail-types.h"
 #include "imap-util.h"
+#include "mail-cache.h"
 #include "dsync-data.h"
 #include "dsync-proxy.h"
 
 #include <stdlib.h>
 
-void dsync_proxy_strings_export(string_t *str,
-				const ARRAY_TYPE(const_string) *strings)
+#define DSYNC_CACHE_DECISION_NO 'n'
+#define DSYNC_CACHE_DECISION_YES 'y'
+#define DSYNC_CACHE_DECISION_TEMP 't'
+#define DSYNC_CACHE_DECISION_FORCED 'f'
+
+void dsync_proxy_cache_fields_export(string_t *str,
+				     const ARRAY_TYPE(mailbox_cache_field) *_fields)
 {
-	const char *const *fields;
+	const struct mailbox_cache_field *fields;
 	unsigned int i, count;
 
-	if (!array_is_created(strings))
+	if (!array_is_created(_fields))
 		return;
 
-	fields = array_get(strings, &count);
+	fields = array_get(_fields, &count);
 	for (i = 0; i < count; i++) {
 		str_append_c(str, '\t');
-		str_tabescape_write(str, fields[i]);
+		str_tabescape_write(str, fields[i].name);
+		str_append_c(str, '\t');
+		switch (fields[i].decision & ~MAIL_CACHE_DECISION_FORCED) {
+		case MAIL_CACHE_DECISION_NO:
+			str_append_c(str, DSYNC_CACHE_DECISION_NO);
+			break;
+		case MAIL_CACHE_DECISION_YES:
+			str_append_c(str, DSYNC_CACHE_DECISION_YES);
+			break;
+		case MAIL_CACHE_DECISION_TEMP:
+			str_append_c(str, DSYNC_CACHE_DECISION_TEMP);
+			break;
+		}
+		if ((fields[i].decision & MAIL_CACHE_DECISION_FORCED) != 0)
+			str_append_c(str, DSYNC_CACHE_DECISION_FORCED);
+		str_printfa(str, "\t%ld", fields[i].last_used);
 	}
 }
 
+static int dsync_proxy_cache_dec_parse(const char *str,
+				       enum mail_cache_decision_type *dec_r)
+{
+	switch (*str++) {
+	case DSYNC_CACHE_DECISION_NO:
+		*dec_r = MAIL_CACHE_DECISION_NO;
+		break;
+	case DSYNC_CACHE_DECISION_YES:
+		*dec_r = MAIL_CACHE_DECISION_YES;
+		break;
+	case DSYNC_CACHE_DECISION_TEMP:
+		*dec_r = MAIL_CACHE_DECISION_TEMP;
+		break;
+	default:
+		return -1;
+	}
+	if (*str == DSYNC_CACHE_DECISION_FORCED) {
+		*dec_r |= MAIL_CACHE_DECISION_FORCED;
+		str++;
+	}
+	if (*str != '\0')
+		return -1;
+	return 0;
+}
+
+int dsync_proxy_cache_fields_import(const char *const *args, pool_t pool,
+				    ARRAY_TYPE(mailbox_cache_field) *fields,
+				    const char **error_r)
+{
+	struct mailbox_cache_field *cache_field;
+	enum mail_cache_decision_type dec;
+	unsigned int i, count = str_array_length(args);
+
+	if (count % 3 != 0) {
+		*error_r = "Invalid mailbox cache fields";
+		return -1;
+	}
+	if (!array_is_created(fields))
+		p_array_init(fields, pool, (count/3) + 1);
+	for (i = 0; i < count; i += 3) {
+		cache_field = array_append_space(fields);
+		cache_field->name = p_strdup(pool, args[i]);
+
+		if (dsync_proxy_cache_dec_parse(args[i+1], &dec) < 0) {
+			*error_r = "Invalid cache decision";
+			return -1;
+		}
+		cache_field->decision = dec;
+		if (str_to_time(args[i+2], &cache_field->last_used) < 0) {
+			*error_r = "Invalid cache last_used";
+			return -1;
+		}
+	}
+	return 0;
+}
+
 void dsync_proxy_msg_export(string_t *str,
 			    const struct dsync_message *msg)
 {
@@ -178,7 +255,7 @@
 		    box->uid_validity, box->uid_next, box->message_count,
 		    (unsigned long long)box->highest_modseq,
 		    box->first_recent_uid);
-	dsync_proxy_strings_export(str, &box->cache_fields);
+	dsync_proxy_cache_fields_export(str, &box->cache_fields);
 }
 
 int dsync_proxy_mailbox_import_unescaped(pool_t pool, const char *const *args,
@@ -270,11 +347,9 @@
 
 	args += i;
 	count -= i;
-	p_array_init(&box_r->cache_fields, pool, count + 1);
-	for (i = 0; i < count; i++) {
-		const char *field_name = p_strdup(pool, args[i]);
-		array_append(&box_r->cache_fields, &field_name, 1);
-	}
+	if (dsync_proxy_cache_fields_import(args, pool, &box_r->cache_fields,
+					    error_r) < 0)
+		return -1;
 	return 0;
 }
 
diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-proxy.h
--- a/src/dsync/dsync-proxy.h	Sat Dec 10 08:43:09 2011 +0200
+++ b/src/dsync/dsync-proxy.h	Sat Dec 10 08:44:33 2011 +0200
@@ -6,14 +6,17 @@
 #define DSYNC_PROXY_CLIENT_TIMEOUT_MSECS (14*60*1000)
 #define DSYNC_PROXY_SERVER_TIMEOUT_MSECS (15*60*1000)
 
-#define DSYNC_PROXY_CLIENT_GREETING_LINE "dsync-client\t1"
-#define DSYNC_PROXY_SERVER_GREETING_LINE "dsync-server\t1"
+#define DSYNC_PROXY_CLIENT_GREETING_LINE "dsync-client\t2"
+#define DSYNC_PROXY_SERVER_GREETING_LINE "dsync-server\t2"
 
 struct dsync_message;
 struct dsync_mailbox;
 
-void dsync_proxy_strings_export(string_t *str,
-				const ARRAY_TYPE(const_string) *strings);
+void dsync_proxy_cache_fields_export(string_t *str,
+				     const ARRAY_TYPE(mailbox_cache_field) *fields);
+int dsync_proxy_cache_fields_import(const char *const *args, pool_t pool,
+				    ARRAY_TYPE(mailbox_cache_field) *fields,
+				    const char **error_r);
 
 void dsync_proxy_msg_export(string_t *str, const struct dsync_message *msg);
 int dsync_proxy_msg_parse_flags(pool_t pool, const char *str,
diff -r 186f2f5ee1c3 -r 3830d5a57fd4 src/dsync/dsync-worker-local.c
--- a/src/dsync/dsync-worker-local.c	Sat Dec 10 08:43:09 2011 +0200
+++ b/src/dsync/dsync-worker-local.c	Sat Dec 10 08:44:33 2011 +0200
@@ -528,8 +528,8 @@
 	struct local_dsync_dir_change *dir_change, change_lookup;
 	struct local_dsync_mailbox *old_lbox;
 	enum mail_error error;
-	const char *const *fields;
-	unsigned int i, field_count;
+	struct mailbox_cache_field *cache_fields;
+	unsigned int i, cache_field_count;
 
 	memset(dsync_box_r, 0, sizeof(*dsync_box_r));
 
@@ -595,12 +595,14 @@
 	dsync_box_r->highest_modseq = status.highest_modseq;
 
 	p_clear(iter->ret_pool);
-	fields = array_get(metadata.cache_fields, &field_count);
-	p_array_init(&dsync_box_r->cache_fields, iter->ret_pool, field_count);
-	for (i = 0; i < field_count; i++) {
-		const char *field_name = p_strdup(iter->ret_pool, fields[i]);
-
-		array_append(&dsync_box_r->cache_fields, &field_name, 1);
+	p_array_init(&dsync_box_r->cache_fields, iter->ret_pool,
+		     array_count(metadata.cache_fields));
+	array_append_array(&dsync_box_r->cache_fields, metadata.cache_fields);
+	cache_fields = array_get_modifiable(&dsync_box_r->cache_fields,
+					    &cache_field_count);
+	for (i = 0; i < cache_field_count; i++) {
+		cache_fields[i].name =
+			p_strdup(iter->ret_pool, cache_fields[i].name);
 	}
 
 	old_lbox = hash_table_lookup(worker->mailbox_hash,
@@ -1443,25 +1445,26 @@
 
 static void
 local_worker_set_cache_fields(struct local_dsync_worker *worker,
-			      const ARRAY_TYPE(const_string) *cache_fields)
+			      const ARRAY_TYPE(mailbox_cache_field) *cache_fields)
 {
 	struct mailbox_update update;
-	const char *const *fields, **new_fields;
+	const struct mailbox_cache_field *fields;
+	struct mailbox_cache_field *new_fields;
 	unsigned int count;
 
 	fields = array_get(cache_fields, &count);
-	new_fields = t_new(const char *, count + 1);
-	memcpy(new_fields, fields, sizeof(const char *) * count);


More information about the dovecot-cvs mailing list