/* *************************************************************************** * 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); } } }
/* *************************************************************************** * Display COMMENT records for textual (XML-like) reports. * * 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. * @tab Number of tabulations to print. * @ifd Input file descriptor. * @rectime Structure where timestamp (expressed in local time * or in UTC depending on whether option -t has 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 for current record has * been saved. * @loctime Structure where timestamp for current record has * been saved. *************************************************************************** */ void write_textual_comments(int curr, int use_tm_start, int use_tm_end, int tab, int ifd, struct tm *rectime, struct tm *loctime) { char cur_date[32], cur_time[32]; char file_comment[MAX_COMMENT_LEN]; sa_fread(ifd, file_comment, MAX_COMMENT_LEN, HARD_SIZE); file_comment[MAX_COMMENT_LEN - 1] = '\0'; /* Fill timestamp structure for current record */ sadf_get_record_timestamp_struct(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))) return; set_record_timestamp_string(curr, cur_date, cur_time, 32, rectime); if (*fmt[f_position]->f_comment) { (*fmt[f_position]->f_comment)(&tab, F_MAIN, cur_date, cur_time, !PRINT_TRUE_TIME(flags), file_comment, &file_hdr); } }
/* *************************************************************************** * 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 option -t has been * used or not) can be saved for current record. * @loctime Structure where timestamp (expressed in local time) * can be saved for current record. *************************************************************************** */ void sadf_print_special(int curr, int use_tm_start, int use_tm_end, int rtype, int ifd, struct tm *rectime, struct tm *loctime) { char cur_date[32], cur_time[32]; int dp = 1; /* Fill timestamp structure (rectime) for current record */ sadf_get_record_timestamp_struct(curr, rectime, loctime); /* Set date and time strings for current record */ set_record_timestamp_string(curr, cur_date, cur_time, 32, rectime); /* 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))) { dp = 0; } if (rtype == R_RESTART) { if (!dp) return; if (*fmt[f_position]->f_restart) { (*fmt[f_position]->f_restart)(NULL, F_MAIN, cur_date, cur_time, !PRINT_TRUE_TIME(flags), &file_hdr); } } else if (rtype == R_COMMENT) { char file_comment[MAX_COMMENT_LEN]; sa_fread(ifd, file_comment, MAX_COMMENT_LEN, HARD_SIZE); file_comment[MAX_COMMENT_LEN - 1] = '\0'; if (!dp || !DISPLAY_COMMENT(flags)) return; if (*fmt[f_position]->f_comment) { (*fmt[f_position]->f_comment)(NULL, F_MAIN, cur_date, cur_time, !PRINT_TRUE_TIME(flags), file_comment, &file_hdr); } } }
/* *************************************************************************** * Display the "timestamp" part of the report (raw format). * * IN: * @parm Pointer on specific parameters (unused here). * @action Action expected from current function. * @cur_date Date string of current record. * @cur_time Time string of current record. * @itv Interval of time with preceding record (unused here). * @file_hdr System activity file standard header (unused here). * @flags Flags for common options. * * RETURNS: * Pointer on the "timestamp" string. *************************************************************************** */ __tm_funct_t print_raw_timestamp(void *parm, int action, char *cur_date, char *cur_time, unsigned long long itv, struct file_header *file_hdr, unsigned int flags) { int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags); static char pre[80]; if (action & F_BEGIN) { snprintf(pre, 80, "%s%s", cur_time, strlen(cur_date) && utc ? " UTC" : ""); pre[79] = '\0'; return pre; } return NULL; }
/* *************************************************************************** * Fill rectime structure according to time data saved in current * structure. * * IN: * @curr Index in array for current sample statistics. *************************************************************************** */ void sar_set_rectime(int curr) { struct tm *ltm; /* Check if option -t was specified on the command line */ if (PRINT_TRUE_TIME(flags)) { /* -t */ rectime.tm_hour = record_hdr[curr].hour; rectime.tm_min = record_hdr[curr].minute; rectime.tm_sec = record_hdr[curr].second; } else { ltm = localtime((const time_t *) &record_hdr[curr].ust_time); rectime = *ltm; } }
/* *************************************************************************** * Display the "timestamp" part of the report (XML format). * * IN: * @tab Number of tabulations. * @action Action expected from current function. * @cur_date Date string of current comment. * @cur_time Time string of current comment. * @utc True if @cur_time is expressed in UTC. * @itv Interval of time with preceding record. * * OUT: * @tab Number of tabulations. *************************************************************************** */ __tm_funct_t print_xml_timestamp(int *tab, int action, char *cur_date, char *cur_time, unsigned long long itv, struct file_header *file_hdr, unsigned int flags) { int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags); if (action & F_BEGIN) { xprintf((*tab)++, "<timestamp date=\"%s\" time=\"%s\" utc=\"%d\" interval=\"%llu\">", cur_date, cur_time, utc ? 1 : 0, itv); } if (action & F_END) { xprintf(--(*tab), "</timestamp>"); } return NULL; }
/* *************************************************************************** * Display the "timestamp" part of the report (db format). * * IN: * @parm Pointer on specific parameters (unused here). * @action Action expected from current function. * @cur_date Date string of current record. * @cur_time Time string of current record. * @itv Interval of time with preceding record. * @file_hdr System activity file standard header. * @flags Flags for common options. * * RETURNS: * Pointer on the "timestamp" string. *************************************************************************** */ __tm_funct_t print_db_timestamp(void *parm, int action, char *cur_date, char *cur_time, unsigned long long itv, struct file_header *file_hdr, unsigned int flags) { int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags); if (action & F_BEGIN) { return print_dbppc_timestamp(F_DB_OUTPUT, file_hdr, cur_date, cur_time, utc, itv); } if (action & F_END) { if (DISPLAY_HORIZONTALLY(flags)) { printf("\n"); } } return NULL; }
/* *************************************************************************** * Fill the rectime and loctime structures with current record's date and * time, based on current record's "number of seconds since the epoch" saved * in file. * The resulting timestamp is expressed in UTC or in local time, depending * on whether option -t has been used or not. * * IN: * @curr Index in array for current sample statistics. * @rectime Structure where timestamp (expressed in local time or in UTC * depending on whether option -t has 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 for current record has been saved. * @loctime Structure where timestamp for current record has been saved. *************************************************************************** */ void sadf_get_record_timestamp_struct(int curr, struct tm *rectime, struct tm *loctime) { struct tm *ltm; if ((ltm = localtime((const time_t *) &record_hdr[curr].ust_time)) != NULL) { *loctime = *ltm; } if (!PRINT_TRUE_TIME(flags)) { /* Option -t not used: Display timestamp in UTC */ ltm = gmtime((const time_t *) &record_hdr[curr].ust_time); } if (ltm) { *rectime = *ltm; } }
/* *************************************************************************** * Display restart records for textual (XML-like) reports. * * 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. * @tab Number of tabulations to print. * @rectime Structure where timestamp (expressed in local time * or in UTC depending on whether option -t has 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 for current record has * been saved. * @loctime Structure where timestamp for current record has * been saved. *************************************************************************** */ void write_textual_restarts(int curr, int use_tm_start, int use_tm_end, int tab, struct tm *rectime, struct tm *loctime) { char cur_date[32], cur_time[32]; /* Fill timestamp structure for current record */ sadf_get_record_timestamp_struct(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))) return; set_record_timestamp_string(curr, cur_date, cur_time, 32, rectime); if (*fmt[f_position]->f_restart) { (*fmt[f_position]->f_restart)(&tab, F_MAIN, cur_date, cur_time, !PRINT_TRUE_TIME(flags), &file_hdr); } }
/* *************************************************************************** * write_mech_stats() - * Replace the old write_stats_for_ppc() and write_stats_for_db(), * making it easier for them to remain in sync and print the same data. * * IN: * @curr Index in array for current sample statistics. * @dt Interval of time in seconds. * @itv Interval of time in jiffies. * @g_itv Interval of time in jiffies multiplied by the number of * processors. * @cur_date Date string for current record. * @cur_time Time string for current record. * @act_id Activity to display, or ~0 for all. *************************************************************************** */ void write_mech_stats(int curr, unsigned long dt, unsigned long long itv, unsigned long long g_itv, char *cur_date, char *cur_time, unsigned int act_id) { int i; char pre[80], temp[80]; /* Text at beginning of each line */ int isdb = (format == F_DB_OUTPUT); /* This substring appears on every output line, preformat it here */ snprintf(pre, 80, "%s%s%ld%s", file_hdr.sa_nodename, seps[isdb], dt, seps[isdb]); if (strlen(cur_date)) { snprintf(temp, 80, "%s%s ", pre, cur_date); } else { strcpy(temp, pre); } snprintf(pre, 80, "%s%s%s", temp, cur_time, strlen(cur_date) && !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags) ? " UTC" : ""); pre[79] = '\0'; if (DISPLAY_HORIZONTALLY(flags)) { printf("%s", pre); } for (i = 0; i < NR_ACT; i++) { if ((act_id != ALL_ACTIVITIES) && (act[i]->id != act_id)) continue; if (IS_SELECTED(act[i]->options) && (act[i]->nr > 0)) { (*act[i]->f_render)(act[i], isdb, pre, curr, NEED_GLOBAL_ITV(act[i]->options) ? g_itv : itv); } } if (DISPLAY_HORIZONTALLY(flags)) { printf("\n"); } }
/* *************************************************************************** * Display the "timestamp" part of the report (JSON format). * * IN: * @tab Number of tabulations. * @action Action expected from current function. * @cur_date Date string of current comment. * @cur_time Time string of current comment. * @utc True if @cur_time is expressed in UTC. * @itv Interval of time with preceding record. * * OUT: * @tab Number of tabulations. *************************************************************************** */ __tm_funct_t print_json_timestamp(int *tab, int action, char *cur_date, char *cur_time, unsigned long long itv, struct file_header *file_hdr, unsigned int flags) { int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags); if (action & F_BEGIN) { xprintf0(*tab, "\"timestamp\": {\"date\": \"%s\", \"time\": \"%s\", " "\"utc\": %d, \"interval\": %llu}", cur_date, cur_time, utc ? 1 : 0, itv); } if (action & F_MAIN) { printf(",\n"); } if (action & F_END) { printf("\n"); } return NULL; }
/* *************************************************************************** * Fill the (struct tm) rectime structure with current record's time, * based on current record's time data saved in file. * The resulting timestamp is expressed in the locale of the file creator * or in the user's own locale depending on whether option -t has been used * or not. * * IN: * @curr Index in array for current sample statistics. * * RETURNS: * 1 if an error was detected, or 0 otherwise. *************************************************************************** */ int sar_get_record_timestamp_struct(int curr) { struct tm *ltm; /* Check if option -t was specified on the command line */ if (PRINT_TRUE_TIME(flags)) { /* -t */ rectime.tm_hour = record_hdr[curr].hour; rectime.tm_min = record_hdr[curr].minute; rectime.tm_sec = record_hdr[curr].second; } else { if ((ltm = localtime((const time_t *) &record_hdr[curr].ust_time)) == NULL) /* * An error was detected. * The rectime structure has NOT been updated. */ return 1; rectime = *ltm; } return 0; }
/* *************************************************************************** * Display activity records for textual (XML-like) formats. * * 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. * @reset Set to TRUE if last_uptime should be reinitialized * (used in next_slice() function). * @tab Number of tabulations to print. * @cpu_nr Number of processors. * @rectime Structure where timestamp (expressed in local time * or in UTC depending on whether option -t has 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: * @cnt Set to 0 to indicate that no other lines of stats * should be displayed. * * RETURNS: * 1 if stats have been successfully displayed. *************************************************************************** */ int write_textual_stats(int curr, int use_tm_start, int use_tm_end, int reset, long *cnt, int tab, __nr_t cpu_nr, struct tm *rectime, struct tm *loctime) { int i; unsigned long long dt, itv, g_itv; char cur_date[32], cur_time[32]; static int cross_day = FALSE; /* Fill timestamp structure (rectime) for current record */ sadf_get_record_timestamp_struct(curr, rectime, loctime); /* * Check time (1). * For this first check, we use the time interval entered on * the command line. This is equivalent to sar's option -i which * selects records at seconds as close as possible to the number * specified by the interval parameter. */ if (!next_slice(record_hdr[2].uptime0, record_hdr[curr].uptime0, reset, interval)) /* Not close enough to desired interval */ return 0; /* Check if we are beginning a new day */ if (use_tm_start && record_hdr[!curr].ust_time && (record_hdr[curr].ust_time > record_hdr[!curr].ust_time) && (record_hdr[curr].hour < record_hdr[!curr].hour)) { cross_day = TRUE; } if (cross_day) { /* * This is necessary if we want to properly handle something like: * sar -s time_start -e time_end with * time_start(day D) > time_end(day D+1) */ loctime->tm_hour += 24; } /* Check time (2) */ if (use_tm_start && (datecmp(loctime, &tm_start) < 0)) /* it's too soon... */ return 0; /* Get interval values */ get_itv_value(&record_hdr[curr], &record_hdr[!curr], cpu_nr, &itv, &g_itv); /* Check time (3) */ if (use_tm_end && (datecmp(loctime, &tm_end) > 0)) { /* It's too late... */ *cnt = 0; return 0; } dt = itv / HZ; /* Correct rounding error for dt */ if ((itv % HZ) >= (HZ / 2)) { dt++; } /* Set date and time strings for current record */ set_record_timestamp_string(curr, cur_date, cur_time, 32, rectime); if (*fmt[f_position]->f_timestamp) { (*fmt[f_position]->f_timestamp)(&tab, F_BEGIN, cur_date, cur_time, !PRINT_TRUE_TIME(flags), dt); } if (format == F_XML_OUTPUT) { tab++; } /* Display textual statistics */ for (i = 0; i < NR_ACT; i++) { /* This code is not generic at all...! */ if (format == F_JSON_OUTPUT) { /* JSON output */ if (CLOSE_MARKUP(act[i]->options) || (IS_SELECTED(act[i]->options) && (act[i]->nr > 0))) { if (IS_SELECTED(act[i]->options) && (act[i]->nr > 0)) { printf(","); if (*fmt[f_position]->f_timestamp) { (*fmt[f_position]->f_timestamp)(&tab, F_MAIN, cur_date, cur_time, !PRINT_TRUE_TIME(flags), dt); } } (*act[i]->f_json_print)(act[i], curr, tab, NEED_GLOBAL_ITV(act[i]->options) ? g_itv : itv); } } else { /* XML output */ if (CLOSE_MARKUP(act[i]->options) || (IS_SELECTED(act[i]->options) && (act[i]->nr > 0))) { (*act[i]->f_xml_print)(act[i], curr, tab, NEED_GLOBAL_ITV(act[i]->options) ? g_itv : itv); } } } if (*fmt[f_position]->f_timestamp) { (*fmt[f_position]->f_timestamp)(&tab, F_END, cur_date, cur_time, !PRINT_TRUE_TIME(flags), dt); } return 1; }
/* *************************************************************************** * Main entry to the sadf program *************************************************************************** */ int main(int argc, char **argv) { int opt = 1, sar_options = 0; int day_offset = 0; int i, rc; char dfile[MAX_FILE_LEN]; char *t; /* Get HZ */ get_HZ(); /* Compute page shift in kB */ get_kb_shift(); dfile[0] = '\0'; #ifdef USE_NLS /* Init National Language Support */ init_nls(); #endif tm_start.use = tm_end.use = FALSE; /* Allocate and init activity bitmaps */ allocate_bitmaps(act); /* Init some structures */ init_structures(); /* Process options */ while (opt < argc) { if (!strcmp(argv[opt], "-I")) { if (argv[++opt] && sar_options) { if (parse_sar_I_opt(argv, &opt, act)) { usage(argv[0]); } } else { usage(argv[0]); } } else if (!strcmp(argv[opt], "-P")) { if (parse_sa_P_opt(argv, &opt, &flags, act)) { usage(argv[0]); } } else if (!strcmp(argv[opt], "-s")) { /* Get time start */ if (parse_timestamp(argv, &opt, &tm_start, DEF_TMSTART)) { usage(argv[0]); } } else if (!strcmp(argv[opt], "-e")) { /* Get time end */ if (parse_timestamp(argv, &opt, &tm_end, DEF_TMEND)) { usage(argv[0]); } } else if (!strcmp(argv[opt], "-O")) { /* Parse SVG options */ if (!argv[++opt] || sar_options) { usage(argv[0]); } for (t = strtok(argv[opt], ","); t; t = strtok(NULL, ",")) { if (!strcmp(t, K_SKIP_EMPTY)) { flags |= S_F_SVG_SKIP; } else if (!strcmp(t, K_AUTOSCALE)) { flags |= S_F_SVG_AUTOSCALE; } else { usage(argv[0]); } } opt++; } else if ((strlen(argv[opt]) > 1) && (strlen(argv[opt]) < 4) && !strncmp(argv[opt], "-", 1) && (strspn(argv[opt] + 1, DIGITS) == (strlen(argv[opt]) - 1))) { if (dfile[0] || day_offset) { /* File already specified */ usage(argv[0]); } day_offset = atoi(argv[opt++] + 1); } else if (!strcmp(argv[opt], "--")) { sar_options = 1; opt++; } else if (!strcmp(argv[opt], "-m")) { if (argv[++opt] && sar_options) { /* Parse sar's option -m */ if (parse_sar_m_opt(argv, &opt, act)) { usage(argv[0]); } } else { usage(argv[0]); } } else if (!strcmp(argv[opt], "-n")) { if (argv[++opt] && sar_options) { /* Parse sar's option -n */ if (parse_sar_n_opt(argv, &opt, act)) { usage(argv[0]); } } else { usage(argv[0]); } } else if (!strncmp(argv[opt], "-", 1)) { /* Other options not previously tested */ if (sar_options) { if ((rc = parse_sar_opt(argv, &opt, act, &flags, C_SADF)) != 0) { if (rc == 1) { usage(argv[0]); } exit(1); } } else { for (i = 1; *(argv[opt] + i); i++) { switch (*(argv[opt] + i)) { case 'C': flags |= S_F_COMMENT; break; case 'c': if (format) { usage(argv[0]); } format = F_CONV_OUTPUT; break; case 'd': if (format) { usage(argv[0]); } format = F_DB_OUTPUT; break; case 'g': if (format) { usage(argv[0]); } format = F_SVG_OUTPUT; break; case 'h': flags |= S_F_HORIZONTALLY; break; case 'H': flags |= S_F_HDR_ONLY; break; case 'j': if (format) { usage(argv[0]); } format = F_JSON_OUTPUT; break; case 'p': if (format) { usage(argv[0]); } format = F_PPC_OUTPUT; break; case 'T': flags |= S_F_LOCAL_TIME; break; case 't': flags |= S_F_TRUE_TIME; break; case 'U': flags |= S_F_SEC_EPOCH; break; case 'x': if (format) { usage(argv[0]); } format = F_XML_OUTPUT; break; case 'V': print_version(); break; default: usage(argv[0]); } } } opt++; } /* Get data file name */ else if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) { if (dfile[0] || day_offset) { /* File already specified */ usage(argv[0]); } if (!strcmp(argv[opt], "-")) { /* File name set to '-' */ set_default_file(dfile, 0, -1); opt++; } else if (!strncmp(argv[opt], "-", 1)) { /* Bad option */ usage(argv[0]); } else { /* Write data to file */ strncpy(dfile, argv[opt++], MAX_FILE_LEN); dfile[MAX_FILE_LEN - 1] = '\0'; /* Check if this is an alternate directory for sa files */ check_alt_sa_dir(dfile, 0, -1); } } else if (interval < 0) { /* Get interval */ if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) { usage(argv[0]); } interval = atol(argv[opt++]); if (interval <= 0) { usage(argv[0]); } } else { /* Get count value */ if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) { usage(argv[0]); } if (count) { /* Count parameter already set */ usage(argv[0]); } count = atol(argv[opt++]); if (count < 0) { usage(argv[0]); } else if (!count) { count = -1; /* To generate a report continuously */ } } } /* sadf reads current daily data file by default */ if (!dfile[0]) { set_default_file(dfile, day_offset, -1); } if (tm_start.use && tm_end.use && (tm_end.tm_hour < tm_start.tm_hour)) { tm_end.tm_hour += 24; } if (USE_PRETTY_OPTION(flags)) { dm_major = get_devmap_major(); } /* Options -T, -t and -U are mutually exclusive */ if ((PRINT_LOCAL_TIME(flags) + PRINT_TRUE_TIME(flags) + PRINT_SEC_EPOCH(flags)) > 1) { usage(argv[0]); } /* * Display all the contents of the daily data file if the count parameter * was not set on the command line. */ if (!count) { count = -1; } /* Default is CPU activity */ select_default_activity(act); /* Check options consistency with selected output format. Default is PPC display */ check_format_options(); if (interval < 0) { interval = 1; } 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); return 0; }