From 3e5cb4c968dac23e2cfc20d1467f624b27d2ae6a Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Fri, 11 Jul 2014 09:56:06 +0200 Subject: [PATCH] Option -c added to sadf: Upgrade an old sa datafile This patch adds option -c to sadf. This option enables the user to upgrade ("convert") an old system activity datafile (version 9.1.6 and later) to the up-to-date format (11.1.1 as of today). Enter "sadf -c old_datafile >new_datafile". Signed-off-by: Sebastien GODARD --- Makefile.in | 4 +- format.c | 16 +- sa.h | 16 +- sa_common.c | 122 +++++-- sa_conv.c | 1003 +++++++++++++++++++++++++++++++++++++++++++++++++++ sa_conv.h | 148 ++++++++ sadc.c | 26 +- sadf.c | 19 +- sadf.h | 5 +- 9 files changed, 1298 insertions(+), 61 deletions(-) create mode 100644 sa_conv.c create mode 100644 sa_conv.h diff --git a/Makefile.in b/Makefile.in index 7880270..45bd140 100644 --- a/Makefile.in +++ b/Makefile.in @@ -208,6 +208,8 @@ format.o: format.c sadf.h sadf_misc.o: sadf_misc.c sadf.h sa.h +sa_conv.o: sa_conv.c sadf.h sa.h sa_conv.h + # Explicit rules needed to prevent possible file corruption # when using parallel execution. libsyscom.a: common.o ioconf.o @@ -233,7 +235,7 @@ sar: sar.o act_sar.o sa_common.o pr_stats.o libsyscom.a sadf.o: sadf.c sadf.h version.h sa.h common.h ioconf.h sysconfig.h -sadf: sadf.o act_sadf.o format.o sadf_misc.o rndr_stats.o xml_stats.o json_stats.o sa_common.o libsyscom.a +sadf: sadf.o act_sadf.o format.o sadf_misc.o sa_conv.o rndr_stats.o xml_stats.o json_stats.o sa_common.o libsyscom.a iostat.o: iostat.c iostat.h version.h common.h ioconf.h sysconfig.h rd_stats.h count.h diff --git a/format.c b/format.c index 9c331cf..6a957ea 100644 --- a/format.c +++ b/format.c @@ -94,6 +94,19 @@ struct report_format json_fmt = { .f_comment = print_json_comment }; +/* + * Display only datafile header. + */ +struct report_format conv_fmt = { + .id = F_CONV_OUTPUT, + .options = FO_BAD_FILE_FORMAT, + .f_header = NULL, + .f_statistics = NULL, + .f_timestamp = NULL, + .f_restart = NULL, + .f_comment = NULL +}; + /* * Array of output formats. */ @@ -102,5 +115,6 @@ struct report_format *fmt[NR_FMT] = { &db_fmt, &ppc_fmt, &xml_fmt, - &json_fmt + &json_fmt, + &conv_fmt }; diff --git a/sa.h b/sa.h index 4240b82..3f970c0 100644 --- a/sa.h +++ b/sa.h @@ -487,6 +487,9 @@ struct activity { */ #define FORMAT_MAGIC 0x2173 +/* Previous datafile format magic number used by older sysstat versions */ +#define PREVIOUS_FORMAT_MAGIC 0x2171 + /* Structure for file magic header data */ struct file_magic { /* @@ -508,10 +511,17 @@ struct file_magic { * Size of file's header (size of file_header structure used by file). */ unsigned int header_size; + /* + * Set to non zero if data file has been converted with "sadf -c" from + * an old format (version x.y.z) to a newest format (version X.Y.Z). + * In this case, the value is: Y*16 + Z + 1. + * The FORMAT_MAGIC value of the file can be used to determine X. + */ + unsigned char upgraded; /* * Padding. Reserved for future use while avoiding a format change. */ - unsigned char pad[64]; + unsigned char pad[63]; }; #define FILE_MAGIC_SIZE (sizeof(struct file_magic)) @@ -829,6 +839,8 @@ extern int datecmp(struct tm *, struct tstamp *); extern void display_sa_file_version(FILE *, struct file_magic *); +extern void + enum_version_nr(struct file_magic *); extern void free_bitmaps(struct activity * []); extern void @@ -871,6 +883,8 @@ extern int reallocate_vol_act_structures(struct activity * [], unsigned int, unsigned int); extern int sa_fread(int, void *, int, int); +extern int + sa_open_read_magic(int *, char *, struct file_magic *, int); extern void select_all_activities(struct activity * []); extern void diff --git a/sa_common.c b/sa_common.c index 9f485a4..66ebe43 100644 --- a/sa_common.c +++ b/sa_common.c @@ -31,6 +31,7 @@ #include #include +#include "version.h" #include "sa.h" #include "common.h" #include "ioconf.h" @@ -1209,37 +1210,30 @@ void read_file_stat_bunch(struct activity *act[], int curr, int ifd, int act_nr, /* *************************************************************************** - * Open a data file, and perform various checks before reading. + * Open a sysstat activity data file and read its magic structure. * * IN: - * @dfile Name of system activity data file - * @act Array of activities. + * @dfile Name of system activity data file. * @ignore Set to 1 if a true sysstat activity file but with a bad * format should not yield an error message. Useful with * sadf -H. * * OUT: - * @ifd System activity data file descriptor + * @fd System activity data file descriptor. * @file_magic file_magic structure containing data read from file magic - * header - * @file_hdr file_hdr structure containing data read from file standard - * header - * @file_actlst Acvtivity list in file. - * @id_seq Activity sequence. + * header. + * + * RETURNS: + * -1 if data file is a sysstat file with an old format, 0 otherwise. *************************************************************************** */ -void check_file_actlst(int *ifd, char *dfile, struct activity *act[], - struct file_magic *file_magic, struct file_header *file_hdr, - struct file_activity **file_actlst, unsigned int id_seq[], +int sa_open_read_magic(int *fd, char *dfile, struct file_magic *file_magic, int ignore) { - int i, j, n, p; - unsigned int a_cpu = FALSE; - struct file_activity *fal; - void *buffer = NULL; + int n; /* Open sa data file */ - if ((*ifd = open(dfile, O_RDONLY)) < 0) { + if ((*fd = open(dfile, O_RDONLY)) < 0) { int saved_errno = errno; fprintf(stderr, _("Cannot open %s: %s\n"), dfile, strerror(errno)); @@ -1251,22 +1245,55 @@ void check_file_actlst(int *ifd, char *dfile, struct activity *act[], } /* Read file magic data */ - n = read(*ifd, file_magic, FILE_MAGIC_SIZE); + n = read(*fd, file_magic, FILE_MAGIC_SIZE); if ((n != FILE_MAGIC_SIZE) || (file_magic->sysstat_magic != SYSSTAT_MAGIC) || - (file_magic->format_magic != FORMAT_MAGIC)) { - - if (ignore && - (n == FILE_MAGIC_SIZE) && - (file_magic->sysstat_magic == SYSSTAT_MAGIC)) - /* Don't display error message. This is for sadf -H */ - return; - else { - /* Display error message and exit */ - handle_invalid_sa_file(ifd, file_magic, dfile, n); - } + ((file_magic->format_magic != FORMAT_MAGIC) && !ignore)) { + /* Display error message and exit */ + handle_invalid_sa_file(fd, file_magic, dfile, n); } + if (file_magic->format_magic != FORMAT_MAGIC) + /* This is an old sa datafile format */ + return -1; + + return 0; +} + +/* + *************************************************************************** + * Open a data file, and perform various checks before reading. + * + * IN: + * @dfile Name of system activity data file. + * @act Array of activities. + * @ignore Set to 1 if a true sysstat activity file but with a bad + * format should not yield an error message. Useful with + * sadf -H. + * + * OUT: + * @ifd System activity data file descriptor. + * @file_magic file_magic structure containing data read from file magic + * header. + * @file_hdr file_hdr structure containing data read from file standard + * header. + * @file_actlst Acvtivity list in file. + * @id_seq Activity sequence. + *************************************************************************** + */ +void check_file_actlst(int *ifd, char *dfile, struct activity *act[], + struct file_magic *file_magic, struct file_header *file_hdr, + struct file_activity **file_actlst, unsigned int id_seq[], + int ignore) +{ + int i, j, p; + unsigned int a_cpu = FALSE; + struct file_activity *fal; + void *buffer = NULL; + + /* Open sa data file and read its magic structure */ + if (sa_open_read_magic(ifd, dfile, file_magic, ignore) < 0) + return; SREALLOC(buffer, char, file_magic->header_size); @@ -1940,3 +1967,40 @@ double compute_ifutil(struct stats_net_dev *st_net_dev, double rx, double tx) return 0; } +/* + *************************************************************************** + * Fill system activity file magic header. + * + * IN: + * @file_magic System activity file magic header. + *************************************************************************** + */ +void enum_version_nr(struct file_magic *fm) +{ + char *v; + char version[16]; + + fm->sysstat_extraversion = 0; + + strcpy(version, VERSION); + + /* Get version number */ + if ((v = strtok(version, ".")) == NULL) + return; + fm->sysstat_version = atoi(v) & 0xff; + + /* Get patchlevel number */ + if ((v = strtok(NULL, ".")) == NULL) + return; + fm->sysstat_patchlevel = atoi(v) & 0xff; + + /* Get sublevel number */ + if ((v = strtok(NULL, ".")) == NULL) + return; + fm->sysstat_sublevel = atoi(v) & 0xff; + + /* Get extraversion number. Don't necessarily exist */ + if ((v = strtok(NULL, ".")) == NULL) + return; + fm->sysstat_extraversion = atoi(v) & 0xff; +} diff --git a/sa_conv.c b/sa_conv.c new file mode 100644 index 0000000..e2f7725 --- /dev/null +++ b/sa_conv.c @@ -0,0 +1,1003 @@ +/* + * sa_conv.c: Convert an old format sa file to the up-to-date format. + * (C) 1999-2014 by Sebastien GODARD (sysstat orange.fr) + * + *************************************************************************** + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * + * for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + *************************************************************************** + */ + +#include +#include +#include +#include +#include + +#include "version.h" +#include "sadf.h" +#include "sa.h" +#include "sa_conv.h" + +#ifdef USE_NLS +# include +# include +# define _(string) gettext(string) +#else +# define _(string) (string) +#endif + +/* + *************************************************************************** + * Read and upgrade file's magic data section. + * + * IN: + * @dfile System activity data file name. + * @stdfd File descriptor for STDOUT. + * + * OUT: + * @fd File descriptor for sa datafile to convert. + * @file_magic Pointer on file_magic structure. + * @previous_format TRUE is sa datafile has an old format which is no + * longer compatible with current one. + * + * RETURNS: + * -1 on error, 0 otherwise. + *************************************************************************** + */ +int upgrade_magic_section(char dfile[], int *fd, int stdfd, + struct file_magic *file_magic, int *previous_format) +{ + int n; + struct file_magic fm; + + /* Open and read sa magic structure */ + sa_open_read_magic(fd, dfile, file_magic, TRUE); + + if ((file_magic->format_magic != FORMAT_MAGIC) && + (file_magic->format_magic != PREVIOUS_FORMAT_MAGIC)) { + fprintf(stderr, _("Cannot convert the format of this file\n")); + return -1; + } + + fprintf(stderr, "file_magic: "); + if (file_magic->format_magic == PREVIOUS_FORMAT_MAGIC) { + /* + * We have read too many bytes: file_magic structure + * was smaller with previous sysstat versions. + * Go back 4 (unsigned int header_size) + 64 (char pad[64]) bytes. + */ + if (lseek(*fd, -68, SEEK_CUR) < 0) { + fprintf(stderr, "\nlseek: %s\n", strerror(errno)); + return -1; + } + /* Set format magic number to that of current version */ + *previous_format = TRUE; + file_magic->format_magic = FORMAT_MAGIC; + + /* Fill new structure members */ + file_magic->header_size = FILE_HEADER_SIZE; + memset(file_magic->pad, 0, 64); + } + + /* Indicate that file has been upgraded */ + enum_version_nr(&fm); + file_magic->upgraded = (fm.sysstat_patchlevel << 4) + + fm.sysstat_sublevel + 1; + + /* Write file_magic structure */ + if ((n = write(stdfd, file_magic, FILE_MAGIC_SIZE)) != FILE_MAGIC_SIZE) { + fprintf(stderr, "\nwrite: %s\n", strerror(errno)); + return -1; + } + fprintf(stderr, "OK\n"); + + return 0; +} + +/* + *************************************************************************** + * Upgrade file_header structure (from 0x2171 format to current format). + * + * IN: + * @buffer Pointer on file's header structure (as read from file). + * + * OUT: + * @file_hdr Pointer on file_header structure (up-to-date format). + *************************************************************************** + */ +void upgrade_file_header(void *buffer, struct file_header *file_hdr) +{ + struct file_header_2171 *f_hdr = (struct file_header_2171 *) buffer; + + file_hdr->sa_ust_time = f_hdr->sa_ust_time; + file_hdr->sa_act_nr = f_hdr->sa_act_nr; + file_hdr->sa_day = f_hdr->sa_day; + file_hdr->sa_month = f_hdr->sa_month; + file_hdr->sa_year = f_hdr->sa_year; + file_hdr->sa_sizeof_long = f_hdr->sa_sizeof_long; + strncpy(file_hdr->sa_sysname, f_hdr->sa_sysname, UTSNAME_LEN); + file_hdr->sa_sysname[UTSNAME_LEN - 1] = '\0'; + strncpy(file_hdr->sa_nodename, f_hdr->sa_nodename, UTSNAME_LEN); + file_hdr->sa_nodename[UTSNAME_LEN - 1] = '\0'; + strncpy(file_hdr->sa_release, f_hdr->sa_release, UTSNAME_LEN); + file_hdr->sa_release[UTSNAME_LEN - 1] = '\0'; + strncpy(file_hdr->sa_machine, f_hdr->sa_machine, UTSNAME_LEN); + file_hdr->sa_machine[UTSNAME_LEN - 1] = '\0'; + /* The last two values below will be updated later */ + file_hdr->sa_vol_act_nr = 0; + file_hdr->sa_last_cpu_nr = 0; +} + +/* + *************************************************************************** + * Upgrade stats_io structure (from ACTIVITY_MAGIC_BASE format to + * ACTIVITY_MAGIC_BASE + 1 format). + * + * IN: + * @act Array of activities. + * @p Position of activity in array. + *************************************************************************** + */ +void upgrade_stats_io(struct activity *act[], int p) +{ + struct stats_io *sic = (struct stats_io *) act[p]->buf[1]; + struct stats_io_8a *sip = (struct stats_io_8a *) act[p]->buf[0]; + + sic->dk_drive = (unsigned long long) sip->dk_drive; + sic->dk_drive_rio = (unsigned long long) sip->dk_drive_rio; + sic->dk_drive_wio = (unsigned long long) sip->dk_drive_wio; + sic->dk_drive_rblk = (unsigned long long) sip->dk_drive_rblk; + sic->dk_drive_wblk = (unsigned long long) sip->dk_drive_wblk; +} + +/* + *************************************************************************** + * Upgrade stats_queue structure (from ACTIVITY_MAGIC_BASE format to + * ACTIVITY_MAGIC_BASE + 1 format). + * + * IN: + * @act Array of activities. + * @p Position of activity in array. + *************************************************************************** + */ +void upgrade_stats_queue(struct activity *act[], int p) +{ + struct stats_queue *sqc = (struct stats_queue *) act[p]->buf[1]; + struct stats_queue_8a *sqp = (struct stats_queue_8a *) act[p]->buf[0]; + + sqc->nr_running = sqp->nr_running; + sqc->procs_blocked = 0; /* New field */ + sqc->load_avg_1 = sqp->load_avg_1; + sqc->load_avg_5 = sqp->load_avg_5; + sqc->load_avg_15 = sqp->load_avg_15; + sqc->nr_threads = sqp->nr_threads; +} + +/* + *************************************************************************** + * Upgrade stats_disk structure (from ACTIVITY_MAGIC_BASE format to + * ACTIVITY_MAGIC_BASE + 1 format). + * + * IN: + * @act Array of activities. + * @p Position of activity in array. + *************************************************************************** + */ +void upgrade_stats_disk(struct activity *act[], int p) +{ + int i; + struct stats_disk *sdc; + struct stats_disk_8a *sdp; + + for (i = 0; i < act[p]->nr; i++) { + sdp = (struct stats_disk_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize); + sdc = (struct stats_disk *) ((char *) act[p]->buf[1] + i * act[p]->fsize); + + sdc->nr_ios = (unsigned long long) sdp->nr_ios; + sdc->rd_sect = (unsigned long) sdp->rd_sect; + sdc->wr_sect = (unsigned long) sdp->wr_sect; + sdc->rd_ticks = (unsigned int) sdp->rd_ticks; + sdc->wr_ticks = (unsigned int) sdp->wr_ticks; + sdc->tot_ticks = (unsigned int) sdp->tot_ticks; + sdc->rq_ticks = (unsigned int) sdp->rq_ticks; + sdc->major = sdp->major; + sdc->minor = sdp->minor; + } +} + +/* + *************************************************************************** + * Upgrade stats_net_dev structure (from ACTIVITY_MAGIC_BASE or + * ACTIVITY_MAGIC_BASE + 1 format to ACTIVITY_MAGIC_BASE + 2 format). + * + * IN: + * @act Array of activities. + * @p Position of activity in array. + * @m_format Structure format magic value. + *************************************************************************** + */ +void upgrade_stats_net_dev(struct activity *act[], int p, unsigned int m_format) +{ + int i; + struct stats_net_dev *sndc; + + if (m_format == ACTIVITY_MAGIC_BASE) { + struct stats_net_dev_8a *sndp_a; + + for (i = 0; i < act[p]->nr; i++) { + sndp_a = (struct stats_net_dev_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize); + sndc = (struct stats_net_dev *) ((char *) act[p]->buf[1] + i * act[p]->fsize); + + sndc->rx_packets = (unsigned long long) sndp_a->rx_packets; + sndc->tx_packets = (unsigned long long) sndp_a->tx_packets; + sndc->rx_bytes = (unsigned long long) sndp_a->rx_bytes; + sndc->tx_bytes = (unsigned long long) sndp_a->tx_bytes; + sndc->rx_compressed = (unsigned long long) sndp_a->rx_compressed; + sndc->tx_compressed = (unsigned long long) sndp_a->tx_compressed; + sndc->multicast = (unsigned long long) sndp_a->multicast; + sndc->speed = 0; /* New field */ + strncpy(sndc->interface, sndp_a->interface, MAX_IFACE_LEN); + sndc->interface[MAX_IFACE_LEN - 1] = '\0'; + sndc->duplex = '\0'; /* New field */ + } + } + else { + struct stats_net_dev_8b *sndp_b; + + for (i = 0; i < act[p]->nr; i++) { + sndp_b = (struct stats_net_dev_8b *) ((char *) act[p]->buf[0] + i * act[p]->msize); + sndc = (struct stats_net_dev *) ((char *) act[p]->buf[1] + i * act[p]->fsize); + + sndc->rx_packets = sndp_b->rx_packets; + sndc->tx_packets = sndp_b->tx_packets; + sndc->rx_bytes = sndp_b->rx_bytes; + sndc->tx_bytes = sndp_b->tx_bytes; + sndc->rx_compressed = sndp_b->rx_compressed; + sndc->tx_compressed = sndp_b->tx_compressed; + sndc->multicast = sndp_b->multicast; + sndc->speed = 0; /* New field */ + strncpy(sndc->interface, sndp_b->interface, MAX_IFACE_LEN); + sndc->interface[MAX_IFACE_LEN - 1] = '\0'; + sndc->duplex = '\0'; /* New field */ + } + } +} + +/* + *************************************************************************** + * Upgrade stats_net_edev structure (from ACTIVITY_MAGIC_BASE format to + * ACTIVITY_MAGIC_BASE + 1 format). + * + * IN: + * @act Array of activities. + * @p Position of activity in array. + *************************************************************************** + */ +void upgrade_stats_net_edev(struct activity *act[], int p) +{ + int i; + struct stats_net_edev *snedc; + struct stats_net_edev_8a *snedp; + + for (i = 0; i < act[p]->nr; i++) { + snedp = (struct stats_net_edev_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize); + snedc = (struct stats_net_edev *) ((char *) act[p]->buf[1] + i * act[p]->fsize); + + snedc->collisions = (unsigned long long) snedp->collisions; + snedc->rx_errors = (unsigned long long) snedp->rx_errors; + snedc->tx_errors = (unsigned long long) snedp->tx_errors; + snedc->rx_dropped = (unsigned long long) snedp->rx_dropped; + snedc->tx_dropped = (unsigned long long) snedp->tx_dropped; + snedc->rx_fifo_errors = (unsigned long long) snedp->rx_fifo_errors; + snedc->tx_fifo_errors = (unsigned long long) snedp->tx_fifo_errors; + snedc->rx_frame_errors = (unsigned long long) snedp->rx_frame_errors; + snedc->tx_carrier_errors = (unsigned long long) snedp->tx_carrier_errors; + strncpy(snedc->interface, snedp->interface, MAX_IFACE_LEN); + snedc->interface[MAX_IFACE_LEN - 1] = '\0'; + } +} + +/* + *************************************************************************** + * Upgrade stats_net_ip structure (from ACTIVITY_MAGIC_BASE format to + * ACTIVITY_MAGIC_BASE + 1 format). + * + * IN: + * @act Array of activities. + * @p Position of activity in array. + *************************************************************************** + */ +void upgrade_stats_net_ip(struct activity *act[], int p) +{ + struct stats_net_ip *snic = (struct stats_net_ip *) act[p]->buf[1]; + struct stats_net_ip_8a *snip = (struct stats_net_ip_8a *) act[p]->buf[0]; + + snic->InReceives = (unsigned long long) snip->InReceives; + snic->ForwDatagrams = (unsigned long long) snip->ForwDatagrams; + snic->InDelivers = (unsigned long long) snip->InDelivers; + snic->OutRequests = (unsigned long long) snip->OutRequests; + snic->ReasmReqds = (unsigned long long) snip->ReasmReqds; + snic->ReasmOKs = (unsigned long long) snip->ReasmOKs; + snic->FragOKs = (unsigned long long) snip->FragOKs; + snic->FragCreates = (unsigned long long) snip->FragCreates; +} + +/* + *************************************************************************** + * Upgrade stats_net_eip structure (from ACTIVITY_MAGIC_BASE format to + * ACTIVITY_MAGIC_BASE + 1 format). + * + * IN: + * @act Array of activities. + * @p Position of activity in array. + *************************************************************************** + */ +void upgrade_stats_net_eip(struct activity *act[], int p) +{ + struct stats_net_eip *sneic = (struct stats_net_eip *) act[p]->buf[1]; + struct stats_net_eip_8a *sneip = (struct stats_net_eip_8a *) act[p]->buf[0]; + + sneic->InHdrErrors = (unsigned long long) sneip->InHdrErrors; + sneic->InAddrErrors = (unsigned long long) sneip->InAddrErrors; + sneic->InUnknownProtos = (unsigned long long) sneip->InUnknownProtos; + sneic->InDiscards = (unsigned long long) sneip->InDiscards; + sneic->OutDiscards = (unsigned long long) sneip->OutDiscards; + sneic->OutNoRoutes = (unsigned long long) sneip->OutNoRoutes; + sneic->ReasmFails = (unsigned long long) sneip->ReasmFails; + sneic->FragFails = (unsigned long long) sneip->FragFails; +} + +/* + *************************************************************************** + * Upgrade stats_net_ip6 structure (from ACTIVITY_MAGIC_BASE format to + * ACTIVITY_MAGIC_BASE + 1 format). + * + * IN: + * @act Array of activities. + * @p Position of activity in array. + *************************************************************************** + */ +void upgrade_stats_net_ip6(struct activity *act[], int p) +{ + struct stats_net_ip6 *snic6 = (struct stats_net_ip6 *) act[p]->buf[1]; + struct stats_net_ip6_8a *snip6 = (struct stats_net_ip6_8a *) act[p]->buf[0]; + + snic6->InReceives6 = (unsigned long long) snip6->InReceives6; + snic6->OutForwDatagrams6 = (unsigned long long) snip6->OutForwDatagrams6; + snic6->InDelivers6 = (unsigned long long) snip6->InDelivers6; + snic6->OutRequests6 = (unsigned long long) snip6->OutRequests6; + snic6->ReasmReqds6 = (unsigned long long) snip6->ReasmReqds6; + snic6->ReasmOKs6 = (unsigned long long) snip6->ReasmOKs6; + snic6->InMcastPkts6 = (unsigned long long) snip6->InMcastPkts6; + snic6->OutMcastPkts6 = (unsigned long long) snip6->OutMcastPkts6; + snic6->FragOKs6 = (unsigned long long) snip6->FragOKs6; + snic6->FragCreates6 = (unsigned long long) snip6->FragCreates6; +} + +/* + *************************************************************************** + * Upgrade stats_net_eip6 structure (from ACTIVITY_MAGIC_BASE format to + * ACTIVITY_MAGIC_BASE + 1 format). + * + * IN: + * @act Array of activities. + * @p Position of activity in array. + *************************************************************************** + */ +void upgrade_stats_net_eip6(struct activity *act[], int p) +{ + struct stats_net_eip6 *sneic6 = (struct stats_net_eip6 *) act[p]->buf[1]; + struct stats_net_eip6_8a *sneip6 = (struct stats_net_eip6_8a *) act[p]->buf[0]; + + sneic6->InHdrErrors6 = (unsigned long long) sneip6->InHdrErrors6; + sneic6->InAddrErrors6 = (unsigned long long) sneip6->InAddrErrors6; + sneic6->InUnknownProtos6 = (unsigned long long) sneip6->InUnknownProtos6; + sneic6->InTooBigErrors6 = (unsigned long long) sneip6->InTooBigErrors6; + sneic6->InDiscards6 = (unsigned long long) sneip6->InDiscards6; + sneic6->OutDiscards6 = (unsigned long long) sneip6->OutDiscards6; + sneic6->InNoRoutes6 = (unsigned long long) sneip6->InNoRoutes6; + sneic6->OutNoRoutes6 = (unsigned long long) sneip6->OutNoRoutes6; + sneic6->ReasmFails6 = (unsigned long long) sneip6->ReasmFails6; + sneic6->FragFails6 = (unsigned long long) sneip6->FragFails6; + sneic6->InTruncatedPkts6 = (unsigned long long) sneip6->InTruncatedPkts6; +} + +/* + *************************************************************************** + * Read and upgrade file's header section. + * + * IN: + * @dfile System activity data file name. + * @fd File descriptor for sa datafile to convert. + * @stdfd File descriptor for STDOUT. + * @act Array of activities. + * @file_magic Pointer on file_magic structure. + * @previous_format TRUE is sa datafile has an old format which is no + * longer compatible with current one. + * + * OUT: + * @file_hdr Pointer on file_header structure. + * @file_actlst Activity list in file. + * @vol_id_seq Sequence of volatile activities. + * + * RETURNS: + * -1 on error, 0 otherwise. +*************************************************************************** + */ +int upgrade_header_section(char dfile[], int fd, int stdfd, + struct activity *act[], struct file_magic *file_magic, + struct file_header *file_hdr, int previous_format, + struct file_activity **file_actlst, unsigned int vol_id_seq[]) +{ + int i, j, n, p; + unsigned int a_cpu = FALSE; + void *buffer = NULL; + struct file_activity *fal; + + /* Read file header structure */ + fprintf(stderr, "file_header: "); + + if (previous_format) { + /* Previous format had 2 unsigned int less */ + n = FILE_HEADER_SIZE - 8; + } + else { + n = file_magic->header_size; + } + + SREALLOC(buffer, char, n); + + sa_fread(fd, buffer, n, HARD_SIZE); + + if (previous_format) { + /* Upgrade file_header structure */ + upgrade_file_header(buffer, file_hdr); + } + else { + memcpy(file_hdr, buffer, MINIMUM(n, FILE_HEADER_SIZE)); + } + + free(buffer); + + /* Read file activity list */ + SREALLOC(*file_actlst, struct file_activity, FILE_ACTIVITY_SIZE * file_hdr->sa_act_nr); + fal = *file_actlst; + + j = 0; + for (i = 0; i < file_hdr->sa_act_nr; i++, fal++) { + + sa_fread(fd, fal, FILE_ACTIVITY_SIZE, HARD_SIZE); + + if ((fal->nr < 1) || (fal->nr2 < 1)) { + /* + * Every activity, known or unknown, + * should have at least one item and sub-item. + */ + fprintf(stderr, _("\nInvalid data found. Aborting...\n")); + return -1; + } + + if ((p = get_activity_position(act, fal->id)) >= 0) { + /* This is a known activity, maybe with an unknown format */ + + if (IS_VOLATILE(act[p]->options) && previous_format) { + /* + * Current activity is known by current version + * as a volatile one: So increment the number of + * volatile activities in file's header (but only + * for old format data files, since up-to-date + * format data files already have the right value here). + */ + file_hdr->sa_vol_act_nr += 1; + + /* + * Create the sequence of volatile activities. + * Used only for old format datafiles. + * For new format datafiles, this is not necessary + * since this sequence already exists following + * the RESTART record. + */ + vol_id_seq[j++] = act[p]->id; + } + + if (fal->id == A_CPU) { + /* + * Old format data files don't know volatile + * activities. The number of CPU is a constant + * all along the file. + */ + if (previous_format) { + file_hdr->sa_last_cpu_nr = fal->nr; + } + a_cpu = TRUE; + } + + /* Size of activity in file is larger than up-to-date activity size */ + if (fal->size > act[p]->msize) { + act[p]->msize = fal->size; + } + + /* + * When upgrading a file: + * fal->size : Size of an item for current activity, as + * read from the file. + * act[p]->msize: Size of the buffer in memory where an item + * for current activity, as read from the file, + * will be saved. We have: + * act[p]->msize >= {fal->size ; act[p]->fsize} + * act[p]->fsize: Size of an item for current activity with + * up-to-date format. + */ + act[p]->nr = fal->nr; + act[p]->nr2 = fal->nr2; + /* + * Don't set act[p]->fsize! Should retain the size of an item + * for up-to-date format! + */ + } + } + + if (!a_cpu) { + /* + * CPU activity should always be in file + * and have a known format (expected magical number). + */ + fprintf(stderr, _("\nCPU activity not found in file. Aborting...\n")); + return -1; + } + + /* Write file_header structure */ + if ((n = write(stdfd, file_hdr, FILE_HEADER_SIZE)) != FILE_HEADER_SIZE) { + fprintf(stderr, "\nwrite: %s\n", strerror(errno)); + return -1; + } + + fprintf(stderr, "OK\n"); + + return 0; +} + +/* + *************************************************************************** + * Upgrade file's activity list section. + * + * IN: + * @stdfd File descriptor for STDOUT. + * @act Array of activities. + * @file_hdr Pointer on file_header structure. + * @file_actlst Activity list in file. + * + * RETURNS: + * -1 on error, 0 otherwise. +*************************************************************************** + */ +int upgrade_activity_section(int stdfd, struct activity *act[], + struct file_header *file_hdr, + struct file_activity *file_actlst) +{ + int i, n, p; + struct file_activity file_act; + struct file_activity *fal; + + fprintf(stderr, "file_activity: "); + + fal = file_actlst; + + for (i = 0; i < file_hdr->sa_act_nr; i++, fal++) { + + file_act = *fal; + if ((p = get_activity_position(act, fal->id)) >= 0) { + /* Update activity magic number */ + file_act.magic = act[p]->magic; + /* Also update its size, which may have changed with recent versions */ + file_act.size = act[p]->fsize; + } + + /* + * Even unknown activities must be written + * (they are counted in sa_act_nr). + */ + if ((n = write(stdfd, &file_act, FILE_ACTIVITY_SIZE))!= FILE_ACTIVITY_SIZE) { + fprintf(stderr, "\nwrite: %s\n", strerror(errno)); + return -1; + } + + fprintf(stderr, "%s ", act[p]->name); + } + + fprintf(stderr, "OK\n"); + + return 0; +} + +/* + *************************************************************************** + * Upgrade a COMMENT record. + * + * IN: + * @fd File descriptor for sa datafile to convert. + * @stdfd File descriptor for STDOUT. + * + * RETURNS: + * -1 on error, 0 otherwise. +*************************************************************************** + */ +int upgrade_comment_record(int fd, int stdfd) +{ + int n; + char file_comment[MAX_COMMENT_LEN]; + + /* Read the COMMENT record */ + sa_fread(fd, file_comment, MAX_COMMENT_LEN, HARD_SIZE); + file_comment[MAX_COMMENT_LEN - 1] = '\0'; + + /* Then write it. No changes at this time */ + if ((n = write(stdfd, file_comment, MAX_COMMENT_LEN)) != MAX_COMMENT_LEN) { + fprintf(stderr, "\nwrite: %s\n", strerror(errno)); + return -1; + } + + fprintf(stderr, "C"); + + return 0; +} + +/* + *************************************************************************** + * Upgrade a RESTART record. + * + * IN: + * @fd File descriptor for sa datafile to convert. + * @stdfd File descriptor for STDOUT. + * @act Array of activities. + * @file_hdr Pointer on file_header structure. + * @previous_format TRUE is sa datafile has an old format which is no + * longer compatible with current one. + * @vol_id_seq Sequence of volatile activities. + * + * RETURNS: + * -1 on error, 0 otherwise. +*************************************************************************** + */ +int upgrade_restart_record(int fd, int stdfd, struct activity *act[], + struct file_header *file_hdr, int previous_format, + unsigned int vol_id_seq[]) +{ + int i, n, p; + struct file_activity file_act; + + /* + * This is a RESTART record. + * Only new format data file have additional structures + * to read here for volatile activities. + */ + for (i = 0; i < file_hdr->sa_vol_act_nr; i++) { + + if (!previous_format) { + sa_fread(fd, &file_act, FILE_ACTIVITY_SIZE, HARD_SIZE); + if (file_act.id) { + reallocate_vol_act_structures(act, file_act.nr, file_act.id); + } + } + else { + memset(&file_act, 0, FILE_ACTIVITY_SIZE); + + /* Old format: Sequence of volatile activities is in vol_id_seq */ + p = get_activity_position(act, vol_id_seq[i]); + + /* Set only the necessary fields */ + file_act.id = act[p]->id; + file_act.nr = act[p]->nr; + } + + if ((n = write(stdfd, &file_act, FILE_ACTIVITY_SIZE)) != FILE_ACTIVITY_SIZE) { + fprintf(stderr, "\nwrite: %s\n", strerror(errno)); + return -1; + } + } + + fprintf(stderr, "R"); + + return 0; +} + +/* + *************************************************************************** + * Upgrade a record which is not a COMMENT or a RESTART one. + * + * IN: + * @fd File descriptor for sa datafile to convert. + * @stdfd File descriptor for STDOUT. + * @act Array of activities. + * @file_hdr Pointer on file_header structure. + * @file_actlst Activity list in file. + * + * RETURNS: + * -1 on error, 0 otherwise. +*************************************************************************** + */ +int upgrade_common_record(int fd, int stdfd, struct activity *act[], + struct file_header *file_hdr, + struct file_activity *file_actlst) +{ + int i, j, k, n, p; + struct file_activity *fal; + void *buffer = NULL; + + /* + * This is not a special record, so read the extra fields, + * even if the format of the activity is unknown. + */ + fal = file_actlst; + for (i = 0; i < file_hdr->sa_act_nr; i++, fal++) { + + if ((p = get_activity_position(act, fal->id)) < 0) { + /* An unknown activity should still be read and written */ + SREALLOC(buffer, void, fal->size * fal->nr * fal->nr2); + sa_fread(fd, buffer, fal->size * fal->nr * fal->nr2, HARD_SIZE); + if ((n = write(stdfd, (char *) buffer, + fal->size * fal->nr * fal->nr2)) != + fal->size * fal->nr * fal->nr2) { + fprintf(stderr, "\nwrite: %s\n", strerror(errno)); + return -1; + } + continue; + } + + if ((act[p]->nr > 0) && + ((act[p]->nr > 1) || (act[p]->nr2 > 1)) && + (act[p]->msize > fal->size)) { + + for (j = 0; j < act[p]->nr; j++) { + for (k = 0; k < act[p]->nr2; k++) { + sa_fread(fd, + (char *) act[p]->buf[0] + (j * act[p]->nr2 + k) * act[p]->msize, + fal->size, HARD_SIZE); + } + } + } + + else if (act[p]->nr > 0) { + sa_fread(fd, act[p]->buf[0], fal->size * act[p]->nr * act[p]->nr2, HARD_SIZE); + } + + if (act[p]->magic != fal->magic) { + + /* Known activity but old format */ + switch (fal->id) { + + case A_IO: + upgrade_stats_io(act, p); + break; + + case A_QUEUE: + upgrade_stats_queue(act, p); + break; + + case A_DISK: + upgrade_stats_disk(act, p); + break; + + case A_NET_DEV: + upgrade_stats_net_dev(act, p, fal->magic); + break; + + case A_NET_EDEV: + upgrade_stats_net_edev(act, p); + break; + + case A_NET_IP: + upgrade_stats_net_ip(act, p); + break; + + case A_NET_EIP: + upgrade_stats_net_eip(act, p); + break; + + case A_NET_IP6: + upgrade_stats_net_ip6(act, p); + break; + + case A_NET_EIP6: + upgrade_stats_net_eip6(act, p); + break; + } + } + else { + /* Known activity with current up-to-date format */ + for (j = 0; j < act[p]->nr; j++) { + for (k = 0; k < act[p]->nr2; k++) { + memcpy((char *) act[p]->buf[1] + (j * act[p]->nr2 + k) * act[p]->msize, + (char *) act[p]->buf[0] + (j * act[p]->nr2 + k) * act[p]->msize, + fal->size); + } + } + } + + for (j = 0; j < act[p]->nr; j++) { + for (k = 0; k < act[p]->nr2; k++) { + if ((n = write(stdfd, + (char *) act[p]->buf[1] + (j * act[p]->nr2 + k) * act[p]->msize, + act[p]->fsize)) != + act[p]->fsize) { + fprintf(stderr, "\nwrite: %s\n", strerror(errno)); + return -1; + } + } + } + } + + fprintf(stderr, "."); + + if (buffer) { + free(buffer); + } + + return 0; +} + +/* + *************************************************************************** + * Upgrade statistics records. + * + * IN: + * @fd File descriptor for sa datafile to convert. + * @stdfd File descriptor for STDOUT. + * @act Array of activities. + * @file_hdr Pointer on file_header structure. + * @previous_format TRUE is sa datafile has an old format which is no + * longer compatible with current one. + * @file_actlst Activity list in file. + * @vol_id_seq Sequence of volatile activities. + * + * RETURNS: + * -1 on error, 0 otherwise. +*************************************************************************** + */ +int upgrade_stat_records(int fd, int stdfd, struct activity *act[], + struct file_header *file_hdr, int previous_format, + struct file_activity *file_actlst, unsigned int vol_id_seq[]) +{ + int n, rtype; + int eosaf = TRUE; + struct record_header record_hdr; + + fprintf(stderr, _("Statistics: ")); + + do { + eosaf = sa_fread(fd, &record_hdr, RECORD_HEADER_SIZE, SOFT_SIZE); + rtype = record_hdr.record_type; + + if (!eosaf) { + + if ((n = write(stdfd, &record_hdr, RECORD_HEADER_SIZE)) + != RECORD_HEADER_SIZE) { + fprintf(stderr, "\nwrite: %s\n", strerror(errno)); + return -1; + } + + if (rtype == R_COMMENT) { + /* Upgrade the COMMENT record */ + if (upgrade_comment_record(fd, stdfd) < 0) + return -1; + } + + else if (rtype == R_RESTART) { + /* Upgrade the RESTART record */ + if (upgrade_restart_record(fd, stdfd, act, file_hdr, + previous_format, vol_id_seq) < 0) + return -1; + } + + else { + /* Upgrade current statistics record */ + if (upgrade_common_record(fd, stdfd, act, file_hdr, + file_actlst) < 0) + return -1; + } + } + } + while (!eosaf); + + return 0; +} + +/* + *************************************************************************** + * Close file descriptors and exit. + * + * IN: + * @fd File descriptor for sa datafile to convert. + * @stdfd File descriptor for STDOUT. + * @exit_code Exit code. + *************************************************************************** + */ +void upgrade_exit(int fd, int stdfd, int exit_code) +{ + if (fd) { + close(fd); + } + if (stdfd) { + close(stdfd); + } + + exit(exit_code); +} + +/* + *************************************************************************** + * Convert a sysstat activity data file from a previous version to the + * up-to-date format. Presently data files from sysstat version 9.1.6 and + * later are converted to current sysstat version format. + * + * IN: + * @dfile System activity data file name. + * @act Array of activities. + *************************************************************************** + */ +void convert_file(char dfile[], struct activity *act[]) +{ + int fd = 0, stdfd = 0; + int previous_format = FALSE; + struct file_magic file_magic; + struct file_header file_hdr; + struct file_activity *file_actlst = NULL; + unsigned int vol_id_seq[NR_ACT]; + + /* Open stdout */ + if ((stdfd = dup(STDOUT_FILENO)) < 0) { + perror("dup"); + upgrade_exit(0, 0, 2); + } + + /* Upgrade file's magic section */ + if (upgrade_magic_section(dfile, &fd, stdfd, &file_magic, + &previous_format) < 0) { + upgrade_exit(fd, stdfd, 2); + } + + /* Upgrade file's header section */ + if (upgrade_header_section(dfile, fd, stdfd, act, + &file_magic, &file_hdr, + previous_format, &file_actlst, + vol_id_seq) < 0) { + upgrade_exit(fd, stdfd, 2); + } + + /* Upgrade file's activity list section */ + if (upgrade_activity_section(stdfd, act, &file_hdr, + file_actlst) < 0) { + upgrade_exit(fd, stdfd, 2); + } + + /* Perform required allocations */ + allocate_structures(act); + + /* Upgrade statistics records */ + if (upgrade_stat_records(fd, stdfd, act, &file_hdr, + previous_format, file_actlst, + vol_id_seq) <0) { + upgrade_exit(fd, stdfd, 2); + } + + fprintf(stderr, + _("\nFile successfully converted to sysstat format version %s\n"), + VERSION); + + free(file_actlst); + free_structures(act); + close(fd); + close(stdfd); +} diff --git a/sa_conv.h b/sa_conv.h new file mode 100644 index 0000000..85416f9 --- /dev/null +++ b/sa_conv.h @@ -0,0 +1,148 @@ +/* + * sa_conv.h: Include file for "sadf -c" command. + * (C) 1999-2014 by Sebastien Godard (sysstat orange.fr) + */ + +#ifndef _SA_CONV_H +#define _SA_CONV_H + +/* + * Header structure for previous system activity data file format + * (v9.1.6 up to v10.2.1). + */ +struct file_header_2171 { + unsigned long sa_ust_time __attribute__ ((aligned (8))); + unsigned int sa_act_nr __attribute__ ((aligned (8))); + unsigned char sa_day; + unsigned char sa_month; + unsigned char sa_year; + char sa_sizeof_long; + char sa_sysname[UTSNAME_LEN]; + char sa_nodename[UTSNAME_LEN]; + char sa_release[UTSNAME_LEN]; + char sa_machine[UTSNAME_LEN]; +}; + +/* Structure stats_io for ACTIVITY_MAGIC_BASE format */ +struct stats_io_8a { + unsigned int dk_drive __attribute__ ((aligned (4))); + unsigned int dk_drive_rio __attribute__ ((packed)); + unsigned int dk_drive_wio __attribute__ ((packed)); + unsigned int dk_drive_rblk __attribute__ ((packed)); + unsigned int dk_drive_wblk __attribute__ ((packed)); +}; + +/* Structure stats_queue for ACTIVITY_MAGIC_BASE format */ +struct stats_queue_8a { + unsigned long nr_running __attribute__ ((aligned (8))); + unsigned int load_avg_1 __attribute__ ((aligned (8))); + unsigned int load_avg_5 __attribute__ ((packed)); + unsigned int load_avg_15 __attribute__ ((packed)); + unsigned int nr_threads __attribute__ ((packed)); +}; + +/* Structure stats_disk for ACTIVITY_MAGIC_BASE format */ +struct stats_disk_8a { + unsigned long long rd_sect __attribute__ ((aligned (16))); + unsigned long long wr_sect __attribute__ ((aligned (16))); + unsigned long rd_ticks __attribute__ ((aligned (16))); + unsigned long wr_ticks __attribute__ ((aligned (8))); + unsigned long tot_ticks __attribute__ ((aligned (8))); + unsigned long rq_ticks __attribute__ ((aligned (8))); + unsigned long nr_ios __attribute__ ((aligned (8))); + unsigned int major __attribute__ ((aligned (8))); + unsigned int minor __attribute__ ((packed)); +}; + +/* Structure stats_net_dev for ACTIVITY_MAGIC_BASE format */ +struct stats_net_dev_8a { + unsigned long rx_packets __attribute__ ((aligned (8))); + unsigned long tx_packets __attribute__ ((aligned (8))); + unsigned long rx_bytes __attribute__ ((aligned (8))); + unsigned long tx_bytes __attribute__ ((aligned (8))); + unsigned long rx_compressed __attribute__ ((aligned (8))); + unsigned long tx_compressed __attribute__ ((aligned (8))); + unsigned long multicast __attribute__ ((aligned (8))); + char interface[MAX_IFACE_LEN] __attribute__ ((aligned (8))); +}; + +/* Structure stats_net_dev for ACTIVITY_MAGIC_BASE + 1 format */ +struct stats_net_dev_8b { + unsigned long long rx_packets __attribute__ ((aligned (16))); + unsigned long long tx_packets __attribute__ ((aligned (16))); + unsigned long long rx_bytes __attribute__ ((aligned (16))); + unsigned long long tx_bytes __attribute__ ((aligned (16))); + unsigned long long rx_compressed __attribute__ ((aligned (16))); + unsigned long long tx_compressed __attribute__ ((aligned (16))); + unsigned long long multicast __attribute__ ((aligned (16))); + char interface[MAX_IFACE_LEN] __attribute__ ((aligned (16))); +}; + +/* Structure stats_net_edev for ACTIVITY_MAGIC_BASE format */ +struct stats_net_edev_8a { + unsigned long collisions __attribute__ ((aligned (8))); + unsigned long rx_errors __attribute__ ((aligned (8))); + unsigned long tx_errors __attribute__ ((aligned (8))); + unsigned long rx_dropped __attribute__ ((aligned (8))); + unsigned long tx_dropped __attribute__ ((aligned (8))); + unsigned long rx_fifo_errors __attribute__ ((aligned (8))); + unsigned long tx_fifo_errors __attribute__ ((aligned (8))); + unsigned long rx_frame_errors __attribute__ ((aligned (8))); + unsigned long tx_carrier_errors __attribute__ ((aligned (8))); + char interface[MAX_IFACE_LEN] __attribute__ ((aligned (8))); +}; + +/* Structure stats_net_ip for ACTIVITY_MAGIC_BASE format */ +struct stats_net_ip_8a { + unsigned long InReceives __attribute__ ((aligned (8))); + unsigned long ForwDatagrams __attribute__ ((aligned (8))); + unsigned long InDelivers __attribute__ ((aligned (8))); + unsigned long OutRequests __attribute__ ((aligned (8))); + unsigned long ReasmReqds __attribute__ ((aligned (8))); + unsigned long ReasmOKs __attribute__ ((aligned (8))); + unsigned long FragOKs __attribute__ ((aligned (8))); + unsigned long FragCreates __attribute__ ((aligned (8))); +}; + +/* Structure stats_net_eip for ACTIVITY_MAGIC_BASE format */ +struct stats_net_eip_8a { + unsigned long InHdrErrors __attribute__ ((aligned (8))); + unsigned long InAddrErrors __attribute__ ((aligned (8))); + unsigned long InUnknownProtos __attribute__ ((aligned (8))); + unsigned long InDiscards __attribute__ ((aligned (8))); + unsigned long OutDiscards __attribute__ ((aligned (8))); + unsigned long OutNoRoutes __attribute__ ((aligned (8))); + unsigned long ReasmFails __attribute__ ((aligned (8))); + unsigned long FragFails __attribute__ ((aligned (8))); +}; + +/* Structure stats_net_ip6 for ACTIVITY_MAGIC_BASE format */ +struct stats_net_ip6_8a { + unsigned long InReceives6 __attribute__ ((aligned (8))); + unsigned long OutForwDatagrams6 __attribute__ ((aligned (8))); + unsigned long InDelivers6 __attribute__ ((aligned (8))); + unsigned long OutRequests6 __attribute__ ((aligned (8))); + unsigned long ReasmReqds6 __attribute__ ((aligned (8))); + unsigned long ReasmOKs6 __attribute__ ((aligned (8))); + unsigned long InMcastPkts6 __attribute__ ((aligned (8))); + unsigned long OutMcastPkts6 __attribute__ ((aligned (8))); + unsigned long FragOKs6 __attribute__ ((aligned (8))); + unsigned long FragCreates6 __attribute__ ((aligned (8))); +}; + +/* Structure stats_net_eip6 for ACTIVITY_MAGIC_BASE format */ +struct stats_net_eip6_8a { + unsigned long InHdrErrors6 __attribute__ ((aligned (8))); + unsigned long InAddrErrors6 __attribute__ ((aligned (8))); + unsigned long InUnknownProtos6 __attribute__ ((aligned (8))); + unsigned long InTooBigErrors6 __attribute__ ((aligned (8))); + unsigned long InDiscards6 __attribute__ ((aligned (8))); + unsigned long OutDiscards6 __attribute__ ((aligned (8))); + unsigned long InNoRoutes6 __attribute__ ((aligned (8))); + unsigned long OutNoRoutes6 __attribute__ ((aligned (8))); + unsigned long ReasmFails6 __attribute__ ((aligned (8))); + unsigned long FragFails6 __attribute__ ((aligned (8))); + unsigned long InTruncatedPkts6 __attribute__ ((aligned (8))); +}; + +#endif /* _SA_CONV_H */ diff --git a/sadc.c b/sadc.c index 3cd3b6a..567233a 100644 --- a/sadc.c +++ b/sadc.c @@ -434,38 +434,14 @@ int ask_for_flock(int fd, int fatal) */ void fill_magic_header(struct file_magic *file_magic) { - char *v; - char version[16]; - 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; - - strcpy(version, VERSION); - /* Get version number */ - if ((v = strtok(version, ".")) == NULL) - return; - file_magic->sysstat_version = atoi(v) & 0xff; - - /* Get patchlevel number */ - if ((v = strtok(NULL, ".")) == NULL) - return; - file_magic->sysstat_patchlevel = atoi(v) & 0xff; - - /* Get sublevel number */ - if ((v = strtok(NULL, ".")) == NULL) - return; - file_magic->sysstat_sublevel = atoi(v) & 0xff; - - /* Get extraversion number. Don't necessarily exist */ - if ((v = strtok(NULL, ".")) == NULL) - return; - file_magic->sysstat_extraversion = atoi(v) & 0xff; + enum_version_nr(file_magic); } /* diff --git a/sadf.c b/sadf.c index cdbddfe..690f73e 100644 --- a/sadf.c +++ b/sadf.c @@ -87,7 +87,7 @@ void usage(char *progname) progname); fprintf(stderr, _("Options are:\n" - "[ -C ] [ -d | -j | -p | -x ] [ -H ] [ -h ] [ -T | -t | -U ] [ -V ]\n" + "[ -C ] [ -c | -d | -j | -p | -x ] [ -H ] [ -h ] [ -T | -t | -U ] [ -V ]\n" "[ -P { [,...] | ALL } ] [ -s [ ] ] [ -e [ ] ]\n" "[ -- ]\n")); exit(1); @@ -1593,6 +1593,13 @@ int main(int argc, char **argv) flags |= S_F_COMMENT; break; + case 'c': + if (format) { + usage(argv[0]); + } + format = F_CONV_OUTPUT; + break; + case 'd': if (format) { usage(argv[0]); @@ -1744,8 +1751,14 @@ int main(int argc, char **argv) interval = 1; } - /* Read stats from file */ - read_stats_from_file(dfile); + if (format == F_CONV_OUTPUT) { + /* Convert file to current format */ + convert_file(dfile, act); + } + else { + /* Read stats from file */ + read_stats_from_file(dfile); + } /* Free bitmaps */ free_bitmaps(act); diff --git a/sadf.h b/sadf.h index df7537a..10114ab 100644 --- a/sadf.h +++ b/sadf.h @@ -27,7 +27,7 @@ */ /* Number of output formats */ -#define NR_FMT 5 +#define NR_FMT 6 /* Output formats */ #define F_DB_OUTPUT 1 @@ -35,6 +35,7 @@ #define F_PPC_OUTPUT 3 #define F_XML_OUTPUT 4 #define F_JSON_OUTPUT 5 +#define F_CONV_OUTPUT 6 /* *************************************************************************** @@ -181,6 +182,8 @@ struct report_format { *************************************************************************** */ +extern void + convert_file(char [], struct activity *[]); extern void xprintf(int, const char *, ...); extern void -- 2.40.0