Cautiously added ENABLE_DISABLE_FSYNC and disable_fsync, hedged about
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 22 Jan 2007 16:29:54 +0000 (16:29 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 22 Jan 2007 16:29:54 +0000 (16:29 +0000)
with much warning text.

13 files changed:
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/EDITME
src/src/config.h.defaults
src/src/deliver.c
src/src/exim.h
src/src/globals.c
src/src/globals.h
src/src/readconf.c
src/src/receive.c
src/src/spool_out.c
src/src/transports/appendfile.c
src/src/transports/smtp.c

index 4c7f8a1676dcf18498cb594e36ee6e6806e679aa..6db4096a781d3964f9303816985cec0a99285567 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.456 2007/01/22 15:56:47 steve Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.457 2007/01/22 16:29:54 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -29,6 +29,10 @@ PH/03 Added additional dnslists conditions == and =& which are different from
 PH/04 Added gnutls_require_{kx,mac,protocols} to give more control over the
       cipher suites used by GnuTLS. These options are ignored by OpenSSL.
 
 PH/04 Added gnutls_require_{kx,mac,protocols} to give more control over the
       cipher suites used by GnuTLS. These options are ignored by OpenSSL.
 
+PH/05 After discussion on the list, added a compile time option ENABLE_DISABLE_
+      FSYNC, which compiles an option called disable_fsync that allows for
+      bypassing fsync(). The documentation is heavily laced with warnings.
+
 SC/01 Updated eximstats to collate all SpamAssassin rejects into one bucket.
 
 
 SC/01 Updated eximstats to collate all SpamAssassin rejects into one bucket.
 
 
index 9cc8f81cc4da0eb993df2785be09d2fdf398d6cf..ac707ae4018a78ce146b300f159c3fed7f34c0fc 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.128 2007/01/18 15:35:42 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.129 2007/01/22 16:29:54 ph10 Exp $
 
 New Features in Exim
 --------------------
 
 New Features in Exim
 --------------------
@@ -175,6 +175,17 @@ Version 4.67
     preference order for the cipher algorithms. The first one in the client's
     list that is also advertised by the server is tried first.
 
     preference order for the cipher algorithms. The first one in the client's
     list that is also advertised by the server is tried first.
 
+ 4. There is a new compile-time option called ENABLE_DISABLE_FSYNC. You must
+    not set this option unless you really, really, really understand what you
+    are doing. No pre-compiled distributions of Exim should ever set this
+    option. When it is set, Exim compiles a runtime option called
+    disable_fsync. If this is set true, Exim no longer calls fsync() to force
+    updated files' data to be written to disc. Unexpected events such as
+    crashes and power outages may cause data to be lost or scrambled. Beware.
+
+    When ENABLE_DISABLE_FSYNC is not set, a reference to disable_fsync in a
+    runtime configuration generates an "unknown option" error.
+
 
 Version 4.66
 ------------
 
 Version 4.66
 ------------
index 5d5af1ff0e39af443a1fae6de8bd3e8ab622b779..77b4f36865ac0c5aba86c71cbc25f64de33efb48 100644 (file)
@@ -1,4 +1,4 @@
-# $Cambridge: exim/src/src/EDITME,v 1.19 2006/12/08 03:16:48 jetmore Exp $
+# $Cambridge: exim/src/src/EDITME,v 1.20 2007/01/22 16:29:54 ph10 Exp $
 
 ##################################################
 #          The Exim mail transport agent         #
 
 ##################################################
 #          The Exim mail transport agent         #
@@ -1117,4 +1117,20 @@ TMPDIR="/tmp"
 
 # SUPPORT_MOVE_FROZEN_MESSAGES=yes
 
 
 # SUPPORT_MOVE_FROZEN_MESSAGES=yes
 
+
+#------------------------------------------------------------------------------
+# Disabling the use of fsync(): DO NOT UNCOMMENT THE FOLLOWING LINE unless you
+# really, really, really know what you are doing. And even then, think again.
+# You should never uncomment this when compiling a binary for distribution.
+# Use it only when compiling Exim for your own use.
+#
+# Uncommenting this line enables the use of a runtime option called
+# disable_fsync, which can be used to stop Exim using fsync() to ensure that
+# files are written to disc before proceeding. When this is disabled, crashes
+# and hardware problems such as power outages can cause data to be lost. This
+# feature should only be used in very exceptional circumstances. YOU HAVE BEEN
+# WARNED.
+
+# ENABLE_DISABLE_FSYNC=yes
+
 # End of EDITME for Exim 4.
 # End of EDITME for Exim 4.
index 455f38af46a0dc3265542bbc361e085dc8039f76..1949cb7f4c6c7ba63627c60db372b6186f42ceb1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/config.h.defaults,v 1.13 2007/01/08 10:50:17 ph10 Exp $ */
+/* $Cambridge: exim/src/src/config.h.defaults,v 1.14 2007/01/22 16:29:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -42,6 +42,8 @@ it's a default value. */
 #define DELIVER_OUT_BUFFER_SIZE    8192
 #define DISABLE_D_OPTION
 
 #define DELIVER_OUT_BUFFER_SIZE    8192
 #define DISABLE_D_OPTION
 
+#define ENABLE_DISABLE_FSYNC
+
 #define EXIMDB_DIRECTORY_MODE      0750
 #define EXIMDB_LOCK_TIMEOUT          60
 #define EXIMDB_LOCKFILE_MODE       0640
 #define EXIMDB_DIRECTORY_MODE      0750
 #define EXIMDB_LOCK_TIMEOUT          60
 #define EXIMDB_LOCKFILE_MODE       0640
index fb853aa5d8f05e164166124e365108832af80095..fae67dc79e36643a2b1d6cfc1be83b141e89bc65 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/deliver.c,v 1.40 2007/01/08 10:50:18 ph10 Exp $ */
+/* $Cambridge: exim/src/src/deliver.c,v 1.41 2007/01/22 16:29:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -774,7 +774,7 @@ if (addr->return_file >= 0 && addr->return_filename != NULL)
   {
   BOOL return_output = FALSE;
   struct stat statbuf;
   {
   BOOL return_output = FALSE;
   struct stat statbuf;
-  fsync(addr->return_file);
+  (void)EXIMfsync(addr->return_file);
 
   /* If there is no output, do nothing. */
 
 
   /* If there is no output, do nothing. */
 
@@ -1979,7 +1979,7 @@ if (!shadowing)
 
   /* Ensure the journal file is pushed out to disk. */
 
 
   /* Ensure the journal file is pushed out to disk. */
 
-  if (fsync(journal_fd) < 0)
+  if (EXIMfsync(journal_fd) < 0)
     log_write(0, LOG_MAIN|LOG_PANIC, "failed to fsync journal: %s",
       strerror(errno));
   }
     log_write(0, LOG_MAIN|LOG_PANIC, "failed to fsync journal: %s",
       strerror(errno));
   }
