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