dovecot-2.2: doveadm sync/backup: Added -g <guid> to sync only t...

dovecot at dovecot.org dovecot at dovecot.org
Mon Mar 25 17:02:22 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/c51873a8e0d9
changeset: 16110:c51873a8e0d9
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Mar 25 17:02:15 2013 +0200
description:
doveadm sync/backup: Added -g <guid> to sync only the specified mailbox (by GUID)
Similar to -m <mailbox name>.

diffstat:

 src/doveadm/dsync/doveadm-dsync.c            |  23 ++++++++---
 src/doveadm/dsync/dsync-brain-mailbox-tree.c |   6 ++-
 src/doveadm/dsync/dsync-brain-private.h      |   3 +-
 src/doveadm/dsync/dsync-brain.c              |   6 +++
 src/doveadm/dsync/dsync-brain.h              |   3 +
 src/doveadm/dsync/dsync-ibc-pipe.c           |   2 +
 src/doveadm/dsync/dsync-ibc-stream.c         |  13 ++++++-
 src/doveadm/dsync/dsync-ibc.h                |   2 +
 src/doveadm/dsync/dsync-mailbox-tree-fill.c  |  53 +++++++++++++++++++--------
 src/doveadm/dsync/dsync-mailbox-tree.h       |   7 ++-
 10 files changed, 88 insertions(+), 30 deletions(-)

diffs (truncated from 345 to 300 lines):

diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/doveadm-dsync.c
--- a/src/doveadm/dsync/doveadm-dsync.c	Mon Mar 25 14:18:20 2013 +0200
+++ b/src/doveadm/dsync/doveadm-dsync.c	Mon Mar 25 17:02:15 2013 +0200
@@ -36,7 +36,7 @@
 #include <ctype.h>
 #include <sys/wait.h>
 
-#define DSYNC_COMMON_GETOPT_ARGS "+dEfl:m:n:Nr:Rs:"
+#define DSYNC_COMMON_GETOPT_ARGS "+dEfg:l:m:n:Nr:Rs:"
 #define DSYNC_REMOTE_CMD_EXIT_WAIT_SECS 30
 
 enum dsync_run_type {
@@ -49,6 +49,7 @@
 	struct doveadm_mail_cmd_context ctx;
 	enum dsync_brain_sync_type sync_type;
 	const char *mailbox, *namespace_prefix;
+	guid_128_t mailbox_guid;
 	const char *state_input, *rawlog_path;
 
 	const char *remote_name;
@@ -75,6 +76,7 @@
 	unsigned int backup:1;
 	unsigned int reverse_backup:1;
 	unsigned int remote_user_prefix:1;
+	unsigned int no_mail_sync:1;
 };
 
 static bool legacy_dsync = FALSE;
@@ -468,13 +470,12 @@
 	else if (ctx->backup)
 		brain_flags |= DSYNC_BRAIN_FLAG_BACKUP_SEND;
 
+	if (ctx->no_mail_sync)
+		brain_flags |= DSYNC_BRAIN_FLAG_NO_MAIL_SYNC;
 	if (doveadm_debug)
 		brain_flags |= DSYNC_BRAIN_FLAG_DEBUG;
