[exim-cvs] cvs commit: exim/exim-doc/doc-txt ChangeLog NewSt…

Góra strony
Delete this message
Reply to this message
Autor: Philip Hazel
Data:  
Dla: exim-cvs
Temat: [exim-cvs] cvs commit: exim/exim-doc/doc-txt ChangeLog NewStuff exim/exim-src/src expand.c functions.h receive.c exim/exim-test-orig/AutoTest/scripts 571
ph10 2004/11/17 14:32:25 GMT

  Modified files:
    exim-doc/doc-txt     ChangeLog NewStuff 
    exim-src/src         expand.c functions.h receive.c 
    exim-test-orig/AutoTest/scripts 571 
  Log:
  Added $spool_size, $log_size, $spool_inodes, $log_inodes.


  Revision  Changes    Path
  1.29      +5 -0      exim/exim-doc/doc-txt/ChangeLog
  1.10      +19 -0     exim/exim-doc/doc-txt/NewStuff
  1.4       +23 -1     exim/exim-src/src/expand.c
  1.3       +1 -0      exim/exim-src/src/functions.h
  1.4       +131 -99   exim/exim-src/src/receive.c
  1.3       +1 -1      exim/exim-test-orig/AutoTest/scripts/571


  Index: ChangeLog
  ===================================================================
  RCS file: /home/cvs/exim/exim-doc/doc-txt/ChangeLog,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- ChangeLog    12 Nov 2004 16:54:55 -0000    1.28
  +++ ChangeLog    17 Nov 2004 14:32:25 -0000    1.29
  @@ -1,4 +1,4 @@
  -$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.28 2004/11/12 16:54:55 ph10 Exp $
  +$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.29 2004/11/17 14:32:25 ph10 Exp $


   Change log file for Exim from version 4.21
   -------------------------------------------
  @@ -116,6 +116,11 @@
   30. Exim went into a mad DNS loop when attempting to do a callout where the
       host was specified on an smtp transport, and looking it up yielded more
       than one IP address.
  +
  +31. Re-factored the code for checking spool and log partition space into a
  +    function that finds that data and another that does the check. The former
  +    is then used to implement four new variables: $spool_space, $log_space,
  +    $spool_inodes, and $log_inodes.



Exim version 4.43

  Index: NewStuff
  ===================================================================
  RCS file: /home/cvs/exim/exim-doc/doc-txt/NewStuff,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- NewStuff    11 Nov 2004 11:40:36 -0000    1.9
  +++ NewStuff    17 Nov 2004 14:32:25 -0000    1.10
  @@ -1,4 +1,4 @@
  -$Cambridge: exim/exim-doc/doc-txt/NewStuff,v 1.9 2004/11/11 11:40:36 ph10 Exp $
  +$Cambridge: exim/exim-doc/doc-txt/NewStuff,v 1.10 2004/11/17 14:32:25 ph10 Exp $


   New Features in Exim
   --------------------
  @@ -70,6 +70,25 @@
    9. $host_address is now set to the target address during the checking of
       ignore_target_hosts.


  +10. There are four new variables called $spool_space, $log_space,
  +    $spool_inodes, and $log_inodes. The first two contain the amount of free
  +    space in the disk partitions where Exim has its spool directory and log
  +    directory, respectively. (When these are in the same partition, the values
  +    will, of course, be the same.) The second two variables contain the numbers
  +    of free inodes in the respective partitions.
  +
  +    NOTE: Because disks can nowadays be very large, the values in the space
  +    variables are in kilobytes rather than in bytes. Thus, for example, to
  +    check in an ACL that there is at least 50M free on the spool, you would
  +    write:
  +
  +       condition = ${if > {$spool_space}{50000}{yes}{no}}
  +
  +    The values are recalculated whenever any of these variables is referenced.
  +    If the relevant file system does not have the concept of inodes, the value
  +    of those variables is -1. If the operating system does not have the ability
  +    to find the amount of free space (only true for experimental systems), the
  +    space value is -1.



