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 * 34*563b4845SMatthew Dillon * $DragonFly: src/sbin/hammer/hammer.c,v 1.6 2008/01/25 05:53:41 dillon Exp $ 350dfeb6c8SMatthew Dillon */ 360dfeb6c8SMatthew Dillon 3761aeeb33SMatthew Dillon #include "hammer.h" 380dfeb6c8SMatthew Dillon 390dfeb6c8SMatthew Dillon static void hammer_parsetime(u_int64_t *tidp, const char *timestr); 40d38ab092SMatthew Dillon static void hammer_parsedevs(const char *blkdevs); 410dfeb6c8SMatthew Dillon static void usage(int exit_code); 420dfeb6c8SMatthew Dillon 43d38ab092SMatthew Dillon int RecurseOpt; 44*563b4845SMatthew Dillon int VerboseOpt; 45d38ab092SMatthew Dillon 460dfeb6c8SMatthew Dillon int 470dfeb6c8SMatthew Dillon main(int ac, char **av) 480dfeb6c8SMatthew Dillon { 490dfeb6c8SMatthew Dillon u_int64_t tid; 500dfeb6c8SMatthew Dillon int ch; 5161aeeb33SMatthew Dillon int status; 52d38ab092SMatthew Dillon char *blkdevs = NULL; 530dfeb6c8SMatthew Dillon 54*563b4845SMatthew Dillon while ((ch = getopt(ac, av, "hf:rv")) != -1) { 550dfeb6c8SMatthew Dillon switch(ch) { 560dfeb6c8SMatthew Dillon case 'h': 570dfeb6c8SMatthew Dillon usage(0); 580dfeb6c8SMatthew Dillon /* not reached */ 59d38ab092SMatthew Dillon case 'r': 60d38ab092SMatthew Dillon RecurseOpt = 1; 61d38ab092SMatthew Dillon break; 62d38ab092SMatthew Dillon case 'f': 63d38ab092SMatthew Dillon blkdevs = optarg; 64d38ab092SMatthew Dillon break; 65*563b4845SMatthew Dillon case 'v': 66*563b4845SMatthew Dillon ++VerboseOpt; 67*563b4845SMatthew Dillon break; 680dfeb6c8SMatthew Dillon default: 690dfeb6c8SMatthew Dillon usage(1); 700dfeb6c8SMatthew Dillon /* not reached */ 710dfeb6c8SMatthew Dillon } 720dfeb6c8SMatthew Dillon } 730dfeb6c8SMatthew Dillon ac -= optind; 740dfeb6c8SMatthew Dillon av += optind; 750dfeb6c8SMatthew Dillon if (ac < 1) { 760dfeb6c8SMatthew Dillon usage(1); 770dfeb6c8SMatthew Dillon /* not reached */ 780dfeb6c8SMatthew Dillon } 790dfeb6c8SMatthew Dillon 800dfeb6c8SMatthew Dillon if (strcmp(av[0], "now") == 0) { 810dfeb6c8SMatthew Dillon hammer_parsetime(&tid, "0s"); 820dfeb6c8SMatthew Dillon printf("0x%08x\n", (int)(tid / 1000000000LL)); 8361aeeb33SMatthew Dillon exit(0); 8461aeeb33SMatthew Dillon } 8561aeeb33SMatthew Dillon if (strcmp(av[0], "stamp") == 0) { 860dfeb6c8SMatthew Dillon if (av[1] == NULL) 870dfeb6c8SMatthew Dillon usage(1); 880dfeb6c8SMatthew Dillon hammer_parsetime(&tid, av[1]); 890dfeb6c8SMatthew Dillon printf("0x%08x\n", (int)(tid / 1000000000LL)); 9061aeeb33SMatthew Dillon exit(0); 9161aeeb33SMatthew Dillon } 92cbd800c2SMatthew Dillon if (strcmp(av[0], "namekey") == 0) { 93cbd800c2SMatthew Dillon int64_t key; 94cbd800c2SMatthew Dillon 95cbd800c2SMatthew Dillon if (av[1] == NULL) 96cbd800c2SMatthew Dillon usage(1); 97cbd800c2SMatthew Dillon key = (int64_t)(crc32(av[1], strlen(av[1])) & 0x7FFFFFFF) << 32; 98cbd800c2SMatthew Dillon if (key == 0) 99cbd800c2SMatthew Dillon key |= 0x100000000LL; 100cbd800c2SMatthew Dillon printf("0x%016llx\n", key); 101cbd800c2SMatthew Dillon exit(0); 102cbd800c2SMatthew Dillon } 103cbd800c2SMatthew Dillon if (strcmp(av[0], "namekey32") == 0) { 104cbd800c2SMatthew Dillon int32_t key; 105cbd800c2SMatthew Dillon 106cbd800c2SMatthew Dillon if (av[1] == NULL) 107cbd800c2SMatthew Dillon usage(1); 108cbd800c2SMatthew Dillon key = crc32(av[1], strlen(av[1])) & 0x7FFFFFFF; 109cbd800c2SMatthew Dillon if (key == 0) 110cbd800c2SMatthew Dillon ++key; 111cbd800c2SMatthew Dillon printf("0x%08x\n", key); 112cbd800c2SMatthew Dillon exit(0); 113cbd800c2SMatthew Dillon } 11461aeeb33SMatthew Dillon 11561aeeb33SMatthew Dillon uuid_name_lookup(&Hammer_FSType, "DragonFly HAMMER", &status); 11661aeeb33SMatthew Dillon if (status != uuid_s_ok) { 11761aeeb33SMatthew Dillon errx(1, "uuids file does not have the DragonFly " 11861aeeb33SMatthew Dillon "HAMMER filesystem type"); 11961aeeb33SMatthew Dillon } 120d38ab092SMatthew Dillon 12161aeeb33SMatthew Dillon init_alist_templates(); 122d38ab092SMatthew Dillon if (strcmp(av[0], "show") == 0) { 123d38ab092SMatthew Dillon int32_t vol_no = -1; 124d38ab092SMatthew Dillon int32_t clu_no = -1; 12561aeeb33SMatthew Dillon 126d38ab092SMatthew Dillon hammer_parsedevs(blkdevs); 127d38ab092SMatthew Dillon if (ac > 1) 128d38ab092SMatthew Dillon sscanf(av[1], "%d:%d", &vol_no, &clu_no); 129d38ab092SMatthew Dillon hammer_cmd_show(vol_no, clu_no, 0); 130d38ab092SMatthew Dillon exit(0); 131d38ab092SMatthew Dillon } 1320dfeb6c8SMatthew Dillon usage(1); 1330dfeb6c8SMatthew Dillon /* not reached */ 1340dfeb6c8SMatthew Dillon return(0); 1350dfeb6c8SMatthew Dillon } 1360dfeb6c8SMatthew Dillon 1370dfeb6c8SMatthew Dillon /* 1380dfeb6c8SMatthew Dillon * Parse a timestamp for the mount point 1390dfeb6c8SMatthew Dillon * 1400dfeb6c8SMatthew Dillon * yyyymmddhhmmss 1410dfeb6c8SMatthew Dillon * -N[s/h/d/m/y] 1420dfeb6c8SMatthew Dillon */ 1430dfeb6c8SMatthew Dillon static 1440dfeb6c8SMatthew Dillon void 1450dfeb6c8SMatthew Dillon hammer_parsetime(u_int64_t *tidp, const char *timestr) 1460dfeb6c8SMatthew Dillon { 1470dfeb6c8SMatthew Dillon struct tm tm; 1480dfeb6c8SMatthew Dillon time_t t; 1490dfeb6c8SMatthew Dillon int32_t n; 1500dfeb6c8SMatthew Dillon char c; 1510dfeb6c8SMatthew Dillon double seconds = 0; 1520dfeb6c8SMatthew Dillon 1530dfeb6c8SMatthew Dillon t = time(NULL); 1540dfeb6c8SMatthew Dillon 1550dfeb6c8SMatthew Dillon if (*timestr == 0) 1560dfeb6c8SMatthew Dillon usage(1); 1570dfeb6c8SMatthew Dillon 1580dfeb6c8SMatthew Dillon if (isalpha(timestr[strlen(timestr)-1])) { 1590dfeb6c8SMatthew Dillon if (sscanf(timestr, "%d%c", &n, &c) != 2) 1600dfeb6c8SMatthew Dillon usage(1); 1610dfeb6c8SMatthew Dillon switch(c) { 1620dfeb6c8SMatthew Dillon case 'Y': 1630dfeb6c8SMatthew Dillon n *= 365; 1640dfeb6c8SMatthew Dillon goto days; 1650dfeb6c8SMatthew Dillon case 'M': 1660dfeb6c8SMatthew Dillon n *= 30; 1670dfeb6c8SMatthew Dillon /* fall through */ 1680dfeb6c8SMatthew Dillon case 'D': 1690dfeb6c8SMatthew Dillon days: 1700dfeb6c8SMatthew Dillon n *= 24; 1710dfeb6c8SMatthew Dillon /* fall through */ 1720dfeb6c8SMatthew Dillon case 'h': 1730dfeb6c8SMatthew Dillon n *= 60; 1740dfeb6c8SMatthew Dillon /* fall through */ 1750dfeb6c8SMatthew Dillon case 'm': 1760dfeb6c8SMatthew Dillon n *= 60; 1770dfeb6c8SMatthew Dillon /* fall through */ 1780dfeb6c8SMatthew Dillon case 's': 1790dfeb6c8SMatthew Dillon t -= n; 1800dfeb6c8SMatthew Dillon break; 1810dfeb6c8SMatthew Dillon default: 1820dfeb6c8SMatthew Dillon usage(1); 1830dfeb6c8SMatthew Dillon } 1840dfeb6c8SMatthew Dillon } else { 1850dfeb6c8SMatthew Dillon localtime_r(&t, &tm); 1860dfeb6c8SMatthew Dillon seconds = (double)tm.tm_sec; 187bc618a92SMatthew Dillon tm.tm_year += 1900; 188bc618a92SMatthew Dillon tm.tm_mon += 1; 1890dfeb6c8SMatthew Dillon n = sscanf(timestr, "%4d%2d%2d:%2d%2d%lf", 1900dfeb6c8SMatthew Dillon &tm.tm_year, &tm.tm_mon, &tm.tm_mday, 1910dfeb6c8SMatthew Dillon &tm.tm_hour, &tm.tm_min, &seconds); 192bc618a92SMatthew Dillon tm.tm_mon -= 1; 193bc618a92SMatthew Dillon tm.tm_year -= 1900; 194bc618a92SMatthew Dillon /* if [:hhmmss] is omitted, assume :000000.0 */ 195bc618a92SMatthew Dillon if (n < 4) 196bc618a92SMatthew Dillon tm.tm_hour = tm.tm_min = tm.tm_sec = 0; 197bc618a92SMatthew Dillon else 1980dfeb6c8SMatthew Dillon tm.tm_sec = (int)seconds; 1990dfeb6c8SMatthew Dillon t = mktime(&tm); 2000dfeb6c8SMatthew Dillon } 2010dfeb6c8SMatthew Dillon *tidp = (u_int64_t)t * 1000000000 + 2020dfeb6c8SMatthew Dillon (seconds - (int)seconds) * 1000000000; 2030dfeb6c8SMatthew Dillon } 2040dfeb6c8SMatthew Dillon 2050dfeb6c8SMatthew Dillon static 2060dfeb6c8SMatthew Dillon void 207d38ab092SMatthew Dillon hammer_parsedevs(const char *blkdevs) 208d38ab092SMatthew Dillon { 209d38ab092SMatthew Dillon char *copy; 210d38ab092SMatthew Dillon char *volname; 211d38ab092SMatthew Dillon 212d38ab092SMatthew Dillon if (blkdevs == NULL) { 213d38ab092SMatthew Dillon errx(1, "A -f blkdevs specification is required " 214d38ab092SMatthew Dillon "for this command"); 215d38ab092SMatthew Dillon } 216d38ab092SMatthew Dillon 217d38ab092SMatthew Dillon copy = strdup(blkdevs); 218d38ab092SMatthew Dillon while ((volname = copy) != NULL) { 219d38ab092SMatthew Dillon if ((copy = strchr(copy, ':')) != NULL) 220d38ab092SMatthew Dillon *copy++ = 0; 221d38ab092SMatthew Dillon setup_volume(-1, volname, 0, O_RDONLY); 222d38ab092SMatthew Dillon } 223d38ab092SMatthew Dillon } 224d38ab092SMatthew Dillon 225d38ab092SMatthew Dillon static 226d38ab092SMatthew Dillon void 2270dfeb6c8SMatthew Dillon usage(int exit_code) 2280dfeb6c8SMatthew Dillon { 2290dfeb6c8SMatthew Dillon fprintf(stderr, 2300dfeb6c8SMatthew Dillon "hammer -h\n" 2310dfeb6c8SMatthew Dillon "hammer now\n" 2320dfeb6c8SMatthew Dillon "hammer stamp <time>\n" 233d38ab092SMatthew Dillon "hammer -f blkdevs [-r] show [vol_no[:clu_no]]\n" 2340dfeb6c8SMatthew Dillon ); 2350dfeb6c8SMatthew Dillon fprintf(stderr, " time: +n[s/m/h/D/M/Y]\n" 2360dfeb6c8SMatthew Dillon " time: yyyymmdd[:hhmmss]\n"); 2370dfeb6c8SMatthew Dillon exit(exit_code); 2380dfeb6c8SMatthew Dillon } 239d38ab092SMatthew Dillon 240