]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: Added -P parameter to do a purge for the remote storage after syncing.
authorTimo Sirainen <tss@iki.fi>
Sat, 21 Sep 2013 22:09:32 +0000 (01:09 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 21 Sep 2013 22:09:32 +0000 (01:09 +0300)
src/doveadm/dsync/doveadm-dsync.c
src/doveadm/dsync/dsync-brain-private.h
src/doveadm/dsync/dsync-brain.c
src/doveadm/dsync/dsync-brain.h
src/doveadm/dsync/dsync-ibc-stream.c

index aa95de56a1fb45315d359f8dad1635277fdde170..da5409c39aba4c380d2058a16e51a53d074126b4 100644 (file)
@@ -36,7 +36,7 @@
 #include <ctype.h>
 #include <sys/wait.h>
 
-#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;
index acfabc560e4fef675603196485e1fcd32fcc2d50..ae565010fab6849f95c49cdda87679ce6a6c8ba3 100644 (file)
@@ -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;
index e623529ed9781d169711acce030f6fe787c00112..1b991eec81f2c2fe5545c65f26ac436b80eb204e 100644 (file)
@@ -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);
 
index 8884e8bcfe6850984b3c4158329e62a5db85f509..5f3360c0d998884033d27bc38cc3964468913e82 100644 (file)
@@ -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 {
index 4d7d42ec1cfb8ef8dce8eef170dd642ff369d450..ac4523854f5e85df3fd043d496547f79d8acca0e 100644 (file)
@@ -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;