kernel/nata: Extract ad_get_geometry().
[dragonfly.git] / sbin / hammer / cmd_stats.c
blobd2758965ec259abca4706acc40c9f9dd02dc452b
1 /*
2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
34 * $DragonFly: src/sbin/hammer/cmd_stats.c,v 1.3 2008/07/14 20:28:07 dillon Exp $
37 #include "hammer.h"
39 #include <sys/sysctl.h>
40 #include <math.h>
42 static void loaddelay(struct timespec *ts, const char *arg);
44 #define _HAMMER "vfs.hammer.stats_"
45 #define bstats_title \
46 " lookups searches inserts deletes elements splits iterations rootiters reciters"
47 #define iostats_title \
48 " f_read f_write d_read d_write i_flushes commits undo redo"
51 * Taken from sys/vfs/hammer/hammer_vfsops.c
53 struct btree_stats {
54 int64_t btree_lookups;
55 int64_t btree_searches;
56 int64_t btree_inserts;
57 int64_t btree_deletes;
58 int64_t btree_elements;
59 int64_t btree_splits;
60 int64_t btree_iterations;
61 int64_t btree_root_iterations;
62 int64_t record_iterations;
65 struct io_stats {
66 int64_t file_read;
67 int64_t file_write;
68 int64_t disk_read;
69 int64_t disk_write;
70 int64_t inode_flushes;
71 int64_t commits;
72 int64_t undo;
73 int64_t redo;
76 static __inline __always_inline
77 int
78 _sysctl(const char *name, int64_t *p)
80 size_t len = sizeof(*p);
81 return(sysctlbyname(name, p, &len, NULL, 0));
84 static __inline __always_inline
85 void
86 collect_bstats(struct btree_stats *p)
88 /* sysctls must exist, so ignore return values */
89 _sysctl(_HAMMER"btree_lookups", &p->btree_lookups);
90 _sysctl(_HAMMER"btree_searches", &p->btree_searches);
91 _sysctl(_HAMMER"btree_inserts", &p->btree_inserts);
92 _sysctl(_HAMMER"btree_deletes", &p->btree_deletes);
93 _sysctl(_HAMMER"btree_elements", &p->btree_elements);
94 _sysctl(_HAMMER"btree_splits", &p->btree_splits);
95 _sysctl(_HAMMER"btree_iterations", &p->btree_iterations);
96 _sysctl(_HAMMER"btree_root_iterations", &p->btree_root_iterations);
97 _sysctl(_HAMMER"record_iterations", &p->record_iterations);
100 static __inline __always_inline
101 void
102 collect_iostats(struct io_stats *p)
104 /* sysctls must exist, so ignore return values */
105 _sysctl(_HAMMER"file_read", &p->file_read);
106 _sysctl(_HAMMER"file_write", &p->file_write);
107 _sysctl(_HAMMER"disk_read", &p->disk_read);
108 _sysctl(_HAMMER"disk_write", &p->disk_write);
109 _sysctl(_HAMMER"inode_flushes", &p->inode_flushes);
110 _sysctl(_HAMMER"commits", &p->commits);
111 _sysctl(_HAMMER"undo", &p->undo);
112 _sysctl(_HAMMER"redo", &p->redo);
115 static __inline __always_inline
116 void
117 print_bstats(const struct btree_stats *p1, const struct btree_stats *p2)
119 printf("%10jd %10jd %10jd %10jd %10jd %10jd %10jd %10jd %10jd",
120 (intmax_t)(p1->btree_lookups - p2->btree_lookups),
121 (intmax_t)(p1->btree_searches - p2->btree_searches),
122 (intmax_t)(p1->btree_inserts - p2->btree_inserts),
123 (intmax_t)(p1->btree_deletes - p2->btree_deletes),
124 (intmax_t)(p1->btree_elements - p2->btree_elements),
125 (intmax_t)(p1->btree_splits - p2->btree_splits),
126 (intmax_t)(p1->btree_iterations - p2->btree_iterations),
127 (intmax_t)(p1->btree_root_iterations - p2->btree_root_iterations),
128 (intmax_t)(p1->record_iterations - p2->record_iterations));
129 /* no trailing \n */
132 static __inline __always_inline
133 void
134 print_iostats(const struct io_stats *p1, const struct io_stats *p2)
136 printf("%9jd %9jd %9jd %9jd %9jd %9jd %9jd %9jd",
137 (intmax_t)(p1->file_read - p2->file_read),
138 (intmax_t)(p1->file_write - p2->file_write),
139 (intmax_t)(p1->disk_read - p2->disk_read),
140 (intmax_t)(p1->disk_write - p2->disk_write),
141 (intmax_t)(p1->inode_flushes - p2->inode_flushes),
142 (intmax_t)(p1->commits - p2->commits),
143 (intmax_t)(p1->undo - p2->undo),
144 (intmax_t)(p1->redo - p2->redo));
145 /* no trailing \n */
148 void
149 hammer_cmd_bstats(char **av, int ac)
151 struct btree_stats st1, st2;
152 struct timespec delay = {1, 0};
153 int count;
155 bzero(&st1, sizeof(st1));
156 bzero(&st2, sizeof(st2));
158 if (ac > 0)
159 loaddelay(&delay, av[0]);
161 for (count = 0; ; ++count) {
162 collect_bstats(&st1);
163 if (count) {
164 if ((count & 15) == 1)
165 printf(bstats_title"\n");
166 print_bstats(&st1, &st2);
167 printf("\n");
169 bcopy(&st1, &st2, sizeof(st2));
170 nanosleep(&delay, NULL);
174 void
175 hammer_cmd_iostats(char **av, int ac)
177 struct io_stats st1, st2;
178 struct timespec delay = {1, 0};
179 int count;
181 bzero(&st1, sizeof(st1));
182 bzero(&st2, sizeof(st2));
184 if (ac > 0)
185 loaddelay(&delay, av[0]);
187 for (count = 0; ; ++count) {
188 collect_iostats(&st1);
189 if (count) {
190 if ((count & 15) == 1)
191 printf(iostats_title"\n");
192 print_iostats(&st1, &st2);
193 printf("\n");
195 bcopy(&st1, &st2, sizeof(st2));
196 nanosleep(&delay, NULL);
200 void
201 hammer_cmd_stats(char **av, int ac)
203 struct btree_stats bst1, bst2;
204 struct io_stats ist1, ist2;
205 struct timespec delay = {1, 0};
206 int count;
208 bzero(&bst1, sizeof(bst1));
209 bzero(&bst2, sizeof(bst2));
210 bzero(&ist1, sizeof(ist1));
211 bzero(&ist2, sizeof(ist2));
213 if (ac > 0)
214 loaddelay(&delay, av[0]);
216 for (count = 0; ; ++count) {
217 collect_bstats(&bst1);
218 collect_iostats(&ist1);
219 if (count) {
220 if ((count & 15) == 1)
221 printf(bstats_title"\t"iostats_title"\n");
222 print_bstats(&bst1, &bst2);
223 printf("\t");
224 print_iostats(&ist1, &ist2);
225 printf("\n");
227 bcopy(&bst1, &bst2, sizeof(bst2));
228 bcopy(&ist1, &ist2, sizeof(ist2));
229 nanosleep(&delay, NULL);
234 * Convert a delay string (e.g. "0.1") into a timespec.
236 static
237 void
238 loaddelay(struct timespec *ts, const char *arg)
240 double d;
242 d = strtod(arg, NULL);
243 if (d < 0.001)
244 d = 0.001;
245 ts->tv_sec = (int)d;
246 ts->tv_nsec = (int)(modf(d, &d) * 1000000000.0);