mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-24 19:28:53 +03:00
Compare commits
270 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a8c2b7ebc6 | |||
| 2af898ee24 | |||
| c32c2f17d0 | |||
| 2254b2bbbe | |||
| 5c4ec382a7 | |||
| e22bfd8149 | |||
| f45ad7bff6 | |||
| 0a3a4d067a | |||
| ba8024a284 | |||
| edc2675aed | |||
| 98bb45e27a | |||
| 44f463824b | |||
| b0d579bc55 | |||
| 7e5def8ae0 | |||
| 89019a846b | |||
| 41f7723e9c | |||
| 2b8c3cb0c8 | |||
| f325d76e96 | |||
| e3fb781c5f | |||
| 14a5e48fb9 | |||
| 01937958ce | |||
| edb504f9db | |||
| 2428fbbfcf | |||
| 16d298188f | |||
| f42f8702ce | |||
| 9e58d5ef38 | |||
| 320f9de8ab | |||
| 262275ab26 | |||
| 55f39a01e6 | |||
| b884768e46 | |||
| f8f4e13776 | |||
| 5f07d51751 | |||
| b2f003c4f4 | |||
| 9014da2b01 | |||
| 45579c9515 | |||
| b32f1279d4 | |||
| 1b0cd07131 | |||
| 8c6867dae4 | |||
| 99310c0aa0 | |||
| d126980e5f | |||
| 88ef5b238b | |||
| 30d8b85702 | |||
| 45f0437912 | |||
| dc3eea871a | |||
| d2c8103a68 | |||
| 3ea1f7f193 | |||
| 4356dd23a9 | |||
| 75318ec497 | |||
| c1629734ab | |||
| 778290d5bc | |||
| 98bc8e0b23 | |||
| caafa436eb | |||
| fe8de1c8a6 | |||
| 1bd93ea1e0 | |||
| 6857950e46 | |||
| 716ce2b89e | |||
| 9daae583d8 | |||
| b5ee3df776 | |||
| 17cd9a8e0c | |||
| 2a16d4cfaf | |||
| 3350a33908 | |||
| 3eef58c9b6 | |||
| 4805781c74 | |||
| b06f40ea9b | |||
| 6b5cc49d81 | |||
| ef7a79488a | |||
| a2f759146d | |||
| f79c0de208 | |||
| 1667816089 | |||
| d1ed1be3cd | |||
| e749242a99 | |||
| 9267ef84fd | |||
| 0ee129199f | |||
| 245be00597 | |||
| c38d702330 | |||
| 3f729907c8 | |||
| cca220d7c6 | |||
| 4ed30958ce | |||
| 2f118072cb | |||
| 7440f10ec1 | |||
| 8bb800d6b4 | |||
| bbf61c118f | |||
| d296b09456 | |||
| 5ac017fc04 | |||
| f5ecab3aef | |||
| fd01167ffd | |||
| 3b118f0a34 | |||
| ebe443c8ff | |||
| 63f3396233 | |||
| 2deb4526ee | |||
| a1662ffcaa | |||
| ea921bf6a6 | |||
| 6e627cc468 | |||
| 3eb3a13628 | |||
| c234706270 | |||
| 6059ba27c4 | |||
| 927f40d089 | |||
| 6356d50e67 | |||
| bd69ae3b53 | |||
| 9a2e90c9fc | |||
| 240ccfc13a | |||
| c30e716c81 | |||
| 267fd7b0f1 | |||
| dc0176eeec | |||
| 0a0af41bd9 | |||
| 3808006edf | |||
| c17922b8a9 | |||
| 8d7f17798d | |||
| 6dc40e2ada | |||
| 792f88131c | |||
| 33bb1e8256 | |||
| bcaba38e42 | |||
| 5e3085e360 | |||
| 99920d823e | |||
| 338523dd6e | |||
| 2644784f49 | |||
| b1f61f05b4 | |||
| e5ba614d05 | |||
| 30ac8de48a | |||
| c705d8386b | |||
| d5b10b3ef3 | |||
| 5a84c60fb9 | |||
| 26941ce90b | |||
| 07ce5d7390 | |||
| 1d805a534b | |||
| a9ff89e05c | |||
| d85011ed69 | |||
| b3da003ebf | |||
| 478754a8f5 | |||
| 31ff122aa2 | |||
| 18c662b845 | |||
| c797f0898e | |||
| 5e566c5772 | |||
| 23227313a2 | |||
| 3713b73335 | |||
| 310e63dfd1 | |||
| a196b3bc3d | |||
| a58e1284d8 | |||
| f1dde3fb20 | |||
| 5f38142e7b | |||
| 29b79dcfe9 | |||
| ecc972c7f0 | |||
| 6c891ade8b | |||
| 03658d5081 | |||
| 5d62588032 | |||
| 6897ea475f | |||
| 3790bfa80f | |||
| 6b278f3223 | |||
| f1236ebf35 | |||
| 184087f822 | |||
| 834815e9f7 | |||
| 0f1ff38476 | |||
| e3b28e16ce | |||
| 2f62fdd644 | |||
| 137b3e6cff | |||
| d1630dda58 | |||
| 701ebd014a | |||
| 5b8ec2cf39 | |||
| 9d1a39cec6 | |||
| 2a7b736dce | |||
| ecc8af1812 | |||
| 129e3e8dc3 | |||
| 9fb09f79e5 | |||
| a2ee6568c6 | |||
| 9c1a8eaa51 | |||
| a8fa31b50b | |||
| 8d82a19def | |||
| c2aacf2087 | |||
| 9a6c57845a | |||
| d27a40d28f | |||
| aebc5df418 | |||
| 7a8bef3983 | |||
| d486dee89e | |||
| 7de8fb33a2 | |||
| 904c03672b | |||
| 03955e3488 | |||
| 88e4e0d5dd | |||
| 03f638a8ef | |||
| 5dc25de668 | |||
| 53e5890cff | |||
| a94447ddf3 | |||
| 7192ec7942 | |||
| 06acbbc429 | |||
| 6116bbd744 | |||
| a803eacf26 | |||
| 504bfc8b49 | |||
| 53a8cbd70e | |||
| 505b97ae20 | |||
| 30a64ebaed | |||
| da16fc5739 | |||
| 3c7fa6ca33 | |||
| 36e0ddb744 | |||
| cf21b5b5b2 | |||
| 1030f807ba | |||
| d45702bcfa | |||
| ddd20dbe0b | |||
| 4a98780933 | |||
| 6db8f1a0d1 | |||
| e06711412b | |||
| 68ba1d2fa9 | |||
| 4e11137989 | |||
| be9be1cc3e | |||
| eab4536081 | |||
| 954516cec1 | |||
| 841cb5ee2a | |||
| d4cf31275b | |||
| fedc1d96a8 | |||
| 59511072b4 | |||
| a5c8119eba | |||
| d7881a6dca | |||
| 951e62169e | |||
| 9add19b37d | |||
| b2d633202d | |||
| 414f4a9c54 | |||
| 1c4f5e7d92 | |||
| 246e515cf8 | |||
| 2d41e75e52 | |||
| d834d6811b | |||
| 029a1b0c20 | |||
| c45254b0ec | |||
| 318fdeb51f | |||
| d3d20bf442 | |||
| 99598264fc | |||
| abe30b7b40 | |||
| f90ee0ca3d | |||
| 4ed955e280 | |||
| 1721f13e76 | |||
| 6e893ef62a | |||
| e0eaaf8144 | |||
| cb8a074dcb | |||
| c3ac4ccabb | |||
| 8d688ce66a | |||
| b544fe4123 | |||
| 926c6ec453 | |||
| 91b2f6ab1c | |||
| 851a7cd833 | |||
| 83d4d1a784 | |||
| 80cc2f6111 | |||
| b97948276d | |||
| 4cfc086e4d | |||
| 25d232f407 | |||
| edd7c24623 | |||
| bef6a8bc3a | |||
| 266b181e75 | |||
| c474f5e9a7 | |||
| 4e6a9e4598 | |||
| 661907e6bc | |||
| d3e7d981d4 | |||
| a2a0440918 | |||
| 45d1abc74d | |||
| 89950722c6 | |||
| 4810a108e8 | |||
| ae5b4a05ff | |||
| 3468fdbd34 | |||
| fb3f1fdbd6 | |||
| 426563be70 | |||
| aec4318870 | |||
| 2d9b57d39f | |||
| 4bdb8fcfa8 | |||
| 58c1c40a5e | |||
| 751575fe6f | |||
| 751941e248 | |||
| ef605a5517 | |||
| 8eb6dcec7d | |||
| 07cbcd5089 | |||
| 12acabe2a4 | |||
| 20c88dc3ef | |||
| 0c8fedeb35 | |||
| affb7141d7 | |||
| e0031d86b7 |
+27
-94
@@ -27,14 +27,11 @@ started?](#what-should-i-know-before-i-get-started)
|
|||||||
* [Commit Message Formats](#commit-message-formats)
|
* [Commit Message Formats](#commit-message-formats)
|
||||||
* [New Changes](#new-changes)
|
* [New Changes](#new-changes)
|
||||||
* [OpenZFS Patch Ports](#openzfs-patch-ports)
|
* [OpenZFS Patch Ports](#openzfs-patch-ports)
|
||||||
* [Coverity Defect Fixes](#coverity-defect-fixes)
|
|
||||||
* [Signed Off By](#signed-off-by)
|
|
||||||
|
|
||||||
Helpful resources
|
Helpful resources
|
||||||
|
|
||||||
* [ZFS on Linux wiki](https://github.com/zfsonlinux/zfs/wiki)
|
* [ZFS on Linux wiki](https://github.com/zfsonlinux/zfs/wiki)
|
||||||
* [OpenZFS Documentation](http://open-zfs.org/wiki/Developer_resources)
|
* [OpenZFS Documentation](http://open-zfs.org/wiki/Developer_resources)
|
||||||
* [Git and GitHub for beginners](https://github.com/zfsonlinux/zfs/wiki/Git-and-GitHub-for-beginners)
|
|
||||||
|
|
||||||
## What should I know before I get started?
|
## What should I know before I get started?
|
||||||
|
|
||||||
@@ -51,20 +48,19 @@ configure option should be set. This will enable additional correctness
|
|||||||
checks and all the ASSERTs to help quickly catch potential issues.
|
checks and all the ASSERTs to help quickly catch potential issues.
|
||||||
|
|
||||||
In addition, there are numerous utilities and debugging files which
|
In addition, there are numerous utilities and debugging files which
|
||||||
provide visibility into the inner workings of ZFS. The most useful
|
provide visibility in to the inner workings of ZFS. The most useful
|
||||||
of these tools are discussed in detail on the [debugging ZFS wiki
|
of these tools are discussed in detail on the [debugging ZFS wiki
|
||||||
page](https://github.com/zfsonlinux/zfs/wiki/Debugging).
|
page](https://github.com/zfsonlinux/zfs/wiki/Debugging).
|
||||||
|
|
||||||
### Where can I ask for help?
|
### Where can I ask for help?
|
||||||
[The zfs-discuss mailing list or IRC](http://list.zfsonlinux.org)
|
The [mailing list](https://github.com/zfsonlinux/zfs/wiki/Mailing-Lists)
|
||||||
are the best places to ask for help. Please do not file support requests
|
is the best place to ask for help.
|
||||||
on the GitHub issue tracker.
|
|
||||||
|
|
||||||
## How Can I Contribute?
|
## How Can I Contribute?
|
||||||
|
|
||||||
### Reporting Bugs
|
### Reporting Bugs
|
||||||
*Please* contact us via the [zfs-discuss mailing
|
*Please* contact us via the [mailing
|
||||||
list or IRC](http://list.zfsonlinux.org) if you aren't
|
list](https://github.com/zfsonlinux/zfs/wiki/Mailing-Lists) if you aren't
|
||||||
certain that you are experiencing a bug.
|
certain that you are experiencing a bug.
|
||||||
|
|
||||||
If you run into an issue, please search our [issue
|
If you run into an issue, please search our [issue
|
||||||
@@ -171,10 +167,18 @@ first line in the commit message.
|
|||||||
please summarize important information such as why the proposed
|
please summarize important information such as why the proposed
|
||||||
approach was chosen or a brief description of the bug you are resolving.
|
approach was chosen or a brief description of the bug you are resolving.
|
||||||
Each line of the body must be 72 characters or less.
|
Each line of the body must be 72 characters or less.
|
||||||
* The last line must be a `Signed-off-by:` tag. See the
|
* The last line must be a `Signed-off-by:` tag with the developer's
|
||||||
[Signed Off By](#signed-off-by) section for more information.
|
name followed by their email. This is the developer's certification
|
||||||
|
that they have the right to submit the patch for inclusion into
|
||||||
|
the code base and indicates agreement to the [Developer's Certificate
|
||||||
|
of Origin](https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin).
|
||||||
|
Code without a proper signoff cannot be merged.
|
||||||
|
|
||||||
An example commit message for new changes is provided below.
|
Git can append the `Signed-off-by` line to your commit messages. Simply
|
||||||
|
provide the `-s` or `--signoff` option when performing a `git commit`.
|
||||||
|
For more information about writing commit messages, visit [How to Write
|
||||||
|
a Git Commit Message](https://chris.beams.io/posts/git-commit/).
|
||||||
|
An example commit message is provided below.
|
||||||
|
|
||||||
```
|
```
|
||||||
This line is a brief summary of your change
|
This line is a brief summary of your change
|
||||||
@@ -188,23 +192,23 @@ Signed-off-by: Contributor <contributor@email.com>
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### OpenZFS Patch Ports
|
#### OpenZFS Patch Ports
|
||||||
If you are porting OpenZFS patches, the commit message must meet
|
If you are porting an OpenZFS patch, the commit message must meet
|
||||||
the following guidelines:
|
the following guidelines:
|
||||||
* The first line must be the summary line from the most important OpenZFS commit being ported.
|
* The first line must be the summary line from the OpenZFS commit.
|
||||||
It must begin with `OpenZFS dddd, dddd - ` where `dddd` are OpenZFS issue numbers.
|
It must begin with `OpenZFS dddd - ` where `dddd` is the OpenZFS issue number.
|
||||||
* Provides a `Authored by:` line to attribute each patch for each original author.
|
* Provides a `Authored by:` line to attribute the patch to the original author.
|
||||||
* Provides the `Reviewed by:` and `Approved by:` lines from each original
|
* Provides the `Reviewed by:` and `Approved by:` lines from the original
|
||||||
OpenZFS commit.
|
OpenZFS commit.
|
||||||
* Provides a `Ported-by:` line with the developer's name followed by
|
* Provides a `Ported-by:` line with the developer's name followed by
|
||||||
their email for each OpenZFS commit.
|
their email.
|
||||||
* Provides a `OpenZFS-issue:` line with link for each original illumos
|
* Provides a `OpenZFS-issue:` line which is a link to the original illumos
|
||||||
issue.
|
issue.
|
||||||
* Provides a `OpenZFS-commit:` line with link for each original OpenZFS commit.
|
* Provides a `OpenZFS-commit:` line which links back to the original OpenZFS
|
||||||
|
commit.
|
||||||
* If necessary, provide some porting notes to describe any deviations from
|
* If necessary, provide some porting notes to describe any deviations from
|
||||||
the original OpenZFS commits.
|
the original OpenZFS commit.
|
||||||
|
|
||||||
An example OpenZFS patch port commit message for a single patch is provided
|
An example OpenZFS patch port commit message is provided below.
|
||||||
below.
|
|
||||||
```
|
```
|
||||||
OpenZFS 1234 - Summary from the original OpenZFS commit
|
OpenZFS 1234 - Summary from the original OpenZFS commit
|
||||||
|
|
||||||
@@ -219,74 +223,3 @@ Provide some porting notes here if necessary.
|
|||||||
OpenZFS-issue: https://www.illumos.org/issues/1234
|
OpenZFS-issue: https://www.illumos.org/issues/1234
|
||||||
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/abcd1234
|
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/abcd1234
|
||||||
```
|
```
|
||||||
|
|
||||||
If necessary, multiple OpenZFS patches can be combined in a single port.
|
|
||||||
This is useful when you are porting a new patch and its subsequent bug
|
|
||||||
fixes. An example commit message is provided below.
|
|
||||||
```
|
|
||||||
OpenZFS 1234, 5678 - Summary of most important OpenZFS commit
|
|
||||||
|
|
||||||
1234 Summary from original OpenZFS commit for 1234
|
|
||||||
|
|
||||||
Authored by: Original Author <original@email.com>
|
|
||||||
Reviewed by: Reviewer Two <reviewer2@email.com>
|
|
||||||
Approved by: Approver One <approver1@email.com>
|
|
||||||
Ported-by: ZFS Contributor <contributor@email.com>
|
|
||||||
|
|
||||||
Provide some porting notes here for 1234 if necessary.
|
|
||||||
|
|
||||||
OpenZFS-issue: https://www.illumos.org/issues/1234
|
|
||||||
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/abcd1234
|
|
||||||
|
|
||||||
5678 Summary from original OpenZFS commit for 5678
|
|
||||||
|
|
||||||
Authored by: Original Author2 <original2@email.com>
|
|
||||||
Reviewed by: Reviewer One <reviewer1@email.com>
|
|
||||||
Approved by: Approver Two <approver2@email.com>
|
|
||||||
Ported-by: ZFS Contributor <contributor@email.com>
|
|
||||||
|
|
||||||
Provide some porting notes here for 5678 if necessary.
|
|
||||||
|
|
||||||
OpenZFS-issue: https://www.illumos.org/issues/5678
|
|
||||||
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/efgh5678
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Coverity Defect Fixes
|
|
||||||
If you are submitting a fix to a
|
|
||||||
[Coverity defect](https://scan.coverity.com/projects/zfsonlinux-zfs),
|
|
||||||
the commit message should meet the following guidelines:
|
|
||||||
* Provides a subject line in the format of
|
|
||||||
`Fix coverity defects: CID dddd, dddd...` where `dddd` represents
|
|
||||||
each CID fixed by the commit.
|
|
||||||
* Provides a body which lists each Coverity defect and how it was corrected.
|
|
||||||
* The last line must be a `Signed-off-by:` tag. See the
|
|
||||||
[Signed Off By](#signed-off-by) section for more information.
|
|
||||||
|
|
||||||
An example Coverity defect fix commit message is provided below.
|
|
||||||
```
|
|
||||||
Fix coverity defects: CID 12345, 67890
|
|
||||||
|
|
||||||
CID 12345: Logically dead code (DEADCODE)
|
|
||||||
|
|
||||||
Removed the if(var != 0) block because the condition could never be
|
|
||||||
satisfied.
|
|
||||||
|
|
||||||
CID 67890: Resource Leak (RESOURCE_LEAK)
|
|
||||||
|
|
||||||
Ensure free is called after allocating memory in function().
|
|
||||||
|
|
||||||
Signed-off-by: Contributor <contributor@email.com>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Signed Off By
|
|
||||||
A line tagged as `Signed-off-by:` must contain the developer's
|
|
||||||
name followed by their email. This is the developer's certification
|
|
||||||
that they have the right to submit the patch for inclusion into
|
|
||||||
the code base and indicates agreement to the [Developer's Certificate
|
|
||||||
of Origin](https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin).
|
|
||||||
Code without a proper signoff cannot be merged.
|
|
||||||
|
|
||||||
Git can append the `Signed-off-by` line to your commit messages. Simply
|
|
||||||
provide the `-s` or `--signoff` option when performing a `git commit`.
|
|
||||||
For more information about writing commit messages, visit [How to Write
|
|
||||||
a Git Commit Message](https://chris.beams.io/posts/git-commit/).
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
<!-- Please fill out the following template, which will help other contributors address your issue. -->
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Thank you for reporting an issue.
|
Thank you for reporting an issue.
|
||||||
|
|
||||||
@@ -16,15 +14,15 @@ Please fill in as much of the template as possible.
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
### System information
|
### System information
|
||||||
<!-- add version after "|" character -->
|
<!-- add version after "|" character -->
|
||||||
Type | Version/Name
|
Type | Version/Name
|
||||||
--- | ---
|
--- | ---
|
||||||
Distribution Name |
|
Distribution Name |
|
||||||
Distribution Version |
|
Distribution Version |
|
||||||
Linux Kernel |
|
Linux Kernel |
|
||||||
Architecture |
|
Architecture |
|
||||||
ZFS Version |
|
ZFS Version |
|
||||||
SPL Version |
|
SPL Version |
|
||||||
<!--
|
<!--
|
||||||
Commands to find ZFS/SPL versions:
|
Commands to find ZFS/SPL versions:
|
||||||
modinfo zfs | grep -iw version
|
modinfo zfs | grep -iw version
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
<!--- Please fill out the following template, which will help other contributors review your Pull Request. -->
|
|
||||||
|
|
||||||
<!--- Provide a general summary of your changes in the Title above -->
|
<!--- Provide a general summary of your changes in the Title above -->
|
||||||
|
|
||||||
<!---
|
<!---
|
||||||
@@ -7,13 +5,13 @@ Documentation on ZFS Buildbot options can be found at
|
|||||||
https://github.com/zfsonlinux/zfs/wiki/Buildbot-Options
|
https://github.com/zfsonlinux/zfs/wiki/Buildbot-Options
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
### Description
|
||||||
|
<!--- Describe your changes in detail -->
|
||||||
|
|
||||||
### Motivation and Context
|
### Motivation and Context
|
||||||
<!--- Why is this change required? What problem does it solve? -->
|
<!--- Why is this change required? What problem does it solve? -->
|
||||||
<!--- If it fixes an open issue, please link to the issue here. -->
|
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||||
|
|
||||||
### Description
|
|
||||||
<!--- Describe your changes in detail -->
|
|
||||||
|
|
||||||
### How Has This Been Tested?
|
### How Has This Been Tested?
|
||||||
<!--- Please describe in detail how you tested your changes. -->
|
<!--- Please describe in detail how you tested your changes. -->
|
||||||
<!--- Include details of your testing environment, and the tests you ran to -->
|
<!--- Include details of your testing environment, and the tests you ran to -->
|
||||||
@@ -32,9 +30,10 @@ https://github.com/zfsonlinux/zfs/wiki/Buildbot-Options
|
|||||||
### Checklist:
|
### Checklist:
|
||||||
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||||
- [ ] My code follows the ZFS on Linux [code style requirements](https://github.com/zfsonlinux/zfs/blob/master/.github/CONTRIBUTING.md#coding-conventions).
|
- [ ] My code follows the ZFS on Linux code style requirements.
|
||||||
- [ ] I have updated the documentation accordingly.
|
- [ ] I have updated the documentation accordingly.
|
||||||
- [ ] I have read the [**contributing** document](https://github.com/zfsonlinux/zfs/blob/master/.github/CONTRIBUTING.md).
|
- [ ] I have read the **CONTRIBUTING** document.
|
||||||
- [ ] I have added [tests](https://github.com/zfsonlinux/zfs/tree/master/tests) to cover my changes.
|
- [ ] I have added tests to cover my changes.
|
||||||
- [ ] All new and existing tests passed.
|
- [ ] All new and existing tests passed.
|
||||||
- [ ] All commit messages are properly formatted and contain [`Signed-off-by`](https://github.com/zfsonlinux/zfs/blob/master/.github/CONTRIBUTING.md#signed-off-by).
|
- [ ] All commit messages are properly formatted and contain `Signed-off-by`.
|
||||||
|
- [ ] Change has been approved by a ZFS on Linux member.
|
||||||
|
|||||||
+17
-9
@@ -1,22 +1,30 @@
|
|||||||
codecov:
|
codecov:
|
||||||
notify:
|
notify:
|
||||||
require_ci_to_pass: false # always post
|
require_ci_to_pass: no
|
||||||
after_n_builds: 2 # user and kernel
|
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
precision: 2 # 2 digits of precision
|
precision: 2
|
||||||
range: "50...90" # red -> yellow -> green
|
round: down
|
||||||
|
range: "50...100"
|
||||||
|
|
||||||
status:
|
status:
|
||||||
project:
|
project:
|
||||||
default:
|
default:
|
||||||
threshold: 1% # allow 1% coverage variance
|
threshold: 1%
|
||||||
|
|
||||||
patch:
|
patch:
|
||||||
default:
|
default:
|
||||||
threshold: 1% # allow 1% coverage variance
|
threshold: 1%
|
||||||
|
|
||||||
|
parsers:
|
||||||
|
gcov:
|
||||||
|
branch_detection:
|
||||||
|
conditional: yes
|
||||||
|
loop: yes
|
||||||
|
method: no
|
||||||
|
macro: no
|
||||||
|
|
||||||
comment:
|
comment:
|
||||||
layout: "reach, diff, flags, footer"
|
layout: "header, sunburst, diff"
|
||||||
behavior: once # update if exists; post new; skip if deleted
|
behavior: default
|
||||||
require_changes: yes # only post when coverage changes
|
require_changes: no
|
||||||
|
|||||||
+2
-6
@@ -14,7 +14,6 @@
|
|||||||
# Normal rules
|
# Normal rules
|
||||||
#
|
#
|
||||||
*.[oa]
|
*.[oa]
|
||||||
*.o.ur-safe
|
|
||||||
*.lo
|
*.lo
|
||||||
*.la
|
*.la
|
||||||
*.mod.c
|
*.mod.c
|
||||||
@@ -22,8 +21,6 @@
|
|||||||
*.swp
|
*.swp
|
||||||
*.gcno
|
*.gcno
|
||||||
*.gcda
|
*.gcda
|
||||||
*.pyc
|
|
||||||
*.pyo
|
|
||||||
.deps
|
.deps
|
||||||
.libs
|
.libs
|
||||||
.dirstamp
|
.dirstamp
|
||||||
@@ -36,7 +33,6 @@ Makefile.in
|
|||||||
# Top level generated files specific to this top level dir
|
# Top level generated files specific to this top level dir
|
||||||
#
|
#
|
||||||
/bin
|
/bin
|
||||||
/build
|
|
||||||
/configure
|
/configure
|
||||||
/config.log
|
/config.log
|
||||||
/config.status
|
/config.status
|
||||||
@@ -45,6 +41,8 @@ Makefile.in
|
|||||||
/zfs_config.h.in
|
/zfs_config.h.in
|
||||||
/zfs.release
|
/zfs.release
|
||||||
/stamp-h1
|
/stamp-h1
|
||||||
|
/.script-config
|
||||||
|
/zfs-script-config.sh
|
||||||
/aclocal.m4
|
/aclocal.m4
|
||||||
/autom4te.cache
|
/autom4te.cache
|
||||||
|
|
||||||
@@ -61,5 +59,3 @@ cscope.*
|
|||||||
*.tar.gz
|
*.tar.gz
|
||||||
*.patch
|
*.patch
|
||||||
*.orig
|
*.orig
|
||||||
*.log
|
|
||||||
venv
|
|
||||||
|
|||||||
-38
@@ -1,38 +0,0 @@
|
|||||||
language: c
|
|
||||||
sudo: required
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
# Travis limits maximum log size, we have to cut tests output
|
|
||||||
- ZFS_TEST_TRAVIS_LOG_MAX_LENGTH=800
|
|
||||||
matrix:
|
|
||||||
# tags are mainly in ascending order
|
|
||||||
- ZFS_TEST_TAGS='acl,atime,bootfs,cachefile,casenorm,chattr,checksum,clean_mirror,compression,ctime,delegate,devices,events,exec,fault,features,grow_pool,zdb,zfs,zfs_bookmark,zfs_change-key,zfs_clone,zfs_copies,zfs_create,zfs_diff,zfs_get,zfs_inherit,zfs_load-key,zfs_rename'
|
|
||||||
- ZFS_TEST_TAGS='cache,history,hkdf,inuse,zfs_property,zfs_receive,zfs_reservation,zfs_send,zfs_set,zfs_share,zfs_snapshot,zfs_unload-key,zfs_unmount,zfs_unshare,zfs_upgrade,zpool,zpool_add,zpool_attach,zpool_clear,zpool_create,zpool_destroy,zpool_detach'
|
|
||||||
- ZFS_TEST_TAGS='grow_replicas,mv_files,cli_user,zfs_mount,zfs_promote,zfs_rollback,zpool_events,zpool_expand,zpool_export,zpool_get,zpool_history,zpool_import,zpool_labelclear,zpool_offline,zpool_online,zpool_remove,zpool_reopen,zpool_replace,zpool_scrub,zpool_set,zpool_status,zpool_sync,zpool_upgrade'
|
|
||||||
- ZFS_TEST_TAGS='zfs_destroy,large_files,largest_pool,link_count,migration,mmap,mmp,mount,nestedfs,no_space,nopwrite,online_offline,pool_names,poolversion,privilege,quota,raidz,redundancy,rsend'
|
|
||||||
- ZFS_TEST_TAGS='inheritance,refquota,refreserv,rename_dirs,replacement,reservation,rootpool,scrub_mirror,slog,snapshot,snapused,sparse,threadsappend,tmpfile,truncate,upgrade,userquota,vdev_zaps,write_dirs,xattr,zvol,libzfs'
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get -qq update
|
|
||||||
- sudo apt-get install --yes -qq build-essential autoconf libtool gawk alien fakeroot linux-headers-$(uname -r)
|
|
||||||
- sudo apt-get install --yes -qq zlib1g-dev uuid-dev libattr1-dev libblkid-dev libselinux-dev libudev-dev libssl-dev
|
|
||||||
# packages for tests
|
|
||||||
- sudo apt-get install --yes -qq parted lsscsi ksh attr acl nfs-kernel-server fio
|
|
||||||
install:
|
|
||||||
- git clone --depth=1 https://github.com/zfsonlinux/spl
|
|
||||||
- cd spl
|
|
||||||
- git checkout master
|
|
||||||
- sh autogen.sh
|
|
||||||
- ./configure
|
|
||||||
- make --no-print-directory -s pkg-utils pkg-kmod
|
|
||||||
- sudo dpkg -i *.deb
|
|
||||||
- cd ..
|
|
||||||
- sh autogen.sh
|
|
||||||
- ./configure
|
|
||||||
- make --no-print-directory -s pkg-utils pkg-kmod
|
|
||||||
- sudo dpkg -i *.deb
|
|
||||||
script:
|
|
||||||
- travis_wait 50 /usr/share/zfs/zfs-tests.sh -v -T $ZFS_TEST_TAGS
|
|
||||||
after_failure:
|
|
||||||
- find /var/tmp/test_results/current/log -type f -name '*' -printf "%f\n" -exec cut -c -$ZFS_TEST_TRAVIS_LOG_MAX_LENGTH {} \;
|
|
||||||
after_success:
|
|
||||||
- find /var/tmp/test_results/current/log -type f -name '*' -printf "%f\n" -exec cut -c -$ZFS_TEST_TRAVIS_LOG_MAX_LENGTH {} \;
|
|
||||||
@@ -1,305 +1,95 @@
|
|||||||
MAINTAINERS:
|
Brian Behlendorf is the principal developer of the ZFS on Linux port.
|
||||||
|
He works full time as a computer scientist at Lawrence Livermore
|
||||||
|
National Laboratory on the ZFS and Lustre filesystems. However,
|
||||||
|
this port would not have been possible without the help of many
|
||||||
|
others who have contributed their time, effort, and insight.
|
||||||
|
|
||||||
Brian Behlendorf <behlendorf1@llnl.gov>
|
Brian Behlendorf <behlendorf1@llnl.gov>
|
||||||
Tony Hutter <hutter2@llnl.gov>
|
|
||||||
|
|
||||||
PAST MAINTAINERS:
|
First and foremost the hard working ZFS developers at Sun/Oracle.
|
||||||
|
They are responsible for the bulk of the code in this project and
|
||||||
|
without their efforts there never would have been a ZFS filesystem.
|
||||||
|
|
||||||
Ned Bass <bass6@llnl.gov>
|
The ZFS Development Team at Sun/Oracle
|
||||||
|
|
||||||
CONTRIBUTORS:
|
Next all the developers at KQ Infotech who implemented a prototype
|
||||||
|
ZFS Posix Layer (ZPL). Their implementation provided an excellent
|
||||||
|
reference for adding the ZPL functionality.
|
||||||
|
|
||||||
Aaron Fineman <abyxcos@gmail.com>
|
Anand Mitra <mitra@kqinfotech.com>
|
||||||
Adam Leventhal <ahl@delphix.com>
|
Anurag Agarwal <anurag@kqinfotech.com>
|
||||||
Adam Stevko <adam.stevko@gmail.com>
|
Neependra Khare <neependra@kqinfotech.com>
|
||||||
Ahmed G <ahmedg@delphix.com>
|
Prasad Joshi <prasad@kqinfotech.com>
|
||||||
Akash Ayare <aayare@delphix.com>
|
Rohan Puri <rohan@kqinfotech.com>
|
||||||
Alan Somers <asomers@gmail.com>
|
Sandip Divekar <sandipd@kqinfotech.com>
|
||||||
Alar Aun <spamtoaun@gmail.com>
|
Shoaib <shoaib@kqinfotech.com>
|
||||||
Albert Lee <trisk@nexenta.com>
|
Shrirang <shrirang@kqinfotech.com>
|
||||||
Alec Salazar <alec.j.salazar@gmail.com>
|
|
||||||
Alejandro R. Sedeño <asedeno@mit.edu>
|
Additionally the following individuals have all made contributions
|
||||||
Alek Pinchuk <alek@nexenta.com>
|
to the project and deserve to be acknowledged.
|
||||||
Alex Braunegg <alex.braunegg@gmail.com>
|
|
||||||
Alex McWhirter <alexmcwhirter@triadic.us>
|
Albert Lee <trisk@nexenta.com>
|
||||||
Alex Reece <alex@delphix.com>
|
Alejandro R. Sedeño <asedeno@mit.edu>
|
||||||
Alex Wilson <alex.wilson@joyent.com>
|
Alex Zhuravlev <bzzz@whamcloud.com>
|
||||||
Alex Zhuravlev <alexey.zhuravlev@intel.com>
|
Alexander Eremin <a.eremin@nexenta.com>
|
||||||
Alexander Eremin <a.eremin@nexenta.com>
|
Alexander Stetsenko <ams@nexenta.com>
|
||||||
Alexander Motin <mav@freebsd.org>
|
Alexey Shvetsov <alexxy@gentoo.org>
|
||||||
Alexander Pyhalov <apyhalov@gmail.com>
|
Andreas Dilger <adilger@whamcloud.com>
|
||||||
Alexander Stetsenko <ams@nexenta.com>
|
Andrew Reid <ColdCanuck@nailedtotheperch.com>
|
||||||
Alexey Shvetsov <alexxy@gentoo.org>
|
Andrew Stormont <andrew.stormont@nexenta.com>
|
||||||
Alexey Smirnoff <fling@member.fsf.org>
|
Andrew Tselischev <andrewtselischev@gmail.com>
|
||||||
Allan Jude <allanjude@freebsd.org>
|
Andriy Gapon <avg@FreeBSD.org>
|
||||||
AndCycle <andcycle@andcycle.idv.tw>
|
Aniruddha Shankar <k@191a.net>
|
||||||
Andreas Buschmann <andreas.buschmann@tech.net.de>
|
Bill Pijewski <wdp@joyent.com>
|
||||||
Andreas Dilger <adilger@intel.com>
|
Chris Dunlap <cdunlap@llnl.gov>
|
||||||
Andrew Barnes <barnes333@gmail.com>
|
Chris Dunlop <chris@onthe.net.au>
|
||||||
Andrew Hamilton <ahamilto@tjhsst.edu>
|
Chris Siden <chris.siden@delphix.com>
|
||||||
Andrew Reid <ColdCanuck@nailedtotheperch.com>
|
Chris Wedgwood <cw@f00f.org>
|
||||||
Andrew Stormont <andrew.stormont@nexenta.com>
|
Christian Kohlschütter <christian@kohlschutter.com>
|
||||||
Andrew Tselischev <andrewtselischev@gmail.com>
|
Christopher Siden <chris.siden@delphix.com>
|
||||||
Andrey Vesnovaty <andrey.vesnovaty@gmail.com>
|
Craig Sanders <github@taz.net.au>
|
||||||
Andriy Gapon <avg@freebsd.org>
|
Cyril Plisko <cyril.plisko@mountall.com>
|
||||||
Andy Bakun <github@thwartedefforts.org>
|
Dan McDonald <danmcd@nexenta.com>
|
||||||
Aniruddha Shankar <k@191a.net>
|
Daniel Verite <daniel@verite.pro>
|
||||||
Antonio Russo <antonio.e.russo@gmail.com>
|
Darik Horn <dajhorn@vanadac.com>
|
||||||
Arkadiusz Bubała <arkadiusz.bubala@open-e.com>
|
Eric Schrock <Eric.Schrock@delphix.com>
|
||||||
Arne Jansen <arne@die-jansens.de>
|
Etienne Dechamps <etienne.dechamps@ovh.net>
|
||||||
Aron Xu <happyaron.xu@gmail.com>
|
Fajar A. Nugraha <github@fajar.net>
|
||||||
Bart Coddens <bart.coddens@gmail.com>
|
Frederik Wessels <wessels147@gmail.com>
|
||||||
Basil Crow <basil.crow@delphix.com>
|
Garrett D'Amore <garrett@nexenta.com>
|
||||||
Huang Liu <liu.huang@zte.com.cn>
|
George Wilson <george.wilson@delphix.com>
|
||||||
Ben Allen <bsallen@alcf.anl.gov>
|
Gordon Ross <gwr@nexenta.com>
|
||||||
Ben Rubson <ben.rubson@gmail.com>
|
Gregor Kopka <mailfrom-github.com@kopka.net>
|
||||||
Benjamin Albrecht <git@albrecht.io>
|
Gunnar Beutner <gunnar@beutner.name>
|
||||||
Bill McGonigle <bill-github.com-public1@bfccomputing.com>
|
James H <james@kagisoft.co.uk>
|
||||||
Bill Pijewski <wdp@joyent.com>
|
Javen Wu <wu.javen@gmail.com>
|
||||||
Boris Protopopov <boris.protopopov@nexenta.com>
|
Jeremy Gill <jgill@parallax-innovations.com>
|
||||||
Brad Lewis <brad.lewis@delphix.com>
|
Jorgen Lundman <lundman@lundman.net>
|
||||||
Brian Behlendorf <behlendorf1@llnl.gov>
|
KORN Andras <korn@elan.rulez.org>
|
||||||
Brian J. Murrell <brian@sun.com>
|
Kyle Fuller <inbox@kylefuller.co.uk>
|
||||||
Caleb James DeLisle <calebdelisle@lavabit.com>
|
Manuel Amador (Rudd-O) <rudd-o@rudd-o.com>
|
||||||
Cao Xuewen <cao.xuewen@zte.com.cn>
|
Martin Matuska <mm@FreeBSD.org>
|
||||||
Carlo Landmeter <clandmeter@gmail.com>
|
Massimo Maggi <massimo@mmmm.it>
|
||||||
Carlos Alberto Lopez Perez <clopez@igalia.com>
|
Matthew Ahrens <mahrens@delphix.com>
|
||||||
Chaoyu Zhang <zhang.chaoyu@zte.com.cn>
|
Michael Martin <mgmartin.mgm@gmail.com>
|
||||||
Chen Can <chen.can2@zte.com.cn>
|
Mike Harsch <mike@harschsystems.com>
|
||||||
Chen Haiquan <oc@yunify.com>
|
Ned Bass <bass6@llnl.gov>
|
||||||
Chip Parker <aparker@enthought.com>
|
Oleg Stepura <oleg@stepura.com>
|
||||||
Chris Burroughs <chris.burroughs@gmail.com>
|
P.SCH <p88@yahoo.com>
|
||||||
Chris Dunlap <cdunlap@llnl.gov>
|
Pawel Jakub Dawidek <pawel@dawidek.net>
|
||||||
Chris Dunlop <chris@onthe.net.au>
|
Prakash Surya <surya1@llnl.gov>
|
||||||
Chris Siden <chris.siden@delphix.com>
|
Prasad Joshi <pjoshi@stec-inc.com>
|
||||||
Chris Wedgwood <cw@f00f.org>
|
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
|
||||||
Chris Williamson <chris.williamson@delphix.com>
|
Richard Laager <rlaager@wiktel.com>
|
||||||
Chris Zubrzycki <github@mid-earth.net>
|
Richard Lowe <richlowe@richlowe.net>
|
||||||
Christ Schlacta <aarcane@aarcane.info>
|
Richard Yao <ryao@cs.stonybrook.edu>
|
||||||
Christer Ekholm <che@chrekh.se>
|
Rohan Puri <rohan.puri15@gmail.com>
|
||||||
Christian Kohlschütter <christian@kohlschutter.com>
|
Shampavman <sham.pavman@nexenta.com>
|
||||||
Christian Neukirchen <chneukirchen@gmail.com>
|
Simon Klinkert <klinkert@webgods.de>
|
||||||
Christian Schwarz <me@cschwarz.com>
|
Suman Chakravartula <suman@gogrid.com>
|
||||||
Christopher Voltz <cjunk@voltz.ws>
|
Tim Haley <Tim.Haley@Sun.COM>
|
||||||
Chunwei Chen <david.chen@nutanix.com>
|
Turbo Fredriksson <turbo@bayour.com>
|
||||||
Clemens Fruhwirth <clemens@endorphin.org>
|
Xin Li <delphij@FreeBSD.org>
|
||||||
Coleman Kane <ckane@colemankane.org>
|
Yuxuan Shui <yshuiv7@gmail.com>
|
||||||
Colin Ian King <colin.king@canonical.com>
|
Zachary Bedell <zac@thebedells.org>
|
||||||
Craig Loomis <cloomis@astro.princeton.edu>
|
nordaux <nordaux@gmail.com>
|
||||||
Craig Sanders <github@taz.net.au>
|
|
||||||
Cyril Plisko <cyril.plisko@infinidat.com>
|
|
||||||
DHE <git@dehacked.net>
|
|
||||||
Damian Wojsław <damian@wojslaw.pl>
|
|
||||||
Dan Kimmel <dan.kimmel@delphix.com>
|
|
||||||
Dan McDonald <danmcd@nexenta.com>
|
|
||||||
Dan Swartzendruber <dswartz@druber.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>
|
|
||||||
Dave Eddy <dave@daveeddy.com>
|
|
||||||
David Lamparter <equinox@diac24.net>
|
|
||||||
David Qian <david.qian@intel.com>
|
|
||||||
David Quigley <david.quigley@intel.com>
|
|
||||||
Debabrata Banerjee <dbanerje@akamai.com>
|
|
||||||
Denys Rtveliashvili <denys@rtveliashvili.name>
|
|
||||||
Derek Dai <daiderek@gmail.com>
|
|
||||||
Dimitri John Ledkov <xnox@ubuntu.com>
|
|
||||||
Dmitry Khasanov <pik4ez@gmail.com>
|
|
||||||
Dominik Hassler <hadfl@omniosce.org>
|
|
||||||
Dominik Honnef <dominikh@fork-bomb.org>
|
|
||||||
Don Brady <don.brady@delphix.com>
|
|
||||||
Dr. András Korn <korn-github.com@elan.rulez.org>
|
|
||||||
Eli Rosenthal <eli.rosenthal@delphix.com>
|
|
||||||
Eric Desrochers <eric.desrochers@canonical.com>
|
|
||||||
Eric Dillmann <eric@jave.fr>
|
|
||||||
Eric Schrock <Eric.Schrock@delphix.com>
|
|
||||||
Etienne Dechamps <etienne@edechamps.fr>
|
|
||||||
Evan Susarret <evansus@gmail.com>
|
|
||||||
Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
|
||||||
Fajar A. Nugraha <github@fajar.net>
|
|
||||||
Fan Yong <fan.yong@intel.com>
|
|
||||||
Feng Sun <loyou85@gmail.com>
|
|
||||||
Frederik Wessels <wessels147@gmail.com>
|
|
||||||
Frédéric Vanniere <f.vanniere@planet-work.com>
|
|
||||||
Garrett D'Amore <garrett@nexenta.com>
|
|
||||||
Garrison Jensen <garrison.jensen@gmail.com>
|
|
||||||
Gary Mills <gary_mills@fastmail.fm>
|
|
||||||
Gaurav Kumar <gauravk.18@gmail.com>
|
|
||||||
GeLiXin <ge.lixin@zte.com.cn>
|
|
||||||
George Amanakis <g_amanakis@yahoo.com>
|
|
||||||
George Melikov <mail@gmelikov.ru>
|
|
||||||
George Wilson <gwilson@delphix.com>
|
|
||||||
Georgy Yakovlev <ya@sysdump.net>
|
|
||||||
Giuseppe Di Natale <guss80@gmail.com>
|
|
||||||
Gordan Bobic <gordan@redsleeve.org>
|
|
||||||
Gordon Ross <gwr@nexenta.com>
|
|
||||||
Gregor Kopka <gregor@kopka.net>
|
|
||||||
Grischa Zengel <github.zfsonlinux@zengel.info>
|
|
||||||
Gunnar Beutner <gunnar@beutner.name>
|
|
||||||
Gvozden Neskovic <neskovic@gmail.com>
|
|
||||||
Hajo Möller <dasjoe@gmail.com>
|
|
||||||
Hans Rosenfeld <hans.rosenfeld@nexenta.com>
|
|
||||||
Håkan Johansson <f96hajo@chalmers.se>
|
|
||||||
Igor Kozhukhov <ikozhukhov@gmail.com>
|
|
||||||
Igor Lvovsky <ilvovsky@gmail.com>
|
|
||||||
Isaac Huang <he.huang@intel.com>
|
|
||||||
JK Dingwall <james@dingwall.me.uk>
|
|
||||||
Jacek Fefliński <feflik@gmail.com>
|
|
||||||
James Cowgill <james.cowgill@mips.com>
|
|
||||||
James Lee <jlee@thestaticvoid.com>
|
|
||||||
James Pan <jiaming.pan@yahoo.com>
|
|
||||||
Jan Engelhardt <jengelh@inai.de>
|
|
||||||
Jan Kryl <jan.kryl@nexenta.com>
|
|
||||||
Jan Sanislo <oystr@cs.washington.edu>
|
|
||||||
Jason King <jason.brian.king@gmail.com>
|
|
||||||
Jason Zaman <jasonzaman@gmail.com>
|
|
||||||
Javen Wu <wu.javen@gmail.com>
|
|
||||||
Jeremy Gill <jgill@parallax-innovations.com>
|
|
||||||
Jeremy Jones <jeremy@delphix.com>
|
|
||||||
Jerry Jelinek <jerry.jelinek@joyent.com>
|
|
||||||
Jinshan Xiong <jinshan.xiong@intel.com>
|
|
||||||
Joe Stein <joe.stein@delphix.com>
|
|
||||||
John Albietz <inthecloud247@gmail.com>
|
|
||||||
John Eismeier <john.eismeier@gmail.com>
|
|
||||||
John L. Hammond <john.hammond@intel.com>
|
|
||||||
John Layman <jlayman@sagecloud.com>
|
|
||||||
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
|
|
||||||
John Wren Kennedy <john.kennedy@delphix.com>
|
|
||||||
Johnny Stenback <github@jstenback.com>
|
|
||||||
Jorgen Lundman <lundman@lundman.net>
|
|
||||||
Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
|
|
||||||
Joshua M. Clulow <josh@sysmgr.org>
|
|
||||||
Justin Bedő <cu@cua0.org>
|
|
||||||
Justin Lecher <jlec@gentoo.org>
|
|
||||||
Justin T. Gibbs <gibbs@FreeBSD.org>
|
|
||||||
Jörg Thalheim <joerg@higgsboson.tk>
|
|
||||||
KORN Andras <korn@elan.rulez.org>
|
|
||||||
Kamil Domański <kamil@domanski.co>
|
|
||||||
Karsten Kretschmer <kkretschmer@gmail.com>
|
|
||||||
Kash Pande <kash@tripleback.net>
|
|
||||||
Keith M Wesolowski <wesolows@foobazco.org>
|
|
||||||
Kevin Tanguy <kevin.tanguy@ovh.net>
|
|
||||||
KireinaHoro <i@jsteward.moe>
|
|
||||||
Kohsuke Kawaguchi <kk@kohsuke.org>
|
|
||||||
Kyle Blatter <kyleblatter@llnl.gov>
|
|
||||||
Kyle Fuller <inbox@kylefuller.co.uk>
|
|
||||||
Loli <ezomori.nozomu@gmail.com>
|
|
||||||
Lars Johannsen <laj@it.dk>
|
|
||||||
Li Dongyang <dongyang.li@anu.edu.au>
|
|
||||||
Li Wei <W.Li@Sun.COM>
|
|
||||||
Lukas Wunner <lukas@wunner.de>
|
|
||||||
Madhav Suresh <madhav.suresh@delphix.com>
|
|
||||||
Manoj Joseph <manoj.joseph@delphix.com>
|
|
||||||
Manuel Amador (Rudd-O) <rudd-o@rudd-o.com>
|
|
||||||
Marcel Huber <marcelhuberfoo@gmail.com>
|
|
||||||
Marcel Telka <marcel.telka@nexenta.com>
|
|
||||||
Marcel Wysocki <maci.stgn@gmail.com>
|
|
||||||
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
|
|
||||||
Mark Wright <markwright@internode.on.net>
|
|
||||||
Martin Matuska <mm@FreeBSD.org>
|
|
||||||
Massimo Maggi <me@massimo-maggi.eu>
|
|
||||||
Matt Johnston <matt@fugro-fsi.com.au>
|
|
||||||
Matt Kemp <matt@mattikus.com>
|
|
||||||
Matthew Ahrens <matt@delphix.com>
|
|
||||||
Matthew Thode <mthode@mthode.org>
|
|
||||||
Matus Kral <matuskral@me.com>
|
|
||||||
Max Grossman <max.grossman@delphix.com>
|
|
||||||
Maximilian Mehnert <maximilian.mehnert@gmx.de>
|
|
||||||
Michael Gebetsroither <michael@mgeb.org>
|
|
||||||
Michael Kjorling <michael@kjorling.se>
|
|
||||||
Michael Martin <mgmartin.mgm@gmail.com>
|
|
||||||
Mike Gerdts <mike.gerdts@joyent.com>
|
|
||||||
Mike Harsch <mike@harschsystems.com>
|
|
||||||
Mike Leddy <mike.leddy@gmail.com>
|
|
||||||
Mike Swanson <mikeonthecomputer@gmail.com>
|
|
||||||
Milan Jurik <milan.jurik@xylab.cz>
|
|
||||||
Morgan Jones <mjones@rice.edu>
|
|
||||||
Moritz Maxeiner <moritz@ucworks.org>
|
|
||||||
Nathaniel Clark <Nathaniel.Clark@misrule.us>
|
|
||||||
Nathaniel Wesley Filardo <nwf@cs.jhu.edu>
|
|
||||||
Nav Ravindranath <nav@delphix.com>
|
|
||||||
Neal Gompa (ニール・ゴンパ) <ngompa13@gmail.com>
|
|
||||||
Ned Bass <bass6@llnl.gov>
|
|
||||||
Neependra Khare <neependra@kqinfotech.com>
|
|
||||||
Neil Stockbridge <neil@dist.ro>
|
|
||||||
Nick Garvey <garvey.nick@gmail.com>
|
|
||||||
Nikolay Borisov <n.borisov.lkml@gmail.com>
|
|
||||||
Olaf Faaland <faaland1@llnl.gov>
|
|
||||||
Oleg Drokin <green@linuxhacker.ru>
|
|
||||||
Oleg Stepura <oleg@stepura.com>
|
|
||||||
Patrik Greco <sikevux@sikevux.se>
|
|
||||||
Paul B. Henson <henson@acm.org>
|
|
||||||
Paul Dagnelie <pcd@delphix.com>
|
|
||||||
Paul Zuchowski <pzuchowski@datto.com>
|
|
||||||
Pavel Boldin <boldin.pavel@gmail.com>
|
|
||||||
Pavel Zakharov <pavel.zakharov@delphix.com>
|
|
||||||
Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
|
||||||
Pedro Giffuni <pfg@freebsd.org>
|
|
||||||
Peng <peng.hse@xtaotech.com>
|
|
||||||
Peter Ashford <ashford@accs.com>
|
|
||||||
Prakash Surya <prakash.surya@delphix.com>
|
|
||||||
Prasad Joshi <prasadjoshi124@gmail.com>
|
|
||||||
Ralf Ertzinger <ralf@skytale.net>
|
|
||||||
Randall Mason <ClashTheBunny@gmail.com>
|
|
||||||
Remy Blank <remy.blank@pobox.com>
|
|
||||||
Ricardo M. Correia <ricardo.correia@oracle.com>
|
|
||||||
Rich Ercolani <rincebrain@gmail.com>
|
|
||||||
Richard Elling <Richard.Elling@RichardElling.com>
|
|
||||||
Richard Laager <rlaager@wiktel.com>
|
|
||||||
Richard Lowe <richlowe@richlowe.net>
|
|
||||||
Richard Sharpe <rsharpe@samba.org>
|
|
||||||
Richard Yao <ryao@gentoo.org>
|
|
||||||
Rohan Puri <rohan.puri15@gmail.com>
|
|
||||||
Romain Dolbeau <romain.dolbeau@atos.net>
|
|
||||||
Roman Strashkin <roman.strashkin@nexenta.com>
|
|
||||||
Ruben Kerkhof <ruben@rubenkerkhof.com>
|
|
||||||
Saso Kiselkov <saso.kiselkov@nexenta.com>
|
|
||||||
Scot W. Stevenson <scot.stevenson@gmail.com>
|
|
||||||
Sean Eric Fagan <sef@ixsystems.com>
|
|
||||||
Sen Haerens <sen@senhaerens.be>
|
|
||||||
Serapheim Dimitropoulos <serapheim@delphix.com>
|
|
||||||
Seth Forshee <seth.forshee@canonical.com>
|
|
||||||
Shampavman <sham.pavman@nexenta.com>
|
|
||||||
Shen Yan <shenyanxxxy@qq.com>
|
|
||||||
Simon Guest <simon.guest@tesujimath.org>
|
|
||||||
Simon Klinkert <simon.klinkert@gmail.com>
|
|
||||||
Sowrabha Gopal <sowrabha.gopal@delphix.com>
|
|
||||||
Stanislav Seletskiy <s.seletskiy@gmail.com>
|
|
||||||
Steffen Müthing <steffen.muething@iwr.uni-heidelberg.de>
|
|
||||||
Stephen Blinick <stephen.blinick@delphix.com>
|
|
||||||
Steve Dougherty <sdougherty@barracuda.com>
|
|
||||||
Steven Burgess <sburgess@dattobackup.com>
|
|
||||||
Steven Hartland <smh@freebsd.org>
|
|
||||||
Steven Johnson <sjohnson@sakuraindustries.com>
|
|
||||||
Stian Ellingsen <stian@plaimi.net>
|
|
||||||
Suman Chakravartula <schakrava@gmail.com>
|
|
||||||
Sydney Vanda <sydney.m.vanda@intel.com>
|
|
||||||
Sören Tempel <soeren+git@soeren-tempel.net>
|
|
||||||
Thijs Cramer <thijs.cramer@gmail.com>
|
|
||||||
Tim Chase <tim@chase2k.com>
|
|
||||||
Tim Connors <tconnors@rather.puzzling.org>
|
|
||||||
Tim Crawford <tcrawford@datto.com>
|
|
||||||
Tim Haley <Tim.Haley@Sun.COM>
|
|
||||||
Tobin Harding <me@tobin.cc>
|
|
||||||
Tom Caputi <tcaputi@datto.com>
|
|
||||||
Tom Matthews <tom@axiom-partners.com>
|
|
||||||
Tom Prince <tom.prince@ualberta.net>
|
|
||||||
Tomohiro Kusumi <kusumi.tomohiro@gmail.com>
|
|
||||||
Tony Hutter <hutter2@llnl.gov>
|
|
||||||
Toomas Soome <tsoome@me.com>
|
|
||||||
Trey Dockendorf <treydock@gmail.com>
|
|
||||||
Turbo Fredriksson <turbo@bayour.com>
|
|
||||||
Tyler J. Stachecki <stachecki.tyler@gmail.com>
|
|
||||||
Vitaut Bajaryn <vitaut.bayaryn@gmail.com>
|
|
||||||
Weigang Li <weigang.li@intel.com>
|
|
||||||
Will Andrews <will@freebsd.org>
|
|
||||||
Will Rouesnel <w.rouesnel@gmail.com>
|
|
||||||
Wolfgang Bumiller <w.bumiller@proxmox.com>
|
|
||||||
Xin Li <delphij@FreeBSD.org>
|
|
||||||
Ying Zhu <casualfisher@gmail.com>
|
|
||||||
YunQiang Su <syq@debian.org>
|
|
||||||
Yuri Pankov <yuri.pankov@gmail.com>
|
|
||||||
Yuxuan Shui <yshuiv7@gmail.com>
|
|
||||||
Zachary Bedell <zac@thebedells.org>
|
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
The [OpenZFS Code of Conduct](http://www.open-zfs.org/wiki/Code_of_Conduct)
|
|
||||||
applies to spaces associated with the ZFS on Linux project, including GitHub.
|
|
||||||
@@ -1,31 +1,33 @@
|
|||||||
Refer to the git commit log for authoritative copyright attribution.
|
The majority of the code in the ZFS on Linux port comes from OpenSolaris
|
||||||
|
which has been released under the terms of the CDDL open source license.
|
||||||
|
This includes the core ZFS code, libavl, libnvpair, libefi, libunicode,
|
||||||
|
and libutil. The original OpenSolaris source can be downloaded from:
|
||||||
|
|
||||||
The original ZFS source code was obtained from Open Solaris which was
|
http://dlc.sun.com/osol/on/downloads/b121/on-src.tar.bz2
|
||||||
released under the terms of the CDDL open source license. Additional
|
|
||||||
changes have been included from OpenZFS and the Illumos project which
|
|
||||||
are similarly licensed. These projects can be found on Github at:
|
|
||||||
|
|
||||||
* https://github.com/illumos/illumos-gate
|
Files which do not originate from OpenSolaris are noted in the file header
|
||||||
* https://github.com/openzfs/openzfs
|
and attributed properly. These exceptions include, but are not limited
|
||||||
|
to, the vdev_disk.c and zvol.c implementation which are licensed under
|
||||||
|
the CDDL.
|
||||||
|
|
||||||
|
The zpios test code is originally derived from the Lustre pios test code
|
||||||
|
which is licensed under the GPLv2. As such the heavily modified zpios
|
||||||
|
kernel test code also remains licensed under the GPLv2.
|
||||||
|
|
||||||
|
The latest stable and development versions of this port can be downloaded
|
||||||
|
from the official ZFS on Linux site located at:
|
||||||
|
|
||||||
|
http://zfsonlinux.org/
|
||||||
|
|
||||||
|
This ZFS on Linux port was produced at the Lawrence Livermore National
|
||||||
|
Laboratory (LLNL) under Contract No. DE-AC52-07NA27344 (Contract 44)
|
||||||
|
between the U.S. Department of Energy (DOE) and Lawrence Livermore
|
||||||
|
National Security, LLC (LLNS) for the operation of LLNL. It has been
|
||||||
|
approved for release under LLNL-CODE-403049.
|
||||||
|
|
||||||
Unless otherwise noted, all files in this distribution are released
|
Unless otherwise noted, all files in this distribution are released
|
||||||
under the Common Development and Distribution License (CDDL).
|
under the Common Development and Distribution License (CDDL).
|
||||||
|
Exceptions are noted within the associated source files. See the file
|
||||||
|
OPENSOLARIS.LICENSE for more information.
|
||||||
|
|
||||||
Exceptions are noted within the associated source files headers and
|
Refer to the git commit log for authoritative copyright attribution.
|
||||||
by including a THIRDPARTYLICENSE file with the license terms. A few
|
|
||||||
notable exceptions and their respective licenses include:
|
|
||||||
|
|
||||||
* Skein Checksum Implementation: module/icp/algs/skein/THIRDPARTYLICENSE
|
|
||||||
* AES Implementation: module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.gladman
|
|
||||||
* AES Implementation: module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.openssl
|
|
||||||
* PBKDF2 Implementation: lib/libzfs/THIRDPARTYLICENSE.openssl
|
|
||||||
* SPL Implementation: module/spl/THIRDPARTYLICENSE.gplv2
|
|
||||||
* GCM Implementaion: module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.cryptogams
|
|
||||||
* GCM Implementaion: module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.openssl
|
|
||||||
* GHASH Implementaion: module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.cryptogams
|
|
||||||
* GHASH Implementaion: module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.openssl
|
|
||||||
|
|
||||||
This product includes software developed by the OpenSSL Project for use
|
|
||||||
in the OpenSSL Toolkit (http://www.openssl.org/)
|
|
||||||
|
|
||||||
See the LICENSE and NOTICE for more information.
|
|
||||||
|
|||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
This work was produced at the Lawrence Livermore National Laboratory
|
||||||
|
(LLNL) under Contract No. DE-AC52-07NA27344 (Contract 44) between
|
||||||
|
the U.S. Department of Energy (DOE) and Lawrence Livermore National
|
||||||
|
Security, LLC (LLNS) for the operation of LLNL.
|
||||||
|
|
||||||
|
This work was prepared as an account of work sponsored by an agency of
|
||||||
|
the United States Government. Neither the United States Government nor
|
||||||
|
Lawrence Livermore National Security, LLC nor any of their employees,
|
||||||
|
makes any warranty, express or implied, or assumes any liability or
|
||||||
|
responsibility for the accuracy, completeness, or usefulness of any
|
||||||
|
information, apparatus, product, or process disclosed, or represents
|
||||||
|
that its use would not infringe privately-owned rights.
|
||||||
|
|
||||||
|
Reference herein to any specific commercial products, process, or
|
||||||
|
services by trade name, trademark, manufacturer or otherwise does
|
||||||
|
not necessarily constitute or imply its endorsement, recommendation,
|
||||||
|
or favoring by the United States Government or Lawrence Livermore
|
||||||
|
National Security, LLC. The views and opinions of authors expressed
|
||||||
|
herein do not necessarily state or reflect those of the United States
|
||||||
|
Government or Lawrence Livermore National Security, LLC, and shall
|
||||||
|
not be used for advertising or product endorsement purposes.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution, and
|
||||||
|
modification are specified in the file OPENSOLARIS.LICENSE.
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
Meta: 1
|
Meta: 1
|
||||||
Name: zfs
|
Name: zfs
|
||||||
Branch: 1.0
|
Branch: 1.0
|
||||||
Version: 0.8.5
|
Version: 0.7.13
|
||||||
Release: 1
|
Release: 1
|
||||||
Release-Tags: relext
|
Release-Tags: relext
|
||||||
License: CDDL
|
License: CDDL
|
||||||
Author: OpenZFS on Linux
|
Author: OpenZFS on Linux
|
||||||
Linux-Maximum: 5.6
|
|
||||||
Linux-Minimum: 2.6.32
|
|
||||||
|
|||||||
+18
-93
@@ -11,42 +11,22 @@ endif
|
|||||||
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
|
||||||
|
|
||||||
kerneldir = $(prefix)/src/zfs-$(VERSION)/$(LINUX_VERSION)
|
kerneldir = @prefix@/src/zfs-$(VERSION)/$(LINUX_VERSION)
|
||||||
nodist_kernel_HEADERS = zfs.release zfs_config.h module/$(LINUX_SYMBOLS)
|
nodist_kernel_HEADERS = zfs.release zfs_config.h module/$(LINUX_SYMBOLS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
AUTOMAKE_OPTIONS = foreign
|
AUTOMAKE_OPTIONS = foreign
|
||||||
EXTRA_DIST = autogen.sh copy-builtin
|
EXTRA_DIST = autogen.sh copy-builtin
|
||||||
EXTRA_DIST += config/config.awk config/rpm.am config/deb.am config/tgz.am
|
EXTRA_DIST += config/config.awk config/rpm.am config/deb.am config/tgz.am
|
||||||
EXTRA_DIST += META AUTHORS COPYRIGHT LICENSE NEWS NOTICE README.md
|
EXTRA_DIST += META DISCLAIMER COPYRIGHT README.markdown OPENSOLARIS.LICENSE
|
||||||
EXTRA_DIST += CODE_OF_CONDUCT.md
|
|
||||||
|
|
||||||
# Include all the extra licensing information for modules
|
|
||||||
EXTRA_DIST += module/icp/algs/skein/THIRDPARTYLICENSE
|
|
||||||
EXTRA_DIST += module/icp/algs/skein/THIRDPARTYLICENSE.descrip
|
|
||||||
EXTRA_DIST += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.gladman
|
|
||||||
EXTRA_DIST += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.gladman.descrip
|
|
||||||
EXTRA_DIST += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.openssl
|
|
||||||
EXTRA_DIST += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.openssl.descrip
|
|
||||||
EXTRA_DIST += module/spl/THIRDPARTYLICENSE.gplv2
|
|
||||||
EXTRA_DIST += module/spl/THIRDPARTYLICENSE.gplv2.descrip
|
|
||||||
EXTRA_DIST += module/zfs/THIRDPARTYLICENSE.cityhash
|
|
||||||
EXTRA_DIST += module/zfs/THIRDPARTYLICENSE.cityhash.descrip
|
|
||||||
|
|
||||||
@CODE_COVERAGE_RULES@
|
@CODE_COVERAGE_RULES@
|
||||||
|
|
||||||
.PHONY: gitrev
|
|
||||||
gitrev:
|
|
||||||
-${top_srcdir}/scripts/make_gitrev.sh
|
|
||||||
|
|
||||||
BUILT_SOURCES = gitrev
|
|
||||||
|
|
||||||
# Double-colon rules are allowed; there are multiple independent definitions.
|
|
||||||
distclean-local::
|
distclean-local::
|
||||||
-$(RM) -R autom4te*.cache build
|
-$(RM) -R autom4te*.cache
|
||||||
-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 \
|
||||||
\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
|
\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
|
||||||
@@ -57,79 +37,30 @@ distclean-local::
|
|||||||
-o -name '*.gcno' \) \
|
-o -name '*.gcno' \) \
|
||||||
-type f -print | xargs $(RM)
|
-type f -print | xargs $(RM)
|
||||||
|
|
||||||
all-local:
|
dist-hook:
|
||||||
-[ -x ${top_builddir}/scripts/zfs-tests.sh ] && \
|
|
||||||
${top_builddir}/scripts/zfs-tests.sh -c
|
|
||||||
|
|
||||||
dist-hook: gitrev
|
|
||||||
cp ${top_srcdir}/include/zfs_gitrev.h $(distdir)/include; \
|
|
||||||
sed -i 's/Release:[[:print:]]*/Release: $(RELEASE)/' \
|
sed -i 's/Release:[[:print:]]*/Release: $(RELEASE)/' \
|
||||||
$(distdir)/META
|
$(distdir)/META
|
||||||
|
|
||||||
# For compatibility, create a matching spl-x.y.z directly which contains
|
checkstyle: cstyle shellcheck flake8 commitcheck
|
||||||
# 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
|
|
||||||
|
|
||||||
codecheck: cstyle shellcheck flake8 mancheck testscheck vcscheck
|
|
||||||
|
|
||||||
checkstyle: codecheck commitcheck
|
|
||||||
|
|
||||||
commitcheck:
|
commitcheck:
|
||||||
@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; \
|
scripts/commitcheck.sh; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cstyle:
|
cstyle:
|
||||||
@find ${top_srcdir} -name build -prune -o -name '*.[hc]' \
|
@find ${top_srcdir} -name '*.[hc]' ! -name 'zfs_config.*' \
|
||||||
! -name 'zfs_config.*' ! -name '*.mod.c' -type f \
|
! -name '*.mod.c' -type f -exec scripts/cstyle.pl -cpP {} \+
|
||||||
-exec ${top_srcdir}/scripts/cstyle.pl -cpP {} \+
|
|
||||||
|
|
||||||
shellcheck:
|
shellcheck:
|
||||||
@if type shellcheck > /dev/null 2>&1; then \
|
@if type shellcheck > /dev/null 2>&1; then \
|
||||||
shellcheck --exclude=SC1090 --format=gcc \
|
shellcheck --exclude=SC1090 --format=gcc scripts/paxcheck.sh \
|
||||||
$$(find ${top_srcdir}/scripts/*.sh -type f) \
|
scripts/zloop.sh \
|
||||||
$$(find ${top_srcdir}/cmd/zed/zed.d/*.sh -type f) \
|
scripts/zfs-tests.sh \
|
||||||
$$(find ${top_srcdir}/cmd/zpool/zpool.d/* -executable); \
|
scripts/zfs.sh \
|
||||||
else \
|
scripts/commitcheck.sh \
|
||||||
echo "skipping shellcheck because shellcheck is not installed"; \
|
$$(find cmd/zed/zed.d/*.sh -type f) \
|
||||||
fi
|
$$(find cmd/zpool/zpool.d/* -executable); \
|
||||||
|
|
||||||
mancheck:
|
|
||||||
@if type mandoc > /dev/null 2>&1; then \
|
|
||||||
find ${top_srcdir}/man/man8 -type f -name 'zfs.8' \
|
|
||||||
-o -name 'zpool.8' -o -name 'zdb.8' \
|
|
||||||
-o -name 'zgenhostid.8' | \
|
|
||||||
xargs mandoc -Tlint -Werror; \
|
|
||||||
else \
|
|
||||||
echo "skipping mancheck because mandoc is not installed"; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
testscheck:
|
|
||||||
@find ${top_srcdir}/tests/zfs-tests -type f \
|
|
||||||
\( -name '*.ksh' -not -executable \) -o \
|
|
||||||
\( -name '*.kshlib' -executable \) -o \
|
|
||||||
\( -name '*.shlib' -executable \) -o \
|
|
||||||
\( -name '*.cfg' -executable \) | \
|
|
||||||
xargs -r stat -c '%A %n' | \
|
|
||||||
awk '{c++; print} END {if(c>0) exit 1}'
|
|
||||||
|
|
||||||
vcscheck:
|
|
||||||
@if git rev-parse --git-dir > /dev/null 2>&1; then \
|
|
||||||
git ls-files . --exclude-standard --others | \
|
|
||||||
awk '{c++; print} END {if(c>0) exit 1}' ; \
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
lint: cppcheck paxcheck
|
lint: cppcheck paxcheck
|
||||||
@@ -139,23 +70,17 @@ cppcheck:
|
|||||||
cppcheck --quiet --force --error-exitcode=2 --inline-suppr \
|
cppcheck --quiet --force --error-exitcode=2 --inline-suppr \
|
||||||
--suppressions-list=.github/suppressions.txt \
|
--suppressions-list=.github/suppressions.txt \
|
||||||
-UHAVE_SSE2 -UHAVE_AVX512F -UHAVE_UIO_ZEROCOPY \
|
-UHAVE_SSE2 -UHAVE_AVX512F -UHAVE_UIO_ZEROCOPY \
|
||||||
${top_srcdir}; \
|
-UHAVE_DNLC ${top_srcdir}; \
|
||||||
else \
|
|
||||||
echo "skipping cppcheck because cppcheck is not installed"; \
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
paxcheck:
|
paxcheck:
|
||||||
@if type scanelf > /dev/null 2>&1; then \
|
@if type scanelf > /dev/null 2>&1; then \
|
||||||
${top_srcdir}/scripts/paxcheck.sh ${top_srcdir}; \
|
scripts/paxcheck.sh ${top_srcdir}; \
|
||||||
else \
|
|
||||||
echo "skipping paxcheck because scanelf is not installed"; \
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
flake8:
|
flake8:
|
||||||
@if type flake8 > /dev/null 2>&1; then \
|
@if type flake8 > /dev/null 2>&1; then \
|
||||||
flake8 ${top_srcdir}; \
|
flake8 ${top_srcdir}; \
|
||||||
else \
|
|
||||||
echo "skipping flake8 because flake8 is not installed"; \
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ctags:
|
ctags:
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
Descriptions of all releases can be found on github:
|
|
||||||
|
|
||||||
https://github.com/zfsonlinux/zfs/releases
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
This work was produced under the auspices of the U.S. Department of Energy by
|
|
||||||
Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.
|
|
||||||
|
|
||||||
This work was prepared as an account of work sponsored by an agency of the
|
|
||||||
United States Government. Neither the United States Government nor Lawrence
|
|
||||||
Livermore National Security, LLC, nor any of their employees makes any warranty,
|
|
||||||
expressed or implied, or assumes any legal liability or responsibility for the
|
|
||||||
accuracy, completeness, or usefulness of any information, apparatus, product, or
|
|
||||||
process disclosed, or represents that its use would not infringe privately owned
|
|
||||||
rights. Reference herein to any specific commercial product, process, or service
|
|
||||||
by trade name, trademark, manufacturer, or otherwise does not necessarily
|
|
||||||
constitute or imply its endorsement, recommendation, or favoring by the United
|
|
||||||
States Government or Lawrence Livermore National Security, LLC. The views and
|
|
||||||
opinions of authors expressed herein do not necessarily state or reflect those
|
|
||||||
of the United States Government or Lawrence Livermore National Security, LLC,
|
|
||||||
and shall not be used for advertising or product endorsement purposes.
|
|
||||||
@@ -4,28 +4,16 @@ ZFS on Linux is an advanced file system and volume manager which was originally
|
|||||||
developed for Solaris and is now maintained by the OpenZFS community.
|
developed for Solaris and is now maintained by the OpenZFS community.
|
||||||
|
|
||||||
[](https://codecov.io/gh/zfsonlinux/zfs)
|
[](https://codecov.io/gh/zfsonlinux/zfs)
|
||||||
[](https://scan.coverity.com/projects/zfsonlinux-zfs)
|
|
||||||
|
|
||||||
# Official Resources
|
# Official Resources
|
||||||
|
|
||||||
* [Site](http://zfsonlinux.org)
|
* [Site](http://zfsonlinux.org)
|
||||||
* [Wiki](https://github.com/zfsonlinux/zfs/wiki)
|
* [Wiki](https://github.com/zfsonlinux/zfs/wiki)
|
||||||
* [Mailing lists](https://github.com/zfsonlinux/zfs/wiki/Mailing-Lists)
|
* [Mailing lists](https://github.com/zfsonlinux/zfs/wiki/Mailing-Lists)
|
||||||
* [OpenZFS site](http://open-zfs.org/)
|
* [OpenZFS site](http://open-zfs.org/)
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
Full documentation for installing ZoL on your favorite Linux distribution can
|
Full documentation for installing ZoL on your favorite Linux distribution can
|
||||||
be found at [our site](http://zfsonlinux.org/).
|
be found at [our site](http://zfsonlinux.org/).
|
||||||
|
|
||||||
# Contribute & Develop
|
# Contribute & Develop
|
||||||
|
|
||||||
We have a separate document with [contribution guidelines](./.github/CONTRIBUTING.md).
|
We have a separate document with [contribution guidelines](./.github/CONTRIBUTING.md).
|
||||||
|
|
||||||
# Release
|
|
||||||
|
|
||||||
ZFS on Linux is released under a CDDL license.
|
|
||||||
For more details see the NOTICE, LICENSE and COPYRIGHT files; `UCRL-CODE-235197`
|
|
||||||
|
|
||||||
# Supported Kernels
|
|
||||||
* The `META` file contains the officially recognized supported kernel versions.
|
|
||||||
@@ -1,15 +1,17 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
### prepare
|
### prepare
|
||||||
#TEST_PREPARE_WATCHDOG="yes"
|
#TEST_PREPARE_WATCHDOG="no"
|
||||||
#TEST_PREPARE_SHARES="yes"
|
|
||||||
|
### SPLAT
|
||||||
|
#TEST_SPLAT_SKIP="yes"
|
||||||
|
#TEST_SPLAT_OPTIONS="-acvx"
|
||||||
|
|
||||||
### ztest
|
### ztest
|
||||||
#TEST_ZTEST_SKIP="yes"
|
#TEST_ZTEST_SKIP="yes"
|
||||||
#TEST_ZTEST_TIMEOUT=1800
|
#TEST_ZTEST_TIMEOUT=1800
|
||||||
#TEST_ZTEST_DIR="/var/tmp/"
|
#TEST_ZTEST_DIR="/var/tmp/"
|
||||||
#TEST_ZTEST_OPTIONS="-V"
|
#TEST_ZTEST_OPTIONS="-V"
|
||||||
#TEST_ZTEST_CORE_DIR="/mnt/zloop"
|
|
||||||
|
|
||||||
### zimport
|
### zimport
|
||||||
#TEST_ZIMPORT_SKIP="yes"
|
#TEST_ZIMPORT_SKIP="yes"
|
||||||
@@ -29,13 +31,9 @@
|
|||||||
|
|
||||||
### zfs-tests.sh
|
### zfs-tests.sh
|
||||||
#TEST_ZFSTESTS_SKIP="yes"
|
#TEST_ZFSTESTS_SKIP="yes"
|
||||||
#TEST_ZFSTESTS_DIR="/mnt/"
|
|
||||||
#TEST_ZFSTESTS_DISKS="vdb vdc vdd"
|
#TEST_ZFSTESTS_DISKS="vdb vdc vdd"
|
||||||
#TEST_ZFSTESTS_DISKSIZE="8G"
|
#TEST_ZFSTESTS_DISKSIZE="8G"
|
||||||
#TEST_ZFSTESTS_ITERS="1"
|
|
||||||
#TEST_ZFSTESTS_OPTIONS="-vx"
|
|
||||||
#TEST_ZFSTESTS_RUNFILE="linux.run"
|
#TEST_ZFSTESTS_RUNFILE="linux.run"
|
||||||
#TEST_ZFSTESTS_TAGS="functional"
|
|
||||||
|
|
||||||
### zfsstress
|
### zfsstress
|
||||||
#TEST_ZFSSTRESS_SKIP="yes"
|
#TEST_ZFSSTRESS_SKIP="yes"
|
||||||
@@ -44,7 +42,6 @@
|
|||||||
#TEST_ZFSSTRESS_RUNTIME=300
|
#TEST_ZFSSTRESS_RUNTIME=300
|
||||||
#TEST_ZFSSTRESS_POOL="tank"
|
#TEST_ZFSSTRESS_POOL="tank"
|
||||||
#TEST_ZFSSTRESS_FS="fish"
|
#TEST_ZFSSTRESS_FS="fish"
|
||||||
#TEST_ZFSSTRESS_FSOPT="-o overlay=on"
|
|
||||||
#TEST_ZFSSTRESS_VDEV="/var/tmp/vdev"
|
#TEST_ZFSSTRESS_VDEV="/var/tmp/vdev"
|
||||||
#TEST_ZFSSTRESS_DIR="/$TEST_ZFSSTRESS_POOL/$TEST_ZFSSTRESS_FS"
|
#TEST_ZFSSTRESS_DIR="/$TEST_ZFSSTRESS_POOL/$TEST_ZFSSTRESS_FS"
|
||||||
#TEST_ZFSSTRESS_OPTIONS=""
|
#TEST_ZFSSTRESS_OPTIONS=""
|
||||||
@@ -86,20 +83,6 @@ Ubuntu*)
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
###
|
|
||||||
#
|
|
||||||
# Run ztest longer on the "coverage" builders to gain more code coverage
|
|
||||||
# data out of ztest, libzpool, etc.
|
|
||||||
#
|
|
||||||
case "$BB_NAME" in
|
|
||||||
*coverage*)
|
|
||||||
TEST_ZTEST_TIMEOUT=3600
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
TEST_ZTEST_TIMEOUT=900
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
###
|
###
|
||||||
#
|
#
|
||||||
# Disable the following test suites on 32-bit systems.
|
# Disable the following test suites on 32-bit systems.
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
autoreconf -fiv || exit 1
|
autoreconf -fiv
|
||||||
rm -Rf autom4te.cache
|
rm -Rf autom4te.cache
|
||||||
|
|||||||
+3
-8
@@ -1,8 +1,3 @@
|
|||||||
SUBDIRS = zfs zpool zdb zhack zinject zstreamdump ztest
|
SUBDIRS = zfs zpool zdb zhack zinject zstreamdump ztest zpios
|
||||||
SUBDIRS += fsck_zfs vdev_id raidz_test zgenhostid
|
SUBDIRS += mount_zfs fsck_zfs zvol_id vdev_id arcstat dbufstat zed
|
||||||
|
SUBDIRS += arc_summary raidz_test zgenhostid
|
||||||
if USING_PYTHON
|
|
||||||
SUBDIRS += arcstat arc_summary dbufstat
|
|
||||||
endif
|
|
||||||
|
|
||||||
SUBDIRS += mount_zfs zed zvol_id zvol_wait
|
|
||||||
|
|||||||
@@ -1,11 +1 @@
|
|||||||
EXTRA_DIST = arc_summary2 arc_summary3
|
dist_bin_SCRIPTS = arc_summary.py
|
||||||
|
|
||||||
if USING_PYTHON_2
|
|
||||||
dist_bin_SCRIPTS = arc_summary2
|
|
||||||
install-exec-hook:
|
|
||||||
mv $(DESTDIR)$(bindir)/arc_summary2 $(DESTDIR)$(bindir)/arc_summary
|
|
||||||
else
|
|
||||||
dist_bin_SCRIPTS = arc_summary3
|
|
||||||
install-exec-hook:
|
|
||||||
mv $(DESTDIR)$(bindir)/arc_summary3 $(DESTDIR)$(bindir)/arc_summary
|
|
||||||
endif
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/python
|
||||||
#
|
#
|
||||||
# $Id: arc_summary.pl,v 388:e27800740aa2 2011-07-08 02:53:29Z jhell $
|
# $Id: arc_summary.pl,v 388:e27800740aa2 2011-07-08 02:53:29Z jhell $
|
||||||
#
|
#
|
||||||
@@ -35,8 +35,6 @@
|
|||||||
# Note some of this code uses older code (eg getopt instead of argparse,
|
# Note some of this code uses older code (eg getopt instead of argparse,
|
||||||
# subprocess.Popen() instead of subprocess.run()) because we need to support
|
# subprocess.Popen() instead of subprocess.run()) because we need to support
|
||||||
# some very old versions of Python.
|
# some very old versions of Python.
|
||||||
#
|
|
||||||
|
|
||||||
"""Print statistics on the ZFS Adjustable Replacement Cache (ARC)
|
"""Print statistics on the ZFS Adjustable Replacement Cache (ARC)
|
||||||
|
|
||||||
Provides basic information on the ARC, its efficiency, the L2ARC (if present),
|
Provides basic information on the ARC, its efficiency, the L2ARC (if present),
|
||||||
@@ -206,10 +204,6 @@ def get_arc_summary(Kstat):
|
|||||||
arc_size = Kstat["kstat.zfs.misc.arcstats.size"]
|
arc_size = Kstat["kstat.zfs.misc.arcstats.size"]
|
||||||
mru_size = Kstat["kstat.zfs.misc.arcstats.mru_size"]
|
mru_size = Kstat["kstat.zfs.misc.arcstats.mru_size"]
|
||||||
mfu_size = Kstat["kstat.zfs.misc.arcstats.mfu_size"]
|
mfu_size = Kstat["kstat.zfs.misc.arcstats.mfu_size"]
|
||||||
meta_limit = Kstat["kstat.zfs.misc.arcstats.arc_meta_limit"]
|
|
||||||
meta_size = Kstat["kstat.zfs.misc.arcstats.arc_meta_used"]
|
|
||||||
dnode_limit = Kstat["kstat.zfs.misc.arcstats.arc_dnode_limit"]
|
|
||||||
dnode_size = Kstat["kstat.zfs.misc.arcstats.dnode_size"]
|
|
||||||
target_max_size = Kstat["kstat.zfs.misc.arcstats.c_max"]
|
target_max_size = Kstat["kstat.zfs.misc.arcstats.c_max"]
|
||||||
target_min_size = Kstat["kstat.zfs.misc.arcstats.c_min"]
|
target_min_size = Kstat["kstat.zfs.misc.arcstats.c_min"]
|
||||||
target_size = Kstat["kstat.zfs.misc.arcstats.c"]
|
target_size = Kstat["kstat.zfs.misc.arcstats.c"]
|
||||||
@@ -234,22 +228,6 @@ def get_arc_summary(Kstat):
|
|||||||
'per': fPerc(target_size, target_max_size),
|
'per': fPerc(target_size, target_max_size),
|
||||||
'num': fBytes(target_size),
|
'num': fBytes(target_size),
|
||||||
}
|
}
|
||||||
output['arc_sizing']['meta_limit'] = {
|
|
||||||
'per': fPerc(meta_limit, target_max_size),
|
|
||||||
'num': fBytes(meta_limit),
|
|
||||||
}
|
|
||||||
output['arc_sizing']['meta_size'] = {
|
|
||||||
'per': fPerc(meta_size, meta_limit),
|
|
||||||
'num': fBytes(meta_size),
|
|
||||||
}
|
|
||||||
output['arc_sizing']['dnode_limit'] = {
|
|
||||||
'per': fPerc(dnode_limit, meta_limit),
|
|
||||||
'num': fBytes(dnode_limit),
|
|
||||||
}
|
|
||||||
output['arc_sizing']['dnode_size'] = {
|
|
||||||
'per': fPerc(dnode_size, dnode_limit),
|
|
||||||
'num': fBytes(dnode_size),
|
|
||||||
}
|
|
||||||
|
|
||||||
# ARC Hash Breakdown
|
# ARC Hash Breakdown
|
||||||
output['arc_hash_break'] = {}
|
output['arc_hash_break'] = {}
|
||||||
@@ -355,26 +333,6 @@ def _arc_summary(Kstat):
|
|||||||
arc['arc_size_break']['frequently_used_cache_size']['num'],
|
arc['arc_size_break']['frequently_used_cache_size']['num'],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
sys.stdout.write("\tMetadata Size (Hard Limit):\t%s\t%s\n" % (
|
|
||||||
arc['arc_sizing']['meta_limit']['per'],
|
|
||||||
arc['arc_sizing']['meta_limit']['num'],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
sys.stdout.write("\tMetadata Size:\t\t\t%s\t%s\n" % (
|
|
||||||
arc['arc_sizing']['meta_size']['per'],
|
|
||||||
arc['arc_sizing']['meta_size']['num'],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
sys.stdout.write("\tDnode Size (Hard Limit):\t%s\t%s\n" % (
|
|
||||||
arc['arc_sizing']['dnode_limit']['per'],
|
|
||||||
arc['arc_sizing']['dnode_limit']['num'],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
sys.stdout.write("\tDnode Size:\t\t\t%s\t%s\n" % (
|
|
||||||
arc['arc_sizing']['dnode_size']['per'],
|
|
||||||
arc['arc_sizing']['dnode_size']['num'],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
sys.stdout.write("\n")
|
sys.stdout.write("\n")
|
||||||
|
|
||||||
@@ -1007,7 +965,7 @@ def zfs_header():
|
|||||||
def usage():
|
def usage():
|
||||||
"""Print usage information"""
|
"""Print usage information"""
|
||||||
|
|
||||||
sys.stdout.write("Usage: arc_summary [-h] [-a] [-d] [-p PAGE]\n\n")
|
sys.stdout.write("Usage: arc_summary.py [-h] [-a] [-d] [-p PAGE]\n\n")
|
||||||
sys.stdout.write("\t -h, --help : "
|
sys.stdout.write("\t -h, --help : "
|
||||||
"Print this help message and exit\n")
|
"Print this help message and exit\n")
|
||||||
sys.stdout.write("\t -a, --alternate : "
|
sys.stdout.write("\t -a, --alternate : "
|
||||||
@@ -1020,10 +978,10 @@ def usage():
|
|||||||
"should be an integer between 1 and " +
|
"should be an integer between 1 and " +
|
||||||
str(len(unSub)) + "\n\n")
|
str(len(unSub)) + "\n\n")
|
||||||
sys.stdout.write("Examples:\n")
|
sys.stdout.write("Examples:\n")
|
||||||
sys.stdout.write("\tarc_summary -a\n")
|
sys.stdout.write("\tarc_summary.py -a\n")
|
||||||
sys.stdout.write("\tarc_summary -p 4\n")
|
sys.stdout.write("\tarc_summary.py -p 4\n")
|
||||||
sys.stdout.write("\tarc_summary -ad\n")
|
sys.stdout.write("\tarc_summary.py -ad\n")
|
||||||
sys.stdout.write("\tarc_summary --page=2\n")
|
sys.stdout.write("\tarc_summary.py --page=2\n")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@@ -1,875 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
#
|
|
||||||
# Copyright (c) 2008 Ben Rockwood <benr@cuddletech.com>,
|
|
||||||
# Copyright (c) 2010 Martin Matuska <mm@FreeBSD.org>,
|
|
||||||
# Copyright (c) 2010-2011 Jason J. Hellenthal <jhell@DataIX.net>,
|
|
||||||
# Copyright (c) 2017 Scot W. Stevenson <scot.stevenson@gmail.com>
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions
|
|
||||||
# are met:
|
|
||||||
#
|
|
||||||
# 1. Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
# 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in the
|
|
||||||
# documentation and/or other materials provided with the distribution.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
# SUCH DAMAGE.
|
|
||||||
"""Print statistics on the ZFS ARC Cache and other information
|
|
||||||
|
|
||||||
Provides basic information on the ARC, its efficiency, the L2ARC (if present),
|
|
||||||
the Data Management Unit (DMU), Virtual Devices (VDEVs), and tunables. See
|
|
||||||
the in-source documentation and code at
|
|
||||||
https://github.com/zfsonlinux/zfs/blob/master/module/zfs/arc.c for details.
|
|
||||||
The original introduction to arc_summary can be found at
|
|
||||||
http://cuddletech.com/?p=454
|
|
||||||
"""
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
DESCRIPTION = 'Print ARC and other statistics for ZFS on Linux'
|
|
||||||
INDENT = ' '*8
|
|
||||||
LINE_LENGTH = 72
|
|
||||||
PROC_PATH = '/proc/spl/kstat/zfs/'
|
|
||||||
SPL_PATH = '/sys/module/spl/parameters/'
|
|
||||||
TUNABLES_PATH = '/sys/module/zfs/parameters/'
|
|
||||||
DATE_FORMAT = '%a %b %d %H:%M:%S %Y'
|
|
||||||
TITLE = 'ZFS Subsystem Report'
|
|
||||||
|
|
||||||
SECTIONS = 'arc archits dmu l2arc spl tunables vdev zil'.split()
|
|
||||||
SECTION_HELP = 'print info from one section ('+' '.join(SECTIONS)+')'
|
|
||||||
|
|
||||||
# Tunables and SPL are handled separately because they come from
|
|
||||||
# different sources
|
|
||||||
SECTION_PATHS = {'arc': 'arcstats',
|
|
||||||
'dmu': 'dmu_tx',
|
|
||||||
'l2arc': 'arcstats', # L2ARC stuff lives in arcstats
|
|
||||||
'vdev': 'vdev_cache_stats',
|
|
||||||
'xuio': 'xuio_stats',
|
|
||||||
'zfetch': 'zfetchstats',
|
|
||||||
'zil': 'zil'}
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description=DESCRIPTION)
|
|
||||||
parser.add_argument('-a', '--alternate', action='store_true', default=False,
|
|
||||||
help='use alternate formatting for tunables and SPL',
|
|
||||||
dest='alt')
|
|
||||||
parser.add_argument('-d', '--description', action='store_true', default=False,
|
|
||||||
help='print descriptions with tunables and SPL',
|
|
||||||
dest='desc')
|
|
||||||
parser.add_argument('-g', '--graph', action='store_true', default=False,
|
|
||||||
help='print graph on ARC use and exit', dest='graph')
|
|
||||||
parser.add_argument('-p', '--page', type=int, dest='page',
|
|
||||||
help='print page by number (DEPRECATED, use "-s")')
|
|
||||||
parser.add_argument('-r', '--raw', action='store_true', default=False,
|
|
||||||
help='dump all available data with minimal formatting',
|
|
||||||
dest='raw')
|
|
||||||
parser.add_argument('-s', '--section', dest='section', help=SECTION_HELP)
|
|
||||||
ARGS = parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
def cleanup_line(single_line):
|
|
||||||
"""Format a raw line of data from /proc and isolate the name value
|
|
||||||
part, returning a tuple with each. Currently, this gets rid of the
|
|
||||||
middle '4'. For example "arc_no_grow 4 0" returns the tuple
|
|
||||||
("arc_no_grow", "0").
|
|
||||||
"""
|
|
||||||
name, _, value = single_line.split()
|
|
||||||
|
|
||||||
return name, value
|
|
||||||
|
|
||||||
|
|
||||||
def draw_graph(kstats_dict):
|
|
||||||
"""Draw a primitive graph representing the basic information on the
|
|
||||||
ARC -- its size and the proportion used by MFU and MRU -- and quit.
|
|
||||||
We use max size of the ARC to calculate how full it is. This is a
|
|
||||||
very rough representation.
|
|
||||||
"""
|
|
||||||
|
|
||||||
arc_stats = isolate_section('arcstats', kstats_dict)
|
|
||||||
|
|
||||||
GRAPH_INDENT = ' '*4
|
|
||||||
GRAPH_WIDTH = 60
|
|
||||||
arc_size = f_bytes(arc_stats['size'])
|
|
||||||
arc_perc = f_perc(arc_stats['size'], arc_stats['c_max'])
|
|
||||||
mfu_size = f_bytes(arc_stats['mfu_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'])
|
|
||||||
dnode_limit = f_bytes(arc_stats['arc_dnode_limit'])
|
|
||||||
dnode_size = f_bytes(arc_stats['dnode_size'])
|
|
||||||
|
|
||||||
info_form = ('ARC: {0} ({1}) MFU: {2} MRU: {3} META: {4} ({5}) '
|
|
||||||
'DNODE {6} ({7})')
|
|
||||||
info_line = info_form.format(arc_size, arc_perc, mfu_size, mru_size,
|
|
||||||
meta_size, meta_limit, dnode_size,
|
|
||||||
dnode_limit)
|
|
||||||
info_spc = ' '*int((GRAPH_WIDTH-len(info_line))/2)
|
|
||||||
info_line = GRAPH_INDENT+info_spc+info_line
|
|
||||||
|
|
||||||
graph_line = GRAPH_INDENT+'+'+('-'*(GRAPH_WIDTH-2))+'+'
|
|
||||||
|
|
||||||
mfu_perc = float(int(arc_stats['mfu_size'])/int(arc_stats['c_max']))
|
|
||||||
mru_perc = float(int(arc_stats['mru_size'])/int(arc_stats['c_max']))
|
|
||||||
arc_perc = float(int(arc_stats['size'])/int(arc_stats['c_max']))
|
|
||||||
total_ticks = float(arc_perc)*GRAPH_WIDTH
|
|
||||||
mfu_ticks = mfu_perc*GRAPH_WIDTH
|
|
||||||
mru_ticks = mru_perc*GRAPH_WIDTH
|
|
||||||
other_ticks = total_ticks-(mfu_ticks+mru_ticks)
|
|
||||||
|
|
||||||
core_form = 'F'*int(mfu_ticks)+'R'*int(mru_ticks)+'O'*int(other_ticks)
|
|
||||||
core_spc = ' '*(GRAPH_WIDTH-(2+len(core_form)))
|
|
||||||
core_line = GRAPH_INDENT+'|'+core_form+core_spc+'|'
|
|
||||||
|
|
||||||
for line in ('', info_line, graph_line, core_line, graph_line, ''):
|
|
||||||
print(line)
|
|
||||||
|
|
||||||
|
|
||||||
def f_bytes(byte_string):
|
|
||||||
"""Return human-readable representation of a byte value in
|
|
||||||
powers of 2 (eg "KiB" for "kibibytes", etc) to two decimal
|
|
||||||
points. Values smaller than one KiB are returned without
|
|
||||||
decimal points. Note "bytes" is a reserved keyword.
|
|
||||||
"""
|
|
||||||
|
|
||||||
prefixes = ([2**80, "YiB"], # yobibytes (yotta)
|
|
||||||
[2**70, "ZiB"], # zebibytes (zetta)
|
|
||||||
[2**60, "EiB"], # exbibytes (exa)
|
|
||||||
[2**50, "PiB"], # pebibytes (peta)
|
|
||||||
[2**40, "TiB"], # tebibytes (tera)
|
|
||||||
[2**30, "GiB"], # gibibytes (giga)
|
|
||||||
[2**20, "MiB"], # mebibytes (mega)
|
|
||||||
[2**10, "KiB"]) # kibibytes (kilo)
|
|
||||||
|
|
||||||
bites = int(byte_string)
|
|
||||||
|
|
||||||
if bites >= 2**10:
|
|
||||||
for limit, unit in prefixes:
|
|
||||||
|
|
||||||
if bites >= limit:
|
|
||||||
value = bites / limit
|
|
||||||
break
|
|
||||||
|
|
||||||
result = '{0:.1f} {1}'.format(value, unit)
|
|
||||||
else:
|
|
||||||
result = '{0} Bytes'.format(bites)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def f_hits(hits_string):
|
|
||||||
"""Create a human-readable representation of the number of hits.
|
|
||||||
The single-letter symbols used are SI to avoid the confusion caused
|
|
||||||
by the different "short scale" and "long scale" representations in
|
|
||||||
English, which use the same words for different values. See
|
|
||||||
https://en.wikipedia.org/wiki/Names_of_large_numbers and:
|
|
||||||
https://physics.nist.gov/cuu/Units/prefixes.html
|
|
||||||
"""
|
|
||||||
|
|
||||||
numbers = ([10**24, 'Y'], # yotta (septillion)
|
|
||||||
[10**21, 'Z'], # zetta (sextillion)
|
|
||||||
[10**18, 'E'], # exa (quintrillion)
|
|
||||||
[10**15, 'P'], # peta (quadrillion)
|
|
||||||
[10**12, 'T'], # tera (trillion)
|
|
||||||
[10**9, 'G'], # giga (billion)
|
|
||||||
[10**6, 'M'], # mega (million)
|
|
||||||
[10**3, 'k']) # kilo (thousand)
|
|
||||||
|
|
||||||
hits = int(hits_string)
|
|
||||||
|
|
||||||
if hits >= 1000:
|
|
||||||
for limit, symbol in numbers:
|
|
||||||
|
|
||||||
if hits >= limit:
|
|
||||||
value = hits/limit
|
|
||||||
break
|
|
||||||
|
|
||||||
result = "%0.1f%s" % (value, symbol)
|
|
||||||
else:
|
|
||||||
result = "%d" % hits
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def f_perc(value1, value2):
|
|
||||||
"""Calculate percentage and return in human-readable form. If
|
|
||||||
rounding produces the result '0.0' though the first number is
|
|
||||||
not zero, include a 'less-than' symbol to avoid confusion.
|
|
||||||
Division by zero is handled by returning 'n/a'; no error
|
|
||||||
is called.
|
|
||||||
"""
|
|
||||||
|
|
||||||
v1 = float(value1)
|
|
||||||
v2 = float(value2)
|
|
||||||
|
|
||||||
try:
|
|
||||||
perc = 100 * v1/v2
|
|
||||||
except ZeroDivisionError:
|
|
||||||
result = 'n/a'
|
|
||||||
else:
|
|
||||||
result = '{0:0.1f} %'.format(perc)
|
|
||||||
|
|
||||||
if result == '0.0 %' and v1 > 0:
|
|
||||||
result = '< 0.1 %'
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def format_raw_line(name, value):
|
|
||||||
"""For the --raw option for the tunable and SPL outputs, decide on the
|
|
||||||
correct formatting based on the --alternate flag.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if ARGS.alt:
|
|
||||||
result = '{0}{1}={2}'.format(INDENT, name, value)
|
|
||||||
else:
|
|
||||||
spc = LINE_LENGTH-(len(INDENT)+len(value))
|
|
||||||
result = '{0}{1:<{spc}}{2}'.format(INDENT, name, value, spc=spc)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def get_kstats():
|
|
||||||
"""Collect information on the ZFS subsystem from the /proc Linux virtual
|
|
||||||
file system. The step does not perform any further processing, giving us
|
|
||||||
the option to only work on what is actually needed. The name "kstat" is a
|
|
||||||
holdover from the Solaris utility of the same name.
|
|
||||||
"""
|
|
||||||
|
|
||||||
result = {}
|
|
||||||
secs = SECTION_PATHS.values()
|
|
||||||
|
|
||||||
for section in secs:
|
|
||||||
|
|
||||||
with open(PROC_PATH+section, 'r') as proc_location:
|
|
||||||
lines = [line for line in proc_location]
|
|
||||||
|
|
||||||
del lines[0:2] # Get rid of header
|
|
||||||
result[section] = lines
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def get_spl_tunables(PATH):
|
|
||||||
"""Collect information on the Solaris Porting Layer (SPL) or the
|
|
||||||
tunables, depending on the PATH given. Does not check if PATH is
|
|
||||||
legal.
|
|
||||||
"""
|
|
||||||
|
|
||||||
result = {}
|
|
||||||
parameters = os.listdir(PATH)
|
|
||||||
|
|
||||||
for name in parameters:
|
|
||||||
|
|
||||||
with open(PATH+name, 'r') as para_file:
|
|
||||||
value = para_file.read()
|
|
||||||
result[name] = value.strip()
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def get_descriptions(request):
|
|
||||||
"""Get the descriptions of the Solaris Porting Layer (SPL) or the
|
|
||||||
tunables, return with minimal formatting.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if request not in ('spl', 'zfs'):
|
|
||||||
print('ERROR: description of "{0}" requested)'.format(request))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
descs = {}
|
|
||||||
target_prefix = 'parm:'
|
|
||||||
|
|
||||||
# We would prefer to do this with /sys/modules -- see the discussion at
|
|
||||||
# get_version() -- but there isn't a way to get the descriptions from
|
|
||||||
# there, so we fall back on modinfo
|
|
||||||
command = ["/sbin/modinfo", request, "-0"]
|
|
||||||
|
|
||||||
# The recommended way to do this is with subprocess.run(). However,
|
|
||||||
# some installed versions of Python are < 3.5, so we offer them
|
|
||||||
# the option of doing it the old way (for now)
|
|
||||||
info = ''
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
if 'run' in dir(subprocess):
|
|
||||||
info = subprocess.run(command, stdout=subprocess.PIPE,
|
|
||||||
universal_newlines=True)
|
|
||||||
raw_output = info.stdout.split('\0')
|
|
||||||
else:
|
|
||||||
info = subprocess.check_output(command, universal_newlines=True)
|
|
||||||
raw_output = info.split('\0')
|
|
||||||
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
print("Error: Descriptions not available (can't access kernel module)")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
for line in raw_output:
|
|
||||||
|
|
||||||
if not line.startswith(target_prefix):
|
|
||||||
continue
|
|
||||||
|
|
||||||
line = line[len(target_prefix):].strip()
|
|
||||||
name, raw_desc = line.split(':', 1)
|
|
||||||
desc = raw_desc.rsplit('(', 1)[0]
|
|
||||||
|
|
||||||
if desc == '':
|
|
||||||
desc = '(No description found)'
|
|
||||||
|
|
||||||
descs[name.strip()] = desc.strip()
|
|
||||||
|
|
||||||
return descs
|
|
||||||
|
|
||||||
|
|
||||||
def get_version(request):
|
|
||||||
"""Get the version number of ZFS or SPL on this machine for header.
|
|
||||||
Returns an error string, but does not raise an error, if we can't
|
|
||||||
get the ZFS/SPL version via modinfo.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if request not in ('spl', 'zfs'):
|
|
||||||
error_msg = '(ERROR: "{0}" requested)'.format(request)
|
|
||||||
return error_msg
|
|
||||||
|
|
||||||
# The original arc_summary called /sbin/modinfo/{spl,zfs} to get
|
|
||||||
# the version information. We switch to /sys/module/{spl,zfs}/version
|
|
||||||
# to make sure we get what is really loaded in the kernel
|
|
||||||
command = ["cat", "/sys/module/{0}/version".format(request)]
|
|
||||||
req = request.upper()
|
|
||||||
version = "(Can't get {0} version)".format(req)
|
|
||||||
|
|
||||||
# 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 = ''
|
|
||||||
if 'run' in dir(subprocess):
|
|
||||||
info = subprocess.run(command, stdout=subprocess.PIPE,
|
|
||||||
universal_newlines=True)
|
|
||||||
version = info.stdout.strip()
|
|
||||||
else:
|
|
||||||
info = subprocess.check_output(command, universal_newlines=True)
|
|
||||||
version = info.strip()
|
|
||||||
|
|
||||||
return version
|
|
||||||
|
|
||||||
|
|
||||||
def print_header():
|
|
||||||
"""Print the initial heading with date and time as well as info on the
|
|
||||||
Linux and ZFS versions. This is not called for the graph.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# datetime is now recommended over time but we keep the exact formatting
|
|
||||||
# from the older version of arc_summary in case there are scripts
|
|
||||||
# that expect it in this way
|
|
||||||
daydate = time.strftime(DATE_FORMAT)
|
|
||||||
spc_date = LINE_LENGTH-len(daydate)
|
|
||||||
sys_version = os.uname()
|
|
||||||
|
|
||||||
sys_msg = sys_version.sysname+' '+sys_version.release
|
|
||||||
zfs = get_version('zfs')
|
|
||||||
spc_zfs = LINE_LENGTH-len(zfs)
|
|
||||||
|
|
||||||
machine_msg = 'Machine: '+sys_version.nodename+' ('+sys_version.machine+')'
|
|
||||||
spl = get_version('spl')
|
|
||||||
spc_spl = LINE_LENGTH-len(spl)
|
|
||||||
|
|
||||||
print('\n'+('-'*LINE_LENGTH))
|
|
||||||
print('{0:<{spc}}{1}'.format(TITLE, daydate, spc=spc_date))
|
|
||||||
print('{0:<{spc}}{1}'.format(sys_msg, zfs, spc=spc_zfs))
|
|
||||||
print('{0:<{spc}}{1}\n'.format(machine_msg, spl, spc=spc_spl))
|
|
||||||
|
|
||||||
|
|
||||||
def print_raw(kstats_dict):
|
|
||||||
"""Print all available data from the system in a minimally sorted format.
|
|
||||||
This can be used as a source to be piped through 'grep'.
|
|
||||||
"""
|
|
||||||
|
|
||||||
sections = sorted(kstats_dict.keys())
|
|
||||||
|
|
||||||
for section in sections:
|
|
||||||
|
|
||||||
print('\n{0}:'.format(section.upper()))
|
|
||||||
lines = sorted(kstats_dict[section])
|
|
||||||
|
|
||||||
for line in lines:
|
|
||||||
name, value = cleanup_line(line)
|
|
||||||
print(format_raw_line(name, value))
|
|
||||||
|
|
||||||
# Tunables and SPL must be handled separately because they come from a
|
|
||||||
# different source and have descriptions the user might request
|
|
||||||
print()
|
|
||||||
section_spl()
|
|
||||||
section_tunables()
|
|
||||||
|
|
||||||
|
|
||||||
def isolate_section(section_name, kstats_dict):
|
|
||||||
"""From the complete information on all sections, retrieve only those
|
|
||||||
for one section.
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
section_data = kstats_dict[section_name]
|
|
||||||
except KeyError:
|
|
||||||
print('ERROR: Data on {0} not available'.format(section_data))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
section_dict = dict(cleanup_line(l) for l in section_data)
|
|
||||||
|
|
||||||
return section_dict
|
|
||||||
|
|
||||||
|
|
||||||
# Formatted output helper functions
|
|
||||||
|
|
||||||
|
|
||||||
def prt_1(text, value):
|
|
||||||
"""Print text and one value, no indent"""
|
|
||||||
spc = ' '*(LINE_LENGTH-(len(text)+len(value)))
|
|
||||||
print('{0}{spc}{1}'.format(text, value, spc=spc))
|
|
||||||
|
|
||||||
|
|
||||||
def prt_i1(text, value):
|
|
||||||
"""Print text and one value, with indent"""
|
|
||||||
spc = ' '*(LINE_LENGTH-(len(INDENT)+len(text)+len(value)))
|
|
||||||
print(INDENT+'{0}{spc}{1}'.format(text, value, spc=spc))
|
|
||||||
|
|
||||||
|
|
||||||
def prt_2(text, value1, value2):
|
|
||||||
"""Print text and two values, no indent"""
|
|
||||||
values = '{0:>9} {1:>9}'.format(value1, value2)
|
|
||||||
spc = ' '*(LINE_LENGTH-(len(text)+len(values)+2))
|
|
||||||
print('{0}{spc} {1}'.format(text, values, spc=spc))
|
|
||||||
|
|
||||||
|
|
||||||
def prt_i2(text, value1, value2):
|
|
||||||
"""Print text and two values, with indent"""
|
|
||||||
values = '{0:>9} {1:>9}'.format(value1, value2)
|
|
||||||
spc = ' '*(LINE_LENGTH-(len(INDENT)+len(text)+len(values)+2))
|
|
||||||
print(INDENT+'{0}{spc} {1}'.format(text, values, spc=spc))
|
|
||||||
|
|
||||||
|
|
||||||
# The section output concentrates on important parameters instead of
|
|
||||||
# being exhaustive (that is what the --raw parameter is for)
|
|
||||||
|
|
||||||
|
|
||||||
def section_arc(kstats_dict):
|
|
||||||
"""Give basic information on the ARC, MRU and MFU. This is the first
|
|
||||||
and most used section.
|
|
||||||
"""
|
|
||||||
|
|
||||||
arc_stats = isolate_section('arcstats', kstats_dict)
|
|
||||||
|
|
||||||
throttle = arc_stats['memory_throttle_count']
|
|
||||||
|
|
||||||
if throttle == '0':
|
|
||||||
health = 'HEALTHY'
|
|
||||||
else:
|
|
||||||
health = 'THROTTLED'
|
|
||||||
|
|
||||||
prt_1('ARC status:', health)
|
|
||||||
prt_i1('Memory throttle count:', throttle)
|
|
||||||
print()
|
|
||||||
|
|
||||||
arc_size = arc_stats['size']
|
|
||||||
arc_target_size = arc_stats['c']
|
|
||||||
arc_max = arc_stats['c_max']
|
|
||||||
arc_min = arc_stats['c_min']
|
|
||||||
mfu_size = arc_stats['mfu_size']
|
|
||||||
mru_size = arc_stats['mru_size']
|
|
||||||
meta_limit = arc_stats['arc_meta_limit']
|
|
||||||
meta_size = arc_stats['arc_meta_used']
|
|
||||||
dnode_limit = arc_stats['arc_dnode_limit']
|
|
||||||
dnode_size = arc_stats['dnode_size']
|
|
||||||
target_size_ratio = '{0}:1'.format(int(arc_max) // int(arc_min))
|
|
||||||
|
|
||||||
prt_2('ARC size (current):',
|
|
||||||
f_perc(arc_size, arc_max), f_bytes(arc_size))
|
|
||||||
prt_i2('Target size (adaptive):',
|
|
||||||
f_perc(arc_target_size, arc_max), f_bytes(arc_target_size))
|
|
||||||
prt_i2('Min size (hard limit):',
|
|
||||||
f_perc(arc_min, arc_max), f_bytes(arc_min))
|
|
||||||
prt_i2('Max size (high water):',
|
|
||||||
target_size_ratio, f_bytes(arc_max))
|
|
||||||
caches_size = int(mfu_size)+int(mru_size)
|
|
||||||
prt_i2('Most Frequently Used (MFU) cache size:',
|
|
||||||
f_perc(mfu_size, caches_size), f_bytes(mfu_size))
|
|
||||||
prt_i2('Most Recently Used (MRU) cache size:',
|
|
||||||
f_perc(mru_size, caches_size), f_bytes(mru_size))
|
|
||||||
prt_i2('Metadata cache size (hard limit):',
|
|
||||||
f_perc(meta_limit, arc_max), f_bytes(meta_limit))
|
|
||||||
prt_i2('Metadata cache size (current):',
|
|
||||||
f_perc(meta_size, meta_limit), f_bytes(meta_size))
|
|
||||||
prt_i2('Dnode cache size (hard limit):',
|
|
||||||
f_perc(dnode_limit, meta_limit), f_bytes(dnode_limit))
|
|
||||||
prt_i2('Dnode cache size (current):',
|
|
||||||
f_perc(dnode_size, dnode_limit), f_bytes(dnode_size))
|
|
||||||
print()
|
|
||||||
|
|
||||||
print('ARC hash breakdown:')
|
|
||||||
prt_i1('Elements max:', f_hits(arc_stats['hash_elements_max']))
|
|
||||||
prt_i2('Elements current:',
|
|
||||||
f_perc(arc_stats['hash_elements'], arc_stats['hash_elements_max']),
|
|
||||||
f_hits(arc_stats['hash_elements']))
|
|
||||||
prt_i1('Collisions:', f_hits(arc_stats['hash_collisions']))
|
|
||||||
|
|
||||||
prt_i1('Chain max:', f_hits(arc_stats['hash_chain_max']))
|
|
||||||
prt_i1('Chains:', f_hits(arc_stats['hash_chains']))
|
|
||||||
print()
|
|
||||||
|
|
||||||
print('ARC misc:')
|
|
||||||
prt_i1('Deleted:', f_hits(arc_stats['deleted']))
|
|
||||||
prt_i1('Mutex misses:', f_hits(arc_stats['mutex_miss']))
|
|
||||||
prt_i1('Eviction skips:', f_hits(arc_stats['evict_skip']))
|
|
||||||
print()
|
|
||||||
|
|
||||||
|
|
||||||
def section_archits(kstats_dict):
|
|
||||||
"""Print information on how the caches are accessed ("arc hits").
|
|
||||||
"""
|
|
||||||
|
|
||||||
arc_stats = isolate_section('arcstats', kstats_dict)
|
|
||||||
all_accesses = int(arc_stats['hits'])+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))
|
|
||||||
|
|
||||||
for title, value in ta_todo:
|
|
||||||
prt_i2(title, f_perc(value, all_accesses), f_hits(value))
|
|
||||||
|
|
||||||
dd_total = int(arc_stats['demand_data_hits']) +\
|
|
||||||
int(arc_stats['demand_data_misses'])
|
|
||||||
prt_i2('Data demand efficiency:',
|
|
||||||
f_perc(arc_stats['demand_data_hits'], dd_total),
|
|
||||||
f_hits(dd_total))
|
|
||||||
|
|
||||||
dp_total = int(arc_stats['prefetch_data_hits']) +\
|
|
||||||
int(arc_stats['prefetch_data_misses'])
|
|
||||||
prt_i2('Data prefetch efficiency:',
|
|
||||||
f_perc(arc_stats['prefetch_data_hits'], dp_total),
|
|
||||||
f_hits(dp_total))
|
|
||||||
|
|
||||||
known_hits = int(arc_stats['mfu_hits']) +\
|
|
||||||
int(arc_stats['mru_hits']) +\
|
|
||||||
int(arc_stats['mfu_ghost_hits']) +\
|
|
||||||
int(arc_stats['mru_ghost_hits'])
|
|
||||||
|
|
||||||
anon_hits = int(arc_stats['hits'])-known_hits
|
|
||||||
|
|
||||||
print()
|
|
||||||
print('Cache hits by cache type:')
|
|
||||||
cl_todo = (('Most frequently used (MFU):', arc_stats['mfu_hits']),
|
|
||||||
('Most recently used (MRU):', arc_stats['mru_hits']),
|
|
||||||
('Most frequently used (MFU) ghost:',
|
|
||||||
arc_stats['mfu_ghost_hits']),
|
|
||||||
('Most recently used (MRU) ghost:',
|
|
||||||
arc_stats['mru_ghost_hits']))
|
|
||||||
|
|
||||||
for title, value in cl_todo:
|
|
||||||
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()
|
|
||||||
|
|
||||||
|
|
||||||
def section_dmu(kstats_dict):
|
|
||||||
"""Collect information on the DMU"""
|
|
||||||
|
|
||||||
zfetch_stats = isolate_section('zfetchstats', kstats_dict)
|
|
||||||
|
|
||||||
zfetch_access_total = int(zfetch_stats['hits'])+int(zfetch_stats['misses'])
|
|
||||||
|
|
||||||
prt_1('DMU prefetch efficiency:', f_hits(zfetch_access_total))
|
|
||||||
prt_i2('Hit ratio:', f_perc(zfetch_stats['hits'], zfetch_access_total),
|
|
||||||
f_hits(zfetch_stats['hits']))
|
|
||||||
prt_i2('Miss ratio:', f_perc(zfetch_stats['misses'], zfetch_access_total),
|
|
||||||
f_hits(zfetch_stats['misses']))
|
|
||||||
print()
|
|
||||||
|
|
||||||
|
|
||||||
def section_l2arc(kstats_dict):
|
|
||||||
"""Collect information on L2ARC device if present. If not, tell user
|
|
||||||
that we're skipping the section.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# The L2ARC statistics live in the same section as the normal ARC stuff
|
|
||||||
arc_stats = isolate_section('arcstats', kstats_dict)
|
|
||||||
|
|
||||||
if arc_stats['l2_size'] == '0':
|
|
||||||
print('L2ARC not detected, skipping section\n')
|
|
||||||
return
|
|
||||||
|
|
||||||
l2_errors = int(arc_stats['l2_writes_error']) +\
|
|
||||||
int(arc_stats['l2_cksum_bad']) +\
|
|
||||||
int(arc_stats['l2_io_error'])
|
|
||||||
|
|
||||||
l2_access_total = int(arc_stats['l2_hits'])+int(arc_stats['l2_misses'])
|
|
||||||
health = 'HEALTHY'
|
|
||||||
|
|
||||||
if l2_errors > 0:
|
|
||||||
health = 'DEGRADED'
|
|
||||||
|
|
||||||
prt_1('L2ARC status:', health)
|
|
||||||
|
|
||||||
l2_todo = (('Low memory aborts:', 'l2_abort_lowmem'),
|
|
||||||
('Free on write:', 'l2_free_on_write'),
|
|
||||||
('R/W clashes:', 'l2_rw_clash'),
|
|
||||||
('Bad checksums:', 'l2_cksum_bad'),
|
|
||||||
('I/O errors:', 'l2_io_error'))
|
|
||||||
|
|
||||||
for title, value in l2_todo:
|
|
||||||
prt_i1(title, f_hits(arc_stats[value]))
|
|
||||||
|
|
||||||
print()
|
|
||||||
prt_1('L2ARC size (adaptive):', f_bytes(arc_stats['l2_size']))
|
|
||||||
prt_i2('Compressed:', f_perc(arc_stats['l2_asize'], arc_stats['l2_size']),
|
|
||||||
f_bytes(arc_stats['l2_asize']))
|
|
||||||
prt_i2('Header size:',
|
|
||||||
f_perc(arc_stats['l2_hdr_size'], arc_stats['l2_size']),
|
|
||||||
f_bytes(arc_stats['l2_hdr_size']))
|
|
||||||
|
|
||||||
print()
|
|
||||||
prt_1('L2ARC breakdown:', f_hits(l2_access_total))
|
|
||||||
prt_i2('Hit ratio:',
|
|
||||||
f_perc(arc_stats['l2_hits'], l2_access_total),
|
|
||||||
f_hits(arc_stats['l2_hits']))
|
|
||||||
prt_i2('Miss ratio:',
|
|
||||||
f_perc(arc_stats['l2_misses'], l2_access_total),
|
|
||||||
f_hits(arc_stats['l2_misses']))
|
|
||||||
prt_i1('Feeds:', f_hits(arc_stats['l2_feeds']))
|
|
||||||
|
|
||||||
print()
|
|
||||||
print('L2ARC writes:')
|
|
||||||
|
|
||||||
if arc_stats['l2_writes_done'] != arc_stats['l2_writes_sent']:
|
|
||||||
prt_i2('Writes sent:', 'FAULTED', f_hits(arc_stats['l2_writes_sent']))
|
|
||||||
prt_i2('Done ratio:',
|
|
||||||
f_perc(arc_stats['l2_writes_done'],
|
|
||||||
arc_stats['l2_writes_sent']),
|
|
||||||
f_bytes(arc_stats['l2_writes_done']))
|
|
||||||
prt_i2('Error ratio:',
|
|
||||||
f_perc(arc_stats['l2_writes_error'],
|
|
||||||
arc_stats['l2_writes_sent']),
|
|
||||||
f_bytes(arc_stats['l2_writes_error']))
|
|
||||||
else:
|
|
||||||
prt_i2('Writes sent:', '100 %', f_bytes(arc_stats['l2_writes_sent']))
|
|
||||||
|
|
||||||
print()
|
|
||||||
print('L2ARC evicts:')
|
|
||||||
prt_i1('Lock retries:', f_hits(arc_stats['l2_evict_lock_retry']))
|
|
||||||
prt_i1('Upon reading:', f_hits(arc_stats['l2_evict_reading']))
|
|
||||||
print()
|
|
||||||
|
|
||||||
|
|
||||||
def section_spl(*_):
|
|
||||||
"""Print the SPL parameters, if requested with alternative format
|
|
||||||
and/or descriptions. This does not use kstats.
|
|
||||||
"""
|
|
||||||
|
|
||||||
spls = get_spl_tunables(SPL_PATH)
|
|
||||||
keylist = sorted(spls.keys())
|
|
||||||
print('Solaris Porting Layer (SPL):')
|
|
||||||
|
|
||||||
if ARGS.desc:
|
|
||||||
descriptions = get_descriptions('spl')
|
|
||||||
|
|
||||||
for key in keylist:
|
|
||||||
value = spls[key]
|
|
||||||
|
|
||||||
if ARGS.desc:
|
|
||||||
try:
|
|
||||||
print(INDENT+'#', descriptions[key])
|
|
||||||
except KeyError:
|
|
||||||
print(INDENT+'# (No description found)') # paranoid
|
|
||||||
|
|
||||||
print(format_raw_line(key, value))
|
|
||||||
|
|
||||||
print()
|
|
||||||
|
|
||||||
|
|
||||||
def section_tunables(*_):
|
|
||||||
"""Print the tunables, if requested with alternative format and/or
|
|
||||||
descriptions. This does not use kstasts.
|
|
||||||
"""
|
|
||||||
|
|
||||||
tunables = get_spl_tunables(TUNABLES_PATH)
|
|
||||||
keylist = sorted(tunables.keys())
|
|
||||||
print('Tunables:')
|
|
||||||
|
|
||||||
if ARGS.desc:
|
|
||||||
descriptions = get_descriptions('zfs')
|
|
||||||
|
|
||||||
for key in keylist:
|
|
||||||
value = tunables[key]
|
|
||||||
|
|
||||||
if ARGS.desc:
|
|
||||||
try:
|
|
||||||
print(INDENT+'#', descriptions[key])
|
|
||||||
except KeyError:
|
|
||||||
print(INDENT+'# (No description found)') # paranoid
|
|
||||||
|
|
||||||
print(format_raw_line(key, value))
|
|
||||||
|
|
||||||
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/zfsonlinux/zfs/blob/master/module/zfs/vdev_cache.c
|
|
||||||
# for details
|
|
||||||
tunables = get_spl_tunables(TUNABLES_PATH)
|
|
||||||
|
|
||||||
if tunables['zfs_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):
|
|
||||||
"""Collect information on the ZFS Intent Log. Some of the information
|
|
||||||
taken from https://github.com/zfsonlinux/zfs/blob/master/include/sys/zil.h
|
|
||||||
"""
|
|
||||||
|
|
||||||
zil_stats = isolate_section('zil', kstats_dict)
|
|
||||||
|
|
||||||
prt_1('ZIL committed transactions:',
|
|
||||||
f_hits(zil_stats['zil_itx_count']))
|
|
||||||
prt_i1('Commit requests:', f_hits(zil_stats['zil_commit_count']))
|
|
||||||
prt_i1('Flushes to stable storage:',
|
|
||||||
f_hits(zil_stats['zil_commit_writer_count']))
|
|
||||||
prt_i2('Transactions to SLOG storage pool:',
|
|
||||||
f_bytes(zil_stats['zil_itx_metaslab_slog_bytes']),
|
|
||||||
f_hits(zil_stats['zil_itx_metaslab_slog_count']))
|
|
||||||
prt_i2('Transactions to non-SLOG storage pool:',
|
|
||||||
f_bytes(zil_stats['zil_itx_metaslab_normal_bytes']),
|
|
||||||
f_hits(zil_stats['zil_itx_metaslab_normal_count']))
|
|
||||||
print()
|
|
||||||
|
|
||||||
|
|
||||||
section_calls = {'arc': section_arc,
|
|
||||||
'archits': section_archits,
|
|
||||||
'dmu': section_dmu,
|
|
||||||
'l2arc': section_l2arc,
|
|
||||||
'spl': section_spl,
|
|
||||||
'tunables': section_tunables,
|
|
||||||
'vdev': section_vdev,
|
|
||||||
'zil': section_zil}
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Run program. The options to draw a graph and to print all data raw are
|
|
||||||
treated separately because they come with their own call.
|
|
||||||
"""
|
|
||||||
|
|
||||||
kstats = get_kstats()
|
|
||||||
|
|
||||||
if ARGS.graph:
|
|
||||||
draw_graph(kstats)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
print_header()
|
|
||||||
|
|
||||||
if ARGS.raw:
|
|
||||||
print_raw(kstats)
|
|
||||||
|
|
||||||
elif ARGS.section:
|
|
||||||
|
|
||||||
try:
|
|
||||||
section_calls[ARGS.section](kstats)
|
|
||||||
except KeyError:
|
|
||||||
print('Error: Section "{0}" unknown'.format(ARGS.section))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
elif ARGS.page:
|
|
||||||
print('WARNING: Pages are deprecated, please use "--section"\n')
|
|
||||||
|
|
||||||
pages_to_calls = {1: 'arc',
|
|
||||||
2: 'archits',
|
|
||||||
3: 'l2arc',
|
|
||||||
4: 'dmu',
|
|
||||||
5: 'vdev',
|
|
||||||
6: 'tunables'}
|
|
||||||
|
|
||||||
try:
|
|
||||||
call = pages_to_calls[ARGS.page]
|
|
||||||
except KeyError:
|
|
||||||
print('Error: Page "{0}" not supported'.format(ARGS.page))
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
section_calls[call](kstats)
|
|
||||||
|
|
||||||
else:
|
|
||||||
# If no parameters were given, we print all sections. We might want to
|
|
||||||
# change the sequence by hand
|
|
||||||
calls = sorted(section_calls.keys())
|
|
||||||
|
|
||||||
for section in calls:
|
|
||||||
section_calls[section](kstats)
|
|
||||||
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
+1
-13
@@ -1,13 +1 @@
|
|||||||
dist_bin_SCRIPTS = arcstat
|
dist_bin_SCRIPTS = arcstat.py
|
||||||
|
|
||||||
#
|
|
||||||
# The arcstat script is compatible with both Python 2.6 and 3.4.
|
|
||||||
# As such the python 3 shebang can be replaced at install time when
|
|
||||||
# targeting a python 2 system. This allows us to maintain a single
|
|
||||||
# version of the source.
|
|
||||||
#
|
|
||||||
if USING_PYTHON_2
|
|
||||||
install-exec-hook:
|
|
||||||
sed --in-place 's|^#!/usr/bin/env python3|#!/usr/bin/env python2|' \
|
|
||||||
$(DESTDIR)$(bindir)/arcstat
|
|
||||||
endif
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/python
|
||||||
#
|
#
|
||||||
# Print out ZFS ARC Statistics exported via kstat(1)
|
# Print out ZFS ARC Statistics exported via kstat(1)
|
||||||
# For a definition of fields, or usage, use arctstat.pl -v
|
# For a definition of fields, or usage, use arctstat.pl -v
|
||||||
@@ -42,8 +42,7 @@
|
|||||||
# @hdr is the array of fields that needs to be printed, so we
|
# @hdr is the array of fields that needs to be printed, so we
|
||||||
# just iterate over this array and print the values using our pretty printer.
|
# just iterate over this array and print the values using our pretty printer.
|
||||||
#
|
#
|
||||||
# This script must remain compatible with Python 2.6+ and Python 3.4+.
|
|
||||||
#
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
@@ -72,7 +71,7 @@ cols = {
|
|||||||
"pm%": [3, 100, "Prefetch miss percentage"],
|
"pm%": [3, 100, "Prefetch miss percentage"],
|
||||||
"mhit": [4, 1000, "Metadata hits per second"],
|
"mhit": [4, 1000, "Metadata 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": [4, 1000, "Metadata accesses per second"],
|
||||||
"mh%": [3, 100, "Metadata hit percentage"],
|
"mh%": [3, 100, "Metadata hit percentage"],
|
||||||
"mm%": [3, 100, "Metadata miss percentage"],
|
"mm%": [3, 100, "Metadata miss percentage"],
|
||||||
"arcsz": [5, 1024, "ARC Size"],
|
"arcsz": [5, 1024, "ARC Size"],
|
||||||
@@ -93,9 +92,6 @@ cols = {
|
|||||||
"l2asize": [7, 1024, "Actual (compressed) size of the L2ARC"],
|
"l2asize": [7, 1024, "Actual (compressed) size of the L2ARC"],
|
||||||
"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"],
|
|
||||||
"need": [4, 1024, "ARC Reclaim need"],
|
|
||||||
"free": [4, 1024, "ARC Free memory"],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v = {}
|
v = {}
|
||||||
@@ -110,7 +106,7 @@ opfile = None
|
|||||||
sep = " " # Default separator is 2 spaces
|
sep = " " # Default separator is 2 spaces
|
||||||
version = "0.4"
|
version = "0.4"
|
||||||
l2exist = False
|
l2exist = False
|
||||||
cmd = ("Usage: arcstat [-hvx] [-f fields] [-o file] [-s string] [interval "
|
cmd = ("Usage: arcstat.py [-hvx] [-f fields] [-o file] [-s string] [interval "
|
||||||
"[count]]\n")
|
"[count]]\n")
|
||||||
cur = {}
|
cur = {}
|
||||||
d = {}
|
d = {}
|
||||||
@@ -139,10 +135,10 @@ def usage():
|
|||||||
sys.stderr.write("\t -s : Override default field separator with custom "
|
sys.stderr.write("\t -s : Override default field separator with custom "
|
||||||
"character or string\n")
|
"character or string\n")
|
||||||
sys.stderr.write("\nExamples:\n")
|
sys.stderr.write("\nExamples:\n")
|
||||||
sys.stderr.write("\tarcstat -o /tmp/a.log 2 10\n")
|
sys.stderr.write("\tarcstat.py -o /tmp/a.log 2 10\n")
|
||||||
sys.stderr.write("\tarcstat -s \",\" -o /tmp/a.log 2 10\n")
|
sys.stderr.write("\tarcstat.py -s \",\" -o /tmp/a.log 2 10\n")
|
||||||
sys.stderr.write("\tarcstat -v\n")
|
sys.stderr.write("\tarcstat.py -v\n")
|
||||||
sys.stderr.write("\tarcstat -f time,hit%,dh%,ph%,mh% 1\n")
|
sys.stderr.write("\tarcstat.py -f time,hit%,dh%,ph%,mh% 1\n")
|
||||||
sys.stderr.write("\n")
|
sys.stderr.write("\n")
|
||||||
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -427,10 +423,6 @@ def calculate():
|
|||||||
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["grow"] = 0 if cur["arc_no_grow"] else 1
|
|
||||||
v["need"] = cur["arc_need_free"]
|
|
||||||
v["free"] = cur["arc_sys_free"]
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global sint
|
global sint
|
||||||
@@ -1,13 +1 @@
|
|||||||
dist_bin_SCRIPTS = dbufstat
|
dist_bin_SCRIPTS = dbufstat.py
|
||||||
|
|
||||||
#
|
|
||||||
# The dbufstat script is compatible with both Python 2.6 and 3.4.
|
|
||||||
# As such the python 3 shebang can be replaced at install time when
|
|
||||||
# targeting a python 2 system. This allows us to maintain a single
|
|
||||||
# version of the source.
|
|
||||||
#
|
|
||||||
if USING_PYTHON_2
|
|
||||||
install-exec-hook:
|
|
||||||
sed --in-place 's|^#!/usr/bin/env python3|#!/usr/bin/env python2|' \
|
|
||||||
$(DESTDIR)$(bindir)/dbufstat
|
|
||||||
endif
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/python
|
||||||
#
|
#
|
||||||
# Print out statistics for all cached dmu buffers. This information
|
# Print out statistics for all cached dmu buffers. This information
|
||||||
# is available through the dbufs kstat and may be post-processed as
|
# is available through the dbufs kstat and may be post-processed as
|
||||||
@@ -27,17 +27,14 @@
|
|||||||
# Copyright (C) 2013 Lawrence Livermore National Security, LLC.
|
# Copyright (C) 2013 Lawrence Livermore National Security, LLC.
|
||||||
# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
||||||
#
|
#
|
||||||
# This script must remain compatible with Python 2.6+ and Python 3.4+.
|
|
||||||
#
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import getopt
|
import getopt
|
||||||
import errno
|
import errno
|
||||||
import re
|
|
||||||
|
|
||||||
bhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize"]
|
bhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize"]
|
||||||
bxhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize",
|
bxhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize",
|
||||||
"meta", "state", "dbholds", "dbc", "list", "atype", "flags",
|
"meta", "state", "dbholds", "list", "atype", "flags",
|
||||||
"count", "asize", "access", "mru", "gmru", "mfu", "gmfu", "l2",
|
"count", "asize", "access", "mru", "gmru", "mfu", "gmfu", "l2",
|
||||||
"l2_dattr", "l2_asize", "l2_comp", "aholds", "dtype", "btype",
|
"l2_dattr", "l2_asize", "l2_comp", "aholds", "dtype", "btype",
|
||||||
"data_bs", "meta_bs", "bsize", "lvls", "dholds", "blocks", "dsize"]
|
"data_bs", "meta_bs", "bsize", "lvls", "dholds", "blocks", "dsize"]
|
||||||
@@ -48,7 +45,7 @@ dxhdr = ["pool", "objset", "object", "dtype", "btype", "data_bs", "meta_bs",
|
|||||||
"bsize", "lvls", "dholds", "blocks", "dsize", "cached", "direct",
|
"bsize", "lvls", "dholds", "blocks", "dsize", "cached", "direct",
|
||||||
"indirect", "bonus", "spill"]
|
"indirect", "bonus", "spill"]
|
||||||
dincompat = ["level", "blkid", "offset", "dbsize", "meta", "state", "dbholds",
|
dincompat = ["level", "blkid", "offset", "dbsize", "meta", "state", "dbholds",
|
||||||
"dbc", "list", "atype", "flags", "count", "asize", "access",
|
"list", "atype", "flags", "count", "asize", "access",
|
||||||
"mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr", "l2_asize",
|
"mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr", "l2_asize",
|
||||||
"l2_comp", "aholds"]
|
"l2_comp", "aholds"]
|
||||||
|
|
||||||
@@ -56,7 +53,7 @@ thdr = ["pool", "objset", "dtype", "cached"]
|
|||||||
txhdr = ["pool", "objset", "dtype", "cached", "direct", "indirect",
|
txhdr = ["pool", "objset", "dtype", "cached", "direct", "indirect",
|
||||||
"bonus", "spill"]
|
"bonus", "spill"]
|
||||||
tincompat = ["object", "level", "blkid", "offset", "dbsize", "meta", "state",
|
tincompat = ["object", "level", "blkid", "offset", "dbsize", "meta", "state",
|
||||||
"dbc", "dbholds", "list", "atype", "flags", "count", "asize",
|
"dbholds", "list", "atype", "flags", "count", "asize",
|
||||||
"access", "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr",
|
"access", "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr",
|
||||||
"l2_asize", "l2_comp", "aholds", "btype", "data_bs", "meta_bs",
|
"l2_asize", "l2_comp", "aholds", "btype", "data_bs", "meta_bs",
|
||||||
"bsize", "lvls", "dholds", "blocks", "dsize"]
|
"bsize", "lvls", "dholds", "blocks", "dsize"]
|
||||||
@@ -73,10 +70,9 @@ cols = {
|
|||||||
"meta": [4, -1, "is this buffer metadata?"],
|
"meta": [4, -1, "is this buffer metadata?"],
|
||||||
"state": [5, -1, "state of buffer (read, cached, etc)"],
|
"state": [5, -1, "state of buffer (read, cached, etc)"],
|
||||||
"dbholds": [7, 1000, "number of holds on buffer"],
|
"dbholds": [7, 1000, "number of holds on buffer"],
|
||||||
"dbc": [3, -1, "in dbuf cache"],
|
|
||||||
"list": [4, -1, "which ARC list contains this buffer"],
|
"list": [4, -1, "which ARC list contains this buffer"],
|
||||||
"atype": [7, -1, "ARC header type (data or metadata)"],
|
"atype": [7, -1, "ARC header type (data or metadata)"],
|
||||||
"flags": [9, -1, "ARC read flags"],
|
"flags": [8, -1, "ARC read flags"],
|
||||||
"count": [5, -1, "ARC data count"],
|
"count": [5, -1, "ARC data count"],
|
||||||
"asize": [7, 1024, "size of this ARC buffer"],
|
"asize": [7, 1024, "size of this ARC buffer"],
|
||||||
"access": [10, -1, "time this ARC buffer was last accessed"],
|
"access": [10, -1, "time this ARC buffer was last accessed"],
|
||||||
@@ -108,8 +104,8 @@ cols = {
|
|||||||
hdr = None
|
hdr = None
|
||||||
xhdr = None
|
xhdr = None
|
||||||
sep = " " # Default separator is 2 spaces
|
sep = " " # Default separator is 2 spaces
|
||||||
cmd = ("Usage: dbufstat [-bdhnrtvx] [-i file] [-f fields] [-o file] "
|
cmd = ("Usage: dbufstat.py [-bdhrtvx] [-i file] [-f fields] [-o file] "
|
||||||
"[-s string] [-F filter]\n")
|
"[-s string]\n")
|
||||||
raw = 0
|
raw = 0
|
||||||
|
|
||||||
|
|
||||||
@@ -155,7 +151,6 @@ def usage():
|
|||||||
sys.stderr.write("\t -b : Print table of information for each dbuf\n")
|
sys.stderr.write("\t -b : Print table of information for each dbuf\n")
|
||||||
sys.stderr.write("\t -d : Print table of information for each dnode\n")
|
sys.stderr.write("\t -d : Print table of information for each dnode\n")
|
||||||
sys.stderr.write("\t -h : Print this help message\n")
|
sys.stderr.write("\t -h : Print this help message\n")
|
||||||
sys.stderr.write("\t -n : Exclude header from output\n")
|
|
||||||
sys.stderr.write("\t -r : Print raw values\n")
|
sys.stderr.write("\t -r : Print raw values\n")
|
||||||
sys.stderr.write("\t -t : Print table of information for each dnode type"
|
sys.stderr.write("\t -t : Print table of information for each dnode type"
|
||||||
"\n")
|
"\n")
|
||||||
@@ -167,13 +162,11 @@ def usage():
|
|||||||
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 "
|
||||||
"character or string\n")
|
"character or string\n")
|
||||||
sys.stderr.write("\t -F : Filter output by value or regex\n")
|
|
||||||
sys.stderr.write("\nExamples:\n")
|
sys.stderr.write("\nExamples:\n")
|
||||||
sys.stderr.write("\tdbufstat -d -o /tmp/d.log\n")
|
sys.stderr.write("\tdbufstat.py -d -o /tmp/d.log\n")
|
||||||
sys.stderr.write("\tdbufstat -t -s \",\" -o /tmp/t.log\n")
|
sys.stderr.write("\tdbufstat.py -t -s \",\" -o /tmp/t.log\n")
|
||||||
sys.stderr.write("\tdbufstat -v\n")
|
sys.stderr.write("\tdbufstat.py -v\n")
|
||||||
sys.stderr.write("\tdbufstat -d -f pool,object,objset,dsize,cached\n")
|
sys.stderr.write("\tdbufstat.py -d -f pool,object,objset,dsize,cached\n")
|
||||||
sys.stderr.write("\tdbufstat -bx -F dbc=1,objset=54,pool=testpool\n")
|
|
||||||
sys.stderr.write("\n")
|
sys.stderr.write("\n")
|
||||||
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -235,8 +228,7 @@ def print_header():
|
|||||||
|
|
||||||
|
|
||||||
def get_typestring(t):
|
def get_typestring(t):
|
||||||
ot_strings = [
|
type_strings = ["DMU_OT_NONE",
|
||||||
"DMU_OT_NONE",
|
|
||||||
# general:
|
# general:
|
||||||
"DMU_OT_OBJECT_DIRECTORY",
|
"DMU_OT_OBJECT_DIRECTORY",
|
||||||
"DMU_OT_OBJECT_ARRAY",
|
"DMU_OT_OBJECT_ARRAY",
|
||||||
@@ -299,39 +291,15 @@ def get_typestring(t):
|
|||||||
"DMU_OT_DEADLIST_HDR",
|
"DMU_OT_DEADLIST_HDR",
|
||||||
"DMU_OT_DSL_CLONES",
|
"DMU_OT_DSL_CLONES",
|
||||||
"DMU_OT_BPOBJ_SUBOBJ"]
|
"DMU_OT_BPOBJ_SUBOBJ"]
|
||||||
otn_strings = {
|
|
||||||
0x80: "DMU_OTN_UINT8_DATA",
|
|
||||||
0xc0: "DMU_OTN_UINT8_METADATA",
|
|
||||||
0x81: "DMU_OTN_UINT16_DATA",
|
|
||||||
0xc1: "DMU_OTN_UINT16_METADATA",
|
|
||||||
0x82: "DMU_OTN_UINT32_DATA",
|
|
||||||
0xc2: "DMU_OTN_UINT32_METADATA",
|
|
||||||
0x83: "DMU_OTN_UINT64_DATA",
|
|
||||||
0xc3: "DMU_OTN_UINT64_METADATA",
|
|
||||||
0x84: "DMU_OTN_ZAP_DATA",
|
|
||||||
0xc4: "DMU_OTN_ZAP_METADATA",
|
|
||||||
0xa0: "DMU_OTN_UINT8_ENC_DATA",
|
|
||||||
0xe0: "DMU_OTN_UINT8_ENC_METADATA",
|
|
||||||
0xa1: "DMU_OTN_UINT16_ENC_DATA",
|
|
||||||
0xe1: "DMU_OTN_UINT16_ENC_METADATA",
|
|
||||||
0xa2: "DMU_OTN_UINT32_ENC_DATA",
|
|
||||||
0xe2: "DMU_OTN_UINT32_ENC_METADATA",
|
|
||||||
0xa3: "DMU_OTN_UINT64_ENC_DATA",
|
|
||||||
0xe3: "DMU_OTN_UINT64_ENC_METADATA",
|
|
||||||
0xa4: "DMU_OTN_ZAP_ENC_DATA",
|
|
||||||
0xe4: "DMU_OTN_ZAP_ENC_METADATA"}
|
|
||||||
|
|
||||||
# If "-rr" option is used, don't convert to string representation
|
# If "-rr" option is used, don't convert to string representation
|
||||||
if raw > 1:
|
if raw > 1:
|
||||||
return "%i" % t
|
return "%i" % t
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if t < len(ot_strings):
|
return type_strings[t]
|
||||||
return ot_strings[t]
|
except IndexError:
|
||||||
else:
|
return "%i" % t
|
||||||
return otn_strings[t]
|
|
||||||
except (IndexError, KeyError):
|
|
||||||
return "(UNKNOWN)"
|
|
||||||
|
|
||||||
|
|
||||||
def get_compstring(c):
|
def get_compstring(c):
|
||||||
@@ -416,32 +384,12 @@ def update_dict(d, k, line, labels):
|
|||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
def skip_line(vals, filters):
|
def print_dict(d):
|
||||||
'''
|
print_header()
|
||||||
Determines if a line should be skipped during printing
|
|
||||||
based on a set of filters
|
|
||||||
'''
|
|
||||||
if len(filters) == 0:
|
|
||||||
return False
|
|
||||||
|
|
||||||
for key in vals:
|
|
||||||
if key in filters:
|
|
||||||
val = prettynum(cols[key][0], cols[key][1], vals[key]).strip()
|
|
||||||
# we want a full match here
|
|
||||||
if re.match("(?:" + filters[key] + r")\Z", val) is None:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def print_dict(d, filters, noheader):
|
|
||||||
if not noheader:
|
|
||||||
print_header()
|
|
||||||
for pool in list(d.keys()):
|
for pool in list(d.keys()):
|
||||||
for objset in list(d[pool].keys()):
|
for objset in list(d[pool].keys()):
|
||||||
for v in list(d[pool][objset].values()):
|
for v in list(d[pool][objset].values()):
|
||||||
if not skip_line(v, filters):
|
print_values(v)
|
||||||
print_values(v)
|
|
||||||
|
|
||||||
|
|
||||||
def dnodes_build_dict(filehandle):
|
def dnodes_build_dict(filehandle):
|
||||||
@@ -482,7 +430,7 @@ def types_build_dict(filehandle):
|
|||||||
return types
|
return types
|
||||||
|
|
||||||
|
|
||||||
def buffers_print_all(filehandle, filters, noheader):
|
def buffers_print_all(filehandle):
|
||||||
labels = dict()
|
labels = dict()
|
||||||
|
|
||||||
# First 3 lines are header information, skip the first two
|
# First 3 lines are header information, skip the first two
|
||||||
@@ -493,14 +441,11 @@ def buffers_print_all(filehandle, filters, noheader):
|
|||||||
for i, v in enumerate(next(filehandle).split()):
|
for i, v in enumerate(next(filehandle).split()):
|
||||||
labels[v] = i
|
labels[v] = i
|
||||||
|
|
||||||
if not noheader:
|
print_header()
|
||||||
print_header()
|
|
||||||
|
|
||||||
# The rest of the file is buffer information
|
# The rest of the file is buffer information
|
||||||
for line in filehandle:
|
for line in filehandle:
|
||||||
vals = parse_line(line.split(), labels)
|
print_values(parse_line(line.split(), labels))
|
||||||
if not skip_line(vals, filters):
|
|
||||||
print_values(vals)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@@ -517,13 +462,11 @@ def main():
|
|||||||
tflag = False
|
tflag = False
|
||||||
vflag = False
|
vflag = False
|
||||||
xflag = False
|
xflag = False
|
||||||
nflag = False
|
|
||||||
filters = dict()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(
|
opts, args = getopt.getopt(
|
||||||
sys.argv[1:],
|
sys.argv[1:],
|
||||||
"bdf:hi:o:rs:tvxF:n",
|
"bdf:hi:o:rs:tvx",
|
||||||
[
|
[
|
||||||
"buffers",
|
"buffers",
|
||||||
"dnodes",
|
"dnodes",
|
||||||
@@ -534,8 +477,7 @@ def main():
|
|||||||
"separator",
|
"separator",
|
||||||
"types",
|
"types",
|
||||||
"verbose",
|
"verbose",
|
||||||
"extended",
|
"extended"
|
||||||
"filter"
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
except getopt.error:
|
except getopt.error:
|
||||||
@@ -565,35 +507,6 @@ def main():
|
|||||||
vflag = True
|
vflag = True
|
||||||
if opt in ('-x', '--extended'):
|
if opt in ('-x', '--extended'):
|
||||||
xflag = True
|
xflag = True
|
||||||
if opt in ('-n', '--noheader'):
|
|
||||||
nflag = True
|
|
||||||
if opt in ('-F', '--filter'):
|
|
||||||
fils = [x.strip() for x in arg.split(",")]
|
|
||||||
|
|
||||||
for fil in fils:
|
|
||||||
f = [x.strip() for x in fil.split("=")]
|
|
||||||
|
|
||||||
if len(f) != 2:
|
|
||||||
sys.stderr.write("Invalid filter '%s'.\n" % fil)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if f[0] not in cols:
|
|
||||||
sys.stderr.write("Invalid field '%s' in filter.\n" % f[0])
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if f[0] in filters:
|
|
||||||
sys.stderr.write("Field '%s' specified multiple times in "
|
|
||||||
"filter.\n" % f[0])
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
try:
|
|
||||||
re.compile("(?:" + f[1] + r")\Z")
|
|
||||||
except re.error:
|
|
||||||
sys.stderr.write("Invalid regex for field '%s' in "
|
|
||||||
"filter.\n" % f[0])
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
filters[f[0]] = f[1]
|
|
||||||
|
|
||||||
if hflag or (xflag and desired_cols):
|
if hflag or (xflag and desired_cols):
|
||||||
usage()
|
usage()
|
||||||
@@ -656,13 +569,13 @@ def main():
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if bflag:
|
if bflag:
|
||||||
buffers_print_all(sys.stdin, filters, nflag)
|
buffers_print_all(sys.stdin)
|
||||||
|
|
||||||
if dflag:
|
if dflag:
|
||||||
print_dict(dnodes_build_dict(sys.stdin), filters, nflag)
|
print_dict(dnodes_build_dict(sys.stdin))
|
||||||
|
|
||||||
if tflag:
|
if tflag:
|
||||||
print_dict(types_build_dict(sys.stdin), filters, nflag)
|
print_dict(types_build_dict(sys.stdin))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# fsck.zfs: A fsck helper to accommodate distributions that expect
|
# fsck.zfs: A fsck helper to accomidate distributions that expect
|
||||||
# to be able to execute a fsck on all filesystem types. Currently
|
# to be able to execute a fsck on all filesystem types. Currently
|
||||||
# this script does nothing but it could be extended to act as a
|
# this script does nothing but it could be extended to act as a
|
||||||
# compatibility wrapper for 'zpool scrub'.
|
# compatibility wrapper for 'zpool scrub'.
|
||||||
|
|||||||
@@ -18,4 +18,7 @@ mount_zfs_SOURCES = \
|
|||||||
|
|
||||||
mount_zfs_LDADD = \
|
mount_zfs_LDADD = \
|
||||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
$(top_builddir)/lib/libzfs/libzfs.la
|
$(top_builddir)/lib/libuutil/libuutil.la \
|
||||||
|
$(top_builddir)/lib/libzpool/libzpool.la \
|
||||||
|
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||||
|
$(top_builddir)/lib/libzfs_core/libzfs_core.la
|
||||||
|
|||||||
@@ -31,11 +31,9 @@
|
|||||||
#include <sys/mntent.h>
|
#include <sys/mntent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
#include <libzutil.h>
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#define ZS_COMMENT 0x00000000 /* comment */
|
#define ZS_COMMENT 0x00000000 /* comment */
|
||||||
#define ZS_ZFSUTIL 0x00000001 /* caller is zfs(8) */
|
#define ZS_ZFSUTIL 0x00000001 /* caller is zfs(8) */
|
||||||
@@ -489,7 +487,7 @@ main(int argc, char **argv)
|
|||||||
zfsutil = 1;
|
zfsutil = 1;
|
||||||
|
|
||||||
if ((g_zfs = libzfs_init()) == NULL) {
|
if ((g_zfs = libzfs_init()) == NULL) {
|
||||||
(void) fprintf(stderr, "%s\n", libzfs_error_init(errno));
|
(void) fprintf(stderr, "%s", libzfs_error_init(errno));
|
||||||
return (MOUNT_SYSERR);
|
return (MOUNT_SYSERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
include $(top_srcdir)/config/Rules.am
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
|
||||||
# Includes kernel code, generate warnings for large stack frames
|
AM_CFLAGS += $(DEBUG_STACKFLAGS) $(FRAME_LARGER_THAN)
|
||||||
AM_CFLAGS += $(FRAME_LARGER_THAN)
|
AM_CPPFLAGS += -DDEBUG
|
||||||
|
|
||||||
# Unconditionally enable ASSERTs
|
|
||||||
AM_CPPFLAGS += -DDEBUG -UNDEBUG
|
|
||||||
|
|
||||||
DEFAULT_INCLUDES += \
|
DEFAULT_INCLUDES += \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
@@ -18,6 +15,8 @@ raidz_test_SOURCES = \
|
|||||||
raidz_bench.c
|
raidz_bench.c
|
||||||
|
|
||||||
raidz_test_LDADD = \
|
raidz_test_LDADD = \
|
||||||
|
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
|
$(top_builddir)/lib/libuutil/libuutil.la \
|
||||||
$(top_builddir)/lib/libzpool/libzpool.la
|
$(top_builddir)/lib/libzpool/libzpool.la
|
||||||
|
|
||||||
raidz_test_LDADD += -lm -ldl
|
raidz_test_LDADD += -lm -ldl
|
||||||
|
|||||||
@@ -702,8 +702,10 @@ run_sweep(void)
|
|||||||
opts->rto_dsize = size_v[s];
|
opts->rto_dsize = size_v[s];
|
||||||
opts->rto_v = 0; /* be quiet */
|
opts->rto_v = 0; /* be quiet */
|
||||||
|
|
||||||
VERIFY3P(thread_create(NULL, 0, sweep_thread, (void *) opts,
|
VERIFY3P(zk_thread_create(NULL, 0,
|
||||||
0, NULL, TS_RUN, defclsyspri), !=, NULL);
|
(thread_func_t)sweep_thread,
|
||||||
|
(void *) opts, 0, NULL, TS_RUN, 0,
|
||||||
|
PTHREAD_CREATE_JOINABLE), !=, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ Usage: vdev_id [-h]
|
|||||||
vdev_id <-d device> [-c config_file] [-p phys_per_port]
|
vdev_id <-d device> [-c config_file] [-p phys_per_port]
|
||||||
[-g sas_direct|sas_switch|scsi] [-m]
|
[-g sas_direct|sas_switch|scsi] [-m]
|
||||||
|
|
||||||
-c specify name of an alternative config file [default=$CONFIG]
|
-c specify name of alernate config file [default=$CONFIG]
|
||||||
-d specify basename of device (i.e. sda)
|
-d specify basename of device (i.e. sda)
|
||||||
-e Create enclose device symlinks only (/dev/by-enclosure)
|
-e Create enclose device symlinks only (/dev/by-enclosure)
|
||||||
-g Storage network topology [default="$TOPOLOGY"]
|
-g Storage network topology [default="$TOPOLOGY"]
|
||||||
|
|||||||
+6
-5
@@ -1,7 +1,6 @@
|
|||||||
include $(top_srcdir)/config/Rules.am
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
|
||||||
# Unconditionally enable debugging for zdb
|
AM_CPPFLAGS += -DDEBUG
|
||||||
AM_CPPFLAGS += -DDEBUG -UNDEBUG
|
|
||||||
|
|
||||||
DEFAULT_INCLUDES += \
|
DEFAULT_INCLUDES += \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
@@ -11,9 +10,11 @@ sbin_PROGRAMS = zdb
|
|||||||
|
|
||||||
zdb_SOURCES = \
|
zdb_SOURCES = \
|
||||||
zdb.c \
|
zdb.c \
|
||||||
zdb_il.c \
|
zdb_il.c
|
||||||
zdb.h
|
|
||||||
|
|
||||||
zdb_LDADD = \
|
zdb_LDADD = \
|
||||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
$(top_builddir)/lib/libzpool/libzpool.la
|
$(top_builddir)/lib/libuutil/libuutil.la \
|
||||||
|
$(top_builddir)/lib/libzpool/libzpool.la \
|
||||||
|
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||||
|
$(top_builddir)/lib/libzfs_core/libzfs_core.la
|
||||||
|
|||||||
+401
-2224
File diff suppressed because it is too large
Load Diff
+66
-92
@@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2017 by Delphix. All rights reserved.
|
* Copyright (c) 2013, 2016 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -42,14 +42,11 @@
|
|||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/zil.h>
|
#include <sys/zil.h>
|
||||||
#include <sys/zil_impl.h>
|
#include <sys/zil_impl.h>
|
||||||
#include <sys/spa_impl.h>
|
|
||||||
#include <sys/abd.h>
|
#include <sys/abd.h>
|
||||||
|
|
||||||
#include "zdb.h"
|
|
||||||
|
|
||||||
extern uint8_t dump_opt[256];
|
extern uint8_t dump_opt[256];
|
||||||
|
|
||||||
static char tab_prefix[4] = "\t\t\t";
|
static char prefix[4] = "\t\t\t";
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_log_bp(const blkptr_t *bp, const char *prefix)
|
print_log_bp(const blkptr_t *bp, const char *prefix)
|
||||||
@@ -62,9 +59,8 @@ print_log_bp(const blkptr_t *bp, const char *prefix)
|
|||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_create(zilog_t *zilog, int txtype, void *arg)
|
zil_prt_rec_create(zilog_t *zilog, int txtype, lr_create_t *lr)
|
||||||
{
|
{
|
||||||
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;
|
||||||
lr_attr_t *lrattr;
|
lr_attr_t *lrattr;
|
||||||
@@ -79,55 +75,49 @@ zil_prt_rec_create(zilog_t *zilog, int txtype, void *arg)
|
|||||||
|
|
||||||
if (txtype == TX_SYMLINK) {
|
if (txtype == TX_SYMLINK) {
|
||||||
link = name + strlen(name) + 1;
|
link = name + strlen(name) + 1;
|
||||||
(void) printf("%s%s -> %s\n", tab_prefix, name, link);
|
(void) printf("%s%s -> %s\n", prefix, name, link);
|
||||||
} else if (txtype != TX_MKXATTR) {
|
} else if (txtype != TX_MKXATTR) {
|
||||||
(void) printf("%s%s\n", tab_prefix, name);
|
(void) printf("%s%s\n", prefix, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) printf("%s%s", tab_prefix, ctime(&crtime));
|
(void) printf("%s%s", prefix, ctime(&crtime));
|
||||||
(void) printf("%sdoid %llu, foid %llu, slots %llu, mode %llo\n",
|
(void) printf("%sdoid %llu, foid %llu, slots %llu, mode %llo\n", prefix,
|
||||||
tab_prefix, (u_longlong_t)lr->lr_doid,
|
(u_longlong_t)lr->lr_doid,
|
||||||
(u_longlong_t)LR_FOID_GET_OBJ(lr->lr_foid),
|
(u_longlong_t)LR_FOID_GET_OBJ(lr->lr_foid),
|
||||||
(u_longlong_t)LR_FOID_GET_SLOTS(lr->lr_foid),
|
(u_longlong_t)LR_FOID_GET_SLOTS(lr->lr_foid),
|
||||||
(longlong_t)lr->lr_mode);
|
(longlong_t)lr->lr_mode);
|
||||||
(void) printf("%suid %llu, gid %llu, gen %llu, rdev 0x%llx\n",
|
(void) printf("%suid %llu, gid %llu, gen %llu, rdev 0x%llx\n", prefix,
|
||||||
tab_prefix,
|
|
||||||
(u_longlong_t)lr->lr_uid, (u_longlong_t)lr->lr_gid,
|
(u_longlong_t)lr->lr_uid, (u_longlong_t)lr->lr_gid,
|
||||||
(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 */
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_remove(zilog_t *zilog, int txtype, void *arg)
|
zil_prt_rec_remove(zilog_t *zilog, int txtype, lr_remove_t *lr)
|
||||||
{
|
{
|
||||||
lr_remove_t *lr = arg;
|
(void) printf("%sdoid %llu, name %s\n", 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 */
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_link(zilog_t *zilog, int txtype, void *arg)
|
zil_prt_rec_link(zilog_t *zilog, int txtype, lr_link_t *lr)
|
||||||
{
|
{
|
||||||
lr_link_t *lr = arg;
|
(void) printf("%sdoid %llu, link_obj %llu, name %s\n", prefix,
|
||||||
|
|
||||||
(void) printf("%sdoid %llu, link_obj %llu, name %s\n", tab_prefix,
|
|
||||||
(u_longlong_t)lr->lr_doid, (u_longlong_t)lr->lr_link_obj,
|
(u_longlong_t)lr->lr_doid, (u_longlong_t)lr->lr_link_obj,
|
||||||
(char *)(lr + 1));
|
(char *)(lr + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_rename(zilog_t *zilog, int txtype, void *arg)
|
zil_prt_rec_rename(zilog_t *zilog, int txtype, lr_rename_t *lr)
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
|
||||||
(void) printf("%ssdoid %llu, tdoid %llu\n", tab_prefix,
|
(void) printf("%ssdoid %llu, tdoid %llu\n", 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", prefix, snm, tnm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
@@ -135,8 +125,9 @@ 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)
|
||||||
{
|
{
|
||||||
char *cdata = data;
|
char *cdata = data;
|
||||||
|
int i;
|
||||||
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
if (isprint(*cdata))
|
if (isprint(*cdata))
|
||||||
(void) printf("%c ", *cdata);
|
(void) printf("%c ", *cdata);
|
||||||
else
|
else
|
||||||
@@ -148,16 +139,15 @@ zil_prt_rec_write_cb(void *data, size_t len, void *unused)
|
|||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_write(zilog_t *zilog, int txtype, void *arg)
|
zil_prt_rec_write(zilog_t *zilog, int txtype, lr_write_t *lr)
|
||||||
{
|
{
|
||||||
lr_write_t *lr = arg;
|
|
||||||
abd_t *data;
|
abd_t *data;
|
||||||
blkptr_t *bp = &lr->lr_blkptr;
|
blkptr_t *bp = &lr->lr_blkptr;
|
||||||
zbookmark_phys_t zb;
|
zbookmark_phys_t zb;
|
||||||
int verbose = MAX(dump_opt['d'], dump_opt['i']);
|
int verbose = MAX(dump_opt['d'], dump_opt['i']);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
(void) printf("%sfoid %llu, offset %llx, length %llx\n", tab_prefix,
|
(void) printf("%sfoid %llu, offset %llx, length %llx\n", prefix,
|
||||||
(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);
|
||||||
|
|
||||||
@@ -165,21 +155,20 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, void *arg)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
|
if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
|
||||||
(void) printf("%shas blkptr, %s\n", tab_prefix,
|
(void) printf("%shas blkptr, %s\n", prefix,
|
||||||
!BP_IS_HOLE(bp) &&
|
!BP_IS_HOLE(bp) &&
|
||||||
bp->blk_birth >= spa_min_claim_txg(zilog->zl_spa) ?
|
bp->blk_birth >= spa_first_txg(zilog->zl_spa) ?
|
||||||
"will claim" : "won't claim");
|
"will claim" : "won't claim");
|
||||||
print_log_bp(bp, tab_prefix);
|
print_log_bp(bp, prefix);
|
||||||
|
|
||||||
if (BP_IS_HOLE(bp)) {
|
if (BP_IS_HOLE(bp)) {
|
||||||
(void) printf("\t\t\tLSIZE 0x%llx\n",
|
(void) printf("\t\t\tLSIZE 0x%llx\n",
|
||||||
(u_longlong_t)BP_GET_LSIZE(bp));
|
(u_longlong_t)BP_GET_LSIZE(bp));
|
||||||
(void) printf("%s<hole>\n", tab_prefix);
|
(void) printf("%s<hole>\n", prefix);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (bp->blk_birth < zilog->zl_header->zh_claim_txg) {
|
if (bp->blk_birth < zilog->zl_header->zh_claim_txg) {
|
||||||
(void) printf("%s<block already committed>\n",
|
(void) printf("%s<block already committed>\n", prefix);
|
||||||
tab_prefix);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +188,7 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, void *arg)
|
|||||||
abd_copy_from_buf(data, lr + 1, lr->lr_length);
|
abd_copy_from_buf(data, lr + 1, lr->lr_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) printf("%s", tab_prefix);
|
(void) printf("%s", prefix);
|
||||||
(void) abd_iterate_func(data,
|
(void) abd_iterate_func(data,
|
||||||
0, MIN(lr->lr_length, (verbose < 6 ? 20 : SPA_MAXBLOCKSIZE)),
|
0, MIN(lr->lr_length, (verbose < 6 ? 20 : SPA_MAXBLOCKSIZE)),
|
||||||
zil_prt_rec_write_cb, NULL);
|
zil_prt_rec_write_cb, NULL);
|
||||||
@@ -211,55 +200,52 @@ out:
|
|||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_truncate(zilog_t *zilog, int txtype, void *arg)
|
zil_prt_rec_truncate(zilog_t *zilog, int txtype, lr_truncate_t *lr)
|
||||||
{
|
{
|
||||||
lr_truncate_t *lr = arg;
|
(void) printf("%sfoid %llu, offset 0x%llx, length 0x%llx\n", prefix,
|
||||||
|
|
||||||
(void) printf("%sfoid %llu, offset 0x%llx, length 0x%llx\n", tab_prefix,
|
|
||||||
(u_longlong_t)lr->lr_foid, (longlong_t)lr->lr_offset,
|
(u_longlong_t)lr->lr_foid, (longlong_t)lr->lr_offset,
|
||||||
(u_longlong_t)lr->lr_length);
|
(u_longlong_t)lr->lr_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_setattr(zilog_t *zilog, int txtype, void *arg)
|
zil_prt_rec_setattr(zilog_t *zilog, int txtype, lr_setattr_t *lr)
|
||||||
{
|
{
|
||||||
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];
|
||||||
|
|
||||||
(void) printf("%sfoid %llu, mask 0x%llx\n", tab_prefix,
|
(void) printf("%sfoid %llu, mask 0x%llx\n", prefix,
|
||||||
(u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_mask);
|
(u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_mask);
|
||||||
|
|
||||||
if (lr->lr_mask & AT_MODE) {
|
if (lr->lr_mask & AT_MODE) {
|
||||||
(void) printf("%sAT_MODE %llo\n", tab_prefix,
|
(void) printf("%sAT_MODE %llo\n", prefix,
|
||||||
(longlong_t)lr->lr_mode);
|
(longlong_t)lr->lr_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lr->lr_mask & AT_UID) {
|
if (lr->lr_mask & AT_UID) {
|
||||||
(void) printf("%sAT_UID %llu\n", tab_prefix,
|
(void) printf("%sAT_UID %llu\n", prefix,
|
||||||
(u_longlong_t)lr->lr_uid);
|
(u_longlong_t)lr->lr_uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lr->lr_mask & AT_GID) {
|
if (lr->lr_mask & AT_GID) {
|
||||||
(void) printf("%sAT_GID %llu\n", tab_prefix,
|
(void) printf("%sAT_GID %llu\n", prefix,
|
||||||
(u_longlong_t)lr->lr_gid);
|
(u_longlong_t)lr->lr_gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lr->lr_mask & AT_SIZE) {
|
if (lr->lr_mask & AT_SIZE) {
|
||||||
(void) printf("%sAT_SIZE %llu\n", tab_prefix,
|
(void) printf("%sAT_SIZE %llu\n", prefix,
|
||||||
(u_longlong_t)lr->lr_size);
|
(u_longlong_t)lr->lr_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lr->lr_mask & AT_ATIME) {
|
if (lr->lr_mask & AT_ATIME) {
|
||||||
(void) printf("%sAT_ATIME %llu.%09llu %s", tab_prefix,
|
(void) printf("%sAT_ATIME %llu.%09llu %s", prefix,
|
||||||
(u_longlong_t)lr->lr_atime[0],
|
(u_longlong_t)lr->lr_atime[0],
|
||||||
(u_longlong_t)lr->lr_atime[1],
|
(u_longlong_t)lr->lr_atime[1],
|
||||||
ctime(&atime));
|
ctime(&atime));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lr->lr_mask & AT_MTIME) {
|
if (lr->lr_mask & AT_MTIME) {
|
||||||
(void) printf("%sAT_MTIME %llu.%09llu %s", tab_prefix,
|
(void) printf("%sAT_MTIME %llu.%09llu %s", prefix,
|
||||||
(u_longlong_t)lr->lr_mtime[0],
|
(u_longlong_t)lr->lr_mtime[0],
|
||||||
(u_longlong_t)lr->lr_mtime[1],
|
(u_longlong_t)lr->lr_mtime[1],
|
||||||
ctime(&mtime));
|
ctime(&mtime));
|
||||||
@@ -268,43 +254,41 @@ zil_prt_rec_setattr(zilog_t *zilog, int txtype, void *arg)
|
|||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
zil_prt_rec_acl(zilog_t *zilog, int txtype, void *arg)
|
zil_prt_rec_acl(zilog_t *zilog, int txtype, lr_acl_t *lr)
|
||||||
{
|
{
|
||||||
lr_acl_t *lr = arg;
|
(void) printf("%sfoid %llu, aclcnt %llu\n", 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*zil_prt_rec_func_t)(zilog_t *, int, void *);
|
typedef void (*zil_prt_rec_func_t)(zilog_t *, int, 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;
|
||||||
const char *zri_name;
|
char *zri_name;
|
||||||
uint64_t zri_count;
|
uint64_t zri_count;
|
||||||
} zil_rec_info_t;
|
} zil_rec_info_t;
|
||||||
|
|
||||||
static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = {
|
static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = {
|
||||||
{.zri_print = NULL, .zri_name = "Total "},
|
{ NULL, "Total " },
|
||||||
{.zri_print = zil_prt_rec_create, .zri_name = "TX_CREATE "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_create, "TX_CREATE " },
|
||||||
{.zri_print = zil_prt_rec_create, .zri_name = "TX_MKDIR "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_create, "TX_MKDIR " },
|
||||||
{.zri_print = zil_prt_rec_create, .zri_name = "TX_MKXATTR "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_create, "TX_MKXATTR " },
|
||||||
{.zri_print = zil_prt_rec_create, .zri_name = "TX_SYMLINK "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_create, "TX_SYMLINK " },
|
||||||
{.zri_print = zil_prt_rec_remove, .zri_name = "TX_REMOVE "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_remove, "TX_REMOVE " },
|
||||||
{.zri_print = zil_prt_rec_remove, .zri_name = "TX_RMDIR "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_remove, "TX_RMDIR " },
|
||||||
{.zri_print = zil_prt_rec_link, .zri_name = "TX_LINK "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_link, "TX_LINK " },
|
||||||
{.zri_print = zil_prt_rec_rename, .zri_name = "TX_RENAME "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_rename, "TX_RENAME " },
|
||||||
{.zri_print = zil_prt_rec_write, .zri_name = "TX_WRITE "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_write, "TX_WRITE " },
|
||||||
{.zri_print = zil_prt_rec_truncate, .zri_name = "TX_TRUNCATE "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_truncate, "TX_TRUNCATE " },
|
||||||
{.zri_print = zil_prt_rec_setattr, .zri_name = "TX_SETATTR "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_setattr, "TX_SETATTR " },
|
||||||
{.zri_print = zil_prt_rec_acl, .zri_name = "TX_ACL_V0 "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_acl, "TX_ACL_V0 " },
|
||||||
{.zri_print = zil_prt_rec_acl, .zri_name = "TX_ACL_ACL "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_acl, "TX_ACL_ACL " },
|
||||||
{.zri_print = zil_prt_rec_create, .zri_name = "TX_CREATE_ACL "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_create, "TX_CREATE_ACL " },
|
||||||
{.zri_print = zil_prt_rec_create, .zri_name = "TX_CREATE_ATTR "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_create, "TX_CREATE_ATTR " },
|
||||||
{.zri_print = zil_prt_rec_create, .zri_name = "TX_CREATE_ACL_ATTR "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_create, "TX_CREATE_ACL_ATTR " },
|
||||||
{.zri_print = zil_prt_rec_create, .zri_name = "TX_MKDIR_ACL "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_create, "TX_MKDIR_ACL " },
|
||||||
{.zri_print = zil_prt_rec_create, .zri_name = "TX_MKDIR_ATTR "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_create, "TX_MKDIR_ATTR " },
|
||||||
{.zri_print = zil_prt_rec_create, .zri_name = "TX_MKDIR_ACL_ATTR "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_create, "TX_MKDIR_ACL_ATTR " },
|
||||||
{.zri_print = zil_prt_rec_write, .zri_name = "TX_WRITE2 "},
|
{ (zil_prt_rec_func_t)zil_prt_rec_write, "TX_WRITE2 " },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
@@ -327,13 +311,8 @@ print_log_record(zilog_t *zilog, lr_t *lr, void *arg, uint64_t claim_txg)
|
|||||||
(u_longlong_t)lr->lrc_txg,
|
(u_longlong_t)lr->lrc_txg,
|
||||||
(u_longlong_t)lr->lrc_seq);
|
(u_longlong_t)lr->lrc_seq);
|
||||||
|
|
||||||
if (txtype && verbose >= 3) {
|
if (txtype && verbose >= 3)
|
||||||
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 {
|
|
||||||
(void) printf("%s(encrypted)\n", tab_prefix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
zil_rec_info[txtype].zri_count++;
|
zil_rec_info[txtype].zri_count++;
|
||||||
zil_rec_info[0].zri_count++;
|
zil_rec_info[0].zri_count++;
|
||||||
@@ -347,7 +326,7 @@ print_log_block(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg)
|
|||||||
{
|
{
|
||||||
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;
|
char *claim;
|
||||||
|
|
||||||
if (verbose <= 3)
|
if (verbose <= 3)
|
||||||
return (0);
|
return (0);
|
||||||
@@ -362,7 +341,7 @@ print_log_block(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg)
|
|||||||
|
|
||||||
if (claim_txg != 0)
|
if (claim_txg != 0)
|
||||||
claim = "already claimed";
|
claim = "already claimed";
|
||||||
else if (bp->blk_birth >= spa_min_claim_txg(zilog->zl_spa))
|
else if (bp->blk_birth >= spa_first_txg(zilog->zl_spa))
|
||||||
claim = "will claim";
|
claim = "will claim";
|
||||||
else
|
else
|
||||||
claim = "won't claim";
|
claim = "won't claim";
|
||||||
@@ -376,7 +355,7 @@ print_log_block(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg)
|
|||||||
static void
|
static void
|
||||||
print_log_stats(int verbose)
|
print_log_stats(int verbose)
|
||||||
{
|
{
|
||||||
unsigned i, w, p10;
|
int i, w, p10;
|
||||||
|
|
||||||
if (verbose > 3)
|
if (verbose > 3)
|
||||||
(void) printf("\n");
|
(void) printf("\n");
|
||||||
@@ -417,15 +396,10 @@ dump_intent_log(zilog_t *zilog)
|
|||||||
for (i = 0; i < TX_MAX_TYPE; i++)
|
for (i = 0; i < TX_MAX_TYPE; i++)
|
||||||
zil_rec_info[i].zri_count = 0;
|
zil_rec_info[i].zri_count = 0;
|
||||||
|
|
||||||
/* see comment in zil_claim() or zil_check_log_chain() */
|
|
||||||
if (zilog->zl_spa->spa_uberblock.ub_checkpoint_txg != 0 &&
|
|
||||||
zh->zh_claim_txg == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (verbose >= 2) {
|
if (verbose >= 2) {
|
||||||
(void) printf("\n");
|
(void) printf("\n");
|
||||||
(void) zil_parse(zilog, print_log_block, print_log_record, NULL,
|
(void) zil_parse(zilog, print_log_block, print_log_record, NULL,
|
||||||
zh->zh_claim_txg, B_FALSE);
|
zh->zh_claim_txg);
|
||||||
print_log_stats(verbose);
|
print_log_stats(verbose);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+51
-5
@@ -1,11 +1,11 @@
|
|||||||
SUBDIRS = zed.d
|
|
||||||
|
|
||||||
include $(top_srcdir)/config/Rules.am
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
|
||||||
DEFAULT_INCLUDES += \
|
DEFAULT_INCLUDES += \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
-I$(top_srcdir)/lib/libspl/include
|
-I$(top_srcdir)/lib/libspl/include
|
||||||
|
|
||||||
|
EXTRA_DIST = zed.d/README
|
||||||
|
|
||||||
sbin_PROGRAMS = zed
|
sbin_PROGRAMS = zed
|
||||||
|
|
||||||
ZED_SRC = \
|
ZED_SRC = \
|
||||||
@@ -40,9 +40,55 @@ FMA_SRC = \
|
|||||||
zed_SOURCES = $(ZED_SRC) $(FMA_SRC)
|
zed_SOURCES = $(ZED_SRC) $(FMA_SRC)
|
||||||
|
|
||||||
zed_LDADD = \
|
zed_LDADD = \
|
||||||
|
$(top_builddir)/lib/libavl/libavl.la \
|
||||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
|
$(top_builddir)/lib/libspl/libspl.la \
|
||||||
$(top_builddir)/lib/libuutil/libuutil.la \
|
$(top_builddir)/lib/libuutil/libuutil.la \
|
||||||
$(top_builddir)/lib/libzfs/libzfs.la
|
$(top_builddir)/lib/libzpool/libzpool.la \
|
||||||
|
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||||
|
$(top_builddir)/lib/libzfs_core/libzfs_core.la
|
||||||
|
|
||||||
zed_LDADD += -lrt
|
zed_LDFLAGS = -lrt -pthread
|
||||||
zed_LDFLAGS = -pthread
|
|
||||||
|
zedconfdir = $(sysconfdir)/zfs/zed.d
|
||||||
|
|
||||||
|
dist_zedconf_DATA = \
|
||||||
|
zed.d/zed-functions.sh \
|
||||||
|
zed.d/zed.rc
|
||||||
|
|
||||||
|
zedexecdir = $(libexecdir)/zfs/zed.d
|
||||||
|
|
||||||
|
dist_zedexec_SCRIPTS = \
|
||||||
|
zed.d/all-debug.sh \
|
||||||
|
zed.d/all-syslog.sh \
|
||||||
|
zed.d/data-notify.sh \
|
||||||
|
zed.d/generic-notify.sh \
|
||||||
|
zed.d/resilver_finish-notify.sh \
|
||||||
|
zed.d/scrub_finish-notify.sh \
|
||||||
|
zed.d/statechange-led.sh \
|
||||||
|
zed.d/statechange-notify.sh \
|
||||||
|
zed.d/vdev_clear-led.sh \
|
||||||
|
zed.d/vdev_attach-led.sh \
|
||||||
|
zed.d/pool_import-led.sh \
|
||||||
|
zed.d/resilver_finish-start-scrub.sh
|
||||||
|
|
||||||
|
zedconfdefaults = \
|
||||||
|
all-syslog.sh \
|
||||||
|
data-notify.sh \
|
||||||
|
resilver_finish-notify.sh \
|
||||||
|
scrub_finish-notify.sh \
|
||||||
|
statechange-led.sh \
|
||||||
|
statechange-notify.sh \
|
||||||
|
vdev_clear-led.sh \
|
||||||
|
vdev_attach-led.sh \
|
||||||
|
pool_import-led.sh \
|
||||||
|
resilver_finish-start-scrub.sh
|
||||||
|
|
||||||
|
install-data-hook:
|
||||||
|
$(MKDIR_P) "$(DESTDIR)$(zedconfdir)"
|
||||||
|
for f in $(zedconfdefaults); do \
|
||||||
|
test -f "$(DESTDIR)$(zedconfdir)/$${f}" -o \
|
||||||
|
-L "$(DESTDIR)$(zedconfdir)/$${f}" || \
|
||||||
|
ln -s "$(zedexecdir)/$${f}" "$(DESTDIR)$(zedconfdir)"; \
|
||||||
|
done
|
||||||
|
chmod 0600 "$(DESTDIR)$(zedconfdir)/zed.rc"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file implements the minimal FMD module API required to support the
|
* This file imlements the minimal FMD module API required to support the
|
||||||
* fault logic modules in ZED. This support includes module registration,
|
* fault logic modules in ZED. This support includes module registration,
|
||||||
* memory allocation, module property accessors, basic case management,
|
* memory allocation, module property accessors, basic case management,
|
||||||
* one-shot timers and SERD engines.
|
* one-shot timers and SERD engines.
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ fmd_serd_eng_empty(fmd_serd_eng_t *sgp)
|
|||||||
void
|
void
|
||||||
fmd_serd_eng_reset(fmd_serd_eng_t *sgp)
|
fmd_serd_eng_reset(fmd_serd_eng_t *sgp)
|
||||||
{
|
{
|
||||||
serd_log_msg(" SERD Engine: resetting %s", sgp->sg_name);
|
serd_log_msg(" SERD Engine: reseting %s", sgp->sg_name);
|
||||||
|
|
||||||
while (sgp->sg_count != 0)
|
while (sgp->sg_count != 0)
|
||||||
fmd_serd_eng_discard(sgp, list_head(&sgp->sg_list));
|
fmd_serd_eng_discard(sgp, list_head(&sgp->sg_list));
|
||||||
|
|||||||
+38
-92
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, Intel Corporation.
|
* Copyright (c) 2016, Intel Corporation.
|
||||||
* Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libnvpair.h>
|
#include <libnvpair.h>
|
||||||
@@ -54,25 +53,13 @@ pthread_t g_agents_tid;
|
|||||||
libzfs_handle_t *g_zfs_hdl;
|
libzfs_handle_t *g_zfs_hdl;
|
||||||
|
|
||||||
/* guid search data */
|
/* guid search data */
|
||||||
typedef enum device_type {
|
|
||||||
DEVICE_TYPE_L2ARC, /* l2arc device */
|
|
||||||
DEVICE_TYPE_SPARE, /* spare device */
|
|
||||||
DEVICE_TYPE_PRIMARY /* any primary pool storage device */
|
|
||||||
} device_type_t;
|
|
||||||
|
|
||||||
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;
|
||||||
char *gs_devid;
|
char *gs_devid;
|
||||||
device_type_t gs_vdev_type;
|
|
||||||
uint64_t gs_vdev_expandtime; /* vdev expansion time */
|
|
||||||
} guid_search_t;
|
} guid_search_t;
|
||||||
|
|
||||||
/*
|
static void
|
||||||
* Walks the vdev tree recursively looking for a matching devid.
|
|
||||||
* Returns B_TRUE as soon as a matching device is found, B_FALSE otherwise.
|
|
||||||
*/
|
|
||||||
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;
|
||||||
@@ -85,48 +72,19 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
|||||||
*/
|
*/
|
||||||
if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_CHILDREN,
|
if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_CHILDREN,
|
||||||
&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)) {
|
zfs_agent_iter_vdev(zhp, child[c], gsp);
|
||||||
gsp->gs_vdev_type = DEVICE_TYPE_PRIMARY;
|
return;
|
||||||
return (B_TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Iterate over any spares and cache devices
|
* On a devid match, grab the vdev guid
|
||||||
*/
|
*/
|
||||||
if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_SPARES,
|
if ((gsp->gs_vdev_guid == 0) &&
|
||||||
&child, &children) == 0) {
|
|
||||||
for (c = 0; c < children; c++) {
|
|
||||||
if (zfs_agent_iter_vdev(zhp, child[c], gsp)) {
|
|
||||||
gsp->gs_vdev_type = DEVICE_TYPE_L2ARC;
|
|
||||||
return (B_TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_L2CACHE,
|
|
||||||
&child, &children) == 0) {
|
|
||||||
for (c = 0; c < children; c++) {
|
|
||||||
if (zfs_agent_iter_vdev(zhp, child[c], gsp)) {
|
|
||||||
gsp->gs_vdev_type = DEVICE_TYPE_SPARE;
|
|
||||||
return (B_TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* On a devid match, grab the vdev guid and expansion time, if any.
|
|
||||||
*/
|
|
||||||
if (gsp->gs_devid != NULL &&
|
|
||||||
(nvlist_lookup_string(nvl, ZPOOL_CONFIG_DEVID, &path) == 0) &&
|
(nvlist_lookup_string(nvl, ZPOOL_CONFIG_DEVID, &path) == 0) &&
|
||||||
(strcmp(gsp->gs_devid, path) == 0)) {
|
(strcmp(gsp->gs_devid, path) == 0)) {
|
||||||
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID,
|
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID,
|
||||||
&gsp->gs_vdev_guid);
|
&gsp->gs_vdev_guid);
|
||||||
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_EXPANSION_TIME,
|
|
||||||
&gsp->gs_vdev_expandtime);
|
|
||||||
return (B_TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (B_FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -141,7 +99,7 @@ zfs_agent_iter_pool(zpool_handle_t *zhp, void *arg)
|
|||||||
if ((config = zpool_get_config(zhp, NULL)) != NULL) {
|
if ((config = zpool_get_config(zhp, NULL)) != NULL) {
|
||||||
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
||||||
&nvl) == 0) {
|
&nvl) == 0) {
|
||||||
(void) zfs_agent_iter_vdev(zhp, nvl, gsp);
|
zfs_agent_iter_vdev(zhp, nvl, gsp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -190,8 +148,6 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int64_t tod[2];
|
int64_t tod[2];
|
||||||
uint64_t pool_guid = 0, vdev_guid = 0;
|
uint64_t pool_guid = 0, vdev_guid = 0;
|
||||||
guid_search_t search = { 0 };
|
|
||||||
device_type_t devtype = DEVICE_TYPE_PRIMARY;
|
|
||||||
|
|
||||||
class = "resource.fs.zfs.removed";
|
class = "resource.fs.zfs.removed";
|
||||||
subclass = "";
|
subclass = "";
|
||||||
@@ -200,55 +156,30 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||||||
(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);
|
||||||
|
|
||||||
(void) gettimeofday(&tv, NULL);
|
|
||||||
tod[0] = tv.tv_sec;
|
|
||||||
tod[1] = tv.tv_usec;
|
|
||||||
(void) nvlist_add_int64_array(payload, FM_EREPORT_TIME, tod, 2);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For multipath, spare and l2arc devices ZFS_EV_VDEV_GUID or
|
* For multipath, ZFS_EV_VDEV_GUID is missing so find it.
|
||||||
* ZFS_EV_POOL_GUID may be missing so find them.
|
|
||||||
*/
|
*/
|
||||||
(void) nvlist_lookup_string(nvl, DEV_IDENTIFIER,
|
if (vdev_guid == 0) {
|
||||||
&search.gs_devid);
|
guid_search_t search = { 0 };
|
||||||
(void) zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search);
|
|
||||||
pool_guid = search.gs_pool_guid;
|
|
||||||
vdev_guid = search.gs_vdev_guid;
|
|
||||||
devtype = search.gs_vdev_type;
|
|
||||||
|
|
||||||
/*
|
(void) nvlist_lookup_string(nvl, DEV_IDENTIFIER,
|
||||||
* We want to avoid reporting "remove" events coming from
|
&search.gs_devid);
|
||||||
* libudev for VDEVs which were expanded recently (10s) and
|
|
||||||
* avoid activating spares in response to partitions being
|
(void) zpool_iter(g_zfs_hdl, zfs_agent_iter_pool,
|
||||||
* deleted and created in rapid succession.
|
&search);
|
||||||
*/
|
pool_guid = search.gs_pool_guid;
|
||||||
if (search.gs_vdev_expandtime != 0 &&
|
vdev_guid = search.gs_vdev_guid;
|
||||||
search.gs_vdev_expandtime + 10 > tv.tv_sec) {
|
|
||||||
zed_log_msg(LOG_INFO, "agent post event: ignoring '%s' "
|
|
||||||
"for recently expanded device '%s'", EC_DEV_REMOVE,
|
|
||||||
search.gs_devid);
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) nvlist_add_uint64(payload,
|
(void) nvlist_add_uint64(payload,
|
||||||
FM_EREPORT_PAYLOAD_ZFS_POOL_GUID, pool_guid);
|
FM_EREPORT_PAYLOAD_ZFS_POOL_GUID, pool_guid);
|
||||||
(void) nvlist_add_uint64(payload,
|
(void) nvlist_add_uint64(payload,
|
||||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID, vdev_guid);
|
FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID, vdev_guid);
|
||||||
switch (devtype) {
|
|
||||||
case DEVICE_TYPE_L2ARC:
|
(void) gettimeofday(&tv, NULL);
|
||||||
(void) nvlist_add_string(payload,
|
tod[0] = tv.tv_sec;
|
||||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE,
|
tod[1] = tv.tv_usec;
|
||||||
VDEV_TYPE_L2CACHE);
|
(void) nvlist_add_int64_array(payload, FM_EREPORT_TIME, tod, 2);
|
||||||
break;
|
|
||||||
case DEVICE_TYPE_SPARE:
|
|
||||||
(void) nvlist_add_string(payload,
|
|
||||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE, VDEV_TYPE_SPARE);
|
|
||||||
break;
|
|
||||||
case DEVICE_TYPE_PRIMARY:
|
|
||||||
(void) nvlist_add_string(payload,
|
|
||||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE, VDEV_TYPE_DISK);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
zed_log_msg(LOG_INFO, "agent post event: mapping '%s' to '%s'",
|
zed_log_msg(LOG_INFO, "agent post event: mapping '%s' to '%s'",
|
||||||
EC_DEV_REMOVE, class);
|
EC_DEV_REMOVE, class);
|
||||||
@@ -262,7 +193,6 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||||||
list_insert_tail(&agent_events, event);
|
list_insert_tail(&agent_events, event);
|
||||||
(void) pthread_mutex_unlock(&agent_lock);
|
(void) pthread_mutex_unlock(&agent_lock);
|
||||||
|
|
||||||
out:
|
|
||||||
(void) pthread_cond_signal(&agent_cond);
|
(void) pthread_cond_signal(&agent_cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,3 +350,19 @@ zfs_agent_fini(void)
|
|||||||
|
|
||||||
g_zfs_hdl = NULL;
|
g_zfs_hdl = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In ZED context, all the FMA agents run in the same thread
|
||||||
|
* and do not require a unique libzfs instance. Modules should
|
||||||
|
* use these stubs.
|
||||||
|
*/
|
||||||
|
libzfs_handle_t *
|
||||||
|
__libzfs_init(void)
|
||||||
|
{
|
||||||
|
return (g_zfs_hdl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__libzfs_fini(libzfs_handle_t *hdl)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,6 +39,13 @@ extern int zfs_slm_init(void);
|
|||||||
extern void zfs_slm_fini(void);
|
extern void zfs_slm_fini(void);
|
||||||
extern void zfs_slm_event(const char *, const char *, nvlist_t *);
|
extern void zfs_slm_event(const char *, const char *, nvlist_t *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In ZED context, all the FMA agents run in the same thread
|
||||||
|
* and do not require a unique libzfs instance.
|
||||||
|
*/
|
||||||
|
extern libzfs_handle_t *__libzfs_init(void);
|
||||||
|
extern void __libzfs_fini(libzfs_handle_t *);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <libuutil.h>
|
#include <libuutil.h>
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
@@ -168,12 +167,14 @@ zfs_case_unserialize(fmd_hdl_t *hdl, fmd_case_t *cp)
|
|||||||
static void
|
static void
|
||||||
zfs_mark_vdev(uint64_t pool_guid, nvlist_t *vd, er_timeval_t *loaded)
|
zfs_mark_vdev(uint64_t pool_guid, nvlist_t *vd, er_timeval_t *loaded)
|
||||||
{
|
{
|
||||||
uint64_t vdev_guid = 0;
|
uint64_t vdev_guid;
|
||||||
uint_t c, children;
|
uint_t c, children;
|
||||||
nvlist_t **child;
|
nvlist_t **child;
|
||||||
zfs_case_t *zcp;
|
zfs_case_t *zcp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
(void) nvlist_lookup_uint64(vd, ZPOOL_CONFIG_GUID, &vdev_guid);
|
ret = nvlist_lookup_uint64(vd, ZPOOL_CONFIG_GUID, &vdev_guid);
|
||||||
|
assert(ret == 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mark any cases associated with this (pool, vdev) pair.
|
* Mark any cases associated with this (pool, vdev) pair.
|
||||||
@@ -252,10 +253,7 @@ zfs_mark_pool(zpool_handle_t *zhp, void *unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &vd);
|
ret = nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &vd);
|
||||||
if (ret) {
|
assert(ret == 0);
|
||||||
zpool_close(zhp);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
zfs_mark_vdev(pool_guid, vd, &loaded);
|
zfs_mark_vdev(pool_guid, vd, &loaded);
|
||||||
|
|
||||||
@@ -379,6 +377,11 @@ zfs_case_solve(fmd_hdl_t *hdl, zfs_case_t *zcp, const char *faultname,
|
|||||||
nvlist_t *detector, *fault;
|
nvlist_t *detector, *fault;
|
||||||
boolean_t serialize;
|
boolean_t serialize;
|
||||||
nvlist_t *fru = NULL;
|
nvlist_t *fru = NULL;
|
||||||
|
#ifdef HAVE_LIBTOPO
|
||||||
|
nvlist_t *fmri;
|
||||||
|
topo_hdl_t *thp;
|
||||||
|
int err;
|
||||||
|
#endif
|
||||||
fmd_hdl_debug(hdl, "solving fault '%s'", faultname);
|
fmd_hdl_debug(hdl, "solving fault '%s'", faultname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -397,6 +400,64 @@ zfs_case_solve(fmd_hdl_t *hdl, zfs_case_t *zcp, const char *faultname,
|
|||||||
zcp->zc_data.zc_vdev_guid);
|
zcp->zc_data.zc_vdev_guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBTOPO
|
||||||
|
/*
|
||||||
|
* We also want to make sure that the detector (pool or vdev) properly
|
||||||
|
* reflects the diagnosed state, when the fault corresponds to internal
|
||||||
|
* ZFS state (i.e. not checksum or I/O error-induced). Otherwise, a
|
||||||
|
* device which was unavailable early in boot (because the driver/file
|
||||||
|
* wasn't available) and is now healthy will be mis-diagnosed.
|
||||||
|
*/
|
||||||
|
if (!fmd_nvl_fmri_present(hdl, detector) ||
|
||||||
|
(checkunusable && !fmd_nvl_fmri_unusable(hdl, detector))) {
|
||||||
|
fmd_case_close(hdl, zcp->zc_case);
|
||||||
|
nvlist_free(detector);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fru = NULL;
|
||||||
|
if (zcp->zc_fru != NULL &&
|
||||||
|
(thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) != NULL) {
|
||||||
|
/*
|
||||||
|
* If the vdev had an associated FRU, then get the FRU nvlist
|
||||||
|
* from the topo handle and use that in the suspect list. We
|
||||||
|
* explicitly lookup the FRU because the fmri reported from the
|
||||||
|
* kernel may not have up to date details about the disk itself
|
||||||
|
* (serial, part, etc).
|
||||||
|
*/
|
||||||
|
if (topo_fmri_str2nvl(thp, zcp->zc_fru, &fmri, &err) == 0) {
|
||||||
|
libzfs_handle_t *zhdl = fmd_hdl_getspecific(hdl);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the disk is part of the system chassis, but the
|
||||||
|
* FRU indicates a different chassis ID than our
|
||||||
|
* current system, then ignore the error. This
|
||||||
|
* indicates that the device was part of another
|
||||||
|
* cluster head, and for obvious reasons cannot be
|
||||||
|
* imported on this system.
|
||||||
|
*/
|
||||||
|
if (libzfs_fru_notself(zhdl, zcp->zc_fru)) {
|
||||||
|
fmd_case_close(hdl, zcp->zc_case);
|
||||||
|
nvlist_free(fmri);
|
||||||
|
fmd_hdl_topo_rele(hdl, thp);
|
||||||
|
nvlist_free(detector);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the device is no longer present on the system, or
|
||||||
|
* topo_fmri_fru() fails for other reasons, then fall
|
||||||
|
* back to the fmri specified in the vdev.
|
||||||
|
*/
|
||||||
|
if (topo_fmri_fru(thp, fmri, &fru, &err) != 0)
|
||||||
|
fru = fmd_nvl_dup(hdl, fmri, FMD_SLEEP);
|
||||||
|
nvlist_free(fmri);
|
||||||
|
}
|
||||||
|
|
||||||
|
fmd_hdl_topo_rele(hdl, thp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
fault = fmd_nvl_create_fault(hdl, faultname, 100, detector,
|
fault = fmd_nvl_create_fault(hdl, faultname, 100, detector,
|
||||||
fru, detector);
|
fru, detector);
|
||||||
fmd_case_add_suspect(hdl, zcp->zc_case, fault);
|
fmd_case_add_suspect(hdl, zcp->zc_case, fault);
|
||||||
@@ -921,27 +982,27 @@ _zfs_diagnosis_init(fmd_hdl_t *hdl)
|
|||||||
{
|
{
|
||||||
libzfs_handle_t *zhdl;
|
libzfs_handle_t *zhdl;
|
||||||
|
|
||||||
if ((zhdl = libzfs_init()) == NULL)
|
if ((zhdl = __libzfs_init()) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((zfs_case_pool = uu_list_pool_create("zfs_case_pool",
|
if ((zfs_case_pool = uu_list_pool_create("zfs_case_pool",
|
||||||
sizeof (zfs_case_t), offsetof(zfs_case_t, zc_node),
|
sizeof (zfs_case_t), offsetof(zfs_case_t, zc_node),
|
||||||
NULL, UU_LIST_POOL_DEBUG)) == NULL) {
|
NULL, UU_LIST_POOL_DEBUG)) == NULL) {
|
||||||
libzfs_fini(zhdl);
|
__libzfs_fini(zhdl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((zfs_cases = uu_list_create(zfs_case_pool, NULL,
|
if ((zfs_cases = uu_list_create(zfs_case_pool, NULL,
|
||||||
UU_LIST_DEBUG)) == NULL) {
|
UU_LIST_DEBUG)) == NULL) {
|
||||||
uu_list_pool_destroy(zfs_case_pool);
|
uu_list_pool_destroy(zfs_case_pool);
|
||||||
libzfs_fini(zhdl);
|
__libzfs_fini(zhdl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0) {
|
if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0) {
|
||||||
uu_list_destroy(zfs_cases);
|
uu_list_destroy(zfs_cases);
|
||||||
uu_list_pool_destroy(zfs_case_pool);
|
uu_list_pool_destroy(zfs_case_pool);
|
||||||
libzfs_fini(zhdl);
|
__libzfs_fini(zhdl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -977,5 +1038,5 @@ _zfs_diagnosis_fini(fmd_hdl_t *hdl)
|
|||||||
uu_list_pool_destroy(zfs_case_pool);
|
uu_list_pool_destroy(zfs_case_pool);
|
||||||
|
|
||||||
zhdl = fmd_hdl_getspecific(hdl);
|
zhdl = fmd_hdl_getspecific(hdl);
|
||||||
libzfs_fini(zhdl);
|
__libzfs_fini(zhdl);
|
||||||
}
|
}
|
||||||
|
|||||||
+62
-101
@@ -23,7 +23,6 @@
|
|||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -64,6 +63,7 @@
|
|||||||
* trigger the FMA fault that we skipped earlier.
|
* trigger the FMA fault that we skipped earlier.
|
||||||
*
|
*
|
||||||
* ZFS on Linux porting notes:
|
* ZFS on Linux porting notes:
|
||||||
|
* In lieu of a thread pool, just spawn a thread on demmand.
|
||||||
* Linux udev provides a disk insert for both the disk and the partition
|
* Linux udev provides a disk insert for both the disk and the partition
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -73,7 +73,6 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <libnvpair.h>
|
#include <libnvpair.h>
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
#include <libzutil.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -83,10 +82,8 @@
|
|||||||
#include <sys/sunddi.h>
|
#include <sys/sunddi.h>
|
||||||
#include <sys/sysevent/eventdefs.h>
|
#include <sys/sysevent/eventdefs.h>
|
||||||
#include <sys/sysevent/dev.h>
|
#include <sys/sysevent/dev.h>
|
||||||
#include <thread_pool.h>
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
|
||||||
#include "zfs_agents.h"
|
#include "zfs_agents.h"
|
||||||
#include "../zed_log.h"
|
#include "../zed_log.h"
|
||||||
|
|
||||||
@@ -99,12 +96,12 @@ typedef void (*zfs_process_func_t)(zpool_handle_t *, nvlist_t *, boolean_t);
|
|||||||
libzfs_handle_t *g_zfshdl;
|
libzfs_handle_t *g_zfshdl;
|
||||||
list_t g_pool_list; /* list of unavailable pools at initialization */
|
list_t g_pool_list; /* list of unavailable pools at initialization */
|
||||||
list_t g_device_list; /* list of disks with asynchronous label request */
|
list_t g_device_list; /* list of disks with asynchronous label request */
|
||||||
tpool_t *g_tpool;
|
|
||||||
boolean_t g_enumeration_done;
|
boolean_t g_enumeration_done;
|
||||||
pthread_t g_zfs_tid; /* zfs_enum_pools() thread */
|
pthread_t g_zfs_tid;
|
||||||
|
|
||||||
typedef struct unavailpool {
|
typedef struct unavailpool {
|
||||||
zpool_handle_t *uap_zhp;
|
zpool_handle_t *uap_zhp;
|
||||||
|
pthread_t uap_enable_tid; /* dataset enable thread if activated */
|
||||||
list_node_t uap_node;
|
list_node_t uap_node;
|
||||||
} unavailpool_t;
|
} unavailpool_t;
|
||||||
|
|
||||||
@@ -137,6 +134,7 @@ zfs_unavail_pool(zpool_handle_t *zhp, void *data)
|
|||||||
unavailpool_t *uap;
|
unavailpool_t *uap;
|
||||||
uap = malloc(sizeof (unavailpool_t));
|
uap = malloc(sizeof (unavailpool_t));
|
||||||
uap->uap_zhp = zhp;
|
uap->uap_zhp = zhp;
|
||||||
|
uap->uap_enable_tid = 0;
|
||||||
list_insert_tail((list_t *)data, uap);
|
list_insert_tail((list_t *)data, uap);
|
||||||
} else {
|
} else {
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
@@ -157,7 +155,7 @@ zfs_unavail_pool(zpool_handle_t *zhp, void *data)
|
|||||||
* 1. physical match with no fs, no partition
|
* 1. physical match with no fs, no partition
|
||||||
* tag it top, partition disk
|
* tag it top, partition disk
|
||||||
*
|
*
|
||||||
* 2. physical match again, see partition and tag
|
* 2. physical match again, see partion and tag
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -428,16 +426,8 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
|
|||||||
nvlist_free(newvd);
|
nvlist_free(newvd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait for udev to verify the links exist, then auto-replace
|
* auto replace a leaf disk at same physical location
|
||||||
* the leaf disk at same physical location.
|
|
||||||
*/
|
*/
|
||||||
if (zpool_label_disk_wait(path, 3000) != 0) {
|
|
||||||
zed_log_msg(LOG_WARNING, "zfs_mod: expected replacement "
|
|
||||||
"disk %s is missing", path);
|
|
||||||
nvlist_free(nvroot);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = zpool_vdev_attach(zhp, fullpath, path, nvroot, B_TRUE);
|
ret = zpool_vdev_attach(zhp, fullpath, path, nvroot, B_TRUE);
|
||||||
|
|
||||||
zed_log_msg(LOG_INFO, " zpool_vdev_replace: %s with %s (%s)",
|
zed_log_msg(LOG_INFO, " zpool_vdev_replace: %s with %s (%s)",
|
||||||
@@ -476,20 +466,7 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
|||||||
&child, &children) == 0) {
|
&child, &children) == 0) {
|
||||||
for (c = 0; c < children; c++)
|
for (c = 0; c < children; c++)
|
||||||
zfs_iter_vdev(zhp, child[c], data);
|
zfs_iter_vdev(zhp, child[c], data);
|
||||||
}
|
return;
|
||||||
|
|
||||||
/*
|
|
||||||
* Iterate over any spares and cache devices
|
|
||||||
*/
|
|
||||||
if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_SPARES,
|
|
||||||
&child, &children) == 0) {
|
|
||||||
for (c = 0; c < children; c++)
|
|
||||||
zfs_iter_vdev(zhp, child[c], data);
|
|
||||||
}
|
|
||||||
if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_L2CACHE,
|
|
||||||
&child, &children) == 0) {
|
|
||||||
for (c = 0; c < children; c++)
|
|
||||||
zfs_iter_vdev(zhp, child[c], 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 */
|
||||||
@@ -534,14 +511,19 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
|
|||||||
(dp->dd_func)(zhp, nvl, dp->dd_islabeled);
|
(dp->dd_func)(zhp, nvl, dp->dd_islabeled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void *
|
||||||
zfs_enable_ds(void *arg)
|
zfs_enable_ds(void *arg)
|
||||||
{
|
{
|
||||||
unavailpool_t *pool = (unavailpool_t *)arg;
|
unavailpool_t *pool = (unavailpool_t *)arg;
|
||||||
|
|
||||||
|
assert(pool->uap_enable_tid = pthread_self());
|
||||||
|
|
||||||
(void) zpool_enable_datasets(pool->uap_zhp, NULL, 0);
|
(void) zpool_enable_datasets(pool->uap_zhp, NULL, 0);
|
||||||
zpool_close(pool->uap_zhp);
|
zpool_close(pool->uap_zhp);
|
||||||
free(pool);
|
pool->uap_zhp = NULL;
|
||||||
|
|
||||||
|
/* Note: zfs_slm_fini() will cleanup this pool entry on exit */
|
||||||
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -576,13 +558,15 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data)
|
|||||||
for (pool = list_head(&g_pool_list); pool != NULL;
|
for (pool = list_head(&g_pool_list); pool != NULL;
|
||||||
pool = list_next(&g_pool_list, pool)) {
|
pool = list_next(&g_pool_list, pool)) {
|
||||||
|
|
||||||
|
if (pool->uap_enable_tid != 0)
|
||||||
|
continue; /* entry already processed */
|
||||||
if (strcmp(zpool_get_name(zhp),
|
if (strcmp(zpool_get_name(zhp),
|
||||||
zpool_get_name(pool->uap_zhp)))
|
zpool_get_name(pool->uap_zhp)))
|
||||||
continue;
|
continue;
|
||||||
if (zfs_toplevel_state(zhp) >= VDEV_STATE_DEGRADED) {
|
if (zfs_toplevel_state(zhp) >= VDEV_STATE_DEGRADED) {
|
||||||
list_remove(&g_pool_list, pool);
|
/* send to a background thread; keep on list */
|
||||||
(void) tpool_dispatch(g_tpool, zfs_enable_ds,
|
(void) pthread_create(&pool->uap_enable_tid,
|
||||||
pool);
|
NULL, zfs_enable_ds, pool);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -674,7 +658,7 @@ zfs_deliver_add(nvlist_t *nvl, boolean_t is_lofi)
|
|||||||
devid, devpath ? devpath : "NULL", is_slice);
|
devid, devpath ? devpath : "NULL", is_slice);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterate over all vdevs looking for a match in the following order:
|
* Iterate over all vdevs looking for a match in the folllowing 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).
|
||||||
*
|
*
|
||||||
@@ -719,8 +703,8 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
|||||||
{
|
{
|
||||||
char *devname = data;
|
char *devname = data;
|
||||||
boolean_t avail_spare, l2cache;
|
boolean_t avail_spare, l2cache;
|
||||||
|
vdev_state_t newstate;
|
||||||
nvlist_t *tgt;
|
nvlist_t *tgt;
|
||||||
int error;
|
|
||||||
|
|
||||||
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));
|
||||||
@@ -728,58 +712,40 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
|||||||
if ((tgt = zpool_find_vdev_by_physpath(zhp, devname,
|
if ((tgt = zpool_find_vdev_by_physpath(zhp, devname,
|
||||||
&avail_spare, &l2cache, NULL)) != NULL) {
|
&avail_spare, &l2cache, NULL)) != NULL) {
|
||||||
char *path, fullpath[MAXPATHLEN];
|
char *path, fullpath[MAXPATHLEN];
|
||||||
uint64_t wholedisk;
|
uint64_t wholedisk = 0ULL;
|
||||||
|
|
||||||
error = nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &path);
|
verify(nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH,
|
||||||
if (error) {
|
&path) == 0);
|
||||||
zpool_close(zhp);
|
verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
|
||||||
return (0);
|
&wholedisk) == 0);
|
||||||
}
|
|
||||||
|
|
||||||
error = nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
|
|
||||||
&wholedisk);
|
|
||||||
if (error)
|
|
||||||
wholedisk = 0;
|
|
||||||
|
|
||||||
|
(void) strlcpy(fullpath, path, sizeof (fullpath));
|
||||||
if (wholedisk) {
|
if (wholedisk) {
|
||||||
path = strrchr(path, '/');
|
char *spath = zfs_strip_partition(fullpath);
|
||||||
if (path != NULL) {
|
if (!spath) {
|
||||||
path = zfs_strip_partition(path + 1);
|
zed_log_msg(LOG_INFO, "%s: Can't alloc",
|
||||||
if (path == NULL) {
|
__func__);
|
||||||
zpool_close(zhp);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
zpool_close(zhp);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) strlcpy(fullpath, path, sizeof (fullpath));
|
(void) strlcpy(fullpath, spath, sizeof (fullpath));
|
||||||
free(path);
|
free(spath);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to reopen the pool associated with this
|
* We need to reopen the pool associated with this
|
||||||
* device so that the kernel can update the size of
|
* device so that the kernel can update the size
|
||||||
* the expanded device. When expanding there is no
|
* of the expanded device.
|
||||||
* need to restart the scrub from the beginning.
|
|
||||||
*/
|
*/
|
||||||
boolean_t scrub_restart = B_FALSE;
|
(void) zpool_reopen(zhp);
|
||||||
(void) zpool_reopen_one(zhp, &scrub_restart);
|
|
||||||
} else {
|
|
||||||
(void) strlcpy(fullpath, path, sizeof (fullpath));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) {
|
if (zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) {
|
||||||
vdev_state_t newstate;
|
zed_log_msg(LOG_INFO, "zfsdle_vdev_online: setting "
|
||||||
|
"device '%s' to ONLINE state in pool '%s'",
|
||||||
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) {
|
fullpath, zpool_get_name(zhp));
|
||||||
error = zpool_vdev_online(zhp, fullpath, 0,
|
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL)
|
||||||
|
(void) zpool_vdev_online(zhp, fullpath, 0,
|
||||||
&newstate);
|
&newstate);
|
||||||
zed_log_msg(LOG_INFO, "zfsdle_vdev_online: "
|
|
||||||
"setting device '%s' to ONLINE state "
|
|
||||||
"in pool '%s': %d", fullpath,
|
|
||||||
zpool_get_name(zhp), error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
return (1);
|
return (1);
|
||||||
@@ -789,32 +755,23 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function handles the ESC_DEV_DLE device change event. Use the
|
* This function handles the ESC_DEV_DLE event.
|
||||||
* provided vdev guid when looking up a disk or partition, when the guid
|
|
||||||
* is not present assume the entire disk is owned by ZFS and append the
|
|
||||||
* expected -part1 partition information then lookup by physical path.
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
zfs_deliver_dle(nvlist_t *nvl)
|
zfs_deliver_dle(nvlist_t *nvl)
|
||||||
{
|
{
|
||||||
char *devname, name[MAXPATHLEN];
|
char *devname;
|
||||||
uint64_t guid;
|
|
||||||
|
|
||||||
if (nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &guid) == 0) {
|
if (nvlist_lookup_string(nvl, DEV_PHYS_PATH, &devname) != 0) {
|
||||||
sprintf(name, "%llu", (u_longlong_t)guid);
|
zed_log_msg(LOG_INFO, "zfs_deliver_dle: no physpath");
|
||||||
} else if (nvlist_lookup_string(nvl, DEV_PHYS_PATH, &devname) == 0) {
|
return (-1);
|
||||||
strlcpy(name, devname, MAXPATHLEN);
|
|
||||||
zfs_append_partition(name, MAXPATHLEN);
|
|
||||||
} else {
|
|
||||||
zed_log_msg(LOG_INFO, "zfs_deliver_dle: no guid or physpath");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zpool_iter(g_zfshdl, zfsdle_vdev_online, name) != 1) {
|
if (zpool_iter(g_zfshdl, zfsdle_vdev_online, devname) != 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", devname);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -892,12 +849,12 @@ zfs_enum_pools(void *arg)
|
|||||||
*
|
*
|
||||||
* sent messages from zevents or udev monitor
|
* sent messages from zevents or udev monitor
|
||||||
*
|
*
|
||||||
* For now, each agent has its own libzfs instance
|
* For now, each agent has it's own libzfs instance
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zfs_slm_init()
|
zfs_slm_init()
|
||||||
{
|
{
|
||||||
if ((g_zfshdl = libzfs_init()) == NULL)
|
if ((g_zfshdl = __libzfs_init()) == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -909,7 +866,7 @@ zfs_slm_init()
|
|||||||
|
|
||||||
if (pthread_create(&g_zfs_tid, NULL, zfs_enum_pools, NULL) != 0) {
|
if (pthread_create(&g_zfs_tid, NULL, zfs_enum_pools, NULL) != 0) {
|
||||||
list_destroy(&g_pool_list);
|
list_destroy(&g_pool_list);
|
||||||
libzfs_fini(g_zfshdl);
|
__libzfs_fini(g_zfshdl);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -927,15 +884,19 @@ zfs_slm_fini()
|
|||||||
|
|
||||||
/* wait for zfs_enum_pools thread to complete */
|
/* wait for zfs_enum_pools thread to complete */
|
||||||
(void) pthread_join(g_zfs_tid, NULL);
|
(void) pthread_join(g_zfs_tid, NULL);
|
||||||
/* destroy the thread pool */
|
|
||||||
if (g_tpool != NULL) {
|
|
||||||
tpool_wait(g_tpool);
|
|
||||||
tpool_destroy(g_tpool);
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((pool = (list_head(&g_pool_list))) != NULL) {
|
while ((pool = (list_head(&g_pool_list))) != NULL) {
|
||||||
|
/*
|
||||||
|
* each pool entry has two possibilities
|
||||||
|
* 1. was made available (so wait for zfs_enable_ds thread)
|
||||||
|
* 2. still unavailable (just close the pool)
|
||||||
|
*/
|
||||||
|
if (pool->uap_enable_tid)
|
||||||
|
(void) pthread_join(pool->uap_enable_tid, NULL);
|
||||||
|
else if (pool->uap_zhp != NULL)
|
||||||
|
zpool_close(pool->uap_zhp);
|
||||||
|
|
||||||
list_remove(&g_pool_list, pool);
|
list_remove(&g_pool_list, pool);
|
||||||
zpool_close(pool->uap_zhp);
|
|
||||||
free(pool);
|
free(pool);
|
||||||
}
|
}
|
||||||
list_destroy(&g_pool_list);
|
list_destroy(&g_pool_list);
|
||||||
@@ -946,7 +907,7 @@ zfs_slm_fini()
|
|||||||
}
|
}
|
||||||
list_destroy(&g_device_list);
|
list_destroy(&g_device_list);
|
||||||
|
|
||||||
libzfs_fini(g_zfshdl);
|
__libzfs_fini(g_zfshdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
+154
-66
@@ -22,7 +22,6 @@
|
|||||||
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016, Intel Corporation.
|
* Copyright (c) 2016, Intel Corporation.
|
||||||
* Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -72,6 +71,7 @@ zfs_retire_clear_data(fmd_hdl_t *hdl, zfs_retire_data_t *zdp)
|
|||||||
*/
|
*/
|
||||||
typedef struct find_cbdata {
|
typedef struct find_cbdata {
|
||||||
uint64_t cb_guid;
|
uint64_t cb_guid;
|
||||||
|
const char *cb_fru;
|
||||||
zpool_handle_t *cb_zhp;
|
zpool_handle_t *cb_zhp;
|
||||||
nvlist_t *cb_vdev;
|
nvlist_t *cb_vdev;
|
||||||
} find_cbdata_t;
|
} find_cbdata_t;
|
||||||
@@ -95,18 +95,26 @@ find_pool(zpool_handle_t *zhp, void *data)
|
|||||||
* Find a vdev within a tree with a matching GUID.
|
* Find a vdev within a tree with a matching GUID.
|
||||||
*/
|
*/
|
||||||
static nvlist_t *
|
static nvlist_t *
|
||||||
find_vdev(libzfs_handle_t *zhdl, nvlist_t *nv, uint64_t search_guid)
|
find_vdev(libzfs_handle_t *zhdl, nvlist_t *nv, const char *search_fru,
|
||||||
|
uint64_t search_guid)
|
||||||
{
|
{
|
||||||
uint64_t guid;
|
uint64_t guid;
|
||||||
nvlist_t **child;
|
nvlist_t **child;
|
||||||
uint_t c, children;
|
uint_t c, children;
|
||||||
nvlist_t *ret;
|
nvlist_t *ret;
|
||||||
|
char *fru;
|
||||||
|
|
||||||
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
|
if (search_fru != NULL) {
|
||||||
guid == search_guid) {
|
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_FRU, &fru) == 0 &&
|
||||||
fmd_hdl_debug(fmd_module_hdl("zfs-retire"),
|
libzfs_fru_compare(zhdl, fru, search_fru))
|
||||||
"matched vdev %llu", guid);
|
return (nv);
|
||||||
return (nv);
|
} else {
|
||||||
|
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
|
||||||
|
guid == search_guid) {
|
||||||
|
fmd_hdl_debug(fmd_module_hdl("zfs-retire"),
|
||||||
|
"matched vdev %llu", guid);
|
||||||
|
return (nv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
|
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
|
||||||
@@ -114,7 +122,8 @@ find_vdev(libzfs_handle_t *zhdl, nvlist_t *nv, uint64_t search_guid)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
for (c = 0; c < children; c++) {
|
for (c = 0; c < children; c++) {
|
||||||
if ((ret = find_vdev(zhdl, child[c], search_guid)) != NULL)
|
if ((ret = find_vdev(zhdl, child[c], search_fru,
|
||||||
|
search_guid)) != NULL)
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,16 +132,8 @@ find_vdev(libzfs_handle_t *zhdl, nvlist_t *nv, uint64_t search_guid)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
for (c = 0; c < children; c++) {
|
for (c = 0; c < children; c++) {
|
||||||
if ((ret = find_vdev(zhdl, child[c], search_guid)) != NULL)
|
if ((ret = find_vdev(zhdl, child[c], search_fru,
|
||||||
return (ret);
|
search_guid)) != NULL)
|
||||||
}
|
|
||||||
|
|
||||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
|
|
||||||
&child, &children) != 0)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
for (c = 0; c < children; c++) {
|
|
||||||
if ((ret = find_vdev(zhdl, child[c], search_guid)) != NULL)
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +167,8 @@ find_by_guid(libzfs_handle_t *zhdl, uint64_t pool_guid, uint64_t vdev_guid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vdev_guid != 0) {
|
if (vdev_guid != 0) {
|
||||||
if ((*vdevp = find_vdev(zhdl, nvroot, vdev_guid)) == NULL) {
|
if ((*vdevp = find_vdev(zhdl, nvroot, NULL,
|
||||||
|
vdev_guid)) == NULL) {
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@@ -175,37 +177,72 @@ find_by_guid(libzfs_handle_t *zhdl, uint64_t pool_guid, uint64_t vdev_guid,
|
|||||||
return (zhp);
|
return (zhp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBTOPO
|
||||||
|
static int
|
||||||
|
search_pool(zpool_handle_t *zhp, void *data)
|
||||||
|
{
|
||||||
|
find_cbdata_t *cbp = data;
|
||||||
|
nvlist_t *config;
|
||||||
|
nvlist_t *nvroot;
|
||||||
|
|
||||||
|
config = zpool_get_config(zhp, NULL);
|
||||||
|
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
||||||
|
&nvroot) != 0) {
|
||||||
|
zpool_close(zhp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cbp->cb_vdev = find_vdev(zpool_get_handle(zhp), nvroot,
|
||||||
|
cbp->cb_fru, 0)) != NULL) {
|
||||||
|
cbp->cb_zhp = zhp;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
zpool_close(zhp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given a FRU FMRI, find the matching pool and vdev.
|
||||||
|
*/
|
||||||
|
static zpool_handle_t *
|
||||||
|
find_by_fru(libzfs_handle_t *zhdl, const char *fru, nvlist_t **vdevp)
|
||||||
|
{
|
||||||
|
find_cbdata_t cb;
|
||||||
|
|
||||||
|
cb.cb_fru = fru;
|
||||||
|
cb.cb_zhp = NULL;
|
||||||
|
if (zpool_iter(zhdl, search_pool, &cb) != 1)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
*vdevp = cb.cb_vdev;
|
||||||
|
return (cb.cb_zhp);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_LIBTOPO */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a vdev, attempt to replace it with every known spare until one
|
* Given a vdev, attempt to replace it with every known spare until one
|
||||||
* succeeds or we run out of devices to try.
|
* succeeds.
|
||||||
* Return whether we were successful or not in replacing the device.
|
|
||||||
*/
|
*/
|
||||||
static boolean_t
|
static void
|
||||||
replace_with_spare(fmd_hdl_t *hdl, zpool_handle_t *zhp, nvlist_t *vdev)
|
replace_with_spare(fmd_hdl_t *hdl, zpool_handle_t *zhp, nvlist_t *vdev)
|
||||||
{
|
{
|
||||||
nvlist_t *config, *nvroot, *replacement;
|
nvlist_t *config, *nvroot, *replacement;
|
||||||
nvlist_t **spares;
|
nvlist_t **spares;
|
||||||
uint_t s, nspares;
|
uint_t s, nspares;
|
||||||
char *dev_name;
|
char *dev_name;
|
||||||
zprop_source_t source;
|
|
||||||
int ashift;
|
|
||||||
|
|
||||||
config = zpool_get_config(zhp, NULL);
|
config = zpool_get_config(zhp, NULL);
|
||||||
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
||||||
&nvroot) != 0)
|
&nvroot) != 0)
|
||||||
return (B_FALSE);
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find out if there are any hot spares available in the pool.
|
* Find out if there are any hot spares available in the pool.
|
||||||
*/
|
*/
|
||||||
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
|
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
|
||||||
&spares, &nspares) != 0)
|
&spares, &nspares) != 0)
|
||||||
return (B_FALSE);
|
return;
|
||||||
|
|
||||||
/*
|
|
||||||
* lookup "ashift" pool property, we may need it for the replacement
|
|
||||||
*/
|
|
||||||
ashift = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &source);
|
|
||||||
|
|
||||||
replacement = fmd_nvl_alloc(hdl, FMD_SLEEP);
|
replacement = fmd_nvl_alloc(hdl, FMD_SLEEP);
|
||||||
|
|
||||||
@@ -225,11 +262,6 @@ replace_with_spare(fmd_hdl_t *hdl, zpool_handle_t *zhp, nvlist_t *vdev)
|
|||||||
&spare_name) != 0)
|
&spare_name) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* if set, add the "ashift" pool property to the spare nvlist */
|
|
||||||
if (source != ZPROP_SRC_DEFAULT)
|
|
||||||
(void) nvlist_add_uint64(spares[s],
|
|
||||||
ZPOOL_CONFIG_ASHIFT, ashift);
|
|
||||||
|
|
||||||
(void) nvlist_add_nvlist_array(replacement,
|
(void) nvlist_add_nvlist_array(replacement,
|
||||||
ZPOOL_CONFIG_CHILDREN, &spares[s], 1);
|
ZPOOL_CONFIG_CHILDREN, &spares[s], 1);
|
||||||
|
|
||||||
@@ -237,17 +269,12 @@ replace_with_spare(fmd_hdl_t *hdl, zpool_handle_t *zhp, nvlist_t *vdev)
|
|||||||
dev_name, 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) == 0) {
|
replacement, B_TRUE) == 0)
|
||||||
free(dev_name);
|
break;
|
||||||
nvlist_free(replacement);
|
|
||||||
return (B_TRUE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(dev_name);
|
free(dev_name);
|
||||||
nvlist_free(replacement);
|
nvlist_free(replacement);
|
||||||
|
|
||||||
return (B_FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -262,6 +289,10 @@ zfs_vdev_repair(fmd_hdl_t *hdl, nvlist_t *nvl)
|
|||||||
zfs_retire_data_t *zdp = fmd_hdl_getspecific(hdl);
|
zfs_retire_data_t *zdp = fmd_hdl_getspecific(hdl);
|
||||||
zfs_retire_repaired_t *zrp;
|
zfs_retire_repaired_t *zrp;
|
||||||
uint64_t pool_guid, vdev_guid;
|
uint64_t pool_guid, vdev_guid;
|
||||||
|
#ifdef HAVE_LIBTOPO
|
||||||
|
nvlist_t *asru;
|
||||||
|
#endif
|
||||||
|
|
||||||
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 || nvlist_lookup_uint64(nvl,
|
&pool_guid) != 0 || nvlist_lookup_uint64(nvl,
|
||||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID, &vdev_guid) != 0)
|
FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID, &vdev_guid) != 0)
|
||||||
@@ -284,6 +315,47 @@ zfs_vdev_repair(fmd_hdl_t *hdl, nvlist_t *nvl)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBTOPO
|
||||||
|
asru = fmd_nvl_alloc(hdl, FMD_SLEEP);
|
||||||
|
|
||||||
|
(void) nvlist_add_uint8(asru, FM_VERSION, ZFS_SCHEME_VERSION0);
|
||||||
|
(void) nvlist_add_string(asru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_ZFS);
|
||||||
|
(void) nvlist_add_uint64(asru, FM_FMRI_ZFS_POOL, pool_guid);
|
||||||
|
(void) nvlist_add_uint64(asru, FM_FMRI_ZFS_VDEV, vdev_guid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We explicitly check for the unusable state here to make sure we
|
||||||
|
* aren't responding to a transient state change. As part of opening a
|
||||||
|
* vdev, it's possible to see the 'statechange' event, only to be
|
||||||
|
* followed by a vdev failure later. If we don't check the current
|
||||||
|
* state of the vdev (or pool) before marking it repaired, then we risk
|
||||||
|
* generating spurious repair events followed immediately by the same
|
||||||
|
* diagnosis.
|
||||||
|
*
|
||||||
|
* This assumes that the ZFS scheme code associated unusable (i.e.
|
||||||
|
* isolated) with its own definition of faulty state. In the case of a
|
||||||
|
* DEGRADED leaf vdev (due to checksum errors), this is not the case.
|
||||||
|
* This works, however, because the transient state change is not
|
||||||
|
* posted in this case. This could be made more explicit by not
|
||||||
|
* relying on the scheme's unusable callback and instead directly
|
||||||
|
* checking the vdev state, where we could correctly account for
|
||||||
|
* DEGRADED state.
|
||||||
|
*/
|
||||||
|
if (!fmd_nvl_fmri_unusable(hdl, asru) && fmd_nvl_fmri_has_fault(hdl,
|
||||||
|
asru, FMD_HAS_FAULT_ASRU, NULL)) {
|
||||||
|
topo_hdl_t *thp;
|
||||||
|
char *fmri = NULL;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION);
|
||||||
|
if (topo_fmri_nvl2str(thp, asru, &fmri, &err) == 0)
|
||||||
|
(void) fmd_repair_asru(hdl, fmri);
|
||||||
|
fmd_hdl_topo_rele(hdl, thp);
|
||||||
|
|
||||||
|
topo_hdl_strfree(thp, fmri);
|
||||||
|
}
|
||||||
|
nvlist_free(asru);
|
||||||
|
#endif
|
||||||
zrp = fmd_hdl_alloc(hdl, sizeof (zfs_retire_repaired_t), FMD_SLEEP);
|
zrp = fmd_hdl_alloc(hdl, sizeof (zfs_retire_repaired_t), FMD_SLEEP);
|
||||||
zrp->zrr_next = zdp->zrd_repaired;
|
zrp->zrr_next = zdp->zrd_repaired;
|
||||||
zrp->zrr_pool = pool_guid;
|
zrp->zrr_pool = pool_guid;
|
||||||
@@ -320,14 +392,10 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
|||||||
fmd_hdl_debug(hdl, "zfs_retire_recv: '%s'", class);
|
fmd_hdl_debug(hdl, "zfs_retire_recv: '%s'", class);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is a resource notifying us of device removal then simply
|
* If this is a resource notifying us of device removal, then simply
|
||||||
* check for an available spare and continue unless the device is a
|
* check for an available spare and continue.
|
||||||
* l2arc vdev, in which case we just offline it.
|
|
||||||
*/
|
*/
|
||||||
if (strcmp(class, "resource.fs.zfs.removed") == 0) {
|
if (strcmp(class, "resource.fs.zfs.removed") == 0) {
|
||||||
char *devtype;
|
|
||||||
char *devname;
|
|
||||||
|
|
||||||
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,
|
nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID,
|
||||||
@@ -338,20 +406,8 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
|||||||
&vdev)) == NULL)
|
&vdev)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
devname = zpool_vdev_name(NULL, zhp, vdev, B_FALSE);
|
if (fmd_prop_get_int32(hdl, "spare_on_remove"))
|
||||||
|
replace_with_spare(hdl, zhp, vdev);
|
||||||
/* Can't replace l2arc with a spare: offline the device */
|
|
||||||
if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE,
|
|
||||||
&devtype) == 0 && strcmp(devtype, VDEV_TYPE_L2CACHE) == 0) {
|
|
||||||
fmd_hdl_debug(hdl, "zpool_vdev_offline '%s'", devname);
|
|
||||||
zpool_vdev_offline(zhp, devname, B_TRUE);
|
|
||||||
} else if (!fmd_prop_get_int32(hdl, "spare_on_remove") ||
|
|
||||||
replace_with_spare(hdl, zhp, vdev) == B_FALSE) {
|
|
||||||
/* Could not handle with spare */
|
|
||||||
fmd_hdl_debug(hdl, "no spare for '%s'", devname);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(devname);
|
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -421,7 +477,39 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_disk) {
|
if (is_disk) {
|
||||||
|
#ifdef HAVE_LIBTOPO
|
||||||
|
/*
|
||||||
|
* This is a disk fault. Lookup the FRU, convert it to
|
||||||
|
* an FMRI string, and attempt to find a matching vdev.
|
||||||
|
*/
|
||||||
|
if (nvlist_lookup_nvlist(fault, FM_FAULT_FRU,
|
||||||
|
&fru) != 0 ||
|
||||||
|
nvlist_lookup_string(fru, FM_FMRI_SCHEME,
|
||||||
|
&scheme) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(scheme, FM_FMRI_SCHEME_HC) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION);
|
||||||
|
if (topo_fmri_nvl2str(thp, fru, &fmri, &err) != 0) {
|
||||||
|
fmd_hdl_topo_rele(hdl, thp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
zhp = find_by_fru(zhdl, fmri, &vdev);
|
||||||
|
topo_hdl_strfree(thp, fmri);
|
||||||
|
fmd_hdl_topo_rele(hdl, thp);
|
||||||
|
|
||||||
|
if (zhp == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
(void) nvlist_lookup_uint64(vdev,
|
||||||
|
ZPOOL_CONFIG_GUID, &vdev_guid);
|
||||||
|
aux = VDEV_AUX_EXTERNAL;
|
||||||
|
#else
|
||||||
continue;
|
continue;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* This is a ZFS fault. Lookup the resource, and
|
* This is a ZFS fault. Lookup the resource, and
|
||||||
@@ -495,7 +583,7 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
|||||||
/*
|
/*
|
||||||
* Attempt to substitute a hot spare.
|
* Attempt to substitute a hot spare.
|
||||||
*/
|
*/
|
||||||
(void) replace_with_spare(hdl, zhp, vdev);
|
replace_with_spare(hdl, zhp, vdev);
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,7 +615,7 @@ _zfs_retire_init(fmd_hdl_t *hdl)
|
|||||||
zfs_retire_data_t *zdp;
|
zfs_retire_data_t *zdp;
|
||||||
libzfs_handle_t *zhdl;
|
libzfs_handle_t *zhdl;
|
||||||
|
|
||||||
if ((zhdl = libzfs_init()) == NULL)
|
if ((zhdl = __libzfs_init()) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0) {
|
if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0) {
|
||||||
@@ -548,7 +636,7 @@ _zfs_retire_fini(fmd_hdl_t *hdl)
|
|||||||
|
|
||||||
if (zdp != NULL) {
|
if (zdp != NULL) {
|
||||||
zfs_retire_clear_data(hdl, zdp);
|
zfs_retire_clear_data(hdl, zdp);
|
||||||
libzfs_fini(zdp->zrd_hdl);
|
__libzfs_fini(zdp->zrd_hdl);
|
||||||
fmd_hdl_free(hdl, zdp, sizeof (zfs_retire_data_t));
|
fmd_hdl_free(hdl, zdp, sizeof (zfs_retire_data_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
history_event-zfs-list-cacher.sh
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
include $(top_srcdir)/config/Rules.am
|
|
||||||
|
|
||||||
EXTRA_DIST = \
|
|
||||||
README \
|
|
||||||
history_event-zfs-list-cacher.sh.in
|
|
||||||
|
|
||||||
zedconfdir = $(sysconfdir)/zfs/zed.d
|
|
||||||
|
|
||||||
dist_zedconf_DATA = \
|
|
||||||
zed-functions.sh \
|
|
||||||
zed.rc
|
|
||||||
|
|
||||||
zedexecdir = $(zfsexecdir)/zed.d
|
|
||||||
|
|
||||||
dist_zedexec_SCRIPTS = \
|
|
||||||
all-debug.sh \
|
|
||||||
all-syslog.sh \
|
|
||||||
data-notify.sh \
|
|
||||||
generic-notify.sh \
|
|
||||||
resilver_finish-notify.sh \
|
|
||||||
scrub_finish-notify.sh \
|
|
||||||
statechange-led.sh \
|
|
||||||
statechange-notify.sh \
|
|
||||||
vdev_clear-led.sh \
|
|
||||||
vdev_attach-led.sh \
|
|
||||||
pool_import-led.sh \
|
|
||||||
resilver_finish-start-scrub.sh
|
|
||||||
|
|
||||||
nodist_zedexec_SCRIPTS = history_event-zfs-list-cacher.sh
|
|
||||||
|
|
||||||
$(nodist_zedexec_SCRIPTS): %: %.in
|
|
||||||
-$(SED) -e 's,@bindir\@,$(bindir),g' \
|
|
||||||
-e 's,@runstatedir\@,$(runstatedir),g' \
|
|
||||||
-e 's,@sbindir\@,$(sbindir),g' \
|
|
||||||
-e 's,@sysconfdir\@,$(sysconfdir),g' \
|
|
||||||
$< >'$@'
|
|
||||||
|
|
||||||
zedconfdefaults = \
|
|
||||||
all-syslog.sh \
|
|
||||||
data-notify.sh \
|
|
||||||
resilver_finish-notify.sh \
|
|
||||||
scrub_finish-notify.sh \
|
|
||||||
statechange-led.sh \
|
|
||||||
statechange-notify.sh \
|
|
||||||
vdev_clear-led.sh \
|
|
||||||
vdev_attach-led.sh \
|
|
||||||
pool_import-led.sh \
|
|
||||||
resilver_finish-start-scrub.sh
|
|
||||||
|
|
||||||
install-data-hook:
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(zedconfdir)"
|
|
||||||
for f in $(zedconfdefaults); do \
|
|
||||||
test -f "$(DESTDIR)$(zedconfdir)/$${f}" -o \
|
|
||||||
-L "$(DESTDIR)$(zedconfdir)/$${f}" || \
|
|
||||||
ln -s "$(zedexecdir)/$${f}" "$(DESTDIR)$(zedconfdir)"; \
|
|
||||||
done
|
|
||||||
chmod 0600 "$(DESTDIR)$(zedconfdir)/zed.rc"
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# Track changes to enumerated pools for use in early-boot
|
|
||||||
set -ef
|
|
||||||
|
|
||||||
FSLIST_DIR="@sysconfdir@/zfs/zfs-list.cache"
|
|
||||||
FSLIST_TMP="@runstatedir@/zfs-list.cache.new"
|
|
||||||
FSLIST="${FSLIST_DIR}/${ZEVENT_POOL}"
|
|
||||||
|
|
||||||
# If the pool specific cache file is not writeable, abort
|
|
||||||
[ -w "${FSLIST}" ] || exit 0
|
|
||||||
|
|
||||||
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
|
|
||||||
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
|
|
||||||
|
|
||||||
zed_exit_if_ignoring_this_event
|
|
||||||
zed_check_cmd "${ZFS}" sort diff grep
|
|
||||||
|
|
||||||
# If we are acting on a snapshot, we have nothing to do
|
|
||||||
printf '%s' "${ZEVENT_HISTORY_DSNAME}" | grep '@' && exit 0
|
|
||||||
|
|
||||||
# We obtain a lock on zfs-list to avoid any simultaneous writes.
|
|
||||||
# If we run into trouble, log and drop the lock
|
|
||||||
abort_alter() {
|
|
||||||
zed_log_msg "Error updating zfs-list.cache!"
|
|
||||||
zed_unlock zfs-list
|
|
||||||
}
|
|
||||||
|
|
||||||
finished() {
|
|
||||||
zed_unlock zfs-list
|
|
||||||
trap - EXIT
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
case "${ZEVENT_HISTORY_INTERNAL_NAME}" in
|
|
||||||
create|"finish receiving"|import|destroy|rename)
|
|
||||||
;;
|
|
||||||
|
|
||||||
export)
|
|
||||||
zed_lock zfs-list
|
|
||||||
trap abort_alter EXIT
|
|
||||||
echo > "${FSLIST}"
|
|
||||||
finished
|
|
||||||
;;
|
|
||||||
|
|
||||||
set|inherit)
|
|
||||||
# Only act if one of the tracked properties is altered.
|
|
||||||
case "${ZEVENT_HISTORY_INTERNAL_STR%%=*}" in
|
|
||||||
canmount|mountpoint|atime|relatime|devices|exec|readonly| \
|
|
||||||
setuid|nbmand|encroot|keylocation|org.openzfs.systemd:requires| \
|
|
||||||
org.openzfs.systemd:requires-mounts-for| \
|
|
||||||
org.openzfs.systemd:before|org.openzfs.systemd:after| \
|
|
||||||
org.openzfs.systemd:wanted-by|org.openzfs.systemd:required-by| \
|
|
||||||
org.openzfs.systemd:nofail|org.openzfs.systemd:ignore \
|
|
||||||
) ;;
|
|
||||||
*) exit 0 ;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
# Ignore all other events.
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
zed_lock zfs-list
|
|
||||||
trap abort_alter EXIT
|
|
||||||
|
|
||||||
PROPS="name,mountpoint,canmount,atime,relatime,devices,exec\
|
|
||||||
,readonly,setuid,nbmand,encroot,keylocation\
|
|
||||||
,org.openzfs.systemd:requires,org.openzfs.systemd:requires-mounts-for\
|
|
||||||
,org.openzfs.systemd:before,org.openzfs.systemd:after\
|
|
||||||
,org.openzfs.systemd:wanted-by,org.openzfs.systemd:required-by\
|
|
||||||
,org.openzfs.systemd:nofail,org.openzfs.systemd:ignore"
|
|
||||||
|
|
||||||
"${ZFS}" list -H -t filesystem -o $PROPS -r "${ZEVENT_POOL}" > "${FSLIST_TMP}"
|
|
||||||
|
|
||||||
# Sort the output so that it is stable
|
|
||||||
sort "${FSLIST_TMP}" -o "${FSLIST_TMP}"
|
|
||||||
|
|
||||||
# Don't modify the file if it hasn't changed
|
|
||||||
diff -q "${FSLIST_TMP}" "${FSLIST}" || mv "${FSLIST_TMP}" "${FSLIST}"
|
|
||||||
rm -f "${FSLIST_TMP}"
|
|
||||||
|
|
||||||
finished
|
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
#
|
#
|
||||||
# Exit codes:
|
# Exit codes:
|
||||||
# 0: enclosure led successfully set
|
# 0: enclosure led successfully set
|
||||||
# 1: enclosure leds not available
|
# 1: enclosure leds not not available
|
||||||
# 2: enclosure leds administratively disabled
|
# 2: enclosure leds administratively disabled
|
||||||
# 3: The led sysfs path passed from ZFS does not exist
|
# 3: The led sysfs path passed from ZFS does not exist
|
||||||
# 4: $ZPOOL not set
|
# 4: $ZPOOL not set
|
||||||
@@ -68,7 +68,7 @@ check_and_set_led()
|
|||||||
# timeout.
|
# timeout.
|
||||||
for _ in $(seq 1 5); do
|
for _ in $(seq 1 5); do
|
||||||
# We want to check the current state first, since writing to the
|
# We want to check the current state first, since writing to the
|
||||||
# 'fault' entry always causes a SES command, even if the
|
# 'fault' entry always always causes a SES command, even if the
|
||||||
# current state is already what you want.
|
# current state is already what you want.
|
||||||
current=$(cat "${file}")
|
current=$(cat "${file}")
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ process_pool()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ -n "$ZEVENT_VDEV_ENC_SYSFS_PATH" ] && [ -n "$ZEVENT_VDEV_STATE_STR" ] ; then
|
if [ ! -z "$ZEVENT_VDEV_ENC_SYSFS_PATH" ] && [ ! -z "$ZEVENT_VDEV_STATE_STR" ] ; then
|
||||||
# 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")
|
||||||
|
|||||||
@@ -434,7 +434,7 @@ zed_guid_to_pool()
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
guid=$(printf "%llu" "$1")
|
guid=$(printf "%llu" "$1")
|
||||||
if [ -n "$guid" ] ; then
|
if [ ! -z "$guid" ] ; then
|
||||||
$ZPOOL get -H -ovalue,name guid | awk '$1=='"$guid"' {print $2}'
|
$ZPOOL get -H -ovalue,name guid | awk '$1=='"$guid"' {print $2}'
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,9 +52,9 @@
|
|||||||
|
|
||||||
##
|
##
|
||||||
# Send notifications for 'ereport.fs.zfs.data' events.
|
# Send notifications for 'ereport.fs.zfs.data' events.
|
||||||
# Disabled by default, any non-empty value will enable the feature.
|
# Disabled by default
|
||||||
#
|
#
|
||||||
#ZED_NOTIFY_DATA=
|
#ZED_NOTIFY_DATA=1
|
||||||
|
|
||||||
##
|
##
|
||||||
# Pushbullet access token.
|
# Pushbullet access token.
|
||||||
@@ -88,8 +88,7 @@ ZED_USE_ENCLOSURE_LEDS=1
|
|||||||
|
|
||||||
##
|
##
|
||||||
# Run a scrub after every resilver
|
# Run a scrub after every resilver
|
||||||
# Disabled by default, 1 to enable and 0 to disable.
|
#ZED_SCRUB_AFTER_RESILVER=1
|
||||||
#ZED_SCRUB_AFTER_RESILVER=0
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# The syslog priority (e.g., specified as a "facility.level" pair).
|
# The syslog priority (e.g., specified as a "facility.level" pair).
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
#include <libnvpair.h>
|
#include <libnvpair.h>
|
||||||
#include <libudev.h>
|
#include <libudev.h>
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
#include <libzutil.h>
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -38,7 +37,7 @@
|
|||||||
* A libudev monitor is established to monitor block device actions and pass
|
* A libudev monitor is established to monitor block device actions and pass
|
||||||
* them on to internal ZED logic modules. Initially, zfs_mod.c is the only
|
* them on to internal ZED logic modules. Initially, zfs_mod.c is the only
|
||||||
* consumer and is the Linux equivalent for the illumos syseventd ZFS SLM
|
* consumer and is the Linux equivalent for the illumos syseventd ZFS SLM
|
||||||
* module responsible for handling disk events for ZFS.
|
* module responsible for handeling disk events for ZFS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pthread_t g_mon_tid;
|
pthread_t g_mon_tid;
|
||||||
|
|||||||
+4
-3
@@ -10,12 +10,13 @@ zfs_SOURCES = \
|
|||||||
zfs_iter.c \
|
zfs_iter.c \
|
||||||
zfs_iter.h \
|
zfs_iter.h \
|
||||||
zfs_main.c \
|
zfs_main.c \
|
||||||
zfs_util.h \
|
zfs_util.h
|
||||||
zfs_project.c \
|
|
||||||
zfs_projectutil.h
|
|
||||||
|
|
||||||
zfs_LDADD = \
|
zfs_LDADD = \
|
||||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
$(top_builddir)/lib/libuutil/libuutil.la \
|
$(top_builddir)/lib/libuutil/libuutil.la \
|
||||||
|
$(top_builddir)/lib/libzpool/libzpool.la \
|
||||||
$(top_builddir)/lib/libzfs/libzfs.la \
|
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||||
$(top_builddir)/lib/libzfs_core/libzfs_core.la
|
$(top_builddir)/lib/libzfs_core/libzfs_core.la
|
||||||
|
|
||||||
|
zfs_LDFLAGS = -pthread
|
||||||
|
|||||||
+6
-22
@@ -31,7 +31,6 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
@@ -134,31 +133,16 @@ zfs_callback(zfs_handle_t *zhp, void *data)
|
|||||||
((cb->cb_flags & ZFS_ITER_DEPTH_LIMIT) == 0 ||
|
((cb->cb_flags & ZFS_ITER_DEPTH_LIMIT) == 0 ||
|
||||||
cb->cb_depth < cb->cb_depth_limit)) {
|
cb->cb_depth < cb->cb_depth_limit)) {
|
||||||
cb->cb_depth++;
|
cb->cb_depth++;
|
||||||
|
if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
|
||||||
/*
|
|
||||||
* If we are not looking for filesystems, we don't need to
|
|
||||||
* recurse into filesystems when we are at our depth limit.
|
|
||||||
*/
|
|
||||||
if ((cb->cb_depth < cb->cb_depth_limit ||
|
|
||||||
(cb->cb_flags & ZFS_ITER_DEPTH_LIMIT) == 0 ||
|
|
||||||
(cb->cb_types &
|
|
||||||
(ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME))) &&
|
|
||||||
zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
|
|
||||||
(void) zfs_iter_filesystems(zhp, zfs_callback, data);
|
(void) zfs_iter_filesystems(zhp, 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(zhp,
|
(void) zfs_iter_snapshots(zhp,
|
||||||
(cb->cb_flags & ZFS_ITER_SIMPLE) != 0,
|
(cb->cb_flags & ZFS_ITER_SIMPLE) != 0, zfs_callback,
|
||||||
zfs_callback, data, 0, 0);
|
data);
|
||||||
}
|
|
||||||
|
|
||||||
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(zhp, zfs_callback, data);
|
(void) zfs_iter_bookmarks(zhp, zfs_callback, data);
|
||||||
}
|
|
||||||
|
|
||||||
cb->cb_depth--;
|
cb->cb_depth--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +224,7 @@ zfs_compare(const void *larg, const void *rarg, void *unused)
|
|||||||
*rat = '\0';
|
*rat = '\0';
|
||||||
|
|
||||||
ret = strcmp(lname, rname);
|
ret = strcmp(lname, rname);
|
||||||
if (ret == 0 && (lat != NULL || rat != NULL)) {
|
if (ret == 0) {
|
||||||
/*
|
/*
|
||||||
* If we're comparing a dataset to one of its snapshots, we
|
* If we're comparing a dataset to one of its snapshots, we
|
||||||
* always make the full dataset first.
|
* always make the full dataset first.
|
||||||
|
|||||||
+163
-1258
File diff suppressed because it is too large
Load Diff
@@ -1,295 +0,0 @@
|
|||||||
/*
|
|
||||||
* CDDL HEADER START
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the terms of the
|
|
||||||
* Common Development and Distribution License (the "License").
|
|
||||||
* You may not use this file except in compliance with the License.
|
|
||||||
*
|
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
||||||
* or http://www.opensolaris.org/os/licensing.
|
|
||||||
* See the License for the specific language governing permissions
|
|
||||||
* and limitations under the License.
|
|
||||||
*
|
|
||||||
* When distributing Covered Code, include this CDDL HEADER in each
|
|
||||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
||||||
* If applicable, add the following below this CDDL HEADER, with the
|
|
||||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
||||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
||||||
*
|
|
||||||
* CDDL HEADER END
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2017, Intle Corporation. All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <strings.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <libintl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/list.h>
|
|
||||||
#include <sys/zfs_project.h>
|
|
||||||
|
|
||||||
#include "zfs_util.h"
|
|
||||||
#include "zfs_projectutil.h"
|
|
||||||
|
|
||||||
typedef struct zfs_project_item {
|
|
||||||
list_node_t zpi_list;
|
|
||||||
char zpi_name[0];
|
|
||||||
} zfs_project_item_t;
|
|
||||||
|
|
||||||
static void
|
|
||||||
zfs_project_item_alloc(list_t *head, const char *name)
|
|
||||||
{
|
|
||||||
zfs_project_item_t *zpi;
|
|
||||||
|
|
||||||
zpi = safe_malloc(sizeof (zfs_project_item_t) + strlen(name) + 1);
|
|
||||||
strcpy(zpi->zpi_name, name);
|
|
||||||
list_insert_tail(head, zpi);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
zfs_project_sanity_check(const char *name, zfs_project_control_t *zpc,
|
|
||||||
struct stat *st)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = stat(name, st);
|
|
||||||
if (ret) {
|
|
||||||
(void) fprintf(stderr, gettext("failed to stat %s: %s\n"),
|
|
||||||
name, strerror(errno));
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!S_ISREG(st->st_mode) && !S_ISDIR(st->st_mode)) {
|
|
||||||
(void) fprintf(stderr, gettext("only support project quota on "
|
|
||||||
"regular file or directory\n"));
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!S_ISDIR(st->st_mode)) {
|
|
||||||
if (zpc->zpc_dironly) {
|
|
||||||
(void) fprintf(stderr, gettext(
|
|
||||||
"'-d' option on non-dir target %s\n"), name);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zpc->zpc_recursive) {
|
|
||||||
(void) fprintf(stderr, gettext(
|
|
||||||
"'-r' option on non-dir target %s\n"), name);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
zfs_project_load_projid(const char *name, zfs_project_control_t *zpc)
|
|
||||||
{
|
|
||||||
zfsxattr_t fsx;
|
|
||||||
int ret, fd;
|
|
||||||
|
|
||||||
fd = open(name, O_RDONLY | O_NOCTTY);
|
|
||||||
if (fd < 0) {
|
|
||||||
(void) fprintf(stderr, gettext("failed to open %s: %s\n"),
|
|
||||||
name, strerror(errno));
|
|
||||||
return (fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ioctl(fd, ZFS_IOC_FSGETXATTR, &fsx);
|
|
||||||
if (ret)
|
|
||||||
(void) fprintf(stderr,
|
|
||||||
gettext("failed to get xattr for %s: %s\n"),
|
|
||||||
name, strerror(errno));
|
|
||||||
else
|
|
||||||
zpc->zpc_expected_projid = fsx.fsx_projid;
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
zfs_project_handle_one(const char *name, zfs_project_control_t *zpc)
|
|
||||||
{
|
|
||||||
zfsxattr_t fsx;
|
|
||||||
int ret, fd;
|
|
||||||
|
|
||||||
fd = open(name, O_RDONLY | O_NOCTTY);
|
|
||||||
if (fd < 0) {
|
|
||||||
if (errno == ENOENT && zpc->zpc_ignore_noent)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
(void) fprintf(stderr, gettext("failed to open %s: %s\n"),
|
|
||||||
name, strerror(errno));
|
|
||||||
return (fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ioctl(fd, ZFS_IOC_FSGETXATTR, &fsx);
|
|
||||||
if (ret) {
|
|
||||||
(void) fprintf(stderr,
|
|
||||||
gettext("failed to get xattr for %s: %s\n"),
|
|
||||||
name, strerror(errno));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (zpc->zpc_op) {
|
|
||||||
case ZFS_PROJECT_OP_LIST:
|
|
||||||
(void) printf("%5u %c %s\n", fsx.fsx_projid,
|
|
||||||
(fsx.fsx_xflags & ZFS_PROJINHERIT_FL) ? 'P' : '-', name);
|
|
||||||
goto out;
|
|
||||||
case ZFS_PROJECT_OP_CHECK:
|
|
||||||
if (fsx.fsx_projid == zpc->zpc_expected_projid &&
|
|
||||||
fsx.fsx_xflags & ZFS_PROJINHERIT_FL)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!zpc->zpc_newline) {
|
|
||||||
char c = '\0';
|
|
||||||
|
|
||||||
(void) printf("%s%c", name, c);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fsx.fsx_projid != zpc->zpc_expected_projid)
|
|
||||||
(void) printf("%s - project ID is not set properly "
|
|
||||||
"(%u/%u)\n", name, fsx.fsx_projid,
|
|
||||||
(uint32_t)zpc->zpc_expected_projid);
|
|
||||||
|
|
||||||
if (!(fsx.fsx_xflags & ZFS_PROJINHERIT_FL))
|
|
||||||
(void) printf("%s - project inherit flag is not set\n",
|
|
||||||
name);
|
|
||||||
|
|
||||||
goto out;
|
|
||||||
case ZFS_PROJECT_OP_CLEAR:
|
|
||||||
if (!(fsx.fsx_xflags & ZFS_PROJINHERIT_FL) &&
|
|
||||||
(zpc->zpc_keep_projid ||
|
|
||||||
fsx.fsx_projid == ZFS_DEFAULT_PROJID))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
fsx.fsx_xflags &= ~ZFS_PROJINHERIT_FL;
|
|
||||||
if (!zpc->zpc_keep_projid)
|
|
||||||
fsx.fsx_projid = ZFS_DEFAULT_PROJID;
|
|
||||||
break;
|
|
||||||
case ZFS_PROJECT_OP_SET:
|
|
||||||
if (fsx.fsx_projid == zpc->zpc_expected_projid &&
|
|
||||||
(!zpc->zpc_set_flag || fsx.fsx_xflags & ZFS_PROJINHERIT_FL))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
fsx.fsx_projid = zpc->zpc_expected_projid;
|
|
||||||
if (zpc->zpc_set_flag)
|
|
||||||
fsx.fsx_xflags |= ZFS_PROJINHERIT_FL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ioctl(fd, ZFS_IOC_FSSETXATTR, &fsx);
|
|
||||||
if (ret)
|
|
||||||
(void) fprintf(stderr,
|
|
||||||
gettext("failed to set xattr for %s: %s\n"),
|
|
||||||
name, strerror(errno));
|
|
||||||
|
|
||||||
out:
|
|
||||||
close(fd);
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
zfs_project_handle_dir(const char *name, zfs_project_control_t *zpc,
|
|
||||||
list_t *head)
|
|
||||||
{
|
|
||||||
char fullname[PATH_MAX];
|
|
||||||
struct dirent *ent;
|
|
||||||
DIR *dir;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
dir = opendir(name);
|
|
||||||
if (dir == NULL) {
|
|
||||||
if (errno == ENOENT && zpc->zpc_ignore_noent)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
ret = -errno;
|
|
||||||
(void) fprintf(stderr, gettext("failed to opendir %s: %s\n"),
|
|
||||||
name, strerror(errno));
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Non-top item, ignore the case of being removed or renamed by race. */
|
|
||||||
zpc->zpc_ignore_noent = B_TRUE;
|
|
||||||
errno = 0;
|
|
||||||
while (!ret && (ent = readdir(dir)) != NULL) {
|
|
||||||
/* skip "." and ".." */
|
|
||||||
if (strcmp(ent->d_name, ".") == 0 ||
|
|
||||||
strcmp(ent->d_name, "..") == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (strlen(ent->d_name) + strlen(name) >=
|
|
||||||
sizeof (fullname) + 1) {
|
|
||||||
errno = ENAMETOOLONG;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(fullname, "%s/%s", name, ent->d_name);
|
|
||||||
ret = zfs_project_handle_one(fullname, zpc);
|
|
||||||
if (!ret && zpc->zpc_recursive && ent->d_type == DT_DIR)
|
|
||||||
zfs_project_item_alloc(head, fullname);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errno && !ret) {
|
|
||||||
ret = -errno;
|
|
||||||
(void) fprintf(stderr, gettext("failed to readdir %s: %s\n"),
|
|
||||||
name, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
zfs_project_handle(const char *name, zfs_project_control_t *zpc)
|
|
||||||
{
|
|
||||||
zfs_project_item_t *zpi;
|
|
||||||
struct stat st;
|
|
||||||
list_t head;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = zfs_project_sanity_check(name, zpc, &st);
|
|
||||||
if (ret)
|
|
||||||
return (ret);
|
|
||||||
|
|
||||||
if ((zpc->zpc_op == ZFS_PROJECT_OP_SET ||
|
|
||||||
zpc->zpc_op == ZFS_PROJECT_OP_CHECK) &&
|
|
||||||
zpc->zpc_expected_projid == ZFS_INVALID_PROJID) {
|
|
||||||
ret = zfs_project_load_projid(name, zpc);
|
|
||||||
if (ret)
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
zpc->zpc_ignore_noent = B_FALSE;
|
|
||||||
ret = zfs_project_handle_one(name, zpc);
|
|
||||||
if (ret || !S_ISDIR(st.st_mode) || zpc->zpc_dironly ||
|
|
||||||
(!zpc->zpc_recursive &&
|
|
||||||
zpc->zpc_op != ZFS_PROJECT_OP_LIST &&
|
|
||||||
zpc->zpc_op != ZFS_PROJECT_OP_CHECK))
|
|
||||||
return (ret);
|
|
||||||
|
|
||||||
list_create(&head, sizeof (zfs_project_item_t),
|
|
||||||
offsetof(zfs_project_item_t, zpi_list));
|
|
||||||
zfs_project_item_alloc(&head, name);
|
|
||||||
while ((zpi = list_remove_head(&head)) != NULL) {
|
|
||||||
if (!ret)
|
|
||||||
ret = zfs_project_handle_dir(zpi->zpi_name, zpc, &head);
|
|
||||||
free(zpi);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* CDDL HEADER START
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the terms of the
|
|
||||||
* Common Development and Distribution License (the "License").
|
|
||||||
* You may not use this file except in compliance with the License.
|
|
||||||
*
|
|
||||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
||||||
* or http://www.opensolaris.org/os/licensing.
|
|
||||||
* See the License for the specific language governing permissions
|
|
||||||
* and limitations under the License.
|
|
||||||
*
|
|
||||||
* When distributing Covered Code, include this CDDL HEADER in each
|
|
||||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
||||||
* If applicable, add the following below this CDDL HEADER, with the
|
|
||||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
||||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
||||||
*
|
|
||||||
* CDDL HEADER END
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2017, Intel Corporation. All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _ZFS_PROJECTUTIL_H
|
|
||||||
#define _ZFS_PROJECTUTIL_H
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
ZFS_PROJECT_OP_DEFAULT = 0,
|
|
||||||
ZFS_PROJECT_OP_LIST = 1,
|
|
||||||
ZFS_PROJECT_OP_CHECK = 2,
|
|
||||||
ZFS_PROJECT_OP_CLEAR = 3,
|
|
||||||
ZFS_PROJECT_OP_SET = 4,
|
|
||||||
} zfs_project_ops_t;
|
|
||||||
|
|
||||||
typedef struct zfs_project_control {
|
|
||||||
uint64_t zpc_expected_projid;
|
|
||||||
zfs_project_ops_t zpc_op;
|
|
||||||
boolean_t zpc_dironly;
|
|
||||||
boolean_t zpc_ignore_noent;
|
|
||||||
boolean_t zpc_keep_projid;
|
|
||||||
boolean_t zpc_newline;
|
|
||||||
boolean_t zpc_recursive;
|
|
||||||
boolean_t zpc_set_flag;
|
|
||||||
} zfs_project_control_t;
|
|
||||||
|
|
||||||
int zfs_project_handle(const char *name, zfs_project_control_t *zpc);
|
|
||||||
|
|
||||||
#endif /* _ZFS_PROJECTUTIL_H */
|
|
||||||
+1
-1
@@ -33,7 +33,7 @@ extern "C" {
|
|||||||
|
|
||||||
void * safe_malloc(size_t size);
|
void * safe_malloc(size_t size);
|
||||||
void nomem(void);
|
void nomem(void);
|
||||||
extern libzfs_handle_t *g_zfs;
|
libzfs_handle_t *g_zfs;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,4 +11,7 @@ zhack_SOURCES = \
|
|||||||
|
|
||||||
zhack_LDADD = \
|
zhack_LDADD = \
|
||||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
$(top_builddir)/lib/libzpool/libzpool.la
|
$(top_builddir)/lib/libuutil/libuutil.la \
|
||||||
|
$(top_builddir)/lib/libzpool/libzpool.la \
|
||||||
|
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||||
|
$(top_builddir)/lib/libzfs_core/libzfs_core.la
|
||||||
|
|||||||
+10
-5
@@ -48,11 +48,12 @@
|
|||||||
#include <sys/zio_compress.h>
|
#include <sys/zio_compress.h>
|
||||||
#include <sys/zfeature.h>
|
#include <sys/zfeature.h>
|
||||||
#include <sys/dmu_tx.h>
|
#include <sys/dmu_tx.h>
|
||||||
#include <libzutil.h>
|
#include <libzfs.h>
|
||||||
|
|
||||||
extern boolean_t zfeature_checks_disable;
|
extern boolean_t zfeature_checks_disable;
|
||||||
|
|
||||||
const char cmdname[] = "zhack";
|
const char cmdname[] = "zhack";
|
||||||
|
libzfs_handle_t *g_zfs;
|
||||||
static importargs_t g_importargs;
|
static importargs_t g_importargs;
|
||||||
static char *g_pool;
|
static char *g_pool;
|
||||||
static boolean_t g_readonly;
|
static boolean_t g_readonly;
|
||||||
@@ -104,7 +105,7 @@ fatal(spa_t *spa, void *tag, const char *fmt, ...)
|
|||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
space_delta_cb(dmu_object_type_t bonustype, void *data,
|
space_delta_cb(dmu_object_type_t bonustype, void *data,
|
||||||
uint64_t *userp, uint64_t *groupp, uint64_t *projectp)
|
uint64_t *userp, uint64_t *groupp)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Is it a valid type of object to track?
|
* Is it a valid type of object to track?
|
||||||
@@ -127,17 +128,20 @@ zhack_import(char *target, boolean_t readonly)
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
kernel_init(readonly ? FREAD : (FREAD | FWRITE));
|
kernel_init(readonly ? FREAD : (FREAD | FWRITE));
|
||||||
|
g_zfs = libzfs_init();
|
||||||
|
ASSERT(g_zfs != NULL);
|
||||||
|
|
||||||
dmu_objset_register_type(DMU_OST_ZFS, space_delta_cb);
|
dmu_objset_register_type(DMU_OST_ZFS, space_delta_cb);
|
||||||
|
|
||||||
g_readonly = readonly;
|
g_readonly = readonly;
|
||||||
|
g_importargs.unique = B_TRUE;
|
||||||
g_importargs.can_be_active = readonly;
|
g_importargs.can_be_active = readonly;
|
||||||
g_pool = strdup(target);
|
g_pool = strdup(target);
|
||||||
|
|
||||||
error = zpool_find_config(NULL, target, &config, &g_importargs,
|
error = zpool_tryimport(g_zfs, target, &config, &g_importargs);
|
||||||
&libzpool_config_ops);
|
|
||||||
if (error)
|
if (error)
|
||||||
fatal(NULL, FTAG, "cannot import '%s'", target);
|
fatal(NULL, FTAG, "cannot import '%s': %s", target,
|
||||||
|
libzfs_error_description(g_zfs));
|
||||||
|
|
||||||
props = NULL;
|
props = NULL;
|
||||||
if (readonly) {
|
if (readonly) {
|
||||||
@@ -525,6 +529,7 @@ main(int argc, char **argv)
|
|||||||
"changes may not be committed to disk\n");
|
"changes may not be committed to disk\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libzfs_fini(g_zfs);
|
||||||
kernel_fini();
|
kernel_fini();
|
||||||
|
|
||||||
return (rv);
|
return (rv);
|
||||||
|
|||||||
@@ -13,4 +13,7 @@ zinject_SOURCES = \
|
|||||||
|
|
||||||
zinject_LDADD = \
|
zinject_LDADD = \
|
||||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
$(top_builddir)/lib/libzfs/libzfs.la
|
$(top_builddir)/lib/libuutil/libuutil.la \
|
||||||
|
$(top_builddir)/lib/libzpool/libzpool.la \
|
||||||
|
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||||
|
$(top_builddir)/lib/libzfs_core/libzfs_core.la
|
||||||
|
|||||||
+111
-17
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
|
|
||||||
|
#include <sys/zfs_context.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -47,6 +49,9 @@
|
|||||||
|
|
||||||
#include "zinject.h"
|
#include "zinject.h"
|
||||||
|
|
||||||
|
extern void kernel_init(int);
|
||||||
|
extern void kernel_fini(void);
|
||||||
|
|
||||||
static int debug;
|
static int debug;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -156,32 +161,51 @@ parse_pathname(const char *inpath, char *dataset, char *relpath,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert from a dataset to a objset id. Note that
|
* Convert from a (dataset, path) pair into a (objset, object) pair. Note that
|
||||||
* we grab the object number from the inode number.
|
* we grab the object number from the inode number, since looking this up via
|
||||||
|
* libzpool is a real pain.
|
||||||
*/
|
*/
|
||||||
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
object_from_path(const char *dataset, uint64_t object, zinject_record_t *record)
|
object_from_path(const char *dataset, const char *path, struct stat64 *statbuf,
|
||||||
|
zinject_record_t *record)
|
||||||
{
|
{
|
||||||
zfs_handle_t *zhp;
|
objset_t *os;
|
||||||
|
int err;
|
||||||
|
|
||||||
if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL)
|
/*
|
||||||
|
* Before doing any libzpool operations, call sync() to ensure that the
|
||||||
|
* on-disk state is consistent with the in-core state.
|
||||||
|
*/
|
||||||
|
sync();
|
||||||
|
|
||||||
|
err = dmu_objset_own(dataset, DMU_OST_ZFS, B_TRUE, FTAG, &os);
|
||||||
|
if (err != 0) {
|
||||||
|
(void) fprintf(stderr, "cannot open dataset '%s': %s\n",
|
||||||
|
dataset, strerror(err));
|
||||||
return (-1);
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
record->zi_objset = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
|
record->zi_objset = dmu_objset_id(os);
|
||||||
record->zi_object = object;
|
record->zi_object = statbuf->st_ino;
|
||||||
|
|
||||||
zfs_close(zhp);
|
dmu_objset_disown(os, FTAG);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the range based on the type, level, and range given.
|
* Calculate the real range based on the type, level, and range given.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
initialize_range(err_type_t type, int level, char *range,
|
calculate_range(const char *dataset, err_type_t type, int level, char *range,
|
||||||
zinject_record_t *record)
|
zinject_record_t *record)
|
||||||
{
|
{
|
||||||
|
objset_t *os = NULL;
|
||||||
|
dnode_t *dn = NULL;
|
||||||
|
int err;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine the numeric range from the string.
|
* Determine the numeric range from the string.
|
||||||
*/
|
*/
|
||||||
@@ -209,7 +233,7 @@ initialize_range(err_type_t type, int level, char *range,
|
|||||||
(void) fprintf(stderr, "invalid range '%s': must be "
|
(void) fprintf(stderr, "invalid range '%s': must be "
|
||||||
"a numeric range of the form 'start[,end]'\n",
|
"a numeric range of the form 'start[,end]'\n",
|
||||||
range);
|
range);
|
||||||
return (-1);
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +253,7 @@ initialize_range(err_type_t type, int level, char *range,
|
|||||||
if (range != NULL) {
|
if (range != NULL) {
|
||||||
(void) fprintf(stderr, "range cannot be specified when "
|
(void) fprintf(stderr, "range cannot be specified when "
|
||||||
"type is 'dnode'\n");
|
"type is 'dnode'\n");
|
||||||
return (-1);
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
record->zi_start = record->zi_object * sizeof (dnode_phys_t);
|
record->zi_start = record->zi_object * sizeof (dnode_phys_t);
|
||||||
@@ -238,9 +262,76 @@ initialize_range(err_type_t type, int level, char *range,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
record->zi_level = level;
|
/*
|
||||||
|
* Get the dnode associated with object, so we can calculate the block
|
||||||
|
* size.
|
||||||
|
*/
|
||||||
|
if ((err = dmu_objset_own(dataset, DMU_OST_ANY,
|
||||||
|
B_TRUE, FTAG, &os)) != 0) {
|
||||||
|
(void) fprintf(stderr, "cannot open dataset '%s': %s\n",
|
||||||
|
dataset, strerror(err));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
return (0);
|
if (record->zi_object == 0) {
|
||||||
|
dn = DMU_META_DNODE(os);
|
||||||
|
} else {
|
||||||
|
err = dnode_hold(os, record->zi_object, FTAG, &dn);
|
||||||
|
if (err != 0) {
|
||||||
|
(void) fprintf(stderr, "failed to hold dnode "
|
||||||
|
"for object %llu\n",
|
||||||
|
(u_longlong_t)record->zi_object);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ziprintf("data shift: %d\n", (int)dn->dn_datablkshift);
|
||||||
|
ziprintf(" ind shift: %d\n", (int)dn->dn_indblkshift);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate range into block IDs.
|
||||||
|
*/
|
||||||
|
if (record->zi_start != 0 || record->zi_end != -1ULL) {
|
||||||
|
record->zi_start >>= dn->dn_datablkshift;
|
||||||
|
record->zi_end >>= dn->dn_datablkshift;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check level, and then translate level 0 blkids into ranges
|
||||||
|
* appropriate for level of indirection.
|
||||||
|
*/
|
||||||
|
record->zi_level = level;
|
||||||
|
if (level > 0) {
|
||||||
|
ziprintf("level 0 blkid range: [%llu, %llu]\n",
|
||||||
|
record->zi_start, record->zi_end);
|
||||||
|
|
||||||
|
if (level >= dn->dn_nlevels) {
|
||||||
|
(void) fprintf(stderr, "level %d exceeds max level "
|
||||||
|
"of object (%d)\n", level, dn->dn_nlevels - 1);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record->zi_start != 0 || record->zi_end != 0) {
|
||||||
|
int shift = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
|
||||||
|
|
||||||
|
for (; level > 0; level--) {
|
||||||
|
record->zi_start >>= shift;
|
||||||
|
record->zi_end >>= shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
out:
|
||||||
|
if (dn) {
|
||||||
|
if (dn != DMU_META_DNODE(os))
|
||||||
|
dnode_rele(dn, FTAG);
|
||||||
|
}
|
||||||
|
if (os)
|
||||||
|
dmu_objset_disown(os, FTAG);
|
||||||
|
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -252,6 +343,8 @@ translate_record(err_type_t type, const char *object, const char *range,
|
|||||||
struct stat64 statbuf;
|
struct stat64 statbuf;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
|
kernel_init(FREAD);
|
||||||
|
|
||||||
debug = (getenv("ZINJECT_DEBUG") != NULL);
|
debug = (getenv("ZINJECT_DEBUG") != NULL);
|
||||||
|
|
||||||
ziprintf("translating: %s\n", object);
|
ziprintf("translating: %s\n", object);
|
||||||
@@ -303,16 +396,16 @@ translate_record(err_type_t type, const char *object, const char *range,
|
|||||||
/*
|
/*
|
||||||
* Convert (dataset, file) into (objset, object)
|
* Convert (dataset, file) into (objset, object)
|
||||||
*/
|
*/
|
||||||
if (object_from_path(dataset, statbuf.st_ino, record) != 0)
|
if (object_from_path(dataset, path, &statbuf, record) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ziprintf("raw objset: %llu\n", record->zi_objset);
|
ziprintf("raw objset: %llu\n", record->zi_objset);
|
||||||
ziprintf("raw object: %llu\n", record->zi_object);
|
ziprintf("raw object: %llu\n", record->zi_object);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For the given object, initialize the range in bytes
|
* For the given object, calculate the real (type, level, range)
|
||||||
*/
|
*/
|
||||||
if (initialize_range(type, level, (char *)range, record) != 0)
|
if (calculate_range(dataset, type, level, (char *)range, record) != 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ziprintf(" objset: %llu\n", record->zi_objset);
|
ziprintf(" objset: %llu\n", record->zi_objset);
|
||||||
@@ -334,6 +427,7 @@ translate_record(err_type_t type, const char *object, const char *range,
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
kernel_fini();
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+30
-163
@@ -36,15 +36,12 @@
|
|||||||
*
|
*
|
||||||
* Errors can be injected into a particular vdev using the '-d' option. This
|
* Errors can be injected into a particular vdev using the '-d' option. This
|
||||||
* option takes a path or vdev GUID to uniquely identify the device within a
|
* option takes a path or vdev GUID to uniquely identify the device within a
|
||||||
* pool. There are four types of errors that can be injected, IO, ENXIO,
|
* pool. There are two types of errors that can be injected, EIO and ENXIO,
|
||||||
* ECHILD, and EILSEQ. These can be controlled through the '-e' option and the
|
* that can be controlled through the '-e' option. The default is ENXIO. For
|
||||||
* default is ENXIO. For EIO failures, any attempt to read data from the device
|
* EIO failures, any attempt to read data from the device will return EIO, but
|
||||||
* will return EIO, but a subsequent attempt to reopen the device will succeed.
|
* subsequent attempt to reopen the device will succeed. For ENXIO failures,
|
||||||
* For ENXIO failures, any attempt to read from the device will return EIO, but
|
* any attempt to read from the device will return EIO, but any attempt to
|
||||||
* any attempt to reopen the device will also return ENXIO. The EILSEQ failures
|
* reopen the device will also return ENXIO.
|
||||||
* only apply to read operations (-T read) and will flip a bit after the device
|
|
||||||
* has read the original data.
|
|
||||||
*
|
|
||||||
* For label faults, the -L option must be specified. This allows faults
|
* For label faults, the -L option must be specified. This allows faults
|
||||||
* to be injected into either the nvlist, uberblock, pad1, or pad2 region
|
* to be injected into either the nvlist, uberblock, pad1, or pad2 region
|
||||||
* of all the labels for the specified device.
|
* of all the labels for the specified device.
|
||||||
@@ -116,9 +113,9 @@
|
|||||||
* specified.
|
* specified.
|
||||||
*
|
*
|
||||||
* The '-e' option takes a string describing the errno to simulate. This must
|
* The '-e' option takes a string describing the errno to simulate. This must
|
||||||
* be one of 'io', 'checksum', 'decompress', or 'decrypt'. In most cases this
|
* be either 'io' or 'checksum'. In most cases this will result in the same
|
||||||
* will result in the same behavior, but RAID-Z will produce a different set of
|
* behavior, but RAID-Z will produce a different set of ereports for this
|
||||||
* ereports for this situation.
|
* situation.
|
||||||
*
|
*
|
||||||
* The '-a', '-u', and '-m' flags toggle internal flush behavior. If '-a' is
|
* The '-a', '-u', and '-m' flags toggle internal flush behavior. If '-a' is
|
||||||
* specified, then the ARC cache is flushed appropriately. If '-u' is
|
* specified, then the ARC cache is flushed appropriately. If '-u' is
|
||||||
@@ -234,12 +231,11 @@ usage(void)
|
|||||||
"\t\tspa_vdev_exit() will trigger a panic.\n"
|
"\t\tspa_vdev_exit() will trigger a panic.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"\tzinject -d device [-e errno] [-L <nvlist|uber|pad1|pad2>] [-F]\n"
|
"\tzinject -d device [-e errno] [-L <nvlist|uber|pad1|pad2>] [-F]\n"
|
||||||
"\t\t[-T <read|write|free|claim|all>] [-f frequency] pool\n\n"
|
"\t [-T <read|write|free|claim|all>] [-f frequency] pool\n"
|
||||||
"\t\tInject a fault into a particular device or the device's\n"
|
"\t\tInject a fault into a particular device or the device's\n"
|
||||||
"\t\tlabel. Label injection can either be 'nvlist', 'uber',\n "
|
"\t\tlabel. Label injection can either be 'nvlist', 'uber',\n "
|
||||||
"\t\t'pad1', or 'pad2'.\n"
|
"\t\t'pad1', or 'pad2'.\n"
|
||||||
"\t\t'errno' can be 'nxio' (the default), 'io', 'dtl', or\n"
|
"\t\t'errno' can be 'nxio' (the default), 'io', or 'dtl'.\n"
|
||||||
"\t\t'corrupt' (bit flip).\n"
|
|
||||||
"\t\t'frequency' is a value between 0.0001 and 100.0 that limits\n"
|
"\t\t'frequency' is a value between 0.0001 and 100.0 that limits\n"
|
||||||
"\t\tdevice error injection to a percentage of the IOs.\n"
|
"\t\tdevice error injection to a percentage of the IOs.\n"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -291,19 +287,16 @@ usage(void)
|
|||||||
"\t\tspecified by the remaining tuple. Each number is in\n"
|
"\t\tspecified by the remaining tuple. Each number is in\n"
|
||||||
"\t\thexadecimal, and only one block can be specified.\n"
|
"\t\thexadecimal, and only one block can be specified.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"\tzinject [-q] <-t type> [-C dvas] [-e errno] [-l level]\n"
|
"\tzinject [-q] <-t type> [-e errno] [-l level] [-r range]\n"
|
||||||
"\t\t[-r range] [-a] [-m] [-u] [-f freq] <object>\n"
|
"\t [-a] [-m] [-u] [-f freq] <object>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"\t\tInject an error into the object specified by the '-t' option\n"
|
"\t\tInject an error into the object specified by the '-t' option\n"
|
||||||
"\t\tand the object descriptor. The 'object' parameter is\n"
|
"\t\tand the object descriptor. The 'object' parameter is\n"
|
||||||
"\t\tinterpreted depending on the '-t' option.\n"
|
"\t\tinterpreted depending on the '-t' option.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"\t\t-q\tQuiet mode. Only print out the handler number added.\n"
|
"\t\t-q\tQuiet mode. Only print out the handler number added.\n"
|
||||||
"\t\t-e\tInject a specific error. Must be one of 'io',\n"
|
"\t\t-e\tInject a specific error. Must be either 'io' or\n"
|
||||||
"\t\t\t'checksum', 'decompress', or 'decrypt'. Default is 'io'.\n"
|
"\t\t\t'checksum'. Default is 'io'.\n"
|
||||||
"\t\t-C\tInject the given error only into specific DVAs. The\n"
|
|
||||||
"\t\t\tDVAs should be specified as a list of 0-indexed DVAs\n"
|
|
||||||
"\t\t\tseparated by commas (ex. '0,2').\n"
|
|
||||||
"\t\t-l\tInject error at a particular block level. Default is "
|
"\t\t-l\tInject error at a particular block level. Default is "
|
||||||
"0.\n"
|
"0.\n"
|
||||||
"\t\t-m\tAutomatically remount underlying filesystem.\n"
|
"\t\t-m\tAutomatically remount underlying filesystem.\n"
|
||||||
@@ -364,20 +357,17 @@ print_data_handler(int id, const char *pool, zinject_record_t *record,
|
|||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if (*count == 0) {
|
if (*count == 0) {
|
||||||
(void) printf("%3s %-15s %-6s %-6s %-8s %3s %-4s "
|
(void) printf("%3s %-15s %-6s %-6s %-8s %3s %-15s\n",
|
||||||
"%-15s\n", "ID", "POOL", "OBJSET", "OBJECT", "TYPE",
|
"ID", "POOL", "OBJSET", "OBJECT", "TYPE", "LVL", "RANGE");
|
||||||
"LVL", "DVAs", "RANGE");
|
|
||||||
(void) printf("--- --------------- ------ "
|
(void) printf("--- --------------- ------ "
|
||||||
"------ -------- --- ---- ---------------\n");
|
"------ -------- --- ---------------\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
*count += 1;
|
*count += 1;
|
||||||
|
|
||||||
(void) printf("%3d %-15s %-6llu %-6llu %-8s %-3d 0x%02x ",
|
(void) printf("%3d %-15s %-6llu %-6llu %-8s %3d ", id, pool,
|
||||||
id, pool, (u_longlong_t)record->zi_objset,
|
(u_longlong_t)record->zi_objset, (u_longlong_t)record->zi_object,
|
||||||
(u_longlong_t)record->zi_object, type_to_name(record->zi_type),
|
type_to_name(record->zi_type), record->zi_level);
|
||||||
record->zi_level, record->zi_dvas);
|
|
||||||
|
|
||||||
|
|
||||||
if (record->zi_start == 0 &&
|
if (record->zi_start == 0 &&
|
||||||
record->zi_end == -1ULL)
|
record->zi_end == -1ULL)
|
||||||
@@ -567,7 +557,6 @@ register_handler(const char *pool, int flags, zinject_record_t *record,
|
|||||||
|
|
||||||
if (ioctl(zfs_fd, ZFS_IOC_INJECT_FAULT, &zc) != 0) {
|
if (ioctl(zfs_fd, ZFS_IOC_INJECT_FAULT, &zc) != 0) {
|
||||||
(void) fprintf(stderr, "failed to add handler: %s\n",
|
(void) fprintf(stderr, "failed to add handler: %s\n",
|
||||||
errno == EDOM ? "block level exceeds max level of object" :
|
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@@ -608,7 +597,6 @@ register_handler(const char *pool, int flags, zinject_record_t *record,
|
|||||||
(void) printf(" range: [%llu, %llu)\n",
|
(void) printf(" range: [%llu, %llu)\n",
|
||||||
(u_longlong_t)record->zi_start,
|
(u_longlong_t)record->zi_start,
|
||||||
(u_longlong_t)record->zi_end);
|
(u_longlong_t)record->zi_end);
|
||||||
(void) printf(" dvas: 0x%x\n", record->zi_dvas);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -681,59 +669,6 @@ parse_frequency(const char *str, uint32_t *percent)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function converts a string specifier for DVAs into a bit mask.
|
|
||||||
* The dva's provided by the user should be 0 indexed and separated by
|
|
||||||
* a comma. For example:
|
|
||||||
* "1" -> 0b0010 (0x2)
|
|
||||||
* "0,1" -> 0b0011 (0x3)
|
|
||||||
* "0,1,2" -> 0b0111 (0x7)
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
parse_dvas(const char *str, uint32_t *dvas_out)
|
|
||||||
{
|
|
||||||
const char *c = str;
|
|
||||||
uint32_t mask = 0;
|
|
||||||
boolean_t need_delim = B_FALSE;
|
|
||||||
|
|
||||||
/* max string length is 5 ("0,1,2") */
|
|
||||||
if (strlen(str) > 5 || strlen(str) == 0)
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
while (*c != '\0') {
|
|
||||||
switch (*c) {
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
/* check for pipe between DVAs */
|
|
||||||
if (need_delim)
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
/* check if this DVA has been set already */
|
|
||||||
if (mask & (1 << ((*c) - '0')))
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
mask |= (1 << ((*c) - '0'));
|
|
||||||
need_delim = B_TRUE;
|
|
||||||
break;
|
|
||||||
case ',':
|
|
||||||
need_delim = B_FALSE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* check for invalid character */
|
|
||||||
return (EINVAL);
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for dangling delimiter */
|
|
||||||
if (!need_delim)
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
*dvas_out = mask;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -760,10 +695,9 @@ main(int argc, char **argv)
|
|||||||
int dur_secs = 0;
|
int dur_secs = 0;
|
||||||
int ret;
|
int ret;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
uint32_t dvas = 0;
|
|
||||||
|
|
||||||
if ((g_zfs = libzfs_init()) == NULL) {
|
if ((g_zfs = libzfs_init()) == NULL) {
|
||||||
(void) fprintf(stderr, "%s\n", libzfs_error_init(errno));
|
(void) fprintf(stderr, "%s", libzfs_error_init(errno));
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,7 +725,7 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while ((c = getopt(argc, argv,
|
while ((c = getopt(argc, argv,
|
||||||
":aA:b:C:d:D:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:")) != -1) {
|
":aA:b:d:D:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a':
|
case 'a':
|
||||||
flags |= ZINJECT_FLUSH_ARC;
|
flags |= ZINJECT_FLUSH_ARC;
|
||||||
@@ -815,17 +749,6 @@ main(int argc, char **argv)
|
|||||||
case 'c':
|
case 'c':
|
||||||
cancel = optarg;
|
cancel = optarg;
|
||||||
break;
|
break;
|
||||||
case 'C':
|
|
||||||
ret = parse_dvas(optarg, &dvas);
|
|
||||||
if (ret != 0) {
|
|
||||||
(void) fprintf(stderr, "invalid DVA list '%s': "
|
|
||||||
"DVAs should be 0 indexed and separated by "
|
|
||||||
"commas.\n", optarg);
|
|
||||||
usage();
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'd':
|
case 'd':
|
||||||
device = optarg;
|
device = optarg;
|
||||||
break;
|
break;
|
||||||
@@ -847,16 +770,10 @@ main(int argc, char **argv)
|
|||||||
error = EIO;
|
error = EIO;
|
||||||
} else if (strcasecmp(optarg, "checksum") == 0) {
|
} else if (strcasecmp(optarg, "checksum") == 0) {
|
||||||
error = ECKSUM;
|
error = ECKSUM;
|
||||||
} else if (strcasecmp(optarg, "decompress") == 0) {
|
|
||||||
error = EINVAL;
|
|
||||||
} else if (strcasecmp(optarg, "decrypt") == 0) {
|
|
||||||
error = EACCES;
|
|
||||||
} else if (strcasecmp(optarg, "nxio") == 0) {
|
} else if (strcasecmp(optarg, "nxio") == 0) {
|
||||||
error = ENXIO;
|
error = ENXIO;
|
||||||
} else if (strcasecmp(optarg, "dtl") == 0) {
|
} else if (strcasecmp(optarg, "dtl") == 0) {
|
||||||
error = ECHILD;
|
error = ECHILD;
|
||||||
} else if (strcasecmp(optarg, "corrupt") == 0) {
|
|
||||||
error = EILSEQ;
|
|
||||||
} else {
|
} else {
|
||||||
(void) fprintf(stderr, "invalid error type "
|
(void) fprintf(stderr, "invalid error type "
|
||||||
"'%s': must be 'io', 'checksum' or "
|
"'%s': must be 'io', 'checksum' or "
|
||||||
@@ -926,7 +843,6 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
range = optarg;
|
range = optarg;
|
||||||
flags |= ZINJECT_CALC_RANGE;
|
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
dur_secs = 1;
|
dur_secs = 1;
|
||||||
@@ -1009,7 +925,7 @@ main(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
||||||
level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED ||
|
level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED ||
|
||||||
record.zi_freq > 0 || dvas != 0) {
|
record.zi_freq > 0) {
|
||||||
(void) fprintf(stderr, "cancel (-c) incompatible with "
|
(void) fprintf(stderr, "cancel (-c) incompatible with "
|
||||||
"any other options\n");
|
"any other options\n");
|
||||||
usage();
|
usage();
|
||||||
@@ -1044,8 +960,7 @@ main(int argc, char **argv)
|
|||||||
* for doing injection, so handle it separately here.
|
* for doing injection, so handle it separately here.
|
||||||
*/
|
*/
|
||||||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
||||||
level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED ||
|
level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED) {
|
||||||
dvas != 0) {
|
|
||||||
(void) fprintf(stderr, "device (-d) incompatible with "
|
(void) fprintf(stderr, "device (-d) incompatible with "
|
||||||
"data error injection\n");
|
"data error injection\n");
|
||||||
usage();
|
usage();
|
||||||
@@ -1066,15 +981,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
if (error == ECKSUM) {
|
if (error == ECKSUM) {
|
||||||
(void) fprintf(stderr, "device error type must be "
|
(void) fprintf(stderr, "device error type must be "
|
||||||
"'io', 'nxio' or 'corrupt'\n");
|
"'io' or 'nxio'\n");
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error == EILSEQ &&
|
|
||||||
(record.zi_freq == 0 || io_type != ZIO_TYPE_READ)) {
|
|
||||||
(void) fprintf(stderr, "device corrupt errors require "
|
|
||||||
"io type read and a frequency value\n");
|
|
||||||
libzfs_fini(g_zfs);
|
libzfs_fini(g_zfs);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@@ -1093,7 +1000,7 @@ main(int argc, char **argv)
|
|||||||
} else if (raw != NULL) {
|
} else if (raw != NULL) {
|
||||||
if (range != NULL || type != TYPE_INVAL || level != 0 ||
|
if (range != NULL || type != TYPE_INVAL || level != 0 ||
|
||||||
record.zi_cmd != ZINJECT_UNINITIALIZED ||
|
record.zi_cmd != ZINJECT_UNINITIALIZED ||
|
||||||
record.zi_freq > 0 || dvas != 0) {
|
record.zi_freq > 0) {
|
||||||
(void) fprintf(stderr, "raw (-b) format with "
|
(void) fprintf(stderr, "raw (-b) format with "
|
||||||
"any other options\n");
|
"any other options\n");
|
||||||
usage();
|
usage();
|
||||||
@@ -1128,8 +1035,7 @@ main(int argc, char **argv)
|
|||||||
error = EIO;
|
error = EIO;
|
||||||
} else if (record.zi_cmd == ZINJECT_PANIC) {
|
} else if (record.zi_cmd == ZINJECT_PANIC) {
|
||||||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
||||||
level != 0 || device != NULL || record.zi_freq > 0 ||
|
level != 0 || device != NULL || record.zi_freq > 0) {
|
||||||
dvas != 0) {
|
|
||||||
(void) fprintf(stderr, "panic (-p) incompatible with "
|
(void) fprintf(stderr, "panic (-p) incompatible with "
|
||||||
"other options\n");
|
"other options\n");
|
||||||
usage();
|
usage();
|
||||||
@@ -1150,15 +1056,6 @@ main(int argc, char **argv)
|
|||||||
record.zi_type = atoi(argv[1]);
|
record.zi_type = atoi(argv[1]);
|
||||||
dataset[0] = '\0';
|
dataset[0] = '\0';
|
||||||
} else if (record.zi_cmd == ZINJECT_IGNORED_WRITES) {
|
} else if (record.zi_cmd == ZINJECT_IGNORED_WRITES) {
|
||||||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
|
||||||
level != 0 || record.zi_freq > 0 || dvas != 0) {
|
|
||||||
(void) fprintf(stderr, "hardware failure (-I) "
|
|
||||||
"incompatible with other options\n");
|
|
||||||
usage();
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
return (2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nowrites == 0) {
|
if (nowrites == 0) {
|
||||||
(void) fprintf(stderr, "-s or -g meaningless "
|
(void) fprintf(stderr, "-s or -g meaningless "
|
||||||
"without -I (ignore writes)\n");
|
"without -I (ignore writes)\n");
|
||||||
@@ -1212,44 +1109,14 @@ main(int argc, char **argv)
|
|||||||
return (2);
|
return (2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == ENXIO || error == EILSEQ) {
|
if (error == ENXIO) {
|
||||||
(void) fprintf(stderr, "data error type must be "
|
(void) fprintf(stderr, "data error type must be "
|
||||||
"'checksum' or 'io'\n");
|
"'checksum' or 'io'\n");
|
||||||
libzfs_fini(g_zfs);
|
libzfs_fini(g_zfs);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dvas != 0) {
|
record.zi_cmd = ZINJECT_DATA_FAULT;
|
||||||
if (error == EACCES || error == EINVAL) {
|
|
||||||
(void) fprintf(stderr, "the '-C' option may "
|
|
||||||
"not be used with logical data errors "
|
|
||||||
"'decrypt' and 'decompress'\n");
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
record.zi_dvas = dvas;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error == EACCES) {
|
|
||||||
if (type != TYPE_DATA) {
|
|
||||||
(void) fprintf(stderr, "decryption errors "
|
|
||||||
"may only be injected for 'data' types\n");
|
|
||||||
libzfs_fini(g_zfs);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
record.zi_cmd = ZINJECT_DECRYPT_FAULT;
|
|
||||||
/*
|
|
||||||
* Internally, ZFS actually uses ECKSUM for decryption
|
|
||||||
* errors since EACCES is used to indicate the key was
|
|
||||||
* not found.
|
|
||||||
*/
|
|
||||||
error = ECKSUM;
|
|
||||||
} else {
|
|
||||||
record.zi_cmd = ZINJECT_DATA_FAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (translate_record(type, argv[0], range, level, &record, pool,
|
if (translate_record(type, argv[0], range, level, &record, pool,
|
||||||
dataset) != 0) {
|
dataset) != 0) {
|
||||||
libzfs_fini(g_zfs);
|
libzfs_fini(g_zfs);
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
/zpios
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
|
||||||
|
DEFAULT_INCLUDES += \
|
||||||
|
-I$(top_srcdir)/include
|
||||||
|
|
||||||
|
sbin_PROGRAMS = zpios
|
||||||
|
|
||||||
|
zpios_SOURCES = \
|
||||||
|
zpios_main.c \
|
||||||
|
zpios_util.c \
|
||||||
|
zpios.h
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* ZPIOS is a heavily modified version of the original PIOS test code.
|
||||||
|
* It is designed to have the test code running in the Linux kernel
|
||||||
|
* against ZFS while still being flexibly controlled from user space.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008-2010 Lawrence Livermore National Security, LLC.
|
||||||
|
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
||||||
|
* Written by Brian Behlendorf <behlendorf1@llnl.gov>.
|
||||||
|
* LLNL-CODE-403049
|
||||||
|
*
|
||||||
|
* Original PIOS Test Code
|
||||||
|
* Copyright (C) 2004 Cluster File Systems, Inc.
|
||||||
|
* Written by Peter Braam <braam@clusterfs.com>
|
||||||
|
* Atul Vidwansa <atul@clusterfs.com>
|
||||||
|
* Milind Dumbare <milind@clusterfs.com>
|
||||||
|
*
|
||||||
|
* This file is part of ZFS on Linux.
|
||||||
|
* For details, see <http://zfsonlinux.org/>.
|
||||||
|
*
|
||||||
|
* ZPIOS is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* ZPIOS is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015, Intel Corporation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ZPIOS_H
|
||||||
|
#define _ZPIOS_H
|
||||||
|
|
||||||
|
#include <zpios-ctl.h>
|
||||||
|
|
||||||
|
#define VERSION_SIZE 64
|
||||||
|
|
||||||
|
/* Regular expressions */
|
||||||
|
#define REGEX_NUMBERS "^[0-9]+$"
|
||||||
|
#define REGEX_NUMBERS_COMMA "^([0-9]+,)*[0-9]+$"
|
||||||
|
#define REGEX_SIZE "^[0-9]+[kKmMgGtT]?$"
|
||||||
|
#define REGEX_SIZE_COMMA "^([0-9]+[kKmMgGtT]?,)*[0-9]+[kKmMgGtT]?$"
|
||||||
|
|
||||||
|
/* Flags for low, high, incr */
|
||||||
|
#define FLAG_SET 0x01
|
||||||
|
#define FLAG_LOW 0x02
|
||||||
|
#define FLAG_HIGH 0x04
|
||||||
|
#define FLAG_INCR 0x08
|
||||||
|
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
|
||||||
|
#define KB (1024)
|
||||||
|
#define MB (KB * 1024)
|
||||||
|
#define GB (MB * 1024)
|
||||||
|
#define TB (GB * 1024)
|
||||||
|
|
||||||
|
#define KMGT_SIZE 16
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All offsets, sizes and counts can be passed to the application in
|
||||||
|
* multiple ways.
|
||||||
|
* 1. a value (stored in val[0], val_count will be 1)
|
||||||
|
* 2. a comma separated list of values (stored in val[], using val_count)
|
||||||
|
* 3. a range and block sizes, low, high, factor (val_count must be 0)
|
||||||
|
*/
|
||||||
|
typedef struct pios_range_repeat {
|
||||||
|
uint64_t val[32]; /* Comma sep array, or low, high, inc */
|
||||||
|
uint64_t val_count; /* Num of values */
|
||||||
|
uint64_t val_low;
|
||||||
|
uint64_t val_high;
|
||||||
|
uint64_t val_inc_perc;
|
||||||
|
uint64_t next_val; /* For multiple runs in get_next() */
|
||||||
|
} range_repeat_t;
|
||||||
|
|
||||||
|
typedef struct cmd_args {
|
||||||
|
range_repeat_t T; /* Thread count */
|
||||||
|
range_repeat_t N; /* Region count */
|
||||||
|
range_repeat_t O; /* Offset count */
|
||||||
|
range_repeat_t C; /* Chunksize */
|
||||||
|
range_repeat_t S; /* Regionsize */
|
||||||
|
range_repeat_t B; /* Blocksize */
|
||||||
|
|
||||||
|
const char *pool; /* Pool */
|
||||||
|
const char *name; /* Name */
|
||||||
|
uint32_t flags; /* Flags */
|
||||||
|
uint32_t block_size; /* ZFS block size */
|
||||||
|
uint32_t io_type; /* DMUIO only */
|
||||||
|
uint32_t verbose; /* Verbose */
|
||||||
|
uint32_t human_readable; /* Human readable output */
|
||||||
|
|
||||||
|
uint64_t regionnoise; /* Region noise */
|
||||||
|
uint64_t chunknoise; /* Chunk noise */
|
||||||
|
uint64_t thread_delay; /* Thread delay */
|
||||||
|
|
||||||
|
char pre[ZPIOS_PATH_SIZE]; /* Pre-exec hook */
|
||||||
|
char post[ZPIOS_PATH_SIZE]; /* Post-exec hook */
|
||||||
|
char log[ZPIOS_PATH_SIZE]; /* Requested log dir */
|
||||||
|
|
||||||
|
/* Control */
|
||||||
|
int current_id;
|
||||||
|
uint64_t current_T;
|
||||||
|
uint64_t current_N;
|
||||||
|
uint64_t current_C;
|
||||||
|
uint64_t current_S;
|
||||||
|
uint64_t current_O;
|
||||||
|
uint64_t current_B;
|
||||||
|
|
||||||
|
uint32_t rc;
|
||||||
|
} cmd_args_t;
|
||||||
|
|
||||||
|
int set_count(char *pattern1, char *pattern2, range_repeat_t *range,
|
||||||
|
char *optarg, uint32_t *flags, char *arg);
|
||||||
|
int set_lhi(char *pattern, range_repeat_t *range, char *optarg,
|
||||||
|
int flag, uint32_t *flag_thread, char *arg);
|
||||||
|
int set_noise(uint64_t *noise, char *optarg, char *arg);
|
||||||
|
int set_load_params(cmd_args_t *args, char *optarg);
|
||||||
|
int check_mutual_exclusive_command_lines(uint32_t flag, char *arg);
|
||||||
|
void print_stats_header(cmd_args_t *args);
|
||||||
|
void print_stats(cmd_args_t *args, zpios_cmd_t *cmd);
|
||||||
|
|
||||||
|
#endif /* _ZPIOS_H */
|
||||||
@@ -0,0 +1,681 @@
|
|||||||
|
/*
|
||||||
|
* ZPIOS is a heavily modified version of the original PIOS test code.
|
||||||
|
* It is designed to have the test code running in the Linux kernel
|
||||||
|
* against ZFS while still being flexibly controlled from user space.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008-2010 Lawrence Livermore National Security, LLC.
|
||||||
|
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
||||||
|
* Written by Brian Behlendorf <behlendorf1@llnl.gov>.
|
||||||
|
* LLNL-CODE-403049
|
||||||
|
*
|
||||||
|
* Original PIOS Test Code
|
||||||
|
* Copyright (C) 2004 Cluster File Systems, Inc.
|
||||||
|
* Written by Peter Braam <braam@clusterfs.com>
|
||||||
|
* Atul Vidwansa <atul@clusterfs.com>
|
||||||
|
* Milind Dumbare <milind@clusterfs.com>
|
||||||
|
*
|
||||||
|
* This file is part of ZFS on Linux.
|
||||||
|
* For details, see <http://zfsonlinux.org/>.
|
||||||
|
*
|
||||||
|
* ZPIOS is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* ZPIOS is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015, Intel Corporation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include "zpios.h"
|
||||||
|
|
||||||
|
static const char short_opt[] =
|
||||||
|
"t:l:h:e:n:i:j:k:o:m:q:r:c:a:b:g:s:A:B:C:"
|
||||||
|
"S:L:p:M:xP:R:G:I:N:T:VzOfHv?";
|
||||||
|
static const struct option long_opt[] = {
|
||||||
|
{"threadcount", required_argument, 0, 't' },
|
||||||
|
{"threadcount_low", required_argument, 0, 'l' },
|
||||||
|
{"threadcount_high", required_argument, 0, 'h' },
|
||||||
|
{"threadcount_incr", required_argument, 0, 'e' },
|
||||||
|
{"regioncount", required_argument, 0, 'n' },
|
||||||
|
{"regioncount_low", required_argument, 0, 'i' },
|
||||||
|
{"regioncount_high", required_argument, 0, 'j' },
|
||||||
|
{"regioncount_incr", required_argument, 0, 'k' },
|
||||||
|
{"offset", required_argument, 0, 'o' },
|
||||||
|
{"offset_low", required_argument, 0, 'm' },
|
||||||
|
{"offset_high", required_argument, 0, 'q' },
|
||||||
|
{"offset_incr", required_argument, 0, 'r' },
|
||||||
|
{"chunksize", required_argument, 0, 'c' },
|
||||||
|
{"chunksize_low", required_argument, 0, 'a' },
|
||||||
|
{"chunksize_high", required_argument, 0, 'b' },
|
||||||
|
{"chunksize_incr", required_argument, 0, 'g' },
|
||||||
|
{"regionsize", required_argument, 0, 's' },
|
||||||
|
{"regionsize_low", required_argument, 0, 'A' },
|
||||||
|
{"regionsize_high", required_argument, 0, 'B' },
|
||||||
|
{"regionsize_incr", required_argument, 0, 'C' },
|
||||||
|
{"blocksize", required_argument, 0, 'S' },
|
||||||
|
{"load", required_argument, 0, 'L' },
|
||||||
|
{"pool", required_argument, 0, 'p' },
|
||||||
|
{"name", required_argument, 0, 'M' },
|
||||||
|
{"cleanup", no_argument, 0, 'x' },
|
||||||
|
{"prerun", required_argument, 0, 'P' },
|
||||||
|
{"postrun", required_argument, 0, 'R' },
|
||||||
|
{"log", required_argument, 0, 'G' },
|
||||||
|
{"regionnoise", required_argument, 0, 'I' },
|
||||||
|
{"chunknoise", required_argument, 0, 'N' },
|
||||||
|
{"threaddelay", required_argument, 0, 'T' },
|
||||||
|
{"verify", no_argument, 0, 'V' },
|
||||||
|
{"zerocopy", no_argument, 0, 'z' },
|
||||||
|
{"nowait", no_argument, 0, 'O' },
|
||||||
|
{"noprefetch", no_argument, 0, 'f' },
|
||||||
|
{"human-readable", no_argument, 0, 'H' },
|
||||||
|
{"verbose", no_argument, 0, 'v' },
|
||||||
|
{"help", no_argument, 0, '?' },
|
||||||
|
{ 0, 0, 0, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static int zpiosctl_fd; /* Control file descriptor */
|
||||||
|
static char zpios_version[VERSION_SIZE]; /* Kernel version string */
|
||||||
|
static char *zpios_buffer = NULL; /* Scratch space area */
|
||||||
|
static int zpios_buffer_size = 0; /* Scratch space size */
|
||||||
|
|
||||||
|
static int
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: zpios\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" --threadcount -t =values\n"
|
||||||
|
" --threadcount_low -l =value\n"
|
||||||
|
" --threadcount_high -h =value\n"
|
||||||
|
" --threadcount_incr -e =value\n"
|
||||||
|
" --regioncount -n =values\n"
|
||||||
|
" --regioncount_low -i =value\n"
|
||||||
|
" --regioncount_high -j =value\n"
|
||||||
|
" --regioncount_incr -k =value\n"
|
||||||
|
" --offset -o =values\n"
|
||||||
|
" --offset_low -m =value\n"
|
||||||
|
" --offset_high -q =value\n"
|
||||||
|
" --offset_incr -r =value\n"
|
||||||
|
" --chunksize -c =values\n"
|
||||||
|
" --chunksize_low -a =value\n"
|
||||||
|
" --chunksize_high -b =value\n"
|
||||||
|
" --chunksize_incr -g =value\n"
|
||||||
|
" --regionsize -s =values\n"
|
||||||
|
" --regionsize_low -A =value\n"
|
||||||
|
" --regionsize_high -B =value\n"
|
||||||
|
" --regionsize_incr -C =value\n"
|
||||||
|
" --blocksize -S =values\n"
|
||||||
|
" --load -L =dmuio|ssf|fpp\n"
|
||||||
|
" --pool -p =pool name\n"
|
||||||
|
" --name -M =test name\n"
|
||||||
|
" --cleanup -x\n"
|
||||||
|
" --prerun -P =pre-command\n"
|
||||||
|
" --postrun -R =post-command\n"
|
||||||
|
" --log -G =log directory\n"
|
||||||
|
" --regionnoise -I =shift\n"
|
||||||
|
" --chunknoise -N =bytes\n"
|
||||||
|
" --threaddelay -T =jiffies\n"
|
||||||
|
" --verify -V\n"
|
||||||
|
" --zerocopy -z\n"
|
||||||
|
" --nowait -O\n"
|
||||||
|
" --noprefetch -f\n"
|
||||||
|
" --human-readable -H\n"
|
||||||
|
" --verbose -v =increase verbosity\n"
|
||||||
|
" --help -? =this help\n\n");
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void args_fini(cmd_args_t *args)
|
||||||
|
{
|
||||||
|
assert(args != NULL);
|
||||||
|
free(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* block size is 128K to 16M, power of 2 */
|
||||||
|
#define MIN_BLKSIZE (128ULL << 10)
|
||||||
|
#define MAX_BLKSIZE (16ULL << 20)
|
||||||
|
#define POW_OF_TWO(x) (((x) & ((x) - 1)) == 0)
|
||||||
|
|
||||||
|
static cmd_args_t *
|
||||||
|
args_init(int argc, char **argv)
|
||||||
|
{
|
||||||
|
cmd_args_t *args;
|
||||||
|
uint32_t fl_th = 0;
|
||||||
|
uint32_t fl_rc = 0;
|
||||||
|
uint32_t fl_of = 0;
|
||||||
|
uint32_t fl_rs = 0;
|
||||||
|
uint32_t fl_cs = 0;
|
||||||
|
uint32_t fl_bs = 0;
|
||||||
|
int c, rc, i;
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
usage();
|
||||||
|
return ((cmd_args_t *)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure and populate the args structures */
|
||||||
|
args = malloc(sizeof (*args));
|
||||||
|
if (args == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
memset(args, 0, sizeof (*args));
|
||||||
|
|
||||||
|
/* provide a default block size of 128K */
|
||||||
|
args->B.next_val = 0;
|
||||||
|
args->B.val[0] = MIN_BLKSIZE;
|
||||||
|
args->B.val_count = 1;
|
||||||
|
|
||||||
|
while ((c = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) {
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 't': /* --thread count */
|
||||||
|
rc = set_count(REGEX_NUMBERS, REGEX_NUMBERS_COMMA,
|
||||||
|
&args->T, optarg, &fl_th, "threadcount");
|
||||||
|
break;
|
||||||
|
case 'l': /* --threadcount_low */
|
||||||
|
rc = set_lhi(REGEX_NUMBERS, &args->T, optarg,
|
||||||
|
FLAG_LOW, &fl_th, "threadcount_low");
|
||||||
|
break;
|
||||||
|
case 'h': /* --threadcount_high */
|
||||||
|
rc = set_lhi(REGEX_NUMBERS, &args->T, optarg,
|
||||||
|
FLAG_HIGH, &fl_th, "threadcount_high");
|
||||||
|
break;
|
||||||
|
case 'e': /* --threadcount_inc */
|
||||||
|
rc = set_lhi(REGEX_NUMBERS, &args->T, optarg,
|
||||||
|
FLAG_INCR, &fl_th, "threadcount_incr");
|
||||||
|
break;
|
||||||
|
case 'n': /* --regioncount */
|
||||||
|
rc = set_count(REGEX_NUMBERS, REGEX_NUMBERS_COMMA,
|
||||||
|
&args->N, optarg, &fl_rc, "regioncount");
|
||||||
|
break;
|
||||||
|
case 'i': /* --regioncount_low */
|
||||||
|
rc = set_lhi(REGEX_NUMBERS, &args->N, optarg,
|
||||||
|
FLAG_LOW, &fl_rc, "regioncount_low");
|
||||||
|
break;
|
||||||
|
case 'j': /* --regioncount_high */
|
||||||
|
rc = set_lhi(REGEX_NUMBERS, &args->N, optarg,
|
||||||
|
FLAG_HIGH, &fl_rc, "regioncount_high");
|
||||||
|
break;
|
||||||
|
case 'k': /* --regioncount_inc */
|
||||||
|
rc = set_lhi(REGEX_NUMBERS, &args->N, optarg,
|
||||||
|
FLAG_INCR, &fl_rc, "regioncount_incr");
|
||||||
|
break;
|
||||||
|
case 'o': /* --offset */
|
||||||
|
rc = set_count(REGEX_SIZE, REGEX_SIZE_COMMA,
|
||||||
|
&args->O, optarg, &fl_of, "offset");
|
||||||
|
break;
|
||||||
|
case 'm': /* --offset_low */
|
||||||
|
rc = set_lhi(REGEX_SIZE, &args->O, optarg,
|
||||||
|
FLAG_LOW, &fl_of, "offset_low");
|
||||||
|
break;
|
||||||
|
case 'q': /* --offset_high */
|
||||||
|
rc = set_lhi(REGEX_SIZE, &args->O, optarg,
|
||||||
|
FLAG_HIGH, &fl_of, "offset_high");
|
||||||
|
break;
|
||||||
|
case 'r': /* --offset_inc */
|
||||||
|
rc = set_lhi(REGEX_NUMBERS, &args->O, optarg,
|
||||||
|
FLAG_INCR, &fl_of, "offset_incr");
|
||||||
|
break;
|
||||||
|
case 'c': /* --chunksize */
|
||||||
|
rc = set_count(REGEX_SIZE, REGEX_SIZE_COMMA,
|
||||||
|
&args->C, optarg, &fl_cs, "chunksize");
|
||||||
|
break;
|
||||||
|
case 'a': /* --chunksize_low */
|
||||||
|
rc = set_lhi(REGEX_SIZE, &args->C, optarg,
|
||||||
|
FLAG_LOW, &fl_cs, "chunksize_low");
|
||||||
|
break;
|
||||||
|
case 'b': /* --chunksize_high */
|
||||||
|
rc = set_lhi(REGEX_SIZE, &args->C, optarg,
|
||||||
|
FLAG_HIGH, &fl_cs, "chunksize_high");
|
||||||
|
break;
|
||||||
|
case 'g': /* --chunksize_inc */
|
||||||
|
rc = set_lhi(REGEX_NUMBERS, &args->C, optarg,
|
||||||
|
FLAG_INCR, &fl_cs, "chunksize_incr");
|
||||||
|
break;
|
||||||
|
case 's': /* --regionsize */
|
||||||
|
rc = set_count(REGEX_SIZE, REGEX_SIZE_COMMA,
|
||||||
|
&args->S, optarg, &fl_rs, "regionsize");
|
||||||
|
break;
|
||||||
|
case 'A': /* --regionsize_low */
|
||||||
|
rc = set_lhi(REGEX_SIZE, &args->S, optarg,
|
||||||
|
FLAG_LOW, &fl_rs, "regionsize_low");
|
||||||
|
break;
|
||||||
|
case 'B': /* --regionsize_high */
|
||||||
|
rc = set_lhi(REGEX_SIZE, &args->S, optarg,
|
||||||
|
FLAG_HIGH, &fl_rs, "regionsize_high");
|
||||||
|
break;
|
||||||
|
case 'C': /* --regionsize_inc */
|
||||||
|
rc = set_lhi(REGEX_NUMBERS, &args->S, optarg,
|
||||||
|
FLAG_INCR, &fl_rs, "regionsize_incr");
|
||||||
|
break;
|
||||||
|
case 'S': /* --blocksize */
|
||||||
|
rc = set_count(REGEX_SIZE, REGEX_SIZE_COMMA,
|
||||||
|
&args->B, optarg, &fl_bs, "blocksize");
|
||||||
|
break;
|
||||||
|
case 'L': /* --load */
|
||||||
|
rc = set_load_params(args, optarg);
|
||||||
|
break;
|
||||||
|
case 'p': /* --pool */
|
||||||
|
args->pool = optarg;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
args->name = optarg;
|
||||||
|
break;
|
||||||
|
case 'x': /* --cleanup */
|
||||||
|
args->flags |= DMU_REMOVE;
|
||||||
|
break;
|
||||||
|
case 'P': /* --prerun */
|
||||||
|
strncpy(args->pre, optarg, ZPIOS_PATH_SIZE - 1);
|
||||||
|
break;
|
||||||
|
case 'R': /* --postrun */
|
||||||
|
strncpy(args->post, optarg, ZPIOS_PATH_SIZE - 1);
|
||||||
|
break;
|
||||||
|
case 'G': /* --log */
|
||||||
|
strncpy(args->log, optarg, ZPIOS_PATH_SIZE - 1);
|
||||||
|
break;
|
||||||
|
case 'I': /* --regionnoise */
|
||||||
|
rc = set_noise(&args->regionnoise, optarg,
|
||||||
|
"regionnoise");
|
||||||
|
break;
|
||||||
|
case 'N': /* --chunknoise */
|
||||||
|
rc = set_noise(&args->chunknoise, optarg, "chunknoise");
|
||||||
|
break;
|
||||||
|
case 'T': /* --threaddelay */
|
||||||
|
rc = set_noise(&args->thread_delay, optarg,
|
||||||
|
"threaddelay");
|
||||||
|
break;
|
||||||
|
case 'V': /* --verify */
|
||||||
|
args->flags |= DMU_VERIFY;
|
||||||
|
break;
|
||||||
|
case 'z': /* --zerocopy */
|
||||||
|
args->flags |= (DMU_WRITE_ZC | DMU_READ_ZC);
|
||||||
|
break;
|
||||||
|
case 'O': /* --nowait */
|
||||||
|
args->flags |= DMU_WRITE_NOWAIT;
|
||||||
|
break;
|
||||||
|
case 'f': /* --noprefetch */
|
||||||
|
args->flags |= DMU_READ_NOPF;
|
||||||
|
break;
|
||||||
|
case 'H': /* --human-readable */
|
||||||
|
args->human_readable = 1;
|
||||||
|
break;
|
||||||
|
case 'v': /* --verbose */
|
||||||
|
args->verbose++;
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
rc = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unknown option '%s'\n",
|
||||||
|
argv[optind - 1]);
|
||||||
|
rc = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
usage();
|
||||||
|
args_fini(args);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check_mutual_exclusive_command_lines(fl_th, "threadcount");
|
||||||
|
check_mutual_exclusive_command_lines(fl_rc, "regioncount");
|
||||||
|
check_mutual_exclusive_command_lines(fl_of, "offset");
|
||||||
|
check_mutual_exclusive_command_lines(fl_rs, "regionsize");
|
||||||
|
check_mutual_exclusive_command_lines(fl_cs, "chunksize");
|
||||||
|
|
||||||
|
if (args->pool == NULL) {
|
||||||
|
fprintf(stderr, "Error: Pool not specified\n");
|
||||||
|
usage();
|
||||||
|
args_fini(args);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((args->flags & (DMU_WRITE_ZC | DMU_READ_ZC)) &&
|
||||||
|
(args->flags & DMU_VERIFY)) {
|
||||||
|
fprintf(stderr, "Error, --zerocopy incompatible --verify, "
|
||||||
|
"used for performance analysis only\n");
|
||||||
|
usage();
|
||||||
|
args_fini(args);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* validate block size(s) */
|
||||||
|
for (i = 0; i < args->B.val_count; i++) {
|
||||||
|
int bs = args->B.val[i];
|
||||||
|
|
||||||
|
if (bs < MIN_BLKSIZE || bs > MAX_BLKSIZE || !POW_OF_TWO(bs)) {
|
||||||
|
fprintf(stderr, "Error: invalid block size %d\n", bs);
|
||||||
|
args_fini(args);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dev_clear(void)
|
||||||
|
{
|
||||||
|
zpios_cfg_t cfg;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
memset(&cfg, 0, sizeof (cfg));
|
||||||
|
cfg.cfg_magic = ZPIOS_CFG_MAGIC;
|
||||||
|
cfg.cfg_cmd = ZPIOS_CFG_BUFFER_CLEAR;
|
||||||
|
cfg.cfg_arg1 = 0;
|
||||||
|
|
||||||
|
rc = ioctl(zpiosctl_fd, ZPIOS_CFG, &cfg);
|
||||||
|
if (rc)
|
||||||
|
fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
|
||||||
|
(unsigned long) ZPIOS_CFG, cfg.cfg_cmd, errno);
|
||||||
|
|
||||||
|
(void) lseek(zpiosctl_fd, 0, SEEK_SET);
|
||||||
|
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Passing a size of zero simply results in querying the current size */
|
||||||
|
static int
|
||||||
|
dev_size(int size)
|
||||||
|
{
|
||||||
|
zpios_cfg_t cfg;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
memset(&cfg, 0, sizeof (cfg));
|
||||||
|
cfg.cfg_magic = ZPIOS_CFG_MAGIC;
|
||||||
|
cfg.cfg_cmd = ZPIOS_CFG_BUFFER_SIZE;
|
||||||
|
cfg.cfg_arg1 = size;
|
||||||
|
|
||||||
|
rc = ioctl(zpiosctl_fd, ZPIOS_CFG, &cfg);
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
|
||||||
|
(unsigned long) ZPIOS_CFG, cfg.cfg_cmd, errno);
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (cfg.cfg_rc1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_fini(void)
|
||||||
|
{
|
||||||
|
if (zpios_buffer)
|
||||||
|
free(zpios_buffer);
|
||||||
|
|
||||||
|
if (zpiosctl_fd != -1) {
|
||||||
|
if (close(zpiosctl_fd) == -1) {
|
||||||
|
fprintf(stderr, "Unable to close %s: %d\n",
|
||||||
|
ZPIOS_DEV, errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dev_init(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
zpiosctl_fd = open(ZPIOS_DEV, O_RDONLY);
|
||||||
|
if (zpiosctl_fd == -1) {
|
||||||
|
fprintf(stderr, "Unable to open %s: %d\n"
|
||||||
|
"Is the zpios module loaded?\n", ZPIOS_DEV, errno);
|
||||||
|
rc = errno;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rc = dev_clear()))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if ((rc = dev_size(0)) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
zpios_buffer_size = rc;
|
||||||
|
zpios_buffer = (char *)malloc(zpios_buffer_size);
|
||||||
|
if (zpios_buffer == NULL) {
|
||||||
|
rc = ENOMEM;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(zpios_buffer, 0, zpios_buffer_size);
|
||||||
|
return (0);
|
||||||
|
error:
|
||||||
|
if (zpiosctl_fd != -1) {
|
||||||
|
if (close(zpiosctl_fd) == -1) {
|
||||||
|
fprintf(stderr, "Unable to close %s: %d\n",
|
||||||
|
ZPIOS_DEV, errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_next(uint64_t *val, range_repeat_t *range)
|
||||||
|
{
|
||||||
|
/* if low, incr, high is given */
|
||||||
|
if (range->val_count == 0) {
|
||||||
|
*val = (range->val_low) +
|
||||||
|
(range->val_low * range->next_val / 100);
|
||||||
|
|
||||||
|
if (*val > range->val_high)
|
||||||
|
return (0); /* No more values, limit exceeded */
|
||||||
|
|
||||||
|
if (!range->next_val)
|
||||||
|
range->next_val = range->val_inc_perc;
|
||||||
|
else
|
||||||
|
range->next_val = range->next_val + range->val_inc_perc;
|
||||||
|
|
||||||
|
return (1); /* more values to come */
|
||||||
|
|
||||||
|
/* if only one val is given */
|
||||||
|
} else if (range->val_count == 1) {
|
||||||
|
if (range->next_val)
|
||||||
|
return (0); /* No more values, we only have one */
|
||||||
|
|
||||||
|
*val = range->val[0];
|
||||||
|
range->next_val = 1;
|
||||||
|
return (1); /* more values to come */
|
||||||
|
|
||||||
|
/* if comma separated values are given */
|
||||||
|
} else if (range->val_count > 1) {
|
||||||
|
if (range->next_val > range->val_count - 1)
|
||||||
|
return (0); /* No more values, limit exceeded */
|
||||||
|
|
||||||
|
*val = range->val[range->next_val];
|
||||||
|
range->next_val++;
|
||||||
|
return (1); /* more values to come */
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
run_one(cmd_args_t *args, uint32_t id, uint32_t T, uint32_t N,
|
||||||
|
uint64_t C, uint64_t S, uint64_t O, uint64_t B)
|
||||||
|
{
|
||||||
|
zpios_cmd_t *cmd;
|
||||||
|
int rc, rc2, cmd_size;
|
||||||
|
|
||||||
|
dev_clear();
|
||||||
|
|
||||||
|
cmd_size = sizeof (zpios_cmd_t) +
|
||||||
|
((T + N + 1) * sizeof (zpios_stats_t));
|
||||||
|
cmd = (zpios_cmd_t *)malloc(cmd_size);
|
||||||
|
if (cmd == NULL)
|
||||||
|
return (ENOMEM);
|
||||||
|
|
||||||
|
memset(cmd, 0, cmd_size);
|
||||||
|
cmd->cmd_magic = ZPIOS_CMD_MAGIC;
|
||||||
|
snprintf(cmd->cmd_pool, sizeof (cmd->cmd_pool), "%s", args->pool);
|
||||||
|
snprintf(cmd->cmd_pre, sizeof (cmd->cmd_pre), "%s", args->pre);
|
||||||
|
snprintf(cmd->cmd_post, sizeof (cmd->cmd_post), "%s", args->post);
|
||||||
|
snprintf(cmd->cmd_log, sizeof (cmd->cmd_log), "%s", args->log);
|
||||||
|
|
||||||
|
cmd->cmd_id = id;
|
||||||
|
cmd->cmd_chunk_size = C;
|
||||||
|
cmd->cmd_thread_count = T;
|
||||||
|
cmd->cmd_region_count = N;
|
||||||
|
cmd->cmd_region_size = S;
|
||||||
|
cmd->cmd_offset = O;
|
||||||
|
cmd->cmd_block_size = B;
|
||||||
|
cmd->cmd_region_noise = args->regionnoise;
|
||||||
|
cmd->cmd_chunk_noise = args->chunknoise;
|
||||||
|
cmd->cmd_thread_delay = args->thread_delay;
|
||||||
|
cmd->cmd_flags = args->flags;
|
||||||
|
cmd->cmd_data_size = (T + N + 1) * sizeof (zpios_stats_t);
|
||||||
|
|
||||||
|
rc = ioctl(zpiosctl_fd, ZPIOS_CMD, cmd);
|
||||||
|
if (rc)
|
||||||
|
args->rc = errno;
|
||||||
|
|
||||||
|
print_stats(args, cmd);
|
||||||
|
|
||||||
|
if (args->verbose) {
|
||||||
|
rc2 = read(zpiosctl_fd, zpios_buffer, zpios_buffer_size);
|
||||||
|
zpios_buffer[zpios_buffer_size - 1] = '\0';
|
||||||
|
if (rc2 < 0) {
|
||||||
|
fprintf(stdout, "Error reading results: %d\n", rc2);
|
||||||
|
} else if ((rc2 > 0) && (strlen(zpios_buffer) > 0)) {
|
||||||
|
fprintf(stdout, "\n%s\n", zpios_buffer);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(cmd);
|
||||||
|
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
run_offsets(cmd_args_t *args)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
while (rc == 0 && get_next(&args->current_O, &args->O)) {
|
||||||
|
rc = run_one(args, args->current_id,
|
||||||
|
args->current_T, args->current_N, args->current_C,
|
||||||
|
args->current_S, args->current_O, args->current_B);
|
||||||
|
args->current_id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
args->O.next_val = 0;
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
run_region_counts(cmd_args_t *args)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
while (rc == 0 && get_next((uint64_t *)&args->current_N, &args->N))
|
||||||
|
rc = run_offsets(args);
|
||||||
|
|
||||||
|
args->N.next_val = 0;
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
run_region_sizes(cmd_args_t *args)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
while (rc == 0 && get_next(&args->current_S, &args->S)) {
|
||||||
|
if (args->current_S < args->current_C) {
|
||||||
|
fprintf(stderr, "Error: in any run chunksize must "
|
||||||
|
"be strictly smaller than regionsize.\n");
|
||||||
|
return (EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = run_region_counts(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
args->S.next_val = 0;
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
run_chunk_sizes(cmd_args_t *args)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
while (rc == 0 && get_next(&args->current_C, &args->C)) {
|
||||||
|
rc = run_region_sizes(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
args->C.next_val = 0;
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
run_block_sizes(cmd_args_t *args)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
while (rc == 0 && get_next(&args->current_B, &args->B)) {
|
||||||
|
rc = run_chunk_sizes(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
args->B.next_val = 0;
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
run_thread_counts(cmd_args_t *args)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
while (rc == 0 && get_next((uint64_t *)&args->current_T, &args->T))
|
||||||
|
rc = run_block_sizes(args);
|
||||||
|
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
cmd_args_t *args;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
/* Argument init and parsing */
|
||||||
|
if ((args = args_init(argc, argv)) == NULL) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Device specific init */
|
||||||
|
if ((rc = dev_init()))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Generic kernel version string */
|
||||||
|
if (args->verbose)
|
||||||
|
fprintf(stdout, "%s", zpios_version);
|
||||||
|
|
||||||
|
print_stats_header(args);
|
||||||
|
rc = run_thread_counts(args);
|
||||||
|
out:
|
||||||
|
if (args != NULL)
|
||||||
|
args_fini(args);
|
||||||
|
|
||||||
|
dev_fini();
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
@@ -0,0 +1,476 @@
|
|||||||
|
/*
|
||||||
|
* ZPIOS is a heavily modified version of the original PIOS test code.
|
||||||
|
* It is designed to have the test code running in the Linux kernel
|
||||||
|
* against ZFS while still being flexibly controlled from user space.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008-2010 Lawrence Livermore National Security, LLC.
|
||||||
|
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
||||||
|
* Written by Brian Behlendorf <behlendorf1@llnl.gov>.
|
||||||
|
* LLNL-CODE-403049
|
||||||
|
*
|
||||||
|
* Original PIOS Test Code
|
||||||
|
* Copyright (C) 2004 Cluster File Systems, Inc.
|
||||||
|
* Written by Peter Braam <braam@clusterfs.com>
|
||||||
|
* Atul Vidwansa <atul@clusterfs.com>
|
||||||
|
* Milind Dumbare <milind@clusterfs.com>
|
||||||
|
*
|
||||||
|
* This file is part of ZFS on Linux.
|
||||||
|
* For details, see <http://zfsonlinux.org/>.
|
||||||
|
*
|
||||||
|
* ZPIOS is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* ZPIOS is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015, Intel Corporation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include "zpios.h"
|
||||||
|
|
||||||
|
/* extracts an unsigned int (64) and K,M,G,T from the string */
|
||||||
|
/* and returns a 64 bit value converted to the proper units */
|
||||||
|
static int
|
||||||
|
kmgt_to_uint64(const char *str, uint64_t *val)
|
||||||
|
{
|
||||||
|
char *endptr;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
*val = strtoll(str, &endptr, 0);
|
||||||
|
if ((str == endptr) && (*val == 0))
|
||||||
|
return (EINVAL);
|
||||||
|
|
||||||
|
switch (endptr[0]) {
|
||||||
|
case 'k': case 'K':
|
||||||
|
*val = (*val) << 10;
|
||||||
|
break;
|
||||||
|
case 'm': case 'M':
|
||||||
|
*val = (*val) << 20;
|
||||||
|
break;
|
||||||
|
case 'g': case 'G':
|
||||||
|
*val = (*val) << 30;
|
||||||
|
break;
|
||||||
|
case 't': case 'T':
|
||||||
|
*val = (*val) << 40;
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rc = EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
uint64_to_kmgt(char *str, uint64_t val)
|
||||||
|
{
|
||||||
|
char postfix[] = "kmgt";
|
||||||
|
int i = -1;
|
||||||
|
|
||||||
|
while ((val >= KB) && (i < 4)) {
|
||||||
|
val = (val >> 10);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= 4)
|
||||||
|
(void) snprintf(str, KMGT_SIZE-1, "inf");
|
||||||
|
else
|
||||||
|
(void) snprintf(str, KMGT_SIZE-1, "%lu%c", (unsigned long)val,
|
||||||
|
(i == -1) ? '\0' : postfix[i]);
|
||||||
|
|
||||||
|
return (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
kmgt_per_sec(char *str, uint64_t v, double t)
|
||||||
|
{
|
||||||
|
char postfix[] = "kmgt";
|
||||||
|
double val = ((double)v) / t;
|
||||||
|
int i = -1;
|
||||||
|
|
||||||
|
while ((val >= (double)KB) && (i < 4)) {
|
||||||
|
val /= (double)KB;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= 4)
|
||||||
|
(void) snprintf(str, KMGT_SIZE-1, "inf");
|
||||||
|
else
|
||||||
|
(void) snprintf(str, KMGT_SIZE-1, "%.2f%c", val,
|
||||||
|
(i == -1) ? '\0' : postfix[i]);
|
||||||
|
|
||||||
|
return (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
print_flags(char *str, uint32_t flags)
|
||||||
|
{
|
||||||
|
str[0] = (flags & DMU_WRITE) ? 'w' : '-';
|
||||||
|
str[1] = (flags & DMU_READ) ? 'r' : '-';
|
||||||
|
str[2] = (flags & DMU_VERIFY) ? 'v' : '-';
|
||||||
|
str[3] = (flags & DMU_REMOVE) ? 'c' : '-';
|
||||||
|
str[4] = (flags & DMU_FPP) ? 'p' : 's';
|
||||||
|
str[5] = (flags & (DMU_WRITE_ZC | DMU_READ_ZC)) ? 'z' : '-';
|
||||||
|
str[6] = (flags & DMU_WRITE_NOWAIT) ? 'O' : '-';
|
||||||
|
str[7] = '\0';
|
||||||
|
|
||||||
|
return (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
regex_match(const char *string, char *pattern)
|
||||||
|
{
|
||||||
|
regex_t re = { 0 };
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB | REG_ICASE);
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stderr, "Error: Couldn't do regcomp, %d\n", rc);
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = regexec(&re, string, (size_t)0, NULL, 0);
|
||||||
|
regfree(&re);
|
||||||
|
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fills the pios_range_repeat structure of comma separated values */
|
||||||
|
static int
|
||||||
|
split_string(const char *optarg, char *pattern, range_repeat_t *range)
|
||||||
|
{
|
||||||
|
const char comma[] = ",";
|
||||||
|
char *cp, *token[32];
|
||||||
|
int rc, i = 0;
|
||||||
|
|
||||||
|
if ((rc = regex_match(optarg, pattern)))
|
||||||
|
return (rc);
|
||||||
|
|
||||||
|
cp = strdup(optarg);
|
||||||
|
if (cp == NULL)
|
||||||
|
return (ENOMEM);
|
||||||
|
|
||||||
|
do {
|
||||||
|
/*
|
||||||
|
* STRTOK(3) Each subsequent call, with a null pointer as the
|
||||||
|
* value of the * first argument, starts searching from the
|
||||||
|
* saved pointer and behaves as described above.
|
||||||
|
*/
|
||||||
|
if (i == 0) {
|
||||||
|
token[i] = strtok(cp, comma);
|
||||||
|
} else {
|
||||||
|
token[i] = strtok(NULL, comma);
|
||||||
|
}
|
||||||
|
} while ((token[i++] != NULL) && (i < 32));
|
||||||
|
|
||||||
|
range->val_count = i - 1;
|
||||||
|
|
||||||
|
for (i = 0; i < range->val_count; i++)
|
||||||
|
kmgt_to_uint64(token[i], &range->val[i]);
|
||||||
|
|
||||||
|
free(cp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
set_count(char *pattern1, char *pattern2, range_repeat_t *range,
|
||||||
|
char *optarg, uint32_t *flags, char *arg)
|
||||||
|
{
|
||||||
|
uint64_t count = range->val_count;
|
||||||
|
|
||||||
|
if (flags)
|
||||||
|
*flags |= FLAG_SET;
|
||||||
|
|
||||||
|
range->next_val = 0;
|
||||||
|
|
||||||
|
if (regex_match(optarg, pattern1) == 0) {
|
||||||
|
kmgt_to_uint64(optarg, &range->val[0]);
|
||||||
|
range->val_count = 1;
|
||||||
|
} else if (split_string(optarg, pattern2, range) < 0) {
|
||||||
|
fprintf(stderr, "Error: Incorrect pattern for %s, '%s'\n",
|
||||||
|
arg, optarg);
|
||||||
|
return (EINVAL);
|
||||||
|
} else if (count == range->val_count) {
|
||||||
|
fprintf(stderr, "Error: input ignored for %s, '%s'\n",
|
||||||
|
arg, optarg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validates the value with regular expression and sets low, high, incr
|
||||||
|
* according to value at which flag will be set. Sets the flag after.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
set_lhi(char *pattern, range_repeat_t *range, char *optarg,
|
||||||
|
int flag, uint32_t *flag_thread, char *arg)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if ((rc = regex_match(optarg, pattern))) {
|
||||||
|
fprintf(stderr, "Error: Wrong pattern in %s, '%s'\n",
|
||||||
|
arg, optarg);
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flag) {
|
||||||
|
case FLAG_LOW:
|
||||||
|
kmgt_to_uint64(optarg, &range->val_low);
|
||||||
|
break;
|
||||||
|
case FLAG_HIGH:
|
||||||
|
kmgt_to_uint64(optarg, &range->val_high);
|
||||||
|
break;
|
||||||
|
case FLAG_INCR:
|
||||||
|
kmgt_to_uint64(optarg, &range->val_inc_perc);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
*flag_thread |= flag;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
set_noise(uint64_t *noise, char *optarg, char *arg)
|
||||||
|
{
|
||||||
|
if (regex_match(optarg, REGEX_NUMBERS) == 0) {
|
||||||
|
kmgt_to_uint64(optarg, noise);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Error: Incorrect pattern for %s\n", arg);
|
||||||
|
return (EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
set_load_params(cmd_args_t *args, char *optarg)
|
||||||
|
{
|
||||||
|
char *param, *search, *searchdup, comma[] = ",";
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
search = strdup(optarg);
|
||||||
|
if (search == NULL)
|
||||||
|
return (ENOMEM);
|
||||||
|
searchdup = search;
|
||||||
|
|
||||||
|
while ((param = strtok(search, comma)) != NULL) {
|
||||||
|
search = NULL;
|
||||||
|
|
||||||
|
if (strcmp("fpp", param) == 0) {
|
||||||
|
args->flags |= DMU_FPP; /* File Per Process/Thread */
|
||||||
|
} else if (strcmp("ssf", param) == 0) {
|
||||||
|
args->flags &= ~DMU_FPP; /* Single Shared File */
|
||||||
|
} else if (strcmp("dmuio", param) == 0) {
|
||||||
|
args->io_type |= DMU_IO;
|
||||||
|
args->flags |= (DMU_WRITE | DMU_READ);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Invalid load: %s\n", param);
|
||||||
|
rc = EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(searchdup);
|
||||||
|
|
||||||
|
return (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks the low, high, increment values against the single value for
|
||||||
|
* mutual exclusion, for e.g threadcount is mutually exclusive to
|
||||||
|
* threadcount_low, ..._high, ..._incr
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
check_mutual_exclusive_command_lines(uint32_t flag, char *arg)
|
||||||
|
{
|
||||||
|
if ((flag & FLAG_SET) && (flag & (FLAG_LOW | FLAG_HIGH | FLAG_INCR))) {
|
||||||
|
fprintf(stderr, "Error: --%s can not be given with --%s_low, "
|
||||||
|
"--%s_high or --%s_incr.\n", arg, arg, arg, arg);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flag & (FLAG_LOW | FLAG_HIGH | FLAG_INCR)) && !(flag & FLAG_SET)) {
|
||||||
|
if (flag != (FLAG_LOW | FLAG_HIGH | FLAG_INCR)) {
|
||||||
|
fprintf(stderr, "Error: One or more values missing "
|
||||||
|
"from --%s_low, --%s_high, --%s_incr.\n",
|
||||||
|
arg, arg, arg);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_stats_header(cmd_args_t *args)
|
||||||
|
{
|
||||||
|
if (args->verbose) {
|
||||||
|
printf(
|
||||||
|
"status name id\tth-cnt\trg-cnt\trg-sz\t"
|
||||||
|
"ch-sz\toffset\trg-no\tch-no\tth-dly\tflags\tblksz\ttime\t"
|
||||||
|
"cr-time\trm-time\twr-time\trd-time\twr-data\twr-ch\t"
|
||||||
|
"wr-bw\trd-data\trd-ch\trd-bw\n");
|
||||||
|
printf(
|
||||||
|
"-------------------------------------------------"
|
||||||
|
"-------------------------------------------------"
|
||||||
|
"-------------------------------------------------"
|
||||||
|
"--------------------------------------------------\n");
|
||||||
|
} else {
|
||||||
|
printf(
|
||||||
|
"status name id\t"
|
||||||
|
"wr-data\twr-ch\twr-bw\t"
|
||||||
|
"rd-data\trd-ch\trd-bw\n");
|
||||||
|
printf(
|
||||||
|
"-----------------------------------------"
|
||||||
|
"--------------------------------------\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_stats_human_readable(cmd_args_t *args, zpios_cmd_t *cmd)
|
||||||
|
{
|
||||||
|
zpios_stats_t *summary_stats;
|
||||||
|
double t_time, wr_time, rd_time, cr_time, rm_time;
|
||||||
|
char str[KMGT_SIZE];
|
||||||
|
|
||||||
|
if (args->rc)
|
||||||
|
printf("FAIL: %3d ", args->rc);
|
||||||
|
else
|
||||||
|
printf("PASS: ");
|
||||||
|
|
||||||
|
printf("%-12s", args->name ? args->name : ZPIOS_NAME);
|
||||||
|
printf("%2u\t", cmd->cmd_id);
|
||||||
|
|
||||||
|
if (args->verbose) {
|
||||||
|
printf("%u\t", cmd->cmd_thread_count);
|
||||||
|
printf("%u\t", cmd->cmd_region_count);
|
||||||
|
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_region_size));
|
||||||
|
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_chunk_size));
|
||||||
|
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_offset));
|
||||||
|
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_region_noise));
|
||||||
|
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_chunk_noise));
|
||||||
|
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_thread_delay));
|
||||||
|
printf("%s\t", print_flags(str, cmd->cmd_flags));
|
||||||
|
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_block_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->rc) {
|
||||||
|
printf("\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
summary_stats = (zpios_stats_t *)cmd->cmd_data_str;
|
||||||
|
t_time = zpios_timespec_to_double(summary_stats->total_time.delta);
|
||||||
|
wr_time = zpios_timespec_to_double(summary_stats->wr_time.delta);
|
||||||
|
rd_time = zpios_timespec_to_double(summary_stats->rd_time.delta);
|
||||||
|
cr_time = zpios_timespec_to_double(summary_stats->cr_time.delta);
|
||||||
|
rm_time = zpios_timespec_to_double(summary_stats->rm_time.delta);
|
||||||
|
|
||||||
|
if (args->verbose) {
|
||||||
|
printf("%.2f\t", t_time);
|
||||||
|
printf("%.3f\t", cr_time);
|
||||||
|
printf("%.3f\t", rm_time);
|
||||||
|
printf("%.2f\t", wr_time);
|
||||||
|
printf("%.2f\t", rd_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\t", uint64_to_kmgt(str, summary_stats->wr_data));
|
||||||
|
printf("%s\t", uint64_to_kmgt(str, summary_stats->wr_chunks));
|
||||||
|
printf("%s\t", kmgt_per_sec(str, summary_stats->wr_data, wr_time));
|
||||||
|
|
||||||
|
printf("%s\t", uint64_to_kmgt(str, summary_stats->rd_data));
|
||||||
|
printf("%s\t", uint64_to_kmgt(str, summary_stats->rd_chunks));
|
||||||
|
printf("%s\n", kmgt_per_sec(str, summary_stats->rd_data, rd_time));
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_stats_table(cmd_args_t *args, zpios_cmd_t *cmd)
|
||||||
|
{
|
||||||
|
zpios_stats_t *summary_stats;
|
||||||
|
double wr_time, rd_time;
|
||||||
|
|
||||||
|
if (args->rc)
|
||||||
|
printf("FAIL: %3d ", args->rc);
|
||||||
|
else
|
||||||
|
printf("PASS: ");
|
||||||
|
|
||||||
|
printf("%-12s", args->name ? args->name : ZPIOS_NAME);
|
||||||
|
printf("%2u\t", cmd->cmd_id);
|
||||||
|
|
||||||
|
if (args->verbose) {
|
||||||
|
printf("%u\t", cmd->cmd_thread_count);
|
||||||
|
printf("%u\t", cmd->cmd_region_count);
|
||||||
|
printf("%llu\t", (long long unsigned)cmd->cmd_region_size);
|
||||||
|
printf("%llu\t", (long long unsigned)cmd->cmd_chunk_size);
|
||||||
|
printf("%llu\t", (long long unsigned)cmd->cmd_offset);
|
||||||
|
printf("%u\t", cmd->cmd_region_noise);
|
||||||
|
printf("%u\t", cmd->cmd_chunk_noise);
|
||||||
|
printf("%u\t", cmd->cmd_thread_delay);
|
||||||
|
printf("0x%x\t", cmd->cmd_flags);
|
||||||
|
printf("%u\t", cmd->cmd_block_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->rc) {
|
||||||
|
printf("\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
summary_stats = (zpios_stats_t *)cmd->cmd_data_str;
|
||||||
|
wr_time = zpios_timespec_to_double(summary_stats->wr_time.delta);
|
||||||
|
rd_time = zpios_timespec_to_double(summary_stats->rd_time.delta);
|
||||||
|
|
||||||
|
if (args->verbose) {
|
||||||
|
printf("%ld.%02ld\t",
|
||||||
|
(long)summary_stats->total_time.delta.ts_sec,
|
||||||
|
(long)summary_stats->total_time.delta.ts_nsec);
|
||||||
|
printf("%ld.%02ld\t",
|
||||||
|
(long)summary_stats->cr_time.delta.ts_sec,
|
||||||
|
(long)summary_stats->cr_time.delta.ts_nsec);
|
||||||
|
printf("%ld.%02ld\t",
|
||||||
|
(long)summary_stats->rm_time.delta.ts_sec,
|
||||||
|
(long)summary_stats->rm_time.delta.ts_nsec);
|
||||||
|
printf("%ld.%02ld\t",
|
||||||
|
(long)summary_stats->wr_time.delta.ts_sec,
|
||||||
|
(long)summary_stats->wr_time.delta.ts_nsec);
|
||||||
|
printf("%ld.%02ld\t",
|
||||||
|
(long)summary_stats->rd_time.delta.ts_sec,
|
||||||
|
(long)summary_stats->rd_time.delta.ts_nsec);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%lld\t", (long long unsigned)summary_stats->wr_data);
|
||||||
|
printf("%lld\t", (long long unsigned)summary_stats->wr_chunks);
|
||||||
|
printf("%.4f\t", (double)summary_stats->wr_data / wr_time);
|
||||||
|
|
||||||
|
printf("%lld\t", (long long unsigned)summary_stats->rd_data);
|
||||||
|
printf("%lld\t", (long long unsigned)summary_stats->rd_chunks);
|
||||||
|
printf("%.4f\n", (double)summary_stats->rd_data / rd_time);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_stats(cmd_args_t *args, zpios_cmd_t *cmd)
|
||||||
|
{
|
||||||
|
if (args->human_readable)
|
||||||
|
print_stats_human_readable(args, cmd);
|
||||||
|
else
|
||||||
|
print_stats_table(args, cmd);
|
||||||
|
}
|
||||||
@@ -16,12 +16,13 @@ zpool_SOURCES = \
|
|||||||
zpool_LDADD = \
|
zpool_LDADD = \
|
||||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
$(top_builddir)/lib/libuutil/libuutil.la \
|
$(top_builddir)/lib/libuutil/libuutil.la \
|
||||||
$(top_builddir)/lib/libzfs/libzfs.la
|
$(top_builddir)/lib/libzpool/libzpool.la \
|
||||||
|
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||||
zpool_LDADD += -lm $(LIBBLKID)
|
$(top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||||
|
-lm $(LIBBLKID)
|
||||||
|
|
||||||
zpoolconfdir = $(sysconfdir)/zfs/zpool.d
|
zpoolconfdir = $(sysconfdir)/zfs/zpool.d
|
||||||
zpoolexecdir = $(zfsexecdir)/zpool.d
|
zpoolexecdir = $(libexecdir)/zfs/zpool.d
|
||||||
|
|
||||||
EXTRA_DIST = zpool.d/README
|
EXTRA_DIST = zpool.d/README
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ if [ "$1" = "-h" ] ; then
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
smartctl_path=$(command -v smartctl)
|
smartctl_path=$(which smartctl)
|
||||||
|
|
||||||
if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ] || [ -n "$samples" ] ; then
|
if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ] || [ -n "$samples" ] ; then
|
||||||
if [ -n "$samples" ] ; then
|
if [ -n "$samples" ] ; then
|
||||||
@@ -228,7 +228,7 @@ smart_test)
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
with_vals=$(echo "$out" | grep -E "$scripts")
|
with_vals=$(echo "$out" | grep -E "$scripts")
|
||||||
if [ -n "$with_vals" ]; then
|
if [ ! -z "$with_vals" ]; then
|
||||||
echo "$with_vals"
|
echo "$with_vals"
|
||||||
without_vals=$(echo "$scripts" | tr "|" "\n" |
|
without_vals=$(echo "$scripts" | tr "|" "\n" |
|
||||||
grep -v -E "$(echo "$with_vals" |
|
grep -v -E "$(echo "$with_vals" |
|
||||||
@@ -237,6 +237,6 @@ else
|
|||||||
without_vals=$(echo "$scripts" | tr "|" "\n" | awk '{print $0"="}')
|
without_vals=$(echo "$scripts" | tr "|" "\n" | awk '{print $0"="}')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$without_vals" ]; then
|
if [ ! -z "$without_vals" ]; then
|
||||||
echo "$without_vals"
|
echo "$without_vals"
|
||||||
fi
|
fi
|
||||||
|
|||||||
+20
-9
@@ -33,10 +33,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <thread_pool.h>
|
|
||||||
|
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
#include <libzutil.h>
|
|
||||||
#include <sys/zfs_context.h>
|
#include <sys/zfs_context.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
@@ -670,21 +668,34 @@ all_pools_for_each_vdev_gather_cb(zpool_handle_t *zhp, void *cb_vcdl)
|
|||||||
static void
|
static void
|
||||||
all_pools_for_each_vdev_run_vcdl(vdev_cmd_data_list_t *vcdl)
|
all_pools_for_each_vdev_run_vcdl(vdev_cmd_data_list_t *vcdl)
|
||||||
{
|
{
|
||||||
tpool_t *t;
|
taskq_t *t;
|
||||||
|
int i;
|
||||||
|
/* 5 * boot_ncpus selfishly chosen since it works best on LLNL's HW */
|
||||||
|
int max_threads = 5 * boot_ncpus;
|
||||||
|
|
||||||
t = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN), 0, NULL);
|
/*
|
||||||
|
* Under Linux we use a taskq to parallelize running a command
|
||||||
|
* on each vdev. It is therefore necessary to initialize this
|
||||||
|
* functionality for the duration of the threads.
|
||||||
|
*/
|
||||||
|
thread_init();
|
||||||
|
|
||||||
|
t = taskq_create("z_pool_cmd", max_threads, defclsyspri, max_threads,
|
||||||
|
INT_MAX, 0);
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Spawn off the command for each vdev */
|
/* Spawn off the command for each vdev */
|
||||||
for (int i = 0; i < vcdl->count; i++) {
|
for (i = 0; i < vcdl->count; i++) {
|
||||||
(void) tpool_dispatch(t, vdev_run_cmd_thread,
|
(void) taskq_dispatch(t, vdev_run_cmd_thread,
|
||||||
(void *) &vcdl->data[i]);
|
(void *) &vcdl->data[i], TQ_SLEEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for threads to finish */
|
/* Wait for threads to finish */
|
||||||
tpool_wait(t);
|
taskq_wait(t);
|
||||||
tpool_destroy(t);
|
taskq_destroy(t);
|
||||||
|
thread_fini();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+345
-1650
File diff suppressed because it is too large
Load Diff
@@ -111,29 +111,3 @@ isnumber(char *str)
|
|||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Find highest one bit set.
|
|
||||||
* Returns bit number + 1 of highest bit that is set, otherwise returns 0.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
highbit64(uint64_t i)
|
|
||||||
{
|
|
||||||
if (i == 0)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
return (NBBY * sizeof (uint64_t) - __builtin_clzll(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find lowest one bit set.
|
|
||||||
* Returns bit number + 1 of lowest bit that is set, otherwise returns 0.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
lowbit64(uint64_t i)
|
|
||||||
{
|
|
||||||
if (i == 0)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
return (__builtin_ffsll(i));
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ void zpool_no_memory(void);
|
|||||||
uint_t num_logs(nvlist_t *nv);
|
uint_t num_logs(nvlist_t *nv);
|
||||||
uint64_t array64_max(uint64_t array[], unsigned int len);
|
uint64_t array64_max(uint64_t array[], unsigned int len);
|
||||||
int isnumber(char *str);
|
int isnumber(char *str);
|
||||||
int highbit64(uint64_t i);
|
|
||||||
int lowbit64(uint64_t i);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Misc utility functions
|
* Misc utility functions
|
||||||
@@ -80,7 +78,7 @@ void pool_list_free(zpool_list_t *);
|
|||||||
int pool_list_count(zpool_list_t *);
|
int pool_list_count(zpool_list_t *);
|
||||||
void pool_list_remove(zpool_list_t *, zpool_handle_t *);
|
void pool_list_remove(zpool_list_t *, zpool_handle_t *);
|
||||||
|
|
||||||
extern libzfs_handle_t *g_zfs;
|
libzfs_handle_t *g_zfs;
|
||||||
|
|
||||||
|
|
||||||
typedef struct vdev_cmd_data
|
typedef struct vdev_cmd_data
|
||||||
|
|||||||
+19
-120
@@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2013, 2018 by Delphix. All rights reserved.
|
* Copyright (c) 2013, 2015 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2016, 2017 Intel Corporation.
|
* Copyright (c) 2016 Intel Corporation.
|
||||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
|
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -69,7 +69,6 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#include <libnvpair.h>
|
#include <libnvpair.h>
|
||||||
#include <libzutil.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <sys/spa.h>
|
#include <sys/spa.h>
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
@@ -189,7 +188,6 @@ static vdev_disk_db_entry_t vdev_disk_database[] = {
|
|||||||
{"ATA INTEL SSDSC2BB60", 4096},
|
{"ATA INTEL SSDSC2BB60", 4096},
|
||||||
{"ATA INTEL SSDSC2BB80", 4096},
|
{"ATA INTEL SSDSC2BB80", 4096},
|
||||||
{"ATA INTEL SSDSC2BW24", 4096},
|
{"ATA INTEL SSDSC2BW24", 4096},
|
||||||
{"ATA INTEL SSDSC2BW48", 4096},
|
|
||||||
{"ATA INTEL SSDSC2BP24", 4096},
|
{"ATA INTEL SSDSC2BP24", 4096},
|
||||||
{"ATA INTEL SSDSC2BP48", 4096},
|
{"ATA INTEL SSDSC2BP48", 4096},
|
||||||
{"NA SmrtStorSDLKAE9W", 4096},
|
{"NA SmrtStorSDLKAE9W", 4096},
|
||||||
@@ -420,25 +418,19 @@ check_disk(const char *path, blkid_cache cache, int force,
|
|||||||
char slice_path[MAXPATHLEN];
|
char slice_path[MAXPATHLEN];
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int fd, i;
|
int fd, i;
|
||||||
int flags = O_RDONLY|O_DIRECT;
|
|
||||||
|
|
||||||
if (!iswholedisk)
|
if (!iswholedisk)
|
||||||
return (check_slice(path, cache, force, isspare));
|
return (check_slice(path, cache, force, isspare));
|
||||||
|
|
||||||
/* only spares can be shared, other devices require exclusive access */
|
if ((fd = open(path, O_RDONLY|O_DIRECT|O_EXCL)) < 0) {
|
||||||
if (!isspare)
|
|
||||||
flags |= O_EXCL;
|
|
||||||
|
|
||||||
if ((fd = open(path, flags)) < 0) {
|
|
||||||
char *value = blkid_get_tag_value(cache, "TYPE", path);
|
char *value = blkid_get_tag_value(cache, "TYPE", path);
|
||||||
(void) fprintf(stderr, gettext("%s is in use and contains "
|
(void) fprintf(stderr, gettext("%s is in use and contains "
|
||||||
"a %s filesystem.\n"), path, value ? value : "unknown");
|
"a %s filesystem.\n"), path, value ? value : "unknown");
|
||||||
free(value);
|
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expected to fail for non-EFI labeled disks. Just check the device
|
* Expected to fail for non-EFI labled disks. Just check the device
|
||||||
* as given and do not attempt to detect and scan partitions.
|
* as given and do not attempt to detect and scan partitions.
|
||||||
*/
|
*/
|
||||||
err = efi_alloc_and_read(fd, &vtoc);
|
err = efi_alloc_and_read(fd, &vtoc);
|
||||||
@@ -554,7 +546,7 @@ is_spare(nvlist_t *config, const char *path)
|
|||||||
uint_t i, nspares;
|
uint_t i, nspares;
|
||||||
boolean_t inuse;
|
boolean_t inuse;
|
||||||
|
|
||||||
if ((fd = open(path, O_RDONLY|O_DIRECT)) < 0)
|
if ((fd = open(path, O_RDONLY)) < 0)
|
||||||
return (B_FALSE);
|
return (B_FALSE);
|
||||||
|
|
||||||
if (zpool_in_use(g_zfs, fd, &state, &name, &inuse) != 0 ||
|
if (zpool_in_use(g_zfs, fd, &state, &name, &inuse) != 0 ||
|
||||||
@@ -691,9 +683,6 @@ make_leaf_vdev(nvlist_t *props, const char *arg, uint64_t is_log)
|
|||||||
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_PATH, path) == 0);
|
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_PATH, path) == 0);
|
||||||
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 0);
|
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 0);
|
||||||
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_LOG, is_log) == 0);
|
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_LOG, is_log) == 0);
|
||||||
if (is_log)
|
|
||||||
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_ALLOCATION_BIAS,
|
|
||||||
VDEV_ALLOC_BIAS_LOG) == 0);
|
|
||||||
if (strcmp(type, VDEV_TYPE_DISK) == 0)
|
if (strcmp(type, VDEV_TYPE_DISK) == 0)
|
||||||
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
|
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
|
||||||
(uint64_t)wholedisk) == 0);
|
(uint64_t)wholedisk) == 0);
|
||||||
@@ -752,9 +741,6 @@ make_leaf_vdev(nvlist_t *props, const char *arg, uint64_t is_log)
|
|||||||
*
|
*
|
||||||
* Otherwise, make sure that the current spec (if there is one) and the new
|
* Otherwise, make sure that the current spec (if there is one) and the new
|
||||||
* spec have consistent replication levels.
|
* spec have consistent replication levels.
|
||||||
*
|
|
||||||
* If there is no current spec (create), make sure new spec has at least
|
|
||||||
* one general purpose vdev.
|
|
||||||
*/
|
*/
|
||||||
typedef struct replication_level {
|
typedef struct replication_level {
|
||||||
char *zprl_type;
|
char *zprl_type;
|
||||||
@@ -829,7 +815,7 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
|||||||
rep.zprl_children = 1;
|
rep.zprl_children = 1;
|
||||||
rep.zprl_parity = 0;
|
rep.zprl_parity = 0;
|
||||||
} else {
|
} else {
|
||||||
int64_t vdev_size;
|
uint64_t vdev_size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a mirror or RAID-Z vdev. Go through and make
|
* This is a mirror or RAID-Z vdev. Go through and make
|
||||||
@@ -859,12 +845,12 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
|||||||
*/
|
*/
|
||||||
type = NULL;
|
type = NULL;
|
||||||
dontreport = 0;
|
dontreport = 0;
|
||||||
vdev_size = -1LL;
|
vdev_size = -1ULL;
|
||||||
for (c = 0; c < children; c++) {
|
for (c = 0; c < children; c++) {
|
||||||
nvlist_t *cnv = child[c];
|
nvlist_t *cnv = child[c];
|
||||||
char *path;
|
char *path;
|
||||||
struct stat64 statbuf;
|
struct stat64 statbuf;
|
||||||
int64_t size = -1LL;
|
uint64_t size = -1ULL;
|
||||||
char *childtype;
|
char *childtype;
|
||||||
int fd, err;
|
int fd, err;
|
||||||
|
|
||||||
@@ -955,7 +941,7 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
|||||||
* (~16MB) then report an error.
|
* (~16MB) then report an error.
|
||||||
*/
|
*/
|
||||||
if (!dontreport &&
|
if (!dontreport &&
|
||||||
(vdev_size != -1LL &&
|
(vdev_size != -1ULL &&
|
||||||
(labs(size - vdev_size) >
|
(labs(size - vdev_size) >
|
||||||
ZPOOL_FUZZ))) {
|
ZPOOL_FUZZ))) {
|
||||||
if (ret != NULL)
|
if (ret != NULL)
|
||||||
@@ -978,7 +964,7 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point, we have the replication of the last toplevel
|
* At this point, we have the replication of the last toplevel
|
||||||
* vdev in 'rep'. Compare it to 'lastrep' to see if it is
|
* vdev in 'rep'. Compare it to 'lastrep' to see if its
|
||||||
* different.
|
* different.
|
||||||
*/
|
*/
|
||||||
if (lastrep.zprl_type != NULL) {
|
if (lastrep.zprl_type != NULL) {
|
||||||
@@ -1287,7 +1273,7 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv)
|
|||||||
* symbolic link will be removed, partition table created,
|
* symbolic link will be removed, partition table created,
|
||||||
* and then block until udev creates the new link.
|
* and then block until udev creates the new link.
|
||||||
*/
|
*/
|
||||||
if (!is_exclusive && !is_spare(NULL, udevpath)) {
|
if (!is_exclusive || !is_spare(NULL, udevpath)) {
|
||||||
char *devnode = strrchr(devpath, '/') + 1;
|
char *devnode = strrchr(devpath, '/') + 1;
|
||||||
|
|
||||||
ret = strncmp(udevpath, UDISK_ROOT, strlen(UDISK_ROOT));
|
ret = strncmp(udevpath, UDISK_ROOT, strlen(UDISK_ROOT));
|
||||||
@@ -1479,13 +1465,6 @@ is_grouping(const char *type, int *mindev, int *maxdev)
|
|||||||
return (VDEV_TYPE_LOG);
|
return (VDEV_TYPE_LOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(type, VDEV_ALLOC_BIAS_SPECIAL) == 0 ||
|
|
||||||
strcmp(type, VDEV_ALLOC_BIAS_DEDUP) == 0) {
|
|
||||||
if (mindev != NULL)
|
|
||||||
*mindev = 1;
|
|
||||||
return (type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(type, "cache") == 0) {
|
if (strcmp(type, "cache") == 0) {
|
||||||
if (mindev != NULL)
|
if (mindev != NULL)
|
||||||
*mindev = 1;
|
*mindev = 1;
|
||||||
@@ -1507,7 +1486,7 @@ construct_spec(nvlist_t *props, int argc, char **argv)
|
|||||||
nvlist_t *nvroot, *nv, **top, **spares, **l2cache;
|
nvlist_t *nvroot, *nv, **top, **spares, **l2cache;
|
||||||
int t, toplevels, mindev, maxdev, nspares, nlogs, nl2cache;
|
int t, toplevels, mindev, maxdev, nspares, nlogs, nl2cache;
|
||||||
const char *type;
|
const char *type;
|
||||||
uint64_t is_log, is_special, is_dedup;
|
uint64_t is_log;
|
||||||
boolean_t seen_logs;
|
boolean_t seen_logs;
|
||||||
|
|
||||||
top = NULL;
|
top = NULL;
|
||||||
@@ -1517,7 +1496,7 @@ construct_spec(nvlist_t *props, int argc, char **argv)
|
|||||||
nspares = 0;
|
nspares = 0;
|
||||||
nlogs = 0;
|
nlogs = 0;
|
||||||
nl2cache = 0;
|
nl2cache = 0;
|
||||||
is_log = is_special = is_dedup = B_FALSE;
|
is_log = B_FALSE;
|
||||||
seen_logs = B_FALSE;
|
seen_logs = B_FALSE;
|
||||||
nvroot = NULL;
|
nvroot = NULL;
|
||||||
|
|
||||||
@@ -1540,7 +1519,7 @@ construct_spec(nvlist_t *props, int argc, char **argv)
|
|||||||
"specified only once\n"));
|
"specified only once\n"));
|
||||||
goto spec_out;
|
goto spec_out;
|
||||||
}
|
}
|
||||||
is_log = is_special = is_dedup = B_FALSE;
|
is_log = B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(type, VDEV_TYPE_LOG) == 0) {
|
if (strcmp(type, VDEV_TYPE_LOG) == 0) {
|
||||||
@@ -1553,8 +1532,6 @@ construct_spec(nvlist_t *props, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
seen_logs = B_TRUE;
|
seen_logs = B_TRUE;
|
||||||
is_log = B_TRUE;
|
is_log = B_TRUE;
|
||||||
is_special = B_FALSE;
|
|
||||||
is_dedup = B_FALSE;
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
/*
|
/*
|
||||||
@@ -1564,24 +1541,6 @@ construct_spec(nvlist_t *props, int argc, char **argv)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(type, VDEV_ALLOC_BIAS_SPECIAL) == 0) {
|
|
||||||
is_special = B_TRUE;
|
|
||||||
is_log = B_FALSE;
|
|
||||||
is_dedup = B_FALSE;
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(type, VDEV_ALLOC_BIAS_DEDUP) == 0) {
|
|
||||||
is_dedup = B_TRUE;
|
|
||||||
is_log = B_FALSE;
|
|
||||||
is_special = B_FALSE;
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(type, VDEV_TYPE_L2CACHE) == 0) {
|
if (strcmp(type, VDEV_TYPE_L2CACHE) == 0) {
|
||||||
if (l2cache != NULL) {
|
if (l2cache != NULL) {
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
@@ -1590,16 +1549,15 @@ construct_spec(nvlist_t *props, int argc, char **argv)
|
|||||||
"specified only once\n"));
|
"specified only once\n"));
|
||||||
goto spec_out;
|
goto spec_out;
|
||||||
}
|
}
|
||||||
is_log = is_special = is_dedup = B_FALSE;
|
is_log = B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_log || is_special || is_dedup) {
|
if (is_log) {
|
||||||
if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
|
if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("invalid vdev "
|
gettext("invalid vdev "
|
||||||
"specification: unsupported '%s' "
|
"specification: unsupported 'log' "
|
||||||
"device: %s\n"), is_log ? "log" :
|
"device: %s\n"), type);
|
||||||
"special", type);
|
|
||||||
goto spec_out;
|
goto spec_out;
|
||||||
}
|
}
|
||||||
nlogs++;
|
nlogs++;
|
||||||
@@ -1656,27 +1614,12 @@ construct_spec(nvlist_t *props, int argc, char **argv)
|
|||||||
nl2cache = children;
|
nl2cache = children;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
/* create a top-level vdev with children */
|
|
||||||
verify(nvlist_alloc(&nv, NV_UNIQUE_NAME,
|
verify(nvlist_alloc(&nv, NV_UNIQUE_NAME,
|
||||||
0) == 0);
|
0) == 0);
|
||||||
verify(nvlist_add_string(nv, ZPOOL_CONFIG_TYPE,
|
verify(nvlist_add_string(nv, ZPOOL_CONFIG_TYPE,
|
||||||
type) == 0);
|
type) == 0);
|
||||||
verify(nvlist_add_uint64(nv,
|
verify(nvlist_add_uint64(nv,
|
||||||
ZPOOL_CONFIG_IS_LOG, is_log) == 0);
|
ZPOOL_CONFIG_IS_LOG, is_log) == 0);
|
||||||
if (is_log)
|
|
||||||
verify(nvlist_add_string(nv,
|
|
||||||
ZPOOL_CONFIG_ALLOCATION_BIAS,
|
|
||||||
VDEV_ALLOC_BIAS_LOG) == 0);
|
|
||||||
if (is_special) {
|
|
||||||
verify(nvlist_add_string(nv,
|
|
||||||
ZPOOL_CONFIG_ALLOCATION_BIAS,
|
|
||||||
VDEV_ALLOC_BIAS_SPECIAL) == 0);
|
|
||||||
}
|
|
||||||
if (is_dedup) {
|
|
||||||
verify(nvlist_add_string(nv,
|
|
||||||
ZPOOL_CONFIG_ALLOCATION_BIAS,
|
|
||||||
VDEV_ALLOC_BIAS_DEDUP) == 0);
|
|
||||||
}
|
|
||||||
if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
|
if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
|
||||||
verify(nvlist_add_uint64(nv,
|
verify(nvlist_add_uint64(nv,
|
||||||
ZPOOL_CONFIG_NPARITY,
|
ZPOOL_CONFIG_NPARITY,
|
||||||
@@ -1701,16 +1644,6 @@ construct_spec(nvlist_t *props, int argc, char **argv)
|
|||||||
|
|
||||||
if (is_log)
|
if (is_log)
|
||||||
nlogs++;
|
nlogs++;
|
||||||
if (is_special) {
|
|
||||||
verify(nvlist_add_string(nv,
|
|
||||||
ZPOOL_CONFIG_ALLOCATION_BIAS,
|
|
||||||
VDEV_ALLOC_BIAS_SPECIAL) == 0);
|
|
||||||
}
|
|
||||||
if (is_dedup) {
|
|
||||||
verify(nvlist_add_string(nv,
|
|
||||||
ZPOOL_CONFIG_ALLOCATION_BIAS,
|
|
||||||
VDEV_ALLOC_BIAS_DEDUP) == 0);
|
|
||||||
}
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
@@ -1811,30 +1744,6 @@ split_mirror_vdev(zpool_handle_t *zhp, char *newname, nvlist_t *props,
|
|||||||
return (newroot);
|
return (newroot);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
num_normal_vdevs(nvlist_t *nvroot)
|
|
||||||
{
|
|
||||||
nvlist_t **top;
|
|
||||||
uint_t t, toplevels, normal = 0;
|
|
||||||
|
|
||||||
verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
|
|
||||||
&top, &toplevels) == 0);
|
|
||||||
|
|
||||||
for (t = 0; t < toplevels; t++) {
|
|
||||||
uint64_t log = B_FALSE;
|
|
||||||
|
|
||||||
(void) nvlist_lookup_uint64(top[t], ZPOOL_CONFIG_IS_LOG, &log);
|
|
||||||
if (log)
|
|
||||||
continue;
|
|
||||||
if (nvlist_exists(top[t], ZPOOL_CONFIG_ALLOCATION_BIAS))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
normal++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get and validate the contents of the given vdev specification. This ensures
|
* Get and validate the contents of the given vdev specification. This ensures
|
||||||
* that the nvlist returned is well-formed, that all the devices exist, and that
|
* that the nvlist returned is well-formed, that all the devices exist, and that
|
||||||
@@ -1867,7 +1776,7 @@ make_root_vdev(zpool_handle_t *zhp, nvlist_t *props, int force, int check_rep,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validate each device to make sure that it's not shared with another
|
* Validate each device to make sure that its not shared with another
|
||||||
* subsystem. We do this even if 'force' is set, because there are some
|
* subsystem. We do this even if 'force' is set, because there are some
|
||||||
* uses (such as a dedicated dump device) that even '-f' cannot
|
* uses (such as a dedicated dump device) that even '-f' cannot
|
||||||
* override.
|
* override.
|
||||||
@@ -1887,16 +1796,6 @@ make_root_vdev(zpool_handle_t *zhp, nvlist_t *props, int force, int check_rep,
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* On pool create the new vdev spec must have one normal vdev.
|
|
||||||
*/
|
|
||||||
if (poolconfig == NULL && num_normal_vdevs(newroot) == 0) {
|
|
||||||
vdev_error(gettext("at least one general top-level vdev must "
|
|
||||||
"be specified\n"));
|
|
||||||
nvlist_free(newroot);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run through the vdev specification and label any whole disks found.
|
* Run through the vdev specification and label any whole disks found.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -11,4 +11,7 @@ zstreamdump_SOURCES = \
|
|||||||
|
|
||||||
zstreamdump_LDADD = \
|
zstreamdump_LDADD = \
|
||||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
$(top_builddir)/lib/libzfs/libzfs.la
|
$(top_builddir)/lib/libuutil/libuutil.la \
|
||||||
|
$(top_builddir)/lib/libzpool/libzpool.la \
|
||||||
|
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||||
|
$(top_builddir)/lib/libzfs_core/libzfs_core.la
|
||||||
|
|||||||
+51
-174
@@ -53,6 +53,7 @@
|
|||||||
*/
|
*/
|
||||||
#define DUMP_GROUPING 4
|
#define DUMP_GROUPING 4
|
||||||
|
|
||||||
|
uint64_t total_write_size = 0;
|
||||||
uint64_t total_stream_len = 0;
|
uint64_t total_stream_len = 0;
|
||||||
FILE *send_stream = 0;
|
FILE *send_stream = 0;
|
||||||
boolean_t do_byteswap = B_FALSE;
|
boolean_t do_byteswap = B_FALSE;
|
||||||
@@ -196,36 +197,12 @@ print_block(char *buf, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Print an array of bytes to stdout as hexadecimal characters. str must
|
|
||||||
* have buf_len * 2 + 1 bytes of space.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
sprintf_bytes(char *str, uint8_t *buf, uint_t buf_len)
|
|
||||||
{
|
|
||||||
int i, n;
|
|
||||||
|
|
||||||
for (i = 0; i < buf_len; i++) {
|
|
||||||
n = sprintf(str, "%02x", buf[i] & 0xff);
|
|
||||||
str += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
str[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *buf = safe_malloc(SPA_MAXBLOCKSIZE);
|
char *buf = safe_malloc(SPA_MAXBLOCKSIZE);
|
||||||
uint64_t drr_record_count[DRR_NUMTYPES] = { 0 };
|
uint64_t drr_record_count[DRR_NUMTYPES] = { 0 };
|
||||||
uint64_t total_payload_size = 0;
|
|
||||||
uint64_t total_overhead_size = 0;
|
|
||||||
uint64_t drr_byte_count[DRR_NUMTYPES] = { 0 };
|
|
||||||
char salt[ZIO_DATA_SALT_LEN * 2 + 1];
|
|
||||||
char iv[ZIO_DATA_IV_LEN * 2 + 1];
|
|
||||||
char mac[ZIO_DATA_MAC_LEN * 2 + 1];
|
|
||||||
uint64_t total_records = 0;
|
uint64_t total_records = 0;
|
||||||
uint64_t payload_size;
|
|
||||||
dmu_replay_record_t thedrr;
|
dmu_replay_record_t thedrr;
|
||||||
dmu_replay_record_t *drr = &thedrr;
|
dmu_replay_record_t *drr = &thedrr;
|
||||||
struct drr_begin *drrb = &thedrr.drr_u.drr_begin;
|
struct drr_begin *drrb = &thedrr.drr_u.drr_begin;
|
||||||
@@ -237,9 +214,8 @@ main(int argc, char *argv[])
|
|||||||
struct drr_free *drrf = &thedrr.drr_u.drr_free;
|
struct drr_free *drrf = &thedrr.drr_u.drr_free;
|
||||||
struct drr_spill *drrs = &thedrr.drr_u.drr_spill;
|
struct drr_spill *drrs = &thedrr.drr_u.drr_spill;
|
||||||
struct drr_write_embedded *drrwe = &thedrr.drr_u.drr_write_embedded;
|
struct drr_write_embedded *drrwe = &thedrr.drr_u.drr_write_embedded;
|
||||||
struct drr_object_range *drror = &thedrr.drr_u.drr_object_range;
|
|
||||||
struct drr_checksum *drrc = &thedrr.drr_u.drr_checksum;
|
struct drr_checksum *drrc = &thedrr.drr_u.drr_checksum;
|
||||||
int c;
|
char c;
|
||||||
boolean_t verbose = B_FALSE;
|
boolean_t verbose = B_FALSE;
|
||||||
boolean_t very_verbose = B_FALSE;
|
boolean_t very_verbose = B_FALSE;
|
||||||
boolean_t first = B_TRUE;
|
boolean_t first = B_TRUE;
|
||||||
@@ -338,9 +314,7 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
drr_record_count[drr->drr_type]++;
|
drr_record_count[drr->drr_type]++;
|
||||||
total_overhead_size += sizeof (*drr);
|
|
||||||
total_records++;
|
total_records++;
|
||||||
payload_size = 0;
|
|
||||||
|
|
||||||
switch (drr->drr_type) {
|
switch (drr->drr_type) {
|
||||||
case DRR_BEGIN:
|
case DRR_BEGIN:
|
||||||
@@ -388,13 +362,10 @@ main(int argc, char *argv[])
|
|||||||
if (ferror(send_stream))
|
if (ferror(send_stream))
|
||||||
perror("fread");
|
perror("fread");
|
||||||
err = nvlist_unpack(buf, sz, &nv, 0);
|
err = nvlist_unpack(buf, sz, &nv, 0);
|
||||||
if (err) {
|
if (err)
|
||||||
perror(strerror(err));
|
perror(strerror(err));
|
||||||
} else {
|
nvlist_print(stdout, nv);
|
||||||
nvlist_print(stdout, nv);
|
nvlist_free(nv);
|
||||||
nvlist_free(nv);
|
|
||||||
}
|
|
||||||
payload_size = sz;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -447,39 +418,26 @@ main(int argc, char *argv[])
|
|||||||
drro->drr_blksz = BSWAP_32(drro->drr_blksz);
|
drro->drr_blksz = BSWAP_32(drro->drr_blksz);
|
||||||
drro->drr_bonuslen =
|
drro->drr_bonuslen =
|
||||||
BSWAP_32(drro->drr_bonuslen);
|
BSWAP_32(drro->drr_bonuslen);
|
||||||
drro->drr_raw_bonuslen =
|
|
||||||
BSWAP_32(drro->drr_raw_bonuslen);
|
|
||||||
drro->drr_toguid = BSWAP_64(drro->drr_toguid);
|
drro->drr_toguid = BSWAP_64(drro->drr_toguid);
|
||||||
drro->drr_maxblkid =
|
|
||||||
BSWAP_64(drro->drr_maxblkid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
payload_size = DRR_OBJECT_PAYLOAD_SIZE(drro);
|
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
(void) printf("OBJECT object = %llu type = %u "
|
(void) printf("OBJECT object = %llu type = %u "
|
||||||
"bonustype = %u blksz = %u bonuslen = %u "
|
"bonustype = %u blksz = %u bonuslen = %u "
|
||||||
"dn_slots = %u raw_bonuslen = %u "
|
"dn_slots = %u\n",
|
||||||
"flags = %u maxblkid = %llu "
|
|
||||||
"indblkshift = %u nlevels = %u "
|
|
||||||
"nblkptr = %u\n",
|
|
||||||
(u_longlong_t)drro->drr_object,
|
(u_longlong_t)drro->drr_object,
|
||||||
drro->drr_type,
|
drro->drr_type,
|
||||||
drro->drr_bonustype,
|
drro->drr_bonustype,
|
||||||
drro->drr_blksz,
|
drro->drr_blksz,
|
||||||
drro->drr_bonuslen,
|
drro->drr_bonuslen,
|
||||||
drro->drr_dn_slots,
|
drro->drr_dn_slots);
|
||||||
drro->drr_raw_bonuslen,
|
|
||||||
drro->drr_flags,
|
|
||||||
(u_longlong_t)drro->drr_maxblkid,
|
|
||||||
drro->drr_indblkshift,
|
|
||||||
drro->drr_nlevels,
|
|
||||||
drro->drr_nblkptr);
|
|
||||||
}
|
}
|
||||||
if (drro->drr_bonuslen > 0) {
|
if (drro->drr_bonuslen > 0) {
|
||||||
(void) ssread(buf, payload_size, &zc);
|
(void) ssread(buf,
|
||||||
if (dump)
|
P2ROUNDUP(drro->drr_bonuslen, 8), &zc);
|
||||||
print_block(buf, payload_size);
|
if (dump) {
|
||||||
|
print_block(buf,
|
||||||
|
P2ROUNDUP(drro->drr_bonuslen, 8));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -513,40 +471,28 @@ main(int argc, char *argv[])
|
|||||||
BSWAP_64(drrw->drr_compressed_size);
|
BSWAP_64(drrw->drr_compressed_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
payload_size = DRR_WRITE_PAYLOAD_SIZE(drrw);
|
uint64_t payload_size = DRR_WRITE_PAYLOAD_SIZE(drrw);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is verbose and/or dump output,
|
* If this is verbose and/or dump output,
|
||||||
* print info on the modified block
|
* print info on the modified block
|
||||||
*/
|
*/
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
sprintf_bytes(salt, drrw->drr_salt,
|
|
||||||
ZIO_DATA_SALT_LEN);
|
|
||||||
sprintf_bytes(iv, drrw->drr_iv,
|
|
||||||
ZIO_DATA_IV_LEN);
|
|
||||||
sprintf_bytes(mac, drrw->drr_mac,
|
|
||||||
ZIO_DATA_MAC_LEN);
|
|
||||||
|
|
||||||
(void) printf("WRITE object = %llu type = %u "
|
(void) printf("WRITE object = %llu type = %u "
|
||||||
"checksum type = %u compression type = %u "
|
"checksum type = %u compression type = %u\n"
|
||||||
"flags = %u offset = %llu "
|
" offset = %llu logical_size = %llu "
|
||||||
"logical_size = %llu "
|
|
||||||
"compressed_size = %llu "
|
"compressed_size = %llu "
|
||||||
"payload_size = %llu props = %llx "
|
"payload_size = %llu "
|
||||||
"salt = %s iv = %s mac = %s\n",
|
"props = %llx\n",
|
||||||
(u_longlong_t)drrw->drr_object,
|
(u_longlong_t)drrw->drr_object,
|
||||||
drrw->drr_type,
|
drrw->drr_type,
|
||||||
drrw->drr_checksumtype,
|
drrw->drr_checksumtype,
|
||||||
drrw->drr_compressiontype,
|
drrw->drr_compressiontype,
|
||||||
drrw->drr_flags,
|
|
||||||
(u_longlong_t)drrw->drr_offset,
|
(u_longlong_t)drrw->drr_offset,
|
||||||
(u_longlong_t)drrw->drr_logical_size,
|
(u_longlong_t)drrw->drr_logical_size,
|
||||||
(u_longlong_t)drrw->drr_compressed_size,
|
(u_longlong_t)drrw->drr_compressed_size,
|
||||||
(u_longlong_t)payload_size,
|
(u_longlong_t)payload_size,
|
||||||
(u_longlong_t)drrw->drr_key.ddk_prop,
|
(u_longlong_t)drrw->drr_key.ddk_prop);
|
||||||
salt,
|
|
||||||
iv,
|
|
||||||
mac);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -559,6 +505,7 @@ main(int argc, char *argv[])
|
|||||||
if (dump) {
|
if (dump) {
|
||||||
print_block(buf, payload_size);
|
print_block(buf, payload_size);
|
||||||
}
|
}
|
||||||
|
total_write_size += payload_size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DRR_WRITE_BYREF:
|
case DRR_WRITE_BYREF:
|
||||||
@@ -582,10 +529,10 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
(void) printf("WRITE_BYREF object = %llu "
|
(void) printf("WRITE_BYREF object = %llu "
|
||||||
"checksum type = %u props = %llx "
|
"checksum type = %u props = %llx\n"
|
||||||
"offset = %llu length = %llu "
|
" offset = %llu length = %llu\n"
|
||||||
"toguid = %llx refguid = %llx "
|
"toguid = %llx refguid = %llx\n"
|
||||||
"refobject = %llu refoffset = %llu\n",
|
" refobject = %llu refoffset = %llu\n",
|
||||||
(u_longlong_t)drrwbr->drr_object,
|
(u_longlong_t)drrwbr->drr_object,
|
||||||
drrwbr->drr_checksumtype,
|
drrwbr->drr_checksumtype,
|
||||||
(u_longlong_t)drrwbr->drr_key.ddk_prop,
|
(u_longlong_t)drrwbr->drr_key.ddk_prop,
|
||||||
@@ -616,40 +563,16 @@ main(int argc, char *argv[])
|
|||||||
if (do_byteswap) {
|
if (do_byteswap) {
|
||||||
drrs->drr_object = BSWAP_64(drrs->drr_object);
|
drrs->drr_object = BSWAP_64(drrs->drr_object);
|
||||||
drrs->drr_length = BSWAP_64(drrs->drr_length);
|
drrs->drr_length = BSWAP_64(drrs->drr_length);
|
||||||
drrs->drr_compressed_size =
|
|
||||||
BSWAP_64(drrs->drr_compressed_size);
|
|
||||||
drrs->drr_type = BSWAP_32(drrs->drr_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
payload_size = DRR_SPILL_PAYLOAD_SIZE(drrs);
|
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
sprintf_bytes(salt, drrs->drr_salt,
|
|
||||||
ZIO_DATA_SALT_LEN);
|
|
||||||
sprintf_bytes(iv, drrs->drr_iv,
|
|
||||||
ZIO_DATA_IV_LEN);
|
|
||||||
sprintf_bytes(mac, drrs->drr_mac,
|
|
||||||
ZIO_DATA_MAC_LEN);
|
|
||||||
|
|
||||||
(void) printf("SPILL block for object = %llu "
|
(void) printf("SPILL block for object = %llu "
|
||||||
"length = %llu flags = %u "
|
"length = %llu\n",
|
||||||
"compression type = %u "
|
(long long unsigned int)drrs->drr_object,
|
||||||
"compressed_size = %llu "
|
(long long unsigned int)drrs->drr_length);
|
||||||
"payload_size = %llu "
|
|
||||||
"salt = %s iv = %s mac = %s\n",
|
|
||||||
(u_longlong_t)drrs->drr_object,
|
|
||||||
(u_longlong_t)drrs->drr_length,
|
|
||||||
drrs->drr_flags,
|
|
||||||
drrs->drr_compressiontype,
|
|
||||||
(u_longlong_t)drrs->drr_compressed_size,
|
|
||||||
(u_longlong_t)payload_size,
|
|
||||||
salt,
|
|
||||||
iv,
|
|
||||||
mac);
|
|
||||||
}
|
}
|
||||||
(void) ssread(buf, payload_size, &zc);
|
(void) ssread(buf, drrs->drr_length, &zc);
|
||||||
if (dump) {
|
if (dump) {
|
||||||
print_block(buf, payload_size);
|
print_block(buf, drrs->drr_length);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DRR_WRITE_EMBEDDED:
|
case DRR_WRITE_EMBEDDED:
|
||||||
@@ -669,8 +592,8 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
(void) printf("WRITE_EMBEDDED object = %llu "
|
(void) printf("WRITE_EMBEDDED object = %llu "
|
||||||
"offset = %llu length = %llu "
|
"offset = %llu length = %llu\n"
|
||||||
"toguid = %llx comp = %u etype = %u "
|
" toguid = %llx comp = %u etype = %u "
|
||||||
"lsize = %u psize = %u\n",
|
"lsize = %u psize = %u\n",
|
||||||
(u_longlong_t)drrwe->drr_object,
|
(u_longlong_t)drrwe->drr_object,
|
||||||
(u_longlong_t)drrwe->drr_offset,
|
(u_longlong_t)drrwe->drr_offset,
|
||||||
@@ -683,38 +606,6 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
(void) ssread(buf,
|
(void) ssread(buf,
|
||||||
P2ROUNDUP(drrwe->drr_psize, 8), &zc);
|
P2ROUNDUP(drrwe->drr_psize, 8), &zc);
|
||||||
if (dump) {
|
|
||||||
print_block(buf,
|
|
||||||
P2ROUNDUP(drrwe->drr_psize, 8));
|
|
||||||
}
|
|
||||||
payload_size = P2ROUNDUP(drrwe->drr_psize, 8);
|
|
||||||
break;
|
|
||||||
case DRR_OBJECT_RANGE:
|
|
||||||
if (do_byteswap) {
|
|
||||||
drror->drr_firstobj =
|
|
||||||
BSWAP_64(drror->drr_firstobj);
|
|
||||||
drror->drr_numslots =
|
|
||||||
BSWAP_64(drror->drr_numslots);
|
|
||||||
drror->drr_toguid = BSWAP_64(drror->drr_toguid);
|
|
||||||
}
|
|
||||||
if (verbose) {
|
|
||||||
sprintf_bytes(salt, drror->drr_salt,
|
|
||||||
ZIO_DATA_SALT_LEN);
|
|
||||||
sprintf_bytes(iv, drror->drr_iv,
|
|
||||||
ZIO_DATA_IV_LEN);
|
|
||||||
sprintf_bytes(mac, drror->drr_mac,
|
|
||||||
ZIO_DATA_MAC_LEN);
|
|
||||||
|
|
||||||
(void) printf("OBJECT_RANGE firstobj = %llu "
|
|
||||||
"numslots = %llu flags = %u "
|
|
||||||
"salt = %s iv = %s mac = %s\n",
|
|
||||||
(u_longlong_t)drror->drr_firstobj,
|
|
||||||
(u_longlong_t)drror->drr_numslots,
|
|
||||||
drror->drr_flags,
|
|
||||||
salt,
|
|
||||||
iv,
|
|
||||||
mac);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case DRR_NUMTYPES:
|
case DRR_NUMTYPES:
|
||||||
/* should never be reached */
|
/* should never be reached */
|
||||||
@@ -728,8 +619,6 @@ main(int argc, char *argv[])
|
|||||||
(longlong_t)drrc->drr_checksum.zc_word[3]);
|
(longlong_t)drrc->drr_checksum.zc_word[3]);
|
||||||
}
|
}
|
||||||
pcksum = zc;
|
pcksum = zc;
|
||||||
drr_byte_count[drr->drr_type] += payload_size;
|
|
||||||
total_payload_size += payload_size;
|
|
||||||
}
|
}
|
||||||
free(buf);
|
free(buf);
|
||||||
fletcher_4_fini();
|
fletcher_4_fini();
|
||||||
@@ -737,40 +626,28 @@ main(int argc, char *argv[])
|
|||||||
/* Print final summary */
|
/* Print final summary */
|
||||||
|
|
||||||
(void) printf("SUMMARY:\n");
|
(void) printf("SUMMARY:\n");
|
||||||
(void) printf("\tTotal DRR_BEGIN records = %lld (%llu bytes)\n",
|
(void) printf("\tTotal DRR_BEGIN records = %lld\n",
|
||||||
(u_longlong_t)drr_record_count[DRR_BEGIN],
|
(u_longlong_t)drr_record_count[DRR_BEGIN]);
|
||||||
(u_longlong_t)drr_byte_count[DRR_BEGIN]);
|
(void) printf("\tTotal DRR_END records = %lld\n",
|
||||||
(void) printf("\tTotal DRR_END records = %lld (%llu bytes)\n",
|
(u_longlong_t)drr_record_count[DRR_END]);
|
||||||
(u_longlong_t)drr_record_count[DRR_END],
|
(void) printf("\tTotal DRR_OBJECT records = %lld\n",
|
||||||
(u_longlong_t)drr_byte_count[DRR_END]);
|
(u_longlong_t)drr_record_count[DRR_OBJECT]);
|
||||||
(void) printf("\tTotal DRR_OBJECT records = %lld (%llu bytes)\n",
|
(void) printf("\tTotal DRR_FREEOBJECTS records = %lld\n",
|
||||||
(u_longlong_t)drr_record_count[DRR_OBJECT],
|
(u_longlong_t)drr_record_count[DRR_FREEOBJECTS]);
|
||||||
(u_longlong_t)drr_byte_count[DRR_OBJECT]);
|
(void) printf("\tTotal DRR_WRITE records = %lld\n",
|
||||||
(void) printf("\tTotal DRR_FREEOBJECTS records = %lld (%llu bytes)\n",
|
(u_longlong_t)drr_record_count[DRR_WRITE]);
|
||||||
(u_longlong_t)drr_record_count[DRR_FREEOBJECTS],
|
(void) printf("\tTotal DRR_WRITE_BYREF records = %lld\n",
|
||||||
(u_longlong_t)drr_byte_count[DRR_FREEOBJECTS]);
|
(u_longlong_t)drr_record_count[DRR_WRITE_BYREF]);
|
||||||
(void) printf("\tTotal DRR_WRITE records = %lld (%llu bytes)\n",
|
(void) printf("\tTotal DRR_WRITE_EMBEDDED records = %lld\n",
|
||||||
(u_longlong_t)drr_record_count[DRR_WRITE],
|
(u_longlong_t)drr_record_count[DRR_WRITE_EMBEDDED]);
|
||||||
(u_longlong_t)drr_byte_count[DRR_WRITE]);
|
(void) printf("\tTotal DRR_FREE records = %lld\n",
|
||||||
(void) printf("\tTotal DRR_WRITE_BYREF records = %lld (%llu bytes)\n",
|
(u_longlong_t)drr_record_count[DRR_FREE]);
|
||||||
(u_longlong_t)drr_record_count[DRR_WRITE_BYREF],
|
(void) printf("\tTotal DRR_SPILL records = %lld\n",
|
||||||
(u_longlong_t)drr_byte_count[DRR_WRITE_BYREF]);
|
(u_longlong_t)drr_record_count[DRR_SPILL]);
|
||||||
(void) printf("\tTotal DRR_WRITE_EMBEDDED records = %lld (%llu "
|
|
||||||
"bytes)\n", (u_longlong_t)drr_record_count[DRR_WRITE_EMBEDDED],
|
|
||||||
(u_longlong_t)drr_byte_count[DRR_WRITE_EMBEDDED]);
|
|
||||||
(void) printf("\tTotal DRR_FREE records = %lld (%llu bytes)\n",
|
|
||||||
(u_longlong_t)drr_record_count[DRR_FREE],
|
|
||||||
(u_longlong_t)drr_byte_count[DRR_FREE]);
|
|
||||||
(void) printf("\tTotal DRR_SPILL records = %lld (%llu bytes)\n",
|
|
||||||
(u_longlong_t)drr_record_count[DRR_SPILL],
|
|
||||||
(u_longlong_t)drr_byte_count[DRR_SPILL]);
|
|
||||||
(void) printf("\tTotal records = %lld\n",
|
(void) printf("\tTotal records = %lld\n",
|
||||||
(u_longlong_t)total_records);
|
(u_longlong_t)total_records);
|
||||||
(void) printf("\tTotal payload size = %lld (0x%llx)\n",
|
(void) printf("\tTotal write size = %lld (0x%llx)\n",
|
||||||
(u_longlong_t)total_payload_size, (u_longlong_t)total_payload_size);
|
(u_longlong_t)total_write_size, (u_longlong_t)total_write_size);
|
||||||
(void) printf("\tTotal header overhead = %lld (0x%llx)\n",
|
|
||||||
(u_longlong_t)total_overhead_size,
|
|
||||||
(u_longlong_t)total_overhead_size);
|
|
||||||
(void) printf("\tTotal stream length = %lld (0x%llx)\n",
|
(void) printf("\tTotal stream length = %lld (0x%llx)\n",
|
||||||
(u_longlong_t)total_stream_len, (u_longlong_t)total_stream_len);
|
(u_longlong_t)total_stream_len, (u_longlong_t)total_stream_len);
|
||||||
return (0);
|
return (0);
|
||||||
|
|||||||
+8
-10
@@ -1,13 +1,9 @@
|
|||||||
include $(top_srcdir)/config/Rules.am
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
|
||||||
# Get rid of compiler warning for unchecked truncating snprintfs on gcc 7.1.1
|
# -Wnoformat-truncation to get rid of compiler warning for unchecked
|
||||||
AM_CFLAGS += $(NO_FORMAT_TRUNCATION)
|
# truncating snprintfs on gcc 7.1.1.
|
||||||
|
AM_CFLAGS += $(DEBUG_STACKFLAGS) $(FRAME_LARGER_THAN) $(NO_FORMAT_TRUNCATION)
|
||||||
# Includes kernel code, generate warnings for large stack frames
|
AM_CPPFLAGS += -DDEBUG
|
||||||
AM_CFLAGS += $(FRAME_LARGER_THAN)
|
|
||||||
|
|
||||||
# Unconditionally enable ASSERTs
|
|
||||||
AM_CPPFLAGS += -DDEBUG -UNDEBUG
|
|
||||||
|
|
||||||
DEFAULT_INCLUDES += \
|
DEFAULT_INCLUDES += \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
@@ -20,7 +16,9 @@ ztest_SOURCES = \
|
|||||||
|
|
||||||
ztest_LDADD = \
|
ztest_LDADD = \
|
||||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
$(top_builddir)/lib/libzpool/libzpool.la
|
$(top_builddir)/lib/libuutil/libuutil.la \
|
||||||
|
$(top_builddir)/lib/libzpool/libzpool.la \
|
||||||
|
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||||
|
$(top_builddir)/lib/libzfs_core/libzfs_core.la
|
||||||
|
|
||||||
ztest_LDADD += -lm
|
ztest_LDADD += -lm
|
||||||
ztest_LDFLAGS = -pthread
|
|
||||||
|
|||||||
+496
-1273
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
|||||||
dist_bin_SCRIPTS = zvol_wait
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
count_zvols() {
|
|
||||||
if [ -z "$zvols" ]; then
|
|
||||||
echo 0
|
|
||||||
else
|
|
||||||
echo "$zvols" | wc -l
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
filter_out_zvols_with_links() {
|
|
||||||
while read -r zvol; do
|
|
||||||
if [ ! -L "/dev/zvol/$zvol" ]; then
|
|
||||||
echo "$zvol"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
filter_out_deleted_zvols() {
|
|
||||||
while read -r zvol; do
|
|
||||||
if zfs list "$zvol" >/dev/null 2>&1; then
|
|
||||||
echo "$zvol"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
list_zvols() {
|
|
||||||
zfs list -t volume -H -o name,volmode,receive_resume_token |
|
|
||||||
while read -r zvol_line; do
|
|
||||||
name=$(echo "$zvol_line" | awk '{print $1}')
|
|
||||||
volmode=$(echo "$zvol_line" | awk '{print $2}')
|
|
||||||
token=$(echo "$zvol_line" | awk '{print $3}')
|
|
||||||
#
|
|
||||||
# /dev links are not created for zvols with volmode = "none".
|
|
||||||
#
|
|
||||||
[ "$volmode" = "none" ] && continue
|
|
||||||
#
|
|
||||||
# We also also ignore partially received zvols if it is
|
|
||||||
# not an incremental receive, as those won't even have a block
|
|
||||||
# device minor node created yet.
|
|
||||||
#
|
|
||||||
if [ "$token" != "-" ]; then
|
|
||||||
#
|
|
||||||
# Incremental receives create an invisible clone that
|
|
||||||
# is not automatically displayed by zfs list.
|
|
||||||
#
|
|
||||||
if ! zfs list "$name/%recv" >/dev/null 2>&1; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
echo "$name"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
zvols=$(list_zvols)
|
|
||||||
zvols_count=$(count_zvols)
|
|
||||||
if [ "$zvols_count" -eq 0 ]; then
|
|
||||||
echo "No zvols found, nothing to do."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Testing $zvols_count zvol links"
|
|
||||||
|
|
||||||
outer_loop=0
|
|
||||||
while [ "$outer_loop" -lt 20 ]; do
|
|
||||||
outer_loop=$((outer_loop + 1))
|
|
||||||
|
|
||||||
old_zvols_count=$(count_zvols)
|
|
||||||
|
|
||||||
inner_loop=0
|
|
||||||
while [ "$inner_loop" -lt 30 ]; do
|
|
||||||
inner_loop=$((inner_loop + 1))
|
|
||||||
|
|
||||||
zvols="$(echo "$zvols" | filter_out_zvols_with_links)"
|
|
||||||
|
|
||||||
zvols_count=$(count_zvols)
|
|
||||||
if [ "$zvols_count" -eq 0 ]; then
|
|
||||||
echo "All zvol links are now present."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Still waiting on $zvols_count zvol links ..."
|
|
||||||
#
|
|
||||||
# Although zvols should normally not be deleted at boot time,
|
|
||||||
# if that is the case then their links will be missing and
|
|
||||||
# we would stall.
|
|
||||||
#
|
|
||||||
if [ "$old_zvols_count" -eq "$zvols_count" ]; then
|
|
||||||
echo "No progress since last loop."
|
|
||||||
echo "Checking if any zvols were deleted."
|
|
||||||
|
|
||||||
zvols=$(echo "$zvols" | filter_out_deleted_zvols)
|
|
||||||
zvols_count=$(count_zvols)
|
|
||||||
|
|
||||||
if [ "$old_zvols_count" -ne "$zvols_count" ]; then
|
|
||||||
echo "$((old_zvols_count - zvols_count)) zvol(s) deleted."
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$zvols_count" -ne 0 ]; then
|
|
||||||
echo "Remaining zvols:"
|
|
||||||
echo "$zvols"
|
|
||||||
else
|
|
||||||
echo "All zvol links are now present."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Timed out waiting on zvol links"
|
|
||||||
exit 1
|
|
||||||
+8
-20
@@ -1,30 +1,18 @@
|
|||||||
#
|
|
||||||
# Default build rules for all user space components, every Makefile.am
|
|
||||||
# should include these rules and override or extend them as needed.
|
|
||||||
#
|
|
||||||
|
|
||||||
DEFAULT_INCLUDES = -include ${top_builddir}/zfs_config.h
|
DEFAULT_INCLUDES = -include ${top_builddir}/zfs_config.h
|
||||||
|
|
||||||
AM_LIBTOOLFLAGS = --silent
|
AM_LIBTOOLFLAGS = --silent
|
||||||
|
AM_CFLAGS = ${DEBUG_CFLAGS} -Wall -Wstrict-prototypes
|
||||||
AM_CFLAGS = -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing
|
AM_CFLAGS += ${NO_UNUSED_BUT_SET_VARIABLE}
|
||||||
AM_CFLAGS += $(NO_OMIT_FRAME_POINTER)
|
AM_CFLAGS += ${NO_BOOL_COMPARE}
|
||||||
AM_CFLAGS += $(DEBUG_CFLAGS)
|
AM_CFLAGS += -fno-strict-aliasing
|
||||||
AM_CFLAGS += $(ASAN_CFLAGS)
|
AM_CFLAGS += -std=gnu99
|
||||||
AM_CFLAGS += $(CODE_COVERAGE_CFLAGS)
|
AM_CFLAGS += $(CODE_COVERAGE_CFLAGS)
|
||||||
|
AM_CPPFLAGS = -D_GNU_SOURCE -D__EXTENSIONS__ -D_REENTRANT
|
||||||
AM_CPPFLAGS = -D_GNU_SOURCE
|
AM_CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_FILE_OFFSET_BITS=64
|
||||||
AM_CPPFLAGS += -D_REENTRANT
|
AM_CPPFLAGS += -D_LARGEFILE64_SOURCE -DHAVE_LARGE_STACKS=1
|
||||||
AM_CPPFLAGS += -D_FILE_OFFSET_BITS=64
|
|
||||||
AM_CPPFLAGS += -D_LARGEFILE64_SOURCE
|
|
||||||
AM_CPPFLAGS += -DHAVE_LARGE_STACKS=1
|
|
||||||
AM_CPPFLAGS += -DTEXT_DOMAIN=\"zfs-linux-user\"
|
AM_CPPFLAGS += -DTEXT_DOMAIN=\"zfs-linux-user\"
|
||||||
AM_CPPFLAGS += -DLIBEXECDIR=\"$(libexecdir)\"
|
AM_CPPFLAGS += -DLIBEXECDIR=\"$(libexecdir)\"
|
||||||
AM_CPPFLAGS += -DRUNSTATEDIR=\"$(runstatedir)\"
|
AM_CPPFLAGS += -DRUNSTATEDIR=\"$(runstatedir)\"
|
||||||
AM_CPPFLAGS += -DSBINDIR=\"$(sbindir)\"
|
AM_CPPFLAGS += -DSBINDIR=\"$(sbindir)\"
|
||||||
AM_CPPFLAGS += -DSYSCONFDIR=\"$(sysconfdir)\"
|
AM_CPPFLAGS += -DSYSCONFDIR=\"$(sysconfdir)\"
|
||||||
AM_CPPFLAGS += $(DEBUG_CPPFLAGS)
|
|
||||||
AM_CPPFLAGS += $(CODE_COVERAGE_CPPFLAGS)
|
AM_CPPFLAGS += $(CODE_COVERAGE_CPPFLAGS)
|
||||||
|
|
||||||
AM_LDFLAGS = $(DEBUG_LDFLAGS)
|
|
||||||
AM_LDFLAGS += $(ASAN_LDFLAGS)
|
|
||||||
|
|||||||
@@ -1,162 +0,0 @@
|
|||||||
dnl #
|
|
||||||
dnl # Enabled -fsanitize=address if supported by gcc.
|
|
||||||
dnl #
|
|
||||||
dnl # LDFLAGS needs -fsanitize=address at all times so libraries compiled with
|
|
||||||
dnl # it will be linked successfully. CFLAGS will vary by binary being built.
|
|
||||||
dnl #
|
|
||||||
dnl # The ASAN_OPTIONS environment variable can be used to further control
|
|
||||||
dnl # the behavior of binaries and libraries build with -fsanitize=address.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_ASAN], [
|
|
||||||
AC_MSG_CHECKING([whether to build with -fsanitize=address support])
|
|
||||||
AC_ARG_ENABLE([asan],
|
|
||||||
[AS_HELP_STRING([--enable-asan],
|
|
||||||
[Enable -fsanitize=address support @<:@default=no@:>@])],
|
|
||||||
[],
|
|
||||||
[enable_asan=no])
|
|
||||||
|
|
||||||
AM_CONDITIONAL([ASAN_ENABLED], [test x$enable_asan = xyes])
|
|
||||||
AC_SUBST([ASAN_ENABLED], [$enable_asan])
|
|
||||||
AC_MSG_RESULT($enable_asan)
|
|
||||||
|
|
||||||
AS_IF([ test "$enable_asan" = "yes" ], [
|
|
||||||
AC_MSG_CHECKING([whether $CC supports -fsanitize=address])
|
|
||||||
saved_cflags="$CFLAGS"
|
|
||||||
CFLAGS="$CFLAGS -fsanitize=address"
|
|
||||||
AC_LINK_IFELSE([
|
|
||||||
AC_LANG_SOURCE([[ int main() { return 0; } ]])
|
|
||||||
], [
|
|
||||||
ASAN_CFLAGS="-fsanitize=address"
|
|
||||||
ASAN_LDFLAGS="-fsanitize=address"
|
|
||||||
ASAN_ZFS="_with_asan"
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
], [
|
|
||||||
AC_MSG_ERROR([$CC does not support -fsanitize=address])
|
|
||||||
])
|
|
||||||
CFLAGS="$saved_cflags"
|
|
||||||
], [
|
|
||||||
ASAN_CFLAGS=""
|
|
||||||
ASAN_LDFLAGS=""
|
|
||||||
ASAN_ZFS="_without_asan"
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_SUBST([ASAN_CFLAGS])
|
|
||||||
AC_SUBST([ASAN_LDFLAGS])
|
|
||||||
AC_SUBST([ASAN_ZFS])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Check if gcc supports -Wframe-larger-than=<size> option.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_FRAME_LARGER_THAN], [
|
|
||||||
AC_MSG_CHECKING([whether $CC supports -Wframe-larger-than=<size>])
|
|
||||||
|
|
||||||
saved_flags="$CFLAGS"
|
|
||||||
CFLAGS="$CFLAGS -Wframe-larger-than=4096"
|
|
||||||
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
|
||||||
FRAME_LARGER_THAN="-Wframe-larger-than=4096"
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
], [
|
|
||||||
FRAME_LARGER_THAN=""
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
])
|
|
||||||
|
|
||||||
CFLAGS="$saved_flags"
|
|
||||||
AC_SUBST([FRAME_LARGER_THAN])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Check if gcc supports -Wno-format-truncation option.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_TRUNCATION], [
|
|
||||||
AC_MSG_CHECKING([whether $CC supports -Wno-format-truncation])
|
|
||||||
|
|
||||||
saved_flags="$CFLAGS"
|
|
||||||
CFLAGS="$CFLAGS -Wno-format-truncation"
|
|
||||||
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
|
||||||
NO_FORMAT_TRUNCATION=-Wno-format-truncation
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
], [
|
|
||||||
NO_FORMAT_TRUNCATION=
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
])
|
|
||||||
|
|
||||||
CFLAGS="$saved_flags"
|
|
||||||
AC_SUBST([NO_FORMAT_TRUNCATION])
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Check if gcc supports -Wno-bool-compare option.
|
|
||||||
dnl #
|
|
||||||
dnl # We actually invoke gcc with the -Wbool-compare option
|
|
||||||
dnl # and infer the 'no-' version does or doesn't exist based upon
|
|
||||||
dnl # the results. This is required because when checking any of
|
|
||||||
dnl # no- prefixed options gcc always returns success.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_BOOL_COMPARE], [
|
|
||||||
AC_MSG_CHECKING([whether $CC supports -Wno-bool-compare])
|
|
||||||
|
|
||||||
saved_flags="$CFLAGS"
|
|
||||||
CFLAGS="$CFLAGS -Wbool-compare"
|
|
||||||
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
|
||||||
NO_BOOL_COMPARE=-Wno-bool-compare
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
], [
|
|
||||||
NO_BOOL_COMPARE=
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
])
|
|
||||||
|
|
||||||
CFLAGS="$saved_flags"
|
|
||||||
AC_SUBST([NO_BOOL_COMPARE])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Check if gcc supports -Wno-unused-but-set-variable option.
|
|
||||||
dnl #
|
|
||||||
dnl # We actually invoke gcc with the -Wunused-but-set-variable option
|
|
||||||
dnl # and infer the 'no-' version does or doesn't exist based upon
|
|
||||||
dnl # the results. This is required because when checking any of
|
|
||||||
dnl # no- prefixed options gcc always returns success.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_UNUSED_BUT_SET_VARIABLE], [
|
|
||||||
AC_MSG_CHECKING([whether $CC supports -Wno-unused-but-set-variable])
|
|
||||||
|
|
||||||
saved_flags="$CFLAGS"
|
|
||||||
CFLAGS="$CFLAGS -Wunused-but-set-variable"
|
|
||||||
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
|
||||||
NO_UNUSED_BUT_SET_VARIABLE=-Wno-unused-but-set-variable
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
], [
|
|
||||||
NO_UNUSED_BUT_SET_VARIABLE=
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
])
|
|
||||||
|
|
||||||
CFLAGS="$saved_flags"
|
|
||||||
AC_SUBST([NO_UNUSED_BUT_SET_VARIABLE])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Check if gcc supports -fno-omit-frame-pointer option.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_OMIT_FRAME_POINTER], [
|
|
||||||
AC_MSG_CHECKING([whether $CC supports -fno-omit-frame-pointer])
|
|
||||||
|
|
||||||
saved_flags="$CFLAGS"
|
|
||||||
CFLAGS="$CFLAGS -fno-omit-frame-pointer"
|
|
||||||
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
|
||||||
NO_OMIT_FRAME_POINTER=-fno-omit-frame-pointer
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
], [
|
|
||||||
NO_OMIT_FRAME_POINTER=
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
])
|
|
||||||
|
|
||||||
CFLAGS="$saved_flags"
|
|
||||||
AC_SUBST([NO_OMIT_FRAME_POINTER])
|
|
||||||
])
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
dnl #
|
||||||
|
dnl # Check if gcc supports -Wno-bool-compare option.
|
||||||
|
dnl #
|
||||||
|
dnl # We actually invoke gcc with the -Wbool-compare option
|
||||||
|
dnl # and infer the 'no-' version does or doesn't exist based upon
|
||||||
|
dnl # the results. This is required because when checking any of
|
||||||
|
dnl # no- prefixed options gcc always returns success.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_NO_BOOL_COMPARE], [
|
||||||
|
AC_MSG_CHECKING([for -Wno-bool-compare support])
|
||||||
|
|
||||||
|
saved_flags="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS -Wbool-compare"
|
||||||
|
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])],
|
||||||
|
[
|
||||||
|
NO_BOOL_COMPARE=-Wno-bool-compare
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
],
|
||||||
|
[
|
||||||
|
NO_BOOL_COMPARE=
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
|
||||||
|
CFLAGS="$saved_flags"
|
||||||
|
AC_SUBST([NO_BOOL_COMPARE])
|
||||||
|
])
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
dnl #
|
||||||
|
dnl # Check if gcc supports -Wno-unused-but-set-variable option.
|
||||||
|
dnl #
|
||||||
|
dnl # We actually invoke gcc with the -Wunused-but-set-variable option
|
||||||
|
dnl # and infer the 'no-' version does or doesn't exist based upon
|
||||||
|
dnl # the results. This is required because when checking any of
|
||||||
|
dnl # no- prefixed options gcc always returns success.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_NO_UNUSED_BUT_SET_VARIABLE], [
|
||||||
|
AC_MSG_CHECKING([for -Wno-unused-but-set-variable support])
|
||||||
|
|
||||||
|
saved_flags="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS -Wunused-but-set-variable"
|
||||||
|
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])],
|
||||||
|
[
|
||||||
|
NO_UNUSED_BUT_SET_VARIABLE=-Wno-unused-but-set-variable
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
],
|
||||||
|
[
|
||||||
|
NO_UNUSED_BUT_SET_VARIABLE=
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
|
||||||
|
CFLAGS="$saved_flags"
|
||||||
|
AC_SUBST([NO_UNUSED_BUT_SET_VARIABLE])
|
||||||
|
])
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
dnl #
|
|
||||||
dnl # The majority of the python scripts are written to be compatible
|
|
||||||
dnl # with Python 2.6 and Python 3.4. Therefore, they may be installed
|
|
||||||
dnl # and used with either interpreter. This option is intended to
|
|
||||||
dnl # to provide a method to specify the default system version, and
|
|
||||||
dnl # set the PYTHON environment variable accordingly.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYTHON], [
|
|
||||||
AC_ARG_WITH([python],
|
|
||||||
AC_HELP_STRING([--with-python[=VERSION]],
|
|
||||||
[default system python version @<:@default=check@:>@]),
|
|
||||||
[with_python=$withval],
|
|
||||||
[with_python=check])
|
|
||||||
|
|
||||||
AS_CASE([$with_python],
|
|
||||||
[check], [AC_CHECK_PROGS([PYTHON], [python3 python2], [:])],
|
|
||||||
[2*], [PYTHON="python${with_python}"],
|
|
||||||
[*python2*], [PYTHON="${with_python}"],
|
|
||||||
[3*], [PYTHON="python${with_python}"],
|
|
||||||
[*python3*], [PYTHON="${with_python}"],
|
|
||||||
[no], [PYTHON=":"],
|
|
||||||
[AC_MSG_ERROR([Unknown --with-python value '$with_python'])]
|
|
||||||
)
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Minimum supported Python versions for utilities:
|
|
||||||
dnl # Python 2.6 or Python 3.4
|
|
||||||
dnl #
|
|
||||||
AM_PATH_PYTHON([], [], [:])
|
|
||||||
AS_IF([test -z "$PYTHON_VERSION"], [
|
|
||||||
PYTHON_VERSION=$(basename $PYTHON | tr -cd 0-9.)
|
|
||||||
])
|
|
||||||
PYTHON_MINOR=${PYTHON_VERSION#*\.}
|
|
||||||
|
|
||||||
AS_CASE([$PYTHON_VERSION],
|
|
||||||
[2.*], [
|
|
||||||
AS_IF([test $PYTHON_MINOR -lt 6],
|
|
||||||
[AC_MSG_ERROR("Python >= 2.6 is required")])
|
|
||||||
],
|
|
||||||
[3.*], [
|
|
||||||
AS_IF([test $PYTHON_MINOR -lt 4],
|
|
||||||
[AC_MSG_ERROR("Python >= 3.4 is required")])
|
|
||||||
],
|
|
||||||
[:|2|3], [],
|
|
||||||
[PYTHON_VERSION=3]
|
|
||||||
)
|
|
||||||
|
|
||||||
AM_CONDITIONAL([USING_PYTHON], [test "$PYTHON" != :])
|
|
||||||
AM_CONDITIONAL([USING_PYTHON_2], [test "x${PYTHON_VERSION%%\.*}" = x2])
|
|
||||||
AM_CONDITIONAL([USING_PYTHON_3], [test "x${PYTHON_VERSION%%\.*}" = x3])
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Request that packages be built for a specific Python version.
|
|
||||||
dnl #
|
|
||||||
AS_IF([test "x$with_python" != xcheck], [
|
|
||||||
PYTHON_PKG_VERSION=$(echo $PYTHON_VERSION | tr -d .)
|
|
||||||
DEFINE_PYTHON_PKG_VERSION='--define "__use_python_pkg_version '${PYTHON_PKG_VERSION}'"'
|
|
||||||
DEFINE_PYTHON_VERSION='--define "__use_python '${PYTHON}'"'
|
|
||||||
], [
|
|
||||||
DEFINE_PYTHON_VERSION=''
|
|
||||||
DEFINE_PYTHON_PKG_VERSION=''
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_SUBST(DEFINE_PYTHON_VERSION)
|
|
||||||
AC_SUBST(DEFINE_PYTHON_PKG_VERSION)
|
|
||||||
])
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
dnl #
|
|
||||||
dnl # ZFS_AC_PYTHON_MODULE(module_name, [action-if-true], [action-if-false])
|
|
||||||
dnl #
|
|
||||||
dnl # Checks for Python module. Freely inspired by AX_PYTHON_MODULE
|
|
||||||
dnl # https://www.gnu.org/software/autoconf-archive/ax_python_module.html
|
|
||||||
dnl # Required by ZFS_AC_CONFIG_ALWAYS_PYZFS.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_PYTHON_MODULE], [
|
|
||||||
PYTHON_NAME=$(basename $PYTHON)
|
|
||||||
AC_MSG_CHECKING([for $PYTHON_NAME module: $1])
|
|
||||||
AS_IF([$PYTHON -c "import $1" 2>/dev/null], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
m4_ifvaln([$2], [$2])
|
|
||||||
], [
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
m4_ifvaln([$3], [$3])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Determines if pyzfs can be built, requires Python 2.7 or later.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
|
||||||
AC_ARG_ENABLE([pyzfs],
|
|
||||||
AC_HELP_STRING([--enable-pyzfs],
|
|
||||||
[install libzfs_core python bindings @<:@default=check@:>@]),
|
|
||||||
[enable_pyzfs=$enableval],
|
|
||||||
[enable_pyzfs=check])
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Packages for pyzfs specifically enabled/disabled.
|
|
||||||
dnl #
|
|
||||||
AS_IF([test "x$enable_pyzfs" != xcheck], [
|
|
||||||
AS_IF([test "x$enable_pyzfs" = xyes], [
|
|
||||||
DEFINE_PYZFS='--with pyzfs'
|
|
||||||
], [
|
|
||||||
DEFINE_PYZFS='--without pyzfs'
|
|
||||||
])
|
|
||||||
], [
|
|
||||||
AS_IF([test "$PYTHON" != :], [
|
|
||||||
DEFINE_PYZFS=''
|
|
||||||
], [
|
|
||||||
enable_pyzfs=no
|
|
||||||
DEFINE_PYZFS='--without pyzfs'
|
|
||||||
])
|
|
||||||
])
|
|
||||||
AC_SUBST(DEFINE_PYZFS)
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Require python-devel libraries
|
|
||||||
dnl #
|
|
||||||
AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [
|
|
||||||
AS_CASE([$PYTHON_VERSION],
|
|
||||||
[3.*], [PYTHON_REQUIRED_VERSION=">= '3.4.0'"],
|
|
||||||
[2.*], [PYTHON_REQUIRED_VERSION=">= '2.7.0'"],
|
|
||||||
[AC_MSG_ERROR("Python $PYTHON_VERSION unknown")]
|
|
||||||
)
|
|
||||||
|
|
||||||
AX_PYTHON_DEVEL([$PYTHON_REQUIRED_VERSION], [
|
|
||||||
AS_IF([test "x$enable_pyzfs" = xyes], [
|
|
||||||
AC_MSG_ERROR("Python $PYTHON_REQUIRED_VERSION development library is not installed")
|
|
||||||
], [test "x$enable_pyzfs" != xno], [
|
|
||||||
enable_pyzfs=no
|
|
||||||
])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Python "setuptools" module is required to build and install pyzfs
|
|
||||||
dnl #
|
|
||||||
AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [
|
|
||||||
ZFS_AC_PYTHON_MODULE([setuptools], [], [
|
|
||||||
AS_IF([test "x$enable_pyzfs" = xyes], [
|
|
||||||
AC_MSG_ERROR("Python $PYTHON_VERSION setuptools is not installed")
|
|
||||||
], [test "x$enable_pyzfs" != xno], [
|
|
||||||
enable_pyzfs=no
|
|
||||||
])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Python "cffi" module is required to run pyzfs
|
|
||||||
dnl #
|
|
||||||
AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [
|
|
||||||
ZFS_AC_PYTHON_MODULE([cffi], [], [
|
|
||||||
AS_IF([test "x$enable_pyzfs" = xyes], [
|
|
||||||
AC_MSG_ERROR("Python $PYTHON_VERSION cffi is not installed")
|
|
||||||
], [test "x$enable_pyzfs" != xno], [
|
|
||||||
enable_pyzfs=no
|
|
||||||
])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # Set enable_pyzfs to 'yes' if every check passed
|
|
||||||
dnl #
|
|
||||||
AS_IF([test "x$enable_pyzfs" = xcheck], [enable_pyzfs=yes])
|
|
||||||
|
|
||||||
AM_CONDITIONAL([PYZFS_ENABLED], [test "x$enable_pyzfs" = xyes])
|
|
||||||
AC_SUBST([PYZFS_ENABLED], [$enable_pyzfs])
|
|
||||||
AC_SUBST(pythonsitedir, [$PYTHON_SITE_PKG])
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether to enable pyzfs: ])
|
|
||||||
AC_MSG_RESULT($enable_pyzfs)
|
|
||||||
])
|
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
# CODE_COVERAGE_LIBS is preferred for clarity; CODE_COVERAGE_LDFLAGS is
|
# CODE_COVERAGE_LIBS is preferred for clarity; CODE_COVERAGE_LDFLAGS is
|
||||||
# deprecated. They have the same value.
|
# deprecated. They have the same value.
|
||||||
#
|
#
|
||||||
# This code was derived from Makefile.decl in GLib, originally licensed
|
# This code was derived from Makefile.decl in GLib, originally licenced
|
||||||
# under LGPLv2.1+.
|
# under LGPLv2.1+.
|
||||||
#
|
#
|
||||||
# LICENSE
|
# LICENSE
|
||||||
|
|||||||
@@ -1,345 +0,0 @@
|
|||||||
# ===========================================================================
|
|
||||||
# https://www.gnu.org/software/autoconf-archive/ax_python_devel.html
|
|
||||||
# ===========================================================================
|
|
||||||
#
|
|
||||||
# SYNOPSIS
|
|
||||||
#
|
|
||||||
# AX_PYTHON_DEVEL([version], [action-if-not-found])
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# Note: Defines as a precious variable "PYTHON_VERSION". Don't override it
|
|
||||||
# in your configure.ac.
|
|
||||||
#
|
|
||||||
# Note: this is a slightly modified version of the original AX_PYTHON_DEVEL
|
|
||||||
# macro which accepts an additional [action-if-not-found] argument. This
|
|
||||||
# allow to detect if Python development is available without aborting the
|
|
||||||
# configure phase with an hard error in case it is not.
|
|
||||||
#
|
|
||||||
# This macro checks for Python and tries to get the include path to
|
|
||||||
# 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LIBS) output
|
|
||||||
# variables. It also exports $(PYTHON_EXTRA_LIBS) and
|
|
||||||
# $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code.
|
|
||||||
#
|
|
||||||
# You can search for some particular version of Python by passing a
|
|
||||||
# parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please
|
|
||||||
# note that you *have* to pass also an operator along with the version to
|
|
||||||
# match, and pay special attention to the single quotes surrounding the
|
|
||||||
# version number. Don't use "PYTHON_VERSION" for this: that environment
|
|
||||||
# variable is declared as precious and thus reserved for the end-user.
|
|
||||||
#
|
|
||||||
# This macro should work for all versions of Python >= 2.1.0. As an end
|
|
||||||
# user, you can disable the check for the python version by setting the
|
|
||||||
# PYTHON_NOVERSIONCHECK environment variable to something else than the
|
|
||||||
# empty string.
|
|
||||||
#
|
|
||||||
# If you need to use this macro for an older Python version, please
|
|
||||||
# contact the authors. We're always open for feedback.
|
|
||||||
#
|
|
||||||
# LICENSE
|
|
||||||
#
|
|
||||||
# Copyright (c) 2009 Sebastian Huber <sebastian-huber@web.de>
|
|
||||||
# Copyright (c) 2009 Alan W. Irwin
|
|
||||||
# Copyright (c) 2009 Rafael Laboissiere <rafael@laboissiere.net>
|
|
||||||
# Copyright (c) 2009 Andrew Collier
|
|
||||||
# Copyright (c) 2009 Matteo Settenvini <matteo@member.fsf.org>
|
|
||||||
# Copyright (c) 2009 Horst Knorr <hk_classes@knoda.org>
|
|
||||||
# Copyright (c) 2013 Daniel Mullner <muellner@math.stanford.edu>
|
|
||||||
# Copyright (c) 2018 loli10K <ezomori.nozomu@gmail.com>
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU General Public License as published by the
|
|
||||||
# Free Software Foundation, either version 3 of the License, or (at your
|
|
||||||
# option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
||||||
# Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along
|
|
||||||
# with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
|
||||||
# gives unlimited permission to copy, distribute and modify the configure
|
|
||||||
# scripts that are the output of Autoconf when processing the Macro. You
|
|
||||||
# need not follow the terms of the GNU General Public License when using
|
|
||||||
# or distributing such scripts, even though portions of the text of the
|
|
||||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
|
||||||
# all other use of the material that constitutes the Autoconf Macro.
|
|
||||||
#
|
|
||||||
# This special exception to the GPL applies to versions of the Autoconf
|
|
||||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
|
||||||
# modified version of the Autoconf Macro, you may extend this special
|
|
||||||
# exception to the GPL to apply to your modified version as well.
|
|
||||||
|
|
||||||
#serial 21
|
|
||||||
|
|
||||||
AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL])
|
|
||||||
AC_DEFUN([AX_PYTHON_DEVEL],[
|
|
||||||
#
|
|
||||||
# Allow the use of a (user set) custom python version
|
|
||||||
#
|
|
||||||
AC_ARG_VAR([PYTHON_VERSION],[The installed Python
|
|
||||||
version to use, for example '2.3'. This string
|
|
||||||
will be appended to the Python interpreter
|
|
||||||
canonical name.])
|
|
||||||
|
|
||||||
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
|
|
||||||
if test -z "$PYTHON"; then
|
|
||||||
m4_ifvaln([$2],[$2],[
|
|
||||||
AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
|
|
||||||
PYTHON_VERSION=""
|
|
||||||
])
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# Check for a version of Python >= 2.1.0
|
|
||||||
#
|
|
||||||
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
|
|
||||||
ac_supports_python_ver=`$PYTHON -c "import sys; \
|
|
||||||
ver = sys.version.split ()[[0]]; \
|
|
||||||
print (ver >= '2.1.0')"`
|
|
||||||
if test "$ac_supports_python_ver" != "True"; then
|
|
||||||
if test -z "$PYTHON_NOVERSIONCHECK"; then
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
m4_ifvaln([$2],[$2],[
|
|
||||||
AC_MSG_FAILURE([
|
|
||||||
This version of the AC@&t@_PYTHON_DEVEL macro
|
|
||||||
doesn't work properly with versions of Python before
|
|
||||||
2.1.0. You may need to re-run configure, setting the
|
|
||||||
variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG,
|
|
||||||
PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
|
|
||||||
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
|
|
||||||
to something else than an empty string.
|
|
||||||
])
|
|
||||||
])
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT([skip at user request])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# if the macro parameter ``version'' is set, honour it
|
|
||||||
#
|
|
||||||
if test -n "$1"; then
|
|
||||||
AC_MSG_CHECKING([for a version of Python $1])
|
|
||||||
ac_supports_python_ver=`$PYTHON -c "import sys; \
|
|
||||||
ver = sys.version.split ()[[0]]; \
|
|
||||||
print (ver $1)"`
|
|
||||||
if test "$ac_supports_python_ver" = "True"; then
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
m4_ifvaln([$2],[$2],[
|
|
||||||
AC_MSG_ERROR([this package requires Python $1.
|
|
||||||
If you have it installed, but it isn't the default Python
|
|
||||||
interpreter in your system path, please pass the PYTHON_VERSION
|
|
||||||
variable to configure. See ``configure --help'' for reference.
|
|
||||||
])
|
|
||||||
PYTHON_VERSION=""
|
|
||||||
])
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# Check if you have distutils, else fail
|
|
||||||
#
|
|
||||||
AC_MSG_CHECKING([for the distutils Python package])
|
|
||||||
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
|
|
||||||
if test $? -eq 0; then
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
m4_ifvaln([$2],[$2],[
|
|
||||||
AC_MSG_ERROR([cannot import Python module "distutils".
|
|
||||||
Please check your Python installation. The error was:
|
|
||||||
$ac_distutils_result])
|
|
||||||
PYTHON_VERSION=""
|
|
||||||
])
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# Check for Python include path
|
|
||||||
#
|
|
||||||
AC_MSG_CHECKING([for Python include path])
|
|
||||||
if test -z "$PYTHON_CPPFLAGS"; then
|
|
||||||
python_path=`$PYTHON -c "import distutils.sysconfig; \
|
|
||||||
print (distutils.sysconfig.get_python_inc ());"`
|
|
||||||
plat_python_path=`$PYTHON -c "import distutils.sysconfig; \
|
|
||||||
print (distutils.sysconfig.get_python_inc (plat_specific=1));"`
|
|
||||||
if test -n "${python_path}"; then
|
|
||||||
if test "${plat_python_path}" != "${python_path}"; then
|
|
||||||
python_path="-I$python_path -I$plat_python_path"
|
|
||||||
else
|
|
||||||
python_path="-I$python_path"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
PYTHON_CPPFLAGS=$python_path
|
|
||||||
fi
|
|
||||||
AC_MSG_RESULT([$PYTHON_CPPFLAGS])
|
|
||||||
AC_SUBST([PYTHON_CPPFLAGS])
|
|
||||||
|
|
||||||
#
|
|
||||||
# Check for Python library path
|
|
||||||
#
|
|
||||||
AC_MSG_CHECKING([for Python library path])
|
|
||||||
if test -z "$PYTHON_LIBS"; then
|
|
||||||
# (makes two attempts to ensure we've got a version number
|
|
||||||
# from the interpreter)
|
|
||||||
ac_python_version=`cat<<EOD | $PYTHON -
|
|
||||||
|
|
||||||
# join all versioning strings, on some systems
|
|
||||||
# major/minor numbers could be in different list elements
|
|
||||||
from distutils.sysconfig import *
|
|
||||||
e = get_config_var('VERSION')
|
|
||||||
if e is not None:
|
|
||||||
print(e)
|
|
||||||
EOD`
|
|
||||||
|
|
||||||
if test -z "$ac_python_version"; then
|
|
||||||
if test -n "$PYTHON_VERSION"; then
|
|
||||||
ac_python_version=$PYTHON_VERSION
|
|
||||||
else
|
|
||||||
ac_python_version=`$PYTHON -c "import sys; \
|
|
||||||
print (sys.version[[:3]])"`
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make the versioning information available to the compiler
|
|
||||||
AC_DEFINE_UNQUOTED([HAVE_PYTHON], ["$ac_python_version"],
|
|
||||||
[If available, contains the Python version number currently in use.])
|
|
||||||
|
|
||||||
# First, the library directory:
|
|
||||||
ac_python_libdir=`cat<<EOD | $PYTHON -
|
|
||||||
|
|
||||||
# There should be only one
|
|
||||||
import distutils.sysconfig
|
|
||||||
e = distutils.sysconfig.get_config_var('LIBDIR')
|
|
||||||
if e is not None:
|
|
||||||
print (e)
|
|
||||||
EOD`
|
|
||||||
|
|
||||||
# Now, for the library:
|
|
||||||
ac_python_library=`cat<<EOD | $PYTHON -
|
|
||||||
|
|
||||||
import distutils.sysconfig
|
|
||||||
c = distutils.sysconfig.get_config_vars()
|
|
||||||
if 'LDVERSION' in c:
|
|
||||||
print ('python'+c[['LDVERSION']])
|
|
||||||
else:
|
|
||||||
print ('python'+c[['VERSION']])
|
|
||||||
EOD`
|
|
||||||
|
|
||||||
# This small piece shamelessly adapted from PostgreSQL python macro;
|
|
||||||
# credits goes to momjian, I think. I'd like to put the right name
|
|
||||||
# in the credits, if someone can point me in the right direction... ?
|
|
||||||
#
|
|
||||||
if test -n "$ac_python_libdir" -a -n "$ac_python_library"
|
|
||||||
then
|
|
||||||
# use the official shared library
|
|
||||||
ac_python_library=`echo "$ac_python_library" | sed "s/^lib//"`
|
|
||||||
PYTHON_LIBS="-L$ac_python_libdir -l$ac_python_library"
|
|
||||||
else
|
|
||||||
# old way: use libpython from python_configdir
|
|
||||||
ac_python_libdir=`$PYTHON -c \
|
|
||||||
"from distutils.sysconfig import get_python_lib as f; \
|
|
||||||
import os; \
|
|
||||||
print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"`
|
|
||||||
PYTHON_LIBS="-L$ac_python_libdir -lpython$ac_python_version"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -z "PYTHON_LIBS"; then
|
|
||||||
m4_ifvaln([$2],[$2],[
|
|
||||||
AC_MSG_ERROR([
|
|
||||||
Cannot determine location of your Python DSO. Please check it was installed with
|
|
||||||
dynamic libraries enabled, or try setting PYTHON_LIBS by hand.
|
|
||||||
])
|
|
||||||
])
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
AC_MSG_RESULT([$PYTHON_LIBS])
|
|
||||||
AC_SUBST([PYTHON_LIBS])
|
|
||||||
|
|
||||||
#
|
|
||||||
# Check for site packages
|
|
||||||
#
|
|
||||||
AC_MSG_CHECKING([for Python site-packages path])
|
|
||||||
if test -z "$PYTHON_SITE_PKG"; then
|
|
||||||
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
|
|
||||||
print (distutils.sysconfig.get_python_lib(0,0));"`
|
|
||||||
fi
|
|
||||||
AC_MSG_RESULT([$PYTHON_SITE_PKG])
|
|
||||||
AC_SUBST([PYTHON_SITE_PKG])
|
|
||||||
|
|
||||||
#
|
|
||||||
# libraries which must be linked in when embedding
|
|
||||||
#
|
|
||||||
AC_MSG_CHECKING(python extra libraries)
|
|
||||||
if test -z "$PYTHON_EXTRA_LIBS"; then
|
|
||||||
PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
|
|
||||||
conf = distutils.sysconfig.get_config_var; \
|
|
||||||
print (conf('LIBS') + ' ' + conf('SYSLIBS'))"`
|
|
||||||
fi
|
|
||||||
AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
|
|
||||||
AC_SUBST(PYTHON_EXTRA_LIBS)
|
|
||||||
|
|
||||||
#
|
|
||||||
# linking flags needed when embedding
|
|
||||||
#
|
|
||||||
AC_MSG_CHECKING(python extra linking flags)
|
|
||||||
if test -z "$PYTHON_EXTRA_LDFLAGS"; then
|
|
||||||
PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
|
|
||||||
conf = distutils.sysconfig.get_config_var; \
|
|
||||||
print (conf('LINKFORSHARED'))"`
|
|
||||||
fi
|
|
||||||
AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
|
|
||||||
AC_SUBST(PYTHON_EXTRA_LDFLAGS)
|
|
||||||
|
|
||||||
#
|
|
||||||
# final check to see if everything compiles alright
|
|
||||||
#
|
|
||||||
AC_MSG_CHECKING([consistency of all components of python development environment])
|
|
||||||
# save current global flags
|
|
||||||
ac_save_LIBS="$LIBS"
|
|
||||||
ac_save_LDFLAGS="$LDFLAGS"
|
|
||||||
ac_save_CPPFLAGS="$CPPFLAGS"
|
|
||||||
LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS $PYTHON_EXTRA_LIBS"
|
|
||||||
LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS"
|
|
||||||
CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
|
|
||||||
AC_LANG_PUSH([C])
|
|
||||||
AC_LINK_IFELSE([
|
|
||||||
AC_LANG_PROGRAM([[#include <Python.h>]],
|
|
||||||
[[Py_Initialize();]])
|
|
||||||
],[pythonexists=yes],[pythonexists=no])
|
|
||||||
AC_LANG_POP([C])
|
|
||||||
# turn back to default flags
|
|
||||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
|
||||||
LIBS="$ac_save_LIBS"
|
|
||||||
LDFLAGS="$ac_save_LDFLAGS"
|
|
||||||
|
|
||||||
AC_MSG_RESULT([$pythonexists])
|
|
||||||
|
|
||||||
if test ! "x$pythonexists" = "xyes"; then
|
|
||||||
m4_ifvaln([$2],[$2],[
|
|
||||||
AC_MSG_FAILURE([
|
|
||||||
Could not link test program to Python. Maybe the main Python library has been
|
|
||||||
installed in some non-standard library path. If so, pass it to configure,
|
|
||||||
via the LIBS environment variable.
|
|
||||||
Example: ./configure LIBS="-L/usr/non-standard-path/python/lib"
|
|
||||||
============================================================================
|
|
||||||
ERROR!
|
|
||||||
You probably have to install the development version of the Python package
|
|
||||||
for your distribution. The exact name of this package varies among them.
|
|
||||||
============================================================================
|
|
||||||
])
|
|
||||||
PYTHON_VERSION=""
|
|
||||||
])
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# all done!
|
|
||||||
#
|
|
||||||
])
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
# ===========================================================================
|
|
||||||
# http://www.gnu.org/software/autoconf-archive/ax_restore_flags.html
|
|
||||||
# ===========================================================================
|
|
||||||
#
|
|
||||||
# SYNOPSIS
|
|
||||||
#
|
|
||||||
# AX_RESTORE_FLAGS()
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# Restore common compilation flags from temporary variables
|
|
||||||
#
|
|
||||||
# LICENSE
|
|
||||||
#
|
|
||||||
# Copyright (c) 2009 Filippo Giunchedi <filippo@esaurito.net>
|
|
||||||
#
|
|
||||||
# Copying and distribution of this file, with or without modification, are
|
|
||||||
# permitted in any medium without royalty provided the copyright notice
|
|
||||||
# and this notice are preserved. This file is offered as-is, without any
|
|
||||||
# warranty.
|
|
||||||
|
|
||||||
#serial 3
|
|
||||||
|
|
||||||
AC_DEFUN([AX_RESTORE_FLAGS], [
|
|
||||||
CPPFLAGS="${CPPFLAGS_save}"
|
|
||||||
CFLAGS="${CFLAGS_save}"
|
|
||||||
CXXFLAGS="${CXXFLAGS_save}"
|
|
||||||
OBJCFLAGS="${OBJCFLAGS_save}"
|
|
||||||
LDFLAGS="${LDFLAGS_save}"
|
|
||||||
LIBS="${LIBS_save}"
|
|
||||||
])
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
# ===========================================================================
|
|
||||||
# http://www.gnu.org/software/autoconf-archive/ax_save_flags.html
|
|
||||||
# ===========================================================================
|
|
||||||
#
|
|
||||||
# SYNOPSIS
|
|
||||||
#
|
|
||||||
# AX_SAVE_FLAGS()
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# Save common compilation flags into temporary variables
|
|
||||||
#
|
|
||||||
# LICENSE
|
|
||||||
#
|
|
||||||
# Copyright (c) 2009 Filippo Giunchedi <filippo@esaurito.net>
|
|
||||||
#
|
|
||||||
# Copying and distribution of this file, with or without modification, are
|
|
||||||
# permitted in any medium without royalty provided the copyright notice
|
|
||||||
# and this notice are preserved. This file is offered as-is, without any
|
|
||||||
# warranty.
|
|
||||||
|
|
||||||
#serial 3
|
|
||||||
|
|
||||||
AC_DEFUN([AX_SAVE_FLAGS], [
|
|
||||||
CPPFLAGS_save="${CPPFLAGS}"
|
|
||||||
CFLAGS_save="${CFLAGS}"
|
|
||||||
CXXFLAGS_save="${CXXFLAGS}"
|
|
||||||
OBJCFLAGS_save="${OBJCFLAGS}"
|
|
||||||
LDFLAGS_save="${LDFLAGS}"
|
|
||||||
LIBS_save="${LIBS}"
|
|
||||||
])
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# `make distclean` deletes files with size 0. This text is to avoid that.
|
|
||||||
+5
-6
@@ -20,7 +20,7 @@ deb-kmod: deb-local rpm-kmod
|
|||||||
arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
|
arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
|
||||||
debarch=`$(DPKG) --print-architecture`; \
|
debarch=`$(DPKG) --print-architecture`; \
|
||||||
pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
|
pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
|
||||||
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1 || exit 1; \
|
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1; \
|
||||||
$(RM) $$pkg1
|
$(RM) $$pkg1
|
||||||
|
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ deb-dkms: deb-local rpm-dkms
|
|||||||
arch=`$(RPM) -qp $${name}-dkms-$${version}.src.rpm --qf %{arch} | tail -1`; \
|
arch=`$(RPM) -qp $${name}-dkms-$${version}.src.rpm --qf %{arch} | tail -1`; \
|
||||||
debarch=`$(DPKG) --print-architecture`; \
|
debarch=`$(DPKG) --print-architecture`; \
|
||||||
pkg1=$${name}-dkms-$${version}.$${arch}.rpm; \
|
pkg1=$${name}-dkms-$${version}.$${arch}.rpm; \
|
||||||
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1 || exit 1; \
|
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1; \
|
||||||
$(RM) $$pkg1
|
$(RM) $$pkg1
|
||||||
|
|
||||||
deb-utils: deb-local rpm-utils
|
deb-utils: deb-local rpm-utils
|
||||||
@@ -45,9 +45,8 @@ deb-utils: deb-local rpm-utils
|
|||||||
pkg5=libzpool2-$${version}.$${arch}.rpm; \
|
pkg5=libzpool2-$${version}.$${arch}.rpm; \
|
||||||
pkg6=libzfs2-devel-$${version}.$${arch}.rpm; \
|
pkg6=libzfs2-devel-$${version}.$${arch}.rpm; \
|
||||||
pkg7=$${name}-test-$${version}.$${arch}.rpm; \
|
pkg7=$${name}-test-$${version}.$${arch}.rpm; \
|
||||||
pkg8=$${name}-dracut-$${version}.noarch.rpm; \
|
pkg8=$${name}-dracut-$${version}.$${arch}.rpm; \
|
||||||
pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \
|
pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \
|
||||||
pkg10=`ls python*-pyzfs-$${version}* | tail -1`; \
|
|
||||||
## Arguments need to be passed to dh_shlibdeps. Alien provides no mechanism
|
## Arguments need to be passed to dh_shlibdeps. Alien provides no mechanism
|
||||||
## to do this, so we install a shim onto the path which calls the real
|
## to do this, so we install a shim onto the path which calls the real
|
||||||
## dh_shlibdeps with the required arguments.
|
## dh_shlibdeps with the required arguments.
|
||||||
@@ -63,10 +62,10 @@ deb-utils: deb-local rpm-utils
|
|||||||
env PATH=$${path_prepend}:$${PATH} \
|
env PATH=$${path_prepend}:$${PATH} \
|
||||||
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch \
|
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch \
|
||||||
$$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
|
$$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
|
||||||
$$pkg8 $$pkg9 $$pkg10 || exit 1; \
|
$$pkg8 $$pkg9; \
|
||||||
$(RM) $${path_prepend}/dh_shlibdeps; \
|
$(RM) $${path_prepend}/dh_shlibdeps; \
|
||||||
rmdir $${path_prepend}; \
|
rmdir $${path_prepend}; \
|
||||||
$(RM) $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
|
$(RM) $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
|
||||||
$$pkg8 $$pkg9 $$pkg10;
|
$$pkg8 $$pkg9;
|
||||||
|
|
||||||
deb: deb-kmod deb-dkms deb-utils
|
deb: deb-kmod deb-dkms deb-utils
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
# find_system_lib.m4 - Macros to search for a system library. -*- Autoconf -*-
|
|
||||||
|
|
||||||
dnl requires pkg.m4 from pkg-config
|
|
||||||
dnl requires ax_save_flags.m4 from autoconf-archive
|
|
||||||
dnl requires ax_restore_flags.m4 from autoconf-archive
|
|
||||||
|
|
||||||
dnl FIND_SYSTEM_LIBRARY(VARIABLE-PREFIX, MODULE, HEADER, HEADER-PREFIXES, LIBRARY, FUNCTIONS, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
|
||||||
|
|
||||||
AC_DEFUN([FIND_SYSTEM_LIBRARY], [
|
|
||||||
AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
|
||||||
|
|
||||||
_library_found=
|
|
||||||
|
|
||||||
PKG_CHECK_MODULES([$1], [$2], [_library_found=1], [
|
|
||||||
AS_IF([test -f /usr/include/[$3]], [
|
|
||||||
AC_SUBST([$1][_CFLAGS], [])
|
|
||||||
AC_SUBST([$1][_LIBS], ["-l[$5]]")
|
|
||||||
_library_found=1
|
|
||||||
],[ AS_IF([test -f /usr/local/include/[$3]], [
|
|
||||||
AC_SUBST([$1][_CFLAGS], ["-I/usr/local/include"])
|
|
||||||
AC_SUBST([$1][_LIBS], ["-L/usr/local -l[$5]]")
|
|
||||||
_library_found=1
|
|
||||||
],[dnl ELSE
|
|
||||||
m4_foreach([prefix], [$4], [
|
|
||||||
AS_IF([test "x$_library_found" != "x1"], [
|
|
||||||
AS_IF([test -f [/usr/include/]prefix[/][$3]], [
|
|
||||||
AC_SUBST([$1][_CFLAGS], ["[-I/usr/include/]prefix["]])
|
|
||||||
AC_SUBST([$1][_LIBS], ["-l[$5]]")
|
|
||||||
_library_found=1
|
|
||||||
],[ AS_IF([test -f [/usr/local/include/]prefix[/][$3]], [
|
|
||||||
AC_SUBST([$1][_CFLAGS], ["[-I/usr/local/include/]prefix["]])
|
|
||||||
AC_SUBST([$1][_LIBS], ["-L/usr/local -l[$5]"])
|
|
||||||
_library_found=1
|
|
||||||
])])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
])])
|
|
||||||
|
|
||||||
AS_IF([test -z "$_library_found"], [
|
|
||||||
AC_MSG_WARN([cannot find [$2] via pkg-config or in the standard locations])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl do some further sanity checks
|
|
||||||
|
|
||||||
AS_IF([test -n "$_library_found"], [
|
|
||||||
AX_SAVE_FLAGS
|
|
||||||
|
|
||||||
CPPFLAGS="$CPPFLAGS $(echo $[$1][_CFLAGS] | sed 's/-include */-include-/g; s/^/ /; s/ [^-][^ ]*//g; s/ -[^Ii][^ ]*//g; s/-include-/-include /g; s/^ //;')"
|
|
||||||
CFLAGS="$CFLAGS $[$1][_CFLAGS]"
|
|
||||||
LDFLAGS="$LDFLAGS $[$1][_LIBS]"
|
|
||||||
|
|
||||||
AC_CHECK_HEADER([$3], [], [
|
|
||||||
AC_MSG_WARN([header [$3] for library [$2] is not usable])
|
|
||||||
_library_found=
|
|
||||||
])
|
|
||||||
|
|
||||||
m4_foreach([func], [$6], [
|
|
||||||
AC_CHECK_LIB([$5], func, [], [
|
|
||||||
AC_MSG_WARN([cannot find ]func[ in library [$5]])
|
|
||||||
_library_found=
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AX_RESTORE_FLAGS
|
|
||||||
])
|
|
||||||
|
|
||||||
AS_IF([test -n "$_library_found"], [
|
|
||||||
:;$7
|
|
||||||
],[dnl ELSE
|
|
||||||
:;$8
|
|
||||||
])
|
|
||||||
])
|
|
||||||
@@ -1,386 +0,0 @@
|
|||||||
# gettext.m4 serial 70 (gettext-0.20)
|
|
||||||
dnl Copyright (C) 1995-2014, 2016, 2018 Free Software Foundation, Inc.
|
|
||||||
dnl This file is free software; the Free Software Foundation
|
|
||||||
dnl gives unlimited permission to copy and/or distribute it,
|
|
||||||
dnl with or without modifications, as long as this notice is preserved.
|
|
||||||
dnl
|
|
||||||
dnl This file can be used in projects which are not available under
|
|
||||||
dnl the GNU General Public License or the GNU Library General Public
|
|
||||||
dnl License but which still want to provide support for the GNU gettext
|
|
||||||
dnl functionality.
|
|
||||||
dnl Please note that the actual code of the GNU gettext library is covered
|
|
||||||
dnl by the GNU Library General Public License, and the rest of the GNU
|
|
||||||
dnl gettext package is covered by the GNU General Public License.
|
|
||||||
dnl They are *not* in the public domain.
|
|
||||||
|
|
||||||
dnl Authors:
|
|
||||||
dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
|
|
||||||
dnl Bruno Haible <haible@clisp.cons.org>, 2000-2006, 2008-2010.
|
|
||||||
|
|
||||||
dnl Macro to add for using GNU gettext.
|
|
||||||
|
|
||||||
dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
|
|
||||||
dnl INTLSYMBOL must be one of 'external', 'use-libtool'.
|
|
||||||
dnl INTLSYMBOL should be 'external' for packages other than GNU gettext, and
|
|
||||||
dnl 'use-libtool' for the packages 'gettext-runtime' and 'gettext-tools'.
|
|
||||||
dnl If INTLSYMBOL is 'use-libtool', then a libtool library
|
|
||||||
dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static,
|
|
||||||
dnl depending on --{enable,disable}-{shared,static} and on the presence of
|
|
||||||
dnl AM-DISABLE-SHARED).
|
|
||||||
dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
|
|
||||||
dnl implementations (in libc or libintl) without the ngettext() function
|
|
||||||
dnl will be ignored. If NEEDSYMBOL is specified and is
|
|
||||||
dnl 'need-formatstring-macros', then GNU gettext implementations that don't
|
|
||||||
dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
|
|
||||||
dnl INTLDIR is used to find the intl libraries. If empty,
|
|
||||||
dnl the value '$(top_builddir)/intl/' is used.
|
|
||||||
dnl
|
|
||||||
dnl The result of the configuration is one of three cases:
|
|
||||||
dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
|
|
||||||
dnl and used.
|
|
||||||
dnl Catalog format: GNU --> install in $(datadir)
|
|
||||||
dnl Catalog extension: .mo after installation, .gmo in source tree
|
|
||||||
dnl 2) GNU gettext has been found in the system's C library.
|
|
||||||
dnl Catalog format: GNU --> install in $(datadir)
|
|
||||||
dnl Catalog extension: .mo after installation, .gmo in source tree
|
|
||||||
dnl 3) No internationalization, always use English msgid.
|
|
||||||
dnl Catalog format: none
|
|
||||||
dnl Catalog extension: none
|
|
||||||
dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur.
|
|
||||||
dnl The use of .gmo is historical (it was needed to avoid overwriting the
|
|
||||||
dnl GNU format catalogs when building on a platform with an X/Open gettext),
|
|
||||||
dnl but we keep it in order not to force irrelevant filename changes on the
|
|
||||||
dnl maintainers.
|
|
||||||
dnl
|
|
||||||
AC_DEFUN([AM_GNU_GETTEXT],
|
|
||||||
[
|
|
||||||
dnl Argument checking.
|
|
||||||
ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [use-libtool], ,
|
|
||||||
[errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
|
|
||||||
])])])])
|
|
||||||
ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old],
|
|
||||||
[errprint([ERROR: Use of AM_GNU_GETTEXT without [external] argument is no longer supported.
|
|
||||||
])])
|
|
||||||
ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
|
|
||||||
[errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
|
|
||||||
])])])])
|
|
||||||
define([gt_included_intl],
|
|
||||||
ifelse([$1], [external], [no], [yes]))
|
|
||||||
gt_NEEDS_INIT
|
|
||||||
AM_GNU_GETTEXT_NEED([$2])
|
|
||||||
|
|
||||||
AC_REQUIRE([AM_PO_SUBDIRS])dnl
|
|
||||||
ifelse(gt_included_intl, yes, [
|
|
||||||
AC_REQUIRE([AM_INTL_SUBDIR])dnl
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
|
|
||||||
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
|
|
||||||
AC_REQUIRE([AC_LIB_RPATH])
|
|
||||||
|
|
||||||
dnl Sometimes libintl requires libiconv, so first search for libiconv.
|
|
||||||
dnl Ideally we would do this search only after the
|
|
||||||
dnl if test "$USE_NLS" = "yes"; then
|
|
||||||
dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
|
|
||||||
dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT
|
|
||||||
dnl the configure script would need to contain the same shell code
|
|
||||||
dnl again, outside any 'if'. There are two solutions:
|
|
||||||
dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
|
|
||||||
dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
|
|
||||||
dnl Since AC_PROVIDE_IFELSE is not documented, we avoid it.
|
|
||||||
ifelse(gt_included_intl, yes, , [
|
|
||||||
AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl Sometimes, on Mac OS X, libintl requires linking with CoreFoundation.
|
|
||||||
gt_INTL_MACOSX
|
|
||||||
|
|
||||||
dnl Set USE_NLS.
|
|
||||||
AC_REQUIRE([AM_NLS])
|
|
||||||
|
|
||||||
ifelse(gt_included_intl, yes, [
|
|
||||||
BUILD_INCLUDED_LIBINTL=no
|
|
||||||
USE_INCLUDED_LIBINTL=no
|
|
||||||
])
|
|
||||||
LIBINTL=
|
|
||||||
LTLIBINTL=
|
|
||||||
POSUB=
|
|
||||||
|
|
||||||
dnl Add a version number to the cache macros.
|
|
||||||
case " $gt_needs " in
|
|
||||||
*" need-formatstring-macros "*) gt_api_version=3 ;;
|
|
||||||
*" need-ngettext "*) gt_api_version=2 ;;
|
|
||||||
*) gt_api_version=1 ;;
|
|
||||||
esac
|
|
||||||
gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
|
|
||||||
gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
|
|
||||||
|
|
||||||
dnl If we use NLS figure out what method
|
|
||||||
if test "$USE_NLS" = "yes"; then
|
|
||||||
gt_use_preinstalled_gnugettext=no
|
|
||||||
ifelse(gt_included_intl, yes, [
|
|
||||||
AC_MSG_CHECKING([whether included gettext is requested])
|
|
||||||
AC_ARG_WITH([included-gettext],
|
|
||||||
[ --with-included-gettext use the GNU gettext library included here],
|
|
||||||
nls_cv_force_use_gnu_gettext=$withval,
|
|
||||||
nls_cv_force_use_gnu_gettext=no)
|
|
||||||
AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext])
|
|
||||||
|
|
||||||
nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
|
|
||||||
if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
|
|
||||||
])
|
|
||||||
dnl User does not insist on using GNU NLS library. Figure out what
|
|
||||||
dnl to use. If GNU gettext is available we use this. Else we have
|
|
||||||
dnl to fall back to GNU NLS library.
|
|
||||||
|
|
||||||
if test $gt_api_version -ge 3; then
|
|
||||||
gt_revision_test_code='
|
|
||||||
#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
|
|
||||||
#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
|
|
||||||
#endif
|
|
||||||
changequote(,)dnl
|
|
||||||
typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
|
|
||||||
changequote([,])dnl
|
|
||||||
'
|
|
||||||
else
|
|
||||||
gt_revision_test_code=
|
|
||||||
fi
|
|
||||||
if test $gt_api_version -ge 2; then
|
|
||||||
gt_expression_test_code=' + * ngettext ("", "", 0)'
|
|
||||||
else
|
|
||||||
gt_expression_test_code=
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
|
|
||||||
[AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[[
|
|
||||||
#include <libintl.h>
|
|
||||||
#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
|
|
||||||
extern int _nl_msg_cat_cntr;
|
|
||||||
extern int *_nl_domain_bindings;
|
|
||||||
#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings)
|
|
||||||
#else
|
|
||||||
#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0
|
|
||||||
#endif
|
|
||||||
$gt_revision_test_code
|
|
||||||
]],
|
|
||||||
[[
|
|
||||||
bindtextdomain ("", "");
|
|
||||||
return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION
|
|
||||||
]])],
|
|
||||||
[eval "$gt_func_gnugettext_libc=yes"],
|
|
||||||
[eval "$gt_func_gnugettext_libc=no"])])
|
|
||||||
|
|
||||||
if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
|
|
||||||
dnl Sometimes libintl requires libiconv, so first search for libiconv.
|
|
||||||
ifelse(gt_included_intl, yes, , [
|
|
||||||
AM_ICONV_LINK
|
|
||||||
])
|
|
||||||
dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL
|
|
||||||
dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv])
|
|
||||||
dnl because that would add "-liconv" to LIBINTL and LTLIBINTL
|
|
||||||
dnl even if libiconv doesn't exist.
|
|
||||||
AC_LIB_LINKFLAGS_BODY([intl])
|
|
||||||
AC_CACHE_CHECK([for GNU gettext in libintl],
|
|
||||||
[$gt_func_gnugettext_libintl],
|
|
||||||
[gt_save_CPPFLAGS="$CPPFLAGS"
|
|
||||||
CPPFLAGS="$CPPFLAGS $INCINTL"
|
|
||||||
gt_save_LIBS="$LIBS"
|
|
||||||
LIBS="$LIBS $LIBINTL"
|
|
||||||
dnl Now see whether libintl exists and does not depend on libiconv.
|
|
||||||
AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[[
|
|
||||||
#include <libintl.h>
|
|
||||||
#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
|
|
||||||
extern int _nl_msg_cat_cntr;
|
|
||||||
extern
|
|
||||||
#ifdef __cplusplus
|
|
||||||
"C"
|
|
||||||
#endif
|
|
||||||
const char *_nl_expand_alias (const char *);
|
|
||||||
#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias (""))
|
|
||||||
#else
|
|
||||||
#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0
|
|
||||||
#endif
|
|
||||||
$gt_revision_test_code
|
|
||||||
]],
|
|
||||||
[[
|
|
||||||
bindtextdomain ("", "");
|
|
||||||
return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION
|
|
||||||
]])],
|
|
||||||
[eval "$gt_func_gnugettext_libintl=yes"],
|
|
||||||
[eval "$gt_func_gnugettext_libintl=no"])
|
|
||||||
dnl Now see whether libintl exists and depends on libiconv.
|
|
||||||
if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
|
|
||||||
LIBS="$LIBS $LIBICONV"
|
|
||||||
AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[[
|
|
||||||
#include <libintl.h>
|
|
||||||
#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
|
|
||||||
extern int _nl_msg_cat_cntr;
|
|
||||||
extern
|
|
||||||
#ifdef __cplusplus
|
|
||||||
"C"
|
|
||||||
#endif
|
|
||||||
const char *_nl_expand_alias (const char *);
|
|
||||||
#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias (""))
|
|
||||||
#else
|
|
||||||
#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0
|
|
||||||
#endif
|
|
||||||
$gt_revision_test_code
|
|
||||||
]],
|
|
||||||
[[
|
|
||||||
bindtextdomain ("", "");
|
|
||||||
return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION
|
|
||||||
]])],
|
|
||||||
[LIBINTL="$LIBINTL $LIBICONV"
|
|
||||||
LTLIBINTL="$LTLIBINTL $LTLIBICONV"
|
|
||||||
eval "$gt_func_gnugettext_libintl=yes"
|
|
||||||
])
|
|
||||||
fi
|
|
||||||
CPPFLAGS="$gt_save_CPPFLAGS"
|
|
||||||
LIBS="$gt_save_LIBS"])
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl If an already present or preinstalled GNU gettext() is found,
|
|
||||||
dnl use it. But if this macro is used in GNU gettext, and GNU
|
|
||||||
dnl gettext is already preinstalled in libintl, we update this
|
|
||||||
dnl libintl. (Cf. the install rule in intl/Makefile.in.)
|
|
||||||
if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \
|
|
||||||
|| { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \
|
|
||||||
&& test "$PACKAGE" != gettext-runtime \
|
|
||||||
&& test "$PACKAGE" != gettext-tools; }; then
|
|
||||||
gt_use_preinstalled_gnugettext=yes
|
|
||||||
else
|
|
||||||
dnl Reset the values set by searching for libintl.
|
|
||||||
LIBINTL=
|
|
||||||
LTLIBINTL=
|
|
||||||
INCINTL=
|
|
||||||
fi
|
|
||||||
|
|
||||||
ifelse(gt_included_intl, yes, [
|
|
||||||
if test "$gt_use_preinstalled_gnugettext" != "yes"; then
|
|
||||||
dnl GNU gettext is not found in the C library.
|
|
||||||
dnl Fall back on included GNU gettext library.
|
|
||||||
nls_cv_use_gnu_gettext=yes
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$nls_cv_use_gnu_gettext" = "yes"; then
|
|
||||||
dnl Mark actions used to generate GNU NLS library.
|
|
||||||
BUILD_INCLUDED_LIBINTL=yes
|
|
||||||
USE_INCLUDED_LIBINTL=yes
|
|
||||||
LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.la $LIBICONV $LIBTHREAD"
|
|
||||||
LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.la $LTLIBICONV $LTLIBTHREAD"
|
|
||||||
LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
|
|
||||||
fi
|
|
||||||
|
|
||||||
CATOBJEXT=
|
|
||||||
if test "$gt_use_preinstalled_gnugettext" = "yes" \
|
|
||||||
|| test "$nls_cv_use_gnu_gettext" = "yes"; then
|
|
||||||
dnl Mark actions to use GNU gettext tools.
|
|
||||||
CATOBJEXT=.gmo
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
|
|
||||||
if test -n "$INTL_MACOSX_LIBS"; then
|
|
||||||
if test "$gt_use_preinstalled_gnugettext" = "yes" \
|
|
||||||
|| test "$nls_cv_use_gnu_gettext" = "yes"; then
|
|
||||||
dnl Some extra flags are needed during linking.
|
|
||||||
LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
|
|
||||||
LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$gt_use_preinstalled_gnugettext" = "yes" \
|
|
||||||
|| test "$nls_cv_use_gnu_gettext" = "yes"; then
|
|
||||||
AC_DEFINE([ENABLE_NLS], [1],
|
|
||||||
[Define to 1 if translation of program messages to the user's native language
|
|
||||||
is requested.])
|
|
||||||
else
|
|
||||||
USE_NLS=no
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether to use NLS])
|
|
||||||
AC_MSG_RESULT([$USE_NLS])
|
|
||||||
if test "$USE_NLS" = "yes"; then
|
|
||||||
AC_MSG_CHECKING([where the gettext function comes from])
|
|
||||||
if test "$gt_use_preinstalled_gnugettext" = "yes"; then
|
|
||||||
if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
|
|
||||||
gt_source="external libintl"
|
|
||||||
else
|
|
||||||
gt_source="libc"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
gt_source="included intl directory"
|
|
||||||
fi
|
|
||||||
AC_MSG_RESULT([$gt_source])
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$USE_NLS" = "yes"; then
|
|
||||||
|
|
||||||
if test "$gt_use_preinstalled_gnugettext" = "yes"; then
|
|
||||||
if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
|
|
||||||
AC_MSG_CHECKING([how to link with libintl])
|
|
||||||
AC_MSG_RESULT([$LIBINTL])
|
|
||||||
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL])
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl For backward compatibility. Some packages may be using this.
|
|
||||||
AC_DEFINE([HAVE_GETTEXT], [1],
|
|
||||||
[Define if the GNU gettext() function is already present or preinstalled.])
|
|
||||||
AC_DEFINE([HAVE_DCGETTEXT], [1],
|
|
||||||
[Define if the GNU dcgettext() function is already present or preinstalled.])
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl We need to process the po/ directory.
|
|
||||||
POSUB=po
|
|
||||||
fi
|
|
||||||
|
|
||||||
ifelse(gt_included_intl, yes, [
|
|
||||||
dnl In GNU gettext we have to set BUILD_INCLUDED_LIBINTL to 'yes'
|
|
||||||
dnl because some of the testsuite requires it.
|
|
||||||
BUILD_INCLUDED_LIBINTL=yes
|
|
||||||
|
|
||||||
dnl Make all variables we use known to autoconf.
|
|
||||||
AC_SUBST([BUILD_INCLUDED_LIBINTL])
|
|
||||||
AC_SUBST([USE_INCLUDED_LIBINTL])
|
|
||||||
AC_SUBST([CATOBJEXT])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl For backward compatibility. Some Makefiles may be using this.
|
|
||||||
INTLLIBS="$LIBINTL"
|
|
||||||
AC_SUBST([INTLLIBS])
|
|
||||||
|
|
||||||
dnl Make all documented variables known to autoconf.
|
|
||||||
AC_SUBST([LIBINTL])
|
|
||||||
AC_SUBST([LTLIBINTL])
|
|
||||||
AC_SUBST([POSUB])
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized.
|
|
||||||
m4_define([gt_NEEDS_INIT],
|
|
||||||
[
|
|
||||||
m4_divert_text([DEFAULTS], [gt_needs=])
|
|
||||||
m4_define([gt_NEEDS_INIT], [])
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL])
|
|
||||||
AC_DEFUN([AM_GNU_GETTEXT_NEED],
|
|
||||||
[
|
|
||||||
m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"])
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
|
|
||||||
AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
|
|
||||||
|
|
||||||
|
|
||||||
dnl Usage: AM_GNU_GETTEXT_REQUIRE_VERSION([gettext-version])
|
|
||||||
AC_DEFUN([AM_GNU_GETTEXT_REQUIRE_VERSION], [])
|
|
||||||
@@ -1,644 +0,0 @@
|
|||||||
# host-cpu-c-abi.m4 serial 11
|
|
||||||
dnl Copyright (C) 2002-2019 Free Software Foundation, Inc.
|
|
||||||
dnl This file is free software; the Free Software Foundation
|
|
||||||
dnl gives unlimited permission to copy and/or distribute it,
|
|
||||||
dnl with or without modifications, as long as this notice is preserved.
|
|
||||||
|
|
||||||
dnl From Bruno Haible and Sam Steingold.
|
|
||||||
|
|
||||||
dnl Sets the HOST_CPU variable to the canonical name of the CPU.
|
|
||||||
dnl Sets the HOST_CPU_C_ABI variable to the canonical name of the CPU with its
|
|
||||||
dnl C language ABI (application binary interface).
|
|
||||||
dnl Also defines __${HOST_CPU}__ and __${HOST_CPU_C_ABI}__ as C macros in
|
|
||||||
dnl config.h.
|
|
||||||
dnl
|
|
||||||
dnl This canonical name can be used to select a particular assembly language
|
|
||||||
dnl source file that will interoperate with C code on the given host.
|
|
||||||
dnl
|
|
||||||
dnl For example:
|
|
||||||
dnl * 'i386' and 'sparc' are different canonical names, because code for i386
|
|
||||||
dnl will not run on SPARC CPUs and vice versa. They have different
|
|
||||||
dnl instruction sets.
|
|
||||||
dnl * 'sparc' and 'sparc64' are different canonical names, because code for
|
|
||||||
dnl 'sparc' and code for 'sparc64' cannot be linked together: 'sparc' code
|
|
||||||
dnl contains 32-bit instructions, whereas 'sparc64' code contains 64-bit
|
|
||||||
dnl instructions. A process on a SPARC CPU can be in 32-bit mode or in 64-bit
|
|
||||||
dnl mode, but not both.
|
|
||||||
dnl * 'mips' and 'mipsn32' are different canonical names, because they use
|
|
||||||
dnl different argument passing and return conventions for C functions, and
|
|
||||||
dnl although the instruction set of 'mips' is a large subset of the
|
|
||||||
dnl instruction set of 'mipsn32'.
|
|
||||||
dnl * 'mipsn32' and 'mips64' are different canonical names, because they use
|
|
||||||
dnl different sizes for the C types like 'int' and 'void *', and although
|
|
||||||
dnl the instruction sets of 'mipsn32' and 'mips64' are the same.
|
|
||||||
dnl * The same canonical name is used for different endiannesses. You can
|
|
||||||
dnl determine the endianness through preprocessor symbols:
|
|
||||||
dnl - 'arm': test __ARMEL__.
|
|
||||||
dnl - 'mips', 'mipsn32', 'mips64': test _MIPSEB vs. _MIPSEL.
|
|
||||||
dnl - 'powerpc64': test _BIG_ENDIAN vs. _LITTLE_ENDIAN.
|
|
||||||
dnl * The same name 'i386' is used for CPUs of type i386, i486, i586
|
|
||||||
dnl (Pentium), AMD K7, Pentium II, Pentium IV, etc., because
|
|
||||||
dnl - Instructions that do not exist on all of these CPUs (cmpxchg,
|
|
||||||
dnl MMX, SSE, SSE2, 3DNow! etc.) are not frequently used. If your
|
|
||||||
dnl assembly language source files use such instructions, you will
|
|
||||||
dnl need to make the distinction.
|
|
||||||
dnl - Speed of execution of the common instruction set is reasonable across
|
|
||||||
dnl the entire family of CPUs. If you have assembly language source files
|
|
||||||
dnl that are optimized for particular CPU types (like GNU gmp has), you
|
|
||||||
dnl will need to make the distinction.
|
|
||||||
dnl See <https://en.wikipedia.org/wiki/X86_instruction_listings>.
|
|
||||||
AC_DEFUN([gl_HOST_CPU_C_ABI],
|
|
||||||
[
|
|
||||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
|
||||||
AC_REQUIRE([gl_C_ASM])
|
|
||||||
AC_CACHE_CHECK([host CPU and C ABI], [gl_cv_host_cpu_c_abi],
|
|
||||||
[case "$host_cpu" in
|
|
||||||
|
|
||||||
changequote(,)dnl
|
|
||||||
i[4567]86 )
|
|
||||||
changequote([,])dnl
|
|
||||||
gl_cv_host_cpu_c_abi=i386
|
|
||||||
;;
|
|
||||||
|
|
||||||
x86_64 )
|
|
||||||
# On x86_64 systems, the C compiler may be generating code in one of
|
|
||||||
# these ABIs:
|
|
||||||
# - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64.
|
|
||||||
# - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64
|
|
||||||
# with native Windows (mingw, MSVC).
|
|
||||||
# - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32.
|
|
||||||
# - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if (defined __x86_64__ || defined __amd64__ \
|
|
||||||
|| defined _M_X64 || defined _M_AMD64)
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __ILP32__ || defined _ILP32
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi=x86_64-x32],
|
|
||||||
[gl_cv_host_cpu_c_abi=x86_64])],
|
|
||||||
[gl_cv_host_cpu_c_abi=i386])
|
|
||||||
;;
|
|
||||||
|
|
||||||
changequote(,)dnl
|
|
||||||
alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] )
|
|
||||||
changequote([,])dnl
|
|
||||||
gl_cv_host_cpu_c_abi=alpha
|
|
||||||
;;
|
|
||||||
|
|
||||||
arm* | aarch64 )
|
|
||||||
# Assume arm with EABI.
|
|
||||||
# On arm64 systems, the C compiler may be generating code in one of
|
|
||||||
# these ABIs:
|
|
||||||
# - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64.
|
|
||||||
# - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32.
|
|
||||||
# - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#ifdef __aarch64__
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __ILP32__ || defined _ILP32
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi=arm64-ilp32],
|
|
||||||
[gl_cv_host_cpu_c_abi=arm64])],
|
|
||||||
[# Don't distinguish little-endian and big-endian arm, since they
|
|
||||||
# don't require different machine code for simple operations and
|
|
||||||
# since the user can distinguish them through the preprocessor
|
|
||||||
# defines __ARMEL__ vs. __ARMEB__.
|
|
||||||
# But distinguish arm which passes floating-point arguments and
|
|
||||||
# return values in integer registers (r0, r1, ...) - this is
|
|
||||||
# gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which
|
|
||||||
# passes them in float registers (s0, s1, ...) and double registers
|
|
||||||
# (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer
|
|
||||||
# sets the preprocessor defines __ARM_PCS (for the first case) and
|
|
||||||
# __ARM_PCS_VFP (for the second case), but older GCC does not.
|
|
||||||
echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c
|
|
||||||
# Look for a reference to the register d0 in the .s file.
|
|
||||||
AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c) >/dev/null 2>&1
|
|
||||||
if LC_ALL=C grep 'd0,' conftest.$gl_asmext >/dev/null; then
|
|
||||||
gl_cv_host_cpu_c_abi=armhf
|
|
||||||
else
|
|
||||||
gl_cv_host_cpu_c_abi=arm
|
|
||||||
fi
|
|
||||||
rm -f conftest*
|
|
||||||
])
|
|
||||||
;;
|
|
||||||
|
|
||||||
hppa1.0 | hppa1.1 | hppa2.0* | hppa64 )
|
|
||||||
# On hppa, the C compiler may be generating 32-bit code or 64-bit
|
|
||||||
# code. In the latter case, it defines _LP64 and __LP64__.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#ifdef __LP64__
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi=hppa64],
|
|
||||||
[gl_cv_host_cpu_c_abi=hppa])
|
|
||||||
;;
|
|
||||||
|
|
||||||
ia64* )
|
|
||||||
# On ia64 on HP-UX, the C compiler may be generating 64-bit code or
|
|
||||||
# 32-bit code. In the latter case, it defines _ILP32.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#ifdef _ILP32
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi=ia64-ilp32],
|
|
||||||
[gl_cv_host_cpu_c_abi=ia64])
|
|
||||||
;;
|
|
||||||
|
|
||||||
mips* )
|
|
||||||
# We should also check for (_MIPS_SZPTR == 64), but gcc keeps this
|
|
||||||
# at 32.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64)
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi=mips64],
|
|
||||||
[# In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but
|
|
||||||
# may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIN32.
|
|
||||||
# In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but
|
|
||||||
# may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIO32.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if (_MIPS_SIM == _ABIN32)
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi=mipsn32],
|
|
||||||
[gl_cv_host_cpu_c_abi=mips])])
|
|
||||||
;;
|
|
||||||
|
|
||||||
powerpc* )
|
|
||||||
# Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD.
|
|
||||||
# No need to distinguish them here; the caller may distinguish
|
|
||||||
# them based on the OS.
|
|
||||||
# On powerpc64 systems, the C compiler may still be generating
|
|
||||||
# 32-bit code. And on powerpc-ibm-aix systems, the C compiler may
|
|
||||||
# be generating 64-bit code.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __powerpc64__ || defined _ARCH_PPC64
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[# On powerpc64, there are two ABIs on Linux: The AIX compatible
|
|
||||||
# one and the ELFv2 one. The latter defines _CALL_ELF=2.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined _CALL_ELF && _CALL_ELF == 2
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi=powerpc64-elfv2],
|
|
||||||
[gl_cv_host_cpu_c_abi=powerpc64])
|
|
||||||
],
|
|
||||||
[gl_cv_host_cpu_c_abi=powerpc])
|
|
||||||
;;
|
|
||||||
|
|
||||||
rs6000 )
|
|
||||||
gl_cv_host_cpu_c_abi=powerpc
|
|
||||||
;;
|
|
||||||
|
|
||||||
riscv32 | riscv64 )
|
|
||||||
# There are 2 architectures (with variants): rv32* and rv64*.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if __riscv_xlen == 64
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[cpu=riscv64],
|
|
||||||
[cpu=riscv32])
|
|
||||||
# There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d.
|
|
||||||
# Size of 'long' and 'void *':
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __LP64__
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[main_abi=lp64],
|
|
||||||
[main_abi=ilp32])
|
|
||||||
# Float ABIs:
|
|
||||||
# __riscv_float_abi_double:
|
|
||||||
# 'float' and 'double' are passed in floating-point registers.
|
|
||||||
# __riscv_float_abi_single:
|
|
||||||
# 'float' are passed in floating-point registers.
|
|
||||||
# __riscv_float_abi_soft:
|
|
||||||
# No values are passed in floating-point registers.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __riscv_float_abi_double
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[float_abi=d],
|
|
||||||
[AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __riscv_float_abi_single
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[float_abi=f],
|
|
||||||
[float_abi=''])
|
|
||||||
])
|
|
||||||
gl_cv_host_cpu_c_abi="${cpu}-${main_abi}${float_abi}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
s390* )
|
|
||||||
# On s390x, the C compiler may be generating 64-bit (= s390x) code
|
|
||||||
# or 31-bit (= s390) code.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __LP64__ || defined __s390x__
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi=s390x],
|
|
||||||
[gl_cv_host_cpu_c_abi=s390])
|
|
||||||
;;
|
|
||||||
|
|
||||||
sparc | sparc64 )
|
|
||||||
# UltraSPARCs running Linux have `uname -m` = "sparc64", but the
|
|
||||||
# C compiler still generates 32-bit code.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __sparcv9 || defined __arch64__
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi=sparc64],
|
|
||||||
[gl_cv_host_cpu_c_abi=sparc])
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
gl_cv_host_cpu_c_abi="$host_cpu"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same.
|
|
||||||
HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'`
|
|
||||||
HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi"
|
|
||||||
AC_SUBST([HOST_CPU])
|
|
||||||
AC_SUBST([HOST_CPU_C_ABI])
|
|
||||||
|
|
||||||
# This was
|
|
||||||
# AC_DEFINE_UNQUOTED([__${HOST_CPU}__])
|
|
||||||
# AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__])
|
|
||||||
# earlier, but KAI C++ 3.2d doesn't like this.
|
|
||||||
sed -e 's/-/_/g' >> confdefs.h <<EOF
|
|
||||||
#ifndef __${HOST_CPU}__
|
|
||||||
#define __${HOST_CPU}__ 1
|
|
||||||
#endif
|
|
||||||
#ifndef __${HOST_CPU_C_ABI}__
|
|
||||||
#define __${HOST_CPU_C_ABI}__ 1
|
|
||||||
#endif
|
|
||||||
EOF
|
|
||||||
AH_TOP([/* CPU and C ABI indicator */
|
|
||||||
#ifndef __i386__
|
|
||||||
#undef __i386__
|
|
||||||
#endif
|
|
||||||
#ifndef __x86_64_x32__
|
|
||||||
#undef __x86_64_x32__
|
|
||||||
#endif
|
|
||||||
#ifndef __x86_64__
|
|
||||||
#undef __x86_64__
|
|
||||||
#endif
|
|
||||||
#ifndef __alpha__
|
|
||||||
#undef __alpha__
|
|
||||||
#endif
|
|
||||||
#ifndef __arm__
|
|
||||||
#undef __arm__
|
|
||||||
#endif
|
|
||||||
#ifndef __armhf__
|
|
||||||
#undef __armhf__
|
|
||||||
#endif
|
|
||||||
#ifndef __arm64_ilp32__
|
|
||||||
#undef __arm64_ilp32__
|
|
||||||
#endif
|
|
||||||
#ifndef __arm64__
|
|
||||||
#undef __arm64__
|
|
||||||
#endif
|
|
||||||
#ifndef __hppa__
|
|
||||||
#undef __hppa__
|
|
||||||
#endif
|
|
||||||
#ifndef __hppa64__
|
|
||||||
#undef __hppa64__
|
|
||||||
#endif
|
|
||||||
#ifndef __ia64_ilp32__
|
|
||||||
#undef __ia64_ilp32__
|
|
||||||
#endif
|
|
||||||
#ifndef __ia64__
|
|
||||||
#undef __ia64__
|
|
||||||
#endif
|
|
||||||
#ifndef __m68k__
|
|
||||||
#undef __m68k__
|
|
||||||
#endif
|
|
||||||
#ifndef __mips__
|
|
||||||
#undef __mips__
|
|
||||||
#endif
|
|
||||||
#ifndef __mipsn32__
|
|
||||||
#undef __mipsn32__
|
|
||||||
#endif
|
|
||||||
#ifndef __mips64__
|
|
||||||
#undef __mips64__
|
|
||||||
#endif
|
|
||||||
#ifndef __powerpc__
|
|
||||||
#undef __powerpc__
|
|
||||||
#endif
|
|
||||||
#ifndef __powerpc64__
|
|
||||||
#undef __powerpc64__
|
|
||||||
#endif
|
|
||||||
#ifndef __powerpc64_elfv2__
|
|
||||||
#undef __powerpc64_elfv2__
|
|
||||||
#endif
|
|
||||||
#ifndef __riscv32__
|
|
||||||
#undef __riscv32__
|
|
||||||
#endif
|
|
||||||
#ifndef __riscv64__
|
|
||||||
#undef __riscv64__
|
|
||||||
#endif
|
|
||||||
#ifndef __riscv32_ilp32__
|
|
||||||
#undef __riscv32_ilp32__
|
|
||||||
#endif
|
|
||||||
#ifndef __riscv32_ilp32f__
|
|
||||||
#undef __riscv32_ilp32f__
|
|
||||||
#endif
|
|
||||||
#ifndef __riscv32_ilp32d__
|
|
||||||
#undef __riscv32_ilp32d__
|
|
||||||
#endif
|
|
||||||
#ifndef __riscv64_ilp32__
|
|
||||||
#undef __riscv64_ilp32__
|
|
||||||
#endif
|
|
||||||
#ifndef __riscv64_ilp32f__
|
|
||||||
#undef __riscv64_ilp32f__
|
|
||||||
#endif
|
|
||||||
#ifndef __riscv64_ilp32d__
|
|
||||||
#undef __riscv64_ilp32d__
|
|
||||||
#endif
|
|
||||||
#ifndef __riscv64_lp64__
|
|
||||||
#undef __riscv64_lp64__
|
|
||||||
#endif
|
|
||||||
#ifndef __riscv64_lp64f__
|
|
||||||
#undef __riscv64_lp64f__
|
|
||||||
#endif
|
|
||||||
#ifndef __riscv64_lp64d__
|
|
||||||
#undef __riscv64_lp64d__
|
|
||||||
#endif
|
|
||||||
#ifndef __s390__
|
|
||||||
#undef __s390__
|
|
||||||
#endif
|
|
||||||
#ifndef __s390x__
|
|
||||||
#undef __s390x__
|
|
||||||
#endif
|
|
||||||
#ifndef __sh__
|
|
||||||
#undef __sh__
|
|
||||||
#endif
|
|
||||||
#ifndef __sparc__
|
|
||||||
#undef __sparc__
|
|
||||||
#endif
|
|
||||||
#ifndef __sparc64__
|
|
||||||
#undef __sparc64__
|
|
||||||
#endif
|
|
||||||
])
|
|
||||||
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
dnl Sets the HOST_CPU_C_ABI_32BIT variable to 'yes' if the C language ABI
|
|
||||||
dnl (application binary interface) is a 32-bit one, or to 'no' otherwise.
|
|
||||||
dnl This is a simplified variant of gl_HOST_CPU_C_ABI.
|
|
||||||
AC_DEFUN([gl_HOST_CPU_C_ABI_32BIT],
|
|
||||||
[
|
|
||||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
|
||||||
AC_CACHE_CHECK([32-bit host C ABI], [gl_cv_host_cpu_c_abi_32bit],
|
|
||||||
[if test -n "$gl_cv_host_cpu_c_abi"; then
|
|
||||||
case "$gl_cv_host_cpu_c_abi" in
|
|
||||||
i386 | x86_64-x32 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | riscv*-ilp32* | s390 | sparc)
|
|
||||||
gl_cv_host_cpu_c_abi_32bit=yes ;;
|
|
||||||
*)
|
|
||||||
gl_cv_host_cpu_c_abi_32bit=no ;;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
case "$host_cpu" in
|
|
||||||
|
|
||||||
changequote(,)dnl
|
|
||||||
i[4567]86 )
|
|
||||||
changequote([,])dnl
|
|
||||||
gl_cv_host_cpu_c_abi_32bit=yes
|
|
||||||
;;
|
|
||||||
|
|
||||||
x86_64 )
|
|
||||||
# On x86_64 systems, the C compiler may be generating code in one of
|
|
||||||
# these ABIs:
|
|
||||||
# - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64.
|
|
||||||
# - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64
|
|
||||||
# with native Windows (mingw, MSVC).
|
|
||||||
# - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32.
|
|
||||||
# - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if (defined __x86_64__ || defined __amd64__ \
|
|
||||||
|| defined _M_X64 || defined _M_AMD64) \
|
|
||||||
&& !(defined __ILP32__ || defined _ILP32)
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=no],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=yes])
|
|
||||||
;;
|
|
||||||
|
|
||||||
arm* | aarch64 )
|
|
||||||
# Assume arm with EABI.
|
|
||||||
# On arm64 systems, the C compiler may be generating code in one of
|
|
||||||
# these ABIs:
|
|
||||||
# - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64.
|
|
||||||
# - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32.
|
|
||||||
# - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __aarch64__ && !(defined __ILP32__ || defined _ILP32)
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=no],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=yes])
|
|
||||||
;;
|
|
||||||
|
|
||||||
hppa1.0 | hppa1.1 | hppa2.0* | hppa64 )
|
|
||||||
# On hppa, the C compiler may be generating 32-bit code or 64-bit
|
|
||||||
# code. In the latter case, it defines _LP64 and __LP64__.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#ifdef __LP64__
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=no],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=yes])
|
|
||||||
;;
|
|
||||||
|
|
||||||
ia64* )
|
|
||||||
# On ia64 on HP-UX, the C compiler may be generating 64-bit code or
|
|
||||||
# 32-bit code. In the latter case, it defines _ILP32.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#ifdef _ILP32
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=yes],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=no])
|
|
||||||
;;
|
|
||||||
|
|
||||||
mips* )
|
|
||||||
# We should also check for (_MIPS_SZPTR == 64), but gcc keeps this
|
|
||||||
# at 32.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64)
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=no],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=yes])
|
|
||||||
;;
|
|
||||||
|
|
||||||
powerpc* )
|
|
||||||
# Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD.
|
|
||||||
# No need to distinguish them here; the caller may distinguish
|
|
||||||
# them based on the OS.
|
|
||||||
# On powerpc64 systems, the C compiler may still be generating
|
|
||||||
# 32-bit code. And on powerpc-ibm-aix systems, the C compiler may
|
|
||||||
# be generating 64-bit code.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __powerpc64__ || defined _ARCH_PPC64
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=no],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=yes])
|
|
||||||
;;
|
|
||||||
|
|
||||||
rs6000 )
|
|
||||||
gl_cv_host_cpu_c_abi_32bit=yes
|
|
||||||
;;
|
|
||||||
|
|
||||||
riscv32 | riscv64 )
|
|
||||||
# There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d.
|
|
||||||
# Size of 'long' and 'void *':
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __LP64__
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=no],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=yes])
|
|
||||||
;;
|
|
||||||
|
|
||||||
s390* )
|
|
||||||
# On s390x, the C compiler may be generating 64-bit (= s390x) code
|
|
||||||
# or 31-bit (= s390) code.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __LP64__ || defined __s390x__
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=no],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=yes])
|
|
||||||
;;
|
|
||||||
|
|
||||||
sparc | sparc64 )
|
|
||||||
# UltraSPARCs running Linux have `uname -m` = "sparc64", but the
|
|
||||||
# C compiler still generates 32-bit code.
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_SOURCE(
|
|
||||||
[[#if defined __sparcv9 || defined __arch64__
|
|
||||||
int ok;
|
|
||||||
#else
|
|
||||||
error fail
|
|
||||||
#endif
|
|
||||||
]])],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=no],
|
|
||||||
[gl_cv_host_cpu_c_abi_32bit=yes])
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
gl_cv_host_cpu_c_abi_32bit=no
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
|
|
||||||
HOST_CPU_C_ABI_32BIT="$gl_cv_host_cpu_c_abi_32bit"
|
|
||||||
])
|
|
||||||
-287
@@ -1,287 +0,0 @@
|
|||||||
# iconv.m4 serial 21
|
|
||||||
dnl Copyright (C) 2000-2002, 2007-2014, 2016-2019 Free Software Foundation,
|
|
||||||
dnl Inc.
|
|
||||||
dnl This file is free software; the Free Software Foundation
|
|
||||||
dnl gives unlimited permission to copy and/or distribute it,
|
|
||||||
dnl with or without modifications, as long as this notice is preserved.
|
|
||||||
|
|
||||||
dnl From Bruno Haible.
|
|
||||||
|
|
||||||
AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
|
|
||||||
[
|
|
||||||
dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
|
|
||||||
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
|
|
||||||
AC_REQUIRE([AC_LIB_RPATH])
|
|
||||||
|
|
||||||
dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
|
|
||||||
dnl accordingly.
|
|
||||||
AC_LIB_LINKFLAGS_BODY([iconv])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([AM_ICONV_LINK],
|
|
||||||
[
|
|
||||||
dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
|
|
||||||
dnl those with the standalone portable GNU libiconv installed).
|
|
||||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
|
||||||
|
|
||||||
dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
|
|
||||||
dnl accordingly.
|
|
||||||
AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
|
|
||||||
|
|
||||||
dnl Add $INCICONV to CPPFLAGS before performing the following checks,
|
|
||||||
dnl because if the user has installed libiconv and not disabled its use
|
|
||||||
dnl via --without-libiconv-prefix, he wants to use it. The first
|
|
||||||
dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed.
|
|
||||||
am_save_CPPFLAGS="$CPPFLAGS"
|
|
||||||
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
|
|
||||||
|
|
||||||
AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
|
|
||||||
am_cv_func_iconv="no, consider installing GNU libiconv"
|
|
||||||
am_cv_lib_iconv=no
|
|
||||||
AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[[
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <iconv.h>
|
|
||||||
]],
|
|
||||||
[[iconv_t cd = iconv_open("","");
|
|
||||||
iconv(cd,NULL,NULL,NULL,NULL);
|
|
||||||
iconv_close(cd);]])],
|
|
||||||
[am_cv_func_iconv=yes])
|
|
||||||
if test "$am_cv_func_iconv" != yes; then
|
|
||||||
am_save_LIBS="$LIBS"
|
|
||||||
LIBS="$LIBS $LIBICONV"
|
|
||||||
AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[[
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <iconv.h>
|
|
||||||
]],
|
|
||||||
[[iconv_t cd = iconv_open("","");
|
|
||||||
iconv(cd,NULL,NULL,NULL,NULL);
|
|
||||||
iconv_close(cd);]])],
|
|
||||||
[am_cv_lib_iconv=yes]
|
|
||||||
[am_cv_func_iconv=yes])
|
|
||||||
LIBS="$am_save_LIBS"
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
if test "$am_cv_func_iconv" = yes; then
|
|
||||||
AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
|
|
||||||
dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11,
|
|
||||||
dnl Solaris 10.
|
|
||||||
am_save_LIBS="$LIBS"
|
|
||||||
if test $am_cv_lib_iconv = yes; then
|
|
||||||
LIBS="$LIBS $LIBICONV"
|
|
||||||
fi
|
|
||||||
am_cv_func_iconv_works=no
|
|
||||||
for ac_iconv_const in '' 'const'; do
|
|
||||||
AC_RUN_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[[
|
|
||||||
#include <iconv.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifndef ICONV_CONST
|
|
||||||
# define ICONV_CONST $ac_iconv_const
|
|
||||||
#endif
|
|
||||||
]],
|
|
||||||
[[int result = 0;
|
|
||||||
/* Test against AIX 5.1 bug: Failures are not distinguishable from successful
|
|
||||||
returns. */
|
|
||||||
{
|
|
||||||
iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
|
|
||||||
if (cd_utf8_to_88591 != (iconv_t)(-1))
|
|
||||||
{
|
|
||||||
static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */
|
|
||||||
char buf[10];
|
|
||||||
ICONV_CONST char *inptr = input;
|
|
||||||
size_t inbytesleft = strlen (input);
|
|
||||||
char *outptr = buf;
|
|
||||||
size_t outbytesleft = sizeof (buf);
|
|
||||||
size_t res = iconv (cd_utf8_to_88591,
|
|
||||||
&inptr, &inbytesleft,
|
|
||||||
&outptr, &outbytesleft);
|
|
||||||
if (res == 0)
|
|
||||||
result |= 1;
|
|
||||||
iconv_close (cd_utf8_to_88591);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Test against Solaris 10 bug: Failures are not distinguishable from
|
|
||||||
successful returns. */
|
|
||||||
{
|
|
||||||
iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
|
|
||||||
if (cd_ascii_to_88591 != (iconv_t)(-1))
|
|
||||||
{
|
|
||||||
static ICONV_CONST char input[] = "\263";
|
|
||||||
char buf[10];
|
|
||||||
ICONV_CONST char *inptr = input;
|
|
||||||
size_t inbytesleft = strlen (input);
|
|
||||||
char *outptr = buf;
|
|
||||||
size_t outbytesleft = sizeof (buf);
|
|
||||||
size_t res = iconv (cd_ascii_to_88591,
|
|
||||||
&inptr, &inbytesleft,
|
|
||||||
&outptr, &outbytesleft);
|
|
||||||
if (res == 0)
|
|
||||||
result |= 2;
|
|
||||||
iconv_close (cd_ascii_to_88591);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Test against AIX 6.1..7.1 bug: Buffer overrun. */
|
|
||||||
{
|
|
||||||
iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
|
|
||||||
if (cd_88591_to_utf8 != (iconv_t)(-1))
|
|
||||||
{
|
|
||||||
static ICONV_CONST char input[] = "\304";
|
|
||||||
static char buf[2] = { (char)0xDE, (char)0xAD };
|
|
||||||
ICONV_CONST char *inptr = input;
|
|
||||||
size_t inbytesleft = 1;
|
|
||||||
char *outptr = buf;
|
|
||||||
size_t outbytesleft = 1;
|
|
||||||
size_t res = iconv (cd_88591_to_utf8,
|
|
||||||
&inptr, &inbytesleft,
|
|
||||||
&outptr, &outbytesleft);
|
|
||||||
if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
|
|
||||||
result |= 4;
|
|
||||||
iconv_close (cd_88591_to_utf8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if 0 /* This bug could be worked around by the caller. */
|
|
||||||
/* Test against HP-UX 11.11 bug: Positive return value instead of 0. */
|
|
||||||
{
|
|
||||||
iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
|
|
||||||
if (cd_88591_to_utf8 != (iconv_t)(-1))
|
|
||||||
{
|
|
||||||
static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
|
|
||||||
char buf[50];
|
|
||||||
ICONV_CONST char *inptr = input;
|
|
||||||
size_t inbytesleft = strlen (input);
|
|
||||||
char *outptr = buf;
|
|
||||||
size_t outbytesleft = sizeof (buf);
|
|
||||||
size_t res = iconv (cd_88591_to_utf8,
|
|
||||||
&inptr, &inbytesleft,
|
|
||||||
&outptr, &outbytesleft);
|
|
||||||
if ((int)res > 0)
|
|
||||||
result |= 8;
|
|
||||||
iconv_close (cd_88591_to_utf8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
|
|
||||||
provided. */
|
|
||||||
{
|
|
||||||
/* Try standardized names. */
|
|
||||||
iconv_t cd1 = iconv_open ("UTF-8", "EUC-JP");
|
|
||||||
/* Try IRIX, OSF/1 names. */
|
|
||||||
iconv_t cd2 = iconv_open ("UTF-8", "eucJP");
|
|
||||||
/* Try AIX names. */
|
|
||||||
iconv_t cd3 = iconv_open ("UTF-8", "IBM-eucJP");
|
|
||||||
/* Try HP-UX names. */
|
|
||||||
iconv_t cd4 = iconv_open ("utf8", "eucJP");
|
|
||||||
if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1)
|
|
||||||
&& cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1))
|
|
||||||
result |= 16;
|
|
||||||
if (cd1 != (iconv_t)(-1))
|
|
||||||
iconv_close (cd1);
|
|
||||||
if (cd2 != (iconv_t)(-1))
|
|
||||||
iconv_close (cd2);
|
|
||||||
if (cd3 != (iconv_t)(-1))
|
|
||||||
iconv_close (cd3);
|
|
||||||
if (cd4 != (iconv_t)(-1))
|
|
||||||
iconv_close (cd4);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
]])],
|
|
||||||
[am_cv_func_iconv_works=yes], ,
|
|
||||||
[case "$host_os" in
|
|
||||||
aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
|
|
||||||
*) am_cv_func_iconv_works="guessing yes" ;;
|
|
||||||
esac])
|
|
||||||
test "$am_cv_func_iconv_works" = no || break
|
|
||||||
done
|
|
||||||
LIBS="$am_save_LIBS"
|
|
||||||
])
|
|
||||||
case "$am_cv_func_iconv_works" in
|
|
||||||
*no) am_func_iconv=no am_cv_lib_iconv=no ;;
|
|
||||||
*) am_func_iconv=yes ;;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
am_func_iconv=no am_cv_lib_iconv=no
|
|
||||||
fi
|
|
||||||
if test "$am_func_iconv" = yes; then
|
|
||||||
AC_DEFINE([HAVE_ICONV], [1],
|
|
||||||
[Define if you have the iconv() function and it works.])
|
|
||||||
fi
|
|
||||||
if test "$am_cv_lib_iconv" = yes; then
|
|
||||||
AC_MSG_CHECKING([how to link with libiconv])
|
|
||||||
AC_MSG_RESULT([$LIBICONV])
|
|
||||||
else
|
|
||||||
dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
|
|
||||||
dnl either.
|
|
||||||
CPPFLAGS="$am_save_CPPFLAGS"
|
|
||||||
LIBICONV=
|
|
||||||
LTLIBICONV=
|
|
||||||
fi
|
|
||||||
AC_SUBST([LIBICONV])
|
|
||||||
AC_SUBST([LTLIBICONV])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
|
|
||||||
dnl avoid warnings like
|
|
||||||
dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
|
|
||||||
dnl This is tricky because of the way 'aclocal' is implemented:
|
|
||||||
dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
|
|
||||||
dnl Otherwise aclocal's initial scan pass would miss the macro definition.
|
|
||||||
dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
|
|
||||||
dnl Otherwise aclocal would emit many "Use of uninitialized value $1"
|
|
||||||
dnl warnings.
|
|
||||||
m4_define([gl_iconv_AC_DEFUN],
|
|
||||||
m4_version_prereq([2.64],
|
|
||||||
[[AC_DEFUN_ONCE(
|
|
||||||
[$1], [$2])]],
|
|
||||||
[m4_ifdef([gl_00GNULIB],
|
|
||||||
[[AC_DEFUN_ONCE(
|
|
||||||
[$1], [$2])]],
|
|
||||||
[[AC_DEFUN(
|
|
||||||
[$1], [$2])]])]))
|
|
||||||
gl_iconv_AC_DEFUN([AM_ICONV],
|
|
||||||
[
|
|
||||||
AM_ICONV_LINK
|
|
||||||
if test "$am_cv_func_iconv" = yes; then
|
|
||||||
AC_MSG_CHECKING([for iconv declaration])
|
|
||||||
AC_CACHE_VAL([am_cv_proto_iconv], [
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[[
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <iconv.h>
|
|
||||||
extern
|
|
||||||
#ifdef __cplusplus
|
|
||||||
"C"
|
|
||||||
#endif
|
|
||||||
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus)
|
|
||||||
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
|
|
||||||
#else
|
|
||||||
size_t iconv();
|
|
||||||
#endif
|
|
||||||
]],
|
|
||||||
[[]])],
|
|
||||||
[am_cv_proto_iconv_arg1=""],
|
|
||||||
[am_cv_proto_iconv_arg1="const"])
|
|
||||||
am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
|
|
||||||
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
|
|
||||||
AC_MSG_RESULT([$am_cv_proto_iconv])
|
|
||||||
else
|
|
||||||
dnl When compiling GNU libiconv on a system that does not have iconv yet,
|
|
||||||
dnl pick the POSIX compliant declaration without 'const'.
|
|
||||||
am_cv_proto_iconv_arg1=""
|
|
||||||
fi
|
|
||||||
AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
|
|
||||||
[Define as const if the declaration of iconv() needs const.])
|
|
||||||
dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>.
|
|
||||||
m4_ifdef([gl_ICONV_H_DEFAULTS],
|
|
||||||
[AC_REQUIRE([gl_ICONV_H_DEFAULTS])
|
|
||||||
if test -n "$am_cv_proto_iconv_arg1"; then
|
|
||||||
ICONV_CONST="const"
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
])
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
# intlmacosx.m4 serial 6 (gettext-0.20)
|
|
||||||
dnl Copyright (C) 2004-2014, 2016, 2019 Free Software Foundation, Inc.
|
|
||||||
dnl This file is free software; the Free Software Foundation
|
|
||||||
dnl gives unlimited permission to copy and/or distribute it,
|
|
||||||
dnl with or without modifications, as long as this notice is preserved.
|
|
||||||
dnl
|
|
||||||
dnl This file can be used in projects which are not available under
|
|
||||||
dnl the GNU General Public License or the GNU Library General Public
|
|
||||||
dnl License but which still want to provide support for the GNU gettext
|
|
||||||
dnl functionality.
|
|
||||||
dnl Please note that the actual code of the GNU gettext library is covered
|
|
||||||
dnl by the GNU Library General Public License, and the rest of the GNU
|
|
||||||
dnl gettext package is covered by the GNU General Public License.
|
|
||||||
dnl They are *not* in the public domain.
|
|
||||||
|
|
||||||
dnl Checks for special options needed on Mac OS X.
|
|
||||||
dnl Defines INTL_MACOSX_LIBS.
|
|
||||||
AC_DEFUN([gt_INTL_MACOSX],
|
|
||||||
[
|
|
||||||
dnl Check for API introduced in Mac OS X 10.4.
|
|
||||||
AC_CACHE_CHECK([for CFPreferencesCopyAppValue],
|
|
||||||
[gt_cv_func_CFPreferencesCopyAppValue],
|
|
||||||
[gt_save_LIBS="$LIBS"
|
|
||||||
LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
|
|
||||||
AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[[#include <CoreFoundation/CFPreferences.h>]],
|
|
||||||
[[CFPreferencesCopyAppValue(NULL, NULL)]])],
|
|
||||||
[gt_cv_func_CFPreferencesCopyAppValue=yes],
|
|
||||||
[gt_cv_func_CFPreferencesCopyAppValue=no])
|
|
||||||
LIBS="$gt_save_LIBS"])
|
|
||||||
if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
|
|
||||||
AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1],
|
|
||||||
[Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework.])
|
|
||||||
fi
|
|
||||||
dnl Check for API introduced in Mac OS X 10.5.
|
|
||||||
AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent],
|
|
||||||
[gt_save_LIBS="$LIBS"
|
|
||||||
LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
|
|
||||||
AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[[#include <CoreFoundation/CFLocale.h>]],
|
|
||||||
[[CFLocaleCopyCurrent();]])],
|
|
||||||
[gt_cv_func_CFLocaleCopyCurrent=yes],
|
|
||||||
[gt_cv_func_CFLocaleCopyCurrent=no])
|
|
||||||
LIBS="$gt_save_LIBS"])
|
|
||||||
if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
|
|
||||||
AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1],
|
|
||||||
[Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework.])
|
|
||||||
fi
|
|
||||||
AC_CACHE_CHECK([for CFLocaleCopyPreferredLanguages], [gt_cv_func_CFLocaleCopyPreferredLanguages],
|
|
||||||
[gt_save_LIBS="$LIBS"
|
|
||||||
LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
|
|
||||||
AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[[#include <CoreFoundation/CFLocale.h>]],
|
|
||||||
[[CFLocaleCopyPreferredLanguages();]])],
|
|
||||||
[gt_cv_func_CFLocaleCopyPreferredLanguages=yes],
|
|
||||||
[gt_cv_func_CFLocaleCopyPreferredLanguages=no])
|
|
||||||
LIBS="$gt_save_LIBS"])
|
|
||||||
if test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then
|
|
||||||
AC_DEFINE([HAVE_CFLOCALECOPYPREFERREDLANGUAGES], [1],
|
|
||||||
[Define to 1 if you have the Mac OS X function CFLocaleCopyPreferredLanguages in the CoreFoundation framework.])
|
|
||||||
fi
|
|
||||||
INTL_MACOSX_LIBS=
|
|
||||||
if test $gt_cv_func_CFPreferencesCopyAppValue = yes \
|
|
||||||
|| test $gt_cv_func_CFLocaleCopyCurrent = yes \
|
|
||||||
|| test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then
|
|
||||||
INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
|
|
||||||
fi
|
|
||||||
AC_SUBST([INTL_MACOSX_LIBS])
|
|
||||||
])
|
|
||||||
@@ -4,23 +4,17 @@ dnl #
|
|||||||
dnl # - access_ok(type, addr, size)
|
dnl # - access_ok(type, addr, size)
|
||||||
dnl # + access_ok(addr, size)
|
dnl # + access_ok(addr, size)
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_ACCESS_OK_TYPE], [
|
|
||||||
ZFS_LINUX_TEST_SRC([access_ok_type], [
|
|
||||||
#include <linux/uaccess.h>
|
|
||||||
],[
|
|
||||||
const void __user __attribute__((unused)) *addr =
|
|
||||||
(void *) 0xdeadbeef;
|
|
||||||
unsigned long __attribute__((unused)) size = 1;
|
|
||||||
int error __attribute__((unused)) = access_ok(0, addr, size);
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_ACCESS_OK_TYPE], [
|
AC_DEFUN([ZFS_AC_KERNEL_ACCESS_OK_TYPE], [
|
||||||
AC_MSG_CHECKING([whether access_ok() has 'type' parameter])
|
AC_MSG_CHECKING([whether access_ok() has 'type' parameter])
|
||||||
ZFS_LINUX_TEST_RESULT([access_ok_type], [
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
],[
|
||||||
|
const void __user __attribute__((unused)) *addr = (void *) 0xdeadbeef;
|
||||||
|
unsigned long __attribute__((unused)) size = 1;
|
||||||
|
int error __attribute__((unused)) = access_ok(0, addr, size);
|
||||||
|
],[
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_ACCESS_OK_TYPE, 1,
|
AC_DEFINE(HAVE_ACCESS_OK_TYPE, 1, [kernel has access_ok with 'type' parameter])
|
||||||
[kernel has access_ok with 'type' parameter])
|
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
|
|||||||
+83
-174
@@ -3,26 +3,32 @@ dnl # Check if posix_acl_release can be used from a ZFS_META_LICENSED
|
|||||||
dnl # module. The is_owner_or_cap macro was replaced by
|
dnl # module. The is_owner_or_cap macro was replaced by
|
||||||
dnl # inode_owner_or_capable
|
dnl # inode_owner_or_capable
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_RELEASE], [
|
AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_RELEASE], [
|
||||||
ZFS_LINUX_TEST_SRC([posix_acl_release], [
|
AC_MSG_CHECKING([whether posix_acl_release() is available])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/cred.h>
|
#include <linux/cred.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/posix_acl.h>
|
#include <linux/posix_acl.h>
|
||||||
], [
|
],[
|
||||||
struct posix_acl *tmp = posix_acl_alloc(1, 0);
|
struct posix_acl* tmp = posix_acl_alloc(1, 0);
|
||||||
posix_acl_release(tmp);
|
posix_acl_release(tmp);
|
||||||
], [], [$ZFS_META_LICENSE])
|
],[
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_RELEASE], [
|
|
||||||
AC_MSG_CHECKING([whether posix_acl_release() is available])
|
|
||||||
ZFS_LINUX_TEST_RESULT([posix_acl_release], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_POSIX_ACL_RELEASE, 1,
|
AC_DEFINE(HAVE_POSIX_ACL_RELEASE, 1,
|
||||||
[posix_acl_release() is available])
|
[posix_acl_release() is available])
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether posix_acl_release() is GPL-only])
|
AC_MSG_CHECKING([whether posix_acl_release() is GPL-only])
|
||||||
ZFS_LINUX_TEST_RESULT([posix_acl_release_license], [
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/cred.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/posix_acl.h>
|
||||||
|
|
||||||
|
MODULE_LICENSE("$ZFS_META_LICENSE");
|
||||||
|
],[
|
||||||
|
struct posix_acl* tmp = posix_acl_alloc(1, 0);
|
||||||
|
posix_acl_release(tmp);
|
||||||
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
@@ -40,25 +46,24 @@ dnl # set_cached_acl() and forget_cached_acl() changed from inline to
|
|||||||
dnl # EXPORT_SYMBOL. In the former case, they may not be usable because of
|
dnl # EXPORT_SYMBOL. In the former case, they may not be usable because of
|
||||||
dnl # posix_acl_release. In the latter case, we can always use them.
|
dnl # posix_acl_release. In the latter case, we can always use them.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_SET_CACHED_ACL_USABLE], [
|
AC_DEFUN([ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE], [
|
||||||
ZFS_LINUX_TEST_SRC([set_cached_acl], [
|
AC_MSG_CHECKING([whether set_cached_acl() is usable])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/module.h>
|
||||||
#include <linux/cred.h>
|
#include <linux/cred.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/posix_acl.h>
|
#include <linux/posix_acl.h>
|
||||||
], [
|
|
||||||
|
MODULE_LICENSE("$ZFS_META_LICENSE");
|
||||||
|
],[
|
||||||
struct inode *ip = NULL;
|
struct inode *ip = NULL;
|
||||||
struct posix_acl *acl = posix_acl_alloc(1, 0);
|
struct posix_acl *acl = posix_acl_alloc(1, 0);
|
||||||
set_cached_acl(ip, ACL_TYPE_ACCESS, acl);
|
set_cached_acl(ip, ACL_TYPE_ACCESS, acl);
|
||||||
forget_cached_acl(ip, ACL_TYPE_ACCESS);
|
forget_cached_acl(ip, ACL_TYPE_ACCESS);
|
||||||
], [], [$ZFS_META_LICENSE])
|
],[
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE], [
|
|
||||||
AC_MSG_CHECKING([whether set_cached_acl() is usable])
|
|
||||||
ZFS_LINUX_TEST_RESULT([set_cached_acl_license], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_SET_CACHED_ACL_USABLE, 1,
|
AC_DEFINE(HAVE_SET_CACHED_ACL_USABLE, 1,
|
||||||
[set_cached_acl() is usable])
|
[posix_acl_release() is usable])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
@@ -72,25 +77,14 @@ dnl #
|
|||||||
dnl # 3.14 API change,
|
dnl # 3.14 API change,
|
||||||
dnl # posix_acl_chmod() is changed to __posix_acl_chmod()
|
dnl # posix_acl_chmod() is changed to __posix_acl_chmod()
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_CHMOD], [
|
AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CHMOD], [
|
||||||
ZFS_LINUX_TEST_SRC([posix_acl_chmod], [
|
AC_MSG_CHECKING([whether posix_acl_chmod exists])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/posix_acl.h>
|
#include <linux/posix_acl.h>
|
||||||
],[
|
],[
|
||||||
posix_acl_chmod(NULL, 0, 0)
|
posix_acl_chmod(NULL, 0, 0)
|
||||||
])
|
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([__posix_acl_chmod], [
|
|
||||||
#include <linux/fs.h>
|
|
||||||
#include <linux/posix_acl.h>
|
|
||||||
],[
|
],[
|
||||||
__posix_acl_chmod(NULL, 0, 0)
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CHMOD], [
|
|
||||||
AC_MSG_CHECKING([whether posix_acl_chmod exists])
|
|
||||||
ZFS_LINUX_TEST_RESULT([posix_acl_chmod], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_POSIX_ACL_CHMOD, 1, [posix_acl_chmod() exists])
|
AC_DEFINE(HAVE_POSIX_ACL_CHMOD, 1, [posix_acl_chmod() exists])
|
||||||
],[
|
],[
|
||||||
@@ -98,10 +92,14 @@ AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CHMOD], [
|
|||||||
])
|
])
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether __posix_acl_chmod exists])
|
AC_MSG_CHECKING([whether __posix_acl_chmod exists])
|
||||||
ZFS_LINUX_TEST_RESULT([__posix_acl_chmod], [
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/posix_acl.h>
|
||||||
|
],[
|
||||||
|
__posix_acl_chmod(NULL, 0, 0)
|
||||||
|
],[
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE___POSIX_ACL_CHMOD, 1,
|
AC_DEFINE(HAVE___POSIX_ACL_CHMOD, 1, [__posix_acl_chmod() exists])
|
||||||
[__posix_acl_chmod() exists])
|
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
@@ -111,22 +109,18 @@ dnl #
|
|||||||
dnl # 3.1 API change,
|
dnl # 3.1 API change,
|
||||||
dnl # posix_acl_equiv_mode now wants an umode_t* instead of a mode_t*
|
dnl # posix_acl_equiv_mode now wants an umode_t* instead of a mode_t*
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
|
AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
|
||||||
ZFS_LINUX_TEST_SRC([posix_acl_equiv_mode], [
|
AC_MSG_CHECKING([whether posix_acl_equiv_mode() wants umode_t])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/posix_acl.h>
|
#include <linux/posix_acl.h>
|
||||||
],[
|
],[
|
||||||
umode_t tmp;
|
umode_t tmp;
|
||||||
posix_acl_equiv_mode(NULL,&tmp);
|
posix_acl_equiv_mode(NULL,&tmp);
|
||||||
])
|
],[
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
|
|
||||||
AC_MSG_CHECKING([whether posix_acl_equiv_mode() wants umode_t])
|
|
||||||
ZFS_LINUX_TEST_RESULT([posix_acl_equiv_mode], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T, 1,
|
AC_DEFINE(HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T, 1,
|
||||||
[posix_acl_equiv_mode wants umode_t*])
|
[ posix_acl_equiv_mode wants umode_t*])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
@@ -136,8 +130,9 @@ dnl #
|
|||||||
dnl # 4.8 API change,
|
dnl # 4.8 API change,
|
||||||
dnl # The function posix_acl_valid now must be passed a namespace.
|
dnl # The function posix_acl_valid now must be passed a namespace.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_VALID_WITH_NS], [
|
AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS], [
|
||||||
ZFS_LINUX_TEST_SRC([posix_acl_valid_with_ns], [
|
AC_MSG_CHECKING([whether posix_acl_valid() wants user namespace])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/posix_acl.h>
|
#include <linux/posix_acl.h>
|
||||||
],[
|
],[
|
||||||
@@ -146,12 +141,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_VALID_WITH_NS], [
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = posix_acl_valid(user_ns, acl);
|
error = posix_acl_valid(user_ns, acl);
|
||||||
])
|
],[
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS], [
|
|
||||||
AC_MSG_CHECKING([whether posix_acl_valid() wants user namespace])
|
|
||||||
ZFS_LINUX_TEST_RESULT([posix_acl_valid_with_ns], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_POSIX_ACL_VALID_WITH_NS, 1,
|
AC_DEFINE(HAVE_POSIX_ACL_VALID_WITH_NS, 1,
|
||||||
[posix_acl_valid() wants user namespace])
|
[posix_acl_valid() wants user namespace])
|
||||||
@@ -165,8 +155,9 @@ dnl # 2.6.27 API change,
|
|||||||
dnl # Check if inode_operations contains the function permission
|
dnl # Check if inode_operations contains the function permission
|
||||||
dnl # and expects the nameidata structure to have been removed.
|
dnl # and expects the nameidata structure to have been removed.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_permission], [
|
AC_MSG_CHECKING([whether iops->permission() exists])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
int permission_fn(struct inode *inode, int mask) { return 0; }
|
int permission_fn(struct inode *inode, int mask) { return 0; }
|
||||||
@@ -175,12 +166,8 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION], [
|
|||||||
iops __attribute__ ((unused)) = {
|
iops __attribute__ ((unused)) = {
|
||||||
.permission = permission_fn,
|
.permission = permission_fn,
|
||||||
};
|
};
|
||||||
],[])
|
],[
|
||||||
])
|
],[
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION], [
|
|
||||||
AC_MSG_CHECKING([whether iops->permission() exists])
|
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_permission], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_PERMISSION, 1, [iops->permission() exists])
|
AC_DEFINE(HAVE_PERMISSION, 1, [iops->permission() exists])
|
||||||
],[
|
],[
|
||||||
@@ -193,8 +180,9 @@ dnl # 2.6.26 API change,
|
|||||||
dnl # Check if inode_operations contains the function permission
|
dnl # Check if inode_operations contains the function permission
|
||||||
dnl # and expects the nameidata structure to be passed.
|
dnl # and expects the nameidata structure to be passed.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_permission_with_nameidata], [
|
AC_MSG_CHECKING([whether iops->permission() wants nameidata])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
|
||||||
@@ -205,12 +193,8 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
|
|||||||
iops __attribute__ ((unused)) = {
|
iops __attribute__ ((unused)) = {
|
||||||
.permission = permission_fn,
|
.permission = permission_fn,
|
||||||
};
|
};
|
||||||
],[])
|
],[
|
||||||
])
|
],[
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
|
|
||||||
AC_MSG_CHECKING([whether iops->permission() wants nameidata])
|
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_permission_with_nameidata], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_PERMISSION, 1, [iops->permission() exists])
|
AC_DEFINE(HAVE_PERMISSION, 1, [iops->permission() exists])
|
||||||
AC_DEFINE(HAVE_PERMISSION_WITH_NAMEIDATA, 1,
|
AC_DEFINE(HAVE_PERMISSION_WITH_NAMEIDATA, 1,
|
||||||
@@ -224,8 +208,9 @@ dnl #
|
|||||||
dnl # 2.6.32 API change,
|
dnl # 2.6.32 API change,
|
||||||
dnl # Check if inode_operations contains the function check_acl
|
dnl # Check if inode_operations contains the function check_acl
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_check_acl], [
|
AC_MSG_CHECKING([whether iops->check_acl() exists])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
int check_acl_fn(struct inode *inode, int mask) { return 0; }
|
int check_acl_fn(struct inode *inode, int mask) { return 0; }
|
||||||
@@ -234,12 +219,8 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL], [
|
|||||||
iops __attribute__ ((unused)) = {
|
iops __attribute__ ((unused)) = {
|
||||||
.check_acl = check_acl_fn,
|
.check_acl = check_acl_fn,
|
||||||
};
|
};
|
||||||
],[])
|
],[
|
||||||
])
|
],[
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL], [
|
|
||||||
AC_MSG_CHECKING([whether iops->check_acl() exists])
|
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_check_acl], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_CHECK_ACL, 1, [iops->check_acl() exists])
|
AC_DEFINE(HAVE_CHECK_ACL, 1, [iops->check_acl() exists])
|
||||||
],[
|
],[
|
||||||
@@ -251,8 +232,9 @@ dnl #
|
|||||||
dnl # 2.6.38 API change,
|
dnl # 2.6.38 API change,
|
||||||
dnl # The function check_acl gained a new parameter: flags
|
dnl # The function check_acl gained a new parameter: flags
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_check_acl_with_flags], [
|
AC_MSG_CHECKING([whether iops->check_acl() wants flags])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
int check_acl_fn(struct inode *inode, int mask,
|
int check_acl_fn(struct inode *inode, int mask,
|
||||||
@@ -262,12 +244,8 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
|
|||||||
iops __attribute__ ((unused)) = {
|
iops __attribute__ ((unused)) = {
|
||||||
.check_acl = check_acl_fn,
|
.check_acl = check_acl_fn,
|
||||||
};
|
};
|
||||||
],[])
|
],[
|
||||||
])
|
],[
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
|
|
||||||
AC_MSG_CHECKING([whether iops->check_acl() wants flags])
|
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_check_acl_with_flags], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_CHECK_ACL, 1, [iops->check_acl() exists])
|
AC_DEFINE(HAVE_CHECK_ACL, 1, [iops->check_acl() exists])
|
||||||
AC_DEFINE(HAVE_CHECK_ACL_WITH_FLAGS, 1,
|
AC_DEFINE(HAVE_CHECK_ACL_WITH_FLAGS, 1,
|
||||||
@@ -281,8 +259,9 @@ dnl #
|
|||||||
dnl # 3.1 API change,
|
dnl # 3.1 API change,
|
||||||
dnl # Check if inode_operations contains the function get_acl
|
dnl # Check if inode_operations contains the function get_acl
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
|
AC_MSG_CHECKING([whether iops->get_acl() exists])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
struct posix_acl *get_acl_fn(struct inode *inode, int type)
|
struct posix_acl *get_acl_fn(struct inode *inode, int type)
|
||||||
@@ -292,12 +271,8 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
|
|||||||
iops __attribute__ ((unused)) = {
|
iops __attribute__ ((unused)) = {
|
||||||
.get_acl = get_acl_fn,
|
.get_acl = get_acl_fn,
|
||||||
};
|
};
|
||||||
],[])
|
],[
|
||||||
])
|
],[
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
|
|
||||||
AC_MSG_CHECKING([whether iops->get_acl() exists])
|
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_GET_ACL, 1, [iops->get_acl() exists])
|
AC_DEFINE(HAVE_GET_ACL, 1, [iops->get_acl() exists])
|
||||||
],[
|
],[
|
||||||
@@ -309,23 +284,20 @@ dnl #
|
|||||||
dnl # 3.14 API change,
|
dnl # 3.14 API change,
|
||||||
dnl # Check if inode_operations contains the function set_acl
|
dnl # Check if inode_operations contains the function set_acl
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [
|
AC_MSG_CHECKING([whether iops->set_acl() exists])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
int set_acl_fn(struct inode *inode, struct posix_acl *acl,
|
int set_acl_fn(struct inode *inode, struct posix_acl *acl, int type)
|
||||||
int type) { return 0; }
|
{ return 0; }
|
||||||
|
|
||||||
static const struct inode_operations
|
static const struct inode_operations
|
||||||
iops __attribute__ ((unused)) = {
|
iops __attribute__ ((unused)) = {
|
||||||
.set_acl = set_acl_fn,
|
.set_acl = set_acl_fn,
|
||||||
};
|
};
|
||||||
],[])
|
],[
|
||||||
])
|
],[
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
|
|
||||||
AC_MSG_CHECKING([whether iops->set_acl() exists])
|
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
|
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
|
||||||
],[
|
],[
|
||||||
@@ -339,79 +311,16 @@ dnl # The kernel get_acl will now check cache before calling i_op->get_acl and
|
|||||||
dnl # do set_cached_acl after that, so i_op->get_acl don't need to do that
|
dnl # do set_cached_acl after that, so i_op->get_acl don't need to do that
|
||||||
dnl # anymore.
|
dnl # anymore.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_ACL_HANDLE_CACHE], [
|
|
||||||
ZFS_LINUX_TEST_SRC([get_acl_handle_cache], [
|
|
||||||
#include <linux/fs.h>
|
|
||||||
],[
|
|
||||||
void *sentinel __attribute__ ((unused)) =
|
|
||||||
uncached_acl_sentinel(NULL);
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE], [
|
AC_DEFUN([ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE], [
|
||||||
AC_MSG_CHECKING([whether uncached_acl_sentinel() exists])
|
AC_MSG_CHECKING([whether uncached_acl_sentinel() exists])
|
||||||
ZFS_LINUX_TEST_RESULT([get_acl_handle_cache], [
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/fs.h>
|
||||||
|
],[
|
||||||
|
void *sentinel __attribute__ ((unused)) = uncached_acl_sentinel(NULL);
|
||||||
|
],[
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_KERNEL_GET_ACL_HANDLE_CACHE, 1,
|
AC_DEFINE(HAVE_KERNEL_GET_ACL_HANDLE_CACHE, 1, [uncached_acl_sentinel() exists])
|
||||||
[uncached_acl_sentinel() exists])
|
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # 4.16 kernel: check if struct posix_acl acl.a_refcount is a refcount_t.
|
|
||||||
dnl # It's an atomic_t on older kernels.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_ACL_HAS_REFCOUNT], [
|
|
||||||
ZFS_LINUX_TEST_SRC([acl_refcount], [
|
|
||||||
#include <linux/backing-dev.h>
|
|
||||||
#include <linux/refcount.h>
|
|
||||||
#include <linux/posix_acl.h>
|
|
||||||
],[
|
|
||||||
struct posix_acl acl;
|
|
||||||
refcount_t *r __attribute__ ((unused)) = &acl.a_refcount;
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_ACL_HAS_REFCOUNT], [
|
|
||||||
AC_MSG_CHECKING([whether posix_acl has refcount_t])
|
|
||||||
ZFS_LINUX_TEST_RESULT([acl_refcount], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_ACL_REFCOUNT, 1, [posix_acl has refcount_t])
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_ACL], [
|
|
||||||
ZFS_AC_KERNEL_SRC_POSIX_ACL_RELEASE
|
|
||||||
ZFS_AC_KERNEL_SRC_SET_CACHED_ACL_USABLE
|
|
||||||
ZFS_AC_KERNEL_SRC_POSIX_ACL_CHMOD
|
|
||||||
ZFS_AC_KERNEL_SRC_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
|
|
||||||
ZFS_AC_KERNEL_SRC_POSIX_ACL_VALID_WITH_NS
|
|
||||||
ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION
|
|
||||||
ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
|
|
||||||
ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL
|
|
||||||
ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
|
|
||||||
ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL
|
|
||||||
ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL
|
|
||||||
ZFS_AC_KERNEL_SRC_GET_ACL_HANDLE_CACHE
|
|
||||||
ZFS_AC_KERNEL_SRC_ACL_HAS_REFCOUNT
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_ACL], [
|
|
||||||
ZFS_AC_KERNEL_POSIX_ACL_RELEASE
|
|
||||||
ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE
|
|
||||||
ZFS_AC_KERNEL_POSIX_ACL_CHMOD
|
|
||||||
ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
|
|
||||||
ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS
|
|
||||||
ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION
|
|
||||||
ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
|
|
||||||
ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL
|
|
||||||
ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
|
|
||||||
ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
|
|
||||||
ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL
|
|
||||||
ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE
|
|
||||||
ZFS_AC_KERNEL_ACL_HAS_REFCOUNT
|
|
||||||
])
|
|
||||||
|
|||||||
@@ -1,23 +1,21 @@
|
|||||||
dnl #
|
dnl #
|
||||||
dnl # Linux 4.9-rc5+ ABI, removal of the .aio_fsync field
|
dnl # Linux 4.9-rc5+ ABI, removal of the .aio_fsync field
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_AIO_FSYNC], [
|
AC_DEFUN([ZFS_AC_KERNEL_AIO_FSYNC], [
|
||||||
ZFS_LINUX_TEST_SRC([aio_fsync], [
|
AC_MSG_CHECKING([whether fops->aio_fsync() exists])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
static const struct file_operations
|
static const struct file_operations
|
||||||
fops __attribute__ ((unused)) = {
|
fops __attribute__ ((unused)) = {
|
||||||
.aio_fsync = NULL,
|
.aio_fsync = NULL,
|
||||||
};
|
};
|
||||||
],[])
|
],[
|
||||||
])
|
],[
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_AIO_FSYNC], [
|
|
||||||
AC_MSG_CHECKING([whether fops->aio_fsync() exists])
|
|
||||||
ZFS_LINUX_TEST_RESULT([aio_fsync], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_FILE_AIO_FSYNC, 1, [fops->aio_fsync() exists])
|
AC_DEFINE(HAVE_FILE_AIO_FSYNC, 1, [fops->aio_fsync() exists])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,16 @@ dnl # solution to handling automounts. Prior to this cifs/nfs clients
|
|||||||
dnl # which required automount support would abuse the follow_link()
|
dnl # which required automount support would abuse the follow_link()
|
||||||
dnl # operation on directories for this purpose.
|
dnl # operation on directories for this purpose.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [
|
AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [
|
||||||
ZFS_LINUX_TEST_SRC([dentry_operations_d_automount], [
|
AC_MSG_CHECKING([whether dops->d_automount() exists])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/dcache.h>
|
#include <linux/dcache.h>
|
||||||
struct vfsmount *d_automount(struct path *p) { return NULL; }
|
struct vfsmount *d_automount(struct path *p) { return NULL; }
|
||||||
struct dentry_operations dops __attribute__ ((unused)) = {
|
struct dentry_operations dops __attribute__ ((unused)) = {
|
||||||
.d_automount = d_automount,
|
.d_automount = d_automount,
|
||||||
};
|
};
|
||||||
],[])
|
],[
|
||||||
])
|
],[
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [
|
|
||||||
AC_MSG_CHECKING([whether dops->d_automount() exists])
|
|
||||||
ZFS_LINUX_TEST_RESULT([dentry_operations_d_automount], [
|
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_AUTOMOUNT, 1, [dops->automount() exists])
|
AC_DEFINE(HAVE_AUTOMOUNT, 1, [dops->automount() exists])
|
||||||
],[
|
],[
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user