mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-26 04:07:45 +03:00
Compare commits
100 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e25f9131d6 | |||
| 4e49d8ed27 | |||
| a969b1b22c | |||
| 18edf7a3ba | |||
| 33003ecc93 | |||
| 07cc8ae46a | |||
| e202d3b867 | |||
| 3d9f37026d | |||
| fc2c0256c5 | |||
| a69765ea5b | |||
| a164143dfd | |||
| c63b47e4da | |||
| 0e30635f9c | |||
| 777c98ee52 | |||
| 164d184ed9 | |||
| 3da577280a | |||
| 433b9a89c4 | |||
| 374f86b5c9 | |||
| 59f1875639 | |||
| aa7258ced0 | |||
| dedd8243fc | |||
| 43d63ab2d4 | |||
| bd9a9a4e1a | |||
| 5219a2691e | |||
| 48f376b0c5 | |||
| 345f8beb58 | |||
| a5c469c5f3 | |||
| 4b3133e671 | |||
| 4f6e0ca117 | |||
| 1d2aea7711 | |||
| 0a4e41d0fa | |||
| 050be02c02 | |||
| 576d34cb11 | |||
| 6281b5c488 | |||
| 231a37c4c0 | |||
| 9d2e5c14b2 | |||
| b644a45bd4 | |||
| fd0893cf1f | |||
| c8d36e2192 | |||
| edaa250bb3 | |||
| 04a6ae0585 | |||
| eb68e3cd56 | |||
| 2098a00318 | |||
| 82e3117095 | |||
| fce0f7aff4 | |||
| df18a44396 | |||
| 41fb4e071c | |||
| 7043742828 | |||
| aa256549d1 | |||
| 083239575a | |||
| 57159a519b | |||
| 8473829d1f | |||
| e45a981f6d | |||
| 5161e5d8a4 | |||
| 92e0d9d183 | |||
| 232fc23c6e | |||
| 11bdc5c8e8 | |||
| 04b02785b6 | |||
| f22254283a | |||
| 7319a73921 | |||
| 596cfb6b15 | |||
| f806306ce0 | |||
| f33b298346 | |||
| 04fcf13de0 | |||
| 37dbf91c8a | |||
| be697f4339 | |||
| c07a8660f0 | |||
| ea62fb4ab7 | |||
| 5aca6e1092 | |||
| d72e004715 | |||
| 9ef565a185 | |||
| 0e72f5fb83 | |||
| e9897e542d | |||
| 70b1b5bb98 | |||
| a2aabac123 | |||
| 3207803abf | |||
| 6219190d7f | |||
| 24a6d8316a | |||
| e23ed1b330 | |||
| 572114d846 | |||
| 6af8e80310 | |||
| f8a124b104 | |||
| 689c53f2c5 | |||
| 0156253d29 | |||
| 3e0962a236 | |||
| 3c0b8c874b | |||
| b586ea5d93 | |||
| 138d2b29dd | |||
| 5371d8dae7 | |||
| a75af541cf | |||
| 75fbe7eb99 | |||
| d0f350c962 | |||
| 2f2d6bece8 | |||
| fbbc375d43 | |||
| e84a2ed7a8 | |||
| f28c7302cb | |||
| 4767037bcf | |||
| d50ce5c9ec | |||
| 05732da4d1 | |||
| 8f7826f73b |
@@ -0,0 +1,57 @@
|
|||||||
|
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
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
pax-utils
|
||||||
|
shellcheck
|
||||||
@@ -6,20 +6,27 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
checkstyle:
|
checkstyle:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
# https://github.com/orgs/community/discussions/47863
|
||||||
sudo apt-get install --yes -qq build-essential autoconf libtool gawk alien fakeroot linux-headers-$(uname -r)
|
sudo apt-mark hold grub-efi-amd64-signed
|
||||||
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 update --fix-missing
|
||||||
# packages for tests
|
sudo apt-get upgrade
|
||||||
sudo apt-get install --yes -qq parted lsscsi ksh attr acl nfs-kernel-server fio
|
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
||||||
sudo apt-get install --yes -qq mandoc cppcheck pax-utils devscripts
|
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/checkstyle-dependencies.txt apt-get install -qq
|
||||||
sudo -E pip --quiet install flake8
|
sudo python3 -m pip install --quiet flake8
|
||||||
|
sudo apt-get clean
|
||||||
|
|
||||||
|
# confirm that the tools are installed
|
||||||
|
# the build system doesn't fail when they are not
|
||||||
|
flake8 --version
|
||||||
|
scanelf --version
|
||||||
|
shellcheck --version
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
sh ./autogen.sh
|
sh ./autogen.sh
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
#!/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,7 +9,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [18.04, 20.04]
|
os: [20.04, 22.04]
|
||||||
runs-on: ubuntu-${{ matrix.os }}
|
runs-on: ubuntu-${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@@ -17,17 +17,12 @@ jobs:
|
|||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
# https://github.com/orgs/community/discussions/47863
|
||||||
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
|
sudo apt-mark hold grub-efi-amd64-signed
|
||||||
git alien fakeroot wget curl bc fio acl \
|
sudo apt-get update --fix-missing
|
||||||
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
|
sudo apt-get upgrade
|
||||||
nfs-kernel-server samba rng-tools xz-utils \
|
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
||||||
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
|
sudo apt-get clean
|
||||||
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 python3-packaging \
|
|
||||||
libcurl4-openssl-dev
|
|
||||||
- name: Autogen.sh
|
- name: Autogen.sh
|
||||||
run: |
|
run: |
|
||||||
sh autogen.sh
|
sh autogen.sh
|
||||||
@@ -56,12 +51,13 @@ jobs:
|
|||||||
sudo udevadm control --reload-rules
|
sudo udevadm control --reload-rules
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
# Workaround to provide additional free space for testing.
|
- name: Clear the kernel ring buffer
|
||||||
# https://github.com/actions/virtual-environments/issues/2840
|
run: |
|
||||||
sudo rm -rf /usr/share/dotnet
|
sudo dmesg -c >/var/tmp/dmesg-prerun
|
||||||
sudo rm -rf /opt/ghc
|
- name: Reclaim and report disk space
|
||||||
sudo rm -rf "/usr/local/share/boost"
|
run: |
|
||||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
${{ 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 -vR -s 3G
|
||||||
@@ -71,7 +67,7 @@ jobs:
|
|||||||
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 $RESULTS_PATH/
|
sudo cp /var/log/syslog /var/tmp/dmesg-prerun $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 /var/tmp/test_results -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||||
@@ -79,5 +75,7 @@ jobs:
|
|||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: Test logs Ubuntu-${{ matrix.os }}
|
name: Test logs Ubuntu-${{ matrix.os }}
|
||||||
path: /var/tmp/test_results/20*/
|
path: |
|
||||||
|
/var/tmp/test_results/*
|
||||||
|
!/var/tmp/test_results/current
|
||||||
if-no-files-found: ignore
|
if-no-files-found: ignore
|
||||||
|
|||||||
@@ -6,24 +6,19 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
# https://github.com/orgs/community/discussions/47863
|
||||||
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
|
sudo apt-mark hold grub-efi-amd64-signed
|
||||||
git alien fakeroot wget curl bc fio acl \
|
sudo apt-get update --fix-missing
|
||||||
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
|
sudo apt-get upgrade
|
||||||
nfs-kernel-server samba rng-tools xz-utils \
|
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
||||||
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
|
sudo apt-get clean
|
||||||
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 python3-packaging \
|
|
||||||
libcurl4-openssl-dev
|
|
||||||
- name: Autogen.sh
|
- name: Autogen.sh
|
||||||
run: |
|
run: |
|
||||||
sh autogen.sh
|
sh autogen.sh
|
||||||
@@ -52,12 +47,13 @@ jobs:
|
|||||||
sudo udevadm control --reload-rules
|
sudo udevadm control --reload-rules
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
# Workaround to provide additional free space for testing.
|
- name: Clear the kernel ring buffer
|
||||||
# https://github.com/actions/virtual-environments/issues/2840
|
run: |
|
||||||
sudo rm -rf /usr/share/dotnet
|
sudo dmesg -c >/var/tmp/dmesg-prerun
|
||||||
sudo rm -rf /opt/ghc
|
- name: Reclaim and report disk space
|
||||||
sudo rm -rf "/usr/local/share/boost"
|
run: |
|
||||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
${{ 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 -vR -s 3G -r sanity
|
||||||
@@ -67,13 +63,15 @@ jobs:
|
|||||||
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 $RESULTS_PATH/
|
sudo cp /var/log/syslog /var/tmp/dmesg-prerun $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 /var/tmp/test_results -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: Test logs
|
name: Test logs Ubuntu-${{ matrix.os }}
|
||||||
path: /var/tmp/test_results/20*/
|
path: |
|
||||||
|
/var/tmp/test_results/*
|
||||||
|
!/var/tmp/test_results/current
|
||||||
if-no-files-found: ignore
|
if-no-files-found: ignore
|
||||||
|
|||||||
+10
-12
@@ -6,7 +6,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
env:
|
env:
|
||||||
TEST_DIR: /var/tmp/zloop
|
TEST_DIR: /var/tmp/zloop
|
||||||
steps:
|
steps:
|
||||||
@@ -15,15 +15,12 @@ jobs:
|
|||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
# https://github.com/orgs/community/discussions/47863
|
||||||
sudo apt-get install --yes -qq build-essential autoconf libtool gdb \
|
sudo apt-mark hold grub-efi-amd64-signed
|
||||||
git alien fakeroot \
|
sudo apt-get update --fix-missing
|
||||||
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
|
sudo apt-get upgrade
|
||||||
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
||||||
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
|
sudo apt-get clean
|
||||||
libpam0g-dev \
|
|
||||||
python-dev python-setuptools python-cffi python-packaging \
|
|
||||||
python3 python3-dev python3-setuptools python3-cffi python3-packaging
|
|
||||||
- name: Autogen.sh
|
- name: Autogen.sh
|
||||||
run: |
|
run: |
|
||||||
sh autogen.sh
|
sh autogen.sh
|
||||||
@@ -44,8 +41,9 @@ jobs:
|
|||||||
- name: Tests
|
- name: Tests
|
||||||
run: |
|
run: |
|
||||||
sudo mkdir -p $TEST_DIR
|
sudo mkdir -p $TEST_DIR
|
||||||
# run for 20 minutes to have a total runner time of 30 minutes
|
# run for 10 minutes or at most 2 iterations for a maximum runner
|
||||||
sudo /usr/share/zfs/zloop.sh -t 1200 -l -m1 -- -T 120 -P 60
|
# time of 20 minutes.
|
||||||
|
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: |
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
The [OpenZFS Code of Conduct](http://www.open-zfs.org/wiki/Code_of_Conduct)
|
The [OpenZFS Code of Conduct](https://openzfs.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.
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
Meta: 1
|
Meta: 1
|
||||||
Name: zfs
|
Name: zfs
|
||||||
Branch: 1.0
|
Branch: 1.0
|
||||||
Version: 2.1.7
|
Version: 2.1.11
|
||||||
Release: 1
|
Release: 1
|
||||||
Release-Tags: relext
|
Release-Tags: relext
|
||||||
License: CDDL
|
License: CDDL
|
||||||
Author: OpenZFS
|
Author: OpenZFS
|
||||||
Linux-Maximum: 6.0
|
Linux-Maximum: 6.2
|
||||||
Linux-Minimum: 3.10
|
Linux-Minimum: 3.10
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
bin_SCRIPTS = arc_summary
|
bin_SCRIPTS = arc_summary
|
||||||
|
|
||||||
CLEANFILES = arc_summary
|
CLEANFILES = arc_summary
|
||||||
EXTRA_DIST = arc_summary2 arc_summary3
|
EXTRA_DIST = 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,21 +191,13 @@ 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",
|
||||||
|
|||||||
@@ -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 2.6+ and Python 3.4+.
|
# This script must remain compatible with Python 3.6+.
|
||||||
#
|
#
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -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 Python 2.6+ and Python 3.4+.
|
# This script must remain compatible with and Python 3.6+.
|
||||||
#
|
#
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
+40
-16
@@ -80,6 +80,7 @@ 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.
|
||||||
@@ -100,7 +101,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +110,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,6 +127,21 @@ 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);
|
||||||
}
|
}
|
||||||
@@ -148,13 +164,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) {
|
if (gsp->gs_vdev_guid && gsp->gs_devid) {
|
||||||
(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_vdev_guid != 0);
|
return (gsp->gs_devid != NULL && gsp->gs_vdev_guid != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -195,11 +211,13 @@ 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);
|
||||||
|
|
||||||
@@ -209,20 +227,24 @@ 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 (pool_guid == 0 || vdev_guid == 0) {
|
if (devid == NULL || pool_guid == 0 || vdev_guid == 0) {
|
||||||
if ((nvlist_lookup_string(nvl, DEV_IDENTIFIER,
|
if (devid == NULL)
|
||||||
&search.gs_devid) == 0) &&
|
search.gs_vdev_guid = vdev_guid;
|
||||||
(zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search)
|
else
|
||||||
== 1)) {
|
search.gs_devid = devid;
|
||||||
if (pool_guid == 0)
|
zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search);
|
||||||
pool_guid = search.gs_pool_guid;
|
if (devid == NULL)
|
||||||
if (vdev_guid == 0)
|
devid = search.gs_devid;
|
||||||
vdev_guid = search.gs_vdev_guid;
|
if (pool_guid == 0)
|
||||||
devtype = search.gs_vdev_type;
|
pool_guid = search.gs_pool_guid;
|
||||||
}
|
if (vdev_guid == 0)
|
||||||
|
vdev_guid = search.gs_vdev_guid;
|
||||||
|
devtype = search.gs_vdev_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -235,7 +257,9 @@ 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,
|
||||||
search.gs_devid);
|
devid);
|
||||||
|
fnvlist_free(payload);
|
||||||
|
free(event);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+36
-11
@@ -185,10 +185,12 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
uint64_t wholedisk = 0ULL;
|
uint64_t wholedisk = 0ULL;
|
||||||
uint64_t offline = 0ULL, faulted = 0ULL;
|
uint64_t offline = 0ULL, faulted = 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_sd = B_FALSE;
|
boolean_t is_sd = B_FALSE;
|
||||||
boolean_t is_mpath_wholedisk = B_FALSE;
|
boolean_t is_mpath_wholedisk = B_FALSE;
|
||||||
uint_t c;
|
uint_t c;
|
||||||
@@ -214,6 +216,7 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_FAULTED, &faulted);
|
(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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special case:
|
* Special case:
|
||||||
@@ -304,11 +307,13 @@ 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,
|
if (zpool_vdev_online(zhp, fullpath, online_flag, &newstate) == 0 &&
|
||||||
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,
|
||||||
@@ -525,7 +530,9 @@ 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
|
||||||
@@ -535,6 +542,8 @@ 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.
|
||||||
@@ -560,19 +569,16 @@ 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)
|
if (dp->dd_found && dp->dd_num_spares == 0)
|
||||||
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) {
|
||||||
uint64_t guid;
|
if (guid != dp->dd_vdev_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;
|
||||||
|
|
||||||
@@ -582,6 +588,12 @@ 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) {
|
||||||
@@ -589,6 +601,12 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
|||||||
__func__, dp->dd_compare, path);
|
__func__, dp->dd_compare, path);
|
||||||
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);
|
||||||
@@ -601,6 +619,10 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,7 +683,9 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -670,7 +694,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)
|
boolean_t is_slice, uint64_t new_vdev_guid)
|
||||||
{
|
{
|
||||||
dev_data_t data = { 0 };
|
dev_data_t data = { 0 };
|
||||||
|
|
||||||
@@ -680,6 +704,7 @@ 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);
|
(void) zpool_iter(g_zfshdl, zfs_iter_pool, &data);
|
||||||
|
|
||||||
@@ -848,7 +873,7 @@ zfs_deliver_add(nvlist_t *nvl, boolean_t is_lofi)
|
|||||||
if (devid_iter(devid, zfs_process_add, is_slice))
|
if (devid_iter(devid, zfs_process_add, is_slice))
|
||||||
return (0);
|
return (0);
|
||||||
if (devpath != NULL && devphys_iter(devpath, devid, zfs_process_add,
|
if (devpath != NULL && devphys_iter(devpath, devid, zfs_process_add,
|
||||||
is_slice))
|
is_slice, vdev_guid))
|
||||||
return (0);
|
return (0);
|
||||||
if (vdev_guid != 0)
|
if (vdev_guid != 0)
|
||||||
(void) guid_iter(pool_guid, vdev_guid, devid, zfs_process_add,
|
(void) guid_iter(pool_guid, vdev_guid, devid, zfs_process_add,
|
||||||
|
|||||||
+105
-10
@@ -75,6 +75,8 @@ 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
|
||||||
@@ -140,6 +142,64 @@ 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.
|
||||||
*/
|
*/
|
||||||
@@ -315,6 +375,8 @@ 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;
|
||||||
@@ -323,6 +385,8 @@ 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);
|
||||||
|
|
||||||
@@ -339,10 +403,26 @@ 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 (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,
|
||||||
@@ -351,13 +431,28 @@ 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);
|
||||||
|
|
||||||
/* Can't replace l2arc with a spare: offline the device */
|
nvlist_lookup_uint64_array(vdev, ZPOOL_CONFIG_VDEV_STATS,
|
||||||
if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE,
|
(uint64_t **)&vs, &c);
|
||||||
&devtype) == 0 && strcmp(devtype, VDEV_TYPE_L2CACHE) == 0) {
|
|
||||||
fmd_hdl_debug(hdl, "zpool_vdev_offline '%s'", devname);
|
/*
|
||||||
zpool_vdev_offline(zhp, devname, B_TRUE);
|
* If state removed is requested for already removed vdev,
|
||||||
} else if (!fmd_prop_get_int32(hdl, "spare_on_remove") ||
|
* its a loopback event from spa_async_remove(). Just
|
||||||
replace_with_spare(hdl, zhp, vdev) == B_FALSE) {
|
* ignore it.
|
||||||
|
*/
|
||||||
|
if (vs->vs_state == VDEV_STATE_REMOVED &&
|
||||||
|
state == VDEV_STATE_REMOVED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Remove the vdev since device is unplugged */
|
||||||
|
if (l2arc || (strcmp(class, "resource.fs.zfs.removed") == 0)) {
|
||||||
|
int status = zpool_vdev_remove_wanted(zhp, devname);
|
||||||
|
fmd_hdl_debug(hdl, "zpool_vdev_remove_wanted '%s'"
|
||||||
|
", ret:%d", devname, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replace the vdev with a spare if its not a l2arc */
|
||||||
|
if (!l2arc && (!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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ if [ "${ZEVENT_VDEV_STATE_STR}" != "FAULTED" ] \
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
umask 077
|
umask 077
|
||||||
note_subject="ZFS device fault for pool ${ZEVENT_POOL_GUID} on $(hostname)"
|
note_subject="ZFS device fault for pool ${ZEVENT_POOL} on $(hostname)"
|
||||||
note_pathname="$(mktemp)"
|
note_pathname="$(mktemp)"
|
||||||
{
|
{
|
||||||
if [ "${ZEVENT_VDEV_STATE_STR}" = "FAULTED" ] ; then
|
if [ "${ZEVENT_VDEV_STATE_STR}" = "FAULTED" ] ; then
|
||||||
@@ -65,7 +65,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_GUID}"
|
echo " pool: ${ZEVENT_POOL} (${ZEVENT_POOL_GUID})"
|
||||||
|
|
||||||
} > "${note_pathname}"
|
} > "${note_pathname}"
|
||||||
|
|
||||||
|
|||||||
+56
-7
@@ -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 [-DnPpRvLecwhb] [-[i|I] snapshot] "
|
return (gettext("\tsend [-DnPpRVvLecwhb] [-[i|I] snapshot] "
|
||||||
"<snapshot>\n"
|
"<snapshot>\n"
|
||||||
"\tsend [-DnvPLecw] [-i snapshot|bookmark] "
|
"\tsend [-DnVvPLecw] [-i snapshot|bookmark] "
|
||||||
"<filesystem|volume|snapshot>\n"
|
"<filesystem|volume|snapshot>\n"
|
||||||
"\tsend [-DnPpvLec] [-i bookmark|snapshot] "
|
"\tsend [-DnPpVvLec] [-i bookmark|snapshot] "
|
||||||
"--redact <bookmark> <snapshot>\n"
|
"--redact <bookmark> <snapshot>\n"
|
||||||
"\tsend [-nvPe] -t <receive_resume_token>\n"
|
"\tsend [-nVvPe] -t <receive_resume_token>\n"
|
||||||
"\tsend [-Pnv] --saved filesystem\n"));
|
"\tsend [-PnVv] --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"));
|
||||||
@@ -3474,6 +3474,8 @@ 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(" ");
|
||||||
@@ -3500,9 +3502,31 @@ 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.
|
||||||
@@ -3565,6 +3589,22 @@ 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
|
||||||
@@ -3576,6 +3616,9 @@ 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");
|
||||||
@@ -4407,6 +4450,7 @@ 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'},
|
||||||
@@ -4421,7 +4465,7 @@ zfs_do_send(int argc, char **argv)
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt_long(argc, argv, ":i:I:RsDpvnPLeht:cwbd:S",
|
while ((c = getopt_long(argc, argv, ":i:I:RsDpVvnPLeht:cwbd:S",
|
||||||
long_options, NULL)) != -1) {
|
long_options, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'i':
|
case 'i':
|
||||||
@@ -4456,6 +4500,9 @@ 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;
|
||||||
@@ -4531,7 +4578,7 @@ zfs_do_send(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags.parsable && flags.verbosity == 0)
|
if ((flags.parsable || flags.progressastitle) && flags.verbosity == 0)
|
||||||
flags.verbosity = 1;
|
flags.verbosity = 1;
|
||||||
|
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
@@ -8693,6 +8740,8 @@ 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.
|
||||||
|
|||||||
+43
-2
@@ -4205,6 +4205,8 @@ 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) {
|
||||||
@@ -4238,6 +4240,8 @@ 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");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4247,6 +4251,37 @@ 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.
|
||||||
@@ -4262,7 +4297,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
|
||||||
printf(" %*s", column_size, buf);
|
print_stat_color(buf, column_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5414,7 +5449,13 @@ 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) {
|
||||||
sprintf(fullpath, "%s/%s", dirpath, ent->d_name);
|
if (snprintf(fullpath, sizeof (fullpath), "%s/%s",
|
||||||
|
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)
|
||||||
|
|||||||
+1
-1
@@ -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);
|
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE, B_FALSE);
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
|
||||||
(void) kill(getpid(), SIGKILL);
|
(void) kill(getpid(), SIGKILL);
|
||||||
|
|||||||
+6
-19
@@ -1,7 +1,6 @@
|
|||||||
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 2.6 and Python 3.4. Therefore, they may be installed
|
dnl # with Python 3.6. This option is intended to
|
||||||
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 #
|
||||||
@@ -13,9 +12,7 @@ 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 python2], [:])],
|
[check], [AC_CHECK_PROGS([PYTHON], [python3], [:])],
|
||||||
[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=":"],
|
||||||
@@ -23,8 +20,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYTHON], [
|
|||||||
)
|
)
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Minimum supported Python versions for utilities:
|
dnl # Minimum supported Python versions for utilities: Python 3.6
|
||||||
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"], [
|
||||||
@@ -33,25 +29,16 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYTHON], [
|
|||||||
PYTHON_MINOR=${PYTHON_VERSION#*\.}
|
PYTHON_MINOR=${PYTHON_VERSION#*\.}
|
||||||
|
|
||||||
AS_CASE([$PYTHON_VERSION],
|
AS_CASE([$PYTHON_VERSION],
|
||||||
[2.*], [
|
|
||||||
AS_IF([test $PYTHON_MINOR -lt 6],
|
|
||||||
[AC_MSG_ERROR("Python >= 2.6 is required")])
|
|
||||||
],
|
|
||||||
[3.*], [
|
[3.*], [
|
||||||
AS_IF([test $PYTHON_MINOR -lt 4],
|
AS_IF([test $PYTHON_MINOR -lt 6],
|
||||||
[AC_MSG_ERROR("Python >= 3.4 is required")])
|
[AC_MSG_ERROR("Python >= 3.6 is required")])
|
||||||
],
|
],
|
||||||
[:|2|3], [],
|
[:|2|3], [],
|
||||||
[PYTHON_VERSION=3]
|
[PYTHON_VERSION=3]
|
||||||
)
|
)
|
||||||
|
|
||||||
AM_CONDITIONAL([USING_PYTHON], [test "$PYTHON" != :])
|
AM_CONDITIONAL([USING_PYTHON], [test "$PYTHON" != :])
|
||||||
AM_CONDITIONAL([USING_PYTHON_2], [test "x${PYTHON_VERSION%%\.*}" = x2])
|
AC_SUBST([PYTHON_SHEBANG], [python3])
|
||||||
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.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ AC_DEFUN([ZFS_AC_PYTHON_MODULE], [
|
|||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Determines if pyzfs can be built, requires Python 2.7 or later.
|
dnl # Determines if pyzfs can be built, requires Python 3.6 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],
|
||||||
@@ -72,12 +72,11 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
|||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Require python-devel libraries
|
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.4.0'"],
|
[3.*], [PYTHON_REQUIRED_VERSION=">= '3.6.0'"],
|
||||||
[2.*], [PYTHON_REQUIRED_VERSION=">= '2.7.0'"],
|
|
||||||
[AC_MSG_ERROR("Python $PYTHON_VERSION unknown")]
|
[AC_MSG_ERROR("Python $PYTHON_VERSION unknown")]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+35
-36
@@ -97,23 +97,13 @@ AC_DEFUN([AX_PYTHON_DEVEL],[
|
|||||||
# Check for a version of Python >= 2.1.0
|
# Check for a version of Python >= 2.1.0
|
||||||
#
|
#
|
||||||
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
|
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
|
||||||
ac_supports_python_ver=`cat<<EOD | $PYTHON -
|
ac_supports_python_ver=`$PYTHON -c "import sys; \
|
||||||
from __future__ import print_function;
|
ver = sys.version.split ()[[0]]; \
|
||||||
import sys;
|
print (ver >= '2.1.0')"`
|
||||||
try:
|
|
||||||
from packaging import version;
|
|
||||||
except ImportError:
|
|
||||||
from distlib import version;
|
|
||||||
ver = sys.version.split ()[[0]];
|
|
||||||
(tst_cmp, tst_ver) = ">= '2.1.0'".split ();
|
|
||||||
tst_ver = tst_ver.strip ("'");
|
|
||||||
eval ("print (version.LegacyVersion (ver)"+ tst_cmp +"version.LegacyVersion (tst_ver))")
|
|
||||||
EOD`
|
|
||||||
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
|
||||||
2.1.0. You may need to re-run configure, setting the
|
2.1.0. You may need to re-run configure, setting the
|
||||||
@@ -122,7 +112,6 @@ 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])
|
||||||
fi
|
fi
|
||||||
@@ -131,37 +120,47 @@ 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])
|
||||||
# Why the strip ()? Because if we don't, version.parse
|
cat << EOF > ax_python_devel_vpy.py
|
||||||
# will, for example, report 3.10.0 >= '3.11.0'
|
class VPy:
|
||||||
ac_supports_python_ver=`cat<<EOD | $PYTHON -
|
def vtup(self, s):
|
||||||
|
return tuple(map(int, s.strip().replace("rc", ".").split(".")))
|
||||||
from __future__ import print_function;
|
def __init__(self):
|
||||||
import sys;
|
import sys
|
||||||
try:
|
self.vpy = tuple(sys.version_info)
|
||||||
from packaging import version;
|
def __eq__(self, s):
|
||||||
except ImportError:
|
return self.vpy == self.vtup(s)
|
||||||
from distlib import version;
|
def __ne__(self, s):
|
||||||
ver = sys.version.split ()[[0]];
|
return self.vpy != self.vtup(s)
|
||||||
(tst_cmp, tst_ver) = "$1".split ();
|
def __lt__(self, s):
|
||||||
tst_ver = tst_ver.strip ("'");
|
return self.vpy < self.vtup(s)
|
||||||
eval ("print (version.LegacyVersion (ver)"+ tst_cmp +"version.LegacyVersion (tst_ver))")
|
def __gt__(self, s):
|
||||||
EOD`
|
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)"`
|
||||||
|
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
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -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; \
|
||||||
|
|||||||
+46
-4
@@ -165,6 +165,9 @@ dnl #
|
|||||||
dnl # 5.15 API change,
|
dnl # 5.15 API change,
|
||||||
dnl # Added the bool rcu argument to get_acl for rcu path walk.
|
dnl # Added the bool rcu argument to get_acl for rcu path walk.
|
||||||
dnl #
|
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>
|
||||||
@@ -189,6 +192,18 @@ 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_inode_acl], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
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], [
|
||||||
@@ -201,7 +216,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
|
|||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_GET_ACL_RCU, 1, [iops->get_acl() takes rcu])
|
AC_DEFINE(HAVE_GET_ACL_RCU, 1, [iops->get_acl() takes rcu])
|
||||||
],[
|
],[
|
||||||
ZFS_LINUX_TEST_ERROR([iops->get_acl()])
|
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()])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
@@ -213,7 +233,22 @@ 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 #
|
||||||
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_userns_dentry], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
@@ -246,11 +281,18 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
|
|||||||
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], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl_userns_dentry], [
|
||||||
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])
|
||||||
|
AC_DEFINE(HAVE_SET_ACL_USERNS_DENTRY_ARG2, 1,
|
||||||
|
[iops->set_acl() takes 4 args, arg2 is struct dentry *])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists, takes 3 args])
|
||||||
|
],[
|
||||||
|
ZFS_LINUX_REQUIRE_API([i_op->set_acl()], [3.14])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -103,6 +103,57 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_CHECK_DISK_CHANGE], [
|
|||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
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
|
||||||
@@ -405,6 +456,8 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
|
|||||||
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_BDEVNAME
|
||||||
ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_SECURE_ERASE
|
ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_SECURE_ERASE
|
||||||
|
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_KOBJ
|
||||||
|
ZFS_AC_KERNEL_SRC_BLKDEV_PART_TO_DEV
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
|
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
|
||||||
@@ -421,4 +474,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
|
|||||||
ZFS_AC_KERNEL_BLKDEV_BDEVNAME
|
ZFS_AC_KERNEL_BLKDEV_BDEVNAME
|
||||||
ZFS_AC_KERNEL_BLKDEV_GET_ERESTARTSYS
|
ZFS_AC_KERNEL_BLKDEV_GET_ERESTARTSYS
|
||||||
ZFS_AC_KERNEL_BLKDEV_ISSUE_SECURE_ERASE
|
ZFS_AC_KERNEL_BLKDEV_ISSUE_SECURE_ERASE
|
||||||
|
ZFS_AC_KERNEL_BLKDEV_BDEV_KOBJ
|
||||||
|
ZFS_AC_KERNEL_BLKDEV_PART_TO_DEV
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -2,7 +2,20 @@ 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], [
|
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>
|
#include <linux/blkdev.h>
|
||||||
], [
|
], [
|
||||||
struct block_device *bdev = NULL;
|
struct block_device *bdev = NULL;
|
||||||
@@ -63,74 +76,85 @@ 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 #
|
||||||
dnl # 5.19 API,
|
dnl # Linux 6.3, and then backports thereof, changed
|
||||||
|
dnl # the signatures on bdev_start_io_acct/bdev_end_io_acct
|
||||||
dnl #
|
dnl #
|
||||||
dnl # disk_start_io_acct() and disk_end_io_acct() have been replaced by
|
AC_MSG_CHECKING([whether 6.3+ bdev_*_io_acct() are available])
|
||||||
dnl # bdev_start_io_acct() and bdev_end_io_acct().
|
ZFS_LINUX_TEST_RESULT([bdev_io_acct_63], [
|
||||||
dnl #
|
|
||||||
AC_MSG_CHECKING([whether generic bdev_*_io_acct() are available])
|
|
||||||
ZFS_LINUX_TEST_RESULT([bdev_io_acct], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_BDEV_IO_ACCT, 1, [bdev_*_io_acct() available])
|
AC_DEFINE(HAVE_BDEV_IO_ACCT_63, 1, [bdev_*_io_acct() available])
|
||||||
], [
|
], [
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 5.12 API,
|
dnl # 5.19 API,
|
||||||
dnl #
|
dnl #
|
||||||
dnl # bio_start_io_acct() and bio_end_io_acct() became GPL-exported
|
dnl # disk_start_io_acct() and disk_end_io_acct() have been replaced by
|
||||||
dnl # so use disk_start_io_acct() and disk_end_io_acct() instead
|
dnl # bdev_start_io_acct() and bdev_end_io_acct().
|
||||||
dnl #
|
dnl #
|
||||||
AC_MSG_CHECKING([whether generic disk_*_io_acct() are available])
|
AC_MSG_CHECKING([whether pre-6.3 bdev_*_io_acct() are available])
|
||||||
ZFS_LINUX_TEST_RESULT([disk_io_acct], [
|
ZFS_LINUX_TEST_RESULT([bdev_io_acct_old], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_DISK_IO_ACCT, 1, [disk_*_io_acct() available])
|
AC_DEFINE(HAVE_BDEV_IO_ACCT_OLD, 1, [bdev_*_io_acct() available])
|
||||||
], [
|
], [
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 5.7 API,
|
dnl # 5.12 API,
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Added bio_start_io_acct() and bio_end_io_acct() helpers.
|
dnl # bio_start_io_acct() and bio_end_io_acct() became GPL-exported
|
||||||
|
dnl # so use disk_start_io_acct() and disk_end_io_acct() instead
|
||||||
dnl #
|
dnl #
|
||||||
AC_MSG_CHECKING([whether generic bio_*_io_acct() are available])
|
AC_MSG_CHECKING([whether generic disk_*_io_acct() are available])
|
||||||
ZFS_LINUX_TEST_RESULT([bio_io_acct], [
|
ZFS_LINUX_TEST_RESULT([disk_io_acct], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_BIO_IO_ACCT, 1, [bio_*_io_acct() available])
|
AC_DEFINE(HAVE_DISK_IO_ACCT, 1, [disk_*_io_acct() available])
|
||||||
], [
|
], [
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 4.14 API,
|
dnl # 5.7 API,
|
||||||
dnl #
|
dnl #
|
||||||
dnl # generic_start_io_acct/generic_end_io_acct now require
|
dnl # Added bio_start_io_acct() and bio_end_io_acct() helpers.
|
||||||
dnl # request_queue to be provided. No functional changes,
|
|
||||||
dnl # but preparation for inflight accounting.
|
|
||||||
dnl #
|
dnl #
|
||||||
AC_MSG_CHECKING([whether generic_*_io_acct wants 4 args])
|
AC_MSG_CHECKING([whether generic bio_*_io_acct() are available])
|
||||||
ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_4args],
|
ZFS_LINUX_TEST_RESULT([bio_io_acct], [
|
||||||
[generic_start_io_acct], [block/bio.c], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_GENERIC_IO_ACCT_4ARG, 1,
|
AC_DEFINE(HAVE_BIO_IO_ACCT, 1, [bio_*_io_acct() available])
|
||||||
[generic_*_io_acct() 4 arg available])
|
|
||||||
], [
|
], [
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 3.19 API addition
|
dnl # 4.14 API,
|
||||||
dnl #
|
dnl #
|
||||||
dnl # torvalds/linux@394ffa50 allows us to increment
|
dnl # generic_start_io_acct/generic_end_io_acct now require
|
||||||
dnl # iostat counters without generic_make_request().
|
dnl # request_queue to be provided. No functional changes,
|
||||||
|
dnl # but preparation for inflight accounting.
|
||||||
dnl #
|
dnl #
|
||||||
AC_MSG_CHECKING(
|
AC_MSG_CHECKING([whether generic_*_io_acct wants 4 args])
|
||||||
[whether generic_*_io_acct wants 3 args])
|
ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_4args],
|
||||||
ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_3args],
|
|
||||||
[generic_start_io_acct], [block/bio.c], [
|
[generic_start_io_acct], [block/bio.c], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_GENERIC_IO_ACCT_3ARG, 1,
|
AC_DEFINE(HAVE_GENERIC_IO_ACCT_4ARG, 1,
|
||||||
[generic_*_io_acct() 3 arg available])
|
[generic_*_io_acct() 4 arg available])
|
||||||
], [
|
], [
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # 3.19 API addition
|
||||||
|
dnl #
|
||||||
|
dnl # torvalds/linux@394ffa50 allows us to increment
|
||||||
|
dnl # iostat counters without generic_make_request().
|
||||||
|
dnl #
|
||||||
|
AC_MSG_CHECKING(
|
||||||
|
[whether generic_*_io_acct wants 3 args])
|
||||||
|
ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_3args],
|
||||||
|
[generic_start_io_acct], [block/bio.c], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_GENERIC_IO_ACCT_3ARG, 1,
|
||||||
|
[generic_*_io_acct() 3 arg available])
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -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" | egrep -qx $1)],[
|
"${srcdir}/scripts/enum-extract.pl" "$2" "$3" | grep -Eqx $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])
|
||||||
|
|||||||
@@ -3,11 +3,25 @@ dnl # 3.11 API change
|
|||||||
dnl # Add support for i_op->tmpfile
|
dnl # Add support for i_op->tmpfile
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
|
||||||
|
dnl #
|
||||||
|
dnl # 6.1 API change
|
||||||
|
dnl # use struct file instead of struct dentry
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
int tmpfile(struct user_namespace *userns,
|
||||||
|
struct inode *inode, struct file *file,
|
||||||
|
umode_t mode) { return 0; }
|
||||||
|
static struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.tmpfile = tmpfile,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 5.11 API change
|
dnl # 5.11 API change
|
||||||
dnl # add support for userns parameter to tmpfile
|
dnl # add support for userns parameter to tmpfile
|
||||||
dnl #
|
dnl #
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile_userns], [
|
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile_dentry_userns], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
int tmpfile(struct user_namespace *userns,
|
int tmpfile(struct user_namespace *userns,
|
||||||
struct inode *inode, struct dentry *dentry,
|
struct inode *inode, struct dentry *dentry,
|
||||||
@@ -17,7 +31,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
|
|||||||
.tmpfile = tmpfile,
|
.tmpfile = tmpfile,
|
||||||
};
|
};
|
||||||
],[])
|
],[])
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [
|
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile_dentry], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
int tmpfile(struct inode *inode, struct dentry *dentry,
|
int tmpfile(struct inode *inode, struct dentry *dentry,
|
||||||
umode_t mode) { return 0; }
|
umode_t mode) { return 0; }
|
||||||
@@ -30,16 +44,24 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
|
|||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
|
AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
|
||||||
AC_MSG_CHECKING([whether i_op->tmpfile() exists])
|
AC_MSG_CHECKING([whether i_op->tmpfile() exists])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_userns], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
|
AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
|
||||||
AC_DEFINE(HAVE_TMPFILE_USERNS, 1, [i_op->tmpfile() has userns])
|
AC_DEFINE(HAVE_TMPFILE_USERNS, 1, [i_op->tmpfile() has userns])
|
||||||
],[
|
],[
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_dentry_userns], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
|
AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
|
||||||
|
AC_DEFINE(HAVE_TMPFILE_USERNS, 1, [i_op->tmpfile() has userns])
|
||||||
|
AC_DEFINE(HAVE_TMPFILE_DENTRY, 1, [i_op->tmpfile() uses old dentry signature])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_dentry], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
|
||||||
|
AC_DEFINE(HAVE_TMPFILE_DENTRY, 1, [i_op->tmpfile() uses old dentry signature])
|
||||||
|
],[
|
||||||
|
ZFS_LINUX_REQUIRE_API([i_op->tmpfile()], [3.11])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|||||||
+35
-3
@@ -404,11 +404,11 @@ AC_DEFUN([ZFS_AC_KERNEL], [
|
|||||||
utsrelease1=$kernelbuild/include/linux/version.h
|
utsrelease1=$kernelbuild/include/linux/version.h
|
||||||
utsrelease2=$kernelbuild/include/linux/utsrelease.h
|
utsrelease2=$kernelbuild/include/linux/utsrelease.h
|
||||||
utsrelease3=$kernelbuild/include/generated/utsrelease.h
|
utsrelease3=$kernelbuild/include/generated/utsrelease.h
|
||||||
AS_IF([test -r $utsrelease1 && fgrep -q UTS_RELEASE $utsrelease1], [
|
AS_IF([test -r $utsrelease1 && grep -qF UTS_RELEASE $utsrelease1], [
|
||||||
utsrelease=$utsrelease1
|
utsrelease=$utsrelease1
|
||||||
], [test -r $utsrelease2 && fgrep -q UTS_RELEASE $utsrelease2], [
|
], [test -r $utsrelease2 && grep -qF UTS_RELEASE $utsrelease2], [
|
||||||
utsrelease=$utsrelease2
|
utsrelease=$utsrelease2
|
||||||
], [test -r $utsrelease3 && fgrep -q UTS_RELEASE $utsrelease3], [
|
], [test -r $utsrelease3 && grep -qF UTS_RELEASE $utsrelease3], [
|
||||||
utsrelease=$utsrelease3
|
utsrelease=$utsrelease3
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -946,3 +946,35 @@ AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER], [
|
|||||||
[test -f build/conftest/conftest.ko], [$3], [$4], [$5])
|
[test -f build/conftest/conftest.ko], [$3], [$4], [$5])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # AS_VERSION_COMPARE_LE
|
||||||
|
dnl # like AS_VERSION_COMPARE_LE, but runs $3 if (and only if) $1 <= $2
|
||||||
|
dnl # AS_VERSION_COMPARE_LE (version-1, version-2, [action-if-less-or-equal], [action-if-greater])
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([AS_VERSION_COMPARE_LE], [
|
||||||
|
AS_VERSION_COMPARE([$1], [$2], [$3], [$3], [$4])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # ZFS_LINUX_REQUIRE_API
|
||||||
|
dnl # like ZFS_LINUX_TEST_ERROR, except only fails if the kernel is
|
||||||
|
dnl # at least some specified version.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_LINUX_REQUIRE_API], [
|
||||||
|
AS_VERSION_COMPARE_LE([$2], [$kernsrcver], [
|
||||||
|
AC_MSG_ERROR([
|
||||||
|
*** None of the expected "$1" interfaces were detected. This
|
||||||
|
*** interface is expected for kernels version "$2" and above.
|
||||||
|
*** This may be because your kernel version is newer than what is
|
||||||
|
*** supported, or you are using a patched custom kernel with
|
||||||
|
*** incompatible modifications. Newer kernels may have incompatible
|
||||||
|
*** APIs.
|
||||||
|
***
|
||||||
|
*** ZFS Version: $ZFS_META_ALIAS
|
||||||
|
*** Compatible Kernels: $ZFS_META_KVER_MIN - $ZFS_META_KVER_MAX
|
||||||
|
])
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|||||||
+10
-27
@@ -173,7 +173,7 @@ AC_DEFUN([ZFS_AC_DEBUG_KMEM_TRACKING], [
|
|||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_DEBUG_INVARIANTS_DETECT_FREEBSD], [
|
AC_DEFUN([ZFS_AC_DEBUG_INVARIANTS_DETECT_FREEBSD], [
|
||||||
AS_IF([sysctl -n kern.conftxt | fgrep -qx $'options\tINVARIANTS'],
|
AS_IF([sysctl -n kern.conftxt | grep -Fqx $'options\tINVARIANTS'],
|
||||||
[enable_invariants="yes"],
|
[enable_invariants="yes"],
|
||||||
[enable_invariants="no"])
|
[enable_invariants="no"])
|
||||||
])
|
])
|
||||||
@@ -518,6 +518,8 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
|
|||||||
VENDOR=alpine ;
|
VENDOR=alpine ;
|
||||||
elif test -f /bin/freebsd-version ; then
|
elif test -f /bin/freebsd-version ; then
|
||||||
VENDOR=freebsd ;
|
VENDOR=freebsd ;
|
||||||
|
elif test -f /etc/openEuler-release ; then
|
||||||
|
VENDOR=openeuler ;
|
||||||
else
|
else
|
||||||
VENDOR= ;
|
VENDOR= ;
|
||||||
fi],
|
fi],
|
||||||
@@ -542,6 +544,7 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
|
|||||||
ubuntu) DEFAULT_PACKAGE=deb ;;
|
ubuntu) DEFAULT_PACKAGE=deb ;;
|
||||||
debian) DEFAULT_PACKAGE=deb ;;
|
debian) DEFAULT_PACKAGE=deb ;;
|
||||||
freebsd) DEFAULT_PACKAGE=pkg ;;
|
freebsd) DEFAULT_PACKAGE=pkg ;;
|
||||||
|
openeuler) DEFAULT_PACKAGE=rpm ;;
|
||||||
*) DEFAULT_PACKAGE=rpm ;;
|
*) DEFAULT_PACKAGE=rpm ;;
|
||||||
esac
|
esac
|
||||||
AC_MSG_RESULT([$DEFAULT_PACKAGE])
|
AC_MSG_RESULT([$DEFAULT_PACKAGE])
|
||||||
@@ -555,35 +558,14 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
|
|||||||
AC_MSG_RESULT([$initdir])
|
AC_MSG_RESULT([$initdir])
|
||||||
AC_SUBST(initdir)
|
AC_SUBST(initdir)
|
||||||
|
|
||||||
AC_MSG_CHECKING([default init script type and shell])
|
AC_MSG_CHECKING([default shell])
|
||||||
case "$VENDOR" in
|
case "$VENDOR" in
|
||||||
toss) DEFAULT_INIT_SCRIPT=redhat ;;
|
gentoo) DEFAULT_INIT_SHELL="/sbin/openrc-run";;
|
||||||
redhat) DEFAULT_INIT_SCRIPT=redhat ;;
|
alpine) DEFAULT_INIT_SHELL="/sbin/openrc-run";;
|
||||||
fedora) DEFAULT_INIT_SCRIPT=fedora ;;
|
*) DEFAULT_INIT_SHELL="/bin/sh" ;;
|
||||||
gentoo) DEFAULT_INIT_SCRIPT=openrc ;;
|
|
||||||
alpine) DEFAULT_INIT_SCRIPT=openrc ;;
|
|
||||||
arch) DEFAULT_INIT_SCRIPT=lsb ;;
|
|
||||||
sles) DEFAULT_INIT_SCRIPT=lsb ;;
|
|
||||||
slackware) DEFAULT_INIT_SCRIPT=lsb ;;
|
|
||||||
lunar) DEFAULT_INIT_SCRIPT=lunar ;;
|
|
||||||
ubuntu) DEFAULT_INIT_SCRIPT=lsb ;;
|
|
||||||
debian) DEFAULT_INIT_SCRIPT=lsb ;;
|
|
||||||
freebsd) DEFAULT_INIT_SCRIPT=freebsd;;
|
|
||||||
*) DEFAULT_INIT_SCRIPT=lsb ;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# On gentoo, it's possible that OpenRC isn't installed. Check if
|
AC_MSG_RESULT([$DEFAULT_INIT_SHELL])
|
||||||
# /sbin/openrc-run exists, and if not, fall back to generic defaults.
|
|
||||||
|
|
||||||
DEFAULT_INIT_SHELL="/bin/sh"
|
|
||||||
AS_IF([test "$DEFAULT_INIT_SCRIPT" = "openrc"], [
|
|
||||||
AS_IF([test -x "/sbin/openrc-run"],
|
|
||||||
[DEFAULT_INIT_SHELL="/sbin/openrc-run"],
|
|
||||||
[DEFAULT_INIT_SCRIPT=lsb])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_MSG_RESULT([$DEFAULT_INIT_SCRIPT:$DEFAULT_INIT_SHELL])
|
|
||||||
AC_SUBST(DEFAULT_INIT_SCRIPT)
|
|
||||||
AC_SUBST(DEFAULT_INIT_SHELL)
|
AC_SUBST(DEFAULT_INIT_SHELL)
|
||||||
|
|
||||||
AC_MSG_CHECKING([default nfs server init script])
|
AC_MSG_CHECKING([default nfs server init script])
|
||||||
@@ -602,6 +584,7 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
|
|||||||
redhat) initconfdir=/etc/sysconfig ;;
|
redhat) initconfdir=/etc/sysconfig ;;
|
||||||
fedora) initconfdir=/etc/sysconfig ;;
|
fedora) initconfdir=/etc/sysconfig ;;
|
||||||
sles) initconfdir=/etc/sysconfig ;;
|
sles) initconfdir=/etc/sysconfig ;;
|
||||||
|
openeuler) initconfdir=/etc/sysconfig ;;
|
||||||
ubuntu) initconfdir=/etc/default ;;
|
ubuntu) initconfdir=/etc/default ;;
|
||||||
debian) initconfdir=/etc/default ;;
|
debian) initconfdir=/etc/default ;;
|
||||||
freebsd) initconfdir=$sysconfdir/rc.conf.d;;
|
freebsd) initconfdir=$sysconfdir/rc.conf.d;;
|
||||||
|
|||||||
@@ -57,6 +57,12 @@ array_contains () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check() {
|
check() {
|
||||||
|
# https://github.com/dracutdevs/dracut/pull/1711 provides a zfs_devs
|
||||||
|
# function to detect the physical devices backing zfs pools. If this
|
||||||
|
# function exists in the version of dracut this module is being called
|
||||||
|
# from, then it does not need to run.
|
||||||
|
type zfs_devs >/dev/null 2>&1 && return 1
|
||||||
|
|
||||||
local mp
|
local mp
|
||||||
local dev
|
local dev
|
||||||
local blockdevs
|
local blockdevs
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ pkgdracut_SCRIPTS = \
|
|||||||
|
|
||||||
pkgdracut_DATA = \
|
pkgdracut_DATA = \
|
||||||
zfs-env-bootfs.service \
|
zfs-env-bootfs.service \
|
||||||
|
zfs-nonroot-necessities.service \
|
||||||
zfs-snapshot-bootfs.service \
|
zfs-snapshot-bootfs.service \
|
||||||
zfs-rollback-bootfs.service
|
zfs-rollback-bootfs.service
|
||||||
|
|
||||||
|
|||||||
@@ -84,11 +84,24 @@ install() {
|
|||||||
inst_simple "${moddir}/zfs-env-bootfs.service" "${systemdsystemunitdir}/zfs-env-bootfs.service"
|
inst_simple "${moddir}/zfs-env-bootfs.service" "${systemdsystemunitdir}/zfs-env-bootfs.service"
|
||||||
systemctl -q --root "${initdir}" add-wants zfs-import.target zfs-env-bootfs.service
|
systemctl -q --root "${initdir}" add-wants zfs-import.target zfs-env-bootfs.service
|
||||||
|
|
||||||
|
inst_simple "${moddir}/zfs-nonroot-necessities.service" "${systemdsystemunitdir}/zfs-nonroot-necessities.service"
|
||||||
|
systemctl -q --root "${initdir}" add-requires initrd-root-fs.target zfs-nonroot-necessities.service
|
||||||
|
|
||||||
for _service in \
|
for _service in \
|
||||||
"zfs-import-scan.service" \
|
"zfs-import-scan.service" \
|
||||||
"zfs-import-cache.service"; do
|
"zfs-import-cache.service"; do
|
||||||
inst_simple "${systemdsystemunitdir}/${_service}"
|
inst_simple "${systemdsystemunitdir}/${_service}"
|
||||||
systemctl -q --root "${initdir}" add-wants zfs-import.target "${_service}"
|
systemctl -q --root "${initdir}" add-wants zfs-import.target "${_service}"
|
||||||
|
|
||||||
|
# Add user-provided unit overrides
|
||||||
|
# - /etc/systemd/system/zfs-import-{scan,cache}.service
|
||||||
|
# - /etc/systemd/system/zfs-import-{scan,cache}.service.d/overrides.conf
|
||||||
|
# -H ensures they are marked host-only
|
||||||
|
# -o ensures there is no error upon absence of these files
|
||||||
|
inst_multiple -o -H \
|
||||||
|
"${systemdsystemconfdir}/${_service}" \
|
||||||
|
"${systemdsystemconfdir}/${_service}.d/"*.conf
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
for _service in \
|
for _service in \
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ ZFS_DATASET="${ZFS_DATASET:-${root}}"
|
|||||||
ZFS_POOL="${ZFS_DATASET%%/*}"
|
ZFS_POOL="${ZFS_DATASET%%/*}"
|
||||||
|
|
||||||
|
|
||||||
if ! zpool get -Ho name "${ZFS_POOL}" > /dev/null 2>&1; then
|
if ! zpool get -Ho value name "${ZFS_POOL}" > /dev/null 2>&1; then
|
||||||
info "ZFS: Importing pool ${ZFS_POOL}..."
|
info "ZFS: Importing pool ${ZFS_POOL}..."
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
if ! zpool import -N ${ZPOOL_IMPORT_OPTS} "${ZFS_POOL}"; then
|
if ! zpool import -N ${ZPOOL_IMPORT_OPTS} "${ZFS_POOL}"; then
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Set BOOTFS environment for dracut
|
Description=Set BOOTFS and BOOTFSFLAGS environment variables for dracut
|
||||||
Documentation=man:zpool(8)
|
|
||||||
DefaultDependencies=no
|
DefaultDependencies=no
|
||||||
After=zfs-import-cache.service
|
After=zfs-import-cache.service
|
||||||
After=zfs-import-scan.service
|
After=zfs-import-scan.service
|
||||||
@@ -8,7 +7,17 @@ Before=zfs-import.target
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
ExecStart=/bin/sh -c "exec systemctl set-environment BOOTFS=$(@sbindir@/zpool list -H -o bootfs | grep -m1 -vFx -)"
|
ExecStart=/bin/sh -c ' \
|
||||||
|
. /lib/dracut-zfs-lib.sh; \
|
||||||
|
decode_root_args || exit 0; \
|
||||||
|
[ "$root" = "zfs:AUTO" ] && root="$(@sbindir@/zpool list -H -o bootfs | grep -m1 -vFx -)"; \
|
||||||
|
rootflags="$(getarg rootflags=)"; \
|
||||||
|
case ",$rootflags," in \
|
||||||
|
*,zfsutil,*) ;; \
|
||||||
|
,,) rootflags=zfsutil ;; \
|
||||||
|
*) rootflags="zfsutil,$rootflags" ;; \
|
||||||
|
esac; \
|
||||||
|
exec systemctl set-environment BOOTFS="$root" BOOTFSFLAGS="$rootflags"'
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=zfs-import.target
|
WantedBy=zfs-import.target
|
||||||
|
|||||||
@@ -14,81 +14,24 @@ GENERATOR_DIR="$1"
|
|||||||
. /lib/dracut-zfs-lib.sh
|
. /lib/dracut-zfs-lib.sh
|
||||||
decode_root_args || exit 0
|
decode_root_args || exit 0
|
||||||
|
|
||||||
[ -z "${rootflags}" ] && rootflags=$(getarg rootflags=)
|
|
||||||
case ",${rootflags}," in
|
|
||||||
*,zfsutil,*) ;;
|
|
||||||
,,) rootflags=zfsutil ;;
|
|
||||||
*) rootflags="zfsutil,${rootflags}" ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
[ -n "$debug" ] && echo "zfs-generator: writing extension for sysroot.mount to $GENERATOR_DIR/sysroot.mount.d/zfs-enhancement.conf" >> /dev/kmsg
|
[ -n "$debug" ] && echo "zfs-generator: writing extension for sysroot.mount to $GENERATOR_DIR/sysroot.mount.d/zfs-enhancement.conf" >> /dev/kmsg
|
||||||
|
|
||||||
|
|
||||||
mkdir -p "$GENERATOR_DIR"/sysroot.mount.d "$GENERATOR_DIR"/initrd-root-fs.target.requires "$GENERATOR_DIR"/dracut-pre-mount.service.d
|
mkdir -p "$GENERATOR_DIR"/sysroot.mount.d "$GENERATOR_DIR"/dracut-pre-mount.service.d
|
||||||
|
|
||||||
{
|
{
|
||||||
echo "[Unit]"
|
echo "[Unit]"
|
||||||
echo "Before=initrd-root-fs.target"
|
echo "Before=initrd-root-fs.target"
|
||||||
echo "After=zfs-import.target"
|
echo "After=zfs-import.target"
|
||||||
echo
|
echo
|
||||||
echo "[Mount]"
|
echo "[Mount]"
|
||||||
if [ "${root}" = "zfs:AUTO" ]; then
|
echo "PassEnvironment=BOOTFS BOOTFSFLAGS"
|
||||||
echo "PassEnvironment=BOOTFS"
|
echo 'What=${BOOTFS}'
|
||||||
echo 'What=${BOOTFS}'
|
|
||||||
else
|
|
||||||
echo "What=${root}"
|
|
||||||
fi
|
|
||||||
echo "Type=zfs"
|
echo "Type=zfs"
|
||||||
echo "Options=${rootflags}"
|
echo 'Options=${BOOTFSFLAGS}'
|
||||||
} > "$GENERATOR_DIR"/sysroot.mount.d/zfs-enhancement.conf
|
} > "$GENERATOR_DIR"/sysroot.mount.d/zfs-enhancement.conf
|
||||||
ln -fs ../sysroot.mount "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount
|
ln -fs ../sysroot.mount "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount
|
||||||
|
|
||||||
|
|
||||||
if [ "${root}" = "zfs:AUTO" ]; then
|
|
||||||
{
|
|
||||||
echo "[Unit]"
|
|
||||||
echo "Before=initrd-root-fs.target"
|
|
||||||
echo "After=sysroot.mount"
|
|
||||||
echo "DefaultDependencies=no"
|
|
||||||
echo
|
|
||||||
echo "[Service]"
|
|
||||||
echo "Type=oneshot"
|
|
||||||
echo "PassEnvironment=BOOTFS"
|
|
||||||
echo "ExecStart=/bin/sh -c '" ' \
|
|
||||||
. /lib/dracut-zfs-lib.sh; \
|
|
||||||
_zfs_nonroot_necessities_cb() { \
|
|
||||||
zfs mount | grep -m1 -q "^$1 " && return 0; \
|
|
||||||
echo "Mounting $1 on /sysroot$2"; \
|
|
||||||
mount -o zfsutil -t zfs "$1" "/sysroot$2"; \
|
|
||||||
}; \
|
|
||||||
for_relevant_root_children "${BOOTFS}" _zfs_nonroot_necessities_cb;' \
|
|
||||||
"'"
|
|
||||||
} > "$GENERATOR_DIR"/zfs-nonroot-necessities.service
|
|
||||||
ln -fs ../zfs-nonroot-necessities.service "$GENERATOR_DIR"/initrd-root-fs.target.requires/zfs-nonroot-necessities.service
|
|
||||||
else
|
|
||||||
# We can solve this statically at generation time, so do!
|
|
||||||
_zfs_generator_cb() {
|
|
||||||
dset="${1}"
|
|
||||||
mpnt="${2}"
|
|
||||||
unit="$(systemd-escape --suffix=mount -p "/sysroot${mpnt}")"
|
|
||||||
|
|
||||||
{
|
|
||||||
echo "[Unit]"
|
|
||||||
echo "Before=initrd-root-fs.target"
|
|
||||||
echo "After=sysroot.mount"
|
|
||||||
echo
|
|
||||||
echo "[Mount]"
|
|
||||||
echo "Where=/sysroot${mpnt}"
|
|
||||||
echo "What=${dset}"
|
|
||||||
echo "Type=zfs"
|
|
||||||
echo "Options=zfsutil"
|
|
||||||
} > "$GENERATOR_DIR/${unit}"
|
|
||||||
ln -fs ../"${unit}" "$GENERATOR_DIR"/initrd-root-fs.target.requires/"${unit}"
|
|
||||||
}
|
|
||||||
|
|
||||||
for_relevant_root_children "${root}" _zfs_generator_cb
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
echo "[Unit]"
|
echo "[Unit]"
|
||||||
echo "After=zfs-import.target"
|
echo "After=zfs-import.target"
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ mount_dataset() {
|
|||||||
|
|
||||||
# for_relevant_root_children DATASET EXEC
|
# for_relevant_root_children DATASET EXEC
|
||||||
# Runs "EXEC dataset mountpoint" for all children of DATASET that are needed for system bringup
|
# Runs "EXEC dataset mountpoint" for all children of DATASET that are needed for system bringup
|
||||||
# Used by zfs-generator.sh and friends, too!
|
# Used by zfs-nonroot-necessities.service and friends, too!
|
||||||
for_relevant_root_children() {
|
for_relevant_root_children() {
|
||||||
dataset="${1}"
|
dataset="${1}"
|
||||||
exec="${2}"
|
exec="${2}"
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
[Unit]
|
||||||
|
Before=initrd-root-fs.target
|
||||||
|
After=sysroot.mount
|
||||||
|
DefaultDependencies=no
|
||||||
|
ConditionEnvironment=BOOTFS
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
PassEnvironment=BOOTFS
|
||||||
|
ExecStart=/bin/sh -c ' \
|
||||||
|
. /lib/dracut-zfs-lib.sh; \
|
||||||
|
_zfs_nonroot_necessities_cb() { \
|
||||||
|
@sbindir@/zfs mount | grep -m1 -q "^$1 " && return 0; \
|
||||||
|
echo "Mounting $1 on /sysroot$2"; \
|
||||||
|
mount -o zfsutil -t zfs "$1" "/sysroot$2"; \
|
||||||
|
}; \
|
||||||
|
for_relevant_root_children "${BOOTFS}" _zfs_nonroot_necessities_cb'
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
RequiredBy=initrd-root-fs.target
|
||||||
@@ -5,8 +5,9 @@ After=zfs-import.target dracut-pre-mount.service zfs-snapshot-bootfs.service
|
|||||||
Before=dracut-mount.service
|
Before=dracut-mount.service
|
||||||
DefaultDependencies=no
|
DefaultDependencies=no
|
||||||
ConditionKernelCommandLine=bootfs.rollback
|
ConditionKernelCommandLine=bootfs.rollback
|
||||||
|
ConditionEnvironment=BOOTFS
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
ExecStart=/bin/sh -c '. /lib/dracut-zfs-lib.sh; decode_root_args || exit; [ "$root" = "zfs:AUTO" ] && root="$BOOTFS"; SNAPNAME="$(getarg bootfs.rollback)"; exec @sbindir@/zfs rollback -Rf "$root@${SNAPNAME:-%v}"'
|
ExecStart=/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.rollback)"; exec @sbindir@/zfs rollback -Rf "$BOOTFS@${SNAPNAME:-%v}"'
|
||||||
RemainAfterExit=yes
|
RemainAfterExit=yes
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ After=zfs-import.target dracut-pre-mount.service
|
|||||||
Before=dracut-mount.service
|
Before=dracut-mount.service
|
||||||
DefaultDependencies=no
|
DefaultDependencies=no
|
||||||
ConditionKernelCommandLine=bootfs.snapshot
|
ConditionKernelCommandLine=bootfs.snapshot
|
||||||
|
ConditionEnvironment=BOOTFS
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
ExecStart=-/bin/sh -c '. /lib/dracut-zfs-lib.sh; decode_root_args || exit; [ "$root" = "zfs:AUTO" ] && root="$BOOTFS"; SNAPNAME="$(getarg bootfs.snapshot)"; exec @sbindir@/zfs snapshot "$root@${SNAPNAME:-%v}"'
|
ExecStart=-/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.snapshot)"; exec @sbindir@/zfs snapshot "$BOOTFS@${SNAPNAME:-%v}"'
|
||||||
RemainAfterExit=yes
|
RemainAfterExit=yes
|
||||||
|
|||||||
@@ -7,5 +7,6 @@ dist_scripts_SCRIPTS = \
|
|||||||
|
|
||||||
SUBDIRS = local-top
|
SUBDIRS = local-top
|
||||||
|
|
||||||
|
SHELLCHECK_IGNORE = ,SC2295
|
||||||
SHELLCHECKDIRS = $(SUBDIRS)
|
SHELLCHECKDIRS = $(SUBDIRS)
|
||||||
SHELLCHECK_SHELL = sh
|
SHELLCHECK_SHELL = sh
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ import_pool()
|
|||||||
|
|
||||||
# Verify that the pool isn't already imported
|
# Verify that the pool isn't already imported
|
||||||
# Make as sure as we can to not require '-f' to import.
|
# Make as sure as we can to not require '-f' to import.
|
||||||
"${ZPOOL}" get name,guid -o value -H 2>/dev/null | grep -Fxq "$pool" && return 0
|
"${ZPOOL}" get -H -o value name,guid 2>/dev/null | grep -Fxq "$pool" && return 0
|
||||||
|
|
||||||
# For backwards compatibility, make sure that ZPOOL_IMPORT_PATH is set
|
# For backwards compatibility, make sure that ZPOOL_IMPORT_PATH is set
|
||||||
# to something we can use later with the real import(s). We want to
|
# to something we can use later with the real import(s). We want to
|
||||||
@@ -331,25 +331,24 @@ mount_fs()
|
|||||||
# Can't use the mountpoint property. Might be one of our
|
# Can't use the mountpoint property. Might be one of our
|
||||||
# clones. Check the 'org.zol:mountpoint' property set in
|
# clones. Check the 'org.zol:mountpoint' property set in
|
||||||
# clone_snap() if that's usable.
|
# clone_snap() if that's usable.
|
||||||
mountpoint=$(get_fs_value "$fs" org.zol:mountpoint)
|
mountpoint1=$(get_fs_value "$fs" org.zol:mountpoint)
|
||||||
if [ "$mountpoint" = "legacy" ] ||
|
if [ "$mountpoint1" = "legacy" ] ||
|
||||||
[ "$mountpoint" = "none" ] ||
|
[ "$mountpoint1" = "none" ] ||
|
||||||
[ "$mountpoint" = "-" ]
|
[ "$mountpoint1" = "-" ]
|
||||||
then
|
then
|
||||||
if [ "$fs" != "${ZFS_BOOTFS}" ]; then
|
if [ "$fs" != "${ZFS_BOOTFS}" ]; then
|
||||||
# We don't have a proper mountpoint and this
|
# We don't have a proper mountpoint and this
|
||||||
# isn't the root fs.
|
# isn't the root fs.
|
||||||
return 0
|
return 0
|
||||||
else
|
|
||||||
# Last hail-mary: Hope 'rootmnt' is set!
|
|
||||||
mountpoint=""
|
|
||||||
fi
|
fi
|
||||||
fi
|
# Don't use mount.zfs -o zfsutils for legacy mountpoint
|
||||||
|
if [ "$mountpoint" = "legacy" ]; then
|
||||||
# If it's not a legacy filesystem, it can only be a
|
ZFS_CMD="mount.zfs"
|
||||||
# native one...
|
fi
|
||||||
if [ "$mountpoint" = "legacy" ]; then
|
# Last hail-mary: Hope 'rootmnt' is set!
|
||||||
ZFS_CMD="mount.zfs"
|
mountpoint=""
|
||||||
|
else
|
||||||
|
mountpoint="$mountpoint1"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -503,7 +502,7 @@ clone_snap()
|
|||||||
echo "Error: $ZFS_ERROR"
|
echo "Error: $ZFS_ERROR"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Failed to clone snapshot."
|
echo "Failed to clone snapshot."
|
||||||
echo "Make sure that the any problems are corrected and then make sure"
|
echo "Make sure that any problems are corrected and then make sure"
|
||||||
echo "that the dataset '$destfs' exists and is bootable."
|
echo "that the dataset '$destfs' exists and is bootable."
|
||||||
shell
|
shell
|
||||||
else
|
else
|
||||||
@@ -884,12 +883,12 @@ mountroot()
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# In case the pool was specified as guid, resolve guid to name
|
# In case the pool was specified as guid, resolve guid to name
|
||||||
pool="$("${ZPOOL}" get name,guid -o name,value -H | \
|
pool="$("${ZPOOL}" get -H -o name,value name,guid | \
|
||||||
awk -v pool="${ZFS_RPOOL}" '$2 == pool { print $1 }')"
|
awk -v pool="${ZFS_RPOOL}" '$2 == pool { print $1 }')"
|
||||||
if [ -n "$pool" ]; then
|
if [ -n "$pool" ]; then
|
||||||
# If $ZFS_BOOTFS contains guid, replace the guid portion with $pool
|
# If $ZFS_BOOTFS contains guid, replace the guid portion with $pool
|
||||||
ZFS_BOOTFS=$(echo "$ZFS_BOOTFS" | \
|
ZFS_BOOTFS=$(echo "$ZFS_BOOTFS" | \
|
||||||
sed -e "s/$("${ZPOOL}" get guid -o value "$pool" -H)/$pool/g")
|
sed -e "s/$("${ZPOOL}" get -H -o value guid "$pool")/$pool/g")
|
||||||
ZFS_RPOOL="${pool}"
|
ZFS_RPOOL="${pool}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -29,13 +29,12 @@ setup(
|
|||||||
"Development Status :: 4 - Beta",
|
"Development Status :: 4 - Beta",
|
||||||
"Intended Audience :: Developers",
|
"Intended Audience :: Developers",
|
||||||
"License :: OSI Approved :: Apache Software License",
|
"License :: OSI Approved :: Apache Software License",
|
||||||
"Programming Language :: Python :: 2",
|
|
||||||
"Programming Language :: Python :: 2.7",
|
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"Programming Language :: Python :: 3.4",
|
|
||||||
"Programming Language :: Python :: 3.5",
|
|
||||||
"Programming Language :: Python :: 3.6",
|
"Programming Language :: Python :: 3.6",
|
||||||
"Programming Language :: Python :: 3.7",
|
"Programming Language :: Python :: 3.7",
|
||||||
|
"Programming Language :: Python :: 3.8",
|
||||||
|
"Programming Language :: Python :: 3.9",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
"Topic :: System :: Filesystems",
|
"Topic :: System :: Filesystems",
|
||||||
"Topic :: Software Development :: Libraries",
|
"Topic :: Software Development :: Libraries",
|
||||||
],
|
],
|
||||||
@@ -53,7 +52,7 @@ setup(
|
|||||||
setup_requires=[
|
setup_requires=[
|
||||||
"cffi",
|
"cffi",
|
||||||
],
|
],
|
||||||
python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,<4',
|
python_requires='>=3.6,<4',
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
test_suite="libzfs_core.test",
|
test_suite="libzfs_core.test",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ ConditionPathIsDirectory=/sys/module/zfs
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=@sbindir@/zed -F
|
ExecStart=@sbindir@/zed -F
|
||||||
Restart=on-abort
|
Restart=always
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
Alias=zed.service
|
Alias=zed.service
|
||||||
|
|||||||
@@ -307,6 +307,7 @@ extern int zpool_vdev_remove_cancel(zpool_handle_t *);
|
|||||||
extern int zpool_vdev_indirect_size(zpool_handle_t *, const char *, uint64_t *);
|
extern int zpool_vdev_indirect_size(zpool_handle_t *, const char *, uint64_t *);
|
||||||
extern int zpool_vdev_split(zpool_handle_t *, char *, nvlist_t **, nvlist_t *,
|
extern int zpool_vdev_split(zpool_handle_t *, char *, nvlist_t **, nvlist_t *,
|
||||||
splitflags_t);
|
splitflags_t);
|
||||||
|
_LIBZFS_H int zpool_vdev_remove_wanted(zpool_handle_t *, const char *);
|
||||||
|
|
||||||
extern int zpool_vdev_fault(zpool_handle_t *, uint64_t, vdev_aux_t);
|
extern int zpool_vdev_fault(zpool_handle_t *, uint64_t, vdev_aux_t);
|
||||||
extern int zpool_vdev_degrade(zpool_handle_t *, uint64_t, vdev_aux_t);
|
extern int zpool_vdev_degrade(zpool_handle_t *, uint64_t, vdev_aux_t);
|
||||||
@@ -692,6 +693,9 @@ typedef struct sendflags {
|
|||||||
/* show progress (ie. -v) */
|
/* show progress (ie. -v) */
|
||||||
boolean_t progress;
|
boolean_t progress;
|
||||||
|
|
||||||
|
/* show progress as process title (ie. -V) */
|
||||||
|
boolean_t progressastitle;
|
||||||
|
|
||||||
/* large blocks (>128K) are permitted */
|
/* large blocks (>128K) are permitted */
|
||||||
boolean_t largeblock;
|
boolean_t largeblock;
|
||||||
|
|
||||||
|
|||||||
+20
-2
@@ -150,14 +150,32 @@ int zfs_ioctl_fd(int fd, unsigned long request, struct zfs_cmd *zc);
|
|||||||
/*
|
/*
|
||||||
* List of colors to use
|
* List of colors to use
|
||||||
*/
|
*/
|
||||||
|
#define ANSI_BLACK "\033[0;30m"
|
||||||
#define ANSI_RED "\033[0;31m"
|
#define ANSI_RED "\033[0;31m"
|
||||||
|
#define ANSI_GREEN "\033[0;32m"
|
||||||
#define ANSI_YELLOW "\033[0;33m"
|
#define ANSI_YELLOW "\033[0;33m"
|
||||||
|
#define ANSI_BLUE "\033[0;34m"
|
||||||
|
#define ANSI_BOLD_BLUE "\033[1;34m" /* light blue */
|
||||||
|
#define ANSI_MAGENTA "\033[0;35m"
|
||||||
|
#define ANSI_CYAN "\033[0;36m"
|
||||||
|
#define ANSI_GRAY "\033[0;37m"
|
||||||
|
|
||||||
#define ANSI_RESET "\033[0m"
|
#define ANSI_RESET "\033[0m"
|
||||||
#define ANSI_BOLD "\033[1m"
|
#define ANSI_BOLD "\033[1m"
|
||||||
|
|
||||||
void color_start(char *color);
|
int use_color(void);
|
||||||
|
void color_start(const char *color);
|
||||||
void color_end(void);
|
void color_end(void);
|
||||||
int printf_color(char *color, char *format, ...);
|
int printf_color(const char *color, char *format, ...);
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
extern char **environ;
|
||||||
|
_LIBZUTIL_H void zfs_setproctitle_init(int argc, char *argv[], char *envp[]);
|
||||||
|
_LIBZUTIL_H void zfs_setproctitle(const char *fmt, ...);
|
||||||
|
#else
|
||||||
|
#define zfs_setproctitle(fmt, ...) setproctitle(fmt, ##__VA_ARGS__)
|
||||||
|
#define zfs_setproctitle_init(x, y, z) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These functions are used by the ZFS libraries and cmd/zpool code, but are
|
* These functions are used by the ZFS libraries and cmd/zpool code, but are
|
||||||
|
|||||||
@@ -256,6 +256,32 @@ bio_set_bi_error(struct bio *bio, int error)
|
|||||||
#define BIO_END_IO(bio, error) bio_endio(bio, error);
|
#define BIO_END_IO(bio, error) bio_endio(bio, error);
|
||||||
#endif /* HAVE_1ARG_BIO_END_IO_T */
|
#endif /* HAVE_1ARG_BIO_END_IO_T */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 5.15 MACRO,
|
||||||
|
* GD_DEAD
|
||||||
|
*
|
||||||
|
* 2.6.36 - 5.14 MACRO,
|
||||||
|
* GENHD_FL_UP
|
||||||
|
*
|
||||||
|
* Check the disk status and return B_TRUE if alive
|
||||||
|
* otherwise B_FALSE
|
||||||
|
*/
|
||||||
|
static inline boolean_t
|
||||||
|
zfs_check_disk_status(struct block_device *bdev)
|
||||||
|
{
|
||||||
|
#if defined(GENHD_FL_UP)
|
||||||
|
return (!!(bdev->bd_disk->flags & GENHD_FL_UP));
|
||||||
|
#elif defined(GD_DEAD)
|
||||||
|
return (!test_bit(GD_DEAD, &bdev->bd_disk->state));
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* This is encountered if neither GENHD_FL_UP nor GD_DEAD is available in
|
||||||
|
* the kernel - likely due to an MACRO change that needs to be chased down.
|
||||||
|
*/
|
||||||
|
#error "Unsupported kernel: no usable disk status check"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 4.1 API,
|
* 4.1 API,
|
||||||
* 3.10.0 CentOS 7.x API,
|
* 3.10.0 CentOS 7.x API,
|
||||||
@@ -357,7 +383,11 @@ vdev_lookup_bdev(const char *path, dev_t *dev)
|
|||||||
static inline void
|
static inline void
|
||||||
bio_set_op_attrs(struct bio *bio, unsigned rw, unsigned flags)
|
bio_set_op_attrs(struct bio *bio, unsigned rw, unsigned flags)
|
||||||
{
|
{
|
||||||
|
#if defined(HAVE_BIO_BI_OPF)
|
||||||
|
bio->bi_opf = rw | flags;
|
||||||
|
#else
|
||||||
bio->bi_rw |= rw | flags;
|
bio->bi_rw |= rw | flags;
|
||||||
|
#endif /* HAVE_BIO_BI_OPF */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -385,7 +415,7 @@ static inline void
|
|||||||
bio_set_flush(struct bio *bio)
|
bio_set_flush(struct bio *bio)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_REQ_PREFLUSH) /* >= 4.10 */
|
#if defined(HAVE_REQ_PREFLUSH) /* >= 4.10 */
|
||||||
bio_set_op_attrs(bio, 0, REQ_PREFLUSH);
|
bio_set_op_attrs(bio, 0, REQ_PREFLUSH | REQ_OP_WRITE);
|
||||||
#elif defined(WRITE_FLUSH_FUA) /* >= 2.6.37 and <= 4.9 */
|
#elif defined(WRITE_FLUSH_FUA) /* >= 2.6.37 and <= 4.9 */
|
||||||
bio_set_op_attrs(bio, 0, WRITE_FLUSH_FUA);
|
bio_set_op_attrs(bio, 0, WRITE_FLUSH_FUA);
|
||||||
#else
|
#else
|
||||||
@@ -551,7 +581,10 @@ blk_generic_start_io_acct(struct request_queue *q __attribute__((unused)),
|
|||||||
struct gendisk *disk __attribute__((unused)),
|
struct gendisk *disk __attribute__((unused)),
|
||||||
int rw __attribute__((unused)), struct bio *bio)
|
int rw __attribute__((unused)), struct bio *bio)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_BDEV_IO_ACCT)
|
#if defined(HAVE_BDEV_IO_ACCT_63)
|
||||||
|
return (bdev_start_io_acct(bio->bi_bdev, bio_op(bio),
|
||||||
|
jiffies));
|
||||||
|
#elif defined(HAVE_BDEV_IO_ACCT_OLD)
|
||||||
return (bdev_start_io_acct(bio->bi_bdev, bio_sectors(bio),
|
return (bdev_start_io_acct(bio->bi_bdev, bio_sectors(bio),
|
||||||
bio_op(bio), jiffies));
|
bio_op(bio), jiffies));
|
||||||
#elif defined(HAVE_DISK_IO_ACCT)
|
#elif defined(HAVE_DISK_IO_ACCT)
|
||||||
@@ -577,7 +610,10 @@ blk_generic_end_io_acct(struct request_queue *q __attribute__((unused)),
|
|||||||
struct gendisk *disk __attribute__((unused)),
|
struct gendisk *disk __attribute__((unused)),
|
||||||
int rw __attribute__((unused)), struct bio *bio, unsigned long start_time)
|
int rw __attribute__((unused)), struct bio *bio, unsigned long start_time)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_BDEV_IO_ACCT)
|
#if defined(HAVE_BDEV_IO_ACCT_63)
|
||||||
|
bdev_end_io_acct(bio->bi_bdev, bio_op(bio), bio_sectors(bio),
|
||||||
|
start_time);
|
||||||
|
#elif defined(HAVE_BDEV_IO_ACCT_OLD)
|
||||||
bdev_end_io_acct(bio->bi_bdev, bio_op(bio), start_time);
|
bdev_end_io_acct(bio->bi_bdev, bio_op(bio), start_time);
|
||||||
#elif defined(HAVE_DISK_IO_ACCT)
|
#elif defined(HAVE_DISK_IO_ACCT)
|
||||||
disk_end_io_acct(disk, bio_op(bio), start_time);
|
disk_end_io_acct(disk, bio_op(bio), start_time);
|
||||||
|
|||||||
@@ -35,6 +35,10 @@
|
|||||||
#define d_make_root(inode) d_alloc_root(inode)
|
#define d_make_root(inode) d_alloc_root(inode)
|
||||||
#endif /* HAVE_D_MAKE_ROOT */
|
#endif /* HAVE_D_MAKE_ROOT */
|
||||||
|
|
||||||
|
#ifdef HAVE_DENTRY_D_U_ALIASES
|
||||||
|
#define d_alias d_u.d_alias
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2.6.30 API change,
|
* 2.6.30 API change,
|
||||||
* The const keyword was added to the 'struct dentry_operations' in
|
* The const keyword was added to the 'struct dentry_operations' in
|
||||||
@@ -70,11 +74,7 @@ zpl_d_drop_aliases(struct inode *inode)
|
|||||||
{
|
{
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
spin_lock(&inode->i_lock);
|
spin_lock(&inode->i_lock);
|
||||||
#ifdef HAVE_DENTRY_D_U_ALIASES
|
|
||||||
hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
|
|
||||||
#else
|
|
||||||
hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
|
hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
|
||||||
#endif
|
|
||||||
if (!IS_ROOT(dentry) && !d_mountpoint(dentry) &&
|
if (!IS_ROOT(dentry) && !d_mountpoint(dentry) &&
|
||||||
(dentry->d_inode == inode)) {
|
(dentry->d_inode == inode)) {
|
||||||
d_drop(dentry);
|
d_drop(dentry);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ KERNEL_H = \
|
|||||||
kmem.h \
|
kmem.h \
|
||||||
kstat.h \
|
kstat.h \
|
||||||
list.h \
|
list.h \
|
||||||
|
misc.h \
|
||||||
mod_os.h \
|
mod_os.h \
|
||||||
mutex.h \
|
mutex.h \
|
||||||
param.h \
|
param.h \
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* CDDL HEADER START
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the terms of the
|
||||||
|
* Common Development and Distribution License (the "License").
|
||||||
|
* You may not use this file except in compliance with the License.
|
||||||
|
*
|
||||||
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
* or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
* See the License for the specific language governing permissions
|
||||||
|
* and limitations under the License.
|
||||||
|
*
|
||||||
|
* When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
* If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
*
|
||||||
|
* CDDL HEADER END
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _OS_LINUX_SPL_MISC_H
|
||||||
|
#define _OS_LINUX_SPL_MISC_H
|
||||||
|
|
||||||
|
#include <linux/kobject.h>
|
||||||
|
|
||||||
|
extern void spl_signal_kobj_evt(struct block_device *bdev);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -67,11 +67,14 @@ extern int zpl_xattr_security_init(struct inode *ip, struct inode *dip,
|
|||||||
#if defined(HAVE_SET_ACL_USERNS)
|
#if defined(HAVE_SET_ACL_USERNS)
|
||||||
extern int zpl_set_acl(struct user_namespace *userns, struct inode *ip,
|
extern int zpl_set_acl(struct user_namespace *userns, struct inode *ip,
|
||||||
struct posix_acl *acl, int type);
|
struct posix_acl *acl, int type);
|
||||||
|
#elif defined(HAVE_SET_ACL_USERNS_DENTRY_ARG2)
|
||||||
|
extern int zpl_set_acl(struct user_namespace *userns, struct dentry *dentry,
|
||||||
|
struct posix_acl *acl, int type);
|
||||||
#else
|
#else
|
||||||
extern int zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type);
|
extern int zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type);
|
||||||
#endif /* HAVE_SET_ACL_USERNS */
|
#endif /* HAVE_SET_ACL_USERNS */
|
||||||
#endif /* HAVE_SET_ACL */
|
#endif /* HAVE_SET_ACL */
|
||||||
#if defined(HAVE_GET_ACL_RCU)
|
#if defined(HAVE_GET_ACL_RCU) || defined(HAVE_GET_INODE_ACL)
|
||||||
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type, bool rcu);
|
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type, bool rcu);
|
||||||
#elif defined(HAVE_GET_ACL)
|
#elif defined(HAVE_GET_ACL)
|
||||||
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type);
|
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#define _SYS_ARC_IMPL_H
|
#define _SYS_ARC_IMPL_H
|
||||||
|
|
||||||
#include <sys/arc.h>
|
#include <sys/arc.h>
|
||||||
|
#include <sys/multilist.h>
|
||||||
#include <sys/zio_crypt.h>
|
#include <sys/zio_crypt.h>
|
||||||
#include <sys/zthr.h>
|
#include <sys/zthr.h>
|
||||||
#include <sys/aggsum.h>
|
#include <sys/aggsum.h>
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ int livelist_bpobj_iterate_from_nofree(bpobj_t *bpo, bpobj_itor_t func,
|
|||||||
void *arg, int64_t start);
|
void *arg, int64_t start);
|
||||||
|
|
||||||
void bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx);
|
void bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx);
|
||||||
|
void bpobj_prefetch_subobj(bpobj_t *bpo, uint64_t subobj);
|
||||||
void bpobj_enqueue(bpobj_t *bpo, const blkptr_t *bp, boolean_t bp_freed,
|
void bpobj_enqueue(bpobj_t *bpo, const blkptr_t *bp, boolean_t bp_freed,
|
||||||
dmu_tx_t *tx);
|
dmu_tx_t *tx);
|
||||||
|
|
||||||
|
|||||||
+8
-7
@@ -65,7 +65,7 @@ extern "C" {
|
|||||||
* them, and increased memory overhead. Increasing these values results in
|
* them, and increased memory overhead. Increasing these values results in
|
||||||
* higher variance in operation time, and reduces memory overhead.
|
* higher variance in operation time, and reduces memory overhead.
|
||||||
*/
|
*/
|
||||||
#define BTREE_CORE_ELEMS 128
|
#define BTREE_CORE_ELEMS 126
|
||||||
#define BTREE_LEAF_SIZE 4096
|
#define BTREE_LEAF_SIZE 4096
|
||||||
|
|
||||||
extern kmem_cache_t *zfs_btree_leaf_cache;
|
extern kmem_cache_t *zfs_btree_leaf_cache;
|
||||||
@@ -95,9 +95,6 @@ typedef struct zfs_btree_leaf {
|
|||||||
uint8_t btl_elems[];
|
uint8_t btl_elems[];
|
||||||
} zfs_btree_leaf_t;
|
} zfs_btree_leaf_t;
|
||||||
|
|
||||||
#define BTREE_LEAF_ESIZE (BTREE_LEAF_SIZE - \
|
|
||||||
offsetof(zfs_btree_leaf_t, btl_elems))
|
|
||||||
|
|
||||||
typedef struct zfs_btree_index {
|
typedef struct zfs_btree_index {
|
||||||
zfs_btree_hdr_t *bti_node;
|
zfs_btree_hdr_t *bti_node;
|
||||||
uint32_t bti_offset;
|
uint32_t bti_offset;
|
||||||
@@ -109,14 +106,15 @@ typedef struct zfs_btree_index {
|
|||||||
} zfs_btree_index_t;
|
} zfs_btree_index_t;
|
||||||
|
|
||||||
typedef struct btree {
|
typedef struct btree {
|
||||||
zfs_btree_hdr_t *bt_root;
|
int (*bt_compar) (const void *, const void *);
|
||||||
int64_t bt_height;
|
|
||||||
size_t bt_elem_size;
|
size_t bt_elem_size;
|
||||||
|
size_t bt_leaf_size;
|
||||||
uint32_t bt_leaf_cap;
|
uint32_t bt_leaf_cap;
|
||||||
|
int32_t bt_height;
|
||||||
uint64_t bt_num_elems;
|
uint64_t bt_num_elems;
|
||||||
uint64_t bt_num_nodes;
|
uint64_t bt_num_nodes;
|
||||||
|
zfs_btree_hdr_t *bt_root;
|
||||||
zfs_btree_leaf_t *bt_bulk; // non-null if bulk loading
|
zfs_btree_leaf_t *bt_bulk; // non-null if bulk loading
|
||||||
int (*bt_compar) (const void *, const void *);
|
|
||||||
} zfs_btree_t;
|
} zfs_btree_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -132,9 +130,12 @@ void zfs_btree_fini(void);
|
|||||||
* compar - function to compare two nodes, it must return exactly: -1, 0, or +1
|
* compar - function to compare two nodes, it must return exactly: -1, 0, or +1
|
||||||
* -1 for <, 0 for ==, and +1 for >
|
* -1 for <, 0 for ==, and +1 for >
|
||||||
* size - the value of sizeof(struct my_type)
|
* size - the value of sizeof(struct my_type)
|
||||||
|
* lsize - custom leaf size
|
||||||
*/
|
*/
|
||||||
void zfs_btree_create(zfs_btree_t *, int (*) (const void *, const void *),
|
void zfs_btree_create(zfs_btree_t *, int (*) (const void *, const void *),
|
||||||
size_t);
|
size_t);
|
||||||
|
void zfs_btree_create_custom(zfs_btree_t *, int (*)(const void *, const void *),
|
||||||
|
size_t, size_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find a node with a matching value in the tree. Returns the matching node
|
* Find a node with a matching value in the tree. Returns the matching node
|
||||||
|
|||||||
+34
-1
@@ -36,6 +36,7 @@
|
|||||||
#include <sys/dmu_zfetch.h>
|
#include <sys/dmu_zfetch.h>
|
||||||
#include <sys/zrlock.h>
|
#include <sys/zrlock.h>
|
||||||
#include <sys/multilist.h>
|
#include <sys/multilist.h>
|
||||||
|
#include <sys/wmsum.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -587,10 +588,42 @@ typedef struct dnode_stats {
|
|||||||
kstat_named_t dnode_move_active;
|
kstat_named_t dnode_move_active;
|
||||||
} dnode_stats_t;
|
} dnode_stats_t;
|
||||||
|
|
||||||
|
typedef struct dnode_sums {
|
||||||
|
wmsum_t dnode_hold_dbuf_hold;
|
||||||
|
wmsum_t dnode_hold_dbuf_read;
|
||||||
|
wmsum_t dnode_hold_alloc_hits;
|
||||||
|
wmsum_t dnode_hold_alloc_misses;
|
||||||
|
wmsum_t dnode_hold_alloc_interior;
|
||||||
|
wmsum_t dnode_hold_alloc_lock_retry;
|
||||||
|
wmsum_t dnode_hold_alloc_lock_misses;
|
||||||
|
wmsum_t dnode_hold_alloc_type_none;
|
||||||
|
wmsum_t dnode_hold_free_hits;
|
||||||
|
wmsum_t dnode_hold_free_misses;
|
||||||
|
wmsum_t dnode_hold_free_lock_misses;
|
||||||
|
wmsum_t dnode_hold_free_lock_retry;
|
||||||
|
wmsum_t dnode_hold_free_refcount;
|
||||||
|
wmsum_t dnode_hold_free_overflow;
|
||||||
|
wmsum_t dnode_free_interior_lock_retry;
|
||||||
|
wmsum_t dnode_allocate;
|
||||||
|
wmsum_t dnode_reallocate;
|
||||||
|
wmsum_t dnode_buf_evict;
|
||||||
|
wmsum_t dnode_alloc_next_chunk;
|
||||||
|
wmsum_t dnode_alloc_race;
|
||||||
|
wmsum_t dnode_alloc_next_block;
|
||||||
|
wmsum_t dnode_move_invalid;
|
||||||
|
wmsum_t dnode_move_recheck1;
|
||||||
|
wmsum_t dnode_move_recheck2;
|
||||||
|
wmsum_t dnode_move_special;
|
||||||
|
wmsum_t dnode_move_handle;
|
||||||
|
wmsum_t dnode_move_rwlock;
|
||||||
|
wmsum_t dnode_move_active;
|
||||||
|
} dnode_sums_t;
|
||||||
|
|
||||||
extern dnode_stats_t dnode_stats;
|
extern dnode_stats_t dnode_stats;
|
||||||
|
extern dnode_sums_t dnode_sums;
|
||||||
|
|
||||||
#define DNODE_STAT_INCR(stat, val) \
|
#define DNODE_STAT_INCR(stat, val) \
|
||||||
atomic_add_64(&dnode_stats.stat.value.ui64, (val));
|
wmsum_add(&dnode_sums.stat, (val))
|
||||||
#define DNODE_STAT_BUMP(stat) \
|
#define DNODE_STAT_BUMP(stat) \
|
||||||
DNODE_STAT_INCR(stat, 1);
|
DNODE_STAT_INCR(stat, 1);
|
||||||
|
|
||||||
|
|||||||
@@ -1518,6 +1518,7 @@ typedef enum {
|
|||||||
#define ZFS_ONLINE_UNSPARE 0x2
|
#define ZFS_ONLINE_UNSPARE 0x2
|
||||||
#define ZFS_ONLINE_FORCEFAULT 0x4
|
#define ZFS_ONLINE_FORCEFAULT 0x4
|
||||||
#define ZFS_ONLINE_EXPAND 0x8
|
#define ZFS_ONLINE_EXPAND 0x8
|
||||||
|
#define ZFS_ONLINE_SPARE 0x10
|
||||||
#define ZFS_OFFLINE_TEMPORARY 0x1
|
#define ZFS_OFFLINE_TEMPORARY 0x1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+1
-1
@@ -837,7 +837,7 @@ extern kmutex_t spa_namespace_lock;
|
|||||||
#define SPA_CONFIG_UPDATE_POOL 0
|
#define SPA_CONFIG_UPDATE_POOL 0
|
||||||
#define SPA_CONFIG_UPDATE_VDEVS 1
|
#define SPA_CONFIG_UPDATE_VDEVS 1
|
||||||
|
|
||||||
extern void spa_write_cachefile(spa_t *, boolean_t, boolean_t);
|
extern void spa_write_cachefile(spa_t *, boolean_t, boolean_t, boolean_t);
|
||||||
extern void spa_config_load(void);
|
extern void spa_config_load(void);
|
||||||
extern nvlist_t *spa_all_configs(uint64_t *);
|
extern nvlist_t *spa_all_configs(uint64_t *);
|
||||||
extern void spa_config_set(spa_t *spa, nvlist_t *config);
|
extern void spa_config_set(spa_t *spa, nvlist_t *config);
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ extern int vdev_degrade(spa_t *spa, uint64_t guid, vdev_aux_t aux);
|
|||||||
extern int vdev_online(spa_t *spa, uint64_t guid, uint64_t flags,
|
extern int vdev_online(spa_t *spa, uint64_t guid, uint64_t flags,
|
||||||
vdev_state_t *);
|
vdev_state_t *);
|
||||||
extern int vdev_offline(spa_t *spa, uint64_t guid, uint64_t flags);
|
extern int vdev_offline(spa_t *spa, uint64_t guid, uint64_t flags);
|
||||||
|
extern int vdev_remove_wanted(spa_t *spa, uint64_t guid);
|
||||||
extern void vdev_clear(spa_t *spa, vdev_t *vd);
|
extern void vdev_clear(spa_t *spa, vdev_t *vd);
|
||||||
|
|
||||||
extern boolean_t vdev_is_dead(vdev_t *vd);
|
extern boolean_t vdev_is_dead(vdev_t *vd);
|
||||||
@@ -189,6 +190,8 @@ typedef enum vdev_config_flag {
|
|||||||
VDEV_CONFIG_MISSING = 1 << 4
|
VDEV_CONFIG_MISSING = 1 << 4
|
||||||
} vdev_config_flag_t;
|
} vdev_config_flag_t;
|
||||||
|
|
||||||
|
extern void vdev_post_kobj_evt(vdev_t *vd);
|
||||||
|
extern void vdev_clear_kobj_evt(vdev_t *vd);
|
||||||
extern void vdev_top_config_generate(spa_t *spa, nvlist_t *config);
|
extern void vdev_top_config_generate(spa_t *spa, nvlist_t *config);
|
||||||
extern nvlist_t *vdev_config_generate(spa_t *spa, vdev_t *vd,
|
extern nvlist_t *vdev_config_generate(spa_t *spa, vdev_t *vd,
|
||||||
boolean_t getstats, vdev_config_flag_t flags);
|
boolean_t getstats, vdev_config_flag_t flags);
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ extern uint32_t zfs_vdev_async_write_max_active;
|
|||||||
* Virtual device operations
|
* Virtual device operations
|
||||||
*/
|
*/
|
||||||
typedef int vdev_init_func_t(spa_t *spa, nvlist_t *nv, void **tsd);
|
typedef int vdev_init_func_t(spa_t *spa, nvlist_t *nv, void **tsd);
|
||||||
|
typedef void vdev_kobj_post_evt_func_t(vdev_t *vd);
|
||||||
typedef void vdev_fini_func_t(vdev_t *vd);
|
typedef void vdev_fini_func_t(vdev_t *vd);
|
||||||
typedef int vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *max_size,
|
typedef int vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *max_size,
|
||||||
uint64_t *ashift, uint64_t *pshift);
|
uint64_t *ashift, uint64_t *pshift);
|
||||||
@@ -123,6 +124,7 @@ typedef const struct vdev_ops {
|
|||||||
vdev_config_generate_func_t *vdev_op_config_generate;
|
vdev_config_generate_func_t *vdev_op_config_generate;
|
||||||
vdev_nparity_func_t *vdev_op_nparity;
|
vdev_nparity_func_t *vdev_op_nparity;
|
||||||
vdev_ndisks_func_t *vdev_op_ndisks;
|
vdev_ndisks_func_t *vdev_op_ndisks;
|
||||||
|
vdev_kobj_post_evt_func_t *vdev_op_kobj_evt_post;
|
||||||
char vdev_op_type[16];
|
char vdev_op_type[16];
|
||||||
boolean_t vdev_op_leaf;
|
boolean_t vdev_op_leaf;
|
||||||
} vdev_ops_t;
|
} vdev_ops_t;
|
||||||
@@ -435,6 +437,7 @@ struct vdev {
|
|||||||
boolean_t vdev_isl2cache; /* was a l2cache device */
|
boolean_t vdev_isl2cache; /* was a l2cache device */
|
||||||
boolean_t vdev_copy_uberblocks; /* post expand copy uberblocks */
|
boolean_t vdev_copy_uberblocks; /* post expand copy uberblocks */
|
||||||
boolean_t vdev_resilver_deferred; /* resilver deferred */
|
boolean_t vdev_resilver_deferred; /* resilver deferred */
|
||||||
|
boolean_t vdev_kobj_flag; /* kobj event record */
|
||||||
vdev_queue_t vdev_queue; /* I/O deadline schedule queue */
|
vdev_queue_t vdev_queue; /* I/O deadline schedule queue */
|
||||||
vdev_cache_t vdev_cache; /* physical block cache */
|
vdev_cache_t vdev_cache; /* physical block cache */
|
||||||
spa_aux_vdev_t *vdev_aux; /* for l2cache and spares vdevs */
|
spa_aux_vdev_t *vdev_aux; /* for l2cache and spares vdevs */
|
||||||
|
|||||||
@@ -66,10 +66,9 @@ typedef struct mzap_phys {
|
|||||||
} mzap_phys_t;
|
} mzap_phys_t;
|
||||||
|
|
||||||
typedef struct mzap_ent {
|
typedef struct mzap_ent {
|
||||||
avl_node_t mze_node;
|
uint32_t mze_hash;
|
||||||
int mze_chunkid;
|
uint16_t mze_cd; /* copy from mze_phys->mze_cd */
|
||||||
uint64_t mze_hash;
|
uint16_t mze_chunkid;
|
||||||
uint32_t mze_cd; /* copy from mze_phys->mze_cd */
|
|
||||||
} mzap_ent_t;
|
} mzap_ent_t;
|
||||||
|
|
||||||
#define MZE_PHYS(zap, mze) \
|
#define MZE_PHYS(zap, mze) \
|
||||||
@@ -164,7 +163,7 @@ typedef struct zap {
|
|||||||
int16_t zap_num_entries;
|
int16_t zap_num_entries;
|
||||||
int16_t zap_num_chunks;
|
int16_t zap_num_chunks;
|
||||||
int16_t zap_alloc_next;
|
int16_t zap_alloc_next;
|
||||||
avl_tree_t zap_avl;
|
zfs_btree_t zap_tree;
|
||||||
} zap_micro;
|
} zap_micro;
|
||||||
} zap_u;
|
} zap_u;
|
||||||
} zap_t;
|
} zap_t;
|
||||||
@@ -202,7 +201,7 @@ int zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
|
|||||||
krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp);
|
krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp);
|
||||||
void zap_unlockdir(zap_t *zap, void *tag);
|
void zap_unlockdir(zap_t *zap, void *tag);
|
||||||
void zap_evict_sync(void *dbu);
|
void zap_evict_sync(void *dbu);
|
||||||
zap_name_t *zap_name_alloc(zap_t *zap, const char *key, matchtype_t mt);
|
zap_name_t *zap_name_alloc_str(zap_t *zap, const char *key, matchtype_t mt);
|
||||||
void zap_name_free(zap_name_t *zn);
|
void zap_name_free(zap_name_t *zn);
|
||||||
int zap_hashbits(zap_t *zap);
|
int zap_hashbits(zap_t *zap);
|
||||||
uint32_t zap_maxcd(zap_t *zap);
|
uint32_t zap_maxcd(zap_t *zap);
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ extern "C" {
|
|||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
#include <sys/kmem_cache.h>
|
#include <sys/kmem_cache.h>
|
||||||
#include <sys/vmem.h>
|
#include <sys/vmem.h>
|
||||||
|
#include <sys/misc.h>
|
||||||
#include <sys/taskq.h>
|
#include <sys/taskq.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/disp.h>
|
#include <sys/disp.h>
|
||||||
|
|||||||
@@ -217,9 +217,9 @@ typedef struct znode {
|
|||||||
|
|
||||||
typedef struct znode_hold {
|
typedef struct znode_hold {
|
||||||
uint64_t zh_obj; /* object id */
|
uint64_t zh_obj; /* object id */
|
||||||
kmutex_t zh_lock; /* lock serializing object access */
|
|
||||||
avl_node_t zh_node; /* avl tree linkage */
|
avl_node_t zh_node; /* avl tree linkage */
|
||||||
zfs_refcount_t zh_refcount; /* active consumer reference count */
|
kmutex_t zh_lock; /* lock serializing object access */
|
||||||
|
int zh_refcount; /* active consumer reference count */
|
||||||
} znode_hold_t;
|
} znode_hold_t;
|
||||||
|
|
||||||
static inline uint64_t
|
static inline uint64_t
|
||||||
|
|||||||
@@ -34,9 +34,8 @@ extern "C" {
|
|||||||
|
|
||||||
typedef struct zrlock {
|
typedef struct zrlock {
|
||||||
kmutex_t zr_mtx;
|
kmutex_t zr_mtx;
|
||||||
volatile int32_t zr_refcount;
|
|
||||||
kcondvar_t zr_cv;
|
kcondvar_t zr_cv;
|
||||||
uint16_t zr_pad;
|
volatile int32_t zr_refcount;
|
||||||
#ifdef ZFS_DEBUG
|
#ifdef ZFS_DEBUG
|
||||||
kthread_t *zr_owner;
|
kthread_t *zr_owner;
|
||||||
const char *zr_caller;
|
const char *zr_caller;
|
||||||
|
|||||||
+25
-7
@@ -99,6 +99,7 @@
|
|||||||
<elf-symbol name='sa_validate_shareopts' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='sa_validate_shareopts' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='snapshot_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='snapshot_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='unshare_one' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='unshare_one' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
|
<elf-symbol name='use_color' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zcmd_alloc_dst_nvlist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zcmd_alloc_dst_nvlist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zcmd_expand_dst_nvlist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zcmd_expand_dst_nvlist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zcmd_free_nvlists' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zcmd_free_nvlists' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
@@ -378,6 +379,7 @@
|
|||||||
<elf-symbol name='zpool_vdev_path_to_guid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zpool_vdev_path_to_guid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zpool_vdev_remove' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zpool_vdev_remove' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zpool_vdev_remove_cancel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zpool_vdev_remove_cancel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
|
<elf-symbol name='zpool_vdev_remove_wanted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zpool_vdev_split' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zpool_vdev_split' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zpool_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zpool_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zpool_wait_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zpool_wait_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
@@ -5069,6 +5071,9 @@
|
|||||||
<parameter type-id='9cf59a50'/>
|
<parameter type-id='9cf59a50'/>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='use_color' mangled-name='use_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='use_color'>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
<function-decl name='mkdirp' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='mkdirp' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='80f4b756'/>
|
<parameter type-id='80f4b756'/>
|
||||||
<parameter type-id='d50d396c'/>
|
<parameter type-id='d50d396c'/>
|
||||||
@@ -5858,6 +5863,11 @@
|
|||||||
<parameter type-id='c19b74c3' name='istmp'/>
|
<parameter type-id='c19b74c3' name='istmp'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='zpool_vdev_remove_wanted' mangled-name='zpool_vdev_remove_wanted' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_remove_wanted'>
|
||||||
|
<parameter type-id='4c81de99' name='zhp'/>
|
||||||
|
<parameter type-id='80f4b756' name='path'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
<function-decl name='zpool_vdev_fault' mangled-name='zpool_vdev_fault' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_fault'>
|
<function-decl name='zpool_vdev_fault' mangled-name='zpool_vdev_fault' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_fault'>
|
||||||
<parameter type-id='4c81de99' name='zhp'/>
|
<parameter type-id='4c81de99' name='zhp'/>
|
||||||
<parameter type-id='9c313c2d' name='guid'/>
|
<parameter type-id='9c313c2d' name='guid'/>
|
||||||
@@ -6098,7 +6108,7 @@
|
|||||||
<array-type-def dimensions='1' type-id='b96825af' size-in-bits='64' id='13339fda'>
|
<array-type-def dimensions='1' type-id='b96825af' size-in-bits='64' id='13339fda'>
|
||||||
<subrange length='8' type-id='7359adad' id='56e0c0b1'/>
|
<subrange length='8' type-id='7359adad' id='56e0c0b1'/>
|
||||||
</array-type-def>
|
</array-type-def>
|
||||||
<class-decl name='sendflags' size-in-bits='544' is-struct='yes' visibility='default' id='f6aa15be'>
|
<class-decl name='sendflags' size-in-bits='576' is-struct='yes' visibility='default' id='f6aa15be'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='verbosity' type-id='95e97e5e' visibility='default'/>
|
<var-decl name='verbosity' type-id='95e97e5e' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
@@ -6130,24 +6140,27 @@
|
|||||||
<var-decl name='progress' type-id='c19b74c3' visibility='default'/>
|
<var-decl name='progress' type-id='c19b74c3' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='320'>
|
<data-member access='public' layout-offset-in-bits='320'>
|
||||||
<var-decl name='largeblock' type-id='c19b74c3' visibility='default'/>
|
<var-decl name='progressastitle' type-id='c19b74c3' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='352'>
|
<data-member access='public' layout-offset-in-bits='352'>
|
||||||
<var-decl name='embed_data' type-id='c19b74c3' visibility='default'/>
|
<var-decl name='largeblock' type-id='c19b74c3' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='384'>
|
<data-member access='public' layout-offset-in-bits='384'>
|
||||||
<var-decl name='compress' type-id='c19b74c3' visibility='default'/>
|
<var-decl name='embed_data' type-id='c19b74c3' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='416'>
|
<data-member access='public' layout-offset-in-bits='416'>
|
||||||
<var-decl name='raw' type-id='c19b74c3' visibility='default'/>
|
<var-decl name='compress' type-id='c19b74c3' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='448'>
|
<data-member access='public' layout-offset-in-bits='448'>
|
||||||
<var-decl name='backup' type-id='c19b74c3' visibility='default'/>
|
<var-decl name='raw' type-id='c19b74c3' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='480'>
|
<data-member access='public' layout-offset-in-bits='480'>
|
||||||
<var-decl name='holds' type-id='c19b74c3' visibility='default'/>
|
<var-decl name='backup' type-id='c19b74c3' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
<data-member access='public' layout-offset-in-bits='512'>
|
<data-member access='public' layout-offset-in-bits='512'>
|
||||||
|
<var-decl name='holds' type-id='c19b74c3' visibility='default'/>
|
||||||
|
</data-member>
|
||||||
|
<data-member access='public' layout-offset-in-bits='544'>
|
||||||
<var-decl name='saved' type-id='c19b74c3' visibility='default'/>
|
<var-decl name='saved' type-id='c19b74c3' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
@@ -6728,6 +6741,11 @@
|
|||||||
<parameter type-id='95e97e5e'/>
|
<parameter type-id='95e97e5e'/>
|
||||||
<return type-id='48b5725f'/>
|
<return type-id='48b5725f'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
|
<function-decl name='zfs_setproctitle' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='80f4b756'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
<function-decl name='avl_insert' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='avl_insert' visibility='default' binding='global' size-in-bits='64'>
|
||||||
<parameter type-id='a3681dea'/>
|
<parameter type-id='a3681dea'/>
|
||||||
<parameter type-id='eaa32e2f'/>
|
<parameter type-id='eaa32e2f'/>
|
||||||
|
|||||||
+66
-49
@@ -45,16 +45,21 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sys/zfs_ioctl.h>
|
#include <sys/zfs_ioctl.h>
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
|
#include <libzutil.h>
|
||||||
#include "libzfs_impl.h"
|
#include "libzfs_impl.h"
|
||||||
|
|
||||||
#define ZDIFF_SNAPDIR "/.zfs/snapshot/"
|
#define ZDIFF_SNAPDIR "/.zfs/snapshot/"
|
||||||
#define ZDIFF_PREFIX "zfs-diff-%d"
|
#define ZDIFF_PREFIX "zfs-diff-%d"
|
||||||
|
|
||||||
#define ZDIFF_ADDED '+'
|
#define ZDIFF_ADDED '+'
|
||||||
#define ZDIFF_MODIFIED 'M'
|
#define ZDIFF_MODIFIED "M"
|
||||||
#define ZDIFF_REMOVED '-'
|
#define ZDIFF_REMOVED '-'
|
||||||
#define ZDIFF_RENAMED 'R'
|
#define ZDIFF_RENAMED "R"
|
||||||
|
|
||||||
|
#define ZDIFF_ADDED_COLOR ANSI_GREEN
|
||||||
|
#define ZDIFF_MODIFIED_COLOR ANSI_YELLOW
|
||||||
|
#define ZDIFF_REMOVED_COLOR ANSI_RED
|
||||||
|
#define ZDIFF_RENAMED_COLOR ANSI_BOLD_BLUE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a {dsname, object id}, get the object path
|
* Given a {dsname, object id}, get the object path
|
||||||
@@ -129,48 +134,54 @@ stream_bytes(FILE *fp, const char *string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/*
|
||||||
print_what(FILE *fp, mode_t what)
|
* Takes the type of change (like `print_file`), outputs the appropriate color
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
type_to_color(char type)
|
||||||
{
|
{
|
||||||
char symbol;
|
if (type == '+')
|
||||||
|
return (ZDIFF_ADDED_COLOR);
|
||||||
|
else if (type == '-')
|
||||||
|
return (ZDIFF_REMOVED_COLOR);
|
||||||
|
else if (type == 'M')
|
||||||
|
return (ZDIFF_MODIFIED_COLOR);
|
||||||
|
else if (type == 'R')
|
||||||
|
return (ZDIFF_RENAMED_COLOR);
|
||||||
|
else
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char
|
||||||
|
get_what(mode_t what)
|
||||||
|
{
|
||||||
switch (what & S_IFMT) {
|
switch (what & S_IFMT) {
|
||||||
case S_IFBLK:
|
case S_IFBLK:
|
||||||
symbol = 'B';
|
return ('B');
|
||||||
break;
|
|
||||||
case S_IFCHR:
|
case S_IFCHR:
|
||||||
symbol = 'C';
|
return ('C');
|
||||||
break;
|
|
||||||
case S_IFDIR:
|
case S_IFDIR:
|
||||||
symbol = '/';
|
return ('/');
|
||||||
break;
|
|
||||||
#ifdef S_IFDOOR
|
#ifdef S_IFDOOR
|
||||||
case S_IFDOOR:
|
case S_IFDOOR:
|
||||||
symbol = '>';
|
return ('>');
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
case S_IFIFO:
|
case S_IFIFO:
|
||||||
symbol = '|';
|
return ('|');
|
||||||
break;
|
|
||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
symbol = '@';
|
return ('@');
|
||||||
break;
|
|
||||||
#ifdef S_IFPORT
|
#ifdef S_IFPORT
|
||||||
case S_IFPORT:
|
case S_IFPORT:
|
||||||
symbol = 'P';
|
return ('P');
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
case S_IFSOCK:
|
case S_IFSOCK:
|
||||||
symbol = '=';
|
return ('=');
|
||||||
break;
|
|
||||||
case S_IFREG:
|
case S_IFREG:
|
||||||
symbol = 'F';
|
return ('F');
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
symbol = '?';
|
return ('?');
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
(void) fprintf(fp, "%c", symbol);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -189,57 +200,63 @@ static void
|
|||||||
print_rename(FILE *fp, differ_info_t *di, const char *old, const char *new,
|
print_rename(FILE *fp, differ_info_t *di, const char *old, const char *new,
|
||||||
zfs_stat_t *isb)
|
zfs_stat_t *isb)
|
||||||
{
|
{
|
||||||
|
if (isatty(fileno(fp)))
|
||||||
|
color_start(ZDIFF_RENAMED_COLOR);
|
||||||
if (di->timestamped)
|
if (di->timestamped)
|
||||||
(void) fprintf(fp, "%10lld.%09lld\t",
|
(void) fprintf(fp, "%10lld.%09lld\t",
|
||||||
(longlong_t)isb->zs_ctime[0],
|
(longlong_t)isb->zs_ctime[0],
|
||||||
(longlong_t)isb->zs_ctime[1]);
|
(longlong_t)isb->zs_ctime[1]);
|
||||||
(void) fprintf(fp, "%c\t", ZDIFF_RENAMED);
|
(void) fputs(ZDIFF_RENAMED "\t", fp);
|
||||||
if (di->classify) {
|
if (di->classify)
|
||||||
print_what(fp, isb->zs_mode);
|
(void) fprintf(fp, "%c\t", get_what(isb->zs_mode));
|
||||||
(void) fprintf(fp, "\t");
|
|
||||||
}
|
|
||||||
print_cmn(fp, di, old);
|
print_cmn(fp, di, old);
|
||||||
if (di->scripted)
|
(void) fputs(di->scripted ? "\t" : " -> ", fp);
|
||||||
(void) fprintf(fp, "\t");
|
|
||||||
else
|
|
||||||
(void) fprintf(fp, " -> ");
|
|
||||||
print_cmn(fp, di, new);
|
print_cmn(fp, di, new);
|
||||||
(void) fprintf(fp, "\n");
|
(void) fputc('\n', fp);
|
||||||
|
|
||||||
|
if (isatty(fileno(fp)))
|
||||||
|
color_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_link_change(FILE *fp, differ_info_t *di, int delta, const char *file,
|
print_link_change(FILE *fp, differ_info_t *di, int delta, const char *file,
|
||||||
zfs_stat_t *isb)
|
zfs_stat_t *isb)
|
||||||
{
|
{
|
||||||
|
if (isatty(fileno(fp)))
|
||||||
|
color_start(ZDIFF_MODIFIED_COLOR);
|
||||||
|
|
||||||
if (di->timestamped)
|
if (di->timestamped)
|
||||||
(void) fprintf(fp, "%10lld.%09lld\t",
|
(void) fprintf(fp, "%10lld.%09lld\t",
|
||||||
(longlong_t)isb->zs_ctime[0],
|
(longlong_t)isb->zs_ctime[0],
|
||||||
(longlong_t)isb->zs_ctime[1]);
|
(longlong_t)isb->zs_ctime[1]);
|
||||||
(void) fprintf(fp, "%c\t", ZDIFF_MODIFIED);
|
(void) fputs(ZDIFF_MODIFIED "\t", fp);
|
||||||
if (di->classify) {
|
if (di->classify)
|
||||||
print_what(fp, isb->zs_mode);
|
(void) fprintf(fp, "%c\t", get_what(isb->zs_mode));
|
||||||
(void) fprintf(fp, "\t");
|
|
||||||
}
|
|
||||||
print_cmn(fp, di, file);
|
print_cmn(fp, di, file);
|
||||||
(void) fprintf(fp, "\t(%+d)", delta);
|
(void) fprintf(fp, "\t(%+d)\n", delta);
|
||||||
(void) fprintf(fp, "\n");
|
if (isatty(fileno(fp)))
|
||||||
|
color_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_file(FILE *fp, differ_info_t *di, char type, const char *file,
|
print_file(FILE *fp, differ_info_t *di, char type, const char *file,
|
||||||
zfs_stat_t *isb)
|
zfs_stat_t *isb)
|
||||||
{
|
{
|
||||||
|
if (isatty(fileno(fp)))
|
||||||
|
color_start(type_to_color(type));
|
||||||
|
|
||||||
if (di->timestamped)
|
if (di->timestamped)
|
||||||
(void) fprintf(fp, "%10lld.%09lld\t",
|
(void) fprintf(fp, "%10lld.%09lld\t",
|
||||||
(longlong_t)isb->zs_ctime[0],
|
(longlong_t)isb->zs_ctime[0],
|
||||||
(longlong_t)isb->zs_ctime[1]);
|
(longlong_t)isb->zs_ctime[1]);
|
||||||
(void) fprintf(fp, "%c\t", type);
|
(void) fprintf(fp, "%c\t", type);
|
||||||
if (di->classify) {
|
if (di->classify)
|
||||||
print_what(fp, isb->zs_mode);
|
(void) fprintf(fp, "%c\t", get_what(isb->zs_mode));
|
||||||
(void) fprintf(fp, "\t");
|
|
||||||
}
|
|
||||||
print_cmn(fp, di, file);
|
print_cmn(fp, di, file);
|
||||||
(void) fprintf(fp, "\n");
|
(void) fputc('\n', fp);
|
||||||
|
|
||||||
|
if (isatty(fileno(fp)))
|
||||||
|
color_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -332,7 +349,7 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj)
|
|||||||
print_link_change(fp, di, change,
|
print_link_change(fp, di, change,
|
||||||
change > 0 ? fobjname : tobjname, &tsb);
|
change > 0 ? fobjname : tobjname, &tsb);
|
||||||
} else if (strcmp(fobjname, tobjname) == 0) {
|
} else if (strcmp(fobjname, tobjname) == 0) {
|
||||||
print_file(fp, di, ZDIFF_MODIFIED, fobjname, &tsb);
|
print_file(fp, di, *ZDIFF_MODIFIED, fobjname, &tsb);
|
||||||
} else {
|
} else {
|
||||||
print_rename(fp, di, fobjname, tobjname, &tsb);
|
print_rename(fp, di, fobjname, tobjname, &tsb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3051,7 +3051,7 @@ zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
|
|||||||
|
|
||||||
verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
|
verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
|
||||||
|
|
||||||
if (avail_spare)
|
if (!(flags & ZFS_ONLINE_SPARE) && avail_spare)
|
||||||
return (zfs_error(hdl, EZFS_ISSPARE, msg));
|
return (zfs_error(hdl, EZFS_ISSPARE, msg));
|
||||||
|
|
||||||
if ((flags & ZFS_ONLINE_EXPAND ||
|
if ((flags & ZFS_ONLINE_EXPAND ||
|
||||||
@@ -3158,6 +3158,40 @@ zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove the specified vdev asynchronously from the configuration, so
|
||||||
|
* that it may come ONLINE if reinserted. This is called from zed on
|
||||||
|
* Udev remove event.
|
||||||
|
* Note: We also have a similar function zpool_vdev_remove() that
|
||||||
|
* removes the vdev from the pool.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
zpool_vdev_remove_wanted(zpool_handle_t *zhp, const char *path)
|
||||||
|
{
|
||||||
|
zfs_cmd_t zc = {"\0"};
|
||||||
|
char errbuf[1024];
|
||||||
|
nvlist_t *tgt;
|
||||||
|
boolean_t avail_spare, l2cache;
|
||||||
|
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
||||||
|
|
||||||
|
(void) snprintf(errbuf, sizeof (errbuf),
|
||||||
|
dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
|
||||||
|
|
||||||
|
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
|
||||||
|
if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
|
||||||
|
NULL)) == NULL)
|
||||||
|
return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
|
||||||
|
|
||||||
|
zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
|
||||||
|
|
||||||
|
zc.zc_cookie = VDEV_STATE_REMOVED;
|
||||||
|
|
||||||
|
if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
return (zpool_standard_error(hdl, errno, errbuf));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mark the given vdev faulted.
|
* Mark the given vdev faulted.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ typedef struct progress_arg {
|
|||||||
boolean_t pa_parsable;
|
boolean_t pa_parsable;
|
||||||
boolean_t pa_estimate;
|
boolean_t pa_estimate;
|
||||||
int pa_verbosity;
|
int pa_verbosity;
|
||||||
|
boolean_t pa_astitle;
|
||||||
|
boolean_t pa_progress;
|
||||||
|
uint64_t pa_size;
|
||||||
} progress_arg_t;
|
} progress_arg_t;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -712,6 +715,7 @@ typedef struct send_dump_data {
|
|||||||
boolean_t seenfrom, seento, replicate, doall, fromorigin;
|
boolean_t seenfrom, seento, replicate, doall, fromorigin;
|
||||||
boolean_t dryrun, parsable, progress, embed_data, std_out;
|
boolean_t dryrun, parsable, progress, embed_data, std_out;
|
||||||
boolean_t large_block, compress, raw, holds;
|
boolean_t large_block, compress, raw, holds;
|
||||||
|
boolean_t progressastitle;
|
||||||
int outfd;
|
int outfd;
|
||||||
boolean_t err;
|
boolean_t err;
|
||||||
nvlist_t *fss;
|
nvlist_t *fss;
|
||||||
@@ -904,6 +908,7 @@ send_progress_thread(void *arg)
|
|||||||
zfs_handle_t *zhp = pa->pa_zhp;
|
zfs_handle_t *zhp = pa->pa_zhp;
|
||||||
uint64_t bytes;
|
uint64_t bytes;
|
||||||
uint64_t blocks;
|
uint64_t blocks;
|
||||||
|
uint64_t total = pa->pa_size / 100;
|
||||||
char buf[16];
|
char buf[16];
|
||||||
time_t t;
|
time_t t;
|
||||||
struct tm *tm;
|
struct tm *tm;
|
||||||
@@ -922,7 +927,7 @@ send_progress_thread(void *arg)
|
|||||||
return ((void *)(uintptr_t)err);
|
return ((void *)(uintptr_t)err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstloop && !pa->pa_parsable) {
|
if (firstloop && !pa->pa_parsable && pa->pa_progress) {
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"TIME %s %sSNAPSHOT %s\n",
|
"TIME %s %sSNAPSHOT %s\n",
|
||||||
pa->pa_estimate ? "BYTES" : " SENT",
|
pa->pa_estimate ? "BYTES" : " SENT",
|
||||||
@@ -934,6 +939,17 @@ send_progress_thread(void *arg)
|
|||||||
(void) time(&t);
|
(void) time(&t);
|
||||||
tm = localtime(&t);
|
tm = localtime(&t);
|
||||||
|
|
||||||
|
if (pa->pa_astitle) {
|
||||||
|
char buf_bytes[16];
|
||||||
|
char buf_size[16];
|
||||||
|
int pct;
|
||||||
|
zfs_nicenum(bytes, buf_bytes, sizeof (buf_bytes));
|
||||||
|
zfs_nicenum(pa->pa_size, buf_size, sizeof (buf_size));
|
||||||
|
pct = (total > 0) ? bytes / total : 100;
|
||||||
|
zfs_setproctitle("sending %s (%d%%: %s/%s)",
|
||||||
|
zhp->zfs_name, MIN(pct, 100), buf_bytes, buf_size);
|
||||||
|
}
|
||||||
|
|
||||||
if (pa->pa_verbosity >= 2 && pa->pa_parsable) {
|
if (pa->pa_verbosity >= 2 && pa->pa_parsable) {
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"%02d:%02d:%02d\t%llu\t%llu\t%s\n",
|
"%02d:%02d:%02d\t%llu\t%llu\t%s\n",
|
||||||
@@ -950,7 +966,7 @@ send_progress_thread(void *arg)
|
|||||||
(void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n",
|
(void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n",
|
||||||
tm->tm_hour, tm->tm_min, tm->tm_sec,
|
tm->tm_hour, tm->tm_min, tm->tm_sec,
|
||||||
(u_longlong_t)bytes, zhp->zfs_name);
|
(u_longlong_t)bytes, zhp->zfs_name);
|
||||||
} else {
|
} else if (pa->pa_progress) {
|
||||||
zfs_nicebytes(bytes, buf, sizeof (buf));
|
zfs_nicebytes(bytes, buf, sizeof (buf));
|
||||||
(void) fprintf(stderr, "%02d:%02d:%02d %5s %s\n",
|
(void) fprintf(stderr, "%02d:%02d:%02d %5s %s\n",
|
||||||
tm->tm_hour, tm->tm_min, tm->tm_sec,
|
tm->tm_hour, tm->tm_min, tm->tm_sec,
|
||||||
@@ -1114,12 +1130,15 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
|
|||||||
* If progress reporting is requested, spawn a new thread to
|
* If progress reporting is requested, spawn a new thread to
|
||||||
* poll ZFS_IOC_SEND_PROGRESS at a regular interval.
|
* poll ZFS_IOC_SEND_PROGRESS at a regular interval.
|
||||||
*/
|
*/
|
||||||
if (sdd->progress) {
|
if (sdd->progress || sdd->progressastitle) {
|
||||||
pa.pa_zhp = zhp;
|
pa.pa_zhp = zhp;
|
||||||
pa.pa_fd = sdd->outfd;
|
pa.pa_fd = sdd->outfd;
|
||||||
pa.pa_parsable = sdd->parsable;
|
pa.pa_parsable = sdd->parsable;
|
||||||
pa.pa_estimate = B_FALSE;
|
pa.pa_estimate = B_FALSE;
|
||||||
pa.pa_verbosity = sdd->verbosity;
|
pa.pa_verbosity = sdd->verbosity;
|
||||||
|
pa.pa_size = sdd->size;
|
||||||
|
pa.pa_astitle = sdd->progressastitle;
|
||||||
|
pa.pa_progress = sdd->progress;
|
||||||
|
|
||||||
if ((err = pthread_create(&tid, NULL,
|
if ((err = pthread_create(&tid, NULL,
|
||||||
send_progress_thread, &pa)) != 0) {
|
send_progress_thread, &pa)) != 0) {
|
||||||
@@ -1131,7 +1150,7 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
|
|||||||
err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
|
err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
|
||||||
fromorigin, sdd->outfd, flags, sdd->debugnv);
|
fromorigin, sdd->outfd, flags, sdd->debugnv);
|
||||||
|
|
||||||
if (sdd->progress) {
|
if (sdd->progress || sdd->progressastitle) {
|
||||||
void *status = NULL;
|
void *status = NULL;
|
||||||
(void) pthread_cancel(tid);
|
(void) pthread_cancel(tid);
|
||||||
(void) pthread_join(tid, &status);
|
(void) pthread_join(tid, &status);
|
||||||
@@ -1462,7 +1481,7 @@ lzc_flags_from_sendflags(const sendflags_t *flags)
|
|||||||
static int
|
static int
|
||||||
estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
|
estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
|
||||||
uint64_t resumeobj, uint64_t resumeoff, uint64_t bytes,
|
uint64_t resumeobj, uint64_t resumeoff, uint64_t bytes,
|
||||||
const char *redactbook, char *errbuf)
|
const char *redactbook, char *errbuf, uint64_t *sizep)
|
||||||
{
|
{
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
FILE *fout = flags->dryrun ? stdout : stderr;
|
FILE *fout = flags->dryrun ? stdout : stderr;
|
||||||
@@ -1470,7 +1489,7 @@ estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
pthread_t ptid;
|
pthread_t ptid;
|
||||||
|
|
||||||
if (flags->progress) {
|
if (flags->progress || flags->progressastitle) {
|
||||||
pa.pa_zhp = zhp;
|
pa.pa_zhp = zhp;
|
||||||
pa.pa_fd = fd;
|
pa.pa_fd = fd;
|
||||||
pa.pa_parsable = flags->parsable;
|
pa.pa_parsable = flags->parsable;
|
||||||
@@ -1489,8 +1508,9 @@ estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
|
|||||||
err = lzc_send_space_resume_redacted(zhp->zfs_name, from,
|
err = lzc_send_space_resume_redacted(zhp->zfs_name, from,
|
||||||
lzc_flags_from_sendflags(flags), resumeobj, resumeoff, bytes,
|
lzc_flags_from_sendflags(flags), resumeobj, resumeoff, bytes,
|
||||||
redactbook, fd, &size);
|
redactbook, fd, &size);
|
||||||
|
*sizep = size;
|
||||||
|
|
||||||
if (flags->progress) {
|
if (flags->progress || flags->progressastitle) {
|
||||||
void *status = NULL;
|
void *status = NULL;
|
||||||
(void) pthread_cancel(ptid);
|
(void) pthread_cancel(ptid);
|
||||||
(void) pthread_join(ptid, &status);
|
(void) pthread_join(ptid, &status);
|
||||||
@@ -1505,6 +1525,9 @@ estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!flags->progress && !flags->parsable)
|
||||||
|
return (err);
|
||||||
|
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err));
|
zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err));
|
||||||
return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
|
return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
|
||||||
@@ -1638,6 +1661,7 @@ zfs_send_resume_impl(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
|
|||||||
uint64_t *redact_snap_guids = NULL;
|
uint64_t *redact_snap_guids = NULL;
|
||||||
int num_redact_snaps = 0;
|
int num_redact_snaps = 0;
|
||||||
char *redact_book = NULL;
|
char *redact_book = NULL;
|
||||||
|
uint64_t size = 0;
|
||||||
|
|
||||||
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
||||||
"cannot resume send"));
|
"cannot resume send"));
|
||||||
@@ -1731,7 +1755,7 @@ zfs_send_resume_impl(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags->verbosity != 0) {
|
if (flags->verbosity != 0 || flags->progressastitle) {
|
||||||
/*
|
/*
|
||||||
* Some of these may have come from the resume token, set them
|
* Some of these may have come from the resume token, set them
|
||||||
* here for size estimate purposes.
|
* here for size estimate purposes.
|
||||||
@@ -1748,7 +1772,7 @@ zfs_send_resume_impl(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
|
|||||||
if (lzc_flags & LZC_SEND_FLAG_SAVED)
|
if (lzc_flags & LZC_SEND_FLAG_SAVED)
|
||||||
tmpflags.saved = B_TRUE;
|
tmpflags.saved = B_TRUE;
|
||||||
error = estimate_size(zhp, fromname, outfd, &tmpflags,
|
error = estimate_size(zhp, fromname, outfd, &tmpflags,
|
||||||
resumeobj, resumeoff, bytes, redact_book, errbuf);
|
resumeobj, resumeoff, bytes, redact_book, errbuf, &size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!flags->dryrun) {
|
if (!flags->dryrun) {
|
||||||
@@ -1758,12 +1782,15 @@ zfs_send_resume_impl(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
|
|||||||
* If progress reporting is requested, spawn a new thread to
|
* If progress reporting is requested, spawn a new thread to
|
||||||
* poll ZFS_IOC_SEND_PROGRESS at a regular interval.
|
* poll ZFS_IOC_SEND_PROGRESS at a regular interval.
|
||||||
*/
|
*/
|
||||||
if (flags->progress) {
|
if (flags->progress || flags->progressastitle) {
|
||||||
pa.pa_zhp = zhp;
|
pa.pa_zhp = zhp;
|
||||||
pa.pa_fd = outfd;
|
pa.pa_fd = outfd;
|
||||||
pa.pa_parsable = flags->parsable;
|
pa.pa_parsable = flags->parsable;
|
||||||
pa.pa_estimate = B_FALSE;
|
pa.pa_estimate = B_FALSE;
|
||||||
pa.pa_verbosity = flags->verbosity;
|
pa.pa_verbosity = flags->verbosity;
|
||||||
|
pa.pa_size = size;
|
||||||
|
pa.pa_astitle = flags->progressastitle;
|
||||||
|
pa.pa_progress = flags->progress;
|
||||||
|
|
||||||
error = pthread_create(&tid, NULL,
|
error = pthread_create(&tid, NULL,
|
||||||
send_progress_thread, &pa);
|
send_progress_thread, &pa);
|
||||||
@@ -1780,7 +1807,7 @@ zfs_send_resume_impl(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
|
|||||||
if (redact_book != NULL)
|
if (redact_book != NULL)
|
||||||
free(redact_book);
|
free(redact_book);
|
||||||
|
|
||||||
if (flags->progress) {
|
if (flags->progress || flags->progress) {
|
||||||
void *status = NULL;
|
void *status = NULL;
|
||||||
(void) pthread_cancel(tid);
|
(void) pthread_cancel(tid);
|
||||||
(void) pthread_join(tid, &status);
|
(void) pthread_join(tid, &status);
|
||||||
@@ -1790,6 +1817,7 @@ zfs_send_resume_impl(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
|
|||||||
(void) snprintf(errbuf, sizeof (errbuf),
|
(void) snprintf(errbuf, sizeof (errbuf),
|
||||||
dgettext(TEXT_DOMAIN,
|
dgettext(TEXT_DOMAIN,
|
||||||
"progress thread exited nonzero"));
|
"progress thread exited nonzero"));
|
||||||
|
zfs_close(zhp);
|
||||||
return (zfs_standard_error(hdl, error, errbuf));
|
return (zfs_standard_error(hdl, error, errbuf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2199,6 +2227,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
|
|||||||
sdd.verbosity = flags->verbosity;
|
sdd.verbosity = flags->verbosity;
|
||||||
sdd.parsable = flags->parsable;
|
sdd.parsable = flags->parsable;
|
||||||
sdd.progress = flags->progress;
|
sdd.progress = flags->progress;
|
||||||
|
sdd.progressastitle = flags->progressastitle;
|
||||||
sdd.dryrun = flags->dryrun;
|
sdd.dryrun = flags->dryrun;
|
||||||
sdd.large_block = flags->largeblock;
|
sdd.large_block = flags->largeblock;
|
||||||
sdd.embed_data = flags->embed_data;
|
sdd.embed_data = flags->embed_data;
|
||||||
@@ -2410,6 +2439,7 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
|
|||||||
char *name = zhp->zfs_name;
|
char *name = zhp->zfs_name;
|
||||||
pthread_t ptid;
|
pthread_t ptid;
|
||||||
progress_arg_t pa = { 0 };
|
progress_arg_t pa = { 0 };
|
||||||
|
uint64_t size = 0;
|
||||||
|
|
||||||
char errbuf[1024];
|
char errbuf[1024];
|
||||||
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
||||||
@@ -2492,9 +2522,9 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
|
|||||||
/*
|
/*
|
||||||
* Perform size estimate if verbose was specified.
|
* Perform size estimate if verbose was specified.
|
||||||
*/
|
*/
|
||||||
if (flags->verbosity != 0) {
|
if (flags->verbosity != 0 || flags->progressastitle) {
|
||||||
err = estimate_size(zhp, from, fd, flags, 0, 0, 0, redactbook,
|
err = estimate_size(zhp, from, fd, flags, 0, 0, 0, redactbook,
|
||||||
errbuf);
|
errbuf, &size);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
@@ -2506,12 +2536,15 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
|
|||||||
* If progress reporting is requested, spawn a new thread to poll
|
* If progress reporting is requested, spawn a new thread to poll
|
||||||
* ZFS_IOC_SEND_PROGRESS at a regular interval.
|
* ZFS_IOC_SEND_PROGRESS at a regular interval.
|
||||||
*/
|
*/
|
||||||
if (flags->progress) {
|
if (flags->progress || flags->progressastitle) {
|
||||||
pa.pa_zhp = zhp;
|
pa.pa_zhp = zhp;
|
||||||
pa.pa_fd = fd;
|
pa.pa_fd = fd;
|
||||||
pa.pa_parsable = flags->parsable;
|
pa.pa_parsable = flags->parsable;
|
||||||
pa.pa_estimate = B_FALSE;
|
pa.pa_estimate = B_FALSE;
|
||||||
pa.pa_verbosity = flags->verbosity;
|
pa.pa_verbosity = flags->verbosity;
|
||||||
|
pa.pa_size = size;
|
||||||
|
pa.pa_astitle = flags->progressastitle;
|
||||||
|
pa.pa_progress = flags->progress;
|
||||||
|
|
||||||
err = pthread_create(&ptid, NULL,
|
err = pthread_create(&ptid, NULL,
|
||||||
send_progress_thread, &pa);
|
send_progress_thread, &pa);
|
||||||
@@ -2525,7 +2558,7 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
|
|||||||
err = lzc_send_redacted(name, from, fd,
|
err = lzc_send_redacted(name, from, fd,
|
||||||
lzc_flags_from_sendflags(flags), redactbook);
|
lzc_flags_from_sendflags(flags), redactbook);
|
||||||
|
|
||||||
if (flags->progress) {
|
if (flags->progress || flags->progressastitle) {
|
||||||
void *status = NULL;
|
void *status = NULL;
|
||||||
(void) pthread_cancel(ptid);
|
(void) pthread_cancel(ptid);
|
||||||
(void) pthread_join(ptid, &status);
|
(void) pthread_join(ptid, &status);
|
||||||
@@ -3966,6 +3999,15 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For plain replicated send, we can ignore encryption
|
||||||
|
* properties other than first stream
|
||||||
|
*/
|
||||||
|
if ((zfs_prop_encryption_key_param(prop) || prop ==
|
||||||
|
ZFS_PROP_ENCRYPTION) && !newfs && recursive && !raw) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* incremental streams can only exclude encryption properties */
|
/* incremental streams can only exclude encryption properties */
|
||||||
if ((zfs_prop_encryption_key_param(prop) ||
|
if ((zfs_prop_encryption_key_param(prop) ||
|
||||||
prop == ZFS_PROP_ENCRYPTION) && !newfs &&
|
prop == ZFS_PROP_ENCRYPTION) && !newfs &&
|
||||||
@@ -4065,7 +4107,8 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
|
|||||||
if (cp != NULL)
|
if (cp != NULL)
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
|
|
||||||
if (!raw && zfs_crypto_create(hdl, namebuf, voprops, NULL,
|
if (!raw && !(!newfs && recursive) &&
|
||||||
|
zfs_crypto_create(hdl, namebuf, voprops, NULL,
|
||||||
B_FALSE, wkeydata_out, wkeylen_out) != 0) {
|
B_FALSE, wkeydata_out, wkeylen_out) != 0) {
|
||||||
fnvlist_free(voprops);
|
fnvlist_free(voprops);
|
||||||
ret = zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
|
ret = zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
|
||||||
|
|||||||
+18
-11
@@ -2027,7 +2027,7 @@ zfs_version_print(void)
|
|||||||
* Return 1 if the user requested ANSI color output, and our terminal supports
|
* Return 1 if the user requested ANSI color output, and our terminal supports
|
||||||
* it. Return 0 for no color.
|
* it. Return 0 for no color.
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
use_color(void)
|
use_color(void)
|
||||||
{
|
{
|
||||||
static int use_color = -1;
|
static int use_color = -1;
|
||||||
@@ -2073,31 +2073,38 @@ use_color(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* color_start() and color_end() are used for when you want to colorize a block
|
* The functions color_start() and color_end() are used for when you want
|
||||||
* of text. For example:
|
* to colorize a block of text.
|
||||||
*
|
*
|
||||||
* color_start(ANSI_RED_FG)
|
* For example:
|
||||||
|
* color_start(ANSI_RED)
|
||||||
* printf("hello");
|
* printf("hello");
|
||||||
* printf("world");
|
* printf("world");
|
||||||
* color_end();
|
* color_end();
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
color_start(char *color)
|
color_start(const char *color)
|
||||||
{
|
{
|
||||||
if (use_color())
|
if (color && use_color()) {
|
||||||
printf("%s", color);
|
fputs(color, stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
color_end(void)
|
color_end(void)
|
||||||
{
|
{
|
||||||
if (use_color())
|
if (use_color()) {
|
||||||
printf(ANSI_RESET);
|
fputs(ANSI_RESET, stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* printf() with a color. If color is NULL, then do a normal printf. */
|
/*
|
||||||
|
* printf() with a color. If color is NULL, then do a normal printf.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
printf_color(char *color, char *format, ...)
|
printf_color(const char *color, char *format, ...)
|
||||||
{
|
{
|
||||||
va_list aptr;
|
va_list aptr;
|
||||||
int rc;
|
int rc;
|
||||||
|
|||||||
@@ -35,6 +35,22 @@
|
|||||||
void
|
void
|
||||||
libzfs_set_pipe_max(int infd)
|
libzfs_set_pipe_max(int infd)
|
||||||
{
|
{
|
||||||
|
#if __linux__
|
||||||
|
/*
|
||||||
|
* Sadly, Linux has an unfixed deadlock if you do SETPIPE_SZ on a pipe
|
||||||
|
* with data in it.
|
||||||
|
* cf. #13232, https://bugzilla.kernel.org/show_bug.cgi?id=212295
|
||||||
|
*
|
||||||
|
* And since the problem is in waking up the writer, there's nothing
|
||||||
|
* we can do about it from here.
|
||||||
|
*
|
||||||
|
* So if people want to, they can set this, but they
|
||||||
|
* may regret it...
|
||||||
|
*/
|
||||||
|
if (getenv("ZFS_SET_PIPE_MAX") == NULL)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
FILE *procf = fopen("/proc/sys/fs/pipe-max-size", "re");
|
FILE *procf = fopen("/proc/sys/fs/pipe-max-size", "re");
|
||||||
|
|
||||||
if (procf != NULL) {
|
if (procf != NULL) {
|
||||||
|
|||||||
@@ -272,6 +272,8 @@
|
|||||||
<elf-symbol name='zfs_niceraw' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zfs_niceraw' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zfs_nicetime' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zfs_nicetime' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zfs_resolve_shortname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zfs_resolve_shortname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
|
<elf-symbol name='zfs_setproctitle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
|
<elf-symbol name='zfs_setproctitle_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zfs_strcmp_pathname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zfs_strcmp_pathname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zfs_strip_partition' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zfs_strip_partition' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
<elf-symbol name='zfs_strip_path' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
<elf-symbol name='zfs_strip_path' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||||
@@ -3340,6 +3342,30 @@
|
|||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
</abi-instr>
|
</abi-instr>
|
||||||
|
<abi-instr address-size='64' path='os/linux/zutil_setproctitle.c' language='LANG_C99'>
|
||||||
|
<function-decl name='warnx' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='80f4b756'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='setenv' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
<parameter type-id='80f4b756'/>
|
||||||
|
<parameter type-id='80f4b756'/>
|
||||||
|
<parameter type-id='95e97e5e'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='zfs_setproctitle_init' mangled-name='zfs_setproctitle_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_setproctitle_init'>
|
||||||
|
<parameter type-id='95e97e5e' name='argc'/>
|
||||||
|
<parameter type-id='9b23c9ad' name='argv'/>
|
||||||
|
<parameter type-id='9b23c9ad' name='envp'/>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='zfs_setproctitle' mangled-name='zfs_setproctitle' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_setproctitle'>
|
||||||
|
<parameter type-id='80f4b756' name='fmt'/>
|
||||||
|
<parameter is-variadic='yes'/>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
</abi-instr>
|
||||||
<abi-instr address-size='64' path='zutil_device_path.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='zutil_device_path.c' language='LANG_C99'>
|
||||||
<qualified-type-def type-id='26a90f95' restrict='yes' id='266fe297'/>
|
<qualified-type-def type-id='26a90f95' restrict='yes' id='266fe297'/>
|
||||||
<qualified-type-def type-id='80f4b756' const='yes' id='b99c00c9'/>
|
<qualified-type-def type-id='80f4b756' const='yes' id='b99c00c9'/>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ USER_C = \
|
|||||||
|
|
||||||
if BUILD_LINUX
|
if BUILD_LINUX
|
||||||
USER_C += \
|
USER_C += \
|
||||||
|
os/linux/zutil_setproctitle.c \
|
||||||
os/linux/zutil_device_path_os.c \
|
os/linux/zutil_device_path_os.c \
|
||||||
os/linux/zutil_import_os.c \
|
os/linux/zutil_import_os.c \
|
||||||
os/linux/zutil_compat.c
|
os/linux/zutil_compat.c
|
||||||
|
|||||||
@@ -0,0 +1,299 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2013 Guillem Jover <guillem@hadrons.org>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <libzutil.h>
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
/* Original value. */
|
||||||
|
const char *arg0;
|
||||||
|
|
||||||
|
/* Title space available. */
|
||||||
|
char *base, *end;
|
||||||
|
|
||||||
|
/* Pointer to original nul character within base. */
|
||||||
|
char *nul;
|
||||||
|
|
||||||
|
boolean_t warned;
|
||||||
|
boolean_t reset;
|
||||||
|
int error;
|
||||||
|
} SPT;
|
||||||
|
|
||||||
|
#define LIBBSD_IS_PATHNAME_SEPARATOR(c) ((c) == '/')
|
||||||
|
#define SPT_MAXTITLE 255
|
||||||
|
|
||||||
|
extern const char *__progname;
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
getprogname(void)
|
||||||
|
{
|
||||||
|
return (__progname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setprogname(const char *progname)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = strlen(progname); i > 0; i--) {
|
||||||
|
if (LIBBSD_IS_PATHNAME_SEPARATOR(progname[i - 1])) {
|
||||||
|
__progname = progname + i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__progname = progname;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline size_t
|
||||||
|
spt_min(size_t a, size_t b)
|
||||||
|
{
|
||||||
|
return ((a < b) ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For discussion on the portability of the various methods, see
|
||||||
|
* https://lists.freebsd.org/pipermail/freebsd-stable/2008-June/043136.html
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
spt_clearenv(void)
|
||||||
|
{
|
||||||
|
char **tmp;
|
||||||
|
|
||||||
|
tmp = malloc(sizeof (*tmp));
|
||||||
|
if (tmp == NULL)
|
||||||
|
return (errno);
|
||||||
|
|
||||||
|
tmp[0] = NULL;
|
||||||
|
environ = tmp;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
spt_copyenv(int envc, char *envp[])
|
||||||
|
{
|
||||||
|
char **envcopy;
|
||||||
|
char *eq;
|
||||||
|
int envsize;
|
||||||
|
int i, error;
|
||||||
|
|
||||||
|
if (environ != envp)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make a copy of the old environ array of pointers, in case
|
||||||
|
* clearenv() or setenv() is implemented to free the internal
|
||||||
|
* environ array, because we will need to access the old environ
|
||||||
|
* contents to make the new copy.
|
||||||
|
*/
|
||||||
|
envsize = (envc + 1) * sizeof (char *);
|
||||||
|
envcopy = malloc(envsize);
|
||||||
|
if (envcopy == NULL)
|
||||||
|
return (errno);
|
||||||
|
memcpy(envcopy, envp, envsize);
|
||||||
|
|
||||||
|
error = spt_clearenv();
|
||||||
|
if (error) {
|
||||||
|
environ = envp;
|
||||||
|
free(envcopy);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; envcopy[i]; i++) {
|
||||||
|
eq = strchr(envcopy[i], '=');
|
||||||
|
if (eq == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*eq = '\0';
|
||||||
|
if (setenv(envcopy[i], eq + 1, 1) < 0)
|
||||||
|
error = errno;
|
||||||
|
*eq = '=';
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
environ = envp;
|
||||||
|
free(envcopy);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dispose of the shallow copy, now that we've finished transfering
|
||||||
|
* the old environment.
|
||||||
|
*/
|
||||||
|
free(envcopy);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
spt_copyargs(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; i < argc || (i >= argc && argv[i]); i++) {
|
||||||
|
if (argv[i] == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tmp = strdup(argv[i]);
|
||||||
|
if (tmp == NULL)
|
||||||
|
return (errno);
|
||||||
|
|
||||||
|
argv[i] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zfs_setproctitle_init(int argc, char *argv[], char *envp[])
|
||||||
|
{
|
||||||
|
char *base, *end, *nul, *tmp;
|
||||||
|
int i, envc, error;
|
||||||
|
|
||||||
|
/* Try to make sure we got called with main() arguments. */
|
||||||
|
if (argc < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
base = argv[0];
|
||||||
|
if (base == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nul = base + strlen(base);
|
||||||
|
end = nul + 1;
|
||||||
|
|
||||||
|
for (i = 0; i < argc || (i >= argc && argv[i]); i++) {
|
||||||
|
if (argv[i] == NULL || argv[i] != end)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
end = argv[i] + strlen(argv[i]) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; envp[i]; i++) {
|
||||||
|
if (envp[i] != end)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
end = envp[i] + strlen(envp[i]) + 1;
|
||||||
|
}
|
||||||
|
envc = i;
|
||||||
|
|
||||||
|
SPT.arg0 = strdup(argv[0]);
|
||||||
|
if (SPT.arg0 == NULL) {
|
||||||
|
SPT.error = errno;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = strdup(getprogname());
|
||||||
|
if (tmp == NULL) {
|
||||||
|
SPT.error = errno;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setprogname(tmp);
|
||||||
|
|
||||||
|
error = spt_copyenv(envc, envp);
|
||||||
|
if (error) {
|
||||||
|
SPT.error = error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = spt_copyargs(argc, argv);
|
||||||
|
if (error) {
|
||||||
|
SPT.error = error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SPT.nul = nul;
|
||||||
|
SPT.base = base;
|
||||||
|
SPT.end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zfs_setproctitle(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
/* Use buffer in case argv[0] is passed. */
|
||||||
|
char buf[SPT_MAXTITLE + 1];
|
||||||
|
va_list ap;
|
||||||
|
char *nul;
|
||||||
|
int len;
|
||||||
|
if (SPT.base == NULL) {
|
||||||
|
if (!SPT.warned) {
|
||||||
|
warnx("setproctitle not initialized, please"
|
||||||
|
"call zfs_setproctitle_init()");
|
||||||
|
SPT.warned = B_TRUE;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fmt) {
|
||||||
|
if (fmt[0] == '-') {
|
||||||
|
/* Skip program name prefix. */
|
||||||
|
fmt++;
|
||||||
|
len = 0;
|
||||||
|
} else {
|
||||||
|
/* Print program name heading for grep. */
|
||||||
|
snprintf(buf, sizeof (buf), "%s: ", getprogname());
|
||||||
|
len = strlen(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
len += vsnprintf(buf + len, sizeof (buf) - len, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
} else {
|
||||||
|
len = snprintf(buf, sizeof (buf), "%s", SPT.arg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len <= 0) {
|
||||||
|
SPT.error = errno;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SPT.reset) {
|
||||||
|
memset(SPT.base, 0, SPT.end - SPT.base);
|
||||||
|
SPT.reset = B_TRUE;
|
||||||
|
} else {
|
||||||
|
memset(SPT.base, 0, spt_min(sizeof (buf), SPT.end - SPT.base));
|
||||||
|
}
|
||||||
|
|
||||||
|
len = spt_min(len, spt_min(sizeof (buf), SPT.end - SPT.base) - 1);
|
||||||
|
memcpy(SPT.base, buf, len);
|
||||||
|
nul = SPT.base + len;
|
||||||
|
|
||||||
|
if (nul < SPT.nul) {
|
||||||
|
*SPT.nul = '.';
|
||||||
|
} else if (nul == SPT.nul && nul + 1 < SPT.end) {
|
||||||
|
*SPT.nul = ' ';
|
||||||
|
*++nul = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
-1
@@ -15,7 +15,7 @@
|
|||||||
.\" own identifying information:
|
.\" own identifying information:
|
||||||
.\" Portions Copyright [yyyy] [name of copyright owner]
|
.\" Portions Copyright [yyyy] [name of copyright owner]
|
||||||
.\"
|
.\"
|
||||||
.Dd June 1, 2021
|
.Dd January 10, 2023
|
||||||
.Dt ZFS 4
|
.Dt ZFS 4
|
||||||
.Os
|
.Os
|
||||||
.
|
.
|
||||||
@@ -233,6 +233,12 @@ relative to the pool.
|
|||||||
Make some blocks above a certain size be gang blocks.
|
Make some blocks above a certain size be gang blocks.
|
||||||
This option is used by the test suite to facilitate testing.
|
This option is used by the test suite to facilitate testing.
|
||||||
.
|
.
|
||||||
|
.It Sy zfs_default_bs Ns = Ns Sy 9 Po 512 B Pc Pq int
|
||||||
|
Default dnode block size as a power of 2.
|
||||||
|
.
|
||||||
|
.It Sy zfs_default_ibs Ns = Ns Sy 17 Po 128 KiB Pc Pq int
|
||||||
|
Default dnode indirect block size as a power of 2.
|
||||||
|
.
|
||||||
.It Sy zfs_history_output_max Ns = Ns Sy 1048576 Ns B Ns B Po 1MB Pc Pq int
|
.It Sy zfs_history_output_max Ns = Ns Sy 1048576 Ns B Ns B Po 1MB Pc Pq int
|
||||||
When attempting to log an output nvlist of an ioctl in the on-disk history,
|
When attempting to log an output nvlist of an ioctl in the on-disk history,
|
||||||
the output will not be stored if it is larger than this size (in bytes).
|
the output will not be stored if it is larger than this size (in bytes).
|
||||||
@@ -2126,6 +2132,13 @@ On very fragmented pools, lowering this
|
|||||||
.Pq typically to Sy 36kB
|
.Pq typically to Sy 36kB
|
||||||
can improve performance.
|
can improve performance.
|
||||||
.
|
.
|
||||||
|
.It Sy zil_min_commit_timeout Ns = Ns Sy 5000 Pq u64
|
||||||
|
This sets the minimum delay in nanoseconds ZIL care to delay block commit,
|
||||||
|
waiting for more records.
|
||||||
|
If ZIL writes are too fast, kernel may not be able sleep for so short interval,
|
||||||
|
increasing log latency above allowed by
|
||||||
|
.Sy zfs_commit_timeout_pct .
|
||||||
|
.
|
||||||
.It Sy zil_nocacheflush Ns = Ns Sy 0 Ns | Ns 1 Pq int
|
.It Sy zil_nocacheflush Ns = Ns Sy 0 Ns | Ns 1 Pq int
|
||||||
Disable the cache flush commands that are normally sent to disk by
|
Disable the cache flush commands that are normally sent to disk by
|
||||||
the ZIL after an LWB write has completed.
|
the ZIL after an LWB write has completed.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
.\" SPDX-License-Identifier: 0BSD
|
.\" SPDX-License-Identifier: 0BSD
|
||||||
.\"
|
.\"
|
||||||
.Dd April 4, 2022
|
.Dd March 28, 2023
|
||||||
.Dt DRACUT.ZFS 7
|
.Dt DRACUT.ZFS 7
|
||||||
.Os
|
.Os
|
||||||
.
|
.
|
||||||
@@ -28,13 +28,13 @@ zfs-import-scan.service \(da \(da | zfs-import-c
|
|||||||
zfs-import.target \(-> dracut-pre-mount.service
|
zfs-import.target \(-> dracut-pre-mount.service
|
||||||
| \(ua |
|
| \(ua |
|
||||||
| dracut-zfs-generator |
|
| dracut-zfs-generator |
|
||||||
| ____________________/|
|
| _____________________/|
|
||||||
|/ \(da
|
|/ \(da
|
||||||
| sysroot.mount \(<-\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em dracut-zfs-generator
|
| sysroot.mount \(<-\(em\(em\(em dracut-zfs-generator
|
||||||
| | \(da |
|
| |
|
||||||
| \(da sysroot-{usr,etc,lib,&c.}.mount |
|
| \(da
|
||||||
| initrd-root-fs.target \(<-\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em or \(da
|
| initrd-root-fs.target \(<-\(em zfs-nonroot-necessities.service
|
||||||
| | zfs-nonroot-necessities.service
|
| | |
|
||||||
| \(da |
|
| \(da |
|
||||||
\(da dracut-mount.service |
|
\(da dracut-mount.service |
|
||||||
zfs-snapshot-bootfs.service | |
|
zfs-snapshot-bootfs.service | |
|
||||||
@@ -42,7 +42,7 @@ zfs-import-scan.service \(da \(da | zfs-import-c
|
|||||||
\(da … |
|
\(da … |
|
||||||
zfs-rollback-bootfs.service | |
|
zfs-rollback-bootfs.service | |
|
||||||
| \(da |
|
| \(da |
|
||||||
| sysroot-usr.mount \(<-\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em/
|
| /sysroot/{usr,etc,lib,&c.} \(<-\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em\(em/
|
||||||
| |
|
| |
|
||||||
| \(da
|
| \(da
|
||||||
| initrd-fs.target
|
| initrd-fs.target
|
||||||
|
|||||||
+13
-11
@@ -29,7 +29,7 @@
|
|||||||
.\" Copyright 2018 Nexenta Systems, Inc.
|
.\" Copyright 2018 Nexenta Systems, Inc.
|
||||||
.\" Copyright 2019 Joyent, Inc.
|
.\" Copyright 2019 Joyent, Inc.
|
||||||
.\"
|
.\"
|
||||||
.Dd April 15, 2021
|
.Dd January 12, 2023
|
||||||
.Dt ZFS-SEND 8
|
.Dt ZFS-SEND 8
|
||||||
.Os
|
.Os
|
||||||
.
|
.
|
||||||
@@ -39,28 +39,28 @@
|
|||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm send
|
.Cm send
|
||||||
.Op Fl DLPRbcehnpsvw
|
.Op Fl DLPVRbcehnpsvw
|
||||||
.Op Oo Fl I Ns | Ns Fl i Oc Ar snapshot
|
.Op Oo Fl I Ns | Ns Fl i Oc Ar snapshot
|
||||||
.Ar snapshot
|
.Ar snapshot
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm send
|
.Cm send
|
||||||
.Op Fl DLPcensvw
|
.Op Fl DLPVcensvw
|
||||||
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
|
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
|
||||||
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm send
|
.Cm send
|
||||||
.Fl -redact Ar redaction_bookmark
|
.Fl -redact Ar redaction_bookmark
|
||||||
.Op Fl DLPcenpv
|
.Op Fl DLPVcenpv
|
||||||
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
|
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
|
||||||
.Ar snapshot
|
.Ar snapshot
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm send
|
.Cm send
|
||||||
.Op Fl Penv
|
.Op Fl PVenv
|
||||||
.Fl t
|
.Fl t
|
||||||
.Ar receive_resume_token
|
.Ar receive_resume_token
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm send
|
.Cm send
|
||||||
.Op Fl Pnv
|
.Op Fl PVnv
|
||||||
.Fl S Ar filesystem
|
.Fl S Ar filesystem
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm redact
|
.Cm redact
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
.It Xo
|
.It Xo
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm send
|
.Cm send
|
||||||
.Op Fl DLPRbcehnpvw
|
.Op Fl DLPVRbcehnpvw
|
||||||
.Op Oo Fl I Ns | Ns Fl i Oc Ar snapshot
|
.Op Oo Fl I Ns | Ns Fl i Oc Ar snapshot
|
||||||
.Ar snapshot
|
.Ar snapshot
|
||||||
.Xc
|
.Xc
|
||||||
@@ -140,6 +140,8 @@ If the
|
|||||||
flag is used to send encrypted datasets, then
|
flag is used to send encrypted datasets, then
|
||||||
.Fl w
|
.Fl w
|
||||||
must also be specified.
|
must also be specified.
|
||||||
|
.It Fl V , -proctitle
|
||||||
|
Set the process title to a per-second report of how much data has been sent.
|
||||||
.It Fl e , -embed
|
.It Fl e , -embed
|
||||||
Generate a more compact stream by using
|
Generate a more compact stream by using
|
||||||
.Sy WRITE_EMBEDDED
|
.Sy WRITE_EMBEDDED
|
||||||
@@ -285,7 +287,7 @@ You will be able to receive your streams on future versions of ZFS.
|
|||||||
.It Xo
|
.It Xo
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm send
|
.Cm send
|
||||||
.Op Fl DLPcenvw
|
.Op Fl DLPVcenvw
|
||||||
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
|
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
|
||||||
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
||||||
.Xc
|
.Xc
|
||||||
@@ -417,7 +419,7 @@ This information includes a per-second report of how much data has been sent.
|
|||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm send
|
.Cm send
|
||||||
.Fl -redact Ar redaction_bookmark
|
.Fl -redact Ar redaction_bookmark
|
||||||
.Op Fl DLPcenpv
|
.Op Fl DLPVcenpv
|
||||||
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
|
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
|
||||||
.Ar snapshot
|
.Ar snapshot
|
||||||
.Xc
|
.Xc
|
||||||
@@ -511,7 +513,7 @@ raw sends and redacted sends cannot be combined at this time.
|
|||||||
.It Xo
|
.It Xo
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm send
|
.Cm send
|
||||||
.Op Fl Penv
|
.Op Fl PVenv
|
||||||
.Fl t
|
.Fl t
|
||||||
.Ar receive_resume_token
|
.Ar receive_resume_token
|
||||||
.Xc
|
.Xc
|
||||||
@@ -526,7 +528,7 @@ for more details.
|
|||||||
.It Xo
|
.It Xo
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm send
|
.Cm send
|
||||||
.Op Fl Pnv
|
.Op Fl PVnv
|
||||||
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
|
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
|
||||||
.Fl S
|
.Fl S
|
||||||
.Ar filesystem
|
.Ar filesystem
|
||||||
|
|||||||
@@ -704,6 +704,14 @@ command will be undone if the share is ever unshared (like via a reboot).
|
|||||||
.El
|
.El
|
||||||
.
|
.
|
||||||
.Sh ENVIRONMENT VARIABLES
|
.Sh ENVIRONMENT VARIABLES
|
||||||
|
.Bl -tag -width "ZFS_COLOR"
|
||||||
|
.It Sy ZFS_COLOR
|
||||||
|
Use ANSI color in
|
||||||
|
.Nm zfs Cm diff
|
||||||
|
and
|
||||||
|
.Nm zfs Cm list
|
||||||
|
output.
|
||||||
|
.El
|
||||||
.Bl -tag -width "ZFS_MOUNT_HELPER"
|
.Bl -tag -width "ZFS_MOUNT_HELPER"
|
||||||
.It Sy ZFS_MOUNT_HELPER
|
.It Sy ZFS_MOUNT_HELPER
|
||||||
Cause
|
Cause
|
||||||
@@ -713,6 +721,14 @@ to use
|
|||||||
to mount ZFS datasets.
|
to mount ZFS datasets.
|
||||||
This option is provided for backwards compatibility with older ZFS versions.
|
This option is provided for backwards compatibility with older ZFS versions.
|
||||||
.El
|
.El
|
||||||
|
.Bl -tag -width "ZFS_SET_PIPE_MAX"
|
||||||
|
.It Sy ZFS_SET_PIPE_MAX
|
||||||
|
Tells
|
||||||
|
.Nm zfs
|
||||||
|
to set the maximum pipe size for sends/recieves.
|
||||||
|
Disabled by default on Linux
|
||||||
|
due to an unfixed deadlock in Linux's pipe size handling code.
|
||||||
|
.El
|
||||||
.
|
.
|
||||||
.Sh INTERFACE STABILITY
|
.Sh INTERFACE STABILITY
|
||||||
.Sy Committed .
|
.Sy Committed .
|
||||||
|
|||||||
@@ -433,6 +433,8 @@ to dump core on exit for the purposes of running
|
|||||||
.It Sy ZFS_COLOR
|
.It Sy ZFS_COLOR
|
||||||
Use ANSI color in
|
Use ANSI color in
|
||||||
.Nm zpool status
|
.Nm zpool status
|
||||||
|
and
|
||||||
|
.Nm zpool iostat
|
||||||
output.
|
output.
|
||||||
.It Sy ZPOOL_IMPORT_PATH
|
.It Sy ZPOOL_IMPORT_PATH
|
||||||
The search path for devices or files to use with the pool.
|
The search path for devices or files to use with the pool.
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#include <sys/kstat.h>
|
#include <sys/kstat.h>
|
||||||
#include <sys/sbuf.h>
|
#include <sys/sbuf.h>
|
||||||
|
#include <sys/zone.h>
|
||||||
|
|
||||||
static MALLOC_DEFINE(M_KSTAT, "kstat_data", "Kernel statistics");
|
static MALLOC_DEFINE(M_KSTAT, "kstat_data", "Kernel statistics");
|
||||||
|
|
||||||
@@ -134,6 +135,55 @@ kstat_sysctl_string(SYSCTL_HANDLER_ARGS)
|
|||||||
return (sysctl_handle_string(oidp, val, len, req));
|
return (sysctl_handle_string(oidp, val, len, req));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
kstat_sysctl_dataset(SYSCTL_HANDLER_ARGS)
|
||||||
|
{
|
||||||
|
kstat_t *ksp = arg1;
|
||||||
|
kstat_named_t *ksent;
|
||||||
|
kstat_named_t *ksent_ds;
|
||||||
|
uint64_t val;
|
||||||
|
char *ds_name;
|
||||||
|
uint32_t ds_len = 0;
|
||||||
|
|
||||||
|
ksent_ds = ksent = ksp->ks_data;
|
||||||
|
ds_name = KSTAT_NAMED_STR_PTR(ksent_ds);
|
||||||
|
ds_len = KSTAT_NAMED_STR_BUFLEN(ksent_ds);
|
||||||
|
ds_name[ds_len-1] = '\0';
|
||||||
|
|
||||||
|
if (!zone_dataset_visible(ds_name, NULL)) {
|
||||||
|
return (EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select the correct element */
|
||||||
|
ksent += arg2;
|
||||||
|
/* Update the aggsums before reading */
|
||||||
|
(void) ksp->ks_update(ksp, KSTAT_READ);
|
||||||
|
val = ksent->value.ui64;
|
||||||
|
|
||||||
|
return (sysctl_handle_64(oidp, &val, 0, req));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
kstat_sysctl_dataset_string(SYSCTL_HANDLER_ARGS)
|
||||||
|
{
|
||||||
|
kstat_t *ksp = arg1;
|
||||||
|
kstat_named_t *ksent = ksp->ks_data;
|
||||||
|
char *val;
|
||||||
|
uint32_t len = 0;
|
||||||
|
|
||||||
|
/* Select the correct element */
|
||||||
|
ksent += arg2;
|
||||||
|
val = KSTAT_NAMED_STR_PTR(ksent);
|
||||||
|
len = KSTAT_NAMED_STR_BUFLEN(ksent);
|
||||||
|
val[len-1] = '\0';
|
||||||
|
|
||||||
|
if (!zone_dataset_visible(val, NULL)) {
|
||||||
|
return (EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (sysctl_handle_string(oidp, val, len, req));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
kstat_sysctl_io(SYSCTL_HANDLER_ARGS)
|
kstat_sysctl_io(SYSCTL_HANDLER_ARGS)
|
||||||
{
|
{
|
||||||
@@ -422,11 +472,20 @@ kstat_install_named(kstat_t *ksp)
|
|||||||
ksp, i, kstat_sysctl, "Q", namelast);
|
ksp, i, kstat_sysctl, "Q", namelast);
|
||||||
break;
|
break;
|
||||||
case KSTAT_DATA_UINT64:
|
case KSTAT_DATA_UINT64:
|
||||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
if (strcmp(ksp->ks_class, "dataset") == 0) {
|
||||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||||
OID_AUTO, namelast,
|
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||||
CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
OID_AUTO, namelast,
|
||||||
ksp, i, kstat_sysctl, "QU", namelast);
|
CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||||
|
ksp, i, kstat_sysctl_dataset, "QU",
|
||||||
|
namelast);
|
||||||
|
} else {
|
||||||
|
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||||
|
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||||
|
OID_AUTO, namelast,
|
||||||
|
CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||||
|
ksp, i, kstat_sysctl, "QU", namelast);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case KSTAT_DATA_LONG:
|
case KSTAT_DATA_LONG:
|
||||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||||
@@ -443,11 +502,21 @@ kstat_install_named(kstat_t *ksp)
|
|||||||
ksp, i, kstat_sysctl, "LU", namelast);
|
ksp, i, kstat_sysctl, "LU", namelast);
|
||||||
break;
|
break;
|
||||||
case KSTAT_DATA_STRING:
|
case KSTAT_DATA_STRING:
|
||||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
if (strcmp(ksp->ks_class, "dataset") == 0) {
|
||||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||||
OID_AUTO, namelast,
|
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||||
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
OID_AUTO, namelast, CTLTYPE_STRING |
|
||||||
ksp, i, kstat_sysctl_string, "A", namelast);
|
CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||||
|
ksp, i, kstat_sysctl_dataset_string, "A",
|
||||||
|
namelast);
|
||||||
|
} else {
|
||||||
|
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||||
|
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||||
|
OID_AUTO, namelast, CTLTYPE_STRING |
|
||||||
|
CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||||
|
ksp, i, kstat_sysctl_string, "A",
|
||||||
|
namelast);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("unsupported type: %d", typelast);
|
panic("unsupported type: %d", typelast);
|
||||||
|
|||||||
@@ -125,7 +125,6 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath,
|
|||||||
struct vfsconf *vfsp;
|
struct vfsconf *vfsp;
|
||||||
struct mount *mp;
|
struct mount *mp;
|
||||||
vnode_t *vp, *mvp;
|
vnode_t *vp, *mvp;
|
||||||
struct ucred *cr;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
ASSERT_VOP_ELOCKED(*vpp, "mount_snapshot");
|
ASSERT_VOP_ELOCKED(*vpp, "mount_snapshot");
|
||||||
@@ -194,15 +193,8 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath,
|
|||||||
* mount(8) and df(1) output.
|
* mount(8) and df(1) output.
|
||||||
*/
|
*/
|
||||||
mp->mnt_flag |= MNT_IGNORE;
|
mp->mnt_flag |= MNT_IGNORE;
|
||||||
/*
|
|
||||||
* XXX: This is evil, but we can't mount a snapshot as a regular user.
|
|
||||||
* XXX: Is is safe when snapshot is mounted from within a jail?
|
|
||||||
*/
|
|
||||||
cr = td->td_ucred;
|
|
||||||
td->td_ucred = kcred;
|
|
||||||
error = VFS_MOUNT(mp);
|
|
||||||
td->td_ucred = cr;
|
|
||||||
|
|
||||||
|
error = VFS_MOUNT(mp);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
/*
|
/*
|
||||||
* Clear VI_MOUNT and decrement the use count "atomically",
|
* Clear VI_MOUNT and decrement the use count "atomically",
|
||||||
|
|||||||
@@ -160,8 +160,6 @@ arc_prune_task(void *arg)
|
|||||||
{
|
{
|
||||||
int64_t nr_scan = (intptr_t)arg;
|
int64_t nr_scan = (intptr_t)arg;
|
||||||
|
|
||||||
arc_reduce_target_size(ptob(nr_scan));
|
|
||||||
|
|
||||||
#ifndef __ILP32__
|
#ifndef __ILP32__
|
||||||
if (nr_scan > INT_MAX)
|
if (nr_scan > INT_MAX)
|
||||||
nr_scan = INT_MAX;
|
nr_scan = INT_MAX;
|
||||||
|
|||||||
@@ -132,16 +132,13 @@ zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag,
|
|||||||
len = IOCPARM_LEN(zcmd);
|
len = IOCPARM_LEN(zcmd);
|
||||||
vecnum = zcmd & 0xff;
|
vecnum = zcmd & 0xff;
|
||||||
zp = (void *)arg;
|
zp = (void *)arg;
|
||||||
uaddr = (void *)zp->zfs_cmd;
|
|
||||||
error = 0;
|
error = 0;
|
||||||
zcl = NULL;
|
zcl = NULL;
|
||||||
|
|
||||||
if (len != sizeof (zfs_iocparm_t)) {
|
if (len != sizeof (zfs_iocparm_t))
|
||||||
printf("len %d vecnum: %d sizeof (zfs_cmd_t) %ju\n",
|
|
||||||
len, vecnum, (uintmax_t)sizeof (zfs_cmd_t));
|
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
|
||||||
|
|
||||||
|
uaddr = (void *)zp->zfs_cmd;
|
||||||
zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
|
zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
|
||||||
/*
|
/*
|
||||||
* Remap ioctl code for legacy user binaries
|
* Remap ioctl code for legacy user binaries
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ spa_generate_rootconf(const char *name)
|
|||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
uint64_t txg;
|
uint64_t txg;
|
||||||
|
|
||||||
|
if (configs[i] == NULL)
|
||||||
|
continue;
|
||||||
txg = fnvlist_lookup_uint64(configs[i], ZPOOL_CONFIG_POOL_TXG);
|
txg = fnvlist_lookup_uint64(configs[i], ZPOOL_CONFIG_POOL_TXG);
|
||||||
if (txg > best_txg) {
|
if (txg > best_txg) {
|
||||||
best_txg = txg;
|
best_txg = txg;
|
||||||
|
|||||||
@@ -356,14 +356,6 @@ SYSCTL_UINT(_vfs_zfs_zfetch, OID_AUTO, max_idistance, CTLFLAG_RWTUN,
|
|||||||
/* dsl_pool.c */
|
/* dsl_pool.c */
|
||||||
|
|
||||||
/* dnode.c */
|
/* dnode.c */
|
||||||
extern int zfs_default_bs;
|
|
||||||
SYSCTL_INT(_vfs_zfs, OID_AUTO, default_bs, CTLFLAG_RWTUN,
|
|
||||||
&zfs_default_bs, 0, "Default dnode block shift");
|
|
||||||
|
|
||||||
extern int zfs_default_ibs;
|
|
||||||
SYSCTL_INT(_vfs_zfs, OID_AUTO, default_ibs, CTLFLAG_RWTUN,
|
|
||||||
&zfs_default_ibs, 0, "Default dnode indirect block shift");
|
|
||||||
|
|
||||||
|
|
||||||
/* dsl_scan.c */
|
/* dsl_scan.c */
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
#include <sys/dsl_dir.h>
|
#include <sys/dsl_dir.h>
|
||||||
#include <sys/spa_boot.h>
|
#include <sys/spa_boot.h>
|
||||||
#include <sys/jail.h>
|
#include <sys/jail.h>
|
||||||
|
#include <sys/osd.h>
|
||||||
#include <ufs/ufs/quota.h>
|
#include <ufs/ufs/quota.h>
|
||||||
#include <sys/zfs_quota.h>
|
#include <sys/zfs_quota.h>
|
||||||
|
|
||||||
@@ -90,6 +91,20 @@ int zfs_debug_level;
|
|||||||
SYSCTL_INT(_vfs_zfs, OID_AUTO, debug, CTLFLAG_RWTUN, &zfs_debug_level, 0,
|
SYSCTL_INT(_vfs_zfs, OID_AUTO, debug, CTLFLAG_RWTUN, &zfs_debug_level, 0,
|
||||||
"Debug level");
|
"Debug level");
|
||||||
|
|
||||||
|
struct zfs_jailparam {
|
||||||
|
int mount_snapshot;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct zfs_jailparam zfs_jailparam0 = {
|
||||||
|
.mount_snapshot = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int zfs_jailparam_slot;
|
||||||
|
|
||||||
|
SYSCTL_JAIL_PARAM_SYS_NODE(zfs, CTLFLAG_RW, "Jail ZFS parameters");
|
||||||
|
SYSCTL_JAIL_PARAM(_zfs, mount_snapshot, CTLTYPE_INT | CTLFLAG_RW, "I",
|
||||||
|
"Allow mounting snapshots in the .zfs directory for unjailed datasets");
|
||||||
|
|
||||||
SYSCTL_NODE(_vfs_zfs, OID_AUTO, version, CTLFLAG_RD, 0, "ZFS versions");
|
SYSCTL_NODE(_vfs_zfs, OID_AUTO, version, CTLFLAG_RD, 0, "ZFS versions");
|
||||||
static int zfs_version_acl = ZFS_ACL_VERSION;
|
static int zfs_version_acl = ZFS_ACL_VERSION;
|
||||||
SYSCTL_INT(_vfs_zfs_version, OID_AUTO, acl, CTLFLAG_RD, &zfs_version_acl, 0,
|
SYSCTL_INT(_vfs_zfs_version, OID_AUTO, acl, CTLFLAG_RD, &zfs_version_acl, 0,
|
||||||
@@ -720,7 +735,7 @@ zfs_register_callbacks(vfs_t *vfsp)
|
|||||||
nbmand = B_FALSE;
|
nbmand = B_FALSE;
|
||||||
} else if (vfs_optionisset(vfsp, MNTOPT_NBMAND, NULL)) {
|
} else if (vfs_optionisset(vfsp, MNTOPT_NBMAND, NULL)) {
|
||||||
nbmand = B_TRUE;
|
nbmand = B_TRUE;
|
||||||
} else if ((error = dsl_prop_get_int_ds(ds, "nbmand", &nbmand) != 0)) {
|
} else if ((error = dsl_prop_get_int_ds(ds, "nbmand", &nbmand)) != 0) {
|
||||||
dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
|
dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
@@ -1332,7 +1347,7 @@ zfs_mount(vfs_t *vfsp)
|
|||||||
char *osname;
|
char *osname;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int canwrite;
|
int canwrite;
|
||||||
bool checkpointrewind;
|
bool checkpointrewind, isctlsnap = false;
|
||||||
|
|
||||||
if (vfs_getopt(vfsp->mnt_optnew, "from", (void **)&osname, NULL))
|
if (vfs_getopt(vfsp->mnt_optnew, "from", (void **)&osname, NULL))
|
||||||
return (SET_ERROR(EINVAL));
|
return (SET_ERROR(EINVAL));
|
||||||
@@ -1347,6 +1362,8 @@ zfs_mount(vfs_t *vfsp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fetch_osname_options(osname, &checkpointrewind);
|
fetch_osname_options(osname, &checkpointrewind);
|
||||||
|
isctlsnap = (mvp != NULL && zfsctl_is_node(mvp) &&
|
||||||
|
strchr(osname, '@') != NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for mount privilege?
|
* Check for mount privilege?
|
||||||
@@ -1355,7 +1372,9 @@ zfs_mount(vfs_t *vfsp)
|
|||||||
* we have local permission to allow it
|
* we have local permission to allow it
|
||||||
*/
|
*/
|
||||||
error = secpolicy_fs_mount(cr, mvp, vfsp);
|
error = secpolicy_fs_mount(cr, mvp, vfsp);
|
||||||
if (error) {
|
if (error && isctlsnap) {
|
||||||
|
secpolicy_fs_mount_clearopts(cr, vfsp);
|
||||||
|
} else if (error) {
|
||||||
if (dsl_deleg_access(osname, ZFS_DELEG_PERM_MOUNT, cr) != 0)
|
if (dsl_deleg_access(osname, ZFS_DELEG_PERM_MOUNT, cr) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -1392,8 +1411,27 @@ zfs_mount(vfs_t *vfsp)
|
|||||||
*/
|
*/
|
||||||
if (!INGLOBALZONE(curproc) &&
|
if (!INGLOBALZONE(curproc) &&
|
||||||
(!zone_dataset_visible(osname, &canwrite) || !canwrite)) {
|
(!zone_dataset_visible(osname, &canwrite) || !canwrite)) {
|
||||||
error = SET_ERROR(EPERM);
|
boolean_t mount_snapshot = B_FALSE;
|
||||||
goto out;
|
|
||||||
|
/*
|
||||||
|
* Snapshots may be mounted in .zfs for unjailed datasets
|
||||||
|
* if allowed by the jail param zfs.mount_snapshot.
|
||||||
|
*/
|
||||||
|
if (isctlsnap) {
|
||||||
|
struct prison *pr;
|
||||||
|
struct zfs_jailparam *zjp;
|
||||||
|
|
||||||
|
pr = curthread->td_ucred->cr_prison;
|
||||||
|
mtx_lock(&pr->pr_mtx);
|
||||||
|
zjp = osd_jail_get(pr, zfs_jailparam_slot);
|
||||||
|
mtx_unlock(&pr->pr_mtx);
|
||||||
|
if (zjp && zjp->mount_snapshot)
|
||||||
|
mount_snapshot = B_TRUE;
|
||||||
|
}
|
||||||
|
if (!mount_snapshot) {
|
||||||
|
error = SET_ERROR(EPERM);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vfsp->vfs_flag |= MNT_NFS4ACLS;
|
vfsp->vfs_flag |= MNT_NFS4ACLS;
|
||||||
@@ -2343,3 +2381,236 @@ zfsvfs_update_fromname(const char *oldname, const char *newname)
|
|||||||
mtx_unlock(&mountlist_mtx);
|
mtx_unlock(&mountlist_mtx);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find a prison with ZFS info.
|
||||||
|
* Return the ZFS info and the (locked) prison.
|
||||||
|
*/
|
||||||
|
static struct zfs_jailparam *
|
||||||
|
zfs_jailparam_find(struct prison *spr, struct prison **prp)
|
||||||
|
{
|
||||||
|
struct prison *pr;
|
||||||
|
struct zfs_jailparam *zjp;
|
||||||
|
|
||||||
|
for (pr = spr; ; pr = pr->pr_parent) {
|
||||||
|
mtx_lock(&pr->pr_mtx);
|
||||||
|
if (pr == &prison0) {
|
||||||
|
zjp = &zfs_jailparam0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
zjp = osd_jail_get(pr, zfs_jailparam_slot);
|
||||||
|
if (zjp != NULL)
|
||||||
|
break;
|
||||||
|
mtx_unlock(&pr->pr_mtx);
|
||||||
|
}
|
||||||
|
*prp = pr;
|
||||||
|
|
||||||
|
return (zjp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure a prison has its own ZFS info. If zjpp is non-null, point it to the
|
||||||
|
* ZFS info and lock the prison.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
zfs_jailparam_alloc(struct prison *pr, struct zfs_jailparam **zjpp)
|
||||||
|
{
|
||||||
|
struct prison *ppr;
|
||||||
|
struct zfs_jailparam *zjp, *nzjp;
|
||||||
|
void **rsv;
|
||||||
|
|
||||||
|
/* If this prison already has ZFS info, return that. */
|
||||||
|
zjp = zfs_jailparam_find(pr, &ppr);
|
||||||
|
if (ppr == pr)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate a new info record. Then check again, in case something
|
||||||
|
* changed during the allocation.
|
||||||
|
*/
|
||||||
|
mtx_unlock(&ppr->pr_mtx);
|
||||||
|
nzjp = malloc(sizeof (struct zfs_jailparam), M_PRISON, M_WAITOK);
|
||||||
|
rsv = osd_reserve(zfs_jailparam_slot);
|
||||||
|
zjp = zfs_jailparam_find(pr, &ppr);
|
||||||
|
if (ppr == pr) {
|
||||||
|
free(nzjp, M_PRISON);
|
||||||
|
osd_free_reserved(rsv);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Inherit the initial values from the ancestor. */
|
||||||
|
mtx_lock(&pr->pr_mtx);
|
||||||
|
(void) osd_jail_set_reserved(pr, zfs_jailparam_slot, rsv, nzjp);
|
||||||
|
(void) memcpy(nzjp, zjp, sizeof (*zjp));
|
||||||
|
zjp = nzjp;
|
||||||
|
mtx_unlock(&ppr->pr_mtx);
|
||||||
|
done:
|
||||||
|
if (zjpp != NULL)
|
||||||
|
*zjpp = zjp;
|
||||||
|
else
|
||||||
|
mtx_unlock(&pr->pr_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Jail OSD methods for ZFS VFS info.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
zfs_jailparam_create(void *obj, void *data)
|
||||||
|
{
|
||||||
|
struct prison *pr = obj;
|
||||||
|
struct vfsoptlist *opts = data;
|
||||||
|
int jsys;
|
||||||
|
|
||||||
|
if (vfs_copyopt(opts, "zfs", &jsys, sizeof (jsys)) == 0 &&
|
||||||
|
jsys == JAIL_SYS_INHERIT)
|
||||||
|
return (0);
|
||||||
|
/*
|
||||||
|
* Inherit a prison's initial values from its parent
|
||||||
|
* (different from JAIL_SYS_INHERIT which also inherits changes).
|
||||||
|
*/
|
||||||
|
zfs_jailparam_alloc(pr, NULL);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
zfs_jailparam_get(void *obj, void *data)
|
||||||
|
{
|
||||||
|
struct prison *ppr, *pr = obj;
|
||||||
|
struct vfsoptlist *opts = data;
|
||||||
|
struct zfs_jailparam *zjp;
|
||||||
|
int jsys, error;
|
||||||
|
|
||||||
|
zjp = zfs_jailparam_find(pr, &ppr);
|
||||||
|
jsys = (ppr == pr) ? JAIL_SYS_NEW : JAIL_SYS_INHERIT;
|
||||||
|
error = vfs_setopt(opts, "zfs", &jsys, sizeof (jsys));
|
||||||
|
if (error != 0 && error != ENOENT)
|
||||||
|
goto done;
|
||||||
|
if (jsys == JAIL_SYS_NEW) {
|
||||||
|
error = vfs_setopt(opts, "zfs.mount_snapshot",
|
||||||
|
&zjp->mount_snapshot, sizeof (zjp->mount_snapshot));
|
||||||
|
if (error != 0 && error != ENOENT)
|
||||||
|
goto done;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* If this prison is inheriting its ZFS info, report
|
||||||
|
* empty/zero parameters.
|
||||||
|
*/
|
||||||
|
static int mount_snapshot = 0;
|
||||||
|
|
||||||
|
error = vfs_setopt(opts, "zfs.mount_snapshot",
|
||||||
|
&mount_snapshot, sizeof (mount_snapshot));
|
||||||
|
if (error != 0 && error != ENOENT)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
error = 0;
|
||||||
|
done:
|
||||||
|
mtx_unlock(&ppr->pr_mtx);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
zfs_jailparam_set(void *obj, void *data)
|
||||||
|
{
|
||||||
|
struct prison *pr = obj;
|
||||||
|
struct prison *ppr;
|
||||||
|
struct vfsoptlist *opts = data;
|
||||||
|
int error, jsys, mount_snapshot;
|
||||||
|
|
||||||
|
/* Set the parameters, which should be correct. */
|
||||||
|
error = vfs_copyopt(opts, "zfs", &jsys, sizeof (jsys));
|
||||||
|
if (error == ENOENT)
|
||||||
|
jsys = -1;
|
||||||
|
error = vfs_copyopt(opts, "zfs.mount_snapshot", &mount_snapshot,
|
||||||
|
sizeof (mount_snapshot));
|
||||||
|
if (error == ENOENT)
|
||||||
|
mount_snapshot = -1;
|
||||||
|
else
|
||||||
|
jsys = JAIL_SYS_NEW;
|
||||||
|
if (jsys == JAIL_SYS_NEW) {
|
||||||
|
/* "zfs=new" or "zfs.*": the prison gets its own ZFS info. */
|
||||||
|
struct zfs_jailparam *zjp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A child jail cannot have more permissions than its parent
|
||||||
|
*/
|
||||||
|
if (pr->pr_parent != &prison0) {
|
||||||
|
zjp = zfs_jailparam_find(pr->pr_parent, &ppr);
|
||||||
|
mtx_unlock(&ppr->pr_mtx);
|
||||||
|
if (zjp->mount_snapshot < mount_snapshot) {
|
||||||
|
return (EPERM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zfs_jailparam_alloc(pr, &zjp);
|
||||||
|
if (mount_snapshot != -1)
|
||||||
|
zjp->mount_snapshot = mount_snapshot;
|
||||||
|
mtx_unlock(&pr->pr_mtx);
|
||||||
|
} else {
|
||||||
|
/* "zfs=inherit": inherit the parent's ZFS info. */
|
||||||
|
mtx_lock(&pr->pr_mtx);
|
||||||
|
osd_jail_del(pr, zfs_jailparam_slot);
|
||||||
|
mtx_unlock(&pr->pr_mtx);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
zfs_jailparam_check(void *obj __unused, void *data)
|
||||||
|
{
|
||||||
|
struct vfsoptlist *opts = data;
|
||||||
|
int error, jsys, mount_snapshot;
|
||||||
|
|
||||||
|
/* Check that the parameters are correct. */
|
||||||
|
error = vfs_copyopt(opts, "zfs", &jsys, sizeof (jsys));
|
||||||
|
if (error != ENOENT) {
|
||||||
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
|
if (jsys != JAIL_SYS_NEW && jsys != JAIL_SYS_INHERIT)
|
||||||
|
return (EINVAL);
|
||||||
|
}
|
||||||
|
error = vfs_copyopt(opts, "zfs.mount_snapshot", &mount_snapshot,
|
||||||
|
sizeof (mount_snapshot));
|
||||||
|
if (error != ENOENT) {
|
||||||
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
|
if (mount_snapshot != 0 && mount_snapshot != 1)
|
||||||
|
return (EINVAL);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
zfs_jailparam_destroy(void *data)
|
||||||
|
{
|
||||||
|
|
||||||
|
free(data, M_PRISON);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
zfs_jailparam_sysinit(void *arg __unused)
|
||||||
|
{
|
||||||
|
struct prison *pr;
|
||||||
|
osd_method_t methods[PR_MAXMETHOD] = {
|
||||||
|
[PR_METHOD_CREATE] = zfs_jailparam_create,
|
||||||
|
[PR_METHOD_GET] = zfs_jailparam_get,
|
||||||
|
[PR_METHOD_SET] = zfs_jailparam_set,
|
||||||
|
[PR_METHOD_CHECK] = zfs_jailparam_check,
|
||||||
|
};
|
||||||
|
|
||||||
|
zfs_jailparam_slot = osd_jail_register(zfs_jailparam_destroy, methods);
|
||||||
|
/* Copy the defaults to any existing prisons. */
|
||||||
|
sx_slock(&allprison_lock);
|
||||||
|
TAILQ_FOREACH(pr, &allprison, pr_list)
|
||||||
|
zfs_jailparam_alloc(pr, NULL);
|
||||||
|
sx_sunlock(&allprison_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
zfs_jailparam_sysuninit(void *arg __unused)
|
||||||
|
{
|
||||||
|
|
||||||
|
osd_jail_deregister(zfs_jailparam_slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
SYSINIT(zfs_jailparam_sysinit, SI_SUB_DRIVERS, SI_ORDER_ANY,
|
||||||
|
zfs_jailparam_sysinit, NULL);
|
||||||
|
SYSUNINIT(zfs_jailparam_sysuninit, SI_SUB_DRIVERS, SI_ORDER_ANY,
|
||||||
|
zfs_jailparam_sysuninit, NULL);
|
||||||
|
|||||||
@@ -536,6 +536,9 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
|
|||||||
* Acquire vnode lock before making it available to the world.
|
* Acquire vnode lock before making it available to the world.
|
||||||
*/
|
*/
|
||||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||||
|
#if __FreeBSD_version >= 1400077
|
||||||
|
vn_set_state(vp, VSTATE_CONSTRUCTED);
|
||||||
|
#endif
|
||||||
VN_LOCK_AREC(vp);
|
VN_LOCK_AREC(vp);
|
||||||
if (vp->v_type != VFIFO)
|
if (vp->v_type != VFIFO)
|
||||||
VN_LOCK_ASHARE(vp);
|
VN_LOCK_ASHARE(vp);
|
||||||
|
|||||||
@@ -1161,7 +1161,10 @@ zvol_cdev_ioctl(struct cdev *dev, ulong_t cmd, caddr_t data,
|
|||||||
|
|
||||||
hole = (cmd == FIOSEEKHOLE);
|
hole = (cmd == FIOSEEKHOLE);
|
||||||
noff = *off;
|
noff = *off;
|
||||||
|
lr = zfs_rangelock_enter(&zv->zv_rangelock, 0, UINT64_MAX,
|
||||||
|
RL_READER);
|
||||||
error = dmu_offset_next(zv->zv_objset, ZVOL_OBJ, hole, &noff);
|
error = dmu_offset_next(zv->zv_objset, ZVOL_OBJ, hole, &noff);
|
||||||
|
zfs_rangelock_exit(lr);
|
||||||
*off = noff;
|
*off = noff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
#include <linux/mod_compat.h>
|
#include <linux/mod_compat.h>
|
||||||
#include <sys/cred.h>
|
#include <sys/cred.h>
|
||||||
#include <sys/vnode.h>
|
#include <sys/vnode.h>
|
||||||
|
#include <sys/misc.h>
|
||||||
|
|
||||||
char spl_gitrev[64] = ZFS_META_GITREV;
|
char spl_gitrev[64] = ZFS_META_GITREV;
|
||||||
|
|
||||||
@@ -540,6 +541,38 @@ ddi_copyin(const void *from, void *to, size_t len, int flags)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ddi_copyin);
|
EXPORT_SYMBOL(ddi_copyin);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Post a uevent to userspace whenever a new vdev adds to the pool. It is
|
||||||
|
* necessary to sync blkid information with udev, which zed daemon uses
|
||||||
|
* during device hotplug to identify the vdev.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
spl_signal_kobj_evt(struct block_device *bdev)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_BDEV_KOBJ) || defined(HAVE_PART_TO_DEV)
|
||||||
|
#ifdef HAVE_BDEV_KOBJ
|
||||||
|
struct kobject *disk_kobj = bdev_kobj(bdev);
|
||||||
|
#else
|
||||||
|
struct kobject *disk_kobj = &part_to_dev(bdev->bd_part)->kobj;
|
||||||
|
#endif
|
||||||
|
if (disk_kobj) {
|
||||||
|
int ret = kobject_uevent(disk_kobj, KOBJ_CHANGE);
|
||||||
|
if (ret) {
|
||||||
|
pr_warn("ZFS: Sending event '%d' to kobject: '%s'"
|
||||||
|
" (%p): failed(ret:%d)\n", KOBJ_CHANGE,
|
||||||
|
kobject_name(disk_kobj), disk_kobj, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* This is encountered if neither bdev_kobj() nor part_to_dev() is available
|
||||||
|
* in the kernel - likely due to an API change that needs to be chased down.
|
||||||
|
*/
|
||||||
|
#error "Unsupported kernel: unable to get struct kobj from bdev"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(spl_signal_kobj_evt);
|
||||||
|
|
||||||
int
|
int
|
||||||
ddi_copyout(const void *from, void *to, size_t len, int flags)
|
ddi_copyout(const void *from, void *to, size_t len, int flags)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ qat_compress_impl(qat_compress_dir_t dir, char *src, int src_len,
|
|||||||
Cpa8U *buffer_meta_src = NULL;
|
Cpa8U *buffer_meta_src = NULL;
|
||||||
Cpa8U *buffer_meta_dst = NULL;
|
Cpa8U *buffer_meta_dst = NULL;
|
||||||
Cpa32U buffer_meta_size = 0;
|
Cpa32U buffer_meta_size = 0;
|
||||||
CpaDcRqResults dc_results;
|
CpaDcRqResults dc_results = {.checksum = 1};
|
||||||
CpaStatus status = CPA_STATUS_FAIL;
|
CpaStatus status = CPA_STATUS_FAIL;
|
||||||
Cpa32U hdr_sz = 0;
|
Cpa32U hdr_sz = 0;
|
||||||
Cpa32U compressed_sz;
|
Cpa32U compressed_sz;
|
||||||
|
|||||||
@@ -179,6 +179,18 @@ vdev_disk_error(zio_t *zio)
|
|||||||
zio->io_flags);
|
zio->io_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vdev_disk_kobj_evt_post(vdev_t *v)
|
||||||
|
{
|
||||||
|
vdev_disk_t *vd = v->vdev_tsd;
|
||||||
|
if (vd && vd->vd_bdev) {
|
||||||
|
spl_signal_kobj_evt(vd->vd_bdev);
|
||||||
|
} else {
|
||||||
|
vdev_dbgmsg(v, "vdev_disk_t is NULL for VDEV:%s\n",
|
||||||
|
v->vdev_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
|
vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
|
||||||
uint64_t *logical_ashift, uint64_t *physical_ashift)
|
uint64_t *logical_ashift, uint64_t *physical_ashift)
|
||||||
@@ -290,6 +302,13 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
|
|||||||
bdev = blkdev_get_by_path(v->vdev_path, mode | FMODE_EXCL,
|
bdev = blkdev_get_by_path(v->vdev_path, mode | FMODE_EXCL,
|
||||||
zfs_vdev_holder);
|
zfs_vdev_holder);
|
||||||
if (unlikely(PTR_ERR(bdev) == -ENOENT)) {
|
if (unlikely(PTR_ERR(bdev) == -ENOENT)) {
|
||||||
|
/*
|
||||||
|
* There is no point of waiting since device is removed
|
||||||
|
* explicitly
|
||||||
|
*/
|
||||||
|
if (v->vdev_removed)
|
||||||
|
break;
|
||||||
|
|
||||||
schedule_timeout(MSEC_TO_TICK(10));
|
schedule_timeout(MSEC_TO_TICK(10));
|
||||||
} else if (unlikely(PTR_ERR(bdev) == -ERESTARTSYS)) {
|
} else if (unlikely(PTR_ERR(bdev) == -ERESTARTSYS)) {
|
||||||
timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms * 10);
|
timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms * 10);
|
||||||
@@ -899,7 +918,7 @@ vdev_disk_io_done(zio_t *zio)
|
|||||||
vdev_t *v = zio->io_vd;
|
vdev_t *v = zio->io_vd;
|
||||||
vdev_disk_t *vd = v->vdev_tsd;
|
vdev_disk_t *vd = v->vdev_tsd;
|
||||||
|
|
||||||
if (zfs_check_media_change(vd->vd_bdev)) {
|
if (!zfs_check_disk_status(vd->vd_bdev)) {
|
||||||
invalidate_bdev(vd->vd_bdev);
|
invalidate_bdev(vd->vd_bdev);
|
||||||
v->vdev_remove_wanted = B_TRUE;
|
v->vdev_remove_wanted = B_TRUE;
|
||||||
spa_async_request(zio->io_spa, SPA_ASYNC_REMOVE);
|
spa_async_request(zio->io_spa, SPA_ASYNC_REMOVE);
|
||||||
@@ -955,7 +974,8 @@ vdev_ops_t vdev_disk_ops = {
|
|||||||
.vdev_op_nparity = NULL,
|
.vdev_op_nparity = NULL,
|
||||||
.vdev_op_ndisks = NULL,
|
.vdev_op_ndisks = NULL,
|
||||||
.vdev_op_type = VDEV_TYPE_DISK, /* name of this vdev type */
|
.vdev_op_type = VDEV_TYPE_DISK, /* name of this vdev type */
|
||||||
.vdev_op_leaf = B_TRUE /* leaf vdev */
|
.vdev_op_leaf = B_TRUE, /* leaf vdev */
|
||||||
|
.vdev_op_kobj_evt_post = vdev_disk_kobj_evt_post
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1066,9 +1066,6 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xzpp, cred_t *cr)
|
|||||||
|
|
||||||
*xzpp = NULL;
|
*xzpp = NULL;
|
||||||
|
|
||||||
if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr)))
|
|
||||||
return (error);
|
|
||||||
|
|
||||||
if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL,
|
if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL,
|
||||||
&acl_ids)) != 0)
|
&acl_ids)) != 0)
|
||||||
return (error);
|
return (error);
|
||||||
|
|||||||
@@ -579,6 +579,7 @@ zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
|
|||||||
boolean_t fuid_dirtied;
|
boolean_t fuid_dirtied;
|
||||||
boolean_t have_acl = B_FALSE;
|
boolean_t have_acl = B_FALSE;
|
||||||
boolean_t waited = B_FALSE;
|
boolean_t waited = B_FALSE;
|
||||||
|
boolean_t skip_acl = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have an ephemeral id, ACL, or XVATTR then
|
* If we have an ephemeral id, ACL, or XVATTR then
|
||||||
@@ -651,7 +652,7 @@ top:
|
|||||||
* Create a new file object and update the directory
|
* Create a new file object and update the directory
|
||||||
* to reference it.
|
* to reference it.
|
||||||
*/
|
*/
|
||||||
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
|
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, skip_acl, cr))) {
|
||||||
if (have_acl)
|
if (have_acl)
|
||||||
zfs_acl_ids_free(&acl_ids);
|
zfs_acl_ids_free(&acl_ids);
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
@@ -162,8 +162,7 @@ zfs_znode_hold_cache_constructor(void *buf, void *arg, int kmflags)
|
|||||||
znode_hold_t *zh = buf;
|
znode_hold_t *zh = buf;
|
||||||
|
|
||||||
mutex_init(&zh->zh_lock, NULL, MUTEX_DEFAULT, NULL);
|
mutex_init(&zh->zh_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||||
zfs_refcount_create(&zh->zh_refcount);
|
zh->zh_refcount = 0;
|
||||||
zh->zh_obj = ZFS_NO_OBJECT;
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@@ -174,7 +173,6 @@ zfs_znode_hold_cache_destructor(void *buf, void *arg)
|
|||||||
znode_hold_t *zh = buf;
|
znode_hold_t *zh = buf;
|
||||||
|
|
||||||
mutex_destroy(&zh->zh_lock);
|
mutex_destroy(&zh->zh_lock);
|
||||||
zfs_refcount_destroy(&zh->zh_refcount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -273,26 +271,26 @@ zfs_znode_hold_enter(zfsvfs_t *zfsvfs, uint64_t obj)
|
|||||||
boolean_t found = B_FALSE;
|
boolean_t found = B_FALSE;
|
||||||
|
|
||||||
zh_new = kmem_cache_alloc(znode_hold_cache, KM_SLEEP);
|
zh_new = kmem_cache_alloc(znode_hold_cache, KM_SLEEP);
|
||||||
zh_new->zh_obj = obj;
|
|
||||||
search.zh_obj = obj;
|
search.zh_obj = obj;
|
||||||
|
|
||||||
mutex_enter(&zfsvfs->z_hold_locks[i]);
|
mutex_enter(&zfsvfs->z_hold_locks[i]);
|
||||||
zh = avl_find(&zfsvfs->z_hold_trees[i], &search, NULL);
|
zh = avl_find(&zfsvfs->z_hold_trees[i], &search, NULL);
|
||||||
if (likely(zh == NULL)) {
|
if (likely(zh == NULL)) {
|
||||||
zh = zh_new;
|
zh = zh_new;
|
||||||
|
zh->zh_obj = obj;
|
||||||
avl_add(&zfsvfs->z_hold_trees[i], zh);
|
avl_add(&zfsvfs->z_hold_trees[i], zh);
|
||||||
} else {
|
} else {
|
||||||
ASSERT3U(zh->zh_obj, ==, obj);
|
ASSERT3U(zh->zh_obj, ==, obj);
|
||||||
found = B_TRUE;
|
found = B_TRUE;
|
||||||
}
|
}
|
||||||
zfs_refcount_add(&zh->zh_refcount, NULL);
|
zh->zh_refcount++;
|
||||||
|
ASSERT3S(zh->zh_refcount, >, 0);
|
||||||
mutex_exit(&zfsvfs->z_hold_locks[i]);
|
mutex_exit(&zfsvfs->z_hold_locks[i]);
|
||||||
|
|
||||||
if (found == B_TRUE)
|
if (found == B_TRUE)
|
||||||
kmem_cache_free(znode_hold_cache, zh_new);
|
kmem_cache_free(znode_hold_cache, zh_new);
|
||||||
|
|
||||||
ASSERT(MUTEX_NOT_HELD(&zh->zh_lock));
|
ASSERT(MUTEX_NOT_HELD(&zh->zh_lock));
|
||||||
ASSERT3S(zfs_refcount_count(&zh->zh_refcount), >, 0);
|
|
||||||
mutex_enter(&zh->zh_lock);
|
mutex_enter(&zh->zh_lock);
|
||||||
|
|
||||||
return (zh);
|
return (zh);
|
||||||
@@ -305,11 +303,11 @@ zfs_znode_hold_exit(zfsvfs_t *zfsvfs, znode_hold_t *zh)
|
|||||||
boolean_t remove = B_FALSE;
|
boolean_t remove = B_FALSE;
|
||||||
|
|
||||||
ASSERT(zfs_znode_held(zfsvfs, zh->zh_obj));
|
ASSERT(zfs_znode_held(zfsvfs, zh->zh_obj));
|
||||||
ASSERT3S(zfs_refcount_count(&zh->zh_refcount), >, 0);
|
|
||||||
mutex_exit(&zh->zh_lock);
|
mutex_exit(&zh->zh_lock);
|
||||||
|
|
||||||
mutex_enter(&zfsvfs->z_hold_locks[i]);
|
mutex_enter(&zfsvfs->z_hold_locks[i]);
|
||||||
if (zfs_refcount_remove(&zh->zh_refcount, NULL) == 0) {
|
ASSERT3S(zh->zh_refcount, >, 0);
|
||||||
|
if (--zh->zh_refcount == 0) {
|
||||||
avl_remove(&zfsvfs->z_hold_trees[i], zh);
|
avl_remove(&zfsvfs->z_hold_trees[i], zh);
|
||||||
remove = B_TRUE;
|
remove = B_TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -224,12 +224,17 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
|
|||||||
|
|
||||||
#ifdef HAVE_TMPFILE
|
#ifdef HAVE_TMPFILE
|
||||||
static int
|
static int
|
||||||
|
#ifndef HAVE_TMPFILE_DENTRY
|
||||||
|
zpl_tmpfile(struct user_namespace *userns, struct inode *dir,
|
||||||
|
struct file *file, umode_t mode)
|
||||||
|
#else
|
||||||
#ifdef HAVE_TMPFILE_USERNS
|
#ifdef HAVE_TMPFILE_USERNS
|
||||||
zpl_tmpfile(struct user_namespace *userns, struct inode *dir,
|
zpl_tmpfile(struct user_namespace *userns, struct inode *dir,
|
||||||
struct dentry *dentry, umode_t mode)
|
struct dentry *dentry, umode_t mode)
|
||||||
#else
|
#else
|
||||||
zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
|
zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
@@ -252,11 +257,21 @@ zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
/* d_tmpfile will do drop_nlink, so we should set it first */
|
/* d_tmpfile will do drop_nlink, so we should set it first */
|
||||||
set_nlink(ip, 1);
|
set_nlink(ip, 1);
|
||||||
|
#ifndef HAVE_TMPFILE_DENTRY
|
||||||
|
d_tmpfile(file, ip);
|
||||||
|
|
||||||
|
error = zpl_xattr_security_init(ip, dir,
|
||||||
|
&file->f_path.dentry->d_name);
|
||||||
|
#else
|
||||||
d_tmpfile(dentry, ip);
|
d_tmpfile(dentry, ip);
|
||||||
|
|
||||||
error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
|
error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
|
||||||
|
#endif
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
error = zpl_init_acl(ip, dir);
|
error = zpl_init_acl(ip, dir);
|
||||||
|
#ifndef HAVE_TMPFILE_DENTRY
|
||||||
|
error = finish_open_simple(file, error);
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* don't need to handle error here, file is already in
|
* don't need to handle error here, file is already in
|
||||||
* unlinked set.
|
* unlinked set.
|
||||||
@@ -711,7 +726,11 @@ const struct inode_operations zpl_inode_operations = {
|
|||||||
#if defined(HAVE_SET_ACL)
|
#if defined(HAVE_SET_ACL)
|
||||||
.set_acl = zpl_set_acl,
|
.set_acl = zpl_set_acl,
|
||||||
#endif /* HAVE_SET_ACL */
|
#endif /* HAVE_SET_ACL */
|
||||||
|
#if defined(HAVE_GET_INODE_ACL)
|
||||||
|
.get_inode_acl = zpl_get_acl,
|
||||||
|
#else
|
||||||
.get_acl = zpl_get_acl,
|
.get_acl = zpl_get_acl,
|
||||||
|
#endif /* HAVE_GET_INODE_ACL */
|
||||||
#endif /* CONFIG_FS_POSIX_ACL */
|
#endif /* CONFIG_FS_POSIX_ACL */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -744,7 +763,11 @@ const struct inode_operations zpl_dir_inode_operations = {
|
|||||||
#if defined(HAVE_SET_ACL)
|
#if defined(HAVE_SET_ACL)
|
||||||
.set_acl = zpl_set_acl,
|
.set_acl = zpl_set_acl,
|
||||||
#endif /* HAVE_SET_ACL */
|
#endif /* HAVE_SET_ACL */
|
||||||
|
#if defined(HAVE_GET_INODE_ACL)
|
||||||
|
.get_inode_acl = zpl_get_acl,
|
||||||
|
#else
|
||||||
.get_acl = zpl_get_acl,
|
.get_acl = zpl_get_acl,
|
||||||
|
#endif /* HAVE_GET_INODE_ACL */
|
||||||
#endif /* CONFIG_FS_POSIX_ACL */
|
#endif /* CONFIG_FS_POSIX_ACL */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -783,6 +806,10 @@ const struct inode_operations zpl_special_inode_operations = {
|
|||||||
#if defined(HAVE_SET_ACL)
|
#if defined(HAVE_SET_ACL)
|
||||||
.set_acl = zpl_set_acl,
|
.set_acl = zpl_set_acl,
|
||||||
#endif /* HAVE_SET_ACL */
|
#endif /* HAVE_SET_ACL */
|
||||||
|
#if defined(HAVE_GET_INODE_ACL)
|
||||||
|
.get_inode_acl = zpl_get_acl,
|
||||||
|
#else
|
||||||
.get_acl = zpl_get_acl,
|
.get_acl = zpl_get_acl,
|
||||||
|
#endif /* HAVE_GET_INODE_ACL */
|
||||||
#endif /* CONFIG_FS_POSIX_ACL */
|
#endif /* CONFIG_FS_POSIX_ACL */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -496,7 +496,7 @@ zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
|
|||||||
vap->va_gid = crgetgid(cr);
|
vap->va_gid = crgetgid(cr);
|
||||||
|
|
||||||
error = -zfs_create(dxzp, (char *)name, vap, 0, 0644, &xzp,
|
error = -zfs_create(dxzp, (char *)name, vap, 0, 0644, &xzp,
|
||||||
cr, 0, NULL);
|
cr, ATTR_NOACLCHECK, NULL);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -1004,11 +1004,18 @@ int
|
|||||||
#ifdef HAVE_SET_ACL_USERNS
|
#ifdef HAVE_SET_ACL_USERNS
|
||||||
zpl_set_acl(struct user_namespace *userns, struct inode *ip,
|
zpl_set_acl(struct user_namespace *userns, struct inode *ip,
|
||||||
struct posix_acl *acl, int type)
|
struct posix_acl *acl, int type)
|
||||||
|
#elif defined(HAVE_SET_ACL_USERNS_DENTRY_ARG2)
|
||||||
|
zpl_set_acl(struct user_namespace *userns, struct dentry *dentry,
|
||||||
|
struct posix_acl *acl, int type)
|
||||||
#else
|
#else
|
||||||
zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type)
|
zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type)
|
||||||
#endif /* HAVE_SET_ACL_USERNS */
|
#endif /* HAVE_SET_ACL_USERNS */
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_SET_ACL_USERNS_DENTRY_ARG2
|
||||||
|
return (zpl_set_acl_impl(d_inode(dentry), acl, type));
|
||||||
|
#else
|
||||||
return (zpl_set_acl_impl(ip, acl, type));
|
return (zpl_set_acl_impl(ip, acl, type));
|
||||||
|
#endif /* HAVE_SET_ACL_USERNS_DENTRY_ARG2 */
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SET_ACL */
|
#endif /* HAVE_SET_ACL */
|
||||||
|
|
||||||
@@ -1067,7 +1074,7 @@ zpl_get_acl_impl(struct inode *ip, int type)
|
|||||||
return (acl);
|
return (acl);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_GET_ACL_RCU)
|
#if defined(HAVE_GET_ACL_RCU) || defined(HAVE_GET_INODE_ACL)
|
||||||
struct posix_acl *
|
struct posix_acl *
|
||||||
zpl_get_acl(struct inode *ip, int type, bool rcu)
|
zpl_get_acl(struct inode *ip, int type, bool rcu)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,9 @@
|
|||||||
* Use is subject to license terms.
|
* Use is subject to license terms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2022 MNX Cloud, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -213,10 +216,10 @@ const int8_t u8_number_of_bytes[0x100] = {
|
|||||||
/* 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F */
|
/* 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F */
|
||||||
I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
|
I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
|
||||||
|
|
||||||
/* 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F */
|
/* 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F */
|
||||||
I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
|
I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
|
||||||
|
|
||||||
/* A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF */
|
/* A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF */
|
||||||
I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
|
I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
|
||||||
|
|
||||||
/* B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF */
|
/* B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF */
|
||||||
@@ -1286,8 +1289,12 @@ TRY_THE_NEXT_MARK:
|
|||||||
saved_l = l - disp[last];
|
saved_l = l - disp[last];
|
||||||
|
|
||||||
while (p < oslast) {
|
while (p < oslast) {
|
||||||
size = u8_number_of_bytes[*p];
|
int8_t number_of_bytes = u8_number_of_bytes[*p];
|
||||||
if (size <= 1 || (p + size) > oslast)
|
|
||||||
|
if (number_of_bytes <= 1)
|
||||||
|
break;
|
||||||
|
size = number_of_bytes;
|
||||||
|
if ((p + size) > oslast)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
saved_p = p;
|
saved_p = p;
|
||||||
@@ -1378,8 +1385,10 @@ SAFE_RETURN:
|
|||||||
*/
|
*/
|
||||||
static size_t
|
static size_t
|
||||||
collect_a_seq(size_t uv, uchar_t *u8s, uchar_t **source, uchar_t *slast,
|
collect_a_seq(size_t uv, uchar_t *u8s, uchar_t **source, uchar_t *slast,
|
||||||
boolean_t is_it_toupper, boolean_t is_it_tolower,
|
boolean_t is_it_toupper,
|
||||||
boolean_t canonical_decomposition, boolean_t compatibility_decomposition,
|
boolean_t is_it_tolower,
|
||||||
|
boolean_t canonical_decomposition,
|
||||||
|
boolean_t compatibility_decomposition,
|
||||||
boolean_t canonical_composition,
|
boolean_t canonical_composition,
|
||||||
int *errnum, u8_normalization_states_t *state)
|
int *errnum, u8_normalization_states_t *state)
|
||||||
{
|
{
|
||||||
|
|||||||
+16
-8
@@ -5943,6 +5943,7 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
|
|||||||
(zio_flags & ZIO_FLAG_RAW_ENCRYPT) != 0;
|
(zio_flags & ZIO_FLAG_RAW_ENCRYPT) != 0;
|
||||||
boolean_t embedded_bp = !!BP_IS_EMBEDDED(bp);
|
boolean_t embedded_bp = !!BP_IS_EMBEDDED(bp);
|
||||||
boolean_t no_buf = *arc_flags & ARC_FLAG_NO_BUF;
|
boolean_t no_buf = *arc_flags & ARC_FLAG_NO_BUF;
|
||||||
|
arc_buf_t *buf = NULL;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
ASSERT(!embedded_bp ||
|
ASSERT(!embedded_bp ||
|
||||||
@@ -5972,7 +5973,7 @@ top:
|
|||||||
if (!zfs_blkptr_verify(spa, bp, zio_flags & ZIO_FLAG_CONFIG_WRITER,
|
if (!zfs_blkptr_verify(spa, bp, zio_flags & ZIO_FLAG_CONFIG_WRITER,
|
||||||
BLK_VERIFY_LOG)) {
|
BLK_VERIFY_LOG)) {
|
||||||
rc = SET_ERROR(ECKSUM);
|
rc = SET_ERROR(ECKSUM);
|
||||||
goto out;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!embedded_bp) {
|
if (!embedded_bp) {
|
||||||
@@ -5992,7 +5993,6 @@ top:
|
|||||||
*/
|
*/
|
||||||
if (hdr != NULL && HDR_HAS_L1HDR(hdr) && (HDR_HAS_RABD(hdr) ||
|
if (hdr != NULL && HDR_HAS_L1HDR(hdr) && (HDR_HAS_RABD(hdr) ||
|
||||||
(hdr->b_l1hdr.b_pabd != NULL && !encrypted_read))) {
|
(hdr->b_l1hdr.b_pabd != NULL && !encrypted_read))) {
|
||||||
arc_buf_t *buf = NULL;
|
|
||||||
*arc_flags |= ARC_FLAG_CACHED;
|
*arc_flags |= ARC_FLAG_CACHED;
|
||||||
|
|
||||||
if (HDR_IO_IN_PROGRESS(hdr)) {
|
if (HDR_IO_IN_PROGRESS(hdr)) {
|
||||||
@@ -6002,7 +6002,7 @@ top:
|
|||||||
mutex_exit(hash_lock);
|
mutex_exit(hash_lock);
|
||||||
ARCSTAT_BUMP(arcstat_cached_only_in_progress);
|
ARCSTAT_BUMP(arcstat_cached_only_in_progress);
|
||||||
rc = SET_ERROR(ENOENT);
|
rc = SET_ERROR(ENOENT);
|
||||||
goto out;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT3P(head_zio, !=, NULL);
|
ASSERT3P(head_zio, !=, NULL);
|
||||||
@@ -6130,9 +6130,7 @@ top:
|
|||||||
ARCSTAT_CONDSTAT(!HDR_PREFETCH(hdr),
|
ARCSTAT_CONDSTAT(!HDR_PREFETCH(hdr),
|
||||||
demand, prefetch, !HDR_ISTYPE_METADATA(hdr),
|
demand, prefetch, !HDR_ISTYPE_METADATA(hdr),
|
||||||
data, metadata, hits);
|
data, metadata, hits);
|
||||||
|
goto done;
|
||||||
if (done)
|
|
||||||
done(NULL, zb, bp, buf, private);
|
|
||||||
} else {
|
} else {
|
||||||
uint64_t lsize = BP_GET_LSIZE(bp);
|
uint64_t lsize = BP_GET_LSIZE(bp);
|
||||||
uint64_t psize = BP_GET_PSIZE(bp);
|
uint64_t psize = BP_GET_PSIZE(bp);
|
||||||
@@ -6145,10 +6143,10 @@ top:
|
|||||||
int alloc_flags = encrypted_read ? ARC_HDR_ALLOC_RDATA : 0;
|
int alloc_flags = encrypted_read ? ARC_HDR_ALLOC_RDATA : 0;
|
||||||
|
|
||||||
if (*arc_flags & ARC_FLAG_CACHED_ONLY) {
|
if (*arc_flags & ARC_FLAG_CACHED_ONLY) {
|
||||||
rc = SET_ERROR(ENOENT);
|
|
||||||
if (hash_lock != NULL)
|
if (hash_lock != NULL)
|
||||||
mutex_exit(hash_lock);
|
mutex_exit(hash_lock);
|
||||||
goto out;
|
rc = SET_ERROR(ENOENT);
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdr == NULL) {
|
if (hdr == NULL) {
|
||||||
@@ -6474,6 +6472,16 @@ out:
|
|||||||
spa_read_history_add(spa, zb, *arc_flags);
|
spa_read_history_add(spa, zb, *arc_flags);
|
||||||
spl_fstrans_unmark(cookie);
|
spl_fstrans_unmark(cookie);
|
||||||
return (rc);
|
return (rc);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (done)
|
||||||
|
done(NULL, zb, bp, buf, private);
|
||||||
|
if (pio && rc != 0) {
|
||||||
|
zio_t *zio = zio_null(pio, spa, NULL, NULL, NULL, zio_flags);
|
||||||
|
zio->io_error = rc;
|
||||||
|
zio_nowait(zio);
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
arc_prune_t *
|
arc_prune_t *
|
||||||
|
|||||||
+63
-2
@@ -663,14 +663,13 @@ bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
VERIFY3U(0, ==, bpobj_open(&subbpo, bpo->bpo_os, subobj));
|
VERIFY3U(0, ==, bpobj_open(&subbpo, bpo->bpo_os, subobj));
|
||||||
VERIFY3U(0, ==, bpobj_space(&subbpo, &used, &comp, &uncomp));
|
|
||||||
|
|
||||||
if (bpobj_is_empty(&subbpo)) {
|
if (bpobj_is_empty(&subbpo)) {
|
||||||
/* No point in having an empty subobj. */
|
/* No point in having an empty subobj. */
|
||||||
bpobj_close(&subbpo);
|
bpobj_close(&subbpo);
|
||||||
bpobj_free(bpo->bpo_os, subobj, tx);
|
bpobj_free(bpo->bpo_os, subobj, tx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
VERIFY3U(0, ==, bpobj_space(&subbpo, &used, &comp, &uncomp));
|
||||||
|
|
||||||
mutex_enter(&bpo->bpo_lock);
|
mutex_enter(&bpo->bpo_lock);
|
||||||
dmu_buf_will_dirty(bpo->bpo_dbuf, tx);
|
dmu_buf_will_dirty(bpo->bpo_dbuf, tx);
|
||||||
@@ -780,6 +779,68 @@ bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prefetch metadata required for bpobj_enqueue_subobj().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
bpobj_prefetch_subobj(bpobj_t *bpo, uint64_t subobj)
|
||||||
|
{
|
||||||
|
dmu_object_info_t doi;
|
||||||
|
bpobj_t subbpo;
|
||||||
|
uint64_t subsubobjs;
|
||||||
|
boolean_t copy_subsub = B_TRUE;
|
||||||
|
boolean_t copy_bps = B_TRUE;
|
||||||
|
|
||||||
|
ASSERT(bpobj_is_open(bpo));
|
||||||
|
ASSERT(subobj != 0);
|
||||||
|
|
||||||
|
if (subobj == dmu_objset_pool(bpo->bpo_os)->dp_empty_bpobj)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (bpobj_open(&subbpo, bpo->bpo_os, subobj) != 0)
|
||||||
|
return;
|
||||||
|
if (bpobj_is_empty(&subbpo)) {
|
||||||
|
bpobj_close(&subbpo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
subsubobjs = subbpo.bpo_phys->bpo_subobjs;
|
||||||
|
bpobj_close(&subbpo);
|
||||||
|
|
||||||
|
if (subsubobjs != 0) {
|
||||||
|
if (dmu_object_info(bpo->bpo_os, subsubobjs, &doi) != 0)
|
||||||
|
return;
|
||||||
|
if (doi.doi_max_offset > doi.doi_data_block_size)
|
||||||
|
copy_subsub = B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmu_object_info(bpo->bpo_os, subobj, &doi) != 0)
|
||||||
|
return;
|
||||||
|
if (doi.doi_max_offset > doi.doi_data_block_size || !copy_subsub)
|
||||||
|
copy_bps = B_FALSE;
|
||||||
|
|
||||||
|
if (copy_subsub && subsubobjs != 0) {
|
||||||
|
if (bpo->bpo_phys->bpo_subobjs) {
|
||||||
|
dmu_prefetch(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs, 0,
|
||||||
|
bpo->bpo_phys->bpo_num_subobjs * sizeof (subobj), 1,
|
||||||
|
ZIO_PRIORITY_ASYNC_READ);
|
||||||
|
}
|
||||||
|
dmu_prefetch(bpo->bpo_os, subsubobjs, 0, 0, 1,
|
||||||
|
ZIO_PRIORITY_ASYNC_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copy_bps) {
|
||||||
|
dmu_prefetch(bpo->bpo_os, bpo->bpo_object, 0,
|
||||||
|
bpo->bpo_phys->bpo_num_blkptrs * sizeof (blkptr_t), 1,
|
||||||
|
ZIO_PRIORITY_ASYNC_READ);
|
||||||
|
dmu_prefetch(bpo->bpo_os, subobj, 0, 0, 1,
|
||||||
|
ZIO_PRIORITY_ASYNC_READ);
|
||||||
|
} else if (bpo->bpo_phys->bpo_subobjs) {
|
||||||
|
dmu_prefetch(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs, 0,
|
||||||
|
bpo->bpo_phys->bpo_num_subobjs * sizeof (subobj), 1,
|
||||||
|
ZIO_PRIORITY_ASYNC_READ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bpobj_enqueue(bpobj_t *bpo, const blkptr_t *bp, boolean_t bp_freed,
|
bpobj_enqueue(bpobj_t *bpo, const blkptr_t *bp, boolean_t bp_freed,
|
||||||
dmu_tx_t *tx)
|
dmu_tx_t *tx)
|
||||||
|
|||||||
+40
-12
@@ -102,7 +102,7 @@ zfs_btree_poison_node(zfs_btree_t *tree, zfs_btree_hdr_t *hdr)
|
|||||||
(void) memset(leaf->btl_elems, 0x0f, hdr->bth_first * size);
|
(void) memset(leaf->btl_elems, 0x0f, hdr->bth_first * size);
|
||||||
(void) memset(leaf->btl_elems +
|
(void) memset(leaf->btl_elems +
|
||||||
(hdr->bth_first + hdr->bth_count) * size, 0x0f,
|
(hdr->bth_first + hdr->bth_count) * size, 0x0f,
|
||||||
BTREE_LEAF_ESIZE -
|
tree->bt_leaf_size - offsetof(zfs_btree_leaf_t, btl_elems) -
|
||||||
(hdr->bth_first + hdr->bth_count) * size);
|
(hdr->bth_first + hdr->bth_count) * size);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -173,16 +173,44 @@ zfs_btree_fini(void)
|
|||||||
kmem_cache_destroy(zfs_btree_leaf_cache);
|
kmem_cache_destroy(zfs_btree_leaf_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
zfs_btree_leaf_alloc(zfs_btree_t *tree)
|
||||||
|
{
|
||||||
|
if (tree->bt_leaf_size == BTREE_LEAF_SIZE)
|
||||||
|
return (kmem_cache_alloc(zfs_btree_leaf_cache, KM_SLEEP));
|
||||||
|
else
|
||||||
|
return (kmem_alloc(tree->bt_leaf_size, KM_SLEEP));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
zfs_btree_leaf_free(zfs_btree_t *tree, void *ptr)
|
||||||
|
{
|
||||||
|
if (tree->bt_leaf_size == BTREE_LEAF_SIZE)
|
||||||
|
return (kmem_cache_free(zfs_btree_leaf_cache, ptr));
|
||||||
|
else
|
||||||
|
return (kmem_free(ptr, tree->bt_leaf_size));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zfs_btree_create(zfs_btree_t *tree, int (*compar) (const void *, const void *),
|
zfs_btree_create(zfs_btree_t *tree, int (*compar) (const void *, const void *),
|
||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
ASSERT3U(size, <=, BTREE_LEAF_ESIZE / 2);
|
zfs_btree_create_custom(tree, compar, size, BTREE_LEAF_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
bzero(tree, sizeof (*tree));
|
void
|
||||||
|
zfs_btree_create_custom(zfs_btree_t *tree,
|
||||||
|
int (*compar) (const void *, const void *),
|
||||||
|
size_t size, size_t lsize)
|
||||||
|
{
|
||||||
|
size_t esize = lsize - offsetof(zfs_btree_leaf_t, btl_elems);
|
||||||
|
|
||||||
|
ASSERT3U(size, <=, esize / 2);
|
||||||
|
memset(tree, 0, sizeof (*tree));
|
||||||
tree->bt_compar = compar;
|
tree->bt_compar = compar;
|
||||||
tree->bt_elem_size = size;
|
tree->bt_elem_size = size;
|
||||||
tree->bt_leaf_cap = P2ALIGN(BTREE_LEAF_ESIZE / size, 2);
|
tree->bt_leaf_size = lsize;
|
||||||
|
tree->bt_leaf_cap = P2ALIGN(esize / size, 2);
|
||||||
tree->bt_height = -1;
|
tree->bt_height = -1;
|
||||||
tree->bt_bulk = NULL;
|
tree->bt_bulk = NULL;
|
||||||
}
|
}
|
||||||
@@ -290,7 +318,7 @@ zfs_btree_find(zfs_btree_t *tree, const void *value, zfs_btree_index_t *where)
|
|||||||
|
|
||||||
zfs_btree_core_t *node = NULL;
|
zfs_btree_core_t *node = NULL;
|
||||||
uint32_t child = 0;
|
uint32_t child = 0;
|
||||||
uint64_t depth = 0;
|
uint32_t depth = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterate down the tree, finding which child the value should be in
|
* Iterate down the tree, finding which child the value should be in
|
||||||
@@ -811,8 +839,7 @@ zfs_btree_insert_into_leaf(zfs_btree_t *tree, zfs_btree_leaf_t *leaf,
|
|||||||
move_count++;
|
move_count++;
|
||||||
}
|
}
|
||||||
tree->bt_num_nodes++;
|
tree->bt_num_nodes++;
|
||||||
zfs_btree_leaf_t *new_leaf = kmem_cache_alloc(zfs_btree_leaf_cache,
|
zfs_btree_leaf_t *new_leaf = zfs_btree_leaf_alloc(tree);
|
||||||
KM_SLEEP);
|
|
||||||
zfs_btree_hdr_t *new_hdr = &new_leaf->btl_hdr;
|
zfs_btree_hdr_t *new_hdr = &new_leaf->btl_hdr;
|
||||||
new_hdr->bth_parent = leaf->btl_hdr.bth_parent;
|
new_hdr->bth_parent = leaf->btl_hdr.bth_parent;
|
||||||
new_hdr->bth_first = (tree->bt_bulk ? 0 : capacity / 4) +
|
new_hdr->bth_first = (tree->bt_bulk ? 0 : capacity / 4) +
|
||||||
@@ -1078,8 +1105,7 @@ zfs_btree_add_idx(zfs_btree_t *tree, const void *value,
|
|||||||
ASSERT0(where->bti_offset);
|
ASSERT0(where->bti_offset);
|
||||||
|
|
||||||
tree->bt_num_nodes++;
|
tree->bt_num_nodes++;
|
||||||
zfs_btree_leaf_t *leaf = kmem_cache_alloc(zfs_btree_leaf_cache,
|
zfs_btree_leaf_t *leaf = zfs_btree_leaf_alloc(tree);
|
||||||
KM_SLEEP);
|
|
||||||
tree->bt_root = &leaf->btl_hdr;
|
tree->bt_root = &leaf->btl_hdr;
|
||||||
tree->bt_height++;
|
tree->bt_height++;
|
||||||
|
|
||||||
@@ -1378,7 +1404,7 @@ zfs_btree_node_destroy(zfs_btree_t *tree, zfs_btree_hdr_t *node)
|
|||||||
{
|
{
|
||||||
tree->bt_num_nodes--;
|
tree->bt_num_nodes--;
|
||||||
if (!zfs_btree_is_core(node)) {
|
if (!zfs_btree_is_core(node)) {
|
||||||
kmem_cache_free(zfs_btree_leaf_cache, node);
|
zfs_btree_leaf_free(tree, node);
|
||||||
} else {
|
} else {
|
||||||
kmem_free(node, sizeof (zfs_btree_core_t) +
|
kmem_free(node, sizeof (zfs_btree_core_t) +
|
||||||
BTREE_CORE_ELEMS * tree->bt_elem_size);
|
BTREE_CORE_ELEMS * tree->bt_elem_size);
|
||||||
@@ -1991,7 +2017,7 @@ zfs_btree_verify_counts(zfs_btree_t *tree)
|
|||||||
*/
|
*/
|
||||||
static uint64_t
|
static uint64_t
|
||||||
zfs_btree_verify_height_helper(zfs_btree_t *tree, zfs_btree_hdr_t *hdr,
|
zfs_btree_verify_height_helper(zfs_btree_t *tree, zfs_btree_hdr_t *hdr,
|
||||||
int64_t height)
|
int32_t height)
|
||||||
{
|
{
|
||||||
if (!zfs_btree_is_core(hdr)) {
|
if (!zfs_btree_is_core(hdr)) {
|
||||||
VERIFY0(height);
|
VERIFY0(height);
|
||||||
@@ -2117,8 +2143,10 @@ zfs_btree_verify_poison_helper(zfs_btree_t *tree, zfs_btree_hdr_t *hdr)
|
|||||||
zfs_btree_leaf_t *leaf = (zfs_btree_leaf_t *)hdr;
|
zfs_btree_leaf_t *leaf = (zfs_btree_leaf_t *)hdr;
|
||||||
for (size_t i = 0; i < hdr->bth_first * size; i++)
|
for (size_t i = 0; i < hdr->bth_first * size; i++)
|
||||||
VERIFY3U(leaf->btl_elems[i], ==, 0x0f);
|
VERIFY3U(leaf->btl_elems[i], ==, 0x0f);
|
||||||
|
size_t esize = tree->bt_leaf_size -
|
||||||
|
offsetof(zfs_btree_leaf_t, btl_elems);
|
||||||
for (size_t i = (hdr->bth_first + hdr->bth_count) * size;
|
for (size_t i = (hdr->bth_first + hdr->bth_count) * size;
|
||||||
i < BTREE_LEAF_ESIZE; i++)
|
i < esize; i++)
|
||||||
VERIFY3U(leaf->btl_elems[i], ==, 0x0f);
|
VERIFY3U(leaf->btl_elems[i], ==, 0x0f);
|
||||||
} else {
|
} else {
|
||||||
zfs_btree_core_t *node = (zfs_btree_core_t *)hdr;
|
zfs_btree_core_t *node = (zfs_btree_core_t *)hdr;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user