Compare commits
No commits in common. "zfs-2.1-release" and "zfs-2.1.0-rc5" have entirely different histories.
zfs-2.1-re
...
zfs-2.1.0-
|
@ -2,7 +2,7 @@
|
|||
name: Bug report
|
||||
about: Create a report to help us improve OpenZFS
|
||||
title: ''
|
||||
labels: 'Type: Defect'
|
||||
labels: 'Type: Defect, Status: Triage Needed'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
@ -25,16 +25,14 @@ Type | Version/Name
|
|||
--- | ---
|
||||
Distribution Name |
|
||||
Distribution Version |
|
||||
Kernel Version |
|
||||
Linux Kernel |
|
||||
Architecture |
|
||||
OpenZFS Version |
|
||||
ZFS Version |
|
||||
SPL Version |
|
||||
<!--
|
||||
Command to find OpenZFS version:
|
||||
zfs version
|
||||
|
||||
Commands to find kernel version:
|
||||
uname -r # Linux
|
||||
freebsd-version -r # FreeBSD
|
||||
Commands to find ZFS/SPL versions:
|
||||
modinfo zfs | grep -iw version
|
||||
modinfo spl | grep -iw version
|
||||
-->
|
||||
|
||||
### Describe the problem you're observing
|
||||
|
|
|
@ -10,5 +10,5 @@ contact_links:
|
|||
url: https://lists.freebsd.org/mailman/listinfo/freebsd-fs
|
||||
about: Get community support for OpenZFS on FreeBSD
|
||||
- name: OpenZFS on IRC
|
||||
url: https://web.libera.chat/#openzfs
|
||||
url: https://webchat.freenode.net/#openzfs
|
||||
about: Use IRC to get community support for OpenZFS
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
acl
|
||||
alien
|
||||
attr
|
||||
autoconf
|
||||
bc
|
||||
build-essential
|
||||
curl
|
||||
dbench
|
||||
debhelper-compat
|
||||
dh-python
|
||||
dkms
|
||||
fakeroot
|
||||
fio
|
||||
gdb
|
||||
gdebi
|
||||
git
|
||||
ksh
|
||||
lcov
|
||||
libacl1-dev
|
||||
libaio-dev
|
||||
libattr1-dev
|
||||
libblkid-dev
|
||||
libcurl4-openssl-dev
|
||||
libdevmapper-dev
|
||||
libelf-dev
|
||||
libffi-dev
|
||||
libmount-dev
|
||||
libpam0g-dev
|
||||
libselinux1-dev
|
||||
libssl-dev
|
||||
libtool
|
||||
libudev-dev
|
||||
linux-headers-generic
|
||||
lsscsi
|
||||
mdadm
|
||||
nfs-kernel-server
|
||||
pamtester
|
||||
parted
|
||||
po-debconf
|
||||
python3
|
||||
python3-all-dev
|
||||
python3-cffi
|
||||
python3-dev
|
||||
python3-packaging
|
||||
python3-pip
|
||||
python3-setuptools
|
||||
python3-sphinx
|
||||
rng-tools-debian
|
||||
rsync
|
||||
samba
|
||||
sysstat
|
||||
uuid-dev
|
||||
watchdog
|
||||
wget
|
||||
xfslibs-dev
|
||||
xz-utils
|
||||
zlib1g-dev
|
|
@ -1,2 +0,0 @@
|
|||
pax-utils
|
||||
shellcheck
|
|
@ -6,27 +6,20 @@ on:
|
|||
|
||||
jobs:
|
||||
checkstyle:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# https://github.com/orgs/community/discussions/47863
|
||||
sudo apt-mark hold grub-efi-amd64-signed
|
||||
sudo apt-get update --fix-missing
|
||||
sudo apt-get upgrade
|
||||
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
||||
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/checkstyle-dependencies.txt apt-get install -qq
|
||||
sudo python3 -m pip install --quiet flake8
|
||||
sudo apt-get clean
|
||||
|
||||
# confirm that the tools are installed
|
||||
# the build system doesn't fail when they are not
|
||||
flake8 --version
|
||||
scanelf --version
|
||||
shellcheck --version
|
||||
sudo apt-get update
|
||||
sudo apt-get install --yes -qq build-essential autoconf libtool gawk alien fakeroot linux-headers-$(uname -r)
|
||||
sudo apt-get install --yes -qq zlib1g-dev uuid-dev libattr1-dev libblkid-dev libselinux-dev libudev-dev libssl-dev python-dev python-setuptools python-cffi python3 python3-dev python3-setuptools python3-cffi
|
||||
# packages for tests
|
||||
sudo apt-get install --yes -qq parted lsscsi ksh attr acl nfs-kernel-server fio
|
||||
sudo apt-get install --yes -qq mandoc cppcheck pax-utils devscripts abigail-tools
|
||||
sudo -E pip --quiet install flake8
|
||||
- name: Prepare
|
||||
run: |
|
||||
sh ./autogen.sh
|
||||
|
@ -39,19 +32,5 @@ jobs:
|
|||
run: |
|
||||
make lint
|
||||
- name: CheckABI
|
||||
id: CheckABI
|
||||
run: |
|
||||
sudo docker run -v $(pwd):/source ghcr.io/openzfs/libabigail make checkabi
|
||||
- name: StoreABI
|
||||
if: failure() && steps.CheckABI.outcome == 'failure'
|
||||
run: |
|
||||
sudo docker run -v $(pwd):/source ghcr.io/openzfs/libabigail make storeabi
|
||||
- name: Prepare artifacts
|
||||
if: failure() && steps.CheckABI.outcome == 'failure'
|
||||
run: |
|
||||
find -name *.abi | tar -cf abi_files.tar -T -
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: failure() && steps.CheckABI.outcome == 'failure'
|
||||
with:
|
||||
name: New ABI files (use only if you're sure about interface changes)
|
||||
path: abi_files.tar
|
||||
make checkabi
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
# remove 4GiB of images
|
||||
sudo systemd-run docker system prune --force --all --volumes
|
||||
|
||||
# remove unused software
|
||||
sudo systemd-run --wait rm -rf \
|
||||
"$AGENT_TOOLSDIRECTORY" \
|
||||
/opt/* \
|
||||
/usr/local/* \
|
||||
/usr/share/az* \
|
||||
/usr/share/dotnet \
|
||||
/usr/share/gradle* \
|
||||
/usr/share/miniconda \
|
||||
/usr/share/swift \
|
||||
/var/lib/gems \
|
||||
/var/lib/mysql \
|
||||
/var/lib/snapd
|
||||
|
||||
# trim the cleaned space
|
||||
sudo fstrim /
|
|
@ -9,20 +9,24 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [20.04, 22.04]
|
||||
os: [18.04, 20.04]
|
||||
runs-on: ubuntu-${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# https://github.com/orgs/community/discussions/47863
|
||||
sudo apt-mark hold grub-efi-amd64-signed
|
||||
sudo apt-get update --fix-missing
|
||||
sudo apt-get upgrade
|
||||
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
||||
sudo apt-get clean
|
||||
sudo apt-get update
|
||||
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
|
||||
git alien fakeroot wget curl bc fio acl \
|
||||
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
|
||||
nfs-kernel-server samba rng-tools xz-utils \
|
||||
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
|
||||
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
||||
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
|
||||
libpam0g-dev pamtester python-dev python-setuptools python-cffi \
|
||||
python3 python3-dev python3-setuptools python3-cffi
|
||||
- name: Autogen.sh
|
||||
run: |
|
||||
sh autogen.sh
|
||||
|
@ -40,42 +44,27 @@ jobs:
|
|||
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
||||
sudo depmod
|
||||
sudo modprobe zfs
|
||||
# Workaround for cloud-init bug
|
||||
# see https://github.com/openzfs/zfs/issues/12644
|
||||
FILE=/lib/udev/rules.d/10-cloud-init-hook-hotplug.rules
|
||||
if [ -r "${FILE}" ]; then
|
||||
HASH=$(md5sum "${FILE}" | awk '{ print $1 }')
|
||||
if [ "${HASH}" = "121ff0ef1936cd2ef65aec0458a35772" ]; then
|
||||
# Just shove a zd* exclusion right above the hotplug hook...
|
||||
sudo sed -i -e s/'LABEL="cloudinit_hook"'/'KERNEL=="zd*", GOTO="cloudinit_end"\n&'/ "${FILE}"
|
||||
sudo udevadm control --reload-rules
|
||||
fi
|
||||
fi
|
||||
- name: Clear the kernel ring buffer
|
||||
run: |
|
||||
sudo dmesg -c >/var/tmp/dmesg-prerun
|
||||
- name: Reclaim and report disk space
|
||||
run: |
|
||||
${{ github.workspace }}/.github/workflows/scripts/reclaim_disk_space.sh
|
||||
df -h /
|
||||
# Workaround to provide additional free space for testing.
|
||||
# https://github.com/actions/virtual-environments/issues/2840
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
sudo rm -rf /opt/ghc
|
||||
sudo rm -rf "/usr/local/share/boost"
|
||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||
- name: Tests
|
||||
run: |
|
||||
/usr/share/zfs/zfs-tests.sh -vR -s 3G
|
||||
timeout-minutes: 330
|
||||
/usr/share/zfs/zfs-tests.sh -v -s 3G
|
||||
- name: Prepare artifacts
|
||||
if: failure()
|
||||
run: |
|
||||
RESULTS_PATH=$(readlink -f /var/tmp/test_results/current)
|
||||
sudo dmesg > $RESULTS_PATH/dmesg
|
||||
sudo cp /var/log/syslog /var/tmp/dmesg-prerun $RESULTS_PATH/
|
||||
sudo cp /var/log/syslog $RESULTS_PATH/
|
||||
sudo chmod +r $RESULTS_PATH/*
|
||||
# Replace ':' in dir names, actions/upload-artifact doesn't support it
|
||||
for f in $(find /var/tmp/test_results -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||
- uses: actions/upload-artifact@v3
|
||||
for f in $(find $RESULTS_PATH -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Test logs Ubuntu-${{ matrix.os }}
|
||||
path: |
|
||||
/var/tmp/test_results/*
|
||||
!/var/tmp/test_results/current
|
||||
path: /var/tmp/test_results/20*/
|
||||
if-no-files-found: ignore
|
||||
|
|
|
@ -6,19 +6,23 @@ on:
|
|||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# https://github.com/orgs/community/discussions/47863
|
||||
sudo apt-mark hold grub-efi-amd64-signed
|
||||
sudo apt-get update --fix-missing
|
||||
sudo apt-get upgrade
|
||||
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
||||
sudo apt-get clean
|
||||
sudo apt-get update
|
||||
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
|
||||
git alien fakeroot wget curl bc fio acl \
|
||||
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
|
||||
nfs-kernel-server samba rng-tools xz-utils \
|
||||
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
|
||||
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
||||
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
|
||||
libpam0g-dev pamtester python-dev python-setuptools python-cffi \
|
||||
python3 python3-dev python3-setuptools python3-cffi
|
||||
- name: Autogen.sh
|
||||
run: |
|
||||
sh autogen.sh
|
||||
|
@ -36,42 +40,27 @@ jobs:
|
|||
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
||||
sudo depmod
|
||||
sudo modprobe zfs
|
||||
# Workaround for cloud-init bug
|
||||
# see https://github.com/openzfs/zfs/issues/12644
|
||||
FILE=/lib/udev/rules.d/10-cloud-init-hook-hotplug.rules
|
||||
if [ -r "${FILE}" ]; then
|
||||
HASH=$(md5sum "${FILE}" | awk '{ print $1 }')
|
||||
if [ "${HASH}" = "121ff0ef1936cd2ef65aec0458a35772" ]; then
|
||||
# Just shove a zd* exclusion right above the hotplug hook...
|
||||
sudo sed -i -e s/'LABEL="cloudinit_hook"'/'KERNEL=="zd*", GOTO="cloudinit_end"\n&'/ "${FILE}"
|
||||
sudo udevadm control --reload-rules
|
||||
fi
|
||||
fi
|
||||
- name: Clear the kernel ring buffer
|
||||
run: |
|
||||
sudo dmesg -c >/var/tmp/dmesg-prerun
|
||||
- name: Reclaim and report disk space
|
||||
run: |
|
||||
${{ github.workspace }}/.github/workflows/scripts/reclaim_disk_space.sh
|
||||
df -h /
|
||||
# Workaround to provide additional free space for testing.
|
||||
# https://github.com/actions/virtual-environments/issues/2840
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
sudo rm -rf /opt/ghc
|
||||
sudo rm -rf "/usr/local/share/boost"
|
||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||
- name: Tests
|
||||
run: |
|
||||
/usr/share/zfs/zfs-tests.sh -vR -s 3G -r sanity
|
||||
timeout-minutes: 330
|
||||
/usr/share/zfs/zfs-tests.sh -v -s 3G -r sanity
|
||||
- name: Prepare artifacts
|
||||
if: failure()
|
||||
run: |
|
||||
RESULTS_PATH=$(readlink -f /var/tmp/test_results/current)
|
||||
sudo dmesg > $RESULTS_PATH/dmesg
|
||||
sudo cp /var/log/syslog /var/tmp/dmesg-prerun $RESULTS_PATH/
|
||||
sudo cp /var/log/syslog $RESULTS_PATH/
|
||||
sudo chmod +r $RESULTS_PATH/*
|
||||
# Replace ':' in dir names, actions/upload-artifact doesn't support it
|
||||
for f in $(find /var/tmp/test_results -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||
- uses: actions/upload-artifact@v3
|
||||
for f in $(find $RESULTS_PATH -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Test logs Ubuntu-${{ matrix.os }}
|
||||
path: |
|
||||
/var/tmp/test_results/*
|
||||
!/var/tmp/test_results/current
|
||||
name: Test logs
|
||||
path: /var/tmp/test_results/20*/
|
||||
if-no-files-found: ignore
|
||||
|
|
|
@ -6,21 +6,24 @@ on:
|
|||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TEST_DIR: /var/tmp/zloop
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# https://github.com/orgs/community/discussions/47863
|
||||
sudo apt-mark hold grub-efi-amd64-signed
|
||||
sudo apt-get update --fix-missing
|
||||
sudo apt-get upgrade
|
||||
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
||||
sudo apt-get clean
|
||||
sudo apt-get update
|
||||
sudo apt-get install --yes -qq build-essential autoconf libtool gdb \
|
||||
git alien fakeroot \
|
||||
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
|
||||
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
||||
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
|
||||
libpam0g-dev \
|
||||
python-dev python-setuptools python-cffi \
|
||||
python3 python3-dev python3-setuptools python3-cffi
|
||||
- name: Autogen.sh
|
||||
run: |
|
||||
sh autogen.sh
|
||||
|
@ -41,14 +44,13 @@ jobs:
|
|||
- name: Tests
|
||||
run: |
|
||||
sudo mkdir -p $TEST_DIR
|
||||
# run for 10 minutes or at most 2 iterations for a maximum runner
|
||||
# time of 20 minutes.
|
||||
sudo /usr/share/zfs/zloop.sh -t 600 -I 2 -l -m1 -- -T 120 -P 60
|
||||
# run for 20 minutes to have a total runner time of 30 minutes
|
||||
sudo /usr/share/zfs/zloop.sh -t 1200 -l -m1
|
||||
- name: Prepare artifacts
|
||||
if: failure()
|
||||
run: |
|
||||
sudo chmod +r -R $TEST_DIR/
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Logs
|
||||
|
@ -56,7 +58,7 @@ jobs:
|
|||
/var/tmp/zloop/*/
|
||||
!/var/tmp/zloop/*/vdev/
|
||||
if-no-files-found: ignore
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Pool files
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
The [OpenZFS Code of Conduct](https://openzfs.org/wiki/Code_of_Conduct)
|
||||
The [OpenZFS Code of Conduct](http://www.open-zfs.org/wiki/Code_of_Conduct)
|
||||
applies to spaces associated with the OpenZFS project, including GitHub.
|
||||
|
|
6
META
6
META
|
@ -1,10 +1,10 @@
|
|||
Meta: 1
|
||||
Name: zfs
|
||||
Branch: 1.0
|
||||
Version: 2.1.15
|
||||
Release: 1
|
||||
Version: 2.1.0
|
||||
Release: rc5
|
||||
Release-Tags: relext
|
||||
License: CDDL
|
||||
Author: OpenZFS
|
||||
Linux-Maximum: 6.7
|
||||
Linux-Maximum: 5.12
|
||||
Linux-Minimum: 3.10
|
||||
|
|
79
Makefile.am
79
Makefile.am
|
@ -1,5 +1,3 @@
|
|||
include $(top_srcdir)/config/Shellcheck.am
|
||||
|
||||
ACLOCAL_AMFLAGS = -I config
|
||||
|
||||
SUBDIRS = include
|
||||
|
@ -8,7 +6,7 @@ SUBDIRS += rpm
|
|||
endif
|
||||
|
||||
if CONFIG_USER
|
||||
SUBDIRS += man scripts lib tests cmd etc contrib
|
||||
SUBDIRS += etc man scripts lib tests cmd contrib
|
||||
if BUILD_LINUX
|
||||
SUBDIRS += udev
|
||||
endif
|
||||
|
@ -103,7 +101,7 @@ endif
|
|||
endif
|
||||
|
||||
PHONY += codecheck
|
||||
codecheck: cstyle shellcheck checkbashisms flake8 mancheck testscheck vcscheck zstdcheck
|
||||
codecheck: cstyle shellcheck checkbashisms flake8 mancheck testscheck vcscheck
|
||||
|
||||
PHONY += checkstyle
|
||||
checkstyle: codecheck commitcheck
|
||||
|
@ -114,47 +112,70 @@ commitcheck:
|
|||
${top_srcdir}/scripts/commitcheck.sh; \
|
||||
fi
|
||||
|
||||
if HAVE_PARALLEL
|
||||
cstyle_line = -print0 | parallel -X0 ${top_srcdir}/scripts/cstyle.pl -cpP {}
|
||||
else
|
||||
cstyle_line = -exec ${top_srcdir}/scripts/cstyle.pl -cpP {} +
|
||||
endif
|
||||
PHONY += cstyle
|
||||
cstyle:
|
||||
@find ${top_srcdir} -name build -prune \
|
||||
-o -type f -name '*.[hc]' \
|
||||
! -name 'zfs_config.*' ! -name '*.mod.c' \
|
||||
! -name 'opt_global.h' ! -name '*_if*.h' \
|
||||
! -name 'zstd_compat_wrapper.h' \
|
||||
! -path './module/zstd/lib/*' \
|
||||
$(cstyle_line)
|
||||
-exec ${top_srcdir}/scripts/cstyle.pl -cpP {} \+
|
||||
|
||||
filter_executable = -exec test -x '{}' \; -print
|
||||
|
||||
SHELLCHECKDIRS = cmd contrib etc scripts tests
|
||||
SHELLCHECKSCRIPTS = autogen.sh
|
||||
PHONY += shellcheck
|
||||
shellcheck:
|
||||
@if type shellcheck > /dev/null 2>&1; then \
|
||||
shellcheck --exclude=SC1090 --exclude=SC1117 --format=gcc \
|
||||
$$(find ${top_srcdir}/scripts/*.sh -type f) \
|
||||
$$(find ${top_srcdir}/cmd/zed/zed.d/*.sh -type f) \
|
||||
$$(find ${top_srcdir}/cmd/zpool/zpool.d/* \
|
||||
-type f ${filter_executable}); \
|
||||
else \
|
||||
echo "skipping shellcheck because shellcheck is not installed"; \
|
||||
fi
|
||||
|
||||
PHONY += checkabi storeabi
|
||||
|
||||
checklibabiversion:
|
||||
libabiversion=`abidw -v | $(SED) 's/[^0-9]//g'`; \
|
||||
if test $$libabiversion -lt "200"; then \
|
||||
/bin/echo -e "\n" \
|
||||
"*** Please use libabigail 2.0.0 version or newer;\n" \
|
||||
"*** otherwise results are not consistent!\n" \
|
||||
"(or see https://github.com/openzfs/libabigail-docker )\n"; \
|
||||
exit 1; \
|
||||
fi;
|
||||
|
||||
checkabi: checklibabiversion lib
|
||||
checkabi: lib
|
||||
$(MAKE) -C lib checkabi
|
||||
|
||||
storeabi: checklibabiversion lib
|
||||
storeabi: lib
|
||||
$(MAKE) -C lib storeabi
|
||||
|
||||
PHONY += checkbashisms
|
||||
checkbashisms:
|
||||
@if type checkbashisms > /dev/null 2>&1; then \
|
||||
checkbashisms -n -p -x \
|
||||
$$(find ${top_srcdir} \
|
||||
-name '.git' -prune \
|
||||
-o -name 'build' -prune \
|
||||
-o -name 'tests' -prune \
|
||||
-o -name 'config' -prune \
|
||||
-o -name 'zed-functions.sh*' -prune \
|
||||
-o -name 'zfs-import*' -prune \
|
||||
-o -name 'zfs-mount*' -prune \
|
||||
-o -name 'zfs-zed*' -prune \
|
||||
-o -name 'smart' -prune \
|
||||
-o -name 'paxcheck.sh' -prune \
|
||||
-o -name 'make_gitrev.sh' -prune \
|
||||
-o -name '90zfs' -prune \
|
||||
-o -type f ! -name 'config*' \
|
||||
! -name 'libtool' \
|
||||
-exec sh -c 'awk "NR==1 && /#!.*bin\/sh.*/ {print FILENAME;}" "{}"' \;); \
|
||||
else \
|
||||
echo "skipping checkbashisms because checkbashisms is not installed"; \
|
||||
fi
|
||||
|
||||
PHONY += mancheck
|
||||
mancheck:
|
||||
${top_srcdir}/scripts/mancheck.sh ${top_srcdir}/man ${top_srcdir}/tests/test-runner/man
|
||||
@if type mandoc > /dev/null 2>&1; then \
|
||||
find ${top_srcdir}/man/man8 -type f -name 'zfs.8' \
|
||||
-o -name 'zpool.8' -o -name 'zdb.8' \
|
||||
-o -name 'zgenhostid.8' | \
|
||||
xargs mandoc -Tlint -Werror; \
|
||||
else \
|
||||
echo "skipping mancheck because mandoc is not installed"; \
|
||||
fi
|
||||
|
||||
if BUILD_LINUX
|
||||
stat_fmt = -c '%A %n'
|
||||
|
@ -179,10 +200,6 @@ vcscheck:
|
|||
awk '{c++; print} END {if(c>0) exit 1}' ; \
|
||||
fi
|
||||
|
||||
PHONY += zstdcheck
|
||||
zstdcheck:
|
||||
@$(MAKE) -C module/zstd checksymbols
|
||||
|
||||
PHONY += lint
|
||||
lint: cppcheck paxcheck
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ This repository contains the code for running OpenZFS on Linux and FreeBSD.
|
|||
* [Documentation](https://openzfs.github.io/openzfs-docs/) - for using and developing this repo
|
||||
* [ZoL Site](https://zfsonlinux.org) - Linux release info & links
|
||||
* [Mailing lists](https://openzfs.github.io/openzfs-docs/Project%20and%20Community/Mailing%20Lists.html)
|
||||
* [OpenZFS site](https://openzfs.org/) - for conference videos and info on other platforms (illumos, OSX, Windows, etc)
|
||||
* [OpenZFS site](http://open-zfs.org/) - for conference videos and info on other platforms (illumos, OSX, Windows, etc)
|
||||
|
||||
# Installation
|
||||
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
include $(top_srcdir)/config/Shellcheck.am
|
||||
|
||||
SUBDIRS = zfs zpool zdb zhack zinject zstream ztest
|
||||
SUBDIRS = zfs zpool zdb zhack zinject zstream zstreamdump ztest
|
||||
SUBDIRS += fsck_zfs vdev_id raidz_test zfs_ids_to_path
|
||||
SUBDIRS += zpool_influxdb
|
||||
|
||||
CPPCHECKDIRS = zfs zpool zdb zhack zinject zstream ztest
|
||||
CPPCHECKDIRS += raidz_test zfs_ids_to_path zpool_influxdb
|
||||
|
||||
# TODO: #12084: SHELLCHECKDIRS = fsck_zfs vdev_id zpool
|
||||
SHELLCHECKDIRS = fsck_zfs zpool
|
||||
|
||||
if USING_PYTHON
|
||||
SUBDIRS += arcstat arc_summary dbufstat
|
||||
endif
|
||||
|
@ -17,7 +12,6 @@ endif
|
|||
if BUILD_LINUX
|
||||
SUBDIRS += mount_zfs zed zgenhostid zvol_id zvol_wait
|
||||
CPPCHECKDIRS += mount_zfs zed zgenhostid zvol_id
|
||||
SHELLCHECKDIRS += zed
|
||||
endif
|
||||
|
||||
PHONY = cppcheck
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
bin_SCRIPTS = arc_summary
|
||||
|
||||
CLEANFILES = arc_summary
|
||||
EXTRA_DIST = arc_summary3
|
||||
EXTRA_DIST = arc_summary2 arc_summary3
|
||||
|
||||
if USING_PYTHON_2
|
||||
SCRIPT = arc_summary2
|
||||
else
|
||||
SCRIPT = arc_summary3
|
||||
endif
|
||||
|
||||
arc_summary: $(SCRIPT)
|
||||
cp $< $@
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,13 +42,6 @@ import os
|
|||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import errno
|
||||
|
||||
# We can't use env -S portably, and we need python3 -u to handle pipes in
|
||||
# the shell abruptly closing the way we want to, so...
|
||||
import io
|
||||
if isinstance(sys.__stderr__.buffer, io.BufferedWriter):
|
||||
os.execv(sys.executable, [sys.executable, "-u"] + sys.argv)
|
||||
|
||||
DESCRIPTION = 'Print ARC and other statistics for OpenZFS'
|
||||
INDENT = ' '*8
|
||||
|
@ -191,13 +184,21 @@ elif sys.platform.startswith('linux'):
|
|||
# there, so we fall back on modinfo
|
||||
command = ["/sbin/modinfo", request, "-0"]
|
||||
|
||||
# The recommended way to do this is with subprocess.run(). However,
|
||||
# some installed versions of Python are < 3.5, so we offer them
|
||||
# the option of doing it the old way (for now)
|
||||
info = ''
|
||||
|
||||
try:
|
||||
|
||||
info = subprocess.run(command, stdout=subprocess.PIPE,
|
||||
check=True, universal_newlines=True)
|
||||
raw_output = info.stdout.split('\0')
|
||||
if 'run' in dir(subprocess):
|
||||
info = subprocess.run(command, stdout=subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
raw_output = info.stdout.split('\0')
|
||||
else:
|
||||
info = subprocess.check_output(command,
|
||||
universal_newlines=True)
|
||||
raw_output = info.split('\0')
|
||||
|
||||
except subprocess.CalledProcessError:
|
||||
print("Error: Descriptions not available",
|
||||
|
@ -220,29 +221,6 @@ elif sys.platform.startswith('linux'):
|
|||
|
||||
return descs
|
||||
|
||||
def handle_unraisableException(exc_type, exc_value=None, exc_traceback=None,
|
||||
err_msg=None, object=None):
|
||||
handle_Exception(exc_type, object, exc_traceback)
|
||||
|
||||
def handle_Exception(ex_cls, ex, tb):
|
||||
if ex_cls is KeyboardInterrupt:
|
||||
sys.exit()
|
||||
|
||||
if ex_cls is BrokenPipeError:
|
||||
# It turns out that while sys.exit() triggers an exception
|
||||
# not handled message on Python 3.8+, os._exit() does not.
|
||||
os._exit(0)
|
||||
|
||||
if ex_cls is OSError:
|
||||
if ex.errno == errno.ENOTCONN:
|
||||
sys.exit()
|
||||
|
||||
raise ex
|
||||
|
||||
if hasattr(sys,'unraisablehook'): # Python 3.8+
|
||||
sys.unraisablehook = handle_unraisableException
|
||||
sys.excepthook = handle_Exception
|
||||
|
||||
|
||||
def cleanup_line(single_line):
|
||||
"""Format a raw line of data from /proc and isolate the name value
|
||||
|
@ -678,9 +656,9 @@ def section_archits(kstats_dict):
|
|||
print()
|
||||
print('Cache hits by data type:')
|
||||
dt_todo = (('Demand data:', arc_stats['demand_data_hits']),
|
||||
('Prefetch data:', arc_stats['prefetch_data_hits']),
|
||||
('Demand prefetch data:', arc_stats['prefetch_data_hits']),
|
||||
('Demand metadata:', arc_stats['demand_metadata_hits']),
|
||||
('Prefetch metadata:',
|
||||
('Demand prefetch metadata:',
|
||||
arc_stats['prefetch_metadata_hits']))
|
||||
|
||||
for title, value in dt_todo:
|
||||
|
@ -689,10 +667,10 @@ def section_archits(kstats_dict):
|
|||
print()
|
||||
print('Cache misses by data type:')
|
||||
dm_todo = (('Demand data:', arc_stats['demand_data_misses']),
|
||||
('Prefetch data:',
|
||||
('Demand prefetch data:',
|
||||
arc_stats['prefetch_data_misses']),
|
||||
('Demand metadata:', arc_stats['demand_metadata_misses']),
|
||||
('Prefetch metadata:',
|
||||
('Demand prefetch metadata:',
|
||||
arc_stats['prefetch_metadata_misses']))
|
||||
|
||||
for title, value in dm_todo:
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
# @hdr is the array of fields that needs to be printed, so we
|
||||
# just iterate over this array and print the values using our pretty printer.
|
||||
#
|
||||
# This script must remain compatible with Python 3.6+.
|
||||
# This script must remain compatible with Python 2.6+ and Python 3.4+.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
@ -271,7 +271,7 @@ def print_values():
|
|||
if pretty_print:
|
||||
fmt = lambda col: prettynum(cols[col][0], cols[col][1], v[col])
|
||||
else:
|
||||
fmt = lambda col: str(v[col])
|
||||
fmt = lambda col: v[col]
|
||||
|
||||
sys.stdout.write(sep.join(fmt(col) for col in hdr))
|
||||
sys.stdout.write("\n")
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
# Copyright (C) 2013 Lawrence Livermore National Security, LLC.
|
||||
# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
||||
#
|
||||
# This script must remain compatible with and Python 3.6+.
|
||||
# This script must remain compatible with Python 2.6+ and Python 3.4+.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
include $(top_srcdir)/config/Substfiles.am
|
||||
include $(top_srcdir)/config/Shellcheck.am
|
||||
|
||||
dist_sbin_SCRIPTS = fsck.zfs
|
||||
|
||||
|
|
|
@ -26,15 +26,15 @@ for dataset in "$@"; do
|
|||
|
||||
case "$(@sbindir@/zpool list -Ho health "$pool")" in
|
||||
DEGRADED)
|
||||
ret=$(( ret | 4 ))
|
||||
ret=$(( $ret | 4 ))
|
||||
;;
|
||||
FAULTED)
|
||||
awk '!/^([[:space:]]*#.*)?$/ && $1 == "'"$dataset"'" && $3 == "zfs" {exit 1}' /etc/fstab || \
|
||||
ret=$(( ret | 8 ))
|
||||
ret=$(( $ret | 8 ))
|
||||
;;
|
||||
"")
|
||||
# Pool not found, error printed by zpool(8)
|
||||
ret=$(( ret | 8 ))
|
||||
ret=$(( $ret | 8 ))
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
|
|
|
@ -185,11 +185,10 @@ main(int argc, char **argv)
|
|||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
if (optopt)
|
||||
(void) fprintf(stderr,
|
||||
gettext("Invalid option '%c'\n"), optopt);
|
||||
(void) fprintf(stderr, gettext("Invalid option '%c'\n"),
|
||||
optopt);
|
||||
(void) fprintf(stderr, gettext("Usage: mount.zfs "
|
||||
"[-sfnvh] [-o options] <dataset> <mountpoint>\n"));
|
||||
"[-sfnv] [-o options] <dataset> <mountpoint>\n"));
|
||||
return (MOUNT_USAGE);
|
||||
}
|
||||
}
|
||||
|
@ -246,6 +245,13 @@ main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
(void) fprintf(stdout, gettext("mount.zfs:\n"
|
||||
" dataset: \"%s\"\n mountpoint: \"%s\"\n"
|
||||
" mountflags: 0x%lx\n zfsflags: 0x%lx\n"
|
||||
" mountopts: \"%s\"\n mtabopts: \"%s\"\n"),
|
||||
dataset, mntpoint, mntflags, zfsflags, mntopts, mtabopt);
|
||||
|
||||
if (mntflags & MS_REMOUNT) {
|
||||
nomtab = 1;
|
||||
remount = 1;
|
||||
|
@ -268,10 +274,7 @@ main(int argc, char **argv)
|
|||
return (MOUNT_USAGE);
|
||||
}
|
||||
|
||||
if (!zfsutil || sloppy ||
|
||||
libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) {
|
||||
zfs_adjust_mount_options(zhp, mntpoint, mntopts, mtabopt);
|
||||
}
|
||||
zfs_adjust_mount_options(zhp, mntpoint, mntopts, mtabopt);
|
||||
|
||||
/* treat all snapshots as legacy mount points */
|
||||
if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT)
|
||||
|
@ -289,11 +292,12 @@ main(int argc, char **argv)
|
|||
if (zfs_version == 0) {
|
||||
fprintf(stderr, gettext("unable to fetch "
|
||||
"ZFS version for filesystem '%s'\n"), dataset);
|
||||
zfs_close(zhp);
|
||||
libzfs_fini(g_zfs);
|
||||
return (MOUNT_SYSERR);
|
||||
}
|
||||
|
||||
zfs_close(zhp);
|
||||
libzfs_fini(g_zfs);
|
||||
|
||||
/*
|
||||
* Legacy mount points may only be mounted using 'mount', never using
|
||||
* 'zfs mount'. However, since 'zfs mount' actually invokes 'mount'
|
||||
|
@ -311,8 +315,6 @@ main(int argc, char **argv)
|
|||
"Use 'zfs set mountpoint=%s' or 'mount -t zfs %s %s'.\n"
|
||||
"See zfs(8) for more information.\n"),
|
||||
dataset, mntpoint, dataset, mntpoint);
|
||||
zfs_close(zhp);
|
||||
libzfs_fini(g_zfs);
|
||||
return (MOUNT_USAGE);
|
||||
}
|
||||
|
||||
|
@ -323,38 +325,14 @@ main(int argc, char **argv)
|
|||
"Use 'zfs set mountpoint=%s' or 'zfs mount %s'.\n"
|
||||
"See zfs(8) for more information.\n"),
|
||||
dataset, "legacy", dataset);
|
||||
zfs_close(zhp);
|
||||
libzfs_fini(g_zfs);
|
||||
return (MOUNT_USAGE);
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
(void) fprintf(stdout, gettext("mount.zfs:\n"
|
||||
" dataset: \"%s\"\n mountpoint: \"%s\"\n"
|
||||
" mountflags: 0x%lx\n zfsflags: 0x%lx\n"
|
||||
" mountopts: \"%s\"\n mtabopts: \"%s\"\n"),
|
||||
dataset, mntpoint, mntflags, zfsflags, mntopts, mtabopt);
|
||||
|
||||
if (!fake) {
|
||||
if (zfsutil && !sloppy &&
|
||||
!libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) {
|
||||
error = zfs_mount_at(zhp, mntopts, mntflags, mntpoint);
|
||||
if (error) {
|
||||
(void) fprintf(stderr, "zfs_mount_at() failed: "
|
||||
"%s", libzfs_error_description(g_zfs));
|
||||
zfs_close(zhp);
|
||||
libzfs_fini(g_zfs);
|
||||
return (MOUNT_SYSERR);
|
||||
}
|
||||
} else {
|
||||
error = mount(dataset, mntpoint, MNTTYPE_ZFS,
|
||||
mntflags, mntopts);
|
||||
}
|
||||
error = mount(dataset, mntpoint, MNTTYPE_ZFS,
|
||||
mntflags, mntopts);
|
||||
}
|
||||
|
||||
zfs_close(zhp);
|
||||
libzfs_fini(g_zfs);
|
||||
|
||||
if (error) {
|
||||
switch (errno) {
|
||||
case ENOENT:
|
||||
|
@ -389,7 +367,7 @@ main(int argc, char **argv)
|
|||
"mount the filesystem again.\n"), dataset);
|
||||
return (MOUNT_SYSERR);
|
||||
}
|
||||
fallthrough;
|
||||
/* fallthru */
|
||||
#endif
|
||||
default:
|
||||
(void) fprintf(stderr, gettext("filesystem "
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
include $(top_srcdir)/config/Shellcheck.am
|
||||
|
||||
dist_udev_SCRIPTS = vdev_id
|
||||
|
|
|
@ -140,8 +140,7 @@ Usage: vdev_id [-h]
|
|||
-p number of phy's per switch port [default=$PHYS_PER_PORT]
|
||||
-h show this summary
|
||||
EOF
|
||||
exit 1
|
||||
# exit with error to avoid processing usage message by a udev rule
|
||||
exit 0
|
||||
}
|
||||
|
||||
map_slot() {
|
||||
|
@ -375,7 +374,7 @@ sas_handler() {
|
|||
i=$((i + 1))
|
||||
done
|
||||
|
||||
PHY=$(ls -vd "$port_dir"/phy* 2>/dev/null | head -1 | awk -F: '{print $NF}')
|
||||
PHY=$(ls -d "$port_dir"/phy* 2>/dev/null | head -1 | awk -F: '{print $NF}')
|
||||
if [ -z "$PHY" ] ; then
|
||||
PHY=0
|
||||
fi
|
||||
|
@ -596,9 +595,7 @@ enclosure_handler () {
|
|||
# DEVPATH=/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0/host0/subsystem/devices/0:0:0:0/scsi_generic/sg0
|
||||
|
||||
# Get the enclosure ID ("0:0:0:0")
|
||||
ENC="${DEVPATH%/*}"
|
||||
ENC="${ENC%/*}"
|
||||
ENC="${ENC##*/}"
|
||||
ENC=$(basename $(readlink -m "/sys/$DEVPATH/../.."))
|
||||
if [ ! -d "/sys/class/enclosure/$ENC" ] ; then
|
||||
# Not an enclosure, bail out
|
||||
return
|
||||
|
@ -618,15 +615,14 @@ enclosure_handler () {
|
|||
|
||||
# The PCI directory is two directories up from the port directory
|
||||
# /sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0
|
||||
PCI_ID_LONG="$(readlink -m "/sys/$PORT_DIR/../..")"
|
||||
PCI_ID_LONG="${PCI_ID_LONG##*/}"
|
||||
PCI_ID_LONG=$(basename $(readlink -m "/sys/$PORT_DIR/../.."))
|
||||
|
||||
# Strip down the PCI address from 0000:05:00.0 to 05:00.0
|
||||
PCI_ID="${PCI_ID_LONG#[0-9]*:}"
|
||||
PCI_ID=$(echo "$PCI_ID_LONG" | sed -r 's/^[0-9]+://g')
|
||||
|
||||
# Name our device according to vdev_id.conf (like "L0" or "U1").
|
||||
NAME=$(awk "/channel/{if (\$1 == \"channel\" && \$2 == \"$PCI_ID\" && \
|
||||
\$3 == \"$PORT_ID\") {print \$4\$3}}" $CONFIG)
|
||||
NAME=$(awk '/channel/{if ($1 == "channel" && $2 == "$PCI_ID" && \
|
||||
$3 == "$PORT_ID") {print ${4}int(count[$4])}; count[$4]++}' $CONFIG)
|
||||
|
||||
echo "${NAME}"
|
||||
}
|
||||
|
@ -677,7 +673,7 @@ alias_handler () {
|
|||
link=$(echo "$link" | sed 's/p[0-9][0-9]*$//')
|
||||
fi
|
||||
# Check both the fully qualified and the base name of link.
|
||||
for l in $link ${link##*/} ; do
|
||||
for l in $link $(basename "$link") ; do
|
||||
if [ ! -z "$l" ]; then
|
||||
alias=$(awk -v var="$l" '($1 == "alias") && \
|
||||
($3 == var) \
|
||||
|
@ -732,7 +728,7 @@ done
|
|||
|
||||
if [ ! -r "$CONFIG" ] ; then
|
||||
echo "Error: Config file \"$CONFIG\" not found"
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "$DEV" ] && [ -z "$ENCLOSURE_MODE" ] ; then
|
||||
|
|
268
cmd/zdb/zdb.c
268
cmd/zdb/zdb.c
|
@ -110,9 +110,8 @@ extern int zfs_recover;
|
|||
extern unsigned long zfs_arc_meta_min, zfs_arc_meta_limit;
|
||||
extern int zfs_vdev_async_read_max_active;
|
||||
extern boolean_t spa_load_verify_dryrun;
|
||||
extern boolean_t spa_mode_readable_spacemaps;
|
||||
extern int zfs_reconstruct_indirect_combinations_max;
|
||||
extern uint_t zfs_btree_verify_intensity;
|
||||
extern int zfs_btree_verify_intensity;
|
||||
|
||||
static const char cmdname[] = "zdb";
|
||||
uint8_t dump_opt[256];
|
||||
|
@ -163,6 +162,12 @@ static int dump_bpobj_cb(void *arg, const blkptr_t *bp, boolean_t free,
|
|||
dmu_tx_t *tx);
|
||||
|
||||
typedef struct sublivelist_verify {
|
||||
/* all ALLOC'd blkptr_t in one sub-livelist */
|
||||
zfs_btree_t sv_all_allocs;
|
||||
|
||||
/* all FREE'd blkptr_t in one sub-livelist */
|
||||
zfs_btree_t sv_all_frees;
|
||||
|
||||
/* FREE's that haven't yet matched to an ALLOC, in one sub-livelist */
|
||||
zfs_btree_t sv_pair;
|
||||
|
||||
|
@ -221,68 +226,29 @@ typedef struct sublivelist_verify_block {
|
|||
|
||||
static void zdb_print_blkptr(const blkptr_t *bp, int flags);
|
||||
|
||||
typedef struct sublivelist_verify_block_refcnt {
|
||||
/* block pointer entry in livelist being verified */
|
||||
blkptr_t svbr_blk;
|
||||
|
||||
/*
|
||||
* Refcount gets incremented to 1 when we encounter the first
|
||||
* FREE entry for the svfbr block pointer and a node for it
|
||||
* is created in our ZDB verification/tracking metadata.
|
||||
*
|
||||
* As we encounter more FREE entries we increment this counter
|
||||
* and similarly decrement it whenever we find the respective
|
||||
* ALLOC entries for this block.
|
||||
*
|
||||
* When the refcount gets to 0 it means that all the FREE and
|
||||
* ALLOC entries of this block have paired up and we no longer
|
||||
* need to track it in our verification logic (e.g. the node
|
||||
* containing this struct in our verification data structure
|
||||
* should be freed).
|
||||
*
|
||||
* [refer to sublivelist_verify_blkptr() for the actual code]
|
||||
*/
|
||||
uint32_t svbr_refcnt;
|
||||
} sublivelist_verify_block_refcnt_t;
|
||||
|
||||
static int
|
||||
sublivelist_block_refcnt_compare(const void *larg, const void *rarg)
|
||||
{
|
||||
const sublivelist_verify_block_refcnt_t *l = larg;
|
||||
const sublivelist_verify_block_refcnt_t *r = rarg;
|
||||
return (livelist_compare(&l->svbr_blk, &r->svbr_blk));
|
||||
}
|
||||
|
||||
static int
|
||||
sublivelist_verify_blkptr(void *arg, const blkptr_t *bp, boolean_t free,
|
||||
dmu_tx_t *tx)
|
||||
{
|
||||
ASSERT3P(tx, ==, NULL);
|
||||
struct sublivelist_verify *sv = arg;
|
||||
sublivelist_verify_block_refcnt_t current = {
|
||||
.svbr_blk = *bp,
|
||||
|
||||
/*
|
||||
* Start with 1 in case this is the first free entry.
|
||||
* This field is not used for our B-Tree comparisons
|
||||
* anyway.
|
||||
*/
|
||||
.svbr_refcnt = 1,
|
||||
};
|
||||
|
||||
char blkbuf[BP_SPRINTF_LEN];
|
||||
zfs_btree_index_t where;
|
||||
sublivelist_verify_block_refcnt_t *pair =
|
||||
zfs_btree_find(&sv->sv_pair, ¤t, &where);
|
||||
if (free) {
|
||||
if (pair == NULL) {
|
||||
/* first free entry for this block pointer */
|
||||
zfs_btree_add(&sv->sv_pair, ¤t);
|
||||
zfs_btree_add(&sv->sv_pair, bp);
|
||||
/* Check if the FREE is a duplicate */
|
||||
if (zfs_btree_find(&sv->sv_all_frees, bp, &where) != NULL) {
|
||||
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp,
|
||||
free);
|
||||
(void) printf("\tERROR: Duplicate FREE: %s\n", blkbuf);
|
||||
} else {
|
||||
pair->svbr_refcnt++;
|
||||
zfs_btree_add_idx(&sv->sv_all_frees, bp, &where);
|
||||
}
|
||||
} else {
|
||||
if (pair == NULL) {
|
||||
/* block that is currently marked as allocated */
|
||||
/* Check if the ALLOC has been freed */
|
||||
if (zfs_btree_find(&sv->sv_pair, bp, &where) != NULL) {
|
||||
zfs_btree_remove_idx(&sv->sv_pair, &where);
|
||||
} else {
|
||||
for (int i = 0; i < SPA_DVAS_PER_BP; i++) {
|
||||
if (DVA_IS_EMPTY(&bp->blk_dva[i]))
|
||||
break;
|
||||
|
@ -297,16 +263,16 @@ sublivelist_verify_blkptr(void *arg, const blkptr_t *bp, boolean_t free,
|
|||
&svb, &where);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check if the ALLOC is a duplicate */
|
||||
if (zfs_btree_find(&sv->sv_all_allocs, bp, &where) != NULL) {
|
||||
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp,
|
||||
free);
|
||||
(void) printf("\tERROR: Duplicate ALLOC: %s\n", blkbuf);
|
||||
} else {
|
||||
/* alloc matches a free entry */
|
||||
pair->svbr_refcnt--;
|
||||
if (pair->svbr_refcnt == 0) {
|
||||
/* all allocs and frees have been matched */
|
||||
zfs_btree_remove_idx(&sv->sv_pair, &where);
|
||||
}
|
||||
zfs_btree_add_idx(&sv->sv_all_allocs, bp, &where);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -314,22 +280,32 @@ static int
|
|||
sublivelist_verify_func(void *args, dsl_deadlist_entry_t *dle)
|
||||
{
|
||||
int err;
|
||||
char blkbuf[BP_SPRINTF_LEN];
|
||||
struct sublivelist_verify *sv = args;
|
||||
|
||||
zfs_btree_create(&sv->sv_pair, sublivelist_block_refcnt_compare,
|
||||
sizeof (sublivelist_verify_block_refcnt_t));
|
||||
zfs_btree_create(&sv->sv_all_allocs, livelist_compare,
|
||||
sizeof (blkptr_t));
|
||||
|
||||
zfs_btree_create(&sv->sv_all_frees, livelist_compare,
|
||||
sizeof (blkptr_t));
|
||||
|
||||
zfs_btree_create(&sv->sv_pair, livelist_compare,
|
||||
sizeof (blkptr_t));
|
||||
|
||||
err = bpobj_iterate_nofree(&dle->dle_bpobj, sublivelist_verify_blkptr,
|
||||
sv, NULL);
|
||||
|
||||
sublivelist_verify_block_refcnt_t *e;
|
||||
zfs_btree_clear(&sv->sv_all_allocs);
|
||||
zfs_btree_destroy(&sv->sv_all_allocs);
|
||||
|
||||
zfs_btree_clear(&sv->sv_all_frees);
|
||||
zfs_btree_destroy(&sv->sv_all_frees);
|
||||
|
||||
blkptr_t *e;
|
||||
zfs_btree_index_t *cookie = NULL;
|
||||
while ((e = zfs_btree_destroy_nodes(&sv->sv_pair, &cookie)) != NULL) {
|
||||
char blkbuf[BP_SPRINTF_LEN];
|
||||
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf),
|
||||
&e->svbr_blk, B_TRUE);
|
||||
(void) printf("\tERROR: %d unmatched FREE(s): %s\n",
|
||||
e->svbr_refcnt, blkbuf);
|
||||
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), e, B_TRUE);
|
||||
(void) printf("\tERROR: Unmatched FREE: %s\n", blkbuf);
|
||||
}
|
||||
zfs_btree_destroy(&sv->sv_pair);
|
||||
|
||||
|
@ -638,14 +614,10 @@ mv_populate_livelist_allocs(metaslab_verify_t *mv, sublivelist_verify_t *sv)
|
|||
/*
|
||||
* [Livelist Check]
|
||||
* Iterate through all the sublivelists and:
|
||||
* - report leftover frees (**)
|
||||
* - report leftover frees
|
||||
* - report double ALLOCs/FREEs
|
||||
* - record leftover ALLOCs together with their TXG [see Cross Check]
|
||||
*
|
||||
* (**) Note: Double ALLOCs are valid in datasets that have dedup
|
||||
* enabled. Similarly double FREEs are allowed as well but
|
||||
* only if they pair up with a corresponding ALLOC entry once
|
||||
* we our done with our sublivelist iteration.
|
||||
*
|
||||
* [Spacemap Check]
|
||||
* for each metaslab:
|
||||
* - iterate over spacemap and then the metaslab's entries in the
|
||||
|
@ -2219,8 +2191,7 @@ snprintf_zstd_header(spa_t *spa, char *blkbuf, size_t buflen,
|
|||
(void) snprintf(blkbuf + strlen(blkbuf),
|
||||
buflen - strlen(blkbuf),
|
||||
" ZSTD:size=%u:version=%u:level=%u:EMBEDDED",
|
||||
zstd_hdr.c_len, zfs_get_hdrversion(&zstd_hdr),
|
||||
zfs_get_hdrlevel(&zstd_hdr));
|
||||
zstd_hdr.c_len, zstd_hdr.version, zstd_hdr.level);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2244,8 +2215,7 @@ snprintf_zstd_header(spa_t *spa, char *blkbuf, size_t buflen,
|
|||
(void) snprintf(blkbuf + strlen(blkbuf),
|
||||
buflen - strlen(blkbuf),
|
||||
" ZSTD:size=%u:version=%u:level=%u:NORMAL",
|
||||
zstd_hdr.c_len, zfs_get_hdrversion(&zstd_hdr),
|
||||
zfs_get_hdrlevel(&zstd_hdr));
|
||||
zstd_hdr.c_len, zstd_hdr.version, zstd_hdr.level);
|
||||
|
||||
abd_return_buf_copy(pabd, buf, BP_GET_LSIZE(bp));
|
||||
}
|
||||
|
@ -2995,7 +2965,7 @@ open_objset(const char *path, void *tag, objset_t **osp)
|
|||
}
|
||||
sa_os = *osp;
|
||||
|
||||
return (err);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3102,22 +3072,13 @@ dump_znode_sa_xattr(sa_handle_t *hdl)
|
|||
(void) printf("\tSA xattrs: %d bytes, %d entries\n\n",
|
||||
sa_xattr_size, sa_xattr_entries);
|
||||
while ((elem = nvlist_next_nvpair(sa_xattr, elem)) != NULL) {
|
||||
boolean_t can_print = !dump_opt['P'];
|
||||
uchar_t *value;
|
||||
uint_t cnt, idx;
|
||||
|
||||
(void) printf("\t\t%s = ", nvpair_name(elem));
|
||||
nvpair_value_byte_array(elem, &value, &cnt);
|
||||
|
||||
for (idx = 0; idx < cnt; ++idx) {
|
||||
if (!isprint(value[idx])) {
|
||||
can_print = B_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; idx < cnt; ++idx) {
|
||||
if (can_print)
|
||||
if (isprint(value[idx]))
|
||||
(void) putchar(value[idx]);
|
||||
else
|
||||
(void) printf("\\%3.3o", value[idx]);
|
||||
|
@ -3134,18 +3095,13 @@ dump_znode_symlink(sa_handle_t *hdl)
|
|||
{
|
||||
int sa_symlink_size = 0;
|
||||
char linktarget[MAXPATHLEN];
|
||||
linktarget[0] = '\0';
|
||||
int error;
|
||||
|
||||
error = sa_size(hdl, sa_attr_table[ZPL_SYMLINK], &sa_symlink_size);
|
||||
if (error || sa_symlink_size == 0) {
|
||||
return;
|
||||
}
|
||||
if (sa_symlink_size >= sizeof (linktarget)) {
|
||||
(void) printf("symlink size %d is too large\n",
|
||||
sa_symlink_size);
|
||||
return;
|
||||
}
|
||||
linktarget[sa_symlink_size] = '\0';
|
||||
if (sa_lookup(hdl, sa_attr_table[ZPL_SYMLINK],
|
||||
&linktarget, sa_symlink_size) == 0)
|
||||
(void) printf("\ttarget %s\n", linktarget);
|
||||
|
@ -4111,7 +4067,7 @@ cksum_record_compare(const void *x1, const void *x2)
|
|||
const cksum_record_t *l = (cksum_record_t *)x1;
|
||||
const cksum_record_t *r = (cksum_record_t *)x2;
|
||||
int arraysize = ARRAY_SIZE(l->cksum.zc_word);
|
||||
int difference = 0;
|
||||
int difference;
|
||||
|
||||
for (int i = 0; i < arraysize; i++) {
|
||||
difference = TREE_CMP(l->cksum.zc_word[i], r->cksum.zc_word[i]);
|
||||
|
@ -4588,7 +4544,7 @@ dump_path_impl(objset_t *os, uint64_t obj, char *name, uint64_t *retobj)
|
|||
case DMU_OT_DIRECTORY_CONTENTS:
|
||||
if (s != NULL && *(s + 1) != '\0')
|
||||
return (dump_path_impl(os, child_obj, s + 1, retobj));
|
||||
fallthrough;
|
||||
/*FALLTHROUGH*/
|
||||
case DMU_OT_PLAIN_FILE_CONTENTS:
|
||||
if (retobj != NULL) {
|
||||
*retobj = child_obj;
|
||||
|
@ -4815,7 +4771,7 @@ dump_label(const char *dev)
|
|||
if (nvlist_size(config, &size, NV_ENCODE_XDR) != 0)
|
||||
size = buflen;
|
||||
|
||||
/* If the device is a cache device read the header. */
|
||||
/* If the device is a cache device clear the header. */
|
||||
if (!read_l2arc_header) {
|
||||
if (nvlist_lookup_uint64(config,
|
||||
ZPOOL_CONFIG_POOL_STATE, &l2cache) == 0 &&
|
||||
|
@ -8281,23 +8237,6 @@ zdb_embedded_block(char *thing)
|
|||
free(buf);
|
||||
}
|
||||
|
||||
/* check for valid hex or decimal numeric string */
|
||||
static boolean_t
|
||||
zdb_numeric(char *str)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (strlen(str) == 0)
|
||||
return (B_FALSE);
|
||||
if (strncmp(str, "0x", 2) == 0 || strncmp(str, "0X", 2) == 0)
|
||||
i = 2;
|
||||
for (; i < strlen(str); i++) {
|
||||
if (!isxdigit(str[i]))
|
||||
return (B_FALSE);
|
||||
}
|
||||
return (B_TRUE);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
@ -8343,7 +8282,7 @@ main(int argc, char **argv)
|
|||
zfs_btree_verify_intensity = 3;
|
||||
|
||||
while ((c = getopt(argc, argv,
|
||||
"AbcCdDeEFGhiI:klLmMNo:Op:PqrRsSt:uU:vVx:XYyZ")) != -1) {
|
||||
"AbcCdDeEFGhiI:klLmMo:Op:PqrRsSt:uU:vVx:XYyZ")) != -1) {
|
||||
switch (c) {
|
||||
case 'b':
|
||||
case 'c':
|
||||
|
@ -8357,7 +8296,6 @@ main(int argc, char **argv)
|
|||
case 'l':
|
||||
case 'm':
|
||||
case 'M':
|
||||
case 'N':
|
||||
case 'O':
|
||||
case 'r':
|
||||
case 'R':
|
||||
|
@ -8449,6 +8387,31 @@ main(int argc, char **argv)
|
|||
(void) fprintf(stderr, "-p option requires use of -e\n");
|
||||
usage();
|
||||
}
|
||||
if (dump_opt['d'] || dump_opt['r']) {
|
||||
/* <pool>[/<dataset | objset id> is accepted */
|
||||
if (argv[2] && (objset_str = strchr(argv[2], '/')) != NULL &&
|
||||
objset_str++ != NULL) {
|
||||
char *endptr;
|
||||
errno = 0;
|
||||
objset_id = strtoull(objset_str, &endptr, 0);
|
||||
/* dataset 0 is the same as opening the pool */
|
||||
if (errno == 0 && endptr != objset_str &&
|
||||
objset_id != 0) {
|
||||
target_is_spa = B_FALSE;
|
||||
dataset_lookup = B_TRUE;
|
||||
} else if (objset_id != 0) {
|
||||
printf("failed to open objset %s "
|
||||
"%llu %s", objset_str,
|
||||
(u_longlong_t)objset_id,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
/* normal dataset name not an objset ID */
|
||||
if (endptr == objset_str) {
|
||||
objset_id = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_LP64)
|
||||
/*
|
||||
|
@ -8477,18 +8440,13 @@ main(int argc, char **argv)
|
|||
*/
|
||||
spa_load_verify_dryrun = B_TRUE;
|
||||
|
||||
/*
|
||||
* ZDB should have ability to read spacemaps.
|
||||
*/
|
||||
spa_mode_readable_spacemaps = B_TRUE;
|
||||
|
||||
kernel_init(SPA_MODE_READ);
|
||||
|
||||
if (dump_all)
|
||||
verbose = MAX(verbose, 1);
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
if (dump_all && strchr("AeEFklLNOPrRSXy", c) == NULL)
|
||||
if (dump_all && strchr("AeEFklLOPrRSXy", c) == NULL)
|
||||
dump_opt[c] = 1;
|
||||
if (dump_opt[c])
|
||||
dump_opt[c] += verbose;
|
||||
|
@ -8527,7 +8485,6 @@ main(int argc, char **argv)
|
|||
return (dump_path(argv[0], argv[1], NULL));
|
||||
}
|
||||
if (dump_opt['r']) {
|
||||
target_is_spa = B_FALSE;
|
||||
if (argc != 3)
|
||||
usage();
|
||||
dump_opt['v'] = verbose;
|
||||
|
@ -8538,10 +8495,6 @@ main(int argc, char **argv)
|
|||
rewind = ZPOOL_DO_REWIND |
|
||||
(dump_opt['X'] ? ZPOOL_EXTREME_REWIND : 0);
|
||||
|
||||
/* -N implies -d */
|
||||
if (dump_opt['N'] && dump_opt['d'] == 0)
|
||||
dump_opt['d'] = dump_opt['N'];
|
||||
|
||||
if (nvlist_alloc(&policy, NV_UNIQUE_NAME_TYPE, 0) != 0 ||
|
||||
nvlist_add_uint64(policy, ZPOOL_LOAD_REQUEST_TXG, max_txg) != 0 ||
|
||||
nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY, rewind) != 0)
|
||||
|
@ -8560,34 +8513,6 @@ main(int argc, char **argv)
|
|||
targetlen = strlen(target);
|
||||
if (targetlen && target[targetlen - 1] == '/')
|
||||
target[targetlen - 1] = '\0';
|
||||
/*
|
||||
* See if an objset ID was supplied (-d <pool>/<objset ID>).
|
||||
* To disambiguate tank/100, consider the 100 as objsetID
|
||||
* if -N was given, otherwise 100 is an objsetID iff
|
||||
* tank/100 as a named dataset fails on lookup.
|
||||
*/
|
||||
objset_str = strchr(target, '/');
|
||||
if (objset_str && strlen(objset_str) > 1 &&
|
||||
zdb_numeric(objset_str + 1)) {
|
||||
char *endptr;
|
||||
errno = 0;
|
||||
objset_str++;
|
||||
objset_id = strtoull(objset_str, &endptr, 0);
|
||||
/* dataset 0 is the same as opening the pool */
|
||||
if (errno == 0 && endptr != objset_str &&
|
||||
objset_id != 0) {
|
||||
if (dump_opt['N'])
|
||||
dataset_lookup = B_TRUE;
|
||||
}
|
||||
/* normal dataset name not an objset ID */
|
||||
if (endptr == objset_str) {
|
||||
objset_id = -1;
|
||||
}
|
||||
} else if (objset_str && !zdb_numeric(objset_str + 1) &&
|
||||
dump_opt['N']) {
|
||||
printf("Supply a numeric objset ID with -N\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
target_pool = target;
|
||||
}
|
||||
|
@ -8705,27 +8630,13 @@ main(int argc, char **argv)
|
|||
}
|
||||
return (error);
|
||||
} else {
|
||||
target_pool = strdup(target);
|
||||
if (strpbrk(target, "/@") != NULL)
|
||||
*strpbrk(target_pool, "/@") = '\0';
|
||||
|
||||
zdb_set_skip_mmp(target);
|
||||
/*
|
||||
* If -N was supplied, the user has indicated that
|
||||
* zdb -d <pool>/<objsetID> is in effect. Otherwise
|
||||
* we first assume that the dataset string is the
|
||||
* dataset name. If dmu_objset_hold fails with the
|
||||
* dataset string, and we have an objset_id, retry the
|
||||
* lookup with the objsetID.
|
||||
*/
|
||||
boolean_t retry = B_TRUE;
|
||||
retry_lookup:
|
||||
if (dataset_lookup == B_TRUE) {
|
||||
/*
|
||||
* Use the supplied id to get the name
|
||||
* for open_objset.
|
||||
*/
|
||||
error = spa_open(target_pool, &spa, FTAG);
|
||||
error = spa_open(target, &spa, FTAG);
|
||||
if (error == 0) {
|
||||
error = name_from_objset_id(spa,
|
||||
objset_id, dsname);
|
||||
|
@ -8734,23 +8645,10 @@ retry_lookup:
|
|||
target = dsname;
|
||||
}
|
||||
}
|
||||
if (error == 0) {
|
||||
if (objset_id > 0 && retry) {
|
||||
int err = dmu_objset_hold(target, FTAG,
|
||||
&os);
|
||||
if (err) {
|
||||
dataset_lookup = B_TRUE;
|
||||
retry = B_FALSE;
|
||||
goto retry_lookup;
|
||||
} else {
|
||||
dmu_objset_rele(os, FTAG);
|
||||
}
|
||||
}
|
||||
if (error == 0)
|
||||
error = open_objset(target, FTAG, &os);
|
||||
}
|
||||
if (error == 0)
|
||||
spa = dmu_objset_spa(os);
|
||||
free(target_pool);
|
||||
}
|
||||
}
|
||||
nvlist_free(policy);
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
include $(top_srcdir)/config/Rules.am
|
||||
include $(top_srcdir)/config/Shellcheck.am
|
||||
|
||||
AM_CFLAGS += $(LIBUDEV_CFLAGS) $(LIBUUID_CFLAGS)
|
||||
|
||||
SUBDIRS = zed.d
|
||||
SHELLCHECKDIRS = $(SUBDIRS)
|
||||
|
||||
sbin_PROGRAMS = zed
|
||||
|
||||
|
@ -45,7 +43,7 @@ zed_LDADD = \
|
|||
$(abs_top_builddir)/lib/libnvpair/libnvpair.la \
|
||||
$(abs_top_builddir)/lib/libuutil/libuutil.la
|
||||
|
||||
zed_LDADD += -lrt $(LIBATOMIC_LIBS) $(LIBUDEV_LIBS) $(LIBUUID_LIBS)
|
||||
zed_LDADD += -lrt $(LIBUDEV_LIBS) $(LIBUUID_LIBS)
|
||||
zed_LDFLAGS = -pthread
|
||||
|
||||
EXTRA_DIST = agents/README.md
|
||||
|
|
|
@ -599,7 +599,6 @@ fmd_timer_install(fmd_hdl_t *hdl, void *arg, fmd_event_t *ep, hrtime_t delta)
|
|||
sev.sigev_notify_function = _timer_notify;
|
||||
sev.sigev_notify_attributes = NULL;
|
||||
sev.sigev_value.sival_ptr = ftp;
|
||||
sev.sigev_signo = 0;
|
||||
|
||||
timer_create(CLOCK_REALTIME, &sev, &ftp->ft_tid);
|
||||
timer_settime(ftp->ft_tid, 0, &its, NULL);
|
||||
|
|
|
@ -80,7 +80,6 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
|||
char *path = NULL;
|
||||
uint_t c, children;
|
||||
nvlist_t **child;
|
||||
uint64_t vdev_guid;
|
||||
|
||||
/*
|
||||
* First iterate over any children.
|
||||
|
@ -101,7 +100,7 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
|||
&child, &children) == 0) {
|
||||
for (c = 0; c < children; c++) {
|
||||
if (zfs_agent_iter_vdev(zhp, child[c], gsp)) {
|
||||
gsp->gs_vdev_type = DEVICE_TYPE_SPARE;
|
||||
gsp->gs_vdev_type = DEVICE_TYPE_L2ARC;
|
||||
return (B_TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +109,7 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
|||
&child, &children) == 0) {
|
||||
for (c = 0; c < children; c++) {
|
||||
if (zfs_agent_iter_vdev(zhp, child[c], gsp)) {
|
||||
gsp->gs_vdev_type = DEVICE_TYPE_L2ARC;
|
||||
gsp->gs_vdev_type = DEVICE_TYPE_SPARE;
|
||||
return (B_TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -127,21 +126,6 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
|||
&gsp->gs_vdev_expandtime);
|
||||
return (B_TRUE);
|
||||
}
|
||||
/*
|
||||
* Otherwise, on a vdev guid match, grab the devid and expansion
|
||||
* time. The devid might be missing on removal since its not part
|
||||
* of blkid cache and L2ARC VDEV does not contain pool guid in its
|
||||
* blkid, so this is a special case for L2ARC VDEV.
|
||||
*/
|
||||
else if (gsp->gs_vdev_guid != 0 && gsp->gs_devid == NULL &&
|
||||
nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, &vdev_guid) == 0 &&
|
||||
gsp->gs_vdev_guid == vdev_guid) {
|
||||
(void) nvlist_lookup_string(nvl, ZPOOL_CONFIG_DEVID,
|
||||
&gsp->gs_devid);
|
||||
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_EXPANSION_TIME,
|
||||
&gsp->gs_vdev_expandtime);
|
||||
return (B_TRUE);
|
||||
}
|
||||
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
@ -164,13 +148,13 @@ zfs_agent_iter_pool(zpool_handle_t *zhp, void *arg)
|
|||
/*
|
||||
* if a match was found then grab the pool guid
|
||||
*/
|
||||
if (gsp->gs_vdev_guid && gsp->gs_devid) {
|
||||
if (gsp->gs_vdev_guid) {
|
||||
(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
||||
&gsp->gs_pool_guid);
|
||||
}
|
||||
|
||||
zpool_close(zhp);
|
||||
return (gsp->gs_devid != NULL && gsp->gs_vdev_guid != 0);
|
||||
return (gsp->gs_vdev_guid != 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -211,13 +195,11 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||
uint64_t pool_guid = 0, vdev_guid = 0;
|
||||
guid_search_t search = { 0 };
|
||||
device_type_t devtype = DEVICE_TYPE_PRIMARY;
|
||||
char *devid = NULL;
|
||||
|
||||
class = "resource.fs.zfs.removed";
|
||||
subclass = "";
|
||||
|
||||
(void) nvlist_add_string(payload, FM_CLASS, class);
|
||||
(void) nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid);
|
||||
(void) nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &pool_guid);
|
||||
(void) nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &vdev_guid);
|
||||
|
||||
|
@ -227,24 +209,20 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||
(void) nvlist_add_int64_array(payload, FM_EREPORT_TIME, tod, 2);
|
||||
|
||||
/*
|
||||
* If devid is missing but vdev_guid is available, find devid
|
||||
* and pool_guid from vdev_guid.
|
||||
* For multipath, spare and l2arc devices ZFS_EV_VDEV_GUID or
|
||||
* ZFS_EV_POOL_GUID may be missing so find them.
|
||||
*/
|
||||
if (devid == NULL || pool_guid == 0 || vdev_guid == 0) {
|
||||
if (devid == NULL)
|
||||
search.gs_vdev_guid = vdev_guid;
|
||||
else
|
||||
search.gs_devid = devid;
|
||||
zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search);
|
||||
if (devid == NULL)
|
||||
devid = search.gs_devid;
|
||||
if (pool_guid == 0)
|
||||
pool_guid = search.gs_pool_guid;
|
||||
if (vdev_guid == 0)
|
||||
vdev_guid = search.gs_vdev_guid;
|
||||
devtype = search.gs_vdev_type;
|
||||
if (pool_guid == 0 || vdev_guid == 0) {
|
||||
if ((nvlist_lookup_string(nvl, DEV_IDENTIFIER,
|
||||
&search.gs_devid) == 0) &&
|
||||
(zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search)
|
||||
== 1)) {
|
||||
if (pool_guid == 0)
|
||||
pool_guid = search.gs_pool_guid;
|
||||
if (vdev_guid == 0)
|
||||
vdev_guid = search.gs_vdev_guid;
|
||||
devtype = search.gs_vdev_type;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -257,9 +235,7 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||
search.gs_vdev_expandtime + 10 > tv.tv_sec) {
|
||||
zed_log_msg(LOG_INFO, "agent post event: ignoring '%s' "
|
||||
"for recently expanded device '%s'", EC_DEV_REMOVE,
|
||||
devid);
|
||||
fnvlist_free(payload);
|
||||
free(event);
|
||||
search.gs_devid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include <sys/fs/zfs.h>
|
||||
#include <sys/fm/protocol.h>
|
||||
#include <sys/fm/fs/zfs.h>
|
||||
#include <sys/zio.h>
|
||||
|
||||
#include "zfs_agents.h"
|
||||
#include "fmd_api.h"
|
||||
|
@ -774,8 +773,6 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
|
|||
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_PROBE_FAILURE))) {
|
||||
char *failmode = NULL;
|
||||
boolean_t checkremove = B_FALSE;
|
||||
uint32_t pri = 0;
|
||||
int32_t flags = 0;
|
||||
|
||||
/*
|
||||
* If this is a checksum or I/O error, then toss it into the
|
||||
|
@ -798,23 +795,6 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
|
|||
checkremove = B_TRUE;
|
||||
} else if (fmd_nvl_class_match(hdl, nvl,
|
||||
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_CHECKSUM))) {
|
||||
/*
|
||||
* We ignore ereports for checksum errors generated by
|
||||
* scrub/resilver I/O to avoid potentially further
|
||||
* degrading the pool while it's being repaired.
|
||||
*/
|
||||
if (((nvlist_lookup_uint32(nvl,
|
||||
FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY, &pri) == 0) &&
|
||||
(pri == ZIO_PRIORITY_SCRUB ||
|
||||
pri == ZIO_PRIORITY_REBUILD)) ||
|
||||
((nvlist_lookup_int32(nvl,
|
||||
FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS, &flags) == 0) &&
|
||||
(flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)))) {
|
||||
fmd_hdl_debug(hdl, "ignoring '%s' for "
|
||||
"scrub/resilver I/O", class);
|
||||
return;
|
||||
}
|
||||
|
||||
if (zcp->zc_data.zc_serd_checksum[0] == '\0') {
|
||||
zfs_serd_name(zcp->zc_data.zc_serd_checksum,
|
||||
pool_guid, vdev_guid, "checksum");
|
||||
|
|
|
@ -141,17 +141,6 @@ zfs_unavail_pool(zpool_handle_t *zhp, void *data)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write an array of strings to the zed log
|
||||
*/
|
||||
static void lines_to_zed_log_msg(char **lines, int lines_cnt)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < lines_cnt; i++) {
|
||||
zed_log_msg(LOG_INFO, "%s", lines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Two stage replace on Linux
|
||||
* since we get disk notifications
|
||||
|
@ -194,20 +183,16 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||
nvlist_t *nvroot, *newvd;
|
||||
pendingdev_t *device;
|
||||
uint64_t wholedisk = 0ULL;
|
||||
uint64_t offline = 0ULL, faulted = 0ULL;
|
||||
uint64_t offline = 0ULL;
|
||||
uint64_t guid = 0ULL;
|
||||
uint64_t is_spare = 0;
|
||||
char *physpath = NULL, *new_devid = NULL, *enc_sysfs_path = NULL;
|
||||
char rawpath[PATH_MAX], fullpath[PATH_MAX];
|
||||
char devpath[PATH_MAX];
|
||||
int ret;
|
||||
int online_flag = ZFS_ONLINE_CHECKREMOVE | ZFS_ONLINE_UNSPARE;
|
||||
boolean_t is_dm = B_FALSE;
|
||||
boolean_t is_sd = B_FALSE;
|
||||
boolean_t is_mpath_wholedisk = B_FALSE;
|
||||
uint_t c;
|
||||
vdev_stat_t *vs;
|
||||
char **lines = NULL;
|
||||
int lines_cnt = 0;
|
||||
|
||||
if (nvlist_lookup_string(vdev, ZPOOL_CONFIG_PATH, &path) != 0)
|
||||
return;
|
||||
|
@ -222,82 +207,19 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||
}
|
||||
|
||||
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_PHYS_PATH, &physpath);
|
||||
|
||||
update_vdev_config_dev_sysfs_path(vdev, path,
|
||||
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
|
||||
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
|
||||
&enc_sysfs_path);
|
||||
|
||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk);
|
||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_OFFLINE, &offline);
|
||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_FAULTED, &faulted);
|
||||
|
||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_GUID, &guid);
|
||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_IS_SPARE, &is_spare);
|
||||
|
||||
/*
|
||||
* Special case:
|
||||
*
|
||||
* We've seen times where a disk won't have a ZPOOL_CONFIG_PHYS_PATH
|
||||
* entry in their config. For example, on this force-faulted disk:
|
||||
*
|
||||
* children[0]:
|
||||
* type: 'disk'
|
||||
* id: 0
|
||||
* guid: 14309659774640089719
|
||||
* path: '/dev/disk/by-vdev/L28'
|
||||
* whole_disk: 0
|
||||
* DTL: 654
|
||||
* create_txg: 4
|
||||
* com.delphix:vdev_zap_leaf: 1161
|
||||
* faulted: 1
|
||||
* aux_state: 'external'
|
||||
* children[1]:
|
||||
* type: 'disk'
|
||||
* id: 1
|
||||
* guid: 16002508084177980912
|
||||
* path: '/dev/disk/by-vdev/L29'
|
||||
* devid: 'dm-uuid-mpath-35000c500a61d68a3'
|
||||
* phys_path: 'L29'
|
||||
* vdev_enc_sysfs_path: '/sys/class/enclosure/0:0:1:0/SLOT 30 32'
|
||||
* whole_disk: 0
|
||||
* DTL: 1028
|
||||
* create_txg: 4
|
||||
* com.delphix:vdev_zap_leaf: 131
|
||||
*
|
||||
* If the disk's path is a /dev/disk/by-vdev/ path, then we can infer
|
||||
* the ZPOOL_CONFIG_PHYS_PATH from the by-vdev disk name.
|
||||
*/
|
||||
if (physpath == NULL && path != NULL) {
|
||||
/* If path begins with "/dev/disk/by-vdev/" ... */
|
||||
if (strncmp(path, DEV_BYVDEV_PATH,
|
||||
strlen(DEV_BYVDEV_PATH)) == 0) {
|
||||
/* Set physpath to the char after "/dev/disk/by-vdev" */
|
||||
physpath = &path[strlen(DEV_BYVDEV_PATH)];
|
||||
}
|
||||
}
|
||||
if (offline)
|
||||
return; /* don't intervene if it was taken offline */
|
||||
|
||||
/*
|
||||
* We don't want to autoreplace offlined disks. However, we do want to
|
||||
* replace force-faulted disks (`zpool offline -f`). Force-faulted
|
||||
* disks have both offline=1 and faulted=1 in the nvlist.
|
||||
*/
|
||||
if (offline && !faulted) {
|
||||
zed_log_msg(LOG_INFO, "%s: %s is offline, skip autoreplace",
|
||||
__func__, path);
|
||||
return;
|
||||
}
|
||||
|
||||
is_mpath_wholedisk = is_mpath_whole_disk(path);
|
||||
is_dm = zfs_dev_is_dm(path);
|
||||
zed_log_msg(LOG_INFO, "zfs_process_add: pool '%s' vdev '%s', phys '%s'"
|
||||
" %s blank disk, %s mpath blank disk, %s labeled, enc sysfs '%s', "
|
||||
"(guid %llu)",
|
||||
zpool_get_name(zhp), path,
|
||||
physpath ? physpath : "NULL",
|
||||
wholedisk ? "is" : "not",
|
||||
is_mpath_wholedisk? "is" : "not",
|
||||
labeled ? "is" : "not",
|
||||
enc_sysfs_path,
|
||||
" wholedisk %d, %s dm (guid %llu)", zpool_get_name(zhp), path,
|
||||
physpath ? physpath : "NULL", wholedisk, is_dm ? "is" : "not",
|
||||
(long long unsigned int)guid);
|
||||
|
||||
/*
|
||||
|
@ -324,18 +246,15 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||
}
|
||||
}
|
||||
|
||||
if (is_spare)
|
||||
online_flag |= ZFS_ONLINE_SPARE;
|
||||
|
||||
/*
|
||||
* Attempt to online the device.
|
||||
*/
|
||||
if (zpool_vdev_online(zhp, fullpath, online_flag, &newstate) == 0 &&
|
||||
if (zpool_vdev_online(zhp, fullpath,
|
||||
ZFS_ONLINE_CHECKREMOVE | ZFS_ONLINE_UNSPARE, &newstate) == 0 &&
|
||||
(newstate == VDEV_STATE_HEALTHY ||
|
||||
newstate == VDEV_STATE_DEGRADED)) {
|
||||
zed_log_msg(LOG_INFO,
|
||||
" zpool_vdev_online: vdev '%s' ('%s') is "
|
||||
"%s", fullpath, physpath, (newstate == VDEV_STATE_HEALTHY) ?
|
||||
zed_log_msg(LOG_INFO, " zpool_vdev_online: vdev %s is %s",
|
||||
fullpath, (newstate == VDEV_STATE_HEALTHY) ?
|
||||
"HEALTHY" : "DEGRADED");
|
||||
return;
|
||||
}
|
||||
|
@ -352,12 +271,11 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||
* vdev online to trigger a FMA fault by posting an ereport.
|
||||
*/
|
||||
if (!zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOREPLACE, NULL) ||
|
||||
!(wholedisk || is_mpath_wholedisk) || (physpath == NULL)) {
|
||||
!(wholedisk || is_dm) || (physpath == NULL)) {
|
||||
(void) zpool_vdev_online(zhp, fullpath, ZFS_ONLINE_FORCEFAULT,
|
||||
&newstate);
|
||||
zed_log_msg(LOG_INFO, "Pool's autoreplace is not enabled or "
|
||||
"not a blank disk for '%s' ('%s')", fullpath,
|
||||
physpath);
|
||||
"not a whole disk for '%s'", fullpath);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -369,7 +287,7 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||
(void) snprintf(rawpath, sizeof (rawpath), "%s%s",
|
||||
is_sd ? DEV_BYVDEV_PATH : DEV_BYPATH_PATH, physpath);
|
||||
|
||||
if (realpath(rawpath, devpath) == NULL && !is_mpath_wholedisk) {
|
||||
if (realpath(rawpath, devpath) == NULL && !is_dm) {
|
||||
zed_log_msg(LOG_INFO, " realpath: %s failed (%s)",
|
||||
rawpath, strerror(errno));
|
||||
|
||||
|
@ -385,31 +303,13 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||
if ((vs->vs_state != VDEV_STATE_DEGRADED) &&
|
||||
(vs->vs_state != VDEV_STATE_FAULTED) &&
|
||||
(vs->vs_state != VDEV_STATE_CANT_OPEN)) {
|
||||
zed_log_msg(LOG_INFO, " not autoreplacing since disk isn't in "
|
||||
"a bad state (currently %d)", vs->vs_state);
|
||||
return;
|
||||
}
|
||||
|
||||
nvlist_lookup_string(vdev, "new_devid", &new_devid);
|
||||
|
||||
if (is_mpath_wholedisk) {
|
||||
if (is_dm) {
|
||||
/* Don't label device mapper or multipath disks. */
|
||||
zed_log_msg(LOG_INFO,
|
||||
" it's a multipath wholedisk, don't label");
|
||||
if (zpool_prepare_disk(zhp, vdev, "autoreplace", &lines,
|
||||
&lines_cnt) != 0) {
|
||||
zed_log_msg(LOG_INFO,
|
||||
" zpool_prepare_disk: could not "
|
||||
"prepare '%s' (%s)", fullpath,
|
||||
libzfs_error_description(g_zfshdl));
|
||||
if (lines_cnt > 0) {
|
||||
zed_log_msg(LOG_INFO,
|
||||
" zfs_prepare_disk output:");
|
||||
lines_to_zed_log_msg(lines, lines_cnt);
|
||||
}
|
||||
libzfs_free_str_array(lines, lines_cnt);
|
||||
return;
|
||||
}
|
||||
} else if (!labeled) {
|
||||
/*
|
||||
* we're auto-replacing a raw disk, so label it first
|
||||
|
@ -432,18 +332,10 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||
* If this is a request to label a whole disk, then attempt to
|
||||
* write out the label.
|
||||
*/
|
||||
if (zpool_prepare_and_label_disk(g_zfshdl, zhp, leafname,
|
||||
vdev, "autoreplace", &lines, &lines_cnt) != 0) {
|
||||
zed_log_msg(LOG_INFO,
|
||||
" zpool_prepare_and_label_disk: could not "
|
||||
if (zpool_label_disk(g_zfshdl, zhp, leafname) != 0) {
|
||||
zed_log_msg(LOG_INFO, " zpool_label_disk: could not "
|
||||
"label '%s' (%s)", leafname,
|
||||
libzfs_error_description(g_zfshdl));
|
||||
if (lines_cnt > 0) {
|
||||
zed_log_msg(LOG_INFO,
|
||||
" zfs_prepare_disk output:");
|
||||
lines_to_zed_log_msg(lines, lines_cnt);
|
||||
}
|
||||
libzfs_free_str_array(lines, lines_cnt);
|
||||
|
||||
(void) zpool_vdev_online(zhp, fullpath,
|
||||
ZFS_ONLINE_FORCEFAULT, &newstate);
|
||||
|
@ -498,8 +390,6 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||
DEV_BYID_PATH, new_devid);
|
||||
}
|
||||
|
||||
libzfs_free_str_array(lines, lines_cnt);
|
||||
|
||||
/*
|
||||
* Construct the root vdev to pass to zpool_vdev_attach(). While adding
|
||||
* the entire vdev structure is harmless, we construct a reduced set of
|
||||
|
@ -573,9 +463,7 @@ typedef struct dev_data {
|
|||
boolean_t dd_islabeled;
|
||||
uint64_t dd_pool_guid;
|
||||
uint64_t dd_vdev_guid;
|
||||
uint64_t dd_new_vdev_guid;
|
||||
const char *dd_new_devid;
|
||||
uint64_t dd_num_spares;
|
||||
} dev_data_t;
|
||||
|
||||
static void
|
||||
|
@ -585,8 +473,6 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
|||
char *path = NULL;
|
||||
uint_t c, children;
|
||||
nvlist_t **child;
|
||||
uint64_t guid = 0;
|
||||
uint64_t isspare = 0;
|
||||
|
||||
/*
|
||||
* First iterate over any children.
|
||||
|
@ -612,16 +498,19 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
|||
}
|
||||
|
||||
/* once a vdev was matched and processed there is nothing left to do */
|
||||
if (dp->dd_found && dp->dd_num_spares == 0)
|
||||
if (dp->dd_found)
|
||||
return;
|
||||
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, &guid);
|
||||
|
||||
/*
|
||||
* Match by GUID if available otherwise fallback to devid or physical
|
||||
*/
|
||||
if (dp->dd_vdev_guid != 0) {
|
||||
if (guid != dp->dd_vdev_guid)
|
||||
uint64_t guid;
|
||||
|
||||
if (nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID,
|
||||
&guid) != 0 || guid != dp->dd_vdev_guid) {
|
||||
return;
|
||||
}
|
||||
zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched on %llu", guid);
|
||||
dp->dd_found = B_TRUE;
|
||||
|
||||
|
@ -631,23 +520,10 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
|||
* illumos, substring matching is not required to accommodate
|
||||
* the partition suffix. An exact match will be present in
|
||||
* the dp->dd_compare value.
|
||||
* If the attached disk already contains a vdev GUID, it means
|
||||
* the disk is not clean. In such a scenario, the physical path
|
||||
* would be a match that makes the disk faulted when trying to
|
||||
* online it. So, we would only want to proceed if either GUID
|
||||
* matches with the last attached disk or the disk is in clean
|
||||
* state.
|
||||
*/
|
||||
if (nvlist_lookup_string(nvl, dp->dd_prop, &path) != 0 ||
|
||||
strcmp(dp->dd_compare, path) != 0) {
|
||||
strcmp(dp->dd_compare, path) != 0)
|
||||
return;
|
||||
}
|
||||
if (dp->dd_new_vdev_guid != 0 && dp->dd_new_vdev_guid != guid) {
|
||||
zed_log_msg(LOG_INFO, " %s: no match (GUID:%llu"
|
||||
" != vdev GUID:%llu)", __func__,
|
||||
dp->dd_new_vdev_guid, guid);
|
||||
return;
|
||||
}
|
||||
|
||||
zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched %s on %s",
|
||||
dp->dd_prop, path);
|
||||
|
@ -660,10 +536,6 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
if (dp->dd_found == B_TRUE && nvlist_lookup_uint64(nvl,
|
||||
ZPOOL_CONFIG_IS_SPARE, &isspare) == 0 && isspare)
|
||||
dp->dd_num_spares++;
|
||||
|
||||
(dp->dd_func)(zhp, nvl, dp->dd_islabeled);
|
||||
}
|
||||
|
||||
|
@ -699,8 +571,6 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data)
|
|||
ZPOOL_CONFIG_VDEV_TREE, &nvl);
|
||||
zfs_iter_vdev(zhp, nvl, data);
|
||||
}
|
||||
} else {
|
||||
zed_log_msg(LOG_INFO, "%s: no config\n", __func__);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -724,9 +594,7 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data)
|
|||
}
|
||||
|
||||
zpool_close(zhp);
|
||||
|
||||
/* cease iteration after a match */
|
||||
return (dp->dd_found && dp->dd_num_spares == 0);
|
||||
return (dp->dd_found); /* cease iteration after a match */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -735,7 +603,7 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data)
|
|||
*/
|
||||
static boolean_t
|
||||
devphys_iter(const char *physical, const char *devid, zfs_process_func_t func,
|
||||
boolean_t is_slice, uint64_t new_vdev_guid)
|
||||
boolean_t is_slice)
|
||||
{
|
||||
dev_data_t data = { 0 };
|
||||
|
||||
|
@ -745,73 +613,6 @@ devphys_iter(const char *physical, const char *devid, zfs_process_func_t func,
|
|||
data.dd_found = B_FALSE;
|
||||
data.dd_islabeled = is_slice;
|
||||
data.dd_new_devid = devid; /* used by auto replace code */
|
||||
data.dd_new_vdev_guid = new_vdev_guid;
|
||||
|
||||
(void) zpool_iter(g_zfshdl, zfs_iter_pool, &data);
|
||||
|
||||
return (data.dd_found);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a device identifier, find any vdevs with a matching by-vdev
|
||||
* path. Normally we shouldn't need this as the comparison would be
|
||||
* made earlier in the devphys_iter(). For example, if we were replacing
|
||||
* /dev/disk/by-vdev/L28, normally devphys_iter() would match the
|
||||
* ZPOOL_CONFIG_PHYS_PATH of "L28" from the old disk config to "L28"
|
||||
* of the new disk config. However, we've seen cases where
|
||||
* ZPOOL_CONFIG_PHYS_PATH was not in the config for the old disk. Here's
|
||||
* an example of a real 2-disk mirror pool where one disk was force
|
||||
* faulted:
|
||||
*
|
||||
* com.delphix:vdev_zap_top: 129
|
||||
* children[0]:
|
||||
* type: 'disk'
|
||||
* id: 0
|
||||
* guid: 14309659774640089719
|
||||
* path: '/dev/disk/by-vdev/L28'
|
||||
* whole_disk: 0
|
||||
* DTL: 654
|
||||
* create_txg: 4
|
||||
* com.delphix:vdev_zap_leaf: 1161
|
||||
* faulted: 1
|
||||
* aux_state: 'external'
|
||||
* children[1]:
|
||||
* type: 'disk'
|
||||
* id: 1
|
||||
* guid: 16002508084177980912
|
||||
* path: '/dev/disk/by-vdev/L29'
|
||||
* devid: 'dm-uuid-mpath-35000c500a61d68a3'
|
||||
* phys_path: 'L29'
|
||||
* vdev_enc_sysfs_path: '/sys/class/enclosure/0:0:1:0/SLOT 30 32'
|
||||
* whole_disk: 0
|
||||
* DTL: 1028
|
||||
* create_txg: 4
|
||||
* com.delphix:vdev_zap_leaf: 131
|
||||
*
|
||||
* So in the case above, the only thing we could compare is the path.
|
||||
*
|
||||
* We can do this because we assume by-vdev paths are authoritative as physical
|
||||
* paths. We could not assume this for normal paths like /dev/sda since the
|
||||
* physical location /dev/sda points to could change over time.
|
||||
*/
|
||||
static boolean_t
|
||||
by_vdev_path_iter(const char *by_vdev_path, const char *devid,
|
||||
zfs_process_func_t func, boolean_t is_slice)
|
||||
{
|
||||
dev_data_t data = { 0 };
|
||||
|
||||
data.dd_compare = by_vdev_path;
|
||||
data.dd_func = func;
|
||||
data.dd_prop = ZPOOL_CONFIG_PATH;
|
||||
data.dd_found = B_FALSE;
|
||||
data.dd_islabeled = is_slice;
|
||||
data.dd_new_devid = devid;
|
||||
|
||||
if (strncmp(by_vdev_path, DEV_BYVDEV_PATH,
|
||||
strlen(DEV_BYVDEV_PATH)) != 0) {
|
||||
/* by_vdev_path doesn't start with "/dev/disk/by-vdev/" */
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
(void) zpool_iter(g_zfshdl, zfs_iter_pool, &data);
|
||||
|
||||
|
@ -839,27 +640,6 @@ devid_iter(const char *devid, zfs_process_func_t func, boolean_t is_slice)
|
|||
return (data.dd_found);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a device guid, find any vdevs with a matching guid.
|
||||
*/
|
||||
static boolean_t
|
||||
guid_iter(uint64_t pool_guid, uint64_t vdev_guid, const char *devid,
|
||||
zfs_process_func_t func, boolean_t is_slice)
|
||||
{
|
||||
dev_data_t data = { 0 };
|
||||
|
||||
data.dd_func = func;
|
||||
data.dd_found = B_FALSE;
|
||||
data.dd_pool_guid = pool_guid;
|
||||
data.dd_vdev_guid = vdev_guid;
|
||||
data.dd_islabeled = is_slice;
|
||||
data.dd_new_devid = devid;
|
||||
|
||||
(void) zpool_iter(g_zfshdl, zfs_iter_pool, &data);
|
||||
|
||||
return (data.dd_found);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a EC_DEV_ADD.ESC_DISK event.
|
||||
*
|
||||
|
@ -882,21 +662,16 @@ guid_iter(uint64_t pool_guid, uint64_t vdev_guid, const char *devid,
|
|||
static int
|
||||
zfs_deliver_add(nvlist_t *nvl, boolean_t is_lofi)
|
||||
{
|
||||
char *devpath = NULL, *devid = NULL;
|
||||
uint64_t pool_guid = 0, vdev_guid = 0;
|
||||
char *devpath = NULL, *devid;
|
||||
boolean_t is_slice;
|
||||
|
||||
/*
|
||||
* Expecting a devid string and an optional physical location and guid
|
||||
* Expecting a devid string and an optional physical location
|
||||
*/
|
||||
if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid) != 0) {
|
||||
zed_log_msg(LOG_INFO, "%s: no dev identifier\n", __func__);
|
||||
if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid) != 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
(void) nvlist_lookup_string(nvl, DEV_PHYS_PATH, &devpath);
|
||||
(void) nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &pool_guid);
|
||||
(void) nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &vdev_guid);
|
||||
|
||||
is_slice = (nvlist_lookup_boolean(nvl, DEV_IS_PART) == 0);
|
||||
|
||||
|
@ -907,28 +682,12 @@ zfs_deliver_add(nvlist_t *nvl, boolean_t is_lofi)
|
|||
* Iterate over all vdevs looking for a match in the following order:
|
||||
* 1. ZPOOL_CONFIG_DEVID (identifies the unique disk)
|
||||
* 2. ZPOOL_CONFIG_PHYS_PATH (identifies disk physical location).
|
||||
* 3. ZPOOL_CONFIG_GUID (identifies unique vdev).
|
||||
* 4. ZPOOL_CONFIG_PATH for /dev/disk/by-vdev devices only (since
|
||||
* by-vdev paths represent physical paths).
|
||||
*
|
||||
* For disks, we only want to pay attention to vdevs marked as whole
|
||||
* disks or are a multipath device.
|
||||
*/
|
||||
if (devid_iter(devid, zfs_process_add, is_slice))
|
||||
return (0);
|
||||
if (devpath != NULL && devphys_iter(devpath, devid, zfs_process_add,
|
||||
is_slice, vdev_guid))
|
||||
return (0);
|
||||
if (vdev_guid != 0)
|
||||
(void) guid_iter(pool_guid, vdev_guid, devid, zfs_process_add,
|
||||
is_slice);
|
||||
|
||||
if (devpath != NULL) {
|
||||
/* Can we match a /dev/disk/by-vdev/ path? */
|
||||
char by_vdev_path[MAXPATHLEN];
|
||||
snprintf(by_vdev_path, sizeof (by_vdev_path),
|
||||
"/dev/disk/by-vdev/%s", devpath);
|
||||
if (by_vdev_path_iter(by_vdev_path, devid, zfs_process_add,
|
||||
is_slice))
|
||||
return (0);
|
||||
}
|
||||
if (!devid_iter(devid, zfs_process_add, is_slice) && devpath != NULL)
|
||||
(void) devphys_iter(devpath, devid, zfs_process_add, is_slice);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -960,96 +719,21 @@ zfs_deliver_check(nvlist_t *nvl)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a path to a vdev, lookup the vdev's physical size from its
|
||||
* config nvlist.
|
||||
*
|
||||
* Returns the vdev's physical size in bytes on success, 0 on error.
|
||||
*/
|
||||
static uint64_t
|
||||
vdev_size_from_config(zpool_handle_t *zhp, const char *vdev_path)
|
||||
{
|
||||
nvlist_t *nvl = NULL;
|
||||
boolean_t avail_spare, l2cache, log;
|
||||
vdev_stat_t *vs = NULL;
|
||||
uint_t c;
|
||||
|
||||
nvl = zpool_find_vdev(zhp, vdev_path, &avail_spare, &l2cache, &log);
|
||||
if (!nvl)
|
||||
return (0);
|
||||
|
||||
verify(nvlist_lookup_uint64_array(nvl, ZPOOL_CONFIG_VDEV_STATS,
|
||||
(uint64_t **)&vs, &c) == 0);
|
||||
if (!vs) {
|
||||
zed_log_msg(LOG_INFO, "%s: no nvlist for '%s'", __func__,
|
||||
vdev_path);
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (vs->vs_pspace);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a path to a vdev, lookup if the vdev is a "whole disk" in the
|
||||
* config nvlist. "whole disk" means that ZFS was passed a whole disk
|
||||
* at pool creation time, which it partitioned up and has full control over.
|
||||
* Thus a partition with wholedisk=1 set tells us that zfs created the
|
||||
* partition at creation time. A partition without whole disk set would have
|
||||
* been created by externally (like with fdisk) and passed to ZFS.
|
||||
*
|
||||
* Returns the whole disk value (either 0 or 1).
|
||||
*/
|
||||
static uint64_t
|
||||
vdev_whole_disk_from_config(zpool_handle_t *zhp, const char *vdev_path)
|
||||
{
|
||||
nvlist_t *nvl = NULL;
|
||||
boolean_t avail_spare, l2cache, log;
|
||||
uint64_t wholedisk = 0;
|
||||
|
||||
nvl = zpool_find_vdev(zhp, vdev_path, &avail_spare, &l2cache, &log);
|
||||
if (!nvl)
|
||||
return (0);
|
||||
|
||||
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk);
|
||||
|
||||
return (wholedisk);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the device size grew more than 1% then return true.
|
||||
*/
|
||||
#define DEVICE_GREW(oldsize, newsize) \
|
||||
((newsize > oldsize) && \
|
||||
((newsize / (newsize - oldsize)) <= 100))
|
||||
|
||||
static int
|
||||
zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
||||
{
|
||||
char *devname = data;
|
||||
boolean_t avail_spare, l2cache;
|
||||
nvlist_t *udev_nvl = data;
|
||||
nvlist_t *tgt;
|
||||
int error;
|
||||
|
||||
char *tmp_devname, devname[MAXPATHLEN] = "";
|
||||
uint64_t guid;
|
||||
|
||||
if (nvlist_lookup_uint64(udev_nvl, ZFS_EV_VDEV_GUID, &guid) == 0) {
|
||||
sprintf(devname, "%llu", (u_longlong_t)guid);
|
||||
} else if (nvlist_lookup_string(udev_nvl, DEV_PHYS_PATH,
|
||||
&tmp_devname) == 0) {
|
||||
strlcpy(devname, tmp_devname, MAXPATHLEN);
|
||||
zfs_append_partition(devname, MAXPATHLEN);
|
||||
} else {
|
||||
zed_log_msg(LOG_INFO, "%s: no guid or physpath", __func__);
|
||||
}
|
||||
|
||||
zed_log_msg(LOG_INFO, "zfsdle_vdev_online: searching for '%s' in '%s'",
|
||||
devname, zpool_get_name(zhp));
|
||||
|
||||
if ((tgt = zpool_find_vdev_by_physpath(zhp, devname,
|
||||
&avail_spare, &l2cache, NULL)) != NULL) {
|
||||
char *path, fullpath[MAXPATHLEN];
|
||||
uint64_t wholedisk = 0;
|
||||
uint64_t wholedisk;
|
||||
|
||||
error = nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &path);
|
||||
if (error) {
|
||||
|
@ -1057,8 +741,10 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
|||
return (0);
|
||||
}
|
||||
|
||||
(void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
|
||||
error = nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
|
||||
&wholedisk);
|
||||
if (error)
|
||||
wholedisk = 0;
|
||||
|
||||
if (wholedisk) {
|
||||
path = strrchr(path, '/');
|
||||
|
@ -1092,75 +778,12 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
|||
vdev_state_t newstate;
|
||||
|
||||
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) {
|
||||
/*
|
||||
* If this disk size has not changed, then
|
||||
* there's no need to do an autoexpand. To
|
||||
* check we look at the disk's size in its
|
||||
* config, and compare it to the disk size
|
||||
* that udev is reporting.
|
||||
*/
|
||||
uint64_t udev_size = 0, conf_size = 0,
|
||||
wholedisk = 0, udev_parent_size = 0;
|
||||
|
||||
/*
|
||||
* Get the size of our disk that udev is
|
||||
* reporting.
|
||||
*/
|
||||
if (nvlist_lookup_uint64(udev_nvl, DEV_SIZE,
|
||||
&udev_size) != 0) {
|
||||
udev_size = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the size of our disk's parent device
|
||||
* from udev (where sda1's parent is sda).
|
||||
*/
|
||||
if (nvlist_lookup_uint64(udev_nvl,
|
||||
DEV_PARENT_SIZE, &udev_parent_size) != 0) {
|
||||
udev_parent_size = 0;
|
||||
}
|
||||
|
||||
conf_size = vdev_size_from_config(zhp,
|
||||
fullpath);
|
||||
|
||||
wholedisk = vdev_whole_disk_from_config(zhp,
|
||||
fullpath);
|
||||
|
||||
/*
|
||||
* Only attempt an autoexpand if the vdev size
|
||||
* changed. There are two different cases
|
||||
* to consider.
|
||||
*
|
||||
* 1. wholedisk=1
|
||||
* If you do a 'zpool create' on a whole disk
|
||||
* (like /dev/sda), then zfs will create
|
||||
* partitions on the disk (like /dev/sda1). In
|
||||
* that case, wholedisk=1 will be set in the
|
||||
* partition's nvlist config. So zed will need
|
||||
* to see if your parent device (/dev/sda)
|
||||
* expanded in size, and if so, then attempt
|
||||
* the autoexpand.
|
||||
*
|
||||
* 2. wholedisk=0
|
||||
* If you do a 'zpool create' on an existing
|
||||
* partition, or a device that doesn't allow
|
||||
* partitions, then wholedisk=0, and you will
|
||||
* simply need to check if the device itself
|
||||
* expanded in size.
|
||||
*/
|
||||
if (DEVICE_GREW(conf_size, udev_size) ||
|
||||
(wholedisk && DEVICE_GREW(conf_size,
|
||||
udev_parent_size))) {
|
||||
error = zpool_vdev_online(zhp, fullpath,
|
||||
0, &newstate);
|
||||
|
||||
zed_log_msg(LOG_INFO,
|
||||
"%s: autoexpanding '%s' from %llu"
|
||||
" to %llu bytes in pool '%s': %d",
|
||||
__func__, fullpath, conf_size,
|
||||
MAX(udev_size, udev_parent_size),
|
||||
zpool_get_name(zhp), error);
|
||||
}
|
||||
error = zpool_vdev_online(zhp, fullpath, 0,
|
||||
&newstate);
|
||||
zed_log_msg(LOG_INFO, "zfsdle_vdev_online: "
|
||||
"setting device '%s' to ONLINE state "
|
||||
"in pool '%s': %d", fullpath,
|
||||
zpool_get_name(zhp), error);
|
||||
}
|
||||
}
|
||||
zpool_close(zhp);
|
||||
|
@ -1188,11 +811,10 @@ zfs_deliver_dle(nvlist_t *nvl)
|
|||
strlcpy(name, devname, MAXPATHLEN);
|
||||
zfs_append_partition(name, MAXPATHLEN);
|
||||
} else {
|
||||
sprintf(name, "unknown");
|
||||
zed_log_msg(LOG_INFO, "zfs_deliver_dle: no guid or physpath");
|
||||
}
|
||||
|
||||
if (zpool_iter(g_zfshdl, zfsdle_vdev_online, nvl) != 1) {
|
||||
if (zpool_iter(g_zfshdl, zfsdle_vdev_online, name) != 1) {
|
||||
zed_log_msg(LOG_INFO, "zfs_deliver_dle: device '%s' not "
|
||||
"found", name);
|
||||
return (1);
|
||||
|
@ -1278,7 +900,7 @@ zfs_enum_pools(void *arg)
|
|||
* For now, each agent has its own libzfs instance
|
||||
*/
|
||||
int
|
||||
zfs_slm_init(void)
|
||||
zfs_slm_init()
|
||||
{
|
||||
if ((g_zfshdl = libzfs_init()) == NULL)
|
||||
return (-1);
|
||||
|
@ -1304,7 +926,7 @@ zfs_slm_init(void)
|
|||
}
|
||||
|
||||
void
|
||||
zfs_slm_fini(void)
|
||||
zfs_slm_fini()
|
||||
{
|
||||
unavailpool_t *pool;
|
||||
pendingdev_t *device;
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include <sys/fm/fs/zfs.h>
|
||||
#include <libzfs.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include "zfs_agents.h"
|
||||
#include "fmd_api.h"
|
||||
|
@ -75,8 +74,6 @@ typedef struct find_cbdata {
|
|||
uint64_t cb_guid;
|
||||
zpool_handle_t *cb_zhp;
|
||||
nvlist_t *cb_vdev;
|
||||
uint64_t cb_vdev_guid;
|
||||
uint64_t cb_num_spares;
|
||||
} find_cbdata_t;
|
||||
|
||||
static int
|
||||
|
@ -142,64 +139,6 @@ find_vdev(libzfs_handle_t *zhdl, nvlist_t *nv, uint64_t search_guid)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
remove_spares(zpool_handle_t *zhp, void *data)
|
||||
{
|
||||
nvlist_t *config, *nvroot;
|
||||
nvlist_t **spares;
|
||||
uint_t nspares;
|
||||
char *devname;
|
||||
find_cbdata_t *cbp = data;
|
||||
uint64_t spareguid = 0;
|
||||
vdev_stat_t *vs;
|
||||
unsigned int c;
|
||||
|
||||
config = zpool_get_config(zhp, NULL);
|
||||
if (nvlist_lookup_nvlist(config,
|
||||
ZPOOL_CONFIG_VDEV_TREE, &nvroot) != 0) {
|
||||
zpool_close(zhp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
|
||||
&spares, &nspares) != 0) {
|
||||
zpool_close(zhp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < nspares; i++) {
|
||||
if (nvlist_lookup_uint64(spares[i], ZPOOL_CONFIG_GUID,
|
||||
&spareguid) == 0 && spareguid == cbp->cb_vdev_guid) {
|
||||
devname = zpool_vdev_name(NULL, zhp, spares[i],
|
||||
B_FALSE);
|
||||
nvlist_lookup_uint64_array(spares[i],
|
||||
ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &c);
|
||||
if (vs->vs_state != VDEV_STATE_REMOVED &&
|
||||
zpool_vdev_remove_wanted(zhp, devname) == 0)
|
||||
cbp->cb_num_spares++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
zpool_close(zhp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a vdev guid, find and remove all spares associated with it.
|
||||
*/
|
||||
static int
|
||||
find_and_remove_spares(libzfs_handle_t *zhdl, uint64_t vdev_guid)
|
||||
{
|
||||
find_cbdata_t cb;
|
||||
|
||||
cb.cb_num_spares = 0;
|
||||
cb.cb_vdev_guid = vdev_guid;
|
||||
zpool_iter(zhdl, remove_spares, &cb);
|
||||
|
||||
return (cb.cb_num_spares);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a (pool, vdev) GUID pair, find the matching pool and vdev.
|
||||
*/
|
||||
|
@ -375,8 +314,6 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
|||
libzfs_handle_t *zhdl = zdp->zrd_hdl;
|
||||
boolean_t fault_device, degrade_device;
|
||||
boolean_t is_repair;
|
||||
boolean_t l2arc = B_FALSE;
|
||||
boolean_t spare = B_FALSE;
|
||||
char *scheme;
|
||||
nvlist_t *vdev = NULL;
|
||||
char *uuid;
|
||||
|
@ -385,8 +322,6 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
|||
boolean_t is_disk;
|
||||
vdev_aux_t aux;
|
||||
uint64_t state = 0;
|
||||
vdev_stat_t *vs;
|
||||
unsigned int c;
|
||||
|
||||
fmd_hdl_debug(hdl, "zfs_retire_recv: '%s'", class);
|
||||
|
||||
|
@ -403,31 +338,10 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
|||
char *devtype;
|
||||
char *devname;
|
||||
|
||||
if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE,
|
||||
&devtype) == 0) {
|
||||
if (strcmp(devtype, VDEV_TYPE_SPARE) == 0)
|
||||
spare = B_TRUE;
|
||||
else if (strcmp(devtype, VDEV_TYPE_L2CACHE) == 0)
|
||||
l2arc = B_TRUE;
|
||||
}
|
||||
|
||||
if (nvlist_lookup_uint64(nvl,
|
||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID, &vdev_guid) != 0)
|
||||
return;
|
||||
|
||||
if (vdev_guid == 0) {
|
||||
fmd_hdl_debug(hdl, "Got a zero GUID");
|
||||
return;
|
||||
}
|
||||
|
||||
if (spare) {
|
||||
int nspares = find_and_remove_spares(zhdl, vdev_guid);
|
||||
fmd_hdl_debug(hdl, "%d spares removed", nspares);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_ZFS_POOL_GUID,
|
||||
&pool_guid) != 0)
|
||||
&pool_guid) != 0 ||
|
||||
nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID,
|
||||
&vdev_guid) != 0)
|
||||
return;
|
||||
|
||||
if ((zhp = find_by_guid(zhdl, pool_guid, vdev_guid,
|
||||
|
@ -436,30 +350,13 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
|||
|
||||
devname = zpool_vdev_name(NULL, zhp, vdev, B_FALSE);
|
||||
|
||||
nvlist_lookup_uint64_array(vdev, ZPOOL_CONFIG_VDEV_STATS,
|
||||
(uint64_t **)&vs, &c);
|
||||
|
||||
/*
|
||||
* If state removed is requested for already removed vdev,
|
||||
* its a loopback event from spa_async_remove(). Just
|
||||
* ignore it.
|
||||
*/
|
||||
if (vs->vs_state == VDEV_STATE_REMOVED &&
|
||||
state == VDEV_STATE_REMOVED)
|
||||
return;
|
||||
|
||||
/* Remove the vdev since device is unplugged */
|
||||
int remove_status = 0;
|
||||
if (l2arc || (strcmp(class, "resource.fs.zfs.removed") == 0)) {
|
||||
remove_status = zpool_vdev_remove_wanted(zhp, devname);
|
||||
fmd_hdl_debug(hdl, "zpool_vdev_remove_wanted '%s'"
|
||||
", err:%d", devname, libzfs_errno(zhdl));
|
||||
}
|
||||
|
||||
/* Replace the vdev with a spare if its not a l2arc */
|
||||
if (!l2arc && !remove_status &&
|
||||
(!fmd_prop_get_int32(hdl, "spare_on_remove") ||
|
||||
replace_with_spare(hdl, zhp, vdev) == B_FALSE)) {
|
||||
/* Can't replace l2arc with a spare: offline the device */
|
||||
if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE,
|
||||
&devtype) == 0 && strcmp(devtype, VDEV_TYPE_L2CACHE) == 0) {
|
||||
fmd_hdl_debug(hdl, "zpool_vdev_offline '%s'", devname);
|
||||
zpool_vdev_offline(zhp, devname, B_TRUE);
|
||||
} else if (!fmd_prop_get_int32(hdl, "spare_on_remove") ||
|
||||
replace_with_spare(hdl, zhp, vdev) == B_FALSE) {
|
||||
/* Could not handle with spare */
|
||||
fmd_hdl_debug(hdl, "no spare for '%s'", devname);
|
||||
}
|
||||
|
|
|
@ -291,7 +291,7 @@ idle:
|
|||
rv = zed_event_service(&zcp);
|
||||
|
||||
/* ENODEV: When kernel module is unloaded (osx) */
|
||||
if (rv != 0)
|
||||
if (rv == ENODEV)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
include $(top_srcdir)/config/Rules.am
|
||||
include $(top_srcdir)/config/Substfiles.am
|
||||
include $(top_srcdir)/config/Shellcheck.am
|
||||
|
||||
EXTRA_DIST += README
|
||||
|
||||
|
@ -21,7 +20,6 @@ dist_zedexec_SCRIPTS = \
|
|||
scrub_finish-notify.sh \
|
||||
statechange-led.sh \
|
||||
statechange-notify.sh \
|
||||
statechange-slot_off.sh \
|
||||
vdev_clear-led.sh \
|
||||
vdev_attach-led.sh \
|
||||
pool_import-led.sh \
|
||||
|
@ -40,7 +38,6 @@ zedconfdefaults = \
|
|||
scrub_finish-notify.sh \
|
||||
statechange-led.sh \
|
||||
statechange-notify.sh \
|
||||
statechange-slot_off.sh \
|
||||
vdev_clear-led.sh \
|
||||
vdev_attach-led.sh \
|
||||
pool_import-led.sh \
|
||||
|
@ -54,6 +51,3 @@ install-data-hook:
|
|||
ln -s "$(zedexecdir)/$${f}" "$(DESTDIR)$(zedconfdir)"; \
|
||||
done
|
||||
chmod 0600 "$(DESTDIR)$(zedconfdir)/zed.rc"
|
||||
|
||||
# False positive: 1>&"${ZED_FLOCK_FD}" looks suspiciously similar to a >&filename bash extension
|
||||
CHECKBASHISMS_IGNORE = -e 'should be >word 2>&1' -e '&"$${ZED_FLOCK_FD}"'
|
||||
|
|
|
@ -12,11 +12,15 @@
|
|||
|
||||
zed_exit_if_ignoring_this_event
|
||||
|
||||
zed_lock "${ZED_DEBUG_LOG}"
|
||||
{
|
||||
printenv | sort
|
||||
echo
|
||||
} 1>&"${ZED_FLOCK_FD}"
|
||||
zed_unlock "${ZED_DEBUG_LOG}"
|
||||
lockfile="$(basename -- "${ZED_DEBUG_LOG}").lock"
|
||||
|
||||
umask 077
|
||||
zed_lock "${lockfile}"
|
||||
exec >> "${ZED_DEBUG_LOG}"
|
||||
|
||||
printenv | sort
|
||||
echo
|
||||
|
||||
exec >&-
|
||||
zed_unlock "${lockfile}"
|
||||
exit 0
|
||||
|
|
|
@ -21,7 +21,7 @@ if [ "${ZED_SYSLOG_DISPLAY_GUIDS}" = "1" ]; then
|
|||
[ -n "${ZEVENT_VDEV_GUID}" ] && msg="${msg} vdev_guid=${ZEVENT_VDEV_GUID}"
|
||||
else
|
||||
[ -n "${ZEVENT_POOL}" ] && msg="${msg} pool='${ZEVENT_POOL}'"
|
||||
[ -n "${ZEVENT_VDEV_PATH}" ] && msg="${msg} vdev=${ZEVENT_VDEV_PATH##*/}"
|
||||
[ -n "${ZEVENT_VDEV_PATH}" ] && msg="${msg} vdev=$(basename "${ZEVENT_VDEV_PATH}")"
|
||||
fi
|
||||
|
||||
# log pool state if state is anything other than 'ACTIVE'
|
||||
|
@ -42,7 +42,6 @@ fi
|
|||
msg="${msg} delay=$((ZEVENT_ZIO_DELAY / 1000000))ms"
|
||||
|
||||
# list the bookmark data together
|
||||
# shellcheck disable=SC2153
|
||||
[ -n "${ZEVENT_ZIO_OBJSET}" ] && \
|
||||
msg="${msg} bookmark=${ZEVENT_ZIO_OBJSET}:${ZEVENT_ZIO_OBJECT}:${ZEVENT_ZIO_LEVEL}:${ZEVENT_ZIO_BLKID}"
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
# Rate-limit the notification based in part on the filename.
|
||||
#
|
||||
rate_limit_tag="${ZEVENT_POOL};${ZEVENT_SUBCLASS};${0##*/}"
|
||||
rate_limit_tag="${ZEVENT_POOL};${ZEVENT_SUBCLASS};$(basename -- "$0")"
|
||||
rate_limit_interval="${ZED_NOTIFY_INTERVAL_SECS}"
|
||||
zed_rate_limit "${rate_limit_tag}" "${rate_limit_interval}" || exit 3
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
# Track changes to enumerated pools for use in early-boot
|
||||
set -ef
|
||||
|
||||
FSLIST="@sysconfdir@/zfs/zfs-list.cache/${ZEVENT_POOL}"
|
||||
FSLIST_TMP="@runstatedir@/zfs-list.cache@${ZEVENT_POOL}"
|
||||
FSLIST_DIR="@sysconfdir@/zfs/zfs-list.cache"
|
||||
FSLIST_TMP="@runstatedir@/zfs-list.cache.new"
|
||||
FSLIST="${FSLIST_DIR}/${ZEVENT_POOL}"
|
||||
|
||||
# If the pool specific cache file is not writeable, abort
|
||||
[ -w "${FSLIST}" ] || exit 0
|
||||
|
@ -18,15 +19,15 @@ zed_check_cmd "${ZFS}" sort diff
|
|||
# If we are acting on a snapshot, we have nothing to do
|
||||
[ "${ZEVENT_HISTORY_DSNAME%@*}" = "${ZEVENT_HISTORY_DSNAME}" ] || exit 0
|
||||
|
||||
# We lock the output file to avoid simultaneous writes.
|
||||
# We obtain a lock on zfs-list to avoid any simultaneous writes.
|
||||
# If we run into trouble, log and drop the lock
|
||||
abort_alter() {
|
||||
zed_log_msg "Error updating zfs-list.cache for ${ZEVENT_POOL}!"
|
||||
zed_unlock "${FSLIST}"
|
||||
zed_log_msg "Error updating zfs-list.cache!"
|
||||
zed_unlock zfs-list
|
||||
}
|
||||
|
||||
finished() {
|
||||
zed_unlock "${FSLIST}"
|
||||
zed_unlock zfs-list
|
||||
trap - EXIT
|
||||
exit 0
|
||||
}
|
||||
|
@ -36,7 +37,7 @@ case "${ZEVENT_HISTORY_INTERNAL_NAME}" in
|
|||
;;
|
||||
|
||||
export)
|
||||
zed_lock "${FSLIST}"
|
||||
zed_lock zfs-list
|
||||
trap abort_alter EXIT
|
||||
echo > "${FSLIST}"
|
||||
finished
|
||||
|
@ -62,7 +63,7 @@ case "${ZEVENT_HISTORY_INTERNAL_NAME}" in
|
|||
;;
|
||||
esac
|
||||
|
||||
zed_lock "${FSLIST}"
|
||||
zed_lock zfs-list
|
||||
trap abort_alter EXIT
|
||||
|
||||
PROPS="name,mountpoint,canmount,atime,relatime,devices,exec\
|
||||
|
@ -78,7 +79,7 @@ PROPS="name,mountpoint,canmount,atime,relatime,devices,exec\
|
|||
sort "${FSLIST_TMP}" -o "${FSLIST_TMP}"
|
||||
|
||||
# Don't modify the file if it hasn't changed
|
||||
diff -q "${FSLIST_TMP}" "${FSLIST}" || cat "${FSLIST_TMP}" > "${FSLIST}"
|
||||
diff -q "${FSLIST_TMP}" "${FSLIST}" || mv "${FSLIST_TMP}" "${FSLIST}"
|
||||
rm -f "${FSLIST_TMP}"
|
||||
|
||||
finished
|
||||
|
|
|
@ -29,8 +29,7 @@
|
|||
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
|
||||
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
|
||||
|
||||
if [ ! -d /sys/class/enclosure ] && [ ! -d /sys/bus/pci/slots ] ; then
|
||||
# No JBOD enclosure or NVMe slots
|
||||
if [ ! -d /sys/class/enclosure ] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -93,29 +92,6 @@ check_and_set_led()
|
|||
done
|
||||
}
|
||||
|
||||
# Fault LEDs for JBODs and NVMe drives are handled a little differently.
|
||||
#
|
||||
# On JBODs the fault LED is called 'fault' and on a path like this:
|
||||
#
|
||||
# /sys/class/enclosure/0:0:1:0/SLOT 10/fault
|
||||
#
|
||||
# On NVMe it's called 'attention' and on a path like this:
|
||||
#
|
||||
# /sys/bus/pci/slot/0/attention
|
||||
#
|
||||
# This function returns the full path to the fault LED file for a given
|
||||
# enclosure/slot directory.
|
||||
#
|
||||
path_to_led()
|
||||
{
|
||||
dir=$1
|
||||
if [ -f "$dir/fault" ] ; then
|
||||
echo "$dir/fault"
|
||||
elif [ -f "$dir/attention" ] ; then
|
||||
echo "$dir/attention"
|
||||
fi
|
||||
}
|
||||
|
||||
state_to_val()
|
||||
{
|
||||
state="$1"
|
||||
|
@ -129,38 +105,6 @@ state_to_val()
|
|||
esac
|
||||
}
|
||||
|
||||
#
|
||||
# Given a nvme name like 'nvme0n1', pass back its slot directory
|
||||
# like "/sys/bus/pci/slots/0"
|
||||
#
|
||||
nvme_dev_to_slot()
|
||||
{
|
||||
dev="$1"
|
||||
|
||||
# Get the address "0000:01:00.0"
|
||||
address=$(cat "/sys/class/block/$dev/device/address")
|
||||
|
||||
# For each /sys/bus/pci/slots subdir that is an actual number
|
||||
# (rather than weird directories like "1-3/").
|
||||
# shellcheck disable=SC2010
|
||||
for i in $(ls /sys/bus/pci/slots/ | grep -E "^[0-9]+$") ; do
|
||||
this_address=$(cat "/sys/bus/pci/slots/$i/address")
|
||||
|
||||
# The format of address is a little different between
|
||||
# /sys/class/block/$dev/device/address and
|
||||
# /sys/bus/pci/slots/
|
||||
#
|
||||
# address= "0000:01:00.0"
|
||||
# this_address = "0000:01:00"
|
||||
#
|
||||
if echo "$address" | grep -Eq ^"$this_address" ; then
|
||||
echo "/sys/bus/pci/slots/$i"
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# process_pool (pool)
|
||||
#
|
||||
# Iterate through a pool and set the vdevs' enclosure slot LEDs to
|
||||
|
@ -190,11 +134,6 @@ process_pool()
|
|||
# Get dev name (like 'sda')
|
||||
dev=$(basename "$(echo "$therest" | awk '{print $(NF-1)}')")
|
||||
vdev_enc_sysfs_path=$(realpath "/sys/class/block/$dev/device/enclosure_device"*)
|
||||
if [ ! -d "$vdev_enc_sysfs_path" ] ; then
|
||||
# This is not a JBOD disk, but it could be a PCI NVMe drive
|
||||
vdev_enc_sysfs_path=$(nvme_dev_to_slot "$dev")
|
||||
fi
|
||||
|
||||
current_val=$(echo "$therest" | awk '{print $NF}')
|
||||
|
||||
if [ "$current_val" != "0" ] ; then
|
||||
|
@ -206,10 +145,9 @@ process_pool()
|
|||
continue
|
||||
fi
|
||||
|
||||
led_path=$(path_to_led "$vdev_enc_sysfs_path")
|
||||
if [ ! -e "$led_path" ] ; then
|
||||
if [ ! -e "$vdev_enc_sysfs_path/fault" ] ; then
|
||||
rc=3
|
||||
zed_log_msg "vdev $vdev '$led_path' doesn't exist"
|
||||
zed_log_msg "vdev $vdev '$file/fault' doesn't exist"
|
||||
continue
|
||||
fi
|
||||
|
||||
|
@ -220,7 +158,7 @@ process_pool()
|
|||
continue
|
||||
fi
|
||||
|
||||
if ! check_and_set_led "$led_path" "$val"; then
|
||||
if ! check_and_set_led "$vdev_enc_sysfs_path/fault" "$val"; then
|
||||
rc=3
|
||||
fi
|
||||
done
|
||||
|
@ -231,8 +169,7 @@ if [ -n "$ZEVENT_VDEV_ENC_SYSFS_PATH" ] && [ -n "$ZEVENT_VDEV_STATE_STR" ] ; the
|
|||
# Got a statechange for an individual vdev
|
||||
val=$(state_to_val "$ZEVENT_VDEV_STATE_STR")
|
||||
vdev=$(basename "$ZEVENT_VDEV_PATH")
|
||||
ledpath=$(path_to_led "$ZEVENT_VDEV_ENC_SYSFS_PATH")
|
||||
check_and_set_led "$ledpath" "$val"
|
||||
check_and_set_led "$ZEVENT_VDEV_ENC_SYSFS_PATH/fault" "$val"
|
||||
else
|
||||
# Process the entire pool
|
||||
poolname=$(zed_guid_to_pool "$ZEVENT_POOL_GUID")
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
# Send notification in response to a fault induced statechange
|
||||
#
|
||||
# ZEVENT_SUBCLASS: 'statechange'
|
||||
# ZEVENT_VDEV_STATE_STR: 'DEGRADED', 'FAULTED', 'REMOVED', or 'UNAVAIL'
|
||||
# ZEVENT_VDEV_STATE_STR: 'DEGRADED', 'FAULTED' or 'REMOVED'
|
||||
#
|
||||
# Exit codes:
|
||||
# 0: notification sent
|
||||
|
@ -31,13 +31,12 @@
|
|||
|
||||
if [ "${ZEVENT_VDEV_STATE_STR}" != "FAULTED" ] \
|
||||
&& [ "${ZEVENT_VDEV_STATE_STR}" != "DEGRADED" ] \
|
||||
&& [ "${ZEVENT_VDEV_STATE_STR}" != "REMOVED" ] \
|
||||
&& [ "${ZEVENT_VDEV_STATE_STR}" != "UNAVAIL" ]; then
|
||||
&& [ "${ZEVENT_VDEV_STATE_STR}" != "REMOVED" ]; then
|
||||
exit 3
|
||||
fi
|
||||
|
||||
umask 077
|
||||
note_subject="ZFS device fault for pool ${ZEVENT_POOL} on $(hostname)"
|
||||
note_subject="ZFS device fault for pool ${ZEVENT_POOL_GUID} on $(hostname)"
|
||||
note_pathname="$(mktemp)"
|
||||
{
|
||||
if [ "${ZEVENT_VDEV_STATE_STR}" = "FAULTED" ] ; then
|
||||
|
@ -65,7 +64,7 @@ note_pathname="$(mktemp)"
|
|||
[ -n "${ZEVENT_VDEV_GUID}" ] && echo " vguid: ${ZEVENT_VDEV_GUID}"
|
||||
[ -n "${ZEVENT_VDEV_DEVID}" ] && echo " devid: ${ZEVENT_VDEV_DEVID}"
|
||||
|
||||
echo " pool: ${ZEVENT_POOL} (${ZEVENT_POOL_GUID})"
|
||||
echo " pool: ${ZEVENT_POOL_GUID}"
|
||||
|
||||
} > "${note_pathname}"
|
||||
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
#!/bin/sh
|
||||
# shellcheck disable=SC3014,SC2154,SC2086,SC2034
|
||||
#
|
||||
# Turn off disk's enclosure slot if it becomes FAULTED.
|
||||
#
|
||||
# Bad SCSI disks can often "disappear and reappear" causing all sorts of chaos
|
||||
# as they flip between FAULTED and ONLINE. If
|
||||
# ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT is set in zed.rc, and the disk gets
|
||||
# FAULTED, then power down the slot via sysfs:
|
||||
#
|
||||
# /sys/class/enclosure/<enclosure>/<slot>/power_status
|
||||
#
|
||||
# We assume the user will be responsible for turning the slot back on again.
|
||||
#
|
||||
# Note that this script requires that your enclosure be supported by the
|
||||
# Linux SCSI Enclosure services (SES) driver. The script will do nothing
|
||||
# if you have no enclosure, or if your enclosure isn't supported.
|
||||
#
|
||||
# Exit codes:
|
||||
# 0: slot successfully powered off
|
||||
# 1: enclosure not available
|
||||
# 2: ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT disabled
|
||||
# 3: vdev was not FAULTED
|
||||
# 4: The enclosure sysfs path passed from ZFS does not exist
|
||||
# 5: Enclosure slot didn't actually turn off after we told it to
|
||||
|
||||
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
|
||||
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
|
||||
|
||||
if [ ! -d /sys/class/enclosure ] ; then
|
||||
# No JBOD enclosure or NVMe slots
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT}" != "1" ] ; then
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ "$ZEVENT_VDEV_STATE_STR" != "FAULTED" ] ; then
|
||||
exit 3
|
||||
fi
|
||||
|
||||
if [ ! -f "$ZEVENT_VDEV_ENC_SYSFS_PATH/power_status" ] ; then
|
||||
exit 4
|
||||
fi
|
||||
|
||||
# Turn off the slot and wait for sysfs to report that the slot is off.
|
||||
# It can take ~400ms on some enclosures and multiple retries may be needed.
|
||||
for i in $(seq 1 20) ; do
|
||||
echo "off" | tee "$ZEVENT_VDEV_ENC_SYSFS_PATH/power_status"
|
||||
|
||||
for j in $(seq 1 5) ; do
|
||||
if [ "$(cat $ZEVENT_VDEV_ENC_SYSFS_PATH/power_status)" == "off" ] ; then
|
||||
break 2
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
done
|
||||
|
||||
if [ "$(cat $ZEVENT_VDEV_ENC_SYSFS_PATH/power_status)" != "off" ] ; then
|
||||
exit 5
|
||||
fi
|
||||
|
||||
zed_log_msg "powered down slot $ZEVENT_VDEV_ENC_SYSFS_PATH for $ZEVENT_VDEV_PATH"
|
|
@ -77,7 +77,7 @@ zed_log_msg()
|
|||
zed_log_err()
|
||||
{
|
||||
logger -p "${ZED_SYSLOG_PRIORITY}" -t "${ZED_SYSLOG_TAG}" -- "error:" \
|
||||
"${0##*/}:""${ZEVENT_EID:+" eid=${ZEVENT_EID}:"}" "$@"
|
||||
"$(basename -- "$0"):""${ZEVENT_EID:+" eid=${ZEVENT_EID}:"}" "$@"
|
||||
}
|
||||
|
||||
|
||||
|
@ -126,8 +126,10 @@ zed_lock()
|
|||
|
||||
# Obtain a lock on the file bound to the given file descriptor.
|
||||
#
|
||||
eval "exec ${fd}>> '${lockfile}'"
|
||||
if ! err="$(flock --exclusive "${fd}" 2>&1)"; then
|
||||
eval "exec ${fd}> '${lockfile}'"
|
||||
err="$(flock --exclusive "${fd}" 2>&1)"
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ]; then
|
||||
zed_log_err "failed to lock \"${lockfile}\": ${err}"
|
||||
fi
|
||||
|
||||
|
@ -163,7 +165,9 @@ zed_unlock()
|
|||
fi
|
||||
|
||||
# Release the lock and close the file descriptor.
|
||||
if ! err="$(flock --unlock "${fd}" 2>&1)"; then
|
||||
err="$(flock --unlock "${fd}" 2>&1)"
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ]; then
|
||||
zed_log_err "failed to unlock \"${lockfile}\": ${err}"
|
||||
fi
|
||||
eval "exec ${fd}>&-"
|
||||
|
@ -202,10 +206,6 @@ zed_notify()
|
|||
[ "${rv}" -eq 0 ] && num_success=$((num_success + 1))
|
||||
[ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1))
|
||||
|
||||
zed_notify_pushover "${subject}" "${pathname}"; rv=$?
|
||||
[ "${rv}" -eq 0 ] && num_success=$((num_success + 1))
|
||||
[ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1))
|
||||
|
||||
[ "${num_success}" -gt 0 ] && return 0
|
||||
[ "${num_failure}" -gt 0 ] && return 1
|
||||
return 2
|
||||
|
@ -224,8 +224,6 @@ zed_notify()
|
|||
# ZED_EMAIL_OPTS. This undergoes the following keyword substitutions:
|
||||
# - @ADDRESS@ is replaced with the space-delimited recipient email address(es)
|
||||
# - @SUBJECT@ is replaced with the notification subject
|
||||
# If @SUBJECT@ was omited here, a "Subject: ..." header will be added to notification
|
||||
#
|
||||
#
|
||||
# Arguments
|
||||
# subject: notification subject
|
||||
|
@ -243,7 +241,7 @@ zed_notify()
|
|||
#
|
||||
zed_notify_email()
|
||||
{
|
||||
local subject="${1:-"ZED notification"}"
|
||||
local subject="$1"
|
||||
local pathname="${2:-"/dev/null"}"
|
||||
|
||||
: "${ZED_EMAIL_PROG:="mail"}"
|
||||
|
@ -260,30 +258,19 @@ zed_notify_email()
|
|||
[ -n "${subject}" ] || return 1
|
||||
if [ ! -r "${pathname}" ]; then
|
||||
zed_log_err \
|
||||
"${ZED_EMAIL_PROG##*/} cannot read \"${pathname}\""
|
||||
"$(basename "${ZED_EMAIL_PROG}") cannot read \"${pathname}\""
|
||||
return 1
|
||||
fi
|
||||
|
||||
# construct cmdline options
|
||||
ZED_EMAIL_OPTS_PARSED="$(echo "${ZED_EMAIL_OPTS}" \
|
||||
ZED_EMAIL_OPTS="$(echo "${ZED_EMAIL_OPTS}" \
|
||||
| sed -e "s/@ADDRESS@/${ZED_EMAIL_ADDR}/g" \
|
||||
-e "s/@SUBJECT@/${subject}/g")"
|
||||
|
||||
# pipe message to email prog
|
||||
# shellcheck disable=SC2086,SC2248
|
||||
{
|
||||
# no subject passed as option?
|
||||
if [ "${ZED_EMAIL_OPTS%@SUBJECT@*}" = "${ZED_EMAIL_OPTS}" ] ; then
|
||||
# inject subject header
|
||||
printf "Subject: %s\n" "${subject}"
|
||||
fi
|
||||
# output message
|
||||
cat "${pathname}"
|
||||
} |
|
||||
eval ${ZED_EMAIL_PROG} ${ZED_EMAIL_OPTS_PARSED} >/dev/null 2>&1
|
||||
# shellcheck disable=SC2086
|
||||
eval "${ZED_EMAIL_PROG}" ${ZED_EMAIL_OPTS} < "${pathname}" >/dev/null 2>&1
|
||||
rv=$?
|
||||
if [ "${rv}" -ne 0 ]; then
|
||||
zed_log_err "${ZED_EMAIL_PROG##*/} exit=${rv}"
|
||||
zed_log_err "$(basename "${ZED_EMAIL_PROG}") exit=${rv}"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
|
@ -430,7 +417,7 @@ zed_notify_slack_webhook()
|
|||
|
||||
# Construct the JSON message for posting.
|
||||
#
|
||||
msg_json="$(printf '{"text": "*%s*\\n%s"}' "${subject}" "${msg_body}" )"
|
||||
msg_json="$(printf '{"text": "*%s*\n%s"}' "${subject}" "${msg_body}" )"
|
||||
|
||||
# Send the POST request and check for errors.
|
||||
#
|
||||
|
@ -450,84 +437,6 @@ zed_notify_slack_webhook()
|
|||
return 0
|
||||
}
|
||||
|
||||
# zed_notify_pushover (subject, pathname)
|
||||
#
|
||||
# Send a notification via Pushover <https://pushover.net/>.
|
||||
# The access token (ZED_PUSHOVER_TOKEN) identifies this client to the
|
||||
# Pushover server. The user token (ZED_PUSHOVER_USER) defines the user or
|
||||
# group to which the notification will be sent.
|
||||
#
|
||||
# Requires curl and sed executables to be installed in the standard PATH.
|
||||
#
|
||||
# References
|
||||
# https://pushover.net/api
|
||||
#
|
||||
# Arguments
|
||||
# subject: notification subject
|
||||
# pathname: pathname containing the notification message (OPTIONAL)
|
||||
#
|
||||
# Globals
|
||||
# ZED_PUSHOVER_TOKEN
|
||||
# ZED_PUSHOVER_USER
|
||||
#
|
||||
# Return
|
||||
# 0: notification sent
|
||||
# 1: notification failed
|
||||
# 2: not configured
|
||||
#
|
||||
zed_notify_pushover()
|
||||
{
|
||||
local subject="$1"
|
||||
local pathname="${2:-"/dev/null"}"
|
||||
local msg_body
|
||||
local msg_out
|
||||
local msg_err
|
||||
local url="https://api.pushover.net/1/messages.json"
|
||||
|
||||
[ -n "${ZED_PUSHOVER_TOKEN}" ] && [ -n "${ZED_PUSHOVER_USER}" ] || return 2
|
||||
|
||||
if [ ! -r "${pathname}" ]; then
|
||||
zed_log_err "pushover cannot read \"${pathname}\""
|
||||
return 1
|
||||
fi
|
||||
|
||||
zed_check_cmd "curl" "sed" || return 1
|
||||
|
||||
# Read the message body in.
|
||||
#
|
||||
msg_body="$(cat "${pathname}")"
|
||||
|
||||
if [ -z "${msg_body}" ]
|
||||
then
|
||||
msg_body=$subject
|
||||
subject=""
|
||||
fi
|
||||
|
||||
# Send the POST request and check for errors.
|
||||
#
|
||||
msg_out="$( \
|
||||
curl \
|
||||
--form-string "token=${ZED_PUSHOVER_TOKEN}" \
|
||||
--form-string "user=${ZED_PUSHOVER_USER}" \
|
||||
--form-string "message=${msg_body}" \
|
||||
--form-string "title=${subject}" \
|
||||
"${url}" \
|
||||
2>/dev/null \
|
||||
)"; rv=$?
|
||||
if [ "${rv}" -ne 0 ]; then
|
||||
zed_log_err "curl exit=${rv}"
|
||||
return 1
|
||||
fi
|
||||
msg_err="$(echo "${msg_out}" \
|
||||
| sed -n -e 's/.*"errors" *:.*\[\(.*\)\].*/\1/p')"
|
||||
if [ -n "${msg_err}" ]; then
|
||||
zed_log_err "pushover \"${msg_err}"\"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# zed_rate_limit (tag, [interval])
|
||||
#
|
||||
# Check whether an event of a given type [tag] has already occurred within the
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
# Email address of the zpool administrator for receipt of notifications;
|
||||
# multiple addresses can be specified if they are delimited by whitespace.
|
||||
# Email will only be sent if ZED_EMAIL_ADDR is defined.
|
||||
# Enabled by default; comment to disable.
|
||||
# Disabled by default; uncomment to enable.
|
||||
#
|
||||
ZED_EMAIL_ADDR="root"
|
||||
#ZED_EMAIL_ADDR="root"
|
||||
|
||||
##
|
||||
# Name or path of executable responsible for sending notifications via email;
|
||||
|
@ -30,7 +30,6 @@ ZED_EMAIL_ADDR="root"
|
|||
# The string @SUBJECT@ will be replaced with the notification subject;
|
||||
# this should be protected with quotes to prevent word-splitting.
|
||||
# Email will only be sent if ZED_EMAIL_ADDR is defined.
|
||||
# If @SUBJECT@ was omited here, a "Subject: ..." header will be added to notification
|
||||
#
|
||||
#ZED_EMAIL_OPTS="-s '@SUBJECT@' @ADDRESS@"
|
||||
|
||||
|
@ -83,23 +82,6 @@ ZED_EMAIL_ADDR="root"
|
|||
#
|
||||
#ZED_SLACK_WEBHOOK_URL=""
|
||||
|
||||
##
|
||||
# Pushover token.
|
||||
# This defines the application from which the notification will be sent.
|
||||
# <https://pushover.net/api#registration>
|
||||
# Disabled by default; uncomment to enable.
|
||||
# ZED_PUSHOVER_USER, below, must also be configured.
|
||||
#
|
||||
#ZED_PUSHOVER_TOKEN=""
|
||||
|
||||
##
|
||||
# Pushover user key.
|
||||
# This defines which user or group will receive Pushover notifications.
|
||||
# <https://pushover.net/api#identifiers>
|
||||
# Disabled by default; uncomment to enable.
|
||||
# ZED_PUSHOVER_TOKEN, above, must also be configured.
|
||||
#ZED_PUSHOVER_USER=""
|
||||
|
||||
##
|
||||
# Default directory for zed state files.
|
||||
#
|
||||
|
@ -107,8 +89,8 @@ ZED_EMAIL_ADDR="root"
|
|||
|
||||
##
|
||||
# Turn on/off enclosure LEDs when drives get DEGRADED/FAULTED. This works for
|
||||
# device mapper and multipath devices as well. This works with JBOD enclosures
|
||||
# and NVMe PCI drives (assuming they're supported by Linux in sysfs).
|
||||
# device mapper and multipath devices as well. Your enclosure must be
|
||||
# supported by the Linux SES driver for this to work.
|
||||
#
|
||||
ZED_USE_ENCLOSURE_LEDS=1
|
||||
|
||||
|
@ -143,8 +125,3 @@ ZED_SYSLOG_SUBCLASS_EXCLUDE="history_event"
|
|||
# Disabled by default, 1 to enable and 0 to disable.
|
||||
#ZED_SYSLOG_DISPLAY_GUIDS=1
|
||||
|
||||
##
|
||||
# Power off the drive's slot in the enclosure if it becomes FAULTED. This can
|
||||
# help silence misbehaving drives. This assumes your drive enclosure fully
|
||||
# supports slot power control via sysfs.
|
||||
#ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT=1
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
@ -72,14 +72,10 @@ zed_udev_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_PATH, strval);
|
||||
if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &strval) == 0)
|
||||
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_IDENTIFIER, strval);
|
||||
if (nvlist_lookup_boolean(nvl, DEV_IS_PART) == B_TRUE)
|
||||
zed_log_msg(LOG_INFO, "\t%s: B_TRUE", DEV_IS_PART);
|
||||
if (nvlist_lookup_string(nvl, DEV_PHYS_PATH, &strval) == 0)
|
||||
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_PHYS_PATH, strval);
|
||||
if (nvlist_lookup_uint64(nvl, DEV_SIZE, &numval) == 0)
|
||||
zed_log_msg(LOG_INFO, "\t%s: %llu", DEV_SIZE, numval);
|
||||
if (nvlist_lookup_uint64(nvl, DEV_PARENT_SIZE, &numval) == 0)
|
||||
zed_log_msg(LOG_INFO, "\t%s: %llu", DEV_PARENT_SIZE, numval);
|
||||
if (nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &numval) == 0)
|
||||
zed_log_msg(LOG_INFO, "\t%s: %llu", ZFS_EV_POOL_GUID, numval);
|
||||
if (nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &numval) == 0)
|
||||
|
@ -132,20 +128,6 @@ dev_event_nvlist(struct udev_device *dev)
|
|||
|
||||
numval *= strtoull(value, NULL, 10);
|
||||
(void) nvlist_add_uint64(nvl, DEV_SIZE, numval);
|
||||
|
||||
/*
|
||||
* If the device has a parent, then get the parent block
|
||||
* device's size as well. For example, /dev/sda1's parent
|
||||
* is /dev/sda.
|
||||
*/
|
||||
struct udev_device *parent_dev = udev_device_get_parent(dev);
|
||||
if ((value = udev_device_get_sysattr_value(parent_dev, "size"))
|
||||
!= NULL) {
|
||||
uint64_t numval = DEV_BSIZE;
|
||||
|
||||
numval *= strtoull(value, NULL, 10);
|
||||
(void) nvlist_add_uint64(nvl, DEV_PARENT_SIZE, numval);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -185,7 +167,7 @@ zed_udev_monitor(void *arg)
|
|||
while (1) {
|
||||
struct udev_device *dev;
|
||||
const char *action, *type, *part, *sectors;
|
||||
const char *bus, *uuid, *devpath;
|
||||
const char *bus, *uuid;
|
||||
const char *class, *subclass;
|
||||
nvlist_t *nvl;
|
||||
boolean_t is_zfs = B_FALSE;
|
||||
|
@ -224,12 +206,6 @@ zed_udev_monitor(void *arg)
|
|||
* if this is a disk and it is partitioned, then the
|
||||
* zfs label will reside in a DEVTYPE=partition and
|
||||
* we can skip passing this event
|
||||
*
|
||||
* Special case: Blank disks are sometimes reported with
|
||||
* an erroneous 'atari' partition, and should not be
|
||||
* excluded from being used as an autoreplace disk:
|
||||
*
|
||||
* https://github.com/openzfs/zfs/issues/13497
|
||||
*/
|
||||
type = udev_device_get_property_value(dev, "DEVTYPE");
|
||||
part = udev_device_get_property_value(dev,
|
||||
|
@ -237,23 +213,9 @@ zed_udev_monitor(void *arg)
|
|||
if (type != NULL && type[0] != '\0' &&
|
||||
strcmp(type, "disk") == 0 &&
|
||||
part != NULL && part[0] != '\0') {
|
||||
const char *devname =
|
||||
udev_device_get_property_value(dev, "DEVNAME");
|
||||
|
||||
if (strcmp(part, "atari") == 0) {
|
||||
zed_log_msg(LOG_INFO,
|
||||
"%s: %s is reporting an atari partition, "
|
||||
"but we're going to assume it's a false "
|
||||
"positive and still use it (issue #13497)",
|
||||
__func__, devname);
|
||||
} else {
|
||||
zed_log_msg(LOG_INFO,
|
||||
"%s: skip %s since it has a %s partition "
|
||||
"already", __func__, devname, part);
|
||||
/* skip and wait for partition event */
|
||||
udev_device_unref(dev);
|
||||
continue;
|
||||
}
|
||||
/* skip and wait for partition event */
|
||||
udev_device_unref(dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -265,11 +227,6 @@ zed_udev_monitor(void *arg)
|
|||
sectors = udev_device_get_sysattr_value(dev, "size");
|
||||
if (sectors != NULL &&
|
||||
strtoull(sectors, NULL, 10) < MINIMUM_SECTORS) {
|
||||
zed_log_msg(LOG_INFO,
|
||||
"%s: %s sectors %s < %llu (minimum)",
|
||||
__func__,
|
||||
udev_device_get_property_value(dev, "DEVNAME"),
|
||||
sectors, MINIMUM_SECTORS);
|
||||
udev_device_unref(dev);
|
||||
continue;
|
||||
}
|
||||
|
@ -279,19 +236,10 @@ zed_udev_monitor(void *arg)
|
|||
* device id string is required in the message schema
|
||||
* for matching with vdevs. Preflight here for expected
|
||||
* udev information.
|
||||
*
|
||||
* Special case:
|
||||
* NVMe devices don't have ID_BUS set (at least on RHEL 7-8),
|
||||
* but they are valid for autoreplace. Add a special case for
|
||||
* them by searching for "/nvme/" in the udev DEVPATH:
|
||||
*
|
||||
* DEVPATH=/devices/pci0000:00/0000:00:1e.0/nvme/nvme2/nvme2n1
|
||||
*/
|
||||
bus = udev_device_get_property_value(dev, "ID_BUS");
|
||||
uuid = udev_device_get_property_value(dev, "DM_UUID");
|
||||
devpath = udev_device_get_devpath(dev);
|
||||
if (!is_zfs && (bus == NULL && uuid == NULL &&
|
||||
strstr(devpath, "/nvme/") == NULL)) {
|
||||
if (!is_zfs && (bus == NULL && uuid == NULL)) {
|
||||
zed_log_msg(LOG_INFO, "zed_udev_monitor: %s no devid "
|
||||
"source", udev_device_get_devnode(dev));
|
||||
udev_device_unref(dev);
|
||||
|
@ -402,7 +350,7 @@ zed_udev_monitor(void *arg)
|
|||
}
|
||||
|
||||
int
|
||||
zed_disk_event_init(void)
|
||||
zed_disk_event_init()
|
||||
{
|
||||
int fd, fflags;
|
||||
|
||||
|
@ -438,7 +386,7 @@ zed_disk_event_init(void)
|
|||
}
|
||||
|
||||
void
|
||||
zed_disk_event_fini(void)
|
||||
zed_disk_event_fini()
|
||||
{
|
||||
/* cancel monitor thread at recvmsg() */
|
||||
(void) pthread_cancel(g_mon_tid);
|
||||
|
@ -456,13 +404,13 @@ zed_disk_event_fini(void)
|
|||
#include "zed_disk_event.h"
|
||||
|
||||
int
|
||||
zed_disk_event_init(void)
|
||||
zed_disk_event_init()
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
zed_disk_event_fini(void)
|
||||
zed_disk_event_fini()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include "zed_strings.h"
|
||||
|
||||
#include "agents/zfs_agents.h"
|
||||
#include <libzutil.h>
|
||||
|
||||
#define MAXBUF 4096
|
||||
|
||||
|
@ -908,25 +907,6 @@ _zed_event_add_time_strings(uint64_t eid, zed_strings_t *zsp, int64_t etime[])
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_zed_event_update_enc_sysfs_path(nvlist_t *nvl)
|
||||
{
|
||||
char *vdev_path;
|
||||
|
||||
if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_PATH,
|
||||
&vdev_path) != 0) {
|
||||
return; /* some other kind of event, ignore it */
|
||||
}
|
||||
|
||||
if (vdev_path == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
update_vdev_config_dev_sysfs_path(nvl, vdev_path,
|
||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_ENC_SYSFS_PATH);
|
||||
}
|
||||
|
||||
/*
|
||||
* Service the next zevent, blocking until one is available.
|
||||
*/
|
||||
|
@ -974,17 +954,6 @@ zed_event_service(struct zed_conf *zcp)
|
|||
zed_log_msg(LOG_WARNING,
|
||||
"Failed to lookup zevent class (eid=%llu)", eid);
|
||||
} else {
|
||||
/*
|
||||
* Special case: If we can dynamically detect an enclosure sysfs
|
||||
* path, then use that value rather than the one stored in the
|
||||
* vd->vdev_enc_sysfs_path. There have been rare cases where
|
||||
* vd->vdev_enc_sysfs_path becomes outdated. However, there
|
||||
* will be other times when we can not dynamically detect the
|
||||
* sysfs path (like if a disk disappears) and have to rely on
|
||||
* the old value for things like turning on the fault LED.
|
||||
*/
|
||||
_zed_event_update_enc_sysfs_path(nvl);
|
||||
|
||||
/* let internal modules see this event first */
|
||||
zfs_agent_post_event(class, NULL, nvl);
|
||||
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "zed_exec.h"
|
||||
#include "zed_log.h"
|
||||
#include "zed_strings.h"
|
||||
|
|
|
@ -315,14 +315,14 @@ get_usage(zfs_help_t idx)
|
|||
case HELP_ROLLBACK:
|
||||
return (gettext("\trollback [-rRf] <snapshot>\n"));
|
||||
case HELP_SEND:
|
||||
return (gettext("\tsend [-DnPpRVvLecwhb] [-[i|I] snapshot] "
|
||||
return (gettext("\tsend [-DnPpRvLecwhb] [-[i|I] snapshot] "
|
||||
"<snapshot>\n"
|
||||
"\tsend [-DnVvPLecw] [-i snapshot|bookmark] "
|
||||
"\tsend [-nvPLecw] [-i snapshot|bookmark] "
|
||||
"<filesystem|volume|snapshot>\n"
|
||||
"\tsend [-DnPpVvLec] [-i bookmark|snapshot] "
|
||||
"\tsend [-DnPpvLec] [-i bookmark|snapshot] "
|
||||
"--redact <bookmark> <snapshot>\n"
|
||||
"\tsend [-nVvPe] -t <receive_resume_token>\n"
|
||||
"\tsend [-PnVv] --saved filesystem\n"));
|
||||
"\tsend [-nvPe] -t <receive_resume_token>\n"
|
||||
"\tsend [-Pnv] --saved filesystem\n"));
|
||||
case HELP_SET:
|
||||
return (gettext("\tset <property=value> ... "
|
||||
"<filesystem|volume|snapshot> ...\n"));
|
||||
|
@ -535,7 +535,7 @@ usage(boolean_t requested)
|
|||
show_properties = B_TRUE;
|
||||
|
||||
if (show_properties) {
|
||||
(void) fprintf(fp, "%s",
|
||||
(void) fprintf(fp,
|
||||
gettext("\nThe following properties are supported:\n"));
|
||||
|
||||
(void) fprintf(fp, "\n\t%-14s %s %s %s\n\n",
|
||||
|
@ -728,32 +728,6 @@ finish_progress(char *done)
|
|||
pt_header = NULL;
|
||||
}
|
||||
|
||||
/* This function checks if the passed fd refers to /dev/null or /dev/zero */
|
||||
#ifdef __linux__
|
||||
static boolean_t
|
||||
is_dev_nullzero(int fd)
|
||||
{
|
||||
struct stat st;
|
||||
fstat(fd, &st);
|
||||
return (major(st.st_rdev) == 1 && (minor(st.st_rdev) == 3 /* null */ ||
|
||||
minor(st.st_rdev) == 5 /* zero */));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
note_dev_error(int err, int fd)
|
||||
{
|
||||
#ifdef __linux__
|
||||
if (err == EINVAL && is_dev_nullzero(fd)) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("Error: Writing directly to /dev/{null,zero} files"
|
||||
" on certain kernels is not currently implemented.\n"
|
||||
"(As a workaround, "
|
||||
"try \"zfs send [...] | cat > /dev/null\")\n"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_mount_and_share(libzfs_handle_t *hdl, const char *dataset, zfs_type_t type)
|
||||
{
|
||||
|
@ -2480,7 +2454,7 @@ upgrade_set_callback(zfs_handle_t *zhp, void *data)
|
|||
|
||||
/* upgrade */
|
||||
if (version < cb->cb_version) {
|
||||
char verstr[24];
|
||||
char verstr[16];
|
||||
(void) snprintf(verstr, sizeof (verstr),
|
||||
"%llu", (u_longlong_t)cb->cb_version);
|
||||
if (cb->cb_lastfs[0] && !same_pool(zhp, cb->cb_lastfs)) {
|
||||
|
@ -3474,8 +3448,6 @@ print_header(list_cbdata_t *cb)
|
|||
boolean_t first = B_TRUE;
|
||||
boolean_t right_justify;
|
||||
|
||||
color_start(ANSI_BOLD);
|
||||
|
||||
for (; pl != NULL; pl = pl->pl_next) {
|
||||
if (!first) {
|
||||
(void) printf(" ");
|
||||
|
@ -3502,31 +3474,9 @@ print_header(list_cbdata_t *cb)
|
|||
(void) printf("%-*s", (int)pl->pl_width, header);
|
||||
}
|
||||
|
||||
color_end();
|
||||
|
||||
(void) printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Decides on the color that the avail value should be printed in.
|
||||
* > 80% used = yellow
|
||||
* > 90% used = red
|
||||
*/
|
||||
static const char *
|
||||
zfs_list_avail_color(zfs_handle_t *zhp)
|
||||
{
|
||||
uint64_t used = zfs_prop_get_int(zhp, ZFS_PROP_USED);
|
||||
uint64_t avail = zfs_prop_get_int(zhp, ZFS_PROP_AVAILABLE);
|
||||
int percentage = (int)((double)avail / MAX(avail + used, 1) * 100);
|
||||
|
||||
if (percentage > 20)
|
||||
return (NULL);
|
||||
else if (percentage > 10)
|
||||
return (ANSI_YELLOW);
|
||||
else
|
||||
return (ANSI_RED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a dataset and a list of fields, print out all the properties according
|
||||
* to the described layout.
|
||||
|
@ -3589,22 +3539,6 @@ print_dataset(zfs_handle_t *zhp, list_cbdata_t *cb)
|
|||
right_justify = B_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* zfs_list_avail_color() needs ZFS_PROP_AVAILABLE + USED
|
||||
* - so we need another for() search for the USED part
|
||||
* - when no colors wanted, we can skip the whole thing
|
||||
*/
|
||||
if (use_color() && pl->pl_prop == ZFS_PROP_AVAILABLE) {
|
||||
zprop_list_t *pl2 = cb->cb_proplist;
|
||||
for (; pl2 != NULL; pl2 = pl2->pl_next) {
|
||||
if (pl2->pl_prop == ZFS_PROP_USED) {
|
||||
color_start(zfs_list_avail_color(zhp));
|
||||
/* found it, no need for more loops */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is being called in scripted mode, or if this is the
|
||||
* last column and it is left-justified, don't include a width
|
||||
|
@ -3616,9 +3550,6 @@ print_dataset(zfs_handle_t *zhp, list_cbdata_t *cb)
|
|||
(void) printf("%*s", (int)pl->pl_width, propstr);
|
||||
else
|
||||
(void) printf("%-*s", (int)pl->pl_width, propstr);
|
||||
|
||||
if (pl->pl_prop == ZFS_PROP_AVAILABLE)
|
||||
color_end();
|
||||
}
|
||||
|
||||
(void) printf("\n");
|
||||
|
@ -4450,7 +4381,6 @@ zfs_do_send(int argc, char **argv)
|
|||
{"props", no_argument, NULL, 'p'},
|
||||
{"parsable", no_argument, NULL, 'P'},
|
||||
{"dedup", no_argument, NULL, 'D'},
|
||||
{"proctitle", no_argument, NULL, 'V'},
|
||||
{"verbose", no_argument, NULL, 'v'},
|
||||
{"dryrun", no_argument, NULL, 'n'},
|
||||
{"large-block", no_argument, NULL, 'L'},
|
||||
|
@ -4465,7 +4395,7 @@ zfs_do_send(int argc, char **argv)
|
|||
};
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt_long(argc, argv, ":i:I:RsDpVvnPLeht:cwbd:S",
|
||||
while ((c = getopt_long(argc, argv, ":i:I:RsDpvnPLeht:cwbd:S",
|
||||
long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'i':
|
||||
|
@ -4500,9 +4430,6 @@ zfs_do_send(int argc, char **argv)
|
|||
case 'P':
|
||||
flags.parsable = B_TRUE;
|
||||
break;
|
||||
case 'V':
|
||||
flags.progressastitle = B_TRUE;
|
||||
break;
|
||||
case 'v':
|
||||
flags.verbosity++;
|
||||
flags.progress = B_TRUE;
|
||||
|
@ -4578,7 +4505,7 @@ zfs_do_send(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if ((flags.parsable || flags.progressastitle) && flags.verbosity == 0)
|
||||
if (flags.parsable && flags.verbosity == 0)
|
||||
flags.verbosity = 1;
|
||||
|
||||
argc -= optind;
|
||||
|
@ -4645,16 +4572,11 @@ zfs_do_send(int argc, char **argv)
|
|||
|
||||
err = zfs_send_saved(zhp, &flags, STDOUT_FILENO,
|
||||
resume_token);
|
||||
if (err != 0)
|
||||
note_dev_error(errno, STDOUT_FILENO);
|
||||
zfs_close(zhp);
|
||||
return (err != 0);
|
||||
} else if (resume_token != NULL) {
|
||||
err = zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
|
||||
resume_token);
|
||||
if (err != 0)
|
||||
note_dev_error(errno, STDOUT_FILENO);
|
||||
return (err);
|
||||
return (zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
|
||||
resume_token));
|
||||
}
|
||||
|
||||
if (flags.skipmissing && !flags.replicate) {
|
||||
|
@ -4705,8 +4627,6 @@ zfs_do_send(int argc, char **argv)
|
|||
err = zfs_send_one(zhp, fromname, STDOUT_FILENO, &flags,
|
||||
redactbook);
|
||||
zfs_close(zhp);
|
||||
if (err != 0)
|
||||
note_dev_error(errno, STDOUT_FILENO);
|
||||
return (err != 0);
|
||||
}
|
||||
|
||||
|
@ -4783,7 +4703,6 @@ zfs_do_send(int argc, char **argv)
|
|||
nvlist_free(dbgnv);
|
||||
}
|
||||
zfs_close(zhp);
|
||||
note_dev_error(errno, STDOUT_FILENO);
|
||||
|
||||
return (err != 0);
|
||||
}
|
||||
|
@ -6640,7 +6559,7 @@ zfs_do_holds(int argc, char **argv)
|
|||
/*
|
||||
* 1. collect holds data, set format options
|
||||
*/
|
||||
ret = zfs_for_each(1, argv + i, flags, types, NULL, NULL, limit,
|
||||
ret = zfs_for_each(argc, argv, flags, types, NULL, NULL, limit,
|
||||
holds_callback, &cb);
|
||||
if (ret != 0)
|
||||
++errors;
|
||||
|
@ -7522,7 +7441,6 @@ unshare_unmount(int op, int argc, char **argv)
|
|||
if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) ==
|
||||
ZFS_CANMOUNT_NOAUTO)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -7719,7 +7637,7 @@ zfs_do_diff(int argc, char **argv)
|
|||
int c;
|
||||
struct sigaction sa;
|
||||
|
||||
while ((c = getopt(argc, argv, "FHth")) != -1) {
|
||||
while ((c = getopt(argc, argv, "FHt")) != -1) {
|
||||
switch (c) {
|
||||
case 'F':
|
||||
flags |= ZFS_DIFF_CLASSIFY;
|
||||
|
@ -7730,9 +7648,6 @@ zfs_do_diff(int argc, char **argv)
|
|||
case 't':
|
||||
flags |= ZFS_DIFF_TIMESTAMP;
|
||||
break;
|
||||
case 'h':
|
||||
flags |= ZFS_DIFF_NO_MANGLE;
|
||||
break;
|
||||
default:
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid option '%c'\n"), optopt);
|
||||
|
@ -8582,7 +8497,7 @@ static int
|
|||
zfs_do_wait(int argc, char **argv)
|
||||
{
|
||||
boolean_t enabled[ZFS_WAIT_NUM_ACTIVITIES];
|
||||
int error = 0, i;
|
||||
int error, i;
|
||||
int c;
|
||||
|
||||
/* By default, wait for all types of activity. */
|
||||
|
@ -8740,8 +8655,6 @@ main(int argc, char **argv)
|
|||
|
||||
libzfs_print_on_error(g_zfs, B_TRUE);
|
||||
|
||||
zfs_setproctitle_init(argc, argv, environ);
|
||||
|
||||
/*
|
||||
* Many commands modify input strings for string parsing reasons.
|
||||
* We create a copy to protect the original argv.
|
||||
|
|
|
@ -207,6 +207,7 @@ static int
|
|||
zfs_project_handle_dir(const char *name, zfs_project_control_t *zpc,
|
||||
list_t *head)
|
||||
{
|
||||
char fullname[PATH_MAX];
|
||||
struct dirent *ent;
|
||||
DIR *dir;
|
||||
int ret = 0;
|
||||
|
@ -226,28 +227,21 @@ zfs_project_handle_dir(const char *name, zfs_project_control_t *zpc,
|
|||
zpc->zpc_ignore_noent = B_TRUE;
|
||||
errno = 0;
|
||||
while (!ret && (ent = readdir(dir)) != NULL) {
|
||||
char *fullname;
|
||||
|
||||
/* skip "." and ".." */
|
||||
if (strcmp(ent->d_name, ".") == 0 ||
|
||||
strcmp(ent->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
if (strlen(ent->d_name) + strlen(name) + 1 >= PATH_MAX) {
|
||||
if (strlen(ent->d_name) + strlen(name) >=
|
||||
sizeof (fullname) + 1) {
|
||||
errno = ENAMETOOLONG;
|
||||
break;
|
||||
}
|
||||
|
||||
if (asprintf(&fullname, "%s/%s", name, ent->d_name) == -1) {
|
||||
errno = ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(fullname, "%s/%s", name, ent->d_name);
|
||||
ret = zfs_project_handle_one(fullname, zpc);
|
||||
if (!ret && zpc->zpc_recursive && ent->d_type == DT_DIR)
|
||||
zfs_project_item_alloc(head, fullname);
|
||||
|
||||
free(fullname);
|
||||
}
|
||||
|
||||
if (errno && !ret) {
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void usage(void);
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
@ -58,11 +60,12 @@ int
|
|||
main(int argc, char **argv)
|
||||
{
|
||||
/* default file path, can be optionally set by user */
|
||||
const char *path = "/etc/hostid";
|
||||
char path[PATH_MAX] = "/etc/hostid";
|
||||
/* holds converted user input or lrand48() generated value */
|
||||
unsigned long input_i = 0;
|
||||
|
||||
int opt;
|
||||
int pathlen;
|
||||
int force_fwrite = 0;
|
||||
while ((opt = getopt_long(argc, argv, "fo:h?", 0, 0)) != -1) {
|
||||
switch (opt) {
|
||||
|
@ -70,7 +73,14 @@ main(int argc, char **argv)
|
|||
force_fwrite = 1;
|
||||
break;
|
||||
case 'o':
|
||||
path = optarg;
|
||||
pathlen = snprintf(path, sizeof (path), "%s", optarg);
|
||||
if (pathlen >= sizeof (path)) {
|
||||
fprintf(stderr, "%s\n", strerror(EOVERFLOW));
|
||||
exit(EXIT_FAILURE);
|
||||
} else if (pathlen < 1) {
|
||||
fprintf(stderr, "%s\n", strerror(EINVAL));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
|
@ -108,7 +118,7 @@ main(int argc, char **argv)
|
|||
if (force_fwrite == 0 && stat(path, &fstat) == 0 &&
|
||||
S_ISREG(fstat.st_mode)) {
|
||||
fprintf(stderr, "%s: %s\n", path, strerror(EEXIST));
|
||||
exit(EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
include $(top_srcdir)/config/Rules.am
|
||||
include $(top_srcdir)/config/Shellcheck.am
|
||||
|
||||
AM_CFLAGS += $(LIBBLKID_CFLAGS) $(LIBUUID_CFLAGS)
|
||||
|
||||
|
@ -26,8 +25,7 @@ zpool_LDADD = \
|
|||
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
||||
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||
$(abs_top_builddir)/lib/libnvpair/libnvpair.la \
|
||||
$(abs_top_builddir)/lib/libuutil/libuutil.la \
|
||||
$(abs_top_builddir)/lib/libzutil/libzutil.la
|
||||
$(abs_top_builddir)/lib/libuutil/libuutil.la
|
||||
|
||||
zpool_LDADD += $(LTLIBINTL)
|
||||
|
||||
|
|
|
@ -101,39 +101,3 @@ check_sector_size_database(char *path, int *sector_size)
|
|||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
after_zpool_upgrade(zpool_handle_t *zhp)
|
||||
{
|
||||
char bootfs[ZPOOL_MAXPROPLEN];
|
||||
|
||||
if (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
|
||||
sizeof (bootfs), NULL, B_FALSE) == 0 &&
|
||||
strcmp(bootfs, "-") != 0) {
|
||||
(void) printf(gettext("Pool '%s' has the bootfs "
|
||||
"property set, you might need to update\nthe boot "
|
||||
"code. See gptzfsboot(8) and loader.efi(8) for "
|
||||
"details.\n"), zpool_get_name(zhp));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
zpool_power_current_state(zpool_handle_t *zhp, char *vdev)
|
||||
{
|
||||
|
||||
(void) zhp;
|
||||
(void) vdev;
|
||||
/* Enclosure slot power not supported on FreeBSD yet */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
zpool_power(zpool_handle_t *zhp, char *vdev, boolean_t turn_on)
|
||||
{
|
||||
|
||||
(void) zhp;
|
||||
(void) vdev;
|
||||
(void) turn_on;
|
||||
/* Enclosure slot power not supported on FreeBSD yet */
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
|
|
@ -405,263 +405,3 @@ check_device(const char *path, boolean_t force,
|
|||
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
after_zpool_upgrade(zpool_handle_t *zhp)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from a sysfs file and return an allocated string. Removes
|
||||
* the newline from the end of the string if there is one.
|
||||
*
|
||||
* Returns a string on success (which must be freed), or NULL on error.
|
||||
*/
|
||||
static char *zpool_sysfs_gets(char *path)
|
||||
{
|
||||
int fd;
|
||||
struct stat statbuf;
|
||||
char *buf = NULL;
|
||||
ssize_t count = 0;
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return (NULL);
|
||||
|
||||
if (fstat(fd, &statbuf) != 0) {
|
||||
close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
buf = calloc(sizeof (*buf), statbuf.st_size + 1);
|
||||
if (buf == NULL) {
|
||||
close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note, we can read less bytes than st_size, and that's ok. Sysfs
|
||||
* files will report their size is 4k even if they only return a small
|
||||
* string.
|
||||
*/
|
||||
count = read(fd, buf, statbuf.st_size);
|
||||
if (count < 0) {
|
||||
/* Error doing read() or we overran the buffer */
|
||||
close(fd);
|
||||
free(buf);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Remove trailing newline */
|
||||
if (buf[count - 1] == '\n')
|
||||
buf[count - 1] = 0;
|
||||
|
||||
close(fd);
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a string to a sysfs file.
|
||||
*
|
||||
* Returns 0 on success, non-zero otherwise.
|
||||
*/
|
||||
static int zpool_sysfs_puts(char *path, char *str)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
file = fopen(path, "w");
|
||||
if (!file) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (fputs(str, file) < 0) {
|
||||
fclose(file);
|
||||
return (-2);
|
||||
}
|
||||
fclose(file);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Given a vdev nvlist_t, rescan its enclosure sysfs path */
|
||||
static void
|
||||
rescan_vdev_config_dev_sysfs_path(nvlist_t *vdev_nv)
|
||||
{
|
||||
update_vdev_config_dev_sysfs_path(vdev_nv,
|
||||
fnvlist_lookup_string(vdev_nv, ZPOOL_CONFIG_PATH),
|
||||
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a power string: "on", "off", "1", or "0", return 0 if it's an
|
||||
* off value, 1 if it's an on value, and -1 if the value is unrecognized.
|
||||
*/
|
||||
static int zpool_power_parse_value(char *str)
|
||||
{
|
||||
if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0))
|
||||
return (0);
|
||||
|
||||
if ((strcmp(str, "on") == 0) || (strcmp(str, "1") == 0))
|
||||
return (1);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a vdev string return an allocated string containing the sysfs path to
|
||||
* its power control file. Also do a check if the power control file really
|
||||
* exists and has correct permissions.
|
||||
*
|
||||
* Example returned strings:
|
||||
*
|
||||
* /sys/class/enclosure/0:0:122:0/10/power_status
|
||||
* /sys/bus/pci/slots/10/power
|
||||
*
|
||||
* Returns allocated string on success (which must be freed), NULL on failure.
|
||||
*/
|
||||
static char *
|
||||
zpool_power_sysfs_path(zpool_handle_t *zhp, char *vdev)
|
||||
{
|
||||
char *enc_sysfs_dir = NULL;
|
||||
char *path = NULL;
|
||||
nvlist_t *vdev_nv = zpool_find_vdev(zhp, vdev, NULL, NULL, NULL);
|
||||
|
||||
if (vdev_nv == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Make sure we're getting the updated enclosure sysfs path */
|
||||
rescan_vdev_config_dev_sysfs_path(vdev_nv);
|
||||
|
||||
if (nvlist_lookup_string(vdev_nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
|
||||
&enc_sysfs_dir) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (asprintf(&path, "%s/power_status", enc_sysfs_dir) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (access(path, W_OK) != 0) {
|
||||
free(path);
|
||||
path = NULL;
|
||||
/* No HDD 'power_control' file, maybe it's NVMe? */
|
||||
if (asprintf(&path, "%s/power", enc_sysfs_dir) == -1) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (access(path, R_OK | W_OK) != 0) {
|
||||
/* Not NVMe either */
|
||||
free(path);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return (path);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a path to a sysfs power control file, return B_TRUE if you should use
|
||||
* "on/off" words to control it, or B_FALSE otherwise ("0/1" to control).
|
||||
*/
|
||||
static boolean_t
|
||||
zpool_power_use_word(char *sysfs_path)
|
||||
{
|
||||
if (strcmp(&sysfs_path[strlen(sysfs_path) - strlen("power_status")],
|
||||
"power_status") == 0) {
|
||||
return (B_TRUE);
|
||||
}
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the sysfs power control value for a vdev.
|
||||
*
|
||||
* Returns:
|
||||
* 0 - Power is off
|
||||
* 1 - Power is on
|
||||
* -1 - Error or unsupported
|
||||
*/
|
||||
int
|
||||
zpool_power_current_state(zpool_handle_t *zhp, char *vdev)
|
||||
{
|
||||
char *val;
|
||||
int rc;
|
||||
|
||||
char *path = zpool_power_sysfs_path(zhp, vdev);
|
||||
if (path == NULL)
|
||||
return (-1);
|
||||
|
||||
val = zpool_sysfs_gets(path);
|
||||
if (val == NULL) {
|
||||
free(path);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
rc = zpool_power_parse_value(val);
|
||||
free(val);
|
||||
free(path);
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn on or off the slot to a device
|
||||
*
|
||||
* Device path is the full path to the device (like /dev/sda or /dev/sda1).
|
||||
*
|
||||
* Return code:
|
||||
* 0: Success
|
||||
* ENOTSUP: Power control not supported for OS
|
||||
* EBADSLT: Couldn't read current power state
|
||||
* ENOENT: No sysfs path to power control
|
||||
* EIO: Couldn't write sysfs power value
|
||||
* EBADE: Sysfs power value didn't change
|
||||
*/
|
||||
int
|
||||
zpool_power(zpool_handle_t *zhp, char *vdev, boolean_t turn_on)
|
||||
{
|
||||
char *sysfs_path;
|
||||
const char *val;
|
||||
int rc;
|
||||
int timeout_ms;
|
||||
|
||||
rc = zpool_power_current_state(zhp, vdev);
|
||||
if (rc == -1) {
|
||||
return (EBADSLT);
|
||||
}
|
||||
|
||||
/* Already correct value? */
|
||||
if (rc == (int)turn_on)
|
||||
return (0);
|
||||
|
||||
sysfs_path = zpool_power_sysfs_path(zhp, vdev);
|
||||
if (sysfs_path == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
if (zpool_power_use_word(sysfs_path)) {
|
||||
val = turn_on ? "on" : "off";
|
||||
} else {
|
||||
val = turn_on ? "1" : "0";
|
||||
}
|
||||
|
||||
rc = zpool_sysfs_puts(sysfs_path, (char *)val);
|
||||
|
||||
free(sysfs_path);
|
||||
if (rc != 0) {
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait up to 30 seconds for sysfs power value to change after
|
||||
* writing it.
|
||||
*/
|
||||
timeout_ms = zpool_getenv_int("ZPOOL_POWER_ON_SLOT_TIMEOUT_MS", 30000);
|
||||
for (int i = 0; i < MAX(1, timeout_ms / 200); i++) {
|
||||
rc = zpool_power_current_state(zhp, vdev);
|
||||
if (rc == (int)turn_on)
|
||||
return (0); /* success */
|
||||
|
||||
fsleep(0.200); /* 200ms */
|
||||
}
|
||||
|
||||
/* sysfs value never changed */
|
||||
return (EBADE);
|
||||
}
|
||||
|
|
|
@ -16,12 +16,14 @@ if [ -L "$dev" ] ; then
|
|||
dev=$(readlink "$dev")
|
||||
fi
|
||||
|
||||
dev="${dev##*/}"
|
||||
dev=$(basename "$dev")
|
||||
val=""
|
||||
if [ -d "/sys/class/block/$dev/slaves" ] ; then
|
||||
# ls -C: output in columns, no newlines, two spaces (change to one)
|
||||
# shellcheck disable=SC2012
|
||||
val=$(ls -C "/sys/class/block/$dev/slaves" | tr -s '[:space:]' ' ')
|
||||
# ls -C: output in columns, no newlines
|
||||
val=$(ls -C "/sys/class/block/$dev/slaves")
|
||||
|
||||
# ls -C will print two spaces between files; change to one space.
|
||||
val=$(echo "$val" | sed -r 's/[[:blank:]]+/ /g')
|
||||
fi
|
||||
|
||||
echo "dm-deps=$val"
|
||||
|
|
|
@ -9,7 +9,7 @@ iostat: Show iostat values since boot (summary page).
|
|||
iostat-1s: Do a single 1-second iostat sample and show values.
|
||||
iostat-10s: Do a single 10-second iostat sample and show values."
|
||||
|
||||
script="${0##*/}"
|
||||
script=$(basename "$0")
|
||||
if [ "$1" = "-h" ] ; then
|
||||
echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2-
|
||||
exit
|
||||
|
@ -42,7 +42,7 @@ else
|
|||
${brief:+"-y"} \
|
||||
${interval:+"$interval"} \
|
||||
${interval:+"1"} \
|
||||
"$VDEV_UPATH" | grep -v '^$' | tail -n 2)
|
||||
"$VDEV_UPATH" | awk NF | tail -n 2)
|
||||
fi
|
||||
|
||||
|
||||
|
@ -61,7 +61,7 @@ fi
|
|||
cols=$(echo "$out" | head -n 1)
|
||||
|
||||
# Get the values and tab separate them to make them cut-able.
|
||||
vals=$(echo "$out" | tail -n 1 | tr -s '[:space:]' '\t')
|
||||
vals=$(echo "$out" | tail -n 1 | sed -r 's/[[:blank:]]+/\t/g')
|
||||
|
||||
i=0
|
||||
for col in $cols ; do
|
||||
|
|
|
@ -48,7 +48,7 @@ size: Show the disk capacity.
|
|||
vendor: Show the disk vendor.
|
||||
lsblk: Show the disk size, vendor, and model number."
|
||||
|
||||
script="${0##*/}"
|
||||
script=$(basename "$0")
|
||||
|
||||
if [ "$1" = "-h" ] ; then
|
||||
echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2-
|
||||
|
|
|
@ -4,23 +4,19 @@
|
|||
#
|
||||
|
||||
if [ "$1" = "-h" ] ; then
|
||||
echo "Show whether a vdev is a file, hdd, ssd, or iscsi."
|
||||
echo "Show whether a vdev is a file, hdd, or ssd."
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ -b "$VDEV_UPATH" ]; then
|
||||
device="${VDEV_UPATH##*/}"
|
||||
read -r val 2>/dev/null < "/sys/block/$device/queue/rotational"
|
||||
case "$val" in
|
||||
0) MEDIA="ssd" ;;
|
||||
1) MEDIA="hdd" ;;
|
||||
esac
|
||||
device=$(basename "$VDEV_UPATH")
|
||||
val=$(cat "/sys/block/$device/queue/rotational" 2>/dev/null)
|
||||
if [ "$val" = "0" ]; then
|
||||
MEDIA="ssd"
|
||||
fi
|
||||
|
||||
vpd_pg83="/sys/block/$device/device/vpd_pg83"
|
||||
if [ -f "$vpd_pg83" ]; then
|
||||
if grep -q --binary "iqn." "$vpd_pg83"; then
|
||||
MEDIA="iscsi"
|
||||
fi
|
||||
if [ "$val" = "1" ]; then
|
||||
MEDIA="hdd"
|
||||
fi
|
||||
else
|
||||
if [ -f "$VDEV_UPATH" ]; then
|
||||
|
|
|
@ -11,7 +11,7 @@ fault_led: Show value of the disk enclosure slot fault LED.
|
|||
locate_led: Show value of the disk enclosure slot locate LED.
|
||||
ses: Show disk's enc, enc device, slot, and fault/locate LED values."
|
||||
|
||||
script="${0##*/}"
|
||||
script=$(basename "$0")
|
||||
if [ "$1" = "-h" ] ; then
|
||||
echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2-
|
||||
exit
|
||||
|
@ -32,30 +32,16 @@ for i in $scripts ; do
|
|||
val=""
|
||||
case $i in
|
||||
enc)
|
||||
if echo "$VDEV_ENC_SYSFS_PATH" | grep -q '/sys/bus/pci/slots' ; then
|
||||
val="$VDEV_ENC_SYSFS_PATH"
|
||||
else
|
||||
val="$(ls """$VDEV_ENC_SYSFS_PATH/../../""" 2>/dev/null)"
|
||||
fi
|
||||
val=$(ls "$VDEV_ENC_SYSFS_PATH/../../" 2>/dev/null)
|
||||
;;
|
||||
slot)
|
||||
if echo "$VDEV_ENC_SYSFS_PATH" | grep -q '/sys/bus/pci/slots' ; then
|
||||
val="$(basename """$VDEV_ENC_SYSFS_PATH""")"
|
||||
else
|
||||
val="$(cat """$VDEV_ENC_SYSFS_PATH/slot""" 2>/dev/null)"
|
||||
fi
|
||||
val=$(cat "$VDEV_ENC_SYSFS_PATH/slot" 2>/dev/null)
|
||||
;;
|
||||
encdev)
|
||||
val=$(ls "$VDEV_ENC_SYSFS_PATH/../device/scsi_generic" 2>/dev/null)
|
||||
;;
|
||||
fault_led)
|
||||
# JBODs fault LED is called 'fault', NVMe fault LED is called
|
||||
# 'attention'.
|
||||
if [ -f "$VDEV_ENC_SYSFS_PATH/fault" ] ; then
|
||||
val=$(cat "$VDEV_ENC_SYSFS_PATH/fault" 2>/dev/null)
|
||||
elif [ -f "$VDEV_ENC_SYSFS_PATH/attention" ] ; then
|
||||
val=$(cat "$VDEV_ENC_SYSFS_PATH/attention" 2>/dev/null)
|
||||
fi
|
||||
val=$(cat "$VDEV_ENC_SYSFS_PATH/fault" 2>/dev/null)
|
||||
;;
|
||||
locate_led)
|
||||
val=$(cat "$VDEV_ENC_SYSFS_PATH/locate" 2>/dev/null)
|
||||
|
|
|
@ -53,7 +53,7 @@ get_filename_from_dir()
|
|||
num_files=$(find "$dir" -maxdepth 1 -type f | wc -l)
|
||||
mod=$((pid % num_files))
|
||||
i=0
|
||||
find "$dir" -type f -printf '%f\n' | while read -r file ; do
|
||||
find "$dir" -type f -printf "%f\n" | while read -r file ; do
|
||||
if [ "$mod" = "$i" ] ; then
|
||||
echo "$file"
|
||||
break
|
||||
|
@ -62,14 +62,17 @@ get_filename_from_dir()
|
|||
done
|
||||
}
|
||||
|
||||
script="${0##*/}"
|
||||
script=$(basename "$0")
|
||||
|
||||
if [ "$1" = "-h" ] ; then
|
||||
echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2-
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ -b "$VDEV_UPATH" ] && PATH="/usr/sbin:$PATH" command -v smartctl > /dev/null || [ -n "$samples" ] ; then
|
||||
smartctl_path=$(command -v smartctl)
|
||||
|
||||
# shellcheck disable=SC2015
|
||||
if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ] || [ -n "$samples" ] ; then
|
||||
if [ -n "$samples" ] ; then
|
||||
# cat a smartctl output text file instead of running smartctl
|
||||
# on a vdev (only used for developer testing).
|
||||
|
@ -77,7 +80,7 @@ if [ -b "$VDEV_UPATH" ] && PATH="/usr/sbin:$PATH" command -v smartctl > /dev/nul
|
|||
echo "file=$file"
|
||||
raw_out=$(cat "$samples/$file")
|
||||
else
|
||||
raw_out=$(sudo smartctl -a "$VDEV_UPATH")
|
||||
raw_out=$(eval "sudo $smartctl_path -a $VDEV_UPATH")
|
||||
fi
|
||||
|
||||
# What kind of drive are we? Look for the right line in smartctl:
|
||||
|
@ -228,11 +231,11 @@ esac
|
|||
with_vals=$(echo "$out" | grep -E "$scripts")
|
||||
if [ -n "$with_vals" ]; then
|
||||
echo "$with_vals"
|
||||
without_vals=$(echo "$scripts" | tr '|' '\n' |
|
||||
without_vals=$(echo "$scripts" | tr "|" "\n" |
|
||||
grep -v -E "$(echo "$with_vals" |
|
||||
awk -F "=" '{print $1}')" | awk '{print $0"="}')
|
||||
else
|
||||
without_vals=$(echo "$scripts" | tr '|' '\n' | awk '{print $0"="}')
|
||||
without_vals=$(echo "$scripts" | tr "|" "\n" | awk '{print $0"="}')
|
||||
fi
|
||||
|
||||
if [ -n "$without_vals" ]; then
|
||||
|
|
|
@ -264,6 +264,51 @@ for_each_pool(int argc, char **argv, boolean_t unavail,
|
|||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
for_each_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, pool_vdev_iter_f func,
|
||||
void *data)
|
||||
{
|
||||
nvlist_t **child;
|
||||
uint_t c, children;
|
||||
int ret = 0;
|
||||
int i;
|
||||
char *type;
|
||||
|
||||
const char *list[] = {
|
||||
ZPOOL_CONFIG_SPARES,
|
||||
ZPOOL_CONFIG_L2CACHE,
|
||||
ZPOOL_CONFIG_CHILDREN
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(list); i++) {
|
||||
if (nvlist_lookup_nvlist_array(nv, list[i], &child,
|
||||
&children) == 0) {
|
||||
for (c = 0; c < children; c++) {
|
||||
uint64_t ishole = 0;
|
||||
|
||||
(void) nvlist_lookup_uint64(child[c],
|
||||
ZPOOL_CONFIG_IS_HOLE, &ishole);
|
||||
|
||||
if (ishole)
|
||||
continue;
|
||||
|
||||
ret |= for_each_vdev_cb(zhp, child[c], func,
|
||||
data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
|
||||
return (ret);
|
||||
|
||||
/* Don't run our function on root vdevs */
|
||||
if (strcmp(type, VDEV_TYPE_ROOT) != 0) {
|
||||
ret |= func(zhp, nv, data);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the equivalent of for_each_pool() for vdevs. It iterates thorough
|
||||
* all vdevs in the pool, ignoring root vdevs and holes, calling func() on
|
||||
|
@ -282,7 +327,7 @@ for_each_vdev(zpool_handle_t *zhp, pool_vdev_iter_f func, void *data)
|
|||
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
||||
&nvroot) == 0);
|
||||
}
|
||||
return (for_each_vdev_cb((void *) zhp, nvroot, func, data));
|
||||
return (for_each_vdev_cb(zhp, nvroot, func, data));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -439,23 +484,39 @@ static void
|
|||
vdev_run_cmd(vdev_cmd_data_t *data, char *cmd)
|
||||
{
|
||||
int rc;
|
||||
char *argv[2] = {cmd};
|
||||
char **env;
|
||||
char *argv[2] = {cmd, 0};
|
||||
char *env[5] = {"PATH=/bin:/sbin:/usr/bin:/usr/sbin", NULL, NULL, NULL,
|
||||
NULL};
|
||||
char **lines = NULL;
|
||||
int lines_cnt = 0;
|
||||
int i;
|
||||
|
||||
env = zpool_vdev_script_alloc_env(data->pool, data->path, data->upath,
|
||||
data->vdev_enc_sysfs_path, NULL, NULL);
|
||||
if (env == NULL)
|
||||
/* Setup our custom environment variables */
|
||||
rc = asprintf(&env[1], "VDEV_PATH=%s",
|
||||
data->path ? data->path : "");
|
||||
if (rc == -1) {
|
||||
env[1] = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = asprintf(&env[2], "VDEV_UPATH=%s",
|
||||
data->upath ? data->upath : "");
|
||||
if (rc == -1) {
|
||||
env[2] = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = asprintf(&env[3], "VDEV_ENC_SYSFS_PATH=%s",
|
||||
data->vdev_enc_sysfs_path ?
|
||||
data->vdev_enc_sysfs_path : "");
|
||||
if (rc == -1) {
|
||||
env[3] = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Run the command */
|
||||
rc = libzfs_run_process_get_stdout_nopath(cmd, argv, env, &lines,
|
||||
&lines_cnt);
|
||||
|
||||
zpool_vdev_script_free_env(env);
|
||||
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
|
@ -467,6 +528,10 @@ vdev_run_cmd(vdev_cmd_data_t *data, char *cmd)
|
|||
out:
|
||||
if (lines != NULL)
|
||||
libzfs_free_str_array(lines, lines_cnt);
|
||||
|
||||
/* Start with i = 1 since env[0] was statically allocated */
|
||||
for (i = 1; i < ARRAY_SIZE(env); i++)
|
||||
free(env[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -538,7 +603,7 @@ vdev_run_cmd_thread(void *cb_cmd_data)
|
|||
|
||||
/* For each vdev in the pool run a command */
|
||||
static int
|
||||
for_each_vdev_run_cb(void *zhp_data, nvlist_t *nv, void *cb_vcdl)
|
||||
for_each_vdev_run_cb(zpool_handle_t *zhp, nvlist_t *nv, void *cb_vcdl)
|
||||
{
|
||||
vdev_cmd_data_list_t *vcdl = cb_vcdl;
|
||||
vdev_cmd_data_t *data;
|
||||
|
@ -546,15 +611,10 @@ for_each_vdev_run_cb(void *zhp_data, nvlist_t *nv, void *cb_vcdl)
|
|||
char *vname = NULL;
|
||||
char *vdev_enc_sysfs_path = NULL;
|
||||
int i, match = 0;
|
||||
zpool_handle_t *zhp = zhp_data;
|
||||
|
||||
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0)
|
||||
return (1);
|
||||
|
||||
/* Make sure we're getting the updated enclosure sysfs path */
|
||||
update_vdev_config_dev_sysfs_path(nv, path,
|
||||
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
|
||||
|
||||
nvlist_lookup_string(nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
|
||||
&vdev_enc_sysfs_path);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include <libnvpair.h>
|
||||
#include <libzfs.h>
|
||||
#include <libzutil.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -68,6 +67,7 @@ int for_each_pool(int, char **, boolean_t unavail, zprop_list_t **,
|
|||
boolean_t, zpool_iter_f, void *);
|
||||
|
||||
/* Vdev list functions */
|
||||
typedef int (*pool_vdev_iter_f)(zpool_handle_t *, nvlist_t *, void *);
|
||||
int for_each_vdev(zpool_handle_t *zhp, pool_vdev_iter_f func, void *data);
|
||||
|
||||
typedef struct zpool_list zpool_list_t;
|
||||
|
@ -124,19 +124,11 @@ vdev_cmd_data_list_t *all_pools_for_each_vdev_run(int argc, char **argv,
|
|||
|
||||
void free_vdev_cmd_data_list(vdev_cmd_data_list_t *vcdl);
|
||||
|
||||
void free_vdev_cmd_data(vdev_cmd_data_t *data);
|
||||
|
||||
int vdev_run_cmd_simple(char *path, char *cmd);
|
||||
|
||||
int check_device(const char *path, boolean_t force,
|
||||
boolean_t isspare, boolean_t iswholedisk);
|
||||
boolean_t check_sector_size_database(char *path, int *sector_size);
|
||||
void vdev_error(const char *fmt, ...);
|
||||
int check_file(const char *file, boolean_t force, boolean_t isspare);
|
||||
void after_zpool_upgrade(zpool_handle_t *zhp);
|
||||
|
||||
int zpool_power(zpool_handle_t *zhp, char *vdev, boolean_t turn_on);
|
||||
int zpool_power_current_state(zpool_handle_t *zhp, char *vdev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -373,10 +373,6 @@ make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary)
|
|||
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_PATH, path) == 0);
|
||||
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 0);
|
||||
|
||||
/* Lookup and add the enclosure sysfs path (if exists) */
|
||||
update_vdev_config_dev_sysfs_path(vdev, path,
|
||||
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
|
||||
|
||||
if (strcmp(type, VDEV_TYPE_DISK) == 0)
|
||||
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
|
||||
(uint64_t)wholedisk) == 0);
|
||||
|
@ -925,15 +921,6 @@ zero_label(char *path)
|
|||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
lines_to_stderr(char *lines[], int lines_cnt)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < lines_cnt; i++) {
|
||||
fprintf(stderr, "%s\n", lines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Go through and find any whole disks in the vdev specification, labelling them
|
||||
* as appropriate. When constructing the vdev spec, we were unable to open this
|
||||
|
@ -945,7 +932,7 @@ lines_to_stderr(char *lines[], int lines_cnt)
|
|||
* need to get the devid after we label the disk.
|
||||
*/
|
||||
static int
|
||||
make_disks(zpool_handle_t *zhp, nvlist_t *nv, boolean_t replacing)
|
||||
make_disks(zpool_handle_t *zhp, nvlist_t *nv)
|
||||
{
|
||||
nvlist_t **child;
|
||||
uint_t c, children;
|
||||
|
@ -1030,8 +1017,6 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv, boolean_t replacing)
|
|||
*/
|
||||
if (!is_exclusive && !is_spare(NULL, udevpath)) {
|
||||
char *devnode = strrchr(devpath, '/') + 1;
|
||||
char **lines = NULL;
|
||||
int lines_cnt = 0;
|
||||
|
||||
ret = strncmp(udevpath, UDISK_ROOT, strlen(UDISK_ROOT));
|
||||
if (ret == 0) {
|
||||
|
@ -1043,27 +1028,9 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv, boolean_t replacing)
|
|||
/*
|
||||
* When labeling a pool the raw device node name
|
||||
* is provided as it appears under /dev/.
|
||||
*
|
||||
* Note that 'zhp' will be NULL when we're creating a
|
||||
* pool.
|
||||
*/
|
||||
if (zpool_prepare_and_label_disk(g_zfs, zhp, devnode,
|
||||
nv, zhp == NULL ? "create" :
|
||||
replacing ? "replace" : "add", &lines,
|
||||
&lines_cnt) != 0) {
|
||||
(void) fprintf(stderr,
|
||||
gettext(
|
||||
"Error preparing/labeling disk.\n"));
|
||||
if (lines_cnt > 0) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("zfs_prepare_disk output:\n"));
|
||||
lines_to_stderr(lines, lines_cnt);
|
||||
}
|
||||
|
||||
libzfs_free_str_array(lines, lines_cnt);
|
||||
if (zpool_label_disk(g_zfs, zhp, devnode) == -1)
|
||||
return (-1);
|
||||
}
|
||||
libzfs_free_str_array(lines, lines_cnt);
|
||||
|
||||
/*
|
||||
* Wait for udev to signal the device is available
|
||||
|
@ -1100,19 +1067,19 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv, boolean_t replacing)
|
|||
}
|
||||
|
||||
for (c = 0; c < children; c++)
|
||||
if ((ret = make_disks(zhp, child[c], replacing)) != 0)
|
||||
if ((ret = make_disks(zhp, child[c])) != 0)
|
||||
return (ret);
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
|
||||
&child, &children) == 0)
|
||||
for (c = 0; c < children; c++)
|
||||
if ((ret = make_disks(zhp, child[c], replacing)) != 0)
|
||||
if ((ret = make_disks(zhp, child[c])) != 0)
|
||||
return (ret);
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
|
||||
&child, &children) == 0)
|
||||
for (c = 0; c < children; c++)
|
||||
if ((ret = make_disks(zhp, child[c], replacing)) != 0)
|
||||
if ((ret = make_disks(zhp, child[c])) != 0)
|
||||
return (ret);
|
||||
|
||||
return (0);
|
||||
|
@ -1773,7 +1740,7 @@ split_mirror_vdev(zpool_handle_t *zhp, char *newname, nvlist_t *props,
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
if (!flags.dryrun && make_disks(zhp, newroot, B_FALSE) != 0) {
|
||||
if (!flags.dryrun && make_disks(zhp, newroot) != 0) {
|
||||
nvlist_free(newroot);
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -1894,7 +1861,7 @@ make_root_vdev(zpool_handle_t *zhp, nvlist_t *props, int force, int check_rep,
|
|||
/*
|
||||
* Run through the vdev specification and label any whole disks found.
|
||||
*/
|
||||
if (!dryrun && make_disks(zhp, newroot, replacing) != 0) {
|
||||
if (!dryrun && make_disks(zhp, newroot) != 0) {
|
||||
nvlist_free(newroot);
|
||||
return (NULL);
|
||||
}
|
||||
|
|
|
@ -1360,7 +1360,7 @@
|
|||
"type": "row"
|
||||
},
|
||||
{
|
||||
"content": "I/O requests that are satisfied by accessing pool devices are managed by the ZIO scheduler.\nThe total latency is measured from the start of the I/O to completion by the disk.\nLatency through each queue is shown prior to its submission to the disk queue.\n\nThis view is useful for observing the effects of tuning the ZIO scheduler min and max values\n(see zfs(4) and [ZFS on Linux Module Parameters](https://openzfs.github.io/openzfs-docs/Performance%20and%20tuning/ZFS%20on%20Linux%20Module%20Parameters.html)):\n+ *zfs_vdev_max_active* controls the ZIO scheduler's disk queue depth (do not confuse with the block device's nr_requests)\n+ *zfs_vdev_sync_read_min_active* and *zfs_vdev_sync_read_max_active* control the synchronous queue for reads: most reads are sync\n+ *zfs_vdev_sync_write_min_active* and *zfs_vdev_sync_write_max_active* control the synchronous queue for writes: \nusually metadata or user data depending on the \"sync\" property setting or I/Os that are requested to be flushed\n+ *zfs_vdev_async_read_min_active* and *zfs_vdev_async_read_max_active* control the asynchronous queue for reads: usually prefetches\n+ *zfs_vdev_async_write_min_active* and *zfs_vdev_async_write_max_active* control the asynchronous queue for writes: \nusually the bulk of all writes at transaction group (txg) commit\n+ *zfs_vdev_scrub_min_active* and *zfs_vdev_scrub_max_active* controls the scan reads: usually scrub or resilver\n\n",
|
||||
"content": "I/O requests that are satisfied by accessing pool devices are managed by the ZIO scheduler.\nThe total latency is measured from the start of the I/O to completion by the disk.\nLatency through each queue is shown prior to its submission to the disk queue.\n\nThis view is useful for observing the effects of tuning the ZIO scheduler min and max values\n(see zfs-module-parameters(5) and [ZFS on Linux Module Parameters](https://openzfs.github.io/openzfs-docs/Performance%20and%20tuning/ZFS%20on%20Linux%20Module%20Parameters.html)):\n+ *zfs_vdev_max_active* controls the ZIO scheduler's disk queue depth (do not confuse with the block device's nr_requests)\n+ *zfs_vdev_sync_read_min_active* and *zfs_vdev_sync_read_max_active* control the synchronous queue for reads: most reads are sync\n+ *zfs_vdev_sync_write_min_active* and *zfs_vdev_sync_write_max_active* control the synchronous queue for writes: \nusually metadata or user data depending on the \"sync\" property setting or I/Os that are requested to be flushed\n+ *zfs_vdev_async_read_min_active* and *zfs_vdev_async_read_max_active* control the asynchronous queue for reads: usually prefetches\n+ *zfs_vdev_async_write_min_active* and *zfs_vdev_async_write_max_active* control the asynchronous queue for writes: \nusually the bulk of all writes at transaction group (txg) commit\n+ *zfs_vdev_scrub_min_active* and *zfs_vdev_scrub_max_active* controls the scan reads: usually scrub or resilver\n\n",
|
||||
"datasource": "${DS_MACBOOK-INFLUX}",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
|
@ -1664,4 +1664,4 @@
|
|||
"list": []
|
||||
},
|
||||
"version": 2
|
||||
}
|
||||
}
|
|
@ -117,7 +117,6 @@ escape_string(char *s)
|
|||
case '=':
|
||||
case '\\':
|
||||
*d++ = '\\';
|
||||
fallthrough;
|
||||
default:
|
||||
*d = *c;
|
||||
}
|
||||
|
@ -684,8 +683,9 @@ print_recursive_stats(stat_printer_f func, nvlist_t *nvroot,
|
|||
|
||||
if (descend && nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
|
||||
&child, &children) == 0) {
|
||||
(void) strlcpy(vdev_name, get_vdev_name(nvroot, parent_name),
|
||||
(void) strncpy(vdev_name, get_vdev_name(nvroot, parent_name),
|
||||
sizeof (vdev_name));
|
||||
vdev_name[sizeof (vdev_name) - 1] = '\0';
|
||||
|
||||
for (c = 0; c < children; c++) {
|
||||
print_recursive_stats(func, child[c], pool_name,
|
||||
|
|
|
@ -15,6 +15,3 @@ zstream_LDADD = \
|
|||
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
||||
|
||||
include $(top_srcdir)/config/CppCheck.am
|
||||
|
||||
install-exec-hook:
|
||||
cd $(DESTDIR)$(sbindir) && $(LN_S) -f zstream zstreamdump
|
||||
|
|
|
@ -49,11 +49,6 @@ zstream_usage(void)
|
|||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *basename = strrchr(argv[0], '/');
|
||||
basename = basename ? (basename + 1) : argv[0];
|
||||
if (argc >= 1 && strcmp(basename, "zstreamdump") == 0)
|
||||
return (zstream_do_dump(argc, argv));
|
||||
|
||||
if (argc < 2)
|
||||
zstream_usage();
|
||||
|
||||
|
|
|
@ -297,7 +297,6 @@ zstream_do_dump(int argc, char *argv[])
|
|||
|
||||
fletcher_4_init();
|
||||
while (read_hdr(drr, &zc)) {
|
||||
uint64_t featureflags = 0;
|
||||
|
||||
/*
|
||||
* If this is the first DMU record being processed, check for
|
||||
|
@ -462,18 +461,6 @@ zstream_do_dump(int argc, char *argv[])
|
|||
BSWAP_64(drro->drr_maxblkid);
|
||||
}
|
||||
|
||||
featureflags =
|
||||
DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
|
||||
|
||||
if (featureflags & DMU_BACKUP_FEATURE_RAW &&
|
||||
drro->drr_bonuslen > drro->drr_raw_bonuslen) {
|
||||
(void) fprintf(stderr,
|
||||
"Warning: Object %llu has bonuslen = "
|
||||
"%u > raw_bonuslen = %u\n\n",
|
||||
(u_longlong_t)drro->drr_object,
|
||||
drro->drr_bonuslen, drro->drr_raw_bonuslen);
|
||||
}
|
||||
|
||||
payload_size = DRR_OBJECT_PAYLOAD_SIZE(drro);
|
||||
|
||||
if (verbose) {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
dist_sbin_SCRIPTS = zstreamdump
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
exec zstream dump "$@"
|
|
@ -124,7 +124,6 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <umem.h>
|
||||
#include <ctype.h>
|
||||
|
@ -193,58 +192,30 @@ typedef struct ztest_shared_opts {
|
|||
char zo_gvars[ZO_GVARS_MAX_COUNT][ZO_GVARS_MAX_ARGLEN];
|
||||
} ztest_shared_opts_t;
|
||||
|
||||
/* Default values for command line options. */
|
||||
#define DEFAULT_POOL "ztest"
|
||||
#define DEFAULT_VDEV_DIR "/tmp"
|
||||
#define DEFAULT_VDEV_COUNT 5
|
||||
#define DEFAULT_VDEV_SIZE (SPA_MINDEVSIZE * 4) /* 256m default size */
|
||||
#define DEFAULT_VDEV_SIZE_STR "256M"
|
||||
#define DEFAULT_ASHIFT SPA_MINBLOCKSHIFT
|
||||
#define DEFAULT_MIRRORS 2
|
||||
#define DEFAULT_RAID_CHILDREN 4
|
||||
#define DEFAULT_RAID_PARITY 1
|
||||
#define DEFAULT_DRAID_DATA 4
|
||||
#define DEFAULT_DRAID_SPARES 1
|
||||
#define DEFAULT_DATASETS_COUNT 7
|
||||
#define DEFAULT_THREADS 23
|
||||
#define DEFAULT_RUN_TIME 300 /* 300 seconds */
|
||||
#define DEFAULT_RUN_TIME_STR "300 sec"
|
||||
#define DEFAULT_PASS_TIME 60 /* 60 seconds */
|
||||
#define DEFAULT_PASS_TIME_STR "60 sec"
|
||||
#define DEFAULT_KILL_RATE 70 /* 70% kill rate */
|
||||
#define DEFAULT_KILLRATE_STR "70%"
|
||||
#define DEFAULT_INITS 1
|
||||
#define DEFAULT_MAX_LOOPS 50 /* 5 minutes */
|
||||
#define DEFAULT_FORCE_GANGING (64 << 10)
|
||||
#define DEFAULT_FORCE_GANGING_STR "64K"
|
||||
|
||||
/* Simplifying assumption: -1 is not a valid default. */
|
||||
#define NO_DEFAULT -1
|
||||
|
||||
static const ztest_shared_opts_t ztest_opts_defaults = {
|
||||
.zo_pool = DEFAULT_POOL,
|
||||
.zo_dir = DEFAULT_VDEV_DIR,
|
||||
.zo_pool = "ztest",
|
||||
.zo_dir = "/tmp",
|
||||
.zo_alt_ztest = { '\0' },
|
||||
.zo_alt_libpath = { '\0' },
|
||||
.zo_vdevs = DEFAULT_VDEV_COUNT,
|
||||
.zo_ashift = DEFAULT_ASHIFT,
|
||||
.zo_mirrors = DEFAULT_MIRRORS,
|
||||
.zo_raid_children = DEFAULT_RAID_CHILDREN,
|
||||
.zo_raid_parity = DEFAULT_RAID_PARITY,
|
||||
.zo_vdevs = 5,
|
||||
.zo_ashift = SPA_MINBLOCKSHIFT,
|
||||
.zo_mirrors = 2,
|
||||
.zo_raid_children = 4,
|
||||
.zo_raid_parity = 1,
|
||||
.zo_raid_type = VDEV_TYPE_RAIDZ,
|
||||
.zo_vdev_size = DEFAULT_VDEV_SIZE,
|
||||
.zo_draid_data = DEFAULT_DRAID_DATA, /* data drives */
|
||||
.zo_draid_spares = DEFAULT_DRAID_SPARES, /* distributed spares */
|
||||
.zo_datasets = DEFAULT_DATASETS_COUNT,
|
||||
.zo_threads = DEFAULT_THREADS,
|
||||
.zo_passtime = DEFAULT_PASS_TIME,
|
||||
.zo_killrate = DEFAULT_KILL_RATE,
|
||||
.zo_vdev_size = SPA_MINDEVSIZE * 4, /* 256m default size */
|
||||
.zo_draid_data = 4, /* data drives */
|
||||
.zo_draid_spares = 1, /* distributed spares */
|
||||
.zo_datasets = 7,
|
||||
.zo_threads = 23,
|
||||
.zo_passtime = 60, /* 60 seconds */
|
||||
.zo_killrate = 70, /* 70% kill rate */
|
||||
.zo_verbose = 0,
|
||||
.zo_mmp_test = 0,
|
||||
.zo_init = DEFAULT_INITS,
|
||||
.zo_time = DEFAULT_RUN_TIME,
|
||||
.zo_maxloops = DEFAULT_MAX_LOOPS, /* max loops during spa_freeze() */
|
||||
.zo_metaslab_force_ganging = DEFAULT_FORCE_GANGING,
|
||||
.zo_init = 1,
|
||||
.zo_time = 300, /* 5 minutes */
|
||||
.zo_maxloops = 50, /* max loops during spa_freeze() */
|
||||
.zo_metaslab_force_ganging = 64 << 10,
|
||||
.zo_special_vdevs = ZTEST_VDEV_CLASS_RND,
|
||||
.zo_gvars_count = 0,
|
||||
};
|
||||
|
@ -713,154 +684,68 @@ nicenumtoull(const char *buf)
|
|||
return (val);
|
||||
}
|
||||
|
||||
typedef struct ztest_option {
|
||||
const char short_opt;
|
||||
const char *long_opt;
|
||||
const char *long_opt_param;
|
||||
const char *comment;
|
||||
unsigned int default_int;
|
||||
char *default_str;
|
||||
} ztest_option_t;
|
||||
|
||||
/*
|
||||
* The following option_table is used for generating the usage info as well as
|
||||
* the long and short option information for calling getopt_long().
|
||||
*/
|
||||
static ztest_option_t option_table[] = {
|
||||
{ 'v', "vdevs", "INTEGER", "Number of vdevs", DEFAULT_VDEV_COUNT,
|
||||
NULL},
|
||||
{ 's', "vdev-size", "INTEGER", "Size of each vdev",
|
||||
NO_DEFAULT, DEFAULT_VDEV_SIZE_STR},
|
||||
{ 'a', "alignment-shift", "INTEGER",
|
||||
"Alignment shift; use 0 for random", DEFAULT_ASHIFT, NULL},
|
||||
{ 'm', "mirror-copies", "INTEGER", "Number of mirror copies",
|
||||
DEFAULT_MIRRORS, NULL},
|
||||
{ 'r', "raid-disks", "INTEGER", "Number of raidz/draid disks",
|
||||
DEFAULT_RAID_CHILDREN, NULL},
|
||||
{ 'R', "raid-parity", "INTEGER", "Raid parity",
|
||||
DEFAULT_RAID_PARITY, NULL},
|
||||
{ 'K', "raid-kind", "raidz|draid|random", "Raid kind",
|
||||
NO_DEFAULT, "random"},
|
||||
{ 'D', "draid-data", "INTEGER", "Number of draid data drives",
|
||||
DEFAULT_DRAID_DATA, NULL},
|
||||
{ 'S', "draid-spares", "INTEGER", "Number of draid spares",
|
||||
DEFAULT_DRAID_SPARES, NULL},
|
||||
{ 'd', "datasets", "INTEGER", "Number of datasets",
|
||||
DEFAULT_DATASETS_COUNT, NULL},
|
||||
{ 't', "threads", "INTEGER", "Number of ztest threads",
|
||||
DEFAULT_THREADS, NULL},
|
||||
{ 'g', "gang-block-threshold", "INTEGER",
|
||||
"Metaslab gang block threshold",
|
||||
NO_DEFAULT, DEFAULT_FORCE_GANGING_STR},
|
||||
{ 'i', "init-count", "INTEGER", "Number of times to initialize pool",
|
||||
DEFAULT_INITS, NULL},
|
||||
{ 'k', "kill-percentage", "INTEGER", "Kill percentage",
|
||||
NO_DEFAULT, DEFAULT_KILLRATE_STR},
|
||||
{ 'p', "pool-name", "STRING", "Pool name",
|
||||
NO_DEFAULT, DEFAULT_POOL},
|
||||
{ 'f', "vdev-file-directory", "PATH", "File directory for vdev files",
|
||||
NO_DEFAULT, DEFAULT_VDEV_DIR},
|
||||
{ 'M', "multi-host", NULL,
|
||||
"Multi-host; simulate pool imported on remote host",
|
||||
NO_DEFAULT, NULL},
|
||||
{ 'E', "use-existing-pool", NULL,
|
||||
"Use existing pool instead of creating new one", NO_DEFAULT, NULL},
|
||||
{ 'T', "run-time", "INTEGER", "Total run time",
|
||||
NO_DEFAULT, DEFAULT_RUN_TIME_STR},
|
||||
{ 'P', "pass-time", "INTEGER", "Time per pass",
|
||||
NO_DEFAULT, DEFAULT_PASS_TIME_STR},
|
||||
{ 'F', "freeze-loops", "INTEGER", "Max loops in spa_freeze()",
|
||||
DEFAULT_MAX_LOOPS, NULL},
|
||||
{ 'B', "alt-ztest", "PATH", "Alternate ztest path",
|
||||
NO_DEFAULT, NULL},
|
||||
{ 'C', "vdev-class-state", "on|off|random", "vdev class state",
|
||||
NO_DEFAULT, "random"},
|
||||
{ 'o', "option", "\"OPTION=INTEGER\"",
|
||||
"Set global variable to an unsigned 32-bit integer value",
|
||||
NO_DEFAULT, NULL},
|
||||
{ 'G', "dump-debug-msg", NULL,
|
||||
"Dump zfs_dbgmsg buffer before exiting due to an error",
|
||||
NO_DEFAULT, NULL},
|
||||
{ 'V', "verbose", NULL,
|
||||
"Verbose (use multiple times for ever more verbosity)",
|
||||
NO_DEFAULT, NULL},
|
||||
{ 'h', "help", NULL, "Show this help",
|
||||
NO_DEFAULT, NULL},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static struct option *long_opts = NULL;
|
||||
static char *short_opts = NULL;
|
||||
|
||||
static void
|
||||
init_options(void)
|
||||
{
|
||||
ASSERT3P(long_opts, ==, NULL);
|
||||
ASSERT3P(short_opts, ==, NULL);
|
||||
|
||||
int count = sizeof (option_table) / sizeof (option_table[0]);
|
||||
long_opts = umem_alloc(sizeof (struct option) * count, UMEM_NOFAIL);
|
||||
|
||||
short_opts = umem_alloc(sizeof (char) * 2 * count, UMEM_NOFAIL);
|
||||
int short_opt_index = 0;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
long_opts[i].val = option_table[i].short_opt;
|
||||
long_opts[i].name = option_table[i].long_opt;
|
||||
long_opts[i].has_arg = option_table[i].long_opt_param != NULL
|
||||
? required_argument : no_argument;
|
||||
long_opts[i].flag = NULL;
|
||||
short_opts[short_opt_index++] = option_table[i].short_opt;
|
||||
if (option_table[i].long_opt_param != NULL) {
|
||||
short_opts[short_opt_index++] = ':';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fini_options(void)
|
||||
{
|
||||
int count = sizeof (option_table) / sizeof (option_table[0]);
|
||||
|
||||
umem_free(long_opts, sizeof (struct option) * count);
|
||||
umem_free(short_opts, sizeof (char) * 2 * count);
|
||||
|
||||
long_opts = NULL;
|
||||
short_opts = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(boolean_t requested)
|
||||
{
|
||||
char option[80];
|
||||
const ztest_shared_opts_t *zo = &ztest_opts_defaults;
|
||||
|
||||
char nice_vdev_size[NN_NUMBUF_SZ];
|
||||
char nice_force_ganging[NN_NUMBUF_SZ];
|
||||
FILE *fp = requested ? stdout : stderr;
|
||||
|
||||
(void) fprintf(fp, "Usage: %s [OPTIONS...]\n", DEFAULT_POOL);
|
||||
for (int i = 0; option_table[i].short_opt != 0; i++) {
|
||||
if (option_table[i].long_opt_param != NULL) {
|
||||
(void) sprintf(option, " -%c --%s=%s",
|
||||
option_table[i].short_opt,
|
||||
option_table[i].long_opt,
|
||||
option_table[i].long_opt_param);
|
||||
} else {
|
||||
(void) sprintf(option, " -%c --%s",
|
||||
option_table[i].short_opt,
|
||||
option_table[i].long_opt);
|
||||
}
|
||||
(void) fprintf(fp, " %-40s%s", option,
|
||||
option_table[i].comment);
|
||||
nicenum(zo->zo_vdev_size, nice_vdev_size, sizeof (nice_vdev_size));
|
||||
nicenum(zo->zo_metaslab_force_ganging, nice_force_ganging,
|
||||
sizeof (nice_force_ganging));
|
||||
|
||||
if (option_table[i].long_opt_param != NULL) {
|
||||
if (option_table[i].default_str != NULL) {
|
||||
(void) fprintf(fp, " (default: %s)",
|
||||
option_table[i].default_str);
|
||||
} else if (option_table[i].default_int != NO_DEFAULT) {
|
||||
(void) fprintf(fp, " (default: %u)",
|
||||
option_table[i].default_int);
|
||||
}
|
||||
}
|
||||
(void) fprintf(fp, "\n");
|
||||
}
|
||||
(void) fprintf(fp, "Usage: %s\n"
|
||||
"\t[-v vdevs (default: %llu)]\n"
|
||||
"\t[-s size_of_each_vdev (default: %s)]\n"
|
||||
"\t[-a alignment_shift (default: %d)] use 0 for random\n"
|
||||
"\t[-m mirror_copies (default: %d)]\n"
|
||||
"\t[-r raidz_disks / draid_disks (default: %d)]\n"
|
||||
"\t[-R raid_parity (default: %d)]\n"
|
||||
"\t[-K raid_kind (default: random)] raidz|draid|random\n"
|
||||
"\t[-D draid_data (default: %d)] in config\n"
|
||||
"\t[-S draid_spares (default: %d)]\n"
|
||||
"\t[-d datasets (default: %d)]\n"
|
||||
"\t[-t threads (default: %d)]\n"
|
||||
"\t[-g gang_block_threshold (default: %s)]\n"
|
||||
"\t[-i init_count (default: %d)] initialize pool i times\n"
|
||||
"\t[-k kill_percentage (default: %llu%%)]\n"
|
||||
"\t[-p pool_name (default: %s)]\n"
|
||||
"\t[-f dir (default: %s)] file directory for vdev files\n"
|
||||
"\t[-M] Multi-host simulate pool imported on remote host\n"
|
||||
"\t[-V] verbose (use multiple times for ever more blather)\n"
|
||||
"\t[-E] use existing pool instead of creating new one\n"
|
||||
"\t[-T time (default: %llu sec)] total run time\n"
|
||||
"\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n"
|
||||
"\t[-P passtime (default: %llu sec)] time per pass\n"
|
||||
"\t[-B alt_ztest (default: <none>)] alternate ztest path\n"
|
||||
"\t[-C vdev class state (default: random)] special=on|off|random\n"
|
||||
"\t[-o variable=value] ... set global variable to an unsigned\n"
|
||||
"\t 32-bit integer value\n"
|
||||
"\t[-G dump zfs_dbgmsg buffer before exiting due to an error\n"
|
||||
"\t[-h] (print help)\n"
|
||||
"",
|
||||
zo->zo_pool,
|
||||
(u_longlong_t)zo->zo_vdevs, /* -v */
|
||||
nice_vdev_size, /* -s */
|
||||
zo->zo_ashift, /* -a */
|
||||
zo->zo_mirrors, /* -m */
|
||||
zo->zo_raid_children, /* -r */
|
||||
zo->zo_raid_parity, /* -R */
|
||||
zo->zo_draid_data, /* -D */
|
||||
zo->zo_draid_spares, /* -S */
|
||||
zo->zo_datasets, /* -d */
|
||||
zo->zo_threads, /* -t */
|
||||
nice_force_ganging, /* -g */
|
||||
zo->zo_init, /* -i */
|
||||
(u_longlong_t)zo->zo_killrate, /* -k */
|
||||
zo->zo_pool, /* -p */
|
||||
zo->zo_dir, /* -f */
|
||||
(u_longlong_t)zo->zo_time, /* -T */
|
||||
(u_longlong_t)zo->zo_maxloops, /* -F */
|
||||
(u_longlong_t)zo->zo_passtime);
|
||||
exit(requested ? 0 : 1);
|
||||
}
|
||||
|
||||
|
@ -932,10 +817,8 @@ process_options(int argc, char **argv)
|
|||
|
||||
bcopy(&ztest_opts_defaults, zo, sizeof (*zo));
|
||||
|
||||
init_options();
|
||||
|
||||
while ((opt = getopt_long(argc, argv, short_opts, long_opts,
|
||||
NULL)) != EOF) {
|
||||
while ((opt = getopt(argc, argv,
|
||||
"v:s:a:m:r:R:K:D:S:d:t:g:i:k:p:f:MVET:P:hF:B:C:o:G")) != EOF) {
|
||||
value = 0;
|
||||
switch (opt) {
|
||||
case 'v':
|
||||
|
@ -1070,8 +953,6 @@ process_options(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
fini_options();
|
||||
|
||||
/* When raid choice is 'random' add a draid pool 50% of the time */
|
||||
if (strcmp(raid_kind, "random") == 0) {
|
||||
(void) strlcpy(raid_kind, (ztest_random(2) == 0) ?
|
||||
|
@ -1184,7 +1065,7 @@ ztest_kill(ztest_shared_t *zs)
|
|||
* See comment above spa_write_cachefile().
|
||||
*/
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE, B_FALSE);
|
||||
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
|
||||
(void) kill(getpid(), SIGKILL);
|
||||
|
@ -2193,7 +2074,6 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap)
|
|||
* but not always, because we also want to verify correct
|
||||
* behavior when the data was not recently read into cache.
|
||||
*/
|
||||
ASSERT(doi.doi_data_block_size);
|
||||
ASSERT0(offset % doi.doi_data_block_size);
|
||||
if (ztest_random(4) != 0) {
|
||||
int prefetch = ztest_random(2) ?
|
||||
|
@ -6670,7 +6550,7 @@ ztest_initialize(ztest_ds_t *zd, uint64_t id)
|
|||
char *path = strdup(rand_vd->vdev_path);
|
||||
boolean_t active = rand_vd->vdev_initialize_thread != NULL;
|
||||
|
||||
zfs_dbgmsg("vd %px, guid %llu", rand_vd, (u_longlong_t)guid);
|
||||
zfs_dbgmsg("vd %px, guid %llu", rand_vd, guid);
|
||||
spa_config_exit(spa, SCL_VDEV, FTAG);
|
||||
|
||||
uint64_t cmd = ztest_random(POOL_INITIALIZE_FUNCS);
|
||||
|
@ -6742,7 +6622,7 @@ ztest_trim(ztest_ds_t *zd, uint64_t id)
|
|||
char *path = strdup(rand_vd->vdev_path);
|
||||
boolean_t active = rand_vd->vdev_trim_thread != NULL;
|
||||
|
||||
zfs_dbgmsg("vd %p, guid %llu", rand_vd, (u_longlong_t)guid);
|
||||
zfs_dbgmsg("vd %p, guid %llu", rand_vd, guid);
|
||||
spa_config_exit(spa, SCL_VDEV, FTAG);
|
||||
|
||||
uint64_t cmd = ztest_random(POOL_TRIM_FUNCS);
|
||||
|
|
|
@ -38,39 +38,40 @@
|
|||
static int
|
||||
ioctl_get_msg(char *var, int fd)
|
||||
{
|
||||
int ret;
|
||||
int error = 0;
|
||||
char msg[ZFS_MAX_DATASET_NAME_LEN];
|
||||
|
||||
ret = ioctl(fd, BLKZNAME, msg);
|
||||
if (ret < 0) {
|
||||
return (ret);
|
||||
error = ioctl(fd, BLKZNAME, msg);
|
||||
if (error < 0) {
|
||||
return (error);
|
||||
}
|
||||
|
||||
snprintf(var, ZFS_MAX_DATASET_NAME_LEN, "%s", msg);
|
||||
return (ret);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int fd = -1, ret = 0, status = EXIT_FAILURE;
|
||||
int fd, error = 0;
|
||||
char zvol_name[ZFS_MAX_DATASET_NAME_LEN];
|
||||
char *zvol_name_part = NULL;
|
||||
char *dev_name;
|
||||
struct stat64 statbuf;
|
||||
int dev_minor, dev_part;
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s /dev/zvol_device_node\n", argv[0]);
|
||||
goto fail;
|
||||
printf("Usage: %s /dev/zvol_device_node\n", argv[0]);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
dev_name = argv[1];
|
||||
ret = stat64(dev_name, &statbuf);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Unable to access device file: %s\n", dev_name);
|
||||
goto fail;
|
||||
error = stat64(dev_name, &statbuf);
|
||||
if (error != 0) {
|
||||
printf("Unable to access device file: %s\n", dev_name);
|
||||
return (errno);
|
||||
}
|
||||
|
||||
dev_minor = minor(statbuf.st_rdev);
|
||||
|
@ -78,23 +79,23 @@ main(int argc, char **argv)
|
|||
|
||||
fd = open(dev_name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Unable to open device file: %s\n", dev_name);
|
||||
goto fail;
|
||||
printf("Unable to open device file: %s\n", dev_name);
|
||||
return (errno);
|
||||
}
|
||||
|
||||
ret = ioctl_get_msg(zvol_name, fd);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ioctl_get_msg failed: %s\n", strerror(errno));
|
||||
goto fail;
|
||||
error = ioctl_get_msg(zvol_name, fd);
|
||||
if (error < 0) {
|
||||
printf("ioctl_get_msg failed:%s\n", strerror(errno));
|
||||
return (errno);
|
||||
}
|
||||
if (dev_part > 0)
|
||||
ret = asprintf(&zvol_name_part, "%s-part%d", zvol_name,
|
||||
rc = asprintf(&zvol_name_part, "%s-part%d", zvol_name,
|
||||
dev_part);
|
||||
else
|
||||
ret = asprintf(&zvol_name_part, "%s", zvol_name);
|
||||
rc = asprintf(&zvol_name_part, "%s", zvol_name);
|
||||
|
||||
if (ret == -1 || zvol_name_part == NULL)
|
||||
goto fail;
|
||||
if (rc == -1 || zvol_name_part == NULL)
|
||||
goto error;
|
||||
|
||||
for (i = 0; i < strlen(zvol_name_part); i++) {
|
||||
if (isblank(zvol_name_part[i]))
|
||||
|
@ -102,13 +103,8 @@ main(int argc, char **argv)
|
|||
}
|
||||
|
||||
printf("%s\n", zvol_name_part);
|
||||
status = EXIT_SUCCESS;
|
||||
|
||||
fail:
|
||||
if (zvol_name_part)
|
||||
free(zvol_name_part);
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
|
||||
return (status);
|
||||
free(zvol_name_part);
|
||||
error:
|
||||
close(fd);
|
||||
return (error);
|
||||
}
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
include $(top_srcdir)/config/Shellcheck.am
|
||||
|
||||
dist_bin_SCRIPTS = zvol_wait
|
||||
|
|
|
@ -20,7 +20,6 @@ filter_out_deleted_zvols() {
|
|||
OIFS="$IFS"
|
||||
IFS="
|
||||
"
|
||||
# shellcheck disable=SC2086
|
||||
zfs list -H -o name $zvols 2>/dev/null
|
||||
IFS="$OIFS"
|
||||
}
|
||||
|
@ -28,17 +27,15 @@ filter_out_deleted_zvols() {
|
|||
list_zvols() {
|
||||
read -r default_volmode < /sys/module/zfs/parameters/zvol_volmode
|
||||
zfs list -t volume -H -o \
|
||||
name,volmode,receive_resume_token,redact_snaps,keystatus |
|
||||
while IFS=" " read -r name volmode token redacted keystatus; do # IFS=\t here!
|
||||
name,volmode,receive_resume_token,redact_snaps |
|
||||
while IFS=" " read -r name volmode token redacted; do # IFS=\t here!
|
||||
|
||||
# /dev links are not created for zvols with volmode = "none",
|
||||
# redacted zvols, or encrypted zvols for which the key has not
|
||||
# been loaded.
|
||||
# /dev links are not created for zvols with volmode = "none"
|
||||
# or for redacted zvols.
|
||||
[ "$volmode" = "none" ] && continue
|
||||
[ "$volmode" = "default" ] && [ "$default_volmode" = "3" ] &&
|
||||
continue
|
||||
[ "$redacted" = "-" ] || continue
|
||||
[ "$keystatus" = "unavailable" ] && continue
|
||||
|
||||
# We also ignore partially received zvols if it is
|
||||
# not an incremental receive, as those won't even have a block
|
||||
|
@ -109,13 +106,6 @@ while [ "$outer_loop" -lt 20 ]; do
|
|||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# zvol_count made some progress - let's stay in this loop.
|
||||
#
|
||||
if [ "$old_zvols_count" -gt "$zvols_count" ]; then
|
||||
outer_loop=$((outer_loop - 1))
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Timed out waiting on zvol links"
|
||||
|
|
|
@ -25,9 +25,5 @@ checkabi:
|
|||
storeabi:
|
||||
cd .libs ; \
|
||||
for lib in $(lib_LTLIBRARIES) ; do \
|
||||
abidw --no-show-locs \
|
||||
--no-corpus-path \
|
||||
--no-comp-dir-path \
|
||||
--type-id-style hash \
|
||||
$${lib%.la}.so > ../$${lib%.la}.abi ; \
|
||||
abidw $${lib%.la}.so > ../$${lib%.la}.abi ; \
|
||||
done
|
||||
|
|
|
@ -26,7 +26,6 @@ AM_LIBTOOLFLAGS = --silent
|
|||
AM_CFLAGS = -std=gnu99 -Wall -Wstrict-prototypes -Wmissing-prototypes
|
||||
AM_CFLAGS += -fno-strict-aliasing
|
||||
AM_CFLAGS += $(NO_OMIT_FRAME_POINTER)
|
||||
AM_CFLAGS += $(IMPLICIT_FALLTHROUGH)
|
||||
AM_CFLAGS += $(DEBUG_CFLAGS)
|
||||
AM_CFLAGS += $(ASAN_CFLAGS)
|
||||
AM_CFLAGS += $(CODE_COVERAGE_CFLAGS) $(NO_FORMAT_ZERO_LENGTH)
|
||||
|
@ -40,8 +39,8 @@ AM_CPPFLAGS = -D_GNU_SOURCE
|
|||
AM_CPPFLAGS += -D_REENTRANT
|
||||
AM_CPPFLAGS += -D_FILE_OFFSET_BITS=64
|
||||
AM_CPPFLAGS += -D_LARGEFILE64_SOURCE
|
||||
AM_CPPFLAGS += -DHAVE_LARGE_STACKS=1
|
||||
AM_CPPFLAGS += -DLIBEXECDIR=\"$(libexecdir)\"
|
||||
AM_CPPFLAGS += -DZFSEXECDIR=\"$(zfsexecdir)\"
|
||||
AM_CPPFLAGS += -DRUNSTATEDIR=\"$(runstatedir)\"
|
||||
AM_CPPFLAGS += -DSBINDIR=\"$(sbindir)\"
|
||||
AM_CPPFLAGS += -DSYSCONFDIR=\"$(sysconfdir)\"
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
.PHONY: shellcheck
|
||||
shellcheck: $(SCRIPTS) $(SHELLCHECKSCRIPTS)
|
||||
if HAVE_SHELLCHECK
|
||||
[ -z "$(SCRIPTS)$(SHELLCHECKSCRIPTS)" ] && exit; shellcheck $$([ -n "$(SHELLCHECK_SHELL)" ] && echo "--shell=$(SHELLCHECK_SHELL)") --exclude=SC1090,SC1091$(SHELLCHECK_IGNORE) --format=gcc $(SCRIPTS) $(SHELLCHECKSCRIPTS)
|
||||
else
|
||||
@[ -z "$(SCRIPTS)$(SHELLCHECKSCRIPTS)" ] && exit; echo "skipping shellcheck of" $(SCRIPTS) $(SHELLCHECKSCRIPTS) "because shellcheck is not installed"
|
||||
endif
|
||||
@set -e; for dir in $(SHELLCHECKDIRS); do $(MAKE) -C $$dir shellcheck; done
|
||||
|
||||
|
||||
# command -v *is* specified by POSIX and every shell in existence supports it
|
||||
.PHONY: checkbashisms
|
||||
checkbashisms: $(SCRIPTS) $(SHELLCHECKSCRIPTS)
|
||||
if HAVE_CHECKBASHISMS
|
||||
[ -z "$(SCRIPTS)$(SHELLCHECKSCRIPTS)" ] && exit; ! if [ -z "$(SHELLCHECK_SHELL)" ]; then \
|
||||
checkbashisms -npx $(SCRIPTS) $(SHELLCHECKSCRIPTS); else \
|
||||
for f in $(SCRIPTS) $(SHELLCHECKSCRIPTS); do echo $$f >&3; { echo '#!/bin/$(SHELLCHECK_SHELL)'; cat $$f; } | checkbashisms -npx; done; \
|
||||
fi 3>&2 2>&1 | grep -vFe "'command' with option other than -p" -e 'command -v' $(CHECKBASHISMS_IGNORE) >&2
|
||||
else
|
||||
@[ -z "$(SCRIPTS)$(SHELLCHECKSCRIPTS)" ] && exit; echo "skipping checkbashisms of" $(SCRIPTS) $(SHELLCHECKSCRIPTS) "because checkbashisms is not installed"
|
||||
endif
|
||||
@set -e; for dir in $(SHELLCHECKDIRS); do $(MAKE) -C $$dir checkbashisms; done
|
|
@ -15,9 +15,7 @@ subst_sed_cmd = \
|
|||
-e 's|@PYTHON[@]|$(PYTHON)|g' \
|
||||
-e 's|@PYTHON_SHEBANG[@]|$(PYTHON_SHEBANG)|g' \
|
||||
-e 's|@DEFAULT_INIT_NFS_SERVER[@]|$(DEFAULT_INIT_NFS_SERVER)|g' \
|
||||
-e 's|@DEFAULT_INIT_SHELL[@]|$(DEFAULT_INIT_SHELL)|g' \
|
||||
-e 's|@LIBFETCH_DYNAMIC[@]|$(LIBFETCH_DYNAMIC)|g' \
|
||||
-e 's|@LIBFETCH_SONAME[@]|$(LIBFETCH_SONAME)|g'
|
||||
-e 's|@DEFAULT_INIT_SHELL[@]|$(DEFAULT_INIT_SHELL)|g'
|
||||
|
||||
SUBSTFILES =
|
||||
CLEANFILES = $(SUBSTFILES)
|
||||
|
|
|
@ -88,7 +88,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_TRUNCATION], [
|
|||
])
|
||||
|
||||
dnl #
|
||||
dnl # Check if gcc supports -Wno-format-zero-length option.
|
||||
dnl # Check if gcc supports -Wno-format-truncation option.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_ZERO_LENGTH], [
|
||||
AC_MSG_CHECKING([whether $CC supports -Wno-format-zero-length])
|
||||
|
@ -108,132 +108,57 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_ZERO_LENGTH], [
|
|||
AC_SUBST([NO_FORMAT_ZERO_LENGTH])
|
||||
])
|
||||
|
||||
|
||||
dnl #
|
||||
dnl # Check if gcc supports -Wno-clobbered option.
|
||||
dnl # Check if gcc supports -Wno-bool-compare option.
|
||||
dnl #
|
||||
dnl # We actually invoke gcc with the -Wclobbered option
|
||||
dnl # We actually invoke gcc with the -Wbool-compare option
|
||||
dnl # and infer the 'no-' version does or doesn't exist based upon
|
||||
dnl # the results. This is required because when checking any of
|
||||
dnl # no- prefixed options gcc always returns success.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_CLOBBERED], [
|
||||
AC_MSG_CHECKING([whether $CC supports -Wno-clobbered])
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_BOOL_COMPARE], [
|
||||
AC_MSG_CHECKING([whether $CC supports -Wno-bool-compare])
|
||||
|
||||
saved_flags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror -Wclobbered"
|
||||
CFLAGS="$CFLAGS -Werror -Wbool-compare"
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||
NO_CLOBBERED=-Wno-clobbered
|
||||
NO_BOOL_COMPARE=-Wno-bool-compare
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
NO_CLOBBERED=
|
||||
NO_BOOL_COMPARE=
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
|
||||
CFLAGS="$saved_flags"
|
||||
AC_SUBST([NO_CLOBBERED])
|
||||
AC_SUBST([NO_BOOL_COMPARE])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Check if gcc supports -Wimplicit-fallthrough option.
|
||||
dnl # Check if gcc supports -Wno-unused-but-set-variable option.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_IMPLICIT_FALLTHROUGH], [
|
||||
AC_MSG_CHECKING([whether $CC supports -Wimplicit-fallthrough])
|
||||
dnl # We actually invoke gcc with the -Wunused-but-set-variable option
|
||||
dnl # and infer the 'no-' version does or doesn't exist based upon
|
||||
dnl # the results. This is required because when checking any of
|
||||
dnl # no- prefixed options gcc always returns success.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_UNUSED_BUT_SET_VARIABLE], [
|
||||
AC_MSG_CHECKING([whether $CC supports -Wno-unused-but-set-variable])
|
||||
|
||||
saved_flags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror -Wimplicit-fallthrough"
|
||||
CFLAGS="$CFLAGS -Werror -Wunused-but-set-variable"
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||
IMPLICIT_FALLTHROUGH=-Wimplicit-fallthrough
|
||||
AC_DEFINE([HAVE_IMPLICIT_FALLTHROUGH], 1,
|
||||
[Define if compiler supports -Wimplicit-fallthrough])
|
||||
NO_UNUSED_BUT_SET_VARIABLE=-Wno-unused-but-set-variable
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
IMPLICIT_FALLTHROUGH=
|
||||
NO_UNUSED_BUT_SET_VARIABLE=
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
|
||||
CFLAGS="$saved_flags"
|
||||
AC_SUBST([IMPLICIT_FALLTHROUGH])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Check if cc supports -Winfinite-recursion option.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_INFINITE_RECURSION], [
|
||||
AC_MSG_CHECKING([whether $CC supports -Winfinite-recursion])
|
||||
|
||||
saved_flags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror -Winfinite-recursion"
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||
INFINITE_RECURSION=-Winfinite-recursion
|
||||
AC_DEFINE([HAVE_INFINITE_RECURSION], 1,
|
||||
[Define if compiler supports -Winfinite-recursion])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
INFINITE_RECURSION=
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
|
||||
CFLAGS="$saved_flags"
|
||||
AC_SUBST([INFINITE_RECURSION])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Check if kernel cc supports -Winfinite-recursion option.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_KERNEL_CC_INFINITE_RECURSION], [
|
||||
AC_MSG_CHECKING([whether $KERNEL_CC supports -Winfinite-recursion])
|
||||
|
||||
saved_cc="$CC"
|
||||
saved_flags="$CFLAGS"
|
||||
CC="gcc"
|
||||
CFLAGS="$CFLAGS -Werror -Winfinite-recursion"
|
||||
|
||||
AS_IF([ test -n "$KERNEL_CC" ], [
|
||||
CC="$KERNEL_CC"
|
||||
])
|
||||
AS_IF([ test -n "$KERNEL_LLVM" ], [
|
||||
CC="clang"
|
||||
])
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||
KERNEL_INFINITE_RECURSION=-Winfinite-recursion
|
||||
AC_DEFINE([HAVE_KERNEL_INFINITE_RECURSION], 1,
|
||||
[Define if compiler supports -Winfinite-recursion])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
KERNEL_INFINITE_RECURSION=
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
|
||||
CC="$saved_cc"
|
||||
CFLAGS="$saved_flags"
|
||||
AC_SUBST([KERNEL_INFINITE_RECURSION])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Check if cc supports -Wformat-overflow option.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_FORMAT_OVERFLOW], [
|
||||
AC_MSG_CHECKING([whether $CC supports -Wformat-overflow])
|
||||
|
||||
saved_flags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror -Wformat-overflow"
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||
FORMAT_OVERFLOW=-Wformat-overflow
|
||||
AC_DEFINE([HAVE_FORMAT_OVERFLOW], 1,
|
||||
[Define if compiler supports -Wformat-overflow])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
FORMAT_OVERFLOW=
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
|
||||
CFLAGS="$saved_flags"
|
||||
AC_SUBST([FORMAT_OVERFLOW])
|
||||
AC_SUBST([NO_UNUSED_BUT_SET_VARIABLE])
|
||||
])
|
||||
|
||||
dnl #
|
||||
|
@ -277,34 +202,3 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_IPA_SRA], [
|
|||
CFLAGS="$saved_flags"
|
||||
AC_SUBST([NO_IPA_SRA])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Check if kernel cc supports -fno-ipa-sra option.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_KERNEL_CC_NO_IPA_SRA], [
|
||||
AC_MSG_CHECKING([whether $KERNEL_CC supports -fno-ipa-sra])
|
||||
|
||||
saved_cc="$CC"
|
||||
saved_flags="$CFLAGS"
|
||||
CC="gcc"
|
||||
CFLAGS="$CFLAGS -Werror -fno-ipa-sra"
|
||||
|
||||
AS_IF([ test -n "$KERNEL_CC" ], [
|
||||
CC="$KERNEL_CC"
|
||||
])
|
||||
AS_IF([ test -n "$KERNEL_LLVM" ], [
|
||||
CC="clang"
|
||||
])
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||
KERNEL_NO_IPA_SRA=-fno-ipa-sra
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
KERNEL_NO_IPA_SRA=
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
|
||||
CC="$saved_cc"
|
||||
CFLAGS="$saved_flags"
|
||||
AC_SUBST([KERNEL_NO_IPA_SRA])
|
||||
])
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
dnl #
|
||||
dnl # Check if GNU parallel is available.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PARALLEL], [
|
||||
AC_CHECK_PROG([PARALLEL], [parallel], [yes])
|
||||
|
||||
AM_CONDITIONAL([HAVE_PARALLEL], [test "x$PARALLEL" = "xyes"])
|
||||
])
|
|
@ -1,6 +1,7 @@
|
|||
dnl #
|
||||
dnl # The majority of the python scripts are written to be compatible
|
||||
dnl # with Python 3.6. This option is intended to
|
||||
dnl # with Python 2.6 and Python 3.4. Therefore, they may be installed
|
||||
dnl # and used with either interpreter. This option is intended to
|
||||
dnl # to provide a method to specify the default system version, and
|
||||
dnl # set the PYTHON environment variable accordingly.
|
||||
dnl #
|
||||
|
@ -12,7 +13,9 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYTHON], [
|
|||
[with_python=check])
|
||||
|
||||
AS_CASE([$with_python],
|
||||
[check], [AC_CHECK_PROGS([PYTHON], [python3], [:])],
|
||||
[check], [AC_CHECK_PROGS([PYTHON], [python3 python2], [:])],
|
||||
[2*], [PYTHON="python${with_python}"],
|
||||
[*python2*], [PYTHON="${with_python}"],
|
||||
[3*], [PYTHON="python${with_python}"],
|
||||
[*python3*], [PYTHON="${with_python}"],
|
||||
[no], [PYTHON=":"],
|
||||
|
@ -20,25 +23,35 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYTHON], [
|
|||
)
|
||||
|
||||
dnl #
|
||||
dnl # Minimum supported Python versions for utilities: Python 3.6
|
||||
dnl # Minimum supported Python versions for utilities:
|
||||
dnl # Python 2.6 or Python 3.4
|
||||
dnl #
|
||||
AM_PATH_PYTHON([], [], [:])
|
||||
AS_IF([test -z "$PYTHON_VERSION"], [
|
||||
PYTHON_VERSION=$(echo ${PYTHON##*/} | tr -cd 0-9.)
|
||||
PYTHON_VERSION=$(basename $PYTHON | tr -cd 0-9.)
|
||||
])
|
||||
PYTHON_MINOR=${PYTHON_VERSION#*\.}
|
||||
|
||||
AS_CASE([$PYTHON_VERSION],
|
||||
[3.*], [
|
||||
[2.*], [
|
||||
AS_IF([test $PYTHON_MINOR -lt 6],
|
||||
[AC_MSG_ERROR("Python >= 3.6 is required")])
|
||||
[AC_MSG_ERROR("Python >= 2.6 is required")])
|
||||
],
|
||||
[3.*], [
|
||||
AS_IF([test $PYTHON_MINOR -lt 4],
|
||||
[AC_MSG_ERROR("Python >= 3.4 is required")])
|
||||
],
|
||||
[:|2|3], [],
|
||||
[PYTHON_VERSION=3]
|
||||
)
|
||||
|
||||
AM_CONDITIONAL([USING_PYTHON], [test "$PYTHON" != :])
|
||||
AC_SUBST([PYTHON_SHEBANG], [python3])
|
||||
AM_CONDITIONAL([USING_PYTHON_2], [test "x${PYTHON_VERSION%%\.*}" = x2])
|
||||
AM_CONDITIONAL([USING_PYTHON_3], [test "x${PYTHON_VERSION%%\.*}" = x3])
|
||||
|
||||
AM_COND_IF([USING_PYTHON_2],
|
||||
[AC_SUBST([PYTHON_SHEBANG], [python2])],
|
||||
[AC_SUBST([PYTHON_SHEBANG], [python3])])
|
||||
|
||||
dnl #
|
||||
dnl # Request that packages be built for a specific Python version.
|
||||
|
|
|
@ -6,7 +6,7 @@ dnl # https://www.gnu.org/software/autoconf-archive/ax_python_module.html
|
|||
dnl # Required by ZFS_AC_CONFIG_ALWAYS_PYZFS.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_PYTHON_MODULE], [
|
||||
PYTHON_NAME=${PYTHON##*/}
|
||||
PYTHON_NAME=$(basename $PYTHON)
|
||||
AC_MSG_CHECKING([for $PYTHON_NAME module: $1])
|
||||
AS_IF([$PYTHON -c "import $1" 2>/dev/null], [
|
||||
AC_MSG_RESULT(yes)
|
||||
|
@ -18,7 +18,7 @@ AC_DEFUN([ZFS_AC_PYTHON_MODULE], [
|
|||
])
|
||||
|
||||
dnl #
|
||||
dnl # Determines if pyzfs can be built, requires Python 3.6 or later.
|
||||
dnl # Determines if pyzfs can be built, requires Python 2.7 or later.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
||||
AC_ARG_ENABLE([pyzfs],
|
||||
|
@ -47,36 +47,12 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
|||
AC_SUBST(DEFINE_PYZFS)
|
||||
|
||||
dnl #
|
||||
dnl # Autodetection disables pyzfs if kernel or srpm config
|
||||
dnl #
|
||||
AS_IF([test "x$enable_pyzfs" = xcheck], [
|
||||
AS_IF([test "x$ZFS_CONFIG" = xkernel -o "x$ZFS_CONFIG" = xsrpm ], [
|
||||
enable_pyzfs=no
|
||||
AC_MSG_NOTICE([Disabling pyzfs for kernel/srpm config])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Python "packaging" (or, failing that, "distlib") module is required to build and install pyzfs
|
||||
dnl #
|
||||
AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [
|
||||
ZFS_AC_PYTHON_MODULE([packaging], [], [
|
||||
ZFS_AC_PYTHON_MODULE([distlib], [], [
|
||||
AS_IF([test "x$enable_pyzfs" = xyes], [
|
||||
AC_MSG_ERROR("Python $PYTHON_VERSION packaging and distlib modules are not installed")
|
||||
], [test "x$enable_pyzfs" != xno], [
|
||||
enable_pyzfs=no
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Require python3-devel libraries
|
||||
dnl # Require python-devel libraries
|
||||
dnl #
|
||||
AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [
|
||||
AS_CASE([$PYTHON_VERSION],
|
||||
[3.*], [PYTHON_REQUIRED_VERSION=">= '3.6.0'"],
|
||||
[3.*], [PYTHON_REQUIRED_VERSION=">= '3.4.0'"],
|
||||
[2.*], [PYTHON_REQUIRED_VERSION=">= '2.7.0'"],
|
||||
[AC_MSG_ERROR("Python $PYTHON_VERSION unknown")]
|
||||
)
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
dnl #
|
||||
dnl # Check if shellcheck and/or checkbashisms are available.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_SHELLCHECK], [
|
||||
AC_CHECK_PROG([SHELLCHECK], [shellcheck], [yes])
|
||||
AC_CHECK_PROG([CHECKBASHISMS], [checkbashisms], [yes])
|
||||
|
||||
AM_CONDITIONAL([HAVE_SHELLCHECK], [test "x$SHELLCHECK" = "xyes"])
|
||||
AM_CONDITIONAL([HAVE_CHECKBASHISMS], [test "x$CHECKBASHISMS" = "xyes"])
|
||||
])
|
|
@ -103,7 +103,8 @@ AC_DEFUN([AX_PYTHON_DEVEL],[
|
|||
if test "$ac_supports_python_ver" != "True"; then
|
||||
if test -z "$PYTHON_NOVERSIONCHECK"; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_FAILURE([
|
||||
m4_ifvaln([$2],[$2],[
|
||||
AC_MSG_FAILURE([
|
||||
This version of the AC@&t@_PYTHON_DEVEL macro
|
||||
doesn't work properly with versions of Python before
|
||||
2.1.0. You may need to re-run configure, setting the
|
||||
|
@ -112,6 +113,7 @@ PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
|
|||
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
|
||||
to something else than an empty string.
|
||||
])
|
||||
])
|
||||
else
|
||||
AC_MSG_RESULT([skip at user request])
|
||||
fi
|
||||
|
@ -120,47 +122,25 @@ to something else than an empty string.
|
|||
fi
|
||||
|
||||
#
|
||||
# If the macro parameter ``version'' is set, honour it.
|
||||
# A Python shim class, VPy, is used to implement correct version comparisons via
|
||||
# string expressions, since e.g. a naive textual ">= 2.7.3" won't work for
|
||||
# Python 2.7.10 (the ".1" being evaluated as less than ".3").
|
||||
# if the macro parameter ``version'' is set, honour it
|
||||
#
|
||||
if test -n "$1"; then
|
||||
AC_MSG_CHECKING([for a version of Python $1])
|
||||
cat << EOF > ax_python_devel_vpy.py
|
||||
class VPy:
|
||||
def vtup(self, s):
|
||||
return tuple(map(int, s.strip().replace("rc", ".").split(".")))
|
||||
def __init__(self):
|
||||
import sys
|
||||
self.vpy = tuple(sys.version_info)
|
||||
def __eq__(self, s):
|
||||
return self.vpy == self.vtup(s)
|
||||
def __ne__(self, s):
|
||||
return self.vpy != self.vtup(s)
|
||||
def __lt__(self, s):
|
||||
return self.vpy < self.vtup(s)
|
||||
def __gt__(self, s):
|
||||
return self.vpy > self.vtup(s)
|
||||
def __le__(self, s):
|
||||
return self.vpy <= self.vtup(s)
|
||||
def __ge__(self, s):
|
||||
return self.vpy >= self.vtup(s)
|
||||
EOF
|
||||
ac_supports_python_ver=`$PYTHON -c "import ax_python_devel_vpy; \
|
||||
ver = ax_python_devel_vpy.VPy(); \
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys; \
|
||||
ver = sys.version.split ()[[0]]; \
|
||||
print (ver $1)"`
|
||||
rm -rf ax_python_devel_vpy*.py* __pycache__/ax_python_devel_vpy*.py*
|
||||
if test "$ac_supports_python_ver" = "True"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([this package requires Python $1.
|
||||
m4_ifvaln([$2],[$2],[
|
||||
AC_MSG_ERROR([this package requires Python $1.
|
||||
If you have it installed, but it isn't the default Python
|
||||
interpreter in your system path, please pass the PYTHON_VERSION
|
||||
variable to configure. See ``configure --help'' for reference.
|
||||
])
|
||||
PYTHON_VERSION=""
|
||||
PYTHON_VERSION=""
|
||||
])
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -168,7 +148,8 @@ variable to configure. See ``configure --help'' for reference.
|
|||
# Check if you have distutils, else fail
|
||||
#
|
||||
AC_MSG_CHECKING([for the distutils Python package])
|
||||
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
|
||||
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
|
||||
if test $? -eq 0; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
|
@ -223,7 +204,7 @@ EOD`
|
|||
ac_python_version=$PYTHON_VERSION
|
||||
else
|
||||
ac_python_version=`$PYTHON -c "import sys; \
|
||||
print ('.'.join(sys.version.split('.')[[:2]]))"`
|
||||
print (sys.version[[:3]])"`
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ deb-utils: deb-local rpm-utils-initramfs
|
|||
## to do this, so we install a shim onto the path which calls the real
|
||||
## dh_shlibdeps with the required arguments.
|
||||
path_prepend=`mktemp -d /tmp/intercept.XXXXXX`; \
|
||||
echo "#!$(SHELL)" > $${path_prepend}/dh_shlibdeps; \
|
||||
echo "#$(SHELL)" > $${path_prepend}/dh_shlibdeps; \
|
||||
echo "`which dh_shlibdeps` -- \
|
||||
-xlibuutil3linux -xlibnvpair3linux -xlibzfs5linux -xlibzpool5linux" \
|
||||
>> $${path_prepend}/dh_shlibdeps; \
|
||||
|
@ -74,7 +74,7 @@ deb-utils: deb-local rpm-utils-initramfs
|
|||
## Debianized packages from the auto-generated dependencies of the new debs,
|
||||
## which should NOT be mixed with the alien-generated debs created here
|
||||
chmod +x $${path_prepend}/dh_shlibdeps; \
|
||||
env "PATH=$${path_prepend}:$${PATH}" \
|
||||
env PATH=$${path_prepend}:$${PATH} \
|
||||
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch \
|
||||
$$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
|
||||
$$pkg8 $$pkg9 $$pkg10 || exit 1; \
|
||||
|
|
|
@ -162,17 +162,11 @@ dnl #
|
|||
dnl # 3.1 API change,
|
||||
dnl # Check if inode_operations contains the function get_acl
|
||||
dnl #
|
||||
dnl # 5.15 API change,
|
||||
dnl # Added the bool rcu argument to get_acl for rcu path walk.
|
||||
dnl #
|
||||
dnl # 6.2 API change,
|
||||
dnl # get_acl() was renamed to get_inode_acl()
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
|
||||
ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static struct posix_acl *get_acl_fn(struct inode *inode, int type)
|
||||
struct posix_acl *get_acl_fn(struct inode *inode, int type)
|
||||
{ return NULL; }
|
||||
|
||||
static const struct inode_operations
|
||||
|
@ -180,49 +174,14 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
|
|||
.get_acl = get_acl_fn,
|
||||
};
|
||||
],[])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([inode_operations_get_acl_rcu], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static struct posix_acl *get_acl_fn(struct inode *inode, int type,
|
||||
bool rcu) { return NULL; }
|
||||
|
||||
static const struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.get_acl = get_acl_fn,
|
||||
};
|
||||
],[])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([inode_operations_get_inode_acl], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static struct posix_acl *get_inode_acl_fn(struct inode *inode, int type,
|
||||
bool rcu) { return NULL; }
|
||||
|
||||
static const struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.get_inode_acl = get_inode_acl_fn,
|
||||
};
|
||||
],[])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
|
||||
AC_MSG_CHECKING([whether iops->get_acl() exists])
|
||||
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GET_ACL, 1, [iops->get_acl() exists])
|
||||
],[
|
||||
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl_rcu], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GET_ACL_RCU, 1, [iops->get_acl() takes rcu])
|
||||
],[
|
||||
ZFS_LINUX_TEST_RESULT([inode_operations_get_inode_acl], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GET_INODE_ACL, 1, [has iops->get_inode_acl()])
|
||||
],[
|
||||
ZFS_LINUX_TEST_ERROR([iops->get_acl() or iops->get_inode_acl()])
|
||||
])
|
||||
])
|
||||
ZFS_LINUX_TEST_ERROR([iops->get_acl()])
|
||||
])
|
||||
])
|
||||
|
||||
|
@ -230,56 +189,11 @@ dnl #
|
|||
dnl # 3.14 API change,
|
||||
dnl # Check if inode_operations contains the function set_acl
|
||||
dnl #
|
||||
dnl # 5.12 API change,
|
||||
dnl # set_acl() added a user_namespace* parameter first
|
||||
dnl #
|
||||
dnl # 6.2 API change,
|
||||
dnl # set_acl() second paramter changed to a struct dentry *
|
||||
dnl #
|
||||
dnl # 6.3 API change,
|
||||
dnl # set_acl() first parameter changed to struct mnt_idmap *
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
|
||||
ZFS_LINUX_TEST_SRC([inode_operations_set_acl_mnt_idmap_dentry], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static int set_acl_fn(struct mnt_idmap *idmap,
|
||||
struct dentry *dent, struct posix_acl *acl,
|
||||
int type) { return 0; }
|
||||
|
||||
static const struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.set_acl = set_acl_fn,
|
||||
};
|
||||
],[])
|
||||
ZFS_LINUX_TEST_SRC([inode_operations_set_acl_userns_dentry], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static int set_acl_fn(struct user_namespace *userns,
|
||||
struct dentry *dent, struct posix_acl *acl,
|
||||
int type) { return 0; }
|
||||
|
||||
static const struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.set_acl = set_acl_fn,
|
||||
};
|
||||
],[])
|
||||
ZFS_LINUX_TEST_SRC([inode_operations_set_acl_userns], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static int set_acl_fn(struct user_namespace *userns,
|
||||
struct inode *inode, struct posix_acl *acl,
|
||||
int type) { return 0; }
|
||||
|
||||
static const struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.set_acl = set_acl_fn,
|
||||
};
|
||||
],[])
|
||||
ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static int set_acl_fn(struct inode *inode, struct posix_acl *acl,
|
||||
int set_acl_fn(struct inode *inode, struct posix_acl *acl,
|
||||
int type) { return 0; }
|
||||
|
||||
static const struct inode_operations
|
||||
|
@ -291,31 +205,11 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
|
|||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
|
||||
AC_MSG_CHECKING([whether iops->set_acl() exists])
|
||||
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl_userns], [
|
||||
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
|
||||
AC_DEFINE(HAVE_SET_ACL_USERNS, 1, [iops->set_acl() takes 4 args])
|
||||
],[
|
||||
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl_mnt_idmap_dentry], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
|
||||
AC_DEFINE(HAVE_SET_ACL_IDMAP_DENTRY, 1,
|
||||
[iops->set_acl() takes 4 args, arg1 is struct mnt_idmap *])
|
||||
],[
|
||||
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl_userns_dentry], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
|
||||
AC_DEFINE(HAVE_SET_ACL_USERNS_DENTRY_ARG2, 1,
|
||||
[iops->set_acl() takes 4 args, arg2 is struct dentry *])
|
||||
],[
|
||||
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists, takes 3 args])
|
||||
],[
|
||||
ZFS_LINUX_REQUIRE_API([i_op->set_acl()], [3.14])
|
||||
])
|
||||
])
|
||||
])
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
dnl #
|
||||
dnl # 5.16 API change
|
||||
dnl # add_disk grew a must-check return code
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_ADD_DISK], [
|
||||
ZFS_LINUX_TEST_SRC([add_disk_ret], [
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct gendisk *disk = NULL;
|
||||
int error __attribute__ ((unused)) = add_disk(disk);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_ADD_DISK], [
|
||||
AC_MSG_CHECKING([whether add_disk() returns int])
|
||||
ZFS_LINUX_TEST_RESULT([add_disk_ret],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_ADD_DISK_RET, 1,
|
||||
[add_disk() returns int])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
|
@ -8,7 +8,7 @@ dnl #
|
|||
AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [
|
||||
ZFS_LINUX_TEST_SRC([dentry_operations_d_automount], [
|
||||
#include <linux/dcache.h>
|
||||
static struct vfsmount *d_automount(struct path *p) { return NULL; }
|
||||
struct vfsmount *d_automount(struct path *p) { return NULL; }
|
||||
struct dentry_operations dops __attribute__ ((unused)) = {
|
||||
.d_automount = d_automount,
|
||||
};
|
||||
|
|
|
@ -8,9 +8,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BDI], [
|
|||
], [
|
||||
char *name = "bdi";
|
||||
atomic_long_t zfs_bdi_seq;
|
||||
int error __attribute__((unused));
|
||||
atomic_long_set(&zfs_bdi_seq, 0);
|
||||
error =
|
||||
int error __attribute__((unused)) =
|
||||
super_setup_bdi_name(&sb, "%.28s-%ld", name,
|
||||
atomic_long_inc_return(&zfs_bdi_seq));
|
||||
])
|
||||
|
|
|
@ -191,24 +191,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_SET_DEV], [
|
|||
], [], [ZFS_META_LICENSE])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Linux 5.16 API
|
||||
dnl #
|
||||
dnl # bio_set_dev is no longer a helper macro and is now an inline function,
|
||||
dnl # meaning that the function it calls internally can no longer be overridden
|
||||
dnl # by our code
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_SET_DEV_MACRO], [
|
||||
ZFS_LINUX_TEST_SRC([bio_set_dev_macro], [
|
||||
#include <linux/bio.h>
|
||||
#include <linux/fs.h>
|
||||
],[
|
||||
#ifndef bio_set_dev
|
||||
#error Not a macro
|
||||
#endif
|
||||
], [], [ZFS_META_LICENSE])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV], [
|
||||
AC_MSG_CHECKING([whether bio_set_dev() is available])
|
||||
ZFS_LINUX_TEST_RESULT([bio_set_dev], [
|
||||
|
@ -223,15 +205,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV], [
|
|||
AC_DEFINE(HAVE_BIO_SET_DEV_GPL_ONLY, 1,
|
||||
[bio_set_dev() GPL-only])
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([whether bio_set_dev() is a macro])
|
||||
ZFS_LINUX_TEST_RESULT([bio_set_dev_macro], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BIO_SET_DEV_MACRO, 1,
|
||||
[bio_set_dev() is a macro])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
@ -247,7 +220,7 @@ dnl #
|
|||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_END_IO_T_ARGS], [
|
||||
ZFS_LINUX_TEST_SRC([bio_end_io_t_args], [
|
||||
#include <linux/bio.h>
|
||||
static void wanted_end_io(struct bio *bio) { return; }
|
||||
void wanted_end_io(struct bio *bio) { return; }
|
||||
bio_end_io_t *end_io __attribute__ ((unused)) = wanted_end_io;
|
||||
], [])
|
||||
])
|
||||
|
@ -321,8 +294,9 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_SUBMIT_BIO], [
|
|||
ZFS_LINUX_TEST_SRC([submit_bio], [
|
||||
#include <linux/bio.h>
|
||||
],[
|
||||
blk_qc_t blk_qc;
|
||||
struct bio *bio = NULL;
|
||||
(void) submit_bio(bio);
|
||||
blk_qc = submit_bio(bio);
|
||||
])
|
||||
])
|
||||
|
||||
|
@ -422,93 +396,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO_BDEV_DISK], [
|
|||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Linux 5.16 API
|
||||
dnl #
|
||||
dnl # The Linux 5.16 API for submit_bio changed the return type to be
|
||||
dnl # void instead of int
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BDEV_SUBMIT_BIO_RETURNS_VOID], [
|
||||
ZFS_LINUX_TEST_SRC([bio_bdev_submit_bio_void], [
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct block_device_operations *bdev = NULL;
|
||||
__attribute__((unused)) void(*f)(struct bio *) = bdev->submit_bio;
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BDEV_SUBMIT_BIO_RETURNS_VOID], [
|
||||
AC_MSG_CHECKING(
|
||||
[whether block_device_operations->submit_bio() returns void])
|
||||
ZFS_LINUX_TEST_RESULT([bio_bdev_submit_bio_void], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BDEV_SUBMIT_BIO_RETURNS_VOID, 1,
|
||||
[block_device_operations->submit_bio() returns void])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Linux 5.16 API
|
||||
dnl #
|
||||
dnl # The Linux 5.16 API moved struct blkcg_gq into linux/blk-cgroup.h, which
|
||||
dnl # has been around since 2015. This test looks for the presence of that
|
||||
dnl # header, so that it can be conditionally included where it exists, but
|
||||
dnl # still be backward compatible with kernels that pre-date its introduction.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_CGROUP_HEADER], [
|
||||
ZFS_LINUX_TEST_SRC([blk_cgroup_header], [
|
||||
#include <linux/blk-cgroup.h>
|
||||
], [])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_CGROUP_HEADER], [
|
||||
AC_MSG_CHECKING([whether linux/blk-cgroup.h exists])
|
||||
ZFS_LINUX_TEST_RESULT([blk_cgroup_header],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_LINUX_BLK_CGROUP_HEADER, 1,
|
||||
[linux/blk-cgroup.h exists])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Linux 5.18 API
|
||||
dnl #
|
||||
dnl # In 07888c665b405b1cd3577ddebfeb74f4717a84c4 ("block: pass a block_device and opf to bio_alloc")
|
||||
dnl # bio_alloc(gfp_t gfp_mask, unsigned short nr_iovecs)
|
||||
dnl # became
|
||||
dnl # bio_alloc(struct block_device *bdev, unsigned short nr_vecs, unsigned int opf, gfp_t gfp_mask)
|
||||
dnl # however
|
||||
dnl # > NULL/0 can be passed, both for the
|
||||
dnl # > passthrough case on a raw request_queue and to temporarily avoid
|
||||
dnl # > refactoring some nasty code.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_ALLOC_4ARG], [
|
||||
ZFS_LINUX_TEST_SRC([bio_alloc_4arg], [
|
||||
#include <linux/bio.h>
|
||||
],[
|
||||
gfp_t gfp_mask = 0;
|
||||
unsigned short nr_iovecs = 0;
|
||||
struct block_device *bdev = NULL;
|
||||
unsigned int opf = 0;
|
||||
|
||||
struct bio *__attribute__((unused)) allocated = bio_alloc(bdev, nr_iovecs, opf, gfp_mask);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BIO_ALLOC_4ARG], [
|
||||
AC_MSG_CHECKING([whether bio_alloc() wants 4 args])
|
||||
ZFS_LINUX_TEST_RESULT([bio_alloc_4arg],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_BIO_ALLOC_4ARG], 1, [bio_alloc() takes 4 arguments])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [
|
||||
ZFS_AC_KERNEL_SRC_REQ
|
||||
ZFS_AC_KERNEL_SRC_BIO_OPS
|
||||
|
@ -520,10 +407,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [
|
|||
ZFS_AC_KERNEL_SRC_BIO_CURRENT_BIO_LIST
|
||||
ZFS_AC_KERNEL_SRC_BLKG_TRYGET
|
||||
ZFS_AC_KERNEL_SRC_BIO_BDEV_DISK
|
||||
ZFS_AC_KERNEL_SRC_BDEV_SUBMIT_BIO_RETURNS_VOID
|
||||
ZFS_AC_KERNEL_SRC_BIO_SET_DEV_MACRO
|
||||
ZFS_AC_KERNEL_SRC_BLK_CGROUP_HEADER
|
||||
ZFS_AC_KERNEL_SRC_BIO_ALLOC_4ARG
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BIO], [
|
||||
|
@ -546,7 +429,4 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO], [
|
|||
ZFS_AC_KERNEL_BIO_CURRENT_BIO_LIST
|
||||
ZFS_AC_KERNEL_BLKG_TRYGET
|
||||
ZFS_AC_KERNEL_BIO_BDEV_DISK
|
||||
ZFS_AC_KERNEL_BDEV_SUBMIT_BIO_RETURNS_VOID
|
||||
ZFS_AC_KERNEL_BLK_CGROUP_HEADER
|
||||
ZFS_AC_KERNEL_BIO_ALLOC_4ARG
|
||||
])
|
||||
|
|
|
@ -23,8 +23,8 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_PLUG], [
|
|||
])
|
||||
|
||||
dnl #
|
||||
dnl # 2.6.32 - 4.11: statically allocated bdi in request_queue
|
||||
dnl # 4.12: dynamically allocated bdi in request_queue
|
||||
dnl # 2.6.32 - 4.11, statically allocated bdi in request_queue
|
||||
dnl # 4.12 - x.y, dynamically allocated bdi in request_queue
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI], [
|
||||
ZFS_LINUX_TEST_SRC([blk_queue_bdi], [
|
||||
|
@ -48,151 +48,69 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_BDI], [
|
|||
])
|
||||
|
||||
dnl #
|
||||
dnl # 5.9: added blk_queue_update_readahead(),
|
||||
dnl # 5.15: renamed to disk_update_readahead()
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_UPDATE_READAHEAD], [
|
||||
ZFS_LINUX_TEST_SRC([blk_queue_update_readahead], [
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct request_queue q;
|
||||
blk_queue_update_readahead(&q);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([disk_update_readahead], [
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct gendisk disk;
|
||||
disk_update_readahead(&disk);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_UPDATE_READAHEAD], [
|
||||
AC_MSG_CHECKING([whether blk_queue_update_readahead() exists])
|
||||
ZFS_LINUX_TEST_RESULT([blk_queue_update_readahead], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLK_QUEUE_UPDATE_READAHEAD, 1,
|
||||
[blk_queue_update_readahead() exists])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
|
||||
AC_MSG_CHECKING([whether disk_update_readahead() exists])
|
||||
ZFS_LINUX_TEST_RESULT([disk_update_readahead], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_DISK_UPDATE_READAHEAD, 1,
|
||||
[disk_update_readahead() exists])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 5.19: bdev_max_discard_sectors() available
|
||||
dnl # 2.6.32: blk_queue_discard() available
|
||||
dnl # 2.6.32 - 4.x API,
|
||||
dnl # blk_queue_discard()
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD], [
|
||||
ZFS_LINUX_TEST_SRC([bdev_max_discard_sectors], [
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct block_device *bdev __attribute__ ((unused)) = NULL;
|
||||
unsigned int error __attribute__ ((unused));
|
||||
|
||||
error = bdev_max_discard_sectors(bdev);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([blk_queue_discard], [
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct request_queue r;
|
||||
struct request_queue *q = &r;
|
||||
struct request_queue *q __attribute__ ((unused)) = NULL;
|
||||
int value __attribute__ ((unused));
|
||||
memset(q, 0, sizeof(r));
|
||||
value = blk_queue_discard(q);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_DISCARD], [
|
||||
AC_MSG_CHECKING([whether bdev_max_discard_sectors() is available])
|
||||
ZFS_LINUX_TEST_RESULT([bdev_max_discard_sectors], [
|
||||
AC_MSG_CHECKING([whether blk_queue_discard() is available])
|
||||
ZFS_LINUX_TEST_RESULT([blk_queue_discard], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BDEV_MAX_DISCARD_SECTORS, 1,
|
||||
[bdev_max_discard_sectors() is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
|
||||
AC_MSG_CHECKING([whether blk_queue_discard() is available])
|
||||
ZFS_LINUX_TEST_RESULT([blk_queue_discard], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLK_QUEUE_DISCARD, 1,
|
||||
[blk_queue_discard() is available])
|
||||
],[
|
||||
ZFS_LINUX_TEST_ERROR([blk_queue_discard])
|
||||
])
|
||||
ZFS_LINUX_TEST_ERROR([blk_queue_discard])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 5.19: bdev_max_secure_erase_sectors() available
|
||||
dnl # 4.8: blk_queue_secure_erase() available
|
||||
dnl # 2.6.36: blk_queue_secdiscard() available
|
||||
dnl # 4.8 - 4.x API,
|
||||
dnl # blk_queue_secure_erase()
|
||||
dnl #
|
||||
dnl # 2.6.36 - 4.7 API,
|
||||
dnl # blk_queue_secdiscard()
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE], [
|
||||
ZFS_LINUX_TEST_SRC([bdev_max_secure_erase_sectors], [
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct block_device *bdev __attribute__ ((unused)) = NULL;
|
||||
unsigned int error __attribute__ ((unused));
|
||||
|
||||
error = bdev_max_secure_erase_sectors(bdev);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([blk_queue_secure_erase], [
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct request_queue r;
|
||||
struct request_queue *q = &r;
|
||||
struct request_queue *q __attribute__ ((unused)) = NULL;
|
||||
int value __attribute__ ((unused));
|
||||
memset(q, 0, sizeof(r));
|
||||
value = blk_queue_secure_erase(q);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([blk_queue_secdiscard], [
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct request_queue r;
|
||||
struct request_queue *q = &r;
|
||||
struct request_queue *q __attribute__ ((unused)) = NULL;
|
||||
int value __attribute__ ((unused));
|
||||
memset(q, 0, sizeof(r));
|
||||
value = blk_queue_secdiscard(q);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE], [
|
||||
AC_MSG_CHECKING([whether bdev_max_secure_erase_sectors() is available])
|
||||
ZFS_LINUX_TEST_RESULT([bdev_max_secure_erase_sectors], [
|
||||
AC_MSG_CHECKING([whether blk_queue_secure_erase() is available])
|
||||
ZFS_LINUX_TEST_RESULT([blk_queue_secure_erase], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BDEV_MAX_SECURE_ERASE_SECTORS, 1,
|
||||
[bdev_max_secure_erase_sectors() is available])
|
||||
AC_DEFINE(HAVE_BLK_QUEUE_SECURE_ERASE, 1,
|
||||
[blk_queue_secure_erase() is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
|
||||
AC_MSG_CHECKING([whether blk_queue_secure_erase() is available])
|
||||
ZFS_LINUX_TEST_RESULT([blk_queue_secure_erase], [
|
||||
AC_MSG_CHECKING([whether blk_queue_secdiscard() is available])
|
||||
ZFS_LINUX_TEST_RESULT([blk_queue_secdiscard], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLK_QUEUE_SECURE_ERASE, 1,
|
||||
[blk_queue_secure_erase() is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
|
||||
AC_MSG_CHECKING([whether blk_queue_secdiscard() is available])
|
||||
ZFS_LINUX_TEST_RESULT([blk_queue_secdiscard], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLK_QUEUE_SECDISCARD, 1,
|
||||
[blk_queue_secdiscard() is available])
|
||||
],[
|
||||
ZFS_LINUX_TEST_ERROR([blk_queue_secure_erase])
|
||||
])
|
||||
[blk_queue_secdiscard() is available])
|
||||
],[
|
||||
ZFS_LINUX_TEST_ERROR([blk_queue_secure_erase])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
@ -259,17 +177,17 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLUSH], [
|
|||
ZFS_LINUX_TEST_SRC([blk_queue_flush], [
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct request_queue *q __attribute__ ((unused)) = NULL;
|
||||
struct request_queue *q = NULL;
|
||||
(void) blk_queue_flush(q, REQ_FLUSH);
|
||||
], [], [ZFS_META_LICENSE])
|
||||
], [$NO_UNUSED_BUT_SET_VARIABLE], [ZFS_META_LICENSE])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([blk_queue_write_cache], [
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct request_queue *q __attribute__ ((unused)) = NULL;
|
||||
struct request_queue *q = NULL;
|
||||
blk_queue_write_cache(q, true, true);
|
||||
], [], [ZFS_META_LICENSE])
|
||||
], [$NO_UNUSED_BUT_SET_VARIABLE], [ZFS_META_LICENSE])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLUSH], [
|
||||
|
@ -322,9 +240,9 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_HW_SECTORS], [
|
|||
ZFS_LINUX_TEST_SRC([blk_queue_max_hw_sectors], [
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct request_queue *q __attribute__ ((unused)) = NULL;
|
||||
struct request_queue *q = NULL;
|
||||
(void) blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
|
||||
], [])
|
||||
], [$NO_UNUSED_BUT_SET_VARIABLE])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS], [
|
||||
|
@ -345,9 +263,9 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_SEGMENTS], [
|
|||
ZFS_LINUX_TEST_SRC([blk_queue_max_segments], [
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct request_queue *q __attribute__ ((unused)) = NULL;
|
||||
struct request_queue *q = NULL;
|
||||
(void) blk_queue_max_segments(q, BLK_MAX_SEGMENTS);
|
||||
], [])
|
||||
], [$NO_UNUSED_BUT_SET_VARIABLE])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS], [
|
||||
|
@ -362,7 +280,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS], [
|
|||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [
|
||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG
|
||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI
|
||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_UPDATE_READAHEAD
|
||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD
|
||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
|
||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_SET
|
||||
|
@ -375,7 +292,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [
|
|||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE], [
|
||||
ZFS_AC_KERNEL_BLK_QUEUE_PLUG
|
||||
ZFS_AC_KERNEL_BLK_QUEUE_BDI
|
||||
ZFS_AC_KERNEL_BLK_QUEUE_UPDATE_READAHEAD
|
||||
ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
|
||||
ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
|
||||
ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET
|
||||
|
|
|
@ -16,90 +16,12 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH], [
|
|||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 6.5.x API change,
|
||||
dnl # blkdev_get_by_path() takes 4 args
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG], [
|
||||
ZFS_LINUX_TEST_SRC([blkdev_get_by_path_4arg], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct block_device *bdev __attribute__ ((unused)) = NULL;
|
||||
const char *path = "path";
|
||||
fmode_t mode = 0;
|
||||
void *holder = NULL;
|
||||
struct blk_holder_ops h;
|
||||
|
||||
bdev = blkdev_get_by_path(path, mode, holder, &h);
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 6.8.x API change
|
||||
dnl # bdev_open_by_path() replaces blkdev_get_by_path()
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_OPEN_BY_PATH], [
|
||||
ZFS_LINUX_TEST_SRC([bdev_open_by_path], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct bdev_handle *bdh __attribute__ ((unused)) = NULL;
|
||||
const char *path = "path";
|
||||
fmode_t mode = 0;
|
||||
void *holder = NULL;
|
||||
struct blk_holder_ops h;
|
||||
|
||||
bdh = bdev_open_by_path(path, mode, holder, &h);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [
|
||||
AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 3 args])
|
||||
AC_MSG_CHECKING([whether blkdev_get_by_path() exists])
|
||||
ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [
|
||||
AC_MSG_RESULT(yes)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 4 args])
|
||||
ZFS_LINUX_TEST_RESULT([blkdev_get_by_path_4arg], [
|
||||
AC_DEFINE(HAVE_BLKDEV_GET_BY_PATH_4ARG, 1,
|
||||
[blkdev_get_by_path() exists and takes 4 args])
|
||||
AC_MSG_RESULT(yes)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether bdev_open_by_path() exists])
|
||||
ZFS_LINUX_TEST_RESULT([bdev_open_by_path], [
|
||||
AC_DEFINE(HAVE_BDEV_OPEN_BY_PATH, 1,
|
||||
[bdev_open_by_path() exists])
|
||||
AC_MSG_RESULT(yes)
|
||||
], [
|
||||
ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 6.5.x API change
|
||||
dnl # blk_mode_t was added as a type to supercede some places where fmode_t
|
||||
dnl # is used
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BLK_MODE_T], [
|
||||
ZFS_LINUX_TEST_SRC([blk_mode_t], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
blk_mode_t m __attribute((unused)) = (blk_mode_t)0;
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BLK_MODE_T], [
|
||||
AC_MSG_CHECKING([whether blk_mode_t is defined])
|
||||
ZFS_LINUX_TEST_RESULT([blk_mode_t], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLK_MODE_T, 1, [blk_mode_t is defined])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()])
|
||||
])
|
||||
])
|
||||
|
||||
|
@ -119,58 +41,12 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT], [
|
|||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 6.5.x API change.
|
||||
dnl # blkdev_put() takes (void* holder) as arg 2
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER], [
|
||||
ZFS_LINUX_TEST_SRC([blkdev_put_holder], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct block_device *bdev = NULL;
|
||||
void *holder = NULL;
|
||||
|
||||
blkdev_put(bdev, holder);
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 6.8.x API change
|
||||
dnl # bdev_release() replaces blkdev_put()
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_RELEASE], [
|
||||
ZFS_LINUX_TEST_SRC([bdev_release], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct bdev_handle *bdh = NULL;
|
||||
bdev_release(bdh);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [
|
||||
AC_MSG_CHECKING([whether blkdev_put() exists])
|
||||
ZFS_LINUX_TEST_RESULT([blkdev_put], [
|
||||
AC_MSG_RESULT(yes)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether blkdev_put() accepts void* as arg 2])
|
||||
ZFS_LINUX_TEST_RESULT([blkdev_put_holder], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLKDEV_PUT_HOLDER, 1,
|
||||
[blkdev_put() accepts void* as arg 2])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether bdev_release() exists])
|
||||
ZFS_LINUX_TEST_RESULT([bdev_release], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BDEV_RELEASE, 1,
|
||||
[bdev_release() exists])
|
||||
], [
|
||||
ZFS_LINUX_TEST_ERROR([blkdev_put()])
|
||||
])
|
||||
])
|
||||
ZFS_LINUX_TEST_ERROR([blkdev_put()])
|
||||
])
|
||||
])
|
||||
|
||||
|
@ -227,84 +103,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_CHECK_DISK_CHANGE], [
|
|||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 6.5.x API change
|
||||
dnl # disk_check_media_change() was added
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_DISK_CHECK_MEDIA_CHANGE], [
|
||||
ZFS_LINUX_TEST_SRC([disk_check_media_change], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct block_device *bdev = NULL;
|
||||
bool error;
|
||||
|
||||
error = disk_check_media_change(bdev->bd_disk);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_DISK_CHECK_MEDIA_CHANGE], [
|
||||
AC_MSG_CHECKING([whether disk_check_media_change() exists])
|
||||
ZFS_LINUX_TEST_RESULT([disk_check_media_change], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_DISK_CHECK_MEDIA_CHANGE, 1,
|
||||
[disk_check_media_change() exists])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # bdev_kobj() is introduced from 5.12
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_KOBJ], [
|
||||
ZFS_LINUX_TEST_SRC([bdev_kobj], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/kobject.h>
|
||||
], [
|
||||
struct block_device *bdev = NULL;
|
||||
struct kobject *disk_kobj;
|
||||
disk_kobj = bdev_kobj(bdev);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEV_KOBJ], [
|
||||
AC_MSG_CHECKING([whether bdev_kobj() exists])
|
||||
ZFS_LINUX_TEST_RESULT([bdev_kobj], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BDEV_KOBJ, 1,
|
||||
[bdev_kobj() exists])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # part_to_dev() was removed in 5.12
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PART_TO_DEV], [
|
||||
ZFS_LINUX_TEST_SRC([part_to_dev], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct hd_struct *p = NULL;
|
||||
struct device *pdev;
|
||||
pdev = part_to_dev(p);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PART_TO_DEV], [
|
||||
AC_MSG_CHECKING([whether part_to_dev() exists])
|
||||
ZFS_LINUX_TEST_RESULT([part_to_dev], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_PART_TO_DEV, 1,
|
||||
[part_to_dev() exists])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 5.10 API, check_disk_change() is removed, in favor of
|
||||
dnl # bdev_check_media_change(), which doesn't force revalidation
|
||||
|
@ -322,7 +120,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_CHECK_MEDIA_CHANGE], [
|
|||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEV_CHECK_MEDIA_CHANGE], [
|
||||
AC_MSG_CHECKING([whether bdev_check_media_change() exists])
|
||||
AC_MSG_CHECKING([whether bdev_disk_changed() exists])
|
||||
ZFS_LINUX_TEST_RESULT([bdev_check_media_change], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BDEV_CHECK_MEDIA_CHANGE, 1,
|
||||
|
@ -496,134 +294,9 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE], [
|
|||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 5.20 API change,
|
||||
dnl # Removed bdevname(), snprintf(.., %pg) should be used.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEVNAME], [
|
||||
ZFS_LINUX_TEST_SRC([bdevname], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct block_device *bdev __attribute__ ((unused)) = NULL;
|
||||
char path[BDEVNAME_SIZE];
|
||||
|
||||
(void) bdevname(bdev, path);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEVNAME], [
|
||||
AC_MSG_CHECKING([whether bdevname() exists])
|
||||
ZFS_LINUX_TEST_RESULT([bdevname], [
|
||||
AC_DEFINE(HAVE_BDEVNAME, 1, [bdevname() is available])
|
||||
AC_MSG_RESULT(yes)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 5.19 API: blkdev_issue_secure_erase()
|
||||
dnl # 3.10 API: blkdev_issue_discard(..., BLKDEV_DISCARD_SECURE)
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_SECURE_ERASE], [
|
||||
ZFS_LINUX_TEST_SRC([blkdev_issue_secure_erase], [
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct block_device *bdev = NULL;
|
||||
sector_t sector = 0;
|
||||
sector_t nr_sects = 0;
|
||||
int error __attribute__ ((unused));
|
||||
|
||||
error = blkdev_issue_secure_erase(bdev,
|
||||
sector, nr_sects, GFP_KERNEL);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([blkdev_issue_discard_flags], [
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct block_device *bdev = NULL;
|
||||
sector_t sector = 0;
|
||||
sector_t nr_sects = 0;
|
||||
unsigned long flags = 0;
|
||||
int error __attribute__ ((unused));
|
||||
|
||||
error = blkdev_issue_discard(bdev,
|
||||
sector, nr_sects, GFP_KERNEL, flags);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_ISSUE_SECURE_ERASE], [
|
||||
AC_MSG_CHECKING([whether blkdev_issue_secure_erase() is available])
|
||||
ZFS_LINUX_TEST_RESULT([blkdev_issue_secure_erase], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLKDEV_ISSUE_SECURE_ERASE, 1,
|
||||
[blkdev_issue_secure_erase() is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
|
||||
AC_MSG_CHECKING([whether blkdev_issue_discard() is available])
|
||||
ZFS_LINUX_TEST_RESULT([blkdev_issue_discard_flags], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLKDEV_ISSUE_DISCARD, 1,
|
||||
[blkdev_issue_discard() is available])
|
||||
],[
|
||||
ZFS_LINUX_TEST_ERROR([blkdev_issue_discard()])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 5.13 API change
|
||||
dnl # blkdev_get_by_path() no longer handles ERESTARTSYS
|
||||
dnl #
|
||||
dnl # Unfortunately we're forced to rely solely on the kernel version
|
||||
dnl # number in order to determine the expected behavior. This was an
|
||||
dnl # internal change to blkdev_get_by_dev(), see commit a8ed1a0607.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_ERESTARTSYS], [
|
||||
AC_MSG_CHECKING([whether blkdev_get_by_path() handles ERESTARTSYS])
|
||||
AS_VERSION_COMPARE([$LINUX_VERSION], [5.13.0], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLKDEV_GET_ERESTARTSYS, 1,
|
||||
[blkdev_get_by_path() handles ERESTARTSYS])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 6.5.x API change
|
||||
dnl # BLK_STS_NEXUS replaced with BLK_STS_RESV_CONFLICT
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BLK_STS_RESV_CONFLICT], [
|
||||
ZFS_LINUX_TEST_SRC([blk_sts_resv_conflict], [
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
blk_status_t s __attribute__ ((unused)) = BLK_STS_RESV_CONFLICT;
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT], [
|
||||
AC_MSG_CHECKING([whether BLK_STS_RESV_CONFLICT is defined])
|
||||
ZFS_LINUX_TEST_RESULT([blk_sts_resv_conflict], [
|
||||
AC_DEFINE(HAVE_BLK_STS_RESV_CONFLICT, 1, [BLK_STS_RESV_CONFLICT is defined])
|
||||
AC_MSG_RESULT(yes)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_OPEN_BY_PATH
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_PUT
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_RELEASE
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV
|
||||
|
@ -632,13 +305,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
|
|||
ZFS_AC_KERNEL_SRC_BLKDEV_CHECK_DISK_CHANGE
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_WHOLE
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEVNAME
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_SECURE_ERASE
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_KOBJ
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_PART_TO_DEV
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_DISK_CHECK_MEDIA_CHANGE
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BLK_STS_RESV_CONFLICT
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BLK_MODE_T
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
|
||||
|
@ -652,12 +318,4 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
|
|||
ZFS_AC_KERNEL_BLKDEV_CHECK_DISK_CHANGE
|
||||
ZFS_AC_KERNEL_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
|
||||
ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE
|
||||
ZFS_AC_KERNEL_BLKDEV_BDEVNAME
|
||||
ZFS_AC_KERNEL_BLKDEV_GET_ERESTARTSYS
|
||||
ZFS_AC_KERNEL_BLKDEV_ISSUE_SECURE_ERASE
|
||||
ZFS_AC_KERNEL_BLKDEV_BDEV_KOBJ
|
||||
ZFS_AC_KERNEL_BLKDEV_PART_TO_DEV
|
||||
ZFS_AC_KERNEL_BLKDEV_DISK_CHECK_MEDIA_CHANGE
|
||||
ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT
|
||||
ZFS_AC_KERNEL_BLKDEV_BLK_MODE_T
|
||||
])
|
||||
|
|
|
@ -5,17 +5,14 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
|
|||
ZFS_LINUX_TEST_SRC([block_device_operations_check_events], [
|
||||
#include <linux/blkdev.h>
|
||||
|
||||
static unsigned int blk_check_events(struct gendisk *disk,
|
||||
unsigned int clearing) {
|
||||
(void) disk, (void) clearing;
|
||||
return (0);
|
||||
}
|
||||
unsigned int blk_check_events(struct gendisk *disk,
|
||||
unsigned int clearing) { return (0); }
|
||||
|
||||
static const struct block_device_operations
|
||||
bops __attribute__ ((unused)) = {
|
||||
.check_events = blk_check_events,
|
||||
};
|
||||
], [], [])
|
||||
], [], [$NO_UNUSED_BUT_SET_VARIABLE])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
|
||||
|
@ -34,10 +31,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
|
|||
ZFS_LINUX_TEST_SRC([block_device_operations_release_void], [
|
||||
#include <linux/blkdev.h>
|
||||
|
||||
static void blk_release(struct gendisk *g, fmode_t mode) {
|
||||
(void) g, (void) mode;
|
||||
return;
|
||||
}
|
||||
void blk_release(struct gendisk *g, fmode_t mode) { return; }
|
||||
|
||||
static const struct block_device_operations
|
||||
bops __attribute__ ((unused)) = {
|
||||
|
@ -46,88 +40,24 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
|
|||
.ioctl = NULL,
|
||||
.compat_ioctl = NULL,
|
||||
};
|
||||
], [], [])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 5.9.x API change
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG], [
|
||||
ZFS_LINUX_TEST_SRC([block_device_operations_release_void_1arg], [
|
||||
#include <linux/blkdev.h>
|
||||
|
||||
static void blk_release(struct gendisk *g) {
|
||||
(void) g;
|
||||
return;
|
||||
}
|
||||
|
||||
static const struct block_device_operations
|
||||
bops __attribute__ ((unused)) = {
|
||||
.open = NULL,
|
||||
.release = blk_release,
|
||||
.ioctl = NULL,
|
||||
.compat_ioctl = NULL,
|
||||
};
|
||||
], [], [])
|
||||
], [], [$NO_UNUSED_BUT_SET_VARIABLE])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
|
||||
AC_MSG_CHECKING([whether bops->release() is void and takes 2 args])
|
||||
AC_MSG_CHECKING([whether bops->release() is void])
|
||||
ZFS_LINUX_TEST_RESULT([block_device_operations_release_void], [
|
||||
AC_MSG_RESULT(yes)
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether bops->release() is void and takes 1 arg])
|
||||
ZFS_LINUX_TEST_RESULT([block_device_operations_release_void_1arg], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG], [1],
|
||||
[Define if release() in block_device_operations takes 1 arg])
|
||||
],[
|
||||
ZFS_LINUX_TEST_ERROR([bops->release()])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 5.13 API change
|
||||
dnl # block_device_operations->revalidate_disk() was removed
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [
|
||||
ZFS_LINUX_TEST_SRC([block_device_operations_revalidate_disk], [
|
||||
#include <linux/blkdev.h>
|
||||
|
||||
static int blk_revalidate_disk(struct gendisk *disk) {
|
||||
(void) disk;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static const struct block_device_operations
|
||||
bops __attribute__ ((unused)) = {
|
||||
.revalidate_disk = blk_revalidate_disk,
|
||||
};
|
||||
], [], [])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [
|
||||
AC_MSG_CHECKING([whether bops->revalidate_disk() exists])
|
||||
ZFS_LINUX_TEST_RESULT([block_device_operations_revalidate_disk], [
|
||||
AC_DEFINE([HAVE_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [1],
|
||||
[Define if revalidate_disk() in block_device_operations])
|
||||
AC_MSG_RESULT(yes)
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
ZFS_LINUX_TEST_ERROR([bops->release()])
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [
|
||||
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
|
||||
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
|
||||
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG
|
||||
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS], [
|
||||
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
|
||||
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
|
||||
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK
|
||||
])
|
||||
|
|
|
@ -7,7 +7,7 @@ dnl #
|
|||
AC_DEFUN([ZFS_AC_KERNEL_SRC_COMMIT_METADATA], [
|
||||
ZFS_LINUX_TEST_SRC([export_operations_commit_metadata], [
|
||||
#include <linux/exportfs.h>
|
||||
static int commit_metadata(struct inode *inode) { return 0; }
|
||||
int commit_metadata(struct inode *inode) { return 0; }
|
||||
static struct export_operations eops __attribute__ ((unused))={
|
||||
.commit_metadata = commit_metadata,
|
||||
};
|
||||
|
|
|
@ -19,47 +19,49 @@ AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEFINED], [
|
|||
])
|
||||
])
|
||||
|
||||
ZFS_AC_KERNEL_SRC_CONFIG_MODULES
|
||||
ZFS_AC_KERNEL_SRC_CONFIG_BLOCK
|
||||
ZFS_AC_KERNEL_SRC_CONFIG_THREAD_SIZE
|
||||
ZFS_AC_KERNEL_SRC_CONFIG_DEBUG_LOCK_ALLOC
|
||||
ZFS_AC_KERNEL_SRC_CONFIG_TRIM_UNUSED_KSYMS
|
||||
ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_DEFLATE
|
||||
ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_INFLATE
|
||||
ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_DEFLATE
|
||||
|
||||
AC_MSG_CHECKING([for kernel config option compatibility])
|
||||
ZFS_LINUX_TEST_COMPILE_ALL([config])
|
||||
AC_MSG_RESULT([done])
|
||||
|
||||
ZFS_AC_KERNEL_CONFIG_MODULES
|
||||
ZFS_AC_KERNEL_CONFIG_BLOCK
|
||||
ZFS_AC_KERNEL_CONFIG_THREAD_SIZE
|
||||
ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC
|
||||
ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS
|
||||
ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE
|
||||
ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE
|
||||
ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Check CONFIG_BLOCK
|
||||
dnl # Check configured THREAD_SIZE
|
||||
dnl #
|
||||
dnl # Verify the kernel has CONFIG_BLOCK support enabled.
|
||||
dnl # The stack size will vary by architecture, but as of Linux 3.15 on x86_64
|
||||
dnl # the default thread stack size was increased to 16K from 8K. Therefore,
|
||||
dnl # on newer kernels and some architectures stack usage optimizations can be
|
||||
dnl # conditionally applied to improve performance without negatively impacting
|
||||
dnl # stability.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_BLOCK], [
|
||||
ZFS_LINUX_TEST_SRC([config_block], [
|
||||
#if !defined(CONFIG_BLOCK)
|
||||
#error CONFIG_BLOCK not defined
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_THREAD_SIZE], [
|
||||
ZFS_LINUX_TEST_SRC([config_thread_size], [
|
||||
#include <linux/module.h>
|
||||
],[
|
||||
#if (THREAD_SIZE < 16384)
|
||||
#error "THREAD_SIZE is less than 16K"
|
||||
#endif
|
||||
],[])
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CONFIG_BLOCK], [
|
||||
AC_MSG_CHECKING([whether CONFIG_BLOCK is defined])
|
||||
ZFS_LINUX_TEST_RESULT([config_block], [
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CONFIG_THREAD_SIZE], [
|
||||
AC_MSG_CHECKING([whether kernel was built with 16K or larger stacks])
|
||||
ZFS_LINUX_TEST_RESULT([config_thread_size], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_LARGE_STACKS, 1, [kernel has large stacks])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([
|
||||
*** This kernel does not include the required block device support.
|
||||
*** Rebuild the kernel with CONFIG_BLOCK=y set.])
|
||||
])
|
||||
])
|
||||
|
||||
|
@ -101,61 +103,6 @@ AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC], [
|
|||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Check CONFIG_MODULES
|
||||
dnl #
|
||||
dnl # Verify the kernel has CONFIG_MODULES support enabled.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_MODULES], [
|
||||
ZFS_LINUX_TEST_SRC([config_modules], [
|
||||
#if !defined(CONFIG_MODULES)
|
||||
#error CONFIG_MODULES not defined
|
||||
#endif
|
||||
],[])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CONFIG_MODULES], [
|
||||
AC_MSG_CHECKING([whether CONFIG_MODULES is defined])
|
||||
AS_IF([test "x$enable_linux_builtin" != xyes], [
|
||||
ZFS_LINUX_TEST_RESULT([config_modules], [
|
||||
AC_MSG_RESULT([yes])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([
|
||||
*** This kernel does not include the required loadable module
|
||||
*** support!
|
||||
***
|
||||
*** To build OpenZFS as a loadable Linux kernel module
|
||||
*** enable loadable module support by setting
|
||||
*** `CONFIG_MODULES=y` in the kernel configuration and run
|
||||
*** `make modules_prepare` in the Linux source tree.
|
||||
***
|
||||
*** If you don't intend to enable loadable kernel module
|
||||
*** support, please compile OpenZFS as a Linux kernel built-in.
|
||||
***
|
||||
*** Prepare the Linux source tree by running `make prepare`,
|
||||
*** use the OpenZFS `--enable-linux-builtin` configure option,
|
||||
*** copy the OpenZFS sources into the Linux source tree using
|
||||
*** `./copy-builtin <linux source directory>`,
|
||||
*** set `CONFIG_ZFS=y` in the kernel configuration and compile
|
||||
*** kernel as usual.
|
||||
])
|
||||
])
|
||||
], [
|
||||
ZFS_LINUX_TRY_COMPILE([], [], [
|
||||
AC_MSG_RESULT([not needed])
|
||||
],[
|
||||
AC_MSG_RESULT([error])
|
||||
AC_MSG_ERROR([
|
||||
*** This kernel is unable to compile object files.
|
||||
***
|
||||
*** Please make sure you prepared the Linux source tree
|
||||
*** by running `make prepare` there.
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Check CONFIG_TRIM_UNUSED_KSYMS
|
||||
dnl #
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
dnl #
|
||||
dnl # On certain architectures `__copy_from_user_inatomic`
|
||||
dnl # is a GPL exported variable and cannot be used by OpenZFS.
|
||||
dnl #
|
||||
|
||||
dnl #
|
||||
dnl # Checking if `__copy_from_user_inatomic` is available.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC___COPY_FROM_USER_INATOMIC], [
|
||||
ZFS_LINUX_TEST_SRC([__copy_from_user_inatomic], [
|
||||
#include <linux/uaccess.h>
|
||||
], [
|
||||
int result __attribute__ ((unused)) = __copy_from_user_inatomic(NULL, NULL, 0);
|
||||
], [], [ZFS_META_LICENSE])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL___COPY_FROM_USER_INATOMIC], [
|
||||
AC_MSG_CHECKING([whether __copy_from_user_inatomic is available])
|
||||
ZFS_LINUX_TEST_RESULT([__copy_from_user_inatomic_license], [
|
||||
AC_MSG_RESULT(yes)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([
|
||||
*** The `__copy_from_user_inatomic()` Linux kernel function is
|
||||
*** incompatible with the CDDL license and will prevent the module
|
||||
*** linking stage from succeeding. OpenZFS cannot be compiled.
|
||||
])
|
||||
])
|
||||
])
|
|
@ -1,29 +0,0 @@
|
|||
dnl #
|
||||
dnl # cpu_has_feature() may referencing GPL-only cpu_feature_keys on powerpc
|
||||
dnl #
|
||||
|
||||
dnl #
|
||||
dnl # Checking if cpu_has_feature is exported GPL-only
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE], [
|
||||
ZFS_LINUX_TEST_SRC([cpu_has_feature], [
|
||||
#include <linux/version.h>
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
|
||||
#include <asm/cpu_has_feature.h>
|
||||
#else
|
||||
#include <asm/cputable.h>
|
||||
#endif
|
||||
], [
|
||||
return cpu_has_feature(CPU_FTR_ALTIVEC) ? 0 : 1;
|
||||
], [], [ZFS_META_LICENSE])
|
||||
])
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CPU_HAS_FEATURE], [
|
||||
AC_MSG_CHECKING([whether cpu_has_feature() is GPL-only])
|
||||
ZFS_LINUX_TEST_RESULT([cpu_has_feature_license], [
|
||||
AC_MSG_RESULT(no)
|
||||
], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_CPU_HAS_FEATURE_GPL_ONLY, 1,
|
||||
[cpu_has_feature() is GPL-only])
|
||||
])
|
||||
])
|
|
@ -2,15 +2,12 @@ dnl #
|
|||
dnl # 4.9, current_time() added
|
||||
dnl # 4.18, return type changed from timespec to timespec64
|
||||
dnl #
|
||||
dnl # Note that we don't care about the return type in this check. If we have
|
||||
dnl # to implement a fallback, we'll know we're <4.9, which was timespec.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_CURRENT_TIME], [
|
||||
ZFS_LINUX_TEST_SRC([current_time], [
|
||||
#include <linux/fs.h>
|
||||
], [
|
||||
struct inode ip __attribute__ ((unused));
|
||||
(void) current_time(&ip);
|
||||
ip.i_atime = current_time(&ip);
|
||||
])
|
||||
])
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
dnl #
|
||||
dnl # 3.18 API change
|
||||
dnl # Dentry aliases are in d_u struct dentry member
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_DENTRY_ALIAS_D_U], [
|
||||
ZFS_LINUX_TEST_SRC([dentry_alias_d_u], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/list.h>
|
||||
], [
|
||||
struct inode *inode __attribute__ ((unused)) = NULL;
|
||||
struct dentry *dentry __attribute__ ((unused)) = NULL;
|
||||
hlist_for_each_entry(dentry, &inode->i_dentry,
|
||||
d_u.d_alias) {
|
||||
d_drop(dentry);
|
||||
}
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_DENTRY_ALIAS_D_U], [
|
||||
AC_MSG_CHECKING([whether dentry aliases are in d_u member])
|
||||
ZFS_LINUX_TEST_RESULT([dentry_alias_d_u], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_DENTRY_D_U_ALIASES, 1,
|
||||
[dentry aliases are in d_u member])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
|
@ -98,7 +98,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_D_REVALIDATE_NAMEIDATA], [
|
|||
#include <linux/dcache.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
static int revalidate (struct dentry *dentry,
|
||||
int revalidate (struct dentry *dentry,
|
||||
struct nameidata *nidata) { return 0; }
|
||||
|
||||
static const struct dentry_operations
|
||||
|
|
|
@ -8,7 +8,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_DIRTY_INODE], [
|
|||
ZFS_LINUX_TEST_SRC([dirty_inode_with_flags], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static void dirty_inode(struct inode *a, int b) { return; }
|
||||
void dirty_inode(struct inode *a, int b) { return; }
|
||||
|
||||
static const struct super_operations
|
||||
sops __attribute__ ((unused)) = {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue