dovecot-2.2: doveadm: "backup" command is working again.

dovecot at dovecot.org dovecot at dovecot.org
Sun Oct 21 10:02:04 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/454d0563927d
changeset: 15231:454d0563927d
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Oct 21 10:01:54 2012 +0300
description:
doveadm: "backup" command is working again.

diffstat:

 src/doveadm/dsync/doveadm-dsync.c                 |   26 ++-
 src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c |    2 +
 src/doveadm/dsync/dsync-brain-mailbox-tree.c      |   11 +-
 src/doveadm/dsync/dsync-brain-mailbox.c           |   47 ++++-
 src/doveadm/dsync/dsync-brain-mails.c             |   42 ++-
 src/doveadm/dsync/dsync-brain-private.h           |   13 +
 src/doveadm/dsync/dsync-brain.c                   |   28 ++-
 src/doveadm/dsync/dsync-brain.h                   |    4 +-
 src/doveadm/dsync/dsync-ibc-stream.c              |   33 ++-
 src/doveadm/dsync/dsync-ibc.h                     |    4 +-
 src/doveadm/dsync/dsync-mailbox-tree-fill.c       |    1 +
 src/doveadm/dsync/dsync-mailbox-tree-sync.c       |  208 +++++++++++++++++----
 src/doveadm/dsync/dsync-mailbox-tree.c            |    2 +
 src/doveadm/dsync/dsync-mailbox-tree.h            |   16 +-
 src/doveadm/dsync/test-dsync-mailbox-tree-sync.c  |    6 +-
 15 files changed, 346 insertions(+), 97 deletions(-)

diffs (truncated from 972 to 300 lines):

diff -r a436e4a7503b -r 454d0563927d src/doveadm/dsync/doveadm-dsync.c
--- a/src/doveadm/dsync/doveadm-dsync.c	Sun Oct 21 08:22:20 2012 +0300
+++ b/src/doveadm/dsync/doveadm-dsync.c	Sun Oct 21 10:01:54 2012 +0300
@@ -23,6 +23,8 @@
 #include <unistd.h>
 #include <ctype.h>
 
+#define DSYNC_COMMON_GETOPT_ARGS "+dEfl:m:n:"
+
 struct dsync_cmd_context {
 	struct doveadm_mail_cmd_context ctx;
 	enum dsync_brain_sync_type sync_type;
@@ -38,7 +40,8 @@
 
 	unsigned int lock:1;
 	unsigned int default_replica_location:1;
-	unsigned int reverse_backup:1; //FIXME
+	unsigned int backup:1;
+	unsigned int reverse_backup:1;
 	unsigned int remote:1;
 };
 
@@ -315,6 +318,7 @@
 	struct dsync_ibc *ibc, *ibc2 = NULL;
 	struct dsync_brain *brain;
 	struct mail_namespace *sync_ns = NULL;
+	enum dsync_brain_flags brain_flags;
 	int ret = 0;
 
 	user->admin = TRUE;
@@ -342,11 +346,16 @@
 	if (doveadm_debug || doveadm_verbose) {
 		// FIXME
 	}
