2 * tapestat: report tape statistics
3 * (C) 2015 Hewlett-Packard Development Company, L.P.
5 * Initial revision by Shane M. SEYMOUR (shane.seymour <at> hpe.com)
6 * Modified for sysstat by Sebastien GODARD (sysstat <at> orange.fr)
14 /* T_: tapestat - D_: Display - F_: Flag */
15 #define T_D_TIMESTAMP 0x00001
16 #define T_D_KILOBYTES 0x00002
17 #define T_D_MEGABYTES 0x00004
18 #define T_D_OMIT_SINCE_BOOT 0x00008
19 #define T_D_ISO 0x00010
20 #define T_D_ZERO_OMIT 0x00020
21 #define T_D_UNIT 0x00040
23 #define DISPLAY_TIMESTAMP(m) (((m) & T_D_TIMESTAMP) == T_D_TIMESTAMP)
24 #define DISPLAY_KILOBYTES(m) (((m) & T_D_KILOBYTES) == T_D_KILOBYTES)
25 #define DISPLAY_MEGABYTES(m) (((m) & T_D_MEGABYTES) == T_D_MEGABYTES)
26 #define DISPLAY_OMIT_SINCE_BOOT(m) (((m) & T_D_OMIT_SINCE_BOOT) == T_D_OMIT_SINCE_BOOT)
27 #define DISPLAY_ISO(m) (((m) & T_D_ISO) == T_D_ISO)
28 #define DISPLAY_ZERO_OMIT(m) (((m) & T_D_ZERO_OMIT) == T_D_ZERO_OMIT)
29 #define DISPLAY_UNIT(m) (((m) & T_D_UNIT) == T_D_UNIT)
31 #define TAPE_STATS_VALID 1
32 #define TAPE_STATS_INVALID 0
34 #define SYSFS_CLASS_TAPE_DIR PRE "/sys/class/scsi_tape"
35 #define TAPE_STAT_PATH PRE "/sys/class/scsi_tape/st%i/stats/"
37 #define TAPE_STAT_FILE_VAL(A, B) \
38 snprintf(filename, MAXPATHLEN, A, i); \
39 if ((fp = fopen(filename, "r")) != NULL) { \
40 if (fscanf(fp, "%"PRId64, &tape_new_stats[i].B) != 1) { \
41 tape_new_stats[i].valid = TAPE_STATS_INVALID; \
45 tape_new_stats[i].valid = TAPE_STATS_INVALID; \
51 * A - tape_stats structure member name, e.g. read_count
52 * B - calc_stats structure member name, e.g. reads_per_second
54 * These macros are not selfcontained they depend on some other
55 * variables defined either as global or local to the function.
58 #define CALC_STAT_CNT(A, B) \
59 if ((tape_new_stats[i].A == tape_old_stats[i].A) || \
63 temp = (double) (tape_new_stats[i].A - \
64 tape_old_stats[i].A) \
65 / (((double) duration) / 1000); \
66 stats->B = (uint64_t) temp; \
68 #define CALC_STAT_KB(A, B) \
69 if ((tape_new_stats[i].A == tape_old_stats[i].A) || \
73 temp = (double) (tape_new_stats[i].A - \
74 tape_old_stats[i].A) \
75 / (((double) duration) / 1000.0); \
76 stats->B = (uint64_t) (temp / 1024.0); \
79 #define TAPE_MAX_PCT 999
81 #define CALC_STAT_PCT(A, B) \
82 if ((tape_new_stats[i].A == tape_old_stats[i].A) || \
86 temp = (double) (tape_new_stats[i].A - \
87 tape_old_stats[i].A) \
88 / (((double) duration)); \
89 stats->B = (uint64_t) (100.0 * temp / 1000000.0); \
90 if (stats->B > TAPE_MAX_PCT) \
91 stats->B = TAPE_MAX_PCT; \
101 uint64_t write_count;
102 uint64_t other_count;
103 uint64_t resid_count;
108 uint64_t reads_per_second;
109 uint64_t writes_per_second;
110 uint64_t other_per_second;
111 uint64_t kbytes_read_per_second;
112 uint64_t kbytes_written_per_second;
113 uint64_t read_pct_wait;
114 uint64_t write_pct_wait;
115 uint64_t all_pct_wait;
116 uint64_t resids_per_second;
119 void tape_get_updated_stats(void);
120 void tape_gather_initial_stats(void);
121 void tape_check_tapes_and_realloc(void);
122 int get_max_tape_drives(void);
123 void tape_uninitialise(void);
124 void tape_initialise(void);
125 void tape_calc_one_stats(struct calc_stats *, int);
126 void tape_write_headings(void);
127 void tape_write_stats(struct calc_stats *, int);
129 #endif /* _TAPESTAT_H */