-	if (ctx->mailbox != NULL && *ctx->mailbox == '\0') {
-		brain_flags |= DSYNC_BRAIN_FLAG_NO_MAIL_SYNC;
-		ctx->mailbox = NULL;
-	}
 	brain = dsync_brain_master_init(user, ibc, sync_ns, ctx->mailbox,
+					ctx->mailbox_guid,
 					ctx->sync_type, brain_flags,
 					ctx->lock_timeout,
 					ctx->state_input == NULL ? "" :
@@ -766,13 +767,23 @@
 	case 'f':
 		ctx->sync_type = DSYNC_BRAIN_SYNC_TYPE_FULL;
 		break;
+	case 'g':
+		if (optarg[0] == '\0')
+			ctx->no_mail_sync = TRUE;
+		else if (guid_128_from_string(optarg, ctx->mailbox_guid) < 0 ||
+			 guid_128_is_empty(ctx->mailbox_guid))
+			i_error("Invalid -g parameter: %s", optarg);
+		break;
 	case 'l':
 		ctx->lock = TRUE;
 		if (str_to_uint(optarg, &ctx->lock_timeout) < 0)
 			i_error("Invalid -l parameter: %s", optarg);
 		break;
 	case 'm':
-		ctx->mailbox = optarg;
+		if (optarg[0] == '\0')
+			ctx->no_mail_sync = TRUE;
+		else
+			ctx->mailbox = optarg;
 		break;
 	case 'n':
 		ctx->namespace_prefix = optarg;
diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-brain-mailbox-tree.c
--- a/src/doveadm/dsync/dsync-brain-mailbox-tree.c	Mon Mar 25 14:18:20 2013 +0200
+++ b/src/doveadm/dsync/dsync-brain-mailbox-tree.c	Mon Mar 25 17:02:15 2013 +0200
@@ -85,14 +85,16 @@
 	/* fill the local mailbox tree */
 	if (brain->sync_ns != NULL) {
 		if (dsync_mailbox_tree_fill(brain->local_mailbox_tree,
-					    brain->sync_ns, brain->sync_box) < 0)
+					    brain->sync_ns, brain->sync_box,
+					    brain->sync_box_guid) < 0)
 			brain->failed = TRUE;
 	} else {
 		for (ns = brain->user->namespaces; ns != NULL; ns = ns->next) {
 			if (!dsync_brain_want_namespace(brain, ns))
 				continue;
 			if (dsync_mailbox_tree_fill(brain->local_mailbox_tree,
-						    ns, brain->sync_box) < 0)
+						    ns, brain->sync_box,
+						    brain->sync_box_guid) < 0)
 				brain->failed = TRUE;
 		}
 	}
diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-brain-private.h
--- a/src/doveadm/dsync/dsync-brain-private.h	Mon Mar 25 14:18:20 2013 +0200
+++ b/src/doveadm/dsync/dsync-brain-private.h	Mon Mar 25 17:02:15 2013 +0200
@@ -50,7 +50,8 @@
 	struct mail_user *user;
 	struct dsync_ibc *ibc;
 	struct mail_namespace *sync_ns;
-	char *sync_box;
+	const char *sync_box;
+	guid_128_t sync_box_guid;
 	enum dsync_brain_sync_type sync_type;
 
 	unsigned int lock_timeout;
diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-brain.c
--- a/src/doveadm/dsync/dsync-brain.c	Mon Mar 25 14:18:20 2013 +0200
+++ b/src/doveadm/dsync/dsync-brain.c	Mon Mar 25 17:02:15 2013 +0200
@@ -87,6 +87,7 @@
 struct dsync_brain *
 dsync_brain_master_init(struct mail_user *user, struct dsync_ibc *ibc,
 			struct mail_namespace *sync_ns, const char *sync_box,
+			const guid_128_t sync_box_guid,
 			enum dsync_brain_sync_type sync_type,
 			enum dsync_brain_flags flags, unsigned int lock_timeout,
 			const char *state)
@@ -103,6 +104,7 @@
 	if (sync_ns != NULL)
 		brain->sync_ns = sync_ns;
 	brain->sync_box = p_strdup(brain->pool, sync_box);
+	memcpy(brain->sync_box_guid, sync_box_guid, sizeof(brain->sync_box_guid));
 	brain->lock_timeout = lock_timeout;
 	brain->master_brain = TRUE;
 	dsync_brain_set_flags(brain, flags);
@@ -121,6 +123,8 @@
 	ibc_set.hostname = my_hostdomain();
 	ibc_set.sync_ns_prefix = sync_ns == NULL ? NULL : sync_ns->prefix;
 	ibc_set.sync_box = sync_box;
+	memcpy(ibc_set.sync_box_guid, sync_box_guid,
+	       sizeof(ibc_set.sync_box_guid));
 	ibc_set.sync_type = sync_type;
 	ibc_set.lock_timeout = lock_timeout;
 	/* reverse the backup direction for the slave */