Version 4.43

  Index: expand.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/expand.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- expand.c    5 Nov 2004 16:53:28 -0000    1.3
  +++ expand.c    17 Nov 2004 14:32:25 -0000    1.4
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/expand.c,v 1.3 2004/11/05 16:53:28 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/expand.c,v 1.4 2004/11/17 14:32:25 ph10 Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -283,7 +283,9 @@
     vtype_reply,          /* value not used; get reply from headers */
     vtype_pid,            /* value not used; result is pid */
     vtype_host_lookup,    /* value not used; get host name */
  -  vtype_load_avg        /* value not used; result is int from os_getloadavg */
  +  vtype_load_avg,       /* value not used; result is int from os_getloadavg */
  +  vtype_pspace,         /* partition space; value is T/F for spool/log */
  +  vtype_pinodes         /* partition inodes; value is T/F for spool/log */  
     };


   /* This table must be kept in alphabetical order. */
  @@ -352,6 +354,8 @@
     { "local_user_gid",      vtype_gid,         &local_user_gid },
     { "local_user_uid",      vtype_uid,         &local_user_uid },
     { "localhost_number",    vtype_int,         &host_number },
  +  { "log_inodes",          vtype_pinodes,     (void *)FALSE },
  +  { "log_space",           vtype_pspace,      (void *)FALSE },  
     { "mailstore_basename",  vtype_stringptr,   &mailstore_basename },
     { "message_age",         vtype_int,         &message_age },
     { "message_body",        vtype_msgbody,     &message_body },
  @@ -421,6 +425,8 @@
     { "sn8",                 vtype_filter_int,  &filter_sn[8] },
     { "sn9",                 vtype_filter_int,  &filter_sn[9] },
     { "spool_directory",     vtype_stringptr,   &spool_directory },
  +  { "spool_inodes",        vtype_pinodes,     (void *)TRUE },
  +  { "spool_space",         vtype_pspace,      (void *)TRUE },  
     { "thisaddress",         vtype_stringptr,   &filter_thisaddress },
     { "tls_certificate_verified", vtype_int,    &tls_certificate_verified },
     { "tls_cipher",          vtype_stringptr,   &tls_cipher },
  @@ -1310,6 +1316,22 @@
         s[ptr] = 0;     /* string_cat() leaves room */
         }
       return s;
  +    
  +    case vtype_pspace:
  +      {
  +      int inodes;
  +      sprintf(CS var_buffer, "%d", 
  +        receive_statvfs((BOOL)(var_table[middle].value), &inodes));  
  +      }
  +    return var_buffer;
  +    
  +    case vtype_pinodes:
  +      {
  +      int inodes;
  +      (void) receive_statvfs((BOOL)(var_table[middle].value), &inodes);  
  +      sprintf(CS var_buffer, "%d", inodes);
  +      }
  +    return var_buffer;
       }
     }



  Index: functions.h
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/functions.h,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- functions.h    4 Nov 2004 12:19:48 -0000    1.2
  +++ functions.h    17 Nov 2004 14:32:25 -0000    1.3
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/functions.h,v 1.2 2004/11/04 12:19:48 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/functions.h,v 1.3 2004/11/17 14:32:25 ph10 Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -180,6 +180,7 @@
   extern BOOL    receive_check_fs(int);
   extern BOOL    receive_check_set_sender(uschar *);
   extern BOOL    receive_msg(BOOL);
  +extern int     receive_statvfs(BOOL, int *); 
   extern void    receive_swallow_smtp(void);
   extern BOOL    regex_match_and_setup(const pcre *, uschar *, int, int);
   extern const pcre *regex_must_compile(uschar *, BOOL, BOOL);


  Index: receive.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/receive.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- receive.c    19 Oct 2004 11:04:26 -0000    1.3
  +++ receive.c    17 Nov 2004 14:32:25 -0000    1.4
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/receive.c,v 1.3 2004/10/19 11:04:26 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/receive.c,v 1.4 2004/11/17 14:32:25 ph10 Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -92,90 +92,55 @@



   /*************************************************
  -*     Check space on spool and log partitions    *
  +*          Read space info for a partition       *
   *************************************************/


