mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-24 19:28:53 +03:00
Compare commits
271 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f92fe0f5c | |||
| 508fff0e4b | |||
| d3942963ee | |||
| 0584ad8f94 | |||
| ea47857090 | |||
| 4ebda5d4d3 | |||
| 57ce66d293 | |||
| da6c288dfc | |||
| aee26af277 | |||
| 620389d32f | |||
| 5d7f47d828 | |||
| 977540168c | |||
| 1143d3d29d | |||
| 088712793e | |||
| e0886c96a8 | |||
| 5e89181544 | |||
| dfbda2465f | |||
| 6b239d1757 | |||
| 9a865b7fb7 | |||
| 3de7aeb68a | |||
| ff64096e75 | |||
| 7e2212990b | |||
| bd83c1e0c6 | |||
| a416b29e16 | |||
| af4b6f7dab | |||
| c3b60ededa | |||
| 57196f8ae9 | |||
| 8dc540ae16 | |||
| efdfb14fc8 | |||
| 2e158b0e0b | |||
| 4cf3e48a3b | |||
| 4e0fff2e02 | |||
| 14973b917c | |||
| a444efb6d7 | |||
| 0bef46e6d5 | |||
| 1180d61152 | |||
| 6ce97bb4a2 | |||
| 27d3cc6cd3 | |||
| d6a0cecab1 | |||
| 2c3d7283b4 | |||
| d7e6f293da | |||
| 2f23f0f940 | |||
| a377bde727 | |||
| e76373de7b | |||
| b05ae1a82a | |||
| b12a6d961c | |||
| 11b165cc9b | |||
| 2dde9202d9 | |||
| 998035d534 | |||
| 64e38df237 | |||
| d3dddbaa20 | |||
| e298695809 | |||
| c650ceb64d | |||
| 13c9a41140 | |||
| af80160f48 | |||
| db9048741b | |||
| b1b1faf0f1 | |||
| 2fe8060cee | |||
| 6e01b47a28 | |||
| cc9dae2404 | |||
| 1fb18c4bde | |||
| a0c055cfd3 | |||
| 91bb2e91bd | |||
| 132240507d | |||
| d6f8f41c21 | |||
| 2f5c39137a | |||
| 90d0023005 | |||
| dbfbc1e524 | |||
| a61c502907 | |||
| f2e890ddfa | |||
| 71f6e6480e | |||
| a1b1007e95 | |||
| 01918aa3f4 | |||
| e1ae0c4b99 | |||
| 475ee3bc2b | |||
| f6ce806298 | |||
| ea034765b4 | |||
| 9d7c10388a | |||
| f67a920a6d | |||
| 5c7c2b1301 | |||
| 5d08b105a2 | |||
| 55b6d4a3d8 | |||
| a0372059b1 | |||
| 68a310dc45 | |||
| 8ed04625db | |||
| c3c65e3cfb | |||
| eb9d335009 | |||
| 85c43508f3 | |||
| 09c0a8fd1a | |||
| ec3b25825e | |||
| 0382362ce0 | |||
| 0458070928 | |||
| 1fc5f8cbfd | |||
| 263b3d64ab | |||
| c1a64be6d4 | |||
| e40ffed021 | |||
| 59d91b4d10 | |||
| d53a6969c1 | |||
| 019739b6e9 | |||
| 7d9f3ef0ef | |||
| 0a01f36b69 | |||
| 9e06df8ab0 | |||
| 57e3b9c3cc | |||
| 605b901ca6 | |||
| c5f268fa14 | |||
| bc7792cad2 | |||
| f3222062c0 | |||
| 6316086b72 | |||
| 7cdd4dd33b | |||
| a7bb2dab4e | |||
| ecebf770c1 | |||
| aa4a84e616 | |||
| cc1c7b0171 | |||
| fa7ee48e10 | |||
| d6bedbbc44 | |||
| ab6717cba6 | |||
| 33a06f27e6 | |||
| 7ad8fc5407 | |||
| 272b178d52 | |||
| 8f3584292f | |||
| 289b1393a4 | |||
| ec75f80a50 | |||
| c2c02e490f | |||
| 793dffb04e | |||
| faa5673982 | |||
| ade8e4b7d6 | |||
| 1a7bad542b | |||
| 17351a79e2 | |||
| 1cb517aebd | |||
| cb2e336038 | |||
| 381a0ca1e8 | |||
| f7a69b93c6 | |||
| 8f6e2b5485 | |||
| 14b56624c8 | |||
| 214ae461f1 | |||
| 12ed5275d1 | |||
| 133fd00930 | |||
| 74256266ff | |||
| 2085a5f992 | |||
| b1dd6351bb | |||
| cb18cf6b0a | |||
| 6c25218c7e | |||
| 0bb2a48ee6 | |||
| f15ec889a9 | |||
| 0db64e9036 | |||
| 85071b2ff5 | |||
| 1a0ce3d5ef | |||
| 08d2e39719 | |||
| f87f41009f | |||
| 918e5c6fca | |||
| 9c5256a2fe | |||
| 39bcdd8d74 | |||
| 075dcad351 | |||
| 5701e393b7 | |||
| 910b43310f | |||
| 4ac37f8b2e | |||
| 6f2012c1dc | |||
| 96f04062e4 | |||
| a7a579e6e1 | |||
| 463d7e1a61 | |||
| 6c1a7be11e | |||
| 1b7d883eaa | |||
| e5c01296ff | |||
| 64b83a0bf1 | |||
| 8fd65351a7 | |||
| 79d9f663b0 | |||
| 478b8ec8f2 | |||
| 219acd907b | |||
| cc33149e5a | |||
| 40abc63c40 | |||
| cdc27fd061 | |||
| 121a34e36b | |||
| dfa2beddea | |||
| 14a1980b35 | |||
| 9747310cc1 | |||
| 0b10994cea | |||
| 692387343f | |||
| 8d869cd840 | |||
| ae8dd6676b | |||
| d938c6ee27 | |||
| dc4d55268c | |||
| bdcf0cca10 | |||
| 7be4669a65 | |||
| e5c4f86e7a | |||
| 4c925936e3 | |||
| 15d3470c2e | |||
| 55cf5a255a | |||
| d682e20ba4 | |||
| 9c470dc6c0 | |||
| 7616fc7971 | |||
| 7bf3959601 | |||
| 25cd7b520d | |||
| 4a30a0b947 | |||
| ecd6ad66b0 | |||
| 2aa0d643fd | |||
| a6b82cc0bb | |||
| 4568b5cfba | |||
| ffc2e74f79 | |||
| 8b03fce289 | |||
| 1f3de97374 | |||
| 7de1797cee | |||
| 44ccb1d20f | |||
| dfd3015048 | |||
| 4a9b29375e | |||
| 2453d0263d | |||
| ab88e9e264 | |||
| 54aaed5c45 | |||
| aa52015d45 | |||
| 5faeaa1365 | |||
| 17792783d0 | |||
| 07d64c07e0 | |||
| f8631d0fe0 | |||
| afe2a5ca12 | |||
| 2a667acfcb | |||
| 5f3f4def83 | |||
| 8bc955f546 | |||
| b3bb604a4c | |||
| 2ae2892235 | |||
| 9d47853c74 | |||
| 30f5b2fbe2 | |||
| ad34215364 | |||
| 1eee2c7b27 | |||
| f17d146ca6 | |||
| a35cadcf14 | |||
| 72a9750ac8 | |||
| 7822c01eb6 | |||
| 96e15d29fa | |||
| bb8db9d927 | |||
| 32cc3f0837 | |||
| f96dbd7a29 | |||
| c30fef2523 | |||
| 487cd2df11 | |||
| 5a674a1b42 | |||
| 52f65648e0 | |||
| 55780d8ec0 | |||
| b3a7e6e7f3 | |||
| ea30225fdb | |||
| 018560b153 | |||
| 48b60cffda | |||
| cb97db792e | |||
| 718ee43362 | |||
| 01219379cf | |||
| 0a51083e39 | |||
| b73e40a5ad | |||
| fa991f2a47 | |||
| dbf8baf8dd | |||
| 9160c441a4 | |||
| 84c1652a0a | |||
| 7474d775c7 | |||
| 506ffdf648 | |||
| 0bf91beab9 | |||
| 04344d5bc3 | |||
| 46aec6d439 | |||
| 1bb4b5a5ae | |||
| 71a3487a89 | |||
| 2aed1ab13d | |||
| d09e1c1343 | |||
| e2f5074c0f | |||
| ca7af7f675 | |||
| 35cce6ea63 | |||
| d539b77934 | |||
| 202e7545dc | |||
| 003f2d04b6 | |||
| ec311430e2 | |||
| 895d39aa83 | |||
| 7f789e150f | |||
| 917f4b334c | |||
| 6613ea3b33 | |||
| e783fa0925 | |||
| dc52c0d725 | |||
| bfdd001679 |
-21
@@ -1,21 +0,0 @@
|
|||||||
env:
|
|
||||||
CIRRUS_CLONE_DEPTH: 1
|
|
||||||
ARCH: amd64
|
|
||||||
|
|
||||||
build_task:
|
|
||||||
matrix:
|
|
||||||
freebsd_instance:
|
|
||||||
image_family: freebsd-12-4
|
|
||||||
freebsd_instance:
|
|
||||||
image_family: freebsd-13-2
|
|
||||||
freebsd_instance:
|
|
||||||
image_family: freebsd-14-0-snap
|
|
||||||
prepare_script:
|
|
||||||
- pkg install -y autoconf automake libtool gettext-runtime gmake ksh93 py39-packaging py39-cffi py39-sysctl
|
|
||||||
configure_script:
|
|
||||||
- env MAKE=gmake ./autogen.sh
|
|
||||||
- env MAKE=gmake ./configure --with-config="user" --with-python=3.9
|
|
||||||
build_script:
|
|
||||||
- gmake -j `sysctl -n kern.smp.cpus`
|
|
||||||
install_script:
|
|
||||||
- gmake install
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
name: Bug report
|
name: Bug report
|
||||||
about: Create a report to help us improve OpenZFS
|
about: Create a report to help us improve OpenZFS
|
||||||
title: ''
|
title: ''
|
||||||
labels: 'Type: Defect'
|
labels: 'Type: Defect, Status: Triage Needed'
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -25,16 +25,14 @@ Type | Version/Name
|
|||||||
--- | ---
|
--- | ---
|
||||||
Distribution Name |
|
Distribution Name |
|
||||||
Distribution Version |
|
Distribution Version |
|
||||||
Kernel Version |
|
Linux Kernel |
|
||||||
Architecture |
|
Architecture |
|
||||||
OpenZFS Version |
|
ZFS Version |
|
||||||
|
SPL Version |
|
||||||
<!--
|
<!--
|
||||||
Command to find OpenZFS version:
|
Commands to find ZFS/SPL versions:
|
||||||
zfs version
|
modinfo zfs | grep -iw version
|
||||||
|
modinfo spl | grep -iw version
|
||||||
Commands to find kernel version:
|
|
||||||
uname -r # Linux
|
|
||||||
freebsd-version -r # FreeBSD
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Describe the problem you're observing
|
### Describe the problem you're observing
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
name: "Custom CodeQL Analysis"
|
|
||||||
|
|
||||||
queries:
|
|
||||||
- uses: ./.github/codeql/custom-queries/cpp/deprecatedFunctionUsage.ql
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
name: "Custom CodeQL Analysis"
|
|
||||||
|
|
||||||
paths-ignore:
|
|
||||||
- tests
|
|
||||||
@@ -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)
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
name: openzfs-cpp-queries
|
|
||||||
version: 0.0.0
|
|
||||||
libraryPathDependencies: codeql-cpp
|
|
||||||
suites: openzfs-cpp-suite
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
|
|
||||||
## The testings are done this way
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
flowchart TB
|
|
||||||
subgraph CleanUp and Summary
|
|
||||||
CleanUp+Summary
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph Functional Testings
|
|
||||||
sanity-checks-20.04
|
|
||||||
zloop-checks-20.04
|
|
||||||
functional-testing-20.04-->Part1-20.04
|
|
||||||
functional-testing-20.04-->Part2-20.04
|
|
||||||
functional-testing-20.04-->Part3-20.04
|
|
||||||
functional-testing-20.04-->Part4-20.04
|
|
||||||
functional-testing-22.04-->Part1-22.04
|
|
||||||
functional-testing-22.04-->Part2-22.04
|
|
||||||
functional-testing-22.04-->Part3-22.04
|
|
||||||
functional-testing-22.04-->Part4-22.04
|
|
||||||
sanity-checks-22.04
|
|
||||||
zloop-checks-22.04
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph Code Checking + Building
|
|
||||||
Build-Ubuntu-20.04
|
|
||||||
codeql.yml
|
|
||||||
checkstyle.yml
|
|
||||||
Build-Ubuntu-22.04
|
|
||||||
end
|
|
||||||
|
|
||||||
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-->zloop-checks-22.04
|
|
||||||
Build-Ubuntu-22.04-->functional-testing-22.04
|
|
||||||
|
|
||||||
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)
|
|
||||||
2) 2x zloop test (~10m) + 2x sanity test (~25m)
|
|
||||||
3) 4x functional testings in parts 1..4 (each ~1h)
|
|
||||||
4) cleanup and create summary
|
|
||||||
- content of summary depends on the results of the steps
|
|
||||||
|
|
||||||
When everything runs fine, the full run should be done in
|
|
||||||
about 2 hours.
|
|
||||||
|
|
||||||
The codeql.yml and checkstyle.yml are not part in this circle.
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
acl
|
|
||||||
alien
|
|
||||||
attr
|
|
||||||
autoconf
|
|
||||||
bc
|
|
||||||
build-essential
|
|
||||||
curl
|
|
||||||
dbench
|
|
||||||
debhelper-compat
|
|
||||||
dh-python
|
|
||||||
dkms
|
|
||||||
fakeroot
|
|
||||||
fio
|
|
||||||
gdb
|
|
||||||
gdebi
|
|
||||||
git
|
|
||||||
ksh
|
|
||||||
lcov
|
|
||||||
libacl1-dev
|
|
||||||
libaio-dev
|
|
||||||
libattr1-dev
|
|
||||||
libblkid-dev
|
|
||||||
libcurl4-openssl-dev
|
|
||||||
libdevmapper-dev
|
|
||||||
libelf-dev
|
|
||||||
libffi-dev
|
|
||||||
libmount-dev
|
|
||||||
libpam0g-dev
|
|
||||||
libselinux1-dev
|
|
||||||
libssl-dev
|
|
||||||
libtool
|
|
||||||
libudev-dev
|
|
||||||
linux-headers-generic
|
|
||||||
lsscsi
|
|
||||||
mdadm
|
|
||||||
nfs-kernel-server
|
|
||||||
pamtester
|
|
||||||
parted
|
|
||||||
po-debconf
|
|
||||||
python3
|
|
||||||
python3-all-dev
|
|
||||||
python3-cffi
|
|
||||||
python3-dev
|
|
||||||
python3-packaging
|
|
||||||
python3-pip
|
|
||||||
python3-setuptools
|
|
||||||
python3-sphinx
|
|
||||||
rng-tools-debian
|
|
||||||
rsync
|
|
||||||
samba
|
|
||||||
sysstat
|
|
||||||
uuid-dev
|
|
||||||
watchdog
|
|
||||||
wget
|
|
||||||
xfslibs-dev
|
|
||||||
xz-utils
|
|
||||||
zlib1g-dev
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
cppcheck
|
|
||||||
devscripts
|
|
||||||
mandoc
|
|
||||||
pax-utils
|
|
||||||
shellcheck
|
|
||||||
@@ -6,54 +6,31 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
checkstyle:
|
checkstyle:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-18.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
# https://github.com/orgs/community/discussions/47863
|
sudo apt-get update
|
||||||
sudo apt-mark hold grub-efi-amd64-signed
|
sudo apt-get install --yes -qq build-essential autoconf libtool gawk alien fakeroot linux-headers-$(uname -r)
|
||||||
sudo apt-get update --fix-missing
|
sudo apt-get install --yes -qq zlib1g-dev uuid-dev libattr1-dev libblkid-dev libselinux-dev libudev-dev libssl-dev python-dev python-setuptools python-cffi python3 python3-dev python3-setuptools python3-cffi
|
||||||
sudo apt-get upgrade
|
# packages for tests
|
||||||
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/build-dependencies.txt apt-get install -qq
|
sudo apt-get install --yes -qq parted lsscsi ksh attr acl nfs-kernel-server fio
|
||||||
sudo xargs --arg-file=${{ github.workspace }}/.github/workflows/checkstyle-dependencies.txt apt-get install -qq
|
sudo apt-get install --yes -qq mandoc cppcheck pax-utils devscripts abigail-tools
|
||||||
sudo python3 -m pip install --quiet flake8
|
sudo -E pip --quiet install flake8
|
||||||
sudo apt-get clean
|
|
||||||
|
|
||||||
# confirm that the tools are installed
|
|
||||||
# the build system doesn't fail when they are not
|
|
||||||
checkbashisms --version
|
|
||||||
cppcheck --version
|
|
||||||
flake8 --version
|
|
||||||
scanelf --version
|
|
||||||
shellcheck --version
|
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
./autogen.sh
|
sh ./autogen.sh
|
||||||
./configure
|
./configure
|
||||||
make -j$(nproc) --no-print-directory --silent
|
make -j$(nproc)
|
||||||
- name: Checkstyle
|
- name: Checkstyle
|
||||||
run: |
|
run: |
|
||||||
make -j$(nproc) --no-print-directory --silent checkstyle
|
make checkstyle
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: |
|
run: |
|
||||||
make -j$(nproc) --no-print-directory --silent lint
|
make lint
|
||||||
- name: CheckABI
|
- name: CheckABI
|
||||||
id: CheckABI
|
|
||||||
run: |
|
run: |
|
||||||
docker run -v $PWD:/source ghcr.io/openzfs/libabigail make -j$(nproc) --no-print-directory --silent checkabi
|
make checkabi
|
||||||
- name: StoreABI
|
|
||||||
if: failure() && steps.CheckABI.outcome == 'failure'
|
|
||||||
run: |
|
|
||||||
docker run -v $PWD:/source ghcr.io/openzfs/libabigail make -j$(nproc) --no-print-directory --silent storeabi
|
|
||||||
- name: Prepare artifacts
|
|
||||||
if: failure() && steps.CheckABI.outcome == 'failure'
|
|
||||||
run: |
|
|
||||||
find -name *.abi | tar -cf abi_files.tar -T -
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: failure() && steps.CheckABI.outcome == 'failure'
|
|
||||||
with:
|
|
||||||
name: New ABI files (use only if you're sure about interface changes)
|
|
||||||
path: abi_files.tar
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
name: "CodeQL"
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
analyze:
|
|
||||||
name: Analyze
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
security-events: write
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
language: [ 'cpp', 'python' ]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Set make jobs
|
|
||||||
run: |
|
|
||||||
echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v2
|
|
||||||
with:
|
|
||||||
config-file: .github/codeql-${{ matrix.language }}.yml
|
|
||||||
languages: ${{ matrix.language }}
|
|
||||||
|
|
||||||
- name: Autobuild
|
|
||||||
uses: github/codeql-action/autobuild@v2
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
|
||||||
uses: github/codeql-action/analyze@v2
|
|
||||||
with:
|
|
||||||
category: "/language:${{matrix.language}}"
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# for runtime reasons we split functional testings into N parts
|
|
||||||
# - use a define to check for missing tarfiles
|
|
||||||
FUNCTIONAL_PARTS="4"
|
|
||||||
|
|
||||||
ZTS_REPORT="tests/test-runner/bin/zts-report.py"
|
|
||||||
chmod +x $ZTS_REPORT
|
|
||||||
|
|
||||||
function output() {
|
|
||||||
echo -e $* >> Summary.md
|
|
||||||
}
|
|
||||||
|
|
||||||
function error() {
|
|
||||||
output ":bangbang: $* :bangbang:\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
# this function generates the real summary
|
|
||||||
# - expects a logfile "log" in current directory
|
|
||||||
function generate() {
|
|
||||||
# we issued some error already
|
|
||||||
test ! -s log && return
|
|
||||||
|
|
||||||
# for overview and zts-report
|
|
||||||
cat log | grep '^Test' > list
|
|
||||||
|
|
||||||
# error details
|
|
||||||
awk '/\[FAIL\]|\[KILLED\]/{ show=1; print; next; }
|
|
||||||
/\[SKIP\]|\[PASS\]/{ show=0; } show' log > err
|
|
||||||
|
|
||||||
# summary of errors
|
|
||||||
if [ -s err ]; then
|
|
||||||
output "<pre>"
|
|
||||||
$ZTS_REPORT --no-maybes ./list >> Summary.md
|
|
||||||
output "</pre>"
|
|
||||||
|
|
||||||
# generate seperate error logfile
|
|
||||||
ERRLOGS=$((ERRLOGS+1))
|
|
||||||
errfile="err-$ERRLOGS.md"
|
|
||||||
echo -e "\n## $headline (debugging)\n" >> $errfile
|
|
||||||
echo "<details><summary>Error Listing - with dmesg and dbgmsg</summary><pre>" >> $errfile
|
|
||||||
dd if=err bs=999k count=1 >> $errfile
|
|
||||||
echo "</pre></details>" >> $errfile
|
|
||||||
else
|
|
||||||
output "All tests passed :thumbsup:"
|
|
||||||
fi
|
|
||||||
|
|
||||||
output "<details><summary>Full Listing</summary><pre>"
|
|
||||||
cat list >> Summary.md
|
|
||||||
output "</pre></details>"
|
|
||||||
|
|
||||||
# remove tmp files
|
|
||||||
rm -f err list log
|
|
||||||
}
|
|
||||||
|
|
||||||
# check tarfiles and untar
|
|
||||||
function check_tarfile() {
|
|
||||||
if [ -f "$1" ]; then
|
|
||||||
tar xf "$1" || error "Tarfile $1 returns some error"
|
|
||||||
else
|
|
||||||
error "Tarfile $1 not found"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# check logfile and concatenate test results
|
|
||||||
function check_logfile() {
|
|
||||||
if [ -f "$1" ]; then
|
|
||||||
cat "$1" >> log
|
|
||||||
else
|
|
||||||
error "Logfile $1 not found"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# sanity
|
|
||||||
function summarize_s() {
|
|
||||||
headline="$1"
|
|
||||||
output "\n## $headline\n"
|
|
||||||
rm -rf testfiles
|
|
||||||
check_tarfile "$2/sanity.tar"
|
|
||||||
check_logfile "testfiles/log"
|
|
||||||
generate
|
|
||||||
}
|
|
||||||
|
|
||||||
# functional
|
|
||||||
function summarize_f() {
|
|
||||||
headline="$1"
|
|
||||||
output "\n## $headline\n"
|
|
||||||
rm -rf testfiles
|
|
||||||
for i in $(seq 1 $FUNCTIONAL_PARTS); do
|
|
||||||
tarfile="$2-part$i/part$i.tar"
|
|
||||||
check_tarfile "$tarfile"
|
|
||||||
check_logfile "testfiles/log"
|
|
||||||
done
|
|
||||||
generate
|
|
||||||
}
|
|
||||||
|
|
||||||
# https://docs.github.com/en/enterprise-server@3.6/actions/using-workflows/workflow-commands-for-github-actions#step-isolation-and-limits
|
|
||||||
# Job summaries are isolated between steps and each step is restricted to a maximum size of 1MiB.
|
|
||||||
# [ ] can not show all error findings here
|
|
||||||
# [x] split files into smaller ones and create additional steps
|
|
||||||
|
|
||||||
ERRLOGS=0
|
|
||||||
if [ ! -f Summary/Summary.md ]; then
|
|
||||||
# first call, we do the default summary (~500k)
|
|
||||||
echo -n > Summary.md
|
|
||||||
summarize_s "Sanity Tests Ubuntu 20.04" Logs-20.04-sanity
|
|
||||||
summarize_s "Sanity Tests Ubuntu 22.04" Logs-22.04-sanity
|
|
||||||
summarize_f "Functional Tests Ubuntu 20.04" Logs-20.04-functional
|
|
||||||
summarize_f "Functional Tests Ubuntu 22.04" Logs-22.04-functional
|
|
||||||
|
|
||||||
cat Summary.md >> $GITHUB_STEP_SUMMARY
|
|
||||||
mkdir -p Summary
|
|
||||||
mv *.md Summary
|
|
||||||
else
|
|
||||||
# here we get, when errors where returned in first call
|
|
||||||
test -f Summary/err-$1.md && cat Summary/err-$1.md >> $GITHUB_STEP_SUMMARY
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
function prerun() {
|
|
||||||
echo "::group::Install build dependencies"
|
|
||||||
# remove snap things, update+upgrade will be faster then
|
|
||||||
for x in lxd core20 snapd; do sudo snap remove $x; done
|
|
||||||
sudo apt-get purge snapd google-chrome-stable firefox
|
|
||||||
# https://github.com/orgs/community/discussions/47863
|
|
||||||
sudo apt-get remove grub-efi-amd64-bin grub-efi-amd64-signed shim-signed --allow-remove-essential
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt upgrade
|
|
||||||
sudo xargs --arg-file=.github/workflows/build-dependencies.txt apt-get install -qq
|
|
||||||
sudo apt-get clean
|
|
||||||
sudo dmesg -c > /var/tmp/dmesg-prerun
|
|
||||||
echo "::endgroup::"
|
|
||||||
}
|
|
||||||
|
|
||||||
function mod_build() {
|
|
||||||
echo "::group::Generate debian packages"
|
|
||||||
./autogen.sh
|
|
||||||
./configure --enable-debug --enable-debuginfo --enable-asan --enable-ubsan
|
|
||||||
make --no-print-directory --silent native-deb-utils native-deb-kmod
|
|
||||||
mv ../*.deb .
|
|
||||||
rm ./openzfs-zfs-dracut*.deb ./openzfs-zfs-dkms*.deb
|
|
||||||
echo "$ImageOS-$ImageVersion" > tests/ImageOS.txt
|
|
||||||
echo "::endgroup::"
|
|
||||||
}
|
|
||||||
|
|
||||||
function mod_install() {
|
|
||||||
# install the pre-built module only on the same runner image
|
|
||||||
MOD=`cat tests/ImageOS.txt`
|
|
||||||
if [ "$MOD" != "$ImageOS-$ImageVersion" ]; then
|
|
||||||
rm -f *.deb
|
|
||||||
mod_build
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "::group::Install and load modules"
|
|
||||||
# don't use kernel-shipped zfs modules
|
|
||||||
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
|
||||||
sudo apt-get install --fix-missing ./*.deb
|
|
||||||
|
|
||||||
# Native Debian packages enable and start the services
|
|
||||||
# Stop zfs-zed daemon, as it may interfere with some ZTS test cases
|
|
||||||
sudo systemctl stop zfs-zed
|
|
||||||
sudo depmod -a
|
|
||||||
sudo modprobe zfs
|
|
||||||
sudo dmesg
|
|
||||||
sudo dmesg -c > /var/tmp/dmesg-module-load
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
echo "::group::Report CPU information"
|
|
||||||
lscpu
|
|
||||||
cat /proc/spl/kstat/zfs/chksum_bench
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
echo "::group::Optimize storage for ZFS testings"
|
|
||||||
# remove swap and umount fast storage
|
|
||||||
# 89GiB -> rootfs + bootfs with ~80MB/s -> don't care
|
|
||||||
# 64GiB -> /mnt with 420MB/s -> new testing ssd
|
|
||||||
sudo swapoff -a
|
|
||||||
|
|
||||||
# this one is fast and mounted @ /mnt
|
|
||||||
# -> we reformat with ext4 + move it to /var/tmp
|
|
||||||
DEV="/dev/disk/azure/resource-part1"
|
|
||||||
sudo umount /mnt
|
|
||||||
sudo mkfs.ext4 -O ^has_journal -F $DEV
|
|
||||||
sudo mount -o noatime,barrier=0 $DEV /var/tmp
|
|
||||||
sudo chmod 1777 /var/tmp
|
|
||||||
|
|
||||||
# disk usage afterwards
|
|
||||||
sudo df -h /
|
|
||||||
sudo df -h /var/tmp
|
|
||||||
sudo fstrim -a
|
|
||||||
echo "::endgroup::"
|
|
||||||
}
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
build)
|
|
||||||
prerun
|
|
||||||
mod_build
|
|
||||||
;;
|
|
||||||
tests)
|
|
||||||
prerun
|
|
||||||
mod_install
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
TDIR="/usr/share/zfs/zfs-tests/tests/functional"
|
|
||||||
echo -n "TODO="
|
|
||||||
case "$1" in
|
|
||||||
part1)
|
|
||||||
# ~1h 20m
|
|
||||||
echo "cli_root"
|
|
||||||
;;
|
|
||||||
part2)
|
|
||||||
# ~1h
|
|
||||||
ls $TDIR|grep '^[a-m]'|grep -v "cli_root"|xargs|tr -s ' ' ','
|
|
||||||
;;
|
|
||||||
part3)
|
|
||||||
# ~1h
|
|
||||||
ls $TDIR|grep '^[n-qs-z]'|xargs|tr -s ' ' ','
|
|
||||||
;;
|
|
||||||
part4)
|
|
||||||
# ~1h
|
|
||||||
ls $TDIR|grep '^r'|xargs|tr -s ' ' ','
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
name: zfs-linux-tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
os:
|
|
||||||
description: 'The ubuntu version: 20.02 or 22.04'
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
|
|
||||||
zloop:
|
|
||||||
runs-on: ubuntu-${{ inputs.os }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: modules-${{ inputs.os }}
|
|
||||||
- name: Install modules
|
|
||||||
run: |
|
|
||||||
tar xzf modules-${{ inputs.os }}.tgz
|
|
||||||
.github/workflows/scripts/setup-dependencies.sh tests
|
|
||||||
- name: Tests
|
|
||||||
timeout-minutes: 30
|
|
||||||
run: |
|
|
||||||
sudo mkdir -p /var/tmp/zloop
|
|
||||||
# run for 10 minutes or at most 2 iterations for a maximum runner
|
|
||||||
# time of 20 minutes.
|
|
||||||
sudo /usr/share/zfs/zloop.sh -t 600 -I 2 -l -m1 -- -T 120 -P 60
|
|
||||||
- name: Prepare artifacts
|
|
||||||
if: failure()
|
|
||||||
run: |
|
|
||||||
sudo chmod +r -R /var/tmp/zloop/
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: failure()
|
|
||||||
with:
|
|
||||||
name: Zpool-logs-${{ inputs.os }}
|
|
||||||
path: |
|
|
||||||
/var/tmp/zloop/*/
|
|
||||||
!/var/tmp/zloop/*/vdev/
|
|
||||||
retention-days: 14
|
|
||||||
if-no-files-found: ignore
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: failure()
|
|
||||||
with:
|
|
||||||
name: Zpool-files-${{ inputs.os }}
|
|
||||||
path: |
|
|
||||||
/var/tmp/zloop/*/vdev/
|
|
||||||
retention-days: 14
|
|
||||||
if-no-files-found: ignore
|
|
||||||
|
|
||||||
sanity:
|
|
||||||
runs-on: ubuntu-${{ inputs.os }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: modules-${{ inputs.os }}
|
|
||||||
- name: Install modules
|
|
||||||
run: |
|
|
||||||
tar xzf modules-${{ inputs.os }}.tgz
|
|
||||||
.github/workflows/scripts/setup-dependencies.sh tests
|
|
||||||
- name: Tests
|
|
||||||
timeout-minutes: 60
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -o pipefail
|
|
||||||
/usr/share/zfs/zfs-tests.sh -vKR -s 3G -r sanity | scripts/zfs-tests-color.sh
|
|
||||||
- name: Prepare artifacts
|
|
||||||
if: success() || failure()
|
|
||||||
run: |
|
|
||||||
RESPATH="/var/tmp/test_results"
|
|
||||||
mv -f $RESPATH/current $RESPATH/testfiles
|
|
||||||
tar cf $RESPATH/sanity.tar -h -C $RESPATH testfiles
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: success() || failure()
|
|
||||||
with:
|
|
||||||
name: Logs-${{ inputs.os }}-sanity
|
|
||||||
path: /var/tmp/test_results/sanity.tar
|
|
||||||
if-no-files-found: ignore
|
|
||||||
|
|
||||||
functional:
|
|
||||||
runs-on: ubuntu-${{ inputs.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
tests: [ part1, part2, part3, part4 ]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: modules-${{ inputs.os }}
|
|
||||||
- name: Install modules
|
|
||||||
run: |
|
|
||||||
tar xzf modules-${{ inputs.os }}.tgz
|
|
||||||
.github/workflows/scripts/setup-dependencies.sh tests
|
|
||||||
- name: Setup tests
|
|
||||||
run: |
|
|
||||||
.github/workflows/scripts/setup-functional.sh ${{ matrix.tests }} >> $GITHUB_ENV
|
|
||||||
- name: Tests
|
|
||||||
timeout-minutes: 120
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -o pipefail
|
|
||||||
/usr/share/zfs/zfs-tests.sh -vKR -s 3G -T ${{ env.TODO }} | scripts/zfs-tests-color.sh
|
|
||||||
- name: Prepare artifacts
|
|
||||||
if: success() || failure()
|
|
||||||
run: |
|
|
||||||
RESPATH="/var/tmp/test_results"
|
|
||||||
mv -f $RESPATH/current $RESPATH/testfiles
|
|
||||||
tar cf $RESPATH/${{ matrix.tests }}.tar -h -C $RESPATH testfiles
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: success() || failure()
|
|
||||||
with:
|
|
||||||
name: Logs-${{ inputs.os }}-functional-${{ matrix.tests }}
|
|
||||||
path: /var/tmp/test_results/${{ matrix.tests }}.tar
|
|
||||||
if-no-files-found: ignore
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
name: zfs-linux
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
|
|
||||||
build:
|
|
||||||
name: Build
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [20.04, 22.04]
|
|
||||||
runs-on: ubuntu-${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
|
||||||
- name: Build modules
|
|
||||||
run: .github/workflows/scripts/setup-dependencies.sh build
|
|
||||||
- name: Prepare modules upload
|
|
||||||
run: tar czf modules-${{ matrix.os }}.tgz *.deb .github tests/test-runner tests/ImageOS.txt
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: modules-${{ matrix.os }}
|
|
||||||
path: modules-${{ matrix.os }}.tgz
|
|
||||||
retention-days: 14
|
|
||||||
|
|
||||||
testings:
|
|
||||||
name: Testing
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [20.04, 22.04]
|
|
||||||
needs: build
|
|
||||||
uses: ./.github/workflows/zfs-linux-tests.yml
|
|
||||||
with:
|
|
||||||
os: ${{ matrix.os }}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if: always()
|
|
||||||
name: Cleanup
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
needs: testings
|
|
||||||
steps:
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
- name: Generating summary
|
|
||||||
run: |
|
|
||||||
tar xzf modules-22.04/modules-22.04.tgz .github tests
|
|
||||||
.github/workflows/scripts/generate-summary.sh
|
|
||||||
# up to 4 steps, each can have 1 MiB output (for debugging log files)
|
|
||||||
- name: Summary for errors #1
|
|
||||||
run: .github/workflows/scripts/generate-summary.sh 1
|
|
||||||
- name: Summary for errors #2
|
|
||||||
run: .github/workflows/scripts/generate-summary.sh 2
|
|
||||||
- name: Summary for errors #3
|
|
||||||
run: .github/workflows/scripts/generate-summary.sh 3
|
|
||||||
- name: Summary for errors #4
|
|
||||||
run: .github/workflows/scripts/generate-summary.sh 4
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: Summary Files
|
|
||||||
path: Summary/
|
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
name: zfs-tests-functional
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
tests-functional-ubuntu:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [18.04, 20.04]
|
||||||
|
runs-on: ubuntu-${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
|
||||||
|
git alien fakeroot wget curl bc fio acl \
|
||||||
|
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
|
||||||
|
nfs-kernel-server samba rng-tools xz-utils \
|
||||||
|
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
|
||||||
|
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
||||||
|
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
|
||||||
|
libpam0g-dev pamtester python-dev python-setuptools python-cffi \
|
||||||
|
python3 python3-dev python3-setuptools python3-cffi
|
||||||
|
- name: Autogen.sh
|
||||||
|
run: |
|
||||||
|
sh autogen.sh
|
||||||
|
- name: Configure
|
||||||
|
run: |
|
||||||
|
./configure --enable-debug --enable-debuginfo
|
||||||
|
- name: Make
|
||||||
|
run: |
|
||||||
|
make --no-print-directory -s pkg-utils pkg-kmod
|
||||||
|
- name: Install
|
||||||
|
run: |
|
||||||
|
sudo dpkg -i *.deb
|
||||||
|
# Update order of directories to search for modules, otherwise
|
||||||
|
# Ubuntu will load kernel-shipped ones.
|
||||||
|
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
||||||
|
sudo depmod
|
||||||
|
sudo modprobe zfs
|
||||||
|
# Workaround to provide additional free space for testing.
|
||||||
|
# https://github.com/actions/virtual-environments/issues/2840
|
||||||
|
sudo rm -rf /usr/share/dotnet
|
||||||
|
sudo rm -rf /opt/ghc
|
||||||
|
sudo rm -rf "/usr/local/share/boost"
|
||||||
|
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||||
|
- name: Tests
|
||||||
|
run: |
|
||||||
|
/usr/share/zfs/zfs-tests.sh -v -s 3G
|
||||||
|
- name: Prepare artifacts
|
||||||
|
if: failure()
|
||||||
|
run: |
|
||||||
|
RESULTS_PATH=$(readlink -f /var/tmp/test_results/current)
|
||||||
|
sudo dmesg > $RESULTS_PATH/dmesg
|
||||||
|
sudo cp /var/log/syslog $RESULTS_PATH/
|
||||||
|
sudo chmod +r $RESULTS_PATH/*
|
||||||
|
# Replace ':' in dir names, actions/upload-artifact doesn't support it
|
||||||
|
for f in $(find $RESULTS_PATH -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: Test logs Ubuntu-${{ matrix.os }}
|
||||||
|
path: /var/tmp/test_results/20*/
|
||||||
|
if-no-files-found: ignore
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
name: zfs-tests-sanity
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
|
||||||
|
git alien fakeroot wget curl bc fio acl \
|
||||||
|
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
|
||||||
|
nfs-kernel-server samba rng-tools xz-utils \
|
||||||
|
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
|
||||||
|
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
||||||
|
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
|
||||||
|
libpam0g-dev pamtester python-dev python-setuptools python-cffi \
|
||||||
|
python3 python3-dev python3-setuptools python3-cffi
|
||||||
|
- name: Autogen.sh
|
||||||
|
run: |
|
||||||
|
sh autogen.sh
|
||||||
|
- name: Configure
|
||||||
|
run: |
|
||||||
|
./configure --enable-debug --enable-debuginfo
|
||||||
|
- name: Make
|
||||||
|
run: |
|
||||||
|
make --no-print-directory -s pkg-utils pkg-kmod
|
||||||
|
- name: Install
|
||||||
|
run: |
|
||||||
|
sudo dpkg -i *.deb
|
||||||
|
# Update order of directories to search for modules, otherwise
|
||||||
|
# Ubuntu will load kernel-shipped ones.
|
||||||
|
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
||||||
|
sudo depmod
|
||||||
|
sudo modprobe zfs
|
||||||
|
# Workaround to provide additional free space for testing.
|
||||||
|
# https://github.com/actions/virtual-environments/issues/2840
|
||||||
|
sudo rm -rf /usr/share/dotnet
|
||||||
|
sudo rm -rf /opt/ghc
|
||||||
|
sudo rm -rf "/usr/local/share/boost"
|
||||||
|
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||||
|
- name: Tests
|
||||||
|
run: |
|
||||||
|
/usr/share/zfs/zfs-tests.sh -v -s 3G -r sanity
|
||||||
|
- name: Prepare artifacts
|
||||||
|
if: failure()
|
||||||
|
run: |
|
||||||
|
RESULTS_PATH=$(readlink -f /var/tmp/test_results/current)
|
||||||
|
sudo dmesg > $RESULTS_PATH/dmesg
|
||||||
|
sudo cp /var/log/syslog $RESULTS_PATH/
|
||||||
|
sudo chmod +r $RESULTS_PATH/*
|
||||||
|
# Replace ':' in dir names, actions/upload-artifact doesn't support it
|
||||||
|
for f in $(find $RESULTS_PATH -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: Test logs
|
||||||
|
path: /var/tmp/test_results/20*/
|
||||||
|
if-no-files-found: ignore
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
name: zloop
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
TEST_DIR: /var/tmp/zloop
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install --yes -qq build-essential autoconf libtool gdb \
|
||||||
|
git alien fakeroot \
|
||||||
|
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
|
||||||
|
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
||||||
|
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
|
||||||
|
libpam0g-dev \
|
||||||
|
python-dev python-setuptools python-cffi \
|
||||||
|
python3 python3-dev python3-setuptools python3-cffi
|
||||||
|
- name: Autogen.sh
|
||||||
|
run: |
|
||||||
|
sh autogen.sh
|
||||||
|
- name: Configure
|
||||||
|
run: |
|
||||||
|
./configure --enable-debug --enable-debuginfo
|
||||||
|
- name: Make
|
||||||
|
run: |
|
||||||
|
make --no-print-directory -s pkg-utils pkg-kmod
|
||||||
|
- name: Install
|
||||||
|
run: |
|
||||||
|
sudo dpkg -i *.deb
|
||||||
|
# Update order of directories to search for modules, otherwise
|
||||||
|
# Ubuntu will load kernel-shipped ones.
|
||||||
|
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
||||||
|
sudo depmod
|
||||||
|
sudo modprobe zfs
|
||||||
|
- name: Tests
|
||||||
|
run: |
|
||||||
|
sudo mkdir -p $TEST_DIR
|
||||||
|
# run for 20 minutes to have a total runner time of 30 minutes
|
||||||
|
sudo /usr/share/zfs/zloop.sh -t 1200 -l -m1
|
||||||
|
- name: Prepare artifacts
|
||||||
|
if: failure()
|
||||||
|
run: |
|
||||||
|
sudo chmod +r -R $TEST_DIR/
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: Logs
|
||||||
|
path: |
|
||||||
|
/var/tmp/zloop/*/
|
||||||
|
!/var/tmp/zloop/*/vdev/
|
||||||
|
if-no-files-found: ignore
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: Pool files
|
||||||
|
path: |
|
||||||
|
/var/tmp/zloop/*/vdev/
|
||||||
|
if-no-files-found: ignore
|
||||||
+36
-56
@@ -1,7 +1,6 @@
|
|||||||
#
|
#
|
||||||
# This is the top-level .gitignore file:
|
# N.B.
|
||||||
# ignore everything except a list of allowed files.
|
# This is the toplevel .gitignore file.
|
||||||
#
|
|
||||||
# This is not the place for entries that are specific to
|
# This is not the place for entries that are specific to
|
||||||
# a subdirectory. Instead add those files to the
|
# a subdirectory. Instead add those files to the
|
||||||
# .gitignore file in that subdirectory.
|
# .gitignore file in that subdirectory.
|
||||||
@@ -11,57 +10,6 @@
|
|||||||
# command after changing this file, to see if there are
|
# command after changing this file, to see if there are
|
||||||
# any tracked files which get ignored after the change.
|
# any tracked files which get ignored after the change.
|
||||||
|
|
||||||
*
|
|
||||||
|
|
||||||
!.github
|
|
||||||
!cmd
|
|
||||||
!config
|
|
||||||
!contrib
|
|
||||||
!etc
|
|
||||||
!include
|
|
||||||
!lib
|
|
||||||
!man
|
|
||||||
!module
|
|
||||||
!rpm
|
|
||||||
!scripts
|
|
||||||
!tests
|
|
||||||
!udev
|
|
||||||
|
|
||||||
!.github/**
|
|
||||||
!cmd/**
|
|
||||||
!config/**
|
|
||||||
!contrib/**
|
|
||||||
!etc/**
|
|
||||||
!include/**
|
|
||||||
!lib/**
|
|
||||||
!man/**
|
|
||||||
!module/**
|
|
||||||
!rpm/**
|
|
||||||
!scripts/**
|
|
||||||
!tests/**
|
|
||||||
!udev/**
|
|
||||||
|
|
||||||
!.editorconfig
|
|
||||||
!.cirrus.yml
|
|
||||||
!.gitignore
|
|
||||||
!.gitmodules
|
|
||||||
!.mailmap
|
|
||||||
!AUTHORS
|
|
||||||
!autogen.sh
|
|
||||||
!CODE_OF_CONDUCT.md
|
|
||||||
!configure.ac
|
|
||||||
!copy-builtin
|
|
||||||
!COPYRIGHT
|
|
||||||
!LICENSE
|
|
||||||
!Makefile.am
|
|
||||||
!META
|
|
||||||
!NEWS
|
|
||||||
!NOTICE
|
|
||||||
!README.md
|
|
||||||
!RELEASES.md
|
|
||||||
!TEST
|
|
||||||
!zfs.release.in
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Normal rules
|
# Normal rules
|
||||||
#
|
#
|
||||||
@@ -83,8 +31,40 @@
|
|||||||
modules.order
|
modules.order
|
||||||
Makefile
|
Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
changelog
|
|
||||||
|
#
|
||||||
|
# Top level generated files specific to this top level dir
|
||||||
|
#
|
||||||
|
/bin
|
||||||
|
/build
|
||||||
|
/configure
|
||||||
|
/config.log
|
||||||
|
/config.status
|
||||||
|
/libtool
|
||||||
|
/zfs_config.h
|
||||||
|
/zfs_config.h.in
|
||||||
|
/zfs.release
|
||||||
|
/stamp-h1
|
||||||
|
/aclocal.m4
|
||||||
|
/autom4te.cache
|
||||||
|
|
||||||
|
#
|
||||||
|
# Top level generic files
|
||||||
|
#
|
||||||
|
!.gitignore
|
||||||
|
tags
|
||||||
|
TAGS
|
||||||
|
current
|
||||||
|
cscope.*
|
||||||
|
*.rpm
|
||||||
|
*.deb
|
||||||
|
*.tar.gz
|
||||||
*.patch
|
*.patch
|
||||||
*.orig
|
*.orig
|
||||||
*.tmp
|
|
||||||
*.log
|
*.log
|
||||||
|
*.tmp
|
||||||
|
venv
|
||||||
|
|
||||||
|
*.so
|
||||||
|
*.so.debug
|
||||||
|
*.so.full
|
||||||
|
|||||||
@@ -1,213 +0,0 @@
|
|||||||
# This file maps the name+email seen in a commit back to a canonical
|
|
||||||
# name+email. Git will replace the commit name/email with the canonical version
|
|
||||||
# wherever it sees it.
|
|
||||||
#
|
|
||||||
# If there is a commit in the history with a "wrong" name or email, list it
|
|
||||||
# here. If you regularly commit with an alternate name or email address and
|
|
||||||
# would like to ensure that you are always listed consistently in the repo, add
|
|
||||||
# mapping here.
|
|
||||||
#
|
|
||||||
# On the other hand, if you use multiple names or email addresses legitimately
|
|
||||||
# (eg you use a company email address for your paid OpenZFS work, and a
|
|
||||||
# personal address for your evening side projects), then don't map one to the
|
|
||||||
# other here.
|
|
||||||
#
|
|
||||||
# The most common formats are:
|
|
||||||
#
|
|
||||||
# Canonical Name <canonical-email>
|
|
||||||
# Canonical Name <canonical-email> <commit-email>
|
|
||||||
# Canonical Name <canonical-email> Commit Name <commit-email>
|
|
||||||
#
|
|
||||||
# See https://git-scm.com/docs/gitmailmap for more info.
|
|
||||||
|
|
||||||
# These maps are making names consistent where they have varied but the email
|
|
||||||
# address has never changed. In most cases, the full name is in the
|
|
||||||
# Signed-off-by of a commit with a matching author.
|
|
||||||
Ahelenia Ziemiańska <nabijaczleweli@gmail.com>
|
|
||||||
Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
|
|
||||||
Alex John <alex@stty.io>
|
|
||||||
Andreas Dilger <adilger@dilger.ca>
|
|
||||||
Andrew Walker <awalker@ixsystems.com>
|
|
||||||
Benedikt Neuffer <github@itfriend.de>
|
|
||||||
Chengfei Zhu <chengfeix.zhu@intel.com>
|
|
||||||
ChenHao Lu <18302010006@fudan.edu.cn>
|
|
||||||
Chris Lindee <chris.lindee+github@gmail.com>
|
|
||||||
Colm Buckley <colm@tuatha.org>
|
|
||||||
Crag Wang <crag0715@gmail.com>
|
|
||||||
Damian Szuberski <szuberskidamian@gmail.com>
|
|
||||||
Daniel Kolesa <daniel@octaforge.org>
|
|
||||||
Debabrata Banerjee <dbavatar@gmail.com>
|
|
||||||
Finix Yan <yanchongwen@hotmail.com>
|
|
||||||
Gaurav Kumar <gauravk.18@gmail.com>
|
|
||||||
Gionatan Danti <g.danti@assyoma.it>
|
|
||||||
Glenn Washburn <development@efficientek.com>
|
|
||||||
Gordan Bobic <gordan.bobic@gmail.com>
|
|
||||||
Gregory Bartholomew <gregory.lee.bartholomew@gmail.com>
|
|
||||||
hedong zhang <h_d_zhang@163.com>
|
|
||||||
Ilkka Sovanto <github@ilkka.kapsi.fi>
|
|
||||||
InsanePrawn <Insane.Prawny@gmail.com>
|
|
||||||
Jason Cohen <jwittlincohen@gmail.com>
|
|
||||||
Jason Harmening <jason.harmening@gmail.com>
|
|
||||||
Jeremy Faulkner <gldisater@gmail.com>
|
|
||||||
Jinshan Xiong <jinshan.xiong@gmail.com>
|
|
||||||
John Poduska <jpoduska@datto.com>
|
|
||||||
Justin Scholz <git@justinscholz.de>
|
|
||||||
Ka Ho Ng <khng300@gmail.com>
|
|
||||||
Kash Pande <github@tripleback.net>
|
|
||||||
Kay Pedersen <christianpe96@gmail.com>
|
|
||||||
KernelOfTruth <kerneloftruth@gmail.com>
|
|
||||||
Liu Hua <liu.hua130@zte.com.cn>
|
|
||||||
Liu Qing <winglq@gmail.com>
|
|
||||||
loli10K <ezomori.nozomu@gmail.com>
|
|
||||||
Mart Frauenlob <allkind@fastest.cc>
|
|
||||||
Matthias Blankertz <matthias@blankertz.org>
|
|
||||||
Michael Gmelin <grembo@FreeBSD.org>
|
|
||||||
Olivier Mazouffre <olivier.mazouffre@ims-bordeaux.fr>
|
|
||||||
Piotr Kubaj <pkubaj@anongoth.pl>
|
|
||||||
Quentin Zdanis <zdanisq@gmail.com>
|
|
||||||
Roberto Ricci <ricci@disroot.org>
|
|
||||||
Rob Norris <robn@despairlabs.com>
|
|
||||||
Rob Norris <rob.norris@klarasystems.com>
|
|
||||||
Sam Lunt <samuel.j.lunt@gmail.com>
|
|
||||||
Sanjeev Bagewadi <sanjeev.bagewadi@gmail.com>
|
|
||||||
Stoiko Ivanov <github@nomore.at>
|
|
||||||
Tamas TEVESZ <ice@extreme.hu>
|
|
||||||
WHR <msl0000023508@gmail.com>
|
|
||||||
Yanping Gao <yanping.gao@xtaotech.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
|
|
||||||
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@myhost.(none)>
|
|
||||||
Brian Behlendorf <behlendorf1@llnl.gov> <ubuntu@ip-172-31-16-145.us-west-1.compute.internal>
|
|
||||||
Brian Behlendorf <behlendorf1@llnl.gov> <ubuntu@ip-172-31-20-6.us-west-1.compute.internal>
|
|
||||||
Herb Wartens <wartens2@llnl.gov> <wartens2@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>
|
|
||||||
Ned Bass <bass6@llnl.gov> <bass6@zeno1.(none)>
|
|
||||||
Tulsi Jain <tulsi.jain@delphix.com> <tulsi.jain@Tulsi-Jains-MacBook-Pro.local>
|
|
||||||
|
|
||||||
# Mappings from Github no-reply addresses
|
|
||||||
ajs124 <git@ajs124.de> <ajs124@users.noreply.github.com>
|
|
||||||
Alek Pinchuk <apinchuk@axcient.com> <alek-p@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>
|
|
||||||
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>
|
|
||||||
Andrew J. Hesford <ajh@sideband.org> <48421688+ahesford@users.noreply.github.com>>
|
|
||||||
Andrew Sun <me@andrewsun.com> <as-com@users.noreply.github.com>
|
|
||||||
Aron Xu <happyaron.xu@gmail.com> <happyaron@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>
|
|
||||||
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>
|
|
||||||
Brad Forschinger <github@bnjf.id.au> <bnjf@users.noreply.github.com>
|
|
||||||
Brandon Thetford <brandon@dodecatec.com> <dodexahedron@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>
|
|
||||||
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>
|
|
||||||
Damian Szuberski <szuberskidamian@gmail.com> <30863496+szubersk@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 Reichelt <hacking@nachtgeist.net> <nachtgeist@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>
|
|
||||||
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>
|
|
||||||
Edmund Nadolski <edmund.nadolski@ixsystems.com> <137826107+ednadolski-ix@users.noreply.github.com>
|
|
||||||
Érico Nogueira <erico.erc@gmail.com> <34201958+ericonr@users.noreply.github.com>
|
|
||||||
Fedor Uporov <fuporov.vstack@gmail.com> <60701163+fuporovvStack@users.noreply.github.com>
|
|
||||||
Felix Dörre <felix@dogcraft.de> <felixdoerre@users.noreply.github.com>
|
|
||||||
Felix Neumärker <xdch47@posteo.de> <34678034+xdch47@users.noreply.github.com>
|
|
||||||
Finix Yan <yancw@info2soft.com> <Finix1979@users.noreply.github.com>
|
|
||||||
Gaurav Kumar <gauravk.18@gmail.com> <gaurkuma@users.noreply.github.com>
|
|
||||||
George Gaydarov <git@gg7.io> <gg7@users.noreply.github.com>
|
|
||||||
Georgy Yakovlev <gyakovlev@gentoo.org> <168902+gyakovlev@users.noreply.github.com>
|
|
||||||
Gerardwx <gerardw@alum.mit.edu> <Gerardwx@users.noreply.github.com>
|
|
||||||
Gian-Carlo DeFazio <defazio1@llnl.gov> <defaziogiancarlo@users.noreply.github.com>
|
|
||||||
Giuseppe Di Natale <dinatale2@llnl.gov> <dinatale2@users.noreply.github.com>
|
|
||||||
Hajo Möller <dasjoe@gmail.com> <dasjoe@users.noreply.github.com>
|
|
||||||
Harry Mallon <hjmallon@gmail.com> <1816667+hjmallon@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>
|
|
||||||
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>
|
|
||||||
Jeff Dike <jdike@akamai.com> <52420226+jdike@users.noreply.github.com>
|
|
||||||
Jitendra Patidar <jitendra.patidar@nutanix.com> <53164267+jsai20@users.noreply.github.com>
|
|
||||||
João Carlos Mendes Luís <jonny@jonny.eng.br> <dioni21@users.noreply.github.com>
|
|
||||||
John Eismeier <john.eismeier@gmail.com> <32205350+jeis2497052@users.noreply.github.com>
|
|
||||||
John L. Hammond <john.hammond@intel.com> <35266395+jhammond-intel@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>
|
|
||||||
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>
|
|
||||||
Kevin Greene <kevin.greene@delphix.com> <104801862+kxgreene@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>
|
|
||||||
Krzysztof Piecuch <piecuch@kpiecuch.pl> <3964215+pikrzysztof@users.noreply.github.com>
|
|
||||||
Kyle Evans <kevans@FreeBSD.org> <kevans91@users.noreply.github.com>
|
|
||||||
Laurențiu Nicola <lnicola@dend.ro> <lnicola@users.noreply.github.com>
|
|
||||||
loli10K <ezomori.nozomu@gmail.com> <loli10K@users.noreply.github.com>
|
|
||||||
Lorenz Hüdepohl <dev@stellardeath.org> <lhuedepohl@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>
|
|
||||||
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>
|
|
||||||
Michael Niewöhner <foss@mniewoehner.de> <c0d3z3r0@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>
|
|
||||||
Nick Mattis <nickm970@gmail.com> <nmattis@users.noreply.github.com>
|
|
||||||
omni <omni+vagant@hack.org> <79493359+omnivagant@users.noreply.github.com>
|
|
||||||
Pablo Correa Gómez <ablocorrea@hotmail.com> <32678034+pablofsf@users.noreply.github.com>
|
|
||||||
Paul Zuchowski <pzuchowski@datto.com> <31706010+PaulZ-98@users.noreply.github.com>
|
|
||||||
Peter Ashford <ashford@accs.com> <pashford@users.noreply.github.com>
|
|
||||||
Peter Dave Hello <hsu@peterdavehello.org> <PeterDaveHello@users.noreply.github.com>
|
|
||||||
Peter Wirdemo <peter.wirdemo@gmail.com> <4224155+pewo@users.noreply.github.com>
|
|
||||||
Petros Koutoupis <petros@petroskoutoupis.com> <pkoutoupis@users.noreply.github.com>
|
|
||||||
Ping Huang <huangping@smartx.com> <101400146+hpingfs@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>
|
|
||||||
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>
|
|
||||||
Roman Strashkin <roman.strashkin@nexenta.com> <Ramzec@users.noreply.github.com>
|
|
||||||
Ryan Hirasaki <ryanhirasaki@gmail.com> <4690732+RyanHir@users.noreply.github.com>
|
|
||||||
Samuel Wycliffe J <samwyc@hpe.com> <115969550+samwyc@users.noreply.github.com>
|
|
||||||
Samuel Wycliffe <samuelwycliffe@gmail.com> <50765275+npc203@users.noreply.github.com>
|
|
||||||
Savyasachee Jha <hi@savyasacheejha.com> <savyajha@users.noreply.github.com>
|
|
||||||
Scott Colby <scott@scolby.com> <scolby33@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>
|
|
||||||
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>
|
|
||||||
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>
|
|
||||||
Tony Perkins <tperkins@datto.com> <62951051+tony-zfs@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>
|
|
||||||
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>
|
|
||||||
Vipin Kumar Verma <vipin.verma@hpe.com> <75025470+vermavipinkumar@users.noreply.github.com>
|
|
||||||
Wolfgang Bumiller <w.bumiller@proxmox.com> <Blub@users.noreply.github.com>
|
|
||||||
xtouqh <xtouqh@hotmail.com> <72357159+xtouqh@users.noreply.github.com>
|
|
||||||
Yuri Pankov <yuripv@FreeBSD.org> <113725409+yuripv@users.noreply.github.com>
|
|
||||||
Yuri Pankov <yuripv@FreeBSD.org> <82001006+yuripv@users.noreply.github.com>
|
|
||||||
@@ -10,663 +10,299 @@ PAST MAINTAINERS:
|
|||||||
CONTRIBUTORS:
|
CONTRIBUTORS:
|
||||||
|
|
||||||
Aaron Fineman <abyxcos@gmail.com>
|
Aaron Fineman <abyxcos@gmail.com>
|
||||||
Adam D. Moss <c@yotes.com>
|
|
||||||
Adam Leventhal <ahl@delphix.com>
|
Adam Leventhal <ahl@delphix.com>
|
||||||
Adam Stevko <adam.stevko@gmail.com>
|
Adam Stevko <adam.stevko@gmail.com>
|
||||||
adisbladis <adis@blad.is>
|
|
||||||
Adrian Chadd <adrian@freebsd.org>
|
|
||||||
Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
|
|
||||||
Ahmed G <ahmedg@delphix.com>
|
Ahmed G <ahmedg@delphix.com>
|
||||||
Aidan Harris <me@aidanharr.is>
|
|
||||||
AJ Jordan <alex@strugee.net>
|
|
||||||
ajs124 <git@ajs124.de>
|
|
||||||
Akash Ayare <aayare@delphix.com>
|
Akash Ayare <aayare@delphix.com>
|
||||||
Akash B <akash-b@hpe.com>
|
|
||||||
Alan Somers <asomers@gmail.com>
|
Alan Somers <asomers@gmail.com>
|
||||||
Alar Aun <spamtoaun@gmail.com>
|
Alar Aun <spamtoaun@gmail.com>
|
||||||
Albert Lee <trisk@nexenta.com>
|
Albert Lee <trisk@nexenta.com>
|
||||||
Alec Salazar <alec.j.salazar@gmail.com>
|
Alec Salazar <alec.j.salazar@gmail.com>
|
||||||
Alejandro Colomar <Colomar.6.4.3@GMail.com>
|
|
||||||
Alejandro R. Sedeño <asedeno@mit.edu>
|
Alejandro R. Sedeño <asedeno@mit.edu>
|
||||||
Alek Pinchuk <alek@nexenta.com>
|
Alek Pinchuk <alek@nexenta.com>
|
||||||
Aleksa Sarai <cyphar@cyphar.com>
|
|
||||||
Alexander Eremin <a.eremin@nexenta.com>
|
|
||||||
Alexander Lobakin <alobakin@pm.me>
|
|
||||||
Alexander Motin <mav@freebsd.org>
|
|
||||||
Alexander Pyhalov <apyhalov@gmail.com>
|
|
||||||
Alexander Richardson <Alexander.Richardson@cl.cam.ac.uk>
|
|
||||||
Alexander Stetsenko <ams@nexenta.com>
|
|
||||||
Alex Braunegg <alex.braunegg@gmail.com>
|
Alex Braunegg <alex.braunegg@gmail.com>
|
||||||
Alexey Shvetsov <alexxy@gentoo.org>
|
|
||||||
Alexey Smirnoff <fling@member.fsf.org>
|
|
||||||
Alex John <alex@stty.io>
|
|
||||||
Alex McWhirter <alexmcwhirter@triadic.us>
|
Alex McWhirter <alexmcwhirter@triadic.us>
|
||||||
Alex Reece <alex@delphix.com>
|
Alex Reece <alex@delphix.com>
|
||||||
Alex Wilson <alex.wilson@joyent.com>
|
Alex Wilson <alex.wilson@joyent.com>
|
||||||
Alex Zhuravlev <alexey.zhuravlev@intel.com>
|
Alex Zhuravlev <alexey.zhuravlev@intel.com>
|
||||||
|
Alexander Eremin <a.eremin@nexenta.com>
|
||||||
|
Alexander Motin <mav@freebsd.org>
|
||||||
|
Alexander Pyhalov <apyhalov@gmail.com>
|
||||||
|
Alexander Stetsenko <ams@nexenta.com>
|
||||||
|
Alexey Shvetsov <alexxy@gentoo.org>
|
||||||
|
Alexey Smirnoff <fling@member.fsf.org>
|
||||||
Allan Jude <allanjude@freebsd.org>
|
Allan Jude <allanjude@freebsd.org>
|
||||||
Allen Holl <allen.m.holl@gmail.com>
|
|
||||||
Alphan Yılmaz <alphanyilmaz@gmail.com>
|
|
||||||
alteriks <alteriks@gmail.com>
|
|
||||||
Alyssa Ross <hi@alyssa.is>
|
|
||||||
Ameer Hamza <ahamza@ixsystems.com>
|
|
||||||
Anatoly Borodin <anatoly.borodin@gmail.com>
|
|
||||||
AndCycle <andcycle@andcycle.idv.tw>
|
AndCycle <andcycle@andcycle.idv.tw>
|
||||||
Andrea Gelmini <andrea.gelmini@gelma.net>
|
|
||||||
Andrea Righi <andrea.righi@canonical.com>
|
|
||||||
Andreas Buschmann <andreas.buschmann@tech.net.de>
|
Andreas Buschmann <andreas.buschmann@tech.net.de>
|
||||||
Andreas Dilger <adilger@intel.com>
|
Andreas Dilger <adilger@intel.com>
|
||||||
Andreas Vögele <andreas@andreasvoegele.com>
|
|
||||||
Andrew Barnes <barnes333@gmail.com>
|
Andrew Barnes <barnes333@gmail.com>
|
||||||
Andrew Hamilton <ahamilto@tjhsst.edu>
|
Andrew Hamilton <ahamilto@tjhsst.edu>
|
||||||
Andrew Innes <andrew.c12@gmail.com>
|
|
||||||
Andrew J. Hesford <ajh@sideband.org>
|
|
||||||
Andrew Reid <ColdCanuck@nailedtotheperch.com>
|
Andrew Reid <ColdCanuck@nailedtotheperch.com>
|
||||||
Andrew Stormont <andrew.stormont@nexenta.com>
|
Andrew Stormont <andrew.stormont@nexenta.com>
|
||||||
Andrew Sun <me@andrewsun.com>
|
|
||||||
Andrew Tselischev <andrewtselischev@gmail.com>
|
Andrew Tselischev <andrewtselischev@gmail.com>
|
||||||
Andrew Turner <andrew@fubar.geek.nz>
|
|
||||||
Andrew Walker <awalker@ixsystems.com>
|
|
||||||
Andrey Prokopenko <job@terem.fr>
|
|
||||||
Andrey Vesnovaty <andrey.vesnovaty@gmail.com>
|
Andrey Vesnovaty <andrey.vesnovaty@gmail.com>
|
||||||
Andriy Gapon <avg@freebsd.org>
|
Andriy Gapon <avg@freebsd.org>
|
||||||
Andy Bakun <github@thwartedefforts.org>
|
Andy Bakun <github@thwartedefforts.org>
|
||||||
Andy Fiddaman <omnios@citrus-it.co.uk>
|
|
||||||
Aniruddha Shankar <k@191a.net>
|
Aniruddha Shankar <k@191a.net>
|
||||||
Anton Gubarkov <anton.gubarkov@gmail.com>
|
|
||||||
Antonio Russo <antonio.e.russo@gmail.com>
|
Antonio Russo <antonio.e.russo@gmail.com>
|
||||||
Arkadiusz Bubała <arkadiusz.bubala@open-e.com>
|
Arkadiusz Bubała <arkadiusz.bubala@open-e.com>
|
||||||
Armin Wehrfritz <dkxls23@gmail.com>
|
|
||||||
Arne Jansen <arne@die-jansens.de>
|
Arne Jansen <arne@die-jansens.de>
|
||||||
Aron Xu <happyaron.xu@gmail.com>
|
Aron Xu <happyaron.xu@gmail.com>
|
||||||
Arshad Hussain <arshad.hussain@aeoncomputing.com>
|
|
||||||
Arun KV <arun.kv@datacore.com>
|
|
||||||
Arvind Sankar <nivedita@alum.mit.edu>
|
|
||||||
Attila Fülöp <attila@fueloep.org>
|
|
||||||
Avatat <kontakt@avatat.pl>
|
|
||||||
Bart Coddens <bart.coddens@gmail.com>
|
Bart Coddens <bart.coddens@gmail.com>
|
||||||
Basil Crow <basil.crow@delphix.com>
|
Basil Crow <basil.crow@delphix.com>
|
||||||
Bassu <bassu@phi9.com>
|
Huang Liu <liu.huang@zte.com.cn>
|
||||||
Ben Allen <bsallen@alcf.anl.gov>
|
Ben Allen <bsallen@alcf.anl.gov>
|
||||||
Ben Cordero <bencord0@condi.me>
|
|
||||||
Benda Xu <orv@debian.org>
|
|
||||||
Benedikt Neuffer <github@itfriend.de>
|
|
||||||
Benjamin Albrecht <git@albrecht.io>
|
|
||||||
Benjamin Gentil <benjgentil.pro@gmail.com>
|
|
||||||
Benjamin Sherman <benjamin@holyarmy.org>
|
|
||||||
Ben McGough <bmcgough@fredhutch.org>
|
|
||||||
Ben Rubson <ben.rubson@gmail.com>
|
Ben Rubson <ben.rubson@gmail.com>
|
||||||
Ben Wolsieffer <benwolsieffer@gmail.com>
|
Benjamin Albrecht <git@albrecht.io>
|
||||||
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 Lewis <brad.lewis@delphix.com>
|
Brad Lewis <brad.lewis@delphix.com>
|
||||||
Brandon Thetford <brandon@dodecatec.com>
|
|
||||||
Brian Atkinson <bwa@g.clemson.edu>
|
|
||||||
Brian Behlendorf <behlendorf1@llnl.gov>
|
Brian Behlendorf <behlendorf1@llnl.gov>
|
||||||
Brian J. Murrell <brian@sun.com>
|
Brian J. Murrell <brian@sun.com>
|
||||||
Brooks Davis <brooks@one-eyed-alien.net>
|
|
||||||
BtbN <btbn@btbn.de>
|
|
||||||
bunder2015 <omfgbunder@gmail.com>
|
|
||||||
buzzingwires <buzzingwires@outlook.com>
|
|
||||||
bzzz77 <bzzz.tomas@gmail.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>
|
||||||
Cedric Maunoury <cedric.maunoury@gmail.com>
|
|
||||||
Chaoyu Zhang <zhang.chaoyu@zte.com.cn>
|
Chaoyu Zhang <zhang.chaoyu@zte.com.cn>
|
||||||
Charles Suh <charles.suh@gmail.com>
|
|
||||||
Chen Can <chen.can2@zte.com.cn>
|
Chen Can <chen.can2@zte.com.cn>
|
||||||
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 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 Wedgwood <cw@f00f.org>
|
||||||
|
Chris Williamson <chris.williamson@delphix.com>
|
||||||
|
Chris Zubrzycki <github@mid-earth.net>
|
||||||
|
Christ Schlacta <aarcane@aarcane.info>
|
||||||
Christer Ekholm <che@chrekh.se>
|
Christer Ekholm <che@chrekh.se>
|
||||||
Christian Kohlschütter <christian@kohlschutter.com>
|
Christian Kohlschütter <christian@kohlschutter.com>
|
||||||
Christian Neukirchen <chneukirchen@gmail.com>
|
Christian Neukirchen <chneukirchen@gmail.com>
|
||||||
Christian Schwarz <me@cschwarz.com>
|
Christian Schwarz <me@cschwarz.com>
|
||||||
Christopher Voltz <cjunk@voltz.ws>
|
Christopher Voltz <cjunk@voltz.ws>
|
||||||
Christ Schlacta <aarcane@aarcane.info>
|
|
||||||
Chris Wedgwood <cw@f00f.org>
|
|
||||||
Chris Williamson <chris.williamson@delphix.com>
|
|
||||||
Chris Zubrzycki <github@mid-earth.net>
|
|
||||||
Chuck Tuffli <ctuffli@gmail.com>
|
|
||||||
Chunwei Chen <david.chen@nutanix.com>
|
Chunwei Chen <david.chen@nutanix.com>
|
||||||
Clemens Fruhwirth <clemens@endorphin.org>
|
Clemens Fruhwirth <clemens@endorphin.org>
|
||||||
Clemens Lang <cl@clang.name>
|
|
||||||
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>
|
|
||||||
Crag Wang <crag0715@gmail.com>
|
|
||||||
Craig Loomis <cloomis@astro.princeton.edu>
|
Craig Loomis <cloomis@astro.princeton.edu>
|
||||||
Craig Sanders <github@taz.net.au>
|
Craig Sanders <github@taz.net.au>
|
||||||
Cyril Plisko <cyril.plisko@infinidat.com>
|
Cyril Plisko <cyril.plisko@infinidat.com>
|
||||||
Cy Schubert <cy@FreeBSD.org>
|
DHE <git@dehacked.net>
|
||||||
Cédric Berger <cedric@precidata.com>
|
|
||||||
Dacian Reece-Stremtan <dacianstremtan@gmail.com>
|
|
||||||
Dag-Erling Smørgrav <des@FreeBSD.org>
|
|
||||||
Damiano Albani <damiano.albani@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 Hoffman <dj.hoffman@delphix.com>
|
|
||||||
Daniel Kobras <d.kobras@science-computing.de>
|
|
||||||
Daniel Kolesa <daniel@octaforge.org>
|
|
||||||
Daniel Perry <dtperry@amazon.com>
|
|
||||||
Daniel Reichelt <hacking@nachtgeist.net>
|
|
||||||
Daniel Stevenson <bot@dstev.net>
|
|
||||||
Daniel Verite <daniel@verite.pro>
|
|
||||||
Daniil Lunev <d.lunev.mail@gmail.com>
|
|
||||||
Dan Kimmel <dan.kimmel@delphix.com>
|
Dan Kimmel <dan.kimmel@delphix.com>
|
||||||
Dan McDonald <danmcd@nexenta.com>
|
Dan McDonald <danmcd@nexenta.com>
|
||||||
Dan Swartzendruber <dswartz@druber.com>
|
Dan Swartzendruber <dswartz@druber.com>
|
||||||
Dan Vatca <dan.vatca@gmail.com>
|
Dan Vatca <dan.vatca@gmail.com>
|
||||||
|
Daniel Hoffman <dj.hoffman@delphix.com>
|
||||||
|
Daniel Verite <daniel@verite.pro>
|
||||||
|
Daniil Lunev <d.lunev.mail@gmail.com>
|
||||||
Darik Horn <dajhorn@vanadac.com>
|
Darik Horn <dajhorn@vanadac.com>
|
||||||
Dave Eddy <dave@daveeddy.com>
|
Dave Eddy <dave@daveeddy.com>
|
||||||
David Hedberg <david@qzx.se>
|
|
||||||
David Lamparter <equinox@diac24.net>
|
David Lamparter <equinox@diac24.net>
|
||||||
David Qian <david.qian@intel.com>
|
David Qian <david.qian@intel.com>
|
||||||
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>
|
|
||||||
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>
|
|
||||||
Didier Roche <didrocks@ubuntu.com>
|
|
||||||
Dimitri John Ledkov <xnox@ubuntu.com>
|
Dimitri John Ledkov <xnox@ubuntu.com>
|
||||||
Dimitry Andric <dimitry@andric.com>
|
|
||||||
Dirkjan Bussink <d.bussink@gmail.com>
|
|
||||||
Dmitry Khasanov <pik4ez@gmail.com>
|
Dmitry Khasanov <pik4ez@gmail.com>
|
||||||
Dominic Pearson <dsp@technoanimal.net>
|
|
||||||
Dominik Hassler <hadfl@omniosce.org>
|
Dominik Hassler <hadfl@omniosce.org>
|
||||||
Dominik Honnef <dominikh@fork-bomb.org>
|
Dominik Honnef <dominikh@fork-bomb.org>
|
||||||
Don Brady <don.brady@delphix.com>
|
Don Brady <don.brady@delphix.com>
|
||||||
Doug Rabson <dfr@rabson.org>
|
|
||||||
Dr. András Korn <korn-github.com@elan.rulez.org>
|
Dr. András Korn <korn-github.com@elan.rulez.org>
|
||||||
Dries Michiels <driesm.michiels@gmail.com>
|
|
||||||
Edmund Nadolski <edmund.nadolski@ixsystems.com>
|
|
||||||
Eitan Adler <lists@eitanadler.com>
|
|
||||||
Eli Rosenthal <eli.rosenthal@delphix.com>
|
Eli Rosenthal <eli.rosenthal@delphix.com>
|
||||||
Eli Schwartz <eschwartz93@gmail.com>
|
|
||||||
Eric Desrochers <eric.desrochers@canonical.com>
|
Eric Desrochers <eric.desrochers@canonical.com>
|
||||||
Eric Dillmann <eric@jave.fr>
|
Eric Dillmann <eric@jave.fr>
|
||||||
Eric Schrock <Eric.Schrock@delphix.com>
|
Eric Schrock <Eric.Schrock@delphix.com>
|
||||||
Ethan Coe-Renner <coerenner1@llnl.gov>
|
|
||||||
Etienne Dechamps <etienne@edechamps.fr>
|
Etienne Dechamps <etienne@edechamps.fr>
|
||||||
Evan Allrich <eallrich@gmail.com>
|
|
||||||
Evan Harris <eharris@puremagic.com>
|
|
||||||
Evan Susarret <evansus@gmail.com>
|
Evan Susarret <evansus@gmail.com>
|
||||||
Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
||||||
Fabio Buso <dev.siroibaf@gmail.com>
|
|
||||||
Fabio Scaccabarozzi <fsvm88@gmail.com>
|
|
||||||
Fajar A. Nugraha <github@fajar.net>
|
Fajar A. Nugraha <github@fajar.net>
|
||||||
Fan Yong <fan.yong@intel.com>
|
Fan Yong <fan.yong@intel.com>
|
||||||
fbynite <fbynite@users.noreply.github.com>
|
|
||||||
Fedor Uporov <fuporov.vstack@gmail.com>
|
|
||||||
Felix Dörre <felix@dogcraft.de>
|
|
||||||
Felix Neumärker <xdch47@posteo.de>
|
|
||||||
Feng Sun <loyou85@gmail.com>
|
Feng Sun <loyou85@gmail.com>
|
||||||
Finix Yan <yancw@info2soft.com>
|
|
||||||
Francesco Mazzoli <f@mazzo.li>
|
|
||||||
Frederik Wessels <wessels147@gmail.com>
|
Frederik Wessels <wessels147@gmail.com>
|
||||||
Frédéric Vanniere <f.vanniere@planet-work.com>
|
Frédéric Vanniere <f.vanniere@planet-work.com>
|
||||||
Gabriel A. Devenyi <gdevenyi@gmail.com>
|
|
||||||
Garrett D'Amore <garrett@nexenta.com>
|
Garrett D'Amore <garrett@nexenta.com>
|
||||||
Garrett Fields <ghfields@gmail.com>
|
|
||||||
Garrison Jensen <garrison.jensen@gmail.com>
|
Garrison Jensen <garrison.jensen@gmail.com>
|
||||||
Gary Mills <gary_mills@fastmail.fm>
|
Gary Mills <gary_mills@fastmail.fm>
|
||||||
Gaurav Kumar <gauravk.18@gmail.com>
|
Gaurav Kumar <gauravk.18@gmail.com>
|
||||||
GeLiXin <ge.lixin@zte.com.cn>
|
GeLiXin <ge.lixin@zte.com.cn>
|
||||||
George Amanakis <g_amanakis@yahoo.com>
|
George Amanakis <g_amanakis@yahoo.com>
|
||||||
George Diamantopoulos <georgediam@gmail.com>
|
|
||||||
George Gaydarov <git@gg7.io>
|
|
||||||
George Melikov <mail@gmelikov.ru>
|
George Melikov <mail@gmelikov.ru>
|
||||||
George Wilson <gwilson@delphix.com>
|
George Wilson <gwilson@delphix.com>
|
||||||
Georgy Yakovlev <ya@sysdump.net>
|
Georgy Yakovlev <ya@sysdump.net>
|
||||||
Gerardwx <gerardw@alum.mit.edu>
|
|
||||||
Gian-Carlo DeFazio <defazio1@llnl.gov>
|
|
||||||
Gionatan Danti <g.danti@assyoma.it>
|
|
||||||
Giuseppe Di Natale <guss80@gmail.com>
|
Giuseppe Di Natale <guss80@gmail.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 Ross <gwr@nexenta.com>
|
Gordon Ross <gwr@nexenta.com>
|
||||||
Gordon Tetlow <gordon@freebsd.org>
|
|
||||||
Graham Christensen <graham@grahamc.com>
|
|
||||||
Graham Perrin <grahamperrin@gmail.com>
|
|
||||||
Gregor Kopka <gregor@kopka.net>
|
Gregor Kopka <gregor@kopka.net>
|
||||||
Gregory Bartholomew <gregory.lee.bartholomew@gmail.com>
|
|
||||||
grembo <freebsd@grem.de>
|
|
||||||
Grischa Zengel <github.zfsonlinux@zengel.info>
|
Grischa Zengel <github.zfsonlinux@zengel.info>
|
||||||
grodik <pat@litke.dev>
|
|
||||||
Gunnar Beutner <gunnar@beutner.name>
|
Gunnar Beutner <gunnar@beutner.name>
|
||||||
Gvozden Neskovic <neskovic@gmail.com>
|
Gvozden Neskovic <neskovic@gmail.com>
|
||||||
Hajo Möller <dasjoe@gmail.com>
|
Hajo Möller <dasjoe@gmail.com>
|
||||||
Han Gao <rabenda.cn@gmail.com>
|
|
||||||
Hans Rosenfeld <hans.rosenfeld@nexenta.com>
|
Hans Rosenfeld <hans.rosenfeld@nexenta.com>
|
||||||
Harald van Dijk <harald@gigawatt.nl>
|
|
||||||
Harry Mallon <hjmallon@gmail.com>
|
|
||||||
Harry Sintonen <github-piru@kyber.fi>
|
|
||||||
HC <mmttdebbcc@yahoo.com>
|
|
||||||
hedong zhang <h_d_zhang@163.com>
|
|
||||||
Heitor Alves de Siqueira <halves@canonical.com>
|
|
||||||
Henrik Riomar <henrik.riomar@gmail.com>
|
|
||||||
Herb Wartens <wartens2@llnl.gov>
|
|
||||||
Hiếu Lê <leorize+oss@disroot.org>
|
|
||||||
Huang Liu <liu.huang@zte.com.cn>
|
|
||||||
Håkan Johansson <f96hajo@chalmers.se>
|
Håkan Johansson <f96hajo@chalmers.se>
|
||||||
Igor K <igor@dilos.org>
|
|
||||||
Igor Kozhukhov <ikozhukhov@gmail.com>
|
Igor Kozhukhov <ikozhukhov@gmail.com>
|
||||||
Igor Lvovsky <ilvovsky@gmail.com>
|
Igor Lvovsky <ilvovsky@gmail.com>
|
||||||
ilbsmart <wgqimut@gmail.com>
|
|
||||||
Ilkka Sovanto <github@ilkka.kapsi.fi>
|
|
||||||
illiliti <illiliti@protonmail.com>
|
|
||||||
ilovezfs <ilovezfs@icloud.com>
|
|
||||||
InsanePrawn <Insane.Prawny@gmail.com>
|
|
||||||
Isaac Huang <he.huang@intel.com>
|
Isaac Huang <he.huang@intel.com>
|
||||||
|
JK Dingwall <james@dingwall.me.uk>
|
||||||
Jacek Fefliński <feflik@gmail.com>
|
Jacek Fefliński <feflik@gmail.com>
|
||||||
Jacob Adams <tookmund@gmail.com>
|
|
||||||
Jake Howard <git@theorangeone.net>
|
|
||||||
James Cowgill <james.cowgill@mips.com>
|
James Cowgill <james.cowgill@mips.com>
|
||||||
James H <james@kagisoft.co.uk>
|
|
||||||
James Lee <jlee@thestaticvoid.com>
|
James Lee <jlee@thestaticvoid.com>
|
||||||
James Pan <jiaming.pan@yahoo.com>
|
James Pan <jiaming.pan@yahoo.com>
|
||||||
James Wah <james@laird-wah.net>
|
|
||||||
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 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>
|
|
||||||
Jeff Dike <jdike@akamai.com>
|
|
||||||
Jeremy Faulkner <gldisater@gmail.com>
|
|
||||||
Jeremy Gill <jgill@parallax-innovations.com>
|
Jeremy Gill <jgill@parallax-innovations.com>
|
||||||
Jeremy Jones <jeremy@delphix.com>
|
Jeremy Jones <jeremy@delphix.com>
|
||||||
Jeremy Visser <jeremy.visser@gmail.com>
|
|
||||||
Jerry Jelinek <jerry.jelinek@joyent.com>
|
Jerry Jelinek <jerry.jelinek@joyent.com>
|
||||||
Jessica Clarke <jrtc27@jrtc27.com>
|
|
||||||
Jinshan Xiong <jinshan.xiong@intel.com>
|
Jinshan Xiong <jinshan.xiong@intel.com>
|
||||||
Jitendra Patidar <jitendra.patidar@nutanix.com>
|
|
||||||
JK Dingwall <james@dingwall.me.uk>
|
|
||||||
Joe Stein <joe.stein@delphix.com>
|
Joe Stein <joe.stein@delphix.com>
|
||||||
John-Mark Gurney <jmg@funkthat.com>
|
|
||||||
John Albietz <inthecloud247@gmail.com>
|
John Albietz <inthecloud247@gmail.com>
|
||||||
John Eismeier <john.eismeier@gmail.com>
|
John Eismeier <john.eismeier@gmail.com>
|
||||||
John Gallagher <john.gallagher@delphix.com>
|
|
||||||
John Layman <jlayman@sagecloud.com>
|
|
||||||
John L. Hammond <john.hammond@intel.com>
|
John L. Hammond <john.hammond@intel.com>
|
||||||
John M. Layman <jml@frijid.net>
|
John Layman <jlayman@sagecloud.com>
|
||||||
Johnny Stenback <github@jstenback.com>
|
|
||||||
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
|
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
|
||||||
John Poduska <jpoduska@datto.com>
|
|
||||||
John Ramsden <johnramsden@riseup.net>
|
|
||||||
John Wren Kennedy <john.kennedy@delphix.com>
|
John Wren Kennedy <john.kennedy@delphix.com>
|
||||||
jokersus <lolivampireslave@gmail.com>
|
Johnny Stenback <github@jstenback.com>
|
||||||
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>
|
|
||||||
Joshua M. Clulow <josh@sysmgr.org>
|
Joshua M. Clulow <josh@sysmgr.org>
|
||||||
José Luis Salvador Rufo <salvador.joseluis@gmail.com>
|
|
||||||
João Carlos Mendes Luís <jonny@jonny.eng.br>
|
|
||||||
Julian Brunner <julian.brunner@gmail.com>
|
|
||||||
Julian Heuking <JulianH@beckhoff.com>
|
|
||||||
jumbi77 <jumbi77@users.noreply.github.com>
|
|
||||||
Justin Bedő <cu@cua0.org>
|
Justin Bedő <cu@cua0.org>
|
||||||
Justin Gottula <justin@jgottula.com>
|
|
||||||
Justin Hibbits <chmeeedalf@gmail.com>
|
|
||||||
Justin Keogh <github.com@v6y.net>
|
|
||||||
Justin Lecher <jlec@gentoo.org>
|
Justin Lecher <jlec@gentoo.org>
|
||||||
Justin Scholz <git@justinscholz.de>
|
|
||||||
Justin T. Gibbs <gibbs@FreeBSD.org>
|
Justin T. Gibbs <gibbs@FreeBSD.org>
|
||||||
jyxent <jordanp@gmail.com>
|
|
||||||
Jörg Thalheim <joerg@higgsboson.tk>
|
Jörg Thalheim <joerg@higgsboson.tk>
|
||||||
ka7 <ka7@la-evento.com>
|
KORN Andras <korn@elan.rulez.org>
|
||||||
Ka Ho Ng <khng@FreeBSD.org>
|
|
||||||
Kamil Domański <kamil@domanski.co>
|
Kamil Domański <kamil@domanski.co>
|
||||||
Karsten Kretschmer <kkretschmer@gmail.com>
|
Karsten Kretschmer <kkretschmer@gmail.com>
|
||||||
Kash Pande <kash@tripleback.net>
|
Kash Pande <kash@tripleback.net>
|
||||||
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>
|
|
||||||
Kevin Bowling <kevin.bowling@kev009.com>
|
|
||||||
Kevin Greene <kevin.greene@delphix.com>
|
|
||||||
Kevin Jin <lostking2008@hotmail.com>
|
|
||||||
Kevin P. Fleming <kevin@km6g.us>
|
|
||||||
Kevin Tanguy <kevin.tanguy@ovh.net>
|
Kevin Tanguy <kevin.tanguy@ovh.net>
|
||||||
KireinaHoro <i@jsteward.moe>
|
KireinaHoro <i@jsteward.moe>
|
||||||
Kjeld Schouten-Lebbing <kjeld@schouten-lebbing.nl>
|
Kjeld Schouten-Lebbing <kjeld@schouten-lebbing.nl>
|
||||||
Kleber Tarcísio <klebertarcisio@yahoo.com.br>
|
|
||||||
Kody A Kantor <kody.kantor@gmail.com>
|
|
||||||
Kohsuke Kawaguchi <kk@kohsuke.org>
|
Kohsuke Kawaguchi <kk@kohsuke.org>
|
||||||
Konstantin Khorenko <khorenko@virtuozzo.com>
|
|
||||||
KORN Andras <korn@elan.rulez.org>
|
|
||||||
Kristof Provost <github@sigsegv.be>
|
|
||||||
Krzysztof Piecuch <piecuch@kpiecuch.pl>
|
|
||||||
Kyle Blatter <kyleblatter@llnl.gov>
|
Kyle Blatter <kyleblatter@llnl.gov>
|
||||||
Kyle Evans <kevans@FreeBSD.org>
|
|
||||||
Kyle Fuller <inbox@kylefuller.co.uk>
|
Kyle Fuller <inbox@kylefuller.co.uk>
|
||||||
Laevos <Laevos@users.noreply.github.com>
|
|
||||||
Lalufu <Lalufu@users.noreply.github.com>
|
|
||||||
Lars Johannsen <laj@it.dk>
|
|
||||||
Laura Hild <lsh@jlab.org>
|
|
||||||
Laurențiu Nicola <lnicola@dend.ro>
|
|
||||||
Lauri Tirkkonen <lauri@hacktheplanet.fi>
|
|
||||||
liaoyuxiangqin <guo.yong33@zte.com.cn>
|
|
||||||
Li Dongyang <dongyang.li@anu.edu.au>
|
|
||||||
Liu Hua <liu.hua130@zte.com.cn>
|
|
||||||
Liu Qing <winglq@gmail.com>
|
|
||||||
Li Wei <W.Li@Sun.COM>
|
|
||||||
Loli <ezomori.nozomu@gmail.com>
|
Loli <ezomori.nozomu@gmail.com>
|
||||||
lorddoskias <lorddoskias@gmail.com>
|
Lars Johannsen <laj@it.dk>
|
||||||
Lorenz Brun <lorenz@dolansoft.org>
|
Li Dongyang <dongyang.li@anu.edu.au>
|
||||||
Lorenz Hüdepohl <dev@stellardeath.org>
|
Li Wei <W.Li@Sun.COM>
|
||||||
louwrentius <louwrentius@gmail.com>
|
|
||||||
Lukas Wunner <lukas@wunner.de>
|
Lukas Wunner <lukas@wunner.de>
|
||||||
luozhengzheng <luo.zhengzheng@zte.com.cn>
|
|
||||||
Luís Henriques <henrix@camandro.org>
|
|
||||||
Madhav Suresh <madhav.suresh@delphix.com>
|
Madhav Suresh <madhav.suresh@delphix.com>
|
||||||
manfromafar <jonsonb10@gmail.com>
|
|
||||||
Manoj Joseph <manoj.joseph@delphix.com>
|
Manoj Joseph <manoj.joseph@delphix.com>
|
||||||
Manuel Amador (Rudd-O) <rudd-o@rudd-o.com>
|
Manuel Amador (Rudd-O) <rudd-o@rudd-o.com>
|
||||||
Marcel Huber <marcelhuberfoo@gmail.com>
|
Marcel Huber <marcelhuberfoo@gmail.com>
|
||||||
Marcel Menzel <mail@mcl.gg>
|
|
||||||
Marcel Schilling <marcel.schilling@uni-luebeck.de>
|
|
||||||
Marcel Telka <marcel.telka@nexenta.com>
|
Marcel Telka <marcel.telka@nexenta.com>
|
||||||
Marcel Wysocki <maci.stgn@gmail.com>
|
Marcel Wysocki <maci.stgn@gmail.com>
|
||||||
Marcin Skarbek <git@skarbek.name>
|
|
||||||
Mariusz Zaborski <mariusz.zaborski@klarasystems.com>
|
|
||||||
Mark Johnston <markj@FreeBSD.org>
|
|
||||||
Mark Maybee <mark.maybee@delphix.com>
|
|
||||||
Mark Roper <markroper@gmail.com>
|
|
||||||
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
|
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
|
||||||
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 Wagner <martin.wagner.dev@gmail.com>
|
|
||||||
Massimo Maggi <me@massimo-maggi.eu>
|
Massimo Maggi <me@massimo-maggi.eu>
|
||||||
Mateusz Guzik <mjguzik@gmail.com>
|
|
||||||
Mateusz Piotrowski <0mp@FreeBSD.org>
|
|
||||||
Mathieu Velten <matmaul@gmail.com>
|
|
||||||
Matt Fiddaman <github@m.fiddaman.uk>
|
|
||||||
Matthew Ahrens <matt@delphix.com>
|
|
||||||
Matthew Thode <mthode@mthode.org>
|
|
||||||
Matthias Blankertz <matthias@blankertz.org>
|
|
||||||
Matt Johnston <matt@fugro-fsi.com.au>
|
Matt Johnston <matt@fugro-fsi.com.au>
|
||||||
Matt Kemp <matt@mattikus.com>
|
Matt Kemp <matt@mattikus.com>
|
||||||
Matt Macy <mmacy@freebsd.org>
|
Matthew Ahrens <matt@delphix.com>
|
||||||
|
Matthew Thode <mthode@mthode.org>
|
||||||
Matus Kral <matuskral@me.com>
|
Matus Kral <matuskral@me.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>
|
|
||||||
Md Islam <mdnahian@outlook.com>
|
|
||||||
megari <megari@iki.fi>
|
|
||||||
Michael D Labriola <michael.d.labriola@gmail.com>
|
|
||||||
Michael Franzl <michael@franzl.name>
|
|
||||||
Michael Gebetsroither <michael@mgeb.org>
|
Michael Gebetsroither <michael@mgeb.org>
|
||||||
Michael Kjorling <michael@kjorling.se>
|
Michael Kjorling <michael@kjorling.se>
|
||||||
Michael Martin <mgmartin.mgm@gmail.com>
|
Michael Martin <mgmartin.mgm@gmail.com>
|
||||||
Michael Niewöhner <foss@mniewoehner.de>
|
Michael Niewöhner <foss@mniewoehner.de>
|
||||||
Michael Zhivich <mzhivich@akamai.com>
|
|
||||||
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>
|
||||||
Mike Swanson <mikeonthecomputer@gmail.com>
|
Mike Swanson <mikeonthecomputer@gmail.com>
|
||||||
Milan Jurik <milan.jurik@xylab.cz>
|
Milan Jurik <milan.jurik@xylab.cz>
|
||||||
Minsoo Choo <minsoochoo0122@proton.me>
|
|
||||||
Mohamed Tawfik <m_tawfik@aucegypt.edu>
|
|
||||||
Morgan Jones <mjones@rice.edu>
|
Morgan Jones <mjones@rice.edu>
|
||||||
Moritz Maxeiner <moritz@ucworks.org>
|
Moritz Maxeiner <moritz@ucworks.org>
|
||||||
Mo Zhou <cdluminate@gmail.com>
|
|
||||||
naivekun <naivekun@outlook.com>
|
|
||||||
nathancheek <myself@nathancheek.com>
|
|
||||||
Nathaniel Clark <Nathaniel.Clark@misrule.us>
|
Nathaniel Clark <Nathaniel.Clark@misrule.us>
|
||||||
Nathaniel Wesley Filardo <nwf@cs.jhu.edu>
|
Nathaniel Wesley Filardo <nwf@cs.jhu.edu>
|
||||||
Nathan Lewis <linux.robotdude@gmail.com>
|
|
||||||
Nav Ravindranath <nav@delphix.com>
|
Nav Ravindranath <nav@delphix.com>
|
||||||
Neal Gompa (ニール・ゴンパ) <ngompa13@gmail.com>
|
Neal Gompa (ニール・ゴンパ) <ngompa13@gmail.com>
|
||||||
Ned Bass <bass6@llnl.gov>
|
Ned Bass <bass6@llnl.gov>
|
||||||
Neependra Khare <neependra@kqinfotech.com>
|
Neependra Khare <neependra@kqinfotech.com>
|
||||||
Neil Stockbridge <neil@dist.ro>
|
Neil Stockbridge <neil@dist.ro>
|
||||||
Nick Black <dank@qemfd.net>
|
|
||||||
Nick Garvey <garvey.nick@gmail.com>
|
Nick Garvey <garvey.nick@gmail.com>
|
||||||
Nick Mattis <nickm970@gmail.com>
|
|
||||||
Nick Terrell <terrelln@fb.com>
|
|
||||||
Niklas Haas <github-c6e1c8@haasn.xyz>
|
|
||||||
Nikolay Borisov <n.borisov.lkml@gmail.com>
|
Nikolay Borisov <n.borisov.lkml@gmail.com>
|
||||||
nordaux <nordaux@gmail.com>
|
|
||||||
ofthesun9 <olivier@ofthesun.net>
|
|
||||||
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>
|
|
||||||
omni <omni+vagant@hack.org>
|
|
||||||
Orivej Desh <orivej@gmx.fr>
|
|
||||||
Pablo Correa Gómez <ablocorrea@hotmail.com>
|
|
||||||
Palash Gandhi <pbg4930@rit.edu>
|
|
||||||
Patrick Mooney <pmooney@pfmooney.com>
|
|
||||||
Patrik Greco <sikevux@sikevux.se>
|
Patrik Greco <sikevux@sikevux.se>
|
||||||
Paul B. Henson <henson@acm.org>
|
Paul B. Henson <henson@acm.org>
|
||||||
Paul Dagnelie <pcd@delphix.com>
|
Paul Dagnelie <pcd@delphix.com>
|
||||||
Paul Zuchowski <pzuchowski@datto.com>
|
Paul Zuchowski <pzuchowski@datto.com>
|
||||||
Pavel Boldin <boldin.pavel@gmail.com>
|
Pavel Boldin <boldin.pavel@gmail.com>
|
||||||
Pavel Snajdr <snajpa@snajpa.net>
|
|
||||||
Pavel Zakharov <pavel.zakharov@delphix.com>
|
Pavel Zakharov <pavel.zakharov@delphix.com>
|
||||||
Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||||
Pedro Giffuni <pfg@freebsd.org>
|
Pedro Giffuni <pfg@freebsd.org>
|
||||||
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 Doherty <peterd@acranox.org>
|
|
||||||
Peter Levine <plevine457@gmail.com>
|
|
||||||
Peter Wirdemo <peter.wirdemo@gmail.com>
|
|
||||||
Petros Koutoupis <petros@petroskoutoupis.com>
|
|
||||||
Philip Pokorny <ppokorny@penguincomputing.com>
|
|
||||||
Philipp Riederer <pt@philipptoelke.de>
|
|
||||||
Phil Kauffman <philip@kauffman.me>
|
|
||||||
Ping Huang <huangping@smartx.com>
|
|
||||||
Piotr Kubaj <pkubaj@anongoth.pl>
|
|
||||||
Piotr P. Stefaniak <pstef@freebsd.org>
|
|
||||||
Prakash Surya <prakash.surya@delphix.com>
|
Prakash Surya <prakash.surya@delphix.com>
|
||||||
Prasad Joshi <prasadjoshi124@gmail.com>
|
Prasad Joshi <prasadjoshi124@gmail.com>
|
||||||
privb0x23 <privb0x23@users.noreply.github.com>
|
|
||||||
P.SCH <p88@yahoo.com>
|
|
||||||
Qiuhao Chen <chenqiuhao1997@gmail.com>
|
|
||||||
Quartz <yyhran@163.com>
|
|
||||||
Quentin Zdanis <zdanisq@gmail.com>
|
|
||||||
Rafael Kitover <rkitover@gmail.com>
|
|
||||||
RageLtMan <sempervictus@users.noreply.github.com>
|
|
||||||
Ralf Ertzinger <ralf@skytale.net>
|
Ralf Ertzinger <ralf@skytale.net>
|
||||||
Randall Mason <ClashTheBunny@gmail.com>
|
Randall Mason <ClashTheBunny@gmail.com>
|
||||||
Remy Blank <remy.blank@pobox.com>
|
Remy Blank <remy.blank@pobox.com>
|
||||||
renelson <bnelson@nelsonbe.com>
|
|
||||||
Reno Reckling <e-github@wthack.de>
|
|
||||||
Ricardo M. Correia <ricardo.correia@oracle.com>
|
Ricardo M. Correia <ricardo.correia@oracle.com>
|
||||||
Riccardo Schirone <rschirone91@gmail.com>
|
Rich Ercolani <rincebrain@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>
|
|
||||||
Rick Macklem <rmacklem@uoguelph.ca>
|
|
||||||
rilysh <nightquick@proton.me>
|
|
||||||
Robert Evans <evansr@google.com>
|
|
||||||
Robert Novak <sailnfool@gmail.com>
|
|
||||||
Roberto Ricci <ricci@disroot.org>
|
|
||||||
Rob Norris <robn@despairlabs.com>
|
|
||||||
Rob Wing <rew@FreeBSD.org>
|
|
||||||
Rohan Puri <rohan.puri15@gmail.com>
|
Rohan Puri <rohan.puri15@gmail.com>
|
||||||
Romain Dolbeau <romain.dolbeau@atos.net>
|
Romain Dolbeau <romain.dolbeau@atos.net>
|
||||||
Roman Strashkin <roman.strashkin@nexenta.com>
|
Roman Strashkin <roman.strashkin@nexenta.com>
|
||||||
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 Lahfa <masterancpp@gmail.com>
|
|
||||||
Ryan Libby <rlibby@FreeBSD.org>
|
|
||||||
Ryan Moeller <freqlabs@FreeBSD.org>
|
|
||||||
Sam Atkinson <samatk@amazon.com>
|
|
||||||
Sam Hathaway <github.com@munkynet.org>
|
|
||||||
Sam James <sam@gentoo.org>
|
|
||||||
Sam Lunt <samuel.j.lunt@gmail.com>
|
|
||||||
Samuel VERSCHELDE <stormi-github@ylix.fr>
|
|
||||||
Samuel Wycliffe <samuelwycliffe@gmail.com>
|
|
||||||
Samuel Wycliffe J <samwyc@hpe.com>
|
|
||||||
Sanjeev Bagewadi <sanjeev.bagewadi@gmail.com>
|
|
||||||
Sara Hartse <sara.hartse@delphix.com>
|
|
||||||
Saso Kiselkov <saso.kiselkov@nexenta.com>
|
Saso Kiselkov <saso.kiselkov@nexenta.com>
|
||||||
Satadru Pramanik <satadru@gmail.com>
|
|
||||||
Savyasachee Jha <genghizkhan91@hawkradius.com>
|
|
||||||
Scott Colby <scott@scolby.com>
|
|
||||||
Scot W. Stevenson <scot.stevenson@gmail.com>
|
Scot W. Stevenson <scot.stevenson@gmail.com>
|
||||||
Sean Eric Fagan <sef@ixsystems.com>
|
Sean Eric Fagan <sef@ixsystems.com>
|
||||||
Sebastian Gottschall <s.gottschall@dd-wrt.com>
|
Sebastian Gottschall <s.gottschall@dd-wrt.com>
|
||||||
Sebastien Roy <seb@delphix.com>
|
|
||||||
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>
|
|
||||||
Shampavman <sham.pavman@nexenta.com>
|
Shampavman <sham.pavman@nexenta.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>
|
||||||
Sowrabha Gopal <sowrabha.gopal@delphix.com>
|
Sowrabha Gopal <sowrabha.gopal@delphix.com>
|
||||||
Spencer Kinny <spencerkinny1995@gmail.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>
|
|
||||||
Steve Dougherty <sdougherty@barracuda.com>
|
Steve Dougherty <sdougherty@barracuda.com>
|
||||||
Steve Mokris <smokris@softpixel.com>
|
|
||||||
Steven Burgess <sburgess@dattobackup.com>
|
Steven Burgess <sburgess@dattobackup.com>
|
||||||
Steven Hartland <smh@freebsd.org>
|
Steven Hartland <smh@freebsd.org>
|
||||||
Steven Johnson <sjohnson@sakuraindustries.com>
|
Steven Johnson <sjohnson@sakuraindustries.com>
|
||||||
Steven Noonan <steven@uplinklabs.net>
|
|
||||||
stf <s@ctrlc.hu>
|
|
||||||
Stian Ellingsen <stian@plaimi.net>
|
Stian Ellingsen <stian@plaimi.net>
|
||||||
Stoiko Ivanov <github@nomore.at>
|
|
||||||
Stéphane Lesimple <speed47_github@speed47.net>
|
|
||||||
Suman Chakravartula <schakrava@gmail.com>
|
Suman Chakravartula <schakrava@gmail.com>
|
||||||
Sydney Vanda <sydney.m.vanda@intel.com>
|
Sydney Vanda <sydney.m.vanda@intel.com>
|
||||||
Sören Tempel <soeren+git@soeren-tempel.net>
|
Sören Tempel <soeren+git@soeren-tempel.net>
|
||||||
Tamas TEVESZ <ice@extreme.hu>
|
|
||||||
Teodor Spæren <teodor_spaeren@riseup.net>
|
|
||||||
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 Lamprecht <guggentom@hotmail.de>
|
|
||||||
Till Maas <opensource@till.name>
|
|
||||||
Tim Chase <tim@chase2k.com>
|
Tim Chase <tim@chase2k.com>
|
||||||
Tim Connors <tconnors@rather.puzzling.org>
|
Tim Connors <tconnors@rather.puzzling.org>
|
||||||
Tim Crawford <tcrawford@datto.com>
|
Tim Crawford <tcrawford@datto.com>
|
||||||
Tim Haley <Tim.Haley@Sun.COM>
|
Tim Haley <Tim.Haley@Sun.COM>
|
||||||
timor <timor.dd@googlemail.com>
|
|
||||||
Timothy Day <tday141@gmail.com>
|
|
||||||
Tim Schumacher <timschumi@gmx.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>
|
|
||||||
Tom Prince <tom.prince@ualberta.net>
|
Tom Prince <tom.prince@ualberta.net>
|
||||||
|
Tomohiro Kusumi <kusumi.tomohiro@gmail.com>
|
||||||
Tony Hutter <hutter2@llnl.gov>
|
Tony Hutter <hutter2@llnl.gov>
|
||||||
Tony Nguyen <tony.nguyen@delphix.com>
|
|
||||||
Tony Perkins <tperkins@datto.com>
|
|
||||||
Toomas Soome <tsoome@me.com>
|
Toomas Soome <tsoome@me.com>
|
||||||
Torsten Wörtwein <twoertwein@gmail.com>
|
|
||||||
Toyam Cox <aviator45003@gmail.com>
|
|
||||||
Trevor Bautista <trevrb@trevrb.net>
|
|
||||||
Trey Dockendorf <treydock@gmail.com>
|
Trey Dockendorf <treydock@gmail.com>
|
||||||
Troels Nørgaard <tnn@tradeshift.com>
|
|
||||||
Tulsi Jain <tulsi.jain@delphix.com>
|
|
||||||
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>
|
|
||||||
Vaibhav Bhanawat <vaibhav.bhanawat@delphix.com>
|
|
||||||
Valmiky Arquissandas <kayvlim@gmail.com>
|
|
||||||
Val Packett <val@packett.cool>
|
|
||||||
Vince van Oosten <techhazard@codeforyouand.me>
|
|
||||||
Violet Purcell <vimproved@inventati.org>
|
|
||||||
Vipin Kumar Verma <vipin.verma@hpe.com>
|
|
||||||
Vitaut Bajaryn <vitaut.bayaryn@gmail.com>
|
Vitaut Bajaryn <vitaut.bayaryn@gmail.com>
|
||||||
Volker Mauel <volkermauel@gmail.com>
|
|
||||||
Václav Skála <skala@vshosting.cz>
|
|
||||||
Walter Huf <hufman@gmail.com>
|
|
||||||
Warner Losh <imp@bsdimp.com>
|
|
||||||
Weigang Li <weigang.li@intel.com>
|
Weigang Li <weigang.li@intel.com>
|
||||||
WHR <msl0000023508@gmail.com>
|
|
||||||
Will Andrews <will@freebsd.org>
|
Will Andrews <will@freebsd.org>
|
||||||
Will Rouesnel <w.rouesnel@gmail.com>
|
Will Rouesnel <w.rouesnel@gmail.com>
|
||||||
Windel Bouwman <windel@windel.nl>
|
|
||||||
Wojciech Małota-Wójcik <outofforest@users.noreply.github.com>
|
|
||||||
Wolfgang Bumiller <w.bumiller@proxmox.com>
|
Wolfgang Bumiller <w.bumiller@proxmox.com>
|
||||||
Xin Li <delphij@FreeBSD.org>
|
Xin Li <delphij@FreeBSD.org>
|
||||||
Xinliang Liu <xinliang.liu@linaro.org>
|
|
||||||
xtouqh <xtouqh@hotmail.com>
|
|
||||||
Yann Collet <cyan@fb.com>
|
|
||||||
Yanping Gao <yanping.gao@xtaotech.com>
|
|
||||||
Ying Zhu <casualfisher@gmail.com>
|
Ying Zhu <casualfisher@gmail.com>
|
||||||
Youzhong Yang <youzhong@gmail.com>
|
|
||||||
yparitcher <y@paritcher.com>
|
|
||||||
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>
|
|
||||||
zgock <zgock@nuc.base.zgock-lab.net>
|
|
||||||
Zhao Yongming <zym@apache.org>
|
|
||||||
Zhenlei Huang <zlei@FreeBSD.org>
|
|
||||||
Zhu Chuang <chuang@melty.land>
|
|
||||||
Érico Nogueira <erico.erc@gmail.com>
|
|
||||||
Đoàn Trần Công Danh <congdanhqx@gmail.com>
|
|
||||||
韩朴宇 <w12101111@gmail.com>
|
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
The [OpenZFS Code of Conduct](https://openzfs.org/wiki/Code_of_Conduct)
|
The [OpenZFS Code of Conduct](http://www.open-zfs.org/wiki/Code_of_Conduct)
|
||||||
applies to spaces associated with the OpenZFS project, including GitHub.
|
applies to spaces associated with the OpenZFS project, including GitHub.
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
Meta: 1
|
Meta: 1
|
||||||
Name: zfs
|
Name: zfs
|
||||||
Branch: 1.0
|
Branch: 1.0
|
||||||
Version: 2.2.5
|
Version: 2.1.0
|
||||||
Release: 1
|
Release: 1
|
||||||
Release-Tags: relext
|
Release-Tags: relext
|
||||||
License: CDDL
|
License: CDDL
|
||||||
Author: OpenZFS
|
Author: OpenZFS
|
||||||
Linux-Maximum: 6.9
|
Linux-Maximum: 5.13
|
||||||
Linux-Minimum: 3.10
|
Linux-Minimum: 3.10
|
||||||
|
|||||||
+114
-96
@@ -1,82 +1,68 @@
|
|||||||
CLEANFILES =
|
|
||||||
dist_noinst_DATA =
|
|
||||||
INSTALL_DATA_HOOKS =
|
|
||||||
ALL_LOCAL =
|
|
||||||
CLEAN_LOCAL =
|
|
||||||
CHECKS = shellcheck checkbashisms
|
|
||||||
|
|
||||||
include $(top_srcdir)/config/Rules.am
|
|
||||||
include $(top_srcdir)/config/CppCheck.am
|
|
||||||
include $(top_srcdir)/config/Shellcheck.am
|
include $(top_srcdir)/config/Shellcheck.am
|
||||||
include $(top_srcdir)/config/Substfiles.am
|
|
||||||
include $(top_srcdir)/scripts/Makefile.am
|
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I config
|
ACLOCAL_AMFLAGS = -I config
|
||||||
|
|
||||||
SUBDIRS = include
|
SUBDIRS = include
|
||||||
if BUILD_LINUX
|
if BUILD_LINUX
|
||||||
include $(srcdir)/%D%/rpm/Makefile.am
|
SUBDIRS += rpm
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if CONFIG_USER
|
if CONFIG_USER
|
||||||
include $(srcdir)/%D%/cmd/Makefile.am
|
SUBDIRS += man scripts lib tests cmd etc contrib
|
||||||
include $(srcdir)/%D%/contrib/Makefile.am
|
|
||||||
include $(srcdir)/%D%/etc/Makefile.am
|
|
||||||
include $(srcdir)/%D%/lib/Makefile.am
|
|
||||||
include $(srcdir)/%D%/man/Makefile.am
|
|
||||||
include $(srcdir)/%D%/tests/Makefile.am
|
|
||||||
if BUILD_LINUX
|
if BUILD_LINUX
|
||||||
include $(srcdir)/%D%/udev/Makefile.am
|
SUBDIRS += udev
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
CPPCHECKDIRS += module
|
|
||||||
if CONFIG_KERNEL
|
if CONFIG_KERNEL
|
||||||
SUBDIRS += module
|
SUBDIRS += module
|
||||||
|
|
||||||
extradir = $(prefix)/src/zfs-$(VERSION)
|
extradir = $(prefix)/src/zfs-$(VERSION)
|
||||||
extra_HEADERS = zfs.release.in zfs_config.h.in
|
extra_HEADERS = zfs.release.in zfs_config.h.in
|
||||||
|
|
||||||
|
if BUILD_LINUX
|
||||||
|
kerneldir = $(prefix)/src/zfs-$(VERSION)/$(LINUX_VERSION)
|
||||||
|
nodist_kernel_HEADERS = zfs.release zfs_config.h module/$(LINUX_SYMBOLS)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
dist_noinst_DATA += autogen.sh copy-builtin
|
AUTOMAKE_OPTIONS = foreign
|
||||||
dist_noinst_DATA += AUTHORS CODE_OF_CONDUCT.md COPYRIGHT LICENSE META NEWS NOTICE
|
EXTRA_DIST = autogen.sh copy-builtin
|
||||||
dist_noinst_DATA += README.md RELEASES.md
|
EXTRA_DIST += config/config.awk config/rpm.am config/deb.am config/tgz.am
|
||||||
dist_noinst_DATA += module/lua/README.zfs module/os/linux/spl/README.md
|
EXTRA_DIST += AUTHORS CODE_OF_CONDUCT.md COPYRIGHT LICENSE META NEWS NOTICE
|
||||||
|
EXTRA_DIST += README.md RELEASES.md
|
||||||
|
EXTRA_DIST += module/lua/README.zfs module/os/linux/spl/README.md
|
||||||
|
|
||||||
# Include all the extra licensing information for modules
|
# Include all the extra licensing information for modules
|
||||||
dist_noinst_DATA += module/icp/algs/skein/THIRDPARTYLICENSE
|
EXTRA_DIST += module/icp/algs/skein/THIRDPARTYLICENSE
|
||||||
dist_noinst_DATA += module/icp/algs/skein/THIRDPARTYLICENSE.descrip
|
EXTRA_DIST += module/icp/algs/skein/THIRDPARTYLICENSE.descrip
|
||||||
dist_noinst_DATA += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.gladman
|
EXTRA_DIST += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.gladman
|
||||||
dist_noinst_DATA += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.gladman.descrip
|
EXTRA_DIST += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.gladman.descrip
|
||||||
dist_noinst_DATA += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.openssl
|
EXTRA_DIST += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.openssl
|
||||||
dist_noinst_DATA += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.openssl.descrip
|
EXTRA_DIST += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.openssl.descrip
|
||||||
dist_noinst_DATA += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.cryptogams
|
EXTRA_DIST += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.cryptogams
|
||||||
dist_noinst_DATA += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.cryptogams.descrip
|
EXTRA_DIST += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.cryptogams.descrip
|
||||||
dist_noinst_DATA += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.openssl
|
EXTRA_DIST += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.openssl
|
||||||
dist_noinst_DATA += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.openssl.descrip
|
EXTRA_DIST += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.openssl.descrip
|
||||||
dist_noinst_DATA += module/os/linux/spl/THIRDPARTYLICENSE.gplv2
|
EXTRA_DIST += module/os/linux/spl/THIRDPARTYLICENSE.gplv2
|
||||||
dist_noinst_DATA += module/os/linux/spl/THIRDPARTYLICENSE.gplv2.descrip
|
EXTRA_DIST += module/os/linux/spl/THIRDPARTYLICENSE.gplv2.descrip
|
||||||
dist_noinst_DATA += module/zfs/THIRDPARTYLICENSE.cityhash
|
EXTRA_DIST += module/zfs/THIRDPARTYLICENSE.cityhash
|
||||||
dist_noinst_DATA += module/zfs/THIRDPARTYLICENSE.cityhash.descrip
|
EXTRA_DIST += module/zfs/THIRDPARTYLICENSE.cityhash.descrip
|
||||||
|
|
||||||
@CODE_COVERAGE_RULES@
|
@CODE_COVERAGE_RULES@
|
||||||
|
|
||||||
GITREV = include/zfs_gitrev.h
|
GITREV = include/zfs_gitrev.h
|
||||||
CLEANFILES += $(GITREV)
|
|
||||||
PHONY += gitrev
|
PHONY = gitrev
|
||||||
gitrev:
|
gitrev:
|
||||||
$(AM_V_GEN)$(top_srcdir)/scripts/make_gitrev.sh $(GITREV)
|
$(AM_V_GEN)$(top_srcdir)/scripts/make_gitrev.sh $(GITREV)
|
||||||
|
|
||||||
all: gitrev
|
all: gitrev
|
||||||
|
|
||||||
PHONY += install-data-hook $(INSTALL_DATA_HOOKS)
|
# Double-colon rules are allowed; there are multiple independent definitions.
|
||||||
install-data-hook: $(INSTALL_DATA_HOOKS)
|
maintainer-clean-local::
|
||||||
|
|
||||||
PHONY += maintainer-clean-local
|
|
||||||
maintainer-clean-local:
|
|
||||||
-$(RM) $(GITREV)
|
-$(RM) $(GITREV)
|
||||||
|
|
||||||
PHONY += distclean-local
|
distclean-local::
|
||||||
distclean-local:
|
|
||||||
-$(RM) -R autom4te*.cache build
|
-$(RM) -R autom4te*.cache build
|
||||||
-find . \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
|
-find . \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
|
||||||
-o -name .pc -o -name .hg -o -name .git \) -prune -o \
|
-o -name .pc -o -name .hg -o -name .git \) -prune -o \
|
||||||
@@ -86,105 +72,137 @@ distclean-local:
|
|||||||
-o -name 'core' -o -name 'Makefile' -o -name 'Module.symvers' \
|
-o -name 'core' -o -name 'Makefile' -o -name 'Module.symvers' \
|
||||||
-o -name '*.order' -o -name '*.markers' -o -name '*.gcda' \
|
-o -name '*.order' -o -name '*.markers' -o -name '*.gcda' \
|
||||||
-o -name '*.gcno' \) \
|
-o -name '*.gcno' \) \
|
||||||
-type f -delete
|
-type f -print | xargs $(RM)
|
||||||
|
|
||||||
PHONY += $(CLEAN_LOCAL)
|
all-local:
|
||||||
clean-local: $(CLEAN_LOCAL)
|
-[ -x ${top_builddir}/scripts/zfs-tests.sh ] && \
|
||||||
|
${top_builddir}/scripts/zfs-tests.sh -c
|
||||||
PHONY += $(ALL_LOCAL)
|
|
||||||
all-local: $(ALL_LOCAL)
|
|
||||||
|
|
||||||
dist-hook:
|
dist-hook:
|
||||||
$(top_srcdir)/scripts/make_gitrev.sh -D $(distdir) $(GITREV)
|
$(AM_V_GEN)$(top_srcdir)/scripts/make_gitrev.sh -D $(distdir) $(GITREV)
|
||||||
$(SED) $(ac_inplace) 's/\(Release:[[:space:]]*\).*/\1$(RELEASE)/' $(distdir)/META
|
$(SED) ${ac_inplace} -e 's/Release:[[:print:]]*/Release: $(RELEASE)/' \
|
||||||
|
$(distdir)/META
|
||||||
|
|
||||||
PHONY += codecheck $(CHECKS)
|
if BUILD_LINUX
|
||||||
codecheck: $(CHECKS)
|
# For compatibility, create a matching spl-x.y.z directly which contains
|
||||||
|
# symlinks to the updated header and object file locations. These
|
||||||
|
# compatibility links will be removed in the next major release.
|
||||||
|
if CONFIG_KERNEL
|
||||||
|
install-data-hook:
|
||||||
|
rm -rf $(DESTDIR)$(prefix)/src/spl-$(VERSION) && \
|
||||||
|
mkdir $(DESTDIR)$(prefix)/src/spl-$(VERSION) && \
|
||||||
|
cd $(DESTDIR)$(prefix)/src/spl-$(VERSION) && \
|
||||||
|
ln -s ../zfs-$(VERSION)/include/spl include && \
|
||||||
|
ln -s ../zfs-$(VERSION)/$(LINUX_VERSION) $(LINUX_VERSION) && \
|
||||||
|
ln -s ../zfs-$(VERSION)/zfs_config.h.in spl_config.h.in && \
|
||||||
|
ln -s ../zfs-$(VERSION)/zfs.release.in spl.release.in && \
|
||||||
|
cd $(DESTDIR)$(prefix)/src/zfs-$(VERSION)/$(LINUX_VERSION) && \
|
||||||
|
ln -fs zfs_config.h spl_config.h && \
|
||||||
|
ln -fs zfs.release spl.release
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
SHELLCHECKSCRIPTS += autogen.sh
|
PHONY += codecheck
|
||||||
|
codecheck: cstyle shellcheck checkbashisms flake8 mancheck testscheck vcscheck
|
||||||
|
|
||||||
PHONY += checkstyle
|
PHONY += checkstyle
|
||||||
checkstyle: codecheck commitcheck
|
checkstyle: codecheck commitcheck
|
||||||
|
|
||||||
PHONY += commitcheck
|
PHONY += commitcheck
|
||||||
commitcheck:
|
commitcheck:
|
||||||
$(AM_V_at)if git rev-parse --git-dir > /dev/null 2>&1; then \
|
@if git rev-parse --git-dir > /dev/null 2>&1; then \
|
||||||
${top_srcdir}/scripts/commitcheck.sh; \
|
${top_srcdir}/scripts/commitcheck.sh; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if HAVE_PARALLEL
|
PHONY += cstyle
|
||||||
cstyle_line = -print0 | parallel -X0 ${top_srcdir}/scripts/cstyle.pl -cpP {}
|
|
||||||
else
|
|
||||||
cstyle_line = -exec ${top_srcdir}/scripts/cstyle.pl -cpP {} +
|
|
||||||
endif
|
|
||||||
CHECKS += cstyle
|
|
||||||
cstyle:
|
cstyle:
|
||||||
$(AM_V_at)find $(top_srcdir) -name build -prune \
|
@find ${top_srcdir} -name build -prune \
|
||||||
-o -type f -name '*.[hc]' \
|
-o -type f -name '*.[hc]' \
|
||||||
! -name 'zfs_config.*' ! -name '*.mod.c' \
|
! -name 'zfs_config.*' ! -name '*.mod.c' \
|
||||||
! -name 'opt_global.h' ! -name '*_if*.h' \
|
! -name 'opt_global.h' ! -name '*_if*.h' \
|
||||||
! -name 'zstd_compat_wrapper.h' \
|
|
||||||
! -path './module/zstd/lib/*' \
|
! -path './module/zstd/lib/*' \
|
||||||
! -path './include/sys/lua/*' \
|
-exec ${top_srcdir}/scripts/cstyle.pl -cpP {} \+
|
||||||
! -path './module/lua/l*.[ch]' \
|
|
||||||
! -path './module/zfs/lz4.c' \
|
|
||||||
$(cstyle_line)
|
|
||||||
|
|
||||||
filter_executable = -exec test -x '{}' \; -print
|
filter_executable = -exec test -x '{}' \; -print
|
||||||
CHECKS += testscheck
|
|
||||||
testscheck:
|
|
||||||
$(AM_V_at)[ $$(find $(top_srcdir)/tests/zfs-tests -type f \
|
|
||||||
\( -name '*.ksh' -not $(filter_executable) \) -o \
|
|
||||||
\( -name '*.kshlib' $(filter_executable) \) -o \
|
|
||||||
\( -name '*.shlib' $(filter_executable) \) -o \
|
|
||||||
\( -name '*.cfg' $(filter_executable) \) | \
|
|
||||||
tee /dev/stderr | wc -l) -eq 0 ]
|
|
||||||
|
|
||||||
CHECKS += vcscheck
|
SHELLCHECKDIRS = cmd contrib etc scripts tests
|
||||||
|
SHELLCHECKSCRIPTS = autogen.sh
|
||||||
|
|
||||||
|
PHONY += checkabi storeabi
|
||||||
|
checkabi: lib
|
||||||
|
$(MAKE) -C lib checkabi
|
||||||
|
|
||||||
|
storeabi: lib
|
||||||
|
$(MAKE) -C lib storeabi
|
||||||
|
|
||||||
|
PHONY += mancheck
|
||||||
|
mancheck:
|
||||||
|
${top_srcdir}/scripts/mancheck.sh ${top_srcdir}/man ${top_srcdir}/tests/test-runner/man
|
||||||
|
|
||||||
|
if BUILD_LINUX
|
||||||
|
stat_fmt = -c '%A %n'
|
||||||
|
else
|
||||||
|
stat_fmt = -f '%Sp %N'
|
||||||
|
endif
|
||||||
|
|
||||||
|
PHONY += testscheck
|
||||||
|
testscheck:
|
||||||
|
@find ${top_srcdir}/tests/zfs-tests -type f \
|
||||||
|
\( -name '*.ksh' -not ${filter_executable} \) -o \
|
||||||
|
\( -name '*.kshlib' ${filter_executable} \) -o \
|
||||||
|
\( -name '*.shlib' ${filter_executable} \) -o \
|
||||||
|
\( -name '*.cfg' ${filter_executable} \) | \
|
||||||
|
xargs -r stat ${stat_fmt} | \
|
||||||
|
awk '{c++; print} END {if(c>0) exit 1}'
|
||||||
|
|
||||||
|
PHONY += vcscheck
|
||||||
vcscheck:
|
vcscheck:
|
||||||
$(AM_V_at)if git rev-parse --git-dir > /dev/null 2>&1; then \
|
@if git rev-parse --git-dir > /dev/null 2>&1; then \
|
||||||
git ls-files . --exclude-standard --others | \
|
git ls-files . --exclude-standard --others | \
|
||||||
awk '{c++; print} END {if(c>0) exit 1}' ; \
|
awk '{c++; print} END {if(c>0) exit 1}' ; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CHECKS += zstdcheck
|
|
||||||
zstdcheck:
|
|
||||||
@$(MAKE) -C module check-zstd-symbols
|
|
||||||
|
|
||||||
PHONY += lint
|
PHONY += lint
|
||||||
lint: cppcheck paxcheck
|
lint: cppcheck paxcheck
|
||||||
|
|
||||||
|
CPPCHECKDIRS = cmd lib module
|
||||||
|
PHONY += cppcheck
|
||||||
|
cppcheck: $(CPPCHECKDIRS)
|
||||||
|
@if test -n "$(CPPCHECK)"; then \
|
||||||
|
set -e ; for dir in $(CPPCHECKDIRS) ; do \
|
||||||
|
$(MAKE) -C $$dir cppcheck ; \
|
||||||
|
done \
|
||||||
|
else \
|
||||||
|
echo "skipping cppcheck because cppcheck is not installed"; \
|
||||||
|
fi
|
||||||
|
|
||||||
PHONY += paxcheck
|
PHONY += paxcheck
|
||||||
paxcheck:
|
paxcheck:
|
||||||
$(AM_V_at)if type scanelf > /dev/null 2>&1; then \
|
@if type scanelf > /dev/null 2>&1; then \
|
||||||
$(top_srcdir)/scripts/paxcheck.sh $(top_builddir); \
|
${top_srcdir}/scripts/paxcheck.sh ${top_builddir}; \
|
||||||
else \
|
else \
|
||||||
echo "skipping paxcheck because scanelf is not installed"; \
|
echo "skipping paxcheck because scanelf is not installed"; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CHECKS += flake8
|
PHONY += flake8
|
||||||
flake8:
|
flake8:
|
||||||
$(AM_V_at)if type flake8 > /dev/null 2>&1; then \
|
@if type flake8 > /dev/null 2>&1; then \
|
||||||
flake8 $(top_srcdir); \
|
flake8 ${top_srcdir}; \
|
||||||
else \
|
else \
|
||||||
echo "skipping flake8 because flake8 is not installed"; \
|
echo "skipping flake8 because flake8 is not installed"; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PHONY += regen-tests
|
|
||||||
regen-tests:
|
|
||||||
@$(MAKE) -C tests/zfs-tests/tests regen
|
|
||||||
|
|
||||||
PHONY += ctags
|
PHONY += ctags
|
||||||
ctags:
|
ctags:
|
||||||
$(RM) tags
|
$(RM) tags
|
||||||
find $(top_srcdir) -name '.?*' -prune \
|
find $(top_srcdir) -name '.?*' -prune \
|
||||||
-o -type f -name '*.[hcS]' -exec ctags -a {} +
|
-o -type f -name '*.[hcS]' -print | xargs ctags -a
|
||||||
|
|
||||||
PHONY += etags
|
PHONY += etags
|
||||||
etags:
|
etags:
|
||||||
$(RM) TAGS
|
$(RM) TAGS
|
||||||
find $(top_srcdir) -name '.?*' -prune \
|
find $(top_srcdir) -name '.?*' -prune \
|
||||||
-o -type f -name '*.[hcS]' -exec etags -a {} +
|
-o -type f -name '*.[hcS]' -print | xargs etags -a
|
||||||
|
|
||||||
PHONY += cscopelist
|
PHONY += cscopelist
|
||||||
cscopelist:
|
cscopelist:
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ This repository contains the code for running OpenZFS on Linux and FreeBSD.
|
|||||||
* [Documentation](https://openzfs.github.io/openzfs-docs/) - for using and developing this repo
|
* [Documentation](https://openzfs.github.io/openzfs-docs/) - for using and developing this repo
|
||||||
* [ZoL Site](https://zfsonlinux.org) - Linux release info & links
|
* [ZoL Site](https://zfsonlinux.org) - Linux release info & links
|
||||||
* [Mailing lists](https://openzfs.github.io/openzfs-docs/Project%20and%20Community/Mailing%20Lists.html)
|
* [Mailing lists](https://openzfs.github.io/openzfs-docs/Project%20and%20Community/Mailing%20Lists.html)
|
||||||
* [OpenZFS site](https://openzfs.org/) - for conference videos and info on other platforms (illumos, OSX, Windows, etc)
|
* [OpenZFS site](http://open-zfs.org/) - for conference videos and info on other platforms (illumos, OSX, Windows, etc)
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
@@ -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 12.4-RELEASE.
|
* Supported FreeBSD versions are any supported branches and releases starting from 12.2-RELEASE.
|
||||||
|
|||||||
+2
-60
@@ -1,62 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
[ "${0%/*}" = "$0" ] || cd "${0%/*}" || exit
|
|
||||||
|
|
||||||
# %reldir%/%canon_reldir% (%D%/%C%) only appeared in automake 1.14, but RHEL/CentOS 7 has 1.13.4
|
autoreconf -fiv || exit 1
|
||||||
# This is an (overly) simplistic preprocessor that papers around this for the duration of the generation step,
|
rm -Rf autom4te.cache
|
||||||
# and can be removed once support for CentOS 7 is dropped
|
|
||||||
automake --version | awk '{print $NF; exit}' | (
|
|
||||||
IFS=. read -r AM_MAJ AM_MIN _
|
|
||||||
[ "$AM_MAJ" -gt 1 ] || [ "$AM_MIN" -ge 14 ]
|
|
||||||
) || {
|
|
||||||
process_root() {
|
|
||||||
root="$1"; shift
|
|
||||||
|
|
||||||
grep -q '%[CD]%' "$root/Makefile.am" || return
|
|
||||||
find "$root" -name Makefile.am "$@" | while read -r dir; do
|
|
||||||
dir="${dir%/Makefile.am}"
|
|
||||||
grep -q '%[CD]%' "$dir/Makefile.am" || continue
|
|
||||||
|
|
||||||
reldir="${dir#"$root"}"
|
|
||||||
reldir="${reldir#/}"
|
|
||||||
|
|
||||||
canon_reldir="$(printf '%s' "$reldir" | tr -C 'a-zA-Z0-9@_' '_')"
|
|
||||||
|
|
||||||
reldir_slash="$reldir/"
|
|
||||||
canon_reldir_slash="${canon_reldir}_"
|
|
||||||
[ -z "$reldir" ] && reldir_slash=
|
|
||||||
[ -z "$reldir" ] && canon_reldir_slash=
|
|
||||||
|
|
||||||
echo "$dir/Makefile.am" >&3
|
|
||||||
sed -i~ -e "s:%D%/:$reldir_slash:g" -e "s:%D%:$reldir:g" \
|
|
||||||
-e "s:%C%_:$canon_reldir_slash:g" -e "s:%C%:$canon_reldir:g" "$dir/Makefile.am"
|
|
||||||
done 3>>"$substituted_files"
|
|
||||||
}
|
|
||||||
|
|
||||||
rollback() {
|
|
||||||
while read -r f; do
|
|
||||||
mv "$f~" "$f"
|
|
||||||
done < "$substituted_files"
|
|
||||||
rm -f "$substituted_files"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
echo "Automake <1.14; papering over missing %reldir%/%canon_reldir% support" >&2
|
|
||||||
|
|
||||||
substituted_files="$(mktemp)"
|
|
||||||
trap rollback EXIT
|
|
||||||
|
|
||||||
roots="$(sed '/Makefile$/!d;/module/d;s:^\s*:./:;s:/Makefile::;/^\.$/d' configure.ac)"
|
|
||||||
|
|
||||||
IFS="
|
|
||||||
"
|
|
||||||
for root in $roots; do
|
|
||||||
root="${root#./}"
|
|
||||||
process_root "$root"
|
|
||||||
done
|
|
||||||
|
|
||||||
set -f
|
|
||||||
# shellcheck disable=SC2086,SC2046
|
|
||||||
process_root . $(printf '!\n-path\n%s/*\n' $roots)
|
|
||||||
}
|
|
||||||
|
|
||||||
autoreconf -fiv && rm -rf autom4te.cache
|
|
||||||
|
|||||||
+19
-108
@@ -1,116 +1,27 @@
|
|||||||
bin_SCRIPTS =
|
include $(top_srcdir)/config/Shellcheck.am
|
||||||
bin_PROGRAMS =
|
|
||||||
sbin_SCRIPTS =
|
|
||||||
sbin_PROGRAMS =
|
|
||||||
dist_bin_SCRIPTS =
|
|
||||||
zfsexec_PROGRAMS =
|
|
||||||
mounthelper_PROGRAMS =
|
|
||||||
|
|
||||||
|
SUBDIRS = zfs zpool zdb zhack zinject zstream ztest
|
||||||
|
SUBDIRS += fsck_zfs vdev_id raidz_test zfs_ids_to_path
|
||||||
|
SUBDIRS += zpool_influxdb
|
||||||
|
|
||||||
sbin_SCRIPTS += fsck.zfs
|
CPPCHECKDIRS = zfs zpool zdb zhack zinject zstream ztest
|
||||||
SHELLCHECKSCRIPTS += fsck.zfs
|
CPPCHECKDIRS += raidz_test zfs_ids_to_path zpool_influxdb
|
||||||
CLEANFILES += fsck.zfs
|
|
||||||
dist_noinst_DATA += %D%/fsck.zfs.in
|
|
||||||
$(call SUBST,fsck.zfs,%D%/)
|
|
||||||
|
|
||||||
|
|
||||||
sbin_PROGRAMS += zfs_ids_to_path
|
|
||||||
CPPCHECKTARGETS += zfs_ids_to_path
|
|
||||||
|
|
||||||
zfs_ids_to_path_SOURCES = \
|
|
||||||
%D%/zfs_ids_to_path.c
|
|
||||||
|
|
||||||
zfs_ids_to_path_LDADD = \
|
|
||||||
libzfs.la
|
|
||||||
|
|
||||||
|
|
||||||
zhack_CPPFLAGS = $(AM_CPPFLAGS) $(FORCEDEBUG_CPPFLAGS)
|
|
||||||
|
|
||||||
sbin_PROGRAMS += zhack
|
|
||||||
CPPCHECKTARGETS += zhack
|
|
||||||
|
|
||||||
zhack_SOURCES = \
|
|
||||||
%D%/zhack.c
|
|
||||||
|
|
||||||
zhack_LDADD = \
|
|
||||||
libzpool.la \
|
|
||||||
libzfs_core.la \
|
|
||||||
libnvpair.la
|
|
||||||
|
|
||||||
|
|
||||||
ztest_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS)
|
|
||||||
# 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
|
|
||||||
CPPCHECKTARGETS += ztest
|
|
||||||
|
|
||||||
ztest_SOURCES = \
|
|
||||||
%D%/ztest.c
|
|
||||||
|
|
||||||
ztest_LDADD = \
|
|
||||||
libzpool.la \
|
|
||||||
libzfs_core.la \
|
|
||||||
libnvpair.la
|
|
||||||
|
|
||||||
ztest_LDADD += -lm
|
|
||||||
ztest_LDFLAGS = -pthread
|
|
||||||
|
|
||||||
|
|
||||||
include $(srcdir)/%D%/raidz_test/Makefile.am
|
|
||||||
include $(srcdir)/%D%/zdb/Makefile.am
|
|
||||||
include $(srcdir)/%D%/zfs/Makefile.am
|
|
||||||
include $(srcdir)/%D%/zinject/Makefile.am
|
|
||||||
include $(srcdir)/%D%/zpool/Makefile.am
|
|
||||||
include $(srcdir)/%D%/zpool_influxdb/Makefile.am
|
|
||||||
include $(srcdir)/%D%/zstream/Makefile.am
|
|
||||||
|
|
||||||
|
|
||||||
if BUILD_LINUX
|
|
||||||
mounthelper_PROGRAMS += mount.zfs
|
|
||||||
CPPCHECKTARGETS += mount.zfs
|
|
||||||
|
|
||||||
mount_zfs_SOURCES = \
|
|
||||||
%D%/mount_zfs.c
|
|
||||||
|
|
||||||
mount_zfs_LDADD = \
|
|
||||||
libzfs.la \
|
|
||||||
libzfs_core.la \
|
|
||||||
libnvpair.la
|
|
||||||
|
|
||||||
mount_zfs_LDADD += $(LTLIBINTL)
|
|
||||||
|
|
||||||
CPPCHECKTARGETS += raidz_test
|
|
||||||
|
|
||||||
|
|
||||||
sbin_PROGRAMS += zgenhostid
|
|
||||||
CPPCHECKTARGETS += zgenhostid
|
|
||||||
|
|
||||||
zgenhostid_SOURCES = \
|
|
||||||
%D%/zgenhostid.c
|
|
||||||
|
|
||||||
|
|
||||||
dist_bin_SCRIPTS += %D%/zvol_wait
|
|
||||||
SHELLCHECKSCRIPTS += %D%/zvol_wait
|
|
||||||
|
|
||||||
|
|
||||||
include $(srcdir)/%D%/zed/Makefile.am
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
# TODO: #12084: SHELLCHECKDIRS = fsck_zfs vdev_id zpool
|
||||||
|
SHELLCHECKDIRS = fsck_zfs zpool
|
||||||
|
|
||||||
if USING_PYTHON
|
if USING_PYTHON
|
||||||
bin_SCRIPTS += arc_summary arcstat dbufstat zilstat
|
SUBDIRS += arcstat arc_summary dbufstat
|
||||||
CLEANFILES += arc_summary arcstat dbufstat zilstat
|
|
||||||
dist_noinst_DATA += %D%/arc_summary %D%/arcstat.in %D%/dbufstat.in %D%/zilstat.in
|
|
||||||
|
|
||||||
$(call SUBST,arcstat,%D%/)
|
|
||||||
$(call SUBST,dbufstat,%D%/)
|
|
||||||
$(call SUBST,zilstat,%D%/)
|
|
||||||
arc_summary: %D%/arc_summary
|
|
||||||
$(AM_V_at)cp $< $@
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if BUILD_LINUX
|
||||||
|
SUBDIRS += mount_zfs zed zgenhostid zvol_id zvol_wait
|
||||||
|
CPPCHECKDIRS += mount_zfs zed zgenhostid zvol_id
|
||||||
|
SHELLCHECKDIRS += zed
|
||||||
|
endif
|
||||||
|
|
||||||
PHONY += cmd
|
PHONY = cppcheck
|
||||||
cmd: $(bin_SCRIPTS) $(bin_PROGRAMS) $(sbin_SCRIPTS) $(sbin_PROGRAMS) $(dist_bin_SCRIPTS) $(zfsexec_PROGRAMS) $(mounthelper_PROGRAMS)
|
cppcheck: $(CPPCHECKDIRS)
|
||||||
|
set -e ; for dir in $(CPPCHECKDIRS) ; do \
|
||||||
|
$(MAKE) -C $$dir cppcheck ; \
|
||||||
|
done
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
arc_summary
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
bin_SCRIPTS = arc_summary
|
||||||
|
|
||||||
|
CLEANFILES = arc_summary
|
||||||
|
EXTRA_DIST = arc_summary2 arc_summary3
|
||||||
|
|
||||||
|
if USING_PYTHON_2
|
||||||
|
SCRIPT = arc_summary2
|
||||||
|
else
|
||||||
|
SCRIPT = arc_summary3
|
||||||
|
endif
|
||||||
|
|
||||||
|
arc_summary: $(SCRIPT)
|
||||||
|
cp $< $@
|
||||||
Executable
+1180
File diff suppressed because it is too large
Load Diff
@@ -64,6 +64,7 @@ SECTION_HELP = 'print info from one section ('+' '.join(SECTIONS)+')'
|
|||||||
SECTION_PATHS = {'arc': 'arcstats',
|
SECTION_PATHS = {'arc': 'arcstats',
|
||||||
'dmu': 'dmu_tx',
|
'dmu': 'dmu_tx',
|
||||||
'l2arc': 'arcstats', # L2ARC stuff lives in arcstats
|
'l2arc': 'arcstats', # L2ARC stuff lives in arcstats
|
||||||
|
'vdev': 'vdev_cache_stats',
|
||||||
'zfetch': 'zfetchstats',
|
'zfetch': 'zfetchstats',
|
||||||
'zil': 'zil'}
|
'zil': 'zil'}
|
||||||
|
|
||||||
@@ -89,6 +90,8 @@ if sys.platform.startswith('freebsd'):
|
|||||||
# Requires py36-sysctl on FreeBSD
|
# Requires py36-sysctl on FreeBSD
|
||||||
import sysctl
|
import sysctl
|
||||||
|
|
||||||
|
VDEV_CACHE_SIZE = 'vdev.cache_size'
|
||||||
|
|
||||||
def is_value(ctl):
|
def is_value(ctl):
|
||||||
return ctl.type != sysctl.CTLTYPE_NODE
|
return ctl.type != sysctl.CTLTYPE_NODE
|
||||||
|
|
||||||
@@ -132,6 +135,8 @@ elif sys.platform.startswith('linux'):
|
|||||||
SPL_PATH = '/sys/module/spl/parameters'
|
SPL_PATH = '/sys/module/spl/parameters'
|
||||||
TUNABLES_PATH = '/sys/module/zfs/parameters'
|
TUNABLES_PATH = '/sys/module/zfs/parameters'
|
||||||
|
|
||||||
|
VDEV_CACHE_SIZE = 'zfs_vdev_cache_size'
|
||||||
|
|
||||||
def load_kstats(section):
|
def load_kstats(section):
|
||||||
path = os.path.join(KSTAT_PATH, section)
|
path = os.path.join(KSTAT_PATH, section)
|
||||||
with open(path) as f:
|
with open(path) as f:
|
||||||
@@ -186,13 +191,21 @@ elif sys.platform.startswith('linux'):
|
|||||||
# there, so we fall back on modinfo
|
# there, so we fall back on modinfo
|
||||||
command = ["/sbin/modinfo", request, "-0"]
|
command = ["/sbin/modinfo", request, "-0"]
|
||||||
|
|
||||||
|
# The recommended way to do this is with subprocess.run(). However,
|
||||||
|
# some installed versions of Python are < 3.5, so we offer them
|
||||||
|
# the option of doing it the old way (for now)
|
||||||
info = ''
|
info = ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
info = subprocess.run(command, stdout=subprocess.PIPE,
|
if 'run' in dir(subprocess):
|
||||||
check=True, universal_newlines=True)
|
info = subprocess.run(command, stdout=subprocess.PIPE,
|
||||||
raw_output = info.stdout.split('\0')
|
universal_newlines=True)
|
||||||
|
raw_output = info.stdout.split('\0')
|
||||||
|
else:
|
||||||
|
info = subprocess.check_output(command,
|
||||||
|
universal_newlines=True)
|
||||||
|
raw_output = info.split('\0')
|
||||||
|
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
print("Error: Descriptions not available",
|
print("Error: Descriptions not available",
|
||||||
@@ -265,14 +278,16 @@ def draw_graph(kstats_dict):
|
|||||||
arc_perc = f_perc(arc_stats['size'], arc_stats['c_max'])
|
arc_perc = f_perc(arc_stats['size'], arc_stats['c_max'])
|
||||||
mfu_size = f_bytes(arc_stats['mfu_size'])
|
mfu_size = f_bytes(arc_stats['mfu_size'])
|
||||||
mru_size = f_bytes(arc_stats['mru_size'])
|
mru_size = f_bytes(arc_stats['mru_size'])
|
||||||
|
meta_limit = f_bytes(arc_stats['arc_meta_limit'])
|
||||||
meta_size = f_bytes(arc_stats['arc_meta_used'])
|
meta_size = f_bytes(arc_stats['arc_meta_used'])
|
||||||
dnode_limit = f_bytes(arc_stats['arc_dnode_limit'])
|
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}) MFU: {2} MRU: {3} META: {4} '
|
info_form = ('ARC: {0} ({1}) MFU: {2} MRU: {3} META: {4} ({5}) '
|
||||||
'DNODE {5} ({6})')
|
'DNODE {6} ({7})')
|
||||||
info_line = info_form.format(arc_size, arc_perc, mfu_size, mru_size,
|
info_line = info_form.format(arc_size, arc_perc, mfu_size, mru_size,
|
||||||
meta_size, dnode_size, dnode_limit)
|
meta_size, meta_limit, 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
|
||||||
|
|
||||||
@@ -551,28 +566,12 @@ def section_arc(kstats_dict):
|
|||||||
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']
|
||||||
meta = arc_stats['meta']
|
mfu_size = arc_stats['mfu_size']
|
||||||
pd = arc_stats['pd']
|
mru_size = arc_stats['mru_size']
|
||||||
pm = arc_stats['pm']
|
meta_limit = arc_stats['arc_meta_limit']
|
||||||
anon_data = arc_stats['anon_data']
|
meta_size = arc_stats['arc_meta_used']
|
||||||
anon_metadata = arc_stats['anon_metadata']
|
|
||||||
mfu_data = arc_stats['mfu_data']
|
|
||||||
mfu_metadata = arc_stats['mfu_metadata']
|
|
||||||
mru_data = arc_stats['mru_data']
|
|
||||||
mru_metadata = arc_stats['mru_metadata']
|
|
||||||
mfug_data = arc_stats['mfu_ghost_data']
|
|
||||||
mfug_metadata = arc_stats['mfu_ghost_metadata']
|
|
||||||
mrug_data = arc_stats['mru_ghost_data']
|
|
||||||
mrug_metadata = arc_stats['mru_ghost_metadata']
|
|
||||||
unc_data = arc_stats['uncached_data']
|
|
||||||
unc_metadata = arc_stats['uncached_metadata']
|
|
||||||
bonus_size = arc_stats['bonus_size']
|
|
||||||
dnode_limit = arc_stats['arc_dnode_limit']
|
dnode_limit = arc_stats['arc_dnode_limit']
|
||||||
dnode_size = arc_stats['dnode_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']
|
|
||||||
target_size_ratio = '{0}:1'.format(int(arc_max) // int(arc_min))
|
target_size_ratio = '{0}:1'.format(int(arc_max) // int(arc_min))
|
||||||
|
|
||||||
prt_2('ARC size (current):',
|
prt_2('ARC size (current):',
|
||||||
@@ -583,56 +582,19 @@ def section_arc(kstats_dict):
|
|||||||
f_perc(arc_min, arc_max), f_bytes(arc_min))
|
f_perc(arc_min, arc_max), f_bytes(arc_min))
|
||||||
prt_i2('Max size (high water):',
|
prt_i2('Max size (high water):',
|
||||||
target_size_ratio, f_bytes(arc_max))
|
target_size_ratio, f_bytes(arc_max))
|
||||||
caches_size = int(anon_data)+int(anon_metadata)+\
|
caches_size = int(mfu_size)+int(mru_size)
|
||||||
int(mfu_data)+int(mfu_metadata)+int(mru_data)+int(mru_metadata)+\
|
prt_i2('Most Frequently Used (MFU) cache size:',
|
||||||
int(unc_data)+int(unc_metadata)
|
f_perc(mfu_size, caches_size), f_bytes(mfu_size))
|
||||||
prt_i2('Anonymous data size:',
|
prt_i2('Most Recently Used (MRU) cache size:',
|
||||||
f_perc(anon_data, caches_size), f_bytes(anon_data))
|
f_perc(mru_size, caches_size), f_bytes(mru_size))
|
||||||
prt_i2('Anonymous metadata size:',
|
prt_i2('Metadata cache size (hard limit):',
|
||||||
f_perc(anon_metadata, caches_size), f_bytes(anon_metadata))
|
f_perc(meta_limit, arc_max), f_bytes(meta_limit))
|
||||||
s = 4294967296
|
prt_i2('Metadata cache size (current):',
|
||||||
v = (s-int(pd))*(s-int(meta))/s
|
f_perc(meta_size, meta_limit), f_bytes(meta_size))
|
||||||
prt_i2('MFU data target:', f_perc(v, s),
|
prt_i2('Dnode cache size (hard limit):',
|
||||||
f_bytes(v / 65536 * caches_size / 65536))
|
f_perc(dnode_limit, meta_limit), f_bytes(dnode_limit))
|
||||||
prt_i2('MFU data size:',
|
prt_i2('Dnode cache size (current):',
|
||||||
f_perc(mfu_data, caches_size), f_bytes(mfu_data))
|
|
||||||
prt_i1('MFU ghost data size:', f_bytes(mfug_data))
|
|
||||||
v = (s-int(pm))*int(meta)/s
|
|
||||||
prt_i2('MFU metadata target:', f_perc(v, s),
|
|
||||||
f_bytes(v / 65536 * caches_size / 65536))
|
|
||||||
prt_i2('MFU metadata size:',
|
|
||||||
f_perc(mfu_metadata, caches_size), f_bytes(mfu_metadata))
|
|
||||||
prt_i1('MFU ghost metadata size:', f_bytes(mfug_metadata))
|
|
||||||
v = int(pd)*(s-int(meta))/s
|
|
||||||
prt_i2('MRU data target:', f_perc(v, s),
|
|
||||||
f_bytes(v / 65536 * caches_size / 65536))
|
|
||||||
prt_i2('MRU data size:',
|
|
||||||
f_perc(mru_data, caches_size), f_bytes(mru_data))
|
|
||||||
prt_i1('MRU ghost data size:', f_bytes(mrug_data))
|
|
||||||
v = int(pm)*int(meta)/s
|
|
||||||
prt_i2('MRU metadata target:', f_perc(v, s),
|
|
||||||
f_bytes(v / 65536 * caches_size / 65536))
|
|
||||||
prt_i2('MRU metadata size:',
|
|
||||||
f_perc(mru_metadata, caches_size), f_bytes(mru_metadata))
|
|
||||||
prt_i1('MRU ghost metadata size:', f_bytes(mrug_metadata))
|
|
||||||
prt_i2('Uncached data size:',
|
|
||||||
f_perc(unc_data, caches_size), f_bytes(unc_data))
|
|
||||||
prt_i2('Uncached metadata size:',
|
|
||||||
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))
|
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:')
|
||||||
@@ -672,119 +634,78 @@ def section_archits(kstats_dict):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
arc_stats = isolate_section('arcstats', kstats_dict)
|
arc_stats = isolate_section('arcstats', kstats_dict)
|
||||||
all_accesses = int(arc_stats['hits'])+int(arc_stats['iohits'])+\
|
all_accesses = int(arc_stats['hits'])+int(arc_stats['misses'])
|
||||||
int(arc_stats['misses'])
|
actual_hits = int(arc_stats['mfu_hits'])+int(arc_stats['mru_hits'])
|
||||||
|
|
||||||
|
prt_1('ARC total accesses (hits + misses):', f_hits(all_accesses))
|
||||||
|
ta_todo = (('Cache hit ratio:', arc_stats['hits']),
|
||||||
|
('Cache miss ratio:', arc_stats['misses']),
|
||||||
|
('Actual hit ratio (MFU + MRU hits):', actual_hits))
|
||||||
|
|
||||||
prt_1('ARC total accesses:', f_hits(all_accesses))
|
|
||||||
ta_todo = (('Total hits:', arc_stats['hits']),
|
|
||||||
('Total I/O hits:', arc_stats['iohits']),
|
|
||||||
('Total misses:', arc_stats['misses']))
|
|
||||||
for title, value in ta_todo:
|
for title, value in ta_todo:
|
||||||
prt_i2(title, f_perc(value, all_accesses), f_hits(value))
|
prt_i2(title, f_perc(value, all_accesses), f_hits(value))
|
||||||
print()
|
|
||||||
|
|
||||||
dd_total = int(arc_stats['demand_data_hits']) +\
|
dd_total = int(arc_stats['demand_data_hits']) +\
|
||||||
int(arc_stats['demand_data_iohits']) +\
|
|
||||||
int(arc_stats['demand_data_misses'])
|
int(arc_stats['demand_data_misses'])
|
||||||
prt_2('ARC demand data accesses:', f_perc(dd_total, all_accesses),
|
prt_i2('Data demand efficiency:',
|
||||||
f_hits(dd_total))
|
f_perc(arc_stats['demand_data_hits'], dd_total),
|
||||||
dd_todo = (('Demand data hits:', arc_stats['demand_data_hits']),
|
f_hits(dd_total))
|
||||||
('Demand data I/O hits:', arc_stats['demand_data_iohits']),
|
|
||||||
('Demand data misses:', arc_stats['demand_data_misses']))
|
|
||||||
for title, value in dd_todo:
|
|
||||||
prt_i2(title, f_perc(value, dd_total), f_hits(value))
|
|
||||||
print()
|
|
||||||
|
|
||||||
dm_total = int(arc_stats['demand_metadata_hits']) +\
|
dp_total = int(arc_stats['prefetch_data_hits']) +\
|
||||||
int(arc_stats['demand_metadata_iohits']) +\
|
|
||||||
int(arc_stats['demand_metadata_misses'])
|
|
||||||
prt_2('ARC demand metadata accesses:', f_perc(dm_total, all_accesses),
|
|
||||||
f_hits(dm_total))
|
|
||||||
dm_todo = (('Demand metadata hits:', arc_stats['demand_metadata_hits']),
|
|
||||||
('Demand metadata I/O hits:',
|
|
||||||
arc_stats['demand_metadata_iohits']),
|
|
||||||
('Demand metadata misses:', arc_stats['demand_metadata_misses']))
|
|
||||||
for title, value in dm_todo:
|
|
||||||
prt_i2(title, f_perc(value, dm_total), f_hits(value))
|
|
||||||
print()
|
|
||||||
|
|
||||||
pd_total = int(arc_stats['prefetch_data_hits']) +\
|
|
||||||
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_i2('Data prefetch efficiency:',
|
||||||
f_hits(pd_total))
|
f_perc(arc_stats['prefetch_data_hits'], dp_total),
|
||||||
pd_todo = (('Prefetch data hits:', arc_stats['prefetch_data_hits']),
|
f_hits(dp_total))
|
||||||
('Prefetch data I/O hits:', arc_stats['prefetch_data_iohits']),
|
|
||||||
('Prefetch data misses:', arc_stats['prefetch_data_misses']))
|
|
||||||
for title, value in pd_todo:
|
|
||||||
prt_i2(title, f_perc(value, pd_total), f_hits(value))
|
|
||||||
print()
|
|
||||||
|
|
||||||
pm_total = int(arc_stats['prefetch_metadata_hits']) +\
|
known_hits = int(arc_stats['mfu_hits']) +\
|
||||||
int(arc_stats['prefetch_metadata_iohits']) +\
|
int(arc_stats['mru_hits']) +\
|
||||||
int(arc_stats['prefetch_metadata_misses'])
|
int(arc_stats['mfu_ghost_hits']) +\
|
||||||
prt_2('ARC prefetch metadata accesses:', f_perc(pm_total, all_accesses),
|
int(arc_stats['mru_ghost_hits'])
|
||||||
f_hits(pm_total))
|
|
||||||
pm_todo = (('Prefetch metadata hits:',
|
|
||||||
arc_stats['prefetch_metadata_hits']),
|
|
||||||
('Prefetch metadata I/O hits:',
|
|
||||||
arc_stats['prefetch_metadata_iohits']),
|
|
||||||
('Prefetch metadata misses:',
|
|
||||||
arc_stats['prefetch_metadata_misses']))
|
|
||||||
for title, value in pm_todo:
|
|
||||||
prt_i2(title, f_perc(value, pm_total), f_hits(value))
|
|
||||||
print()
|
|
||||||
|
|
||||||
all_prefetches = int(arc_stats['predictive_prefetch'])+\
|
anon_hits = int(arc_stats['hits'])-known_hits
|
||||||
int(arc_stats['prescient_prefetch'])
|
|
||||||
prt_2('ARC predictive prefetches:',
|
|
||||||
f_perc(arc_stats['predictive_prefetch'], all_prefetches),
|
|
||||||
f_hits(arc_stats['predictive_prefetch']))
|
|
||||||
prt_i2('Demand hits after predictive:',
|
|
||||||
f_perc(arc_stats['demand_hit_predictive_prefetch'],
|
|
||||||
arc_stats['predictive_prefetch']),
|
|
||||||
f_hits(arc_stats['demand_hit_predictive_prefetch']))
|
|
||||||
prt_i2('Demand I/O hits after predictive:',
|
|
||||||
f_perc(arc_stats['demand_iohit_predictive_prefetch'],
|
|
||||||
arc_stats['predictive_prefetch']),
|
|
||||||
f_hits(arc_stats['demand_iohit_predictive_prefetch']))
|
|
||||||
never = int(arc_stats['predictive_prefetch']) -\
|
|
||||||
int(arc_stats['demand_hit_predictive_prefetch']) -\
|
|
||||||
int(arc_stats['demand_iohit_predictive_prefetch'])
|
|
||||||
prt_i2('Never demanded after predictive:',
|
|
||||||
f_perc(never, arc_stats['predictive_prefetch']),
|
|
||||||
f_hits(never))
|
|
||||||
print()
|
|
||||||
|
|
||||||
prt_2('ARC prescient prefetches:',
|
|
||||||
f_perc(arc_stats['prescient_prefetch'], all_prefetches),
|
|
||||||
f_hits(arc_stats['prescient_prefetch']))
|
|
||||||
prt_i2('Demand hits after prescient:',
|
|
||||||
f_perc(arc_stats['demand_hit_prescient_prefetch'],
|
|
||||||
arc_stats['prescient_prefetch']),
|
|
||||||
f_hits(arc_stats['demand_hit_prescient_prefetch']))
|
|
||||||
prt_i2('Demand I/O hits after prescient:',
|
|
||||||
f_perc(arc_stats['demand_iohit_prescient_prefetch'],
|
|
||||||
arc_stats['prescient_prefetch']),
|
|
||||||
f_hits(arc_stats['demand_iohit_prescient_prefetch']))
|
|
||||||
never = int(arc_stats['prescient_prefetch'])-\
|
|
||||||
int(arc_stats['demand_hit_prescient_prefetch'])-\
|
|
||||||
int(arc_stats['demand_iohit_prescient_prefetch'])
|
|
||||||
prt_i2('Never demanded after prescient:',
|
|
||||||
f_perc(never, arc_stats['prescient_prefetch']),
|
|
||||||
f_hits(never))
|
|
||||||
print()
|
print()
|
||||||
|
print('Cache hits by cache type:')
|
||||||
print('ARC states hits of all accesses:')
|
|
||||||
cl_todo = (('Most frequently used (MFU):', arc_stats['mfu_hits']),
|
cl_todo = (('Most frequently used (MFU):', arc_stats['mfu_hits']),
|
||||||
('Most recently used (MRU):', arc_stats['mru_hits']),
|
('Most recently used (MRU):', arc_stats['mru_hits']),
|
||||||
('Most frequently used (MFU) ghost:',
|
('Most frequently used (MFU) ghost:',
|
||||||
arc_stats['mfu_ghost_hits']),
|
arc_stats['mfu_ghost_hits']),
|
||||||
('Most recently used (MRU) ghost:',
|
('Most recently used (MRU) ghost:',
|
||||||
arc_stats['mru_ghost_hits']),
|
arc_stats['mru_ghost_hits']))
|
||||||
('Uncached:', arc_stats['uncached_hits']))
|
|
||||||
for title, value in cl_todo:
|
for title, value in cl_todo:
|
||||||
prt_i2(title, f_perc(value, all_accesses), f_hits(value))
|
prt_i2(title, f_perc(value, arc_stats['hits']), f_hits(value))
|
||||||
|
|
||||||
|
# For some reason, anon_hits can turn negative, which is weird. Until we
|
||||||
|
# have figured out why this happens, we just hide the problem, following
|
||||||
|
# the behavior of the original arc_summary.
|
||||||
|
if anon_hits >= 0:
|
||||||
|
prt_i2('Anonymously used:',
|
||||||
|
f_perc(anon_hits, arc_stats['hits']), f_hits(anon_hits))
|
||||||
|
|
||||||
|
print()
|
||||||
|
print('Cache hits by data type:')
|
||||||
|
dt_todo = (('Demand data:', arc_stats['demand_data_hits']),
|
||||||
|
('Demand prefetch data:', arc_stats['prefetch_data_hits']),
|
||||||
|
('Demand metadata:', arc_stats['demand_metadata_hits']),
|
||||||
|
('Demand prefetch metadata:',
|
||||||
|
arc_stats['prefetch_metadata_hits']))
|
||||||
|
|
||||||
|
for title, value in dt_todo:
|
||||||
|
prt_i2(title, f_perc(value, arc_stats['hits']), f_hits(value))
|
||||||
|
|
||||||
|
print()
|
||||||
|
print('Cache misses by data type:')
|
||||||
|
dm_todo = (('Demand data:', arc_stats['demand_data_misses']),
|
||||||
|
('Demand prefetch data:',
|
||||||
|
arc_stats['prefetch_data_misses']),
|
||||||
|
('Demand metadata:', arc_stats['demand_metadata_misses']),
|
||||||
|
('Demand prefetch metadata:',
|
||||||
|
arc_stats['prefetch_metadata_misses']))
|
||||||
|
|
||||||
|
for title, value in dm_todo:
|
||||||
|
prt_i2(title, f_perc(value, arc_stats['misses']), f_hits(value))
|
||||||
|
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
@@ -793,28 +714,13 @@ 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 prefetch efficiency:', f_hits(zfetch_access_total))
|
||||||
prt_i2('Stream hits:',
|
prt_i2('Hit ratio:', 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('Miss ratio:', f_perc(zfetch_stats['misses'], zfetch_access_total),
|
||||||
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:',
|
|
||||||
f_perc(zfetch_stats['misses'], zfetch_access_total),
|
|
||||||
f_hits(zfetch_stats['misses']))
|
f_hits(zfetch_stats['misses']))
|
||||||
prt_i2('Streams limit reached:',
|
|
||||||
f_perc(zfetch_stats['max_streams'], zfetch_stats['misses']),
|
|
||||||
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']))
|
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
@@ -846,8 +752,7 @@ def section_l2arc(kstats_dict):
|
|||||||
('Free on write:', 'l2_free_on_write'),
|
('Free on write:', 'l2_free_on_write'),
|
||||||
('R/W clashes:', 'l2_rw_clash'),
|
('R/W clashes:', 'l2_rw_clash'),
|
||||||
('Bad checksums:', 'l2_cksum_bad'),
|
('Bad checksums:', 'l2_cksum_bad'),
|
||||||
('Read errors:', 'l2_io_error'),
|
('I/O errors:', 'l2_io_error'))
|
||||||
('Write errors:', 'l2_writes_error'))
|
|
||||||
|
|
||||||
for title, value in l2_todo:
|
for title, value in l2_todo:
|
||||||
prt_i1(title, f_hits(arc_stats[value]))
|
prt_i1(title, f_hits(arc_stats[value]))
|
||||||
@@ -883,20 +788,28 @@ def section_l2arc(kstats_dict):
|
|||||||
prt_i2('Miss ratio:',
|
prt_i2('Miss ratio:',
|
||||||
f_perc(arc_stats['l2_misses'], l2_access_total),
|
f_perc(arc_stats['l2_misses'], l2_access_total),
|
||||||
f_hits(arc_stats['l2_misses']))
|
f_hits(arc_stats['l2_misses']))
|
||||||
|
prt_i1('Feeds:', f_hits(arc_stats['l2_feeds']))
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print('L2ARC I/O:')
|
print('L2ARC writes:')
|
||||||
prt_i2('Reads:',
|
|
||||||
f_bytes(arc_stats['l2_read_bytes']),
|
if arc_stats['l2_writes_done'] != arc_stats['l2_writes_sent']:
|
||||||
f_hits(arc_stats['l2_hits']))
|
prt_i2('Writes sent:', 'FAULTED', f_hits(arc_stats['l2_writes_sent']))
|
||||||
prt_i2('Writes:',
|
prt_i2('Done ratio:',
|
||||||
f_bytes(arc_stats['l2_write_bytes']),
|
f_perc(arc_stats['l2_writes_done'],
|
||||||
f_hits(arc_stats['l2_writes_sent']))
|
arc_stats['l2_writes_sent']),
|
||||||
|
f_hits(arc_stats['l2_writes_done']))
|
||||||
|
prt_i2('Error ratio:',
|
||||||
|
f_perc(arc_stats['l2_writes_error'],
|
||||||
|
arc_stats['l2_writes_sent']),
|
||||||
|
f_hits(arc_stats['l2_writes_error']))
|
||||||
|
else:
|
||||||
|
prt_i2('Writes sent:', '100 %', f_hits(arc_stats['l2_writes_sent']))
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print('L2ARC evicts:')
|
print('L2ARC evicts:')
|
||||||
prt_i1('L1 cached:', f_hits(arc_stats['l2_evict_l1cached']))
|
prt_i1('Lock retries:', f_hits(arc_stats['l2_evict_lock_retry']))
|
||||||
prt_i1('While reading:', f_hits(arc_stats['l2_evict_reading']))
|
prt_i1('Upon reading:', f_hits(arc_stats['l2_evict_reading']))
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
@@ -956,6 +869,35 @@ def section_tunables(*_):
|
|||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def section_vdev(kstats_dict):
|
||||||
|
"""Collect information on VDEV caches"""
|
||||||
|
|
||||||
|
# Currently [Nov 2017] the VDEV cache is disabled, because it is actually
|
||||||
|
# harmful. When this is the case, we just skip the whole entry. See
|
||||||
|
# https://github.com/openzfs/zfs/blob/master/module/zfs/vdev_cache.c
|
||||||
|
# for details
|
||||||
|
tunables = get_vdev_params()
|
||||||
|
|
||||||
|
if tunables[VDEV_CACHE_SIZE] == '0':
|
||||||
|
print('VDEV cache disabled, skipping section\n')
|
||||||
|
return
|
||||||
|
|
||||||
|
vdev_stats = isolate_section('vdev_cache_stats', kstats_dict)
|
||||||
|
|
||||||
|
vdev_cache_total = int(vdev_stats['hits']) +\
|
||||||
|
int(vdev_stats['misses']) +\
|
||||||
|
int(vdev_stats['delegations'])
|
||||||
|
|
||||||
|
prt_1('VDEV cache summary:', f_hits(vdev_cache_total))
|
||||||
|
prt_i2('Hit ratio:', f_perc(vdev_stats['hits'], vdev_cache_total),
|
||||||
|
f_hits(vdev_stats['hits']))
|
||||||
|
prt_i2('Miss ratio:', f_perc(vdev_stats['misses'], vdev_cache_total),
|
||||||
|
f_hits(vdev_stats['misses']))
|
||||||
|
prt_i2('Delegations:', f_perc(vdev_stats['delegations'], vdev_cache_total),
|
||||||
|
f_hits(vdev_stats['delegations']))
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
def section_zil(kstats_dict):
|
def section_zil(kstats_dict):
|
||||||
"""Collect information on the ZFS Intent Log. Some of the information
|
"""Collect information on the ZFS Intent Log. Some of the information
|
||||||
taken from https://github.com/openzfs/zfs/blob/master/include/sys/zil.h
|
taken from https://github.com/openzfs/zfs/blob/master/include/sys/zil.h
|
||||||
@@ -983,6 +925,7 @@ section_calls = {'arc': section_arc,
|
|||||||
'l2arc': section_l2arc,
|
'l2arc': section_l2arc,
|
||||||
'spl': section_spl,
|
'spl': section_spl,
|
||||||
'tunables': section_tunables,
|
'tunables': section_tunables,
|
||||||
|
'vdev': section_vdev,
|
||||||
'zil': section_zil}
|
'zil': section_zil}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
arcstat
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
include $(top_srcdir)/config/Substfiles.am
|
||||||
|
|
||||||
|
bin_SCRIPTS = arcstat
|
||||||
|
|
||||||
|
SUBSTFILES += $(bin_SCRIPTS)
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
# with the License.
|
# with the License.
|
||||||
#
|
#
|
||||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
# or https://opensource.org/licenses/CDDL-1.0.
|
# or http://www.opensolaris.org/os/licensing.
|
||||||
# See the License for the specific language governing permissions
|
# See the License for the specific language governing permissions
|
||||||
# and limitations under the License.
|
# and limitations under the License.
|
||||||
#
|
#
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
# @hdr is the array of fields that needs to be printed, so we
|
# @hdr is the array of fields that needs to be printed, so we
|
||||||
# just iterate over this array and print the values using our pretty printer.
|
# just iterate over this array and print the values using our pretty printer.
|
||||||
#
|
#
|
||||||
# This script must remain compatible with Python 3.6+.
|
# This script must remain compatible with Python 2.6+ and Python 3.4+.
|
||||||
#
|
#
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
@@ -62,64 +62,31 @@ from signal import signal, SIGINT, SIGWINCH, SIG_DFL
|
|||||||
cols = {
|
cols = {
|
||||||
# HDR: [Size, Scale, Description]
|
# HDR: [Size, Scale, Description]
|
||||||
"time": [8, -1, "Time"],
|
"time": [8, -1, "Time"],
|
||||||
"hits": [4, 1000, "ARC hits per second"],
|
"hits": [4, 1000, "ARC reads per second"],
|
||||||
"iohs": [4, 1000, "ARC I/O hits per second"],
|
|
||||||
"miss": [4, 1000, "ARC misses per second"],
|
"miss": [4, 1000, "ARC misses per second"],
|
||||||
"read": [4, 1000, "Total ARC accesses per second"],
|
"read": [4, 1000, "Total ARC accesses per second"],
|
||||||
"hit%": [4, 100, "ARC hit percentage"],
|
"hit%": [4, 100, "ARC hit percentage"],
|
||||||
"ioh%": [4, 100, "ARC I/O hit percentage"],
|
|
||||||
"miss%": [5, 100, "ARC miss percentage"],
|
"miss%": [5, 100, "ARC miss percentage"],
|
||||||
"dhit": [4, 1000, "Demand hits per second"],
|
"dhit": [4, 1000, "Demand hits per second"],
|
||||||
"dioh": [4, 1000, "Demand I/O hits per second"],
|
|
||||||
"dmis": [4, 1000, "Demand misses per second"],
|
"dmis": [4, 1000, "Demand misses per second"],
|
||||||
"dh%": [3, 100, "Demand hit percentage"],
|
"dh%": [3, 100, "Demand hit percentage"],
|
||||||
"di%": [3, 100, "Demand I/O hit percentage"],
|
|
||||||
"dm%": [3, 100, "Demand miss percentage"],
|
"dm%": [3, 100, "Demand miss percentage"],
|
||||||
"ddhit": [5, 1000, "Demand data hits per second"],
|
|
||||||
"ddioh": [5, 1000, "Demand data I/O hits per second"],
|
|
||||||
"ddmis": [5, 1000, "Demand data misses per second"],
|
|
||||||
"ddh%": [4, 100, "Demand data hit percentage"],
|
|
||||||
"ddi%": [4, 100, "Demand data I/O hit percentage"],
|
|
||||||
"ddm%": [4, 100, "Demand data miss percentage"],
|
|
||||||
"dmhit": [5, 1000, "Demand metadata hits per second"],
|
|
||||||
"dmioh": [5, 1000, "Demand metadata I/O hits per second"],
|
|
||||||
"dmmis": [5, 1000, "Demand metadata misses per second"],
|
|
||||||
"dmh%": [4, 100, "Demand metadata hit percentage"],
|
|
||||||
"dmi%": [4, 100, "Demand metadata I/O hit percentage"],
|
|
||||||
"dmm%": [4, 100, "Demand metadata miss percentage"],
|
|
||||||
"phit": [4, 1000, "Prefetch hits per second"],
|
"phit": [4, 1000, "Prefetch hits per second"],
|
||||||
"pioh": [4, 1000, "Prefetch I/O hits per second"],
|
|
||||||
"pmis": [4, 1000, "Prefetch misses per second"],
|
"pmis": [4, 1000, "Prefetch misses per second"],
|
||||||
"ph%": [3, 100, "Prefetch hits percentage"],
|
"ph%": [3, 100, "Prefetch hits percentage"],
|
||||||
"pi%": [3, 100, "Prefetch I/O hits percentage"],
|
|
||||||
"pm%": [3, 100, "Prefetch miss percentage"],
|
"pm%": [3, 100, "Prefetch miss percentage"],
|
||||||
"pdhit": [5, 1000, "Prefetch data hits per second"],
|
|
||||||
"pdioh": [5, 1000, "Prefetch data I/O hits per second"],
|
|
||||||
"pdmis": [5, 1000, "Prefetch data misses per second"],
|
|
||||||
"pdh%": [4, 100, "Prefetch data hits percentage"],
|
|
||||||
"pdi%": [4, 100, "Prefetch data I/O hits percentage"],
|
|
||||||
"pdm%": [4, 100, "Prefetch data miss percentage"],
|
|
||||||
"pmhit": [5, 1000, "Prefetch metadata hits per second"],
|
|
||||||
"pmioh": [5, 1000, "Prefetch metadata I/O hits per second"],
|
|
||||||
"pmmis": [5, 1000, "Prefetch metadata misses per second"],
|
|
||||||
"pmh%": [4, 100, "Prefetch metadata hits percentage"],
|
|
||||||
"pmi%": [4, 100, "Prefetch metadata I/O hits percentage"],
|
|
||||||
"pmm%": [4, 100, "Prefetch metadata miss percentage"],
|
|
||||||
"mhit": [4, 1000, "Metadata hits per second"],
|
"mhit": [4, 1000, "Metadata hits per second"],
|
||||||
"mioh": [4, 1000, "Metadata I/O hits per second"],
|
|
||||||
"mmis": [4, 1000, "Metadata misses per second"],
|
"mmis": [4, 1000, "Metadata misses per second"],
|
||||||
"mread": [5, 1000, "Metadata accesses per second"],
|
"mread": [5, 1000, "Metadata accesses per second"],
|
||||||
"mh%": [3, 100, "Metadata hit percentage"],
|
"mh%": [3, 100, "Metadata hit percentage"],
|
||||||
"mi%": [3, 100, "Metadata I/O hit percentage"],
|
|
||||||
"mm%": [3, 100, "Metadata miss percentage"],
|
"mm%": [3, 100, "Metadata miss percentage"],
|
||||||
"arcsz": [5, 1024, "ARC size"],
|
"arcsz": [5, 1024, "ARC size"],
|
||||||
"size": [5, 1024, "ARC size"],
|
"size": [4, 1024, "ARC size"],
|
||||||
"c": [5, 1024, "ARC target size"],
|
"c": [4, 1024, "ARC target size"],
|
||||||
"mfu": [4, 1000, "MFU list hits per second"],
|
"mfu": [4, 1000, "MFU list hits per second"],
|
||||||
"mru": [4, 1000, "MRU list hits per second"],
|
"mru": [4, 1000, "MRU list hits per second"],
|
||||||
"mfug": [4, 1000, "MFU ghost list hits per second"],
|
"mfug": [4, 1000, "MFU ghost list hits per second"],
|
||||||
"mrug": [4, 1000, "MRU ghost list hits per second"],
|
"mrug": [4, 1000, "MRU ghost list hits per second"],
|
||||||
"unc": [4, 1000, "Uncached list hits per second"],
|
|
||||||
"eskip": [5, 1000, "evict_skip per second"],
|
"eskip": [5, 1000, "evict_skip per second"],
|
||||||
"el2skip": [7, 1000, "evict skip, due to l2 writes, per second"],
|
"el2skip": [7, 1000, "evict skip, due to l2 writes, per second"],
|
||||||
"el2cach": [7, 1024, "Size of L2 cached evictions per second"],
|
"el2cach": [7, 1024, "Size of L2 cached evictions per second"],
|
||||||
@@ -129,11 +96,7 @@ cols = {
|
|||||||
"el2inel": [7, 1024, "Size of L2 ineligible evictions per second"],
|
"el2inel": [7, 1024, "Size of L2 ineligible evictions per second"],
|
||||||
"mtxmis": [6, 1000, "mutex_miss per second"],
|
"mtxmis": [6, 1000, "mutex_miss per second"],
|
||||||
"dread": [5, 1000, "Demand accesses per second"],
|
"dread": [5, 1000, "Demand accesses per second"],
|
||||||
"ddread": [6, 1000, "Demand data accesses per second"],
|
|
||||||
"dmread": [6, 1000, "Demand metadata accesses per second"],
|
|
||||||
"pread": [5, 1000, "Prefetch accesses per second"],
|
"pread": [5, 1000, "Prefetch accesses per second"],
|
||||||
"pdread": [6, 1000, "Prefetch data accesses per second"],
|
|
||||||
"pmread": [6, 1000, "Prefetch metadata accesses per second"],
|
|
||||||
"l2hits": [6, 1000, "L2ARC hits per second"],
|
"l2hits": [6, 1000, "L2ARC hits per second"],
|
||||||
"l2miss": [6, 1000, "L2ARC misses per second"],
|
"l2miss": [6, 1000, "L2ARC misses per second"],
|
||||||
"l2read": [6, 1000, "Total L2ARC accesses per second"],
|
"l2read": [6, 1000, "Total L2ARC accesses per second"],
|
||||||
@@ -153,34 +116,23 @@ cols = {
|
|||||||
"l2size": [6, 1024, "Size of the L2ARC"],
|
"l2size": [6, 1024, "Size of the L2ARC"],
|
||||||
"l2bytes": [7, 1024, "Bytes read per second from the L2ARC"],
|
"l2bytes": [7, 1024, "Bytes read per second from the L2ARC"],
|
||||||
"grow": [4, 1000, "ARC grow disabled"],
|
"grow": [4, 1000, "ARC grow disabled"],
|
||||||
"need": [5, 1024, "ARC reclaim need"],
|
"need": [4, 1024, "ARC reclaim need"],
|
||||||
"free": [5, 1024, "ARC free memory"],
|
"free": [4, 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 = {}
|
||||||
hdr = ["time", "read", "ddread", "ddh%", "dmread", "dmh%", "pread", "ph%",
|
hdr = ["time", "read", "miss", "miss%", "dmis", "dm%", "pmis", "pm%", "mmis",
|
||||||
"size", "c", "avail"]
|
"mm%", "size", "c", "avail"]
|
||||||
xhdr = ["time", "mfu", "mru", "mfug", "mrug", "unc", "eskip", "mtxmis",
|
xhdr = ["time", "mfu", "mru", "mfug", "mrug", "eskip", "mtxmis", "dread",
|
||||||
"dread", "pread", "read"]
|
"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
|
||||||
opfile = None
|
opfile = None
|
||||||
sep = " " # Default separator is 2 spaces
|
sep = " " # Default separator is 2 spaces
|
||||||
|
version = "0.4"
|
||||||
l2exist = False
|
l2exist = False
|
||||||
cmd = ("Usage: arcstat [-havxp] [-f fields] [-o file] [-s string] [interval "
|
cmd = ("Usage: arcstat [-havxp] [-f fields] [-o file] [-s string] [interval "
|
||||||
"[count]]\n")
|
"[count]]\n")
|
||||||
@@ -200,8 +152,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 +163,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 +203,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 "
|
||||||
@@ -331,7 +271,7 @@ def print_values():
|
|||||||
if pretty_print:
|
if pretty_print:
|
||||||
fmt = lambda col: prettynum(cols[col][0], cols[col][1], v[col])
|
fmt = lambda col: prettynum(cols[col][0], cols[col][1], v[col])
|
||||||
else:
|
else:
|
||||||
fmt = lambda col: str(v[col])
|
fmt = lambda col: v[col]
|
||||||
|
|
||||||
sys.stdout.write(sep.join(fmt(col) for col in hdr))
|
sys.stdout.write(sep.join(fmt(col) for col in hdr))
|
||||||
sys.stdout.write("\n")
|
sys.stdout.write("\n")
|
||||||
@@ -381,7 +321,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 +332,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 +374,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 +389,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
|
||||||
@@ -509,131 +441,73 @@ def calculate():
|
|||||||
|
|
||||||
v = dict()
|
v = dict()
|
||||||
v["time"] = time.strftime("%H:%M:%S", time.localtime())
|
v["time"] = time.strftime("%H:%M:%S", time.localtime())
|
||||||
v["hits"] = d["hits"] // sint
|
v["hits"] = d["hits"] / sint
|
||||||
v["iohs"] = d["iohits"] // sint
|
v["miss"] = d["misses"] / sint
|
||||||
v["miss"] = d["misses"] // sint
|
v["read"] = v["hits"] + v["miss"]
|
||||||
v["read"] = v["hits"] + v["iohs"] + v["miss"]
|
v["hit%"] = 100 * v["hits"] / v["read"] if v["read"] > 0 else 0
|
||||||
v["hit%"] = 100 * v["hits"] // v["read"] if v["read"] > 0 else 0
|
v["miss%"] = 100 - v["hit%"] if v["read"] > 0 else 0
|
||||||
v["ioh%"] = 100 * v["iohs"] // v["read"] if v["read"] > 0 else 0
|
|
||||||
v["miss%"] = 100 - v["hit%"] - v["ioh%"] if v["read"] > 0 else 0
|
|
||||||
|
|
||||||
v["dhit"] = (d["demand_data_hits"] + d["demand_metadata_hits"]) // sint
|
v["dhit"] = (d["demand_data_hits"] + d["demand_metadata_hits"]) / sint
|
||||||
v["dioh"] = (d["demand_data_iohits"] + d["demand_metadata_iohits"]) // sint
|
v["dmis"] = (d["demand_data_misses"] + d["demand_metadata_misses"]) / sint
|
||||||
v["dmis"] = (d["demand_data_misses"] + d["demand_metadata_misses"]) // sint
|
|
||||||
|
|
||||||
v["dread"] = v["dhit"] + v["dioh"] + v["dmis"]
|
v["dread"] = v["dhit"] + v["dmis"]
|
||||||
v["dh%"] = 100 * v["dhit"] // v["dread"] if v["dread"] > 0 else 0
|
v["dh%"] = 100 * v["dhit"] / v["dread"] if v["dread"] > 0 else 0
|
||||||
v["di%"] = 100 * v["dioh"] // v["dread"] if v["dread"] > 0 else 0
|
v["dm%"] = 100 - v["dh%"] if v["dread"] > 0 else 0
|
||||||
v["dm%"] = 100 - v["dh%"] - v["di%"] if v["dread"] > 0 else 0
|
|
||||||
|
|
||||||
v["ddhit"] = d["demand_data_hits"] // sint
|
v["phit"] = (d["prefetch_data_hits"] + d["prefetch_metadata_hits"]) / sint
|
||||||
v["ddioh"] = d["demand_data_iohits"] // sint
|
|
||||||
v["ddmis"] = d["demand_data_misses"] // sint
|
|
||||||
|
|
||||||
v["ddread"] = v["ddhit"] + v["ddioh"] + v["ddmis"]
|
|
||||||
v["ddh%"] = 100 * v["ddhit"] // v["ddread"] if v["ddread"] > 0 else 0
|
|
||||||
v["ddi%"] = 100 * v["ddioh"] // v["ddread"] if v["ddread"] > 0 else 0
|
|
||||||
v["ddm%"] = 100 - v["ddh%"] - v["ddi%"] if v["ddread"] > 0 else 0
|
|
||||||
|
|
||||||
v["dmhit"] = d["demand_metadata_hits"] // sint
|
|
||||||
v["dmioh"] = d["demand_metadata_iohits"] // sint
|
|
||||||
v["dmmis"] = d["demand_metadata_misses"] // sint
|
|
||||||
|
|
||||||
v["dmread"] = v["dmhit"] + v["dmioh"] + v["dmmis"]
|
|
||||||
v["dmh%"] = 100 * v["dmhit"] // v["dmread"] if v["dmread"] > 0 else 0
|
|
||||||
v["dmi%"] = 100 * v["dmioh"] // v["dmread"] if v["dmread"] > 0 else 0
|
|
||||||
v["dmm%"] = 100 - v["dmh%"] - v["dmi%"] if v["dmread"] > 0 else 0
|
|
||||||
|
|
||||||
v["phit"] = (d["prefetch_data_hits"] + d["prefetch_metadata_hits"]) // sint
|
|
||||||
v["pioh"] = (d["prefetch_data_iohits"] +
|
|
||||||
d["prefetch_metadata_iohits"]) // sint
|
|
||||||
v["pmis"] = (d["prefetch_data_misses"] +
|
v["pmis"] = (d["prefetch_data_misses"] +
|
||||||
d["prefetch_metadata_misses"]) // sint
|
d["prefetch_metadata_misses"]) / sint
|
||||||
|
|
||||||
v["pread"] = v["phit"] + v["pioh"] + v["pmis"]
|
v["pread"] = v["phit"] + v["pmis"]
|
||||||
v["ph%"] = 100 * v["phit"] // v["pread"] if v["pread"] > 0 else 0
|
v["ph%"] = 100 * v["phit"] / v["pread"] if v["pread"] > 0 else 0
|
||||||
v["pi%"] = 100 * v["pioh"] // v["pread"] if v["pread"] > 0 else 0
|
v["pm%"] = 100 - v["ph%"] if v["pread"] > 0 else 0
|
||||||
v["pm%"] = 100 - v["ph%"] - v["pi%"] if v["pread"] > 0 else 0
|
|
||||||
|
|
||||||
v["pdhit"] = d["prefetch_data_hits"] // sint
|
|
||||||
v["pdioh"] = d["prefetch_data_iohits"] // sint
|
|
||||||
v["pdmis"] = d["prefetch_data_misses"] // sint
|
|
||||||
|
|
||||||
v["pdread"] = v["pdhit"] + v["pdioh"] + v["pdmis"]
|
|
||||||
v["pdh%"] = 100 * v["pdhit"] // v["pdread"] if v["pdread"] > 0 else 0
|
|
||||||
v["pdi%"] = 100 * v["pdioh"] // v["pdread"] if v["pdread"] > 0 else 0
|
|
||||||
v["pdm%"] = 100 - v["pdh%"] - v["pdi%"] if v["pdread"] > 0 else 0
|
|
||||||
|
|
||||||
v["pmhit"] = d["prefetch_metadata_hits"] // sint
|
|
||||||
v["pmioh"] = d["prefetch_metadata_iohits"] // sint
|
|
||||||
v["pmmis"] = d["prefetch_metadata_misses"] // sint
|
|
||||||
|
|
||||||
v["pmread"] = v["pmhit"] + v["pmioh"] + v["pmmis"]
|
|
||||||
v["pmh%"] = 100 * v["pmhit"] // v["pmread"] if v["pmread"] > 0 else 0
|
|
||||||
v["pmi%"] = 100 * v["pmioh"] // v["pmread"] if v["pmread"] > 0 else 0
|
|
||||||
v["pmm%"] = 100 - v["pmh%"] - v["pmi%"] if v["pmread"] > 0 else 0
|
|
||||||
|
|
||||||
v["mhit"] = (d["prefetch_metadata_hits"] +
|
v["mhit"] = (d["prefetch_metadata_hits"] +
|
||||||
d["demand_metadata_hits"]) // sint
|
d["demand_metadata_hits"]) / sint
|
||||||
v["mioh"] = (d["prefetch_metadata_iohits"] +
|
|
||||||
d["demand_metadata_iohits"]) // sint
|
|
||||||
v["mmis"] = (d["prefetch_metadata_misses"] +
|
v["mmis"] = (d["prefetch_metadata_misses"] +
|
||||||
d["demand_metadata_misses"]) // sint
|
d["demand_metadata_misses"]) / sint
|
||||||
|
|
||||||
v["mread"] = v["mhit"] + v["mioh"] + v["mmis"]
|
v["mread"] = v["mhit"] + v["mmis"]
|
||||||
v["mh%"] = 100 * v["mhit"] // v["mread"] if v["mread"] > 0 else 0
|
v["mh%"] = 100 * v["mhit"] / v["mread"] if v["mread"] > 0 else 0
|
||||||
v["mi%"] = 100 * v["mioh"] // v["mread"] if v["mread"] > 0 else 0
|
v["mm%"] = 100 - v["mh%"] if v["mread"] > 0 else 0
|
||||||
v["mm%"] = 100 - v["mh%"] - v["mi%"] if v["mread"] > 0 else 0
|
|
||||||
|
|
||||||
v["arcsz"] = cur["size"]
|
v["arcsz"] = cur["size"]
|
||||||
v["size"] = cur["size"]
|
v["size"] = cur["size"]
|
||||||
v["c"] = cur["c"]
|
v["c"] = cur["c"]
|
||||||
v["mfu"] = d["mfu_hits"] // sint
|
v["mfu"] = d["mfu_hits"] / sint
|
||||||
v["mru"] = d["mru_hits"] // sint
|
v["mru"] = d["mru_hits"] / sint
|
||||||
v["mrug"] = d["mru_ghost_hits"] // sint
|
v["mrug"] = d["mru_ghost_hits"] / sint
|
||||||
v["mfug"] = d["mfu_ghost_hits"] // sint
|
v["mfug"] = d["mfu_ghost_hits"] / sint
|
||||||
v["unc"] = d["uncached_hits"] // sint
|
v["eskip"] = d["evict_skip"] / sint
|
||||||
v["eskip"] = d["evict_skip"] // sint
|
v["el2skip"] = d["evict_l2_skip"] / sint
|
||||||
v["el2skip"] = d["evict_l2_skip"] // sint
|
v["el2cach"] = d["evict_l2_cached"] / sint
|
||||||
v["el2cach"] = d["evict_l2_cached"] // sint
|
v["el2el"] = d["evict_l2_eligible"] / sint
|
||||||
v["el2el"] = d["evict_l2_eligible"] // sint
|
v["el2mfu"] = d["evict_l2_eligible_mfu"] / sint
|
||||||
v["el2mfu"] = d["evict_l2_eligible_mfu"] // sint
|
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
|
||||||
v["l2miss"] = d["l2_misses"] // sint
|
v["l2miss"] = d["l2_misses"] / sint
|
||||||
v["l2read"] = v["l2hits"] + v["l2miss"]
|
v["l2read"] = v["l2hits"] + v["l2miss"]
|
||||||
v["l2hit%"] = 100 * v["l2hits"] // v["l2read"] if v["l2read"] > 0 else 0
|
v["l2hit%"] = 100 * v["l2hits"] / v["l2read"] if v["l2read"] > 0 else 0
|
||||||
|
|
||||||
v["l2miss%"] = 100 - v["l2hit%"] if v["l2read"] > 0 else 0
|
v["l2miss%"] = 100 - v["l2hit%"] if v["l2read"] > 0 else 0
|
||||||
v["l2asize"] = cur["l2_asize"]
|
v["l2asize"] = cur["l2_asize"]
|
||||||
v["l2size"] = cur["l2_size"]
|
v["l2size"] = cur["l2_size"]
|
||||||
v["l2bytes"] = d["l2_read_bytes"] // sint
|
v["l2bytes"] = d["l2_read_bytes"] / sint
|
||||||
|
|
||||||
v["l2pref"] = cur["l2_prefetch_asize"]
|
v["l2pref"] = cur["l2_prefetch_asize"]
|
||||||
v["l2mfu"] = cur["l2_mfu_asize"]
|
v["l2mfu"] = cur["l2_mfu_asize"]
|
||||||
v["l2mru"] = cur["l2_mru_asize"]
|
v["l2mru"] = cur["l2_mru_asize"]
|
||||||
v["l2data"] = cur["l2_bufc_data_asize"]
|
v["l2data"] = cur["l2_bufc_data_asize"]
|
||||||
v["l2meta"] = cur["l2_bufc_metadata_asize"]
|
v["l2meta"] = cur["l2_bufc_metadata_asize"]
|
||||||
v["l2pref%"] = 100 * v["l2pref"] // v["l2asize"]
|
v["l2pref%"] = 100 * v["l2pref"] / v["l2asize"]
|
||||||
v["l2mfu%"] = 100 * v["l2mfu"] // v["l2asize"]
|
v["l2mfu%"] = 100 * v["l2mfu"] / v["l2asize"]
|
||||||
v["l2mru%"] = 100 * v["l2mru"] // v["l2asize"]
|
v["l2mru%"] = 100 * v["l2mru"] / v["l2asize"]
|
||||||
v["l2data%"] = 100 * v["l2data"] // v["l2asize"]
|
v["l2data%"] = 100 * v["l2data"] / v["l2asize"]
|
||||||
v["l2meta%"] = 100 * v["l2meta"] // v["l2asize"]
|
v["l2meta%"] = 100 * v["l2meta"] / v["l2asize"]
|
||||||
|
|
||||||
v["grow"] = 0 if cur["arc_no_grow"] else 1
|
v["grow"] = 0 if cur["arc_no_grow"] else 1
|
||||||
v["need"] = cur["arc_need_free"]
|
v["need"] = cur["arc_need_free"]
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
dbufstat
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
include $(top_srcdir)/config/Substfiles.am
|
||||||
|
|
||||||
|
bin_SCRIPTS = dbufstat
|
||||||
|
|
||||||
|
SUBSTFILES += $(bin_SCRIPTS)
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
# with the License.
|
# with the License.
|
||||||
#
|
#
|
||||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
# or https://opensource.org/licenses/CDDL-1.0.
|
# or http://www.opensolaris.org/os/licensing.
|
||||||
# See the License for the specific language governing permissions
|
# See the License for the specific language governing permissions
|
||||||
# and limitations under the License.
|
# and limitations under the License.
|
||||||
#
|
#
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
# Copyright (C) 2013 Lawrence Livermore National Security, LLC.
|
# Copyright (C) 2013 Lawrence Livermore National Security, LLC.
|
||||||
# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
||||||
#
|
#
|
||||||
# This script must remain compatible with and Python 3.6+.
|
# This script must remain compatible with Python 2.6+ and Python 3.4+.
|
||||||
#
|
#
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/fsck.zfs
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
include $(top_srcdir)/config/Substfiles.am
|
||||||
|
include $(top_srcdir)/config/Shellcheck.am
|
||||||
|
|
||||||
|
dist_sbin_SCRIPTS = fsck.zfs
|
||||||
|
|
||||||
|
SUBSTFILES += $(dist_sbin_SCRIPTS)
|
||||||
@@ -7,13 +7,13 @@
|
|||||||
# see fsck.zfs(8)
|
# see fsck.zfs(8)
|
||||||
#
|
#
|
||||||
|
|
||||||
if [ $# -eq 0 ]; then
|
if [ "$#" = "0" ]; then
|
||||||
echo "Usage: $0 [options] dataset…" >&2
|
echo "Usage: $0 [options] dataset…" >&2
|
||||||
exit 16
|
exit 16
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ret=0
|
ret=0
|
||||||
for dataset; do
|
for dataset in "$@"; do
|
||||||
case "$dataset" in
|
case "$dataset" in
|
||||||
-*)
|
-*)
|
||||||
continue
|
continue
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
mount.zfs
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ignore the prefix for the mount helper. It must be installed in /sbin/
|
||||||
|
# because this path is hardcoded in the mount(8) for security reasons.
|
||||||
|
# However, if needed, the configure option --with-mounthelperdir= can be used
|
||||||
|
# to override the default install location.
|
||||||
|
#
|
||||||
|
sbindir=$(mounthelperdir)
|
||||||
|
sbin_PROGRAMS = mount.zfs
|
||||||
|
|
||||||
|
mount_zfs_SOURCES = \
|
||||||
|
mount_zfs.c
|
||||||
|
|
||||||
|
mount_zfs_LDADD = \
|
||||||
|
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
||||||
|
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||||
|
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
||||||
|
|
||||||
|
mount_zfs_LDADD += $(LTLIBINTL)
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -74,7 +74,7 @@ parse_dataset(const char *target, char **dataset)
|
|||||||
|
|
||||||
nvlist_t *cfg = NULL;
|
nvlist_t *cfg = NULL;
|
||||||
if (zpool_read_label(fd, &cfg, NULL) == 0) {
|
if (zpool_read_label(fd, &cfg, NULL) == 0) {
|
||||||
const char *nm = NULL;
|
char *nm = NULL;
|
||||||
if (!nvlist_lookup_string(cfg, ZPOOL_CONFIG_POOL_NAME, &nm))
|
if (!nvlist_lookup_string(cfg, ZPOOL_CONFIG_POOL_NAME, &nm))
|
||||||
strlcpy(*dataset, nm, PATH_MAX);
|
strlcpy(*dataset, nm, PATH_MAX);
|
||||||
nvlist_free(cfg);
|
nvlist_free(cfg);
|
||||||
@@ -108,21 +108,20 @@ mtab_is_writeable(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mtab_update(const char *dataset, const char *mntpoint, const char *type,
|
mtab_update(char *dataset, char *mntpoint, char *type, char *mntopts)
|
||||||
const char *mntopts)
|
|
||||||
{
|
{
|
||||||
struct mntent mnt;
|
struct mntent mnt;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
mnt.mnt_fsname = (char *)dataset;
|
mnt.mnt_fsname = dataset;
|
||||||
mnt.mnt_dir = (char *)mntpoint;
|
mnt.mnt_dir = mntpoint;
|
||||||
mnt.mnt_type = (char *)type;
|
mnt.mnt_type = type;
|
||||||
mnt.mnt_opts = (char *)(mntopts ?: "");
|
mnt.mnt_opts = mntopts ? mntopts : "";
|
||||||
mnt.mnt_freq = 0;
|
mnt.mnt_freq = 0;
|
||||||
mnt.mnt_passno = 0;
|
mnt.mnt_passno = 0;
|
||||||
|
|
||||||
fp = setmntent("/etc/mtab", "a+e");
|
fp = setmntent("/etc/mtab", "a+");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
(void) fprintf(stderr, gettext(
|
(void) fprintf(stderr, gettext(
|
||||||
"filesystem '%s' was mounted, but /etc/mtab "
|
"filesystem '%s' was mounted, but /etc/mtab "
|
||||||
@@ -247,6 +246,13 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
(void) fprintf(stdout, gettext("mount.zfs:\n"
|
||||||
|
" dataset: \"%s\"\n mountpoint: \"%s\"\n"
|
||||||
|
" mountflags: 0x%lx\n zfsflags: 0x%lx\n"
|
||||||
|
" mountopts: \"%s\"\n mtabopts: \"%s\"\n"),
|
||||||
|
dataset, mntpoint, mntflags, zfsflags, mntopts, mtabopt);
|
||||||
|
|
||||||
if (mntflags & MS_REMOUNT) {
|
if (mntflags & MS_REMOUNT) {
|
||||||
nomtab = 1;
|
nomtab = 1;
|
||||||
remount = 1;
|
remount = 1;
|
||||||
@@ -269,10 +275,7 @@ main(int argc, char **argv)
|
|||||||
return (MOUNT_USAGE);
|
return (MOUNT_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!zfsutil || sloppy ||
|
zfs_adjust_mount_options(zhp, mntpoint, mntopts, mtabopt);
|
||||||
libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) {
|
|
||||||
zfs_adjust_mount_options(zhp, mntpoint, mntopts, mtabopt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* treat all snapshots as legacy mount points */
|
/* treat all snapshots as legacy mount points */
|
||||||
if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT)
|
if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT)
|
||||||
@@ -290,11 +293,12 @@ main(int argc, char **argv)
|
|||||||
if (zfs_version == 0) {
|
if (zfs_version == 0) {
|
||||||
fprintf(stderr, gettext("unable to fetch "
|
fprintf(stderr, gettext("unable to fetch "
|
||||||
"ZFS version for filesystem '%s'\n"), dataset);
|
"ZFS version for filesystem '%s'\n"), dataset);
|
||||||
zfs_close(zhp);
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
return (MOUNT_SYSERR);
|
return (MOUNT_SYSERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zfs_close(zhp);
|
||||||
|
libzfs_fini(g_zfs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Legacy mount points may only be mounted using 'mount', never using
|
* Legacy mount points may only be mounted using 'mount', never using
|
||||||
* 'zfs mount'. However, since 'zfs mount' actually invokes 'mount'
|
* 'zfs mount'. However, since 'zfs mount' actually invokes 'mount'
|
||||||
@@ -312,8 +316,6 @@ main(int argc, char **argv)
|
|||||||
"Use 'zfs set mountpoint=%s' or 'mount -t zfs %s %s'.\n"
|
"Use 'zfs set mountpoint=%s' or 'mount -t zfs %s %s'.\n"
|
||||||
"See zfs(8) for more information.\n"),
|
"See zfs(8) for more information.\n"),
|
||||||
dataset, mntpoint, dataset, mntpoint);
|
dataset, mntpoint, dataset, mntpoint);
|
||||||
zfs_close(zhp);
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
return (MOUNT_USAGE);
|
return (MOUNT_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,38 +326,14 @@ main(int argc, char **argv)
|
|||||||
"Use 'zfs set mountpoint=%s' or 'zfs mount %s'.\n"
|
"Use 'zfs set mountpoint=%s' or 'zfs mount %s'.\n"
|
||||||
"See zfs(8) for more information.\n"),
|
"See zfs(8) for more information.\n"),
|
||||||
dataset, "legacy", dataset);
|
dataset, "legacy", dataset);
|
||||||
zfs_close(zhp);
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
return (MOUNT_USAGE);
|
return (MOUNT_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
(void) fprintf(stdout, gettext("mount.zfs:\n"
|
|
||||||
" dataset: \"%s\"\n mountpoint: \"%s\"\n"
|
|
||||||
" mountflags: 0x%lx\n zfsflags: 0x%lx\n"
|
|
||||||
" mountopts: \"%s\"\n mtabopts: \"%s\"\n"),
|
|
||||||
dataset, mntpoint, mntflags, zfsflags, mntopts, mtabopt);
|
|
||||||
|
|
||||||
if (!fake) {
|
if (!fake) {
|
||||||
if (zfsutil && !sloppy &&
|
error = mount(dataset, mntpoint, MNTTYPE_ZFS,
|
||||||
!libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) {
|
mntflags, mntopts);
|
||||||
error = zfs_mount_at(zhp, mntopts, mntflags, mntpoint);
|
|
||||||
if (error) {
|
|
||||||
(void) fprintf(stderr, "zfs_mount_at() failed: "
|
|
||||||
"%s", libzfs_error_description(g_zfs));
|
|
||||||
zfs_close(zhp);
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
return (MOUNT_SYSERR);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
error = mount(dataset, mntpoint, MNTTYPE_ZFS,
|
|
||||||
mntflags, mntopts);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zfs_close(zhp);
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case ENOENT:
|
case ENOENT:
|
||||||
@@ -390,8 +368,8 @@ main(int argc, char **argv)
|
|||||||
"mount the filesystem again.\n"), dataset);
|
"mount the filesystem again.\n"), dataset);
|
||||||
return (MOUNT_SYSERR);
|
return (MOUNT_SYSERR);
|
||||||
}
|
}
|
||||||
|
/* fallthru */
|
||||||
#endif
|
#endif
|
||||||
zfs_fallthrough;
|
|
||||||
default:
|
default:
|
||||||
(void) fprintf(stderr, gettext("filesystem "
|
(void) fprintf(stderr, gettext("filesystem "
|
||||||
"'%s' can not be mounted: %s\n"), dataset,
|
"'%s' can not be mounted: %s\n"), dataset,
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/raidz_test
|
||||||
@@ -1,16 +1,22 @@
|
|||||||
raidz_test_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS)
|
include $(top_srcdir)/config/Rules.am
|
||||||
raidz_test_CPPFLAGS = $(AM_CPPFLAGS) $(FORCEDEBUG_CPPFLAGS)
|
|
||||||
|
|
||||||
bin_PROGRAMS += raidz_test
|
# Includes kernel code, generate warnings for large stack frames
|
||||||
CPPCHECKTARGETS += raidz_test
|
AM_CFLAGS += $(FRAME_LARGER_THAN)
|
||||||
|
|
||||||
|
# Unconditionally enable ASSERTs
|
||||||
|
AM_CPPFLAGS += -DDEBUG -UNDEBUG -DZFS_DEBUG
|
||||||
|
|
||||||
|
bin_PROGRAMS = raidz_test
|
||||||
|
|
||||||
raidz_test_SOURCES = \
|
raidz_test_SOURCES = \
|
||||||
%D%/raidz_bench.c \
|
raidz_test.h \
|
||||||
%D%/raidz_test.c \
|
raidz_test.c \
|
||||||
%D%/raidz_test.h
|
raidz_bench.c
|
||||||
|
|
||||||
raidz_test_LDADD = \
|
raidz_test_LDADD = \
|
||||||
libzpool.la \
|
$(abs_top_builddir)/lib/libzpool/libzpool.la \
|
||||||
libzfs_core.la
|
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la
|
||||||
|
|
||||||
raidz_test_LDADD += -lm
|
raidz_test_LDADD += -lm
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -63,7 +63,7 @@ bench_fini_raidz_maps(void)
|
|||||||
{
|
{
|
||||||
/* tear down golden zio */
|
/* tear down golden zio */
|
||||||
raidz_free(zio_bench.io_abd, max_data_size);
|
raidz_free(zio_bench.io_abd, max_data_size);
|
||||||
memset(&zio_bench, 0, sizeof (zio_t));
|
bzero(&zio_bench, sizeof (zio_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|||||||
+24
-27
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -37,11 +37,11 @@
|
|||||||
static int *rand_data;
|
static int *rand_data;
|
||||||
raidz_test_opts_t rto_opts;
|
raidz_test_opts_t rto_opts;
|
||||||
|
|
||||||
static char pid_s[16];
|
static char gdb[256];
|
||||||
|
static const char gdb_tmpl[] = "gdb -ex \"set pagination 0\" -p %d";
|
||||||
|
|
||||||
static void sig_handler(int signo)
|
static void sig_handler(int signo)
|
||||||
{
|
{
|
||||||
int old_errno = errno;
|
|
||||||
struct sigaction action;
|
struct sigaction action;
|
||||||
/*
|
/*
|
||||||
* Restore default action and re-raise signal so SIGSEGV and
|
* Restore default action and re-raise signal so SIGSEGV and
|
||||||
@@ -52,32 +52,22 @@ static void sig_handler(int signo)
|
|||||||
action.sa_flags = 0;
|
action.sa_flags = 0;
|
||||||
(void) sigaction(signo, &action, NULL);
|
(void) sigaction(signo, &action, NULL);
|
||||||
|
|
||||||
if (rto_opts.rto_gdb) {
|
if (rto_opts.rto_gdb)
|
||||||
pid_t pid = fork();
|
if (system(gdb)) { }
|
||||||
if (pid == 0) {
|
|
||||||
execlp("gdb", "gdb", "-ex", "set pagination 0",
|
|
||||||
"-p", pid_s, NULL);
|
|
||||||
_exit(-1);
|
|
||||||
} else if (pid > 0)
|
|
||||||
while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
raise(signo);
|
raise(signo);
|
||||||
errno = old_errno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_opts(raidz_test_opts_t *opts, boolean_t force)
|
static void print_opts(raidz_test_opts_t *opts, boolean_t force)
|
||||||
{
|
{
|
||||||
const char *verbose;
|
char *verbose;
|
||||||
switch (opts->rto_v) {
|
switch (opts->rto_v) {
|
||||||
case D_ALL:
|
case 0:
|
||||||
verbose = "no";
|
verbose = "no";
|
||||||
break;
|
break;
|
||||||
case D_INFO:
|
case 1:
|
||||||
verbose = "info";
|
verbose = "info";
|
||||||
break;
|
break;
|
||||||
case D_DEBUG:
|
|
||||||
default:
|
default:
|
||||||
verbose = "debug";
|
verbose = "debug";
|
||||||
break;
|
break;
|
||||||
@@ -120,7 +110,7 @@ static void usage(boolean_t requested)
|
|||||||
"\t[-B benchmark all raidz implementations]\n"
|
"\t[-B benchmark all raidz implementations]\n"
|
||||||
"\t[-e use expanded raidz map (default: %s)]\n"
|
"\t[-e use expanded raidz map (default: %s)]\n"
|
||||||
"\t[-r expanded raidz map reflow offset (default: %llx)]\n"
|
"\t[-r expanded raidz map reflow offset (default: %llx)]\n"
|
||||||
"\t[-v increase verbosity (default: %d)]\n"
|
"\t[-v increase verbosity (default: %zu)]\n"
|
||||||
"\t[-h (print help)]\n"
|
"\t[-h (print help)]\n"
|
||||||
"\t[-T test the test, see if failure would be detected]\n"
|
"\t[-T test the test, see if failure would be detected]\n"
|
||||||
"\t[-D debug (attach gdb on SIGSEGV)]\n"
|
"\t[-D debug (attach gdb on SIGSEGV)]\n"
|
||||||
@@ -132,7 +122,7 @@ static void usage(boolean_t requested)
|
|||||||
rto_opts.rto_sweep ? "yes" : "no", /* -S */
|
rto_opts.rto_sweep ? "yes" : "no", /* -S */
|
||||||
rto_opts.rto_expand ? "yes" : "no", /* -e */
|
rto_opts.rto_expand ? "yes" : "no", /* -e */
|
||||||
(u_longlong_t)o->rto_expand_offset, /* -r */
|
(u_longlong_t)o->rto_expand_offset, /* -r */
|
||||||
o->rto_v); /* -v */
|
o->rto_v); /* -d */
|
||||||
|
|
||||||
exit(requested ? 0 : 1);
|
exit(requested ? 0 : 1);
|
||||||
}
|
}
|
||||||
@@ -141,11 +131,14 @@ static void process_options(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
size_t value;
|
size_t value;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
raidz_test_opts_t *o = &rto_opts;
|
raidz_test_opts_t *o = &rto_opts;
|
||||||
|
|
||||||
memcpy(o, &rto_opts_defaults, sizeof (*o));
|
bcopy(&rto_opts_defaults, o, sizeof (*o));
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "TDBSvha:er:o:d:s:t:")) != -1) {
|
while ((opt = getopt(argc, argv, "TDBSvha:er:o:d:s:t:")) != -1) {
|
||||||
|
value = 0;
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'a':
|
case 'a':
|
||||||
value = strtoull(optarg, NULL, 0);
|
value = strtoull(optarg, NULL, 0);
|
||||||
@@ -264,8 +257,12 @@ cmp_data(raidz_test_opts_t *opts, raidz_map_t *rm)
|
|||||||
static int
|
static int
|
||||||
init_rand(void *data, size_t size, void *private)
|
init_rand(void *data, size_t size, void *private)
|
||||||
{
|
{
|
||||||
(void) private;
|
int i;
|
||||||
memcpy(data, rand_data, size);
|
int *dst = (int *)data;
|
||||||
|
|
||||||
|
for (i = 0; i < size / sizeof (int); i++)
|
||||||
|
dst[i] = rand_data[i];
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -837,7 +834,7 @@ static kcondvar_t sem_cv;
|
|||||||
static int max_free_slots;
|
static int max_free_slots;
|
||||||
static int free_slots;
|
static int free_slots;
|
||||||
|
|
||||||
static __attribute__((noreturn)) void
|
static void
|
||||||
sweep_thread(void *arg)
|
sweep_thread(void *arg)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
@@ -937,7 +934,7 @@ run_sweep(void)
|
|||||||
opts = umem_zalloc(sizeof (raidz_test_opts_t), UMEM_NOFAIL);
|
opts = umem_zalloc(sizeof (raidz_test_opts_t), UMEM_NOFAIL);
|
||||||
opts->rto_ashift = ashift_v[a];
|
opts->rto_ashift = ashift_v[a];
|
||||||
opts->rto_dcols = dcols_v[d];
|
opts->rto_dcols = dcols_v[d];
|
||||||
opts->rto_offset = (1ULL << ashift_v[a]) * rand();
|
opts->rto_offset = (1 << ashift_v[a]) * rand();
|
||||||
opts->rto_dsize = size_v[s];
|
opts->rto_dsize = size_v[s];
|
||||||
opts->rto_expand = rto_opts.rto_expand;
|
opts->rto_expand = rto_opts.rto_expand;
|
||||||
opts->rto_expand_offset = rto_opts.rto_expand_offset;
|
opts->rto_expand_offset = rto_opts.rto_expand_offset;
|
||||||
@@ -981,8 +978,8 @@ main(int argc, char **argv)
|
|||||||
struct sigaction action;
|
struct sigaction action;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
/* init gdb pid string early */
|
/* init gdb string early */
|
||||||
(void) sprintf(pid_s, "%d", getpid());
|
(void) sprintf(gdb, gdb_tmpl, getpid());
|
||||||
|
|
||||||
action.sa_handler = sig_handler;
|
action.sa_handler = sig_handler;
|
||||||
sigemptyset(&action.sa_mask);
|
sigemptyset(&action.sa_mask);
|
||||||
|
|||||||
+13
-15
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#include <sys/spa.h>
|
#include <sys/spa.h>
|
||||||
|
|
||||||
static const char *const raidz_impl_names[] = {
|
static const char *raidz_impl_names[] = {
|
||||||
"original",
|
"original",
|
||||||
"scalar",
|
"scalar",
|
||||||
"sse2",
|
"sse2",
|
||||||
@@ -42,18 +42,12 @@ static const char *const raidz_impl_names[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
enum raidz_verbosity {
|
|
||||||
D_ALL,
|
|
||||||
D_INFO,
|
|
||||||
D_DEBUG,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct raidz_test_opts {
|
typedef struct raidz_test_opts {
|
||||||
size_t rto_ashift;
|
size_t rto_ashift;
|
||||||
uint64_t rto_offset;
|
uint64_t rto_offset;
|
||||||
size_t rto_dcols;
|
size_t rto_dcols;
|
||||||
size_t rto_dsize;
|
size_t rto_dsize;
|
||||||
enum raidz_verbosity rto_v;
|
size_t rto_v;
|
||||||
size_t rto_sweep;
|
size_t rto_sweep;
|
||||||
size_t rto_sweep_timeout;
|
size_t rto_sweep_timeout;
|
||||||
size_t rto_benchmark;
|
size_t rto_benchmark;
|
||||||
@@ -74,7 +68,7 @@ static const raidz_test_opts_t rto_opts_defaults = {
|
|||||||
.rto_offset = 1ULL << 0,
|
.rto_offset = 1ULL << 0,
|
||||||
.rto_dcols = 8,
|
.rto_dcols = 8,
|
||||||
.rto_dsize = 1<<19,
|
.rto_dsize = 1<<19,
|
||||||
.rto_v = D_ALL,
|
.rto_v = 0,
|
||||||
.rto_sweep = 0,
|
.rto_sweep = 0,
|
||||||
.rto_benchmark = 0,
|
.rto_benchmark = 0,
|
||||||
.rto_expand = 0,
|
.rto_expand = 0,
|
||||||
@@ -92,19 +86,23 @@ static inline size_t ilog2(size_t a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define LOG(lvl, ...) \
|
#define D_ALL 0
|
||||||
|
#define D_INFO 1
|
||||||
|
#define D_DEBUG 2
|
||||||
|
|
||||||
|
#define LOG(lvl, a...) \
|
||||||
{ \
|
{ \
|
||||||
if (rto_opts.rto_v >= lvl) \
|
if (rto_opts.rto_v >= lvl) \
|
||||||
(void) fprintf(stdout, __VA_ARGS__); \
|
(void) fprintf(stdout, a); \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
#define LOG_OPT(lvl, opt, ...) \
|
#define LOG_OPT(lvl, opt, a...) \
|
||||||
{ \
|
{ \
|
||||||
if (opt->rto_v >= lvl) \
|
if (opt->rto_v >= lvl) \
|
||||||
(void) fprintf(stdout, __VA_ARGS__); \
|
(void) fprintf(stdout, a); \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
#define ERR(...) (void) fprintf(stderr, __VA_ARGS__)
|
#define ERR(a...) (void) fprintf(stderr, a)
|
||||||
|
|
||||||
|
|
||||||
#define DBLSEP "================\n"
|
#define DBLSEP "================\n"
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
include $(top_srcdir)/config/Shellcheck.am
|
||||||
|
|
||||||
|
dist_udev_SCRIPTS = vdev_id
|
||||||
@@ -140,8 +140,7 @@ Usage: vdev_id [-h]
|
|||||||
-p number of phy's per switch port [default=$PHYS_PER_PORT]
|
-p number of phy's per switch port [default=$PHYS_PER_PORT]
|
||||||
-h show this summary
|
-h show this summary
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 0
|
||||||
# exit with error to avoid processing usage message by a udev rule
|
|
||||||
}
|
}
|
||||||
|
|
||||||
map_slot() {
|
map_slot() {
|
||||||
@@ -375,7 +374,7 @@ sas_handler() {
|
|||||||
i=$((i + 1))
|
i=$((i + 1))
|
||||||
done
|
done
|
||||||
|
|
||||||
PHY=$(ls -vd "$port_dir"/phy* 2>/dev/null | head -1 | awk -F: '{print $NF}')
|
PHY=$(ls -d "$port_dir"/phy* 2>/dev/null | head -1 | awk -F: '{print $NF}')
|
||||||
if [ -z "$PHY" ] ; then
|
if [ -z "$PHY" ] ; then
|
||||||
PHY=0
|
PHY=0
|
||||||
fi
|
fi
|
||||||
@@ -596,9 +595,7 @@ enclosure_handler () {
|
|||||||
# DEVPATH=/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0/host0/subsystem/devices/0:0:0:0/scsi_generic/sg0
|
# DEVPATH=/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0/host0/subsystem/devices/0:0:0:0/scsi_generic/sg0
|
||||||
|
|
||||||
# Get the enclosure ID ("0:0:0:0")
|
# Get the enclosure ID ("0:0:0:0")
|
||||||
ENC="${DEVPATH%/*}"
|
ENC=$(basename $(readlink -m "/sys/$DEVPATH/../.."))
|
||||||
ENC="${ENC%/*}"
|
|
||||||
ENC="${ENC##*/}"
|
|
||||||
if [ ! -d "/sys/class/enclosure/$ENC" ] ; then
|
if [ ! -d "/sys/class/enclosure/$ENC" ] ; then
|
||||||
# Not an enclosure, bail out
|
# Not an enclosure, bail out
|
||||||
return
|
return
|
||||||
@@ -618,15 +615,14 @@ enclosure_handler () {
|
|||||||
|
|
||||||
# The PCI directory is two directories up from the port directory
|
# The PCI directory is two directories up from the port directory
|
||||||
# /sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0
|
# /sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0
|
||||||
PCI_ID_LONG="$(readlink -m "/sys/$PORT_DIR/../..")"
|
PCI_ID_LONG=$(basename $(readlink -m "/sys/$PORT_DIR/../.."))
|
||||||
PCI_ID_LONG="${PCI_ID_LONG##*/}"
|
|
||||||
|
|
||||||
# Strip down the PCI address from 0000:05:00.0 to 05:00.0
|
# Strip down the PCI address from 0000:05:00.0 to 05:00.0
|
||||||
PCI_ID="${PCI_ID_LONG#[0-9]*:}"
|
PCI_ID=$(echo "$PCI_ID_LONG" | sed -r 's/^[0-9]+://g')
|
||||||
|
|
||||||
# Name our device according to vdev_id.conf (like "L0" or "U1").
|
# Name our device according to vdev_id.conf (like "L0" or "U1").
|
||||||
NAME=$(awk "/channel/{if (\$1 == \"channel\" && \$2 == \"$PCI_ID\" && \
|
NAME=$(awk '/channel/{if ($1 == "channel" && $2 == "$PCI_ID" && \
|
||||||
\$3 == \"$PORT_ID\") {print \$4\$3}}" $CONFIG)
|
$3 == "$PORT_ID") {print ${4}int(count[$4])}; count[$4]++}' $CONFIG)
|
||||||
|
|
||||||
echo "${NAME}"
|
echo "${NAME}"
|
||||||
}
|
}
|
||||||
@@ -677,7 +673,7 @@ alias_handler () {
|
|||||||
link=$(echo "$link" | sed 's/p[0-9][0-9]*$//')
|
link=$(echo "$link" | sed 's/p[0-9][0-9]*$//')
|
||||||
fi
|
fi
|
||||||
# Check both the fully qualified and the base name of link.
|
# Check both the fully qualified and the base name of link.
|
||||||
for l in $link ${link##*/} ; do
|
for l in $link $(basename "$link") ; do
|
||||||
if [ ! -z "$l" ]; then
|
if [ ! -z "$l" ]; then
|
||||||
alias=$(awk -v var="$l" '($1 == "alias") && \
|
alias=$(awk -v var="$l" '($1 == "alias") && \
|
||||||
($3 == var) \
|
($3 == var) \
|
||||||
@@ -732,7 +728,7 @@ done
|
|||||||
|
|
||||||
if [ ! -r "$CONFIG" ] ; then
|
if [ ! -r "$CONFIG" ] ; then
|
||||||
echo "Error: Config file \"$CONFIG\" not found"
|
echo "Error: Config file \"$CONFIG\" not found"
|
||||||
exit 1
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$DEV" ] && [ -z "$ENCLOSURE_MODE" ] ; then
|
if [ -z "$DEV" ] && [ -z "$ENCLOSURE_MODE" ] ; then
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/zdb
|
||||||
+12
-11
@@ -1,17 +1,18 @@
|
|||||||
zdb_CPPFLAGS = $(AM_CPPFLAGS) $(FORCEDEBUG_CPPFLAGS)
|
include $(top_srcdir)/config/Rules.am
|
||||||
zdb_CFLAGS = $(AM_CFLAGS) $(LIBCRYPTO_CFLAGS)
|
|
||||||
|
|
||||||
sbin_PROGRAMS += zdb
|
# Unconditionally enable debugging for zdb
|
||||||
CPPCHECKTARGETS += zdb
|
AM_CPPFLAGS += -DDEBUG -UNDEBUG -DZFS_DEBUG
|
||||||
|
|
||||||
|
sbin_PROGRAMS = zdb
|
||||||
|
|
||||||
zdb_SOURCES = \
|
zdb_SOURCES = \
|
||||||
%D%/zdb.c \
|
zdb.c \
|
||||||
%D%/zdb.h \
|
zdb_il.c \
|
||||||
%D%/zdb_il.c
|
zdb.h
|
||||||
|
|
||||||
zdb_LDADD = \
|
zdb_LDADD = \
|
||||||
libzpool.la \
|
$(abs_top_builddir)/lib/libzpool/libzpool.la \
|
||||||
libzfs_core.la \
|
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||||
libnvpair.la
|
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
||||||
|
|
||||||
zdb_LDADD += $(LIBCRYPTO_LIBS)
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|||||||
+408
-1238
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
|
|||||||
+15
-124
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -60,10 +60,10 @@ print_log_bp(const blkptr_t *bp, const char *prefix)
|
|||||||
(void) printf("%s%s\n", prefix, blkbuf);
|
(void) printf("%s%s\n", prefix, blkbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_create(zilog_t *zilog, int txtype, const void *arg)
|
zil_prt_rec_create(zilog_t *zilog, int txtype, const void *arg)
|
||||||
{
|
{
|
||||||
(void) zilog;
|
|
||||||
const lr_create_t *lr = arg;
|
const lr_create_t *lr = arg;
|
||||||
time_t crtime = lr->lr_crtime[0];
|
time_t crtime = lr->lr_crtime[0];
|
||||||
char *name, *link;
|
char *name, *link;
|
||||||
@@ -96,20 +96,20 @@ zil_prt_rec_create(zilog_t *zilog, int txtype, const void *arg)
|
|||||||
(u_longlong_t)lr->lr_gen, (u_longlong_t)lr->lr_rdev);
|
(u_longlong_t)lr->lr_gen, (u_longlong_t)lr->lr_rdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_remove(zilog_t *zilog, int txtype, const void *arg)
|
zil_prt_rec_remove(zilog_t *zilog, int txtype, const void *arg)
|
||||||
{
|
{
|
||||||
(void) zilog, (void) txtype;
|
|
||||||
const lr_remove_t *lr = arg;
|
const lr_remove_t *lr = arg;
|
||||||
|
|
||||||
(void) printf("%sdoid %llu, name %s\n", tab_prefix,
|
(void) printf("%sdoid %llu, name %s\n", tab_prefix,
|
||||||
(u_longlong_t)lr->lr_doid, (char *)(lr + 1));
|
(u_longlong_t)lr->lr_doid, (char *)(lr + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_link(zilog_t *zilog, int txtype, const void *arg)
|
zil_prt_rec_link(zilog_t *zilog, int txtype, const void *arg)
|
||||||
{
|
{
|
||||||
(void) zilog, (void) txtype;
|
|
||||||
const lr_link_t *lr = arg;
|
const lr_link_t *lr = arg;
|
||||||
|
|
||||||
(void) printf("%sdoid %llu, link_obj %llu, name %s\n", tab_prefix,
|
(void) printf("%sdoid %llu, link_obj %llu, name %s\n", tab_prefix,
|
||||||
@@ -117,10 +117,10 @@ zil_prt_rec_link(zilog_t *zilog, int txtype, const void *arg)
|
|||||||
(char *)(lr + 1));
|
(char *)(lr + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_rename(zilog_t *zilog, int txtype, const void *arg)
|
zil_prt_rec_rename(zilog_t *zilog, int txtype, const void *arg)
|
||||||
{
|
{
|
||||||
(void) zilog, (void) txtype;
|
|
||||||
const lr_rename_t *lr = arg;
|
const lr_rename_t *lr = arg;
|
||||||
char *snm = (char *)(lr + 1);
|
char *snm = (char *)(lr + 1);
|
||||||
char *tnm = snm + strlen(snm) + 1;
|
char *tnm = snm + strlen(snm) + 1;
|
||||||
@@ -128,20 +128,12 @@ zil_prt_rec_rename(zilog_t *zilog, int txtype, const void *arg)
|
|||||||
(void) printf("%ssdoid %llu, tdoid %llu\n", tab_prefix,
|
(void) printf("%ssdoid %llu, tdoid %llu\n", tab_prefix,
|
||||||
(u_longlong_t)lr->lr_sdoid, (u_longlong_t)lr->lr_tdoid);
|
(u_longlong_t)lr->lr_sdoid, (u_longlong_t)lr->lr_tdoid);
|
||||||
(void) printf("%ssrc %s tgt %s\n", tab_prefix, snm, tnm);
|
(void) printf("%ssrc %s tgt %s\n", tab_prefix, snm, tnm);
|
||||||
switch (txtype) {
|
|
||||||
case TX_RENAME_EXCHANGE:
|
|
||||||
(void) printf("%sflags RENAME_EXCHANGE\n", tab_prefix);
|
|
||||||
break;
|
|
||||||
case TX_RENAME_WHITEOUT:
|
|
||||||
(void) printf("%sflags RENAME_WHITEOUT\n", tab_prefix);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
zil_prt_rec_write_cb(void *data, size_t len, void *unused)
|
zil_prt_rec_write_cb(void *data, size_t len, void *unused)
|
||||||
{
|
{
|
||||||
(void) unused;
|
|
||||||
char *cdata = data;
|
char *cdata = data;
|
||||||
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
@@ -154,6 +146,7 @@ zil_prt_rec_write_cb(void *data, size_t len, void *unused)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_write(zilog_t *zilog, int txtype, const void *arg)
|
zil_prt_rec_write(zilog_t *zilog, int txtype, const void *arg)
|
||||||
{
|
{
|
||||||
@@ -168,7 +161,7 @@ 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)) {
|
||||||
@@ -178,8 +171,6 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, const void *arg)
|
|||||||
"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));
|
||||||
@@ -192,7 +183,6 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, const void *arg)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT3U(BP_GET_LSIZE(bp), !=, 0);
|
|
||||||
SET_BOOKMARK(&zb, dmu_objset_id(zilog->zl_os),
|
SET_BOOKMARK(&zb, dmu_objset_id(zilog->zl_os),
|
||||||
lr->lr_foid, ZB_ZIL_LEVEL,
|
lr->lr_foid, ZB_ZIL_LEVEL,
|
||||||
lr->lr_offset / BP_GET_LSIZE(bp));
|
lr->lr_offset / BP_GET_LSIZE(bp));
|
||||||
@@ -204,9 +194,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,32 +209,10 @@ out:
|
|||||||
abd_free(data);
|
abd_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* ARGSUSED */
|
||||||
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->blk_birth >= 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)
|
||||||
{
|
{
|
||||||
(void) zilog, (void) txtype;
|
|
||||||
const lr_truncate_t *lr = arg;
|
const lr_truncate_t *lr = arg;
|
||||||
|
|
||||||
(void) printf("%sfoid %llu, offset 0x%llx, length 0x%llx\n", tab_prefix,
|
(void) printf("%sfoid %llu, offset 0x%llx, length 0x%llx\n", tab_prefix,
|
||||||
@@ -255,10 +220,10 @@ zil_prt_rec_truncate(zilog_t *zilog, int txtype, const void *arg)
|
|||||||
(u_longlong_t)lr->lr_length);
|
(u_longlong_t)lr->lr_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_setattr(zilog_t *zilog, int txtype, const void *arg)
|
zil_prt_rec_setattr(zilog_t *zilog, int txtype, const void *arg)
|
||||||
{
|
{
|
||||||
(void) zilog, (void) txtype;
|
|
||||||
const lr_setattr_t *lr = arg;
|
const lr_setattr_t *lr = arg;
|
||||||
time_t atime = (time_t)lr->lr_atime[0];
|
time_t atime = (time_t)lr->lr_atime[0];
|
||||||
time_t mtime = (time_t)lr->lr_mtime[0];
|
time_t mtime = (time_t)lr->lr_mtime[0];
|
||||||
@@ -301,83 +266,19 @@ zil_prt_rec_setattr(zilog_t *zilog, int txtype, const void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* ARGSUSED */
|
||||||
zil_prt_rec_setsaxattr(zilog_t *zilog, int txtype, const void *arg)
|
|
||||||
{
|
|
||||||
(void) zilog, (void) txtype;
|
|
||||||
const lr_setsaxattr_t *lr = arg;
|
|
||||||
|
|
||||||
char *name = (char *)(lr + 1);
|
|
||||||
(void) printf("%sfoid %llu\n", tab_prefix,
|
|
||||||
(u_longlong_t)lr->lr_foid);
|
|
||||||
|
|
||||||
(void) printf("%sXAT_NAME %s\n", tab_prefix, name);
|
|
||||||
if (lr->lr_size == 0) {
|
|
||||||
(void) printf("%sXAT_VALUE NULL\n", tab_prefix);
|
|
||||||
} else {
|
|
||||||
(void) printf("%sXAT_VALUE ", tab_prefix);
|
|
||||||
char *val = name + (strlen(name) + 1);
|
|
||||||
for (int i = 0; i < lr->lr_size; i++) {
|
|
||||||
(void) printf("%c", *val);
|
|
||||||
val++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_acl(zilog_t *zilog, int txtype, const void *arg)
|
zil_prt_rec_acl(zilog_t *zilog, int txtype, const void *arg)
|
||||||
{
|
{
|
||||||
(void) zilog, (void) txtype;
|
|
||||||
const lr_acl_t *lr = arg;
|
const lr_acl_t *lr = arg;
|
||||||
|
|
||||||
(void) printf("%sfoid %llu, aclcnt %llu\n", tab_prefix,
|
(void) printf("%sfoid %llu, aclcnt %llu\n", tab_prefix,
|
||||||
(u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_aclcnt);
|
(u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_aclcnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
zil_prt_rec_clone_range(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("%sfoid %llu, offset %llx, length %llx, blksize %llx\n",
|
|
||||||
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);
|
|
||||||
|
|
||||||
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++) {
|
|
||||||
(void) printf("%s[%u/%llu] ", tab_prefix, i + 1,
|
|
||||||
(u_longlong_t)lr->lr_nbps);
|
|
||||||
print_log_bp(&lr->lr_bps[i], "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 +293,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 "},
|
||||||
@@ -406,19 +305,12 @@ static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = {
|
|||||||
{.zri_print = zil_prt_rec_create, .zri_name = "TX_MKDIR_ATTR "},
|
{.zri_print = zil_prt_rec_create, .zri_name = "TX_MKDIR_ATTR "},
|
||||||
{.zri_print = zil_prt_rec_create, .zri_name = "TX_MKDIR_ACL_ATTR "},
|
{.zri_print = zil_prt_rec_create, .zri_name = "TX_MKDIR_ACL_ATTR "},
|
||||||
{.zri_print = zil_prt_rec_write, .zri_name = "TX_WRITE2 "},
|
{.zri_print = zil_prt_rec_write, .zri_name = "TX_WRITE2 "},
|
||||||
{.zri_print = zil_prt_rec_setsaxattr,
|
|
||||||
.zri_name = "TX_SETSAXATTR "},
|
|
||||||
{.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_clone_range,
|
|
||||||
.zri_print_enc = zil_prt_rec_clone_range_enc,
|
|
||||||
.zri_name = "TX_CLONE_RANGE "},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
print_log_record(zilog_t *zilog, const lr_t *lr, void *arg, uint64_t claim_txg)
|
print_log_record(zilog_t *zilog, const lr_t *lr, void *arg, uint64_t claim_txg)
|
||||||
{
|
{
|
||||||
(void) arg, (void) claim_txg;
|
|
||||||
int txtype;
|
int txtype;
|
||||||
int verbose = MAX(dump_opt['d'], dump_opt['i']);
|
int verbose = MAX(dump_opt['d'], dump_opt['i']);
|
||||||
|
|
||||||
@@ -438,8 +330,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);
|
||||||
}
|
}
|
||||||
@@ -451,11 +341,11 @@ print_log_record(zilog_t *zilog, const lr_t *lr, void *arg, uint64_t claim_txg)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
print_log_block(zilog_t *zilog, const blkptr_t *bp, void *arg,
|
print_log_block(zilog_t *zilog, const blkptr_t *bp, void *arg,
|
||||||
uint64_t claim_txg)
|
uint64_t claim_txg)
|
||||||
{
|
{
|
||||||
(void) arg;
|
|
||||||
char blkbuf[BP_SPRINTF_LEN + 10];
|
char blkbuf[BP_SPRINTF_LEN + 10];
|
||||||
int verbose = MAX(dump_opt['d'], dump_opt['i']);
|
int verbose = MAX(dump_opt['d'], dump_opt['i']);
|
||||||
const char *claim;
|
const char *claim;
|
||||||
@@ -506,6 +396,7 @@ print_log_stats(int verbose)
|
|||||||
(void) printf("\n");
|
(void) printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
void
|
void
|
||||||
dump_intent_log(zilog_t *zilog)
|
dump_intent_log(zilog_t *zilog)
|
||||||
{
|
{
|
||||||
|
|||||||
+44
-37
@@ -1,46 +1,53 @@
|
|||||||
include $(srcdir)/%D%/zed.d/Makefile.am
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
include $(top_srcdir)/config/Shellcheck.am
|
||||||
|
|
||||||
zed_CFLAGS = $(AM_CFLAGS)
|
AM_CFLAGS += $(LIBUDEV_CFLAGS) $(LIBUUID_CFLAGS)
|
||||||
zed_CFLAGS += $(LIBUDEV_CFLAGS) $(LIBUUID_CFLAGS)
|
|
||||||
|
|
||||||
sbin_PROGRAMS += zed
|
SUBDIRS = zed.d
|
||||||
CPPCHECKTARGETS += zed
|
SHELLCHECKDIRS = $(SUBDIRS)
|
||||||
|
|
||||||
zed_SOURCES = \
|
sbin_PROGRAMS = zed
|
||||||
%D%/zed.c \
|
|
||||||
%D%/zed.h \
|
ZED_SRC = \
|
||||||
%D%/zed_conf.c \
|
zed.c \
|
||||||
%D%/zed_conf.h \
|
zed.h \
|
||||||
%D%/zed_disk_event.c \
|
zed_conf.c \
|
||||||
%D%/zed_disk_event.h \
|
zed_conf.h \
|
||||||
%D%/zed_event.c \
|
zed_disk_event.c \
|
||||||
%D%/zed_event.h \
|
zed_disk_event.h \
|
||||||
%D%/zed_exec.c \
|
zed_event.c \
|
||||||
%D%/zed_exec.h \
|
zed_event.h \
|
||||||
%D%/zed_file.c \
|
zed_exec.c \
|
||||||
%D%/zed_file.h \
|
zed_exec.h \
|
||||||
%D%/zed_log.c \
|
zed_file.c \
|
||||||
%D%/zed_log.h \
|
zed_file.h \
|
||||||
%D%/zed_strings.c \
|
zed_log.c \
|
||||||
%D%/zed_strings.h \
|
zed_log.h \
|
||||||
\
|
zed_strings.c \
|
||||||
%D%/agents/fmd_api.c \
|
zed_strings.h
|
||||||
%D%/agents/fmd_api.h \
|
|
||||||
%D%/agents/fmd_serd.c \
|
FMA_SRC = \
|
||||||
%D%/agents/fmd_serd.h \
|
agents/zfs_agents.c \
|
||||||
%D%/agents/zfs_agents.c \
|
agents/zfs_agents.h \
|
||||||
%D%/agents/zfs_agents.h \
|
agents/zfs_diagnosis.c \
|
||||||
%D%/agents/zfs_diagnosis.c \
|
agents/zfs_mod.c \
|
||||||
%D%/agents/zfs_mod.c \
|
agents/zfs_retire.c \
|
||||||
%D%/agents/zfs_retire.c
|
agents/fmd_api.c \
|
||||||
|
agents/fmd_api.h \
|
||||||
|
agents/fmd_serd.c \
|
||||||
|
agents/fmd_serd.h
|
||||||
|
|
||||||
|
zed_SOURCES = $(ZED_SRC) $(FMA_SRC)
|
||||||
|
|
||||||
zed_LDADD = \
|
zed_LDADD = \
|
||||||
libzfs.la \
|
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
||||||
libzfs_core.la \
|
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||||
libnvpair.la \
|
$(abs_top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
libuutil.la
|
$(abs_top_builddir)/lib/libuutil/libuutil.la
|
||||||
|
|
||||||
zed_LDADD += -lrt $(LIBATOMIC_LIBS) $(LIBUDEV_LIBS) $(LIBUUID_LIBS)
|
zed_LDADD += -lrt $(LIBATOMIC_LIBS) $(LIBUDEV_LIBS) $(LIBUUID_LIBS)
|
||||||
zed_LDFLAGS = -pthread
|
zed_LDFLAGS = -pthread
|
||||||
|
|
||||||
dist_noinst_DATA += %D%/agents/README.md
|
EXTRA_DIST = agents/README.md
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|||||||
+45
-61
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -39,7 +38,7 @@
|
|||||||
#include <sys/fm/protocol.h>
|
#include <sys/fm/protocol.h>
|
||||||
#include <uuid/uuid.h>
|
#include <uuid/uuid.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <string.h>
|
#include <strings.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "fmd_api.h"
|
#include "fmd_api.h"
|
||||||
@@ -98,7 +97,6 @@ _umem_logging_init(void)
|
|||||||
int
|
int
|
||||||
fmd_hdl_register(fmd_hdl_t *hdl, int version, const fmd_hdl_info_t *mip)
|
fmd_hdl_register(fmd_hdl_t *hdl, int version, const fmd_hdl_info_t *mip)
|
||||||
{
|
{
|
||||||
(void) version;
|
|
||||||
fmd_module_t *mp = (fmd_module_t *)hdl;
|
fmd_module_t *mp = (fmd_module_t *)hdl;
|
||||||
|
|
||||||
mp->mod_info = mip;
|
mp->mod_info = mip;
|
||||||
@@ -181,21 +179,18 @@ fmd_hdl_getspecific(fmd_hdl_t *hdl)
|
|||||||
void *
|
void *
|
||||||
fmd_hdl_alloc(fmd_hdl_t *hdl, size_t size, int flags)
|
fmd_hdl_alloc(fmd_hdl_t *hdl, size_t size, int flags)
|
||||||
{
|
{
|
||||||
(void) hdl;
|
|
||||||
return (umem_alloc(size, flags));
|
return (umem_alloc(size, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
fmd_hdl_zalloc(fmd_hdl_t *hdl, size_t size, int flags)
|
fmd_hdl_zalloc(fmd_hdl_t *hdl, size_t size, int flags)
|
||||||
{
|
{
|
||||||
(void) hdl;
|
|
||||||
return (umem_zalloc(size, flags));
|
return (umem_zalloc(size, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fmd_hdl_free(fmd_hdl_t *hdl, void *data, size_t size)
|
fmd_hdl_free(fmd_hdl_t *hdl, void *data, size_t size)
|
||||||
{
|
{
|
||||||
(void) hdl;
|
|
||||||
umem_free(data, size);
|
umem_free(data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,8 +217,6 @@ fmd_hdl_debug(fmd_hdl_t *hdl, const char *format, ...)
|
|||||||
int32_t
|
int32_t
|
||||||
fmd_prop_get_int32(fmd_hdl_t *hdl, const char *name)
|
fmd_prop_get_int32(fmd_hdl_t *hdl, const char *name)
|
||||||
{
|
{
|
||||||
(void) hdl;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These can be looked up in mp->modinfo->fmdi_props
|
* These can be looked up in mp->modinfo->fmdi_props
|
||||||
* For now we just hard code for phase 2. In the
|
* For now we just hard code for phase 2. In the
|
||||||
@@ -232,6 +225,26 @@ 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)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,24 +334,22 @@ fmd_case_uuresolved(fmd_hdl_t *hdl, const char *uuid)
|
|||||||
fmd_hdl_debug(hdl, "case resolved by uuid (%s)", uuid);
|
fmd_hdl_debug(hdl, "case resolved by uuid (%s)", uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean_t
|
int
|
||||||
fmd_case_solved(fmd_hdl_t *hdl, fmd_case_t *cp)
|
fmd_case_solved(fmd_hdl_t *hdl, fmd_case_t *cp)
|
||||||
{
|
{
|
||||||
(void) hdl;
|
return ((cp->ci_state >= FMD_CASE_SOLVED) ? FMD_B_TRUE : FMD_B_FALSE);
|
||||||
return (cp->ci_state >= FMD_CASE_SOLVED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fmd_case_add_ereport(fmd_hdl_t *hdl, fmd_case_t *cp, fmd_event_t *ep)
|
fmd_case_add_ereport(fmd_hdl_t *hdl, fmd_case_t *cp, fmd_event_t *ep)
|
||||||
{
|
{
|
||||||
(void) hdl, (void) cp, (void) ep;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zed_log_fault(nvlist_t *nvl, const char *uuid, const char *code)
|
zed_log_fault(nvlist_t *nvl, const char *uuid, const char *code)
|
||||||
{
|
{
|
||||||
nvlist_t *rsrc;
|
nvlist_t *rsrc;
|
||||||
const char *strval;
|
char *strval;
|
||||||
uint64_t guid;
|
uint64_t guid;
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
|
|
||||||
@@ -351,7 +362,7 @@ zed_log_fault(nvlist_t *nvl, const char *uuid, const char *code)
|
|||||||
if (code != NULL)
|
if (code != NULL)
|
||||||
zed_log_msg(LOG_INFO, "\t%s: %s", FM_SUSPECT_DIAG_CODE, code);
|
zed_log_msg(LOG_INFO, "\t%s: %s", FM_SUSPECT_DIAG_CODE, code);
|
||||||
if (nvlist_lookup_uint8(nvl, FM_FAULT_CERTAINTY, &byte) == 0)
|
if (nvlist_lookup_uint8(nvl, FM_FAULT_CERTAINTY, &byte) == 0)
|
||||||
zed_log_msg(LOG_INFO, "\t%s: %hhu", FM_FAULT_CERTAINTY, byte);
|
zed_log_msg(LOG_INFO, "\t%s: %llu", FM_FAULT_CERTAINTY, byte);
|
||||||
if (nvlist_lookup_nvlist(nvl, FM_FAULT_RESOURCE, &rsrc) == 0) {
|
if (nvlist_lookup_nvlist(nvl, FM_FAULT_RESOURCE, &rsrc) == 0) {
|
||||||
if (nvlist_lookup_string(rsrc, FM_FMRI_SCHEME, &strval) == 0)
|
if (nvlist_lookup_string(rsrc, FM_FMRI_SCHEME, &strval) == 0)
|
||||||
zed_log_msg(LOG_INFO, "\t%s: %s", FM_FMRI_SCHEME,
|
zed_log_msg(LOG_INFO, "\t%s: %s", FM_FMRI_SCHEME,
|
||||||
@@ -368,8 +379,7 @@ zed_log_fault(nvlist_t *nvl, const char *uuid, const char *code)
|
|||||||
static const char *
|
static const char *
|
||||||
fmd_fault_mkcode(nvlist_t *fault)
|
fmd_fault_mkcode(nvlist_t *fault)
|
||||||
{
|
{
|
||||||
const char *class;
|
char *class, *code = "-";
|
||||||
const char *code = "-";
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: message codes come from: openzfs/usr/src/cmd/fm/dicts/ZFS.po
|
* Note: message codes come from: openzfs/usr/src/cmd/fm/dicts/ZFS.po
|
||||||
@@ -418,8 +428,7 @@ fmd_case_add_suspect(fmd_hdl_t *hdl, fmd_case_t *cp, nvlist_t *fault)
|
|||||||
err |= nvlist_add_string(nvl, FM_SUSPECT_DIAG_CODE, code);
|
err |= nvlist_add_string(nvl, FM_SUSPECT_DIAG_CODE, code);
|
||||||
err |= nvlist_add_int64_array(nvl, FM_SUSPECT_DIAG_TIME, tod, 2);
|
err |= nvlist_add_int64_array(nvl, FM_SUSPECT_DIAG_TIME, tod, 2);
|
||||||
err |= nvlist_add_uint32(nvl, FM_SUSPECT_FAULT_SZ, 1);
|
err |= nvlist_add_uint32(nvl, FM_SUSPECT_FAULT_SZ, 1);
|
||||||
err |= nvlist_add_nvlist_array(nvl, FM_SUSPECT_FAULT_LIST,
|
err |= nvlist_add_nvlist_array(nvl, FM_SUSPECT_FAULT_LIST, &fault, 1);
|
||||||
(const nvlist_t **)&fault, 1);
|
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
zed_log_die("failed to populate nvlist");
|
zed_log_die("failed to populate nvlist");
|
||||||
@@ -434,21 +443,19 @@ fmd_case_add_suspect(fmd_hdl_t *hdl, fmd_case_t *cp, nvlist_t *fault)
|
|||||||
void
|
void
|
||||||
fmd_case_setspecific(fmd_hdl_t *hdl, fmd_case_t *cp, void *data)
|
fmd_case_setspecific(fmd_hdl_t *hdl, fmd_case_t *cp, void *data)
|
||||||
{
|
{
|
||||||
(void) hdl;
|
|
||||||
cp->ci_data = data;
|
cp->ci_data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
fmd_case_getspecific(fmd_hdl_t *hdl, fmd_case_t *cp)
|
fmd_case_getspecific(fmd_hdl_t *hdl, fmd_case_t *cp)
|
||||||
{
|
{
|
||||||
(void) hdl;
|
|
||||||
return (cp->ci_data);
|
return (cp->ci_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fmd_buf_create(fmd_hdl_t *hdl, fmd_case_t *cp, const char *name, size_t size)
|
fmd_buf_create(fmd_hdl_t *hdl, fmd_case_t *cp, const char *name, size_t size)
|
||||||
{
|
{
|
||||||
assert(strcmp(name, "data") == 0), (void) name;
|
assert(strcmp(name, "data") == 0);
|
||||||
assert(cp->ci_bufptr == NULL);
|
assert(cp->ci_bufptr == NULL);
|
||||||
assert(size < (1024 * 1024));
|
assert(size < (1024 * 1024));
|
||||||
|
|
||||||
@@ -460,24 +467,22 @@ void
|
|||||||
fmd_buf_read(fmd_hdl_t *hdl, fmd_case_t *cp,
|
fmd_buf_read(fmd_hdl_t *hdl, fmd_case_t *cp,
|
||||||
const char *name, void *buf, size_t size)
|
const char *name, void *buf, size_t size)
|
||||||
{
|
{
|
||||||
(void) hdl;
|
assert(strcmp(name, "data") == 0);
|
||||||
assert(strcmp(name, "data") == 0), (void) name;
|
|
||||||
assert(cp->ci_bufptr != NULL);
|
assert(cp->ci_bufptr != NULL);
|
||||||
assert(size <= cp->ci_bufsiz);
|
assert(size <= cp->ci_bufsiz);
|
||||||
|
|
||||||
memcpy(buf, cp->ci_bufptr, size);
|
bcopy(cp->ci_bufptr, buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fmd_buf_write(fmd_hdl_t *hdl, fmd_case_t *cp,
|
fmd_buf_write(fmd_hdl_t *hdl, fmd_case_t *cp,
|
||||||
const char *name, const void *buf, size_t size)
|
const char *name, const void *buf, size_t size)
|
||||||
{
|
{
|
||||||
(void) hdl;
|
assert(strcmp(name, "data") == 0);
|
||||||
assert(strcmp(name, "data") == 0), (void) name;
|
|
||||||
assert(cp->ci_bufptr != NULL);
|
assert(cp->ci_bufptr != NULL);
|
||||||
assert(cp->ci_bufsiz >= size);
|
assert(cp->ci_bufsiz >= size);
|
||||||
|
|
||||||
memcpy(cp->ci_bufptr, buf, size);
|
bcopy(buf, cp->ci_bufptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SERD Engines */
|
/* SERD Engines */
|
||||||
@@ -514,19 +519,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 +527,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 +540,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 (FMD_B_FALSE);
|
||||||
}
|
}
|
||||||
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,10 +563,10 @@ _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));
|
bzero(&its, sizeof (struct itimerspec));
|
||||||
timer_settime(ftp->ft_tid, 0, &its, NULL);
|
timer_settime(ftp->ft_tid, 0, &its, NULL);
|
||||||
|
|
||||||
/* Note that the fmdo_timeout can remove this timer */
|
/* Note that the fmdo_timeout can remove this timer */
|
||||||
@@ -593,7 +582,6 @@ _timer_notify(union sigval sv)
|
|||||||
fmd_timer_t *
|
fmd_timer_t *
|
||||||
fmd_timer_install(fmd_hdl_t *hdl, void *arg, fmd_event_t *ep, hrtime_t delta)
|
fmd_timer_install(fmd_hdl_t *hdl, void *arg, fmd_event_t *ep, hrtime_t delta)
|
||||||
{
|
{
|
||||||
(void) ep;
|
|
||||||
struct sigevent sev;
|
struct sigevent sev;
|
||||||
struct itimerspec its;
|
struct itimerspec its;
|
||||||
fmd_timer_t *ftp;
|
fmd_timer_t *ftp;
|
||||||
@@ -611,7 +599,6 @@ fmd_timer_install(fmd_hdl_t *hdl, void *arg, fmd_event_t *ep, hrtime_t delta)
|
|||||||
sev.sigev_notify_function = _timer_notify;
|
sev.sigev_notify_function = _timer_notify;
|
||||||
sev.sigev_notify_attributes = NULL;
|
sev.sigev_notify_attributes = NULL;
|
||||||
sev.sigev_value.sival_ptr = ftp;
|
sev.sigev_value.sival_ptr = ftp;
|
||||||
sev.sigev_signo = 0;
|
|
||||||
|
|
||||||
timer_create(CLOCK_REALTIME, &sev, &ftp->ft_tid);
|
timer_create(CLOCK_REALTIME, &sev, &ftp->ft_tid);
|
||||||
timer_settime(ftp->ft_tid, 0, &its, NULL);
|
timer_settime(ftp->ft_tid, 0, &its, NULL);
|
||||||
@@ -638,7 +625,6 @@ nvlist_t *
|
|||||||
fmd_nvl_create_fault(fmd_hdl_t *hdl, const char *class, uint8_t certainty,
|
fmd_nvl_create_fault(fmd_hdl_t *hdl, const char *class, uint8_t certainty,
|
||||||
nvlist_t *asru, nvlist_t *fru, nvlist_t *resource)
|
nvlist_t *asru, nvlist_t *fru, nvlist_t *resource)
|
||||||
{
|
{
|
||||||
(void) hdl;
|
|
||||||
nvlist_t *nvl;
|
nvlist_t *nvl;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
@@ -702,8 +688,7 @@ fmd_strmatch(const char *s, const char *p)
|
|||||||
int
|
int
|
||||||
fmd_nvl_class_match(fmd_hdl_t *hdl, nvlist_t *nvl, const char *pattern)
|
fmd_nvl_class_match(fmd_hdl_t *hdl, nvlist_t *nvl, const char *pattern)
|
||||||
{
|
{
|
||||||
(void) hdl;
|
char *class;
|
||||||
const char *class;
|
|
||||||
|
|
||||||
return (nvl != NULL &&
|
return (nvl != NULL &&
|
||||||
nvlist_lookup_string(nvl, FM_CLASS, &class) == 0 &&
|
nvlist_lookup_string(nvl, FM_CLASS, &class) == 0 &&
|
||||||
@@ -713,7 +698,6 @@ fmd_nvl_class_match(fmd_hdl_t *hdl, nvlist_t *nvl, const char *pattern)
|
|||||||
nvlist_t *
|
nvlist_t *
|
||||||
fmd_nvl_alloc(fmd_hdl_t *hdl, int flags)
|
fmd_nvl_alloc(fmd_hdl_t *hdl, int flags)
|
||||||
{
|
{
|
||||||
(void) hdl, (void) flags;
|
|
||||||
nvlist_t *nvl = NULL;
|
nvlist_t *nvl = NULL;
|
||||||
|
|
||||||
if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
|
if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -72,6 +72,10 @@ typedef struct fmd_case {
|
|||||||
} fmd_case_t;
|
} fmd_case_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define FMD_B_FALSE 0 /* false value for booleans as int */
|
||||||
|
#define FMD_B_TRUE 1 /* true value for booleans as int */
|
||||||
|
|
||||||
|
|
||||||
#define FMD_CASE_UNSOLVED 0 /* case is not yet solved (waiting) */
|
#define FMD_CASE_UNSOLVED 0 /* case is not yet solved (waiting) */
|
||||||
#define FMD_CASE_SOLVED 1 /* case is solved (suspects added) */
|
#define FMD_CASE_SOLVED 1 /* case is solved (suspects added) */
|
||||||
#define FMD_CASE_CLOSE_WAIT 2 /* case is executing fmdo_close() */
|
#define FMD_CASE_CLOSE_WAIT 2 /* case is executing fmdo_close() */
|
||||||
@@ -151,6 +155,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 */
|
||||||
@@ -171,7 +176,8 @@ extern int fmd_case_uuclosed(fmd_hdl_t *, const char *);
|
|||||||
extern int fmd_case_uuisresolved(fmd_hdl_t *, const char *);
|
extern int fmd_case_uuisresolved(fmd_hdl_t *, const char *);
|
||||||
extern void fmd_case_uuresolved(fmd_hdl_t *, const char *);
|
extern void fmd_case_uuresolved(fmd_hdl_t *, const char *);
|
||||||
|
|
||||||
extern boolean_t fmd_case_solved(fmd_hdl_t *, fmd_case_t *);
|
extern int fmd_case_solved(fmd_hdl_t *, fmd_case_t *);
|
||||||
|
extern int fmd_case_closed(fmd_hdl_t *, fmd_case_t *);
|
||||||
|
|
||||||
extern void fmd_case_add_ereport(fmd_hdl_t *, fmd_case_t *, fmd_event_t *);
|
extern void fmd_case_add_ereport(fmd_hdl_t *, fmd_case_t *, fmd_event_t *);
|
||||||
extern void fmd_case_add_serd(fmd_hdl_t *, fmd_case_t *, const char *);
|
extern void fmd_case_add_serd(fmd_hdl_t *, fmd_case_t *, const char *);
|
||||||
@@ -194,12 +200,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);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* with the License.
|
* with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <strings.h>
|
||||||
#include <sys/list.h>
|
#include <sys/list.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
@@ -74,18 +74,9 @@ fmd_serd_eng_alloc(const char *name, uint64_t n, hrtime_t t)
|
|||||||
fmd_serd_eng_t *sgp;
|
fmd_serd_eng_t *sgp;
|
||||||
|
|
||||||
sgp = malloc(sizeof (fmd_serd_eng_t));
|
sgp = malloc(sizeof (fmd_serd_eng_t));
|
||||||
if (sgp == NULL) {
|
bzero(sgp, sizeof (fmd_serd_eng_t));
|
||||||
perror("malloc");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
memset(sgp, 0, sizeof (fmd_serd_eng_t));
|
|
||||||
|
|
||||||
sgp->sg_name = strdup(name);
|
sgp->sg_name = strdup(name);
|
||||||
if (sgp->sg_name == NULL) {
|
|
||||||
perror("strdup");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
sgp->sg_flags = FMD_SERD_DIRTY;
|
sgp->sg_flags = FMD_SERD_DIRTY;
|
||||||
sgp->sg_n = n;
|
sgp->sg_n = n;
|
||||||
sgp->sg_t = t;
|
sgp->sg_t = t;
|
||||||
@@ -132,12 +123,6 @@ fmd_serd_hash_create(fmd_serd_hash_t *shp)
|
|||||||
shp->sh_hashlen = FMD_STR_BUCKETS;
|
shp->sh_hashlen = FMD_STR_BUCKETS;
|
||||||
shp->sh_hash = calloc(shp->sh_hashlen, sizeof (void *));
|
shp->sh_hash = calloc(shp->sh_hashlen, sizeof (void *));
|
||||||
shp->sh_count = 0;
|
shp->sh_count = 0;
|
||||||
|
|
||||||
if (shp->sh_hash == NULL) {
|
|
||||||
perror("calloc");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -154,7 +139,7 @@ fmd_serd_hash_destroy(fmd_serd_hash_t *shp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(shp->sh_hash);
|
free(shp->sh_hash);
|
||||||
memset(shp, 0, sizeof (fmd_serd_hash_t));
|
bzero(shp, sizeof (fmd_serd_hash_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -249,17 +234,13 @@ fmd_serd_eng_record(fmd_serd_eng_t *sgp, hrtime_t hrt)
|
|||||||
if (sgp->sg_flags & FMD_SERD_FIRED) {
|
if (sgp->sg_flags & FMD_SERD_FIRED) {
|
||||||
serd_log_msg(" SERD Engine: record %s already fired!",
|
serd_log_msg(" SERD Engine: record %s already fired!",
|
||||||
sgp->sg_name);
|
sgp->sg_name);
|
||||||
return (B_FALSE);
|
return (FMD_B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (sgp->sg_count >= sgp->sg_n)
|
while (sgp->sg_count >= sgp->sg_n)
|
||||||
fmd_serd_eng_discard(sgp, list_tail(&sgp->sg_list));
|
fmd_serd_eng_discard(sgp, list_tail(&sgp->sg_list));
|
||||||
|
|
||||||
sep = malloc(sizeof (fmd_serd_elem_t));
|
sep = malloc(sizeof (fmd_serd_elem_t));
|
||||||
if (sep == NULL) {
|
|
||||||
perror("malloc");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
sep->se_hrt = hrt;
|
sep->se_hrt = hrt;
|
||||||
|
|
||||||
list_insert_head(&sgp->sg_list, sep);
|
list_insert_head(&sgp->sg_list, sep);
|
||||||
@@ -278,11 +259,11 @@ fmd_serd_eng_record(fmd_serd_eng_t *sgp, hrtime_t hrt)
|
|||||||
fmd_event_delta(oep->se_hrt, sep->se_hrt) <= sgp->sg_t) {
|
fmd_event_delta(oep->se_hrt, sep->se_hrt) <= sgp->sg_t) {
|
||||||
sgp->sg_flags |= FMD_SERD_FIRED | FMD_SERD_DIRTY;
|
sgp->sg_flags |= FMD_SERD_FIRED | FMD_SERD_DIRTY;
|
||||||
serd_log_msg(" SERD Engine: fired %s", sgp->sg_name);
|
serd_log_msg(" SERD Engine: fired %s", sgp->sg_name);
|
||||||
return (B_TRUE);
|
return (FMD_B_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
sgp->sg_flags |= FMD_SERD_DIRTY;
|
sgp->sg_flags |= FMD_SERD_DIRTY;
|
||||||
return (B_FALSE);
|
return (FMD_B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -310,9 +291,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;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* with the License.
|
* with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-46
@@ -64,7 +64,7 @@ typedef enum device_type {
|
|||||||
typedef struct guid_search {
|
typedef struct guid_search {
|
||||||
uint64_t gs_pool_guid;
|
uint64_t gs_pool_guid;
|
||||||
uint64_t gs_vdev_guid;
|
uint64_t gs_vdev_guid;
|
||||||
const char *gs_devid;
|
char *gs_devid;
|
||||||
device_type_t gs_vdev_type;
|
device_type_t gs_vdev_type;
|
||||||
uint64_t gs_vdev_expandtime; /* vdev expansion time */
|
uint64_t gs_vdev_expandtime; /* vdev expansion time */
|
||||||
} guid_search_t;
|
} guid_search_t;
|
||||||
@@ -77,10 +77,9 @@ static boolean_t
|
|||||||
zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
||||||
{
|
{
|
||||||
guid_search_t *gsp = arg;
|
guid_search_t *gsp = arg;
|
||||||
const char *path = NULL;
|
char *path = NULL;
|
||||||
uint_t c, children;
|
uint_t c, children;
|
||||||
nvlist_t **child;
|
nvlist_t **child;
|
||||||
uint64_t vdev_guid;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First iterate over any children.
|
* First iterate over any children.
|
||||||
@@ -101,7 +100,7 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
|||||||
&child, &children) == 0) {
|
&child, &children) == 0) {
|
||||||
for (c = 0; c < children; c++) {
|
for (c = 0; c < children; c++) {
|
||||||
if (zfs_agent_iter_vdev(zhp, child[c], gsp)) {
|
if (zfs_agent_iter_vdev(zhp, child[c], gsp)) {
|
||||||
gsp->gs_vdev_type = DEVICE_TYPE_SPARE;
|
gsp->gs_vdev_type = DEVICE_TYPE_L2ARC;
|
||||||
return (B_TRUE);
|
return (B_TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,7 +109,7 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
|||||||
&child, &children) == 0) {
|
&child, &children) == 0) {
|
||||||
for (c = 0; c < children; c++) {
|
for (c = 0; c < children; c++) {
|
||||||
if (zfs_agent_iter_vdev(zhp, child[c], gsp)) {
|
if (zfs_agent_iter_vdev(zhp, child[c], gsp)) {
|
||||||
gsp->gs_vdev_type = DEVICE_TYPE_L2ARC;
|
gsp->gs_vdev_type = DEVICE_TYPE_SPARE;
|
||||||
return (B_TRUE);
|
return (B_TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,21 +126,6 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
|||||||
&gsp->gs_vdev_expandtime);
|
&gsp->gs_vdev_expandtime);
|
||||||
return (B_TRUE);
|
return (B_TRUE);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* Otherwise, on a vdev guid match, grab the devid and expansion
|
|
||||||
* time. The devid might be missing on removal since its not part
|
|
||||||
* of blkid cache and L2ARC VDEV does not contain pool guid in its
|
|
||||||
* blkid, so this is a special case for L2ARC VDEV.
|
|
||||||
*/
|
|
||||||
else if (gsp->gs_vdev_guid != 0 && gsp->gs_devid == NULL &&
|
|
||||||
nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, &vdev_guid) == 0 &&
|
|
||||||
gsp->gs_vdev_guid == vdev_guid) {
|
|
||||||
(void) nvlist_lookup_string(nvl, ZPOOL_CONFIG_DEVID,
|
|
||||||
&gsp->gs_devid);
|
|
||||||
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_EXPANSION_TIME,
|
|
||||||
&gsp->gs_vdev_expandtime);
|
|
||||||
return (B_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (B_FALSE);
|
return (B_FALSE);
|
||||||
}
|
}
|
||||||
@@ -164,13 +148,13 @@ zfs_agent_iter_pool(zpool_handle_t *zhp, void *arg)
|
|||||||
/*
|
/*
|
||||||
* if a match was found then grab the pool guid
|
* if a match was found then grab the pool guid
|
||||||
*/
|
*/
|
||||||
if (gsp->gs_vdev_guid && gsp->gs_devid) {
|
if (gsp->gs_vdev_guid) {
|
||||||
(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
||||||
&gsp->gs_pool_guid);
|
&gsp->gs_pool_guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
return (gsp->gs_devid != NULL && gsp->gs_vdev_guid != 0);
|
return (gsp->gs_vdev_guid != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -211,13 +195,11 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||||||
uint64_t pool_guid = 0, vdev_guid = 0;
|
uint64_t pool_guid = 0, vdev_guid = 0;
|
||||||
guid_search_t search = { 0 };
|
guid_search_t search = { 0 };
|
||||||
device_type_t devtype = DEVICE_TYPE_PRIMARY;
|
device_type_t devtype = DEVICE_TYPE_PRIMARY;
|
||||||
const char *devid = NULL;
|
|
||||||
|
|
||||||
class = "resource.fs.zfs.removed";
|
class = "resource.fs.zfs.removed";
|
||||||
subclass = "";
|
subclass = "";
|
||||||
|
|
||||||
(void) nvlist_add_string(payload, FM_CLASS, class);
|
(void) nvlist_add_string(payload, FM_CLASS, class);
|
||||||
(void) nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid);
|
|
||||||
(void) nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &pool_guid);
|
(void) nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &pool_guid);
|
||||||
(void) nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &vdev_guid);
|
(void) nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &vdev_guid);
|
||||||
|
|
||||||
@@ -227,24 +209,20 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||||||
(void) nvlist_add_int64_array(payload, FM_EREPORT_TIME, tod, 2);
|
(void) nvlist_add_int64_array(payload, FM_EREPORT_TIME, tod, 2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If devid is missing but vdev_guid is available, find devid
|
|
||||||
* and pool_guid from vdev_guid.
|
|
||||||
* For multipath, spare and l2arc devices ZFS_EV_VDEV_GUID or
|
* For multipath, spare and l2arc devices ZFS_EV_VDEV_GUID or
|
||||||
* ZFS_EV_POOL_GUID may be missing so find them.
|
* ZFS_EV_POOL_GUID may be missing so find them.
|
||||||
*/
|
*/
|
||||||
if (devid == NULL || pool_guid == 0 || vdev_guid == 0) {
|
if (pool_guid == 0 || vdev_guid == 0) {
|
||||||
if (devid == NULL)
|
if ((nvlist_lookup_string(nvl, DEV_IDENTIFIER,
|
||||||
search.gs_vdev_guid = vdev_guid;
|
&search.gs_devid) == 0) &&
|
||||||
else
|
(zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search)
|
||||||
search.gs_devid = devid;
|
== 1)) {
|
||||||
zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search);
|
if (pool_guid == 0)
|
||||||
if (devid == NULL)
|
pool_guid = search.gs_pool_guid;
|
||||||
devid = search.gs_devid;
|
if (vdev_guid == 0)
|
||||||
if (pool_guid == 0)
|
vdev_guid = search.gs_vdev_guid;
|
||||||
pool_guid = search.gs_pool_guid;
|
devtype = search.gs_vdev_type;
|
||||||
if (vdev_guid == 0)
|
}
|
||||||
vdev_guid = search.gs_vdev_guid;
|
|
||||||
devtype = search.gs_vdev_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -257,9 +235,7 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||||||
search.gs_vdev_expandtime + 10 > tv.tv_sec) {
|
search.gs_vdev_expandtime + 10 > tv.tv_sec) {
|
||||||
zed_log_msg(LOG_INFO, "agent post event: ignoring '%s' "
|
zed_log_msg(LOG_INFO, "agent post event: ignoring '%s' "
|
||||||
"for recently expanded device '%s'", EC_DEV_REMOVE,
|
"for recently expanded device '%s'", EC_DEV_REMOVE,
|
||||||
devid);
|
search.gs_devid);
|
||||||
fnvlist_free(payload);
|
|
||||||
free(event);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,8 +327,6 @@ zfs_agent_dispatch(const char *class, const char *subclass, nvlist_t *nvl)
|
|||||||
static void *
|
static void *
|
||||||
zfs_agent_consumer_thread(void *arg)
|
zfs_agent_consumer_thread(void *arg)
|
||||||
{
|
{
|
||||||
(void) arg;
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
agent_event_t *event;
|
agent_event_t *event;
|
||||||
|
|
||||||
@@ -369,7 +343,9 @@ zfs_agent_consumer_thread(void *arg)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((event = list_remove_head(&agent_events)) != NULL) {
|
if ((event = (list_head(&agent_events))) != NULL) {
|
||||||
|
list_remove(&agent_events, event);
|
||||||
|
|
||||||
(void) pthread_mutex_unlock(&agent_lock);
|
(void) pthread_mutex_unlock(&agent_lock);
|
||||||
|
|
||||||
/* dispatch to all event subscribers */
|
/* dispatch to all event subscribers */
|
||||||
@@ -432,7 +408,8 @@ zfs_agent_fini(void)
|
|||||||
(void) pthread_join(g_agents_tid, NULL);
|
(void) pthread_join(g_agents_tid, NULL);
|
||||||
|
|
||||||
/* drain any pending events */
|
/* drain any pending events */
|
||||||
while ((event = list_remove_head(&agent_events)) != NULL) {
|
while ((event = (list_head(&agent_events))) != NULL) {
|
||||||
|
list_remove(&agent_events, event);
|
||||||
nvlist_free(event->ae_nvl);
|
nvlist_free(event->ae_nvl);
|
||||||
free(event);
|
free(event);
|
||||||
}
|
}
|
||||||
|
|||||||
+54
-192
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -23,11 +23,11 @@
|
|||||||
* 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>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
#include <libuutil.h>
|
#include <libuutil.h>
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -35,29 +35,14 @@
|
|||||||
#include <sys/fs/zfs.h>
|
#include <sys/fs/zfs.h>
|
||||||
#include <sys/fm/protocol.h>
|
#include <sys/fm/protocol.h>
|
||||||
#include <sys/fm/fs/zfs.h>
|
#include <sys/fm/fs/zfs.h>
|
||||||
#include <sys/zio.h>
|
|
||||||
|
|
||||||
#include "zfs_agents.h"
|
#include "zfs_agents.h"
|
||||||
#include "fmd_api.h"
|
#include "fmd_api.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default values for the serd engine when processing checksum or io errors. The
|
* Our serd engines are named 'zfs_<pool_guid>_<vdev_guid>_{checksum,io}'. This
|
||||||
* semantics are N <events> in T <seconds>.
|
* #define reserves enough space for two 64-bit hex values plus the length of
|
||||||
*/
|
* the longest string.
|
||||||
#define DEFAULT_CHECKSUM_N 10 /* events */
|
|
||||||
#define DEFAULT_CHECKSUM_T 600 /* seconds */
|
|
||||||
#define DEFAULT_IO_N 10 /* events */
|
|
||||||
#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:
|
|
||||||
* 'zfs_<pool_guid>_<vdev_guid>_{checksum,io,slow_io}'
|
|
||||||
* This #define reserves enough space for two 64-bit hex values plus the
|
|
||||||
* length of the longest string.
|
|
||||||
*/
|
*/
|
||||||
#define MAX_SERDLEN (16 * 2 + sizeof ("zfs___checksum"))
|
#define MAX_SERDLEN (16 * 2 + sizeof ("zfs___checksum"))
|
||||||
|
|
||||||
@@ -74,7 +59,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 +105,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,13 +115,11 @@ 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.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
zfs_case_serialize(zfs_case_t *zcp)
|
zfs_case_serialize(fmd_hdl_t *hdl, zfs_case_t *zcp)
|
||||||
{
|
{
|
||||||
zcp->zc_data.zc_version = CASE_DATA_VERSION_SERD;
|
zcp->zc_data.zc_version = CASE_DATA_VERSION_SERD;
|
||||||
}
|
}
|
||||||
@@ -180,42 +161,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.
|
||||||
@@ -264,10 +209,10 @@ zfs_mark_vdev(uint64_t pool_guid, nvlist_t *vd, er_timeval_t *loaded)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
static int
|
static int
|
||||||
zfs_mark_pool(zpool_handle_t *zhp, void *unused)
|
zfs_mark_pool(zpool_handle_t *zhp, void *unused)
|
||||||
{
|
{
|
||||||
(void) unused;
|
|
||||||
zfs_case_t *zcp;
|
zfs_case_t *zcp;
|
||||||
uint64_t pool_guid;
|
uint64_t pool_guid;
|
||||||
uint64_t *tod;
|
uint64_t *tod;
|
||||||
@@ -422,21 +367,14 @@ 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
|
||||||
* case.
|
* case.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
zfs_case_solve(fmd_hdl_t *hdl, zfs_case_t *zcp, const char *faultname)
|
zfs_case_solve(fmd_hdl_t *hdl, zfs_case_t *zcp, const char *faultname,
|
||||||
|
boolean_t checkunusable)
|
||||||
{
|
{
|
||||||
nvlist_t *detector, *fault;
|
nvlist_t *detector, *fault;
|
||||||
boolean_t serialize;
|
boolean_t serialize;
|
||||||
@@ -474,7 +412,7 @@ zfs_case_solve(fmd_hdl_t *hdl, zfs_case_t *zcp, const char *faultname)
|
|||||||
serialize = B_TRUE;
|
serialize = B_TRUE;
|
||||||
}
|
}
|
||||||
if (serialize)
|
if (serialize)
|
||||||
zfs_case_serialize(zcp);
|
zfs_case_serialize(hdl, zcp);
|
||||||
|
|
||||||
nvlist_free(detector);
|
nvlist_free(detector);
|
||||||
}
|
}
|
||||||
@@ -486,10 +424,10 @@ timeval_earlier(er_timeval_t *a, er_timeval_t *b)
|
|||||||
(a->ertv_sec == b->ertv_sec && a->ertv_nsec < b->ertv_nsec));
|
(a->ertv_sec == b->ertv_sec && a->ertv_nsec < b->ertv_nsec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
static void
|
static void
|
||||||
zfs_ereport_when(fmd_hdl_t *hdl, nvlist_t *nvl, er_timeval_t *when)
|
zfs_ereport_when(fmd_hdl_t *hdl, nvlist_t *nvl, er_timeval_t *when)
|
||||||
{
|
{
|
||||||
(void) hdl;
|
|
||||||
int64_t *tod;
|
int64_t *tod;
|
||||||
uint_t nelem;
|
uint_t nelem;
|
||||||
|
|
||||||
@@ -505,20 +443,19 @@ zfs_ereport_when(fmd_hdl_t *hdl, nvlist_t *nvl, er_timeval_t *when)
|
|||||||
/*
|
/*
|
||||||
* Main fmd entry point.
|
* Main fmd entry point.
|
||||||
*/
|
*/
|
||||||
|
/*ARGSUSED*/
|
||||||
static void
|
static void
|
||||||
zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
|
zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
|
||||||
{
|
{
|
||||||
zfs_case_t *zcp, *dcp;
|
zfs_case_t *zcp, *dcp;
|
||||||
int32_t pool_state;
|
int32_t pool_state;
|
||||||
uint64_t ena, pool_guid, vdev_guid;
|
uint64_t ena, pool_guid, vdev_guid;
|
||||||
uint64_t checksum_n, checksum_t;
|
|
||||||
uint64_t io_n, io_t;
|
|
||||||
er_timeval_t pool_load;
|
er_timeval_t pool_load;
|
||||||
er_timeval_t er_when;
|
er_timeval_t er_when;
|
||||||
nvlist_t *detector;
|
nvlist_t *detector;
|
||||||
boolean_t pool_found = B_FALSE;
|
boolean_t pool_found = B_FALSE;
|
||||||
boolean_t isresource;
|
boolean_t isresource;
|
||||||
const char *type;
|
char *type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We subscribe to notifications for vdev or pool removal. In these
|
* We subscribe to notifications for vdev or pool removal. In these
|
||||||
@@ -686,7 +623,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;
|
||||||
}
|
}
|
||||||
@@ -747,16 +686,13 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
|
|||||||
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);
|
||||||
zcp->zc_data.zc_has_remove_timer = 0;
|
zcp->zc_data.zc_has_remove_timer = 0;
|
||||||
zfs_case_serialize(zcp);
|
zfs_case_serialize(hdl, zcp);
|
||||||
}
|
}
|
||||||
if (zcp->zc_data.zc_serd_io[0] != '\0')
|
if (zcp->zc_data.zc_serd_io[0] != '\0')
|
||||||
fmd_serd_reset(hdl, zcp->zc_data.zc_serd_io);
|
fmd_serd_reset(hdl, zcp->zc_data.zc_serd_io);
|
||||||
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 +721,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
|
||||||
@@ -819,18 +751,18 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
|
|||||||
fmd_case_close(hdl, dcp->zc_case);
|
fmd_case_close(hdl, dcp->zc_case);
|
||||||
}
|
}
|
||||||
|
|
||||||
zfs_case_solve(hdl, zcp, "fault.fs.zfs.pool");
|
zfs_case_solve(hdl, zcp, "fault.fs.zfs.pool", B_TRUE);
|
||||||
} else if (fmd_nvl_class_match(hdl, nvl,
|
} else if (fmd_nvl_class_match(hdl, nvl,
|
||||||
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_LOG_REPLAY))) {
|
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_LOG_REPLAY))) {
|
||||||
/*
|
/*
|
||||||
* Pool level fault for reading the intent logs.
|
* Pool level fault for reading the intent logs.
|
||||||
*/
|
*/
|
||||||
zfs_case_solve(hdl, zcp, "fault.fs.zfs.log_replay");
|
zfs_case_solve(hdl, zcp, "fault.fs.zfs.log_replay", B_TRUE);
|
||||||
} else if (fmd_nvl_class_match(hdl, nvl, "ereport.fs.zfs.vdev.*")) {
|
} else if (fmd_nvl_class_match(hdl, nvl, "ereport.fs.zfs.vdev.*")) {
|
||||||
/*
|
/*
|
||||||
* Device fault.
|
* Device fault.
|
||||||
*/
|
*/
|
||||||
zfs_case_solve(hdl, zcp, "fault.fs.zfs.device");
|
zfs_case_solve(hdl, zcp, "fault.fs.zfs.device", B_TRUE);
|
||||||
} else if (fmd_nvl_class_match(hdl, nvl,
|
} else if (fmd_nvl_class_match(hdl, nvl,
|
||||||
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_IO)) ||
|
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_IO)) ||
|
||||||
fmd_nvl_class_match(hdl, nvl,
|
fmd_nvl_class_match(hdl, nvl,
|
||||||
@@ -838,13 +770,9 @@ 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;
|
char *failmode = NULL;
|
||||||
boolean_t checkremove = B_FALSE;
|
boolean_t checkremove = B_FALSE;
|
||||||
uint32_t pri = 0;
|
|
||||||
int32_t flags = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is a checksum or I/O error, then toss it into the
|
* If this is a checksum or I/O error, then toss it into the
|
||||||
@@ -856,113 +784,30 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
|
|||||||
if (fmd_nvl_class_match(hdl, nvl,
|
if (fmd_nvl_class_match(hdl, nvl,
|
||||||
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_IO))) {
|
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_IO))) {
|
||||||
if (zcp->zc_data.zc_serd_io[0] == '\0') {
|
if (zcp->zc_data.zc_serd_io[0] == '\0') {
|
||||||
if (nvlist_lookup_uint64(nvl,
|
|
||||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_IO_N,
|
|
||||||
&io_n) != 0) {
|
|
||||||
io_n = DEFAULT_IO_N;
|
|
||||||
}
|
|
||||||
if (nvlist_lookup_uint64(nvl,
|
|
||||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_IO_T,
|
|
||||||
&io_t) != 0) {
|
|
||||||
io_t = DEFAULT_IO_T;
|
|
||||||
}
|
|
||||||
zfs_serd_name(zcp->zc_data.zc_serd_io,
|
zfs_serd_name(zcp->zc_data.zc_serd_io,
|
||||||
pool_guid, vdev_guid, "io");
|
pool_guid, vdev_guid, "io");
|
||||||
fmd_serd_create(hdl, zcp->zc_data.zc_serd_io,
|
fmd_serd_create(hdl, zcp->zc_data.zc_serd_io,
|
||||||
io_n,
|
fmd_prop_get_int32(hdl, "io_N"),
|
||||||
SEC2NSEC(io_t));
|
fmd_prop_get_int64(hdl, "io_T"));
|
||||||
zfs_case_serialize(zcp);
|
zfs_case_serialize(hdl, zcp);
|
||||||
}
|
}
|
||||||
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))) {
|
||||||
/*
|
|
||||||
* We ignore ereports for checksum errors generated by
|
|
||||||
* scrub/resilver I/O to avoid potentially further
|
|
||||||
* degrading the pool while it's being repaired.
|
|
||||||
*/
|
|
||||||
if (((nvlist_lookup_uint32(nvl,
|
|
||||||
FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY, &pri) == 0) &&
|
|
||||||
(pri == ZIO_PRIORITY_SCRUB ||
|
|
||||||
pri == ZIO_PRIORITY_REBUILD)) ||
|
|
||||||
((nvlist_lookup_int32(nvl,
|
|
||||||
FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS, &flags) == 0) &&
|
|
||||||
(flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)))) {
|
|
||||||
fmd_hdl_debug(hdl, "ignoring '%s' for "
|
|
||||||
"scrub/resilver I/O", class);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zcp->zc_data.zc_serd_checksum[0] == '\0') {
|
if (zcp->zc_data.zc_serd_checksum[0] == '\0') {
|
||||||
if (nvlist_lookup_uint64(nvl,
|
|
||||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_CKSUM_N,
|
|
||||||
&checksum_n) != 0) {
|
|
||||||
checksum_n = DEFAULT_CHECKSUM_N;
|
|
||||||
}
|
|
||||||
if (nvlist_lookup_uint64(nvl,
|
|
||||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_CKSUM_T,
|
|
||||||
&checksum_t) != 0) {
|
|
||||||
checksum_t = DEFAULT_CHECKSUM_T;
|
|
||||||
}
|
|
||||||
|
|
||||||
zfs_serd_name(zcp->zc_data.zc_serd_checksum,
|
zfs_serd_name(zcp->zc_data.zc_serd_checksum,
|
||||||
pool_guid, vdev_guid, "checksum");
|
pool_guid, vdev_guid, "checksum");
|
||||||
fmd_serd_create(hdl,
|
fmd_serd_create(hdl,
|
||||||
zcp->zc_data.zc_serd_checksum,
|
zcp->zc_data.zc_serd_checksum,
|
||||||
checksum_n,
|
fmd_prop_get_int32(hdl, "checksum_N"),
|
||||||
SEC2NSEC(checksum_t));
|
fmd_prop_get_int64(hdl, "checksum_T"));
|
||||||
zfs_case_serialize(zcp);
|
zfs_case_serialize(hdl, zcp);
|
||||||
}
|
}
|
||||||
if (fmd_serd_record(hdl,
|
if (fmd_serd_record(hdl,
|
||||||
zcp->zc_data.zc_serd_checksum, ep)) {
|
zcp->zc_data.zc_serd_checksum, ep)) {
|
||||||
zfs_case_solve(hdl, zcp,
|
zfs_case_solve(hdl, zcp,
|
||||||
"fault.fs.zfs.vdev.checksum");
|
"fault.fs.zfs.vdev.checksum", B_FALSE);
|
||||||
}
|
}
|
||||||
} else if (fmd_nvl_class_match(hdl, nvl,
|
} else if (fmd_nvl_class_match(hdl, nvl,
|
||||||
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_IO_FAILURE)) &&
|
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_IO_FAILURE)) &&
|
||||||
@@ -972,11 +817,12 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
|
|||||||
if (strncmp(failmode, FM_EREPORT_FAILMODE_CONTINUE,
|
if (strncmp(failmode, FM_EREPORT_FAILMODE_CONTINUE,
|
||||||
strlen(FM_EREPORT_FAILMODE_CONTINUE)) == 0) {
|
strlen(FM_EREPORT_FAILMODE_CONTINUE)) == 0) {
|
||||||
zfs_case_solve(hdl, zcp,
|
zfs_case_solve(hdl, zcp,
|
||||||
"fault.fs.zfs.io_failure_continue");
|
"fault.fs.zfs.io_failure_continue",
|
||||||
|
B_FALSE);
|
||||||
} else if (strncmp(failmode, FM_EREPORT_FAILMODE_WAIT,
|
} else if (strncmp(failmode, FM_EREPORT_FAILMODE_WAIT,
|
||||||
strlen(FM_EREPORT_FAILMODE_WAIT)) == 0) {
|
strlen(FM_EREPORT_FAILMODE_WAIT)) == 0) {
|
||||||
zfs_case_solve(hdl, zcp,
|
zfs_case_solve(hdl, zcp,
|
||||||
"fault.fs.zfs.io_failure_wait");
|
"fault.fs.zfs.io_failure_wait", B_FALSE);
|
||||||
}
|
}
|
||||||
} else if (fmd_nvl_class_match(hdl, nvl,
|
} else if (fmd_nvl_class_match(hdl, nvl,
|
||||||
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_PROBE_FAILURE))) {
|
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_PROBE_FAILURE))) {
|
||||||
@@ -998,7 +844,7 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
|
|||||||
zfs_remove_timeout);
|
zfs_remove_timeout);
|
||||||
if (!zcp->zc_data.zc_has_remove_timer) {
|
if (!zcp->zc_data.zc_has_remove_timer) {
|
||||||
zcp->zc_data.zc_has_remove_timer = 1;
|
zcp->zc_data.zc_has_remove_timer = 1;
|
||||||
zfs_case_serialize(zcp);
|
zfs_case_serialize(hdl, zcp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1008,13 +854,14 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
|
|||||||
* The timeout is fired when we diagnosed an I/O error, and it was not due to
|
* The timeout is fired when we diagnosed an I/O error, and it was not due to
|
||||||
* device removal (which would cause the timeout to be cancelled).
|
* device removal (which would cause the timeout to be cancelled).
|
||||||
*/
|
*/
|
||||||
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zfs_fm_timeout(fmd_hdl_t *hdl, id_t id, void *data)
|
zfs_fm_timeout(fmd_hdl_t *hdl, id_t id, void *data)
|
||||||
{
|
{
|
||||||
zfs_case_t *zcp = data;
|
zfs_case_t *zcp = data;
|
||||||
|
|
||||||
if (id == zcp->zc_remove_timer)
|
if (id == zcp->zc_remove_timer)
|
||||||
zfs_case_solve(hdl, zcp, "fault.fs.zfs.vdev.io");
|
zfs_case_solve(hdl, zcp, "fault.fs.zfs.vdev.io", B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1030,8 +877,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);
|
||||||
|
|
||||||
@@ -1040,15 +885,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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1089,6 +949,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
|
||||||
|
|||||||
+90
-497
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -24,7 +24,6 @@
|
|||||||
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
|
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2016, 2017, Intel Corporation.
|
* Copyright (c) 2016, 2017, Intel Corporation.
|
||||||
* Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
|
* Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
|
||||||
* Copyright (c) 2023, Klara Inc.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -134,11 +133,6 @@ zfs_unavail_pool(zpool_handle_t *zhp, void *data)
|
|||||||
if (zfs_toplevel_state(zhp) < VDEV_STATE_DEGRADED) {
|
if (zfs_toplevel_state(zhp) < VDEV_STATE_DEGRADED) {
|
||||||
unavailpool_t *uap;
|
unavailpool_t *uap;
|
||||||
uap = malloc(sizeof (unavailpool_t));
|
uap = malloc(sizeof (unavailpool_t));
|
||||||
if (uap == NULL) {
|
|
||||||
perror("malloc");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
uap->uap_zhp = zhp;
|
uap->uap_zhp = zhp;
|
||||||
list_insert_tail((list_t *)data, uap);
|
list_insert_tail((list_t *)data, uap);
|
||||||
} else {
|
} else {
|
||||||
@@ -147,17 +141,6 @@ zfs_unavail_pool(zpool_handle_t *zhp, void *data)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Write an array of strings to the zed log
|
|
||||||
*/
|
|
||||||
static void lines_to_zed_log_msg(char **lines, int lines_cnt)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < lines_cnt; i++) {
|
|
||||||
zed_log_msg(LOG_INFO, "%s", lines[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Two stage replace on Linux
|
* Two stage replace on Linux
|
||||||
* since we get disk notifications
|
* since we get disk notifications
|
||||||
@@ -195,31 +178,22 @@ static void lines_to_zed_log_msg(char **lines, int lines_cnt)
|
|||||||
static void
|
static void
|
||||||
zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
||||||
{
|
{
|
||||||
const char *path;
|
char *path;
|
||||||
vdev_state_t newstate;
|
vdev_state_t newstate;
|
||||||
nvlist_t *nvroot, *newvd;
|
nvlist_t *nvroot, *newvd;
|
||||||
pendingdev_t *device;
|
pendingdev_t *device;
|
||||||
uint64_t wholedisk = 0ULL;
|
uint64_t wholedisk = 0ULL;
|
||||||
uint64_t offline = 0ULL, faulted = 0ULL;
|
uint64_t offline = 0ULL;
|
||||||
uint64_t guid = 0ULL;
|
uint64_t guid = 0ULL;
|
||||||
uint64_t is_spare = 0;
|
char *physpath = NULL, *new_devid = NULL, *enc_sysfs_path = NULL;
|
||||||
const char *physpath = NULL, *new_devid = NULL, *enc_sysfs_path = NULL;
|
|
||||||
char rawpath[PATH_MAX], fullpath[PATH_MAX];
|
char rawpath[PATH_MAX], fullpath[PATH_MAX];
|
||||||
char pathbuf[PATH_MAX];
|
char devpath[PATH_MAX];
|
||||||
int ret;
|
int ret;
|
||||||
int online_flag = ZFS_ONLINE_CHECKREMOVE | ZFS_ONLINE_UNSPARE;
|
boolean_t is_dm = B_FALSE;
|
||||||
boolean_t is_sd = B_FALSE;
|
boolean_t is_sd = B_FALSE;
|
||||||
boolean_t is_mpath_wholedisk = B_FALSE;
|
|
||||||
uint_t c;
|
uint_t c;
|
||||||
vdev_stat_t *vs;
|
vdev_stat_t *vs;
|
||||||
char **lines = NULL;
|
|
||||||
int lines_cnt = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the persistent path, typically under the '/dev/disk/by-id' or
|
|
||||||
* '/dev/disk/by-vdev' directories. Note that this path can change
|
|
||||||
* when a vdev is replaced with a new disk.
|
|
||||||
*/
|
|
||||||
if (nvlist_lookup_string(vdev, ZPOOL_CONFIG_PATH, &path) != 0)
|
if (nvlist_lookup_string(vdev, ZPOOL_CONFIG_PATH, &path) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -233,82 +207,19 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
}
|
}
|
||||||
|
|
||||||
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_PHYS_PATH, &physpath);
|
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_PHYS_PATH, &physpath);
|
||||||
|
|
||||||
update_vdev_config_dev_sysfs_path(vdev, path,
|
|
||||||
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
|
|
||||||
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
|
(void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
|
||||||
&enc_sysfs_path);
|
&enc_sysfs_path);
|
||||||
|
|
||||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk);
|
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk);
|
||||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_OFFLINE, &offline);
|
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_OFFLINE, &offline);
|
||||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_FAULTED, &faulted);
|
|
||||||
|
|
||||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_GUID, &guid);
|
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_GUID, &guid);
|
||||||
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_IS_SPARE, &is_spare);
|
|
||||||
|
|
||||||
/*
|
if (offline)
|
||||||
* Special case:
|
return; /* don't intervene if it was taken offline */
|
||||||
*
|
|
||||||
* We've seen times where a disk won't have a ZPOOL_CONFIG_PHYS_PATH
|
|
||||||
* entry in their config. For example, on this force-faulted disk:
|
|
||||||
*
|
|
||||||
* children[0]:
|
|
||||||
* type: 'disk'
|
|
||||||
* id: 0
|
|
||||||
* guid: 14309659774640089719
|
|
||||||
* path: '/dev/disk/by-vdev/L28'
|
|
||||||
* whole_disk: 0
|
|
||||||
* DTL: 654
|
|
||||||
* create_txg: 4
|
|
||||||
* com.delphix:vdev_zap_leaf: 1161
|
|
||||||
* faulted: 1
|
|
||||||
* aux_state: 'external'
|
|
||||||
* children[1]:
|
|
||||||
* type: 'disk'
|
|
||||||
* id: 1
|
|
||||||
* guid: 16002508084177980912
|
|
||||||
* path: '/dev/disk/by-vdev/L29'
|
|
||||||
* devid: 'dm-uuid-mpath-35000c500a61d68a3'
|
|
||||||
* phys_path: 'L29'
|
|
||||||
* vdev_enc_sysfs_path: '/sys/class/enclosure/0:0:1:0/SLOT 30 32'
|
|
||||||
* whole_disk: 0
|
|
||||||
* DTL: 1028
|
|
||||||
* create_txg: 4
|
|
||||||
* com.delphix:vdev_zap_leaf: 131
|
|
||||||
*
|
|
||||||
* If the disk's path is a /dev/disk/by-vdev/ path, then we can infer
|
|
||||||
* the ZPOOL_CONFIG_PHYS_PATH from the by-vdev disk name.
|
|
||||||
*/
|
|
||||||
if (physpath == NULL && path != NULL) {
|
|
||||||
/* If path begins with "/dev/disk/by-vdev/" ... */
|
|
||||||
if (strncmp(path, DEV_BYVDEV_PATH,
|
|
||||||
strlen(DEV_BYVDEV_PATH)) == 0) {
|
|
||||||
/* Set physpath to the char after "/dev/disk/by-vdev" */
|
|
||||||
physpath = &path[strlen(DEV_BYVDEV_PATH)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
is_dm = zfs_dev_is_dm(path);
|
||||||
* We don't want to autoreplace offlined disks. However, we do want to
|
|
||||||
* replace force-faulted disks (`zpool offline -f`). Force-faulted
|
|
||||||
* disks have both offline=1 and faulted=1 in the nvlist.
|
|
||||||
*/
|
|
||||||
if (offline && !faulted) {
|
|
||||||
zed_log_msg(LOG_INFO, "%s: %s is offline, skip autoreplace",
|
|
||||||
__func__, path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
is_mpath_wholedisk = is_mpath_whole_disk(path);
|
|
||||||
zed_log_msg(LOG_INFO, "zfs_process_add: pool '%s' vdev '%s', phys '%s'"
|
zed_log_msg(LOG_INFO, "zfs_process_add: pool '%s' vdev '%s', phys '%s'"
|
||||||
" %s blank disk, %s mpath blank disk, %s labeled, enc sysfs '%s', "
|
" wholedisk %d, %s dm (guid %llu)", zpool_get_name(zhp), path,
|
||||||
"(guid %llu)",
|
physpath ? physpath : "NULL", wholedisk, is_dm ? "is" : "not",
|
||||||
zpool_get_name(zhp), path,
|
|
||||||
physpath ? physpath : "NULL",
|
|
||||||
wholedisk ? "is" : "not",
|
|
||||||
is_mpath_wholedisk? "is" : "not",
|
|
||||||
labeled ? "is" : "not",
|
|
||||||
enc_sysfs_path,
|
|
||||||
(long long unsigned int)guid);
|
(long long unsigned int)guid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -335,18 +246,15 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_spare)
|
|
||||||
online_flag |= ZFS_ONLINE_SPARE;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attempt to online the device.
|
* Attempt to online the device.
|
||||||
*/
|
*/
|
||||||
if (zpool_vdev_online(zhp, fullpath, online_flag, &newstate) == 0 &&
|
if (zpool_vdev_online(zhp, fullpath,
|
||||||
|
ZFS_ONLINE_CHECKREMOVE | ZFS_ONLINE_UNSPARE, &newstate) == 0 &&
|
||||||
(newstate == VDEV_STATE_HEALTHY ||
|
(newstate == VDEV_STATE_HEALTHY ||
|
||||||
newstate == VDEV_STATE_DEGRADED)) {
|
newstate == VDEV_STATE_DEGRADED)) {
|
||||||
zed_log_msg(LOG_INFO,
|
zed_log_msg(LOG_INFO, " zpool_vdev_online: vdev %s is %s",
|
||||||
" zpool_vdev_online: vdev '%s' ('%s') is "
|
fullpath, (newstate == VDEV_STATE_HEALTHY) ?
|
||||||
"%s", fullpath, physpath, (newstate == VDEV_STATE_HEALTHY) ?
|
|
||||||
"HEALTHY" : "DEGRADED");
|
"HEALTHY" : "DEGRADED");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -363,12 +271,11 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
* vdev online to trigger a FMA fault by posting an ereport.
|
* vdev online to trigger a FMA fault by posting an ereport.
|
||||||
*/
|
*/
|
||||||
if (!zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOREPLACE, NULL) ||
|
if (!zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOREPLACE, NULL) ||
|
||||||
!(wholedisk || is_mpath_wholedisk) || (physpath == NULL)) {
|
!(wholedisk || is_dm) || (physpath == NULL)) {
|
||||||
(void) zpool_vdev_online(zhp, fullpath, ZFS_ONLINE_FORCEFAULT,
|
(void) zpool_vdev_online(zhp, fullpath, ZFS_ONLINE_FORCEFAULT,
|
||||||
&newstate);
|
&newstate);
|
||||||
zed_log_msg(LOG_INFO, "Pool's autoreplace is not enabled or "
|
zed_log_msg(LOG_INFO, "Pool's autoreplace is not enabled or "
|
||||||
"not a blank disk for '%s' ('%s')", fullpath,
|
"not a whole disk for '%s'", fullpath);
|
||||||
physpath);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,50 +287,29 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
(void) snprintf(rawpath, sizeof (rawpath), "%s%s",
|
(void) snprintf(rawpath, sizeof (rawpath), "%s%s",
|
||||||
is_sd ? DEV_BYVDEV_PATH : DEV_BYPATH_PATH, physpath);
|
is_sd ? DEV_BYVDEV_PATH : DEV_BYPATH_PATH, physpath);
|
||||||
|
|
||||||
if (realpath(rawpath, pathbuf) == NULL && !is_mpath_wholedisk) {
|
if (realpath(rawpath, devpath) == NULL && !is_dm) {
|
||||||
zed_log_msg(LOG_INFO, " realpath: %s failed (%s)",
|
zed_log_msg(LOG_INFO, " realpath: %s failed (%s)",
|
||||||
rawpath, strerror(errno));
|
rawpath, strerror(errno));
|
||||||
|
|
||||||
int err = zpool_vdev_online(zhp, fullpath,
|
(void) zpool_vdev_online(zhp, fullpath, ZFS_ONLINE_FORCEFAULT,
|
||||||
ZFS_ONLINE_FORCEFAULT, &newstate);
|
&newstate);
|
||||||
|
|
||||||
zed_log_msg(LOG_INFO, " zpool_vdev_online: %s FORCEFAULT (%s) "
|
zed_log_msg(LOG_INFO, " zpool_vdev_online: %s FORCEFAULT (%s)",
|
||||||
"err %d, new state %d",
|
fullpath, libzfs_error_description(g_zfshdl));
|
||||||
fullpath, libzfs_error_description(g_zfshdl), err,
|
|
||||||
err ? (int)newstate : 0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only autoreplace bad disks */
|
/* Only autoreplace bad disks */
|
||||||
if ((vs->vs_state != VDEV_STATE_DEGRADED) &&
|
if ((vs->vs_state != VDEV_STATE_DEGRADED) &&
|
||||||
(vs->vs_state != VDEV_STATE_FAULTED) &&
|
(vs->vs_state != VDEV_STATE_FAULTED) &&
|
||||||
(vs->vs_state != VDEV_STATE_REMOVED) &&
|
|
||||||
(vs->vs_state != VDEV_STATE_CANT_OPEN)) {
|
(vs->vs_state != VDEV_STATE_CANT_OPEN)) {
|
||||||
zed_log_msg(LOG_INFO, " not autoreplacing since disk isn't in "
|
|
||||||
"a bad state (currently %llu)", vs->vs_state);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nvlist_lookup_string(vdev, "new_devid", &new_devid);
|
nvlist_lookup_string(vdev, "new_devid", &new_devid);
|
||||||
|
|
||||||
if (is_mpath_wholedisk) {
|
if (is_dm) {
|
||||||
/* Don't label device mapper or multipath disks. */
|
/* Don't label device mapper or multipath disks. */
|
||||||
zed_log_msg(LOG_INFO,
|
|
||||||
" it's a multipath wholedisk, don't label");
|
|
||||||
if (zpool_prepare_disk(zhp, vdev, "autoreplace", &lines,
|
|
||||||
&lines_cnt) != 0) {
|
|
||||||
zed_log_msg(LOG_INFO,
|
|
||||||
" zpool_prepare_disk: could not "
|
|
||||||
"prepare '%s' (%s)", fullpath,
|
|
||||||
libzfs_error_description(g_zfshdl));
|
|
||||||
if (lines_cnt > 0) {
|
|
||||||
zed_log_msg(LOG_INFO,
|
|
||||||
" zfs_prepare_disk output:");
|
|
||||||
lines_to_zed_log_msg(lines, lines_cnt);
|
|
||||||
}
|
|
||||||
libzfs_free_str_array(lines, lines_cnt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (!labeled) {
|
} else if (!labeled) {
|
||||||
/*
|
/*
|
||||||
* we're auto-replacing a raw disk, so label it first
|
* we're auto-replacing a raw disk, so label it first
|
||||||
@@ -440,24 +326,16 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
* to trigger a ZFS fault for the device (and any hot spare
|
* to trigger a ZFS fault for the device (and any hot spare
|
||||||
* replacement).
|
* replacement).
|
||||||
*/
|
*/
|
||||||
leafname = strrchr(pathbuf, '/') + 1;
|
leafname = strrchr(devpath, '/') + 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is a request to label a whole disk, then attempt to
|
* If this is a request to label a whole disk, then attempt to
|
||||||
* write out the label.
|
* write out the label.
|
||||||
*/
|
*/
|
||||||
if (zpool_prepare_and_label_disk(g_zfshdl, zhp, leafname,
|
if (zpool_label_disk(g_zfshdl, zhp, leafname) != 0) {
|
||||||
vdev, "autoreplace", &lines, &lines_cnt) != 0) {
|
zed_log_msg(LOG_INFO, " zpool_label_disk: could not "
|
||||||
zed_log_msg(LOG_WARNING,
|
|
||||||
" zpool_prepare_and_label_disk: could not "
|
|
||||||
"label '%s' (%s)", leafname,
|
"label '%s' (%s)", leafname,
|
||||||
libzfs_error_description(g_zfshdl));
|
libzfs_error_description(g_zfshdl));
|
||||||
if (lines_cnt > 0) {
|
|
||||||
zed_log_msg(LOG_INFO,
|
|
||||||
" zfs_prepare_disk output:");
|
|
||||||
lines_to_zed_log_msg(lines, lines_cnt);
|
|
||||||
}
|
|
||||||
libzfs_free_str_array(lines, lines_cnt);
|
|
||||||
|
|
||||||
(void) zpool_vdev_online(zhp, fullpath,
|
(void) zpool_vdev_online(zhp, fullpath,
|
||||||
ZFS_ONLINE_FORCEFAULT, &newstate);
|
ZFS_ONLINE_FORCEFAULT, &newstate);
|
||||||
@@ -471,16 +349,11 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
* completed.
|
* completed.
|
||||||
*/
|
*/
|
||||||
device = malloc(sizeof (pendingdev_t));
|
device = malloc(sizeof (pendingdev_t));
|
||||||
if (device == NULL) {
|
|
||||||
perror("malloc");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) strlcpy(device->pd_physpath, physpath,
|
(void) strlcpy(device->pd_physpath, physpath,
|
||||||
sizeof (device->pd_physpath));
|
sizeof (device->pd_physpath));
|
||||||
list_insert_tail(&g_device_list, device);
|
list_insert_tail(&g_device_list, device);
|
||||||
|
|
||||||
zed_log_msg(LOG_NOTICE, " zpool_label_disk: async '%s' (%llu)",
|
zed_log_msg(LOG_INFO, " zpool_label_disk: async '%s' (%llu)",
|
||||||
leafname, (u_longlong_t)guid);
|
leafname, (u_longlong_t)guid);
|
||||||
|
|
||||||
return; /* resumes at EC_DEV_ADD.ESC_DISK for partition */
|
return; /* resumes at EC_DEV_ADD.ESC_DISK for partition */
|
||||||
@@ -503,8 +376,8 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
/* unexpected partition slice encountered */
|
/* unexpected partition slice encountered */
|
||||||
zed_log_msg(LOG_WARNING, "labeled disk %s was "
|
zed_log_msg(LOG_INFO, "labeled disk %s unexpected here",
|
||||||
"unexpected here", fullpath);
|
fullpath);
|
||||||
(void) zpool_vdev_online(zhp, fullpath,
|
(void) zpool_vdev_online(zhp, fullpath,
|
||||||
ZFS_ONLINE_FORCEFAULT, &newstate);
|
ZFS_ONLINE_FORCEFAULT, &newstate);
|
||||||
return;
|
return;
|
||||||
@@ -513,21 +386,10 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
zed_log_msg(LOG_INFO, " zpool_label_disk: resume '%s' (%llu)",
|
zed_log_msg(LOG_INFO, " zpool_label_disk: resume '%s' (%llu)",
|
||||||
physpath, (u_longlong_t)guid);
|
physpath, (u_longlong_t)guid);
|
||||||
|
|
||||||
/*
|
(void) snprintf(devpath, sizeof (devpath), "%s%s",
|
||||||
* Paths that begin with '/dev/disk/by-id/' will change and so
|
DEV_BYID_PATH, new_devid);
|
||||||
* they must be updated before calling zpool_vdev_attach().
|
|
||||||
*/
|
|
||||||
if (strncmp(path, DEV_BYID_PATH, strlen(DEV_BYID_PATH)) == 0) {
|
|
||||||
(void) snprintf(pathbuf, sizeof (pathbuf), "%s%s",
|
|
||||||
DEV_BYID_PATH, new_devid);
|
|
||||||
zed_log_msg(LOG_INFO, " zpool_label_disk: path '%s' "
|
|
||||||
"replaced by '%s'", path, pathbuf);
|
|
||||||
path = pathbuf;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
libzfs_free_str_array(lines, lines_cnt);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct the root vdev to pass to zpool_vdev_attach(). While adding
|
* Construct the root vdev to pass to zpool_vdev_attach(). While adding
|
||||||
* the entire vdev structure is harmless, we construct a reduced set of
|
* the entire vdev structure is harmless, we construct a reduced set of
|
||||||
@@ -552,8 +414,8 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH, enc_sysfs_path) != 0) ||
|
ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH, enc_sysfs_path) != 0) ||
|
||||||
nvlist_add_uint64(newvd, ZPOOL_CONFIG_WHOLE_DISK, wholedisk) != 0 ||
|
nvlist_add_uint64(newvd, ZPOOL_CONFIG_WHOLE_DISK, wholedisk) != 0 ||
|
||||||
nvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE, VDEV_TYPE_ROOT) != 0 ||
|
nvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE, VDEV_TYPE_ROOT) != 0 ||
|
||||||
nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
|
nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, &newvd,
|
||||||
(const nvlist_t **)&newvd, 1) != 0) {
|
1) != 0) {
|
||||||
zed_log_msg(LOG_WARNING, "zfs_mod: unable to add nvlist pairs");
|
zed_log_msg(LOG_WARNING, "zfs_mod: unable to add nvlist pairs");
|
||||||
nvlist_free(newvd);
|
nvlist_free(newvd);
|
||||||
nvlist_free(nvroot);
|
nvlist_free(nvroot);
|
||||||
@@ -566,11 +428,9 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
* Wait for udev to verify the links exist, then auto-replace
|
* Wait for udev to verify the links exist, then auto-replace
|
||||||
* the leaf disk at same physical location.
|
* the leaf disk at same physical location.
|
||||||
*/
|
*/
|
||||||
if (zpool_label_disk_wait(path, DISK_LABEL_WAIT) != 0) {
|
if (zpool_label_disk_wait(path, 3000) != 0) {
|
||||||
zed_log_msg(LOG_WARNING, "zfs_mod: pool '%s', after labeling "
|
zed_log_msg(LOG_WARNING, "zfs_mod: expected replacement "
|
||||||
"replacement disk, the expected disk partition link '%s' "
|
"disk %s is missing", path);
|
||||||
"is missing after waiting %u ms",
|
|
||||||
zpool_get_name(zhp), path, DISK_LABEL_WAIT);
|
|
||||||
nvlist_free(nvroot);
|
nvlist_free(nvroot);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -585,7 +445,7 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
B_TRUE, B_FALSE);
|
B_TRUE, B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
zed_log_msg(LOG_WARNING, " zpool_vdev_replace: %s with %s (%s)",
|
zed_log_msg(LOG_INFO, " zpool_vdev_replace: %s with %s (%s)",
|
||||||
fullpath, path, (ret == 0) ? "no errors" :
|
fullpath, path, (ret == 0) ? "no errors" :
|
||||||
libzfs_error_description(g_zfshdl));
|
libzfs_error_description(g_zfshdl));
|
||||||
|
|
||||||
@@ -603,20 +463,16 @@ typedef struct dev_data {
|
|||||||
boolean_t dd_islabeled;
|
boolean_t dd_islabeled;
|
||||||
uint64_t dd_pool_guid;
|
uint64_t dd_pool_guid;
|
||||||
uint64_t dd_vdev_guid;
|
uint64_t dd_vdev_guid;
|
||||||
uint64_t dd_new_vdev_guid;
|
|
||||||
const char *dd_new_devid;
|
const char *dd_new_devid;
|
||||||
uint64_t dd_num_spares;
|
|
||||||
} dev_data_t;
|
} dev_data_t;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
||||||
{
|
{
|
||||||
dev_data_t *dp = data;
|
dev_data_t *dp = data;
|
||||||
const char *path = NULL;
|
char *path = NULL;
|
||||||
uint_t c, children;
|
uint_t c, children;
|
||||||
nvlist_t **child;
|
nvlist_t **child;
|
||||||
uint64_t guid = 0;
|
|
||||||
uint64_t isspare = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First iterate over any children.
|
* First iterate over any children.
|
||||||
@@ -642,16 +498,19 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* once a vdev was matched and processed there is nothing left to do */
|
/* once a vdev was matched and processed there is nothing left to do */
|
||||||
if (dp->dd_found && dp->dd_num_spares == 0)
|
if (dp->dd_found)
|
||||||
return;
|
return;
|
||||||
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, &guid);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Match by GUID if available otherwise fallback to devid or physical
|
* Match by GUID if available otherwise fallback to devid or physical
|
||||||
*/
|
*/
|
||||||
if (dp->dd_vdev_guid != 0) {
|
if (dp->dd_vdev_guid != 0) {
|
||||||
if (guid != dp->dd_vdev_guid)
|
uint64_t guid;
|
||||||
|
|
||||||
|
if (nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID,
|
||||||
|
&guid) != 0 || guid != dp->dd_vdev_guid) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched on %llu", guid);
|
zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched on %llu", guid);
|
||||||
dp->dd_found = B_TRUE;
|
dp->dd_found = B_TRUE;
|
||||||
|
|
||||||
@@ -661,39 +520,22 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
|||||||
* illumos, substring matching is not required to accommodate
|
* illumos, substring matching is not required to accommodate
|
||||||
* the partition suffix. An exact match will be present in
|
* the partition suffix. An exact match will be present in
|
||||||
* the dp->dd_compare value.
|
* the dp->dd_compare value.
|
||||||
* If the attached disk already contains a vdev GUID, it means
|
|
||||||
* the disk is not clean. In such a scenario, the physical path
|
|
||||||
* would be a match that makes the disk faulted when trying to
|
|
||||||
* online it. So, we would only want to proceed if either GUID
|
|
||||||
* matches with the last attached disk or the disk is in clean
|
|
||||||
* state.
|
|
||||||
*/
|
*/
|
||||||
if (nvlist_lookup_string(nvl, dp->dd_prop, &path) != 0 ||
|
if (nvlist_lookup_string(nvl, dp->dd_prop, &path) != 0 ||
|
||||||
strcmp(dp->dd_compare, path) != 0) {
|
strcmp(dp->dd_compare, path) != 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if (dp->dd_new_vdev_guid != 0 && dp->dd_new_vdev_guid != guid) {
|
|
||||||
zed_log_msg(LOG_INFO, " %s: no match (GUID:%llu"
|
|
||||||
" != vdev GUID:%llu)", __func__,
|
|
||||||
dp->dd_new_vdev_guid, guid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched %s on %s",
|
zed_log_msg(LOG_INFO, " zfs_iter_vdev: matched %s on %s",
|
||||||
dp->dd_prop, path);
|
dp->dd_prop, path);
|
||||||
dp->dd_found = B_TRUE;
|
dp->dd_found = B_TRUE;
|
||||||
|
|
||||||
/* pass the new devid for use by auto-replacing code */
|
/* pass the new devid for use by replacing code */
|
||||||
if (dp->dd_new_devid != NULL) {
|
if (dp->dd_new_devid != NULL) {
|
||||||
(void) nvlist_add_string(nvl, "new_devid",
|
(void) nvlist_add_string(nvl, "new_devid",
|
||||||
dp->dd_new_devid);
|
dp->dd_new_devid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dp->dd_found == B_TRUE && nvlist_lookup_uint64(nvl,
|
|
||||||
ZPOOL_CONFIG_IS_SPARE, &isspare) == 0 && isspare)
|
|
||||||
dp->dd_num_spares++;
|
|
||||||
|
|
||||||
(dp->dd_func)(zhp, nvl, dp->dd_islabeled);
|
(dp->dd_func)(zhp, nvl, dp->dd_islabeled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -729,8 +571,6 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data)
|
|||||||
ZPOOL_CONFIG_VDEV_TREE, &nvl);
|
ZPOOL_CONFIG_VDEV_TREE, &nvl);
|
||||||
zfs_iter_vdev(zhp, nvl, data);
|
zfs_iter_vdev(zhp, nvl, data);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
zed_log_msg(LOG_INFO, "%s: no config\n", __func__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -754,9 +594,7 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
|
return (dp->dd_found); /* cease iteration after a match */
|
||||||
/* cease iteration after a match */
|
|
||||||
return (dp->dd_found && dp->dd_num_spares == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -765,7 +603,7 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data)
|
|||||||
*/
|
*/
|
||||||
static boolean_t
|
static boolean_t
|
||||||
devphys_iter(const char *physical, const char *devid, zfs_process_func_t func,
|
devphys_iter(const char *physical, const char *devid, zfs_process_func_t func,
|
||||||
boolean_t is_slice, uint64_t new_vdev_guid)
|
boolean_t is_slice)
|
||||||
{
|
{
|
||||||
dev_data_t data = { 0 };
|
dev_data_t data = { 0 };
|
||||||
|
|
||||||
@@ -775,73 +613,6 @@ devphys_iter(const char *physical, const char *devid, zfs_process_func_t func,
|
|||||||
data.dd_found = B_FALSE;
|
data.dd_found = B_FALSE;
|
||||||
data.dd_islabeled = is_slice;
|
data.dd_islabeled = is_slice;
|
||||||
data.dd_new_devid = devid; /* used by auto replace code */
|
data.dd_new_devid = devid; /* used by auto replace code */
|
||||||
data.dd_new_vdev_guid = new_vdev_guid;
|
|
||||||
|
|
||||||
(void) zpool_iter(g_zfshdl, zfs_iter_pool, &data);
|
|
||||||
|
|
||||||
return (data.dd_found);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given a device identifier, find any vdevs with a matching by-vdev
|
|
||||||
* path. Normally we shouldn't need this as the comparison would be
|
|
||||||
* made earlier in the devphys_iter(). For example, if we were replacing
|
|
||||||
* /dev/disk/by-vdev/L28, normally devphys_iter() would match the
|
|
||||||
* ZPOOL_CONFIG_PHYS_PATH of "L28" from the old disk config to "L28"
|
|
||||||
* of the new disk config. However, we've seen cases where
|
|
||||||
* ZPOOL_CONFIG_PHYS_PATH was not in the config for the old disk. Here's
|
|
||||||
* an example of a real 2-disk mirror pool where one disk was force
|
|
||||||
* faulted:
|
|
||||||
*
|
|
||||||
* com.delphix:vdev_zap_top: 129
|
|
||||||
* children[0]:
|
|
||||||
* type: 'disk'
|
|
||||||
* id: 0
|
|
||||||
* guid: 14309659774640089719
|
|
||||||
* path: '/dev/disk/by-vdev/L28'
|
|
||||||
* whole_disk: 0
|
|
||||||
* DTL: 654
|
|
||||||
* create_txg: 4
|
|
||||||
* com.delphix:vdev_zap_leaf: 1161
|
|
||||||
* faulted: 1
|
|
||||||
* aux_state: 'external'
|
|
||||||
* children[1]:
|
|
||||||
* type: 'disk'
|
|
||||||
* id: 1
|
|
||||||
* guid: 16002508084177980912
|
|
||||||
* path: '/dev/disk/by-vdev/L29'
|
|
||||||
* devid: 'dm-uuid-mpath-35000c500a61d68a3'
|
|
||||||
* phys_path: 'L29'
|
|
||||||
* vdev_enc_sysfs_path: '/sys/class/enclosure/0:0:1:0/SLOT 30 32'
|
|
||||||
* whole_disk: 0
|
|
||||||
* DTL: 1028
|
|
||||||
* create_txg: 4
|
|
||||||
* com.delphix:vdev_zap_leaf: 131
|
|
||||||
*
|
|
||||||
* So in the case above, the only thing we could compare is the path.
|
|
||||||
*
|
|
||||||
* We can do this because we assume by-vdev paths are authoritative as physical
|
|
||||||
* paths. We could not assume this for normal paths like /dev/sda since the
|
|
||||||
* physical location /dev/sda points to could change over time.
|
|
||||||
*/
|
|
||||||
static boolean_t
|
|
||||||
by_vdev_path_iter(const char *by_vdev_path, const char *devid,
|
|
||||||
zfs_process_func_t func, boolean_t is_slice)
|
|
||||||
{
|
|
||||||
dev_data_t data = { 0 };
|
|
||||||
|
|
||||||
data.dd_compare = by_vdev_path;
|
|
||||||
data.dd_func = func;
|
|
||||||
data.dd_prop = ZPOOL_CONFIG_PATH;
|
|
||||||
data.dd_found = B_FALSE;
|
|
||||||
data.dd_islabeled = is_slice;
|
|
||||||
data.dd_new_devid = devid;
|
|
||||||
|
|
||||||
if (strncmp(by_vdev_path, DEV_BYVDEV_PATH,
|
|
||||||
strlen(DEV_BYVDEV_PATH)) != 0) {
|
|
||||||
/* by_vdev_path doesn't start with "/dev/disk/by-vdev/" */
|
|
||||||
return (B_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) zpool_iter(g_zfshdl, zfs_iter_pool, &data);
|
(void) zpool_iter(g_zfshdl, zfs_iter_pool, &data);
|
||||||
|
|
||||||
@@ -869,27 +640,6 @@ devid_iter(const char *devid, zfs_process_func_t func, boolean_t is_slice)
|
|||||||
return (data.dd_found);
|
return (data.dd_found);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Given a device guid, find any vdevs with a matching guid.
|
|
||||||
*/
|
|
||||||
static boolean_t
|
|
||||||
guid_iter(uint64_t pool_guid, uint64_t vdev_guid, const char *devid,
|
|
||||||
zfs_process_func_t func, boolean_t is_slice)
|
|
||||||
{
|
|
||||||
dev_data_t data = { 0 };
|
|
||||||
|
|
||||||
data.dd_func = func;
|
|
||||||
data.dd_found = B_FALSE;
|
|
||||||
data.dd_pool_guid = pool_guid;
|
|
||||||
data.dd_vdev_guid = vdev_guid;
|
|
||||||
data.dd_islabeled = is_slice;
|
|
||||||
data.dd_new_devid = devid;
|
|
||||||
|
|
||||||
(void) zpool_iter(g_zfshdl, zfs_iter_pool, &data);
|
|
||||||
|
|
||||||
return (data.dd_found);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle a EC_DEV_ADD.ESC_DISK event.
|
* Handle a EC_DEV_ADD.ESC_DISK event.
|
||||||
*
|
*
|
||||||
@@ -910,23 +660,18 @@ guid_iter(uint64_t pool_guid, uint64_t vdev_guid, const char *devid,
|
|||||||
* phys_path: 'pci-0000:04:00.0-sas-0x4433221106000000-lun-0'
|
* phys_path: 'pci-0000:04:00.0-sas-0x4433221106000000-lun-0'
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
zfs_deliver_add(nvlist_t *nvl)
|
zfs_deliver_add(nvlist_t *nvl, boolean_t is_lofi)
|
||||||
{
|
{
|
||||||
const char *devpath = NULL, *devid = NULL;
|
char *devpath = NULL, *devid;
|
||||||
uint64_t pool_guid = 0, vdev_guid = 0;
|
|
||||||
boolean_t is_slice;
|
boolean_t is_slice;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expecting a devid string and an optional physical location and guid
|
* Expecting a devid string and an optional physical location
|
||||||
*/
|
*/
|
||||||
if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid) != 0) {
|
if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid) != 0)
|
||||||
zed_log_msg(LOG_INFO, "%s: no dev identifier\n", __func__);
|
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
|
||||||
|
|
||||||
(void) nvlist_lookup_string(nvl, DEV_PHYS_PATH, &devpath);
|
(void) nvlist_lookup_string(nvl, DEV_PHYS_PATH, &devpath);
|
||||||
(void) nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &pool_guid);
|
|
||||||
(void) nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &vdev_guid);
|
|
||||||
|
|
||||||
is_slice = (nvlist_lookup_boolean(nvl, DEV_IS_PART) == 0);
|
is_slice = (nvlist_lookup_boolean(nvl, DEV_IS_PART) == 0);
|
||||||
|
|
||||||
@@ -937,28 +682,12 @@ zfs_deliver_add(nvlist_t *nvl)
|
|||||||
* Iterate over all vdevs looking for a match in the following order:
|
* Iterate over all vdevs looking for a match in the following order:
|
||||||
* 1. ZPOOL_CONFIG_DEVID (identifies the unique disk)
|
* 1. ZPOOL_CONFIG_DEVID (identifies the unique disk)
|
||||||
* 2. ZPOOL_CONFIG_PHYS_PATH (identifies disk physical location).
|
* 2. ZPOOL_CONFIG_PHYS_PATH (identifies disk physical location).
|
||||||
* 3. ZPOOL_CONFIG_GUID (identifies unique vdev).
|
*
|
||||||
* 4. ZPOOL_CONFIG_PATH for /dev/disk/by-vdev devices only (since
|
* For disks, we only want to pay attention to vdevs marked as whole
|
||||||
* by-vdev paths represent physical paths).
|
* disks or are a multipath device.
|
||||||
*/
|
*/
|
||||||
if (devid_iter(devid, zfs_process_add, is_slice))
|
if (!devid_iter(devid, zfs_process_add, is_slice) && devpath != NULL)
|
||||||
return (0);
|
(void) devphys_iter(devpath, devid, zfs_process_add, is_slice);
|
||||||
if (devpath != NULL && devphys_iter(devpath, devid, zfs_process_add,
|
|
||||||
is_slice, vdev_guid))
|
|
||||||
return (0);
|
|
||||||
if (vdev_guid != 0)
|
|
||||||
(void) guid_iter(pool_guid, vdev_guid, devid, zfs_process_add,
|
|
||||||
is_slice);
|
|
||||||
|
|
||||||
if (devpath != NULL) {
|
|
||||||
/* Can we match a /dev/disk/by-vdev/ path? */
|
|
||||||
char by_vdev_path[MAXPATHLEN];
|
|
||||||
snprintf(by_vdev_path, sizeof (by_vdev_path),
|
|
||||||
"/dev/disk/by-vdev/%s", devpath);
|
|
||||||
if (by_vdev_path_iter(by_vdev_path, devid, zfs_process_add,
|
|
||||||
is_slice))
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@@ -990,98 +719,21 @@ zfs_deliver_check(nvlist_t *nvl)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Given a path to a vdev, lookup the vdev's physical size from its
|
|
||||||
* config nvlist.
|
|
||||||
*
|
|
||||||
* Returns the vdev's physical size in bytes on success, 0 on error.
|
|
||||||
*/
|
|
||||||
static uint64_t
|
|
||||||
vdev_size_from_config(zpool_handle_t *zhp, const char *vdev_path)
|
|
||||||
{
|
|
||||||
nvlist_t *nvl = NULL;
|
|
||||||
boolean_t avail_spare, l2cache, log;
|
|
||||||
vdev_stat_t *vs = NULL;
|
|
||||||
uint_t c;
|
|
||||||
|
|
||||||
nvl = zpool_find_vdev(zhp, vdev_path, &avail_spare, &l2cache, &log);
|
|
||||||
if (!nvl)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
verify(nvlist_lookup_uint64_array(nvl, ZPOOL_CONFIG_VDEV_STATS,
|
|
||||||
(uint64_t **)&vs, &c) == 0);
|
|
||||||
if (!vs) {
|
|
||||||
zed_log_msg(LOG_INFO, "%s: no nvlist for '%s'", __func__,
|
|
||||||
vdev_path);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (vs->vs_pspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given a path to a vdev, lookup if the vdev is a "whole disk" in the
|
|
||||||
* config nvlist. "whole disk" means that ZFS was passed a whole disk
|
|
||||||
* at pool creation time, which it partitioned up and has full control over.
|
|
||||||
* Thus a partition with wholedisk=1 set tells us that zfs created the
|
|
||||||
* partition at creation time. A partition without whole disk set would have
|
|
||||||
* been created by externally (like with fdisk) and passed to ZFS.
|
|
||||||
*
|
|
||||||
* Returns the whole disk value (either 0 or 1).
|
|
||||||
*/
|
|
||||||
static uint64_t
|
|
||||||
vdev_whole_disk_from_config(zpool_handle_t *zhp, const char *vdev_path)
|
|
||||||
{
|
|
||||||
nvlist_t *nvl = NULL;
|
|
||||||
boolean_t avail_spare, l2cache, log;
|
|
||||||
uint64_t wholedisk = 0;
|
|
||||||
|
|
||||||
nvl = zpool_find_vdev(zhp, vdev_path, &avail_spare, &l2cache, &log);
|
|
||||||
if (!nvl)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk);
|
|
||||||
|
|
||||||
return (wholedisk);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the device size grew more than 1% then return true.
|
|
||||||
*/
|
|
||||||
#define DEVICE_GREW(oldsize, newsize) \
|
|
||||||
((newsize > oldsize) && \
|
|
||||||
((newsize / (newsize - oldsize)) <= 100))
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
||||||
{
|
{
|
||||||
|
char *devname = data;
|
||||||
boolean_t avail_spare, l2cache;
|
boolean_t avail_spare, l2cache;
|
||||||
nvlist_t *udev_nvl = data;
|
|
||||||
nvlist_t *tgt;
|
nvlist_t *tgt;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
const char *tmp_devname;
|
|
||||||
char devname[MAXPATHLEN] = "";
|
|
||||||
uint64_t guid;
|
|
||||||
|
|
||||||
if (nvlist_lookup_uint64(udev_nvl, ZFS_EV_VDEV_GUID, &guid) == 0) {
|
|
||||||
sprintf(devname, "%llu", (u_longlong_t)guid);
|
|
||||||
} else if (nvlist_lookup_string(udev_nvl, DEV_PHYS_PATH,
|
|
||||||
&tmp_devname) == 0) {
|
|
||||||
strlcpy(devname, tmp_devname, MAXPATHLEN);
|
|
||||||
zfs_append_partition(devname, MAXPATHLEN);
|
|
||||||
} else {
|
|
||||||
zed_log_msg(LOG_INFO, "%s: no guid or physpath", __func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
zed_log_msg(LOG_INFO, "zfsdle_vdev_online: searching for '%s' in '%s'",
|
zed_log_msg(LOG_INFO, "zfsdle_vdev_online: searching for '%s' in '%s'",
|
||||||
devname, zpool_get_name(zhp));
|
devname, zpool_get_name(zhp));
|
||||||
|
|
||||||
if ((tgt = zpool_find_vdev_by_physpath(zhp, devname,
|
if ((tgt = zpool_find_vdev_by_physpath(zhp, devname,
|
||||||
&avail_spare, &l2cache, NULL)) != NULL) {
|
&avail_spare, &l2cache, NULL)) != NULL) {
|
||||||
const char *path;
|
char *path, fullpath[MAXPATHLEN];
|
||||||
char fullpath[MAXPATHLEN];
|
uint64_t wholedisk;
|
||||||
uint64_t wholedisk = 0;
|
|
||||||
|
|
||||||
error = nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &path);
|
error = nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &path);
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -1089,15 +741,16 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
|
error = nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
|
||||||
&wholedisk);
|
&wholedisk);
|
||||||
|
if (error)
|
||||||
|
wholedisk = 0;
|
||||||
|
|
||||||
if (wholedisk) {
|
if (wholedisk) {
|
||||||
char *tmp;
|
|
||||||
path = strrchr(path, '/');
|
path = strrchr(path, '/');
|
||||||
if (path != NULL) {
|
if (path != NULL) {
|
||||||
tmp = zfs_strip_partition(path + 1);
|
path = zfs_strip_partition(path + 1);
|
||||||
if (tmp == NULL) {
|
if (path == NULL) {
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@@ -1106,8 +759,8 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) strlcpy(fullpath, tmp, sizeof (fullpath));
|
(void) strlcpy(fullpath, path, sizeof (fullpath));
|
||||||
free(tmp);
|
free(path);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to reopen the pool associated with this
|
* We need to reopen the pool associated with this
|
||||||
@@ -1125,75 +778,12 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
|||||||
vdev_state_t newstate;
|
vdev_state_t newstate;
|
||||||
|
|
||||||
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) {
|
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) {
|
||||||
/*
|
error = zpool_vdev_online(zhp, fullpath, 0,
|
||||||
* If this disk size has not changed, then
|
&newstate);
|
||||||
* there's no need to do an autoexpand. To
|
zed_log_msg(LOG_INFO, "zfsdle_vdev_online: "
|
||||||
* check we look at the disk's size in its
|
"setting device '%s' to ONLINE state "
|
||||||
* config, and compare it to the disk size
|
"in pool '%s': %d", fullpath,
|
||||||
* that udev is reporting.
|
zpool_get_name(zhp), error);
|
||||||
*/
|
|
||||||
uint64_t udev_size = 0, conf_size = 0,
|
|
||||||
wholedisk = 0, udev_parent_size = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the size of our disk that udev is
|
|
||||||
* reporting.
|
|
||||||
*/
|
|
||||||
if (nvlist_lookup_uint64(udev_nvl, DEV_SIZE,
|
|
||||||
&udev_size) != 0) {
|
|
||||||
udev_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the size of our disk's parent device
|
|
||||||
* from udev (where sda1's parent is sda).
|
|
||||||
*/
|
|
||||||
if (nvlist_lookup_uint64(udev_nvl,
|
|
||||||
DEV_PARENT_SIZE, &udev_parent_size) != 0) {
|
|
||||||
udev_parent_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
conf_size = vdev_size_from_config(zhp,
|
|
||||||
fullpath);
|
|
||||||
|
|
||||||
wholedisk = vdev_whole_disk_from_config(zhp,
|
|
||||||
fullpath);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Only attempt an autoexpand if the vdev size
|
|
||||||
* changed. There are two different cases
|
|
||||||
* to consider.
|
|
||||||
*
|
|
||||||
* 1. wholedisk=1
|
|
||||||
* If you do a 'zpool create' on a whole disk
|
|
||||||
* (like /dev/sda), then zfs will create
|
|
||||||
* partitions on the disk (like /dev/sda1). In
|
|
||||||
* that case, wholedisk=1 will be set in the
|
|
||||||
* partition's nvlist config. So zed will need
|
|
||||||
* to see if your parent device (/dev/sda)
|
|
||||||
* expanded in size, and if so, then attempt
|
|
||||||
* the autoexpand.
|
|
||||||
*
|
|
||||||
* 2. wholedisk=0
|
|
||||||
* If you do a 'zpool create' on an existing
|
|
||||||
* partition, or a device that doesn't allow
|
|
||||||
* partitions, then wholedisk=0, and you will
|
|
||||||
* simply need to check if the device itself
|
|
||||||
* expanded in size.
|
|
||||||
*/
|
|
||||||
if (DEVICE_GREW(conf_size, udev_size) ||
|
|
||||||
(wholedisk && DEVICE_GREW(conf_size,
|
|
||||||
udev_parent_size))) {
|
|
||||||
error = zpool_vdev_online(zhp, fullpath,
|
|
||||||
0, &newstate);
|
|
||||||
|
|
||||||
zed_log_msg(LOG_INFO,
|
|
||||||
"%s: autoexpanding '%s' from %llu"
|
|
||||||
" to %llu bytes in pool '%s': %d",
|
|
||||||
__func__, fullpath, conf_size,
|
|
||||||
MAX(udev_size, udev_parent_size),
|
|
||||||
zpool_get_name(zhp), error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
@@ -1212,8 +802,7 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
|||||||
static int
|
static int
|
||||||
zfs_deliver_dle(nvlist_t *nvl)
|
zfs_deliver_dle(nvlist_t *nvl)
|
||||||
{
|
{
|
||||||
const char *devname;
|
char *devname, name[MAXPATHLEN];
|
||||||
char name[MAXPATHLEN];
|
|
||||||
uint64_t guid;
|
uint64_t guid;
|
||||||
|
|
||||||
if (nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &guid) == 0) {
|
if (nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &guid) == 0) {
|
||||||
@@ -1222,11 +811,10 @@ zfs_deliver_dle(nvlist_t *nvl)
|
|||||||
strlcpy(name, devname, MAXPATHLEN);
|
strlcpy(name, devname, MAXPATHLEN);
|
||||||
zfs_append_partition(name, MAXPATHLEN);
|
zfs_append_partition(name, MAXPATHLEN);
|
||||||
} else {
|
} else {
|
||||||
sprintf(name, "unknown");
|
|
||||||
zed_log_msg(LOG_INFO, "zfs_deliver_dle: no guid or physpath");
|
zed_log_msg(LOG_INFO, "zfs_deliver_dle: no guid or physpath");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zpool_iter(g_zfshdl, zfsdle_vdev_online, nvl) != 1) {
|
if (zpool_iter(g_zfshdl, zfsdle_vdev_online, name) != 1) {
|
||||||
zed_log_msg(LOG_INFO, "zfs_deliver_dle: device '%s' not "
|
zed_log_msg(LOG_INFO, "zfs_deliver_dle: device '%s' not "
|
||||||
"found", name);
|
"found", name);
|
||||||
return (1);
|
return (1);
|
||||||
@@ -1250,15 +838,18 @@ static int
|
|||||||
zfs_slm_deliver_event(const char *class, const char *subclass, nvlist_t *nvl)
|
zfs_slm_deliver_event(const char *class, const char *subclass, nvlist_t *nvl)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
boolean_t is_check = B_FALSE, is_dle = B_FALSE;
|
boolean_t is_lofi = B_FALSE, is_check = B_FALSE, is_dle = B_FALSE;
|
||||||
|
|
||||||
if (strcmp(class, EC_DEV_ADD) == 0) {
|
if (strcmp(class, EC_DEV_ADD) == 0) {
|
||||||
/*
|
/*
|
||||||
* We're mainly interested in disk additions, but we also listen
|
* We're mainly interested in disk additions, but we also listen
|
||||||
* for new loop devices, to allow for simplified testing.
|
* for new loop devices, to allow for simplified testing.
|
||||||
*/
|
*/
|
||||||
if (strcmp(subclass, ESC_DISK) != 0 &&
|
if (strcmp(subclass, ESC_DISK) == 0)
|
||||||
strcmp(subclass, ESC_LOFI) != 0)
|
is_lofi = B_FALSE;
|
||||||
|
else if (strcmp(subclass, ESC_LOFI) == 0)
|
||||||
|
is_lofi = B_TRUE;
|
||||||
|
else
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
is_check = B_FALSE;
|
is_check = B_FALSE;
|
||||||
@@ -1282,16 +873,15 @@ zfs_slm_deliver_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||||||
else if (is_check)
|
else if (is_check)
|
||||||
ret = zfs_deliver_check(nvl);
|
ret = zfs_deliver_check(nvl);
|
||||||
else
|
else
|
||||||
ret = zfs_deliver_add(nvl);
|
ret = zfs_deliver_add(nvl, is_lofi);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
static void *
|
static void *
|
||||||
zfs_enum_pools(void *arg)
|
zfs_enum_pools(void *arg)
|
||||||
{
|
{
|
||||||
(void) arg;
|
|
||||||
|
|
||||||
(void) zpool_iter(g_zfshdl, zfs_unavail_pool, (void *)&g_pool_list);
|
(void) zpool_iter(g_zfshdl, zfs_unavail_pool, (void *)&g_pool_list);
|
||||||
/*
|
/*
|
||||||
* Linux - instead of using a thread pool, each list entry
|
* Linux - instead of using a thread pool, each list entry
|
||||||
@@ -1310,7 +900,7 @@ zfs_enum_pools(void *arg)
|
|||||||
* For now, each agent has its own libzfs instance
|
* For now, each agent has its own libzfs instance
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zfs_slm_init(void)
|
zfs_slm_init()
|
||||||
{
|
{
|
||||||
if ((g_zfshdl = libzfs_init()) == NULL)
|
if ((g_zfshdl = libzfs_init()) == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
@@ -1336,7 +926,7 @@ zfs_slm_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zfs_slm_fini(void)
|
zfs_slm_fini()
|
||||||
{
|
{
|
||||||
unavailpool_t *pool;
|
unavailpool_t *pool;
|
||||||
pendingdev_t *device;
|
pendingdev_t *device;
|
||||||
@@ -1349,14 +939,17 @@ zfs_slm_fini(void)
|
|||||||
tpool_destroy(g_tpool);
|
tpool_destroy(g_tpool);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((pool = list_remove_head(&g_pool_list)) != NULL) {
|
while ((pool = (list_head(&g_pool_list))) != NULL) {
|
||||||
|
list_remove(&g_pool_list, pool);
|
||||||
zpool_close(pool->uap_zhp);
|
zpool_close(pool->uap_zhp);
|
||||||
free(pool);
|
free(pool);
|
||||||
}
|
}
|
||||||
list_destroy(&g_pool_list);
|
list_destroy(&g_pool_list);
|
||||||
|
|
||||||
while ((device = list_remove_head(&g_device_list)) != NULL)
|
while ((device = (list_head(&g_device_list))) != NULL) {
|
||||||
|
list_remove(&g_device_list, device);
|
||||||
free(device);
|
free(device);
|
||||||
|
}
|
||||||
list_destroy(&g_device_list);
|
list_destroy(&g_device_list);
|
||||||
|
|
||||||
libzfs_fini(g_zfshdl);
|
libzfs_fini(g_zfshdl);
|
||||||
|
|||||||
+20
-127
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -38,10 +38,8 @@
|
|||||||
#include <sys/fs/zfs.h>
|
#include <sys/fs/zfs.h>
|
||||||
#include <sys/fm/protocol.h>
|
#include <sys/fm/protocol.h>
|
||||||
#include <sys/fm/fs/zfs.h>
|
#include <sys/fm/fs/zfs.h>
|
||||||
#include <libzutil.h>
|
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <libgen.h>
|
|
||||||
|
|
||||||
#include "zfs_agents.h"
|
#include "zfs_agents.h"
|
||||||
#include "fmd_api.h"
|
#include "fmd_api.h"
|
||||||
@@ -76,8 +74,6 @@ typedef struct find_cbdata {
|
|||||||
uint64_t cb_guid;
|
uint64_t cb_guid;
|
||||||
zpool_handle_t *cb_zhp;
|
zpool_handle_t *cb_zhp;
|
||||||
nvlist_t *cb_vdev;
|
nvlist_t *cb_vdev;
|
||||||
uint64_t cb_vdev_guid;
|
|
||||||
uint64_t cb_num_spares;
|
|
||||||
} find_cbdata_t;
|
} find_cbdata_t;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -143,64 +139,6 @@ find_vdev(libzfs_handle_t *zhdl, nvlist_t *nv, uint64_t search_guid)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
remove_spares(zpool_handle_t *zhp, void *data)
|
|
||||||
{
|
|
||||||
nvlist_t *config, *nvroot;
|
|
||||||
nvlist_t **spares;
|
|
||||||
uint_t nspares;
|
|
||||||
char *devname;
|
|
||||||
find_cbdata_t *cbp = data;
|
|
||||||
uint64_t spareguid = 0;
|
|
||||||
vdev_stat_t *vs;
|
|
||||||
unsigned int c;
|
|
||||||
|
|
||||||
config = zpool_get_config(zhp, NULL);
|
|
||||||
if (nvlist_lookup_nvlist(config,
|
|
||||||
ZPOOL_CONFIG_VDEV_TREE, &nvroot) != 0) {
|
|
||||||
zpool_close(zhp);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
|
|
||||||
&spares, &nspares) != 0) {
|
|
||||||
zpool_close(zhp);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < nspares; i++) {
|
|
||||||
if (nvlist_lookup_uint64(spares[i], ZPOOL_CONFIG_GUID,
|
|
||||||
&spareguid) == 0 && spareguid == cbp->cb_vdev_guid) {
|
|
||||||
devname = zpool_vdev_name(NULL, zhp, spares[i],
|
|
||||||
B_FALSE);
|
|
||||||
nvlist_lookup_uint64_array(spares[i],
|
|
||||||
ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &c);
|
|
||||||
if (vs->vs_state != VDEV_STATE_REMOVED &&
|
|
||||||
zpool_vdev_remove_wanted(zhp, devname) == 0)
|
|
||||||
cbp->cb_num_spares++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
zpool_close(zhp);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given a vdev guid, find and remove all spares associated with it.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
find_and_remove_spares(libzfs_handle_t *zhdl, uint64_t vdev_guid)
|
|
||||||
{
|
|
||||||
find_cbdata_t cb;
|
|
||||||
|
|
||||||
cb.cb_num_spares = 0;
|
|
||||||
cb.cb_vdev_guid = vdev_guid;
|
|
||||||
zpool_iter(zhdl, remove_spares, &cb);
|
|
||||||
|
|
||||||
return (cb.cb_num_spares);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a (pool, vdev) GUID pair, find the matching pool and vdev.
|
* Given a (pool, vdev) GUID pair, find the matching pool and vdev.
|
||||||
*/
|
*/
|
||||||
@@ -282,7 +220,7 @@ replace_with_spare(fmd_hdl_t *hdl, zpool_handle_t *zhp, nvlist_t *vdev)
|
|||||||
*/
|
*/
|
||||||
for (s = 0; s < nspares; s++) {
|
for (s = 0; s < nspares; s++) {
|
||||||
boolean_t rebuild = B_FALSE;
|
boolean_t rebuild = B_FALSE;
|
||||||
const char *spare_name, *type;
|
char *spare_name, *type;
|
||||||
|
|
||||||
if (nvlist_lookup_string(spares[s], ZPOOL_CONFIG_PATH,
|
if (nvlist_lookup_string(spares[s], ZPOOL_CONFIG_PATH,
|
||||||
&spare_name) != 0)
|
&spare_name) != 0)
|
||||||
@@ -299,10 +237,10 @@ replace_with_spare(fmd_hdl_t *hdl, zpool_handle_t *zhp, nvlist_t *vdev)
|
|||||||
ZPOOL_CONFIG_ASHIFT, ashift);
|
ZPOOL_CONFIG_ASHIFT, ashift);
|
||||||
|
|
||||||
(void) nvlist_add_nvlist_array(replacement,
|
(void) nvlist_add_nvlist_array(replacement,
|
||||||
ZPOOL_CONFIG_CHILDREN, (const nvlist_t **)&spares[s], 1);
|
ZPOOL_CONFIG_CHILDREN, &spares[s], 1);
|
||||||
|
|
||||||
fmd_hdl_debug(hdl, "zpool_vdev_replace '%s' with spare '%s'",
|
fmd_hdl_debug(hdl, "zpool_vdev_replace '%s' with spare '%s'",
|
||||||
dev_name, zfs_basename(spare_name));
|
dev_name, basename(spare_name));
|
||||||
|
|
||||||
if (zpool_vdev_attach(zhp, dev_name, spare_name,
|
if (zpool_vdev_attach(zhp, dev_name, spare_name,
|
||||||
replacement, B_TRUE, rebuild) == 0) {
|
replacement, B_TRUE, rebuild) == 0) {
|
||||||
@@ -323,6 +261,7 @@ replace_with_spare(fmd_hdl_t *hdl, zpool_handle_t *zhp, nvlist_t *vdev)
|
|||||||
* ASRU is now usable. ZFS has found the device to be present and
|
* ASRU is now usable. ZFS has found the device to be present and
|
||||||
* functioning.
|
* functioning.
|
||||||
*/
|
*/
|
||||||
|
/*ARGSUSED*/
|
||||||
static void
|
static void
|
||||||
zfs_vdev_repair(fmd_hdl_t *hdl, nvlist_t *nvl)
|
zfs_vdev_repair(fmd_hdl_t *hdl, nvlist_t *nvl)
|
||||||
{
|
{
|
||||||
@@ -361,11 +300,11 @@ zfs_vdev_repair(fmd_hdl_t *hdl, nvlist_t *nvl)
|
|||||||
vdev_guid, pool_guid);
|
vdev_guid, pool_guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
static void
|
static void
|
||||||
zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
||||||
const char *class)
|
const char *class)
|
||||||
{
|
{
|
||||||
(void) ep;
|
|
||||||
uint64_t pool_guid, vdev_guid;
|
uint64_t pool_guid, vdev_guid;
|
||||||
zpool_handle_t *zhp;
|
zpool_handle_t *zhp;
|
||||||
nvlist_t *resource, *fault;
|
nvlist_t *resource, *fault;
|
||||||
@@ -375,23 +314,18 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
|||||||
libzfs_handle_t *zhdl = zdp->zrd_hdl;
|
libzfs_handle_t *zhdl = zdp->zrd_hdl;
|
||||||
boolean_t fault_device, degrade_device;
|
boolean_t fault_device, degrade_device;
|
||||||
boolean_t is_repair;
|
boolean_t is_repair;
|
||||||
boolean_t l2arc = B_FALSE;
|
char *scheme;
|
||||||
boolean_t spare = B_FALSE;
|
|
||||||
const char *scheme;
|
|
||||||
nvlist_t *vdev = NULL;
|
nvlist_t *vdev = NULL;
|
||||||
const char *uuid;
|
char *uuid;
|
||||||
int repair_done = 0;
|
int repair_done = 0;
|
||||||
boolean_t retire;
|
boolean_t retire;
|
||||||
boolean_t is_disk;
|
boolean_t is_disk;
|
||||||
vdev_aux_t aux;
|
vdev_aux_t aux;
|
||||||
uint64_t state = 0;
|
uint64_t state = 0;
|
||||||
vdev_stat_t *vs;
|
|
||||||
unsigned int c;
|
|
||||||
|
|
||||||
fmd_hdl_debug(hdl, "zfs_retire_recv: '%s'", class);
|
fmd_hdl_debug(hdl, "zfs_retire_recv: '%s'", class);
|
||||||
|
|
||||||
(void) nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE,
|
nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE, &state);
|
||||||
&state);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is a resource notifying us of device removal then simply
|
* If this is a resource notifying us of device removal then simply
|
||||||
@@ -401,34 +335,13 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
|||||||
if (strcmp(class, "resource.fs.zfs.removed") == 0 ||
|
if (strcmp(class, "resource.fs.zfs.removed") == 0 ||
|
||||||
(strcmp(class, "resource.fs.zfs.statechange") == 0 &&
|
(strcmp(class, "resource.fs.zfs.statechange") == 0 &&
|
||||||
(state == VDEV_STATE_REMOVED || state == VDEV_STATE_FAULTED))) {
|
(state == VDEV_STATE_REMOVED || state == VDEV_STATE_FAULTED))) {
|
||||||
const char *devtype;
|
char *devtype;
|
||||||
char *devname;
|
char *devname;
|
||||||
|
|
||||||
if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE,
|
|
||||||
&devtype) == 0) {
|
|
||||||
if (strcmp(devtype, VDEV_TYPE_SPARE) == 0)
|
|
||||||
spare = B_TRUE;
|
|
||||||
else if (strcmp(devtype, VDEV_TYPE_L2CACHE) == 0)
|
|
||||||
l2arc = B_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvlist_lookup_uint64(nvl,
|
|
||||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID, &vdev_guid) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (vdev_guid == 0) {
|
|
||||||
fmd_hdl_debug(hdl, "Got a zero GUID");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spare) {
|
|
||||||
int nspares = find_and_remove_spares(zhdl, vdev_guid);
|
|
||||||
fmd_hdl_debug(hdl, "%d spares removed", nspares);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_ZFS_POOL_GUID,
|
if (nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_ZFS_POOL_GUID,
|
||||||
&pool_guid) != 0)
|
&pool_guid) != 0 ||
|
||||||
|
nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID,
|
||||||
|
&vdev_guid) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((zhp = find_by_guid(zhdl, pool_guid, vdev_guid,
|
if ((zhp = find_by_guid(zhdl, pool_guid, vdev_guid,
|
||||||
@@ -437,30 +350,13 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
|||||||
|
|
||||||
devname = zpool_vdev_name(NULL, zhp, vdev, B_FALSE);
|
devname = zpool_vdev_name(NULL, zhp, vdev, B_FALSE);
|
||||||
|
|
||||||
nvlist_lookup_uint64_array(vdev, ZPOOL_CONFIG_VDEV_STATS,
|
/* Can't replace l2arc with a spare: offline the device */
|
||||||
(uint64_t **)&vs, &c);
|
if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE,
|
||||||
|
&devtype) == 0 && strcmp(devtype, VDEV_TYPE_L2CACHE) == 0) {
|
||||||
/*
|
fmd_hdl_debug(hdl, "zpool_vdev_offline '%s'", devname);
|
||||||
* If state removed is requested for already removed vdev,
|
zpool_vdev_offline(zhp, devname, B_TRUE);
|
||||||
* its a loopback event from spa_async_remove(). Just
|
} else if (!fmd_prop_get_int32(hdl, "spare_on_remove") ||
|
||||||
* ignore it.
|
replace_with_spare(hdl, zhp, vdev) == B_FALSE) {
|
||||||
*/
|
|
||||||
if (vs->vs_state == VDEV_STATE_REMOVED &&
|
|
||||||
state == VDEV_STATE_REMOVED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Remove the vdev since device is unplugged */
|
|
||||||
int remove_status = 0;
|
|
||||||
if (l2arc || (strcmp(class, "resource.fs.zfs.removed") == 0)) {
|
|
||||||
remove_status = zpool_vdev_remove_wanted(zhp, devname);
|
|
||||||
fmd_hdl_debug(hdl, "zpool_vdev_remove_wanted '%s'"
|
|
||||||
", err:%d", devname, libzfs_errno(zhdl));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Replace the vdev with a spare if its not a l2arc */
|
|
||||||
if (!l2arc && !remove_status &&
|
|
||||||
(!fmd_prop_get_int32(hdl, "spare_on_remove") ||
|
|
||||||
replace_with_spare(hdl, zhp, vdev) == B_FALSE)) {
|
|
||||||
/* Could not handle with spare */
|
/* Could not handle with spare */
|
||||||
fmd_hdl_debug(hdl, "no spare for '%s'", devname);
|
fmd_hdl_debug(hdl, "no spare for '%s'", devname);
|
||||||
}
|
}
|
||||||
@@ -523,9 +419,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;
|
||||||
|
|||||||
+1
-3
@@ -36,7 +36,6 @@ static volatile sig_atomic_t _got_hup = 0;
|
|||||||
static void
|
static void
|
||||||
_exit_handler(int signum)
|
_exit_handler(int signum)
|
||||||
{
|
{
|
||||||
(void) signum;
|
|
||||||
_got_exit = 1;
|
_got_exit = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +45,6 @@ _exit_handler(int signum)
|
|||||||
static void
|
static void
|
||||||
_hup_handler(int signum)
|
_hup_handler(int signum)
|
||||||
{
|
{
|
||||||
(void) signum;
|
|
||||||
_got_hup = 1;
|
_got_hup = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,7 +291,7 @@ idle:
|
|||||||
rv = zed_event_service(&zcp);
|
rv = zed_event_service(&zcp);
|
||||||
|
|
||||||
/* ENODEV: When kernel module is unloaded (osx) */
|
/* ENODEV: When kernel module is unloaded (osx) */
|
||||||
if (rv != 0)
|
if (rv == ENODEV)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+33
-33
@@ -1,28 +1,33 @@
|
|||||||
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
include $(top_srcdir)/config/Substfiles.am
|
||||||
|
include $(top_srcdir)/config/Shellcheck.am
|
||||||
|
|
||||||
|
EXTRA_DIST += README
|
||||||
|
|
||||||
zedconfdir = $(sysconfdir)/zfs/zed.d
|
zedconfdir = $(sysconfdir)/zfs/zed.d
|
||||||
|
|
||||||
dist_zedconf_DATA = \
|
dist_zedconf_DATA = \
|
||||||
%D%/zed-functions.sh \
|
zed-functions.sh \
|
||||||
%D%/zed.rc
|
zed.rc
|
||||||
|
|
||||||
zedexecdir = $(zfsexecdir)/zed.d
|
zedexecdir = $(zfsexecdir)/zed.d
|
||||||
|
|
||||||
dist_zedexec_SCRIPTS = \
|
dist_zedexec_SCRIPTS = \
|
||||||
%D%/all-debug.sh \
|
all-debug.sh \
|
||||||
%D%/all-syslog.sh \
|
all-syslog.sh \
|
||||||
%D%/data-notify.sh \
|
data-notify.sh \
|
||||||
%D%/generic-notify.sh \
|
generic-notify.sh \
|
||||||
%D%/pool_import-led.sh \
|
resilver_finish-notify.sh \
|
||||||
%D%/resilver_finish-notify.sh \
|
scrub_finish-notify.sh \
|
||||||
%D%/resilver_finish-start-scrub.sh \
|
statechange-led.sh \
|
||||||
%D%/scrub_finish-notify.sh \
|
statechange-notify.sh \
|
||||||
%D%/statechange-led.sh \
|
vdev_clear-led.sh \
|
||||||
%D%/statechange-notify.sh \
|
vdev_attach-led.sh \
|
||||||
%D%/statechange-slot_off.sh \
|
pool_import-led.sh \
|
||||||
%D%/trim_finish-notify.sh \
|
resilver_finish-start-scrub.sh \
|
||||||
%D%/vdev_attach-led.sh \
|
trim_finish-notify.sh
|
||||||
%D%/vdev_clear-led.sh
|
|
||||||
|
|
||||||
nodist_zedexec_SCRIPTS = \
|
nodist_zedexec_SCRIPTS = history_event-zfs-list-cacher.sh
|
||||||
%D%/history_event-zfs-list-cacher.sh
|
|
||||||
|
|
||||||
SUBSTFILES += $(nodist_zedexec_SCRIPTS)
|
SUBSTFILES += $(nodist_zedexec_SCRIPTS)
|
||||||
|
|
||||||
@@ -30,28 +35,23 @@ zedconfdefaults = \
|
|||||||
all-syslog.sh \
|
all-syslog.sh \
|
||||||
data-notify.sh \
|
data-notify.sh \
|
||||||
history_event-zfs-list-cacher.sh \
|
history_event-zfs-list-cacher.sh \
|
||||||
pool_import-led.sh \
|
|
||||||
resilver_finish-notify.sh \
|
resilver_finish-notify.sh \
|
||||||
resilver_finish-start-scrub.sh \
|
|
||||||
scrub_finish-notify.sh \
|
scrub_finish-notify.sh \
|
||||||
statechange-led.sh \
|
statechange-led.sh \
|
||||||
statechange-notify.sh \
|
statechange-notify.sh \
|
||||||
statechange-slot_off.sh \
|
vdev_clear-led.sh \
|
||||||
vdev_attach-led.sh \
|
vdev_attach-led.sh \
|
||||||
vdev_clear-led.sh
|
pool_import-led.sh \
|
||||||
|
resilver_finish-start-scrub.sh
|
||||||
|
|
||||||
dist_noinst_DATA += %D%/README
|
install-data-hook:
|
||||||
|
|
||||||
INSTALL_DATA_HOOKS += zed-install-data-hook
|
|
||||||
zed-install-data-hook:
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(zedconfdir)"
|
$(MKDIR_P) "$(DESTDIR)$(zedconfdir)"
|
||||||
set -x; for f in $(zedconfdefaults); do \
|
for f in $(zedconfdefaults); do \
|
||||||
[ -f "$(DESTDIR)$(zedconfdir)/$${f}" ] ||\
|
test -f "$(DESTDIR)$(zedconfdir)/$${f}" -o \
|
||||||
[ -L "$(DESTDIR)$(zedconfdir)/$${f}" ] || \
|
-L "$(DESTDIR)$(zedconfdir)/$${f}" || \
|
||||||
$(LN_S) "$(zedexecdir)/$${f}" "$(DESTDIR)$(zedconfdir)"; \
|
ln -s "$(zedexecdir)/$${f}" "$(DESTDIR)$(zedconfdir)"; \
|
||||||
done
|
done
|
||||||
|
chmod 0600 "$(DESTDIR)$(zedconfdir)/zed.rc"
|
||||||
|
|
||||||
SHELLCHECKSCRIPTS += $(dist_zedconf_DATA) $(dist_zedexec_SCRIPTS) $(nodist_zedexec_SCRIPTS)
|
|
||||||
$(call SHELLCHECK_OPTS,$(dist_zedconf_DATA) $(dist_zedexec_SCRIPTS) $(nodist_zedexec_SCRIPTS)): SHELLCHECK_SHELL = sh
|
|
||||||
# False positive: 1>&"${ZED_FLOCK_FD}" looks suspiciously similar to a >&filename bash extension
|
# False positive: 1>&"${ZED_FLOCK_FD}" looks suspiciously similar to a >&filename bash extension
|
||||||
$(call SHELLCHECK_OPTS,$(dist_zedconf_DATA) $(dist_zedexec_SCRIPTS) $(nodist_zedexec_SCRIPTS)): CHECKBASHISMS_IGNORE = -e 'should be >word 2>&1' -e '&"$${ZED_FLOCK_FD}"'
|
CHECKBASHISMS_IGNORE = -e 'should be >word 2>&1' -e '&"$${ZED_FLOCK_FD}"'
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# shellcheck disable=SC2154
|
|
||||||
#
|
#
|
||||||
# Log all environment variables to ZED_DEBUG_LOG.
|
# Log all environment variables to ZED_DEBUG_LOG.
|
||||||
#
|
#
|
||||||
@@ -15,7 +14,7 @@ zed_exit_if_ignoring_this_event
|
|||||||
|
|
||||||
zed_lock "${ZED_DEBUG_LOG}"
|
zed_lock "${ZED_DEBUG_LOG}"
|
||||||
{
|
{
|
||||||
env | sort
|
printenv | sort
|
||||||
echo
|
echo
|
||||||
} 1>&"${ZED_FLOCK_FD}"
|
} 1>&"${ZED_FLOCK_FD}"
|
||||||
zed_unlock "${ZED_DEBUG_LOG}"
|
zed_unlock "${ZED_DEBUG_LOG}"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# shellcheck disable=SC2154
|
|
||||||
#
|
#
|
||||||
# Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
|
# Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
|
||||||
# Copyright (c) 2020 by Delphix. All rights reserved.
|
# Copyright (c) 2020 by Delphix. All rights reserved.
|
||||||
@@ -22,7 +21,7 @@ if [ "${ZED_SYSLOG_DISPLAY_GUIDS}" = "1" ]; then
|
|||||||
[ -n "${ZEVENT_VDEV_GUID}" ] && msg="${msg} vdev_guid=${ZEVENT_VDEV_GUID}"
|
[ -n "${ZEVENT_VDEV_GUID}" ] && msg="${msg} vdev_guid=${ZEVENT_VDEV_GUID}"
|
||||||
else
|
else
|
||||||
[ -n "${ZEVENT_POOL}" ] && msg="${msg} pool='${ZEVENT_POOL}'"
|
[ -n "${ZEVENT_POOL}" ] && msg="${msg} pool='${ZEVENT_POOL}'"
|
||||||
[ -n "${ZEVENT_VDEV_PATH}" ] && msg="${msg} vdev=${ZEVENT_VDEV_PATH##*/}"
|
[ -n "${ZEVENT_VDEV_PATH}" ] && msg="${msg} vdev=$(basename "${ZEVENT_VDEV_PATH}")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# log pool state if state is anything other than 'ACTIVE'
|
# log pool state if state is anything other than 'ACTIVE'
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# shellcheck disable=SC2154
|
|
||||||
#
|
#
|
||||||
# Send notification in response to a DATA error.
|
# Send notification in response to a DATA error.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# shellcheck disable=SC2154
|
|
||||||
#
|
#
|
||||||
# Send notification in response to a given zevent.
|
# Send notification in response to a given zevent.
|
||||||
#
|
#
|
||||||
@@ -24,7 +23,7 @@
|
|||||||
|
|
||||||
# Rate-limit the notification based in part on the filename.
|
# Rate-limit the notification based in part on the filename.
|
||||||
#
|
#
|
||||||
rate_limit_tag="${ZEVENT_POOL};${ZEVENT_SUBCLASS};${0##*/}"
|
rate_limit_tag="${ZEVENT_POOL};${ZEVENT_SUBCLASS};$(basename -- "$0")"
|
||||||
rate_limit_interval="${ZED_NOTIFY_INTERVAL_SECS}"
|
rate_limit_interval="${ZED_NOTIFY_INTERVAL_SECS}"
|
||||||
zed_rate_limit "${rate_limit_tag}" "${rate_limit_interval}" || exit 3
|
zed_rate_limit "${rate_limit_tag}" "${rate_limit_interval}" || exit 3
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# shellcheck disable=SC2154
|
|
||||||
#
|
#
|
||||||
# Track changes to enumerated pools for use in early-boot
|
# Track changes to enumerated pools for use in early-boot
|
||||||
set -ef
|
set -ef
|
||||||
@@ -73,7 +72,7 @@ PROPS="name,mountpoint,canmount,atime,relatime,devices,exec\
|
|||||||
,org.openzfs.systemd:wanted-by,org.openzfs.systemd:required-by\
|
,org.openzfs.systemd:wanted-by,org.openzfs.systemd:required-by\
|
||||||
,org.openzfs.systemd:nofail,org.openzfs.systemd:ignore"
|
,org.openzfs.systemd:nofail,org.openzfs.systemd:ignore"
|
||||||
|
|
||||||
"${ZFS}" list -H -t filesystem -o "${PROPS}" -r "${ZEVENT_POOL}" > "${FSLIST_TMP}"
|
"${ZFS}" list -H -t filesystem -o $PROPS -r "${ZEVENT_POOL}" > "${FSLIST_TMP}"
|
||||||
|
|
||||||
# Sort the output so that it is stable
|
# Sort the output so that it is stable
|
||||||
sort "${FSLIST_TMP}" -o "${FSLIST_TMP}"
|
sort "${FSLIST_TMP}" -o "${FSLIST_TMP}"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# shellcheck disable=SC2154
|
|
||||||
# resilver_finish-start-scrub.sh
|
# resilver_finish-start-scrub.sh
|
||||||
# Run a scrub after a resilver
|
# Run a scrub after a resilver
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# shellcheck disable=SC2154
|
|
||||||
#
|
#
|
||||||
# Send notification in response to a RESILVER_FINISH or SCRUB_FINISH.
|
# Send notification in response to a RESILVER_FINISH or SCRUB_FINISH.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# shellcheck disable=SC2154
|
|
||||||
#
|
#
|
||||||
# Turn off/on vdevs' enclosure fault LEDs when their pool's state changes.
|
# Turn off/on vdevs' enclosure fault LEDs when their pool's state changes.
|
||||||
#
|
#
|
||||||
@@ -30,8 +29,7 @@
|
|||||||
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
|
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
|
||||||
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
|
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
|
||||||
|
|
||||||
if [ ! -d /sys/class/enclosure ] && [ ! -d /sys/bus/pci/slots ] ; then
|
if [ ! -d /sys/class/enclosure ] ; then
|
||||||
# No JBOD enclosure or NVMe slots
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -94,75 +92,19 @@ check_and_set_led()
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# Fault LEDs for JBODs and NVMe drives are handled a little differently.
|
|
||||||
#
|
|
||||||
# On JBODs the fault LED is called 'fault' and on a path like this:
|
|
||||||
#
|
|
||||||
# /sys/class/enclosure/0:0:1:0/SLOT 10/fault
|
|
||||||
#
|
|
||||||
# On NVMe it's called 'attention' and on a path like this:
|
|
||||||
#
|
|
||||||
# /sys/bus/pci/slot/0/attention
|
|
||||||
#
|
|
||||||
# This function returns the full path to the fault LED file for a given
|
|
||||||
# enclosure/slot directory.
|
|
||||||
#
|
|
||||||
path_to_led()
|
|
||||||
{
|
|
||||||
dir=$1
|
|
||||||
if [ -f "$dir/fault" ] ; then
|
|
||||||
echo "$dir/fault"
|
|
||||||
elif [ -f "$dir/attention" ] ; then
|
|
||||||
echo "$dir/attention"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
state_to_val()
|
state_to_val()
|
||||||
{
|
{
|
||||||
state="$1"
|
state="$1"
|
||||||
case "$state" in
|
case "$state" in
|
||||||
FAULTED|DEGRADED|UNAVAIL|REMOVED)
|
FAULTED|DEGRADED|UNAVAIL)
|
||||||
echo 1
|
echo 1
|
||||||
;;
|
;;
|
||||||
ONLINE)
|
ONLINE)
|
||||||
echo 0
|
echo 0
|
||||||
;;
|
;;
|
||||||
*)
|
|
||||||
echo "invalid state: $state"
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
# Given a nvme name like 'nvme0n1', pass back its slot directory
|
|
||||||
# like "/sys/bus/pci/slots/0"
|
|
||||||
#
|
|
||||||
nvme_dev_to_slot()
|
|
||||||
{
|
|
||||||
dev="$1"
|
|
||||||
|
|
||||||
# Get the address "0000:01:00.0"
|
|
||||||
read -r address < "/sys/class/block/$dev/device/address"
|
|
||||||
|
|
||||||
find /sys/bus/pci/slots -regex '.*/[0-9]+/address$' | \
|
|
||||||
while read -r sys_addr; do
|
|
||||||
read -r this_address < "$sys_addr"
|
|
||||||
|
|
||||||
# The format of address is a little different between
|
|
||||||
# /sys/class/block/$dev/device/address and
|
|
||||||
# /sys/bus/pci/slots/
|
|
||||||
#
|
|
||||||
# address= "0000:01:00.0"
|
|
||||||
# this_address = "0000:01:00"
|
|
||||||
#
|
|
||||||
if echo "$address" | grep -Eq ^"$this_address" ; then
|
|
||||||
echo "${sys_addr%/*}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# process_pool (pool)
|
# process_pool (pool)
|
||||||
#
|
#
|
||||||
# Iterate through a pool and set the vdevs' enclosure slot LEDs to
|
# Iterate through a pool and set the vdevs' enclosure slot LEDs to
|
||||||
@@ -192,11 +134,6 @@ process_pool()
|
|||||||
# Get dev name (like 'sda')
|
# Get dev name (like 'sda')
|
||||||
dev=$(basename "$(echo "$therest" | awk '{print $(NF-1)}')")
|
dev=$(basename "$(echo "$therest" | awk '{print $(NF-1)}')")
|
||||||
vdev_enc_sysfs_path=$(realpath "/sys/class/block/$dev/device/enclosure_device"*)
|
vdev_enc_sysfs_path=$(realpath "/sys/class/block/$dev/device/enclosure_device"*)
|
||||||
if [ ! -d "$vdev_enc_sysfs_path" ] ; then
|
|
||||||
# This is not a JBOD disk, but it could be a PCI NVMe drive
|
|
||||||
vdev_enc_sysfs_path=$(nvme_dev_to_slot "$dev")
|
|
||||||
fi
|
|
||||||
|
|
||||||
current_val=$(echo "$therest" | awk '{print $NF}')
|
current_val=$(echo "$therest" | awk '{print $NF}')
|
||||||
|
|
||||||
if [ "$current_val" != "0" ] ; then
|
if [ "$current_val" != "0" ] ; then
|
||||||
@@ -208,10 +145,9 @@ process_pool()
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
led_path=$(path_to_led "$vdev_enc_sysfs_path")
|
if [ ! -e "$vdev_enc_sysfs_path/fault" ] ; then
|
||||||
if [ ! -e "$led_path" ] ; then
|
|
||||||
rc=3
|
rc=3
|
||||||
zed_log_msg "vdev $vdev '$led_path' doesn't exist"
|
zed_log_msg "vdev $vdev '$file/fault' doesn't exist"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -222,7 +158,7 @@ process_pool()
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! check_and_set_led "$led_path" "$val"; then
|
if ! check_and_set_led "$vdev_enc_sysfs_path/fault" "$val"; then
|
||||||
rc=3
|
rc=3
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -233,8 +169,7 @@ if [ -n "$ZEVENT_VDEV_ENC_SYSFS_PATH" ] && [ -n "$ZEVENT_VDEV_STATE_STR" ] ; the
|
|||||||
# Got a statechange for an individual vdev
|
# Got a statechange for an individual vdev
|
||||||
val=$(state_to_val "$ZEVENT_VDEV_STATE_STR")
|
val=$(state_to_val "$ZEVENT_VDEV_STATE_STR")
|
||||||
vdev=$(basename "$ZEVENT_VDEV_PATH")
|
vdev=$(basename "$ZEVENT_VDEV_PATH")
|
||||||
ledpath=$(path_to_led "$ZEVENT_VDEV_ENC_SYSFS_PATH")
|
check_and_set_led "$ZEVENT_VDEV_ENC_SYSFS_PATH/fault" "$val"
|
||||||
check_and_set_led "$ledpath" "$val"
|
|
||||||
else
|
else
|
||||||
# Process the entire pool
|
# Process the entire pool
|
||||||
poolname=$(zed_guid_to_pool "$ZEVENT_POOL_GUID")
|
poolname=$(zed_guid_to_pool "$ZEVENT_POOL_GUID")
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# shellcheck disable=SC2154
|
|
||||||
#
|
#
|
||||||
# CDDL HEADER START
|
# CDDL HEADER START
|
||||||
#
|
#
|
||||||
@@ -16,7 +15,7 @@
|
|||||||
# Send notification in response to a fault induced statechange
|
# Send notification in response to a fault induced statechange
|
||||||
#
|
#
|
||||||
# ZEVENT_SUBCLASS: 'statechange'
|
# ZEVENT_SUBCLASS: 'statechange'
|
||||||
# ZEVENT_VDEV_STATE_STR: 'DEGRADED', 'FAULTED', 'REMOVED', or 'UNAVAIL'
|
# ZEVENT_VDEV_STATE_STR: 'DEGRADED', 'FAULTED' or 'REMOVED'
|
||||||
#
|
#
|
||||||
# Exit codes:
|
# Exit codes:
|
||||||
# 0: notification sent
|
# 0: notification sent
|
||||||
@@ -32,13 +31,12 @@
|
|||||||
|
|
||||||
if [ "${ZEVENT_VDEV_STATE_STR}" != "FAULTED" ] \
|
if [ "${ZEVENT_VDEV_STATE_STR}" != "FAULTED" ] \
|
||||||
&& [ "${ZEVENT_VDEV_STATE_STR}" != "DEGRADED" ] \
|
&& [ "${ZEVENT_VDEV_STATE_STR}" != "DEGRADED" ] \
|
||||||
&& [ "${ZEVENT_VDEV_STATE_STR}" != "REMOVED" ] \
|
&& [ "${ZEVENT_VDEV_STATE_STR}" != "REMOVED" ]; then
|
||||||
&& [ "${ZEVENT_VDEV_STATE_STR}" != "UNAVAIL" ]; then
|
|
||||||
exit 3
|
exit 3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
umask 077
|
umask 077
|
||||||
note_subject="ZFS device fault for pool ${ZEVENT_POOL} on $(hostname)"
|
note_subject="ZFS device fault for pool ${ZEVENT_POOL_GUID} on $(hostname)"
|
||||||
note_pathname="$(mktemp)"
|
note_pathname="$(mktemp)"
|
||||||
{
|
{
|
||||||
if [ "${ZEVENT_VDEV_STATE_STR}" = "FAULTED" ] ; then
|
if [ "${ZEVENT_VDEV_STATE_STR}" = "FAULTED" ] ; then
|
||||||
@@ -66,7 +64,7 @@ note_pathname="$(mktemp)"
|
|||||||
[ -n "${ZEVENT_VDEV_GUID}" ] && echo " vguid: ${ZEVENT_VDEV_GUID}"
|
[ -n "${ZEVENT_VDEV_GUID}" ] && echo " vguid: ${ZEVENT_VDEV_GUID}"
|
||||||
[ -n "${ZEVENT_VDEV_DEVID}" ] && echo " devid: ${ZEVENT_VDEV_DEVID}"
|
[ -n "${ZEVENT_VDEV_DEVID}" ] && echo " devid: ${ZEVENT_VDEV_DEVID}"
|
||||||
|
|
||||||
echo " pool: ${ZEVENT_POOL} (${ZEVENT_POOL_GUID})"
|
echo " pool: ${ZEVENT_POOL_GUID}"
|
||||||
|
|
||||||
} > "${note_pathname}"
|
} > "${note_pathname}"
|
||||||
|
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# shellcheck disable=SC3014,SC2154,SC2086,SC2034
|
|
||||||
#
|
|
||||||
# Turn off disk's enclosure slot if it becomes FAULTED.
|
|
||||||
#
|
|
||||||
# Bad SCSI disks can often "disappear and reappear" causing all sorts of chaos
|
|
||||||
# as they flip between FAULTED and ONLINE. If
|
|
||||||
# ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT is set in zed.rc, and the disk gets
|
|
||||||
# FAULTED, then power down the slot via sysfs:
|
|
||||||
#
|
|
||||||
# /sys/class/enclosure/<enclosure>/<slot>/power_status
|
|
||||||
#
|
|
||||||
# We assume the user will be responsible for turning the slot back on again.
|
|
||||||
#
|
|
||||||
# Note that this script requires that your enclosure be supported by the
|
|
||||||
# Linux SCSI Enclosure services (SES) driver. The script will do nothing
|
|
||||||
# if you have no enclosure, or if your enclosure isn't supported.
|
|
||||||
#
|
|
||||||
# Exit codes:
|
|
||||||
# 0: slot successfully powered off
|
|
||||||
# 1: enclosure not available
|
|
||||||
# 2: ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT disabled
|
|
||||||
# 3: vdev was not FAULTED
|
|
||||||
# 4: The enclosure sysfs path passed from ZFS does not exist
|
|
||||||
# 5: Enclosure slot didn't actually turn off after we told it to
|
|
||||||
|
|
||||||
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
|
|
||||||
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
|
|
||||||
|
|
||||||
if [ ! -d /sys/class/enclosure ] ; then
|
|
||||||
# No JBOD enclosure or NVMe slots
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT}" != "1" ] ; then
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$ZEVENT_VDEV_STATE_STR" != "FAULTED" ] ; then
|
|
||||||
exit 3
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "$ZEVENT_VDEV_ENC_SYSFS_PATH/power_status" ] ; then
|
|
||||||
exit 4
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Turn off the slot and wait for sysfs to report that the slot is off.
|
|
||||||
# It can take ~400ms on some enclosures and multiple retries may be needed.
|
|
||||||
for i in $(seq 1 20) ; do
|
|
||||||
echo "off" | tee "$ZEVENT_VDEV_ENC_SYSFS_PATH/power_status"
|
|
||||||
|
|
||||||
for j in $(seq 1 5) ; do
|
|
||||||
if [ "$(cat $ZEVENT_VDEV_ENC_SYSFS_PATH/power_status)" == "off" ] ; then
|
|
||||||
break 2
|
|
||||||
fi
|
|
||||||
sleep 0.1
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "$(cat $ZEVENT_VDEV_ENC_SYSFS_PATH/power_status)" != "off" ] ; then
|
|
||||||
exit 5
|
|
||||||
fi
|
|
||||||
|
|
||||||
zed_log_msg "powered down slot $ZEVENT_VDEV_ENC_SYSFS_PATH for $ZEVENT_VDEV_PATH"
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# shellcheck disable=SC2154
|
|
||||||
#
|
#
|
||||||
# Send notification in response to a TRIM_FINISH. The event
|
# Send notification in response to a TRIM_FINISH. The event
|
||||||
# will be received for each vdev in the pool which was trimmed.
|
# will be received for each vdev in the pool which was trimmed.
|
||||||
|
|||||||
+10
-202
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# shellcheck disable=SC2154,SC3043
|
# shellcheck disable=SC2039
|
||||||
# zed-functions.sh
|
# zed-functions.sh
|
||||||
#
|
#
|
||||||
# ZED helper functions for use in ZEDLETs
|
# ZED helper functions for use in ZEDLETs
|
||||||
@@ -76,7 +76,8 @@ zed_log_msg()
|
|||||||
#
|
#
|
||||||
zed_log_err()
|
zed_log_err()
|
||||||
{
|
{
|
||||||
zed_log_msg "error: ${0##*/}:""${ZEVENT_EID:+" eid=${ZEVENT_EID}:"}" "$@"
|
logger -p "${ZED_SYSLOG_PRIORITY}" -t "${ZED_SYSLOG_TAG}" -- "error:" \
|
||||||
|
"$(basename -- "$0"):""${ZEVENT_EID:+" eid=${ZEVENT_EID}:"}" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -201,14 +202,6 @@ zed_notify()
|
|||||||
[ "${rv}" -eq 0 ] && num_success=$((num_success + 1))
|
[ "${rv}" -eq 0 ] && num_success=$((num_success + 1))
|
||||||
[ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1))
|
[ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1))
|
||||||
|
|
||||||
zed_notify_pushover "${subject}" "${pathname}"; rv=$?
|
|
||||||
[ "${rv}" -eq 0 ] && num_success=$((num_success + 1))
|
|
||||||
[ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1))
|
|
||||||
|
|
||||||
zed_notify_ntfy "${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
|
||||||
@@ -227,8 +220,6 @@ zed_notify()
|
|||||||
# ZED_EMAIL_OPTS. This undergoes the following keyword substitutions:
|
# ZED_EMAIL_OPTS. This undergoes the following keyword substitutions:
|
||||||
# - @ADDRESS@ is replaced with the space-delimited recipient email address(es)
|
# - @ADDRESS@ is replaced with the space-delimited recipient email address(es)
|
||||||
# - @SUBJECT@ is replaced with the notification subject
|
# - @SUBJECT@ is replaced with the notification subject
|
||||||
# If @SUBJECT@ was omited here, a "Subject: ..." header will be added to notification
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
# Arguments
|
# Arguments
|
||||||
# subject: notification subject
|
# subject: notification subject
|
||||||
@@ -246,7 +237,7 @@ zed_notify()
|
|||||||
#
|
#
|
||||||
zed_notify_email()
|
zed_notify_email()
|
||||||
{
|
{
|
||||||
local subject="${1:-"ZED notification"}"
|
local subject="$1"
|
||||||
local pathname="${2:-"/dev/null"}"
|
local pathname="${2:-"/dev/null"}"
|
||||||
|
|
||||||
: "${ZED_EMAIL_PROG:="mail"}"
|
: "${ZED_EMAIL_PROG:="mail"}"
|
||||||
@@ -263,30 +254,19 @@ zed_notify_email()
|
|||||||
[ -n "${subject}" ] || return 1
|
[ -n "${subject}" ] || return 1
|
||||||
if [ ! -r "${pathname}" ]; then
|
if [ ! -r "${pathname}" ]; then
|
||||||
zed_log_err \
|
zed_log_err \
|
||||||
"${ZED_EMAIL_PROG##*/} cannot read \"${pathname}\""
|
"$(basename "${ZED_EMAIL_PROG}") cannot read \"${pathname}\""
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# construct cmdline options
|
ZED_EMAIL_OPTS="$(echo "${ZED_EMAIL_OPTS}" \
|
||||||
ZED_EMAIL_OPTS_PARSED="$(echo "${ZED_EMAIL_OPTS}" \
|
|
||||||
| sed -e "s/@ADDRESS@/${ZED_EMAIL_ADDR}/g" \
|
| sed -e "s/@ADDRESS@/${ZED_EMAIL_ADDR}/g" \
|
||||||
-e "s/@SUBJECT@/${subject}/g")"
|
-e "s/@SUBJECT@/${subject}/g")"
|
||||||
|
|
||||||
# pipe message to email prog
|
# shellcheck disable=SC2086
|
||||||
# shellcheck disable=SC2086,SC2248
|
eval ${ZED_EMAIL_PROG} ${ZED_EMAIL_OPTS} < "${pathname}" >/dev/null 2>&1
|
||||||
{
|
|
||||||
# no subject passed as option?
|
|
||||||
if [ "${ZED_EMAIL_OPTS%@SUBJECT@*}" = "${ZED_EMAIL_OPTS}" ] ; then
|
|
||||||
# inject subject header
|
|
||||||
printf "Subject: %s\n" "${subject}"
|
|
||||||
fi
|
|
||||||
# output message
|
|
||||||
cat "${pathname}"
|
|
||||||
} |
|
|
||||||
eval ${ZED_EMAIL_PROG} ${ZED_EMAIL_OPTS_PARSED} >/dev/null 2>&1
|
|
||||||
rv=$?
|
rv=$?
|
||||||
if [ "${rv}" -ne 0 ]; then
|
if [ "${rv}" -ne 0 ]; then
|
||||||
zed_log_err "${ZED_EMAIL_PROG##*/} exit=${rv}"
|
zed_log_err "$(basename "${ZED_EMAIL_PROG}") exit=${rv}"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
return 0
|
return 0
|
||||||
@@ -433,7 +413,7 @@ zed_notify_slack_webhook()
|
|||||||
|
|
||||||
# Construct the JSON message for posting.
|
# Construct the JSON message for posting.
|
||||||
#
|
#
|
||||||
msg_json="$(printf '{"text": "*%s*\\n%s"}' "${subject}" "${msg_body}" )"
|
msg_json="$(printf '{"text": "*%s*\n%s"}' "${subject}" "${msg_body}" )"
|
||||||
|
|
||||||
# Send the POST request and check for errors.
|
# Send the POST request and check for errors.
|
||||||
#
|
#
|
||||||
@@ -453,178 +433,6 @@ zed_notify_slack_webhook()
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# zed_notify_pushover (subject, pathname)
|
|
||||||
#
|
|
||||||
# Send a notification via Pushover <https://pushover.net/>.
|
|
||||||
# The access token (ZED_PUSHOVER_TOKEN) identifies this client to the
|
|
||||||
# Pushover server. The user token (ZED_PUSHOVER_USER) defines the user or
|
|
||||||
# group to which the notification will be sent.
|
|
||||||
#
|
|
||||||
# Requires curl and sed executables to be installed in the standard PATH.
|
|
||||||
#
|
|
||||||
# References
|
|
||||||
# https://pushover.net/api
|
|
||||||
#
|
|
||||||
# Arguments
|
|
||||||
# subject: notification subject
|
|
||||||
# pathname: pathname containing the notification message (OPTIONAL)
|
|
||||||
#
|
|
||||||
# Globals
|
|
||||||
# ZED_PUSHOVER_TOKEN
|
|
||||||
# ZED_PUSHOVER_USER
|
|
||||||
#
|
|
||||||
# Return
|
|
||||||
# 0: notification sent
|
|
||||||
# 1: notification failed
|
|
||||||
# 2: not configured
|
|
||||||
#
|
|
||||||
zed_notify_pushover()
|
|
||||||
{
|
|
||||||
local subject="$1"
|
|
||||||
local pathname="${2:-"/dev/null"}"
|
|
||||||
local msg_body
|
|
||||||
local msg_out
|
|
||||||
local msg_err
|
|
||||||
local url="https://api.pushover.net/1/messages.json"
|
|
||||||
|
|
||||||
[ -n "${ZED_PUSHOVER_TOKEN}" ] && [ -n "${ZED_PUSHOVER_USER}" ] || return 2
|
|
||||||
|
|
||||||
if [ ! -r "${pathname}" ]; then
|
|
||||||
zed_log_err "pushover cannot read \"${pathname}\""
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
zed_check_cmd "curl" "sed" || return 1
|
|
||||||
|
|
||||||
# Read the message body in.
|
|
||||||
#
|
|
||||||
msg_body="$(cat "${pathname}")"
|
|
||||||
|
|
||||||
if [ -z "${msg_body}" ]
|
|
||||||
then
|
|
||||||
msg_body=$subject
|
|
||||||
subject=""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Send the POST request and check for errors.
|
|
||||||
#
|
|
||||||
msg_out="$( \
|
|
||||||
curl \
|
|
||||||
--form-string "token=${ZED_PUSHOVER_TOKEN}" \
|
|
||||||
--form-string "user=${ZED_PUSHOVER_USER}" \
|
|
||||||
--form-string "message=${msg_body}" \
|
|
||||||
--form-string "title=${subject}" \
|
|
||||||
"${url}" \
|
|
||||||
2>/dev/null \
|
|
||||||
)"; rv=$?
|
|
||||||
if [ "${rv}" -ne 0 ]; then
|
|
||||||
zed_log_err "curl exit=${rv}"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
msg_err="$(echo "${msg_out}" \
|
|
||||||
| sed -n -e 's/.*"errors" *:.*\[\(.*\)\].*/\1/p')"
|
|
||||||
if [ -n "${msg_err}" ]; then
|
|
||||||
zed_log_err "pushover \"${msg_err}"\"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# zed_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_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
|
||||||
|
|||||||
+7
-51
@@ -1,7 +1,8 @@
|
|||||||
##
|
##
|
||||||
# zed.rc – ZEDLET configuration.
|
# zed.rc
|
||||||
|
#
|
||||||
|
# This file should be owned by root and permissioned 0600.
|
||||||
##
|
##
|
||||||
# shellcheck disable=SC2034
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Absolute path to the debug output file.
|
# Absolute path to the debug output file.
|
||||||
@@ -12,9 +13,9 @@
|
|||||||
# Email address of the zpool administrator for receipt of notifications;
|
# Email address of the zpool administrator for receipt of notifications;
|
||||||
# multiple addresses can be specified if they are delimited by whitespace.
|
# multiple addresses can be specified if they are delimited by whitespace.
|
||||||
# Email will only be sent if ZED_EMAIL_ADDR is defined.
|
# Email will only be sent if ZED_EMAIL_ADDR is defined.
|
||||||
# Enabled by default; comment to disable.
|
# Disabled by default; uncomment to enable.
|
||||||
#
|
#
|
||||||
ZED_EMAIL_ADDR="root"
|
#ZED_EMAIL_ADDR="root"
|
||||||
|
|
||||||
##
|
##
|
||||||
# Name or path of executable responsible for sending notifications via email;
|
# Name or path of executable responsible for sending notifications via email;
|
||||||
@@ -29,7 +30,6 @@ ZED_EMAIL_ADDR="root"
|
|||||||
# The string @SUBJECT@ will be replaced with the notification subject;
|
# The string @SUBJECT@ will be replaced with the notification subject;
|
||||||
# this should be protected with quotes to prevent word-splitting.
|
# this should be protected with quotes to prevent word-splitting.
|
||||||
# Email will only be sent if ZED_EMAIL_ADDR is defined.
|
# Email will only be sent if ZED_EMAIL_ADDR is defined.
|
||||||
# If @SUBJECT@ was omited here, a "Subject: ..." header will be added to notification
|
|
||||||
#
|
#
|
||||||
#ZED_EMAIL_OPTS="-s '@SUBJECT@' @ADDRESS@"
|
#ZED_EMAIL_OPTS="-s '@SUBJECT@' @ADDRESS@"
|
||||||
|
|
||||||
@@ -82,23 +82,6 @@ ZED_EMAIL_ADDR="root"
|
|||||||
#
|
#
|
||||||
#ZED_SLACK_WEBHOOK_URL=""
|
#ZED_SLACK_WEBHOOK_URL=""
|
||||||
|
|
||||||
##
|
|
||||||
# Pushover token.
|
|
||||||
# This defines the application from which the notification will be sent.
|
|
||||||
# <https://pushover.net/api#registration>
|
|
||||||
# Disabled by default; uncomment to enable.
|
|
||||||
# ZED_PUSHOVER_USER, below, must also be configured.
|
|
||||||
#
|
|
||||||
#ZED_PUSHOVER_TOKEN=""
|
|
||||||
|
|
||||||
##
|
|
||||||
# Pushover user key.
|
|
||||||
# This defines which user or group will receive Pushover notifications.
|
|
||||||
# <https://pushover.net/api#identifiers>
|
|
||||||
# Disabled by default; uncomment to enable.
|
|
||||||
# ZED_PUSHOVER_TOKEN, above, must also be configured.
|
|
||||||
#ZED_PUSHOVER_USER=""
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Default directory for zed state files.
|
# Default directory for zed state files.
|
||||||
#
|
#
|
||||||
@@ -106,8 +89,8 @@ ZED_EMAIL_ADDR="root"
|
|||||||
|
|
||||||
##
|
##
|
||||||
# Turn on/off enclosure LEDs when drives get DEGRADED/FAULTED. This works for
|
# Turn on/off enclosure LEDs when drives get DEGRADED/FAULTED. This works for
|
||||||
# device mapper and multipath devices as well. This works with JBOD enclosures
|
# device mapper and multipath devices as well. Your enclosure must be
|
||||||
# and NVMe PCI drives (assuming they're supported by Linux in sysfs).
|
# supported by the Linux SES driver for this to work.
|
||||||
#
|
#
|
||||||
ZED_USE_ENCLOSURE_LEDS=1
|
ZED_USE_ENCLOSURE_LEDS=1
|
||||||
|
|
||||||
@@ -142,30 +125,3 @@ ZED_SYSLOG_SUBCLASS_EXCLUDE="history_event"
|
|||||||
# Disabled by default, 1 to enable and 0 to disable.
|
# Disabled by default, 1 to enable and 0 to disable.
|
||||||
#ZED_SYSLOG_DISPLAY_GUIDS=1
|
#ZED_SYSLOG_DISPLAY_GUIDS=1
|
||||||
|
|
||||||
##
|
|
||||||
# Power off the drive's slot in the enclosure if it becomes FAULTED. This can
|
|
||||||
# help silence misbehaving drives. This assumes your drive enclosure fully
|
|
||||||
# supports slot power control via sysfs.
|
|
||||||
#ZED_POWER_OFF_ENCLOSURE_SLOT_ON_FAULT=1
|
|
||||||
|
|
||||||
##
|
|
||||||
# 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"
|
|
||||||
|
|||||||
+3
-18
@@ -22,7 +22,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -48,7 +47,6 @@ zed_conf_init(struct zed_conf *zcp)
|
|||||||
zcp->zevent_fd = -1; /* opened in zed_event_init() */
|
zcp->zevent_fd = -1; /* opened in zed_event_init() */
|
||||||
|
|
||||||
zcp->max_jobs = 16;
|
zcp->max_jobs = 16;
|
||||||
zcp->max_zevent_buf_len = 1 << 20;
|
|
||||||
|
|
||||||
if (!(zcp->pid_file = strdup(ZED_PID_FILE)) ||
|
if (!(zcp->pid_file = strdup(ZED_PID_FILE)) ||
|
||||||
!(zcp->zedlet_dir = strdup(ZED_ZEDLET_DIR)) ||
|
!(zcp->zedlet_dir = strdup(ZED_ZEDLET_DIR)) ||
|
||||||
@@ -142,8 +140,6 @@ _zed_conf_display_help(const char *prog, boolean_t got_err)
|
|||||||
.v = ZED_STATE_FILE },
|
.v = ZED_STATE_FILE },
|
||||||
{ .o = "-j JOBS", .d = "Start at most JOBS at once.",
|
{ .o = "-j JOBS", .d = "Start at most JOBS at once.",
|
||||||
.v = "16" },
|
.v = "16" },
|
||||||
{ .o = "-b LEN", .d = "Cap kernel event buffer at LEN entries.",
|
|
||||||
.v = "1048576" },
|
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -233,7 +229,7 @@ _zed_conf_parse_path(char **resultp, const char *path)
|
|||||||
void
|
void
|
||||||
zed_conf_parse_opts(struct zed_conf *zcp, int argc, char **argv)
|
zed_conf_parse_opts(struct zed_conf *zcp, int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char * const opts = ":hLVd:p:P:s:vfFMZIj:b:";
|
const char * const opts = ":hLVd:p:P:s:vfFMZIj:";
|
||||||
int opt;
|
int opt;
|
||||||
unsigned long raw;
|
unsigned long raw;
|
||||||
|
|
||||||
@@ -294,17 +290,6 @@ zed_conf_parse_opts(struct zed_conf *zcp, int argc, char **argv)
|
|||||||
zcp->max_jobs = raw;
|
zcp->max_jobs = raw;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'b':
|
|
||||||
errno = 0;
|
|
||||||
raw = strtoul(optarg, NULL, 0);
|
|
||||||
if (errno == ERANGE || raw > INT32_MAX) {
|
|
||||||
zed_log_die("%lu is too large", raw);
|
|
||||||
} if (raw == 0) {
|
|
||||||
zcp->max_zevent_buf_len = INT32_MAX;
|
|
||||||
} else {
|
|
||||||
zcp->max_zevent_buf_len = raw;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
if (optopt == '?')
|
if (optopt == '?')
|
||||||
@@ -657,7 +642,7 @@ zed_conf_read_state(struct zed_conf *zcp, uint64_t *eidp, int64_t etime[])
|
|||||||
} else if (n != len) {
|
} else if (n != len) {
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
zed_log_msg(LOG_WARNING,
|
zed_log_msg(LOG_WARNING,
|
||||||
"Failed to read state file \"%s\": Read %zd of %zd bytes",
|
"Failed to read state file \"%s\": Read %d of %d bytes",
|
||||||
zcp->state_file, n, len);
|
zcp->state_file, n, len);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
@@ -706,7 +691,7 @@ zed_conf_write_state(struct zed_conf *zcp, uint64_t eid, int64_t etime[])
|
|||||||
if (n != len) {
|
if (n != len) {
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
zed_log_msg(LOG_WARNING,
|
zed_log_msg(LOG_WARNING,
|
||||||
"Failed to write state file \"%s\": Wrote %zd of %zd bytes",
|
"Failed to write state file \"%s\": Wrote %d of %d bytes",
|
||||||
zcp->state_file, n, len);
|
zcp->state_file, n, len);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ struct zed_conf {
|
|||||||
int zevent_fd; /* fd for access to zevents */
|
int zevent_fd; /* fd for access to zevents */
|
||||||
|
|
||||||
int16_t max_jobs; /* max zedlets to run at one time */
|
int16_t max_jobs; /* max zedlets to run at one time */
|
||||||
int32_t max_zevent_buf_len; /* max size of kernel event list */
|
|
||||||
|
|
||||||
boolean_t do_force:1; /* true if force enabled */
|
boolean_t do_force:1; /* true if force enabled */
|
||||||
boolean_t do_foreground:1; /* true if run in foreground */
|
boolean_t do_foreground:1; /* true if run in foreground */
|
||||||
|
|||||||
+15
-67
@@ -49,7 +49,7 @@ struct udev_monitor *g_mon;
|
|||||||
#define DEV_BYID_PATH "/dev/disk/by-id/"
|
#define DEV_BYID_PATH "/dev/disk/by-id/"
|
||||||
|
|
||||||
/* 64MB is minimum usable disk for ZFS */
|
/* 64MB is minimum usable disk for ZFS */
|
||||||
#define MINIMUM_SECTORS 131072ULL
|
#define MINIMUM_SECTORS 131072
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -60,7 +60,7 @@ struct udev_monitor *g_mon;
|
|||||||
static void
|
static void
|
||||||
zed_udev_event(const char *class, const char *subclass, nvlist_t *nvl)
|
zed_udev_event(const char *class, const char *subclass, nvlist_t *nvl)
|
||||||
{
|
{
|
||||||
const char *strval;
|
char *strval;
|
||||||
uint64_t numval;
|
uint64_t numval;
|
||||||
|
|
||||||
zed_log_msg(LOG_INFO, "zed_disk_event:");
|
zed_log_msg(LOG_INFO, "zed_disk_event:");
|
||||||
@@ -72,14 +72,10 @@ zed_udev_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||||||
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_PATH, strval);
|
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_PATH, strval);
|
||||||
if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &strval) == 0)
|
if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, &strval) == 0)
|
||||||
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_IDENTIFIER, strval);
|
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_IDENTIFIER, strval);
|
||||||
if (nvlist_lookup_boolean(nvl, DEV_IS_PART) == B_TRUE)
|
|
||||||
zed_log_msg(LOG_INFO, "\t%s: B_TRUE", DEV_IS_PART);
|
|
||||||
if (nvlist_lookup_string(nvl, DEV_PHYS_PATH, &strval) == 0)
|
if (nvlist_lookup_string(nvl, DEV_PHYS_PATH, &strval) == 0)
|
||||||
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_PHYS_PATH, strval);
|
zed_log_msg(LOG_INFO, "\t%s: %s", DEV_PHYS_PATH, strval);
|
||||||
if (nvlist_lookup_uint64(nvl, DEV_SIZE, &numval) == 0)
|
if (nvlist_lookup_uint64(nvl, DEV_SIZE, &numval) == 0)
|
||||||
zed_log_msg(LOG_INFO, "\t%s: %llu", DEV_SIZE, numval);
|
zed_log_msg(LOG_INFO, "\t%s: %llu", DEV_SIZE, numval);
|
||||||
if (nvlist_lookup_uint64(nvl, DEV_PARENT_SIZE, &numval) == 0)
|
|
||||||
zed_log_msg(LOG_INFO, "\t%s: %llu", DEV_PARENT_SIZE, numval);
|
|
||||||
if (nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &numval) == 0)
|
if (nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &numval) == 0)
|
||||||
zed_log_msg(LOG_INFO, "\t%s: %llu", ZFS_EV_POOL_GUID, numval);
|
zed_log_msg(LOG_INFO, "\t%s: %llu", ZFS_EV_POOL_GUID, numval);
|
||||||
if (nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &numval) == 0)
|
if (nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &numval) == 0)
|
||||||
@@ -132,20 +128,6 @@ dev_event_nvlist(struct udev_device *dev)
|
|||||||
|
|
||||||
numval *= strtoull(value, NULL, 10);
|
numval *= strtoull(value, NULL, 10);
|
||||||
(void) nvlist_add_uint64(nvl, DEV_SIZE, numval);
|
(void) nvlist_add_uint64(nvl, DEV_SIZE, numval);
|
||||||
|
|
||||||
/*
|
|
||||||
* If the device has a parent, then get the parent block
|
|
||||||
* device's size as well. For example, /dev/sda1's parent
|
|
||||||
* is /dev/sda.
|
|
||||||
*/
|
|
||||||
struct udev_device *parent_dev = udev_device_get_parent(dev);
|
|
||||||
if ((value = udev_device_get_sysattr_value(parent_dev, "size"))
|
|
||||||
!= NULL) {
|
|
||||||
uint64_t numval = DEV_BSIZE;
|
|
||||||
|
|
||||||
numval *= strtoull(value, NULL, 10);
|
|
||||||
(void) nvlist_add_uint64(nvl, DEV_PARENT_SIZE, numval);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -178,15 +160,14 @@ static void *
|
|||||||
zed_udev_monitor(void *arg)
|
zed_udev_monitor(void *arg)
|
||||||
{
|
{
|
||||||
struct udev_monitor *mon = arg;
|
struct udev_monitor *mon = arg;
|
||||||
const char *tmp;
|
char *tmp, *tmp2;
|
||||||
char *tmp2;
|
|
||||||
|
|
||||||
zed_log_msg(LOG_INFO, "Waiting for new udev disk events...");
|
zed_log_msg(LOG_INFO, "Waiting for new udev disk events...");
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
struct udev_device *dev;
|
struct udev_device *dev;
|
||||||
const char *action, *type, *part, *sectors;
|
const char *action, *type, *part, *sectors;
|
||||||
const char *bus, *uuid, *devpath;
|
const char *bus, *uuid;
|
||||||
const char *class, *subclass;
|
const char *class, *subclass;
|
||||||
nvlist_t *nvl;
|
nvlist_t *nvl;
|
||||||
boolean_t is_zfs = B_FALSE;
|
boolean_t is_zfs = B_FALSE;
|
||||||
@@ -225,12 +206,6 @@ zed_udev_monitor(void *arg)
|
|||||||
* if this is a disk and it is partitioned, then the
|
* if this is a disk and it is partitioned, then the
|
||||||
* zfs label will reside in a DEVTYPE=partition and
|
* zfs label will reside in a DEVTYPE=partition and
|
||||||
* we can skip passing this event
|
* we can skip passing this event
|
||||||
*
|
|
||||||
* Special case: Blank disks are sometimes reported with
|
|
||||||
* an erroneous 'atari' partition, and should not be
|
|
||||||
* excluded from being used as an autoreplace disk:
|
|
||||||
*
|
|
||||||
* https://github.com/openzfs/zfs/issues/13497
|
|
||||||
*/
|
*/
|
||||||
type = udev_device_get_property_value(dev, "DEVTYPE");
|
type = udev_device_get_property_value(dev, "DEVTYPE");
|
||||||
part = udev_device_get_property_value(dev,
|
part = udev_device_get_property_value(dev,
|
||||||
@@ -238,23 +213,9 @@ zed_udev_monitor(void *arg)
|
|||||||
if (type != NULL && type[0] != '\0' &&
|
if (type != NULL && type[0] != '\0' &&
|
||||||
strcmp(type, "disk") == 0 &&
|
strcmp(type, "disk") == 0 &&
|
||||||
part != NULL && part[0] != '\0') {
|
part != NULL && part[0] != '\0') {
|
||||||
const char *devname =
|
/* skip and wait for partition event */
|
||||||
udev_device_get_property_value(dev, "DEVNAME");
|
udev_device_unref(dev);
|
||||||
|
continue;
|
||||||
if (strcmp(part, "atari") == 0) {
|
|
||||||
zed_log_msg(LOG_INFO,
|
|
||||||
"%s: %s is reporting an atari partition, "
|
|
||||||
"but we're going to assume it's a false "
|
|
||||||
"positive and still use it (issue #13497)",
|
|
||||||
__func__, devname);
|
|
||||||
} else {
|
|
||||||
zed_log_msg(LOG_INFO,
|
|
||||||
"%s: skip %s since it has a %s partition "
|
|
||||||
"already", __func__, devname, part);
|
|
||||||
/* skip and wait for partition event */
|
|
||||||
udev_device_unref(dev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -266,11 +227,6 @@ zed_udev_monitor(void *arg)
|
|||||||
sectors = udev_device_get_sysattr_value(dev, "size");
|
sectors = udev_device_get_sysattr_value(dev, "size");
|
||||||
if (sectors != NULL &&
|
if (sectors != NULL &&
|
||||||
strtoull(sectors, NULL, 10) < MINIMUM_SECTORS) {
|
strtoull(sectors, NULL, 10) < MINIMUM_SECTORS) {
|
||||||
zed_log_msg(LOG_INFO,
|
|
||||||
"%s: %s sectors %s < %llu (minimum)",
|
|
||||||
__func__,
|
|
||||||
udev_device_get_property_value(dev, "DEVNAME"),
|
|
||||||
sectors, MINIMUM_SECTORS);
|
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -280,19 +236,10 @@ zed_udev_monitor(void *arg)
|
|||||||
* device id string is required in the message schema
|
* device id string is required in the message schema
|
||||||
* for matching with vdevs. Preflight here for expected
|
* for matching with vdevs. Preflight here for expected
|
||||||
* udev information.
|
* udev information.
|
||||||
*
|
|
||||||
* Special case:
|
|
||||||
* NVMe devices don't have ID_BUS set (at least on RHEL 7-8),
|
|
||||||
* but they are valid for autoreplace. Add a special case for
|
|
||||||
* them by searching for "/nvme/" in the udev DEVPATH:
|
|
||||||
*
|
|
||||||
* DEVPATH=/devices/pci0000:00/0000:00:1e.0/nvme/nvme2/nvme2n1
|
|
||||||
*/
|
*/
|
||||||
bus = udev_device_get_property_value(dev, "ID_BUS");
|
bus = udev_device_get_property_value(dev, "ID_BUS");
|
||||||
uuid = udev_device_get_property_value(dev, "DM_UUID");
|
uuid = udev_device_get_property_value(dev, "DM_UUID");
|
||||||
devpath = udev_device_get_devpath(dev);
|
if (!is_zfs && (bus == NULL && uuid == NULL)) {
|
||||||
if (!is_zfs && (bus == NULL && uuid == NULL &&
|
|
||||||
strstr(devpath, "/nvme/") == NULL)) {
|
|
||||||
zed_log_msg(LOG_INFO, "zed_udev_monitor: %s no devid "
|
zed_log_msg(LOG_INFO, "zed_udev_monitor: %s no devid "
|
||||||
"source", udev_device_get_devnode(dev));
|
"source", udev_device_get_devnode(dev));
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
@@ -337,7 +284,7 @@ zed_udev_monitor(void *arg)
|
|||||||
if (strcmp(class, EC_DEV_STATUS) == 0 &&
|
if (strcmp(class, EC_DEV_STATUS) == 0 &&
|
||||||
udev_device_get_property_value(dev, "DM_UUID") &&
|
udev_device_get_property_value(dev, "DM_UUID") &&
|
||||||
udev_device_get_property_value(dev, "MPATH_SBIN_PATH")) {
|
udev_device_get_property_value(dev, "MPATH_SBIN_PATH")) {
|
||||||
tmp = udev_device_get_devnode(dev);
|
tmp = (char *)udev_device_get_devnode(dev);
|
||||||
tmp2 = zfs_get_underlying_path(tmp);
|
tmp2 = zfs_get_underlying_path(tmp);
|
||||||
if (tmp && tmp2 && (strcmp(tmp, tmp2) != 0)) {
|
if (tmp && tmp2 && (strcmp(tmp, tmp2) != 0)) {
|
||||||
/*
|
/*
|
||||||
@@ -354,7 +301,8 @@ zed_udev_monitor(void *arg)
|
|||||||
class = EC_DEV_ADD;
|
class = EC_DEV_ADD;
|
||||||
subclass = ESC_DISK;
|
subclass = ESC_DISK;
|
||||||
} else {
|
} else {
|
||||||
tmp = udev_device_get_property_value(dev,
|
tmp = (char *)
|
||||||
|
udev_device_get_property_value(dev,
|
||||||
"DM_NR_VALID_PATHS");
|
"DM_NR_VALID_PATHS");
|
||||||
/* treat as a multipath remove */
|
/* treat as a multipath remove */
|
||||||
if (tmp != NULL && strcmp(tmp, "0") == 0) {
|
if (tmp != NULL && strcmp(tmp, "0") == 0) {
|
||||||
@@ -402,7 +350,7 @@ zed_udev_monitor(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
zed_disk_event_init(void)
|
zed_disk_event_init()
|
||||||
{
|
{
|
||||||
int fd, fflags;
|
int fd, fflags;
|
||||||
|
|
||||||
@@ -438,7 +386,7 @@ zed_disk_event_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zed_disk_event_fini(void)
|
zed_disk_event_fini()
|
||||||
{
|
{
|
||||||
/* cancel monitor thread at recvmsg() */
|
/* cancel monitor thread at recvmsg() */
|
||||||
(void) pthread_cancel(g_mon_tid);
|
(void) pthread_cancel(g_mon_tid);
|
||||||
@@ -456,13 +404,13 @@ zed_disk_event_fini(void)
|
|||||||
#include "zed_disk_event.h"
|
#include "zed_disk_event.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
zed_disk_event_init(void)
|
zed_disk_event_init()
|
||||||
{
|
{
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zed_disk_event_fini(void)
|
zed_disk_event_fini()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-59
@@ -35,12 +35,9 @@
|
|||||||
#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
|
||||||
|
|
||||||
static int max_zevent_buf_len = 1 << 20;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open the libzfs interface.
|
* Open the libzfs interface.
|
||||||
*/
|
*/
|
||||||
@@ -73,9 +70,6 @@ zed_event_init(struct zed_conf *zcp)
|
|||||||
zed_log_die("Failed to initialize disk events");
|
zed_log_die("Failed to initialize disk events");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zcp->max_zevent_buf_len != 0)
|
|
||||||
max_zevent_buf_len = zcp->max_zevent_buf_len;
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +105,7 @@ _bump_event_queue_length(void)
|
|||||||
{
|
{
|
||||||
int zzlm = -1, wr;
|
int zzlm = -1, wr;
|
||||||
char qlen_buf[12] = {0}; /* parameter is int => max "-2147483647\n" */
|
char qlen_buf[12] = {0}; /* parameter is int => max "-2147483647\n" */
|
||||||
long int qlen, orig_qlen;
|
long int qlen;
|
||||||
|
|
||||||
zzlm = open("/sys/module/zfs/parameters/zfs_zevent_len_max", O_RDWR);
|
zzlm = open("/sys/module/zfs/parameters/zfs_zevent_len_max", O_RDWR);
|
||||||
if (zzlm < 0)
|
if (zzlm < 0)
|
||||||
@@ -122,7 +116,7 @@ _bump_event_queue_length(void)
|
|||||||
qlen_buf[sizeof (qlen_buf) - 1] = '\0';
|
qlen_buf[sizeof (qlen_buf) - 1] = '\0';
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
orig_qlen = qlen = strtol(qlen_buf, NULL, 10);
|
qlen = strtol(qlen_buf, NULL, 10);
|
||||||
if (errno == ERANGE)
|
if (errno == ERANGE)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@@ -131,21 +125,11 @@ _bump_event_queue_length(void)
|
|||||||
else
|
else
|
||||||
qlen *= 2;
|
qlen *= 2;
|
||||||
|
|
||||||
/*
|
if (qlen > INT_MAX)
|
||||||
* Don't consume all of kernel memory with event logs if something
|
qlen = INT_MAX;
|
||||||
* goes wrong.
|
|
||||||
*/
|
|
||||||
if (qlen > max_zevent_buf_len)
|
|
||||||
qlen = max_zevent_buf_len;
|
|
||||||
if (qlen == orig_qlen)
|
|
||||||
goto done;
|
|
||||||
wr = snprintf(qlen_buf, sizeof (qlen_buf), "%ld", qlen);
|
wr = snprintf(qlen_buf, sizeof (qlen_buf), "%ld", qlen);
|
||||||
if (wr >= sizeof (qlen_buf)) {
|
|
||||||
wr = sizeof (qlen_buf) - 1;
|
|
||||||
zed_log_msg(LOG_WARNING, "Truncation in %s()", __func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pwrite(zzlm, qlen_buf, wr + 1, 0) < 0)
|
if (pwrite(zzlm, qlen_buf, wr, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
zed_log_msg(LOG_WARNING, "Bumping queue length to %ld", qlen);
|
zed_log_msg(LOG_WARNING, "Bumping queue length to %ld", qlen);
|
||||||
@@ -613,7 +597,7 @@ _zed_event_add_string_array(uint64_t eid, zed_strings_t *zsp,
|
|||||||
char buf[MAXBUF];
|
char buf[MAXBUF];
|
||||||
int buflen = sizeof (buf);
|
int buflen = sizeof (buf);
|
||||||
const char *name;
|
const char *name;
|
||||||
const char **strp;
|
char **strp;
|
||||||
uint_t nelem;
|
uint_t nelem;
|
||||||
uint_t i;
|
uint_t i;
|
||||||
char *p;
|
char *p;
|
||||||
@@ -653,7 +637,7 @@ _zed_event_add_nvpair(uint64_t eid, zed_strings_t *zsp, nvpair_t *nvp)
|
|||||||
uint16_t i16;
|
uint16_t i16;
|
||||||
uint32_t i32;
|
uint32_t i32;
|
||||||
uint64_t i64;
|
uint64_t i64;
|
||||||
const char *str;
|
char *str;
|
||||||
|
|
||||||
assert(zsp != NULL);
|
assert(zsp != NULL);
|
||||||
assert(nvp != NULL);
|
assert(nvp != NULL);
|
||||||
@@ -900,21 +884,21 @@ _zed_event_get_subclass(const char *class)
|
|||||||
static void
|
static void
|
||||||
_zed_event_add_time_strings(uint64_t eid, zed_strings_t *zsp, int64_t etime[])
|
_zed_event_add_time_strings(uint64_t eid, zed_strings_t *zsp, int64_t etime[])
|
||||||
{
|
{
|
||||||
struct tm stp;
|
struct tm *stp;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
|
||||||
assert(zsp != NULL);
|
assert(zsp != NULL);
|
||||||
assert(etime != NULL);
|
assert(etime != NULL);
|
||||||
|
|
||||||
_zed_event_add_var(eid, zsp, ZEVENT_VAR_PREFIX, "TIME_SECS",
|
_zed_event_add_var(eid, zsp, ZEVENT_VAR_PREFIX, "TIME_SECS",
|
||||||
"%" PRId64, etime[0]);
|
"%lld", (long long int) etime[0]);
|
||||||
_zed_event_add_var(eid, zsp, ZEVENT_VAR_PREFIX, "TIME_NSECS",
|
_zed_event_add_var(eid, zsp, ZEVENT_VAR_PREFIX, "TIME_NSECS",
|
||||||
"%" PRId64, etime[1]);
|
"%lld", (long long int) etime[1]);
|
||||||
|
|
||||||
if (!localtime_r((const time_t *) &etime[0], &stp)) {
|
if (!(stp = localtime((const time_t *) &etime[0]))) {
|
||||||
zed_log_msg(LOG_WARNING, "Failed to add %s%s for eid=%llu: %s",
|
zed_log_msg(LOG_WARNING, "Failed to add %s%s for eid=%llu: %s",
|
||||||
ZEVENT_VAR_PREFIX, "TIME_STRING", eid, "localtime error");
|
ZEVENT_VAR_PREFIX, "TIME_STRING", eid, "localtime error");
|
||||||
} else if (!strftime(buf, sizeof (buf), "%Y-%m-%d %H:%M:%S%z", &stp)) {
|
} else if (!strftime(buf, sizeof (buf), "%Y-%m-%d %H:%M:%S%z", stp)) {
|
||||||
zed_log_msg(LOG_WARNING, "Failed to add %s%s for eid=%llu: %s",
|
zed_log_msg(LOG_WARNING, "Failed to add %s%s for eid=%llu: %s",
|
||||||
ZEVENT_VAR_PREFIX, "TIME_STRING", eid, "strftime error");
|
ZEVENT_VAR_PREFIX, "TIME_STRING", eid, "strftime error");
|
||||||
} else {
|
} else {
|
||||||
@@ -923,25 +907,6 @@ _zed_event_add_time_strings(uint64_t eid, zed_strings_t *zsp, int64_t etime[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
_zed_event_update_enc_sysfs_path(nvlist_t *nvl)
|
|
||||||
{
|
|
||||||
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.
|
||||||
*/
|
*/
|
||||||
@@ -955,7 +920,7 @@ zed_event_service(struct zed_conf *zcp)
|
|||||||
uint64_t eid;
|
uint64_t eid;
|
||||||
int64_t *etime;
|
int64_t *etime;
|
||||||
uint_t nelem;
|
uint_t nelem;
|
||||||
const char *class;
|
char *class;
|
||||||
const char *subclass;
|
const char *subclass;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
@@ -989,17 +954,6 @@ zed_event_service(struct zed_conf *zcp)
|
|||||||
zed_log_msg(LOG_WARNING,
|
zed_log_msg(LOG_WARNING,
|
||||||
"Failed to lookup zevent class (eid=%llu)", eid);
|
"Failed to lookup zevent class (eid=%llu)", eid);
|
||||||
} else {
|
} else {
|
||||||
/*
|
|
||||||
* Special case: If we can dynamically detect an enclosure sysfs
|
|
||||||
* path, then use that value rather than the one stored in the
|
|
||||||
* vd->vdev_enc_sysfs_path. There have been rare cases where
|
|
||||||
* vd->vdev_enc_sysfs_path becomes outdated. However, there
|
|
||||||
* will be other times when we can not dynamically detect the
|
|
||||||
* sysfs path (like if a disk disappears) and have to rely on
|
|
||||||
* the old value for things like turning on the fault LED.
|
|
||||||
*/
|
|
||||||
_zed_event_update_enc_sysfs_path(nvl);
|
|
||||||
|
|
||||||
/* let internal modules see this event first */
|
/* let internal modules see this event first */
|
||||||
zfs_agent_post_event(class, NULL, nvl);
|
zfs_agent_post_event(class, NULL, nvl);
|
||||||
|
|
||||||
|
|||||||
+2
-11
@@ -26,8 +26,6 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include "zed_exec.h"
|
#include "zed_exec.h"
|
||||||
#include "zed_log.h"
|
#include "zed_log.h"
|
||||||
#include "zed_strings.h"
|
#include "zed_strings.h"
|
||||||
@@ -175,10 +173,6 @@ _zed_exec_fork_child(uint64_t eid, const char *dir, const char *prog,
|
|||||||
node->pid = pid;
|
node->pid = pid;
|
||||||
node->eid = eid;
|
node->eid = eid;
|
||||||
node->name = strdup(prog);
|
node->name = strdup(prog);
|
||||||
if (node->name == NULL) {
|
|
||||||
perror("strdup");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
avl_add(&_launched_processes, node);
|
avl_add(&_launched_processes, node);
|
||||||
}
|
}
|
||||||
@@ -191,14 +185,11 @@ _zed_exec_fork_child(uint64_t eid, const char *dir, const char *prog,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
_nop(int sig)
|
_nop(int sig)
|
||||||
{
|
{}
|
||||||
(void) sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
_reap_children(void *arg)
|
_reap_children(void *arg)
|
||||||
{
|
{
|
||||||
(void) arg;
|
|
||||||
struct launched_process_node node, *pnode;
|
struct launched_process_node node, *pnode;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int status;
|
int status;
|
||||||
@@ -267,7 +258,7 @@ _reap_children(void *arg)
|
|||||||
zed_log_msg(LOG_INFO,
|
zed_log_msg(LOG_INFO,
|
||||||
"Finished \"%s\" eid=%llu pid=%d "
|
"Finished \"%s\" eid=%llu pid=%d "
|
||||||
"time=%llu.%06us status=0x%X",
|
"time=%llu.%06us status=0x%X",
|
||||||
node.name, node.eid, pid,
|
node.name, node.eid,
|
||||||
(unsigned long long) usage.ru_utime.tv_sec,
|
(unsigned long long) usage.ru_utime.tv_sec,
|
||||||
(unsigned int) usage.ru_utime.tv_usec,
|
(unsigned int) usage.ru_utime.tv_usec,
|
||||||
(unsigned int) status);
|
(unsigned int) status);
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ void zed_log_syslog_close(void);
|
|||||||
|
|
||||||
void zed_log_msg(int priority, const char *fmt, ...);
|
void zed_log_msg(int priority, const char *fmt, ...);
|
||||||
|
|
||||||
__attribute__((format(printf, 1, 2), __noreturn__))
|
|
||||||
void zed_log_die(const char *fmt, ...);
|
void zed_log_die(const char *fmt, ...);
|
||||||
|
|
||||||
#endif /* !ZED_LOG_H */
|
#endif /* !ZED_LOG_H */
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
/zfs
|
||||||
+15
-12
@@ -1,22 +1,25 @@
|
|||||||
sbin_PROGRAMS += zfs
|
include $(top_srcdir)/config/Rules.am
|
||||||
CPPCHECKTARGETS += zfs
|
|
||||||
|
sbin_PROGRAMS = zfs
|
||||||
|
|
||||||
zfs_SOURCES = \
|
zfs_SOURCES = \
|
||||||
%D%/zfs_iter.c \
|
zfs_iter.c \
|
||||||
%D%/zfs_iter.h \
|
zfs_iter.h \
|
||||||
%D%/zfs_main.c \
|
zfs_main.c \
|
||||||
%D%/zfs_project.c \
|
zfs_util.h \
|
||||||
%D%/zfs_projectutil.h \
|
zfs_project.c \
|
||||||
%D%/zfs_util.h
|
zfs_projectutil.h
|
||||||
|
|
||||||
zfs_LDADD = \
|
zfs_LDADD = \
|
||||||
libzfs.la \
|
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
||||||
libzfs_core.la \
|
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||||
libnvpair.la \
|
$(abs_top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
libuutil.la
|
$(abs_top_builddir)/lib/libuutil/libuutil.la
|
||||||
|
|
||||||
zfs_LDADD += $(LTLIBINTL)
|
zfs_LDADD += $(LTLIBINTL)
|
||||||
|
|
||||||
if BUILD_FREEBSD
|
if BUILD_FREEBSD
|
||||||
zfs_LDADD += -lgeom -ljail
|
zfs_LDADD += -lgeom -ljail
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|||||||
+27
-69
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
|
|
||||||
@@ -143,20 +144,19 @@ zfs_callback(zfs_handle_t *zhp, void *data)
|
|||||||
(cb->cb_types &
|
(cb->cb_types &
|
||||||
(ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME))) &&
|
(ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME))) &&
|
||||||
zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
|
zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
|
||||||
(void) zfs_iter_filesystems_v2(zhp, cb->cb_flags,
|
(void) zfs_iter_filesystems(zhp, zfs_callback, data);
|
||||||
zfs_callback, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
|
if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
|
||||||
ZFS_TYPE_BOOKMARK)) == 0) && include_snaps) {
|
ZFS_TYPE_BOOKMARK)) == 0) && include_snaps) {
|
||||||
(void) zfs_iter_snapshots_v2(zhp, cb->cb_flags,
|
(void) zfs_iter_snapshots(zhp,
|
||||||
|
(cb->cb_flags & ZFS_ITER_SIMPLE) != 0,
|
||||||
zfs_callback, data, 0, 0);
|
zfs_callback, data, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
|
if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
|
||||||
ZFS_TYPE_BOOKMARK)) == 0) && include_bmarks) {
|
ZFS_TYPE_BOOKMARK)) == 0) && include_bmarks) {
|
||||||
(void) zfs_iter_bookmarks_v2(zhp, cb->cb_flags,
|
(void) zfs_iter_bookmarks(zhp, zfs_callback, data);
|
||||||
zfs_callback, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cb->cb_depth--;
|
cb->cb_depth--;
|
||||||
@@ -175,7 +175,7 @@ zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
|
|||||||
zfs_sort_column_t *col;
|
zfs_sort_column_t *col;
|
||||||
zfs_prop_t prop;
|
zfs_prop_t prop;
|
||||||
|
|
||||||
if ((prop = zfs_name_to_prop(name)) == ZPROP_USERPROP &&
|
if ((prop = zfs_name_to_prop(name)) == ZPROP_INVAL &&
|
||||||
!zfs_prop_user(name))
|
!zfs_prop_user(name))
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
|
|||||||
|
|
||||||
col->sc_prop = prop;
|
col->sc_prop = prop;
|
||||||
col->sc_reverse = reverse;
|
col->sc_reverse = reverse;
|
||||||
if (prop == ZPROP_USERPROP) {
|
if (prop == ZPROP_INVAL) {
|
||||||
col->sc_user_prop = safe_malloc(strlen(name) + 1);
|
col->sc_user_prop = safe_malloc(strlen(name) + 1);
|
||||||
(void) strcpy(col->sc_user_prop, name);
|
(void) strcpy(col->sc_user_prop, name);
|
||||||
}
|
}
|
||||||
@@ -212,62 +212,16 @@ zfs_free_sort_columns(zfs_sort_column_t *sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int
|
||||||
* Return true if all of the properties to be sorted are populated by
|
zfs_sort_only_by_name(const zfs_sort_column_t *sc)
|
||||||
* dsl_dataset_fast_stat(). Note that sc == NULL (no sort) means we
|
|
||||||
* don't need any extra properties, so returns true.
|
|
||||||
*/
|
|
||||||
boolean_t
|
|
||||||
zfs_sort_only_by_fast(const zfs_sort_column_t *sc)
|
|
||||||
{
|
{
|
||||||
while (sc != NULL) {
|
return (sc != NULL && sc->sc_next == NULL &&
|
||||||
switch (sc->sc_prop) {
|
sc->sc_prop == ZFS_PROP_NAME);
|
||||||
case ZFS_PROP_NAME:
|
|
||||||
case ZFS_PROP_GUID:
|
|
||||||
case ZFS_PROP_CREATETXG:
|
|
||||||
case ZFS_PROP_NUMCLONES:
|
|
||||||
case ZFS_PROP_INCONSISTENT:
|
|
||||||
case ZFS_PROP_REDACTED:
|
|
||||||
case ZFS_PROP_ORIGIN:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return (B_FALSE);
|
|
||||||
}
|
|
||||||
sc = sc->sc_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (B_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean_t
|
|
||||||
zfs_list_only_by_fast(const zprop_list_t *p)
|
|
||||||
{
|
|
||||||
if (p == NULL) {
|
|
||||||
/* NULL means 'all' so we can't use simple mode */
|
|
||||||
return (B_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (p != NULL) {
|
|
||||||
switch (p->pl_prop) {
|
|
||||||
case ZFS_PROP_NAME:
|
|
||||||
case ZFS_PROP_GUID:
|
|
||||||
case ZFS_PROP_CREATETXG:
|
|
||||||
case ZFS_PROP_NUMCLONES:
|
|
||||||
case ZFS_PROP_INCONSISTENT:
|
|
||||||
case ZFS_PROP_REDACTED:
|
|
||||||
case ZFS_PROP_ORIGIN:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return (B_FALSE);
|
|
||||||
}
|
|
||||||
p = p->pl_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (B_TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
zfs_compare(const void *larg, const void *rarg)
|
zfs_compare(const void *larg, const void *rarg, void *unused)
|
||||||
{
|
{
|
||||||
zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
|
zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
|
||||||
zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
|
zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
|
||||||
@@ -348,8 +302,8 @@ zfs_sort(const void *larg, const void *rarg, void *data)
|
|||||||
|
|
||||||
for (psc = sc; psc != NULL; psc = psc->sc_next) {
|
for (psc = sc; psc != NULL; psc = psc->sc_next) {
|
||||||
char lbuf[ZFS_MAXPROPLEN], rbuf[ZFS_MAXPROPLEN];
|
char lbuf[ZFS_MAXPROPLEN], rbuf[ZFS_MAXPROPLEN];
|
||||||
const char *lstr, *rstr;
|
char *lstr, *rstr;
|
||||||
uint64_t lnum = 0, rnum = 0;
|
uint64_t lnum, rnum;
|
||||||
boolean_t lvalid, rvalid;
|
boolean_t lvalid, rvalid;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@@ -359,7 +313,7 @@ zfs_sort(const void *larg, const void *rarg, void *data)
|
|||||||
* Otherwise, we compare 'lnum' and 'rnum'.
|
* Otherwise, we compare 'lnum' and 'rnum'.
|
||||||
*/
|
*/
|
||||||
lstr = rstr = NULL;
|
lstr = rstr = NULL;
|
||||||
if (psc->sc_prop == ZPROP_USERPROP) {
|
if (psc->sc_prop == ZPROP_INVAL) {
|
||||||
nvlist_t *luser, *ruser;
|
nvlist_t *luser, *ruser;
|
||||||
nvlist_t *lval, *rval;
|
nvlist_t *lval, *rval;
|
||||||
|
|
||||||
@@ -400,9 +354,11 @@ zfs_sort(const void *larg, const void *rarg, void *data)
|
|||||||
zfs_get_type(r), B_FALSE);
|
zfs_get_type(r), B_FALSE);
|
||||||
|
|
||||||
if (lvalid)
|
if (lvalid)
|
||||||
lnum = zfs_prop_get_int(l, psc->sc_prop);
|
(void) zfs_prop_get_numeric(l, psc->sc_prop,
|
||||||
|
&lnum, NULL, NULL, 0);
|
||||||
if (rvalid)
|
if (rvalid)
|
||||||
rnum = zfs_prop_get_int(r, psc->sc_prop);
|
(void) zfs_prop_get_numeric(r, psc->sc_prop,
|
||||||
|
&rnum, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lvalid && !rvalid)
|
if (!lvalid && !rvalid)
|
||||||
@@ -426,7 +382,7 @@ zfs_sort(const void *larg, const void *rarg, void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (zfs_compare(larg, rarg));
|
return (zfs_compare(larg, rarg, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -498,21 +454,23 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
|
|||||||
cb.cb_flags |= ZFS_ITER_RECURSE;
|
cb.cb_flags |= ZFS_ITER_RECURSE;
|
||||||
ret = zfs_iter_root(g_zfs, zfs_callback, &cb);
|
ret = zfs_iter_root(g_zfs, zfs_callback, &cb);
|
||||||
} else {
|
} else {
|
||||||
zfs_handle_t *zhp = NULL;
|
int i;
|
||||||
zfs_type_t argtype = types;
|
zfs_handle_t *zhp;
|
||||||
|
zfs_type_t argtype;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're recursive, then we always allow filesystems as
|
* If we're recursive, then we always allow filesystems as
|
||||||
* arguments. If we also are interested in snapshots or
|
* arguments. If we also are interested in snapshots or
|
||||||
* bookmarks, then we can take volumes as well.
|
* bookmarks, then we can take volumes as well.
|
||||||
*/
|
*/
|
||||||
|
argtype = types;
|
||||||
if (flags & ZFS_ITER_RECURSE) {
|
if (flags & ZFS_ITER_RECURSE) {
|
||||||
argtype |= ZFS_TYPE_FILESYSTEM;
|
argtype |= ZFS_TYPE_FILESYSTEM;
|
||||||
if (types & (ZFS_TYPE_SNAPSHOT | ZFS_TYPE_BOOKMARK))
|
if (types & (ZFS_TYPE_SNAPSHOT | ZFS_TYPE_BOOKMARK))
|
||||||
argtype |= ZFS_TYPE_VOLUME;
|
argtype |= ZFS_TYPE_VOLUME;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
if (flags & ZFS_ITER_ARGS_CAN_BE_PATHS) {
|
if (flags & ZFS_ITER_ARGS_CAN_BE_PATHS) {
|
||||||
zhp = zfs_path_to_zhandle(g_zfs, argv[i],
|
zhp = zfs_path_to_zhandle(g_zfs, argv[i],
|
||||||
argtype);
|
argtype);
|
||||||
|
|||||||
+10
-3
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -40,12 +40,19 @@ typedef struct zfs_sort_column {
|
|||||||
boolean_t sc_reverse;
|
boolean_t sc_reverse;
|
||||||
} zfs_sort_column_t;
|
} zfs_sort_column_t;
|
||||||
|
|
||||||
|
#define ZFS_ITER_RECURSE (1 << 0)
|
||||||
|
#define ZFS_ITER_ARGS_CAN_BE_PATHS (1 << 1)
|
||||||
|
#define ZFS_ITER_PROP_LISTSNAPS (1 << 2)
|
||||||
|
#define ZFS_ITER_DEPTH_LIMIT (1 << 3)
|
||||||
|
#define ZFS_ITER_RECVD_PROPS (1 << 4)
|
||||||
|
#define ZFS_ITER_LITERAL_PROPS (1 << 5)
|
||||||
|
#define ZFS_ITER_SIMPLE (1 << 6)
|
||||||
|
|
||||||
int zfs_for_each(int, char **, int options, zfs_type_t,
|
int zfs_for_each(int, char **, int options, zfs_type_t,
|
||||||
zfs_sort_column_t *, zprop_list_t **, int, zfs_iter_f, void *);
|
zfs_sort_column_t *, zprop_list_t **, int, zfs_iter_f, void *);
|
||||||
int zfs_add_sort_column(zfs_sort_column_t **, const char *, boolean_t);
|
int zfs_add_sort_column(zfs_sort_column_t **, const char *, boolean_t);
|
||||||
void zfs_free_sort_columns(zfs_sort_column_t *);
|
void zfs_free_sort_columns(zfs_sort_column_t *);
|
||||||
boolean_t zfs_sort_only_by_fast(const zfs_sort_column_t *);
|
int zfs_sort_only_by_name(const zfs_sort_column_t *);
|
||||||
boolean_t zfs_list_only_by_fast(const zprop_list_t *);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
+469
-711
File diff suppressed because it is too large
Load Diff
+6
-12
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <strings.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
@@ -207,6 +207,7 @@ static int
|
|||||||
zfs_project_handle_dir(const char *name, zfs_project_control_t *zpc,
|
zfs_project_handle_dir(const char *name, zfs_project_control_t *zpc,
|
||||||
list_t *head)
|
list_t *head)
|
||||||
{
|
{
|
||||||
|
char fullname[PATH_MAX];
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -226,28 +227,21 @@ zfs_project_handle_dir(const char *name, zfs_project_control_t *zpc,
|
|||||||
zpc->zpc_ignore_noent = B_TRUE;
|
zpc->zpc_ignore_noent = B_TRUE;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
while (!ret && (ent = readdir(dir)) != NULL) {
|
while (!ret && (ent = readdir(dir)) != NULL) {
|
||||||
char *fullname;
|
|
||||||
|
|
||||||
/* skip "." and ".." */
|
/* skip "." and ".." */
|
||||||
if (strcmp(ent->d_name, ".") == 0 ||
|
if (strcmp(ent->d_name, ".") == 0 ||
|
||||||
strcmp(ent->d_name, "..") == 0)
|
strcmp(ent->d_name, "..") == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strlen(ent->d_name) + strlen(name) + 1 >= PATH_MAX) {
|
if (strlen(ent->d_name) + strlen(name) >=
|
||||||
|
sizeof (fullname) + 1) {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asprintf(&fullname, "%s/%s", name, ent->d_name) == -1) {
|
sprintf(fullname, "%s/%s", name, ent->d_name);
|
||||||
errno = ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = zfs_project_handle_one(fullname, zpc);
|
ret = zfs_project_handle_one(fullname, zpc);
|
||||||
if (!ret && zpc->zpc_recursive && ent->d_type == DT_DIR)
|
if (!ret && zpc->zpc_recursive && ent->d_type == DT_DIR)
|
||||||
zfs_project_item_alloc(head, fullname);
|
zfs_project_item_alloc(head, fullname);
|
||||||
|
|
||||||
free(fullname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errno && !ret) {
|
if (errno && !ret) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
|
|||||||
+2
-2
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *safe_malloc(size_t size);
|
void * safe_malloc(size_t size);
|
||||||
void nomem(void);
|
void nomem(void);
|
||||||
extern libzfs_handle_t *g_zfs;
|
extern libzfs_handle_t *g_zfs;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
zfs_ids_to_path
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
|
||||||
|
sbin_PROGRAMS = zfs_ids_to_path
|
||||||
|
|
||||||
|
zfs_ids_to_path_SOURCES = \
|
||||||
|
zfs_ids_to_path.c
|
||||||
|
|
||||||
|
zfs_ids_to_path_LDADD = \
|
||||||
|
$(abs_top_builddir)/lib/libzfs/libzfs.la
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/zgenhostid
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
|
||||||
|
sbin_PROGRAMS = zgenhostid
|
||||||
|
|
||||||
|
zgenhostid_SOURCES = zgenhostid.c
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
* You may not use this file except in compliance with the License.
|
* You may not use this file except in compliance with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
* or https://opensource.org/licenses/CDDL-1.0.
|
* or http://www.opensolaris.org/os/licensing.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
static __attribute__((noreturn)) void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
@@ -51,6 +51,7 @@ usage(void)
|
|||||||
" will be generated.\n"
|
" will be generated.\n"
|
||||||
"The value must be unique among your systems.\n");
|
"The value must be unique among your systems.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user