From: Sebastien GODARD Date: Sun, 4 Mar 2018 09:02:52 +0000 (+0100) Subject: sar: Test for zero value when reallocating all the buffers X-Git-Tag: v11.7.3~24 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=309f4436c5488412491e387d9d2a5261631185db;p=sysstat sar: Test for zero value when reallocating all the buffers When sar reads the contents of a file and meets a LINUX RESTART, it may have to reallocate the buffers used to save CPU statistics to match the new number of CPU. If the number of CPU has increased it doubles the size of its buffers. There is a problem though if CPU activity was not included in file (or if its format was unknown to current sysstat version). In this case the buffer size was zero. So test this before reallocating buffers. Below is a sample output before the patch was applied. The file contains only A_PCSW activity then a LINUX RESTART message (which cannot be displayed): $ sar -f data0 -w Linux 4.4.14-200.fc22.x86_64 (test.home) 03/04/18 _x86_64_ (8 CPU) 09:31:50 proc/s cswch/s 09:31:51 0.00 402.00 09:31:52 0.00 356.00 Average: 0.00 379.00 srealloc <------------------------- Error! Signed-off-by: Sebastien GODARD --- diff --git a/sa_common.c b/sa_common.c index b274d32..a5579a8 100644 --- a/sa_common.c +++ b/sa_common.c @@ -437,7 +437,6 @@ void free_structures(struct activity *act[]) *************************************************************************** * Reallocate all the buffers for given activity. The new size is the double * of the original one. - * NB: nr_allocated is > 0. * * IN: * @a Activity whose buffers need to be reallocated. @@ -446,16 +445,26 @@ void free_structures(struct activity *act[]) void reallocate_all_buffers(struct activity *a) { int j; + size_t nr_realloc; + + if (!a->nr_allocated) { + nr_realloc = (a->nr_ini ? a->nr_ini : 1); + } + else { + nr_realloc = a->nr_allocated * 2; + } for (j = 0; j < 3; j++) { SREALLOC(a->buf[j], void, - (size_t) a->msize * (size_t) a->nr_allocated * 2 * (size_t) a->nr2); + (size_t) a->msize * nr_realloc * (size_t) a->nr2); /* Init additional space which has been allocated */ - memset(a->buf[j] + a->msize * a->nr_allocated * a->nr2, 0, - (size_t) a->msize * (size_t) a->nr_allocated * (size_t) a->nr2); + if (a->nr_allocated) { + memset(a->buf[j] + a->msize * a->nr_allocated * a->nr2, 0, + (size_t) a->msize * (size_t) a->nr_allocated * (size_t) a->nr2); + } } - a->nr_allocated *= 2; + a->nr_allocated = nr_realloc; } /* @@ -2634,6 +2643,8 @@ int print_special_record(struct record_header *record_hdr, unsigned int l_flags, * But if it is the case, @nr_ini will be used in the loop * to display all processors. So update its value here and * reallocate buffers if needed. + * NB: We may have nr_allocated=0 here if A_CPU activity has + * not been collected in file (or if it has an unknown format). */ p = get_activity_position(act, A_CPU, EXIT_IF_NOT_FOUND); act[p]->nr_ini = file_hdr->sa_cpu_nr;