monit-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Large-file support


From: Will Bryant
Subject: Large-file support
Date: Sun, 25 Jun 2006 17:12:12 +1200
User-agent: Thunderbird 1.5.0.4 (X11/20060615)

Hi guys,

I've been having problems with monit claiming that my log files don't
exist whenever they're over 2GB in size.  This is because monit is using
the traditional stat/seek variants without enabling large-file support.

Please find attached a patch against CVS HEAD that I've drafted to fix
this.  It contains the following changes:

   1. Use the AC_SYS_LARGEFILE macro in configure.ac, so that the
      necessary defines will be set on those systems that do have
      large-file support.  Thus off_t will be 64-bit, and the *64
      variants of the libc file functions (eg. fseek64 and stat64) will
      be called.
   2. Change the type of Info_T's st_size and readpos members to off_t,
      to match what the libc APIs actually use (whether using large-file
      support or not) - IMHO size_t is really only appropriate for
      memory sizes, rather than file sizes, since the two don't
      necessarily correspond.
   3. Change the type of Size_T's size member to unsigned long long (was
      unsigned long), to make it big enough to hold sizes >4gb.
   4. Change a number of casts and printf format-specifiers to match
      change 3.  I elected to change all instances, rather than leaving
      half the codebase using one size and the rest another, which would
      IMHO be too likely to introduce unnecessary bugs in the future
      when ppl copy-and-paste bits of code around.
   5. Widened the operands to Util_evalQExpression. 


Comments on this patch?

I think the format specifier changes are the most likely source of
trouble, as they require that the libc supports %llu.  AFAIK this is
true for all of the supported platforms, but I'm really only familiar
with glibc's implementation.  Similarly, my patch requires that
compilers support 'long long' types, but my understanding is that that's
been the case in all the usual compilers for some time.

Note that, regardless of whether or not my patch is applied, many calls
to Util_evalQExpression are made with unsigned types, which are
truncated down to signed operands; having said that, I checked and
couldn't find any instances where this is currently a problem, since
file sizes are actually signed in the libc RTL (ie. the full range of
Info_T's st_size member won't be used, so no problem there) and memory
sizes are compared in kbytes rather than bytes; but IMHO, it would still
be nicer to have an unsigned overload.

Cheers,
Will
Index: CHANGES.txt
===================================================================
RCS file: /sources/monit/monit/CHANGES.txt,v
retrieving revision 1.304
diff -u -r1.304 CHANGES.txt
--- CHANGES.txt 21 Jun 2006 08:47:02 -0000      1.304
+++ CHANGES.txt 25 Jun 2006 05:03:31 -0000
@@ -11,6 +11,9 @@
 * Fix the warning logged on solaris when ssh protocol test
   was used to test sun version of sshd.
 
+* Fix handling of >2GB files by using the Large File Support
+  APIs on those platforms that support it.
+
 
 Version 4.8.1
 
Index: configure.ac
===================================================================
RCS file: /sources/monit/monit/configure.ac,v
retrieving revision 1.139
diff -u -r1.139 configure.ac
--- configure.ac        20 Jun 2006 23:18:40 -0000      1.139
+++ configure.ac        25 Jun 2006 05:03:31 -0000
@@ -291,6 +291,9 @@
 AC_CHECK_FUNCS(setlocale)
 AC_CHECK_FUNCS(getaddrinfo)
 
+# Turn on large-file support, on those platforms that implement it
+AC_SYS_LARGEFILE
+
 
 # Check if we do need external GNU replacements
 AC_FUNC_GETLOADAVG
