* tapestat: report tape statistics
* (C) 2015 Hewlett-Packard Development Company, L.P.
*
- * Initial revision by Shane M. SEYMOUR (shane.seymour <at> hp.com)
+ * Initial revision by Shane M. SEYMOUR (shane.seymour <at> hpe.com)
* Modified for sysstat by Sebastien GODARD (sysstat <at> orange.fr)
*
***************************************************************************
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA *
***************************************************************************
*/
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/utsname.h>
+
+#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#undef HZ /* sys/param.h defines HZ but needed for MAXPATHLEN */
+#endif
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 256
+#endif
#include "version.h"
#include "tapestat.h"
-#include "common.h"
+#include "rd_stats.h"
#include "count.h"
#ifdef USE_NLS
#define _(string) (string)
#endif
+#ifdef USE_SCCSID
#define SCCSID "@(#)sysstat-" VERSION ": " __FILE__ " compiled " __DATE__ " " __TIME__
char *sccsid(void) { return (SCCSID); }
+#endif
+
+#ifdef TEST
+void int_handler(int n) { return; }
+#endif
int cpu_nr = 0; /* Nb of processors on the machine */
int flags = 0; /* Flag for common options and system state */
long interval = 0;
-char timestamp[64];
+char timestamp[TIMESTAMP_LEN];
struct sigaction alrm_act;
+/* Number of decimal places */
+int dplaces_nr = -1;
+
/*
* For tape stats - it would be extremely rare for there to be a very large
* number of tape drives attached to a system. I wouldn't expect to see more
fprintf(stderr, _("Usage: %s [ options ] [ <interval> [ <count> ] ]\n"),
progname);
fprintf(stderr, _("Options are:\n"
- "[ -k | -m ] [ -t ] [ -V ] [ -y ] [ -z ]\n"));
+ "[ --human ] [ -k | -m ] [ -t ] [ -V ] [ -y ] [ -z ]\n"));
exit(1);
}
/* Count again number of tapes */
new_max_tape_drives = get_max_tape_drives();
- if ((new_max_tape_drives == 0) && (max_tape_drives == 0)) {
- /* If there are no tape drives don't change anything */
- return;
- } else {
- if (new_max_tape_drives > max_tape_drives) {
- /* New tapes found: Realloc structures */
- tape_old_stats = (struct tape_stats *)
- realloc(tape_old_stats, sizeof(struct tape_stats) * new_max_tape_drives);
- tape_new_stats=(struct tape_stats *)
- realloc(tape_new_stats, sizeof(struct tape_stats) * new_max_tape_drives);
- if ((tape_old_stats == NULL) || (tape_new_stats == NULL)) {
- if (tape_old_stats != NULL) {
- free(tape_old_stats);
- tape_old_stats = NULL;
- }
- if (tape_new_stats != NULL) {
- free(tape_new_stats);
- tape_new_stats = NULL;
- }
- return;
+ if (new_max_tape_drives > max_tape_drives && new_max_tape_drives > 0) {
+ /* New tapes found: Realloc structures */
+ struct tape_stats *tape_old_stats_t = (struct tape_stats *)
+ realloc(tape_old_stats, sizeof(struct tape_stats) * new_max_tape_drives);
+ struct tape_stats *tape_new_stats_t = (struct tape_stats *)
+ realloc(tape_new_stats, sizeof(struct tape_stats) * new_max_tape_drives);
+ if ((tape_old_stats_t == NULL) || (tape_new_stats_t == NULL)) {
+ if (tape_old_stats_t != NULL) {
+ free(tape_old_stats_t);
+ tape_old_stats_t = NULL;
+ } else {
+ free(tape_old_stats);
+ tape_old_stats = NULL;
}
-
- for (i = max_tape_drives; i < new_max_tape_drives; i++) {
- tape_old_stats[i].valid = TAPE_STATS_INVALID;
- tape_new_stats[i].valid = TAPE_STATS_INVALID;
+ if (tape_new_stats_t != NULL) {
+ free(tape_new_stats_t);
+ tape_new_stats_t = NULL;
+ } else {
+ free(tape_new_stats);
+ tape_new_stats = NULL;
}
- max_tape_drives = new_max_tape_drives;
+
+ perror("realloc");
+ exit(4);
}
+
+ tape_old_stats = tape_old_stats_t;
+ tape_new_stats = tape_new_stats_t;
+
+ for (i = max_tape_drives; i < new_max_tape_drives; i++) {
+ tape_old_stats[i].valid = TAPE_STATS_INVALID;
+ tape_new_stats[i].valid = TAPE_STATS_INVALID;
+ }
+ max_tape_drives = new_max_tape_drives;
}
}
tape_new_stats[i].valid = TAPE_STATS_VALID;
tape_old_stats[i].valid = TAPE_STATS_VALID;
- gettimeofday(&tape_old_stats[i].tv, NULL);
+ __gettimeofday(&tape_old_stats[i].tv, NULL);
tape_new_stats[i].tv.tv_sec = tape_old_stats[i].tv.tv_sec;
tape_new_stats[i].tv.tv_usec = tape_old_stats[i].tv.tv_usec;
* to open a file gets the tape drive marked invalid.
*/
tape_new_stats[i].valid = TAPE_STATS_VALID;
- gettimeofday(&tape_new_stats[i].tv, NULL);
+ __gettimeofday(&tape_new_stats[i].tv, NULL);
TAPE_STAT_FILE_VAL(TAPE_STAT_PATH "read_ns", read_time)
TAPE_STAT_FILE_VAL(TAPE_STAT_PATH "write_ns", write_time)
*/
void tape_write_headings(void)
{
- printf("Tape: r/s w/s ");
+ printf("Tape: r/s w/s ");
if (DISPLAY_MEGABYTES(flags)) {
printf("MB_read/s MB_wrtn/s");
} else {
printf("kB_read/s kB_wrtn/s");
}
- printf(" %%Rd %%Wr %%Oa Rs/s Ot/s\n");
+ printf(" %%Rd %%Wr %%Oa Rs/s Ot/s\n");
}
/*
/* If duration is zero we need to calculate the ms since boot time */
if (duration == 0) {
- fp = fopen("/proc/uptime", "r");
+ fp = fopen(UPTIME, "r");
/*
* Get uptime from /proc/uptime and if we can't then just set duration to
if (fp == NULL) {
duration = 0;
} else {
- fscanf(fp, "%lf", &temp);
+ if (fscanf(fp, "%lf", &temp) != 1) {
+ temp = 0;
+ }
duration = (uint64_t) (temp * 1000);
fclose(fp);
}
sprintf(buffer, "st%i ", i);
buffer[5] = 0;
- printf("%s%7"PRId64" %7"PRId64" %11"PRId64
- " %11"PRId64" %3"PRId64" %3"PRId64" %3"PRId64
- " %7"PRId64" %7"PRId64"\n", buffer,
- tape->reads_per_second, tape->writes_per_second,
- tape->kbytes_read_per_second/divisor,
- tape->kbytes_written_per_second/divisor,
- tape->read_pct_wait, tape->write_pct_wait,
- tape->all_pct_wait, tape->resids_per_second,
- tape->other_per_second);
+ cprintf_in(IS_STR, "%s", buffer, 0);
+ cprintf_u64(NO_UNIT, 2, 7,
+ tape->reads_per_second,
+ tape->writes_per_second);
+ cprintf_u64(DISPLAY_UNIT(flags) ? UNIT_KILOBYTE : NO_UNIT, 2, 11,
+ DISPLAY_UNIT(flags) ? tape->kbytes_read_per_second
+ : tape->kbytes_read_per_second / divisor,
+ DISPLAY_UNIT(flags) ? tape->kbytes_written_per_second
+ : tape->kbytes_written_per_second / divisor);
+ cprintf_pc(DISPLAY_UNIT(flags), 3, 4, 0,
+ (double) tape->read_pct_wait,
+ (double) tape->write_pct_wait,
+ (double) tape->all_pct_wait);
+ cprintf_u64(NO_UNIT, 2, 7,
+ tape->resids_per_second,
+ tape->other_per_second);
+ printf("\n");
}
/*
* Print everything now (stats and uptime).
*
* IN:
- * @curr Index in array for current sample statistics.
* @rectime Current date and time.
***************************************************************************
*/
-void write_stats(int curr, struct tm *rectime)
+void write_stats(struct tm *rectime)
{
int i;
struct calc_stats tape;
/*
***************************************************************************
- * Main loop: Read I/O stats from the relevant sources and display them.
+ * Main loop: Read tape stats from the relevant sources and display them.
*
* IN:
* @count Number of lines of stats to print.
* @rectime Current date and time.
***************************************************************************
*/
-void rw_io_stat_loop(long int count, struct tm *rectime)
+void rw_tape_stat_loop(long int count, struct tm *rectime)
{
struct tape_stats *tmp;
- int curr = 1;
int skip = 0;
/* Should we skip first report? */
skip = 1;
}
- /* Don't buffer data if redirected to a pipe */
- setbuf(stdout, NULL);
-
do {
if (tape_new_stats == NULL) {
/* Check whether we should skip first report */
if (!skip) {
/* Print results */
- write_stats(curr, rectime);
+ write_stats(rectime);
if (count > 0) {
count--;
}
if (count) {
- curr ^= 1;
- pause();
+ __pause();
}
}
while (count);
init_nls();
#endif
- /* Get HZ */
- get_HZ();
+ /* Init color strings */
+ init_colors();
/* Process args... */
while (opt < argc) {
- if (!strncmp(argv[opt], "-", 1)) {
+
+ if (!strcmp(argv[opt], "--human")) {
+ flags |= T_D_UNIT;
+ opt++;
+ }
+
+ else if (!strncmp(argv[opt], "-", 1)) {
for (i = 1; *(argv[opt] + i); i++) {
switch (*(argv[opt] + i)) {
get_localtime(&rectime, 0);
+ /*
+ * Don't buffer data if redirected to a pipe.
+ * Note: With musl-c, the behavior of this function is undefined except
+ * when it is the first operation on the stream.
+ */
+ setbuf(stdout, NULL);
+
/* Get system name, release number and hostname */
- uname(&header);
+ __uname(&header);
if (print_gal_header(&rectime, header.sysname, header.release,
- header.nodename, header.machine, cpu_nr)) {
+ header.nodename, header.machine, cpu_nr,
+ PLAIN_OUTPUT)) {
flags |= T_D_ISO;
}
printf("\n");
alarm(interval);
/* Main loop */
- rw_io_stat_loop(count, &rectime);
+ rw_tape_stat_loop(count, &rectime);
/* Free structures */
tape_uninitialise();