@@ -302,6 +306,8 @@
 						     ibc_set->sync_ns_prefix);
 	}
 	brain->sync_box = p_strdup(brain->pool, ibc_set->sync_box);
+	memcpy(brain->sync_box_guid, ibc_set->sync_box_guid,
+	       sizeof(brain->sync_box_guid));
 	i_assert(brain->sync_type == DSYNC_BRAIN_SYNC_TYPE_UNKNOWN);
 	brain->sync_type = ibc_set->sync_type;
 	dsync_brain_set_flags(brain, ibc_set->brain_flags);
diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-brain.h
--- a/src/doveadm/dsync/dsync-brain.h	Mon Mar 25 14:18:20 2013 +0200
+++ b/src/doveadm/dsync/dsync-brain.h	Mon Mar 25 17:02:15 2013 +0200
@@ -1,6 +1,8 @@
 #ifndef DSYNC_BRAIN_H
 #define DSYNC_BRAIN_H
 
+#include "guid.h"
+
 struct mail_namespace;
 struct mail_user;
 struct dsync_ibc;
@@ -31,6 +33,7 @@
 struct dsync_brain *
 dsync_brain_master_init(struct mail_user *user, struct dsync_ibc *ibc,
 			struct mail_namespace *sync_ns, const char *sync_box,
+			const guid_128_t sync_box_guid,
 			enum dsync_brain_sync_type sync_type,
 			enum dsync_brain_flags flags, unsigned int lock_timeout,
 			const char *state);
diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-ibc-pipe.c
--- a/src/doveadm/dsync/dsync-ibc-pipe.c	Mon Mar 25 14:18:20 2013 +0200
+++ b/src/doveadm/dsync/dsync-ibc-pipe.c	Mon Mar 25 17:02:15 2013 +0200
@@ -161,6 +161,8 @@
 	item->u.set = *set;
 	item->u.set.sync_ns_prefix = p_strdup(item->pool, set->sync_ns_prefix);
 	item->u.set.sync_box = p_strdup(item->pool, set->sync_box);
+	memcpy(item->u.set.sync_box_guid, set->sync_box_guid,
+	       sizeof(item->u.set.sync_box_guid));
 }
 
 static enum dsync_ibc_recv_ret
diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-ibc-stream.c
--- a/src/doveadm/dsync/dsync-ibc-stream.c	Mon Mar 25 14:18:20 2013 +0200
+++ b/src/doveadm/dsync/dsync-ibc-stream.c	Mon Mar 25 17:02:15 2013 +0200
@@ -70,7 +70,8 @@
 	{ .name = "handshake",
 	  .chr = 'H',
 	  .required_keys = "hostname",
-	  .optional_keys = "sync_ns_prefix sync_box sync_type debug sync_visible_namespaces "
+	  .optional_keys = "sync_ns_prefix sync_box sync_box_guid sync_type "
+	  	"debug sync_visible_namespaces "
 	  	"send_mail_requests backup_send backup_recv lock_timeout"
 	},
 	{ .name = "mailbox_state",
@@ -589,6 +590,10 @@
 	}
 	if (set->sync_box != NULL)
 		dsync_serializer_encode_add(encoder, "sync_box", set->sync_box);