Index: monitor.h
===================================================================
RCS file: /sources/monit/monit/monitor.h,v
retrieving revision 1.186
diff -u -r1.186 monitor.h
--- monitor.h   27 Apr 2006 20:56:41 -0000      1.186
+++ monitor.h   25 Jun 2006 05:03:32 -0000
@@ -493,7 +493,7 @@
 /** Defines size object */
 typedef struct mysize {
   int  operator;                                    /**< Comparison operator */
-  unsigned long size;                                    /**< Size watermark */
+  unsigned long long size;                               /**< Size watermark */
   int  test_changes;            /**< TRUE if we only should test for changes */
   EventAction_T action;  /**< Description of the action upon event occurence */
   
@@ -585,8 +585,8 @@
   long   space_total;                           /**< Used space total blocks */
 
   /* File specific */
-  size_t st_size;                                                  /**< Size */
-  size_t readpos;                           /**< Position for regex matching */
+  off_t st_size;                                                   /**< Size */
+  off_t readpos;                            /**< Position for regex matching */
   ino_t  st_ino_prev;                 /**< Previous inode for regex matching */
   char  *cs_sum;                                               /**< Checksum */
 
Index: p.y
===================================================================
RCS file: /sources/monit/monit/p.y,v
retrieving revision 1.236
diff -u -r1.236 p.y
--- p.y 23 Jun 2006 20:38:12 -0000      1.236
+++ p.y 25 Jun 2006 05:03:33 -0000
@@ -1448,7 +1448,7 @@
 
 size            : IF SIZE operator NUMBER unit rate1 THEN action1 recovery {
                     sizeset.operator= $<number>3;
-                    sizeset.size= ((unsigned long)$4 * $<number>5);
+                    sizeset.size= ((unsigned long long)$4 * $<number>5);
                     addeventaction(&(sizeset).action, $<number>8, $<number>9);
                     addsize(&sizeset, FALSE);
                   }
@@ -2044,7 +2044,7 @@
   s->action= ss->action;
   s->test_changes= ss->test_changes;
   if(ss->test_changes || nosize)
-    s->size= (unsigned long)buf.st_size;
+    s->size= (unsigned long long)buf.st_size;
  
   s->next= current->sizelist;
   current->sizelist= s;
Index: util.c
===================================================================
RCS file: /sources/monit/monit/util.c,v
retrieving revision 1.184
diff -u -r1.184 util.c
--- util.c      27 Apr 2006 20:16:03 -0000      1.184
+++ util.c      25 Jun 2006 05:03:34 -0000
@@ -862,7 +862,7 @@
         "Size",
         ratio1, actionnames[a->failed->id]);
     else