+
+	brain_flags = DSYNC_BRAIN_FLAG_MAILS_HAVE_GUIDS |
+		DSYNC_BRAIN_FLAG_SEND_GUID_REQUESTS;
+	if (ctx->reverse_backup)
+		brain_flags |= DSYNC_BRAIN_FLAG_BACKUP_RECV;
+	else if (ctx->backup)
+		brain_flags |= DSYNC_BRAIN_FLAG_BACKUP_SEND;
+
 	brain = dsync_brain_master_init(user, ibc, sync_ns,
-					ctx->sync_type,
-					DSYNC_BRAIN_FLAG_MAILS_HAVE_GUIDS |
-					DSYNC_BRAIN_FLAG_SEND_REQUESTS,
-					"");
+					ctx->sync_type, brain_flags, "");
 
 	if (!ctx->remote) {
 		if (cmd_dsync_run_local(ctx, user, brain, ibc2) < 0)
@@ -469,6 +478,8 @@
 		ctx->namespace_prefix = optarg;
 		break;
 	case 'R':
+		if (!ctx->backup)
+			return FALSE;
 		ctx->reverse_backup = TRUE;
 		break;
 	default:
@@ -482,7 +493,7 @@
 	struct dsync_cmd_context *ctx;
 
 	ctx = doveadm_mail_cmd_alloc(struct dsync_cmd_context);
-	ctx->ctx.getopt_args = "+dEfl:m:n:R";
+	ctx->ctx.getopt_args = DSYNC_COMMON_GETOPT_ARGS;
 	ctx->ctx.v.parse_arg = cmd_mailbox_dsync_parse_arg;
 	ctx->ctx.v.preinit = cmd_dsync_preinit;
 	ctx->ctx.v.init = cmd_dsync_init;
@@ -498,8 +509,9 @@
 	struct dsync_cmd_context *ctx;
 
 	_ctx = cmd_dsync_alloc();
+	_ctx->getopt_args = DSYNC_COMMON_GETOPT_ARGS"R";
 	ctx = (struct dsync_cmd_context *)_ctx;
-	//FIXME
+	ctx->backup = TRUE;
 	return _ctx;
 }
 
diff -r a436e4a7503b -r 454d0563927d src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c
--- a/src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c	Sun Oct 21 08:22:20 2012 +0300
+++ b/src/doveadm/dsync/dsync-brain-mailbox-tree-sync.c	Sun Oct 21 10:01:54 2012 +0300
@@ -70,6 +70,8 @@
 	enum mail_error error;
 	int ret = -1;
 
+	i_assert(!brain->backup_send);
+
 	switch (change->type) {
 	case DSYNC_MAILBOX_TREE_SYNC_TYPE_DELETE_BOX:
 		/* make sure we're deleting the correct mailbox */
diff -r a436e4a7503b -r 454d0563927d src/doveadm/dsync/dsync-brain-mailbox-tree.c
--- a/src/doveadm/dsync/dsync-brain-mailbox-tree.c	Sun Oct 21 08:22:20 2012 +0300
+++ b/src/doveadm/dsync/dsync-brain-mailbox-tree.c	Sun Oct 21 10:01:54 2012 +0300
@@ -279,9 +279,18 @@
 {
 	struct dsync_mailbox_tree_sync_ctx *ctx;
 	const struct dsync_mailbox_tree_sync_change *change;
+	enum dsync_mailbox_trees_sync_type sync_type;
+
+	if (brain->backup_send)
+		sync_type = DSYNC_MAILBOX_TREES_SYNC_TYPE_PRESERVE_LOCAL;
+	else if (brain->backup_recv)
+		sync_type = DSYNC_MAILBOX_TREES_SYNC_TYPE_PRESERVE_REMOTE;
+	else
+		sync_type = DSYNC_MAILBOX_TREES_SYNC_TYPE_TWOWAY;
 
 	ctx = dsync_mailbox_trees_sync_init(brain->local_mailbox_tree,
-					    brain->remote_mailbox_tree);
+					    brain->remote_mailbox_tree,
+					    sync_type);
 	while ((change = dsync_mailbox_trees_sync_next(ctx)) != NULL) {
 		if (dsync_brain_mailbox_tree_sync_change(brain, change) < 0)
 			brain->failed = TRUE;
diff -r a436e4a7503b -r 454d0563927d src/doveadm/dsync/dsync-brain-mailbox.c
--- a/src/doveadm/dsync/dsync-brain-mailbox.c	Sun Oct 21 08:22:20 2012 +0300
+++ b/src/doveadm/dsync/dsync-brain-mailbox.c	Sun Oct 21 10:01:54 2012 +0300
@@ -90,11 +90,31 @@
 	}
 }
 
