dovecot-2.2: replicator: Have remote dsync notify the replicator...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Apr 7 14:46:51 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/f1ba737bc241
changeset: 16217:f1ba737bc241
user: Timo Sirainen <tss at iki.fi>
date: Sun Apr 07 14:46:45 2013 +0300
description:
replicator: Have remote dsync notify the replicator that the user was just synced.
This way the replicators are roughly in sync.
diffstat:
src/doveadm/dsync/doveadm-dsync.c | 58 ++++++++++++++++++++++--
src/replication/replicator/doveadm-connection.c | 28 ++++++++++++
src/replication/replicator/dsync-client.c | 2 +-
3 files changed, 82 insertions(+), 6 deletions(-)
diffs (170 lines):
diff -r 9824f8df62a3 -r f1ba737bc241 src/doveadm/dsync/doveadm-dsync.c
--- a/src/doveadm/dsync/doveadm-dsync.c Sat Apr 06 21:01:41 2013 +0300
+++ b/src/doveadm/dsync/doveadm-dsync.c Sun Apr 07 14:46:45 2013 +0300
@@ -36,7 +36,7 @@
#include <ctype.h>
#include <sys/wait.h>
-#define DSYNC_COMMON_GETOPT_ARGS "+dEfg:l:m:n:Nr:Rs:"
+#define DSYNC_COMMON_GETOPT_ARGS "+dEfg:l:m:n:Nr:Rs:U"
#define DSYNC_REMOTE_CMD_EXIT_WAIT_SECS 30
enum dsync_run_type {
@@ -78,6 +78,7 @@
unsigned int remote_user_prefix:1;
unsigned int no_mail_sync:1;
unsigned int local_location_from_arg:1;
+ unsigned int replicator_notify:1;
};
static bool legacy_dsync = FALSE;
@@ -441,6 +442,42 @@
name, temp_prefix);
}
+static void
+dsync_replicator_notify(struct dsync_cmd_context *ctx, const char *state_str)
+{
+#define REPLICATOR_HANDSHAKE "VERSION\treplicator-doveadm-client\t1\t0\n"
+ const char *path;
+ string_t *str;
+ int fd;
+
+ path = t_strdup_printf("%s/replicator-doveadm",
+ ctx->ctx.cur_mail_user->set->base_dir);
+ fd = net_connect_unix(path);
+ if (fd == -1) {
+ if (errno == ECONNREFUSED || errno == ENOENT) {
+ /* replicator not running on this server. ignore. */
+ return;
+ }
+ i_error("net_connect_unix(%s) failed: %m", path);
+ return;
+ }
+ str = t_str_new(128);
+ str_append(str, REPLICATOR_HANDSHAKE"NOTIFY\t");
+ str_append_tabescaped(str, ctx->ctx.cur_mail_user->username);
+ str_append_c(str, '\t');
+ if (ctx->sync_type == DSYNC_BRAIN_SYNC_TYPE_FULL)
+ str_append_c(str, 'f');
+ str_append_c(str, '\t');
+ str_append_tabescaped(str, state_str);
+ str_append_c(str, '\n');
+ if (write_full(fd, str_data(str), str_len(str)) < 0)
+ i_error("write(%s) failed: %m", path);
+ /* we only wanted to notify replicator. we don't care enough about the
+ answer to wait for it. */
+ if (close(fd) < 0)
+ i_error("close(%s) failed: %m", path);
+}
+
static int
cmd_dsync_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
{
@@ -450,6 +487,7 @@
struct mail_namespace *sync_ns = NULL;
enum dsync_brain_flags brain_flags;
bool remote_errors_logged = FALSE;
+ string_t *state_str = NULL;
int status = 0, ret = 0;
user->admin = TRUE;
@@ -501,13 +539,15 @@
}
if (ctx->state_input != NULL) {
- string_t *str = t_str_new(128);
- dsync_brain_get_state(brain, str);
- doveadm_print(str_c(str));
+ state_str = t_str_new(128);
+ dsync_brain_get_state(brain, state_str);
+ doveadm_print(str_c(state_str));
}
- if (dsync_brain_deinit(&brain) < 0)
+ if (dsync_brain_deinit(&brain) < 0) {
ctx->ctx.exit_code = EX_TEMPFAIL;
+ ret = -1;
+ }
dsync_ibc_deinit(&ibc);
if (ibc2 != NULL)
dsync_ibc_deinit(&ibc2);
@@ -540,6 +580,11 @@
i_close_fd(&ctx->fd_err);
ctx->input = NULL;
ctx->output = NULL;
+
+ if (ctx->replicator_notify) {
+ dsync_replicator_notify(ctx, state_str == NULL ? "" :
+ str_c(state_str));
+ }
return ret;
}
@@ -820,6 +865,9 @@
ctx->sync_type = DSYNC_BRAIN_SYNC_TYPE_STATE;
ctx->state_input = optarg;
break;
+ case 'U':
+ ctx->replicator_notify = TRUE;
+ break;
default:
return FALSE;
}
diff -r 9824f8df62a3 -r f1ba737bc241 src/replication/replicator/doveadm-connection.c
--- a/src/replication/replicator/doveadm-connection.c Sat Apr 06 21:01:41 2013 +0300
+++ b/src/replication/replicator/doveadm-connection.c Sun Apr 07 14:46:45 2013 +0300
@@ -137,6 +137,32 @@
return 0;
}
+static int
+client_input_notify(struct doveadm_connection *client, const char *const *args)
+{
+ struct replicator_user *user;
+
+ /* <username> <flags> <state> */
+ if (str_array_length(args) < 3) {
+ i_error("%s: NOTIFY: Invalid parameters", client->conn.name);
+ return -1;
+ }
+
+ user = replicator_queue_add(client->queue, args[0],
+ REPLICATION_PRIORITY_NONE);
+ if (args[1][0] == 'f')
+ user->last_full_sync = ioloop_time;
+ user->last_fast_sync = ioloop_time;
+ user->last_update = ioloop_time;
+
+ if (args[2][0] != '\0') {
+ i_free(user->state);
+ user->state = i_strdup(args[2]);
+ }
+ o_stream_send_str(client->conn.output, "+\n");
+ return 0;
+}
+
static int client_input_args(struct connection *conn, const char *const *args)
{
struct doveadm_connection *client = (struct doveadm_connection *)conn;
@@ -152,6 +178,8 @@
return client_input_status(client, args);
else if (strcmp(cmd, "REPLICATE") == 0)
return client_input_replicate(client, args);
+ else if (strcmp(cmd, "NOTIFY") == 0)
+ return client_input_notify(client, args);
i_error("%s: Unknown command: %s", conn->name, cmd);
return -1;
}
diff -r 9824f8df62a3 -r f1ba737bc241 src/replication/replicator/dsync-client.c
--- a/src/replication/replicator/dsync-client.c Sat Apr 06 21:01:41 2013 +0300
+++ b/src/replication/replicator/dsync-client.c Sun Apr 07 14:46:45 2013 +0300
@@ -209,7 +209,7 @@
str_printfa(cmd, "\tsync\t-d\t-N\t-l\t%u", DSYNC_LOCK_TIMEOUT_SECS);
if (full)
str_append(cmd, "\t-f");
- str_append(cmd, "\t-s\t");
+ str_append(cmd, "\t-U\t-s\t");
if (state != NULL)
str_append(cmd, state);
str_append_c(cmd, '\n');
More information about the dovecot-cvs
mailing list