imapd and pop3d processes accumulate when clients disappear

Gary Mills mills at cc.umanitoba.ca
Mon Jan 10 17:23:16 EST 2011


I've noticed on our murder front end that imapd and pop3d processes
gradually accumulate.  Some of these can be several months old.  In
both cases, the reason seems to be that the process is listening on
standard input, but the client has disappeared.  Here's a typical
stack trace:

    # pstack 5802
    5802:	  imapd -s
     feb1a8f5 read     (0, 822dd48, 5)
     fec2dfaf sock_read () + 3f

This only seems to happen when the client is using SSL or STARTTLS.
The read() never times out.  Of course, restarting the Cyrus service
does clean up these abandoned processes, but there should be a better
way.  I've found that a simple modification to the daemons that
enables TCP keepalives solves the problem.  We also shorten the
keepalive interval with a global setting, but that shouldn't affect
the results once the client has disappeared.

I'll attach the two patches.  They are for cyrus-imapd-2.3.8.  It
would be better to have a Cyrus master option to enable these socket
options, but these certainly work.

-- 
-Gary Mills-        -Unix Group-        -Computer and Network Services-
-------------- next part --------------
--- pop3d.c-nokeep	Wed Apr 11 10:49:59 2007
+++ pop3d.c	Mon May 17 18:17:22 2010
@@ -494,6 +494,12 @@
 	if (getsockname(0, (struct sockaddr *)&popd_localaddr, &salen) == 0) {
 	    popd_haveaddr = 1;
 	}
+	/* Set keepalive option */
+	{
+	  int oval = 1;
+	  (void)setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (const void *)&oval,
+		     sizeof(oval));
+	}
     }
 
     /* other params should be filled in */
-------------- next part --------------
--- imapd.c-nokeep	Sun May 13 08:41:16 2007
+++ imapd.c	Tue Jan  4 08:03:05 2011
@@ -786,6 +786,12 @@
 		imapd_haveaddr = 1;
 	    }
 	}
+	/* Set keepalive option */
+	{
+	  int oval = 1;
+	  (void)setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (const void *)&oval,
+		     sizeof(oval));
+	}
 
 #ifdef DRAC_AUTH
 	if (((struct sockaddr *)&imapd_remoteaddr)->sa_family == AF_INET)


More information about the Info-cyrus mailing list