+void dsync_brain_sync_init_box_states(struct dsync_brain *brain)
+{
+	if (brain->backup_send) {
+		/* we have an exporter, but no importer. */
+		brain->box_send_state = DSYNC_BOX_STATE_CHANGES;
+		brain->box_recv_state = brain->guid_requests ?
+			DSYNC_BOX_STATE_MAIL_REQUESTS :
+			DSYNC_BOX_STATE_RECV_LAST_COMMON;
+	} else if (brain->backup_recv) {
+		/* we have an importer, but no exporter */
+		brain->box_send_state = brain->guid_requests ?
+			DSYNC_BOX_STATE_MAIL_REQUESTS :
+			DSYNC_BOX_STATE_DONE;
+		brain->box_recv_state = DSYNC_BOX_STATE_CHANGES;
+	} else {
+		brain->box_send_state = DSYNC_BOX_STATE_CHANGES;
+		brain->box_recv_state = DSYNC_BOX_STATE_CHANGES;
+	}
+}
+
 static int
 dsync_brain_sync_mailbox_init(struct dsync_brain *brain,
 			      struct mailbox *box,
 			      const struct dsync_mailbox *local_dsync_box,
-			      enum dsync_box_state box_state)
+			      bool wait_for_remote_box)
 {
 	enum dsync_mailbox_exporter_flags exporter_flags = 0;
 	const struct dsync_mailbox_state *state;
@@ -107,8 +127,12 @@
 
 	brain->box = box;
 	brain->pre_box_state = brain->state;
-	brain->box_recv_state = box_state;
-	brain->box_send_state = box_state;
+	if (wait_for_remote_box) {
+		brain->box_send_state = DSYNC_BOX_STATE_MAILBOX;
+		brain->box_recv_state = DSYNC_BOX_STATE_MAILBOX;
+	} else {
+		dsync_brain_sync_init_box_states(brain);
+	}
 	brain->local_dsync_box = *local_dsync_box;
 	memset(&brain->remote_dsync_box, 0, sizeof(brain->remote_dsync_box));
 
@@ -143,7 +167,8 @@
 		exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_AUTO_EXPORT_MAILS;
 	if (brain->mails_have_guids)
 		exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_MAILS_HAVE_GUIDS;
-	brain->box_exporter =
+
+	brain->box_exporter = brain->backup_recv ? NULL :
 		dsync_mailbox_export_init(box, brain->log_scan, last_common_uid,
 					  last_common_modseq, exporter_flags);
 	return 0;
@@ -181,7 +206,7 @@
 	if (brain->mails_have_guids)
 		import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_MAILS_HAVE_GUIDS;
 
-	brain->box_importer =
+	brain->box_importer = brain->backup_send ? NULL :
 		dsync_mailbox_import_init(brain->box, brain->log_scan,
 					  last_common_uid, last_common_modseq,
 					  remote_dsync_box->uid_next,
@@ -290,6 +315,7 @@
 dsync_brain_try_next_mailbox(struct dsync_brain *brain, struct mailbox **box_r,
 			     struct dsync_mailbox *dsync_box_r)
 {
+	enum mailbox_flags flags = 0;
 	struct dsync_mailbox dsync_box;
 	struct mailbox *box;
 	struct dsync_mailbox_node *node;
@@ -311,7 +337,11 @@
 		return -1;
 	}
 
-	box = mailbox_alloc(node->ns->list, vname, 0);
+	if (brain->backup_send) {
+		/* make sure mailbox isn't modified */
+		flags |= MAILBOX_FLAG_READONLY;
+	}
+	box = mailbox_alloc(node->ns->list, vname, flags);
 	for (;;) {
 		if ((ret = dsync_box_get(box, &dsync_box)) <= 0) {
 			if (ret < 0)
@@ -376,8 +406,7 @@
 
 	/* start exporting this mailbox (wait for remote to start importing) */
 	dsync_ibc_send_mailbox(brain->ibc, &dsync_box);
-	(void)dsync_brain_sync_mailbox_init(brain, box, &dsync_box,
-					    DSYNC_BOX_STATE_MAILBOX);
+	(void)dsync_brain_sync_mailbox_init(brain, box, &dsync_box, TRUE);
 	brain->state = DSYNC_STATE_SYNC_MAILS;
 }
 
@@ -582,7 +611,7 @@
 
 	/* start export/import */
 	if (dsync_brain_sync_mailbox_init(brain, box, &local_dsync_box,
-					  DSYNC_BOX_STATE_CHANGES) == 0)
+					  FALSE) == 0)
 		dsync_brain_sync_mailbox_init_remote(brain, dsync_box);
 
 	brain->state = DSYNC_STATE_SYNC_MAILS;
diff -r a436e4a7503b -r 454d0563927d src/doveadm/dsync/dsync-brain-mails.c
--- a/src/doveadm/dsync/dsync-brain-mails.c	Sun Oct 21 08:22:20 2012 +0300
+++ b/src/doveadm/dsync/dsync-brain-mails.c	Sun Oct 21 10:01:54 2012 +0300
@@ -45,10 +45,7 @@
 		return TRUE;
 	}
 	dsync_brain_sync_mailbox_init_remote(brain, dsync_box);