-/* This function is called before accepting a message; if any thresholds are
-set, it checks them. If a message_size is supplied, it checks that there is
-enough space for that size plus the threshold - i.e. that the message won't
-reduce the space to the threshold. Not all OS have statvfs(); for those that
-don't, this function always returns TRUE. For some OS the old function and
-struct name statfs is used; that is handled by a macro, defined in exim.h.
+/* This function is called by receive_check_fs() below, and also by string
+expansion for variables such as $spool_space. The field names for the statvfs
+structure are macros, because not all OS have F_FAVAIL and it seems tidier to
+have macros for F_BAVAIL and F_FILES as well. Some kinds of file system do not
+have inodes, and they return -1 for the number available.

  -Arguments:
  -  msg_size     the (estimated) size of an incoming message
  +Later: It turns out that some file systems that do not have the concept of
  +inodes return 0 rather than -1. Such systems should also return 0 for the total
  +number of inodes, so we require that to be greater than zero before returning 
  +an inode count.


  -Returns:       FALSE if there isn't enough space, or if the information cannot
  -                 be obtained
  -               TRUE if no check was done or there is enough space
  +Arguments:
  +  isspool       TRUE for spool partition, FALSE for log partition
  +  inodeptr      address of int to receive inode count; -1 if there isn't one
  +  
  +Returns:        available on-root space, in kilobytes
  +                -1 for log partition if there isn't one  
  +                
  +All values are -1 if the STATFS functions are not available. 
   */


