]> granicus.if.org Git - sysstat/commitdiff
sar: Take into account a change of CPU number in sar datafile (1)
authorSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 26 Jan 2014 16:28:15 +0000 (17:28 +0100)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 26 Jan 2014 16:28:15 +0000 (17:28 +0100)
On virtual machine, after CPU change (e.g. power off machine ->
add 1 cpu -> power on machine), sar command doesn't display
previous data (from today) from the current saXX file.

This is the first patch aimed at making sar able to take into account
a change of CPU count in its datafiles.

This patch adds a new field into file's header data (last_cpu_nr)
which gives the number of CPU the machine had when the last sample of
data was appended to the file.
Sar data file format is no longer compatible with that from previous
sysstat versions. To be able to add other fields to file's header
in the future without making it incompatible again, also add a
field (header_size) to file's magic data giving the size of file's
header.

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

diff --git a/sa.h b/sa.h
index dfa3c52acf5796e80ce30cd128bd817527bad4fa..d24eb8e145c773992ef304ced32c1e51b6eb3d01 100644 (file)
--- a/sa.h
+++ b/sa.h
@@ -480,10 +480,14 @@ struct activity {
  * Modified to indicate that the format of the file is
  * no longer compatible with that of previous sysstat versions.
  */
-#define FORMAT_MAGIC   0x2171
+#define FORMAT_MAGIC   0x2172
 
 /* Structure for file magic header data */
 struct file_magic {
+       /*
+        * Size of file's header (size of file_header structure used by file).
+        */
+       unsigned int header_size;
        /*
         * This field identifies the file as a file created by sysstat.
         */
@@ -510,6 +514,10 @@ struct file_header {
         * Timestamp in seconds since the epoch.
         */
        unsigned long sa_ust_time       __attribute__ ((aligned (8)));
+       /*
+        * Number of CPU items (1 .. CPU_NR + 1) for the last sample in file.
+        */
+       unsigned int last_cpu_nr;
        /*
         * Number of activities saved in the file
         */
index cf066a361158bde53ceb50ae13ca2301e7076473..52cb3c225f5b2f466c9f40d5173309385008394c 100644 (file)
@@ -1103,6 +1103,7 @@ void check_file_actlst(int *ifd, char *dfile, struct activity *act[],
        int i, j, n, p;
        unsigned int a_cpu = FALSE;
        struct file_activity *fal;
+       void *buffer = NULL;
 
        /* Open sa data file */
        if ((*ifd = open(dfile, O_RDONLY)) < 0) {
@@ -1128,9 +1129,13 @@ void check_file_actlst(int *ifd, char *dfile, struct activity *act[],
                }
        }
 
+       SREALLOC(buffer, char, file_magic->header_size);
+       
        /* Read sa data file standard header and allocate activity list */
-       sa_fread(*ifd, file_hdr, FILE_HEADER_SIZE, HARD_SIZE);
-
+       sa_fread(*ifd, buffer, file_magic->header_size, HARD_SIZE);
+       memcpy(file_hdr, buffer, MINIMUM(file_magic->header_size, FILE_HEADER_SIZE));
+       free(buffer);
+       
        SREALLOC(*file_actlst, struct file_activity, FILE_ACTIVITY_SIZE * file_hdr->sa_nr_act);
        fal = *file_actlst;
 
diff --git a/sadc.c b/sadc.c
index ab3e0ca9b7dbc712b5c621b5bcc5ef70b86b42f6..8f42fd83c9fac7383611fa3941833f7518fe3645 100644 (file)
--- a/sadc.c
+++ b/sadc.c
@@ -436,6 +436,8 @@ void fill_magic_header(struct file_magic *file_magic)
 
        memset(file_magic, 0, FILE_MAGIC_SIZE);
 
+       file_magic->header_size = FILE_HEADER_SIZE;
+       
        file_magic->sysstat_magic = SYSSTAT_MAGIC;
        file_magic->format_magic  = FORMAT_MAGIC;
        file_magic->sysstat_extraversion = 0;
@@ -713,7 +715,8 @@ void open_ofile(int *ofd, char ofile[])
        struct file_magic file_magic;
        struct file_activity file_act[NR_ACT];
        struct tm rectime;
-       ssize_t sz;
+       void *buffer = NULL;
+       ssize_t sz, n;
        int i, p;
 
        if (ofile[0]) {
@@ -750,8 +753,14 @@ void open_ofile(int *ofd, char ofile[])
                                handle_invalid_sa_file(ofd, &file_magic, ofile, sz);
                        }
 
+                       SREALLOC(buffer, char, file_magic.header_size);
+       
                        /* Read file standard header */
-                       if (read(*ofd, &file_hdr, FILE_HEADER_SIZE) != FILE_HEADER_SIZE) {
+                       n = read(*ofd, buffer, file_magic.header_size);
+                       memcpy(&file_hdr, buffer, MINIMUM(file_magic.header_size, FILE_HEADER_SIZE));
+                       free(buffer);
+                       
+                       if (n != file_magic.header_size) {
                                /* Display error message and exit */
                                handle_invalid_sa_file(ofd, &file_magic, ofile, 0);
                        }
diff --git a/sar.c b/sar.c
index b28c5b1f84a61d425d7336863de6ba5fb1c428e2..92c2229b888d0c78a952a0e2ed642d777a3e9140 100644 (file)
--- a/sar.c
+++ b/sar.c
@@ -829,7 +829,12 @@ void read_header_data(void)
                exit(3);
        }
 
-       /* Read header data */
+       /*
+        * Read header data.
+        * No need to take into account file_magic.header_size. We are sure that
+        * sadc and sar are from the same version (we have checked FORMAT_MAGIC
+        * but also VERSION above) and thus the size of file_header is FILE_HEADER_SIZE.
+        */
        if (sa_read(&file_hdr, FILE_HEADER_SIZE)) {
                print_read_error();
        }