[erlang-questions] run_erl and fsync

Michael Santos michael.santos@REDACTED
Fri Jul 27 14:34:23 CEST 2012


On Thu, Jul 26, 2012 at 09:27:56AM -0700, Damienuk Davis wrote:
> It's linux (Redhat ES 5.2) platform with following server configuration
> DL370 with 2*6core and 12GB RAM 
> Is it safe to define O_SYNC (this will cause to bybass fsync call)?

According to the man page, fsync() will result in 2 writes (data + 
mtime). So, O_SYNC should be faster.

> What can be the impact to the system?

Some of the log might be lost in a crash if sync writes are
disabled.

Here's an untested patch to run_erl that gives the option of disabling
sync writes. It'd be nice to add an option to use syslog too.

diff --git a/erts/etc/unix/run_erl.c b/erts/etc/unix/run_erl.c
index 6b350e8..e2de798 100644
--- a/erts/etc/unix/run_erl.c
+++ b/erts/etc/unix/run_erl.c
@@ -169,6 +169,7 @@ static int log_generations = DEFAULT_LOG_GENERATIONS;
 static int log_maxsize     = DEFAULT_LOG_MAXSIZE;
 static int log_alive_minutes = DEFAULT_LOG_ALIVE_MINUTES;
 static int log_activity_minutes = DEFAULT_LOG_ACTIVITY_MINUTES;
+static int log_sync_on_write = 1;
 static int log_alive_in_gmt = 0;
 static char log_alive_format[ALIVE_BUFFSIZ+1];
 static int run_daemon = 0;
@@ -296,6 +297,9 @@ int main(int argc, char **argv)
     if (log_maxsize < LOG_MIN_MAXSIZE)
       ERROR1(LOG_ERR,"Minimum RUN_ERL_LOG_MAXSIZE is %d", LOG_MIN_MAXSIZE);
   }
+  if ((p = getenv("RUN_ERL_DISABLE_SYNC_ON_WRITE"))) {
+    log_sync_on_write = 0;
+  }
 
   /*
    * Create FIFOs and open them 
@@ -480,6 +484,7 @@ static void pass_on(pid_t childpid)
     int maxfd;
     int ready;
     int got_some = 0; /* from to_erl */
+    int flags = O_RDWR|O_APPEND|O_CREAT;
     
     /* Open the to_erl pipe for reading.
      * We can't open the writing side because nobody is reading and 
@@ -495,9 +500,11 @@ static void pass_on(pid_t childpid)
 #endif
     
     /* Open the log file */
+    if (log_sync_on_write)
+        flags |= O_SYNC;
     
     lognum = find_next_log_num();
-    lfd = open_log(lognum, O_RDWR|O_APPEND|O_CREAT|O_SYNC);
+    lfd = open_log(lognum, flags);
     
     /* Enter the work loop */
     
@@ -842,7 +849,8 @@ static int open_log(int log_num, int flags)
       status("Error in writing to log.\n");
 
 #if USE_FSYNC
-  fsync(lfd);
+  if (log_sync_on_write)
+      fsync(lfd);
 #endif
 
   return lfd;
@@ -855,14 +863,19 @@ static int open_log(int log_num, int flags)
 static void write_to_log(int* lfd, int* log_num, char* buf, int len)
 {
   int size;
+  int flags = O_RDWR|O_CREAT|O_TRUNC|O_SYNC;
 
   /* Decide if new logfile needed, and open if so */
   
   size = lseek(*lfd,0,SEEK_END);
   if(size+len > log_maxsize) {
+    if (!log_sync_on_write) {
+        fsync(*lfd);
+        flags &= ~O_SYNC;
+    }
     sf_close(*lfd);
     *log_num = next_log(*log_num);
-    *lfd = open_log(*log_num, O_RDWR|O_CREAT|O_TRUNC|O_SYNC); 
+    *lfd = open_log(*log_num, flags);
   }
 
   /* Write to log file */
@@ -872,7 +885,8 @@ static void write_to_log(int* lfd, int* log_num, char* buf, int len)
   }
 
 #if USE_FSYNC
-  fsync(*lfd);
+  if (log_sync_on_write)
+    fsync(*lfd);
 #endif
 }
 



More information about the erlang-questions mailing list