dovecot-2.2: Merged changes from v2.1 tree.
dovecot at dovecot.org
dovecot at dovecot.org
Mon Oct 29 17:55:55 EET 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/1b46c1bf9d1e
changeset: 15337:1b46c1bf9d1e
user: Timo Sirainen <tss at iki.fi>
date: Mon Oct 29 17:55:35 2012 +0200
description:
Merged changes from v2.1 tree.
diffstat:
configure.in | 1 +
src/auth/auth-request-handler.c | 13 +-
src/director/director-connection.c | 56 ++--
src/director/director-request.c | 75 +++++-
src/director/director.c | 48 +++-
src/director/director.h | 6 +-
src/director/main.c | 2 +-
src/director/notify-connection.c | 1 -
src/director/user-directory.c | 17 +-
src/doveadm/doveadm-mail-altmove.c | 7 +
src/doveadm/server-connection.c | 3 +-
src/lib-dict/dict-client.c | 11 +
src/lib-dict/dict-redis.c | 2 +
src/lib-index/mail-cache-compress.c | 7 +-
src/lib-index/mail-cache-fields.c | 48 ++--
src/lib-index/mail-cache-lookup.c | 27 +-
src/lib-index/mail-cache-private.h | 19 +-
src/lib-index/mail-cache-transaction.c | 17 +-
src/lib-index/mail-cache.c | 168 ++++++++++----
src/lib-index/mail-index-view-sync.c | 3 +-
src/lib-index/mail-index.h | 5 +-
src/lib-index/mail-transaction-log-file.c | 62 +++-
src/lib-index/mail-transaction-log-private.h | 4 +-
src/lib-index/mail-transaction-log.c | 13 +-
src/lib-master/master-service-settings-cache.c | 7 +-
src/lib-master/master-service.c | 1 +
src/lib-storage/index/dbox-common/dbox-file.c | 11 +-
src/lib-storage/index/dbox-common/dbox-save.c | 16 +-
src/lib-storage/index/dbox-common/dbox-storage.c | 9 +
src/lib-storage/index/dbox-multi/mdbox-save.c | 2 -
src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c | 6 +-
src/lib-storage/index/dbox-single/sdbox-save.c | 13 +-
src/lib-storage/index/dbox-single/sdbox-storage.c | 2 +-
src/lib-storage/index/index-mail.c | 51 ++--
src/lib-storage/index/index-mail.h | 2 +
src/lib-storage/index/index-storage.c | 2 +
src/lib-storage/list/mailbox-list-fs-iter.c | 27 +-
src/lib-storage/list/mailbox-list-iter.c | 5 +
src/lib-storage/list/mailbox-list-subscriptions.c | 4 +-
src/lib-storage/mail-search.c | 63 -----
src/lib-storage/mail-storage.c | 12 +-
src/lib-storage/mailbox-list.c | 17 +-
src/lib/compat.h | 4 +
src/lib/ipwd.c | 4 +
src/lmtp/lmtp-proxy.c | 1 +
src/login-common/client-common.c | 3 +
src/login-common/client-common.h | 1 +
src/plugins/fts-lucene/lucene-wrapper.cc | 3 +-
src/plugins/fts/decode2text.sh | 3 +-
src/plugins/lazy-expunge/lazy-expunge-plugin.c | 8 +-
src/plugins/quota/quota-dict.c | 14 +-
src/plugins/quota/quota-dirsize.c | 1 +
src/plugins/quota/quota-fs.c | 3 +-
src/plugins/quota/quota-maildir.c | 1 +
src/plugins/quota/quota-private.h | 2 +-
src/plugins/quota/quota-storage.c | 20 +
src/plugins/stats/stats-plugin.c | 36 +++
57 files changed, 654 insertions(+), 315 deletions(-)
diffs (truncated from 2376 to 300 lines):
diff -r 0b4b2e37b793 -r 1b46c1bf9d1e configure.in
--- a/configure.in Mon Oct 29 16:51:46 2012 +0200
+++ b/configure.in Mon Oct 29 17:55:35 2012 +0200
@@ -2178,6 +2178,7 @@
AC_CHECK_PROG(MYSQL_CONFIG, mysql_config, mysql_config, NO)
if test $MYSQL_CONFIG = NO; then
# based on code from PHP
+ MYSQL_LIBS="-lmysqlclient -lz -lm"
for i in /usr /usr/local /usr/local/mysql; do
for j in include include/mysql ""; do
if test -r "$i/$j/mysql.h"; then
diff -r 0b4b2e37b793 -r 1b46c1bf9d1e src/auth/auth-request-handler.c
--- a/src/auth/auth-request-handler.c Mon Oct 29 16:51:46 2012 +0200
+++ b/src/auth/auth-request-handler.c Mon Oct 29 17:55:35 2012 +0200
@@ -404,19 +404,18 @@
static void auth_request_timeout(struct auth_request *request)
{
- const char *str;
+ unsigned int secs = (unsigned int)(time(NULL) - request->last_access);
- str = t_strdup_printf("Request %u.%u timeouted after %u secs, state=%d",
- request->handler->client_pid, request->id,
- (unsigned int)(time(NULL) - request->last_access),
- request->state);
if (request->state != AUTH_REQUEST_STATE_MECH_CONTINUE) {
/* client's fault */
auth_request_log_error(request, request->mech->mech_name,
- "%s", str);
+ "Request %u.%u timed out after %u secs, state=%d",
+ request->handler->client_pid, request->id,
+ secs, request->state);
} else if (request->set->verbose) {
auth_request_log_info(request, request->mech->mech_name,
- "%s", str);
+ "Request timed out waiting for client to continue authentication "
+ "(%u secs)", secs);
}
auth_request_handler_remove(request->handler, request);
}
diff -r 0b4b2e37b793 -r 1b46c1bf9d1e src/director/director-connection.c
--- a/src/director/director-connection.c Mon Oct 29 16:51:46 2012 +0200
+++ b/src/director/director-connection.c Mon Oct 29 17:55:35 2012 +0200
@@ -453,12 +453,15 @@
*user_r = user_directory_add(dir->users, username_hash,
host, timestamp);
(*user_r)->weak = weak;
+ dir_debug("user refresh: %u added", username_hash);
return TRUE;
}
if (user->weak) {
if (!weak) {
/* removing user's weakness */
+ dir_debug("user refresh: %u weakness removed",
+ username_hash);
unset_weak_user = TRUE;
user->weak = FALSE;
ret = TRUE;
@@ -468,6 +471,7 @@
} else if (weak &&
!user_directory_user_is_recently_updated(dir->users, user)) {
/* mark the user as weak */
+ dir_debug("user refresh: %u set weak", username_hash);
user->weak = TRUE;
ret = TRUE;
} else if (user->host != host) {
@@ -515,6 +519,8 @@
user_directory_refresh(dir->users, user);
ret = TRUE;
}
+ dir_debug("user refresh: %u refreshed timeout to %ld",
+ username_hash, (long)user->timestamp);
if (unset_weak_user) {
/* user is no longer weak. handle pending requests for
@@ -725,8 +731,10 @@
bool weak = TRUE;
int ret;
- if ((ret = director_cmd_is_seen(conn, &args, &dir_host)) != 0)
- return ret > 0;
+ /* note that unlike other commands we don't want to just ignore
+ duplicate commands */
+ if ((ret = director_cmd_is_seen(conn, &args, &dir_host)) < 0)
+ return FALSE;
if (str_array_length(args) != 2 ||
str_to_uint(args[0], &username_hash) < 0 ||
@@ -936,7 +944,7 @@
unsigned int handshake_secs = time(NULL) - conn->created;
string_t *str;
- if (handshake_secs >= DIRECTOR_HANDSHAKE_WARN_SECS || dir->debug) {
+ if (handshake_secs >= DIRECTOR_HANDSHAKE_WARN_SECS || director_debug) {
str = t_str_new(128);
str_printfa(str, "director(%s): Handshake took %u secs, "
"bytes in=%"PRIuUOFF_T" out=%"PRIuUOFF_T,
@@ -1063,10 +1071,8 @@
/* duplicate SYNC (which was sent just in case the
previous one got lost) */
} else {
- if (dir->debug) {
- i_debug("Ring is synced (%s sent seq=%u)",
- conn->name, seq);
- }
+ dir_debug("Ring is synced (%s sent seq=%u)",
+ conn->name, seq);
director_set_ring_synced(dir);
}
} else if (dir->right != NULL) {
@@ -1128,23 +1134,18 @@
director_host_cmp_to_self(host, dir->right->host,
dir->self_host) <= 0) {
/* the old connection is the correct one */
- if (dir->debug) {
- i_debug("Ignoring CONNECT request to %s "
- "(current right is %s)",
- host->name, dir->right->name);
- }
+ dir_debug("Ignoring CONNECT request to %s (current right is %s)",
+ host->name, dir->right->name);
return TRUE;
}
- if (dir->debug) {
- if (dir->right == NULL) {
- i_debug("Received CONNECT request to %s, "
- "initializing right", host->name);
- } else {
- i_debug("Received CONNECT request to %s, "
- "replacing current right %s",
- host->name, dir->right->name);
- }
+ if (dir->right == NULL) {
+ dir_debug("Received CONNECT request to %s, "
+ "initializing right", host->name);
+ } else {
+ dir_debug("Received CONNECT request to %s, "
+ "replacing current right %s",
+ host->name, dir->right->name);
}
/* connect here */
@@ -1252,6 +1253,8 @@
const char *cmd, *const *args;
bool ret;
+ dir_debug("input: %s: %s", conn->name, line);
+
args = t_strsplit_tab(line);
cmd = args[0]; args++;
if (cmd == NULL) {
@@ -1531,9 +1534,9 @@
*_conn = NULL;
- if (dir->debug && conn->host != NULL) {
- i_debug("Disconnecting from %s: %s",
- conn->host->name, remote_reason);
+ if (conn->host != NULL) {
+ dir_debug("Disconnecting from %s: %s",
+ conn->host->name, remote_reason);
}
if (*remote_reason != '\0' &&
conn->minor_version >= DIRECTOR_VERSION_QUIT) {
@@ -1625,6 +1628,11 @@
if (conn->output->closed || !conn->connected)
return;
+ if (director_debug) T_BEGIN {
+ const char *const *lines = t_strsplit(data, "\n");
+ for (; lines[1] != NULL; lines++)
+ dir_debug("output: %s: %s", conn->name, *lines);
+ } T_END;
ret = o_stream_send(conn->output, data, len);
if (ret != (off_t)len) {
if (ret < 0)
diff -r 0b4b2e37b793 -r 1b46c1bf9d1e src/director/director-request.c
--- a/src/director/director-request.c Mon Oct 29 16:51:46 2012 +0200
+++ b/src/director/director-request.c Mon Oct 29 17:55:35 2012 +0200
@@ -12,24 +12,44 @@
#define DIRECTOR_REQUEST_TIMEOUT_SECS 30
#define RING_NOCONN_WARNING_DELAY_MSECS (2*1000)
+enum director_request_delay_reason {
+ REQUEST_DELAY_NONE = 0,
+ REQUEST_DELAY_RINGNOTHANDSHAKED,
+ REQUEST_DELAY_RINGNOTSYNCED,
+ REQUEST_DELAY_NOHOSTS,
+ REQUEST_DELAY_WEAK,
+ REQUEST_DELAY_KILL
+};
+
+static const char *delay_reason_strings[] = {
+ "unknown",
+ "ring not handshaked",
+ "ring not synced",
+ "no hosts",
+ "weak user",
+ "kill waiting"
+};
+
struct director_request {
struct director *dir;
time_t create_time;
unsigned int username_hash;
+ enum director_request_delay_reason delay_reason;
director_request_callback *callback;
void *context;
};
static const char *
-director_request_get_timeout_error(struct director_request *request)
+director_request_get_timeout_error(struct director_request *request,
+ struct user *user, string_t *str)
{
- string_t *str = t_str_new(128);
- struct user *user;
unsigned int secs;
- str_printfa(str, "Timeout - queued for %u secs (",
+ str_truncate(str, 0);
+ str_printfa(str, "Timeout because %s - queued for %u secs (",
+ delay_reason_strings[request->delay_reason],
(unsigned int)(ioloop_time - request->create_time));
if (request->dir->ring_last_sync_time == 0)
@@ -42,8 +62,6 @@
str_printfa(str, "Ring not synced for %u secs", secs);
}
- user = user_directory_lookup(request->dir->users,
- request->username_hash);
if (user != NULL) {
if (user->weak)
str_append(str, ", weak user");
@@ -57,7 +75,9 @@
static void director_request_timeout(struct director *dir)
{
struct director_request **requestp, *request;
+ struct user *user;
const char *errormsg;
+ string_t *str = t_str_new(128);
while (array_count(&dir->pending_requests) > 0) {
requestp = array_idx_modifiable(&dir->pending_requests, 0);
@@ -67,8 +87,19 @@
DIRECTOR_REQUEST_TIMEOUT_SECS > ioloop_time)
break;
+ user = user_directory_lookup(request->dir->users,
+ request->username_hash);
+ errormsg = director_request_get_timeout_error(request,
+ user, str);
+ if (user != NULL &&
+ request->delay_reason == REQUEST_DELAY_WEAK) {
+ /* weakness appears to have gotten stuck. this is a
+ bug, but try to fix it for future requests by
+ removing the weakness. */
+ user->weak = FALSE;
+ }
+
array_delete(&dir->pending_requests, 0, 1);
- errormsg = director_request_get_timeout_error(request);
T_BEGIN {
request->callback(NULL, errormsg, request->context);
} T_END;
@@ -127,13 +158,18 @@
ring_noconn_warning, dir);
}
-static bool director_request_existing(struct director *dir, struct user *user)
+static bool
+director_request_existing(struct director_request *request, struct user *user)
{
+ struct director *dir = request->dir;
struct mail_host *host;
if (user->kill_state != USER_KILL_STATE_NONE) {
/* delay processing this user's connections until
its existing connections have been killed */
+ request->delay_reason = REQUEST_DELAY_KILL;
+ dir_debug("request: %u waiting for kill to finish",
+ user->username_hash);
return FALSE;
}
if (dir->right == NULL && dir->ring_synced) {
@@ -147,6 +183,9 @@
if (user->weak) {
/* wait for user to become non-weak */
+ request->delay_reason = REQUEST_DELAY_WEAK;
+ dir_debug("request: %u waiting for weakness",
+ request->username_hash);
return FALSE;
}
if (!user_directory_user_is_near_expiring(dir->users, user))
More information about the dovecot-cvs
mailing list