]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - tools/tools/zfsboottest/zfsboottest.c
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / tools / tools / zfsboottest / zfsboottest.c
1 /*-
2  * Copyright (c) 2010 Doug Rabson
3  * Copyright (c) 2011 Andriy Gapon
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 /* $FreeBSD$ */
28
29 #include <sys/param.h>
30 #include <sys/queue.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <stdint.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdarg.h>
37 #include <stddef.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40
41 #define NBBY 8
42
43 void
44 pager_output(const char *line)
45 {
46         fprintf(stderr, "%s", line);
47 }
48
49 #define ZFS_TEST
50 #define printf(...)      fprintf(stderr, __VA_ARGS__)
51 #include "zfsimpl.c"
52 #undef printf
53
54 static int
55 vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
56 {
57         int fd = *(int *) priv;
58
59         if (pread(fd, buf, bytes, off) != bytes)
60                 return (-1);
61         return (0);
62 }
63
64 static int
65 zfs_read(spa_t *spa, dnode_phys_t *dn, void *buf, size_t size, off_t off)
66 {
67         const znode_phys_t *zp = (const znode_phys_t *) dn->dn_bonus;
68         size_t n;
69         int rc;
70
71         n = size;
72         if (off + n > zp->zp_size)
73                 n = zp->zp_size - off;
74
75         rc = dnode_read(spa, dn, off, buf, n);
76         if (rc)
77                 return (-rc);
78
79         return (n);
80 }
81
82 int
83 main(int argc, char** argv)
84 {
85         char buf[512];
86         int fd[100];
87         struct stat sb;
88         dnode_phys_t dn;
89         spa_t *spa;
90         off_t off;
91         ssize_t n;
92         int i;
93
94         zfs_init();
95         if (argc == 1) {
96                 static char *av[] = {
97                         "zfstest", "COPYRIGHT",
98                         "/dev/da0p2", "/dev/da1p2", "/dev/da2p2",
99                         NULL,
100                 };
101                 argc = 5;
102                 argv = av;
103         }
104         for (i = 2; i < argc; i++) {
105                 fd[i] = open(argv[i], O_RDONLY);
106                 if (fd[i] < 0)
107                         continue;
108                 if (vdev_probe(vdev_read, &fd[i], NULL) != 0)
109                         close(fd[i]);
110         }
111         spa_all_status();
112
113         spa = STAILQ_FIRST(&zfs_pools);
114         if (spa == NULL) {
115                 fprintf(stderr, "no pools\n");
116                 exit(1);
117         }
118
119         if (zfs_mount_pool(spa)) {
120                 fprintf(stderr, "can't mount pool\n");
121                 exit(1);
122         }
123
124         if (zfs_lookup(spa, argv[1], &dn)) {
125                 fprintf(stderr, "can't lookup\n");
126                 exit(1);
127         }
128
129         if (zfs_dnode_stat(spa, &dn, &sb)) {
130                 fprintf(stderr, "can't stat\n");
131                 exit(1);
132         }
133
134
135         off = 0;
136         do {
137                 n = sb.st_size - off;
138                 n = n > sizeof(buf) ? sizeof(buf) : n;
139                 n = zfs_read(spa, &dn, buf, n, off);
140                 if (n < 0) {
141                         fprintf(stderr, "zfs_read failed\n");
142                         exit(1);
143                 }
144                 write(1, buf, n);
145                 off += n;
146         } while (off < sb.st_size);
147
148         return (0);
149 }