[OpenAFS-devel] patch to reset volume usage data at midnight in current timezone

Rainer Toebbicke rtb@pclella.cern.ch
Fri, 13 Jan 2006 16:11:08 +0100


This is a multi-part message in MIME format.
--------------020007030204050907020001
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

This is the second go at a problem I already reported in spring 2005 - 
at the time it was pointed out that my solution at was based on a 
misunderstanding.

volume.c (fileserver) uses the second parameter of gettimeofday to 
determine the timezone offset in order to calculate when midnight is 
(rather: was). However, that second parameter is non-standard and does 
not work e.g. on Solaris where the effectively calculated midnight 
then depends on the contents of the stack.

This patch uses localtime() and mktime() to calculate midnight, the 
additional overhead is neglegible given it does not happen very often.

The result has of course its own little problems on the two switching 
days: in spring (on the nothern hemisphere) because the 
daylight-saving-flag will be incorrect depending on when the routine 
is called (however, I haven't seen an implementation of mktime() yet 
that really cares) and again in the autumn when for one hour "in the 
past day" actually means 25 not 24 hours. Both issues could of course 
still be addressed, but that gets messy to do in a portable manner and 
in the current code layout. Hence simply a comment.

(Bcc'ed to openafs-bugs).

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Rainer Toebbicke
European Laboratory for Particle Physics(CERN) - Geneva, Switzerland
Phone: +41 22 767 8985       Fax: +41 22 767 7155

--------------020007030204050907020001
Content-Type: text/plain;
 name="patch_timezone"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="patch_timezone"

--- openafs/src/vol/volume.c.2rig	2005-06-17 14:25:54.000000000 +0200
+++ openafs/src/vol/volume.c	2005-06-20 10:54:07.000000000 +0200
@@ -228,8 +228,6 @@
 
 extern struct Lock FSYNC_handler_lock;
 
-static int TimeZoneCorrection;	/* Number of seconds west of GMT */
-
 /* Common message used when the volume goes off line */
 char *VSalvageMessage =
     "Files in this volume are currently unavailable; call operations";
@@ -255,8 +253,6 @@
 		   int connect, int volcache)
 {
     int errors = 0;		/* Number of errors while finding vice partitions. */
-    struct timeval tv;
-    struct timezone tz;
 
     programType = pt;
 
@@ -273,8 +269,6 @@
     Lock_Init(&vol_listLock);
     Lock_Init(&FSYNC_handler_lock);
     srandom(time(0));		/* For VGetVolumeInfo */
-    gettimeofday(&tv, &tz);
-    TimeZoneCorrection = tz.tz_minuteswest * 60;
 
     if (volcache > VolumeCacheSize)
 	VolumeCacheSize = volcache;
@@ -1809,7 +1803,29 @@
 #define OneDay	(24*60*60)	/* 24 hours */
 #endif /* OPENAFS_VOL_STATS */
 
-#define Midnight(date) ((date-TimeZoneCorrection)/OneDay*OneDay+TimeZoneCorrection)
+static time_t
+Midnight(time_t t) {
+    struct tm local;
+    time_t midnight;
+
+#ifdef AFS_PTHREAD_ENV
+    localtime_r(&t, &local);
+#else
+    local = *localtime(&t);
+#endif
+
+    /* the following is strictly speaking problematic on the
+       switching day to daylight saving time, after the switch,
+       as tm_isdst does not match.  Similarly, on the looong day when
+       switching back the OneDay check will not do what naively expected!
+       The effects are minor, though, and more a matter of interpreting
+       the numbers. */
+    local.tm_hour = local.tm_min=local.tm_sec = 0;
+    midnight = mktime(&local);
+
+    return( (midnight!=(time_t) -1) ? midnight : (t/OneDay)*OneDay );
+
+}
 
 /*------------------------------------------------------------------------
  * [export] VAdjustVolumeStatistics

--------------020007030204050907020001--