bbe899b96e
This bring huge amount of changes, I'll enumerate only user-visible changes: - Delegated Administration Allows regular users to perform ZFS operations, like file system creation, snapshot creation, etc. - L2ARC Level 2 cache for ZFS - allows to use additional disks for cache. Huge performance improvements mostly for random read of mostly static content. - slog Allow to use additional disks for ZFS Intent Log to speed up operations like fsync(2). - vfs.zfs.super_owner Allows regular users to perform privileged operations on files stored on ZFS file systems owned by him. Very careful with this one. - chflags(2) Not all the flags are supported. This still needs work. - ZFSBoot Support to boot off of ZFS pool. Not finished, AFAIK. Submitted by: dfr - Snapshot properties - New failure modes Before if write requested failed, system paniced. Now one can select from one of three failure modes: - panic - panic on write error - wait - wait for disk to reappear - continue - serve read requests if possible, block write requests - Refquota, refreservation properties Just quota and reservation properties, but don't count space consumed by children file systems, clones and snapshots. - Sparse volumes ZVOLs that don't reserve space in the pool. - External attributes Compatible with extattr(2). - NFSv4-ACLs Not sure about the status, might not be complete yet. Submitted by: trasz - Creation-time properties - Regression tests for zpool(8) command. Obtained from: OpenSolaris
437 lines
8.4 KiB
Bash
Executable File
437 lines
8.4 KiB
Bash
Executable File
# $FreeBSD$
|
|
|
|
ntest=1
|
|
os=`uname -s`
|
|
|
|
echo ${dir} | egrep '^/' >/dev/null 2>&1
|
|
if [ $? -eq 0 ]; then
|
|
maindir="${dir}/../.."
|
|
else
|
|
maindir="`pwd`/${dir}/../.."
|
|
fi
|
|
|
|
# Set up correct command names and switches
|
|
if [ -z "${LUSTRE}" ]; then
|
|
ZPOOL="zpool"
|
|
ZFS="zfs"
|
|
ZDB="zdb"
|
|
zpool_f_flag="-f"
|
|
else
|
|
ZPOOL="lzpool"
|
|
ZFS="lzfs"
|
|
ZDB="lzdb"
|
|
zpool_f_flag="-F"
|
|
no_mountpoint=1
|
|
fi
|
|
|
|
# Use correct arguments to cmd line programs
|
|
stat --version 2>/dev/null | grep GNU >/dev/null
|
|
if [ $? -eq 0 ]; then
|
|
GNU_STAT="yes"
|
|
fi
|
|
if [ "${os}" = "SunOS" ]; then
|
|
import_flags="-d /dev/lofi"
|
|
mount_t_flag="-F"
|
|
else
|
|
mount_t_flag="-t"
|
|
fi
|
|
|
|
die()
|
|
{
|
|
echo "${1}" > /dev/stderr
|
|
exit 1
|
|
}
|
|
|
|
calcsum()
|
|
{
|
|
dd if="${1}" bs=1M 2>/dev/null | openssl md5
|
|
}
|
|
|
|
create_file()
|
|
{
|
|
name="${1}"
|
|
size="${2}"
|
|
|
|
dd if=/dev/urandom of=${name} bs=${size} count=1 >/dev/null 2>&1
|
|
sync
|
|
}
|
|
|
|
expect()
|
|
{
|
|
eorig="${1}"
|
|
eexp=`echo "${eorig}" | egrep -v '^[ ]*$' | sed 's/^[ ][ ]*//g;s/[ ][ ]*$//g;s/[ ][ ]*/ /g;s/$/%EoL%/' | xargs`
|
|
shift
|
|
gorig=`sh -c "$*" 2>&1`
|
|
got=`echo "${gorig}" | egrep -v '^[ ]*$' | sed 's/^[ ][ ]*//g;s/[ ][ ]*$//g;s/[ ][ ]*/ /g;s/$/%EoL%/' | xargs`
|
|
echo "${got}" | egrep "${eexp}" >/dev/null
|
|
if [ $? -eq 0 ]; then
|
|
echo "ok ${ntest} ${add_msg}"
|
|
else
|
|
echo "not ok ${ntest} ${add_msg}"
|
|
echo "# ----- expected from: $*"
|
|
echo "${eorig}" | sed 's/^/# /'
|
|
echo "# ----- got:"
|
|
echo "${gorig}" | sed 's/^/# /'
|
|
echo "# ----- end"
|
|
fi
|
|
ntest=`expr $ntest + 1`
|
|
}
|
|
|
|
expect_ok()
|
|
{
|
|
out=`$* 2>&1`
|
|
ec=$?
|
|
if [ $ec -eq 0 ]; then
|
|
echo "ok ${ntest} ${add_msg}"
|
|
echo "# ----- expected success from: $*"
|
|
if [ ! -z "${out}" ]; then
|
|
echo "# ----- output (exit code=${ec}):"
|
|
echo "${out}" | sed 's/^/# /'
|
|
echo "# ----- end"
|
|
fi
|
|
else
|
|
echo "not ok ${ntest} ${add_msg}"
|
|
echo "# ----- expected success from: $*"
|
|
echo "# ----- output (exit code=${ec}):"
|
|
echo "${out}" | sed 's/^/# /'
|
|
echo "# ----- end"
|
|
fi
|
|
ntest=`expr $ntest + 1`
|
|
}
|
|
|
|
expect_fl()
|
|
{
|
|
out=`$* 2>&1`
|
|
ec=$?
|
|
if [ $ec -ne 0 ]; then
|
|
echo "ok ${ntest} ${add_msg}"
|
|
echo "# ----- expected failure from: $*"
|
|
if [ ! -z "${out}" ]; then
|
|
echo "# ----- output (exit code=${ec}):"
|
|
echo "${out}" | sed 's/^/# /'
|
|
echo "# ----- end"
|
|
fi
|
|
else
|
|
echo "not ok ${ntest} ${add_msg}"
|
|
echo "# ----- expected failure from: $*"
|
|
echo "# ----- output (exit code=${ec}):"
|
|
echo "${out}" | sed 's/^/# /'
|
|
echo "# ----- end"
|
|
fi
|
|
ntest=`expr $ntest + 1`
|
|
}
|
|
|
|
quick_exit()
|
|
{
|
|
echo "1..1"
|
|
echo "ok 1"
|
|
exit 0
|
|
}
|
|
|
|
# Set up a scratch tmpfs directory (Linux only)
|
|
setup_tmpfs()
|
|
{
|
|
cmd="mktemp -d /tmp/zfs-regression.XXXXXXXXXX"
|
|
TMPDIR=`${cmd}` || die "failed: ${cmd}"
|
|
cmd="mount -t tmpfs none ${TMPDIR}"
|
|
${cmd} || die "failed: ${cmd}"
|
|
}
|
|
|
|
# Clean up the tmpfs directory (Linux only)
|
|
cleanup_tmpfs()
|
|
{
|
|
if [ -n "${TMPDIR}" ]; then
|
|
cmd="umount ${TMPDIR} && rmdir ${TMPDIR}"
|
|
eval "${cmd}" || die "failed: ${cmd}"
|
|
fi
|
|
}
|
|
|
|
# Truncate a file
|
|
truncate_cmd()
|
|
{
|
|
size="${1}"
|
|
file="${2}"
|
|
|
|
cmd="dd if=/dev/null of=${file} bs=1 count=0 seek=${size}"
|
|
${cmd} > /dev/null 2>&1 || die "failed: ${cmd}"
|
|
}
|
|
|
|
# Create a memory-backed block device
|
|
create_memdisk()
|
|
{
|
|
size="${1}"
|
|
devname="${2}"
|
|
|
|
if [ "${os}" = "FreeBSD" ]; then
|
|
if [ -n "${devname}" ]; then
|
|
devparam="-u ${devname}"
|
|
fi
|
|
cmd="mdconfig -a -t swap -s ${size} ${devparam} 2>/dev/null"
|
|
DISKNAME=`${cmd}` || die "failed: ${cmd}"
|
|
if [ -n "${devname}" ]; then
|
|
DISKNAME="${devname}"
|
|
fi
|
|
FDISKNAME="/dev/${DISKNAME}"
|
|
elif [ "${os}" = "SunOS" ]; then
|
|
cmd="mktemp /tmp/zfstest.XXXXXXXXXX"
|
|
fname=`${cmd}` || die "failed: ${cmd}"
|
|
|
|
truncate_cmd "${size}" "${fname}"
|
|
|
|
if [ -n "${devname}" ]; then
|
|
cmd="lofiadm -a ${fname} ${devname}"
|
|
${cmd} || die "failed: ${cmd}"
|
|
DISKNAME="${devname}"
|
|
else
|
|
cmd="lofiadm -a ${fname}"
|
|
DISKNAME=`${cmd}` || die "failed: ${cmd}"
|
|
fi
|
|
FDISKNAME="${DISKNAME}"
|
|
elif [ "${os}" = "Linux" ]; then
|
|
if [ -z "${TMPDIR_DISKS}" ]; then
|
|
setup_tmpfs
|
|
TMPDIR_DISKS="${TMPDIR}"
|
|
fi
|
|
|
|
cmd="mktemp ${TMPDIR_DISKS}/disk.XXXXXXXXXX"
|
|
fname=`${cmd}` || die "failed: ${cmd}"
|
|
|
|
truncate_cmd "${size}" "${fname}"
|
|
|
|
if [ -n "${devname}" ]; then
|
|
devname=`echo ${devname} | cut -c 9-`
|
|
cmd="losetup /dev/${devname} ${fname} 2>&1"
|
|
eval ${cmd} || die "failed: ${cmd}"
|
|
DISKNAME="${devname}"
|
|
else
|
|
cmd="losetup -s -f ${fname} 2>&1"
|
|
diskname=`eval ${cmd}`
|
|
|
|
if [ "${diskname}" = "losetup: could not find any free loop device" ]; then
|
|
# If there are no free loopback devices, create one more
|
|
max=`echo /dev/loop* | awk 'BEGIN { RS=" "; FS="loop" } {if ($2 > max) max = $2} END {print max}'`
|
|
max=$((max + 1))
|
|
cmd="mknod /dev/loop${max} b 7 ${max}"
|
|
${cmd} || die "failed: ${cmd}"
|
|
|
|
cmd="losetup -s -f ${fname}"
|
|
diskname=`${cmd}` || die "failed: ${cmd}"
|
|
fi
|
|
DISKNAME=`eval echo ${diskname} | sed 's/^\/dev\///'`
|
|
fi
|
|
ln /dev/${DISKNAME} /dev/zfstest_${DISKNAME}
|
|
DISKNAME="zfstest_${DISKNAME}"
|
|
FDISKNAME="/dev/${DISKNAME}"
|
|
else
|
|
die "Sorry, your OS is not supported"
|
|
fi
|
|
}
|
|
|
|
# Destroy a memory-backed block device
|
|
destroy_memdisk()
|
|
{
|
|
disk="${1}"
|
|
|
|
if [ "${os}" = "FreeBSD" ]; then
|
|
cmd="mdconfig -d -u ${disk}"
|
|
${cmd} || die "failed: ${cmd}"
|
|
elif [ "${os}" = "SunOS" ]; then
|
|
cmd="lofiadm ${disk}"
|
|
fname=`${cmd}` || die "failed: ${cmd}"
|
|
|
|
cmd="lofiadm -d ${disk}"
|
|
${cmd} || die "failed: ${cmd}"
|
|
|
|
cmd="rm ${fname}"
|
|
${cmd} || die "failed: ${cmd}"
|
|
elif [ "${os}" = "Linux" ]; then
|
|
cmd="rm /dev/${disk}"
|
|
${cmd} || die "failed: ${cmd}"
|
|
disk=`echo ${disk} | cut -c 9-`
|
|
|
|
cmd="losetup /dev/${disk} | awk '{print substr(\$3, 2, length(\$3)-2)}'"
|
|
fname=`eval ${cmd}` || die "failed: ${cmd}"
|
|
|
|
cmd="losetup -d /dev/${disk}"
|
|
${cmd} || die "failed: ${cmd}"
|
|
|
|
cmd="rm ${fname}"
|
|
${cmd} || die "failed: ${cmd}"
|
|
else
|
|
die "Sorry, your OS is not supported"
|
|
fi
|
|
}
|
|
|
|
disks_create()
|
|
{
|
|
if [ -z "${ndisks}" ]; then
|
|
start=0
|
|
else
|
|
start=${ndisks}
|
|
fi
|
|
ndisks=$((start+$1))
|
|
n=$((ndisks-$start))
|
|
if [ -z "${2}" ]; then
|
|
size="96M"
|
|
else
|
|
size="${2}"
|
|
fi
|
|
for i in `nums $n $start`; do
|
|
create_memdisk ${size}
|
|
eval disk${i}="${DISKNAME}"
|
|
eval fdisk${i}="${FDISKNAME}"
|
|
done
|
|
}
|
|
|
|
disks_destroy()
|
|
{
|
|
for i in `nums $ndisks 0`; do
|
|
eval disk=\$disk${i}
|
|
if [ ! -z "${disk}" ]; then
|
|
destroy_memdisk ${disk}
|
|
fi
|
|
done
|
|
[ -n "${TMPDIR_DISKS}" ] && TMPDIR="${TMPDIR_DISKS}" cleanup_tmpfs
|
|
return 0
|
|
}
|
|
|
|
disk_create()
|
|
{
|
|
diskno=${1}
|
|
eval disk=\$disk${diskno}
|
|
if [ ! -z ${disk} ]; then
|
|
die "disk${diskno} is already set"
|
|
fi
|
|
dname=${2}
|
|
if [ -z "${3}" ]; then
|
|
size="96M"
|
|
else
|
|
size="${3}"
|
|
fi
|
|
create_memdisk ${size} ${dname}
|
|
[ "${DISKNAME}" = "${dname}" ] || die "${DISKNAME} != ${dname}"
|
|
eval disk${diskno}="${DISKNAME}"
|
|
eval fdisk${diskno}="${FDISKNAME}"
|
|
}
|
|
|
|
disk_destroy()
|
|
{
|
|
eval disk=\$disk${1}
|
|
destroy_memdisk ${disk}
|
|
eval disk${1}=""
|
|
}
|
|
|
|
files_create()
|
|
{
|
|
if [ -z "${nfiles}" ]; then
|
|
start=0
|
|
else
|
|
start=${nfiles}
|
|
fi
|
|
nfiles=$((start+$1))
|
|
n=$((nfiles-$start))
|
|
if [ -z "${2}" ]; then
|
|
size="96M"
|
|
else
|
|
size="${2}"
|
|
fi
|
|
for i in `nums $n $start`; do
|
|
if [ "${os}" = "Linux" ]; then
|
|
if [ -z "${TMPDIR_FILES}" ]; then
|
|
setup_tmpfs
|
|
TMPDIR_FILES="${TMPDIR}"
|
|
fi
|
|
file=`mktemp ${TMPDIR_FILES}/zfstest.XXXXXXXX`
|
|
else
|
|
file=`mktemp /tmp/zfstest.XXXXXXXX`
|
|
fi
|
|
truncate_cmd ${size} ${file}
|
|
eval file${i}=${file}
|
|
done
|
|
}
|
|
|
|
files_destroy()
|
|
{
|
|
for i in `nums $nfiles 0`; do
|
|
eval file=\$file${i}
|
|
rm -f ${file}
|
|
done
|
|
nfiles=0
|
|
[ -n "${TMPDIR_FILES}" ] && TMPDIR="${TMPDIR_FILES}" cleanup_tmpfs
|
|
return 0
|
|
}
|
|
|
|
name_create()
|
|
{
|
|
echo "zfstest_`dd if=/dev/urandom bs=1k count=1 2>/dev/null | openssl md5 | cut -b -8`"
|
|
}
|
|
|
|
names_create()
|
|
{
|
|
nnames=$1
|
|
for i in `nums $nnames 0`; do
|
|
eval name${i}=`name_create`
|
|
done
|
|
}
|
|
|
|
is_mountpoint()
|
|
{
|
|
dir="${1}"
|
|
if [ ! -d "${dir}" ]; then
|
|
return 1
|
|
fi
|
|
if [ -n "${GNU_STAT}" ]; then
|
|
statcmd="stat -c"
|
|
else
|
|
statcmd="stat -f"
|
|
fi
|
|
if [ "`${statcmd} '%d' ${dir} 2>/dev/null`" -eq "`${statcmd} '%d' ${dir}/.. 2>/dev/null`" ]; then
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
nums()
|
|
{
|
|
which jot >/dev/null 2>&1
|
|
if [ $? -eq 0 ]; then
|
|
jot ${1} ${2}
|
|
return $?
|
|
fi
|
|
|
|
start="${2}"
|
|
[ -z "${start}" ] && start="1";
|
|
end=$((${1}+${start}-1))
|
|
|
|
which seq >/dev/null 2>&1
|
|
if [ $? -eq 0 ]; then
|
|
seq ${start} ${end}
|
|
return $?
|
|
fi
|
|
|
|
i=1
|
|
while :; do
|
|
echo $i
|
|
if [ $i -eq ${1} ]; then
|
|
break
|
|
fi
|
|
i=$((i+1))
|
|
done
|
|
}
|
|
|
|
wait_for_resilver()
|
|
{
|
|
for i in `nums 64`; do
|
|
${ZPOOL} status ${1} | grep replacing >/dev/null
|
|
if [ $? -ne 0 ]; then
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
}
|
|
|
|
get_guid()
|
|
{
|
|
${ZDB} -l ${1} | grep -B1 ${1} | grep guid | head -n1 | awk 'BEGIN {FS="="} {print $2}'
|
|
}
|