From 312a6a906d69e61c7704ae608e269865269c3c83 Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Sat, 12 Mar 2016 11:27:30 +0100 Subject: [PATCH] sar: Fix possible compatibility issues between sysstat versions Fix an issue that made sar unable to read statistics for network and disk devices from a datafile created by a more recent version of sysstat when the size of the structures used to save those statistics was greater than that of the current version. This may be the case when eg. new fields are appended to network or disk structures. Signed-off-by: Sebastien GODARD --- sa_common.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/sa_common.c b/sa_common.c index 3ac1960..db8d949 100644 --- a/sa_common.c +++ b/sa_common.c @@ -636,10 +636,10 @@ unsigned int check_net_dev_reg(struct activity *a, int curr, int ref, struct stats_net_dev *sndc, *sndp; unsigned int index = 0; - sndc = (struct stats_net_dev *) a->buf[curr] + pos; + sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + pos * a->msize); while (index < a->nr) { - sndp = (struct stats_net_dev *) a->buf[ref] + index; + sndp = (struct stats_net_dev *) ((char *) a->buf[ref] + index * a->msize); if (!strcmp(sndc->interface, sndp->interface)) { /* * Network interface found. @@ -709,7 +709,7 @@ unsigned int check_net_dev_reg(struct activity *a, int curr, int ref, /* Network interface not found: Look for the first free structure */ for (index = 0; index < a->nr; index++) { - sndp = (struct stats_net_dev *) a->buf[ref] + index; + sndp = (struct stats_net_dev *) ((char *) a->buf[ref] + index * a->msize); if (!strcmp(sndp->interface, "")) break; } @@ -718,7 +718,7 @@ unsigned int check_net_dev_reg(struct activity *a, int curr, int ref, index = pos; } - sndp = (struct stats_net_dev *) a->buf[ref] + index; + sndp = (struct stats_net_dev *) ((char *) a->buf[ref] + index * a->msize); /* Since the name is not the same, reset all the structure */ memset(sndp, 0, STATS_NET_DEV_SIZE); strcpy(sndp->interface, sndc->interface); @@ -748,10 +748,10 @@ unsigned int check_net_edev_reg(struct activity *a, int curr, int ref, struct stats_net_edev *snedc, *snedp; unsigned int index = 0; - snedc = (struct stats_net_edev *) a->buf[curr] + pos; + snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + pos * a->msize); while (index < a->nr) { - snedp = (struct stats_net_edev *) a->buf[ref] + index; + snedp = (struct stats_net_edev *) ((char *) a->buf[ref] + index * a->msize); if (!strcmp(snedc->interface, snedp->interface)) { /* * Network interface found. @@ -781,7 +781,7 @@ unsigned int check_net_edev_reg(struct activity *a, int curr, int ref, /* Network interface not found: Look for the first free structure */ for (index = 0; index < a->nr; index++) { - snedp = (struct stats_net_edev *) a->buf[ref] + index; + snedp = (struct stats_net_edev *) ((char *) a->buf[ref] + index * a->msize); if (!strcmp(snedp->interface, "")) break; } @@ -790,7 +790,7 @@ unsigned int check_net_edev_reg(struct activity *a, int curr, int ref, index = pos; } - snedp = (struct stats_net_edev *) a->buf[ref] + index; + snedp = (struct stats_net_edev *) ((char *) a->buf[ref] + index * a->msize); /* Since the name is not the same, reset all the structure */ memset(snedp, 0, STATS_NET_EDEV_SIZE); strcpy(snedp->interface, snedc->interface); @@ -818,10 +818,10 @@ int check_disk_reg(struct activity *a, int curr, int ref, int pos) struct stats_disk *sdc, *sdp; int index = 0; - sdc = (struct stats_disk *) a->buf[curr] + pos; + sdc = (struct stats_disk *) ((char *) a->buf[curr] + pos * a->msize); while (index < a->nr) { - sdp = (struct stats_disk *) a->buf[ref] + index; + sdp = (struct stats_disk *) ((char *) a->buf[ref] + index * a->msize); if ((sdc->major == sdp->major) && (sdc->minor == sdp->minor)) { /* @@ -846,20 +846,16 @@ int check_disk_reg(struct activity *a, int curr, int ref, int pos) /* Disk not found: Look for the first free structure */ for (index = 0; index < a->nr; index++) { - sdp = (struct stats_disk *) a->buf[ref] + index; - if (!(sdp->major + sdp->minor)) { - memset(sdp, 0, STATS_DISK_SIZE); - sdp->major = sdc->major; - sdp->minor = sdc->minor; + sdp = (struct stats_disk *) ((char *) a->buf[ref] + index * a->msize); + if (!(sdp->major + sdp->minor)) break; - } } if (index >= a->nr) { /* No free structure found: Default is structure of same rank */ index = pos; } - sdp = (struct stats_disk *) a->buf[ref] + index; + sdp = (struct stats_disk *) ((char *) a->buf[ref] + index * a->msize); /* Since the device is not the same, reset all the structure */ memset(sdp, 0, STATS_DISK_SIZE); sdp->major = sdc->major; -- 2.49.0