Evren Yurtesen
Home arrow Blog arrow qmail-todo using too much CPU
Thursday, 20 November 2008
 
 
Newsflash

The http://dev.yurtesen.com is officially opened! You can register and submit your articles and guides. We will examine them and publish.

 
qmail-todo using too much CPU Print
Written by Evren Yurtesen   
Wednesday, 20 February 2008

It is rare however ext-todo patched or even unpatched qmail might start using too much CPU. This is because qmail-todo going into a loop and checking queue/todo directory way too many times.  You can find the simple fix to this problem in this article.

Qmail-todo checks the queue/lock/trigger named pipe to see if it should check the queue/todo directory for new messages. However sometimes it gets messed up and starts checking the queue/todo directory hundreds of times in a second which cause high CPU load and might cause disk problems as well. Many people assume that this is because the hardware disk io speed is not fast enough so this is causing the qmail-todo problem but in fact the problem is elsewhere (although a hardware upgrade would most likely solve the problem too)

Below is a small patch which fixes this problem (it patches the qmail-todo.c)

The patch adds a SLEEP_MIN parameter where one can setup minimum time between opening queue/todo directory. It sets it to 5 seconds. This is a very reasonable value. When qmail-todo opens the queue/todo directory, it processes all the messages, this means that messages would arrive max 5s delayed because of the patch. (if copy/paste doesnt help with the patch, you can perhaps do the changes manually, but please let me know)

--- work/qmail-1.03/qmail-todo.c        2008-02-20 22:04:09.000000000 +0200
+++ qmail-todo.c        2008-02-14 15:07:17.000000000 +0200
@@ -28,6 +28,7 @@
 /* important timing feature: when triggered, respond instantly */
 #define SLEEP_TODO 1500 /* check todo/ every 25 minutes in any case */
 #define SLEEP_FUZZ 1 /* slop a bit on sleeps to avoid zeno effect */
+#define SLEEP_MIN 5 /* min interval to loop to open todo dir (sleep in between) */
 #define SLEEP_FOREVER 86400 /* absolute maximum time spent in select() */
 #define SLEEP_SYSFAIL 123

@@ -347,7 +348,7 @@

 /* this file is not so long ------------------------------------------ TODO */

-datetime_sec nexttodorun;
+datetime_sec nexttodorun,oldtodorun;
 DIR *tododir; /* if 0, have to opendir again */
 stralloc todoline = {0};
 char todobuf[SUBSTDIO_INSIZE];
@@ -385,6 +386,7 @@
  int c;
  unsigned long uid;
  unsigned long pid;
+ int elapsed_time;

  fd = -1;
  fdinfo = -1;
@@ -398,7 +400,10 @@
      if (recent < nexttodorun)
        return;
    trigger_set();
+      elapsed_time=( recent - oldtodorun );
+   if ( 0 <= elapsed_time && elapsed_time < SLEEP_MIN ) sleep(SLEEP_MIN-elapsed_time);
    tododir = opendir("todo");
+   oldtodorun = now();
    if (!tododir)
     {
      pausedir("todo");

 

Last Updated ( Saturday, 31 May 2008 )
 
Next >
Google Search
Donate For My Work

Amazon Search


 
Top! Top!