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 * 34de1c0b31SMatthew Dillon * $DragonFly: src/sbin/hammer/hammer.c,v 1.44 2008/11/13 02:04:27 dillon Exp $ 350dfeb6c8SMatthew Dillon */ 360dfeb6c8SMatthew Dillon 3761aeeb33SMatthew Dillon #include "hammer.h" 380006adaeSMatthew Dillon #include <signal.h> 39d71afe7bSMatthew Dillon #include <math.h> 409c9ac2f1SMatthew Dillon #include <fstab.h> 410dfeb6c8SMatthew Dillon 42d38ab092SMatthew Dillon static void hammer_parsedevs(const char *blkdevs); 430006adaeSMatthew Dillon static void sigalrm(int signo); 44445faa69SMatthew Dillon static void sigintr(int signo); 450dfeb6c8SMatthew Dillon static void usage(int exit_code); 460dfeb6c8SMatthew Dillon 47d38ab092SMatthew Dillon int RecurseOpt; 48563b4845SMatthew Dillon int VerboseOpt; 49e95314deSMatthew Dillon int QuietOpt; 50d71afe7bSMatthew Dillon int NoSyncOpt; 51243ca327SMatthew Dillon int TwoWayPipeOpt; 52243ca327SMatthew Dillon int TimeoutOpt; 5348eadef9SMatthew Dillon int DelayOpt = 5; 546c45ca3eSMatthew Dillon char *SshPort; 5507485271SMichael Neumann int ForceYesOpt = 0; 563a998207SMatthew Dillon int CompressOpt; 57e7f926a5SMatthew Dillon int ForceOpt; 58445faa69SMatthew Dillon int RunningIoctl; 59445faa69SMatthew Dillon int DidInterrupt; 600bd7a37cSMatthew Dillon int BulkOpt; 6148eadef9SMatthew Dillon u_int64_t BandwidthOpt; 62527a7bdbSMatthew Dillon u_int64_t SplitupOpt = 4ULL * 1024ULL * 1024ULL * 1024ULL; 63fbe1c665SMatthew Dillon u_int64_t MemoryLimit = 1024LLU * 1024 * 1024; 64b6ced256SMatthew Dillon const char *SplitupOptStr; 65d7ae405cSMatthew Dillon const char *CyclePath; 66da804f11SMatthew Dillon const char *LinkPath; 67*69f5a58cSMatthew Dillon const char *RestrictTarget; 68d38ab092SMatthew Dillon 690dfeb6c8SMatthew Dillon int 700dfeb6c8SMatthew Dillon main(int ac, char **av) 710dfeb6c8SMatthew Dillon { 72d38ab092SMatthew Dillon char *blkdevs = NULL; 7348eadef9SMatthew Dillon char *ptr; 74*69f5a58cSMatthew Dillon char *restrictcmd = NULL; 7548eadef9SMatthew Dillon u_int32_t status; 7648eadef9SMatthew Dillon int ch; 770faa08a1SMatthew Dillon int cacheSize = 0; 780dfeb6c8SMatthew Dillon 79269cdd19SMatthew Dillon while ((ch = getopt(ac, av, 80*69f5a58cSMatthew Dillon "b:c:de:hf:i:m:p:qrs:t:v2yBC:FR:S:T:X")) != -1) { 810dfeb6c8SMatthew Dillon switch(ch) { 82243ca327SMatthew Dillon case '2': 83243ca327SMatthew Dillon TwoWayPipeOpt = 1; 84243ca327SMatthew Dillon break; 8507485271SMichael Neumann case 'y': 8607485271SMichael Neumann ForceYesOpt = 1; 8707485271SMichael Neumann break; 8848eadef9SMatthew Dillon case 'b': 8948eadef9SMatthew Dillon BandwidthOpt = strtoull(optarg, &ptr, 0); 9048eadef9SMatthew Dillon switch(*ptr) { 9148eadef9SMatthew Dillon case 'g': 9248eadef9SMatthew Dillon case 'G': 9348eadef9SMatthew Dillon BandwidthOpt *= 1024; 9448eadef9SMatthew Dillon /* fall through */ 9548eadef9SMatthew Dillon case 'm': 9648eadef9SMatthew Dillon case 'M': 9748eadef9SMatthew Dillon BandwidthOpt *= 1024; 9848eadef9SMatthew Dillon /* fall through */ 9948eadef9SMatthew Dillon case 'k': 10048eadef9SMatthew Dillon case 'K': 10148eadef9SMatthew Dillon BandwidthOpt *= 1024; 10248eadef9SMatthew Dillon break; 103224ac2f2SMatthew Dillon case '\0': 104224ac2f2SMatthew Dillon /* bytes per second if no suffix */ 105224ac2f2SMatthew Dillon break; 10648eadef9SMatthew Dillon default: 10748eadef9SMatthew Dillon usage(1); 10848eadef9SMatthew Dillon } 10948eadef9SMatthew Dillon break; 1103d7b2393SMatthew Dillon case 'S': 111b6ced256SMatthew Dillon SplitupOptStr = strdup(optarg); 1123d7b2393SMatthew Dillon SplitupOpt = strtoull(optarg, &ptr, 0); 1133d7b2393SMatthew Dillon switch(*ptr) { 1143d7b2393SMatthew Dillon case 'g': 1153d7b2393SMatthew Dillon case 'G': 1163d7b2393SMatthew Dillon SplitupOpt *= 1024; 1173d7b2393SMatthew Dillon /* fall through */ 1183d7b2393SMatthew Dillon case 'm': 1193d7b2393SMatthew Dillon case 'M': 1203d7b2393SMatthew Dillon SplitupOpt *= 1024; 1213d7b2393SMatthew Dillon /* fall through */ 1223d7b2393SMatthew Dillon case 'k': 1233d7b2393SMatthew Dillon case 'K': 1243d7b2393SMatthew Dillon SplitupOpt *= 1024; 1253d7b2393SMatthew Dillon break; 1263d7b2393SMatthew Dillon case '\0': 1273d7b2393SMatthew Dillon /* bytes per second if no suffix */ 1283d7b2393SMatthew Dillon break; 1293d7b2393SMatthew Dillon default: 1303d7b2393SMatthew Dillon usage(1); 1313d7b2393SMatthew Dillon } 1323d7b2393SMatthew Dillon break; 133d7ae405cSMatthew Dillon case 'c': 134d7ae405cSMatthew Dillon CyclePath = optarg; 135d7ae405cSMatthew Dillon break; 136ba7b52c9SMatthew Dillon case 'd': 137ba7b52c9SMatthew Dillon ++DebugOpt; 138ba7b52c9SMatthew Dillon break; 139269cdd19SMatthew Dillon case 'e': 140269cdd19SMatthew Dillon ScoreBoardFile = optarg; 141269cdd19SMatthew Dillon break; 1420dfeb6c8SMatthew Dillon case 'h': 1430dfeb6c8SMatthew Dillon usage(0); 1440dfeb6c8SMatthew Dillon /* not reached */ 14548eadef9SMatthew Dillon case 'i': 14648eadef9SMatthew Dillon DelayOpt = strtol(optarg, NULL, 0); 14748eadef9SMatthew Dillon break; 148fbe1c665SMatthew Dillon case 'm': 149fbe1c665SMatthew Dillon MemoryLimit = strtouq(optarg, &ptr, 0); 150fbe1c665SMatthew Dillon switch(*ptr) { 151fbe1c665SMatthew Dillon case 't': 152fbe1c665SMatthew Dillon case 'T': 153fbe1c665SMatthew Dillon MemoryLimit *= 1024; 154fbe1c665SMatthew Dillon /* fall through */ 155fbe1c665SMatthew Dillon case 'g': 156fbe1c665SMatthew Dillon case 'G': 157fbe1c665SMatthew Dillon MemoryLimit *= 1024; 158fbe1c665SMatthew Dillon /* fall through */ 159fbe1c665SMatthew Dillon case 'm': 160fbe1c665SMatthew Dillon case 'M': 161fbe1c665SMatthew Dillon MemoryLimit *= 1024; 162fbe1c665SMatthew Dillon /* fall through */ 163fbe1c665SMatthew Dillon case 'k': 164fbe1c665SMatthew Dillon case 'K': 165fbe1c665SMatthew Dillon MemoryLimit *= 1024; 166fbe1c665SMatthew Dillon /* fall through */ 167fbe1c665SMatthew Dillon default: 168fbe1c665SMatthew Dillon break; 169fbe1c665SMatthew Dillon } 170fbe1c665SMatthew Dillon 171fbe1c665SMatthew Dillon /* minimum limit */ 172fbe1c665SMatthew Dillon if (MemoryLimit < 1024 * 1024) 173fbe1c665SMatthew Dillon MemoryLimit = 1024 * 1024; 174fbe1c665SMatthew Dillon break; 1756c45ca3eSMatthew Dillon case 'p': 1766c45ca3eSMatthew Dillon SshPort = optarg; 1776c45ca3eSMatthew Dillon break; 178d38ab092SMatthew Dillon case 'r': 179d38ab092SMatthew Dillon RecurseOpt = 1; 180d38ab092SMatthew Dillon break; 181d38ab092SMatthew Dillon case 'f': 182d38ab092SMatthew Dillon blkdevs = optarg; 183d38ab092SMatthew Dillon break; 184da804f11SMatthew Dillon case 's': 185da804f11SMatthew Dillon LinkPath = optarg; 186da804f11SMatthew Dillon break; 1870006adaeSMatthew Dillon case 't': 188243ca327SMatthew Dillon TimeoutOpt = strtol(optarg, NULL, 0); 1890006adaeSMatthew Dillon break; 190563b4845SMatthew Dillon case 'v': 191e95314deSMatthew Dillon if (QuietOpt > 0) 192e95314deSMatthew Dillon --QuietOpt; 193e95314deSMatthew Dillon else 194563b4845SMatthew Dillon ++VerboseOpt; 195563b4845SMatthew Dillon break; 196e95314deSMatthew Dillon case 'q': 197e95314deSMatthew Dillon if (VerboseOpt > 0) 198e95314deSMatthew Dillon --VerboseOpt; 199e95314deSMatthew Dillon else 200e95314deSMatthew Dillon ++QuietOpt; 201e95314deSMatthew Dillon break; 2020bd7a37cSMatthew Dillon case 'B': 2030bd7a37cSMatthew Dillon BulkOpt = 1; 2040bd7a37cSMatthew Dillon break; 2050faa08a1SMatthew Dillon case 'C': 2060faa08a1SMatthew Dillon cacheSize = strtol(optarg, &ptr, 0); 2070faa08a1SMatthew Dillon switch(*ptr) { 2080faa08a1SMatthew Dillon case 'm': 2090faa08a1SMatthew Dillon case 'M': 2100faa08a1SMatthew Dillon cacheSize *= 1024; 2110faa08a1SMatthew Dillon /* fall through */ 2120faa08a1SMatthew Dillon case 'k': 2130faa08a1SMatthew Dillon case 'K': 2140faa08a1SMatthew Dillon cacheSize *= 1024; 215b46b99bfSMatthew Dillon ++ptr; 2160faa08a1SMatthew Dillon break; 2170faa08a1SMatthew Dillon case '\0': 218b46b99bfSMatthew Dillon case ':': 2190faa08a1SMatthew Dillon /* bytes if no suffix */ 2200faa08a1SMatthew Dillon break; 2210faa08a1SMatthew Dillon default: 2220faa08a1SMatthew Dillon usage(1); 2230faa08a1SMatthew Dillon } 224b46b99bfSMatthew Dillon if (*ptr == ':') { 225b46b99bfSMatthew Dillon UseReadAhead = strtol(ptr + 1, NULL, 0); 226b46b99bfSMatthew Dillon UseReadBehind = -UseReadAhead; 227b46b99bfSMatthew Dillon } 2280faa08a1SMatthew Dillon if (cacheSize < 1024 * 1024) 2290faa08a1SMatthew Dillon cacheSize = 1024 * 1024; 230b46b99bfSMatthew Dillon if (UseReadAhead < 0) 231b46b99bfSMatthew Dillon usage(1); 232b46b99bfSMatthew Dillon if (UseReadAhead * HAMMER_BUFSIZE / cacheSize / 16) { 233b46b99bfSMatthew Dillon UseReadAhead = cacheSize / 16 / HAMMER_BUFSIZE; 234b46b99bfSMatthew Dillon UseReadBehind = -UseReadAhead; 235b46b99bfSMatthew Dillon } 2360faa08a1SMatthew Dillon hammer_cache_set(cacheSize); 2370faa08a1SMatthew Dillon break; 238e7f926a5SMatthew Dillon case 'F': 239e7f926a5SMatthew Dillon ForceOpt = 1; 240e7f926a5SMatthew Dillon break; 241*69f5a58cSMatthew Dillon case 'R': 242*69f5a58cSMatthew Dillon if (restrictcmd == NULL) 243*69f5a58cSMatthew Dillon restrictcmd = optarg; 244*69f5a58cSMatthew Dillon break; 245*69f5a58cSMatthew Dillon case 'T': 246*69f5a58cSMatthew Dillon if (RestrictTarget == NULL) 247*69f5a58cSMatthew Dillon RestrictTarget = optarg; 248*69f5a58cSMatthew Dillon break; 2493a998207SMatthew Dillon case 'X': 2503a998207SMatthew Dillon CompressOpt = 1; 2513a998207SMatthew Dillon break; 2520dfeb6c8SMatthew Dillon default: 2530dfeb6c8SMatthew Dillon usage(1); 2540dfeb6c8SMatthew Dillon /* not reached */ 2550dfeb6c8SMatthew Dillon } 2560dfeb6c8SMatthew Dillon } 2570dfeb6c8SMatthew Dillon ac -= optind; 2580dfeb6c8SMatthew Dillon av += optind; 2590dfeb6c8SMatthew Dillon if (ac < 1) { 2600dfeb6c8SMatthew Dillon usage(1); 2610dfeb6c8SMatthew Dillon /* not reached */ 2620dfeb6c8SMatthew Dillon } 2630dfeb6c8SMatthew Dillon 2640006adaeSMatthew Dillon signal(SIGALRM, sigalrm); 265445faa69SMatthew Dillon signal(SIGINT, sigintr); 2660006adaeSMatthew Dillon 267*69f5a58cSMatthew Dillon /* 268*69f5a58cSMatthew Dillon * Check command restriction (used by hammer ssh-remote). Several 269*69f5a58cSMatthew Dillon * commands may be iterated with a comma. 270*69f5a58cSMatthew Dillon */ 271*69f5a58cSMatthew Dillon if (restrictcmd) { 272*69f5a58cSMatthew Dillon char *elm; 273*69f5a58cSMatthew Dillon 274*69f5a58cSMatthew Dillon ptr = strdup(restrictcmd); 275*69f5a58cSMatthew Dillon while ((elm = strsep(&ptr, ",")) != NULL) { 276*69f5a58cSMatthew Dillon if (strcmp(av[0], elm) == 0) 277*69f5a58cSMatthew Dillon break; 278*69f5a58cSMatthew Dillon } 279*69f5a58cSMatthew Dillon if (elm == NULL) { 280*69f5a58cSMatthew Dillon fprintf(stderr, "hammer-remote: request does not match " 281*69f5a58cSMatthew Dillon "restricted command\n"); 282*69f5a58cSMatthew Dillon exit(1); 283*69f5a58cSMatthew Dillon } 284*69f5a58cSMatthew Dillon free(ptr); 285*69f5a58cSMatthew Dillon } 286*69f5a58cSMatthew Dillon 287*69f5a58cSMatthew Dillon /* 288*69f5a58cSMatthew Dillon * Parse commands 289*69f5a58cSMatthew Dillon */ 290367431cfSMatthew Dillon if (strcmp(av[0], "synctid") == 0) { 291367431cfSMatthew Dillon hammer_cmd_synctid(av + 1, ac - 1); 292367431cfSMatthew Dillon exit(0); 293367431cfSMatthew Dillon } 2945e435c92SMatthew Dillon if (strcmp(av[0], "namekey2") == 0) { 2955e435c92SMatthew Dillon int64_t key; 2965e435c92SMatthew Dillon int32_t crcx; 2975e435c92SMatthew Dillon int len; 2985e435c92SMatthew Dillon const char *aname = av[1]; 2995e435c92SMatthew Dillon 3005e435c92SMatthew Dillon if (aname == NULL) 3015e435c92SMatthew Dillon usage(1); 3025e435c92SMatthew Dillon len = strlen(aname); 3035e435c92SMatthew Dillon key = (u_int32_t)crc32(aname, len) & 0xFFFFFFFEU; 3045e435c92SMatthew Dillon 3055e435c92SMatthew Dillon switch(len) { 3065e435c92SMatthew Dillon default: 3075e435c92SMatthew Dillon crcx = crc32(aname + 3, len - 5); 3085e435c92SMatthew Dillon crcx = crcx ^ (crcx >> 6) ^ (crcx >> 12); 3095e435c92SMatthew Dillon key |= (int64_t)(crcx & 0x3F) << 42; 3105e435c92SMatthew Dillon /* fall through */ 3115e435c92SMatthew Dillon case 5: 3125e435c92SMatthew Dillon case 4: 3135e435c92SMatthew Dillon /* fall through */ 3145e435c92SMatthew Dillon case 3: 3155e435c92SMatthew Dillon key |= ((int64_t)(aname[2] & 0x1F) << 48); 3165e435c92SMatthew Dillon /* fall through */ 3175e435c92SMatthew Dillon case 2: 3185e435c92SMatthew Dillon key |= ((int64_t)(aname[1] & 0x1F) << 53) | 3195e435c92SMatthew Dillon ((int64_t)(aname[len-2] & 0x1F) << 37); 3205e435c92SMatthew Dillon /* fall through */ 3215e435c92SMatthew Dillon case 1: 3225e435c92SMatthew Dillon key |= ((int64_t)(aname[0] & 0x1F) << 58) | 3235e435c92SMatthew Dillon ((int64_t)(aname[len-1] & 0x1F) << 32); 3245e435c92SMatthew Dillon /* fall through */ 3255e435c92SMatthew Dillon case 0: 3265e435c92SMatthew Dillon break; 3275e435c92SMatthew Dillon } 3285e435c92SMatthew Dillon if (key == 0) 3295e435c92SMatthew Dillon key |= 0x100000000LL; 330a276dc6bSMatthew Dillon printf("0x%016jx\n", (uintmax_t)key); 3315e435c92SMatthew Dillon exit(0); 3325e435c92SMatthew Dillon } 3335e435c92SMatthew Dillon if (strcmp(av[0], "namekey1") == 0) { 334cbd800c2SMatthew Dillon int64_t key; 335cbd800c2SMatthew Dillon 336cbd800c2SMatthew Dillon if (av[1] == NULL) 337cbd800c2SMatthew Dillon usage(1); 338cbd800c2SMatthew Dillon key = (int64_t)(crc32(av[1], strlen(av[1])) & 0x7FFFFFFF) << 32; 339cbd800c2SMatthew Dillon if (key == 0) 340cbd800c2SMatthew Dillon key |= 0x100000000LL; 341a276dc6bSMatthew Dillon printf("0x%016jx\n", (uintmax_t)key); 342cbd800c2SMatthew Dillon exit(0); 343cbd800c2SMatthew Dillon } 344cbd800c2SMatthew Dillon if (strcmp(av[0], "namekey32") == 0) { 345cbd800c2SMatthew Dillon int32_t key; 346cbd800c2SMatthew Dillon 347cbd800c2SMatthew Dillon if (av[1] == NULL) 348cbd800c2SMatthew Dillon usage(1); 349cbd800c2SMatthew Dillon key = crc32(av[1], strlen(av[1])) & 0x7FFFFFFF; 350cbd800c2SMatthew Dillon if (key == 0) 351cbd800c2SMatthew Dillon ++key; 352cbd800c2SMatthew Dillon printf("0x%08x\n", key); 353cbd800c2SMatthew Dillon exit(0); 354cbd800c2SMatthew Dillon } 35534ebae70SMatthew Dillon if (strcmp(av[0], "pfs-status") == 0) { 35634ebae70SMatthew Dillon hammer_cmd_pseudofs_status(av + 1, ac - 1); 35734ebae70SMatthew Dillon exit(0); 35834ebae70SMatthew Dillon } 359d4e5b69bSMatthew Dillon if (strcmp(av[0], "pfs-master") == 0) { 360d4e5b69bSMatthew Dillon hammer_cmd_pseudofs_create(av + 1, ac - 1, 0); 361d4e5b69bSMatthew Dillon exit(0); 362d4e5b69bSMatthew Dillon } 363d4e5b69bSMatthew Dillon if (strcmp(av[0], "pfs-slave") == 0) { 364d4e5b69bSMatthew Dillon hammer_cmd_pseudofs_create(av + 1, ac - 1, 1); 36534ebae70SMatthew Dillon exit(0); 36634ebae70SMatthew Dillon } 36734ebae70SMatthew Dillon if (strcmp(av[0], "pfs-update") == 0) { 368d4e5b69bSMatthew Dillon hammer_cmd_pseudofs_update(av + 1, ac - 1); 36966db8054SMatthew Dillon exit(0); 37066db8054SMatthew Dillon } 3719c67b4d2SMatthew Dillon if (strcmp(av[0], "pfs-upgrade") == 0) { 3729c67b4d2SMatthew Dillon hammer_cmd_pseudofs_upgrade(av + 1, ac - 1); 3739c67b4d2SMatthew Dillon exit(0); 3749c67b4d2SMatthew Dillon } 3759c67b4d2SMatthew Dillon if (strcmp(av[0], "pfs-downgrade") == 0) { 3769c67b4d2SMatthew Dillon hammer_cmd_pseudofs_downgrade(av + 1, ac - 1); 3779c67b4d2SMatthew Dillon exit(0); 3789c67b4d2SMatthew Dillon } 379243ca327SMatthew Dillon if (strcmp(av[0], "pfs-destroy") == 0) { 380243ca327SMatthew Dillon hammer_cmd_pseudofs_destroy(av + 1, ac - 1); 381243ca327SMatthew Dillon exit(0); 382243ca327SMatthew Dillon } 383a7fbbf91SMatthew Dillon if (strcmp(av[0], "status") == 0) { 384a7fbbf91SMatthew Dillon hammer_cmd_status(av + 1, ac - 1); 385a7fbbf91SMatthew Dillon exit(0); 386a7fbbf91SMatthew Dillon } 38713ce745dSMatthew Dillon if (strcmp(av[0], "prune") == 0) { 388b5aaba7fSMatthew Dillon hammer_cmd_softprune(av + 1, ac - 1, 0); 38913ce745dSMatthew Dillon exit(0); 39013ce745dSMatthew Dillon } 39183f2a3aaSMatthew Dillon if (strcmp(av[0], "config") == 0) { 39283f2a3aaSMatthew Dillon hammer_cmd_config(av + 1, ac - 1); 39383f2a3aaSMatthew Dillon exit(0); 39483f2a3aaSMatthew Dillon } 39583f2a3aaSMatthew Dillon if (strcmp(av[0], "viconfig") == 0) { 39683f2a3aaSMatthew Dillon hammer_cmd_viconfig(av + 1, ac - 1); 39783f2a3aaSMatthew Dillon exit(0); 39883f2a3aaSMatthew Dillon } 3996a6e350fSMatthew Dillon if (strcmp(av[0], "cleanup") == 0) { 4006a6e350fSMatthew Dillon hammer_cmd_cleanup(av + 1, ac - 1); 4016a6e350fSMatthew Dillon exit(0); 4026a6e350fSMatthew Dillon } 403b66b9421SAntonio Huete if (strcmp(av[0], "info") == 0) { 404eac446c5SMatthew Dillon hammer_cmd_info(); 405b66b9421SAntonio Huete exit(0); 406b66b9421SAntonio Huete } 407b5aaba7fSMatthew Dillon if (strcmp(av[0], "prune-everything") == 0) { 408b5aaba7fSMatthew Dillon hammer_cmd_softprune(av + 1, ac - 1, 1); 409e8969ef0SMatthew Dillon exit(0); 410e8969ef0SMatthew Dillon } 411*69f5a58cSMatthew Dillon if (strcmp(av[0], "ssh-remote") == 0) { 412*69f5a58cSMatthew Dillon if (ac != 3) 413*69f5a58cSMatthew Dillon usage(1); 414*69f5a58cSMatthew Dillon hammer_cmd_sshremote(av[1], av[2]); 415*69f5a58cSMatthew Dillon exit(0); 416*69f5a58cSMatthew Dillon } 41783f2a3aaSMatthew Dillon if (strcmp(av[0], "snap") == 0) { 41883f2a3aaSMatthew Dillon hammer_cmd_snap(av + 1, ac - 1, 0, 1); 41983f2a3aaSMatthew Dillon exit(0); 42083f2a3aaSMatthew Dillon } 42183f2a3aaSMatthew Dillon if (strcmp(av[0], "snaplo") == 0) { 42283f2a3aaSMatthew Dillon hammer_cmd_snap(av + 1, ac - 1, 0, 0); 42383f2a3aaSMatthew Dillon exit(0); 42483f2a3aaSMatthew Dillon } 42583f2a3aaSMatthew Dillon if (strcmp(av[0], "snapq") == 0) { 42683f2a3aaSMatthew Dillon hammer_cmd_snap(av + 1, ac - 1, 1, 0); 42783f2a3aaSMatthew Dillon exit(0); 42883f2a3aaSMatthew Dillon } 42983f2a3aaSMatthew Dillon if (strcmp(av[0], "snapls") == 0) { 43083f2a3aaSMatthew Dillon hammer_cmd_snapls(av + 1, ac - 1); 43183f2a3aaSMatthew Dillon exit(0); 43283f2a3aaSMatthew Dillon } 43383f2a3aaSMatthew Dillon if (strcmp(av[0], "snaprm") == 0) { 43483f2a3aaSMatthew Dillon hammer_cmd_snaprm(av + 1, ac - 1); 43583f2a3aaSMatthew Dillon exit(0); 43683f2a3aaSMatthew Dillon } 4376b669ab4SMichael Neumann if (strcmp(av[0], "snapshot") == 0) { 4386b669ab4SMichael Neumann hammer_cmd_snapshot(av + 1, ac - 1); 4396b669ab4SMichael Neumann exit(0); 4406b669ab4SMichael Neumann } 44168e079b8SMatthew Dillon if (strcmp(av[0], "bstats") == 0) { 44268e079b8SMatthew Dillon hammer_cmd_bstats(av + 1, ac - 1); 44368e079b8SMatthew Dillon exit(0); 44468e079b8SMatthew Dillon } 44568e079b8SMatthew Dillon if (strcmp(av[0], "iostats") == 0) { 44668e079b8SMatthew Dillon hammer_cmd_iostats(av + 1, ac - 1); 44768e079b8SMatthew Dillon exit(0); 44868e079b8SMatthew Dillon } 44913ce745dSMatthew Dillon 45013ce745dSMatthew Dillon if (strncmp(av[0], "history", 7) == 0) { 45113ce745dSMatthew Dillon hammer_cmd_history(av[0] + 7, av + 1, ac - 1); 45213ce745dSMatthew Dillon exit(0); 45313ce745dSMatthew Dillon } 454797a0b63SMatthew Dillon if (strcmp(av[0], "rebalance") == 0) { 455797a0b63SMatthew Dillon signal(SIGINT, sigalrm); 456797a0b63SMatthew Dillon hammer_cmd_rebalance(av + 1, ac - 1); 457797a0b63SMatthew Dillon exit(0); 458797a0b63SMatthew Dillon } 459ba7b52c9SMatthew Dillon if (strncmp(av[0], "reblock", 7) == 0) { 4606a6e350fSMatthew Dillon signal(SIGINT, sigalrm); 461ba7b52c9SMatthew Dillon if (strcmp(av[0], "reblock") == 0) 462ba7b52c9SMatthew Dillon hammer_cmd_reblock(av + 1, ac - 1, -1); 463ba7b52c9SMatthew Dillon else if (strcmp(av[0], "reblock-btree") == 0) 464ba7b52c9SMatthew Dillon hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_BTREE); 46558c17893SMatthew Dillon else if (strcmp(av[0], "reblock-inodes") == 0) 46658c17893SMatthew Dillon hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_INODES); 4679e29c876SMatthew Dillon else if (strcmp(av[0], "reblock-dirs") == 0) 4689e29c876SMatthew Dillon hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_DIRS); 469ba7b52c9SMatthew Dillon else if (strcmp(av[0], "reblock-data") == 0) 470ba7b52c9SMatthew Dillon hammer_cmd_reblock(av + 1, ac - 1, HAMMER_IOC_DO_DATA); 471ba7b52c9SMatthew Dillon else 472ba7b52c9SMatthew Dillon usage(1); 4733f673d5cSMatthew Dillon exit(0); 4743f673d5cSMatthew Dillon } 475a7fbbf91SMatthew Dillon if (strncmp(av[0], "mirror", 6) == 0) { 476a7fbbf91SMatthew Dillon if (strcmp(av[0], "mirror-read") == 0) 47748eadef9SMatthew Dillon hammer_cmd_mirror_read(av + 1, ac - 1, 0); 4787a27dae7SMatthew Dillon else if (strcmp(av[0], "mirror-read-stream") == 0) 47948eadef9SMatthew Dillon hammer_cmd_mirror_read(av + 1, ac - 1, 1); 480a7fbbf91SMatthew Dillon else if (strcmp(av[0], "mirror-write") == 0) 481a7fbbf91SMatthew Dillon hammer_cmd_mirror_write(av + 1, ac - 1); 482a7fbbf91SMatthew Dillon else if (strcmp(av[0], "mirror-copy") == 0) 48348eadef9SMatthew Dillon hammer_cmd_mirror_copy(av + 1, ac - 1, 0); 48448eadef9SMatthew Dillon else if (strcmp(av[0], "mirror-stream") == 0) 48548eadef9SMatthew Dillon hammer_cmd_mirror_copy(av + 1, ac - 1, 1); 486243ca327SMatthew Dillon else if (strcmp(av[0], "mirror-dump") == 0) 487243ca327SMatthew Dillon hammer_cmd_mirror_dump(); 488a7fbbf91SMatthew Dillon else 489a7fbbf91SMatthew Dillon usage(1); 490a7fbbf91SMatthew Dillon exit(0); 491a7fbbf91SMatthew Dillon } 492bb29b5d8SMatthew Dillon if (strcmp(av[0], "dedup-simulate") == 0) { 493bb29b5d8SMatthew Dillon hammer_cmd_dedup_simulate(av + 1, ac - 1); 494bb29b5d8SMatthew Dillon exit(0); 495bb29b5d8SMatthew Dillon } 496bb29b5d8SMatthew Dillon if (strcmp(av[0], "dedup") == 0) { 497bb29b5d8SMatthew Dillon hammer_cmd_dedup(av + 1, ac - 1); 498bb29b5d8SMatthew Dillon exit(0); 499bb29b5d8SMatthew Dillon } 500de1c0b31SMatthew Dillon if (strcmp(av[0], "version") == 0) { 501de1c0b31SMatthew Dillon hammer_cmd_get_version(av + 1, ac - 1); 502de1c0b31SMatthew Dillon exit(0); 503de1c0b31SMatthew Dillon } 504de1c0b31SMatthew Dillon if (strcmp(av[0], "version-upgrade") == 0) { 505de1c0b31SMatthew Dillon hammer_cmd_set_version(av + 1, ac - 1); 506de1c0b31SMatthew Dillon exit(0); 507de1c0b31SMatthew Dillon } 508d121f61cSMichael Neumann if (strcmp(av[0], "volume-add") == 0) { 509d121f61cSMichael Neumann hammer_cmd_volume_add(av + 1, ac - 1); 510e27700cfSMichael Neumann exit(0); 511e27700cfSMichael Neumann } 512865c9609SMichael Neumann if (strcmp(av[0], "volume-del") == 0) { 513865c9609SMichael Neumann hammer_cmd_volume_del(av + 1, ac - 1); 514865c9609SMichael Neumann exit(0); 515865c9609SMichael Neumann } 516e914c91dSStathis Kamperis if (strcmp(av[0], "volume-list") == 0) { 517e914c91dSStathis Kamperis hammer_cmd_volume_list(av + 1, ac - 1); 518e914c91dSStathis Kamperis exit(0); 519e914c91dSStathis Kamperis } 52061aeeb33SMatthew Dillon 52161aeeb33SMatthew Dillon uuid_name_lookup(&Hammer_FSType, "DragonFly HAMMER", &status); 52261aeeb33SMatthew Dillon if (status != uuid_s_ok) { 52361aeeb33SMatthew Dillon errx(1, "uuids file does not have the DragonFly " 52461aeeb33SMatthew Dillon "HAMMER filesystem type"); 52561aeeb33SMatthew Dillon } 526d38ab092SMatthew Dillon 527d38ab092SMatthew Dillon if (strcmp(av[0], "show") == 0) { 528e7f926a5SMatthew Dillon u_int32_t lo = 0; 529a276dc6bSMatthew Dillon intmax_t obj_id = (int64_t)HAMMER_MIN_OBJID; 53061aeeb33SMatthew Dillon 531d38ab092SMatthew Dillon hammer_parsedevs(blkdevs); 532d38ab092SMatthew Dillon if (ac > 1) 533a276dc6bSMatthew Dillon sscanf(av[1], "%08x:%jx", &lo, &obj_id); 534a276dc6bSMatthew Dillon hammer_cmd_show(-1, lo, (int64_t)obj_id, 0, NULL, NULL); 535d38ab092SMatthew Dillon exit(0); 536d38ab092SMatthew Dillon } 5376aec797fSMatthew Dillon if (strcmp(av[0], "show-undo") == 0) { 5386aec797fSMatthew Dillon hammer_parsedevs(blkdevs); 5396aec797fSMatthew Dillon hammer_cmd_show_undo(); 5406aec797fSMatthew Dillon exit(0); 5416aec797fSMatthew Dillon } 542b9107f58SMatthew Dillon if (strcmp(av[0], "recover") == 0) { 543b9107f58SMatthew Dillon hammer_parsedevs(blkdevs); 544b9107f58SMatthew Dillon if (ac <= 1) 545b9107f58SMatthew Dillon errx(1, "hammer recover required target directory"); 546b9107f58SMatthew Dillon hammer_cmd_recover(av[1]); 547b9107f58SMatthew Dillon exit(0); 548b9107f58SMatthew Dillon } 549eb3f8f1fSMatthew Dillon if (strcmp(av[0], "blockmap") == 0) { 550eb3f8f1fSMatthew Dillon hammer_parsedevs(blkdevs); 551eb3f8f1fSMatthew Dillon hammer_cmd_blockmap(); 552eb3f8f1fSMatthew Dillon exit(0); 553eb3f8f1fSMatthew Dillon } 5546ed4c886SMatthew Dillon if (strcmp(av[0], "checkmap") == 0) { 5556ed4c886SMatthew Dillon hammer_parsedevs(blkdevs); 5566ed4c886SMatthew Dillon hammer_cmd_checkmap(); 5576ed4c886SMatthew Dillon exit(0); 5586ed4c886SMatthew Dillon } 5590dfeb6c8SMatthew Dillon usage(1); 5600dfeb6c8SMatthew Dillon /* not reached */ 5610dfeb6c8SMatthew Dillon return(0); 5620dfeb6c8SMatthew Dillon } 5630dfeb6c8SMatthew Dillon 5649c9ac2f1SMatthew Dillon /* 5659c9ac2f1SMatthew Dillon * Parse the device specification. 5669c9ac2f1SMatthew Dillon * 5679c9ac2f1SMatthew Dillon * Multi-volume hammer devices are colon-separated. Each element 5689c9ac2f1SMatthew Dillon * may be further expanded via /etc/devtab. One may also specify 5699c9ac2f1SMatthew Dillon * a single element which is expanded into multiple elements via 5709c9ac2f1SMatthew Dillon * /etc/devtab. 5719c9ac2f1SMatthew Dillon */ 5720dfeb6c8SMatthew Dillon static 5730dfeb6c8SMatthew Dillon void 574d38ab092SMatthew Dillon hammer_parsedevs(const char *blkdevs) 575d38ab092SMatthew Dillon { 576d38ab092SMatthew Dillon char *copy; 577d38ab092SMatthew Dillon char *volname; 578d38ab092SMatthew Dillon 579d38ab092SMatthew Dillon if (blkdevs == NULL) { 580f6532f03SThomas Nikolajsen errx(1, "A -f blkdevs specification is required " 581d38ab092SMatthew Dillon "for this command"); 582d38ab092SMatthew Dillon } 583d38ab092SMatthew Dillon 584d38ab092SMatthew Dillon copy = strdup(blkdevs); 585d38ab092SMatthew Dillon while ((volname = copy) != NULL) { 586d38ab092SMatthew Dillon if ((copy = strchr(copy, ':')) != NULL) 587d38ab092SMatthew Dillon *copy++ = 0; 5889c9ac2f1SMatthew Dillon volname = getdevpath(volname, 0); 5899c9ac2f1SMatthew Dillon if (strchr(volname, ':')) 5909c9ac2f1SMatthew Dillon hammer_parsedevs(volname); 5919c9ac2f1SMatthew Dillon else 592d38ab092SMatthew Dillon setup_volume(-1, volname, 0, O_RDONLY); 593d38ab092SMatthew Dillon } 594d38ab092SMatthew Dillon } 595d38ab092SMatthew Dillon 596d38ab092SMatthew Dillon static 597d38ab092SMatthew Dillon void 5980006adaeSMatthew Dillon sigalrm(int signo __unused) 5990006adaeSMatthew Dillon { 6000006adaeSMatthew Dillon /* do nothing (interrupts HAMMER ioctl) */ 6010006adaeSMatthew Dillon } 6020006adaeSMatthew Dillon 6030006adaeSMatthew Dillon static 6040006adaeSMatthew Dillon void 605445faa69SMatthew Dillon sigintr(int signo __unused) 606445faa69SMatthew Dillon { 607445faa69SMatthew Dillon if (RunningIoctl == 0) 608445faa69SMatthew Dillon _exit(1); 609445faa69SMatthew Dillon DidInterrupt = 1; 610445faa69SMatthew Dillon /* do nothing (interrupts HAMMER ioctl) */ 611445faa69SMatthew Dillon } 612445faa69SMatthew Dillon 613445faa69SMatthew Dillon static 614445faa69SMatthew Dillon void 6150dfeb6c8SMatthew Dillon usage(int exit_code) 6160dfeb6c8SMatthew Dillon { 6170dfeb6c8SMatthew Dillon fprintf(stderr, 6180dfeb6c8SMatthew Dillon "hammer -h\n" 6198ceaba31SSascha Wildner "hammer [-2BqrvXy] [-b bandwidth] [-C cachesize[:readahead]] [-c cyclefile]\n" 6203d7b2393SMatthew Dillon " [-f blkdevs] [-i delay] [-t seconds] [-S splitup]\n" 6213d7b2393SMatthew Dillon " command [argument ...]\n" 62284082922SThomas Nikolajsen "hammer synctid <filesystem> [quick]\n" 62384082922SThomas Nikolajsen "hammer bstats [interval]\n" 62484082922SThomas Nikolajsen "hammer iostats [interval]\n" 625bb8e52c0SThomas Nikolajsen "hammer history[@offset[,len]] <file> ...\n" 6265e435c92SMatthew Dillon "hammer namekey1 <path>\n" 6275e435c92SMatthew Dillon "hammer namekey2 <path>\n" 6284567021bSThomas Nikolajsen "hammer namekey32 <path>\n" 629bb8e52c0SThomas Nikolajsen "hammer cleanup [<filesystem> ...]\n" 630b66b9421SAntonio Huete "hammer info\n" 631bb8e52c0SThomas Nikolajsen "hammer snapshot [<filesystem>] <snapshot-dir>\n" 63216265794SThomas Nikolajsen "hammer snapshot <filesystem> <snapshot-dir> [<note>]\n" 633bb8e52c0SThomas Nikolajsen "hammer prune <softlink-dir>\n" 634bb8e52c0SThomas Nikolajsen "hammer prune-everything <filesystem>\n" 635797a0b63SMatthew Dillon "hammer rebalance <filesystem> [saturation_percentage]\n" 6364567021bSThomas Nikolajsen "hammer reblock[-btree|-inodes|-dirs|-data] " 63784082922SThomas Nikolajsen "<filesystem> [fill_percentage]\n" 63834bb69d8SThomas Nikolajsen "hammer pfs-status <dirpath> ...\n" 639d4e5b69bSMatthew Dillon "hammer pfs-master <dirpath> [options]\n" 640d4e5b69bSMatthew Dillon "hammer pfs-slave <dirpath> [options]\n" 64134ebae70SMatthew Dillon "hammer pfs-update <dirpath> [options]\n" 6429c67b4d2SMatthew Dillon "hammer pfs-upgrade <dirpath>\n" 6439c67b4d2SMatthew Dillon "hammer pfs-downgrade <dirpath>\n" 6449c67b4d2SMatthew Dillon "hammer pfs-destroy <dirpath>\n" 645bb8e52c0SThomas Nikolajsen "hammer mirror-read <filesystem> [begin-tid]\n" 646bb8e52c0SThomas Nikolajsen "hammer mirror-read-stream <filesystem> [begin-tid]\n" 647bb8e52c0SThomas Nikolajsen "hammer mirror-write <filesystem>\n" 648bb8e52c0SThomas Nikolajsen "hammer mirror-dump\n" 649bb8e52c0SThomas Nikolajsen "hammer mirror-copy [[user@]host:]<filesystem>" 650bb8e52c0SThomas Nikolajsen " [[user@]host:]<filesystem>\n" 651bb8e52c0SThomas Nikolajsen "hammer mirror-stream [[user@]host:]<filesystem>" 652bb8e52c0SThomas Nikolajsen " [[user@]host:]<filesystem>\n" 653*69f5a58cSMatthew Dillon "hammer ssh-remote command filesystem\n" 6545e435c92SMatthew Dillon "hammer version <filesystem>\n" 6554567021bSThomas Nikolajsen "hammer version-upgrade <filesystem> <version> [force]\n" 656d121f61cSMichael Neumann "hammer volume-add <device> <filesystem>\n" 657865c9609SMichael Neumann "hammer volume-del <device> <filesystem>\n" 658e914c91dSStathis Kamperis "hammer volume-list <filesystem>\n" 6590dfeb6c8SMatthew Dillon ); 66083f2a3aaSMatthew Dillon 661f6532f03SThomas Nikolajsen fprintf(stderr, "\nHAMMER utility version 3+ commands:\n"); 66283f2a3aaSMatthew Dillon 66383f2a3aaSMatthew Dillon fprintf(stderr, 66483f2a3aaSMatthew Dillon "hammer config [<filesystem> [<configfile>]]\n" 66583f2a3aaSMatthew Dillon "hammer viconfig [<filesystem>]\n" 666f6532f03SThomas Nikolajsen "hammer snap <path> [<note>]\n" 667f6532f03SThomas Nikolajsen "hammer snaplo <path> [<note>]\n" 668f6532f03SThomas Nikolajsen "hammer snapq <dir> [<note>]\n" 669aaf93065SThomas Nikolajsen "hammer snaprm <path> ...\n" 670aaf93065SThomas Nikolajsen "hammer snaprm <transid> ...\n" 671aaf93065SThomas Nikolajsen "hammer snaprm <filesystem> <transid> ...\n" 672f6532f03SThomas Nikolajsen "hammer snapls [<path> ...]\n" 673f6532f03SThomas Nikolajsen ); 674f6532f03SThomas Nikolajsen 675f6532f03SThomas Nikolajsen fprintf(stderr, "\nHAMMER utility version 4+ commands:\n"); 676f6532f03SThomas Nikolajsen 677f6532f03SThomas Nikolajsen fprintf(stderr, 678c71cab34SMatthew Dillon "hammer -f blkdevs blockmap\n" 679c71cab34SMatthew Dillon "hammer -f blkdevs checkmap\n" 680c71cab34SMatthew Dillon "hammer -f blkdevs [-qqq] show [lo:objid]\n" 681f6532f03SThomas Nikolajsen "hammer -f blkdevs show-undo\n" 682b9107f58SMatthew Dillon "hammer -f blkdevs recover <target_dir>\n" 68383f2a3aaSMatthew Dillon ); 68483f2a3aaSMatthew Dillon 685bb29b5d8SMatthew Dillon fprintf(stderr, "\nHAMMER utility version 5+ commands:\n"); 686bb29b5d8SMatthew Dillon 687bb29b5d8SMatthew Dillon fprintf(stderr, 688bb29b5d8SMatthew Dillon "hammer dedup-simulate <filesystem>\n" 689bb29b5d8SMatthew Dillon "hammer dedup <filesystem>\n" 690bb29b5d8SMatthew Dillon ); 691bb29b5d8SMatthew Dillon 6920dfeb6c8SMatthew Dillon exit(exit_code); 6930dfeb6c8SMatthew Dillon } 694d38ab092SMatthew Dillon 695