zfsboottest.sh revision 254037
1295041Sbr#!/bin/sh
2295041Sbr#
3295041Sbr# Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>
4295041Sbr# All rights reserved.
5295041Sbr#
6295041Sbr# Redistribution and use in source and binary forms, with or without
7295041Sbr# modification, are permitted provided that the following conditions
8295041Sbr# are met:
9295041Sbr# 1. Redistributions of source code must retain the above copyright
10295041Sbr#    notice, this list of conditions and the following disclaimer.
11295041Sbr# 2. Redistributions in binary form must reproduce the above copyright
12295041Sbr#    notice, this list of conditions and the following disclaimer in the
13295041Sbr#    documentation and/or other materials provided with the distribution.
14295041Sbr#
15295041Sbr# THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
16295041Sbr# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17295041Sbr# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18295041Sbr# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
19295041Sbr# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20295041Sbr# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21295041Sbr# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22295041Sbr# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23295041Sbr# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24295041Sbr# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25295041Sbr# SUCH DAMAGE.
26295041Sbr#
27295041Sbr# $FreeBSD: stable/9/tools/tools/zfsboottest/zfsboottest.sh 254037 2013-08-07 07:32:56Z avg $
28295041Sbr
29295041Sbrif [ $# -ne 1 ]; then
30295041Sbr	echo "usage: zfsboottest.sh <pool>" >&2
31295041Sbr	exit 1
32295041Sbrfi
33295041Sbr
34295041Sbrwhich -s zfsboottest
35295041Sbrif [ $? -eq 0 ]; then
36295041Sbr	zfsboottest="zfsboottest"
37295041Sbrelse
38295041Sbr	if [ ! -x "/usr/src/tools/tools/zfsboottest/zfsboottest" ]; then
39295041Sbr		echo "Unable to find \"zfsboottest\" utility." >&2
40295041Sbr		exit 1
41295041Sbr	fi
42295041Sbr	zfsboottest="/usr/src/tools/tools/zfsboottest/zfsboottest"
43295041Sbrfi
44295041Sbr
45295041Sbrstartdir="/boot"
46295041Sbr
47295041Sbrpool="${1}"
48295041Sbrzpool list "${pool}" >/dev/null 2>&1
49295041Sbrif [ $? -ne 0 ]; then
50295041Sbr	echo "No such pool \"${pool}\"." >&2
51295041Sbr	exit 1
52295041Sbrfi
53295041Sbrbootfs=`zpool get bootfs "${pool}" | tail -1 | awk '{print $3}'`
54295041Sbrif [ "${bootfs}" = "-" ]; then
55295041Sbr	bootfs="${pool}"
56295041Sbrfi
57295041Sbrmountpoint=`df -t zfs "${bootfs}" 2>/dev/null | tail -1 | awk '{print $6}'`
58295041Sbrif [ -z "${mountpoint}" ]; then
59295041Sbr	echo "The \"${bootfs}\" dataset is not mounted." >&2
60295041Sbr	exit 1
61295041Sbrfi
62295041Sbrif [ ! -d "${mountpoint}${startdir}" ]; then
63295041Sbr	echo "The \"${mountpoint}${startdir}\" directory doesn't exist." >&2
64295041Sbr	exit 1
65295041Sbrfi
66295041Sbrvdevs=""
67295041Sbrfor vdev in `zpool status "${pool}" | grep ONLINE | awk '{print $1}'`; do
68295041Sbr	vdev="/dev/${vdev#/dev/}"
69295041Sbr	if [ -c "${vdev}" ]; then
70295041Sbr		if [ -z "${vdevs}" ]; then
71295041Sbr			vdevs="${vdev}"
72295041Sbr		else
73295041Sbr			vdevs="${vdevs} ${vdev}"
74295041Sbr		fi
75295041Sbr	fi
76295041Sbrdone
77295041Sbr
78295041Sbrlist0=`mktemp /tmp/zfsboottest.XXXXXXXXXX`
79295041Sbrif [ $? -ne 0 ]; then
80295041Sbr	echo "Unable to create temporary file." >&2
81295041Sbr	exit 1
82295041Sbrfi
83295041Sbrlist1=`mktemp /tmp/zfsboottest.XXXXXXXXXX`
84295041Sbrif [ $? -ne 0 ]; then
85295041Sbr	echo "Unable to create temporary file." >&2
86295041Sbr	rm -f "${list0}"
87295041Sbr	exit 1
88295041Sbrfi
89295041Sbr
90295041Sbrecho "zfsboottest.sh is reading all the files in ${mountpoint}${startdir} using"
91295041Sbrecho "boot code and using file system code."
92295041Sbrecho "It calculates MD5 checksums for all the files and will compare them."
93295041Sbrecho "If all files can be properly read using boot code, it is very likely you"
94295041Sbrecho "will be able to boot from \"${pool}\" pool>:> Good luck!"
95295041Sbrecho
96295041Sbr
97295041Sbr"${zfsboottest}" ${vdevs} - `find "${mountpoint}${startdir}" -type f | sed "s@^${mountpoint}@@"` | egrep '^[0-9a-z]{32} /' | sort -k 2 >"${list0}"
98295041Sbrfind "${mountpoint}${startdir}" -type f | xargs md5 -r | sed "s@ ${mountpoint}@ @" | egrep '^[0-9a-z]{32} /' | sort -k 2 >"${list1}"
99295041Sbr
100295041Sbrdiff -u "${list0}" "${list1}"
101295041Sbrec=$?
102295041Sbr
103295041Sbrrm -f "${list0}" "${list1}"
104295041Sbr
105295041Sbrif [ $? -ne 0 ]; then
106295041Sbr	echo >&2
107295041Sbr	echo "You may not be able to boot." >&2
108295041Sbr	exit 1
109295041Sbrfi
110295041Sbr
111295041Sbrecho "OK"
112295041Sbr