...
authorHeiko Schlittermann (I24) <hs@schlittermann.de>
Wed, 23 Feb 2011 00:53:41 +0100
changeset 7 3e755b50b6a4
parent 6 d2183655483b
child 8 282974b20ef8
...
src.lock_maildirsize
--- a/src.lock_maildirsize	Sun Feb 20 23:59:48 2011 +0100
+++ b/src.lock_maildirsize	Wed Feb 23 00:53:41 2011 +0100
@@ -1,18 +1,18 @@
 # HG changeset patch
-# Parent 5037ac63d7aece4b5e96e26bace1ab4b7e791804
+# Parent d54ee7005f7f7b5970ce45caf7487a9fd929e55f
 
-diff -r 5037ac63d7ae Local/Makefile
---- a/Local/Makefile	Sat Feb 19 13:42:16 2011 +0100
-+++ b/Local/Makefile	Sun Feb 20 23:37:25 2011 +0100
+diff -r d54ee7005f7f Local/Makefile
+--- a/Local/Makefile	Mon Feb 21 22:52:42 2011 +0100
++++ b/Local/Makefile	Wed Feb 23 00:53:29 2011 +0100
 @@ -1,4 +1,5 @@
  # $Cambridge: exim/src/src/EDITME,v 1.27 2010/06/12 15:21:25 jetmore Exp $
 +EXTRALIBS_EXIM=-lrt
  
  ##################################################
  #          The Exim mail transport agent         #
-diff -r 5037ac63d7ae src/transports/appendfile.c
---- a/src/transports/appendfile.c	Sat Feb 19 13:42:16 2011 +0100
-+++ b/src/transports/appendfile.c	Sun Feb 20 23:37:25 2011 +0100
+diff -r d54ee7005f7f src/transports/appendfile.c
+--- a/src/transports/appendfile.c	Mon Feb 21 22:52:42 2011 +0100
++++ b/src/transports/appendfile.c	Wed Feb 23 00:53:29 2011 +0100
 @@ -13,6 +13,7 @@
  
  #ifdef SUPPORT_MAILDIR
@@ -21,7 +21,38 @@
  #endif
  
  
-@@ -278,8 +279,8 @@
+@@ -239,6 +240,30 @@
+   TRUE            /* quota_is_inclusive */
+ };
+ 
++void hs12_lock(int fd, int type, const char* msg)
++{
++	struct timespec t0, t1;
++	clock_gettime(CLOCK_REALTIME, &t0);
++	const char *ltype =
++			type == F_UNLCK ? "UNLOCK"
++			: type == F_RDLCK ? "READ LOCK"
++			: "WRITE LOCK";
++
++	DEBUG(D_transport) debug_printf("%s: %s\n", ltype, msg);
++					
++
++	(void)apply_lock(fd, type, 1, 120, 0, 0);
++	if (type == F_UNLCK) return;
++
++	clock_gettime(CLOCK_REALTIME, &t1);
++	t1.tv_sec -= t0.tv_sec;
++	t1.tv_nsec -= t0.tv_nsec;
++	if (t1.tv_nsec < 0) { t1.tv_sec--; t1.tv_nsec *= -1; }
++	DEBUG(D_transport) 
++		 debug_printf("%s: %s was waiting for %d.%09d seconds\n", 
++			 ltype, msg, t1.tv_sec, t1.tv_nsec);
++	return;
++}
+ 
+ 
+ /*************************************************
+@@ -278,8 +303,8 @@
  gid = gid;
  
  if (ob->expand_maildir_use_size_file)
@@ -32,7 +63,7 @@
  
  /* Loop for quota, quota_filecount, quota_warn_threshold, mailbox_size,
  mailbox_filecount */
-@@ -841,7 +842,7 @@
+@@ -841,7 +866,7 @@
                sigalrm_seen set if there has been a timeout
  */
  