index ea973d3dae87c59bbcb5226de42bd80e4af4a602..8fa6959c82f4c97dd2d77e6a624bee68bd72c9e1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/exim.h,v 1.21 2007/01/08 10:50:18 ph10 Exp $ */
+/* $Cambridge: exim/src/src/exim.h,v 1.22 2007/01/22 16:29:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -461,6 +461,12 @@ requires various things that are set therein. */
 #include <dlfcn.h>
 #endif
 
 #include <dlfcn.h>
 #endif
 
+#ifdef ENABLE_DISABLE_FSYNC
+#define EXIMfsync(f) (disable_fsync? 0 : fsync(f))
+#else
+#define EXIMfsync(f) fsync(f)
+#endif
+
 /* Backward compatibility; LOOKUP_LSEARCH now includes all three */
 
 #if (!defined LOOKUP_LSEARCH) && (defined LOOKUP_WILDLSEARCH || defined LOOKUP_NWILDLSEARCH)
 /* Backward compatibility; LOOKUP_LSEARCH now includes all three */
 
 #if (!defined LOOKUP_LSEARCH) && (defined LOOKUP_WILDLSEARCH || defined LOOKUP_NWILDLSEARCH)
index c60ef864f151b82220b7eed89f91bee8fdc55c10..74b6554cf5119bc1afa44797de774bf777f1c305 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.63 2007/01/18 15:35:42 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.64 2007/01/22 16:29:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -499,6 +499,9 @@ int     demime_errorlevel      = 0;
 int     demime_ok              = 0;
 uschar *demime_reason          = NULL;
 #endif
 int     demime_ok              = 0;
 uschar *demime_reason          = NULL;
 #endif
