#
# 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
# 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, 2016 by Delphix. All rights reserved.
#
#
# 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
if is_global_zone ; then
fi
if is_global_zone ; then
fi
return 0
}
#
# Cleanup the BACKDIR and given pool content and all the sub datasets
#
# $1 pool name
#
function cleanup_pool
{
typeset pool=$1
if is_global_zone ; then
else
if datasetexists $ds ; then
fi
fi
done
fi
typeset mntpnt=$(get_prop mountpoint $pool)
# Make sure mountpoint directory is empty
if [[ -d $mntpnt ]]; then
fi
fi
if [[ -d $mntpnt ]]; then
fi
return 0
}
function cleanup_pools
{
}
#
# 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
typeset -i ret=$?
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
return $?
}
#
# Compare the given two dataset properties
#
# $1 dataset 1
# $2 dataset 2
#
function cmp_ds_prop
{
typeset dtst1=$1
typeset dtst2=$2
"atime" "canmount" "checksum" "compression" "copies" "devices" \
"exec" "quota" "readonly" "recordsize" "reservation" "setuid" \
"sharenfs" "snapdir" "version" "volsize" "xattr" "zoned" \
"mountpoint";
do
done
typeset -i ret=$?
return $ret
}
#
# Random create directories and files
#
# $1 directory
#
function random_tree
{
typeset dir=$1
if [[ -d $dir ]]; then
fi
typeset -i ret=$?
return $ret
}
#
# Put data in filesystem and take snapshot
#
# $1 snapshot name
#
function snapshot_tree
{
typeset snap=$1
typeset -i ret=0
typeset mntpnt=$(get_prop mountpoint $ds)
eval random_tree $mntpnt/${snap##$ds}
fi
fi
fi
return $ret
}
#
# Destroy the given snapshot and stuff
#
# $1 snapshot
#
function destroy_tree
{
typeset -i ret=0
typeset snap
ret=$?
typeset mntpnt=$(get_prop mountpoint $ds)
fi
fi
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
echo $list
}
#
# Output inherited properties whitch is edited for file system
#
function fs_inherit_prop
{
typeset fs_prop
if is_global_zone ; then
if ! is_te_enabled ; then
fi
else
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
#
fi
echo $dstfs
}
#
# Make test files
#
# $1 Number of files to create
# $2 Maximum file size
# $3 File ID offset
# $4 File system to create the files on
#
function mk_files
{
nfiles=$1
maxsize=$2
fs=$4
done
}
#
# Remove test files
#
# $1 Number of files to remove
# $2 Maximum file size
# $3 File ID offset
# $4 File system to remove the files from
#
function rm_files
{
nfiles=$1
maxsize=$2
fs=$4
done
}
#
# Mess up file contents
#
# $1 The file path
#
function mess_file
{
file=$1
#
# We corrupt 2 bytes to minimize the chance that we
# write the same value that's already there.
#
else
fi
}
#
#
# $1 The sent filesystem
# $2 The received filesystem
#
function file_check
{
sendfs=$1
recvfs=$2
fi
fi
}
#
# Resume test helper
#
# $1 The ZFS send command
# $2 The filesystem where the streams are sent
# $3 The receive filesystem
#
function resume_test
{
sendcmd=$1
streamfs=$2
recvfs=$3
log_must eval "$sendcmd >/$streamfs/$stream_num"
for ((i=0; i<2; i=i+1)); do
log_must eval "zfs send -v -t $token >/$streamfs/$stream_num"
[[ -f /$streamfs/$stream_num ]] || \
log_fail "NO FILE /$streamfs/$stream_num"
done
}
#
#
# $1 The "send" filesystem
# $2 The "recv" filesystem
#
function test_fs_setup
{
typeset sendfs=$1
typeset recvfs=$2
log_must wait
log_must wait
log_must wait
log_must eval "zfs send -v $sendfs@a >/$sendpool/initial.zsend"
fi
if datasetexists $streamfs; then
fi
}
#
# Check to see if the specified features are set in a send stream.
#
# $1 The stream file
# $2-$n The flags expected in the stream
#
function stream_has_features
{
typeset file=$1
shift
typeset -A feature
feature[dedupprops]="2"
feature[embed_data]="10000"
feature[mooch_byteswap]="40000"
feature[large_blocks]="80000"
feature[compressed]="400000"
done
return 0
}
#
# Parse zstreamdump -v output. The output varies for each kind of record:
# BEGIN records are simply output as "BEGIN"
# END records are output as "END"
# OBJECT records become "OBJECT <object num>"
# FREEOBJECTS records become "FREEOBJECTS <startobj> <numobjs>"
# FREE records become "<record type> <start> <length>"
# WRITE records become:
# "<record type> <compression type> <start> <logical size> <compressed size>
# <data size>"
#
function parse_dump
{
if ($1 == "BEGIN" || $1 == "END") print $1
if ($1 == "OBJECT") print $1" "$4
if ($1 == "FREEOBJECTS") print $1" "$4" "$7
if ($1 == "FREE") print $1" "$7" "$10
if ($1 == "WRITE") print $1" "$15" "$18" "$21" "$24" "$27}'
}
#
# Given a send stream, verify that the size of the stream matches what's
# expected based on the source or target dataset. If the stream is an
# incremental stream, subtract the size of the source snapshot before
# comparing. This function does not currently handle incremental streams
# that remove data.
#
# $1 The zstreamdump output file
# $2 The dataset to compare against
# This can be a source of a send or recv target (fs, not snapshot)
# $3 The percentage below which verification is deemed a failure
# $4 The source snapshot of an incremental send
#
function verify_stream_size
{
typeset stream=$1
typeset ds=$2
typeset percent=${3:-90}
typeset inc_src=$4
datasetexists $ds || log_fail "No such dataset: $ds"
typeset stream_size=$(cat $stream | zstreamdump | sed -n \
's/ Total write size = \(.*\) (0x.*)/\1/p')
typeset inc_size=0
if [[ -n $inc_src ]]; then
if stream_has_features $stream compressed; then
fi
fi
if stream_has_features $stream compressed; then
else
fi
"$stream_size $ds_size differed by too much"
}
# Cleanup function for tests involving resumable send
function resume_cleanup
{
typeset sendfs=$1
typeset streamfs=$2
}