]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync backup: Handle better deletion of mailboxes from destination.
authorTimo Sirainen <tss@iki.fi>
Wed, 23 Mar 2011 22:01:16 +0000 (00:01 +0200)
committerTimo Sirainen <tss@iki.fi>
Wed, 23 Mar 2011 22:01:16 +0000 (00:01 +0200)
src/dsync/dsync-worker-local.c

index 1b26f04153f06a9a00875ab66b8237c3cca01712..95b3946eab86fe875fe001ec80340933ec63ea7e 100644 (file)
@@ -49,6 +49,7 @@ struct local_dsync_mailbox {
        struct mail_namespace *ns;
        mailbox_guid_t guid;
        const char *storage_name;
+       bool deleted;
 };
 
 struct local_dsync_mailbox_change {
@@ -797,6 +798,10 @@ static int local_mailbox_open(struct local_dsync_worker *worker,
                        dsync_guid_to_str(guid));
                return -1;
        }
+       if (lbox->deleted) {
+               *box_r = NULL;
+               return 0;
+       }
 
        box = mailbox_alloc(lbox->ns->list, lbox->storage_name, flags);
        if (mailbox_sync(box, 0) < 0 ||
@@ -817,7 +822,7 @@ static int local_mailbox_open(struct local_dsync_worker *worker,
                return -1;
        }
        *box_r = box;
-       return 0;
+       return 1;
 }
 
 static int iter_local_mailbox_open(struct local_dsync_worker_msg_iter *iter)
@@ -828,14 +833,22 @@ static int iter_local_mailbox_open(struct local_dsync_worker_msg_iter *iter)
        struct mailbox *box;
        struct mailbox_transaction_context *trans;
        struct mail_search_args *search_args;
+       int ret;
 
-       if (iter->mailbox_idx == iter->mailbox_count) {
-               /* no more mailboxes */
-               return -1;
-       }
+       for (;;) {
+               if (iter->mailbox_idx == iter->mailbox_count) {
+                       /* no more mailboxes */
+                       return -1;
+               }
 
-       guid = &iter->mailboxes[iter->mailbox_idx];
-       if (local_mailbox_open(worker, guid, &box) < 0) {
+               guid = &iter->mailboxes[iter->mailbox_idx];
+               ret = local_mailbox_open(worker, guid, &box);
+               if (ret != 0)
+                       break;
+               /* mailbox was deleted. try next one. */
+               iter->mailbox_idx++;
+       }
+       if (ret < 0) {
                i_error("msg iteration failed: Couldn't open mailbox %s",
                        dsync_guid_to_str(guid));
                iter->iter.failed = TRUE;
@@ -1282,6 +1295,8 @@ local_worker_delete_mailbox(struct dsync_worker *_worker,
                i_error("Can't delete mailbox %s: %s", lbox->storage_name,
                        mail_storage_get_last_error(storage, NULL));
                dsync_worker_set_failure(_worker);
+       } else {
+               lbox->deleted = TRUE;
        }
        mailbox_free(&box);
        mailbox_list_set_changelog_timestamp(lbox->ns->list, (time_t)-1);
@@ -1492,7 +1507,7 @@ local_worker_select_mailbox(struct dsync_worker *_worker,
                local_worker_mailbox_close(worker);
        worker->selected_box_guid = *mailbox;
 
-       if (local_mailbox_open(worker, mailbox, &worker->selected_box) < 0) {
+       if (local_mailbox_open(worker, mailbox, &worker->selected_box) <= 0) {
                dsync_worker_set_failure(_worker);
                return;
        }
@@ -1601,7 +1616,7 @@ local_worker_msg_copy(struct dsync_worker *_worker,
        struct mail_save_context *save_ctx;
        int ret;
 
-       if (local_mailbox_open(worker, src_mailbox, &src_box) < 0) {
+       if (local_mailbox_open(worker, src_mailbox, &src_box) <= 0) {
                callback(FALSE, context);
                return;
        }
@@ -1793,7 +1808,7 @@ local_worker_msg_get_next(struct local_dsync_worker *worker,
 
        if (!dsync_guid_equals(&worker->get_mailbox, &get->mailbox)) {
                local_worker_msg_box_close(worker);
-               if (local_mailbox_open(worker, &get->mailbox, &box) < 0) {
+               if (local_mailbox_open(worker, &get->mailbox, &box) <= 0) {
                        get->callback(DSYNC_MSG_GET_RESULT_FAILED,
                                      NULL, get->context);
                        return;