Notable upstream pull request merges:
 #17042 ece35e0e6 zpool: allow relative vdev paths
 #17046 c43df8bbb vdev_file: unify FreeBSD and Linux implementations
 #17064 ee8803adc vdev_file: make FLUSH and TRIM asynchronous
 #17066 ecc44c45c include: move zio_priority_t into zfs.h
 #17071 ab3db6d15 arc: avoid possible deadlock in arc_read
 #17079 682c5f6a0 Fix wrong free function in arc_hdr_decrypt
 #17080 701093c44 Don't try to get mg of hole vdev in removal
 #17081 d7d274471 Better fill empty metaslabs
 #17088 a5fb5c55b spa: fix signature mismatch for spa_boot_init as
                  eventhandler required
 #17089 7f05fface gcm_avx_init: zero the ghash state after hashing the IV
 #17122 fe674998b Check portable objset MAC even if local is zeroed

Obtained from:	OpenZFS
OpenZFS commit:	fe674998bb
This commit is contained in:
Martin Matuska committed 2025-03-09 12:52:57 +01:00
commit d2a8fad357
101 files changed
+26005 -1030

No files matched your search

+1 -1
View File
@@ -207,7 +207,6 @@ contrib/openzfs/module/os/freebsd/zfs/hkdf.c optional zfs compile-with "${ZFS_C
contrib/openzfs/module/os/freebsd/zfs/kmod_core.c optional zfs compile-with "${ZFS_C}"
contrib/openzfs/module/os/freebsd/zfs/spa_os.c optional zfs compile-with "${ZFS_C}"
contrib/openzfs/module/os/freebsd/zfs/sysctl_os.c optional zfs compile-with "${ZFS_C} -include $S/modules/zfs/zfs_config.h"
contrib/openzfs/module/os/freebsd/zfs/vdev_file.c optional zfs compile-with "${ZFS_C}"
contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c optional zfs compile-with "${ZFS_C}"
contrib/openzfs/module/os/freebsd/zfs/vdev_geom.c optional zfs compile-with "${ZFS_C}"
contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c optional zfs compile-with "${ZFS_C}"
@@ -332,6 +331,7 @@ contrib/openzfs/module/zfs/unique.c optional zfs compile-with "${ZFS_C}"
contrib/openzfs/module/zfs/vdev.c optional zfs compile-with "${ZFS_C}"
contrib/openzfs/module/zfs/vdev_draid.c optional zfs compile-with "${ZFS_C}"
contrib/openzfs/module/zfs/vdev_draid_rand.c optional zfs compile-with "${ZFS_C}"
contrib/openzfs/module/zfs/vdev_file.c optional zfs compile-with "${ZFS_C}"
contrib/openzfs/module/zfs/vdev_indirect.c optional zfs compile-with "${ZFS_C}"
contrib/openzfs/module/zfs/vdev_indirect_births.c optional zfs compile-with "${ZFS_C}"
contrib/openzfs/module/zfs/vdev_indirect_mapping.c optional zfs compile-with "${ZFS_C}"
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
run: |
# for x in lxd core20 snapd; do sudo snap remove $x; done
sudo apt-get purge -y snapd google-chrome-stable firefox
ONLY_DEPS=1 .github/workflows/scripts/qemu-3-deps.sh ubuntu22
ONLY_DEPS=1 .github/workflows/scripts/qemu-3-deps-vm.sh ubuntu22
sudo apt-get install -y cppcheck devscripts mandoc pax-utils shellcheck
sudo python -m pipx install --quiet flake8
# confirm that the tools are installed
@@ -220,6 +220,15 @@ sudo virt-install \
--disk $DISK,bus=virtio,cache=none,format=$FORMAT,driver.discard=unmap \
--import --noautoconsole >/dev/null
# Give the VMs hostnames so we don't have to refer to them with
# hardcoded IP addresses.
#
# vm0: Initial VM we install dependencies and build ZFS on.
# vm1..2 Testing VMs
for i in {0..9} ; do
echo "192.168.122.1$i vm$i" | sudo tee -a /etc/hosts
done
# in case the directory isn't there already
mkdir -p $HOME/.ssh
+232
View File
@@ -0,0 +1,232 @@
#!/usr/bin/env bash
######################################################################
# 3) install dependencies for compiling and loading
#
# $1: OS name (like 'fedora41')
######################################################################
set -eu
function archlinux() {
echo "##[group]Running pacman -Syu"
sudo btrfs filesystem resize max /
sudo pacman -Syu --noconfirm
echo "##[endgroup]"
echo "##[group]Install Development Tools"
sudo pacman -Sy --noconfirm base-devel bc cpio cryptsetup dhclient dkms \
fakeroot fio gdb inetutils jq less linux linux-headers lsscsi nfs-utils \
parted pax perf python-packaging python-setuptools qemu-guest-agent ksh \
samba sysstat rng-tools rsync wget xxhash
echo "##[endgroup]"
}
function debian() {
export DEBIAN_FRONTEND="noninteractive"
echo "##[group]Running apt-get update+upgrade"
sudo apt-get update -y
sudo apt-get upgrade -y
echo "##[endgroup]"
echo "##[group]Install Development Tools"
sudo apt-get install -y \
acl alien attr autoconf bc cpio cryptsetup curl dbench dh-python dkms \
fakeroot fio gdb gdebi git ksh lcov isc-dhcp-client jq libacl1-dev \
libaio-dev libattr1-dev libblkid-dev libcurl4-openssl-dev libdevmapper-dev \
libelf-dev libffi-dev libmount-dev libpam0g-dev libselinux-dev libssl-dev \
libtool libtool-bin libudev-dev libunwind-dev linux-headers-$(uname -r) \
lsscsi nfs-kernel-server pamtester parted python3 python3-all-dev \
python3-cffi python3-dev python3-distlib python3-packaging \
python3-setuptools python3-sphinx qemu-guest-agent rng-tools rpm2cpio \
rsync samba sysstat uuid-dev watchdog wget xfslibs-dev xxhash zlib1g-dev
echo "##[endgroup]"
}
function freebsd() {
export ASSUME_ALWAYS_YES="YES"
echo "##[group]Install Development Tools"
sudo pkg install -y autoconf automake autotools base64 checkbashisms fio \
gdb gettext gettext-runtime git gmake gsed jq ksh93 lcov libtool lscpu \
pkgconf python python3 pamtester pamtester qemu-guest-agent rsync xxhash
sudo pkg install -xy \
'^samba4[[:digit:]]+$' \
'^py3[[:digit:]]+-cffi$' \
'^py3[[:digit:]]+-sysctl$' \
'^py3[[:digit:]]+-packaging$'
echo "##[endgroup]"
}
# common packages for: almalinux, centos, redhat
function rhel() {
echo "##[group]Running dnf update"
echo "max_parallel_downloads=10" | sudo -E tee -a /etc/dnf/dnf.conf
sudo dnf clean all
sudo dnf update -y --setopt=fastestmirror=1 --refresh
echo "##[endgroup]"
echo "##[group]Install Development Tools"
# Alma wants "Development Tools", Fedora 41 wants "development-tools"
if ! sudo dnf group install -y "Development Tools" ; then
echo "Trying 'development-tools' instead of 'Development Tools'"
sudo dnf group install -y development-tools
fi
sudo dnf install -y \
acl attr bc bzip2 cryptsetup curl dbench dkms elfutils-libelf-devel fio \
gdb git jq kernel-rpm-macros ksh libacl-devel libaio-devel \
libargon2-devel libattr-devel libblkid-devel libcurl-devel libffi-devel \
ncompress libselinux-devel libtirpc-devel libtool libudev-devel \
libuuid-devel lsscsi mdadm nfs-utils openssl-devel pam-devel pamtester \
parted perf python3 python3-cffi python3-devel python3-packaging \
kernel-devel python3-setuptools qemu-guest-agent rng-tools rpcgen \
rpm-build rsync samba sysstat systemd watchdog wget xfsprogs-devel xxhash \
zlib-devel
echo "##[endgroup]"
}
function tumbleweed() {
echo "##[group]Running zypper is TODO!"
sleep 23456
echo "##[endgroup]"
}
# Install dependencies
case "$1" in
almalinux8)
echo "##[group]Enable epel and powertools repositories"
sudo dnf config-manager -y --set-enabled powertools
sudo dnf install -y epel-release
echo "##[endgroup]"
rhel
echo "##[group]Install kernel-abi-whitelists"
sudo dnf install -y kernel-abi-whitelists
echo "##[endgroup]"
;;
almalinux9|centos-stream9|centos-stream10)
echo "##[group]Enable epel and crb repositories"
sudo dnf config-manager -y --set-enabled crb
sudo dnf install -y epel-release
echo "##[endgroup]"
rhel
echo "##[group]Install kernel-abi-stablelists"
sudo dnf install -y kernel-abi-stablelists
echo "##[endgroup]"
;;
archlinux)
archlinux
;;
debian*)
echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
debian
echo "##[group]Install Debian specific"
sudo apt-get install -yq linux-perf dh-sequence-dkms
echo "##[endgroup]"
;;
fedora*)
rhel
sudo dnf install -y libunwind-devel
;;
freebsd*)
freebsd
;;
tumbleweed)
tumbleweed
;;
ubuntu*)
debian
echo "##[group]Install Ubuntu specific"
sudo apt-get install -yq linux-tools-common libtirpc-dev \
linux-modules-extra-$(uname -r)
if [ "$1" != "ubuntu20" ]; then
sudo apt-get install -yq dh-sequence-dkms
fi
echo "##[endgroup]"
echo "##[group]Delete Ubuntu OpenZFS modules"
for i in $(find /lib/modules -name zfs -type d); do sudo rm -rvf $i; done
echo "##[endgroup]"
;;
esac
# This script is used for checkstyle + zloop deps also.
# Install only the needed packages and exit - when used this way.
test -z "${ONLY_DEPS:-}" || exit 0
# Start services
echo "##[group]Enable services"
case "$1" in
freebsd*)
# add virtio things
echo 'virtio_load="YES"' | sudo -E tee -a /boot/loader.conf
for i in balloon blk console random scsi; do
echo "virtio_${i}_load=\"YES\"" | sudo -E tee -a /boot/loader.conf
done
echo "fdescfs /dev/fd fdescfs rw 0 0" | sudo -E tee -a /etc/fstab
sudo -E mount /dev/fd
sudo -E touch /etc/zfs/exports
sudo -E sysrc mountd_flags="/etc/zfs/exports"
echo '[global]' | sudo -E tee /usr/local/etc/smb4.conf >/dev/null
sudo -E service nfsd enable
sudo -E service qemu-guest-agent enable
sudo -E service samba_server enable
;;
debian*|ubuntu*)
sudo -E systemctl enable nfs-kernel-server
sudo -E systemctl enable qemu-guest-agent
sudo -E systemctl enable smbd
;;
*)
# All other linux distros
sudo -E systemctl enable nfs-server
sudo -E systemctl enable qemu-guest-agent
sudo -E systemctl enable smb
;;
esac
echo "##[endgroup]"
# Setup Kernel cmdline
CMDLINE="console=tty0 console=ttyS0,115200n8"
CMDLINE="$CMDLINE selinux=0"
CMDLINE="$CMDLINE random.trust_cpu=on"
CMDLINE="$CMDLINE no_timer_check"
case "$1" in
almalinux*|centos*|fedora*)
GRUB_CFG="/boot/grub2/grub.cfg"
GRUB_MKCONFIG="grub2-mkconfig"
CMDLINE="$CMDLINE biosdevname=0 net.ifnames=0"
echo 'GRUB_SERIAL_COMMAND="serial --speed=115200"' \
| sudo tee -a /etc/default/grub >/dev/null
;;
ubuntu24)
GRUB_CFG="/boot/grub/grub.cfg"
GRUB_MKCONFIG="grub-mkconfig"
echo 'GRUB_DISABLE_OS_PROBER="false"' \
| sudo tee -a /etc/default/grub >/dev/null
;;
*)
GRUB_CFG="/boot/grub/grub.cfg"
GRUB_MKCONFIG="grub-mkconfig"
;;
esac
case "$1" in
archlinux|freebsd*)
true
;;
*)
echo "##[group]Edit kernel cmdline"
sudo sed -i -e '/^GRUB_CMDLINE_LINUX/d' /etc/default/grub || true
echo "GRUB_CMDLINE_LINUX=\"$CMDLINE\"" \
| sudo tee -a /etc/default/grub >/dev/null
sudo $GRUB_MKCONFIG -o $GRUB_CFG
echo "##[endgroup]"
;;
esac
# reset cloud-init configuration and poweroff
sudo cloud-init clean --logs
sleep 2 && sudo poweroff &
exit 0
+12 -226
View File
@@ -1,229 +1,15 @@
#!/usr/bin/env bash
######################################################################
# 3) install dependencies for compiling and loading
# 3) Wait for VM to boot from previous step and launch dependencies
# script on it.
#
# $1: OS name (like 'fedora41')
######################################################################
set -eu
function archlinux() {
echo "##[group]Running pacman -Syu"
sudo btrfs filesystem resize max /
sudo pacman -Syu --noconfirm
echo "##[endgroup]"
echo "##[group]Install Development Tools"
sudo pacman -Sy --noconfirm base-devel bc cpio cryptsetup dhclient dkms \
fakeroot fio gdb inetutils jq less linux linux-headers lsscsi nfs-utils \
parted pax perf python-packaging python-setuptools qemu-guest-agent ksh \
samba sysstat rng-tools rsync wget xxhash
echo "##[endgroup]"
}
function debian() {
export DEBIAN_FRONTEND="noninteractive"
echo "##[group]Running apt-get update+upgrade"
sudo apt-get update -y
sudo apt-get upgrade -y
echo "##[endgroup]"
echo "##[group]Install Development Tools"
sudo apt-get install -y \
acl alien attr autoconf bc cpio cryptsetup curl dbench dh-python dkms \
fakeroot fio gdb gdebi git ksh lcov isc-dhcp-client jq libacl1-dev \
libaio-dev libattr1-dev libblkid-dev libcurl4-openssl-dev libdevmapper-dev \
libelf-dev libffi-dev libmount-dev libpam0g-dev libselinux-dev libssl-dev \
libtool libtool-bin libudev-dev libunwind-dev linux-headers-$(uname -r) \
lsscsi nfs-kernel-server pamtester parted python3 python3-all-dev \
python3-cffi python3-dev python3-distlib python3-packaging \
python3-setuptools python3-sphinx qemu-guest-agent rng-tools rpm2cpio \
rsync samba sysstat uuid-dev watchdog wget xfslibs-dev xxhash zlib1g-dev
echo "##[endgroup]"
}
function freebsd() {
export ASSUME_ALWAYS_YES="YES"
echo "##[group]Install Development Tools"
sudo pkg install -y autoconf automake autotools base64 checkbashisms fio \
gdb gettext gettext-runtime git gmake gsed jq ksh93 lcov libtool lscpu \
pkgconf python python3 pamtester pamtester qemu-guest-agent rsync xxhash
sudo pkg install -xy \
'^samba4[[:digit:]]+$' \
'^py3[[:digit:]]+-cffi$' \
'^py3[[:digit:]]+-sysctl$' \
'^py3[[:digit:]]+-packaging$'
echo "##[endgroup]"
}
# common packages for: almalinux, centos, redhat
function rhel() {
echo "##[group]Running dnf update"
echo "max_parallel_downloads=10" | sudo -E tee -a /etc/dnf/dnf.conf
sudo dnf clean all
sudo dnf update -y --setopt=fastestmirror=1 --refresh
echo "##[endgroup]"
echo "##[group]Install Development Tools"
# Alma wants "Development Tools", Fedora 41 wants "development-tools"
if ! sudo dnf group install -y "Development Tools" ; then
echo "Trying 'development-tools' instead of 'Development Tools'"
sudo dnf group install -y development-tools
fi
sudo dnf install -y \
acl attr bc bzip2 cryptsetup curl dbench dkms elfutils-libelf-devel fio \
gdb git jq kernel-rpm-macros ksh libacl-devel libaio-devel \
libargon2-devel libattr-devel libblkid-devel libcurl-devel libffi-devel \
ncompress libselinux-devel libtirpc-devel libtool libudev-devel \
libuuid-devel lsscsi mdadm nfs-utils openssl-devel pam-devel pamtester \
parted perf python3 python3-cffi python3-devel python3-packaging \
kernel-devel python3-setuptools qemu-guest-agent rng-tools rpcgen \
rpm-build rsync samba sysstat systemd watchdog wget xfsprogs-devel xxhash \
zlib-devel
echo "##[endgroup]"
}
function tumbleweed() {
echo "##[group]Running zypper is TODO!"
sleep 23456
echo "##[endgroup]"
}
# Install dependencies
case "$1" in
almalinux8)
echo "##[group]Enable epel and powertools repositories"
sudo dnf config-manager -y --set-enabled powertools
sudo dnf install -y epel-release
echo "##[endgroup]"
rhel
echo "##[group]Install kernel-abi-whitelists"
sudo dnf install -y kernel-abi-whitelists
echo "##[endgroup]"
;;
almalinux9|centos-stream9|centos-stream10)
echo "##[group]Enable epel and crb repositories"
sudo dnf config-manager -y --set-enabled crb
sudo dnf install -y epel-release
echo "##[endgroup]"
rhel
echo "##[group]Install kernel-abi-stablelists"
sudo dnf install -y kernel-abi-stablelists
echo "##[endgroup]"
;;
archlinux)
archlinux
;;
debian*)
echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
debian
echo "##[group]Install Debian specific"
sudo apt-get install -yq linux-perf dh-sequence-dkms
echo "##[endgroup]"
;;
fedora*)
rhel
;;
freebsd*)
freebsd
;;
tumbleweed)
tumbleweed
;;
ubuntu*)
debian
echo "##[group]Install Ubuntu specific"
sudo apt-get install -yq linux-tools-common libtirpc-dev \
linux-modules-extra-$(uname -r)
if [ "$1" != "ubuntu20" ]; then
sudo apt-get install -yq dh-sequence-dkms
fi
echo "##[endgroup]"
echo "##[group]Delete Ubuntu OpenZFS modules"
for i in $(find /lib/modules -name zfs -type d); do sudo rm -rvf $i; done
echo "##[endgroup]"
;;
esac
# This script is used for checkstyle + zloop deps also.
# Install only the needed packages and exit - when used this way.
test -z "${ONLY_DEPS:-}" || exit 0
# Start services
echo "##[group]Enable services"
case "$1" in
freebsd*)
# add virtio things
echo 'virtio_load="YES"' | sudo -E tee -a /boot/loader.conf
for i in balloon blk console random scsi; do
echo "virtio_${i}_load=\"YES\"" | sudo -E tee -a /boot/loader.conf
done
echo "fdescfs /dev/fd fdescfs rw 0 0" | sudo -E tee -a /etc/fstab
sudo -E mount /dev/fd
sudo -E touch /etc/zfs/exports
sudo -E sysrc mountd_flags="/etc/zfs/exports"
echo '[global]' | sudo -E tee /usr/local/etc/smb4.conf >/dev/null
sudo -E service nfsd enable
sudo -E service qemu-guest-agent enable
sudo -E service samba_server enable
;;
debian*|ubuntu*)
sudo -E systemctl enable nfs-kernel-server
sudo -E systemctl enable qemu-guest-agent
sudo -E systemctl enable smbd
;;
*)
# All other linux distros
sudo -E systemctl enable nfs-server
sudo -E systemctl enable qemu-guest-agent
sudo -E systemctl enable smb
;;
esac
echo "##[endgroup]"
# Setup Kernel cmdline
CMDLINE="console=tty0 console=ttyS0,115200n8"
CMDLINE="$CMDLINE selinux=0"
CMDLINE="$CMDLINE random.trust_cpu=on"
CMDLINE="$CMDLINE no_timer_check"
case "$1" in
almalinux*|centos*|fedora*)
GRUB_CFG="/boot/grub2/grub.cfg"
GRUB_MKCONFIG="grub2-mkconfig"
CMDLINE="$CMDLINE biosdevname=0 net.ifnames=0"
echo 'GRUB_SERIAL_COMMAND="serial --speed=115200"' \
| sudo tee -a /etc/default/grub >/dev/null
;;
ubuntu24)
GRUB_CFG="/boot/grub/grub.cfg"
GRUB_MKCONFIG="grub-mkconfig"
echo 'GRUB_DISABLE_OS_PROBER="false"' \
| sudo tee -a /etc/default/grub >/dev/null
;;
*)
GRUB_CFG="/boot/grub/grub.cfg"
GRUB_MKCONFIG="grub-mkconfig"
;;
esac
case "$1" in
archlinux|freebsd*)
true
;;
*)
echo "##[group]Edit kernel cmdline"
sudo sed -i -e '/^GRUB_CMDLINE_LINUX/d' /etc/default/grub || true
echo "GRUB_CMDLINE_LINUX=\"$CMDLINE\"" \
| sudo tee -a /etc/default/grub >/dev/null
sudo $GRUB_MKCONFIG -o $GRUB_CFG
echo "##[endgroup]"
;;
esac
# reset cloud-init configuration and poweroff
sudo cloud-init clean --logs
sleep 2 && sudo poweroff &
exit 0
.github/workflows/scripts/qemu-wait-for-vm.sh vm0
scp .github/workflows/scripts/qemu-3-deps-vm.sh zfs@vm0:qemu-3-deps-vm.sh
PID=`pidof /usr/bin/qemu-system-x86_64`
ssh zfs@vm0 '$HOME/qemu-3-deps-vm.sh' $1
# wait for poweroff to succeed
tail --pid=$PID -f /dev/null
sleep 5 # avoid this: "error: Domain is already active"
rm -f $HOME/.ssh/known_hosts
+370
View File
@@ -0,0 +1,370 @@
#!/usr/bin/env bash
######################################################################
# 4) configure and build openzfs modules. This is run on the VMs.
#
# Usage:
#
# qemu-4-build-vm.sh OS [--enable-debug][--dkms][--poweroff]
# [--release][--repo][--tarball]
#
# OS: OS name like 'fedora41'
# --enable-debug: Build RPMs with '--enable-debug' (for testing)
# --dkms: Build DKMS RPMs as well
# --poweroff: Power-off the VM after building
# --release Build zfs-release*.rpm as well
# --repo After building everything, copy RPMs into /tmp/repo
# in the ZFS RPM repository file structure. Also
# copy tarballs if they were built.
# --tarball: Also build a tarball of ZFS source
######################################################################
ENABLE_DEBUG=""
DKMS=""
POWEROFF=""
RELEASE=""
REPO=""
TARBALL=""
while [[ $# -gt 0 ]]; do
case $1 in
--enable-debug)
ENABLE_DEBUG=1
shift
;;
--dkms)
DKMS=1
shift
;;
--poweroff)
POWEROFF=1
shift
;;
--release)
RELEASE=1
shift
;;
--repo)
REPO=1
shift
;;
--tarball)
TARBALL=1
shift
;;
*)
OS=$1
shift
;;
esac
done
set -eu
function run() {
LOG="/var/tmp/build-stderr.txt"
echo "****************************************************"
echo "$(date) ($*)"
echo "****************************************************"
($@ || echo $? > /tmp/rv) 3>&1 1>&2 2>&3 | stdbuf -eL -oL tee -a $LOG
if [ -f /tmp/rv ]; then
RV=$(cat /tmp/rv)
echo "****************************************************"
echo "exit with value=$RV ($*)"
echo "****************************************************"
echo 1 > /var/tmp/build-exitcode.txt
exit $RV
fi
}
# Look at the RPMs in the current directory and copy/move them to
# /tmp/repo, using the directory structure we use for the ZFS RPM repos.
#
# For example:
# /tmp/repo/epel-testing/9.5
# /tmp/repo/epel-testing/9.5/SRPMS
# /tmp/repo/epel-testing/9.5/SRPMS/zfs-2.3.99-1.el9.src.rpm
# /tmp/repo/epel-testing/9.5/SRPMS/zfs-kmod-2.3.99-1.el9.src.rpm
# /tmp/repo/epel-testing/9.5/kmod
# /tmp/repo/epel-testing/9.5/kmod/x86_64
# /tmp/repo/epel-testing/9.5/kmod/x86_64/debug
# /tmp/repo/epel-testing/9.5/kmod/x86_64/debug/kmod-zfs-debuginfo-2.3.99-1.el9.x86_64.rpm
# /tmp/repo/epel-testing/9.5/kmod/x86_64/debug/libnvpair3-debuginfo-2.3.99-1.el9.x86_64.rpm
# /tmp/repo/epel-testing/9.5/kmod/x86_64/debug/libuutil3-debuginfo-2.3.99-1.el9.x86_64.rpm
# ...
function copy_rpms_to_repo {
# Pick a RPM to query. It doesn't matter which one - we just want to extract
# the 'Build Host' value from it.
rpm=$(ls zfs-*.rpm | head -n 1)
# Get zfs version '2.2.99'
zfs_ver=$(rpm -qpi $rpm | awk '/Version/{print $3}')
# Get "2.1" or "2.2"
zfs_major=$(echo $zfs_ver | grep -Eo [0-9]+\.[0-9]+)
# Get 'almalinux9.5' or 'fedora41' type string
build_host=$(rpm -qpi $rpm | awk '/Build Host/{print $4}')
# Get '9.5' or '41' OS version
os_ver=$(echo $build_host | grep -Eo '[0-9\.]+$')
# Our ZFS version and OS name will determine which repo the RPMs
# will go in (regular or testing). Fedora always gets the newest
# releases, and Alma gets the older releases.
case $build_host in
almalinux*)
case $zfs_major in
2.2)
d="epel"
;;
*)
d="epel-testing"
;;
esac
;;
fedora*)
d="fedora"
;;
esac
prefix=/tmp/repo
dst="$prefix/$d/$os_ver"
# Special case: move zfs-release*.rpm out of the way first (if we built them).
# This will make filtering the other RPMs easier.
mkdir -p $dst
mv zfs-release*.rpm $dst || true
# Copy source RPMs
mkdir -p $dst/SRPMS
cp $(ls *.src.rpm) $dst/SRPMS/
if [[ "$build_host" =~ "almalinux" ]] ; then
# Copy kmods+userspace
mkdir -p $dst/kmod/x86_64/debug
cp $(ls *.rpm | grep -Ev 'src.rpm|dkms|debuginfo') $dst/kmod/x86_64
cp *debuginfo*.rpm $dst/kmod/x86_64/debug
fi
if [ -n "$DKMS" ] ; then
# Copy dkms+userspace
mkdir -p $dst/x86_64
cp $(ls *.rpm | grep -Ev 'src.rpm|kmod|debuginfo') $dst/x86_64
fi
# Copy debug
mkdir -p $dst/x86_64/debug
cp $(ls *debuginfo*.rpm | grep -v kmod) $dst/x86_64/debug
}
function freebsd() {
extra="${1:-}"
export MAKE="gmake"
echo "##[group]Autogen.sh"
run ./autogen.sh
echo "##[endgroup]"
echo "##[group]Configure"
run ./configure \
--prefix=/usr/local \
--with-libintl-prefix=/usr/local \
--enable-pyzfs \
--enable-debuginfo $extra
echo "##[endgroup]"
echo "##[group]Build"
run gmake -j$(sysctl -n hw.ncpu)
echo "##[endgroup]"
echo "##[group]Install"
run sudo gmake install
echo "##[endgroup]"
}
function linux() {
extra="${1:-}"
echo "##[group]Autogen.sh"
run ./autogen.sh
echo "##[endgroup]"
echo "##[group]Configure"
run ./configure \
--prefix=/usr \
--enable-pyzfs \
--enable-debuginfo $extra
echo "##[endgroup]"
echo "##[group]Build"
run make -j$(nproc)
echo "##[endgroup]"
echo "##[group]Install"
run sudo make install
echo "##[endgroup]"
}
function rpm_build_and_install() {
extra="${1:-}"
# Build RPMs with XZ compression by default (since gzip decompression is slow)
echo "%_binary_payload w7.xzdio" >> ~/.rpmmacros
echo "##[group]Autogen.sh"
run ./autogen.sh
echo "##[endgroup]"
echo "##[group]Configure"
run ./configure --enable-debuginfo $extra
echo "##[endgroup]"
echo "##[group]Build"
run make pkg-kmod pkg-utils
echo "##[endgroup]"
if [ -n "$DKMS" ] ; then
echo "##[group]DKMS"
make rpm-dkms
echo "##[endgroup]"
fi
if [ -n "$REPO" ] ; then
echo "Skipping install since we're only building RPMs and nothing else"
else
echo "##[group]Install"
run sudo dnf -y --nobest install $(ls *.rpm | grep -Ev 'dkms|src.rpm')
echo "##[endgroup]"
fi
# Optionally build the zfs-release.*.rpm
if [ -n "$RELEASE" ] ; then
echo "##[group]Release"
pushd ~
sudo dnf -y install rpm-build || true
# Check out a sparse copy of zfsonlinux.github.com.git so we don't get
# all the binaries. We just need a few kilobytes of files to build RPMs.
git clone --depth 1 --no-checkout \
https://github.com/zfsonlinux/zfsonlinux.github.com.git
cd zfsonlinux.github.com
git sparse-checkout set zfs-release
git checkout
cd zfs-release
mkdir -p ~/rpmbuild/{BUILDROOT,SPECS,RPMS,SRPMS,SOURCES,BUILD}
cp RPM-GPG-KEY-openzfs* *.repo ~/rpmbuild/SOURCES
cp zfs-release.spec ~/rpmbuild/SPECS/
rpmbuild -ba ~/rpmbuild/SPECS/zfs-release.spec
# ZFS release RPMs are built. Copy them to the ~/zfs directory just to
# keep all the RPMs in the same place.
cp ~/rpmbuild/RPMS/noarch/*.rpm .
cp ~/rpmbuild/SRPMS/*.rpm .
popd
rm -fr ~/rpmbuild
echo "##[endgroup]"
fi
if [ -n "$REPO" ] ; then
echo "##[group]Repo"
copy_rpms_to_repo
echo "##[endgroup]"
fi
}
function deb_build_and_install() {
extra="${1:-}"
echo "##[group]Autogen.sh"
run ./autogen.sh
echo "##[endgroup]"
echo "##[group]Configure"
run ./configure \
--prefix=/usr \
--enable-pyzfs \
--enable-debuginfo $extra
echo "##[endgroup]"
echo "##[group]Build"
run make native-deb-kmod native-deb-utils
echo "##[endgroup]"
echo "##[group]Install"
# Do kmod install. Note that when you build the native debs, the
# packages themselves are placed in parent directory '../' rather than
# in the source directory like the rpms are.
run sudo apt-get -y install $(find ../ | grep -E '\.deb$' \
| grep -Ev 'dkms|dracut')
echo "##[endgroup]"
}
# Debug: show kernel cmdline
if [ -f /proc/cmdline ] ; then
cat /proc/cmdline || true
fi
# Set our hostname to our OS name and version number. Specifically, we set the
# major and minor number so that when we query the Build Host field in the RPMs
# we build, we can see what specific version of Fedora/Almalinux we were using
# to build them. This is helpful for matching up KMOD versions.
#
# Examples:
#
# rhel8.10
# almalinux9.5
# fedora40
source /etc/os-release
sudo hostname "$ID$VERSION_ID"
# save some sysinfo
uname -a > /var/tmp/uname.txt
cd $HOME/zfs
export PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin"
extra=""
if [ -n "$ENABLE_DEBUG" ] ; then
extra="--enable-debug"
fi
# build
case "$OS" in
freebsd*)
freebsd "$extra"
;;
alma*|centos*)
rpm_build_and_install "--with-spec=redhat $extra"
;;
fedora*)
rpm_build_and_install "$extra"
;;
debian*|ubuntu*)
deb_build_and_install "$extra"
;;
*)
linux "$extra"
;;
esac
# Optionally build tarballs. The tarball's root directory name will be named
# after the current tag, like 'zfs-2.3.0' or 'master'.
if [ -n "$TARBALL" ] ; then
tag="$(git symbolic-ref -q --short HEAD || git describe --tags --exact-match)"
git archive --format=tar.gz -o $tag.tar.gz $tag
if [ -n "$REPO" ] ; then
mkdir -p /tmp/repo/releases
cp $tag.tar.gz /tmp/repo/releases
fi
fi
# building the zfs module was ok
echo 0 > /var/tmp/build-exitcode.txt
# reset cloud-init configuration and poweroff
if [ -n "$POWEROFF" ] ; then
sudo cloud-init clean --logs
sync && sleep 2 && sudo poweroff &
fi
exit 0
+4 -146
View File
@@ -3,151 +3,9 @@
######################################################################
# 4) configure and build openzfs modules
######################################################################
echo "Build modules in QEMU machine"
set -eu
# Bring our VM back up and copy over ZFS source
.github/workflows/scripts/qemu-prepare-for-build.sh
function run() {
LOG="/var/tmp/build-stderr.txt"
echo "****************************************************"
echo "$(date) ($*)"
echo "****************************************************"
($@ || echo $? > /tmp/rv) 3>&1 1>&2 2>&3 | stdbuf -eL -oL tee -a $LOG
if [ -f /tmp/rv ]; then
RV=$(cat /tmp/rv)
echo "****************************************************"
echo "exit with value=$RV ($*)"
echo "****************************************************"
echo 1 > /var/tmp/build-exitcode.txt
exit $RV
fi
}
function freebsd() {
export MAKE="gmake"
echo "##[group]Autogen.sh"
run ./autogen.sh
echo "##[endgroup]"
echo "##[group]Configure"
run ./configure \
--prefix=/usr/local \
--with-libintl-prefix=/usr/local \
--enable-pyzfs \
--enable-debug \
--enable-debuginfo
echo "##[endgroup]"
echo "##[group]Build"
run gmake -j$(sysctl -n hw.ncpu)
echo "##[endgroup]"
echo "##[group]Install"
run sudo gmake install
echo "##[endgroup]"
}
function linux() {
echo "##[group]Autogen.sh"
run ./autogen.sh
echo "##[endgroup]"
echo "##[group]Configure"
run ./configure \
--prefix=/usr \
--enable-pyzfs \
--enable-debug \
--enable-debuginfo
echo "##[endgroup]"
echo "##[group]Build"
run make -j$(nproc)
echo "##[endgroup]"
echo "##[group]Install"
run sudo make install
echo "##[endgroup]"
}
function rpm_build_and_install() {
EXTRA_CONFIG="${1:-}"
echo "##[group]Autogen.sh"
run ./autogen.sh
echo "##[endgroup]"
echo "##[group]Configure"
run ./configure --enable-debug --enable-debuginfo $EXTRA_CONFIG
echo "##[endgroup]"
echo "##[group]Build"
run make pkg-kmod pkg-utils
echo "##[endgroup]"
echo "##[group]Install"
run sudo dnf -y --nobest install $(ls *.rpm | grep -v src.rpm)
echo "##[endgroup]"
}
function deb_build_and_install() {
echo "##[group]Autogen.sh"
run ./autogen.sh
echo "##[endgroup]"
echo "##[group]Configure"
run ./configure \
--prefix=/usr \
--enable-pyzfs \
--enable-debug \
--enable-debuginfo
echo "##[endgroup]"
echo "##[group]Build"
run make native-deb-kmod native-deb-utils
echo "##[endgroup]"
echo "##[group]Install"
# Do kmod install. Note that when you build the native debs, the
# packages themselves are placed in parent directory '../' rather than
# in the source directory like the rpms are.
run sudo apt-get -y install $(find ../ | grep -E '\.deb$' \
| grep -Ev 'dkms|dracut')
echo "##[endgroup]"
}
# Debug: show kernel cmdline
if [ -f /proc/cmdline ] ; then
cat /proc/cmdline || true
fi
# save some sysinfo
uname -a > /var/tmp/uname.txt
cd $HOME/zfs
export PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin"
# build
case "$1" in
freebsd*)
freebsd
;;
alma*|centos*)
rpm_build_and_install "--with-spec=redhat"
;;
fedora*)
rpm_build_and_install
;;
debian*|ubuntu*)
deb_build_and_install
;;
*)
linux
;;
esac
# building the zfs module was ok
echo 0 > /var/tmp/build-exitcode.txt
# reset cloud-init configuration and poweroff
sudo cloud-init clean --logs
sync && sleep 2 && sudo poweroff &
exit 0
ssh zfs@vm0 '$HOME/zfs/.github/workflows/scripts/qemu-4-build-vm.sh' $@
@@ -109,9 +109,7 @@ rm crontab.txt
# check if the machines are okay
echo "Waiting for vm's to come up... (${VMs}x CPU=$CPU RAM=$RAM)"
for i in $(seq 1 $VMs); do
while true; do
ssh 2>/dev/null [email protected]$i "uname -a" && break
done
.github/workflows/scripts/qemu-wait-for-vm.sh vm$i
done
echo "All $VMs VMs are up now."
@@ -29,8 +29,9 @@ MERGE="$BASE/.github/workflows/scripts/merge_summary.awk"
# catch result files of testings (vm's should be there)
for i in $(seq 1 $VMs); do
rsync -arL zfs@192.168.122.1$i:$RESPATH/current $RESPATH/vm$i || true
scp zfs@192.168.122.1$i:"/var/tmp/*.txt" $RESPATH/vm$i || true
rsync -arL zfs@vm$i:$RESPATH/current $RESPATH/vm$i || true
scp zfs@vm$i:"/var/tmp/*.txt" $RESPATH/vm$i || true
scp zfs@vm$i:"/var/tmp/*.rpm" $RESPATH/vm$i || true
done
cp -f /var/tmp/*.txt $RESPATH || true
cd $RESPATH
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
# Helper script to run after installing dependencies. This brings the VM back
# up and copies over the zfs source directory.
echo "Build modules in QEMU machine"
sudo virsh start openzfs
.github/workflows/scripts/qemu-wait-for-vm.sh vm0
rsync -ar $HOME/work/zfs/zfs zfs@vm0:./
+90
View File
@@ -0,0 +1,90 @@
#!/bin/bash
#
# Do a test install of ZFS from an external repository.
#
# USAGE:
#
# ./qemu-test-repo-vm [URL]
#
# URL: URL to use instead of http://download.zfsonlinux.org
# If blank, use the default repo from zfs-release RPM.
set -e
source /etc/os-release
OS="$ID"
VERSION="$VERSION_ID"
ALTHOST=""
if [ -n "$1" ] ; then
ALTHOST="$1"
fi
# Write summary to /tmp/repo so our artifacts scripts pick it up
mkdir /tmp/repo
SUMMARY=/tmp/repo/$OS-$VERSION-summary.txt
# $1: Repo 'zfs' 'zfs-kmod' 'zfs-testing' 'zfs-testing-kmod'
# $2: (optional) Alternate host than 'http://download.zfsonlinux.org' to
# install from. Blank means use default from zfs-release RPM.
function test_install {
repo=$1
host=""
if [ -n "$2" ] ; then
host=$2
fi
args="--disablerepo=zfs --enablerepo=$repo"
# If we supplied an alternate repo URL, and have not already edited
# zfs.repo, then update the repo file.
if [ -n "$host" ] && ! grep -q $host /etc/yum.repos.d/zfs.repo ; then
sudo sed -i "s;baseurl=http://download.zfsonlinux.org;baseurl=$host;g" /etc/yum.repos.d/zfs.repo
fi
sudo dnf -y install $args zfs zfs-test
# Load modules and create a simple pool as a sanity test.
sudo /usr/share/zfs/zfs.sh -r
truncate -s 100M /tmp/file
sudo zpool create tank /tmp/file
sudo zpool status
# Print out repo name, rpm installed (kmod or dkms), and repo URL
baseurl=$(grep -A 5 "\[$repo\]" /etc/yum.repos.d/zfs.repo | awk -F'=' '/baseurl=/{print $2; exit}')
package=$(sudo rpm -qa | grep zfs | grep -E 'kmod|dkms')
echo "$repo $package $baseurl" >> $SUMMARY
sudo zpool destroy tank
sudo rm /tmp/file
sudo dnf -y remove zfs
}
echo "##[group]Installing from repo"
# The openzfs docs are the authoritative instructions for the install. Use
# the specific version of zfs-release RPM it recommends.
case $OS in
almalinux*)
url='https://raw.githubusercontent.com/openzfs/openzfs-docs/refs/heads/master/docs/Getting%20Started/RHEL-based%20distro/index.rst'
name=$(curl -Ls $url | grep 'dnf install' | grep -Eo 'zfs-release-[0-9]+-[0-9]+')
sudo dnf -y install https://zfsonlinux.org/epel/$name$(rpm --eval "%{dist}").noarch.rpm 2>&1
sudo rpm -qi zfs-release
test_install zfs $ALTHOST
test_install zfs-kmod $ALTHOST
test_install zfs-testing $ALTHOST
test_install zfs-testing-kmod $ALTHOST
;;
fedora*)
url='https://raw.githubusercontent.com/openzfs/openzfs-docs/refs/heads/master/docs/Getting%20Started/Fedora/index.rst'
name=$(curl -Ls $url | grep 'dnf install' | grep -Eo 'zfs-release-[0-9]+-[0-9]+')
sudo dnf -y install -y https://zfsonlinux.org/fedora/$name$(rpm --eval "%{dist}").noarch.rpm
test_install zfs $ALTHOST
;;
esac
echo "##[endgroup]"
# Write out a simple version of the summary here. Later on we will collate all
# the summaries and put them into a nice table in the workflow Summary page.
echo "Summary: "
cat $SUMMARY
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
#
# Wait for a VM to boot up and become active. This is used in a number of our
# scripts.
#
# $1: VM hostname or IP address
while pidof /usr/bin/qemu-system-x86_64 >/dev/null; do
ssh 2>/dev/null zfs@$1 "uname -a" && break
done
@@ -0,0 +1,32 @@
#!/bin/bash
#
# Recursively go though a directory structure and replace duplicate files with
# symlinks. This cuts down our RPM repo size by ~25%.
#
# replace-dupes-with-symlinks.sh [DIR]
#
# DIR: Directory to traverse. Defaults to current directory if not specified.
#
src="$1"
if [ -z "$src" ] ; then
src="."
fi
declare -A db
pushd "$src"
while read line ; do
bn="$(basename $line)"
if [ -z "${db[$bn]}" ] ; then
# First time this file has been seen
db[$bn]="$line"
else
if diff -b "$line" "${db[$bn]}" &>/dev/null ; then
# Files are the same, make a symlink
rm "$line"
ln -sr "${db[$bn]}" "$line"
fi
fi
done <<< "$(find . -type f)"
popd
@@ -0,0 +1,140 @@
# This workflow is used to build and test RPM packages. It is a
# 'workflow_dispatch' workflow, which means it gets run manually.
#
# The workflow has a dropdown menu with two options:
#
# Build RPMs - Build release RPMs and tarballs and put them into an artifact
# ZIP file. The directory structure used in the ZIP file mirrors
# the ZFS yum repo.
#
# Test repo - Test install the ZFS RPMs from the ZFS repo. On EL distos, this
# will do a DKMS and KMOD test install from both the regular and
# testing repos. On Fedora, it will do a DKMS install from the
# regular repo. All test install results will be displayed in the
# Summary page. Note that the workflow provides an optional text
# text box where you can specify the full URL to an alternate repo.
# If left blank, it will install from the default repo from the
# zfs-release RPM (http://download.zfsonlinux.org).
#
# Most users will never need to use this workflow. It will be used primary by
# ZFS admins for building and testing releases.
#
name: zfs-qemu-packages
on:
workflow_dispatch:
inputs:
test_type:
type: choice
required: false
default: "Build RPMs"
description: "Build RPMs or test the repo?"
options:
- "Build RPMs"
- "Test repo"
repo_url:
type: string
required: false
default: ""
description: "(optional) repo URL (blank: use http://download.zfsonlinux.org)"
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
zfs-qemu-packages-jobs:
name: qemu-VMs
strategy:
fail-fast: false
matrix:
os: ['almalinux8', 'almalinux9', 'fedora40', 'fedora41']
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup QEMU
timeout-minutes: 10
run: .github/workflows/scripts/qemu-1-setup.sh
- name: Start build machine
timeout-minutes: 10
run: .github/workflows/scripts/qemu-2-start.sh ${{ matrix.os }}
- name: Install dependencies
timeout-minutes: 20
run: |
.github/workflows/scripts/qemu-3-deps.sh ${{ matrix.os }}
- name: Build modules or Test repo
timeout-minutes: 30
run: |
set -e
if [ "${{ github.event.inputs.test_type }}" == "Test repo" ] ; then
# Bring VM back up and copy over zfs source
.github/workflows/scripts/qemu-prepare-for-build.sh
mkdir -p /tmp/repo
ssh zfs@vm0 '$HOME/zfs/.github/workflows/scripts/qemu-test-repo-vm.sh' ${{ github.event.inputs.repo_url }}
else
.github/workflows/scripts/qemu-4-build.sh --repo --release --dkms --tarball ${{ matrix.os }}
fi
- name: Prepare artifacts
if: always()
timeout-minutes: 10
run: |
rsync -a zfs@vm0:/tmp/repo /tmp || true
.github/workflows/scripts/replace-dupes-with-symlinks.sh /tmp/repo
tar -cf ${{ matrix.os }}-repo.tar -C /tmp repo
- uses: actions/upload-artifact@v4
id: artifact-upload
if: always()
with:
name: ${{ matrix.os }}-repo
path: ${{ matrix.os }}-repo.tar
compression-level: 0
retention-days: 2
if-no-files-found: ignore
combine_repos:
if: always()
needs: [zfs-qemu-packages-jobs]
name: "Results"
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
id: artifact-download
if: always()
- name: Test Summary
if: always()
run: |
for i in $(find . -type f -iname "*.tar") ; do
tar -xf $i -C /tmp
done
tar -cf all-repo.tar -C /tmp repo
# If we're installing from a repo, print out the summary of the versions
# that got installed using Markdown.
if [ "${{ github.event.inputs.test_type }}" == "Test repo" ] ; then
cd /tmp/repo
for i in $(ls *.txt) ; do
nicename="$(echo $i | sed 's/.txt//g; s/-/ /g')"
echo "### $nicename" >> $GITHUB_STEP_SUMMARY
echo "|repo|RPM|URL|" >> $GITHUB_STEP_SUMMARY
echo "|:---|:---|:---|" >> $GITHUB_STEP_SUMMARY
awk '{print "|"$1"|"$2"|"$3"|"}' $i >> $GITHUB_STEP_SUMMARY
done
fi
- uses: actions/upload-artifact@v4
id: artifact-upload2
if: always()
with:
name: all-repo
path: all-repo.tar
compression-level: 0
retention-days: 5
if-no-files-found: ignore
+4 -27
View File
@@ -49,7 +49,7 @@ jobs:
os_selection="$FULL_OS"
fi
os_json=$(echo ${os_selection} | jq -c)
# Add optional runners
if [ "${{ github.event.inputs.include_stream9 }}" == 'true' ]; then
os_json=$(echo $os_json | jq -c '. += ["centos-stream9"]')
@@ -57,14 +57,11 @@ jobs:
if [ "${{ github.event.inputs.include_stream10 }}" == 'true' ]; then
os_json=$(echo $os_json | jq -c '. += ["centos-stream10"]')
fi
echo $os_json
echo "os=$os_json" >> $GITHUB_OUTPUT
echo "ci_type=$ci_type" >> $GITHUB_OUTPUT
qemu-vm:
name: qemu-x86
needs: [ test-config ]
@@ -95,31 +92,11 @@ jobs:
- name: Install dependencies
timeout-minutes: 20
run: |
echo "Install dependencies in QEMU machine"
IP=192.168.122.10
while pidof /usr/bin/qemu-system-x86_64 >/dev/null; do
ssh 2>/dev/null zfs@$IP "uname -a" && break
done
scp .github/workflows/scripts/qemu-3-deps.sh zfs@$IP:qemu-3-deps.sh
PID=`pidof /usr/bin/qemu-system-x86_64`
ssh zfs@$IP '$HOME/qemu-3-deps.sh' ${{ matrix.os }}
# wait for poweroff to succeed
tail --pid=$PID -f /dev/null
sleep 5 # avoid this: "error: Domain is already active"
rm -f $HOME/.ssh/known_hosts
run: .github/workflows/scripts/qemu-3-deps.sh ${{ matrix.os }}
- name: Build modules
timeout-minutes: 30
run: |
echo "Build modules in QEMU machine"
sudo virsh start openzfs
IP=192.168.122.10
while pidof /usr/bin/qemu-system-x86_64 >/dev/null; do
ssh 2>/dev/null zfs@$IP "uname -a" && break
done
rsync -ar $HOME/work/zfs/zfs zfs@$IP:./
ssh zfs@$IP '$HOME/zfs/.github/workflows/scripts/qemu-4-build.sh' ${{ matrix.os }}
run: .github/workflows/scripts/qemu-4-build.sh --poweroff --enable-debug ${{ matrix.os }}
- name: Setup testing machines
timeout-minutes: 5
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get purge -y snapd google-chrome-stable firefox
ONLY_DEPS=1 .github/workflows/scripts/qemu-3-deps.sh ubuntu24
ONLY_DEPS=1 .github/workflows/scripts/qemu-3-deps-vm.sh ubuntu24
- name: Autogen.sh
run: |
sed -i '/DEBUG_CFLAGS="-Werror"/s/^/#/' config/zfs-build.m4
+1 -1
View File
@@ -6,5 +6,5 @@ Release: 1
Release-Tags: relext
License: CDDL
Author: OpenZFS
Linux-Maximum: 6.12
Linux-Maximum: 6.13
Linux-Minimum: 4.18
+4 -2
View File
@@ -2059,6 +2059,8 @@ dump_ddt_object(ddt_t *ddt, ddt_type_t type, ddt_class_t class)
if (dump_opt['D'] < 3)
return;
(void) printf("%s: object=%llu\n", name,
(u_longlong_t)ddt->ddt_object[type][class]);
zpool_dump_ddt(NULL, &ddt->ddt_histogram[type][class]);
if (dump_opt['D'] < 4)
@@ -9043,7 +9045,7 @@ zdb_read_block(char *thing, spa_t *spa)
const blkptr_t *b = (const blkptr_t *)(void *)
((uintptr_t)buf + (uintptr_t)blkptr_offset);
if (zfs_blkptr_verify(spa, b,
BLK_CONFIG_NEEDED, BLK_VERIFY_ONLY) == B_FALSE) {
BLK_CONFIG_NEEDED, BLK_VERIFY_ONLY)) {
abd_return_buf_copy(pabd, buf, lsize);
borrowed = B_FALSE;
buf = lbuf;
@@ -9052,7 +9054,7 @@ zdb_read_block(char *thing, spa_t *spa)
b = (const blkptr_t *)(void *)
((uintptr_t)buf + (uintptr_t)blkptr_offset);
if (lsize == -1 || zfs_blkptr_verify(spa, b,
BLK_CONFIG_NEEDED, BLK_VERIFY_LOG) == B_FALSE) {
BLK_CONFIG_NEEDED, BLK_VERIFY_LOG)) {
printf("invalid block pointer at this DVA\n");
goto out;
}
-1
View File
@@ -150,7 +150,6 @@ COMMON_H = \
sys/zio_compress.h \
sys/zio_crypt.h \
sys/zio_impl.h \
sys/zio_priority.h \
sys/zrlock.h \
sys/zthr.h \
\
-1
View File
@@ -48,7 +48,6 @@
#include <sys/cred.h>
#include <sys/fs/zfs.h>
#include <sys/zio_compress.h>
#include <sys/zio_priority.h>
#include <sys/uio.h>
#include <sys/zfs_file.h>
+21 -2
View File
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2024 by Delphix. All rights reserved.
* Copyright (c) 2011, 2014, 2016, 2024 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2013, 2017 Joyent, Inc. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
@@ -37,7 +37,6 @@
#define _SYS_FS_ZFS_H extern __attribute__((visibility("default")))
#include <sys/time.h>
#include <sys/zio_priority.h>
#ifdef __cplusplus
extern "C" {
@@ -1126,6 +1125,26 @@ typedef enum zio_type {
*/
#define ZIO_TYPE_IOCTL ZIO_TYPE_FLUSH
/*
* ZIO priority types. Needed to interpret vdev statistics below.
*
* NOTE: PLEASE UPDATE THE ENUM STRINGS IN zfs_valstr.c IF YOU ADD ANOTHER
* VALUE.
*/
typedef enum zio_priority {
ZIO_PRIORITY_SYNC_READ,
ZIO_PRIORITY_SYNC_WRITE, /* ZIL */
ZIO_PRIORITY_ASYNC_READ, /* prefetch */
ZIO_PRIORITY_ASYNC_WRITE, /* spa_sync() */
ZIO_PRIORITY_SCRUB, /* asynchronous scrub/resilver reads */
ZIO_PRIORITY_REMOVAL, /* reads/writes for vdev removal */
ZIO_PRIORITY_INITIALIZING, /* initializing I/O */
ZIO_PRIORITY_TRIM, /* trim I/O (discard) */
ZIO_PRIORITY_REBUILD, /* reads/writes for vdev rebuild */
ZIO_PRIORITY_NUM_QUEUEABLE,
ZIO_PRIORITY_NOW, /* non-queued i/os (e.g. free) */
} zio_priority_t;
/*
* Pool statistics. Note: all fields should be 64-bit because this
* is passed between kernel and userland as an nvlist uint64 array.
+1 -1
View File
@@ -1214,7 +1214,7 @@ extern void vdev_mirror_stat_fini(void);
/* Initialization and termination */
extern void spa_init(spa_mode_t mode);
extern void spa_fini(void);
extern void spa_boot_init(void);
extern void spa_boot_init(void *);
/* properties */
extern int spa_prop_set(spa_t *spa, nvlist_t *nvp);
+2 -2
View File
@@ -35,7 +35,6 @@
#ifndef _ZIO_H
#define _ZIO_H
#include <sys/zio_priority.h>
#include <sys/zfs_context.h>
#include <sys/spa.h>
#include <sys/txg.h>
@@ -546,6 +545,7 @@ enum blk_verify_flag {
enum blk_config_flag {
BLK_CONFIG_HELD, // SCL_VDEV held for writer
BLK_CONFIG_NEEDED, // SCL_VDEV should be obtained for reader
BLK_CONFIG_NEEDED_TRY, // Try with SCL_VDEV for reader
BLK_CONFIG_SKIP, // skip checks which require SCL_VDEV
};
@@ -663,7 +663,7 @@ extern void zio_suspend(spa_t *spa, zio_t *zio, zio_suspend_reason_t);
extern int zio_resume(spa_t *spa);
extern void zio_resume_wait(spa_t *spa);
extern boolean_t zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp,
extern int zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp,
enum blk_config_flag blk_config, enum blk_verify_flag blk_verify);
/*
@@ -1,47 +0,0 @@
/*
* CDDL HEADER START
*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
*/
#ifndef _ZIO_PRIORITY_H
#define _ZIO_PRIORITY_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* NOTE: PLEASE UPDATE THE ENUM STRINGS IN zfs_valstr.c IF YOU ADD ANOTHER
* VALUE.
*/
typedef enum zio_priority {
ZIO_PRIORITY_SYNC_READ,
ZIO_PRIORITY_SYNC_WRITE, /* ZIL */
ZIO_PRIORITY_ASYNC_READ, /* prefetch */
ZIO_PRIORITY_ASYNC_WRITE, /* spa_sync() */
ZIO_PRIORITY_SCRUB, /* asynchronous scrub/resilver reads */
ZIO_PRIORITY_REMOVAL, /* reads/writes for vdev removal */
ZIO_PRIORITY_INITIALIZING, /* initializing I/O */
ZIO_PRIORITY_TRIM, /* trim I/O (discard) */
ZIO_PRIORITY_REBUILD, /* reads/writes for vdev rebuild */
ZIO_PRIORITY_NUM_QUEUEABLE,
ZIO_PRIORITY_NOW, /* non-queued i/os (e.g. free) */
} zio_priority_t;
#ifdef __cplusplus
}
#endif
#endif /* _ZIO_PRIORITY_H */
+1 -1
View File
@@ -46,7 +46,6 @@ nodist_libzpool_la_SOURCES = \
module/lua/lvm.c \
module/lua/lzio.c \
\
module/os/linux/zfs/vdev_file.c \
module/os/linux/zfs/zio_crypt.c \
\
module/zcommon/cityhash.c \
@@ -143,6 +142,7 @@ nodist_libzpool_la_SOURCES = \
module/zfs/vdev.c \
module/zfs/vdev_draid.c \
module/zfs/vdev_draid_rand.c \
module/zfs/vdev_file.c \
module/zfs/vdev_indirect.c \
module/zfs/vdev_indirect_births.c \
module/zfs/vdev_indirect_mapping.c \
@@ -57,6 +57,7 @@ int
zfs_resolve_shortname(const char *name, char *path, size_t len)
{
const char *env = getenv("ZPOOL_IMPORT_PATH");
char resolved_path[PATH_MAX];
if (env) {
for (;;) {
@@ -85,6 +86,20 @@ zfs_resolve_shortname(const char *name, char *path, size_t len)
}
}
/*
* The user can pass a relative path like ./file1 for the vdev. The path
* must contain a directory prefix like './file1' or '../file1'. Simply
* passing 'file1' is not allowed, as it may match a block device name.
*/
if ((strncmp(name, "./", 2) == 0 || strncmp(name, "../", 3) == 0) &&
realpath(name, resolved_path) != NULL) {
if (access(resolved_path, F_OK) == 0) {
if (strlen(resolved_path) + 1 <= len) {
if (strlcpy(path, resolved_path, len) < len)
return (0); /* success */
}
}
}
return (errno = ENOENT);
}
+1 -1
View File
@@ -385,6 +385,7 @@ ZFS_OBJS := \
vdev.o \
vdev_draid.o \
vdev_draid_rand.o \
vdev_file.o \
vdev_indirect.o \
vdev_indirect_births.o \
vdev_indirect_mapping.o \
@@ -446,7 +447,6 @@ ZFS_OBJS_OS := \
spa_misc_os.o \
trace.o \
vdev_disk.o \
vdev_file.o \
vdev_raidz.o \
vdev_label_os.o \
zfs_acl.o \
+1 -1
View File
@@ -199,7 +199,6 @@ SRCS+= abd_os.c \
kmod_core.c \
spa_os.c \
sysctl_os.c \
vdev_file.c \
vdev_geom.c \
vdev_label_os.c \
zfs_acl.c \
@@ -313,6 +312,7 @@ SRCS+= abd.c \
vdev.c \
vdev_draid.c \
vdev_draid_rand.c \
vdev_file.c \
vdev_indirect_births.c \
vdev_indirect.c \
vdev_indirect_mapping.c \
@@ -1426,7 +1426,6 @@ gcm_init_avx(gcm_ctx_t *ctx, const uint8_t *iv, size_t iv_len,
B_FALSE);
/* Init H (encrypt zero block) and create the initial counter block. */
memset(ctx->gcm_ghash, 0, sizeof (ctx->gcm_ghash));
memset(H, 0, sizeof (ctx->gcm_H));
kfpu_begin();
aes_encrypt_intel(keysched, aes_rounds,
@@ -1455,6 +1454,8 @@ gcm_init_avx(gcm_ctx_t *ctx, const uint8_t *iv, size_t iv_len,
kfpu_begin();
}
memset(ctx->gcm_ghash, 0, sizeof (ctx->gcm_ghash));
/* Openssl post increments the counter, adjust for that. */
gcm_incr_counter_block(ctx);
@@ -1,342 +0,0 @@
/*
* 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 https://opensource.org/licenses/CDDL-1.0.
* 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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2020 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
#include <sys/spa.h>
#include <sys/file.h>
#include <sys/vdev_file.h>
#include <sys/vdev_impl.h>
#include <sys/zio.h>
#include <sys/fs/zfs.h>
#include <sys/fm/fs/zfs.h>
#include <sys/abd.h>
#include <sys/stat.h>
/*
* Virtual device vector for files.
*/
static taskq_t *vdev_file_taskq;
static uint_t vdev_file_logical_ashift = SPA_MINBLOCKSHIFT;
static uint_t vdev_file_physical_ashift = SPA_MINBLOCKSHIFT;
void
vdev_file_init(void)
{
vdev_file_taskq = taskq_create("z_vdev_file", MAX(max_ncpus, 16),
minclsyspri, max_ncpus, INT_MAX, 0);
}
void
vdev_file_fini(void)
{
taskq_destroy(vdev_file_taskq);
}
static void
vdev_file_hold(vdev_t *vd)
{
ASSERT3P(vd->vdev_path, !=, NULL);
}
static void
vdev_file_rele(vdev_t *vd)
{
ASSERT3P(vd->vdev_path, !=, NULL);
}
static mode_t
vdev_file_open_mode(spa_mode_t spa_mode)
{
mode_t mode = 0;
if ((spa_mode & SPA_MODE_READ) && (spa_mode & SPA_MODE_WRITE)) {
mode = O_RDWR;
} else if (spa_mode & SPA_MODE_READ) {
mode = O_RDONLY;
} else if (spa_mode & SPA_MODE_WRITE) {
mode = O_WRONLY;
}
return (mode | O_LARGEFILE);
}
static int
vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
uint64_t *logical_ashift, uint64_t *physical_ashift)
{
vdev_file_t *vf;
zfs_file_t *fp;
zfs_file_attr_t zfa;
int error;
/*
* Rotational optimizations only make sense on block devices.
*/
vd->vdev_nonrot = B_TRUE;
/*
* Allow TRIM on file based vdevs. This may not always be supported,
* since it depends on your kernel version and underlying filesystem
* type but it is always safe to attempt.
*/
vd->vdev_has_trim = B_TRUE;
/*
* Disable secure TRIM on file based vdevs. There is no way to
* request this behavior from the underlying filesystem.
*/
vd->vdev_has_securetrim = B_FALSE;
/*
* We must have a pathname, and it must be absolute.
*/
if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') {
vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
return (SET_ERROR(EINVAL));
}
/*
* Reopen the device if it's not currently open. Otherwise,
* just update the physical size of the device.
*/
if (vd->vdev_tsd != NULL) {
ASSERT(vd->vdev_reopening);
vf = vd->vdev_tsd;
goto skip_open;
}
vf = vd->vdev_tsd = kmem_zalloc(sizeof (vdev_file_t), KM_SLEEP);
/*
* We always open the files from the root of the global zone, even if
* we're in a local zone. If the user has gotten to this point, the
* administrator has already decided that the pool should be available
* to local zone users, so the underlying devices should be as well.
*/
ASSERT3P(vd->vdev_path, !=, NULL);
ASSERT(vd->vdev_path[0] == '/');
error = zfs_file_open(vd->vdev_path,
vdev_file_open_mode(spa_mode(vd->vdev_spa)), 0, &fp);
if (error) {
vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
return (error);
}
vf->vf_file = fp;
#ifdef _KERNEL
/*
* Make sure it's a regular file.
*/
if (zfs_file_getattr(fp, &zfa)) {
return (SET_ERROR(ENODEV));
}
if (!S_ISREG(zfa.zfa_mode)) {
vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
return (SET_ERROR(ENODEV));
}
#endif
skip_open:
error = zfs_file_getattr(vf->vf_file, &zfa);
if (error) {
vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
return (error);
}
*max_psize = *psize = zfa.zfa_size;
*logical_ashift = vdev_file_logical_ashift;
*physical_ashift = vdev_file_physical_ashift;
return (0);
}
static void
vdev_file_close(vdev_t *vd)
{
vdev_file_t *vf = vd->vdev_tsd;
if (vd->vdev_reopening || vf == NULL)
return;
if (vf->vf_file != NULL) {
zfs_file_close(vf->vf_file);
}
vd->vdev_delayed_close = B_FALSE;
kmem_free(vf, sizeof (vdev_file_t));
vd->vdev_tsd = NULL;
}
/*
* Implements the interrupt side for file vdev types. This routine will be
* called when the I/O completes allowing us to transfer the I/O to the
* interrupt taskqs. For consistency, the code structure mimics disk vdev
* types.
*/
static void
vdev_file_io_intr(zio_t *zio)
{
zio_delay_interrupt(zio);
}
static void
vdev_file_io_strategy(void *arg)
{
zio_t *zio = arg;
vdev_t *vd = zio->io_vd;
vdev_file_t *vf;
void *buf;
ssize_t resid;
loff_t off;
ssize_t size;
int err;
off = zio->io_offset;
size = zio->io_size;
resid = 0;
vf = vd->vdev_tsd;
ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE);
if (zio->io_type == ZIO_TYPE_READ) {
buf = abd_borrow_buf(zio->io_abd, zio->io_size);
err = zfs_file_pread(vf->vf_file, buf, size, off, &resid);
abd_return_buf_copy(zio->io_abd, buf, size);
} else {
buf = abd_borrow_buf_copy(zio->io_abd, zio->io_size);
err = zfs_file_pwrite(vf->vf_file, buf, size, off, &resid);
abd_return_buf(zio->io_abd, buf, size);
}
zio->io_error = err;
if (resid != 0 && zio->io_error == 0)
zio->io_error = ENOSPC;
vdev_file_io_intr(zio);
}
static void
vdev_file_io_start(zio_t *zio)
{
vdev_t *vd = zio->io_vd;
vdev_file_t *vf = vd->vdev_tsd;
if (zio->io_type == ZIO_TYPE_FLUSH) {
/* XXPOLICY */
if (!vdev_readable(vd)) {
zio->io_error = SET_ERROR(ENXIO);
zio_interrupt(zio);
return;
}
zio->io_error = zfs_file_fsync(vf->vf_file, O_SYNC|O_DSYNC);
zio_execute(zio);
return;
} else if (zio->io_type == ZIO_TYPE_TRIM) {
ASSERT3U(zio->io_size, !=, 0);
zio->io_error = zfs_file_deallocate(vf->vf_file,
zio->io_offset, zio->io_size);
zio_execute(zio);
return;
}
ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE);
zio->io_target_timestamp = zio_handle_io_delay(zio);
VERIFY3U(taskq_dispatch(vdev_file_taskq, vdev_file_io_strategy, zio,
TQ_SLEEP), !=, 0);
}
static void
vdev_file_io_done(zio_t *zio)
{
(void) zio;
}
vdev_ops_t vdev_file_ops = {
.vdev_op_init = NULL,
.vdev_op_fini = NULL,
.vdev_op_open = vdev_file_open,
.vdev_op_close = vdev_file_close,
.vdev_op_asize = vdev_default_asize,
.vdev_op_min_asize = vdev_default_min_asize,
.vdev_op_min_alloc = NULL,
.vdev_op_io_start = vdev_file_io_start,
.vdev_op_io_done = vdev_file_io_done,
.vdev_op_state_change = NULL,
.vdev_op_need_resilver = NULL,
.vdev_op_hold = vdev_file_hold,
.vdev_op_rele = vdev_file_rele,
.vdev_op_remap = NULL,
.vdev_op_xlate = vdev_default_xlate,
.vdev_op_rebuild_asize = NULL,
.vdev_op_metaslab_init = NULL,
.vdev_op_config_generate = NULL,
.vdev_op_nparity = NULL,
.vdev_op_ndisks = NULL,
.vdev_op_type = VDEV_TYPE_FILE, /* name of this vdev type */
.vdev_op_leaf = B_TRUE /* leaf vdev */
};
/*
* From userland we access disks just like files.
*/
#ifndef _KERNEL
vdev_ops_t vdev_disk_ops = {
.vdev_op_init = NULL,
.vdev_op_fini = NULL,
.vdev_op_open = vdev_file_open,
.vdev_op_close = vdev_file_close,
.vdev_op_asize = vdev_default_asize,
.vdev_op_min_asize = vdev_default_min_asize,
.vdev_op_min_alloc = NULL,
.vdev_op_io_start = vdev_file_io_start,
.vdev_op_io_done = vdev_file_io_done,
.vdev_op_state_change = NULL,
.vdev_op_need_resilver = NULL,
.vdev_op_hold = vdev_file_hold,
.vdev_op_rele = vdev_file_rele,
.vdev_op_remap = NULL,
.vdev_op_xlate = vdev_default_xlate,
.vdev_op_rebuild_asize = NULL,
.vdev_op_metaslab_init = NULL,
.vdev_op_config_generate = NULL,
.vdev_op_nparity = NULL,
.vdev_op_ndisks = NULL,
.vdev_op_type = VDEV_TYPE_DISK, /* name of this vdev type */
.vdev_op_leaf = B_TRUE /* leaf vdev */
};
#endif
ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, logical_ashift, UINT, ZMOD_RW,
"Logical ashift for file-based devices");
ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, physical_ashift, UINT, ZMOD_RW,
"Physical ashift for file-based devices");
+23 -5
View File
@@ -1905,7 +1905,7 @@ arc_hdr_decrypt(arc_buf_hdr_t *hdr, spa_t *spa, const zbookmark_phys_t *zb)
error:
arc_hdr_free_abd(hdr, B_FALSE);
if (cabd != NULL)
arc_free_data_buf(hdr, cabd, arc_hdr_size(hdr), hdr);
arc_free_data_abd(hdr, cabd, arc_hdr_size(hdr), hdr);
return (ret);
}
@@ -5683,6 +5683,7 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
boolean_t no_buf = *arc_flags & ARC_FLAG_NO_BUF;
arc_buf_t *buf = NULL;
int rc = 0;
boolean_t bp_validation = B_FALSE;
ASSERT(!embedded_bp ||
BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_DATA);
@@ -5725,7 +5726,7 @@ top:
* should always be the case since the blkptr is protected by
* a checksum.
*/
if (!zfs_blkptr_verify(spa, bp, BLK_CONFIG_SKIP,
if (zfs_blkptr_verify(spa, bp, BLK_CONFIG_SKIP,
BLK_VERIFY_LOG)) {
mutex_exit(hash_lock);
rc = SET_ERROR(ECKSUM);
@@ -5877,6 +5878,8 @@ top:
abd_t *hdr_abd;
int alloc_flags = encrypted_read ? ARC_HDR_ALLOC_RDATA : 0;
arc_buf_contents_t type = BP_GET_BUFC_TYPE(bp);
int config_lock;
int error;
if (*arc_flags & ARC_FLAG_CACHED_ONLY) {
if (hash_lock != NULL)
@@ -5885,16 +5888,31 @@ top:
goto done;
}
if (zio_flags & ZIO_FLAG_CONFIG_WRITER) {
config_lock = BLK_CONFIG_HELD;
} else if (hash_lock != NULL) {
/*
* Prevent lock order reversal
*/
config_lock = BLK_CONFIG_NEEDED_TRY;
} else {
config_lock = BLK_CONFIG_NEEDED;
}
/*
* Verify the block pointer contents are reasonable. This
* should always be the case since the blkptr is protected by
* a checksum.
*/
if (!zfs_blkptr_verify(spa, bp,
(zio_flags & ZIO_FLAG_CONFIG_WRITER) ?
BLK_CONFIG_HELD : BLK_CONFIG_NEEDED, BLK_VERIFY_LOG)) {
if (!bp_validation && (error = zfs_blkptr_verify(spa, bp,
config_lock, BLK_VERIFY_LOG))) {
if (hash_lock != NULL)
mutex_exit(hash_lock);
if (error == EBUSY && !zfs_blkptr_verify(spa, bp,
BLK_CONFIG_NEEDED, BLK_VERIFY_LOG)) {
bp_validation = B_TRUE;
goto top;
}
rc = SET_ERROR(ECKSUM);
goto done;
}
+5 -2
View File
@@ -2738,8 +2738,11 @@ spa_do_crypt_objset_mac_abd(boolean_t generate, spa_t *spa, uint64_t dsobj,
}
if (memcmp(portable_mac, osp->os_portable_mac,
ZIO_OBJSET_MAC_LEN) != 0 ||
memcmp(local_mac, osp->os_local_mac, ZIO_OBJSET_MAC_LEN) != 0) {
ZIO_OBJSET_MAC_LEN) != 0) {
abd_return_buf(abd, buf, datalen);
return (SET_ERROR(ECKSUM));
}
if (memcmp(local_mac, osp->os_local_mac, ZIO_OBJSET_MAC_LEN) != 0) {
/*
* If the MAC is zeroed out, we failed to decrypt it.
* This should only arise, at least on Linux,
+1 -1
View File
@@ -2305,7 +2305,7 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_dataset_t *ds, dmu_objset_type_t ostype,
DMU_USERUSED_OBJECT, tx);
}
arc_buf_destroy(buf, &buf);
} else if (!zfs_blkptr_verify(spa, bp,
} else if (zfs_blkptr_verify(spa, bp,
BLK_CONFIG_NEEDED, BLK_VERIFY_LOG)) {
/*
* Sanity check the block pointer contents, this is handled
@@ -3545,6 +3545,15 @@ metaslab_segment_may_passivate(metaslab_t *msp)
if (WEIGHT_IS_SPACEBASED(msp->ms_weight) || spa_sync_pass(spa) > 1)
return;
/*
* As long as a single largest free segment covers majorioty of free
* space, don't consider the metaslab fragmented. It should allow
* us to fill new unfragmented metaslabs full before switching.
*/
if (metaslab_largest_allocatable(msp) >
zfs_range_tree_space(msp->ms_allocatable) * 15 / 16)
return;
/*
* Since we are in the middle of a sync pass, the most accurate
* information that is accessible to us is the in-core range tree
+1 -1
View File
@@ -2778,7 +2778,7 @@ spa_load_verify_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
* When damaged consider it to be a metadata error since we cannot
* trust the BP_GET_TYPE and BP_GET_LEVEL values.
*/
if (!zfs_blkptr_verify(spa, bp, BLK_CONFIG_NEEDED, BLK_VERIFY_LOG)) {
if (zfs_blkptr_verify(spa, bp, BLK_CONFIG_NEEDED, BLK_VERIFY_LOG)) {
atomic_inc_64(&sle->sle_meta_count);
return (0);
}
+2 -1
View File
@@ -2549,8 +2549,9 @@ spa_name_compare(const void *a1, const void *a2)
}
void
spa_boot_init(void)
spa_boot_init(void *unused)
{
(void) unused;
spa_config_load();
}
@@ -21,26 +21,19 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2020 by Delphix. All rights reserved.
* Copyright (c) 2025, Klara, Inc.
*/
#include <sys/zfs_context.h>
#include <sys/spa.h>
#include <sys/spa_impl.h>
#include <sys/vdev_file.h>
#include <sys/vdev_impl.h>
#include <sys/vdev_trim.h>
#include <sys/zio.h>
#include <sys/fs/zfs.h>
#include <sys/fm/fs/zfs.h>
#include <sys/abd.h>
#include <sys/vnode.h>
#include <sys/zfs_file.h>
#ifdef _KERNEL
#include <linux/falloc.h>
#include <sys/fcntl.h>
#else
#include <fcntl.h>
#endif
#include <sys/stat.h>
/*
* Virtual device vector for files.
*/
@@ -58,16 +51,31 @@ static taskq_t *vdev_file_taskq;
static uint_t vdev_file_logical_ashift = SPA_MINBLOCKSHIFT;
static uint_t vdev_file_physical_ashift = SPA_MINBLOCKSHIFT;
void
vdev_file_init(void)
{
vdev_file_taskq = taskq_create("z_vdev_file", MAX(boot_ncpus, 16),
minclsyspri, boot_ncpus, INT_MAX, TASKQ_DYNAMIC);
VERIFY(vdev_file_taskq);
}
void
vdev_file_fini(void)
{
taskq_destroy(vdev_file_taskq);
}
static void
vdev_file_hold(vdev_t *vd)
{
ASSERT(vd->vdev_path != NULL);
ASSERT3P(vd->vdev_path, !=, NULL);
}
static void
vdev_file_rele(vdev_t *vd)
{
ASSERT(vd->vdev_path != NULL);
ASSERT3P(vd->vdev_path, !=, NULL);
}
static mode_t
@@ -139,7 +147,8 @@ vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
* administrator has already decided that the pool should be available
* to local zone users, so the underlying devices should be as well.
*/
ASSERT(vd->vdev_path != NULL && vd->vdev_path[0] == '/');
ASSERT3P(vd->vdev_path, !=, NULL);
ASSERT3S(vd->vdev_path[0], ==, '/');
error = zfs_file_open(vd->vdev_path,
vdev_file_open_mode(spa_mode(vd->vdev_spa)), 0, &fp);
@@ -201,8 +210,8 @@ vdev_file_io_strategy(void *arg)
zio_t *zio = (zio_t *)arg;
vdev_t *vd = zio->io_vd;
vdev_file_t *vf = vd->vdev_tsd;
ssize_t resid;
void *buf;
ssize_t resid;
loff_t off;
ssize_t size;
int err;
@@ -211,6 +220,7 @@ vdev_file_io_strategy(void *arg)
size = zio->io_size;
resid = 0;
ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE);
if (zio->io_type == ZIO_TYPE_READ) {
buf = abd_borrow_buf(zio->io_abd, zio->io_size);
err = zfs_file_pread(vf->vf_file, buf, size, off, &resid);
@@ -238,11 +248,22 @@ vdev_file_io_fsync(void *arg)
zio_interrupt(zio);
}
static void
vdev_file_io_deallocate(void *arg)
{
zio_t *zio = (zio_t *)arg;
vdev_file_t *vf = zio->io_vd->vdev_tsd;
zio->io_error = zfs_file_deallocate(vf->vf_file,
zio->io_offset, zio->io_size);
zio_interrupt(zio);
}
static void
vdev_file_io_start(zio_t *zio)
{
vdev_t *vd = zio->io_vd;
vdev_file_t *vf = vd->vdev_tsd;
if (zio->io_type == ZIO_TYPE_FLUSH) {
/* XXPOLICY */
@@ -253,36 +274,27 @@ vdev_file_io_start(zio_t *zio)
}
if (zfs_nocacheflush) {
zio_execute(zio);
zio_interrupt(zio);
return;
}
/*
* We cannot safely call vfs_fsync() when PF_FSTRANS
* is set in the current context. Filesystems like
* XFS include sanity checks to verify it is not
* already set, see xfs_vm_writepage(). Therefore
* the sync must be dispatched to a different context.
*/
if (__spl_pf_fstrans_check()) {
VERIFY3U(taskq_dispatch(vdev_file_taskq,
vdev_file_io_fsync, zio, TQ_SLEEP), !=,
TASKQID_INVALID);
return;
}
VERIFY3U(taskq_dispatch(vdev_file_taskq,
vdev_file_io_fsync, zio, TQ_SLEEP), !=, TASKQID_INVALID);
zio->io_error = zfs_file_fsync(vf->vf_file, O_SYNC | O_DSYNC);
zio_execute(zio);
return;
} else if (zio->io_type == ZIO_TYPE_TRIM) {
ASSERT3U(zio->io_size, !=, 0);
zio->io_error = zfs_file_deallocate(vf->vf_file,
zio->io_offset, zio->io_size);
zio_execute(zio);
return;
}
if (zio->io_type == ZIO_TYPE_TRIM) {
ASSERT3U(zio->io_size, !=, 0);
VERIFY3U(taskq_dispatch(vdev_file_taskq,
vdev_file_io_deallocate, zio, TQ_SLEEP), !=,
TASKQID_INVALID);
return;
}
ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE);
zio->io_target_timestamp = zio_handle_io_delay(zio);
VERIFY3U(taskq_dispatch(vdev_file_taskq, vdev_file_io_strategy, zio,
@@ -320,21 +332,6 @@ vdev_ops_t vdev_file_ops = {
.vdev_op_leaf = B_TRUE /* leaf vdev */
};
void
vdev_file_init(void)
{
vdev_file_taskq = taskq_create("z_vdev_file", MAX(boot_ncpus, 16),
minclsyspri, boot_ncpus, INT_MAX, TASKQ_DYNAMIC);
VERIFY(vdev_file_taskq);
}
void
vdev_file_fini(void)
{
taskq_destroy(vdev_file_taskq);
}
/*
* From userland we access disks just like files.
*/
@@ -209,8 +209,8 @@ vdev_passivate(vdev_t *vd, uint64_t *txg)
for (uint64_t id = 0; id < rvd->vdev_children; id++) {
vdev_t *cvd = rvd->vdev_child[id];
if (cvd == vd ||
cvd->vdev_ops == &vdev_indirect_ops)
if (cvd == vd || !vdev_is_concrete(cvd) ||
vdev_is_dead(cvd))
continue;
metaslab_class_t *mc = cvd->vdev_mg->mg_class;
+12 -7
View File
@@ -1164,7 +1164,7 @@ zfs_blkptr_verify_log(spa_t *spa, const blkptr_t *bp,
* it only contains known object types, checksum/compression identifiers,
* block sizes within the maximum allowed limits, valid DVAs, etc.
*
* If everything checks out B_TRUE is returned. The zfs_blkptr_verify
* If everything checks out 0 is returned. The zfs_blkptr_verify
* argument controls the behavior when an invalid field is detected.
*
* Values for blk_verify_flag:
@@ -1179,7 +1179,7 @@ zfs_blkptr_verify_log(spa_t *spa, const blkptr_t *bp,
* BLK_CONFIG_SKIP: skip checks which require SCL_VDEV, for better
* performance
*/
boolean_t
int
zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp,
enum blk_config_flag blk_config, enum blk_verify_flag blk_verify)
{
@@ -1211,7 +1211,7 @@ zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp,
"blkptr at %px has invalid PSIZE %llu",
bp, (longlong_t)BPE_GET_PSIZE(bp));
}
return (errors == 0);
return (errors ? ECKSUM : 0);
}
if (unlikely(BP_GET_CHECKSUM(bp) >= ZIO_CHECKSUM_FUNCTIONS)) {
errors += zfs_blkptr_verify_log(spa, bp, blk_verify,
@@ -1229,7 +1229,7 @@ zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp,
* will be done once the zio is executed in vdev_mirror_map_alloc.
*/
if (unlikely(!spa->spa_trust_config))
return (errors == 0);
return (errors ? ECKSUM : 0);
switch (blk_config) {
case BLK_CONFIG_HELD:
@@ -1238,8 +1238,12 @@ zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp,
case BLK_CONFIG_NEEDED:
spa_config_enter(spa, SCL_VDEV, bp, RW_READER);
break;
case BLK_CONFIG_NEEDED_TRY:
if (!spa_config_tryenter(spa, SCL_VDEV, bp, RW_READER))
return (EBUSY);
break;
case BLK_CONFIG_SKIP:
return (errors == 0);
return (errors ? ECKSUM : 0);
default:
panic("invalid blk_config %u", blk_config);
}
@@ -1294,10 +1298,11 @@ zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp,
bp, i, (longlong_t)offset);
}
}
if (blk_config == BLK_CONFIG_NEEDED)
if (blk_config == BLK_CONFIG_NEEDED || blk_config ==
BLK_CONFIG_NEEDED_TRY)
spa_config_exit(spa, SCL_VDEV, bp);
return (errors == 0);
return (errors ? ECKSUM : 0);
}
boolean_t
+235
View File
@@ -0,0 +1,235 @@
#!/usr/bin/env perl
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025, Rob Norris <[email protected]>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# This programs converts AEAD test vectors from Project Wycheproof into a
# format that can be consumed more easily by tests/zfs-tests/cmd/crypto_test.
# See tests/zfs-tests/tests/functional/crypto/README for more info.
#
use 5.010;
use warnings;
use strict;
use JSON qw(decode_json);
sub usage {
say "usage: $0 <infile> [<outfile>]";
exit 1;
}
my ($infile, $outfile) = @ARGV;
usage() if !defined $infile;
open my $infh, '<', $infile or die "E: $infile: $!\n";
my $json = do { local $/; <$infh> };
close $infh;
my $data = decode_json $json;
select STDERR;
# 0.8 had a slightly different format. 0.9* is current, stabilising for 1.0
my $version = $data->{generatorVersion} // "[unknown]";
if ("$version" !~ m/^0\.9[^0-9]/) {
warn
"W: this converter was written for Wycheproof 0.9 test vectors\n".
" input file has version: $version\n".
" bravely continuing, but expect crashes or garbled output\n";
}
# we only support AEAD tests
my $schema = $data->{schema} // "[unknown]";
if ("$schema" ne 'aead_test_schema.json') {
warn
"W: this converter is expecting AEAD test vectors\n".
" input file has schema: $schema\n".
" bravely continuing, but expect crashes or garbled output\n";
}
# sanity check; algorithm is provided
my $algorithm = $data->{algorithm};
if (!defined $algorithm) {
die "E: $infile: required field 'algorithm' not found\n";
}
# sanity check; test count is present and correct
my $ntests = 0;
$ntests += $_ for map { scalar @{$_->{tests}} } @{$data->{testGroups}};
if (!exists $data->{numberOfTests}) {
warn "W: input file has no test count, using mine: $ntests\n";
} elsif ($data->{numberOfTests} != $ntests) {
warn
"W: input file has incorrect test count: $data->{numberOfTests}\n".
" using my own count: $ntests\n";
}
say " version: $version";
say " schema: $schema";
say "algorithm: $algorithm";
say " ntests: $ntests";
my $skipped = 0;
my @tests;
# tests are grouped into "test groups". groups have the same type and IV, key
# and tag sizes. we can infer this info from the tests themselves, but it's
# useful for sanity checks
#
# "testGroups" : [
# {
# "ivSize" : 96,
# "keySize" : 128,
# "tagSize" : 128,
# "type" : "AeadTest",
# "tests" : [ ... ]
#
for my $group (@{$data->{testGroups}}) {
# skip non-AEAD test groups
my $type = $group->{type} // "[unknown]";
if ($type ne 'AeadTest') {
warn "W: group has unexpected type '$type', skipping it\n";
$skipped += @{$data->{tests}};
next;
}
my ($iv_size, $key_size, $tag_size) =
@$group{qw(ivSize keySize tagSize)};
# a typical test:
#
# {
# "tcId" : 48,
# "comment" : "Flipped bit 63 in tag",
# "flags" : [
# "ModifiedTag"
# ],
# "key" : "000102030405060708090a0b0c0d0e0f",
# "iv" : "505152535455565758595a5b",
# "aad" : "",
# "msg" : "202122232425262728292a2b2c2d2e2f",
# "ct" : "eb156d081ed6b6b55f4612f021d87b39",
# "tag" : "d8847dbc326a066988c77ad3863e6083",
# "result" : "invalid"
# },
#
# we include everything in the output. the id is useful output so the
# user can go back to the original test. comment and flags are useful
# for output in a failing test
#
for my $test (@{$group->{tests}}) {
my ($id, $comment, $iv, $key, $msg, $ct, $aad, $tag, $result) =
@$test{qw(tcId comment iv key msg ct aad tag result)};
# sanity check; iv, key and tag must have the length declared
# by the group params
unless (
length_check($id, 'iv', $iv, $iv_size) &&
length_check($id, 'key', $key, $key_size) &&
length_check($id, 'tag', $tag, $tag_size)) {
$skipped++;
next;
}
# flatten and sort the flags into a single string
my $flags;
if ($test->{flags}) {
$flags = join(' ', sort @{$test->{flags}});
}
# the completed test record. we'll emit this later once we're
# finished with the input; the output file is not open yet.
push @tests, [
[ id => $id ],
[ comment => $comment ],
(defined $flags ? [ flags => $flags ] : ()),
[ iv => $iv ],
[ key => $key ],
[ msg => $msg ],
[ ct => $ct ],
[ aad => $aad ],
[ tag => $tag ],
[ result => $result ],
];
}
}
if ($skipped) {
$ntests -= $skipped;
warn "W: skipped $skipped tests; new test count: $ntests\n";
}
if ($ntests == 0) {
die "E: no tests extracted, sorry!\n";
my $outfh;
if ($outfile) {
open $outfh, '>', $outfile or die "E: $outfile: $!\n";
} else {
$outfh = *STDOUT;
}
# the "header" record has the algorithm and count of tests
say $outfh "algorithm: $algorithm";
say $outfh "tests: $ntests";
#
for my $test (@tests) {
# blank line is a record separator
say $outfh "";
# output the test data in a simple record of 'key: value' lines
#
# id: 48
# comment: Flipped bit 63 in tag
# flags: ModifiedTag
# iv: 505152535455565758595a5b
# key: 000102030405060708090a0b0c0d0e0f
# msg: 202122232425262728292a2b2c2d2e2f
# ct: eb156d081ed6b6b55f4612f021d87b39
# aad:
# tag: d8847dbc326a066988c77ad3863e6083
# result: invalid
for my $row (@$test) {
my ($k, $v) = @$row;
say $outfh "$k: $v";
}
}
close $outfh;
# check that the length of hex string matches the wanted number of bits
sub length_check {
my ($id, $name, $hexstr, $wantbits) = @_;
my $got = length($hexstr)/2;
my $want = $wantbits/8;
return 1 if $got == $want;
my $gotbits = $got*8;
say
"W: $id: '$name' has incorrect len, skipping test:\n".
" got $got bytes ($gotbits bits)\n".
" want $want bytes ($wantbits bits)\n";
return;
}
+11 -5
View File
@@ -152,7 +152,7 @@ cleanup_all() {
else
TEST_LOOPBACKS=$("${LOSETUP}" -a | awk -F: '/file-vdev/ {print $1}')
fi
TEST_FILES=$(ls "${FILEDIR}"/file-vdev* /var/tmp/file-vdev* 2>/dev/null)
TEST_FILES=$(ls "${FILEDIR}"/file-vdev* 2>/dev/null)
msg
msg "--- Cleanup ---"
@@ -308,8 +308,8 @@ constrain_path() {
# Special case links for zfs test suite utilities
create_links "$CMD_DIR/tests/zfs-tests/cmd" "$ZFSTEST_FILES"
else
# Constrained path set to /var/tmp/constrained_path.*
SYSTEMDIR=${SYSTEMDIR:-/var/tmp/constrained_path.XXXXXX}
# Constrained path set to $FILEDIR/constrained_path.*
SYSTEMDIR=${SYSTEMDIR:-$FILEDIR/constrained_path.XXXXXX}
STF_PATH=$(mktemp -d "$SYSTEMDIR")
STF_PATH_REMOVE="yes"
STF_MISSING_BIN=""
@@ -492,7 +492,7 @@ if [ -n "$SINGLETEST" ]; then
if [ -n "$TAGS" ]; then
fail "-t and -T are mutually exclusive."
fi
RUNFILE_DIR="/var/tmp"
RUNFILE_DIR="$FILEDIR"
RUNFILES="zfs-tests.$$.run"
[ -n "$QUIET" ] && SINGLEQUIET="True" || SINGLEQUIET="False"
@@ -505,7 +505,6 @@ user = $SINGLETESTUSER
timeout = 600
post_user = root
post =
outputdir = /var/tmp/test_results
EOF
if [ "$SINGLETEST" = "${SINGLETEST%/*}" ] ; then
NEWSINGLETEST=$(find "$STF_SUITE" -name "$SINGLETEST*" -print -quit)
@@ -719,6 +718,12 @@ if [ -e /sys/module/zfs/parameters/zfs_dbgmsg_enable ]; then
sudo sh -c "echo 0 >/proc/spl/kstat/zfs/dbgmsg"
fi
#
# Set TMPDIR. Some tests run mktemp, and we want those files contained to
# the work dir the same as any other.
#
export TMPDIR="$FILEDIR"
msg
msg "--- Configuration ---"
msg "Runfiles: $RUNFILES"
@@ -726,6 +731,7 @@ msg "STF_TOOLS: $STF_TOOLS"
msg "STF_SUITE: $STF_SUITE"
msg "STF_PATH: $STF_PATH"
msg "FILEDIR: $FILEDIR"
msg "TMPDIR: $TMPDIR"
msg "FILES: $FILES"
msg "LOOPBACKS: $LOOPBACKS"
msg "DISKS: $DISKS"
@@ -25,7 +25,6 @@ post_user = root
post = cleanup
failsafe_user = root
failsafe = callbacks/zfs_failsafe
outputdir = /var/tmp/test_results
tags = ['bclone']
[tests/functional/bclone]
@@ -25,7 +25,6 @@ post_user = root
post = cleanup
failsafe_user = root
failsafe = callbacks/zfs_failsafe
outputdir = /var/tmp/test_results
tags = ['functional']
[tests/functional/acl/off]
@@ -665,6 +664,12 @@ tags = ['functional', 'zap_shrink']
tests = ['crtime_001_pos' ]
tags = ['functional', 'crtime']
[tests/functional/crypto]
tests = ['icp_aes_ccm', 'icp_aes_gcm']
pre =
post =
tags = ['functional', 'crypto']
[tests/functional/ctime]
tests = ['ctime_001_pos' ]
tags = ['functional', 'ctime']
@@ -678,7 +683,7 @@ tags = ['functional', 'deadman']
[tests/functional/dedup]
tests = ['dedup_fdt_create', 'dedup_fdt_import', 'dedup_legacy_create',
'dedup_legacy_import', 'dedup_legacy_fdt_upgrade',
'dedup_legacy_fdt_mixed', 'dedup_quota']
'dedup_legacy_fdt_mixed', 'dedup_quota', 'dedup_prune', 'dedup_zap_shrink']
pre =
post =
tags = ['functional', 'dedup']
@@ -888,7 +893,8 @@ tests = ['removal_all_vdev', 'removal_cancel', 'removal_check_space',
'removal_with_send_recv', 'removal_with_snapshot',
'removal_with_write', 'removal_with_zdb', 'remove_expanded',
'remove_mirror', 'remove_mirror_sanity', 'remove_raidz',
'remove_indirect', 'remove_attach_mirror', 'removal_reservation']
'remove_indirect', 'remove_attach_mirror', 'removal_reservation',
'removal_with_hole']
tags = ['functional', 'removal']
[tests/functional/rename_dirs]
@@ -19,7 +19,6 @@ post_user = root
post = cleanup
failsafe_user = root
failsafe = callbacks/zfs_failsafe
outputdir = /var/tmp/test_results
tags = ['functional']
[tests/functional/cli_root/zfs_jail:FreeBSD]
@@ -19,7 +19,6 @@ post_user = root
post = cleanup
failsafe_user = root
failsafe = callbacks/zfs_failsafe
outputdir = /var/tmp/test_results
tags = ['functional']
[tests/functional/acl/posix:Linux]
@@ -17,7 +17,6 @@
quiet = False
user = root
timeout = 10800
outputdir = /var/tmp/test_results
[/opt/zfs-tests/tests/longevity]
tests = ['slop_space_test']
@@ -21,7 +21,6 @@ user = root
timeout = 0
post_user = root
post = cleanup
outputdir = /var/tmp/test_results
tags = ['perf']
[tests/perf/regression]
@@ -27,7 +27,6 @@ post_user = root
post = cleanup
failsafe_user = root
failsafe = callbacks/zfs_failsafe
outputdir = /var/tmp/test_results
tags = ['functional']
[tests/functional/acl/off]
@@ -19,7 +19,6 @@ post_user = root
post = cleanup
failsafe_user = root
failsafe = callbacks/zfs_failsafe
outputdir = /var/tmp/test_results
tags = ['functional']
[tests/functional/inuse:illumos]
@@ -238,7 +238,15 @@ User: %s
if os.path.isfile(cmd+'.sh') and os.access(cmd+'.sh', os.X_OK):
cmd += '.sh'
ret = '%s -E -u %s %s' % (SUDO, user, cmd)
# glibc (at least) will not pass TMPDIR through to setuid programs.
# if set, arrange for it to be reset before running the target cmd
tmpdir = os.getenv('TMPDIR')
if tmpdir:
tmpdirarg = 'env TMPDIR=%s' % tmpdir
else:
tmpdirarg = ''
ret = '%s -E -u %s %s %s' % (SUDO, user, tmpdirarg, cmd)
return ret.split(' ')
def collect_output(self, proc, debug=False):
@@ -746,8 +754,11 @@ class TestRun(object):
for opt in TestRun.props:
if config.has_option('DEFAULT', opt):
setattr(self, opt, config.get('DEFAULT', opt))
self.outputdir = os.path.join(self.outputdir, self.timestamp)
if opt == 'outputdir':
outputdir = config.get('DEFAULT', opt)
setattr(self, opt, os.path.join(outputdir, self.timestamp))
else:
setattr(self, opt, config.get('DEFAULT', opt))
testdir = options.testdir
@@ -775,6 +786,11 @@ class TestRun(object):
failsafe = config.get(sect, prop)
setattr(testgroup, prop,
os.path.join(testdir, failsafe))
elif prop == 'outputdir':
outputdir = config.get(sect, prop)
setattr(self, opt,
os.path.join(outputdir,
self.timestamp))
else:
setattr(testgroup, prop,
config.get(sect, prop))
@@ -793,6 +809,11 @@ class TestRun(object):
failsafe = config.get(sect, prop)
setattr(test, prop,
os.path.join(testdir, failsafe))
elif prop == 'outputdir':
outputdir = config.get(sect, prop)
setattr(self, opt,
os.path.join(outputdir,
self.timestamp))
else:
setattr(test, prop, config.get(sect, prop))
@@ -4,6 +4,7 @@
/clonefile
/clone_mmap_cached
/clone_mmap_write
/crypto_test
/devname2devid
/dir_rd_update
/draid
@@ -30,6 +30,11 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/btree_test
libzfs_core.la
scripts_zfs_tests_bin_PROGRAMS += %D%/crypto_test
%C%_crypto_test_SOURCES = %D%/crypto_test.c
%C%_crypto_test_LDADD = libzpool.la
if WANT_DEVNAME2DEVID
scripts_zfs_tests_bin_PROGRAMS += %D%/devname2devid
%C%_devname2devid_CFLAGS = $(AM_CFLAGS) $(LIBUDEV_CFLAGS)
File diff suppressed because it is too large. Load diff
@@ -186,6 +186,7 @@ export ZFSTEST_FILES='badsend
clonefile
clone_mmap_cached
clone_mmap_write
crypto_test
devname2devid
dir_rd_update
draid
@@ -184,7 +184,7 @@ Linux)
DEV_RDSKDIR="/dev"
DEV_MPATHDIR="/dev/mapper"
ZEDLET_DIR="/var/tmp/zed"
ZEDLET_DIR="$TEST_BASE_DIR/zed"
ZED_LOG="$ZEDLET_DIR/zed.log"
ZED_DEBUG_LOG="$ZEDLET_DIR/zed.debug.log"
VDEVID_CONF="$ZEDLET_DIR/vdev_id.conf"
@@ -915,7 +915,7 @@ function set_partition
log_fail "The slice, size or disk name is unspecified."
fi
typeset format_file=/var/tmp/format_in.$$
typeset format_file="$TEST_BASE_DIR"/format_in.$$
echo "partition" >$format_file
echo "$slicenum" >> $format_file
@@ -2404,7 +2404,7 @@ function add_user #<group_name> <user_name> <basedir>
{
typeset group=$1
typeset user=$2
typeset basedir=${3:-"/var/tmp"}
typeset basedir=${3:-"$TEST_BASE_DIR"}
if ((${#group} == 0 || ${#user} == 0)); then
log_fail "group name or user name are not defined."
@@ -2434,7 +2434,7 @@ function add_user #<group_name> <user_name> <basedir>
function del_user #<logname> <basedir>
{
typeset user=$1
typeset basedir=${2:-"/var/tmp"}
typeset basedir=${2:-"$TEST_BASE_DIR"}
if ((${#user} == 0)); then
log_fail "login name is necessary."
@@ -3184,7 +3184,7 @@ function zed_start
return
fi
# ZEDLET_DIR=/var/tmp/zed
# ZEDLET_DIR=$TEST_BASE_DIR/zed
if [[ ! -d $ZEDLET_DIR ]]; then
log_must mkdir $ZEDLET_DIR
fi
@@ -139,6 +139,10 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
functional/checksum/default.cfg \
functional/clean_mirror/clean_mirror_common.kshlib \
functional/clean_mirror/default.cfg \
functional/crypto/aes_ccm_test.json \
functional/crypto/aes_ccm_test.txt \
functional/crypto/aes_gcm_test.json \
functional/crypto/aes_gcm_test.txt \
functional/cli_root/cli_common.kshlib \
functional/cli_root/zfs_copies/zfs_copies.cfg \
functional/cli_root/zfs_copies/zfs_copies.kshlib \
@@ -1427,9 +1431,8 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/crtime/cleanup.ksh \
functional/crtime/crtime_001_pos.ksh \
functional/crtime/setup.ksh \
functional/ctime/cleanup.ksh \
functional/ctime/ctime_001_pos.ksh \
functional/ctime/setup.ksh \
functional/crypto/icp_aes_ccm.ksh \
functional/crypto/icp_aes_gcm.ksh \
functional/deadman/deadman_ratelimit.ksh \
functional/deadman/deadman_sync.ksh \
functional/deadman/deadman_zio.ksh \
@@ -1441,7 +1444,9 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/dedup/dedup_legacy_import.ksh \
functional/dedup/dedup_legacy_fdt_upgrade.ksh \
functional/dedup/dedup_legacy_fdt_mixed.ksh \
functional/dedup/dedup_prune.ksh \
functional/dedup/dedup_quota.ksh \
functional/dedup/dedup_zap_shrink.ksh \
functional/delegate/cleanup.ksh \
functional/delegate/setup.ksh \
functional/delegate/zfs_allow_001_pos.ksh \
@@ -1853,6 +1858,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/removal/removal_with_export.ksh \
functional/removal/removal_with_faulted.ksh \
functional/removal/removal_with_ganging.ksh \
functional/removal/removal_with_hole.ksh \
functional/removal/removal_with_indirect.ksh \
functional/removal/removal_with_remove.ksh \
functional/removal/removal_with_scrub.ksh \
@@ -130,7 +130,7 @@ function test_posix_mode # base
}
# Sanity check on tmpfs first
tmpdir=$(TMPDIR=$TEST_BASE_DIR mktemp -d)
tmpdir=$(mktemp -d)
log_must mount -t tmpfs tmp $tmpdir
log_must chmod 777 $tmpdir
@@ -40,8 +40,8 @@
# dbufstat and the dbufs kstat output
#
DBUFSTATS_FILE=$(mktemp $TEST_BASE_DIR/dbufstats.out.XXXXXX)
DBUFS_FILE=$(mktemp $TEST_BASE_DIR/dbufs.out.XXXXXX)
DBUFSTATS_FILE=$(mktemp -t dbufstats.out.XXXXXX)
DBUFS_FILE=$(mktemp -t dbufs.out.XXXXXX)
function cleanup
{
@@ -42,7 +42,7 @@
# 8. Ensure that at least some dbufs moved to the mfu list in the ARC
#
DBUFS_FILE=$(mktemp $TEST_BASE_DIR/dbufs.out.XXXXXX)
DBUFS_FILE=$(mktemp -t dbufs.out.XXXXXX)
function cleanup
{
@@ -48,11 +48,13 @@ function get_same_blocks
if [ ${#KEY} -gt 0 ]; then
KEY="--key=$KEY"
fi
typeset zdbout=${TMPDIR:-$TEST_BASE_DIR}/zdbout.$$
typeset zdbout1=$(mktemp)
typeset zdbout2=$(mktemp)
zdb $KEY -vvvvv $1 -O $2 | \
awk '/ L0 / { print l++ " " $3 " " $7 }' > $zdbout.a
awk '/ L0 / { print l++ " " $3 " " $7 }' > $zdbout1
zdb $KEY -vvvvv $3 -O $4 | \
awk '/ L0 / { print l++ " " $3 " " $7 }' > $zdbout.b
echo $(sort -n $zdbout.a $zdbout.b | uniq -d | cut -f1 -d' ')
awk '/ L0 / { print l++ " " $3 " " $7 }' > $zdbout2
echo $(sort -n $zdbout1 $zdbout2 | uniq -d | cut -f1 -d' ')
rm -f $zdbout1 $zdbout2
}
@@ -38,10 +38,10 @@
verify_runnable "both"
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
MNTPT=$TMPDIR/zfs_mount_test_race_mntpt
DISK1="$TMPDIR/zfs_mount_test_race_disk1"
DISK2="$TMPDIR/zfs_mount_test_race_disk2"
DISKDIR=$(mktemp -d)
MNTPT=$DISKDIR/zfs_mount_test_race_mntpt
DISK1="$DISKDIR/zfs_mount_test_race_disk1"
DISK2="$DISKDIR/zfs_mount_test_race_disk2"
TESTPOOL1=zfs_mount_test_race_tp1
TESTPOOL2=zfs_mount_test_race_tp2
@@ -54,11 +54,9 @@ function cleanup
{
zpool destroy $TESTPOOL1
zpool destroy $TESTPOOL2
rm -rf $MNTPT
rm -rf $DISKDIR
rm -rf /$TESTPOOL1
rm -rf /$TESTPOOL2
rm -f $DISK1
rm -f $DISK2
export __ZFS_POOL_RESTRICT="$TESTPOOL1 $TESTPOOL2"
log_must zfs $mountall
unset __ZFS_POOL_RESTRICT
@@ -48,8 +48,8 @@ function cleanup
log_assert "Verify that 'zfs send' drills appropriate holes"
log_onexit cleanup
streamfile=$(mktemp $TESTDIR/file.XXXXXX)
vdev=$(mktemp $TEST_BASE_DIR/file.XXXXXX)
streamfile=$(mktemp)
vdev=$(mktemp)
function test_pool
@@ -160,7 +160,7 @@ while (( i < ${#pools[*]} )); do
((i = i + 1))
done
VDEV_FILE=$(mktemp $TEST_BASE_DIR/tmp.XXXXXX)
VDEV_FILE=$(mktemp)
log_must mkfile -n 128M $VDEV_FILE
log_must zpool create overflow $VDEV_FILE
@@ -29,9 +29,9 @@
# home directory.
#
# STRATEGY:
# 1. Change HOME to /var/tmp
# 1. Change HOME to /var/tmp (TEST_BASE_DIR)
# 2. Make a simple script that echoes a key value pair
# in /var/tmp/.zpool.d
# in $HOME/.zpool.d
# 3. Make sure it can be run with -c
# 4. Remove the script we created
@@ -29,9 +29,9 @@
# home directory.
#
# STRATEGY:
# 1. Change HOME to /var/tmp
# 1. Change HOME to /var/tmp (TEST_BASE_DIR)
# 2. Make a simple script that echoes a key value pair
# in /var/tmp/.zpool.d
# in $HOME/.zpool.d
# 3. Make sure it can be run with -c
# 4. Remove the script we created
@@ -0,0 +1,7 @@
.json test vectors taken from Project Wycheproof:
https://github.com/c2sp/wycheproof
Licensed under the Apache License, Version 2.0
.txt files generated with scripts/convert_wycheproof.pl
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,27 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
# CDDL HEADER END
#
#
# Copyright (c) 2025, Rob Norris <[email protected]>
#
. $STF_SUITE/include/libtest.shlib
log_assert "ICP passes test vectors for AES-CCM"
log_must crypto_test -c $STF_SUITE/tests/functional/crypto/aes_ccm_test.txt
log_pass "ICP passes test vectors for AES-CCM"
@@ -0,0 +1,27 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
# CDDL HEADER END
#
#
# Copyright (c) 2025, Rob Norris <[email protected]>
#
. $STF_SUITE/include/libtest.shlib
log_assert "ICP passes test vectors for AES-GCM"
log_must crypto_test -c $STF_SUITE/tests/functional/crypto/aes_gcm_test.txt
log_pass "ICP passes test vectors for AES-GCM"
@@ -0,0 +1,96 @@
#!/bin/ksh -p
# 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 https://opensource.org/licenses/CDDL-1.0.
# 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 (c) 2025, Klara Inc.
#
# DESCRIPTION:
# Verify that zpool ddtprune successfully reduces the number of entries
# in the DDT.
#
# STRATEGY:
# 1. Create a pool with dedup=on
# 2. Add duplicate entries to the DDT
# 3. Verify ddtprune doesn't remove duplicate entries
# 4. Convert some entries to non-duplicate
# 5. Verify ddtprune removes non-duplicate entries
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/events/events_common.kshlib
verify_runnable "both"
log_assert "Verify DDT pruning correctly removes non-duplicate entries"
# We set the dedup log txg interval to 1, to get a log flush every txg,
# effectively disabling the log. Without this it's hard to predict when
# entries appear in the DDT ZAP
log_must save_tunable DEDUP_LOG_TXG_MAX
log_must set_tunable32 DEDUP_LOG_TXG_MAX 1
function cleanup
{
if poolexists $TESTPOOL ; then
destroy_pool $TESTPOOL
fi
log_must restore_tunable DEDUP_LOG_TXG_MAX
}
function ddt_entries
{
typeset -i entries=$(zpool status -D $TESTPOOL | \
grep "dedup: DDT entries" | awk '{print $4}')
echo ${entries}
}
log_onexit cleanup
log_must zpool create -f -o feature@block_cloning=disabled $TESTPOOL $DISKS
log_must zfs create -o recordsize=512 -o dedup=on $TESTPOOL/$TESTFS
typeset mountpoint=$(get_prop mountpoint $TESTPOOL/$TESTFS)
log_must dd if=/dev/urandom of=$mountpoint/f1 bs=512k count=1
log_must cp $mountpoint/f1 $mountpoint/f2
sync_pool $TESTPOOL
entries=$(ddt_entries)
log_note "ddt entries before: $entries"
log_must zpool ddtprune -p 100 $TESTPOOL
sync_pool $TESTPOOL
new_entries=$(ddt_entries)
[[ "$entries" -eq "$new_entries" ]] || \
log_fail "DDT entries changed from $entries to $new_entries"
log_must truncate -s 128k $mountpoint/f2
sync_pool $TESTPOOL
sleep 1
log_must zpool ddtprune -p 100 $TESTPOOL
sync_pool $TESTPOOL
new_entries=$(ddt_entries)
[[ "$((entries / 4))" -eq "$new_entries" ]] || \
log_fail "DDT entries did not shrink enough: $entries -> $new_entries"
log_pass "DDT pruning correctly removes non-duplicate entries"
@@ -0,0 +1,82 @@
#! /bin/ksh -p
#
# 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 https://opensource.org/licenses/CDDL-1.0.
# 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 (c) 2024, 2025, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
# Create a large number of entries in the DDT. Then remove all entries and
# check that the DDT zap was shrunk. Use zdb to check that the zap object
# contains only one leaf block using zdb.
#
verify_runnable "global"
log_assert "Create a large number of entries in the DDT. " \
"Ensure DDT ZAP object shrank after removing entries."
# We set the dedup log txg interval to 1, to get a log flush every txg,
# effectively disabling the log. Without this it's hard to predict when
# entries appear in the DDT ZAP
log_must save_tunable DEDUP_LOG_TXG_MAX
log_must set_tunable32 DEDUP_LOG_TXG_MAX 1
function cleanup
{
if poolexists $TESTPOOL ; then
destroy_pool $TESTPOOL
fi
log_must restore_tunable DEDUP_LOG_TXG_MAX
}
log_onexit cleanup
log_must create_pool $TESTPOOL $DISKS
log_must zfs create -o dedup=sha256 -o recordsize=512 $TESTPOOL/$TESTFS
typeset mountpoint=$(get_prop mountpoint $TESTPOOL/$TESTFS)
log_must dd if=/dev/urandom of=$mountpoint/file bs=512k count=1
sync_pool $TESTPOOL
zap_obj=$(zdb -DDD $TESTPOOL | grep "DDT-sha256-zap-unique" | sed -n 's/.*object=//p')
nleafs=$(zdb -dddd $TESTPOOL "$zap_obj" | grep "Leaf blocks:" | awk -F\: '{print($2);}')
log_must test 1 -lt $nleafs
nleafs_old=$nleafs
log_must truncate -s 512 $mountpoint/file
sync_pool $TESTPOOL
nleafs=$(zdb -dddd $TESTPOOL "$zap_obj" | grep "Leaf blocks:" | awk -F\: '{print($2);}')
log_must test $nleafs -lt $nleafs_old
log_must zpool export $TESTPOOL
log_must zpool import $TESTPOOL
nleafs=$(zdb -dddd $TESTPOOL "$zap_obj" | grep "Leaf blocks:" | awk -F\: '{print($2);}')
log_must test $nleafs -lt $nleafs_old
log_pass "ZAP object shrank after removing entries."
@@ -26,13 +26,14 @@
. $STF_SUITE/include/libtest.shlib
DATAFILE="$TMPDIR/datafile"
DATAFILE=$(mktemp)
function cleanup
{
zpool clear $TESTPOOL
destroy_pool $TESTPOOL
unload_scsi_debug
rm -f $DATA_FILE
rm -f $DATAFILE
}
log_onexit cleanup
@@ -28,7 +28,7 @@ typeset ds_name="panic"
typeset sendfs="$POOL/$ds_name"
typeset recvfs="$POOL2/$ds_name"
typeset clone="$POOL/${ds_name}_clone"
typeset stream=$(mktemp $TEST_BASE_DIR/stream.XXXX)
typeset stream=$(mktemp -t stream.XXXX)
function cleanup
{
@@ -21,24 +21,24 @@
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/removal/removal.kshlib
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
log_must mkfile $MINVDEVSIZE $TMPDIR/dsk1
log_must mkfile $MINVDEVSIZE $TMPDIR/dsk2
DISKS="$TMPDIR/dsk1 $TMPDIR/dsk2"
REMOVEDISK=$TMPDIR/dsk1
DISKDIR=$(mktemp -d)
log_must mkfile $MINVDEVSIZE $DISKDIR/dsk1
log_must mkfile $MINVDEVSIZE $DISKDIR/dsk2
DISKS="$DISKDIR/dsk1 $DISKDIR/dsk2"
REMOVEDISK=$DISKDIR/dsk1
log_must default_setup_noexit "$DISKS"
function cleanup
{
default_cleanup_noexit
log_must rm -f $DISKS
log_must rm -rf $DISKDIR
}
log_onexit cleanup
# Write a little more than half the pool.
log_must dd if=/dev/urandom of=/$TESTDIR/$TESTFILE0 bs=$((2**20)) \
count=$((MINVDEVSIZE / (1024 * 1024)))
log_mustnot zpool remove $TESTPOOL $TMPDIR/dsk1
log_mustnot zpool remove $TESTPOOL $DISKDIR/dsk1
log_pass "Removal will not succeed if insufficient space."
@@ -44,18 +44,18 @@
# that the files contents remain the same across transfers.
#
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
log_must mkfile $(($MINVDEVSIZE * 2)) $TMPDIR/dsk1
log_must mkfile $(($MINVDEVSIZE * 2)) $TMPDIR/dsk2
DISKS="$TMPDIR/dsk1 $TMPDIR/dsk2"
REMOVEDISK=$TMPDIR/dsk1
DISKDIR=$(mktemp -d)
log_must mkfile $(($MINVDEVSIZE * 2)) $DISKDIR/dsk1
log_must mkfile $(($MINVDEVSIZE * 2)) $DISKDIR/dsk2
DISKS="$DISKDIR/dsk1 $DISKDIR/dsk2"
REMOVEDISK=$DISKDIR/dsk1
log_must default_setup_noexit "$DISKS"
function cleanup
{
default_cleanup_noexit
log_must rm -f $DISKS
log_must rm -rf $DISKDIR
# reset REMOVE_MAX_SEGMENT to 1M
set_tunable32 REMOVE_MAX_SEGMENT 1048576
@@ -71,19 +71,19 @@ FILE_CONTENTS=$(<$TESTDIR/$TESTFILE0)
log_must [ "x$(<$TESTDIR/$TESTFILE0)" = "x$FILE_CONTENTS" ]
for i in {1..10}; do
log_must zpool remove $TESTPOOL $TMPDIR/dsk1
log_must zpool remove $TESTPOOL $DISKDIR/dsk1
log_must wait_for_removal $TESTPOOL
log_mustnot vdevs_in_pool $TESTPOOL $TMPDIR/dsk1
log_must zpool add $TESTPOOL $TMPDIR/dsk1
log_mustnot vdevs_in_pool $TESTPOOL $DISKDIR/dsk1
log_must zpool add $TESTPOOL $DISKDIR/dsk1
log_must zinject -a
log_must dd if=$TESTDIR/$TESTFILE0 of=/dev/null
log_must [ "x$(<$TESTDIR/$TESTFILE0)" = "x$FILE_CONTENTS" ]
log_must zpool remove $TESTPOOL $TMPDIR/dsk2
log_must zpool remove $TESTPOOL $DISKDIR/dsk2
log_must wait_for_removal $TESTPOOL
log_mustnot vdevs_in_pool $TESTPOOL $TMPDIR/dsk2
log_must zpool add $TESTPOOL $TMPDIR/dsk2
log_mustnot vdevs_in_pool $TESTPOOL $DISKDIR/dsk2
log_must zpool add $TESTPOOL $DISKDIR/dsk2
log_must zinject -a
log_must dd if=$TESTDIR/$TESTFILE0 of=/dev/null
@@ -21,18 +21,18 @@
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/removal/removal.kshlib
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
log_must mkfile 1g $TMPDIR/dsk1
log_must mkfile 1g $TMPDIR/dsk2
DISKS="$TMPDIR/dsk1 $TMPDIR/dsk2"
REMOVEDISK=$TMPDIR/dsk1
DISKDIR=$(mktemp -d)
log_must mkfile 1g $DISKDIR/dsk1
log_must mkfile 1g $DISKDIR/dsk2
DISKS="$DISKDIR/dsk1 $DISKDIR/dsk2"
REMOVEDISK=$DISKDIR/dsk1
default_setup_noexit "$DISKS"
function cleanup
{
default_cleanup_noexit
log_must rm -f $DISKS
log_must rm -rf $DISKDIR
}
log_onexit cleanup
@@ -21,14 +21,14 @@
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/removal/removal.kshlib
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
log_must mkfile 1g $TMPDIR/dsk1
log_must mkfile 1g $TMPDIR/dsk2
DISKDIR=$(mktemp -d)
log_must mkfile 1g $DISKDIR/dsk1
log_must mkfile 1g $DISKDIR/dsk2
function cleanup
{
default_cleanup_noexit
log_must rm -f $TMPDIR/dsk1 $TMPDIR/dsk2
log_must rm -rf $DISKDIR
}
default_setup_noexit "$DISKS"
@@ -36,10 +36,10 @@ log_onexit cleanup
function callback
{
log_mustnot zpool attach -f $TESTPOOL $TMPDIR/dsk1 $TMPDIR/dsk2
log_mustnot zpool attach -f $TESTPOOL $DISKDIR/dsk1 $DISKDIR/dsk2
log_mustnot zpool add -f $TESTPOOL \
raidz $TMPDIR/dsk1 $TMPDIR/dsk2
log_must zpool add -f $TESTPOOL $TMPDIR/dsk1
raidz $DISKDIR/dsk1 $DISKDIR/dsk2
log_must zpool add -f $TESTPOOL $DISKDIR/dsk1
return 0
}
@@ -44,11 +44,11 @@
# 7. Lastly verify the pool data is still intact.
#
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
DISK0=$TMPDIR/dsk0
DISK1=$TMPDIR/dsk1
DISK2=$TMPDIR/dsk2
DISK3=$TMPDIR/dsk3
DISKDIR=$(mktemp -d)
DISK0=$DISKDIR/dsk0
DISK1=$DISKDIR/dsk1
DISK2=$DISKDIR/dsk2
DISK3=$DISKDIR/dsk3
log_must truncate -s $MINVDEVSIZE $DISK0 $DISK1
log_must truncate -s $((MINVDEVSIZE * 4)) $DISK2 $DISK3
@@ -57,7 +57,7 @@ function cleanup
{
log_must zinject -c all
default_cleanup_noexit
log_must rm -f $DISK0 $DISK1 $DISK2 $DISK3
log_must rm -rf $DISKDIR
}
function wait_for_removing_cancel
@@ -88,7 +88,7 @@ log_must file_write -o create -f $TESTDIR/$TESTFILE1 -b $((2**20)) -c $((2**8))
# Flush the ARC to minimize cache effects.
log_must zpool export $TESTPOOL
log_must zpool import -d $TMPDIR $TESTPOOL
log_must zpool import -d $DISKDIR $TESTPOOL
# Verify that unexpected read errors automatically cancel the removal.
log_must zinject -d $DISK0 -e io -T all -f 100 $TESTPOOL
@@ -99,7 +99,7 @@ log_must zinject -c all
# Flush the ARC to minimize cache effects.
log_must zpool export $TESTPOOL
log_must zpool import -d $TMPDIR $TESTPOOL
log_must zpool import -d $DISKDIR $TESTPOOL
# Verify that unexpected write errors automatically cancel the removal.
log_must zinject -d $DISK3 -e io -T all -f 100 $TESTPOOL
@@ -63,11 +63,11 @@
# data is still intact.
#
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
DISK0=$TMPDIR/dsk0
DISK1=$TMPDIR/dsk1
DISK2=$TMPDIR/dsk2
DISK3=$TMPDIR/dsk3
DISKDIR=$(mktemp -d)
DISK0=$DISKDIR/dsk0
DISK1=$DISKDIR/dsk1
DISK2=$DISKDIR/dsk2
DISK3=$DISKDIR/dsk3
log_must truncate -s $MINVDEVSIZE $DISK0 $DISK1
log_must truncate -s $((MINVDEVSIZE * 4)) $DISK2 $DISK3
@@ -75,7 +75,7 @@ log_must truncate -s $((MINVDEVSIZE * 4)) $DISK2 $DISK3
function cleanup
{
default_cleanup_noexit
log_must rm -f $DISK0 $DISK1 $DISK2 $DISK3
log_must rm -rf $DISKDIR
}
default_setup_noexit "mirror $DISK0 $DISK1 mirror $DISK2 $DISK3"
@@ -0,0 +1,34 @@
#! /bin/ksh -p
#
# CDDL HEADER START
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
# CDDL HEADER END
#
#
# Copyright (c) 2025 by Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/removal/removal.kshlib
log_onexit default_cleanup_noexit
DISK1="$(echo $DISKS | cut -d' ' -f1)"
DISK2="$(echo $DISKS | cut -d' ' -f2)"
DISK3="$(echo $DISKS | cut -d' ' -f3)"
log_must zpool create $TESTPOOL $DISK1 log $DISK2
log_must zpool add $TESTPOOL $DISK3
log_must zpool remove $TESTPOOL $DISK2
log_must zpool remove $TESTPOOL $DISK1
log_pass "Removal with a hole as the first other device doesn't panic."
@@ -21,12 +21,11 @@
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/removal/removal.kshlib
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
DISK1="$TMPDIR/dsk1"
DISK2="$TMPDIR/dsk2"
DISK3="$TMPDIR/dsk3"
DISK4="$TMPDIR/dsk4"
DISKDIR=$(mktemp -d)
DISK1="$DISKDIR/dsk1"
DISK2="$DISKDIR/dsk2"
DISK3="$DISKDIR/dsk3"
DISK4="$DISKDIR/dsk4"
DISKS="$DISK1 $DISK2 $DISK3 $DISK4"
log_must mkfile $(($MINVDEVSIZE * 2)) $DISK1
@@ -37,7 +36,7 @@ log_must mkfile $(($MINVDEVSIZE * 2)) $DISK4
function cleanup
{
default_cleanup_noexit
log_must rm -f $DISKS
log_must rm -rf $DISKDIR
}
# Build a zpool with 2 mirror vdevs
@@ -21,7 +21,7 @@
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/removal/removal.kshlib
zdbout=${TMPDIR:-$TEST_BASE_DIR}/zdbout.$$
zdbout=$(mktemp)
if is_linux; then
log_unsupported "ZDB fails during concurrent pool activity."
@@ -34,10 +34,9 @@
command -v fio > /dev/null || log_unsupported "fio missing"
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
DISK1="$TMPDIR/dsk1"
DISK2="$TMPDIR/dsk2"
DISKDIR=$(mktemp -d)
DISK1="$DISKDIR/dsk1"
DISK2="$DISKDIR/dsk2"
DISKS="$DISK1 $DISK2"
# fio options
@@ -58,7 +57,7 @@ log_must mkfile 4g $DISK2
function cleanup
{
default_cleanup_noexit
log_must rm -f $DISKS
log_must rm -rf $DISKDIR
}
log_must zpool create -O recordsize=4k $TESTPOOL $DISK1 $DISK2
@@ -32,10 +32,10 @@
#
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
DISK0=$TMPDIR/dsk0
DISK1=$TMPDIR/dsk1
DISK2=$TMPDIR/dsk2
DISKDIR=$(mktemp -d)
DISK0=$DISKDIR/dsk0
DISK1=$DISKDIR/dsk1
DISK2=$DISKDIR/dsk2
log_must truncate -s $MINVDEVSIZE $DISK0
log_must truncate -s $(($MINVDEVSIZE * 3)) $DISK1
@@ -44,7 +44,7 @@ log_must truncate -s $MINVDEVSIZE $DISK2
function cleanup
{
default_cleanup_noexit
log_must rm -f $DISK0 $DISK1 $DISK2
log_must rm -rf $DISKDIR
}
#
@@ -21,11 +21,10 @@
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/removal/removal.kshlib
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
DISK1="$TMPDIR/dsk1"
DISK2="$TMPDIR/dsk2"
DISK3="$TMPDIR/dsk3"
DISKDIR=$(mktemp -d)
DISK1="$DISKDIR/dsk1"
DISK2="$DISKDIR/dsk2"
DISK3="$DISKDIR/dsk3"
DISKS="$DISK1 $DISK2 $DISK3"
log_must mkfile $(($MINVDEVSIZE * 2)) $DISK1
@@ -35,7 +34,7 @@ log_must mkfile $(($MINVDEVSIZE * 2)) $DISK3
function cleanup
{
default_cleanup_noexit
log_must rm -f $DISKS
log_must rm -rf $DISKDIR
}
log_must default_setup_noexit "$DISK1 mirror $DISK2 $DISK3"
@@ -21,28 +21,28 @@
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/removal/removal.kshlib
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
log_must mkfile $MINVDEVSIZE $TMPDIR/dsk1
log_must mkfile $MINVDEVSIZE $TMPDIR/dsk2
log_must mkfile $MINVDEVSIZE $TMPDIR/dsk3
DISKS1="$TMPDIR/dsk1"
DISKS2="$TMPDIR/dsk2 $TMPDIR/dsk3"
DISKDIR=$(mktemp -d)
log_must mkfile $MINVDEVSIZE $DISKDIR/dsk1
log_must mkfile $MINVDEVSIZE $DISKDIR/dsk2
log_must mkfile $MINVDEVSIZE $DISKDIR/dsk3
DISKS1="$DISKDIR/dsk1"
DISKS2="$DISKDIR/dsk2 $DISKDIR/dsk3"
DISKS="$DISKS1 $DISKS2"
function cleanup
{
default_cleanup_noexit
log_must rm -f $DISKS
log_must rm -rf $DISKDIR
}
log_must default_setup_noexit "$DISKS1 raidz $DISKS2"
log_onexit cleanup
# Attempt to remove the non raidz disk.
log_mustnot zpool remove $TESTPOOL $TMPDIR/dsk1
log_mustnot zpool remove $TESTPOOL $DISKDIR/dsk1
# Attempt to remove one of the raidz disks.
log_mustnot zpool remove $TESTPOOL $TMPDIR/dsk2
log_mustnot zpool remove $TESTPOOL $DISKDIR/dsk2
# Attempt to remove the raidz.
log_mustnot zpool remove $TESTPOOL raidz1-1
@@ -63,7 +63,7 @@ function cleanup
log_assert "Verify an archive of a file system is identical to " \
"an archive of its snapshot."
SNAPSHOT_TARDIR="$(mktemp -d /tmp/zfstests_snapshot_002.XXXXXX)"
SNAPSHOT_TARDIR="$(mktemp -t -d zfstests_snapshot_002.XXXXXX)"
log_onexit cleanup
typeset -i COUNT=21
@@ -72,7 +72,7 @@ function cleanup
log_assert "Verify that an archive of a dataset is identical to " \
"an archive of the dataset's snapshot."
SNAPSHOT_TARDIR="$(mktemp -d /tmp/zfstests_snapshot_006.XXXXXX)"
SNAPSHOT_TARDIR="$(mktemp -t -d zfstests_snapshot_006.XXXXXX)"
log_onexit cleanup
typeset -i COUNT=21
@@ -58,7 +58,7 @@ log_onexit user_ns_cleanup
log_must zfs create -o zoned=on "$TESTPOOL/userns"
# 1. Try to pass a non-namespace file to zfs zone.
temp_file="$(TMPDIR=$TEST_BASE_DIR mktemp)"
temp_file="$(mktemp)"
log_mustnot zfs zone "$temp_file" "$TESTPOOL/userns"
# 2. Try to pass a non-namespace and non-existent file to zfs zone.
@@ -47,8 +47,8 @@ if ! is_linux ; then
log_unsupported "Only linux supports dd with oflag=dsync for FUA writes"
fi
typeset datafile1="$(mktemp zvol_misc_fua1.XXXXXX)"
typeset datafile2="$(mktemp zvol_misc_fua2.XXXXXX)"
typeset datafile1="$(mktemp -t zvol_misc_fua1.XXXXXX)"
typeset datafile2="$(mktemp -t zvol_misc_fua2.XXXXXX)"
typeset zvolpath=${ZVOL_DEVDIR}/$TESTPOOL/$TESTVOL
function cleanup
@@ -65,8 +65,8 @@ if ! is_physical_device $DISKS; then
log_unsupported "This directory cannot be run on raw files."
fi
typeset datafile1="$(mktemp zvol_misc_flags1.XXXXXX)"
typeset datafile2="$(mktemp zvol_misc_flags2.XXXXXX)"
typeset datafile1="$(mktemp -t zvol_misc_flags1.XXXXXX)"
typeset datafile2="$(mktemp -t zvol_misc_flags2.XXXXXX)"
typeset zvolpath=${ZVOL_DEVDIR}/$TESTPOOL/$TESTVOL
function cleanup
@@ -57,7 +57,7 @@ biggest_zvol_size_possible=$(largest_volsize_from_pool $TESTPOOL)
typeset -f each_zvol_size=$(( floor($biggest_zvol_size_possible * 0.9 / \
$num_zvols )))
typeset tmpdir="$(mktemp -d zvol_stress_fio_state.XXXXXX)"
typeset tmpdir="$(mktemp -t -d zvol_stress_fio_state.XXXXXX)"
function create_zvols
{
@@ -41,7 +41,7 @@
# 1. Create a pool
# 2. Create a zvol volume
# 3. Use zvol as swap space
# 4. Create a file under /var/tmp
# 4. Create a file under /var/tmp (TEST_BASE_DIR)
#
verify_runnable "global"
@@ -63,11 +63,11 @@ voldev=${ZVOL_DEVDIR}/$TESTPOOL/$TESTVOL
log_note "Add zvol volume as swap space"
log_must swap_setup $voldev
log_note "Create a file under /var/tmp"
log_note "Create a file under $TEST_BASE_DIR"
log_must file_write -o create -f $TEMPFILE \
-b $BLOCKSZ -c $NUM_WRITES -d $DATA
[[ ! -f $TEMPFILE ]] && log_fail "Unable to create file under /var/tmp"
[[ ! -f $TEMPFILE ]] && log_fail "Unable to create file under $TEST_BASE_DIR"
filesize=`ls -l $TEMPFILE | awk '{print $5}'`
tf_size=$(( BLOCKSZ * NUM_WRITES ))
@@ -39,7 +39,7 @@
#
# STRATEGY:
# 1. Create a new zvol and add it as swap
# 2. Fill //var/tmp with 80% the size of the zvol
# 2. Fill //var/tmp (TEST_BASE_DIR) with 80% the size of the zvol
# 5. Remove the new zvol, and restore original swap devices
#
@@ -54,7 +54,7 @@ function cleanup
fi
}
log_assert "Using a zvol as swap space, fill /var/tmp to 80%."
log_assert "Using a zvol as swap space, fill $TEST_BASE_DIR to 80%."
log_onexit cleanup
@@ -73,4 +73,4 @@ log_must dd if=/dev/urandom of=$TEMPFILE bs=1048576 count=$count
log_must rm -f $TEMPFILE
log_must swap_cleanup $swapdev
log_pass "Using a zvol as swap space, fill /var/tmp to 80%."
log_pass "Using a zvol as swap space, fill $TEST_BASE_DIR to 80%."
+1 -1
View File
@@ -185,7 +185,6 @@ SRCS+= abd_os.c \
kmod_core.c \
spa_os.c \
sysctl_os.c \
vdev_file.c \
vdev_geom.c \
vdev_label_os.c \
zfs_acl.c \
@@ -298,6 +297,7 @@ SRCS+= abd.c \
vdev.c \
vdev_draid.c \
vdev_draid_rand.c \
vdev_file.c \
vdev_indirect.c \
vdev_indirect_births.c \
vdev_indirect_mapping.c \
+3 -2
View File
@@ -218,6 +218,7 @@
the CoreFoundation framework. */
/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */
/* check_disk_change() exists */
/* #undef HAVE_CHECK_DISK_CHANGE */
/* copy_splice_read exists */
@@ -793,7 +794,7 @@
/* #undef ZFS_DEVICE_MINOR */
/* Define the project alias string. */
#define ZFS_META_ALIAS "zfs-2.3.99-189-FreeBSD_g6a2f7b384"
#define ZFS_META_ALIAS "zfs-2.3.99-212-FreeBSD_gfe674998b"
/* Define the project author. */
#define ZFS_META_AUTHOR "OpenZFS"
@@ -823,7 +824,7 @@
#define ZFS_META_NAME "zfs"
/* Define the project release. */
#define ZFS_META_RELEASE "189-FreeBSD_g6a2f7b384"
#define ZFS_META_RELEASE "212-FreeBSD_gfe674998b"
/* Define the project version. */
#define ZFS_META_VERSION "2.3.99"
Loaded 100 of 101 files, more files were not shown because too many files have changed in this diff. Show more