@@ -41,7 +72,7 @@
  apply_lock(int fd, int fcntltype, BOOL dofcntl, int fcntltime, BOOL doflock,
      int flocktime)
  {
-@@ -887,7 +888,6 @@
+@@ -887,7 +912,6 @@
  
  
  
@@ -49,14 +80,11 @@
  #ifdef SUPPORT_MBX
  /*************************************************
  *         Copy message into MBX mailbox          *
-@@ -2416,18 +2416,32 @@
+@@ -2416,18 +2440,19 @@
        {
        off_t size;
        int filecount;
 +      uschar *excuse;
-+
-+      struct timespec t0, t1;
-+      clock_gettime(CLOCK_REALTIME, &t0);
  
        maildirsize_fd = maildir_ensure_sizefile(check_path, ob, regex, dir_regex,
 -        &size, &filecount);
@@ -67,34 +95,24 @@
          addr->basic_errno = errno;
 -        addr->message = string_sprintf("while opening or reading "
 -          "%s/maildirsize", check_path);
-+        //addr->message = string_sprintf("%s", excuse);
 +        addr->message = excuse;
          return FALSE;
          }
  
 +
-+      clock_gettime(CLOCK_REALTIME, &t1);
-+      t1.tv_sec -= t0.tv_sec;
-+      t1.tv_nsec -= t0.tv_nsec;
-+      if (t1.tv_nsec < 0) { t1.tv_sec--; t1.tv_nsec *= -1; }
-+      DEBUG(D_transport) {
-+         if (t1.tv_sec >= 1) debug_printf("%s/maildirsize was locked for %d.09ld seconds\n",
-+          check_path, t1.tv_sec, t1.tv_nsec);
-+      }
-+          
        if (mailbox_size < 0) mailbox_size = size;
        if (mailbox_filecount < 0) mailbox_filecount = filecount;
        }
-@@ -3125,6 +3139,8 @@
+@@ -3125,6 +3150,8 @@
        uschar *renamename = newname;
        fd = -1;
  
-+			if (lockfd >= 0) (void)apply_lock(lockfd, F_RDLCK, 1, 120, 0, 0);  // hs12
++			if (lockfd >= 0) hs12_lock(lockfd, F_RDLCK, "delivery");
 +
        DEBUG(D_transport) debug_printf("renaming temporary file\n");
  
        /* If there is no rename name set, we are in a non-maildir, non-mailstore
-@@ -3245,6 +3261,7 @@
+@@ -3245,6 +3272,7 @@
            filename = dataname = NULL;   /* Prevents attempt to unlink at end */
            }
          }        /* maildir or mailstore */
@@ -102,21 +120,21 @@
        }          /* successful write + close */
      }            /* isdirectory */
    }              /* write success */
-@@ -3280,6 +3297,11 @@
+@@ -3280,6 +3308,11 @@
  detected, in order to get the file closed and the lock file tidied away. */
  
  RETURN:
 +if (lockfd >= 0) 
 +  {
-+	(void)apply_lock(lockfd, F_UNLCK, 1, 120, 0, 0); // hs12
++	hs12_lock(lockfd, F_UNLCK, "done delivery");
 +	(void)close(lockfd);
 +	}
  
  #ifdef SUPPORT_MBX
  if (mbx_lockfd >= 0)
-diff -r 5037ac63d7ae src/transports/appendfile.h
---- a/src/transports/appendfile.h	Sat Feb 19 13:42:16 2011 +0100
-+++ b/src/transports/appendfile.h	Sun Feb 20 23:37:25 2011 +0100
+diff -r d54ee7005f7f src/transports/appendfile.h
+--- a/src/transports/appendfile.h	Mon Feb 21 22:52:42 2011 +0100
++++ b/src/transports/appendfile.h	Wed Feb 23 00:53:29 2011 +0100
 @@ -95,5 +95,8 @@
  /* Function that is shared with tf_maildir.c */
  
@@ -126,9 +144,9 @@
 +
  
  /* End of transports/appendfile.h */
-diff -r 5037ac63d7ae src/transports/tf_maildir.c
---- a/src/transports/tf_maildir.c	Sat Feb 19 13:42:16 2011 +0100
-+++ b/src/transports/tf_maildir.c	Sun Feb 20 23:37:25 2011 +0100
+diff -r d54ee7005f7f src/transports/tf_maildir.c
+--- a/src/transports/tf_maildir.c	Mon Feb 21 22:52:42 2011 +0100
++++ b/src/transports/tf_maildir.c	Wed Feb 23 00:53:29 2011 +0100
 @@ -367,13 +367,16 @@
  
  Returns:           >=0  a file descriptor for an open maildirsize file
