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