Ken & Bill,

Here's a patch that's small but has a *big* performance
change in it.  This patches the 5.3.15 distribution.

Over the last few months, I've been seeing my mailserver
incur 90-99% CPU utilization during peak loads.  During
that time, I was seeing between 5 & 10 authentications
per second.  Auth's were taking 2-3 seconds each.

I've updated the courier authdaemon to keep the connections
alive (removing the vclose() in preauthvchkpw) and passing
the environment over the auth socket.  That helped alot,
however my cpu was still at 80-99% (both CPU's).

This patch changes vopen_smtp_relay() from a void to int.
The function should return non-zero only if the ip list changed
and tcprules should be run.  Before, tcprules was fork/exec'd
on every authentication.  With this patch, its only run if
a new IP address was inserted into the relay table.  My cpu's
dramatically changed so that they're 99% idle !!!  I don't
even see them at the top of the process list (ever).  I used
to have 5-15 daemons at the top all the time before this patch.
(And I thought I was going to need more hardware...)  Now
I can process 5 auth's per second with only one or two daemons
running.  Each auth now only takes milliseconds, even at
peak times.

There is a catch...  I've only patched the mysql code to return
the proper values if the table was updated.  I've updated oracle
and pgsql to return 1 if the table was updated, 0 on error.  So
we need someone to update the code for the other databases to
regognize when the replace did an insert vs. a replace (delete/insert).
Mysql returns 1 row affected on insert only, 2 rows affected if
there was a delete/insert (i.e. replace).  We only need to update
tcprules if there was an insert only.

I'll be creating a patch for the courier authlib code so
you can run authdaemon as well soon.

Thanks,

Brian


  > Ken, all:
  > 
  > I've put together vpopmail 5.3.15 with a few minor fixes for 
  > vdeloldusers and vlimits (from Brian):
  > 
  > ChangeLog:
  > http://shupp.org/patches/vpopmail-ChangeLog
  > 
  > Download:
  > http://shupp.org/patches/vpopmail-5.3.15.tar.gz
  > 
  > Cheers,
  > 
  > Bill Shupp
  > 
  > 

diff -c vpopmail-5.3.15.orig/vmysql.c vpopmail-5.3.15/vmysql.c
*** vpopmail-5.3.15.orig/vmysql.c       Fri Jan 24 03:30:33 2003
--- vpopmail-5.3.15/vmysql.c    Mon Jan 27 08:43:31 2003
***************
*** 702,717 ****
  }
  
  #ifdef POP_AUTH_OPEN_RELAY
! void vopen_smtp_relay()
  {
   char *ipaddr;
   time_t mytime;
   int err;
  
      mytime = time(NULL);
      ipaddr = getenv("TCPREMOTEIP");
      if ( ipaddr == NULL ) {
!         return;
      }
  
      if ( ipaddr != NULL &&  ipaddr[0] == ':') {
--- 702,718 ----
  }
  
  #ifdef POP_AUTH_OPEN_RELAY
! int vopen_smtp_relay()
  {
   char *ipaddr;
   time_t mytime;
   int err;
+  int rows;
  
      mytime = time(NULL);
      ipaddr = getenv("TCPREMOTEIP");
      if ( ipaddr == NULL ) {
!         return 0;
      }
  
      if ( ipaddr != NULL &&  ipaddr[0] == ':') {
***************
*** 720,726 ****
          ++ipaddr;
      }
  
!     if ( (err=vauth_open_update()) != 0 ) return;
  
      snprintf( SqlBufUpdate, SQL_BUF_SIZE,
  "replace into relay ( ip_addr, timestamp ) values ( \"%s\", %d )",
--- 721,727 ----
          ++ipaddr;
      }
  
!     if ( (err=vauth_open_update()) != 0 ) return 0;
  
      snprintf( SqlBufUpdate, SQL_BUF_SIZE,
  "replace into relay ( ip_addr, timestamp ) values ( \"%s\", %d )",
***************
*** 731,739 ****
              printf("vmysql: sql error[7]: %s\n", mysql_error(&mysql_update));
          }
      }
      res_update = mysql_store_result(&mysql_update);
      mysql_free_result(res_update);
!     return;
  }
  
  void vupdate_rules(int fdm)
--- 732,744 ----
              printf("vmysql: sql error[7]: %s\n", mysql_error(&mysql_update));
          }
      }
+     rows = mysql_affected_rows(&mysql_update);
      res_update = mysql_store_result(&mysql_update);
      mysql_free_result(res_update);
! 
!     /* return true if only INSERT (didn't exist) */
!     /* would return 2 if replaced, or -1 if error */
!     return rows == 1;
  }
  
  void vupdate_rules(int fdm)
***************
*** 1493,1499 ****
          "disable_smtp, perm_account, perm_alias, perm_forward, "
          "perm_autoresponder, perm_maillist, perm_quota, perm_defaultquota) \n"
          "VALUES \n"
!         "('%s', %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)",
          domain,
          limits->maxpopaccounts,
          limits->maxaliases,
--- 1498,1504 ----
          "disable_smtp, perm_account, perm_alias, perm_forward, "
          "perm_autoresponder, perm_maillist, perm_quota, perm_defaultquota) \n"
          "VALUES \n"
!         "('%s', %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, 
%d, %d, %d, %d, %d, %d)",
          domain,
          limits->maxpopaccounts,
          limits->maxaliases,
