#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 {
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).
*/
* 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
#define FILE_MAGIC_SIZE (sizeof(struct file_magic))
-
/* Header structure for system activity data file */
struct file_header {
/*
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) {
/* 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) ||
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;
/* 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);
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 *);
*/
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];
+ }
}
/*
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 */