Commit | Line | Data |
---|---|---|
dbb8d92d AB |
1 | /* |
2 | * blktrace output analysis: generate a timeline & gather statistics | |
3 | * | |
4 | * (C) Copyright 2009 Hewlett-Packard Development Company, L.P. | |
5 | * Alan D. Brunelle (alan.brunelle@hp.com) | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | * | |
21 | */ | |
22 | #include "globals.h" | |
23 | ||
24 | struct files { | |
25 | FILE *fp; | |
26 | char *nm; | |
27 | }; | |
28 | ||
29 | struct rstat { | |
30 | struct list_head head; | |
31 | struct files files[2]; | |
32 | unsigned long long ios, nblks; | |
33 | long long base_sec; | |
34 | }; | |
35 | ||
36 | static struct rstat *sys_info; | |
37 | static LIST_HEAD(rstats); | |
38 | ||
39 | static int do_open(struct files *fip, char *bn, char *pn) | |
40 | { | |
6abaea7a | 41 | fip->nm = malloc(strlen(bn) + 16); |
dbb8d92d AB |
42 | sprintf(fip->nm, "%s_%s.dat", bn, pn); |
43 | ||
44 | fip->fp = my_fopen(fip->nm, "w"); | |
45 | if (fip->fp) { | |
46 | add_file(fip->fp, fip->nm); | |
47 | return 0; | |
48 | } | |
49 | ||
50 | free(fip->nm); | |
51 | return -1; | |
52 | } | |
53 | ||
a155ab98 | 54 | static int init_rsip(struct rstat *rsip, struct d_info *dip) |
dbb8d92d | 55 | { |
a155ab98 AB |
56 | char *nm = dip ? dip->dip_name : "sys"; |
57 | ||
6abaea7a | 58 | rsip->base_sec = -1; |
dbb8d92d | 59 | rsip->ios = rsip->nblks = 0; |
a155ab98 AB |
60 | if (do_open(&rsip->files[0], nm, "iops_fp") || |
61 | do_open(&rsip->files[1], nm, "mbps_fp")) | |
dbb8d92d AB |
62 | return -1; |
63 | ||
64 | list_add_tail(&rsip->head, &rstats); | |
65 | return 0; | |
66 | } | |
67 | ||
68 | static void rstat_emit(struct rstat *rsip, double cur) | |
69 | { | |
70 | double mbps; | |
71 | ||
72 | /* | |
73 | * I/Os per second is easy: just the ios | |
74 | */ | |
75 | fprintf(rsip->files[0].fp, "%lld %llu\n", rsip->base_sec, rsip->ios); | |
76 | ||
77 | /* | |
78 | * MB/s we convert blocks to mb... | |
79 | */ | |
80 | mbps = ((double)rsip->nblks * 512.0) / (1024.0 * 1024.0); | |
81 | fprintf(rsip->files[1].fp, "%lld %lf\n", rsip->base_sec, mbps); | |
82 | ||
83 | rsip->base_sec = (unsigned long long)cur; | |
84 | rsip->ios = rsip->nblks = 0; | |
85 | } | |
86 | ||
87 | static void __add(struct rstat *rsip, double cur, unsigned long long nblks) | |
88 | { | |
89 | if (rsip->base_sec < 0) | |
90 | rsip->base_sec = (long long)cur; | |
91 | else if (((long long)cur - rsip->base_sec) >= 1) | |
92 | rstat_emit(rsip, cur); | |
93 | ||
94 | rsip->ios++; | |
95 | rsip->nblks += nblks; | |
96 | } | |
97 | ||
a155ab98 | 98 | void *rstat_alloc(struct d_info *dip) |
dbb8d92d AB |
99 | { |
100 | struct rstat *rsip = malloc(sizeof(*rsip)); | |
101 | ||
a155ab98 | 102 | if (!init_rsip(rsip, dip)) |
dbb8d92d AB |
103 | return rsip; |
104 | ||
105 | free(rsip); | |
106 | return NULL; | |
107 | } | |
108 | ||
109 | void rstat_free(void *ptr) | |
110 | { | |
111 | struct rstat *rsip = ptr; | |
112 | ||
113 | rstat_emit(rsip, last_t_seen); | |
114 | list_del(&rsip->head); | |
115 | free(rsip); | |
116 | } | |
117 | ||
118 | void rstat_add(void *ptr, double cur, unsigned long long nblks) | |
119 | { | |
120 | if (ptr != NULL) | |
121 | __add((struct rstat *)ptr, cur, nblks); | |
122 | __add(sys_info, cur, nblks); | |
123 | } | |
124 | ||
125 | int rstat_init(void) | |
126 | { | |
a155ab98 | 127 | sys_info = rstat_alloc(NULL); |
dbb8d92d AB |
128 | return sys_info != NULL; |
129 | } | |
130 | ||
131 | void rstat_exit(void) | |
132 | { | |
133 | struct list_head *p, *q; | |
134 | ||
135 | list_for_each_safe(p, q, &rstats) { | |
136 | struct rstat *rsip = list_entry(p, struct rstat, head); | |
137 | rstat_free(rsip); | |
138 | } | |
139 | } |