diff -c vpopmail-5.3.15.orig/voracle.pc vpopmail-5.3.15/voracle.pc
*** vpopmail-5.3.15.orig/voracle.pc     Sat Apr  6 09:30:33 2002
--- vpopmail-5.3.15/voracle.pc  Mon Jan 27 08:44:12 2003
***************
*** 653,659 ****
        return(0);
  }
  
! void vopen_smtp_relay()
  {
   char *ipaddr;
   time_t mytime;
--- 653,659 ----
        return(0);
  }
  
! int vopen_smtp_relay()
  {
   char *ipaddr;
   time_t mytime;
***************
*** 662,668 ****
      mytime = time(NULL);
      ipaddr = getenv("TCPREMOTEIP");
      if ( ipaddr == NULL ) {
!         return;
      }
  
          if ( ipaddr != NULL &&  ipaddr[0] == ':') {
--- 662,668 ----
      mytime = time(NULL);
      ipaddr = getenv("TCPREMOTEIP");
      if ( ipaddr == NULL ) {
!         return 0;
      }
  
          if ( ipaddr != NULL &&  ipaddr[0] == ':') {
***************
*** 679,685 ****
      EXEC SQL PREPARE S FROM :SqlBuf;
      EXEC SQL EXECUTE S;
      EXEC SQL COMMIT;
!     return;
  }
  
  #ifdef POP_AUTH_OPEN_RELAY 
--- 679,685 ----
      EXEC SQL PREPARE S FROM :SqlBuf;
      EXEC SQL EXECUTE S;
      EXEC SQL COMMIT;
!     return 1;
  }
  
  #ifdef POP_AUTH_OPEN_RELAY 
diff -c vpopmail-5.3.15.orig/vpgsql.c vpopmail-5.3.15/vpgsql.c
*** vpopmail-5.3.15.orig/vpgsql.c       Thu Jun 20 23:13:43 2002
--- vpopmail-5.3.15/vpgsql.c    Mon Jan 27 08:46:07 2003
***************
*** 610,616 ****
  }
  
  #ifdef POP_AUTH_OPEN_RELAY
! void vopen_smtp_relay()
  {
    PGresult *pgres;
    char *ipaddr;
--- 610,616 ----
  }
  
  #ifdef POP_AUTH_OPEN_RELAY
! int vopen_smtp_relay()
  {
    PGresult *pgres;
    char *ipaddr;
***************
*** 620,626 ****
    mytime = time(NULL);
    ipaddr = getenv("TCPREMOTEIP");
    if ( ipaddr == NULL ) {
!     return;
    }
  
    if ( ipaddr != NULL &&  ipaddr[0] == ':') {
--- 620,626 ----
    mytime = time(NULL);
    ipaddr = getenv("TCPREMOTEIP");
    if ( ipaddr == NULL ) {
!     return 0;
    }
  
    if ( ipaddr != NULL &&  ipaddr[0] == ':') {
***************
*** 629,635 ****
      ++ipaddr;
    }
  
!   if ( (err=vauth_open()) != 0 ) return (err);
  
    snprintf( SqlBufUpdate, SQL_BUF_SIZE, 
            "replace into relay ( ip_addr, timestamp ) values ( '%s', %d )",
--- 629,635 ----
      ++ipaddr;
    }
  
!   if ( (err=vauth_open()) != 0 ) return 0;
  
    snprintf( SqlBufUpdate, SQL_BUF_SIZE, 
            "replace into relay ( ip_addr, timestamp ) values ( '%s', %d )",
***************
*** 647,653 ****
              PQresultErrorMessage(pgres));
      } 
      if( pgres ) PQclear(pgres);
!     return;
  }
  
  void vupdate_rules(int fdm)
--- 647,654 ----
              PQresultErrorMessage(pgres));
      } 
      if( pgres ) PQclear(pgres);
!     /* need to return non-zero value if value inserted */
!     return 1;
  }
  
  void vupdate_rules(int fdm)
diff -c vpopmail-5.3.15.orig/vpopmail.c vpopmail-5.3.15/vpopmail.c
*** vpopmail-5.3.15.orig/vpopmail.c     Fri Oct 25 11:16:17 2002
--- vpopmail-5.3.15/vpopmail.c  Mon Jan 27 08:45:03 2003
***************
*** 2050,2057 ****
  int open_smtp_relay()
  {
  #ifdef USE_SQL
!   vopen_smtp_relay();  
!   update_rules();
  #else
   FILE *fs;
   FILE *fs1;
--- 2050,2057 ----
  int open_smtp_relay()
  {
  #ifdef USE_SQL
!   if (vopen_smtp_relay())
!     update_rules();
  #else
   FILE *fs;
   FILE *fs1;
diff -c vpopmail-5.3.15.orig/vpopmail.h vpopmail-5.3.15/vpopmail.h
*** vpopmail-5.3.15.orig/vpopmail.h     Wed Oct 23 15:48:49 2002
--- vpopmail-5.3.15/vpopmail.h  Mon Jan 27 08:44:45 2003
***************
*** 133,139 ****
  struct vqpasswd *vgetent(FILE *);
  int pw_comp(char *, char *, char *, int);
  void vset_default_domain( char *);
! void vopen_smtp_relay();      
  void vupdate_rules(int);
  void vclear_open_smtp(time_t, time_t);
  char *verror(int);
--- 133,139 ----
  struct vqpasswd *vgetent(FILE *);
  int pw_comp(char *, char *, char *, int);
  void vset_default_domain( char *);
! int vopen_smtp_relay();       
  void vupdate_rules(int);
  void vclear_open_smtp(time_t, time_t);
  char *verror(int);

Reply via email to