Compare commits

..

1 Commits

Author SHA1 Message Date
Brian Behlendorf 2d97c62d52 Revert "Do not persist user/group/project quota zap objects when unneeded"
This reverts commit 797f55ef12.
2023-10-23 09:14:46 -07:00
675 changed files with 13173 additions and 39787 deletions

View File

@ -1,4 +0,0 @@
name: "Custom CodeQL Analysis"
queries:
- uses: ./.github/codeql/custom-queries/cpp/deprecatedFunctionUsage.ql

View File

@ -1,4 +0,0 @@
name: "Custom CodeQL Analysis"
paths-ignore:
- tests

View File

@ -1,59 +0,0 @@
/**
* @name Deprecated function usage detection
* @description Detects functions whose usage is banned from the OpenZFS
* codebase due to QA concerns.
* @kind problem
* @severity error
* @id cpp/deprecated-function-usage
*/
import cpp
predicate isDeprecatedFunction(Function f) {
f.getName() = "strtok" or
f.getName() = "__xpg_basename" or
f.getName() = "basename" or
f.getName() = "dirname" or
f.getName() = "bcopy" or
f.getName() = "bcmp" or
f.getName() = "bzero" or
f.getName() = "asctime" or
f.getName() = "asctime_r" or
f.getName() = "gmtime" or
f.getName() = "localtime" or
f.getName() = "strncpy"
}
string getReplacementMessage(Function f) {
if f.getName() = "strtok" then
result = "Use strtok_r(3) instead!"
else if f.getName() = "__xpg_basename" then
result = "basename(3) is underspecified. Use zfs_basename() instead!"
else if f.getName() = "basename" then
result = "basename(3) is underspecified. Use zfs_basename() instead!"
else if f.getName() = "dirname" then
result = "dirname(3) is underspecified. Use zfs_dirnamelen() instead!"
else if f.getName() = "bcopy" then
result = "bcopy(3) is deprecated. Use memcpy(3)/memmove(3) instead!"
else if f.getName() = "bcmp" then
result = "bcmp(3) is deprecated. Use memcmp(3) instead!"
else if f.getName() = "bzero" then
result = "bzero(3) is deprecated. Use memset(3) instead!"
else if f.getName() = "asctime" then
result = "Use strftime(3) instead!"
else if f.getName() = "asctime_r" then
result = "Use strftime(3) instead!"
else if f.getName() = "gmtime" then
result = "gmtime(3) isn't thread-safe. Use gmtime_r(3) instead!"
else if f.getName() = "localtime" then
result = "localtime(3) isn't thread-safe. Use localtime_r(3) instead!"
else
result = "strncpy(3) is deprecated. Use strlcpy(3) instead!"
}
from FunctionCall fc, Function f
where
fc.getTarget() = f and
isDeprecatedFunction(f)
select fc, getReplacementMessage(f)

View File

@ -1,4 +0,0 @@
name: openzfs-cpp-queries
version: 0.0.0
libraryPathDependencies: codeql-cpp
suites: openzfs-cpp-suite

View File

@ -4,54 +4,44 @@
```mermaid ```mermaid
flowchart TB flowchart TB
subgraph CleanUp and Summary subgraph CleanUp and Summary
CleanUp+Summary Part1-20.04-->CleanUp+nice+Summary
Part2-20.04-->CleanUp+nice+Summary
PartN-20.04-->CleanUp+nice+Summary
Part1-22.04-->CleanUp+nice+Summary
Part2-22.04-->CleanUp+nice+Summary
PartN-22.04-->CleanUp+nice+Summary
end end
subgraph Functional Testings subgraph Functional Testings
sanity-checks-20.04
zloop-checks-20.04
functional-testing-20.04-->Part1-20.04 functional-testing-20.04-->Part1-20.04
functional-testing-20.04-->Part2-20.04 functional-testing-20.04-->Part2-20.04
functional-testing-20.04-->Part3-20.04 functional-testing-20.04-->PartN-20.04
functional-testing-20.04-->Part4-20.04
functional-testing-22.04-->Part1-22.04 functional-testing-22.04-->Part1-22.04
functional-testing-22.04-->Part2-22.04 functional-testing-22.04-->Part2-22.04
functional-testing-22.04-->Part3-22.04 functional-testing-22.04-->PartN-22.04
functional-testing-22.04-->Part4-22.04 end
sanity-checks-22.04
zloop-checks-22.04 subgraph Sanity and zloop Testings
sanity-checks-20.04-->functional-testing-20.04
sanity-checks-22.04-->functional-testing-22.04
zloop-checks-20.04-->functional
zloop-checks-22.04-->functional
end end
subgraph Code Checking + Building subgraph Code Checking + Building
Build-Ubuntu-20.04
codeql.yml codeql.yml
checkstyle.yml checkstyle.yml
Build-Ubuntu-22.04
end
Build-Ubuntu-20.04-->sanity-checks-20.04 Build-Ubuntu-20.04-->sanity-checks-20.04
Build-Ubuntu-20.04-->zloop-checks-20.04
Build-Ubuntu-20.04-->functional-testing-20.04
Build-Ubuntu-22.04-->sanity-checks-22.04 Build-Ubuntu-22.04-->sanity-checks-22.04
Build-Ubuntu-20.04-->zloop-checks-20.04
Build-Ubuntu-22.04-->zloop-checks-22.04 Build-Ubuntu-22.04-->zloop-checks-22.04
Build-Ubuntu-22.04-->functional-testing-22.04 end
sanity-checks-20.04-->CleanUp+Summary
Part1-20.04-->CleanUp+Summary
Part2-20.04-->CleanUp+Summary
Part3-20.04-->CleanUp+Summary
Part4-20.04-->CleanUp+Summary
Part1-22.04-->CleanUp+Summary
Part2-22.04-->CleanUp+Summary
Part3-22.04-->CleanUp+Summary
Part4-22.04-->CleanUp+Summary
sanity-checks-22.04-->CleanUp+Summary
``` ```
1) build zfs modules for Ubuntu 20.04 and 22.04 (~15m) 1) build zfs modules for Ubuntu 20.04 and 22.04 (~15m)
2) 2x zloop test (~10m) + 2x sanity test (~25m) 2) 2x zloop test (~10m) + 2x sanity test (~25m)
3) 4x functional testings in parts 1..4 (each ~1h) 3) functional testings in parts 1..5 (each ~1h)
4) cleanup and create summary 4) cleanup and create summary
- content of summary depends on the results of the steps - content of summary depends on the results of the steps

View File

@ -8,7 +8,7 @@ jobs:
checkstyle: checkstyle:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - 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
@ -52,7 +52,7 @@ jobs:
if: failure() && steps.CheckABI.outcome == 'failure' if: failure() && steps.CheckABI.outcome == 'failure'
run: | run: |
find -name *.abi | tar -cf abi_files.tar -T - find -name *.abi | tar -cf abi_files.tar -T -
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
if: failure() && steps.CheckABI.outcome == 'failure' if: failure() && steps.CheckABI.outcome == 'failure'
with: with:
name: New ABI files (use only if you're sure about interface changes) name: New ABI files (use only if you're sure about interface changes)

View File

@ -24,12 +24,11 @@ jobs:
echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v2
with: with:
config-file: .github/codeql-${{ matrix.language }}.yml
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
- name: Autobuild - name: Autobuild

View File

@ -87,7 +87,7 @@ function summarize_f() {
output "\n## $headline\n" output "\n## $headline\n"
rm -rf testfiles rm -rf testfiles
for i in $(seq 1 $FUNCTIONAL_PARTS); do for i in $(seq 1 $FUNCTIONAL_PARTS); do
tarfile="$2-part$i/part$i.tar" tarfile="$2/part$i.tar"
check_tarfile "$tarfile" check_tarfile "$tarfile"
check_logfile "testfiles/log" check_logfile "testfiles/log"
done done

View File

@ -55,24 +55,29 @@ function mod_install() {
cat /proc/spl/kstat/zfs/chksum_bench cat /proc/spl/kstat/zfs/chksum_bench
echo "::endgroup::" echo "::endgroup::"
echo "::group::Optimize storage for ZFS testings" echo "::group::Reclaim and report disk space"
# remove swap and umount fast storage # remove 4GiB of images
# 89GiB -> rootfs + bootfs with ~80MB/s -> don't care sudo systemd-run docker system prune --force --all --volumes
# 64GiB -> /mnt with 420MB/s -> new testing ssd
sudo swapoff -a
# this one is fast and mounted @ /mnt # remove unused software
# -> we reformat with ext4 + move it to /var/tmp sudo systemd-run --wait rm -rf \
DEV="/dev/disk/azure/resource-part1" "$AGENT_TOOLSDIRECTORY" \
sudo umount /mnt /opt/* \
sudo mkfs.ext4 -O ^has_journal -F $DEV /usr/local/* \
sudo mount -o noatime,barrier=0 $DEV /var/tmp /usr/share/az* \
sudo chmod 1777 /var/tmp /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 /
# disk usage afterwards # disk usage afterwards
sudo df -h / df -h /
sudo df -h /var/tmp
sudo fstrim -a
echo "::endgroup::" echo "::endgroup::"
} }

View File

@ -13,10 +13,10 @@ jobs:
zloop: zloop:
runs-on: ubuntu-${{ inputs.os }} runs-on: ubuntu-${{ inputs.os }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
with: with:
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v3
with: with:
name: modules-${{ inputs.os }} name: modules-${{ inputs.os }}
- name: Install modules - name: Install modules
@ -34,19 +34,19 @@ jobs:
if: failure() if: failure()
run: | run: |
sudo chmod +r -R /var/tmp/zloop/ sudo chmod +r -R /var/tmp/zloop/
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
if: failure() if: failure()
with: with:
name: Zloop-logs-${{ inputs.os }} name: Zpool-logs-${{ inputs.os }}
path: | path: |
/var/tmp/zloop/*/ /var/tmp/zloop/*/
!/var/tmp/zloop/*/vdev/ !/var/tmp/zloop/*/vdev/
retention-days: 14 retention-days: 14
if-no-files-found: ignore if-no-files-found: ignore
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
if: failure() if: failure()
with: with:
name: Zloop-files-${{ inputs.os }} name: Zpool-files-${{ inputs.os }}
path: | path: |
/var/tmp/zloop/*/vdev/ /var/tmp/zloop/*/vdev/
retention-days: 14 retention-days: 14
@ -55,10 +55,10 @@ jobs:
sanity: sanity:
runs-on: ubuntu-${{ inputs.os }} runs-on: ubuntu-${{ inputs.os }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
with: with:
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v3
with: with:
name: modules-${{ inputs.os }} name: modules-${{ inputs.os }}
- name: Install modules - name: Install modules
@ -77,7 +77,7 @@ jobs:
RESPATH="/var/tmp/test_results" RESPATH="/var/tmp/test_results"
mv -f $RESPATH/current $RESPATH/testfiles mv -f $RESPATH/current $RESPATH/testfiles
tar cf $RESPATH/sanity.tar -h -C $RESPATH testfiles tar cf $RESPATH/sanity.tar -h -C $RESPATH testfiles
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
if: success() || failure() if: success() || failure()
with: with:
name: Logs-${{ inputs.os }}-sanity name: Logs-${{ inputs.os }}-sanity
@ -91,10 +91,10 @@ jobs:
matrix: matrix:
tests: [ part1, part2, part3, part4 ] tests: [ part1, part2, part3, part4 ]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
with: with:
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v3
with: with:
name: modules-${{ inputs.os }} name: modules-${{ inputs.os }}
- name: Install modules - name: Install modules
@ -116,9 +116,9 @@ jobs:
RESPATH="/var/tmp/test_results" RESPATH="/var/tmp/test_results"
mv -f $RESPATH/current $RESPATH/testfiles mv -f $RESPATH/current $RESPATH/testfiles
tar cf $RESPATH/${{ matrix.tests }}.tar -h -C $RESPATH testfiles tar cf $RESPATH/${{ matrix.tests }}.tar -h -C $RESPATH testfiles
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
if: success() || failure() if: success() || failure()
with: with:
name: Logs-${{ inputs.os }}-functional-${{ matrix.tests }} name: Logs-${{ inputs.os }}-functional
path: /var/tmp/test_results/${{ matrix.tests }}.tar path: /var/tmp/test_results/${{ matrix.tests }}.tar
if-no-files-found: ignore if-no-files-found: ignore

View File

@ -14,14 +14,14 @@ jobs:
os: [20.04, 22.04] os: [20.04, 22.04]
runs-on: ubuntu-${{ matrix.os }} runs-on: ubuntu-${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
with: with:
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: Build modules - name: Build modules
run: .github/workflows/scripts/setup-dependencies.sh build run: .github/workflows/scripts/setup-dependencies.sh build
- name: Prepare modules upload - name: Prepare modules upload
run: tar czf modules-${{ matrix.os }}.tgz *.deb .github tests/test-runner tests/ImageOS.txt run: tar czf modules-${{ matrix.os }}.tgz *.deb .github tests/test-runner tests/ImageOS.txt
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
with: with:
name: modules-${{ matrix.os }} name: modules-${{ matrix.os }}
path: modules-${{ matrix.os }}.tgz path: modules-${{ matrix.os }}.tgz
@ -44,7 +44,7 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
needs: testings needs: testings
steps: steps:
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v3
- name: Generating summary - name: Generating summary
run: | run: |
tar xzf modules-22.04/modules-22.04.tgz .github tests tar xzf modules-22.04/modules-22.04.tgz .github tests
@ -58,7 +58,7 @@ jobs:
run: .github/workflows/scripts/generate-summary.sh 3 run: .github/workflows/scripts/generate-summary.sh 3
- name: Summary for errors #4 - name: Summary for errors #4
run: .github/workflows/scripts/generate-summary.sh 4 run: .github/workflows/scripts/generate-summary.sh 4
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
with: with:
name: Summary Files name: Summary Files
path: Summary/ path: Summary/

1
.gitignore vendored
View File

@ -83,7 +83,6 @@
modules.order modules.order
Makefile Makefile
Makefile.in Makefile.in
changelog
*.patch *.patch
*.orig *.orig
*.tmp *.tmp

View File

@ -30,7 +30,6 @@ Andreas Dilger <adilger@dilger.ca>
Andrew Walker <awalker@ixsystems.com> Andrew Walker <awalker@ixsystems.com>
Benedikt Neuffer <github@itfriend.de> Benedikt Neuffer <github@itfriend.de>
Chengfei Zhu <chengfeix.zhu@intel.com> Chengfei Zhu <chengfeix.zhu@intel.com>
ChenHao Lu <18302010006@fudan.edu.cn>
Chris Lindee <chris.lindee+github@gmail.com> Chris Lindee <chris.lindee+github@gmail.com>
Colm Buckley <colm@tuatha.org> Colm Buckley <colm@tuatha.org>
Crag Wang <crag0715@gmail.com> Crag Wang <crag0715@gmail.com>
@ -44,7 +43,6 @@ Glenn Washburn <development@efficientek.com>
Gordan Bobic <gordan.bobic@gmail.com> Gordan Bobic <gordan.bobic@gmail.com>
Gregory Bartholomew <gregory.lee.bartholomew@gmail.com> Gregory Bartholomew <gregory.lee.bartholomew@gmail.com>
hedong zhang <h_d_zhang@163.com> hedong zhang <h_d_zhang@163.com>
Ilkka Sovanto <github@ilkka.kapsi.fi>
InsanePrawn <Insane.Prawny@gmail.com> InsanePrawn <Insane.Prawny@gmail.com>
Jason Cohen <jwittlincohen@gmail.com> Jason Cohen <jwittlincohen@gmail.com>
Jason Harmening <jason.harmening@gmail.com> Jason Harmening <jason.harmening@gmail.com>
@ -59,7 +57,6 @@ KernelOfTruth <kerneloftruth@gmail.com>
Liu Hua <liu.hua130@zte.com.cn> Liu Hua <liu.hua130@zte.com.cn>
Liu Qing <winglq@gmail.com> Liu Qing <winglq@gmail.com>
loli10K <ezomori.nozomu@gmail.com> loli10K <ezomori.nozomu@gmail.com>
Mart Frauenlob <allkind@fastest.cc>
Matthias Blankertz <matthias@blankertz.org> Matthias Blankertz <matthias@blankertz.org>
Michael Gmelin <grembo@FreeBSD.org> Michael Gmelin <grembo@FreeBSD.org>
Olivier Mazouffre <olivier.mazouffre@ims-bordeaux.fr> Olivier Mazouffre <olivier.mazouffre@ims-bordeaux.fr>
@ -76,12 +73,6 @@ WHR <msl0000023508@gmail.com>
Yanping Gao <yanping.gao@xtaotech.com> Yanping Gao <yanping.gao@xtaotech.com>
Youzhong Yang <youzhong@gmail.com> Youzhong Yang <youzhong@gmail.com>
# Signed-off-by: overriding Author:
Ryan <errornointernet@envs.net> <error.nointernet@gmail.com>
Qiuhao Chen <chenqiuhao1997@gmail.com> <haohao0924@126.com>
Yuxin Wang <yuxinwang9999@gmail.com> <Bi11gates9999@gmail.com>
Zhenlei Huang <zlei@FreeBSD.org> <zlei.huang@gmail.com>
# Commits from strange places, long ago # Commits from strange places, long ago
Brian Behlendorf <behlendorf1@llnl.gov> <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c> Brian Behlendorf <behlendorf1@llnl.gov> <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>
Brian Behlendorf <behlendorf1@llnl.gov> <behlendo@fedora-17-amd64.(none)> Brian Behlendorf <behlendorf1@llnl.gov> <behlendo@fedora-17-amd64.(none)>
@ -98,7 +89,6 @@ Alek Pinchuk <apinchuk@axcient.com> <alek-p@users.noreply.github.com>
Alexander Lobakin <alobakin@pm.me> <solbjorn@users.noreply.github.com> Alexander Lobakin <alobakin@pm.me> <solbjorn@users.noreply.github.com>
Alexey Smirnoff <fling@member.fsf.org> <fling-@users.noreply.github.com> Alexey Smirnoff <fling@member.fsf.org> <fling-@users.noreply.github.com>
Allen Holl <allen.m.holl@gmail.com> <65494904+allen-4@users.noreply.github.com> Allen Holl <allen.m.holl@gmail.com> <65494904+allen-4@users.noreply.github.com>
Alphan Yılmaz <alphanyilmaz@gmail.com> <a1ea321@users.noreply.github.com>
Ameer Hamza <ahamza@ixsystems.com> <106930537+ixhamza@users.noreply.github.com> Ameer Hamza <ahamza@ixsystems.com> <106930537+ixhamza@users.noreply.github.com>
Andrew J. Hesford <ajh@sideband.org> <48421688+ahesford@users.noreply.github.com>> Andrew J. Hesford <ajh@sideband.org> <48421688+ahesford@users.noreply.github.com>>
Andrew Sun <me@andrewsun.com> <as-com@users.noreply.github.com> Andrew Sun <me@andrewsun.com> <as-com@users.noreply.github.com>
@ -106,22 +96,18 @@ Aron Xu <happyaron.xu@gmail.com> <happyaron@users.noreply.github.com>
Arun KV <arun.kv@datacore.com> <65647132+arun-kv@users.noreply.github.com> Arun KV <arun.kv@datacore.com> <65647132+arun-kv@users.noreply.github.com>
Ben Wolsieffer <benwolsieffer@gmail.com> <lopsided98@users.noreply.github.com> Ben Wolsieffer <benwolsieffer@gmail.com> <lopsided98@users.noreply.github.com>
bernie1995 <bernie.pikes@gmail.com> <42413912+bernie1995@users.noreply.github.com> bernie1995 <bernie.pikes@gmail.com> <42413912+bernie1995@users.noreply.github.com>
Bojan Novković <bnovkov@FreeBSD.org> <72801811+bnovkov@users.noreply.github.com>
Boris Protopopov <boris.protopopov@actifio.com> <bprotopopov@users.noreply.github.com> Boris Protopopov <boris.protopopov@actifio.com> <bprotopopov@users.noreply.github.com>
Brad Forschinger <github@bnjf.id.au> <bnjf@users.noreply.github.com> Brad Forschinger <github@bnjf.id.au> <bnjf@users.noreply.github.com>
Brandon Thetford <brandon@dodecatec.com> <dodexahedron@users.noreply.github.com> Brandon Thetford <brandon@dodecatec.com> <dodexahedron@users.noreply.github.com>
buzzingwires <buzzingwires@outlook.com> <131118055+buzzingwires@users.noreply.github.com> buzzingwires <buzzingwires@outlook.com> <131118055+buzzingwires@users.noreply.github.com>
Cedric Maunoury <cedric.maunoury@gmail.com> <38213715+cedricmaunoury@users.noreply.github.com> Cedric Maunoury <cedric.maunoury@gmail.com> <38213715+cedricmaunoury@users.noreply.github.com>
Charles Suh <charles.suh@gmail.com> <charlessuh@users.noreply.github.com> Charles Suh <charles.suh@gmail.com> <charlessuh@users.noreply.github.com>
Chris Peredun <chris.peredun@ixsystems.com> <126915832+chrisperedun@users.noreply.github.com>
Dacian Reece-Stremtan <dacianstremtan@gmail.com> <35844628+dacianstremtan@users.noreply.github.com> Dacian Reece-Stremtan <dacianstremtan@gmail.com> <35844628+dacianstremtan@users.noreply.github.com>
Damian Szuberski <szuberskidamian@gmail.com> <30863496+szubersk@users.noreply.github.com> Damian Szuberski <szuberskidamian@gmail.com> <30863496+szubersk@users.noreply.github.com>
Daniel Hiepler <d-git@coderdu.de> <32984777+heeplr@users.noreply.github.com> Daniel Hiepler <d-git@coderdu.de> <32984777+heeplr@users.noreply.github.com>
Daniel Kobras <d.kobras@science-computing.de> <sckobras@users.noreply.github.com> Daniel Kobras <d.kobras@science-computing.de> <sckobras@users.noreply.github.com>
Daniel Reichelt <hacking@nachtgeist.net> <nachtgeist@users.noreply.github.com> Daniel Reichelt <hacking@nachtgeist.net> <nachtgeist@users.noreply.github.com>
David Quigley <david.quigley@intel.com> <dpquigl@users.noreply.github.com> David Quigley <david.quigley@intel.com> <dpquigl@users.noreply.github.com>
Dennis R. Friedrichsen <dennis.r.friedrichsen@gmail.com> <31087738+dennisfriedrichsen@users.noreply.github.com>
Dex Wood <slash2314@gmail.com> <slash2314@users.noreply.github.com>
DHE <git@dehacked.net> <DeHackEd@users.noreply.github.com> DHE <git@dehacked.net> <DeHackEd@users.noreply.github.com>
Dmitri John Ledkov <dimitri.ledkov@canonical.com> <19779+xnox@users.noreply.github.com> Dmitri John Ledkov <dimitri.ledkov@canonical.com> <19779+xnox@users.noreply.github.com>
Dries Michiels <driesm.michiels@gmail.com> <32487486+driesmp@users.noreply.github.com> Dries Michiels <driesm.michiels@gmail.com> <32487486+driesmp@users.noreply.github.com>
@ -142,7 +128,6 @@ Harry Mallon <hjmallon@gmail.com> <1816667+hjmallon@users.noreply.github.com>
Hiếu Lê <leorize+oss@disroot.org> <alaviss@users.noreply.github.com> Hiếu Lê <leorize+oss@disroot.org> <alaviss@users.noreply.github.com>
Jake Howard <git@theorangeone.net> <RealOrangeOne@users.noreply.github.com> Jake Howard <git@theorangeone.net> <RealOrangeOne@users.noreply.github.com>
James Cowgill <james.cowgill@mips.com> <jcowgill@users.noreply.github.com> James Cowgill <james.cowgill@mips.com> <jcowgill@users.noreply.github.com>
Jaron Kent-Dobias <jaron@kent-dobias.com> <kentdobias@users.noreply.github.com>
Jason King <jason.king@joyent.com> <jasonbking@users.noreply.github.com> Jason King <jason.king@joyent.com> <jasonbking@users.noreply.github.com>
Jeff Dike <jdike@akamai.com> <52420226+jdike@users.noreply.github.com> Jeff Dike <jdike@akamai.com> <52420226+jdike@users.noreply.github.com>
Jitendra Patidar <jitendra.patidar@nutanix.com> <53164267+jsai20@users.noreply.github.com> Jitendra Patidar <jitendra.patidar@nutanix.com> <53164267+jsai20@users.noreply.github.com>
@ -152,9 +137,7 @@ John L. Hammond <john.hammond@intel.com> <35266395+jhammond-intel@users.noreply.
John-Mark Gurney <jmg@funkthat.com> <jmgurney@users.noreply.github.com> John-Mark Gurney <jmg@funkthat.com> <jmgurney@users.noreply.github.com>
John Ramsden <johnramsden@riseup.net> <johnramsden@users.noreply.github.com> John Ramsden <johnramsden@riseup.net> <johnramsden@users.noreply.github.com>
Jonathon Fernyhough <jonathon@m2x.dev> <559369+jonathonf@users.noreply.github.com> Jonathon Fernyhough <jonathon@m2x.dev> <559369+jonathonf@users.noreply.github.com>
Jose Luis Duran <jlduran@gmail.com> <jlduran@users.noreply.github.com>
Justin Hibbits <chmeeedalf@gmail.com> <chmeeedalf@users.noreply.github.com> Justin Hibbits <chmeeedalf@gmail.com> <chmeeedalf@users.noreply.github.com>
Kevin Greene <kevin.greene@delphix.com> <104801862+kxgreene@users.noreply.github.com>
Kevin Jin <lostking2008@hotmail.com> <33590050+jxdking@users.noreply.github.com> Kevin Jin <lostking2008@hotmail.com> <33590050+jxdking@users.noreply.github.com>
Kevin P. Fleming <kevin@km6g.us> <kpfleming@users.noreply.github.com> Kevin P. Fleming <kevin@km6g.us> <kpfleming@users.noreply.github.com>
Krzysztof Piecuch <piecuch@kpiecuch.pl> <3964215+pikrzysztof@users.noreply.github.com> Krzysztof Piecuch <piecuch@kpiecuch.pl> <3964215+pikrzysztof@users.noreply.github.com>
@ -165,11 +148,9 @@ Lorenz Hüdepohl <dev@stellardeath.org> <lhuedepohl@users.noreply.github.com>
Luís Henriques <henrix@camandro.org> <73643340+lumigch@users.noreply.github.com> Luís Henriques <henrix@camandro.org> <73643340+lumigch@users.noreply.github.com>
Marcin Skarbek <git@skarbek.name> <mskarbek@users.noreply.github.com> Marcin Skarbek <git@skarbek.name> <mskarbek@users.noreply.github.com>
Matt Fiddaman <github@m.fiddaman.uk> <81489167+matt-fidd@users.noreply.github.com> Matt Fiddaman <github@m.fiddaman.uk> <81489167+matt-fidd@users.noreply.github.com>
Maxim Filimonov <che@bein.link> <part1zano@users.noreply.github.com>
Max Zettlmeißl <max@zettlmeissl.de> <6818198+maxz@users.noreply.github.com> Max Zettlmeißl <max@zettlmeissl.de> <6818198+maxz@users.noreply.github.com>
Michael Niewöhner <foss@mniewoehner.de> <c0d3z3r0@users.noreply.github.com> Michael Niewöhner <foss@mniewoehner.de> <c0d3z3r0@users.noreply.github.com>
Michael Zhivich <mzhivich@akamai.com> <33133421+mzhivich@users.noreply.github.com> Michael Zhivich <mzhivich@akamai.com> <33133421+mzhivich@users.noreply.github.com>
MigeljanImeri <ImeriMigel@gmail.com> <78048439+MigeljanImeri@users.noreply.github.com>
Mo Zhou <cdluminate@gmail.com> <5723047+cdluminate@users.noreply.github.com> Mo Zhou <cdluminate@gmail.com> <5723047+cdluminate@users.noreply.github.com>
Nick Mattis <nickm970@gmail.com> <nmattis@users.noreply.github.com> Nick Mattis <nickm970@gmail.com> <nmattis@users.noreply.github.com>
omni <omni+vagant@hack.org> <79493359+omnivagant@users.noreply.github.com> omni <omni+vagant@hack.org> <79493359+omnivagant@users.noreply.github.com>
@ -183,7 +164,6 @@ Ping Huang <huangping@smartx.com> <101400146+hpingfs@users.noreply.github.com>
Piotr P. Stefaniak <pstef@freebsd.org> <pstef@users.noreply.github.com> Piotr P. Stefaniak <pstef@freebsd.org> <pstef@users.noreply.github.com>
Richard Allen <belperite@gmail.com> <33836503+belperite@users.noreply.github.com> Richard Allen <belperite@gmail.com> <33836503+belperite@users.noreply.github.com>
Rich Ercolani <rincebrain@gmail.com> <214141+rincebrain@users.noreply.github.com> Rich Ercolani <rincebrain@gmail.com> <214141+rincebrain@users.noreply.github.com>
Rick Macklem <rmacklem@uoguelph.ca> <64620010+rmacklem@users.noreply.github.com>
Rob Wing <rob.wing@klarasystems.com> <98866084+rob-wing@users.noreply.github.com> Rob Wing <rob.wing@klarasystems.com> <98866084+rob-wing@users.noreply.github.com>
Roman Strashkin <roman.strashkin@nexenta.com> <Ramzec@users.noreply.github.com> Roman Strashkin <roman.strashkin@nexenta.com> <Ramzec@users.noreply.github.com>
Ryan Hirasaki <ryanhirasaki@gmail.com> <4690732+RyanHir@users.noreply.github.com> Ryan Hirasaki <ryanhirasaki@gmail.com> <4690732+RyanHir@users.noreply.github.com>
@ -194,17 +174,13 @@ Scott Colby <scott@scolby.com> <scolby33@users.noreply.github.com>
Sean Eric Fagan <kithrup@mac.com> <kithrup@users.noreply.github.com> Sean Eric Fagan <kithrup@mac.com> <kithrup@users.noreply.github.com>
Spencer Kinny <spencerkinny1995@gmail.com> <30333052+Spencer-Kinny@users.noreply.github.com> Spencer Kinny <spencerkinny1995@gmail.com> <30333052+Spencer-Kinny@users.noreply.github.com>
Srikanth N S <srikanth.nagasubbaraoseetharaman@hpe.com> <75025422+nssrikanth@users.noreply.github.com> Srikanth N S <srikanth.nagasubbaraoseetharaman@hpe.com> <75025422+nssrikanth@users.noreply.github.com>
Stefan Lendl <s.lendl@proxmox.com> <1321542+stfl@users.noreply.github.com>
Thomas Bertschinger <bertschinger@lanl.gov> <101425190+bertschinger@users.noreply.github.com>
Thomas Geppert <geppi@digitx.de> <geppi@users.noreply.github.com> Thomas Geppert <geppi@digitx.de> <geppi@users.noreply.github.com>
Tim Crawford <tcrawford@datto.com> <crawfxrd@users.noreply.github.com> Tim Crawford <tcrawford@datto.com> <crawfxrd@users.noreply.github.com>
Todd Seidelmann <18294602+seidelma@users.noreply.github.com>
Tom Matthews <tom@axiom-partners.com> <tomtastic@users.noreply.github.com> Tom Matthews <tom@axiom-partners.com> <tomtastic@users.noreply.github.com>
Tony Perkins <tperkins@datto.com> <62951051+tony-zfs@users.noreply.github.com> Tony Perkins <tperkins@datto.com> <62951051+tony-zfs@users.noreply.github.com>
Torsten Wörtwein <twoertwein@gmail.com> <twoertwein@users.noreply.github.com> Torsten Wörtwein <twoertwein@gmail.com> <twoertwein@users.noreply.github.com>
Tulsi Jain <tulsi.jain@delphix.com> <TulsiJain@users.noreply.github.com> Tulsi Jain <tulsi.jain@delphix.com> <TulsiJain@users.noreply.github.com>
Václav Skála <skala@vshosting.cz> <33496485+vaclavskala@users.noreply.github.com> Václav Skála <skala@vshosting.cz> <33496485+vaclavskala@users.noreply.github.com>
Vaibhav Bhanawat <vaibhav.bhanawat@delphix.com> <88050553+vaibhav-delphix@users.noreply.github.com>
Violet Purcell <vimproved@inventati.org> <66446404+vimproved@users.noreply.github.com> Violet Purcell <vimproved@inventati.org> <66446404+vimproved@users.noreply.github.com>
Vipin Kumar Verma <vipin.verma@hpe.com> <75025470+vermavipinkumar@users.noreply.github.com> Vipin Kumar Verma <vipin.verma@hpe.com> <75025470+vermavipinkumar@users.noreply.github.com>
Wolfgang Bumiller <w.bumiller@proxmox.com> <Blub@users.noreply.github.com> Wolfgang Bumiller <w.bumiller@proxmox.com> <Blub@users.noreply.github.com>

48
AUTHORS
View File

@ -46,7 +46,6 @@ CONTRIBUTORS:
Alex Zhuravlev <alexey.zhuravlev@intel.com> Alex Zhuravlev <alexey.zhuravlev@intel.com>
Allan Jude <allanjude@freebsd.org> Allan Jude <allanjude@freebsd.org>
Allen Holl <allen.m.holl@gmail.com> Allen Holl <allen.m.holl@gmail.com>
Alphan Yılmaz <alphanyilmaz@gmail.com>
alteriks <alteriks@gmail.com> alteriks <alteriks@gmail.com>
Alyssa Ross <hi@alyssa.is> Alyssa Ross <hi@alyssa.is>
Ameer Hamza <ahamza@ixsystems.com> Ameer Hamza <ahamza@ixsystems.com>
@ -89,18 +88,15 @@ CONTRIBUTORS:
Bassu <bassu@phi9.com> Bassu <bassu@phi9.com>
Ben Allen <bsallen@alcf.anl.gov> Ben Allen <bsallen@alcf.anl.gov>
Ben Cordero <bencord0@condi.me> Ben Cordero <bencord0@condi.me>
Benda Xu <orv@debian.org>
Benedikt Neuffer <github@itfriend.de> Benedikt Neuffer <github@itfriend.de>
Benjamin Albrecht <git@albrecht.io> Benjamin Albrecht <git@albrecht.io>
Benjamin Gentil <benjgentil.pro@gmail.com> Benjamin Gentil <benjgentil.pro@gmail.com>
Benjamin Sherman <benjamin@holyarmy.org>
Ben McGough <bmcgough@fredhutch.org> Ben McGough <bmcgough@fredhutch.org>
Ben Rubson <ben.rubson@gmail.com> Ben Rubson <ben.rubson@gmail.com>
Ben Wolsieffer <benwolsieffer@gmail.com> Ben Wolsieffer <benwolsieffer@gmail.com>
bernie1995 <bernie.pikes@gmail.com> bernie1995 <bernie.pikes@gmail.com>
Bill McGonigle <bill-github.com-public1@bfccomputing.com> Bill McGonigle <bill-github.com-public1@bfccomputing.com>
Bill Pijewski <wdp@joyent.com> Bill Pijewski <wdp@joyent.com>
Bojan Novković <bnovkov@FreeBSD.org>
Boris Protopopov <boris.protopopov@nexenta.com> Boris Protopopov <boris.protopopov@nexenta.com>
Brad Forschinger <github@bnjf.id.au> Brad Forschinger <github@bnjf.id.au>
Brad Lewis <brad.lewis@delphix.com> Brad Lewis <brad.lewis@delphix.com>
@ -115,7 +111,6 @@ CONTRIBUTORS:
bzzz77 <bzzz.tomas@gmail.com> bzzz77 <bzzz.tomas@gmail.com>
cable2999 <cable2999@users.noreply.github.com> cable2999 <cable2999@users.noreply.github.com>
Caleb James DeLisle <calebdelisle@lavabit.com> Caleb James DeLisle <calebdelisle@lavabit.com>
Cameron Harr <harr1@llnl.gov>
Cao Xuewen <cao.xuewen@zte.com.cn> Cao Xuewen <cao.xuewen@zte.com.cn>
Carlo Landmeter <clandmeter@gmail.com> Carlo Landmeter <clandmeter@gmail.com>
Carlos Alberto Lopez Perez <clopez@igalia.com> Carlos Alberto Lopez Perez <clopez@igalia.com>
@ -125,15 +120,12 @@ CONTRIBUTORS:
Chen Can <chen.can2@zte.com.cn> Chen Can <chen.can2@zte.com.cn>
Chengfei Zhu <chengfeix.zhu@intel.com> Chengfei Zhu <chengfeix.zhu@intel.com>
Chen Haiquan <oc@yunify.com> Chen Haiquan <oc@yunify.com>
ChenHao Lu <18302010006@fudan.edu.cn>
Chip Parker <aparker@enthought.com> Chip Parker <aparker@enthought.com>
Chris Burroughs <chris.burroughs@gmail.com> Chris Burroughs <chris.burroughs@gmail.com>
Chris Davidson <christopher.davidson@gmail.com>
Chris Dunlap <cdunlap@llnl.gov> Chris Dunlap <cdunlap@llnl.gov>
Chris Dunlop <chris@onthe.net.au> Chris Dunlop <chris@onthe.net.au>
Chris Lindee <chris.lindee+github@gmail.com> Chris Lindee <chris.lindee+github@gmail.com>
Chris McDonough <chrism@plope.com> Chris McDonough <chrism@plope.com>
Chris Peredun <chris.peredun@ixsystems.com>
Chris Siden <chris.siden@delphix.com> Chris Siden <chris.siden@delphix.com>
Chris Siebenmann <cks.github@cs.toronto.edu> Chris Siebenmann <cks.github@cs.toronto.edu>
Christer Ekholm <che@chrekh.se> Christer Ekholm <che@chrekh.se>
@ -152,7 +144,6 @@ CONTRIBUTORS:
Clint Armstrong <clint@clintarmstrong.net> Clint Armstrong <clint@clintarmstrong.net>
Coleman Kane <ckane@colemankane.org> Coleman Kane <ckane@colemankane.org>
Colin Ian King <colin.king@canonical.com> Colin Ian King <colin.king@canonical.com>
Colin Percival <cperciva@tarsnap.com>
Colm Buckley <colm@tuatha.org> Colm Buckley <colm@tuatha.org>
Crag Wang <crag0715@gmail.com> Crag Wang <crag0715@gmail.com>
Craig Loomis <cloomis@astro.princeton.edu> Craig Loomis <cloomis@astro.princeton.edu>
@ -165,12 +156,10 @@ CONTRIBUTORS:
Damiano Albani <damiano.albani@gmail.com> Damiano Albani <damiano.albani@gmail.com>
Damian Szuberski <szuberskidamian@gmail.com> Damian Szuberski <szuberskidamian@gmail.com>
Damian Wojsław <damian@wojslaw.pl> Damian Wojsław <damian@wojslaw.pl>
Daniel Berlin <dberlin@dberlin.org>
Daniel Hiepler <d-git@coderdu.de> Daniel Hiepler <d-git@coderdu.de>
Daniel Hoffman <dj.hoffman@delphix.com> Daniel Hoffman <dj.hoffman@delphix.com>
Daniel Kobras <d.kobras@science-computing.de> Daniel Kobras <d.kobras@science-computing.de>
Daniel Kolesa <daniel@octaforge.org> Daniel Kolesa <daniel@octaforge.org>
Daniel Perry <dtperry@amazon.com>
Daniel Reichelt <hacking@nachtgeist.net> Daniel Reichelt <hacking@nachtgeist.net>
Daniel Stevenson <bot@dstev.net> Daniel Stevenson <bot@dstev.net>
Daniel Verite <daniel@verite.pro> Daniel Verite <daniel@verite.pro>
@ -187,11 +176,8 @@ CONTRIBUTORS:
David Quigley <david.quigley@intel.com> David Quigley <david.quigley@intel.com>
Debabrata Banerjee <dbanerje@akamai.com> Debabrata Banerjee <dbanerje@akamai.com>
D. Ebdrup <debdrup@freebsd.org> D. Ebdrup <debdrup@freebsd.org>
Dennis R. Friedrichsen <dennis.r.friedrichsen@gmail.com>
Denys Rtveliashvili <denys@rtveliashvili.name> Denys Rtveliashvili <denys@rtveliashvili.name>
Derek Dai <daiderek@gmail.com> Derek Dai <daiderek@gmail.com>
Derek Schrock <dereks@lifeofadishwasher.com>
Dex Wood <slash2314@gmail.com>
DHE <git@dehacked.net> DHE <git@dehacked.net>
Didier Roche <didrocks@ubuntu.com> Didier Roche <didrocks@ubuntu.com>
Dimitri John Ledkov <xnox@ubuntu.com> Dimitri John Ledkov <xnox@ubuntu.com>
@ -249,12 +235,9 @@ CONTRIBUTORS:
Gionatan Danti <g.danti@assyoma.it> Gionatan Danti <g.danti@assyoma.it>
Giuseppe Di Natale <guss80@gmail.com> Giuseppe Di Natale <guss80@gmail.com>
Glenn Washburn <development@efficientek.com> Glenn Washburn <development@efficientek.com>
glibg10b <glibg10b@users.noreply.github.com>
gofaster <felix.gofaster@gmail.com>
Gordan Bobic <gordan@redsleeve.org> Gordan Bobic <gordan@redsleeve.org>
Gordon Bergling <gbergling@googlemail.com> Gordon Bergling <gbergling@googlemail.com>
Gordon Ross <gwr@nexenta.com> Gordon Ross <gwr@nexenta.com>
Gordon Tetlow <gordon@freebsd.org>
Graham Christensen <graham@grahamc.com> Graham Christensen <graham@grahamc.com>
Graham Perrin <grahamperrin@gmail.com> Graham Perrin <grahamperrin@gmail.com>
Gregor Kopka <gregor@kopka.net> Gregor Kopka <gregor@kopka.net>
@ -282,7 +265,6 @@ CONTRIBUTORS:
Igor Kozhukhov <ikozhukhov@gmail.com> Igor Kozhukhov <ikozhukhov@gmail.com>
Igor Lvovsky <ilvovsky@gmail.com> Igor Lvovsky <ilvovsky@gmail.com>
ilbsmart <wgqimut@gmail.com> ilbsmart <wgqimut@gmail.com>
Ilkka Sovanto <github@ilkka.kapsi.fi>
illiliti <illiliti@protonmail.com> illiliti <illiliti@protonmail.com>
ilovezfs <ilovezfs@icloud.com> ilovezfs <ilovezfs@icloud.com>
InsanePrawn <Insane.Prawny@gmail.com> InsanePrawn <Insane.Prawny@gmail.com>
@ -298,11 +280,9 @@ CONTRIBUTORS:
Jan Engelhardt <jengelh@inai.de> Jan Engelhardt <jengelh@inai.de>
Jan Kryl <jan.kryl@nexenta.com> Jan Kryl <jan.kryl@nexenta.com>
Jan Sanislo <oystr@cs.washington.edu> Jan Sanislo <oystr@cs.washington.edu>
Jaron Kent-Dobias <jaron@kent-dobias.com>
Jason Cohen <jwittlincohen@gmail.com> Jason Cohen <jwittlincohen@gmail.com>
Jason Harmening <jason.harmening@gmail.com> Jason Harmening <jason.harmening@gmail.com>
Jason King <jason.brian.king@gmail.com> Jason King <jason.brian.king@gmail.com>
Jason Lee <jasonlee@lanl.gov>
Jason Zaman <jasonzaman@gmail.com> Jason Zaman <jasonzaman@gmail.com>
Javen Wu <wu.javen@gmail.com> Javen Wu <wu.javen@gmail.com>
Jean-Baptiste Lallement <jean-baptiste@ubuntu.com> Jean-Baptiste Lallement <jean-baptiste@ubuntu.com>
@ -333,7 +313,6 @@ CONTRIBUTORS:
Jonathon Fernyhough <jonathon@m2x.dev> Jonathon Fernyhough <jonathon@m2x.dev>
Jorgen Lundman <lundman@lundman.net> Jorgen Lundman <lundman@lundman.net>
Josef 'Jeff' Sipek <josef.sipek@nexenta.com> Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Jose Luis Duran <jlduran@gmail.com>
Josh Soref <jsoref@users.noreply.github.com> Josh Soref <jsoref@users.noreply.github.com>
Joshua M. Clulow <josh@sysmgr.org> Joshua M. Clulow <josh@sysmgr.org>
José Luis Salvador Rufo <salvador.joseluis@gmail.com> José Luis Salvador Rufo <salvador.joseluis@gmail.com>
@ -357,10 +336,8 @@ CONTRIBUTORS:
Kash Pande <kash@tripleback.net> Kash Pande <kash@tripleback.net>
Kay Pedersen <christianpe96@gmail.com> Kay Pedersen <christianpe96@gmail.com>
Keith M Wesolowski <wesolows@foobazco.org> Keith M Wesolowski <wesolows@foobazco.org>
Kent Ross <k@mad.cash>
KernelOfTruth <kerneloftruth@gmail.com> KernelOfTruth <kerneloftruth@gmail.com>
Kevin Bowling <kevin.bowling@kev009.com> Kevin Bowling <kevin.bowling@kev009.com>
Kevin Greene <kevin.greene@delphix.com>
Kevin Jin <lostking2008@hotmail.com> Kevin Jin <lostking2008@hotmail.com>
Kevin P. Fleming <kevin@km6g.us> Kevin P. Fleming <kevin@km6g.us>
Kevin Tanguy <kevin.tanguy@ovh.net> Kevin Tanguy <kevin.tanguy@ovh.net>
@ -412,10 +389,8 @@ CONTRIBUTORS:
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM> Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
marku89 <mar42@kola.li> marku89 <mar42@kola.li>
Mark Wright <markwright@internode.on.net> Mark Wright <markwright@internode.on.net>
Mart Frauenlob <allkind@fastest.cc>
Martin Matuska <mm@FreeBSD.org> Martin Matuska <mm@FreeBSD.org>
Martin Rüegg <martin.rueegg@metaworx.ch> Martin Rüegg <martin.rueegg@metaworx.ch>
Martin Wagner <martin.wagner.dev@gmail.com>
Massimo Maggi <me@massimo-maggi.eu> Massimo Maggi <me@massimo-maggi.eu>
Mateusz Guzik <mjguzik@gmail.com> Mateusz Guzik <mjguzik@gmail.com>
Mateusz Piotrowski <0mp@FreeBSD.org> Mateusz Piotrowski <0mp@FreeBSD.org>
@ -430,7 +405,6 @@ CONTRIBUTORS:
Matus Kral <matuskral@me.com> Matus Kral <matuskral@me.com>
Mauricio Faria de Oliveira <mfo@canonical.com> Mauricio Faria de Oliveira <mfo@canonical.com>
Max Grossman <max.grossman@delphix.com> Max Grossman <max.grossman@delphix.com>
Maxim Filimonov <che@bein.link>
Maximilian Mehnert <maximilian.mehnert@gmx.de> Maximilian Mehnert <maximilian.mehnert@gmx.de>
Max Zettlmeißl <max@zettlmeissl.de> Max Zettlmeißl <max@zettlmeissl.de>
Md Islam <mdnahian@outlook.com> Md Islam <mdnahian@outlook.com>
@ -443,7 +417,6 @@ CONTRIBUTORS:
Michael Niewöhner <foss@mniewoehner.de> Michael Niewöhner <foss@mniewoehner.de>
Michael Zhivich <mzhivich@akamai.com> Michael Zhivich <mzhivich@akamai.com>
Michal Vasilek <michal@vasilek.cz> Michal Vasilek <michal@vasilek.cz>
MigeljanImeri <ImeriMigel@gmail.com>
Mike Gerdts <mike.gerdts@joyent.com> Mike Gerdts <mike.gerdts@joyent.com>
Mike Harsch <mike@harschsystems.com> Mike Harsch <mike@harschsystems.com>
Mike Leddy <mike.leddy@gmail.com> Mike Leddy <mike.leddy@gmail.com>
@ -475,7 +448,6 @@ CONTRIBUTORS:
Olaf Faaland <faaland1@llnl.gov> Olaf Faaland <faaland1@llnl.gov>
Oleg Drokin <green@linuxhacker.ru> Oleg Drokin <green@linuxhacker.ru>
Oleg Stepura <oleg@stepura.com> Oleg Stepura <oleg@stepura.com>
Olivier Certner <olce.freebsd@certner.fr>
Olivier Mazouffre <olivier.mazouffre@ims-bordeaux.fr> Olivier Mazouffre <olivier.mazouffre@ims-bordeaux.fr>
omni <omni+vagant@hack.org> omni <omni+vagant@hack.org>
Orivej Desh <orivej@gmx.fr> Orivej Desh <orivej@gmx.fr>
@ -494,7 +466,6 @@ CONTRIBUTORS:
Peng <peng.hse@xtaotech.com> Peng <peng.hse@xtaotech.com>
Peter Ashford <ashford@accs.com> Peter Ashford <ashford@accs.com>
Peter Dave Hello <hsu@peterdavehello.org> Peter Dave Hello <hsu@peterdavehello.org>
Peter Doherty <peterd@acranox.org>
Peter Levine <plevine457@gmail.com> Peter Levine <plevine457@gmail.com>
Peter Wirdemo <peter.wirdemo@gmail.com> Peter Wirdemo <peter.wirdemo@gmail.com>
Petros Koutoupis <petros@petroskoutoupis.com> Petros Koutoupis <petros@petroskoutoupis.com>
@ -508,8 +479,6 @@ CONTRIBUTORS:
Prasad Joshi <prasadjoshi124@gmail.com> Prasad Joshi <prasadjoshi124@gmail.com>
privb0x23 <privb0x23@users.noreply.github.com> privb0x23 <privb0x23@users.noreply.github.com>
P.SCH <p88@yahoo.com> P.SCH <p88@yahoo.com>
Qiuhao Chen <chenqiuhao1997@gmail.com>
Quartz <yyhran@163.com>
Quentin Zdanis <zdanisq@gmail.com> Quentin Zdanis <zdanisq@gmail.com>
Rafael Kitover <rkitover@gmail.com> Rafael Kitover <rkitover@gmail.com>
RageLtMan <sempervictus@users.noreply.github.com> RageLtMan <sempervictus@users.noreply.github.com>
@ -522,15 +491,11 @@ CONTRIBUTORS:
Riccardo Schirone <rschirone91@gmail.com> Riccardo Schirone <rschirone91@gmail.com>
Richard Allen <belperite@gmail.com> Richard Allen <belperite@gmail.com>
Richard Elling <Richard.Elling@RichardElling.com> Richard Elling <Richard.Elling@RichardElling.com>
Richard Kojedzinszky <richard@kojedz.in>
Richard Laager <rlaager@wiktel.com> Richard Laager <rlaager@wiktel.com>
Richard Lowe <richlowe@richlowe.net> Richard Lowe <richlowe@richlowe.net>
Richard Sharpe <rsharpe@samba.org> Richard Sharpe <rsharpe@samba.org>
Richard Yao <ryao@gentoo.org> Richard Yao <ryao@gentoo.org>
Rich Ercolani <rincebrain@gmail.com> Rich Ercolani <rincebrain@gmail.com>
Rick Macklem <rmacklem@uoguelph.ca>
rilysh <nightquick@proton.me>
Robert Evans <evansr@google.com>
Robert Novak <sailnfool@gmail.com> Robert Novak <sailnfool@gmail.com>
Roberto Ricci <ricci@disroot.org> Roberto Ricci <ricci@disroot.org>
Rob Norris <robn@despairlabs.com> Rob Norris <robn@despairlabs.com>
@ -540,14 +505,11 @@ CONTRIBUTORS:
Roman Strashkin <roman.strashkin@nexenta.com> Roman Strashkin <roman.strashkin@nexenta.com>
Ross Williams <ross@ross-williams.net> Ross Williams <ross@ross-williams.net>
Ruben Kerkhof <ruben@rubenkerkhof.com> Ruben Kerkhof <ruben@rubenkerkhof.com>
Ryan <errornointernet@envs.net>
Ryan Hirasaki <ryanhirasaki@gmail.com> Ryan Hirasaki <ryanhirasaki@gmail.com>
Ryan Lahfa <masterancpp@gmail.com> Ryan Lahfa <masterancpp@gmail.com>
Ryan Libby <rlibby@FreeBSD.org> Ryan Libby <rlibby@FreeBSD.org>
Ryan Moeller <freqlabs@FreeBSD.org> Ryan Moeller <freqlabs@FreeBSD.org>
Sam Atkinson <samatk@amazon.com>
Sam Hathaway <github.com@munkynet.org> Sam Hathaway <github.com@munkynet.org>
Sam James <sam@gentoo.org>
Sam Lunt <samuel.j.lunt@gmail.com> Sam Lunt <samuel.j.lunt@gmail.com>
Samuel VERSCHELDE <stormi-github@ylix.fr> Samuel VERSCHELDE <stormi-github@ylix.fr>
Samuel Wycliffe <samuelwycliffe@gmail.com> Samuel Wycliffe <samuelwycliffe@gmail.com>
@ -565,12 +527,9 @@ CONTRIBUTORS:
Sen Haerens <sen@senhaerens.be> Sen Haerens <sen@senhaerens.be>
Serapheim Dimitropoulos <serapheim@delphix.com> Serapheim Dimitropoulos <serapheim@delphix.com>
Seth Forshee <seth.forshee@canonical.com> Seth Forshee <seth.forshee@canonical.com>
Seth Troisi <sethtroisi@google.com>
Shaan Nobee <sniper111@gmail.com> Shaan Nobee <sniper111@gmail.com>
Shampavman <sham.pavman@nexenta.com> Shampavman <sham.pavman@nexenta.com>
Shaun Tancheff <shaun@aeonazure.com> Shaun Tancheff <shaun@aeonazure.com>
Shawn Bayern <sbayern@law.fsu.edu>
Shengqi Chen <harry-chen@outlook.com>
Shen Yan <shenyanxxxy@qq.com> Shen Yan <shenyanxxxy@qq.com>
Simon Guest <simon.guest@tesujimath.org> Simon Guest <simon.guest@tesujimath.org>
Simon Klinkert <simon.klinkert@gmail.com> Simon Klinkert <simon.klinkert@gmail.com>
@ -578,7 +537,6 @@ CONTRIBUTORS:
Spencer Kinny <spencerkinny1995@gmail.com> Spencer Kinny <spencerkinny1995@gmail.com>
Srikanth N S <srikanth.nagasubbaraoseetharaman@hpe.com> Srikanth N S <srikanth.nagasubbaraoseetharaman@hpe.com>
Stanislav Seletskiy <s.seletskiy@gmail.com> Stanislav Seletskiy <s.seletskiy@gmail.com>
Stefan Lendl <s.lendl@proxmox.com>
Steffen Müthing <steffen.muething@iwr.uni-heidelberg.de> Steffen Müthing <steffen.muething@iwr.uni-heidelberg.de>
Stephen Blinick <stephen.blinick@delphix.com> Stephen Blinick <stephen.blinick@delphix.com>
sterlingjensen <sterlingjensen@users.noreply.github.com> sterlingjensen <sterlingjensen@users.noreply.github.com>
@ -599,7 +557,6 @@ CONTRIBUTORS:
Teodor Spæren <teodor_spaeren@riseup.net> Teodor Spæren <teodor_spaeren@riseup.net>
TerraTech <TerraTech@users.noreply.github.com> TerraTech <TerraTech@users.noreply.github.com>
Thijs Cramer <thijs.cramer@gmail.com> Thijs Cramer <thijs.cramer@gmail.com>
Thomas Bertschinger <bertschinger@lanl.gov>
Thomas Geppert <geppi@digitx.de> Thomas Geppert <geppi@digitx.de>
Thomas Lamprecht <guggentom@hotmail.de> Thomas Lamprecht <guggentom@hotmail.de>
Till Maas <opensource@till.name> Till Maas <opensource@till.name>
@ -612,7 +569,6 @@ CONTRIBUTORS:
Tim Schumacher <timschumi@gmx.de> Tim Schumacher <timschumi@gmx.de>
Tino Reichardt <milky-zfs@mcmilk.de> Tino Reichardt <milky-zfs@mcmilk.de>
Tobin Harding <me@tobin.cc> Tobin Harding <me@tobin.cc>
Todd Seidelmann <seidelma@users.noreply.github.com>
Tom Caputi <tcaputi@datto.com> Tom Caputi <tcaputi@datto.com>
Tom Matthews <tom@axiom-partners.com> Tom Matthews <tom@axiom-partners.com>
Tomohiro Kusumi <kusumi.tomohiro@gmail.com> Tomohiro Kusumi <kusumi.tomohiro@gmail.com>
@ -630,7 +586,6 @@ CONTRIBUTORS:
Turbo Fredriksson <turbo@bayour.com> Turbo Fredriksson <turbo@bayour.com>
Tyler J. Stachecki <stachecki.tyler@gmail.com> Tyler J. Stachecki <stachecki.tyler@gmail.com>
Umer Saleem <usaleem@ixsystems.com> Umer Saleem <usaleem@ixsystems.com>
Vaibhav Bhanawat <vaibhav.bhanawat@delphix.com>
Valmiky Arquissandas <kayvlim@gmail.com> Valmiky Arquissandas <kayvlim@gmail.com>
Val Packett <val@packett.cool> Val Packett <val@packett.cool>
Vince van Oosten <techhazard@codeforyouand.me> Vince van Oosten <techhazard@codeforyouand.me>
@ -659,13 +614,10 @@ CONTRIBUTORS:
yuina822 <ayuichi@club.kyutech.ac.jp> yuina822 <ayuichi@club.kyutech.ac.jp>
YunQiang Su <syq@debian.org> YunQiang Su <syq@debian.org>
Yuri Pankov <yuri.pankov@gmail.com> Yuri Pankov <yuri.pankov@gmail.com>
Yuxin Wang <yuxinwang9999@gmail.com>
Yuxuan Shui <yshuiv7@gmail.com> Yuxuan Shui <yshuiv7@gmail.com>
Zachary Bedell <zac@thebedells.org> Zachary Bedell <zac@thebedells.org>
Zach Dykstra <dykstra.zachary@gmail.com> Zach Dykstra <dykstra.zachary@gmail.com>
zgock <zgock@nuc.base.zgock-lab.net> zgock <zgock@nuc.base.zgock-lab.net>
Zhao Yongming <zym@apache.org>
Zhenlei Huang <zlei@FreeBSD.org>
Zhu Chuang <chuang@melty.land> Zhu Chuang <chuang@melty.land>
Érico Nogueira <erico.erc@gmail.com> Érico Nogueira <erico.erc@gmail.com>
Đoàn Trần Công Danh <congdanhqx@gmail.com> Đoàn Trần Công Danh <congdanhqx@gmail.com>

2
META
View File

@ -6,5 +6,5 @@ Release: 1
Release-Tags: relext Release-Tags: relext
License: CDDL License: CDDL
Author: OpenZFS Author: OpenZFS
Linux-Maximum: 6.10 Linux-Maximum: 6.5
Linux-Minimum: 3.10 Linux-Minimum: 3.10

View File

@ -32,4 +32,4 @@ For more details see the NOTICE, LICENSE and COPYRIGHT files; `UCRL-CODE-235197`
# Supported Kernels # Supported Kernels
* The `META` file contains the officially recognized supported Linux kernel versions. * The `META` file contains the officially recognized supported Linux kernel versions.
* Supported FreeBSD versions are any supported branches and releases starting from 13.0-RELEASE. * Supported FreeBSD versions are any supported branches and releases starting from 12.2-RELEASE.

View File

@ -24,7 +24,7 @@ zfs_ids_to_path_LDADD = \
libzfs.la libzfs.la
zhack_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS) zhack_CPPFLAGS = $(AM_CPPFLAGS) $(FORCEDEBUG_CPPFLAGS)
sbin_PROGRAMS += zhack sbin_PROGRAMS += zhack
CPPCHECKTARGETS += zhack CPPCHECKTARGETS += zhack
@ -39,7 +39,9 @@ zhack_LDADD = \
ztest_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS) ztest_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS)
ztest_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS) # Get rid of compiler warning for unchecked truncating snprintfs on gcc 7.1.1
ztest_CFLAGS += $(NO_FORMAT_TRUNCATION)
ztest_CPPFLAGS = $(AM_CPPFLAGS) $(FORCEDEBUG_CPPFLAGS)
sbin_PROGRAMS += ztest sbin_PROGRAMS += ztest
CPPCHECKTARGETS += ztest CPPCHECKTARGETS += ztest

View File

@ -260,34 +260,33 @@ def draw_graph(kstats_dict):
arc_stats = isolate_section('arcstats', kstats_dict) arc_stats = isolate_section('arcstats', kstats_dict)
GRAPH_INDENT = ' '*4 GRAPH_INDENT = ' '*4
GRAPH_WIDTH = 70 GRAPH_WIDTH = 60
arc_max = int(arc_stats['c_max'])
arc_size = f_bytes(arc_stats['size']) arc_size = f_bytes(arc_stats['size'])
arc_perc = f_perc(arc_stats['size'], arc_max) arc_perc = f_perc(arc_stats['size'], arc_stats['c_max'])
data_size = f_bytes(arc_stats['data_size']) mfu_size = f_bytes(arc_stats['mfu_size'])
meta_size = f_bytes(arc_stats['metadata_size']) mru_size = f_bytes(arc_stats['mru_size'])
meta_size = f_bytes(arc_stats['arc_meta_used'])
dnode_limit = f_bytes(arc_stats['arc_dnode_limit'])
dnode_size = f_bytes(arc_stats['dnode_size']) dnode_size = f_bytes(arc_stats['dnode_size'])
info_form = ('ARC: {0} ({1}) Data: {2} Meta: {3} Dnode: {4}') info_form = ('ARC: {0} ({1}) MFU: {2} MRU: {3} META: {4} '
info_line = info_form.format(arc_size, arc_perc, data_size, meta_size, 'DNODE {5} ({6})')
dnode_size) info_line = info_form.format(arc_size, arc_perc, mfu_size, mru_size,
meta_size, dnode_size, dnode_limit)
info_spc = ' '*int((GRAPH_WIDTH-len(info_line))/2) info_spc = ' '*int((GRAPH_WIDTH-len(info_line))/2)
info_line = GRAPH_INDENT+info_spc+info_line info_line = GRAPH_INDENT+info_spc+info_line
graph_line = GRAPH_INDENT+'+'+('-'*(GRAPH_WIDTH-2))+'+' graph_line = GRAPH_INDENT+'+'+('-'*(GRAPH_WIDTH-2))+'+'
arc_perc = float(int(arc_stats['size'])/arc_max) mfu_perc = float(int(arc_stats['mfu_size'])/int(arc_stats['c_max']))
data_perc = float(int(arc_stats['data_size'])/arc_max) mru_perc = float(int(arc_stats['mru_size'])/int(arc_stats['c_max']))
meta_perc = float(int(arc_stats['metadata_size'])/arc_max) arc_perc = float(int(arc_stats['size'])/int(arc_stats['c_max']))
dnode_perc = float(int(arc_stats['dnode_size'])/arc_max)
total_ticks = float(arc_perc)*GRAPH_WIDTH total_ticks = float(arc_perc)*GRAPH_WIDTH
data_ticks = data_perc*GRAPH_WIDTH mfu_ticks = mfu_perc*GRAPH_WIDTH
meta_ticks = meta_perc*GRAPH_WIDTH mru_ticks = mru_perc*GRAPH_WIDTH
dnode_ticks = dnode_perc*GRAPH_WIDTH other_ticks = total_ticks-(mfu_ticks+mru_ticks)
other_ticks = total_ticks-(data_ticks+meta_ticks+dnode_ticks)
core_form = 'D'*int(data_ticks)+'M'*int(meta_ticks)+'N'*int(dnode_ticks)+\ core_form = 'F'*int(mfu_ticks)+'R'*int(mru_ticks)+'O'*int(other_ticks)
'O'*int(other_ticks)
core_spc = ' '*(GRAPH_WIDTH-(2+len(core_form))) core_spc = ' '*(GRAPH_WIDTH-(2+len(core_form)))
core_line = GRAPH_INDENT+'|'+core_form+core_spc+'|' core_line = GRAPH_INDENT+'|'+core_form+core_spc+'|'
@ -537,87 +536,56 @@ def section_arc(kstats_dict):
arc_stats = isolate_section('arcstats', kstats_dict) arc_stats = isolate_section('arcstats', kstats_dict)
memory_all = arc_stats['memory_all_bytes'] throttle = arc_stats['memory_throttle_count']
memory_free = arc_stats['memory_free_bytes']
memory_avail = arc_stats['memory_available_bytes'] if throttle == '0':
health = 'HEALTHY'
else:
health = 'THROTTLED'
prt_1('ARC status:', health)
prt_i1('Memory throttle count:', throttle)
print()
arc_size = arc_stats['size'] arc_size = arc_stats['size']
arc_target_size = arc_stats['c'] arc_target_size = arc_stats['c']
arc_max = arc_stats['c_max'] arc_max = arc_stats['c_max']
arc_min = arc_stats['c_min'] arc_min = arc_stats['c_min']
dnode_limit = arc_stats['arc_dnode_limit']
print('ARC status:')
prt_i1('Total memory size:', f_bytes(memory_all))
prt_i2('Min target size:', f_perc(arc_min, memory_all), f_bytes(arc_min))
prt_i2('Max target size:', f_perc(arc_max, memory_all), f_bytes(arc_max))
prt_i2('Target size (adaptive):',
f_perc(arc_size, arc_max), f_bytes(arc_target_size))
prt_i2('Current size:', f_perc(arc_size, arc_max), f_bytes(arc_size))
prt_i1('Free memory size:', f_bytes(memory_free))
prt_i1('Available memory size:', f_bytes(memory_avail))
print()
compressed_size = arc_stats['compressed_size']
overhead_size = arc_stats['overhead_size']
bonus_size = arc_stats['bonus_size']
dnode_size = arc_stats['dnode_size']
dbuf_size = arc_stats['dbuf_size']
hdr_size = arc_stats['hdr_size']
l2_hdr_size = arc_stats['l2_hdr_size']
abd_chunk_waste_size = arc_stats['abd_chunk_waste_size']
prt_1('ARC structal breakdown (current size):', f_bytes(arc_size))
prt_i2('Compressed size:',
f_perc(compressed_size, arc_size), f_bytes(compressed_size))
prt_i2('Overhead size:',
f_perc(overhead_size, arc_size), f_bytes(overhead_size))
prt_i2('Bonus size:',
f_perc(bonus_size, arc_size), f_bytes(bonus_size))
prt_i2('Dnode size:',
f_perc(dnode_size, arc_size), f_bytes(dnode_size))
prt_i2('Dbuf size:',
f_perc(dbuf_size, arc_size), f_bytes(dbuf_size))
prt_i2('Header size:',
f_perc(hdr_size, arc_size), f_bytes(hdr_size))
prt_i2('L2 header size:',
f_perc(l2_hdr_size, arc_size), f_bytes(l2_hdr_size))
prt_i2('ABD chunk waste size:',
f_perc(abd_chunk_waste_size, arc_size), f_bytes(abd_chunk_waste_size))
print()
meta = arc_stats['meta'] meta = arc_stats['meta']
pd = arc_stats['pd'] pd = arc_stats['pd']
pm = arc_stats['pm'] pm = arc_stats['pm']
data_size = arc_stats['data_size']
metadata_size = arc_stats['metadata_size']
anon_data = arc_stats['anon_data'] anon_data = arc_stats['anon_data']
anon_metadata = arc_stats['anon_metadata'] anon_metadata = arc_stats['anon_metadata']
mfu_data = arc_stats['mfu_data'] mfu_data = arc_stats['mfu_data']
mfu_metadata = arc_stats['mfu_metadata'] mfu_metadata = arc_stats['mfu_metadata']
mfu_edata = arc_stats['mfu_evictable_data']
mfu_emetadata = arc_stats['mfu_evictable_metadata']
mru_data = arc_stats['mru_data'] mru_data = arc_stats['mru_data']
mru_metadata = arc_stats['mru_metadata'] mru_metadata = arc_stats['mru_metadata']
mru_edata = arc_stats['mru_evictable_data']
mru_emetadata = arc_stats['mru_evictable_metadata']
mfug_data = arc_stats['mfu_ghost_data'] mfug_data = arc_stats['mfu_ghost_data']
mfug_metadata = arc_stats['mfu_ghost_metadata'] mfug_metadata = arc_stats['mfu_ghost_metadata']
mrug_data = arc_stats['mru_ghost_data'] mrug_data = arc_stats['mru_ghost_data']
mrug_metadata = arc_stats['mru_ghost_metadata'] mrug_metadata = arc_stats['mru_ghost_metadata']
unc_data = arc_stats['uncached_data'] unc_data = arc_stats['uncached_data']
unc_metadata = arc_stats['uncached_metadata'] unc_metadata = arc_stats['uncached_metadata']
bonus_size = arc_stats['bonus_size']
dnode_limit = arc_stats['arc_dnode_limit']
dnode_size = arc_stats['dnode_size']
dbuf_size = arc_stats['dbuf_size']
hdr_size = arc_stats['hdr_size']
l2_hdr_size = arc_stats['l2_hdr_size']
abd_chunk_waste_size = arc_stats['abd_chunk_waste_size']
target_size_ratio = '{0}:1'.format(int(arc_max) // int(arc_min))
prt_2('ARC size (current):',
f_perc(arc_size, arc_max), f_bytes(arc_size))
prt_i2('Target size (adaptive):',
f_perc(arc_target_size, arc_max), f_bytes(arc_target_size))
prt_i2('Min size (hard limit):',
f_perc(arc_min, arc_max), f_bytes(arc_min))
prt_i2('Max size (high water):',
target_size_ratio, f_bytes(arc_max))
caches_size = int(anon_data)+int(anon_metadata)+\ caches_size = int(anon_data)+int(anon_metadata)+\
int(mfu_data)+int(mfu_metadata)+int(mru_data)+int(mru_metadata)+\ int(mfu_data)+int(mfu_metadata)+int(mru_data)+int(mru_metadata)+\
int(unc_data)+int(unc_metadata) int(unc_data)+int(unc_metadata)
prt_1('ARC types breakdown (compressed + overhead):', f_bytes(caches_size))
prt_i2('Data size:',
f_perc(data_size, caches_size), f_bytes(data_size))
prt_i2('Metadata size:',
f_perc(metadata_size, caches_size), f_bytes(metadata_size))
print()
prt_1('ARC states breakdown (compressed + overhead):', f_bytes(caches_size))
prt_i2('Anonymous data size:', prt_i2('Anonymous data size:',
f_perc(anon_data, caches_size), f_bytes(anon_data)) f_perc(anon_data, caches_size), f_bytes(anon_data))
prt_i2('Anonymous metadata size:', prt_i2('Anonymous metadata size:',
@ -628,37 +596,43 @@ def section_arc(kstats_dict):
f_bytes(v / 65536 * caches_size / 65536)) f_bytes(v / 65536 * caches_size / 65536))
prt_i2('MFU data size:', prt_i2('MFU data size:',
f_perc(mfu_data, caches_size), f_bytes(mfu_data)) f_perc(mfu_data, caches_size), f_bytes(mfu_data))
prt_i2('MFU evictable data size:',
f_perc(mfu_edata, caches_size), f_bytes(mfu_edata))
prt_i1('MFU ghost data size:', f_bytes(mfug_data)) prt_i1('MFU ghost data size:', f_bytes(mfug_data))
v = (s-int(pm))*int(meta)/s v = (s-int(pm))*int(meta)/s
prt_i2('MFU metadata target:', f_perc(v, s), prt_i2('MFU metadata target:', f_perc(v, s),
f_bytes(v / 65536 * caches_size / 65536)) f_bytes(v / 65536 * caches_size / 65536))
prt_i2('MFU metadata size:', prt_i2('MFU metadata size:',
f_perc(mfu_metadata, caches_size), f_bytes(mfu_metadata)) f_perc(mfu_metadata, caches_size), f_bytes(mfu_metadata))
prt_i2('MFU evictable metadata size:',
f_perc(mfu_emetadata, caches_size), f_bytes(mfu_emetadata))
prt_i1('MFU ghost metadata size:', f_bytes(mfug_metadata)) prt_i1('MFU ghost metadata size:', f_bytes(mfug_metadata))
v = int(pd)*(s-int(meta))/s v = int(pd)*(s-int(meta))/s
prt_i2('MRU data target:', f_perc(v, s), prt_i2('MRU data target:', f_perc(v, s),
f_bytes(v / 65536 * caches_size / 65536)) f_bytes(v / 65536 * caches_size / 65536))
prt_i2('MRU data size:', prt_i2('MRU data size:',
f_perc(mru_data, caches_size), f_bytes(mru_data)) f_perc(mru_data, caches_size), f_bytes(mru_data))
prt_i2('MRU evictable data size:',
f_perc(mru_edata, caches_size), f_bytes(mru_edata))
prt_i1('MRU ghost data size:', f_bytes(mrug_data)) prt_i1('MRU ghost data size:', f_bytes(mrug_data))
v = int(pm)*int(meta)/s v = int(pm)*int(meta)/s
prt_i2('MRU metadata target:', f_perc(v, s), prt_i2('MRU metadata target:', f_perc(v, s),
f_bytes(v / 65536 * caches_size / 65536)) f_bytes(v / 65536 * caches_size / 65536))
prt_i2('MRU metadata size:', prt_i2('MRU metadata size:',
f_perc(mru_metadata, caches_size), f_bytes(mru_metadata)) f_perc(mru_metadata, caches_size), f_bytes(mru_metadata))
prt_i2('MRU evictable metadata size:',
f_perc(mru_emetadata, caches_size), f_bytes(mru_emetadata))
prt_i1('MRU ghost metadata size:', f_bytes(mrug_metadata)) prt_i1('MRU ghost metadata size:', f_bytes(mrug_metadata))
prt_i2('Uncached data size:', prt_i2('Uncached data size:',
f_perc(unc_data, caches_size), f_bytes(unc_data)) f_perc(unc_data, caches_size), f_bytes(unc_data))
prt_i2('Uncached metadata size:', prt_i2('Uncached metadata size:',
f_perc(unc_metadata, caches_size), f_bytes(unc_metadata)) f_perc(unc_metadata, caches_size), f_bytes(unc_metadata))
prt_i2('Bonus size:',
f_perc(bonus_size, arc_size), f_bytes(bonus_size))
prt_i2('Dnode cache target:',
f_perc(dnode_limit, arc_max), f_bytes(dnode_limit))
prt_i2('Dnode cache size:',
f_perc(dnode_size, dnode_limit), f_bytes(dnode_size))
prt_i2('Dbuf size:',
f_perc(dbuf_size, arc_size), f_bytes(dbuf_size))
prt_i2('Header size:',
f_perc(hdr_size, arc_size), f_bytes(hdr_size))
prt_i2('L2 header size:',
f_perc(l2_hdr_size, arc_size), f_bytes(l2_hdr_size))
prt_i2('ABD chunk waste size:',
f_perc(abd_chunk_waste_size, arc_size), f_bytes(abd_chunk_waste_size))
print() print()
print('ARC hash breakdown:') print('ARC hash breakdown:')
@ -673,9 +647,6 @@ def section_arc(kstats_dict):
print() print()
print('ARC misc:') print('ARC misc:')
prt_i1('Memory throttles:', arc_stats['memory_throttle_count'])
prt_i1('Memory direct reclaims:', arc_stats['memory_direct_count'])
prt_i1('Memory indirect reclaims:', arc_stats['memory_indirect_count'])
prt_i1('Deleted:', f_hits(arc_stats['deleted'])) prt_i1('Deleted:', f_hits(arc_stats['deleted']))
prt_i1('Mutex misses:', f_hits(arc_stats['mutex_miss'])) prt_i1('Mutex misses:', f_hits(arc_stats['mutex_miss']))
prt_i1('Eviction skips:', f_hits(arc_stats['evict_skip'])) prt_i1('Eviction skips:', f_hits(arc_stats['evict_skip']))
@ -740,7 +711,7 @@ def section_archits(kstats_dict):
pd_total = int(arc_stats['prefetch_data_hits']) +\ pd_total = int(arc_stats['prefetch_data_hits']) +\
int(arc_stats['prefetch_data_iohits']) +\ int(arc_stats['prefetch_data_iohits']) +\
int(arc_stats['prefetch_data_misses']) int(arc_stats['prefetch_data_misses'])
prt_2('ARC prefetch data accesses:', f_perc(pd_total, all_accesses), prt_2('ARC prefetch metadata accesses:', f_perc(pd_total, all_accesses),
f_hits(pd_total)) f_hits(pd_total))
pd_todo = (('Prefetch data hits:', arc_stats['prefetch_data_hits']), pd_todo = (('Prefetch data hits:', arc_stats['prefetch_data_hits']),
('Prefetch data I/O hits:', arc_stats['prefetch_data_iohits']), ('Prefetch data I/O hits:', arc_stats['prefetch_data_iohits']),
@ -822,27 +793,18 @@ def section_dmu(kstats_dict):
zfetch_stats = isolate_section('zfetchstats', kstats_dict) zfetch_stats = isolate_section('zfetchstats', kstats_dict)
zfetch_access_total = int(zfetch_stats['hits']) +\ zfetch_access_total = int(zfetch_stats['hits'])+int(zfetch_stats['misses'])
int(zfetch_stats['future']) + int(zfetch_stats['stride']) +\
int(zfetch_stats['past']) + int(zfetch_stats['misses'])
prt_1('DMU predictive prefetcher calls:', f_hits(zfetch_access_total)) prt_1('DMU predictive prefetcher calls:', f_hits(zfetch_access_total))
prt_i2('Stream hits:', prt_i2('Stream hits:',
f_perc(zfetch_stats['hits'], zfetch_access_total), f_perc(zfetch_stats['hits'], zfetch_access_total),
f_hits(zfetch_stats['hits'])) f_hits(zfetch_stats['hits']))
future = int(zfetch_stats['future']) + int(zfetch_stats['stride'])
prt_i2('Hits ahead of stream:', f_perc(future, zfetch_access_total),
f_hits(future))
prt_i2('Hits behind stream:',
f_perc(zfetch_stats['past'], zfetch_access_total),
f_hits(zfetch_stats['past']))
prt_i2('Stream misses:', prt_i2('Stream misses:',
f_perc(zfetch_stats['misses'], zfetch_access_total), f_perc(zfetch_stats['misses'], zfetch_access_total),
f_hits(zfetch_stats['misses'])) f_hits(zfetch_stats['misses']))
prt_i2('Streams limit reached:', prt_i2('Streams limit reached:',
f_perc(zfetch_stats['max_streams'], zfetch_stats['misses']), f_perc(zfetch_stats['max_streams'], zfetch_stats['misses']),
f_hits(zfetch_stats['max_streams'])) f_hits(zfetch_stats['max_streams']))
prt_i1('Stream strides:', f_hits(zfetch_stats['stride']))
prt_i1('Prefetches issued', f_hits(zfetch_stats['io_issued'])) prt_i1('Prefetches issued', f_hits(zfetch_stats['io_issued']))
print() print()

View File

@ -157,16 +157,6 @@ cols = {
"free": [5, 1024, "ARC free memory"], "free": [5, 1024, "ARC free memory"],
"avail": [5, 1024, "ARC available memory"], "avail": [5, 1024, "ARC available memory"],
"waste": [5, 1024, "Wasted memory due to round up to pagesize"], "waste": [5, 1024, "Wasted memory due to round up to pagesize"],
"ztotal": [6, 1000, "zfetch total prefetcher calls per second"],
"zhits": [5, 1000, "zfetch stream hits per second"],
"zahead": [6, 1000, "zfetch hits ahead of streams per second"],
"zpast": [5, 1000, "zfetch hits behind streams per second"],
"zmisses": [7, 1000, "zfetch stream misses per second"],
"zmax": [4, 1000, "zfetch limit reached per second"],
"zfuture": [7, 1000, "zfetch stream future per second"],
"zstride": [7, 1000, "zfetch stream strides per second"],
"zissued": [7, 1000, "zfetch prefetches issued per second"],
"zactive": [7, 1000, "zfetch prefetches active per second"],
} }
v = {} v = {}
@ -174,8 +164,6 @@ hdr = ["time", "read", "ddread", "ddh%", "dmread", "dmh%", "pread", "ph%",
"size", "c", "avail"] "size", "c", "avail"]
xhdr = ["time", "mfu", "mru", "mfug", "mrug", "unc", "eskip", "mtxmis", xhdr = ["time", "mfu", "mru", "mfug", "mrug", "unc", "eskip", "mtxmis",
"dread", "pread", "read"] "dread", "pread", "read"]
zhdr = ["time", "ztotal", "zhits", "zahead", "zpast", "zmisses", "zmax",
"zfuture", "zstride", "zissued", "zactive"]
sint = 1 # Default interval is 1 second sint = 1 # Default interval is 1 second
count = 1 # Default count is 1 count = 1 # Default count is 1
hdr_intr = 20 # Print header every 20 lines of output hdr_intr = 20 # Print header every 20 lines of output
@ -200,8 +188,6 @@ if sys.platform.startswith('freebsd'):
k = [ctl for ctl in sysctl.filter('kstat.zfs.misc.arcstats') k = [ctl for ctl in sysctl.filter('kstat.zfs.misc.arcstats')
if ctl.type != sysctl.CTLTYPE_NODE] if ctl.type != sysctl.CTLTYPE_NODE]
k += [ctl for ctl in sysctl.filter('kstat.zfs.misc.zfetchstats')
if ctl.type != sysctl.CTLTYPE_NODE]
if not k: if not k:
sys.exit(1) sys.exit(1)
@ -213,28 +199,19 @@ if sys.platform.startswith('freebsd'):
continue continue
name, value = s.name, s.value name, value = s.name, s.value
# Trims 'kstat.zfs.misc.arcstats' from the name
if "arcstats" in name: kstat[name[24:]] = int(value)
# Trims 'kstat.zfs.misc.arcstats' from the name
kstat[name[24:]] = int(value)
else:
kstat["zfetch_" + name[27:]] = int(value)
elif sys.platform.startswith('linux'): elif sys.platform.startswith('linux'):
def kstat_update(): def kstat_update():
global kstat global kstat
k1 = [line.strip() for line in open('/proc/spl/kstat/zfs/arcstats')] k = [line.strip() for line in open('/proc/spl/kstat/zfs/arcstats')]
k2 = ["zfetch_" + line.strip() for line in if not k:
open('/proc/spl/kstat/zfs/zfetchstats')]
if k1 is None or k2 is None:
sys.exit(1) sys.exit(1)
del k1[0:2] del k[0:2]
del k2[0:2]
k = k1 + k2
kstat = {} kstat = {}
for s in k: for s in k:
@ -262,7 +239,6 @@ def usage():
sys.stderr.write("\t -v : List all possible field headers and definitions" sys.stderr.write("\t -v : List all possible field headers and definitions"
"\n") "\n")
sys.stderr.write("\t -x : Print extended stats\n") sys.stderr.write("\t -x : Print extended stats\n")
sys.stderr.write("\t -z : Print zfetch stats\n")
sys.stderr.write("\t -f : Specify specific fields to print (see -v)\n") sys.stderr.write("\t -f : Specify specific fields to print (see -v)\n")
sys.stderr.write("\t -o : Redirect output to the specified file\n") sys.stderr.write("\t -o : Redirect output to the specified file\n")
sys.stderr.write("\t -s : Override default field separator with custom " sys.stderr.write("\t -s : Override default field separator with custom "
@ -381,7 +357,6 @@ def init():
global count global count
global hdr global hdr
global xhdr global xhdr
global zhdr
global opfile global opfile
global sep global sep
global out global out
@ -393,17 +368,15 @@ def init():
xflag = False xflag = False
hflag = False hflag = False
vflag = False vflag = False
zflag = False
i = 1 i = 1
try: try:
opts, args = getopt.getopt( opts, args = getopt.getopt(
sys.argv[1:], sys.argv[1:],
"axzo:hvs:f:p", "axo:hvs:f:p",
[ [
"all", "all",
"extended", "extended",
"zfetch",
"outfile", "outfile",
"help", "help",
"verbose", "verbose",
@ -437,15 +410,13 @@ def init():
i += 1 i += 1
if opt in ('-p', '--parsable'): if opt in ('-p', '--parsable'):
pretty_print = False pretty_print = False
if opt in ('-z', '--zfetch'):
zflag = True
i += 1 i += 1
argv = sys.argv[i:] argv = sys.argv[i:]
sint = int(argv[0]) if argv else sint sint = int(argv[0]) if argv else sint
count = int(argv[1]) if len(argv) > 1 else (0 if len(argv) > 0 else 1) count = int(argv[1]) if len(argv) > 1 else (0 if len(argv) > 0 else 1)
if hflag or (xflag and zflag) or ((zflag or xflag) and desired_cols): if hflag or (xflag and desired_cols):
usage() usage()
if vflag: if vflag:
@ -454,9 +425,6 @@ def init():
if xflag: if xflag:
hdr = xhdr hdr = xhdr
if zflag:
hdr = zhdr
update_hdr_intr() update_hdr_intr()
# check if L2ARC exists # check if L2ARC exists
@ -601,17 +569,6 @@ def calculate():
v["el2mru"] = d["evict_l2_eligible_mru"] // sint v["el2mru"] = d["evict_l2_eligible_mru"] // sint
v["el2inel"] = d["evict_l2_ineligible"] // sint v["el2inel"] = d["evict_l2_ineligible"] // sint
v["mtxmis"] = d["mutex_miss"] // sint v["mtxmis"] = d["mutex_miss"] // sint
v["ztotal"] = (d["zfetch_hits"] + d["zfetch_future"] + d["zfetch_stride"] +
d["zfetch_past"] + d["zfetch_misses"]) // sint
v["zhits"] = d["zfetch_hits"] // sint
v["zahead"] = (d["zfetch_future"] + d["zfetch_stride"]) // sint
v["zpast"] = d["zfetch_past"] // sint
v["zmisses"] = d["zfetch_misses"] // sint
v["zmax"] = d["zfetch_max_streams"] // sint
v["zfuture"] = d["zfetch_future"] // sint
v["zstride"] = d["zfetch_stride"] // sint
v["zissued"] = d["zfetch_io_issued"] // sint
v["zactive"] = d["zfetch_io_active"] // sint
if l2exist: if l2exist:
v["l2hits"] = d["l2_hits"] // sint v["l2hits"] = d["l2_hits"] // sint

View File

@ -37,7 +37,7 @@ import re
bhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize"] bhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize"]
bxhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize", bxhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize",
"usize", "meta", "state", "dbholds", "dbc", "list", "atype", "flags", "meta", "state", "dbholds", "dbc", "list", "atype", "flags",
"count", "asize", "access", "mru", "gmru", "mfu", "gmfu", "l2", "count", "asize", "access", "mru", "gmru", "mfu", "gmfu", "l2",
"l2_dattr", "l2_asize", "l2_comp", "aholds", "dtype", "btype", "l2_dattr", "l2_asize", "l2_comp", "aholds", "dtype", "btype",
"data_bs", "meta_bs", "bsize", "lvls", "dholds", "blocks", "dsize"] "data_bs", "meta_bs", "bsize", "lvls", "dholds", "blocks", "dsize"]
@ -47,17 +47,17 @@ dhdr = ["pool", "objset", "object", "dtype", "cached"]
dxhdr = ["pool", "objset", "object", "dtype", "btype", "data_bs", "meta_bs", dxhdr = ["pool", "objset", "object", "dtype", "btype", "data_bs", "meta_bs",
"bsize", "lvls", "dholds", "blocks", "dsize", "cached", "direct", "bsize", "lvls", "dholds", "blocks", "dsize", "cached", "direct",
"indirect", "bonus", "spill"] "indirect", "bonus", "spill"]
dincompat = ["level", "blkid", "offset", "dbsize", "usize", "meta", "state", dincompat = ["level", "blkid", "offset", "dbsize", "meta", "state", "dbholds",
"dbholds", "dbc", "list", "atype", "flags", "count", "asize", "dbc", "list", "atype", "flags", "count", "asize", "access",
"access", "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr", "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr", "l2_asize",
"l2_asize", "l2_comp", "aholds"] "l2_comp", "aholds"]
thdr = ["pool", "objset", "dtype", "cached"] thdr = ["pool", "objset", "dtype", "cached"]
txhdr = ["pool", "objset", "dtype", "cached", "direct", "indirect", txhdr = ["pool", "objset", "dtype", "cached", "direct", "indirect",
"bonus", "spill"] "bonus", "spill"]
tincompat = ["object", "level", "blkid", "offset", "dbsize", "usize", "meta", tincompat = ["object", "level", "blkid", "offset", "dbsize", "meta", "state",
"state", "dbc", "dbholds", "list", "atype", "flags", "count", "dbc", "dbholds", "list", "atype", "flags", "count", "asize",
"asize", "access", "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr", "access", "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr",
"l2_asize", "l2_comp", "aholds", "btype", "data_bs", "meta_bs", "l2_asize", "l2_comp", "aholds", "btype", "data_bs", "meta_bs",
"bsize", "lvls", "dholds", "blocks", "dsize"] "bsize", "lvls", "dholds", "blocks", "dsize"]
@ -70,7 +70,6 @@ cols = {
"blkid": [8, -1, "block number of buffer"], "blkid": [8, -1, "block number of buffer"],
"offset": [12, 1024, "offset in object of buffer"], "offset": [12, 1024, "offset in object of buffer"],
"dbsize": [7, 1024, "size of buffer"], "dbsize": [7, 1024, "size of buffer"],
"usize": [7, 1024, "size of attached user data"],
"meta": [4, -1, "is this buffer metadata?"], "meta": [4, -1, "is this buffer metadata?"],
"state": [5, -1, "state of buffer (read, cached, etc)"], "state": [5, -1, "state of buffer (read, cached, etc)"],
"dbholds": [7, 1000, "number of holds on buffer"], "dbholds": [7, 1000, "number of holds on buffer"],
@ -400,7 +399,6 @@ def update_dict(d, k, line, labels):
key = line[labels[k]] key = line[labels[k]]
dbsize = int(line[labels['dbsize']]) dbsize = int(line[labels['dbsize']])
usize = int(line[labels['usize']])
blkid = int(line[labels['blkid']]) blkid = int(line[labels['blkid']])
level = int(line[labels['level']]) level = int(line[labels['level']])
@ -418,7 +416,7 @@ def update_dict(d, k, line, labels):
d[pool][objset][key]['indirect'] = 0 d[pool][objset][key]['indirect'] = 0
d[pool][objset][key]['spill'] = 0 d[pool][objset][key]['spill'] = 0
d[pool][objset][key]['cached'] += dbsize + usize d[pool][objset][key]['cached'] += dbsize
if blkid == -1: if blkid == -1:
d[pool][objset][key]['bonus'] += dbsize d[pool][objset][key]['bonus'] += dbsize

View File

@ -269,7 +269,8 @@ main(int argc, char **argv)
return (MOUNT_USAGE); return (MOUNT_USAGE);
} }
if (sloppy || libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) { if (!zfsutil || sloppy ||
libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) {
zfs_adjust_mount_options(zhp, mntpoint, mntopts, mtabopt); zfs_adjust_mount_options(zhp, mntpoint, mntopts, mtabopt);
} }
@ -336,7 +337,7 @@ main(int argc, char **argv)
dataset, mntpoint, mntflags, zfsflags, mntopts, mtabopt); dataset, mntpoint, mntflags, zfsflags, mntopts, mtabopt);
if (!fake) { if (!fake) {
if (!remount && !sloppy && if (zfsutil && !sloppy &&
!libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) { !libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) {
error = zfs_mount_at(zhp, mntopts, mntflags, mntpoint); error = zfs_mount_at(zhp, mntopts, mntflags, mntpoint);
if (error) { if (error) {

View File

@ -1,5 +1,5 @@
raidz_test_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS) raidz_test_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS)
raidz_test_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS) raidz_test_CPPFLAGS = $(AM_CPPFLAGS) $(FORCEDEBUG_CPPFLAGS)
bin_PROGRAMS += raidz_test bin_PROGRAMS += raidz_test
CPPCHECKTARGETS += raidz_test CPPCHECKTARGETS += raidz_test

View File

@ -84,10 +84,10 @@ run_gen_bench_impl(const char *impl)
if (rto_opts.rto_expand) { if (rto_opts.rto_expand) {
rm_bench = vdev_raidz_map_alloc_expanded( rm_bench = vdev_raidz_map_alloc_expanded(
&zio_bench, zio_bench.io_abd,
zio_bench.io_size, zio_bench.io_offset,
rto_opts.rto_ashift, ncols+1, ncols, rto_opts.rto_ashift, ncols+1, ncols,
fn+1, rto_opts.rto_expand_offset, fn+1, rto_opts.rto_expand_offset);
0, B_FALSE);
} else { } else {
rm_bench = vdev_raidz_map_alloc(&zio_bench, rm_bench = vdev_raidz_map_alloc(&zio_bench,
BENCH_ASHIFT, ncols, fn+1); BENCH_ASHIFT, ncols, fn+1);
@ -172,10 +172,10 @@ run_rec_bench_impl(const char *impl)
if (rto_opts.rto_expand) { if (rto_opts.rto_expand) {
rm_bench = vdev_raidz_map_alloc_expanded( rm_bench = vdev_raidz_map_alloc_expanded(
&zio_bench, zio_bench.io_abd,
zio_bench.io_size, zio_bench.io_offset,
BENCH_ASHIFT, ncols+1, ncols, BENCH_ASHIFT, ncols+1, ncols,
PARITY_PQR, PARITY_PQR, rto_opts.rto_expand_offset);
rto_opts.rto_expand_offset, 0, B_FALSE);
} else { } else {
rm_bench = vdev_raidz_map_alloc(&zio_bench, rm_bench = vdev_raidz_map_alloc(&zio_bench,
BENCH_ASHIFT, ncols, PARITY_PQR); BENCH_ASHIFT, ncols, PARITY_PQR);

View File

@ -327,12 +327,14 @@ init_raidz_golden_map(raidz_test_opts_t *opts, const int parity)
if (opts->rto_expand) { if (opts->rto_expand) {
opts->rm_golden = opts->rm_golden =
vdev_raidz_map_alloc_expanded(opts->zio_golden, vdev_raidz_map_alloc_expanded(opts->zio_golden->io_abd,
opts->zio_golden->io_size, opts->zio_golden->io_offset,
opts->rto_ashift, total_ncols+1, total_ncols, opts->rto_ashift, total_ncols+1, total_ncols,
parity, opts->rto_expand_offset, 0, B_FALSE); parity, opts->rto_expand_offset);
rm_test = vdev_raidz_map_alloc_expanded(zio_test, rm_test = vdev_raidz_map_alloc_expanded(zio_test->io_abd,
zio_test->io_size, zio_test->io_offset,
opts->rto_ashift, total_ncols+1, total_ncols, opts->rto_ashift, total_ncols+1, total_ncols,
parity, opts->rto_expand_offset, 0, B_FALSE); parity, opts->rto_expand_offset);
} else { } else {
opts->rm_golden = vdev_raidz_map_alloc(opts->zio_golden, opts->rm_golden = vdev_raidz_map_alloc(opts->zio_golden,
opts->rto_ashift, total_ncols, parity); opts->rto_ashift, total_ncols, parity);
@ -359,6 +361,187 @@ init_raidz_golden_map(raidz_test_opts_t *opts, const int parity)
return (err); return (err);
} }
/*
* If reflow is not in progress, reflow_offset should be UINT64_MAX.
* For each row, if the row is entirely before reflow_offset, it will
* come from the new location. Otherwise this row will come from the
* old location. Therefore, rows that straddle the reflow_offset will
* come from the old location.
*
* NOTE: Until raidz expansion is implemented this function is only
* needed by raidz_test.c to the multi-row raid_map_t functionality.
*/
raidz_map_t *
vdev_raidz_map_alloc_expanded(abd_t *abd, uint64_t size, uint64_t offset,
uint64_t ashift, uint64_t physical_cols, uint64_t logical_cols,
uint64_t nparity, uint64_t reflow_offset)
{
/* The zio's size in units of the vdev's minimum sector size. */
uint64_t s = size >> ashift;
uint64_t q, r, bc, devidx, asize = 0, tot;
/*
* "Quotient": The number of data sectors for this stripe on all but
* the "big column" child vdevs that also contain "remainder" data.
* AKA "full rows"
*/
q = s / (logical_cols - nparity);
/*
* "Remainder": The number of partial stripe data sectors in this I/O.
* This will add a sector to some, but not all, child vdevs.
*/
r = s - q * (logical_cols - nparity);
/* The number of "big columns" - those which contain remainder data. */
bc = (r == 0 ? 0 : r + nparity);
/*
* The total number of data and parity sectors associated with
* this I/O.
*/
tot = s + nparity * (q + (r == 0 ? 0 : 1));
/* How many rows contain data (not skip) */
uint64_t rows = howmany(tot, logical_cols);
int cols = MIN(tot, logical_cols);
raidz_map_t *rm = kmem_zalloc(offsetof(raidz_map_t, rm_row[rows]),
KM_SLEEP);
rm->rm_nrows = rows;
for (uint64_t row = 0; row < rows; row++) {
raidz_row_t *rr = kmem_alloc(offsetof(raidz_row_t,
rr_col[cols]), KM_SLEEP);
rm->rm_row[row] = rr;
/* The starting RAIDZ (parent) vdev sector of the row. */
uint64_t b = (offset >> ashift) + row * logical_cols;
/*
* If we are in the middle of a reflow, and any part of this
* row has not been copied, then use the old location of
* this row.
*/
int row_phys_cols = physical_cols;
if (b + (logical_cols - nparity) > reflow_offset >> ashift)
row_phys_cols--;
/* starting child of this row */
uint64_t child_id = b % row_phys_cols;
/* The starting byte offset on each child vdev. */
uint64_t child_offset = (b / row_phys_cols) << ashift;
/*
* We set cols to the entire width of the block, even
* if this row is shorter. This is needed because parity
* generation (for Q and R) needs to know the entire width,
* because it treats the short row as though it was
* full-width (and the "phantom" sectors were zero-filled).
*
* Another approach to this would be to set cols shorter
* (to just the number of columns that we might do i/o to)
* and have another mechanism to tell the parity generation
* about the "entire width". Reconstruction (at least
* vdev_raidz_reconstruct_general()) would also need to
* know about the "entire width".
*/
rr->rr_cols = cols;
rr->rr_bigcols = bc;
rr->rr_missingdata = 0;
rr->rr_missingparity = 0;
rr->rr_firstdatacol = nparity;
rr->rr_abd_empty = NULL;
rr->rr_nempty = 0;
for (int c = 0; c < rr->rr_cols; c++, child_id++) {
if (child_id >= row_phys_cols) {
child_id -= row_phys_cols;
child_offset += 1ULL << ashift;
}
rr->rr_col[c].rc_devidx = child_id;
rr->rr_col[c].rc_offset = child_offset;
rr->rr_col[c].rc_orig_data = NULL;
rr->rr_col[c].rc_error = 0;
rr->rr_col[c].rc_tried = 0;
rr->rr_col[c].rc_skipped = 0;
rr->rr_col[c].rc_need_orig_restore = B_FALSE;
uint64_t dc = c - rr->rr_firstdatacol;
if (c < rr->rr_firstdatacol) {
rr->rr_col[c].rc_size = 1ULL << ashift;
rr->rr_col[c].rc_abd =
abd_alloc_linear(rr->rr_col[c].rc_size,
B_TRUE);
} else if (row == rows - 1 && bc != 0 && c >= bc) {
/*
* Past the end, this for parity generation.
*/
rr->rr_col[c].rc_size = 0;
rr->rr_col[c].rc_abd = NULL;
} else {
/*
* "data column" (col excluding parity)
* Add an ASCII art diagram here
*/
uint64_t off;
if (c < bc || r == 0) {
off = dc * rows + row;
} else {
off = r * rows +
(dc - r) * (rows - 1) + row;
}
rr->rr_col[c].rc_size = 1ULL << ashift;
rr->rr_col[c].rc_abd = abd_get_offset_struct(
&rr->rr_col[c].rc_abdstruct,
abd, off << ashift, 1 << ashift);
}
asize += rr->rr_col[c].rc_size;
}
/*
* If all data stored spans all columns, there's a danger that
* parity will always be on the same device and, since parity
* isn't read during normal operation, that that device's I/O
* bandwidth won't be used effectively. We therefore switch
* the parity every 1MB.
*
* ...at least that was, ostensibly, the theory. As a practical
* matter unless we juggle the parity between all devices
* evenly, we won't see any benefit. Further, occasional writes
* that aren't a multiple of the LCM of the number of children
* and the minimum stripe width are sufficient to avoid pessimal
* behavior. Unfortunately, this decision created an implicit
* on-disk format requirement that we need to support for all
* eternity, but only for single-parity RAID-Z.
*
* If we intend to skip a sector in the zeroth column for
* padding we must make sure to note this swap. We will never
* intend to skip the first column since at least one data and
* one parity column must appear in each row.
*/
if (rr->rr_firstdatacol == 1 && rr->rr_cols > 1 &&
(offset & (1ULL << 20))) {
ASSERT(rr->rr_cols >= 2);
ASSERT(rr->rr_col[0].rc_size == rr->rr_col[1].rc_size);
devidx = rr->rr_col[0].rc_devidx;
uint64_t o = rr->rr_col[0].rc_offset;
rr->rr_col[0].rc_devidx = rr->rr_col[1].rc_devidx;
rr->rr_col[0].rc_offset = rr->rr_col[1].rc_offset;
rr->rr_col[1].rc_devidx = devidx;
rr->rr_col[1].rc_offset = o;
}
}
ASSERT3U(asize, ==, tot << ashift);
/* init RAIDZ parity ops */
rm->rm_ops = vdev_raidz_math_get_ops();
return (rm);
}
static raidz_map_t * static raidz_map_t *
init_raidz_map(raidz_test_opts_t *opts, zio_t **zio, const int parity) init_raidz_map(raidz_test_opts_t *opts, zio_t **zio, const int parity)
{ {
@ -378,9 +561,10 @@ init_raidz_map(raidz_test_opts_t *opts, zio_t **zio, const int parity)
init_zio_abd(*zio); init_zio_abd(*zio);
if (opts->rto_expand) { if (opts->rto_expand) {
rm = vdev_raidz_map_alloc_expanded(*zio, rm = vdev_raidz_map_alloc_expanded((*zio)->io_abd,
(*zio)->io_size, (*zio)->io_offset,
opts->rto_ashift, total_ncols+1, total_ncols, opts->rto_ashift, total_ncols+1, total_ncols,
parity, opts->rto_expand_offset, 0, B_FALSE); parity, opts->rto_expand_offset);
} else { } else {
rm = vdev_raidz_map_alloc(*zio, opts->rto_ashift, rm = vdev_raidz_map_alloc(*zio, opts->rto_ashift,
total_ncols, parity); total_ncols, parity);

View File

@ -119,4 +119,7 @@ void init_zio_abd(zio_t *zio);
void run_raidz_benchmark(void); void run_raidz_benchmark(void);
struct raidz_map *vdev_raidz_map_alloc_expanded(abd_t *, uint64_t, uint64_t,
uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
#endif /* RAIDZ_TEST_H */ #endif /* RAIDZ_TEST_H */

View File

@ -1,4 +1,4 @@
zdb_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS) zdb_CPPFLAGS = $(AM_CPPFLAGS) $(FORCEDEBUG_CPPFLAGS)
zdb_CFLAGS = $(AM_CFLAGS) $(LIBCRYPTO_CFLAGS) zdb_CFLAGS = $(AM_CFLAGS) $(LIBCRYPTO_CFLAGS)
sbin_PROGRAMS += zdb sbin_PROGRAMS += zdb
@ -10,7 +10,6 @@ zdb_SOURCES = \
%D%/zdb_il.c %D%/zdb_il.c
zdb_LDADD = \ zdb_LDADD = \
libzdb.la \
libzpool.la \ libzpool.la \
libzfs_core.la \ libzfs_core.la \
libnvpair.la libnvpair.la

File diff suppressed because it is too large Load Diff

View File

@ -168,25 +168,23 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, const void *arg)
(u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_offset, (u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_offset,
(u_longlong_t)lr->lr_length); (u_longlong_t)lr->lr_length);
if (txtype == TX_WRITE2 || verbose < 4) if (txtype == TX_WRITE2 || verbose < 5)
return; return;
if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) { if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
(void) printf("%shas blkptr, %s\n", tab_prefix, (void) printf("%shas blkptr, %s\n", tab_prefix,
!BP_IS_HOLE(bp) && BP_GET_LOGICAL_BIRTH(bp) >= !BP_IS_HOLE(bp) &&
spa_min_claim_txg(zilog->zl_spa) ? bp->blk_birth >= spa_min_claim_txg(zilog->zl_spa) ?
"will claim" : "won't claim"); "will claim" : "won't claim");
print_log_bp(bp, tab_prefix); print_log_bp(bp, tab_prefix);
if (verbose < 5)
return;
if (BP_IS_HOLE(bp)) { if (BP_IS_HOLE(bp)) {
(void) printf("\t\t\tLSIZE 0x%llx\n", (void) printf("\t\t\tLSIZE 0x%llx\n",
(u_longlong_t)BP_GET_LSIZE(bp)); (u_longlong_t)BP_GET_LSIZE(bp));
(void) printf("%s<hole>\n", tab_prefix); (void) printf("%s<hole>\n", tab_prefix);
return; return;
} }
if (BP_GET_LOGICAL_BIRTH(bp) < zilog->zl_header->zh_claim_txg) { if (bp->blk_birth < zilog->zl_header->zh_claim_txg) {
(void) printf("%s<block already committed>\n", (void) printf("%s<block already committed>\n",
tab_prefix); tab_prefix);
return; return;
@ -204,9 +202,6 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, const void *arg)
if (error) if (error)
goto out; goto out;
} else { } else {
if (verbose < 5)
return;
/* data is stored after the end of the lr_write record */ /* data is stored after the end of the lr_write record */
data = abd_alloc(lr->lr_length, B_FALSE); data = abd_alloc(lr->lr_length, B_FALSE);
abd_copy_from_buf(data, lr + 1, lr->lr_length); abd_copy_from_buf(data, lr + 1, lr->lr_length);
@ -222,28 +217,6 @@ out:
abd_free(data); abd_free(data);
} }
static void
zil_prt_rec_write_enc(zilog_t *zilog, int txtype, const void *arg)
{
(void) txtype;
const lr_write_t *lr = arg;
const blkptr_t *bp = &lr->lr_blkptr;
int verbose = MAX(dump_opt['d'], dump_opt['i']);
(void) printf("%s(encrypted)\n", tab_prefix);
if (verbose < 4)
return;
if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
(void) printf("%shas blkptr, %s\n", tab_prefix,
!BP_IS_HOLE(bp) && BP_GET_LOGICAL_BIRTH(bp) >=
spa_min_claim_txg(zilog->zl_spa) ?
"will claim" : "won't claim");
print_log_bp(bp, tab_prefix);
}
}
static void static void
zil_prt_rec_truncate(zilog_t *zilog, int txtype, const void *arg) zil_prt_rec_truncate(zilog_t *zilog, int txtype, const void *arg)
{ {
@ -339,34 +312,11 @@ zil_prt_rec_clone_range(zilog_t *zilog, int txtype, const void *arg)
{ {
(void) zilog, (void) txtype; (void) zilog, (void) txtype;
const lr_clone_range_t *lr = arg; const lr_clone_range_t *lr = arg;
int verbose = MAX(dump_opt['d'], dump_opt['i']);
(void) printf("%sfoid %llu, offset %llx, length %llx, blksize %llx\n", (void) printf("%sfoid %llu, offset %llx, length %llx, blksize %llx\n",
tab_prefix, (u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_offset, tab_prefix, (u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_offset,
(u_longlong_t)lr->lr_length, (u_longlong_t)lr->lr_blksz); (u_longlong_t)lr->lr_length, (u_longlong_t)lr->lr_blksz);
if (verbose < 4)
return;
for (unsigned int i = 0; i < lr->lr_nbps; i++) {
(void) printf("%s[%u/%llu] ", tab_prefix, i + 1,
(u_longlong_t)lr->lr_nbps);
print_log_bp(&lr->lr_bps[i], "");
}
}
static void
zil_prt_rec_clone_range_enc(zilog_t *zilog, int txtype, const void *arg)
{
(void) zilog, (void) txtype;
const lr_clone_range_t *lr = arg;
int verbose = MAX(dump_opt['d'], dump_opt['i']);
(void) printf("%s(encrypted)\n", tab_prefix);
if (verbose < 4)
return;
for (unsigned int i = 0; i < lr->lr_nbps; i++) { for (unsigned int i = 0; i < lr->lr_nbps; i++) {
(void) printf("%s[%u/%llu] ", tab_prefix, i + 1, (void) printf("%s[%u/%llu] ", tab_prefix, i + 1,
(u_longlong_t)lr->lr_nbps); (u_longlong_t)lr->lr_nbps);
@ -377,7 +327,6 @@ zil_prt_rec_clone_range_enc(zilog_t *zilog, int txtype, const void *arg)
typedef void (*zil_prt_rec_func_t)(zilog_t *, int, const void *); typedef void (*zil_prt_rec_func_t)(zilog_t *, int, const void *);
typedef struct zil_rec_info { typedef struct zil_rec_info {
zil_prt_rec_func_t zri_print; zil_prt_rec_func_t zri_print;
zil_prt_rec_func_t zri_print_enc;
const char *zri_name; const char *zri_name;
uint64_t zri_count; uint64_t zri_count;
} zil_rec_info_t; } zil_rec_info_t;
@ -392,9 +341,7 @@ static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = {
{.zri_print = zil_prt_rec_remove, .zri_name = "TX_RMDIR "}, {.zri_print = zil_prt_rec_remove, .zri_name = "TX_RMDIR "},
{.zri_print = zil_prt_rec_link, .zri_name = "TX_LINK "}, {.zri_print = zil_prt_rec_link, .zri_name = "TX_LINK "},
{.zri_print = zil_prt_rec_rename, .zri_name = "TX_RENAME "}, {.zri_print = zil_prt_rec_rename, .zri_name = "TX_RENAME "},
{.zri_print = zil_prt_rec_write, {.zri_print = zil_prt_rec_write, .zri_name = "TX_WRITE "},
.zri_print_enc = zil_prt_rec_write_enc,
.zri_name = "TX_WRITE "},
{.zri_print = zil_prt_rec_truncate, .zri_name = "TX_TRUNCATE "}, {.zri_print = zil_prt_rec_truncate, .zri_name = "TX_TRUNCATE "},
{.zri_print = zil_prt_rec_setattr, .zri_name = "TX_SETATTR "}, {.zri_print = zil_prt_rec_setattr, .zri_name = "TX_SETATTR "},
{.zri_print = zil_prt_rec_acl, .zri_name = "TX_ACL_V0 "}, {.zri_print = zil_prt_rec_acl, .zri_name = "TX_ACL_V0 "},
@ -411,7 +358,6 @@ static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = {
{.zri_print = zil_prt_rec_rename, .zri_name = "TX_RENAME_EXCHANGE "}, {.zri_print = zil_prt_rec_rename, .zri_name = "TX_RENAME_EXCHANGE "},
{.zri_print = zil_prt_rec_rename, .zri_name = "TX_RENAME_WHITEOUT "}, {.zri_print = zil_prt_rec_rename, .zri_name = "TX_RENAME_WHITEOUT "},
{.zri_print = zil_prt_rec_clone_range, {.zri_print = zil_prt_rec_clone_range,
.zri_print_enc = zil_prt_rec_clone_range_enc,
.zri_name = "TX_CLONE_RANGE "}, .zri_name = "TX_CLONE_RANGE "},
}; };
@ -438,8 +384,6 @@ print_log_record(zilog_t *zilog, const lr_t *lr, void *arg, uint64_t claim_txg)
if (txtype && verbose >= 3) { if (txtype && verbose >= 3) {
if (!zilog->zl_os->os_encrypted) { if (!zilog->zl_os->os_encrypted) {
zil_rec_info[txtype].zri_print(zilog, txtype, lr); zil_rec_info[txtype].zri_print(zilog, txtype, lr);
} else if (zil_rec_info[txtype].zri_print_enc) {
zil_rec_info[txtype].zri_print_enc(zilog, txtype, lr);
} else { } else {
(void) printf("%s(encrypted)\n", tab_prefix); (void) printf("%s(encrypted)\n", tab_prefix);
} }
@ -473,7 +417,7 @@ print_log_block(zilog_t *zilog, const blkptr_t *bp, void *arg,
if (claim_txg != 0) if (claim_txg != 0)
claim = "already claimed"; claim = "already claimed";
else if (BP_GET_LOGICAL_BIRTH(bp) >= spa_min_claim_txg(zilog->zl_spa)) else if (bp->blk_birth >= spa_min_claim_txg(zilog->zl_spa))
claim = "will claim"; claim = "will claim";
else else
claim = "won't claim"; claim = "won't claim";

View File

@ -22,7 +22,6 @@
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* *
* Copyright (c) 2016, Intel Corporation. * Copyright (c) 2016, Intel Corporation.
* Copyright (c) 2023, Klara Inc.
*/ */
/* /*
@ -232,6 +231,28 @@ fmd_prop_get_int32(fmd_hdl_t *hdl, const char *name)
if (strcmp(name, "spare_on_remove") == 0) if (strcmp(name, "spare_on_remove") == 0)
return (1); return (1);
if (strcmp(name, "io_N") == 0 || strcmp(name, "checksum_N") == 0)
return (10); /* N = 10 events */
return (0);
}
int64_t
fmd_prop_get_int64(fmd_hdl_t *hdl, const char *name)
{
(void) hdl;
/*
* These can be looked up in mp->modinfo->fmdi_props
* For now we just hard code for phase 2. In the
* future, there can be a ZED based override.
*/
if (strcmp(name, "remove_timeout") == 0)
return (15ULL * 1000ULL * 1000ULL * 1000ULL); /* 15 sec */
if (strcmp(name, "io_T") == 0 || strcmp(name, "checksum_T") == 0)
return (1000ULL * 1000ULL * 1000ULL * 600ULL); /* 10 min */
return (0); return (0);
} }
@ -514,19 +535,6 @@ fmd_serd_exists(fmd_hdl_t *hdl, const char *name)
return (fmd_serd_eng_lookup(&mp->mod_serds, name) != NULL); return (fmd_serd_eng_lookup(&mp->mod_serds, name) != NULL);
} }
int
fmd_serd_active(fmd_hdl_t *hdl, const char *name)
{
fmd_module_t *mp = (fmd_module_t *)hdl;
fmd_serd_eng_t *sgp;
if ((sgp = fmd_serd_eng_lookup(&mp->mod_serds, name)) == NULL) {
zed_log_msg(LOG_ERR, "serd engine '%s' does not exist", name);
return (0);
}
return (fmd_serd_eng_fired(sgp) || !fmd_serd_eng_empty(sgp));
}
void void
fmd_serd_reset(fmd_hdl_t *hdl, const char *name) fmd_serd_reset(fmd_hdl_t *hdl, const char *name)
{ {
@ -535,10 +543,12 @@ fmd_serd_reset(fmd_hdl_t *hdl, const char *name)
if ((sgp = fmd_serd_eng_lookup(&mp->mod_serds, name)) == NULL) { if ((sgp = fmd_serd_eng_lookup(&mp->mod_serds, name)) == NULL) {
zed_log_msg(LOG_ERR, "serd engine '%s' does not exist", name); zed_log_msg(LOG_ERR, "serd engine '%s' does not exist", name);
} else { return;
fmd_serd_eng_reset(sgp);
fmd_hdl_debug(hdl, "serd_reset %s", name);
} }
fmd_serd_eng_reset(sgp);
fmd_hdl_debug(hdl, "serd_reset %s", name);
} }
int int
@ -546,21 +556,16 @@ fmd_serd_record(fmd_hdl_t *hdl, const char *name, fmd_event_t *ep)
{ {
fmd_module_t *mp = (fmd_module_t *)hdl; fmd_module_t *mp = (fmd_module_t *)hdl;
fmd_serd_eng_t *sgp; fmd_serd_eng_t *sgp;
int err;
if ((sgp = fmd_serd_eng_lookup(&mp->mod_serds, name)) == NULL) { if ((sgp = fmd_serd_eng_lookup(&mp->mod_serds, name)) == NULL) {
zed_log_msg(LOG_ERR, "failed to add record to SERD engine '%s'", zed_log_msg(LOG_ERR, "failed to add record to SERD engine '%s'",
name); name);
return (0); return (0);
} }
return (fmd_serd_eng_record(sgp, ep->ev_hrt)); err = fmd_serd_eng_record(sgp, ep->ev_hrt);
}
void return (err);
fmd_serd_gc(fmd_hdl_t *hdl)
{
fmd_module_t *mp = (fmd_module_t *)hdl;
fmd_serd_hash_apply(&mp->mod_serds, fmd_serd_eng_gc, NULL);
} }
/* FMD Timers */ /* FMD Timers */
@ -574,7 +579,7 @@ _timer_notify(union sigval sv)
const fmd_hdl_ops_t *ops = mp->mod_info->fmdi_ops; const fmd_hdl_ops_t *ops = mp->mod_info->fmdi_ops;
struct itimerspec its; struct itimerspec its;
fmd_hdl_debug(hdl, "%s timer fired (%p)", mp->mod_name, ftp->ft_tid); fmd_hdl_debug(hdl, "timer fired (%p)", ftp->ft_tid);
/* disarm the timer */ /* disarm the timer */
memset(&its, 0, sizeof (struct itimerspec)); memset(&its, 0, sizeof (struct itimerspec));

View File

@ -151,6 +151,7 @@ extern void fmd_hdl_vdebug(fmd_hdl_t *, const char *, va_list);
extern void fmd_hdl_debug(fmd_hdl_t *, const char *, ...); extern void fmd_hdl_debug(fmd_hdl_t *, const char *, ...);
extern int32_t fmd_prop_get_int32(fmd_hdl_t *, const char *); extern int32_t fmd_prop_get_int32(fmd_hdl_t *, const char *);
extern int64_t fmd_prop_get_int64(fmd_hdl_t *, const char *);
#define FMD_STAT_NOALLOC 0x0 /* fmd should use caller's memory */ #define FMD_STAT_NOALLOC 0x0 /* fmd should use caller's memory */
#define FMD_STAT_ALLOC 0x1 /* fmd should allocate stats memory */ #define FMD_STAT_ALLOC 0x1 /* fmd should allocate stats memory */
@ -194,12 +195,10 @@ extern size_t fmd_buf_size(fmd_hdl_t *, fmd_case_t *, const char *);
extern void fmd_serd_create(fmd_hdl_t *, const char *, uint_t, hrtime_t); extern void fmd_serd_create(fmd_hdl_t *, const char *, uint_t, hrtime_t);
extern void fmd_serd_destroy(fmd_hdl_t *, const char *); extern void fmd_serd_destroy(fmd_hdl_t *, const char *);
extern int fmd_serd_exists(fmd_hdl_t *, const char *); extern int fmd_serd_exists(fmd_hdl_t *, const char *);
extern int fmd_serd_active(fmd_hdl_t *, const char *);
extern void fmd_serd_reset(fmd_hdl_t *, const char *); extern void fmd_serd_reset(fmd_hdl_t *, const char *);
extern int fmd_serd_record(fmd_hdl_t *, const char *, fmd_event_t *); extern int fmd_serd_record(fmd_hdl_t *, const char *, fmd_event_t *);
extern int fmd_serd_fired(fmd_hdl_t *, const char *); extern int fmd_serd_fired(fmd_hdl_t *, const char *);
extern int fmd_serd_empty(fmd_hdl_t *, const char *); extern int fmd_serd_empty(fmd_hdl_t *, const char *);
extern void fmd_serd_gc(fmd_hdl_t *);
extern id_t fmd_timer_install(fmd_hdl_t *, void *, fmd_event_t *, hrtime_t); extern id_t fmd_timer_install(fmd_hdl_t *, void *, fmd_event_t *, hrtime_t);
extern void fmd_timer_remove(fmd_hdl_t *, id_t); extern void fmd_timer_remove(fmd_hdl_t *, id_t);

View File

@ -310,9 +310,8 @@ fmd_serd_eng_reset(fmd_serd_eng_t *sgp)
} }
void void
fmd_serd_eng_gc(fmd_serd_eng_t *sgp, void *arg) fmd_serd_eng_gc(fmd_serd_eng_t *sgp)
{ {
(void) arg;
fmd_serd_elem_t *sep, *nep; fmd_serd_elem_t *sep, *nep;
hrtime_t hrt; hrtime_t hrt;

View File

@ -77,7 +77,7 @@ extern int fmd_serd_eng_fired(fmd_serd_eng_t *);
extern int fmd_serd_eng_empty(fmd_serd_eng_t *); extern int fmd_serd_eng_empty(fmd_serd_eng_t *);
extern void fmd_serd_eng_reset(fmd_serd_eng_t *); extern void fmd_serd_eng_reset(fmd_serd_eng_t *);
extern void fmd_serd_eng_gc(fmd_serd_eng_t *, void *); extern void fmd_serd_eng_gc(fmd_serd_eng_t *);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -23,7 +23,6 @@
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2016, Intel Corporation. * Copyright (c) 2016, Intel Corporation.
* Copyright (c) 2023, Klara Inc.
*/ */
#include <stddef.h> #include <stddef.h>
@ -48,16 +47,11 @@
#define DEFAULT_CHECKSUM_T 600 /* seconds */ #define DEFAULT_CHECKSUM_T 600 /* seconds */
#define DEFAULT_IO_N 10 /* events */ #define DEFAULT_IO_N 10 /* events */
#define DEFAULT_IO_T 600 /* seconds */ #define DEFAULT_IO_T 600 /* seconds */
#define DEFAULT_SLOW_IO_N 10 /* events */
#define DEFAULT_SLOW_IO_T 30 /* seconds */
#define CASE_GC_TIMEOUT_SECS 43200 /* 12 hours */
/* /*
* Our serd engines are named in the following format: * Our serd engines are named 'zfs_<pool_guid>_<vdev_guid>_{checksum,io}'. This
* 'zfs_<pool_guid>_<vdev_guid>_{checksum,io,slow_io}' * #define reserves enough space for two 64-bit hex values plus the length of
* This #define reserves enough space for two 64-bit hex values plus the * the longest string.
* length of the longest string.
*/ */
#define MAX_SERDLEN (16 * 2 + sizeof ("zfs___checksum")) #define MAX_SERDLEN (16 * 2 + sizeof ("zfs___checksum"))
@ -74,7 +68,6 @@ typedef struct zfs_case_data {
int zc_pool_state; int zc_pool_state;
char zc_serd_checksum[MAX_SERDLEN]; char zc_serd_checksum[MAX_SERDLEN];
char zc_serd_io[MAX_SERDLEN]; char zc_serd_io[MAX_SERDLEN];
char zc_serd_slow_io[MAX_SERDLEN];
int zc_has_remove_timer; int zc_has_remove_timer;
} zfs_case_data_t; } zfs_case_data_t;
@ -121,8 +114,7 @@ zfs_de_stats_t zfs_stats = {
{ "resource_drops", FMD_TYPE_UINT64, "resource related ereports" } { "resource_drops", FMD_TYPE_UINT64, "resource related ereports" }
}; };
/* wait 15 seconds after a removal */ static hrtime_t zfs_remove_timeout;
static hrtime_t zfs_remove_timeout = SEC2NSEC(15);
uu_list_pool_t *zfs_case_pool; uu_list_pool_t *zfs_case_pool;
uu_list_t *zfs_cases; uu_list_t *zfs_cases;
@ -132,8 +124,6 @@ uu_list_t *zfs_cases;
#define ZFS_MAKE_EREPORT(type) \ #define ZFS_MAKE_EREPORT(type) \
FM_EREPORT_CLASS "." ZFS_ERROR_CLASS "." type FM_EREPORT_CLASS "." ZFS_ERROR_CLASS "." type
static void zfs_purge_cases(fmd_hdl_t *hdl);
/* /*
* Write out the persistent representation of an active case. * Write out the persistent representation of an active case.
*/ */
@ -180,42 +170,6 @@ zfs_case_unserialize(fmd_hdl_t *hdl, fmd_case_t *cp)
return (zcp); return (zcp);
} }
/*
* count other unique slow-io cases in a pool
*/
static uint_t
zfs_other_slow_cases(fmd_hdl_t *hdl, const zfs_case_data_t *zfs_case)
{
zfs_case_t *zcp;
uint_t cases = 0;
static hrtime_t next_check = 0;
/*
* Note that plumbing in some external GC would require adding locking,
* since most of this module code is not thread safe and assumes there
* is only one thread running against the module. So we perform GC here
* inline periodically so that future delay induced faults will be
* possible once the issue causing multiple vdev delays is resolved.
*/
if (gethrestime_sec() > next_check) {
/* Periodically purge old SERD entries and stale cases */
fmd_serd_gc(hdl);
zfs_purge_cases(hdl);
next_check = gethrestime_sec() + CASE_GC_TIMEOUT_SECS;
}
for (zcp = uu_list_first(zfs_cases); zcp != NULL;
zcp = uu_list_next(zfs_cases, zcp)) {
if (zcp->zc_data.zc_pool_guid == zfs_case->zc_pool_guid &&
zcp->zc_data.zc_vdev_guid != zfs_case->zc_vdev_guid &&
zcp->zc_data.zc_serd_slow_io[0] != '\0' &&
fmd_serd_active(hdl, zcp->zc_data.zc_serd_slow_io)) {
cases++;
}
}
return (cases);
}
/* /*
* Iterate over any active cases. If any cases are associated with a pool or * Iterate over any active cases. If any cases are associated with a pool or
* vdev which is no longer present on the system, close the associated case. * vdev which is no longer present on the system, close the associated case.
@ -422,14 +376,6 @@ zfs_serd_name(char *buf, uint64_t pool_guid, uint64_t vdev_guid,
(long long unsigned int)vdev_guid, type); (long long unsigned int)vdev_guid, type);
} }
static void
zfs_case_retire(fmd_hdl_t *hdl, zfs_case_t *zcp)
{
fmd_hdl_debug(hdl, "retiring case");
fmd_case_close(hdl, zcp->zc_case);
}
/* /*
* Solve a given ZFS case. This first checks to make sure the diagnosis is * Solve a given ZFS case. This first checks to make sure the diagnosis is
* still valid, as well as cleaning up any pending timer associated with the * still valid, as well as cleaning up any pending timer associated with the
@ -686,7 +632,9 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
if (strcmp(class, if (strcmp(class,
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_DATA)) == 0 || ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_DATA)) == 0 ||
strcmp(class, strcmp(class,
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_CONFIG_CACHE_WRITE)) == 0) { ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_CONFIG_CACHE_WRITE)) == 0 ||
strcmp(class,
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_DELAY)) == 0) {
zfs_stats.resource_drops.fmds_value.ui64++; zfs_stats.resource_drops.fmds_value.ui64++;
return; return;
} }
@ -754,9 +702,6 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
if (zcp->zc_data.zc_serd_checksum[0] != '\0') if (zcp->zc_data.zc_serd_checksum[0] != '\0')
fmd_serd_reset(hdl, fmd_serd_reset(hdl,
zcp->zc_data.zc_serd_checksum); zcp->zc_data.zc_serd_checksum);
if (zcp->zc_data.zc_serd_slow_io[0] != '\0')
fmd_serd_reset(hdl,
zcp->zc_data.zc_serd_slow_io);
} else if (fmd_nvl_class_match(hdl, nvl, } else if (fmd_nvl_class_match(hdl, nvl,
ZFS_MAKE_RSRC(FM_RESOURCE_STATECHANGE))) { ZFS_MAKE_RSRC(FM_RESOURCE_STATECHANGE))) {
uint64_t state = 0; uint64_t state = 0;
@ -785,11 +730,7 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
if (fmd_case_solved(hdl, zcp->zc_case)) if (fmd_case_solved(hdl, zcp->zc_case))
return; return;
if (vdev_guid) fmd_hdl_debug(hdl, "error event '%s'", class);
fmd_hdl_debug(hdl, "error event '%s', vdev %llu", class,
vdev_guid);
else
fmd_hdl_debug(hdl, "error event '%s'", class);
/* /*
* Determine if we should solve the case and generate a fault. We solve * Determine if we should solve the case and generate a fault. We solve
@ -838,12 +779,11 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
fmd_nvl_class_match(hdl, nvl, fmd_nvl_class_match(hdl, nvl,
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_IO_FAILURE)) || ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_IO_FAILURE)) ||
fmd_nvl_class_match(hdl, nvl, fmd_nvl_class_match(hdl, nvl,
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_DELAY)) ||
fmd_nvl_class_match(hdl, nvl,
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_PROBE_FAILURE))) { ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_PROBE_FAILURE))) {
const char *failmode = NULL; const char *failmode = NULL;
boolean_t checkremove = B_FALSE; boolean_t checkremove = B_FALSE;
uint32_t pri = 0; uint32_t pri = 0;
int32_t flags = 0;
/* /*
* If this is a checksum or I/O error, then toss it into the * If this is a checksum or I/O error, then toss it into the
@ -874,75 +814,20 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
} }
if (fmd_serd_record(hdl, zcp->zc_data.zc_serd_io, ep)) if (fmd_serd_record(hdl, zcp->zc_data.zc_serd_io, ep))
checkremove = B_TRUE; checkremove = B_TRUE;
} else if (fmd_nvl_class_match(hdl, nvl,
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_DELAY))) {
uint64_t slow_io_n, slow_io_t;
/*
* Create a slow io SERD engine when the VDEV has the
* 'vdev_slow_io_n' and 'vdev_slow_io_n' properties.
*/
if (zcp->zc_data.zc_serd_slow_io[0] == '\0' &&
nvlist_lookup_uint64(nvl,
FM_EREPORT_PAYLOAD_ZFS_VDEV_SLOW_IO_N,
&slow_io_n) == 0 &&
nvlist_lookup_uint64(nvl,
FM_EREPORT_PAYLOAD_ZFS_VDEV_SLOW_IO_T,
&slow_io_t) == 0) {
zfs_serd_name(zcp->zc_data.zc_serd_slow_io,
pool_guid, vdev_guid, "slow_io");
fmd_serd_create(hdl,
zcp->zc_data.zc_serd_slow_io,
slow_io_n,
SEC2NSEC(slow_io_t));
zfs_case_serialize(zcp);
}
/* Pass event to SERD engine and see if this triggers */
if (zcp->zc_data.zc_serd_slow_io[0] != '\0' &&
fmd_serd_record(hdl, zcp->zc_data.zc_serd_slow_io,
ep)) {
/*
* Ignore a slow io diagnosis when other
* VDEVs in the pool show signs of being slow.
*/
if (zfs_other_slow_cases(hdl, &zcp->zc_data)) {
zfs_case_retire(hdl, zcp);
fmd_hdl_debug(hdl, "pool %llu has "
"multiple slow io cases -- skip "
"degrading vdev %llu",
(u_longlong_t)
zcp->zc_data.zc_pool_guid,
(u_longlong_t)
zcp->zc_data.zc_vdev_guid);
} else {
zfs_case_solve(hdl, zcp,
"fault.fs.zfs.vdev.slow_io");
}
}
} else if (fmd_nvl_class_match(hdl, nvl, } else if (fmd_nvl_class_match(hdl, nvl,
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_CHECKSUM))) { ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_CHECKSUM))) {
uint64_t flags = 0;
int32_t flags32 = 0;
/* /*
* We ignore ereports for checksum errors generated by * We ignore ereports for checksum errors generated by
* scrub/resilver I/O to avoid potentially further * scrub/resilver I/O to avoid potentially further
* degrading the pool while it's being repaired. * degrading the pool while it's being repaired.
*
* Note that FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS used to
* be int32. To allow newer zed to work on older
* kernels, if we don't find the flags, we look for
* the older ones too.
*/ */
if (((nvlist_lookup_uint32(nvl, if (((nvlist_lookup_uint32(nvl,
FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY, &pri) == 0) && FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY, &pri) == 0) &&
(pri == ZIO_PRIORITY_SCRUB || (pri == ZIO_PRIORITY_SCRUB ||
pri == ZIO_PRIORITY_REBUILD)) || pri == ZIO_PRIORITY_REBUILD)) ||
((nvlist_lookup_uint64(nvl,
FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS, &flags) == 0) &&
(flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER))) ||
((nvlist_lookup_int32(nvl, ((nvlist_lookup_int32(nvl,
FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS, &flags32) == 0) && FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS, &flags) == 0) &&
(flags32 & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)))) { (flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)))) {
fmd_hdl_debug(hdl, "ignoring '%s' for " fmd_hdl_debug(hdl, "ignoring '%s' for "
"scrub/resilver I/O", class); "scrub/resilver I/O", class);
return; return;
@ -1039,8 +924,6 @@ zfs_fm_close(fmd_hdl_t *hdl, fmd_case_t *cs)
fmd_serd_destroy(hdl, zcp->zc_data.zc_serd_checksum); fmd_serd_destroy(hdl, zcp->zc_data.zc_serd_checksum);
if (zcp->zc_data.zc_serd_io[0] != '\0') if (zcp->zc_data.zc_serd_io[0] != '\0')
fmd_serd_destroy(hdl, zcp->zc_data.zc_serd_io); fmd_serd_destroy(hdl, zcp->zc_data.zc_serd_io);
if (zcp->zc_data.zc_serd_slow_io[0] != '\0')
fmd_serd_destroy(hdl, zcp->zc_data.zc_serd_slow_io);
if (zcp->zc_data.zc_has_remove_timer) if (zcp->zc_data.zc_has_remove_timer)
fmd_timer_remove(hdl, zcp->zc_remove_timer); fmd_timer_remove(hdl, zcp->zc_remove_timer);
@ -1049,15 +932,30 @@ zfs_fm_close(fmd_hdl_t *hdl, fmd_case_t *cs)
fmd_hdl_free(hdl, zcp, sizeof (zfs_case_t)); fmd_hdl_free(hdl, zcp, sizeof (zfs_case_t));
} }
/*
* We use the fmd gc entry point to look for old cases that no longer apply.
* This allows us to keep our set of case data small in a long running system.
*/
static void
zfs_fm_gc(fmd_hdl_t *hdl)
{
zfs_purge_cases(hdl);
}
static const fmd_hdl_ops_t fmd_ops = { static const fmd_hdl_ops_t fmd_ops = {
zfs_fm_recv, /* fmdo_recv */ zfs_fm_recv, /* fmdo_recv */
zfs_fm_timeout, /* fmdo_timeout */ zfs_fm_timeout, /* fmdo_timeout */
zfs_fm_close, /* fmdo_close */ zfs_fm_close, /* fmdo_close */
NULL, /* fmdo_stats */ NULL, /* fmdo_stats */
NULL, /* fmdo_gc */ zfs_fm_gc, /* fmdo_gc */
}; };
static const fmd_prop_t fmd_props[] = { static const fmd_prop_t fmd_props[] = {
{ "checksum_N", FMD_TYPE_UINT32, "10" },
{ "checksum_T", FMD_TYPE_TIME, "10min" },
{ "io_N", FMD_TYPE_UINT32, "10" },
{ "io_T", FMD_TYPE_TIME, "10min" },
{ "remove_timeout", FMD_TYPE_TIME, "15sec" },
{ NULL, 0, NULL } { NULL, 0, NULL }
}; };
@ -1098,6 +996,8 @@ _zfs_diagnosis_init(fmd_hdl_t *hdl)
(void) fmd_stat_create(hdl, FMD_STAT_NOALLOC, sizeof (zfs_stats) / (void) fmd_stat_create(hdl, FMD_STAT_NOALLOC, sizeof (zfs_stats) /
sizeof (fmd_stat_t), (fmd_stat_t *)&zfs_stats); sizeof (fmd_stat_t), (fmd_stat_t *)&zfs_stats);
zfs_remove_timeout = fmd_prop_get_int64(hdl, "remove_timeout");
} }
void void

View File

@ -233,12 +233,8 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
} }
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_PHYS_PATH, &physpath); (void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_PHYS_PATH, &physpath);
update_vdev_config_dev_sysfs_path(vdev, path,
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH, (void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
&enc_sysfs_path); &enc_sysfs_path);
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk); (void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk);
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_OFFLINE, &offline); (void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_OFFLINE, &offline);
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_FAULTED, &faulted); (void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_FAULTED, &faulted);
@ -702,7 +698,7 @@ zfs_enable_ds(void *arg)
{ {
unavailpool_t *pool = (unavailpool_t *)arg; unavailpool_t *pool = (unavailpool_t *)arg;
(void) zpool_enable_datasets(pool->uap_zhp, NULL, 0, 512); (void) zpool_enable_datasets(pool->uap_zhp, NULL, 0);
zpool_close(pool->uap_zhp); zpool_close(pool->uap_zhp);
free(pool); free(pool);
} }

View File

@ -523,9 +523,6 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
} else if (fmd_nvl_class_match(hdl, fault, } else if (fmd_nvl_class_match(hdl, fault,
"fault.fs.zfs.vdev.checksum")) { "fault.fs.zfs.vdev.checksum")) {
degrade_device = B_TRUE; degrade_device = B_TRUE;
} else if (fmd_nvl_class_match(hdl, fault,
"fault.fs.zfs.vdev.slow_io")) {
degrade_device = B_TRUE;
} else if (fmd_nvl_class_match(hdl, fault, } else if (fmd_nvl_class_match(hdl, fault,
"fault.fs.zfs.device")) { "fault.fs.zfs.device")) {
fault_device = B_FALSE; fault_device = B_FALSE;

View File

@ -9,7 +9,6 @@ dist_zedexec_SCRIPTS = \
%D%/all-debug.sh \ %D%/all-debug.sh \
%D%/all-syslog.sh \ %D%/all-syslog.sh \
%D%/data-notify.sh \ %D%/data-notify.sh \
%D%/deadman-slot_off.sh \
%D%/generic-notify.sh \ %D%/generic-notify.sh \
%D%/pool_import-led.sh \ %D%/pool_import-led.sh \
%D%/resilver_finish-notify.sh \ %D%/resilver_finish-notify.sh \
@ -30,7 +29,6 @@ SUBSTFILES += $(nodist_zedexec_SCRIPTS)
zedconfdefaults = \ zedconfdefaults = \
all-syslog.sh \ all-syslog.sh \
data-notify.sh \ data-notify.sh \
deadman-slot_off.sh \
history_event-zfs-list-cacher.sh \ history_event-zfs-list-cacher.sh \
pool_import-led.sh \ pool_import-led.sh \
resilver_finish-notify.sh \ resilver_finish-notify.sh \

View File

@ -1,71 +0,0 @@
#!/bin/sh
# shellcheck disable=SC3014,SC2154,SC2086,SC2034
#
# Turn off disk's enclosure slot if an I/O is hung triggering the deadman.
#
# It's possible for outstanding I/O to a misbehaving SCSI disk to neither
# promptly complete or return an error. This can occur due to retry and
# recovery actions taken by the SCSI layer, driver, or disk. When it occurs
# the pool will be unresponsive even though there may be sufficient redundancy
# configured to proceeded without this single disk.
#
# When a hung I/O is detected by the kmods it will be posted as a deadman
# event. By default an I/O is considered to be hung after 5 minutes. This
# value can be changed with the zfs_deadman_ziotime_ms module parameter.
# If ZED_POWER_OFF_ENCLOSURE_SLOT_ON_DEADMAN is set the disk's enclosure
# slot will be powered off causing the outstanding I/O to fail. The ZED
# will then handle this like a normal disk failure and FAULT the vdev.
#
# We assume the user will be responsible for turning the slot back on
# after replacing the disk.
#
# Note that this script requires that your enclosure be supported by the
# Linux SCSI Enclosure services (SES) driver. The script will do nothing
# if you have no enclosure, or if your enclosure isn't supported.
#
# Exit codes:
# 0: slot successfully powered off
# 1: enclosure not available
# 2: ZED_POWER_OFF_ENCLOSURE_SLOT_ON_DEADMAN disabled
# 3: System not configured to wait on deadman
# 4: The enclosure sysfs path passed from ZFS does not exist
# 5: Enclosure slot didn't actually turn off after we told it to
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
if [ ! -d /sys/class/enclosure ] ; then
# No JBOD enclosure or NVMe slots
exit 1
fi
if [ "${ZED_POWER_OFF_ENCLOSURE_SLOT_ON_DEADMAN}" != "1" ] ; then
exit 2
fi
if [ "$ZEVENT_POOL_FAILMODE" != "wait" ] ; then
exit 3
fi
if [ ! -f "$ZEVENT_VDEV_ENC_SYSFS_PATH/power_status" ] ; then
exit 4
fi
# Turn off the slot and wait for sysfs to report that the slot is off.
# It can take ~400ms on some enclosures and multiple retries may be needed.
for i in $(seq 1 20) ; do
echo "off" | tee "$ZEVENT_VDEV_ENC_SYSFS_PATH/power_status"
for j in $(seq 1 5) ; do
if [ "$(cat $ZEVENT_VDEV_ENC_SYSFS_PATH/power_status)" == "off" ] ; then
break 2
fi
sleep 0.1
done
done
if [ "$(cat $ZEVENT_VDEV_ENC_SYSFS_PATH/power_status)" != "off" ] ; then
exit 5
fi
zed_log_msg "powered down slot $ZEVENT_VDEV_ENC_SYSFS_PATH for $ZEVENT_VDEV_PATH"

View File

@ -5,7 +5,7 @@
# #
# Bad SCSI disks can often "disappear and reappear" causing all sorts of chaos # Bad SCSI disks can often "disappear and reappear" causing all sorts of chaos
# as they flip between FAULTED and ONLINE. If # as they flip between FAULTED and ONLINE. If
# ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT is set in zed.rc, and the disk gets # ZED_POWER_OFF_ENCLOUSRE_SLOT_ON_FAULT is set in zed.rc, and the disk gets
# FAULTED, then power down the slot via sysfs: # FAULTED, then power down the slot via sysfs:
# #
# /sys/class/enclosure/<enclosure>/<slot>/power_status # /sys/class/enclosure/<enclosure>/<slot>/power_status
@ -19,7 +19,7 @@
# Exit codes: # Exit codes:
# 0: slot successfully powered off # 0: slot successfully powered off
# 1: enclosure not available # 1: enclosure not available
# 2: ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT disabled # 2: ZED_POWER_OFF_ENCLOUSRE_SLOT_ON_FAULT disabled
# 3: vdev was not FAULTED # 3: vdev was not FAULTED
# 4: The enclosure sysfs path passed from ZFS does not exist # 4: The enclosure sysfs path passed from ZFS does not exist
# 5: Enclosure slot didn't actually turn off after we told it to # 5: Enclosure slot didn't actually turn off after we told it to
@ -32,7 +32,7 @@ if [ ! -d /sys/class/enclosure ] ; then
exit 1 exit 1
fi fi
if [ "${ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT}" != "1" ] ; then if [ "${ZED_POWER_OFF_ENCLOUSRE_SLOT_ON_FAULT}" != "1" ] ; then
exit 2 exit 2
fi fi

View File

@ -205,14 +205,6 @@ zed_notify()
[ "${rv}" -eq 0 ] && num_success=$((num_success + 1)) [ "${rv}" -eq 0 ] && num_success=$((num_success + 1))
[ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1)) [ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1))
zed_notify_ntfy "${subject}" "${pathname}"; rv=$?
[ "${rv}" -eq 0 ] && num_success=$((num_success + 1))
[ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1))
zed_notify_gotify "${subject}" "${pathname}"; rv=$?
[ "${rv}" -eq 0 ] && num_success=$((num_success + 1))
[ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1))
[ "${num_success}" -gt 0 ] && return 0 [ "${num_success}" -gt 0 ] && return 0
[ "${num_failure}" -gt 0 ] && return 1 [ "${num_failure}" -gt 0 ] && return 1
return 2 return 2
@ -535,191 +527,6 @@ zed_notify_pushover()
} }
# zed_notify_ntfy (subject, pathname)
#
# Send a notification via Ntfy.sh <https://ntfy.sh/>.
# The ntfy topic (ZED_NTFY_TOPIC) identifies the topic that the notification
# will be sent to Ntfy.sh server. The ntfy url (ZED_NTFY_URL) defines the
# self-hosted or provided hosted ntfy service location. The ntfy access token
# <https://docs.ntfy.sh/publish/#access-tokens> (ZED_NTFY_ACCESS_TOKEN) reprsents an
# access token that could be used if a topic is read/write protected. If a
# topic can be written to publicaly, a ZED_NTFY_ACCESS_TOKEN is not required.
#
# Requires curl and sed executables to be installed in the standard PATH.
#
# References
# https://docs.ntfy.sh
#
# Arguments
# subject: notification subject
# pathname: pathname containing the notification message (OPTIONAL)
#
# Globals
# ZED_NTFY_TOPIC
# ZED_NTFY_ACCESS_TOKEN (OPTIONAL)
# ZED_NTFY_URL
#
# Return
# 0: notification sent
# 1: notification failed
# 2: not configured
#
zed_notify_ntfy()
{
local subject="$1"
local pathname="${2:-"/dev/null"}"
local msg_body
local msg_out
local msg_err
[ -n "${ZED_NTFY_TOPIC}" ] || return 2
local url="${ZED_NTFY_URL:-"https://ntfy.sh"}/${ZED_NTFY_TOPIC}"
if [ ! -r "${pathname}" ]; then
zed_log_err "ntfy cannot read \"${pathname}\""
return 1
fi
zed_check_cmd "curl" "sed" || return 1
# Read the message body in.
#
msg_body="$(cat "${pathname}")"
if [ -z "${msg_body}" ]
then
msg_body=$subject
subject=""
fi
# Send the POST request and check for errors.
#
if [ -n "${ZED_NTFY_ACCESS_TOKEN}" ]; then
msg_out="$( \
curl \
-u ":${ZED_NTFY_ACCESS_TOKEN}" \
-H "Title: ${subject}" \
-d "${msg_body}" \
-H "Priority: high" \
"${url}" \
2>/dev/null \
)"; rv=$?
else
msg_out="$( \
curl \
-H "Title: ${subject}" \
-d "${msg_body}" \
-H "Priority: high" \
"${url}" \
2>/dev/null \
)"; rv=$?
fi
if [ "${rv}" -ne 0 ]; then
zed_log_err "curl exit=${rv}"
return 1
fi
msg_err="$(echo "${msg_out}" \
| sed -n -e 's/.*"errors" *:.*\[\(.*\)\].*/\1/p')"
if [ -n "${msg_err}" ]; then
zed_log_err "ntfy \"${msg_err}"\"
return 1
fi
return 0
}
# zed_notify_gotify (subject, pathname)
#
# Send a notification via Gotify <https://gotify.net/>.
# The Gotify URL (ZED_GOTIFY_URL) defines a self-hosted Gotify location.
# The Gotify application token (ZED_GOTIFY_APPTOKEN) defines a
# Gotify application token which is associated with a message.
# The optional Gotify priority value (ZED_GOTIFY_PRIORITY) overrides the
# default or configured priority at the Gotify server for the application.
#
# Requires curl and sed executables to be installed in the standard PATH.
#
# References
# https://gotify.net/docs/index
#
# Arguments
# subject: notification subject
# pathname: pathname containing the notification message (OPTIONAL)
#
# Globals
# ZED_GOTIFY_URL
# ZED_GOTIFY_APPTOKEN
# ZED_GOTIFY_PRIORITY
#
# Return
# 0: notification sent
# 1: notification failed
# 2: not configured
#
zed_notify_gotify()
{
local subject="$1"
local pathname="${2:-"/dev/null"}"
local msg_body
local msg_out
local msg_err
[ -n "${ZED_GOTIFY_URL}" ] && [ -n "${ZED_GOTIFY_APPTOKEN}" ] || return 2
local url="${ZED_GOTIFY_URL}/message?token=${ZED_GOTIFY_APPTOKEN}"
if [ ! -r "${pathname}" ]; then
zed_log_err "gotify cannot read \"${pathname}\""
return 1
fi
zed_check_cmd "curl" "sed" || return 1
# Read the message body in.
#
msg_body="$(cat "${pathname}")"
if [ -z "${msg_body}" ]
then
msg_body=$subject
subject=""
fi
# Send the POST request and check for errors.
#
if [ -n "${ZED_GOTIFY_PRIORITY}" ]; then
msg_out="$( \
curl \
--form-string "title=${subject}" \
--form-string "message=${msg_body}" \
--form-string "priority=${ZED_GOTIFY_PRIORITY}" \
"${url}" \
2>/dev/null \
)"; rv=$?
else
msg_out="$( \
curl \
--form-string "title=${subject}" \
--form-string "message=${msg_body}" \
"${url}" \
2>/dev/null \
)"; rv=$?
fi
if [ "${rv}" -ne 0 ]; then
zed_log_err "curl exit=${rv}"
return 1
fi
msg_err="$(echo "${msg_out}" \
| sed -n -e 's/.*"errors" *:.*\[\(.*\)\].*/\1/p')"
if [ -n "${msg_err}" ]; then
zed_log_err "gotify \"${msg_err}"\"
return 1
fi
return 0
}
# zed_rate_limit (tag, [interval]) # zed_rate_limit (tag, [interval])
# #
# Check whether an event of a given type [tag] has already occurred within the # Check whether an event of a given type [tag] has already occurred within the

View File

@ -146,54 +146,4 @@ ZED_SYSLOG_SUBCLASS_EXCLUDE="history_event"
# Power off the drive's slot in the enclosure if it becomes FAULTED. This can # Power off the drive's slot in the enclosure if it becomes FAULTED. This can
# help silence misbehaving drives. This assumes your drive enclosure fully # help silence misbehaving drives. This assumes your drive enclosure fully
# supports slot power control via sysfs. # supports slot power control via sysfs.
#ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT=1 #ZED_POWER_OFF_ENCLOUSRE_SLOT_ON_FAULT=1
##
# Power off the drive's slot in the enclosure if there is a hung I/O which
# exceeds the deadman timeout. This can help prevent a single misbehaving
# drive from rendering a redundant pool unavailable. This assumes your drive
# enclosure fully supports slot power control via sysfs.
#ZED_POWER_OFF_ENCLOSURE_SLOT_ON_DEADMAN=1
##
# Ntfy topic
# This defines which topic will receive the ntfy notification.
# <https://docs.ntfy.sh/publish/>
# Disabled by default; uncomment to enable.
#ZED_NTFY_TOPIC=""
##
# Ntfy access token (optional for public topics)
# This defines an access token which can be used
# to allow you to authenticate when sending to topics
# <https://docs.ntfy.sh/publish/#access-tokens>
# Disabled by default; uncomment to enable.
#ZED_NTFY_ACCESS_TOKEN=""
##
# Ntfy Service URL
# This defines which service the ntfy call will be directed toward
# <https://docs.ntfy.sh/install/>
# https://ntfy.sh by default; uncomment to enable an alternative service url.
#ZED_NTFY_URL="https://ntfy.sh"
##
# Gotify server URL
# This defines a URL that the Gotify call will be directed toward.
# <https://gotify.net/docs/index>
# Disabled by default; uncomment to enable.
#ZED_GOTIFY_URL=""
##
# Gotify application token
# This defines a Gotify application token which a message is associated with.
# This token is generated when an application is created on the Gotify server.
# Disabled by default; uncomment to enable.
#ZED_GOTIFY_APPTOKEN=""
##
# Gotify priority (optional)
# If defined, this overrides the default priority of the
# Gotify application associated with ZED_GOTIFY_APPTOKEN.
# Value is an integer 0 and up.
#ZED_GOTIFY_PRIORITY=""

View File

@ -35,7 +35,6 @@
#include "zed_strings.h" #include "zed_strings.h"
#include "agents/zfs_agents.h" #include "agents/zfs_agents.h"
#include <libzutil.h>
#define MAXBUF 4096 #define MAXBUF 4096
@ -923,25 +922,6 @@ _zed_event_add_time_strings(uint64_t eid, zed_strings_t *zsp, int64_t etime[])
} }
} }
static void
_zed_event_update_enc_sysfs_path(nvlist_t *nvl)
{
const char *vdev_path;
if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_PATH,
&vdev_path) != 0) {
return; /* some other kind of event, ignore it */
}
if (vdev_path == NULL) {
return;
}
update_vdev_config_dev_sysfs_path(nvl, vdev_path,
FM_EREPORT_PAYLOAD_ZFS_VDEV_ENC_SYSFS_PATH);
}
/* /*
* Service the next zevent, blocking until one is available. * Service the next zevent, blocking until one is available.
*/ */
@ -989,17 +969,6 @@ zed_event_service(struct zed_conf *zcp)
zed_log_msg(LOG_WARNING, zed_log_msg(LOG_WARNING,
"Failed to lookup zevent class (eid=%llu)", eid); "Failed to lookup zevent class (eid=%llu)", eid);
} else { } else {
/*
* Special case: If we can dynamically detect an enclosure sysfs
* path, then use that value rather than the one stored in the
* vd->vdev_enc_sysfs_path. There have been rare cases where
* vd->vdev_enc_sysfs_path becomes outdated. However, there
* will be other times when we can not dynamically detect the
* sysfs path (like if a disk disappears) and have to rely on
* the old value for things like turning on the fault LED.
*/
_zed_event_update_enc_sysfs_path(nvl);
/* let internal modules see this event first */ /* let internal modules see this event first */
zfs_agent_post_event(class, NULL, nvl); zfs_agent_post_event(class, NULL, nvl);

View File

@ -134,10 +134,6 @@ static int zfs_do_unzone(int argc, char **argv);
static int zfs_do_help(int argc, char **argv); static int zfs_do_help(int argc, char **argv);
enum zfs_options {
ZFS_OPTION_JSON_NUMS_AS_INT = 1024
};
/* /*
* Enable a reasonable set of defaults for libumem debugging on DEBUG builds. * Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
*/ */
@ -276,8 +272,6 @@ static zfs_command_t command_table[] = {
#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0])) #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
#define MAX_CMD_LEN 256
zfs_command_t *current_command; zfs_command_t *current_command;
static const char * static const char *
@ -298,7 +292,7 @@ get_usage(zfs_help_t idx)
"<filesystem|volume>@<snap>[%<snap>][,...]\n" "<filesystem|volume>@<snap>[%<snap>][,...]\n"
"\tdestroy <filesystem|volume>#<bookmark>\n")); "\tdestroy <filesystem|volume>#<bookmark>\n"));
case HELP_GET: case HELP_GET:
return (gettext("\tget [-rHp] [-j [--json-int]] [-d max] " return (gettext("\tget [-rHp] [-d max] "
"[-o \"all\" | field[,...]]\n" "[-o \"all\" | field[,...]]\n"
"\t [-t type[,...]] [-s source[,...]]\n" "\t [-t type[,...]] [-s source[,...]]\n"
"\t <\"all\" | property[,...]> " "\t <\"all\" | property[,...]> "
@ -310,14 +304,12 @@ get_usage(zfs_help_t idx)
return (gettext("\tupgrade [-v]\n" return (gettext("\tupgrade [-v]\n"
"\tupgrade [-r] [-V version] <-a | filesystem ...>\n")); "\tupgrade [-r] [-V version] <-a | filesystem ...>\n"));
case HELP_LIST: case HELP_LIST:
return (gettext("\tlist [-Hp] [-j [--json-int]] [-r|-d max] " return (gettext("\tlist [-Hp] [-r|-d max] [-o property[,...]] "
"[-o property[,...]] [-s property]...\n\t " "[-s property]...\n\t [-S property]... [-t type[,...]] "
"[-S property]... [-t type[,...]] "
"[filesystem|volume|snapshot] ...\n")); "[filesystem|volume|snapshot] ...\n"));
case HELP_MOUNT: case HELP_MOUNT:
return (gettext("\tmount [-j]\n" return (gettext("\tmount\n"
"\tmount [-flvO] [-o opts] <-a|-R filesystem|" "\tmount [-flvO] [-o opts] <-a | filesystem>\n"));
"filesystem>\n"));
case HELP_PROMOTE: case HELP_PROMOTE:
return (gettext("\tpromote <clone-filesystem>\n")); return (gettext("\tpromote <clone-filesystem>\n"));
case HELP_RECEIVE: case HELP_RECEIVE:
@ -427,7 +419,7 @@ get_usage(zfs_help_t idx)
"\t <filesystem|volume>\n" "\t <filesystem|volume>\n"
"\tchange-key -i [-l] <filesystem|volume>\n")); "\tchange-key -i [-l] <filesystem|volume>\n"));
case HELP_VERSION: case HELP_VERSION:
return (gettext("\tversion [-j]\n")); return (gettext("\tversion\n"));
case HELP_REDACT: case HELP_REDACT:
return (gettext("\tredact <snapshot> <bookmark> " return (gettext("\tredact <snapshot> <bookmark> "
"<redaction_snapshot> ...\n")); "<redaction_snapshot> ...\n"));
@ -1892,89 +1884,7 @@ is_recvd_column(zprop_get_cbdata_t *cbp)
} }
/* /*
* Generates an nvlist with output version for every command based on params. * zfs get [-rHp] [-o all | field[,field]...] [-s source[,source]...]
* Purpose of this is to add a version of JSON output, considering the schema
* format might be updated for each command in future.
*
* Schema:
*
* "output_version": {
* "command": string,
* "vers_major": integer,
* "vers_minor": integer,
* }
*/
static nvlist_t *
zfs_json_schema(int maj_v, int min_v)
{
nvlist_t *sch = NULL;
nvlist_t *ov = NULL;
char cmd[MAX_CMD_LEN];
snprintf(cmd, MAX_CMD_LEN, "zfs %s", current_command->name);
sch = fnvlist_alloc();
ov = fnvlist_alloc();
fnvlist_add_string(ov, "command", cmd);
fnvlist_add_uint32(ov, "vers_major", maj_v);
fnvlist_add_uint32(ov, "vers_minor", min_v);
fnvlist_add_nvlist(sch, "output_version", ov);
fnvlist_free(ov);
return (sch);
}
static void
fill_dataset_info(nvlist_t *list, zfs_handle_t *zhp, boolean_t as_int)
{
char createtxg[ZFS_MAXPROPLEN];
zfs_type_t type = zfs_get_type(zhp);
nvlist_add_string(list, "name", zfs_get_name(zhp));
switch (type) {
case ZFS_TYPE_FILESYSTEM:
fnvlist_add_string(list, "type", "FILESYSTEM");
break;
case ZFS_TYPE_VOLUME:
fnvlist_add_string(list, "type", "VOLUME");
break;
case ZFS_TYPE_SNAPSHOT:
fnvlist_add_string(list, "type", "SNAPSHOT");
break;
case ZFS_TYPE_POOL:
fnvlist_add_string(list, "type", "POOL");
break;
case ZFS_TYPE_BOOKMARK:
fnvlist_add_string(list, "type", "BOOKMARK");
break;
default:
fnvlist_add_string(list, "type", "UNKNOWN");
break;
}
if (type != ZFS_TYPE_POOL)
fnvlist_add_string(list, "pool", zfs_get_pool_name(zhp));
if (as_int) {
fnvlist_add_uint64(list, "createtxg", zfs_prop_get_int(zhp,
ZFS_PROP_CREATETXG));
} else {
if (zfs_prop_get(zhp, ZFS_PROP_CREATETXG, createtxg,
sizeof (createtxg), NULL, NULL, 0, B_TRUE) == 0)
fnvlist_add_string(list, "createtxg", createtxg);
}
if (type == ZFS_TYPE_SNAPSHOT) {
char *ds, *snap;
ds = snap = strdup(zfs_get_name(zhp));
ds = strsep(&snap, "@");
fnvlist_add_string(list, "dataset", ds);
fnvlist_add_string(list, "snapshot_name", snap);
free(ds);
}
}
/*
* zfs get [-rHp] [-j [--json-int]] [-o all | field[,field]...]
* [-s source[,source]...]
* < all | property[,property]... > < fs | snap | vol > ... * < all | property[,property]... > < fs | snap | vol > ...
* *
* -r recurse over any child datasets * -r recurse over any child datasets
@ -1987,8 +1897,6 @@ fill_dataset_info(nvlist_t *list, zfs_handle_t *zhp, boolean_t as_int)
* "local,default,inherited,received,temporary,none". Default is * "local,default,inherited,received,temporary,none". Default is
* all six. * all six.
* -p Display values in parsable (literal) format. * -p Display values in parsable (literal) format.
* -j Display output in JSON format.
* --json-int Display numbers as integers instead of strings.
* *
* Prints properties for the given datasets. The user can control which * Prints properties for the given datasets. The user can control which
* columns to display as well as which property types to allow. * columns to display as well as which property types to allow.
@ -2008,21 +1916,9 @@ get_callback(zfs_handle_t *zhp, void *data)
nvlist_t *user_props = zfs_get_user_props(zhp); nvlist_t *user_props = zfs_get_user_props(zhp);
zprop_list_t *pl = cbp->cb_proplist; zprop_list_t *pl = cbp->cb_proplist;
nvlist_t *propval; nvlist_t *propval;
nvlist_t *item, *d, *props;
item = d = props = NULL;
const char *strval; const char *strval;
const char *sourceval; const char *sourceval;
boolean_t received = is_recvd_column(cbp); boolean_t received = is_recvd_column(cbp);
int err = 0;
if (cbp->cb_json) {
d = fnvlist_lookup_nvlist(cbp->cb_jsobj, "datasets");
if (d == NULL) {
fprintf(stderr, "datasets obj not found.\n");
exit(1);
}
props = fnvlist_alloc();
}
for (; pl != NULL; pl = pl->pl_next) { for (; pl != NULL; pl = pl->pl_next) {
char *recvdval = NULL; char *recvdval = NULL;
@ -2057,9 +1953,9 @@ get_callback(zfs_handle_t *zhp, void *data)
cbp->cb_literal) == 0)) cbp->cb_literal) == 0))
recvdval = rbuf; recvdval = rbuf;
err = zprop_collect_property(zfs_get_name(zhp), cbp, zprop_print_one_property(zfs_get_name(zhp), cbp,
zfs_prop_to_name(pl->pl_prop), zfs_prop_to_name(pl->pl_prop),
buf, sourcetype, source, recvdval, props); buf, sourcetype, source, recvdval);
} else if (zfs_prop_userquota(pl->pl_user_prop)) { } else if (zfs_prop_userquota(pl->pl_user_prop)) {
sourcetype = ZPROP_SRC_LOCAL; sourcetype = ZPROP_SRC_LOCAL;
@ -2069,9 +1965,8 @@ get_callback(zfs_handle_t *zhp, void *data)
(void) strlcpy(buf, "-", sizeof (buf)); (void) strlcpy(buf, "-", sizeof (buf));
} }
err = zprop_collect_property(zfs_get_name(zhp), cbp, zprop_print_one_property(zfs_get_name(zhp), cbp,
pl->pl_user_prop, buf, sourcetype, source, NULL, pl->pl_user_prop, buf, sourcetype, source, NULL);
props);
} else if (zfs_prop_written(pl->pl_user_prop)) { } else if (zfs_prop_written(pl->pl_user_prop)) {
sourcetype = ZPROP_SRC_LOCAL; sourcetype = ZPROP_SRC_LOCAL;
@ -2081,9 +1976,8 @@ get_callback(zfs_handle_t *zhp, void *data)
(void) strlcpy(buf, "-", sizeof (buf)); (void) strlcpy(buf, "-", sizeof (buf));
} }
err = zprop_collect_property(zfs_get_name(zhp), cbp, zprop_print_one_property(zfs_get_name(zhp), cbp,
pl->pl_user_prop, buf, sourcetype, source, NULL, pl->pl_user_prop, buf, sourcetype, source, NULL);
props);
} else { } else {
if (nvlist_lookup_nvlist(user_props, if (nvlist_lookup_nvlist(user_props,
pl->pl_user_prop, &propval) != 0) { pl->pl_user_prop, &propval) != 0) {
@ -2115,24 +2009,9 @@ get_callback(zfs_handle_t *zhp, void *data)
cbp->cb_literal) == 0)) cbp->cb_literal) == 0))
recvdval = rbuf; recvdval = rbuf;
err = zprop_collect_property(zfs_get_name(zhp), cbp, zprop_print_one_property(zfs_get_name(zhp), cbp,
pl->pl_user_prop, strval, sourcetype, pl->pl_user_prop, strval, sourcetype,
source, recvdval, props); source, recvdval);
}
if (err != 0)
return (err);
}
if (cbp->cb_json) {
if (!nvlist_empty(props)) {
item = fnvlist_alloc();
fill_dataset_info(item, zhp, cbp->cb_json_as_int);
fnvlist_add_nvlist(item, "properties", props);
fnvlist_add_nvlist(d, zfs_get_name(zhp), item);
fnvlist_free(props);
fnvlist_free(item);
} else {
fnvlist_free(props);
} }
} }
@ -2149,7 +2028,6 @@ zfs_do_get(int argc, char **argv)
int ret = 0; int ret = 0;
int limit = 0; int limit = 0;
zprop_list_t fake_name = { 0 }; zprop_list_t fake_name = { 0 };
nvlist_t *data;
/* /*
* Set up default columns and sources. * Set up default columns and sources.
@ -2161,14 +2039,8 @@ zfs_do_get(int argc, char **argv)
cb.cb_columns[3] = GET_COL_SOURCE; cb.cb_columns[3] = GET_COL_SOURCE;
cb.cb_type = ZFS_TYPE_DATASET; cb.cb_type = ZFS_TYPE_DATASET;
struct option long_options[] = {
{"json-int", no_argument, NULL, ZFS_OPTION_JSON_NUMS_AS_INT},
{0, 0, 0, 0}
};
/* check options */ /* check options */
while ((c = getopt_long(argc, argv, ":d:o:s:jrt:Hp", long_options, while ((c = getopt(argc, argv, ":d:o:s:rt:Hp")) != -1) {
NULL)) != -1) {
switch (c) { switch (c) {
case 'p': case 'p':
cb.cb_literal = B_TRUE; cb.cb_literal = B_TRUE;
@ -2182,17 +2054,6 @@ zfs_do_get(int argc, char **argv)
case 'H': case 'H':
cb.cb_scripted = B_TRUE; cb.cb_scripted = B_TRUE;
break; break;
case 'j':
cb.cb_json = B_TRUE;
cb.cb_jsobj = zfs_json_schema(0, 1);
data = fnvlist_alloc();
fnvlist_add_nvlist(cb.cb_jsobj, "datasets", data);
fnvlist_free(data);
break;
case ZFS_OPTION_JSON_NUMS_AS_INT:
cb.cb_json_as_int = B_TRUE;
cb.cb_literal = B_TRUE;
break;
case ':': case ':':
(void) fprintf(stderr, gettext("missing argument for " (void) fprintf(stderr, gettext("missing argument for "
"'%c' option\n"), optopt); "'%c' option\n"), optopt);
@ -2284,25 +2145,15 @@ found2:;
for (char *tok; (tok = strsep(&optarg, ",")); ) { for (char *tok; (tok = strsep(&optarg, ",")); ) {
static const char *const type_opts[] = { static const char *const type_opts[] = {
"filesystem", "filesystem", "volume",
"fs", "snapshot", "snap",
"volume",
"vol",
"snapshot",
"snap",
"bookmark", "bookmark",
"all" "all" };
};
static const int type_types[] = { static const int type_types[] = {
ZFS_TYPE_FILESYSTEM, ZFS_TYPE_FILESYSTEM, ZFS_TYPE_VOLUME,
ZFS_TYPE_FILESYSTEM, ZFS_TYPE_SNAPSHOT, ZFS_TYPE_SNAPSHOT,
ZFS_TYPE_VOLUME,
ZFS_TYPE_VOLUME,
ZFS_TYPE_SNAPSHOT,
ZFS_TYPE_SNAPSHOT,
ZFS_TYPE_BOOKMARK, ZFS_TYPE_BOOKMARK,
ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK };
};
for (i = 0; i < ARRAY_SIZE(type_opts); ++i) for (i = 0; i < ARRAY_SIZE(type_opts); ++i)
if (strcmp(tok, type_opts[i]) == 0) { if (strcmp(tok, type_opts[i]) == 0) {
@ -2316,6 +2167,7 @@ found2:;
found3:; found3:;
} }
break; break;
case '?': case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"), (void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt); optopt);
@ -2332,12 +2184,6 @@ found3:;
usage(B_FALSE); usage(B_FALSE);
} }
if (!cb.cb_json && cb.cb_json_as_int) {
(void) fprintf(stderr, gettext("'--json-int' only works with"
" '-j' option\n"));
usage(B_FALSE);
}
fields = argv[0]; fields = argv[0];
/* /*
@ -2378,11 +2224,6 @@ found3:;
ret = zfs_for_each(argc, argv, flags, types, NULL, ret = zfs_for_each(argc, argv, flags, types, NULL,
&cb.cb_proplist, limit, get_callback, &cb); &cb.cb_proplist, limit, get_callback, &cb);
if (ret == 0 && cb.cb_json)
zcmd_print_json(cb.cb_jsobj);
else if (ret != 0 && cb.cb_json)
nvlist_free(cb.cb_jsobj);
if (cb.cb_proplist == &fake_name) if (cb.cb_proplist == &fake_name)
zprop_free_list(fake_name.pl_next); zprop_free_list(fake_name.pl_next);
else else
@ -3590,9 +3431,6 @@ typedef struct list_cbdata {
boolean_t cb_literal; boolean_t cb_literal;
boolean_t cb_scripted; boolean_t cb_scripted;
zprop_list_t *cb_proplist; zprop_list_t *cb_proplist;
boolean_t cb_json;
nvlist_t *cb_jsobj;
boolean_t cb_json_as_int;
} list_cbdata_t; } list_cbdata_t;
/* /*
@ -3663,11 +3501,10 @@ zfs_list_avail_color(zfs_handle_t *zhp)
/* /*
* 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, or return an nvlist containing all the fields, later * to the described layout.
* to be printed out as JSON object.
*/ */
static void static void
collect_dataset(zfs_handle_t *zhp, list_cbdata_t *cb) print_dataset(zfs_handle_t *zhp, list_cbdata_t *cb)
{ {
zprop_list_t *pl = cb->cb_proplist; zprop_list_t *pl = cb->cb_proplist;
boolean_t first = B_TRUE; boolean_t first = B_TRUE;
@ -3676,23 +3513,9 @@ collect_dataset(zfs_handle_t *zhp, list_cbdata_t *cb)
nvlist_t *propval; nvlist_t *propval;
const char *propstr; const char *propstr;
boolean_t right_justify; boolean_t right_justify;
nvlist_t *item, *d, *props;
item = d = props = NULL;
zprop_source_t sourcetype = ZPROP_SRC_NONE;
char source[ZFS_MAX_DATASET_NAME_LEN];
if (cb->cb_json) {
d = fnvlist_lookup_nvlist(cb->cb_jsobj, "datasets");
if (d == NULL) {
fprintf(stderr, "datasets obj not found.\n");
exit(1);
}
item = fnvlist_alloc();
props = fnvlist_alloc();
fill_dataset_info(item, zhp, cb->cb_json_as_int);
}
for (; pl != NULL; pl = pl->pl_next) { for (; pl != NULL; pl = pl->pl_next) {
if (!cb->cb_json && !first) { if (!first) {
if (cb->cb_scripted) if (cb->cb_scripted)
(void) putchar('\t'); (void) putchar('\t');
else else
@ -3708,112 +3531,69 @@ collect_dataset(zfs_handle_t *zhp, list_cbdata_t *cb)
right_justify = zfs_prop_align_right(pl->pl_prop); right_justify = zfs_prop_align_right(pl->pl_prop);
} else if (pl->pl_prop != ZPROP_USERPROP) { } else if (pl->pl_prop != ZPROP_USERPROP) {
if (zfs_prop_get(zhp, pl->pl_prop, property, if (zfs_prop_get(zhp, pl->pl_prop, property,
sizeof (property), &sourcetype, source, sizeof (property), NULL, NULL, 0,
sizeof (source), cb->cb_literal) != 0) cb->cb_literal) != 0)
propstr = "-"; propstr = "-";
else else
propstr = property; propstr = property;
right_justify = zfs_prop_align_right(pl->pl_prop); right_justify = zfs_prop_align_right(pl->pl_prop);
} else if (zfs_prop_userquota(pl->pl_user_prop)) { } else if (zfs_prop_userquota(pl->pl_user_prop)) {
sourcetype = ZPROP_SRC_LOCAL;
if (zfs_prop_get_userquota(zhp, pl->pl_user_prop, if (zfs_prop_get_userquota(zhp, pl->pl_user_prop,
property, sizeof (property), cb->cb_literal) != 0) { property, sizeof (property), cb->cb_literal) != 0)
sourcetype = ZPROP_SRC_NONE;
propstr = "-"; propstr = "-";
} else { else
propstr = property; propstr = property;
}
right_justify = B_TRUE; right_justify = B_TRUE;
} else if (zfs_prop_written(pl->pl_user_prop)) { } else if (zfs_prop_written(pl->pl_user_prop)) {
sourcetype = ZPROP_SRC_LOCAL;
if (zfs_prop_get_written(zhp, pl->pl_user_prop, if (zfs_prop_get_written(zhp, pl->pl_user_prop,
property, sizeof (property), cb->cb_literal) != 0) { property, sizeof (property), cb->cb_literal) != 0)
sourcetype = ZPROP_SRC_NONE;
propstr = "-"; propstr = "-";
} else { else
propstr = property; propstr = property;
}
right_justify = B_TRUE; right_justify = B_TRUE;
} else { } else {
if (nvlist_lookup_nvlist(userprops, if (nvlist_lookup_nvlist(userprops,
pl->pl_user_prop, &propval) != 0) { pl->pl_user_prop, &propval) != 0)
propstr = "-"; propstr = "-";
} else { else
propstr = fnvlist_lookup_string(propval, propstr = fnvlist_lookup_string(propval,
ZPROP_VALUE); ZPROP_VALUE);
strlcpy(source,
fnvlist_lookup_string(propval,
ZPROP_SOURCE), ZFS_MAX_DATASET_NAME_LEN);
if (strcmp(source,
zfs_get_name(zhp)) == 0) {
sourcetype = ZPROP_SRC_LOCAL;
} else if (strcmp(source,
ZPROP_SOURCE_VAL_RECVD) == 0) {
sourcetype = ZPROP_SRC_RECEIVED;
} else {
sourcetype = ZPROP_SRC_INHERITED;
}
}
right_justify = B_FALSE; right_justify = B_FALSE;
} }
if (cb->cb_json) { /*
if (pl->pl_prop == ZFS_PROP_NAME) * zfs_list_avail_color() needs ZFS_PROP_AVAILABLE + USED
continue; * - so we need another for() search for the USED part
if (zprop_nvlist_one_property( * - when no colors wanted, we can skip the whole thing
zfs_prop_to_name(pl->pl_prop), propstr, */
sourcetype, source, NULL, props, if (use_color() && pl->pl_prop == ZFS_PROP_AVAILABLE) {
cb->cb_json_as_int) != 0) zprop_list_t *pl2 = cb->cb_proplist;
nomem(); for (; pl2 != NULL; pl2 = pl2->pl_next) {
} else { if (pl2->pl_prop == ZFS_PROP_USED) {
/* color_start(zfs_list_avail_color(zhp));
* zfs_list_avail_color() needs /* found it, no need for more loops */
* ZFS_PROP_AVAILABLE + USED, so we need another break;
* for() search for the USED part when no colors
* wanted, we can skip the whole thing
*/
if (use_color() && pl->pl_prop == ZFS_PROP_AVAILABLE) {
zprop_list_t *pl2 = cb->cb_proplist;
for (; pl2 != NULL; pl2 = pl2->pl_next) {
if (pl2->pl_prop == ZFS_PROP_USED) {
color_start(
zfs_list_avail_color(zhp));
/*
* found it, no need for more
* loops
*/
break;
}
} }
} }
/*
* If this is being called in scripted mode, or if
* this is the last column and it is left-justified,
* don't include a width format specifier.
*/
if (cb->cb_scripted || (pl->pl_next == NULL &&
!right_justify))
(void) fputs(propstr, stdout);
else if (right_justify) {
(void) printf("%*s", (int)pl->pl_width,
propstr);
} else {
(void) printf("%-*s", (int)pl->pl_width,
propstr);
}
if (pl->pl_prop == ZFS_PROP_AVAILABLE)
color_end();
} }
/*
* 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
* format specifier.
*/
if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
(void) fputs(propstr, stdout);
else if (right_justify)
(void) printf("%*s", (int)pl->pl_width, propstr);
else
(void) printf("%-*s", (int)pl->pl_width, propstr);
if (pl->pl_prop == ZFS_PROP_AVAILABLE)
color_end();
} }
if (cb->cb_json) {
fnvlist_add_nvlist(item, "properties", props); (void) putchar('\n');
fnvlist_add_nvlist(d, zfs_get_name(zhp), item);
fnvlist_free(props);
fnvlist_free(item);
} else
(void) putchar('\n');
} }
/* /*
@ -3825,12 +3605,12 @@ list_callback(zfs_handle_t *zhp, void *data)
list_cbdata_t *cbp = data; list_cbdata_t *cbp = data;
if (cbp->cb_first) { if (cbp->cb_first) {
if (!cbp->cb_scripted && !cbp->cb_json) if (!cbp->cb_scripted)
print_header(cbp); print_header(cbp);
cbp->cb_first = B_FALSE; cbp->cb_first = B_FALSE;
} }
collect_dataset(zhp, cbp); print_dataset(zhp, cbp);
return (0); return (0);
} }
@ -3849,16 +3629,9 @@ zfs_do_list(int argc, char **argv)
int ret = 0; int ret = 0;
zfs_sort_column_t *sortcol = NULL; zfs_sort_column_t *sortcol = NULL;
int flags = ZFS_ITER_PROP_LISTSNAPS | ZFS_ITER_ARGS_CAN_BE_PATHS; int flags = ZFS_ITER_PROP_LISTSNAPS | ZFS_ITER_ARGS_CAN_BE_PATHS;
nvlist_t *data = NULL;
struct option long_options[] = {
{"json-int", no_argument, NULL, ZFS_OPTION_JSON_NUMS_AS_INT},
{0, 0, 0, 0}
};
/* check options */ /* check options */
while ((c = getopt_long(argc, argv, "jHS:d:o:prs:t:", long_options, while ((c = getopt(argc, argv, "HS:d:o:prs:t:")) != -1) {
NULL)) != -1) {
switch (c) { switch (c) {
case 'o': case 'o':
fields = optarg; fields = optarg;
@ -3873,17 +3646,6 @@ zfs_do_list(int argc, char **argv)
case 'r': case 'r':
flags |= ZFS_ITER_RECURSE; flags |= ZFS_ITER_RECURSE;
break; break;
case 'j':
cb.cb_json = B_TRUE;
cb.cb_jsobj = zfs_json_schema(0, 1);
data = fnvlist_alloc();
fnvlist_add_nvlist(cb.cb_jsobj, "datasets", data);
fnvlist_free(data);
break;
case ZFS_OPTION_JSON_NUMS_AS_INT:
cb.cb_json_as_int = B_TRUE;
cb.cb_literal = B_TRUE;
break;
case 'H': case 'H':
cb.cb_scripted = B_TRUE; cb.cb_scripted = B_TRUE;
break; break;
@ -3910,25 +3672,15 @@ zfs_do_list(int argc, char **argv)
for (char *tok; (tok = strsep(&optarg, ",")); ) { for (char *tok; (tok = strsep(&optarg, ",")); ) {
static const char *const type_subopts[] = { static const char *const type_subopts[] = {
"filesystem", "filesystem", "volume",
"fs", "snapshot", "snap",
"volume",
"vol",
"snapshot",
"snap",
"bookmark", "bookmark",
"all" "all" };
};
static const int type_types[] = { static const int type_types[] = {
ZFS_TYPE_FILESYSTEM, ZFS_TYPE_FILESYSTEM, ZFS_TYPE_VOLUME,
ZFS_TYPE_FILESYSTEM, ZFS_TYPE_SNAPSHOT, ZFS_TYPE_SNAPSHOT,
ZFS_TYPE_VOLUME,
ZFS_TYPE_VOLUME,
ZFS_TYPE_SNAPSHOT,
ZFS_TYPE_SNAPSHOT,
ZFS_TYPE_BOOKMARK, ZFS_TYPE_BOOKMARK,
ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK };
};
for (c = 0; c < ARRAY_SIZE(type_subopts); ++c) for (c = 0; c < ARRAY_SIZE(type_subopts); ++c)
if (strcmp(tok, type_subopts[c]) == 0) { if (strcmp(tok, type_subopts[c]) == 0) {
@ -3957,12 +3709,6 @@ found3:;
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (!cb.cb_json && cb.cb_json_as_int) {
(void) fprintf(stderr, gettext("'--json-int' only works with"
" '-j' option\n"));
usage(B_FALSE);
}
/* /*
* If "-o space" and no types were specified, don't display snapshots. * If "-o space" and no types were specified, don't display snapshots.
*/ */
@ -4002,11 +3748,6 @@ found3:;
ret = zfs_for_each(argc, argv, flags, types, sortcol, &cb.cb_proplist, ret = zfs_for_each(argc, argv, flags, types, sortcol, &cb.cb_proplist,
limit, list_callback, &cb); limit, list_callback, &cb);
if (ret == 0 && cb.cb_json)
zcmd_print_json(cb.cb_jsobj);
else if (ret != 0 && cb.cb_json)
nvlist_free(cb.cb_jsobj);
zprop_free_list(cb.cb_proplist); zprop_free_list(cb.cb_proplist);
zfs_free_sort_columns(sortcol); zfs_free_sort_columns(sortcol);
@ -7003,8 +6744,6 @@ zfs_do_holds(int argc, char **argv)
#define MOUNT_TIME 1 /* seconds */ #define MOUNT_TIME 1 /* seconds */
typedef struct get_all_state { typedef struct get_all_state {
char **ga_datasets;
int ga_count;
boolean_t ga_verbose; boolean_t ga_verbose;
get_all_cb_t *ga_cbp; get_all_cb_t *ga_cbp;
} get_all_state_t; } get_all_state_t;
@ -7051,35 +6790,19 @@ get_one_dataset(zfs_handle_t *zhp, void *data)
return (0); return (0);
} }
static int
get_recursive_datasets(zfs_handle_t *zhp, void *data)
{
get_all_state_t *state = data;
int len = strlen(zfs_get_name(zhp));
for (int i = 0; i < state->ga_count; ++i) {
if (strcmp(state->ga_datasets[i], zfs_get_name(zhp)) == 0)
return (get_one_dataset(zhp, data));
else if ((strncmp(state->ga_datasets[i], zfs_get_name(zhp),
len) == 0) && state->ga_datasets[i][len] == '/') {
(void) zfs_iter_filesystems_v2(zhp, 0,
get_recursive_datasets, data);
}
}
zfs_close(zhp);
return (0);
}
static void static void
get_all_datasets(get_all_state_t *state) get_all_datasets(get_all_cb_t *cbp, boolean_t verbose)
{ {
if (state->ga_verbose) get_all_state_t state = {
set_progress_header(gettext("Reading ZFS config")); .ga_verbose = verbose,
if (state->ga_datasets == NULL) .ga_cbp = cbp
(void) zfs_iter_root(g_zfs, get_one_dataset, state); };
else
(void) zfs_iter_root(g_zfs, get_recursive_datasets, state);
if (state->ga_verbose) if (verbose)
set_progress_header(gettext("Reading ZFS config"));
(void) zfs_iter_root(g_zfs, get_one_dataset, &state);
if (verbose)
finish_progress(gettext("done.")); finish_progress(gettext("done."));
} }
@ -7425,38 +7148,24 @@ static int
share_mount(int op, int argc, char **argv) share_mount(int op, int argc, char **argv)
{ {
int do_all = 0; int do_all = 0;
int recursive = 0;
boolean_t verbose = B_FALSE; boolean_t verbose = B_FALSE;
boolean_t json = B_FALSE;
int c, ret = 0; int c, ret = 0;
char *options = NULL; char *options = NULL;
int flags = 0; int flags = 0;
nvlist_t *jsobj, *data, *item;
const uint_t mount_nthr = 512;
uint_t nthr;
jsobj = data = item = NULL;
/* check options */ /* check options */
while ((c = getopt(argc, argv, op == OP_MOUNT ? ":ajRlvo:Of" : "al")) while ((c = getopt(argc, argv, op == OP_MOUNT ? ":alvo:Of" : "al"))
!= -1) { != -1) {
switch (c) { switch (c) {
case 'a': case 'a':
do_all = 1; do_all = 1;
break; break;
case 'R':
recursive = 1;
break;
case 'v': case 'v':
verbose = B_TRUE; verbose = B_TRUE;
break; break;
case 'l': case 'l':
flags |= MS_CRYPT; flags |= MS_CRYPT;
break; break;
case 'j':
json = B_TRUE;
jsobj = zfs_json_schema(0, 1);
data = fnvlist_alloc();
break;
case 'o': case 'o':
if (*optarg == '\0') { if (*optarg == '\0') {
(void) fprintf(stderr, gettext("empty mount " (void) fprintf(stderr, gettext("empty mount "
@ -7491,13 +7200,8 @@ share_mount(int op, int argc, char **argv)
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (json && argc != 0) {
(void) fprintf(stderr, gettext("too many arguments\n"));
usage(B_FALSE);
}
/* check number of arguments */ /* check number of arguments */
if (do_all || recursive) { if (do_all) {
enum sa_protocol protocol = SA_NO_PROTOCOL; enum sa_protocol protocol = SA_NO_PROTOCOL;
if (op == OP_SHARE && argc > 0) { if (op == OP_SHARE && argc > 0) {
@ -7506,38 +7210,14 @@ share_mount(int op, int argc, char **argv)
argv++; argv++;
} }
if (argc != 0 && do_all) { if (argc != 0) {
(void) fprintf(stderr, gettext("too many arguments\n")); (void) fprintf(stderr, gettext("too many arguments\n"));
usage(B_FALSE); usage(B_FALSE);
} }
if (argc == 0 && recursive) {
(void) fprintf(stderr,
gettext("no dataset provided\n"));
usage(B_FALSE);
}
start_progress_timer(); start_progress_timer();
get_all_cb_t cb = { 0 }; get_all_cb_t cb = { 0 };
get_all_state_t state = { 0 }; get_all_datasets(&cb, verbose);
if (argc == 0) {
state.ga_datasets = NULL;
state.ga_count = -1;
} else {
zfs_handle_t *zhp;
for (int i = 0; i < argc; i++) {
zhp = zfs_open(g_zfs, argv[i],
ZFS_TYPE_FILESYSTEM);
if (zhp == NULL)
usage(B_FALSE);
zfs_close(zhp);
}
state.ga_datasets = argv;
state.ga_count = argc;
}
state.ga_verbose = verbose;
state.ga_cbp = &cb;
get_all_datasets(&state);
if (cb.cb_used == 0) { if (cb.cb_used == 0) {
free(options); free(options);
@ -7554,8 +7234,7 @@ share_mount(int op, int argc, char **argv)
pthread_mutex_init(&share_mount_state.sm_lock, NULL); pthread_mutex_init(&share_mount_state.sm_lock, NULL);
/* For a 'zfs share -a' operation start with a clean slate. */ /* For a 'zfs share -a' operation start with a clean slate. */
if (op == OP_SHARE) zfs_truncate_shares(NULL);
zfs_truncate_shares(NULL);
/* /*
* libshare isn't mt-safe, so only do the operation in parallel * libshare isn't mt-safe, so only do the operation in parallel
@ -7563,9 +7242,9 @@ share_mount(int op, int argc, char **argv)
* be serialized so that we can prompt the user for their keys * be serialized so that we can prompt the user for their keys
* in a consistent manner. * in a consistent manner.
*/ */
nthr = op == OP_MOUNT && !(flags & MS_CRYPT) ? mount_nthr : 1;
zfs_foreach_mountpoint(g_zfs, cb.cb_handles, cb.cb_used, zfs_foreach_mountpoint(g_zfs, cb.cb_handles, cb.cb_used,
share_mount_one_cb, &share_mount_state, nthr); share_mount_one_cb, &share_mount_state,
op == OP_MOUNT && !(flags & MS_CRYPT));
zfs_commit_shares(NULL); zfs_commit_shares(NULL);
ret = share_mount_state.sm_status; ret = share_mount_state.sm_status;
@ -7599,30 +7278,12 @@ share_mount(int op, int argc, char **argv)
if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0 || if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0 ||
strchr(entry.mnt_special, '@') != NULL) strchr(entry.mnt_special, '@') != NULL)
continue; continue;
if (json) {
item = fnvlist_alloc(); (void) printf("%-30s %s\n", entry.mnt_special,
fnvlist_add_string(item, "filesystem", entry.mnt_mountp);
entry.mnt_special);
fnvlist_add_string(item, "mountpoint",
entry.mnt_mountp);
fnvlist_add_nvlist(data, entry.mnt_special,
item);
fnvlist_free(item);
} else {
(void) printf("%-30s %s\n", entry.mnt_special,
entry.mnt_mountp);
}
} }
(void) fclose(mnttab); (void) fclose(mnttab);
if (json) {
fnvlist_add_nvlist(jsobj, "datasets", data);
if (nvlist_empty(data))
fnvlist_free(jsobj);
else
zcmd_print_json(jsobj);
fnvlist_free(data);
}
} else { } else {
zfs_handle_t *zhp; zfs_handle_t *zhp;
@ -9080,39 +8741,8 @@ found:;
static int static int
zfs_do_version(int argc, char **argv) zfs_do_version(int argc, char **argv)
{ {
int c; (void) argc, (void) argv;
nvlist_t *jsobj = NULL, *zfs_ver = NULL; return (zfs_version_print() != 0);
boolean_t json = B_FALSE;
while ((c = getopt(argc, argv, "j")) != -1) {
switch (c) {
case 'j':
json = B_TRUE;
jsobj = zfs_json_schema(0, 1);
break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
usage(B_FALSE);
}
}
argc -= optind;
if (argc != 0) {
(void) fprintf(stderr, "too many arguments\n");
usage(B_FALSE);
}
if (json) {
zfs_ver = zfs_version_nvlist();
if (zfs_ver) {
fnvlist_add_nvlist(jsobj, "zfs_version", zfs_ver);
zcmd_print_json(jsobj);
fnvlist_free(zfs_ver);
return (0);
} else
return (-1);
} else
return (zfs_version_print() != 0);
} }
/* Display documentation */ /* Display documentation */

View File

@ -612,8 +612,8 @@ zhack_repair_undetach(uberblock_t *ub, nvlist_t *cfg, const int l)
* Uberblock root block pointer has valid birth TXG. * Uberblock root block pointer has valid birth TXG.
* Copying it to the label NVlist * Copying it to the label NVlist
*/ */
if (BP_GET_LOGICAL_BIRTH(&ub->ub_rootbp) != 0) { if (ub->ub_rootbp.blk_birth != 0) {
const uint64_t txg = BP_GET_LOGICAL_BIRTH(&ub->ub_rootbp); const uint64_t txg = ub->ub_rootbp.blk_birth;
ub->ub_txg = txg; ub->ub_txg = txg;
if (nvlist_remove_all(cfg, ZPOOL_CONFIG_CREATE_TXG) != 0) { if (nvlist_remove_all(cfg, ZPOOL_CONFIG_CREATE_TXG) != 0) {

View File

@ -43,9 +43,6 @@ cols = {
"obj": [12, -1, "objset"], "obj": [12, -1, "objset"],
"cc": [5, 1000, "zil_commit_count"], "cc": [5, 1000, "zil_commit_count"],
"cwc": [5, 1000, "zil_commit_writer_count"], "cwc": [5, 1000, "zil_commit_writer_count"],
"cec": [5, 1000, "zil_commit_error_count"],
"csc": [5, 1000, "zil_commit_stall_count"],
"cSc": [5, 1000, "zil_commit_suspend_count"],
"ic": [5, 1000, "zil_itx_count"], "ic": [5, 1000, "zil_itx_count"],
"iic": [5, 1000, "zil_itx_indirect_count"], "iic": [5, 1000, "zil_itx_indirect_count"],
"iib": [5, 1024, "zil_itx_indirect_bytes"], "iib": [5, 1024, "zil_itx_indirect_bytes"],

View File

@ -22,7 +22,6 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2017, Intel Corporation. * Copyright (c) 2017, Intel Corporation.
* Copyright (c) 2023-2024, Klara Inc.
*/ */
/* /*
@ -209,38 +208,6 @@ type_to_name(uint64_t type)
} }
} }
struct errstr {
int err;
const char *str;
};
static const struct errstr errstrtable[] = {
{ EIO, "io" },
{ ECKSUM, "checksum" },
{ EINVAL, "decompress" },
{ EACCES, "decrypt" },
{ ENXIO, "nxio" },
{ ECHILD, "dtl" },
{ EILSEQ, "corrupt" },
{ ENOSYS, "noop" },
{ 0, NULL },
};
static int
str_to_err(const char *str)
{
for (int i = 0; errstrtable[i].str != NULL; i++)
if (strcasecmp(errstrtable[i].str, str) == 0)
return (errstrtable[i].err);
return (-1);
}
static const char *
err_to_str(int err)
{
for (int i = 0; errstrtable[i].str != NULL; i++)
if (errstrtable[i].err == err)
return (errstrtable[i].str);
return ("[unknown]");
}
/* /*
* Print usage message. * Print usage message.
@ -266,12 +233,12 @@ usage(void)
"\t\tspa_vdev_exit() will trigger a panic.\n" "\t\tspa_vdev_exit() will trigger a panic.\n"
"\n" "\n"
"\tzinject -d device [-e errno] [-L <nvlist|uber|pad1|pad2>] [-F]\n" "\tzinject -d device [-e errno] [-L <nvlist|uber|pad1|pad2>] [-F]\n"
"\t\t[-T <read|write|free|claim|flush|all>] [-f frequency] pool\n\n" "\t\t[-T <read|write|free|claim|all>] [-f frequency] pool\n\n"
"\t\tInject a fault into a particular device or the device's\n" "\t\tInject a fault into a particular device or the device's\n"
"\t\tlabel. Label injection can either be 'nvlist', 'uber',\n " "\t\tlabel. Label injection can either be 'nvlist', 'uber',\n "
"\t\t'pad1', or 'pad2'.\n" "\t\t'pad1', or 'pad2'.\n"
"\t\t'errno' can be 'nxio' (the default), 'io', 'dtl',\n" "\t\t'errno' can be 'nxio' (the default), 'io', 'dtl', or\n"
"\t\t'corrupt' (bit flip), or 'noop' (successfully do nothing).\n" "\t\t'corrupt' (bit flip).\n"
"\t\t'frequency' is a value between 0.0001 and 100.0 that limits\n" "\t\t'frequency' is a value between 0.0001 and 100.0 that limits\n"
"\t\tdevice error injection to a percentage of the IOs.\n" "\t\tdevice error injection to a percentage of the IOs.\n"
"\n" "\n"
@ -310,11 +277,6 @@ usage(void)
"\t\tcreate 3 lanes on the device; one lane with a latency\n" "\t\tcreate 3 lanes on the device; one lane with a latency\n"
"\t\tof 10 ms and two lanes with a 25 ms latency.\n" "\t\tof 10 ms and two lanes with a 25 ms latency.\n"
"\n" "\n"
"\tzinject -P import|export -s <seconds> pool\n"
"\t\tAdd an artificial delay to a future pool import or export,\n"
"\t\tsuch that the operation takes a minimum of supplied seconds\n"
"\t\tto complete.\n"
"\n"
"\tzinject -I [-s <seconds> | -g <txgs>] pool\n" "\tzinject -I [-s <seconds> | -g <txgs>] pool\n"
"\t\tCause the pool to stop writing blocks yet not\n" "\t\tCause the pool to stop writing blocks yet not\n"
"\t\treport errors for a duration. Simulates buggy hardware\n" "\t\treport errors for a duration. Simulates buggy hardware\n"
@ -397,10 +359,8 @@ print_data_handler(int id, const char *pool, zinject_record_t *record,
{ {
int *count = data; int *count = data;
if (record->zi_guid != 0 || record->zi_func[0] != '\0' || if (record->zi_guid != 0 || record->zi_func[0] != '\0')
record->zi_duration != 0) {
return (0); return (0);
}
if (*count == 0) { if (*count == 0) {
(void) printf("%3s %-15s %-6s %-6s %-8s %3s %-4s " (void) printf("%3s %-15s %-6s %-6s %-8s %3s %-4s "
@ -432,10 +392,6 @@ static int
print_device_handler(int id, const char *pool, zinject_record_t *record, print_device_handler(int id, const char *pool, zinject_record_t *record,
void *data) void *data)
{ {
static const char *iotypestr[] = {
"null", "read", "write", "free", "claim", "flush", "trim", "all",
};
int *count = data; int *count = data;
if (record->zi_guid == 0 || record->zi_func[0] != '\0') if (record->zi_guid == 0 || record->zi_func[0] != '\0')
@ -445,21 +401,14 @@ print_device_handler(int id, const char *pool, zinject_record_t *record,
return (0); return (0);
if (*count == 0) { if (*count == 0) {
(void) printf("%3s %-15s %-16s %-5s %-10s %-9s\n", (void) printf("%3s %-15s %s\n", "ID", "POOL", "GUID");
"ID", "POOL", "GUID", "TYPE", "ERROR", "FREQ"); (void) printf("--- --------------- ----------------\n");
(void) printf(
"--- --------------- ---------------- "
"----- ---------- ---------\n");
} }
*count += 1; *count += 1;
double freq = record->zi_freq == 0 ? 100.0f : (void) printf("%3d %-15s %llx\n", id, pool,
(((double)record->zi_freq) / ZI_PERCENTAGE_MAX) * 100.0f; (u_longlong_t)record->zi_guid);
(void) printf("%3d %-15s %llx %-5s %-10s %8.4f%%\n", id, pool,
(u_longlong_t)record->zi_guid, iotypestr[record->zi_iotype],
err_to_str(record->zi_error), freq);
return (0); return (0);
} }
@ -514,33 +463,6 @@ print_panic_handler(int id, const char *pool, zinject_record_t *record,
return (0); return (0);
} }
static int
print_pool_delay_handler(int id, const char *pool, zinject_record_t *record,
void *data)
{
int *count = data;
if (record->zi_cmd != ZINJECT_DELAY_IMPORT &&
record->zi_cmd != ZINJECT_DELAY_EXPORT) {
return (0);
}
if (*count == 0) {
(void) printf("%3s %-19s %-11s %s\n",
"ID", "POOL", "DELAY (sec)", "COMMAND");
(void) printf("--- ------------------- -----------"
" -------\n");
}
*count += 1;
(void) printf("%3d %-19s %-11llu %s\n",
id, pool, (u_longlong_t)record->zi_duration,
record->zi_cmd == ZINJECT_DELAY_IMPORT ? "import": "export");
return (0);
}
/* /*
* Print all registered error handlers. Returns the number of handlers * Print all registered error handlers. Returns the number of handlers
* registered. * registered.
@ -571,13 +493,6 @@ print_all_handlers(void)
count = 0; count = 0;
} }
(void) iter_handlers(print_pool_delay_handler, &count);
if (count > 0) {
total += count;
(void) printf("\n");
count = 0;
}
(void) iter_handlers(print_panic_handler, &count); (void) iter_handlers(print_panic_handler, &count);
return (count + total); return (count + total);
@ -650,27 +565,9 @@ register_handler(const char *pool, int flags, zinject_record_t *record,
zc.zc_guid = flags; zc.zc_guid = flags;
if (zfs_ioctl(g_zfs, ZFS_IOC_INJECT_FAULT, &zc) != 0) { if (zfs_ioctl(g_zfs, ZFS_IOC_INJECT_FAULT, &zc) != 0) {
const char *errmsg = strerror(errno); (void) fprintf(stderr, "failed to add handler: %s\n",
errno == EDOM ? "block level exceeds max level of object" :
switch (errno) { strerror(errno));
case EDOM:
errmsg = "block level exceeds max level of object";
break;
case EEXIST:
if (record->zi_cmd == ZINJECT_DELAY_IMPORT)
errmsg = "pool already imported";
if (record->zi_cmd == ZINJECT_DELAY_EXPORT)
errmsg = "a handler already exists";
break;
case ENOENT:
/* import delay injector running on older zfs module */
if (record->zi_cmd == ZINJECT_DELAY_IMPORT)
errmsg = "import delay injector not supported";
break;
default:
break;
}
(void) fprintf(stderr, "failed to add handler: %s\n", errmsg);
return (1); return (1);
} }
@ -695,9 +592,6 @@ register_handler(const char *pool, int flags, zinject_record_t *record,
} else if (record->zi_duration < 0) { } else if (record->zi_duration < 0) {
(void) printf(" txgs: %lld \n", (void) printf(" txgs: %lld \n",
(u_longlong_t)-record->zi_duration); (u_longlong_t)-record->zi_duration);
} else if (record->zi_timer > 0) {
(void) printf(" timer: %lld ms\n",
(u_longlong_t)NSEC2MSEC(record->zi_timer));
} else { } else {
(void) printf("objset: %llu\n", (void) printf("objset: %llu\n",
(u_longlong_t)record->zi_objset); (u_longlong_t)record->zi_objset);
@ -896,7 +790,7 @@ main(int argc, char **argv)
} }
while ((c = getopt(argc, argv, while ((c = getopt(argc, argv,
":aA:b:C:d:D:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:P:")) != -1) { ":aA:b:C:d:D:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:")) != -1) {
switch (c) { switch (c) {
case 'a': case 'a':
flags |= ZINJECT_FLUSH_ARC; flags |= ZINJECT_FLUSH_ARC;
@ -948,12 +842,24 @@ main(int argc, char **argv)
} }
break; break;
case 'e': case 'e':
error = str_to_err(optarg); if (strcasecmp(optarg, "io") == 0) {
if (error < 0) { error = EIO;
} else if (strcasecmp(optarg, "checksum") == 0) {
error = ECKSUM;
} else if (strcasecmp(optarg, "decompress") == 0) {
error = EINVAL;
} else if (strcasecmp(optarg, "decrypt") == 0) {
error = EACCES;
} else if (strcasecmp(optarg, "nxio") == 0) {
error = ENXIO;
} else if (strcasecmp(optarg, "dtl") == 0) {
error = ECHILD;
} else if (strcasecmp(optarg, "corrupt") == 0) {
error = EILSEQ;
} else {
(void) fprintf(stderr, "invalid error type " (void) fprintf(stderr, "invalid error type "
"'%s': must be one of: io decompress " "'%s': must be 'io', 'checksum' or "
"decrypt nxio dtl corrupt noop\n", "'nxio'\n", optarg);
optarg);
usage(); usage();
libzfs_fini(g_zfs); libzfs_fini(g_zfs);
return (1); return (1);
@ -1014,19 +920,6 @@ main(int argc, char **argv)
sizeof (record.zi_func)); sizeof (record.zi_func));
record.zi_cmd = ZINJECT_PANIC; record.zi_cmd = ZINJECT_PANIC;
break; break;
case 'P':
if (strcasecmp(optarg, "import") == 0) {
record.zi_cmd = ZINJECT_DELAY_IMPORT;
} else if (strcasecmp(optarg, "export") == 0) {
record.zi_cmd = ZINJECT_DELAY_EXPORT;
} else {
(void) fprintf(stderr, "invalid command '%s': "
"must be 'import' or 'export'\n", optarg);
usage();
libzfs_fini(g_zfs);
return (1);
}
break;
case 'q': case 'q':
quiet = 1; quiet = 1;
break; break;
@ -1054,14 +947,12 @@ main(int argc, char **argv)
io_type = ZIO_TYPE_FREE; io_type = ZIO_TYPE_FREE;
} else if (strcasecmp(optarg, "claim") == 0) { } else if (strcasecmp(optarg, "claim") == 0) {
io_type = ZIO_TYPE_CLAIM; io_type = ZIO_TYPE_CLAIM;
} else if (strcasecmp(optarg, "flush") == 0) {
io_type = ZIO_TYPE_FLUSH;
} else if (strcasecmp(optarg, "all") == 0) { } else if (strcasecmp(optarg, "all") == 0) {
io_type = ZIO_TYPES; io_type = ZIO_TYPES;
} else { } else {
(void) fprintf(stderr, "invalid I/O type " (void) fprintf(stderr, "invalid I/O type "
"'%s': must be 'read', 'write', 'free', " "'%s': must be 'read', 'write', 'free', "
"'claim', 'flush' or 'all'\n", optarg); "'claim' or 'all'\n", optarg);
usage(); usage();
libzfs_fini(g_zfs); libzfs_fini(g_zfs);
return (1); return (1);
@ -1108,7 +999,7 @@ main(int argc, char **argv)
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (record.zi_duration != 0 && record.zi_cmd == 0) if (record.zi_duration != 0)
record.zi_cmd = ZINJECT_IGNORED_WRITES; record.zi_cmd = ZINJECT_IGNORED_WRITES;
if (cancel != NULL) { if (cancel != NULL) {
@ -1192,22 +1083,6 @@ main(int argc, char **argv)
libzfs_fini(g_zfs); libzfs_fini(g_zfs);
return (1); return (1);
} }
if (record.zi_nlanes) {
switch (io_type) {
case ZIO_TYPE_READ:
case ZIO_TYPE_WRITE:
case ZIO_TYPES:
break;
default:
(void) fprintf(stderr, "I/O type for a delay "
"must be 'read' or 'write'\n");
usage();
libzfs_fini(g_zfs);
return (1);
}
}
if (!error) if (!error)
error = ENXIO; error = ENXIO;
@ -1254,8 +1129,8 @@ main(int argc, char **argv)
if (raw != NULL || range != NULL || type != TYPE_INVAL || if (raw != NULL || range != NULL || type != TYPE_INVAL ||
level != 0 || device != NULL || record.zi_freq > 0 || level != 0 || device != NULL || record.zi_freq > 0 ||
dvas != 0) { dvas != 0) {
(void) fprintf(stderr, "%s incompatible with other " (void) fprintf(stderr, "panic (-p) incompatible with "
"options\n", "import|export delay (-P)"); "other options\n");
usage(); usage();
libzfs_fini(g_zfs); libzfs_fini(g_zfs);
return (2); return (2);
@ -1273,28 +1148,6 @@ main(int argc, char **argv)
if (argv[1] != NULL) if (argv[1] != NULL)
record.zi_type = atoi(argv[1]); record.zi_type = atoi(argv[1]);
dataset[0] = '\0'; dataset[0] = '\0';
} else if (record.zi_cmd == ZINJECT_DELAY_IMPORT ||
record.zi_cmd == ZINJECT_DELAY_EXPORT) {
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
level != 0 || device != NULL || record.zi_freq > 0 ||
dvas != 0) {
(void) fprintf(stderr, "%s incompatible with other "
"options\n", "import|export delay (-P)");
usage();
libzfs_fini(g_zfs);
return (2);
}
if (argc != 1 || record.zi_duration <= 0) {
(void) fprintf(stderr, "import|export delay (-P) "
"injection requires a duration (-s) and a single "
"pool name\n");
usage();
libzfs_fini(g_zfs);
return (2);
}
(void) strlcpy(pool, argv[0], sizeof (pool));
} else if (record.zi_cmd == ZINJECT_IGNORED_WRITES) { } else if (record.zi_cmd == ZINJECT_IGNORED_WRITES) {
if (raw != NULL || range != NULL || type != TYPE_INVAL || if (raw != NULL || range != NULL || type != TYPE_INVAL ||
level != 0 || record.zi_freq > 0 || dvas != 0) { level != 0 || record.zi_freq > 0 || dvas != 0) {

View File

@ -1,9 +1,6 @@
# Features which are supported by GRUB2 # Features which are supported by GRUB2
allocation_classes
async_destroy async_destroy
block_cloning
bookmarks bookmarks
device_rebuild
embedded_data embedded_data
empty_bpobj empty_bpobj
enabled_txg enabled_txg
@ -12,12 +9,6 @@ filesystem_limits
hole_birth hole_birth
large_blocks large_blocks
livelist livelist
log_spacemap
lz4_compress lz4_compress
project_quota
resilver_defer
spacemap_histogram spacemap_histogram
spacemap_v2
userobj_accounting
zilsaxattr
zpool_checkpoint zpool_checkpoint

View File

@ -6,6 +6,7 @@ edonr
embedded_data embedded_data
empty_bpobj empty_bpobj
enabled_txg enabled_txg
encryption
extensible_dataset extensible_dataset
filesystem_limits filesystem_limits
hole_birth hole_birth

View File

@ -124,24 +124,3 @@ check_file(const char *file, boolean_t force, boolean_t isspare)
{ {
return (check_file_generic(file, force, isspare)); return (check_file_generic(file, force, isspare));
} }
int
zpool_power_current_state(zpool_handle_t *zhp, char *vdev)
{
(void) zhp;
(void) vdev;
/* Enclosure slot power not supported on FreeBSD yet */
return (-1);
}
int
zpool_power(zpool_handle_t *zhp, char *vdev, boolean_t turn_on)
{
(void) zhp;
(void) vdev;
(void) turn_on;
/* Enclosure slot power not supported on FreeBSD yet */
return (ENOTSUP);
}

View File

@ -416,258 +416,3 @@ check_file(const char *file, boolean_t force, boolean_t isspare)
{ {
return (check_file_generic(file, force, isspare)); return (check_file_generic(file, force, isspare));
} }
/*
* Read from a sysfs file and return an allocated string. Removes
* the newline from the end of the string if there is one.
*
* Returns a string on success (which must be freed), or NULL on error.
*/
static char *zpool_sysfs_gets(char *path)
{
int fd;
struct stat statbuf;
char *buf = NULL;
ssize_t count = 0;
fd = open(path, O_RDONLY);
if (fd < 0)
return (NULL);
if (fstat(fd, &statbuf) != 0) {
close(fd);
return (NULL);
}
buf = calloc(statbuf.st_size + 1, sizeof (*buf));
if (buf == NULL) {
close(fd);
return (NULL);
}
/*
* Note, we can read less bytes than st_size, and that's ok. Sysfs
* files will report their size is 4k even if they only return a small
* string.
*/
count = read(fd, buf, statbuf.st_size);
if (count < 0) {
/* Error doing read() or we overran the buffer */
close(fd);
free(buf);
return (NULL);
}
/* Remove trailing newline */
if (count > 0 && buf[count - 1] == '\n')
buf[count - 1] = 0;
close(fd);
return (buf);
}
/*
* Write a string to a sysfs file.
*
* Returns 0 on success, non-zero otherwise.
*/
static int zpool_sysfs_puts(char *path, char *str)
{
FILE *file;
file = fopen(path, "w");
if (!file) {
return (-1);
}
if (fputs(str, file) < 0) {
fclose(file);
return (-2);
}
fclose(file);
return (0);
}
/* Given a vdev nvlist_t, rescan its enclosure sysfs path */
static void
rescan_vdev_config_dev_sysfs_path(nvlist_t *vdev_nv)
{
update_vdev_config_dev_sysfs_path(vdev_nv,
fnvlist_lookup_string(vdev_nv, ZPOOL_CONFIG_PATH),
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
}
/*
* Given a power string: "on", "off", "1", or "0", return 0 if it's an
* off value, 1 if it's an on value, and -1 if the value is unrecognized.
*/
static int zpool_power_parse_value(char *str)
{
if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0))
return (0);
if ((strcmp(str, "on") == 0) || (strcmp(str, "1") == 0))
return (1);
return (-1);
}
/*
* Given a vdev string return an allocated string containing the sysfs path to
* its power control file. Also do a check if the power control file really
* exists and has correct permissions.
*
* Example returned strings:
*
* /sys/class/enclosure/0:0:122:0/10/power_status
* /sys/bus/pci/slots/10/power
*
* Returns allocated string on success (which must be freed), NULL on failure.
*/
static char *
zpool_power_sysfs_path(zpool_handle_t *zhp, char *vdev)
{
const char *enc_sysfs_dir = NULL;
char *path = NULL;
nvlist_t *vdev_nv = zpool_find_vdev(zhp, vdev, NULL, NULL, NULL);
if (vdev_nv == NULL) {
return (NULL);
}
/* Make sure we're getting the updated enclosure sysfs path */
rescan_vdev_config_dev_sysfs_path(vdev_nv);
if (nvlist_lookup_string(vdev_nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
&enc_sysfs_dir) != 0) {
return (NULL);
}
if (asprintf(&path, "%s/power_status", enc_sysfs_dir) == -1)
return (NULL);
if (access(path, W_OK) != 0) {
free(path);
path = NULL;
/* No HDD 'power_control' file, maybe it's NVMe? */
if (asprintf(&path, "%s/power", enc_sysfs_dir) == -1) {
return (NULL);
}
if (access(path, R_OK | W_OK) != 0) {
/* Not NVMe either */
free(path);
return (NULL);
}
}
return (path);
}
/*
* Given a path to a sysfs power control file, return B_TRUE if you should use
* "on/off" words to control it, or B_FALSE otherwise ("0/1" to control).
*/
static boolean_t
zpool_power_use_word(char *sysfs_path)
{
if (strcmp(&sysfs_path[strlen(sysfs_path) - strlen("power_status")],
"power_status") == 0) {
return (B_TRUE);
}
return (B_FALSE);
}
/*
* Check the sysfs power control value for a vdev.
*
* Returns:
* 0 - Power is off
* 1 - Power is on
* -1 - Error or unsupported
*/
int
zpool_power_current_state(zpool_handle_t *zhp, char *vdev)
{
char *val;
int rc;
char *path = zpool_power_sysfs_path(zhp, vdev);
if (path == NULL)
return (-1);
val = zpool_sysfs_gets(path);
if (val == NULL) {
free(path);
return (-1);
}
rc = zpool_power_parse_value(val);
free(val);
free(path);
return (rc);
}
/*
* Turn on or off the slot to a device
*
* Device path is the full path to the device (like /dev/sda or /dev/sda1).
*
* Return code:
* 0: Success
* ENOTSUP: Power control not supported for OS
* EBADSLT: Couldn't read current power state
* ENOENT: No sysfs path to power control
* EIO: Couldn't write sysfs power value
* EBADE: Sysfs power value didn't change
*/
int
zpool_power(zpool_handle_t *zhp, char *vdev, boolean_t turn_on)
{
char *sysfs_path;
const char *val;
int rc;
int timeout_ms;
rc = zpool_power_current_state(zhp, vdev);
if (rc == -1) {
return (EBADSLT);
}
/* Already correct value? */
if (rc == (int)turn_on)
return (0);
sysfs_path = zpool_power_sysfs_path(zhp, vdev);
if (sysfs_path == NULL)
return (ENOENT);
if (zpool_power_use_word(sysfs_path)) {
val = turn_on ? "on" : "off";
} else {
val = turn_on ? "1" : "0";
}
rc = zpool_sysfs_puts(sysfs_path, (char *)val);
free(sysfs_path);
if (rc != 0) {
return (EIO);
}
/*
* Wait up to 30 seconds for sysfs power value to change after
* writing it.
*/
timeout_ms = zpool_getenv_int("ZPOOL_POWER_ON_SLOT_TIMEOUT_MS", 30000);
for (int i = 0; i < MAX(1, timeout_ms / 200); i++) {
rc = zpool_power_current_state(zhp, vdev);
if (rc == (int)turn_on)
return (0); /* success */
fsleep(0.200); /* 200ms */
}
/* sysfs value never changed */
return (EBADE);
}

View File

@ -33,18 +33,10 @@ for i in $scripts ; do
val="" val=""
case $i in case $i in
enc) enc)
if echo "$VDEV_ENC_SYSFS_PATH" | grep -q '/sys/bus/pci/slots' ; then val=$(ls "$VDEV_ENC_SYSFS_PATH/../../" 2>/dev/null)
val="$VDEV_ENC_SYSFS_PATH"
else
val="$(ls """$VDEV_ENC_SYSFS_PATH/../../""" 2>/dev/null)"
fi
;; ;;
slot) slot)
if echo "$VDEV_ENC_SYSFS_PATH" | grep -q '/sys/bus/pci/slots' ; then val=$(cat "$VDEV_ENC_SYSFS_PATH/slot" 2>/dev/null)
val="$(basename """$VDEV_ENC_SYSFS_PATH""")"
else
val="$(cat """$VDEV_ENC_SYSFS_PATH/slot""" 2>/dev/null)"
fi
;; ;;
encdev) encdev)
val=$(ls "$VDEV_ENC_SYSFS_PATH/../device/scsi_generic" 2>/dev/null) val=$(ls "$VDEV_ENC_SYSFS_PATH/../device/scsi_generic" 2>/dev/null)

View File

@ -554,10 +554,6 @@ for_each_vdev_run_cb(void *zhp_data, nvlist_t *nv, void *cb_vcdl)
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0) if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0)
return (1); return (1);
/* Make sure we're getting the updated enclosure sysfs path */
update_vdev_config_dev_sysfs_path(nv, path,
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
nvlist_lookup_string(nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH, nvlist_lookup_string(nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
&vdev_enc_sysfs_path); &vdev_enc_sysfs_path);

File diff suppressed because it is too large Load Diff

View File

@ -138,9 +138,6 @@ int check_file(const char *file, boolean_t force, boolean_t isspare);
void after_zpool_upgrade(zpool_handle_t *zhp); void after_zpool_upgrade(zpool_handle_t *zhp);
int check_file_generic(const char *file, boolean_t force, boolean_t isspare); int check_file_generic(const char *file, boolean_t force, boolean_t isspare);
int zpool_power(zpool_handle_t *zhp, char *vdev, boolean_t turn_on);
int zpool_power_current_state(zpool_handle_t *zhp, char *vdev);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -372,10 +372,6 @@ make_leaf_vdev(nvlist_t *props, const char *arg, boolean_t is_primary)
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_PATH, path) == 0); verify(nvlist_add_string(vdev, ZPOOL_CONFIG_PATH, path) == 0);
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 0); verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 0);
/* Lookup and add the enclosure sysfs path (if exists) */
update_vdev_config_dev_sysfs_path(vdev, path,
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
if (strcmp(type, VDEV_TYPE_DISK) == 0) if (strcmp(type, VDEV_TYPE_DISK) == 0)
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK, verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
(uint64_t)wholedisk) == 0); (uint64_t)wholedisk) == 0);

View File

@ -1,5 +1,3 @@
zstream_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS)
sbin_PROGRAMS += zstream sbin_PROGRAMS += zstream
CPPCHECKTARGETS += zstream CPPCHECKTARGETS += zstream

View File

@ -22,8 +22,6 @@
/* /*
* Copyright 2022 Axcient. All rights reserved. * Copyright 2022 Axcient. All rights reserved.
* Use is subject to license terms. * Use is subject to license terms.
*
* Copyright (c) 2024, Klara, Inc.
*/ */
#include <err.h> #include <err.h>
@ -259,73 +257,83 @@ zstream_do_decompress(int argc, char *argv[])
ENTRY e = {.key = key}; ENTRY e = {.key = key};
p = hsearch(e, FIND); p = hsearch(e, FIND);
if (p == NULL) { if (p != NULL) {
zio_decompress_func_t *xfunc = NULL;
switch ((enum zio_compress)(intptr_t)p->data) {
case ZIO_COMPRESS_OFF:
xfunc = NULL;
break;
case ZIO_COMPRESS_LZJB:
xfunc = lzjb_decompress;
break;
case ZIO_COMPRESS_GZIP_1:
xfunc = gzip_decompress;
break;
case ZIO_COMPRESS_ZLE:
xfunc = zle_decompress;
break;
case ZIO_COMPRESS_LZ4:
xfunc = lz4_decompress_zfs;
break;
case ZIO_COMPRESS_ZSTD:
xfunc = zfs_zstd_decompress;
break;
default:
assert(B_FALSE);
}
/*
* Read and decompress the block
*/
char *lzbuf = safe_calloc(payload_size);
(void) sfread(lzbuf, payload_size, stdin);
if (xfunc == NULL) {
memcpy(buf, lzbuf, payload_size);
drrw->drr_compressiontype =
ZIO_COMPRESS_OFF;
if (verbose)
fprintf(stderr, "Resetting "
"compression type to off "
"for ino %llu offset "
"%llu\n",
(u_longlong_t)
drrw->drr_object,
(u_longlong_t)
drrw->drr_offset);
} else if (0 != xfunc(lzbuf, buf,
payload_size, payload_size, 0)) {
/*
* The block must not be compressed,
* at least not with this compression
* type, possibly because it gets
* written multiple times in this
* stream.
*/
warnx("decompression failed for "
"ino %llu offset %llu",
(u_longlong_t)drrw->drr_object,
(u_longlong_t)drrw->drr_offset);
memcpy(buf, lzbuf, payload_size);
} else if (verbose) {
drrw->drr_compressiontype =
ZIO_COMPRESS_OFF;
fprintf(stderr, "successfully "
"decompressed ino %llu "
"offset %llu\n",
(u_longlong_t)drrw->drr_object,
(u_longlong_t)drrw->drr_offset);
} else {
drrw->drr_compressiontype =
ZIO_COMPRESS_OFF;
}
free(lzbuf);
} else {
/* /*
* Read the contents of the block unaltered * Read the contents of the block unaltered
*/ */
(void) sfread(buf, payload_size, stdin); (void) sfread(buf, payload_size, stdin);
break;
} }
/*
* Read and decompress the block
*/
enum zio_compress c =
(enum zio_compress)(intptr_t)p->data;
if (c == ZIO_COMPRESS_OFF) {
(void) sfread(buf, payload_size, stdin);
drrw->drr_compressiontype = 0;
drrw->drr_compressed_size = 0;
if (verbose)
fprintf(stderr,
"Resetting compression type to "
"off for ino %llu offset %llu\n",
(u_longlong_t)drrw->drr_object,
(u_longlong_t)drrw->drr_offset);
break;
}
uint64_t lsize = drrw->drr_logical_size;
ASSERT3U(payload_size, <=, lsize);
char *lzbuf = safe_calloc(payload_size);
(void) sfread(lzbuf, payload_size, stdin);
abd_t sabd, dabd;
abd_get_from_buf_struct(&sabd, lzbuf, payload_size);
abd_get_from_buf_struct(&dabd, buf, lsize);
int err = zio_decompress_data(c, &sabd, &dabd,
payload_size, lsize, NULL);
abd_free(&dabd);
abd_free(&sabd);
if (err == 0) {
drrw->drr_compressiontype = 0;
drrw->drr_compressed_size = 0;
payload_size = lsize;
if (verbose) {
fprintf(stderr,
"successfully decompressed "
"ino %llu offset %llu\n",
(u_longlong_t)drrw->drr_object,
(u_longlong_t)drrw->drr_offset);
}
} else {
/*
* The block must not be compressed, at least
* not with this compression type, possibly
* because it gets written multiple times in
* this stream.
*/
warnx("decompression failed for "
"ino %llu offset %llu",
(u_longlong_t)drrw->drr_object,
(u_longlong_t)drrw->drr_offset);
memcpy(buf, lzbuf, payload_size);
}
free(lzbuf);
break; break;
} }

View File

@ -22,9 +22,10 @@
/* /*
* Copyright 2022 Axcient. All rights reserved. * Copyright 2022 Axcient. All rights reserved.
* Use is subject to license terms. * Use is subject to license terms.
* */
/*
* Copyright (c) 2022 by Delphix. All rights reserved. * Copyright (c) 2022 by Delphix. All rights reserved.
* Copyright (c) 2024, Klara, Inc.
*/ */
#include <err.h> #include <err.h>
@ -71,12 +72,12 @@ zstream_do_recompress(int argc, char *argv[])
dmu_replay_record_t *drr = &thedrr; dmu_replay_record_t *drr = &thedrr;
zio_cksum_t stream_cksum; zio_cksum_t stream_cksum;
int c; int c;
int level = 0; int level = -1;
while ((c = getopt(argc, argv, "l:")) != -1) { while ((c = getopt(argc, argv, "l:")) != -1) {
switch (c) { switch (c) {
case 'l': case 'l':
if (sscanf(optarg, "%d", &level) != 1) { if (sscanf(optarg, "%d", &level) != 0) {
fprintf(stderr, fprintf(stderr,
"failed to parse level '%s'\n", "failed to parse level '%s'\n",
optarg); optarg);
@ -96,22 +97,34 @@ zstream_do_recompress(int argc, char *argv[])
if (argc != 1) if (argc != 1)
zstream_usage(); zstream_usage();
int type = 0;
enum zio_compress ctype; zio_compress_info_t *cinfo = NULL;
if (strcmp(argv[0], "off") == 0) { if (0 == strcmp(argv[0], "off")) {
ctype = ZIO_COMPRESS_OFF; type = ZIO_COMPRESS_OFF;
cinfo = &zio_compress_table[type];
} else if (0 == strcmp(argv[0], "inherit") ||
0 == strcmp(argv[0], "empty") ||
0 == strcmp(argv[0], "on")) {
// Fall through to invalid compression type case
} else { } else {
for (ctype = 0; ctype < ZIO_COMPRESS_FUNCTIONS; ctype++) { for (int i = 0; i < ZIO_COMPRESS_FUNCTIONS; i++) {
if (strcmp(argv[0], if (0 == strcmp(zio_compress_table[i].ci_name,
zio_compress_table[ctype].ci_name) == 0) argv[0])) {
cinfo = &zio_compress_table[i];
type = i;
break; break;
}
} }
if (ctype == ZIO_COMPRESS_FUNCTIONS || }
zio_compress_table[ctype].ci_compress == NULL) { if (cinfo == NULL) {
fprintf(stderr, "Invalid compression type %s.\n", fprintf(stderr, "Invalid compression type %s.\n",
argv[0]); argv[0]);
exit(2); exit(2);
} }
if (cinfo->ci_compress == NULL) {
type = 0;
cinfo = &zio_compress_table[0];
} }
if (isatty(STDIN_FILENO)) { if (isatty(STDIN_FILENO)) {
@ -122,7 +135,6 @@ zstream_do_recompress(int argc, char *argv[])
exit(1); exit(1);
} }
abd_init();
fletcher_4_init(); fletcher_4_init();
zio_init(); zio_init();
zstd_init(); zstd_init();
@ -235,78 +247,63 @@ zstream_do_recompress(int argc, char *argv[])
(void) sfread(buf, payload_size, stdin); (void) sfread(buf, payload_size, stdin);
break; break;
} }
enum zio_compress dtype = drrw->drr_compressiontype; if (drrw->drr_compressiontype >=
if (dtype >= ZIO_COMPRESS_FUNCTIONS) { ZIO_COMPRESS_FUNCTIONS) {
fprintf(stderr, "Invalid compression type in " fprintf(stderr, "Invalid compression type in "
"stream: %d\n", dtype); "stream: %d\n", drrw->drr_compressiontype);
exit(3); exit(3);
} }
if (zio_compress_table[dtype].ci_decompress == NULL) zio_compress_info_t *dinfo =
dtype = ZIO_COMPRESS_OFF; &zio_compress_table[drrw->drr_compressiontype];
/* Set up buffers to minimize memcpys */ /* Set up buffers to minimize memcpys */
char *cbuf, *dbuf; char *cbuf, *dbuf;
if (ctype == ZIO_COMPRESS_OFF) if (cinfo->ci_compress == NULL)
dbuf = buf; dbuf = buf;
else else
dbuf = safe_calloc(bufsz); dbuf = safe_calloc(bufsz);
if (dtype == ZIO_COMPRESS_OFF) if (dinfo->ci_decompress == NULL)
cbuf = dbuf; cbuf = dbuf;
else else
cbuf = safe_calloc(payload_size); cbuf = safe_calloc(payload_size);
/* Read and decompress the payload */ /* Read and decompress the payload */
(void) sfread(cbuf, payload_size, stdin); (void) sfread(cbuf, payload_size, stdin);
if (dtype != ZIO_COMPRESS_OFF) { if (dinfo->ci_decompress != NULL) {
abd_t cabd, dabd; if (0 != dinfo->ci_decompress(cbuf, dbuf,
abd_get_from_buf_struct(&cabd, payload_size, MIN(bufsz,
cbuf, payload_size); drrw->drr_logical_size), dinfo->ci_level)) {
abd_get_from_buf_struct(&dabd, dbuf,
MIN(bufsz, drrw->drr_logical_size));
if (zio_decompress_data(dtype, &cabd, &dabd,
payload_size, abd_get_size(&dabd),
NULL) != 0) {
warnx("decompression type %d failed " warnx("decompression type %d failed "
"for ino %llu offset %llu", "for ino %llu offset %llu",
dtype, type,
(u_longlong_t)drrw->drr_object, (u_longlong_t)drrw->drr_object,
(u_longlong_t)drrw->drr_offset); (u_longlong_t)drrw->drr_offset);
exit(4); exit(4);
} }
payload_size = drrw->drr_logical_size; payload_size = drrw->drr_logical_size;
abd_free(&dabd);
abd_free(&cabd);
free(cbuf); free(cbuf);
} }
/* Recompress the payload */ /* Recompress the payload */
if (ctype != ZIO_COMPRESS_OFF) { if (cinfo->ci_compress != NULL) {
abd_t dabd, abd; payload_size = P2ROUNDUP(cinfo->ci_compress(
abd_get_from_buf_struct(&dabd, dbuf, buf, drrw->drr_logical_size,
dbuf, drrw->drr_logical_size); MIN(payload_size, bufsz), (level == -1 ?
abd_t *pabd = cinfo->ci_level : level)),
abd_get_from_buf_struct(&abd, buf, bufsz); SPA_MINBLOCKSIZE);
size_t csize = zio_compress_data(ctype, &dabd, if (payload_size != drrw->drr_logical_size) {
&pabd, drrw->drr_logical_size, level); drrw->drr_compressiontype = type;
size_t rounded = drrw->drr_compressed_size =
P2ROUNDUP(csize, SPA_MINBLOCKSIZE); payload_size;
if (rounded >= drrw->drr_logical_size) { } else {
memcpy(buf, dbuf, payload_size); memcpy(buf, dbuf, payload_size);
drrw->drr_compressiontype = 0; drrw->drr_compressiontype = 0;
drrw->drr_compressed_size = 0; drrw->drr_compressed_size = 0;
} else {
abd_zero_off(pabd, csize,
rounded - csize);
drrw->drr_compressiontype = ctype;
drrw->drr_compressed_size =
payload_size = rounded;
} }
abd_free(&abd);
abd_free(&dabd);
free(dbuf); free(dbuf);
} else { } else {
drrw->drr_compressiontype = 0; drrw->drr_compressiontype = type;
drrw->drr_compressed_size = 0; drrw->drr_compressed_size = 0;
} }
break; break;
@ -374,7 +371,6 @@ zstream_do_recompress(int argc, char *argv[])
fletcher_4_fini(); fletcher_4_fini();
zio_fini(); zio_fini();
zstd_fini(); zstd_fini();
abd_fini();
return (0); return (0);
} }

View File

@ -56,6 +56,15 @@ typedef struct redup_table {
int numhashbits; int numhashbits;
} redup_table_t; } redup_table_t;
int
highbit64(uint64_t i)
{
if (i == 0)
return (0);
return (NBBY * sizeof (uint64_t) - __builtin_clzll(i));
}
void * void *
safe_calloc(size_t n) safe_calloc(size_t n)
{ {
@ -177,7 +186,7 @@ static void
zfs_redup_stream(int infd, int outfd, boolean_t verbose) zfs_redup_stream(int infd, int outfd, boolean_t verbose)
{ {
int bufsz = SPA_MAXBLOCKSIZE; int bufsz = SPA_MAXBLOCKSIZE;
dmu_replay_record_t thedrr; dmu_replay_record_t thedrr = { 0 };
dmu_replay_record_t *drr = &thedrr; dmu_replay_record_t *drr = &thedrr;
redup_table_t rdt; redup_table_t rdt;
zio_cksum_t stream_cksum; zio_cksum_t stream_cksum;
@ -185,8 +194,6 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
uint64_t num_records = 0; uint64_t num_records = 0;
uint64_t num_write_byref_records = 0; uint64_t num_write_byref_records = 0;
memset(&thedrr, 0, sizeof (dmu_replay_record_t));
#ifdef _ILP32 #ifdef _ILP32
uint64_t max_rde_size = SMALLEST_POSSIBLE_MAX_RDT_MB << 20; uint64_t max_rde_size = SMALLEST_POSSIBLE_MAX_RDT_MB << 20;
#else #else

File diff suppressed because it is too large Load Diff

View File

@ -10,8 +10,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/include \ -I$(top_srcdir)/include \
-I$(top_srcdir)/module/icp/include \ -I$(top_srcdir)/module/icp/include \
-I$(top_srcdir)/lib/libspl/include \ -I$(top_srcdir)/lib/libspl/include \
-I$(top_srcdir)/lib/libspl/include/os/@ac_system_l@ \ -I$(top_srcdir)/lib/libspl/include/os/@ac_system_l@
-I$(top_srcdir)/lib/libzpool/include
AM_LIBTOOLFLAGS = --silent AM_LIBTOOLFLAGS = --silent
@ -22,9 +21,7 @@ AM_CFLAGS += $(IMPLICIT_FALLTHROUGH)
AM_CFLAGS += $(DEBUG_CFLAGS) AM_CFLAGS += $(DEBUG_CFLAGS)
AM_CFLAGS += $(ASAN_CFLAGS) AM_CFLAGS += $(ASAN_CFLAGS)
AM_CFLAGS += $(UBSAN_CFLAGS) AM_CFLAGS += $(UBSAN_CFLAGS)
AM_CFLAGS += $(CODE_COVERAGE_CFLAGS) AM_CFLAGS += $(CODE_COVERAGE_CFLAGS) $(NO_FORMAT_ZERO_LENGTH)
AM_CFLAGS += $(NO_FORMAT_ZERO_LENGTH)
AM_CFLAGS += $(NO_FORMAT_TRUNCATION)
if BUILD_FREEBSD if BUILD_FREEBSD
AM_CFLAGS += -fPIC -Werror -Wno-unknown-pragmas -Wno-enum-conversion AM_CFLAGS += -fPIC -Werror -Wno-unknown-pragmas -Wno-enum-conversion
AM_CFLAGS += -include $(top_srcdir)/include/os/freebsd/spl/sys/ccompile.h AM_CFLAGS += -include $(top_srcdir)/include/os/freebsd/spl/sys/ccompile.h
@ -45,6 +42,21 @@ AM_CPPFLAGS += $(DEBUG_CPPFLAGS)
AM_CPPFLAGS += $(CODE_COVERAGE_CPPFLAGS) AM_CPPFLAGS += $(CODE_COVERAGE_CPPFLAGS)
AM_CPPFLAGS += -DTEXT_DOMAIN=\"zfs-@ac_system_l@-user\" AM_CPPFLAGS += -DTEXT_DOMAIN=\"zfs-@ac_system_l@-user\"
AM_CPPFLAGS_NOCHECK = -D"strtok(...)=strtok(__VA_ARGS__) __attribute__((deprecated(\"Use strtok_r(3) instead!\")))"
AM_CPPFLAGS_NOCHECK += -D"__xpg_basename(...)=__xpg_basename(__VA_ARGS__) __attribute__((deprecated(\"basename(3) is underspecified. Use zfs_basename() instead!\")))"
AM_CPPFLAGS_NOCHECK += -D"basename(...)=basename(__VA_ARGS__) __attribute__((deprecated(\"basename(3) is underspecified. Use zfs_basename() instead!\")))"
AM_CPPFLAGS_NOCHECK += -D"dirname(...)=dirname(__VA_ARGS__) __attribute__((deprecated(\"dirname(3) is underspecified. Use zfs_dirnamelen() instead!\")))"
AM_CPPFLAGS_NOCHECK += -D"bcopy(...)=__attribute__((deprecated(\"bcopy(3) is deprecated. Use memcpy(3)/memmove(3) instead!\"))) bcopy(__VA_ARGS__)"
AM_CPPFLAGS_NOCHECK += -D"bcmp(...)=__attribute__((deprecated(\"bcmp(3) is deprecated. Use memcmp(3) instead!\"))) bcmp(__VA_ARGS__)"
AM_CPPFLAGS_NOCHECK += -D"bzero(...)=__attribute__((deprecated(\"bzero(3) is deprecated. Use memset(3) instead!\"))) bzero(__VA_ARGS__)"
AM_CPPFLAGS_NOCHECK += -D"asctime(...)=__attribute__((deprecated(\"Use strftime(3) instead!\"))) asctime(__VA_ARGS__)"
AM_CPPFLAGS_NOCHECK += -D"asctime_r(...)=__attribute__((deprecated(\"Use strftime(3) instead!\"))) asctime_r(__VA_ARGS__)"
AM_CPPFLAGS_NOCHECK += -D"gmtime(...)=__attribute__((deprecated(\"gmtime(3) isn't thread-safe. Use gmtime_r(3) instead!\"))) gmtime(__VA_ARGS__)"
AM_CPPFLAGS_NOCHECK += -D"localtime(...)=__attribute__((deprecated(\"localtime(3) isn't thread-safe. Use localtime_r(3) instead!\"))) localtime(__VA_ARGS__)"
AM_CPPFLAGS_NOCHECK += -D"strncpy(...)=__attribute__((deprecated(\"strncpy(3) is deprecated. Use strlcpy(3) instead!\"))) strncpy(__VA_ARGS__)"
AM_CPPFLAGS += $(AM_CPPFLAGS_NOCHECK)
if ASAN_ENABLED if ASAN_ENABLED
AM_CPPFLAGS += -DZFS_ASAN_ENABLED AM_CPPFLAGS += -DZFS_ASAN_ENABLED
endif endif
@ -58,7 +70,7 @@ AM_LDFLAGS += $(ASAN_LDFLAGS)
AM_LDFLAGS += $(UBSAN_LDFLAGS) AM_LDFLAGS += $(UBSAN_LDFLAGS)
if BUILD_FREEBSD if BUILD_FREEBSD
AM_LDFLAGS += -fstack-protector-strong AM_LDFLAGS += -fstack-protector-strong -shared
AM_LDFLAGS += -Wl,-x -Wl,--fatal-warnings -Wl,--warn-shared-textrel AM_LDFLAGS += -Wl,-x -Wl,--fatal-warnings -Wl,--warn-shared-textrel
AM_LDFLAGS += -lm AM_LDFLAGS += -lm
endif endif
@ -71,7 +83,4 @@ KERNEL_CFLAGS = $(FRAME_LARGER_THAN)
LIBRARY_CFLAGS = -no-suppress LIBRARY_CFLAGS = -no-suppress
# Forcibly enable asserts/debugging for libzpool &al. # Forcibly enable asserts/debugging for libzpool &al.
# Since ZFS_DEBUG can change shared data structures, all libzpool users must FORCEDEBUG_CPPFLAGS = -DDEBUG -UNDEBUG -DZFS_DEBUG
# be compiled with the same flags.
# See https://github.com/openzfs/zfs/issues/16476
LIBZPOOL_CPPFLAGS = -DDEBUG -UNDEBUG -DZFS_DEBUG

View File

@ -18,7 +18,6 @@ subst_sed_cmd = \
-e 's|@ASAN_ENABLED[@]|$(ASAN_ENABLED)|g' \ -e 's|@ASAN_ENABLED[@]|$(ASAN_ENABLED)|g' \
-e 's|@DEFAULT_INIT_NFS_SERVER[@]|$(DEFAULT_INIT_NFS_SERVER)|g' \ -e 's|@DEFAULT_INIT_NFS_SERVER[@]|$(DEFAULT_INIT_NFS_SERVER)|g' \
-e 's|@DEFAULT_INIT_SHELL[@]|$(DEFAULT_INIT_SHELL)|g' \ -e 's|@DEFAULT_INIT_SHELL[@]|$(DEFAULT_INIT_SHELL)|g' \
-e 's|@IS_SYSV_RC[@]|$(IS_SYSV_RC)|g' \
-e 's|@LIBFETCH_DYNAMIC[@]|$(LIBFETCH_DYNAMIC)|g' \ -e 's|@LIBFETCH_DYNAMIC[@]|$(LIBFETCH_DYNAMIC)|g' \
-e 's|@LIBFETCH_SONAME[@]|$(LIBFETCH_SONAME)|g' \ -e 's|@LIBFETCH_SONAME[@]|$(LIBFETCH_SONAME)|g' \
-e 's|@PYTHON[@]|$(PYTHON)|g' \ -e 's|@PYTHON[@]|$(PYTHON)|g' \
@ -44,4 +43,4 @@ SUBSTFILES =
CLEANFILES += $(SUBSTFILES) CLEANFILES += $(SUBSTFILES)
dist_noinst_DATA += $(SUBSTFILES:=.in) dist_noinst_DATA += $(SUBSTFILES:=.in)
$(SUBSTFILES): $(call SUBST,%,) $(call SUBST,%,)

View File

@ -80,11 +80,10 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
[AC_MSG_ERROR("Python $PYTHON_VERSION unknown")] [AC_MSG_ERROR("Python $PYTHON_VERSION unknown")]
) )
AS_IF([test "x$enable_pyzfs" = xyes], [ AX_PYTHON_DEVEL([$PYTHON_REQUIRED_VERSION], [
AX_PYTHON_DEVEL([$PYTHON_REQUIRED_VERSION]) AS_IF([test "x$enable_pyzfs" = xyes], [
], [ AC_MSG_ERROR("Python $PYTHON_REQUIRED_VERSION development library is not installed")
AX_PYTHON_DEVEL([$PYTHON_REQUIRED_VERSION], [true]) ], [test "x$enable_pyzfs" != xno], [
AS_IF([test "x$ax_python_devel_found" = xno], [
enable_pyzfs=no enable_pyzfs=no
]) ])
]) ])

View File

@ -4,13 +4,18 @@
# #
# SYNOPSIS # SYNOPSIS
# #
# AX_PYTHON_DEVEL([version[,optional]]) # AX_PYTHON_DEVEL([version], [action-if-not-found])
# #
# DESCRIPTION # DESCRIPTION
# #
# Note: Defines as a precious variable "PYTHON_VERSION". Don't override it # Note: Defines as a precious variable "PYTHON_VERSION". Don't override it
# in your configure.ac. # in your configure.ac.
# #
# Note: this is a slightly modified version of the original AX_PYTHON_DEVEL
# macro which accepts an additional [action-if-not-found] argument. This
# allow to detect if Python development is available without aborting the
# configure phase with an hard error in case it is not.
#
# This macro checks for Python and tries to get the include path to # This macro checks for Python and tries to get the include path to
# 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LIBS) output # 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LIBS) output
# variables. It also exports $(PYTHON_EXTRA_LIBS) and # variables. It also exports $(PYTHON_EXTRA_LIBS) and
@ -23,11 +28,6 @@
# version number. Don't use "PYTHON_VERSION" for this: that environment # version number. Don't use "PYTHON_VERSION" for this: that environment
# variable is declared as precious and thus reserved for the end-user. # variable is declared as precious and thus reserved for the end-user.
# #
# By default this will fail if it does not detect a development version of
# python. If you want it to continue, set optional to true, like
# AX_PYTHON_DEVEL([], [true]). The ax_python_devel_found variable will be
# "no" if it fails.
#
# This macro should work for all versions of Python >= 2.1.0. As an end # This macro should work for all versions of Python >= 2.1.0. As an end
# user, you can disable the check for the python version by setting the # user, you can disable the check for the python version by setting the
# PYTHON_NOVERSIONCHECK environment variable to something else than the # PYTHON_NOVERSIONCHECK environment variable to something else than the
@ -45,6 +45,7 @@
# Copyright (c) 2009 Matteo Settenvini <matteo@member.fsf.org> # Copyright (c) 2009 Matteo Settenvini <matteo@member.fsf.org>
# Copyright (c) 2009 Horst Knorr <hk_classes@knoda.org> # Copyright (c) 2009 Horst Knorr <hk_classes@knoda.org>
# Copyright (c) 2013 Daniel Mullner <muellner@math.stanford.edu> # Copyright (c) 2013 Daniel Mullner <muellner@math.stanford.edu>
# Copyright (c) 2018 loli10K <ezomori.nozomu@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the # under the terms of the GNU General Public License as published by the
@ -72,18 +73,10 @@
# modified version of the Autoconf Macro, you may extend this special # modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well. # exception to the GPL to apply to your modified version as well.
#serial 36 #serial 21
AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL]) AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL])
AC_DEFUN([AX_PYTHON_DEVEL],[ AC_DEFUN([AX_PYTHON_DEVEL],[
# Get whether it's optional
if test -z "$2"; then
ax_python_devel_optional=false
else
ax_python_devel_optional=$2
fi
ax_python_devel_found=yes
# #
# Allow the use of a (user set) custom python version # Allow the use of a (user set) custom python version
# #
@ -94,26 +87,23 @@ AC_DEFUN([AX_PYTHON_DEVEL],[
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
if test -z "$PYTHON"; then if test -z "$PYTHON"; then
AC_MSG_WARN([Cannot find python$PYTHON_VERSION in your system path]) m4_ifvaln([$2],[$2],[
if ! $ax_python_devel_optional; then AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
AC_MSG_ERROR([Giving up, python development not available]) PYTHON_VERSION=""
fi ])
ax_python_devel_found=no
PYTHON_VERSION=""
fi fi
if test $ax_python_devel_found = yes; then #
# # 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=`$PYTHON -c "import sys; \
ac_supports_python_ver=`$PYTHON -c "import sys; \
ver = sys.version.split ()[[0]]; \ ver = sys.version.split ()[[0]]; \
print (ver >= '2.1.0')"` print (ver >= '2.1.0')"`
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])
AC_MSG_WARN([ 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,27 +112,20 @@ 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.
]) ])
if ! $ax_python_devel_optional; then
AC_MSG_FAILURE([Giving up])
fi
ax_python_devel_found=no
PYTHON_VERSION=""
else else
AC_MSG_RESULT([skip at user request]) AC_MSG_RESULT([skip at user request])
fi fi
else else
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
fi
fi fi
if test $ax_python_devel_found = yes; then #
# # 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
# 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
# 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").
# Python 2.7.10 (the ".1" being evaluated as less than ".3"). #
# if test -n "$1"; then
if test -n "$1"; then
AC_MSG_CHECKING([for a version of Python $1]) AC_MSG_CHECKING([for a version of Python $1])
cat << EOF > ax_python_devel_vpy.py cat << EOF > ax_python_devel_vpy.py
class VPy: class VPy:
@ -150,7 +133,7 @@ class VPy:
return tuple(map(int, s.strip().replace("rc", ".").split("."))) return tuple(map(int, s.strip().replace("rc", ".").split(".")))
def __init__(self): def __init__(self):
import sys import sys
self.vpy = tuple(sys.version_info)[[:3]] self.vpy = tuple(sys.version_info)
def __eq__(self, s): def __eq__(self, s):
return self.vpy == self.vtup(s) return self.vpy == self.vtup(s)
def __ne__(self, s): def __ne__(self, s):
@ -172,69 +155,25 @@ EOF
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
else else
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
AC_MSG_WARN([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.
]) ])
if ! $ax_python_devel_optional; then
AC_MSG_ERROR([Giving up])
fi
ax_python_devel_found=no
PYTHON_VERSION="" PYTHON_VERSION=""
fi fi
fi
fi fi
if test $ax_python_devel_found = yes; then #
# # Check for Python include path
# Check if you have distutils, else fail #
# #
AC_MSG_CHECKING([for the sysconfig Python package]) AC_MSG_CHECKING([for Python include path])
ac_sysconfig_result=`$PYTHON -c "import sysconfig" 2>&1` if test -z "$PYTHON_CPPFLAGS"; then
if test $? -eq 0; then python_path=`$PYTHON -c "import sysconfig; \
AC_MSG_RESULT([yes]) print (sysconfig.get_path('include'));"`
IMPORT_SYSCONFIG="import sysconfig" plat_python_path=`$PYTHON -c "import sysconfig; \
else print (sysconfig.get_path('platinclude'));"`
AC_MSG_RESULT([no])
AC_MSG_CHECKING([for the distutils Python package])
ac_sysconfig_result=`$PYTHON -c "from distutils import sysconfig" 2>&1`
if test $? -eq 0; then
AC_MSG_RESULT([yes])
IMPORT_SYSCONFIG="from distutils import sysconfig"
else
AC_MSG_WARN([cannot import Python module "distutils".
Please check your Python installation. The error was:
$ac_sysconfig_result])
if ! $ax_python_devel_optional; then
AC_MSG_ERROR([Giving up])
fi
ax_python_devel_found=no
PYTHON_VERSION=""
fi
fi
fi
if test $ax_python_devel_found = yes; then
#
# Check for Python include path
#
AC_MSG_CHECKING([for Python include path])
if test -z "$PYTHON_CPPFLAGS"; then
if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
# sysconfig module has different functions
python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
print (sysconfig.get_path ('include'));"`
plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
print (sysconfig.get_path ('platinclude'));"`
else
# old distutils way
python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
print (sysconfig.get_python_inc ());"`
plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
print (sysconfig.get_python_inc (plat_specific=1));"`
fi
if test -n "${python_path}"; then if test -n "${python_path}"; then
if test "${plat_python_path}" != "${python_path}"; then if test "${plat_python_path}" != "${python_path}"; then
python_path="-I$python_path -I$plat_python_path" python_path="-I$python_path -I$plat_python_path"
@ -243,15 +182,15 @@ $ac_sysconfig_result])
fi fi
fi fi
PYTHON_CPPFLAGS=$python_path PYTHON_CPPFLAGS=$python_path
fi fi
AC_MSG_RESULT([$PYTHON_CPPFLAGS]) AC_MSG_RESULT([$PYTHON_CPPFLAGS])
AC_SUBST([PYTHON_CPPFLAGS]) AC_SUBST([PYTHON_CPPFLAGS])
# #
# Check for Python library path # Check for Python library path
# #
AC_MSG_CHECKING([for Python library path]) AC_MSG_CHECKING([for Python library path])
if test -z "$PYTHON_LIBS"; then if test -z "$PYTHON_LIBS"; then
# (makes two attempts to ensure we've got a version number # (makes two attempts to ensure we've got a version number
# from the interpreter) # from the interpreter)
ac_python_version=`cat<<EOD | $PYTHON - ac_python_version=`cat<<EOD | $PYTHON -
@ -269,7 +208,7 @@ EOD`
ac_python_version=$PYTHON_VERSION ac_python_version=$PYTHON_VERSION
else else
ac_python_version=`$PYTHON -c "import sys; \ ac_python_version=`$PYTHON -c "import sys; \
print ("%d.%d" % sys.version_info[[:2]])"` print ('.'.join(sys.version.split('.')[[:2]]))"`
fi fi
fi fi
@ -281,7 +220,7 @@ EOD`
ac_python_libdir=`cat<<EOD | $PYTHON - ac_python_libdir=`cat<<EOD | $PYTHON -
# There should be only one # There should be only one
$IMPORT_SYSCONFIG import sysconfig
e = sysconfig.get_config_var('LIBDIR') e = sysconfig.get_config_var('LIBDIR')
if e is not None: if e is not None:
print (e) print (e)
@ -290,7 +229,7 @@ EOD`
# Now, for the library: # Now, for the library:
ac_python_library=`cat<<EOD | $PYTHON - ac_python_library=`cat<<EOD | $PYTHON -
$IMPORT_SYSCONFIG import sysconfig
c = sysconfig.get_config_vars() c = sysconfig.get_config_vars()
if 'LDVERSION' in c: if 'LDVERSION' in c:
print ('python'+c[['LDVERSION']]) print ('python'+c[['LDVERSION']])
@ -310,140 +249,88 @@ EOD`
else else
# old way: use libpython from python_configdir # old way: use libpython from python_configdir
ac_python_libdir=`$PYTHON -c \ ac_python_libdir=`$PYTHON -c \
"from sysconfig import get_python_lib as f; \ "import sysconfig; \
import os; \ import os; \
print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"` print (os.path.join(sysconfig.get_path('platstdlib'), 'config'));"`
PYTHON_LIBS="-L$ac_python_libdir -lpython$ac_python_version" PYTHON_LIBS="-L$ac_python_libdir -lpython$ac_python_version"
fi fi
if test -z "PYTHON_LIBS"; then if test -z "PYTHON_LIBS"; then
AC_MSG_WARN([ m4_ifvaln([$2],[$2],[
AC_MSG_ERROR([
Cannot determine location of your Python DSO. Please check it was installed with Cannot determine location of your Python DSO. Please check it was installed with
dynamic libraries enabled, or try setting PYTHON_LIBS by hand. dynamic libraries enabled, or try setting PYTHON_LIBS by hand.
])
]) ])
if ! $ax_python_devel_optional; then
AC_MSG_ERROR([Giving up])
fi
ax_python_devel_found=no
PYTHON_VERSION=""
fi fi
fi
fi fi
AC_MSG_RESULT([$PYTHON_LIBS])
AC_SUBST([PYTHON_LIBS])
if test $ax_python_devel_found = yes; then #
AC_MSG_RESULT([$PYTHON_LIBS]) # Check for site packages
AC_SUBST([PYTHON_LIBS]) #
AC_MSG_CHECKING([for Python site-packages path])
if test -z "$PYTHON_SITE_PKG"; then
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
print (distutils.sysconfig.get_python_lib(0,0));" 2>/dev/null || \
$PYTHON -c "import sysconfig; \
print (sysconfig.get_path('purelib'));"`
fi
AC_MSG_RESULT([$PYTHON_SITE_PKG])
AC_SUBST([PYTHON_SITE_PKG])
# #
# Check for site packages # libraries which must be linked in when embedding
# #
AC_MSG_CHECKING([for Python site-packages path]) AC_MSG_CHECKING(python extra libraries)
if test -z "$PYTHON_SITE_PKG"; then if test -z "$PYTHON_EXTRA_LIBS"; then
if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then PYTHON_EXTRA_LIBS=`$PYTHON -c "import sysconfig; \
PYTHON_SITE_PKG=`$PYTHON -c "
$IMPORT_SYSCONFIG;
if hasattr(sysconfig, 'get_default_scheme'):
scheme = sysconfig.get_default_scheme()
else:
scheme = sysconfig._get_default_scheme()
if scheme == 'posix_local':
# Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/
scheme = 'posix_prefix'
prefix = '$prefix'
if prefix == 'NONE':
prefix = '$ac_default_prefix'
sitedir = sysconfig.get_path('purelib', scheme, vars={'base': prefix})
print(sitedir)"`
else
# distutils.sysconfig way
PYTHON_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
print (sysconfig.get_python_lib(0,0));"`
fi
fi
AC_MSG_RESULT([$PYTHON_SITE_PKG])
AC_SUBST([PYTHON_SITE_PKG])
#
# Check for platform-specific site packages
#
AC_MSG_CHECKING([for Python platform specific site-packages path])
if test -z "$PYTHON_PLATFORM_SITE_PKG"; then
if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
PYTHON_PLATFORM_SITE_PKG=`$PYTHON -c "
$IMPORT_SYSCONFIG;
if hasattr(sysconfig, 'get_default_scheme'):
scheme = sysconfig.get_default_scheme()
else:
scheme = sysconfig._get_default_scheme()
if scheme == 'posix_local':
# Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/
scheme = 'posix_prefix'
prefix = '$prefix'
if prefix == 'NONE':
prefix = '$ac_default_prefix'
sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase': prefix})
print(sitedir)"`
else
# distutils.sysconfig way
PYTHON_PLATFORM_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
print (sysconfig.get_python_lib(1,0));"`
fi
fi
AC_MSG_RESULT([$PYTHON_PLATFORM_SITE_PKG])
AC_SUBST([PYTHON_PLATFORM_SITE_PKG])
#
# libraries which must be linked in when embedding
#
AC_MSG_CHECKING(python extra libraries)
if test -z "$PYTHON_EXTRA_LIBS"; then
PYTHON_EXTRA_LIBS=`$PYTHON -c "$IMPORT_SYSCONFIG; \
conf = sysconfig.get_config_var; \ conf = sysconfig.get_config_var; \
print (conf('LIBS') + ' ' + conf('SYSLIBS'))"` print (conf('LIBS') + ' ' + conf('SYSLIBS'))"`
fi fi
AC_MSG_RESULT([$PYTHON_EXTRA_LIBS]) AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
AC_SUBST(PYTHON_EXTRA_LIBS) AC_SUBST(PYTHON_EXTRA_LIBS)
# #
# linking flags needed when embedding # linking flags needed when embedding
# #
AC_MSG_CHECKING(python extra linking flags) AC_MSG_CHECKING(python extra linking flags)
if test -z "$PYTHON_EXTRA_LDFLAGS"; then if test -z "$PYTHON_EXTRA_LDFLAGS"; then
PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "$IMPORT_SYSCONFIG; \ PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import sysconfig; \
conf = sysconfig.get_config_var; \ conf = sysconfig.get_config_var; \
print (conf('LINKFORSHARED'))"` print (conf('LINKFORSHARED'))"`
# Hack for macos, it sticks this in here. fi
PYTHON_EXTRA_LDFLAGS=`echo $PYTHON_EXTRA_LDFLAGS | sed 's/CoreFoundation.*$/CoreFoundation/'` AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
fi AC_SUBST(PYTHON_EXTRA_LDFLAGS)
AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
AC_SUBST(PYTHON_EXTRA_LDFLAGS)
# #
# final check to see if everything compiles alright # final check to see if everything compiles alright
# #
AC_MSG_CHECKING([consistency of all components of python development environment]) AC_MSG_CHECKING([consistency of all components of python development environment])
# save current global flags # save current global flags
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
ac_save_LDFLAGS="$LDFLAGS" ac_save_LDFLAGS="$LDFLAGS"
ac_save_CPPFLAGS="$CPPFLAGS" ac_save_CPPFLAGS="$CPPFLAGS"
LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS" LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS $PYTHON_EXTRA_LIBS"
LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS" LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS"
CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS" CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
AC_LANG_PUSH([C]) AC_LANG_PUSH([C])
AC_LINK_IFELSE([ AC_LINK_IFELSE([
AC_LANG_PROGRAM([[#include <Python.h>]], AC_LANG_PROGRAM([[#include <Python.h>]],
[[Py_Initialize();]]) [[Py_Initialize();]])
],[pythonexists=yes],[pythonexists=no]) ],[pythonexists=yes],[pythonexists=no])
AC_LANG_POP([C]) AC_LANG_POP([C])
# turn back to default flags # turn back to default flags
CPPFLAGS="$ac_save_CPPFLAGS" CPPFLAGS="$ac_save_CPPFLAGS"
LIBS="$ac_save_LIBS" LIBS="$ac_save_LIBS"
LDFLAGS="$ac_save_LDFLAGS" LDFLAGS="$ac_save_LDFLAGS"
AC_MSG_RESULT([$pythonexists]) AC_MSG_RESULT([$pythonexists])
if test ! "x$pythonexists" = "xyes"; then if test ! "x$pythonexists" = "xyes"; then
AC_MSG_WARN([ m4_ifvaln([$2],[$2],[
AC_MSG_FAILURE([
Could not link test program to Python. Maybe the main Python library has been Could not link test program to Python. Maybe the main Python library has been
installed in some non-standard library path. If so, pass it to configure, installed in some non-standard library path. If so, pass it to configure,
via the LIBS environment variable. via the LIBS environment variable.
@ -453,13 +340,9 @@ print(sitedir)"`
You probably have to install the development version of the Python package You probably have to install the development version of the Python package
for your distribution. The exact name of this package varies among them. for your distribution. The exact name of this package varies among them.
============================================================================ ============================================================================
]) ])
if ! $ax_python_devel_optional; then PYTHON_VERSION=""
AC_MSG_ERROR([Giving up]) ])
fi
ax_python_devel_found=no
PYTHON_VERSION=""
fi
fi fi
# #

View File

@ -90,8 +90,8 @@ AC_DEFUN([ZFS_AC_FIND_SYSTEM_LIBRARY], [
AC_DEFINE([HAVE_][$1], [1], [Define if you have [$5]]) AC_DEFINE([HAVE_][$1], [1], [Define if you have [$5]])
$7 $7
],[dnl ELSE ],[dnl ELSE
AC_SUBST([$1]_CFLAGS, [""]) AC_SUBST([$1]_CFLAGS, [])
AC_SUBST([$1]_LIBS, [""]) AC_SUBST([$1]_LIBS, [])
AC_MSG_WARN([cannot find [$5] via pkg-config or in the standard locations]) AC_MSG_WARN([cannot find [$5] via pkg-config or in the standard locations])
$8 $8
]) ])

View File

@ -172,7 +172,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [ ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
#include <linux/fs.h> #include <linux/fs.h>
static struct posix_acl *get_acl_fn(struct inode *inode, int type) struct posix_acl *get_acl_fn(struct inode *inode, int type)
{ return NULL; } { return NULL; }
static const struct inode_operations static const struct inode_operations
@ -184,7 +184,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
ZFS_LINUX_TEST_SRC([inode_operations_get_acl_rcu], [ ZFS_LINUX_TEST_SRC([inode_operations_get_acl_rcu], [
#include <linux/fs.h> #include <linux/fs.h>
static struct posix_acl *get_acl_fn(struct inode *inode, int type, struct posix_acl *get_acl_fn(struct inode *inode, int type,
bool rcu) { return NULL; } bool rcu) { return NULL; }
static const struct inode_operations static const struct inode_operations
@ -196,7 +196,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
ZFS_LINUX_TEST_SRC([inode_operations_get_inode_acl], [ ZFS_LINUX_TEST_SRC([inode_operations_get_inode_acl], [
#include <linux/fs.h> #include <linux/fs.h>
static struct posix_acl *get_inode_acl_fn(struct inode *inode, int type, struct posix_acl *get_inode_acl_fn(struct inode *inode, int type,
bool rcu) { return NULL; } bool rcu) { return NULL; }
static const struct inode_operations static const struct inode_operations
@ -243,7 +243,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
ZFS_LINUX_TEST_SRC([inode_operations_set_acl_mnt_idmap_dentry], [ ZFS_LINUX_TEST_SRC([inode_operations_set_acl_mnt_idmap_dentry], [
#include <linux/fs.h> #include <linux/fs.h>
static int set_acl_fn(struct mnt_idmap *idmap, int set_acl_fn(struct mnt_idmap *idmap,
struct dentry *dent, struct posix_acl *acl, struct dentry *dent, struct posix_acl *acl,
int type) { return 0; } int type) { return 0; }
@ -255,7 +255,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
ZFS_LINUX_TEST_SRC([inode_operations_set_acl_userns_dentry], [ ZFS_LINUX_TEST_SRC([inode_operations_set_acl_userns_dentry], [
#include <linux/fs.h> #include <linux/fs.h>
static int set_acl_fn(struct user_namespace *userns, int set_acl_fn(struct user_namespace *userns,
struct dentry *dent, struct posix_acl *acl, struct dentry *dent, struct posix_acl *acl,
int type) { return 0; } int type) { return 0; }
@ -267,7 +267,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
ZFS_LINUX_TEST_SRC([inode_operations_set_acl_userns], [ ZFS_LINUX_TEST_SRC([inode_operations_set_acl_userns], [
#include <linux/fs.h> #include <linux/fs.h>
static int set_acl_fn(struct user_namespace *userns, int set_acl_fn(struct user_namespace *userns,
struct inode *inode, struct posix_acl *acl, struct inode *inode, struct posix_acl *acl,
int type) { return 0; } int type) { return 0; }
@ -279,7 +279,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [ ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [
#include <linux/fs.h> #include <linux/fs.h>
static int set_acl_fn(struct inode *inode, struct posix_acl *acl, int set_acl_fn(struct inode *inode, struct posix_acl *acl,
int type) { return 0; } int type) { return 0; }
static const struct inode_operations static const struct inode_operations

View File

@ -8,7 +8,7 @@ dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [
ZFS_LINUX_TEST_SRC([dentry_operations_d_automount], [ ZFS_LINUX_TEST_SRC([dentry_operations_d_automount], [
#include <linux/dcache.h> #include <linux/dcache.h>
static struct vfsmount *d_automount(struct path *p) { return NULL; } struct vfsmount *d_automount(struct path *p) { return NULL; }
struct dentry_operations dops __attribute__ ((unused)) = { struct dentry_operations dops __attribute__ ((unused)) = {
.d_automount = d_automount, .d_automount = d_automount,
}; };

View File

@ -247,7 +247,7 @@ dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_END_IO_T_ARGS], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_END_IO_T_ARGS], [
ZFS_LINUX_TEST_SRC([bio_end_io_t_args], [ ZFS_LINUX_TEST_SRC([bio_end_io_t_args], [
#include <linux/bio.h> #include <linux/bio.h>
static void wanted_end_io(struct bio *bio) { return; } void wanted_end_io(struct bio *bio) { return; }
bio_end_io_t *end_io __attribute__ ((unused)) = wanted_end_io; bio_end_io_t *end_io __attribute__ ((unused)) = wanted_end_io;
], []) ], [])
]) ])

View File

@ -25,8 +25,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_PLUG], [
dnl # dnl #
dnl # 2.6.32 - 4.11: statically allocated bdi in request_queue dnl # 2.6.32 - 4.11: statically allocated bdi in request_queue
dnl # 4.12: dynamically allocated bdi in request_queue dnl # 4.12: dynamically allocated bdi in request_queue
dnl # 6.11: bdi no longer available through request_queue, so get it from
dnl # the gendisk attached to the queue
dnl # dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI], [
ZFS_LINUX_TEST_SRC([blk_queue_bdi], [ ZFS_LINUX_TEST_SRC([blk_queue_bdi], [
@ -49,30 +47,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_BDI], [
]) ])
]) ])
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISK_BDI], [
ZFS_LINUX_TEST_SRC([blk_queue_disk_bdi], [
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
], [
struct request_queue q;
struct gendisk disk;
struct backing_dev_info bdi __attribute__ ((unused));
q.disk = &disk;
q.disk->bdi = &bdi;
])
])
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_DISK_BDI], [
AC_MSG_CHECKING([whether backing_dev_info is available through queue gendisk])
ZFS_LINUX_TEST_RESULT([blk_queue_disk_bdi], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLK_QUEUE_DISK_BDI, 1,
[backing_dev_info is available through queue gendisk])
],[
AC_MSG_RESULT(no)
])
])
dnl # dnl #
dnl # 5.9: added blk_queue_update_readahead(), dnl # 5.9: added blk_queue_update_readahead(),
dnl # 5.15: renamed to disk_update_readahead() dnl # 5.15: renamed to disk_update_readahead()
@ -358,7 +332,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS], [
ZFS_LINUX_TEST_RESULT([blk_queue_max_hw_sectors], [ ZFS_LINUX_TEST_RESULT([blk_queue_max_hw_sectors], [
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
],[ ],[
AC_MSG_RESULT(no) ZFS_LINUX_TEST_ERROR([blk_queue_max_hw_sectors])
]) ])
]) ])
@ -381,7 +355,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS], [
ZFS_LINUX_TEST_RESULT([blk_queue_max_segments], [ ZFS_LINUX_TEST_RESULT([blk_queue_max_segments], [
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
], [ ], [
AC_MSG_RESULT(no) ZFS_LINUX_TEST_ERROR([blk_queue_max_segments])
]) ])
]) ])
@ -403,14 +377,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_MQ], [
(void) blk_mq_alloc_tag_set(&tag_set); (void) blk_mq_alloc_tag_set(&tag_set);
return BLK_STS_OK; return BLK_STS_OK;
], []) ], [])
ZFS_LINUX_TEST_SRC([blk_mq_rq_hctx], [
#include <linux/blk-mq.h>
#include <linux/blkdev.h>
], [
struct request rq = {0};
struct blk_mq_hw_ctx *hctx = NULL;
rq.mq_hctx = hctx;
], [])
]) ])
AC_DEFUN([ZFS_AC_KERNEL_BLK_MQ], [ AC_DEFUN([ZFS_AC_KERNEL_BLK_MQ], [
@ -418,13 +384,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_MQ], [
ZFS_LINUX_TEST_RESULT([blk_mq], [ ZFS_LINUX_TEST_RESULT([blk_mq], [
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLK_MQ, 1, [block multiqueue is available]) AC_DEFINE(HAVE_BLK_MQ, 1, [block multiqueue is available])
AC_MSG_CHECKING([whether block multiqueue hardware context is cached in struct request])
ZFS_LINUX_TEST_RESULT([blk_mq_rq_hctx], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLK_MQ_RQ_HCTX, 1, [block multiqueue hardware context is cached in struct request])
], [
AC_MSG_RESULT(no)
])
], [ ], [
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
]) ])
@ -433,7 +392,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_MQ], [
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [
ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG
ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI
ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISK_BDI
ZFS_AC_KERNEL_SRC_BLK_QUEUE_UPDATE_READAHEAD ZFS_AC_KERNEL_SRC_BLK_QUEUE_UPDATE_READAHEAD
ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD
ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
@ -448,7 +406,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE], [ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE], [
ZFS_AC_KERNEL_BLK_QUEUE_PLUG ZFS_AC_KERNEL_BLK_QUEUE_PLUG
ZFS_AC_KERNEL_BLK_QUEUE_BDI ZFS_AC_KERNEL_BLK_QUEUE_BDI
ZFS_AC_KERNEL_BLK_QUEUE_DISK_BDI
ZFS_AC_KERNEL_BLK_QUEUE_UPDATE_READAHEAD ZFS_AC_KERNEL_BLK_QUEUE_UPDATE_READAHEAD
ZFS_AC_KERNEL_BLK_QUEUE_DISCARD ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE

View File

@ -35,45 +35,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG], [
]) ])
]) ])
dnl #
dnl # 6.8.x API change
dnl # bdev_open_by_path() replaces blkdev_get_by_path()
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_OPEN_BY_PATH], [
ZFS_LINUX_TEST_SRC([bdev_open_by_path], [
#include <linux/fs.h>
#include <linux/blkdev.h>
], [
struct bdev_handle *bdh __attribute__ ((unused)) = NULL;
const char *path = "path";
fmode_t mode = 0;
void *holder = NULL;
struct blk_holder_ops h;
bdh = bdev_open_by_path(path, mode, holder, &h);
])
])
dnl #
dnl # 6.9.x API change
dnl # bdev_file_open_by_path() replaced bdev_open_by_path(),
dnl # and returns struct file*
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BDEV_FILE_OPEN_BY_PATH], [
ZFS_LINUX_TEST_SRC([bdev_file_open_by_path], [
#include <linux/fs.h>
#include <linux/blkdev.h>
], [
struct file *file __attribute__ ((unused)) = NULL;
const char *path = "path";
fmode_t mode = 0;
void *holder = NULL;
struct blk_holder_ops h;
file = bdev_file_open_by_path(path, mode, holder, &h);
])
])
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [
AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 3 args]) AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 3 args])
ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [ ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [
@ -86,24 +47,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [
[blkdev_get_by_path() exists and takes 4 args]) [blkdev_get_by_path() exists and takes 4 args])
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
], [ ], [
AC_MSG_RESULT(no) ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()])
AC_MSG_CHECKING([whether bdev_open_by_path() exists])
ZFS_LINUX_TEST_RESULT([bdev_open_by_path], [
AC_DEFINE(HAVE_BDEV_OPEN_BY_PATH, 1,
[bdev_open_by_path() exists])
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether bdev_file_open_by_path() exists])
ZFS_LINUX_TEST_RESULT([bdev_file_open_by_path], [
AC_DEFINE(HAVE_BDEV_FILE_OPEN_BY_PATH, 1,
[bdev_file_open_by_path() exists])
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()])
])
])
]) ])
]) ])
]) ])
@ -164,50 +108,18 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER], [
]) ])
]) ])
dnl #
dnl # 6.8.x API change
dnl # bdev_release() replaces blkdev_put()
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_RELEASE], [
ZFS_LINUX_TEST_SRC([bdev_release], [
#include <linux/fs.h>
#include <linux/blkdev.h>
], [
struct bdev_handle *bdh = NULL;
bdev_release(bdh);
])
])
dnl #
dnl # 6.9.x API change
dnl #
dnl # bdev_release() now private, but because bdev_file_open_by_path() returns
dnl # struct file*, we can just use fput(). So the blkdev_put test no longer
dnl # fails if not found.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [
AC_MSG_CHECKING([whether blkdev_put() exists]) AC_MSG_CHECKING([whether blkdev_put() exists])
ZFS_LINUX_TEST_RESULT([blkdev_put], [ ZFS_LINUX_TEST_RESULT([blkdev_put], [
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLKDEV_PUT, 1, [blkdev_put() exists])
], [ ], [
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether blkdev_put() accepts void* as arg 2]) AC_MSG_CHECKING([whether blkdev_put() accepts void* as arg 2])
ZFS_LINUX_TEST_RESULT([blkdev_put_holder], [ ZFS_LINUX_TEST_RESULT([blkdev_put_holder], [
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLKDEV_PUT_HOLDER, 1, AC_DEFINE(HAVE_BLKDEV_PUT_HOLDER, 1,
[blkdev_put() accepts void* as arg 2]) [blkdev_put() accepts void* as arg 2])
], [ ], [
AC_MSG_RESULT(no) ZFS_LINUX_TEST_ERROR([blkdev_put()])
AC_MSG_CHECKING([whether bdev_release() exists])
ZFS_LINUX_TEST_RESULT([bdev_release], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BDEV_RELEASE, 1,
[bdev_release() exists])
], [
AC_MSG_RESULT(no)
])
]) ])
]) ])
]) ])
@ -534,30 +446,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE], [
]) ])
]) ])
dnl #
dnl # 5.16 API change
dnl # Added bdev_nr_bytes() helper.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_NR_BYTES], [
ZFS_LINUX_TEST_SRC([bdev_nr_bytes], [
#include <linux/blkdev.h>
],[
struct block_device *bdev = NULL;
loff_t nr_bytes __attribute__ ((unused)) = 0;
nr_bytes = bdev_nr_bytes(bdev);
])
])
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEV_NR_BYTES], [
AC_MSG_CHECKING([whether bdev_nr_bytes() is available])
ZFS_LINUX_TEST_RESULT([bdev_nr_bytes], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BDEV_NR_BYTES, 1, [bdev_nr_bytes() is available])
],[
AC_MSG_RESULT(no)
])
])
dnl # dnl #
dnl # 5.20 API change, dnl # 5.20 API change,
dnl # Removed bdevname(), snprintf(.., %pg) should be used. dnl # Removed bdevname(), snprintf(.., %pg) should be used.
@ -585,29 +473,11 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEVNAME], [
]) ])
dnl # dnl #
dnl # TRIM support: discard and secure erase. We make use of asynchronous dnl # 5.19 API: blkdev_issue_secure_erase()
dnl # functions when available. dnl # 3.10 API: blkdev_issue_discard(..., BLKDEV_DISCARD_SECURE)
dnl # dnl #
dnl # 3.10: AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_SECURE_ERASE], [
dnl # sync discard: blkdev_issue_discard(..., 0) ZFS_LINUX_TEST_SRC([blkdev_issue_secure_erase], [
dnl # sync erase: blkdev_issue_discard(..., BLKDEV_DISCARD_SECURE)
dnl # async discard: [not available]
dnl # async erase: [not available]
dnl #
dnl # 4.7:
dnl # sync discard: blkdev_issue_discard(..., 0)
dnl # sync erase: blkdev_issue_discard(..., BLKDEV_DISCARD_SECURE)
dnl # async discard: __blkdev_issue_discard(..., 0)
dnl # async erase: __blkdev_issue_discard(..., BLKDEV_DISCARD_SECURE)
dnl #
dnl # 5.19:
dnl # sync discard: blkdev_issue_discard(...)
dnl # sync erase: blkdev_issue_secure_erase(...)
dnl # async discard: __blkdev_issue_discard(...)
dnl # async erase: [not available]
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_DISCARD], [
ZFS_LINUX_TEST_SRC([blkdev_issue_discard_noflags], [
#include <linux/blkdev.h> #include <linux/blkdev.h>
],[ ],[
struct block_device *bdev = NULL; struct block_device *bdev = NULL;
@ -615,9 +485,10 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_DISCARD], [
sector_t nr_sects = 0; sector_t nr_sects = 0;
int error __attribute__ ((unused)); int error __attribute__ ((unused));
error = blkdev_issue_discard(bdev, error = blkdev_issue_secure_erase(bdev,
sector, nr_sects, GFP_KERNEL); sector, nr_sects, GFP_KERNEL);
]) ])
ZFS_LINUX_TEST_SRC([blkdev_issue_discard_flags], [ ZFS_LINUX_TEST_SRC([blkdev_issue_discard_flags], [
#include <linux/blkdev.h> #include <linux/blkdev.h>
],[ ],[
@ -630,77 +501,9 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_DISCARD], [
error = blkdev_issue_discard(bdev, error = blkdev_issue_discard(bdev,
sector, nr_sects, GFP_KERNEL, flags); sector, nr_sects, GFP_KERNEL, flags);
]) ])
ZFS_LINUX_TEST_SRC([blkdev_issue_discard_async_noflags], [
#include <linux/blkdev.h>
],[
struct block_device *bdev = NULL;
sector_t sector = 0;
sector_t nr_sects = 0;
struct bio *biop = NULL;
int error __attribute__ ((unused));
error = __blkdev_issue_discard(bdev,
sector, nr_sects, GFP_KERNEL, &biop);
])
ZFS_LINUX_TEST_SRC([blkdev_issue_discard_async_flags], [
#include <linux/blkdev.h>
],[
struct block_device *bdev = NULL;
sector_t sector = 0;
sector_t nr_sects = 0;
unsigned long flags = 0;
struct bio *biop = NULL;
int error __attribute__ ((unused));
error = __blkdev_issue_discard(bdev,
sector, nr_sects, GFP_KERNEL, flags, &biop);
])
ZFS_LINUX_TEST_SRC([blkdev_issue_secure_erase], [
#include <linux/blkdev.h>
],[
struct block_device *bdev = NULL;
sector_t sector = 0;
sector_t nr_sects = 0;
int error __attribute__ ((unused));
error = blkdev_issue_secure_erase(bdev,
sector, nr_sects, GFP_KERNEL);
])
]) ])
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_ISSUE_DISCARD], [ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_ISSUE_SECURE_ERASE], [
AC_MSG_CHECKING([whether blkdev_issue_discard() is available])
ZFS_LINUX_TEST_RESULT([blkdev_issue_discard_noflags], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLKDEV_ISSUE_DISCARD_NOFLAGS, 1,
[blkdev_issue_discard() is available])
],[
AC_MSG_RESULT(no)
])
AC_MSG_CHECKING([whether blkdev_issue_discard(flags) is available])
ZFS_LINUX_TEST_RESULT([blkdev_issue_discard_flags], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLKDEV_ISSUE_DISCARD_FLAGS, 1,
[blkdev_issue_discard(flags) is available])
],[
AC_MSG_RESULT(no)
])
AC_MSG_CHECKING([whether __blkdev_issue_discard() is available])
ZFS_LINUX_TEST_RESULT([blkdev_issue_discard_async_noflags], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLKDEV_ISSUE_DISCARD_ASYNC_NOFLAGS, 1,
[__blkdev_issue_discard() is available])
],[
AC_MSG_RESULT(no)
])
AC_MSG_CHECKING([whether __blkdev_issue_discard(flags) is available])
ZFS_LINUX_TEST_RESULT([blkdev_issue_discard_async_flags], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLKDEV_ISSUE_DISCARD_ASYNC_FLAGS, 1,
[__blkdev_issue_discard(flags) is available])
],[
AC_MSG_RESULT(no)
])
AC_MSG_CHECKING([whether blkdev_issue_secure_erase() is available]) AC_MSG_CHECKING([whether blkdev_issue_secure_erase() is available])
ZFS_LINUX_TEST_RESULT([blkdev_issue_secure_erase], [ ZFS_LINUX_TEST_RESULT([blkdev_issue_secure_erase], [
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
@ -708,6 +511,15 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_ISSUE_DISCARD], [
[blkdev_issue_secure_erase() is available]) [blkdev_issue_secure_erase() is available])
],[ ],[
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether blkdev_issue_discard() is available])
ZFS_LINUX_TEST_RESULT([blkdev_issue_discard_flags], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLKDEV_ISSUE_DISCARD, 1,
[blkdev_issue_discard() is available])
],[
ZFS_LINUX_TEST_ERROR([blkdev_issue_discard()])
])
]) ])
]) ])
@ -758,11 +570,8 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT], [
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_OPEN_BY_PATH
ZFS_AC_KERNEL_SRC_BDEV_FILE_OPEN_BY_PATH
ZFS_AC_KERNEL_SRC_BLKDEV_PUT ZFS_AC_KERNEL_SRC_BLKDEV_PUT
ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_RELEASE
ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART
ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV
ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV
@ -771,9 +580,8 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
ZFS_AC_KERNEL_SRC_BLKDEV_CHECK_DISK_CHANGE ZFS_AC_KERNEL_SRC_BLKDEV_CHECK_DISK_CHANGE
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_CHECK_MEDIA_CHANGE ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_WHOLE ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_WHOLE
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_NR_BYTES
ZFS_AC_KERNEL_SRC_BLKDEV_BDEVNAME ZFS_AC_KERNEL_SRC_BLKDEV_BDEVNAME
ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_DISCARD ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_SECURE_ERASE
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_KOBJ ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_KOBJ
ZFS_AC_KERNEL_SRC_BLKDEV_PART_TO_DEV ZFS_AC_KERNEL_SRC_BLKDEV_PART_TO_DEV
ZFS_AC_KERNEL_SRC_BLKDEV_DISK_CHECK_MEDIA_CHANGE ZFS_AC_KERNEL_SRC_BLKDEV_DISK_CHECK_MEDIA_CHANGE
@ -792,10 +600,9 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
ZFS_AC_KERNEL_BLKDEV_CHECK_DISK_CHANGE ZFS_AC_KERNEL_BLKDEV_CHECK_DISK_CHANGE
ZFS_AC_KERNEL_BLKDEV_BDEV_CHECK_MEDIA_CHANGE ZFS_AC_KERNEL_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE
ZFS_AC_KERNEL_BLKDEV_BDEV_NR_BYTES
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_DISCARD ZFS_AC_KERNEL_BLKDEV_ISSUE_SECURE_ERASE
ZFS_AC_KERNEL_BLKDEV_BDEV_KOBJ ZFS_AC_KERNEL_BLKDEV_BDEV_KOBJ
ZFS_AC_KERNEL_BLKDEV_PART_TO_DEV ZFS_AC_KERNEL_BLKDEV_PART_TO_DEV
ZFS_AC_KERNEL_BLKDEV_DISK_CHECK_MEDIA_CHANGE ZFS_AC_KERNEL_BLKDEV_DISK_CHECK_MEDIA_CHANGE

View File

@ -5,7 +5,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
ZFS_LINUX_TEST_SRC([block_device_operations_check_events], [ ZFS_LINUX_TEST_SRC([block_device_operations_check_events], [
#include <linux/blkdev.h> #include <linux/blkdev.h>
static unsigned int blk_check_events(struct gendisk *disk, unsigned int blk_check_events(struct gendisk *disk,
unsigned int clearing) { unsigned int clearing) {
(void) disk, (void) clearing; (void) disk, (void) clearing;
return (0); return (0);
@ -34,7 +34,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
ZFS_LINUX_TEST_SRC([block_device_operations_release_void], [ ZFS_LINUX_TEST_SRC([block_device_operations_release_void], [
#include <linux/blkdev.h> #include <linux/blkdev.h>
static void blk_release(struct gendisk *g, fmode_t mode) { void blk_release(struct gendisk *g, fmode_t mode) {
(void) g, (void) mode; (void) g, (void) mode;
return; return;
} }
@ -56,7 +56,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG], [
ZFS_LINUX_TEST_SRC([block_device_operations_release_void_1arg], [ ZFS_LINUX_TEST_SRC([block_device_operations_release_void_1arg], [
#include <linux/blkdev.h> #include <linux/blkdev.h>
static void blk_release(struct gendisk *g) { void blk_release(struct gendisk *g) {
(void) g; (void) g;
return; return;
} }
@ -96,7 +96,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [
ZFS_LINUX_TEST_SRC([block_device_operations_revalidate_disk], [ ZFS_LINUX_TEST_SRC([block_device_operations_revalidate_disk], [
#include <linux/blkdev.h> #include <linux/blkdev.h>
static int blk_revalidate_disk(struct gendisk *disk) { int blk_revalidate_disk(struct gendisk *disk) {
(void) disk; (void) disk;
return(0); return(0);
} }

View File

@ -7,7 +7,7 @@ dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_COMMIT_METADATA], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_COMMIT_METADATA], [
ZFS_LINUX_TEST_SRC([export_operations_commit_metadata], [ ZFS_LINUX_TEST_SRC([export_operations_commit_metadata], [
#include <linux/exportfs.h> #include <linux/exportfs.h>
static int commit_metadata(struct inode *inode) { return 0; } int commit_metadata(struct inode *inode) { return 0; }
static struct export_operations eops __attribute__ ((unused))={ static struct export_operations eops __attribute__ ((unused))={
.commit_metadata = commit_metadata, .commit_metadata = commit_metadata,
}; };

View File

@ -2,15 +2,12 @@ dnl #
dnl # 4.9, current_time() added dnl # 4.9, current_time() added
dnl # 4.18, return type changed from timespec to timespec64 dnl # 4.18, return type changed from timespec to timespec64
dnl # dnl #
dnl # Note that we don't care about the return type in this check. If we have
dnl # to implement a fallback, we'll know we're <4.9, which was timespec.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_CURRENT_TIME], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_CURRENT_TIME], [
ZFS_LINUX_TEST_SRC([current_time], [ ZFS_LINUX_TEST_SRC([current_time], [
#include <linux/fs.h> #include <linux/fs.h>
], [ ], [
struct inode ip __attribute__ ((unused)); struct inode ip __attribute__ ((unused));
(void) current_time(&ip); ip.i_atime = current_time(&ip);
]) ])
]) ])

View File

@ -98,7 +98,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_D_REVALIDATE_NAMEIDATA], [
#include <linux/dcache.h> #include <linux/dcache.h>
#include <linux/sched.h> #include <linux/sched.h>
static int revalidate (struct dentry *dentry, int revalidate (struct dentry *dentry,
struct nameidata *nidata) { return 0; } struct nameidata *nidata) { return 0; }
static const struct dentry_operations static const struct dentry_operations

View File

@ -8,7 +8,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_DIRTY_INODE], [
ZFS_LINUX_TEST_SRC([dirty_inode_with_flags], [ ZFS_LINUX_TEST_SRC([dirty_inode_with_flags], [
#include <linux/fs.h> #include <linux/fs.h>
static void dirty_inode(struct inode *a, int b) { return; } void dirty_inode(struct inode *a, int b) { return; }
static const struct super_operations static const struct super_operations
sops __attribute__ ((unused)) = { sops __attribute__ ((unused)) = {

View File

@ -7,7 +7,7 @@ dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_ENCODE_FH_WITH_INODE], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_ENCODE_FH_WITH_INODE], [
ZFS_LINUX_TEST_SRC([export_operations_encode_fh], [ ZFS_LINUX_TEST_SRC([export_operations_encode_fh], [
#include <linux/exportfs.h> #include <linux/exportfs.h>
static int encode_fh(struct inode *inode, __u32 *fh, int *max_len, int encode_fh(struct inode *inode, __u32 *fh, int *max_len,
struct inode *parent) { return 0; } struct inode *parent) { return 0; }
static struct export_operations eops __attribute__ ((unused))={ static struct export_operations eops __attribute__ ((unused))={
.encode_fh = encode_fh, .encode_fh = encode_fh,

View File

@ -6,7 +6,7 @@ dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_EVICT_INODE], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_EVICT_INODE], [
ZFS_LINUX_TEST_SRC([evict_inode], [ ZFS_LINUX_TEST_SRC([evict_inode], [
#include <linux/fs.h> #include <linux/fs.h>
static void evict_inode (struct inode * t) { return; } void evict_inode (struct inode * t) { return; }
static struct super_operations sops __attribute__ ((unused)) = { static struct super_operations sops __attribute__ ((unused)) = {
.evict_inode = evict_inode, .evict_inode = evict_inode,
}; };

View File

@ -11,7 +11,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FALLOCATE], [
ZFS_LINUX_TEST_SRC([file_fallocate], [ ZFS_LINUX_TEST_SRC([file_fallocate], [
#include <linux/fs.h> #include <linux/fs.h>
static long test_fallocate(struct file *file, int mode, long test_fallocate(struct file *file, int mode,
loff_t offset, loff_t len) { return 0; } loff_t offset, loff_t len) { return 0; }
static const struct file_operations static const struct file_operations

View File

@ -4,7 +4,6 @@ dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_FILEMAP], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_FILEMAP], [
ZFS_LINUX_TEST_SRC([filemap_range_has_page], [ ZFS_LINUX_TEST_SRC([filemap_range_has_page], [
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/pagemap.h>
],[ ],[
struct address_space *mapping = NULL; struct address_space *mapping = NULL;
loff_t lstart = 0; loff_t lstart = 0;

View File

@ -1,8 +1,7 @@
dnl # dnl #
dnl # Starting from Linux 5.13, flush_dcache_page() becomes an inline dnl # Starting from Linux 5.13, flush_dcache_page() becomes an inline
dnl # function and may indirectly referencing GPL-only symbols: dnl # function and may indirectly referencing GPL-only cpu_feature_keys on
dnl # on powerpc: cpu_feature_keys dnl # powerpc
dnl # on riscv: PageHuge (added from 6.2)
dnl # dnl #
dnl # dnl #

View File

@ -79,12 +79,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [
__kernel_fpu_end(); __kernel_fpu_end();
], [], [ZFS_META_LICENSE]) ], [], [ZFS_META_LICENSE])
ZFS_LINUX_TEST_SRC([kernel_neon], [
#include <asm/neon.h>
], [
kernel_neon_begin();
kernel_neon_end();
], [], [ZFS_META_LICENSE])
]) ])
AC_DEFUN([ZFS_AC_KERNEL_FPU], [ AC_DEFUN([ZFS_AC_KERNEL_FPU], [
@ -111,20 +105,9 @@ AC_DEFUN([ZFS_AC_KERNEL_FPU], [
AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1, AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1,
[kernel exports FPU functions]) [kernel exports FPU functions])
],[ ],[
dnl # AC_MSG_RESULT(internal)
dnl # ARM neon symbols (only on arm and arm64) AC_DEFINE(HAVE_KERNEL_FPU_INTERNAL, 1,
dnl # could be GPL-only on arm64 after Linux 6.2 [kernel fpu internal])
dnl #
ZFS_LINUX_TEST_RESULT([kernel_neon_license],[
AC_MSG_RESULT(kernel_neon_*)
AC_DEFINE(HAVE_KERNEL_NEON, 1,
[kernel has kernel_neon_* functions])
],[
# catch-all
AC_MSG_RESULT(internal)
AC_DEFINE(HAVE_KERNEL_FPU_INTERNAL, 1,
[kernel fpu internal])
])
]) ])
]) ])
]) ])

View File

@ -5,7 +5,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FSYNC], [
ZFS_LINUX_TEST_SRC([fsync_without_dentry], [ ZFS_LINUX_TEST_SRC([fsync_without_dentry], [
#include <linux/fs.h> #include <linux/fs.h>
static int test_fsync(struct file *f, int x) { return 0; } int test_fsync(struct file *f, int x) { return 0; }
static const struct file_operations static const struct file_operations
fops __attribute__ ((unused)) = { fops __attribute__ ((unused)) = {
@ -16,7 +16,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FSYNC], [
ZFS_LINUX_TEST_SRC([fsync_range], [ ZFS_LINUX_TEST_SRC([fsync_range], [
#include <linux/fs.h> #include <linux/fs.h>
static int test_fsync(struct file *f, loff_t a, loff_t b, int c) int test_fsync(struct file *f, loff_t a, loff_t b, int c)
{ return 0; } { return 0; }
static const struct file_operations static const struct file_operations

View File

@ -5,7 +5,7 @@ dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [
ZFS_LINUX_TEST_SRC([inode_operations_get_link], [ ZFS_LINUX_TEST_SRC([inode_operations_get_link], [
#include <linux/fs.h> #include <linux/fs.h>
static const char *get_link(struct dentry *de, struct inode *ip, const char *get_link(struct dentry *de, struct inode *ip,
struct delayed_call *done) { return "symlink"; } struct delayed_call *done) { return "symlink"; }
static struct inode_operations static struct inode_operations
iops __attribute__ ((unused)) = { iops __attribute__ ((unused)) = {
@ -15,7 +15,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [
ZFS_LINUX_TEST_SRC([inode_operations_get_link_cookie], [ ZFS_LINUX_TEST_SRC([inode_operations_get_link_cookie], [
#include <linux/fs.h> #include <linux/fs.h>
static const char *get_link(struct dentry *de, struct const char *get_link(struct dentry *de, struct
inode *ip, void **cookie) { return "symlink"; } inode *ip, void **cookie) { return "symlink"; }
static struct inode_operations static struct inode_operations
iops __attribute__ ((unused)) = { iops __attribute__ ((unused)) = {
@ -25,7 +25,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [
ZFS_LINUX_TEST_SRC([inode_operations_follow_link], [ ZFS_LINUX_TEST_SRC([inode_operations_follow_link], [
#include <linux/fs.h> #include <linux/fs.h>
static const char *follow_link(struct dentry *de, const char *follow_link(struct dentry *de,
void **cookie) { return "symlink"; } void **cookie) { return "symlink"; }
static struct inode_operations static struct inode_operations
iops __attribute__ ((unused)) = { iops __attribute__ ((unused)) = {
@ -35,7 +35,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [
ZFS_LINUX_TEST_SRC([inode_operations_follow_link_nameidata], [ ZFS_LINUX_TEST_SRC([inode_operations_follow_link_nameidata], [
#include <linux/fs.h> #include <linux/fs.h>
static void *follow_link(struct dentry *de, struct void *follow_link(struct dentry *de, struct
nameidata *nd) { return (void *)NULL; } nameidata *nd) { return (void *)NULL; }
static struct inode_operations static struct inode_operations
iops __attribute__ ((unused)) = { iops __attribute__ ((unused)) = {

View File

@ -23,28 +23,3 @@ AC_DEFUN([ZFS_AC_KERNEL_IDMAP_MNT_API], [
]) ])
]) ])
dnl #
dnl # 6.8 decouples mnt_idmap from user_namespace. This is all internal
dnl # to mnt_idmap so we can't detect it directly, but we detect a related
dnl # change as use that as a signal.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_IDMAP_NO_USERNS], [
ZFS_LINUX_TEST_SRC([idmap_no_userns], [
#include <linux/uidgid.h>
], [
struct uid_gid_map *map = NULL;
map_id_down(map, 0);
])
])
AC_DEFUN([ZFS_AC_KERNEL_IDMAP_NO_USERNS], [
AC_MSG_CHECKING([whether idmapped mounts have a user namespace])
ZFS_LINUX_TEST_RESULT([idmap_no_userns], [
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_IDMAP_NO_USERNS, 1,
[mnt_idmap does not have user_namespace])
], [
AC_MSG_RESULT([no])
])
])

View File

@ -7,7 +7,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sched.h> #include <linux/sched.h>
static int inode_create(struct mnt_idmap *idmap, int inode_create(struct mnt_idmap *idmap,
struct inode *inode ,struct dentry *dentry, struct inode *inode ,struct dentry *dentry,
umode_t umode, bool flag) { return 0; } umode_t umode, bool flag) { return 0; }
@ -25,7 +25,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sched.h> #include <linux/sched.h>
static int inode_create(struct user_namespace *userns, int inode_create(struct user_namespace *userns,
struct inode *inode ,struct dentry *dentry, struct inode *inode ,struct dentry *dentry,
umode_t umode, bool flag) { return 0; } umode_t umode, bool flag) { return 0; }
@ -42,7 +42,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sched.h> #include <linux/sched.h>
static int inode_create(struct inode *inode ,struct dentry *dentry, int inode_create(struct inode *inode ,struct dentry *dentry,
umode_t umode, bool flag) { return 0; } umode_t umode, bool flag) { return 0; }
static const struct inode_operations static const struct inode_operations

View File

@ -7,7 +7,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
ZFS_LINUX_TEST_SRC([inode_operations_getattr_mnt_idmap], [ ZFS_LINUX_TEST_SRC([inode_operations_getattr_mnt_idmap], [
#include <linux/fs.h> #include <linux/fs.h>
static int test_getattr( int test_getattr(
struct mnt_idmap *idmap, struct mnt_idmap *idmap,
const struct path *p, struct kstat *k, const struct path *p, struct kstat *k,
u32 request_mask, unsigned int query_flags) u32 request_mask, unsigned int query_flags)
@ -28,7 +28,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
ZFS_LINUX_TEST_SRC([inode_operations_getattr_userns], [ ZFS_LINUX_TEST_SRC([inode_operations_getattr_userns], [
#include <linux/fs.h> #include <linux/fs.h>
static int test_getattr( int test_getattr(
struct user_namespace *userns, struct user_namespace *userns,
const struct path *p, struct kstat *k, const struct path *p, struct kstat *k,
u32 request_mask, unsigned int query_flags) u32 request_mask, unsigned int query_flags)
@ -47,7 +47,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [ ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
#include <linux/fs.h> #include <linux/fs.h>
static int test_getattr( int test_getattr(
const struct path *p, struct kstat *k, const struct path *p, struct kstat *k,
u32 request_mask, unsigned int query_flags) u32 request_mask, unsigned int query_flags)
{ return 0; } { return 0; }
@ -61,7 +61,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
ZFS_LINUX_TEST_SRC([inode_operations_getattr_vfsmount], [ ZFS_LINUX_TEST_SRC([inode_operations_getattr_vfsmount], [
#include <linux/fs.h> #include <linux/fs.h>
static int test_getattr( int test_getattr(
struct vfsmount *mnt, struct dentry *d, struct vfsmount *mnt, struct dentry *d,
struct kstat *k) struct kstat *k)
{ return 0; } { return 0; }

View File

@ -6,7 +6,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_LOOKUP_FLAGS], [
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sched.h> #include <linux/sched.h>
static struct dentry *inode_lookup(struct inode *inode, struct dentry *inode_lookup(struct inode *inode,
struct dentry *dentry, unsigned int flags) { return NULL; } struct dentry *dentry, unsigned int flags) { return NULL; }
static const struct inode_operations iops static const struct inode_operations iops

View File

@ -8,12 +8,12 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_PERMISSION], [
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sched.h> #include <linux/sched.h>
static int test_permission(struct mnt_idmap *idmap, int inode_permission(struct mnt_idmap *idmap,
struct inode *inode, int mask) { return 0; } struct inode *inode, int mask) { return 0; }
static const struct inode_operations static const struct inode_operations
iops __attribute__ ((unused)) = { iops __attribute__ ((unused)) = {
.permission = test_permission, .permission = inode_permission,
}; };
],[]) ],[])
@ -25,12 +25,12 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_PERMISSION], [
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sched.h> #include <linux/sched.h>
static int test_permission(struct user_namespace *userns, int inode_permission(struct user_namespace *userns,
struct inode *inode, int mask) { return 0; } struct inode *inode, int mask) { return 0; }
static const struct inode_operations static const struct inode_operations
iops __attribute__ ((unused)) = { iops __attribute__ ((unused)) = {
.permission = test_permission, .permission = inode_permission,
}; };
],[]) ],[])
]) ])

View File

@ -7,7 +7,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_SETATTR], [
ZFS_LINUX_TEST_SRC([inode_operations_setattr_mnt_idmap], [ ZFS_LINUX_TEST_SRC([inode_operations_setattr_mnt_idmap], [
#include <linux/fs.h> #include <linux/fs.h>
static int test_setattr( int test_setattr(
struct mnt_idmap *idmap, struct mnt_idmap *idmap,
struct dentry *de, struct iattr *ia) struct dentry *de, struct iattr *ia)
{ return 0; } { return 0; }
@ -27,7 +27,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_SETATTR], [
ZFS_LINUX_TEST_SRC([inode_operations_setattr_userns], [ ZFS_LINUX_TEST_SRC([inode_operations_setattr_userns], [
#include <linux/fs.h> #include <linux/fs.h>
static int test_setattr( int test_setattr(
struct user_namespace *userns, struct user_namespace *userns,
struct dentry *de, struct iattr *ia) struct dentry *de, struct iattr *ia)
{ return 0; } { return 0; }
@ -41,7 +41,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_SETATTR], [
ZFS_LINUX_TEST_SRC([inode_operations_setattr], [ ZFS_LINUX_TEST_SRC([inode_operations_setattr], [
#include <linux/fs.h> #include <linux/fs.h>
static int test_setattr( int test_setattr(
struct dentry *de, struct iattr *ia) struct dentry *de, struct iattr *ia)
{ return 0; } { return 0; }

View File

@ -47,53 +47,11 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_TIMES], [
#include <linux/fs.h> #include <linux/fs.h>
],[ ],[
struct inode ip; struct inode ip;
struct timespec64 ts = {0}; struct timespec64 ts;
memset(&ip, 0, sizeof(ip)); memset(&ip, 0, sizeof(ip));
inode_set_ctime_to_ts(&ip, ts); inode_set_ctime_to_ts(&ip, ts);
]) ])
dnl #
dnl # 6.7 API change
dnl # i_atime/i_mtime no longer directly accessible, must use
dnl # inode_get_mtime(ip), inode_set_mtime*(ip) to
dnl # read/write.
dnl #
ZFS_LINUX_TEST_SRC([inode_get_atime], [
#include <linux/fs.h>
],[
struct inode ip;
memset(&ip, 0, sizeof(ip));
inode_get_atime(&ip);
])
ZFS_LINUX_TEST_SRC([inode_get_mtime], [
#include <linux/fs.h>
],[
struct inode ip;
memset(&ip, 0, sizeof(ip));
inode_get_mtime(&ip);
])
ZFS_LINUX_TEST_SRC([inode_set_atime_to_ts], [
#include <linux/fs.h>
],[
struct inode ip;
struct timespec64 ts = {0};
memset(&ip, 0, sizeof(ip));
inode_set_atime_to_ts(&ip, ts);
])
ZFS_LINUX_TEST_SRC([inode_set_mtime_to_ts], [
#include <linux/fs.h>
],[
struct inode ip;
struct timespec64 ts = {0};
memset(&ip, 0, sizeof(ip));
inode_set_mtime_to_ts(&ip, ts);
])
]) ])
AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [ AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
@ -132,40 +90,4 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
],[ ],[
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
]) ])
AC_MSG_CHECKING([whether inode_get_atime() exists])
ZFS_LINUX_TEST_RESULT([inode_get_atime], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_INODE_GET_ATIME, 1,
[inode_get_atime() exists in linux/fs.h])
],[
AC_MSG_RESULT(no)
])
AC_MSG_CHECKING([whether inode_set_atime_to_ts() exists])
ZFS_LINUX_TEST_RESULT([inode_set_atime_to_ts], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_INODE_SET_ATIME_TO_TS, 1,
[inode_set_atime_to_ts() exists in linux/fs.h])
],[
AC_MSG_RESULT(no)
])
AC_MSG_CHECKING([whether inode_get_mtime() exists])
ZFS_LINUX_TEST_RESULT([inode_get_mtime], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_INODE_GET_MTIME, 1,
[inode_get_mtime() exists in linux/fs.h])
],[
AC_MSG_RESULT(no)
])
AC_MSG_CHECKING([whether inode_set_mtime_to_ts() exists])
ZFS_LINUX_TEST_RESULT([inode_set_mtime_to_ts], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_INODE_SET_MTIME_TO_TS, 1,
[inode_set_mtime_to_ts() exists in linux/fs.h])
],[
AC_MSG_RESULT(no)
])
]) ])

View File

@ -1,23 +0,0 @@
dnl #
dnl # 5.11 API change
dnl # kmap_atomic() was deprecated in favor of kmap_local_page()
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_KMAP_LOCAL_PAGE], [
ZFS_LINUX_TEST_SRC([kmap_local_page], [
#include <linux/highmem.h>
],[
struct page page;
kmap_local_page(&page);
])
])
AC_DEFUN([ZFS_AC_KERNEL_KMAP_LOCAL_PAGE], [
AC_MSG_CHECKING([whether kmap_local_page exists])
ZFS_LINUX_TEST_RESULT([kmap_local_page], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_KMAP_LOCAL_PAGE, 1,
[kernel has kmap_local_page])
],[
AC_MSG_RESULT(no)
])
])

View File

@ -4,7 +4,7 @@ dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [
ZFS_LINUX_TEST_SRC([make_request_fn_void], [ ZFS_LINUX_TEST_SRC([make_request_fn_void], [
#include <linux/blkdev.h> #include <linux/blkdev.h>
static void make_request(struct request_queue *q, void make_request(struct request_queue *q,
struct bio *bio) { return; } struct bio *bio) { return; }
],[ ],[
blk_queue_make_request(NULL, &make_request); blk_queue_make_request(NULL, &make_request);
@ -12,7 +12,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [
ZFS_LINUX_TEST_SRC([make_request_fn_blk_qc_t], [ ZFS_LINUX_TEST_SRC([make_request_fn_blk_qc_t], [
#include <linux/blkdev.h> #include <linux/blkdev.h>
static blk_qc_t make_request(struct request_queue *q, blk_qc_t make_request(struct request_queue *q,
struct bio *bio) { return (BLK_QC_T_NONE); } struct bio *bio) { return (BLK_QC_T_NONE); }
],[ ],[
blk_queue_make_request(NULL, &make_request); blk_queue_make_request(NULL, &make_request);
@ -20,7 +20,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [
ZFS_LINUX_TEST_SRC([blk_alloc_queue_request_fn], [ ZFS_LINUX_TEST_SRC([blk_alloc_queue_request_fn], [
#include <linux/blkdev.h> #include <linux/blkdev.h>
static blk_qc_t make_request(struct request_queue *q, blk_qc_t make_request(struct request_queue *q,
struct bio *bio) { return (BLK_QC_T_NONE); } struct bio *bio) { return (BLK_QC_T_NONE); }
],[ ],[
struct request_queue *q __attribute__ ((unused)); struct request_queue *q __attribute__ ((unused));
@ -29,7 +29,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [
ZFS_LINUX_TEST_SRC([blk_alloc_queue_request_fn_rh], [ ZFS_LINUX_TEST_SRC([blk_alloc_queue_request_fn_rh], [
#include <linux/blkdev.h> #include <linux/blkdev.h>
static blk_qc_t make_request(struct request_queue *q, blk_qc_t make_request(struct request_queue *q,
struct bio *bio) { return (BLK_QC_T_NONE); } struct bio *bio) { return (BLK_QC_T_NONE); }
],[ ],[
struct request_queue *q __attribute__ ((unused)); struct request_queue *q __attribute__ ((unused));
@ -50,21 +50,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [
disk = blk_alloc_disk(NUMA_NO_NODE); disk = blk_alloc_disk(NUMA_NO_NODE);
]) ])
ZFS_LINUX_TEST_SRC([blk_alloc_disk_2arg], [
#include <linux/blkdev.h>
],[
struct queue_limits *lim = NULL;
struct gendisk *disk __attribute__ ((unused));
disk = blk_alloc_disk(lim, NUMA_NO_NODE);
])
ZFS_LINUX_TEST_SRC([blkdev_queue_limits_features], [
#include <linux/blkdev.h>
],[
struct queue_limits *lim = NULL;
lim->features = 0;
])
ZFS_LINUX_TEST_SRC([blk_cleanup_disk], [ ZFS_LINUX_TEST_SRC([blk_cleanup_disk], [
#include <linux/blkdev.h> #include <linux/blkdev.h>
],[ ],[
@ -111,45 +96,6 @@ AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
], [ ], [
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
]) ])
dnl #
dnl # Linux 6.9 API Change:
dnl # blk_alloc_queue() takes a nullable queue_limits arg.
dnl #
AC_MSG_CHECKING([whether blk_alloc_disk() exists and takes 2 args])
ZFS_LINUX_TEST_RESULT([blk_alloc_disk_2arg], [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_BLK_ALLOC_DISK_2ARG], 1, [blk_alloc_disk() exists and takes 2 args])
dnl #
dnl # Linux 6.11 API change:
dnl # struct queue_limits gains a 'features' field,
dnl # used to set flushing options
dnl #
AC_MSG_CHECKING([whether struct queue_limits has a features field])
ZFS_LINUX_TEST_RESULT([blkdev_queue_limits_features], [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_BLKDEV_QUEUE_LIMITS_FEATURES], 1,
[struct queue_limits has a features field])
], [
AC_MSG_RESULT(no)
])
dnl #
dnl # 5.20 API change,
dnl # Removed blk_cleanup_disk(), put_disk() should be used.
dnl #
AC_MSG_CHECKING([whether blk_cleanup_disk() exists])
ZFS_LINUX_TEST_RESULT([blk_cleanup_disk], [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_BLK_CLEANUP_DISK], 1,
[blk_cleanup_disk() exists])
], [
AC_MSG_RESULT(no)
])
], [
AC_MSG_RESULT(no)
])
],[ ],[
AC_MSG_RESULT(no) AC_MSG_RESULT(no)

View File

@ -9,7 +9,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR], [
ZFS_LINUX_TEST_SRC([mkdir_mnt_idmap], [ ZFS_LINUX_TEST_SRC([mkdir_mnt_idmap], [
#include <linux/fs.h> #include <linux/fs.h>
static int mkdir(struct mnt_idmap *idmap, int mkdir(struct mnt_idmap *idmap,
struct inode *inode, struct dentry *dentry, struct inode *inode, struct dentry *dentry,
umode_t umode) { return 0; } umode_t umode) { return 0; }
static const struct inode_operations static const struct inode_operations
@ -26,7 +26,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR], [
ZFS_LINUX_TEST_SRC([mkdir_user_namespace], [ ZFS_LINUX_TEST_SRC([mkdir_user_namespace], [
#include <linux/fs.h> #include <linux/fs.h>
static int mkdir(struct user_namespace *userns, int mkdir(struct user_namespace *userns,
struct inode *inode, struct dentry *dentry, struct inode *inode, struct dentry *dentry,
umode_t umode) { return 0; } umode_t umode) { return 0; }
@ -47,7 +47,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR], [
ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [ ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
#include <linux/fs.h> #include <linux/fs.h>
static int mkdir(struct inode *inode, struct dentry *dentry, int mkdir(struct inode *inode, struct dentry *dentry,
umode_t umode) { return 0; } umode_t umode) { return 0; }
static const struct inode_operations static const struct inode_operations

View File

@ -7,7 +7,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MKNOD], [
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sched.h> #include <linux/sched.h>
static int tmp_mknod(struct mnt_idmap *idmap, int tmp_mknod(struct mnt_idmap *idmap,
struct inode *inode ,struct dentry *dentry, struct inode *inode ,struct dentry *dentry,
umode_t u, dev_t d) { return 0; } umode_t u, dev_t d) { return 0; }
@ -25,7 +25,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MKNOD], [
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sched.h> #include <linux/sched.h>
static int tmp_mknod(struct user_namespace *userns, int tmp_mknod(struct user_namespace *userns,
struct inode *inode ,struct dentry *dentry, struct inode *inode ,struct dentry *dentry,
umode_t u, dev_t d) { return 0; } umode_t u, dev_t d) { return 0; }

View File

@ -1,36 +0,0 @@
AC_DEFUN([ZFS_AC_KERNEL_SRC_MM_PAGE_SIZE], [
ZFS_LINUX_TEST_SRC([page_size], [
#include <linux/mm.h>
],[
unsigned long s;
s = page_size(NULL);
])
])
AC_DEFUN([ZFS_AC_KERNEL_MM_PAGE_SIZE], [
AC_MSG_CHECKING([whether page_size() is available])
ZFS_LINUX_TEST_RESULT([page_size], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_MM_PAGE_SIZE, 1, [page_size() is available])
],[
AC_MSG_RESULT(no)
])
])
AC_DEFUN([ZFS_AC_KERNEL_SRC_MM_PAGE_MAPPING], [
ZFS_LINUX_TEST_SRC([page_mapping], [
#include <linux/pagemap.h>
],[
struct page *p = NULL;
struct address_space *m = page_mapping(NULL);
])
])
AC_DEFUN([ZFS_AC_KERNEL_MM_PAGE_MAPPING], [
AC_MSG_CHECKING([whether page_mapping() is available])
ZFS_LINUX_TEST_RESULT([page_mapping], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_MM_PAGE_MAPPING, 1, [page_mapping() is available])
],[
AC_MSG_RESULT(no)
])
])

View File

@ -7,14 +7,14 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_PROC_OPERATIONS], [
ZFS_LINUX_TEST_SRC([proc_ops_struct], [ ZFS_LINUX_TEST_SRC([proc_ops_struct], [
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
static int test_open(struct inode *ip, struct file *fp) { return 0; } int test_open(struct inode *ip, struct file *fp) { return 0; }
static ssize_t test_read(struct file *fp, char __user *ptr, ssize_t test_read(struct file *fp, char __user *ptr,
size_t size, loff_t *offp) { return 0; } size_t size, loff_t *offp) { return 0; }
static ssize_t test_write(struct file *fp, const char __user *ptr, ssize_t test_write(struct file *fp, const char __user *ptr,
size_t size, loff_t *offp) { return 0; } size_t size, loff_t *offp) { return 0; }
static loff_t test_lseek(struct file *fp, loff_t off, int flag) loff_t test_lseek(struct file *fp, loff_t off, int flag)
{ return 0; } { return 0; }
static int test_release(struct inode *ip, struct file *fp) int test_release(struct inode *ip, struct file *fp)
{ return 0; } { return 0; }
const struct proc_ops test_ops __attribute__ ((unused)) = { const struct proc_ops test_ops __attribute__ ((unused)) = {

View File

@ -4,7 +4,7 @@ dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_PUT_LINK], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_PUT_LINK], [
ZFS_LINUX_TEST_SRC([put_link_cookie], [ ZFS_LINUX_TEST_SRC([put_link_cookie], [
#include <linux/fs.h> #include <linux/fs.h>
static void put_link(struct inode *ip, void *cookie) void put_link(struct inode *ip, void *cookie)
{ return; } { return; }
static struct inode_operations static struct inode_operations
iops __attribute__ ((unused)) = { iops __attribute__ ((unused)) = {
@ -14,7 +14,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_PUT_LINK], [
ZFS_LINUX_TEST_SRC([put_link_nameidata], [ ZFS_LINUX_TEST_SRC([put_link_nameidata], [
#include <linux/fs.h> #include <linux/fs.h>
static void put_link(struct dentry *de, struct void put_link(struct dentry *de, struct
nameidata *nd, void *ptr) { return; } nameidata *nd, void *ptr) { return; }
static struct inode_operations static struct inode_operations
iops __attribute__ ((unused)) = { iops __attribute__ ((unused)) = {

View File

@ -25,62 +25,3 @@ AC_DEFUN([ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE], [
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
]) ])
]) ])
dnl #
dnl # Linux 6.11 register_sysctl() enforces that sysctl tables no longer
dnl # supply a sentinel end-of-table element. 6.6 introduces
dnl # register_sysctl_sz() to enable callers to choose, so we use it if
dnl # available for backward compatibility.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_SZ], [
ZFS_LINUX_TEST_SRC([has_register_sysctl_sz], [
#include <linux/sysctl.h>
],[
struct ctl_table test_table[] __attribute__((unused)) = {0};
register_sysctl_sz("", test_table, 0);
])
])
AC_DEFUN([ZFS_AC_KERNEL_REGISTER_SYSCTL_SZ], [
AC_MSG_CHECKING([whether register_sysctl_sz exists])
ZFS_LINUX_TEST_RESULT([has_register_sysctl_sz], [
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_REGISTER_SYSCTL_SZ, 1,
[register_sysctl_sz exists])
],[
AC_MSG_RESULT([no])
])
])
dnl #
dnl # Linux 6.11 makes const the ctl_table arg of proc_handler
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_PROC_HANDLER_CTL_TABLE_CONST], [
ZFS_LINUX_TEST_SRC([has_proc_handler_ctl_table_const], [
#include <linux/sysctl.h>
static int test_handler(
const struct ctl_table *ctl __attribute((unused)),
int write __attribute((unused)),
void *buffer __attribute((unused)),
size_t *lenp __attribute((unused)),
loff_t *ppos __attribute((unused)))
{
return (0);
}
], [
proc_handler *ph __attribute((unused)) =
&test_handler;
])
])
AC_DEFUN([ZFS_AC_KERNEL_PROC_HANDLER_CTL_TABLE_CONST], [
AC_MSG_CHECKING([whether proc_handler ctl_table arg is const])
ZFS_LINUX_TEST_RESULT([has_proc_handler_ctl_table_const], [
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_PROC_HANDLER_CTL_TABLE_CONST, 1,
[proc_handler ctl_table arg is const])
], [
AC_MSG_RESULT([no])
])
])

View File

@ -8,7 +8,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
dnl # dnl #
ZFS_LINUX_TEST_SRC([inode_operations_rename2], [ ZFS_LINUX_TEST_SRC([inode_operations_rename2], [
#include <linux/fs.h> #include <linux/fs.h>
static int rename2_fn(struct inode *sip, struct dentry *sdp, int rename2_fn(struct inode *sip, struct dentry *sdp,
struct inode *tip, struct dentry *tdp, struct inode *tip, struct dentry *tdp,
unsigned int flags) { return 0; } unsigned int flags) { return 0; }
@ -26,7 +26,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
dnl # dnl #
ZFS_LINUX_TEST_SRC([inode_operations_rename_flags], [ ZFS_LINUX_TEST_SRC([inode_operations_rename_flags], [
#include <linux/fs.h> #include <linux/fs.h>
static int rename_fn(struct inode *sip, struct dentry *sdp, int rename_fn(struct inode *sip, struct dentry *sdp,
struct inode *tip, struct dentry *tdp, struct inode *tip, struct dentry *tdp,
unsigned int flags) { return 0; } unsigned int flags) { return 0; }
@ -44,7 +44,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
dnl # dnl #
ZFS_LINUX_TEST_SRC([dir_inode_operations_wrapper_rename2], [ ZFS_LINUX_TEST_SRC([dir_inode_operations_wrapper_rename2], [
#include <linux/fs.h> #include <linux/fs.h>
static int rename2_fn(struct inode *sip, struct dentry *sdp, int rename2_fn(struct inode *sip, struct dentry *sdp,
struct inode *tip, struct dentry *tdp, struct inode *tip, struct dentry *tdp,
unsigned int flags) { return 0; } unsigned int flags) { return 0; }
@ -62,7 +62,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
dnl # dnl #
ZFS_LINUX_TEST_SRC([inode_operations_rename_userns], [ ZFS_LINUX_TEST_SRC([inode_operations_rename_userns], [
#include <linux/fs.h> #include <linux/fs.h>
static int rename_fn(struct user_namespace *user_ns, struct inode *sip, int rename_fn(struct user_namespace *user_ns, struct inode *sip,
struct dentry *sdp, struct inode *tip, struct dentry *tdp, struct dentry *sdp, struct inode *tip, struct dentry *tdp,
unsigned int flags) { return 0; } unsigned int flags) { return 0; }
@ -77,7 +77,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
dnl # dnl #
ZFS_LINUX_TEST_SRC([inode_operations_rename_mnt_idmap], [ ZFS_LINUX_TEST_SRC([inode_operations_rename_mnt_idmap], [
#include <linux/fs.h> #include <linux/fs.h>
static int rename_fn(struct mnt_idmap *idmap, struct inode *sip, int rename_fn(struct mnt_idmap *idmap, struct inode *sip,
struct dentry *sdp, struct inode *tip, struct dentry *tdp, struct dentry *sdp, struct inode *tip, struct dentry *tdp,
unsigned int flags) { return 0; } unsigned int flags) { return 0; }

View File

@ -5,7 +5,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SHOW_OPTIONS], [
ZFS_LINUX_TEST_SRC([super_operations_show_options], [ ZFS_LINUX_TEST_SRC([super_operations_show_options], [
#include <linux/fs.h> #include <linux/fs.h>
static int show_options(struct seq_file * x, struct dentry * y) { int show_options(struct seq_file * x, struct dentry * y) {
return 0; return 0;
}; };

View File

@ -8,6 +8,9 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK], [
ZFS_LINUX_TEST_SRC([super_block_s_shrink], [ ZFS_LINUX_TEST_SRC([super_block_s_shrink], [
#include <linux/fs.h> #include <linux/fs.h>
int shrink(struct shrinker *s, struct shrink_control *sc)
{ return 0; }
static const struct super_block static const struct super_block
sb __attribute__ ((unused)) = { sb __attribute__ ((unused)) = {
.s_shrink.seeks = DEFAULT_SEEKS, .s_shrink.seeks = DEFAULT_SEEKS,
@ -16,44 +19,12 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK], [
],[]) ],[])
]) ])
dnl #
dnl # 6.7 API change
dnl # s_shrink is now a pointer.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK_PTR], [
ZFS_LINUX_TEST_SRC([super_block_s_shrink_ptr], [
#include <linux/fs.h>
static unsigned long shrinker_cb(struct shrinker *shrink,
struct shrink_control *sc) { return 0; }
static struct shrinker shrinker = {
.count_objects = shrinker_cb,
.scan_objects = shrinker_cb,
.seeks = DEFAULT_SEEKS,
};
static const struct super_block
sb __attribute__ ((unused)) = {
.s_shrink = &shrinker,
};
],[])
])
AC_DEFUN([ZFS_AC_KERNEL_SUPER_BLOCK_S_SHRINK], [ AC_DEFUN([ZFS_AC_KERNEL_SUPER_BLOCK_S_SHRINK], [
AC_MSG_CHECKING([whether super_block has s_shrink]) AC_MSG_CHECKING([whether super_block has s_shrink])
ZFS_LINUX_TEST_RESULT([super_block_s_shrink], [ ZFS_LINUX_TEST_RESULT([super_block_s_shrink], [
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SUPER_BLOCK_S_SHRINK, 1,
[have super_block s_shrink])
],[ ],[
AC_MSG_RESULT(no) ZFS_LINUX_TEST_ERROR([sb->s_shrink()])
AC_MSG_CHECKING([whether super_block has s_shrink pointer])
ZFS_LINUX_TEST_RESULT([super_block_s_shrink_ptr], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SUPER_BLOCK_S_SHRINK_PTR, 1,
[have super_block s_shrink pointer])
],[
AC_MSG_RESULT(no)
ZFS_LINUX_TEST_ERROR([sb->s_shrink()])
])
]) ])
]) ])
@ -86,7 +57,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [
AC_DEFUN([ZFS_AC_KERNEL_SRC_REGISTER_SHRINKER_VARARG], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_REGISTER_SHRINKER_VARARG], [
ZFS_LINUX_TEST_SRC([register_shrinker_vararg], [ ZFS_LINUX_TEST_SRC([register_shrinker_vararg], [
#include <linux/mm.h> #include <linux/mm.h>
static unsigned long shrinker_cb(struct shrinker *shrink, unsigned long shrinker_cb(struct shrinker *shrink,
struct shrink_control *sc) { return 0; } struct shrink_control *sc) { return 0; }
],[ ],[
struct shrinker cache_shrinker = { struct shrinker cache_shrinker = {
@ -101,7 +72,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_REGISTER_SHRINKER_VARARG], [
AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK], [
ZFS_LINUX_TEST_SRC([shrinker_cb_shrink_control], [ ZFS_LINUX_TEST_SRC([shrinker_cb_shrink_control], [
#include <linux/mm.h> #include <linux/mm.h>
static int shrinker_cb(struct shrinker *shrink, int shrinker_cb(struct shrinker *shrink,
struct shrink_control *sc) { return 0; } struct shrink_control *sc) { return 0; }
],[ ],[
struct shrinker cache_shrinker = { struct shrinker cache_shrinker = {
@ -113,7 +84,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK], [
ZFS_LINUX_TEST_SRC([shrinker_cb_shrink_control_split], [ ZFS_LINUX_TEST_SRC([shrinker_cb_shrink_control_split], [
#include <linux/mm.h> #include <linux/mm.h>
static unsigned long shrinker_cb(struct shrinker *shrink, unsigned long shrinker_cb(struct shrinker *shrink,
struct shrink_control *sc) { return 0; } struct shrink_control *sc) { return 0; }
],[ ],[
struct shrinker cache_shrinker = { struct shrinker cache_shrinker = {
@ -125,25 +96,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK], [
]) ])
]) ])
dnl #
dnl # 6.7 API change
dnl # register_shrinker has been replaced by shrinker_register.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER_REGISTER], [
ZFS_LINUX_TEST_SRC([shrinker_register], [
#include <linux/shrinker.h>
static unsigned long shrinker_cb(struct shrinker *shrink,
struct shrink_control *sc) { return 0; }
],[
struct shrinker cache_shrinker = {
.count_objects = shrinker_cb,
.scan_objects = shrinker_cb,
.seeks = DEFAULT_SEEKS,
};
shrinker_register(&cache_shrinker);
])
])
AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[ AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
dnl # dnl #
dnl # 6.0 API change dnl # 6.0 API change
@ -181,36 +133,14 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
dnl # cs->shrink() is logically split in to dnl # cs->shrink() is logically split in to
dnl # cs->count_objects() and cs->scan_objects() dnl # cs->count_objects() and cs->scan_objects()
dnl # dnl #
AC_MSG_CHECKING( AC_MSG_CHECKING([if cs->count_objects callback exists])
[whether cs->count_objects callback exists])
ZFS_LINUX_TEST_RESULT( ZFS_LINUX_TEST_RESULT(
[shrinker_cb_shrink_control_split],[ [shrinker_cb_shrink_control_split],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK, 1,
[cs->count_objects exists])
],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING(
[whether shrinker_register exists])
ZFS_LINUX_TEST_RESULT([shrinker_register], [
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SHRINKER_REGISTER, 1, AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK, 1,
[shrinker_register exists]) [cs->count_objects exists])
],[
dnl # We assume that the split shrinker
dnl # callback exists if
dnl # shrinker_register() exists,
dnl # because the latter is a much more
dnl # recent addition, and the macro
dnl # test for shrinker_register() only
dnl # works if the callback is split
AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK,
1, [cs->count_objects exists])
],[
AC_MSG_RESULT(no)
ZFS_LINUX_TEST_ERROR([shrinker]) ZFS_LINUX_TEST_ERROR([shrinker])
])
]) ])
]) ])
]) ])
@ -244,12 +174,10 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT], [
AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER], [
ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK
ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK_PTR
ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_HAS_NID ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_HAS_NID
ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK
ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT
ZFS_AC_KERNEL_SRC_REGISTER_SHRINKER_VARARG ZFS_AC_KERNEL_SRC_REGISTER_SHRINKER_VARARG
ZFS_AC_KERNEL_SRC_SHRINKER_REGISTER
]) ])
AC_DEFUN([ZFS_AC_KERNEL_SHRINKER], [ AC_DEFUN([ZFS_AC_KERNEL_SHRINKER], [

Some files were not shown because too many files have changed in this diff Show More