Beispiel #1
0
/*
 ***************************************************************************
 * 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;
}
Beispiel #2
0
/*
 ***************************************************************************
 * Display file contents in selected format (logic #2).
 * Logic #2:	Grouped by activity. Sorted by timestamp. Stop on RESTART
 * 		records.
 * Formats:	ppc, CSV
 *
 * IN:
 * @ifd		File descriptor of input file.
 * @file_actlst	List of (known or unknown) activities in file.
 * @cpu_nr	Number of processors for current activity data file.
 * @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.
 * @file_magic	file_magic structure filled with file magic header data.
 ***************************************************************************
 */
void logic2_display_loop(int ifd, struct file_activity *file_actlst, __nr_t cpu_nr,
			 struct tm *rectime, struct tm *loctime, char *file,
			 struct file_magic *file_magic)
{
	int i, p;
	int curr = 1, rtype;
	int eosaf = TRUE, reset = FALSE;
	long cnt = 1;
	off_t fpos;

	/* Read system statistics from file */
	do {
		/*
		 * If this record is a special (RESTART or COMMENT) one, print it and
		 * (try to) get another one.
		 */
		do {
			if (read_next_sample(ifd, IGNORE_NOTHING, 0,
					     file, &rtype, 0, file_magic, file_actlst,
					     rectime, loctime))
				/* End of sa data file */
				return;
		}
		while ((rtype == R_RESTART) || (rtype == R_COMMENT) ||
		       (tm_start.use && (datecmp(loctime, &tm_start) < 0)) ||
		       (tm_end.use && (datecmp(loctime, &tm_end) >= 0)));

		/* Save the first stats collected. Used for example in next_slice() function */
		copy_structures(act, id_seq, record_hdr, 2, 0);

		/* Set flag to reset last_uptime variable. Should be done after a LINUX RESTART record */
		reset = TRUE;

		/* Save current file position */
		if ((fpos = lseek(ifd, 0, SEEK_CUR)) < 0) {
			perror("lseek");
			exit(2);
		}

		/* Read and write stats located between two possible Linux restarts */

		if (DISPLAY_HORIZONTALLY(flags)) {
			/*
			 * If stats are displayed horizontally, then all activities
			 * are printed on the same line.
			 */
			rw_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf,
					  ALL_ACTIVITIES, &reset, file_actlst,
					  cpu_nr, rectime, loctime, file, file_magic);
		}
		else {
			/* For each requested activity... */
			for (i = 0; i < NR_ACT; i++) {

				if (!id_seq[i])
					continue;

				p = get_activity_position(act, id_seq[i], EXIT_IF_NOT_FOUND);
				if (!IS_SELECTED(act[p]->options))
					continue;

				if (!HAS_MULTIPLE_OUTPUTS(act[p]->options)) {
					rw_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf,
							  act[p]->id, &reset, file_actlst,
							  cpu_nr, rectime, loctime, file,
							  file_magic);
				}
				else {
					unsigned int optf, msk;

					optf = act[p]->opt_flags;

					for (msk = 1; msk < 0x100; msk <<= 1) {
						if ((act[p]->opt_flags & 0xff) & msk) {
							act[p]->opt_flags &= (0xffffff00 + msk);

							rw_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf,
									  act[p]->id, &reset, file_actlst,
									  cpu_nr, rectime, loctime, file,
									  file_magic);
							act[p]->opt_flags = optf;
						}
					}
				}
			}
		}

		if (!cnt) {
			/* Go to next Linux restart, if possible */
			do {
				eosaf = read_next_sample(ifd, IGNORE_RESTART | DONT_READ_VOLATILE,
							 curr, file, &rtype, 0, file_magic,
							 file_actlst, rectime, loctime);
			}
			while (!eosaf && (rtype != R_RESTART));
		}

		/*
		 * The last record we read was a RESTART one: Print it.
		 * NB: Unlike COMMENTS records (which are displayed for each
		 * activity), RESTART ones are only displayed once.
		 */
		if (!eosaf && (record_hdr[curr].record_type == R_RESTART)) {
			print_special_record(&record_hdr[curr], flags, &tm_start, &tm_end,
					     R_RESTART, ifd, rectime, loctime, file, 0,
					     file_magic, &file_hdr, act, fmt[f_position]);
		}
	}
	while (!eosaf);
}