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