]> granicus.if.org Git - sysstat/commitdiff
Added a new magical value for each activity in file.
authorSebastien Godard <sysstat@orange.fr>
Sun, 10 Oct 2010 14:39:28 +0000 (16:39 +0200)
committerSebastien Godard <sysstat@orange.fr>
Sun, 10 Oct 2010 14:39:28 +0000 (16:39 +0200)
A format change can now hit only one activity instead of the whole file.
Sadf has also been updated to be able to display activities with
unknown format (sadf -H).

CHANGES
activity.c
sa.h
sa_common.c
sadc.c
sadf.c
sar.c

diff --git a/CHANGES b/CHANGES
index a918eb7ba4de28ad7f3da73a0369fc4d2391cb53..84280f4987a4019a4c9ba665a3730e427bf968c1 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,9 @@ Changes:
 xxxx/xx/xx: Version 9.1.6 - Sebastien Godard (sysstat <at> orange.fr)
          WARNING: Daily data files format has changed, and is *not*
          compatible with the previous one! [0x2171]
+       * Added a new magical value for each activity in file.
+         A format change can now hit only one activity instead of
+         the whole file.
        * Added hugepages utilization statistics to sar.
        * [Ivana Varekova]: Moved manual pages to $prefix/share/man
          instead of $prefix/man.
