Update OpenZFS to 2.0.0-rc3-gfc5966
This commit is contained in:
parent
01ea34f1d8
commit
e2228bd990
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor-sys/openzfs/dist/; revision=366348 svn path=/vendor-sys/openzfs/2.0-rc3-gfc5966/; revision=366349; tag=vendor/openzfs/2.0-rc3-gfc5966
345
.github/CONTRIBUTING.md
vendored
Normal file
345
.github/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,345 @@
|
||||
# Contributing to OpenZFS
|
||||
<p align="center">
|
||||
<img alt="OpenZFS Logo"
|
||||
src="https://openzfs.github.io/openzfs-docs/_static/img/logo/480px-Open-ZFS-Secondary-Logo-Colour-halfsize.png"/>
|
||||
</p>
|
||||
|
||||
*First of all, thank you for taking the time to contribute!*
|
||||
|
||||
By using the following guidelines, you can help us make OpenZFS even better.
|
||||
|
||||
## Table Of Contents
|
||||
[What should I know before I get
|
||||
started?](#what-should-i-know-before-i-get-started)
|
||||
|
||||
* [Get ZFS](#get-zfs)
|
||||
* [Debug ZFS](#debug-zfs)
|
||||
* [Where can I ask for help?](#where-can-I-ask-for-help)
|
||||
|
||||
[How Can I Contribute?](#how-can-i-contribute)
|
||||
|
||||
* [Reporting Bugs](#reporting-bugs)
|
||||
* [Suggesting Enhancements](#suggesting-enhancements)
|
||||
* [Pull Requests](#pull-requests)
|
||||
* [Testing](#testing)
|
||||
|
||||
[Style Guides](#style-guides)
|
||||
|
||||
* [Coding Conventions](#coding-conventions)
|
||||
* [Commit Message Formats](#commit-message-formats)
|
||||
* [New Changes](#new-changes)
|
||||
* [OpenZFS Patch Ports](#openzfs-patch-ports)
|
||||
* [Coverity Defect Fixes](#coverity-defect-fixes)
|
||||
* [Signed Off By](#signed-off-by)
|
||||
|
||||
Helpful resources
|
||||
|
||||
* [OpenZFS Documentation](https://openzfs.github.io/openzfs-docs/)
|
||||
* [OpenZFS Developer Resources](http://open-zfs.org/wiki/Developer_resources)
|
||||
* [Git and GitHub for beginners](https://openzfs.github.io/openzfs-docs/Developer%20Resources/Git%20and%20GitHub%20for%20beginners.html)
|
||||
|
||||
## What should I know before I get started?
|
||||
|
||||
### Get ZFS
|
||||
You can build zfs packages by following [these
|
||||
instructions](https://openzfs.github.io/openzfs-docs/Developer%20Resources/Building%20ZFS.html),
|
||||
or install stable packages from [your distribution's
|
||||
repository](https://openzfs.github.io/openzfs-docs/Getting%20Started/index.html).
|
||||
|
||||
### Debug ZFS
|
||||
A variety of methods and tools are available to aid ZFS developers.
|
||||
It's strongly recommended that when developing a patch the `--enable-debug`
|
||||
configure option should be set. This will enable additional correctness
|
||||
checks and all the ASSERTs to help quickly catch potential issues.
|
||||
|
||||
In addition, there are numerous utilities and debugging files which
|
||||
provide visibility into the inner workings of ZFS. The most useful
|
||||
of these tools are discussed in detail on the [Troubleshooting
|
||||
page](https://openzfs.github.io/openzfs-docs/Basic%20Concepts/Troubleshooting.html).
|
||||
|
||||
### Where can I ask for help?
|
||||
The [zfs-discuss mailing
|
||||
list](https://openzfs.github.io/openzfs-docs/Project%20and%20Community/Mailing%20Lists.html)
|
||||
or IRC are the best places to ask for help. Please do not file
|
||||
support requests on the GitHub issue tracker.
|
||||
|
||||
## How Can I Contribute?
|
||||
|
||||
### Reporting Bugs
|
||||
*Please* contact us via the [zfs-discuss mailing
|
||||
list](https://openzfs.github.io/openzfs-docs/Project%20and%20Community/Mailing%20Lists.html)
|
||||
or IRC if you aren't certain that you are experiencing a bug.
|
||||
|
||||
If you run into an issue, please search our [issue
|
||||
tracker](https://github.com/openzfs/zfs/issues) *first* to ensure the
|
||||
issue hasn't been reported before. Open a new issue only if you haven't
|
||||
found anything similar to your issue.
|
||||
|
||||
You can open a new issue and search existing issues using the public [issue
|
||||
tracker](https://github.com/openzfs/zfs/issues).
|
||||
|
||||
#### When opening a new issue, please include the following information at the top of the issue:
|
||||
* What distribution (with version) you are using.
|
||||
* The spl and zfs versions you are using, installation method (repository
|
||||
or manual compilation).
|
||||
* Describe the issue you are experiencing.
|
||||
* Describe how to reproduce the issue.
|
||||
* Including any warning/errors/backtraces from the system logs.
|
||||
|
||||
When a new issue is opened, it is not uncommon for developers to request
|
||||
additional information.
|
||||
|
||||
In general, the more detail you share about a problem the quicker a
|
||||
developer can resolve it. For example, providing a simple test case is always
|
||||
exceptionally helpful.
|
||||
|
||||
Be prepared to work with the developers investigating your issue. Your
|
||||
assistance is crucial in providing a quick solution. They may ask for
|
||||
information like:
|
||||
|
||||
* Your pool configuration as reported by `zdb` or `zpool status`.
|
||||
* Your hardware configuration, such as
|
||||
* Number of CPUs.
|
||||
* Amount of memory.
|
||||
* Whether your system has ECC memory.
|
||||
* Whether it is running under a VMM/Hypervisor.
|
||||
* Kernel version.
|
||||
* Values of the spl/zfs module parameters.
|
||||
* Stack traces which may be logged to `dmesg`.
|
||||
|
||||
### Suggesting Enhancements
|
||||
OpenZFS is a widely deployed production filesystem which is under active
|
||||
development. The team's primary focus is on fixing known issues, improving
|
||||
performance, and adding compelling new features.
|
||||
|
||||
You can view the list of proposed features
|
||||
by filtering the issue tracker by the ["Type: Feature"
|
||||
label](https://github.com/openzfs/zfs/issues?q=is%3Aopen+is%3Aissue+label%3A%22Type%3A+Feature%22).
|
||||
If you have an idea for a feature first check this list. If your idea already
|
||||
appears then add a +1 to the top most comment, this helps us gauge interest
|
||||
in that feature.
|
||||
|
||||
Otherwise, open a new issue and describe your proposed feature. Why is this
|
||||
feature needed? What problem does it solve?
|
||||
|
||||
### Pull Requests
|
||||
|
||||
#### General
|
||||
|
||||
* All pull requests must be based on the current master branch and apply
|
||||
without conflicts.
|
||||
* Please attempt to limit pull requests to a single commit which resolves
|
||||
one specific issue.
|
||||
* Make sure your commit messages are in the correct format. See the
|
||||
[Commit Message Formats](#commit-message-formats) section for more information.
|
||||
* When updating a pull request squash multiple commits by performing a
|
||||
[rebase](https://git-scm.com/docs/git-rebase) (squash).
|
||||
* For large pull requests consider structuring your changes as a stack of
|
||||
logically independent patches which build on each other. This makes large
|
||||
changes easier to review and approve which speeds up the merging process.
|
||||
* Try to keep pull requests simple. Simple code with comments is much easier
|
||||
to review and approve.
|
||||
* All proposed changes must be approved by an OpenZFS organization member.
|
||||
* If you have an idea you'd like to discuss or which requires additional testing, consider opening it as a draft pull request.
|
||||
Once everything is in good shape and the details have been worked out you can remove its draft status.
|
||||
Any required reviews can then be finalized and the pull request merged.
|
||||
|
||||
#### Tests and Benchmarks
|
||||
* Every pull request will by tested by the buildbot on multiple platforms by running the [zfs-tests.sh and zloop.sh](
|
||||
https://openzfs.github.io/openzfs-docs/Developer%20Resources/Building%20ZFS.html#running-zloop-sh-and-zfs-tests-sh) test suites.
|
||||
* To verify your changes conform to the [style guidelines](
|
||||
https://github.com/openzfs/zfs/blob/master/.github/CONTRIBUTING.md#style-guides
|
||||
), please run `make checkstyle` and resolve any warnings.
|
||||
* Static code analysis of each pull request is performed by the buildbot; run `make lint` to check your changes.
|
||||
* Test cases should be provided when appropriate.
|
||||
This includes making sure new features have adequate code coverage.
|
||||
* If your pull request improves performance, please include some benchmarks.
|
||||
* The pull request must pass all required [ZFS
|
||||
Buildbot](http://build.zfsonlinux.org/) builders before
|
||||
being accepted. If you are experiencing intermittent TEST
|
||||
builder failures, you may be experiencing a [test suite
|
||||
issue](https://github.com/openzfs/zfs/issues?q=is%3Aissue+is%3Aopen+label%3A%22Type%3A+Test+Suite%22).
|
||||
There are also various [buildbot options](https://openzfs.github.io/openzfs-docs/Developer%20Resources/Buildbot%20Options.html)
|
||||
to control how changes are tested.
|
||||
|
||||
### Testing
|
||||
All help is appreciated! If you're in a position to run the latest code
|
||||
consider helping us by reporting any functional problems, performance
|
||||
regressions or other suspected issues. By running the latest code to a wide
|
||||
range of realistic workloads, configurations and architectures we're better
|
||||
able quickly identify and resolve potential issues.
|
||||
|
||||
Users can also run the [ZFS Test
|
||||
Suite](https://github.com/openzfs/zfs/tree/master/tests) on their systems
|
||||
to verify ZFS is behaving as intended.
|
||||
|
||||
## Style Guides
|
||||
|
||||
### Repository Structure
|
||||
|
||||
OpenZFS uses a standardised branching structure.
|
||||
- The "development and main branch", is the branch all development should be based on.
|
||||
- "Release branches" contain the latest released code for said version.
|
||||
- "Staging branches" contain selected commits prior to being released.
|
||||
|
||||
**Branch Names:**
|
||||
- Development and Main branch: `master`
|
||||
- Release branches: `zfs-$VERSION-release`
|
||||
- Staging branches: `zfs-$VERSION-staging`
|
||||
|
||||
`$VERSION` should be replaced with the `major.minor` version number.
|
||||
_(This is the version number without the `.patch` version at the end)_
|
||||
|
||||
### Coding Conventions
|
||||
We currently use [C Style and Coding Standards for
|
||||
SunOS](http://www.cis.upenn.edu/%7Elee/06cse480/data/cstyle.ms.pdf) as our
|
||||
coding convention.
|
||||
|
||||
This repository has an `.editorconfig` file. If your editor [supports
|
||||
editorconfig](https://editorconfig.org/#download), it will
|
||||
automatically respect most of this project's whitespace preferences.
|
||||
|
||||
Additionally, Git can help warn on whitespace problems as well:
|
||||
|
||||
```
|
||||
git config --local core.whitespace trailing-space,space-before-tab,indent-with-non-tab,-tab-in-indent
|
||||
```
|
||||
|
||||
### Commit Message Formats
|
||||
#### New Changes
|
||||
Commit messages for new changes must meet the following guidelines:
|
||||
* In 72 characters or less, provide a summary of the change as the
|
||||
first line in the commit message.
|
||||
* A body which provides a description of the change. If necessary,
|
||||
please summarize important information such as why the proposed
|
||||
approach was chosen or a brief description of the bug you are resolving.
|
||||
Each line of the body must be 72 characters or less.
|
||||
* The last line must be a `Signed-off-by:` tag. See the
|
||||
[Signed Off By](#signed-off-by) section for more information.
|
||||
|
||||
An example commit message for new changes is provided below.
|
||||
|
||||
```
|
||||
This line is a brief summary of your change
|
||||
|
||||
Please provide at least a couple sentences describing the
|
||||
change. If necessary, please summarize decisions such as
|
||||
why the proposed approach was chosen or what bug you are
|
||||
attempting to solve.
|
||||
|
||||
Signed-off-by: Contributor <contributor@email.com>
|
||||
```
|
||||
|
||||
#### OpenZFS Patch Ports
|
||||
If you are porting OpenZFS patches, the commit message must meet
|
||||
the following guidelines:
|
||||
* The first line must be the summary line from the most important OpenZFS commit being ported.
|
||||
It must begin with `OpenZFS dddd, dddd - ` where `dddd` are OpenZFS issue numbers.
|
||||
* Provides a `Authored by:` line to attribute each patch for each original author.
|
||||
* Provides the `Reviewed by:` and `Approved by:` lines from each original
|
||||
OpenZFS commit.
|
||||
* Provides a `Ported-by:` line with the developer's name followed by
|
||||
their email for each OpenZFS commit.
|
||||
* Provides a `OpenZFS-issue:` line with link for each original illumos
|
||||
issue.
|
||||
* Provides a `OpenZFS-commit:` line with link for each original OpenZFS commit.
|
||||
* If necessary, provide some porting notes to describe any deviations from
|
||||
the original OpenZFS commits.
|
||||
|
||||
An example OpenZFS patch port commit message for a single patch is provided
|
||||
below.
|
||||
```
|
||||
OpenZFS 1234 - Summary from the original OpenZFS commit
|
||||
|
||||
Authored by: Original Author <original@email.com>
|
||||
Reviewed by: Reviewer One <reviewer1@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 if necessary.
|
||||
|
||||
OpenZFS-issue: https://www.illumos.org/issues/1234
|
||||
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/).
|
||||
|
||||
#### Co-authored By
|
||||
If someone else had part in your pull request, please add the following to the commit:
|
||||
`Co-authored-by: Name <gitregistered@email.address>`
|
||||
This is useful if their authorship was lost during squashing, rebasing, etc.,
|
||||
but may be used in any situation where there are co-authors.
|
||||
|
||||
The email address used here should be the same as on the GitHub profile of said user.
|
||||
If said user does not have their email address public, please use the following instead:
|
||||
`Co-authored-by: Name <[username]@users.noreply.github.com>`
|
@ -363,16 +363,16 @@ get_usage(zfs_help_t idx)
|
||||
return (gettext("\tuserspace [-Hinp] [-o field[,...]] "
|
||||
"[-s field] ...\n"
|
||||
"\t [-S field] ... [-t type[,...]] "
|
||||
"<filesystem|snapshot>\n"));
|
||||
"<filesystem|snapshot|path>\n"));
|
||||
case HELP_GROUPSPACE:
|
||||
return (gettext("\tgroupspace [-Hinp] [-o field[,...]] "
|
||||
"[-s field] ...\n"
|
||||
"\t [-S field] ... [-t type[,...]] "
|
||||
"<filesystem|snapshot>\n"));
|
||||
"<filesystem|snapshot|path>\n"));
|
||||
case HELP_PROJECTSPACE:
|
||||
return (gettext("\tprojectspace [-Hp] [-o field[,...]] "
|
||||
"[-s field] ... \n"
|
||||
"\t [-S field] ... <filesystem|snapshot>\n"));
|
||||
"\t [-S field] ... <filesystem|snapshot|path>\n"));
|
||||
case HELP_PROJECT:
|
||||
return (gettext("\tproject [-d|-r] <directory|file ...>\n"
|
||||
"\tproject -c [-0] [-d|-r] [-p id] <directory|file ...>\n"
|
||||
@ -2481,11 +2481,13 @@ zfs_do_upgrade(int argc, char **argv)
|
||||
|
||||
/*
|
||||
* zfs userspace [-Hinp] [-o field[,...]] [-s field [-s field]...]
|
||||
* [-S field [-S field]...] [-t type[,...]] filesystem | snapshot
|
||||
* [-S field [-S field]...] [-t type[,...]]
|
||||
* filesystem | snapshot | path
|
||||
* zfs groupspace [-Hinp] [-o field[,...]] [-s field [-s field]...]
|
||||
* [-S field [-S field]...] [-t type[,...]] filesystem | snapshot
|
||||
* [-S field [-S field]...] [-t type[,...]]
|
||||
* filesystem | snapshot | path
|
||||
* zfs projectspace [-Hp] [-o field[,...]] [-s field [-s field]...]
|
||||
* [-S field [-S field]...] filesystem | snapshot
|
||||
* [-S field [-S field]...] filesystem | snapshot | path
|
||||
*
|
||||
* -H Scripted mode; elide headers and separate columns by tabs.
|
||||
* -i Translate SID to POSIX ID.
|
||||
@ -3191,7 +3193,7 @@ zfs_do_userspace(int argc, char **argv)
|
||||
} while (delim != NULL);
|
||||
}
|
||||
|
||||
if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM |
|
||||
if ((zhp = zfs_path_to_zhandle(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM |
|
||||
ZFS_TYPE_SNAPSHOT)) == NULL)
|
||||
return (1);
|
||||
if (zhp->zfs_head_type != ZFS_TYPE_FILESYSTEM) {
|
||||
|
@ -91,7 +91,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_DEBUG_LOCK_ALLOC], [
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC], [
|
||||
AC_MSG_CHECKING([whether mutex_lock() is GPL-only])
|
||||
ZFS_LINUX_TEST_RESULT([config_debug_lock_alloc], [
|
||||
ZFS_LINUX_TEST_RESULT([config_debug_lock_alloc_license], [
|
||||
AC_MSG_RESULT(no)
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
|
@ -6,10 +6,11 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_OBJTOOL], [
|
||||
dnl # 4.6 API for compile-time stack validation
|
||||
ZFS_LINUX_TEST_SRC([objtool], [
|
||||
#undef __ASSEMBLY__
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/frame.h>
|
||||
],[
|
||||
#if !defined(FRAME_BEGIN)
|
||||
CTASSERT(1);
|
||||
#error "FRAME_BEGIN is not defined"
|
||||
#endif
|
||||
])
|
||||
|
||||
@ -18,7 +19,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_OBJTOOL], [
|
||||
#include <linux/frame.h>
|
||||
],[
|
||||
#if !defined(STACK_FRAME_NON_STANDARD)
|
||||
CTASSERT(1);
|
||||
#error "STACK_FRAME_NON_STANDARD is not defined."
|
||||
#endif
|
||||
])
|
||||
])
|
||||
|
@ -204,6 +204,7 @@ AC_CONFIG_FILES([
|
||||
tests/zfs-tests/Makefile
|
||||
tests/zfs-tests/callbacks/Makefile
|
||||
tests/zfs-tests/cmd/Makefile
|
||||
tests/zfs-tests/cmd/badsend/Makefile
|
||||
tests/zfs-tests/cmd/btree_test/Makefile
|
||||
tests/zfs-tests/cmd/chg_usr_exec/Makefile
|
||||
tests/zfs-tests/cmd/devname2devid/Makefile
|
||||
|
@ -15,8 +15,8 @@
|
||||
# See "4.5 Disable root prompt on the initramfs" of Securing Debian Manual:
|
||||
# https://www.debian.org/doc/manuals/securing-debian-howto/ch4.en.html
|
||||
shell() {
|
||||
if type panic > /dev/null 2>&1; then
|
||||
panic $@
|
||||
if command -v panic > /dev/null 2>&1; then
|
||||
panic
|
||||
else
|
||||
/bin/sh
|
||||
fi
|
||||
@ -26,22 +26,23 @@ shell() {
|
||||
# pools and mounting any filesystems.
|
||||
pre_mountroot()
|
||||
{
|
||||
if type run_scripts > /dev/null 2>&1 && \
|
||||
[ -f "/scripts/local-top" -o -d "/scripts/local-top" ]
|
||||
if command -v run_scripts > /dev/null 2>&1
|
||||
then
|
||||
[ "$quiet" != "y" ] && \
|
||||
zfs_log_begin_msg "Running /scripts/local-top"
|
||||
run_scripts /scripts/local-top
|
||||
[ "$quiet" != "y" ] && zfs_log_end_msg
|
||||
fi
|
||||
if [ -f "/scripts/local-top" ] || [ -d "/scripts/local-top" ]
|
||||
then
|
||||
[ "$quiet" != "y" ] && \
|
||||
zfs_log_begin_msg "Running /scripts/local-top"
|
||||
run_scripts /scripts/local-top
|
||||
[ "$quiet" != "y" ] && zfs_log_end_msg
|
||||
fi
|
||||
|
||||
if type run_scripts > /dev/null 2>&1 && \
|
||||
[ -f "/scripts/local-premount" -o -d "/scripts/local-premount" ]
|
||||
then
|
||||
[ "$quiet" != "y" ] && \
|
||||
zfs_log_begin_msg "Running /scripts/local-premount"
|
||||
run_scripts /scripts/local-premount
|
||||
[ "$quiet" != "y" ] && zfs_log_end_msg
|
||||
if [ -f "/scripts/local-premount" ] || [ -d "/scripts/local-premount" ]
|
||||
then
|
||||
[ "$quiet" != "y" ] && \
|
||||
zfs_log_begin_msg "Running /scripts/local-premount"
|
||||
run_scripts /scripts/local-premount
|
||||
[ "$quiet" != "y" ] && zfs_log_end_msg
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@ -57,10 +58,10 @@ disable_plymouth()
|
||||
# Get a ZFS filesystem property value.
|
||||
get_fs_value()
|
||||
{
|
||||
local fs="$1"
|
||||
local value=$2
|
||||
fs="$1"
|
||||
value=$2
|
||||
|
||||
"${ZFS}" get -H -ovalue $value "$fs" 2> /dev/null
|
||||
"${ZFS}" get -H -ovalue "$value" "$fs" 2> /dev/null
|
||||
}
|
||||
|
||||
# Find the 'bootfs' property on pool $1.
|
||||
@ -68,7 +69,7 @@ get_fs_value()
|
||||
# pool by exporting it again.
|
||||
find_rootfs()
|
||||
{
|
||||
local pool="$1"
|
||||
pool="$1"
|
||||
|
||||
# If 'POOL_IMPORTED' isn't set, no pool imported and therefore
|
||||
# we won't be able to find a root fs.
|
||||
@ -84,7 +85,7 @@ find_rootfs()
|
||||
|
||||
# Make sure it's not '-' and that it starts with /.
|
||||
if [ "${ZFS_BOOTFS}" != "-" ] && \
|
||||
$(get_fs_value "${ZFS_BOOTFS}" mountpoint | grep -q '^/$')
|
||||
get_fs_value "${ZFS_BOOTFS}" mountpoint | grep -q '^/$'
|
||||
then
|
||||
# Keep it mounted
|
||||
POOL_IMPORTED=1
|
||||
@ -101,14 +102,13 @@ find_rootfs()
|
||||
# Support function to get a list of all pools, separated with ';'
|
||||
find_pools()
|
||||
{
|
||||
local CMD="$*"
|
||||
local pools pool
|
||||
CMD="$*"
|
||||
|
||||
pools=$($CMD 2> /dev/null | \
|
||||
grep -E "pool:|^[a-zA-Z0-9]" | \
|
||||
sed 's@.*: @@' | \
|
||||
while read pool; do \
|
||||
echo -n "$pool;"
|
||||
while read -r pool; do \
|
||||
printf "%s" "$pool;"
|
||||
done)
|
||||
|
||||
echo "${pools%%;}" # Return without the last ';'.
|
||||
@ -117,8 +117,6 @@ find_pools()
|
||||
# Get a list of all available pools
|
||||
get_pools()
|
||||
{
|
||||
local available_pools npools
|
||||
|
||||
if [ -n "${ZFS_POOL_IMPORT}" ]; then
|
||||
echo "$ZFS_POOL_IMPORT"
|
||||
return 0
|
||||
@ -159,9 +157,8 @@ get_pools()
|
||||
# Filter out any exceptions...
|
||||
if [ -n "$ZFS_POOL_EXCEPTIONS" ]
|
||||
then
|
||||
local found=""
|
||||
local apools=""
|
||||
local pool exception
|
||||
found=""
|
||||
apools=""
|
||||
OLD_IFS="$IFS" ; IFS=";"
|
||||
|
||||
for pool in $available_pools
|
||||
@ -194,8 +191,7 @@ get_pools()
|
||||
# Import given pool $1
|
||||
import_pool()
|
||||
{
|
||||
local pool="$1"
|
||||
local dirs dir
|
||||
pool="$1"
|
||||
|
||||
# Verify that the pool isn't already imported
|
||||
# Make as sure as we can to not require '-f' to import.
|
||||
@ -205,7 +201,7 @@ import_pool()
|
||||
# to something we can use later with the real import(s). We want to
|
||||
# make sure we find all by* dirs, BUT by-vdev should be first (if it
|
||||
# exists).
|
||||
if [ -n "$USE_DISK_BY_ID" -a -z "$ZPOOL_IMPORT_PATH" ]
|
||||
if [ -n "$USE_DISK_BY_ID" ] && [ -z "$ZPOOL_IMPORT_PATH" ]
|
||||
then
|
||||
dirs="$(for dir in $(echo /dev/disk/by-*)
|
||||
do
|
||||
@ -213,7 +209,7 @@ import_pool()
|
||||
echo "$dir" | grep -q /by-vdev && continue
|
||||
[ ! -d "$dir" ] && continue
|
||||
|
||||
echo -n "$dir:"
|
||||
printf "%s" "$dir:"
|
||||
done | sed 's,:$,,g')"
|
||||
|
||||
if [ -d "/dev/disk/by-vdev" ]
|
||||
@ -277,7 +273,7 @@ import_pool()
|
||||
# with more logging etc.
|
||||
load_module_initrd()
|
||||
{
|
||||
if [ "$ZFS_INITRD_PRE_MOUNTROOT_SLEEP" > 0 ]
|
||||
if [ "$ZFS_INITRD_PRE_MOUNTROOT_SLEEP" -gt 0 ] 2>/dev/null
|
||||
then
|
||||
if [ "$quiet" != "y" ]; then
|
||||
zfs_log_begin_msg "Sleeping for" \
|
||||
@ -288,9 +284,9 @@ load_module_initrd()
|
||||
fi
|
||||
|
||||
# Wait for all of the /dev/{hd,sd}[a-z] device nodes to appear.
|
||||
if type wait_for_udev > /dev/null 2>&1 ; then
|
||||
if command -v wait_for_udev > /dev/null 2>&1 ; then
|
||||
wait_for_udev 10
|
||||
elif type wait_for_dev > /dev/null 2>&1 ; then
|
||||
elif command -v wait_for_dev > /dev/null 2>&1 ; then
|
||||
wait_for_dev
|
||||
fi
|
||||
|
||||
@ -300,7 +296,7 @@ load_module_initrd()
|
||||
# Load the module
|
||||
load_module "zfs" || return 1
|
||||
|
||||
if [ "$ZFS_INITRD_POST_MODPROBE_SLEEP" > 0 ]
|
||||
if [ "$ZFS_INITRD_POST_MODPROBE_SLEEP" -gt 0 ] 2>/dev/null
|
||||
then
|
||||
if [ "$quiet" != "y" ]; then
|
||||
zfs_log_begin_msg "Sleeping for" \
|
||||
@ -316,12 +312,10 @@ load_module_initrd()
|
||||
# Mount a given filesystem
|
||||
mount_fs()
|
||||
{
|
||||
local fs="$1"
|
||||
local mountpoint
|
||||
fs="$1"
|
||||
|
||||
# Check that the filesystem exists
|
||||
"${ZFS}" list -oname -tfilesystem -H "${fs}" > /dev/null 2>&1
|
||||
[ "$?" -ne 0 ] && return 1
|
||||
"${ZFS}" list -oname -tfilesystem -H "${fs}" > /dev/null 2>&1 || return 1
|
||||
|
||||
# Skip filesystems with canmount=off. The root fs should not have
|
||||
# canmount=off, but ignore it for backwards compatibility just in case.
|
||||
@ -333,14 +327,14 @@ mount_fs()
|
||||
|
||||
# Need the _original_ datasets mountpoint!
|
||||
mountpoint=$(get_fs_value "$fs" mountpoint)
|
||||
if [ "$mountpoint" = "legacy" -o "$mountpoint" = "none" ]; then
|
||||
if [ "$mountpoint" = "legacy" ] || [ "$mountpoint" = "none" ]; then
|
||||
# Can't use the mountpoint property. Might be one of our
|
||||
# clones. Check the 'org.zol:mountpoint' property set in
|
||||
# clone_snap() if that's usable.
|
||||
mountpoint=$(get_fs_value "$fs" org.zol:mountpoint)
|
||||
if [ "$mountpoint" = "legacy" -o \
|
||||
"$mountpoint" = "none" -o \
|
||||
"$mountpoint" = "-" ]
|
||||
if [ "$mountpoint" = "legacy" ] ||
|
||||
[ "$mountpoint" = "none" ] ||
|
||||
[ "$mountpoint" = "-" ]
|
||||
then
|
||||
if [ "$fs" != "${ZFS_BOOTFS}" ]; then
|
||||
# We don't have a proper mountpoint and this
|
||||
@ -396,10 +390,10 @@ mount_fs()
|
||||
# Unlock a ZFS native encrypted filesystem.
|
||||
decrypt_fs()
|
||||
{
|
||||
local fs="$1"
|
||||
|
||||
fs="$1"
|
||||
|
||||
# If pool encryption is active and the zfs command understands '-o encryption'
|
||||
if [ "$(zpool list -H -o feature@encryption $(echo "${fs}" | awk -F\/ '{print $1}'))" = 'active' ]; then
|
||||
if [ "$(zpool list -H -o feature@encryption "$(echo "${fs}" | awk -F/ '{print $1}')")" = 'active' ]; then
|
||||
|
||||
# Determine dataset that holds key for root dataset
|
||||
ENCRYPTIONROOT="$(get_fs_value "${fs}" encryptionroot)"
|
||||
@ -427,7 +421,7 @@ decrypt_fs()
|
||||
TRY_COUNT=$((TRY_COUNT - 1))
|
||||
done
|
||||
|
||||
# Prompt with systemd, if active
|
||||
# Prompt with systemd, if active
|
||||
elif [ -e /run/systemd/system ]; then
|
||||
echo "systemd-ask-password" > /run/zfs_console_askpwd_cmd
|
||||
while [ $TRY_COUNT -gt 0 ]; do
|
||||
@ -454,7 +448,7 @@ decrypt_fs()
|
||||
# Destroy a given filesystem.
|
||||
destroy_fs()
|
||||
{
|
||||
local fs="$1"
|
||||
fs="$1"
|
||||
|
||||
[ "$quiet" != "y" ] && \
|
||||
zfs_log_begin_msg "Destroying '$fs'"
|
||||
@ -489,9 +483,9 @@ destroy_fs()
|
||||
# mounted with a 'zfs mount -a' in the init/systemd scripts).
|
||||
clone_snap()
|
||||
{
|
||||
local snap="$1"
|
||||
local destfs="$2"
|
||||
local mountpoint="$3"
|
||||
snap="$1"
|
||||
destfs="$2"
|
||||
mountpoint="$3"
|
||||
|
||||
[ "$quiet" != "y" ] && zfs_log_begin_msg "Cloning '$snap' to '$destfs'"
|
||||
|
||||
@ -529,7 +523,7 @@ clone_snap()
|
||||
# Rollback a given snapshot.
|
||||
rollback_snap()
|
||||
{
|
||||
local snap="$1"
|
||||
snap="$1"
|
||||
|
||||
[ "$quiet" != "y" ] && zfs_log_begin_msg "Rollback $snap"
|
||||
|
||||
@ -559,9 +553,8 @@ rollback_snap()
|
||||
# to the user to choose from.
|
||||
ask_user_snap()
|
||||
{
|
||||
local fs="$1"
|
||||
local i=1
|
||||
local SNAP snapnr snap debug
|
||||
fs="$1"
|
||||
i=1
|
||||
|
||||
# We need to temporarily disable debugging. Set 'debug' so we
|
||||
# remember to enabled it again.
|
||||
@ -574,16 +567,16 @@ ask_user_snap()
|
||||
# Because we need the resulting snapshot, which is sent on
|
||||
# stdout to the caller, we use stderr for our questions.
|
||||
echo "What snapshot do you want to boot from?" > /dev/stderr
|
||||
while read snap; do
|
||||
while read -r snap; do
|
||||
echo " $i: ${snap}" > /dev/stderr
|
||||
eval `echo SNAP_$i=$snap`
|
||||
eval "$(echo SNAP_$i=$snap)"
|
||||
i=$((i + 1))
|
||||
done <<EOT
|
||||
$("${ZFS}" list -H -oname -tsnapshot -r "${fs}")
|
||||
EOT
|
||||
|
||||
echo -n " Snap nr [1-$((i-1))]? " > /dev/stderr
|
||||
read snapnr
|
||||
echo "%s" " Snap nr [1-$((i-1))]? " > /dev/stderr
|
||||
read -r snapnr
|
||||
|
||||
# Re-enable debugging.
|
||||
if [ -n "${debug}" ]; then
|
||||
@ -591,16 +584,16 @@ EOT
|
||||
set -x
|
||||
fi
|
||||
|
||||
echo "$(eval echo "$"SNAP_$snapnr)"
|
||||
echo "$(eval echo '$SNAP_'$snapnr)"
|
||||
}
|
||||
|
||||
setup_snapshot_booting()
|
||||
{
|
||||
local snap="$1"
|
||||
local s destfs subfs mountpoint retval=0 filesystems fs
|
||||
snap="$1"
|
||||
retval=0
|
||||
|
||||
# Make sure that the snapshot specified actually exist.
|
||||
if [ ! $(get_fs_value "${snap}" type) ]
|
||||
# Make sure that the snapshot specified actually exists.
|
||||
if [ ! "$(get_fs_value "${snap}" type)" ]
|
||||
then
|
||||
# Snapshot does not exist (...@<null> ?)
|
||||
# ask the user for a snapshot to use.
|
||||
@ -617,7 +610,7 @@ setup_snapshot_booting()
|
||||
then
|
||||
# If the destination dataset for the clone
|
||||
# already exists, destroy it. Recursively
|
||||
if [ $(get_fs_value "${rootfs}_${snapname}" type) ]; then
|
||||
if [ "$(get_fs_value "${rootfs}_${snapname}" type)" ]; then
|
||||
filesystems=$("${ZFS}" list -oname -tfilesystem -H \
|
||||
-r -Sname "${ZFS_BOOTFS}")
|
||||
for fs in $filesystems; do
|
||||
@ -652,8 +645,8 @@ setup_snapshot_booting()
|
||||
# with clone_snap(). If legacy or none, then use
|
||||
# the sub fs value.
|
||||
mountpoint=$(get_fs_value "${s%%@*}" mountpoint)
|
||||
if [ "$mountpoint" = "legacy" -o \
|
||||
"$mountpoint" = "none" ]
|
||||
if [ "$mountpoint" = "legacy" ] || \
|
||||
[ "$mountpoint" = "none" ]
|
||||
then
|
||||
if [ -n "${subfs}" ]; then
|
||||
mountpoint="${subfs}"
|
||||
@ -678,8 +671,6 @@ setup_snapshot_booting()
|
||||
# This is the main function.
|
||||
mountroot()
|
||||
{
|
||||
local snaporig snapsub destfs pool POOLS
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# I N I T I A L S E T U P
|
||||
|
||||
@ -742,7 +733,7 @@ mountroot()
|
||||
# No longer set in the defaults file, but it could have been set in
|
||||
# get_pools() in some circumstances. If it's something, but not 'yes',
|
||||
# it's no good to us.
|
||||
[ -n "$USE_DISK_BY_ID" -a "$USE_DISK_BY_ID" != 'yes' ] && \
|
||||
[ -n "$USE_DISK_BY_ID" ] && [ "$USE_DISK_BY_ID" != 'yes' ] && \
|
||||
unset USE_DISK_BY_ID
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
@ -788,12 +779,12 @@ mountroot()
|
||||
# ------------
|
||||
# If we have 'ROOT' (see above), but not 'ZFS_BOOTFS', then use
|
||||
# 'ROOT'
|
||||
[ -n "$ROOT" -a -z "${ZFS_BOOTFS}" ] && ZFS_BOOTFS="$ROOT"
|
||||
[ -n "$ROOT" ] && [ -z "${ZFS_BOOTFS}" ] && ZFS_BOOTFS="$ROOT"
|
||||
|
||||
# ------------
|
||||
# Check for the `-B zfs-bootfs=%s/%u,...` kind of parameter.
|
||||
# NOTE: Only use the pool name and dataset. The rest is not
|
||||
# supported by ZoL (whatever it's for).
|
||||
# supported by OpenZFS (whatever it's for).
|
||||
if [ -z "$ZFS_RPOOL" ]
|
||||
then
|
||||
# The ${zfs-bootfs} variable is set at the kernel command
|
||||
@ -809,11 +800,11 @@ mountroot()
|
||||
|
||||
# ------------
|
||||
# No root fs or pool specified - do auto detect.
|
||||
if [ -z "$ZFS_RPOOL" -a -z "${ZFS_BOOTFS}" ]
|
||||
if [ -z "$ZFS_RPOOL" ] && [ -z "${ZFS_BOOTFS}" ]
|
||||
then
|
||||
# Do auto detect. Do this by 'cheating' - set 'root=zfs:AUTO'
|
||||
# which will be caught later
|
||||
ROOT=zfs:AUTO
|
||||
ROOT='zfs:AUTO'
|
||||
fi
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
@ -858,7 +849,7 @@ mountroot()
|
||||
fi
|
||||
|
||||
# Import the pool (if not already done so in the AUTO check above).
|
||||
if [ -n "$ZFS_RPOOL" -a -z "${POOL_IMPORTED}" ]
|
||||
if [ -n "$ZFS_RPOOL" ] && [ -z "${POOL_IMPORTED}" ]
|
||||
then
|
||||
[ "$quiet" != "y" ] && \
|
||||
zfs_log_begin_msg "Importing ZFS root pool '$ZFS_RPOOL'"
|
||||
@ -971,7 +962,7 @@ mountroot()
|
||||
|
||||
touch /run/zfs_unlock_complete
|
||||
if [ -e /run/zfs_unlock_complete_notify ]; then
|
||||
read zfs_unlock_complete_notify < /run/zfs_unlock_complete_notify
|
||||
read -r zfs_unlock_complete_notify < /run/zfs_unlock_complete_notify
|
||||
fi
|
||||
|
||||
# ------------
|
||||
@ -989,8 +980,8 @@ mountroot()
|
||||
echo
|
||||
|
||||
echo "=> waiting for ENTER before continuing because of 'zfsdebug=1'. "
|
||||
echo -n " 'c' for shell, 'r' for reboot, 'ENTER' to continue. "
|
||||
read b
|
||||
printf "%s" " 'c' for shell, 'r' for reboot, 'ENTER' to continue. "
|
||||
read -r b
|
||||
|
||||
[ "$b" = "c" ] && /bin/sh
|
||||
[ "$b" = "r" ] && reboot -f
|
||||
@ -1000,12 +991,14 @@ mountroot()
|
||||
|
||||
# ------------
|
||||
# Run local bottom script
|
||||
if type run_scripts > /dev/null 2>&1 && \
|
||||
[ -f "/scripts/local-bottom" -o -d "/scripts/local-bottom" ]
|
||||
if command -v run_scripts > /dev/null 2>&1
|
||||
then
|
||||
[ "$quiet" != "y" ] && \
|
||||
zfs_log_begin_msg "Running /scripts/local-bottom"
|
||||
run_scripts /scripts/local-bottom
|
||||
[ "$quiet" != "y" ] && zfs_log_end_msg
|
||||
if [ -f "/scripts/local-bottom" ] || [ -d "/scripts/local-bottom" ]
|
||||
then
|
||||
[ "$quiet" != "y" ] && \
|
||||
zfs_log_begin_msg "Running /scripts/local-bottom"
|
||||
run_scripts /scripts/local-bottom
|
||||
[ "$quiet" != "y" ] && zfs_log_end_msg
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
17
contrib/intel_qat/patch/0001-cryptohash.diff
Normal file
17
contrib/intel_qat/patch/0001-cryptohash.diff
Normal file
@ -0,0 +1,17 @@
|
||||
cryptohash.h was dropped and merged with crypto/sha.sh in 5.8 kernel. Details in:
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=228c4f265c6eb60eaa4ed0edb3bf7c113173576c
|
||||
|
||||
---
|
||||
diff --git a/quickassist/utilities/osal/src/linux/kernel_space/OsalCryptoInterface.c b/quickassist/utilities/osal/src/linux/kernel_space/OsalCryptoInterface.c
|
||||
index 4c389da..e602377 100644
|
||||
--- a/quickassist/utilities/osal/src/linux/kernel_space/OsalCryptoInterface.c
|
||||
+++ b/quickassist/utilities/osal/src/linux/kernel_space/OsalCryptoInterface.c
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
#include "Osal.h"
|
||||
#include <linux/crypto.h>
|
||||
-#include <linux/cryptohash.h>
|
||||
+#include <crypto/sha.h>
|
||||
#include <linux/version.h>
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
|
||||
#include <crypto/internal/hash.h>
|
20
contrib/intel_qat/patch/0001-pci_aer.diff
Normal file
20
contrib/intel_qat/patch/0001-pci_aer.diff
Normal file
@ -0,0 +1,20 @@
|
||||
In kernel 5.7 the pci_cleanup_aer_uncorrect_error_status() function was
|
||||
renamed with the following commit:
|
||||
|
||||
git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=894020fdd88c1e9a74c60b67c0f19f1c7696ba2f
|
||||
|
||||
This simply updates the function call with the proper name (pci_aer_clear_nonfatal_status()).
|
||||
|
||||
---
|
||||
diff --git a/quickassist/qat/drivers/crypto/qat/qat_common/adf_aer.c b/quickassist/qat/drivers/crypto/qat/qat_common/adf_aer.c
|
||||
index a6ce6df..545bb79 100644
|
||||
--- a/quickassist/qat/drivers/crypto/qat/qat_common/adf_aer.c
|
||||
+++ b/quickassist/qat/drivers/crypto/qat/qat_common/adf_aer.c
|
||||
@@ -304,7 +304,7 @@ static pci_ers_result_t adf_slot_reset(struct pci_dev *pdev)
|
||||
pr_err("QAT: Can't find acceleration device\n");
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
}
|
||||
- pci_cleanup_aer_uncorrect_error_status(pdev);
|
||||
+ pci_aer_clear_nonfatal_status(pdev);
|
||||
if (adf_dev_aer_schedule_reset(accel_dev, ADF_DEV_RESET_SYNC))
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
35
contrib/intel_qat/patch/0001-timespec.diff
Normal file
35
contrib/intel_qat/patch/0001-timespec.diff
Normal file
@ -0,0 +1,35 @@
|
||||
This patch attempts to expose timespec and getnstimeofday which were
|
||||
explicitly hidden in the 5.6 kernel with the introduction of the
|
||||
following commits:
|
||||
|
||||
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c766d1472c70d25ad475cf56042af1652e792b23
|
||||
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=412c53a680a97cb1ae2c0ab60230e193bee86387
|
||||
|
||||
Code received from users@dpdk.org, issue tracked under QATE-59888.
|
||||
|
||||
---
|
||||
diff --git a/quickassist/lookaside/access_layer/src/sample_code/performance/framework/linux/kernel_space/cpa_sample_code_utils.c b/quickassist/lookaside/access_layer/src/sample_code/performance/framework/linux/kernel_space/cpa_sample_code_utils.c
|
||||
index 4639834..523e376 100644
|
||||
--- a/quickassist/lookaside/access_layer/src/sample_code/performance/framework/linux/kernel_space/cpa_sample_code_utils.c
|
||||
+++ b/quickassist/lookaside/access_layer/src/sample_code/performance/framework/linux/kernel_space/cpa_sample_code_utils.c
|
||||
@@ -107,6 +107,8 @@ atomic_t arrived;
|
||||
extern struct device perf_device;
|
||||
#endif
|
||||
|
||||
+#define timespec timespec64
|
||||
+#define getnstimeofday ktime_get_real_ts64
|
||||
|
||||
/* Define a number for timeout */
|
||||
#define SAMPLE_CODE_MAX_LONG (0x7FFFFFFF)
|
||||
diff --git a/quickassist/qat/compat/qat_compat.h b/quickassist/qat/compat/qat_compat.h
|
||||
index 2a02eaf..3515092 100644
|
||||
--- a/quickassist/qat/compat/qat_compat.h
|
||||
+++ b/quickassist/qat/compat/qat_compat.h
|
||||
@@ -466,4 +466,7 @@ static inline void pci_ignore_hotplug(struct pci_dev *dev)
|
||||
#if (RHEL_RELEASE_CODE && RHEL_RELEASE_VERSION(7, 3) <= RHEL_RELEASE_CODE)
|
||||
#define QAT_KPT_CAP_DISCOVERY
|
||||
#endif
|
||||
+
|
||||
+#define timespec timespec64
|
||||
+#define getnstimeofday ktime_get_real_ts64
|
||||
#endif /* _QAT_COMPAT_H_ */
|
30
contrib/intel_qat/patch/LICENSE
Normal file
30
contrib/intel_qat/patch/LICENSE
Normal file
@ -0,0 +1,30 @@
|
||||
BSD LICENSE
|
||||
|
||||
Copyright (c) Intel Corporation.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT
|
||||
OWNER 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.
|
27
contrib/intel_qat/readme.md
Normal file
27
contrib/intel_qat/readme.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Intel_QAT easy install script
|
||||
|
||||
This contrib contains community compatibility patches to get Intel QAT working on the following kernel versions:
|
||||
- 5.6
|
||||
- 5.7
|
||||
- 5.8
|
||||
|
||||
These patches are based on the following Intel QAT version:
|
||||
[1.7.l.4.10.0-00014](https://01.org/sites/default/files/downloads/qat1.7.l.4.10.0-00014.tar.gz)
|
||||
|
||||
When using QAT with above kernels versions, the following patches needs to be applied using:
|
||||
patch -p1 < _$PATCH_
|
||||
_Where $PATCH refers to the path of the patch in question_
|
||||
|
||||
### 5.6
|
||||
/patch/0001-timespec.diff
|
||||
|
||||
### 5.7
|
||||
/patch/0001-pci_aer.diff
|
||||
|
||||
### 5.8
|
||||
/patch/0001-cryptohash.diff
|
||||
|
||||
|
||||
_Patches are supplied by [Storage Performance Development Kit (SPDK)](https://github.com/spdk/spdk)_
|
||||
|
||||
|
@ -83,6 +83,14 @@ typedef struct kstat_s kstat_t;
|
||||
typedef int kid_t; /* unique kstat id */
|
||||
typedef int kstat_update_t(struct kstat_s *, int); /* dynamic update cb */
|
||||
|
||||
struct seq_file {
|
||||
char *sf_buf;
|
||||
size_t sf_size;
|
||||
};
|
||||
|
||||
void seq_printf(struct seq_file *m, const char *fmt, ...);
|
||||
|
||||
|
||||
typedef struct kstat_module {
|
||||
char ksm_name[KSTAT_STRLEN+1]; /* module name */
|
||||
struct list_head ksm_module_list; /* module linkage */
|
||||
@ -92,6 +100,7 @@ typedef struct kstat_module {
|
||||
|
||||
typedef struct kstat_raw_ops {
|
||||
int (*headers)(char *buf, size_t size);
|
||||
int (*seq_headers)(struct seq_file *);
|
||||
int (*data)(char *buf, size_t size, void *data);
|
||||
void *(*addr)(kstat_t *ksp, loff_t index);
|
||||
} kstat_raw_ops_t;
|
||||
@ -112,6 +121,7 @@ struct kstat_s {
|
||||
size_t ks_data_size; /* size of kstat data section */
|
||||
kstat_update_t *ks_update; /* dynamic updates */
|
||||
void *ks_private; /* private data */
|
||||
void *ks_private1; /* private data */
|
||||
kmutex_t ks_private_lock; /* kstat private data lock */
|
||||
kmutex_t *ks_lock; /* kstat data lock */
|
||||
struct list_head ks_list; /* kstat linkage */
|
||||
@ -185,6 +195,12 @@ extern void __kstat_set_raw_ops(kstat_t *ksp,
|
||||
int (*data)(char *buf, size_t size, void *data),
|
||||
void* (*addr)(kstat_t *ksp, loff_t index));
|
||||
|
||||
extern void __kstat_set_seq_raw_ops(kstat_t *ksp,
|
||||
int (*headers)(struct seq_file *),
|
||||
int (*data)(char *buf, size_t size, void *data),
|
||||
void* (*addr)(kstat_t *ksp, loff_t index));
|
||||
|
||||
|
||||
extern kstat_t *__kstat_create(const char *ks_module, int ks_instance,
|
||||
const char *ks_name, const char *ks_class, uchar_t ks_type,
|
||||
uint_t ks_ndata, uchar_t ks_flags);
|
||||
@ -196,6 +212,8 @@ extern void kstat_waitq_exit(kstat_io_t *);
|
||||
extern void kstat_runq_enter(kstat_io_t *);
|
||||
extern void kstat_runq_exit(kstat_io_t *);
|
||||
|
||||
#define kstat_set_seq_raw_ops(k, h, d, a) \
|
||||
__kstat_set_seq_raw_ops(k, h, d, a)
|
||||
#define kstat_set_raw_ops(k, h, d, a) \
|
||||
__kstat_set_raw_ops(k, h, d, a)
|
||||
#define kstat_create(m, i, n, c, t, s, f) \
|
||||
|
@ -33,16 +33,18 @@
|
||||
* procfs list manipulation
|
||||
*/
|
||||
|
||||
struct seq_file { };
|
||||
void seq_printf(struct seq_file *m, const char *fmt, ...);
|
||||
|
||||
typedef struct procfs_list {
|
||||
typedef struct procfs_list procfs_list_t;
|
||||
struct procfs_list {
|
||||
void *pl_private;
|
||||
void *pl_next_data;
|
||||
kmutex_t pl_lock;
|
||||
list_t pl_list;
|
||||
uint64_t pl_next_id;
|
||||
int (*pl_show)(struct seq_file *f, void *p);
|
||||
int (*pl_show_header)(struct seq_file *f);
|
||||
int (*pl_clear)(procfs_list_t *procfs_list);
|
||||
size_t pl_node_offset;
|
||||
} procfs_list_t;
|
||||
};
|
||||
|
||||
typedef struct procfs_list_node {
|
||||
list_node_t pln_link;
|
||||
@ -50,6 +52,7 @@ typedef struct procfs_list_node {
|
||||
} procfs_list_node_t;
|
||||
|
||||
void procfs_list_install(const char *module,
|
||||
const char *submodule,
|
||||
const char *name,
|
||||
mode_t mode,
|
||||
procfs_list_t *procfs_list,
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#ifdef __i386__
|
||||
#include <x86/fpu.h>
|
||||
#else
|
||||
@ -42,16 +43,15 @@
|
||||
#define kfpu_allowed() 1
|
||||
#define kfpu_initialize(tsk) do {} while (0)
|
||||
|
||||
#define kfpu_begin() { \
|
||||
critical_enter(); \
|
||||
fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX); \
|
||||
#define kfpu_begin() { \
|
||||
if (__predict_false(!is_fpu_kern_thread(0))) \
|
||||
fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);\
|
||||
}
|
||||
|
||||
#define kfpu_end() \
|
||||
{ \
|
||||
fpu_kern_leave(curthread, NULL); \
|
||||
critical_exit(); \
|
||||
}
|
||||
#define kfpu_end() { \
|
||||
if (__predict_false(curpcb->pcb_flags & PCB_FPUNOSAVE)) \
|
||||
fpu_kern_leave(curthread, NULL); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if OS supports AVX and AVX2 by checking XCR0
|
||||
|
@ -57,6 +57,7 @@ typedef struct procfs_list_node {
|
||||
} procfs_list_node_t;
|
||||
|
||||
void procfs_list_install(const char *module,
|
||||
const char *submodule,
|
||||
const char *name,
|
||||
mode_t mode,
|
||||
procfs_list_t *procfs_list,
|
||||
|
@ -23,7 +23,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__KERNEL__) && defined(HAVE_STACK_FRAME_NON_STANDARD)
|
||||
#if defined(__KERNEL__) && defined(HAVE_KERNEL_OBJTOOL) && \
|
||||
defined(HAVE_STACK_FRAME_NON_STANDARD)
|
||||
#include <linux/frame.h>
|
||||
#else
|
||||
#define STACK_FRAME_NON_STANDARD(func)
|
||||
|
@ -368,11 +368,7 @@ extern int lcompat_hashnum(int64_t);
|
||||
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
|
||||
** CHANGE it if it uses too much C-stack space.
|
||||
*/
|
||||
#ifdef __linux__
|
||||
#define LUAL_BUFFERSIZE 512
|
||||
#else
|
||||
#define LUAL_BUFFERSIZE 1024
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -386,6 +386,7 @@ typedef struct procfs_list_node {
|
||||
} procfs_list_node_t;
|
||||
|
||||
void procfs_list_install(const char *module,
|
||||
const char *submodule,
|
||||
const char *name,
|
||||
mode_t mode,
|
||||
procfs_list_t *procfs_list,
|
||||
|
@ -90,6 +90,7 @@ int zfs_zstd_decompress_level(void *s_start, void *d_start, size_t s_len,
|
||||
size_t d_len, uint8_t *level);
|
||||
int zfs_zstd_decompress(void *s_start, void *d_start, size_t s_len,
|
||||
size_t d_len, int n);
|
||||
void zfs_zstd_cache_reap_now(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -228,21 +228,33 @@ nfs_copy_entries(char *filename, const char *mountpoint)
|
||||
int error = SA_OK;
|
||||
char *line;
|
||||
|
||||
/*
|
||||
* If the file doesn't exist then there is nothing more
|
||||
* we need to do.
|
||||
*/
|
||||
FILE *oldfp = fopen(ZFS_EXPORTS_FILE, "r");
|
||||
if (oldfp == NULL)
|
||||
return (SA_OK);
|
||||
|
||||
FILE *newfp = fopen(filename, "w+");
|
||||
fputs(FILE_HEADER, newfp);
|
||||
while ((line = zgetline(oldfp, mountpoint)) != NULL)
|
||||
fprintf(newfp, "%s\n", line);
|
||||
if (ferror(oldfp) != 0) {
|
||||
error = ferror(oldfp);
|
||||
if (newfp == NULL) {
|
||||
fprintf(stderr, "failed to open %s file: %s", filename,
|
||||
strerror(errno));
|
||||
fclose(oldfp);
|
||||
return (SA_SYSTEM_ERR);
|
||||
}
|
||||
fputs(FILE_HEADER, newfp);
|
||||
|
||||
/*
|
||||
* The ZFS_EXPORTS_FILE may not exist yet. If that's the
|
||||
* case then just write out the new file.
|
||||
*/
|
||||
if (oldfp != NULL) {
|
||||
while ((line = zgetline(oldfp, mountpoint)) != NULL)
|
||||
fprintf(newfp, "%s\n", line);
|
||||
if (ferror(oldfp) != 0) {
|
||||
error = ferror(oldfp);
|
||||
}
|
||||
if (fclose(oldfp) != 0) {
|
||||
fprintf(stderr, "Unable to close file %s: %s\n",
|
||||
filename, strerror(errno));
|
||||
error = error != 0 ? error : SA_SYSTEM_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (error == 0 && ferror(newfp) != 0) {
|
||||
error = ferror(newfp);
|
||||
}
|
||||
@ -252,8 +264,6 @@ nfs_copy_entries(char *filename, const char *mountpoint)
|
||||
filename, strerror(errno));
|
||||
error = error != 0 ? error : SA_SYSTEM_ERR;
|
||||
}
|
||||
fclose(oldfp);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -393,6 +393,14 @@ static char *
|
||||
nfs_init_tmpfile(void)
|
||||
{
|
||||
char *tmpfile = NULL;
|
||||
struct stat sb;
|
||||
|
||||
if (stat(ZFS_EXPORTS_DIR, &sb) < 0 &&
|
||||
mkdir(ZFS_EXPORTS_DIR, 0755) < 0) {
|
||||
fprintf(stderr, "failed to create %s: %s\n",
|
||||
ZFS_EXPORTS_DIR, strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (asprintf(&tmpfile, "%s%s", ZFS_EXPORTS_FILE, ".XXXXXXXX") == -1) {
|
||||
fprintf(stderr, "Unable to allocate temporary file\n");
|
||||
@ -481,36 +489,49 @@ nfs_copy_entries(char *filename, const char *mountpoint)
|
||||
size_t buflen = 0;
|
||||
int error = SA_OK;
|
||||
|
||||
/*
|
||||
* If the file doesn't exist then there is nothing more
|
||||
* we need to do.
|
||||
*/
|
||||
FILE *oldfp = fopen(ZFS_EXPORTS_FILE, "r");
|
||||
if (oldfp == NULL)
|
||||
return (SA_OK);
|
||||
|
||||
FILE *newfp = fopen(filename, "w+");
|
||||
if (newfp == NULL) {
|
||||
fprintf(stderr, "failed to open %s file: %s", filename,
|
||||
strerror(errno));
|
||||
fclose(oldfp);
|
||||
return (SA_SYSTEM_ERR);
|
||||
}
|
||||
fputs(FILE_HEADER, newfp);
|
||||
while ((getline(&buf, &buflen, oldfp)) != -1) {
|
||||
char *space = NULL;
|
||||
|
||||
if (buf[0] == '\n' || buf[0] == '#')
|
||||
continue;
|
||||
/*
|
||||
* The ZFS_EXPORTS_FILE may not exist yet. If that's the
|
||||
* case then just write out the new file.
|
||||
*/
|
||||
if (oldfp != NULL) {
|
||||
while (getline(&buf, &buflen, oldfp) != -1) {
|
||||
char *space = NULL;
|
||||
|
||||
if ((space = strchr(buf, ' ')) != NULL) {
|
||||
int mountpoint_len = strlen(mountpoint);
|
||||
|
||||
if (space - buf == mountpoint_len &&
|
||||
strncmp(mountpoint, buf, mountpoint_len) == 0) {
|
||||
if (buf[0] == '\n' || buf[0] == '#')
|
||||
continue;
|
||||
|
||||
if ((space = strchr(buf, ' ')) != NULL) {
|
||||
int mountpoint_len = strlen(mountpoint);
|
||||
|
||||
if (space - buf == mountpoint_len &&
|
||||
strncmp(mountpoint, buf,
|
||||
mountpoint_len) == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fputs(buf, newfp);
|
||||
}
|
||||
|
||||
if (ferror(oldfp) != 0) {
|
||||
error = ferror(oldfp);
|
||||
}
|
||||
if (fclose(oldfp) != 0) {
|
||||
fprintf(stderr, "Unable to close file %s: %s\n",
|
||||
filename, strerror(errno));
|
||||
error = error != 0 ? error : SA_SYSTEM_ERR;
|
||||
}
|
||||
fputs(buf, newfp);
|
||||
}
|
||||
|
||||
if (oldfp != NULL && ferror(oldfp) != 0) {
|
||||
error = ferror(oldfp);
|
||||
}
|
||||
if (error == 0 && ferror(newfp) != 0) {
|
||||
error = ferror(newfp);
|
||||
}
|
||||
@ -521,8 +542,6 @@ nfs_copy_entries(char *filename, const char *mountpoint)
|
||||
filename, strerror(errno));
|
||||
error = error != 0 ? error : SA_SYSTEM_ERR;
|
||||
}
|
||||
fclose(oldfp);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -701,13 +720,5 @@ static const sa_share_ops_t nfs_shareops = {
|
||||
void
|
||||
libshare_nfs_init(void)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
nfs_fstype = register_fstype("nfs", &nfs_shareops);
|
||||
|
||||
if (stat(ZFS_EXPORTS_DIR, &sb) < 0 &&
|
||||
mkdir(ZFS_EXPORTS_DIR, 0755) < 0) {
|
||||
fprintf(stderr, "failed to create %s: %s\n",
|
||||
ZFS_EXPORTS_DIR, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
@ -444,6 +444,7 @@ seq_printf(struct seq_file *m, const char *fmt, ...)
|
||||
|
||||
void
|
||||
procfs_list_install(const char *module,
|
||||
const char *submodule,
|
||||
const char *name,
|
||||
mode_t mode,
|
||||
procfs_list_t *procfs_list,
|
||||
|
@ -44,7 +44,7 @@
|
||||
.Oo Fl s Ar field Oc Ns ...
|
||||
.Oo Fl S Ar field Oc Ns ...
|
||||
.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc
|
||||
.Ar filesystem Ns | Ns Ar snapshot
|
||||
.Ar filesystem Ns | Ns Ar snapshot Ns | Ns Ar path
|
||||
.Nm
|
||||
.Cm groupspace
|
||||
.Op Fl Hinp
|
||||
@ -52,14 +52,14 @@
|
||||
.Oo Fl s Ar field Oc Ns ...
|
||||
.Oo Fl S Ar field Oc Ns ...
|
||||
.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc
|
||||
.Ar filesystem Ns | Ns Ar snapshot
|
||||
.Ar filesystem Ns | Ns Ar snapshot Ns | Ns Ar path
|
||||
.Nm
|
||||
.Cm projectspace
|
||||
.Op Fl Hp
|
||||
.Oo Fl o Ar field Ns Oo , Ns Ar field Oc Ns ... Oc
|
||||
.Oo Fl s Ar field Oc Ns ...
|
||||
.Oo Fl S Ar field Oc Ns ...
|
||||
.Ar filesystem Ns | Ns Ar snapshot
|
||||
.Ar filesystem Ns | Ns Ar snapshot Ns | Ns Ar path
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -width ""
|
||||
.It Xo
|
||||
@ -70,10 +70,11 @@
|
||||
.Oo Fl s Ar field Oc Ns ...
|
||||
.Oo Fl S Ar field Oc Ns ...
|
||||
.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc
|
||||
.Ar filesystem Ns | Ns Ar snapshot
|
||||
.Ar filesystem Ns | Ns Ar snapshot Ns | Ns Ar path
|
||||
.Xc
|
||||
Displays space consumed by, and quotas on, each user in the specified filesystem
|
||||
or snapshot.
|
||||
Displays space consumed by, and quotas on, each user in the specified filesystem,
|
||||
snapshot, or path.
|
||||
If a path is given, the filesystem that contains that path will be used.
|
||||
This corresponds to the
|
||||
.Sy userused@ Ns Em user ,
|
||||
.Sy userobjused@ Ns Em user ,
|
||||
@ -167,7 +168,7 @@ except that the default types to display are
|
||||
.Oo Fl o Ar field Ns Oo , Ns Ar field Oc Ns ... Oc
|
||||
.Oo Fl s Ar field Oc Ns ...
|
||||
.Oo Fl S Ar field Oc Ns ...
|
||||
.Ar filesystem Ns | Ns Ar snapshot
|
||||
.Ar filesystem Ns | Ns Ar snapshot Ns | Ns Ar path
|
||||
.Xc
|
||||
Displays space consumed by, and quotas on, each project in the specified
|
||||
filesystem or snapshot. This subcommand is identical to
|
||||
|
@ -55,6 +55,8 @@ This command supports removing hot spare, cache, log, and both mirrored and
|
||||
non-redundant primary top-level vdevs, including dedup and special vdevs.
|
||||
When the primary pool storage includes a top-level raidz vdev only hot spare,
|
||||
cache, and log devices can be removed.
|
||||
Note that keys for all encrypted datasets must be loaded for top-level vdevs
|
||||
to be removed.
|
||||
.sp
|
||||
Removing a top-level vdev reduces the total amount of space in the storage pool.
|
||||
The specified device will be evacuated by copying all allocated space from it to
|
||||
|
@ -126,16 +126,7 @@ typedef LUAI_UACNUMBER l_uacNumber;
|
||||
* Minimum amount of available stack space (in bytes) to make a C call. With
|
||||
* gsub() recursion, the stack space between each luaD_call() is 1256 bytes.
|
||||
*/
|
||||
#if defined(__FreeBSD__)
|
||||
/*
|
||||
* FreeBSD needs a few extra bytes in unoptimized debug builds to avoid a
|
||||
* double-fault handling the error when the max call depth is exceeded just
|
||||
* before the C stack runs out. 64 bytes seems to do the trick.
|
||||
*/
|
||||
#define LUAI_MINCSTACK 4160
|
||||
#else
|
||||
#define LUAI_MINCSTACK 4096
|
||||
#endif
|
||||
|
||||
/*
|
||||
** maximum number of upvalues in a closure (both C and Lua). (Value
|
||||
|
@ -55,6 +55,17 @@ __kstat_set_raw_ops(kstat_t *ksp,
|
||||
ksp->ks_raw_ops.addr = addr;
|
||||
}
|
||||
|
||||
void
|
||||
__kstat_set_seq_raw_ops(kstat_t *ksp,
|
||||
int (*headers)(struct seq_file *f),
|
||||
int (*data)(char *buf, size_t size, void *data),
|
||||
void *(*addr)(kstat_t *ksp, loff_t index))
|
||||
{
|
||||
ksp->ks_raw_ops.seq_headers = headers;
|
||||
ksp->ks_raw_ops.data = data;
|
||||
ksp->ks_raw_ops.addr = addr;
|
||||
}
|
||||
|
||||
static int
|
||||
kstat_default_update(kstat_t *ksp, int rw)
|
||||
{
|
||||
@ -160,7 +171,7 @@ kstat_sysctl_raw(SYSCTL_HANDLER_ARGS)
|
||||
void *data;
|
||||
kstat_t *ksp = arg1;
|
||||
void *(*addr_op)(kstat_t *ksp, loff_t index);
|
||||
int n, rc = 0;
|
||||
int n, has_header, rc = 0;
|
||||
|
||||
sb = sbuf_new_auto();
|
||||
if (sb == NULL)
|
||||
@ -180,14 +191,25 @@ kstat_sysctl_raw(SYSCTL_HANDLER_ARGS)
|
||||
ksp->ks_raw_buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
|
||||
|
||||
n = 0;
|
||||
has_header = (ksp->ks_raw_ops.headers ||
|
||||
ksp->ks_raw_ops.seq_headers);
|
||||
|
||||
restart_headers:
|
||||
if (ksp->ks_raw_ops.headers) {
|
||||
rc = ksp->ks_raw_ops.headers(
|
||||
ksp->ks_raw_buf, ksp->ks_raw_bufsize);
|
||||
} else if (ksp->ks_raw_ops.seq_headers) {
|
||||
struct seq_file f;
|
||||
|
||||
f.sf_buf = ksp->ks_raw_buf;
|
||||
f.sf_size = ksp->ks_raw_bufsize;
|
||||
rc = ksp->ks_raw_ops.seq_headers(&f);
|
||||
}
|
||||
if (has_header) {
|
||||
if (rc == ENOMEM && !kstat_resize_raw(ksp))
|
||||
goto restart_headers;
|
||||
if (rc == 0)
|
||||
sbuf_printf(sb, "%s", ksp->ks_raw_buf);
|
||||
sbuf_printf(sb, "\n%s", ksp->ks_raw_buf);
|
||||
}
|
||||
|
||||
while ((data = addr_op(ksp, n)) != NULL) {
|
||||
@ -220,16 +242,21 @@ kstat_t *
|
||||
__kstat_create(const char *module, int instance, const char *name,
|
||||
const char *class, uchar_t ks_type, uint_t ks_ndata, uchar_t flags)
|
||||
{
|
||||
char buf[KSTAT_STRLEN];
|
||||
struct sysctl_oid *root;
|
||||
kstat_t *ksp;
|
||||
char *pool;
|
||||
|
||||
KASSERT(instance == 0, ("instance=%d", instance));
|
||||
if ((ks_type == KSTAT_TYPE_INTR) || (ks_type == KSTAT_TYPE_IO))
|
||||
ASSERT(ks_ndata == 1);
|
||||
|
||||
if (class == NULL)
|
||||
class = "misc";
|
||||
|
||||
/*
|
||||
* Allocate the main structure. We don't need to copy module/class/name
|
||||
* stuff in here, because it is only used for sysctl node creation
|
||||
* Allocate the main structure. We don't need to keep a copy of
|
||||
* module in here, because it is only used for sysctl node creation
|
||||
* done in this function.
|
||||
*/
|
||||
ksp = malloc(sizeof (*ksp), M_KSTAT, M_WAITOK|M_ZERO);
|
||||
@ -237,8 +264,8 @@ __kstat_create(const char *module, int instance, const char *name,
|
||||
ksp->ks_crtime = gethrtime();
|
||||
ksp->ks_snaptime = ksp->ks_crtime;
|
||||
ksp->ks_instance = instance;
|
||||
strncpy(ksp->ks_name, name, KSTAT_STRLEN);
|
||||
strncpy(ksp->ks_class, class, KSTAT_STRLEN);
|
||||
(void) strlcpy(ksp->ks_name, name, KSTAT_STRLEN);
|
||||
(void) strlcpy(ksp->ks_class, class, KSTAT_STRLEN);
|
||||
ksp->ks_type = ks_type;
|
||||
ksp->ks_flags = flags;
|
||||
ksp->ks_update = kstat_default_update;
|
||||
@ -247,28 +274,28 @@ __kstat_create(const char *module, int instance, const char *name,
|
||||
ksp->ks_lock = &ksp->ks_private_lock;
|
||||
|
||||
switch (ksp->ks_type) {
|
||||
case KSTAT_TYPE_RAW:
|
||||
ksp->ks_ndata = 1;
|
||||
ksp->ks_data_size = ks_ndata;
|
||||
break;
|
||||
case KSTAT_TYPE_NAMED:
|
||||
ksp->ks_ndata = ks_ndata;
|
||||
ksp->ks_data_size = ks_ndata * sizeof (kstat_named_t);
|
||||
break;
|
||||
case KSTAT_TYPE_INTR:
|
||||
ksp->ks_ndata = ks_ndata;
|
||||
ksp->ks_data_size = ks_ndata * sizeof (kstat_intr_t);
|
||||
break;
|
||||
case KSTAT_TYPE_IO:
|
||||
ksp->ks_ndata = ks_ndata;
|
||||
ksp->ks_data_size = ks_ndata * sizeof (kstat_io_t);
|
||||
break;
|
||||
case KSTAT_TYPE_TIMER:
|
||||
ksp->ks_ndata = ks_ndata;
|
||||
ksp->ks_data_size = ks_ndata * sizeof (kstat_timer_t);
|
||||
break;
|
||||
default:
|
||||
panic("Undefined kstat type %d\n", ksp->ks_type);
|
||||
case KSTAT_TYPE_RAW:
|
||||
ksp->ks_ndata = 1;
|
||||
ksp->ks_data_size = ks_ndata;
|
||||
break;
|
||||
case KSTAT_TYPE_NAMED:
|
||||
ksp->ks_ndata = ks_ndata;
|
||||
ksp->ks_data_size = ks_ndata * sizeof (kstat_named_t);
|
||||
break;
|
||||
case KSTAT_TYPE_INTR:
|
||||
ksp->ks_ndata = ks_ndata;
|
||||
ksp->ks_data_size = ks_ndata * sizeof (kstat_intr_t);
|
||||
break;
|
||||
case KSTAT_TYPE_IO:
|
||||
ksp->ks_ndata = ks_ndata;
|
||||
ksp->ks_data_size = ks_ndata * sizeof (kstat_io_t);
|
||||
break;
|
||||
case KSTAT_TYPE_TIMER:
|
||||
ksp->ks_ndata = ks_ndata;
|
||||
ksp->ks_data_size = ks_ndata * sizeof (kstat_timer_t);
|
||||
break;
|
||||
default:
|
||||
panic("Undefined kstat type %d\n", ksp->ks_type);
|
||||
}
|
||||
|
||||
if (ksp->ks_flags & KSTAT_FLAG_VIRTUAL) {
|
||||
@ -280,10 +307,22 @@ __kstat_create(const char *module, int instance, const char *name,
|
||||
ksp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Some kstats use a module name like "zfs/poolname" to distinguish a
|
||||
* set of kstats belonging to a specific pool. Split on '/' to add an
|
||||
* extra node for the pool name if needed.
|
||||
*/
|
||||
(void) strlcpy(buf, module, KSTAT_STRLEN);
|
||||
module = buf;
|
||||
pool = strchr(module, '/');
|
||||
if (pool != NULL)
|
||||
*pool++ = '\0';
|
||||
|
||||
/*
|
||||
* Create sysctl tree for those statistics:
|
||||
*
|
||||
* kstat.<module>.<class>.<name>.
|
||||
* kstat.<module>[.<pool>].<class>.<name>
|
||||
*/
|
||||
sysctl_ctx_init(&ksp->ks_sysctl_ctx);
|
||||
root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx,
|
||||
@ -295,11 +334,26 @@ __kstat_create(const char *module, int instance, const char *name,
|
||||
free(ksp, M_KSTAT);
|
||||
return (NULL);
|
||||
}
|
||||
if (pool != NULL) {
|
||||
root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(root), OID_AUTO, pool, CTLFLAG_RW, 0, "");
|
||||
if (root == NULL) {
|
||||
printf("%s: Cannot create kstat.%s.%s tree!\n",
|
||||
__func__, module, pool);
|
||||
sysctl_ctx_free(&ksp->ks_sysctl_ctx);
|
||||
free(ksp, M_KSTAT);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx, SYSCTL_CHILDREN(root),
|
||||
OID_AUTO, class, CTLFLAG_RW, 0, "");
|
||||
if (root == NULL) {
|
||||
printf("%s: Cannot create kstat.%s.%s tree!\n", __func__,
|
||||
module, class);
|
||||
if (pool != NULL)
|
||||
printf("%s: Cannot create kstat.%s.%s.%s tree!\n",
|
||||
__func__, module, pool, class);
|
||||
else
|
||||
printf("%s: Cannot create kstat.%s.%s tree!\n",
|
||||
__func__, module, class);
|
||||
sysctl_ctx_free(&ksp->ks_sysctl_ctx);
|
||||
free(ksp, M_KSTAT);
|
||||
return (NULL);
|
||||
@ -309,8 +363,13 @@ __kstat_create(const char *module, int instance, const char *name,
|
||||
SYSCTL_CHILDREN(root),
|
||||
OID_AUTO, name, CTLFLAG_RW, 0, "");
|
||||
if (root == NULL) {
|
||||
printf("%s: Cannot create kstat.%s.%s.%s tree!\n",
|
||||
__func__, module, class, name);
|
||||
if (pool != NULL)
|
||||
printf("%s: Cannot create kstat.%s.%s.%s.%s "
|
||||
"tree!\n", __func__, module, pool, class,
|
||||
name);
|
||||
else
|
||||
printf("%s: Cannot create kstat.%s.%s.%s "
|
||||
"tree!\n", __func__, module, class, name);
|
||||
sysctl_ctx_free(&ksp->ks_sysctl_ctx);
|
||||
free(ksp, M_KSTAT);
|
||||
return (NULL);
|
||||
@ -342,64 +401,62 @@ kstat_install_named(kstat_t *ksp)
|
||||
namelast = ksent->name;
|
||||
}
|
||||
switch (typelast) {
|
||||
case KSTAT_DATA_CHAR:
|
||||
/* Not Implemented */
|
||||
break;
|
||||
case KSTAT_DATA_INT32:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_S32 | CTLFLAG_RD, ksp, i,
|
||||
kstat_sysctl, "I", namelast);
|
||||
break;
|
||||
case KSTAT_DATA_UINT32:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_U32 | CTLFLAG_RD, ksp, i,
|
||||
kstat_sysctl, "IU", namelast);
|
||||
break;
|
||||
case KSTAT_DATA_INT64:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_S64 | CTLFLAG_RD, ksp, i,
|
||||
kstat_sysctl, "Q", namelast);
|
||||
break;
|
||||
case KSTAT_DATA_UINT64:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_U64 | CTLFLAG_RD, ksp, i,
|
||||
kstat_sysctl, "QU", namelast);
|
||||
break;
|
||||
case KSTAT_DATA_LONG:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_LONG | CTLFLAG_RD, ksp, i,
|
||||
kstat_sysctl, "L", namelast);
|
||||
break;
|
||||
case KSTAT_DATA_ULONG:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_ULONG | CTLFLAG_RD, ksp, i,
|
||||
kstat_sysctl, "LU", namelast);
|
||||
break;
|
||||
case KSTAT_DATA_STRING:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_STRING | CTLFLAG_RD, ksp, i,
|
||||
kstat_sysctl_string, "A", namelast);
|
||||
break;
|
||||
default:
|
||||
panic("unsupported type: %d", typelast);
|
||||
case KSTAT_DATA_CHAR:
|
||||
/* Not Implemented */
|
||||
break;
|
||||
case KSTAT_DATA_INT32:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_S32 | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
ksp, i, kstat_sysctl, "I", namelast);
|
||||
break;
|
||||
case KSTAT_DATA_UINT32:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_U32 | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
ksp, i, kstat_sysctl, "IU", namelast);
|
||||
break;
|
||||
case KSTAT_DATA_INT64:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_S64 | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
ksp, i, kstat_sysctl, "Q", namelast);
|
||||
break;
|
||||
case KSTAT_DATA_UINT64:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
ksp, i, kstat_sysctl, "QU", namelast);
|
||||
break;
|
||||
case KSTAT_DATA_LONG:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_LONG | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
ksp, i, kstat_sysctl, "L", namelast);
|
||||
break;
|
||||
case KSTAT_DATA_ULONG:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_ULONG | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
ksp, i, kstat_sysctl, "LU", namelast);
|
||||
break;
|
||||
case KSTAT_DATA_STRING:
|
||||
SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, namelast,
|
||||
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
ksp, i, kstat_sysctl_string, "A", namelast);
|
||||
break;
|
||||
default:
|
||||
panic("unsupported type: %d", typelast);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -411,39 +468,37 @@ kstat_install(kstat_t *ksp)
|
||||
VERIFY(ksp->ks_type == KSTAT_TYPE_RAW);
|
||||
|
||||
switch (ksp->ks_type) {
|
||||
case KSTAT_TYPE_NAMED:
|
||||
return (kstat_install_named(ksp));
|
||||
break;
|
||||
case KSTAT_TYPE_RAW:
|
||||
if (ksp->ks_raw_ops.data) {
|
||||
root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, ksp->ks_name,
|
||||
CTLTYPE_STRING | CTLFLAG_RD, ksp, 0,
|
||||
kstat_sysctl_raw, "A", ksp->ks_name);
|
||||
} else {
|
||||
root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, ksp->ks_name,
|
||||
CTLTYPE_OPAQUE | CTLFLAG_RD, ksp, 0,
|
||||
kstat_sysctl_raw, "", ksp->ks_name);
|
||||
}
|
||||
VERIFY(root != NULL);
|
||||
break;
|
||||
case KSTAT_TYPE_IO:
|
||||
case KSTAT_TYPE_NAMED:
|
||||
return (kstat_install_named(ksp));
|
||||
case KSTAT_TYPE_RAW:
|
||||
if (ksp->ks_raw_ops.data) {
|
||||
root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, ksp->ks_name,
|
||||
CTLTYPE_STRING | CTLFLAG_RD, ksp, 0,
|
||||
kstat_sysctl_io, "A", ksp->ks_name);
|
||||
break;
|
||||
case KSTAT_TYPE_TIMER:
|
||||
case KSTAT_TYPE_INTR:
|
||||
default:
|
||||
panic("unsupported kstat type %d\n", ksp->ks_type);
|
||||
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
ksp, 0, kstat_sysctl_raw, "A", ksp->ks_name);
|
||||
} else {
|
||||
root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, ksp->ks_name,
|
||||
CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
ksp, 0, kstat_sysctl_raw, "", ksp->ks_name);
|
||||
}
|
||||
break;
|
||||
case KSTAT_TYPE_IO:
|
||||
root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, ksp->ks_name,
|
||||
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
ksp, 0, kstat_sysctl_io, "A", ksp->ks_name);
|
||||
break;
|
||||
case KSTAT_TYPE_TIMER:
|
||||
case KSTAT_TYPE_INTR:
|
||||
default:
|
||||
panic("unsupported kstat type %d\n", ksp->ks_type);
|
||||
}
|
||||
VERIFY(root != NULL);
|
||||
ksp->ks_sysctl_root = root;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -32,12 +32,74 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/procfs_list.h>
|
||||
|
||||
typedef struct procfs_list_iter {
|
||||
procfs_list_t *pli_pl;
|
||||
void *pli_elt;
|
||||
} pli_t;
|
||||
|
||||
void
|
||||
seq_printf(struct seq_file *m, const char *fmt, ...)
|
||||
{}
|
||||
seq_printf(struct seq_file *f, const char *fmt, ...)
|
||||
{
|
||||
va_list adx;
|
||||
|
||||
va_start(adx, fmt);
|
||||
(void) vsnprintf(f->sf_buf, f->sf_size, fmt, adx);
|
||||
va_end(adx);
|
||||
}
|
||||
|
||||
static int
|
||||
procfs_list_update(kstat_t *ksp, int rw)
|
||||
{
|
||||
procfs_list_t *pl = ksp->ks_private;
|
||||
|
||||
if (rw == KSTAT_WRITE)
|
||||
pl->pl_clear(pl);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
procfs_list_data(char *buf, size_t size, void *data)
|
||||
{
|
||||
pli_t *p;
|
||||
void *elt;
|
||||
procfs_list_t *pl;
|
||||
struct seq_file f;
|
||||
|
||||
p = data;
|
||||
pl = p->pli_pl;
|
||||
elt = p->pli_elt;
|
||||
free(p, M_TEMP);
|
||||
f.sf_buf = buf;
|
||||
f.sf_size = size;
|
||||
return (pl->pl_show(&f, elt));
|
||||
}
|
||||
|
||||
static void *
|
||||
procfs_list_addr(kstat_t *ksp, loff_t n)
|
||||
{
|
||||
procfs_list_t *pl = ksp->ks_private;
|
||||
void *elt = ksp->ks_private1;
|
||||
pli_t *p = NULL;
|
||||
|
||||
|
||||
if (n == 0)
|
||||
ksp->ks_private1 = list_head(&pl->pl_list);
|
||||
else if (elt)
|
||||
ksp->ks_private1 = list_next(&pl->pl_list, elt);
|
||||
|
||||
if (ksp->ks_private1) {
|
||||
p = malloc(sizeof (*p), M_TEMP, M_WAITOK);
|
||||
p->pli_pl = pl;
|
||||
p->pli_elt = ksp->ks_private1;
|
||||
}
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
void
|
||||
procfs_list_install(const char *module,
|
||||
const char *submodule,
|
||||
const char *name,
|
||||
mode_t mode,
|
||||
procfs_list_t *procfs_list,
|
||||
@ -46,12 +108,31 @@ procfs_list_install(const char *module,
|
||||
int (*clear)(procfs_list_t *procfs_list),
|
||||
size_t procfs_list_node_off)
|
||||
{
|
||||
kstat_t *procfs_kstat;
|
||||
|
||||
mutex_init(&procfs_list->pl_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
list_create(&procfs_list->pl_list,
|
||||
procfs_list_node_off + sizeof (procfs_list_node_t),
|
||||
procfs_list_node_off + offsetof(procfs_list_node_t, pln_link));
|
||||
procfs_list->pl_show = show;
|
||||
procfs_list->pl_show_header = show_header;
|
||||
procfs_list->pl_clear = clear;
|
||||
procfs_list->pl_next_id = 1;
|
||||
procfs_list->pl_node_offset = procfs_list_node_off;
|
||||
|
||||
procfs_kstat = kstat_create(module, 0, name, submodule,
|
||||
KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);
|
||||
|
||||
if (procfs_kstat) {
|
||||
procfs_kstat->ks_lock = &procfs_list->pl_lock;
|
||||
procfs_kstat->ks_ndata = UINT32_MAX;
|
||||
procfs_kstat->ks_private = procfs_list;
|
||||
procfs_kstat->ks_update = procfs_list_update;
|
||||
kstat_set_seq_raw_ops(procfs_kstat, show_header,
|
||||
procfs_list_data, procfs_list_addr);
|
||||
kstat_install(procfs_kstat);
|
||||
procfs_list->pl_private = procfs_kstat;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -62,6 +143,7 @@ void
|
||||
procfs_list_destroy(procfs_list_t *procfs_list)
|
||||
{
|
||||
ASSERT(list_is_empty(&procfs_list->pl_list));
|
||||
kstat_delete(procfs_list->pl_private);
|
||||
list_destroy(&procfs_list->pl_list);
|
||||
mutex_destroy(&procfs_list->pl_lock);
|
||||
}
|
||||
|
@ -169,6 +169,10 @@ taskq_tsd_set(void *context)
|
||||
{
|
||||
taskq_t *tq = context;
|
||||
|
||||
#if defined(__amd64__) || defined(__i386__) || defined(__aarch64__)
|
||||
if (context != NULL && tsd_get(taskq_tsd) == NULL)
|
||||
fpu_kern_thread(FPU_KERN_NORMAL);
|
||||
#endif
|
||||
tsd_set(taskq_tsd, tq);
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/zio_checksum.h>
|
||||
#include <sys/vdev_removal.h>
|
||||
#include <sys/dsl_crypt.h>
|
||||
#include <sys/zfs_context.h>
|
||||
|
||||
#include <sys/zfs_ioctl_compat.h>
|
||||
#include <sys/zfs_ioctl_impl.h>
|
||||
@ -98,7 +99,7 @@ __FBSDID("$FreeBSD$");
|
||||
SYSCTL_DECL(_vfs_zfs);
|
||||
SYSCTL_DECL(_vfs_zfs_vdev);
|
||||
|
||||
|
||||
extern uint_t rrw_tsd_key;
|
||||
static int zfs_version_ioctl = ZFS_IOCVER_OZFS;
|
||||
SYSCTL_DECL(_vfs_zfs_version);
|
||||
SYSCTL_INT(_vfs_zfs_version, OID_AUTO, ioctl, CTLFLAG_RD, &zfs_version_ioctl,
|
||||
@ -180,6 +181,7 @@ zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag,
|
||||
if (zcl)
|
||||
kmem_free(zcl, sizeof (zfs_cmd_legacy_t));
|
||||
kmem_free(zc, sizeof (zfs_cmd_t));
|
||||
MPASS(tsd_get(rrw_tsd_key) == NULL);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -243,8 +243,9 @@ sysctl_vfs_zfs_arc_no_grow_shift(SYSCTL_HANDLER_ARGS)
|
||||
return (0);
|
||||
}
|
||||
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_no_grow_shift, CTLTYPE_U32 | CTLFLAG_RWTUN,
|
||||
0, sizeof (uint32_t), sysctl_vfs_zfs_arc_no_grow_shift, "U",
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_no_grow_shift,
|
||||
CTLTYPE_U32 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 0, sizeof (uint32_t),
|
||||
sysctl_vfs_zfs_arc_no_grow_shift, "U",
|
||||
"log2(fraction of ARC which must be free to allow growing)");
|
||||
|
||||
int
|
||||
@ -275,10 +276,12 @@ param_set_arc_int(SYSCTL_HANDLER_ARGS)
|
||||
return (0);
|
||||
}
|
||||
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_min, CTLTYPE_ULONG | CTLFLAG_RWTUN,
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_min,
|
||||
CTLTYPE_ULONG | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&zfs_arc_min, sizeof (zfs_arc_min), param_set_arc_long, "LU",
|
||||
"min arc size (LEGACY)");
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_max, CTLTYPE_ULONG | CTLFLAG_RWTUN,
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_max,
|
||||
CTLTYPE_ULONG | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&zfs_arc_max, sizeof (zfs_arc_max), param_set_arc_long, "LU",
|
||||
"max arc size (LEGACY)");
|
||||
|
||||
@ -558,11 +561,13 @@ param_set_max_auto_ashift(SYSCTL_HANDLER_ARGS)
|
||||
return (0);
|
||||
}
|
||||
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, min_auto_ashift, CTLTYPE_U64 | CTLFLAG_RWTUN,
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, min_auto_ashift,
|
||||
CTLTYPE_U64 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&zfs_vdev_min_auto_ashift, sizeof (zfs_vdev_min_auto_ashift),
|
||||
param_set_min_auto_ashift, "QU",
|
||||
"Min ashift used when creating new top-level vdev. (LEGACY)");
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, max_auto_ashift, CTLTYPE_U64 | CTLFLAG_RWTUN,
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, max_auto_ashift,
|
||||
CTLTYPE_U64 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
|
||||
&zfs_vdev_max_auto_ashift, sizeof (zfs_vdev_max_auto_ashift),
|
||||
param_set_max_auto_ashift, "QU",
|
||||
"Max ashift used when optimizing for logical -> physical sector size on "
|
||||
|
@ -322,8 +322,10 @@ zfs_ioctl_ozfs_to_legacy(int request)
|
||||
if (request > ZFS_IOC_LAST)
|
||||
return (-1);
|
||||
|
||||
if (request > ZFS_IOC_PLATFORM)
|
||||
if (request > ZFS_IOC_PLATFORM) {
|
||||
request -= ZFS_IOC_PLATFORM + 1;
|
||||
return (zfs_ioctl_ozfs_to_legacy_platform_[request]);
|
||||
}
|
||||
if (request >= sizeof (zfs_ioctl_ozfs_to_legacy_common_)/sizeof (long))
|
||||
return (-1);
|
||||
return (zfs_ioctl_ozfs_to_legacy_common_[request]);
|
||||
|
@ -1532,7 +1532,11 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
|
||||
* 'z_parent' is self referential for non-snapshots.
|
||||
*/
|
||||
#ifdef FREEBSD_NAMECACHE
|
||||
#if __FreeBSD_version >= 1300117
|
||||
cache_purgevfs(zfsvfs->z_parent->z_vfs);
|
||||
#else
|
||||
cache_purgevfs(zfsvfs->z_parent->z_vfs, true);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1234,8 +1234,7 @@ zio_crypt_do_indirect_mac_checksum_abd(boolean_t generate, abd_t *abd,
|
||||
* accommodate some of the drivers, the authbuf needs to be logically before
|
||||
* the data. This means that we need to copy the source to the destination,
|
||||
* and set up an extra iovec_t at the beginning to handle the authbuf.
|
||||
* It also means we'll only return one uio_t, which we do via the clumsy
|
||||
* ifdef in the function declaration.
|
||||
* It also means we'll only return one uio_t.
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
@ -1245,52 +1244,46 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
|
||||
uio_t *out_uio, uint_t *enc_len, uint8_t **authbuf, uint_t *auth_len,
|
||||
boolean_t *no_crypt)
|
||||
{
|
||||
int ret;
|
||||
uint64_t txtype, lr_len;
|
||||
uint_t nr_src, nr_dst, crypt_len;
|
||||
uint_t aad_len = 0, nr_iovecs = 0, total_len = 0;
|
||||
iovec_t *src_iovecs = NULL, *dst_iovecs = NULL;
|
||||
uint8_t *aadbuf = zio_buf_alloc(datalen);
|
||||
uint8_t *src, *dst, *slrp, *dlrp, *blkend, *aadp;
|
||||
iovec_t *dst_iovecs;
|
||||
zil_chain_t *zilc;
|
||||
lr_t *lr;
|
||||
uint8_t *aadbuf = zio_buf_alloc(datalen);
|
||||
uint64_t txtype, lr_len;
|
||||
uint_t crypt_len, nr_iovecs, vec;
|
||||
uint_t aad_len = 0, total_len = 0;
|
||||
|
||||
/* cipherbuf always needs an extra iovec for the MAC */
|
||||
if (encrypt) {
|
||||
src = plainbuf;
|
||||
dst = cipherbuf;
|
||||
nr_src = 0;
|
||||
nr_dst = 1;
|
||||
} else {
|
||||
src = cipherbuf;
|
||||
dst = plainbuf;
|
||||
nr_src = 1;
|
||||
nr_dst = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need at least two iovecs -- one for the AAD,
|
||||
* one for the MAC.
|
||||
*/
|
||||
bcopy(src, dst, datalen);
|
||||
nr_dst = 2;
|
||||
|
||||
/* find the start and end record of the log block */
|
||||
/* Find the start and end record of the log block. */
|
||||
zilc = (zil_chain_t *)src;
|
||||
slrp = src + sizeof (zil_chain_t);
|
||||
aadp = aadbuf;
|
||||
blkend = src + ((byteswap) ? BSWAP_64(zilc->zc_nused) : zilc->zc_nused);
|
||||
|
||||
/* calculate the number of encrypted iovecs we will need */
|
||||
/*
|
||||
* Calculate the number of encrypted iovecs we will need.
|
||||
*/
|
||||
|
||||
/* We need at least two iovecs -- one for the AAD, one for the MAC. */
|
||||
nr_iovecs = 2;
|
||||
|
||||
for (; slrp < blkend; slrp += lr_len) {
|
||||
lr = (lr_t *)slrp;
|
||||
|
||||
if (!byteswap) {
|
||||
txtype = lr->lrc_txtype;
|
||||
lr_len = lr->lrc_reclen;
|
||||
} else {
|
||||
if (byteswap) {
|
||||
txtype = BSWAP_64(lr->lrc_txtype);
|
||||
lr_len = BSWAP_64(lr->lrc_reclen);
|
||||
} else {
|
||||
txtype = lr->lrc_txtype;
|
||||
lr_len = lr->lrc_reclen;
|
||||
}
|
||||
|
||||
nr_iovecs++;
|
||||
@ -1298,27 +1291,7 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
|
||||
nr_iovecs++;
|
||||
}
|
||||
|
||||
nr_src = 0;
|
||||
nr_dst += nr_iovecs;
|
||||
|
||||
/* allocate the iovec arrays */
|
||||
if (nr_src != 0) {
|
||||
src_iovecs = kmem_alloc(nr_src * sizeof (iovec_t), KM_SLEEP);
|
||||
if (src_iovecs == NULL) {
|
||||
ret = SET_ERROR(ENOMEM);
|
||||
goto error;
|
||||
}
|
||||
bzero(src_iovecs, nr_src * sizeof (iovec_t));
|
||||
}
|
||||
|
||||
if (nr_dst != 0) {
|
||||
dst_iovecs = kmem_alloc(nr_dst * sizeof (iovec_t), KM_SLEEP);
|
||||
if (dst_iovecs == NULL) {
|
||||
ret = SET_ERROR(ENOMEM);
|
||||
goto error;
|
||||
}
|
||||
bzero(dst_iovecs, nr_dst * sizeof (iovec_t));
|
||||
}
|
||||
dst_iovecs = kmem_alloc(nr_iovecs * sizeof (iovec_t), KM_SLEEP);
|
||||
|
||||
/*
|
||||
* Copy the plain zil header over and authenticate everything except
|
||||
@ -1326,18 +1299,20 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
|
||||
* the embedded checksum will not have been calculated yet, so we don't
|
||||
* authenticate that.
|
||||
*/
|
||||
bcopy(src, dst, sizeof (zil_chain_t));
|
||||
bcopy(src, aadp, sizeof (zil_chain_t) - sizeof (zio_eck_t));
|
||||
aadp += sizeof (zil_chain_t) - sizeof (zio_eck_t);
|
||||
aad_len += sizeof (zil_chain_t) - sizeof (zio_eck_t);
|
||||
|
||||
/* loop over records again, filling in iovecs */
|
||||
/* The first one will contain the authbuf */
|
||||
nr_iovecs = 1;
|
||||
|
||||
slrp = src + sizeof (zil_chain_t);
|
||||
dlrp = dst + sizeof (zil_chain_t);
|
||||
|
||||
/*
|
||||
* Loop over records again, filling in iovecs.
|
||||
*/
|
||||
|
||||
/* The first iovec will contain the authbuf. */
|
||||
vec = 1;
|
||||
|
||||
for (; slrp < blkend; slrp += lr_len, dlrp += lr_len) {
|
||||
lr = (lr_t *)slrp;
|
||||
|
||||
@ -1355,8 +1330,6 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
|
||||
aadp += sizeof (lr_t);
|
||||
aad_len += sizeof (lr_t);
|
||||
|
||||
ASSERT3P(dst_iovecs, !=, NULL);
|
||||
|
||||
/*
|
||||
* If this is a TX_WRITE record we want to encrypt everything
|
||||
* except the bp if exists. If the bp does exist we want to
|
||||
@ -1365,9 +1338,9 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
|
||||
if (txtype == TX_WRITE) {
|
||||
crypt_len = sizeof (lr_write_t) -
|
||||
sizeof (lr_t) - sizeof (blkptr_t);
|
||||
dst_iovecs[nr_iovecs].iov_base = (char *)dlrp +
|
||||
dst_iovecs[vec].iov_base = (char *)dlrp +
|
||||
sizeof (lr_t);
|
||||
dst_iovecs[nr_iovecs].iov_len = crypt_len;
|
||||
dst_iovecs[vec].iov_len = crypt_len;
|
||||
|
||||
/* copy the bp now since it will not be encrypted */
|
||||
bcopy(slrp + sizeof (lr_write_t) - sizeof (blkptr_t),
|
||||
@ -1377,56 +1350,45 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
|
||||
aadp, sizeof (blkptr_t));
|
||||
aadp += sizeof (blkptr_t);
|
||||
aad_len += sizeof (blkptr_t);
|
||||
nr_iovecs++;
|
||||
vec++;
|
||||
total_len += crypt_len;
|
||||
|
||||
if (lr_len != sizeof (lr_write_t)) {
|
||||
crypt_len = lr_len - sizeof (lr_write_t);
|
||||
dst_iovecs[nr_iovecs].iov_base = (char *)
|
||||
dst_iovecs[vec].iov_base = (char *)
|
||||
dlrp + sizeof (lr_write_t);
|
||||
dst_iovecs[nr_iovecs].iov_len = crypt_len;
|
||||
nr_iovecs++;
|
||||
dst_iovecs[vec].iov_len = crypt_len;
|
||||
vec++;
|
||||
total_len += crypt_len;
|
||||
}
|
||||
} else {
|
||||
crypt_len = lr_len - sizeof (lr_t);
|
||||
dst_iovecs[nr_iovecs].iov_base = (char *)dlrp +
|
||||
dst_iovecs[vec].iov_base = (char *)dlrp +
|
||||
sizeof (lr_t);
|
||||
dst_iovecs[nr_iovecs].iov_len = crypt_len;
|
||||
nr_iovecs++;
|
||||
dst_iovecs[vec].iov_len = crypt_len;
|
||||
vec++;
|
||||
total_len += crypt_len;
|
||||
}
|
||||
}
|
||||
|
||||
*no_crypt = (nr_iovecs == 0);
|
||||
/* The last iovec will contain the MAC. */
|
||||
ASSERT3U(vec, ==, nr_iovecs - 1);
|
||||
|
||||
/* AAD */
|
||||
dst_iovecs[0].iov_base = aadbuf;
|
||||
dst_iovecs[0].iov_len = aad_len;
|
||||
/* MAC */
|
||||
dst_iovecs[vec].iov_base = 0;
|
||||
dst_iovecs[vec].iov_len = 0;
|
||||
|
||||
*no_crypt = (vec == 1);
|
||||
*enc_len = total_len;
|
||||
*authbuf = aadbuf;
|
||||
*auth_len = aad_len;
|
||||
dst_iovecs[0].iov_base = aadbuf;
|
||||
dst_iovecs[0].iov_len = aad_len;
|
||||
|
||||
out_uio->uio_iov = dst_iovecs;
|
||||
out_uio->uio_iovcnt = nr_dst;
|
||||
out_uio->uio_iovcnt = nr_iovecs;
|
||||
|
||||
return (0);
|
||||
|
||||
error:
|
||||
zio_buf_free(aadbuf, datalen);
|
||||
if (src_iovecs != NULL)
|
||||
kmem_free(src_iovecs, nr_src * sizeof (iovec_t));
|
||||
if (dst_iovecs != NULL)
|
||||
kmem_free(dst_iovecs, nr_dst * sizeof (iovec_t));
|
||||
|
||||
*enc_len = 0;
|
||||
*authbuf = NULL;
|
||||
*auth_len = 0;
|
||||
*no_crypt = B_FALSE;
|
||||
puio->uio_iov = NULL;
|
||||
puio->uio_iovcnt = 0;
|
||||
out_uio->uio_iov = NULL;
|
||||
out_uio->uio_iovcnt = 0;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1438,29 +1400,22 @@ zio_crypt_init_uios_dnode(boolean_t encrypt, uint64_t version,
|
||||
uio_t *puio, uio_t *out_uio, uint_t *enc_len, uint8_t **authbuf,
|
||||
uint_t *auth_len, boolean_t *no_crypt)
|
||||
{
|
||||
int ret;
|
||||
uint_t nr_src, nr_dst, crypt_len;
|
||||
uint_t aad_len = 0, nr_iovecs = 0, total_len = 0;
|
||||
uint_t i, j, max_dnp = datalen >> DNODE_SHIFT;
|
||||
iovec_t *src_iovecs = NULL, *dst_iovecs = NULL;
|
||||
uint8_t *aadbuf = zio_buf_alloc(datalen);
|
||||
uint8_t *src, *dst, *aadp;
|
||||
dnode_phys_t *dnp, *adnp, *sdnp, *ddnp;
|
||||
uint8_t *aadbuf = zio_buf_alloc(datalen);
|
||||
iovec_t *dst_iovecs;
|
||||
uint_t nr_iovecs, crypt_len, vec;
|
||||
uint_t aad_len = 0, total_len = 0;
|
||||
uint_t i, j, max_dnp = datalen >> DNODE_SHIFT;
|
||||
|
||||
if (encrypt) {
|
||||
src = plainbuf;
|
||||
dst = cipherbuf;
|
||||
nr_src = 0;
|
||||
nr_dst = 1;
|
||||
} else {
|
||||
src = cipherbuf;
|
||||
dst = plainbuf;
|
||||
nr_src = 1;
|
||||
nr_dst = 0;
|
||||
}
|
||||
|
||||
bcopy(src, dst, datalen);
|
||||
nr_dst = 2;
|
||||
|
||||
sdnp = (dnode_phys_t *)src;
|
||||
ddnp = (dnode_phys_t *)dst;
|
||||
@ -1470,6 +1425,10 @@ zio_crypt_init_uios_dnode(boolean_t encrypt, uint64_t version,
|
||||
* Count the number of iovecs we will need to do the encryption by
|
||||
* counting the number of bonus buffers that need to be encrypted.
|
||||
*/
|
||||
|
||||
/* We need at least two iovecs -- one for the AAD, one for the MAC. */
|
||||
nr_iovecs = 2;
|
||||
|
||||
for (i = 0; i < max_dnp; i += sdnp[i].dn_extra_slots + 1) {
|
||||
/*
|
||||
* This block may still be byteswapped. However, all of the
|
||||
@ -1484,34 +1443,17 @@ zio_crypt_init_uios_dnode(boolean_t encrypt, uint64_t version,
|
||||
}
|
||||
}
|
||||
|
||||
nr_src = 0;
|
||||
nr_dst += nr_iovecs;
|
||||
|
||||
if (nr_src != 0) {
|
||||
src_iovecs = kmem_alloc(nr_src * sizeof (iovec_t), KM_SLEEP);
|
||||
if (src_iovecs == NULL) {
|
||||
ret = SET_ERROR(ENOMEM);
|
||||
goto error;
|
||||
}
|
||||
bzero(src_iovecs, nr_src * sizeof (iovec_t));
|
||||
}
|
||||
|
||||
if (nr_dst != 0) {
|
||||
dst_iovecs = kmem_alloc(nr_dst * sizeof (iovec_t), KM_SLEEP);
|
||||
if (dst_iovecs == NULL) {
|
||||
ret = SET_ERROR(ENOMEM);
|
||||
goto error;
|
||||
}
|
||||
bzero(dst_iovecs, nr_dst * sizeof (iovec_t));
|
||||
}
|
||||
|
||||
nr_iovecs = 1;
|
||||
dst_iovecs = kmem_alloc(nr_iovecs * sizeof (iovec_t), KM_SLEEP);
|
||||
|
||||
/*
|
||||
* Iterate through the dnodes again, this time filling in the uios
|
||||
* we allocated earlier. We also concatenate any data we want to
|
||||
* authenticate onto aadbuf.
|
||||
*/
|
||||
|
||||
/* The first iovec will contain the authbuf. */
|
||||
vec = 1;
|
||||
|
||||
for (i = 0; i < max_dnp; i += sdnp[i].dn_extra_slots + 1) {
|
||||
dnp = &sdnp[i];
|
||||
|
||||
@ -1565,12 +1507,10 @@ zio_crypt_init_uios_dnode(boolean_t encrypt, uint64_t version,
|
||||
if (dnp->dn_type != DMU_OT_NONE &&
|
||||
DMU_OT_IS_ENCRYPTED(dnp->dn_bonustype) &&
|
||||
dnp->dn_bonuslen != 0) {
|
||||
ASSERT3U(nr_iovecs, <, nr_dst);
|
||||
ASSERT3P(dst_iovecs, !=, NULL);
|
||||
dst_iovecs[nr_iovecs].iov_base = DN_BONUS(&ddnp[i]);
|
||||
dst_iovecs[nr_iovecs].iov_len = crypt_len;
|
||||
dst_iovecs[vec].iov_base = DN_BONUS(&ddnp[i]);
|
||||
dst_iovecs[vec].iov_len = crypt_len;
|
||||
|
||||
nr_iovecs++;
|
||||
vec++;
|
||||
total_len += crypt_len;
|
||||
} else {
|
||||
bcopy(DN_BONUS(dnp), DN_BONUS(&ddnp[i]), crypt_len);
|
||||
@ -1580,33 +1520,24 @@ zio_crypt_init_uios_dnode(boolean_t encrypt, uint64_t version,
|
||||
}
|
||||
}
|
||||
|
||||
*no_crypt = (nr_iovecs == 0);
|
||||
/* The last iovec will contain the MAC. */
|
||||
ASSERT3U(vec, ==, nr_iovecs - 1);
|
||||
|
||||
/* AAD */
|
||||
dst_iovecs[0].iov_base = aadbuf;
|
||||
dst_iovecs[0].iov_len = aad_len;
|
||||
/* MAC */
|
||||
dst_iovecs[vec].iov_base = 0;
|
||||
dst_iovecs[vec].iov_len = 0;
|
||||
|
||||
*no_crypt = (vec == 1);
|
||||
*enc_len = total_len;
|
||||
*authbuf = aadbuf;
|
||||
*auth_len = aad_len;
|
||||
|
||||
dst_iovecs[0].iov_base = aadbuf;
|
||||
dst_iovecs[0].iov_len = aad_len;
|
||||
out_uio->uio_iov = dst_iovecs;
|
||||
out_uio->uio_iovcnt = nr_dst;
|
||||
out_uio->uio_iovcnt = nr_iovecs;
|
||||
|
||||
return (0);
|
||||
|
||||
error:
|
||||
zio_buf_free(aadbuf, datalen);
|
||||
if (src_iovecs != NULL)
|
||||
kmem_free(src_iovecs, nr_src * sizeof (iovec_t));
|
||||
if (dst_iovecs != NULL)
|
||||
kmem_free(dst_iovecs, nr_dst * sizeof (iovec_t));
|
||||
|
||||
*enc_len = 0;
|
||||
*authbuf = NULL;
|
||||
*auth_len = 0;
|
||||
*no_crypt = B_FALSE;
|
||||
out_uio->uio_iov = NULL;
|
||||
out_uio->uio_iovcnt = 0;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
|
@ -89,7 +89,17 @@ procfs_list_next_node(procfs_list_cursor_t *cursor, loff_t *pos)
|
||||
cursor->cached_node = next_node;
|
||||
cursor->cached_pos = NODE_ID(procfs_list, cursor->cached_node);
|
||||
*pos = cursor->cached_pos;
|
||||
} else {
|
||||
/*
|
||||
* seq_read() expects ->next() to update the position even
|
||||
* when there are no more entries. Advance the position to
|
||||
* prevent a warning from being logged.
|
||||
*/
|
||||
cursor->cached_node = NULL;
|
||||
cursor->cached_pos++;
|
||||
*pos = cursor->cached_pos;
|
||||
}
|
||||
|
||||
return (next_node);
|
||||
}
|
||||
|
||||
@ -105,6 +115,8 @@ procfs_list_seq_start(struct seq_file *f, loff_t *pos)
|
||||
cursor->cached_node = SEQ_START_TOKEN;
|
||||
cursor->cached_pos = 0;
|
||||
return (SEQ_START_TOKEN);
|
||||
} else if (cursor->cached_node == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -207,6 +219,7 @@ static const kstat_proc_op_t procfs_list_operations = {
|
||||
*/
|
||||
void
|
||||
procfs_list_install(const char *module,
|
||||
const char *submodule,
|
||||
const char *name,
|
||||
mode_t mode,
|
||||
procfs_list_t *procfs_list,
|
||||
@ -215,6 +228,12 @@ procfs_list_install(const char *module,
|
||||
int (*clear)(procfs_list_t *procfs_list),
|
||||
size_t procfs_list_node_off)
|
||||
{
|
||||
char *modulestr;
|
||||
|
||||
if (submodule != NULL)
|
||||
modulestr = kmem_asprintf("%s/%s", module, submodule);
|
||||
else
|
||||
modulestr = kmem_asprintf("%s", module);
|
||||
mutex_init(&procfs_list->pl_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
list_create(&procfs_list->pl_list,
|
||||
procfs_list_node_off + sizeof (procfs_list_node_t),
|
||||
@ -225,9 +244,10 @@ procfs_list_install(const char *module,
|
||||
procfs_list->pl_clear = clear;
|
||||
procfs_list->pl_node_offset = procfs_list_node_off;
|
||||
|
||||
kstat_proc_entry_init(&procfs_list->pl_kstat_entry, module, name);
|
||||
kstat_proc_entry_init(&procfs_list->pl_kstat_entry, modulestr, name);
|
||||
kstat_proc_entry_install(&procfs_list->pl_kstat_entry, mode,
|
||||
&procfs_list_operations, procfs_list);
|
||||
kmem_strfree(modulestr);
|
||||
}
|
||||
EXPORT_SYMBOL(procfs_list_install);
|
||||
|
||||
|
@ -436,6 +436,16 @@ vdev_submit_bio_impl(struct bio *bio)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* preempt_schedule_notrace is GPL-only which breaks the ZFS build, so
|
||||
* replace it with preempt_schedule under the following condition:
|
||||
*/
|
||||
#if defined(CONFIG_ARM64) && \
|
||||
defined(CONFIG_PREEMPTION) && \
|
||||
defined(CONFIG_BLK_CGROUP)
|
||||
#define preempt_schedule_notrace(x) preempt_schedule(x)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BIO_SET_DEV
|
||||
#if defined(CONFIG_BLK_CGROUP) && defined(HAVE_BIO_SET_DEV_GPL_ONLY)
|
||||
/*
|
||||
|
@ -94,6 +94,7 @@ void
|
||||
zfs_dbgmsg_init(void)
|
||||
{
|
||||
procfs_list_install("zfs",
|
||||
NULL,
|
||||
"dbgmsg",
|
||||
0600,
|
||||
&zfs_dbgmsgs,
|
||||
|
@ -308,6 +308,7 @@
|
||||
#include <sys/aggsum.h>
|
||||
#include <cityhash.h>
|
||||
#include <sys/vdev_trim.h>
|
||||
#include <sys/zstd/zstd.h>
|
||||
|
||||
#ifndef _KERNEL
|
||||
/* set with ZFS_DEBUG=watch, to enable watchpoints on frozen buffers */
|
||||
@ -4859,6 +4860,7 @@ static boolean_t
|
||||
arc_reap_cb_check(void *arg, zthr_t *zthr)
|
||||
{
|
||||
int64_t free_memory = arc_available_memory();
|
||||
static int reap_cb_check_counter = 0;
|
||||
|
||||
/*
|
||||
* If a kmem reap is already active, don't schedule more. We must
|
||||
@ -4883,6 +4885,14 @@ arc_reap_cb_check(void *arg, zthr_t *zthr)
|
||||
arc_no_grow = B_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called unconditionally every 60 seconds to reclaim unused
|
||||
* zstd compression and decompression context. This is done
|
||||
* here to avoid the need for an independent thread.
|
||||
*/
|
||||
if (!((reap_cb_check_counter++) % 60))
|
||||
zfs_zstd_cache_reap_now();
|
||||
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,8 @@ dbuf_stats_hash_table_data(char *buf, size_t size, void *data)
|
||||
|
||||
ASSERT3S(dsh->idx, >=, 0);
|
||||
ASSERT3S(dsh->idx, <=, h->hash_table_mask);
|
||||
memset(buf, 0, size);
|
||||
if (size)
|
||||
buf[0] = 0;
|
||||
|
||||
mutex_enter(DBUF_HASH_MUTEX(h, dsh->idx));
|
||||
for (db = h->hash_table[dsh->idx]; db != NULL; db = db->db_hash_next) {
|
||||
|
@ -643,7 +643,7 @@ dump_freeobjects(dmu_send_cookie_t *dscp, uint64_t firstobj, uint64_t numobjs)
|
||||
* receiving side.
|
||||
*/
|
||||
if (maxobj > 0) {
|
||||
if (maxobj < firstobj)
|
||||
if (maxobj <= firstobj)
|
||||
return (0);
|
||||
|
||||
if (maxobj < firstobj + numobjs)
|
||||
@ -663,8 +663,6 @@ dump_freeobjects(dmu_send_cookie_t *dscp, uint64_t firstobj, uint64_t numobjs)
|
||||
return (SET_ERROR(EINTR));
|
||||
dscp->dsc_pending_op = PENDING_NONE;
|
||||
}
|
||||
if (numobjs == 0)
|
||||
numobjs = UINT64_MAX - firstobj;
|
||||
|
||||
if (dscp->dsc_pending_op == PENDING_FREEOBJECTS) {
|
||||
/*
|
||||
@ -2686,12 +2684,15 @@ dmu_send_obj(const char *pool, uint64_t tosnap, uint64_t fromsnap,
|
||||
bcopy(fromredact, dspp.fromredactsnaps, size);
|
||||
}
|
||||
|
||||
if (!dsl_dataset_is_before(dspp.to_ds, fromds, 0)) {
|
||||
boolean_t is_before =
|
||||
dsl_dataset_is_before(dspp.to_ds, fromds, 0);
|
||||
dspp.is_clone = (dspp.to_ds->ds_dir !=
|
||||
fromds->ds_dir);
|
||||
dsl_dataset_rele(fromds, FTAG);
|
||||
if (!is_before) {
|
||||
dsl_pool_rele(dspp.dp, FTAG);
|
||||
err = SET_ERROR(EXDEV);
|
||||
} else {
|
||||
dspp.is_clone = (dspp.to_ds->ds_dir !=
|
||||
fromds->ds_dir);
|
||||
dsl_dataset_rele(fromds, FTAG);
|
||||
err = dmu_send_impl(&dspp);
|
||||
}
|
||||
} else {
|
||||
|
@ -1355,7 +1355,8 @@ dnode_hold_impl(objset_t *os, uint64_t object, int flag, int slots,
|
||||
* We do not need to decrypt to read the dnode so it doesn't matter
|
||||
* if we get the encrypted or decrypted version.
|
||||
*/
|
||||
err = dbuf_read(db, NULL, DB_RF_CANFAIL | DB_RF_NO_DECRYPT);
|
||||
err = dbuf_read(db, NULL, DB_RF_CANFAIL |
|
||||
DB_RF_NO_DECRYPT | DB_RF_NOPREFETCH);
|
||||
if (err) {
|
||||
DNODE_STAT_BUMP(dnode_hold_dbuf_read);
|
||||
dbuf_rele(db, FTAG);
|
||||
@ -2396,7 +2397,8 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
|
||||
return (SET_ERROR(ESRCH));
|
||||
}
|
||||
error = dbuf_read(db, NULL,
|
||||
DB_RF_CANFAIL | DB_RF_HAVESTRUCT | DB_RF_NO_DECRYPT);
|
||||
DB_RF_CANFAIL | DB_RF_HAVESTRUCT |
|
||||
DB_RF_NO_DECRYPT | DB_RF_NOPREFETCH);
|
||||
if (error) {
|
||||
dbuf_rele(db, FTAG);
|
||||
return (error);
|
||||
|
@ -235,11 +235,7 @@ dsl_crypto_params_create_nvlist(dcp_cmd_t cmd, nvlist_t *props,
|
||||
return (0);
|
||||
|
||||
error:
|
||||
if (wkey != NULL)
|
||||
dsl_wrapping_key_free(wkey);
|
||||
if (dcp != NULL)
|
||||
kmem_free(dcp, sizeof (dsl_crypto_params_t));
|
||||
|
||||
kmem_free(dcp, sizeof (dsl_crypto_params_t));
|
||||
*dcp_out = NULL;
|
||||
return (ret);
|
||||
}
|
||||
|
@ -2169,6 +2169,7 @@ spa_import_progress_init(void)
|
||||
spa_import_progress_list;
|
||||
|
||||
procfs_list_install("zfs",
|
||||
NULL,
|
||||
"import_progress",
|
||||
0644,
|
||||
&spa_import_progress_list->procfs_list,
|
||||
|
@ -122,14 +122,11 @@ static void
|
||||
spa_read_history_init(spa_t *spa)
|
||||
{
|
||||
spa_history_list_t *shl = &spa->spa_stats.read_history;
|
||||
char *module;
|
||||
|
||||
shl->size = 0;
|
||||
|
||||
module = kmem_asprintf("zfs/%s", spa_name(spa));
|
||||
|
||||
shl->procfs_list.pl_private = shl;
|
||||
procfs_list_install(module,
|
||||
procfs_list_install("zfs",
|
||||
spa_name(spa),
|
||||
"reads",
|
||||
0600,
|
||||
&shl->procfs_list,
|
||||
@ -137,8 +134,6 @@ spa_read_history_init(spa_t *spa)
|
||||
spa_read_history_show_header,
|
||||
spa_read_history_clear,
|
||||
offsetof(spa_read_history_t, srh_node));
|
||||
|
||||
kmem_strfree(module);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -293,14 +288,11 @@ static void
|
||||
spa_txg_history_init(spa_t *spa)
|
||||
{
|
||||
spa_history_list_t *shl = &spa->spa_stats.txg_history;
|
||||
char *module;
|
||||
|
||||
shl->size = 0;
|
||||
|
||||
module = kmem_asprintf("zfs/%s", spa_name(spa));
|
||||
|
||||
shl->procfs_list.pl_private = shl;
|
||||
procfs_list_install(module,
|
||||
procfs_list_install("zfs",
|
||||
spa_name(spa),
|
||||
"txgs",
|
||||
0644,
|
||||
&shl->procfs_list,
|
||||
@ -308,8 +300,6 @@ spa_txg_history_init(spa_t *spa)
|
||||
spa_txg_history_show_header,
|
||||
spa_txg_history_clear,
|
||||
offsetof(spa_txg_history_t, sth_node));
|
||||
|
||||
kmem_strfree(module);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -699,14 +689,12 @@ static void
|
||||
spa_mmp_history_init(spa_t *spa)
|
||||
{
|
||||
spa_history_list_t *shl = &spa->spa_stats.mmp_history;
|
||||
char *module;
|
||||
|
||||
shl->size = 0;
|
||||
|
||||
module = kmem_asprintf("zfs/%s", spa_name(spa));
|
||||
|
||||
shl->procfs_list.pl_private = shl;
|
||||
procfs_list_install(module,
|
||||
procfs_list_install("zfs",
|
||||
spa_name(spa),
|
||||
"multihost",
|
||||
0644,
|
||||
&shl->procfs_list,
|
||||
@ -714,8 +702,6 @@ spa_mmp_history_init(spa_t *spa)
|
||||
spa_mmp_history_show_header,
|
||||
spa_mmp_history_clear,
|
||||
offsetof(spa_mmp_history_t, smh_node));
|
||||
|
||||
kmem_strfree(module);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -584,15 +584,22 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
|
||||
(wr_state == WR_COPIED ? len : 0));
|
||||
lr = (lr_write_t *)&itx->itx_lr;
|
||||
|
||||
DB_DNODE_ENTER(db);
|
||||
if (wr_state == WR_COPIED && dmu_read_by_dnode(DB_DNODE(db),
|
||||
off, len, lr + 1, DMU_READ_NO_PREFETCH) != 0) {
|
||||
zil_itx_destroy(itx);
|
||||
itx = zil_itx_create(txtype, sizeof (*lr));
|
||||
lr = (lr_write_t *)&itx->itx_lr;
|
||||
wr_state = WR_NEED_COPY;
|
||||
/*
|
||||
* For WR_COPIED records, copy the data into the lr_write_t.
|
||||
*/
|
||||
if (wr_state == WR_COPIED) {
|
||||
int err;
|
||||
DB_DNODE_ENTER(db);
|
||||
err = dmu_read_by_dnode(DB_DNODE(db), off, len, lr + 1,
|
||||
DMU_READ_NO_PREFETCH);
|
||||
if (err != 0) {
|
||||
zil_itx_destroy(itx);
|
||||
itx = zil_itx_create(txtype, sizeof (*lr));
|
||||
lr = (lr_write_t *)&itx->itx_lr;
|
||||
wr_state = WR_NEED_COPY;
|
||||
}
|
||||
DB_DNODE_EXIT(db);
|
||||
}
|
||||
DB_DNODE_EXIT(db);
|
||||
|
||||
itx->itx_wr_state = wr_state;
|
||||
lr->lr_foid = zp->z_id;
|
||||
|
@ -238,7 +238,7 @@ zstd_mempool_alloc(struct zstd_pool *zstd_mempool, size_t size)
|
||||
* Check if objects fits the size, if so we take it and
|
||||
* update the timestamp.
|
||||
*/
|
||||
if (!mem && pool->mem && size <= pool->size) {
|
||||
if (size && !mem && pool->mem && size <= pool->size) {
|
||||
pool->timeout = gethrestime_sec() +
|
||||
ZSTD_POOL_TIMEOUT;
|
||||
mem = pool->mem;
|
||||
@ -257,7 +257,7 @@ zstd_mempool_alloc(struct zstd_pool *zstd_mempool, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
if (mem) {
|
||||
if (!size || mem) {
|
||||
return (mem);
|
||||
}
|
||||
|
||||
@ -688,6 +688,19 @@ zstd_mempool_deinit(void)
|
||||
zstd_mempool_cctx = NULL;
|
||||
}
|
||||
|
||||
/* release unused memory from pool */
|
||||
|
||||
void
|
||||
zfs_zstd_cache_reap_now(void)
|
||||
{
|
||||
/*
|
||||
* calling alloc with zero size seeks
|
||||
* and releases old unused objects
|
||||
*/
|
||||
zstd_mempool_alloc(zstd_mempool_cctx, 0);
|
||||
zstd_mempool_alloc(zstd_mempool_dctx, 0);
|
||||
}
|
||||
|
||||
extern int __init
|
||||
zstd_init(void)
|
||||
{
|
||||
@ -729,10 +742,11 @@ module_init(zstd_init);
|
||||
module_exit(zstd_fini);
|
||||
|
||||
ZFS_MODULE_DESCRIPTION("ZSTD Compression for ZFS");
|
||||
ZFS_MODULE_LICENSE("BSD");
|
||||
ZFS_MODULE_LICENSE("Dual BSD/GPL");
|
||||
ZFS_MODULE_VERSION(ZSTD_VERSION_STRING);
|
||||
|
||||
EXPORT_SYMBOL(zfs_zstd_compress);
|
||||
EXPORT_SYMBOL(zfs_zstd_decompress_level);
|
||||
EXPORT_SYMBOL(zfs_zstd_decompress);
|
||||
EXPORT_SYMBOL(zfs_zstd_cache_reap_now);
|
||||
#endif
|
||||
|
@ -790,7 +790,7 @@ tests = ['recv_dedup', 'recv_dedup_encrypted_zvol', 'rsend_001_pos',
|
||||
'send_freeobjects', 'send_realloc_files',
|
||||
'send_realloc_encrypted_files', 'send_spill_block', 'send_holds',
|
||||
'send_hole_birth', 'send_mixed_raw', 'send-wR_encrypted_zvol',
|
||||
'send_partial_dataset']
|
||||
'send_partial_dataset', 'send_invalid']
|
||||
tags = ['functional', 'rsend']
|
||||
|
||||
[tests/functional/scrub_mirror]
|
||||
|
@ -1,6 +1,7 @@
|
||||
EXTRA_DIST = file_common.h
|
||||
|
||||
SUBDIRS = \
|
||||
badsend \
|
||||
btree_test \
|
||||
chg_usr_exec \
|
||||
devname2devid \
|
||||
|
1
tests/zfs-tests/cmd/badsend/.gitignore
vendored
Normal file
1
tests/zfs-tests/cmd/badsend/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/badsend
|
11
tests/zfs-tests/cmd/badsend/Makefile.am
Normal file
11
tests/zfs-tests/cmd/badsend/Makefile.am
Normal file
@ -0,0 +1,11 @@
|
||||
include $(top_srcdir)/config/Rules.am
|
||||
|
||||
pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
|
||||
|
||||
pkgexec_PROGRAMS = badsend
|
||||
|
||||
badsend_SOURCES = badsend.c
|
||||
badsend_LDADD = \
|
||||
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
||||
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
136
tests/zfs-tests/cmd/badsend/badsend.c
Normal file
136
tests/zfs-tests/cmd/badsend/badsend.c
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright 2020 iXsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Test some invalid send operations with libzfs/libzfs_core.
|
||||
*
|
||||
* Specifying the to and from snaps in the wrong order should return EXDEV.
|
||||
* We are checking that the early return doesn't accidentally leave any
|
||||
* references held, so this test is designed to trigger a panic when asserts
|
||||
* are verified with the bug present.
|
||||
*/
|
||||
|
||||
#include <libzfs.h>
|
||||
#include <libzfs_core.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sysexits.h>
|
||||
#include <err.h>
|
||||
|
||||
static void
|
||||
usage(const char *name)
|
||||
{
|
||||
fprintf(stderr, "usage: %s snap0 snap1\n", name);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char const * const argv[])
|
||||
{
|
||||
sendflags_t flags = { 0 };
|
||||
libzfs_handle_t *zhdl;
|
||||
zfs_handle_t *zhp;
|
||||
const char *fromfull, *tofull, *fsname, *fromsnap, *tosnap, *p;
|
||||
uint64_t size;
|
||||
int fd, error;
|
||||
|
||||
if (argc != 3)
|
||||
usage(argv[0]);
|
||||
|
||||
fromfull = argv[1];
|
||||
tofull = argv[2];
|
||||
|
||||
p = strchr(fromfull, '@');
|
||||
if (p == NULL)
|
||||
usage(argv[0]);
|
||||
fromsnap = p + 1;
|
||||
|
||||
p = strchr(tofull, '@');
|
||||
if (p == NULL)
|
||||
usage(argv[0]);
|
||||
tosnap = p + 1;
|
||||
|
||||
fsname = strndup(tofull, p - tofull);
|
||||
if (strncmp(fsname, fromfull, p - tofull) != 0)
|
||||
usage(argv[0]);
|
||||
|
||||
fd = open("/dev/null", O_WRONLY);
|
||||
if (fd == -1)
|
||||
err(EX_OSERR, "open(\"/dev/null\", O_WRONLY)");
|
||||
|
||||
zhdl = libzfs_init();
|
||||
if (zhdl == NULL)
|
||||
errx(EX_OSERR, "libzfs_init(): %s", libzfs_error_init(errno));
|
||||
|
||||
zhp = zfs_open(zhdl, fsname, ZFS_TYPE_FILESYSTEM);
|
||||
if (zhp == NULL)
|
||||
err(EX_OSERR, "zfs_open(\"%s\")", fsname);
|
||||
|
||||
/*
|
||||
* Exercise EXDEV in dmu_send_obj. The error gets translated to
|
||||
* EZFS_CROSSTARGET in libzfs.
|
||||
*/
|
||||
error = zfs_send(zhp, tosnap, fromsnap, &flags, fd, NULL, NULL, NULL);
|
||||
if (error == 0 || libzfs_errno(zhdl) != EZFS_CROSSTARGET)
|
||||
errx(EX_OSERR, "zfs_send(\"%s\", \"%s\") should have failed "
|
||||
"with EZFS_CROSSTARGET, not %d",
|
||||
tofull, fromfull, libzfs_errno(zhdl));
|
||||
printf("zfs_send(\"%s\", \"%s\"): %s\n",
|
||||
tofull, fromfull, libzfs_error_description(zhdl));
|
||||
|
||||
zfs_close(zhp);
|
||||
|
||||
/*
|
||||
* Exercise EXDEV in dmu_send.
|
||||
*/
|
||||
error = lzc_send_resume_redacted(fromfull, tofull, fd, 0, 0, 0, NULL);
|
||||
if (error != EXDEV)
|
||||
errx(EX_OSERR, "lzc_send_resume_redacted(\"%s\", \"%s\")"
|
||||
" should have failed with EXDEV, not %d",
|
||||
fromfull, tofull, error);
|
||||
printf("lzc_send_resume_redacted(\"%s\", \"%s\"): %s\n",
|
||||
fromfull, tofull, strerror(error));
|
||||
|
||||
/*
|
||||
* Exercise EXDEV in dmu_send_estimate_fast.
|
||||
*/
|
||||
error = lzc_send_space_resume_redacted(fromfull, tofull, 0, 0, 0, 0,
|
||||
NULL, fd, &size);
|
||||
if (error != EXDEV)
|
||||
errx(EX_OSERR, "lzc_send_space_resume_redacted(\"%s\", \"%s\")"
|
||||
" should have failed with EXDEV, not %d",
|
||||
fromfull, tofull, error);
|
||||
printf("lzc_send_space_resume_redacted(\"%s\", \"%s\"): %s\n",
|
||||
fromfull, tofull, strerror(error));
|
||||
|
||||
close(fd);
|
||||
libzfs_fini(zhdl);
|
||||
free((void *)fsname);
|
||||
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
@ -190,7 +190,8 @@ export ZFS_FILES='zdb
|
||||
zstreamdump
|
||||
zfs_ids_to_path'
|
||||
|
||||
export ZFSTEST_FILES='btree_test
|
||||
export ZFSTEST_FILES='badsend
|
||||
btree_test
|
||||
chg_usr_exec
|
||||
devname2devid
|
||||
dir_rd_update
|
||||
|
@ -51,6 +51,7 @@ dist_pkgdata_SCRIPTS = \
|
||||
send_spill_block.ksh \
|
||||
send_holds.ksh \
|
||||
send_hole_birth.ksh \
|
||||
send_invalid.ksh \
|
||||
send_mixed_raw.ksh \
|
||||
send-wR_encrypted_zvol.ksh
|
||||
|
||||
|
52
tests/zfs-tests/tests/functional/rsend/send_invalid.ksh
Normal file
52
tests/zfs-tests/tests/functional/rsend/send_invalid.ksh
Normal file
@ -0,0 +1,52 @@
|
||||
#!/bin/ksh
|
||||
|
||||
#
|
||||
# This file and its contents are supplied under the terms of the
|
||||
# Common Development and Distribution License ("CDDL"), version a.0.
|
||||
# You may only use this file in accordance with the terms of version
|
||||
# a.0 of the CDDL.
|
||||
#
|
||||
# A full copy of the text of the CDDL should have accompanied this
|
||||
# source. A copy of the CDDL is also available via the Internet at
|
||||
# http://www.illumos.org/license/CDDL.
|
||||
#
|
||||
|
||||
#
|
||||
# Portions Copyright 2020 iXsystems, Inc.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/rsend/rsend.kshlib
|
||||
|
||||
#
|
||||
# Description:
|
||||
# Verify that send with invalid options will fail gracefully.
|
||||
#
|
||||
# Strategy:
|
||||
# 1. Perform zfs send on the cli with the order of the snapshots reversed
|
||||
# 2. Perform zfs send using libzfs with the order of the snapshots reversed
|
||||
#
|
||||
|
||||
verify_runnable "both"
|
||||
|
||||
log_assert "Verify that send with invalid options will fail gracefully."
|
||||
|
||||
function cleanup
|
||||
{
|
||||
datasetexists $testfs && destroy_dataset $testfs -r
|
||||
}
|
||||
log_onexit cleanup
|
||||
|
||||
testfs=$POOL/fs
|
||||
|
||||
log_must zfs create $testfs
|
||||
log_must zfs snap $testfs@snap0
|
||||
log_must zfs snap $testfs@snap1
|
||||
|
||||
# Test bad send with the CLI
|
||||
log_mustnot eval "zfs send -i $testfs@snap1 $testfs@snap0 >/dev/null"
|
||||
|
||||
# Test bad send with libzfs/libzfs_core
|
||||
log_must badsend $testfs@snap0 $testfs@snap1
|
||||
|
||||
log_pass "Send with invalid options fails gracefully."
|
Loading…
Reference in New Issue
Block a user