1#!/usr/local/bin/ksh93 -p 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or http://www.opensolaris.org/os/licensing. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22 23# $FreeBSD$ 24 25# 26# Copyright 2013 Spectra Logic All rights reserved. 27# Use is subject to license terms. 28# 29 30. $STF_SUITE/include/libtest.kshlib 31 32################################################################################# 33# 34# __stc_assertion_start 35# 36# ID: zpool_import_014_pos 37# 38# DESCRIPTION: 39# Verify that a disk-backed exported pool with some of its vdev labels 40# corrupted can still be imported 41# STRATEGY: 42# 1. Create a disk-backed pool 43# 2. Export it 44# 3. Overwrite one or more of its vdev labels 45# 4. Use zdb to verify that the labels are damaged 46# 5. Verify 'zpool import' can import it 47# 48# TESTABILITY: explicit 49# 50# TEST_AUTOMATION_LEVEL: automated 51# 52# CODING_STATUS: COMPLETED (2013-03-15) 53# 54# __stc_assertion_end 55# 56################################################################################ 57 58verify_runnable "global" 59 60# ZFS has four vdev labels per vdev 61typeset -i N_VDEV_LABELS=4 62# Size of a single label, in bytes 63typeset -i VDEV_LABEL_SIZE=$(( 256 * 1024)) 64 65 66# 67# The authoritative version of this calculation can be found in the function of 68# the same name in vdev_label.c. The rounding of psize is based on the 69# calculation in vdev_disk_read_rootlabel in vdev_disk.c 70# 71# arg1: vdev size in bytes 72# arg2: label index, 0 through 3 73# 74function vdev_label_offset 75{ 76 typeset -il psize=$1 77 typeset -i l=$2 78 typeset -il offset 79 typeset -il roundsize 80 81 roundsize=$(( $psize & -$VDEV_LABEL_SIZE )) 82 if [[ $l -lt $(( N_VDEV_LABELS / 2 )) ]]; then 83 offset=$(( l * $VDEV_LABEL_SIZE)) 84 else 85 offset=$(( l * $VDEV_LABEL_SIZE + $roundsize - $N_VDEV_LABELS * $VDEV_LABEL_SIZE )) 86 fi 87 echo $offset 88} 89 90log_assert "Verify that a disk-backed exported pool with some of its vdev labels corrupted can still be imported" 91 92typeset -i i 93typeset -i j 94set -A DISKS_ARRAY $DISKS 95typeset DISK=${DISKS_ARRAY[0]} 96typeset PROV=${DISK#/dev/} 97typeset -il psize=$(geom disk list $PROV | awk '/Mediasize/ {print $2}') 98if [[ -z $psize ]]; then 99 log_fail "Could not determine the capacity of $DISK" 100fi 101 102for ((i=0; $i<$N_VDEV_LABELS; i=$i+1 )); do 103 log_must $ZPOOL create -f $TESTPOOL $DISK 104 log_must $ZPOOL export $TESTPOOL 105 106 # Corrupt all labels except the ith 107 for ((j=0; $j<$N_VDEV_LABELS; j=$j+1 )); do 108 typeset -il offset 109 110 [[ $i -eq $j ]] && continue 111 112 log_note offset=vdev_label_offset $psize $j 113 offset=$(vdev_label_offset $psize $j) 114 log_must $DD if=/dev/zero of=$DISK bs=1024 \ 115 count=$(( $VDEV_LABEL_SIZE / 1024 )) \ 116 oseek=$(( $offset / 1024 )) \ 117 conv=notrunc 118 done 119 120 typeset -i num_labels=$( $ZDB -l $DISK | $GREP pool_guid | wc -l ) 121 if [[ $num_labels -ne 1 ]]; then 122 $ZDB -l $DISK 123 log_fail "Expected 1 vdev label but found $num_labels" 124 fi 125 126 log_must $ZPOOL import $TESTPOOL 127 destroy_pool $TESTPOOL 128done 129 130log_pass 131