index 81ff0a1c01c28b87828f3003de3f8f9fef6e4083..23293da29785544c7af460d170e3aa3ebdb517fc 100644 (file)
@@ -66,6 +66,7 @@ struct act_bitmap irq_bitmap = {
 struct activity cpu_act = {
        .id             = A_CPU,
        .options        = AO_COLLECTED + AO_REMANENT + AO_GLOBAL_ITV + AO_MULTIPLE_OUTPUTS,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = wrap_get_cpu_nr,
        .f_count2       = NULL,
@@ -95,6 +96,7 @@ struct activity cpu_act = {
 struct activity pcsw_act = {
        .id             = A_PCSW,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -123,6 +125,7 @@ struct activity pcsw_act = {
 struct activity irq_act = {
        .id             = A_IRQ,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = wrap_get_irq_nr,
        .f_count2       = NULL,
@@ -151,6 +154,7 @@ struct activity irq_act = {
 struct activity swap_act = {
        .id             = A_SWAP,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -179,6 +183,7 @@ struct activity swap_act = {
 struct activity paging_act = {
        .id             = A_PAGE,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -208,6 +213,7 @@ struct activity paging_act = {
 struct activity io_act = {
        .id             = A_IO,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -236,6 +242,7 @@ struct activity io_act = {
 struct activity memory_act = {
        .id             = A_MEMORY,
        .options        = AO_COLLECTED + AO_MULTIPLE_OUTPUTS,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -266,6 +273,7 @@ struct activity memory_act = {
 struct activity ktables_act = {
        .id             = A_KTABLES,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -294,6 +302,7 @@ struct activity ktables_act = {
 struct activity queue_act = {
        .id             = A_QUEUE,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -322,6 +331,7 @@ struct activity queue_act = {
 struct activity serial_act = {
        .id             = A_SERIAL,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = wrap_get_serial_nr,
        .f_count2       = NULL,
@@ -350,6 +360,7 @@ struct activity serial_act = {
 struct activity disk_act = {
        .id             = A_DISK,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = wrap_get_disk_nr,
        .f_count2       = NULL,
@@ -378,6 +389,7 @@ struct activity disk_act = {
 struct activity net_dev_act = {
        .id             = A_NET_DEV,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = wrap_get_iface_nr,
        .f_count2       = NULL,
@@ -406,6 +418,7 @@ struct activity net_dev_act = {
 struct activity net_edev_act = {
        .id             = A_NET_EDEV,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = wrap_get_iface_nr,
        .f_count2       = NULL,
@@ -435,6 +448,7 @@ struct activity net_edev_act = {
 struct activity net_nfs_act = {
        .id             = A_NET_NFS,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -463,6 +477,7 @@ struct activity net_nfs_act = {
 struct activity net_nfsd_act = {
        .id             = A_NET_NFSD,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -492,6 +507,7 @@ struct activity net_nfsd_act = {
 struct activity net_sock_act = {
        .id             = A_NET_SOCK,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -520,6 +536,7 @@ struct activity net_sock_act = {
 struct activity net_ip_act = {
        .id             = A_NET_IP,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -548,6 +565,7 @@ struct activity net_ip_act = {
 struct activity net_eip_act = {
        .id             = A_NET_EIP,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -576,6 +594,7 @@ struct activity net_eip_act = {
 struct activity net_icmp_act = {
        .id             = A_NET_ICMP,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -605,6 +624,7 @@ struct activity net_icmp_act = {
 struct activity net_eicmp_act = {
        .id             = A_NET_EICMP,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -634,6 +654,7 @@ struct activity net_eicmp_act = {
 struct activity net_tcp_act = {
        .id             = A_NET_TCP,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -662,6 +683,7 @@ struct activity net_tcp_act = {
 struct activity net_etcp_act = {
        .id             = A_NET_ETCP,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -690,6 +712,7 @@ struct activity net_etcp_act = {
 struct activity net_udp_act = {
        .id             = A_NET_UDP,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -718,6 +741,7 @@ struct activity net_udp_act = {
 struct activity net_sock6_act = {
        .id             = A_NET_SOCK6,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -746,6 +770,7 @@ struct activity net_sock6_act = {
 struct activity net_ip6_act = {
        .id             = A_NET_IP6,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -775,6 +800,7 @@ struct activity net_ip6_act = {
 struct activity net_eip6_act = {
        .id             = A_NET_EIP6,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -804,6 +830,7 @@ struct activity net_eip6_act = {
 struct activity net_icmp6_act = {
        .id             = A_NET_ICMP6,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -834,6 +861,7 @@ struct activity net_icmp6_act = {
 struct activity net_eicmp6_act = {
        .id             = A_NET_EICMP6,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -863,6 +891,7 @@ struct activity net_eicmp6_act = {
 struct activity net_udp6_act = {
        .id             = A_NET_UDP6,
        .options        = AO_CLOSE_MARKUP,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
@@ -891,6 +920,7 @@ struct activity net_udp6_act = {
 struct activity pwr_cpufreq_act = {
        .id             = A_PWR_CPUFREQ,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = wrap_get_cpu_nr,
        .f_count2       = NULL,
@@ -919,6 +949,7 @@ struct activity pwr_cpufreq_act = {
 struct activity pwr_fan_act = {
        .id             = A_PWR_FAN,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = wrap_get_fan_nr,
        .f_count2       = NULL,
@@ -947,6 +978,7 @@ struct activity pwr_fan_act = {
 struct activity pwr_temp_act = {
        .id             = A_PWR_TEMP,
        .options        = AO_NULL,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = wrap_get_temp_nr,
        .f_count2       = NULL,
@@ -975,6 +1007,7 @@ struct activity pwr_temp_act = {
 struct activity pwr_in_act = {
        .id             = A_PWR_IN,
        .options        = AO_CLOSE_MARKUP,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = wrap_get_in_nr,
        .f_count2       = NULL,
@@ -1003,6 +1036,7 @@ struct activity pwr_in_act = {
 struct activity huge_act = {
        .id             = A_HUGE,
        .options        = AO_COLLECTED,
+       .magic          = ACTIVITY_MAGIC_BASE,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
        .f_count2       = NULL,
diff --git a/sa.h b/sa.h
index 33eadd0c2cdf879a9b237276842b26b97b9392ef..ec51d9ed3c4749154f72780ee96c96446e833c94 100644 (file)
--- a/sa.h
+++ b/sa.h
@@ -284,6 +284,12 @@ struct activity {
         * Activity options (AO_SELECTED, ...)
         */
        unsigned int options;
+       /*
+        * Activity magical number. This number changes when activity format in file
+        * is no longer compatible with the format of that same activity from
+        * previous versions.
+        */
+       unsigned int magic;
        /*
         * The f_count() function is used to count the number of
         * items (serial lines, network interfaces, etc.) -> @nr
@@ -507,12 +513,26 @@ struct file_header {
 #define FILE_HEADER_SIZE       (sizeof(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 {
        /*
         * Identification value of activity.
         */
        unsigned int id         __attribute__ ((aligned (4)));
+       /*
+        * Activity magical number.
+        */
+       unsigned int magic      __attribute__ ((packed));
        /*
         * Number of items for this activity.
         */
index e0ec8551a1303801dbc23e031bf2e0c1d6089e13..72eff3cbced5c5362b378d3f59264fe087d089d5 100644 (file)
@@ -990,10 +990,11 @@ void read_file_stat_bunch(struct activity *act[], int curr, int ifd, int act_nr,
 
        for (i = 0; i < act_nr; i++, fal++) {
 
-               if ((p = get_activity_position(act, fal->id)) < 0) {
+               if (((p = get_activity_position(act, fal->id)) < 0) ||
+                   (act[p]->magic != fal->magic)) {
                        /*
                         * Ignore current activity in file, which is unknown to
-                        * current sysstat version.
+                        * current sysstat version or has an unknown format.
                         */
                        if (lseek(ifd, fal->size * fal->nr * fal->nr2, SEEK_CUR) < (fal->size * fal->nr * fal->nr2)) {
                                close(ifd);
@@ -1095,23 +1096,46 @@ void check_file_actlst(int *ifd, char *dfile, struct activity *act[],
                        handle_invalid_sa_file(ifd, file_magic, dfile, 0);
                }
 
+               if ((p = get_activity_position(act, fal->id)) < 0)
+                       /* Unknown activity */
+                       continue;
+               
+               if (act[p]->magic != fal->magic) {
+                       /* Bad magical number */
+                       if (ignore) {
+                               /*
+                                * This is how sadf -H knows that this
+                                * activity has an unknown format.
+                                */
+                               act[p]->magic = ACTIVITY_MAGIC_UNKNOWN;
+                       }
+                       else
+                               continue;
+               }
+
                if (fal->id == A_CPU) {
                        a_cpu = TRUE;
                }
 
-               if ((p = get_activity_position(act, fal->id)) >= 0) {
-                       if (fal->size > act[p]->msize) {
-                               act[p]->msize = fal->size;
-                       }
-                       act[p]->fsize = fal->size;
-                       act[p]->nr    = fal->nr;
-                       act[p]->nr2   = fal->nr2;
-                       id_seq[j++]   = fal->id;
+               if (fal->size > act[p]->msize) {
+                       act[p]->msize = fal->size;
                }
+               act[p]->fsize = fal->size;
+               act[p]->nr    = fal->nr;
+               act[p]->nr2   = fal->nr2;
+               /*
+                * 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 (!a_cpu) {
-               /* CPU activity should always be in file */
+               /*
+                * CPU activity should always be in file
+                * and have a known format (expected magical number).
+                */
                handle_invalid_sa_file(ifd, file_magic, dfile, 0);
        }
 
diff --git a/sadc.c b/sadc.c
index a3a6b571a6dacd1eaa522af1c44eb67c3de6bdc3..0489e1206aa79d81357b718b5992cad9364b4233 100644 (file)
--- a/sadc.c
+++ b/sadc.c
@@ -249,6 +249,7 @@ void sa_sys_init(void)
                                act[i]->nr2 = (*act[i]->f_count2)(act[i]);
                        }
                        /* else act[i]->nr2 is a constant and doesn't need to be calculated */
+                       
                        if (!act[i]->nr2) {
                                act[i]->nr = 0;
                        }
@@ -415,7 +416,7 @@ void fill_magic_header(struct file_magic *file_magic)
  * Fill system activity file header, then write it (or print it if stdout).
  *
  * IN:
- * @fd                 Output file descriptor. May be stdout.
+ * @fd Output file descriptor. May be stdout.
  ***************************************************************************
  */
 void setup_file_hdr(int fd)
@@ -473,10 +474,11 @@ void setup_file_hdr(int fd)
                        continue;
 
                if (IS_COLLECTED(act[p]->options)) {
-                       file_act.id   = act[p]->id;
-                       file_act.nr   = act[p]->nr;
-                       file_act.nr2  = act[p]->nr2;
-                       file_act.size = act[p]->fsize;
+                       file_act.id    = act[p]->id;
+                       file_act.magic = act[p]->magic;
+                       file_act.nr    = act[p]->nr;
+                       file_act.nr2   = act[p]->nr2;
+                       file_act.size  = act[p]->fsize;
 
                        if ((n = write_all(fd, &file_act, FILE_ACTIVITY_SIZE))
                            != FILE_ACTIVITY_SIZE)
@@ -502,8 +504,8 @@ write_error:
  * before the cron daemon is started to avoid conflict with sa1/sa2 scripts.
  *
  * IN:
- * @ofd                        Output file descriptor.
- * @rtype              Record type to write (dummy or comment).
+ * @ofd                Output file descriptor.
+ * @rtype      Record type to write (dummy or comment).
  ***************************************************************************
  */
 void write_special_record(int ofd, int rtype)
@@ -547,7 +549,7 @@ void write_special_record(int ofd, int rtype)
  * Write stats (or print them if stdout).
  *
  * IN:
- * @ofd                        Output file descriptor. May be stdout.
+ * @ofd                Output file descriptor. May be stdout.
  ***************************************************************************
  */
 void write_stats(int ofd)
@@ -591,10 +593,10 @@ void write_stats(int ofd)
  * Create a system activity daily data file.
  *
  * IN:
- * @ofile              Name of output file.
+ * @ofile      Name of output file.
  *
  * OUT:
- * @ofd                        Output file descriptor.
+ * @ofd                Output file descriptor.
  ***************************************************************************
  */
 void create_sa_file(int *ofd, char *ofile)
@@ -623,11 +625,11 @@ void create_sa_file(int *ofd, char *ofile)
  * Get descriptor for stdout.
  *
  * IN:
- * @stdfd              A value >= 0 indicates that stats data should also
- *                     be written to stdout.
+ * @stdfd      A value >= 0 indicates that stats data should also
+ *             be written to stdout.
  *
  * OUT:
- * @stdfd              Stdout file descriptor.
+ * @stdfd      Stdout file descriptor.
  ***************************************************************************
  */
 void open_stdout(int *stdfd)
@@ -648,10 +650,10 @@ void open_stdout(int *stdfd)
  * We may enter this function several times (when we rotate a file).
  *
  * IN:
- * @ofile              Name of output file.
+ * @ofile      Name of output file.
  *
  * OUT:
- * @ofd                        Output file descriptor.
+ * @ofd                Output file descriptor.
  ***************************************************************************
  */
 void open_ofile(int *ofd, char ofile[])
@@ -727,8 +729,12 @@ void open_ofile(int *ofd, char ofile[])
 
                                p = get_activity_position(act, file_act.id);
 
-                               if ((p < 0) || (act[p]->fsize != file_act.size))
-                                       /* Unknown activity in list or item size has changed */
+                               if ((p < 0) || (act[p]->fsize != file_act.size) ||
+                                   (act[p]->magic != file_act.magic))
+                                       /*
+                                        * Unknown activity in list or item size has changed or
+                                        * unknown activity format.
+                                        */
                                        goto append_error;
 
                                if ((act[p]->nr != file_act.nr) || (act[p]->nr2 != file_act.nr2)) {
diff --git a/sadf.c b/sadf.c
index 45006ca04b4b24ab1d7843767c499dd550e9d11b..b746442cb9a68fba6741d559505a62075f83e4c9 100644 (file)
--- a/sadf.c
+++ b/sadf.c
@@ -591,9 +591,9 @@ void sadf_print_special(int curr, int use_tm_start, int use_tm_end, int rtype, i
  * Display data file header.
  *
  * IN:
- * @dfile      Name of system activity data file
- * @file_magic System activity file magic header
- * @file_hdr   System activity file standard header
+ * @dfile      Name of system activity data file.
+ * @file_magic System activity file magic header.
+ * @file_hdr   System activity file standard header.
  ***************************************************************************
  */
 void display_file_header(char *dfile, struct file_magic *file_magic,
@@ -601,7 +601,7 @@ void display_file_header(char *dfile, struct file_magic *file_magic,
 {
        int i, p;
        static __nr_t cpu_nr = -1;
-       
+
        if (cpu_nr < 0) {
                cpu_nr = act[get_activity_position(act, A_CPU)]->nr;
        }
@@ -632,7 +632,10 @@ void display_file_header(char *dfile, struct file_magic *file_magic,
                }
                printf("%02d: %s\t(x%d)", act[p]->id, act[p]->name, act[p]->nr);
                if (act[p]->f_count2 || (act[p]->nr2 > 1)) {
-                       printf(" (x%d)", act[p]->nr2);
+                       printf("\t(x%d)", act[p]->nr2);
+               }
+               if (act[p]->magic == ACTIVITY_MAGIC_UNKNOWN) {
+                       printf(_("\t[Unknown activity format]"));
                }
                printf("\n");
        }
diff --git a/sar.c b/sar.c
index 861291401236de056986689cb504d052c77486a3..84cc5627529a15390b53f2eac5f9752aa65e0bd1 100644 (file)
--- a/sar.c
+++ b/sar.c
@@ -804,7 +804,9 @@ void read_header_data(void)
 
                if ((p < 0) || (act[p]->fsize != file_act.size)
                            || !file_act.nr
-                           || !file_act.nr2) {
+                           || !file_act.nr2
+                           || (act[p]->magic != file_act.magic)) {
+                       /* Remember that we are reading data from sadc and not from a file... */
                        fprintf(stderr, _("Inconsistent input data\n"));
                        exit(3);
                }
@@ -894,7 +896,10 @@ void read_stats_from_file(char from_file[])
                        exit(2);
                }
 
-               /* Read and write stats located between two possible Linux restarts */
+               /*
+                * Read and write stats located between two possible Linux restarts.
+                * Activities that should be displayed are saved in id_seq[] array.
+                */
                for (i = 0; i < NR_ACT; i++) {
 
                        if (!id_seq[i])