+	if (!guid_128_is_empty(set->sync_box_guid)) {
+		dsync_serializer_encode_add(encoder, "sync_box_guid",
+			guid_128_to_string(set->sync_box_guid));
+	}
 
 	sync_type[0] = sync_type[1] = '\0';
 	switch (set->sync_type) {
@@ -655,6 +660,12 @@
 		set->sync_ns_prefix = p_strdup(pool, value);
 	if (dsync_deserializer_decode_try(decoder, "sync_box", &value))
 		set->sync_box = p_strdup(pool, value);
+	if (dsync_deserializer_decode_try(decoder, "sync_box_guid", &value) &&
+	    guid_128_from_string(value, set->sync_box_guid) < 0) {
+		dsync_ibc_input_error(ibc, decoder,
+				      "Invalid sync_box_guid: %s", value);
+		return DSYNC_IBC_RECV_RET_TRYAGAIN;
+	}
 	if (dsync_deserializer_decode_try(decoder, "sync_type", &value)) {
 		switch (value[0]) {
 		case 'f':
diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-ibc.h
--- a/src/doveadm/dsync/dsync-ibc.h	Mon Mar 25 14:18:20 2013 +0200
+++ b/src/doveadm/dsync/dsync-ibc.h	Mon Mar 25 17:02:15 2013 +0200
@@ -37,6 +37,8 @@
 	const char *sync_ns_prefix;
 	/* if non-NULL, sync only this mailbox name */
 	const char *sync_box;
+	/* if non-empty, sync only this mailbox GUID */
+	guid_128_t sync_box_guid;
 
 	enum dsync_brain_sync_type sync_type;
 	enum dsync_brain_flags brain_flags;
diff -r acb88f199704 -r c51873a8e0d9 src/doveadm/dsync/dsync-mailbox-tree-fill.c
--- a/src/doveadm/dsync/dsync-mailbox-tree-fill.c	Mon Mar 25 14:18:20 2013 +0200
+++ b/src/doveadm/dsync/dsync-mailbox-tree-fill.c	Mon Mar 25 17:02:15 2013 +0200
@@ -31,6 +31,17 @@
 }
 
 static int
+dsync_mailbox_tree_add_exists_node(struct dsync_mailbox_tree *tree,
+				   const struct mailbox_info *info,
+				   struct dsync_mailbox_node **node_r)
+{
+	if (dsync_mailbox_tree_add_node(tree, info, node_r) < 0)
+		return -1;
+	(*node_r)->existence = DSYNC_MAILBOX_NODE_EXISTS;
+	return 0;
+}
+
+static int
 dsync_mailbox_tree_get_selectable(struct mailbox *box,
 				  struct mailbox_metadata *metadata_r,
 				  struct mailbox_status *status_r)
@@ -55,7 +66,8 @@
 }
 
 static int dsync_mailbox_tree_add(struct dsync_mailbox_tree *tree,
-				  const struct mailbox_info *info)
+				  const struct mailbox_info *info,
+				  const guid_128_t box_guid)
 {
 	struct dsync_mailbox_node *node;
 	struct mailbox *box;
@@ -63,16 +75,14 @@
 	struct mailbox_status status;
 	const char *errstr;
 	enum mail_error error;
+	int ret = 0;
 
 	if ((info->flags & MAILBOX_NONEXISTENT) != 0)
 		return 0;
-
-	if (dsync_mailbox_tree_add_node(tree, info, &node) < 0)
-		return -1;
-	node->existence = DSYNC_MAILBOX_NODE_EXISTS;
-
-	if ((info->flags & MAILBOX_NOSELECT) != 0)
-		return 0;
+	if ((info->flags & MAILBOX_NOSELECT) != 0) {
+		return !guid_128_is_empty(box_guid) ? 0 :
+			dsync_mailbox_tree_add_exists_node(tree, info, &node);
+	}
 
 	/* get GUID and UIDVALIDITY for selectable mailbox */
 	box = mailbox_alloc(info->ns->list, info->vname, 0);
@@ -88,16 +98,24 @@
 		default:
 			i_error("Failed to access mailbox %s: %s",
 				info->vname, errstr);
-			mailbox_free(&box);
-			return -1;
+			ret = -1;
 		}
-	} else {
-		memcpy(node->mailbox_guid, metadata.guid,
-		       sizeof(node->mailbox_guid));
-		node->uid_validity = status.uidvalidity;
-		node->uid_next = status.uidnext;
+		mailbox_free(&box);
+		return ret;
 	}
 	mailbox_free(&box);
+
+	if (!guid_128_is_empty(box_guid) &&
+	    !guid_128_equals(box_guid, metadata.guid)) {
+		/* unwanted mailbox */
+		return 0;
+	}
+	if (dsync_mailbox_tree_add_exists_node(tree, info, &node) < 0)


More information about the dovecot-cvs mailing list