]> granicus.if.org Git - sysstat/commitdiff
Make sure that datafiles with unknown activities can be read by sar
authorSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 23 Jan 2022 09:57:16 +0000 (10:57 +0100)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 23 Jan 2022 09:57:16 +0000 (10:57 +0100)
When the structure containing statistics for an activity is modified
(with the number of fields of type A increased and of type B decreased),
sar and sadf might not be able to read the corresponding datafile.
Make sure that they can read the other activities in file, even if the
unknown activity is ignored.

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

diff --git a/sa.h b/sa.h
index bc47b6cd7479e662c567df9e7b1e8539f14107f0..a695821b863ddad0d967f574709deeb20efbc35c 100644 (file)
--- a/sa.h
+++ b/sa.h
@@ -634,11 +634,6 @@ struct file_header {
  * Base magical number for activities.
  */
 #define ACTIVITY_MAGIC_BASE    0x8a
-/*
- * Magical value used for activities with
- * unknown format (used for sadf -H only).
- */
-#define ACTIVITY_MAGIC_UNKNOWN 0x89
 
 /* List of activities saved in file */
 struct file_activity {
index 87e6363d872d2fb9fef4ef49370faf36831d7fc1..35ed7567e7b53571ea36cad507b79b80cd12c394 100644 (file)
@@ -2020,19 +2020,11 @@ void check_file_actlst(int *ifd, char *dfile, struct activity *act[], uint64_t f
                        /* Unknown activity */
                        continue;
 
-               skip = FALSE;
-               if (fal->magic != act[p]->magic) {
-                       /* Bad magical number */
-                       if (DISPLAY_HDR_ONLY(flags)) {
-                               /*
-                                * This is how sadf -H knows that this
-                                * activity has an unknown format.
-                                */
-                               act[p]->magic = ACTIVITY_MAGIC_UNKNOWN;
-                       }
-                       else {
-                               skip = TRUE;
-                       }
+               if ((fal->magic != act[p]->magic) && !DISPLAY_HDR_ONLY(flags)) {
+                       skip = TRUE;
+               }
+               else {
+                       skip = FALSE;
                }
 
                /* Check max value for known activities */
@@ -2047,7 +2039,8 @@ void check_file_actlst(int *ifd, char *dfile, struct activity *act[], uint64_t f
                /*
                 * Number of fields of each type ("long long", or "long"
                 * or "int") composing the structure with statistics may
-                * only increase with new sysstat versions. Here, we may
+                * only increase with new sysstat versions, unless we change
+                * the activity's magic number. Here, we may
                 * be reading a file created by current sysstat version,
                 * or by an older or a newer version.
                 */
@@ -2058,15 +2051,7 @@ void check_file_actlst(int *ifd, char *dfile, struct activity *act[], uint64_t f
                     ((fal->types_nr[0] <= act[p]->gtypes_nr[0]) &&
                     (fal->types_nr[1] <= act[p]->gtypes_nr[1]) &&
                     (fal->types_nr[2] <= act[p]->gtypes_nr[2]))) &&
-                    (act[p]->magic != ACTIVITY_MAGIC_UNKNOWN) && !DISPLAY_HDR_ONLY(flags)) {
-                       /*
-                        * This may not be an error (that's actually why we may have changed
-                        * the magic number for this activity above).
-                        * So, if the activity magic number has changed (e.g.: ACTIVITY_MAGIC_UNKNOWN)
-                        * and we want to display only the header, then ignore the error.
-                        * If we want to also display the stats then we must stop here because
-                        * we won't know how to map the contents of the stats structure.
-                        */
+                    (fal->magic == act[p]->magic) && !DISPLAY_HDR_ONLY(flags)) {
 #ifdef DEBUG
                        fprintf(stderr, "%s: id=%d file=%d,%d,%d activity=%d,%d,%d\n",
                                __FUNCTION__, fal->id, fal->types_nr[0], fal->types_nr[1], fal->types_nr[2],
@@ -2083,13 +2068,6 @@ void check_file_actlst(int *ifd, char *dfile, struct activity *act[], uint64_t f
                        goto format_error;
                }
 
-               if (skip)
-                       /*
-                        * This is an unknown activity and we want stats about it:
-                        * This is not possible so skip it.
-                        */
-                       continue;
-
                for (k = 0; k < 3; k++) {
                        act[p]->ftypes_nr[k] = fal->types_nr[k];
                }
@@ -2101,12 +2079,15 @@ void check_file_actlst(int *ifd, char *dfile, struct activity *act[], uint64_t f
                act[p]->nr_ini = fal->nr;
                act[p]->nr2    = fal->nr2;
                act[p]->fsize  = fal->size;
+
                /*
                 * This is a known activity with a known format
                 * (magical number). Only such activities will be displayed.
                 * (Well, this may also be an unknown format if we have entered sadf -H.)
                 */
-               id_seq[j++] = fal->id;
+               if (!skip) {
+                       id_seq[j++] = fal->id;
+               }
        }
 
        while (j < NR_ACT) {
index 7e7eddfbd2fe9ad9e79cb27d229c126edc23f96f..473e5d939b2082edee1aad237e22763a539b6644 100644 (file)
@@ -1276,7 +1276,7 @@ __printf_funct_t print_hdr_header(void *parm, int action, char *dfile,
                                printf("x%d", fal->nr2);
                        }
                        printf("\t(%d,%d,%d)", fal->types_nr[0], fal->types_nr[1], fal->types_nr[2]);
-                       if ((p >= 0) && (act[p]->magic == ACTIVITY_MAGIC_UNKNOWN)) {
+                       if ((p >= 0) && (act[p]->magic != fal->magic)) {
                                printf(_(" \t[Unknown format]"));
                        }
                        printf("\n");