-BOOL
-receive_check_fs(int msg_size)
+int
+receive_statvfs(BOOL isspool, int *inodeptr)
{
#ifdef HAVE_STATFS
-BOOL rc = TRUE;
struct STATVFS statbuf;
+uschar *path;
+uschar *name;
+uschar buffer[1024];

-memset(&statbuf, 0, sizeof(statbuf));
+/* The spool directory must always exist. */

  -/* The field names are macros, because not all OS have F_FAVAIL and it seems
  -tidier to have macros for F_BAVAIL and F_FILES as well. Some kinds of file
  -server do not have inodes, and they return -1 for the number available, so we
  -do the check only when this field is non-negative.
  -
  -Later: It turns out that some file systems that do not have the concept of
  -inodes return 0 rather than -1. Such systems should also return 0 for the total
  -number of inodes, so we require that to be greater than zero before doing the
  -test. */
  -
  -if (check_spool_space > 0 || msg_size > 0 || check_spool_inodes > 0)
  +if (isspool)
     {
  -  if (STATVFS(CS spool_directory, &statbuf) != 0)
  -    {
  -    log_write(0, LOG_MAIN|LOG_PANIC, "cannot accept message: failed to stat "
  -      "spool directory %s: %s", spool_directory, strerror(errno));
  -    smtp_closedown(US"spool directory problem");
  -    exim_exit(EXIT_FAILURE);
  -    }
  -
  -  /* check_spool_space is held in K because disks are getting huge */
  -
  -  if (statbuf.F_BAVAIL < (unsigned long)
  -        ((((double)check_spool_space) * 1024.0 + (double)msg_size) /
  -            (double)statbuf.F_FRSIZE)
  -       ||
  -      (statbuf.F_FILES > 0 &&
  -       statbuf.F_FAVAIL >= 0 &&
  -       statbuf.F_FAVAIL < check_spool_inodes))
  -    rc = FALSE;
  -
  -  DEBUG(D_receive)
  -    debug_printf("spool directory %s space = %d blocks; inodes = %d; "
  -      "check_space = %dK (%d blocks); inodes = %d; msg_size = %d (%d blocks)\n",
  -      spool_directory, (int)statbuf.F_BAVAIL, (int)statbuf.F_FAVAIL,
  -      check_spool_space,
  -      (int)(((double)check_spool_space * 1024.0) / (double)statbuf.F_FRSIZE),
  -      check_spool_inodes, msg_size, (int)(msg_size / statbuf.F_FRSIZE));
  -
  -  if (!rc)
  -    {
  -    log_write(0, LOG_MAIN, "spool directory space check failed: space=%d "
  -      "inodes=%d", (int)statbuf.F_BAVAIL, (int)statbuf.F_FAVAIL);
  -    return FALSE;
  -    }
  -  }
  -
  +  path = spool_directory; 
  +  name = US"spool"; 
  +  } 
  +  
   /* Need to cut down the log file path to the directory, and to ignore any
   appearance of "syslog" in it. */


  -if (check_log_space > 0 || check_log_inodes > 0)
  +else
     {
  -  uschar *path;
     int sep = ':';              /* Not variable - outside scripts use */
  -  uschar *cp;
     uschar *p = log_file_path;
  -  uschar buffer[1024];
  +  name = US"log"; 


     /* An empty log_file_path means "use the default". This is the same as an
     empty item in a list. */
  @@ -186,50 +151,117 @@
       if (Ustrcmp(path, "syslog") != 0) break;
       }


  -  if (path == NULL) return TRUE;    /* No log files, so no problem */
  +  if (path == NULL)  /* No log files */
  +    {
  +    *inodeptr = -1; 
  +    return -1;       
  +    } 
  +
  +  /* An empty string means use the default, which is in the spool directory. 
  +  But don't just use the spool directory, as it is possible that the log 
  +  subdirectory has been symbolically linked elsewhere. */


  -  /* An empty string means use the default */
  +  if (path[0] == 0) 
  +    {
  +    sprintf(CS buffer, CS"%s/log", CS spool_directory);
  +    path = buffer;
  +    }  
  +  else 
  +    {
  +    uschar *cp; 
  +    if ((cp = Ustrrchr(path, '/')) != NULL) *cp = 0;
  +    } 
  +  }
  +  
  +/* We now have the patch; do the business */


  -  if (path[0] == 0)
  -    path = string_sprintf("%s/log/%%slog", spool_directory);
  +memset(&statbuf, 0, sizeof(statbuf));


  -  if ((cp = Ustrrchr(path, '/')) == NULL)
  -    {
  -    DEBUG(D_receive) debug_printf("cannot find slash in %s\n", path);
  -    return FALSE;
  -    }
  -  *cp = 0;
  +if (STATVFS(CS path, &statbuf) != 0)
  +  {
  +  log_write(0, LOG_MAIN|LOG_PANIC, "cannot accept message: failed to stat "
  +    "%s directory %s: %s", name, spool_directory, strerror(errno));
  +  smtp_closedown(US"spool or log directory problem");
  +  exim_exit(EXIT_FAILURE);
  +  }
  +  
  +*inodeptr = (statbuf.F_FILES > 0)? statbuf.F_FAVAIL : -1;


  -  if (STATVFS(CS path, &statbuf) != 0)
  -    {
  -    log_write(0, LOG_MAIN|LOG_PANIC, "cannot accept message: failed to stat "
  -      "log directory %s: %s", path, strerror(errno));
  -    smtp_closedown(US"log directory problem");
  -    exim_exit(EXIT_FAILURE);
  -    }
  +/* Disks are getting huge. Take care with computing the size in kilobytes. */
  + 
  +return (int)(((double)statbuf.F_BAVAIL * (double)statbuf.F_FRSIZE)/1024.0);
  +
  +/* Unable to find partition sizes in this environment. */
  +
  +#else
  +*inodeptr = -1;
  +return -1;
  +#endif
  +}


  -  if (statbuf.F_BAVAIL < (unsigned long)
  -        (((double)check_log_space * 1024.0) / (double)statbuf.F_FRSIZE)
  -      ||
  -      statbuf.F_FAVAIL < check_log_inodes) rc = FALSE;


  -  DEBUG(D_receive)
  -    debug_printf("log directory %s space = %d blocks; inodes = %d; "
  -      "check_space = %dK (%d blocks); inodes = %d\n",
  -      path, (int)statbuf.F_BAVAIL, (int)statbuf.F_FAVAIL,
  -      check_log_space,
  -      (int)(((double)check_log_space * 1024.0) / (double)statbuf.F_FRSIZE),
  -      check_log_inodes);


  -  if (!rc)
  -    {
  -    log_write(0, LOG_MAIN, "log directory space check failed: space=%d "
  -      "inodes=%d", (int)statbuf.F_BAVAIL, (int)statbuf.F_FAVAIL);
  +
  +/*************************************************
  +*     Check space on spool and log partitions    *
  +*************************************************/
  +
  +/* This function is called before accepting a message; if any thresholds are
  +set, it checks them. If a message_size is supplied, it checks that there is
  +enough space for that size plus the threshold - i.e. that the message won't
  +reduce the space to the threshold. Not all OS have statvfs(); for those that
  +don't, this function always returns TRUE. For some OS the old function and
  +struct name statfs is used; that is handled by a macro, defined in exim.h.
  +
  +Arguments:
  +  msg_size     the (estimated) size of an incoming message
  +
  +Returns:       FALSE if there isn't enough space, or if the information cannot
  +                 be obtained
  +               TRUE if no check was done or there is enough space
  +*/
  +
  +BOOL
  +receive_check_fs(int msg_size)
  +{
  +int space, inodes;
  +
  +if (check_spool_space > 0 || msg_size > 0 || check_spool_inodes > 0)
  +  {
  +  space = receive_statvfs(TRUE, &inodes); 
  +  
  +  DEBUG(D_receive)
  +    debug_printf("spool directory space = %dK inodes = %d "
  +      "check_space = %dK inodes = %d msg_size = %d\n",
  +      space, inodes, check_spool_space, check_spool_inodes, msg_size);
  +  
  +  if ((space >= 0 && space < check_spool_space) || 
  +      (inodes >= 0 && inodes < check_spool_inodes))
  +    {   
  +    log_write(0, LOG_MAIN, "spool directory space check failed: space=%d "
  +      "inodes=%d", space, inodes);
       return FALSE;
       }
     }


  -#endif
  +if (check_log_space > 0 || check_log_inodes > 0)
  +  {
  +  space = receive_statvfs(FALSE, &inodes); 
  +  
  +  DEBUG(D_receive)
  +    debug_printf("log directory space = %dK inodes = %d "
  +      "check_space = %dK inodes = %d\n",
  +      space, inodes, check_log_space, check_log_inodes);
  +  
  +  if ((space >= 0 && space < check_log_space) || 
  +      (inodes >= 0 && inodes < check_log_inodes))
  +    {   
  +    log_write(0, LOG_MAIN, "log directory space check failed: space=%d "
  +      "inodes=%d", space, inodes);
  +    return FALSE;
  +    }
  +  }   
  +  
   return TRUE;
   }



  Index: 571
  ===================================================================
  RCS file: /home/cvs/exim/exim-test-orig/AutoTest/scripts/571,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- 571    19 Oct 2004 11:04:26 -0000    1.2
  +++ 571    17 Nov 2004 14:32:25 -0000    1.3
  @@ -186,7 +186,7 @@
   exim -DSERVER=server -DSUBMISSION_OPTIONS=/domain=a.b.c/sender_retain -bd -oX 1225
   ****
   0
  -sleep 1
  +sleep 2
   ****
   0
   client 127.0.0.1 1225