-	brain->box_recv_state = DSYNC_BOX_STATE_CHANGES;
-	brain->box_send_state = DSYNC_BOX_STATE_CHANGES;
-
-	i_assert(brain->box_importer != NULL);
+	dsync_brain_sync_init_box_states(brain);
 	return TRUE;
 }
 
@@ -61,8 +58,10 @@
 		return FALSE;
 	if (ret == DSYNC_IBC_RECV_RET_FINISHED) {
 		dsync_mailbox_import_changes_finish(brain->box_importer);
-		brain->box_recv_state = brain->guid_requests ?
-			DSYNC_BOX_STATE_MAIL_REQUESTS : DSYNC_BOX_STATE_MAILS;
+		if (brain->guid_requests && brain->box_exporter != NULL)
+			brain->box_recv_state = DSYNC_BOX_STATE_MAIL_REQUESTS;
+		else
+			brain->box_recv_state = DSYNC_BOX_STATE_MAILS;
 		return TRUE;
 	}
 	dsync_mailbox_import_change(brain->box_importer, change);
@@ -78,8 +77,10 @@
 			return;
 	}
 	dsync_ibc_send_end_of_list(brain->ibc);
-	brain->box_send_state = brain->guid_requests ?
-		DSYNC_BOX_STATE_MAIL_REQUESTS : DSYNC_BOX_STATE_MAILS;
+	if (brain->guid_requests && brain->box_importer != NULL)
+		brain->box_send_state = DSYNC_BOX_STATE_MAIL_REQUESTS;
+	else
+		brain->box_send_state = DSYNC_BOX_STATE_MAILS;
 }
 
 static bool dsync_brain_recv_mail_request(struct dsync_brain *brain)
@@ -88,11 +89,14 @@
 	enum dsync_ibc_recv_ret ret;
 
 	i_assert(brain->guid_requests);
+	i_assert(brain->box_exporter != NULL);
 
 	if ((ret = dsync_ibc_recv_mail_request(brain->ibc, &request)) == 0)
 		return FALSE;
 	if (ret == DSYNC_IBC_RECV_RET_FINISHED) {
-		brain->box_recv_state = DSYNC_BOX_STATE_MAILS;
+		brain->box_recv_state = brain->box_importer != NULL ?
+			DSYNC_BOX_STATE_MAILS :
+			DSYNC_BOX_STATE_RECV_LAST_COMMON;
 		return TRUE;
 	}
 	dsync_mailbox_export_want_mail(brain->box_exporter, request);
@@ -111,7 +115,12 @@
 	}
 	if (brain->box_recv_state > DSYNC_BOX_STATE_CHANGES) {
 		dsync_ibc_send_end_of_list(brain->ibc);
-		brain->box_send_state = DSYNC_BOX_STATE_MAILS;
+		if (brain->box_exporter != NULL)
+			brain->box_send_state = DSYNC_BOX_STATE_MAILS;
+		else {
+			i_assert(brain->box_recv_state != DSYNC_BOX_STATE_DONE);
+			brain->box_send_state = DSYNC_BOX_STATE_DONE;
+		}
 	}
 }
 
@@ -126,11 +135,14 @@
 		return;
 
 	/* finished with this mailbox */


More information about the dovecot-cvs mailing list