xref: /dragonfly/sbin/hammer/hammer.c (revision 563b4845)
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