dovecot-2.2: dsync: Added support for syncing mailbox attributes.

dovecot at dovecot.org dovecot at dovecot.org
Thu Mar 14 15:41:49 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/c6082de4bf5b
changeset: 16025:c6082de4bf5b
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Mar 14 15:41:09 2013 +0200
description:
dsync: Added support for syncing mailbox attributes.

diffstat:

 src/doveadm/dsync/Makefile.am                  |    1 +
 src/doveadm/dsync/dsync-brain-mailbox.c        |    8 +-
 src/doveadm/dsync/dsync-brain-mails.c          |   36 ++++++
 src/doveadm/dsync/dsync-brain-private.h        |    1 +
 src/doveadm/dsync/dsync-ibc-pipe.c             |   34 ++++++
 src/doveadm/dsync/dsync-ibc-private.h          |    6 +
 src/doveadm/dsync/dsync-ibc-stream.c           |  136 ++++++++++++++++++++++--
 src/doveadm/dsync/dsync-ibc.c                  |   17 +++
 src/doveadm/dsync/dsync-ibc.h                  |    8 +
 src/doveadm/dsync/dsync-mailbox-export.c       |  120 +++++++++++++++++++++-
 src/doveadm/dsync/dsync-mailbox-export.h       |    3 +-
 src/doveadm/dsync/dsync-mailbox-import.c       |  115 +++++++++++++++++++++
 src/doveadm/dsync/dsync-mailbox-import.h       |    3 +
 src/doveadm/dsync/dsync-mailbox.c              |   17 +++
 src/doveadm/dsync/dsync-mailbox.h              |   16 ++
 src/doveadm/dsync/dsync-transaction-log-scan.c |   72 +++++++++++++
 src/doveadm/dsync/dsync-transaction-log-scan.h |    5 +
 17 files changed, 578 insertions(+), 20 deletions(-)

diffs (truncated from 1002 to 300 lines):

diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/Makefile.am
--- a/src/doveadm/dsync/Makefile.am	Thu Mar 14 15:32:14 2013 +0200
+++ b/src/doveadm/dsync/Makefile.am	Thu Mar 14 15:41:09 2013 +0200
@@ -21,6 +21,7 @@
 	dsync-brain-mails.c \
 	dsync-deserializer.c \
 	dsync-mail.c \
+	dsync-mailbox.c \
 	dsync-mailbox-import.c \
 	dsync-mailbox-export.c \
 	dsync-mailbox-state.c \
diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/dsync-brain-mailbox.c
--- a/src/doveadm/dsync/dsync-brain-mailbox.c	Thu Mar 14 15:32:14 2013 +0200
+++ b/src/doveadm/dsync/dsync-brain-mailbox.c	Thu Mar 14 15:41:09 2013 +0200
@@ -84,7 +84,7 @@
 {
 	if (brain->backup_send) {
 		/* we have an exporter, but no importer. */
-		brain->box_send_state = DSYNC_BOX_STATE_CHANGES;
+		brain->box_send_state = DSYNC_BOX_STATE_ATTRIBUTES;
 		brain->box_recv_state = brain->mail_requests ?
 			DSYNC_BOX_STATE_MAIL_REQUESTS :
 			DSYNC_BOX_STATE_RECV_LAST_COMMON;
@@ -93,10 +93,10 @@
 		brain->box_send_state = brain->mail_requests ?
 			DSYNC_BOX_STATE_MAIL_REQUESTS :
 			DSYNC_BOX_STATE_DONE;
-		brain->box_recv_state = DSYNC_BOX_STATE_CHANGES;
+		brain->box_recv_state = DSYNC_BOX_STATE_ATTRIBUTES;
 	} else {
-		brain->box_send_state = DSYNC_BOX_STATE_CHANGES;
-		brain->box_recv_state = DSYNC_BOX_STATE_CHANGES;
+		brain->box_send_state = DSYNC_BOX_STATE_ATTRIBUTES;
+		brain->box_recv_state = DSYNC_BOX_STATE_ATTRIBUTES;
 	}
 }
 
diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/dsync-brain-mails.c
--- a/src/doveadm/dsync/dsync-brain-mails.c	Thu Mar 14 15:32:14 2013 +0200
+++ b/src/doveadm/dsync/dsync-brain-mails.c	Thu Mar 14 15:41:09 2013 +0200
@@ -11,6 +11,7 @@
 const char *dsync_box_state_names[DSYNC_BOX_STATE_DONE+1] = {
 	"mailbox",
 	"changes",
+	"attributes",
 	"mail_requests",
 	"mails",
 	"recv_last_common",
@@ -59,6 +60,34 @@
 	return TRUE;
 }
 
+static bool dsync_brain_recv_mailbox_attribute(struct dsync_brain *brain)
+{
+	const struct dsync_mailbox_attribute *attr;
+	enum dsync_ibc_recv_ret ret;
+
+	if ((ret = dsync_ibc_recv_mailbox_attribute(brain->ibc, &attr)) == 0)
+		return FALSE;
+	if (ret == DSYNC_IBC_RECV_RET_FINISHED) {
+		brain->box_recv_state = DSYNC_BOX_STATE_CHANGES;
+		return TRUE;
+	}
+	if (dsync_mailbox_import_attribute(brain->box_importer, attr) < 0)
+		brain->failed = TRUE;
+	return TRUE;
+}
+
+static void dsync_brain_send_mailbox_attribute(struct dsync_brain *brain)
+{
+	const struct dsync_mailbox_attribute *attr;
+
+	while ((attr = dsync_mailbox_export_next_attr(brain->box_exporter)) != NULL) {
+		if (dsync_ibc_send_mailbox_attribute(brain->ibc, attr) == 0)
+			return;
+	}
+	dsync_ibc_send_end_of_list(brain->ibc);
+	brain->box_send_state = DSYNC_BOX_STATE_CHANGES;
+}
+
 static bool dsync_brain_recv_mail_change(struct dsync_brain *brain)
 {
 	const struct dsync_mail_change *change;
@@ -278,6 +307,9 @@
 	case DSYNC_BOX_STATE_MAILBOX:
 		changed = dsync_brain_master_sync_recv_mailbox(brain);
 		break;
+	case DSYNC_BOX_STATE_ATTRIBUTES:
+		changed = dsync_brain_recv_mailbox_attribute(brain);
+		break;
 	case DSYNC_BOX_STATE_CHANGES:
 		changed = dsync_brain_recv_mail_change(brain);
 		break;
@@ -299,6 +331,10 @@
 		case DSYNC_BOX_STATE_MAILBOX:
 			/* wait for mailbox to be received first */
 			break;
+		case DSYNC_BOX_STATE_ATTRIBUTES:
+			dsync_brain_send_mailbox_attribute(brain);
+			changed = TRUE;
+			break;
 		case DSYNC_BOX_STATE_CHANGES:
 			dsync_brain_send_mail_change(brain);
 			changed = TRUE;
diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/dsync-brain-private.h
--- a/src/doveadm/dsync/dsync-brain-private.h	Thu Mar 14 15:32:14 2013 +0200
+++ b/src/doveadm/dsync/dsync-brain-private.h	Thu Mar 14 15:41:09 2013 +0200
@@ -38,6 +38,7 @@
 enum dsync_box_state {
 	DSYNC_BOX_STATE_MAILBOX,
 	DSYNC_BOX_STATE_CHANGES,
+	DSYNC_BOX_STATE_ATTRIBUTES,
 	DSYNC_BOX_STATE_MAIL_REQUESTS,
 	DSYNC_BOX_STATE_MAILS,
 	DSYNC_BOX_STATE_RECV_LAST_COMMON,
diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/dsync-ibc-pipe.c
--- a/src/doveadm/dsync/dsync-ibc-pipe.c	Thu Mar 14 15:32:14 2013 +0200
+++ b/src/doveadm/dsync/dsync-ibc-pipe.c	Thu Mar 14 15:41:09 2013 +0200
@@ -16,6 +16,7 @@
 	ITEM_MAILBOX_TREE_NODE,
 	ITEM_MAILBOX_DELETE,
 	ITEM_MAILBOX,
+	ITEM_MAILBOX_ATTRIBUTE,
 	ITEM_MAIL_CHANGE,
 	ITEM_MAIL_REQUEST,
 	ITEM_MAIL
@@ -31,6 +32,7 @@
 		struct dsync_mailbox_node node;
 		guid_128_t mailbox_guid;
 		struct dsync_mailbox dsync_box;
+		struct dsync_mailbox_attribute attr;
 		struct dsync_mail_change change;
 		struct dsync_mail_request request;
 		struct dsync_mail mail;
@@ -84,6 +86,7 @@
 	case ITEM_HANDSHAKE:
 	case ITEM_MAILBOX:
 	case ITEM_MAILBOX_TREE_NODE:
+	case ITEM_MAILBOX_ATTRIBUTE:
 	case ITEM_MAIL_CHANGE:
 	case ITEM_MAIL_REQUEST:
 	case ITEM_MAIL:
@@ -342,6 +345,35 @@
 }
 
 static void
+dsync_ibc_pipe_send_mailbox_attribute(struct dsync_ibc *ibc,
+				      const struct dsync_mailbox_attribute *attr)
+{
+	struct dsync_ibc_pipe *pipe = (struct dsync_ibc_pipe *)ibc;
+	struct item *item;
+
+	item = dsync_ibc_pipe_push_item(pipe->remote, ITEM_MAILBOX_ATTRIBUTE);
+	dsync_mailbox_attribute_dup(item->pool, attr, &item->u.attr);
+}
+
+static enum dsync_ibc_recv_ret
+dsync_ibc_pipe_recv_mailbox_attribute(struct dsync_ibc *ibc,
+				      const struct dsync_mailbox_attribute **attr_r)
+{
+	struct dsync_ibc_pipe *pipe = (struct dsync_ibc_pipe *)ibc;
+	struct item *item;
+
+	if (dsync_ibc_pipe_try_pop_eol(pipe))
+		return DSYNC_IBC_RECV_RET_FINISHED;
+
+	item = dsync_ibc_pipe_pop_item(pipe, ITEM_MAILBOX_ATTRIBUTE);
+	if (item == NULL)
+		return DSYNC_IBC_RECV_RET_TRYAGAIN;
+
+	*attr_r = &item->u.attr;
+	return DSYNC_IBC_RECV_RET_OK;
+}
+
+static void
 dsync_ibc_pipe_send_change(struct dsync_ibc *ibc,
 			   const struct dsync_mail_change *change)
 {
@@ -470,6 +502,8 @@
 	dsync_ibc_pipe_recv_mailbox_deletes,
 	dsync_ibc_pipe_send_mailbox,
 	dsync_ibc_pipe_recv_mailbox,
+	dsync_ibc_pipe_send_mailbox_attribute,
+	dsync_ibc_pipe_recv_mailbox_attribute,
 	dsync_ibc_pipe_send_change,
 	dsync_ibc_pipe_recv_change,
 	dsync_ibc_pipe_send_mail_request,
diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/dsync-ibc-private.h
--- a/src/doveadm/dsync/dsync-ibc-private.h	Thu Mar 14 15:32:14 2013 +0200
+++ b/src/doveadm/dsync/dsync-ibc-private.h	Thu Mar 14 15:41:09 2013 +0200
@@ -43,6 +43,12 @@
 		(*recv_mailbox)(struct dsync_ibc *ibc,
 				const struct dsync_mailbox **dsync_box_r);
 
+	void (*send_mailbox_attribute)(struct dsync_ibc *ibc,
+				       const struct dsync_mailbox_attribute *attr);
+	enum dsync_ibc_recv_ret
+		(*recv_mailbox_attribute)(struct dsync_ibc *ibc,
+					  const struct dsync_mailbox_attribute **attr_r);
+
 	void (*send_change)(struct dsync_ibc *ibc,
 			    const struct dsync_mail_change *change);
 	enum dsync_ibc_recv_ret
diff -r f3cd9e5cbe99 -r c6082de4bf5b src/doveadm/dsync/dsync-ibc-stream.c
--- a/src/doveadm/dsync/dsync-ibc-stream.c	Thu Mar 14 15:32:14 2013 +0200
+++ b/src/doveadm/dsync/dsync-ibc-stream.c	Thu Mar 14 15:41:09 2013 +0200
@@ -28,7 +28,10 @@
 #define DSYNC_IBC_STREAM_OUTBUF_THROTTLE_SIZE (1024*128)
 
 #define DSYNC_PROTOCOL_VERSION_MAJOR 3
-#define DSYNC_HANDSHAKE_VERSION "VERSION\tdsync\t3\t0\n"
+#define DSYNC_PROTOCOL_VERSION_MINOR 1
+#define DSYNC_HANDSHAKE_VERSION "VERSION\tdsync\t3\t1\n"
+
+#define DSYNC_PROTOCOL_MINOR_HAVE_ATTRIBUTES 1
 
 enum item_type {
 	ITEM_NONE,
@@ -40,6 +43,7 @@
 	ITEM_MAILBOX_DELETE,
 	ITEM_MAILBOX,
 
+	ITEM_MAILBOX_ATTRIBUTE,
 	ITEM_MAIL_CHANGE,
 	ITEM_MAIL_REQUEST,
 	ITEM_MAIL,
@@ -92,6 +96,11 @@
 		"first_recent_uid highest_modseq highest_pvt_modseq",
 	  .optional_keys = "mailbox_lost cache_fields have_guids"
 	},
+	{ .name = "mailbox_attribute",
+	  .chr = 'A',
+	  .required_keys = "type key",
+	  .optional_keys = "value deleted last_change modseq"
+	},
 	{ .name = "mail_change",
 	  .chr = 'C',
 	  .required_keys = "type uid",
@@ -126,6 +135,7 @@
 	struct io *io;
 	struct timeout *to;
 
+	unsigned int minor_version;
 	struct dsync_serializer *serializers[ITEM_END_OF_LIST];
 	struct dsync_deserializer *deserializers[ITEM_END_OF_LIST];
 
@@ -195,16 +205,9 @@
 					 &data, &size, 0)) > 0) {
 		add = '\0';
 		for (i = 0; i < size; i++) {
-			if (data[i] == '\n') {
-				if ((i == 0 && ibc->mail_output_last != '\r') ||
-				    (i > 0 && data[i-1] != '\r')) {
-					/* missing CR */
-					add = '\r';
-					break;
-				}
-			} else if (data[i] == '.' &&
-				   ((i == 0 && ibc->mail_output_last == '\n') ||
-				    (i > 0 && data[i-1] == '\n'))) {
+			if (data[i] == '.' &&
+			    ((i == 0 && ibc->mail_output_last == '\n') ||
+			     (i > 0 && data[i-1] == '\n'))) {
 				/* escape the dot */
 				add = '.';
 				break;
@@ -243,7 +246,8 @@
 		return -1;
 	}
 
-	/* finished sending the stream */
+	/* finished sending the stream. use "CRLF." instead of "LF." just in
+	   case we're sending binary data that ends with CR. */
 	o_stream_nsend_str(ibc->output, "\r\n.\r\n");
 	i_stream_unref(&ibc->mail_output);
 	return 1;
@@ -429,8 +433,9 @@
 		return TRUE;
 
 	if (!ibc->version_received) {
-		if (!version_string_verify(line, "dsync",
-					   DSYNC_PROTOCOL_VERSION_MAJOR)) {
+		if (!version_string_verify_full(line, "dsync",
+						DSYNC_PROTOCOL_VERSION_MAJOR,
+						&ibc->minor_version)) {
 			dsync_ibc_input_error(ibc, NULL,
 				"Remote dsync doesn't use compatible protocol");
 			return DSYNC_IBC_RECV_RET_TRYAGAIN;
@@ -1185,6 +1190,107 @@
 }
 
 static void
+dsync_ibc_stream_send_mailbox_attribute(struct dsync_ibc *_ibc,
+					const struct dsync_mailbox_attribute *attr)
+{
+	struct dsync_ibc_stream *ibc = (struct dsync_ibc_stream *)_ibc;
+	struct dsync_serializer_encoder *encoder;
+	string_t *str = t_str_new(128);
+	char type[2];
+


More information about the dovecot-cvs mailing list