From: Timo Sirainen Date: Sat, 21 Sep 2013 22:09:32 +0000 (+0300) Subject: dsync: Added -P parameter to do a purge for the remote storage after syncing. X-Git-Tag: 2.2.6~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d0ff92b81b05166d800e04bbd2054a664305a330;p=thirdparty%2Fdovecot%2Fcore.git dsync: Added -P parameter to do a purge for the remote storage after syncing. --- diff --git a/src/doveadm/dsync/doveadm-dsync.c b/src/doveadm/dsync/doveadm-dsync.c index aa95de56a1..da5409c39a 100644 --- a/src/doveadm/dsync/doveadm-dsync.c +++ b/src/doveadm/dsync/doveadm-dsync.c @@ -36,7 +36,7 @@ #include #include -#define DSYNC_COMMON_GETOPT_ARGS "+1dEfg:l:m:n:Nr:Rs:Ux:" +#define DSYNC_COMMON_GETOPT_ARGS "+1dEfg:l:m:n:NPr:Rs:Ux:" #define DSYNC_REMOTE_CMD_EXIT_WAIT_SECS 30 /* The broken_char is mainly set to get a proper error message when trying to convert a mailbox with a name that can't be used properly translated between @@ -78,6 +78,7 @@ struct dsync_cmd_context { unsigned int lock_timeout; unsigned int lock:1; + unsigned int purge_remote:1; unsigned int sync_visible_namespaces:1; unsigned int default_replica_location:1; unsigned int oneway:1; @@ -364,6 +365,7 @@ cmd_dsync_run_local(struct dsync_cmd_context *ctx, struct mail_user *user, } brain2 = dsync_brain_slave_init(user2, ibc2, TRUE); + mail_user_unref(&user2); brain1_running = brain2_running = TRUE; changed1 = changed2 = TRUE; @@ -376,7 +378,6 @@ cmd_dsync_run_local(struct dsync_cmd_context *ctx, struct mail_user *user, brain1_running = dsync_brain_run(brain, &changed1); brain2_running = dsync_brain_run(brain2, &changed2); } - mail_user_unref(&user2); *changes_during_sync_r = dsync_brain_has_unexpected_changes(brain2); if (dsync_brain_deinit(&brain2) < 0) { ctx->ctx.exit_code = EX_TEMPFAIL; @@ -545,6 +546,8 @@ cmd_dsync_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) brain_flags = DSYNC_BRAIN_FLAG_SEND_MAIL_REQUESTS; if (ctx->sync_visible_namespaces) brain_flags |= DSYNC_BRAIN_FLAG_SYNC_VISIBLE_NAMESPACES; + if (ctx->purge_remote) + brain_flags |= DSYNC_BRAIN_FLAG_PURGE_REMOTE; if (ctx->reverse_backup) brain_flags |= DSYNC_BRAIN_FLAG_BACKUP_RECV; @@ -904,6 +907,9 @@ cmd_mailbox_dsync_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c) case 'N': ctx->sync_visible_namespaces = TRUE; break; + case 'P': + ctx->purge_remote = TRUE; + break; case 'r': ctx->rawlog_path = optarg; break; diff --git a/src/doveadm/dsync/dsync-brain-private.h b/src/doveadm/dsync/dsync-brain-private.h index acfabc560e..ae565010fa 100644 --- a/src/doveadm/dsync/dsync-brain-private.h +++ b/src/doveadm/dsync/dsync-brain-private.h @@ -92,6 +92,7 @@ struct dsync_brain { unsigned int mail_requests:1; unsigned int backup_send:1; unsigned int backup_recv:1; + unsigned int purge:1; unsigned int debug:1; unsigned int sync_visible_namespaces:1; unsigned int no_mail_sync:1; diff --git a/src/doveadm/dsync/dsync-brain.c b/src/doveadm/dsync/dsync-brain.c index e623529ed9..1b991eec81 100644 --- a/src/doveadm/dsync/dsync-brain.c +++ b/src/doveadm/dsync/dsync-brain.c @@ -104,6 +104,7 @@ dsync_brain_common_init(struct mail_user *user, struct dsync_ibc *ibc) pool_t pool; service_set = master_service_settings_get(master_service); + mail_user_ref(user); pool = pool_alloconly_create("dsync brain", 10240); brain = p_new(pool, struct dsync_brain, 1); @@ -220,6 +221,23 @@ dsync_brain_slave_init(struct mail_user *user, struct dsync_ibc *ibc, return brain; } +static void dsync_brain_purge(struct dsync_brain *brain) +{ + struct mail_namespace *ns; + struct mail_storage *storage; + + for (ns = brain->user->namespaces; ns != NULL; ns = ns->next) { + if (!dsync_brain_want_namespace(brain, ns)) + continue; + + storage = mail_namespace_get_default_storage(ns); + if (mail_storage_purge(storage) < 0) { + i_error("Purging namespace '%s' failed: %s", ns->prefix, + mail_storage_get_last_error(storage, NULL)); + } + } +} + int dsync_brain_deinit(struct dsync_brain **_brain) { struct dsync_brain *brain = *_brain; @@ -240,6 +258,9 @@ int dsync_brain_deinit(struct dsync_brain **_brain) brain->failed = TRUE; dsync_ibc_close_mail_streams(brain->ibc); + if (brain->purge && !brain->failed) + dsync_brain_purge(brain); + if (brain->box != NULL) dsync_brain_sync_mailbox_deinit(brain); if (brain->local_tree_iter != NULL) @@ -261,6 +282,7 @@ int dsync_brain_deinit(struct dsync_brain **_brain) } ret = brain->failed ? -1 : 0; + mail_user_unref(&brain->user); pool_unref(&brain->pool); return ret; } @@ -383,7 +405,11 @@ static bool dsync_brain_slave_recv_handshake(struct dsync_brain *brain) 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); + /* this flag is only set on the remote slave brain */ + brain->purge = (ibc_set->brain_flags & + DSYNC_BRAIN_FLAG_PURGE_REMOTE) != 0; dsync_brain_mailbox_trees_init(brain); diff --git a/src/doveadm/dsync/dsync-brain.h b/src/doveadm/dsync/dsync-brain.h index 8884e8bcfe..5f3360c0d9 100644 --- a/src/doveadm/dsync/dsync-brain.h +++ b/src/doveadm/dsync/dsync-brain.h @@ -19,7 +19,10 @@ enum dsync_brain_flags { /* Used with BACKUP_SEND/RECV: Don't force the Use the two-way syncing algorithm, but don't actually modify anything locally. (Useful during migration.) */ - DSYNC_BRAIN_FLAG_NO_BACKUP_OVERWRITE = 0x40 + DSYNC_BRAIN_FLAG_NO_BACKUP_OVERWRITE = 0x40, + /* Run storage purge on the remote after syncing. + Useful with e.g. a nightly doveadm backup. */ + DSYNC_BRAIN_FLAG_PURGE_REMOTE = 0x80 }; enum dsync_brain_sync_type { diff --git a/src/doveadm/dsync/dsync-ibc-stream.c b/src/doveadm/dsync/dsync-ibc-stream.c index 4d7d42ec1c..ac4523854f 100644 --- a/src/doveadm/dsync/dsync-ibc-stream.c +++ b/src/doveadm/dsync/dsync-ibc-stream.c @@ -75,7 +75,7 @@ static const struct { .optional_keys = "sync_ns_prefix sync_box sync_box_guid sync_type " "debug sync_visible_namespaces exclude_mailboxes " "send_mail_requests backup_send backup_recv lock_timeout " - "no_mail_sync no_backup_overwrite" + "no_mail_sync no_backup_overwrite purge_remote" }, { .name = "mailbox_state", .chr = 'S', @@ -660,6 +660,8 @@ dsync_ibc_stream_send_handshake(struct dsync_ibc *_ibc, dsync_serializer_encode_add(encoder, "no_mail_sync", ""); if ((set->brain_flags & DSYNC_BRAIN_FLAG_NO_BACKUP_OVERWRITE) != 0) dsync_serializer_encode_add(encoder, "no_backup_overwrite", ""); + if ((set->brain_flags & DSYNC_BRAIN_FLAG_PURGE_REMOTE) != 0) + dsync_serializer_encode_add(encoder, "purge_remote", ""); dsync_serializer_encode_finish(&encoder, str); dsync_ibc_stream_send_string(ibc, str); @@ -750,6 +752,8 @@ dsync_ibc_stream_recv_handshake(struct dsync_ibc *_ibc, set->brain_flags |= DSYNC_BRAIN_FLAG_NO_MAIL_SYNC; if (dsync_deserializer_decode_try(decoder, "no_backup_overwrite", &value)) set->brain_flags |= DSYNC_BRAIN_FLAG_NO_BACKUP_OVERWRITE; + if (dsync_deserializer_decode_try(decoder, "purge_remote", &value)) + set->brain_flags |= DSYNC_BRAIN_FLAG_PURGE_REMOTE; *set_r = set; return DSYNC_IBC_RECV_RET_OK;