@@ -147,7 +165,7 @@
  {
  int count, fd;
  off_t cached_quota = 0;
-@@ -381,25 +384,80 @@
+@@ -381,25 +384,48 @@
  int filecount = 0;
  int linecount = 0;
  off_t size = 0;
@@ -157,69 +175,36 @@
  uschar *ptr = buffer;
  uschar *endptr;
  
+-/* Try a few times to open or create the file, in case another process is doing
+-the same thing. */
 +filename = string_sprintf("%s/maildirsize", path);
 +lockname = string_sprintf("%s.lock", filename);
 +hitchname = string_sprintf( "%s.%s.%08x.%08x", lockname, primary_hostname,
 +      (unsigned int)(time(NULL)), (unsigned int)getpid());
-+
+ 
+-filename = string_sprintf("%s/maildirsize", path);
 +/* Try to create a lock file. Here we should copy the loop from appendfile.c,
 +since our approach is quite simplified */
 +lockfd = Uopen(lockname, O_CREAT|O_RDWR, ob->mode ? ob->mode : 0600);
 +if (lockfd < 0)
-+  {
-+    if (errno != ENOENT)
 +	  {
 +	  *excuse = string_sprintf("open %s", lockname);
 +	  return -1;
 +	  }
 +
-+	lockfd = Uopen(hitchname, O_WRONLY|O_CREAT|O_EXCL, ob->mode ? ob->mode : 0600);
-+	if (lockfd < 0) 
-+	  {
-+		*excuse = string_sprintf("open %s", hitchname);
-+		return -1;
-+	  }
-+	if (link(hitchname, lockname) < 0)
-+	  {
-+	  int save_errno = errno;
-+	  (void)unlink(hitchname);
-+	  errno = save_errno;
-+	  if (errno != EEXIST) 
-+		{
-+		  *excuse = string_sprintf("link %s -> %s", hitchname, lockname);
-+		  return -1;
-+		}
-+	  (void)close(lockfd);
-+	  lockfd = Uopen(lockname, O_WRONLY, ob->mode ? ob->mode : 0600);
-+	  if (lockfd < 0) 
-+		{
-+		*excuse = string_sprintf("open %s", lockname);
-+		return -1;
-+		}
-+	  }
-+	(void)unlink(hitchname);
-+  }
-+	
-+
 +/* Before doing anything here we try to open and lock the maildirsize.lock
 +file. This should prevent/avoid races and parallel recalculations. We
 +need to do this on an extra lockfile, since the maildirsize file itself
 +gets renamed during the recalculation. */
 +
-+if (lockfd >= 0)
-+(void)apply_lock(lockfd, F_WRLCK, 1, 120, 0, 0);	// hs12
++hs12_lock(lockfd, F_WRLCK, "checking");
 +if (sigalrm_seen) 
 +  {
 +  *excuse = string_sprintf("timeout locking %s", lockname);
 +  return -1;
 +  }
-+DEBUG(D_transport) debug_printf("locked (WR) %s\n", lockname);
 +
- /* Try a few times to open or create the file, in case another process is doing
- the same thing. */
  
--filename = string_sprintf("%s/maildirsize", path);
--
  DEBUG(D_transport) debug_printf("looking for maildirsize in %s\n", path);
  fd = Uopen(filename, O_RDWR|O_APPEND, ob->mode ? ob->mode : 0600);
 -if (fd < 0)
@@ -231,24 +216,64 @@
    goto RECALCULATE;
 -  }
 +}
++(void)lseek(fd, 0, SEEK_SET);
++
  
  /* The file has been successfully opened. Check that the cached quota value is
  still correct, and that the size of the file is still small enough. If so,
-@@ -588,8 +646,10 @@
+@@ -520,16 +546,12 @@
+       }
      }
    }
+-
+-
+-/* If *endptr is not zero, there was a syntax error in the file. */
+-
+-else
++else /* If *endptr is not zero, there was a syntax error in the file. */
+   {
++  time_t old_latest, new_latest;
+   int len;
+-  time_t old_latest, new_latest;
+   uschar *tempname;
+-  struct timeval tv;
++	struct timeval tv;
  
-+	DEBUG(D_transport) debug_printf("releasing lock\n");
-+  (void)apply_lock(lockfd, F_UNLCK, 1, 120, 0, 0);
+   DEBUG(D_transport)
+     {
+@@ -549,6 +571,13 @@
+ 
+   RECALCULATE:
+ 
++	//hs12_lock(lockfd, F_WRLCK, "recalc");
++	if (sigalrm_seen)
++		{
++			*excuse = "timeout while locking for recalc";
++			return -1;
++		}
++
+   if (fd >= 0) (void)close(fd);
+   old_latest = 0;
+   filecount = 0;
+@@ -586,10 +615,14 @@
+     (void)close(fd);
+     fd = -2;
+     }
++    hs12_lock(lockfd, F_UNLCK, "done recalc");
+   }
+ 
++   hs12_lock(lockfd, F_UNLCK, "done check");
++	
++
 +
  /* Return the sizes and the file descriptor, if any */
 -
  DEBUG(D_transport) debug_printf("returning maildir size=" OFF_T_FMT
    " filecount=%d\n", size, filecount);
  *returned_size = size;
-diff -r 5037ac63d7ae src/transports/tf_maildir.h
---- a/src/transports/tf_maildir.h	Sat Feb 19 13:42:16 2011 +0100
-+++ b/src/transports/tf_maildir.h	Sun Feb 20 23:37:25 2011 +0100
+diff -r d54ee7005f7f src/transports/tf_maildir.h
+--- a/src/transports/tf_maildir.h	Mon Feb 21 22:52:42 2011 +0100
++++ b/src/transports/tf_maildir.h	Wed Feb 23 00:53:29 2011 +0100
 @@ -16,7 +16,7 @@
                  uschar *);
  extern int    maildir_ensure_sizefile(uschar *,