]> granicus.if.org Git - sysstat/commitdiff
sadc/sar: New format (part 5): Remap file_header structure
authorSebastien GODARD <sysstat@users.noreply.github.com>
Mon, 25 Sep 2017 15:39:17 +0000 (17:39 +0200)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Mon, 25 Sep 2017 15:39:17 +0000 (17:39 +0200)
Remap file_header structure from an older (or newer) sysstat version to
current format (from current sysstat version).

file_header is one the structure composing the header of a binary data
file.

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

diff --git a/sa.h b/sa.h
index 296ec45fa2c4d89372ab7dec6aeb27f39a973e1f..53860cc111bf4c8774ab767b70e0a667c73dcfbb 100644 (file)
--- a/sa.h
+++ b/sa.h
@@ -372,7 +372,7 @@ struct svg_hdr_parm {
 #define PREVIOUS_FORMAT_MAGIC  0x2173
 
 /* Padding in file_magic structure. See below. */
-#define FILE_MAGIC_PADDING     60
+#define FILE_MAGIC_PADDING     48
 
 /* Structure for file magic header data */
 struct file_magic {
@@ -391,6 +391,9 @@ struct file_magic {
        unsigned char sysstat_patchlevel;
        unsigned char sysstat_sublevel;
        unsigned char sysstat_extraversion;
+#define FILE_MAGIC_ULL_NR      0       /* Nr of unsigned long long below */
+#define FILE_MAGIC_UL_NR       0       /* Nr of unsigned long below */
+#define FILE_MAGIC_U_NR                5       /* Nr of [unsigned] int below */
        /*
         * Size of file's header (size of file_header structure used by file).
         */
@@ -402,6 +405,11 @@ struct file_magic {
         * The FORMAT_MAGIC value of the file can be used to determine X.
         */
        unsigned int upgraded;
+       /*
+        * Description of the file_header structure
+        * (nr of "long long", nr of "long" and nr of "int").
+        */
+       unsigned int hdr_types_nr[3];
        /*
         * Padding. Reserved for future use while avoiding a format change.
         * sysstat always reads a number of bytes which is that expected for
@@ -413,7 +421,6 @@ struct file_magic {
 
 #define FILE_MAGIC_SIZE        (sizeof(struct file_magic))
 
-
 /* Header structure for system activity data file */
 struct file_header {
        /*
index 2b84e4ba3a626b334676b695f7f4765ec48a3316..ee2b972cd3ccc797d22a221a6957b306d9a3aaa3 100644 (file)
@@ -1338,6 +1338,7 @@ int sa_open_read_magic(int *fd, char *dfile, struct file_magic *file_magic,
                       int ignore, int *endian_mismatch)
 {
        int n;
+       unsigned int fm_types_nr[] = {FILE_MAGIC_ULL_NR, FILE_MAGIC_UL_NR, FILE_MAGIC_U_NR};
 
        /* Open sa data file */
        if ((*fd = open(dfile, O_RDONLY)) < 0) {
@@ -1366,7 +1367,7 @@ int sa_open_read_magic(int *fd, char *dfile, struct file_magic *file_magic,
                /* Swap bytes for file_magic fields */
                file_magic->sysstat_magic = __builtin_bswap16(file_magic->sysstat_magic);
                file_magic->format_magic  = __builtin_bswap16(file_magic->format_magic);
-               file_magic->header_size   = __builtin_bswap32(file_magic->header_size);
+               swap_struct(fm_types_nr, &file_magic->header_size, 0);
        }
 
        if ((file_magic->sysstat_version > 10) ||
@@ -1379,6 +1380,14 @@ int sa_open_read_magic(int *fd, char *dfile, struct file_magic *file_magic,
                        handle_invalid_sa_file(fd, file_magic, dfile, n);
                }
        }
+       if ((file_magic->sysstat_version > 11) ||
+           ((file_magic->sysstat_version == 11) && (file_magic->sysstat_patchlevel >= 7))) {
+               /* hdr_types_nr field exists only for sysstat versions 11.7.1 and later */
+               if (MAP_SIZE(file_magic->hdr_types_nr) > file_magic->header_size) {
+                       handle_invalid_sa_file(fd, file_magic, dfile, n);
+               }
+       }
+
        if (file_magic->format_magic != FORMAT_MAGIC)
                /* This is an old (or new) sa datafile format */
                return -1;
@@ -1434,9 +1443,11 @@ void check_file_actlst(int *ifd, char *dfile, struct activity *act[],
        /* Read sa data file standard header and allocate activity list */
        sa_fread(*ifd, buffer, file_magic->header_size, HARD_SIZE);
        /*
-        * Data file header size may be greater than FILE_HEADER_SIZE, but
-        * anyway only the first FILE_HEADER_SIZE bytes can be interpreted.
+        * Data file header size (file_magic->header_size) may be greater or
+        * smaller than FILE_HEADER_SIZE. Remap the fields of the file header
+        * then copy its contents to the expected  structure.
         */
+       remap_struct(hdr_types_nr, file_magic->hdr_types_nr, buffer, file_magic->header_size);
        memcpy(file_hdr, buffer, FILE_HEADER_SIZE);
        free(buffer);
 
diff --git a/sadc.c b/sadc.c
index e58dac9c9436abbab9ca59238fb06df7538cc5de..e8928de86b7f71700d70ed8f5a2639ac4ccb1c30 100644 (file)
--- a/sadc.c
+++ b/sadc.c
@@ -72,6 +72,7 @@ char comment[MAX_COMMENT_LEN];
 unsigned int id_seq[NR_ACT];
 unsigned int vol_id_seq[NR_ACT];
 
+extern unsigned int hdr_types_nr[];
 extern struct activity *act[];
 extern __nr_t (*f_count[]) (struct activity *);
 
@@ -458,14 +459,20 @@ int ask_for_flock(int fd, int fatal)
  */
 void fill_magic_header(struct file_magic *file_magic)
 {
-       memset(file_magic, 0, FILE_MAGIC_SIZE);
+       int i;
 
-       file_magic->header_size = FILE_HEADER_SIZE;
+       memset(file_magic, 0, FILE_MAGIC_SIZE);
 
        file_magic->sysstat_magic = SYSSTAT_MAGIC;
        file_magic->format_magic  = FORMAT_MAGIC;
 
        enum_version_nr(file_magic);
+
+       file_magic->header_size = FILE_HEADER_SIZE;
+
+       for (i = 0; i < 3; i++) {
+               file_magic->hdr_types_nr[i] = hdr_types_nr[i];
+       }
 }
 
 /*
@@ -851,10 +858,15 @@ void open_ofile(int *ofd, char ofile[], int restart_mark)
                create_sa_file(ofd, ofile);
                return;
        }
+
+       /* Test various values ("strict writing" rule) */
        if ((sz != FILE_MAGIC_SIZE) ||
            (file_magic.sysstat_magic != SYSSTAT_MAGIC) ||
            (file_magic.format_magic != FORMAT_MAGIC) ||
-           (file_magic.header_size != FILE_HEADER_SIZE)) {
+           (file_magic.header_size != FILE_HEADER_SIZE) ||
+           (file_magic.hdr_types_nr[0] != FILE_HEADER_ULL_NR) ||
+           (file_magic.hdr_types_nr[1] != FILE_HEADER_UL_NR) ||
+           (file_magic.hdr_types_nr[2] != FILE_HEADER_U_NR)) {
                if (FORCE_FILE(flags)) {
                        close(*ofd);
                        /* -F option used: Truncate file */