dsync-brain.c revision a6f6a702edf0c73e552e33174c8d29f5dce79555
/* Copyright (c) 2009-2011 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "hash.h"
#include "master-service.h"
#include "dsync-worker.h"
#include "dsync-brain-private.h"
#include <unistd.h>
#define DSYNC_WRONG_DIRECTION_ERROR_MSG \
"dsync backup: " \
"Looks like you're trying to run backup in wrong direction. " \
"Source is empty and destination is not."
static void
static void
struct dsync_brain *
struct dsync_worker *dest_worker,
{
struct dsync_brain *brain;
if ((flags & DSYNC_BRAIN_FLAG_VERBOSE) != 0) {
}
return brain;
}
{
}
{
ret = -1;
if (ret < 0) {
/* make sure we unreference save input streams before workers
are deinitialized, so they can destroy the streams */
}
ret = -1;
return ret;
}
{
return;
/* both lists are finished */
}
static void dsync_worker_mailbox_input(void *context)
{
int ret;
&dsync_box)) > 0) {
continue;
if (!dsync_mailbox_is_noselect(dup_box))
else
}
if (ret < 0) {
/* finished listing mailboxes */
}
}
static struct dsync_brain_mailbox_list *
struct dsync_worker *worker)
{
struct dsync_brain_mailbox_list *list;
list);
return list;
}
static void
{
}
{
return;
/* both lists are finished */
}
static int
const struct dsync_worker_subscription *s2)
{
}
static int
const struct dsync_worker_unsubscription *u2)
{
int ret;
}
static void dsync_worker_subs_input(void *context)
{
struct dsync_worker_subscription subs;
struct dsync_worker_unsubscription unsubs;
int ret;
}
if (ret == 0)
return;
&unsubs)) > 0) {
}
if (ret < 0) {
/* finished listing subscriptions */
}
}
static struct dsync_brain_subs_list *
struct dsync_worker *worker)
{
struct dsync_brain_subs_list *list;
return list;
}
static void
{
}
enum dsync_brain_mailbox_action {
};
static void
struct dsync_worker *action_worker,
struct dsync_mailbox *action_box)
{
struct dsync_mailbox new_box;
/* backup mode: switch actions */
switch (action) {
break;
break;
break;
}
}
switch (action) {
break;
new_box = *action_box;
new_box.first_recent_uid = 0;
new_box.highest_modseq = 0;
break;
else
break;
}
}
static bool
{
struct dsync_mailbox *const *boxes;
unsigned int count;
if (count == 0)
return TRUE;
boxes[0]->message_count == 0)
return TRUE;
return FALSE;
}
{
bool src_deleted, dest_deleted;
int ret;
}
GUID, so we can do this quickly. */
dest_boxes[dest]);
if (ret < 0) {
/* exists only in source */
if (!src_deleted) {
}
src++;
} else if (ret > 0) {
/* exists only in dest */
if (!dest_deleted) {
}
dest++;
} else if (src_deleted) {
/* delete from dest too */
if (!dest_deleted) {
}
} else if (dest_deleted) {
/* delete from src too */
} else {
}
}
continue;
}
continue;
}
}
{
bool src_deleted, dest_deleted;
int ret;
action_box = NULL;
if (ret < 0) {
/* exists only in source */
if (!src_deleted) {
}
src++;
} else if (ret > 0) {
/* exists only in dest */
if (!dest_deleted) {
}
dest++;
} else if (src_deleted) {
/* delete from dest too */
if (!dest_deleted) {
}
} else if (dest_deleted) {
/* delete from src too */
} else {
}
}
continue;
}
continue;
}
}
static bool
const struct dsync_worker_subscription *subs,
{
const struct dsync_worker_unsubscription *unsubs;
struct dsync_worker_unsubscription lookup;
*last_change_r = 0;
return FALSE;
return FALSE;
} else {
return TRUE;
}
}
{
const struct dsync_worker_subscription *action_subs;
struct dsync_worker *action_worker;
bool subscribe;
int ret;
/* subscriptions are sorted by name. */
if (dest == dest_count)
break;
ret = 1;
} else if (dest == dest_count) {
ret = -1;
} else {
if (ret == 0) {
continue;
}
}
if (ret < 0) {
/* subscribed only in source */
&last_change)) {
} else {
}
src++;
} else {
/* subscribed only in dest */
&last_change)) {
} else {
}
dest++;
}
/* backup mode: switch action */
}
}
}
const struct dsync_mailbox *box1,
const struct dsync_mailbox *box2)
{
}
return TRUE;
}
}
return TRUE;
}
(unsigned long long)box1->highest_modseq,
(unsigned long long)box2->highest_modseq);
}
return TRUE;
}
}
return TRUE;
}
return FALSE;
}
const struct dsync_mailbox *box1,
const struct dsync_mailbox *box2)
{
return TRUE;
}
static void
bool full_sync)
{
struct dsync_brain_mailbox *brain_box;
bool src_deleted, dest_deleted;
int ret;
if (ret == 0) {
if ((full_sync ||
dest_boxes[dest])) &&
!src_deleted && !dest_deleted) {
}
} else if (ret < 0) {
/* exists only in source */
if (!src_deleted) {
i_info("%s: only in source (guid=%s)",
}
}
src++;
} else {
/* exists only in dest */
if (!dest_deleted) {
i_info("%s: only in dest (guid=%s)",
}
}
dest++;
}
}
continue;
i_info("%s: only in source (guid=%s)",
}
}
continue;
i_info("%s: only in dest (guid=%s)",
}
}
}
{
bool ret;
if (array_count(&mailboxes) > 0) {
} else {
}
pool_unref(&pool);
return ret;
}
static void
const struct dsync_brain_mailbox *mailbox)
{
} else {
}
}
static void
{
const struct dsync_brain_mailbox *mailbox;
/* no mailboxes changed */
return;
}
/* don't update mailboxes if any changes had failed.
for example if some messages couldn't be saved, we don't
want to increase the next_uid to jump over them */
}
if (!failed_changes) {
}
}
}
{
case DSYNC_STATE_SYNC_FLUSH:
case DSYNC_STATE_SYNC_FLUSH2:
break;
default:
}
if (!success)
}
{
/* we can't safely continue, especially with backup */
return;
}
break;
break;
/* fall through */
/* fall through */
case DSYNC_STATE_SYNC_MSGS:
if (dsync_brain_sync_msgs(brain))
break;
/* no mailboxes changed */
/* wait until all saves are done, so we don't try to close
the mailbox too early */
break;
break;
/* fall through */
case DSYNC_STATE_SYNC_FLUSH:
break;
case DSYNC_STATE_SYNC_FLUSH2:
break;
case DSYNC_STATE_SYNC_END:
break;
default:
i_unreached();
}
}
{
enum dsync_state old_state;
break;
}
}
{
return brain->unexpected_changes ||
}
{
}