+#ifdef ENABLE_DISABLE_FSYNC
+BOOL    disable_fsync          = FALSE;
+#endif
 BOOL    disable_ipv6           = FALSE;
 BOOL    disable_logging        = FALSE;
 
 BOOL    disable_ipv6           = FALSE;
 BOOL    disable_logging        = FALSE;
 
index 090e1b4834d2dbfd98fffb690f5ac4349b86c2fc..660d62fe5c0858787cce487ff5d1f465461821b3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.44 2007/01/18 15:35:42 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.45 2007/01/22 16:29:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -278,6 +278,9 @@ extern int     demime_errorlevel;      /* Severity of MIME error */
 extern int     demime_ok;              /* Nonzero if message has been demimed */
 extern uschar *demime_reason;          /* Reason for broken MIME container */
 #endif
 extern int     demime_ok;              /* Nonzero if message has been demimed */
 extern uschar *demime_reason;          /* Reason for broken MIME container */
 #endif
+#ifdef ENABLE_DISABLE_FSYNC
+extern BOOL    disable_fsync;          /* Not for normal use */
+#endif
 extern BOOL    disable_ipv6;           /* Don't do any IPv6 things */
 extern BOOL    disable_logging;        /* Disables log writing when TRUE */
 
 extern BOOL    disable_ipv6;           /* Don't do any IPv6 things */
 extern BOOL    disable_logging;        /* Disables log writing when TRUE */
 
