Commit | Line | Data |
---|---|---|
0dfeb6c8 MD |
1 | /* |
2 | * Copyright (c) 2007 The DragonFly Project. All rights reserved. | |
84e57c2c | 3 | * |
0dfeb6c8 MD |
4 | * This code is derived from software contributed to The DragonFly Project |
5 | * by Matthew Dillon <dillon@backplane.com> | |
84e57c2c | 6 | * |
0dfeb6c8 MD |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
84e57c2c | 10 | * |
0dfeb6c8 MD |
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. | |
84e57c2c | 20 | * |
0dfeb6c8 MD |
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. | |
0dfeb6c8 MD |
33 | */ |
34 | ||
b45803e3 TK |
35 | #include "hammer.h" |
36 | ||
41ae0862 TK |
37 | #include <fstab.h> |
38 | ||
94c6425e | 39 | static __inline void hammer_parse_blkdevs(const char *blkdevs, int oflags); |
52e303fe | 40 | static void __hammer_parse_blkdevs(const char *blkdevs, int oflags, |
6f3c8414 | 41 | int verify_volume, int verify_count); |
0006adae | 42 | static void sigalrm(int signo); |
445faa69 | 43 | static void sigintr(int signo); |
8eff4093 | 44 | static void usage(int exit_code) __dead2; |
0dfeb6c8 | 45 | |
d38ab092 | 46 | int RecurseOpt; |
563b4845 | 47 | int VerboseOpt; |
e95314de | 48 | int QuietOpt; |
243ca327 MD |
49 | int TwoWayPipeOpt; |
50 | int TimeoutOpt; | |
48eadef9 | 51 | int DelayOpt = 5; |
6c45ca3e | 52 | char *SshPort; |
b1f25588 | 53 | int ForceYesOpt; |
3a998207 | 54 | int CompressOpt; |
e7f926a5 | 55 | int ForceOpt; |
445faa69 MD |
56 | int RunningIoctl; |
57 | int DidInterrupt; | |
0bd7a37c | 58 | int BulkOpt; |
5e1e1454 | 59 | int AllPFS; |
46137e17 TK |
60 | uint64_t BandwidthOpt; |
61 | uint64_t SplitupOpt = 4ULL * 1024ULL * 1024ULL * 1024ULL; | |
62 | uint64_t MemoryLimit = 1024LLU * 1024 * 1024; | |
b6ced256 | 63 | const char *SplitupOptStr; |
d7ae405c | 64 | const char *CyclePath; |
d38ab092 | 65 | |
0dfeb6c8 MD |
66 | int |
67 | main(int ac, char **av) | |
68 | { | |
d38ab092 | 69 | char *blkdevs = NULL; |
48eadef9 | 70 | char *ptr; |
69f5a58c | 71 | char *restrictcmd = NULL; |
48eadef9 | 72 | int ch; |
0dfeb6c8 | 73 | |
269cdd19 | 74 | while ((ch = getopt(ac, av, |
fa581c8a | 75 | "b:c:de:hf:i:m:p:qrt:v2yABC:FR:S:T:X")) != -1) { |
0dfeb6c8 | 76 | switch(ch) { |
243ca327 MD |
77 | case '2': |
78 | TwoWayPipeOpt = 1; | |
79 | break; | |
07485271 MN |
80 | case 'y': |
81 | ForceYesOpt = 1; | |
82 | break; | |
48eadef9 MD |
83 | case 'b': |
84 | BandwidthOpt = strtoull(optarg, &ptr, 0); | |
85 | switch(*ptr) { | |
86 | case 'g': | |
87 | case 'G': | |
88 | BandwidthOpt *= 1024; | |
89 | /* fall through */ | |
90 | case 'm': | |
91 | case 'M': | |
92 | BandwidthOpt *= 1024; | |
93 | /* fall through */ | |
94 | case 'k': | |
95 | case 'K': | |
96 | BandwidthOpt *= 1024; | |
97 | break; | |
224ac2f2 MD |
98 | case '\0': |
99 | /* bytes per second if no suffix */ | |
100 | break; | |
48eadef9 MD |
101 | default: |
102 | usage(1); | |
88cdee70 | 103 | /* not reached */ |
48eadef9 MD |
104 | } |
105 | break; | |
3d7b2393 | 106 | case 'S': |
b6ced256 | 107 | SplitupOptStr = strdup(optarg); |
3d7b2393 MD |
108 | SplitupOpt = strtoull(optarg, &ptr, 0); |
109 | switch(*ptr) { | |
110 | case 'g': | |
111 | case 'G': | |
112 | SplitupOpt *= 1024; | |
113 | /* fall through */ | |
114 | case 'm': | |
115 | case 'M': | |
116 | SplitupOpt *= 1024; | |
117 | /* fall through */ | |
118 | case 'k': | |
119 | case 'K': | |
120 | SplitupOpt *= 1024; | |
121 | break; | |
122 | case '\0': | |
123 | /* bytes per second if no suffix */ | |
124 | break; | |
125 | default: | |
126 | usage(1); | |
88cdee70 | 127 | /* not reached */ |
3d7b2393 MD |
128 | } |
129 | break; | |
d7ae405c MD |
130 | case 'c': |
131 | CyclePath = optarg; | |
132 | break; | |
ba7b52c9 MD |
133 | case 'd': |
134 | ++DebugOpt; | |
135 | break; | |
269cdd19 MD |
136 | case 'e': |
137 | ScoreBoardFile = optarg; | |
138 | break; | |
0dfeb6c8 MD |
139 | case 'h': |
140 | usage(0); | |
141 | /* not reached */ | |
48eadef9 MD |
142 | case 'i': |
143 | DelayOpt = strtol(optarg, NULL, 0); | |
144 | break; | |
fbe1c665 MD |
145 | case 'm': |
146 | MemoryLimit = strtouq(optarg, &ptr, 0); | |
147 | switch(*ptr) { | |
148 | case 't': | |
149 | case 'T': | |
150 | MemoryLimit *= 1024; | |
151 | /* fall through */ | |
152 | case 'g': | |
153 | case 'G': | |
154 | MemoryLimit *= 1024; | |
155 | /* fall through */ | |
156 | case 'm': | |
157 | case 'M': | |
158 | MemoryLimit *= 1024; | |
159 | /* fall through */ | |
160 | case 'k': | |
161 | case 'K': | |
162 | MemoryLimit *= 1024; | |
163 | /* fall through */ | |
164 | default: | |
165 | break; | |
166 | } | |
167 | ||
168 | /* minimum limit */ | |
169 | if (MemoryLimit < 1024 * 1024) | |
170 | MemoryLimit = 1024 * 1024; | |
171 | break; | |
6c45ca3e MD |
172 | case 'p': |
173 | SshPort = optarg; | |
174 | break; | |
d38ab092 MD |
175 | case 'r': |
176 | RecurseOpt = 1; | |
177 | break; | |
178 | case 'f': | |
179 | blkdevs = optarg; | |
180 | break; | |
0006adae | 181 | case 't': |
243ca327 | 182 | TimeoutOpt = strtol(optarg, NULL, 0); |
0006adae | 183 | break; |
563b4845 | 184 | case 'v': |
e95314de MD |
185 | if (QuietOpt > 0) |
186 | --QuietOpt; | |
187 | else | |
188 | ++VerboseOpt; | |
189 | break; | |
190 | case 'q': | |
191 | if (VerboseOpt > 0) | |
192 | --VerboseOpt; | |
193 | else | |
194 | ++QuietOpt; | |
563b4845 | 195 | break; |
5e1e1454 TK |
196 | case 'A': |
197 | AllPFS = 1; | |
198 | break; | |
0bd7a37c MD |
199 | case 'B': |
200 | BulkOpt = 1; | |
201 | break; | |
0faa08a1 | 202 | case 'C': |
88cdee70 | 203 | if (hammer_parse_cache_size(optarg) == -1) { |
0faa08a1 | 204 | usage(1); |
88cdee70 TK |
205 | /* not reached */ |
206 | } | |
0faa08a1 | 207 | break; |
e7f926a5 MD |
208 | case 'F': |
209 | ForceOpt = 1; | |
210 | break; | |
69f5a58c MD |
211 | case 'R': |
212 | if (restrictcmd == NULL) | |
213 | restrictcmd = optarg; | |
214 | break; | |
215 | case 'T': | |
216 | if (RestrictTarget == NULL) | |
217 | RestrictTarget = optarg; | |
218 | break; | |
3a998207 MD |
219 | case 'X': |
220 | CompressOpt = 1; | |
221 | break; | |
0dfeb6c8 MD |
222 | default: |
223 | usage(1); | |
224 | /* not reached */ | |
225 | } | |
226 | } | |
227 | ac -= optind; | |
228 | av += optind; | |
229 | if (ac < 1) { | |
230 | usage(1); | |
231 | /* not reached */ | |
232 | } | |
233 | ||
243ca327 | 234 | signal(SIGALRM, sigalrm); |
445faa69 | 235 | signal(SIGINT, sigintr); |
0006adae | 236 | |
69f5a58c MD |
237 | /* |
238 | * Check command restriction (used by hammer ssh-remote). Several | |
239 | * commands may be iterated with a comma. | |
240 | */ | |
241 | if (restrictcmd) { | |
16712f18 | 242 | char *elm, *dup; |
69f5a58c | 243 | |
16712f18 | 244 | dup = ptr = strdup(restrictcmd); |
f254e677 | 245 | while ((elm = strsep(&ptr, ",")) != NULL) { |
69f5a58c MD |
246 | if (strcmp(av[0], elm) == 0) |
247 | break; | |
f254e677 | 248 | } |
73cca638 | 249 | if (elm == NULL) { |
02318f07 TK |
250 | errx(1, "hammer-remote: request does not match " |
251 | "restricted command"); | |
73cca638 TK |
252 | /* not reached */ |
253 | } | |
16712f18 | 254 | free(dup); |
69f5a58c MD |
255 | } |
256 | ||
81a213a5 TK |
257 | /* |
258 | * Lookup the filesystem type | |
259 | */ | |
3cd578ed | 260 | if (hammer_uuid_name_lookup(&Hammer_FSType, HAMMER_FSTYPE_STRING)) { |
f2458895 TK |
261 | errx(1, "uuids file does not have the DragonFly " |
262 | "HAMMER filesystem type"); | |
73cca638 | 263 | /* not reached */ |
f254e677 | 264 | } |
f2458895 | 265 | |
69f5a58c MD |
266 | /* |
267 | * Parse commands | |
268 | */ | |
367431cf MD |
269 | if (strcmp(av[0], "synctid") == 0) { |
270 | hammer_cmd_synctid(av + 1, ac - 1); | |
271 | exit(0); | |
272 | } | |
5e435c92 MD |
273 | if (strcmp(av[0], "namekey2") == 0) { |
274 | int64_t key; | |
275 | int32_t crcx; | |
276 | int len; | |
277 | const char *aname = av[1]; | |
278 | ||
88cdee70 | 279 | if (aname == NULL) { |
5e435c92 | 280 | usage(1); |
88cdee70 TK |
281 | /* not reached */ |
282 | } | |
5e435c92 | 283 | len = strlen(aname); |
46137e17 | 284 | key = (uint32_t)crc32(aname, len) & 0xFFFFFFFEU; |
5e435c92 MD |
285 | |
286 | switch(len) { | |
287 | default: | |
288 | crcx = crc32(aname + 3, len - 5); | |
289 | crcx = crcx ^ (crcx >> 6) ^ (crcx >> 12); | |
290 | key |= (int64_t)(crcx & 0x3F) << 42; | |
291 | /* fall through */ | |
292 | case 5: | |
293 | case 4: | |
294 | /* fall through */ | |
295 | case 3: | |
296 | key |= ((int64_t)(aname[2] & 0x1F) << 48); | |
297 | /* fall through */ | |
298 | case 2: | |
299 | key |= ((int64_t)(aname[1] & 0x1F) << 53) | | |
300 | ((int64_t)(aname[len-2] & 0x1F) << 37); | |
301 | /* fall through */ | |
302 | case 1: | |
303 | key |= ((int64_t)(aname[0] & 0x1F) << 58) | | |
304 | ((int64_t)(aname[len-1] & 0x1F) << 32); | |
305 | /* fall through */ | |
306 | case 0: | |
307 | break; | |
308 | } | |
309 | if (key == 0) | |
310 | key |= 0x100000000LL; | |
a276dc6b | 311 | printf("0x%016jx\n", (uintmax_t)key); |
5e435c92 MD |
312 | exit(0); |
313 | } | |
314 | if (strcmp(av[0], "namekey1") == 0) { | |
cbd800c2 MD |
315 | int64_t key; |
316 | ||
88cdee70 | 317 | if (av[1] == NULL) { |
cbd800c2 | 318 | usage(1); |
88cdee70 TK |
319 | /* not reached */ |
320 | } | |
cbd800c2 MD |
321 | key = (int64_t)(crc32(av[1], strlen(av[1])) & 0x7FFFFFFF) << 32; |
322 | if (key == 0) | |
323 | key |= 0x100000000LL; | |
a276dc6b | 324 | printf("0x%016jx\n", (uintmax_t)key); |
cbd800c2 MD |
325 | exit(0); |
326 | } | |
327 | if (strcmp(av[0], "namekey32") == 0) { | |
328 | int32_t key; | |
329 | ||
88cdee70 | 330 | if (av[1] == NULL) { |
cbd800c2 | 331 | usage(1); |
88cdee70 TK |
332 | /* not reached */ |
333 | } | |
cbd800c2 MD |
334 | key = crc32(av[1], strlen(av[1])) & 0x7FFFFFFF; |
335 | if (key == 0) | |
336 | ++key; | |
337 | printf("0x%08x\n", key); | |
338 | exit(0); | |
339 | } | |
34ebae70 MD |
340 | if (strcmp(av[0], "pfs-status") == 0) { |
341 | hammer_cmd_pseudofs_status(av + 1, ac - 1); | |
342 | exit(0); | |
343 | } | |
d4e5b69b MD |
344 | if (strcmp(av[0], "pfs-master") == 0) { |
345 | hammer_cmd_pseudofs_create(av + 1, ac - 1, 0); | |
346 | exit(0); | |
347 | } | |
348 | if (strcmp(av[0], "pfs-slave") == 0) { | |
349 | hammer_cmd_pseudofs_create(av + 1, ac - 1, 1); | |
34ebae70 MD |
350 | exit(0); |
351 | } | |
352 | if (strcmp(av[0], "pfs-update") == 0) { | |
d4e5b69b | 353 | hammer_cmd_pseudofs_update(av + 1, ac - 1); |
66db8054 MD |
354 | exit(0); |
355 | } | |
9c67b4d2 MD |
356 | if (strcmp(av[0], "pfs-upgrade") == 0) { |
357 | hammer_cmd_pseudofs_upgrade(av + 1, ac - 1); | |
358 | exit(0); | |
359 | } | |
360 | if (strcmp(av[0], "pfs-downgrade") == 0) { | |
361 | hammer_cmd_pseudofs_downgrade(av + 1, ac - 1); | |
362 | exit(0); | |
363 | } | |
243ca327 MD |
364 | if (strcmp(av[0], "pfs-destroy") == 0) { |
365 | hammer_cmd_pseudofs_destroy(av + 1, ac - 1); | |
366 | exit(0); | |
367 | } | |
13ce745d | 368 | if (strcmp(av[0], "prune") == 0) { |
b5aaba7f | 369 | hammer_cmd_softprune(av + 1, ac - 1, 0); |
13ce745d MD |
370 | exit(0); |
371 | } | |
91e559fd TK |
372 | if (strcmp(av[0], "prune-everything") == 0) { |
373 | hammer_cmd_softprune(av + 1, ac - 1, 1); | |
374 | exit(0); | |
375 | } | |
83f2a3aa MD |
376 | if (strcmp(av[0], "config") == 0) { |
377 | hammer_cmd_config(av + 1, ac - 1); | |
378 | exit(0); | |
379 | } | |
380 | if (strcmp(av[0], "viconfig") == 0) { | |
381 | hammer_cmd_viconfig(av + 1, ac - 1); | |
382 | exit(0); | |
383 | } | |
6a6e350f MD |
384 | if (strcmp(av[0], "cleanup") == 0) { |
385 | hammer_cmd_cleanup(av + 1, ac - 1); | |
386 | exit(0); | |
387 | } | |
a360fdde JM |
388 | if (strcmp(av[0], "abort-cleanup") == 0) { |
389 | hammer_cmd_abort_cleanup(av + 1, ac - 1); | |
390 | exit(0); | |
391 | } | |
b66b9421 | 392 | if (strcmp(av[0], "info") == 0) { |
61630cfc | 393 | hammer_cmd_info(av + 1, ac - 1); |
b66b9421 AH |
394 | exit(0); |
395 | } | |
69f5a58c | 396 | if (strcmp(av[0], "ssh-remote") == 0) { |
88cdee70 | 397 | if (ac != 3) { |
69f5a58c | 398 | usage(1); |
88cdee70 TK |
399 | /* not reached */ |
400 | } | |
69f5a58c MD |
401 | hammer_cmd_sshremote(av[1], av[2]); |
402 | exit(0); | |
403 | } | |
83f2a3aa MD |
404 | if (strcmp(av[0], "snap") == 0) { |
405 | hammer_cmd_snap(av + 1, ac - 1, 0, 1); | |
406 | exit(0); | |
407 | } | |
408 | if (strcmp(av[0], "snaplo") == 0) { | |
409 | hammer_cmd_snap(av + 1, ac - 1, 0, 0); | |
410 | exit(0); | |
411 | } | |
412 | if (strcmp(av[0], "snapq") == 0) { | |
413 | hammer_cmd_snap(av + 1, ac - 1, 1, 0); | |
414 | exit(0); | |
415 | } | |
416 | if (strcmp(av[0], "snapls") == 0) { | |
417 | hammer_cmd_snapls(av + 1, ac - 1); | |
418 | exit(0); | |
419 | } | |
420 | if (strcmp(av[0], "snaprm") == 0) { | |
421 | hammer_cmd_snaprm(av + 1, ac - 1); | |
422 | exit(0); | |
423 | } | |
6b669ab4 MN |
424 | if (strcmp(av[0], "snapshot") == 0) { |
425 | hammer_cmd_snapshot(av + 1, ac - 1); | |
426 | exit(0); | |
427 | } | |
68e079b8 MD |
428 | if (strcmp(av[0], "bstats") == 0) { |
429 | hammer_cmd_bstats(av + 1, ac - 1); | |
430 | exit(0); | |
431 | } | |
432 | if (strcmp(av[0], "iostats") == 0) { | |
433 | hammer_cmd_iostats(av + 1, ac - 1); | |
434 | exit(0); | |
435 | } | |
3f760d89 TK |
436 | if (strcmp(av[0], "stats") == 0) { |
437 | hammer_cmd_stats(av + 1, ac - 1); | |
438 | exit(0); | |
439 | } | |
13ce745d MD |
440 | |
441 | if (strncmp(av[0], "history", 7) == 0) { | |
00b46268 | 442 | hammer_cmd_history(av[0] + 7, av + 1, ac - 1); |
13ce745d MD |
443 | exit(0); |
444 | } | |
797a0b63 MD |
445 | if (strcmp(av[0], "rebalance") == 0) { |
446 | signal(SIGINT, sigalrm); | |
447 | hammer_cmd_rebalance(av + 1, ac - 1); | |
448 | exit(0); | |
449 | } | |
ba7b52c9 | 450 | if (strncmp(av[0], "reblock", 7) == 0) { |
6a6e350f | 451 | signal(SIGINT, sigalrm); |
ba7b52c9 | 452 | if (strcmp(av[0], "reblock") == 0) |
0c4c331a | 453 | hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_FLAGS); |
ba7b52c9 MD |
454 | else if (strcmp(av[0], "reblock-btree") == 0) |
455 | hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_BTREE); | |
58c17893 MD |
456 | else if (strcmp(av[0], "reblock-inodes") == 0) |
457 | hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_INODES); | |
9e29c876 MD |
458 | else if (strcmp(av[0], "reblock-dirs") == 0) |
459 | hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_DIRS); | |
ba7b52c9 MD |
460 | else if (strcmp(av[0], "reblock-data") == 0) |
461 | hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_DATA); | |
88cdee70 | 462 | else { |
ba7b52c9 | 463 | usage(1); |
88cdee70 TK |
464 | /* not reached */ |
465 | } | |
3f673d5c MD |
466 | exit(0); |
467 | } | |
a7fbbf91 MD |
468 | if (strncmp(av[0], "mirror", 6) == 0) { |
469 | if (strcmp(av[0], "mirror-read") == 0) | |
48eadef9 | 470 | hammer_cmd_mirror_read(av + 1, ac - 1, 0); |
7a27dae7 | 471 | else if (strcmp(av[0], "mirror-read-stream") == 0) |
48eadef9 | 472 | hammer_cmd_mirror_read(av + 1, ac - 1, 1); |
a7fbbf91 MD |
473 | else if (strcmp(av[0], "mirror-write") == 0) |
474 | hammer_cmd_mirror_write(av + 1, ac - 1); | |
475 | else if (strcmp(av[0], "mirror-copy") == 0) | |
48eadef9 MD |
476 | hammer_cmd_mirror_copy(av + 1, ac - 1, 0); |
477 | else if (strcmp(av[0], "mirror-stream") == 0) | |
478 | hammer_cmd_mirror_copy(av + 1, ac - 1, 1); | |
243ca327 | 479 | else if (strcmp(av[0], "mirror-dump") == 0) |
9f1b0121 | 480 | hammer_cmd_mirror_dump(av + 1, ac - 1); |
88cdee70 | 481 | else { |
a7fbbf91 | 482 | usage(1); |
88cdee70 TK |
483 | /* not reached */ |
484 | } | |
a7fbbf91 MD |
485 | exit(0); |
486 | } | |
bb29b5d8 MD |
487 | if (strcmp(av[0], "dedup-simulate") == 0) { |
488 | hammer_cmd_dedup_simulate(av + 1, ac - 1); | |
489 | exit(0); | |
490 | } | |
491 | if (strcmp(av[0], "dedup") == 0) { | |
492 | hammer_cmd_dedup(av + 1, ac - 1); | |
493 | exit(0); | |
494 | } | |
de1c0b31 MD |
495 | if (strcmp(av[0], "version") == 0) { |
496 | hammer_cmd_get_version(av + 1, ac - 1); | |
497 | exit(0); | |
498 | } | |
499 | if (strcmp(av[0], "version-upgrade") == 0) { | |
500 | hammer_cmd_set_version(av + 1, ac - 1); | |
501 | exit(0); | |
502 | } | |
d121f61c MN |
503 | if (strcmp(av[0], "volume-add") == 0) { |
504 | hammer_cmd_volume_add(av + 1, ac - 1); | |
e27700cf MN |
505 | exit(0); |
506 | } | |
865c9609 MN |
507 | if (strcmp(av[0], "volume-del") == 0) { |
508 | hammer_cmd_volume_del(av + 1, ac - 1); | |
509 | exit(0); | |
510 | } | |
e914c91d | 511 | if (strcmp(av[0], "volume-list") == 0) { |
56c2f4d6 | 512 | hammer_cmd_volume_list(av + 1, ac - 1); |
b45632fb TK |
513 | exit(0); |
514 | } | |
515 | if (strcmp(av[0], "volume-blkdevs") == 0) { | |
56c2f4d6 | 516 | hammer_cmd_volume_blkdevs(av + 1, ac - 1); |
e914c91d SK |
517 | exit(0); |
518 | } | |
61aeeb33 | 519 | |
d38ab092 | 520 | if (strcmp(av[0], "show") == 0) { |
913b6663 | 521 | const char *arg = NULL; |
16712f18 | 522 | char *p, *dup; |
c6121c98 | 523 | int filter = -1; |
337ec5f8 | 524 | int obfuscate = 0; |
db7212b1 | 525 | int indent = 0; |
61aeeb33 | 526 | |
52e303fe | 527 | hammer_parse_blkdevs(blkdevs, O_RDONLY); |
73cca638 | 528 | if (ac > 3) { |
db7212b1 | 529 | errx(1, "Too many options specified"); |
73cca638 TK |
530 | /* not reached */ |
531 | } | |
d38ab092 | 532 | if (ac > 1) |
913b6663 | 533 | arg = av[1]; |
c6121c98 | 534 | if (ac > 2) { |
16712f18 TK |
535 | dup = ptr = strdup(av[2]); |
536 | while ((p = strsep(&ptr, ",")) != NULL) { | |
52e2f1b5 | 537 | if (strcmp(p, "filter") == 0) |
db7212b1 | 538 | filter = 1; |
52e2f1b5 | 539 | else if (strcmp(p, "nofilter") == 0) |
db7212b1 | 540 | filter = 0; |
52e2f1b5 | 541 | else if (strcmp(p, "obfuscate") == 0) |
db7212b1 | 542 | obfuscate = 1; |
52e2f1b5 | 543 | else if (strcmp(p, "indent") == 0) |
db7212b1 | 544 | indent = 1; |
db7212b1 | 545 | } |
16712f18 | 546 | free(dup); |
337ec5f8 | 547 | } |
db7212b1 | 548 | hammer_cmd_show(arg, filter, obfuscate, indent); |
d38ab092 MD |
549 | exit(0); |
550 | } | |
6aec797f | 551 | if (strcmp(av[0], "show-undo") == 0) { |
52e303fe | 552 | hammer_parse_blkdevs(blkdevs, O_RDONLY); |
6aec797f MD |
553 | hammer_cmd_show_undo(); |
554 | exit(0); | |
555 | } | |
b9107f58 | 556 | if (strcmp(av[0], "recover") == 0) { |
52e303fe | 557 | __hammer_parse_blkdevs(blkdevs, O_RDONLY, 0, 1); |
e819b271 | 558 | hammer_cmd_recover(av + 1, ac - 1); |
b9107f58 MD |
559 | exit(0); |
560 | } | |
eb3f8f1f | 561 | if (strcmp(av[0], "blockmap") == 0) { |
52e303fe | 562 | hammer_parse_blkdevs(blkdevs, O_RDONLY); |
eb3f8f1f MD |
563 | hammer_cmd_blockmap(); |
564 | exit(0); | |
565 | } | |
6ed4c886 | 566 | if (strcmp(av[0], "checkmap") == 0) { |
52e303fe | 567 | hammer_parse_blkdevs(blkdevs, O_RDONLY); |
6ed4c886 MD |
568 | hammer_cmd_checkmap(); |
569 | exit(0); | |
570 | } | |
2eccaef5 | 571 | if (strcmp(av[0], "strip") == 0) { |
52e303fe | 572 | __hammer_parse_blkdevs(blkdevs, O_RDWR, 0, 0); |
2eccaef5 TK |
573 | hammer_cmd_strip(); |
574 | exit(0); | |
575 | } | |
576 | ||
61aeeb33 MD |
577 | usage(1); |
578 | /* not reached */ | |
0dfeb6c8 MD |
579 | return(0); |
580 | } | |
581 | ||
9c9ac2f1 MD |
582 | /* |
583 | * Parse the device specification. | |
584 | * | |
585 | * Multi-volume hammer devices are colon-separated. Each element | |
586 | * may be further expanded via /etc/devtab. One may also specify | |
587 | * a single element which is expanded into multiple elements via | |
588 | * /etc/devtab. | |
589 | */ | |
d38ab092 MD |
590 | static |
591 | void | |
52e303fe | 592 | __hammer_parse_blkdevs(const char *blkdevs, int oflags, int verify_volume, |
6f3c8414 | 593 | int verify_count) |
d38ab092 | 594 | { |
2dba5fa7 | 595 | volume_info_t volume = NULL; |
d38ab092 MD |
596 | char *copy; |
597 | char *volname; | |
6f3c8414 | 598 | int vol_count = 0; |
d38ab092 | 599 | |
f254e677 | 600 | if (blkdevs == NULL) { |
f6532f03 | 601 | errx(1, "A -f blkdevs specification is required " |
d38ab092 | 602 | "for this command"); |
73cca638 | 603 | /* not reached */ |
f254e677 | 604 | } |
d38ab092 MD |
605 | |
606 | copy = strdup(blkdevs); | |
607 | while ((volname = copy) != NULL) { | |
608 | if ((copy = strchr(copy, ':')) != NULL) | |
609 | *copy++ = 0; | |
9c9ac2f1 | 610 | volname = getdevpath(volname, 0); |
4c09d9c4 | 611 | if (strchr(volname, ':')) { |
52e303fe | 612 | __hammer_parse_blkdevs(volname, oflags, verify_volume, |
6f3c8414 | 613 | verify_count); |
4c09d9c4 | 614 | } else { |
6f3c8414 | 615 | volume = load_volume(volname, oflags, verify_volume); |
5ebff42a | 616 | assert(volume); |
6f3c8414 | 617 | ++vol_count; |
9c56653b | 618 | } |
8e99b497 | 619 | free(volname); |
d38ab092 | 620 | } |
8e99b497 | 621 | free(copy); |
9c56653b | 622 | |
5ebff42a | 623 | assert(volume); |
6f3c8414 TK |
624 | if (verify_count) { |
625 | if (vol_count != volume->ondisk->vol_count) { | |
626 | errx(1, "Volume header says %d volumes, but %d specified.", | |
627 | volume->ondisk->vol_count, vol_count); | |
628 | /* not reached */ | |
629 | } | |
630 | if (get_root_volume() == NULL) { | |
631 | errx(1, "No root volume found"); | |
632 | /* not reached */ | |
633 | } | |
73cca638 | 634 | } |
d38ab092 MD |
635 | } |
636 | ||
c2b74c42 TK |
637 | static __inline |
638 | void | |
52e303fe | 639 | hammer_parse_blkdevs(const char *blkdevs, int oflags) |
c2b74c42 | 640 | { |
52e303fe | 641 | __hammer_parse_blkdevs(blkdevs, oflags, 1, 1); |
c2b74c42 TK |
642 | } |
643 | ||
0006adae MD |
644 | static |
645 | void | |
646 | sigalrm(int signo __unused) | |
647 | { | |
648 | /* do nothing (interrupts HAMMER ioctl) */ | |
649 | } | |
650 | ||
445faa69 MD |
651 | static |
652 | void | |
653 | sigintr(int signo __unused) | |
654 | { | |
655 | if (RunningIoctl == 0) | |
656 | _exit(1); | |
657 | DidInterrupt = 1; | |
658 | /* do nothing (interrupts HAMMER ioctl) */ | |
659 | } | |
660 | ||
0dfeb6c8 MD |
661 | static |
662 | void | |
663 | usage(int exit_code) | |
664 | { | |
84e57c2c | 665 | fprintf(stderr, |
0dfeb6c8 | 666 | "hammer -h\n" |
dda14c07 TK |
667 | "hammer [-2ABFqrvXy] [-b bandwidth] [-C cachesize[:readahead]] \n" |
668 | " [-R restrictcmd] [-T restrictpath] [-c cyclefile]\n" | |
669 | " [-e scoreboardfile] [-f blkdevs] [-i delay] [-p ssh-port]\n" | |
670 | " [-S splitsize] [-t seconds] [-m memlimit] command [argument ...]\n" | |
84082922 | 671 | "hammer synctid <filesystem> [quick]\n" |
bb8e52c0 TN |
672 | "hammer bstats [interval]\n" |
673 | "hammer iostats [interval]\n" | |
7b431e68 | 674 | "hammer stats [interval]\n" |
bb8e52c0 | 675 | "hammer history[@offset[,len]] <file> ...\n" |
5e435c92 MD |
676 | "hammer namekey1 <path>\n" |
677 | "hammer namekey2 <path>\n" | |
4567021b | 678 | "hammer namekey32 <path>\n" |
bb8e52c0 | 679 | "hammer cleanup [<filesystem> ...]\n" |
a360fdde | 680 | "hammer abort-cleanup\n" |
8a03ae8a | 681 | "hammer info [<dirpath> ...]\n" |
bb8e52c0 | 682 | "hammer snapshot [<filesystem>] <snapshot-dir>\n" |
16265794 | 683 | "hammer snapshot <filesystem> <snapshot-dir> [<note>]\n" |
84082922 | 684 | "hammer prune <softlink-dir>\n" |
b5aaba7f | 685 | "hammer prune-everything <filesystem>\n" |
797a0b63 | 686 | "hammer rebalance <filesystem> [saturation_percentage]\n" |
4567021b | 687 | "hammer reblock[-btree|-inodes|-dirs|-data] " |
84082922 | 688 | "<filesystem> [fill_percentage]\n" |
34bb69d8 | 689 | "hammer pfs-status <dirpath> ...\n" |
d4e5b69b MD |
690 | "hammer pfs-master <dirpath> [options]\n" |
691 | "hammer pfs-slave <dirpath> [options]\n" | |
34ebae70 | 692 | "hammer pfs-update <dirpath> [options]\n" |
9c67b4d2 MD |
693 | "hammer pfs-upgrade <dirpath>\n" |
694 | "hammer pfs-downgrade <dirpath>\n" | |
695 | "hammer pfs-destroy <dirpath>\n" | |
bb8e52c0 TN |
696 | "hammer mirror-read <filesystem> [begin-tid]\n" |
697 | "hammer mirror-read-stream <filesystem> [begin-tid]\n" | |
698 | "hammer mirror-write <filesystem>\n" | |
9f1b0121 | 699 | "hammer mirror-dump [header]\n" |
bb8e52c0 TN |
700 | "hammer mirror-copy [[user@]host:]<filesystem>" |
701 | " [[user@]host:]<filesystem>\n" | |
702 | "hammer mirror-stream [[user@]host:]<filesystem>" | |
703 | " [[user@]host:]<filesystem>\n" | |
69f5a58c | 704 | "hammer ssh-remote command filesystem\n" |
5e435c92 | 705 | "hammer version <filesystem>\n" |
4567021b | 706 | "hammer version-upgrade <filesystem> <version> [force]\n" |
d121f61c | 707 | "hammer volume-add <device> <filesystem>\n" |
865c9609 | 708 | "hammer volume-del <device> <filesystem>\n" |
e914c91d | 709 | "hammer volume-list <filesystem>\n" |
b45632fb | 710 | "hammer volume-blkdevs <filesystem>\n" |
0dfeb6c8 | 711 | ); |
83f2a3aa | 712 | |
f6532f03 | 713 | fprintf(stderr, "\nHAMMER utility version 3+ commands:\n"); |
83f2a3aa MD |
714 | |
715 | fprintf(stderr, | |
716 | "hammer config [<filesystem> [<configfile>]]\n" | |
717 | "hammer viconfig [<filesystem>]\n" | |
f6532f03 TN |
718 | "hammer snap <path> [<note>]\n" |
719 | "hammer snaplo <path> [<note>]\n" | |
720 | "hammer snapq <dir> [<note>]\n" | |
aaf93065 TN |
721 | "hammer snaprm <path> ...\n" |
722 | "hammer snaprm <transid> ...\n" | |
723 | "hammer snaprm <filesystem> <transid> ...\n" | |
f6532f03 TN |
724 | "hammer snapls [<path> ...]\n" |
725 | ); | |
726 | ||
727 | fprintf(stderr, "\nHAMMER utility version 4+ commands:\n"); | |
728 | ||
729 | fprintf(stderr, | |
c71cab34 MD |
730 | "hammer -f blkdevs blockmap\n" |
731 | "hammer -f blkdevs checkmap\n" | |
732 | "hammer -f blkdevs [-qqq] show [lo:objid]\n" | |
f6532f03 | 733 | "hammer -f blkdevs show-undo\n" |
3d900665 | 734 | "hammer -f blkdevs recover <target_dir> [full|quick]\n" |
2eccaef5 | 735 | "hammer -f blkdevs strip\n" |
83f2a3aa MD |
736 | ); |
737 | ||
bb29b5d8 MD |
738 | fprintf(stderr, "\nHAMMER utility version 5+ commands:\n"); |
739 | ||
740 | fprintf(stderr, | |
741 | "hammer dedup-simulate <filesystem>\n" | |
742 | "hammer dedup <filesystem>\n" | |
743 | ); | |
744 | ||
0dfeb6c8 MD |
745 | exit(exit_code); |
746 | } | |
d38ab092 | 747 |