From f4878ad79941bec3674946a9bb4ac921b8cec46e Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Wed, 5 Feb 2014 15:56:26 +0100 Subject: [PATCH] sar: Take into account a change of CPU number in sar datafile (4) Update sadf so that it can read the new datafiles format. sadf now displays the CPU count in the restart messages. Signed-off-by: Sebastien GODARD --- sa.h | 2 + sa_common.c | 30 ++++++-- sadf.c | 202 +++++++++++++++++++++++++++++++++------------------- sadf.h | 11 +-- sadf_misc.c | 34 +++++---- 5 files changed, 183 insertions(+), 96 deletions(-) diff --git a/sa.h b/sa.h index df59374..1ef7413 100644 --- a/sa.h +++ b/sa.h @@ -795,6 +795,8 @@ extern __read_funct_t /* Other functions */ extern void allocate_bitmaps(struct activity * []); +extern void + allocate_cpu_structures(struct activity * [], unsigned int); extern void allocate_structures(struct activity * []); extern int diff --git a/sa_common.c b/sa_common.c index f0338e8..829736d 100644 --- a/sa_common.c +++ b/sa_common.c @@ -1234,6 +1234,28 @@ void check_file_actlst(int *ifd, char *dfile, struct activity *act[], } } +/* + *************************************************************************** + * Set number of CPU items and reallocate CPU structures accordingly. + * + * IN: + * @act Array of activities. + * @cpu_nr Number of CPU items. + *************************************************************************** + */ +void allocate_cpu_structures(struct activity *act[], unsigned int cpu_nr) +{ + int j, p; + + /* Set new CPU count and reallocate structures */ + p = get_activity_position(act, A_CPU); + act[p]->nr = cpu_nr; + + for (j = 0; j < 3; j++) { + SREALLOC(act[p]->buf[j], void, act[p]->msize * act[p]->nr * act[p]->nr2); + } +} + /* *************************************************************************** * Read the new CPU count following a RESTART record. Then set corresponding @@ -1250,7 +1272,6 @@ void check_file_actlst(int *ifd, char *dfile, struct activity *act[], unsigned int read_new_cpu_nr(int ifd, struct activity *act[]) { unsigned int new_cpu_nr; - int j, p; /* Read new number of CPU following the RESTART record */ sa_fread(ifd, &new_cpu_nr, sizeof(unsigned int), HARD_SIZE); @@ -1263,12 +1284,7 @@ unsigned int read_new_cpu_nr(int ifd, struct activity *act[]) } /* Set new CPU count and reallocate structures */ - p = get_activity_position(act, A_CPU); - act[p]->nr = new_cpu_nr; - - for (j = 0; j < 3; j++) { - SREALLOC(act[p]->buf[j], void, act[p]->msize * act[p]->nr * act[p]->nr2); - } + allocate_cpu_structures(act, new_cpu_nr); return new_cpu_nr; } diff --git a/sadf.c b/sadf.c index 671083a..94fe097 100644 --- a/sadf.c +++ b/sadf.c @@ -341,6 +341,7 @@ void xprintf(int nr_tab, const char *fmtf, ...) * been used or not) can be saved for current record. * @loctime Structure where timestamp (expressed in local time) * can be saved for current record. + * @new_cpu_nr CPU count associated with restart mark. * * OUT: * @rectime Structure where timestamp for current record has @@ -350,7 +351,8 @@ void xprintf(int nr_tab, const char *fmtf, ...) *************************************************************************** */ void write_textual_restarts(int curr, int use_tm_start, int use_tm_end, int tab, - struct tm *rectime, struct tm *loctime) + struct tm *rectime, struct tm *loctime, + unsigned int new_cpu_nr) { char cur_date[32], cur_time[32]; @@ -367,7 +369,8 @@ void write_textual_restarts(int curr, int use_tm_start, int use_tm_end, int tab, if (*fmt[f_position]->f_restart) { (*fmt[f_position]->f_restart)(&tab, F_MAIN, cur_date, cur_time, !PRINT_LOCAL_TIME(flags) && - !PRINT_TRUE_TIME(flags), &file_hdr); + !PRINT_TRUE_TIME(flags), &file_hdr, + new_cpu_nr); } } @@ -784,6 +787,7 @@ void sadf_print_special(int curr, int use_tm_start, int use_tm_end, int rtype, i { char cur_date[32], cur_time[32]; int dp = 1; + unsigned int new_cpu_nr; /* Fill timestamp structure (rectime) for current record */ sadf_get_record_timestamp_struct(curr, rectime, loctime); @@ -798,13 +802,17 @@ void sadf_print_special(int curr, int use_tm_start, int use_tm_end, int rtype, i } if (rtype == R_RESTART) { + /* Don't forget to read new number of CPU */ + new_cpu_nr = read_new_cpu_nr(ifd, act); + if (!dp) return; if (*fmt[f_position]->f_restart) { (*fmt[f_position]->f_restart)(NULL, F_MAIN, cur_date, cur_time, !PRINT_LOCAL_TIME(flags) && - !PRINT_TRUE_TIME(flags), &file_hdr); + !PRINT_TRUE_TIME(flags), &file_hdr, + new_cpu_nr); } } else if (rtype == R_COMMENT) { @@ -941,6 +949,7 @@ void textual_display_loop(int ifd, struct file_activity *file_actlst, char *dfil { int curr, tab = 0, rtype; int eosaf = TRUE, next, reset = FALSE; + unsigned int save_cpu_nr, new_cpu_nr; long cnt = 1; off_t fpos; @@ -949,6 +958,8 @@ void textual_display_loop(int ifd, struct file_activity *file_actlst, char *dfil perror("lseek"); exit(2); } + /* Save number of CPU items for current file position */ + save_cpu_nr = act[get_activity_position(act, A_CPU)]->nr; /* Print header (eg. XML file header) */ if (*fmt[f_position]->f_header) { @@ -970,24 +981,29 @@ void textual_display_loop(int ifd, struct file_activity *file_actlst, char *dfil eosaf = sa_fread(ifd, &record_hdr[0], RECORD_HEADER_SIZE, SOFT_SIZE); rtype = record_hdr[0].record_type; - if (!eosaf && (rtype != R_RESTART) && (rtype != R_COMMENT)) { - /* - * OK: Previous record was not a special one. - * So read now the extra fields. - */ - read_file_stat_bunch(act, 0, ifd, file_hdr.sa_nr_act, - file_actlst); - sadf_get_record_timestamp_struct(0, rectime, loctime); - } - - if (!eosaf && (rtype == R_COMMENT)) { - /* - * Ignore COMMENT record. - * (Unlike RESTART records, COMMENT records have an additional - * comment field). - */ - if (lseek(ifd, MAX_COMMENT_LEN, SEEK_CUR) < MAX_COMMENT_LEN) { - perror("lseek"); + if (!eosaf) { + if (rtype == R_COMMENT) { + /* Ignore COMMENT record */ + if (lseek(ifd, MAX_COMMENT_LEN, SEEK_CUR) < MAX_COMMENT_LEN) { + perror("lseek"); + } + } + else if (rtype == R_RESTART) { + /* + * Ignore RESTART record (don't display it) + * but anyway we have to reallocate CPU structures + * according to new CPU count (value saved after RESTART record). + */ + read_new_cpu_nr(ifd, act); + } + else { + /* + * OK: Previous record was not a special one. + * So read now the extra fields. + */ + read_file_stat_bunch(act, 0, ifd, file_hdr.sa_nr_act, + file_actlst); + sadf_get_record_timestamp_struct(0, rectime, loctime); } } } @@ -1008,32 +1024,41 @@ void textual_display_loop(int ifd, struct file_activity *file_actlst, char *dfil SOFT_SIZE); rtype = record_hdr[curr].record_type; - if (!eosaf && (rtype != R_RESTART) && (rtype != R_COMMENT)) { - /* Read the extra fields since it's not a special record */ - read_file_stat_bunch(act, curr, ifd, file_hdr.sa_nr_act, - file_actlst); - - if (*fmt[f_position]->f_statistics) { - (*fmt[f_position]->f_statistics)(&tab, F_MAIN); + if (!eosaf) { + if (rtype == R_COMMENT) { + /* Ignore COMMENT record */ + if (lseek(ifd, MAX_COMMENT_LEN, SEEK_CUR) < MAX_COMMENT_LEN) { + perror("lseek"); + } } + else if (rtype == R_RESTART) { + /* + * Ignore RESTART record (don't display it) + * but anyway we have to reallocate CPU structures + * according to new CPU count (value saved after RESTART record. + */ + read_new_cpu_nr(ifd, act); + } + else { + /* This is not a special record, so read the extra fields */ + read_file_stat_bunch(act, curr, ifd, file_hdr.sa_nr_act, + file_actlst); - /* next is set to 1 when we were close enough to desired interval */ - next = write_textual_stats(curr, tm_start.use, tm_end.use, reset, - &cnt, tab, cpu_nr, rectime, loctime); - - if (next) { - curr ^= 1; - if (cnt > 0) { - cnt--; + if (*fmt[f_position]->f_statistics) { + (*fmt[f_position]->f_statistics)(&tab, F_MAIN); } - } - reset = FALSE; - } - if (!eosaf && (rtype == R_COMMENT)) { - /* Ignore COMMENT record */ - if (lseek(ifd, MAX_COMMENT_LEN, SEEK_CUR) < MAX_COMMENT_LEN) { - perror("lseek"); + /* next is set to 1 when we were close enough to desired interval */ + next = write_textual_stats(curr, tm_start.use, tm_end.use, reset, + &cnt, tab, cpu_nr, rectime, loctime); + + if (next) { + curr ^= 1; + if (cnt > 0) { + cnt--; + } + } + reset = FALSE; } } } @@ -1045,14 +1070,25 @@ void textual_display_loop(int ifd, struct file_activity *file_actlst, char *dfil eosaf = sa_fread(ifd, &record_hdr[curr], RECORD_HEADER_SIZE, SOFT_SIZE); rtype = record_hdr[curr].record_type; - if (!eosaf && (rtype != R_RESTART) && (rtype != R_COMMENT)) { - read_file_stat_bunch(act, curr, ifd, file_hdr.sa_nr_act, - file_actlst); - } - else if (!eosaf && (rtype == R_COMMENT)) { - /* Ignore COMMENT record */ - if (lseek(ifd, MAX_COMMENT_LEN, SEEK_CUR) < MAX_COMMENT_LEN) { - perror("lseek"); + if (!eosaf) { + if (rtype == R_COMMENT) { + /* Ignore COMMENT record */ + if (lseek(ifd, MAX_COMMENT_LEN, SEEK_CUR) < MAX_COMMENT_LEN) { + perror("lseek"); + } + } + else if (rtype == R_RESTART) { + /* + * Ignore RESTART record (don't display it) + * but anyway we have to reallocate CPU structures + * according to new CPU count (value saved after RESTART record. + */ + read_new_cpu_nr(ifd, act); + } + else { + /* This is not a special record: Read the extra fields */ + read_file_stat_bunch(act, curr, ifd, file_hdr.sa_nr_act, + file_actlst); } } } @@ -1067,16 +1103,18 @@ void textual_display_loop(int ifd, struct file_activity *file_actlst, char *dfil (*fmt[f_position]->f_statistics)(&tab, F_END); } - /* Rewind file */ + /* Rewind file... */ if (lseek(ifd, fpos, SEEK_SET) < fpos) { perror("lseek"); exit(2); } + /* ... and restore number of CPU items for this position in file */ + allocate_cpu_structures(act, save_cpu_nr); /* Process now RESTART entries to display restart messages */ if (*fmt[f_position]->f_restart) { (*fmt[f_position]->f_restart)(&tab, F_BEGIN, NULL, NULL, FALSE, - &file_hdr); + &file_hdr, 0); } do { @@ -1084,13 +1122,13 @@ void textual_display_loop(int ifd, struct file_activity *file_actlst, char *dfil SOFT_SIZE)) == 0) { rtype = record_hdr[0].record_type; - if ((rtype != R_RESTART) && (rtype != R_COMMENT)) { - read_file_stat_bunch(act, 0, ifd, file_hdr.sa_nr_act, - file_actlst); - } if (rtype == R_RESTART) { + /* Read new CPU count */ + new_cpu_nr = read_new_cpu_nr(ifd, act); + + /* Display RESTART records */ write_textual_restarts(0, tm_start.use, tm_end.use, tab, - rectime, loctime); + rectime, loctime, new_cpu_nr); } else if (rtype == R_COMMENT) { /* Ignore COMMENT record */ @@ -1098,19 +1136,26 @@ void textual_display_loop(int ifd, struct file_activity *file_actlst, char *dfil perror("lseek"); } } + else { + /* Not a special record: Read the extra fields */ + read_file_stat_bunch(act, 0, ifd, file_hdr.sa_nr_act, + file_actlst); + } } } while (!eosaf); if (*fmt[f_position]->f_restart) { - (*fmt[f_position]->f_restart)(&tab, F_END, NULL, NULL, FALSE, &file_hdr); + (*fmt[f_position]->f_restart)(&tab, F_END, NULL, NULL, FALSE, &file_hdr, 0); } - /* Rewind file */ + /* Rewind file... */ if (lseek(ifd, fpos, SEEK_SET) < fpos) { perror("lseek"); exit(2); } + /* ... and restore number of CPU items for this position in file */ + allocate_cpu_structures(act, save_cpu_nr); /* Last, process COMMENT entries to display comments */ if (DISPLAY_COMMENT(flags)) { @@ -1123,14 +1168,24 @@ void textual_display_loop(int ifd, struct file_activity *file_actlst, char *dfil SOFT_SIZE)) == 0) { rtype = record_hdr[0].record_type; - if ((rtype != R_RESTART) && (rtype != R_COMMENT)) { - read_file_stat_bunch(act, 0, ifd, file_hdr.sa_nr_act, - file_actlst); - } if (rtype == R_COMMENT) { + /* Display R_COMMENT records */ write_textual_comments(0, tm_start.use, tm_end.use, tab, ifd, rectime, loctime); } + else if (rtype == R_RESTART) { + /* + * Ignore RESTART record (don't display it) + * but anyway we have to reallocate CPU structures + * according to new CPU count (value saved after RESTART record. + */ + read_new_cpu_nr(ifd, act); + } + else { + /* Not a special record: Read the extra fields */ + read_file_stat_bunch(act, 0, ifd, file_hdr.sa_nr_act, + file_actlst); + } } } while (!eosaf); @@ -1269,14 +1324,17 @@ void main_display_loop(int ifd, struct file_activity *file_actlst, __nr_t cpu_nr eosaf = sa_fread(ifd, &record_hdr[curr], RECORD_HEADER_SIZE, SOFT_SIZE); rtype = record_hdr[curr].record_type; - if (!eosaf && (rtype != R_RESTART) && (rtype != R_COMMENT)) { - read_file_stat_bunch(act, curr, ifd, file_hdr.sa_nr_act, - file_actlst); - } - else if (!eosaf && (rtype == R_COMMENT)) { - /* This was a COMMENT record: print it */ - sadf_print_special(curr, tm_start.use, tm_end.use, - R_COMMENT, ifd, rectime, loctime); + if (!eosaf) { + if (rtype == R_COMMENT) { + /* This was a COMMENT record: print it */ + sadf_print_special(curr, tm_start.use, tm_end.use, + R_COMMENT, ifd, rectime, loctime); + } + else if (rtype != R_RESTART) { + /* This is not a RESTART or a COMMENT record */ + read_file_stat_bunch(act, curr, ifd, file_hdr.sa_nr_act, + file_actlst); + } } } while (!eosaf && (rtype != R_RESTART)); diff --git a/sadf.h b/sadf.h index 4ba646b..45424df 100644 --- a/sadf.h +++ b/sadf.h @@ -163,7 +163,8 @@ struct report_format { /* * This function displays the restart messages. */ - __printf_funct_t (*f_restart) (int *, int, char *, char *, int, struct file_header *); + __printf_funct_t (*f_restart) (int *, int, char *, char *, int, struct file_header *, + unsigned int); /* * This function displays the comments. */ @@ -185,13 +186,13 @@ extern void * Prototypes used to display restart messages */ __printf_funct_t - print_db_restart(int *, int, char *, char *, int, struct file_header *); + print_db_restart(int *, int, char *, char *, int, struct file_header *, unsigned int); __printf_funct_t - print_ppc_restart(int *, int, char *, char *, int, struct file_header *); + print_ppc_restart(int *, int, char *, char *, int, struct file_header *, unsigned int); __printf_funct_t - print_xml_restart(int *, int, char *, char *, int, struct file_header *); + print_xml_restart(int *, int, char *, char *, int, struct file_header *, unsigned int); __printf_funct_t - print_json_restart(int *, int, char *, char *, int, struct file_header *); + print_json_restart(int *, int, char *, char *, int, struct file_header *, unsigned int); /* * Prototypes used to display comments diff --git a/sadf_misc.c b/sadf_misc.c index 70e5cd6..c0446b3 100644 --- a/sadf_misc.c +++ b/sadf_misc.c @@ -45,10 +45,11 @@ extern unsigned int flags; * @utc True if @cur_time is expressed in UTC. * @sep Character used as separator. * @file_hdr System activity file standard header. + * @cpu_nr CPU count associated with restart mark. *************************************************************************** */ void print_dbppc_restart(char *cur_date, char *cur_time, int utc, char sep, - struct file_header *file_hdr) + struct file_header *file_hdr, unsigned int cpu_nr) { printf("%s%c-1%c", file_hdr->sa_nodename, sep, sep); if (strlen(cur_date)) { @@ -58,7 +59,8 @@ void print_dbppc_restart(char *cur_date, char *cur_time, int utc, char sep, if (strlen(cur_date) && utc) { printf(" UTC"); } - printf("%cLINUX-RESTART\n", sep); + printf("%cLINUX-RESTART\t(%d CPU)\n", + sep, cpu_nr > 1 ? cpu_nr - 1 : 1); } /* @@ -72,14 +74,16 @@ void print_dbppc_restart(char *cur_date, char *cur_time, int utc, char sep, * @cur_time Time string of current restart message. * @utc True if @cur_time is expressed in UTC. * @file_hdr System activity file standard header. + * @cpu_nr CPU count associated with restart mark. *************************************************************************** */ __printf_funct_t print_db_restart(int *tab, int action, char *cur_date, - char *cur_time, int utc, struct file_header *file_hdr) + char *cur_time, int utc, struct file_header *file_hdr, + unsigned int cpu_nr) { /* Actions F_BEGIN and F_END ignored */ if (action == F_MAIN) { - print_dbppc_restart(cur_date, cur_time, utc, ';', file_hdr); + print_dbppc_restart(cur_date, cur_time, utc, ';', file_hdr, cpu_nr); } } @@ -94,14 +98,16 @@ __printf_funct_t print_db_restart(int *tab, int action, char *cur_date, * @cur_time Time string of current restart message. * @utc True if @cur_time is expressed in UTC. * @file_hdr System activity file standard header. + * @cpu_nr CPU count associated with restart mark. *************************************************************************** */ __printf_funct_t print_ppc_restart(int *tab, int action, char *cur_date, - char *cur_time, int utc, struct file_header *file_hdr) + char *cur_time, int utc, struct file_header *file_hdr, + unsigned int cpu_nr) { /* Actions F_BEGIN and F_END ignored */ if (action == F_MAIN) { - print_dbppc_restart(cur_date, cur_time, utc, '\t', file_hdr); + print_dbppc_restart(cur_date, cur_time, utc, '\t', file_hdr, cpu_nr); } } @@ -116,20 +122,22 @@ __printf_funct_t print_ppc_restart(int *tab, int action, char *cur_date, * @cur_time Time string of current restart message. * @utc True if @cur_time is expressed in UTC. * @file_hdr System activity file standard header (unused here). + * @cpu_nr CPU count associated with restart mark. * * OUT: * @tab Number of tabulations. *************************************************************************** */ __printf_funct_t print_xml_restart(int *tab, int action, char *cur_date, - char *cur_time, int utc, struct file_header *file_hdr) + char *cur_time, int utc, struct file_header *file_hdr, + unsigned int cpu_nr) { if (action & F_BEGIN) { xprintf((*tab)++, ""); } if (action & F_MAIN) { - xprintf(*tab, "", - cur_date, cur_time, utc ? 1 : 0); + xprintf(*tab, "", + cur_date, cur_time, utc ? 1 : 0, cpu_nr > 1 ? cpu_nr - 1 : 1); } if (action & F_END) { xprintf(--(*tab), ""); @@ -147,13 +155,15 @@ __printf_funct_t print_xml_restart(int *tab, int action, char *cur_date, * @cur_time Time string of current restart message. * @utc True if @cur_time is expressed in UTC. * @file_hdr System activity file standard header (unused here). + * @cpu_nr CPU count associated with restart mark. * * OUT: * @tab Number of tabulations. *************************************************************************** */ __printf_funct_t print_json_restart(int *tab, int action, char *cur_date, - char *cur_time, int utc, struct file_header *file_hdr) + char *cur_time, int utc, struct file_header *file_hdr, + unsigned int cpu_nr) { static int sep = FALSE; @@ -166,8 +176,8 @@ __printf_funct_t print_json_restart(int *tab, int action, char *cur_date, printf(",\n"); } xprintf((*tab)++, "{"); - xprintf(*tab, "\"boot\": {\"date\": \"%s\", \"time\": \"%s\", \"utc\": %d}", - cur_date, cur_time, utc ? 1 : 0); + xprintf(*tab, "\"boot\": {\"date\": \"%s\", \"time\": \"%s\", \"utc\": %d, \"cpu_count\": %d}", + cur_date, cur_time, utc ? 1 : 0, cpu_nr > 1 ? cpu_nr - 1 : 1); xprintf0(--(*tab), "}"); sep = TRUE; } -- 2.40.0