Compare commits
No commits in common. "zfs-2.1-release" and "zfs-2.1.0-rc8" have entirely different histories.
zfs-2.1-re
...
zfs-2.1.0-
|
@ -2,7 +2,7 @@
|
||||||
name: Bug report
|
name: Bug report
|
||||||
about: Create a report to help us improve OpenZFS
|
about: Create a report to help us improve OpenZFS
|
||||||
title: ''
|
title: ''
|
||||||
labels: 'Type: Defect'
|
labels: 'Type: Defect, Status: Triage Needed'
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -25,16 +25,14 @@ Type | Version/Name
|
||||||
--- | ---
|
--- | ---
|
||||||
Distribution Name |
|
Distribution Name |
|
||||||
Distribution Version |
|
Distribution Version |
|
||||||
Kernel Version |
|
Linux Kernel |
|
||||||
Architecture |
|
Architecture |
|
||||||
OpenZFS Version |
|
ZFS Version |
|
||||||
|
SPL Version |
|
||||||
<!--
|
<!--
|
||||||
Command to find OpenZFS version:
|
Commands to find ZFS/SPL versions:
|
||||||
zfs version
|
modinfo zfs | grep -iw version
|
||||||
|
modinfo spl | grep -iw version
|
||||||
Commands to find kernel version:
|
|
||||||
uname -r # Linux
|
|
||||||
freebsd-version -r # FreeBSD
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Describe the problem you're observing
|
### Describe the problem you're observing
|
||||||
|
|
|
@ -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:
|
jobs:
|
||||||
checkstyle:
|
checkstyle:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-18.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
# https://github.com/orgs/community/discussions/47863
|
sudo apt-get update
|
||||||
sudo apt-mark hold grub-efi-amd64-signed
|
sudo apt-get install --yes -qq build-essential autoconf libtool gawk alien fakeroot linux-headers-$(uname -r)
|
||||||
sudo apt-get update --fix-missing
|
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
|
||||||
sudo apt-get upgrade
|
# packages for tests
|
||||||
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
sudo apt-get install --yes -qq parted lsscsi ksh attr acl nfs-kernel-server fio
|
||||||
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/checkstyle-dependencies.txt apt-get install -qq
|
sudo apt-get install --yes -qq mandoc cppcheck pax-utils devscripts abigail-tools
|
||||||
sudo python3 -m pip install --quiet flake8
|
sudo -E pip --quiet install 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
|
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
sh ./autogen.sh
|
sh ./autogen.sh
|
||||||
|
@ -39,19 +32,5 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
make lint
|
make lint
|
||||||
- name: CheckABI
|
- name: CheckABI
|
||||||
id: CheckABI
|
|
||||||
run: |
|
run: |
|
||||||
sudo docker run -v $(pwd):/source ghcr.io/openzfs/libabigail make checkabi
|
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
|
|
||||||
|
|
|
@ -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:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [20.04, 22.04]
|
os: [18.04, 20.04]
|
||||||
runs-on: ubuntu-${{ matrix.os }}
|
runs-on: ubuntu-${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
# https://github.com/orgs/community/discussions/47863
|
sudo apt-get update
|
||||||
sudo apt-mark hold grub-efi-amd64-signed
|
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
|
||||||
sudo apt-get update --fix-missing
|
git alien fakeroot wget curl bc fio acl \
|
||||||
sudo apt-get upgrade
|
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
|
||||||
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
nfs-kernel-server samba rng-tools xz-utils \
|
||||||
sudo apt-get clean
|
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
|
- name: Autogen.sh
|
||||||
run: |
|
run: |
|
||||||
sh autogen.sh
|
sh autogen.sh
|
||||||
|
@ -40,42 +44,27 @@ jobs:
|
||||||
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
||||||
sudo depmod
|
sudo depmod
|
||||||
sudo modprobe zfs
|
sudo modprobe zfs
|
||||||
# Workaround for cloud-init bug
|
# Workaround to provide additional free space for testing.
|
||||||
# see https://github.com/openzfs/zfs/issues/12644
|
# https://github.com/actions/virtual-environments/issues/2840
|
||||||
FILE=/lib/udev/rules.d/10-cloud-init-hook-hotplug.rules
|
sudo rm -rf /usr/share/dotnet
|
||||||
if [ -r "${FILE}" ]; then
|
sudo rm -rf /opt/ghc
|
||||||
HASH=$(md5sum "${FILE}" | awk '{ print $1 }')
|
sudo rm -rf "/usr/local/share/boost"
|
||||||
if [ "${HASH}" = "121ff0ef1936cd2ef65aec0458a35772" ]; then
|
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||||
# 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 /
|
|
||||||
- name: Tests
|
- name: Tests
|
||||||
run: |
|
run: |
|
||||||
/usr/share/zfs/zfs-tests.sh -vR -s 3G
|
/usr/share/zfs/zfs-tests.sh -v -s 3G
|
||||||
timeout-minutes: 330
|
|
||||||
- name: Prepare artifacts
|
- name: Prepare artifacts
|
||||||
if: failure()
|
if: failure()
|
||||||
run: |
|
run: |
|
||||||
RESULTS_PATH=$(readlink -f /var/tmp/test_results/current)
|
RESULTS_PATH=$(readlink -f /var/tmp/test_results/current)
|
||||||
sudo dmesg > $RESULTS_PATH/dmesg
|
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/*
|
sudo chmod +r $RESULTS_PATH/*
|
||||||
# Replace ':' in dir names, actions/upload-artifact doesn't support it
|
# 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
|
for f in $(find $RESULTS_PATH -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v2
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: Test logs Ubuntu-${{ matrix.os }}
|
name: Test logs Ubuntu-${{ matrix.os }}
|
||||||
path: |
|
path: /var/tmp/test_results/20*/
|
||||||
/var/tmp/test_results/*
|
|
||||||
!/var/tmp/test_results/current
|
|
||||||
if-no-files-found: ignore
|
if-no-files-found: ignore
|
||||||
|
|
|
@ -6,19 +6,23 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
# https://github.com/orgs/community/discussions/47863
|
sudo apt-get update
|
||||||
sudo apt-mark hold grub-efi-amd64-signed
|
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
|
||||||
sudo apt-get update --fix-missing
|
git alien fakeroot wget curl bc fio acl \
|
||||||
sudo apt-get upgrade
|
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
|
||||||
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
nfs-kernel-server samba rng-tools xz-utils \
|
||||||
sudo apt-get clean
|
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
|
- name: Autogen.sh
|
||||||
run: |
|
run: |
|
||||||
sh autogen.sh
|
sh autogen.sh
|
||||||
|
@ -36,42 +40,27 @@ jobs:
|
||||||
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
||||||
sudo depmod
|
sudo depmod
|
||||||
sudo modprobe zfs
|
sudo modprobe zfs
|
||||||
# Workaround for cloud-init bug
|
# Workaround to provide additional free space for testing.
|
||||||
# see https://github.com/openzfs/zfs/issues/12644
|
# https://github.com/actions/virtual-environments/issues/2840
|
||||||
FILE=/lib/udev/rules.d/10-cloud-init-hook-hotplug.rules
|
sudo rm -rf /usr/share/dotnet
|
||||||
if [ -r "${FILE}" ]; then
|
sudo rm -rf /opt/ghc
|
||||||
HASH=$(md5sum "${FILE}" | awk '{ print $1 }')
|
sudo rm -rf "/usr/local/share/boost"
|
||||||
if [ "${HASH}" = "121ff0ef1936cd2ef65aec0458a35772" ]; then
|
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||||
# 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 /
|
|
||||||
- name: Tests
|
- name: Tests
|
||||||
run: |
|
run: |
|
||||||
/usr/share/zfs/zfs-tests.sh -vR -s 3G -r sanity
|
/usr/share/zfs/zfs-tests.sh -v -s 3G -r sanity
|
||||||
timeout-minutes: 330
|
|
||||||
- name: Prepare artifacts
|
- name: Prepare artifacts
|
||||||
if: failure()
|
if: failure()
|
||||||
run: |
|
run: |
|
||||||
RESULTS_PATH=$(readlink -f /var/tmp/test_results/current)
|
RESULTS_PATH=$(readlink -f /var/tmp/test_results/current)
|
||||||
sudo dmesg > $RESULTS_PATH/dmesg
|
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/*
|
sudo chmod +r $RESULTS_PATH/*
|
||||||
# Replace ':' in dir names, actions/upload-artifact doesn't support it
|
# 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
|
for f in $(find $RESULTS_PATH -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v2
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: Test logs Ubuntu-${{ matrix.os }}
|
name: Test logs
|
||||||
path: |
|
path: /var/tmp/test_results/20*/
|
||||||
/var/tmp/test_results/*
|
|
||||||
!/var/tmp/test_results/current
|
|
||||||
if-no-files-found: ignore
|
if-no-files-found: ignore
|
||||||
|
|
|
@ -6,21 +6,24 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
TEST_DIR: /var/tmp/zloop
|
TEST_DIR: /var/tmp/zloop
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
# https://github.com/orgs/community/discussions/47863
|
sudo apt-get update
|
||||||
sudo apt-mark hold grub-efi-amd64-signed
|
sudo apt-get install --yes -qq build-essential autoconf libtool gdb \
|
||||||
sudo apt-get update --fix-missing
|
git alien fakeroot \
|
||||||
sudo apt-get upgrade
|
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
|
||||||
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
||||||
sudo apt-get clean
|
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
|
- name: Autogen.sh
|
||||||
run: |
|
run: |
|
||||||
sh autogen.sh
|
sh autogen.sh
|
||||||
|
@ -41,14 +44,13 @@ jobs:
|
||||||
- name: Tests
|
- name: Tests
|
||||||
run: |
|
run: |
|
||||||
sudo mkdir -p $TEST_DIR
|
sudo mkdir -p $TEST_DIR
|
||||||
# run for 10 minutes or at most 2 iterations for a maximum runner
|
# run for 20 minutes to have a total runner time of 30 minutes
|
||||||
# time of 20 minutes.
|
sudo /usr/share/zfs/zloop.sh -t 1200 -l -m1
|
||||||
sudo /usr/share/zfs/zloop.sh -t 600 -I 2 -l -m1 -- -T 120 -P 60
|
|
||||||
- name: Prepare artifacts
|
- name: Prepare artifacts
|
||||||
if: failure()
|
if: failure()
|
||||||
run: |
|
run: |
|
||||||
sudo chmod +r -R $TEST_DIR/
|
sudo chmod +r -R $TEST_DIR/
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v2
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: Logs
|
name: Logs
|
||||||
|
@ -56,7 +58,7 @@ jobs:
|
||||||
/var/tmp/zloop/*/
|
/var/tmp/zloop/*/
|
||||||
!/var/tmp/zloop/*/vdev/
|
!/var/tmp/zloop/*/vdev/
|
||||||
if-no-files-found: ignore
|
if-no-files-found: ignore
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v2
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: Pool files
|
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.
|
applies to spaces associated with the OpenZFS project, including GitHub.
|
||||||
|
|
6
META
6
META
|
@ -1,10 +1,10 @@
|
||||||
Meta: 1
|
Meta: 1
|
||||||
Name: zfs
|
Name: zfs
|
||||||
Branch: 1.0
|
Branch: 1.0
|
||||||
Version: 2.1.15
|
Version: 2.1.0
|
||||||
Release: 1
|
Release: rc8
|
||||||
Release-Tags: relext
|
Release-Tags: relext
|
||||||
License: CDDL
|
License: CDDL
|
||||||
Author: OpenZFS
|
Author: OpenZFS
|
||||||
Linux-Maximum: 6.7
|
Linux-Maximum: 5.13
|
||||||
Linux-Minimum: 3.10
|
Linux-Minimum: 3.10
|
||||||
|
|
29
Makefile.am
29
Makefile.am
|
@ -103,7 +103,7 @@ endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
PHONY += codecheck
|
PHONY += codecheck
|
||||||
codecheck: cstyle shellcheck checkbashisms flake8 mancheck testscheck vcscheck zstdcheck
|
codecheck: cstyle shellcheck checkbashisms flake8 mancheck testscheck vcscheck
|
||||||
|
|
||||||
PHONY += checkstyle
|
PHONY += checkstyle
|
||||||
checkstyle: codecheck commitcheck
|
checkstyle: codecheck commitcheck
|
||||||
|
@ -114,20 +114,14 @@ commitcheck:
|
||||||
${top_srcdir}/scripts/commitcheck.sh; \
|
${top_srcdir}/scripts/commitcheck.sh; \
|
||||||
fi
|
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
|
PHONY += cstyle
|
||||||
cstyle:
|
cstyle:
|
||||||
@find ${top_srcdir} -name build -prune \
|
@find ${top_srcdir} -name build -prune \
|
||||||
-o -type f -name '*.[hc]' \
|
-o -type f -name '*.[hc]' \
|
||||||
! -name 'zfs_config.*' ! -name '*.mod.c' \
|
! -name 'zfs_config.*' ! -name '*.mod.c' \
|
||||||
! -name 'opt_global.h' ! -name '*_if*.h' \
|
! -name 'opt_global.h' ! -name '*_if*.h' \
|
||||||
! -name 'zstd_compat_wrapper.h' \
|
|
||||||
! -path './module/zstd/lib/*' \
|
! -path './module/zstd/lib/*' \
|
||||||
$(cstyle_line)
|
-exec ${top_srcdir}/scripts/cstyle.pl -cpP {} \+
|
||||||
|
|
||||||
filter_executable = -exec test -x '{}' \; -print
|
filter_executable = -exec test -x '{}' \; -print
|
||||||
|
|
||||||
|
@ -135,21 +129,10 @@ SHELLCHECKDIRS = cmd contrib etc scripts tests
|
||||||
SHELLCHECKSCRIPTS = autogen.sh
|
SHELLCHECKSCRIPTS = autogen.sh
|
||||||
|
|
||||||
PHONY += checkabi storeabi
|
PHONY += checkabi storeabi
|
||||||
|
checkabi: lib
|
||||||
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
|
|
||||||
$(MAKE) -C lib checkabi
|
$(MAKE) -C lib checkabi
|
||||||
|
|
||||||
storeabi: checklibabiversion lib
|
storeabi: lib
|
||||||
$(MAKE) -C lib storeabi
|
$(MAKE) -C lib storeabi
|
||||||
|
|
||||||
PHONY += mancheck
|
PHONY += mancheck
|
||||||
|
@ -179,10 +162,6 @@ vcscheck:
|
||||||
awk '{c++; print} END {if(c>0) exit 1}' ; \
|
awk '{c++; print} END {if(c>0) exit 1}' ; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PHONY += zstdcheck
|
|
||||||
zstdcheck:
|
|
||||||
@$(MAKE) -C module/zstd checksymbols
|
|
||||||
|
|
||||||
PHONY += lint
|
PHONY += lint
|
||||||
lint: cppcheck paxcheck
|
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
|
* [Documentation](https://openzfs.github.io/openzfs-docs/) - for using and developing this repo
|
||||||
* [ZoL Site](https://zfsonlinux.org) - Linux release info & links
|
* [ZoL Site](https://zfsonlinux.org) - Linux release info & links
|
||||||
* [Mailing lists](https://openzfs.github.io/openzfs-docs/Project%20and%20Community/Mailing%20Lists.html)
|
* [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
|
# Installation
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
bin_SCRIPTS = arc_summary
|
bin_SCRIPTS = arc_summary
|
||||||
|
|
||||||
CLEANFILES = 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
|
SCRIPT = arc_summary3
|
||||||
|
endif
|
||||||
|
|
||||||
arc_summary: $(SCRIPT)
|
arc_summary: $(SCRIPT)
|
||||||
cp $< $@
|
cp $< $@
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -191,13 +191,21 @@ elif sys.platform.startswith('linux'):
|
||||||
# there, so we fall back on modinfo
|
# there, so we fall back on modinfo
|
||||||
command = ["/sbin/modinfo", request, "-0"]
|
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 = ''
|
info = ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
if 'run' in dir(subprocess):
|
||||||
info = subprocess.run(command, stdout=subprocess.PIPE,
|
info = subprocess.run(command, stdout=subprocess.PIPE,
|
||||||
check=True, universal_newlines=True)
|
universal_newlines=True)
|
||||||
raw_output = info.stdout.split('\0')
|
raw_output = info.stdout.split('\0')
|
||||||
|
else:
|
||||||
|
info = subprocess.check_output(command,
|
||||||
|
universal_newlines=True)
|
||||||
|
raw_output = info.split('\0')
|
||||||
|
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
print("Error: Descriptions not available",
|
print("Error: Descriptions not available",
|
||||||
|
@ -678,9 +686,9 @@ def section_archits(kstats_dict):
|
||||||
print()
|
print()
|
||||||
print('Cache hits by data type:')
|
print('Cache hits by data type:')
|
||||||
dt_todo = (('Demand data:', arc_stats['demand_data_hits']),
|
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']),
|
('Demand metadata:', arc_stats['demand_metadata_hits']),
|
||||||
('Prefetch metadata:',
|
('Demand prefetch metadata:',
|
||||||
arc_stats['prefetch_metadata_hits']))
|
arc_stats['prefetch_metadata_hits']))
|
||||||
|
|
||||||
for title, value in dt_todo:
|
for title, value in dt_todo:
|
||||||
|
@ -689,10 +697,10 @@ def section_archits(kstats_dict):
|
||||||
print()
|
print()
|
||||||
print('Cache misses by data type:')
|
print('Cache misses by data type:')
|
||||||
dm_todo = (('Demand data:', arc_stats['demand_data_misses']),
|
dm_todo = (('Demand data:', arc_stats['demand_data_misses']),
|
||||||
('Prefetch data:',
|
('Demand prefetch data:',
|
||||||
arc_stats['prefetch_data_misses']),
|
arc_stats['prefetch_data_misses']),
|
||||||
('Demand metadata:', arc_stats['demand_metadata_misses']),
|
('Demand metadata:', arc_stats['demand_metadata_misses']),
|
||||||
('Prefetch metadata:',
|
('Demand prefetch metadata:',
|
||||||
arc_stats['prefetch_metadata_misses']))
|
arc_stats['prefetch_metadata_misses']))
|
||||||
|
|
||||||
for title, value in dm_todo:
|
for title, value in dm_todo:
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
# @hdr is the array of fields that needs to be printed, so we
|
# @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.
|
# 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
|
import sys
|
||||||
|
@ -271,7 +271,7 @@ def print_values():
|
||||||
if pretty_print:
|
if pretty_print:
|
||||||
fmt = lambda col: prettynum(cols[col][0], cols[col][1], v[col])
|
fmt = lambda col: prettynum(cols[col][0], cols[col][1], v[col])
|
||||||
else:
|
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(sep.join(fmt(col) for col in hdr))
|
||||||
sys.stdout.write("\n")
|
sys.stdout.write("\n")
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
# Copyright (C) 2013 Lawrence Livermore National Security, LLC.
|
# Copyright (C) 2013 Lawrence Livermore National Security, LLC.
|
||||||
# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
# 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
|
import sys
|
||||||
|
|
|
@ -246,6 +246,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) {
|
if (mntflags & MS_REMOUNT) {
|
||||||
nomtab = 1;
|
nomtab = 1;
|
||||||
remount = 1;
|
remount = 1;
|
||||||
|
@ -268,10 +275,7 @@ main(int argc, char **argv)
|
||||||
return (MOUNT_USAGE);
|
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 */
|
/* treat all snapshots as legacy mount points */
|
||||||
if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT)
|
if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT)
|
||||||
|
@ -289,11 +293,12 @@ main(int argc, char **argv)
|
||||||
if (zfs_version == 0) {
|
if (zfs_version == 0) {
|
||||||
fprintf(stderr, gettext("unable to fetch "
|
fprintf(stderr, gettext("unable to fetch "
|
||||||
"ZFS version for filesystem '%s'\n"), dataset);
|
"ZFS version for filesystem '%s'\n"), dataset);
|
||||||
zfs_close(zhp);
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
return (MOUNT_SYSERR);
|
return (MOUNT_SYSERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zfs_close(zhp);
|
||||||
|
libzfs_fini(g_zfs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Legacy mount points may only be mounted using 'mount', never using
|
* Legacy mount points may only be mounted using 'mount', never using
|
||||||
* 'zfs mount'. However, since 'zfs mount' actually invokes 'mount'
|
* 'zfs mount'. However, since 'zfs mount' actually invokes 'mount'
|
||||||
|
@ -311,8 +316,6 @@ main(int argc, char **argv)
|
||||||
"Use 'zfs set mountpoint=%s' or 'mount -t zfs %s %s'.\n"
|
"Use 'zfs set mountpoint=%s' or 'mount -t zfs %s %s'.\n"
|
||||||
"See zfs(8) for more information.\n"),
|
"See zfs(8) for more information.\n"),
|
||||||
dataset, mntpoint, dataset, mntpoint);
|
dataset, mntpoint, dataset, mntpoint);
|
||||||
zfs_close(zhp);
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
return (MOUNT_USAGE);
|
return (MOUNT_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,37 +326,13 @@ main(int argc, char **argv)
|
||||||
"Use 'zfs set mountpoint=%s' or 'zfs mount %s'.\n"
|
"Use 'zfs set mountpoint=%s' or 'zfs mount %s'.\n"
|
||||||
"See zfs(8) for more information.\n"),
|
"See zfs(8) for more information.\n"),
|
||||||
dataset, "legacy", dataset);
|
dataset, "legacy", dataset);
|
||||||
zfs_close(zhp);
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
return (MOUNT_USAGE);
|
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 (!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,
|
error = mount(dataset, mntpoint, MNTTYPE_ZFS,
|
||||||
mntflags, mntopts);
|
mntflags, mntopts);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
zfs_close(zhp);
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
|
@ -389,7 +368,7 @@ main(int argc, char **argv)
|
||||||
"mount the filesystem again.\n"), dataset);
|
"mount the filesystem again.\n"), dataset);
|
||||||
return (MOUNT_SYSERR);
|
return (MOUNT_SYSERR);
|
||||||
}
|
}
|
||||||
fallthrough;
|
/* fallthru */
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
(void) fprintf(stderr, gettext("filesystem "
|
(void) fprintf(stderr, gettext("filesystem "
|
||||||
|
|
|
@ -140,8 +140,7 @@ Usage: vdev_id [-h]
|
||||||
-p number of phy's per switch port [default=$PHYS_PER_PORT]
|
-p number of phy's per switch port [default=$PHYS_PER_PORT]
|
||||||
-h show this summary
|
-h show this summary
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 0
|
||||||
# exit with error to avoid processing usage message by a udev rule
|
|
||||||
}
|
}
|
||||||
|
|
||||||
map_slot() {
|
map_slot() {
|
||||||
|
@ -375,7 +374,7 @@ sas_handler() {
|
||||||
i=$((i + 1))
|
i=$((i + 1))
|
||||||
done
|
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
|
if [ -z "$PHY" ] ; then
|
||||||
PHY=0
|
PHY=0
|
||||||
fi
|
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
|
# 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")
|
# Get the enclosure ID ("0:0:0:0")
|
||||||
ENC="${DEVPATH%/*}"
|
ENC=$(basename $(readlink -m "/sys/$DEVPATH/../.."))
|
||||||
ENC="${ENC%/*}"
|
|
||||||
ENC="${ENC##*/}"
|
|
||||||
if [ ! -d "/sys/class/enclosure/$ENC" ] ; then
|
if [ ! -d "/sys/class/enclosure/$ENC" ] ; then
|
||||||
# Not an enclosure, bail out
|
# Not an enclosure, bail out
|
||||||
return
|
return
|
||||||
|
@ -618,15 +615,14 @@ enclosure_handler () {
|
||||||
|
|
||||||
# The PCI directory is two directories up from the port directory
|
# The PCI directory is two directories up from the port directory
|
||||||
# /sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0
|
# /sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0
|
||||||
PCI_ID_LONG="$(readlink -m "/sys/$PORT_DIR/../..")"
|
PCI_ID_LONG=$(basename $(readlink -m "/sys/$PORT_DIR/../.."))
|
||||||
PCI_ID_LONG="${PCI_ID_LONG##*/}"
|
|
||||||
|
|
||||||
# Strip down the PCI address from 0000:05:00.0 to 05:00.0
|
# 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 our device according to vdev_id.conf (like "L0" or "U1").
|
||||||
NAME=$(awk "/channel/{if (\$1 == \"channel\" && \$2 == \"$PCI_ID\" && \
|
NAME=$(awk '/channel/{if ($1 == "channel" && $2 == "$PCI_ID" && \
|
||||||
\$3 == \"$PORT_ID\") {print \$4\$3}}" $CONFIG)
|
$3 == "$PORT_ID") {print ${4}int(count[$4])}; count[$4]++}' $CONFIG)
|
||||||
|
|
||||||
echo "${NAME}"
|
echo "${NAME}"
|
||||||
}
|
}
|
||||||
|
@ -677,7 +673,7 @@ alias_handler () {
|
||||||
link=$(echo "$link" | sed 's/p[0-9][0-9]*$//')
|
link=$(echo "$link" | sed 's/p[0-9][0-9]*$//')
|
||||||
fi
|
fi
|
||||||
# Check both the fully qualified and the base name of link.
|
# 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
|
if [ ! -z "$l" ]; then
|
||||||
alias=$(awk -v var="$l" '($1 == "alias") && \
|
alias=$(awk -v var="$l" '($1 == "alias") && \
|
||||||
($3 == var) \
|
($3 == var) \
|
||||||
|
@ -732,7 +728,7 @@ done
|
||||||
|
|
||||||
if [ ! -r "$CONFIG" ] ; then
|
if [ ! -r "$CONFIG" ] ; then
|
||||||
echo "Error: Config file \"$CONFIG\" not found"
|
echo "Error: Config file \"$CONFIG\" not found"
|
||||||
exit 1
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$DEV" ] && [ -z "$ENCLOSURE_MODE" ] ; then
|
if [ -z "$DEV" ] && [ -z "$ENCLOSURE_MODE" ] ; then
|
||||||
|
|
151
cmd/zdb/zdb.c
151
cmd/zdb/zdb.c
|
@ -110,9 +110,8 @@ extern int zfs_recover;
|
||||||
extern unsigned long zfs_arc_meta_min, zfs_arc_meta_limit;
|
extern unsigned long zfs_arc_meta_min, zfs_arc_meta_limit;
|
||||||
extern int zfs_vdev_async_read_max_active;
|
extern int zfs_vdev_async_read_max_active;
|
||||||
extern boolean_t spa_load_verify_dryrun;
|
extern boolean_t spa_load_verify_dryrun;
|
||||||
extern boolean_t spa_mode_readable_spacemaps;
|
|
||||||
extern int zfs_reconstruct_indirect_combinations_max;
|
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";
|
static const char cmdname[] = "zdb";
|
||||||
uint8_t dump_opt[256];
|
uint8_t dump_opt[256];
|
||||||
|
@ -2219,8 +2218,7 @@ snprintf_zstd_header(spa_t *spa, char *blkbuf, size_t buflen,
|
||||||
(void) snprintf(blkbuf + strlen(blkbuf),
|
(void) snprintf(blkbuf + strlen(blkbuf),
|
||||||
buflen - strlen(blkbuf),
|
buflen - strlen(blkbuf),
|
||||||
" ZSTD:size=%u:version=%u:level=%u:EMBEDDED",
|
" ZSTD:size=%u:version=%u:level=%u:EMBEDDED",
|
||||||
zstd_hdr.c_len, zfs_get_hdrversion(&zstd_hdr),
|
zstd_hdr.c_len, zstd_hdr.version, zstd_hdr.level);
|
||||||
zfs_get_hdrlevel(&zstd_hdr));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2244,8 +2242,7 @@ snprintf_zstd_header(spa_t *spa, char *blkbuf, size_t buflen,
|
||||||
(void) snprintf(blkbuf + strlen(blkbuf),
|
(void) snprintf(blkbuf + strlen(blkbuf),
|
||||||
buflen - strlen(blkbuf),
|
buflen - strlen(blkbuf),
|
||||||
" ZSTD:size=%u:version=%u:level=%u:NORMAL",
|
" ZSTD:size=%u:version=%u:level=%u:NORMAL",
|
||||||
zstd_hdr.c_len, zfs_get_hdrversion(&zstd_hdr),
|
zstd_hdr.c_len, zstd_hdr.version, zstd_hdr.level);
|
||||||
zfs_get_hdrlevel(&zstd_hdr));
|
|
||||||
|
|
||||||
abd_return_buf_copy(pabd, buf, BP_GET_LSIZE(bp));
|
abd_return_buf_copy(pabd, buf, BP_GET_LSIZE(bp));
|
||||||
}
|
}
|
||||||
|
@ -2995,7 +2992,7 @@ open_objset(const char *path, void *tag, objset_t **osp)
|
||||||
}
|
}
|
||||||
sa_os = *osp;
|
sa_os = *osp;
|
||||||
|
|
||||||
return (err);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -3102,22 +3099,13 @@ dump_znode_sa_xattr(sa_handle_t *hdl)
|
||||||
(void) printf("\tSA xattrs: %d bytes, %d entries\n\n",
|
(void) printf("\tSA xattrs: %d bytes, %d entries\n\n",
|
||||||
sa_xattr_size, sa_xattr_entries);
|
sa_xattr_size, sa_xattr_entries);
|
||||||
while ((elem = nvlist_next_nvpair(sa_xattr, elem)) != NULL) {
|
while ((elem = nvlist_next_nvpair(sa_xattr, elem)) != NULL) {
|
||||||
boolean_t can_print = !dump_opt['P'];
|
|
||||||
uchar_t *value;
|
uchar_t *value;
|
||||||
uint_t cnt, idx;
|
uint_t cnt, idx;
|
||||||
|
|
||||||
(void) printf("\t\t%s = ", nvpair_name(elem));
|
(void) printf("\t\t%s = ", nvpair_name(elem));
|
||||||
nvpair_value_byte_array(elem, &value, &cnt);
|
nvpair_value_byte_array(elem, &value, &cnt);
|
||||||
|
|
||||||
for (idx = 0; idx < cnt; ++idx) {
|
for (idx = 0; idx < cnt; ++idx) {
|
||||||
if (!isprint(value[idx])) {
|
if (isprint(value[idx]))
|
||||||
can_print = B_FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (idx = 0; idx < cnt; ++idx) {
|
|
||||||
if (can_print)
|
|
||||||
(void) putchar(value[idx]);
|
(void) putchar(value[idx]);
|
||||||
else
|
else
|
||||||
(void) printf("\\%3.3o", value[idx]);
|
(void) printf("\\%3.3o", value[idx]);
|
||||||
|
@ -3134,18 +3122,13 @@ dump_znode_symlink(sa_handle_t *hdl)
|
||||||
{
|
{
|
||||||
int sa_symlink_size = 0;
|
int sa_symlink_size = 0;
|
||||||
char linktarget[MAXPATHLEN];
|
char linktarget[MAXPATHLEN];
|
||||||
|
linktarget[0] = '\0';
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = sa_size(hdl, sa_attr_table[ZPL_SYMLINK], &sa_symlink_size);
|
error = sa_size(hdl, sa_attr_table[ZPL_SYMLINK], &sa_symlink_size);
|
||||||
if (error || sa_symlink_size == 0) {
|
if (error || sa_symlink_size == 0) {
|
||||||
return;
|
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],
|
if (sa_lookup(hdl, sa_attr_table[ZPL_SYMLINK],
|
||||||
&linktarget, sa_symlink_size) == 0)
|
&linktarget, sa_symlink_size) == 0)
|
||||||
(void) printf("\ttarget %s\n", linktarget);
|
(void) printf("\ttarget %s\n", linktarget);
|
||||||
|
@ -4111,7 +4094,7 @@ cksum_record_compare(const void *x1, const void *x2)
|
||||||
const cksum_record_t *l = (cksum_record_t *)x1;
|
const cksum_record_t *l = (cksum_record_t *)x1;
|
||||||
const cksum_record_t *r = (cksum_record_t *)x2;
|
const cksum_record_t *r = (cksum_record_t *)x2;
|
||||||
int arraysize = ARRAY_SIZE(l->cksum.zc_word);
|
int arraysize = ARRAY_SIZE(l->cksum.zc_word);
|
||||||
int difference = 0;
|
int difference;
|
||||||
|
|
||||||
for (int i = 0; i < arraysize; i++) {
|
for (int i = 0; i < arraysize; i++) {
|
||||||
difference = TREE_CMP(l->cksum.zc_word[i], r->cksum.zc_word[i]);
|
difference = TREE_CMP(l->cksum.zc_word[i], r->cksum.zc_word[i]);
|
||||||
|
@ -4588,7 +4571,7 @@ dump_path_impl(objset_t *os, uint64_t obj, char *name, uint64_t *retobj)
|
||||||
case DMU_OT_DIRECTORY_CONTENTS:
|
case DMU_OT_DIRECTORY_CONTENTS:
|
||||||
if (s != NULL && *(s + 1) != '\0')
|
if (s != NULL && *(s + 1) != '\0')
|
||||||
return (dump_path_impl(os, child_obj, s + 1, retobj));
|
return (dump_path_impl(os, child_obj, s + 1, retobj));
|
||||||
fallthrough;
|
/*FALLTHROUGH*/
|
||||||
case DMU_OT_PLAIN_FILE_CONTENTS:
|
case DMU_OT_PLAIN_FILE_CONTENTS:
|
||||||
if (retobj != NULL) {
|
if (retobj != NULL) {
|
||||||
*retobj = child_obj;
|
*retobj = child_obj;
|
||||||
|
@ -4815,7 +4798,7 @@ dump_label(const char *dev)
|
||||||
if (nvlist_size(config, &size, NV_ENCODE_XDR) != 0)
|
if (nvlist_size(config, &size, NV_ENCODE_XDR) != 0)
|
||||||
size = buflen;
|
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 (!read_l2arc_header) {
|
||||||
if (nvlist_lookup_uint64(config,
|
if (nvlist_lookup_uint64(config,
|
||||||
ZPOOL_CONFIG_POOL_STATE, &l2cache) == 0 &&
|
ZPOOL_CONFIG_POOL_STATE, &l2cache) == 0 &&
|
||||||
|
@ -8281,23 +8264,6 @@ zdb_embedded_block(char *thing)
|
||||||
free(buf);
|
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
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -8343,7 +8309,7 @@ main(int argc, char **argv)
|
||||||
zfs_btree_verify_intensity = 3;
|
zfs_btree_verify_intensity = 3;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv,
|
while ((c = getopt(argc, argv,
|
||||||
"AbcCdDeEFGhiI:klLmMNo:Op:PqrRsSt:uU:vVx:XYyZ")) != -1) {
|
"AbcCdDeEFGhiI:klLmMo:Op:PqrRsSt:uU:vVx:XYyZ")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'b':
|
case 'b':
|
||||||
case 'c':
|
case 'c':
|
||||||
|
@ -8357,7 +8323,6 @@ main(int argc, char **argv)
|
||||||
case 'l':
|
case 'l':
|
||||||
case 'm':
|
case 'm':
|
||||||
case 'M':
|
case 'M':
|
||||||
case 'N':
|
|
||||||
case 'O':
|
case 'O':
|
||||||
case 'r':
|
case 'r':
|
||||||
case 'R':
|
case 'R':
|
||||||
|
@ -8449,6 +8414,31 @@ main(int argc, char **argv)
|
||||||
(void) fprintf(stderr, "-p option requires use of -e\n");
|
(void) fprintf(stderr, "-p option requires use of -e\n");
|
||||||
usage();
|
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)
|
#if defined(_LP64)
|
||||||
/*
|
/*
|
||||||
|
@ -8477,18 +8467,13 @@ main(int argc, char **argv)
|
||||||
*/
|
*/
|
||||||
spa_load_verify_dryrun = B_TRUE;
|
spa_load_verify_dryrun = B_TRUE;
|
||||||
|
|
||||||
/*
|
|
||||||
* ZDB should have ability to read spacemaps.
|
|
||||||
*/
|
|
||||||
spa_mode_readable_spacemaps = B_TRUE;
|
|
||||||
|
|
||||||
kernel_init(SPA_MODE_READ);
|
kernel_init(SPA_MODE_READ);
|
||||||
|
|
||||||
if (dump_all)
|
if (dump_all)
|
||||||
verbose = MAX(verbose, 1);
|
verbose = MAX(verbose, 1);
|
||||||
|
|
||||||
for (c = 0; c < 256; c++) {
|
for (c = 0; c < 256; c++) {
|
||||||
if (dump_all && strchr("AeEFklLNOPrRSXy", c) == NULL)
|
if (dump_all && strchr("AeEFklLOPrRSXy", c) == NULL)
|
||||||
dump_opt[c] = 1;
|
dump_opt[c] = 1;
|
||||||
if (dump_opt[c])
|
if (dump_opt[c])
|
||||||
dump_opt[c] += verbose;
|
dump_opt[c] += verbose;
|
||||||
|
@ -8527,7 +8512,6 @@ main(int argc, char **argv)
|
||||||
return (dump_path(argv[0], argv[1], NULL));
|
return (dump_path(argv[0], argv[1], NULL));
|
||||||
}
|
}
|
||||||
if (dump_opt['r']) {
|
if (dump_opt['r']) {
|
||||||
target_is_spa = B_FALSE;
|
|
||||||
if (argc != 3)
|
if (argc != 3)
|
||||||
usage();
|
usage();
|
||||||
dump_opt['v'] = verbose;
|
dump_opt['v'] = verbose;
|
||||||
|
@ -8538,10 +8522,6 @@ main(int argc, char **argv)
|
||||||
rewind = ZPOOL_DO_REWIND |
|
rewind = ZPOOL_DO_REWIND |
|
||||||
(dump_opt['X'] ? ZPOOL_EXTREME_REWIND : 0);
|
(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 ||
|
if (nvlist_alloc(&policy, NV_UNIQUE_NAME_TYPE, 0) != 0 ||
|
||||||
nvlist_add_uint64(policy, ZPOOL_LOAD_REQUEST_TXG, max_txg) != 0 ||
|
nvlist_add_uint64(policy, ZPOOL_LOAD_REQUEST_TXG, max_txg) != 0 ||
|
||||||
nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY, rewind) != 0)
|
nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY, rewind) != 0)
|
||||||
|
@ -8560,34 +8540,6 @@ main(int argc, char **argv)
|
||||||
targetlen = strlen(target);
|
targetlen = strlen(target);
|
||||||
if (targetlen && target[targetlen - 1] == '/')
|
if (targetlen && target[targetlen - 1] == '/')
|
||||||
target[targetlen - 1] = '\0';
|
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 {
|
} else {
|
||||||
target_pool = target;
|
target_pool = target;
|
||||||
}
|
}
|
||||||
|
@ -8705,27 +8657,13 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
return (error);
|
return (error);
|
||||||
} else {
|
} else {
|
||||||
target_pool = strdup(target);
|
|
||||||
if (strpbrk(target, "/@") != NULL)
|
|
||||||
*strpbrk(target_pool, "/@") = '\0';
|
|
||||||
|
|
||||||
zdb_set_skip_mmp(target);
|
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) {
|
if (dataset_lookup == B_TRUE) {
|
||||||
/*
|
/*
|
||||||
* Use the supplied id to get the name
|
* Use the supplied id to get the name
|
||||||
* for open_objset.
|
* for open_objset.
|
||||||
*/
|
*/
|
||||||
error = spa_open(target_pool, &spa, FTAG);
|
error = spa_open(target, &spa, FTAG);
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
error = name_from_objset_id(spa,
|
error = name_from_objset_id(spa,
|
||||||
objset_id, dsname);
|
objset_id, dsname);
|
||||||
|
@ -8734,23 +8672,10 @@ retry_lookup:
|
||||||
target = dsname;
|
target = dsname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error == 0) {
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
error = open_objset(target, FTAG, &os);
|
error = open_objset(target, FTAG, &os);
|
||||||
}
|
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
spa = dmu_objset_spa(os);
|
spa = dmu_objset_spa(os);
|
||||||
free(target_pool);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nvlist_free(policy);
|
nvlist_free(policy);
|
||||||
|
|
|
@ -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_function = _timer_notify;
|
||||||
sev.sigev_notify_attributes = NULL;
|
sev.sigev_notify_attributes = NULL;
|
||||||
sev.sigev_value.sival_ptr = ftp;
|
sev.sigev_value.sival_ptr = ftp;
|
||||||
sev.sigev_signo = 0;
|
|
||||||
|
|
||||||
timer_create(CLOCK_REALTIME, &sev, &ftp->ft_tid);
|
timer_create(CLOCK_REALTIME, &sev, &ftp->ft_tid);
|
||||||
timer_settime(ftp->ft_tid, 0, &its, NULL);
|
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;
|
char *path = NULL;
|
||||||
uint_t c, children;
|
uint_t c, children;
|
||||||
nvlist_t **child;
|
nvlist_t **child;
|
||||||
uint64_t vdev_guid;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First iterate over any children.
|
* 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) {
|
&child, &children) == 0) {
|
||||||
for (c = 0; c < children; c++) {
|
for (c = 0; c < children; c++) {
|
||||||
if (zfs_agent_iter_vdev(zhp, child[c], gsp)) {
|
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);
|
return (B_TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,7 +109,7 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
||||||
&child, &children) == 0) {
|
&child, &children) == 0) {
|
||||||
for (c = 0; c < children; c++) {
|
for (c = 0; c < children; c++) {
|
||||||
if (zfs_agent_iter_vdev(zhp, child[c], gsp)) {
|
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);
|
return (B_TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,21 +126,6 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
||||||
&gsp->gs_vdev_expandtime);
|
&gsp->gs_vdev_expandtime);
|
||||||
return (B_TRUE);
|
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);
|
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 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,
|
(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
||||||
&gsp->gs_pool_guid);
|
&gsp->gs_pool_guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
return (gsp->gs_devid != NULL && gsp->gs_vdev_guid != 0);
|
return (gsp->gs_vdev_guid != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
uint64_t pool_guid = 0, vdev_guid = 0;
|
||||||
guid_search_t search = { 0 };
|
guid_search_t search = { 0 };
|
||||||
device_type_t devtype = DEVICE_TYPE_PRIMARY;
|
device_type_t devtype = DEVICE_TYPE_PRIMARY;
|
||||||
char *devid = NULL;
|
|
||||||
|
|
||||||
class = "resource.fs.zfs.removed";
|
class = "resource.fs.zfs.removed";
|
||||||
subclass = "";
|
subclass = "";
|
||||||
|
|
||||||
(void) nvlist_add_string(payload, FM_CLASS, class);
|
(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_POOL_GUID, &pool_guid);
|
||||||
(void) nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &vdev_guid);
|
(void) nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &vdev_guid);
|
||||||
|
|
||||||
|
@ -227,25 +209,21 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
||||||
(void) nvlist_add_int64_array(payload, FM_EREPORT_TIME, tod, 2);
|
(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
|
* For multipath, spare and l2arc devices ZFS_EV_VDEV_GUID or
|
||||||
* ZFS_EV_POOL_GUID may be missing so find them.
|
* ZFS_EV_POOL_GUID may be missing so find them.
|
||||||
*/
|
*/
|
||||||
if (devid == NULL || pool_guid == 0 || vdev_guid == 0) {
|
if (pool_guid == 0 || vdev_guid == 0) {
|
||||||
if (devid == NULL)
|
if ((nvlist_lookup_string(nvl, DEV_IDENTIFIER,
|
||||||
search.gs_vdev_guid = vdev_guid;
|
&search.gs_devid) == 0) &&
|
||||||
else
|
(zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search)
|
||||||
search.gs_devid = devid;
|
== 1)) {
|
||||||
zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search);
|
|
||||||
if (devid == NULL)
|
|
||||||
devid = search.gs_devid;
|
|
||||||
if (pool_guid == 0)
|
if (pool_guid == 0)
|
||||||
pool_guid = search.gs_pool_guid;
|
pool_guid = search.gs_pool_guid;
|
||||||
if (vdev_guid == 0)
|
if (vdev_guid == 0)
|
||||||
vdev_guid = search.gs_vdev_guid;
|
vdev_guid = search.gs_vdev_guid;
|
||||||
devtype = search.gs_vdev_type;
|
devtype = search.gs_vdev_type;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to avoid reporting "remove" events coming from
|
* We want to avoid reporting "remove" events coming from
|
||||||
|
@ -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) {
|
search.gs_vdev_expandtime + 10 > tv.tv_sec) {
|
||||||
zed_log_msg(LOG_INFO, "agent post event: ignoring '%s' "
|
zed_log_msg(LOG_INFO, "agent post event: ignoring '%s' "
|
||||||
"for recently expanded device '%s'", EC_DEV_REMOVE,
|
"for recently expanded device '%s'", EC_DEV_REMOVE,
|
||||||
devid);
|
search.gs_devid);
|
||||||
fnvlist_free(payload);
|
|
||||||
free(event);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include <sys/fs/zfs.h>
|
#include <sys/fs/zfs.h>
|
||||||
#include <sys/fm/protocol.h>
|
#include <sys/fm/protocol.h>
|
||||||
#include <sys/fm/fs/zfs.h>
|
#include <sys/fm/fs/zfs.h>
|
||||||
#include <sys/zio.h>
|
|
||||||
|
|
||||||
#include "zfs_agents.h"
|
#include "zfs_agents.h"
|
||||||
#include "fmd_api.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))) {
|
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_PROBE_FAILURE))) {
|
||||||
char *failmode = NULL;
|
char *failmode = NULL;
|
||||||
boolean_t checkremove = B_FALSE;
|
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
|
* 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;
|
checkremove = B_TRUE;
|
||||||
} else if (fmd_nvl_class_match(hdl, nvl,
|
} else if (fmd_nvl_class_match(hdl, nvl,
|
||||||
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_CHECKSUM))) {
|
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') {
|
if (zcp->zc_data.zc_serd_checksum[0] == '\0') {
|
||||||
zfs_serd_name(zcp->zc_data.zc_serd_checksum,
|
zfs_serd_name(zcp->zc_data.zc_serd_checksum,
|
||||||
pool_guid, vdev_guid, "checksum");
|
pool_guid, vdev_guid, "checksum");
|
||||||
|
|
|
@ -141,17 +141,6 @@ zfs_unavail_pool(zpool_handle_t *zhp, void *data)
|
||||||
return (0);
|
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
|
* Two stage replace on Linux
|
||||||
* since we get disk notifications
|
* 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;
|
nvlist_t *nvroot, *newvd;
|
||||||
pendingdev_t *device;
|
pendingdev_t *device;
|
||||||
uint64_t wholedisk = 0ULL;
|
uint64_t wholedisk = 0ULL;
|
||||||
uint64_t offline = 0ULL, faulted = 0ULL;
|
uint64_t offline = 0ULL;
|
||||||
uint64_t guid = 0ULL;
|
uint64_t guid = 0ULL;
|
||||||
uint64_t is_spare = 0;
|
|
||||||
char *physpath = NULL, *new_devid = NULL, *enc_sysfs_path = NULL;
|
char *physpath = NULL, *new_devid = NULL, *enc_sysfs_path = NULL;
|
||||||
char rawpath[PATH_MAX], fullpath[PATH_MAX];
|
char rawpath[PATH_MAX], fullpath[PATH_MAX];
|
||||||
char devpath[PATH_MAX];
|
char devpath[PATH_MAX];
|
||||||
int ret;
|
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_sd = B_FALSE;
|
||||||
boolean_t is_mpath_wholedisk = B_FALSE;
|
|
||||||
uint_t c;
|
uint_t c;
|
||||||
vdev_stat_t *vs;
|
vdev_stat_t *vs;
|
||||||
char **lines = NULL;
|
|
||||||
int lines_cnt = 0;
|
|
||||||
|
|
||||||
if (nvlist_lookup_string(vdev, ZPOOL_CONFIG_PATH, &path) != 0)
|
if (nvlist_lookup_string(vdev, ZPOOL_CONFIG_PATH, &path) != 0)
|
||||||
return;
|
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);
|
(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,
|
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
|
||||||
&enc_sysfs_path);
|
&enc_sysfs_path);
|
||||||
|
|
||||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk);
|
(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_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_GUID, &guid);
|
||||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_IS_SPARE, &is_spare);
|
|
||||||
|
|
||||||
/*
|
if (offline)
|
||||||
* Special case:
|
return; /* don't intervene if it was taken offline */
|
||||||
*
|
|
||||||
* 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)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
is_dm = zfs_dev_is_dm(path);
|
||||||
* 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);
|
|
||||||
zed_log_msg(LOG_INFO, "zfs_process_add: pool '%s' vdev '%s', phys '%s'"
|
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', "
|
" wholedisk %d, %s dm (guid %llu)", zpool_get_name(zhp), path,
|
||||||
"(guid %llu)",
|
physpath ? physpath : "NULL", wholedisk, is_dm ? "is" : "not",
|
||||||
zpool_get_name(zhp), path,
|
|
||||||
physpath ? physpath : "NULL",
|
|
||||||
wholedisk ? "is" : "not",
|
|
||||||
is_mpath_wholedisk? "is" : "not",
|
|
||||||
labeled ? "is" : "not",
|
|
||||||
enc_sysfs_path,
|
|
||||||
(long long unsigned int)guid);
|
(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.
|
* 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_HEALTHY ||
|
||||||
newstate == VDEV_STATE_DEGRADED)) {
|
newstate == VDEV_STATE_DEGRADED)) {
|
||||||
zed_log_msg(LOG_INFO,
|
zed_log_msg(LOG_INFO, " zpool_vdev_online: vdev %s is %s",
|
||||||
" zpool_vdev_online: vdev '%s' ('%s') is "
|
fullpath, (newstate == VDEV_STATE_HEALTHY) ?
|
||||||
"%s", fullpath, physpath, (newstate == VDEV_STATE_HEALTHY) ?
|
|
||||||
"HEALTHY" : "DEGRADED");
|
"HEALTHY" : "DEGRADED");
|
||||||
return;
|
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.
|
* vdev online to trigger a FMA fault by posting an ereport.
|
||||||
*/
|
*/
|
||||||
if (!zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOREPLACE, NULL) ||
|
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,
|
(void) zpool_vdev_online(zhp, fullpath, ZFS_ONLINE_FORCEFAULT,
|
||||||
&newstate);
|
&newstate);
|
||||||
zed_log_msg(LOG_INFO, "Pool's autoreplace is not enabled or "
|
zed_log_msg(LOG_INFO, "Pool's autoreplace is not enabled or "
|
||||||
"not a blank disk for '%s' ('%s')", fullpath,
|
"not a whole disk for '%s'", fullpath);
|
||||||
physpath);
|
|
||||||
return;
|
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",
|
(void) snprintf(rawpath, sizeof (rawpath), "%s%s",
|
||||||
is_sd ? DEV_BYVDEV_PATH : DEV_BYPATH_PATH, physpath);
|
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)",
|
zed_log_msg(LOG_INFO, " realpath: %s failed (%s)",
|
||||||
rawpath, strerror(errno));
|
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) &&
|
if ((vs->vs_state != VDEV_STATE_DEGRADED) &&
|
||||||
(vs->vs_state != VDEV_STATE_FAULTED) &&
|
(vs->vs_state != VDEV_STATE_FAULTED) &&
|
||||||
(vs->vs_state != VDEV_STATE_CANT_OPEN)) {
|
(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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nvlist_lookup_string(vdev, "new_devid", &new_devid);
|
nvlist_lookup_string(vdev, "new_devid", &new_devid);
|
||||||
|
|
||||||
if (is_mpath_wholedisk) {
|
if (is_dm) {
|
||||||
/* Don't label device mapper or multipath disks. */
|
/* 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) {
|
} else if (!labeled) {
|
||||||
/*
|
/*
|
||||||
* we're auto-replacing a raw disk, so label it first
|
* 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
|
* If this is a request to label a whole disk, then attempt to
|
||||||
* write out the label.
|
* write out the label.
|
||||||
*/
|
*/
|
||||||
if (zpool_prepare_and_label_disk(g_zfshdl, zhp, leafname,
|
if (zpool_label_disk(g_zfshdl, zhp, leafname) != 0) {
|
||||||
vdev, "autoreplace", &lines, &lines_cnt) != 0) {
|
zed_log_msg(LOG_INFO, " zpool_label_disk: could not "
|
||||||
zed_log_msg(LOG_INFO,
|
|
||||||
" zpool_prepare_and_label_disk: could not "
|
|
||||||
"label '%s' (%s)", leafname,
|
"label '%s' (%s)", leafname,
|
||||||
libzfs_error_description(g_zfshdl));
|
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,
|
(void) zpool_vdev_online(zhp, fullpath,
|
||||||
ZFS_ONLINE_FORCEFAULT, &newstate);
|
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);
|
DEV_BYID_PATH, new_devid);
|
||||||
}
|
}
|
||||||
|
|
||||||
libzfs_free_str_array(lines, lines_cnt);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct the root vdev to pass to zpool_vdev_attach(). While adding
|
* Construct the root vdev to pass to zpool_vdev_attach(). While adding
|
||||||
* the entire vdev structure is harmless, we construct a reduced set of
|
* the entire vdev structure is harmless, we construct a reduced set of
|
||||||
|
@ -573,9 +463,7 @@ typedef struct dev_data {
|
||||||
boolean_t dd_islabeled;
|
boolean_t dd_islabeled;
|
||||||
uint64_t dd_pool_guid;
|
uint64_t dd_pool_guid;
|
||||||
uint64_t dd_vdev_guid;
|
uint64_t dd_vdev_guid;
|
||||||
uint64_t dd_new_vdev_guid;
|
|
||||||
const char *dd_new_devid;
|
const char *dd_new_devid;
|
||||||
uint64_t dd_num_spares;
|
|
||||||
} dev_data_t;
|
} dev_data_t;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -585,8 +473,6 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
uint_t c, children;
|
uint_t c, children;
|
||||||
nvlist_t **child;
|
nvlist_t **child;
|
||||||
uint64_t guid = 0;
|
|
||||||
uint64_t isspare = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First iterate over any children.
|
* 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 */
|
/* 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;
|
return;
|
||||||
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, &guid);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Match by GUID if available otherwise fallback to devid or physical
|
* Match by GUID if available otherwise fallback to devid or physical
|
||||||
*/
|
*/
|
||||||
if (dp->dd_vdev_guid != 0) {
|
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;
|
return;
|
||||||
|
}
|
||||||
zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched on %llu", guid);
|
zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched on %llu", guid);
|
||||||
dp->dd_found = B_TRUE;
|
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
|
* illumos, substring matching is not required to accommodate
|
||||||
* the partition suffix. An exact match will be present in
|
* the partition suffix. An exact match will be present in
|
||||||
* the dp->dd_compare value.
|
* 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 ||
|
if (nvlist_lookup_string(nvl, dp->dd_prop, &path) != 0 ||
|
||||||
strcmp(dp->dd_compare, path) != 0) {
|
strcmp(dp->dd_compare, path) != 0)
|
||||||
return;
|
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",
|
zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched %s on %s",
|
||||||
dp->dd_prop, path);
|
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);
|
(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);
|
ZPOOL_CONFIG_VDEV_TREE, &nvl);
|
||||||
zfs_iter_vdev(zhp, nvl, data);
|
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);
|
zpool_close(zhp);
|
||||||
|
return (dp->dd_found); /* cease iteration after a match */
|
||||||
/* cease iteration after a match */
|
|
||||||
return (dp->dd_found && dp->dd_num_spares == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -735,7 +603,7 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data)
|
||||||
*/
|
*/
|
||||||
static boolean_t
|
static boolean_t
|
||||||
devphys_iter(const char *physical, const char *devid, zfs_process_func_t func,
|
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 };
|
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_found = B_FALSE;
|
||||||
data.dd_islabeled = is_slice;
|
data.dd_islabeled = is_slice;
|
||||||
data.dd_new_devid = devid; /* used by auto replace code */
|
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);
|
(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);
|
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.
|
* 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
|
static int
|
||||||
zfs_deliver_add(nvlist_t *nvl, boolean_t is_lofi)
|
zfs_deliver_add(nvlist_t *nvl, boolean_t is_lofi)
|
||||||
{
|
{
|
||||||
char *devpath = NULL, *devid = NULL;
|
char *devpath = NULL, *devid;
|
||||||
uint64_t pool_guid = 0, vdev_guid = 0;
|
|
||||||
boolean_t is_slice;
|
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) {
|
if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid) != 0)
|
||||||
zed_log_msg(LOG_INFO, "%s: no dev identifier\n", __func__);
|
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
|
||||||
|
|
||||||
(void) nvlist_lookup_string(nvl, DEV_PHYS_PATH, &devpath);
|
(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);
|
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:
|
* Iterate over all vdevs looking for a match in the following order:
|
||||||
* 1. ZPOOL_CONFIG_DEVID (identifies the unique disk)
|
* 1. ZPOOL_CONFIG_DEVID (identifies the unique disk)
|
||||||
* 2. ZPOOL_CONFIG_PHYS_PATH (identifies disk physical location).
|
* 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
|
* For disks, we only want to pay attention to vdevs marked as whole
|
||||||
* by-vdev paths represent physical paths).
|
* disks or are a multipath device.
|
||||||
*/
|
*/
|
||||||
if (devid_iter(devid, zfs_process_add, is_slice))
|
if (!devid_iter(devid, zfs_process_add, is_slice) && devpath != NULL)
|
||||||
return (0);
|
(void) devphys_iter(devpath, devid, zfs_process_add, is_slice);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -960,96 +719,21 @@ zfs_deliver_check(nvlist_t *nvl)
|
||||||
return (0);
|
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
|
static int
|
||||||
zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
||||||
{
|
{
|
||||||
|
char *devname = data;
|
||||||
boolean_t avail_spare, l2cache;
|
boolean_t avail_spare, l2cache;
|
||||||
nvlist_t *udev_nvl = data;
|
|
||||||
nvlist_t *tgt;
|
nvlist_t *tgt;
|
||||||
int error;
|
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'",
|
zed_log_msg(LOG_INFO, "zfsdle_vdev_online: searching for '%s' in '%s'",
|
||||||
devname, zpool_get_name(zhp));
|
devname, zpool_get_name(zhp));
|
||||||
|
|
||||||
if ((tgt = zpool_find_vdev_by_physpath(zhp, devname,
|
if ((tgt = zpool_find_vdev_by_physpath(zhp, devname,
|
||||||
&avail_spare, &l2cache, NULL)) != NULL) {
|
&avail_spare, &l2cache, NULL)) != NULL) {
|
||||||
char *path, fullpath[MAXPATHLEN];
|
char *path, fullpath[MAXPATHLEN];
|
||||||
uint64_t wholedisk = 0;
|
uint64_t wholedisk;
|
||||||
|
|
||||||
error = nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &path);
|
error = nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &path);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -1057,8 +741,10 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
|
error = nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
|
||||||
&wholedisk);
|
&wholedisk);
|
||||||
|
if (error)
|
||||||
|
wholedisk = 0;
|
||||||
|
|
||||||
if (wholedisk) {
|
if (wholedisk) {
|
||||||
path = strrchr(path, '/');
|
path = strrchr(path, '/');
|
||||||
|
@ -1092,77 +778,14 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
||||||
vdev_state_t newstate;
|
vdev_state_t newstate;
|
||||||
|
|
||||||
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) {
|
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) {
|
||||||
/*
|
error = zpool_vdev_online(zhp, fullpath, 0,
|
||||||
* If this disk size has not changed, then
|
&newstate);
|
||||||
* there's no need to do an autoexpand. To
|
zed_log_msg(LOG_INFO, "zfsdle_vdev_online: "
|
||||||
* check we look at the disk's size in its
|
"setting device '%s' to ONLINE state "
|
||||||
* config, and compare it to the disk size
|
"in pool '%s': %d", fullpath,
|
||||||
* 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);
|
zpool_get_name(zhp), error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
@ -1188,11 +811,10 @@ zfs_deliver_dle(nvlist_t *nvl)
|
||||||
strlcpy(name, devname, MAXPATHLEN);
|
strlcpy(name, devname, MAXPATHLEN);
|
||||||
zfs_append_partition(name, MAXPATHLEN);
|
zfs_append_partition(name, MAXPATHLEN);
|
||||||
} else {
|
} else {
|
||||||
sprintf(name, "unknown");
|
|
||||||
zed_log_msg(LOG_INFO, "zfs_deliver_dle: no guid or physpath");
|
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 "
|
zed_log_msg(LOG_INFO, "zfs_deliver_dle: device '%s' not "
|
||||||
"found", name);
|
"found", name);
|
||||||
return (1);
|
return (1);
|
||||||
|
@ -1278,7 +900,7 @@ zfs_enum_pools(void *arg)
|
||||||
* For now, each agent has its own libzfs instance
|
* For now, each agent has its own libzfs instance
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zfs_slm_init(void)
|
zfs_slm_init()
|
||||||
{
|
{
|
||||||
if ((g_zfshdl = libzfs_init()) == NULL)
|
if ((g_zfshdl = libzfs_init()) == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -1304,7 +926,7 @@ zfs_slm_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zfs_slm_fini(void)
|
zfs_slm_fini()
|
||||||
{
|
{
|
||||||
unavailpool_t *pool;
|
unavailpool_t *pool;
|
||||||
pendingdev_t *device;
|
pendingdev_t *device;
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include <sys/fm/fs/zfs.h>
|
#include <sys/fm/fs/zfs.h>
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <libgen.h>
|
|
||||||
|
|
||||||
#include "zfs_agents.h"
|
#include "zfs_agents.h"
|
||||||
#include "fmd_api.h"
|
#include "fmd_api.h"
|
||||||
|
@ -75,8 +74,6 @@ typedef struct find_cbdata {
|
||||||
uint64_t cb_guid;
|
uint64_t cb_guid;
|
||||||
zpool_handle_t *cb_zhp;
|
zpool_handle_t *cb_zhp;
|
||||||
nvlist_t *cb_vdev;
|
nvlist_t *cb_vdev;
|
||||||
uint64_t cb_vdev_guid;
|
|
||||||
uint64_t cb_num_spares;
|
|
||||||
} find_cbdata_t;
|
} find_cbdata_t;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -142,64 +139,6 @@ find_vdev(libzfs_handle_t *zhdl, nvlist_t *nv, uint64_t search_guid)
|
||||||
return (NULL);
|
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.
|
* 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;
|
libzfs_handle_t *zhdl = zdp->zrd_hdl;
|
||||||
boolean_t fault_device, degrade_device;
|
boolean_t fault_device, degrade_device;
|
||||||
boolean_t is_repair;
|
boolean_t is_repair;
|
||||||
boolean_t l2arc = B_FALSE;
|
|
||||||
boolean_t spare = B_FALSE;
|
|
||||||
char *scheme;
|
char *scheme;
|
||||||
nvlist_t *vdev = NULL;
|
nvlist_t *vdev = NULL;
|
||||||
char *uuid;
|
char *uuid;
|
||||||
|
@ -385,8 +322,6 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
||||||
boolean_t is_disk;
|
boolean_t is_disk;
|
||||||
vdev_aux_t aux;
|
vdev_aux_t aux;
|
||||||
uint64_t state = 0;
|
uint64_t state = 0;
|
||||||
vdev_stat_t *vs;
|
|
||||||
unsigned int c;
|
|
||||||
|
|
||||||
fmd_hdl_debug(hdl, "zfs_retire_recv: '%s'", class);
|
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 *devtype;
|
||||||
char *devname;
|
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,
|
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;
|
return;
|
||||||
|
|
||||||
if ((zhp = find_by_guid(zhdl, pool_guid, vdev_guid,
|
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);
|
devname = zpool_vdev_name(NULL, zhp, vdev, B_FALSE);
|
||||||
|
|
||||||
nvlist_lookup_uint64_array(vdev, ZPOOL_CONFIG_VDEV_STATS,
|
/* Can't replace l2arc with a spare: offline the device */
|
||||||
(uint64_t **)&vs, &c);
|
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);
|
||||||
* If state removed is requested for already removed vdev,
|
zpool_vdev_offline(zhp, devname, B_TRUE);
|
||||||
* its a loopback event from spa_async_remove(). Just
|
} else if (!fmd_prop_get_int32(hdl, "spare_on_remove") ||
|
||||||
* ignore it.
|
replace_with_spare(hdl, zhp, vdev) == B_FALSE) {
|
||||||
*/
|
|
||||||
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)) {
|
|
||||||
/* Could not handle with spare */
|
/* Could not handle with spare */
|
||||||
fmd_hdl_debug(hdl, "no spare for '%s'", devname);
|
fmd_hdl_debug(hdl, "no spare for '%s'", devname);
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,7 +291,7 @@ idle:
|
||||||
rv = zed_event_service(&zcp);
|
rv = zed_event_service(&zcp);
|
||||||
|
|
||||||
/* ENODEV: When kernel module is unloaded (osx) */
|
/* ENODEV: When kernel module is unloaded (osx) */
|
||||||
if (rv != 0)
|
if (rv == ENODEV)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ dist_zedexec_SCRIPTS = \
|
||||||
scrub_finish-notify.sh \
|
scrub_finish-notify.sh \
|
||||||
statechange-led.sh \
|
statechange-led.sh \
|
||||||
statechange-notify.sh \
|
statechange-notify.sh \
|
||||||
statechange-slot_off.sh \
|
|
||||||
vdev_clear-led.sh \
|
vdev_clear-led.sh \
|
||||||
vdev_attach-led.sh \
|
vdev_attach-led.sh \
|
||||||
pool_import-led.sh \
|
pool_import-led.sh \
|
||||||
|
@ -40,7 +39,6 @@ zedconfdefaults = \
|
||||||
scrub_finish-notify.sh \
|
scrub_finish-notify.sh \
|
||||||
statechange-led.sh \
|
statechange-led.sh \
|
||||||
statechange-notify.sh \
|
statechange-notify.sh \
|
||||||
statechange-slot_off.sh \
|
|
||||||
vdev_clear-led.sh \
|
vdev_clear-led.sh \
|
||||||
vdev_attach-led.sh \
|
vdev_attach-led.sh \
|
||||||
pool_import-led.sh \
|
pool_import-led.sh \
|
||||||
|
|
|
@ -21,7 +21,7 @@ if [ "${ZED_SYSLOG_DISPLAY_GUIDS}" = "1" ]; then
|
||||||
[ -n "${ZEVENT_VDEV_GUID}" ] && msg="${msg} vdev_guid=${ZEVENT_VDEV_GUID}"
|
[ -n "${ZEVENT_VDEV_GUID}" ] && msg="${msg} vdev_guid=${ZEVENT_VDEV_GUID}"
|
||||||
else
|
else
|
||||||
[ -n "${ZEVENT_POOL}" ] && msg="${msg} pool='${ZEVENT_POOL}'"
|
[ -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
|
fi
|
||||||
|
|
||||||
# log pool state if state is anything other than 'ACTIVE'
|
# log pool state if state is anything other than 'ACTIVE'
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
# Rate-limit the notification based in part on the filename.
|
# 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}"
|
rate_limit_interval="${ZED_NOTIFY_INTERVAL_SECS}"
|
||||||
zed_rate_limit "${rate_limit_tag}" "${rate_limit_interval}" || exit 3
|
zed_rate_limit "${rate_limit_tag}" "${rate_limit_interval}" || exit 3
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,7 @@
|
||||||
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
|
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
|
||||||
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
|
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
|
||||||
|
|
||||||
if [ ! -d /sys/class/enclosure ] && [ ! -d /sys/bus/pci/slots ] ; then
|
if [ ! -d /sys/class/enclosure ] ; then
|
||||||
# No JBOD enclosure or NVMe slots
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -93,29 +92,6 @@ check_and_set_led()
|
||||||
done
|
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_to_val()
|
||||||
{
|
{
|
||||||
state="$1"
|
state="$1"
|
||||||
|
@ -129,38 +105,6 @@ state_to_val()
|
||||||
esac
|
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)
|
# process_pool (pool)
|
||||||
#
|
#
|
||||||
# Iterate through a pool and set the vdevs' enclosure slot LEDs to
|
# Iterate through a pool and set the vdevs' enclosure slot LEDs to
|
||||||
|
@ -190,11 +134,6 @@ process_pool()
|
||||||
# Get dev name (like 'sda')
|
# Get dev name (like 'sda')
|
||||||
dev=$(basename "$(echo "$therest" | awk '{print $(NF-1)}')")
|
dev=$(basename "$(echo "$therest" | awk '{print $(NF-1)}')")
|
||||||
vdev_enc_sysfs_path=$(realpath "/sys/class/block/$dev/device/enclosure_device"*)
|
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}')
|
current_val=$(echo "$therest" | awk '{print $NF}')
|
||||||
|
|
||||||
if [ "$current_val" != "0" ] ; then
|
if [ "$current_val" != "0" ] ; then
|
||||||
|
@ -206,10 +145,9 @@ process_pool()
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
led_path=$(path_to_led "$vdev_enc_sysfs_path")
|
if [ ! -e "$vdev_enc_sysfs_path/fault" ] ; then
|
||||||
if [ ! -e "$led_path" ] ; then
|
|
||||||
rc=3
|
rc=3
|
||||||
zed_log_msg "vdev $vdev '$led_path' doesn't exist"
|
zed_log_msg "vdev $vdev '$file/fault' doesn't exist"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -220,7 +158,7 @@ process_pool()
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! check_and_set_led "$led_path" "$val"; then
|
if ! check_and_set_led "$vdev_enc_sysfs_path/fault" "$val"; then
|
||||||
rc=3
|
rc=3
|
||||||
fi
|
fi
|
||||||
done
|
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
|
# Got a statechange for an individual vdev
|
||||||
val=$(state_to_val "$ZEVENT_VDEV_STATE_STR")
|
val=$(state_to_val "$ZEVENT_VDEV_STATE_STR")
|
||||||
vdev=$(basename "$ZEVENT_VDEV_PATH")
|
vdev=$(basename "$ZEVENT_VDEV_PATH")
|
||||||
ledpath=$(path_to_led "$ZEVENT_VDEV_ENC_SYSFS_PATH")
|
check_and_set_led "$ZEVENT_VDEV_ENC_SYSFS_PATH/fault" "$val"
|
||||||
check_and_set_led "$ledpath" "$val"
|
|
||||||
else
|
else
|
||||||
# Process the entire pool
|
# Process the entire pool
|
||||||
poolname=$(zed_guid_to_pool "$ZEVENT_POOL_GUID")
|
poolname=$(zed_guid_to_pool "$ZEVENT_POOL_GUID")
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
# Send notification in response to a fault induced statechange
|
# Send notification in response to a fault induced statechange
|
||||||
#
|
#
|
||||||
# ZEVENT_SUBCLASS: 'statechange'
|
# ZEVENT_SUBCLASS: 'statechange'
|
||||||
# ZEVENT_VDEV_STATE_STR: 'DEGRADED', 'FAULTED', 'REMOVED', or 'UNAVAIL'
|
# ZEVENT_VDEV_STATE_STR: 'DEGRADED', 'FAULTED' or 'REMOVED'
|
||||||
#
|
#
|
||||||
# Exit codes:
|
# Exit codes:
|
||||||
# 0: notification sent
|
# 0: notification sent
|
||||||
|
@ -31,13 +31,12 @@
|
||||||
|
|
||||||
if [ "${ZEVENT_VDEV_STATE_STR}" != "FAULTED" ] \
|
if [ "${ZEVENT_VDEV_STATE_STR}" != "FAULTED" ] \
|
||||||
&& [ "${ZEVENT_VDEV_STATE_STR}" != "DEGRADED" ] \
|
&& [ "${ZEVENT_VDEV_STATE_STR}" != "DEGRADED" ] \
|
||||||
&& [ "${ZEVENT_VDEV_STATE_STR}" != "REMOVED" ] \
|
&& [ "${ZEVENT_VDEV_STATE_STR}" != "REMOVED" ]; then
|
||||||
&& [ "${ZEVENT_VDEV_STATE_STR}" != "UNAVAIL" ]; then
|
|
||||||
exit 3
|
exit 3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
umask 077
|
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)"
|
note_pathname="$(mktemp)"
|
||||||
{
|
{
|
||||||
if [ "${ZEVENT_VDEV_STATE_STR}" = "FAULTED" ] ; then
|
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_GUID}" ] && echo " vguid: ${ZEVENT_VDEV_GUID}"
|
||||||
[ -n "${ZEVENT_VDEV_DEVID}" ] && echo " devid: ${ZEVENT_VDEV_DEVID}"
|
[ -n "${ZEVENT_VDEV_DEVID}" ] && echo " devid: ${ZEVENT_VDEV_DEVID}"
|
||||||
|
|
||||||
echo " pool: ${ZEVENT_POOL} (${ZEVENT_POOL_GUID})"
|
echo " pool: ${ZEVENT_POOL_GUID}"
|
||||||
|
|
||||||
} > "${note_pathname}"
|
} > "${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()
|
zed_log_err()
|
||||||
{
|
{
|
||||||
logger -p "${ZED_SYSLOG_PRIORITY}" -t "${ZED_SYSLOG_TAG}" -- "error:" \
|
logger -p "${ZED_SYSLOG_PRIORITY}" -t "${ZED_SYSLOG_TAG}" -- "error:" \
|
||||||
"${0##*/}:""${ZEVENT_EID:+" eid=${ZEVENT_EID}:"}" "$@"
|
"$(basename -- "$0"):""${ZEVENT_EID:+" eid=${ZEVENT_EID}:"}" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -202,10 +202,6 @@ zed_notify()
|
||||||
[ "${rv}" -eq 0 ] && num_success=$((num_success + 1))
|
[ "${rv}" -eq 0 ] && num_success=$((num_success + 1))
|
||||||
[ "${rv}" -eq 1 ] && num_failure=$((num_failure + 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_success}" -gt 0 ] && return 0
|
||||||
[ "${num_failure}" -gt 0 ] && return 1
|
[ "${num_failure}" -gt 0 ] && return 1
|
||||||
return 2
|
return 2
|
||||||
|
@ -224,8 +220,6 @@ zed_notify()
|
||||||
# ZED_EMAIL_OPTS. This undergoes the following keyword substitutions:
|
# ZED_EMAIL_OPTS. This undergoes the following keyword substitutions:
|
||||||
# - @ADDRESS@ is replaced with the space-delimited recipient email address(es)
|
# - @ADDRESS@ is replaced with the space-delimited recipient email address(es)
|
||||||
# - @SUBJECT@ is replaced with the notification subject
|
# - @SUBJECT@ is replaced with the notification subject
|
||||||
# If @SUBJECT@ was omited here, a "Subject: ..." header will be added to notification
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
# Arguments
|
# Arguments
|
||||||
# subject: notification subject
|
# subject: notification subject
|
||||||
|
@ -243,7 +237,7 @@ zed_notify()
|
||||||
#
|
#
|
||||||
zed_notify_email()
|
zed_notify_email()
|
||||||
{
|
{
|
||||||
local subject="${1:-"ZED notification"}"
|
local subject="$1"
|
||||||
local pathname="${2:-"/dev/null"}"
|
local pathname="${2:-"/dev/null"}"
|
||||||
|
|
||||||
: "${ZED_EMAIL_PROG:="mail"}"
|
: "${ZED_EMAIL_PROG:="mail"}"
|
||||||
|
@ -260,30 +254,19 @@ zed_notify_email()
|
||||||
[ -n "${subject}" ] || return 1
|
[ -n "${subject}" ] || return 1
|
||||||
if [ ! -r "${pathname}" ]; then
|
if [ ! -r "${pathname}" ]; then
|
||||||
zed_log_err \
|
zed_log_err \
|
||||||
"${ZED_EMAIL_PROG##*/} cannot read \"${pathname}\""
|
"$(basename "${ZED_EMAIL_PROG}") cannot read \"${pathname}\""
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# construct cmdline options
|
ZED_EMAIL_OPTS="$(echo "${ZED_EMAIL_OPTS}" \
|
||||||
ZED_EMAIL_OPTS_PARSED="$(echo "${ZED_EMAIL_OPTS}" \
|
|
||||||
| sed -e "s/@ADDRESS@/${ZED_EMAIL_ADDR}/g" \
|
| sed -e "s/@ADDRESS@/${ZED_EMAIL_ADDR}/g" \
|
||||||
-e "s/@SUBJECT@/${subject}/g")"
|
-e "s/@SUBJECT@/${subject}/g")"
|
||||||
|
|
||||||
# pipe message to email prog
|
# shellcheck disable=SC2086
|
||||||
# shellcheck disable=SC2086,SC2248
|
eval ${ZED_EMAIL_PROG} ${ZED_EMAIL_OPTS} < "${pathname}" >/dev/null 2>&1
|
||||||
{
|
|
||||||
# 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
|
|
||||||
rv=$?
|
rv=$?
|
||||||
if [ "${rv}" -ne 0 ]; then
|
if [ "${rv}" -ne 0 ]; then
|
||||||
zed_log_err "${ZED_EMAIL_PROG##*/} exit=${rv}"
|
zed_log_err "$(basename "${ZED_EMAIL_PROG}") exit=${rv}"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
return 0
|
return 0
|
||||||
|
@ -430,7 +413,7 @@ zed_notify_slack_webhook()
|
||||||
|
|
||||||
# Construct the JSON message for posting.
|
# 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.
|
# Send the POST request and check for errors.
|
||||||
#
|
#
|
||||||
|
@ -450,84 +433,6 @@ zed_notify_slack_webhook()
|
||||||
return 0
|
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])
|
# zed_rate_limit (tag, [interval])
|
||||||
#
|
#
|
||||||
# Check whether an event of a given type [tag] has already occurred within the
|
# 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;
|
# Email address of the zpool administrator for receipt of notifications;
|
||||||
# multiple addresses can be specified if they are delimited by whitespace.
|
# multiple addresses can be specified if they are delimited by whitespace.
|
||||||
# Email will only be sent if ZED_EMAIL_ADDR is defined.
|
# 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;
|
# 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;
|
# The string @SUBJECT@ will be replaced with the notification subject;
|
||||||
# this should be protected with quotes to prevent word-splitting.
|
# this should be protected with quotes to prevent word-splitting.
|
||||||
# Email will only be sent if ZED_EMAIL_ADDR is defined.
|
# 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@"
|
#ZED_EMAIL_OPTS="-s '@SUBJECT@' @ADDRESS@"
|
||||||
|
|
||||||
|
@ -83,23 +82,6 @@ ZED_EMAIL_ADDR="root"
|
||||||
#
|
#
|
||||||
#ZED_SLACK_WEBHOOK_URL=""
|
#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.
|
# 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
|
# 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
|
# device mapper and multipath devices as well. Your enclosure must be
|
||||||
# and NVMe PCI drives (assuming they're supported by Linux in sysfs).
|
# supported by the Linux SES driver for this to work.
|
||||||
#
|
#
|
||||||
ZED_USE_ENCLOSURE_LEDS=1
|
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.
|
# Disabled by default, 1 to enable and 0 to disable.
|
||||||
#ZED_SYSLOG_DISPLAY_GUIDS=1
|
#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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <unistd.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);
|
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_PATH, strval);
|
||||||
if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &strval) == 0)
|
if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &strval) == 0)
|
||||||
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_IDENTIFIER, strval);
|
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)
|
if (nvlist_lookup_string(nvl, DEV_PHYS_PATH, &strval) == 0)
|
||||||
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_PHYS_PATH, strval);
|
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_PHYS_PATH, strval);
|
||||||
if (nvlist_lookup_uint64(nvl, DEV_SIZE, &numval) == 0)
|
if (nvlist_lookup_uint64(nvl, DEV_SIZE, &numval) == 0)
|
||||||
zed_log_msg(LOG_INFO, "\t%s: %llu", DEV_SIZE, numval);
|
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)
|
if (nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &numval) == 0)
|
||||||
zed_log_msg(LOG_INFO, "\t%s: %llu", ZFS_EV_POOL_GUID, numval);
|
zed_log_msg(LOG_INFO, "\t%s: %llu", ZFS_EV_POOL_GUID, numval);
|
||||||
if (nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &numval) == 0)
|
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);
|
numval *= strtoull(value, NULL, 10);
|
||||||
(void) nvlist_add_uint64(nvl, DEV_SIZE, numval);
|
(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) {
|
while (1) {
|
||||||
struct udev_device *dev;
|
struct udev_device *dev;
|
||||||
const char *action, *type, *part, *sectors;
|
const char *action, *type, *part, *sectors;
|
||||||
const char *bus, *uuid, *devpath;
|
const char *bus, *uuid;
|
||||||
const char *class, *subclass;
|
const char *class, *subclass;
|
||||||
nvlist_t *nvl;
|
nvlist_t *nvl;
|
||||||
boolean_t is_zfs = B_FALSE;
|
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
|
* if this is a disk and it is partitioned, then the
|
||||||
* zfs label will reside in a DEVTYPE=partition and
|
* zfs label will reside in a DEVTYPE=partition and
|
||||||
* we can skip passing this event
|
* 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");
|
type = udev_device_get_property_value(dev, "DEVTYPE");
|
||||||
part = udev_device_get_property_value(dev,
|
part = udev_device_get_property_value(dev,
|
||||||
|
@ -237,24 +213,10 @@ zed_udev_monitor(void *arg)
|
||||||
if (type != NULL && type[0] != '\0' &&
|
if (type != NULL && type[0] != '\0' &&
|
||||||
strcmp(type, "disk") == 0 &&
|
strcmp(type, "disk") == 0 &&
|
||||||
part != NULL && part[0] != '\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 */
|
/* skip and wait for partition event */
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ignore small partitions
|
* ignore small partitions
|
||||||
|
@ -265,11 +227,6 @@ zed_udev_monitor(void *arg)
|
||||||
sectors = udev_device_get_sysattr_value(dev, "size");
|
sectors = udev_device_get_sysattr_value(dev, "size");
|
||||||
if (sectors != NULL &&
|
if (sectors != NULL &&
|
||||||
strtoull(sectors, NULL, 10) < MINIMUM_SECTORS) {
|
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);
|
udev_device_unref(dev);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -279,19 +236,10 @@ zed_udev_monitor(void *arg)
|
||||||
* device id string is required in the message schema
|
* device id string is required in the message schema
|
||||||
* for matching with vdevs. Preflight here for expected
|
* for matching with vdevs. Preflight here for expected
|
||||||
* udev information.
|
* 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");
|
bus = udev_device_get_property_value(dev, "ID_BUS");
|
||||||
uuid = udev_device_get_property_value(dev, "DM_UUID");
|
uuid = udev_device_get_property_value(dev, "DM_UUID");
|
||||||
devpath = udev_device_get_devpath(dev);
|
if (!is_zfs && (bus == NULL && uuid == NULL)) {
|
||||||
if (!is_zfs && (bus == NULL && uuid == NULL &&
|
|
||||||
strstr(devpath, "/nvme/") == NULL)) {
|
|
||||||
zed_log_msg(LOG_INFO, "zed_udev_monitor: %s no devid "
|
zed_log_msg(LOG_INFO, "zed_udev_monitor: %s no devid "
|
||||||
"source", udev_device_get_devnode(dev));
|
"source", udev_device_get_devnode(dev));
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
|
@ -402,7 +350,7 @@ zed_udev_monitor(void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
zed_disk_event_init(void)
|
zed_disk_event_init()
|
||||||
{
|
{
|
||||||
int fd, fflags;
|
int fd, fflags;
|
||||||
|
|
||||||
|
@ -438,7 +386,7 @@ zed_disk_event_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zed_disk_event_fini(void)
|
zed_disk_event_fini()
|
||||||
{
|
{
|
||||||
/* cancel monitor thread at recvmsg() */
|
/* cancel monitor thread at recvmsg() */
|
||||||
(void) pthread_cancel(g_mon_tid);
|
(void) pthread_cancel(g_mon_tid);
|
||||||
|
@ -456,13 +404,13 @@ zed_disk_event_fini(void)
|
||||||
#include "zed_disk_event.h"
|
#include "zed_disk_event.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
zed_disk_event_init(void)
|
zed_disk_event_init()
|
||||||
{
|
{
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zed_disk_event_fini(void)
|
zed_disk_event_fini()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include "zed_strings.h"
|
#include "zed_strings.h"
|
||||||
|
|
||||||
#include "agents/zfs_agents.h"
|
#include "agents/zfs_agents.h"
|
||||||
#include <libzutil.h>
|
|
||||||
|
|
||||||
#define MAXBUF 4096
|
#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.
|
* 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,
|
zed_log_msg(LOG_WARNING,
|
||||||
"Failed to lookup zevent class (eid=%llu)", eid);
|
"Failed to lookup zevent class (eid=%llu)", eid);
|
||||||
} else {
|
} 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 */
|
/* let internal modules see this event first */
|
||||||
zfs_agent_post_event(class, NULL, nvl);
|
zfs_agent_post_event(class, NULL, nvl);
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include "zed_exec.h"
|
#include "zed_exec.h"
|
||||||
#include "zed_log.h"
|
#include "zed_log.h"
|
||||||
#include "zed_strings.h"
|
#include "zed_strings.h"
|
||||||
|
|
|
@ -315,14 +315,14 @@ get_usage(zfs_help_t idx)
|
||||||
case HELP_ROLLBACK:
|
case HELP_ROLLBACK:
|
||||||
return (gettext("\trollback [-rRf] <snapshot>\n"));
|
return (gettext("\trollback [-rRf] <snapshot>\n"));
|
||||||
case HELP_SEND:
|
case HELP_SEND:
|
||||||
return (gettext("\tsend [-DnPpRVvLecwhb] [-[i|I] snapshot] "
|
return (gettext("\tsend [-DnPpRvLecwhb] [-[i|I] snapshot] "
|
||||||
"<snapshot>\n"
|
"<snapshot>\n"
|
||||||
"\tsend [-DnVvPLecw] [-i snapshot|bookmark] "
|
"\tsend [-nvPLecw] [-i snapshot|bookmark] "
|
||||||
"<filesystem|volume|snapshot>\n"
|
"<filesystem|volume|snapshot>\n"
|
||||||
"\tsend [-DnPpVvLec] [-i bookmark|snapshot] "
|
"\tsend [-DnPpvLec] [-i bookmark|snapshot] "
|
||||||
"--redact <bookmark> <snapshot>\n"
|
"--redact <bookmark> <snapshot>\n"
|
||||||
"\tsend [-nVvPe] -t <receive_resume_token>\n"
|
"\tsend [-nvPe] -t <receive_resume_token>\n"
|
||||||
"\tsend [-PnVv] --saved filesystem\n"));
|
"\tsend [-Pnv] --saved filesystem\n"));
|
||||||
case HELP_SET:
|
case HELP_SET:
|
||||||
return (gettext("\tset <property=value> ... "
|
return (gettext("\tset <property=value> ... "
|
||||||
"<filesystem|volume|snapshot> ...\n"));
|
"<filesystem|volume|snapshot> ...\n"));
|
||||||
|
@ -535,7 +535,7 @@ usage(boolean_t requested)
|
||||||
show_properties = B_TRUE;
|
show_properties = B_TRUE;
|
||||||
|
|
||||||
if (show_properties) {
|
if (show_properties) {
|
||||||
(void) fprintf(fp, "%s",
|
(void) fprintf(fp,
|
||||||
gettext("\nThe following properties are supported:\n"));
|
gettext("\nThe following properties are supported:\n"));
|
||||||
|
|
||||||
(void) fprintf(fp, "\n\t%-14s %s %s %s\n\n",
|
(void) fprintf(fp, "\n\t%-14s %s %s %s\n\n",
|
||||||
|
@ -2480,7 +2480,7 @@ upgrade_set_callback(zfs_handle_t *zhp, void *data)
|
||||||
|
|
||||||
/* upgrade */
|
/* upgrade */
|
||||||
if (version < cb->cb_version) {
|
if (version < cb->cb_version) {
|
||||||
char verstr[24];
|
char verstr[16];
|
||||||
(void) snprintf(verstr, sizeof (verstr),
|
(void) snprintf(verstr, sizeof (verstr),
|
||||||
"%llu", (u_longlong_t)cb->cb_version);
|
"%llu", (u_longlong_t)cb->cb_version);
|
||||||
if (cb->cb_lastfs[0] && !same_pool(zhp, cb->cb_lastfs)) {
|
if (cb->cb_lastfs[0] && !same_pool(zhp, cb->cb_lastfs)) {
|
||||||
|
@ -3474,8 +3474,6 @@ print_header(list_cbdata_t *cb)
|
||||||
boolean_t first = B_TRUE;
|
boolean_t first = B_TRUE;
|
||||||
boolean_t right_justify;
|
boolean_t right_justify;
|
||||||
|
|
||||||
color_start(ANSI_BOLD);
|
|
||||||
|
|
||||||
for (; pl != NULL; pl = pl->pl_next) {
|
for (; pl != NULL; pl = pl->pl_next) {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
(void) printf(" ");
|
(void) printf(" ");
|
||||||
|
@ -3502,31 +3500,9 @@ print_header(list_cbdata_t *cb)
|
||||||
(void) printf("%-*s", (int)pl->pl_width, header);
|
(void) printf("%-*s", (int)pl->pl_width, header);
|
||||||
}
|
}
|
||||||
|
|
||||||
color_end();
|
|
||||||
|
|
||||||
(void) printf("\n");
|
(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
|
* Given a dataset and a list of fields, print out all the properties according
|
||||||
* to the described layout.
|
* to the described layout.
|
||||||
|
@ -3589,22 +3565,6 @@ print_dataset(zfs_handle_t *zhp, list_cbdata_t *cb)
|
||||||
right_justify = B_FALSE;
|
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
|
* 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
|
* last column and it is left-justified, don't include a width
|
||||||
|
@ -3616,9 +3576,6 @@ print_dataset(zfs_handle_t *zhp, list_cbdata_t *cb)
|
||||||
(void) printf("%*s", (int)pl->pl_width, propstr);
|
(void) printf("%*s", (int)pl->pl_width, propstr);
|
||||||
else
|
else
|
||||||
(void) printf("%-*s", (int)pl->pl_width, propstr);
|
(void) printf("%-*s", (int)pl->pl_width, propstr);
|
||||||
|
|
||||||
if (pl->pl_prop == ZFS_PROP_AVAILABLE)
|
|
||||||
color_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) printf("\n");
|
(void) printf("\n");
|
||||||
|
@ -4450,7 +4407,6 @@ zfs_do_send(int argc, char **argv)
|
||||||
{"props", no_argument, NULL, 'p'},
|
{"props", no_argument, NULL, 'p'},
|
||||||
{"parsable", no_argument, NULL, 'P'},
|
{"parsable", no_argument, NULL, 'P'},
|
||||||
{"dedup", no_argument, NULL, 'D'},
|
{"dedup", no_argument, NULL, 'D'},
|
||||||
{"proctitle", no_argument, NULL, 'V'},
|
|
||||||
{"verbose", no_argument, NULL, 'v'},
|
{"verbose", no_argument, NULL, 'v'},
|
||||||
{"dryrun", no_argument, NULL, 'n'},
|
{"dryrun", no_argument, NULL, 'n'},
|
||||||
{"large-block", no_argument, NULL, 'L'},
|
{"large-block", no_argument, NULL, 'L'},
|
||||||
|
@ -4465,7 +4421,7 @@ zfs_do_send(int argc, char **argv)
|
||||||
};
|
};
|
||||||
|
|
||||||
/* check options */
|
/* 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) {
|
long_options, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'i':
|
case 'i':
|
||||||
|
@ -4500,9 +4456,6 @@ zfs_do_send(int argc, char **argv)
|
||||||
case 'P':
|
case 'P':
|
||||||
flags.parsable = B_TRUE;
|
flags.parsable = B_TRUE;
|
||||||
break;
|
break;
|
||||||
case 'V':
|
|
||||||
flags.progressastitle = B_TRUE;
|
|
||||||
break;
|
|
||||||
case 'v':
|
case 'v':
|
||||||
flags.verbosity++;
|
flags.verbosity++;
|
||||||
flags.progress = B_TRUE;
|
flags.progress = B_TRUE;
|
||||||
|
@ -4578,7 +4531,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;
|
flags.verbosity = 1;
|
||||||
|
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
|
@ -6640,7 +6593,7 @@ zfs_do_holds(int argc, char **argv)
|
||||||
/*
|
/*
|
||||||
* 1. collect holds data, set format options
|
* 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);
|
holds_callback, &cb);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
++errors;
|
++errors;
|
||||||
|
@ -7522,7 +7475,6 @@ unshare_unmount(int op, int argc, char **argv)
|
||||||
if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) ==
|
if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) ==
|
||||||
ZFS_CANMOUNT_NOAUTO)
|
ZFS_CANMOUNT_NOAUTO)
|
||||||
continue;
|
continue;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7719,7 +7671,7 @@ zfs_do_diff(int argc, char **argv)
|
||||||
int c;
|
int c;
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "FHth")) != -1) {
|
while ((c = getopt(argc, argv, "FHt")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'F':
|
case 'F':
|
||||||
flags |= ZFS_DIFF_CLASSIFY;
|
flags |= ZFS_DIFF_CLASSIFY;
|
||||||
|
@ -7730,9 +7682,6 @@ zfs_do_diff(int argc, char **argv)
|
||||||
case 't':
|
case 't':
|
||||||
flags |= ZFS_DIFF_TIMESTAMP;
|
flags |= ZFS_DIFF_TIMESTAMP;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
|
||||||
flags |= ZFS_DIFF_NO_MANGLE;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("invalid option '%c'\n"), optopt);
|
gettext("invalid option '%c'\n"), optopt);
|
||||||
|
@ -8582,7 +8531,7 @@ static int
|
||||||
zfs_do_wait(int argc, char **argv)
|
zfs_do_wait(int argc, char **argv)
|
||||||
{
|
{
|
||||||
boolean_t enabled[ZFS_WAIT_NUM_ACTIVITIES];
|
boolean_t enabled[ZFS_WAIT_NUM_ACTIVITIES];
|
||||||
int error = 0, i;
|
int error, i;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
/* By default, wait for all types of activity. */
|
/* By default, wait for all types of activity. */
|
||||||
|
@ -8740,8 +8689,6 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
libzfs_print_on_error(g_zfs, B_TRUE);
|
libzfs_print_on_error(g_zfs, B_TRUE);
|
||||||
|
|
||||||
zfs_setproctitle_init(argc, argv, environ);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Many commands modify input strings for string parsing reasons.
|
* Many commands modify input strings for string parsing reasons.
|
||||||
* We create a copy to protect the original argv.
|
* 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,
|
zfs_project_handle_dir(const char *name, zfs_project_control_t *zpc,
|
||||||
list_t *head)
|
list_t *head)
|
||||||
{
|
{
|
||||||
|
char fullname[PATH_MAX];
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
int ret = 0;
|
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;
|
zpc->zpc_ignore_noent = B_TRUE;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
while (!ret && (ent = readdir(dir)) != NULL) {
|
while (!ret && (ent = readdir(dir)) != NULL) {
|
||||||
char *fullname;
|
|
||||||
|
|
||||||
/* skip "." and ".." */
|
/* skip "." and ".." */
|
||||||
if (strcmp(ent->d_name, ".") == 0 ||
|
if (strcmp(ent->d_name, ".") == 0 ||
|
||||||
strcmp(ent->d_name, "..") == 0)
|
strcmp(ent->d_name, "..") == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strlen(ent->d_name) + strlen(name) + 1 >= PATH_MAX) {
|
if (strlen(ent->d_name) + strlen(name) >=
|
||||||
|
sizeof (fullname) + 1) {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asprintf(&fullname, "%s/%s", name, ent->d_name) == -1) {
|
sprintf(fullname, "%s/%s", name, ent->d_name);
|
||||||
errno = ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = zfs_project_handle_one(fullname, zpc);
|
ret = zfs_project_handle_one(fullname, zpc);
|
||||||
if (!ret && zpc->zpc_recursive && ent->d_type == DT_DIR)
|
if (!ret && zpc->zpc_recursive && ent->d_type == DT_DIR)
|
||||||
zfs_project_item_alloc(head, fullname);
|
zfs_project_item_alloc(head, fullname);
|
||||||
|
|
||||||
free(fullname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errno && !ret) {
|
if (errno && !ret) {
|
||||||
|
|
|
@ -26,8 +26,7 @@ zpool_LDADD = \
|
||||||
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
||||||
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||||
$(abs_top_builddir)/lib/libnvpair/libnvpair.la \
|
$(abs_top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
$(abs_top_builddir)/lib/libuutil/libuutil.la \
|
$(abs_top_builddir)/lib/libuutil/libuutil.la
|
||||||
$(abs_top_builddir)/lib/libzutil/libzutil.la
|
|
||||||
|
|
||||||
zpool_LDADD += $(LTLIBINTL)
|
zpool_LDADD += $(LTLIBINTL)
|
||||||
|
|
||||||
|
|
|
@ -116,24 +116,3 @@ after_zpool_upgrade(zpool_handle_t *zhp)
|
||||||
"details.\n"), zpool_get_name(zhp));
|
"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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -410,258 +410,3 @@ void
|
||||||
after_zpool_upgrade(zpool_handle_t *zhp)
|
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")
|
dev=$(readlink "$dev")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dev="${dev##*/}"
|
dev=$(basename "$dev")
|
||||||
val=""
|
val=""
|
||||||
if [ -d "/sys/class/block/$dev/slaves" ] ; then
|
if [ -d "/sys/class/block/$dev/slaves" ] ; then
|
||||||
# ls -C: output in columns, no newlines, two spaces (change to one)
|
# ls -C: output in columns, no newlines
|
||||||
# shellcheck disable=SC2012
|
val=$(ls -C "/sys/class/block/$dev/slaves")
|
||||||
val=$(ls -C "/sys/class/block/$dev/slaves" | tr -s '[:space:]' ' ')
|
|
||||||
|
# ls -C will print two spaces between files; change to one space.
|
||||||
|
val=$(echo "$val" | sed -r 's/[[:blank:]]+/ /g')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "dm-deps=$val"
|
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-1s: Do a single 1-second iostat sample and show values.
|
||||||
iostat-10s: Do a single 10-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
|
if [ "$1" = "-h" ] ; then
|
||||||
echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2-
|
echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2-
|
||||||
exit
|
exit
|
||||||
|
@ -42,7 +42,7 @@ else
|
||||||
${brief:+"-y"} \
|
${brief:+"-y"} \
|
||||||
${interval:+"$interval"} \
|
${interval:+"$interval"} \
|
||||||
${interval:+"1"} \
|
${interval:+"1"} \
|
||||||
"$VDEV_UPATH" | grep -v '^$' | tail -n 2)
|
"$VDEV_UPATH" | awk NF | tail -n 2)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ fi
|
||||||
cols=$(echo "$out" | head -n 1)
|
cols=$(echo "$out" | head -n 1)
|
||||||
|
|
||||||
# Get the values and tab separate them to make them cut-able.
|
# 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
|
i=0
|
||||||
for col in $cols ; do
|
for col in $cols ; do
|
||||||
|
|
|
@ -48,7 +48,7 @@ size: Show the disk capacity.
|
||||||
vendor: Show the disk vendor.
|
vendor: Show the disk vendor.
|
||||||
lsblk: Show the disk size, vendor, and model number."
|
lsblk: Show the disk size, vendor, and model number."
|
||||||
|
|
||||||
script="${0##*/}"
|
script=$(basename "$0")
|
||||||
|
|
||||||
if [ "$1" = "-h" ] ; then
|
if [ "$1" = "-h" ] ; then
|
||||||
echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2-
|
echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2-
|
||||||
|
|
|
@ -4,23 +4,19 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
if [ "$1" = "-h" ] ; then
|
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
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -b "$VDEV_UPATH" ]; then
|
if [ -b "$VDEV_UPATH" ]; then
|
||||||
device="${VDEV_UPATH##*/}"
|
device=$(basename "$VDEV_UPATH")
|
||||||
read -r val 2>/dev/null < "/sys/block/$device/queue/rotational"
|
val=$(cat "/sys/block/$device/queue/rotational" 2>/dev/null)
|
||||||
case "$val" in
|
if [ "$val" = "0" ]; then
|
||||||
0) MEDIA="ssd" ;;
|
MEDIA="ssd"
|
||||||
1) MEDIA="hdd" ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
vpd_pg83="/sys/block/$device/device/vpd_pg83"
|
|
||||||
if [ -f "$vpd_pg83" ]; then
|
|
||||||
if grep -q --binary "iqn." "$vpd_pg83"; then
|
|
||||||
MEDIA="iscsi"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$val" = "1" ]; then
|
||||||
|
MEDIA="hdd"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [ -f "$VDEV_UPATH" ]; then
|
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.
|
locate_led: Show value of the disk enclosure slot locate LED.
|
||||||
ses: Show disk's enc, enc device, slot, and fault/locate LED values."
|
ses: Show disk's enc, enc device, slot, and fault/locate LED values."
|
||||||
|
|
||||||
script="${0##*/}"
|
script=$(basename "$0")
|
||||||
if [ "$1" = "-h" ] ; then
|
if [ "$1" = "-h" ] ; then
|
||||||
echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2-
|
echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2-
|
||||||
exit
|
exit
|
||||||
|
@ -32,30 +32,16 @@ for i in $scripts ; do
|
||||||
val=""
|
val=""
|
||||||
case $i in
|
case $i in
|
||||||
enc)
|
enc)
|
||||||
if echo "$VDEV_ENC_SYSFS_PATH" | grep -q '/sys/bus/pci/slots' ; then
|
val=$(ls "$VDEV_ENC_SYSFS_PATH/../../" 2>/dev/null)
|
||||||
val="$VDEV_ENC_SYSFS_PATH"
|
|
||||||
else
|
|
||||||
val="$(ls """$VDEV_ENC_SYSFS_PATH/../../""" 2>/dev/null)"
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
slot)
|
slot)
|
||||||
if echo "$VDEV_ENC_SYSFS_PATH" | grep -q '/sys/bus/pci/slots' ; then
|
val=$(cat "$VDEV_ENC_SYSFS_PATH/slot" 2>/dev/null)
|
||||||
val="$(basename """$VDEV_ENC_SYSFS_PATH""")"
|
|
||||||
else
|
|
||||||
val="$(cat """$VDEV_ENC_SYSFS_PATH/slot""" 2>/dev/null)"
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
encdev)
|
encdev)
|
||||||
val=$(ls "$VDEV_ENC_SYSFS_PATH/../device/scsi_generic" 2>/dev/null)
|
val=$(ls "$VDEV_ENC_SYSFS_PATH/../device/scsi_generic" 2>/dev/null)
|
||||||
;;
|
;;
|
||||||
fault_led)
|
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)
|
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
|
|
||||||
;;
|
;;
|
||||||
locate_led)
|
locate_led)
|
||||||
val=$(cat "$VDEV_ENC_SYSFS_PATH/locate" 2>/dev/null)
|
val=$(cat "$VDEV_ENC_SYSFS_PATH/locate" 2>/dev/null)
|
||||||
|
|
|
@ -264,6 +264,51 @@ for_each_pool(int argc, char **argv, boolean_t unavail,
|
||||||
return (ret);
|
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
|
* 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
|
* 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,
|
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
||||||
&nvroot) == 0);
|
&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)
|
vdev_run_cmd(vdev_cmd_data_t *data, char *cmd)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
char *argv[2] = {cmd};
|
char *argv[2] = {cmd, 0};
|
||||||
char **env;
|
char *env[5] = {"PATH=/bin:/sbin:/usr/bin:/usr/sbin", NULL, NULL, NULL,
|
||||||
|
NULL};
|
||||||
char **lines = NULL;
|
char **lines = NULL;
|
||||||
int lines_cnt = 0;
|
int lines_cnt = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
env = zpool_vdev_script_alloc_env(data->pool, data->path, data->upath,
|
/* Setup our custom environment variables */
|
||||||
data->vdev_enc_sysfs_path, NULL, NULL);
|
rc = asprintf(&env[1], "VDEV_PATH=%s",
|
||||||
if (env == NULL)
|
data->path ? data->path : "");
|
||||||
|
if (rc == -1) {
|
||||||
|
env[1] = NULL;
|
||||||
goto out;
|
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 */
|
/* Run the command */
|
||||||
rc = libzfs_run_process_get_stdout_nopath(cmd, argv, env, &lines,
|
rc = libzfs_run_process_get_stdout_nopath(cmd, argv, env, &lines,
|
||||||
&lines_cnt);
|
&lines_cnt);
|
||||||
|
|
||||||
zpool_vdev_script_free_env(env);
|
|
||||||
|
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -467,6 +528,10 @@ vdev_run_cmd(vdev_cmd_data_t *data, char *cmd)
|
||||||
out:
|
out:
|
||||||
if (lines != NULL)
|
if (lines != NULL)
|
||||||
libzfs_free_str_array(lines, lines_cnt);
|
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 */
|
/* For each vdev in the pool run a command */
|
||||||
static int
|
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_list_t *vcdl = cb_vcdl;
|
||||||
vdev_cmd_data_t *data;
|
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 *vname = NULL;
|
||||||
char *vdev_enc_sysfs_path = NULL;
|
char *vdev_enc_sysfs_path = NULL;
|
||||||
int i, match = 0;
|
int i, match = 0;
|
||||||
zpool_handle_t *zhp = zhp_data;
|
|
||||||
|
|
||||||
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0)
|
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0)
|
||||||
return (1);
|
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,
|
nvlist_lookup_string(nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
|
||||||
&vdev_enc_sysfs_path);
|
&vdev_enc_sysfs_path);
|
||||||
|
|
||||||
|
|
|
@ -345,7 +345,7 @@ get_usage(zpool_help_t idx)
|
||||||
return (gettext("\tattach [-fsw] [-o property=value] "
|
return (gettext("\tattach [-fsw] [-o property=value] "
|
||||||
"<pool> <device> <new-device>\n"));
|
"<pool> <device> <new-device>\n"));
|
||||||
case HELP_CLEAR:
|
case HELP_CLEAR:
|
||||||
return (gettext("\tclear [[--power]|[-nF]] <pool> [device]\n"));
|
return (gettext("\tclear [-nF] <pool> [device]\n"));
|
||||||
case HELP_CREATE:
|
case HELP_CREATE:
|
||||||
return (gettext("\tcreate [-fnd] [-o property=value] ... \n"
|
return (gettext("\tcreate [-fnd] [-o property=value] ... \n"
|
||||||
"\t [-O file-system-property=value] ... \n"
|
"\t [-O file-system-property=value] ... \n"
|
||||||
|
@ -381,11 +381,9 @@ get_usage(zpool_help_t idx)
|
||||||
"[-T d|u] [pool] ... \n"
|
"[-T d|u] [pool] ... \n"
|
||||||
"\t [interval [count]]\n"));
|
"\t [interval [count]]\n"));
|
||||||
case HELP_OFFLINE:
|
case HELP_OFFLINE:
|
||||||
return (gettext("\toffline [--power]|[[-f][-t]] <pool> "
|
return (gettext("\toffline [-f] [-t] <pool> <device> ...\n"));
|
||||||
"<device> ...\n"));
|
|
||||||
case HELP_ONLINE:
|
case HELP_ONLINE:
|
||||||
return (gettext("\tonline [--power][-e] <pool> <device> "
|
return (gettext("\tonline [-e] <pool> <device> ...\n"));
|
||||||
"...\n"));
|
|
||||||
case HELP_REPLACE:
|
case HELP_REPLACE:
|
||||||
return (gettext("\treplace [-fsw] [-o property=value] "
|
return (gettext("\treplace [-fsw] [-o property=value] "
|
||||||
"<pool> <device> [new-device]\n"));
|
"<pool> <device> [new-device]\n"));
|
||||||
|
@ -394,7 +392,7 @@ get_usage(zpool_help_t idx)
|
||||||
case HELP_REOPEN:
|
case HELP_REOPEN:
|
||||||
return (gettext("\treopen [-n] <pool>\n"));
|
return (gettext("\treopen [-n] <pool>\n"));
|
||||||
case HELP_INITIALIZE:
|
case HELP_INITIALIZE:
|
||||||
return (gettext("\tinitialize [-c | -s | -u] [-w] <pool> "
|
return (gettext("\tinitialize [-c | -s] [-w] <pool> "
|
||||||
"[<device> ...]\n"));
|
"[<device> ...]\n"));
|
||||||
case HELP_SCRUB:
|
case HELP_SCRUB:
|
||||||
return (gettext("\tscrub [-s | -p] [-w] <pool> ...\n"));
|
return (gettext("\tscrub [-s | -p] [-w] <pool> ...\n"));
|
||||||
|
@ -404,7 +402,7 @@ get_usage(zpool_help_t idx)
|
||||||
return (gettext("\ttrim [-dw] [-r <rate>] [-c | -s] <pool> "
|
return (gettext("\ttrim [-dw] [-r <rate>] [-c | -s] <pool> "
|
||||||
"[<device> ...]\n"));
|
"[<device> ...]\n"));
|
||||||
case HELP_STATUS:
|
case HELP_STATUS:
|
||||||
return (gettext("\tstatus [--power] [-c [script1,script2,...]] "
|
return (gettext("\tstatus [-c [script1,script2,...]] "
|
||||||
"[-igLpPstvxD] [-T d|u] [pool] ... \n"
|
"[-igLpPstvxD] [-T d|u] [pool] ... \n"
|
||||||
"\t [interval [count]]\n"));
|
"\t [interval [count]]\n"));
|
||||||
case HELP_UPGRADE:
|
case HELP_UPGRADE:
|
||||||
|
@ -487,77 +485,6 @@ print_prop_cb(int prop, void *cb)
|
||||||
return (ZPROP_CONT);
|
return (ZPROP_CONT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Given a leaf vdev name like 'L5' return its VDEV_CONFIG_PATH like
|
|
||||||
* '/dev/disk/by-vdev/L5'.
|
|
||||||
*/
|
|
||||||
static const char *
|
|
||||||
vdev_name_to_path(zpool_handle_t *zhp, char *vdev)
|
|
||||||
{
|
|
||||||
nvlist_t *vdev_nv = zpool_find_vdev(zhp, vdev, NULL, NULL, NULL);
|
|
||||||
if (vdev_nv == NULL) {
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
return (fnvlist_lookup_string(vdev_nv, ZPOOL_CONFIG_PATH));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
zpool_power_on(zpool_handle_t *zhp, char *vdev)
|
|
||||||
{
|
|
||||||
return (zpool_power(zhp, vdev, B_TRUE));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
zpool_power_on_and_disk_wait(zpool_handle_t *zhp, char *vdev)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = zpool_power_on(zhp, vdev);
|
|
||||||
if (rc != 0)
|
|
||||||
return (rc);
|
|
||||||
|
|
||||||
zpool_disk_wait(vdev_name_to_path(zhp, vdev));
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
zpool_power_on_pool_and_wait_for_devices(zpool_handle_t *zhp)
|
|
||||||
{
|
|
||||||
nvlist_t *nv;
|
|
||||||
const char *path = NULL;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* Power up all the devices first */
|
|
||||||
FOR_EACH_REAL_LEAF_VDEV(zhp, nv) {
|
|
||||||
path = fnvlist_lookup_string(nv, ZPOOL_CONFIG_PATH);
|
|
||||||
if (path != NULL) {
|
|
||||||
rc = zpool_power_on(zhp, (char *)path);
|
|
||||||
if (rc != 0) {
|
|
||||||
return (rc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Wait for their devices to show up. Since we powered them on
|
|
||||||
* at roughly the same time, they should all come online around
|
|
||||||
* the same time.
|
|
||||||
*/
|
|
||||||
FOR_EACH_REAL_LEAF_VDEV(zhp, nv) {
|
|
||||||
path = fnvlist_lookup_string(nv, ZPOOL_CONFIG_PATH);
|
|
||||||
zpool_disk_wait(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
zpool_power_off(zpool_handle_t *zhp, char *vdev)
|
|
||||||
{
|
|
||||||
return (zpool_power(zhp, vdev, B_FALSE));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display usage message. If we're inside a command, display only the usage for
|
* Display usage message. If we're inside a command, display only the usage for
|
||||||
* that command. Otherwise, iterate over the entire command table and display
|
* that command. Otherwise, iterate over the entire command table and display
|
||||||
|
@ -592,7 +519,7 @@ usage(boolean_t requested)
|
||||||
(strcmp(current_command->name, "get") == 0) ||
|
(strcmp(current_command->name, "get") == 0) ||
|
||||||
(strcmp(current_command->name, "list") == 0))) {
|
(strcmp(current_command->name, "list") == 0))) {
|
||||||
|
|
||||||
(void) fprintf(fp, "%s",
|
(void) fprintf(fp,
|
||||||
gettext("\nthe following properties are supported:\n"));
|
gettext("\nthe following properties are supported:\n"));
|
||||||
|
|
||||||
(void) fprintf(fp, "\n\t%-19s %s %s\n\n",
|
(void) fprintf(fp, "\n\t%-19s %s %s\n\n",
|
||||||
|
@ -621,13 +548,12 @@ usage(boolean_t requested)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zpool initialize [-c | -s | -u] [-w] <pool> [<vdev> ...]
|
* zpool initialize [-c | -s] [-w] <pool> [<vdev> ...]
|
||||||
* Initialize all unused blocks in the specified vdevs, or all vdevs in the pool
|
* Initialize all unused blocks in the specified vdevs, or all vdevs in the pool
|
||||||
* if none specified.
|
* if none specified.
|
||||||
*
|
*
|
||||||
* -c Cancel. Ends active initializing.
|
* -c Cancel. Ends active initializing.
|
||||||
* -s Suspend. Initializing can then be restarted with no flags.
|
* -s Suspend. Initializing can then be restarted with no flags.
|
||||||
* -u Uninitialize. Clears initialization state.
|
|
||||||
* -w Wait. Blocks until initializing has completed.
|
* -w Wait. Blocks until initializing has completed.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
@ -643,14 +569,12 @@ zpool_do_initialize(int argc, char **argv)
|
||||||
struct option long_options[] = {
|
struct option long_options[] = {
|
||||||
{"cancel", no_argument, NULL, 'c'},
|
{"cancel", no_argument, NULL, 'c'},
|
||||||
{"suspend", no_argument, NULL, 's'},
|
{"suspend", no_argument, NULL, 's'},
|
||||||
{"uninit", no_argument, NULL, 'u'},
|
|
||||||
{"wait", no_argument, NULL, 'w'},
|
{"wait", no_argument, NULL, 'w'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
pool_initialize_func_t cmd_type = POOL_INITIALIZE_START;
|
pool_initialize_func_t cmd_type = POOL_INITIALIZE_START;
|
||||||
while ((c = getopt_long(argc, argv, "csuw", long_options,
|
while ((c = getopt_long(argc, argv, "csw", long_options, NULL)) != -1) {
|
||||||
NULL)) != -1) {
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
if (cmd_type != POOL_INITIALIZE_START &&
|
if (cmd_type != POOL_INITIALIZE_START &&
|
||||||
|
@ -670,15 +594,6 @@ zpool_do_initialize(int argc, char **argv)
|
||||||
}
|
}
|
||||||
cmd_type = POOL_INITIALIZE_SUSPEND;
|
cmd_type = POOL_INITIALIZE_SUSPEND;
|
||||||
break;
|
break;
|
||||||
case 'u':
|
|
||||||
if (cmd_type != POOL_INITIALIZE_START &&
|
|
||||||
cmd_type != POOL_INITIALIZE_UNINIT) {
|
|
||||||
(void) fprintf(stderr, gettext("-u cannot be "
|
|
||||||
"combined with other options\n"));
|
|
||||||
usage(B_FALSE);
|
|
||||||
}
|
|
||||||
cmd_type = POOL_INITIALIZE_UNINIT;
|
|
||||||
break;
|
|
||||||
case 'w':
|
case 'w':
|
||||||
wait = B_TRUE;
|
wait = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -705,8 +620,8 @@ zpool_do_initialize(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait && (cmd_type != POOL_INITIALIZE_START)) {
|
if (wait && (cmd_type != POOL_INITIALIZE_START)) {
|
||||||
(void) fprintf(stderr, gettext("-w cannot be used with -c, -s"
|
(void) fprintf(stderr, gettext("-w cannot be used with -c or "
|
||||||
"or -u\n"));
|
"-s\n"));
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1300,26 +1215,6 @@ zpool_do_remove(int argc, char **argv)
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Return 1 if a vdev is active (being used in a pool)
|
|
||||||
* Return 0 if a vdev is inactive (offlined or faulted, or not in active pool)
|
|
||||||
*
|
|
||||||
* This is useful for checking if a disk in an active pool is offlined or
|
|
||||||
* faulted.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
vdev_is_active(char *vdev_path)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
fd = open(vdev_path, O_EXCL);
|
|
||||||
if (fd < 0) {
|
|
||||||
return (1); /* cant open O_EXCL - disk is active */
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
return (0); /* disk is inactive in the pool */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zpool labelclear [-f] <vdev>
|
* zpool labelclear [-f] <vdev>
|
||||||
*
|
*
|
||||||
|
@ -1429,23 +1324,9 @@ zpool_do_labelclear(int argc, char **argv)
|
||||||
case POOL_STATE_ACTIVE:
|
case POOL_STATE_ACTIVE:
|
||||||
case POOL_STATE_SPARE:
|
case POOL_STATE_SPARE:
|
||||||
case POOL_STATE_L2CACHE:
|
case POOL_STATE_L2CACHE:
|
||||||
/*
|
|
||||||
* We allow the user to call 'zpool offline -f'
|
|
||||||
* on an offlined disk in an active pool. We can check if
|
|
||||||
* the disk is online by calling vdev_is_active().
|
|
||||||
*/
|
|
||||||
if (force && !vdev_is_active(vdev))
|
|
||||||
break;
|
|
||||||
|
|
||||||
(void) fprintf(stderr, gettext(
|
(void) fprintf(stderr, gettext(
|
||||||
"%s is a member (%s) of pool \"%s\""),
|
"%s is a member (%s) of pool \"%s\"\n"),
|
||||||
vdev, zpool_pool_state_to_name(state), name);
|
vdev, zpool_pool_state_to_name(state), name);
|
||||||
|
|
||||||
if (force) {
|
|
||||||
(void) fprintf(stderr, gettext(
|
|
||||||
". Offline the disk first to clear its label."));
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
|
@ -2127,13 +2008,11 @@ typedef struct status_cbdata {
|
||||||
boolean_t cb_explain;
|
boolean_t cb_explain;
|
||||||
boolean_t cb_first;
|
boolean_t cb_first;
|
||||||
boolean_t cb_dedup_stats;
|
boolean_t cb_dedup_stats;
|
||||||
boolean_t cb_print_unhealthy;
|
|
||||||
boolean_t cb_print_status;
|
boolean_t cb_print_status;
|
||||||
boolean_t cb_print_slow_ios;
|
boolean_t cb_print_slow_ios;
|
||||||
boolean_t cb_print_vdev_init;
|
boolean_t cb_print_vdev_init;
|
||||||
boolean_t cb_print_vdev_trim;
|
boolean_t cb_print_vdev_trim;
|
||||||
vdev_cmd_data_list_t *vcdl;
|
vdev_cmd_data_list_t *vcdl;
|
||||||
boolean_t cb_print_power;
|
|
||||||
} status_cbdata_t;
|
} status_cbdata_t;
|
||||||
|
|
||||||
/* Return 1 if string is NULL, empty, or whitespace; return 0 otherwise. */
|
/* Return 1 if string is NULL, empty, or whitespace; return 0 otherwise. */
|
||||||
|
@ -2326,35 +2205,6 @@ health_str_to_color(const char *health)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Called for each leaf vdev. Returns 0 if the vdev is healthy.
|
|
||||||
* A vdev is unhealthy if any of the following are true:
|
|
||||||
* 1) there are read, write, or checksum errors,
|
|
||||||
* 2) its state is not ONLINE, or
|
|
||||||
* 3) slow IO reporting was requested (-s) and there are slow IOs.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
vdev_health_check_cb(void *hdl_data, nvlist_t *nv, void *data)
|
|
||||||
{
|
|
||||||
status_cbdata_t *cb = data;
|
|
||||||
vdev_stat_t *vs;
|
|
||||||
uint_t vsc;
|
|
||||||
(void) hdl_data;
|
|
||||||
|
|
||||||
if (nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
|
|
||||||
(uint64_t **)&vs, &vsc) != 0)
|
|
||||||
return (1);
|
|
||||||
|
|
||||||
if (vs->vs_checksum_errors || vs->vs_read_errors ||
|
|
||||||
vs->vs_write_errors || vs->vs_state != VDEV_STATE_HEALTHY)
|
|
||||||
return (1);
|
|
||||||
|
|
||||||
if (cb->cb_print_slow_ios && vs->vs_slow_ios)
|
|
||||||
return (1);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print out configuration state as requested by status_callback.
|
* Print out configuration state as requested by status_callback.
|
||||||
*/
|
*/
|
||||||
|
@ -2373,8 +2223,7 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
|
||||||
const char *state;
|
const char *state;
|
||||||
char *type;
|
char *type;
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
char *rcolor = NULL, *wcolor = NULL, *ccolor = NULL,
|
char *rcolor = NULL, *wcolor = NULL, *ccolor = NULL;
|
||||||
*scolor = NULL;
|
|
||||||
|
|
||||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
|
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
|
||||||
&child, &children) != 0)
|
&child, &children) != 0)
|
||||||
|
@ -2401,15 +2250,6 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
|
||||||
state = gettext("AVAIL");
|
state = gettext("AVAIL");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If '-e' is specified then top-level vdevs and their children
|
|
||||||
* can be pruned if all of their leaves are healthy.
|
|
||||||
*/
|
|
||||||
if (cb->cb_print_unhealthy && depth > 0 &&
|
|
||||||
for_each_vdev_in_nvlist(nv, vdev_health_check_cb, cb) == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf_color(health_str_to_color(state),
|
printf_color(health_str_to_color(state),
|
||||||
"\t%*s%-*s %-8s", depth, "", cb->cb_namewidth - depth,
|
"\t%*s%-*s %-8s", depth, "", cb->cb_namewidth - depth,
|
||||||
name, state);
|
name, state);
|
||||||
|
@ -2424,9 +2264,6 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
|
||||||
if (vs->vs_checksum_errors)
|
if (vs->vs_checksum_errors)
|
||||||
ccolor = ANSI_RED;
|
ccolor = ANSI_RED;
|
||||||
|
|
||||||
if (vs->vs_slow_ios)
|
|
||||||
scolor = ANSI_BLUE;
|
|
||||||
|
|
||||||
if (cb->cb_literal) {
|
if (cb->cb_literal) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
printf_color(rcolor, "%5llu",
|
printf_color(rcolor, "%5llu",
|
||||||
|
@ -2459,30 +2296,9 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cb->cb_literal)
|
if (cb->cb_literal)
|
||||||
printf_color(scolor, " %5llu",
|
printf(" %5llu", (u_longlong_t)vs->vs_slow_ios);
|
||||||
(u_longlong_t)vs->vs_slow_ios);
|
|
||||||
else
|
else
|
||||||
printf_color(scolor, " %5s", rbuf);
|
printf(" %5s", rbuf);
|
||||||
}
|
|
||||||
if (cb->cb_print_power) {
|
|
||||||
if (children == 0) {
|
|
||||||
/* Only leaf vdevs have physical slots */
|
|
||||||
switch (zpool_power_current_state(zhp, (char *)
|
|
||||||
fnvlist_lookup_string(nv,
|
|
||||||
ZPOOL_CONFIG_PATH))) {
|
|
||||||
case 0:
|
|
||||||
printf_color(ANSI_RED, " %5s",
|
|
||||||
gettext("off"));
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
printf(" %5s", gettext("on"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf(" %5s", "-");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf(" %5s", "-");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2588,14 +2404,7 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
|
||||||
(void) nvlist_lookup_uint64_array(root, ZPOOL_CONFIG_SCAN_STATS,
|
(void) nvlist_lookup_uint64_array(root, ZPOOL_CONFIG_SCAN_STATS,
|
||||||
(uint64_t **)&ps, &c);
|
(uint64_t **)&ps, &c);
|
||||||
|
|
||||||
/*
|
if (ps != NULL && ps->pss_state == DSS_SCANNING && children == 0) {
|
||||||
* If you force fault a drive that's resilvering, its scan stats can
|
|
||||||
* get frozen in time, giving the false impression that it's
|
|
||||||
* being resilvered. That's why we check the state to see if the vdev
|
|
||||||
* is healthy before reporting "resilvering" or "repairing".
|
|
||||||
*/
|
|
||||||
if (ps != NULL && ps->pss_state == DSS_SCANNING && children == 0 &&
|
|
||||||
vs->vs_state == VDEV_STATE_HEALTHY) {
|
|
||||||
if (vs->vs_scan_processed != 0) {
|
if (vs->vs_scan_processed != 0) {
|
||||||
(void) printf(gettext(" (%s)"),
|
(void) printf(gettext(" (%s)"),
|
||||||
(ps->pss_func == POOL_SCAN_RESILVER) ?
|
(ps->pss_func == POOL_SCAN_RESILVER) ?
|
||||||
|
@ -2607,7 +2416,7 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
|
||||||
|
|
||||||
/* The top-level vdevs have the rebuild stats */
|
/* The top-level vdevs have the rebuild stats */
|
||||||
if (vrs != NULL && vrs->vrs_state == VDEV_REBUILD_ACTIVE &&
|
if (vrs != NULL && vrs->vrs_state == VDEV_REBUILD_ACTIVE &&
|
||||||
children == 0 && vs->vs_state == VDEV_STATE_HEALTHY) {
|
children == 0) {
|
||||||
if (vs->vs_rebuild_processed != 0) {
|
if (vs->vs_rebuild_processed != 0) {
|
||||||
(void) printf(gettext(" (resilvering)"));
|
(void) printf(gettext(" (resilvering)"));
|
||||||
}
|
}
|
||||||
|
@ -3955,10 +3764,9 @@ zpool_do_import(int argc, char **argv)
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = import_pools(pools, props, mntopts, flags,
|
err = import_pools(pools, props, mntopts, flags, argv[0],
|
||||||
argc >= 1 ? argv[0] : NULL,
|
argc == 1 ? NULL : argv[1], do_destroyed, pool_specified,
|
||||||
argc >= 2 ? argv[1] : NULL,
|
do_all, &idata);
|
||||||
do_destroyed, pool_specified, do_all, &idata);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're using the cachefile and we failed to import, then
|
* If we're using the cachefile and we failed to import, then
|
||||||
|
@ -3978,10 +3786,9 @@ zpool_do_import(int argc, char **argv)
|
||||||
nvlist_free(pools);
|
nvlist_free(pools);
|
||||||
pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops);
|
pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops);
|
||||||
|
|
||||||
err = import_pools(pools, props, mntopts, flags,
|
err = import_pools(pools, props, mntopts, flags, argv[0],
|
||||||
argc >= 1 ? argv[0] : NULL,
|
argc == 1 ? NULL : argv[1], do_destroyed, pool_specified,
|
||||||
argc >= 2 ? argv[1] : NULL,
|
do_all, &idata);
|
||||||
do_destroyed, pool_specified, do_all, &idata);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -4355,8 +4162,6 @@ print_iostat_header_impl(iostat_cbdata_t *cb, unsigned int force_column_width,
|
||||||
unsigned int namewidth;
|
unsigned int namewidth;
|
||||||
const char *title;
|
const char *title;
|
||||||
|
|
||||||
color_start(ANSI_BOLD);
|
|
||||||
|
|
||||||
if (cb->cb_flags & IOS_ANYHISTO_M) {
|
if (cb->cb_flags & IOS_ANYHISTO_M) {
|
||||||
title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)];
|
title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)];
|
||||||
} else if (cb->cb_vdev_names_count) {
|
} else if (cb->cb_vdev_names_count) {
|
||||||
|
@ -4390,8 +4195,6 @@ print_iostat_header_impl(iostat_cbdata_t *cb, unsigned int force_column_width,
|
||||||
if (cb->vcdl != NULL)
|
if (cb->vcdl != NULL)
|
||||||
print_cmd_columns(cb->vcdl, 1);
|
print_cmd_columns(cb->vcdl, 1);
|
||||||
|
|
||||||
color_end();
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4401,37 +4204,6 @@ print_iostat_header(iostat_cbdata_t *cb)
|
||||||
print_iostat_header_impl(cb, 0, NULL);
|
print_iostat_header_impl(cb, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Prints a size string (i.e. 120M) with the suffix ("M") colored
|
|
||||||
* by order of magnitude. Uses column_size to add padding.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
print_stat_color(const char *statbuf, unsigned int column_size)
|
|
||||||
{
|
|
||||||
fputs(" ", stdout);
|
|
||||||
size_t len = strlen(statbuf);
|
|
||||||
while (len < column_size) {
|
|
||||||
fputc(' ', stdout);
|
|
||||||
column_size--;
|
|
||||||
}
|
|
||||||
if (*statbuf == '0') {
|
|
||||||
color_start(ANSI_GRAY);
|
|
||||||
fputc('0', stdout);
|
|
||||||
} else {
|
|
||||||
for (; *statbuf; statbuf++) {
|
|
||||||
if (*statbuf == 'K') color_start(ANSI_GREEN);
|
|
||||||
else if (*statbuf == 'M') color_start(ANSI_YELLOW);
|
|
||||||
else if (*statbuf == 'G') color_start(ANSI_RED);
|
|
||||||
else if (*statbuf == 'T') color_start(ANSI_BOLD_BLUE);
|
|
||||||
else if (*statbuf == 'P') color_start(ANSI_MAGENTA);
|
|
||||||
else if (*statbuf == 'E') color_start(ANSI_CYAN);
|
|
||||||
fputc(*statbuf, stdout);
|
|
||||||
if (--column_size <= 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
color_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display a single statistic.
|
* Display a single statistic.
|
||||||
|
@ -4447,7 +4219,7 @@ print_one_stat(uint64_t value, enum zfs_nicenum_format format,
|
||||||
if (scripted)
|
if (scripted)
|
||||||
printf("\t%s", buf);
|
printf("\t%s", buf);
|
||||||
else
|
else
|
||||||
print_stat_color(buf, column_size);
|
printf(" %*s", column_size, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5017,7 +4789,7 @@ children:
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
|
vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
|
||||||
cb->cb_name_flags | VDEV_NAME_TYPE_ID);
|
cb->cb_name_flags);
|
||||||
ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
|
ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
|
||||||
newchild[c], cb, depth + 2);
|
newchild[c], cb, depth + 2);
|
||||||
free(vname);
|
free(vname);
|
||||||
|
@ -5060,7 +4832,7 @@ children:
|
||||||
}
|
}
|
||||||
|
|
||||||
vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
|
vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
|
||||||
cb->cb_name_flags | VDEV_NAME_TYPE_ID);
|
cb->cb_name_flags);
|
||||||
ret += print_vdev_stats(zhp, vname, oldnv ?
|
ret += print_vdev_stats(zhp, vname, oldnv ?
|
||||||
oldchild[c] : NULL, newchild[c], cb, depth + 2);
|
oldchild[c] : NULL, newchild[c], cb, depth + 2);
|
||||||
free(vname);
|
free(vname);
|
||||||
|
@ -5357,12 +5129,11 @@ get_stat_flags(zpool_list_t *list)
|
||||||
* Return 1 if cb_data->cb_vdev_names[0] is this vdev's name, 0 otherwise.
|
* Return 1 if cb_data->cb_vdev_names[0] is this vdev's name, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
is_vdev_cb(void *zhp_data, nvlist_t *nv, void *cb_data)
|
is_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, void *cb_data)
|
||||||
{
|
{
|
||||||
iostat_cbdata_t *cb = cb_data;
|
iostat_cbdata_t *cb = cb_data;
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
zpool_handle_t *zhp = zhp_data;
|
|
||||||
|
|
||||||
name = zpool_vdev_name(g_zfs, zhp, nv, cb->cb_name_flags);
|
name = zpool_vdev_name(g_zfs, zhp, nv, cb->cb_name_flags);
|
||||||
|
|
||||||
|
@ -5523,6 +5294,19 @@ get_interval_count_filter_guids(int *argc, char **argv, float *interval,
|
||||||
interval, count);
|
interval, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Floating point sleep(). Allows you to pass in a floating point value for
|
||||||
|
* seconds.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
fsleep(float sec)
|
||||||
|
{
|
||||||
|
struct timespec req;
|
||||||
|
req.tv_sec = floor(sec);
|
||||||
|
req.tv_nsec = (sec - (float)req.tv_sec) * NANOSEC;
|
||||||
|
nanosleep(&req, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Terminal height, in rows. Returns -1 if stdout is not connected to a TTY or
|
* Terminal height, in rows. Returns -1 if stdout is not connected to a TTY or
|
||||||
* if we were unable to determine its size.
|
* if we were unable to determine its size.
|
||||||
|
@ -5586,13 +5370,7 @@ print_zpool_dir_scripts(char *dirpath)
|
||||||
if ((dir = opendir(dirpath)) != NULL) {
|
if ((dir = opendir(dirpath)) != NULL) {
|
||||||
/* print all the files and directories within directory */
|
/* print all the files and directories within directory */
|
||||||
while ((ent = readdir(dir)) != NULL) {
|
while ((ent = readdir(dir)) != NULL) {
|
||||||
if (snprintf(fullpath, sizeof (fullpath), "%s/%s",
|
sprintf(fullpath, "%s/%s", dirpath, ent->d_name);
|
||||||
dirpath, ent->d_name) >= sizeof (fullpath)) {
|
|
||||||
(void) fprintf(stderr,
|
|
||||||
gettext("internal error: "
|
|
||||||
"ZPOOL_SCRIPTS_PATH too large.\n"));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print the scripts */
|
/* Print the scripts */
|
||||||
if (stat(fullpath, &dir_stat) == 0)
|
if (stat(fullpath, &dir_stat) == 0)
|
||||||
|
@ -5643,8 +5421,8 @@ get_namewidth_iostat(zpool_handle_t *zhp, void *data)
|
||||||
* get_namewidth() returns the maximum width of any name in that column
|
* get_namewidth() returns the maximum width of any name in that column
|
||||||
* for any pool/vdev/device line that will be output.
|
* for any pool/vdev/device line that will be output.
|
||||||
*/
|
*/
|
||||||
width = get_namewidth(zhp, cb->cb_namewidth,
|
width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags,
|
||||||
cb->cb_name_flags | VDEV_NAME_TYPE_ID, cb->cb_verbose);
|
cb->cb_verbose);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The width we are calculating is the width of the header and also the
|
* The width we are calculating is the width of the header and also the
|
||||||
|
@ -6220,7 +5998,6 @@ print_one_column(zpool_prop_t prop, uint64_t value, const char *str,
|
||||||
size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
|
size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
|
||||||
|
|
||||||
switch (prop) {
|
switch (prop) {
|
||||||
case ZPOOL_PROP_SIZE:
|
|
||||||
case ZPOOL_PROP_EXPANDSZ:
|
case ZPOOL_PROP_EXPANDSZ:
|
||||||
case ZPOOL_PROP_CHECKPOINT:
|
case ZPOOL_PROP_CHECKPOINT:
|
||||||
case ZPOOL_PROP_DEDUPRATIO:
|
case ZPOOL_PROP_DEDUPRATIO:
|
||||||
|
@ -6316,12 +6093,8 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
|
||||||
* 'toplevel' boolean value is passed to the print_one_column()
|
* 'toplevel' boolean value is passed to the print_one_column()
|
||||||
* to indicate that the value is valid.
|
* to indicate that the value is valid.
|
||||||
*/
|
*/
|
||||||
if (vs->vs_pspace)
|
print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, NULL, scripted,
|
||||||
print_one_column(ZPOOL_PROP_SIZE, vs->vs_pspace, NULL,
|
toplevel, format);
|
||||||
scripted, B_TRUE, format);
|
|
||||||
else
|
|
||||||
print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, NULL,
|
|
||||||
scripted, toplevel, format);
|
|
||||||
print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, NULL,
|
print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, NULL,
|
||||||
scripted, toplevel, format);
|
scripted, toplevel, format);
|
||||||
print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
|
print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
|
||||||
|
@ -6372,7 +6145,7 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vname = zpool_vdev_name(g_zfs, zhp, child[c],
|
vname = zpool_vdev_name(g_zfs, zhp, child[c],
|
||||||
cb->cb_name_flags | VDEV_NAME_TYPE_ID);
|
cb->cb_name_flags);
|
||||||
print_list_stats(zhp, vname, child[c], cb, depth + 2, B_FALSE);
|
print_list_stats(zhp, vname, child[c], cb, depth + 2, B_FALSE);
|
||||||
free(vname);
|
free(vname);
|
||||||
}
|
}
|
||||||
|
@ -6406,7 +6179,7 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
|
||||||
printed = B_TRUE;
|
printed = B_TRUE;
|
||||||
}
|
}
|
||||||
vname = zpool_vdev_name(g_zfs, zhp, child[c],
|
vname = zpool_vdev_name(g_zfs, zhp, child[c],
|
||||||
cb->cb_name_flags | VDEV_NAME_TYPE_ID);
|
cb->cb_name_flags);
|
||||||
print_list_stats(zhp, vname, child[c], cb, depth + 2,
|
print_list_stats(zhp, vname, child[c], cb, depth + 2,
|
||||||
B_FALSE);
|
B_FALSE);
|
||||||
free(vname);
|
free(vname);
|
||||||
|
@ -6472,8 +6245,8 @@ get_namewidth_list(zpool_handle_t *zhp, void *data)
|
||||||
list_cbdata_t *cb = data;
|
list_cbdata_t *cb = data;
|
||||||
int width;
|
int width;
|
||||||
|
|
||||||
width = get_namewidth(zhp, cb->cb_namewidth,
|
width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags,
|
||||||
cb->cb_name_flags | VDEV_NAME_TYPE_ID, cb->cb_verbose);
|
cb->cb_verbose);
|
||||||
|
|
||||||
if (width < 9)
|
if (width < 9)
|
||||||
width = 9;
|
width = 9;
|
||||||
|
@ -7011,12 +6784,10 @@ zpool_do_split(int argc, char **argv)
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define POWER_OPT 1024
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zpool online [--power] <pool> <device> ...
|
* zpool online <pool> <device> ...
|
||||||
*
|
|
||||||
* --power: Power on the enclosure slot to the drive (if possible)
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zpool_do_online(int argc, char **argv)
|
zpool_do_online(int argc, char **argv)
|
||||||
|
@ -7027,21 +6798,13 @@ zpool_do_online(int argc, char **argv)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
vdev_state_t newstate;
|
vdev_state_t newstate;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
boolean_t is_power_on = B_FALSE;
|
|
||||||
struct option long_options[] = {
|
|
||||||
{"power", no_argument, NULL, POWER_OPT},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt_long(argc, argv, "e", long_options, NULL)) != -1) {
|
while ((c = getopt(argc, argv, "e")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'e':
|
case 'e':
|
||||||
flags |= ZFS_ONLINE_EXPAND;
|
flags |= ZFS_ONLINE_EXPAND;
|
||||||
break;
|
break;
|
||||||
case POWER_OPT:
|
|
||||||
is_power_on = B_TRUE;
|
|
||||||
break;
|
|
||||||
case '?':
|
case '?':
|
||||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||||
optopt);
|
optopt);
|
||||||
|
@ -7049,9 +6812,6 @@ zpool_do_online(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libzfs_envvar_is_set("ZPOOL_AUTO_POWER_ON_SLOT"))
|
|
||||||
is_power_on = B_TRUE;
|
|
||||||
|
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
|
@ -7071,29 +6831,6 @@ zpool_do_online(int argc, char **argv)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
vdev_state_t oldstate;
|
|
||||||
boolean_t avail_spare, l2cache;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (is_power_on) {
|
|
||||||
rc = zpool_power_on_and_disk_wait(zhp, argv[i]);
|
|
||||||
if (rc == ENOTSUP) {
|
|
||||||
(void) fprintf(stderr,
|
|
||||||
gettext("Power control not supported\n"));
|
|
||||||
}
|
|
||||||
if (rc != 0)
|
|
||||||
return (rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
nvlist_t *tgt = zpool_find_vdev(zhp, argv[i], &avail_spare,
|
|
||||||
&l2cache, NULL);
|
|
||||||
if (tgt == NULL) {
|
|
||||||
ret = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
uint_t vsc;
|
|
||||||
oldstate = ((vdev_stat_t *)fnvlist_lookup_uint64_array(tgt,
|
|
||||||
ZPOOL_CONFIG_VDEV_STATS, &vsc))->vs_state;
|
|
||||||
if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
|
if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
|
||||||
if (newstate != VDEV_STATE_HEALTHY) {
|
if (newstate != VDEV_STATE_HEALTHY) {
|
||||||
(void) printf(gettext("warning: device '%s' "
|
(void) printf(gettext("warning: device '%s' "
|
||||||
|
@ -7107,17 +6844,6 @@ zpool_do_online(int argc, char **argv)
|
||||||
(void) printf(gettext("use 'zpool "
|
(void) printf(gettext("use 'zpool "
|
||||||
"replace' to replace devices "
|
"replace' to replace devices "
|
||||||
"that are no longer present\n"));
|
"that are no longer present\n"));
|
||||||
if ((flags & ZFS_ONLINE_EXPAND)) {
|
|
||||||
(void) printf(gettext("%s: failed "
|
|
||||||
"to expand usable space on "
|
|
||||||
"unhealthy device '%s'\n"),
|
|
||||||
(oldstate >= VDEV_STATE_DEGRADED ?
|
|
||||||
"error" : "warning"), argv[i]);
|
|
||||||
if (oldstate >= VDEV_STATE_DEGRADED) {
|
|
||||||
ret = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
@ -7130,15 +6856,12 @@ zpool_do_online(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zpool offline [-ft]|[--power] <pool> <device> ...
|
* zpool offline [-ft] <pool> <device> ...
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* -f Force the device into a faulted state.
|
* -f Force the device into a faulted state.
|
||||||
*
|
*
|
||||||
* -t Only take the device off-line temporarily. The offline/faulted
|
* -t Only take the device off-line temporarily. The offline/faulted
|
||||||
* state will not be persistent across reboots.
|
* state will not be persistent across reboots.
|
||||||
*
|
|
||||||
* --power Power off the enclosure slot to the drive (if possible)
|
|
||||||
*/
|
*/
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
int
|
int
|
||||||
|
@ -7150,15 +6873,9 @@ zpool_do_offline(int argc, char **argv)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
boolean_t istmp = B_FALSE;
|
boolean_t istmp = B_FALSE;
|
||||||
boolean_t fault = B_FALSE;
|
boolean_t fault = B_FALSE;
|
||||||
boolean_t is_power_off = B_FALSE;
|
|
||||||
|
|
||||||
struct option long_options[] = {
|
|
||||||
{"power", no_argument, NULL, POWER_OPT},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt_long(argc, argv, "ft", long_options, NULL)) != -1) {
|
while ((c = getopt(argc, argv, "ft")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'f':
|
case 'f':
|
||||||
fault = B_TRUE;
|
fault = B_TRUE;
|
||||||
|
@ -7166,9 +6883,6 @@ zpool_do_offline(int argc, char **argv)
|
||||||
case 't':
|
case 't':
|
||||||
istmp = B_TRUE;
|
istmp = B_TRUE;
|
||||||
break;
|
break;
|
||||||
case POWER_OPT:
|
|
||||||
is_power_off = B_TRUE;
|
|
||||||
break;
|
|
||||||
case '?':
|
case '?':
|
||||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||||
optopt);
|
optopt);
|
||||||
|
@ -7176,20 +6890,6 @@ zpool_do_offline(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_power_off && fault) {
|
|
||||||
(void) fprintf(stderr,
|
|
||||||
gettext("-0 and -f cannot be used together\n"));
|
|
||||||
usage(B_FALSE);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_power_off && istmp) {
|
|
||||||
(void) fprintf(stderr,
|
|
||||||
gettext("-0 and -t cannot be used together\n"));
|
|
||||||
usage(B_FALSE);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
|
@ -7209,22 +6909,8 @@ zpool_do_offline(int argc, char **argv)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
|
if (fault) {
|
||||||
uint64_t guid = zpool_vdev_path_to_guid(zhp, argv[i]);
|
uint64_t guid = zpool_vdev_path_to_guid(zhp, argv[i]);
|
||||||
if (is_power_off) {
|
|
||||||
/*
|
|
||||||
* Note: we have to power off first, then set REMOVED,
|
|
||||||
* or else zpool_vdev_set_removed_state() returns
|
|
||||||
* EAGAIN.
|
|
||||||
*/
|
|
||||||
ret = zpool_power_off(zhp, argv[i]);
|
|
||||||
if (ret != 0) {
|
|
||||||
(void) fprintf(stderr, "%s %s %d\n",
|
|
||||||
gettext("unable to power off slot for"),
|
|
||||||
argv[i], ret);
|
|
||||||
}
|
|
||||||
zpool_vdev_set_removed_state(zhp, guid, VDEV_AUX_NONE);
|
|
||||||
|
|
||||||
} else if (fault) {
|
|
||||||
vdev_aux_t aux;
|
vdev_aux_t aux;
|
||||||
if (istmp == B_FALSE) {
|
if (istmp == B_FALSE) {
|
||||||
/* Force the fault to persist across imports */
|
/* Force the fault to persist across imports */
|
||||||
|
@ -7247,7 +6933,7 @@ zpool_do_offline(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zpool clear [-nF]|[--power] <pool> [device]
|
* zpool clear <pool> [device]
|
||||||
*
|
*
|
||||||
* Clear all errors associated with a pool or a particular device.
|
* Clear all errors associated with a pool or a particular device.
|
||||||
*/
|
*/
|
||||||
|
@ -7259,20 +6945,13 @@ zpool_do_clear(int argc, char **argv)
|
||||||
boolean_t dryrun = B_FALSE;
|
boolean_t dryrun = B_FALSE;
|
||||||
boolean_t do_rewind = B_FALSE;
|
boolean_t do_rewind = B_FALSE;
|
||||||
boolean_t xtreme_rewind = B_FALSE;
|
boolean_t xtreme_rewind = B_FALSE;
|
||||||
boolean_t is_power_on = B_FALSE;
|
|
||||||
uint32_t rewind_policy = ZPOOL_NO_REWIND;
|
uint32_t rewind_policy = ZPOOL_NO_REWIND;
|
||||||
nvlist_t *policy = NULL;
|
nvlist_t *policy = NULL;
|
||||||
zpool_handle_t *zhp;
|
zpool_handle_t *zhp;
|
||||||
char *pool, *device;
|
char *pool, *device;
|
||||||
|
|
||||||
struct option long_options[] = {
|
|
||||||
{"power", no_argument, NULL, POWER_OPT},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt_long(argc, argv, "FnX", long_options,
|
while ((c = getopt(argc, argv, "FnX")) != -1) {
|
||||||
NULL)) != -1) {
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'F':
|
case 'F':
|
||||||
do_rewind = B_TRUE;
|
do_rewind = B_TRUE;
|
||||||
|
@ -7283,9 +6962,6 @@ zpool_do_clear(int argc, char **argv)
|
||||||
case 'X':
|
case 'X':
|
||||||
xtreme_rewind = B_TRUE;
|
xtreme_rewind = B_TRUE;
|
||||||
break;
|
break;
|
||||||
case POWER_OPT:
|
|
||||||
is_power_on = B_TRUE;
|
|
||||||
break;
|
|
||||||
case '?':
|
case '?':
|
||||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||||
optopt);
|
optopt);
|
||||||
|
@ -7293,9 +6969,6 @@ zpool_do_clear(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libzfs_envvar_is_set("ZPOOL_AUTO_POWER_ON_SLOT"))
|
|
||||||
is_power_on = B_TRUE;
|
|
||||||
|
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
|
@ -7336,14 +7009,6 @@ zpool_do_clear(int argc, char **argv)
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_power_on) {
|
|
||||||
if (device == NULL) {
|
|
||||||
zpool_power_on_pool_and_wait_for_devices(zhp);
|
|
||||||
} else {
|
|
||||||
zpool_power_on_and_disk_wait(zhp, device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zpool_clear(zhp, device, policy) != 0)
|
if (zpool_clear(zhp, device, policy) != 0)
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
|
@ -7794,20 +7459,19 @@ print_scan_scrub_resilver_status(pool_scan_stat_t *ps)
|
||||||
|
|
||||||
zfs_nicebytes(ps->pss_processed, processed_buf, sizeof (processed_buf));
|
zfs_nicebytes(ps->pss_processed, processed_buf, sizeof (processed_buf));
|
||||||
|
|
||||||
int is_resilver = ps->pss_func == POOL_SCAN_RESILVER;
|
assert(ps->pss_func == POOL_SCAN_SCRUB ||
|
||||||
int is_scrub = ps->pss_func == POOL_SCAN_SCRUB;
|
ps->pss_func == POOL_SCAN_RESILVER);
|
||||||
assert(is_resilver || is_scrub);
|
|
||||||
|
|
||||||
/* Scan is finished or canceled. */
|
/* Scan is finished or canceled. */
|
||||||
if (ps->pss_state == DSS_FINISHED) {
|
if (ps->pss_state == DSS_FINISHED) {
|
||||||
secs_to_dhms(end - start, time_buf);
|
secs_to_dhms(end - start, time_buf);
|
||||||
|
|
||||||
if (is_scrub) {
|
if (ps->pss_func == POOL_SCAN_SCRUB) {
|
||||||
(void) printf(gettext("scrub repaired %s "
|
(void) printf(gettext("scrub repaired %s "
|
||||||
"in %s with %llu errors on %s"), processed_buf,
|
"in %s with %llu errors on %s"), processed_buf,
|
||||||
time_buf, (u_longlong_t)ps->pss_errors,
|
time_buf, (u_longlong_t)ps->pss_errors,
|
||||||
ctime(&end));
|
ctime(&end));
|
||||||
} else if (is_resilver) {
|
} else if (ps->pss_func == POOL_SCAN_RESILVER) {
|
||||||
(void) printf(gettext("resilvered %s "
|
(void) printf(gettext("resilvered %s "
|
||||||
"in %s with %llu errors on %s"), processed_buf,
|
"in %s with %llu errors on %s"), processed_buf,
|
||||||
time_buf, (u_longlong_t)ps->pss_errors,
|
time_buf, (u_longlong_t)ps->pss_errors,
|
||||||
|
@ -7815,10 +7479,10 @@ print_scan_scrub_resilver_status(pool_scan_stat_t *ps)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (ps->pss_state == DSS_CANCELED) {
|
} else if (ps->pss_state == DSS_CANCELED) {
|
||||||
if (is_scrub) {
|
if (ps->pss_func == POOL_SCAN_SCRUB) {
|
||||||
(void) printf(gettext("scrub canceled on %s"),
|
(void) printf(gettext("scrub canceled on %s"),
|
||||||
ctime(&end));
|
ctime(&end));
|
||||||
} else if (is_resilver) {
|
} else if (ps->pss_func == POOL_SCAN_RESILVER) {
|
||||||
(void) printf(gettext("resilver canceled on %s"),
|
(void) printf(gettext("resilver canceled on %s"),
|
||||||
ctime(&end));
|
ctime(&end));
|
||||||
}
|
}
|
||||||
|
@ -7828,7 +7492,7 @@ print_scan_scrub_resilver_status(pool_scan_stat_t *ps)
|
||||||
assert(ps->pss_state == DSS_SCANNING);
|
assert(ps->pss_state == DSS_SCANNING);
|
||||||
|
|
||||||
/* Scan is in progress. Resilvers can't be paused. */
|
/* Scan is in progress. Resilvers can't be paused. */
|
||||||
if (is_scrub) {
|
if (ps->pss_func == POOL_SCAN_SCRUB) {
|
||||||
if (pause == 0) {
|
if (pause == 0) {
|
||||||
(void) printf(gettext("scrub in progress since %s"),
|
(void) printf(gettext("scrub in progress since %s"),
|
||||||
ctime(&start));
|
ctime(&start));
|
||||||
|
@ -7838,7 +7502,7 @@ print_scan_scrub_resilver_status(pool_scan_stat_t *ps)
|
||||||
(void) printf(gettext("\tscrub started on %s"),
|
(void) printf(gettext("\tscrub started on %s"),
|
||||||
ctime(&start));
|
ctime(&start));
|
||||||
}
|
}
|
||||||
} else if (is_resilver) {
|
} else if (ps->pss_func == POOL_SCAN_RESILVER) {
|
||||||
(void) printf(gettext("resilver in progress since %s"),
|
(void) printf(gettext("resilver in progress since %s"),
|
||||||
ctime(&start));
|
ctime(&start));
|
||||||
}
|
}
|
||||||
|
@ -7880,27 +7544,17 @@ print_scan_scrub_resilver_status(pool_scan_stat_t *ps)
|
||||||
scanned_buf, issued_buf, total_buf);
|
scanned_buf, issued_buf, total_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_resilver) {
|
if (ps->pss_func == POOL_SCAN_RESILVER) {
|
||||||
(void) printf(gettext("\t%s resilvered, %.2f%% done"),
|
(void) printf(gettext("\t%s resilvered, %.2f%% done"),
|
||||||
processed_buf, 100 * fraction_done);
|
processed_buf, 100 * fraction_done);
|
||||||
} else if (is_scrub) {
|
} else if (ps->pss_func == POOL_SCAN_SCRUB) {
|
||||||
(void) printf(gettext("\t%s repaired, %.2f%% done"),
|
(void) printf(gettext("\t%s repaired, %.2f%% done"),
|
||||||
processed_buf, 100 * fraction_done);
|
processed_buf, 100 * fraction_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pause == 0) {
|
if (pause == 0) {
|
||||||
/*
|
|
||||||
* Only provide an estimate iff:
|
|
||||||
* 1) the time remaining is valid, and
|
|
||||||
* 2) the issue rate exceeds 10 MB/s, and
|
|
||||||
* 3) it's either:
|
|
||||||
* a) a resilver which has started repairs, or
|
|
||||||
* b) a scrub which has entered the issue phase.
|
|
||||||
*/
|
|
||||||
if (total_secs_left != UINT64_MAX &&
|
if (total_secs_left != UINT64_MAX &&
|
||||||
issue_rate >= 10 * 1024 * 1024 &&
|
issue_rate >= 10 * 1024 * 1024) {
|
||||||
((is_resilver && ps->pss_processed > 0) ||
|
|
||||||
(is_scrub && issued > 0))) {
|
|
||||||
(void) printf(gettext(", %s to go\n"), time_buf);
|
(void) printf(gettext(", %s to go\n"), time_buf);
|
||||||
} else {
|
} else {
|
||||||
(void) printf(gettext(", no estimated "
|
(void) printf(gettext(", no estimated "
|
||||||
|
@ -8852,10 +8506,6 @@ status_callback(zpool_handle_t *zhp, void *data)
|
||||||
printf_color(ANSI_BOLD, " %5s", gettext("SLOW"));
|
printf_color(ANSI_BOLD, " %5s", gettext("SLOW"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cbp->cb_print_power) {
|
|
||||||
printf_color(ANSI_BOLD, " %5s", gettext("POWER"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cbp->vcdl != NULL)
|
if (cbp->vcdl != NULL)
|
||||||
print_cmd_columns(cbp->vcdl, 0);
|
print_cmd_columns(cbp->vcdl, 0);
|
||||||
|
|
||||||
|
@ -8903,13 +8553,11 @@ status_callback(zpool_handle_t *zhp, void *data)
|
||||||
if (nerr == 0)
|
if (nerr == 0)
|
||||||
(void) printf(gettext("errors: No known data "
|
(void) printf(gettext("errors: No known data "
|
||||||
"errors\n"));
|
"errors\n"));
|
||||||
else if (!cbp->cb_verbose) {
|
else if (!cbp->cb_verbose)
|
||||||
color_start(ANSI_RED);
|
|
||||||
(void) printf(gettext("errors: %llu data "
|
(void) printf(gettext("errors: %llu data "
|
||||||
"errors, use '-v' for a list\n"),
|
"errors, use '-v' for a list\n"),
|
||||||
(u_longlong_t)nerr);
|
(u_longlong_t)nerr);
|
||||||
color_end();
|
else
|
||||||
} else
|
|
||||||
print_error_log(zhp);
|
print_error_log(zhp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8924,11 +8572,10 @@ status_callback(zpool_handle_t *zhp, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zpool status [-c [script1,script2,...]] [-igLpPstvx] [--power] [-T d|u] ...
|
* zpool status [-c [script1,script2,...]] [-igLpPstvx] [-T d|u] [pool] ...
|
||||||
* [pool] [interval [count]]
|
* [interval [count]]
|
||||||
*
|
*
|
||||||
* -c CMD For each vdev, run command CMD
|
* -c CMD For each vdev, run command CMD
|
||||||
* -e Display only unhealthy vdevs
|
|
||||||
* -i Display vdev initialization status.
|
* -i Display vdev initialization status.
|
||||||
* -g Display guid for individual vdev name.
|
* -g Display guid for individual vdev name.
|
||||||
* -L Follow links when resolving vdev path name.
|
* -L Follow links when resolving vdev path name.
|
||||||
|
@ -8940,7 +8587,6 @@ status_callback(zpool_handle_t *zhp, void *data)
|
||||||
* -D Display dedup status (undocumented)
|
* -D Display dedup status (undocumented)
|
||||||
* -t Display vdev TRIM status.
|
* -t Display vdev TRIM status.
|
||||||
* -T Display a timestamp in date(1) or Unix format
|
* -T Display a timestamp in date(1) or Unix format
|
||||||
* --power Display vdev enclosure slot power status
|
|
||||||
*
|
*
|
||||||
* Describes the health status of all pools or some subset.
|
* Describes the health status of all pools or some subset.
|
||||||
*/
|
*/
|
||||||
|
@ -8954,14 +8600,8 @@ zpool_do_status(int argc, char **argv)
|
||||||
status_cbdata_t cb = { 0 };
|
status_cbdata_t cb = { 0 };
|
||||||
char *cmd = NULL;
|
char *cmd = NULL;
|
||||||
|
|
||||||
struct option long_options[] = {
|
|
||||||
{"power", no_argument, NULL, POWER_OPT},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt_long(argc, argv, "c:eigLpPsvxDtT:", long_options,
|
while ((c = getopt(argc, argv, "c:igLpPsvxDtT:")) != -1) {
|
||||||
NULL)) != -1) {
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
if (cmd != NULL) {
|
if (cmd != NULL) {
|
||||||
|
@ -8987,9 +8627,6 @@ zpool_do_status(int argc, char **argv)
|
||||||
}
|
}
|
||||||
cmd = optarg;
|
cmd = optarg;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
|
||||||
cb.cb_print_unhealthy = B_TRUE;
|
|
||||||
break;
|
|
||||||
case 'i':
|
case 'i':
|
||||||
cb.cb_print_vdev_init = B_TRUE;
|
cb.cb_print_vdev_init = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -9023,9 +8660,6 @@ zpool_do_status(int argc, char **argv)
|
||||||
case 'T':
|
case 'T':
|
||||||
get_timestamp_arg(*optarg);
|
get_timestamp_arg(*optarg);
|
||||||
break;
|
break;
|
||||||
case POWER_OPT:
|
|
||||||
cb.cb_print_power = B_TRUE;
|
|
||||||
break;
|
|
||||||
case '?':
|
case '?':
|
||||||
if (optopt == 'c') {
|
if (optopt == 'c') {
|
||||||
print_zpool_script_list("status");
|
print_zpool_script_list("status");
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#include <libnvpair.h>
|
#include <libnvpair.h>
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
#include <libzutil.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -68,6 +67,7 @@ int for_each_pool(int, char **, boolean_t unavail, zprop_list_t **,
|
||||||
boolean_t, zpool_iter_f, void *);
|
boolean_t, zpool_iter_f, void *);
|
||||||
|
|
||||||
/* Vdev list functions */
|
/* 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);
|
int for_each_vdev(zpool_handle_t *zhp, pool_vdev_iter_f func, void *data);
|
||||||
|
|
||||||
typedef struct zpool_list zpool_list_t;
|
typedef struct zpool_list zpool_list_t;
|
||||||
|
@ -124,10 +124,6 @@ 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_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,
|
int check_device(const char *path, boolean_t force,
|
||||||
boolean_t isspare, boolean_t iswholedisk);
|
boolean_t isspare, boolean_t iswholedisk);
|
||||||
boolean_t check_sector_size_database(char *path, int *sector_size);
|
boolean_t check_sector_size_database(char *path, int *sector_size);
|
||||||
|
@ -135,9 +131,6 @@ void vdev_error(const char *fmt, ...);
|
||||||
int check_file(const char *file, boolean_t force, boolean_t isspare);
|
int check_file(const char *file, boolean_t force, boolean_t isspare);
|
||||||
void after_zpool_upgrade(zpool_handle_t *zhp);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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_PATH, path) == 0);
|
||||||
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 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)
|
if (strcmp(type, VDEV_TYPE_DISK) == 0)
|
||||||
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
|
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
|
||||||
(uint64_t)wholedisk) == 0);
|
(uint64_t)wholedisk) == 0);
|
||||||
|
@ -925,15 +921,6 @@ zero_label(char *path)
|
||||||
return (0);
|
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
|
* 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
|
* 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.
|
* need to get the devid after we label the disk.
|
||||||
*/
|
*/
|
||||||
static int
|
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;
|
nvlist_t **child;
|
||||||
uint_t c, children;
|
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)) {
|
if (!is_exclusive && !is_spare(NULL, udevpath)) {
|
||||||
char *devnode = strrchr(devpath, '/') + 1;
|
char *devnode = strrchr(devpath, '/') + 1;
|
||||||
char **lines = NULL;
|
|
||||||
int lines_cnt = 0;
|
|
||||||
|
|
||||||
ret = strncmp(udevpath, UDISK_ROOT, strlen(UDISK_ROOT));
|
ret = strncmp(udevpath, UDISK_ROOT, strlen(UDISK_ROOT));
|
||||||
if (ret == 0) {
|
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
|
* When labeling a pool the raw device node name
|
||||||
* is provided as it appears under /dev/.
|
* 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,
|
if (zpool_label_disk(g_zfs, zhp, devnode) == -1)
|
||||||
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);
|
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
|
||||||
libzfs_free_str_array(lines, lines_cnt);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait for udev to signal the device is available
|
* 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++)
|
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 (ret);
|
||||||
|
|
||||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
|
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
|
||||||
&child, &children) == 0)
|
&child, &children) == 0)
|
||||||
for (c = 0; c < children; c++)
|
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 (ret);
|
||||||
|
|
||||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
|
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
|
||||||
&child, &children) == 0)
|
&child, &children) == 0)
|
||||||
for (c = 0; c < children; c++)
|
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 (ret);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -1773,7 +1740,7 @@ split_mirror_vdev(zpool_handle_t *zhp, char *newname, nvlist_t *props,
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!flags.dryrun && make_disks(zhp, newroot, B_FALSE) != 0) {
|
if (!flags.dryrun && make_disks(zhp, newroot) != 0) {
|
||||||
nvlist_free(newroot);
|
nvlist_free(newroot);
|
||||||
return (NULL);
|
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.
|
* 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);
|
nvlist_free(newroot);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,6 @@ escape_string(char *s)
|
||||||
case '=':
|
case '=':
|
||||||
case '\\':
|
case '\\':
|
||||||
*d++ = '\\';
|
*d++ = '\\';
|
||||||
fallthrough;
|
|
||||||
default:
|
default:
|
||||||
*d = *c;
|
*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,
|
if (descend && nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
|
||||||
&child, &children) == 0) {
|
&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));
|
sizeof (vdev_name));
|
||||||
|
vdev_name[sizeof (vdev_name) - 1] = '\0';
|
||||||
|
|
||||||
for (c = 0; c < children; c++) {
|
for (c = 0; c < children; c++) {
|
||||||
print_recursive_stats(func, child[c], pool_name,
|
print_recursive_stats(func, child[c], pool_name,
|
||||||
|
|
|
@ -297,7 +297,6 @@ zstream_do_dump(int argc, char *argv[])
|
||||||
|
|
||||||
fletcher_4_init();
|
fletcher_4_init();
|
||||||
while (read_hdr(drr, &zc)) {
|
while (read_hdr(drr, &zc)) {
|
||||||
uint64_t featureflags = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is the first DMU record being processed, check for
|
* 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);
|
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);
|
payload_size = DRR_OBJECT_PAYLOAD_SIZE(drro);
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
|
|
@ -1184,7 +1184,7 @@ ztest_kill(ztest_shared_t *zs)
|
||||||
* See comment above spa_write_cachefile().
|
* See comment above spa_write_cachefile().
|
||||||
*/
|
*/
|
||||||
mutex_enter(&spa_namespace_lock);
|
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);
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
|
||||||
(void) kill(getpid(), SIGKILL);
|
(void) kill(getpid(), SIGKILL);
|
||||||
|
@ -2193,7 +2193,6 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap)
|
||||||
* but not always, because we also want to verify correct
|
* but not always, because we also want to verify correct
|
||||||
* behavior when the data was not recently read into cache.
|
* behavior when the data was not recently read into cache.
|
||||||
*/
|
*/
|
||||||
ASSERT(doi.doi_data_block_size);
|
|
||||||
ASSERT0(offset % doi.doi_data_block_size);
|
ASSERT0(offset % doi.doi_data_block_size);
|
||||||
if (ztest_random(4) != 0) {
|
if (ztest_random(4) != 0) {
|
||||||
int prefetch = ztest_random(2) ?
|
int prefetch = ztest_random(2) ?
|
||||||
|
|
|
@ -38,39 +38,40 @@
|
||||||
static int
|
static int
|
||||||
ioctl_get_msg(char *var, int fd)
|
ioctl_get_msg(char *var, int fd)
|
||||||
{
|
{
|
||||||
int ret;
|
int error = 0;
|
||||||
char msg[ZFS_MAX_DATASET_NAME_LEN];
|
char msg[ZFS_MAX_DATASET_NAME_LEN];
|
||||||
|
|
||||||
ret = ioctl(fd, BLKZNAME, msg);
|
error = ioctl(fd, BLKZNAME, msg);
|
||||||
if (ret < 0) {
|
if (error < 0) {
|
||||||
return (ret);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(var, ZFS_MAX_DATASET_NAME_LEN, "%s", msg);
|
snprintf(var, ZFS_MAX_DATASET_NAME_LEN, "%s", msg);
|
||||||
return (ret);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
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[ZFS_MAX_DATASET_NAME_LEN];
|
||||||
char *zvol_name_part = NULL;
|
char *zvol_name_part = NULL;
|
||||||
char *dev_name;
|
char *dev_name;
|
||||||
struct stat64 statbuf;
|
struct stat64 statbuf;
|
||||||
int dev_minor, dev_part;
|
int dev_minor, dev_part;
|
||||||
int i;
|
int i;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
fprintf(stderr, "Usage: %s /dev/zvol_device_node\n", argv[0]);
|
printf("Usage: %s /dev/zvol_device_node\n", argv[0]);
|
||||||
goto fail;
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_name = argv[1];
|
dev_name = argv[1];
|
||||||
ret = stat64(dev_name, &statbuf);
|
error = stat64(dev_name, &statbuf);
|
||||||
if (ret != 0) {
|
if (error != 0) {
|
||||||
fprintf(stderr, "Unable to access device file: %s\n", dev_name);
|
printf("Unable to access device file: %s\n", dev_name);
|
||||||
goto fail;
|
return (errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_minor = minor(statbuf.st_rdev);
|
dev_minor = minor(statbuf.st_rdev);
|
||||||
|
@ -78,23 +79,23 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
fd = open(dev_name, O_RDONLY);
|
fd = open(dev_name, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
fprintf(stderr, "Unable to open device file: %s\n", dev_name);
|
printf("Unable to open device file: %s\n", dev_name);
|
||||||
goto fail;
|
return (errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ioctl_get_msg(zvol_name, fd);
|
error = ioctl_get_msg(zvol_name, fd);
|
||||||
if (ret < 0) {
|
if (error < 0) {
|
||||||
fprintf(stderr, "ioctl_get_msg failed: %s\n", strerror(errno));
|
printf("ioctl_get_msg failed:%s\n", strerror(errno));
|
||||||
goto fail;
|
return (errno);
|
||||||
}
|
}
|
||||||
if (dev_part > 0)
|
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);
|
dev_part);
|
||||||
else
|
else
|
||||||
ret = asprintf(&zvol_name_part, "%s", zvol_name);
|
rc = asprintf(&zvol_name_part, "%s", zvol_name);
|
||||||
|
|
||||||
if (ret == -1 || zvol_name_part == NULL)
|
if (rc == -1 || zvol_name_part == NULL)
|
||||||
goto fail;
|
goto error;
|
||||||
|
|
||||||
for (i = 0; i < strlen(zvol_name_part); i++) {
|
for (i = 0; i < strlen(zvol_name_part); i++) {
|
||||||
if (isblank(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);
|
printf("%s\n", zvol_name_part);
|
||||||
status = EXIT_SUCCESS;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
if (zvol_name_part)
|
|
||||||
free(zvol_name_part);
|
free(zvol_name_part);
|
||||||
if (fd >= 0)
|
error:
|
||||||
close(fd);
|
close(fd);
|
||||||
|
return (error);
|
||||||
return (status);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,17 +28,15 @@ filter_out_deleted_zvols() {
|
||||||
list_zvols() {
|
list_zvols() {
|
||||||
read -r default_volmode < /sys/module/zfs/parameters/zvol_volmode
|
read -r default_volmode < /sys/module/zfs/parameters/zvol_volmode
|
||||||
zfs list -t volume -H -o \
|
zfs list -t volume -H -o \
|
||||||
name,volmode,receive_resume_token,redact_snaps,keystatus |
|
name,volmode,receive_resume_token,redact_snaps |
|
||||||
while IFS=" " read -r name volmode token redacted keystatus; do # IFS=\t here!
|
while IFS=" " read -r name volmode token redacted; do # IFS=\t here!
|
||||||
|
|
||||||
# /dev links are not created for zvols with volmode = "none",
|
# /dev links are not created for zvols with volmode = "none"
|
||||||
# redacted zvols, or encrypted zvols for which the key has not
|
# or for redacted zvols.
|
||||||
# been loaded.
|
|
||||||
[ "$volmode" = "none" ] && continue
|
[ "$volmode" = "none" ] && continue
|
||||||
[ "$volmode" = "default" ] && [ "$default_volmode" = "3" ] &&
|
[ "$volmode" = "default" ] && [ "$default_volmode" = "3" ] &&
|
||||||
continue
|
continue
|
||||||
[ "$redacted" = "-" ] || continue
|
[ "$redacted" = "-" ] || continue
|
||||||
[ "$keystatus" = "unavailable" ] && continue
|
|
||||||
|
|
||||||
# We also ignore partially received zvols if it is
|
# We also ignore partially received zvols if it is
|
||||||
# not an incremental receive, as those won't even have a block
|
# not an incremental receive, as those won't even have a block
|
||||||
|
@ -109,13 +107,6 @@ while [ "$outer_loop" -lt 20 ]; do
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
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
|
done
|
||||||
|
|
||||||
echo "Timed out waiting on zvol links"
|
echo "Timed out waiting on zvol links"
|
||||||
|
|
|
@ -25,9 +25,5 @@ checkabi:
|
||||||
storeabi:
|
storeabi:
|
||||||
cd .libs ; \
|
cd .libs ; \
|
||||||
for lib in $(lib_LTLIBRARIES) ; do \
|
for lib in $(lib_LTLIBRARIES) ; do \
|
||||||
abidw --no-show-locs \
|
abidw $${lib%.la}.so > ../$${lib%.la}.abi ; \
|
||||||
--no-corpus-path \
|
|
||||||
--no-comp-dir-path \
|
|
||||||
--type-id-style hash \
|
|
||||||
$${lib%.la}.so > ../$${lib%.la}.abi ; \
|
|
||||||
done
|
done
|
||||||
|
|
|
@ -26,7 +26,6 @@ AM_LIBTOOLFLAGS = --silent
|
||||||
AM_CFLAGS = -std=gnu99 -Wall -Wstrict-prototypes -Wmissing-prototypes
|
AM_CFLAGS = -std=gnu99 -Wall -Wstrict-prototypes -Wmissing-prototypes
|
||||||
AM_CFLAGS += -fno-strict-aliasing
|
AM_CFLAGS += -fno-strict-aliasing
|
||||||
AM_CFLAGS += $(NO_OMIT_FRAME_POINTER)
|
AM_CFLAGS += $(NO_OMIT_FRAME_POINTER)
|
||||||
AM_CFLAGS += $(IMPLICIT_FALLTHROUGH)
|
|
||||||
AM_CFLAGS += $(DEBUG_CFLAGS)
|
AM_CFLAGS += $(DEBUG_CFLAGS)
|
||||||
AM_CFLAGS += $(ASAN_CFLAGS)
|
AM_CFLAGS += $(ASAN_CFLAGS)
|
||||||
AM_CFLAGS += $(CODE_COVERAGE_CFLAGS) $(NO_FORMAT_ZERO_LENGTH)
|
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_REENTRANT
|
||||||
AM_CPPFLAGS += -D_FILE_OFFSET_BITS=64
|
AM_CPPFLAGS += -D_FILE_OFFSET_BITS=64
|
||||||
AM_CPPFLAGS += -D_LARGEFILE64_SOURCE
|
AM_CPPFLAGS += -D_LARGEFILE64_SOURCE
|
||||||
|
AM_CPPFLAGS += -DHAVE_LARGE_STACKS=1
|
||||||
AM_CPPFLAGS += -DLIBEXECDIR=\"$(libexecdir)\"
|
AM_CPPFLAGS += -DLIBEXECDIR=\"$(libexecdir)\"
|
||||||
AM_CPPFLAGS += -DZFSEXECDIR=\"$(zfsexecdir)\"
|
|
||||||
AM_CPPFLAGS += -DRUNSTATEDIR=\"$(runstatedir)\"
|
AM_CPPFLAGS += -DRUNSTATEDIR=\"$(runstatedir)\"
|
||||||
AM_CPPFLAGS += -DSBINDIR=\"$(sbindir)\"
|
AM_CPPFLAGS += -DSBINDIR=\"$(sbindir)\"
|
||||||
AM_CPPFLAGS += -DSYSCONFDIR=\"$(sysconfdir)\"
|
AM_CPPFLAGS += -DSYSCONFDIR=\"$(sysconfdir)\"
|
||||||
|
|
|
@ -15,9 +15,7 @@ subst_sed_cmd = \
|
||||||
-e 's|@PYTHON[@]|$(PYTHON)|g' \
|
-e 's|@PYTHON[@]|$(PYTHON)|g' \
|
||||||
-e 's|@PYTHON_SHEBANG[@]|$(PYTHON_SHEBANG)|g' \
|
-e 's|@PYTHON_SHEBANG[@]|$(PYTHON_SHEBANG)|g' \
|
||||||
-e 's|@DEFAULT_INIT_NFS_SERVER[@]|$(DEFAULT_INIT_NFS_SERVER)|g' \
|
-e 's|@DEFAULT_INIT_NFS_SERVER[@]|$(DEFAULT_INIT_NFS_SERVER)|g' \
|
||||||
-e 's|@DEFAULT_INIT_SHELL[@]|$(DEFAULT_INIT_SHELL)|g' \
|
-e 's|@DEFAULT_INIT_SHELL[@]|$(DEFAULT_INIT_SHELL)|g'
|
||||||
-e 's|@LIBFETCH_DYNAMIC[@]|$(LIBFETCH_DYNAMIC)|g' \
|
|
||||||
-e 's|@LIBFETCH_SONAME[@]|$(LIBFETCH_SONAME)|g'
|
|
||||||
|
|
||||||
SUBSTFILES =
|
SUBSTFILES =
|
||||||
CLEANFILES = $(SUBSTFILES)
|
CLEANFILES = $(SUBSTFILES)
|
||||||
|
|
|
@ -88,7 +88,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_TRUNCATION], [
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Check if gcc supports -Wno-format-zero-length option.
|
dnl # Check if gcc supports -Wno-format-truncation option.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_ZERO_LENGTH], [
|
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_ZERO_LENGTH], [
|
||||||
AC_MSG_CHECKING([whether $CC supports -Wno-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])
|
AC_SUBST([NO_FORMAT_ZERO_LENGTH])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Check if gcc supports -Wno-clobbered option.
|
dnl # Check if gcc supports -Wno-bool-compare option.
|
||||||
dnl #
|
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 # and infer the 'no-' version does or doesn't exist based upon
|
||||||
dnl # the results. This is required because when checking any of
|
dnl # the results. This is required because when checking any of
|
||||||
dnl # no- prefixed options gcc always returns success.
|
dnl # no- prefixed options gcc always returns success.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_CLOBBERED], [
|
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_BOOL_COMPARE], [
|
||||||
AC_MSG_CHECKING([whether $CC supports -Wno-clobbered])
|
AC_MSG_CHECKING([whether $CC supports -Wno-bool-compare])
|
||||||
|
|
||||||
saved_flags="$CFLAGS"
|
saved_flags="$CFLAGS"
|
||||||
CFLAGS="$CFLAGS -Werror -Wclobbered"
|
CFLAGS="$CFLAGS -Werror -Wbool-compare"
|
||||||
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||||
NO_CLOBBERED=-Wno-clobbered
|
NO_BOOL_COMPARE=-Wno-bool-compare
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
], [
|
], [
|
||||||
NO_CLOBBERED=
|
NO_BOOL_COMPARE=
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
])
|
])
|
||||||
|
|
||||||
CFLAGS="$saved_flags"
|
CFLAGS="$saved_flags"
|
||||||
AC_SUBST([NO_CLOBBERED])
|
AC_SUBST([NO_BOOL_COMPARE])
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Check if gcc supports -Wimplicit-fallthrough option.
|
dnl # Check if gcc supports -Wno-unused-but-set-variable option.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_IMPLICIT_FALLTHROUGH], [
|
dnl # We actually invoke gcc with the -Wunused-but-set-variable option
|
||||||
AC_MSG_CHECKING([whether $CC supports -Wimplicit-fallthrough])
|
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"
|
saved_flags="$CFLAGS"
|
||||||
CFLAGS="$CFLAGS -Werror -Wimplicit-fallthrough"
|
CFLAGS="$CFLAGS -Werror -Wunused-but-set-variable"
|
||||||
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||||
IMPLICIT_FALLTHROUGH=-Wimplicit-fallthrough
|
NO_UNUSED_BUT_SET_VARIABLE=-Wno-unused-but-set-variable
|
||||||
AC_DEFINE([HAVE_IMPLICIT_FALLTHROUGH], 1,
|
|
||||||
[Define if compiler supports -Wimplicit-fallthrough])
|
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
], [
|
], [
|
||||||
IMPLICIT_FALLTHROUGH=
|
NO_UNUSED_BUT_SET_VARIABLE=
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
])
|
])
|
||||||
|
|
||||||
CFLAGS="$saved_flags"
|
CFLAGS="$saved_flags"
|
||||||
AC_SUBST([IMPLICIT_FALLTHROUGH])
|
AC_SUBST([NO_UNUSED_BUT_SET_VARIABLE])
|
||||||
])
|
|
||||||
|
|
||||||
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])
|
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
|
@ -277,34 +202,3 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_IPA_SRA], [
|
||||||
CFLAGS="$saved_flags"
|
CFLAGS="$saved_flags"
|
||||||
AC_SUBST([NO_IPA_SRA])
|
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 #
|
||||||
dnl # The majority of the python scripts are written to be compatible
|
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 # to provide a method to specify the default system version, and
|
||||||
dnl # set the PYTHON environment variable accordingly.
|
dnl # set the PYTHON environment variable accordingly.
|
||||||
dnl #
|
dnl #
|
||||||
|
@ -12,7 +13,9 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYTHON], [
|
||||||
[with_python=check])
|
[with_python=check])
|
||||||
|
|
||||||
AS_CASE([$with_python],
|
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}"],
|
[3*], [PYTHON="python${with_python}"],
|
||||||
[*python3*], [PYTHON="${with_python}"],
|
[*python3*], [PYTHON="${with_python}"],
|
||||||
[no], [PYTHON=":"],
|
[no], [PYTHON=":"],
|
||||||
|
@ -20,25 +23,35 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYTHON], [
|
||||||
)
|
)
|
||||||
|
|
||||||
dnl #
|
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 #
|
dnl #
|
||||||
AM_PATH_PYTHON([], [], [:])
|
AM_PATH_PYTHON([], [], [:])
|
||||||
AS_IF([test -z "$PYTHON_VERSION"], [
|
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#*\.}
|
PYTHON_MINOR=${PYTHON_VERSION#*\.}
|
||||||
|
|
||||||
AS_CASE([$PYTHON_VERSION],
|
AS_CASE([$PYTHON_VERSION],
|
||||||
[3.*], [
|
[2.*], [
|
||||||
AS_IF([test $PYTHON_MINOR -lt 6],
|
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], [],
|
[:|2|3], [],
|
||||||
[PYTHON_VERSION=3]
|
[PYTHON_VERSION=3]
|
||||||
)
|
)
|
||||||
|
|
||||||
AM_CONDITIONAL([USING_PYTHON], [test "$PYTHON" != :])
|
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 #
|
||||||
dnl # Request that packages be built for a specific Python version.
|
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 # Required by ZFS_AC_CONFIG_ALWAYS_PYZFS.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_PYTHON_MODULE], [
|
AC_DEFUN([ZFS_AC_PYTHON_MODULE], [
|
||||||
PYTHON_NAME=${PYTHON##*/}
|
PYTHON_NAME=$(basename $PYTHON)
|
||||||
AC_MSG_CHECKING([for $PYTHON_NAME module: $1])
|
AC_MSG_CHECKING([for $PYTHON_NAME module: $1])
|
||||||
AS_IF([$PYTHON -c "import $1" 2>/dev/null], [
|
AS_IF([$PYTHON -c "import $1" 2>/dev/null], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
@ -18,7 +18,7 @@ AC_DEFUN([ZFS_AC_PYTHON_MODULE], [
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
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 #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
||||||
AC_ARG_ENABLE([pyzfs],
|
AC_ARG_ENABLE([pyzfs],
|
||||||
|
@ -47,36 +47,12 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
||||||
AC_SUBST(DEFINE_PYZFS)
|
AC_SUBST(DEFINE_PYZFS)
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Autodetection disables pyzfs if kernel or srpm config
|
dnl # Require python-devel libraries
|
||||||
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 #
|
dnl #
|
||||||
AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [
|
AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [
|
||||||
AS_CASE([$PYTHON_VERSION],
|
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")]
|
[AC_MSG_ERROR("Python $PYTHON_VERSION unknown")]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ AC_DEFUN([AX_PYTHON_DEVEL],[
|
||||||
if test "$ac_supports_python_ver" != "True"; then
|
if test "$ac_supports_python_ver" != "True"; then
|
||||||
if test -z "$PYTHON_NOVERSIONCHECK"; then
|
if test -z "$PYTHON_NOVERSIONCHECK"; then
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
|
m4_ifvaln([$2],[$2],[
|
||||||
AC_MSG_FAILURE([
|
AC_MSG_FAILURE([
|
||||||
This version of the AC@&t@_PYTHON_DEVEL macro
|
This version of the AC@&t@_PYTHON_DEVEL macro
|
||||||
doesn't work properly with versions of Python before
|
doesn't work properly with versions of Python before
|
||||||
|
@ -111,6 +112,7 @@ variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG,
|
||||||
PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
|
PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
|
||||||
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
|
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
|
||||||
to something else than an empty string.
|
to something else than an empty string.
|
||||||
|
])
|
||||||
])
|
])
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT([skip at user request])
|
AC_MSG_RESULT([skip at user request])
|
||||||
|
@ -120,47 +122,25 @@ to something else than an empty string.
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#
|
#
|
||||||
# If the macro parameter ``version'' is set, honour it.
|
# 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 test -n "$1"; then
|
if test -n "$1"; then
|
||||||
AC_MSG_CHECKING([for a version of Python $1])
|
AC_MSG_CHECKING([for a version of Python $1])
|
||||||
cat << EOF > ax_python_devel_vpy.py
|
ac_supports_python_ver=`$PYTHON -c "import sys; \
|
||||||
class VPy:
|
ver = sys.version.split ()[[0]]; \
|
||||||
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(); \
|
|
||||||
print (ver $1)"`
|
print (ver $1)"`
|
||||||
rm -rf ax_python_devel_vpy*.py* __pycache__/ax_python_devel_vpy*.py*
|
|
||||||
if test "$ac_supports_python_ver" = "True"; then
|
if test "$ac_supports_python_ver" = "True"; then
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
|
m4_ifvaln([$2],[$2],[
|
||||||
AC_MSG_ERROR([this package requires Python $1.
|
AC_MSG_ERROR([this package requires Python $1.
|
||||||
If you have it installed, but it isn't the default Python
|
If you have it installed, but it isn't the default Python
|
||||||
interpreter in your system path, please pass the PYTHON_VERSION
|
interpreter in your system path, please pass the PYTHON_VERSION
|
||||||
variable to configure. See ``configure --help'' for reference.
|
variable to configure. See ``configure --help'' for reference.
|
||||||
])
|
])
|
||||||
PYTHON_VERSION=""
|
PYTHON_VERSION=""
|
||||||
|
])
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -223,7 +203,7 @@ EOD`
|
||||||
ac_python_version=$PYTHON_VERSION
|
ac_python_version=$PYTHON_VERSION
|
||||||
else
|
else
|
||||||
ac_python_version=`$PYTHON -c "import sys; \
|
ac_python_version=`$PYTHON -c "import sys; \
|
||||||
print ('.'.join(sys.version.split('.')[[:2]]))"`
|
print (sys.version[[:3]])"`
|
||||||
fi
|
fi
|
||||||
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
|
## to do this, so we install a shim onto the path which calls the real
|
||||||
## dh_shlibdeps with the required arguments.
|
## dh_shlibdeps with the required arguments.
|
||||||
path_prepend=`mktemp -d /tmp/intercept.XXXXXX`; \
|
path_prepend=`mktemp -d /tmp/intercept.XXXXXX`; \
|
||||||
echo "#!$(SHELL)" > $${path_prepend}/dh_shlibdeps; \
|
echo "#$(SHELL)" > $${path_prepend}/dh_shlibdeps; \
|
||||||
echo "`which dh_shlibdeps` -- \
|
echo "`which dh_shlibdeps` -- \
|
||||||
-xlibuutil3linux -xlibnvpair3linux -xlibzfs5linux -xlibzpool5linux" \
|
-xlibuutil3linux -xlibnvpair3linux -xlibzfs5linux -xlibzpool5linux" \
|
||||||
>> $${path_prepend}/dh_shlibdeps; \
|
>> $${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,
|
## Debianized packages from the auto-generated dependencies of the new debs,
|
||||||
## which should NOT be mixed with the alien-generated debs created here
|
## which should NOT be mixed with the alien-generated debs created here
|
||||||
chmod +x $${path_prepend}/dh_shlibdeps; \
|
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 \
|
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch \
|
||||||
$$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
|
$$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
|
||||||
$$pkg8 $$pkg9 $$pkg10 || exit 1; \
|
$$pkg8 $$pkg9 $$pkg10 || exit 1; \
|
||||||
|
|
|
@ -162,17 +162,11 @@ dnl #
|
||||||
dnl # 3.1 API change,
|
dnl # 3.1 API change,
|
||||||
dnl # Check if inode_operations contains the function get_acl
|
dnl # Check if inode_operations contains the function get_acl
|
||||||
dnl #
|
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], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
|
ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
|
||||||
#include <linux/fs.h>
|
#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; }
|
{ return NULL; }
|
||||||
|
|
||||||
static const struct inode_operations
|
static const struct inode_operations
|
||||||
|
@ -180,49 +174,14 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
|
||||||
.get_acl = get_acl_fn,
|
.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_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
|
||||||
AC_MSG_CHECKING([whether iops->get_acl() exists])
|
AC_MSG_CHECKING([whether iops->get_acl() exists])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_GET_ACL, 1, [iops->get_acl() exists])
|
|
||||||
],[
|
],[
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl_rcu], [
|
ZFS_LINUX_TEST_ERROR([iops->get_acl()])
|
||||||
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()])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -233,41 +192,11 @@ dnl #
|
||||||
dnl # 5.12 API change,
|
dnl # 5.12 API change,
|
||||||
dnl # set_acl() added a user_namespace* parameter first
|
dnl # set_acl() added a user_namespace* parameter first
|
||||||
dnl #
|
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], [
|
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], [
|
ZFS_LINUX_TEST_SRC([inode_operations_set_acl_userns], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
static int set_acl_fn(struct user_namespace *userns,
|
int set_acl_fn(struct user_namespace *userns,
|
||||||
struct inode *inode, struct posix_acl *acl,
|
struct inode *inode, struct posix_acl *acl,
|
||||||
int type) { return 0; }
|
int type) { return 0; }
|
||||||
|
|
||||||
|
@ -279,7 +208,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [
|
ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [
|
||||||
#include <linux/fs.h>
|
#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; }
|
int type) { return 0; }
|
||||||
|
|
||||||
static const struct inode_operations
|
static const struct inode_operations
|
||||||
|
@ -295,26 +224,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
|
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
|
||||||
AC_DEFINE(HAVE_SET_ACL_USERNS, 1, [iops->set_acl() takes 4 args])
|
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], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists, takes 3 args])
|
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], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [
|
||||||
ZFS_LINUX_TEST_SRC([dentry_operations_d_automount], [
|
ZFS_LINUX_TEST_SRC([dentry_operations_d_automount], [
|
||||||
#include <linux/dcache.h>
|
#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)) = {
|
struct dentry_operations dops __attribute__ ((unused)) = {
|
||||||
.d_automount = d_automount,
|
.d_automount = d_automount,
|
||||||
};
|
};
|
||||||
|
|
|
@ -191,24 +191,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_SET_DEV], [
|
||||||
], [], [ZFS_META_LICENSE])
|
], [], [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_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV], [
|
||||||
AC_MSG_CHECKING([whether bio_set_dev() is available])
|
AC_MSG_CHECKING([whether bio_set_dev() is available])
|
||||||
ZFS_LINUX_TEST_RESULT([bio_set_dev], [
|
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,
|
AC_DEFINE(HAVE_BIO_SET_DEV_GPL_ONLY, 1,
|
||||||
[bio_set_dev() GPL-only])
|
[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)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
|
@ -247,7 +220,7 @@ dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_END_IO_T_ARGS], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_END_IO_T_ARGS], [
|
||||||
ZFS_LINUX_TEST_SRC([bio_end_io_t_args], [
|
ZFS_LINUX_TEST_SRC([bio_end_io_t_args], [
|
||||||
#include <linux/bio.h>
|
#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;
|
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], [
|
ZFS_LINUX_TEST_SRC([submit_bio], [
|
||||||
#include <linux/bio.h>
|
#include <linux/bio.h>
|
||||||
],[
|
],[
|
||||||
|
blk_qc_t blk_qc;
|
||||||
struct bio *bio = NULL;
|
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], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [
|
||||||
ZFS_AC_KERNEL_SRC_REQ
|
ZFS_AC_KERNEL_SRC_REQ
|
||||||
ZFS_AC_KERNEL_SRC_BIO_OPS
|
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_BIO_CURRENT_BIO_LIST
|
||||||
ZFS_AC_KERNEL_SRC_BLKG_TRYGET
|
ZFS_AC_KERNEL_SRC_BLKG_TRYGET
|
||||||
ZFS_AC_KERNEL_SRC_BIO_BDEV_DISK
|
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], [
|
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_BIO_CURRENT_BIO_LIST
|
||||||
ZFS_AC_KERNEL_BLKG_TRYGET
|
ZFS_AC_KERNEL_BLKG_TRYGET
|
||||||
ZFS_AC_KERNEL_BIO_BDEV_DISK
|
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
|
|
||||||
])
|
])
|
||||||
|
|
|
@ -48,135 +48,54 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_BDI], [
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 5.9: added blk_queue_update_readahead(),
|
dnl # 2.6.32 API,
|
||||||
dnl # 5.15: renamed to disk_update_readahead()
|
dnl # blk_queue_discard()
|
||||||
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 #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD], [
|
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], [
|
ZFS_LINUX_TEST_SRC([blk_queue_discard], [
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
],[
|
],[
|
||||||
struct request_queue r;
|
struct request_queue *q __attribute__ ((unused)) = NULL;
|
||||||
struct request_queue *q = &r;
|
|
||||||
int value __attribute__ ((unused));
|
int value __attribute__ ((unused));
|
||||||
memset(q, 0, sizeof(r));
|
|
||||||
value = blk_queue_discard(q);
|
value = blk_queue_discard(q);
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_DISCARD], [
|
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_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])
|
AC_MSG_CHECKING([whether blk_queue_discard() is available])
|
||||||
ZFS_LINUX_TEST_RESULT([blk_queue_discard], [
|
ZFS_LINUX_TEST_RESULT([blk_queue_discard], [
|
||||||
AC_MSG_RESULT(yes)
|
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 #
|
||||||
dnl # 5.19: bdev_max_secure_erase_sectors() available
|
dnl # 4.8 API,
|
||||||
dnl # 4.8: blk_queue_secure_erase() available
|
dnl # blk_queue_secure_erase()
|
||||||
dnl # 2.6.36: blk_queue_secdiscard() available
|
dnl #
|
||||||
|
dnl # 2.6.36 - 4.7 API,
|
||||||
|
dnl # blk_queue_secdiscard()
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE], [
|
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], [
|
ZFS_LINUX_TEST_SRC([blk_queue_secure_erase], [
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
],[
|
],[
|
||||||
struct request_queue r;
|
struct request_queue *q __attribute__ ((unused)) = NULL;
|
||||||
struct request_queue *q = &r;
|
|
||||||
int value __attribute__ ((unused));
|
int value __attribute__ ((unused));
|
||||||
memset(q, 0, sizeof(r));
|
|
||||||
value = blk_queue_secure_erase(q);
|
value = blk_queue_secure_erase(q);
|
||||||
])
|
])
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([blk_queue_secdiscard], [
|
ZFS_LINUX_TEST_SRC([blk_queue_secdiscard], [
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
],[
|
],[
|
||||||
struct request_queue r;
|
struct request_queue *q __attribute__ ((unused)) = NULL;
|
||||||
struct request_queue *q = &r;
|
|
||||||
int value __attribute__ ((unused));
|
int value __attribute__ ((unused));
|
||||||
memset(q, 0, sizeof(r));
|
|
||||||
value = blk_queue_secdiscard(q);
|
value = blk_queue_secdiscard(q);
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE], [
|
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_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_BDEV_MAX_SECURE_ERASE_SECTORS, 1,
|
|
||||||
[bdev_max_secure_erase_sectors() is available])
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether blk_queue_secure_erase() is available])
|
AC_MSG_CHECKING([whether blk_queue_secure_erase() is available])
|
||||||
ZFS_LINUX_TEST_RESULT([blk_queue_secure_erase], [
|
ZFS_LINUX_TEST_RESULT([blk_queue_secure_erase], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
@ -195,7 +114,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE], [
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 4.16 API change,
|
dnl # 4.16 API change,
|
||||||
|
@ -259,17 +177,17 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLUSH], [
|
||||||
ZFS_LINUX_TEST_SRC([blk_queue_flush], [
|
ZFS_LINUX_TEST_SRC([blk_queue_flush], [
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
], [
|
], [
|
||||||
struct request_queue *q __attribute__ ((unused)) = NULL;
|
struct request_queue *q = NULL;
|
||||||
(void) blk_queue_flush(q, REQ_FLUSH);
|
(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], [
|
ZFS_LINUX_TEST_SRC([blk_queue_write_cache], [
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
], [
|
], [
|
||||||
struct request_queue *q __attribute__ ((unused)) = NULL;
|
struct request_queue *q = NULL;
|
||||||
blk_queue_write_cache(q, true, true);
|
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], [
|
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], [
|
ZFS_LINUX_TEST_SRC([blk_queue_max_hw_sectors], [
|
||||||
#include <linux/blkdev.h>
|
#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);
|
(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], [
|
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], [
|
ZFS_LINUX_TEST_SRC([blk_queue_max_segments], [
|
||||||
#include <linux/blkdev.h>
|
#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);
|
(void) blk_queue_max_segments(q, BLK_MAX_SEGMENTS);
|
||||||
], [])
|
], [$NO_UNUSED_BUT_SET_VARIABLE])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS], [
|
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], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [
|
||||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG
|
ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG
|
||||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI
|
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_DISCARD
|
||||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
|
ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
|
||||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_SET
|
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], [
|
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE], [
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_PLUG
|
ZFS_AC_KERNEL_BLK_QUEUE_PLUG
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_BDI
|
ZFS_AC_KERNEL_BLK_QUEUE_BDI
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_UPDATE_READAHEAD
|
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
|
ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
|
ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET
|
ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET
|
||||||
|
|
|
@ -16,92 +16,14 @@ 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_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], [
|
ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [
|
||||||
AC_MSG_RESULT(yes)
|
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()])
|
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)
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 2.6.38 API change,
|
dnl # 2.6.38 API change,
|
||||||
|
@ -119,60 +41,14 @@ 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_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [
|
||||||
AC_MSG_CHECKING([whether blkdev_put() exists])
|
AC_MSG_CHECKING([whether blkdev_put() exists])
|
||||||
ZFS_LINUX_TEST_RESULT([blkdev_put], [
|
ZFS_LINUX_TEST_RESULT([blkdev_put], [
|
||||||
AC_MSG_RESULT(yes)
|
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()])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 4.1 API, exported blkdev_reread_part() symbol, back ported to the
|
dnl # 4.1 API, exported blkdev_reread_part() symbol, back ported to the
|
||||||
|
@ -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 #
|
||||||
dnl # 5.10 API, check_disk_change() is removed, in favor of
|
dnl # 5.10 API, check_disk_change() is removed, in favor of
|
||||||
dnl # bdev_check_media_change(), which doesn't force revalidation
|
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_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], [
|
ZFS_LINUX_TEST_RESULT([bdev_check_media_change], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_BDEV_CHECK_MEDIA_CHANGE, 1,
|
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], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
|
||||||
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
|
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
|
||||||
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_REREAD_PART
|
||||||
ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV
|
ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV
|
||||||
ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_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_CHECK_DISK_CHANGE
|
||||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
|
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
|
||||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_WHOLE
|
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], [
|
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_CHECK_DISK_CHANGE
|
||||||
ZFS_AC_KERNEL_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
|
ZFS_AC_KERNEL_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
|
||||||
ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE
|
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], [
|
ZFS_LINUX_TEST_SRC([block_device_operations_check_events], [
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
|
|
||||||
static unsigned int blk_check_events(struct gendisk *disk,
|
unsigned int blk_check_events(struct gendisk *disk,
|
||||||
unsigned int clearing) {
|
unsigned int clearing) { return (0); }
|
||||||
(void) disk, (void) clearing;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct block_device_operations
|
static const struct block_device_operations
|
||||||
bops __attribute__ ((unused)) = {
|
bops __attribute__ ((unused)) = {
|
||||||
.check_events = blk_check_events,
|
.check_events = blk_check_events,
|
||||||
};
|
};
|
||||||
], [], [])
|
], [], [$NO_UNUSED_BUT_SET_VARIABLE])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
|
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], [
|
ZFS_LINUX_TEST_SRC([block_device_operations_release_void], [
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
|
|
||||||
static void blk_release(struct gendisk *g, fmode_t mode) {
|
void blk_release(struct gendisk *g, fmode_t mode) { return; }
|
||||||
(void) g, (void) mode;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct block_device_operations
|
static const struct block_device_operations
|
||||||
bops __attribute__ ((unused)) = {
|
bops __attribute__ ((unused)) = {
|
||||||
|
@ -46,47 +40,17 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
|
||||||
.ioctl = NULL,
|
.ioctl = NULL,
|
||||||
.compat_ioctl = NULL,
|
.compat_ioctl = NULL,
|
||||||
};
|
};
|
||||||
], [], [])
|
], [], [$NO_UNUSED_BUT_SET_VARIABLE])
|
||||||
])
|
|
||||||
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
], [], [])
|
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
|
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], [
|
ZFS_LINUX_TEST_RESULT([block_device_operations_release_void], [
|
||||||
AC_MSG_RESULT(yes)
|
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()])
|
ZFS_LINUX_TEST_ERROR([bops->release()])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 5.13 API change
|
dnl # 5.13 API change
|
||||||
|
@ -96,8 +60,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [
|
||||||
ZFS_LINUX_TEST_SRC([block_device_operations_revalidate_disk], [
|
ZFS_LINUX_TEST_SRC([block_device_operations_revalidate_disk], [
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
|
|
||||||
static int blk_revalidate_disk(struct gendisk *disk) {
|
int blk_revalidate_disk(struct gendisk *disk) {
|
||||||
(void) disk;
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +68,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [
|
||||||
bops __attribute__ ((unused)) = {
|
bops __attribute__ ((unused)) = {
|
||||||
.revalidate_disk = blk_revalidate_disk,
|
.revalidate_disk = blk_revalidate_disk,
|
||||||
};
|
};
|
||||||
], [], [])
|
], [], [$NO_UNUSED_BUT_SET_VARIABLE])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [
|
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [
|
||||||
|
@ -122,7 +85,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [
|
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_CHECK_EVENTS
|
||||||
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
|
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
|
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_COMMIT_METADATA], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_COMMIT_METADATA], [
|
||||||
ZFS_LINUX_TEST_SRC([export_operations_commit_metadata], [
|
ZFS_LINUX_TEST_SRC([export_operations_commit_metadata], [
|
||||||
#include <linux/exportfs.h>
|
#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))={
|
static struct export_operations eops __attribute__ ((unused))={
|
||||||
.commit_metadata = commit_metadata,
|
.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_THREAD_SIZE
|
||||||
ZFS_AC_KERNEL_SRC_CONFIG_BLOCK
|
|
||||||
ZFS_AC_KERNEL_SRC_CONFIG_DEBUG_LOCK_ALLOC
|
ZFS_AC_KERNEL_SRC_CONFIG_DEBUG_LOCK_ALLOC
|
||||||
ZFS_AC_KERNEL_SRC_CONFIG_TRIM_UNUSED_KSYMS
|
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_INFLATE
|
||||||
|
ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_DEFLATE
|
||||||
|
|
||||||
AC_MSG_CHECKING([for kernel config option compatibility])
|
AC_MSG_CHECKING([for kernel config option compatibility])
|
||||||
ZFS_LINUX_TEST_COMPILE_ALL([config])
|
ZFS_LINUX_TEST_COMPILE_ALL([config])
|
||||||
AC_MSG_RESULT([done])
|
AC_MSG_RESULT([done])
|
||||||
|
|
||||||
ZFS_AC_KERNEL_CONFIG_MODULES
|
ZFS_AC_KERNEL_CONFIG_THREAD_SIZE
|
||||||
ZFS_AC_KERNEL_CONFIG_BLOCK
|
|
||||||
ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC
|
ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC
|
||||||
ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS
|
ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS
|
||||||
ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE
|
|
||||||
ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE
|
ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE
|
||||||
|
ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Check CONFIG_BLOCK
|
dnl # Check configured THREAD_SIZE
|
||||||
dnl #
|
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 #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_BLOCK], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_THREAD_SIZE], [
|
||||||
ZFS_LINUX_TEST_SRC([config_block], [
|
ZFS_LINUX_TEST_SRC([config_thread_size], [
|
||||||
#if !defined(CONFIG_BLOCK)
|
#include <linux/module.h>
|
||||||
#error CONFIG_BLOCK not defined
|
],[
|
||||||
|
#if (THREAD_SIZE < 16384)
|
||||||
|
#error "THREAD_SIZE is less than 16K"
|
||||||
#endif
|
#endif
|
||||||
],[])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_CONFIG_BLOCK], [
|
AC_DEFUN([ZFS_AC_KERNEL_CONFIG_THREAD_SIZE], [
|
||||||
AC_MSG_CHECKING([whether CONFIG_BLOCK is defined])
|
AC_MSG_CHECKING([whether kernel was built with 16K or larger stacks])
|
||||||
ZFS_LINUX_TEST_RESULT([config_block], [
|
ZFS_LINUX_TEST_RESULT([config_thread_size], [
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE(HAVE_LARGE_STACKS, 1, [kernel has large stacks])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT([no])
|
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 #
|
||||||
dnl # Check CONFIG_TRIM_UNUSED_KSYMS
|
dnl # Check CONFIG_TRIM_UNUSED_KSYMS
|
||||||
dnl #
|
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.9, current_time() added
|
||||||
dnl # 4.18, return type changed from timespec to timespec64
|
dnl # 4.18, return type changed from timespec to timespec64
|
||||||
dnl #
|
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], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_CURRENT_TIME], [
|
||||||
ZFS_LINUX_TEST_SRC([current_time], [
|
ZFS_LINUX_TEST_SRC([current_time], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
], [
|
], [
|
||||||
struct inode ip __attribute__ ((unused));
|
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/dcache.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
|
||||||
static int revalidate (struct dentry *dentry,
|
int revalidate (struct dentry *dentry,
|
||||||
struct nameidata *nidata) { return 0; }
|
struct nameidata *nidata) { return 0; }
|
||||||
|
|
||||||
static const struct dentry_operations
|
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], [
|
ZFS_LINUX_TEST_SRC([dirty_inode_with_flags], [
|
||||||
#include <linux/fs.h>
|
#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
|
static const struct super_operations
|
||||||
sops __attribute__ ((unused)) = {
|
sops __attribute__ ((unused)) = {
|
||||||
|
|
|
@ -7,7 +7,7 @@ dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_ENCODE_FH_WITH_INODE], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_ENCODE_FH_WITH_INODE], [
|
||||||
ZFS_LINUX_TEST_SRC([export_operations_encode_fh], [
|
ZFS_LINUX_TEST_SRC([export_operations_encode_fh], [
|
||||||
#include <linux/exportfs.h>
|
#include <linux/exportfs.h>
|
||||||
static int encode_fh(struct inode *inode, __u32 *fh, int *max_len,
|
int encode_fh(struct inode *inode, __u32 *fh, int *max_len,
|
||||||
struct inode *parent) { return 0; }
|
struct inode *parent) { return 0; }
|
||||||
static struct export_operations eops __attribute__ ((unused))={
|
static struct export_operations eops __attribute__ ((unused))={
|
||||||
.encode_fh = encode_fh,
|
.encode_fh = encode_fh,
|
||||||
|
|
|
@ -6,7 +6,7 @@ dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_EVICT_INODE], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_EVICT_INODE], [
|
||||||
ZFS_LINUX_TEST_SRC([evict_inode], [
|
ZFS_LINUX_TEST_SRC([evict_inode], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
static void evict_inode (struct inode * t) { return; }
|
void evict_inode (struct inode * t) { return; }
|
||||||
static struct super_operations sops __attribute__ ((unused)) = {
|
static struct super_operations sops __attribute__ ((unused)) = {
|
||||||
.evict_inode = evict_inode,
|
.evict_inode = evict_inode,
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,15 +3,11 @@ dnl # Linux 2.6.38 - 3.x API
|
||||||
dnl # The fallocate callback was moved from the inode_operations
|
dnl # The fallocate callback was moved from the inode_operations
|
||||||
dnl # structure to the file_operations structure.
|
dnl # structure to the file_operations structure.
|
||||||
dnl #
|
dnl #
|
||||||
dnl #
|
|
||||||
dnl # Linux 3.15+
|
|
||||||
dnl # fallocate learned a new flag, FALLOC_FL_ZERO_RANGE
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_FALLOCATE], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_FALLOCATE], [
|
||||||
ZFS_LINUX_TEST_SRC([file_fallocate], [
|
ZFS_LINUX_TEST_SRC([file_fallocate], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
static long test_fallocate(struct file *file, int mode,
|
long test_fallocate(struct file *file, int mode,
|
||||||
loff_t offset, loff_t len) { return 0; }
|
loff_t offset, loff_t len) { return 0; }
|
||||||
|
|
||||||
static const struct file_operations
|
static const struct file_operations
|
||||||
|
@ -19,25 +15,12 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FALLOCATE], [
|
||||||
.fallocate = test_fallocate,
|
.fallocate = test_fallocate,
|
||||||
};
|
};
|
||||||
], [])
|
], [])
|
||||||
ZFS_LINUX_TEST_SRC([falloc_fl_zero_range], [
|
|
||||||
#include <linux/falloc.h>
|
|
||||||
],[
|
|
||||||
int flags __attribute__ ((unused));
|
|
||||||
flags = FALLOC_FL_ZERO_RANGE;
|
|
||||||
])
|
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_FALLOCATE], [
|
AC_DEFUN([ZFS_AC_KERNEL_FALLOCATE], [
|
||||||
AC_MSG_CHECKING([whether fops->fallocate() exists])
|
AC_MSG_CHECKING([whether fops->fallocate() exists])
|
||||||
ZFS_LINUX_TEST_RESULT([file_fallocate], [
|
ZFS_LINUX_TEST_RESULT([file_fallocate], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_MSG_CHECKING([whether FALLOC_FL_ZERO_RANGE exists])
|
|
||||||
ZFS_LINUX_TEST_RESULT([falloc_fl_zero_range], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_FALLOC_FL_ZERO_RANGE, 1, [FALLOC_FL_ZERO_RANGE is defined])
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
])
|
|
||||||
],[
|
],[
|
||||||
ZFS_LINUX_TEST_ERROR([file_fallocate])
|
ZFS_LINUX_TEST_ERROR([file_fallocate])
|
||||||
])
|
])
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ], [
|
|
||||||
dnl #
|
|
||||||
dnl # Kernel 6.5 - generic_file_splice_read was removed in favor
|
|
||||||
dnl # of copy_splice_read for the .splice_read member of the
|
|
||||||
dnl # file_operations struct.
|
|
||||||
dnl #
|
|
||||||
ZFS_LINUX_TEST_SRC([has_copy_splice_read], [
|
|
||||||
#include <linux/fs.h>
|
|
||||||
|
|
||||||
struct file_operations fops __attribute__((unused)) = {
|
|
||||||
.splice_read = copy_splice_read,
|
|
||||||
};
|
|
||||||
],[])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_COPY_SPLICE_READ], [
|
|
||||||
AC_MSG_CHECKING([whether copy_splice_read() exists])
|
|
||||||
ZFS_LINUX_TEST_RESULT([has_copy_splice_read], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_COPY_SPLICE_READ, 1,
|
|
||||||
[copy_splice_read exists])
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
])
|
|
||||||
])
|
|
|
@ -1,26 +0,0 @@
|
||||||
dnl #
|
|
||||||
dnl # filemap_range_has_page was not available till 4.13
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_FILEMAP], [
|
|
||||||
ZFS_LINUX_TEST_SRC([filemap_range_has_page], [
|
|
||||||
#include <linux/fs.h>
|
|
||||||
],[
|
|
||||||
struct address_space *mapping = NULL;
|
|
||||||
loff_t lstart = 0;
|
|
||||||
loff_t lend = 0;
|
|
||||||
bool ret __attribute__ ((unused));
|
|
||||||
|
|
||||||
ret = filemap_range_has_page(mapping, lstart, lend);
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_FILEMAP], [
|
|
||||||
AC_MSG_CHECKING([whether filemap_range_has_page() is available])
|
|
||||||
ZFS_LINUX_TEST_RESULT([filemap_range_has_page], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_FILEMAP_RANGE_HAS_PAGE, 1,
|
|
||||||
[filemap_range_has_page() is available])
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
])
|
|
||||||
])
|
|
|
@ -1,26 +0,0 @@
|
||||||
dnl #
|
|
||||||
dnl # Starting from Linux 5.13, flush_dcache_page() becomes an inline
|
|
||||||
dnl # function and may indirectly referencing GPL-only cpu_feature_keys on
|
|
||||||
dnl # powerpc
|
|
||||||
dnl #
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Checking if flush_dcache_page is exported GPL-only
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_FLUSH_DCACHE_PAGE], [
|
|
||||||
ZFS_LINUX_TEST_SRC([flush_dcache_page], [
|
|
||||||
#include <asm/cacheflush.h>
|
|
||||||
], [
|
|
||||||
flush_dcache_page(0);
|
|
||||||
], [], [ZFS_META_LICENSE])
|
|
||||||
])
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_FLUSH_DCACHE_PAGE], [
|
|
||||||
AC_MSG_CHECKING([whether flush_dcache_page() is GPL-only])
|
|
||||||
ZFS_LINUX_TEST_RESULT([flush_dcache_page_license], [
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_FLUSH_DCACHE_PAGE_GPL_ONLY, 1,
|
|
||||||
[flush_dcache_page() is GPL-only])
|
|
||||||
])
|
|
||||||
])
|
|
|
@ -2,18 +2,6 @@ dnl #
|
||||||
dnl # Handle differences in kernel FPU code.
|
dnl # Handle differences in kernel FPU code.
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Kernel
|
dnl # Kernel
|
||||||
dnl # 5.19: The asm/fpu/internal.h header was removed, it has been
|
|
||||||
dnl # effectively empty since the 5.16 kernel.
|
|
||||||
dnl #
|
|
||||||
dnl # 5.16: XCR code put into asm/fpu/xcr.h
|
|
||||||
dnl # HAVE_KERNEL_FPU_XCR_HEADER
|
|
||||||
dnl #
|
|
||||||
dnl # XSTATE_XSAVE and XSTATE_XRESTORE aren't accessible any more
|
|
||||||
dnl # HAVE_KERNEL_FPU_XSAVE_INTERNAL
|
|
||||||
dnl #
|
|
||||||
dnl # 5.11: kernel_fpu_begin() is an inlined function now, so don't check
|
|
||||||
dnl # for it inside the kernel symbols.
|
|
||||||
dnl #
|
|
||||||
dnl # 5.0: Wrappers have been introduced to save/restore the FPU state.
|
dnl # 5.0: Wrappers have been introduced to save/restore the FPU state.
|
||||||
dnl # This change was made to the 4.19.38 and 4.14.120 LTS kernels.
|
dnl # This change was made to the 4.19.38 and 4.14.120 LTS kernels.
|
||||||
dnl # HAVE_KERNEL_FPU_INTERNAL
|
dnl # HAVE_KERNEL_FPU_INTERNAL
|
||||||
|
@ -36,31 +24,9 @@ AC_DEFUN([ZFS_AC_KERNEL_FPU_HEADER], [
|
||||||
],[
|
],[
|
||||||
AC_DEFINE(HAVE_KERNEL_FPU_API_HEADER, 1,
|
AC_DEFINE(HAVE_KERNEL_FPU_API_HEADER, 1,
|
||||||
[kernel has asm/fpu/api.h])
|
[kernel has asm/fpu/api.h])
|
||||||
fpu_headers="asm/fpu/api.h"
|
AC_MSG_RESULT(asm/fpu/api.h)
|
||||||
|
|
||||||
ZFS_LINUX_TRY_COMPILE([
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <asm/fpu/xcr.h>
|
|
||||||
],[
|
],[
|
||||||
],[
|
AC_MSG_RESULT(i387.h & xcr.h)
|
||||||
AC_DEFINE(HAVE_KERNEL_FPU_XCR_HEADER, 1,
|
|
||||||
[kernel has asm/fpu/xcr.h])
|
|
||||||
fpu_headers="$fpu_headers asm/fpu/xcr.h"
|
|
||||||
])
|
|
||||||
|
|
||||||
ZFS_LINUX_TRY_COMPILE([
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <asm/fpu/internal.h>
|
|
||||||
],[
|
|
||||||
],[
|
|
||||||
AC_DEFINE(HAVE_KERNEL_FPU_INTERNAL_HEADER, 1,
|
|
||||||
[kernel has asm/fpu/internal.h])
|
|
||||||
fpu_headers="$fpu_headers asm/fpu/internal.h"
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_MSG_RESULT([$fpu_headers])
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT([i387.h & xcr.h])
|
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -91,13 +57,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [
|
||||||
__kernel_fpu_end();
|
__kernel_fpu_end();
|
||||||
], [], [ZFS_META_LICENSE])
|
], [], [ZFS_META_LICENSE])
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([kernel_neon], [
|
|
||||||
#include <asm/neon.h>
|
|
||||||
], [
|
|
||||||
kernel_neon_begin();
|
|
||||||
kernel_neon_end();
|
|
||||||
], [], [ZFS_META_LICENSE])
|
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([fpu_internal], [
|
ZFS_LINUX_TEST_SRC([fpu_internal], [
|
||||||
#if defined(__x86_64) || defined(__x86_64__) || \
|
#if defined(__x86_64) || defined(__x86_64__) || \
|
||||||
defined(__i386) || defined(__i386__)
|
defined(__i386) || defined(__i386__)
|
||||||
|
@ -113,9 +72,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#ifdef HAVE_KERNEL_FPU_API_HEADER
|
#ifdef HAVE_KERNEL_FPU_API_HEADER
|
||||||
#include <asm/fpu/api.h>
|
#include <asm/fpu/api.h>
|
||||||
#ifdef HAVE_KERNEL_FPU_INTERNAL_HEADER
|
|
||||||
#include <asm/fpu/internal.h>
|
#include <asm/fpu/internal.h>
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
#include <asm/i387.h>
|
#include <asm/i387.h>
|
||||||
#include <asm/xcr.h>
|
#include <asm/xcr.h>
|
||||||
|
@ -135,38 +92,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [
|
||||||
struct fxregs_state *fxr __attribute__ ((unused)) = &st->fxsave;
|
struct fxregs_state *fxr __attribute__ ((unused)) = &st->fxsave;
|
||||||
struct xregs_state *xr __attribute__ ((unused)) = &st->xsave;
|
struct xregs_state *xr __attribute__ ((unused)) = &st->xsave;
|
||||||
])
|
])
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([fpu_xsave_internal], [
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#if defined(__x86_64) || defined(__x86_64__) || \
|
|
||||||
defined(__i386) || defined(__i386__)
|
|
||||||
#if !defined(__x86)
|
|
||||||
#define __x86
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__x86)
|
|
||||||
#error Unsupported architecture
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <linux/types.h>
|
|
||||||
#ifdef HAVE_KERNEL_FPU_API_HEADER
|
|
||||||
#include <asm/fpu/api.h>
|
|
||||||
#ifdef HAVE_KERNEL_FPU_INTERNAL_HEADER
|
|
||||||
#include <asm/fpu/internal.h>
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <asm/i387.h>
|
|
||||||
#include <asm/xcr.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
],[
|
|
||||||
struct fpu *fpu = ¤t->thread.fpu;
|
|
||||||
union fpregs_state *st = &fpu->fpstate->regs;
|
|
||||||
struct fregs_state *fr __attribute__ ((unused)) = &st->fsave;
|
|
||||||
struct fxregs_state *fxr __attribute__ ((unused)) = &st->fxsave;
|
|
||||||
struct xregs_state *xr __attribute__ ((unused)) = &st->xsave;
|
|
||||||
])
|
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_FPU], [
|
AC_DEFUN([ZFS_AC_KERNEL_FPU], [
|
||||||
|
@ -174,7 +99,8 @@ AC_DEFUN([ZFS_AC_KERNEL_FPU], [
|
||||||
dnl # Legacy kernel
|
dnl # Legacy kernel
|
||||||
dnl #
|
dnl #
|
||||||
AC_MSG_CHECKING([whether kernel fpu is available])
|
AC_MSG_CHECKING([whether kernel fpu is available])
|
||||||
ZFS_LINUX_TEST_RESULT([kernel_fpu_license], [
|
ZFS_LINUX_TEST_RESULT_SYMBOL([kernel_fpu_license],
|
||||||
|
[kernel_fpu_begin], [arch/x86/kernel/fpu/core.c], [
|
||||||
AC_MSG_RESULT(kernel_fpu_*)
|
AC_MSG_RESULT(kernel_fpu_*)
|
||||||
AC_DEFINE(HAVE_KERNEL_FPU, 1,
|
AC_DEFINE(HAVE_KERNEL_FPU, 1,
|
||||||
[kernel has kernel_fpu_* functions])
|
[kernel has kernel_fpu_* functions])
|
||||||
|
@ -192,30 +118,14 @@ AC_DEFUN([ZFS_AC_KERNEL_FPU], [
|
||||||
[kernel has __kernel_fpu_* functions])
|
[kernel has __kernel_fpu_* functions])
|
||||||
AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1,
|
AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1,
|
||||||
[kernel exports FPU functions])
|
[kernel exports FPU functions])
|
||||||
],[
|
|
||||||
dnl #
|
|
||||||
dnl # ARM neon symbols (only on arm and arm64)
|
|
||||||
dnl # could be GPL-only on arm64 after Linux 6.2
|
|
||||||
dnl #
|
|
||||||
ZFS_LINUX_TEST_RESULT([kernel_neon_license],[
|
|
||||||
AC_MSG_RESULT(kernel_neon_*)
|
|
||||||
AC_DEFINE(HAVE_KERNEL_NEON, 1,
|
|
||||||
[kernel has kernel_neon_* functions])
|
|
||||||
],[
|
],[
|
||||||
ZFS_LINUX_TEST_RESULT([fpu_internal], [
|
ZFS_LINUX_TEST_RESULT([fpu_internal], [
|
||||||
AC_MSG_RESULT(internal)
|
AC_MSG_RESULT(internal)
|
||||||
AC_DEFINE(HAVE_KERNEL_FPU_INTERNAL, 1,
|
AC_DEFINE(HAVE_KERNEL_FPU_INTERNAL, 1,
|
||||||
[kernel fpu internal])
|
[kernel fpu internal])
|
||||||
],[
|
|
||||||
ZFS_LINUX_TEST_RESULT([fpu_xsave_internal], [
|
|
||||||
AC_MSG_RESULT(internal with internal XSAVE)
|
|
||||||
AC_DEFINE(HAVE_KERNEL_FPU_XSAVE_INTERNAL, 1,
|
|
||||||
[kernel fpu and XSAVE internal])
|
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(unavailable)
|
AC_MSG_RESULT(unavailable)
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
dnl #
|
|
||||||
dnl # 6.6 API change,
|
|
||||||
dnl # fsync_bdev was removed in favor of sync_blockdev
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_SYNC_BDEV], [
|
|
||||||
ZFS_LINUX_TEST_SRC([fsync_bdev], [
|
|
||||||
#include <linux/blkdev.h>
|
|
||||||
],[
|
|
||||||
fsync_bdev(NULL);
|
|
||||||
])
|
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([sync_blockdev], [
|
|
||||||
#include <linux/blkdev.h>
|
|
||||||
],[
|
|
||||||
sync_blockdev(NULL);
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SYNC_BDEV], [
|
|
||||||
AC_MSG_CHECKING([whether fsync_bdev() exists])
|
|
||||||
ZFS_LINUX_TEST_RESULT([fsync_bdev], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_FSYNC_BDEV, 1,
|
|
||||||
[fsync_bdev() is declared in include/blkdev.h])
|
|
||||||
],[
|
|
||||||
AC_MSG_CHECKING([whether sync_blockdev() exists])
|
|
||||||
ZFS_LINUX_TEST_RESULT([sync_blockdev], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_SYNC_BLOCKDEV, 1,
|
|
||||||
[sync_blockdev() is declared in include/blkdev.h])
|
|
||||||
],[
|
|
||||||
ZFS_LINUX_TEST_ERROR(
|
|
||||||
[neither fsync_bdev() nor sync_blockdev() exist])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
])
|
|
|
@ -5,7 +5,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FSYNC], [
|
||||||
ZFS_LINUX_TEST_SRC([fsync_without_dentry], [
|
ZFS_LINUX_TEST_SRC([fsync_without_dentry], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
static int test_fsync(struct file *f, int x) { return 0; }
|
int test_fsync(struct file *f, int x) { return 0; }
|
||||||
|
|
||||||
static const struct file_operations
|
static const struct file_operations
|
||||||
fops __attribute__ ((unused)) = {
|
fops __attribute__ ((unused)) = {
|
||||||
|
@ -16,7 +16,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FSYNC], [
|
||||||
ZFS_LINUX_TEST_SRC([fsync_range], [
|
ZFS_LINUX_TEST_SRC([fsync_range], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
static int test_fsync(struct file *f, loff_t a, loff_t b, int c)
|
int test_fsync(struct file *f, loff_t a, loff_t b, int c)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
|
||||||
static const struct file_operations
|
static const struct file_operations
|
||||||
|
|
|
@ -4,14 +4,7 @@ dnl #
|
||||||
dnl # generic_fillattr in linux/fs.h now requires a struct user_namespace*
|
dnl # generic_fillattr in linux/fs.h now requires a struct user_namespace*
|
||||||
dnl # as the first arg, to support idmapped mounts.
|
dnl # as the first arg, to support idmapped mounts.
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 6.3 API
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS], [
|
||||||
dnl # generic_fillattr() now takes struct mnt_idmap* as the first argument
|
|
||||||
dnl #
|
|
||||||
dnl # 6.6 API
|
|
||||||
dnl # generic_fillattr() now takes u32 as second argument, representing a
|
|
||||||
dnl # request_mask for statx
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR], [
|
|
||||||
ZFS_LINUX_TEST_SRC([generic_fillattr_userns], [
|
ZFS_LINUX_TEST_SRC([generic_fillattr_userns], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
],[
|
],[
|
||||||
|
@ -20,40 +13,9 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR], [
|
||||||
struct kstat *k = NULL;
|
struct kstat *k = NULL;
|
||||||
generic_fillattr(userns, in, k);
|
generic_fillattr(userns, in, k);
|
||||||
])
|
])
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([generic_fillattr_mnt_idmap], [
|
|
||||||
#include <linux/fs.h>
|
|
||||||
],[
|
|
||||||
struct mnt_idmap *idmap = NULL;
|
|
||||||
struct inode *in = NULL;
|
|
||||||
struct kstat *k = NULL;
|
|
||||||
generic_fillattr(idmap, in, k);
|
|
||||||
])
|
])
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([generic_fillattr_mnt_idmap_reqmask], [
|
AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS], [
|
||||||
#include <linux/fs.h>
|
|
||||||
],[
|
|
||||||
struct mnt_idmap *idmap = NULL;
|
|
||||||
struct inode *in = NULL;
|
|
||||||
struct kstat *k = NULL;
|
|
||||||
generic_fillattr(idmap, 0, in, k);
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR], [
|
|
||||||
AC_MSG_CHECKING(
|
|
||||||
[whether generic_fillattr requires struct mnt_idmap* and request_mask])
|
|
||||||
ZFS_LINUX_TEST_RESULT([generic_fillattr_mnt_idmap_reqmask], [
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
AC_DEFINE(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK, 1,
|
|
||||||
[generic_fillattr requires struct mnt_idmap* and u32 request_mask])
|
|
||||||
],[
|
|
||||||
AC_MSG_CHECKING([whether generic_fillattr requires struct mnt_idmap*])
|
|
||||||
ZFS_LINUX_TEST_RESULT([generic_fillattr_mnt_idmap], [
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
AC_DEFINE(HAVE_GENERIC_FILLATTR_IDMAP, 1,
|
|
||||||
[generic_fillattr requires struct mnt_idmap*])
|
|
||||||
],[
|
|
||||||
AC_MSG_CHECKING([whether generic_fillattr requires struct user_namespace*])
|
AC_MSG_CHECKING([whether generic_fillattr requires struct user_namespace*])
|
||||||
ZFS_LINUX_TEST_RESULT([generic_fillattr_userns], [
|
ZFS_LINUX_TEST_RESULT([generic_fillattr_userns], [
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
|
@ -63,6 +25,4 @@ AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR], [
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
|
@ -2,32 +2,6 @@ dnl #
|
||||||
dnl # Check for generic io accounting interface.
|
dnl # Check for generic io accounting interface.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [
|
||||||
ZFS_LINUX_TEST_SRC([bdev_io_acct_63], [
|
|
||||||
#include <linux/blkdev.h>
|
|
||||||
], [
|
|
||||||
struct block_device *bdev = NULL;
|
|
||||||
struct bio *bio = NULL;
|
|
||||||
unsigned long passed_time = 0;
|
|
||||||
unsigned long start_time;
|
|
||||||
|
|
||||||
start_time = bdev_start_io_acct(bdev, bio_op(bio),
|
|
||||||
passed_time);
|
|
||||||
bdev_end_io_acct(bdev, bio_op(bio), bio_sectors(bio), start_time);
|
|
||||||
])
|
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([bdev_io_acct_old], [
|
|
||||||
#include <linux/blkdev.h>
|
|
||||||
], [
|
|
||||||
struct block_device *bdev = NULL;
|
|
||||||
struct bio *bio = NULL;
|
|
||||||
unsigned long passed_time = 0;
|
|
||||||
unsigned long start_time;
|
|
||||||
|
|
||||||
start_time = bdev_start_io_acct(bdev, bio_sectors(bio),
|
|
||||||
bio_op(bio), passed_time);
|
|
||||||
bdev_end_io_acct(bdev, bio_op(bio), start_time);
|
|
||||||
])
|
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([disk_io_acct], [
|
ZFS_LINUX_TEST_SRC([disk_io_acct], [
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
], [
|
], [
|
||||||
|
@ -75,29 +49,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT], [
|
AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT], [
|
||||||
dnl #
|
|
||||||
dnl # Linux 6.3, and then backports thereof, changed
|
|
||||||
dnl # the signatures on bdev_start_io_acct/bdev_end_io_acct
|
|
||||||
dnl #
|
|
||||||
AC_MSG_CHECKING([whether 6.3+ bdev_*_io_acct() are available])
|
|
||||||
ZFS_LINUX_TEST_RESULT([bdev_io_acct_63], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_BDEV_IO_ACCT_63, 1, [bdev_*_io_acct() available])
|
|
||||||
], [
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # 5.19 API,
|
|
||||||
dnl #
|
|
||||||
dnl # disk_start_io_acct() and disk_end_io_acct() have been replaced by
|
|
||||||
dnl # bdev_start_io_acct() and bdev_end_io_acct().
|
|
||||||
dnl #
|
|
||||||
AC_MSG_CHECKING([whether pre-6.3 bdev_*_io_acct() are available])
|
|
||||||
ZFS_LINUX_TEST_RESULT([bdev_io_acct_old], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_BDEV_IO_ACCT_OLD, 1, [bdev_*_io_acct() available])
|
|
||||||
], [
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 5.12 API,
|
dnl # 5.12 API,
|
||||||
dnl #
|
dnl #
|
||||||
|
@ -159,5 +110,3 @@ AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT], [
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
dnl #
|
|
||||||
dnl # 5.17 API change,
|
|
||||||
dnl #
|
|
||||||
dnl # GENHD_FL_EXT_DEVT flag removed
|
|
||||||
dnl # GENHD_FL_NO_PART_SCAN renamed GENHD_FL_NO_PART
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_GENHD_FLAGS], [
|
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([genhd_fl_ext_devt], [
|
|
||||||
#include <linux/blkdev.h>
|
|
||||||
], [
|
|
||||||
int flags __attribute__ ((unused)) = GENHD_FL_EXT_DEVT;
|
|
||||||
])
|
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([genhd_fl_no_part], [
|
|
||||||
#include <linux/blkdev.h>
|
|
||||||
], [
|
|
||||||
int flags __attribute__ ((unused)) = GENHD_FL_NO_PART;
|
|
||||||
])
|
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([genhd_fl_no_part_scan], [
|
|
||||||
#include <linux/blkdev.h>
|
|
||||||
], [
|
|
||||||
int flags __attribute__ ((unused)) = GENHD_FL_NO_PART_SCAN;
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_GENHD_FLAGS], [
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether GENHD_FL_EXT_DEVT flag is available])
|
|
||||||
ZFS_LINUX_TEST_RESULT([genhd_fl_ext_devt], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(ZFS_GENHD_FL_EXT_DEVT, GENHD_FL_EXT_DEVT,
|
|
||||||
[GENHD_FL_EXT_DEVT flag is available])
|
|
||||||
], [
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
AC_DEFINE(ZFS_GENHD_FL_EXT_DEVT, 0,
|
|
||||||
[GENHD_FL_EXT_DEVT flag is not available])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether GENHD_FL_NO_PART flag is available])
|
|
||||||
ZFS_LINUX_TEST_RESULT([genhd_fl_no_part], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(ZFS_GENHD_FL_NO_PART, GENHD_FL_NO_PART,
|
|
||||||
[GENHD_FL_NO_PART flag is available])
|
|
||||||
], [
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether GENHD_FL_NO_PART_SCAN flag is available])
|
|
||||||
ZFS_LINUX_TEST_RESULT([genhd_fl_no_part_scan], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(ZFS_GENHD_FL_NO_PART, GENHD_FL_NO_PART_SCAN,
|
|
||||||
[GENHD_FL_NO_PART_SCAN flag is available])
|
|
||||||
], [
|
|
||||||
ZFS_LINUX_TEST_ERROR([GENHD_FL_NO_PART|GENHD_FL_NO_PART_SCAN])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
])
|
|
|
@ -5,9 +5,9 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_DISK_RO], [
|
||||||
ZFS_LINUX_TEST_SRC([get_disk_ro], [
|
ZFS_LINUX_TEST_SRC([get_disk_ro], [
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
],[
|
],[
|
||||||
struct gendisk *disk __attribute__ ((unused)) = NULL;
|
struct gendisk *disk = NULL;
|
||||||
(void) get_disk_ro(disk);
|
(void) get_disk_ro(disk);
|
||||||
], [])
|
], [$NO_UNUSED_BUT_SET_VARIABLE])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_RO], [
|
AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_RO], [
|
||||||
|
|
|
@ -5,7 +5,7 @@ dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_get_link], [
|
ZFS_LINUX_TEST_SRC([inode_operations_get_link], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
static const char *get_link(struct dentry *de, struct inode *ip,
|
const char *get_link(struct dentry *de, struct inode *ip,
|
||||||
struct delayed_call *done) { return "symlink"; }
|
struct delayed_call *done) { return "symlink"; }
|
||||||
static struct inode_operations
|
static struct inode_operations
|
||||||
iops __attribute__ ((unused)) = {
|
iops __attribute__ ((unused)) = {
|
||||||
|
@ -15,7 +15,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_get_link_cookie], [
|
ZFS_LINUX_TEST_SRC([inode_operations_get_link_cookie], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
static const char *get_link(struct dentry *de, struct
|
const char *get_link(struct dentry *de, struct
|
||||||
inode *ip, void **cookie) { return "symlink"; }
|
inode *ip, void **cookie) { return "symlink"; }
|
||||||
static struct inode_operations
|
static struct inode_operations
|
||||||
iops __attribute__ ((unused)) = {
|
iops __attribute__ ((unused)) = {
|
||||||
|
@ -25,7 +25,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_follow_link], [
|
ZFS_LINUX_TEST_SRC([inode_operations_follow_link], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
static const char *follow_link(struct dentry *de,
|
const char *follow_link(struct dentry *de,
|
||||||
void **cookie) { return "symlink"; }
|
void **cookie) { return "symlink"; }
|
||||||
static struct inode_operations
|
static struct inode_operations
|
||||||
iops __attribute__ ((unused)) = {
|
iops __attribute__ ((unused)) = {
|
||||||
|
@ -35,7 +35,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_follow_link_nameidata], [
|
ZFS_LINUX_TEST_SRC([inode_operations_follow_link_nameidata], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
static void *follow_link(struct dentry *de, struct
|
void *follow_link(struct dentry *de, struct
|
||||||
nameidata *nd) { return (void *)NULL; }
|
nameidata *nd) { return (void *)NULL; }
|
||||||
static struct inode_operations
|
static struct inode_operations
|
||||||
iops __attribute__ ((unused)) = {
|
iops __attribute__ ((unused)) = {
|
||||||
|
|
|
@ -55,7 +55,7 @@ dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_ENUM_MEMBER], [
|
AC_DEFUN([ZFS_AC_KERNEL_ENUM_MEMBER], [
|
||||||
AC_MSG_CHECKING([whether enum $2 contains $1])
|
AC_MSG_CHECKING([whether enum $2 contains $1])
|
||||||
AS_IF([AC_TRY_COMMAND(
|
AS_IF([AC_TRY_COMMAND(
|
||||||
"${srcdir}/scripts/enum-extract.pl" "$2" "$3" | grep -Eqx $1)],[
|
"${srcdir}/scripts/enum-extract.pl" "$2" "$3" | egrep -qx $1)],[
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
AC_DEFINE(m4_join([_], [ZFS_ENUM], m4_toupper($2), $1), 1,
|
AC_DEFINE(m4_join([_], [ZFS_ENUM], m4_toupper($2), $1), 1,
|
||||||
[enum $2 contains $1])
|
[enum $2 contains $1])
|
||||||
|
|
|
@ -6,8 +6,8 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GROUP_INFO_GID], [
|
||||||
ZFS_LINUX_TEST_SRC([group_info_gid], [
|
ZFS_LINUX_TEST_SRC([group_info_gid], [
|
||||||
#include <linux/cred.h>
|
#include <linux/cred.h>
|
||||||
],[
|
],[
|
||||||
struct group_info gi __attribute__ ((unused)) = {};
|
struct group_info *gi = groups_alloc(1);
|
||||||
gi.gid[0] = KGIDT_INIT(0);
|
gi->gid[0] = KGIDT_INIT(0);
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,4 @@
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
|
||||||
dnl #
|
|
||||||
dnl # 6.3 API change
|
|
||||||
dnl # The first arg is changed to struct mnt_idmap *
|
|
||||||
dnl #
|
|
||||||
ZFS_LINUX_TEST_SRC([create_mnt_idmap], [
|
|
||||||
#include <linux/fs.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
|
|
||||||
static int inode_create(struct mnt_idmap *idmap,
|
|
||||||
struct inode *inode ,struct dentry *dentry,
|
|
||||||
umode_t umode, bool flag) { return 0; }
|
|
||||||
|
|
||||||
static const struct inode_operations
|
|
||||||
iops __attribute__ ((unused)) = {
|
|
||||||
.create = inode_create,
|
|
||||||
};
|
|
||||||
],[])
|
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 5.12 API change that added the struct user_namespace* arg
|
dnl # 5.12 API change that added the struct user_namespace* arg
|
||||||
dnl # to the front of this function type's arg list.
|
dnl # to the front of this function type's arg list.
|
||||||
|
@ -25,7 +7,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
|
||||||
static int inode_create(struct user_namespace *userns,
|
int inode_create(struct user_namespace *userns,
|
||||||
struct inode *inode ,struct dentry *dentry,
|
struct inode *inode ,struct dentry *dentry,
|
||||||
umode_t umode, bool flag) { return 0; }
|
umode_t umode, bool flag) { return 0; }
|
||||||
|
|
||||||
|
@ -42,7 +24,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
|
||||||
static int inode_create(struct inode *inode ,struct dentry *dentry,
|
int inode_create(struct inode *inode ,struct dentry *dentry,
|
||||||
umode_t umode, bool flag) { return 0; }
|
umode_t umode, bool flag) { return 0; }
|
||||||
|
|
||||||
static const struct inode_operations
|
static const struct inode_operations
|
||||||
|
@ -53,14 +35,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_CREATE], [
|
AC_DEFUN([ZFS_AC_KERNEL_CREATE], [
|
||||||
AC_MSG_CHECKING([whether iops->create() takes struct mnt_idmap*])
|
|
||||||
ZFS_LINUX_TEST_RESULT([create_mnt_idmap], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_IOPS_CREATE_IDMAP, 1,
|
|
||||||
[iops->create() takes struct mnt_idmap*])
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether iops->create() takes struct user_namespace*])
|
AC_MSG_CHECKING([whether iops->create() takes struct user_namespace*])
|
||||||
ZFS_LINUX_TEST_RESULT([create_userns], [
|
ZFS_LINUX_TEST_RESULT([create_userns], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
@ -77,4 +51,3 @@ AC_DEFUN([ZFS_AC_KERNEL_CREATE], [
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
|
||||||
|
|
|
@ -1,24 +1,4 @@
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
|
||||||
dnl #
|
|
||||||
dnl # Linux 6.3 API
|
|
||||||
dnl # The first arg of getattr I/O operations handler type
|
|
||||||
dnl # is changed to struct mnt_idmap*
|
|
||||||
dnl #
|
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_getattr_mnt_idmap], [
|
|
||||||
#include <linux/fs.h>
|
|
||||||
|
|
||||||
static int test_getattr(
|
|
||||||
struct mnt_idmap *idmap,
|
|
||||||
const struct path *p, struct kstat *k,
|
|
||||||
u32 request_mask, unsigned int query_flags)
|
|
||||||
{ return 0; }
|
|
||||||
|
|
||||||
static const struct inode_operations
|
|
||||||
iops __attribute__ ((unused)) = {
|
|
||||||
.getattr = test_getattr,
|
|
||||||
};
|
|
||||||
],[])
|
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Linux 5.12 API
|
dnl # Linux 5.12 API
|
||||||
dnl # The getattr I/O operations handler type was extended to require
|
dnl # The getattr I/O operations handler type was extended to require
|
||||||
|
@ -28,7 +8,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_getattr_userns], [
|
ZFS_LINUX_TEST_SRC([inode_operations_getattr_userns], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
static int test_getattr(
|
int test_getattr(
|
||||||
struct user_namespace *userns,
|
struct user_namespace *userns,
|
||||||
const struct path *p, struct kstat *k,
|
const struct path *p, struct kstat *k,
|
||||||
u32 request_mask, unsigned int query_flags)
|
u32 request_mask, unsigned int query_flags)
|
||||||
|
@ -47,7 +27,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
|
ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
static int test_getattr(
|
int test_getattr(
|
||||||
const struct path *p, struct kstat *k,
|
const struct path *p, struct kstat *k,
|
||||||
u32 request_mask, unsigned int query_flags)
|
u32 request_mask, unsigned int query_flags)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
@ -61,7 +41,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_getattr_vfsmount], [
|
ZFS_LINUX_TEST_SRC([inode_operations_getattr_vfsmount], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
static int test_getattr(
|
int test_getattr(
|
||||||
struct vfsmount *mnt, struct dentry *d,
|
struct vfsmount *mnt, struct dentry *d,
|
||||||
struct kstat *k)
|
struct kstat *k)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
@ -74,16 +54,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
|
||||||
dnl #
|
|
||||||
dnl # Kernel 6.3 test
|
|
||||||
dnl #
|
|
||||||
AC_MSG_CHECKING([whether iops->getattr() takes mnt_idmap])
|
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_mnt_idmap], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_IDMAP_IOPS_GETATTR, 1,
|
|
||||||
[iops->getattr() takes struct mnt_idmap*])
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Kernel 5.12 test
|
dnl # Kernel 5.12 test
|
||||||
dnl #
|
dnl #
|
||||||
|
@ -120,4 +90,3 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_LOOKUP_FLAGS], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
|
||||||
static struct dentry *inode_lookup(struct inode *inode,
|
struct dentry *inode_lookup(struct inode *inode,
|
||||||
struct dentry *dentry, unsigned int flags) { return NULL; }
|
struct dentry *dentry, unsigned int flags) { return NULL; }
|
||||||
|
|
||||||
static const struct inode_operations iops
|
static const struct inode_operations iops
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue