zfsboottest.c revision 225609
1210650Sdfr/*-
2210650Sdfr * Copyright (c) 2010 Doug Rabson
3225609Savg * Copyright (c) 2011 Andriy Gapon
4210650Sdfr * All rights reserved.
5210650Sdfr *
6210650Sdfr * Redistribution and use in source and binary forms, with or without
7210650Sdfr * modification, are permitted provided that the following conditions
8210650Sdfr * are met:
9210650Sdfr * 1. Redistributions of source code must retain the above copyright
10210650Sdfr *    notice, this list of conditions and the following disclaimer.
11210650Sdfr * 2. Redistributions in binary form must reproduce the above copyright
12210650Sdfr *    notice, this list of conditions and the following disclaimer in the
13210650Sdfr *    documentation and/or other materials provided with the distribution.
14210650Sdfr *
15210650Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16210650Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17210650Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18210650Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19210650Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20210650Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21210650Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22210650Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23210650Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24210650Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25210650Sdfr * SUCH DAMAGE.
26210650Sdfr */
27210650Sdfr/* $FreeBSD: head/tools/tools/zfsboottest/zfsboottest.c 225609 2011-09-16 08:24:31Z avg $ */
28210650Sdfr
29210650Sdfr#include <sys/param.h>
30210650Sdfr#include <sys/queue.h>
31225529Savg#include <errno.h>
32210650Sdfr#include <fcntl.h>
33210650Sdfr#include <stdint.h>
34210650Sdfr#include <stdio.h>
35210650Sdfr#include <string.h>
36210650Sdfr#include <stdarg.h>
37210650Sdfr#include <stddef.h>
38210650Sdfr#include <stdlib.h>
39225529Savg#include <unistd.h>
40210650Sdfr
41210650Sdfr#define NBBY 8
42210650Sdfr
43210650Sdfrvoid
44210650Sdfrpager_output(const char *line)
45210650Sdfr{
46225529Savg	fprintf(stderr, "%s", line);
47210650Sdfr}
48210650Sdfr
49225609Savg#define ZFS_TEST
50225609Savg#define	printf(...)	 fprintf(stderr, __VA_ARGS__)
51210650Sdfr#include "zfsimpl.c"
52225609Savg#undef printf
53210650Sdfr
54210650Sdfrstatic int
55210650Sdfrvdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
56210650Sdfr{
57210650Sdfr	int fd = *(int *) priv;
58210650Sdfr
59210650Sdfr	if (pread(fd, buf, bytes, off) != bytes)
60225529Savg		return (-1);
61225529Savg	return (0);
62210650Sdfr}
63210650Sdfr
64210650Sdfrstatic int
65210650Sdfrzfs_read(spa_t *spa, dnode_phys_t *dn, void *buf, size_t size, off_t off)
66210650Sdfr{
67210650Sdfr	const znode_phys_t *zp = (const znode_phys_t *) dn->dn_bonus;
68210650Sdfr	size_t n;
69210650Sdfr	int rc;
70210650Sdfr
71210650Sdfr	n = size;
72210650Sdfr	if (off + n > zp->zp_size)
73210650Sdfr		n = zp->zp_size - off;
74225529Savg
75210650Sdfr	rc = dnode_read(spa, dn, off, buf, n);
76210650Sdfr	if (rc)
77225529Savg		return (-rc);
78210650Sdfr
79210650Sdfr	return (n);
80210650Sdfr}
81210650Sdfr
82210650Sdfrint
83210650Sdfrmain(int argc, char** argv)
84210650Sdfr{
85225529Savg	char buf[512];
86225529Savg	int fd[100];
87225529Savg	struct stat sb;
88225529Savg	dnode_phys_t dn;
89225529Savg	spa_t *spa;
90225609Savg	off_t off;
91225609Savg	ssize_t n;
92225609Savg	int i;
93210650Sdfr
94210650Sdfr	zfs_init();
95210650Sdfr	if (argc == 1) {
96210650Sdfr		static char *av[] = {
97225529Savg			"zfstest", "COPYRIGHT",
98225529Savg			"/dev/da0p2", "/dev/da1p2", "/dev/da2p2",
99210650Sdfr			NULL,
100210650Sdfr		};
101225529Savg		argc = 5;
102210650Sdfr		argv = av;
103210650Sdfr	}
104225529Savg	for (i = 2; i < argc; i++) {
105210650Sdfr		fd[i] = open(argv[i], O_RDONLY);
106210650Sdfr		if (fd[i] < 0)
107210650Sdfr			continue;
108210650Sdfr		if (vdev_probe(vdev_read, &fd[i], NULL) != 0)
109210650Sdfr			close(fd[i]);
110210650Sdfr	}
111210650Sdfr	spa_all_status();
112210650Sdfr
113210650Sdfr	spa = STAILQ_FIRST(&zfs_pools);
114225529Savg	if (spa == NULL) {
115225529Savg		fprintf(stderr, "no pools\n");
116210650Sdfr		exit(1);
117225529Savg	}
118210650Sdfr
119225529Savg	if (zfs_mount_pool(spa)) {
120225529Savg		fprintf(stderr, "can't mount pool\n");
121210650Sdfr		exit(1);
122225529Savg	}
123210650Sdfr
124225529Savg	if (zfs_lookup(spa, argv[1], &dn)) {
125225529Savg		fprintf(stderr, "can't lookup\n");
126225529Savg		exit(1);
127225529Savg	}
128225529Savg
129225529Savg	if (zfs_dnode_stat(spa, &dn, &sb)) {
130225529Savg		fprintf(stderr, "can't stat\n");
131225529Savg		exit(1);
132225529Savg	}
133225529Savg
134225529Savg
135210650Sdfr	off = 0;
136210650Sdfr	do {
137225609Savg		n = sb.st_size - off;
138225609Savg		n = n > sizeof(buf) ? sizeof(buf) : n;
139225609Savg		n = zfs_read(spa, &dn, buf, n, off);
140225529Savg		if (n < 0) {
141225529Savg			fprintf(stderr, "zfs_read failed\n");
142225529Savg			exit(1);
143225529Savg		}
144210650Sdfr		write(1, buf, n);
145210650Sdfr		off += n;
146225529Savg	} while (off < sb.st_size);
147225529Savg
148225529Savg	return (0);
149210650Sdfr}
150