/* *************************************************************************** * Read next sample statistics. If it's a special record (RESTART or COMMENT) * then display it if requested. Also fill timestamps structures. * * IN: * @ifd File descriptor * @action Flags indicating if special records should be displayed or not. * * @curr Index in array for current sample statistics. * @file System activity data file name (name of file being read). * @rtype Record type (RESTART, COMMENT, etc.) * @tab Number of tabulations to print. * @file_actlst List of (known or unknown) activities in file. * @file_magic System activity file magic header. * @rectime Structure where timestamp (expressed in local time or in UTC * depending on whether options -T/-t have been used or not) can * be saved for current record. * @loctime Structure where timestamp (expressed in local time) can be * saved for current record. * * OUT: * @rectime Structure where timestamp (expressed in local time or in UTC * depending on whether options -T/-t have been used or not) has * been saved for current record. * @loctime Structure where timestamp (expressed in local time) has been * saved for current record. * * RETURNS: * TRUE if end of file has been reached. *************************************************************************** */ int read_next_sample(int ifd, int action, int curr, char *file, int *rtype, int tab, struct file_magic *file_magic, struct file_activity *file_actlst, struct tm *rectime, struct tm *loctime) { int eosaf; /* Read current record */ eosaf = sa_fread(ifd, &record_hdr[curr], RECORD_HEADER_SIZE, SOFT_SIZE); *rtype = record_hdr[curr].record_type; if (!eosaf) { if (*rtype == R_COMMENT) { if (action & IGNORE_COMMENT) { /* Ignore COMMENT record */ if (lseek(ifd, MAX_COMMENT_LEN, SEEK_CUR) < MAX_COMMENT_LEN) { perror("lseek"); } } else { /* Display COMMENT record */ print_special_record(curr, tm_start.use, tm_end.use, *rtype, ifd, rectime, loctime, file, tab, file_magic); } } else if (*rtype == R_RESTART) { if (action & IGNORE_RESTART) { /* * Ignore RESTART record (don't display it) * but anyway we have to reallocate volatile * activities structures (unless we don't want to * do it now). */ if (!(action & DONT_READ_VOLATILE)) { read_vol_act_structures(ifd, act, file, file_magic, file_hdr.sa_vol_act_nr); } } else { /* Display RESTART record */ print_special_record(curr, tm_start.use, tm_end.use, *rtype, ifd, rectime, loctime, file, tab, file_magic); } } else { /* * OK: Previous record was not a special one. * So read now the extra fields. */ read_file_stat_bunch(act, curr, ifd, file_hdr.sa_act_nr, file_actlst); sa_get_record_timestamp_struct(flags, &record_hdr[curr], rectime, loctime); } } return eosaf; }
/* *************************************************************************** * Print contents of a special (RESTART or COMMENT) record. * * IN: * @curr Index in array for current sample statistics. * @use_tm_start Set to TRUE if option -s has been used. * @use_tm_end Set to TRUE if option -e has been used. * @rtype Record type (RESTART or COMMENT). * @ifd Input file descriptor. * @rectime Structure where timestamp (expressed in local time * or in UTC depending on whether options -T/-t have * been used or not) can be saved for current record. * @loctime Structure where timestamp (expressed in local time) * can be saved for current record. * @file Name of file being read. * @tab Number of tabulations to print. * @file_magic file_magic structure filled with file magic header * data. *************************************************************************** */ void print_special_record(int curr, int use_tm_start, int use_tm_end, int rtype, int ifd, struct tm *rectime, struct tm *loctime, char *file, int tab, struct file_magic *file_magic) { char cur_date[32], cur_time[32]; int dp = 1; unsigned int new_cpu_nr; /* Fill timestamp structure (rectime) for current record */ sa_get_record_timestamp_struct(flags, &record_hdr[curr], rectime, loctime); /* The record must be in the interval specified by -s/-e options */ if ((use_tm_start && (datecmp(loctime, &tm_start) < 0)) || (use_tm_end && (datecmp(loctime, &tm_end) > 0))) { /* Will not display the special record */ dp = 0; } else { /* Set date and time strings to be displayed for current record */ set_record_timestamp_string(curr, cur_date, cur_time, 32, rectime); } if (rtype == R_RESTART) { /* Don't forget to read the volatile activities structures */ new_cpu_nr = read_vol_act_structures(ifd, act, file, file_magic, file_hdr.sa_vol_act_nr); if (!dp) return; 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, new_cpu_nr); } } else if (rtype == R_COMMENT) { char file_comment[MAX_COMMENT_LEN]; /* Read and replace non printable chars in comment */ replace_nonprintable_char(ifd, file_comment); if (!dp || !DISPLAY_COMMENT(flags)) return; if (*fmt[f_position]->f_comment) { (*fmt[f_position]->f_comment)(&tab, F_MAIN, cur_date, cur_time, !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags), file_comment, &file_hdr); } } }
/* *************************************************************************** * Print a Linux restart message (contents of a RESTART record) or a * comment (contents of a COMMENT record). * * IN: * @curr Index in array for current sample statistics. * @use_tm_start Set to TRUE if option -s has been used. * @use_tm_end Set to TRUE if option -e has been used. * @rtype Record type to display. * @ifd Input file descriptor. * @file Name of file being read. * @file_magic file_magic structure filled with file magic header * data. * * RETURNS: * 1 if the record has been successfully displayed, and 0 otherwise. *************************************************************************** */ int sar_print_special(int curr, int use_tm_start, int use_tm_end, int rtype, int ifd, char *file, struct file_magic *file_magic) { char cur_time[26], restart[64]; int dp = 1; unsigned int new_cpu_nr; if (set_record_timestamp_string(curr, cur_time, 26)) return 0; /* The record must be in the interval specified by -s/-e options */ if ((use_tm_start && (datecmp(&rectime, &tm_start) < 0)) || (use_tm_end && (datecmp(&rectime, &tm_end) > 0))) { dp = 0; } if (rtype == R_RESTART) { /* Don't forget to read the volatile activities structures */ new_cpu_nr = read_vol_act_structures(ifd, act, file, file_magic, file_hdr.sa_vol_act_nr); if (dp) { printf("\n%-11s", cur_time); sprintf(restart, " LINUX RESTART\t(%d CPU)\n", new_cpu_nr > 1 ? new_cpu_nr - 1 : 1); cprintf_s(IS_RESTART, "%s", restart); return 1; } } else if (rtype == R_COMMENT) { char file_comment[MAX_COMMENT_LEN]; /* Don't forget to read comment record even if it won't be displayed... */ replace_nonprintable_char(ifd, file_comment); if (dp && DISPLAY_COMMENT(flags)) { printf("%-11s", cur_time); cprintf_s(IS_COMMENT, " COM %s\n", file_comment); return 1; } } return 0; }