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# 24# Copyright 2013 Spectra Logic All rights reserved. 25# Use is subject to license terms. 26# 27 28. $STF_SUITE/include/libtest.kshlib 29 30################################################################################# 31# 32# __stc_assertion_start 33# 34# ID: zpool_import_014_pos 35# 36# DESCRIPTION: 37# Verify that a disk-backed exported pool with some of its vdev labels 38# corrupted can still be imported 39# STRATEGY: 40# 1. Create a disk-backed pool 41# 2. Export it 42# 3. Overwrite one or more of its vdev labels 43# 4. Use zdb to verify that the labels are damaged 44# 5. Verify 'zpool import' can import it 45# 46# TESTABILITY: explicit 47# 48# TEST_AUTOMATION_LEVEL: automated 49# 50# CODING_STATUS: COMPLETED (2013-03-15) 51# 52# __stc_assertion_end 53# 54################################################################################ 55 56verify_runnable "global" 57 58# ZFS has four vdev labels per vdev 59typeset -i N_VDEV_LABELS=4 60# Size of a single label, in bytes 61typeset -i VDEV_LABEL_SIZE=$(( 256 * 1024)) 62 63 64# 65# The authoritative version of this calculation can be found in the function of 66# the same name in vdev_label.c. The rounding of psize is based on the 67# calculation in vdev_disk_read_rootlabel in vdev_disk.c 68# 69# arg1: vdev size in bytes 70# arg2: label index, 0 through 3 71# 72function vdev_label_offset 73{ 74 typeset -il psize=$1 75 typeset -i l=$2 76 typeset -il offset 77 typeset -il roundsize 78 79 roundsize=$(( $psize & -$VDEV_LABEL_SIZE )) 80 if [[ $l -lt $(( N_VDEV_LABELS / 2 )) ]]; then 81 offset=$(( l * $VDEV_LABEL_SIZE)) 82 else 83 offset=$(( l * $VDEV_LABEL_SIZE + $roundsize - $N_VDEV_LABELS * $VDEV_LABEL_SIZE )) 84 fi 85 echo $offset 86} 87 88log_assert "Verify that a disk-backed exported pool with some of its vdev labels corrupted can still be imported" 89 90typeset -i i 91typeset -i j 92set -A DISKS_ARRAY $DISKS 93typeset DISK=${DISKS_ARRAY[0]} 94typeset PROV=${DISK#/dev/} 95typeset -il psize=$(geom disk list $PROV | awk '/Mediasize/ {print $2}') 96if [[ -z $psize ]]; then 97 log_fail "Could not determine the capacity of $DISK" 98fi 99 100for ((i=0; $i<$N_VDEV_LABELS; i=$i+1 )); do 101 log_must $ZPOOL create -f $TESTPOOL $DISK 102 log_must $ZPOOL export $TESTPOOL 103 104 # Corrupt all labels except the ith 105 for ((j=0; $j<$N_VDEV_LABELS; j=$j+1 )); do 106 typeset -il offset 107 108 [[ $i -eq $j ]] && continue 109 110 log_note offset=vdev_label_offset $psize $j 111 offset=$(vdev_label_offset $psize $j) 112 log_must $DD if=/dev/zero of=$DISK bs=1024 \ 113 count=$(( $VDEV_LABEL_SIZE / 1024 )) \ 114 oseek=$(( $offset / 1024 )) \ 115 conv=notrunc 116 done 117 118 typeset -i num_labels=$( $ZDB -l $DISK | $GREP pool_guid | wc -l ) 119 if [[ $num_labels -ne 1 ]]; then 120 $ZDB -l $DISK 121 log_fail "Expected 1 vdev label but found $num_labels" 122 fi 123 124 log_must $ZPOOL import $TESTPOOL 125 destroy_pool $TESTPOOL 126done 127 128log_pass 129