dovecot-2.0: Mail storage service processes now sleep/die if tim...

dovecot at dovecot.org dovecot at dovecot.org
Mon Jun 22 04:38:19 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/b9f5982e68ee
changeset: 9495:b9f5982e68ee
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Jun 21 21:45:52 2009 -0400
description:
Mail storage service processes now sleep/die if time moves backwards.

diffstat:

1 file changed, 40 insertions(+)
src/lib-storage/mail-storage-service.c |   40 ++++++++++++++++++++++++++++++++

diffs (78 lines):

diff -r a442d3c40693 -r b9f5982e68ee src/lib-storage/mail-storage-service.c
--- a/src/lib-storage/mail-storage-service.c	Sun Jun 21 21:44:54 2009 -0400
+++ b/src/lib-storage/mail-storage-service.c	Sun Jun 21 21:45:52 2009 -0400
@@ -1,6 +1,7 @@
 /* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "ioloop.h"
 #include "array.h"
 #include "hostpid.h"
 #include "module-dir.h"
@@ -22,6 +23,10 @@
 #include <pwd.h>
 #include <grp.h>
 
+/* If time moves backwards more than this, kill ourself instead of sleeping. */
+#define MAX_TIME_BACKWARDS_SLEEP 5
+#define MAX_NOWARN_FORWARD_SECS 10
+
 struct mail_storage_service_multi_ctx {
 	struct master_service *service;
 	struct auth_master_connection *conn;
@@ -459,6 +464,37 @@ mail_storage_service_init_log(struct mas
 	} T_END;
 }
 
+static void mail_storage_service_time_moved(time_t old_time, time_t new_time)
+{
+	long diff = new_time - old_time;
+
+	if (diff > 0) {
+		if (diff > MAX_NOWARN_FORWARD_SECS)
+			i_warning("Time jumped forwards %ld seconds", diff);
+		return;
+	}
+	diff = -diff;
+
+	if (diff > MAX_TIME_BACKWARDS_SLEEP) {
+		i_fatal("Time just moved backwards by %ld seconds. "
+			"This might cause a lot of problems, "
+			"so I'll just kill myself now. "
+			"http://wiki.dovecot.org/TimeMovedBackwards", diff);
+	} else {
+		i_error("Time just moved backwards by %ld seconds. "
+			"I'll sleep now until we're back in present. "
+			"http://wiki.dovecot.org/TimeMovedBackwards", diff);
+		/* Sleep extra second to make sure usecs also grows. */
+		diff++;
+
+		while (diff > 0 && sleep(diff) != 0) {
+			/* don't use sleep()'s return value, because
+			   it could get us to a long loop in case
+			   interrupts just keep coming */
+			diff = old_time - time(NULL) + 1;
+		}
+	}
+}
 static struct mail_user *
 init_user_real(struct master_service *service,
 	       const struct mail_storage_service_input *_input,
@@ -476,6 +512,8 @@ init_user_real(struct master_service *se
 	unsigned int len;
 	bool userdb_lookup;
 
+	io_loop_set_time_moved_callback(current_ioloop,
+					mail_storage_service_time_moved);
 	master_service_init_finish(service);
 
 	userdb_lookup = (flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0;
@@ -583,6 +621,8 @@ mail_storage_service_multi_init(struct m
 	const struct mail_storage_settings *mail_set;
 	void **sets;
 
+	io_loop_set_time_moved_callback(current_ioloop,
+					mail_storage_service_time_moved);
 	master_service_init_finish(service);
 
 	ctx = i_new(struct mail_storage_service_multi_ctx, 1);


More information about the dovecot-cvs mailing list