]> granicus.if.org Git - sysstat/commitdiff
sadf: PCP: Fix illegal result timestamp error
authorSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 7 Apr 2019 06:36:38 +0000 (08:36 +0200)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 7 Apr 2019 06:36:38 +0000 (08:36 +0200)
pmiWrite() function (from the PCP API) has a very nasty impact on
mktime().
Once pmiWrite has been called, subsequent mktime() calls will no longer
give the same result using the same input data, resulting in timestamps
that can be wrong because associated with a different timezone.
This patch tries to fix that.

Signed-off-by: Sebastien GODARD <sysstat@users.noreply.github.com>
sadf_misc.c

index 30f924b6cf39716915373aefb5cbbe1c8ac31ef4..9211f2bd6cf890a3c6a59abba443a8630f4038de 100644 (file)
@@ -867,12 +867,28 @@ __tm_funct_t print_pcp_timestamp(void *parm, int action, char *cur_date,
        int rc;
        struct tm lrectime;
        unsigned long long utc_sec = record_hdr->ust_time;
+       static long long delta_utc = LONG_MAX;
 
        if (action & F_END) {
                if (!PRINT_LOCAL_TIME(flags)) {
-                       /* Convert a time_t value from local time to UTC */
-                       if (gmtime_r((const time_t *) &(record_hdr->ust_time), &lrectime)) {
-                               utc_sec = mktime(&lrectime);
+                       if (delta_utc == LONG_MAX) {
+                               /* Convert a time_t value from local time to UTC */
+                               if (gmtime_r((const time_t *) &(record_hdr->ust_time), &lrectime)) {
+                                       utc_sec = mktime(&lrectime);
+                                       delta_utc = utc_sec - record_hdr->ust_time;
+                               }
+                       }
+                       else {
+                               /*
+                                * Once pmiWrite() has been called (after the first stats sample),
+                                * subsequent mktime() calls will not give the same result with
+                                * the same input data. So compute a time shift that will be used
+                                * for the next samples.
+                                * We should (really) be careful if pmiWrite() was to be used sooner
+                                * than for the first stats sample (e.g. if we want to save a
+                                * LINUX RESTART record heading the file).
+                                */
+                               utc_sec += delta_utc;
                        }
                }
 
@@ -1242,6 +1258,8 @@ __printf_funct_t print_pcp_header(void *parm, int action, char *dfile,
 {
 #ifdef HAVE_PCP
        char buf[64];
+       struct tm lrectime;
+       unsigned long long utc_sec = file_hdr->sa_ust_time;
 
        if (action & F_BEGIN) {
                /* Create new PCP context */
@@ -1269,7 +1287,14 @@ __printf_funct_t print_pcp_header(void *parm, int action, char *dfile,
 
        if (action & F_END) {
                if (action & F_BEGIN) {
-                       pmiWrite(file_hdr->sa_ust_time, 0);
+                       /* Only the header data will be written to PCP archive */
+                       if (!PRINT_LOCAL_TIME(flags)) {
+                               /* Convert a time_t value from local time to UTC */
+                               if (gmtime_r((const time_t *) &(file_hdr->sa_ust_time), &lrectime)) {
+                                       utc_sec = mktime(&lrectime);
+                               }
+                       }
+                       pmiWrite(utc_sec, 0);
                }
                pmiEnd();
        }