rsend.kshlib revision f38cb554a534c6df738be3f4d23327e69888e634
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#
# Copyright (c) 2013 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/rsend/rsend.cfg
#
# Set up test model which includes various datasets
#
# @final
# @snapB
# @init
# |
# ______ pclone
# | /
# |@psnap
# || @final
# ||@final @final @snapC
# ||@snapC @snapC @snapB
# ||@snapA @snapB @snapA
# ||@init @init @init
# ||| | |
# $pool -------- $FS ------- fs1 ------- fs2
# \ \\_____ \ |
# vol vol \____ \ @fsnap
# | | \ \ \
# @init @vsnap | ------------ fclone
# @snapA @init \ | |
# @final @snapB \ | @init
# @snapC vclone @snapA
# @final | @final
# @init
# @snapC
# @final
#
# $1 pool name
#
function setup_test_model
{
typeset pool=$1
log_must $ZFS create -p $pool/$FS/fs1/fs2
log_must $ZFS snapshot $pool@psnap
log_must $ZFS clone $pool@psnap $pool/pclone
if is_global_zone ; then
log_must $ZFS create -V 16M $pool/vol
log_must $ZFS create -V 16M $pool/$FS/vol
log_must $ZFS snapshot $pool/$FS/vol@vsnap
log_must $ZFS clone $pool/$FS/vol@vsnap $pool/$FS/vclone
fi
log_must snapshot_tree $pool/$FS/fs1/fs2@fsnap
log_must $ZFS clone $pool/$FS/fs1/fs2@fsnap $pool/$FS/fs1/fclone
log_must $ZFS snapshot -r $pool@init
log_must snapshot_tree $pool@snapA
log_must snapshot_tree $pool@snapC
log_must snapshot_tree $pool/pclone@snapB
log_must snapshot_tree $pool/$FS@snapB
log_must snapshot_tree $pool/$FS@snapC
log_must snapshot_tree $pool/$FS/fs1@snapA
log_must snapshot_tree $pool/$FS/fs1@snapB
log_must snapshot_tree $pool/$FS/fs1@snapC
log_must snapshot_tree $pool/$FS/fs1/fclone@snapA
if is_global_zone ; then
log_must $ZFS snapshot $pool/vol@snapA
log_must $ZFS snapshot $pool/$FS/vol@snapB
log_must $ZFS snapshot $pool/$FS/vol@snapC
log_must $ZFS snapshot $pool/$FS/vclone@snapC
fi
log_must $ZFS snapshot -r $pool@final
return 0
}
#
# Cleanup the BACKDIR and given pool content and all the sub datasets
#
# $1 pool name
#
function cleanup_pool
{
typeset pool=$1
log_must $RM -rf $BACKDIR/*
if is_global_zone ; then
log_must $ZFS destroy -Rf $pool
else
typeset list=$($ZFS list -H -r -t filesystem,snapshot,volume -o name $pool)
for ds in $list ; do
if [[ $ds != $pool ]] ; then
if datasetexists $ds ; then
log_must $ZFS destroy -Rf $ds
fi
fi
done
fi
typeset mntpnt=$(get_prop mountpoint $pool)
if ! ismounted $pool ; then
# Make sure mountpoint directory is empty
if [[ -d $mntpnt ]]; then
log_must $RM -rf $mntpnt/*
fi
log_must $ZFS mount $pool
fi
if [[ -d $mntpnt ]]; then
log_must $RM -rf $mntpnt/*
fi
return 0
}
#
# Detect if the given two filesystems have same sub-datasets
#
# $1 source filesystem
# $2 destination filesystem
#
function cmp_ds_subs
{
typeset src_fs=$1
typeset dst_fs=$2
$ZFS list -r -H -t filesystem,snapshot,volume -o name $src_fs > $BACKDIR/src1
$ZFS list -r -H -t filesystem,snapshot,volume -o name $dst_fs > $BACKDIR/dst1
eval $SED -e 's:^$src_fs:PREFIX:g' < $BACKDIR/src1 > $BACKDIR/src
eval $SED -e 's:^$dst_fs:PREFIX:g' < $BACKDIR/dst1 > $BACKDIR/dst
$DIFF $BACKDIR/src $BACKDIR/dst
typeset -i ret=$?
$RM -f $BACKDIR/src $BACKDIR/dst $BACKDIR/src1 $BACKDIR/dst1
return $ret
}
#
# Compare all the directores and files in two filesystems
#
# $1 source filesystem
# $2 destination filesystem
#
function cmp_ds_cont
{
typeset src_fs=$1
typeset dst_fs=$2
typeset srcdir dstdir
srcdir=$(get_prop mountpoint $src_fs)
dstdir=$(get_prop mountpoint $dst_fs)
$DIFF -r $srcdir $dstdir > /dev/null 2>&1
echo $?
}
#
# Compare the given two dataset properties
#
# $1 dataset 1
# $2 dataset 2
#
function cmp_ds_prop
{
typeset dtst1=$1
typeset dtst2=$2
for item in "type" "origin" "volblocksize" "aclinherit" "aclmode" \
"atime" "canmount" "checksum" "compression" "copies" "devices" \
"exec" "quota" "readonly" "recordsize" "reservation" "setuid" \
"sharenfs" "snapdir" "version" "volsize" "xattr" "zoned" \
"mountpoint";
do
$ZFS get -H -o property,value,source $item $dtst1 >> \
$BACKDIR/dtst1
$ZFS get -H -o property,value,source $item $dtst2 >> \
$BACKDIR/dtst2
done
eval $SED -e 's:$dtst1:PREFIX:g' < $BACKDIR/dtst1 > $BACKDIR/dtst1
eval $SED -e 's:$dtst2:PREFIX:g' < $BACKDIR/dtst2 > $BACKDIR/dtst2
$DIFF $BACKDIR/dtst1 $BACKDIR/dtst2
typeset -i ret=$?
$RM -f $BACKDIR/dtst1 $BACKDIR/dtst2
return $ret
}
#
# Random create directories and files
#
# $1 directory
#
function random_tree
{
typeset dir=$1
if [[ -d $dir ]]; then
$RM -rf $dir
fi
$MKDIR -p $dir
typeset -i ret=$?
typeset -i nl nd nf
((nl = RANDOM % 6 + 1))
((nd = RANDOM % 3 ))
((nf = RANDOM % 5 ))
$MKTREE -b $dir -l $nl -d $nd -f $nf
((ret |= $?))
return $ret
}
#
# Put data in filesystem and take snapshot
#
# $1 snapshot name
#
function snapshot_tree
{
typeset snap=$1
typeset ds=${snap%%@*}
typeset type=$(get_prop "type" $ds)
typeset -i ret=0
if [[ $type == "filesystem" ]]; then
typeset mntpnt=$(get_prop mountpoint $ds)
((ret |= $?))
if ((ret == 0)) ; then
eval random_tree $mntpnt/${snap##$ds}
((ret |= $?))
fi
fi
if ((ret == 0)) ; then
$ZFS snapshot $snap
((ret |= $?))
fi
return $ret
}
#
# Destroy the given snapshot and stuff
#
# $1 snapshot
#
function destroy_tree
{
typeset -i ret=0
typeset snap
for snap in "$@" ; do
$ZFS destroy $snap
ret=$?
typeset ds=${snap%%@*}
typeset type=$(get_prop "type" $ds)
if [[ $type == "filesystem" ]]; then
typeset mntpnt=$(get_prop mountpoint $ds)
((ret |= $?))
if ((ret != 0)); then
$RM -r $mntpnt/$snap
((ret |= $?))
fi
fi
if ((ret != 0)); then
return $ret
fi
done
return 0
}
#
# Get all the sub-datasets of give dataset with specific suffix
#
# $1 Given dataset
# $2 Suffix
#
function getds_with_suffix
{
typeset ds=$1
typeset suffix=$2
typeset list=$($ZFS list -r -H -t filesystem,snapshot,volume -o name $ds \
| $GREP "$suffix$")
$ECHO $list
}
#
# Output inherited properties whitch is edited for file system
#
function fs_inherit_prop
{
typeset fs_prop
if is_global_zone ; then
fs_prop=$($ZFS inherit 2>&1 | \
$AWK '$2=="YES" && $3=="YES" {print $1}')
if ! is_te_enabled ; then
fs_prop=$(echo $fs_prop | $GREP -v "mlslabel")
fi
else
fs_prop=$($ZFS inherit 2>&1 | \
$AWK '$2=="YES" && $3=="YES" {print $1}'|
$EGREP -v "devices|mlslabel|sharenfs|sharesmb|zoned")
fi
$ECHO $fs_prop
}
#
# Output inherited properties for volume
#
function vol_inherit_prop
{
$ECHO "checksum readonly"
}
#
# Get the destination dataset to compare
#
function get_dst_ds
{
typeset srcfs=$1
typeset dstfs=$2
#
# If the srcfs is not pool
#
if ! $ZPOOL list $srcfs > /dev/null 2>&1 ; then
eval dstfs="$dstfs/${srcfs#*/}"
fi
$ECHO $dstfs
}