]> granicus.if.org Git - sysstat/commitdiff
Add function to remap a structure
authorSebastien GODARD <sysstat@users.noreply.github.com>
Fri, 22 Sep 2017 06:33:13 +0000 (08:33 +0200)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Fri, 22 Sep 2017 06:33:13 +0000 (08:33 +0200)
This function will be used to map two structures from two
different sysstat versions.
It will thus be possible to add new fields, e.g., in structures
containing statistics and still be possible for another sysstat version
to read its contents properly.

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

diff --git a/sa.h b/sa.h
index a79c48edf0992477340c8abc202dfe89f3d278bb..50f4c45ce315c527778468eec351ae6f0d464962 100644 (file)
--- a/sa.h
+++ b/sa.h
@@ -1194,6 +1194,8 @@ __nr_t read_vol_act_structures
        (int, struct activity * [], char *, struct file_magic *, unsigned int, int, int);
 int reallocate_vol_act_structures
        (struct activity * [], unsigned int, unsigned int);
+void remap_struct
+       (int [], int [], void *, int);
 void replace_nonprintable_char
        (int, char *);
 int sa_fread
index d7cb66e627420901b9b8951dde566ea0aeee9ec2..2fe29f328a716298d69417e973367173407d8dac 100644 (file)
@@ -1029,6 +1029,77 @@ void swap_struct(int types_nr[], void *ps, int is64bit)
        }
 }
 
+/*
+ ***************************************************************************
+ * Map the fields of a structure containing statistics read from a file to
+ * those of the structure known by current sysstat version.
+ * Each structure (either read from file or from current sysstat version)
+ * are described by 3 values: The number of [unsigned] long long integers,
+ * the number of [unsigned] long integers following in the structure, and
+ * last the number of [unsigned] integers.
+ * We assume that those numbers will *never* decrease with newer sysstat
+ * versions.
+ *
+ * IN:
+ * @gtypes_nr  Structure description as expected for current sysstat version.
+ * @ftypes_nr  Structure description as read from file.
+ * @ps         Pointer on structure containing statistics.
+ * @st_size    Size of the structure containing statistics. This is the size
+ *             of the structure *read from file* (not the size of the
+ *             structure expected by current sysstat version).
+ ***************************************************************************
+ */
+void remap_struct(int gtypes_nr[], int ftypes_nr[], void *ps, int st_size)
+{
+       int d;
+
+       /* Remap [unsigned] long fields */
+       d = gtypes_nr[0] - ftypes_nr[0];
+       if (d) {
+               memmove(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH,
+                       ((char *) ps) + ftypes_nr[0] * ULL_ALIGNMENT_WIDTH,
+                       st_size - ftypes_nr[0] * ULL_ALIGNMENT_WIDTH);
+               if (d > 0) {
+                       memset(((char *) ps) + ftypes_nr[0] * ULL_ALIGNMENT_WIDTH,
+                              0, d * ULL_ALIGNMENT_WIDTH);
+               }
+       }
+       /* Remap [unsigned] int fields */
+       d = gtypes_nr[1] - ftypes_nr[1];
+       if (d) {
+               memmove(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH
+                                     + gtypes_nr[1] * UL_ALIGNMENT_WIDTH,
+                       ((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH
+                                     + ftypes_nr[1] * UL_ALIGNMENT_WIDTH,
+                       st_size - ftypes_nr[0] * ULL_ALIGNMENT_WIDTH
+                               - ftypes_nr[1] * UL_ALIGNMENT_WIDTH);
+               if (d > 0) {
+                       memset(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH
+                                            + ftypes_nr[1] * UL_ALIGNMENT_WIDTH,
+                              0, d * UL_ALIGNMENT_WIDTH);
+               }
+       }
+       /* Remap possible fields (like strings of chars) following int fields */
+       d = gtypes_nr[2] - ftypes_nr[2];
+       if (d) {
+               memmove(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH
+                                     + gtypes_nr[1] * UL_ALIGNMENT_WIDTH
+                                     + gtypes_nr[2] * U_ALIGNMENT_WIDTH,
+                       ((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH
+                                     + gtypes_nr[1] * UL_ALIGNMENT_WIDTH
+                                     + ftypes_nr[2] * U_ALIGNMENT_WIDTH,
+                       st_size - ftypes_nr[0] * ULL_ALIGNMENT_WIDTH
+                               - ftypes_nr[1] * UL_ALIGNMENT_WIDTH
+                               - ftypes_nr[2] * U_ALIGNMENT_WIDTH);
+               if (d > 0) {
+                       memset(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH
+                                            + gtypes_nr[1] * UL_ALIGNMENT_WIDTH
+                                            + ftypes_nr[2] * U_ALIGNMENT_WIDTH,
+                              0, d * U_ALIGNMENT_WIDTH);
+               }
+       }
+}
+
 /*
  ***************************************************************************
  * Read data from a system activity data file.