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
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
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
34 * $DragonFly: src/sbin/hammer/cmd_stats.c,v 1.3 2008/07/14 20:28:07 dillon Exp $
39 #include <sys/sysctl.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
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
;
60 int64_t btree_iterations
;
61 int64_t btree_root_iterations
;
62 int64_t record_iterations
;
70 int64_t inode_flushes
;
76 static __inline __always_inline
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
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
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
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
));
132 static __inline __always_inline
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
));
149 hammer_cmd_bstats(char **av
, int ac
)
151 struct btree_stats st1
, st2
;
152 struct timespec delay
= {1, 0};
155 bzero(&st1
, sizeof(st1
));
156 bzero(&st2
, sizeof(st2
));
159 loaddelay(&delay
, av
[0]);
161 for (count
= 0; ; ++count
) {
162 collect_bstats(&st1
);
164 if ((count
& 15) == 1)
165 printf(bstats_title
"\n");
166 print_bstats(&st1
, &st2
);
169 bcopy(&st1
, &st2
, sizeof(st2
));
170 nanosleep(&delay
, NULL
);
175 hammer_cmd_iostats(char **av
, int ac
)
177 struct io_stats st1
, st2
;
178 struct timespec delay
= {1, 0};
181 bzero(&st1
, sizeof(st1
));
182 bzero(&st2
, sizeof(st2
));
185 loaddelay(&delay
, av
[0]);
187 for (count
= 0; ; ++count
) {
188 collect_iostats(&st1
);
190 if ((count
& 15) == 1)
191 printf(iostats_title
"\n");
192 print_iostats(&st1
, &st2
);
195 bcopy(&st1
, &st2
, sizeof(st2
));
196 nanosleep(&delay
, NULL
);
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};
208 bzero(&bst1
, sizeof(bst1
));
209 bzero(&bst2
, sizeof(bst2
));
210 bzero(&ist1
, sizeof(ist1
));
211 bzero(&ist2
, sizeof(ist2
));
214 loaddelay(&delay
, av
[0]);
216 for (count
= 0; ; ++count
) {
217 collect_bstats(&bst1
);
218 collect_iostats(&ist1
);
220 if ((count
& 15) == 1)
221 printf(bstats_title
"\t"iostats_title
"\n");
222 print_bstats(&bst1
, &bst2
);
224 print_iostats(&ist1
, &ist2
);
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.
238 loaddelay(struct timespec
*ts
, const char *arg
)
242 d
= strtod(arg
, NULL
);
246 ts
->tv_nsec
= (int)(modf(d
, &d
) * 1000000000.0);