2 * Copyright (c) 2007 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/hammer.c,v 1.24 2008/06/23 21:31:56 dillon Exp $
41 static void hammer_parsetime(u_int64_t
*tidp
, const char *timestr
);
42 static void hammer_parsedevs(const char *blkdevs
);
43 static void sigalrm(int signo
);
44 static void usage(int exit_code
);
49 const char *CyclePath
;
53 main(int ac
, char **av
)
62 while ((ch
= getopt(ac
, av
, "c:dhf:rs:t:v")) != -1) {
83 timeout
= strtol(optarg
, NULL
, 0);
101 signal(SIGALRM
, sigalrm
);
105 if (strcmp(av
[0], "now") == 0) {
106 tid
= (hammer_tid_t
)time(NULL
) * 1000000000LLU;
107 printf("0x%08x\n", (int)(tid
/ 1000000000LL));
110 if (strcmp(av
[0], "now64") == 0) {
111 gettimeofday(&tv
, NULL
);
112 tid
= (hammer_tid_t
)tv
.tv_sec
* 1000000000LLU +
113 tv
.tv_usec
* 1000LLU;
114 printf("0x%016llx\n", tid
);
117 if (strcmp(av
[0], "synctid") == 0) {
118 hammer_cmd_synctid(av
+ 1, ac
- 1);
121 if (strcmp(av
[0], "stamp") == 0) {
124 hammer_parsetime(&tid
, av
[1]);
125 printf("0x%08x\n", (int)(tid
/ 1000000000LL));
128 if (strcmp(av
[0], "stamp64") == 0) {
131 hammer_parsetime(&tid
, av
[1]);
132 printf("0x%016llx\n", tid
);
135 if (strcmp(av
[0], "date") == 0) {
140 tid
= strtoull(av
[1], NULL
, 16);
141 if (tid
>= 0x100000000LLU
)
142 tid
/= 1000000000LLU;
144 printf("%s", ctime(&t
));
147 if (strcmp(av
[0], "namekey") == 0) {
152 key
= (int64_t)(crc32(av
[1], strlen(av
[1])) & 0x7FFFFFFF) << 32;
154 key
|= 0x100000000LL
;
155 printf("0x%016llx\n", key
);
158 if (strcmp(av
[0], "namekey32") == 0) {
163 key
= crc32(av
[1], strlen(av
[1])) & 0x7FFFFFFF;
166 printf("0x%08x\n", key
);
169 if (strcmp(av
[0], "pseudofs") == 0) {
170 hammer_cmd_pseudofs(av
+ 1, ac
- 1);
173 if (strcmp(av
[0], "prune") == 0) {
174 hammer_cmd_softprune(av
+ 1, ac
- 1, 0);
177 if (strcmp(av
[0], "prune-everything") == 0) {
178 hammer_cmd_softprune(av
+ 1, ac
- 1, 1);
181 if (strcmp(av
[0], "bstats") == 0) {
182 hammer_cmd_bstats(av
+ 1, ac
- 1);
185 if (strcmp(av
[0], "iostats") == 0) {
186 hammer_cmd_iostats(av
+ 1, ac
- 1);
190 if (strncmp(av
[0], "history", 7) == 0) {
191 hammer_cmd_history(av
[0] + 7, av
+ 1, ac
- 1);
194 if (strncmp(av
[0], "reblock", 7) == 0) {
195 if (strcmp(av
[0], "reblock") == 0)
196 hammer_cmd_reblock(av
+ 1, ac
- 1, -1);
197 else if (strcmp(av
[0], "reblock-btree") == 0)
198 hammer_cmd_reblock(av
+ 1, ac
- 1, HAMMER_IOC_DO_BTREE
);
199 else if (strcmp(av
[0], "reblock-inodes") == 0)
200 hammer_cmd_reblock(av
+ 1, ac
- 1, HAMMER_IOC_DO_INODES
);
201 else if (strcmp(av
[0], "reblock-dirs") == 0)
202 hammer_cmd_reblock(av
+ 1, ac
- 1, HAMMER_IOC_DO_DIRS
);
203 else if (strcmp(av
[0], "reblock-data") == 0)
204 hammer_cmd_reblock(av
+ 1, ac
- 1, HAMMER_IOC_DO_DATA
);
210 uuid_name_lookup(&Hammer_FSType
, "DragonFly HAMMER", &status
);
211 if (status
!= uuid_s_ok
) {
212 errx(1, "uuids file does not have the DragonFly "
213 "HAMMER filesystem type");
216 if (strcmp(av
[0], "show") == 0) {
217 hammer_off_t node_offset
= (hammer_off_t
)-1;
219 hammer_parsedevs(blkdevs
);
221 sscanf(av
[1], "%llx", &node_offset
);
222 hammer_cmd_show(node_offset
, 0, NULL
, NULL
);
225 if (strcmp(av
[0], "blockmap") == 0) {
226 hammer_parsedevs(blkdevs
);
227 hammer_cmd_blockmap();
236 * Parse a timestamp for the mount point
243 hammer_parsetime(u_int64_t
*tidp
, const char *timestr
)
250 gettimeofday(&tv
, NULL
);
255 if (isalpha(timestr
[strlen(timestr
)-1])) {
256 if (sscanf(timestr
, "%d%c", &n
, &c
) != 2)
284 localtime_r(&tv
.tv_sec
, &tm
);
285 seconds
= (double)tm
.tm_sec
;
288 n
= sscanf(timestr
, "%4d%2d%2d:%2d%2d%lf",
289 &tm
.tm_year
, &tm
.tm_mon
, &tm
.tm_mday
,
290 &tm
.tm_hour
, &tm
.tm_min
, &seconds
);
293 /* if [:hhmmss] is omitted, assume :000000.0 */
295 tm
.tm_hour
= tm
.tm_min
= tm
.tm_sec
= 0;
297 tm
.tm_sec
= (int)seconds
;
298 tv
.tv_sec
= mktime(&tm
);
299 tv
.tv_usec
= (int)((seconds
- floor(seconds
)) * 1000000.0);
301 *tidp
= (u_int64_t
)tv
.tv_sec
* 1000000000LLU +
302 tv
.tv_usec
* 1000LLU;
307 hammer_parsedevs(const char *blkdevs
)
312 if (blkdevs
== NULL
) {
313 errx(1, "A -f blkdevs specification is required "
317 copy
= strdup(blkdevs
);
318 while ((volname
= copy
) != NULL
) {
319 if ((copy
= strchr(copy
, ':')) != NULL
)
321 setup_volume(-1, volname
, 0, O_RDONLY
);
327 sigalrm(int signo __unused
)
329 /* do nothing (interrupts HAMMER ioctl) */
338 "hammer [-x] now[64]\n"
339 "hammer [-t timeout] [-c cyclefile] ....\n"
340 "hammer stamp[64] <time>\n"
341 "hammer prune <softlink-dir>\n"
342 "hammer prune-everything <filesystem>\n"
343 "hammer bstats <interval>\n"
344 "hammer iostats <interval>\n"
345 "hammer reblock <filesystem> [compact%%] (default 90%%)\n"
346 "hammer pseudofs <dirpath>\n"
347 "hammer history[@offset[,len]] <file-1>...<file-N>\n"
348 "hammer -f blkdevs [-r] show\n"
349 "hammer -f blkdevs blockmap\n"
351 fprintf(stderr
, "time: +n[s/m/h/D/M/Y]\n"
352 "time: yyyymmdd[:hhmmss]\n"
353 "modulo_time: n{s,m,h,d,M,y}\n");