-      printf(" %-20s = if %s %lu byte(s) %s then %s else if passed %s then 
%s\n",
+      printf(" %-20s = if %s %llu byte(s) %s then %s else if passed %s then 
%s\n",
         "Size", operatornames[sl->operator], sl->size,
         ratio1, actionnames[a->failed->id],
         ratio2, actionnames[a->passed->id]);
@@ -1759,7 +1759,7 @@
  * @param rightExpression rval
  * Returns the boolean value of the expression
  */
-int Util_evalQExpression(int operator, int left, int right) {
+int Util_evalQExpression(int operator, long long left, long long right) {
 
   switch(operator) {
   case OPERATOR_GREATER:
Index: util.h
===================================================================
RCS file: /sources/monit/monit/util.h,v
retrieving revision 1.15
diff -u -r1.15 util.h
--- util.h      11 Apr 2006 23:23:26 -0000      1.15
+++ util.h      25 Jun 2006 05:03:34 -0000
@@ -371,7 +371,7 @@
  * @param rightExpression rval
  * @return the boolean value of the expression
  */
-int Util_evalQExpression(int operator, int left, int right);
+int Util_evalQExpression(int operator, long long left, long long right);
 
 
 /*
Index: validate.c
===================================================================
RCS file: /sources/monit/monit/validate.c,v
retrieving revision 1.153
diff -u -r1.153 validate.c
--- validate.c  23 Jun 2006 21:51:25 -0000      1.153
+++ validate.c  25 Jun 2006 05:03:36 -0000
@@ -1091,7 +1091,7 @@
         /* reset expected value for next cycle */
         sl->size= s->inf->st_size;
       } else {
-        DEBUG("'%s' size has not changed [current size=%lu B]\n", s->name,
+        DEBUG("'%s' size has not changed [current size=%llu B]\n", s->name,
               s->inf->st_size);
         Event_post(s, EVENT_CHANGED, STATE_PASSED, sl->action,
           "'%s' size was not changed", s->name, s->path);
@@ -1102,10 +1102,10 @@
     /* we are testing constant value for failed or passed state */
     if(Util_evalQExpression(sl->operator, s->inf->st_size, sl->size)) {
       Event_post(s, EVENT_SIZE, STATE_FAILED, sl->action,
-        "'%s' size test failed for %s -- current size is %lu B",
+        "'%s' size test failed for %s -- current size is %llu B",
         s->name, s->path, s->inf->st_size);
     } else {
-      DEBUG("'%s' file size check passed [current size=%lu B]\n", s->name,
+      DEBUG("'%s' file size check passed [current size=%llu B]\n", s->name,
             s->inf->st_size);
       Event_post(s, EVENT_SIZE, STATE_PASSED, sl->action, "'%s' size passed", 
s->name);
     }
Index: xml.c
===================================================================
RCS file: /sources/monit/monit/xml.c,v
retrieving revision 1.24
diff -u -r1.24 xml.c
--- xml.c       23 Jun 2006 22:00:34 -0000      1.24
+++ xml.c       25 Jun 2006 05:03:36 -0000
@@ -212,8 +212,8 @@
       }
       if(S->type == TYPE_FILE) {
         buf_print(B,
-               "\t\t<size>%lu</size>\r\n",
-               (unsigned long) S->inf->st_size);
+               "\t\t<size>%llu</size>\r\n",
+               (unsigned long long) S->inf->st_size);
         if(S->checksum) {
           buf_print(B,
                  "\t\t<checksum type=\"%s\">%s</checksum>\r\n",
Index: http/cervlet.c
===================================================================
RCS file: /sources/monit/monit/http/cervlet.c,v
retrieving revision 1.203
diff -u -r1.203 cervlet.c
--- http/cervlet.c      23 Jun 2006 20:47:39 -0000      1.203
+++ http/cervlet.c      25 Jun 2006 05:03:37 -0000
@@ -1133,11 +1133,11 @@
     } else {
       
       out_print(res,
-       "<td align=\"right\">%lu&nbsp;B</td>"
+       "<td align=\"right\">%llu&nbsp;B</td>"
        "<td align=\"right\">%o</td>"
        "<td align=\"right\">%d</td>"
        "<td align=\"right\">%d</td>",
-       (unsigned long)s->inf->st_size,
+       (unsigned long long)s->inf->st_size,
        s->inf->st_mode & 07777,
        s->inf->st_uid,
        s->inf->st_gid);
@@ -1748,7 +1748,7 @@
 
         out_print(res,
           "<tr><td>Associated size</td>"
-          "<td>If %s %lu byte(s) %s then %s else if passed %s then 
%s</td></tr>",
+          "<td>If %s %llu byte(s) %s then %s else if passed %s then 
%s</td></tr>",
           operatornames[sl->operator], sl->size,
           ratio1, actionnames[a->failed->id],
           ratio2, actionnames[a->passed->id]);
@@ -2235,9 +2235,9 @@
     } else {
 
       out_print(res,
-        "<tr><td>Size</td><td><font%s>%lu B</td></tr>",
+        "<tr><td>Size</td><td><font%s>%llu B</td></tr>",
         (s->error & EVENT_SIZE)?" color='#ff0000'":"",
-        (unsigned long) s->inf->st_size);
+        (unsigned long long) s->inf->st_size);
 
     }
   }
@@ -2484,8 +2484,8 @@
       }
       if(s->type == TYPE_FILE) {
         out_print(res,
-               "  %-33s %lu B\n",
-               "size", (unsigned long) s->inf->st_size);
+               "  %-33s %llu B\n",
+               "size", (unsigned long long) s->inf->st_size);
         if(s->checksum) {
        out_print(res,
                  "  %-33s %s(%s)\n",

reply via email to

[Prev in Thread] Current Thread [Next in Thread]