index c3514aba5ddac919d3925e0af5c514f519fdf59e..1b4a04b668d69462f2491df6cf415044ae14150e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/readconf.c,v 1.27 2007/01/18 15:35:42 ph10 Exp $ */
+/* $Cambridge: exim/src/src/readconf.c,v 1.28 2007/01/22 16:29:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -195,6 +195,9 @@ static optionlist optionlist_config[] = {
   { "deliver_drop_privilege",   opt_bool,        &deliver_drop_privilege },
   { "deliver_queue_load_max",   opt_fixed,       &deliver_queue_load_max },
   { "delivery_date_remove",     opt_bool,        &delivery_date_remove },
   { "deliver_drop_privilege",   opt_bool,        &deliver_drop_privilege },
   { "deliver_queue_load_max",   opt_fixed,       &deliver_queue_load_max },
   { "delivery_date_remove",     opt_bool,        &delivery_date_remove },
+#ifdef ENABLE_DISABLE_FSYNC
+  { "disable_fsync",            opt_bool,        &disable_fsync },
+#endif
   { "disable_ipv6",             opt_bool,        &disable_ipv6 },
   { "dns_again_means_nonexist", opt_stringptr,   &dns_again_means_nonexist },
   { "dns_check_names_pattern",  opt_stringptr,   &check_dns_names_pattern },
   { "disable_ipv6",             opt_bool,        &disable_ipv6 },
   { "dns_again_means_nonexist", opt_stringptr,   &dns_again_means_nonexist },
   { "dns_check_names_pattern",  opt_stringptr,   &check_dns_names_pattern },
index b741b05b270ac0e46bcced259263eedf70ccdf5f..db86947a46f3c4767a213b19d658e52f018668d3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/receive.c,v 1.32 2007/01/08 10:50:18 ph10 Exp $ */
+/* $Cambridge: exim/src/src/receive.c,v 1.33 2007/01/22 16:29:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -2730,7 +2730,7 @@ the input in cases of output errors, since the far end doesn't expect to see
 anything until the terminating dot line is sent. */
 
 if (fflush(data_file) == EOF || ferror(data_file) ||
 anything until the terminating dot line is sent. */
 
 if (fflush(data_file) == EOF || ferror(data_file) ||
-    fsync(fileno(data_file)) < 0 || (receive_ferror)())
+    EXIMfsync(fileno(data_file)) < 0 || (receive_ferror)())
   {
   uschar *msg_errno = US strerror(errno);
   BOOL input_error = (receive_ferror)() != 0;
   {
   uschar *msg_errno = US strerror(errno);
   BOOL input_error = (receive_ferror)() != 0;
index d64b45de016a4c6ccf2ac6b3ef31c9923f426f6b..724b00e44b2db381ea535601d1bd52ea5f91eeb4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/spool_out.c,v 1.12 2007/01/08 10:50:18 ph10 Exp $ */
+/* $Cambridge: exim/src/src/spool_out.c,v 1.13 2007/01/22 16:29:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -287,7 +287,7 @@ if (fflush(f) != 0 || ferror(f))
 just pushes it out of C, and fclose() doesn't guarantee to do the write
 either. That's just the way Unix works... */
 
 just pushes it out of C, and fclose() doesn't guarantee to do the write
 either. That's just the way Unix works... */
 
-if (fsync(fileno(f)) < 0)
+if (EXIMfsync(fileno(f)) < 0)
   return spool_write_error(where, errmsg, US"sync", temp_name, f);
 
 /* Get the size of the file, and close it. */
   return spool_write_error(where, errmsg, US"sync", temp_name, f);
 
 /* Get the size of the file, and close it. */
@@ -325,7 +325,7 @@ sprintf(CS temp_name, "%s/input/%s/.", spool_directory, message_subdir);
 if ((fd = Uopen(temp_name, O_RDONLY|O_DIRECTORY, 0)) < 0)
   return spool_write_error(where, errmsg, US"directory open", name, NULL);
 
 if ((fd = Uopen(temp_name, O_RDONLY|O_DIRECTORY, 0)) < 0)
   return spool_write_error(where, errmsg, US"directory open", name, NULL);
 
-if (fsync(fd) < 0 && errno != EINVAL)
+if (EXIMfsync(fd) < 0 && errno != EINVAL)
   return spool_write_error(where, errmsg, US"directory sync", name, NULL);
 
 if (close(fd) < 0)
   return spool_write_error(where, errmsg, US"directory sync", name, NULL);
 
 if (close(fd) < 0)
index 8266bf9bb49427cc9284d803405eacd6e7b4ed40..f31232a0f496ffd45632b637dffb884b62cd11c0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.20 2007/01/08 10:50:20 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.21 2007/01/22 16:29:55 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -2791,7 +2791,7 @@ if (temp_file != NULL && ob->mbx_format)
 /* Force out the remaining data to check for any errors; some OS don't allow
 fsync() to be called for a FIFO. */
 
 /* Force out the remaining data to check for any errors; some OS don't allow
 fsync() to be called for a FIFO. */
 
-if (yield == OK && !isfifo && fsync(fd) < 0) yield = DEFER;
+if (yield == OK && !isfifo && EXIMfsync(fd) < 0) yield = DEFER;
 
 /* Update message_size to the accurate count of bytes written, including
 added headers. */
 
 /* Update message_size to the accurate count of bytes written, including
 added headers. */
index 887b1ff821a897630a95a73d7007e92d5b637de8..c1396b9b4d996354960621737955775a64884bbd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/smtp.c,v 1.31 2007/01/18 15:35:43 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/smtp.c,v 1.32 2007/01/22 16:29:55 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1690,7 +1690,7 @@ if (!ok) ok = TRUE; else
 
     /* Ensure the journal file is pushed out to disk. */
 
 
     /* Ensure the journal file is pushed out to disk. */
 
-    if (fsync(journal_fd) < 0)
+    if (EXIMfsync(journal_fd) < 0)
       log_write(0, LOG_MAIN|LOG_PANIC, "failed to fsync journal: %s",
         strerror(errno));
     }
       log_write(0, LOG_MAIN|LOG_PANIC, "failed to fsync journal: %s",
         strerror(errno));
     }