xref: /dragonfly/sbin/hammer/hammer.c (revision d50f9ae3)
10dfeb6c8SMatthew Dillon /*
20dfeb6c8SMatthew Dillon  * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
30dfeb6c8SMatthew Dillon  *
40dfeb6c8SMatthew Dillon  * This code is derived from software contributed to The DragonFly Project
50dfeb6c8SMatthew Dillon  * by Matthew Dillon <dillon@backplane.com>
60dfeb6c8SMatthew Dillon  *
70dfeb6c8SMatthew Dillon  * Redistribution and use in source and binary forms, with or without
80dfeb6c8SMatthew Dillon  * modification, are permitted provided that the following conditions
90dfeb6c8SMatthew Dillon  * are met:
100dfeb6c8SMatthew Dillon  *
110dfeb6c8SMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
120dfeb6c8SMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
130dfeb6c8SMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
140dfeb6c8SMatthew Dillon  *    notice, this list of conditions and the following disclaimer in
150dfeb6c8SMatthew Dillon  *    the documentation and/or other materials provided with the
160dfeb6c8SMatthew Dillon  *    distribution.
170dfeb6c8SMatthew Dillon  * 3. Neither the name of The DragonFly Project nor the names of its
180dfeb6c8SMatthew Dillon  *    contributors may be used to endorse or promote products derived
190dfeb6c8SMatthew Dillon  *    from this software without specific, prior written permission.
200dfeb6c8SMatthew Dillon  *
210dfeb6c8SMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
220dfeb6c8SMatthew Dillon  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
230dfeb6c8SMatthew Dillon  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
240dfeb6c8SMatthew Dillon  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
250dfeb6c8SMatthew Dillon  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
260dfeb6c8SMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
270dfeb6c8SMatthew Dillon  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
280dfeb6c8SMatthew Dillon  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
290dfeb6c8SMatthew Dillon  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
300dfeb6c8SMatthew Dillon  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
310dfeb6c8SMatthew Dillon  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
320dfeb6c8SMatthew Dillon  * SUCH DAMAGE.
330dfeb6c8SMatthew Dillon  */
340dfeb6c8SMatthew Dillon 
35b45803e3STomohiro Kusumi #include "hammer.h"
36b45803e3STomohiro Kusumi 
3741ae0862STomohiro Kusumi #include <fstab.h>
3841ae0862STomohiro Kusumi 
39*94c6425eSSascha Wildner static __inline void hammer_parse_blkdevs(const char *blkdevs, int oflags);
4052e303feSTomohiro Kusumi static void __hammer_parse_blkdevs(const char *blkdevs, int oflags,
416f3c8414STomohiro Kusumi 		int verify_volume, int verify_count);
420006adaeSMatthew Dillon static void sigalrm(int signo);
43445faa69SMatthew Dillon static void sigintr(int signo);
448eff4093SSascha Wildner static void usage(int exit_code) __dead2;
450dfeb6c8SMatthew Dillon 
46d38ab092SMatthew Dillon int RecurseOpt;
47563b4845SMatthew Dillon int VerboseOpt;
48e95314deSMatthew Dillon int QuietOpt;
49243ca327SMatthew Dillon int TwoWayPipeOpt;
50243ca327SMatthew Dillon int TimeoutOpt;
5148eadef9SMatthew Dillon int DelayOpt = 5;
526c45ca3eSMatthew Dillon char *SshPort;
53b1f25588STomohiro Kusumi int ForceYesOpt;
543a998207SMatthew Dillon int CompressOpt;
55e7f926a5SMatthew Dillon int ForceOpt;
56445faa69SMatthew Dillon int RunningIoctl;
57445faa69SMatthew Dillon int DidInterrupt;
580bd7a37cSMatthew Dillon int BulkOpt;
595e1e1454STomohiro Kusumi int AllPFS;
6046137e17STomohiro Kusumi uint64_t BandwidthOpt;
6146137e17STomohiro Kusumi uint64_t SplitupOpt = 4ULL * 1024ULL * 1024ULL * 1024ULL;
6246137e17STomohiro Kusumi uint64_t MemoryLimit = 1024LLU * 1024 * 1024;
63b6ced256SMatthew Dillon const char *SplitupOptStr;
64d7ae405cSMatthew Dillon const char *CyclePath;
65d38ab092SMatthew Dillon 
660dfeb6c8SMatthew Dillon int
main(int ac,char ** av)670dfeb6c8SMatthew Dillon main(int ac, char **av)
680dfeb6c8SMatthew Dillon {
69d38ab092SMatthew Dillon 	char *blkdevs = NULL;
7048eadef9SMatthew Dillon 	char *ptr;
7169f5a58cSMatthew Dillon 	char *restrictcmd = NULL;
7248eadef9SMatthew Dillon 	int ch;
730dfeb6c8SMatthew Dillon 
74269cdd19SMatthew Dillon 	while ((ch = getopt(ac, av,
75fa581c8aSTomohiro Kusumi 			    "b:c:de:hf:i:m:p:qrt:v2yABC:FR:S:T:X")) != -1) {
760dfeb6c8SMatthew Dillon 		switch(ch) {
77243ca327SMatthew Dillon 		case '2':
78243ca327SMatthew Dillon 			TwoWayPipeOpt = 1;
79243ca327SMatthew Dillon 			break;
8007485271SMichael Neumann 		case 'y':
8107485271SMichael Neumann 			ForceYesOpt = 1;
8207485271SMichael Neumann 			break;
8348eadef9SMatthew Dillon 		case 'b':
8448eadef9SMatthew Dillon 			BandwidthOpt = strtoull(optarg, &ptr, 0);
8548eadef9SMatthew Dillon 			switch(*ptr) {
8648eadef9SMatthew Dillon 			case 'g':
8748eadef9SMatthew Dillon 			case 'G':
8848eadef9SMatthew Dillon 				BandwidthOpt *= 1024;
8948eadef9SMatthew Dillon 				/* fall through */
9048eadef9SMatthew Dillon 			case 'm':
9148eadef9SMatthew Dillon 			case 'M':
9248eadef9SMatthew Dillon 				BandwidthOpt *= 1024;
9348eadef9SMatthew Dillon 				/* fall through */
9448eadef9SMatthew Dillon 			case 'k':
9548eadef9SMatthew Dillon 			case 'K':
9648eadef9SMatthew Dillon 				BandwidthOpt *= 1024;
9748eadef9SMatthew Dillon 				break;
98224ac2f2SMatthew Dillon 			case '\0':
99224ac2f2SMatthew Dillon 				/* bytes per second if no suffix */
100224ac2f2SMatthew Dillon 				break;
10148eadef9SMatthew Dillon 			default:
10248eadef9SMatthew Dillon 				usage(1);
10388cdee70STomohiro Kusumi 				/* not reached */
10448eadef9SMatthew Dillon 			}
10548eadef9SMatthew Dillon 			break;
1063d7b2393SMatthew Dillon 		case 'S':
107b6ced256SMatthew Dillon 			SplitupOptStr = strdup(optarg);
1083d7b2393SMatthew Dillon 			SplitupOpt = strtoull(optarg, &ptr, 0);
1093d7b2393SMatthew Dillon 			switch(*ptr) {
1103d7b2393SMatthew Dillon 			case 'g':
1113d7b2393SMatthew Dillon 			case 'G':
1123d7b2393SMatthew Dillon 				SplitupOpt *= 1024;
1133d7b2393SMatthew Dillon 				/* fall through */
1143d7b2393SMatthew Dillon 			case 'm':
1153d7b2393SMatthew Dillon 			case 'M':
1163d7b2393SMatthew Dillon 				SplitupOpt *= 1024;
1173d7b2393SMatthew Dillon 				/* fall through */
1183d7b2393SMatthew Dillon 			case 'k':
1193d7b2393SMatthew Dillon 			case 'K':
1203d7b2393SMatthew Dillon 				SplitupOpt *= 1024;
1213d7b2393SMatthew Dillon 				break;
1223d7b2393SMatthew Dillon 			case '\0':
1233d7b2393SMatthew Dillon 				/* bytes per second if no suffix */
1243d7b2393SMatthew Dillon 				break;
1253d7b2393SMatthew Dillon 			default:
1263d7b2393SMatthew Dillon 				usage(1);
12788cdee70STomohiro Kusumi 				/* not reached */
1283d7b2393SMatthew Dillon 			}
1293d7b2393SMatthew Dillon 			break;
130d7ae405cSMatthew Dillon 		case 'c':
131d7ae405cSMatthew Dillon 			CyclePath = optarg;
132d7ae405cSMatthew Dillon 			break;
133ba7b52c9SMatthew Dillon 		case 'd':
134ba7b52c9SMatthew Dillon 			++DebugOpt;
135ba7b52c9SMatthew Dillon 			break;
136269cdd19SMatthew Dillon 		case 'e':
137269cdd19SMatthew Dillon 			ScoreBoardFile = optarg;
138269cdd19SMatthew Dillon 			break;
1390dfeb6c8SMatthew Dillon 		case 'h':
1400dfeb6c8SMatthew Dillon 			usage(0);
1410dfeb6c8SMatthew Dillon 			/* not reached */
14248eadef9SMatthew Dillon 		case 'i':
14348eadef9SMatthew Dillon 			DelayOpt = strtol(optarg, NULL, 0);
14448eadef9SMatthew Dillon 			break;
145fbe1c665SMatthew Dillon 		case 'm':
146fbe1c665SMatthew Dillon 			MemoryLimit = strtouq(optarg, &ptr, 0);
147fbe1c665SMatthew Dillon 			switch(*ptr) {
148fbe1c665SMatthew Dillon 			case 't':
149fbe1c665SMatthew Dillon 			case 'T':
150fbe1c665SMatthew Dillon 				MemoryLimit *= 1024;
151fbe1c665SMatthew Dillon 				/* fall through */
152fbe1c665SMatthew Dillon 			case 'g':
153fbe1c665SMatthew Dillon 			case 'G':
154fbe1c665SMatthew Dillon 				MemoryLimit *= 1024;
155fbe1c665SMatthew Dillon 				/* fall through */
156fbe1c665SMatthew Dillon 			case 'm':
157fbe1c665SMatthew Dillon 			case 'M':
158fbe1c665SMatthew Dillon 				MemoryLimit *= 1024;
159fbe1c665SMatthew Dillon 				/* fall through */
160fbe1c665SMatthew Dillon 			case 'k':
161fbe1c665SMatthew Dillon 			case 'K':
162fbe1c665SMatthew Dillon 				MemoryLimit *= 1024;
163fbe1c665SMatthew Dillon 				/* fall through */
164fbe1c665SMatthew Dillon 			default:
165fbe1c665SMatthew Dillon 				break;
166fbe1c665SMatthew Dillon 			}
167fbe1c665SMatthew Dillon 
168fbe1c665SMatthew Dillon 			/* minimum limit */
169fbe1c665SMatthew Dillon 			if (MemoryLimit < 1024 * 1024)
170fbe1c665SMatthew Dillon 				MemoryLimit = 1024 * 1024;
171fbe1c665SMatthew Dillon 			break;
1726c45ca3eSMatthew Dillon 		case 'p':
1736c45ca3eSMatthew Dillon 			SshPort = optarg;
1746c45ca3eSMatthew Dillon 			break;
175d38ab092SMatthew Dillon 		case 'r':
176d38ab092SMatthew Dillon 			RecurseOpt = 1;
177d38ab092SMatthew Dillon 			break;
178d38ab092SMatthew Dillon 		case 'f':
179d38ab092SMatthew Dillon 			blkdevs = optarg;
180d38ab092SMatthew Dillon 			break;
1810006adaeSMatthew Dillon 		case 't':
182243ca327SMatthew Dillon 			TimeoutOpt = strtol(optarg, NULL, 0);
1830006adaeSMatthew Dillon 			break;
184563b4845SMatthew Dillon 		case 'v':
185e95314deSMatthew Dillon 			if (QuietOpt > 0)
186e95314deSMatthew Dillon 				--QuietOpt;
187e95314deSMatthew Dillon 			else
188563b4845SMatthew Dillon 				++VerboseOpt;
189563b4845SMatthew Dillon 			break;
190e95314deSMatthew Dillon 		case 'q':
191e95314deSMatthew Dillon 			if (VerboseOpt > 0)
192e95314deSMatthew Dillon 				--VerboseOpt;
193e95314deSMatthew Dillon 			else
194e95314deSMatthew Dillon 				++QuietOpt;
195e95314deSMatthew Dillon 			break;
1965e1e1454STomohiro Kusumi 		case 'A':
1975e1e1454STomohiro Kusumi 			AllPFS = 1;
1985e1e1454STomohiro Kusumi 			break;
1990bd7a37cSMatthew Dillon 		case 'B':
2000bd7a37cSMatthew Dillon 			BulkOpt = 1;
2010bd7a37cSMatthew Dillon 			break;
2020faa08a1SMatthew Dillon 		case 'C':
20388cdee70STomohiro Kusumi 			if (hammer_parse_cache_size(optarg) == -1) {
2040faa08a1SMatthew Dillon 				usage(1);
20588cdee70STomohiro Kusumi 				/* not reached */
20688cdee70STomohiro Kusumi 			}
2070faa08a1SMatthew Dillon 			break;
208e7f926a5SMatthew Dillon 		case 'F':
209e7f926a5SMatthew Dillon 			ForceOpt = 1;
210e7f926a5SMatthew Dillon 			break;
21169f5a58cSMatthew Dillon 		case 'R':
21269f5a58cSMatthew Dillon 			if (restrictcmd == NULL)
21369f5a58cSMatthew Dillon 				restrictcmd = optarg;
21469f5a58cSMatthew Dillon 			break;
21569f5a58cSMatthew Dillon 		case 'T':
21669f5a58cSMatthew Dillon 			if (RestrictTarget == NULL)
21769f5a58cSMatthew Dillon 				RestrictTarget = optarg;
21869f5a58cSMatthew Dillon 			break;
2193a998207SMatthew Dillon 		case 'X':
2203a998207SMatthew Dillon 			CompressOpt = 1;
2213a998207SMatthew Dillon 			break;
2220dfeb6c8SMatthew Dillon 		default:
2230dfeb6c8SMatthew Dillon 			usage(1);
2240dfeb6c8SMatthew Dillon 			/* not reached */
2250dfeb6c8SMatthew Dillon 		}
2260dfeb6c8SMatthew Dillon 	}
2270dfeb6c8SMatthew Dillon 	ac -= optind;
2280dfeb6c8SMatthew Dillon 	av += optind;
2290dfeb6c8SMatthew Dillon 	if (ac < 1) {
2300dfeb6c8SMatthew Dillon 		usage(1);
2310dfeb6c8SMatthew Dillon 		/* not reached */
2320dfeb6c8SMatthew Dillon 	}
2330dfeb6c8SMatthew Dillon 
2340006adaeSMatthew Dillon 	signal(SIGALRM, sigalrm);
235445faa69SMatthew Dillon 	signal(SIGINT, sigintr);
2360006adaeSMatthew Dillon 
23769f5a58cSMatthew Dillon 	/*
23869f5a58cSMatthew Dillon 	 * Check command restriction (used by hammer ssh-remote).  Several
23969f5a58cSMatthew Dillon 	 * commands may be iterated with a comma.
24069f5a58cSMatthew Dillon 	 */
24169f5a58cSMatthew Dillon 	if (restrictcmd) {
24216712f18STomohiro Kusumi 		char *elm, *dup;
24369f5a58cSMatthew Dillon 
24416712f18STomohiro Kusumi 		dup = ptr = strdup(restrictcmd);
245f254e677STomohiro Kusumi 		while ((elm = strsep(&ptr, ",")) != NULL) {
24669f5a58cSMatthew Dillon 			if (strcmp(av[0], elm) == 0)
24769f5a58cSMatthew Dillon 				break;
248f254e677STomohiro Kusumi 		}
24973cca638STomohiro Kusumi 		if (elm == NULL) {
25002318f07STomohiro Kusumi 			errx(1, "hammer-remote: request does not match "
25102318f07STomohiro Kusumi 				"restricted command");
25273cca638STomohiro Kusumi 			/* not reached */
25373cca638STomohiro Kusumi 		}
25416712f18STomohiro Kusumi 		free(dup);
25569f5a58cSMatthew Dillon 	}
25669f5a58cSMatthew Dillon 
25781a213a5STomohiro Kusumi 	/*
25881a213a5STomohiro Kusumi 	 * Lookup the filesystem type
25981a213a5STomohiro Kusumi 	 */
2603cd578edSTomohiro Kusumi 	if (hammer_uuid_name_lookup(&Hammer_FSType, HAMMER_FSTYPE_STRING)) {
261f2458895STomohiro Kusumi 		errx(1, "uuids file does not have the DragonFly "
262f2458895STomohiro Kusumi 			"HAMMER filesystem type");
26373cca638STomohiro Kusumi 		/* not reached */
264f254e677STomohiro Kusumi 	}
265f2458895STomohiro Kusumi 
26669f5a58cSMatthew Dillon 	/*
26769f5a58cSMatthew Dillon 	 * Parse commands
26869f5a58cSMatthew Dillon 	 */
269367431cfSMatthew Dillon 	if (strcmp(av[0], "synctid") == 0) {
270367431cfSMatthew Dillon 		hammer_cmd_synctid(av + 1, ac - 1);
271367431cfSMatthew Dillon 		exit(0);
272367431cfSMatthew Dillon 	}
2735e435c92SMatthew Dillon 	if (strcmp(av[0], "namekey2") == 0) {
2745e435c92SMatthew Dillon 		int64_t key;
2755e435c92SMatthew Dillon 		int32_t crcx;
2765e435c92SMatthew Dillon 		int len;
2775e435c92SMatthew Dillon 		const char *aname = av[1];
2785e435c92SMatthew Dillon 
27988cdee70STomohiro Kusumi 		if (aname == NULL) {
2805e435c92SMatthew Dillon 			usage(1);
28188cdee70STomohiro Kusumi 			/* not reached */
28288cdee70STomohiro Kusumi 		}
2835e435c92SMatthew Dillon 		len = strlen(aname);
28446137e17STomohiro Kusumi 		key = (uint32_t)crc32(aname, len) & 0xFFFFFFFEU;
2855e435c92SMatthew Dillon 
2865e435c92SMatthew Dillon 		switch(len) {
2875e435c92SMatthew Dillon 		default:
2885e435c92SMatthew Dillon 			crcx = crc32(aname + 3, len - 5);
2895e435c92SMatthew Dillon 			crcx = crcx ^ (crcx >> 6) ^ (crcx >> 12);
2905e435c92SMatthew Dillon 			key |= (int64_t)(crcx & 0x3F) << 42;
2915e435c92SMatthew Dillon 			/* fall through */
2925e435c92SMatthew Dillon 		case 5:
2935e435c92SMatthew Dillon 		case 4:
2945e435c92SMatthew Dillon 			/* fall through */
2955e435c92SMatthew Dillon 		case 3:
2965e435c92SMatthew Dillon 			key |= ((int64_t)(aname[2] & 0x1F) << 48);
2975e435c92SMatthew Dillon 			/* fall through */
2985e435c92SMatthew Dillon 		case 2:
2995e435c92SMatthew Dillon 			key |= ((int64_t)(aname[1] & 0x1F) << 53) |
3005e435c92SMatthew Dillon 			       ((int64_t)(aname[len-2] & 0x1F) << 37);
3015e435c92SMatthew Dillon 			/* fall through */
3025e435c92SMatthew Dillon 		case 1:
3035e435c92SMatthew Dillon 			key |= ((int64_t)(aname[0] & 0x1F) << 58) |
3045e435c92SMatthew Dillon 			       ((int64_t)(aname[len-1] & 0x1F) << 32);
3055e435c92SMatthew Dillon 			/* fall through */
3065e435c92SMatthew Dillon 		case 0:
3075e435c92SMatthew Dillon 			break;
3085e435c92SMatthew Dillon 		}
3095e435c92SMatthew Dillon 		if (key == 0)
3105e435c92SMatthew Dillon 			key |= 0x100000000LL;
311a276dc6bSMatthew Dillon 		printf("0x%016jx\n", (uintmax_t)key);
3125e435c92SMatthew Dillon 		exit(0);
3135e435c92SMatthew Dillon 	}
3145e435c92SMatthew Dillon 	if (strcmp(av[0], "namekey1") == 0) {
315cbd800c2SMatthew Dillon 		int64_t key;
316cbd800c2SMatthew Dillon 
31788cdee70STomohiro Kusumi 		if (av[1] == NULL) {
318cbd800c2SMatthew Dillon 			usage(1);
31988cdee70STomohiro Kusumi 			/* not reached */
32088cdee70STomohiro Kusumi 		}
321cbd800c2SMatthew Dillon 		key = (int64_t)(crc32(av[1], strlen(av[1])) & 0x7FFFFFFF) << 32;
322cbd800c2SMatthew Dillon 		if (key == 0)
323cbd800c2SMatthew Dillon 			key |= 0x100000000LL;
324a276dc6bSMatthew Dillon 		printf("0x%016jx\n", (uintmax_t)key);
325cbd800c2SMatthew Dillon 		exit(0);
326cbd800c2SMatthew Dillon 	}
327cbd800c2SMatthew Dillon 	if (strcmp(av[0], "namekey32") == 0) {
328cbd800c2SMatthew Dillon 		int32_t key;
329cbd800c2SMatthew Dillon 
33088cdee70STomohiro Kusumi 		if (av[1] == NULL) {
331cbd800c2SMatthew Dillon 			usage(1);
33288cdee70STomohiro Kusumi 			/* not reached */
33388cdee70STomohiro Kusumi 		}
334cbd800c2SMatthew Dillon 		key = crc32(av[1], strlen(av[1])) & 0x7FFFFFFF;
335cbd800c2SMatthew Dillon 		if (key == 0)
336cbd800c2SMatthew Dillon 			++key;
337cbd800c2SMatthew Dillon 		printf("0x%08x\n", key);
338cbd800c2SMatthew Dillon 		exit(0);
339cbd800c2SMatthew Dillon 	}
34034ebae70SMatthew Dillon 	if (strcmp(av[0], "pfs-status") == 0) {
34134ebae70SMatthew Dillon 		hammer_cmd_pseudofs_status(av + 1, ac - 1);
34234ebae70SMatthew Dillon 		exit(0);
34334ebae70SMatthew Dillon 	}
344d4e5b69bSMatthew Dillon 	if (strcmp(av[0], "pfs-master") == 0) {
345d4e5b69bSMatthew Dillon 		hammer_cmd_pseudofs_create(av + 1, ac - 1, 0);
346d4e5b69bSMatthew Dillon 		exit(0);
347d4e5b69bSMatthew Dillon 	}
348d4e5b69bSMatthew Dillon 	if (strcmp(av[0], "pfs-slave") == 0) {
349d4e5b69bSMatthew Dillon 		hammer_cmd_pseudofs_create(av + 1, ac - 1, 1);
35034ebae70SMatthew Dillon 		exit(0);
35134ebae70SMatthew Dillon 	}
35234ebae70SMatthew Dillon 	if (strcmp(av[0], "pfs-update") == 0) {
353d4e5b69bSMatthew Dillon 		hammer_cmd_pseudofs_update(av + 1, ac - 1);
35466db8054SMatthew Dillon 		exit(0);
35566db8054SMatthew Dillon 	}
3569c67b4d2SMatthew Dillon 	if (strcmp(av[0], "pfs-upgrade") == 0) {
3579c67b4d2SMatthew Dillon 		hammer_cmd_pseudofs_upgrade(av + 1, ac - 1);
3589c67b4d2SMatthew Dillon 		exit(0);
3599c67b4d2SMatthew Dillon 	}
3609c67b4d2SMatthew Dillon 	if (strcmp(av[0], "pfs-downgrade") == 0) {
3619c67b4d2SMatthew Dillon 		hammer_cmd_pseudofs_downgrade(av + 1, ac - 1);
3629c67b4d2SMatthew Dillon 		exit(0);
3639c67b4d2SMatthew Dillon 	}
364243ca327SMatthew Dillon 	if (strcmp(av[0], "pfs-destroy") == 0) {
365243ca327SMatthew Dillon 		hammer_cmd_pseudofs_destroy(av + 1, ac - 1);
366243ca327SMatthew Dillon 		exit(0);
367243ca327SMatthew Dillon 	}
36813ce745dSMatthew Dillon 	if (strcmp(av[0], "prune") == 0) {
369b5aaba7fSMatthew Dillon 		hammer_cmd_softprune(av + 1, ac - 1, 0);
37013ce745dSMatthew Dillon 		exit(0);
37113ce745dSMatthew Dillon 	}
37291e559fdSTomohiro Kusumi 	if (strcmp(av[0], "prune-everything") == 0) {
37391e559fdSTomohiro Kusumi 		hammer_cmd_softprune(av + 1, ac - 1, 1);
37491e559fdSTomohiro Kusumi 		exit(0);
37591e559fdSTomohiro Kusumi 	}
37683f2a3aaSMatthew Dillon 	if (strcmp(av[0], "config") == 0) {
37783f2a3aaSMatthew Dillon 		hammer_cmd_config(av + 1, ac - 1);
37883f2a3aaSMatthew Dillon 		exit(0);
37983f2a3aaSMatthew Dillon 	}
38083f2a3aaSMatthew Dillon 	if (strcmp(av[0], "viconfig") == 0) {
38183f2a3aaSMatthew Dillon 		hammer_cmd_viconfig(av + 1, ac - 1);
38283f2a3aaSMatthew Dillon 		exit(0);
38383f2a3aaSMatthew Dillon 	}
3846a6e350fSMatthew Dillon 	if (strcmp(av[0], "cleanup") == 0) {
3856a6e350fSMatthew Dillon 		hammer_cmd_cleanup(av + 1, ac - 1);
3866a6e350fSMatthew Dillon 		exit(0);
3876a6e350fSMatthew Dillon 	}
388a360fddeSJohn Marino 	if (strcmp(av[0], "abort-cleanup") == 0) {
389a360fddeSJohn Marino 		hammer_cmd_abort_cleanup(av + 1, ac - 1);
390a360fddeSJohn Marino 		exit(0);
391a360fddeSJohn Marino 	}
392b66b9421SAntonio Huete 	if (strcmp(av[0], "info") == 0) {
39361630cfcSAntonio Huete Jimenez 		hammer_cmd_info(av + 1, ac - 1);
394b66b9421SAntonio Huete 		exit(0);
395b66b9421SAntonio Huete 	}
39669f5a58cSMatthew Dillon 	if (strcmp(av[0], "ssh-remote") == 0) {
39788cdee70STomohiro Kusumi 		if (ac != 3) {
39869f5a58cSMatthew Dillon 			usage(1);
39988cdee70STomohiro Kusumi 			/* not reached */
40088cdee70STomohiro Kusumi 		}
40169f5a58cSMatthew Dillon 		hammer_cmd_sshremote(av[1], av[2]);
40269f5a58cSMatthew Dillon 		exit(0);
40369f5a58cSMatthew Dillon 	}
40483f2a3aaSMatthew Dillon 	if (strcmp(av[0], "snap") == 0) {
40583f2a3aaSMatthew Dillon 		hammer_cmd_snap(av + 1, ac - 1, 0, 1);
40683f2a3aaSMatthew Dillon 		exit(0);
40783f2a3aaSMatthew Dillon 	}
40883f2a3aaSMatthew Dillon 	if (strcmp(av[0], "snaplo") == 0) {
40983f2a3aaSMatthew Dillon 		hammer_cmd_snap(av + 1, ac - 1, 0, 0);
41083f2a3aaSMatthew Dillon 		exit(0);
41183f2a3aaSMatthew Dillon 	}
41283f2a3aaSMatthew Dillon 	if (strcmp(av[0], "snapq") == 0) {
41383f2a3aaSMatthew Dillon 		hammer_cmd_snap(av + 1, ac - 1, 1, 0);
41483f2a3aaSMatthew Dillon 		exit(0);
41583f2a3aaSMatthew Dillon 	}
41683f2a3aaSMatthew Dillon 	if (strcmp(av[0], "snapls") == 0) {
41783f2a3aaSMatthew Dillon 		hammer_cmd_snapls(av + 1, ac - 1);
41883f2a3aaSMatthew Dillon 		exit(0);
41983f2a3aaSMatthew Dillon 	}
42083f2a3aaSMatthew Dillon 	if (strcmp(av[0], "snaprm") == 0) {
42183f2a3aaSMatthew Dillon 		hammer_cmd_snaprm(av + 1, ac - 1);
42283f2a3aaSMatthew Dillon 		exit(0);
42383f2a3aaSMatthew Dillon 	}
4246b669ab4SMichael Neumann 	if (strcmp(av[0], "snapshot") == 0) {
4256b669ab4SMichael Neumann 		hammer_cmd_snapshot(av + 1, ac - 1);
4266b669ab4SMichael Neumann 		exit(0);
4276b669ab4SMichael Neumann 	}
42868e079b8SMatthew Dillon 	if (strcmp(av[0], "bstats") == 0) {
42968e079b8SMatthew Dillon 		hammer_cmd_bstats(av + 1, ac - 1);
43068e079b8SMatthew Dillon 		exit(0);
43168e079b8SMatthew Dillon 	}
43268e079b8SMatthew Dillon 	if (strcmp(av[0], "iostats") == 0) {
43368e079b8SMatthew Dillon 		hammer_cmd_iostats(av + 1, ac - 1);
43468e079b8SMatthew Dillon 		exit(0);
43568e079b8SMatthew Dillon 	}
4363f760d89STomohiro Kusumi 	if (strcmp(av[0], "stats") == 0) {
4373f760d89STomohiro Kusumi 		hammer_cmd_stats(av + 1, ac - 1);
4383f760d89STomohiro Kusumi 		exit(0);
4393f760d89STomohiro Kusumi 	}
44013ce745dSMatthew Dillon 
44113ce745dSMatthew Dillon 	if (strncmp(av[0], "history", 7) == 0) {
44200b46268SAntonio Huete Jimenez 		hammer_cmd_history(av[0] + 7, av + 1, ac - 1);
44313ce745dSMatthew Dillon 		exit(0);
44413ce745dSMatthew Dillon 	}
445797a0b63SMatthew Dillon 	if (strcmp(av[0], "rebalance") == 0) {
446797a0b63SMatthew Dillon 		signal(SIGINT, sigalrm);
447797a0b63SMatthew Dillon 		hammer_cmd_rebalance(av + 1, ac - 1);
448797a0b63SMatthew Dillon 		exit(0);
449797a0b63SMatthew Dillon 	}
450ba7b52c9SMatthew Dillon 	if (strncmp(av[0], "reblock", 7) == 0) {
4516a6e350fSMatthew Dillon 		signal(SIGINT, sigalrm);
452ba7b52c9SMatthew Dillon 		if (strcmp(av[0], "reblock") == 0)
4530c4c331aSTomohiro Kusumi 			hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_FLAGS);
454ba7b52c9SMatthew Dillon 		else if (strcmp(av[0], "reblock-btree") == 0)
455ba7b52c9SMatthew Dillon 			hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_BTREE);
45658c17893SMatthew Dillon 		else if (strcmp(av[0], "reblock-inodes") == 0)
45758c17893SMatthew Dillon 			hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_INODES);
4589e29c876SMatthew Dillon 		else if (strcmp(av[0], "reblock-dirs") == 0)
4599e29c876SMatthew Dillon 			hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_DIRS);
460ba7b52c9SMatthew Dillon 		else if (strcmp(av[0], "reblock-data") == 0)
461ba7b52c9SMatthew Dillon 			hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_DATA);
46288cdee70STomohiro Kusumi 		else {
463ba7b52c9SMatthew Dillon 			usage(1);
46488cdee70STomohiro Kusumi 			/* not reached */
46588cdee70STomohiro Kusumi 		}
4663f673d5cSMatthew Dillon 		exit(0);
4673f673d5cSMatthew Dillon 	}
468a7fbbf91SMatthew Dillon 	if (strncmp(av[0], "mirror", 6) == 0) {
469a7fbbf91SMatthew Dillon 		if (strcmp(av[0], "mirror-read") == 0)
47048eadef9SMatthew Dillon 			hammer_cmd_mirror_read(av + 1, ac - 1, 0);
4717a27dae7SMatthew Dillon 		else if (strcmp(av[0], "mirror-read-stream") == 0)
47248eadef9SMatthew Dillon 			hammer_cmd_mirror_read(av + 1, ac - 1, 1);
473a7fbbf91SMatthew Dillon 		else if (strcmp(av[0], "mirror-write") == 0)
474a7fbbf91SMatthew Dillon 			hammer_cmd_mirror_write(av + 1, ac - 1);
475a7fbbf91SMatthew Dillon 		else if (strcmp(av[0], "mirror-copy") == 0)
47648eadef9SMatthew Dillon 			hammer_cmd_mirror_copy(av + 1, ac - 1, 0);
47748eadef9SMatthew Dillon 		else if (strcmp(av[0], "mirror-stream") == 0)
47848eadef9SMatthew Dillon 			hammer_cmd_mirror_copy(av + 1, ac - 1, 1);
479243ca327SMatthew Dillon 		else if (strcmp(av[0], "mirror-dump") == 0)
4809f1b0121SAntonio Huete Jimenez 			hammer_cmd_mirror_dump(av + 1, ac - 1);
48188cdee70STomohiro Kusumi 		else {
482a7fbbf91SMatthew Dillon 			usage(1);
48388cdee70STomohiro Kusumi 			/* not reached */
48488cdee70STomohiro Kusumi 		}
485a7fbbf91SMatthew Dillon 		exit(0);
486a7fbbf91SMatthew Dillon 	}
487bb29b5d8SMatthew Dillon 	if (strcmp(av[0], "dedup-simulate") == 0) {
488bb29b5d8SMatthew Dillon 		hammer_cmd_dedup_simulate(av + 1, ac - 1);
489bb29b5d8SMatthew Dillon 		exit(0);
490bb29b5d8SMatthew Dillon 	}
491bb29b5d8SMatthew Dillon 	if (strcmp(av[0], "dedup") == 0) {
492bb29b5d8SMatthew Dillon 		hammer_cmd_dedup(av + 1, ac - 1);
493bb29b5d8SMatthew Dillon 		exit(0);
494bb29b5d8SMatthew Dillon 	}
495de1c0b31SMatthew Dillon 	if (strcmp(av[0], "version") == 0) {
496de1c0b31SMatthew Dillon 		hammer_cmd_get_version(av + 1, ac - 1);
497de1c0b31SMatthew Dillon 		exit(0);
498de1c0b31SMatthew Dillon 	}
499de1c0b31SMatthew Dillon 	if (strcmp(av[0], "version-upgrade") == 0) {
500de1c0b31SMatthew Dillon 		hammer_cmd_set_version(av + 1, ac - 1);
501de1c0b31SMatthew Dillon 		exit(0);
502de1c0b31SMatthew Dillon 	}
503d121f61cSMichael Neumann 	if (strcmp(av[0], "volume-add") == 0) {
504d121f61cSMichael Neumann 		hammer_cmd_volume_add(av + 1, ac - 1);
505e27700cfSMichael Neumann 		exit(0);
506e27700cfSMichael Neumann 	}
507865c9609SMichael Neumann 	if (strcmp(av[0], "volume-del") == 0) {
508865c9609SMichael Neumann 		hammer_cmd_volume_del(av + 1, ac - 1);
509865c9609SMichael Neumann 		exit(0);
510865c9609SMichael Neumann 	}
511e914c91dSStathis Kamperis 	if (strcmp(av[0], "volume-list") == 0) {
51256c2f4d6STomohiro Kusumi 		hammer_cmd_volume_list(av + 1, ac - 1);
513b45632fbSTomohiro Kusumi 		exit(0);
514b45632fbSTomohiro Kusumi 	}
515b45632fbSTomohiro Kusumi 	if (strcmp(av[0], "volume-blkdevs") == 0) {
51656c2f4d6STomohiro Kusumi 		hammer_cmd_volume_blkdevs(av + 1, ac - 1);
517e914c91dSStathis Kamperis 		exit(0);
518e914c91dSStathis Kamperis 	}
51961aeeb33SMatthew Dillon 
520d38ab092SMatthew Dillon 	if (strcmp(av[0], "show") == 0) {
521913b6663STomohiro Kusumi 		const char *arg = NULL;
52216712f18STomohiro Kusumi 		char *p, *dup;
523c6121c98STomohiro Kusumi 		int filter = -1;
524337ec5f8STomohiro Kusumi 		int obfuscate = 0;
525db7212b1STomohiro Kusumi 		int indent = 0;
52661aeeb33SMatthew Dillon 
52752e303feSTomohiro Kusumi 		hammer_parse_blkdevs(blkdevs, O_RDONLY);
52873cca638STomohiro Kusumi 		if (ac > 3) {
529db7212b1STomohiro Kusumi 			errx(1, "Too many options specified");
53073cca638STomohiro Kusumi 			/* not reached */
53173cca638STomohiro Kusumi 		}
532d38ab092SMatthew Dillon 		if (ac > 1)
533913b6663STomohiro Kusumi 			arg = av[1];
534c6121c98STomohiro Kusumi 		if (ac > 2) {
53516712f18STomohiro Kusumi 			dup = ptr = strdup(av[2]);
53616712f18STomohiro Kusumi 			while ((p = strsep(&ptr, ",")) != NULL) {
53752e2f1b5STomohiro Kusumi 				if (strcmp(p, "filter") == 0)
538c6121c98STomohiro Kusumi 					filter = 1;
53952e2f1b5STomohiro Kusumi 				else if (strcmp(p, "nofilter") == 0)
540c6121c98STomohiro Kusumi 					filter = 0;
54152e2f1b5STomohiro Kusumi 				else if (strcmp(p, "obfuscate") == 0)
542337ec5f8STomohiro Kusumi 					obfuscate = 1;
54352e2f1b5STomohiro Kusumi 				else if (strcmp(p, "indent") == 0)
544db7212b1STomohiro Kusumi 					indent = 1;
545337ec5f8STomohiro Kusumi 			}
54616712f18STomohiro Kusumi 			free(dup);
547db7212b1STomohiro Kusumi 		}
548db7212b1STomohiro Kusumi 		hammer_cmd_show(arg, filter, obfuscate, indent);
549d38ab092SMatthew Dillon 		exit(0);
550d38ab092SMatthew Dillon 	}
5516aec797fSMatthew Dillon 	if (strcmp(av[0], "show-undo") == 0) {
55252e303feSTomohiro Kusumi 		hammer_parse_blkdevs(blkdevs, O_RDONLY);
5536aec797fSMatthew Dillon 		hammer_cmd_show_undo();
5546aec797fSMatthew Dillon 		exit(0);
5556aec797fSMatthew Dillon 	}
556b9107f58SMatthew Dillon 	if (strcmp(av[0], "recover") == 0) {
55752e303feSTomohiro Kusumi 		__hammer_parse_blkdevs(blkdevs, O_RDONLY, 0, 1);
558e819b271STomohiro Kusumi 		hammer_cmd_recover(av + 1, ac - 1);
559b9107f58SMatthew Dillon 		exit(0);
560b9107f58SMatthew Dillon 	}
561eb3f8f1fSMatthew Dillon 	if (strcmp(av[0], "blockmap") == 0) {
56252e303feSTomohiro Kusumi 		hammer_parse_blkdevs(blkdevs, O_RDONLY);
563eb3f8f1fSMatthew Dillon 		hammer_cmd_blockmap();
564eb3f8f1fSMatthew Dillon 		exit(0);
565eb3f8f1fSMatthew Dillon 	}
5666ed4c886SMatthew Dillon 	if (strcmp(av[0], "checkmap") == 0) {
56752e303feSTomohiro Kusumi 		hammer_parse_blkdevs(blkdevs, O_RDONLY);
5686ed4c886SMatthew Dillon 		hammer_cmd_checkmap();
5696ed4c886SMatthew Dillon 		exit(0);
5706ed4c886SMatthew Dillon 	}
5712eccaef5STomohiro Kusumi 	if (strcmp(av[0], "strip") == 0) {
57252e303feSTomohiro Kusumi 		__hammer_parse_blkdevs(blkdevs, O_RDWR, 0, 0);
5732eccaef5STomohiro Kusumi 		hammer_cmd_strip();
5742eccaef5STomohiro Kusumi 		exit(0);
5752eccaef5STomohiro Kusumi 	}
5762eccaef5STomohiro Kusumi 
5770dfeb6c8SMatthew Dillon 	usage(1);
5780dfeb6c8SMatthew Dillon 	/* not reached */
5790dfeb6c8SMatthew Dillon 	return(0);
5800dfeb6c8SMatthew Dillon }
5810dfeb6c8SMatthew Dillon 
5829c9ac2f1SMatthew Dillon /*
5839c9ac2f1SMatthew Dillon  * Parse the device specification.
5849c9ac2f1SMatthew Dillon  *
5859c9ac2f1SMatthew Dillon  * Multi-volume hammer devices are colon-separated.  Each element
5869c9ac2f1SMatthew Dillon  * may be further expanded via /etc/devtab.  One may also specify
5879c9ac2f1SMatthew Dillon  * a single element which is expanded into multiple elements via
5889c9ac2f1SMatthew Dillon  * /etc/devtab.
5899c9ac2f1SMatthew Dillon  */
5900dfeb6c8SMatthew Dillon static
5910dfeb6c8SMatthew Dillon void
__hammer_parse_blkdevs(const char * blkdevs,int oflags,int verify_volume,int verify_count)59252e303feSTomohiro Kusumi __hammer_parse_blkdevs(const char *blkdevs, int oflags, int verify_volume,
5936f3c8414STomohiro Kusumi 	int verify_count)
594d38ab092SMatthew Dillon {
5952dba5fa7STomohiro Kusumi 	volume_info_t volume = NULL;
596d38ab092SMatthew Dillon 	char *copy;
597d38ab092SMatthew Dillon 	char *volname;
5986f3c8414STomohiro Kusumi 	int vol_count = 0;
599d38ab092SMatthew Dillon 
600f254e677STomohiro Kusumi 	if (blkdevs == NULL) {
601f6532f03SThomas Nikolajsen 		errx(1, "A -f blkdevs specification is required "
602d38ab092SMatthew Dillon 			"for this command");
60373cca638STomohiro Kusumi 		/* not reached */
604f254e677STomohiro Kusumi 	}
605d38ab092SMatthew Dillon 
606d38ab092SMatthew Dillon 	copy = strdup(blkdevs);
607d38ab092SMatthew Dillon 	while ((volname = copy) != NULL) {
608d38ab092SMatthew Dillon 		if ((copy = strchr(copy, ':')) != NULL)
609d38ab092SMatthew Dillon 			*copy++ = 0;
6109c9ac2f1SMatthew Dillon 		volname = getdevpath(volname, 0);
6114c09d9c4SMatthew Dillon 		if (strchr(volname, ':')) {
61252e303feSTomohiro Kusumi 			__hammer_parse_blkdevs(volname, oflags, verify_volume,
6136f3c8414STomohiro Kusumi 				verify_count);
6144c09d9c4SMatthew Dillon 		} else {
6156f3c8414STomohiro Kusumi 			volume = load_volume(volname, oflags, verify_volume);
6165ebff42aSTomohiro Kusumi 			assert(volume);
6176f3c8414STomohiro Kusumi 			++vol_count;
6189c56653bSTomohiro Kusumi 		}
6198e99b497STomohiro Kusumi 		free(volname);
620d38ab092SMatthew Dillon 	}
6218e99b497STomohiro Kusumi 	free(copy);
6229c56653bSTomohiro Kusumi 
6235ebff42aSTomohiro Kusumi 	assert(volume);
6246f3c8414STomohiro Kusumi 	if (verify_count) {
6256f3c8414STomohiro Kusumi 		if (vol_count != volume->ondisk->vol_count) {
62691ad3f6fSTomohiro Kusumi 			errx(1, "Volume header says %d volumes, but %d specified.",
6276f3c8414STomohiro Kusumi 				volume->ondisk->vol_count, vol_count);
62873cca638STomohiro Kusumi 			/* not reached */
62973cca638STomohiro Kusumi 		}
63073cca638STomohiro Kusumi 		if (get_root_volume() == NULL) {
63142700c9dSTomohiro Kusumi 			errx(1, "No root volume found");
63273cca638STomohiro Kusumi 			/* not reached */
63373cca638STomohiro Kusumi 		}
634d38ab092SMatthew Dillon 	}
6356f3c8414STomohiro Kusumi }
636d38ab092SMatthew Dillon 
637c2b74c42STomohiro Kusumi static __inline
638c2b74c42STomohiro Kusumi void
hammer_parse_blkdevs(const char * blkdevs,int oflags)63952e303feSTomohiro Kusumi hammer_parse_blkdevs(const char *blkdevs, int oflags)
640c2b74c42STomohiro Kusumi {
64152e303feSTomohiro Kusumi 	__hammer_parse_blkdevs(blkdevs, oflags, 1, 1);
642c2b74c42STomohiro Kusumi }
643c2b74c42STomohiro Kusumi 
644d38ab092SMatthew Dillon static
645d38ab092SMatthew Dillon void
sigalrm(int signo __unused)6460006adaeSMatthew Dillon sigalrm(int signo __unused)
6470006adaeSMatthew Dillon {
6480006adaeSMatthew Dillon 	/* do nothing (interrupts HAMMER ioctl) */
6490006adaeSMatthew Dillon }
6500006adaeSMatthew Dillon 
6510006adaeSMatthew Dillon static
6520006adaeSMatthew Dillon void
sigintr(int signo __unused)653445faa69SMatthew Dillon sigintr(int signo __unused)
654445faa69SMatthew Dillon {
655445faa69SMatthew Dillon 	if (RunningIoctl == 0)
656445faa69SMatthew Dillon 		_exit(1);
657445faa69SMatthew Dillon 	DidInterrupt = 1;
658445faa69SMatthew Dillon 	/* do nothing (interrupts HAMMER ioctl) */
659445faa69SMatthew Dillon }
660445faa69SMatthew Dillon 
661445faa69SMatthew Dillon static
662445faa69SMatthew Dillon void
usage(int exit_code)6630dfeb6c8SMatthew Dillon usage(int exit_code)
6640dfeb6c8SMatthew Dillon {
6650dfeb6c8SMatthew Dillon 	fprintf(stderr,
6660dfeb6c8SMatthew Dillon 		"hammer -h\n"
667dda14c07STomohiro Kusumi 		"hammer [-2ABFqrvXy] [-b bandwidth] [-C cachesize[:readahead]] \n"
668dda14c07STomohiro Kusumi 		"       [-R restrictcmd] [-T restrictpath] [-c cyclefile]\n"
669dda14c07STomohiro Kusumi 		"       [-e scoreboardfile] [-f blkdevs] [-i delay] [-p ssh-port]\n"
670dda14c07STomohiro Kusumi 		"       [-S splitsize] [-t seconds] [-m memlimit] command [argument ...]\n"
67184082922SThomas Nikolajsen 		"hammer synctid <filesystem> [quick]\n"
67284082922SThomas Nikolajsen 		"hammer bstats [interval]\n"
67384082922SThomas Nikolajsen 		"hammer iostats [interval]\n"
6747b431e68STomohiro Kusumi 		"hammer stats [interval]\n"
675bb8e52c0SThomas Nikolajsen 		"hammer history[@offset[,len]] <file> ...\n"
6765e435c92SMatthew Dillon 		"hammer namekey1 <path>\n"
6775e435c92SMatthew Dillon 		"hammer namekey2 <path>\n"
6784567021bSThomas Nikolajsen 		"hammer namekey32 <path>\n"
679bb8e52c0SThomas Nikolajsen 		"hammer cleanup [<filesystem> ...]\n"
680a360fddeSJohn Marino 		"hammer abort-cleanup\n"
6818a03ae8aSAntonio Huete Jimenez 		"hammer info [<dirpath> ...]\n"
682bb8e52c0SThomas Nikolajsen 		"hammer snapshot [<filesystem>] <snapshot-dir>\n"
68316265794SThomas Nikolajsen 		"hammer snapshot <filesystem> <snapshot-dir> [<note>]\n"
684bb8e52c0SThomas Nikolajsen 		"hammer prune <softlink-dir>\n"
685bb8e52c0SThomas Nikolajsen 		"hammer prune-everything <filesystem>\n"
686797a0b63SMatthew Dillon 		"hammer rebalance <filesystem> [saturation_percentage]\n"
6874567021bSThomas Nikolajsen 		"hammer reblock[-btree|-inodes|-dirs|-data] "
68884082922SThomas Nikolajsen 			"<filesystem> [fill_percentage]\n"
68934bb69d8SThomas Nikolajsen 		"hammer pfs-status <dirpath> ...\n"
690d4e5b69bSMatthew Dillon 		"hammer pfs-master <dirpath> [options]\n"
691d4e5b69bSMatthew Dillon 		"hammer pfs-slave <dirpath> [options]\n"
69234ebae70SMatthew Dillon 		"hammer pfs-update <dirpath> [options]\n"
6939c67b4d2SMatthew Dillon 		"hammer pfs-upgrade <dirpath>\n"
6949c67b4d2SMatthew Dillon 		"hammer pfs-downgrade <dirpath>\n"
6959c67b4d2SMatthew Dillon 		"hammer pfs-destroy <dirpath>\n"
696bb8e52c0SThomas Nikolajsen 		"hammer mirror-read <filesystem> [begin-tid]\n"
697bb8e52c0SThomas Nikolajsen 		"hammer mirror-read-stream <filesystem> [begin-tid]\n"
698bb8e52c0SThomas Nikolajsen 		"hammer mirror-write <filesystem>\n"
6999f1b0121SAntonio Huete Jimenez 		"hammer mirror-dump [header]\n"
700bb8e52c0SThomas Nikolajsen 		"hammer mirror-copy [[user@]host:]<filesystem>"
701bb8e52c0SThomas Nikolajsen 				  " [[user@]host:]<filesystem>\n"
702bb8e52c0SThomas Nikolajsen 		"hammer mirror-stream [[user@]host:]<filesystem>"
703bb8e52c0SThomas Nikolajsen 				    " [[user@]host:]<filesystem>\n"
70469f5a58cSMatthew Dillon 		"hammer ssh-remote command filesystem\n"
7055e435c92SMatthew Dillon 		"hammer version <filesystem>\n"
7064567021bSThomas Nikolajsen 		"hammer version-upgrade <filesystem> <version> [force]\n"
707d121f61cSMichael Neumann 		"hammer volume-add <device> <filesystem>\n"
708865c9609SMichael Neumann 		"hammer volume-del <device> <filesystem>\n"
709e914c91dSStathis Kamperis 		"hammer volume-list <filesystem>\n"
710b45632fbSTomohiro Kusumi 		"hammer volume-blkdevs <filesystem>\n"
7110dfeb6c8SMatthew Dillon 	);
71283f2a3aaSMatthew Dillon 
713f6532f03SThomas Nikolajsen 	fprintf(stderr, "\nHAMMER utility version 3+ commands:\n");
71483f2a3aaSMatthew Dillon 
71583f2a3aaSMatthew Dillon 	fprintf(stderr,
71683f2a3aaSMatthew Dillon 		"hammer config [<filesystem> [<configfile>]]\n"
71783f2a3aaSMatthew Dillon 		"hammer viconfig [<filesystem>]\n"
718f6532f03SThomas Nikolajsen 		"hammer snap <path> [<note>]\n"
719f6532f03SThomas Nikolajsen 		"hammer snaplo <path> [<note>]\n"
720f6532f03SThomas Nikolajsen 		"hammer snapq <dir> [<note>]\n"
721aaf93065SThomas Nikolajsen 		"hammer snaprm <path> ...\n"
722aaf93065SThomas Nikolajsen 		"hammer snaprm <transid> ...\n"
723aaf93065SThomas Nikolajsen 		"hammer snaprm <filesystem> <transid> ...\n"
724f6532f03SThomas Nikolajsen 		"hammer snapls [<path> ...]\n"
725f6532f03SThomas Nikolajsen 	);
726f6532f03SThomas Nikolajsen 
727f6532f03SThomas Nikolajsen 	fprintf(stderr, "\nHAMMER utility version 4+ commands:\n");
728f6532f03SThomas Nikolajsen 
729f6532f03SThomas Nikolajsen 	fprintf(stderr,
730c71cab34SMatthew Dillon 		"hammer -f blkdevs blockmap\n"
731c71cab34SMatthew Dillon 		"hammer -f blkdevs checkmap\n"
732c71cab34SMatthew Dillon 		"hammer -f blkdevs [-qqq] show [lo:objid]\n"
733f6532f03SThomas Nikolajsen 		"hammer -f blkdevs show-undo\n"
7343d900665STomohiro Kusumi 		"hammer -f blkdevs recover <target_dir> [full|quick]\n"
7352eccaef5STomohiro Kusumi 		"hammer -f blkdevs strip\n"
73683f2a3aaSMatthew Dillon 	);
73783f2a3aaSMatthew Dillon 
738bb29b5d8SMatthew Dillon 	fprintf(stderr, "\nHAMMER utility version 5+ commands:\n");
739bb29b5d8SMatthew Dillon 
740bb29b5d8SMatthew Dillon 	fprintf(stderr,
741bb29b5d8SMatthew Dillon 		"hammer dedup-simulate <filesystem>\n"
742bb29b5d8SMatthew Dillon 		"hammer dedup <filesystem>\n"
743bb29b5d8SMatthew Dillon 	);
744bb29b5d8SMatthew Dillon 
7450dfeb6c8SMatthew Dillon 	exit(exit_code);
7460dfeb6c8SMatthew Dillon }
747d38ab092SMatthew Dillon 
748