]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/gstat/gstat.c
This commit was generated by cvs2svn to compensate for changes in r156373,
[FreeBSD/FreeBSD.git] / usr.sbin / gstat / gstat.c
1 /*-
2  * Copyright (c) 2003 Poul-Henning Kamp
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The names of the authors may not be used to endorse or promote
14  *    products derived from this software without specific prior written
15  *    permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31
32
33 #include <stdio.h>
34 #include <stdint.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <paths.h>
38 #include <curses.h>
39 #include <unistd.h>
40 #include <fcntl.h>
41 #include <errno.h>
42 #include <err.h>
43 #include <sys/mman.h>
44 #include <sys/time.h>
45 #include <libgeom.h>
46 #include <sys/resource.h>
47 #include <devstat.h>
48 #include <sys/devicestat.h>
49
50 static int flag_a, flag_c, flag_d;
51 static int flag_I = 500000;
52
53 static void usage(void);
54
55 int
56 main(int argc, char **argv)
57 {
58         int error, i, quit;
59         struct devstat *gsp, *gsq;
60         void *sp, *sq;
61         double dt;
62         struct timespec tp, tq;
63         struct gmesh gmp;
64         struct gprovider *pp;
65         struct gconsumer *cp;
66         struct gident *gid;
67         short cf, cb;
68         char *p;
69         long double ld[11];
70         uint64_t u64;
71
72         while ((i = getopt(argc, argv, "adcI:")) != -1) {
73                 switch (i) {
74                 case 'a':
75                         flag_a = 1;
76                         break;
77                 case 'c':
78                         flag_c = 1;
79                         break;
80                 case 'd':
81                         flag_d = 1;
82                         break;
83                 case 'I':
84                         p = NULL;
85                         i = strtoul(optarg, &p, 0);
86                         if (p == optarg || errno == EINVAL ||
87                             errno == ERANGE) {
88                                 errx(1, "Invalid argument to -I");
89                         } else if (!strcmp(p, "s"))
90                                 i *= 1000000;
91                         else if (!strcmp(p, "ms"))
92                                 i *= 1000;
93                         else if (!strcmp(p, "us"))
94                                 i *= 1;
95                         flag_I = i;
96                         break;
97                 case '?':
98                 default:
99                         usage();
100                 }
101         }
102         argc -= optind;
103         argv += optind;
104         if (argc != 0)
105                 usage();
106
107         i = geom_gettree(&gmp);
108         if (i != 0)
109                 err(1, "geom_gettree = %d", i);
110         error = geom_stats_open();
111         if (error)
112                 err(1, "geom_stats_open()");
113         sq = NULL;
114         sq = geom_stats_snapshot_get();
115         if (sq == NULL)
116                 err(1, "geom_stats_snapshot()");
117         initscr();
118         start_color();
119         use_default_colors();
120         pair_content(0, &cf, &cb);
121         init_pair(1, COLOR_GREEN, cb);
122         init_pair(2, COLOR_MAGENTA, cb);
123         init_pair(3, COLOR_RED, cb);
124         cbreak();
125         noecho();
126         nonl();
127         nodelay(stdscr, 1);
128         intrflush(stdscr, FALSE);
129         keypad(stdscr, TRUE);
130         geom_stats_snapshot_timestamp(sq, &tq);
131         for (quit = 0; !quit;) {
132                 sp = geom_stats_snapshot_get();
133                 if (sp == NULL)
134                         err(1, "geom_stats_snapshot()");
135                 geom_stats_snapshot_timestamp(sp, &tp);
136                 dt = tp.tv_sec - tq.tv_sec;
137                 dt += (tp.tv_nsec - tq.tv_nsec) * 1e-9;
138                 tq = tp;
139         
140                 geom_stats_snapshot_reset(sp);
141                 geom_stats_snapshot_reset(sq);
142                 move(0,0);
143                 printw("dT: %5.3f  flag_I %dus  sizeof %d  i %d\n",
144                     dt, flag_I, sizeof(*gsp), i);
145                 printw(" L(q)  ops/s   ");
146                 printw(" r/s   kBps   ms/r   ");
147                 printw(" w/s   kBps   ms/w   ");
148                 if (flag_d)
149                         printw(" d/s   kBps   ms/d   ");
150                 printw("%%busy Name\n");
151                 for (;;) {
152                         gsp = geom_stats_snapshot_next(sp);
153                         gsq = geom_stats_snapshot_next(sq);
154                         if (gsp == NULL || gsq == NULL)
155                                 break;
156                         if (gsp->id == NULL)
157                                 continue;
158                         gid = geom_lookupid(&gmp, gsp->id);
159                         if (gid == NULL) {
160                                 geom_deletetree(&gmp);
161                                 i = geom_gettree(&gmp);
162                                 if (i != 0)
163                                         err(1, "geom_gettree = %d", i);
164                                 gid = geom_lookupid(&gmp, gsp->id);
165                         }
166                         if (gid == NULL)
167                                 continue;
168                         if (gid != NULL && gid->lg_what == ISCONSUMER &&
169                             !flag_c)
170                                 continue;
171                         if (gsp->sequence0 != gsp->sequence1) {
172                                 printw("*\n");
173                                 continue;
174                         }
175                         devstat_compute_statistics(gsp, gsq, dt, 
176                             DSM_QUEUE_LENGTH, &u64,
177                             DSM_TRANSFERS_PER_SECOND, &ld[0],
178
179                             DSM_TRANSFERS_PER_SECOND_READ, &ld[1],
180                             DSM_MB_PER_SECOND_READ, &ld[2],
181                             DSM_MS_PER_TRANSACTION_READ, &ld[3],
182
183                             DSM_TRANSFERS_PER_SECOND_WRITE, &ld[4],
184                             DSM_MB_PER_SECOND_WRITE, &ld[5],
185                             DSM_MS_PER_TRANSACTION_WRITE, &ld[6],
186
187                             DSM_BUSY_PCT, &ld[7],
188                             DSM_TRANSFERS_PER_SECOND_FREE, &ld[8],
189                             DSM_MB_PER_SECOND_FREE, &ld[9],
190                             DSM_MS_PER_TRANSACTION_FREE, &ld[10],
191                             DSM_NONE);
192
193                         if (flag_a && ld[7] < 0.1) {
194                                 *gsq = *gsp;
195                                 continue;
196                         }
197
198                         printw(" %4ju", (uintmax_t)u64);
199                         printw(" %6.0f", (double)ld[0]);
200                         printw(" %6.0f", (double)ld[1]);
201                         printw(" %6.0f", (double)ld[2] * 1024);
202                         printw(" %6.1f", (double)ld[3]);
203                         printw(" %6.0f", (double)ld[4]);
204                         printw(" %6.0f", (double)ld[5] * 1024);
205                         printw(" %6.1f", (double)ld[6]);
206
207                         if (flag_d) {
208                                 printw(" %6.0f", (double)ld[8]);
209                                 printw(" %6.0f", (double)ld[9] * 1024);
210                                 printw(" %6.1f", (double)ld[10]);
211                         }
212
213                         if (ld[7] > 80)
214                                 i = 3;
215                         else if (ld[7] > 50)
216                                 i = 2;
217                         else 
218                                 i = 1;
219                         attron(COLOR_PAIR(i));
220                         printw(" %6.1lf", (double)ld[7]);
221                         attroff(COLOR_PAIR(i));
222                         printw("|");
223                         if (gid == NULL) {
224                                 printw(" ??");
225                         } else if (gid->lg_what == ISPROVIDER) {
226                                 pp = gid->lg_ptr;
227                                 printw(" %s", pp->lg_name);
228                         } else if (gid->lg_what == ISCONSUMER) {
229                                 cp = gid->lg_ptr;
230                                 printw(" %s/%s/%s",
231                                     cp->lg_geom->lg_class->lg_name,
232                                     cp->lg_geom->lg_name,
233                                     cp->lg_provider->lg_name);
234                         }
235                         clrtoeol();
236                         printw("\n");
237                         *gsq = *gsp;
238                 }
239                 geom_stats_snapshot_free(sp);
240                 clrtobot();
241                 refresh();
242                 usleep(flag_I);
243                 i = getch();
244                 switch (i) {
245                 case '>':
246                         flag_I *= 2;
247                         break;
248                 case '<':
249                         flag_I /= 2;
250                         if (flag_I < 1000)
251                                 flag_I = 1000;
252                         break;
253                 case 'c':
254                         flag_c = !flag_c;
255                         break;
256                 case 'q':
257                         quit = 1;
258                         break;
259                 default:
260                         break;
261                 }
262         }
263
264         endwin();
265         exit (0);
266 }
267
268 static void
269 usage(void)
270 {
271         fprintf(stderr, "usage: gstat [-acd] [-I interval]\n");
272         exit(1);
273         /* NOTREACHED */
274 }