dovecot-2.1: director: If request is timed out, log an error.
dovecot at dovecot.org
dovecot at dovecot.org
Tue Jan 10 21:38:03 EET 2012
details: http://hg.dovecot.org/dovecot-2.1/rev/c70965e8b27d
changeset: 13921:c70965e8b27d
user: Timo Sirainen <tss at iki.fi>
date: Tue Jan 10 21:37:54 2012 +0200
description:
director: If request is timed out, log an error.
diffstat:
src/director/director-connection.c | 4 ++--
src/director/director-request.c | 33 +++++++++++++++++++++++++++++++--
src/director/director-request.h | 3 ++-
src/director/director.c | 11 ++++++++++-
src/director/director.h | 2 ++
src/director/login-connection.c | 35 +++++++++++++++++++----------------
6 files changed, 66 insertions(+), 22 deletions(-)
diffs (218 lines):
diff -r ee7b18b1fc00 -r c70965e8b27d src/director/director-connection.c
--- a/src/director/director-connection.c Tue Jan 10 13:12:08 2012 +0200
+++ b/src/director/director-connection.c Tue Jan 10 21:37:54 2012 +0200
@@ -570,7 +570,7 @@
/* we're connected to both directors. see if the ring is
finished by sending a SYNC. if we get it back, it's done. */
dir->sync_seq++;
- dir->ring_synced = FALSE;
+ director_set_ring_unsynced(dir);
director_connection_send(dir->right,
t_strdup_printf("SYNC\t%s\t%u\t%u\n",
net_ip2addr(&dir->self_ip),
@@ -1130,7 +1130,7 @@
if (dir->left == NULL || dir->right == NULL) {
/* we aren't synced until we're again connected to a ring */
dir->sync_seq++;
- dir->ring_synced = FALSE;
+ director_set_ring_unsynced(dir);
}
}
diff -r ee7b18b1fc00 -r c70965e8b27d src/director/director-request.c
--- a/src/director/director-request.c Tue Jan 10 13:12:08 2012 +0200
+++ b/src/director/director-request.c Tue Jan 10 21:37:54 2012 +0200
@@ -3,6 +3,7 @@
#include "lib.h"
#include "ioloop.h"
#include "array.h"
+#include "str.h"
#include "mail-host.h"
#include "user-directory.h"
#include "director.h"
@@ -21,9 +22,32 @@
void *context;
};
+static const char *
+director_request_get_timeout_error(struct director_request *request)
+{
+ string_t *str = t_str_new(128);
+ unsigned int secs;
+
+ str_printfa(str, "Timeout - queued for %u secs (",
+ (unsigned int)(ioloop_time - request->create_time));
+
+ if (request->dir->ring_last_sync_time == 0)
+ str_append(str, "Ring has never been synced");
+ else {
+ secs =ioloop_time - request->dir->ring_last_sync_time;
+ if (request->dir->ring_synced)
+ str_printfa(str, "Ring synced for %u secs", secs);
+ else
+ str_printfa(str, "Ring not synced for %u secs", secs);
+ }
+ str_append_c(str, ')');
+ return str_c(str);
+}
+
static void director_request_timeout(struct director *dir)
{
struct director_request **requestp, *request;
+ const char *errormsg;
while (array_count(&dir->pending_requests) > 0) {
requestp = array_idx_modifiable(&dir->pending_requests, 0);
@@ -34,7 +58,10 @@
break;
array_delete(&dir->pending_requests, 0, 1);
- request->callback(NULL, request->context);
+ errormsg = director_request_get_timeout_error(request);
+ T_BEGIN {
+ request->callback(NULL, errormsg, request->context);
+ } T_END;
i_free(request);
}
@@ -126,7 +153,9 @@
}
director_update_user(dir, dir->self_host, user);
- request->callback(&user->host->ip, request->context);
+ T_BEGIN {
+ request->callback(&user->host->ip, NULL, request->context);
+ } T_END;
i_free(request);
return TRUE;
}
diff -r ee7b18b1fc00 -r c70965e8b27d src/director/director-request.h
--- a/src/director/director-request.h Tue Jan 10 13:12:08 2012 +0200
+++ b/src/director/director-request.h Tue Jan 10 21:37:54 2012 +0200
@@ -5,7 +5,8 @@
struct director_request;
typedef void
-director_request_callback(const struct ip_addr *ip, void *context);
+director_request_callback(const struct ip_addr *ip, const char *errormsg,
+ void *context);
void director_request(struct director *dir, const char *username,
director_request_callback *callback, void *context);
diff -r ee7b18b1fc00 -r c70965e8b27d src/director/director.c
--- a/src/director/director.c Tue Jan 10 13:12:08 2012 +0200
+++ b/src/director/director.c Tue Jan 10 21:37:54 2012 +0200
@@ -226,9 +226,18 @@
}
dir->ring_synced = TRUE;
+ dir->ring_last_sync_time = ioloop_time;
director_set_state_changed(dir);
}
+void director_set_ring_unsynced(struct director *dir)
+{
+ if (dir->ring_synced) {
+ dir->ring_synced = FALSE;
+ dir->ring_last_sync_time = ioloop_time;
+ }
+}
+
static void director_sync(struct director *dir)
{
if (dir->sync_frozen) {
@@ -243,7 +252,7 @@
/* we're synced again when we receive this SYNC back */
dir->sync_seq++;
- dir->ring_synced = FALSE;
+ director_set_ring_unsynced(dir);
if (dir->debug) {
i_debug("Ring is desynced (seq=%u, sending SYNC to %s)",
diff -r ee7b18b1fc00 -r c70965e8b27d src/director/director.h
--- a/src/director/director.h Tue Jan 10 13:12:08 2012 +0200
+++ b/src/director/director.h Tue Jan 10 21:37:54 2012 +0200
@@ -45,6 +45,7 @@
struct ipc_client *ipc_proxy;
unsigned int sync_seq;
+ time_t ring_last_sync_time;
/* director ring handshaking is complete.
director can start serving clients. */
@@ -71,6 +72,7 @@
void director_set_ring_handshaked(struct director *dir);
void director_set_ring_synced(struct director *dir);
+void director_set_ring_unsynced(struct director *dir);
void director_set_state_changed(struct director *dir);
void director_update_host(struct director *dir, struct director_host *src,
diff -r ee7b18b1fc00 -r c70965e8b27d src/director/login-connection.c
--- a/src/director/login-connection.c Tue Jan 10 13:12:08 2012 +0200
+++ b/src/director/login-connection.c Tue Jan 10 21:37:54 2012 +0200
@@ -30,7 +30,7 @@
struct login_host_request {
struct login_connection *conn;
- char *line;
+ char *line, *username;
};
static struct login_connection *login_connections;
@@ -70,29 +70,31 @@
(void)o_stream_sendv(conn->output, iov, N_ELEMENTS(iov));
}
-static void login_host_callback(const struct ip_addr *ip, void *context)
+static void
+login_host_callback(const struct ip_addr *ip, const char *errormsg,
+ void *context)
{
struct login_host_request *request = context;
struct director *dir = request->conn->dir;
const char *line;
unsigned int secs;
- T_BEGIN {
- if (ip != NULL) {
- secs = dir->set->director_user_expire / 2;
- line = t_strdup_printf("%s\thost=%s\tproxy_refresh=%u",
- request->line, net_ip2addr(ip),
- secs);
- } else {
- i_assert(strncmp(request->line, "OK\t", 3) == 0);
- line = t_strconcat("FAIL\t",
- t_strcut(request->line + 3, '\t'),
- "\ttemp", NULL);
- }
- login_connection_send_line(request->conn, line);
- } T_END;
+ if (ip != NULL) {
+ secs = dir->set->director_user_expire / 2;
+ line = t_strdup_printf("%s\thost=%s\tproxy_refresh=%u",
+ request->line, net_ip2addr(ip), secs);
+ } else {
+ i_assert(strncmp(request->line, "OK\t", 3) == 0);
+
+ i_error("director: User %s host lookup failed: %s",
+ request->username, errormsg);
+ line = t_strconcat("FAIL\t", t_strcut(request->line + 3, '\t'),
+ "\ttemp", NULL);
+ }
+ login_connection_send_line(request->conn, line);
login_connection_unref(&request->conn);
+ i_free(request->username);
i_free(request->line);
i_free(request);
}
@@ -155,6 +157,7 @@
request = i_new(struct login_host_request, 1);
request->conn = conn;
request->line = i_strdup(line);
+ request->username = i_strdup(username);
conn->refcount++;
director_request(conn->dir, username, login_host_callback, request);
More information about the dovecot-cvs
mailing list