zfsboottest.c revision 254035
1166551Smarcel/*-
2188723Smarcel * Copyright (c) 2010 Doug Rabson
3166551Smarcel * Copyright (c) 2011 Andriy Gapon
4166551Smarcel * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>
5166551Smarcel * All rights reserved.
6166551Smarcel *
7166551Smarcel * Redistribution and use in source and binary forms, with or without
8166551Smarcel * modification, are permitted provided that the following conditions
9166551Smarcel * are met:
10166551Smarcel * 1. Redistributions of source code must retain the above copyright
11166551Smarcel *    notice, this list of conditions and the following disclaimer.
12166551Smarcel * 2. Redistributions in binary form must reproduce the above copyright
13166551Smarcel *    notice, this list of conditions and the following disclaimer in the
14166551Smarcel *    documentation and/or other materials provided with the distribution.
15166551Smarcel *
16166551Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17166551Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18166551Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19166551Smarcel * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20166551Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21166551Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22166551Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23166551Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24166551Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25166551Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26166551Smarcel * SUCH DAMAGE.
27166551Smarcel */
28166551Smarcel/* $FreeBSD: stable/9/tools/tools/zfsboottest/zfsboottest.c 254035 2013-08-07 07:31:21Z avg $ */
29166551Smarcel
30166551Smarcel#include <sys/param.h>
31166551Smarcel#include <sys/queue.h>
32166551Smarcel#include <err.h>
33166551Smarcel#include <errno.h>
34166551Smarcel#include <fcntl.h>
35166561Srodrigc#include <md5.h>
36166551Smarcel#include <stdint.h>
37166551Smarcel#include <stdio.h>
38166551Smarcel#include <string.h>
39166551Smarcel#include <stdarg.h>
40166551Smarcel#include <stddef.h>
41166551Smarcel#include <stdlib.h>
42166551Smarcel#include <unistd.h>
43188723Smarcel
44188723Smarcel#define NBBY 8
45191130Smarcel
46191130Smarcelvoid
47191130Smarcelpager_output(const char *line)
48191130Smarcel{
49191130Smarcel
50191130Smarcel	fprintf(stderr, "%s", line);
51191130Smarcel}
52191130Smarcel
53191130Smarcel#define ZFS_TEST
54191130Smarcel#define	printf(...)	 fprintf(stderr, __VA_ARGS__)
55188723Smarcel#include "libzfs.h"
56188723Smarcel#include "zfsimpl.c"
57188723Smarcel#undef printf
58188723Smarcel
59188723Smarcelstatic int
60188723Smarcelvdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
61207094Smarcel{
62207094Smarcel	int fd = *(int *)priv;
63207094Smarcel
64207094Smarcel	if (pread(fd, buf, bytes, off) != bytes)
65207094Smarcel		return (-1);
66207094Smarcel	return (0);
67207094Smarcel}
68214352Sae
69214352Saestatic int
70214352Saezfs_read(spa_t *spa, dnode_phys_t *dn, void *buf, size_t size, off_t off)
71214352Sae{
72214352Sae	const znode_phys_t *zp = (const znode_phys_t *) dn->dn_bonus;
73214352Sae	size_t n;
74188723Smarcel	int rc;
75188723Smarcel
76166551Smarcel	n = size;
77166551Smarcel	if (off + n > zp->zp_size)
78166551Smarcel		n = zp->zp_size - off;
79166551Smarcel
80166551Smarcel	rc = dnode_read(spa, dn, off, buf, n);
81166551Smarcel	if (rc != 0)
82166551Smarcel		return (-rc);
83178180Smarcel
84178180Smarcel	return (n);
85178180Smarcel}
86178180Smarcel
87178180Smarcelint
88178180Smarcelmain(int argc, char** argv)
89166551Smarcel{
90166551Smarcel	char buf[512], hash[33];
91166551Smarcel	MD5_CTX ctx;
92166551Smarcel	struct stat sb;
93166551Smarcel	struct zfsmount zfsmnt;
94166551Smarcel	dnode_phys_t dn;
95166551Smarcel#if 0
96166551Smarcel	uint64_t rootobj;
97166551Smarcel#endif
98166551Smarcel	spa_t *spa;
99166551Smarcel	off_t off;
100166551Smarcel	ssize_t n;
101166551Smarcel	int i, failures, *fd;
102166551Smarcel
103166551Smarcel	zfs_init();
104166551Smarcel	if (argc == 1) {
105166551Smarcel		static char *av[] = {
106166551Smarcel			"zfsboottest",
107166551Smarcel			"/dev/gpt/system0",
108166551Smarcel			"/dev/gpt/system1",
109166551Smarcel			"-",
110166551Smarcel			"/boot/zfsloader",
111166551Smarcel			"/boot/support.4th",
112166551Smarcel			"/boot/kernel/kernel",
113166551Smarcel			NULL,
114166551Smarcel		};
115191130Smarcel		argc = sizeof(av) / sizeof(av[0]) - 1;
116191130Smarcel		argv = av;
117191130Smarcel	}
118191130Smarcel	for (i = 1; i < argc; i++) {
119191130Smarcel		if (strcmp(argv[i], "-") == 0)
120191130Smarcel			break;
121191130Smarcel	}
122191130Smarcel	fd = malloc(sizeof(fd[0]) * (i - 1));
123166551Smarcel	if (fd == NULL)
124166551Smarcel		errx(1, "Unable to allocate memory.");
125166551Smarcel	for (i = 1; i < argc; i++) {
126166551Smarcel		if (strcmp(argv[i], "-") == 0)
127166551Smarcel			break;
128166551Smarcel		fd[i - 1] = open(argv[i], O_RDONLY);
129166551Smarcel		if (fd[i - 1] == -1) {
130207094Smarcel			warn("open(%s) failed", argv[i]);
131207094Smarcel			continue;
132207094Smarcel		}
133207094Smarcel		if (vdev_probe(vdev_read, &fd[i - 1], NULL) != 0) {
134207094Smarcel			warnx("vdev_probe(%s) failed", argv[i]);
135207094Smarcel			close(fd[i - 1]);
136207094Smarcel		}
137166551Smarcel	}
138166551Smarcel
139166551Smarcel	spa = STAILQ_FIRST(&zfs_pools);
140166551Smarcel	if (spa == NULL) {
141166551Smarcel		fprintf(stderr, "no pools\n");
142166551Smarcel		exit(1);
143166551Smarcel	}
144166551Smarcel
145166551Smarcel	if (zfs_spa_init(spa)) {
146188659Smarcel		fprintf(stderr, "can't init pool\n");
147188659Smarcel		exit(1);
148188659Smarcel	}
149188659Smarcel
150188659Smarcel	spa_all_status();
151188659Smarcel
152188659Smarcel#if 0
153188659Smarcel	uint64_t rootobj;
154188659Smarcel	if (zfs_get_root(spa, &rootobj)) {
155188659Smarcel		fprintf(stderr, "can't get root\n");
156188659Smarcel		exit(1);
157188723Smarcel	}
158188659Smarcel
159166551Smarcel	if (zfs_mount(spa, rootobj, &zfsmnt)) {
160166551Smarcel#else
161166551Smarcel	if (zfs_mount(spa, 0, &zfsmnt)) {
162166551Smarcel		fprintf(stderr, "can't mount\n");
163166551Smarcel		exit(1);
164166551Smarcel#endif
165166551Smarcel	}
166166551Smarcel
167166551Smarcel	printf("\n");
168166551Smarcel	for (++i, failures = 0; i < argc; i++) {
169166551Smarcel		if (zfs_lookup(&zfsmnt, argv[i], &dn)) {
170166551Smarcel			fprintf(stderr, "%s: can't lookup\n", argv[i]);
171166551Smarcel			failures++;
172214352Sae			continue;
173214352Sae		}
174214352Sae
175214352Sae		if (zfs_dnode_stat(spa, &dn, &sb)) {
176214352Sae			fprintf(stderr, "%s: can't stat\n", argv[i]);
177179853Smarcel			failures++;
178179853Smarcel			continue;
179179853Smarcel		}
180179853Smarcel
181179853Smarcel		off = 0;
182179853Smarcel		MD5Init(&ctx);
183179853Smarcel		do {
184179853Smarcel			n = sb.st_size - off;
185166551Smarcel			n = n > sizeof(buf) ? sizeof(buf) : n;
186166551Smarcel			n = zfs_read(spa, &dn, buf, n, off);
187166551Smarcel			if (n < 0) {
188166551Smarcel				fprintf(stderr, "%s: zfs_read failed\n",
189166551Smarcel				    argv[i]);
190166551Smarcel				failures++;
191166551Smarcel				break;
192166551Smarcel			}
193166551Smarcel			MD5Update(&ctx, buf, n);
194166551Smarcel			off += n;
195166551Smarcel		} while (off < sb.st_size);
196166551Smarcel		if (off < sb.st_size)
197166551Smarcel			continue;
198166551Smarcel		MD5End(&ctx, hash);
199		printf("%s %s\n", hash, argv[i]);
200	}
201
202	return (failures == 0 ? 0 : 1);
203}
204