From: Sebastien GODARD Date: Mon, 25 Sep 2017 15:39:17 +0000 (+0200) Subject: sadc/sar: New format (part 5): Remap file_header structure X-Git-Tag: v11.7.1~69 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6dd65059d5f38d43c8fbf30c7690e9eb8d8c403f;p=sysstat sadc/sar: New format (part 5): Remap file_header structure 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 --- diff --git a/sa.h b/sa.h index 296ec45..53860cc 100644 --- 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 { /* diff --git a/sa_common.c b/sa_common.c index 2b84e4b..ee2b972 100644 --- a/sa_common.c +++ b/sa_common.c @@ -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 e58dac9..e8928de 100644 --- 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 */