diff --git a/cddl/share/zfs/compatibility.d/Makefile b/cddl/share/zfs/compatibility.d/Makefile index 8bc18bcd639..255f4a3542b 100644 --- a/cddl/share/zfs/compatibility.d/Makefile +++ b/cddl/share/zfs/compatibility.d/Makefile @@ -19,6 +19,10 @@ FILES= \ openzfsonosx-1.9.3 \ openzfs-2.0-freebsd \ openzfs-2.0-linux \ + openzfs-2.1-freebsd \ + openzfs-2.1-linux \ + zol-0.6.1 \ + zol-0.6.4 \ zol-0.6.5 \ zol-0.7 \ zol-0.8 diff --git a/sys/contrib/openzfs/.github/ISSUE_TEMPLATE/config.yml b/sys/contrib/openzfs/.github/ISSUE_TEMPLATE/config.yml index dd8f0557a30..952414f66ac 100644 --- a/sys/contrib/openzfs/.github/ISSUE_TEMPLATE/config.yml +++ b/sys/contrib/openzfs/.github/ISSUE_TEMPLATE/config.yml @@ -10,5 +10,5 @@ contact_links: url: https://lists.freebsd.org/mailman/listinfo/freebsd-fs about: Get community support for OpenZFS on FreeBSD - name: OpenZFS on IRC - url: https://webchat.freenode.net/#openzfs + url: https://kiwiirc.com/nextclient/irc.libera.chat/openzfs about: Use IRC to get community support for OpenZFS diff --git a/sys/contrib/openzfs/.github/workflows/zfs-tests-functional.yml b/sys/contrib/openzfs/.github/workflows/zfs-tests-functional.yml index 631f174b74f..d2b5764dbf8 100644 --- a/sys/contrib/openzfs/.github/workflows/zfs-tests-functional.yml +++ b/sys/contrib/openzfs/.github/workflows/zfs-tests-functional.yml @@ -26,7 +26,7 @@ jobs: xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \ libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \ libpam0g-dev pamtester python-dev python-setuptools python-cffi \ - python3 python3-dev python3-setuptools python3-cffi + python3 python3-dev python3-setuptools python3-cffi libcurl4-openssl-dev - name: Autogen.sh run: | sh autogen.sh @@ -44,6 +44,12 @@ jobs: sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf sudo depmod sudo modprobe zfs + # Workaround to provide additional free space for testing. + # https://github.com/actions/virtual-environments/issues/2840 + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" - name: Tests run: | /usr/share/zfs/zfs-tests.sh -v -s 3G diff --git a/sys/contrib/openzfs/.github/workflows/zfs-tests-sanity.yml b/sys/contrib/openzfs/.github/workflows/zfs-tests-sanity.yml index e0339975757..9e2ed1b2f7c 100644 --- a/sys/contrib/openzfs/.github/workflows/zfs-tests-sanity.yml +++ b/sys/contrib/openzfs/.github/workflows/zfs-tests-sanity.yml @@ -22,7 +22,7 @@ jobs: xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \ libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \ libpam0g-dev pamtester python-dev python-setuptools python-cffi \ - python3 python3-dev python3-setuptools python3-cffi + python3 python3-dev python3-setuptools python3-cffi libcurl4-openssl-dev - name: Autogen.sh run: | sh autogen.sh @@ -40,6 +40,12 @@ jobs: sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf sudo depmod sudo modprobe zfs + # Workaround to provide additional free space for testing. + # https://github.com/actions/virtual-environments/issues/2840 + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" - name: Tests run: | /usr/share/zfs/zfs-tests.sh -v -s 3G -r sanity diff --git a/sys/contrib/openzfs/.gitmodules b/sys/contrib/openzfs/.gitmodules index d400f10a7e6..9eaa2b0495d 100644 --- a/sys/contrib/openzfs/.gitmodules +++ b/sys/contrib/openzfs/.gitmodules @@ -1,3 +1,3 @@ [submodule "scripts/zfs-images"] path = scripts/zfs-images - url = https://github.com/zfsonlinux/zfs-images + url = https://github.com/openzfs/zfs-images diff --git a/sys/contrib/openzfs/META b/sys/contrib/openzfs/META index 48084928871..b97858eedd9 100644 --- a/sys/contrib/openzfs/META +++ b/sys/contrib/openzfs/META @@ -1,8 +1,8 @@ Meta: 1 Name: zfs Branch: 1.0 -Version: 2.1.0 -Release: rc1 +Version: 2.1.99 +Release: 1 Release-Tags: relext License: CDDL Author: OpenZFS diff --git a/sys/contrib/openzfs/Makefile.am b/sys/contrib/openzfs/Makefile.am index b7cc4ce8565..4e7e29589fc 100644 --- a/sys/contrib/openzfs/Makefile.am +++ b/sys/contrib/openzfs/Makefile.am @@ -1,3 +1,5 @@ +include $(top_srcdir)/config/Shellcheck.am + ACLOCAL_AMFLAGS = -I config SUBDIRS = include @@ -6,7 +8,7 @@ SUBDIRS += rpm endif if CONFIG_USER -SUBDIRS += etc man scripts lib tests cmd contrib +SUBDIRS += man scripts lib tests cmd etc contrib if BUILD_LINUX SUBDIRS += udev endif @@ -26,8 +28,8 @@ endif AUTOMAKE_OPTIONS = foreign EXTRA_DIST = autogen.sh copy-builtin EXTRA_DIST += config/config.awk config/rpm.am config/deb.am config/tgz.am -EXTRA_DIST += META AUTHORS COPYRIGHT LICENSE NEWS NOTICE README.md -EXTRA_DIST += CODE_OF_CONDUCT.md +EXTRA_DIST += AUTHORS CODE_OF_CONDUCT.md COPYRIGHT LICENSE META NEWS NOTICE +EXTRA_DIST += README.md RELEASES.md EXTRA_DIST += module/lua/README.zfs module/os/linux/spl/README.md # Include all the extra licensing information for modules @@ -123,17 +125,8 @@ cstyle: filter_executable = -exec test -x '{}' \; -print -PHONY += shellcheck -shellcheck: - @if type shellcheck > /dev/null 2>&1; then \ - shellcheck --exclude=SC1090 --exclude=SC1117 --format=gcc \ - $$(find ${top_srcdir}/scripts/*.sh -type f) \ - $$(find ${top_srcdir}/cmd/zed/zed.d/*.sh -type f) \ - $$(find ${top_srcdir}/cmd/zpool/zpool.d/* \ - -type f ${filter_executable}); \ - else \ - echo "skipping shellcheck because shellcheck is not installed"; \ - fi +SHELLCHECKDIRS = cmd contrib etc scripts tests +SHELLCHECKSCRIPTS = autogen.sh PHONY += checkabi storeabi checkabi: lib @@ -142,40 +135,9 @@ checkabi: lib storeabi: lib $(MAKE) -C lib storeabi -PHONY += checkbashisms -checkbashisms: - @if type checkbashisms > /dev/null 2>&1; then \ - checkbashisms -n -p -x \ - $$(find ${top_srcdir} \ - -name '.git' -prune \ - -o -name 'build' -prune \ - -o -name 'tests' -prune \ - -o -name 'config' -prune \ - -o -name 'zed-functions.sh*' -prune \ - -o -name 'zfs-import*' -prune \ - -o -name 'zfs-mount*' -prune \ - -o -name 'zfs-zed*' -prune \ - -o -name 'smart' -prune \ - -o -name 'paxcheck.sh' -prune \ - -o -name 'make_gitrev.sh' -prune \ - -o -name '90zfs' -prune \ - -o -type f ! -name 'config*' \ - ! -name 'libtool' \ - -exec sh -c 'awk "NR==1 && /\#\!.*bin\/sh.*/ {print FILENAME;}" "{}"' \;); \ - else \ - echo "skipping checkbashisms because checkbashisms is not installed"; \ - fi - PHONY += mancheck mancheck: - @if type mandoc > /dev/null 2>&1; then \ - find ${top_srcdir}/man/man8 -type f -name 'zfs.8' \ - -o -name 'zpool.8' -o -name 'zdb.8' \ - -o -name 'zgenhostid.8' | \ - xargs mandoc -Tlint -Werror; \ - else \ - echo "skipping mancheck because mandoc is not installed"; \ - fi + ${top_srcdir}/scripts/mancheck.sh ${top_srcdir}/man ${top_srcdir}/tests/test-runner/man if BUILD_LINUX stat_fmt = -c '%A %n' diff --git a/sys/contrib/openzfs/RELEASES.md b/sys/contrib/openzfs/RELEASES.md new file mode 100644 index 00000000000..55bfdb80ef6 --- /dev/null +++ b/sys/contrib/openzfs/RELEASES.md @@ -0,0 +1,37 @@ +OpenZFS uses the MAJOR.MINOR.PATCH versioning scheme described here: + + * MAJOR - Incremented at the discretion of the OpenZFS developers to indicate + a particularly noteworthy feature or change. An increase in MAJOR number + does not indicate any incompatible on-disk format change. The ability + to import a ZFS pool is controlled by the feature flags enabled on the + pool and the feature flags supported by the installed OpenZFS version. + Increasing the MAJOR version is expected to be an infrequent occurrence. + + * MINOR - Incremented to indicate new functionality such as a new feature + flag, pool/dataset property, zfs/zpool sub-command, new user/kernel + interface, etc. MINOR releases may introduce incompatible changes to the + user space library APIs (libzfs.so). Existing user/kernel interfaces are + considered to be stable to maximize compatibility between OpenZFS releases. + Additions to the user/kernel interface are backwards compatible. + + * PATCH - Incremented when applying documentation updates, important bug + fixes, minor performance improvements, and kernel compatibility patches. + The user space library APIs and user/kernel interface are considered to + be stable. PATCH releases for a MAJOR.MINOR are published as needed. + +Two release branches are maintained for OpenZFS, they are: + + * OpenZFS LTS - A designated MAJOR.MINOR release with periodic PATCH + releases that incorporate important changes backported from newer OpenZFS + releases. This branch is intended for use in environments using an + LTS, enterprise, or similarly managed kernel (RHEL, Ubuntu LTS, Debian). + Minor changes to support these distribution kernels will be applied as + needed. New kernel versions released after the OpenZFS LTS release are + not supported. LTS releases will receive patches for at least 2 years. + The current LTS release is OpenZFS 2.1. + + * OpenZFS current - Tracks the newest MAJOR.MINOR release. This branch + includes support for the latest OpenZFS features and recently releases + kernels. When a new MINOR release is tagged the previous MINOR release + will no longer be maintained (unless it is an LTS release). New MINOR + releases are planned to occur roughly annually. diff --git a/sys/contrib/openzfs/cmd/Makefile.am b/sys/contrib/openzfs/cmd/Makefile.am index 473fcb0e07a..5fc9e83971d 100644 --- a/sys/contrib/openzfs/cmd/Makefile.am +++ b/sys/contrib/openzfs/cmd/Makefile.am @@ -1,10 +1,15 @@ -SUBDIRS = zfs zpool zdb zhack zinject zstream zstreamdump ztest +include $(top_srcdir)/config/Shellcheck.am + +SUBDIRS = zfs zpool zdb zhack zinject zstream ztest SUBDIRS += fsck_zfs vdev_id raidz_test zfs_ids_to_path SUBDIRS += zpool_influxdb CPPCHECKDIRS = zfs zpool zdb zhack zinject zstream ztest CPPCHECKDIRS += raidz_test zfs_ids_to_path zpool_influxdb +# TODO: #12084: SHELLCHECKDIRS = fsck_zfs vdev_id zpool +SHELLCHECKDIRS = fsck_zfs zpool + if USING_PYTHON SUBDIRS += arcstat arc_summary dbufstat endif @@ -12,6 +17,7 @@ endif if BUILD_LINUX SUBDIRS += mount_zfs zed zgenhostid zvol_id zvol_wait CPPCHECKDIRS += mount_zfs zed zgenhostid zvol_id +SHELLCHECKDIRS += zed endif PHONY = cppcheck diff --git a/sys/contrib/openzfs/cmd/arc_summary/arc_summary2 b/sys/contrib/openzfs/cmd/arc_summary/arc_summary2 index 75b5697526f..3302a802d14 100755 --- a/sys/contrib/openzfs/cmd/arc_summary/arc_summary2 +++ b/sys/contrib/openzfs/cmd/arc_summary/arc_summary2 @@ -102,18 +102,6 @@ show_tunable_descriptions = False alternate_tunable_layout = False -def handle_Exception(ex_cls, ex, tb): - if ex is IOError: - if ex.errno == errno.EPIPE: - sys.exit() - - if ex is KeyboardInterrupt: - sys.exit() - - -sys.excepthook = handle_Exception - - def get_Kstat(): """Collect information on the ZFS subsystem from the /proc virtual file system. The name "kstat" is a holdover from the Solaris utility @@ -1137,48 +1125,55 @@ def main(): global alternate_tunable_layout try: - opts, args = getopt.getopt( - sys.argv[1:], - "adp:h", ["alternate", "description", "page=", "help"] - ) - except getopt.error as e: - sys.stderr.write("Error: %s\n" % e.msg) - usage() - sys.exit(1) - - args = {} - for opt, arg in opts: - if opt in ('-a', '--alternate'): - args['a'] = True - if opt in ('-d', '--description'): - args['d'] = True - if opt in ('-p', '--page'): - args['p'] = arg - if opt in ('-h', '--help'): - usage() - sys.exit(0) - - Kstat = get_Kstat() - - alternate_tunable_layout = 'a' in args - show_tunable_descriptions = 'd' in args - - pages = [] - - if 'p' in args: try: - pages.append(unSub[int(args['p']) - 1]) - except IndexError: - sys.stderr.write('the argument to -p must be between 1 and ' + - str(len(unSub)) + '\n') + opts, args = getopt.getopt( + sys.argv[1:], + "adp:h", ["alternate", "description", "page=", "help"] + ) + except getopt.error as e: + sys.stderr.write("Error: %s\n" % e.msg) + usage() sys.exit(1) - else: - pages = unSub - zfs_header() - for page in pages: - page(Kstat) - sys.stdout.write("\n") + args = {} + for opt, arg in opts: + if opt in ('-a', '--alternate'): + args['a'] = True + if opt in ('-d', '--description'): + args['d'] = True + if opt in ('-p', '--page'): + args['p'] = arg + if opt in ('-h', '--help'): + usage() + sys.exit(0) + + Kstat = get_Kstat() + + alternate_tunable_layout = 'a' in args + show_tunable_descriptions = 'd' in args + + pages = [] + + if 'p' in args: + try: + pages.append(unSub[int(args['p']) - 1]) + except IndexError: + sys.stderr.write('the argument to -p must be between 1 and ' + + str(len(unSub)) + '\n') + sys.exit(1) + else: + pages = unSub + + zfs_header() + for page in pages: + page(Kstat) + sys.stdout.write("\n") + except IOError as ex: + if (ex.errno == errno.EPIPE): + sys.exit(0) + raise + except KeyboardInterrupt: + sys.exit(0) if __name__ == '__main__': diff --git a/sys/contrib/openzfs/cmd/arc_summary/arc_summary3 b/sys/contrib/openzfs/cmd/arc_summary/arc_summary3 index 96f7990e172..7b28012ede4 100755 --- a/sys/contrib/openzfs/cmd/arc_summary/arc_summary3 +++ b/sys/contrib/openzfs/cmd/arc_summary/arc_summary3 @@ -42,6 +42,13 @@ import os import subprocess import sys import time +import errno + +# We can't use env -S portably, and we need python3 -u to handle pipes in +# the shell abruptly closing the way we want to, so... +import io +if isinstance(sys.__stderr__.buffer, io.BufferedWriter): + os.execv(sys.executable, [sys.executable, "-u"] + sys.argv) DESCRIPTION = 'Print ARC and other statistics for OpenZFS' INDENT = ' '*8 @@ -161,21 +168,11 @@ elif sys.platform.startswith('linux'): # The original arc_summary called /sbin/modinfo/{spl,zfs} to get # the version information. We switch to /sys/module/{spl,zfs}/version # to make sure we get what is really loaded in the kernel - command = ["cat", "/sys/module/{0}/version".format(request)] - req = request.upper() - - # The recommended way to do this is with subprocess.run(). However, - # some installed versions of Python are < 3.5, so we offer them - # the option of doing it the old way (for now) - if 'run' in dir(subprocess): - info = subprocess.run(command, stdout=subprocess.PIPE, - universal_newlines=True) - version = info.stdout.strip() - else: - info = subprocess.check_output(command, universal_newlines=True) - version = info.strip() - - return version + try: + with open("/sys/module/{}/version".format(request)) as f: + return f.read().strip() + except: + return "(unknown)" def get_descriptions(request): """Get the descriptions of the Solaris Porting Layer (SPL) or the @@ -231,6 +228,29 @@ elif sys.platform.startswith('linux'): return descs +def handle_unraisableException(exc_type, exc_value=None, exc_traceback=None, + err_msg=None, object=None): + handle_Exception(exc_type, object, exc_traceback) + +def handle_Exception(ex_cls, ex, tb): + if ex_cls is KeyboardInterrupt: + sys.exit() + + if ex_cls is BrokenPipeError: + # It turns out that while sys.exit() triggers an exception + # not handled message on Python 3.8+, os._exit() does not. + os._exit(0) + + if ex_cls is OSError: + if ex.errno == errno.ENOTCONN: + sys.exit() + + raise ex + +if hasattr(sys,'unraisablehook'): # Python 3.8+ + sys.unraisablehook = handle_unraisableException +sys.excepthook = handle_Exception + def cleanup_line(single_line): """Format a raw line of data from /proc and isolate the name value diff --git a/sys/contrib/openzfs/cmd/fsck_zfs/.gitignore b/sys/contrib/openzfs/cmd/fsck_zfs/.gitignore new file mode 100644 index 00000000000..0edf0309e94 --- /dev/null +++ b/sys/contrib/openzfs/cmd/fsck_zfs/.gitignore @@ -0,0 +1 @@ +/fsck.zfs diff --git a/sys/contrib/openzfs/cmd/fsck_zfs/Makefile.am b/sys/contrib/openzfs/cmd/fsck_zfs/Makefile.am index 2380f56fa4d..f8139f117ff 100644 --- a/sys/contrib/openzfs/cmd/fsck_zfs/Makefile.am +++ b/sys/contrib/openzfs/cmd/fsck_zfs/Makefile.am @@ -1 +1,6 @@ +include $(top_srcdir)/config/Substfiles.am +include $(top_srcdir)/config/Shellcheck.am + dist_sbin_SCRIPTS = fsck.zfs + +SUBSTFILES += $(dist_sbin_SCRIPTS) diff --git a/sys/contrib/openzfs/cmd/fsck_zfs/fsck.zfs b/sys/contrib/openzfs/cmd/fsck_zfs/fsck.zfs deleted file mode 100755 index 129a7f39c38..00000000000 --- a/sys/contrib/openzfs/cmd/fsck_zfs/fsck.zfs +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -# -# fsck.zfs: A fsck helper to accommodate distributions that expect -# to be able to execute a fsck on all filesystem types. Currently -# this script does nothing but it could be extended to act as a -# compatibility wrapper for 'zpool scrub'. -# - -exit 0 diff --git a/sys/contrib/openzfs/cmd/fsck_zfs/fsck.zfs.in b/sys/contrib/openzfs/cmd/fsck_zfs/fsck.zfs.in new file mode 100755 index 00000000000..37096902cb9 --- /dev/null +++ b/sys/contrib/openzfs/cmd/fsck_zfs/fsck.zfs.in @@ -0,0 +1,44 @@ +#!/bin/sh +# +# fsck.zfs: A fsck helper to accommodate distributions that expect +# to be able to execute a fsck on all filesystem types. +# +# This script simply bubbles up some already-known-about errors, +# see fsck.zfs(8) +# + +if [ "$#" = "0" ]; then + echo "Usage: $0 [options] dataset…" >&2 + exit 16 +fi + +ret=0 +for dataset in "$@"; do + case "$dataset" in + -*) + continue + ;; + *) + ;; + esac + + pool="${dataset%%/*}" + + case "$(@sbindir@/zpool list -Ho health "$pool")" in + DEGRADED) + ret=$(( ret | 4 )) + ;; + FAULTED) + awk '!/^([[:space:]]*#.*)?$/ && $1 == "'"$dataset"'" && $3 == "zfs" {exit 1}' /etc/fstab || \ + ret=$(( ret | 8 )) + ;; + "") + # Pool not found, error printed by zpool(8) + ret=$(( ret | 8 )) + ;; + *) + ;; + esac +done + +exit "$ret" diff --git a/sys/contrib/openzfs/cmd/mount_zfs/mount_zfs.c b/sys/contrib/openzfs/cmd/mount_zfs/mount_zfs.c index 5196c3e5cb5..b9be69d1fb0 100644 --- a/sys/contrib/openzfs/cmd/mount_zfs/mount_zfs.c +++ b/sys/contrib/openzfs/cmd/mount_zfs/mount_zfs.c @@ -185,10 +185,11 @@ main(int argc, char **argv) break; case 'h': case '?': - (void) fprintf(stderr, gettext("Invalid option '%c'\n"), - optopt); + if (optopt) + (void) fprintf(stderr, + gettext("Invalid option '%c'\n"), optopt); (void) fprintf(stderr, gettext("Usage: mount.zfs " - "[-sfnv] [-o options] \n")); + "[-sfnvh] [-o options] \n")); return (MOUNT_USAGE); } } diff --git a/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c b/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c index 9a8be549c5c..c1610a8d1b0 100644 --- a/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c +++ b/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c @@ -37,11 +37,11 @@ static int *rand_data; raidz_test_opts_t rto_opts; -static char gdb[256]; -static const char gdb_tmpl[] = "gdb -ex \"set pagination 0\" -p %d"; +static char pid_s[16]; static void sig_handler(int signo) { + int old_errno = errno; struct sigaction action; /* * Restore default action and re-raise signal so SIGSEGV and @@ -52,10 +52,19 @@ static void sig_handler(int signo) action.sa_flags = 0; (void) sigaction(signo, &action, NULL); - if (rto_opts.rto_gdb) - if (system(gdb)) { } + if (rto_opts.rto_gdb) { + pid_t pid = fork(); + if (pid == 0) { + execlp("gdb", "gdb", "-ex", "set pagination 0", + "-p", pid_s, NULL); + _exit(-1); + } else if (pid > 0) + while (waitpid(pid, NULL, 0) == -1 && errno == EINTR) + ; + } raise(signo); + errno = old_errno; } static void print_opts(raidz_test_opts_t *opts, boolean_t force) @@ -978,8 +987,8 @@ main(int argc, char **argv) struct sigaction action; int err = 0; - /* init gdb string early */ - (void) sprintf(gdb, gdb_tmpl, getpid()); + /* init gdb pid string early */ + (void) sprintf(pid_s, "%d", getpid()); action.sa_handler = sig_handler; sigemptyset(&action.sa_mask); diff --git a/sys/contrib/openzfs/cmd/vdev_id/Makefile.am b/sys/contrib/openzfs/cmd/vdev_id/Makefile.am index fb815faad08..4071c6d5ed6 100644 --- a/sys/contrib/openzfs/cmd/vdev_id/Makefile.am +++ b/sys/contrib/openzfs/cmd/vdev_id/Makefile.am @@ -1 +1,3 @@ +include $(top_srcdir)/config/Shellcheck.am + dist_udev_SCRIPTS = vdev_id diff --git a/sys/contrib/openzfs/cmd/vdev_id/vdev_id b/sys/contrib/openzfs/cmd/vdev_id/vdev_id index d8918da1078..d349ba43ca9 100755 --- a/sys/contrib/openzfs/cmd/vdev_id/vdev_id +++ b/sys/contrib/openzfs/cmd/vdev_id/vdev_id @@ -147,8 +147,9 @@ map_slot() { LINUX_SLOT=$1 CHANNEL=$2 - MAPPED_SLOT=$(awk '$1 == "slot" && $2 == "${LINUX_SLOT}" && \ - $4 ~ /^${CHANNEL}$|^$/ { print $3; exit}' $CONFIG) + MAPPED_SLOT=$(awk -v linux_slot="$LINUX_SLOT" -v channel="$CHANNEL" \ + '$1 == "slot" && $2 == linux_slot && \ + ($4 ~ "^"channel"$" || $4 ~ /^$/) { print $3; exit}' $CONFIG) if [ -z "$MAPPED_SLOT" ] ; then MAPPED_SLOT=$LINUX_SLOT fi @@ -163,7 +164,7 @@ map_channel() { case $TOPOLOGY in "sas_switch") MAPPED_CHAN=$(awk -v port="$PORT" \ - '$1 == "channel" && $2 == ${PORT} \ + '$1 == "channel" && $2 == port \ { print $3; exit }' $CONFIG) ;; "sas_direct"|"scsi") diff --git a/sys/contrib/openzfs/cmd/zdb/zdb.c b/sys/contrib/openzfs/cmd/zdb/zdb.c index f7a6e17d70e..5017a0e7d5d 100644 --- a/sys/contrib/openzfs/cmd/zdb/zdb.c +++ b/sys/contrib/openzfs/cmd/zdb/zdb.c @@ -32,6 +32,7 @@ * [1] Portions of this software were developed by Allan Jude * under sponsorship from the FreeBSD Foundation. * Copyright (c) 2021 Allan Jude + * Copyright (c) 2021 Toomas Soome */ #include @@ -162,12 +163,6 @@ static int dump_bpobj_cb(void *arg, const blkptr_t *bp, boolean_t free, dmu_tx_t *tx); typedef struct sublivelist_verify { - /* all ALLOC'd blkptr_t in one sub-livelist */ - zfs_btree_t sv_all_allocs; - - /* all FREE'd blkptr_t in one sub-livelist */ - zfs_btree_t sv_all_frees; - /* FREE's that haven't yet matched to an ALLOC, in one sub-livelist */ zfs_btree_t sv_pair; @@ -226,29 +221,68 @@ typedef struct sublivelist_verify_block { static void zdb_print_blkptr(const blkptr_t *bp, int flags); +typedef struct sublivelist_verify_block_refcnt { + /* block pointer entry in livelist being verified */ + blkptr_t svbr_blk; + + /* + * Refcount gets incremented to 1 when we encounter the first + * FREE entry for the svfbr block pointer and a node for it + * is created in our ZDB verification/tracking metadata. + * + * As we encounter more FREE entries we increment this counter + * and similarly decrement it whenever we find the respective + * ALLOC entries for this block. + * + * When the refcount gets to 0 it means that all the FREE and + * ALLOC entries of this block have paired up and we no longer + * need to track it in our verification logic (e.g. the node + * containing this struct in our verification data structure + * should be freed). + * + * [refer to sublivelist_verify_blkptr() for the actual code] + */ + uint32_t svbr_refcnt; +} sublivelist_verify_block_refcnt_t; + +static int +sublivelist_block_refcnt_compare(const void *larg, const void *rarg) +{ + const sublivelist_verify_block_refcnt_t *l = larg; + const sublivelist_verify_block_refcnt_t *r = rarg; + return (livelist_compare(&l->svbr_blk, &r->svbr_blk)); +} + static int sublivelist_verify_blkptr(void *arg, const blkptr_t *bp, boolean_t free, dmu_tx_t *tx) { ASSERT3P(tx, ==, NULL); struct sublivelist_verify *sv = arg; - char blkbuf[BP_SPRINTF_LEN]; + sublivelist_verify_block_refcnt_t current = { + .svbr_blk = *bp, + + /* + * Start with 1 in case this is the first free entry. + * This field is not used for our B-Tree comparisons + * anyway. + */ + .svbr_refcnt = 1, + }; + zfs_btree_index_t where; + sublivelist_verify_block_refcnt_t *pair = + zfs_btree_find(&sv->sv_pair, ¤t, &where); if (free) { - zfs_btree_add(&sv->sv_pair, bp); - /* Check if the FREE is a duplicate */ - if (zfs_btree_find(&sv->sv_all_frees, bp, &where) != NULL) { - snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp, - free); - (void) printf("\tERROR: Duplicate FREE: %s\n", blkbuf); + if (pair == NULL) { + /* first free entry for this block pointer */ + zfs_btree_add(&sv->sv_pair, ¤t); } else { - zfs_btree_add_idx(&sv->sv_all_frees, bp, &where); + pair->svbr_refcnt++; } } else { - /* Check if the ALLOC has been freed */ - if (zfs_btree_find(&sv->sv_pair, bp, &where) != NULL) { - zfs_btree_remove_idx(&sv->sv_pair, &where); - } else { + if (pair == NULL) { + /* block that is currently marked as allocated */ for (int i = 0; i < SPA_DVAS_PER_BP; i++) { if (DVA_IS_EMPTY(&bp->blk_dva[i])) break; @@ -263,16 +297,16 @@ sublivelist_verify_blkptr(void *arg, const blkptr_t *bp, boolean_t free, &svb, &where); } } - } - /* Check if the ALLOC is a duplicate */ - if (zfs_btree_find(&sv->sv_all_allocs, bp, &where) != NULL) { - snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp, - free); - (void) printf("\tERROR: Duplicate ALLOC: %s\n", blkbuf); } else { - zfs_btree_add_idx(&sv->sv_all_allocs, bp, &where); + /* alloc matches a free entry */ + pair->svbr_refcnt--; + if (pair->svbr_refcnt == 0) { + /* all allocs and frees have been matched */ + zfs_btree_remove_idx(&sv->sv_pair, &where); + } } } + return (0); } @@ -280,32 +314,22 @@ static int sublivelist_verify_func(void *args, dsl_deadlist_entry_t *dle) { int err; - char blkbuf[BP_SPRINTF_LEN]; struct sublivelist_verify *sv = args; - zfs_btree_create(&sv->sv_all_allocs, livelist_compare, - sizeof (blkptr_t)); - - zfs_btree_create(&sv->sv_all_frees, livelist_compare, - sizeof (blkptr_t)); - - zfs_btree_create(&sv->sv_pair, livelist_compare, - sizeof (blkptr_t)); + zfs_btree_create(&sv->sv_pair, sublivelist_block_refcnt_compare, + sizeof (sublivelist_verify_block_refcnt_t)); err = bpobj_iterate_nofree(&dle->dle_bpobj, sublivelist_verify_blkptr, sv, NULL); - zfs_btree_clear(&sv->sv_all_allocs); - zfs_btree_destroy(&sv->sv_all_allocs); - - zfs_btree_clear(&sv->sv_all_frees); - zfs_btree_destroy(&sv->sv_all_frees); - - blkptr_t *e; + sublivelist_verify_block_refcnt_t *e; zfs_btree_index_t *cookie = NULL; while ((e = zfs_btree_destroy_nodes(&sv->sv_pair, &cookie)) != NULL) { - snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), e, B_TRUE); - (void) printf("\tERROR: Unmatched FREE: %s\n", blkbuf); + char blkbuf[BP_SPRINTF_LEN]; + snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), + &e->svbr_blk, B_TRUE); + (void) printf("\tERROR: %d unmatched FREE(s): %s\n", + e->svbr_refcnt, blkbuf); } zfs_btree_destroy(&sv->sv_pair); @@ -614,10 +638,14 @@ mv_populate_livelist_allocs(metaslab_verify_t *mv, sublivelist_verify_t *sv) /* * [Livelist Check] * Iterate through all the sublivelists and: - * - report leftover frees - * - report double ALLOCs/FREEs + * - report leftover frees (**) * - record leftover ALLOCs together with their TXG [see Cross Check] * + * (**) Note: Double ALLOCs are valid in datasets that have dedup + * enabled. Similarly double FREEs are allowed as well but + * only if they pair up with a corresponding ALLOC entry once + * we our done with our sublivelist iteration. + * * [Spacemap Check] * for each metaslab: * - iterate over spacemap and then the metaslab's entries in the @@ -2066,10 +2094,7 @@ dump_history(spa_t *spa) uint64_t resid, len, off = 0; uint_t num = 0; int error; - time_t tsec; - struct tm t; char tbuf[30]; - char internalstr[MAXPATHLEN]; if ((buf = malloc(SPA_OLD_MAXBLOCKSIZE)) == NULL) { (void) fprintf(stderr, "%s: unable to allocate I/O buffer\n", @@ -2095,38 +2120,81 @@ dump_history(spa_t *spa) (void) printf("\nHistory:\n"); for (unsigned i = 0; i < num; i++) { - uint64_t time, txg, ievent; - char *cmd, *intstr; boolean_t printed = B_FALSE; - if (nvlist_lookup_uint64(events[i], ZPOOL_HIST_TIME, - &time) != 0) - goto next; - if (nvlist_lookup_string(events[i], ZPOOL_HIST_CMD, - &cmd) != 0) { - if (nvlist_lookup_uint64(events[i], - ZPOOL_HIST_INT_EVENT, &ievent) != 0) - goto next; - verify(nvlist_lookup_uint64(events[i], - ZPOOL_HIST_TXG, &txg) == 0); - verify(nvlist_lookup_string(events[i], - ZPOOL_HIST_INT_STR, &intstr) == 0); + if (nvlist_exists(events[i], ZPOOL_HIST_TIME)) { + time_t tsec; + struct tm t; + + tsec = fnvlist_lookup_uint64(events[i], + ZPOOL_HIST_TIME); + (void) localtime_r(&tsec, &t); + (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); + } else { + tbuf[0] = '\0'; + } + + if (nvlist_exists(events[i], ZPOOL_HIST_CMD)) { + (void) printf("%s %s\n", tbuf, + fnvlist_lookup_string(events[i], ZPOOL_HIST_CMD)); + } else if (nvlist_exists(events[i], ZPOOL_HIST_INT_EVENT)) { + uint64_t ievent; + + ievent = fnvlist_lookup_uint64(events[i], + ZPOOL_HIST_INT_EVENT); if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) goto next; - (void) snprintf(internalstr, - sizeof (internalstr), - "[internal %s txg:%lld] %s", + (void) printf(" %s [internal %s txg:%ju] %s\n", + tbuf, zfs_history_event_names[ievent], - (longlong_t)txg, intstr); - cmd = internalstr; - } - tsec = time; - (void) localtime_r(&tsec, &t); - (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); - (void) printf("%s %s\n", tbuf, cmd); - printed = B_TRUE; + fnvlist_lookup_uint64(events[i], + ZPOOL_HIST_TXG), + fnvlist_lookup_string(events[i], + ZPOOL_HIST_INT_STR)); + } else if (nvlist_exists(events[i], ZPOOL_HIST_INT_NAME)) { + (void) printf("%s [txg:%ju] %s", tbuf, + fnvlist_lookup_uint64(events[i], + ZPOOL_HIST_TXG), + fnvlist_lookup_string(events[i], + ZPOOL_HIST_INT_NAME)); + if (nvlist_exists(events[i], ZPOOL_HIST_DSNAME)) { + (void) printf(" %s (%llu)", + fnvlist_lookup_string(events[i], + ZPOOL_HIST_DSNAME), + (u_longlong_t)fnvlist_lookup_uint64( + events[i], + ZPOOL_HIST_DSID)); + } + + (void) printf(" %s\n", fnvlist_lookup_string(events[i], + ZPOOL_HIST_INT_STR)); + } else if (nvlist_exists(events[i], ZPOOL_HIST_IOCTL)) { + (void) printf("%s ioctl %s\n", tbuf, + fnvlist_lookup_string(events[i], + ZPOOL_HIST_IOCTL)); + + if (nvlist_exists(events[i], ZPOOL_HIST_INPUT_NVL)) { + (void) printf(" input:\n"); + dump_nvlist(fnvlist_lookup_nvlist(events[i], + ZPOOL_HIST_INPUT_NVL), 8); + } + if (nvlist_exists(events[i], ZPOOL_HIST_OUTPUT_NVL)) { + (void) printf(" output:\n"); + dump_nvlist(fnvlist_lookup_nvlist(events[i], + ZPOOL_HIST_OUTPUT_NVL), 8); + } + if (nvlist_exists(events[i], ZPOOL_HIST_ERRNO)) { + (void) printf(" errno: %lld\n", + (longlong_t)fnvlist_lookup_int64(events[i], + ZPOOL_HIST_ERRNO)); + } + } else { + goto next; + } + + printed = B_TRUE; next: if (dump_opt['h'] > 1) { if (!printed) @@ -3550,7 +3618,7 @@ static int parse_object_range(char *range, zopt_object_range_t *zor, char **msg) { uint64_t flags = 0; - char *p, *s, *dup, *flagstr; + char *p, *s, *dup, *flagstr, *tmp = NULL; size_t len; int i; int rc = 0; @@ -3579,7 +3647,7 @@ parse_object_range(char *range, zopt_object_range_t *zor, char **msg) } dup = strdup(range); - s = strtok(dup, ":"); + s = strtok_r(dup, ":", &tmp); zor->zor_obj_start = strtoull(s, &p, 0); if (*p != '\0') { @@ -3588,7 +3656,7 @@ parse_object_range(char *range, zopt_object_range_t *zor, char **msg) goto out; } - s = strtok(NULL, ":"); + s = strtok_r(NULL, ":", &tmp); zor->zor_obj_end = strtoull(s, &p, 0); if (*p != '\0') { @@ -3603,11 +3671,11 @@ parse_object_range(char *range, zopt_object_range_t *zor, char **msg) goto out; } - s = strtok(NULL, ":"); + s = strtok_r(NULL, ":", &tmp); if (s == NULL) { zor->zor_flags = ZOR_FLAG_ALL_TYPES; goto out; - } else if (strtok(NULL, ":") != NULL) { + } else if (strtok_r(NULL, ":", &tmp) != NULL) { *msg = "Invalid colon-delimited field after flags"; rc = 1; goto out; @@ -5932,7 +6000,8 @@ zdb_leak_init_prepare_indirect_vdevs(spa_t *spa, zdb_cb_t *zcb) vdev_metaslab_group_create(vd); VERIFY0(vdev_metaslab_init(vd, 0)); - vdev_indirect_mapping_t *vim = vd->vdev_indirect_mapping; + vdev_indirect_mapping_t *vim __maybe_unused = + vd->vdev_indirect_mapping; uint64_t vim_idx = 0; for (uint64_t m = 0; m < vd->vdev_ms_count; m++) { @@ -7041,7 +7110,7 @@ verify_checkpoint_vdev_spacemaps(spa_t *checkpoint, spa_t *current) for (uint64_t c = ckpoint_rvd->vdev_children; c < current_rvd->vdev_children; c++) { vdev_t *current_vd = current_rvd->vdev_child[c]; - ASSERT3P(current_vd->vdev_checkpoint_sm, ==, NULL); + VERIFY3P(current_vd->vdev_checkpoint_sm, ==, NULL); } } @@ -7817,15 +7886,15 @@ name_from_objset_id(spa_t *spa, uint64_t objset_id, char *outstr) static boolean_t zdb_parse_block_sizes(char *sizes, uint64_t *lsize, uint64_t *psize) { - char *s0, *s1; + char *s0, *s1, *tmp = NULL; if (sizes == NULL) return (B_FALSE); - s0 = strtok(sizes, "/"); + s0 = strtok_r(sizes, "/", &tmp); if (s0 == NULL) return (B_FALSE); - s1 = strtok(NULL, "/"); + s1 = strtok_r(NULL, "/", &tmp); *lsize = strtoull(s0, NULL, 16); *psize = s1 ? strtoull(s1, NULL, 16) : *lsize; return (*lsize >= *psize && *psize > 0); @@ -7900,7 +7969,6 @@ zdb_decompress_block(abd_t *pabd, void *buf, void *lbuf, uint64_t lsize, if (lsize > maxlsize) { exceeded = B_TRUE; } - buf = lbuf; if (*cfuncp == ZIO_COMPRESS_ZLE) { printf("\nZLE decompression was selected. If you " "suspect the results are wrong,\ntry avoiding ZLE " @@ -7942,20 +8010,21 @@ zdb_read_block(char *thing, spa_t *spa) vdev_t *vd; abd_t *pabd; void *lbuf, *buf; - char *s, *p, *dup, *vdev, *flagstr, *sizes; + char *s, *p, *dup, *vdev, *flagstr, *sizes, *tmp = NULL; int i, error; boolean_t borrowed = B_FALSE, found = B_FALSE; dup = strdup(thing); - s = strtok(dup, ":"); + s = strtok_r(dup, ":", &tmp); vdev = s ? s : ""; - s = strtok(NULL, ":"); + s = strtok_r(NULL, ":", &tmp); offset = strtoull(s ? s : "", NULL, 16); - sizes = strtok(NULL, ":"); - s = strtok(NULL, ":"); + sizes = strtok_r(NULL, ":", &tmp); + s = strtok_r(NULL, ":", &tmp); flagstr = strdup(s ? s : ""); s = NULL; + tmp = NULL; if (!zdb_parse_block_sizes(sizes, &lsize, &psize)) s = "invalid size(s)"; if (!IS_P2ALIGNED(psize, DEV_BSIZE) || !IS_P2ALIGNED(lsize, DEV_BSIZE)) @@ -7967,7 +8036,9 @@ zdb_read_block(char *thing, spa_t *spa) goto done; } - for (s = strtok(flagstr, ":"); s; s = strtok(NULL, ":")) { + for (s = strtok_r(flagstr, ":", &tmp); + s != NULL; + s = strtok_r(NULL, ":", &tmp)) { for (i = 0; i < strlen(flagstr); i++) { int bit = flagbits[(uchar_t)flagstr[i]]; @@ -8451,7 +8522,7 @@ main(int argc, char **argv) dump_opt[c] += verbose; } - aok = (dump_opt['A'] == 1) || (dump_opt['A'] > 2); + libspl_assert_ok = (dump_opt['A'] == 1) || (dump_opt['A'] > 2); zfs_recover = (dump_opt['A'] > 1); argc -= optind; diff --git a/sys/contrib/openzfs/cmd/zed/Makefile.am b/sys/contrib/openzfs/cmd/zed/Makefile.am index 7d2fe124fb6..7b662994d1c 100644 --- a/sys/contrib/openzfs/cmd/zed/Makefile.am +++ b/sys/contrib/openzfs/cmd/zed/Makefile.am @@ -1,8 +1,10 @@ include $(top_srcdir)/config/Rules.am +include $(top_srcdir)/config/Shellcheck.am AM_CFLAGS += $(LIBUDEV_CFLAGS) $(LIBUUID_CFLAGS) SUBDIRS = zed.d +SHELLCHECKDIRS = $(SUBDIRS) sbin_PROGRAMS = zed @@ -43,7 +45,7 @@ zed_LDADD = \ $(abs_top_builddir)/lib/libnvpair/libnvpair.la \ $(abs_top_builddir)/lib/libuutil/libuutil.la -zed_LDADD += -lrt $(LIBUDEV_LIBS) $(LIBUUID_LIBS) +zed_LDADD += -lrt $(LIBATOMIC_LIBS) $(LIBUDEV_LIBS) $(LIBUUID_LIBS) zed_LDFLAGS = -pthread EXTRA_DIST = agents/README.md diff --git a/sys/contrib/openzfs/cmd/zed/agents/zfs_agents.c b/sys/contrib/openzfs/cmd/zed/agents/zfs_agents.c index 67b7951b0e6..35dd818ff80 100644 --- a/sys/contrib/openzfs/cmd/zed/agents/zfs_agents.c +++ b/sys/contrib/openzfs/cmd/zed/agents/zfs_agents.c @@ -392,6 +392,7 @@ zfs_agent_init(libzfs_handle_t *zfs_hdl) list_destroy(&agent_events); zed_log_die("Failed to initialize agents"); } + pthread_setname_np(g_agents_tid, "agents"); } void diff --git a/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c b/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c index 4a58e1f1dbd..b564f2b12a2 100644 --- a/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c +++ b/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c @@ -918,6 +918,7 @@ zfs_slm_init() return (-1); } + pthread_setname_np(g_zfs_tid, "enum-pools"); list_create(&g_device_list, sizeof (struct pendingdev), offsetof(struct pendingdev, pd_node)); diff --git a/sys/contrib/openzfs/cmd/zed/zed.c b/sys/contrib/openzfs/cmd/zed/zed.c index 907b8af0d01..0aa03fded46 100644 --- a/sys/contrib/openzfs/cmd/zed/zed.c +++ b/sys/contrib/openzfs/cmd/zed/zed.c @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). @@ -60,8 +60,8 @@ _setup_sig_handlers(void) zed_log_die("Failed to initialize sigset"); sa.sa_flags = SA_RESTART; - sa.sa_handler = SIG_IGN; + sa.sa_handler = SIG_IGN; if (sigaction(SIGPIPE, &sa, NULL) < 0) zed_log_die("Failed to ignore SIGPIPE"); @@ -75,6 +75,10 @@ _setup_sig_handlers(void) sa.sa_handler = _hup_handler; if (sigaction(SIGHUP, &sa, NULL) < 0) zed_log_die("Failed to register SIGHUP handler"); + + (void) sigaddset(&sa.sa_mask, SIGCHLD); + if (pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL) < 0) + zed_log_die("Failed to block SIGCHLD"); } /* @@ -212,22 +216,20 @@ _finish_daemonize(void) int main(int argc, char *argv[]) { - struct zed_conf *zcp; + struct zed_conf zcp; uint64_t saved_eid; int64_t saved_etime[2]; zed_log_init(argv[0]); zed_log_stderr_open(LOG_NOTICE); - zcp = zed_conf_create(); - zed_conf_parse_opts(zcp, argc, argv); - if (zcp->do_verbose) + zed_conf_init(&zcp); + zed_conf_parse_opts(&zcp, argc, argv); + if (zcp.do_verbose) zed_log_stderr_open(LOG_INFO); if (geteuid() != 0) zed_log_die("Must be run as root"); - zed_conf_parse_file(zcp); - zed_file_close_from(STDERR_FILENO + 1); (void) umask(0); @@ -235,32 +237,32 @@ main(int argc, char *argv[]) if (chdir("/") < 0) zed_log_die("Failed to change to root directory"); - if (zed_conf_scan_dir(zcp) < 0) + if (zed_conf_scan_dir(&zcp) < 0) exit(EXIT_FAILURE); - if (!zcp->do_foreground) { + if (!zcp.do_foreground) { _start_daemonize(); zed_log_syslog_open(LOG_DAEMON); } _setup_sig_handlers(); - if (zcp->do_memlock) + if (zcp.do_memlock) _lock_memory(); - if ((zed_conf_write_pid(zcp) < 0) && (!zcp->do_force)) + if ((zed_conf_write_pid(&zcp) < 0) && (!zcp.do_force)) exit(EXIT_FAILURE); - if (!zcp->do_foreground) + if (!zcp.do_foreground) _finish_daemonize(); zed_log_msg(LOG_NOTICE, "ZFS Event Daemon %s-%s (PID %d)", ZFS_META_VERSION, ZFS_META_RELEASE, (int)getpid()); - if (zed_conf_open_state(zcp) < 0) + if (zed_conf_open_state(&zcp) < 0) exit(EXIT_FAILURE); - if (zed_conf_read_state(zcp, &saved_eid, saved_etime) < 0) + if (zed_conf_read_state(&zcp, &saved_eid, saved_etime) < 0) exit(EXIT_FAILURE); idle: @@ -269,24 +271,24 @@ idle: * successful. */ do { - if (!zed_event_init(zcp)) + if (!zed_event_init(&zcp)) break; /* Wait for some time and try again. tunable? */ sleep(30); - } while (!_got_exit && zcp->do_idle); + } while (!_got_exit && zcp.do_idle); if (_got_exit) goto out; - zed_event_seek(zcp, saved_eid, saved_etime); + zed_event_seek(&zcp, saved_eid, saved_etime); while (!_got_exit) { int rv; if (_got_hup) { _got_hup = 0; - (void) zed_conf_scan_dir(zcp); + (void) zed_conf_scan_dir(&zcp); } - rv = zed_event_service(zcp); + rv = zed_event_service(&zcp); /* ENODEV: When kernel module is unloaded (osx) */ if (rv == ENODEV) @@ -294,13 +296,13 @@ idle: } zed_log_msg(LOG_NOTICE, "Exiting"); - zed_event_fini(zcp); + zed_event_fini(&zcp); - if (zcp->do_idle && !_got_exit) + if (zcp.do_idle && !_got_exit) goto idle; out: - zed_conf_destroy(zcp); + zed_conf_destroy(&zcp); zed_log_fini(); exit(EXIT_SUCCESS); } diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am b/sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am index 8b2d0c20028..3eece353ef9 100644 --- a/sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am +++ b/sys/contrib/openzfs/cmd/zed/zed.d/Makefile.am @@ -1,5 +1,6 @@ include $(top_srcdir)/config/Rules.am include $(top_srcdir)/config/Substfiles.am +include $(top_srcdir)/config/Shellcheck.am EXTRA_DIST += README diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/data-notify.sh b/sys/contrib/openzfs/cmd/zed/zed.d/data-notify.sh index 639b459bdd3..792d30a66d2 100755 --- a/sys/contrib/openzfs/cmd/zed/zed.d/data-notify.sh +++ b/sys/contrib/openzfs/cmd/zed/zed.d/data-notify.sh @@ -25,7 +25,7 @@ zed_rate_limit "${rate_limit_tag}" || exit 3 umask 077 note_subject="ZFS ${ZEVENT_SUBCLASS} error for ${ZEVENT_POOL} on $(hostname)" -note_pathname="${TMPDIR:="/tmp"}/$(basename -- "$0").${ZEVENT_EID}.$$" +note_pathname="$(mktemp)" { echo "ZFS has detected a data error:" echo diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/generic-notify.sh b/sys/contrib/openzfs/cmd/zed/zed.d/generic-notify.sh index e438031a088..1db26980c1a 100755 --- a/sys/contrib/openzfs/cmd/zed/zed.d/generic-notify.sh +++ b/sys/contrib/openzfs/cmd/zed/zed.d/generic-notify.sh @@ -31,7 +31,7 @@ umask 077 pool_str="${ZEVENT_POOL:+" for ${ZEVENT_POOL}"}" host_str=" on $(hostname)" note_subject="ZFS ${ZEVENT_SUBCLASS} event${pool_str}${host_str}" -note_pathname="${TMPDIR:="/tmp"}/$(basename -- "$0").${ZEVENT_EID}.$$" +note_pathname="$(mktemp)" { echo "ZFS has posted the following event:" echo diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in b/sys/contrib/openzfs/cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in index bf5a121f6a7..15f0a8ed618 100755 --- a/sys/contrib/openzfs/cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in +++ b/sys/contrib/openzfs/cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in @@ -14,10 +14,10 @@ FSLIST="${FSLIST_DIR}/${ZEVENT_POOL}" . "${ZED_ZEDLET_DIR}/zed-functions.sh" [ "$ZEVENT_SUBCLASS" != "history_event" ] && exit 0 -zed_check_cmd "${ZFS}" sort diff grep +zed_check_cmd "${ZFS}" sort diff # If we are acting on a snapshot, we have nothing to do -printf '%s' "${ZEVENT_HISTORY_DSNAME}" | grep '@' && exit 0 +[ "${ZEVENT_HISTORY_DSNAME%@*}" = "${ZEVENT_HISTORY_DSNAME}" ] || exit 0 # We obtain a lock on zfs-list to avoid any simultaneous writes. # If we run into trouble, log and drop the lock diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/scrub_finish-notify.sh b/sys/contrib/openzfs/cmd/zed/zed.d/scrub_finish-notify.sh index 2145a100a3f..5c0124b8d7e 100755 --- a/sys/contrib/openzfs/cmd/zed/zed.d/scrub_finish-notify.sh +++ b/sys/contrib/openzfs/cmd/zed/zed.d/scrub_finish-notify.sh @@ -41,7 +41,7 @@ fi umask 077 note_subject="ZFS ${ZEVENT_SUBCLASS} event for ${ZEVENT_POOL} on $(hostname)" -note_pathname="${TMPDIR:="/tmp"}/$(basename -- "$0").${ZEVENT_EID}.$$" +note_pathname="$(mktemp)" { echo "ZFS has finished a ${action}:" echo diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/statechange-led.sh b/sys/contrib/openzfs/cmd/zed/zed.d/statechange-led.sh index e656e125d37..0f9da320431 100755 --- a/sys/contrib/openzfs/cmd/zed/zed.d/statechange-led.sh +++ b/sys/contrib/openzfs/cmd/zed/zed.d/statechange-led.sh @@ -1,21 +1,21 @@ #!/bin/sh # -# Turn off/on the VDEV's enclosure fault LEDs when the pool's state changes. +# Turn off/on vdevs' enclosure fault LEDs when their pool's state changes. # -# Turn the VDEV's fault LED on if it becomes FAULTED, DEGRADED or UNAVAIL. -# Turn the LED off when it's back ONLINE again. +# Turn a vdev's fault LED on if it becomes FAULTED, DEGRADED or UNAVAIL. +# Turn its LED off when it's back ONLINE again. # # This script run in two basic modes: # # 1. If $ZEVENT_VDEV_ENC_SYSFS_PATH and $ZEVENT_VDEV_STATE_STR are set, then -# only set the LED for that particular VDEV. This is the case for statechange +# only set the LED for that particular vdev. This is the case for statechange # events and some vdev_* events. # -# 2. If those vars are not set, then check the state of all VDEVs in the pool +# 2. If those vars are not set, then check the state of all vdevs in the pool # and set the LEDs accordingly. This is the case for pool_import events. # # Note that this script requires that your enclosure be supported by the -# Linux SCSI enclosure services (ses) driver. The script will do nothing +# Linux SCSI Enclosure services (SES) driver. The script will do nothing # if you have no enclosure, or if your enclosure isn't supported. # # Exit codes: @@ -59,6 +59,10 @@ check_and_set_led() file="$1" val="$2" + if [ -z "$val" ]; then + return 0 + fi + if [ ! -e "$file" ] ; then return 3 fi @@ -66,11 +70,11 @@ check_and_set_led() # If another process is accessing the LED when we attempt to update it, # the update will be lost so retry until the LED actually changes or we # timeout. - for _ in $(seq 1 5); do + for _ in 1 2 3 4 5; do # We want to check the current state first, since writing to the # 'fault' entry always causes a SES command, even if the # current state is already what you want. - current=$(cat "${file}") + read -r current < "${file}" # On some enclosures if you write 1 to fault, and read it back, # it will return 2. Treat all non-zero values as 1 for @@ -85,27 +89,29 @@ check_and_set_led() else break fi - done + done } state_to_val() { state="$1" - if [ "$state" = "FAULTED" ] || [ "$state" = "DEGRADED" ] || \ - [ "$state" = "UNAVAIL" ] ; then - echo 1 - elif [ "$state" = "ONLINE" ] ; then - echo 0 - fi + case "$state" in + FAULTED|DEGRADED|UNAVAIL) + echo 1 + ;; + ONLINE) + echo 0 + ;; + esac } -# process_pool ([pool]) +# process_pool (pool) # -# Iterate through a pool (or pools) and set the VDEV's enclosure slot LEDs to -# the VDEV's state. +# Iterate through a pool and set the vdevs' enclosure slot LEDs to +# those vdevs' state. # # Arguments -# pool: Optional pool name. If not specified, iterate though all pools. +# pool: Pool name. # # Return # 0 on success, 3 on missing sysfs path @@ -113,19 +119,22 @@ state_to_val() process_pool() { pool="$1" + + # The output will be the vdevs only (from "grep '/dev/'"): + # + # U45 ONLINE 0 0 0 /dev/sdk 0 + # U46 ONLINE 0 0 0 /dev/sdm 0 + # U47 ONLINE 0 0 0 /dev/sdn 0 + # U50 ONLINE 0 0 0 /dev/sdbn 0 + # + ZPOOL_SCRIPTS_AS_ROOT=1 $ZPOOL status -c upath,fault_led "$pool" | grep '/dev/' | ( rc=0 - - # Lookup all the current LED values and paths in parallel - #shellcheck disable=SC2016 - cmd='echo led_token=$(cat "$VDEV_ENC_SYSFS_PATH/fault"),"$VDEV_ENC_SYSFS_PATH",' - out=$($ZPOOL status -vc "$cmd" "$pool" | grep 'led_token=') - - #shellcheck disable=SC2034 - echo "$out" | while read -r vdev state read write chksum therest; do + while read -r vdev state _ _ _ therest; do # Read out current LED value and path - tmp=$(echo "$therest" | sed 's/^.*led_token=//g') - vdev_enc_sysfs_path=$(echo "$tmp" | awk -F ',' '{print $2}') - current_val=$(echo "$tmp" | awk -F ',' '{print $1}') + # Get dev name (like 'sda') + dev=$(basename "$(echo "$therest" | awk '{print $(NF-1)}')") + vdev_enc_sysfs_path=$(realpath "/sys/class/block/$dev/device/enclosure_device"*) + current_val=$(echo "$therest" | awk '{print $NF}') if [ "$current_val" != "0" ] ; then current_val=1 @@ -137,36 +146,27 @@ process_pool() fi if [ ! -e "$vdev_enc_sysfs_path/fault" ] ; then - #shellcheck disable=SC2030 - rc=1 + rc=3 zed_log_msg "vdev $vdev '$file/fault' doesn't exist" - continue; + continue fi val=$(state_to_val "$state") if [ "$current_val" = "$val" ] ; then # LED is already set correctly - continue; + continue fi if ! check_and_set_led "$vdev_enc_sysfs_path/fault" "$val"; then - rc=1 + rc=3 fi - done - - #shellcheck disable=SC2031 - if [ "$rc" = "0" ] ; then - return 0 - else - # We didn't see a sysfs entry that we wanted to set - return 3 - fi + exit "$rc"; ) } if [ -n "$ZEVENT_VDEV_ENC_SYSFS_PATH" ] && [ -n "$ZEVENT_VDEV_STATE_STR" ] ; then - # Got a statechange for an individual VDEV + # Got a statechange for an individual vdev val=$(state_to_val "$ZEVENT_VDEV_STATE_STR") vdev=$(basename "$ZEVENT_VDEV_PATH") check_and_set_led "$ZEVENT_VDEV_ENC_SYSFS_PATH/fault" "$val" diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/statechange-notify.sh b/sys/contrib/openzfs/cmd/zed/zed.d/statechange-notify.sh index f46080a0323..76f09061c5b 100755 --- a/sys/contrib/openzfs/cmd/zed/zed.d/statechange-notify.sh +++ b/sys/contrib/openzfs/cmd/zed/zed.d/statechange-notify.sh @@ -37,7 +37,7 @@ fi umask 077 note_subject="ZFS device fault for pool ${ZEVENT_POOL_GUID} on $(hostname)" -note_pathname="${TMPDIR:="/tmp"}/$(basename -- "$0").${ZEVENT_EID}.$$" +note_pathname="$(mktemp)" { if [ "${ZEVENT_VDEV_STATE_STR}" = "FAULTED" ] ; then echo "The number of I/O errors associated with a ZFS device exceeded" diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/trim_finish-notify.sh b/sys/contrib/openzfs/cmd/zed/zed.d/trim_finish-notify.sh index 5075302997e..8fdb64531d0 100755 --- a/sys/contrib/openzfs/cmd/zed/zed.d/trim_finish-notify.sh +++ b/sys/contrib/openzfs/cmd/zed/zed.d/trim_finish-notify.sh @@ -19,7 +19,7 @@ zed_check_cmd "${ZPOOL}" || exit 9 umask 077 note_subject="ZFS ${ZEVENT_SUBCLASS} event for ${ZEVENT_POOL} on $(hostname)" -note_pathname="${TMPDIR:="/tmp"}/$(basename -- "$0").${ZEVENT_EID}.$$" +note_pathname="$(mktemp)" { echo "ZFS has finished a trim:" echo diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh b/sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh index 44a9b8d2330..c4ed5aa8ac7 100644 --- a/sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh +++ b/sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh @@ -127,9 +127,7 @@ zed_lock() # Obtain a lock on the file bound to the given file descriptor. # eval "exec ${fd}> '${lockfile}'" - err="$(flock --exclusive "${fd}" 2>&1)" - # shellcheck disable=SC2181 - if [ $? -ne 0 ]; then + if ! err="$(flock --exclusive "${fd}" 2>&1)"; then zed_log_err "failed to lock \"${lockfile}\": ${err}" fi @@ -165,9 +163,7 @@ zed_unlock() fi # Release the lock and close the file descriptor. - err="$(flock --unlock "${fd}" 2>&1)" - # shellcheck disable=SC2181 - if [ $? -ne 0 ]; then + if ! err="$(flock --unlock "${fd}" 2>&1)"; then zed_log_err "failed to unlock \"${lockfile}\": ${err}" fi eval "exec ${fd}>&-" @@ -206,6 +202,10 @@ zed_notify() [ "${rv}" -eq 0 ] && num_success=$((num_success + 1)) [ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1)) + zed_notify_pushover "${subject}" "${pathname}"; rv=$? + [ "${rv}" -eq 0 ] && num_success=$((num_success + 1)) + [ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1)) + [ "${num_success}" -gt 0 ] && return 0 [ "${num_failure}" -gt 0 ] && return 1 return 2 @@ -267,7 +267,7 @@ zed_notify_email() -e "s/@SUBJECT@/${subject}/g")" # shellcheck disable=SC2086 - eval "${ZED_EMAIL_PROG}" ${ZED_EMAIL_OPTS} < "${pathname}" >/dev/null 2>&1 + ${ZED_EMAIL_PROG} ${ZED_EMAIL_OPTS} < "${pathname}" >/dev/null 2>&1 rv=$? if [ "${rv}" -ne 0 ]; then zed_log_err "$(basename "${ZED_EMAIL_PROG}") exit=${rv}" @@ -367,7 +367,7 @@ zed_notify_pushbullet() # # Notification via Slack Webhook . # The Webhook URL (ZED_SLACK_WEBHOOK_URL) identifies this client to the -# Slack channel. +# Slack channel. # # Requires awk, curl, and sed executables to be installed in the standard PATH. # @@ -437,6 +437,84 @@ zed_notify_slack_webhook() return 0 } +# zed_notify_pushover (subject, pathname) +# +# Send a notification via Pushover . +# The access token (ZED_PUSHOVER_TOKEN) identifies this client to the +# Pushover server. The user token (ZED_PUSHOVER_USER) defines the user or +# group to which the notification will be sent. +# +# Requires curl and sed executables to be installed in the standard PATH. +# +# References +# https://pushover.net/api +# +# Arguments +# subject: notification subject +# pathname: pathname containing the notification message (OPTIONAL) +# +# Globals +# ZED_PUSHOVER_TOKEN +# ZED_PUSHOVER_USER +# +# Return +# 0: notification sent +# 1: notification failed +# 2: not configured +# +zed_notify_pushover() +{ + local subject="$1" + local pathname="${2:-"/dev/null"}" + local msg_body + local msg_out + local msg_err + local url="https://api.pushover.net/1/messages.json" + + [ -n "${ZED_PUSHOVER_TOKEN}" ] && [ -n "${ZED_PUSHOVER_USER}" ] || return 2 + + if [ ! -r "${pathname}" ]; then + zed_log_err "pushover cannot read \"${pathname}\"" + return 1 + fi + + zed_check_cmd "curl" "sed" || return 1 + + # Read the message body in. + # + msg_body="$(cat "${pathname}")" + + if [ -z "${msg_body}" ] + then + msg_body=$subject + subject="" + fi + + # Send the POST request and check for errors. + # + msg_out="$( \ + curl \ + --form-string "token=${ZED_PUSHOVER_TOKEN}" \ + --form-string "user=${ZED_PUSHOVER_USER}" \ + --form-string "message=${msg_body}" \ + --form-string "title=${subject}" \ + "${url}" \ + 2>/dev/null \ + )"; rv=$? + if [ "${rv}" -ne 0 ]; then + zed_log_err "curl exit=${rv}" + return 1 + fi + msg_err="$(echo "${msg_out}" \ + | sed -n -e 's/.*"errors" *:.*\[\(.*\)\].*/\1/p')" + if [ -n "${msg_err}" ]; then + zed_log_err "pushover \"${msg_err}"\" + return 1 + fi + return 0 +} + + # zed_rate_limit (tag, [interval]) # # Check whether an event of a given type [tag] has already occurred within the @@ -511,10 +589,8 @@ zed_guid_to_pool() return fi - guid=$(printf "%llu" "$1") - if [ -n "$guid" ] ; then - $ZPOOL get -H -ovalue,name guid | awk '$1=='"$guid"' {print $2}' - fi + guid="$(printf "%u" "$1")" + $ZPOOL get -H -ovalue,name guid | awk '$1 == '"$guid"' {print $2; exit}' } # zed_exit_if_ignoring_this_event diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/zed.rc b/sys/contrib/openzfs/cmd/zed/zed.d/zed.rc index df560f921e6..55da4c1ab30 100644 --- a/sys/contrib/openzfs/cmd/zed/zed.d/zed.rc +++ b/sys/contrib/openzfs/cmd/zed/zed.d/zed.rc @@ -82,6 +82,23 @@ # #ZED_SLACK_WEBHOOK_URL="" +## +# Pushover token. +# This defines the application from which the notification will be sent. +# +# Disabled by default; uncomment to enable. +# ZED_PUSHOVER_USER, below, must also be configured. +# +#ZED_PUSHOVER_TOKEN="" + +## +# Pushover user key. +# This defines which user or group will receive Pushover notifications. +# +# Disabled by default; uncomment to enable. +# ZED_PUSHOVER_TOKEN, above, must also be configured. +#ZED_PUSHOVER_USER="" + ## # Default directory for zed state files. # diff --git a/sys/contrib/openzfs/cmd/zed/zed.h b/sys/contrib/openzfs/cmd/zed/zed.h index be57f1136fe..94f13c2c9da 100644 --- a/sys/contrib/openzfs/cmd/zed/zed.h +++ b/sys/contrib/openzfs/cmd/zed/zed.h @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). @@ -15,11 +15,6 @@ #ifndef ZED_H #define ZED_H -/* - * Absolute path for the default zed configuration file. - */ -#define ZED_CONF_FILE SYSCONFDIR "/zfs/zed.conf" - /* * Absolute path for the default zed pid file. */ @@ -35,16 +30,6 @@ */ #define ZED_ZEDLET_DIR SYSCONFDIR "/zfs/zed.d" -/* - * Reserved for future use. - */ -#define ZED_MAX_EVENTS 0 - -/* - * Reserved for future use. - */ -#define ZED_MIN_EVENTS 0 - /* * String prefix for ZED variables passed via environment variables. */ diff --git a/sys/contrib/openzfs/cmd/zed/zed_conf.c b/sys/contrib/openzfs/cmd/zed/zed_conf.c index c15f01fecb4..2cf2311dbb4 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_conf.c +++ b/sys/contrib/openzfs/cmd/zed/zed_conf.c @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). @@ -32,43 +32,26 @@ #include "zed_strings.h" /* - * Return a new configuration with default values. + * Initialise the configuration with default values. */ -struct zed_conf * -zed_conf_create(void) +void +zed_conf_init(struct zed_conf *zcp) { - struct zed_conf *zcp; + memset(zcp, 0, sizeof (*zcp)); - zcp = calloc(1, sizeof (*zcp)); - if (!zcp) - goto nomem; + /* zcp->zfs_hdl opened in zed_event_init() */ + /* zcp->zedlets created in zed_conf_scan_dir() */ - zcp->syslog_facility = LOG_DAEMON; - zcp->min_events = ZED_MIN_EVENTS; - zcp->max_events = ZED_MAX_EVENTS; - zcp->pid_fd = -1; - zcp->zedlets = NULL; /* created via zed_conf_scan_dir() */ - zcp->state_fd = -1; /* opened via zed_conf_open_state() */ - zcp->zfs_hdl = NULL; /* opened via zed_event_init() */ - zcp->zevent_fd = -1; /* opened via zed_event_init() */ + zcp->pid_fd = -1; /* opened in zed_conf_write_pid() */ + zcp->state_fd = -1; /* opened in zed_conf_open_state() */ + zcp->zevent_fd = -1; /* opened in zed_event_init() */ - if (!(zcp->conf_file = strdup(ZED_CONF_FILE))) - goto nomem; + zcp->max_jobs = 16; - if (!(zcp->pid_file = strdup(ZED_PID_FILE))) - goto nomem; - - if (!(zcp->zedlet_dir = strdup(ZED_ZEDLET_DIR))) - goto nomem; - - if (!(zcp->state_file = strdup(ZED_STATE_FILE))) - goto nomem; - - return (zcp); - -nomem: - zed_log_die("Failed to create conf: %s", strerror(errno)); - return (NULL); + if (!(zcp->pid_file = strdup(ZED_PID_FILE)) || + !(zcp->zedlet_dir = strdup(ZED_ZEDLET_DIR)) || + !(zcp->state_file = strdup(ZED_STATE_FILE))) + zed_log_die("Failed to create conf: %s", strerror(errno)); } /* @@ -79,9 +62,6 @@ nomem: void zed_conf_destroy(struct zed_conf *zcp) { - if (!zcp) - return; - if (zcp->state_fd >= 0) { if (close(zcp->state_fd) < 0) zed_log_msg(LOG_WARNING, @@ -102,10 +82,6 @@ zed_conf_destroy(struct zed_conf *zcp) zcp->pid_file, strerror(errno)); zcp->pid_fd = -1; } - if (zcp->conf_file) { - free(zcp->conf_file); - zcp->conf_file = NULL; - } if (zcp->pid_file) { free(zcp->pid_file); zcp->pid_file = NULL; @@ -122,7 +98,6 @@ zed_conf_destroy(struct zed_conf *zcp) zed_strings_destroy(zcp->zedlets); zcp->zedlets = NULL; } - free(zcp); } /* @@ -132,46 +107,52 @@ zed_conf_destroy(struct zed_conf *zcp) * otherwise, output to stderr and exit with a failure status. */ static void -_zed_conf_display_help(const char *prog, int got_err) +_zed_conf_display_help(const char *prog, boolean_t got_err) { + struct opt { const char *o, *d, *v; }; + FILE *fp = got_err ? stderr : stdout; - int w1 = 4; /* width of leading whitespace */ - int w2 = 8; /* width of L-justified option field */ + + struct opt *oo; + struct opt iopts[] = { + { .o = "-h", .d = "Display help" }, + { .o = "-L", .d = "Display license information" }, + { .o = "-V", .d = "Display version information" }, + {}, + }; + struct opt nopts[] = { + { .o = "-v", .d = "Be verbose" }, + { .o = "-f", .d = "Force daemon to run" }, + { .o = "-F", .d = "Run daemon in the foreground" }, + { .o = "-I", + .d = "Idle daemon until kernel module is (re)loaded" }, + { .o = "-M", .d = "Lock all pages in memory" }, + { .o = "-P", .d = "$PATH for ZED to use (only used by ZTS)" }, + { .o = "-Z", .d = "Zero state file" }, + {}, + }; + struct opt vopts[] = { + { .o = "-d DIR", .d = "Read enabled ZEDLETs from DIR.", + .v = ZED_ZEDLET_DIR }, + { .o = "-p FILE", .d = "Write daemon's PID to FILE.", + .v = ZED_PID_FILE }, + { .o = "-s FILE", .d = "Write daemon's state to FILE.", + .v = ZED_STATE_FILE }, + { .o = "-j JOBS", .d = "Start at most JOBS at once.", + .v = "16" }, + {}, + }; fprintf(fp, "Usage: %s [OPTION]...\n", (prog ? prog : "zed")); fprintf(fp, "\n"); - fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-h", - "Display help."); - fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-L", - "Display license information."); - fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-V", - "Display version information."); + for (oo = iopts; oo->o; ++oo) + fprintf(fp, " %*s %s\n", -8, oo->o, oo->d); fprintf(fp, "\n"); - fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-v", - "Be verbose."); - fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-f", - "Force daemon to run."); - fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-F", - "Run daemon in the foreground."); - fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-I", - "Idle daemon until kernel module is (re)loaded."); - fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-M", - "Lock all pages in memory."); - fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-P", - "$PATH for ZED to use (only used by ZTS)."); - fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-Z", - "Zero state file."); + for (oo = nopts; oo->o; ++oo) + fprintf(fp, " %*s %s\n", -8, oo->o, oo->d); fprintf(fp, "\n"); -#if 0 - fprintf(fp, "%*c%*s %s [%s]\n", w1, 0x20, -w2, "-c FILE", - "Read configuration from FILE.", ZED_CONF_FILE); -#endif - fprintf(fp, "%*c%*s %s [%s]\n", w1, 0x20, -w2, "-d DIR", - "Read enabled ZEDLETs from DIR.", ZED_ZEDLET_DIR); - fprintf(fp, "%*c%*s %s [%s]\n", w1, 0x20, -w2, "-p FILE", - "Write daemon's PID to FILE.", ZED_PID_FILE); - fprintf(fp, "%*c%*s %s [%s]\n", w1, 0x20, -w2, "-s FILE", - "Write daemon's state to FILE.", ZED_STATE_FILE); + for (oo = vopts; oo->o; ++oo) + fprintf(fp, " %*s %s [%s]\n", -8, oo->o, oo->d, oo->v); fprintf(fp, "\n"); exit(got_err ? EXIT_FAILURE : EXIT_SUCCESS); @@ -183,20 +164,14 @@ _zed_conf_display_help(const char *prog, int got_err) static void _zed_conf_display_license(void) { - const char **pp; - const char *text[] = { - "The ZFS Event Daemon (ZED) is distributed under the terms of the", - " Common Development and Distribution License (CDDL-1.0)", - " .", - "", + printf( + "The ZFS Event Daemon (ZED) is distributed under the terms of the\n" + " Common Development and Distribution License (CDDL-1.0)\n" + " .\n" + "\n" "Developed at Lawrence Livermore National Laboratory" - " (LLNL-CODE-403049).", - "", - NULL - }; - - for (pp = text; *pp; pp++) - printf("%s\n", *pp); + " (LLNL-CODE-403049).\n" + "\n"); exit(EXIT_SUCCESS); } @@ -231,16 +206,19 @@ _zed_conf_parse_path(char **resultp, const char *path) if (path[0] == '/') { *resultp = strdup(path); - } else if (!getcwd(buf, sizeof (buf))) { - zed_log_die("Failed to get current working dir: %s", - strerror(errno)); - } else if (strlcat(buf, "/", sizeof (buf)) >= sizeof (buf)) { - zed_log_die("Failed to copy path: %s", strerror(ENAMETOOLONG)); - } else if (strlcat(buf, path, sizeof (buf)) >= sizeof (buf)) { - zed_log_die("Failed to copy path: %s", strerror(ENAMETOOLONG)); } else { + if (!getcwd(buf, sizeof (buf))) + zed_log_die("Failed to get current working dir: %s", + strerror(errno)); + + if (strlcat(buf, "/", sizeof (buf)) >= sizeof (buf) || + strlcat(buf, path, sizeof (buf)) >= sizeof (buf)) + zed_log_die("Failed to copy path: %s", + strerror(ENAMETOOLONG)); + *resultp = strdup(buf); } + if (!*resultp) zed_log_die("Failed to copy path: %s", strerror(ENOMEM)); } @@ -251,8 +229,9 @@ _zed_conf_parse_path(char **resultp, const char *path) void zed_conf_parse_opts(struct zed_conf *zcp, int argc, char **argv) { - const char * const opts = ":hLVc:d:p:P:s:vfFMZI"; + const char * const opts = ":hLVd:p:P:s:vfFMZIj:"; int opt; + unsigned long raw; if (!zcp || !argv || !argv[0]) zed_log_die("Failed to parse options: Internal error"); @@ -262,7 +241,7 @@ zed_conf_parse_opts(struct zed_conf *zcp, int argc, char **argv) while ((opt = getopt(argc, argv, opts)) != -1) { switch (opt) { case 'h': - _zed_conf_display_help(argv[0], EXIT_SUCCESS); + _zed_conf_display_help(argv[0], B_FALSE); break; case 'L': _zed_conf_display_license(); @@ -270,9 +249,6 @@ zed_conf_parse_opts(struct zed_conf *zcp, int argc, char **argv) case 'V': _zed_conf_display_version(); break; - case 'c': - _zed_conf_parse_path(&zcp->conf_file, optarg); - break; case 'd': _zed_conf_parse_path(&zcp->zedlet_dir, optarg); break; @@ -303,31 +279,30 @@ zed_conf_parse_opts(struct zed_conf *zcp, int argc, char **argv) case 'Z': zcp->do_zero = 1; break; + case 'j': + errno = 0; + raw = strtoul(optarg, NULL, 0); + if (errno == ERANGE || raw > INT16_MAX) { + zed_log_die("%lu is too many jobs", raw); + } if (raw == 0) { + zed_log_die("0 jobs makes no sense"); + } else { + zcp->max_jobs = raw; + } + break; case '?': default: if (optopt == '?') - _zed_conf_display_help(argv[0], EXIT_SUCCESS); + _zed_conf_display_help(argv[0], B_FALSE); - fprintf(stderr, "%s: %s '-%c'\n\n", argv[0], - "Invalid option", optopt); - _zed_conf_display_help(argv[0], EXIT_FAILURE); + fprintf(stderr, "%s: Invalid option '-%c'\n\n", + argv[0], optopt); + _zed_conf_display_help(argv[0], B_TRUE); break; } } } -/* - * Parse the configuration file into the configuration [zcp]. - * - * FIXME: Not yet implemented. - */ -void -zed_conf_parse_file(struct zed_conf *zcp) -{ - if (!zcp) - zed_log_die("Failed to parse config: %s", strerror(EINVAL)); -} - /* * Scan the [zcp] zedlet_dir for files to exec based on the event class. * Files must be executable by user, but not writable by group or other. @@ -335,8 +310,6 @@ zed_conf_parse_file(struct zed_conf *zcp) * * Return 0 on success with an updated set of zedlets, * or -1 on error with errno set. - * - * FIXME: Check if zedlet_dir and all parent dirs are secure. */ int zed_conf_scan_dir(struct zed_conf *zcp) @@ -452,8 +425,6 @@ zed_conf_scan_dir(struct zed_conf *zcp) int zed_conf_write_pid(struct zed_conf *zcp) { - const mode_t dirmode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - const mode_t filemode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; char buf[PATH_MAX]; int n; char *p; @@ -481,7 +452,7 @@ zed_conf_write_pid(struct zed_conf *zcp) if (p) *p = '\0'; - if ((mkdirp(buf, dirmode) < 0) && (errno != EEXIST)) { + if ((mkdirp(buf, 0755) < 0) && (errno != EEXIST)) { zed_log_msg(LOG_ERR, "Failed to create directory \"%s\": %s", buf, strerror(errno)); goto err; @@ -491,7 +462,7 @@ zed_conf_write_pid(struct zed_conf *zcp) */ mask = umask(0); umask(mask | 022); - zcp->pid_fd = open(zcp->pid_file, (O_RDWR | O_CREAT), filemode); + zcp->pid_fd = open(zcp->pid_file, O_RDWR | O_CREAT | O_CLOEXEC, 0644); umask(mask); if (zcp->pid_fd < 0) { zed_log_msg(LOG_ERR, "Failed to open PID file \"%s\": %s", @@ -528,7 +499,7 @@ zed_conf_write_pid(struct zed_conf *zcp) errno = ERANGE; zed_log_msg(LOG_ERR, "Failed to write PID file \"%s\": %s", zcp->pid_file, strerror(errno)); - } else if (zed_file_write_n(zcp->pid_fd, buf, n) != n) { + } else if (write(zcp->pid_fd, buf, n) != n) { zed_log_msg(LOG_ERR, "Failed to write PID file \"%s\": %s", zcp->pid_file, strerror(errno)); } else if (fdatasync(zcp->pid_fd) < 0) { @@ -556,7 +527,6 @@ int zed_conf_open_state(struct zed_conf *zcp) { char dirbuf[PATH_MAX]; - mode_t dirmode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; int n; char *p; int rv; @@ -578,7 +548,7 @@ zed_conf_open_state(struct zed_conf *zcp) if (p) *p = '\0'; - if ((mkdirp(dirbuf, dirmode) < 0) && (errno != EEXIST)) { + if ((mkdirp(dirbuf, 0755) < 0) && (errno != EEXIST)) { zed_log_msg(LOG_WARNING, "Failed to create directory \"%s\": %s", dirbuf, strerror(errno)); @@ -596,7 +566,7 @@ zed_conf_open_state(struct zed_conf *zcp) (void) unlink(zcp->state_file); zcp->state_fd = open(zcp->state_file, - (O_RDWR | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); + O_RDWR | O_CREAT | O_CLOEXEC, 0644); if (zcp->state_fd < 0) { zed_log_msg(LOG_WARNING, "Failed to open state file \"%s\": %s", zcp->state_file, strerror(errno)); diff --git a/sys/contrib/openzfs/cmd/zed/zed_conf.h b/sys/contrib/openzfs/cmd/zed/zed_conf.h index f44d2038296..0b30a1503c5 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_conf.h +++ b/sys/contrib/openzfs/cmd/zed/zed_conf.h @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). @@ -20,43 +20,39 @@ #include "zed_strings.h" struct zed_conf { - unsigned do_force:1; /* true if force enabled */ - unsigned do_foreground:1; /* true if run in foreground */ - unsigned do_memlock:1; /* true if locking memory */ - unsigned do_verbose:1; /* true if verbosity enabled */ - unsigned do_zero:1; /* true if zeroing state */ - unsigned do_idle:1; /* true if idle enabled */ - int syslog_facility; /* syslog facility value */ - int min_events; /* RESERVED FOR FUTURE USE */ - int max_events; /* RESERVED FOR FUTURE USE */ - char *conf_file; /* abs path to config file */ char *pid_file; /* abs path to pid file */ - int pid_fd; /* fd to pid file for lock */ char *zedlet_dir; /* abs path to zedlet dir */ - zed_strings_t *zedlets; /* names of enabled zedlets */ char *state_file; /* abs path to state file */ - int state_fd; /* fd to state file */ + libzfs_handle_t *zfs_hdl; /* handle to libzfs */ - int zevent_fd; /* fd for access to zevents */ + zed_strings_t *zedlets; /* names of enabled zedlets */ char *path; /* custom $PATH for zedlets to use */ + + int pid_fd; /* fd to pid file for lock */ + int state_fd; /* fd to state file */ + int zevent_fd; /* fd for access to zevents */ + + int16_t max_jobs; /* max zedlets to run at one time */ + + boolean_t do_force:1; /* true if force enabled */ + boolean_t do_foreground:1; /* true if run in foreground */ + boolean_t do_memlock:1; /* true if locking memory */ + boolean_t do_verbose:1; /* true if verbosity enabled */ + boolean_t do_zero:1; /* true if zeroing state */ + boolean_t do_idle:1; /* true if idle enabled */ }; -struct zed_conf *zed_conf_create(void); - +void zed_conf_init(struct zed_conf *zcp); void zed_conf_destroy(struct zed_conf *zcp); void zed_conf_parse_opts(struct zed_conf *zcp, int argc, char **argv); -void zed_conf_parse_file(struct zed_conf *zcp); - int zed_conf_scan_dir(struct zed_conf *zcp); int zed_conf_write_pid(struct zed_conf *zcp); int zed_conf_open_state(struct zed_conf *zcp); - int zed_conf_read_state(struct zed_conf *zcp, uint64_t *eidp, int64_t etime[]); - int zed_conf_write_state(struct zed_conf *zcp, uint64_t eid, int64_t etime[]); #endif /* !ZED_CONF_H */ diff --git a/sys/contrib/openzfs/cmd/zed/zed_disk_event.c b/sys/contrib/openzfs/cmd/zed/zed_disk_event.c index 174d2452325..6ec566cff3c 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_disk_event.c +++ b/sys/contrib/openzfs/cmd/zed/zed_disk_event.c @@ -379,6 +379,7 @@ zed_disk_event_init() return (-1); } + pthread_setname_np(g_mon_tid, "udev monitor"); zed_log_msg(LOG_INFO, "zed_disk_event_init"); return (0); diff --git a/sys/contrib/openzfs/cmd/zed/zed_event.c b/sys/contrib/openzfs/cmd/zed/zed_event.c index 8892087d6e6..9eaad0e92fb 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_event.c +++ b/sys/contrib/openzfs/cmd/zed/zed_event.c @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). @@ -15,7 +15,7 @@ #include #include #include -#include /* FIXME: Replace with libzfs_core. */ +#include #include #include #include @@ -54,7 +54,7 @@ zed_event_init(struct zed_conf *zcp) zed_log_die("Failed to initialize libzfs"); } - zcp->zevent_fd = open(ZFS_DEV, O_RDWR); + zcp->zevent_fd = open(ZFS_DEV, O_RDWR | O_CLOEXEC); if (zcp->zevent_fd < 0) { if (zcp->do_idle) return (-1); @@ -96,6 +96,47 @@ zed_event_fini(struct zed_conf *zcp) libzfs_fini(zcp->zfs_hdl); zcp->zfs_hdl = NULL; } + + zed_exec_fini(); +} + +static void +_bump_event_queue_length(void) +{ + int zzlm = -1, wr; + char qlen_buf[12] = {0}; /* parameter is int => max "-2147483647\n" */ + long int qlen; + + zzlm = open("/sys/module/zfs/parameters/zfs_zevent_len_max", O_RDWR); + if (zzlm < 0) + goto done; + + if (read(zzlm, qlen_buf, sizeof (qlen_buf)) < 0) + goto done; + qlen_buf[sizeof (qlen_buf) - 1] = '\0'; + + errno = 0; + qlen = strtol(qlen_buf, NULL, 10); + if (errno == ERANGE) + goto done; + + if (qlen <= 0) + qlen = 512; /* default zfs_zevent_len_max value */ + else + qlen *= 2; + + if (qlen > INT_MAX) + qlen = INT_MAX; + wr = snprintf(qlen_buf, sizeof (qlen_buf), "%ld", qlen); + + if (pwrite(zzlm, qlen_buf, wr, 0) < 0) + goto done; + + zed_log_msg(LOG_WARNING, "Bumping queue length to %ld", qlen); + +done: + if (zzlm > -1) + (void) close(zzlm); } /* @@ -136,10 +177,7 @@ zed_event_seek(struct zed_conf *zcp, uint64_t saved_eid, int64_t saved_etime[]) if (n_dropped > 0) { zed_log_msg(LOG_WARNING, "Missed %d events", n_dropped); - /* - * FIXME: Increase max size of event nvlist in - * /sys/module/zfs/parameters/zfs_zevent_len_max ? - */ + _bump_event_queue_length(); } if (nvlist_lookup_uint64(nvl, "eid", &eid) != 0) { zed_log_msg(LOG_WARNING, "Failed to lookup zevent eid"); @@ -211,7 +249,7 @@ _zed_event_value_is_hex(const char *name) * * All environment variables in [zsp] should be added through this function. */ -static int +static __attribute__((format(printf, 5, 6))) int _zed_event_add_var(uint64_t eid, zed_strings_t *zsp, const char *prefix, const char *name, const char *fmt, ...) { @@ -586,8 +624,6 @@ _zed_event_add_string_array(uint64_t eid, zed_strings_t *zsp, * Convert the nvpair [nvp] to a string which is added to the environment * of the child process. * Return 0 on success, -1 on error. - * - * FIXME: Refactor with cmd/zpool/zpool_main.c:zpool_do_events_nvprint()? */ static void _zed_event_add_nvpair(uint64_t eid, zed_strings_t *zsp, nvpair_t *nvp) @@ -686,23 +722,11 @@ _zed_event_add_nvpair(uint64_t eid, zed_strings_t *zsp, nvpair_t *nvp) _zed_event_add_var(eid, zsp, prefix, name, "%llu", (u_longlong_t)i64); break; - case DATA_TYPE_NVLIST: - _zed_event_add_var(eid, zsp, prefix, name, - "%s", "_NOT_IMPLEMENTED_"); /* FIXME */ - break; case DATA_TYPE_STRING: (void) nvpair_value_string(nvp, &str); _zed_event_add_var(eid, zsp, prefix, name, "%s", (str ? str : "")); break; - case DATA_TYPE_BOOLEAN_ARRAY: - _zed_event_add_var(eid, zsp, prefix, name, - "%s", "_NOT_IMPLEMENTED_"); /* FIXME */ - break; - case DATA_TYPE_BYTE_ARRAY: - _zed_event_add_var(eid, zsp, prefix, name, - "%s", "_NOT_IMPLEMENTED_"); /* FIXME */ - break; case DATA_TYPE_INT8_ARRAY: _zed_event_add_int8_array(eid, zsp, prefix, nvp); break; @@ -730,9 +754,11 @@ _zed_event_add_nvpair(uint64_t eid, zed_strings_t *zsp, nvpair_t *nvp) case DATA_TYPE_STRING_ARRAY: _zed_event_add_string_array(eid, zsp, prefix, nvp); break; + case DATA_TYPE_NVLIST: + case DATA_TYPE_BOOLEAN_ARRAY: + case DATA_TYPE_BYTE_ARRAY: case DATA_TYPE_NVLIST_ARRAY: - _zed_event_add_var(eid, zsp, prefix, name, - "%s", "_NOT_IMPLEMENTED_"); /* FIXME */ + _zed_event_add_var(eid, zsp, prefix, name, "_NOT_IMPLEMENTED_"); break; default: errno = EINVAL; @@ -912,10 +938,7 @@ zed_event_service(struct zed_conf *zcp) if (n_dropped > 0) { zed_log_msg(LOG_WARNING, "Missed %d events", n_dropped); - /* - * FIXME: Increase max size of event nvlist in - * /sys/module/zfs/parameters/zfs_zevent_len_max ? - */ + _bump_event_queue_length(); } if (nvlist_lookup_uint64(nvl, "eid", &eid) != 0) { zed_log_msg(LOG_WARNING, "Failed to lookup zevent eid"); @@ -953,8 +976,7 @@ zed_event_service(struct zed_conf *zcp) _zed_event_add_time_strings(eid, zsp, etime); - zed_exec_process(eid, class, subclass, - zcp->zedlet_dir, zcp->zedlets, zsp, zcp->zevent_fd); + zed_exec_process(eid, class, subclass, zcp, zsp); zed_conf_write_state(zcp, eid, etime); diff --git a/sys/contrib/openzfs/cmd/zed/zed_event.h b/sys/contrib/openzfs/cmd/zed/zed_event.h index 264c377ed91..5606f14a21a 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_event.h +++ b/sys/contrib/openzfs/cmd/zed/zed_event.h @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). diff --git a/sys/contrib/openzfs/cmd/zed/zed_exec.c b/sys/contrib/openzfs/cmd/zed/zed_exec.c index e8f51021386..1eecfa0a92c 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_exec.c +++ b/sys/contrib/openzfs/cmd/zed/zed_exec.c @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). @@ -18,17 +18,53 @@ #include #include #include +#include +#include +#include #include #include #include #include +#include #include "zed_exec.h" -#include "zed_file.h" #include "zed_log.h" #include "zed_strings.h" #define ZEVENT_FILENO 3 +struct launched_process_node { + avl_node_t node; + pid_t pid; + uint64_t eid; + char *name; +}; + +static int +_launched_process_node_compare(const void *x1, const void *x2) +{ + pid_t p1; + pid_t p2; + + assert(x1 != NULL); + assert(x2 != NULL); + + p1 = ((const struct launched_process_node *) x1)->pid; + p2 = ((const struct launched_process_node *) x2)->pid; + + if (p1 < p2) + return (-1); + else if (p1 == p2) + return (0); + else + return (1); +} + +static pthread_t _reap_children_tid = (pthread_t)-1; +static volatile boolean_t _reap_children_stop; +static avl_tree_t _launched_processes; +static pthread_mutex_t _launched_processes_lock = PTHREAD_MUTEX_INITIALIZER; +static int16_t _launched_processes_limit; + /* * Create an environment string array for passing to execve() using the * NAME=VALUE strings in container [zsp]. @@ -79,20 +115,26 @@ _zed_exec_create_env(zed_strings_t *zsp) */ static void _zed_exec_fork_child(uint64_t eid, const char *dir, const char *prog, - char *env[], int zfd) + char *env[], int zfd, boolean_t in_foreground) { char path[PATH_MAX]; int n; pid_t pid; int fd; - pid_t wpid; - int status; + struct launched_process_node *node; + sigset_t mask; + struct timespec launch_timeout = + { .tv_sec = 0, .tv_nsec = 200 * 1000 * 1000, }; assert(dir != NULL); assert(prog != NULL); assert(env != NULL); assert(zfd >= 0); + while (__atomic_load_n(&_launched_processes_limit, + __ATOMIC_SEQ_CST) <= 0) + (void) nanosleep(&launch_timeout, NULL); + n = snprintf(path, sizeof (path), "%s/%s", dir, prog); if ((n < 0) || (n >= sizeof (path))) { zed_log_msg(LOG_WARNING, @@ -100,101 +142,179 @@ _zed_exec_fork_child(uint64_t eid, const char *dir, const char *prog, prog, eid, strerror(ENAMETOOLONG)); return; } + (void) pthread_mutex_lock(&_launched_processes_lock); pid = fork(); if (pid < 0) { + (void) pthread_mutex_unlock(&_launched_processes_lock); zed_log_msg(LOG_WARNING, "Failed to fork \"%s\" for eid=%llu: %s", prog, eid, strerror(errno)); return; } else if (pid == 0) { + (void) sigemptyset(&mask); + (void) sigprocmask(SIG_SETMASK, &mask, NULL); + (void) umask(022); - if ((fd = open("/dev/null", O_RDWR)) != -1) { + if (in_foreground && /* we're already devnulled if daemonised */ + (fd = open("/dev/null", O_RDWR | O_CLOEXEC)) != -1) { (void) dup2(fd, STDIN_FILENO); (void) dup2(fd, STDOUT_FILENO); (void) dup2(fd, STDERR_FILENO); } (void) dup2(zfd, ZEVENT_FILENO); - zed_file_close_from(ZEVENT_FILENO + 1); execle(path, prog, NULL, env); _exit(127); } /* parent process */ + node = calloc(1, sizeof (*node)); + if (node) { + node->pid = pid; + node->eid = eid; + node->name = strdup(prog); + + avl_add(&_launched_processes, node); + } + (void) pthread_mutex_unlock(&_launched_processes_lock); + + __atomic_sub_fetch(&_launched_processes_limit, 1, __ATOMIC_SEQ_CST); zed_log_msg(LOG_INFO, "Invoking \"%s\" eid=%llu pid=%d", prog, eid, pid); +} - /* FIXME: Timeout rogue child processes with sigalarm? */ +static void +_nop(int sig) +{} - /* - * Wait for child process using WNOHANG to limit - * the time spent waiting to 10 seconds (10,000ms). - */ - for (n = 0; n < 1000; n++) { - wpid = waitpid(pid, &status, WNOHANG); - if (wpid == (pid_t)-1) { - if (errno == EINTR) - continue; - zed_log_msg(LOG_WARNING, - "Failed to wait for \"%s\" eid=%llu pid=%d", - prog, eid, pid); - break; - } else if (wpid == 0) { - struct timespec t; +static void * +_reap_children(void *arg) +{ + struct launched_process_node node, *pnode; + pid_t pid; + int status; + struct rusage usage; + struct sigaction sa = {}; - /* child still running */ - t.tv_sec = 0; - t.tv_nsec = 10000000; /* 10ms */ - (void) nanosleep(&t, NULL); - continue; - } + (void) sigfillset(&sa.sa_mask); + (void) sigdelset(&sa.sa_mask, SIGCHLD); + (void) pthread_sigmask(SIG_SETMASK, &sa.sa_mask, NULL); - if (WIFEXITED(status)) { - zed_log_msg(LOG_INFO, - "Finished \"%s\" eid=%llu pid=%d exit=%d", - prog, eid, pid, WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) { - zed_log_msg(LOG_INFO, - "Finished \"%s\" eid=%llu pid=%d sig=%d/%s", - prog, eid, pid, WTERMSIG(status), - strsignal(WTERMSIG(status))); + (void) sigemptyset(&sa.sa_mask); + sa.sa_handler = _nop; + sa.sa_flags = SA_NOCLDSTOP; + (void) sigaction(SIGCHLD, &sa, NULL); + + for (_reap_children_stop = B_FALSE; !_reap_children_stop; ) { + (void) pthread_mutex_lock(&_launched_processes_lock); + pid = wait4(0, &status, WNOHANG, &usage); + + if (pid == 0 || pid == (pid_t)-1) { + (void) pthread_mutex_unlock(&_launched_processes_lock); + if (pid == 0 || errno == ECHILD) + pause(); + else if (errno != EINTR) + zed_log_msg(LOG_WARNING, + "Failed to wait for children: %s", + strerror(errno)); } else { - zed_log_msg(LOG_INFO, - "Finished \"%s\" eid=%llu pid=%d status=0x%X", - prog, eid, (unsigned int) status); + memset(&node, 0, sizeof (node)); + node.pid = pid; + pnode = avl_find(&_launched_processes, &node, NULL); + if (pnode) { + memcpy(&node, pnode, sizeof (node)); + + avl_remove(&_launched_processes, pnode); + free(pnode); + } + (void) pthread_mutex_unlock(&_launched_processes_lock); + __atomic_add_fetch(&_launched_processes_limit, 1, + __ATOMIC_SEQ_CST); + + usage.ru_utime.tv_sec += usage.ru_stime.tv_sec; + usage.ru_utime.tv_usec += usage.ru_stime.tv_usec; + usage.ru_utime.tv_sec += + usage.ru_utime.tv_usec / (1000 * 1000); + usage.ru_utime.tv_usec %= 1000 * 1000; + + if (WIFEXITED(status)) { + zed_log_msg(LOG_INFO, + "Finished \"%s\" eid=%llu pid=%d " + "time=%llu.%06us exit=%d", + node.name, node.eid, pid, + (unsigned long long) usage.ru_utime.tv_sec, + (unsigned int) usage.ru_utime.tv_usec, + WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + zed_log_msg(LOG_INFO, + "Finished \"%s\" eid=%llu pid=%d " + "time=%llu.%06us sig=%d/%s", + node.name, node.eid, pid, + (unsigned long long) usage.ru_utime.tv_sec, + (unsigned int) usage.ru_utime.tv_usec, + WTERMSIG(status), + strsignal(WTERMSIG(status))); + } else { + zed_log_msg(LOG_INFO, + "Finished \"%s\" eid=%llu pid=%d " + "time=%llu.%06us status=0x%X", + node.name, node.eid, + (unsigned long long) usage.ru_utime.tv_sec, + (unsigned int) usage.ru_utime.tv_usec, + (unsigned int) status); + } + + free(node.name); } - break; } - /* - * kill child process after 10 seconds - */ - if (wpid == 0) { - zed_log_msg(LOG_WARNING, "Killing hung \"%s\" pid=%d", - prog, pid); - (void) kill(pid, SIGKILL); - (void) waitpid(pid, &status, 0); + return (NULL); +} + +void +zed_exec_fini(void) +{ + struct launched_process_node *node; + void *ck = NULL; + + if (_reap_children_tid == (pthread_t)-1) + return; + + _reap_children_stop = B_TRUE; + (void) pthread_kill(_reap_children_tid, SIGCHLD); + (void) pthread_join(_reap_children_tid, NULL); + + while ((node = avl_destroy_nodes(&_launched_processes, &ck)) != NULL) { + free(node->name); + free(node); } + avl_destroy(&_launched_processes); + + (void) pthread_mutex_destroy(&_launched_processes_lock); + (void) pthread_mutex_init(&_launched_processes_lock, NULL); + + _reap_children_tid = (pthread_t)-1; } /* * Process the event [eid] by synchronously invoking all zedlets with a * matching class prefix. * - * Each executable in [zedlets] from the directory [dir] is matched against - * the event's [class], [subclass], and the "all" class (which matches - * all events). Every zedlet with a matching class prefix is invoked. + * Each executable in [zcp->zedlets] from the directory [zcp->zedlet_dir] + * is matched against the event's [class], [subclass], and the "all" class + * (which matches all events). + * Every zedlet with a matching class prefix is invoked. * The NAME=VALUE strings in [envs] will be passed to the zedlet as * environment variables. * - * The file descriptor [zfd] is the zevent_fd used to track the + * The file descriptor [zcp->zevent_fd] is the zevent_fd used to track the * current cursor location within the zevent nvlist. * * Return 0 on success, -1 on error. */ int zed_exec_process(uint64_t eid, const char *class, const char *subclass, - const char *dir, zed_strings_t *zedlets, zed_strings_t *envs, int zfd) + struct zed_conf *zcp, zed_strings_t *envs) { const char *class_strings[4]; const char *allclass = "all"; @@ -203,9 +323,22 @@ zed_exec_process(uint64_t eid, const char *class, const char *subclass, char **e; int n; - if (!dir || !zedlets || !envs || zfd < 0) + if (!zcp->zedlet_dir || !zcp->zedlets || !envs || zcp->zevent_fd < 0) return (-1); + if (_reap_children_tid == (pthread_t)-1) { + _launched_processes_limit = zcp->max_jobs; + + if (pthread_create(&_reap_children_tid, NULL, + _reap_children, NULL) != 0) + return (-1); + pthread_setname_np(_reap_children_tid, "reap ZEDLETs"); + + avl_create(&_launched_processes, _launched_process_node_compare, + sizeof (struct launched_process_node), + offsetof(struct launched_process_node, node)); + } + csp = class_strings; if (class) @@ -221,11 +354,13 @@ zed_exec_process(uint64_t eid, const char *class, const char *subclass, e = _zed_exec_create_env(envs); - for (z = zed_strings_first(zedlets); z; z = zed_strings_next(zedlets)) { + for (z = zed_strings_first(zcp->zedlets); z; + z = zed_strings_next(zcp->zedlets)) { for (csp = class_strings; *csp; csp++) { n = strlen(*csp); if ((strncmp(z, *csp, n) == 0) && !isalpha(z[n])) - _zed_exec_fork_child(eid, dir, z, e, zfd); + _zed_exec_fork_child(eid, zcp->zedlet_dir, + z, e, zcp->zevent_fd, zcp->do_foreground); } } free(e); diff --git a/sys/contrib/openzfs/cmd/zed/zed_exec.h b/sys/contrib/openzfs/cmd/zed/zed_exec.h index 5eb9170abfe..e4c8d86335b 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_exec.h +++ b/sys/contrib/openzfs/cmd/zed/zed_exec.h @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). @@ -17,9 +17,11 @@ #include #include "zed_strings.h" +#include "zed_conf.h" + +void zed_exec_fini(void); int zed_exec_process(uint64_t eid, const char *class, const char *subclass, - const char *dir, zed_strings_t *zedlets, zed_strings_t *envs, - int zevent_fd); + struct zed_conf *zcp, zed_strings_t *envs); #endif /* !ZED_EXEC_H */ diff --git a/sys/contrib/openzfs/cmd/zed/zed_file.c b/sys/contrib/openzfs/cmd/zed/zed_file.c index b51b1ca9dcf..b62f68b2610 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_file.c +++ b/sys/contrib/openzfs/cmd/zed/zed_file.c @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). @@ -12,73 +12,17 @@ * You may not use this file except in compliance with the license. */ +#include #include #include #include #include -#include #include #include #include #include "zed_file.h" #include "zed_log.h" -/* - * Read up to [n] bytes from [fd] into [buf]. - * Return the number of bytes read, 0 on EOF, or -1 on error. - */ -ssize_t -zed_file_read_n(int fd, void *buf, size_t n) -{ - unsigned char *p; - size_t n_left; - ssize_t n_read; - - p = buf; - n_left = n; - while (n_left > 0) { - if ((n_read = read(fd, p, n_left)) < 0) { - if (errno == EINTR) - continue; - else - return (-1); - - } else if (n_read == 0) { - break; - } - n_left -= n_read; - p += n_read; - } - return (n - n_left); -} - -/* - * Write [n] bytes from [buf] out to [fd]. - * Return the number of bytes written, or -1 on error. - */ -ssize_t -zed_file_write_n(int fd, void *buf, size_t n) -{ - const unsigned char *p; - size_t n_left; - ssize_t n_written; - - p = buf; - n_left = n; - while (n_left > 0) { - if ((n_written = write(fd, p, n_left)) < 0) { - if (errno == EINTR) - continue; - else - return (-1); - - } - n_left -= n_written; - p += n_written; - } - return (n); -} - /* * Set an exclusive advisory lock on the open file descriptor [fd]. * Return 0 on success, 1 if a conflicting lock is held by another process, @@ -160,6 +104,13 @@ zed_file_is_locked(int fd) return (lock.l_pid); } + +#if __APPLE__ +#define PROC_SELF_FD "/dev/fd" +#else /* Linux-compatible layout */ +#define PROC_SELF_FD "/proc/self/fd" +#endif + /* * Close all open file descriptors greater than or equal to [lowfd]. * Any errors encountered while closing file descriptors are ignored. @@ -167,51 +118,24 @@ zed_file_is_locked(int fd) void zed_file_close_from(int lowfd) { - const int maxfd_def = 256; - int errno_bak; - struct rlimit rl; - int maxfd; + int errno_bak = errno; + int maxfd = 0; int fd; + DIR *fddir; + struct dirent *fdent; - errno_bak = errno; - - if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { - maxfd = maxfd_def; - } else if (rl.rlim_max == RLIM_INFINITY) { - maxfd = maxfd_def; + if ((fddir = opendir(PROC_SELF_FD)) != NULL) { + while ((fdent = readdir(fddir)) != NULL) { + fd = atoi(fdent->d_name); + if (fd > maxfd && fd != dirfd(fddir)) + maxfd = fd; + } + (void) closedir(fddir); } else { - maxfd = rl.rlim_max; + maxfd = sysconf(_SC_OPEN_MAX); } for (fd = lowfd; fd < maxfd; fd++) (void) close(fd); errno = errno_bak; } - -/* - * Set the CLOEXEC flag on file descriptor [fd] so it will be automatically - * closed upon successful execution of one of the exec functions. - * Return 0 on success, or -1 on error. - * - * FIXME: No longer needed? - */ -int -zed_file_close_on_exec(int fd) -{ - int flags; - - if (fd < 0) { - errno = EBADF; - return (-1); - } - flags = fcntl(fd, F_GETFD); - if (flags == -1) - return (-1); - - flags |= FD_CLOEXEC; - - if (fcntl(fd, F_SETFD, flags) == -1) - return (-1); - - return (0); -} diff --git a/sys/contrib/openzfs/cmd/zed/zed_file.h b/sys/contrib/openzfs/cmd/zed/zed_file.h index 7dcae83810e..7e3a0efcaf3 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_file.h +++ b/sys/contrib/openzfs/cmd/zed/zed_file.h @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). @@ -18,10 +18,6 @@ #include #include -ssize_t zed_file_read_n(int fd, void *buf, size_t n); - -ssize_t zed_file_write_n(int fd, void *buf, size_t n); - int zed_file_lock(int fd); int zed_file_unlock(int fd); @@ -30,6 +26,4 @@ pid_t zed_file_is_locked(int fd); void zed_file_close_from(int fd); -int zed_file_close_on_exec(int fd); - #endif /* !ZED_FILE_H */ diff --git a/sys/contrib/openzfs/cmd/zed/zed_log.c b/sys/contrib/openzfs/cmd/zed/zed_log.c index 948dad52adb..0c4ab6f47db 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_log.c +++ b/sys/contrib/openzfs/cmd/zed/zed_log.c @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). diff --git a/sys/contrib/openzfs/cmd/zed/zed_log.h b/sys/contrib/openzfs/cmd/zed/zed_log.h index 0daaad11df5..ed88ad41d7e 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_log.h +++ b/sys/contrib/openzfs/cmd/zed/zed_log.h @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). diff --git a/sys/contrib/openzfs/cmd/zed/zed_strings.c b/sys/contrib/openzfs/cmd/zed/zed_strings.c index 89964317e48..52a86e9296f 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_strings.c +++ b/sys/contrib/openzfs/cmd/zed/zed_strings.c @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). diff --git a/sys/contrib/openzfs/cmd/zed/zed_strings.h b/sys/contrib/openzfs/cmd/zed/zed_strings.h index 63d776f9b48..804639592fe 100644 --- a/sys/contrib/openzfs/cmd/zed/zed_strings.h +++ b/sys/contrib/openzfs/cmd/zed/zed_strings.h @@ -3,7 +3,7 @@ * * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. - * Refer to the ZoL git commit log for authoritative copyright attribution. + * Refer to the OpenZFS git commit log for authoritative copyright attribution. * * The contents of this file are subject to the terms of the * Common Development and Distribution License Version 1.0 (CDDL-1.0). diff --git a/sys/contrib/openzfs/cmd/zfs/zfs_main.c b/sys/contrib/openzfs/cmd/zfs/zfs_main.c index 1a5129f7949..c583053dbae 100644 --- a/sys/contrib/openzfs/cmd/zfs/zfs_main.c +++ b/sys/contrib/openzfs/cmd/zfs/zfs_main.c @@ -52,6 +52,8 @@ #include #include #include +#include +#include #include #include #include @@ -78,12 +80,10 @@ #include "zfs_iter.h" #include "zfs_util.h" #include "zfs_comutil.h" -#include "libzfs_impl.h" #include "zfs_projectutil.h" libzfs_handle_t *g_zfs; -static FILE *mnttab_file; static char history_str[HIS_MAX_RECORD_LEN]; static boolean_t log_history = B_TRUE; @@ -3316,7 +3316,7 @@ zfs_do_userspace(int argc, char **argv) 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) { + if (zfs_get_underlying_type(zhp) != ZFS_TYPE_FILESYSTEM) { (void) fprintf(stderr, gettext("operation is only applicable " "to filesystems and their snapshots\n")); zfs_close(zhp); @@ -4376,6 +4376,7 @@ zfs_do_send(int argc, char **argv) struct option long_options[] = { {"replicate", no_argument, NULL, 'R'}, + {"skip-missing", no_argument, NULL, 's'}, {"redact", required_argument, NULL, 'd'}, {"props", no_argument, NULL, 'p'}, {"parsable", no_argument, NULL, 'P'}, @@ -4394,7 +4395,7 @@ zfs_do_send(int argc, char **argv) }; /* check options */ - while ((c = getopt_long(argc, argv, ":i:I:RDpvnPLeht:cwbd:S", + while ((c = getopt_long(argc, argv, ":i:I:RsDpvnPLeht:cwbd:S", long_options, NULL)) != -1) { switch (c) { case 'i': @@ -4411,6 +4412,9 @@ zfs_do_send(int argc, char **argv) case 'R': flags.replicate = B_TRUE; break; + case 's': + flags.skipmissing = B_TRUE; + break; case 'd': redactbook = optarg; break; @@ -4575,6 +4579,13 @@ zfs_do_send(int argc, char **argv) resume_token)); } + if (flags.skipmissing && !flags.replicate) { + (void) fprintf(stderr, + gettext("skip-missing flag can only be used in " + "conjunction with replicate\n")); + usage(B_FALSE); + } + /* * For everything except -R and -I, use the new, cleaner code path. */ @@ -7052,8 +7063,7 @@ share_mount(int op, int argc, char **argv) get_all_datasets(&cb, verbose); if (cb.cb_used == 0) { - if (options != NULL) - free(options); + free(options); return (0); } @@ -7083,6 +7093,7 @@ share_mount(int op, int argc, char **argv) zfs_close(cb.cb_handles[i]); free(cb.cb_handles); } else if (argc == 0) { + FILE *mnttab; struct mnttab entry; if ((op == OP_SHARE) || (options != NULL)) { @@ -7098,14 +7109,12 @@ share_mount(int op, int argc, char **argv) * automatically. */ - /* Reopen MNTTAB to prevent reading stale data from open file */ - if (freopen(MNTTAB, "r", mnttab_file) == NULL) { - if (options != NULL) - free(options); + if ((mnttab = fopen(MNTTAB, "re")) == NULL) { + free(options); return (ENOENT); } - while (getmntent(mnttab_file, &entry) == 0) { + while (getmntent(mnttab, &entry) == 0) { if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0 || strchr(entry.mnt_special, '@') != NULL) continue; @@ -7114,6 +7123,7 @@ share_mount(int op, int argc, char **argv) entry.mnt_mountp); } + (void) fclose(mnttab); } else { zfs_handle_t *zhp; @@ -7134,9 +7144,7 @@ share_mount(int op, int argc, char **argv) } } - if (options != NULL) - free(options); - + free(options); return (ret); } @@ -7199,10 +7207,6 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual) * Search for the given (major,minor) pair in the mount table. */ - /* Reopen MNTTAB to prevent reading stale data from open file */ - if (freopen(MNTTAB, "r", mnttab_file) == NULL) - return (ENOENT); - if (getextmntent(path, &entry, &statbuf) != 0) { if (op == OP_SHARE) { (void) fprintf(stderr, gettext("cannot %s '%s': not " @@ -7342,6 +7346,7 @@ unshare_unmount(int op, int argc, char **argv) * the special type (dataset name), and walk the result in * reverse to make sure to get any snapshots first. */ + FILE *mnttab; struct mnttab entry; uu_avl_pool_t *pool; uu_avl_t *tree = NULL; @@ -7374,11 +7379,10 @@ unshare_unmount(int op, int argc, char **argv) ((tree = uu_avl_create(pool, NULL, UU_DEFAULT)) == NULL)) nomem(); - /* Reopen MNTTAB to prevent reading stale data from open file */ - if (freopen(MNTTAB, "r", mnttab_file) == NULL) + if ((mnttab = fopen(MNTTAB, "re")) == NULL) return (ENOENT); - while (getmntent(mnttab_file, &entry) == 0) { + while (getmntent(mnttab, &entry) == 0) { /* ignore non-ZFS entries */ if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0) @@ -7448,6 +7452,7 @@ unshare_unmount(int op, int argc, char **argv) free(node); } } + (void) fclose(mnttab); /* * Walk the AVL tree in reverse, unmounting each filesystem and @@ -8638,8 +8643,6 @@ main(int argc, char **argv) return (1); } - mnttab_file = g_zfs->libzfs_mnttab; - zfs_save_arguments(argc, argv, history_str, sizeof (history_str)); libzfs_print_on_error(g_zfs, B_TRUE); diff --git a/sys/contrib/openzfs/cmd/zfs_ids_to_path/zfs_ids_to_path.c b/sys/contrib/openzfs/cmd/zfs_ids_to_path/zfs_ids_to_path.c index 80dd5bf2dc2..1d3bb6b29ee 100644 --- a/sys/contrib/openzfs/cmd/zfs_ids_to_path/zfs_ids_to_path.c +++ b/sys/contrib/openzfs/cmd/zfs_ids_to_path/zfs_ids_to_path.c @@ -35,7 +35,7 @@ libzfs_handle_t *g_zfs; static void usage(int err) { - fprintf(stderr, "Usage: [-v] zfs_ids_to_path " + fprintf(stderr, "Usage: zfs_ids_to_path [-v] " "\n"); exit(err); } @@ -63,11 +63,11 @@ main(int argc, char **argv) uint64_t objset, object; if (sscanf(argv[1], "%llu", (u_longlong_t *)&objset) != 1) { - (void) fprintf(stderr, "Invalid objset id: %s\n", argv[2]); + (void) fprintf(stderr, "Invalid objset id: %s\n", argv[1]); usage(2); } if (sscanf(argv[2], "%llu", (u_longlong_t *)&object) != 1) { - (void) fprintf(stderr, "Invalid object id: %s\n", argv[3]); + (void) fprintf(stderr, "Invalid object id: %s\n", argv[2]); usage(3); } if ((g_zfs = libzfs_init()) == NULL) { @@ -76,7 +76,7 @@ main(int argc, char **argv) } zpool_handle_t *pool = zpool_open(g_zfs, argv[0]); if (pool == NULL) { - fprintf(stderr, "Could not open pool %s\n", argv[1]); + fprintf(stderr, "Could not open pool %s\n", argv[0]); libzfs_fini(g_zfs); return (5); } diff --git a/sys/contrib/openzfs/cmd/zgenhostid/zgenhostid.c b/sys/contrib/openzfs/cmd/zgenhostid/zgenhostid.c index 50fcf05e420..4a4ca80e00e 100644 --- a/sys/contrib/openzfs/cmd/zgenhostid/zgenhostid.c +++ b/sys/contrib/openzfs/cmd/zgenhostid/zgenhostid.c @@ -36,8 +36,6 @@ #include #include -static void usage(void); - static void usage(void) { @@ -60,12 +58,11 @@ int main(int argc, char **argv) { /* default file path, can be optionally set by user */ - char path[PATH_MAX] = "/etc/hostid"; + const char *path = "/etc/hostid"; /* holds converted user input or lrand48() generated value */ unsigned long input_i = 0; int opt; - int pathlen; int force_fwrite = 0; while ((opt = getopt_long(argc, argv, "fo:h?", 0, 0)) != -1) { switch (opt) { @@ -73,14 +70,7 @@ main(int argc, char **argv) force_fwrite = 1; break; case 'o': - pathlen = snprintf(path, sizeof (path), "%s", optarg); - if (pathlen >= sizeof (path)) { - fprintf(stderr, "%s\n", strerror(EOVERFLOW)); - exit(EXIT_FAILURE); - } else if (pathlen < 1) { - fprintf(stderr, "%s\n", strerror(EINVAL)); - exit(EXIT_FAILURE); - } + path = optarg; break; case 'h': case '?': @@ -118,7 +108,7 @@ main(int argc, char **argv) if (force_fwrite == 0 && stat(path, &fstat) == 0 && S_ISREG(fstat.st_mode)) { fprintf(stderr, "%s: %s\n", path, strerror(EEXIST)); - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } /* @@ -137,7 +127,7 @@ main(int argc, char **argv) } /* - * we need just 4 bytes in native endianess + * we need just 4 bytes in native endianness * not using sethostid() because it may be missing or just a stub */ uint32_t hostid = input_i; diff --git a/sys/contrib/openzfs/cmd/zhack/zhack.c b/sys/contrib/openzfs/cmd/zhack/zhack.c index 08263120c7c..c1017ec2386 100644 --- a/sys/contrib/openzfs/cmd/zhack/zhack.c +++ b/sys/contrib/openzfs/cmd/zhack/zhack.c @@ -48,10 +48,9 @@ #include #include #include +#include #include -extern boolean_t zfeature_checks_disable; - const char cmdname[] = "zhack"; static importargs_t g_importargs; static char *g_pool; diff --git a/sys/contrib/openzfs/cmd/zpool/Makefile.am b/sys/contrib/openzfs/cmd/zpool/Makefile.am index abfa940c3d7..aad45d4f749 100644 --- a/sys/contrib/openzfs/cmd/zpool/Makefile.am +++ b/sys/contrib/openzfs/cmd/zpool/Makefile.am @@ -1,4 +1,5 @@ include $(top_srcdir)/config/Rules.am +include $(top_srcdir)/config/Shellcheck.am AM_CFLAGS += $(LIBBLKID_CFLAGS) $(LIBUUID_CFLAGS) @@ -146,6 +147,10 @@ dist_zpoolcompat_DATA = \ compatibility.d/openzfsonosx-1.9.3 \ compatibility.d/openzfs-2.0-freebsd \ compatibility.d/openzfs-2.0-linux \ + compatibility.d/openzfs-2.1-freebsd \ + compatibility.d/openzfs-2.1-linux \ + compatibility.d/zol-0.6.1 \ + compatibility.d/zol-0.6.4 \ compatibility.d/zol-0.6.5 \ compatibility.d/zol-0.7 \ compatibility.d/zol-0.8 diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfs-2.1-freebsd b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfs-2.1-freebsd new file mode 100644 index 00000000000..9fde997e8c6 --- /dev/null +++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfs-2.1-freebsd @@ -0,0 +1,34 @@ +# Features supported by OpenZFS 2.1 on FreeBSD +allocation_classes +async_destroy +bookmark_v2 +bookmark_written +bookmarks +device_rebuild +device_removal +draid +embedded_data +empty_bpobj +enabled_txg +encryption +extensible_dataset +filesystem_limits +hole_birth +large_blocks +large_dnode +livelist +log_spacemap +lz4_compress +multi_vdev_crash_dump +obsolete_counts +project_quota +redacted_datasets +redaction_bookmarks +resilver_defer +sha512 +skein +spacemap_histogram +spacemap_v2 +userobj_accounting +zpool_checkpoint +zstd_compress diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfs-2.1-linux b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfs-2.1-linux new file mode 100644 index 00000000000..c3ff176bf8f --- /dev/null +++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfs-2.1-linux @@ -0,0 +1,35 @@ +# Features supported by OpenZFS 2.1 on Linux +allocation_classes +async_destroy +bookmark_v2 +bookmark_written +bookmarks +device_rebuild +device_removal +draid +edonr +embedded_data +empty_bpobj +enabled_txg +encryption +extensible_dataset +filesystem_limits +hole_birth +large_blocks +large_dnode +livelist +log_spacemap +lz4_compress +multi_vdev_crash_dump +obsolete_counts +project_quota +redacted_datasets +redaction_bookmarks +resilver_defer +sha512 +skein +spacemap_histogram +spacemap_v2 +userobj_accounting +zpool_checkpoint +zstd_compress diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.6.1 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.6.1 new file mode 100644 index 00000000000..9bc963ddcca --- /dev/null +++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.6.1 @@ -0,0 +1,4 @@ +# Features supported by ZFSonLinux v0.6.1 +async_destroy +empty_bpobj +lz4_compress diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.6.4 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.6.4 new file mode 100644 index 00000000000..82a2698c8c5 --- /dev/null +++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.6.4 @@ -0,0 +1,10 @@ +# Features supported by ZFSonLinux v0.6.4 +async_destroy +bookmarks +embedded_data +empty_bpobj +enabled_txg +extensible_dataset +hole_birth +lz4_compress +spacemap_histogram diff --git a/sys/contrib/openzfs/cmd/zpool/os/freebsd/zpool_vdev_os.c b/sys/contrib/openzfs/cmd/zpool/os/freebsd/zpool_vdev_os.c index 7d48f61a0ee..aa66d29fa60 100644 --- a/sys/contrib/openzfs/cmd/zpool/os/freebsd/zpool_vdev_os.c +++ b/sys/contrib/openzfs/cmd/zpool/os/freebsd/zpool_vdev_os.c @@ -101,3 +101,18 @@ check_sector_size_database(char *path, int *sector_size) { return (0); } + +void +after_zpool_upgrade(zpool_handle_t *zhp) +{ + char bootfs[ZPOOL_MAXPROPLEN]; + + if (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs, + sizeof (bootfs), NULL, B_FALSE) == 0 && + strcmp(bootfs, "-") != 0) { + (void) printf(gettext("Pool '%s' has the bootfs " + "property set, you might need to update\nthe boot " + "code. See gptzfsboot(8) and loader.efi(8) for " + "details.\n"), zpool_get_name(zhp)); + } +} diff --git a/sys/contrib/openzfs/cmd/zpool/os/linux/zpool_vdev_os.c b/sys/contrib/openzfs/cmd/zpool/os/linux/zpool_vdev_os.c index 55a9367ec18..da87aa79f36 100644 --- a/sys/contrib/openzfs/cmd/zpool/os/linux/zpool_vdev_os.c +++ b/sys/contrib/openzfs/cmd/zpool/os/linux/zpool_vdev_os.c @@ -405,3 +405,8 @@ check_device(const char *path, boolean_t force, return (error); } + +void +after_zpool_upgrade(zpool_handle_t *zhp) +{ +} diff --git a/sys/contrib/openzfs/cmd/zpool/zpool.d/smart b/sys/contrib/openzfs/cmd/zpool/zpool.d/smart index f8854b75227..b95256d7564 100755 --- a/sys/contrib/openzfs/cmd/zpool/zpool.d/smart +++ b/sys/contrib/openzfs/cmd/zpool/zpool.d/smart @@ -53,7 +53,7 @@ get_filename_from_dir() num_files=$(find "$dir" -maxdepth 1 -type f | wc -l) mod=$((pid % num_files)) i=0 - find "$dir" -type f -printf "%f\n" | while read -r file ; do + find "$dir" -type f -printf '%f\n' | while read -r file ; do if [ "$mod" = "$i" ] ; then echo "$file" break @@ -62,17 +62,14 @@ get_filename_from_dir() done } -script=$(basename "$0") +script="${0##*/}" if [ "$1" = "-h" ] ; then echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2- exit fi -smartctl_path=$(command -v smartctl) - -# shellcheck disable=SC2015 -if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ] || [ -n "$samples" ] ; then +if [ -b "$VDEV_UPATH" ] && PATH="/usr/sbin:$PATH" command -v smartctl > /dev/null || [ -n "$samples" ] ; then if [ -n "$samples" ] ; then # cat a smartctl output text file instead of running smartctl # on a vdev (only used for developer testing). @@ -80,7 +77,7 @@ if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ] || [ -n "$samples" ] ; then echo "file=$file" raw_out=$(cat "$samples/$file") else - raw_out=$(eval "sudo $smartctl_path -a $VDEV_UPATH") + raw_out=$(sudo smartctl -a "$VDEV_UPATH") fi # What kind of drive are we? Look for the right line in smartctl: @@ -231,11 +228,11 @@ esac with_vals=$(echo "$out" | grep -E "$scripts") if [ -n "$with_vals" ]; then echo "$with_vals" - without_vals=$(echo "$scripts" | tr "|" "\n" | + without_vals=$(echo "$scripts" | tr '|' '\n' | grep -v -E "$(echo "$with_vals" | awk -F "=" '{print $1}')" | awk '{print $0"="}') else - without_vals=$(echo "$scripts" | tr "|" "\n" | awk '{print $0"="}') + without_vals=$(echo "$scripts" | tr '|' '\n' | awk '{print $0"="}') fi if [ -n "$without_vals" ]; then diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_iter.c b/sys/contrib/openzfs/cmd/zpool/zpool_iter.c index d70d266699c..3d7a0cfc35e 100644 --- a/sys/contrib/openzfs/cmd/zpool/zpool_iter.c +++ b/sys/contrib/openzfs/cmd/zpool/zpool_iter.c @@ -494,19 +494,25 @@ vdev_run_cmd(vdev_cmd_data_t *data, char *cmd) /* Setup our custom environment variables */ rc = asprintf(&env[1], "VDEV_PATH=%s", data->path ? data->path : ""); - if (rc == -1) + if (rc == -1) { + env[1] = NULL; goto out; + } rc = asprintf(&env[2], "VDEV_UPATH=%s", data->upath ? data->upath : ""); - if (rc == -1) + if (rc == -1) { + env[2] = NULL; goto out; + } rc = asprintf(&env[3], "VDEV_ENC_SYSFS_PATH=%s", data->vdev_enc_sysfs_path ? data->vdev_enc_sysfs_path : ""); - if (rc == -1) + if (rc == -1) { + env[3] = NULL; goto out; + } /* Run the command */ rc = libzfs_run_process_get_stdout_nopath(cmd, argv, env, &lines, @@ -525,8 +531,7 @@ out: /* Start with i = 1 since env[0] was statically allocated */ for (i = 1; i < ARRAY_SIZE(env); i++) - if (env[i] != NULL) - free(env[i]); + free(env[i]); } /* diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_main.c b/sys/contrib/openzfs/cmd/zpool/zpool_main.c index e23604b3d81..02415b15793 100644 --- a/sys/contrib/openzfs/cmd/zpool/zpool_main.c +++ b/sys/contrib/openzfs/cmd/zpool/zpool_main.c @@ -32,6 +32,7 @@ * Copyright (c) 2017, Intel Corporation. * Copyright (c) 2019, loli10K * Copyright (c) 2021, Colm Buckley + * Copyright [2021] Hewlett Packard Enterprise Development LP */ #include @@ -786,7 +787,7 @@ add_prop_list(const char *propname, char *propval, nvlist_t **props, if (poolprop) { const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION); - const char *fname = + const char *cname = zpool_prop_to_name(ZPOOL_PROP_COMPATIBILITY); if ((prop = zpool_name_to_prop(propname)) == ZPOOL_PROP_INVAL && @@ -811,16 +812,19 @@ add_prop_list(const char *propname, char *propval, nvlist_t **props, } /* - * compatibility property and version should not be specified - * at the same time. + * if version is specified, only "legacy" compatibility + * may be requested */ if ((prop == ZPOOL_PROP_COMPATIBILITY && + strcmp(propval, ZPOOL_COMPAT_LEGACY) != 0 && nvlist_exists(proplist, vname)) || (prop == ZPOOL_PROP_VERSION && - nvlist_exists(proplist, fname))) { - (void) fprintf(stderr, gettext("'compatibility' and " - "'version' properties cannot be specified " - "together\n")); + nvlist_exists(proplist, cname) && + strcmp(fnvlist_lookup_string(proplist, cname), + ZPOOL_COMPAT_LEGACY) != 0)) { + (void) fprintf(stderr, gettext("when 'version' is " + "specified, the 'compatibility' feature may only " + "be set to '" ZPOOL_COMPAT_LEGACY "'\n")); return (2); } @@ -1065,7 +1069,7 @@ zpool_do_add(int argc, char **argv) free(vname); } } - /* And finaly the spares */ + /* And finally the spares */ if (nvlist_lookup_nvlist_array(poolnvroot, ZPOOL_CONFIG_SPARES, &sparechild, &sparechildren) == 0 && sparechildren > 0) { hadspare = B_TRUE; @@ -1674,6 +1678,7 @@ zpool_do_create(int argc, char **argv) * - enable_pool_features (ie: no '-d' or '-o version') * - it's supported by the kernel module * - it's in the requested feature set + * - warn if it's enabled but not in compat */ for (spa_feature_t i = 0; i < SPA_FEATURES; i++) { char propname[MAXPATHLEN]; @@ -1687,6 +1692,14 @@ zpool_do_create(int argc, char **argv) if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0) (void) nvlist_remove_all(props, propname); + if (strcmp(propval, + ZFS_FEATURE_ENABLED) == 0 && + !requested_features[i]) + (void) fprintf(stderr, gettext( + "Warning: feature \"%s\" enabled " + "but is not in specified " + "'compatibility' feature set.\n"), + feat->fi_uname); } else if ( enable_pool_features && feat->fi_zfs_mod_supported && @@ -2367,6 +2380,10 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name, (void) printf(gettext("all children offline")); break; + case VDEV_AUX_BAD_LABEL: + (void) printf(gettext("invalid label")); + break; + default: (void) printf(gettext("corrupted data")); break; @@ -2509,6 +2526,10 @@ print_import_config(status_cbdata_t *cb, const char *name, nvlist_t *nv, (void) printf(gettext("all children offline")); break; + case VDEV_AUX_BAD_LABEL: + (void) printf(gettext("invalid label")); + break; + default: (void) printf(gettext("corrupted data")); break; @@ -2717,8 +2738,10 @@ show_import(nvlist_t *config, boolean_t report_error) case ZPOOL_STATUS_FEAT_DISABLED: printf_color(ANSI_BOLD, gettext("status: ")); - printf_color(ANSI_YELLOW, gettext("Some supported and " - "requested features are not enabled on the pool.\n")); + printf_color(ANSI_YELLOW, gettext("Some supported " + "features are not enabled on the pool.\n\t" + "(Note that they may be intentionally disabled " + "if the\n\t'compatibility' property is set.)\n")); break; case ZPOOL_STATUS_COMPATIBILITY_ERR: @@ -2728,6 +2751,13 @@ show_import(nvlist_t *config, boolean_t report_error) "property.\n")); break; + case ZPOOL_STATUS_INCOMPATIBLE_FEAT: + printf_color(ANSI_BOLD, gettext("status: ")); + printf_color(ANSI_YELLOW, gettext("One or more features " + "are enabled on the pool despite not being\n" + "requested by the 'compatibility' property.\n")); + break; + case ZPOOL_STATUS_UNSUP_FEAT_READ: printf_color(ANSI_BOLD, gettext("status: ")); printf_color(ANSI_YELLOW, gettext("The pool uses the following " @@ -3469,16 +3499,8 @@ zpool_do_import(int argc, char **argv) cachefile = optarg; break; case 'd': - if (searchdirs == NULL) { - searchdirs = safe_malloc(sizeof (char *)); - } else { - char **tmp = safe_malloc((nsearch + 1) * - sizeof (char *)); - bcopy(searchdirs, tmp, nsearch * - sizeof (char *)); - free(searchdirs); - searchdirs = tmp; - } + searchdirs = safe_realloc(searchdirs, + (nsearch + 1) * sizeof (char *)); searchdirs[nsearch++] = optarg; break; case 'D': @@ -3668,24 +3690,16 @@ zpool_do_import(int argc, char **argv) * Check the environment for the preferred search path. */ if ((searchdirs == NULL) && (env = getenv("ZPOOL_IMPORT_PATH"))) { - char *dir; + char *dir, *tmp = NULL; envdup = strdup(env); - dir = strtok(envdup, ":"); - while (dir != NULL) { - if (searchdirs == NULL) { - searchdirs = safe_malloc(sizeof (char *)); - } else { - char **tmp = safe_malloc((nsearch + 1) * - sizeof (char *)); - bcopy(searchdirs, tmp, nsearch * - sizeof (char *)); - free(searchdirs); - searchdirs = tmp; - } + for (dir = strtok_r(envdup, ":", &tmp); + dir != NULL; + dir = strtok_r(NULL, ":", &tmp)) { + searchdirs = safe_realloc(searchdirs, + (nsearch + 1) * sizeof (char *)); searchdirs[nsearch++] = dir; - dir = strtok(NULL, ":"); } } @@ -3724,10 +3738,8 @@ zpool_do_import(int argc, char **argv) } if (err == 1) { - if (searchdirs != NULL) - free(searchdirs); - if (envdup != NULL) - free(envdup); + free(searchdirs); + free(envdup); nvlist_free(policy); nvlist_free(pools); nvlist_free(props); @@ -3765,10 +3777,8 @@ error: nvlist_free(props); nvlist_free(pools); nvlist_free(policy); - if (searchdirs != NULL) - free(searchdirs); - if (envdup != NULL) - free(envdup); + free(searchdirs); + free(envdup); return (err ? 1 : 0); } @@ -4965,8 +4975,8 @@ get_interval_count(int *argcp, char **argv, float *iv, if (*end == '\0' && errno == 0) { if (interval == 0) { - (void) fprintf(stderr, gettext("interval " - "cannot be zero\n")); + (void) fprintf(stderr, gettext( + "interval cannot be zero\n")); usage(B_FALSE); } /* @@ -4996,8 +5006,8 @@ get_interval_count(int *argcp, char **argv, float *iv, if (*end == '\0' && errno == 0) { if (interval == 0) { - (void) fprintf(stderr, gettext("interval " - "cannot be zero\n")); + (void) fprintf(stderr, gettext( + "interval cannot be zero\n")); usage(B_FALSE); } @@ -5359,7 +5369,7 @@ print_zpool_dir_scripts(char *dirpath) static void print_zpool_script_list(char *subcommand) { - char *dir, *sp; + char *dir, *sp, *tmp; printf(gettext("Available 'zpool %s -c' commands:\n"), subcommand); @@ -5367,11 +5377,10 @@ print_zpool_script_list(char *subcommand) if (sp == NULL) return; - dir = strtok(sp, ":"); - while (dir != NULL) { + for (dir = strtok_r(sp, ":", &tmp); + dir != NULL; + dir = strtok_r(NULL, ":", &tmp)) print_zpool_dir_scripts(dir); - dir = strtok(NULL, ":"); - } free(sp); } @@ -6000,7 +6009,7 @@ print_one_column(zpool_prop_t prop, uint64_t value, const char *str, break; case ZPOOL_PROP_HEALTH: width = 8; - snprintf(propval, sizeof (propval), "%-*s", (int)width, str); + (void) strlcpy(propval, str, sizeof (propval)); break; default: zfs_nicenum_format(value, propval, sizeof (propval), format); @@ -8055,7 +8064,8 @@ status_callback(zpool_handle_t *zhp, void *data) (reason == ZPOOL_STATUS_OK || reason == ZPOOL_STATUS_VERSION_OLDER || reason == ZPOOL_STATUS_FEAT_DISABLED || - reason == ZPOOL_STATUS_COMPATIBILITY_ERR)) { + reason == ZPOOL_STATUS_COMPATIBILITY_ERR || + reason == ZPOOL_STATUS_INCOMPATIBLE_FEAT)) { if (!cbp->cb_allpools) { (void) printf(gettext("pool '%s' is healthy\n"), zpool_get_name(zhp)); @@ -8254,6 +8264,18 @@ status_callback(zpool_handle_t *zhp, void *data) ZPOOL_DATA_COMPAT_D ".\n")); break; + case ZPOOL_STATUS_INCOMPATIBLE_FEAT: + printf_color(ANSI_BOLD, gettext("status: ")); + printf_color(ANSI_YELLOW, gettext("One or more features " + "are enabled on the pool despite not being\n\t" + "requested by the 'compatibility' property.\n")); + printf_color(ANSI_BOLD, gettext("action: ")); + printf_color(ANSI_YELLOW, gettext("Consider setting " + "'compatibility' to an appropriate value, or\n\t" + "adding needed features to the relevant file in\n\t" + ZPOOL_SYSCONF_COMPAT_D " or " ZPOOL_DATA_COMPAT_D ".\n")); + break; + case ZPOOL_STATUS_UNSUP_FEAT_READ: printf_color(ANSI_BOLD, gettext("status: ")); printf_color(ANSI_YELLOW, gettext("The pool cannot be accessed " @@ -8713,6 +8735,11 @@ upgrade_version(zpool_handle_t *zhp, uint64_t version) verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &oldversion) == 0); + char compat[ZFS_MAXPROPLEN]; + if (zpool_get_prop(zhp, ZPOOL_PROP_COMPATIBILITY, compat, + ZFS_MAXPROPLEN, NULL, B_FALSE) != 0) + compat[0] = '\0'; + assert(SPA_VERSION_IS_SUPPORTED(oldversion)); assert(oldversion < version); @@ -8727,6 +8754,13 @@ upgrade_version(zpool_handle_t *zhp, uint64_t version) return (1); } + if (strcmp(compat, ZPOOL_COMPAT_LEGACY) == 0) { + (void) fprintf(stderr, gettext("Upgrade not performed because " + "'compatibility' property set to '" + ZPOOL_COMPAT_LEGACY "'.\n")); + return (1); + } + ret = zpool_upgrade(zhp, version); if (ret != 0) return (ret); @@ -8803,7 +8837,7 @@ upgrade_cb(zpool_handle_t *zhp, void *arg) upgrade_cbdata_t *cbp = arg; nvlist_t *config; uint64_t version; - boolean_t printnl = B_FALSE; + boolean_t modified_pool = B_FALSE; int ret; config = zpool_get_config(zhp, NULL); @@ -8817,7 +8851,7 @@ upgrade_cb(zpool_handle_t *zhp, void *arg) ret = upgrade_version(zhp, cbp->cb_version); if (ret != 0) return (ret); - printnl = B_TRUE; + modified_pool = B_TRUE; /* * If they did "zpool upgrade -a", then we could @@ -8837,12 +8871,13 @@ upgrade_cb(zpool_handle_t *zhp, void *arg) if (count > 0) { cbp->cb_first = B_FALSE; - printnl = B_TRUE; + modified_pool = B_TRUE; } } - if (printnl) { - (void) printf(gettext("\n")); + if (modified_pool) { + (void) printf("\n"); + (void) after_zpool_upgrade(zhp); } return (0); @@ -8868,7 +8903,10 @@ upgrade_list_older_cb(zpool_handle_t *zhp, void *arg) "be upgraded to use feature flags. After " "being upgraded, these pools\nwill no " "longer be accessible by software that does not " - "support feature\nflags.\n\n")); + "support feature\nflags.\n\n" + "Note that setting a pool's 'compatibility' " + "feature to '" ZPOOL_COMPAT_LEGACY "' will\n" + "inhibit upgrades.\n\n")); (void) printf(gettext("VER POOL\n")); (void) printf(gettext("--- ------------\n")); cbp->cb_first = B_FALSE; @@ -8914,7 +8952,11 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg) "software\nthat does not support " "the feature. See " "zpool-features(5) for " - "details.\n\n")); + "details.\n\n" + "Note that the pool " + "'compatibility' feature can be " + "used to inhibit\nfeature " + "upgrades.\n\n")); (void) printf(gettext("POOL " "FEATURE\n")); (void) printf(gettext("------" @@ -8948,7 +8990,7 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg) static int upgrade_one(zpool_handle_t *zhp, void *data) { - boolean_t printnl = B_FALSE; + boolean_t modified_pool = B_FALSE; upgrade_cbdata_t *cbp = data; uint64_t cur_version; int ret; @@ -8976,7 +9018,7 @@ upgrade_one(zpool_handle_t *zhp, void *data) } if (cur_version != cbp->cb_version) { - printnl = B_TRUE; + modified_pool = B_TRUE; ret = upgrade_version(zhp, cbp->cb_version); if (ret != 0) return (ret); @@ -8989,7 +9031,7 @@ upgrade_one(zpool_handle_t *zhp, void *data) return (ret); if (count != 0) { - printnl = B_TRUE; + modified_pool = B_TRUE; } else if (cur_version == SPA_VERSION) { (void) printf(gettext("Pool '%s' already has all " "supported and requested features enabled.\n"), @@ -8997,8 +9039,9 @@ upgrade_one(zpool_handle_t *zhp, void *data) } } - if (printnl) { - (void) printf(gettext("\n")); + if (modified_pool) { + (void) printf("\n"); + (void) after_zpool_upgrade(zhp); } return (0); @@ -9970,6 +10013,63 @@ set_callback(zpool_handle_t *zhp, void *data) int error; set_cbdata_t *cb = (set_cbdata_t *)data; + /* Check if we have out-of-bounds features */ + if (strcmp(cb->cb_propname, ZPOOL_CONFIG_COMPATIBILITY) == 0) { + boolean_t features[SPA_FEATURES]; + if (zpool_do_load_compat(cb->cb_value, features) != + ZPOOL_COMPATIBILITY_OK) + return (-1); + + nvlist_t *enabled = zpool_get_features(zhp); + spa_feature_t i; + for (i = 0; i < SPA_FEATURES; i++) { + const char *fguid = spa_feature_table[i].fi_guid; + if (nvlist_exists(enabled, fguid) && !features[i]) + break; + } + if (i < SPA_FEATURES) + (void) fprintf(stderr, gettext("Warning: one or " + "more features already enabled on pool '%s'\n" + "are not present in this compatibility set.\n"), + zpool_get_name(zhp)); + } + + /* if we're setting a feature, check it's in compatibility set */ + if (zpool_prop_feature(cb->cb_propname) && + strcmp(cb->cb_value, ZFS_FEATURE_ENABLED) == 0) { + char *fname = strchr(cb->cb_propname, '@') + 1; + spa_feature_t f; + + if (zfeature_lookup_name(fname, &f) == 0) { + char compat[ZFS_MAXPROPLEN]; + if (zpool_get_prop(zhp, ZPOOL_PROP_COMPATIBILITY, + compat, ZFS_MAXPROPLEN, NULL, B_FALSE) != 0) + compat[0] = '\0'; + + boolean_t features[SPA_FEATURES]; + if (zpool_do_load_compat(compat, features) != + ZPOOL_COMPATIBILITY_OK) { + (void) fprintf(stderr, gettext("Error: " + "cannot enable feature '%s' on pool '%s'\n" + "because the pool's 'compatibility' " + "property cannot be parsed.\n"), + fname, zpool_get_name(zhp)); + return (-1); + } + + if (!features[f]) { + (void) fprintf(stderr, gettext("Error: " + "cannot enable feature '%s' on pool '%s'\n" + "as it is not specified in this pool's " + "current compatibility set.\n" + "Consider setting 'compatibility' to a " + "less restrictive set, or to 'off'.\n"), + fname, zpool_get_name(zhp)); + return (-1); + } + } + } + error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); if (!error) @@ -10492,28 +10592,25 @@ zpool_do_version(int argc, char **argv) static zpool_compat_status_t zpool_do_load_compat(const char *compat, boolean_t *list) { - char badword[ZFS_MAXPROPLEN]; - char badfile[MAXPATHLEN]; + char report[1024]; + zpool_compat_status_t ret; - switch (ret = zpool_load_compat(compat, list, badword, badfile)) { + ret = zpool_load_compat(compat, list, report, 1024); + switch (ret) { + case ZPOOL_COMPATIBILITY_OK: break; - case ZPOOL_COMPATIBILITY_READERR: - (void) fprintf(stderr, gettext("error reading compatibility " - "file '%s'\n"), badfile); - break; - case ZPOOL_COMPATIBILITY_BADFILE: - (void) fprintf(stderr, gettext("compatibility file '%s' " - "too large or not newline-terminated\n"), badfile); - break; - case ZPOOL_COMPATIBILITY_BADWORD: - (void) fprintf(stderr, gettext("unknown feature '%s' in " - "compatibility file '%s'\n"), badword, badfile); - break; + case ZPOOL_COMPATIBILITY_NOFILES: - (void) fprintf(stderr, gettext("no compatibility files " - "specified\n")); + case ZPOOL_COMPATIBILITY_BADFILE: + case ZPOOL_COMPATIBILITY_BADTOKEN: + (void) fprintf(stderr, "Error: %s\n", report); + break; + + case ZPOOL_COMPATIBILITY_WARNTOKEN: + (void) fprintf(stderr, "Warning: %s\n", report); + ret = ZPOOL_COMPATIBILITY_OK; break; } return (ret); diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_util.c b/sys/contrib/openzfs/cmd/zpool/zpool_util.c index 1c1eb024f36..1c64c83d8ff 100644 --- a/sys/contrib/openzfs/cmd/zpool/zpool_util.c +++ b/sys/contrib/openzfs/cmd/zpool/zpool_util.c @@ -49,6 +49,22 @@ safe_malloc(size_t size) return (data); } +/* + * Utility function to guarantee realloc() success. + */ +void * +safe_realloc(void *from, size_t size) +{ + void *data; + + if ((data = realloc(from, size)) == NULL) { + (void) fprintf(stderr, "internal error: out of memory\n"); + exit(1); + } + + return (data); +} + /* * Display an out of memory error message and abort the current program. */ diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_util.h b/sys/contrib/openzfs/cmd/zpool/zpool_util.h index abaa22d78c2..71db4dc3560 100644 --- a/sys/contrib/openzfs/cmd/zpool/zpool_util.h +++ b/sys/contrib/openzfs/cmd/zpool/zpool_util.h @@ -39,6 +39,7 @@ extern "C" { * Basic utility functions */ void *safe_malloc(size_t); +void *safe_realloc(void *, size_t); void zpool_no_memory(void); uint_t num_logs(nvlist_t *nv); uint64_t array64_max(uint64_t array[], unsigned int len); @@ -129,6 +130,7 @@ int check_device(const char *path, boolean_t force, boolean_t check_sector_size_database(char *path, int *sector_size); void vdev_error(const char *fmt, ...); int check_file(const char *file, boolean_t force, boolean_t isspare); +void after_zpool_upgrade(zpool_handle_t *zhp); #ifdef __cplusplus } diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c b/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c index c86081a8153..3d83da641ec 100644 --- a/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c +++ b/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c @@ -445,7 +445,7 @@ typedef struct replication_level { /* * N.B. For the purposes of comparing replication levels dRAID can be - * considered functionally equivilant to raidz. + * considered functionally equivalent to raidz. */ static boolean_t is_raidz_mirror(replication_level_t *a, replication_level_t *b, diff --git a/sys/contrib/openzfs/cmd/zpool_influxdb/zpool_influxdb.c b/sys/contrib/openzfs/cmd/zpool_influxdb/zpool_influxdb.c index 71ffcb25381..5dc39afe830 100644 --- a/sys/contrib/openzfs/cmd/zpool_influxdb/zpool_influxdb.c +++ b/sys/contrib/openzfs/cmd/zpool_influxdb/zpool_influxdb.c @@ -71,7 +71,7 @@ #include #include #include -#include +#include #define POOL_MEASUREMENT "zpool_stats" #define SCAN_MEASUREMENT "zpool_scan_stats" @@ -101,9 +101,10 @@ typedef int (*stat_printer_f)(nvlist_t *, const char *, const char *); * caller is responsible for freeing result */ static char * -escape_string(char *s) +escape_string(const char *s) { - char *c, *d; + const char *c; + char *d; char *t = (char *)malloc(ZFS_MAX_DATASET_NAME_LEN * 2); if (t == NULL) { fprintf(stderr, "error: cannot allocate memory\n"); @@ -714,7 +715,7 @@ print_stats(zpool_handle_t *zhp, void *data) /* if not this pool return quickly */ if (data && - strncmp(data, zhp->zpool_name, ZFS_MAX_DATASET_NAME_LEN) != 0) { + strncmp(data, zpool_get_name(zhp), ZFS_MAX_DATASET_NAME_LEN) != 0) { zpool_close(zhp); return (0); } @@ -742,7 +743,7 @@ print_stats(zpool_handle_t *zhp, void *data) return (3); } - pool_name = escape_string(zhp->zpool_name); + pool_name = escape_string(zpool_get_name(zhp)); err = print_recursive_stats(print_summary_stats, nvroot, pool_name, NULL, 1); /* if any of these return an error, skip the rest */ diff --git a/sys/contrib/openzfs/cmd/zstream/Makefile.am b/sys/contrib/openzfs/cmd/zstream/Makefile.am index 69e1adbcbd6..8e813027fa3 100644 --- a/sys/contrib/openzfs/cmd/zstream/Makefile.am +++ b/sys/contrib/openzfs/cmd/zstream/Makefile.am @@ -15,3 +15,6 @@ zstream_LDADD = \ $(abs_top_builddir)/lib/libnvpair/libnvpair.la include $(top_srcdir)/config/CppCheck.am + +install-exec-hook: + cd $(DESTDIR)$(sbindir) && $(LN_S) -f zstream zstreamdump diff --git a/sys/contrib/openzfs/cmd/zstream/zstream.c b/sys/contrib/openzfs/cmd/zstream/zstream.c index cbcb560a863..523ae068971 100644 --- a/sys/contrib/openzfs/cmd/zstream/zstream.c +++ b/sys/contrib/openzfs/cmd/zstream/zstream.c @@ -49,6 +49,11 @@ zstream_usage(void) int main(int argc, char *argv[]) { + char *basename = strrchr(argv[0], '/'); + basename = basename ? (basename + 1) : argv[0]; + if (argc >= 1 && strcmp(basename, "zstreamdump") == 0) + return (zstream_do_dump(argc, argv)); + if (argc < 2) zstream_usage(); diff --git a/sys/contrib/openzfs/cmd/zstream/zstream_redup.c b/sys/contrib/openzfs/cmd/zstream/zstream_redup.c index 15dd8a1ed12..474527e76ea 100644 --- a/sys/contrib/openzfs/cmd/zstream/zstream_redup.c +++ b/sys/contrib/openzfs/cmd/zstream/zstream_redup.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/sys/contrib/openzfs/cmd/zstreamdump/Makefile.am b/sys/contrib/openzfs/cmd/zstreamdump/Makefile.am deleted file mode 100644 index 2c04d851315..00000000000 --- a/sys/contrib/openzfs/cmd/zstreamdump/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -dist_sbin_SCRIPTS = zstreamdump diff --git a/sys/contrib/openzfs/cmd/zstreamdump/zstreamdump b/sys/contrib/openzfs/cmd/zstreamdump/zstreamdump deleted file mode 100755 index fbf02ee687f..00000000000 --- a/sys/contrib/openzfs/cmd/zstreamdump/zstreamdump +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -zstream dump "$@" diff --git a/sys/contrib/openzfs/cmd/ztest/ztest.c b/sys/contrib/openzfs/cmd/ztest/ztest.c index 7193eafe3d2..73694b0b352 100644 --- a/sys/contrib/openzfs/cmd/ztest/ztest.c +++ b/sys/contrib/openzfs/cmd/ztest/ztest.c @@ -124,6 +124,7 @@ #include #include #include +#include #include #include #include @@ -192,30 +193,58 @@ typedef struct ztest_shared_opts { char zo_gvars[ZO_GVARS_MAX_COUNT][ZO_GVARS_MAX_ARGLEN]; } ztest_shared_opts_t; +/* Default values for command line options. */ +#define DEFAULT_POOL "ztest" +#define DEFAULT_VDEV_DIR "/tmp" +#define DEFAULT_VDEV_COUNT 5 +#define DEFAULT_VDEV_SIZE (SPA_MINDEVSIZE * 4) /* 256m default size */ +#define DEFAULT_VDEV_SIZE_STR "256M" +#define DEFAULT_ASHIFT SPA_MINBLOCKSHIFT +#define DEFAULT_MIRRORS 2 +#define DEFAULT_RAID_CHILDREN 4 +#define DEFAULT_RAID_PARITY 1 +#define DEFAULT_DRAID_DATA 4 +#define DEFAULT_DRAID_SPARES 1 +#define DEFAULT_DATASETS_COUNT 7 +#define DEFAULT_THREADS 23 +#define DEFAULT_RUN_TIME 300 /* 300 seconds */ +#define DEFAULT_RUN_TIME_STR "300 sec" +#define DEFAULT_PASS_TIME 60 /* 60 seconds */ +#define DEFAULT_PASS_TIME_STR "60 sec" +#define DEFAULT_KILL_RATE 70 /* 70% kill rate */ +#define DEFAULT_KILLRATE_STR "70%" +#define DEFAULT_INITS 1 +#define DEFAULT_MAX_LOOPS 50 /* 5 minutes */ +#define DEFAULT_FORCE_GANGING (64 << 10) +#define DEFAULT_FORCE_GANGING_STR "64K" + +/* Simplifying assumption: -1 is not a valid default. */ +#define NO_DEFAULT -1 + static const ztest_shared_opts_t ztest_opts_defaults = { - .zo_pool = "ztest", - .zo_dir = "/tmp", + .zo_pool = DEFAULT_POOL, + .zo_dir = DEFAULT_VDEV_DIR, .zo_alt_ztest = { '\0' }, .zo_alt_libpath = { '\0' }, - .zo_vdevs = 5, - .zo_ashift = SPA_MINBLOCKSHIFT, - .zo_mirrors = 2, - .zo_raid_children = 4, - .zo_raid_parity = 1, + .zo_vdevs = DEFAULT_VDEV_COUNT, + .zo_ashift = DEFAULT_ASHIFT, + .zo_mirrors = DEFAULT_MIRRORS, + .zo_raid_children = DEFAULT_RAID_CHILDREN, + .zo_raid_parity = DEFAULT_RAID_PARITY, .zo_raid_type = VDEV_TYPE_RAIDZ, - .zo_vdev_size = SPA_MINDEVSIZE * 4, /* 256m default size */ - .zo_draid_data = 4, /* data drives */ - .zo_draid_spares = 1, /* distributed spares */ - .zo_datasets = 7, - .zo_threads = 23, - .zo_passtime = 60, /* 60 seconds */ - .zo_killrate = 70, /* 70% kill rate */ + .zo_vdev_size = DEFAULT_VDEV_SIZE, + .zo_draid_data = DEFAULT_DRAID_DATA, /* data drives */ + .zo_draid_spares = DEFAULT_DRAID_SPARES, /* distributed spares */ + .zo_datasets = DEFAULT_DATASETS_COUNT, + .zo_threads = DEFAULT_THREADS, + .zo_passtime = DEFAULT_PASS_TIME, + .zo_killrate = DEFAULT_KILL_RATE, .zo_verbose = 0, .zo_mmp_test = 0, - .zo_init = 1, - .zo_time = 300, /* 5 minutes */ - .zo_maxloops = 50, /* max loops during spa_freeze() */ - .zo_metaslab_force_ganging = 64 << 10, + .zo_init = DEFAULT_INITS, + .zo_time = DEFAULT_RUN_TIME, + .zo_maxloops = DEFAULT_MAX_LOOPS, /* max loops during spa_freeze() */ + .zo_metaslab_force_ganging = DEFAULT_FORCE_GANGING, .zo_special_vdevs = ZTEST_VDEV_CLASS_RND, .zo_gvars_count = 0, }; @@ -684,68 +713,154 @@ nicenumtoull(const char *buf) return (val); } +typedef struct ztest_option { + const char short_opt; + const char *long_opt; + const char *long_opt_param; + const char *comment; + unsigned int default_int; + char *default_str; +} ztest_option_t; + +/* + * The following option_table is used for generating the usage info as well as + * the long and short option information for calling getopt_long(). + */ +static ztest_option_t option_table[] = { + { 'v', "vdevs", "INTEGER", "Number of vdevs", DEFAULT_VDEV_COUNT, + NULL}, + { 's', "vdev-size", "INTEGER", "Size of each vdev", + NO_DEFAULT, DEFAULT_VDEV_SIZE_STR}, + { 'a', "alignment-shift", "INTEGER", + "Alignment shift; use 0 for random", DEFAULT_ASHIFT, NULL}, + { 'm', "mirror-copies", "INTEGER", "Number of mirror copies", + DEFAULT_MIRRORS, NULL}, + { 'r', "raid-disks", "INTEGER", "Number of raidz/draid disks", + DEFAULT_RAID_CHILDREN, NULL}, + { 'R', "raid-parity", "INTEGER", "Raid parity", + DEFAULT_RAID_PARITY, NULL}, + { 'K', "raid-kind", "raidz|draid|random", "Raid kind", + NO_DEFAULT, "random"}, + { 'D', "draid-data", "INTEGER", "Number of draid data drives", + DEFAULT_DRAID_DATA, NULL}, + { 'S', "draid-spares", "INTEGER", "Number of draid spares", + DEFAULT_DRAID_SPARES, NULL}, + { 'd', "datasets", "INTEGER", "Number of datasets", + DEFAULT_DATASETS_COUNT, NULL}, + { 't', "threads", "INTEGER", "Number of ztest threads", + DEFAULT_THREADS, NULL}, + { 'g', "gang-block-threshold", "INTEGER", + "Metaslab gang block threshold", + NO_DEFAULT, DEFAULT_FORCE_GANGING_STR}, + { 'i', "init-count", "INTEGER", "Number of times to initialize pool", + DEFAULT_INITS, NULL}, + { 'k', "kill-percentage", "INTEGER", "Kill percentage", + NO_DEFAULT, DEFAULT_KILLRATE_STR}, + { 'p', "pool-name", "STRING", "Pool name", + NO_DEFAULT, DEFAULT_POOL}, + { 'f', "vdev-file-directory", "PATH", "File directory for vdev files", + NO_DEFAULT, DEFAULT_VDEV_DIR}, + { 'M', "multi-host", NULL, + "Multi-host; simulate pool imported on remote host", + NO_DEFAULT, NULL}, + { 'E', "use-existing-pool", NULL, + "Use existing pool instead of creating new one", NO_DEFAULT, NULL}, + { 'T', "run-time", "INTEGER", "Total run time", + NO_DEFAULT, DEFAULT_RUN_TIME_STR}, + { 'P', "pass-time", "INTEGER", "Time per pass", + NO_DEFAULT, DEFAULT_PASS_TIME_STR}, + { 'F', "freeze-loops", "INTEGER", "Max loops in spa_freeze()", + DEFAULT_MAX_LOOPS, NULL}, + { 'B', "alt-ztest", "PATH", "Alternate ztest path", + NO_DEFAULT, NULL}, + { 'C', "vdev-class-state", "on|off|random", "vdev class state", + NO_DEFAULT, "random"}, + { 'o', "option", "\"OPTION=INTEGER\"", + "Set global variable to an unsigned 32-bit integer value", + NO_DEFAULT, NULL}, + { 'G', "dump-debug-msg", NULL, + "Dump zfs_dbgmsg buffer before exiting due to an error", + NO_DEFAULT, NULL}, + { 'V', "verbose", NULL, + "Verbose (use multiple times for ever more verbosity)", + NO_DEFAULT, NULL}, + { 'h', "help", NULL, "Show this help", + NO_DEFAULT, NULL}, + {0, 0, 0, 0, 0, 0} +}; + +static struct option *long_opts = NULL; +static char *short_opts = NULL; + +static void +init_options(void) +{ + ASSERT3P(long_opts, ==, NULL); + ASSERT3P(short_opts, ==, NULL); + + int count = sizeof (option_table) / sizeof (option_table[0]); + long_opts = umem_alloc(sizeof (struct option) * count, UMEM_NOFAIL); + + short_opts = umem_alloc(sizeof (char) * 2 * count, UMEM_NOFAIL); + int short_opt_index = 0; + + for (int i = 0; i < count; i++) { + long_opts[i].val = option_table[i].short_opt; + long_opts[i].name = option_table[i].long_opt; + long_opts[i].has_arg = option_table[i].long_opt_param != NULL + ? required_argument : no_argument; + long_opts[i].flag = NULL; + short_opts[short_opt_index++] = option_table[i].short_opt; + if (option_table[i].long_opt_param != NULL) { + short_opts[short_opt_index++] = ':'; + } + } +} + +static void +fini_options(void) +{ + int count = sizeof (option_table) / sizeof (option_table[0]); + + umem_free(long_opts, sizeof (struct option) * count); + umem_free(short_opts, sizeof (char) * 2 * count); + + long_opts = NULL; + short_opts = NULL; +} + static void usage(boolean_t requested) { - const ztest_shared_opts_t *zo = &ztest_opts_defaults; - - char nice_vdev_size[NN_NUMBUF_SZ]; - char nice_force_ganging[NN_NUMBUF_SZ]; + char option[80]; FILE *fp = requested ? stdout : stderr; - nicenum(zo->zo_vdev_size, nice_vdev_size, sizeof (nice_vdev_size)); - nicenum(zo->zo_metaslab_force_ganging, nice_force_ganging, - sizeof (nice_force_ganging)); + (void) fprintf(fp, "Usage: %s [OPTIONS...]\n", DEFAULT_POOL); + for (int i = 0; option_table[i].short_opt != 0; i++) { + if (option_table[i].long_opt_param != NULL) { + (void) sprintf(option, " -%c --%s=%s", + option_table[i].short_opt, + option_table[i].long_opt, + option_table[i].long_opt_param); + } else { + (void) sprintf(option, " -%c --%s", + option_table[i].short_opt, + option_table[i].long_opt); + } + (void) fprintf(fp, " %-40s%s", option, + option_table[i].comment); - (void) fprintf(fp, "Usage: %s\n" - "\t[-v vdevs (default: %llu)]\n" - "\t[-s size_of_each_vdev (default: %s)]\n" - "\t[-a alignment_shift (default: %d)] use 0 for random\n" - "\t[-m mirror_copies (default: %d)]\n" - "\t[-r raidz_disks / draid_disks (default: %d)]\n" - "\t[-R raid_parity (default: %d)]\n" - "\t[-K raid_kind (default: random)] raidz|draid|random\n" - "\t[-D draid_data (default: %d)] in config\n" - "\t[-S draid_spares (default: %d)]\n" - "\t[-d datasets (default: %d)]\n" - "\t[-t threads (default: %d)]\n" - "\t[-g gang_block_threshold (default: %s)]\n" - "\t[-i init_count (default: %d)] initialize pool i times\n" - "\t[-k kill_percentage (default: %llu%%)]\n" - "\t[-p pool_name (default: %s)]\n" - "\t[-f dir (default: %s)] file directory for vdev files\n" - "\t[-M] Multi-host simulate pool imported on remote host\n" - "\t[-V] verbose (use multiple times for ever more blather)\n" - "\t[-E] use existing pool instead of creating new one\n" - "\t[-T time (default: %llu sec)] total run time\n" - "\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n" - "\t[-P passtime (default: %llu sec)] time per pass\n" - "\t[-B alt_ztest (default: )] alternate ztest path\n" - "\t[-C vdev class state (default: random)] special=on|off|random\n" - "\t[-o variable=value] ... set global variable to an unsigned\n" - "\t 32-bit integer value\n" - "\t[-G dump zfs_dbgmsg buffer before exiting due to an error\n" - "\t[-h] (print help)\n" - "", - zo->zo_pool, - (u_longlong_t)zo->zo_vdevs, /* -v */ - nice_vdev_size, /* -s */ - zo->zo_ashift, /* -a */ - zo->zo_mirrors, /* -m */ - zo->zo_raid_children, /* -r */ - zo->zo_raid_parity, /* -R */ - zo->zo_draid_data, /* -D */ - zo->zo_draid_spares, /* -S */ - zo->zo_datasets, /* -d */ - zo->zo_threads, /* -t */ - nice_force_ganging, /* -g */ - zo->zo_init, /* -i */ - (u_longlong_t)zo->zo_killrate, /* -k */ - zo->zo_pool, /* -p */ - zo->zo_dir, /* -f */ - (u_longlong_t)zo->zo_time, /* -T */ - (u_longlong_t)zo->zo_maxloops, /* -F */ - (u_longlong_t)zo->zo_passtime); + if (option_table[i].long_opt_param != NULL) { + if (option_table[i].default_str != NULL) { + (void) fprintf(fp, " (default: %s)", + option_table[i].default_str); + } else if (option_table[i].default_int != NO_DEFAULT) { + (void) fprintf(fp, " (default: %u)", + option_table[i].default_int); + } + } + (void) fprintf(fp, "\n"); + } exit(requested ? 0 : 1); } @@ -817,8 +932,10 @@ process_options(int argc, char **argv) bcopy(&ztest_opts_defaults, zo, sizeof (*zo)); - while ((opt = getopt(argc, argv, - "v:s:a:m:r:R:K:D:S:d:t:g:i:k:p:f:MVET:P:hF:B:C:o:G")) != EOF) { + init_options(); + + while ((opt = getopt_long(argc, argv, short_opts, long_opts, + NULL)) != EOF) { value = 0; switch (opt) { case 'v': @@ -953,6 +1070,8 @@ process_options(int argc, char **argv) } } + fini_options(); + /* When raid choice is 'random' add a draid pool 50% of the time */ if (strcmp(raid_kind, "random") == 0) { (void) strlcpy(raid_kind, (ztest_random(2) == 0) ? @@ -5979,7 +6098,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id) vd0->vdev_resilver_txg != 0)) { /* * Make vd0 explicitly claim to be unreadable, - * or unwriteable, or reach behind its back + * or unwritable, or reach behind its back * and close the underlying fd. We can do this if * maxfaults == 0 because we'll fail and reexecute, * and we can do it if maxfaults >= 2 because we'll diff --git a/sys/contrib/openzfs/cmd/zvol_wait/Makefile.am b/sys/contrib/openzfs/cmd/zvol_wait/Makefile.am index 564031c9799..2e5bf332338 100644 --- a/sys/contrib/openzfs/cmd/zvol_wait/Makefile.am +++ b/sys/contrib/openzfs/cmd/zvol_wait/Makefile.am @@ -1 +1,3 @@ +include $(top_srcdir)/config/Shellcheck.am + dist_bin_SCRIPTS = zvol_wait diff --git a/sys/contrib/openzfs/cmd/zvol_wait/zvol_wait b/sys/contrib/openzfs/cmd/zvol_wait/zvol_wait index 9a3948da556..2aa929b0ca2 100755 --- a/sys/contrib/openzfs/cmd/zvol_wait/zvol_wait +++ b/sys/contrib/openzfs/cmd/zvol_wait/zvol_wait @@ -9,45 +9,42 @@ count_zvols() { } filter_out_zvols_with_links() { - while read -r zvol; do - if [ ! -L "/dev/zvol/$zvol" ]; then + echo "$zvols" | tr ' ' '+' | while read -r zvol; do + if ! [ -L "/dev/zvol/$zvol" ]; then echo "$zvol" fi - done + done | tr '+' ' ' } filter_out_deleted_zvols() { - while read -r zvol; do - if zfs list "$zvol" >/dev/null 2>&1; then - echo "$zvol" - fi - done + OIFS="$IFS" + IFS=" +" + # shellcheck disable=SC2086 + zfs list -H -o name $zvols 2>/dev/null + IFS="$OIFS" } list_zvols() { + read -r default_volmode < /sys/module/zfs/parameters/zvol_volmode zfs list -t volume -H -o \ - name,volmode,receive_resume_token,redact_snaps | - while read -r zvol_line; do - name=$(echo "$zvol_line" | awk '{print $1}') - volmode=$(echo "$zvol_line" | awk '{print $2}') - token=$(echo "$zvol_line" | awk '{print $3}') - redacted=$(echo "$zvol_line" | awk '{print $4}') - # + name,volmode,receive_resume_token,redact_snaps | + while IFS=" " read -r name volmode token redacted; do # IFS=\t here! + # /dev links are not created for zvols with volmode = "none" # or for redacted zvols. - # [ "$volmode" = "none" ] && continue + [ "$volmode" = "default" ] && [ "$default_volmode" = "3" ] && + continue [ "$redacted" = "-" ] || continue - # - # We also also ignore partially received zvols if it is + + # We also ignore partially received zvols if it is # not an incremental receive, as those won't even have a block # device minor node created yet. - # if [ "$token" != "-" ]; then - # + # Incremental receives create an invisible clone that # is not automatically displayed by zfs list. - # if ! zfs list "$name/%recv" >/dev/null 2>&1; then continue fi @@ -75,7 +72,7 @@ while [ "$outer_loop" -lt 20 ]; do while [ "$inner_loop" -lt 30 ]; do inner_loop=$((inner_loop + 1)) - zvols="$(echo "$zvols" | filter_out_zvols_with_links)" + zvols="$(filter_out_zvols_with_links)" zvols_count=$(count_zvols) if [ "$zvols_count" -eq 0 ]; then @@ -95,7 +92,7 @@ while [ "$outer_loop" -lt 20 ]; do echo "No progress since last loop." echo "Checking if any zvols were deleted." - zvols=$(echo "$zvols" | filter_out_deleted_zvols) + zvols=$(filter_out_deleted_zvols) zvols_count=$(count_zvols) if [ "$old_zvols_count" -ne "$zvols_count" ]; then diff --git a/sys/contrib/openzfs/config/Abigail.am b/sys/contrib/openzfs/config/Abigail.am index 599f611942b..0a74741b4e4 100644 --- a/sys/contrib/openzfs/config/Abigail.am +++ b/sys/contrib/openzfs/config/Abigail.am @@ -25,5 +25,5 @@ checkabi: storeabi: cd .libs ; \ for lib in $(lib_LTLIBRARIES) ; do \ - abidw $${lib%.la}.so > ../$${lib%.la}.abi ; \ + abidw --no-show-locs $${lib%.la}.so > ../$${lib%.la}.abi ; \ done diff --git a/sys/contrib/openzfs/config/CppCheck.am b/sys/contrib/openzfs/config/CppCheck.am index 13c633c6003..e53013bd01c 100644 --- a/sys/contrib/openzfs/config/CppCheck.am +++ b/sys/contrib/openzfs/config/CppCheck.am @@ -1,5 +1,5 @@ # -# Default rules for running cppcheck against the the user space components. +# Default rules for running cppcheck against the user space components. # PHONY += cppcheck diff --git a/sys/contrib/openzfs/config/Rules.am b/sys/contrib/openzfs/config/Rules.am index 99587eab2bf..ef10d493896 100644 --- a/sys/contrib/openzfs/config/Rules.am +++ b/sys/contrib/openzfs/config/Rules.am @@ -53,6 +53,7 @@ endif if BUILD_FREEBSD AM_CPPFLAGS += -DTEXT_DOMAIN=\"zfs-freebsd-user\" endif +AM_CPPFLAGS += -D"strtok(...)=strtok(__VA_ARGS__) __attribute__((deprecated(\"Use strtok_r(3) instead!\")))" AM_LDFLAGS = $(DEBUG_LDFLAGS) AM_LDFLAGS += $(ASAN_LDFLAGS) diff --git a/sys/contrib/openzfs/config/Shellcheck.am b/sys/contrib/openzfs/config/Shellcheck.am new file mode 100644 index 00000000000..6b805b797d1 --- /dev/null +++ b/sys/contrib/openzfs/config/Shellcheck.am @@ -0,0 +1,22 @@ +.PHONY: shellcheck +shellcheck: $(SCRIPTS) $(SHELLCHECKSCRIPTS) +if HAVE_SHELLCHECK + [ -z "$(SCRIPTS)$(SHELLCHECKSCRIPTS)" ] && exit; shellcheck $$([ -n "$(SHELLCHECK_SHELL)" ] && echo "--shell=$(SHELLCHECK_SHELL)") --exclude=SC1090,SC1091$(SHELLCHECK_IGNORE) --format=gcc $(SCRIPTS) $(SHELLCHECKSCRIPTS) +else + @[ -z "$(SCRIPTS)$(SHELLCHECKSCRIPTS)" ] && exit; echo "skipping shellcheck of" $(SCRIPTS) $(SHELLCHECKSCRIPTS) "because shellcheck is not installed" +endif + @set -e; for dir in $(SHELLCHECKDIRS); do $(MAKE) -C $$dir shellcheck; done + + +# command -v *is* specified by POSIX and every shell in existence supports it +.PHONY: checkbashisms +checkbashisms: $(SCRIPTS) $(SHELLCHECKSCRIPTS) +if HAVE_CHECKBASHISMS + [ -z "$(SCRIPTS)$(SHELLCHECKSCRIPTS)" ] && exit; ! if [ -z "$(SHELLCHECK_SHELL)" ]; then \ + checkbashisms -npx $(SCRIPTS) $(SHELLCHECKSCRIPTS); else \ + for f in $(SCRIPTS) $(SHELLCHECKSCRIPTS); do echo $$f >&3; { echo '#!/bin/$(SHELLCHECK_SHELL)'; cat $$f; } | checkbashisms -npx; done; \ + fi 3>&2 2>&1 | grep -vFe "'command' with option other than -p" -e 'command -v' $(CHECKBASHISMS_IGNORE) >&2 +else + @[ -z "$(SCRIPTS)$(SHELLCHECKSCRIPTS)" ] && exit; echo "skipping checkbashisms of" $(SCRIPTS) $(SHELLCHECKSCRIPTS) "because checkbashisms is not installed" +endif + @set -e; for dir in $(SHELLCHECKDIRS); do $(MAKE) -C $$dir checkbashisms; done diff --git a/sys/contrib/openzfs/config/Substfiles.am b/sys/contrib/openzfs/config/Substfiles.am index 63697bfa2b6..911903e10e6 100644 --- a/sys/contrib/openzfs/config/Substfiles.am +++ b/sys/contrib/openzfs/config/Substfiles.am @@ -15,7 +15,9 @@ subst_sed_cmd = \ -e 's|@PYTHON[@]|$(PYTHON)|g' \ -e 's|@PYTHON_SHEBANG[@]|$(PYTHON_SHEBANG)|g' \ -e 's|@DEFAULT_INIT_NFS_SERVER[@]|$(DEFAULT_INIT_NFS_SERVER)|g' \ - -e 's|@DEFAULT_INIT_SHELL[@]|$(DEFAULT_INIT_SHELL)|g' + -e 's|@DEFAULT_INIT_SHELL[@]|$(DEFAULT_INIT_SHELL)|g' \ + -e 's|@LIBFETCH_DYNAMIC[@]|$(LIBFETCH_DYNAMIC)|g' \ + -e 's|@LIBFETCH_SONAME[@]|$(LIBFETCH_SONAME)|g' SUBSTFILES = CLEANFILES = $(SUBSTFILES) diff --git a/sys/contrib/openzfs/config/always-shellcheck.m4 b/sys/contrib/openzfs/config/always-shellcheck.m4 new file mode 100644 index 00000000000..2a9a099746f --- /dev/null +++ b/sys/contrib/openzfs/config/always-shellcheck.m4 @@ -0,0 +1,10 @@ +dnl # +dnl # Check if shellcheck and/or checkbashisms are available. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_SHELLCHECK], [ + AC_CHECK_PROG([SHELLCHECK], [shellcheck], [yes]) + AC_CHECK_PROG([CHECKBASHISMS], [checkbashisms], [yes]) + + AM_CONDITIONAL([HAVE_SHELLCHECK], [test "x$SHELLCHECK" = "xyes"]) + AM_CONDITIONAL([HAVE_CHECKBASHISMS], [test "x$CHECKBASHISMS" = "xyes"]) +]) diff --git a/sys/contrib/openzfs/config/ax_python_devel.m4 b/sys/contrib/openzfs/config/ax_python_devel.m4 index c51b45b7d54..faf6c2b0d7e 100644 --- a/sys/contrib/openzfs/config/ax_python_devel.m4 +++ b/sys/contrib/openzfs/config/ax_python_devel.m4 @@ -148,8 +148,7 @@ variable to configure. See ``configure --help'' for reference. # Check if you have distutils, else fail # AC_MSG_CHECKING([for the distutils Python package]) - ac_distutils_result=`$PYTHON -c "import distutils" 2>&1` - if test $? -eq 0; then + if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) diff --git a/sys/contrib/openzfs/config/deb.am b/sys/contrib/openzfs/config/deb.am index 639a46efddb..cdbdbecb356 100644 --- a/sys/contrib/openzfs/config/deb.am +++ b/sys/contrib/openzfs/config/deb.am @@ -14,7 +14,19 @@ deb-local: "*** package for your distribution which provides ${ALIEN},\n" \ "*** re-run configure, and try again.\n"; \ exit 1; \ - fi) + fi; \ + if test "${ALIEN_MAJOR}" = "8" && \ + test "${ALIEN_MINOR}" = "95"; then \ + if test "${ALIEN_POINT}" = "1" || \ + test "${ALIEN_POINT}" = "2" || \ + test "${ALIEN_POINT}" = "3"; then \ + /bin/echo -e "\n" \ + "*** Installed version of ${ALIEN} is known to be broken;\n" \ + "*** attempting to generate debs will fail! See\n" \ + "*** https://github.com/openzfs/zfs/issues/11650 for details.\n"; \ + exit 1; \ + fi; \ + fi) deb-kmod: deb-local rpm-kmod name=${PACKAGE}; \ @@ -43,9 +55,9 @@ deb-utils: deb-local rpm-utils-initramfs pkg1=$${name}-$${version}.$${arch}.rpm; \ pkg2=libnvpair3-$${version}.$${arch}.rpm; \ pkg3=libuutil3-$${version}.$${arch}.rpm; \ - pkg4=libzfs4-$${version}.$${arch}.rpm; \ - pkg5=libzpool4-$${version}.$${arch}.rpm; \ - pkg6=libzfs4-devel-$${version}.$${arch}.rpm; \ + pkg4=libzfs5-$${version}.$${arch}.rpm; \ + pkg5=libzpool5-$${version}.$${arch}.rpm; \ + pkg6=libzfs5-devel-$${version}.$${arch}.rpm; \ pkg7=$${name}-test-$${version}.$${arch}.rpm; \ pkg8=$${name}-dracut-$${version}.noarch.rpm; \ pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \ @@ -56,7 +68,7 @@ deb-utils: deb-local rpm-utils-initramfs path_prepend=`mktemp -d /tmp/intercept.XXXXXX`; \ echo "#$(SHELL)" > $${path_prepend}/dh_shlibdeps; \ echo "`which dh_shlibdeps` -- \ - -xlibuutil3linux -xlibnvpair3linux -xlibzfs4linux -xlibzpool4linux" \ + -xlibuutil3linux -xlibnvpair3linux -xlibzfs5linux -xlibzpool5linux" \ >> $${path_prepend}/dh_shlibdeps; \ ## These -x arguments are passed to dpkg-shlibdeps, which exclude the ## Debianized packages from the auto-generated dependencies of the new debs, diff --git a/sys/contrib/openzfs/config/kernel-acl.m4 b/sys/contrib/openzfs/config/kernel-acl.m4 index e02ce665323..c6da4df24eb 100644 --- a/sys/contrib/openzfs/config/kernel-acl.m4 +++ b/sys/contrib/openzfs/config/kernel-acl.m4 @@ -189,7 +189,22 @@ dnl # dnl # 3.14 API change, dnl # Check if inode_operations contains the function set_acl dnl # +dnl # 5.12 API change, +dnl # set_acl() added a user_namespace* parameter first +dnl # AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [ + ZFS_LINUX_TEST_SRC([inode_operations_set_acl_userns], [ + #include + + int set_acl_fn(struct user_namespace *userns, + struct inode *inode, struct posix_acl *acl, + int type) { return 0; } + + static const struct inode_operations + iops __attribute__ ((unused)) = { + .set_acl = set_acl_fn, + }; + ],[]) ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [ #include @@ -205,11 +220,17 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [ AC_MSG_CHECKING([whether iops->set_acl() exists]) - ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [ + ZFS_LINUX_TEST_RESULT([inode_operations_set_acl_userns], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists]) + AC_DEFINE(HAVE_SET_ACL_USERNS, 1, [iops->set_acl() takes 4 args]) ],[ - AC_MSG_RESULT(no) + ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists, takes 3 args]) + ],[ + AC_MSG_RESULT(no) + ]) ]) ]) diff --git a/sys/contrib/openzfs/config/kernel-bdi.m4 b/sys/contrib/openzfs/config/kernel-bdi.m4 index 9351df71b4b..9758863a9cb 100644 --- a/sys/contrib/openzfs/config/kernel-bdi.m4 +++ b/sys/contrib/openzfs/config/kernel-bdi.m4 @@ -8,7 +8,9 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BDI], [ ], [ char *name = "bdi"; atomic_long_t zfs_bdi_seq; - int error __attribute__((unused)) = + int error __attribute__((unused)); + atomic_long_set(&zfs_bdi_seq, 0); + error = super_setup_bdi_name(&sb, "%.28s-%ld", name, atomic_long_inc_return(&zfs_bdi_seq)); ]) diff --git a/sys/contrib/openzfs/config/kernel-blk-queue.m4 b/sys/contrib/openzfs/config/kernel-blk-queue.m4 index ff2da92e9ee..1dced82ce68 100644 --- a/sys/contrib/openzfs/config/kernel-blk-queue.m4 +++ b/sys/contrib/openzfs/config/kernel-blk-queue.m4 @@ -23,8 +23,8 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_PLUG], [ ]) dnl # -dnl # 2.6.32 - 4.11, statically allocated bdi in request_queue -dnl # 4.12 - x.y, dynamically allocated bdi in request_queue +dnl # 2.6.32 - 4.11: statically allocated bdi in request_queue +dnl # 4.12: dynamically allocated bdi in request_queue dnl # AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI], [ ZFS_LINUX_TEST_SRC([blk_queue_bdi], [ @@ -48,7 +48,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_BDI], [ ]) dnl # -dnl # 2.6.32 - 4.x API, +dnl # 2.6.32 API, dnl # blk_queue_discard() dnl # AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD], [ @@ -71,7 +71,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_DISCARD], [ ]) dnl # -dnl # 4.8 - 4.x API, +dnl # 4.8 API, dnl # blk_queue_secure_erase() dnl # dnl # 2.6.36 - 4.7 API, diff --git a/sys/contrib/openzfs/config/kernel-block-device-operations.m4 b/sys/contrib/openzfs/config/kernel-block-device-operations.m4 index 8e64ecca909..a48618185bf 100644 --- a/sys/contrib/openzfs/config/kernel-block-device-operations.m4 +++ b/sys/contrib/openzfs/config/kernel-block-device-operations.m4 @@ -52,12 +52,44 @@ AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [ ]) ]) +dnl # +dnl # 5.13 API change +dnl # block_device_operations->revalidate_disk() was removed +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [ + ZFS_LINUX_TEST_SRC([block_device_operations_revalidate_disk], [ + #include + + int blk_revalidate_disk(struct gendisk *disk) { + return(0); + } + + static const struct block_device_operations + bops __attribute__ ((unused)) = { + .revalidate_disk = blk_revalidate_disk, + }; + ], [], [$NO_UNUSED_BUT_SET_VARIABLE]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [ + AC_MSG_CHECKING([whether bops->revalidate_disk() exists]) + ZFS_LINUX_TEST_RESULT([block_device_operations_revalidate_disk], [ + AC_DEFINE([HAVE_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [1], + [Define if revalidate_disk() in block_device_operations]) + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + ]) +]) + AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [ ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID + ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK ]) AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS], [ ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID + ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK ]) diff --git a/sys/contrib/openzfs/config/kernel-generic_fillattr.m4 b/sys/contrib/openzfs/config/kernel-generic_fillattr.m4 index 50c8031305b..0acd5d53103 100644 --- a/sys/contrib/openzfs/config/kernel-generic_fillattr.m4 +++ b/sys/contrib/openzfs/config/kernel-generic_fillattr.m4 @@ -16,7 +16,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS], [ ]) AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS], [ - AC_MSG_CHECKING([whether generic_fillattr requres struct user_namespace*]) + AC_MSG_CHECKING([whether generic_fillattr requires struct user_namespace*]) ZFS_LINUX_TEST_RESULT([generic_fillattr_userns], [ AC_MSG_RESULT([yes]) AC_DEFINE(HAVE_GENERIC_FILLATTR_USERNS, 1, diff --git a/sys/contrib/openzfs/config/kernel-is_owner_or_cap.m4 b/sys/contrib/openzfs/config/kernel-is_owner_or_cap.m4 index 3c3c6ad2240..a90cf3da641 100644 --- a/sys/contrib/openzfs/config/kernel-is_owner_or_cap.m4 +++ b/sys/contrib/openzfs/config/kernel-is_owner_or_cap.m4 @@ -4,6 +4,10 @@ dnl # The is_owner_or_cap() macro was renamed to inode_owner_or_capable(), dnl # This is used for permission checks in the xattr and file attribute call dnl # paths. dnl # +dnl # 5.12 API change, +dnl # inode_owner_or_capable() now takes struct user_namespace * +dnl # to support idmapped mounts +dnl # AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE], [ ZFS_LINUX_TEST_SRC([inode_owner_or_capable], [ #include diff --git a/sys/contrib/openzfs/config/kernel-percpu.m4 b/sys/contrib/openzfs/config/kernel-percpu.m4 index 700d97a2585..5125dd5c5bb 100644 --- a/sys/contrib/openzfs/config/kernel-percpu.m4 +++ b/sys/contrib/openzfs/config/kernel-percpu.m4 @@ -25,6 +25,31 @@ AC_DEFUN([ZFS_AC_KERNEL_PERCPU_COUNTER_INIT], [ ]) ]) +dnl # +dnl # 4.13 API change, +dnl # __percpu_counter_add() was renamed to percpu_counter_add_batch(). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_PERCPU_COUNTER_ADD_BATCH], [ + ZFS_LINUX_TEST_SRC([percpu_counter_add_batch], [ + #include + ],[ + struct percpu_counter counter; + + percpu_counter_add_batch(&counter, 1, 1); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_PERCPU_COUNTER_ADD_BATCH], [ + AC_MSG_CHECKING([whether percpu_counter_add_batch() is defined]) + ZFS_LINUX_TEST_RESULT([percpu_counter_add_batch], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PERCPU_COUNTER_ADD_BATCH, 1, + [percpu_counter_add_batch() is defined]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + dnl # dnl # 5.10 API change, dnl # The "count" was moved into ref->data, from ref @@ -51,10 +76,12 @@ AC_DEFUN([ZFS_AC_KERNEL_PERCPU_REF_COUNT_IN_DATA], [ ]) AC_DEFUN([ZFS_AC_KERNEL_SRC_PERCPU], [ ZFS_AC_KERNEL_SRC_PERCPU_COUNTER_INIT + ZFS_AC_KERNEL_SRC_PERCPU_COUNTER_ADD_BATCH ZFS_AC_KERNEL_SRC_PERCPU_REF_COUNT_IN_DATA ]) AC_DEFUN([ZFS_AC_KERNEL_PERCPU], [ ZFS_AC_KERNEL_PERCPU_COUNTER_INIT + ZFS_AC_KERNEL_PERCPU_COUNTER_ADD_BATCH ZFS_AC_KERNEL_PERCPU_REF_COUNT_IN_DATA ]) diff --git a/sys/contrib/openzfs/config/kernel-rename.m4 b/sys/contrib/openzfs/config/kernel-rename.m4 index 31d199f33bb..302db43f574 100644 --- a/sys/contrib/openzfs/config/kernel-rename.m4 +++ b/sys/contrib/openzfs/config/kernel-rename.m4 @@ -44,6 +44,7 @@ AC_DEFUN([ZFS_AC_KERNEL_RENAME], [ ],[ AC_MSG_RESULT(no) + AC_MSG_CHECKING([whether iop->rename() wants flags]) ZFS_LINUX_TEST_RESULT([inode_operations_rename_flags], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1, diff --git a/sys/contrib/openzfs/config/kernel-siginfo.m4 b/sys/contrib/openzfs/config/kernel-siginfo.m4 new file mode 100644 index 00000000000..6ddb0dcc37d --- /dev/null +++ b/sys/contrib/openzfs/config/kernel-siginfo.m4 @@ -0,0 +1,21 @@ +dnl # +dnl # 4.20 API change +dnl # Added kernel_siginfo_t +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SIGINFO], [ + ZFS_LINUX_TEST_SRC([siginfo], [ + #include + ],[ + kernel_siginfo_t info __attribute__ ((unused)); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SIGINFO], [ + AC_MSG_CHECKING([whether kernel_siginfo_t tyepedef exists]) + ZFS_LINUX_TEST_RESULT([siginfo], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SIGINFO, 1, [kernel_siginfo_t exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/sys/contrib/openzfs/config/kernel-signal-stop.m4 b/sys/contrib/openzfs/config/kernel-signal-stop.m4 new file mode 100644 index 00000000000..6cb86e7c4cd --- /dev/null +++ b/sys/contrib/openzfs/config/kernel-signal-stop.m4 @@ -0,0 +1,21 @@ +dnl # +dnl # 4.4 API change +dnl # Added kernel_signal_stop +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SIGNAL_STOP], [ + ZFS_LINUX_TEST_SRC([signal_stop], [ + #include + ],[ + kernel_signal_stop(); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SIGNAL_STOP], [ + AC_MSG_CHECKING([whether signal_stop() exists]) + ZFS_LINUX_TEST_RESULT([signal_stop], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SIGNAL_STOP, 1, [signal_stop() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/sys/contrib/openzfs/config/kernel-special-state.m4 b/sys/contrib/openzfs/config/kernel-special-state.m4 new file mode 100644 index 00000000000..aa60aabebc4 --- /dev/null +++ b/sys/contrib/openzfs/config/kernel-special-state.m4 @@ -0,0 +1,21 @@ +dnl # +dnl # 4.17 API change +dnl # Added set_special_state() function +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SET_SPECIAL_STATE], [ + ZFS_LINUX_TEST_SRC([set_special_state], [ + #include + ],[ + set_special_state(TASK_STOPPED); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SET_SPECIAL_STATE], [ + AC_MSG_CHECKING([whether set_special_state() exists]) + ZFS_LINUX_TEST_RESULT([set_special_state], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SET_SPECIAL_STATE, 1, [set_special_state() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/sys/contrib/openzfs/config/kernel-tmpfile.m4 b/sys/contrib/openzfs/config/kernel-tmpfile.m4 index f510bfe6ba0..45c2e6ceea5 100644 --- a/sys/contrib/openzfs/config/kernel-tmpfile.m4 +++ b/sys/contrib/openzfs/config/kernel-tmpfile.m4 @@ -3,23 +3,43 @@ dnl # 3.11 API change dnl # Add support for i_op->tmpfile dnl # AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [ - ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [ + dnl # + dnl # 5.11 API change + dnl # add support for userns parameter to tmpfile + dnl # + ZFS_LINUX_TEST_SRC([inode_operations_tmpfile_userns], [ #include - int tmpfile(struct inode *inode, struct dentry *dentry, + int tmpfile(struct user_namespace *userns, + struct inode *inode, struct dentry *dentry, umode_t mode) { return 0; } static struct inode_operations iops __attribute__ ((unused)) = { .tmpfile = tmpfile, }; ],[]) + ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [ + #include + int tmpfile(struct inode *inode, struct dentry *dentry, + umode_t mode) { return 0; } + static struct inode_operations + iops __attribute__ ((unused)) = { + .tmpfile = tmpfile, + }; + ],[]) ]) AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [ AC_MSG_CHECKING([whether i_op->tmpfile() exists]) - ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [ + ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_userns], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists]) + AC_DEFINE(HAVE_TMPFILE_USERNS, 1, [i_op->tmpfile() has userns]) ],[ - AC_MSG_RESULT(no) + ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists]) + ],[ + AC_MSG_RESULT(no) + ]) ]) ]) diff --git a/sys/contrib/openzfs/config/kernel.m4 b/sys/contrib/openzfs/config/kernel.m4 index dfb6165d879..7196e66ca28 100644 --- a/sys/contrib/openzfs/config/kernel.m4 +++ b/sys/contrib/openzfs/config/kernel.m4 @@ -129,6 +129,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ ZFS_AC_KERNEL_SRC_MKNOD ZFS_AC_KERNEL_SRC_SYMLINK ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS + ZFS_AC_KERNEL_SRC_SIGNAL_STOP + ZFS_AC_KERNEL_SRC_SIGINFO + ZFS_AC_KERNEL_SRC_SET_SPECIAL_STATE AC_MSG_CHECKING([for available kernel interfaces]) ZFS_LINUX_TEST_COMPILE_ALL([kabi]) @@ -231,6 +234,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ ZFS_AC_KERNEL_MKNOD ZFS_AC_KERNEL_SYMLINK ZFS_AC_KERNEL_BIO_MAX_SEGS + ZFS_AC_KERNEL_SIGNAL_STOP + ZFS_AC_KERNEL_SIGINFO + ZFS_AC_KERNEL_SET_SPECIAL_STATE ]) dnl # diff --git a/sys/contrib/openzfs/config/user-libatomic.m4 b/sys/contrib/openzfs/config/user-libatomic.m4 new file mode 100644 index 00000000000..14a60bbea9d --- /dev/null +++ b/sys/contrib/openzfs/config/user-libatomic.m4 @@ -0,0 +1,34 @@ +dnl # +dnl # If -latomic exists, it's needed for __atomic intrinsics. +dnl # +dnl # Some systems (like FreeBSD 13) don't have a libatomic at all because +dnl # their toolchain doesn't ship it – they obviously don't need it. +dnl # +dnl # Others (like sufficiently ancient CentOS) have one, +dnl # but terminally broken or unlinkable (e.g. it's a dangling symlink, +dnl # or a linker script that points to a nonexistent file) – +dnl # most arches affected by this don't actually need -latomic (and if they do, +dnl # then they should have libatomic that actually exists and links, +dnl # so don't fall into this category). +dnl # +dnl # Technically, we could check if the platform *actually* needs -latomic, +dnl # or if it has native support for all the intrinsics we use, +dnl # but it /really/ doesn't matter, and C11 recommends to always link it. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_LIBATOMIC], [ + AC_MSG_CHECKING([whether -latomic is present]) + + saved_libs="$LIBS" + LIBS="$LIBS -latomic" + + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [ + LIBATOMIC_LIBS="-latomic" + AC_MSG_RESULT([yes]) + ], [ + LIBATOMIC_LIBS="" + AC_MSG_RESULT([no]) + ]) + + LIBS="$saved_libs" + AC_SUBST([LIBATOMIC_LIBS]) +]) diff --git a/sys/contrib/openzfs/config/user-libfetch.m4 b/sys/contrib/openzfs/config/user-libfetch.m4 new file mode 100644 index 00000000000..f5149fc1a5d --- /dev/null +++ b/sys/contrib/openzfs/config/user-libfetch.m4 @@ -0,0 +1,71 @@ +dnl # +dnl # Check for a libfetch - either fetch(3) or libcurl. +dnl # +dnl # There are two configuration dimensions: +dnl # * fetch(3) vs libcurl +dnl # * static vs dynamic +dnl # +dnl # fetch(3) is only dynamic. +dnl # We use sover 6, which first appeared in FreeBSD 8.0-RELEASE. +dnl # +dnl # libcurl development packages include curl-config(1) – we want: +dnl # * HTTPS support +dnl # * version at least 7.16 (October 2006), for sover 4 +dnl # * to decide if it's static or not +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_LIBFETCH], [ + AC_MSG_CHECKING([for libfetch]) + LIBFETCH_LIBS= + LIBFETCH_IS_FETCH=0 + LIBFETCH_IS_LIBCURL=0 + LIBFETCH_DYNAMIC=0 + LIBFETCH_SONAME= + have_libfetch= + + saved_libs="$LIBS" + LIBS="$LIBS -lfetch" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + #include + ]], [fetchGetURL("", "");])], [ + have_libfetch=1 + LIBFETCH_IS_FETCH=1 + LIBFETCH_DYNAMIC=1 + LIBFETCH_SONAME='"libfetch.so.6"' + LIBFETCH_LIBS="-ldl" + AC_MSG_RESULT([fetch(3)]) + ], []) + LIBS="$saved_libs" + + if test -z "$have_libfetch"; then + if curl-config --protocols 2>/dev/null | grep -q HTTPS && + test "$(printf "%u" "0x$(curl-config --vernum)")" -ge "$(printf "%u" "0x071000")"; then + have_libfetch=1 + LIBFETCH_IS_LIBCURL=1 + if test "$(curl-config --built-shared)" = "yes"; then + LIBFETCH_DYNAMIC=1 + LIBFETCH_SONAME='"libcurl.so.4"' + LIBFETCH_LIBS="-ldl" + AC_MSG_RESULT([libcurl]) + else + LIBFETCH_LIBS="$(curl-config --libs)" + AC_MSG_RESULT([libcurl (static)]) + fi + + CCFLAGS="$CCFLAGS $(curl-config --cflags)" + fi + fi + + if test -z "$have_libfetch"; then + AC_MSG_RESULT([none]) + fi + + AC_SUBST([LIBFETCH_LIBS]) + AC_SUBST([LIBFETCH_DYNAMIC]) + AC_SUBST([LIBFETCH_SONAME]) + AC_DEFINE_UNQUOTED([LIBFETCH_IS_FETCH], [$LIBFETCH_IS_FETCH], [libfetch is fetch(3)]) + AC_DEFINE_UNQUOTED([LIBFETCH_IS_LIBCURL], [$LIBFETCH_IS_LIBCURL], [libfetch is libcurl]) + AC_DEFINE_UNQUOTED([LIBFETCH_DYNAMIC], [$LIBFETCH_DYNAMIC], [whether the chosen libfetch is to be loaded at run-time]) + AC_DEFINE_UNQUOTED([LIBFETCH_SONAME], [$LIBFETCH_SONAME], [soname of chosen libfetch]) +]) diff --git a/sys/contrib/openzfs/config/user.m4 b/sys/contrib/openzfs/config/user.m4 index c220675514e..670820b3771 100644 --- a/sys/contrib/openzfs/config/user.m4 +++ b/sys/contrib/openzfs/config/user.m4 @@ -21,6 +21,8 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [ ZFS_AC_CONFIG_USER_LIBUDEV ZFS_AC_CONFIG_USER_LIBCRYPTO ZFS_AC_CONFIG_USER_LIBAIO + ZFS_AC_CONFIG_USER_LIBATOMIC + ZFS_AC_CONFIG_USER_LIBFETCH ZFS_AC_CONFIG_USER_CLOCK_GETTIME ZFS_AC_CONFIG_USER_PAM ZFS_AC_CONFIG_USER_RUNSTATEDIR diff --git a/sys/contrib/openzfs/config/zfs-build.m4 b/sys/contrib/openzfs/config/zfs-build.m4 index cd5996c0424..1af4356cde1 100644 --- a/sys/contrib/openzfs/config/zfs-build.m4 +++ b/sys/contrib/openzfs/config/zfs-build.m4 @@ -34,6 +34,9 @@ dnl # When debugging is enabled: dnl # - Enable all ASSERTs (-DDEBUG) dnl # - Promote all compiler warnings to errors (-Werror) dnl # +dnl # (If INVARIANTS is detected, we need to force DEBUG, or strange panics +dnl # can ensue.) +dnl # AC_DEFUN([ZFS_AC_DEBUG], [ AC_MSG_CHECKING([whether assertion support will be enabled]) AC_ARG_ENABLE([debug], @@ -49,6 +52,20 @@ AC_DEFUN([ZFS_AC_DEBUG], [ [ZFS_AC_DEBUG_DISABLE], [AC_MSG_ERROR([Unknown option $enable_debug])]) + AS_CASE(["x$enable_invariants"], + ["xyes"], + [], + ["xno"], + [], + [ZFS_AC_DEBUG_INVARIANTS_DETECT]) + + AS_CASE(["x$enable_invariants"], + ["xyes"], + [ZFS_AC_DEBUG_ENABLE], + ["xno"], + [], + [AC_MSG_ERROR([Unknown option $enable_invariants])]) + AC_SUBST(DEBUG_CFLAGS) AC_SUBST(DEBUG_CPPFLAGS) AC_SUBST(DEBUG_LDFLAGS) @@ -207,6 +224,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [ ZFS_AC_CONFIG_ALWAYS_PYZFS ZFS_AC_CONFIG_ALWAYS_SED ZFS_AC_CONFIG_ALWAYS_CPPCHECK + ZFS_AC_CONFIG_ALWAYS_SHELLCHECK ]) AC_DEFUN([ZFS_AC_CONFIG], [ @@ -437,6 +455,9 @@ AC_DEFUN([ZFS_AC_ALIEN], [ AC_MSG_CHECKING([whether $ALIEN is available]) AS_IF([tmp=$($ALIEN --version 2>/dev/null)], [ ALIEN_VERSION=$(echo $tmp | $AWK '{ print $[3] }') + ALIEN_MAJOR=$(echo ${ALIEN_VERSION} | $AWK -F'.' '{ print $[1] }') + ALIEN_MINOR=$(echo ${ALIEN_VERSION} | $AWK -F'.' '{ print $[2] }') + ALIEN_POINT=$(echo ${ALIEN_VERSION} | $AWK -F'.' '{ print $[3] }') HAVE_ALIEN=yes AC_MSG_RESULT([$HAVE_ALIEN ($ALIEN_VERSION)]) ],[ @@ -447,6 +468,9 @@ AC_DEFUN([ZFS_AC_ALIEN], [ AC_SUBST(HAVE_ALIEN) AC_SUBST(ALIEN) AC_SUBST(ALIEN_VERSION) + AC_SUBST(ALIEN_MAJOR) + AC_SUBST(ALIEN_MINOR) + AC_SUBST(ALIEN_POINT) ]) dnl # diff --git a/sys/contrib/openzfs/configure.ac b/sys/contrib/openzfs/configure.ac index e31d1227139..077ad7c43f4 100644 --- a/sys/contrib/openzfs/configure.ac +++ b/sys/contrib/openzfs/configure.ac @@ -48,6 +48,7 @@ AC_CONFIG_HEADERS([zfs_config.h], [ LT_INIT AC_PROG_INSTALL AC_PROG_CC +AC_PROG_LN_S PKG_PROG_PKG_CONFIG AM_PROG_AS AM_PROG_CC_C_O @@ -83,7 +84,6 @@ AC_CONFIG_FILES([ cmd/zinject/Makefile cmd/zpool/Makefile cmd/zstream/Makefile - cmd/zstreamdump/Makefile cmd/ztest/Makefile cmd/zvol_id/Makefile cmd/zvol_wait/Makefile diff --git a/sys/contrib/openzfs/contrib/Makefile.am b/sys/contrib/openzfs/contrib/Makefile.am index 9547878d07d..5ec13ece532 100644 --- a/sys/contrib/openzfs/contrib/Makefile.am +++ b/sys/contrib/openzfs/contrib/Makefile.am @@ -1,3 +1,5 @@ +include $(top_srcdir)/config/Shellcheck.am + SUBDIRS = bash_completion.d pyzfs zcp if BUILD_LINUX SUBDIRS += bpftrace dracut initramfs @@ -6,3 +8,5 @@ if PAM_ZFS_ENABLED SUBDIRS += pam_zfs_key endif DIST_SUBDIRS = bash_completion.d bpftrace dracut initramfs pam_zfs_key pyzfs zcp + +SHELLCHECKDIRS = bash_completion.d bpftrace dracut initramfs diff --git a/sys/contrib/openzfs/contrib/bash_completion.d/.gitignore b/sys/contrib/openzfs/contrib/bash_completion.d/.gitignore new file mode 100644 index 00000000000..0fd9cc63af2 --- /dev/null +++ b/sys/contrib/openzfs/contrib/bash_completion.d/.gitignore @@ -0,0 +1 @@ +/zfs diff --git a/sys/contrib/openzfs/contrib/bash_completion.d/Makefile.am b/sys/contrib/openzfs/contrib/bash_completion.d/Makefile.am index 4f13af6b3c3..8c8d1acebe1 100644 --- a/sys/contrib/openzfs/contrib/bash_completion.d/Makefile.am +++ b/sys/contrib/openzfs/contrib/bash_completion.d/Makefile.am @@ -1,5 +1,13 @@ +include $(top_srcdir)/config/Substfiles.am +include $(top_srcdir)/config/Shellcheck.am + bashcompletiondir = $(sysconfdir)/bash_completion.d noinst_DATA = zfs -EXTRA_DIST = $(noinst_DATA) +EXTRA_DIST += $(noinst_DATA) +SUBSTFILES += $(noinst_DATA) + +SHELLCHECKSCRIPTS = $(noinst_DATA) +SHELLCHECK_SHELL = bash +SHELLCHECK_IGNORE = ,SC2207 diff --git a/sys/contrib/openzfs/contrib/bash_completion.d/zfs b/sys/contrib/openzfs/contrib/bash_completion.d/zfs.in similarity index 88% rename from sys/contrib/openzfs/contrib/bash_completion.d/zfs rename to sys/contrib/openzfs/contrib/bash_completion.d/zfs.in index 094527340c8..41ce2f871e3 100644 --- a/sys/contrib/openzfs/contrib/bash_completion.d/zfs +++ b/sys/contrib/openzfs/contrib/bash_completion.d/zfs.in @@ -21,13 +21,8 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. -if [[ -w /dev/zfs ]]; then - __ZFS_CMD="zfs" - __ZPOOL_CMD="zpool" -else - __ZFS_CMD="sudo zfs" - __ZPOOL_CMD="sudo zpool" -fi +__ZFS_CMD="@sbindir@/zfs" +__ZPOOL_CMD="@sbindir@/zpool" # Disable bash's built-in hostname completion, as this makes it impossible to # provide completions containing an @-sign, which is necessary for completing @@ -67,24 +62,25 @@ __zfs_list_filesystems() __zfs_match_snapshot() { - local base_dataset=${cur%@*} - if [[ $base_dataset != $cur ]] + local base_dataset="${cur%@*}" + if [ "$base_dataset" != "$cur" ] then - $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 $base_dataset + $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset" else - if [[ $cur != "" ]] && __zfs_list_datasets $cur &> /dev/null + if [ "$cur" != "" ] && __zfs_list_datasets "$cur" &> /dev/null then - $__ZFS_CMD list -H -o name -s name -t filesystem -r $cur | tail -n +2 + $__ZFS_CMD list -H -o name -s name -t filesystem -r "$cur" | tail -n +2 # We output the base dataset name even though we might be # completing a command that can only take a snapshot, because it # prevents bash from considering the completion finished when it # ends in the bare @. - echo $cur - echo $cur@ + echo "$cur" + echo "$cur@" else - local datasets=$(__zfs_list_datasets) + local datasets + datasets="$(__zfs_list_datasets)" # As above - echo $datasets + echo "$datasets" if [[ "$cur" == */ ]] then # If the current command ends with a slash, then the only way @@ -94,54 +90,57 @@ __zfs_match_snapshot() local num_children # This is actually off by one as zfs list includes the named # dataset in addition to its children - num_children=$(__zfs_list_datasets -d 1 ${cur%/} 2> /dev/null | wc -l) + num_children=$(__zfs_list_datasets -d 1 "${cur%/}" 2> /dev/null | wc -l) if [[ $num_children != 2 ]] then return 0 fi fi - echo "$datasets" | awk '{print $1"@"}' + echo "$datasets" | awk '{print $1 "@"}' fi fi } __zfs_match_snapshot_or_bookmark() { - local base_dataset=${cur%[#@]*} - if [[ $base_dataset != $cur ]] + local base_dataset="${cur%[#@]*}" + if [ "$base_dataset" != "$cur" ] then if [[ $cur == *@* ]] then - $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 $base_dataset + $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset" else - $__ZFS_CMD list -H -o name -s name -t bookmark -d 1 $base_dataset + $__ZFS_CMD list -H -o name -s name -t bookmark -d 1 "$base_dataset" fi else $__ZFS_CMD list -H -o name -s name -t filesystem,volume - if [[ $cur != "" ]] && $__ZFS_CMD list -H -o name -s name -t filesystem,volume $cur &> /dev/null + if [ -e "$cur" ] && $__ZFS_CMD list -H -o name -s name -t filesystem,volume "$cur" &> /dev/null then - echo $cur@ - echo $cur# + echo "$cur@" + echo "$cur#" fi fi } __zfs_match_multiple_snapshots() { - local existing_opts=$(expr "$cur" : '\(.*\)[%,]') - if [[ $existing_opts ]] + local existing_opts + existing_opts="$(expr "$cur" : '\(.*\)[%,]')" + if [ -e "$existing_opts" ] then - local base_dataset=${cur%@*} - if [[ $base_dataset != $cur ]] + local base_dataset="${cur%@*}" + if [ "$base_dataset" != "$cur" ] then - local cur=${cur##*,} + local cur="${cur##*,}" if [[ $cur =~ ^%|%.*% ]] then # correct range syntax is start%end return 1 fi - local range_start=$(expr "$cur" : '\(.*%\)') - $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 $base_dataset | sed 's$.*@$'$range_start'$g' + local range_start + range_start="$(expr "$cur" : '\(.*%\)')" + # shellcheck disable=SC2016 + $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset" | sed 's$.*@$'"$range_start"'$g' fi else __zfs_match_snapshot_or_bookmark @@ -165,7 +164,7 @@ __zfs_argument_chosen() then return 0 fi - for property in $@ + for property in "$@" do if [[ $prev == "$property"* ]] then @@ -183,6 +182,7 @@ __zfs_complete_ordered_arguments() local list2=$2 local cur=$3 local extra=$4 + # shellcheck disable=SC2086 if __zfs_argument_chosen $list1 then COMPREPLY=($(compgen -W "$list2 $extra" -- "$cur")) @@ -195,10 +195,11 @@ __zfs_complete_multiple_options() { local options=$1 local cur=$2 + local existing_opts COMPREPLY=($(compgen -W "$options" -- "${cur##*,}")) - local existing_opts=$(expr "$cur" : '\(.*,\)') - if [[ $existing_opts ]] + existing_opts=$(expr "$cur" : '\(.*,\)') + if [[ $existing_opts ]] then COMPREPLY=( "${COMPREPLY[@]/#/${existing_opts}}" ) fi @@ -292,6 +293,7 @@ __zfs_complete() *) if ! __zfs_complete_switch "H,r,p,d,o,t,s" then + # shellcheck disable=SC2046 if __zfs_argument_chosen $(__zfs_get_properties) then COMPREPLY=($(compgen -W "$(__zfs_match_snapshot)" -- "$cur")) @@ -305,7 +307,7 @@ __zfs_complete() inherit) if ! __zfs_complete_switch "r" then - __zfs_complete_ordered_arguments "$(__zfs_get_inheritable_properties)" "$(__zfs_match_snapshot)" $cur + __zfs_complete_ordered_arguments "$(__zfs_get_inheritable_properties)" "$(__zfs_match_snapshot)" "$cur" fi ;; list) @@ -371,7 +373,7 @@ __zfs_complete() esac ;; set) - __zfs_complete_ordered_arguments "$(__zfs_get_editable_properties)" "$(__zfs_match_snapshot)" $cur + __zfs_complete_ordered_arguments "$(__zfs_get_editable_properties)" "$(__zfs_match_snapshot)" "$cur" __zfs_complete_nospace ;; upgrade) @@ -390,7 +392,7 @@ __zfs_complete() destroy) if ! __zfs_complete_switch "d,f,n,p,R,r,v" then - __zfs_complete_multiple_options "$(__zfs_match_multiple_snapshots)" $cur + __zfs_complete_multiple_options "$(__zfs_match_multiple_snapshots)" "$cur" __zfs_complete_nospace fi ;; @@ -427,7 +429,7 @@ __zpool_list_pools() __zpool_complete() { - local cur prev cmd cmds + local cur prev cmd cmds pools COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" @@ -442,7 +444,7 @@ __zpool_complete() case "${cmd}" in get) - __zfs_complete_ordered_arguments "$(__zpool_get_properties)" "$(__zpool_list_pools)" $cur + __zfs_complete_ordered_arguments "$(__zpool_get_properties)" "$(__zpool_list_pools)" "$cur" return 0 ;; import) @@ -455,12 +457,13 @@ __zpool_complete() return 0 ;; set) - __zfs_complete_ordered_arguments "$(__zpool_get_editable_properties)" "$(__zpool_list_pools)" $cur + __zfs_complete_ordered_arguments "$(__zpool_get_editable_properties)" "$(__zpool_list_pools)" "$cur" __zfs_complete_nospace return 0 ;; add|attach|clear|create|detach|offline|online|remove|replace) - local pools="$(__zpool_list_pools)" + pools="$(__zpool_list_pools)" + # shellcheck disable=SC2086 if __zfs_argument_chosen $pools then _filedir diff --git a/sys/contrib/openzfs/contrib/bpftrace/Makefile.am b/sys/contrib/openzfs/contrib/bpftrace/Makefile.am index 327bc64425d..05e4f1c507c 100644 --- a/sys/contrib/openzfs/contrib/bpftrace/Makefile.am +++ b/sys/contrib/openzfs/contrib/bpftrace/Makefile.am @@ -1,3 +1,7 @@ +include $(top_srcdir)/config/Shellcheck.am + EXTRA_DIST = \ taskqlatency.bt \ zfs-trace.sh + +SHELLCHECKSCRIPTS = zfs-trace.sh diff --git a/sys/contrib/openzfs/contrib/bpftrace/zfs-trace.sh b/sys/contrib/openzfs/contrib/bpftrace/zfs-trace.sh index 13230b78c3c..54f66f3ba3f 100755 --- a/sys/contrib/openzfs/contrib/bpftrace/zfs-trace.sh +++ b/sys/contrib/openzfs/contrib/bpftrace/zfs-trace.sh @@ -1,9 +1,9 @@ #!/bin/sh -ZVER=$(cat /sys/module/zfs/version | cut -f 1 -d '-') +ZVER=$(cut -f 1 -d '-' /sys/module/zfs/version) KVER=$(uname -r) -bpftrace \ +exec bpftrace \ --include "/usr/src/zfs-$ZVER/$KVER/zfs_config.h" \ -I "/usr/src/zfs-$ZVER/include" \ -I "/usr/src/zfs-$ZVER/include/spl" \ diff --git a/sys/contrib/openzfs/contrib/dracut/02zfsexpandknowledge/Makefile.am b/sys/contrib/openzfs/contrib/dracut/02zfsexpandknowledge/Makefile.am index d31d389a0e5..b1bbb6bd3aa 100644 --- a/sys/contrib/openzfs/contrib/dracut/02zfsexpandknowledge/Makefile.am +++ b/sys/contrib/openzfs/contrib/dracut/02zfsexpandknowledge/Makefile.am @@ -1,4 +1,5 @@ include $(top_srcdir)/config/Substfiles.am +include $(top_srcdir)/config/Shellcheck.am pkgdracutdir = $(dracutdir)/modules.d/02zfsexpandknowledge pkgdracut_SCRIPTS = \ diff --git a/sys/contrib/openzfs/contrib/dracut/02zfsexpandknowledge/module-setup.sh.in b/sys/contrib/openzfs/contrib/dracut/02zfsexpandknowledge/module-setup.sh.in index 8429bd10941..d21ab74cc0d 100755 --- a/sys/contrib/openzfs/contrib/dracut/02zfsexpandknowledge/module-setup.sh.in +++ b/sys/contrib/openzfs/contrib/dracut/02zfsexpandknowledge/module-setup.sh.in @@ -14,22 +14,16 @@ get_pool_devices() { local poolconfigtemp local poolconfigoutput local pooldev - local prefix local resolved - poolconfigtemp=`mktemp` - @sbindir@/zpool list -v -H -P "$1" > "$poolconfigtemp" 2>&1 - if [ "$?" != "0" ] ; then - poolconfigoutput=$(cat "$poolconfigtemp") + poolconfigtemp="$(mktemp)" + if ! @sbindir@/zpool list -v -H -P "$1" > "$poolconfigtemp" 2>&1 ; then + poolconfigoutput="$(cat "$poolconfigtemp")" dinfo "zfsexpandknowledge: pool $1 cannot be listed: $poolconfigoutput" else - cat "$poolconfigtemp" | awk -F '\t' '/\t\/dev/ { print $2 }' | \ - while read pooldev ; do - if [ -n "$pooldev" -a -e "$pooldev" ] ; then - if [ -h "$pooldev" ] ; then - resolved=`readlink -f "$pooldev"` - else - resolved="$pooldev" - fi + awk -F '\t' '/\t\/dev/ { print $2 }' "$poolconfigtemp" | \ + while read -r pooldev ; do + if [ -e "$pooldev" ] ; then + resolved="$(readlink -f "$pooldev")" dinfo "zfsexpandknowledge: pool $1 has device $pooldev (which resolves to $resolved)" echo "$resolved" fi @@ -40,22 +34,20 @@ get_pool_devices() { find_zfs_block_devices() { local dev - local blockdev local mp local fstype local pool - local key - local n - local poolconfigoutput - numfields=`head -1 /proc/self/mountinfo | awk '{print NF}'` - if [ "$numfields" == "10" ] ; then - fields="n n n n mp n n fstype dev n" + local _ + numfields="$(awk '{print NF; exit}' /proc/self/mountinfo)" + if [ "$numfields" = "10" ] ; then + fields="_ _ _ _ mp _ _ fstype dev _" else - fields="n n n n mp n n n fstype dev n" + fields="_ _ _ _ mp _ _ _ fstype dev _" fi - while read $fields ; do - if [ "$fstype" != "zfs" ]; then continue ; fi - if [ "$mp" == "$1" ]; then + # shellcheck disable=SC2086 + while read -r ${fields?} ; do + [ "$fstype" = "zfs" ] || continue + if [ "$mp" = "$1" ]; then pool=$(echo "$dev" | cut -d / -f 1) get_pool_devices "$pool" fi @@ -77,10 +69,9 @@ check() { local _depdev local _depdevname local _depdevtype - local _depmajmin - local _dev -if [[ $hostonly ]]; then +# shellcheck disable=SC2154 +if [ -n "$hostonly" ]; then for mp in \ "/" \ @@ -100,21 +91,20 @@ if [[ $hostonly ]]; then mountpoint "$mp" >/dev/null 2>&1 || continue blockdevs=$(find_zfs_block_devices "$mp") if [ -z "$blockdevs" ] ; then continue ; fi - dinfo "zfsexpandknowledge: block devices backing ZFS dataset $mp: $blockdevs" + dinfo "zfsexpandknowledge: block devices backing ZFS dataset $mp: ${blockdevs//$'\n'/ }" for dev in $blockdevs do array_contains "$dev" "${host_devs[@]}" || host_devs+=("$dev") fstype=$(get_devtype "$dev") host_fs_types["$dev"]="$fstype" majmin=$(get_maj_min "$dev") - if [[ -d /sys/dev/block/$majmin/slaves ]] ; then - for _depdev in /sys/dev/block/$majmin/slaves/*; do + if [ -d "/sys/dev/block/$majmin/slaves" ] ; then + for _depdev in "/sys/dev/block/$majmin/slaves"/*; do [[ -f $_depdev/dev ]] || continue _depdev=/dev/$(basename "$_depdev") _depdevname=$(udevadm info --query=property --name="$_depdev" | grep "^DEVNAME=" | sed 's|^DEVNAME=||') _depdevtype=$(get_devtype "$_depdevname") - _depmajmin=$(get_maj_min "$_depdevname") - dinfo "zfsexpandknowledge: underlying block device backing ZFS dataset $mp: $_depdevname" + dinfo "zfsexpandknowledge: underlying block device backing ZFS dataset $mp: ${_depdevname//$'\n'/ }" array_contains "$_depdevname" "${host_devs[@]}" || host_devs+=("$_depdevname") host_fs_types["$_depdevname"]="$_depdevtype" done diff --git a/sys/contrib/openzfs/contrib/dracut/90zfs/Makefile.am b/sys/contrib/openzfs/contrib/dracut/90zfs/Makefile.am index a4843827ede..ff3a2b27f24 100644 --- a/sys/contrib/openzfs/contrib/dracut/90zfs/Makefile.am +++ b/sys/contrib/openzfs/contrib/dracut/90zfs/Makefile.am @@ -1,4 +1,5 @@ include $(top_srcdir)/config/Substfiles.am +include $(top_srcdir)/config/Shellcheck.am pkgdracutdir = $(dracutdir)/modules.d/90zfs pkgdracut_SCRIPTS = \ @@ -17,3 +18,6 @@ pkgdracut_DATA = \ zfs-rollback-bootfs.service SUBSTFILES += $(pkgdracut_SCRIPTS) $(pkgdracut_DATA) + +# Provided by /bin/sleep, and, again, every implementation of that supports this +CHECKBASHISMS_IGNORE = -e 'sleep only takes one integer' -e 'sleep 0.' diff --git a/sys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in b/sys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in index b6b86e2eafb..817da5b2b4a 100755 --- a/sys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in +++ b/sys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in @@ -1,4 +1,5 @@ #!/usr/bin/env bash +# shellcheck disable=SC2154 check() { # We depend on udev-rules being loaded @@ -8,8 +9,6 @@ check() { for tool in "@sbindir@/zgenhostid" "@sbindir@/zpool" "@sbindir@/zfs" "@mounthelperdir@/mount.zfs" ; do test -x "$tool" || return 1 done - # Verify grep exists - which grep >/dev/null 2>&1 || return 1 return 0 } @@ -43,19 +42,29 @@ install() { dracut_install @sbindir@/zpool # Workaround for https://github.com/openzfs/zfs/issues/4749 by # ensuring libgcc_s.so(.1) is included - if [[ -n "$(ldd @sbindir@/zpool | grep -F 'libgcc_s.so')" ]]; then + if ldd @sbindir@/zpool | grep -qF 'libgcc_s.so'; then # Dracut will have already tracked and included it :; - elif command -v gcc-config 2>&1 1>/dev/null; then + elif command -v gcc-config >/dev/null 2>&1; then # On systems with gcc-config (Gentoo, Funtoo, etc.): # Use the current profile to resolve the appropriate path - dracut_install "/usr/lib/gcc/$(s=$(gcc-config -c); echo ${s%-*}/${s##*-})/libgcc_s.so.1" - elif [[ -n "$(ls /usr/lib/libgcc_s.so* 2>/dev/null)" ]]; then + s="$(gcc-config -c)" + dracut_install "/usr/lib/gcc/${s%-*}/${s##*-}/libgcc_s.so"* + elif [ "$(echo /usr/lib/libgcc_s.so*)" != "/usr/lib/libgcc_s.so*" ]; then # Try a simple path first dracut_install /usr/lib/libgcc_s.so* + elif [ "$(echo /lib*/libgcc_s.so*)" != "/lib*/libgcc_s.so*" ]; then + # SUSE + dracut_install /lib*/libgcc_s.so* else # Fallback: Guess the path and include all matches - dracut_install /usr/lib/gcc/*/*/libgcc_s.so* + dracut_install /usr/lib*/gcc/**/libgcc_s.so* + fi + # shellcheck disable=SC2050 + if [ @LIBFETCH_DYNAMIC@ != 0 ]; then + for d in $libdirs; do + [ -e "$d/"@LIBFETCH_SONAME@ ] && dracut_install "$d/"@LIBFETCH_SONAME@ + done fi dracut_install @mounthelperdir@/mount.zfs dracut_install @udevdir@/vdev_id diff --git a/sys/contrib/openzfs/contrib/dracut/90zfs/mount-zfs.sh.in b/sys/contrib/openzfs/contrib/dracut/90zfs/mount-zfs.sh.in index 4a892e9382c..68e3f0e0d60 100755 --- a/sys/contrib/openzfs/contrib/dracut/90zfs/mount-zfs.sh.in +++ b/sys/contrib/openzfs/contrib/dracut/90zfs/mount-zfs.sh.in @@ -1,4 +1,5 @@ #!/bin/sh +# shellcheck disable=SC2034,SC2154 . /lib/dracut-zfs-lib.sh @@ -38,11 +39,10 @@ modprobe zfs 2>/dev/null udevadm settle if [ "${root}" = "zfs:AUTO" ] ; then - ZFS_DATASET="$(find_bootfs)" - if [ $? -ne 0 ] ; then + if ! ZFS_DATASET="$(find_bootfs)" ; then + # shellcheck disable=SC2086 zpool import -N -a ${ZPOOL_IMPORT_OPTS} - ZFS_DATASET="$(find_bootfs)" - if [ $? -ne 0 ] ; then + if ! ZFS_DATASET="$(find_bootfs)" ; then warn "ZFS: No bootfs attribute found in importable pools." export_all -F @@ -58,7 +58,7 @@ ZFS_POOL="${ZFS_DATASET%%/*}" if import_pool "${ZFS_POOL}" ; then # Load keys if we can or if we need to - if [ "$(zpool list -H -o feature@encryption "$(echo "${ZFS_POOL}" | awk -F/ '{print $1}')")" = 'active' ]; then + if [ "$(zpool list -H -o feature@encryption "${ZFS_POOL}")" = 'active' ]; then # if the root dataset has encryption enabled ENCRYPTIONROOT="$(zfs get -H -o value encryptionroot "${ZFS_DATASET}")" if ! [ "${ENCRYPTIONROOT}" = "-" ]; then diff --git a/sys/contrib/openzfs/contrib/dracut/90zfs/parse-zfs.sh.in b/sys/contrib/openzfs/contrib/dracut/90zfs/parse-zfs.sh.in index 768de9dd251..fe786a88069 100755 --- a/sys/contrib/openzfs/contrib/dracut/90zfs/parse-zfs.sh.in +++ b/sys/contrib/openzfs/contrib/dracut/90zfs/parse-zfs.sh.in @@ -1,4 +1,5 @@ #!/bin/sh +# shellcheck disable=SC2034,SC2154 . /lib/dracut-lib.sh @@ -28,7 +29,7 @@ case "${root}" in info "ZFS: Enabling autodetection of bootfs after udev settles." ;; - ZFS\=*|zfs:*|zfs:FILESYSTEM\=*|FILESYSTEM\=*) + ZFS=*|zfs:*|FILESYSTEM=*) # root is explicit ZFS root. Parse it now. We can handle # a root=... param in any of the following formats: # root=ZFS=rpool/ROOT diff --git a/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-env-bootfs.service.in b/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-env-bootfs.service.in index 2bc43482c18..e143cb5ec1e 100644 --- a/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-env-bootfs.service.in +++ b/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-env-bootfs.service.in @@ -8,7 +8,7 @@ Before=zfs-import.target [Service] Type=oneshot -ExecStart=/bin/sh -c "systemctl set-environment BOOTFS=$(@sbindir@/zpool list -H -o bootfs | grep -m1 -v '^-$')" +ExecStart=/bin/sh -c "exec systemctl set-environment BOOTFS=$(@sbindir@/zpool list -H -o bootfs | grep -m1 -v '^-$')" [Install] WantedBy=zfs-import.target diff --git a/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-generator.sh.in b/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-generator.sh.in index 12293bd24f7..b57c64c688b 100755 --- a/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-generator.sh.in +++ b/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-generator.sh.in @@ -1,6 +1,8 @@ #!/bin/sh +# shellcheck disable=SC2016,SC1004 -echo "zfs-generator: starting" >> /dev/kmsg +grep -wq debug /proc/cmdline && debug=1 +[ -n "$debug" ] && echo "zfs-generator: starting" >> /dev/kmsg GENERATOR_DIR="$1" [ -n "$GENERATOR_DIR" ] || { @@ -10,12 +12,13 @@ GENERATOR_DIR="$1" [ -f /lib/dracut-lib.sh ] && dracutlib=/lib/dracut-lib.sh [ -f /usr/lib/dracut/modules.d/99base/dracut-lib.sh ] && dracutlib=/usr/lib/dracut/modules.d/99base/dracut-lib.sh - command -v getarg >/dev/null 2>&1 || { - echo "zfs-generator: loading Dracut library from $dracutlib" >> /dev/kmsg + [ -n "$debug" ] && echo "zfs-generator: loading Dracut library from $dracutlib" >> /dev/kmsg . "$dracutlib" } +. /lib/dracut-zfs-lib.sh + [ -z "$root" ] && root=$(getarg root=) [ -z "$rootfstype" ] && rootfstype=$(getarg rootfstype=) [ -z "$rootflags" ] && rootflags=$(getarg rootflags=) @@ -27,44 +30,90 @@ command -v getarg >/dev/null 2>&1 || { [ "$rootfstype" != "zfs" ] && exit 0 -rootfstype=zfs case ",${rootflags}," in *,zfsutil,*) ;; ,,) rootflags=zfsutil ;; *) rootflags="zfsutil,${rootflags}" ;; esac -echo "zfs-generator: writing extension for sysroot.mount to $GENERATOR_DIR"/sysroot.mount.d/zfs-enhancement.conf >> /dev/kmsg +if [ "${root}" != "zfs:AUTO" ]; then + root="${root##zfs:}" + root="${root##ZFS=}" +fi -[ -d "$GENERATOR_DIR" ] || mkdir "$GENERATOR_DIR" -[ -d "$GENERATOR_DIR"/sysroot.mount.d ] || mkdir "$GENERATOR_DIR"/sysroot.mount.d +[ -n "$debug" ] && echo "zfs-generator: writing extension for sysroot.mount to $GENERATOR_DIR/sysroot.mount.d/zfs-enhancement.conf" >> /dev/kmsg + +mkdir -p "$GENERATOR_DIR"/sysroot.mount.d "$GENERATOR_DIR"/initrd-root-fs.target.requires "$GENERATOR_DIR"/dracut-pre-mount.service.d { echo "[Unit]" echo "Before=initrd-root-fs.target" echo "After=zfs-import.target" + echo echo "[Mount]" - if [ "${root}" = "zfs:AUTO" ] ; then + if [ "${root}" = "zfs:AUTO" ]; then echo "PassEnvironment=BOOTFS" echo 'What=${BOOTFS}' else - root="${root##zfs:}" - root="${root##ZFS=}" echo "What=${root}" fi - echo "Type=${rootfstype}" + echo "Type=zfs" echo "Options=${rootflags}" } > "$GENERATOR_DIR"/sysroot.mount.d/zfs-enhancement.conf - -[ -d "$GENERATOR_DIR"/initrd-root-fs.target.requires ] || mkdir -p "$GENERATOR_DIR"/initrd-root-fs.target.requires -ln -s ../sysroot.mount "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount +ln -fs ../sysroot.mount "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount -[ -d "$GENERATOR_DIR"/dracut-pre-mount.service.d ] || mkdir "$GENERATOR_DIR"/dracut-pre-mount.service.d +if [ "${root}" = "zfs:AUTO" ]; then + { + echo "[Unit]" + echo "Before=initrd-root-fs.target" + echo "After=sysroot.mount" + echo "DefaultDependencies=no" + echo + echo "[Service]" + echo "Type=oneshot" + echo "PassEnvironment=BOOTFS" + echo "ExecStart=/bin/sh -c '" ' \ + . /lib/dracut-zfs-lib.sh; \ + _zfs_nonroot_necessities_cb() { \ + zfs mount | grep -m1 -q "^$1 " && return 0; \ + echo "Mounting $1 on /sysroot$2"; \ + mount -o zfsutil -t zfs "$1" "/sysroot$2"; \ + }; \ + for_relevant_root_children "${BOOTFS}" _zfs_nonroot_necessities_cb;' \ + "'" + } > "$GENERATOR_DIR"/zfs-nonroot-necessities.service + ln -fs ../zfs-nonroot-necessities.service "$GENERATOR_DIR"/initrd-root-fs.target.requires/zfs-nonroot-necessities.service +else + # We can solve this statically at generation time, so do! + _zfs_generator_cb() { + dset="${1}" + mpnt="${2}" + unit="sysroot$(echo "$mpnt" | sed 's;/;-;g').mount" + + { + echo "[Unit]" + echo "Before=initrd-root-fs.target" + echo "After=sysroot.mount" + echo + echo "[Mount]" + echo "Where=/sysroot${mpnt}" + echo "What=${dset}" + echo "Type=zfs" + echo "Options=zfsutil" + } > "$GENERATOR_DIR/${unit}" + ln -fs ../"${unit}" "$GENERATOR_DIR"/initrd-root-fs.target.requires/"${unit}" + } + + for_relevant_root_children "${root}" _zfs_generator_cb +fi + { echo "[Unit]" echo "After=zfs-import.target" } > "$GENERATOR_DIR"/dracut-pre-mount.service.d/zfs-enhancement.conf -echo "zfs-generator: finished" >> /dev/kmsg +[ -n "$debug" ] && echo "zfs-generator: finished" >> /dev/kmsg + +exit 0 diff --git a/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-lib.sh.in b/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-lib.sh.in index c39cc5cfff1..10b0b701a23 100755 --- a/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-lib.sh.in +++ b/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-lib.sh.in @@ -5,12 +5,8 @@ command -v getargbool >/dev/null || { # Compatibility with older Dracut versions. # With apologies to the Dracut developers. getargbool() { - if ! [ -z "$_b" ]; then - unset _b - fi _default="$1"; shift - _b=$(getarg "$@") - [ $? -ne 0 ] && [ -z "$_b" ] && _b="$_default" + ! _b=$(getarg "$@") && [ -z "$_b" ] && _b="$_default" if [ -n "$_b" ]; then [ "$_b" = "0" ] && return 1 [ "$_b" = "no" ] && return 1 @@ -23,6 +19,7 @@ command -v getargbool >/dev/null || { OLDIFS="${IFS}" NEWLINE=" " +TAB=" " ZPOOL_IMPORT_OPTS="" if getargbool 0 zfs_force -y zfs.force -y zfsforce ; then @@ -58,10 +55,11 @@ find_bootfs() { # import_pool POOL # imports the given zfs pool if it isn't imported already. import_pool() { - pool="${1}" + pool="${1}" if ! zpool list -H "${pool}" > /dev/null 2>&1; then info "ZFS: Importing pool ${pool}..." + # shellcheck disable=SC2086 if ! zpool import -N ${ZPOOL_IMPORT_OPTS} "${pool}" ; then warn "ZFS: Unable to import pool ${pool}" return 1 @@ -71,32 +69,67 @@ import_pool() { return 0 } +_mount_dataset_cb() { + mount -o zfsutil -t zfs "${1}" "${NEWROOT}${2}" +} + # mount_dataset DATASET # mounts the given zfs dataset. mount_dataset() { - dataset="${1}" + dataset="${1}" mountpoint="$(zfs get -H -o value mountpoint "${dataset}")" + ret=0 # We need zfsutil for non-legacy mounts and not for legacy mounts. if [ "${mountpoint}" = "legacy" ] ; then - mount -t zfs "${dataset}" "${NEWROOT}" + mount -t zfs "${dataset}" "${NEWROOT}" || ret=$? else - mount -o zfsutil -t zfs "${dataset}" "${NEWROOT}" + mount -o zfsutil -t zfs "${dataset}" "${NEWROOT}" || ret=$? + + if [ "$ret" = "0" ]; then + for_relevant_root_children "${dataset}" _mount_dataset_cb || ret=$? + fi fi - return $? + return ${ret} +} + +# for_relevant_root_children DATASET EXEC +# Runs "EXEC dataset mountpoint" for all children of DATASET that are needed for system bringup +# Used by zfs-generator.sh and friends, too! +for_relevant_root_children() { + dataset="${1}" + exec="${2}" + + zfs list -t filesystem -Ho name,mountpoint,canmount -r "${dataset}" | + ( + _ret=0 + while IFS="${TAB}" read -r dataset mountpoint canmount; do + [ "$canmount" != "on" ] && continue + + case "$mountpoint" in + /etc|/bin|/lib|/lib??|/libx32|/usr) + # If these aren't mounted we may not be able to get to the real init at all, or pollute the dataset holding the rootfs + "${exec}" "${dataset}" "${mountpoint}" || _ret=$? + ;; + *) + # Up to the real init to remount everything else it might need + ;; + esac + done + exit ${_ret} + ) } # export_all OPTS # exports all imported zfs pools. export_all() { - opts="${@}" ret=0 IFS="${NEWLINE}" for pool in $(zpool list -H -o name) ; do if zpool list -H "${pool}" > /dev/null 2>&1; then - zpool export "${pool}" ${opts} || ret=$? + zpool export "${pool}" "$@" || ret=$? fi done IFS="${OLDIFS}" diff --git a/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-load-key.sh.in b/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-load-key.sh.in index 9b7716ae9e2..2138ff943c6 100755 --- a/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-load-key.sh.in +++ b/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-load-key.sh.in @@ -1,4 +1,5 @@ #!/bin/sh +# shellcheck disable=SC2154 # only run this on systemd systems, we handle the decrypt in mount-zfs.sh in the mount hook otherwise [ -e /bin/systemctl ] || [ -e /usr/bin/systemctl ] || return 0 @@ -32,25 +33,41 @@ else fi # if pool encryption is active and the zfs command understands '-o encryption' -if [ "$(zpool list -H -o feature@encryption "$(echo "${BOOTFS}" | awk -F/ '{print $1}')")" = 'active' ]; then +if [ "$(zpool list -H -o feature@encryption "${BOOTFS%%/*}")" = 'active' ]; then # if the root dataset has encryption enabled ENCRYPTIONROOT="$(zfs get -H -o value encryptionroot "${BOOTFS}")" - # where the key is stored (in a file or loaded via prompt) - KEYLOCATION="$(zfs get -H -o value keylocation "${ENCRYPTIONROOT}")" if ! [ "${ENCRYPTIONROOT}" = "-" ]; then KEYSTATUS="$(zfs get -H -o value keystatus "${ENCRYPTIONROOT}")" # continue only if the key needs to be loaded [ "$KEYSTATUS" = "unavailable" ] || exit 0 - # if key is stored in a file, do not prompt - if ! [ "${KEYLOCATION}" = "prompt" ]; then - zfs load-key "${ENCRYPTIONROOT}" - else - # decrypt them - TRY_COUNT=5 - while [ $TRY_COUNT -gt 0 ]; do - systemd-ask-password "Encrypted ZFS password for ${BOOTFS}" --no-tty | zfs load-key "${ENCRYPTIONROOT}" && break - TRY_COUNT=$((TRY_COUNT - 1)) - done - fi + + KEYLOCATION="$(zfs get -H -o value keylocation "${ENCRYPTIONROOT}")" + case "${KEYLOCATION%%://*}" in + prompt) + for _ in 1 2 3; do + systemd-ask-password "Encrypted ZFS password for ${BOOTFS}" --no-tty | zfs load-key "${ENCRYPTIONROOT}" && break + done + ;; + http*) + systemctl start network-online.target + zfs load-key "${ENCRYPTIONROOT}" + ;; + file) + KEYFILE="${KEYLOCATION#file://}" + [ -r "${KEYFILE}" ] || udevadm settle + [ -r "${KEYFILE}" ] || { + info "Waiting for key ${KEYFILE} for ${ENCRYPTIONROOT}..." + for _ in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do + sleep 0.5s + [ -r "${KEYFILE}" ] && break + done + } + [ -r "${KEYFILE}" ] || warn "Key ${KEYFILE} for ${ENCRYPTIONROOT} hasn't appeared. Trying anyway." + zfs load-key "${ENCRYPTIONROOT}" + ;; + *) + zfs load-key "${ENCRYPTIONROOT}" + ;; + esac fi fi diff --git a/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-rollback-bootfs.service.in b/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-rollback-bootfs.service.in index 4b058c1b8c9..bdc24694320 100644 --- a/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-rollback-bootfs.service.in +++ b/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-rollback-bootfs.service.in @@ -10,5 +10,5 @@ ConditionKernelCommandLine=bootfs.rollback # ${BOOTFS} should have been set by zfs-env-bootfs.service Type=oneshot ExecStartPre=/bin/sh -c 'test -n "${BOOTFS}"' -ExecStart=/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.rollback)"; /sbin/zfs rollback -Rf "${BOOTFS}@${SNAPNAME:-%v}"' +ExecStart=/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.rollback)"; exec @sbindir@/zfs rollback -Rf "${BOOTFS}@${SNAPNAME:-%v}"' RemainAfterExit=yes diff --git a/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-snapshot-bootfs.service.in b/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-snapshot-bootfs.service.in index cfd5f7029f0..6ea13850c3a 100644 --- a/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-snapshot-bootfs.service.in +++ b/sys/contrib/openzfs/contrib/dracut/90zfs/zfs-snapshot-bootfs.service.in @@ -10,5 +10,5 @@ ConditionKernelCommandLine=bootfs.snapshot # ${BOOTFS} should have been set by zfs-env-bootfs.service Type=oneshot ExecStartPre=/bin/sh -c 'test -n "${BOOTFS}"' -ExecStart=-/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.snapshot)"; /sbin/zfs snapshot "${BOOTFS}@${SNAPNAME:-%v}"' +ExecStart=-/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.snapshot)"; exec @sbindir@/zfs snapshot "${BOOTFS}@${SNAPNAME:-%v}"' RemainAfterExit=yes diff --git a/sys/contrib/openzfs/contrib/dracut/Makefile.am b/sys/contrib/openzfs/contrib/dracut/Makefile.am index 1065e5e94f0..8c9a6be0899 100644 --- a/sys/contrib/openzfs/contrib/dracut/Makefile.am +++ b/sys/contrib/openzfs/contrib/dracut/Makefile.am @@ -1,3 +1,6 @@ +include $(top_srcdir)/config/Shellcheck.am + SUBDIRS = 02zfsexpandknowledge 90zfs +SHELLCHECKDIRS = $(SUBDIRS) EXTRA_DIST = README.dracut.markdown diff --git a/sys/contrib/openzfs/contrib/initramfs/Makefile.am b/sys/contrib/openzfs/contrib/initramfs/Makefile.am index 5eac6e2155d..931ceb1316a 100644 --- a/sys/contrib/openzfs/contrib/initramfs/Makefile.am +++ b/sys/contrib/openzfs/contrib/initramfs/Makefile.am @@ -1,9 +1,12 @@ +include $(top_srcdir)/config/Shellcheck.am + initrddir = /usr/share/initramfs-tools dist_initrd_SCRIPTS = \ zfsunlock SUBDIRS = conf.d conf-hooks.d hooks scripts +SHELLCHECKDIRS = hooks scripts EXTRA_DIST = \ README.initramfs.markdown diff --git a/sys/contrib/openzfs/contrib/initramfs/hooks/Makefile.am b/sys/contrib/openzfs/contrib/initramfs/hooks/Makefile.am index f303e995b9c..0cd1aafcd35 100644 --- a/sys/contrib/openzfs/contrib/initramfs/hooks/Makefile.am +++ b/sys/contrib/openzfs/contrib/initramfs/hooks/Makefile.am @@ -1,4 +1,5 @@ include $(top_srcdir)/config/Substfiles.am +include $(top_srcdir)/config/Shellcheck.am hooksdir = /usr/share/initramfs-tools/hooks diff --git a/sys/contrib/openzfs/contrib/initramfs/hooks/zfs.in b/sys/contrib/openzfs/contrib/initramfs/hooks/zfs.in index 67d27a7649b..bdf169fd96c 100755 --- a/sys/contrib/openzfs/contrib/initramfs/hooks/zfs.in +++ b/sys/contrib/openzfs/contrib/initramfs/hooks/zfs.in @@ -1,109 +1,57 @@ #!/bin/sh # -# Add ZoL filesystem capabilities to an initrd, usually for a native ZFS root. +# Add OpenZFS filesystem capabilities to an initrd, usually for a native ZFS root. # -# This hook installs udev rules for ZoL. -PREREQ="udev" - -# These prerequisites are provided by the zfsutils package. The zdb utility is -# not strictly required, but it can be useful at the initramfs recovery prompt. -COPY_EXEC_LIST="@sbindir@/zdb @sbindir@/zpool @sbindir@/zfs" -COPY_EXEC_LIST="$COPY_EXEC_LIST @mounthelperdir@/mount.zfs @udevdir@/vdev_id" -COPY_EXEC_LIST="$COPY_EXEC_LIST @udevdir@/zvol_id" -COPY_FILE_LIST="/etc/hostid @sysconfdir@/zfs/zpool.cache" -COPY_FILE_LIST="$COPY_FILE_LIST @initconfdir@/zfs" -COPY_FILE_LIST="$COPY_FILE_LIST @sysconfdir@/zfs/zfs-functions" -COPY_FILE_LIST="$COPY_FILE_LIST @sysconfdir@/zfs/vdev_id.conf" -COPY_FILE_LIST="$COPY_FILE_LIST @udevruledir@/60-zvol.rules" -COPY_FILE_LIST="$COPY_FILE_LIST @udevruledir@/69-vdev.rules" - -# These prerequisites are provided by the base system. -COPY_EXEC_LIST="$COPY_EXEC_LIST /usr/bin/dirname /bin/hostname /sbin/blkid" -COPY_EXEC_LIST="$COPY_EXEC_LIST /usr/bin/env" -COPY_EXEC_LIST="$COPY_EXEC_LIST $(which systemd-ask-password)" - -# Explicitly specify all kernel modules because automatic dependency resolution -# is unreliable on many systems. -BASE_MODULES="zlib_deflate spl zavl zcommon znvpair zunicode zlua zfs icp" -CRPT_MODULES="sun-ccm sun-gcm sun-ctr" -MANUAL_ADD_MODULES_LIST="$BASE_MODULES" - -# Generic result code. -RC=0 - -case $1 in -prereqs) - echo "$PREREQ" - exit 0 - ;; -esac - -for ii in $COPY_EXEC_LIST -do - if [ ! -x "$ii" ] - then - echo "Error: $ii is not executable." - RC=2 - fi -done - -if [ "$RC" -ne 0 ] -then - exit "$RC" +if [ "$1" = "prereqs" ]; then + echo "udev" + exit fi . /usr/share/initramfs-tools/hook-functions -mkdir -p "$DESTDIR/etc/" - -# ZDB uses pthreads for some functions, but the library dependency is not -# automatically detected. The `find` utility and extended `cp` options are -# used here because libgcc_s.so could be in a subdirectory of /lib for -# multi-arch installations. -cp --target-directory="$DESTDIR" --parents $(find /lib/ -type f -name libgcc_s.so.1) - -for ii in $COPY_EXEC_LIST -do - copy_exec "$ii" +for req in "@sbindir@/zpool" "@sbindir@/zfs" "@mounthelperdir@/mount.zfs"; do + copy_exec "$req" || { + echo "$req not available!" >&2 + exit 2 + } done -for ii in $COPY_FILE_LIST -do - dir=$(dirname "$ii") - [ -d "$dir" ] && mkdir -p "$DESTDIR/$dir" - [ -f "$ii" ] && cp -p "$ii" "$DESTDIR/$ii" +copy_exec "@sbindir@/zdb" +copy_exec "@udevdir@/vdev_id" +copy_exec "@udevdir@/zvol_id" +if command -v systemd-ask-password > /dev/null; then + copy_exec "$(command -v systemd-ask-password)" +fi + +# We use pthreads, but i-t from buster doesn't automatically +# copy this indirect dependency: this can be removed when buster finally dies. +find /lib/ -type f -name "libgcc_s.so.[1-9]" | while read -r libgcc; do + copy_exec "$libgcc" done -for ii in $MANUAL_ADD_MODULES_LIST -do - manual_add_modules "$ii" -done +# shellcheck disable=SC2050 +if [ @LIBFETCH_DYNAMIC@ != 0 ]; then + find /lib/ -name @LIBFETCH_SONAME@ | while read -r libfetch; do + copy_exec "$libfetch" + done +fi -if [ -f "/etc/hostname" ] -then - cp -p "/etc/hostname" "$DESTDIR/etc/" +copy_file config "/etc/hostid" +copy_file cache "@sysconfdir@/zfs/zpool.cache" +copy_file config "@initconfdir@/zfs" +copy_file config "@sysconfdir@/zfs/zfs-functions" +copy_file config "@sysconfdir@/zfs/vdev_id.conf" +copy_file rule "@udevruledir@/60-zvol.rules" +copy_file rule "@udevruledir@/69-vdev.rules" + +manual_add_modules zfs + +if [ -f "/etc/hostname" ]; then + copy_file config "/etc/hostname" else - hostname >"$DESTDIR/etc/hostname" + hostname="$(mktemp -t hostname.XXXXXXXXXX)" + hostname > "$hostname" + copy_file config "$hostname" "/etc/hostname" + rm -f "$hostname" fi - -for ii in zfs zfs.conf spl spl.conf -do - if [ -f "/etc/modprobe.d/$ii" ]; then - if [ ! -d "$DESTDIR/etc/modprobe.d" ]; then - mkdir -p $DESTDIR/etc/modprobe.d - fi - cp -p "/etc/modprobe.d/$ii" $DESTDIR/etc/modprobe.d/ - fi -done - -# With pull request #1476 (not yet merged) comes a verbose warning -# if /usr/bin/net doesn't exist or isn't executable. Just create -# a dummy... -[ ! -d "$DESTDIR/usr/bin" ] && mkdir -p "$DESTDIR/usr/bin" -if [ ! -x "$DESTDIR/usr/bin/net" ]; then - touch "$DESTDIR/usr/bin/net" - chmod +x "$DESTDIR/usr/bin/net" -fi - -exit 0 diff --git a/sys/contrib/openzfs/contrib/initramfs/hooks/zfsunlock.in b/sys/contrib/openzfs/contrib/initramfs/hooks/zfsunlock.in index d451726545d..4776087d9a7 100644 --- a/sys/contrib/openzfs/contrib/initramfs/hooks/zfsunlock.in +++ b/sys/contrib/openzfs/contrib/initramfs/hooks/zfsunlock.in @@ -1,17 +1,9 @@ #!/bin/sh -PREREQ="dropbear" - -prereqs() { - echo "$PREREQ" -} - -case "$1" in - prereqs) - prereqs - exit 0 - ;; -esac +if [ "$1" = "prereqs" ]; then + echo "dropbear" + exit +fi . /usr/share/initramfs-tools/hook-functions diff --git a/sys/contrib/openzfs/contrib/initramfs/scripts/Makefile.am b/sys/contrib/openzfs/contrib/initramfs/scripts/Makefile.am index 2a142096e44..444a5f374bf 100644 --- a/sys/contrib/openzfs/contrib/initramfs/scripts/Makefile.am +++ b/sys/contrib/openzfs/contrib/initramfs/scripts/Makefile.am @@ -1,6 +1,11 @@ +include $(top_srcdir)/config/Shellcheck.am + scriptsdir = /usr/share/initramfs-tools/scripts -dist_scripts_DATA = \ +dist_scripts_SCRIPTS = \ zfs SUBDIRS = local-top + +SHELLCHECKDIRS = $(SUBDIRS) +SHELLCHECK_SHELL = sh diff --git a/sys/contrib/openzfs/contrib/initramfs/scripts/local-top/Makefile.am b/sys/contrib/openzfs/contrib/initramfs/scripts/local-top/Makefile.am index 1523a907c86..897f9b2e212 100644 --- a/sys/contrib/openzfs/contrib/initramfs/scripts/local-top/Makefile.am +++ b/sys/contrib/openzfs/contrib/initramfs/scripts/local-top/Makefile.am @@ -1,3 +1,5 @@ +include $(top_srcdir)/config/Shellcheck.am + localtopdir = /usr/share/initramfs-tools/scripts/local-top dist_localtop_SCRIPTS = \ diff --git a/sys/contrib/openzfs/contrib/initramfs/scripts/local-top/zfs b/sys/contrib/openzfs/contrib/initramfs/scripts/local-top/zfs index e8e5cd26451..6b80e9f4360 100755 --- a/sys/contrib/openzfs/contrib/initramfs/scripts/local-top/zfs +++ b/sys/contrib/openzfs/contrib/initramfs/scripts/local-top/zfs @@ -1,18 +1,11 @@ #!/bin/sh -PREREQ="mdadm mdrun multipath" +# shellcheck disable=SC2154 -prereqs() -{ - echo "$PREREQ" -} -case $1 in -# get pre-requisites -prereqs) - prereqs +if [ "$1" = "prereqs" ]; then + echo mdadm mdrun multipath exit 0 - ;; -esac +fi # @@ -20,10 +13,10 @@ esac # message() { - if [ -x /bin/plymouth ] && plymouth --ping; then - plymouth message --text="$@" + if plymouth --ping 2>/dev/null; then + plymouth message --text="$*" else - echo "$@" >&2 + echo "$*" >&2 fi return 0 } diff --git a/sys/contrib/openzfs/contrib/initramfs/scripts/zfs b/sys/contrib/openzfs/contrib/initramfs/scripts/zfs index 130aad5debd..306e6e157e6 100644 --- a/sys/contrib/openzfs/contrib/initramfs/scripts/zfs +++ b/sys/contrib/openzfs/contrib/initramfs/scripts/zfs @@ -5,6 +5,8 @@ # # Enable this by passing boot=zfs on the kernel command line. # +# $quiet, $root, $rpool, $bootfs come from the cmdline: +# shellcheck disable=SC2154 # Source the common functions . /etc/zfs/zfs-functions @@ -94,22 +96,18 @@ find_rootfs() # Not boot fs here, export it and later try again.. "${ZPOOL}" export "$pool" - POOL_IMPORTED="" - + POOL_IMPORTED= + ZFS_BOOTFS= return 1 } # Support function to get a list of all pools, separated with ';' find_pools() { - CMD="$*" - - pools=$($CMD 2> /dev/null | \ + pools=$("$@" 2> /dev/null | \ grep -E "pool:|^[a-zA-Z0-9]" | \ sed 's@.*: @@' | \ - while read -r pool; do \ - printf "%s" "$pool;" - done) + tr '\n' ';') echo "${pools%%;}" # Return without the last ';'. } @@ -203,7 +201,7 @@ import_pool() # exists). if [ -n "$USE_DISK_BY_ID" ] && [ -z "$ZPOOL_IMPORT_PATH" ] then - dirs="$(for dir in $(echo /dev/disk/by-*) + dirs="$(for dir in /dev/disk/by-* do # Ignore by-vdev here - we want it first! echo "$dir" | grep -q /by-vdev && continue @@ -273,6 +271,8 @@ import_pool() # with more logging etc. load_module_initrd() { + [ -n "$ROOTDELAY" ] && ZFS_INITRD_PRE_MOUNTROOT_SLEEP="$ROOTDELAY" + if [ "$ZFS_INITRD_PRE_MOUNTROOT_SLEEP" -gt 0 ] 2>/dev/null then if [ "$quiet" != "y" ]; then @@ -327,6 +327,7 @@ mount_fs() # Need the _original_ datasets mountpoint! mountpoint=$(get_fs_value "$fs" mountpoint) + ZFS_CMD="mount -o zfsutil -t zfs" 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 @@ -346,15 +347,11 @@ mount_fs() fi fi + # If it's not a legacy filesystem, it can only be a + # native one... if [ "$mountpoint" = "legacy" ]; then ZFS_CMD="mount -t zfs" - else - # If it's not a legacy filesystem, it can only be a - # native one... - ZFS_CMD="mount -o zfsutil -t zfs" fi - else - ZFS_CMD="mount -o zfsutil -t zfs" fi # Possibly decrypt a filesystem using native encryption. @@ -393,7 +390,7 @@ decrypt_fs() 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 "${fs%%/*}")" = 'active' ]; then # Determine dataset that holds key for root dataset ENCRYPTIONROOT="$(get_fs_value "${fs}" encryptionroot)" @@ -406,28 +403,25 @@ decrypt_fs() KEYSTATUS="$(get_fs_value "${ENCRYPTIONROOT}" keystatus)" # Continue only if the key needs to be loaded [ "$KEYSTATUS" = "unavailable" ] || return 0 - TRY_COUNT=3 - # If key is stored in a file, do not prompt + # Do not prompt if key is stored noninteractively, if ! [ "${KEYLOCATION}" = "prompt" ]; then $ZFS load-key "${ENCRYPTIONROOT}" # Prompt with plymouth, if active - elif [ -e /bin/plymouth ] && /bin/plymouth --ping 2>/dev/null; then + elif /bin/plymouth --ping 2>/dev/null; then echo "plymouth" > /run/zfs_console_askpwd_cmd - while [ $TRY_COUNT -gt 0 ]; do + for _ in 1 2 3; do plymouth ask-for-password --prompt "Encrypted ZFS password for ${ENCRYPTIONROOT}" | \ $ZFS load-key "${ENCRYPTIONROOT}" && break - TRY_COUNT=$((TRY_COUNT - 1)) done # 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 + for _ in 1 2 3; do systemd-ask-password "Encrypted ZFS password for ${ENCRYPTIONROOT}" --no-tty | \ $ZFS load-key "${ENCRYPTIONROOT}" && break - TRY_COUNT=$((TRY_COUNT - 1)) done # Prompt with ZFS tty, otherwise @@ -554,7 +548,6 @@ rollback_snap() ask_user_snap() { fs="$1" - i=1 # We need to temporarily disable debugging. Set 'debug' so we # remember to enabled it again. @@ -567,16 +560,25 @@ 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 -r snap; do - echo " $i: ${snap}" > /dev/stderr - eval "$(echo SNAP_$i=$snap)" - i=$((i + 1)) - done < /dev/stderr - read -r snapnr + i=1 + for snap in "$@"; do + echo " $i: $snap" + i=$((i + 1)) + done > /dev/stderr + + # expr instead of test here because [ a -lt 0 ] errors out, + # but expr falls back to lexicographical, which works out right + snapnr=0 + while expr "$snapnr" "<" 1 > /dev/null || + expr "$snapnr" ">" "$#" > /dev/null + do + printf "%s" "Snap nr [1-$#]? " > /dev/stderr + read -r snapnr + done # Re-enable debugging. if [ -n "${debug}" ]; then @@ -584,7 +586,7 @@ EOT set -x fi - echo "$(eval echo '$SNAP_'$snapnr)" + eval echo '$'"$snapnr" } setup_snapshot_booting() @@ -704,7 +706,8 @@ mountroot() # ------------ # Look for the cache file (if any). - [ ! -f ${ZPOOL_CACHE} ] && unset ZPOOL_CACHE + [ -f "${ZPOOL_CACHE}" ] || unset ZPOOL_CACHE + [ -s "${ZPOOL_CACHE}" ] || unset ZPOOL_CACHE # ------------ # Compatibility: 'ROOT' is for Debian GNU/Linux (etc), @@ -794,7 +797,8 @@ mountroot() # # Reassign the variable by dumping the environment and # stripping the zfs-bootfs= prefix. Let the shell handle - # quoting through the eval command. + # quoting through the eval command: + # shellcheck disable=SC2046 eval ZFS_RPOOL=$(set | sed -n -e 's,^zfs-bootfs=,,p') fi @@ -815,6 +819,11 @@ mountroot() then # Try to detect both pool and root fs. + # If we got here, that means we don't have a hint so as to + # the root dataset, but with root=zfs:AUTO on cmdline, + # this says "zfs:AUTO" here and interferes with checks later + ZFS_BOOTFS= + [ "$quiet" != "y" ] && \ zfs_log_begin_msg "Attempting to import additional pools." @@ -832,8 +841,8 @@ mountroot() do [ -z "$pool" ] && continue - import_pool "$pool" - find_rootfs "$pool" + IFS="$OLD_IFS" import_pool "$pool" + IFS="$OLD_IFS" find_rootfs "$pool" && break done IFS="$OLD_IFS" @@ -871,7 +880,7 @@ mountroot() echo "" echo "No pool imported. Manually import the root pool" echo "at the command prompt and then exit." - echo "Hint: Try: zpool import -R ${rootmnt} -N ${ZFS_RPOOL}" + echo "Hint: Try: zpool import -N ${ZFS_RPOOL}" shell fi @@ -885,30 +894,6 @@ mountroot() ZFS_RPOOL="${pool}" fi - # Set the no-op scheduler on the disks containing the vdevs of - # the root pool. For single-queue devices, this scheduler is - # "noop", for multi-queue devices, it is "none". - # ZFS already does this for wholedisk vdevs (for all pools), so this - # is only important for partitions. - "${ZPOOL}" status -L "${ZFS_RPOOL}" 2> /dev/null | - awk '/^\t / && !/(mirror|raidz)/ { - dev=$1; - sub(/[0-9]+$/, "", dev); - print dev - }' | - while read -r i - do - SCHEDULER=/sys/block/$i/queue/scheduler - if [ -e "${SCHEDULER}" ] - then - # Query to see what schedulers are available - case "$(cat "${SCHEDULER}")" in - *noop*) echo noop > "${SCHEDULER}" ;; - *none*) echo none > "${SCHEDULER}" ;; - esac - fi - done - # ---------------------------------------------------------------- # P R E P A R E R O O T F I L E S Y S T E M @@ -954,15 +939,20 @@ mountroot() # Go through the complete list (recursively) of all filesystems below # the real root dataset - filesystems=$("${ZFS}" list -oname -tfilesystem -H -r "${ZFS_BOOTFS}") - for fs in $filesystems $ZFS_INITRD_ADDITIONAL_DATASETS - do + filesystems="$("${ZFS}" list -oname -tfilesystem -H -r "${ZFS_BOOTFS}")" + OLD_IFS="$IFS" ; IFS=" +" + for fs in $filesystems; do + IFS="$OLD_IFS" mount_fs "$fs" + done + IFS="$OLD_IFS" + for fs in $ZFS_INITRD_ADDITIONAL_DATASETS; do mount_fs "$fs" done touch /run/zfs_unlock_complete if [ -e /run/zfs_unlock_complete_notify ]; then - read -r zfs_unlock_complete_notify < /run/zfs_unlock_complete_notify + read -r < /run/zfs_unlock_complete_notify fi # ------------ diff --git a/sys/contrib/openzfs/contrib/pyzfs/libzfs_core/test/test_libzfs_core.py b/sys/contrib/openzfs/contrib/pyzfs/libzfs_core/test/test_libzfs_core.py index 87138b305f7..d949d88d5a1 100644 --- a/sys/contrib/openzfs/contrib/pyzfs/libzfs_core/test/test_libzfs_core.py +++ b/sys/contrib/openzfs/contrib/pyzfs/libzfs_core/test/test_libzfs_core.py @@ -252,9 +252,9 @@ def skipUnlessBookmarksSupported(f): def snap_always_unmounted_before_destruction(): - # Apparently ZoL automatically unmounts the snapshot + # Apparently OpenZFS automatically unmounts the snapshot # only if it is mounted at its default .zfs/snapshot - # mountpoint. + # mountpoint under Linux. return ( platform.system() != 'Linux', 'snapshot is not auto-unmounted') diff --git a/sys/contrib/openzfs/copy-builtin b/sys/contrib/openzfs/copy-builtin index 36e19545d9c..cd6f259092e 100755 --- a/sys/contrib/openzfs/copy-builtin +++ b/sys/contrib/openzfs/copy-builtin @@ -1,6 +1,6 @@ -#!/usr/bin/env bash +#!/bin/sh -set -e +set -ef usage() { @@ -9,26 +9,25 @@ usage() } [ "$#" -eq 1 ] || usage -KERNEL_DIR="$(readlink --canonicalize-existing "$1")" +KERNEL_DIR="$1" if ! [ -e 'zfs_config.h' ] then - echo >&2 - echo " $0: you did not run configure, or you're not in the ZFS source directory." >&2 - echo " $0: run configure with --with-linux=$KERNEL_DIR and --enable-linux-builtin." >&2 - echo >&2 - exit 1 -fi + echo "$0: you did not run configure, or you're not in the ZFS source directory." + echo "$0: run configure with --with-linux=$KERNEL_DIR and --enable-linux-builtin." -make clean || true + exit 1 +fi >&2 + +make clean ||: make gitrev rm -rf "$KERNEL_DIR/include/zfs" "$KERNEL_DIR/fs/zfs" -cp --recursive include "$KERNEL_DIR/include/zfs" -cp --recursive module "$KERNEL_DIR/fs/zfs" +cp -R include "$KERNEL_DIR/include/zfs" +cp -R module "$KERNEL_DIR/fs/zfs" cp zfs_config.h "$KERNEL_DIR/include/zfs/" -cat > "$KERNEL_DIR/fs/zfs/Kconfig" <<"EOF" +cat > "$KERNEL_DIR/fs/zfs/Kconfig" < "$FILE.new" @@ -72,8 +70,5 @@ add_after() add_after "$KERNEL_DIR/fs/Kconfig" 'if BLOCK' 'source "fs/zfs/Kconfig"' add_after "$KERNEL_DIR/fs/Makefile" 'endif' 'obj-$(CONFIG_ZFS) += zfs/' -echo >&2 -echo " $0: done." >&2 -echo " $0: now you can build the kernel with ZFS support." >&2 -echo " $0: make sure you enable ZFS support (CONFIG_ZFS) before building." >&2 -echo >&2 +echo "$0: done. now you can build the kernel with ZFS support." >&2 +echo "$0: make sure you enable ZFS support (CONFIG_ZFS) before building." >&2 diff --git a/sys/contrib/openzfs/etc/Makefile.am b/sys/contrib/openzfs/etc/Makefile.am index ac71da9445d..aa9ff182c86 100644 --- a/sys/contrib/openzfs/etc/Makefile.am +++ b/sys/contrib/openzfs/etc/Makefile.am @@ -1,5 +1,9 @@ +include $(top_srcdir)/config/Shellcheck.am + SUBDIRS = zfs sudoers.d +SHELLCHECKDIRS = zfs if BUILD_LINUX +SHELLCHECKDIRS += default $(ZFS_INIT_SYSV) SUBDIRS += default $(ZFS_INIT_SYSTEMD) $(ZFS_INIT_SYSV) $(ZFS_MODULE_LOAD) endif DIST_SUBDIRS = default init.d zfs systemd modules-load.d sudoers.d diff --git a/sys/contrib/openzfs/etc/default/Makefile.am b/sys/contrib/openzfs/etc/default/Makefile.am index 0ec868e1348..b88eb549493 100644 --- a/sys/contrib/openzfs/etc/default/Makefile.am +++ b/sys/contrib/openzfs/etc/default/Makefile.am @@ -1,5 +1,9 @@ include $(top_srcdir)/config/Substfiles.am +include $(top_srcdir)/config/Shellcheck.am initconf_SCRIPTS = zfs SUBSTFILES += $(initconf_SCRIPTS) + +SHELLCHECK_SHELL = sh +SHELLCHECK_IGNORE = ,SC2034 diff --git a/sys/contrib/openzfs/etc/init.d/Makefile.am b/sys/contrib/openzfs/etc/init.d/Makefile.am index 9285a995a1c..f93af1fd77e 100644 --- a/sys/contrib/openzfs/etc/init.d/Makefile.am +++ b/sys/contrib/openzfs/etc/init.d/Makefile.am @@ -1,7 +1,10 @@ include $(top_srcdir)/config/Substfiles.am +include $(top_srcdir)/config/Shellcheck.am EXTRA_DIST += README.md init_SCRIPTS = zfs-import zfs-mount zfs-share zfs-zed SUBSTFILES += $(init_SCRIPTS) + +SHELLCHECK_SHELL = dash # local variables diff --git a/sys/contrib/openzfs/etc/init.d/zfs-import.in b/sys/contrib/openzfs/etc/init.d/zfs-import.in index 714cc6c089d..e4bc7b8339f 100755 --- a/sys/contrib/openzfs/etc/init.d/zfs-import.in +++ b/sys/contrib/openzfs/etc/init.d/zfs-import.in @@ -26,10 +26,8 @@ # # Released under the 2-clause BSD license. # -# The original script that acted as a template for this script came from -# the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a -# licensing stansa) in the commit dated Mar 24, 2011: -# https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a +# This script is based on debian/zfsutils.zfs.init from the +# Debian GNU/kFreeBSD zfsutils 8.1-3 package, written by Aurelien Jarno. # Source the common init script . @sysconfdir@/zfs/zfs-functions @@ -56,16 +54,13 @@ do_verbatim_import() # Support function to get a list of all pools, separated with ';' find_pools() { - local CMD="$*" local pools - pools=$($CMD 2> /dev/null | \ + pools=$("$@" 2> /dev/null | \ grep -E "pool:|^[a-zA-Z0-9]" | \ sed 's@.*: @@' | \ sort | \ - while read pool; do \ - echo -n "$pool;" - done) + tr '\n' ';') echo "${pools%%;}" # Return without the last ';'. } @@ -77,10 +72,11 @@ do_import_all_visible() local exception dir ZPOOL_IMPORT_PATH RET=0 r=1 # In case not shutdown cleanly. + # shellcheck disable=SC2154 [ -n "$init" ] && rm -f /etc/dfs/sharetab # Just simplify code later on. - if [ -n "$USE_DISK_BY_ID" -a "$USE_DISK_BY_ID" != 'yes' ] + if [ -n "$USE_DISK_BY_ID" ] && [ "$USE_DISK_BY_ID" != 'yes' ] then # It's something, but not 'yes' so it's no good to us. unset USE_DISK_BY_ID @@ -153,7 +149,7 @@ do_import_all_visible() # 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 local dirs dirs="$(for dir in $(echo /dev/disk/by-*) @@ -162,7 +158,7 @@ do_import_all_visible() 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" ] @@ -219,6 +215,7 @@ do_import_all_visible() # Import by using ZPOOL_IMPORT_PATH (either set above or in # the config file) _or_ with the 'built in' default search # paths. This is the preferred way. + # shellcheck disable=SC2086 "$ZPOOL" import -N ${ZPOOL_IMPORT_OPTS} "$pool" 2> /dev/null r="$?" ; RET=$((RET + r)) if [ "$r" -eq 0 ] @@ -231,7 +228,7 @@ do_import_all_visible() # using the cache file soon and that might succeed. [ ! -f "$ZPOOL_CACHE" ] && zfs_log_end_msg "$RET" - if [ "$r" -gt 0 -a -f "$ZPOOL_CACHE" ] + if [ "$r" -gt 0 ] && [ -f "$ZPOOL_CACHE" ] then # Failed to import without a cache file. Try WITH... if [ -z "$init" ] && check_boolean "$VERBOSE_MOUNT" @@ -240,6 +237,7 @@ do_import_all_visible() zfs_log_progress_msg " using cache file" fi + # shellcheck disable=SC2086 "$ZPOOL" import -c "$ZPOOL_CACHE" -N ${ZPOOL_IMPORT_OPTS} \ "$pool" 2> /dev/null r="$?" ; RET=$((RET + r)) @@ -254,7 +252,7 @@ do_import_all_visible() [ -n "$init" ] && zfs_log_end_msg "$RET" IFS="$OLD_IFS" - [ -n "$already_imported" -a -z "$available_pools" ] && return 0 + [ -n "$already_imported" ] && [ -z "$available_pools" ] && return 0 return "$RET" } diff --git a/sys/contrib/openzfs/etc/init.d/zfs-mount.in b/sys/contrib/openzfs/etc/init.d/zfs-mount.in index 9b400916f42..000619b6717 100755 --- a/sys/contrib/openzfs/etc/init.d/zfs-mount.in +++ b/sys/contrib/openzfs/etc/init.d/zfs-mount.in @@ -23,10 +23,8 @@ # # Released under the 2-clause BSD license. # -# The original script that acted as a template for this script came from -# the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a -# licensing stansa) in the commit dated Mar 24, 2011: -# https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a +# This script is based on debian/zfsutils.zfs.init from the +# Debian GNU/kFreeBSD zfsutils 8.1-3 package, written by Aurelien Jarno. # Source the common init script . @sysconfdir@/zfs/zfs-functions @@ -34,9 +32,8 @@ # ---------------------------------------------------- chkroot() { - while read line; do - set -- $line - if [ "$2" = "/" ]; then + while read -r _ mp _; do + if [ "$mp" = "/" ]; then return 0 fi done < /proc/self/mounts @@ -65,7 +62,7 @@ do_depend() # Mount all datasets/filesystems do_mount() { - local verbose overlay i mntpt val + local verbose overlay i mntpt check_boolean "$VERBOSE_MOUNT" && verbose=v check_boolean "$DO_OVERLAY_MOUNTS" && overlay=O @@ -83,11 +80,11 @@ do_mount() read_mtab "^/dev/(zd|zvol)" read_fstab "^/dev/(zd|zvol)" - i=0; var=$(eval echo FSTAB_$i) - while [ -n "$(eval echo "$""$var")" ] + i=0; var="FSTAB_0" + while [ -n "$(eval echo "\$$var")" ] do - mntpt=$(eval echo "$""$var") - dev=$(eval echo "$"FSTAB_dev_$i) + mntpt=$(eval echo "\$$var") + dev=$(eval echo "\$FSTAB_dev_$i") if ! in_mtab "$mntpt" && ! is_mounted "$mntpt" && [ -e "$dev" ] then check_boolean "$VERBOSE_MOUNT" && \ @@ -96,15 +93,15 @@ do_mount() fi i=$((i + 1)) - var=$(eval echo FSTAB_$i) + var=$(eval echo "FSTAB_$i") done read_mtab "[[:space:]]zfs[[:space:]]" read_fstab "[[:space:]]zfs[[:space:]]" - i=0; var=$(eval echo FSTAB_$i) - while [ -n "$(eval echo "$""$var")" ] + i=0; var=$(eval echo "FSTAB_$i") + while [ -n "$(eval echo "\$$var")" ] do - mntpt=$(eval echo "$""$var") + mntpt=$(eval echo "\$$var") if ! in_mtab "$mntpt" && ! is_mounted "$mntpt" then check_boolean "$VERBOSE_MOUNT" && \ @@ -113,7 +110,7 @@ do_mount() fi i=$((i + 1)) - var=$(eval echo FSTAB_$i) + var=$(eval echo "FSTAB_$i") done check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 0 @@ -136,11 +133,11 @@ do_unmount() read_mtab "^/dev/(zd|zvol)" read_fstab "^/dev/(zd|zvol)" - i=0; var=$(eval echo FSTAB_$i) - while [ -n "$(eval echo "$""$var")" ] + i=0; var="FSTAB_0" + while [ -n "$(eval echo "\$$var")" ] do - mntpt=$(eval echo "$""$var") - dev=$(eval echo "$"FSTAB_dev_$i) + mntpt=$(eval echo "\$$var") + dev=$(eval echo "\$FSTAB_dev_$i") if in_mtab "$mntpt" then check_boolean "$VERBOSE_MOUNT" && \ @@ -149,15 +146,15 @@ do_unmount() fi i=$((i + 1)) - var=$(eval echo FSTAB_$i) + var=$(eval echo "FSTAB_$i") done read_mtab "[[:space:]]zfs[[:space:]]" read_fstab "[[:space:]]zfs[[:space:]]" - i=0; var=$(eval echo FSTAB_$i) - while [ -n "$(eval echo "$""$var")" ] + i=0; var="FSTAB_0" + while [ -n "$(eval echo "\$$var")" ] do - mntpt=$(eval echo "$""$var") + mntpt=$(eval echo "\$$var") if in_mtab "$mntpt"; then check_boolean "$VERBOSE_MOUNT" && \ zfs_log_progress_msg "$mntpt " @@ -165,7 +162,7 @@ do_unmount() fi i=$((i + 1)) - var=$(eval echo FSTAB_$i) + var=$(eval echo "FSTAB_$i") done check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 0 diff --git a/sys/contrib/openzfs/etc/init.d/zfs-share.in b/sys/contrib/openzfs/etc/init.d/zfs-share.in index 3256d1d067f..ef628fe4636 100755 --- a/sys/contrib/openzfs/etc/init.d/zfs-share.in +++ b/sys/contrib/openzfs/etc/init.d/zfs-share.in @@ -22,10 +22,8 @@ # # Released under the 2-clause BSD license. # -# The original script that acted as a template for this script came from -# the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a -# licensing stansa) in the commit dated Mar 24, 2011: -# https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a +# This script is based on debian/zfsutils.zfs.init from the +# Debian GNU/kFreeBSD zfsutils 8.1-3 package, written by Aurelien Jarno. # Source the common init script . @sysconfdir@/zfs/zfs-functions diff --git a/sys/contrib/openzfs/etc/init.d/zfs-zed.in b/sys/contrib/openzfs/etc/init.d/zfs-zed.in index 6af9ee60c8c..e5256cbc628 100755 --- a/sys/contrib/openzfs/etc/init.d/zfs-zed.in +++ b/sys/contrib/openzfs/etc/init.d/zfs-zed.in @@ -21,10 +21,8 @@ # # Released under the 2-clause BSD license. # -# The original script that acted as a template for this script came from -# the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a -# licensing stansa) in the commit dated Mar 24, 2011: -# https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a +# This script is based on debian/zfsutils.zfs.init from the +# Debian GNU/kFreeBSD zfsutils 8.1-3 package, written by Aurelien Jarno. # Source the common init script . @sysconfdir@/zfs/zfs-functions @@ -32,6 +30,7 @@ ZED_NAME="zed" ZED_PIDFILE="@runstatedir@/$ZED_NAME.pid" +# shellcheck disable=SC2034 extra_started_commands="reload" # Exit if the package is not installed @@ -57,24 +56,20 @@ do_start() do_stop() { - local pools RET + local pools check_module_loaded "zfs" || exit 0 zfs_action "Stopping ZFS Event Daemon" zfs_daemon_stop \ - "$ZED_PIDFILE" "$ZED" "$ZED_NAME" - if [ "$?" -eq "0" ] + "$ZED_PIDFILE" "$ZED" "$ZED_NAME" || return "$?" + + # Let's see if we have any pools imported + pools=$("$ZPOOL" list -H -oname) + if [ -z "$pools" ] then - # Let's see if we have any pools imported - pools=$("$ZPOOL" list -H -oname) - if [ -z "$pools" ] - then - # No pools imported, it is/should be safe/possible to - # unload modules. - zfs_action "Unloading modules" rmmod zfs zunicode \ - zavl zcommon znvpair zlua spl - return "$?" - fi - else + # No pools imported, it is/should be safe/possible to + # unload modules. + zfs_action "Unloading modules" rmmod zfs zunicode \ + zavl zcommon znvpair zlua spl return "$?" fi } diff --git a/sys/contrib/openzfs/etc/systemd/Makefile.am b/sys/contrib/openzfs/etc/systemd/Makefile.am index 7b47b93fc10..66232a5ff19 100644 --- a/sys/contrib/openzfs/etc/systemd/Makefile.am +++ b/sys/contrib/openzfs/etc/systemd/Makefile.am @@ -1 +1,4 @@ +include $(top_srcdir)/config/Shellcheck.am + SUBDIRS = system system-generators +SHELLCHECKDIRS = system-generators diff --git a/sys/contrib/openzfs/etc/systemd/system-generators/Makefile.am b/sys/contrib/openzfs/etc/systemd/system-generators/Makefile.am index fee88dad8ca..e5920bf3920 100644 --- a/sys/contrib/openzfs/etc/systemd/system-generators/Makefile.am +++ b/sys/contrib/openzfs/etc/systemd/system-generators/Makefile.am @@ -1,6 +1,14 @@ -include $(top_srcdir)/config/Substfiles.am +include $(top_srcdir)/config/Rules.am -systemdgenerator_SCRIPTS = \ +systemdgenerator_PROGRAMS = \ zfs-mount-generator -SUBSTFILES += $(systemdgenerator_SCRIPTS) +zfs_mount_generator_SOURCES = \ + zfs-mount-generator.c + +zfs_mount_generator_LDADD = \ + $(abs_top_builddir)/lib/libzfs/libzfs.la + +zfs_mount_generator_LDFLAGS = -pthread + +include $(top_srcdir)/config/CppCheck.am diff --git a/sys/contrib/openzfs/etc/systemd/system-generators/zfs-mount-generator.c b/sys/contrib/openzfs/etc/systemd/system-generators/zfs-mount-generator.c new file mode 100644 index 00000000000..b806339deb2 --- /dev/null +++ b/sys/contrib/openzfs/etc/systemd/system-generators/zfs-mount-generator.c @@ -0,0 +1,1083 @@ +/* + * Copyright (c) 2017 Antonio Russo + * Copyright (c) 2020 InsanePrawn + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STRCMP ((int(*)(const void *, const void *))&strcmp) +#define PID_T_CMP ((int(*)(const void *, const void *))&pid_t_cmp) + +static int +pid_t_cmp(const pid_t *lhs, const pid_t *rhs) +{ + /* + * This is always valid, quoth sys_types.h(7posix): + * > blksize_t, pid_t, and ssize_t shall be signed integer types. + */ + return (*lhs - *rhs); +} + +#define EXIT_ENOMEM() \ + do { \ + fprintf(stderr, PROGNAME "[%d]: " \ + "not enough memory (L%d)!\n", getpid(), __LINE__); \ + _exit(1); \ + } while (0) + + +#define PROGNAME "zfs-mount-generator" +#define FSLIST SYSCONFDIR "/zfs/zfs-list.cache" +#define ZFS SBINDIR "/zfs" + +#define OUTPUT_HEADER \ + "# Automatically generated by " PROGNAME "\n" \ + "\n" + +/* + * Starts like the one in libzfs_util.c but also matches "//" + * and captures until the end, since we actually use it for path extraxion + */ +#define URI_REGEX_S "^\\([A-Za-z][A-Za-z0-9+.\\-]*\\):\\/\\/\\(.*\\)$" +static regex_t uri_regex; + +static char *argv0; + +static const char *destdir = "/tmp"; +static int destdir_fd = -1; + +static void *known_pools = NULL; /* tsearch() of C strings */ +static struct { + sem_t noauto_not_on_sem; + + sem_t noauto_names_sem; + size_t noauto_names_len; + size_t noauto_names_max; + char noauto_names[][NAME_MAX]; +} *noauto_files; + + +static char * +systemd_escape(const char *input, const char *prepend, const char *append) +{ + size_t len = strlen(input); + size_t applen = strlen(append); + size_t prelen = strlen(prepend); + char *ret = malloc(4 * len + prelen + applen + 1); + if (!ret) + EXIT_ENOMEM(); + + memcpy(ret, prepend, prelen); + char *out = ret + prelen; + + const char *cur = input; + if (*cur == '.') { + memcpy(out, "\\x2e", 4); + out += 4; + ++cur; + } + for (; *cur; ++cur) { + if (*cur == '/') + *(out++) = '-'; + else if (strchr( + "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + ":_.", *cur)) + *(out++) = *cur; + else { + sprintf(out, "\\x%02x", (int)*cur); + out += 4; + } + } + + memcpy(out, append, applen + 1); + return (ret); +} + +static void +simplify_path(char *path) +{ + char *out = path; + for (char *cur = path; *cur; ++cur) { + if (*cur == '/') { + while (*(cur + 1) == '/') + ++cur; + *(out++) = '/'; + } else + *(out++) = *cur; + } + + *(out++) = '\0'; +} + +static bool +strendswith(const char *what, const char *suff) +{ + size_t what_l = strlen(what); + size_t suff_l = strlen(suff); + + return ((what_l >= suff_l) && + (strcmp(what + what_l - suff_l, suff) == 0)); +} + +/* Assumes already-simplified path, doesn't modify input */ +static char * +systemd_escape_path(char *input, const char *prepend, const char *append) +{ + if (strcmp(input, "/") == 0) { + char *ret; + if (asprintf(&ret, "%s-%s", prepend, append) == -1) + EXIT_ENOMEM(); + return (ret); + } else { + /* + * path_is_normalized() (flattened for absolute paths here), + * required for proper escaping + */ + if (strstr(input, "/./") || strstr(input, "/../") || + strendswith(input, "/.") || strendswith(input, "/..")) + return (NULL); + + + if (input[0] == '/') + ++input; + + char *back = &input[strlen(input) - 1]; + bool deslash = *back == '/'; + if (deslash) + *back = '\0'; + + char *ret = systemd_escape(input, prepend, append); + + if (deslash) + *back = '/'; + return (ret); + } +} + +static FILE * +fopenat(int dirfd, const char *pathname, int flags, + const char *stream_mode, mode_t mode) +{ + int fd = openat(dirfd, pathname, flags, mode); + if (fd < 0) + return (NULL); + + return (fdopen(fd, stream_mode)); +} + +static int +line_worker(char *line, const char *cachefile) +{ + char *toktmp; + /* BEGIN CSTYLED */ + const char *dataset = strtok_r(line, "\t", &toktmp); + char *p_mountpoint = strtok_r(NULL, "\t", &toktmp); + const char *p_canmount = strtok_r(NULL, "\t", &toktmp); + const char *p_atime = strtok_r(NULL, "\t", &toktmp); + const char *p_relatime = strtok_r(NULL, "\t", &toktmp); + const char *p_devices = strtok_r(NULL, "\t", &toktmp); + const char *p_exec = strtok_r(NULL, "\t", &toktmp); + const char *p_readonly = strtok_r(NULL, "\t", &toktmp); + const char *p_setuid = strtok_r(NULL, "\t", &toktmp); + const char *p_nbmand = strtok_r(NULL, "\t", &toktmp); + const char *p_encroot = strtok_r(NULL, "\t", &toktmp) ?: "-"; + char *p_keyloc = strtok_r(NULL, "\t", &toktmp) ?: strdupa("none"); + const char *p_systemd_requires = strtok_r(NULL, "\t", &toktmp) ?: "-"; + const char *p_systemd_requiresmountsfor = strtok_r(NULL, "\t", &toktmp) ?: "-"; + const char *p_systemd_before = strtok_r(NULL, "\t", &toktmp) ?: "-"; + const char *p_systemd_after = strtok_r(NULL, "\t", &toktmp) ?: "-"; + char *p_systemd_wantedby = strtok_r(NULL, "\t", &toktmp) ?: strdupa("-"); + char *p_systemd_requiredby = strtok_r(NULL, "\t", &toktmp) ?: strdupa("-"); + const char *p_systemd_nofail = strtok_r(NULL, "\t", &toktmp) ?: "-"; + const char *p_systemd_ignore = strtok_r(NULL, "\t", &toktmp) ?: "-"; + /* END CSTYLED */ + + const char *pool = dataset; + if ((toktmp = strchr(pool, '/')) != NULL) + pool = strndupa(pool, toktmp - pool); + + if (p_nbmand == NULL) { + fprintf(stderr, PROGNAME "[%d]: %s: not enough tokens!\n", + getpid(), dataset); + return (1); + } + + strncpy(argv0, dataset, strlen(argv0)); + + /* Minimal pre-requisites to mount a ZFS dataset */ + const char *after = "zfs-import.target"; + const char *wants = "zfs-import.target"; + const char *bindsto = NULL; + char *wantedby = NULL; + char *requiredby = NULL; + bool noauto = false; + bool wantedby_append = true; + + /* + * zfs-import.target is not needed if the pool is already imported. + * This avoids a dependency loop on root-on-ZFS systems: + * systemd-random-seed.service After (via RequiresMountsFor) + * var-lib.mount After + * zfs-import.target After + * zfs-import-{cache,scan}.service After + * cryptsetup.service After + * systemd-random-seed.service + */ + if (tfind(pool, &known_pools, STRCMP)) { + after = ""; + wants = ""; + } + + if (strcmp(p_systemd_after, "-") == 0) + p_systemd_after = NULL; + if (strcmp(p_systemd_before, "-") == 0) + p_systemd_before = NULL; + if (strcmp(p_systemd_requires, "-") == 0) + p_systemd_requires = NULL; + if (strcmp(p_systemd_requiresmountsfor, "-") == 0) + p_systemd_requiresmountsfor = NULL; + + + if (strcmp(p_encroot, "-") != 0) { + char *keyloadunit = + systemd_escape(p_encroot, "zfs-load-key@", ".service"); + + if (strcmp(dataset, p_encroot) == 0) { + const char *keymountdep = NULL; + bool is_prompt = false; + + regmatch_t uri_matches[3]; + if (regexec(&uri_regex, p_keyloc, + sizeof (uri_matches) / sizeof (*uri_matches), + uri_matches, 0) == 0) { + p_keyloc[uri_matches[2].rm_eo] = '\0'; + const char *path = + &p_keyloc[uri_matches[2].rm_so]; + + /* + * Assumes all URI keylocations need + * the mount for their path; + * http://, for example, wouldn't + * (but it'd need network-online.target et al.) + */ + keymountdep = path; + } else { + if (strcmp(p_keyloc, "prompt") != 0) + fprintf(stderr, PROGNAME "[%d]: %s: " + "unknown non-URI keylocation=%s\n", + getpid(), dataset, p_keyloc); + + is_prompt = true; + } + + + /* Generate the key-load .service unit */ + FILE *keyloadunit_f = fopenat(destdir_fd, keyloadunit, + O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, "w", + 0644); + if (!keyloadunit_f) { + fprintf(stderr, PROGNAME "[%d]: %s: " + "couldn't open %s under %s: %s\n", + getpid(), dataset, keyloadunit, destdir, + strerror(errno)); + return (1); + } + + fprintf(keyloadunit_f, + OUTPUT_HEADER + "[Unit]\n" + "Description=Load ZFS key for %s\n" + "SourcePath=" FSLIST "/%s\n" + "Documentation=man:zfs-mount-generator(8)\n" + "DefaultDependencies=no\n" + "Wants=%s\n" + "After=%s\n", + dataset, cachefile, wants, after); + + if (p_systemd_requires) + fprintf(keyloadunit_f, + "Requires=%s\n", p_systemd_requires); + + if (p_systemd_requiresmountsfor || keymountdep) { + fprintf(keyloadunit_f, "RequiresMountsFor="); + if (p_systemd_requiresmountsfor) + fprintf(keyloadunit_f, + "%s ", p_systemd_requiresmountsfor); + if (keymountdep) + fprintf(keyloadunit_f, + "'%s'", keymountdep); + fprintf(keyloadunit_f, "\n"); + } + + /* BEGIN CSTYLED */ + fprintf(keyloadunit_f, + "\n" + "[Service]\n" + "Type=oneshot\n" + "RemainAfterExit=yes\n" + "# This avoids a dependency loop involving systemd-journald.socket if this\n" + "# dataset is a parent of the root filesystem.\n" + "StandardOutput=null\n" + "StandardError=null\n" + "ExecStart=/bin/sh -euc '" + "[ \"$$(" ZFS " get -H -o value keystatus \"%s\")\" = \"unavailable\" ] || exit 0;", + dataset); + if (is_prompt) + fprintf(keyloadunit_f, + "for i in 1 2 3; do " + "systemd-ask-password --id=\"zfs:%s\" \"Enter passphrase for %s:\" |" + "" ZFS " load-key \"%s\" && exit 0;" + "done;" + "exit 1", + dataset, dataset, dataset); + else + fprintf(keyloadunit_f, + "exec " ZFS " load-key \"%s\"", + dataset); + + fprintf(keyloadunit_f, + "'\n" + "ExecStop=/bin/sh -euc '" + "[ \"$$(" ZFS " get -H -o value keystatus \"%s\")\" = \"available\" ] || exit 0;" + "exec " ZFS " unload-key \"%s\"" + "'\n", + dataset, dataset); + /* END CSTYLED */ + + (void) fclose(keyloadunit_f); + } + + /* Update dependencies for the mount file to want this */ + bindsto = keyloadunit; + if (after[0] == '\0') + after = keyloadunit; + else if (asprintf(&toktmp, "%s %s", after, keyloadunit) != -1) + after = toktmp; + else + EXIT_ENOMEM(); + } + + + /* Skip generation of the mount unit if org.openzfs.systemd:ignore=on */ + if (strcmp(p_systemd_ignore, "-") == 0 || + strcmp(p_systemd_ignore, "off") == 0) { + /* ok */ + } else if (strcmp(p_systemd_ignore, "on") == 0) + return (0); + else { + fprintf(stderr, PROGNAME "[%d]: %s: " + "invalid org.openzfs.systemd:ignore=%s\n", + getpid(), dataset, p_systemd_ignore); + return (1); + } + + /* Check for canmount */ + if (strcmp(p_canmount, "on") == 0) { + /* ok */ + } else if (strcmp(p_canmount, "noauto") == 0) + noauto = true; + else if (strcmp(p_canmount, "off") == 0) + return (0); + else { + fprintf(stderr, PROGNAME "[%d]: %s: invalid canmount=%s\n", + getpid(), dataset, p_canmount); + return (1); + } + + /* Check for legacy and blank mountpoints */ + if (strcmp(p_mountpoint, "legacy") == 0 || + strcmp(p_mountpoint, "none") == 0) + return (0); + else if (p_mountpoint[0] != '/') { + fprintf(stderr, PROGNAME "[%d]: %s: invalid mountpoint=%s\n", + getpid(), dataset, p_mountpoint); + return (1); + } + + /* Escape the mountpoint per systemd policy */ + simplify_path(p_mountpoint); + const char *mountfile = systemd_escape_path(p_mountpoint, "", ".mount"); + if (mountfile == NULL) { + fprintf(stderr, + PROGNAME "[%d]: %s: abnormal simplified mountpoint: %s\n", + getpid(), dataset, p_mountpoint); + return (1); + } + + + /* + * Parse options, cf. lib/libzfs/libzfs_mount.c:zfs_add_options + * + * The longest string achievable here is + * ",atime,strictatime,nodev,noexec,rw,nosuid,nomand". + */ + char opts[64] = ""; + + /* atime */ + if (strcmp(p_atime, "on") == 0) { + /* relatime */ + if (strcmp(p_relatime, "on") == 0) + strcat(opts, ",atime,relatime"); + else if (strcmp(p_relatime, "off") == 0) + strcat(opts, ",atime,strictatime"); + else + fprintf(stderr, + PROGNAME "[%d]: %s: invalid relatime=%s\n", + getpid(), dataset, p_relatime); + } else if (strcmp(p_atime, "off") == 0) { + strcat(opts, ",noatime"); + } else + fprintf(stderr, PROGNAME "[%d]: %s: invalid atime=%s\n", + getpid(), dataset, p_atime); + + /* devices */ + if (strcmp(p_devices, "on") == 0) + strcat(opts, ",dev"); + else if (strcmp(p_devices, "off") == 0) + strcat(opts, ",nodev"); + else + fprintf(stderr, PROGNAME "[%d]: %s: invalid devices=%s\n", + getpid(), dataset, p_devices); + + /* exec */ + if (strcmp(p_exec, "on") == 0) + strcat(opts, ",exec"); + else if (strcmp(p_exec, "off") == 0) + strcat(opts, ",noexec"); + else + fprintf(stderr, PROGNAME "[%d]: %s: invalid exec=%s\n", + getpid(), dataset, p_exec); + + /* readonly */ + if (strcmp(p_readonly, "on") == 0) + strcat(opts, ",ro"); + else if (strcmp(p_readonly, "off") == 0) + strcat(opts, ",rw"); + else + fprintf(stderr, PROGNAME "[%d]: %s: invalid readonly=%s\n", + getpid(), dataset, p_readonly); + + /* setuid */ + if (strcmp(p_setuid, "on") == 0) + strcat(opts, ",suid"); + else if (strcmp(p_setuid, "off") == 0) + strcat(opts, ",nosuid"); + else + fprintf(stderr, PROGNAME "[%d]: %s: invalid setuid=%s\n", + getpid(), dataset, p_setuid); + + /* nbmand */ + if (strcmp(p_nbmand, "on") == 0) + strcat(opts, ",mand"); + else if (strcmp(p_nbmand, "off") == 0) + strcat(opts, ",nomand"); + else + fprintf(stderr, PROGNAME "[%d]: %s: invalid nbmand=%s\n", + getpid(), dataset, p_setuid); + + if (strcmp(p_systemd_wantedby, "-") != 0) { + noauto = true; + + if (strcmp(p_systemd_wantedby, "none") != 0) + wantedby = p_systemd_wantedby; + } + + if (strcmp(p_systemd_requiredby, "-") != 0) { + noauto = true; + + if (strcmp(p_systemd_requiredby, "none") != 0) + requiredby = p_systemd_requiredby; + } + + /* + * For datasets with canmount=on, a dependency is created for + * local-fs.target by default. To avoid regressions, this dependency + * is reduced to "wants" rather than "requires" when nofail!=off. + * **THIS MAY CHANGE** + * noauto=on disables this behavior completely. + */ + if (!noauto) { + if (strcmp(p_systemd_nofail, "off") == 0) + requiredby = strdupa("local-fs.target"); + else { + wantedby = strdupa("local-fs.target"); + wantedby_append = strcmp(p_systemd_nofail, "on") != 0; + } + } + + /* + * Handle existing files: + * 1. We never overwrite existing files, although we may delete + * files if we're sure they were created by us. (see 5.) + * 2. We handle files differently based on canmount. + * Units with canmount=on always have precedence over noauto. + * This is enforced by the noauto_not_on_sem semaphore, + * which is only unlocked when the last canmount=on process exits. + * It is important to use p_canmount and not noauto here, + * since we categorise by canmount while other properties, + * e.g. org.openzfs.systemd:wanted-by, also modify noauto. + * 3. If no unit file exists for a noauto dataset, we create one. + * Additionally, we use noauto_files to track the unit file names + * (which are the systemd-escaped mountpoints) of all (exclusively) + * noauto datasets that had a file created. + * 4. If the file to be created is found in the tracking array, + * we do NOT create it. + * 5. If a file exists for a noauto dataset, + * we check whether the file name is in the array. + * If it is, we have multiple noauto datasets for the same + * mountpoint. In such cases, we remove the file for safety. + * We leave the file name in the tracking array to avoid + * further noauto datasets creating a file for this path again. + */ + + { + sem_t *our_sem = (strcmp(p_canmount, "on") == 0) ? + &noauto_files->noauto_names_sem : + &noauto_files->noauto_not_on_sem; + while (sem_wait(our_sem) == -1 && errno == EINTR) + ; + } + + struct stat stbuf; + bool already_exists = fstatat(destdir_fd, mountfile, &stbuf, 0) == 0; + + bool is_known = false; + for (size_t i = 0; i < noauto_files->noauto_names_len; ++i) { + if (strncmp( + noauto_files->noauto_names[i], mountfile, NAME_MAX) == 0) { + is_known = true; + break; + } + } + + if (already_exists) { + if (is_known) { + /* If it's in $noauto_files, we must be noauto too */ + + /* See 5 */ + errno = 0; + (void) unlinkat(destdir_fd, mountfile, 0); + + /* See 2 */ + fprintf(stderr, PROGNAME "[%d]: %s: " + "removing duplicate noauto unit %s%s%s\n", + getpid(), dataset, mountfile, + errno ? "" : " failed: ", + errno ? "" : strerror(errno)); + } else { + /* Don't log for canmount=noauto */ + if (strcmp(p_canmount, "on") == 0) + fprintf(stderr, PROGNAME "[%d]: %s: " + "%s already exists. Skipping.\n", + getpid(), dataset, mountfile); + } + + /* File exists: skip current dataset */ + if (strcmp(p_canmount, "on") == 0) + sem_post(&noauto_files->noauto_names_sem); + return (0); + } else { + if (is_known) { + /* See 4 */ + if (strcmp(p_canmount, "on") == 0) + sem_post(&noauto_files->noauto_names_sem); + return (0); + } else if (strcmp(p_canmount, "noauto") == 0) { + if (noauto_files->noauto_names_len == + noauto_files->noauto_names_max) + fprintf(stderr, PROGNAME "[%d]: %s: " + "noauto dataset limit (%zu) reached! " + "Not tracking %s. Please report this to " + "https://github.com/openzfs/zfs\n", + getpid(), dataset, + noauto_files->noauto_names_max, mountfile); + else { + strncpy(noauto_files->noauto_names[ + noauto_files->noauto_names_len], + mountfile, NAME_MAX); + ++noauto_files->noauto_names_len; + } + } + } + + + FILE *mountfile_f = fopenat(destdir_fd, mountfile, + O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, "w", 0644); + if (strcmp(p_canmount, "on") == 0) + sem_post(&noauto_files->noauto_names_sem); + if (!mountfile_f) { + fprintf(stderr, + PROGNAME "[%d]: %s: couldn't open %s under %s: %s\n", + getpid(), dataset, mountfile, destdir, strerror(errno)); + return (1); + } + + fprintf(mountfile_f, + OUTPUT_HEADER + "[Unit]\n" + "SourcePath=" FSLIST "/%s\n" + "Documentation=man:zfs-mount-generator(8)\n" + "\n" + "Before=", + cachefile); + + if (p_systemd_before) + fprintf(mountfile_f, "%s ", p_systemd_before); + fprintf(mountfile_f, "zfs-mount.service"); /* Ensures we don't race */ + if (requiredby) + fprintf(mountfile_f, " %s", requiredby); + if (wantedby && wantedby_append) + fprintf(mountfile_f, " %s", wantedby); + + fprintf(mountfile_f, + "\n" + "After="); + if (p_systemd_after) + fprintf(mountfile_f, "%s ", p_systemd_after); + fprintf(mountfile_f, "%s\n", after); + + fprintf(mountfile_f, "Wants=%s\n", wants); + + if (bindsto) + fprintf(mountfile_f, "BindsTo=%s\n", bindsto); + if (p_systemd_requires) + fprintf(mountfile_f, "Requires=%s\n", p_systemd_requires); + if (p_systemd_requiresmountsfor) + fprintf(mountfile_f, + "RequiresMountsFor=%s\n", p_systemd_requiresmountsfor); + + fprintf(mountfile_f, + "\n" + "[Mount]\n" + "Where=%s\n" + "What=%s\n" + "Type=zfs\n" + "Options=defaults%s,zfsutil\n", + p_mountpoint, dataset, opts); + + (void) fclose(mountfile_f); + + if (!requiredby && !wantedby) + return (0); + + /* Finally, create the appropriate dependencies */ + char *linktgt; + if (asprintf(&linktgt, "../%s", mountfile) == -1) + EXIT_ENOMEM(); + + char *dependencies[][2] = { + {"wants", wantedby}, + {"requires", requiredby}, + {} + }; + for (__typeof__(&*dependencies) dep = &*dependencies; **dep; ++dep) { + if (!(*dep)[1]) + continue; + + for (char *reqby = strtok_r((*dep)[1], " ", &toktmp); + reqby; + reqby = strtok_r(NULL, " ", &toktmp)) { + char *depdir; + if (asprintf(&depdir, "%s.%s", reqby, (*dep)[0]) == -1) + EXIT_ENOMEM(); + + (void) mkdirat(destdir_fd, depdir, 0755); + int depdir_fd = openat(destdir_fd, depdir, + O_PATH | O_DIRECTORY | O_CLOEXEC); + if (depdir_fd < 0) { + fprintf(stderr, PROGNAME "[%d]: %s: " + "couldn't open %s under %s: %s\n", + getpid(), dataset, depdir, destdir, + strerror(errno)); + free(depdir); + continue; + } + + if (symlinkat(linktgt, depdir_fd, mountfile) == -1) + fprintf(stderr, PROGNAME "[%d]: %s: " + "couldn't symlink at " + "%s under %s under %s: %s\n", + getpid(), dataset, mountfile, + depdir, destdir, strerror(errno)); + + (void) close(depdir_fd); + free(depdir); + } + } + + return (0); +} + + +static int +pool_enumerator(zpool_handle_t *pool, void *data __attribute__((unused))) +{ + int ret = 0; + + /* + * Pools are guaranteed-unique by the kernel, + * no risk of leaking dupes here + */ + char *name = strdup(zpool_get_name(pool)); + if (!name || !tsearch(name, &known_pools, STRCMP)) { + free(name); + ret = ENOMEM; + } + + zpool_close(pool); + return (ret); +} + +int +main(int argc, char **argv) +{ + struct timespec time_init = {}; + clock_gettime(CLOCK_MONOTONIC_RAW, &time_init); + + { + int kmfd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC); + if (kmfd >= 0) { + (void) dup2(kmfd, STDERR_FILENO); + (void) close(kmfd); + } + } + + uint8_t debug = 0; + + argv0 = argv[0]; + switch (argc) { + case 1: + /* Use default */ + break; + case 2: + case 4: + destdir = argv[1]; + break; + default: + fprintf(stderr, + PROGNAME "[%d]: wrong argument count: %d\n", + getpid(), argc - 1); + _exit(1); + } + + { + destdir_fd = open(destdir, O_PATH | O_DIRECTORY | O_CLOEXEC); + if (destdir_fd < 0) { + fprintf(stderr, PROGNAME "[%d]: " + "can't open destination directory %s: %s\n", + getpid(), destdir, strerror(errno)); + _exit(1); + } + } + + DIR *fslist_dir = opendir(FSLIST); + if (!fslist_dir) { + if (errno != ENOENT) + fprintf(stderr, + PROGNAME "[%d]: couldn't open " FSLIST ": %s\n", + getpid(), strerror(errno)); + _exit(0); + } + + { + libzfs_handle_t *libzfs = libzfs_init(); + if (libzfs) { + if (zpool_iter(libzfs, pool_enumerator, NULL) != 0) + fprintf(stderr, PROGNAME "[%d]: " + "error listing pools, ignoring\n", + getpid()); + libzfs_fini(libzfs); + } else + fprintf(stderr, PROGNAME "[%d]: " + "couldn't start libzfs, ignoring\n", + getpid()); + } + + { + int regerr = regcomp(&uri_regex, URI_REGEX_S, 0); + if (regerr != 0) { + fprintf(stderr, + PROGNAME "[%d]: invalid regex: %d\n", + getpid(), regerr); + _exit(1); + } + } + + { + /* + * We could just get a gigabyte here and Not Care, + * but if vm.overcommit_memory=2, then MAP_NORESERVE is ignored + * and we'd try (and likely fail) to rip it out of swap + */ + noauto_files = mmap(NULL, 4 * 1024 * 1024, + PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); + if (noauto_files == MAP_FAILED) { + fprintf(stderr, + PROGNAME "[%d]: couldn't allocate IPC region: %s\n", + getpid(), strerror(errno)); + _exit(1); + } + + sem_init(&noauto_files->noauto_not_on_sem, true, 0); + sem_init(&noauto_files->noauto_names_sem, true, 1); + noauto_files->noauto_names_len = 0; + /* Works out to 16447ish, *well* enough */ + noauto_files->noauto_names_max = + (4 * 1024 * 1024 - sizeof (*noauto_files)) / NAME_MAX; + } + + char *line = NULL; + size_t linelen = 0; + struct timespec time_start = {}; + { + const char *dbgenv = getenv("ZFS_DEBUG"); + if (dbgenv) + debug = atoi(dbgenv); + else { + FILE *cmdline = fopen("/proc/cmdline", "re"); + if (cmdline != NULL) { + if (getline(&line, &linelen, cmdline) >= 0) + debug = strstr(line, "debug") ? 2 : 0; + (void) fclose(cmdline); + } + } + + if (debug && !isatty(STDOUT_FILENO)) + dup2(STDERR_FILENO, STDOUT_FILENO); + } + + size_t forked_canmount_on = 0; + size_t forked_canmount_not_on = 0; + size_t canmount_on_pids_len = 128; + pid_t *canmount_on_pids = + malloc(canmount_on_pids_len * sizeof (*canmount_on_pids)); + if (canmount_on_pids == NULL) + canmount_on_pids_len = 0; + + if (debug) + clock_gettime(CLOCK_MONOTONIC_RAW, &time_start); + + ssize_t read; + pid_t pid; + struct dirent *cachent; + while ((cachent = readdir(fslist_dir)) != NULL) { + if (strcmp(cachent->d_name, ".") == 0 || + strcmp(cachent->d_name, "..") == 0) + continue; + + FILE *cachefile = fopenat(dirfd(fslist_dir), cachent->d_name, + O_RDONLY | O_CLOEXEC, "r", 0); + if (!cachefile) { + fprintf(stderr, PROGNAME "[%d]: " + "couldn't open %s under " FSLIST ": %s\n", + getpid(), cachent->d_name, strerror(errno)); + continue; + } + + while ((read = getline(&line, &linelen, cachefile)) >= 0) { + line[read - 1] = '\0'; /* newline */ + + switch (pid = fork()) { + case -1: + fprintf(stderr, + PROGNAME "[%d]: couldn't fork for %s: %s\n", + getpid(), line, strerror(errno)); + break; + case 0: /* child */ + _exit(line_worker(line, cachent->d_name)); + default: { /* parent */ + char *tmp; + char *dset = strtok_r(line, "\t", &tmp); + strtok_r(NULL, "\t", &tmp); + char *canmount = strtok_r(NULL, "\t", &tmp); + bool canmount_on = + canmount && strncmp(canmount, "on", 2) == 0; + + if (debug >= 2) + printf(PROGNAME ": forked %d, " + "canmount_on=%d, dataset=%s\n", + (int)pid, canmount_on, dset); + + if (canmount_on && + forked_canmount_on == + canmount_on_pids_len) { + size_t new_len = + (canmount_on_pids_len ?: 16) * 2; + void *new_pidlist = + realloc(canmount_on_pids, + new_len * + sizeof (*canmount_on_pids)); + if (!new_pidlist) { + fprintf(stderr, + PROGNAME "[%d]: " + "out of memory! " + "Mount ordering may be " + "affected.\n", getpid()); + continue; + } + + canmount_on_pids = new_pidlist; + canmount_on_pids_len = new_len; + } + + if (canmount_on) { + canmount_on_pids[forked_canmount_on] = + pid; + ++forked_canmount_on; + } else + ++forked_canmount_not_on; + break; + } + } + } + + (void) fclose(cachefile); + } + free(line); + + if (forked_canmount_on == 0) { + /* No canmount=on processes to finish, so don't deadlock here */ + for (size_t i = 0; i < forked_canmount_not_on; ++i) + sem_post(&noauto_files->noauto_not_on_sem); + } else { + /* Likely a no-op, since we got these from a narrow fork loop */ + qsort(canmount_on_pids, forked_canmount_on, + sizeof (*canmount_on_pids), PID_T_CMP); + } + + int status, ret = 0; + struct rusage usage; + size_t forked_canmount_on_max = forked_canmount_on; + while ((pid = wait4(-1, &status, 0, &usage)) != -1) { + ret |= WEXITSTATUS(status) | WTERMSIG(status); + + if (forked_canmount_on != 0) { + if (bsearch(&pid, canmount_on_pids, + forked_canmount_on_max, sizeof (*canmount_on_pids), + PID_T_CMP)) + --forked_canmount_on; + + if (forked_canmount_on == 0) { + /* + * All canmount=on processes have finished, + * let all the lower-priority ones finish now + */ + for (size_t i = 0; + i < forked_canmount_not_on; ++i) + sem_post( + &noauto_files->noauto_not_on_sem); + } + } + + if (debug >= 2) + printf(PROGNAME ": %d done, user=%llu.%06us, " + "system=%llu.%06us, maxrss=%ldB, ex=0x%x\n", + (int)pid, + (unsigned long long) usage.ru_utime.tv_sec, + (unsigned int) usage.ru_utime.tv_usec, + (unsigned long long) usage.ru_stime.tv_sec, + (unsigned int) usage.ru_stime.tv_usec, + usage.ru_maxrss * 1024, status); + } + + if (debug) { + struct timespec time_end = {}; + clock_gettime(CLOCK_MONOTONIC_RAW, &time_end); + + getrusage(RUSAGE_SELF, &usage); + printf( + "\n" + PROGNAME ": self : " + "user=%llu.%06us, system=%llu.%06us, maxrss=%ldB\n", + (unsigned long long) usage.ru_utime.tv_sec, + (unsigned int) usage.ru_utime.tv_usec, + (unsigned long long) usage.ru_stime.tv_sec, + (unsigned int) usage.ru_stime.tv_usec, + usage.ru_maxrss * 1024); + + getrusage(RUSAGE_CHILDREN, &usage); + printf(PROGNAME ": children: " + "user=%llu.%06us, system=%llu.%06us, maxrss=%ldB\n", + (unsigned long long) usage.ru_utime.tv_sec, + (unsigned int) usage.ru_utime.tv_usec, + (unsigned long long) usage.ru_stime.tv_sec, + (unsigned int) usage.ru_stime.tv_usec, + usage.ru_maxrss * 1024); + + if (time_start.tv_nsec > time_end.tv_nsec) { + time_end.tv_nsec = + 1000000000 + time_end.tv_nsec - time_start.tv_nsec; + time_end.tv_sec -= 1; + } else + time_end.tv_nsec -= time_start.tv_nsec; + time_end.tv_sec -= time_start.tv_sec; + + if (time_init.tv_nsec > time_start.tv_nsec) { + time_start.tv_nsec = + 1000000000 + time_start.tv_nsec - time_init.tv_nsec; + time_start.tv_sec -= 1; + } else + time_start.tv_nsec -= time_init.tv_nsec; + time_start.tv_sec -= time_init.tv_sec; + + time_init.tv_nsec = time_start.tv_nsec + time_end.tv_nsec; + time_init.tv_sec = + time_start.tv_sec + time_end.tv_sec + + time_init.tv_nsec / 1000000000; + time_init.tv_nsec %= 1000000000; + + printf(PROGNAME ": wall : " + "total=%llu.%09llus = " + "init=%llu.%09llus + real=%llu.%09llus\n", + (unsigned long long) time_init.tv_sec, + (unsigned long long) time_init.tv_nsec, + (unsigned long long) time_start.tv_sec, + (unsigned long long) time_start.tv_nsec, + (unsigned long long) time_end.tv_sec, + (unsigned long long) time_end.tv_nsec); + } + + _exit(ret); +} diff --git a/sys/contrib/openzfs/etc/systemd/system-generators/zfs-mount-generator.in b/sys/contrib/openzfs/etc/systemd/system-generators/zfs-mount-generator.in deleted file mode 100755 index 28439f424ad..00000000000 --- a/sys/contrib/openzfs/etc/systemd/system-generators/zfs-mount-generator.in +++ /dev/null @@ -1,473 +0,0 @@ -#!/bin/sh - -# zfs-mount-generator - generates systemd mount units for zfs -# Copyright (c) 2017 Antonio Russo -# Copyright (c) 2020 InsanePrawn -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -set -e - -FSLIST="@sysconfdir@/zfs/zfs-list.cache" - -[ -d "${FSLIST}" ] || exit 0 - -do_fail() { - printf 'zfs-mount-generator: %s\n' "$*" > /dev/kmsg - exit 1 -} - -# test if $1 is in space-separated list $2 -is_known() { - query="$1" - IFS=' ' - for element in $2 ; do - if [ "$query" = "$element" ] ; then - return 0 - fi - done - return 1 -} - -# create dependency on unit file $1 -# of type $2, i.e. "wants" or "requires" -# in the target units from space-separated list $3 -create_dependencies() { - unitfile="$1" - suffix="$2" - IFS=' ' - for target in $3 ; do - target_dir="${dest_norm}/${target}.${suffix}/" - mkdir -p "${target_dir}" - ln -s "../${unitfile}" "${target_dir}" - done -} - -# see systemd.generator -if [ $# -eq 0 ] ; then - dest_norm="/tmp" -elif [ $# -eq 3 ] ; then - dest_norm="${1}" -else - do_fail "zero or three arguments required" -fi - -pools=$(zpool list -H -o name || true) - -# All needed information about each ZFS is available from -# zfs list -H -t filesystem -o -# cached in $FSLIST, and each line is processed by the following function: -# See the list below for the properties and their order - -process_line() { - - # zfs list -H -o name,... - # fields are tab separated - IFS="$(printf '\t')" - # shellcheck disable=SC2086 - set -- $1 - - dataset="${1}" - pool="${dataset%%/*}" - p_mountpoint="${2}" - p_canmount="${3}" - p_atime="${4}" - p_relatime="${5}" - p_devices="${6}" - p_exec="${7}" - p_readonly="${8}" - p_setuid="${9}" - p_nbmand="${10}" - p_encroot="${11}" - p_keyloc="${12}" - p_systemd_requires="${13}" - p_systemd_requiresmountsfor="${14}" - p_systemd_before="${15}" - p_systemd_after="${16}" - p_systemd_wantedby="${17}" - p_systemd_requiredby="${18}" - p_systemd_nofail="${19}" - p_systemd_ignore="${20}" - - # Minimal pre-requisites to mount a ZFS dataset - # By ordering before zfs-mount.service, we avoid race conditions. - after="zfs-import.target" - before="zfs-mount.service" - wants="zfs-import.target" - requires="" - requiredmounts="" - bindsto="" - wantedby="" - requiredby="" - noauto="off" - - # If the pool is already imported, zfs-import.target is not needed. This - # avoids a dependency loop on root-on-ZFS systems: - # systemd-random-seed.service After (via RequiresMountsFor) var-lib.mount - # After zfs-import.target After zfs-import-{cache,scan}.service After - # cryptsetup.service After systemd-random-seed.service. - # - # Pools are newline-separated and may contain spaces in their names. - # There is no better portable way to set IFS to just a newline. Using - # $(printf '\n') doesn't work because $(...) strips trailing newlines. - IFS=" -" - for p in $pools ; do - if [ "$p" = "$pool" ] ; then - after="" - wants="" - break - fi - done - - if [ -n "${p_systemd_after}" ] && \ - [ "${p_systemd_after}" != "-" ] ; then - after="${p_systemd_after} ${after}" - fi - - if [ -n "${p_systemd_before}" ] && \ - [ "${p_systemd_before}" != "-" ] ; then - before="${p_systemd_before} ${before}" - fi - - if [ -n "${p_systemd_requires}" ] && \ - [ "${p_systemd_requires}" != "-" ] ; then - requires="Requires=${p_systemd_requires}" - fi - - if [ -n "${p_systemd_requiresmountsfor}" ] && \ - [ "${p_systemd_requiresmountsfor}" != "-" ] ; then - requiredmounts="RequiresMountsFor=${p_systemd_requiresmountsfor}" - fi - - # Handle encryption - if [ -n "${p_encroot}" ] && - [ "${p_encroot}" != "-" ] ; then - keyloadunit="zfs-load-key-$(systemd-escape "${p_encroot}").service" - if [ "${p_encroot}" = "${dataset}" ] ; then - keymountdep="" - if [ "${p_keyloc%%://*}" = "file" ] ; then - if [ -n "${requiredmounts}" ] ; then - keymountdep="${requiredmounts} '${p_keyloc#file://}'" - else - keymountdep="RequiresMountsFor='${p_keyloc#file://}'" - fi - keyloadscript="@sbindir@/zfs load-key \"${dataset}\"" - elif [ "${p_keyloc}" = "prompt" ] ; then - keyloadscript="\ -count=0;\ -while [ \$\$count -lt 3 ];do\ - systemd-ask-password --id=\"zfs:${dataset}\"\ - \"Enter passphrase for ${dataset}:\"|\ - @sbindir@/zfs load-key \"${dataset}\" && exit 0;\ - count=\$\$((count + 1));\ -done;\ -exit 1" - else - printf 'zfs-mount-generator: (%s) invalid keylocation\n' \ - "${dataset}" >/dev/kmsg - fi - keyloadcmd="\ -/bin/sh -c '\ -set -eu;\ -keystatus=\"\$\$(@sbindir@/zfs get -H -o value keystatus \"${dataset}\")\";\ -[ \"\$\$keystatus\" = \"unavailable\" ] || exit 0;\ -${keyloadscript}'" - keyunloadcmd="\ -/bin/sh -c '\ -set -eu;\ -keystatus=\"\$\$(@sbindir@/zfs get -H -o value keystatus \"${dataset}\")\";\ -[ \"\$\$keystatus\" = \"available\" ] || exit 0;\ -@sbindir@/zfs unload-key \"${dataset}\"'" - - - - # Generate the key-load .service unit - # - # Note: It is tempting to use a `< "${dest_norm}/${keyloadunit}" - fi - # Update the dependencies for the mount file to want the - # key-loading unit. - wants="${wants}" - bindsto="BindsTo=${keyloadunit}" - after="${after} ${keyloadunit}" - fi - - # Prepare the .mount unit - - # skip generation of the mount unit if org.openzfs.systemd:ignore is "on" - if [ -n "${p_systemd_ignore}" ] ; then - if [ "${p_systemd_ignore}" = "on" ] ; then - return - elif [ "${p_systemd_ignore}" = "-" ] \ - || [ "${p_systemd_ignore}" = "off" ] ; then - : # This is OK - else - do_fail "invalid org.openzfs.systemd:ignore for ${dataset}" - fi - fi - - # Check for canmount=off . - if [ "${p_canmount}" = "off" ] ; then - return - elif [ "${p_canmount}" = "noauto" ] ; then - noauto="on" - elif [ "${p_canmount}" = "on" ] ; then - : # This is OK - else - do_fail "invalid canmount for ${dataset}" - fi - - # Check for legacy and blank mountpoints. - if [ "${p_mountpoint}" = "legacy" ] ; then - return - elif [ "${p_mountpoint}" = "none" ] ; then - return - elif [ "${p_mountpoint%"${p_mountpoint#?}"}" != "/" ] ; then - do_fail "invalid mountpoint for ${dataset}" - fi - - # Escape the mountpoint per systemd policy. - mountfile="$(systemd-escape --path --suffix=mount "${p_mountpoint}")" - - # Parse options - # see lib/libzfs/libzfs_mount.c:zfs_add_options - opts="" - - # atime - if [ "${p_atime}" = on ] ; then - # relatime - if [ "${p_relatime}" = on ] ; then - opts="${opts},atime,relatime" - elif [ "${p_relatime}" = off ] ; then - opts="${opts},atime,strictatime" - else - printf 'zfs-mount-generator: (%s) invalid relatime\n' \ - "${dataset}" >/dev/kmsg - fi - elif [ "${p_atime}" = off ] ; then - opts="${opts},noatime" - else - printf 'zfs-mount-generator: (%s) invalid atime\n' \ - "${dataset}" >/dev/kmsg - fi - - # devices - if [ "${p_devices}" = on ] ; then - opts="${opts},dev" - elif [ "${p_devices}" = off ] ; then - opts="${opts},nodev" - else - printf 'zfs-mount-generator: (%s) invalid devices\n' \ - "${dataset}" >/dev/kmsg - fi - - # exec - if [ "${p_exec}" = on ] ; then - opts="${opts},exec" - elif [ "${p_exec}" = off ] ; then - opts="${opts},noexec" - else - printf 'zfs-mount-generator: (%s) invalid exec\n' \ - "${dataset}" >/dev/kmsg - fi - - # readonly - if [ "${p_readonly}" = on ] ; then - opts="${opts},ro" - elif [ "${p_readonly}" = off ] ; then - opts="${opts},rw" - else - printf 'zfs-mount-generator: (%s) invalid readonly\n' \ - "${dataset}" >/dev/kmsg - fi - - # setuid - if [ "${p_setuid}" = on ] ; then - opts="${opts},suid" - elif [ "${p_setuid}" = off ] ; then - opts="${opts},nosuid" - else - printf 'zfs-mount-generator: (%s) invalid setuid\n' \ - "${dataset}" >/dev/kmsg - fi - - # nbmand - if [ "${p_nbmand}" = on ] ; then - opts="${opts},mand" - elif [ "${p_nbmand}" = off ] ; then - opts="${opts},nomand" - else - printf 'zfs-mount-generator: (%s) invalid nbmand\n' \ - "${dataset}" >/dev/kmsg - fi - - if [ -n "${p_systemd_wantedby}" ] && \ - [ "${p_systemd_wantedby}" != "-" ] ; then - noauto="on" - if [ "${p_systemd_wantedby}" = "none" ] ; then - wantedby="" - else - wantedby="${p_systemd_wantedby}" - before="${before} ${wantedby}" - fi - fi - - if [ -n "${p_systemd_requiredby}" ] && \ - [ "${p_systemd_requiredby}" != "-" ] ; then - noauto="on" - if [ "${p_systemd_requiredby}" = "none" ] ; then - requiredby="" - else - requiredby="${p_systemd_requiredby}" - before="${before} ${requiredby}" - fi - fi - - # For datasets with canmount=on, a dependency is created for - # local-fs.target by default. To avoid regressions, this dependency - # is reduced to "wants" rather than "requires" when nofail is not "off". - # **THIS MAY CHANGE** - # noauto=on disables this behavior completely. - if [ "${noauto}" != "on" ] ; then - if [ "${p_systemd_nofail}" = "off" ] ; then - requiredby="local-fs.target" - before="${before} local-fs.target" - else - wantedby="local-fs.target" - if [ "${p_systemd_nofail}" != "on" ] ; then - before="${before} local-fs.target" - fi - fi - fi - - # Handle existing files: - # 1. We never overwrite existing files, although we may delete - # files if we're sure they were created by us. (see 5.) - # 2. We handle files differently based on canmount. Units with canmount=on - # always have precedence over noauto. This is enforced by the sort pipe - # in the loop around this function. - # It is important to use $p_canmount and not $noauto here, since we - # sort by canmount while other properties also modify $noauto, e.g. - # org.openzfs.systemd:wanted-by. - # 3. If no unit file exists for a noauto dataset, we create one. - # Additionally, we use $noauto_files to track the unit file names - # (which are the systemd-escaped mountpoints) of all (exclusively) - # noauto datasets that had a file created. - # 4. If the file to be created is found in the tracking variable, - # we do NOT create it. - # 5. If a file exists for a noauto dataset, we check whether the file - # name is in the variable. If it is, we have multiple noauto datasets - # for the same mountpoint. In such cases, we remove the file for safety. - # To avoid further noauto datasets creating a file for this path again, - # we leave the file name in the tracking variable. - if [ -e "${dest_norm}/${mountfile}" ] ; then - if is_known "$mountfile" "$noauto_files" ; then - # if it's in $noauto_files, we must be noauto too. See 2. - printf 'zfs-mount-generator: removing duplicate noauto %s\n' \ - "${mountfile}" >/dev/kmsg - # See 5. - rm "${dest_norm}/${mountfile}" - else - # don't log for canmount=noauto - if [ "${p_canmount}" = "on" ] ; then - printf 'zfs-mount-generator: %s already exists. Skipping.\n' \ - "${mountfile}" >/dev/kmsg - fi - fi - # file exists; Skip current dataset. - return - else - if is_known "${mountfile}" "${noauto_files}" ; then - # See 4. - return - elif [ "${p_canmount}" = "noauto" ] ; then - noauto_files="${mountfile} ${noauto_files}" - fi - fi - - # Create the .mount unit file. - # - # (Do not use `< "${dest_norm}/${mountfile}" - - # Finally, create the appropriate dependencies - create_dependencies "${mountfile}" "wants" "$wantedby" - create_dependencies "${mountfile}" "requires" "$requiredby" - -} - -for cachefile in "${FSLIST}/"* ; do - # Disable glob expansion to protect against special characters when parsing. - set -f - # Sort cachefile's lines by canmount, "on" before "noauto" - # and feed each line into process_line - sort -t "$(printf '\t')" -k 3 -r "${cachefile}" | \ - ( # subshell is necessary for `sort|while read` and $noauto_files - noauto_files="" - while read -r fs ; do - process_line "${fs}" - done - ) -done diff --git a/sys/contrib/openzfs/etc/zfs/Makefile.am b/sys/contrib/openzfs/etc/zfs/Makefile.am index b9123c176b9..3dee81c7586 100644 --- a/sys/contrib/openzfs/etc/zfs/Makefile.am +++ b/sys/contrib/openzfs/etc/zfs/Makefile.am @@ -1,4 +1,5 @@ include $(top_srcdir)/config/Substfiles.am +include $(top_srcdir)/config/Shellcheck.am pkgsysconfdir = $(sysconfdir)/zfs @@ -13,3 +14,5 @@ pkgsysconf_SCRIPTS = \ zfs-functions SUBSTFILES += $(pkgsysconf_SCRIPTS) + +SHELLCHECK_SHELL = dash # local variables diff --git a/sys/contrib/openzfs/etc/zfs/zfs-functions.in b/sys/contrib/openzfs/etc/zfs/zfs-functions.in index c2ce6157c6e..2fb065afdb9 100644 --- a/sys/contrib/openzfs/etc/zfs/zfs-functions.in +++ b/sys/contrib/openzfs/etc/zfs/zfs-functions.in @@ -5,22 +5,20 @@ # # Released under the 2-clause BSD license. # -# The original script that acted as a template for this script came from -# the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a -# licensing stansa) in the commit dated Mar 24, 2011: -# https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a +# This script is based on debian/zfsutils.zfs.init from the +# Debian GNU/kFreeBSD zfsutils 8.1-3 package, written by Aurelien Jarno. PATH=/sbin:/bin:/usr/bin:/usr/sbin # Source function library if [ -f /etc/rc.d/init.d/functions ]; then - # RedHat and derivates + # RedHat and derivatives . /etc/rc.d/init.d/functions elif [ -L /etc/init.d/functions.sh ]; then # Gentoo . /etc/init.d/functions.sh elif [ -f /lib/lsb/init-functions ]; then - # LSB, Debian GNU/Linux and derivates + # LSB, Debian, and derivatives . /lib/lsb/init-functions fi @@ -46,7 +44,7 @@ elif type success > /dev/null 2>&1 ; then fi } - zfs_log_begin_msg() { echo -n "$1 "; } + zfs_log_begin_msg() { printf "%s" "$1 "; } zfs_log_end_msg() { zfs_set_ifs "$OLD_IFS" if [ "$1" -eq 0 ]; then @@ -63,17 +61,17 @@ elif type success > /dev/null 2>&1 ; then echo zfs_set_ifs "$TMP_IFS" } - zfs_log_progress_msg() { echo -n $"$1"; } + zfs_log_progress_msg() { printf "%s" "$""$1"; } elif type einfo > /dev/null 2>&1 ; then # Gentoo functions zfs_log_begin_msg() { ebegin "$1"; } zfs_log_end_msg() { eend "$1"; } zfs_log_failure_msg() { eend "$1"; } -# zfs_log_progress_msg() { echo -n "$1"; } - zfs_log_progress_msg() { echo -n; } +# zfs_log_progress_msg() { printf "%s" "$1"; } + zfs_log_progress_msg() { :; } else # Unknown - simple substitutes. - zfs_log_begin_msg() { echo -n "$1"; } + zfs_log_begin_msg() { printf "%s" "$1"; } zfs_log_end_msg() { ret=$1 if [ "$ret" -ge 1 ]; then @@ -84,7 +82,7 @@ else return "$ret" } zfs_log_failure_msg() { echo "$1"; } - zfs_log_progress_msg() { echo -n "$1"; } + zfs_log_progress_msg() { printf "%s" "$1"; } fi # Paths to what we need @@ -136,27 +134,28 @@ zfs_daemon_start() { local PIDFILE="$1"; shift local DAEMON_BIN="$1"; shift - local DAEMON_ARGS="$*" if type start-stop-daemon > /dev/null 2>&1 ; then # LSB functions start-stop-daemon --start --quiet --pidfile "$PIDFILE" \ --exec "$DAEMON_BIN" --test > /dev/null || return 1 - start-stop-daemon --start --quiet --exec "$DAEMON_BIN" -- \ - $DAEMON_ARGS || return 2 + # shellcheck disable=SC2086 + start-stop-daemon --start --quiet --exec "$DAEMON_BIN" -- \ + "$@" || return 2 - # On Debian GNU/Linux, there's a 'sendsigs' script that will + # On Debian, there's a 'sendsigs' script that will # kill basically everything quite early and zed is stopped # much later than that. We don't want zed to be among them, # so add the zed pid to list of pids to ignore. - if [ -f "$PIDFILE" -a -d /run/sendsigs.omit.d ] + if [ -f "$PIDFILE" ] && [ -d /run/sendsigs.omit.d ] then ln -sf "$PIDFILE" /run/sendsigs.omit.d/zed fi elif type daemon > /dev/null 2>&1 ; then - # Fedora/RedHat functions - daemon --pidfile "$PIDFILE" "$DAEMON_BIN" $DAEMON_ARGS + # Fedora/RedHat functions + # shellcheck disable=SC2086 + daemon --pidfile "$PIDFILE" "$DAEMON_BIN" "$@" return $? else # Unsupported @@ -182,15 +181,17 @@ zfs_daemon_stop() # LSB functions start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \ --pidfile "$PIDFILE" --name "$DAEMON_NAME" - [ "$?" = 0 ] && rm -f "$PIDFILE" + ret="$?" + [ "$ret" = 0 ] && rm -f "$PIDFILE" - return $? + return "$ret" elif type killproc > /dev/null 2>&1 ; then # Fedora/RedHat functions killproc -p "$PIDFILE" "$DAEMON_NAME" - [ "$?" = 0 ] && rm -f "$PIDFILE" + ret="$?" + [ "$ret" = 0 ] && rm -f "$PIDFILE" - return $? + return "$ret" else # Unsupported return 3 @@ -234,7 +235,7 @@ zfs_daemon_reload() return $? elif type killproc > /dev/null 2>&1 ; then # Fedora/RedHat functions - killproc -p "$PIDFILE" "$DAEMON_NAME" -HUP + killproc -p "$PIDFILE" "$DAEMON_NAME" -HUP return $? else # Unsupported @@ -287,6 +288,7 @@ checksystem() # HOWEVER, only do this if we're called at the boot up # (from init), not if we're running interactively (as in # from the shell - we know what we're doing). + # shellcheck disable=SC2154 [ -n "$init" ] && exit 3 fi @@ -301,6 +303,7 @@ checksystem() get_root_pool() { + # shellcheck disable=SC2046 set -- $(mount | grep ' on / ') [ "$5" = "zfs" ] && echo "${1%%/*}" } @@ -338,9 +341,10 @@ load_module() read_mtab() { local match="$1" - local fs mntpnt fstype opts rest TMPFILE + local fs mntpnt fstype opts rest # Unset all MTAB_* variables + # shellcheck disable=SC2046 unset $(env | grep ^MTAB_ | sed 's,=.*,,') while read -r fs mntpnt fstype opts rest; do @@ -352,8 +356,8 @@ read_mtab() # * We need to use the external echo, because the # internal one would interpret the backslash code # (incorrectly), giving us a  instead. - mntpnt=$(/bin/echo "$mntpnt" | sed "s,\\\0,\\\00,g") - fs=$(/bin/echo "$fs" | sed "s,\\\0,\\\00,") + mntpnt=$(/bin/echo "$mntpnt" | sed 's,\\0,\\00,g') + fs=$(/bin/echo "$fs" | sed 's,\\0,\\00,') # Remove 'unwanted' characters. mntpnt=$(printf '%b\n' "$mntpnt" | sed -e 's,/,,g' \ @@ -361,7 +365,7 @@ read_mtab() fs=$(printf '%b\n' "$fs") # Set the variable. - eval export MTAB_$mntpnt=\"$fs\" + eval export "MTAB_$mntpnt=\"$fs\"" fi done < /proc/self/mounts } @@ -371,10 +375,10 @@ in_mtab() local mntpnt="$1" # Remove 'unwanted' characters. mntpnt=$(printf '%b\n' "$mntpnt" | sed -e 's,/,,g' \ - -e 's,-,,g' -e 's,\.,,g' -e 's, ,,g') + -e 's,-,,g' -e 's,\.,,g' -e 's, ,,g') local var - var="$(eval echo MTAB_$mntpnt)" + var="$(eval echo "MTAB_$mntpnt")" [ "$(eval echo "$""$var")" != "" ] return "$?" } @@ -383,21 +387,22 @@ in_mtab() read_fstab() { local match="$1" - local i var TMPFILE + local i var # Unset all FSTAB_* variables + # shellcheck disable=SC2046 unset $(env | grep ^FSTAB_ | sed 's,=.*,,') i=0 while read -r fs mntpnt fstype opts; do - echo "$fs" | egrep -qE '^#|^$' && continue - echo "$mntpnt" | egrep -qE '^none|^swap' && continue - echo "$fstype" | egrep -qE '^swap' && continue + echo "$fs" | grep -qE '^#|^$' && continue + echo "$mntpnt" | grep -qE '^none|^swap' && continue + echo "$fstype" | grep -qE '^swap' && continue if echo "$fs $mntpnt $fstype $opts" | grep -qE "$match"; then - eval export FSTAB_dev_$i="$fs" + eval export "FSTAB_dev_$i=$fs" fs=$(printf '%b\n' "$fs" | sed 's,/,_,g') - eval export FSTAB_$i="$mntpnt" + eval export "FSTAB_$i=$mntpnt" i=$((i + 1)) fi @@ -408,7 +413,7 @@ in_fstab() { local var - var="$(eval echo FSTAB_$1)" + var="$(eval echo "FSTAB_$1")" [ "${var}" != "" ] return $? } @@ -416,19 +421,11 @@ in_fstab() is_mounted() { local mntpt="$1" - local line + local mp - mount | \ - while read line; do - if echo "$line" | grep -q " on $mntpt "; then - # returns: - # 0 on unsuccessful match - # 1 on a successful match - return 1 - fi - done + while read -r _ mp _; do + [ "$mp" = "$mntpt" ] && return 0 + done < /proc/self/mounts - # The negation will flip the subshell return result where the default - # return value is 0 when a match is not found. - return $(( !$? )) + return 1 } diff --git a/sys/contrib/openzfs/include/Makefile.am b/sys/contrib/openzfs/include/Makefile.am index 17286ecbb7f..4da43afd850 100644 --- a/sys/contrib/openzfs/include/Makefile.am +++ b/sys/contrib/openzfs/include/Makefile.am @@ -17,7 +17,6 @@ USER_H = \ libzfs.h \ libzfsbootenv.h \ libzfs_core.h \ - libzfs_impl.h \ libzutil.h \ thread_pool.h diff --git a/sys/contrib/openzfs/include/cityhash.h b/sys/contrib/openzfs/include/cityhash.h index 33c3b7bc253..3b2d1e84b5b 100644 --- a/sys/contrib/openzfs/include/cityhash.h +++ b/sys/contrib/openzfs/include/cityhash.h @@ -24,7 +24,7 @@ */ #ifndef _SYS_CITYHASH_H -#define _SYS_CITYHASH_H +#define _SYS_CITYHASH_H extern __attribute__((visibility("default"))) #include @@ -32,7 +32,7 @@ extern "C" { #endif -uint64_t cityhash4(uint64_t, uint64_t, uint64_t, uint64_t); +_SYS_CITYHASH_H uint64_t cityhash4(uint64_t, uint64_t, uint64_t, uint64_t); #ifdef __cplusplus } diff --git a/sys/contrib/openzfs/include/libuutil.h b/sys/contrib/openzfs/include/libuutil.h index d0248901b4e..1d179945cca 100644 --- a/sys/contrib/openzfs/include/libuutil.h +++ b/sys/contrib/openzfs/include/libuutil.h @@ -98,28 +98,6 @@ extern int *uu_exit_ok(void); extern int *uu_exit_fatal(void); extern int *uu_exit_usage(void); -/* - * Debug print facility functions. - */ -typedef struct uu_dprintf uu_dprintf_t; - -typedef enum { - UU_DPRINTF_SILENT, - UU_DPRINTF_FATAL, - UU_DPRINTF_WARNING, - UU_DPRINTF_NOTICE, - UU_DPRINTF_INFO, - UU_DPRINTF_DEBUG -} uu_dprintf_severity_t; - -extern uu_dprintf_t *uu_dprintf_create(const char *, uu_dprintf_severity_t, - uint_t); -/*PRINTFLIKE3*/ -extern void uu_dprintf(uu_dprintf_t *, uu_dprintf_severity_t, - const char *, ...); -extern void uu_dprintf_destroy(uu_dprintf_t *); -extern const char *uu_dprintf_getname(uu_dprintf_t *); - /* * Identifier test flags and function. */ @@ -128,11 +106,6 @@ extern const char *uu_dprintf_getname(uu_dprintf_t *); int uu_check_name(const char *, uint_t); -/* - * File creation functions. - */ -extern int uu_open_tmp(const char *dir, uint_t uflags); - /* * Convenience functions. */ @@ -149,7 +122,6 @@ extern boolean_t uu_streq(const char *a, const char *b); extern char *uu_strndup(const char *s, size_t n); extern boolean_t uu_strbw(const char *a, const char *b); extern void *uu_memdup(const void *buf, size_t sz); -extern void uu_dump(FILE *out, const char *prefix, const void *buf, size_t len); /* * Comparison function type definition. diff --git a/sys/contrib/openzfs/include/libuutil_impl.h b/sys/contrib/openzfs/include/libuutil_impl.h index f978b475eff..50d8e012d5f 100644 --- a/sys/contrib/openzfs/include/libuutil_impl.h +++ b/sys/contrib/openzfs/include/libuutil_impl.h @@ -46,12 +46,6 @@ void uu_set_error(uint_t); void uu_panic(const char *format, ...); -struct uu_dprintf { - char *uud_name; - uu_dprintf_severity_t uud_severity; - uint_t uud_flags; -}; - /* * For debugging purposes, libuutil keeps around linked lists of all uu_lists * and uu_avls, along with pointers to their parents. These can cause false diff --git a/sys/contrib/openzfs/include/libzfs.h b/sys/contrib/openzfs/include/libzfs.h index 5f0bc03be14..9ef280636d4 100644 --- a/sys/contrib/openzfs/include/libzfs.h +++ b/sys/contrib/openzfs/include/libzfs.h @@ -32,7 +32,7 @@ */ #ifndef _LIBZFS_H -#define _LIBZFS_H +#define _LIBZFS_H extern __attribute__((visibility("default"))) #include #include @@ -196,64 +196,64 @@ typedef struct zfs_handle zfs_handle_t; typedef struct zpool_handle zpool_handle_t; typedef struct libzfs_handle libzfs_handle_t; -extern int zpool_wait(zpool_handle_t *, zpool_wait_activity_t); -extern int zpool_wait_status(zpool_handle_t *, zpool_wait_activity_t, +_LIBZFS_H int zpool_wait(zpool_handle_t *, zpool_wait_activity_t); +_LIBZFS_H int zpool_wait_status(zpool_handle_t *, zpool_wait_activity_t, boolean_t *, boolean_t *); /* * Library initialization */ -extern libzfs_handle_t *libzfs_init(void); -extern void libzfs_fini(libzfs_handle_t *); +_LIBZFS_H libzfs_handle_t *libzfs_init(void); +_LIBZFS_H void libzfs_fini(libzfs_handle_t *); -extern libzfs_handle_t *zpool_get_handle(zpool_handle_t *); -extern libzfs_handle_t *zfs_get_handle(zfs_handle_t *); +_LIBZFS_H libzfs_handle_t *zpool_get_handle(zpool_handle_t *); +_LIBZFS_H libzfs_handle_t *zfs_get_handle(zfs_handle_t *); -extern void libzfs_print_on_error(libzfs_handle_t *, boolean_t); +_LIBZFS_H void libzfs_print_on_error(libzfs_handle_t *, boolean_t); -extern void zfs_save_arguments(int argc, char **, char *, int); -extern int zpool_log_history(libzfs_handle_t *, const char *); +_LIBZFS_H void zfs_save_arguments(int argc, char **, char *, int); +_LIBZFS_H int zpool_log_history(libzfs_handle_t *, const char *); -extern int libzfs_errno(libzfs_handle_t *); -extern const char *libzfs_error_init(int); -extern const char *libzfs_error_action(libzfs_handle_t *); -extern const char *libzfs_error_description(libzfs_handle_t *); -extern int zfs_standard_error(libzfs_handle_t *, int, const char *); -extern void libzfs_mnttab_init(libzfs_handle_t *); -extern void libzfs_mnttab_fini(libzfs_handle_t *); -extern void libzfs_mnttab_cache(libzfs_handle_t *, boolean_t); -extern int libzfs_mnttab_find(libzfs_handle_t *, const char *, +_LIBZFS_H int libzfs_errno(libzfs_handle_t *); +_LIBZFS_H const char *libzfs_error_init(int); +_LIBZFS_H const char *libzfs_error_action(libzfs_handle_t *); +_LIBZFS_H const char *libzfs_error_description(libzfs_handle_t *); +_LIBZFS_H int zfs_standard_error(libzfs_handle_t *, int, const char *); +_LIBZFS_H void libzfs_mnttab_init(libzfs_handle_t *); +_LIBZFS_H void libzfs_mnttab_fini(libzfs_handle_t *); +_LIBZFS_H void libzfs_mnttab_cache(libzfs_handle_t *, boolean_t); +_LIBZFS_H int libzfs_mnttab_find(libzfs_handle_t *, const char *, struct mnttab *); -extern void libzfs_mnttab_add(libzfs_handle_t *, const char *, +_LIBZFS_H void libzfs_mnttab_add(libzfs_handle_t *, const char *, const char *, const char *); -extern void libzfs_mnttab_remove(libzfs_handle_t *, const char *); +_LIBZFS_H void libzfs_mnttab_remove(libzfs_handle_t *, const char *); /* * Basic handle functions */ -extern zpool_handle_t *zpool_open(libzfs_handle_t *, const char *); -extern zpool_handle_t *zpool_open_canfail(libzfs_handle_t *, const char *); -extern void zpool_close(zpool_handle_t *); -extern const char *zpool_get_name(zpool_handle_t *); -extern int zpool_get_state(zpool_handle_t *); -extern const char *zpool_state_to_name(vdev_state_t, vdev_aux_t); -extern const char *zpool_pool_state_to_name(pool_state_t); -extern void zpool_free_handles(libzfs_handle_t *); +_LIBZFS_H zpool_handle_t *zpool_open(libzfs_handle_t *, const char *); +_LIBZFS_H zpool_handle_t *zpool_open_canfail(libzfs_handle_t *, const char *); +_LIBZFS_H void zpool_close(zpool_handle_t *); +_LIBZFS_H const char *zpool_get_name(zpool_handle_t *); +_LIBZFS_H int zpool_get_state(zpool_handle_t *); +_LIBZFS_H const char *zpool_state_to_name(vdev_state_t, vdev_aux_t); +_LIBZFS_H const char *zpool_pool_state_to_name(pool_state_t); +_LIBZFS_H void zpool_free_handles(libzfs_handle_t *); /* * Iterate over all active pools in the system. */ typedef int (*zpool_iter_f)(zpool_handle_t *, void *); -extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *); -extern boolean_t zpool_skip_pool(const char *); +_LIBZFS_H int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *); +_LIBZFS_H boolean_t zpool_skip_pool(const char *); /* * Functions to create and destroy pools */ -extern int zpool_create(libzfs_handle_t *, const char *, nvlist_t *, +_LIBZFS_H int zpool_create(libzfs_handle_t *, const char *, nvlist_t *, nvlist_t *, nvlist_t *); -extern int zpool_destroy(zpool_handle_t *, const char *); -extern int zpool_add(zpool_handle_t *, nvlist_t *); +_LIBZFS_H int zpool_destroy(zpool_handle_t *, const char *); +_LIBZFS_H int zpool_add(zpool_handle_t *, nvlist_t *); typedef struct splitflags { /* do not split, but return the config that would be split off */ @@ -281,57 +281,60 @@ typedef struct trimflags { /* * Functions to manipulate pool and vdev state */ -extern int zpool_scan(zpool_handle_t *, pool_scan_func_t, pool_scrub_cmd_t); -extern int zpool_initialize(zpool_handle_t *, pool_initialize_func_t, +_LIBZFS_H int zpool_scan(zpool_handle_t *, pool_scan_func_t, pool_scrub_cmd_t); +_LIBZFS_H int zpool_initialize(zpool_handle_t *, pool_initialize_func_t, nvlist_t *); -extern int zpool_initialize_wait(zpool_handle_t *, pool_initialize_func_t, +_LIBZFS_H int zpool_initialize_wait(zpool_handle_t *, pool_initialize_func_t, nvlist_t *); -extern int zpool_trim(zpool_handle_t *, pool_trim_func_t, nvlist_t *, +_LIBZFS_H int zpool_trim(zpool_handle_t *, pool_trim_func_t, nvlist_t *, trimflags_t *); -extern int zpool_clear(zpool_handle_t *, const char *, nvlist_t *); -extern int zpool_reguid(zpool_handle_t *); -extern int zpool_reopen_one(zpool_handle_t *, void *); +_LIBZFS_H int zpool_clear(zpool_handle_t *, const char *, nvlist_t *); +_LIBZFS_H int zpool_reguid(zpool_handle_t *); +_LIBZFS_H int zpool_reopen_one(zpool_handle_t *, void *); -extern int zpool_sync_one(zpool_handle_t *, void *); +_LIBZFS_H int zpool_sync_one(zpool_handle_t *, void *); -extern int zpool_vdev_online(zpool_handle_t *, const char *, int, +_LIBZFS_H int zpool_vdev_online(zpool_handle_t *, const char *, int, vdev_state_t *); -extern int zpool_vdev_offline(zpool_handle_t *, const char *, boolean_t); -extern int zpool_vdev_attach(zpool_handle_t *, const char *, +_LIBZFS_H int zpool_vdev_offline(zpool_handle_t *, const char *, boolean_t); +_LIBZFS_H int zpool_vdev_attach(zpool_handle_t *, const char *, const char *, nvlist_t *, int, boolean_t); -extern int zpool_vdev_detach(zpool_handle_t *, const char *); -extern int zpool_vdev_remove(zpool_handle_t *, const char *); -extern int zpool_vdev_remove_cancel(zpool_handle_t *); -extern int zpool_vdev_indirect_size(zpool_handle_t *, const char *, uint64_t *); -extern int zpool_vdev_split(zpool_handle_t *, char *, nvlist_t **, nvlist_t *, - splitflags_t); +_LIBZFS_H int zpool_vdev_detach(zpool_handle_t *, const char *); +_LIBZFS_H int zpool_vdev_remove(zpool_handle_t *, const char *); +_LIBZFS_H int zpool_vdev_remove_cancel(zpool_handle_t *); +_LIBZFS_H int zpool_vdev_indirect_size(zpool_handle_t *, const char *, + uint64_t *); +_LIBZFS_H int zpool_vdev_split(zpool_handle_t *, char *, nvlist_t **, + nvlist_t *, splitflags_t); -extern int zpool_vdev_fault(zpool_handle_t *, uint64_t, vdev_aux_t); -extern int zpool_vdev_degrade(zpool_handle_t *, uint64_t, vdev_aux_t); -extern int zpool_vdev_clear(zpool_handle_t *, uint64_t); +_LIBZFS_H int zpool_vdev_fault(zpool_handle_t *, uint64_t, vdev_aux_t); +_LIBZFS_H int zpool_vdev_degrade(zpool_handle_t *, uint64_t, vdev_aux_t); +_LIBZFS_H int zpool_vdev_clear(zpool_handle_t *, uint64_t); -extern nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *, +_LIBZFS_H nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *, boolean_t *, boolean_t *); -extern nvlist_t *zpool_find_vdev_by_physpath(zpool_handle_t *, const char *, +_LIBZFS_H nvlist_t *zpool_find_vdev_by_physpath(zpool_handle_t *, const char *, boolean_t *, boolean_t *, boolean_t *); -extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, const char *); -extern uint64_t zpool_vdev_path_to_guid(zpool_handle_t *zhp, const char *path); +_LIBZFS_H int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, + const char *); +_LIBZFS_H uint64_t zpool_vdev_path_to_guid(zpool_handle_t *zhp, + const char *path); -const char *zpool_get_state_str(zpool_handle_t *); +_LIBZFS_H const char *zpool_get_state_str(zpool_handle_t *); /* * Functions to manage pool properties */ -extern int zpool_set_prop(zpool_handle_t *, const char *, const char *); -extern int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *, +_LIBZFS_H int zpool_set_prop(zpool_handle_t *, const char *, const char *); +_LIBZFS_H int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *, size_t proplen, zprop_source_t *, boolean_t literal); -extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t, +_LIBZFS_H uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t, zprop_source_t *); -extern int zpool_props_refresh(zpool_handle_t *); +_LIBZFS_H int zpool_props_refresh(zpool_handle_t *); -extern const char *zpool_prop_to_name(zpool_prop_t); -extern const char *zpool_prop_values(zpool_prop_t); +_LIBZFS_H const char *zpool_prop_to_name(zpool_prop_t); +_LIBZFS_H const char *zpool_prop_values(zpool_prop_t); /* * Pool health statistics. @@ -393,6 +396,7 @@ typedef enum { ZPOOL_STATUS_REBUILD_SCRUB, /* recommend scrubbing the pool */ ZPOOL_STATUS_NON_NATIVE_ASHIFT, /* (e.g. 512e dev with ashift of 9) */ ZPOOL_STATUS_COMPATIBILITY_ERR, /* bad 'compatibility' property */ + ZPOOL_STATUS_INCOMPATIBLE_FEAT, /* feature set outside compatibility */ /* * Finally, the following indicates a healthy pool. @@ -400,36 +404,36 @@ typedef enum { ZPOOL_STATUS_OK } zpool_status_t; -extern zpool_status_t zpool_get_status(zpool_handle_t *, char **, +_LIBZFS_H zpool_status_t zpool_get_status(zpool_handle_t *, char **, zpool_errata_t *); -extern zpool_status_t zpool_import_status(nvlist_t *, char **, +_LIBZFS_H zpool_status_t zpool_import_status(nvlist_t *, char **, zpool_errata_t *); /* * Statistics and configuration functions. */ -extern nvlist_t *zpool_get_config(zpool_handle_t *, nvlist_t **); -extern nvlist_t *zpool_get_features(zpool_handle_t *); -extern int zpool_refresh_stats(zpool_handle_t *, boolean_t *); -extern int zpool_get_errlog(zpool_handle_t *, nvlist_t **); +_LIBZFS_H nvlist_t *zpool_get_config(zpool_handle_t *, nvlist_t **); +_LIBZFS_H nvlist_t *zpool_get_features(zpool_handle_t *); +_LIBZFS_H int zpool_refresh_stats(zpool_handle_t *, boolean_t *); +_LIBZFS_H int zpool_get_errlog(zpool_handle_t *, nvlist_t **); /* * Import and export functions */ -extern int zpool_export(zpool_handle_t *, boolean_t, const char *); -extern int zpool_export_force(zpool_handle_t *, const char *); -extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *, +_LIBZFS_H int zpool_export(zpool_handle_t *, boolean_t, const char *); +_LIBZFS_H int zpool_export_force(zpool_handle_t *, const char *); +_LIBZFS_H int zpool_import(libzfs_handle_t *, nvlist_t *, const char *, char *altroot); -extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *, +_LIBZFS_H int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *, nvlist_t *, int); -extern void zpool_print_unsup_feat(nvlist_t *config); +_LIBZFS_H void zpool_print_unsup_feat(nvlist_t *config); /* * Miscellaneous pool functions */ struct zfs_cmd; -extern const char *zfs_history_event_names[]; +_LIBZFS_H const char *zfs_history_event_names[]; typedef enum { VDEV_NAME_PATH = 1 << 0, @@ -438,38 +442,39 @@ typedef enum { VDEV_NAME_TYPE_ID = 1 << 3, } vdev_name_t; -extern char *zpool_vdev_name(libzfs_handle_t *, zpool_handle_t *, nvlist_t *, +_LIBZFS_H char *zpool_vdev_name(libzfs_handle_t *, zpool_handle_t *, nvlist_t *, int name_flags); -extern int zpool_upgrade(zpool_handle_t *, uint64_t); -extern int zpool_get_history(zpool_handle_t *, nvlist_t **, uint64_t *, +_LIBZFS_H int zpool_upgrade(zpool_handle_t *, uint64_t); +_LIBZFS_H int zpool_get_history(zpool_handle_t *, nvlist_t **, uint64_t *, boolean_t *); -extern int zpool_events_next(libzfs_handle_t *, nvlist_t **, int *, unsigned, +_LIBZFS_H int zpool_events_next(libzfs_handle_t *, nvlist_t **, int *, unsigned, int); -extern int zpool_events_clear(libzfs_handle_t *, int *); -extern int zpool_events_seek(libzfs_handle_t *, uint64_t, int); -extern void zpool_obj_to_path_ds(zpool_handle_t *, uint64_t, uint64_t, char *, +_LIBZFS_H int zpool_events_clear(libzfs_handle_t *, int *); +_LIBZFS_H int zpool_events_seek(libzfs_handle_t *, uint64_t, int); +_LIBZFS_H void zpool_obj_to_path_ds(zpool_handle_t *, uint64_t, uint64_t, + char *, size_t); +_LIBZFS_H void zpool_obj_to_path(zpool_handle_t *, uint64_t, uint64_t, char *, size_t); -extern void zpool_obj_to_path(zpool_handle_t *, uint64_t, uint64_t, char *, - size_t); -extern int zfs_ioctl(libzfs_handle_t *, int, struct zfs_cmd *); -extern int zpool_get_physpath(zpool_handle_t *, char *, size_t); -extern void zpool_explain_recover(libzfs_handle_t *, const char *, int, +_LIBZFS_H int zfs_ioctl(libzfs_handle_t *, int, struct zfs_cmd *); +_LIBZFS_H int zpool_get_physpath(zpool_handle_t *, char *, size_t); +_LIBZFS_H void zpool_explain_recover(libzfs_handle_t *, const char *, int, nvlist_t *); -extern int zpool_checkpoint(zpool_handle_t *); -extern int zpool_discard_checkpoint(zpool_handle_t *); -extern boolean_t zpool_is_draid_spare(const char *); +_LIBZFS_H int zpool_checkpoint(zpool_handle_t *); +_LIBZFS_H int zpool_discard_checkpoint(zpool_handle_t *); +_LIBZFS_H boolean_t zpool_is_draid_spare(const char *); /* * Basic handle manipulations. These functions do not create or destroy the * underlying datasets, only the references to them. */ -extern zfs_handle_t *zfs_open(libzfs_handle_t *, const char *, int); -extern zfs_handle_t *zfs_handle_dup(zfs_handle_t *); -extern void zfs_close(zfs_handle_t *); -extern zfs_type_t zfs_get_type(const zfs_handle_t *); -extern const char *zfs_get_name(const zfs_handle_t *); -extern zpool_handle_t *zfs_get_pool_handle(const zfs_handle_t *); -extern const char *zfs_get_pool_name(const zfs_handle_t *); +_LIBZFS_H zfs_handle_t *zfs_open(libzfs_handle_t *, const char *, int); +_LIBZFS_H zfs_handle_t *zfs_handle_dup(zfs_handle_t *); +_LIBZFS_H void zfs_close(zfs_handle_t *); +_LIBZFS_H zfs_type_t zfs_get_type(const zfs_handle_t *); +_LIBZFS_H zfs_type_t zfs_get_underlying_type(const zfs_handle_t *); +_LIBZFS_H const char *zfs_get_name(const zfs_handle_t *); +_LIBZFS_H zpool_handle_t *zfs_get_pool_handle(const zfs_handle_t *); +_LIBZFS_H const char *zfs_get_pool_name(const zfs_handle_t *); /* * Property management functions. Some functions are shared with the kernel, @@ -479,58 +484,60 @@ extern const char *zfs_get_pool_name(const zfs_handle_t *); /* * zfs dataset property management */ -extern const char *zfs_prop_default_string(zfs_prop_t); -extern uint64_t zfs_prop_default_numeric(zfs_prop_t); -extern const char *zfs_prop_column_name(zfs_prop_t); -extern boolean_t zfs_prop_align_right(zfs_prop_t); +_LIBZFS_H const char *zfs_prop_default_string(zfs_prop_t); +_LIBZFS_H uint64_t zfs_prop_default_numeric(zfs_prop_t); +_LIBZFS_H const char *zfs_prop_column_name(zfs_prop_t); +_LIBZFS_H boolean_t zfs_prop_align_right(zfs_prop_t); -extern nvlist_t *zfs_valid_proplist(libzfs_handle_t *, zfs_type_t, nvlist_t *, - uint64_t, zfs_handle_t *, zpool_handle_t *, boolean_t, const char *); +_LIBZFS_H nvlist_t *zfs_valid_proplist(libzfs_handle_t *, zfs_type_t, + nvlist_t *, uint64_t, zfs_handle_t *, zpool_handle_t *, boolean_t, + const char *); -extern const char *zfs_prop_to_name(zfs_prop_t); -extern int zfs_prop_set(zfs_handle_t *, const char *, const char *); -extern int zfs_prop_set_list(zfs_handle_t *, nvlist_t *); -extern int zfs_prop_get(zfs_handle_t *, zfs_prop_t, char *, size_t, +_LIBZFS_H const char *zfs_prop_to_name(zfs_prop_t); +_LIBZFS_H int zfs_prop_set(zfs_handle_t *, const char *, const char *); +_LIBZFS_H int zfs_prop_set_list(zfs_handle_t *, nvlist_t *); +_LIBZFS_H int zfs_prop_get(zfs_handle_t *, zfs_prop_t, char *, size_t, zprop_source_t *, char *, size_t, boolean_t); -extern int zfs_prop_get_recvd(zfs_handle_t *, const char *, char *, size_t, +_LIBZFS_H int zfs_prop_get_recvd(zfs_handle_t *, const char *, char *, size_t, boolean_t); -extern int zfs_prop_get_numeric(zfs_handle_t *, zfs_prop_t, uint64_t *, +_LIBZFS_H int zfs_prop_get_numeric(zfs_handle_t *, zfs_prop_t, uint64_t *, zprop_source_t *, char *, size_t); -extern int zfs_prop_get_userquota_int(zfs_handle_t *zhp, const char *propname, - uint64_t *propvalue); -extern int zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname, +_LIBZFS_H int zfs_prop_get_userquota_int(zfs_handle_t *zhp, + const char *propname, uint64_t *propvalue); +_LIBZFS_H int zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname, char *propbuf, int proplen, boolean_t literal); -extern int zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname, +_LIBZFS_H int zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname, uint64_t *propvalue); -extern int zfs_prop_get_written(zfs_handle_t *zhp, const char *propname, +_LIBZFS_H int zfs_prop_get_written(zfs_handle_t *zhp, const char *propname, char *propbuf, int proplen, boolean_t literal); -extern int zfs_prop_get_feature(zfs_handle_t *zhp, const char *propname, +_LIBZFS_H int zfs_prop_get_feature(zfs_handle_t *zhp, const char *propname, char *buf, size_t len); -extern uint64_t getprop_uint64(zfs_handle_t *, zfs_prop_t, char **); -extern uint64_t zfs_prop_get_int(zfs_handle_t *, zfs_prop_t); -extern int zfs_prop_inherit(zfs_handle_t *, const char *, boolean_t); -extern const char *zfs_prop_values(zfs_prop_t); -extern int zfs_prop_is_string(zfs_prop_t prop); -extern nvlist_t *zfs_get_all_props(zfs_handle_t *); -extern nvlist_t *zfs_get_user_props(zfs_handle_t *); -extern nvlist_t *zfs_get_recvd_props(zfs_handle_t *); -extern nvlist_t *zfs_get_clones_nvl(zfs_handle_t *); +_LIBZFS_H uint64_t getprop_uint64(zfs_handle_t *, zfs_prop_t, char **); +_LIBZFS_H uint64_t zfs_prop_get_int(zfs_handle_t *, zfs_prop_t); +_LIBZFS_H int zfs_prop_inherit(zfs_handle_t *, const char *, boolean_t); +_LIBZFS_H const char *zfs_prop_values(zfs_prop_t); +_LIBZFS_H int zfs_prop_is_string(zfs_prop_t prop); +_LIBZFS_H nvlist_t *zfs_get_all_props(zfs_handle_t *); +_LIBZFS_H nvlist_t *zfs_get_user_props(zfs_handle_t *); +_LIBZFS_H nvlist_t *zfs_get_recvd_props(zfs_handle_t *); +_LIBZFS_H nvlist_t *zfs_get_clones_nvl(zfs_handle_t *); -extern int zfs_wait_status(zfs_handle_t *, zfs_wait_activity_t, +_LIBZFS_H int zfs_wait_status(zfs_handle_t *, zfs_wait_activity_t, boolean_t *, boolean_t *); /* * zfs encryption management */ -extern int zfs_crypto_get_encryption_root(zfs_handle_t *, boolean_t *, char *); -extern int zfs_crypto_create(libzfs_handle_t *, char *, nvlist_t *, nvlist_t *, - boolean_t stdin_available, uint8_t **, uint_t *); -extern int zfs_crypto_clone_check(libzfs_handle_t *, zfs_handle_t *, char *, +_LIBZFS_H int zfs_crypto_get_encryption_root(zfs_handle_t *, boolean_t *, + char *); +_LIBZFS_H int zfs_crypto_create(libzfs_handle_t *, char *, nvlist_t *, + nvlist_t *, boolean_t stdin_available, uint8_t **, uint_t *); +_LIBZFS_H int zfs_crypto_clone_check(libzfs_handle_t *, zfs_handle_t *, char *, nvlist_t *); -extern int zfs_crypto_attempt_load_keys(libzfs_handle_t *, char *); -extern int zfs_crypto_load_key(zfs_handle_t *, boolean_t, char *); -extern int zfs_crypto_unload_key(zfs_handle_t *); -extern int zfs_crypto_rewrap(zfs_handle_t *, nvlist_t *, boolean_t); +_LIBZFS_H int zfs_crypto_attempt_load_keys(libzfs_handle_t *, char *); +_LIBZFS_H int zfs_crypto_load_key(zfs_handle_t *, boolean_t, char *); +_LIBZFS_H int zfs_crypto_unload_key(zfs_handle_t *); +_LIBZFS_H int zfs_crypto_rewrap(zfs_handle_t *, nvlist_t *, boolean_t); typedef struct zprop_list { int pl_prop; @@ -542,9 +549,9 @@ typedef struct zprop_list { boolean_t pl_fixed; } zprop_list_t; -extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **, boolean_t, +_LIBZFS_H int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **, boolean_t, boolean_t); -extern void zfs_prune_proplist(zfs_handle_t *, uint8_t *); +_LIBZFS_H void zfs_prune_proplist(zfs_handle_t *, uint8_t *); #define ZFS_MOUNTPOINT_NONE "none" #define ZFS_MOUNTPOINT_LEGACY "legacy" @@ -559,22 +566,23 @@ extern void zfs_prune_proplist(zfs_handle_t *, uint8_t *); /* * zpool property management */ -extern int zpool_expand_proplist(zpool_handle_t *, zprop_list_t **, boolean_t); -extern int zpool_prop_get_feature(zpool_handle_t *, const char *, char *, +_LIBZFS_H int zpool_expand_proplist(zpool_handle_t *, zprop_list_t **, + boolean_t); +_LIBZFS_H int zpool_prop_get_feature(zpool_handle_t *, const char *, char *, size_t); -extern const char *zpool_prop_default_string(zpool_prop_t); -extern uint64_t zpool_prop_default_numeric(zpool_prop_t); -extern const char *zpool_prop_column_name(zpool_prop_t); -extern boolean_t zpool_prop_align_right(zpool_prop_t); +_LIBZFS_H const char *zpool_prop_default_string(zpool_prop_t); +_LIBZFS_H uint64_t zpool_prop_default_numeric(zpool_prop_t); +_LIBZFS_H const char *zpool_prop_column_name(zpool_prop_t); +_LIBZFS_H boolean_t zpool_prop_align_right(zpool_prop_t); /* * Functions shared by zfs and zpool property management. */ -extern int zprop_iter(zprop_func func, void *cb, boolean_t show_all, +_LIBZFS_H int zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered, zfs_type_t type); -extern int zprop_get_list(libzfs_handle_t *, char *, zprop_list_t **, +_LIBZFS_H int zprop_get_list(libzfs_handle_t *, char *, zprop_list_t **, zfs_type_t); -extern void zprop_free_list(zprop_list_t *); +_LIBZFS_H void zprop_free_list(zprop_list_t *); #define ZFS_GET_NCOLS 5 @@ -601,7 +609,7 @@ typedef struct zprop_get_cbdata { zfs_type_t cb_type; } zprop_get_cbdata_t; -void zprop_print_one_property(const char *, zprop_get_cbdata_t *, +_LIBZFS_H void zprop_print_one_property(const char *, zprop_get_cbdata_t *, const char *, const char *, zprop_source_t, const char *, const char *); @@ -609,17 +617,19 @@ void zprop_print_one_property(const char *, zprop_get_cbdata_t *, * Iterator functions. */ typedef int (*zfs_iter_f)(zfs_handle_t *, void *); -extern int zfs_iter_root(libzfs_handle_t *, zfs_iter_f, void *); -extern int zfs_iter_children(zfs_handle_t *, zfs_iter_f, void *); -extern int zfs_iter_dependents(zfs_handle_t *, boolean_t, zfs_iter_f, void *); -extern int zfs_iter_filesystems(zfs_handle_t *, zfs_iter_f, void *); -extern int zfs_iter_snapshots(zfs_handle_t *, boolean_t, zfs_iter_f, void *, +_LIBZFS_H int zfs_iter_root(libzfs_handle_t *, zfs_iter_f, void *); +_LIBZFS_H int zfs_iter_children(zfs_handle_t *, zfs_iter_f, void *); +_LIBZFS_H int zfs_iter_dependents(zfs_handle_t *, boolean_t, zfs_iter_f, + void *); +_LIBZFS_H int zfs_iter_filesystems(zfs_handle_t *, zfs_iter_f, void *); +_LIBZFS_H int zfs_iter_snapshots(zfs_handle_t *, boolean_t, zfs_iter_f, void *, uint64_t, uint64_t); -extern int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *, +_LIBZFS_H int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *, uint64_t, uint64_t); -extern int zfs_iter_snapspec(zfs_handle_t *, const char *, zfs_iter_f, void *); -extern int zfs_iter_bookmarks(zfs_handle_t *, zfs_iter_f, void *); -extern int zfs_iter_mounted(zfs_handle_t *, zfs_iter_f, void *); +_LIBZFS_H int zfs_iter_snapspec(zfs_handle_t *, const char *, zfs_iter_f, + void *); +_LIBZFS_H int zfs_iter_bookmarks(zfs_handle_t *, zfs_iter_f, void *); +_LIBZFS_H int zfs_iter_mounted(zfs_handle_t *, zfs_iter_f, void *); typedef struct get_all_cb { zfs_handle_t **cb_handles; @@ -627,24 +637,25 @@ typedef struct get_all_cb { size_t cb_used; } get_all_cb_t; -void zfs_foreach_mountpoint(libzfs_handle_t *, zfs_handle_t **, size_t, - zfs_iter_f, void *, boolean_t); -void libzfs_add_handle(get_all_cb_t *, zfs_handle_t *); +_LIBZFS_H void zfs_foreach_mountpoint(libzfs_handle_t *, zfs_handle_t **, + size_t, zfs_iter_f, void *, boolean_t); +_LIBZFS_H void libzfs_add_handle(get_all_cb_t *, zfs_handle_t *); /* * Functions to create and destroy datasets. */ -extern int zfs_create(libzfs_handle_t *, const char *, zfs_type_t, +_LIBZFS_H int zfs_create(libzfs_handle_t *, const char *, zfs_type_t, nvlist_t *); -extern int zfs_create_ancestors(libzfs_handle_t *, const char *); -extern int zfs_destroy(zfs_handle_t *, boolean_t); -extern int zfs_destroy_snaps(zfs_handle_t *, char *, boolean_t); -extern int zfs_destroy_snaps_nvl(libzfs_handle_t *, nvlist_t *, boolean_t); -extern int zfs_clone(zfs_handle_t *, const char *, nvlist_t *); -extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, nvlist_t *); -extern int zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, +_LIBZFS_H int zfs_create_ancestors(libzfs_handle_t *, const char *); +_LIBZFS_H int zfs_destroy(zfs_handle_t *, boolean_t); +_LIBZFS_H int zfs_destroy_snaps(zfs_handle_t *, char *, boolean_t); +_LIBZFS_H int zfs_destroy_snaps_nvl(libzfs_handle_t *, nvlist_t *, boolean_t); +_LIBZFS_H int zfs_clone(zfs_handle_t *, const char *, nvlist_t *); +_LIBZFS_H int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, + nvlist_t *); +_LIBZFS_H int zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props); -extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, boolean_t); +_LIBZFS_H int zfs_rollback(zfs_handle_t *, zfs_handle_t *, boolean_t); typedef struct renameflags { /* recursive rename */ @@ -657,7 +668,7 @@ typedef struct renameflags { int forceunmount : 1; } renameflags_t; -extern int zfs_rename(zfs_handle_t *, const char *, renameflags_t); +_LIBZFS_H int zfs_rename(zfs_handle_t *, const char *, renameflags_t); typedef struct sendflags { /* Amount of extra information to print. */ @@ -666,6 +677,9 @@ typedef struct sendflags { /* recursive send (ie, -R) */ boolean_t replicate; + /* for recursive send, skip sending missing snapshots */ + boolean_t skipmissing; + /* for incrementals, do all intermediate snapshots */ boolean_t doall; @@ -711,34 +725,35 @@ typedef struct sendflags { typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *); -extern int zfs_send(zfs_handle_t *, const char *, const char *, +_LIBZFS_H int zfs_send(zfs_handle_t *, const char *, const char *, sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **); -extern int zfs_send_one(zfs_handle_t *, const char *, int, sendflags_t *, +_LIBZFS_H int zfs_send_one(zfs_handle_t *, const char *, int, sendflags_t *, const char *); -extern int zfs_send_progress(zfs_handle_t *, int, uint64_t *, uint64_t *); -extern int zfs_send_resume(libzfs_handle_t *, sendflags_t *, int outfd, +_LIBZFS_H int zfs_send_progress(zfs_handle_t *, int, uint64_t *, uint64_t *); +_LIBZFS_H int zfs_send_resume(libzfs_handle_t *, sendflags_t *, int outfd, const char *); -extern int zfs_send_saved(zfs_handle_t *, sendflags_t *, int, const char *); -extern nvlist_t *zfs_send_resume_token_to_nvlist(libzfs_handle_t *hdl, +_LIBZFS_H int zfs_send_saved(zfs_handle_t *, sendflags_t *, int, const char *); +_LIBZFS_H nvlist_t *zfs_send_resume_token_to_nvlist(libzfs_handle_t *hdl, const char *token); -extern int zfs_promote(zfs_handle_t *); -extern int zfs_hold(zfs_handle_t *, const char *, const char *, +_LIBZFS_H int zfs_promote(zfs_handle_t *); +_LIBZFS_H int zfs_hold(zfs_handle_t *, const char *, const char *, boolean_t, int); -extern int zfs_hold_nvl(zfs_handle_t *, int, nvlist_t *); -extern int zfs_release(zfs_handle_t *, const char *, const char *, boolean_t); -extern int zfs_get_holds(zfs_handle_t *, nvlist_t **); -extern uint64_t zvol_volsize_to_reservation(zpool_handle_t *, uint64_t, +_LIBZFS_H int zfs_hold_nvl(zfs_handle_t *, int, nvlist_t *); +_LIBZFS_H int zfs_release(zfs_handle_t *, const char *, const char *, + boolean_t); +_LIBZFS_H int zfs_get_holds(zfs_handle_t *, nvlist_t **); +_LIBZFS_H uint64_t zvol_volsize_to_reservation(zpool_handle_t *, uint64_t, nvlist_t *); typedef int (*zfs_userspace_cb_t)(void *arg, const char *domain, uid_t rid, uint64_t space); -extern int zfs_userspace(zfs_handle_t *, zfs_userquota_prop_t, +_LIBZFS_H int zfs_userspace(zfs_handle_t *, zfs_userquota_prop_t, zfs_userspace_cb_t, void *); -extern int zfs_get_fsacl(zfs_handle_t *, nvlist_t **); -extern int zfs_set_fsacl(zfs_handle_t *, boolean_t, nvlist_t *); +_LIBZFS_H int zfs_get_fsacl(zfs_handle_t *, nvlist_t **); +_LIBZFS_H int zfs_set_fsacl(zfs_handle_t *, boolean_t, nvlist_t *); typedef struct recvflags { /* print informational messages (ie, -v was specified) */ @@ -787,7 +802,7 @@ typedef struct recvflags { boolean_t forceunmount; } recvflags_t; -extern int zfs_receive(libzfs_handle_t *, const char *, nvlist_t *, +_LIBZFS_H int zfs_receive(libzfs_handle_t *, const char *, nvlist_t *, recvflags_t *, int, avl_tree_t *); typedef enum diff_flags { @@ -796,70 +811,71 @@ typedef enum diff_flags { ZFS_DIFF_CLASSIFY = 0x4 } diff_flags_t; -extern int zfs_show_diffs(zfs_handle_t *, int, const char *, const char *, +_LIBZFS_H int zfs_show_diffs(zfs_handle_t *, int, const char *, const char *, int); /* * Miscellaneous functions. */ -extern const char *zfs_type_to_name(zfs_type_t); -extern void zfs_refresh_properties(zfs_handle_t *); -extern int zfs_name_valid(const char *, zfs_type_t); -extern zfs_handle_t *zfs_path_to_zhandle(libzfs_handle_t *, const char *, +_LIBZFS_H const char *zfs_type_to_name(zfs_type_t); +_LIBZFS_H void zfs_refresh_properties(zfs_handle_t *); +_LIBZFS_H int zfs_name_valid(const char *, zfs_type_t); +_LIBZFS_H zfs_handle_t *zfs_path_to_zhandle(libzfs_handle_t *, const char *, zfs_type_t); -extern int zfs_parent_name(zfs_handle_t *, char *, size_t); -extern boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *, +_LIBZFS_H int zfs_parent_name(zfs_handle_t *, char *, size_t); +_LIBZFS_H boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *, zfs_type_t); -extern int zfs_spa_version(zfs_handle_t *, int *); -extern boolean_t zfs_bookmark_exists(const char *path); +_LIBZFS_H int zfs_spa_version(zfs_handle_t *, int *); +_LIBZFS_H boolean_t zfs_bookmark_exists(const char *path); /* * Mount support functions. */ -extern boolean_t is_mounted(libzfs_handle_t *, const char *special, char **); -extern boolean_t zfs_is_mounted(zfs_handle_t *, char **); -extern int zfs_mount(zfs_handle_t *, const char *, int); -extern int zfs_mount_at(zfs_handle_t *, const char *, int, const char *); -extern int zfs_unmount(zfs_handle_t *, const char *, int); -extern int zfs_unmountall(zfs_handle_t *, int); +_LIBZFS_H boolean_t is_mounted(libzfs_handle_t *, const char *special, char **); +_LIBZFS_H boolean_t zfs_is_mounted(zfs_handle_t *, char **); +_LIBZFS_H int zfs_mount(zfs_handle_t *, const char *, int); +_LIBZFS_H int zfs_mount_at(zfs_handle_t *, const char *, int, const char *); +_LIBZFS_H int zfs_unmount(zfs_handle_t *, const char *, int); +_LIBZFS_H int zfs_unmountall(zfs_handle_t *, int); +_LIBZFS_H int zfs_mount_delegation_check(void); #if defined(__linux__) -extern int zfs_parse_mount_options(char *mntopts, unsigned long *mntflags, +_LIBZFS_H int zfs_parse_mount_options(char *mntopts, unsigned long *mntflags, unsigned long *zfsflags, int sloppy, char *badopt, char *mtabopt); -extern void zfs_adjust_mount_options(zfs_handle_t *zhp, const char *mntpoint, +_LIBZFS_H void zfs_adjust_mount_options(zfs_handle_t *zhp, const char *mntpoint, char *mntopts, char *mtabopt); #endif /* * Share support functions. */ -extern boolean_t zfs_is_shared(zfs_handle_t *); -extern int zfs_share(zfs_handle_t *); -extern int zfs_unshare(zfs_handle_t *); +_LIBZFS_H boolean_t zfs_is_shared(zfs_handle_t *); +_LIBZFS_H int zfs_share(zfs_handle_t *); +_LIBZFS_H int zfs_unshare(zfs_handle_t *); /* * Protocol-specific share support functions. */ -extern boolean_t zfs_is_shared_nfs(zfs_handle_t *, char **); -extern boolean_t zfs_is_shared_smb(zfs_handle_t *, char **); -extern int zfs_share_nfs(zfs_handle_t *); -extern int zfs_share_smb(zfs_handle_t *); -extern int zfs_shareall(zfs_handle_t *); -extern int zfs_unshare_nfs(zfs_handle_t *, const char *); -extern int zfs_unshare_smb(zfs_handle_t *, const char *); -extern int zfs_unshareall_nfs(zfs_handle_t *); -extern int zfs_unshareall_smb(zfs_handle_t *); -extern int zfs_unshareall_bypath(zfs_handle_t *, const char *); -extern int zfs_unshareall_bytype(zfs_handle_t *, const char *, const char *); -extern int zfs_unshareall(zfs_handle_t *); -extern int zfs_deleg_share_nfs(libzfs_handle_t *, char *, char *, char *, +_LIBZFS_H boolean_t zfs_is_shared_nfs(zfs_handle_t *, char **); +_LIBZFS_H boolean_t zfs_is_shared_smb(zfs_handle_t *, char **); +_LIBZFS_H int zfs_share_nfs(zfs_handle_t *); +_LIBZFS_H int zfs_share_smb(zfs_handle_t *); +_LIBZFS_H int zfs_shareall(zfs_handle_t *); +_LIBZFS_H int zfs_unshare_nfs(zfs_handle_t *, const char *); +_LIBZFS_H int zfs_unshare_smb(zfs_handle_t *, const char *); +_LIBZFS_H int zfs_unshareall_nfs(zfs_handle_t *); +_LIBZFS_H int zfs_unshareall_smb(zfs_handle_t *); +_LIBZFS_H int zfs_unshareall_bypath(zfs_handle_t *, const char *); +_LIBZFS_H int zfs_unshareall_bytype(zfs_handle_t *, const char *, const char *); +_LIBZFS_H int zfs_unshareall(zfs_handle_t *); +_LIBZFS_H int zfs_deleg_share_nfs(libzfs_handle_t *, char *, char *, char *, void *, void *, int, zfs_share_op_t); -extern void zfs_commit_nfs_shares(void); -extern void zfs_commit_smb_shares(void); -extern void zfs_commit_all_shares(void); -extern void zfs_commit_shares(const char *); +_LIBZFS_H void zfs_commit_nfs_shares(void); +_LIBZFS_H void zfs_commit_smb_shares(void); +_LIBZFS_H void zfs_commit_all_shares(void); +_LIBZFS_H void zfs_commit_shares(const char *); -extern int zfs_nicestrtonum(libzfs_handle_t *, const char *, uint64_t *); +_LIBZFS_H int zfs_nicestrtonum(libzfs_handle_t *, const char *, uint64_t *); /* * Utility functions to run an external process. @@ -868,77 +884,79 @@ extern int zfs_nicestrtonum(libzfs_handle_t *, const char *, uint64_t *); #define STDERR_VERBOSE 0x02 #define NO_DEFAULT_PATH 0x04 /* Don't use $PATH to lookup the command */ -int libzfs_run_process(const char *, char **, int); -int libzfs_run_process_get_stdout(const char *, char *[], char *[], - char **[], int *); -int libzfs_run_process_get_stdout_nopath(const char *, char *[], char *[], +_LIBZFS_H int libzfs_run_process(const char *, char **, int); +_LIBZFS_H int libzfs_run_process_get_stdout(const char *, char *[], char *[], char **[], int *); +_LIBZFS_H int libzfs_run_process_get_stdout_nopath(const char *, char *[], + char *[], char **[], int *); -void libzfs_free_str_array(char **, int); +_LIBZFS_H void libzfs_free_str_array(char **, int); -int libzfs_envvar_is_set(char *); +_LIBZFS_H int libzfs_envvar_is_set(char *); /* * Utility functions for zfs version */ -extern void zfs_version_userland(char *, int); -extern int zfs_version_kernel(char *, int); -extern int zfs_version_print(void); +_LIBZFS_H void zfs_version_userland(char *, int); +_LIBZFS_H int zfs_version_kernel(char *, int); +_LIBZFS_H int zfs_version_print(void); /* * Given a device or file, determine if it is part of a pool. */ -extern int zpool_in_use(libzfs_handle_t *, int, pool_state_t *, char **, +_LIBZFS_H int zpool_in_use(libzfs_handle_t *, int, pool_state_t *, char **, boolean_t *); /* * Label manipulation. */ -extern int zpool_clear_label(int); -extern int zpool_set_bootenv(zpool_handle_t *, const nvlist_t *); -extern int zpool_get_bootenv(zpool_handle_t *, nvlist_t **); +_LIBZFS_H int zpool_clear_label(int); +_LIBZFS_H int zpool_set_bootenv(zpool_handle_t *, const nvlist_t *); +_LIBZFS_H int zpool_get_bootenv(zpool_handle_t *, nvlist_t **); /* * Management interfaces for SMB ACL files */ -int zfs_smb_acl_add(libzfs_handle_t *, char *, char *, char *); -int zfs_smb_acl_remove(libzfs_handle_t *, char *, char *, char *); -int zfs_smb_acl_purge(libzfs_handle_t *, char *, char *); -int zfs_smb_acl_rename(libzfs_handle_t *, char *, char *, char *, char *); +_LIBZFS_H int zfs_smb_acl_add(libzfs_handle_t *, char *, char *, char *); +_LIBZFS_H int zfs_smb_acl_remove(libzfs_handle_t *, char *, char *, char *); +_LIBZFS_H int zfs_smb_acl_purge(libzfs_handle_t *, char *, char *); +_LIBZFS_H int zfs_smb_acl_rename(libzfs_handle_t *, char *, char *, char *, + char *); /* * Enable and disable datasets within a pool by mounting/unmounting and * sharing/unsharing them. */ -extern int zpool_enable_datasets(zpool_handle_t *, const char *, int); -extern int zpool_disable_datasets(zpool_handle_t *, boolean_t); +_LIBZFS_H int zpool_enable_datasets(zpool_handle_t *, const char *, int); +_LIBZFS_H int zpool_disable_datasets(zpool_handle_t *, boolean_t); /* * Parse a features file for -o compatibility */ typedef enum { ZPOOL_COMPATIBILITY_OK, - ZPOOL_COMPATIBILITY_READERR, + ZPOOL_COMPATIBILITY_WARNTOKEN, + ZPOOL_COMPATIBILITY_BADTOKEN, ZPOOL_COMPATIBILITY_BADFILE, - ZPOOL_COMPATIBILITY_BADWORD, ZPOOL_COMPATIBILITY_NOFILES } zpool_compat_status_t; -extern zpool_compat_status_t zpool_load_compat(const char *, - boolean_t *, char *, char *); +_LIBZFS_H zpool_compat_status_t zpool_load_compat(const char *, + boolean_t *, char *, size_t); #ifdef __FreeBSD__ /* * Attach/detach the given filesystem to/from the given jail. */ -extern int zfs_jail(zfs_handle_t *zhp, int jailid, int attach); +_LIBZFS_H int zfs_jail(zfs_handle_t *zhp, int jailid, int attach); /* * Set loader options for next boot. */ -extern int zpool_nextboot(libzfs_handle_t *, uint64_t, uint64_t, const char *); +_LIBZFS_H int zpool_nextboot(libzfs_handle_t *, uint64_t, uint64_t, + const char *); #endif /* __FreeBSD__ */ diff --git a/sys/contrib/openzfs/include/libzutil.h b/sys/contrib/openzfs/include/libzutil.h index 82a80267890..5b092796180 100644 --- a/sys/contrib/openzfs/include/libzutil.h +++ b/sys/contrib/openzfs/include/libzutil.h @@ -24,7 +24,7 @@ */ #ifndef _LIBZUTIL_H -#define _LIBZUTIL_H +#define _LIBZUTIL_H extern __attribute__((visibility("default"))) #include #include @@ -56,8 +56,8 @@ typedef const struct pool_config_ops { /* * An instance of pool_config_ops_t is expected in the caller's binary. */ -extern const pool_config_ops_t libzfs_config_ops; -extern const pool_config_ops_t libzpool_config_ops; +_LIBZUTIL_H const pool_config_ops_t libzfs_config_ops; +_LIBZUTIL_H const pool_config_ops_t libzpool_config_ops; typedef struct importargs { char **path; /* a list of paths to search */ @@ -70,21 +70,21 @@ typedef struct importargs { nvlist_t *policy; /* load policy (max txg, rewind, etc.) */ } importargs_t; -extern nvlist_t *zpool_search_import(void *, importargs_t *, - const pool_config_ops_t *); -extern int zpool_find_config(void *, const char *, nvlist_t **, importargs_t *, +_LIBZUTIL_H nvlist_t *zpool_search_import(void *, importargs_t *, const pool_config_ops_t *); +_LIBZUTIL_H int zpool_find_config(void *, const char *, nvlist_t **, + importargs_t *, const pool_config_ops_t *); -extern const char * const * zpool_default_search_paths(size_t *count); -extern int zpool_read_label(int, nvlist_t **, int *); -extern int zpool_label_disk_wait(const char *, int); +_LIBZUTIL_H const char * const * zpool_default_search_paths(size_t *count); +_LIBZUTIL_H int zpool_read_label(int, nvlist_t **, int *); +_LIBZUTIL_H int zpool_label_disk_wait(const char *, int); struct udev_device; -extern int zfs_device_get_devid(struct udev_device *, char *, size_t); -extern int zfs_device_get_physical(struct udev_device *, char *, size_t); +_LIBZUTIL_H int zfs_device_get_devid(struct udev_device *, char *, size_t); +_LIBZUTIL_H int zfs_device_get_physical(struct udev_device *, char *, size_t); -extern void update_vdev_config_dev_strs(nvlist_t *); +_LIBZUTIL_H void update_vdev_config_dev_strs(nvlist_t *); /* * Default device paths @@ -93,23 +93,24 @@ extern void update_vdev_config_dev_strs(nvlist_t *); #define UDISK_ROOT "/dev/disk" #define ZVOL_ROOT "/dev/zvol" -extern int zfs_append_partition(char *path, size_t max_len); -extern int zfs_resolve_shortname(const char *name, char *path, size_t pathlen); +_LIBZUTIL_H int zfs_append_partition(char *path, size_t max_len); +_LIBZUTIL_H int zfs_resolve_shortname(const char *name, char *path, + size_t pathlen); -extern char *zfs_strip_partition(char *); -extern char *zfs_strip_path(char *); +_LIBZUTIL_H char *zfs_strip_partition(char *); +_LIBZUTIL_H char *zfs_strip_path(char *); -extern int zfs_strcmp_pathname(const char *, const char *, int); +_LIBZUTIL_H int zfs_strcmp_pathname(const char *, const char *, int); -extern boolean_t zfs_dev_is_dm(const char *); -extern boolean_t zfs_dev_is_whole_disk(const char *); -extern int zfs_dev_flush(int); -extern char *zfs_get_underlying_path(const char *); -extern char *zfs_get_enclosure_sysfs_path(const char *); +_LIBZUTIL_H boolean_t zfs_dev_is_dm(const char *); +_LIBZUTIL_H boolean_t zfs_dev_is_whole_disk(const char *); +_LIBZUTIL_H int zfs_dev_flush(int); +_LIBZUTIL_H char *zfs_get_underlying_path(const char *); +_LIBZUTIL_H char *zfs_get_enclosure_sysfs_path(const char *); -extern boolean_t is_mpath_whole_disk(const char *); +_LIBZUTIL_H boolean_t is_mpath_whole_disk(const char *); -extern boolean_t zfs_isnumber(const char *); +_LIBZUTIL_H boolean_t zfs_isnumber(const char *); /* * Formats for iostat numbers. Examples: "12K", "30ms", "4B", "2321234", "-". @@ -131,21 +132,21 @@ enum zfs_nicenum_format { /* * Convert a number to a human-readable form. */ -extern void zfs_nicebytes(uint64_t, char *, size_t); -extern void zfs_nicenum(uint64_t, char *, size_t); -extern void zfs_nicenum_format(uint64_t, char *, size_t, +_LIBZUTIL_H void zfs_nicebytes(uint64_t, char *, size_t); +_LIBZUTIL_H void zfs_nicenum(uint64_t, char *, size_t); +_LIBZUTIL_H void zfs_nicenum_format(uint64_t, char *, size_t, enum zfs_nicenum_format); -extern void zfs_nicetime(uint64_t, char *, size_t); -extern void zfs_niceraw(uint64_t, char *, size_t); +_LIBZUTIL_H void zfs_nicetime(uint64_t, char *, size_t); +_LIBZUTIL_H void zfs_niceraw(uint64_t, char *, size_t); #define nicenum(num, buf, size) zfs_nicenum(num, buf, size) -extern void zpool_dump_ddt(const ddt_stat_t *, const ddt_histogram_t *); -extern int zpool_history_unpack(char *, uint64_t, uint64_t *, nvlist_t ***, +_LIBZUTIL_H void zpool_dump_ddt(const ddt_stat_t *, const ddt_histogram_t *); +_LIBZUTIL_H int zpool_history_unpack(char *, uint64_t, uint64_t *, nvlist_t ***, uint_t *); struct zfs_cmd; -int zfs_ioctl_fd(int fd, unsigned long request, struct zfs_cmd *zc); +_LIBZUTIL_H int zfs_ioctl_fd(int fd, unsigned long request, struct zfs_cmd *zc); /* * List of colors to use @@ -155,9 +156,9 @@ int zfs_ioctl_fd(int fd, unsigned long request, struct zfs_cmd *zc); #define ANSI_RESET "\033[0m" #define ANSI_BOLD "\033[1m" -void color_start(char *color); -void color_end(void); -int printf_color(char *color, char *format, ...); +_LIBZUTIL_H void color_start(char *color); +_LIBZUTIL_H void color_end(void); +_LIBZUTIL_H int printf_color(char *color, char *format, ...); #ifdef __cplusplus } diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/Makefile.am b/sys/contrib/openzfs/include/os/freebsd/spl/sys/Makefile.am index 6bee47830d9..232aaf569fa 100644 --- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/Makefile.am +++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/Makefile.am @@ -8,7 +8,6 @@ KERNEL_H = \ ccompile.h \ cmn_err.h \ condvar.h \ - console.h \ cred.h \ ctype.h \ debug.h \ @@ -69,6 +68,7 @@ KERNEL_H = \ vmsystm.h \ vnode_impl.h \ vnode.h \ + wmsum.h \ zmod.h \ zone.h diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/console.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/console.h deleted file mode 100644 index a0bf8175e6c..00000000000 --- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/console.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2020 iXsystems, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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. - * - * $FreeBSD$ - */ - -#ifndef _SPL_CONSOLE_H -#define _SPL_CONSOLE_H - -#define console_vprintf vprintf -#define console_printf printf - -#endif /* _SPL_CONSOLE_H */ diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/vfs.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/vfs.h index a432f6c5673..22d57cc473e 100644 --- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/vfs.h +++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/vfs.h @@ -55,8 +55,6 @@ typedef int umode_t; #define VFS_NOSETUID MNT_NOSUID #define VFS_NOEXEC MNT_NOEXEC -#define fs_vscan(vp, cr, async) (0) - #define VROOT VV_ROOT #define XU_NGROUPS 16 diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode.h index fa7bbd88c6c..3670712a045 100644 --- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode.h +++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode.h @@ -66,13 +66,8 @@ typedef struct vop_vector vnodeops_t; #define vop_fid_args vop_vptofh_args #define a_fid a_fhp -#define IS_XATTRDIR(dvp) (0) - -#define v_count v_usecount - #define rootvfs (rootvnode == NULL ? NULL : rootvnode->v_mount) - #ifndef IN_BASE static __inline int vn_is_readonly(vnode_t *vp) diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode_impl.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode_impl.h index 94ec1ad4ef6..c82b1fc9ad1 100644 --- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode_impl.h +++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode_impl.h @@ -210,7 +210,7 @@ enum create { CRCREAT, CRMKNOD, CRMKDIR }; /* reason for create */ * * The cc_caller_id is used to identify one or more callers who invoke * operations, possibly on behalf of others. For example, the NFS - * server could have it's own cc_caller_id which can be detected by + * server could have its own cc_caller_id which can be detected by * vnode/vfs operations or (FEM) monitors on those operations. New * caller IDs are generated by fs_new_caller_id(). */ diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/wmsum.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/wmsum.h new file mode 100644 index 00000000000..9fdd1901b7e --- /dev/null +++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/wmsum.h @@ -0,0 +1,72 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.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. + * + * CDDL HEADER END + */ + +/* + * wmsum counters are a reduced version of aggsum counters, optimized for + * write-mostly scenarios. They do not provide optimized read functions, + * but instead allow much cheaper add function. The primary usage is + * infrequently read statistic counters, not requiring exact precision. + * + * The FreeBSD implementation is directly mapped into counter(9) KPI. + */ + +#ifndef _SYS_WMSUM_H +#define _SYS_WMSUM_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define wmsum_t counter_u64_t + +static inline void +wmsum_init(wmsum_t *ws, uint64_t value) +{ + + *ws = counter_u64_alloc(M_WAITOK); + counter_u64_add(*ws, value); +} + +static inline void +wmsum_fini(wmsum_t *ws) +{ + + counter_u64_free(*ws); +} + +static inline uint64_t +wmsum_value(wmsum_t *ws) +{ + + return (counter_u64_fetch(*ws)); +} + +static inline void +wmsum_add(wmsum_t *ws, int64_t delta) +{ + + counter_u64_add(*ws, delta); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_WMSUM_H */ diff --git a/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vfsops_os.h b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vfsops_os.h index a263b48f751..ccbbf4f7322 100644 --- a/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vfsops_os.h +++ b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vfsops_os.h @@ -98,7 +98,6 @@ struct zfsvfs { struct zfsctl_root *z_ctldir; /* .zfs directory pointer */ boolean_t z_show_ctldir; /* expose .zfs in the root dir */ boolean_t z_issnap; /* true if this is a snapshot */ - boolean_t z_vscan; /* virus scan on/off */ boolean_t z_use_fuids; /* version allows fuids */ boolean_t z_replay; /* set during ZIL replay */ boolean_t z_use_sa; /* version allow system attributes */ diff --git a/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_znode_impl.h b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_znode_impl.h index dde87973f96..7d28bddbf51 100644 --- a/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_znode_impl.h +++ b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_znode_impl.h @@ -54,7 +54,7 @@ extern "C" { #define ZNODE_OS_FIELDS \ struct zfsvfs *z_zfsvfs; \ vnode_t *z_vnode; \ - char *z_cached_symlink; \ + char *z_cached_symlink; \ uint64_t z_uid; \ uint64_t z_gid; \ uint64_t z_gen; \ @@ -78,8 +78,6 @@ typedef struct zfs_soft_state { void *zss_data; } zfs_soft_state_t; -extern minor_t zfsdev_minor_alloc(void); - /* * Range locking rules * -------------------- diff --git a/sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h b/sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h index ee066537b90..87d54107201 100644 --- a/sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h +++ b/sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h @@ -52,7 +52,7 @@ blk_queue_flag_clear(unsigned int flag, struct request_queue *q) #endif /* - * 4.7 - 4.x API, + * 4.7 API, * The blk_queue_write_cache() interface has replaced blk_queue_flush() * interface. However, the new interface is GPL-only thus we implement * our own trivial wrapper when the GPL-only version is detected. @@ -254,14 +254,14 @@ bio_set_bi_error(struct bio *bio, int error) #endif /* HAVE_1ARG_BIO_END_IO_T */ /* - * 4.1 - x.y.z API, + * 4.1 API, * 3.10.0 CentOS 7.x API, * blkdev_reread_part() * * For older kernels trigger a re-reading of the partition table by calling * check_disk_change() which calls flush_disk() to invalidate the device. * - * For newer kernels (as of 5.10), bdev_check_media_chage is used, in favor of + * For newer kernels (as of 5.10), bdev_check_media_change is used, in favor of * check_disk_change(), with the modification that invalidation is no longer * forced. */ @@ -277,18 +277,22 @@ bio_set_bi_error(struct bio *bio, int error) static inline int zfs_check_media_change(struct block_device *bdev) { +#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK struct gendisk *gd = bdev->bd_disk; const struct block_device_operations *bdo = gd->fops; +#endif if (!bdev_check_media_change(bdev)) return (0); +#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK /* * Force revalidation, to mimic the old behavior of * check_disk_change() */ if (bdo->revalidate_disk) bdo->revalidate_disk(gd); +#endif return (0); } @@ -366,7 +370,7 @@ bio_set_op_attrs(struct bio *bio, unsigned rw, unsigned flags) * * 4.8 - 4.9 API, * REQ_FLUSH was renamed to REQ_PREFLUSH. For consistency with previous - * ZoL releases, prefer the WRITE_FLUSH_FUA flag set if it's available. + * OpenZFS releases, prefer the WRITE_FLUSH_FUA flag set if it's available. * * 4.10 API, * The read/write flags and their modifiers, including WRITE_FLUSH, @@ -387,7 +391,7 @@ bio_set_flush(struct bio *bio) } /* - * 4.8 - 4.x API, + * 4.8 API, * REQ_OP_FLUSH * * 4.8-rc0 - 4.8-rc1, @@ -417,7 +421,7 @@ bio_is_flush(struct bio *bio) } /* - * 4.8 - 4.x API, + * 4.8 API, * REQ_FUA flag moved to bio->bi_opf * * 2.6.x - 4.7 API, @@ -436,7 +440,7 @@ bio_is_fua(struct bio *bio) } /* - * 4.8 - 4.x API, + * 4.8 API, * REQ_OP_DISCARD * * 2.6.36 - 4.7 API, @@ -458,7 +462,7 @@ bio_is_discard(struct bio *bio) } /* - * 4.8 - 4.x API, + * 4.8 API, * REQ_OP_SECURE_ERASE * * 2.6.36 - 4.7 API, @@ -488,7 +492,7 @@ blk_queue_discard_granularity(struct request_queue *q, unsigned int dg) } /* - * 4.8 - 4.x API, + * 4.8 API, * blk_queue_secure_erase() * * 2.6.36 - 4.7 API, diff --git a/sys/contrib/openzfs/include/os/linux/kernel/linux/mod_compat.h b/sys/contrib/openzfs/include/os/linux/kernel/linux/mod_compat.h index e96e9531300..cc42c3f7c74 100644 --- a/sys/contrib/openzfs/include/os/linux/kernel/linux/mod_compat.h +++ b/sys/contrib/openzfs/include/os/linux/kernel/linux/mod_compat.h @@ -83,7 +83,7 @@ enum scope_prefix_types { /* * Declare a module parameter / sysctl node * - * "scope_prefix" the part of the the sysctl / sysfs tree the node resides under + * "scope_prefix" the part of the sysctl / sysfs tree the node resides under * (currently a no-op on Linux) * "name_prefix" the part of the variable name that will be excluded from the * exported names on platforms with a hierarchical namespace diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/Makefile.am b/sys/contrib/openzfs/include/os/linux/spl/sys/Makefile.am index 0fd4cd37a7e..48c27f970fc 100644 --- a/sys/contrib/openzfs/include/os/linux/spl/sys/Makefile.am +++ b/sys/contrib/openzfs/include/os/linux/spl/sys/Makefile.am @@ -6,7 +6,6 @@ KERNEL_H = \ callo.h \ cmn_err.h \ condvar.h \ - console.h \ cred.h \ ctype.h \ debug.h \ @@ -55,6 +54,7 @@ KERNEL_H = \ vmsystm.h \ vnode.h \ wait.h \ + wmsum.h \ zmod.h \ zone.h diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/atomic.h b/sys/contrib/openzfs/include/os/linux/spl/sys/atomic.h index 2d21cbb3e14..8f7fa5aeda1 100644 --- a/sys/contrib/openzfs/include/os/linux/spl/sys/atomic.h +++ b/sys/contrib/openzfs/include/os/linux/spl/sys/atomic.h @@ -48,6 +48,8 @@ #define atomic_sub_32_nv(v, i) atomic_sub_return((i), (atomic_t *)(v)) #define atomic_cas_32(v, x, y) atomic_cmpxchg((atomic_t *)(v), x, y) #define atomic_swap_32(v, x) atomic_xchg((atomic_t *)(v), x) +#define atomic_load_32(v) atomic_read((atomic_t *)(v)) +#define atomic_store_32(v, x) atomic_set((atomic_t *)(v), x) #define atomic_inc_64(v) atomic64_inc((atomic64_t *)(v)) #define atomic_dec_64(v) atomic64_dec((atomic64_t *)(v)) #define atomic_add_64(v, i) atomic64_add((i), (atomic64_t *)(v)) @@ -58,6 +60,8 @@ #define atomic_sub_64_nv(v, i) atomic64_sub_return((i), (atomic64_t *)(v)) #define atomic_cas_64(v, x, y) atomic64_cmpxchg((atomic64_t *)(v), x, y) #define atomic_swap_64(v, x) atomic64_xchg((atomic64_t *)(v), x) +#define atomic_load_64(v) atomic64_read((atomic64_t *)(v)) +#define atomic_store_64(v, x) atomic64_set((atomic64_t *)(v), x) #ifdef _LP64 static __inline__ void * diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/console.h b/sys/contrib/openzfs/include/os/linux/spl/sys/console.h deleted file mode 100644 index 6af395cc2d7..00000000000 --- a/sys/contrib/openzfs/include/os/linux/spl/sys/console.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC. - * Copyright (C) 2007 The Regents of the University of California. - * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). - * Written by Brian Behlendorf . - * UCRL-CODE-235197 - * - * This file is part of the SPL, Solaris Porting Layer. - * - * The SPL is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * The SPL is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with the SPL. If not, see . - */ - -#ifndef _SPL_CONSOLE_H -#define _SPL_CONSOLE_H - -#define console_vprintf vprintk -#define console_printf printk - -#endif /* _SPL_CONSOLE_H */ diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/signal.h b/sys/contrib/openzfs/include/os/linux/spl/sys/signal.h index fd32f08b348..6b538c8966f 100644 --- a/sys/contrib/openzfs/include/os/linux/spl/sys/signal.h +++ b/sys/contrib/openzfs/include/os/linux/spl/sys/signal.h @@ -33,22 +33,6 @@ #define FORREAL 0 /* Usual side-effects */ #define JUSTLOOKING 1 /* Don't stop the process */ -/* - * The "why" argument indicates the allowable side-effects of the call: - * - * FORREAL: Extract the next pending signal from p_sig into p_cursig; - * stop the process if a stop has been requested or if a traced signal - * is pending. - * - * JUSTLOOKING: Don't stop the process, just indicate whether or not - * a signal might be pending (FORREAL is needed to tell for sure). - */ -static __inline__ int -issig(int why) -{ - ASSERT(why == FORREAL || why == JUSTLOOKING); - - return (signal_pending(current)); -} +extern int issig(int why); #endif /* SPL_SIGNAL_H */ diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/thread.h b/sys/contrib/openzfs/include/os/linux/spl/sys/thread.h index 99d9c9bf382..220742387b6 100644 --- a/sys/contrib/openzfs/include/os/linux/spl/sys/thread.h +++ b/sys/contrib/openzfs/include/os/linux/spl/sys/thread.h @@ -70,4 +70,17 @@ extern struct task_struct *spl_kthread_create(int (*func)(void *), extern proc_t p0; +#ifdef HAVE_SIGINFO +typedef kernel_siginfo_t spl_kernel_siginfo_t; +#else +typedef siginfo_t spl_kernel_siginfo_t; +#endif + +#ifdef HAVE_SET_SPECIAL_STATE +#define spl_set_special_state(x) set_special_state((x)) +#else +#define spl_set_special_state(x) __set_current_state((x)) +#endif + + #endif /* _SPL_THREAD_H */ diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/wmsum.h b/sys/contrib/openzfs/include/os/linux/spl/sys/wmsum.h new file mode 100644 index 00000000000..0871bd69504 --- /dev/null +++ b/sys/contrib/openzfs/include/os/linux/spl/sys/wmsum.h @@ -0,0 +1,76 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.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. + * + * CDDL HEADER END + */ + +/* + * wmsum counters are a reduced version of aggsum counters, optimized for + * write-mostly scenarios. They do not provide optimized read functions, + * but instead allow much cheaper add function. The primary usage is + * infrequently read statistic counters, not requiring exact precision. + * + * The Linux implementation is directly mapped into percpu_counter KPI. + */ + +#ifndef _SYS_WMSUM_H +#define _SYS_WMSUM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct percpu_counter wmsum_t; + +static inline void +wmsum_init(wmsum_t *ws, uint64_t value) +{ + +#ifdef HAVE_PERCPU_COUNTER_INIT_WITH_GFP + percpu_counter_init(ws, value, GFP_KERNEL); +#else + percpu_counter_init(ws, value); +#endif +} + +static inline void +wmsum_fini(wmsum_t *ws) +{ + + percpu_counter_destroy(ws); +} + +static inline uint64_t +wmsum_value(wmsum_t *ws) +{ + + return (percpu_counter_sum(ws)); +} + +static inline void +wmsum_add(wmsum_t *ws, int64_t delta) +{ + +#ifdef HAVE_PERCPU_COUNTER_ADD_BATCH + percpu_counter_add_batch(ws, delta, INT_MAX / 2); +#else + __percpu_counter_add(ws, delta, INT_MAX / 2); +#endif +} + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_WMSUM_H */ diff --git a/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vfsops_os.h b/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vfsops_os.h index 7b4a1aac9aa..8e03ae99a7f 100644 --- a/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vfsops_os.h +++ b/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vfsops_os.h @@ -113,7 +113,6 @@ struct zfsvfs { struct inode *z_ctldir; /* .zfs directory inode */ boolean_t z_show_ctldir; /* expose .zfs in the root dir */ boolean_t z_issnap; /* true if this is a snapshot */ - boolean_t z_vscan; /* virus scan on/off */ boolean_t z_use_fuids; /* version allows fuids */ boolean_t z_replay; /* set during ZIL replay */ boolean_t z_use_sa; /* version allow system attributes */ diff --git a/sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h b/sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h index 21825d1f378..54f3fa0fdb0 100644 --- a/sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h +++ b/sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h @@ -63,7 +63,12 @@ extern int zpl_xattr_security_init(struct inode *ip, struct inode *dip, const struct qstr *qstr); #if defined(CONFIG_FS_POSIX_ACL) #if defined(HAVE_SET_ACL) +#if defined(HAVE_SET_ACL_USERNS) +extern int zpl_set_acl(struct user_namespace *userns, struct inode *ip, + struct posix_acl *acl, int type); +#else extern int zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type); +#endif /* HAVE_SET_ACL_USERNS */ #endif /* HAVE_SET_ACL */ extern struct posix_acl *zpl_get_acl(struct inode *ip, int type); extern int zpl_init_acl(struct inode *ip, struct inode *dir); diff --git a/sys/contrib/openzfs/include/sys/aggsum.h b/sys/contrib/openzfs/include/sys/aggsum.h index cb43727f1df..65800058cbf 100644 --- a/sys/contrib/openzfs/include/sys/aggsum.h +++ b/sys/contrib/openzfs/include/sys/aggsum.h @@ -39,15 +39,16 @@ struct aggsum_bucket { typedef struct aggsum { kmutex_t as_lock; int64_t as_lower_bound; - int64_t as_upper_bound; + uint64_t as_upper_bound; + aggsum_bucket_t *as_buckets ____cacheline_aligned; uint_t as_numbuckets; - aggsum_bucket_t *as_buckets; + uint_t as_bucketshift; } aggsum_t; void aggsum_init(aggsum_t *, uint64_t); void aggsum_fini(aggsum_t *); int64_t aggsum_lower_bound(aggsum_t *); -int64_t aggsum_upper_bound(aggsum_t *); +uint64_t aggsum_upper_bound(aggsum_t *); int aggsum_compare(aggsum_t *, uint64_t); uint64_t aggsum_value(aggsum_t *); void aggsum_add(aggsum_t *, int64_t); diff --git a/sys/contrib/openzfs/include/sys/dataset_kstats.h b/sys/contrib/openzfs/include/sys/dataset_kstats.h index 667d1b85fa2..b165b98576d 100644 --- a/sys/contrib/openzfs/include/sys/dataset_kstats.h +++ b/sys/contrib/openzfs/include/sys/dataset_kstats.h @@ -27,18 +27,18 @@ #ifndef _SYS_DATASET_KSTATS_H #define _SYS_DATASET_KSTATS_H -#include +#include #include #include -typedef struct dataset_aggsum_stats_t { - aggsum_t das_writes; - aggsum_t das_nwritten; - aggsum_t das_reads; - aggsum_t das_nread; - aggsum_t das_nunlinks; - aggsum_t das_nunlinked; -} dataset_aggsum_stats_t; +typedef struct dataset_sum_stats_t { + wmsum_t dss_writes; + wmsum_t dss_nwritten; + wmsum_t dss_reads; + wmsum_t dss_nread; + wmsum_t dss_nunlinks; + wmsum_t dss_nunlinked; +} dataset_sum_stats_t; typedef struct dataset_kstat_values { kstat_named_t dkv_ds_name; @@ -59,7 +59,7 @@ typedef struct dataset_kstat_values { } dataset_kstat_values_t; typedef struct dataset_kstats { - dataset_aggsum_stats_t dk_aggsums; + dataset_sum_stats_t dk_sums; kstat_t *dk_kstats; } dataset_kstats_t; diff --git a/sys/contrib/openzfs/include/sys/dsl_scan.h b/sys/contrib/openzfs/include/sys/dsl_scan.h index 19c3dd599b1..fb1f1d65bad 100644 --- a/sys/contrib/openzfs/include/sys/dsl_scan.h +++ b/sys/contrib/openzfs/include/sys/dsl_scan.h @@ -163,6 +163,7 @@ typedef struct dsl_scan_io_queue dsl_scan_io_queue_t; void scan_init(void); void scan_fini(void); int dsl_scan_init(struct dsl_pool *dp, uint64_t txg); +int dsl_scan_setup_check(void *, dmu_tx_t *); void dsl_scan_setup_sync(void *, dmu_tx_t *); void dsl_scan_fini(struct dsl_pool *dp); void dsl_scan_sync(struct dsl_pool *, dmu_tx_t *); diff --git a/sys/contrib/openzfs/include/sys/fm/util.h b/sys/contrib/openzfs/include/sys/fm/util.h index ea8c61a8b9b..56ba8798beb 100644 --- a/sys/contrib/openzfs/include/sys/fm/util.h +++ b/sys/contrib/openzfs/include/sys/fm/util.h @@ -92,7 +92,6 @@ typedef struct zfs_zevent { extern void fm_init(void); extern void fm_fini(void); -extern void fm_nvprint(nvlist_t *); extern void zfs_zevent_post_cb(nvlist_t *nvl, nvlist_t *detector); extern int zfs_zevent_post(nvlist_t *, nvlist_t *, zevent_cb_t *); extern void zfs_zevent_drain_all(int *); diff --git a/sys/contrib/openzfs/include/sys/fs/zfs.h b/sys/contrib/openzfs/include/sys/fs/zfs.h index 71d736d5cc9..5d43750594c 100644 --- a/sys/contrib/openzfs/include/sys/fs/zfs.h +++ b/sys/contrib/openzfs/include/sys/fs/zfs.h @@ -32,7 +32,7 @@ */ #ifndef _SYS_FS_ZFS_H -#define _SYS_FS_ZFS_H +#define _SYS_FS_ZFS_H extern __attribute__((visibility("default"))) #include #include @@ -205,7 +205,7 @@ typedef enum { ZFS_NUM_USERQUOTA_PROPS } zfs_userquota_prop_t; -extern const char *zfs_userquota_prop_prefixes[ZFS_NUM_USERQUOTA_PROPS]; +_SYS_FS_ZFS_H const char *zfs_userquota_prop_prefixes[ZFS_NUM_USERQUOTA_PROPS]; /* * Pool properties are identified by these constants and must be added to the @@ -301,38 +301,41 @@ typedef int (*zprop_func)(int, void *); /* * Dataset property functions shared between libzfs and kernel. */ -const char *zfs_prop_default_string(zfs_prop_t); -uint64_t zfs_prop_default_numeric(zfs_prop_t); -boolean_t zfs_prop_readonly(zfs_prop_t); -boolean_t zfs_prop_visible(zfs_prop_t prop); -boolean_t zfs_prop_inheritable(zfs_prop_t); -boolean_t zfs_prop_setonce(zfs_prop_t); -boolean_t zfs_prop_encryption_key_param(zfs_prop_t); -boolean_t zfs_prop_valid_keylocation(const char *, boolean_t); -const char *zfs_prop_to_name(zfs_prop_t); -zfs_prop_t zfs_name_to_prop(const char *); -boolean_t zfs_prop_user(const char *); -boolean_t zfs_prop_userquota(const char *); -boolean_t zfs_prop_written(const char *); -int zfs_prop_index_to_string(zfs_prop_t, uint64_t, const char **); -int zfs_prop_string_to_index(zfs_prop_t, const char *, uint64_t *); -uint64_t zfs_prop_random_value(zfs_prop_t, uint64_t seed); -boolean_t zfs_prop_valid_for_type(int, zfs_type_t, boolean_t); +_SYS_FS_ZFS_H const char *zfs_prop_default_string(zfs_prop_t); +_SYS_FS_ZFS_H uint64_t zfs_prop_default_numeric(zfs_prop_t); +_SYS_FS_ZFS_H boolean_t zfs_prop_readonly(zfs_prop_t); +_SYS_FS_ZFS_H boolean_t zfs_prop_visible(zfs_prop_t prop); +_SYS_FS_ZFS_H boolean_t zfs_prop_inheritable(zfs_prop_t); +_SYS_FS_ZFS_H boolean_t zfs_prop_setonce(zfs_prop_t); +_SYS_FS_ZFS_H boolean_t zfs_prop_encryption_key_param(zfs_prop_t); +_SYS_FS_ZFS_H boolean_t zfs_prop_valid_keylocation(const char *, boolean_t); +_SYS_FS_ZFS_H const char *zfs_prop_to_name(zfs_prop_t); +_SYS_FS_ZFS_H zfs_prop_t zfs_name_to_prop(const char *); +_SYS_FS_ZFS_H boolean_t zfs_prop_user(const char *); +_SYS_FS_ZFS_H boolean_t zfs_prop_userquota(const char *); +_SYS_FS_ZFS_H boolean_t zfs_prop_written(const char *); +_SYS_FS_ZFS_H int zfs_prop_index_to_string(zfs_prop_t, uint64_t, const char **); +_SYS_FS_ZFS_H int zfs_prop_string_to_index(zfs_prop_t, const char *, + uint64_t *); +_SYS_FS_ZFS_H uint64_t zfs_prop_random_value(zfs_prop_t, uint64_t seed); +_SYS_FS_ZFS_H boolean_t zfs_prop_valid_for_type(int, zfs_type_t, boolean_t); /* * Pool property functions shared between libzfs and kernel. */ -zpool_prop_t zpool_name_to_prop(const char *); -const char *zpool_prop_to_name(zpool_prop_t); -const char *zpool_prop_default_string(zpool_prop_t); -uint64_t zpool_prop_default_numeric(zpool_prop_t); -boolean_t zpool_prop_readonly(zpool_prop_t); -boolean_t zpool_prop_setonce(zpool_prop_t); -boolean_t zpool_prop_feature(const char *); -boolean_t zpool_prop_unsupported(const char *); -int zpool_prop_index_to_string(zpool_prop_t, uint64_t, const char **); -int zpool_prop_string_to_index(zpool_prop_t, const char *, uint64_t *); -uint64_t zpool_prop_random_value(zpool_prop_t, uint64_t seed); +_SYS_FS_ZFS_H zpool_prop_t zpool_name_to_prop(const char *); +_SYS_FS_ZFS_H const char *zpool_prop_to_name(zpool_prop_t); +_SYS_FS_ZFS_H const char *zpool_prop_default_string(zpool_prop_t); +_SYS_FS_ZFS_H uint64_t zpool_prop_default_numeric(zpool_prop_t); +_SYS_FS_ZFS_H boolean_t zpool_prop_readonly(zpool_prop_t); +_SYS_FS_ZFS_H boolean_t zpool_prop_setonce(zpool_prop_t); +_SYS_FS_ZFS_H boolean_t zpool_prop_feature(const char *); +_SYS_FS_ZFS_H boolean_t zpool_prop_unsupported(const char *); +_SYS_FS_ZFS_H int zpool_prop_index_to_string(zpool_prop_t, uint64_t, + const char **); +_SYS_FS_ZFS_H int zpool_prop_string_to_index(zpool_prop_t, const char *, + uint64_t *); +_SYS_FS_ZFS_H uint64_t zpool_prop_random_value(zpool_prop_t, uint64_t seed); /* * Definitions for the Delegation. @@ -1613,6 +1616,47 @@ typedef enum { #define ZFS_EV_HIST_DSID "history_dsid" #define ZFS_EV_RESILVER_TYPE "resilver_type" + +/* + * We currently support block sizes from 512 bytes to 16MB. + * The benefits of larger blocks, and thus larger IO, need to be weighed + * against the cost of COWing a giant block to modify one byte, and the + * large latency of reading or writing a large block. + * + * Note that although blocks up to 16MB are supported, the recordsize + * property can not be set larger than zfs_max_recordsize (default 1MB). + * See the comment near zfs_max_recordsize in dsl_dataset.c for details. + * + * Note that although the LSIZE field of the blkptr_t can store sizes up + * to 32MB, the dnode's dn_datablkszsec can only store sizes up to + * 32MB - 512 bytes. Therefore, we limit SPA_MAXBLOCKSIZE to 16MB. + */ +#define SPA_MINBLOCKSHIFT 9 +#define SPA_OLD_MAXBLOCKSHIFT 17 +#define SPA_MAXBLOCKSHIFT 24 +#define SPA_MINBLOCKSIZE (1ULL << SPA_MINBLOCKSHIFT) +#define SPA_OLD_MAXBLOCKSIZE (1ULL << SPA_OLD_MAXBLOCKSHIFT) +#define SPA_MAXBLOCKSIZE (1ULL << SPA_MAXBLOCKSHIFT) + + +/* supported encryption algorithms */ +enum zio_encrypt { + ZIO_CRYPT_INHERIT = 0, + ZIO_CRYPT_ON, + ZIO_CRYPT_OFF, + ZIO_CRYPT_AES_128_CCM, + ZIO_CRYPT_AES_192_CCM, + ZIO_CRYPT_AES_256_CCM, + ZIO_CRYPT_AES_128_GCM, + ZIO_CRYPT_AES_192_GCM, + ZIO_CRYPT_AES_256_GCM, + ZIO_CRYPT_FUNCTIONS +}; + +#define ZIO_CRYPT_ON_VALUE ZIO_CRYPT_AES_256_GCM +#define ZIO_CRYPT_DEFAULT ZIO_CRYPT_OFF + + #ifdef __cplusplus } #endif diff --git a/sys/contrib/openzfs/include/sys/spa.h b/sys/contrib/openzfs/include/sys/spa.h index c960478efe5..374d36e7327 100644 --- a/sys/contrib/openzfs/include/sys/spa.h +++ b/sys/contrib/openzfs/include/sys/spa.h @@ -72,27 +72,6 @@ struct dsl_pool; struct dsl_dataset; struct dsl_crypto_params; -/* - * We currently support block sizes from 512 bytes to 16MB. - * The benefits of larger blocks, and thus larger IO, need to be weighed - * against the cost of COWing a giant block to modify one byte, and the - * large latency of reading or writing a large block. - * - * Note that although blocks up to 16MB are supported, the recordsize - * property can not be set larger than zfs_max_recordsize (default 1MB). - * See the comment near zfs_max_recordsize in dsl_dataset.c for details. - * - * Note that although the LSIZE field of the blkptr_t can store sizes up - * to 32MB, the dnode's dn_datablkszsec can only store sizes up to - * 32MB - 512 bytes. Therefore, we limit SPA_MAXBLOCKSIZE to 16MB. - */ -#define SPA_MINBLOCKSHIFT 9 -#define SPA_OLD_MAXBLOCKSHIFT 17 -#define SPA_MAXBLOCKSHIFT 24 -#define SPA_MINBLOCKSIZE (1ULL << SPA_MINBLOCKSHIFT) -#define SPA_OLD_MAXBLOCKSIZE (1ULL << SPA_OLD_MAXBLOCKSHIFT) -#define SPA_MAXBLOCKSIZE (1ULL << SPA_MAXBLOCKSHIFT) - /* * Alignment Shift (ashift) is an immutable, internal top-level vdev property * which can only be set at vdev creation time. Physical writes are always done diff --git a/sys/contrib/openzfs/include/sys/vdev_draid.h b/sys/contrib/openzfs/include/sys/vdev_draid.h index 65417a93c4e..52ce4ba1610 100644 --- a/sys/contrib/openzfs/include/sys/vdev_draid.h +++ b/sys/contrib/openzfs/include/sys/vdev_draid.h @@ -51,7 +51,7 @@ extern "C" { * dRAID permutation map. */ typedef struct draid_map { - uint64_t dm_children; /* # of permuation columns */ + uint64_t dm_children; /* # of permutation columns */ uint64_t dm_nperms; /* # of permutation rows */ uint64_t dm_seed; /* dRAID map seed */ uint64_t dm_checksum; /* Checksum of generated map */ diff --git a/sys/contrib/openzfs/include/sys/vdev_impl.h b/sys/contrib/openzfs/include/sys/vdev_impl.h index db4fe1447eb..3cfde40a77f 100644 --- a/sys/contrib/openzfs/include/sys/vdev_impl.h +++ b/sys/contrib/openzfs/include/sys/vdev_impl.h @@ -458,10 +458,11 @@ struct vdev { kmutex_t vdev_probe_lock; /* protects vdev_probe_zio */ /* - * We rate limit ZIO delay and ZIO checksum events, since they + * We rate limit ZIO delay, deadman, and checksum events, since they * can flood ZED with tons of events when a drive is acting up. */ zfs_ratelimit_t vdev_delay_rl; + zfs_ratelimit_t vdev_deadman_rl; zfs_ratelimit_t vdev_checksum_rl; }; @@ -501,7 +502,7 @@ typedef enum vbe_vers { * and is protected by an embedded checksum. By default, GRUB will * check if the boot filesystem supports storing the environment data * in a special location, and if so, will invoke filesystem specific - * logic to retrieve it. This can be overriden by a variable, should + * logic to retrieve it. This can be overridden by a variable, should * the user so desire. */ VB_RAW = 0, diff --git a/sys/contrib/openzfs/include/sys/vdev_raidz_impl.h b/sys/contrib/openzfs/include/sys/vdev_raidz_impl.h index b94d59eb776..908723da0c2 100644 --- a/sys/contrib/openzfs/include/sys/vdev_raidz_impl.h +++ b/sys/contrib/openzfs/include/sys/vdev_raidz_impl.h @@ -113,7 +113,8 @@ typedef struct raidz_col { uint8_t rc_tried; /* Did we attempt this I/O column? */ uint8_t rc_skipped; /* Did we skip this I/O column? */ uint8_t rc_need_orig_restore; /* need to restore from orig_data? */ - uint8_t rc_repair; /* Write good data to this column */ + uint8_t rc_force_repair; /* Write good data to this column */ + uint8_t rc_allow_repair; /* Allow repair I/O to this column */ } raidz_col_t; typedef struct raidz_row { diff --git a/sys/contrib/openzfs/include/sys/vdev_rebuild.h b/sys/contrib/openzfs/include/sys/vdev_rebuild.h index 61ae15c5d09..b59fbe15390 100644 --- a/sys/contrib/openzfs/include/sys/vdev_rebuild.h +++ b/sys/contrib/openzfs/include/sys/vdev_rebuild.h @@ -60,7 +60,7 @@ typedef struct vdev_rebuild_phys { /* * The vdev_rebuild_t describes the current state and how a top-level vdev * should be rebuilt. The core elements are the top-vdev, the metaslab being - * rebuilt, range tree containing the allocted extents and the on-disk state. + * rebuilt, range tree containing the allocated extents and the on-disk state. */ typedef struct vdev_rebuild { vdev_t *vr_top_vdev; /* top-level vdev to rebuild */ diff --git a/sys/contrib/openzfs/include/sys/zfs_context.h b/sys/contrib/openzfs/include/sys/zfs_context.h index 6cdcc6d3096..89afa98253f 100644 --- a/sys/contrib/openzfs/include/sys/zfs_context.h +++ b/sys/contrib/openzfs/include/sys/zfs_context.h @@ -160,8 +160,6 @@ extern void vpanic(const char *, va_list) __NORETURN; #define fm_panic panic -extern int aok; - /* * DTrace SDT probes have different signatures in userland than they do in * the kernel. If they're being used in kernel code, re-define them out of @@ -638,8 +636,8 @@ extern void delay(clock_t ticks); #define NN_NUMBUF_SZ (6) extern uint64_t physmem; -extern char *random_path; -extern char *urandom_path; +extern const char *random_path; +extern const char *urandom_path; extern int highbit64(uint64_t i); extern int lowbit64(uint64_t i); diff --git a/sys/contrib/openzfs/include/sys/zfs_ioctl.h b/sys/contrib/openzfs/include/sys/zfs_ioctl.h index 8834c52990d..41c978a3fff 100644 --- a/sys/contrib/openzfs/include/sys/zfs_ioctl.h +++ b/sys/contrib/openzfs/include/sys/zfs_ioctl.h @@ -567,7 +567,6 @@ typedef struct zfsdev_state { extern void *zfsdev_get_state(minor_t minor, enum zfsdev_state_type which); extern int zfsdev_getminor(int fd, minor_t *minorp); -extern minor_t zfsdev_minor_alloc(void); extern uint_t zfs_fsyncer_key; extern uint_t zfs_allow_log_key; diff --git a/sys/contrib/openzfs/include/sys/zfs_ioctl_impl.h b/sys/contrib/openzfs/include/sys/zfs_ioctl_impl.h index 787475cf396..3db67ae9841 100644 --- a/sys/contrib/openzfs/include/sys/zfs_ioctl_impl.h +++ b/sys/contrib/openzfs/include/sys/zfs_ioctl_impl.h @@ -82,6 +82,7 @@ void zfs_ioctl_register(const char *, zfs_ioc_t, zfs_ioc_func_t *, boolean_t, boolean_t, const zfs_ioc_key_t *, size_t); uint64_t zfs_max_nvlist_src_size_os(void); +void zfs_ioctl_update_mount_cache(const char *dsname); void zfs_ioctl_init_os(void); boolean_t zfs_vfs_held(zfsvfs_t *); @@ -91,6 +92,10 @@ void zfs_vfs_rele(zfsvfs_t *); long zfsdev_ioctl_common(uint_t, zfs_cmd_t *, int); int zfsdev_attach(void); void zfsdev_detach(void); +void zfsdev_private_set_state(void *, zfsdev_state_t *); +zfsdev_state_t *zfsdev_private_get_state(void *); +int zfsdev_state_init(void *); +void zfsdev_state_destroy(void *); int zfs_kmod_init(void); void zfs_kmod_fini(void); diff --git a/sys/contrib/openzfs/include/sys/zfs_sysfs.h b/sys/contrib/openzfs/include/sys/zfs_sysfs.h index 925d7ad542f..14ba61fc4b0 100644 --- a/sys/contrib/openzfs/include/sys/zfs_sysfs.h +++ b/sys/contrib/openzfs/include/sys/zfs_sysfs.h @@ -23,7 +23,7 @@ */ #ifndef _SYS_ZFS_SYSFS_H -#define _SYS_ZFS_SYSFS_H +#define _SYS_ZFS_SYSFS_H extern __attribute__((visibility("default"))) #ifdef _KERNEL @@ -35,7 +35,7 @@ void zfs_sysfs_fini(void); #define zfs_sysfs_init() #define zfs_sysfs_fini() -boolean_t zfs_mod_supported(const char *, const char *); +_SYS_ZFS_SYSFS_H boolean_t zfs_mod_supported(const char *, const char *); #endif #define ZFS_SYSFS_POOL_PROPERTIES "properties.pool" diff --git a/sys/contrib/openzfs/include/sys/zio.h b/sys/contrib/openzfs/include/sys/zio.h index 3728550134b..c792cb65b67 100644 --- a/sys/contrib/openzfs/include/sys/zio.h +++ b/sys/contrib/openzfs/include/sys/zio.h @@ -108,23 +108,6 @@ enum zio_checksum { #define ZIO_DEDUPCHECKSUM ZIO_CHECKSUM_SHA256 -/* supported encryption algorithms */ -enum zio_encrypt { - ZIO_CRYPT_INHERIT = 0, - ZIO_CRYPT_ON, - ZIO_CRYPT_OFF, - ZIO_CRYPT_AES_128_CCM, - ZIO_CRYPT_AES_192_CCM, - ZIO_CRYPT_AES_256_CCM, - ZIO_CRYPT_AES_128_GCM, - ZIO_CRYPT_AES_192_GCM, - ZIO_CRYPT_AES_256_GCM, - ZIO_CRYPT_FUNCTIONS -}; - -#define ZIO_CRYPT_ON_VALUE ZIO_CRYPT_AES_256_GCM -#define ZIO_CRYPT_DEFAULT ZIO_CRYPT_OFF - /* macros defining encryption lengths */ #define ZIO_OBJSET_MAC_LEN 32 #define ZIO_DATA_IV_LEN 12 diff --git a/sys/contrib/openzfs/include/sys/zio_checksum.h b/sys/contrib/openzfs/include/sys/zio_checksum.h index 45abd3bd313..9a73a626229 100644 --- a/sys/contrib/openzfs/include/sys/zio_checksum.h +++ b/sys/contrib/openzfs/include/sys/zio_checksum.h @@ -25,7 +25,7 @@ */ #ifndef _SYS_ZIO_CHECKSUM_H -#define _SYS_ZIO_CHECKSUM_H +#define _SYS_ZIO_CHECKSUM_H extern __attribute__((visibility("default"))) #include #include @@ -101,7 +101,8 @@ typedef struct zio_bad_cksum { uint8_t zbc_has_cksum; /* expected/actual valid */ } zio_bad_cksum_t; -extern zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS]; +_SYS_ZIO_CHECKSUM_H zio_checksum_info_t + zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS]; /* * Checksum routines. @@ -122,7 +123,7 @@ extern zio_checksum_t abd_checksum_edonr_byteswap; extern zio_checksum_tmpl_init_t abd_checksum_edonr_tmpl_init; extern zio_checksum_tmpl_free_t abd_checksum_edonr_tmpl_free; -extern zio_abd_checksum_func_t fletcher_4_abd_ops; +_SYS_ZIO_CHECKSUM_H zio_abd_checksum_func_t fletcher_4_abd_ops; extern zio_checksum_t abd_fletcher_4_native; extern zio_checksum_t abd_fletcher_4_byteswap; diff --git a/sys/contrib/openzfs/include/zfeature_common.h b/sys/contrib/openzfs/include/zfeature_common.h index 76dd7ed5747..874cbd9ff71 100644 --- a/sys/contrib/openzfs/include/zfeature_common.h +++ b/sys/contrib/openzfs/include/zfeature_common.h @@ -27,7 +27,7 @@ */ #ifndef _ZFEATURE_COMMON_H -#define _ZFEATURE_COMMON_H +#define _ZFEATURE_COMMON_H extern __attribute__((visibility("default"))) #include #include @@ -116,16 +116,17 @@ typedef int (zfeature_func_t)(zfeature_info_t *, void *); #define ZFS_FEATURE_DEBUG -extern zfeature_info_t spa_feature_table[SPA_FEATURES]; +_ZFEATURE_COMMON_H zfeature_info_t spa_feature_table[SPA_FEATURES]; +_ZFEATURE_COMMON_H boolean_t zfeature_checks_disable; -extern boolean_t zfeature_is_valid_guid(const char *); +_ZFEATURE_COMMON_H boolean_t zfeature_is_valid_guid(const char *); -extern boolean_t zfeature_is_supported(const char *); -extern int zfeature_lookup_guid(const char *, spa_feature_t *); -extern int zfeature_lookup_name(const char *, spa_feature_t *); -extern boolean_t zfeature_depends_on(spa_feature_t, spa_feature_t); +_ZFEATURE_COMMON_H boolean_t zfeature_is_supported(const char *); +_ZFEATURE_COMMON_H int zfeature_lookup_guid(const char *, spa_feature_t *); +_ZFEATURE_COMMON_H int zfeature_lookup_name(const char *, spa_feature_t *); +_ZFEATURE_COMMON_H boolean_t zfeature_depends_on(spa_feature_t, spa_feature_t); -extern void zpool_feature_init(void); +_ZFEATURE_COMMON_H void zpool_feature_init(void); #ifdef __cplusplus } diff --git a/sys/contrib/openzfs/include/zfs_comutil.h b/sys/contrib/openzfs/include/zfs_comutil.h index 17b07d9e4b0..3e4716224a0 100644 --- a/sys/contrib/openzfs/include/zfs_comutil.h +++ b/sys/contrib/openzfs/include/zfs_comutil.h @@ -24,7 +24,7 @@ */ #ifndef _ZFS_COMUTIL_H -#define _ZFS_COMUTIL_H +#define _ZFS_COMUTIL_H extern __attribute__((visibility("default"))) #include #include @@ -33,17 +33,18 @@ extern "C" { #endif -extern boolean_t zfs_allocatable_devs(nvlist_t *); -extern boolean_t zfs_special_devs(nvlist_t *, char *); -extern void zpool_get_load_policy(nvlist_t *, zpool_load_policy_t *); +_ZFS_COMUTIL_H boolean_t zfs_allocatable_devs(nvlist_t *); +_ZFS_COMUTIL_H boolean_t zfs_special_devs(nvlist_t *, char *); +_ZFS_COMUTIL_H void zpool_get_load_policy(nvlist_t *, zpool_load_policy_t *); -extern int zfs_zpl_version_map(int spa_version); -extern int zfs_spa_version_map(int zpl_version); +_ZFS_COMUTIL_H int zfs_zpl_version_map(int spa_version); +_ZFS_COMUTIL_H int zfs_spa_version_map(int zpl_version); -extern boolean_t zfs_dataset_name_hidden(const char *); +_ZFS_COMUTIL_H boolean_t zfs_dataset_name_hidden(const char *); #define ZFS_NUM_LEGACY_HISTORY_EVENTS 41 -extern const char *zfs_history_event_names[ZFS_NUM_LEGACY_HISTORY_EVENTS]; +_ZFS_COMUTIL_H const char * + zfs_history_event_names[ZFS_NUM_LEGACY_HISTORY_EVENTS]; #ifdef __cplusplus } diff --git a/sys/contrib/openzfs/include/zfs_deleg.h b/sys/contrib/openzfs/include/zfs_deleg.h index 5738b2a73dc..1ae08850fbe 100644 --- a/sys/contrib/openzfs/include/zfs_deleg.h +++ b/sys/contrib/openzfs/include/zfs_deleg.h @@ -25,7 +25,7 @@ */ #ifndef _ZFS_DELEG_H -#define _ZFS_DELEG_H +#define _ZFS_DELEG_H extern __attribute__((visibility("default"))) #include @@ -85,12 +85,12 @@ typedef struct zfs_deleg_perm_tab { zfs_deleg_note_t z_note; } zfs_deleg_perm_tab_t; -extern zfs_deleg_perm_tab_t zfs_deleg_perm_tab[]; +_ZFS_DELEG_H zfs_deleg_perm_tab_t zfs_deleg_perm_tab[]; -int zfs_deleg_verify_nvlist(nvlist_t *nvlist); -void zfs_deleg_whokey(char *attr, zfs_deleg_who_type_t type, +_ZFS_DELEG_H int zfs_deleg_verify_nvlist(nvlist_t *nvlist); +_ZFS_DELEG_H void zfs_deleg_whokey(char *attr, zfs_deleg_who_type_t type, char checkflag, void *data); -const char *zfs_deleg_canonicalize_perm(const char *perm); +_ZFS_DELEG_H const char *zfs_deleg_canonicalize_perm(const char *perm); #ifdef __cplusplus } diff --git a/sys/contrib/openzfs/include/zfs_fletcher.h b/sys/contrib/openzfs/include/zfs_fletcher.h index 9e8b2cf7c72..bb356c59acb 100644 --- a/sys/contrib/openzfs/include/zfs_fletcher.h +++ b/sys/contrib/openzfs/include/zfs_fletcher.h @@ -27,7 +27,7 @@ */ #ifndef _ZFS_FLETCHER_H -#define _ZFS_FLETCHER_H +#define _ZFS_FLETCHER_H extern __attribute__((visibility("default"))) #include #include @@ -48,19 +48,24 @@ extern "C" { * checksum method is added. This method will ignore last (size % 4) bytes of * the data buffer. */ -void fletcher_init(zio_cksum_t *); -void fletcher_2_native(const void *, uint64_t, const void *, zio_cksum_t *); -void fletcher_2_byteswap(const void *, uint64_t, const void *, zio_cksum_t *); -void fletcher_4_native(const void *, uint64_t, const void *, zio_cksum_t *); -int fletcher_2_incremental_native(void *, size_t, void *); -int fletcher_2_incremental_byteswap(void *, size_t, void *); -void fletcher_4_native_varsize(const void *, uint64_t, zio_cksum_t *); -void fletcher_4_byteswap(const void *, uint64_t, const void *, zio_cksum_t *); -int fletcher_4_incremental_native(void *, size_t, void *); -int fletcher_4_incremental_byteswap(void *, size_t, void *); -int fletcher_4_impl_set(const char *selector); -void fletcher_4_init(void); -void fletcher_4_fini(void); +_ZFS_FLETCHER_H void fletcher_init(zio_cksum_t *); +_ZFS_FLETCHER_H void fletcher_2_native(const void *, uint64_t, const void *, + zio_cksum_t *); +_ZFS_FLETCHER_H void fletcher_2_byteswap(const void *, uint64_t, const void *, + zio_cksum_t *); +_ZFS_FLETCHER_H void fletcher_4_native(const void *, uint64_t, const void *, + zio_cksum_t *); +_ZFS_FLETCHER_H int fletcher_2_incremental_native(void *, size_t, void *); +_ZFS_FLETCHER_H int fletcher_2_incremental_byteswap(void *, size_t, void *); +_ZFS_FLETCHER_H void fletcher_4_native_varsize(const void *, uint64_t, + zio_cksum_t *); +_ZFS_FLETCHER_H void fletcher_4_byteswap(const void *, uint64_t, const void *, + zio_cksum_t *); +_ZFS_FLETCHER_H int fletcher_4_incremental_native(void *, size_t, void *); +_ZFS_FLETCHER_H int fletcher_4_incremental_byteswap(void *, size_t, void *); +_ZFS_FLETCHER_H int fletcher_4_impl_set(const char *selector); +_ZFS_FLETCHER_H void fletcher_4_init(void); +_ZFS_FLETCHER_H void fletcher_4_fini(void); @@ -124,31 +129,31 @@ typedef struct fletcher_4_func { const char *name; } fletcher_4_ops_t; -extern const fletcher_4_ops_t fletcher_4_superscalar_ops; -extern const fletcher_4_ops_t fletcher_4_superscalar4_ops; +_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_superscalar_ops; +_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_superscalar4_ops; #if defined(HAVE_SSE2) -extern const fletcher_4_ops_t fletcher_4_sse2_ops; +_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_sse2_ops; #endif #if defined(HAVE_SSE2) && defined(HAVE_SSSE3) -extern const fletcher_4_ops_t fletcher_4_ssse3_ops; +_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_ssse3_ops; #endif #if defined(HAVE_AVX) && defined(HAVE_AVX2) -extern const fletcher_4_ops_t fletcher_4_avx2_ops; +_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_avx2_ops; #endif #if defined(__x86_64) && defined(HAVE_AVX512F) -extern const fletcher_4_ops_t fletcher_4_avx512f_ops; +_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_avx512f_ops; #endif #if defined(__x86_64) && defined(HAVE_AVX512BW) -extern const fletcher_4_ops_t fletcher_4_avx512bw_ops; +_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_avx512bw_ops; #endif #if defined(__aarch64__) -extern const fletcher_4_ops_t fletcher_4_aarch64_neon_ops; +_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_aarch64_neon_ops; #endif #ifdef __cplusplus diff --git a/sys/contrib/openzfs/include/zfs_namecheck.h b/sys/contrib/openzfs/include/zfs_namecheck.h index 197c40b56e8..4739b065c51 100644 --- a/sys/contrib/openzfs/include/zfs_namecheck.h +++ b/sys/contrib/openzfs/include/zfs_namecheck.h @@ -27,7 +27,7 @@ */ #ifndef _ZFS_NAMECHECK_H -#define _ZFS_NAMECHECK_H +#define _ZFS_NAMECHECK_H extern __attribute__((visibility("default"))) #ifdef __cplusplus extern "C" { @@ -51,18 +51,22 @@ typedef enum { #define ZFS_PERMSET_MAXLEN 64 -extern int zfs_max_dataset_nesting; +_ZFS_NAMECHECK_H int zfs_max_dataset_nesting; -int get_dataset_depth(const char *); -int pool_namecheck(const char *, namecheck_err_t *, char *); -int entity_namecheck(const char *, namecheck_err_t *, char *); -int dataset_namecheck(const char *, namecheck_err_t *, char *); -int snapshot_namecheck(const char *, namecheck_err_t *, char *); -int bookmark_namecheck(const char *, namecheck_err_t *, char *); -int dataset_nestcheck(const char *); -int mountpoint_namecheck(const char *, namecheck_err_t *); -int zfs_component_namecheck(const char *, namecheck_err_t *, char *); -int permset_namecheck(const char *, namecheck_err_t *, char *); +_ZFS_NAMECHECK_H int get_dataset_depth(const char *); +_ZFS_NAMECHECK_H int pool_namecheck(const char *, namecheck_err_t *, char *); +_ZFS_NAMECHECK_H int entity_namecheck(const char *, namecheck_err_t *, char *); +_ZFS_NAMECHECK_H int dataset_namecheck(const char *, namecheck_err_t *, char *); +_ZFS_NAMECHECK_H int snapshot_namecheck(const char *, namecheck_err_t *, + char *); +_ZFS_NAMECHECK_H int bookmark_namecheck(const char *, namecheck_err_t *, + char *); +_ZFS_NAMECHECK_H int dataset_nestcheck(const char *); +_ZFS_NAMECHECK_H int mountpoint_namecheck(const char *, namecheck_err_t *); +_ZFS_NAMECHECK_H int zfs_component_namecheck(const char *, namecheck_err_t *, + char *); +_ZFS_NAMECHECK_H int permset_namecheck(const char *, namecheck_err_t *, + char *); #ifdef __cplusplus } diff --git a/sys/contrib/openzfs/include/zfs_prop.h b/sys/contrib/openzfs/include/zfs_prop.h index 89b6a20243f..91b5032e705 100644 --- a/sys/contrib/openzfs/include/zfs_prop.h +++ b/sys/contrib/openzfs/include/zfs_prop.h @@ -24,7 +24,7 @@ */ #ifndef _ZFS_PROP_H -#define _ZFS_PROP_H +#define _ZFS_PROP_H extern __attribute__((visibility("default"))) #include #include @@ -87,44 +87,46 @@ typedef struct { /* * zfs dataset property functions */ -void zfs_prop_init(void); -zprop_type_t zfs_prop_get_type(zfs_prop_t); -boolean_t zfs_prop_delegatable(zfs_prop_t prop); -zprop_desc_t *zfs_prop_get_table(void); +_ZFS_PROP_H void zfs_prop_init(void); +_ZFS_PROP_H zprop_type_t zfs_prop_get_type(zfs_prop_t); +_ZFS_PROP_H boolean_t zfs_prop_delegatable(zfs_prop_t prop); +_ZFS_PROP_H zprop_desc_t *zfs_prop_get_table(void); /* * zpool property functions */ -void zpool_prop_init(void); -zprop_type_t zpool_prop_get_type(zpool_prop_t); -zprop_desc_t *zpool_prop_get_table(void); +_ZFS_PROP_H void zpool_prop_init(void); +_ZFS_PROP_H zprop_type_t zpool_prop_get_type(zpool_prop_t); +_ZFS_PROP_H zprop_desc_t *zpool_prop_get_table(void); /* * Common routines to initialize property tables */ -void zprop_register_impl(int, const char *, zprop_type_t, uint64_t, +_ZFS_PROP_H void zprop_register_impl(int, const char *, zprop_type_t, uint64_t, const char *, zprop_attr_t, int, const char *, const char *, boolean_t, boolean_t, const zprop_index_t *); -void zprop_register_string(int, const char *, const char *, +_ZFS_PROP_H void zprop_register_string(int, const char *, const char *, zprop_attr_t attr, int, const char *, const char *); -void zprop_register_number(int, const char *, uint64_t, zprop_attr_t, int, - const char *, const char *); -void zprop_register_index(int, const char *, uint64_t, zprop_attr_t, int, - const char *, const char *, const zprop_index_t *); -void zprop_register_hidden(int, const char *, zprop_type_t, zprop_attr_t, - int, const char *); +_ZFS_PROP_H void zprop_register_number(int, const char *, uint64_t, + zprop_attr_t, int, const char *, const char *); +_ZFS_PROP_H void zprop_register_index(int, const char *, uint64_t, zprop_attr_t, + int, const char *, const char *, const zprop_index_t *); +_ZFS_PROP_H void zprop_register_hidden(int, const char *, zprop_type_t, + zprop_attr_t, int, const char *); /* * Common routines for zfs and zpool property management */ -int zprop_iter_common(zprop_func, void *, boolean_t, boolean_t, zfs_type_t); -int zprop_name_to_prop(const char *, zfs_type_t); -int zprop_string_to_index(int, const char *, uint64_t *, zfs_type_t); -int zprop_index_to_string(int, uint64_t, const char **, zfs_type_t); -uint64_t zprop_random_value(int, uint64_t, zfs_type_t); -const char *zprop_values(int, zfs_type_t); -size_t zprop_width(int, boolean_t *, zfs_type_t); -boolean_t zprop_valid_for_type(int, zfs_type_t, boolean_t); +_ZFS_PROP_H int zprop_iter_common(zprop_func, void *, boolean_t, boolean_t, + zfs_type_t); +_ZFS_PROP_H int zprop_name_to_prop(const char *, zfs_type_t); +_ZFS_PROP_H int zprop_string_to_index(int, const char *, uint64_t *, + zfs_type_t); +_ZFS_PROP_H int zprop_index_to_string(int, uint64_t, const char **, zfs_type_t); +_ZFS_PROP_H uint64_t zprop_random_value(int, uint64_t, zfs_type_t); +_ZFS_PROP_H const char *zprop_values(int, zfs_type_t); +_ZFS_PROP_H size_t zprop_width(int, boolean_t *, zfs_type_t); +_ZFS_PROP_H boolean_t zprop_valid_for_type(int, zfs_type_t, boolean_t); #ifdef __cplusplus } diff --git a/sys/contrib/openzfs/lib/libefi/rdwr_efi.c b/sys/contrib/openzfs/lib/libefi/rdwr_efi.c index ca7a760b649..1e022cc8eea 100644 --- a/sys/contrib/openzfs/lib/libefi/rdwr_efi.c +++ b/sys/contrib/openzfs/lib/libefi/rdwr_efi.c @@ -218,22 +218,15 @@ read_disk_info(int fd, diskaddr_t *capacity, uint_t *lbsize) static char * efi_get_devname(int fd) { - char *path; - char *dev_name; - - path = calloc(1, PATH_MAX); - if (path == NULL) - return (NULL); + char path[32]; /* * The libefi API only provides the open fd and not the file path. * To handle this realpath(3) is used to resolve the block device * name from /proc/self/fd/. */ - (void) sprintf(path, "/proc/self/fd/%d", fd); - dev_name = realpath(path, NULL); - free(path); - return (dev_name); + (void) snprintf(path, sizeof (path), "/proc/self/fd/%d", fd); + return (realpath(path, NULL)); } static int diff --git a/sys/contrib/openzfs/lib/libnvpair/libnvpair.abi b/sys/contrib/openzfs/lib/libnvpair/libnvpair.abi index c1b50a8aa39..697a67b7fc6 100644 --- a/sys/contrib/openzfs/lib/libnvpair/libnvpair.abi +++ b/sys/contrib/openzfs/lib/libnvpair/libnvpair.abi @@ -1,6 +1,5 @@ - @@ -231,7 +230,7 @@ - + @@ -241,59 +240,814 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - + - + - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -324,2482 +1078,2571 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - + + + + + - - - - + + + + + - - - - + + + + - - - - + + + + + + - - - - + + + + + + - - - - + + + + + + - - - - + + + + + + - - - - + + + + + + - - - - + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + - - - - + + + - - - - + + + - - - - + + + - - - - + + + - - - - + + + - - - - - - + + + + + + + - - - - - - + + + - - - - - - + + + - - - - - - + + + - - - - - - + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + - - - - - - + + + - - - - - - + + + - - - - - - + + + - - - - - - + + + + + - - - - + + + + + - - - - - + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + + - - - - - + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - + + + + + - - - + + + + + - - - - + + + + + - - - + + + + + - - - - + + + + + - - - - + + + + + - - - - + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + diff --git a/sys/contrib/openzfs/lib/libnvpair/libnvpair_json.c b/sys/contrib/openzfs/lib/libnvpair/libnvpair_json.c index 37a392391fb..15b6f4afaf7 100644 --- a/sys/contrib/openzfs/lib/libnvpair/libnvpair_json.c +++ b/sys/contrib/openzfs/lib/libnvpair/libnvpair_json.c @@ -54,6 +54,13 @@ nvlist_print_json_string(FILE *fp, const char *input) FPRINTF(fp, "\""); while ((sz = mbrtowc(&c, input, MB_CUR_MAX, &mbr)) > 0) { + if (sz == (size_t)-1 || sz == (size_t)-2) { + /* + * We last read an invalid multibyte character sequence, + * so return an error. + */ + return (-1); + } switch (c) { case '"': FPRINTF(fp, "\\\""); @@ -97,14 +104,6 @@ nvlist_print_json_string(FILE *fp, const char *input) input += sz; } - if (sz == (size_t)-1 || sz == (size_t)-2) { - /* - * We last read an invalid multibyte character sequence, - * so return an error. - */ - return (-1); - } - FPRINTF(fp, "\""); return (0); } diff --git a/sys/contrib/openzfs/lib/libshare/Makefile.am b/sys/contrib/openzfs/lib/libshare/Makefile.am index 7cef13c3da7..e42609c6496 100644 --- a/sys/contrib/openzfs/lib/libshare/Makefile.am +++ b/sys/contrib/openzfs/lib/libshare/Makefile.am @@ -7,6 +7,7 @@ noinst_LTLIBRARIES = libshare.la USER_C = \ libshare_impl.h \ libshare.c \ + nfs.c \ nfs.h \ smb.h diff --git a/sys/contrib/openzfs/lib/libshare/libshare.c b/sys/contrib/openzfs/lib/libshare/libshare.c index d32a282a36e..a228645fbf8 100644 --- a/sys/contrib/openzfs/lib/libshare/libshare.c +++ b/sys/contrib/openzfs/lib/libshare/libshare.c @@ -36,7 +36,6 @@ #include #include #include -#include "libzfs_impl.h" #include "libshare_impl.h" #include "nfs.h" #include "smb.h" diff --git a/sys/contrib/openzfs/lib/libshare/libshare_impl.h b/sys/contrib/openzfs/lib/libshare/libshare_impl.h index cc5ef40085b..63a6907539e 100644 --- a/sys/contrib/openzfs/lib/libshare/libshare_impl.h +++ b/sys/contrib/openzfs/lib/libshare/libshare_impl.h @@ -24,6 +24,8 @@ * Copyright (c) 2011 Gunnar Beutner * Copyright (c) 2019, 2020 by Delphix. All rights reserved. */ +#ifndef _LIBSPL_LIBSHARE_IMPL_H +#define _LIBSPL_LIBSHARE_IMPL_H typedef struct sa_share_fsinfo { char *shareopts; @@ -59,3 +61,5 @@ typedef struct sa_fstype { } sa_fstype_t; sa_fstype_t *register_fstype(const char *name, const sa_share_ops_t *ops); + +#endif /* _LIBSPL_LIBSHARE_IMPL_H */ diff --git a/sys/contrib/openzfs/lib/libshare/nfs.c b/sys/contrib/openzfs/lib/libshare/nfs.c new file mode 100644 index 00000000000..44d3e93d42f --- /dev/null +++ b/sys/contrib/openzfs/lib/libshare/nfs.c @@ -0,0 +1,157 @@ +/* + * 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 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include "nfs.h" + + +static int nfs_lock_fd = -1; + + +/* + * nfs_exports_[lock|unlock] are used to guard against conconcurrent + * updates to the exports file. Each protocol is responsible for + * providing the necessary locking to ensure consistency. + */ +static int +nfs_exports_lock(const char *name) +{ + int err; + + nfs_lock_fd = open(name, O_RDWR | O_CREAT | O_CLOEXEC, 0600); + if (nfs_lock_fd == -1) { + err = errno; + fprintf(stderr, "failed to lock %s: %s\n", name, strerror(err)); + return (err); + } + + if (flock(nfs_lock_fd, LOCK_EX) != 0) { + err = errno; + fprintf(stderr, "failed to lock %s: %s\n", name, strerror(err)); + (void) close(nfs_lock_fd); + nfs_lock_fd = -1; + return (err); + } + + return (0); +} + +static void +nfs_exports_unlock(const char *name) +{ + verify(nfs_lock_fd > 0); + + if (flock(nfs_lock_fd, LOCK_UN) != 0) { + fprintf(stderr, "failed to unlock %s: %s\n", + name, strerror(errno)); + } + + (void) close(nfs_lock_fd); + nfs_lock_fd = -1; +} + +static char * +nfs_init_tmpfile(const char *prefix, const char *mdir) +{ + char *tmpfile = NULL; + struct stat sb; + + if (mdir != NULL && + stat(mdir, &sb) < 0 && + mkdir(mdir, 0755) < 0) { + fprintf(stderr, "failed to create %s: %s\n", + mdir, strerror(errno)); + return (NULL); + } + + if (asprintf(&tmpfile, "%s.XXXXXXXX", prefix) == -1) { + fprintf(stderr, "Unable to allocate temporary file\n"); + return (NULL); + } + + int fd = mkostemp(tmpfile, O_CLOEXEC); + if (fd == -1) { + fprintf(stderr, "Unable to create temporary file: %s", + strerror(errno)); + free(tmpfile); + return (NULL); + } + close(fd); + return (tmpfile); +} + +static int +nfs_fini_tmpfile(const char *exports, char *tmpfile) +{ + if (rename(tmpfile, exports) == -1) { + fprintf(stderr, "Unable to rename %s: %s\n", tmpfile, + strerror(errno)); + unlink(tmpfile); + free(tmpfile); + return (SA_SYSTEM_ERR); + } + free(tmpfile); + return (SA_OK); +} + +__attribute__((visibility("hidden"))) int +nfs_toggle_share(const char *lockfile, const char *exports, + const char *expdir, sa_share_impl_t impl_share, + int(*cbk)(sa_share_impl_t impl_share, char *filename)) +{ + int error; + char *filename; + + if ((filename = nfs_init_tmpfile(exports, expdir)) == NULL) + return (SA_SYSTEM_ERR); + + error = nfs_exports_lock(lockfile); + if (error != 0) { + unlink(filename); + free(filename); + return (error); + } + + error = nfs_copy_entries(filename, impl_share->sa_mountpoint); + if (error != SA_OK) + goto fullerr; + + error = cbk(impl_share, filename); + if (error != SA_OK) + goto fullerr; + + error = nfs_fini_tmpfile(exports, filename); + nfs_exports_unlock(lockfile); + return (error); + +fullerr: + unlink(filename); + free(filename); + nfs_exports_unlock(lockfile); + return (error); +} diff --git a/sys/contrib/openzfs/lib/libshare/nfs.h b/sys/contrib/openzfs/lib/libshare/nfs.h index b9ea6ee2f8c..4dbcdf59859 100644 --- a/sys/contrib/openzfs/lib/libshare/nfs.h +++ b/sys/contrib/openzfs/lib/libshare/nfs.h @@ -24,4 +24,13 @@ * Copyright (c) 2011 Gunnar Beutner */ +#include "libshare_impl.h" + +#define FILE_HEADER "# !!! DO NOT EDIT THIS FILE MANUALLY !!!\n\n" + void libshare_nfs_init(void); + +int nfs_copy_entries(char *filename, const char *mountpoint); +int nfs_toggle_share(const char *lockfile, const char *exports, + const char *expdir, sa_share_impl_t impl_share, + int(*cbk)(sa_share_impl_t impl_share, char *filename)); diff --git a/sys/contrib/openzfs/lib/libshare/os/freebsd/nfs.c b/sys/contrib/openzfs/lib/libshare/os/freebsd/nfs.c index 5951b9eafa2..b82491f2ebe 100644 --- a/sys/contrib/openzfs/lib/libshare/os/freebsd/nfs.c +++ b/sys/contrib/openzfs/lib/libshare/os/freebsd/nfs.c @@ -42,12 +42,11 @@ __FBSDID("$FreeBSD$"); #include #include -#include "libzfs_impl.h" +#include #include "libshare_impl.h" #include "nfs.h" #define _PATH_MOUNTDPID "/var/run/mountd.pid" -#define FILE_HEADER "# !!! DO NOT EDIT THIS FILE MANUALLY !!!\n\n" #define OPTSSIZE 1024 #define MAXLINESIZE (PATH_MAX + OPTSSIZE) #define ZFS_EXPORTS_FILE "/etc/zfs/exports" @@ -55,44 +54,6 @@ __FBSDID("$FreeBSD$"); static sa_fstype_t *nfs_fstype; -static int nfs_lock_fd = -1; - -/* - * The nfs_exports_[lock|unlock] is used to guard against conconcurrent - * updates to the exports file. Each protocol is responsible for - * providing the necessary locking to ensure consistency. - */ -static int -nfs_exports_lock(void) -{ - nfs_lock_fd = open(ZFS_EXPORTS_LOCK, - O_RDWR | O_CREAT, 0600); - if (nfs_lock_fd == -1) { - fprintf(stderr, "failed to lock %s: %s\n", - ZFS_EXPORTS_LOCK, strerror(errno)); - return (errno); - } - if (flock(nfs_lock_fd, LOCK_EX) != 0) { - fprintf(stderr, "failed to lock %s: %s\n", - ZFS_EXPORTS_LOCK, strerror(errno)); - return (errno); - } - return (0); -} - -static void -nfs_exports_unlock(void) -{ - verify(nfs_lock_fd > 0); - - if (flock(nfs_lock_fd, LOCK_UN) != 0) { - fprintf(stderr, "failed to unlock %s: %s\n", - ZFS_EXPORTS_LOCK, strerror(errno)); - } - close(nfs_lock_fd); - nfs_lock_fd = -1; -} - /* * Read one line from a file. Skip comments, empty lines and a line with a * mountpoint specified in the 'skip' argument. @@ -182,54 +143,18 @@ translate_opts(const char *shareopts) return (newopts); } -static char * -nfs_init_tmpfile(void) -{ - char *tmpfile = NULL; - - if (asprintf(&tmpfile, "%s%s", ZFS_EXPORTS_FILE, ".XXXXXXXX") == -1) { - fprintf(stderr, "Unable to allocate buffer for temporary " - "file name\n"); - return (NULL); - } - - int fd = mkstemp(tmpfile); - if (fd == -1) { - fprintf(stderr, "Unable to create temporary file: %s", - strerror(errno)); - free(tmpfile); - return (NULL); - } - close(fd); - return (tmpfile); -} - -static int -nfs_fini_tmpfile(char *tmpfile) -{ - if (rename(tmpfile, ZFS_EXPORTS_FILE) == -1) { - fprintf(stderr, "Unable to rename %s: %s\n", tmpfile, - strerror(errno)); - unlink(tmpfile); - free(tmpfile); - return (SA_SYSTEM_ERR); - } - free(tmpfile); - return (SA_OK); -} - /* * This function copies all entries from the exports file to "filename", * omitting any entries for the specified mountpoint. */ -static int +__attribute__((visibility("hidden"))) int nfs_copy_entries(char *filename, const char *mountpoint) { int error = SA_OK; char *line; - FILE *oldfp = fopen(ZFS_EXPORTS_FILE, "r"); - FILE *newfp = fopen(filename, "w+"); + FILE *oldfp = fopen(ZFS_EXPORTS_FILE, "re"); + FILE *newfp = fopen(filename, "w+e"); if (newfp == NULL) { fprintf(stderr, "failed to open %s file: %s", filename, strerror(errno)); @@ -268,38 +193,15 @@ nfs_copy_entries(char *filename, const char *mountpoint) } static int -nfs_enable_share(sa_share_impl_t impl_share) +nfs_enable_share_impl(sa_share_impl_t impl_share, char *filename) { - char *filename = NULL; - int error; - - if ((filename = nfs_init_tmpfile()) == NULL) - return (SA_SYSTEM_ERR); - - error = nfs_exports_lock(); - if (error != 0) { - unlink(filename); - free(filename); - return (error); - } - - error = nfs_copy_entries(filename, impl_share->sa_mountpoint); - if (error != SA_OK) { - unlink(filename); - free(filename); - nfs_exports_unlock(); - return (error); - } - - FILE *fp = fopen(filename, "a+"); + FILE *fp = fopen(filename, "a+e"); if (fp == NULL) { fprintf(stderr, "failed to open %s file: %s", filename, strerror(errno)); - unlink(filename); - free(filename); - nfs_exports_unlock(); return (SA_SYSTEM_ERR); } + char *shareopts = FSINFO(impl_share, nfs_fstype)->shareopts; if (strcmp(shareopts, "on") == 0) shareopts = ""; @@ -308,67 +210,49 @@ nfs_enable_share(sa_share_impl_t impl_share) translate_opts(shareopts)) < 0) { fprintf(stderr, "failed to write to %s\n", filename); fclose(fp); - unlink(filename); - free(filename); - nfs_exports_unlock(); return (SA_SYSTEM_ERR); } if (fclose(fp) != 0) { fprintf(stderr, "Unable to close file %s: %s\n", filename, strerror(errno)); - unlink(filename); - free(filename); - nfs_exports_unlock(); return (SA_SYSTEM_ERR); } - error = nfs_fini_tmpfile(filename); - nfs_exports_unlock(); - return (error); + + return (SA_OK); +} + +static int +nfs_enable_share(sa_share_impl_t impl_share) +{ + return (nfs_toggle_share( + ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, NULL, impl_share, + nfs_enable_share_impl)); +} + +static int +nfs_disable_share_impl(sa_share_impl_t impl_share, char *filename) +{ + return (SA_OK); } static int nfs_disable_share(sa_share_impl_t impl_share) { - int error; - char *filename = NULL; - - if ((filename = nfs_init_tmpfile()) == NULL) - return (SA_SYSTEM_ERR); - - error = nfs_exports_lock(); - if (error != 0) { - unlink(filename); - free(filename); - return (error); - } - - error = nfs_copy_entries(filename, impl_share->sa_mountpoint); - if (error != SA_OK) { - unlink(filename); - free(filename); - nfs_exports_unlock(); - return (error); - } - - error = nfs_fini_tmpfile(filename); - nfs_exports_unlock(); - return (error); + return (nfs_toggle_share( + ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, NULL, impl_share, + nfs_disable_share_impl)); } -/* - * NOTE: This function returns a static buffer and thus is not thread-safe. - */ static boolean_t nfs_is_shared(sa_share_impl_t impl_share) { - static char line[MAXLINESIZE]; - char *s, last; + char *s, last, line[MAXLINESIZE]; size_t len; char *mntpoint = impl_share->sa_mountpoint; size_t mntlen = strlen(mntpoint); - FILE *fp = fopen(ZFS_EXPORTS_FILE, "r"); + FILE *fp = fopen(ZFS_EXPORTS_FILE, "re"); if (fp == NULL) return (B_FALSE); diff --git a/sys/contrib/openzfs/lib/libshare/os/linux/nfs.c b/sys/contrib/openzfs/lib/libshare/os/linux/nfs.c index 1efa321b7bc..c236f25698f 100644 --- a/sys/contrib/openzfs/lib/libshare/os/linux/nfs.c +++ b/sys/contrib/openzfs/lib/libshare/os/linux/nfs.c @@ -42,7 +42,6 @@ #include "libshare_impl.h" #include "nfs.h" -#define FILE_HEADER "# !!! DO NOT EDIT THIS FILE MANUALLY !!!\n\n" #define ZFS_EXPORTS_DIR "/etc/exports.d" #define ZFS_EXPORTS_FILE ZFS_EXPORTS_DIR"/zfs.exports" #define ZFS_EXPORTS_LOCK ZFS_EXPORTS_FILE".lock" @@ -55,44 +54,6 @@ typedef int (*nfs_shareopt_callback_t)(const char *opt, const char *value, typedef int (*nfs_host_callback_t)(const char *sharepath, const char *filename, const char *host, const char *security, const char *access, void *cookie); -static int nfs_lock_fd = -1; - -/* - * The nfs_exports_[lock|unlock] is used to guard against conconcurrent - * updates to the exports file. Each protocol is responsible for - * providing the necessary locking to ensure consistency. - */ -static int -nfs_exports_lock(void) -{ - nfs_lock_fd = open(ZFS_EXPORTS_LOCK, - O_RDWR | O_CREAT, 0600); - if (nfs_lock_fd == -1) { - fprintf(stderr, "failed to lock %s: %s\n", - ZFS_EXPORTS_LOCK, strerror(errno)); - return (errno); - } - if (flock(nfs_lock_fd, LOCK_EX) != 0) { - fprintf(stderr, "failed to lock %s: %s\n", - ZFS_EXPORTS_LOCK, strerror(errno)); - return (errno); - } - return (0); -} - -static void -nfs_exports_unlock(void) -{ - verify(nfs_lock_fd > 0); - - if (flock(nfs_lock_fd, LOCK_UN) != 0) { - fprintf(stderr, "failed to unlock %s: %s\n", - ZFS_EXPORTS_LOCK, strerror(errno)); - } - close(nfs_lock_fd); - nfs_lock_fd = -1; -} - /* * Invokes the specified callback function for each Solaris share option * listed in the specified string. @@ -389,49 +350,6 @@ get_linux_shareopts(const char *shareopts, char **plinux_opts) return (error); } -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"); - return (NULL); - } - - int fd = mkstemp(tmpfile); - if (fd == -1) { - fprintf(stderr, "Unable to create temporary file: %s", - strerror(errno)); - free(tmpfile); - return (NULL); - } - close(fd); - return (tmpfile); -} - -static int -nfs_fini_tmpfile(char *tmpfile) -{ - if (rename(tmpfile, ZFS_EXPORTS_FILE) == -1) { - fprintf(stderr, "Unable to rename %s: %s\n", tmpfile, - strerror(errno)); - unlink(tmpfile); - free(tmpfile); - return (SA_SYSTEM_ERR); - } - free(tmpfile); - return (SA_OK); -} - /* * This function populates an entry into /etc/exports.d/zfs.exports. * This file is consumed by the linux nfs server so that zfs shares are @@ -453,7 +371,7 @@ nfs_add_entry(const char *filename, const char *sharepath, if (linux_opts == NULL) linux_opts = ""; - FILE *fp = fopen(filename, "a+"); + FILE *fp = fopen(filename, "a+e"); if (fp == NULL) { fprintf(stderr, "failed to open %s file: %s", filename, strerror(errno)); @@ -482,15 +400,15 @@ nfs_add_entry(const char *filename, const char *sharepath, * This function copies all entries from the exports file to "filename", * omitting any entries for the specified mountpoint. */ -static int +__attribute__((visibility("hidden"))) int nfs_copy_entries(char *filename, const char *mountpoint) { char *buf = NULL; size_t buflen = 0; int error = SA_OK; - FILE *oldfp = fopen(ZFS_EXPORTS_FILE, "r"); - FILE *newfp = fopen(filename, "w+"); + FILE *oldfp = fopen(ZFS_EXPORTS_FILE, "re"); + FILE *newfp = fopen(filename, "w+e"); if (newfp == NULL) { fprintf(stderr, "failed to open %s file: %s", filename, strerror(errno)); @@ -549,81 +467,45 @@ nfs_copy_entries(char *filename, const char *mountpoint) * Enables NFS sharing for the specified share. */ static int -nfs_enable_share(sa_share_impl_t impl_share) +nfs_enable_share_impl(sa_share_impl_t impl_share, char *filename) { char *shareopts, *linux_opts; - char *filename = NULL; int error; - if ((filename = nfs_init_tmpfile()) == NULL) - return (SA_SYSTEM_ERR); - - error = nfs_exports_lock(); - if (error != 0) { - unlink(filename); - free(filename); - return (error); - } - - error = nfs_copy_entries(filename, impl_share->sa_mountpoint); - if (error != SA_OK) { - unlink(filename); - free(filename); - nfs_exports_unlock(); - return (error); - } - shareopts = FSINFO(impl_share, nfs_fstype)->shareopts; error = get_linux_shareopts(shareopts, &linux_opts); - if (error != SA_OK) { - unlink(filename); - free(filename); - nfs_exports_unlock(); + if (error != SA_OK) return (error); - } error = foreach_nfs_host(impl_share, filename, nfs_add_entry, linux_opts); free(linux_opts); - if (error == 0) { - error = nfs_fini_tmpfile(filename); - } else { - unlink(filename); - free(filename); - } - nfs_exports_unlock(); return (error); } +static int +nfs_enable_share(sa_share_impl_t impl_share) +{ + return (nfs_toggle_share( + ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, ZFS_EXPORTS_DIR, impl_share, + nfs_enable_share_impl)); +} + /* * Disables NFS sharing for the specified share. */ +static int +nfs_disable_share_impl(sa_share_impl_t impl_share, char *filename) +{ + return (SA_OK); +} + static int nfs_disable_share(sa_share_impl_t impl_share) { - int error; - char *filename = NULL; - - if ((filename = nfs_init_tmpfile()) == NULL) - return (SA_SYSTEM_ERR); - - error = nfs_exports_lock(); - if (error != 0) { - unlink(filename); - free(filename); - return (error); - } - - error = nfs_copy_entries(filename, impl_share->sa_mountpoint); - if (error != SA_OK) { - unlink(filename); - free(filename); - nfs_exports_unlock(); - return (error); - } - error = nfs_fini_tmpfile(filename); - nfs_exports_unlock(); - return (error); + return (nfs_toggle_share( + ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, ZFS_EXPORTS_DIR, impl_share, + nfs_disable_share_impl)); } static boolean_t @@ -632,7 +514,7 @@ nfs_is_shared(sa_share_impl_t impl_share) size_t buflen = 0; char *buf = NULL; - FILE *fp = fopen(ZFS_EXPORTS_FILE, "r"); + FILE *fp = fopen(ZFS_EXPORTS_FILE, "re"); if (fp == NULL) { return (B_FALSE); } diff --git a/sys/contrib/openzfs/lib/libshare/os/linux/smb.c b/sys/contrib/openzfs/lib/libshare/os/linux/smb.c index 3dcf666eb69..9b18848e09c 100644 --- a/sys/contrib/openzfs/lib/libshare/os/linux/smb.c +++ b/sys/contrib/openzfs/lib/libshare/os/linux/smb.c @@ -107,7 +107,7 @@ smb_retrieve_shares(void) if (!S_ISREG(eStat.st_mode)) continue; - if ((share_file_fp = fopen(file_path, "r")) == NULL) { + if ((share_file_fp = fopen(file_path, "re")) == NULL) { rc = SA_SYSTEM_ERR; goto out; } @@ -308,7 +308,7 @@ smb_disable_share_one(const char *sharename) argv[2] = NET_CMD_ARG_HOST; argv[3] = (char *)"usershare"; argv[4] = (char *)"delete"; - argv[5] = strdup(sharename); + argv[5] = (char *)sharename; argv[6] = NULL; rc = libzfs_run_process(argv[0], argv, 0); diff --git a/sys/contrib/openzfs/lib/libspl/Makefile.am b/sys/contrib/openzfs/lib/libspl/Makefile.am index d27932aff98..8457df6dcdf 100644 --- a/sys/contrib/openzfs/lib/libspl/Makefile.am +++ b/sys/contrib/openzfs/lib/libspl/Makefile.am @@ -1,26 +1,16 @@ include $(top_srcdir)/config/Rules.am -if TARGET_CPU_I386 -TARGET_CPU_ATOMIC_SOURCE = asm-i386/atomic.S -else -if TARGET_CPU_X86_64 -TARGET_CPU_ATOMIC_SOURCE = asm-x86_64/atomic.S -else -TARGET_CPU_ATOMIC_SOURCE = asm-generic/atomic.c -endif -endif - SUBDIRS = include -AM_CCASFLAGS = \ - $(CFLAGS) - noinst_LTLIBRARIES = libspl_assert.la libspl.la libspl_assert_la_SOURCES = \ assert.c USER_C = \ + libspl_impl.h \ + atomic.c \ + getexecname.c \ list.c \ mkdirp.c \ page.c \ @@ -47,20 +37,11 @@ USER_C += \ os/freebsd/zone.c endif -libspl_la_SOURCES = \ - $(USER_C) \ - $(TARGET_CPU_ATOMIC_SOURCE) +libspl_la_SOURCES = $(USER_C) libspl_la_LIBADD = \ libspl_assert.la -libspl_la_LIBADD += $(LIBCLOCK_GETTIME) +libspl_la_LIBADD += $(LIBATOMIC_LIBS) $(LIBCLOCK_GETTIME) include $(top_srcdir)/config/CppCheck.am - -# Override the default SOURCES which includes TARGET_CPU_ATOMIC_SOURCE -# in order to always evaluate the generic asm-generic/atomic.c source. -CPPCHECKSRC = $(USER_C) asm-generic/atomic.c -cppcheck: - $(CPPCHECK) -j$(CPU_COUNT) $(CPPCHECKFLAGS) --force \ - $(DEFAULT_INCLUDES) $(CPPCHECKSRC) diff --git a/sys/contrib/openzfs/lib/libspl/asm-generic/.gitignore b/sys/contrib/openzfs/lib/libspl/asm-generic/.gitignore deleted file mode 100644 index 2792cf7b455..00000000000 --- a/sys/contrib/openzfs/lib/libspl/asm-generic/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/atomic.S diff --git a/sys/contrib/openzfs/lib/libspl/asm-i386/atomic.S b/sys/contrib/openzfs/lib/libspl/asm-i386/atomic.S deleted file mode 100644 index 7a574b0d172..00000000000 --- a/sys/contrib/openzfs/lib/libspl/asm-i386/atomic.S +++ /dev/null @@ -1,840 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - - .ident "%Z%%M% %I% %E% SMI" - - .file "%M%" - -#define _ASM -#ifdef __linux__ -#include -#elif __FreeBSD__ -#include -#define SET_SIZE(x) -#endif - ENTRY(atomic_inc_8) - ALTENTRY(atomic_inc_uchar) - movl 4(%esp), %eax - lock - incb (%eax) - ret - SET_SIZE(atomic_inc_uchar) - SET_SIZE(atomic_inc_8) - - ENTRY(atomic_inc_16) - ALTENTRY(atomic_inc_ushort) - movl 4(%esp), %eax - lock - incw (%eax) - ret - SET_SIZE(atomic_inc_ushort) - SET_SIZE(atomic_inc_16) - - ENTRY(atomic_inc_32) - ALTENTRY(atomic_inc_uint) - ALTENTRY(atomic_inc_ulong) - movl 4(%esp), %eax - lock - incl (%eax) - ret - SET_SIZE(atomic_inc_ulong) - SET_SIZE(atomic_inc_uint) - SET_SIZE(atomic_inc_32) - - ENTRY(atomic_inc_8_nv) - ALTENTRY(atomic_inc_uchar_nv) - movl 4(%esp), %edx - movb (%edx), %al -1: - leal 1(%eax), %ecx - lock - cmpxchgb %cl, (%edx) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_inc_uchar_nv) - SET_SIZE(atomic_inc_8_nv) - - ENTRY(atomic_inc_16_nv) - ALTENTRY(atomic_inc_ushort_nv) - movl 4(%esp), %edx - movw (%edx), %ax -1: - leal 1(%eax), %ecx - lock - cmpxchgw %cx, (%edx) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_inc_ushort_nv) - SET_SIZE(atomic_inc_16_nv) - - ENTRY(atomic_inc_32_nv) - ALTENTRY(atomic_inc_uint_nv) - ALTENTRY(atomic_inc_ulong_nv) - movl 4(%esp), %edx - movl (%edx), %eax -1: - leal 1(%eax), %ecx - lock - cmpxchgl %ecx, (%edx) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_inc_ulong_nv) - SET_SIZE(atomic_inc_uint_nv) - SET_SIZE(atomic_inc_32_nv) - - /* - * NOTE: If atomic_inc_64 and atomic_inc_64_nv are ever - * separated, you need to also edit the libc i386 platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_inc_64_nv. - */ - ENTRY(atomic_inc_64) - ALTENTRY(atomic_inc_64_nv) - pushl %edi - pushl %ebx - movl 12(%esp), %edi - movl (%edi), %eax - movl 4(%edi), %edx -1: - xorl %ebx, %ebx - xorl %ecx, %ecx - incl %ebx - addl %eax, %ebx - adcl %edx, %ecx - lock - cmpxchg8b (%edi) - jne 1b - movl %ebx, %eax - movl %ecx, %edx - popl %ebx - popl %edi - ret - SET_SIZE(atomic_inc_64_nv) - SET_SIZE(atomic_inc_64) - - ENTRY(atomic_dec_8) - ALTENTRY(atomic_dec_uchar) - movl 4(%esp), %eax - lock - decb (%eax) - ret - SET_SIZE(atomic_dec_uchar) - SET_SIZE(atomic_dec_8) - - ENTRY(atomic_dec_16) - ALTENTRY(atomic_dec_ushort) - movl 4(%esp), %eax - lock - decw (%eax) - ret - SET_SIZE(atomic_dec_ushort) - SET_SIZE(atomic_dec_16) - - ENTRY(atomic_dec_32) - ALTENTRY(atomic_dec_uint) - ALTENTRY(atomic_dec_ulong) - movl 4(%esp), %eax - lock - decl (%eax) - ret - SET_SIZE(atomic_dec_ulong) - SET_SIZE(atomic_dec_uint) - SET_SIZE(atomic_dec_32) - - ENTRY(atomic_dec_8_nv) - ALTENTRY(atomic_dec_uchar_nv) - movl 4(%esp), %edx - movb (%edx), %al -1: - leal -1(%eax), %ecx - lock - cmpxchgb %cl, (%edx) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_dec_uchar_nv) - SET_SIZE(atomic_dec_8_nv) - - ENTRY(atomic_dec_16_nv) - ALTENTRY(atomic_dec_ushort_nv) - movl 4(%esp), %edx - movw (%edx), %ax -1: - leal -1(%eax), %ecx - lock - cmpxchgw %cx, (%edx) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_dec_ushort_nv) - SET_SIZE(atomic_dec_16_nv) - - ENTRY(atomic_dec_32_nv) - ALTENTRY(atomic_dec_uint_nv) - ALTENTRY(atomic_dec_ulong_nv) - movl 4(%esp), %edx - movl (%edx), %eax -1: - leal -1(%eax), %ecx - lock - cmpxchgl %ecx, (%edx) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_dec_ulong_nv) - SET_SIZE(atomic_dec_uint_nv) - SET_SIZE(atomic_dec_32_nv) - - /* - * NOTE: If atomic_dec_64 and atomic_dec_64_nv are ever - * separated, it is important to edit the libc i386 platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_dec_64_nv. - */ - ENTRY(atomic_dec_64) - ALTENTRY(atomic_dec_64_nv) - pushl %edi - pushl %ebx - movl 12(%esp), %edi - movl (%edi), %eax - movl 4(%edi), %edx -1: - xorl %ebx, %ebx - xorl %ecx, %ecx - not %ecx - not %ebx - addl %eax, %ebx - adcl %edx, %ecx - lock - cmpxchg8b (%edi) - jne 1b - movl %ebx, %eax - movl %ecx, %edx - popl %ebx - popl %edi - ret - SET_SIZE(atomic_dec_64_nv) - SET_SIZE(atomic_dec_64) - - ENTRY(atomic_add_8) - ALTENTRY(atomic_add_char) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - addb %cl, (%eax) - ret - SET_SIZE(atomic_add_char) - SET_SIZE(atomic_add_8) - - ENTRY(atomic_add_16) - ALTENTRY(atomic_add_short) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - addw %cx, (%eax) - ret - SET_SIZE(atomic_add_short) - SET_SIZE(atomic_add_16) - - ENTRY(atomic_add_32) - ALTENTRY(atomic_add_int) - ALTENTRY(atomic_add_ptr) - ALTENTRY(atomic_add_long) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - addl %ecx, (%eax) - ret - SET_SIZE(atomic_add_long) - SET_SIZE(atomic_add_ptr) - SET_SIZE(atomic_add_int) - SET_SIZE(atomic_add_32) - - ENTRY(atomic_sub_8) - ALTENTRY(atomic_sub_char) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - subb %cl, (%eax) - ret - SET_SIZE(atomic_sub_char) - SET_SIZE(atomic_sub_8) - - ENTRY(atomic_sub_16) - ALTENTRY(atomic_sub_short) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - subw %cx, (%eax) - ret - SET_SIZE(atomic_sub_short) - SET_SIZE(atomic_sub_16) - - ENTRY(atomic_sub_32) - ALTENTRY(atomic_sub_int) - ALTENTRY(atomic_sub_ptr) - ALTENTRY(atomic_sub_long) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - subl %ecx, (%eax) - ret - SET_SIZE(atomic_sub_long) - SET_SIZE(atomic_sub_ptr) - SET_SIZE(atomic_sub_int) - SET_SIZE(atomic_sub_32) - - ENTRY(atomic_or_8) - ALTENTRY(atomic_or_uchar) - movl 4(%esp), %eax - movb 8(%esp), %cl - lock - orb %cl, (%eax) - ret - SET_SIZE(atomic_or_uchar) - SET_SIZE(atomic_or_8) - - ENTRY(atomic_or_16) - ALTENTRY(atomic_or_ushort) - movl 4(%esp), %eax - movw 8(%esp), %cx - lock - orw %cx, (%eax) - ret - SET_SIZE(atomic_or_ushort) - SET_SIZE(atomic_or_16) - - ENTRY(atomic_or_32) - ALTENTRY(atomic_or_uint) - ALTENTRY(atomic_or_ulong) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - orl %ecx, (%eax) - ret - SET_SIZE(atomic_or_ulong) - SET_SIZE(atomic_or_uint) - SET_SIZE(atomic_or_32) - - ENTRY(atomic_and_8) - ALTENTRY(atomic_and_uchar) - movl 4(%esp), %eax - movb 8(%esp), %cl - lock - andb %cl, (%eax) - ret - SET_SIZE(atomic_and_uchar) - SET_SIZE(atomic_and_8) - - ENTRY(atomic_and_16) - ALTENTRY(atomic_and_ushort) - movl 4(%esp), %eax - movw 8(%esp), %cx - lock - andw %cx, (%eax) - ret - SET_SIZE(atomic_and_ushort) - SET_SIZE(atomic_and_16) - - ENTRY(atomic_and_32) - ALTENTRY(atomic_and_uint) - ALTENTRY(atomic_and_ulong) - movl 4(%esp), %eax - movl 8(%esp), %ecx - lock - andl %ecx, (%eax) - ret - SET_SIZE(atomic_and_ulong) - SET_SIZE(atomic_and_uint) - SET_SIZE(atomic_and_32) - - ENTRY(atomic_add_8_nv) - ALTENTRY(atomic_add_char_nv) - movl 4(%esp), %edx - movb (%edx), %al -1: - movl 8(%esp), %ecx - addb %al, %cl - lock - cmpxchgb %cl, (%edx) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_add_char_nv) - SET_SIZE(atomic_add_8_nv) - - ENTRY(atomic_add_16_nv) - ALTENTRY(atomic_add_short_nv) - movl 4(%esp), %edx - movw (%edx), %ax -1: - movl 8(%esp), %ecx - addw %ax, %cx - lock - cmpxchgw %cx, (%edx) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_add_short_nv) - SET_SIZE(atomic_add_16_nv) - - ENTRY(atomic_add_32_nv) - ALTENTRY(atomic_add_int_nv) - ALTENTRY(atomic_add_ptr_nv) - ALTENTRY(atomic_add_long_nv) - movl 4(%esp), %edx - movl (%edx), %eax -1: - movl 8(%esp), %ecx - addl %eax, %ecx - lock - cmpxchgl %ecx, (%edx) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_add_long_nv) - SET_SIZE(atomic_add_ptr_nv) - SET_SIZE(atomic_add_int_nv) - SET_SIZE(atomic_add_32_nv) - - ENTRY(atomic_sub_8_nv) - ALTENTRY(atomic_sub_char_nv) - movl 4(%esp), %edx - movb (%edx), %al -1: - movl 8(%esp), %ecx - subb %al, %cl - lock - cmpxchgb %cl, (%edx) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_sub_char_nv) - SET_SIZE(atomic_sub_8_nv) - - ENTRY(atomic_sub_16_nv) - ALTENTRY(atomic_sub_short_nv) - movl 4(%esp), %edx - movw (%edx), %ax -1: - movl 8(%esp), %ecx - subw %ax, %cx - lock - cmpxchgw %cx, (%edx) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_sub_short_nv) - SET_SIZE(atomic_sub_16_nv) - - ENTRY(atomic_sub_32_nv) - ALTENTRY(atomic_sub_int_nv) - ALTENTRY(atomic_sub_ptr_nv) - ALTENTRY(atomic_sub_long_nv) - movl 4(%esp), %edx - movl (%edx), %eax -1: - movl 8(%esp), %ecx - subl %eax, %ecx - lock - cmpxchgl %ecx, (%edx) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_sub_long_nv) - SET_SIZE(atomic_sub_ptr_nv) - SET_SIZE(atomic_sub_int_nv) - SET_SIZE(atomic_sub_32_nv) - - /* - * NOTE: If atomic_add_64 and atomic_add_64_nv are ever - * separated, it is important to edit the libc i386 platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_add_64_nv. - */ - ENTRY(atomic_add_64) - ALTENTRY(atomic_add_64_nv) - pushl %edi - pushl %ebx - movl 12(%esp), %edi - movl (%edi), %eax - movl 4(%edi), %edx -1: - movl 16(%esp), %ebx - movl 20(%esp), %ecx - addl %eax, %ebx - adcl %edx, %ecx - lock - cmpxchg8b (%edi) - jne 1b - movl %ebx, %eax - movl %ecx, %edx - popl %ebx - popl %edi - ret - SET_SIZE(atomic_add_64_nv) - SET_SIZE(atomic_add_64) - - ENTRY(atomic_sub_64) - ALTENTRY(atomic_sub_64_nv) - pushl %edi - pushl %ebx - movl 12(%esp), %edi - movl (%edi), %eax - movl 4(%edi), %edx -1: - movl 16(%esp), %ebx - movl 20(%esp), %ecx - subl %eax, %ebx - sbbl %edx, %ecx - lock - cmpxchg8b (%edi) - jne 1b - movl %ebx, %eax - movl %ecx, %edx - popl %ebx - popl %edi - ret - SET_SIZE(atomic_sub_64_nv) - SET_SIZE(atomic_sub_64) - - ENTRY(atomic_or_8_nv) - ALTENTRY(atomic_or_uchar_nv) - movl 4(%esp), %edx - movb (%edx), %al -1: - movl 8(%esp), %ecx - orb %al, %cl - lock - cmpxchgb %cl, (%edx) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_or_uchar_nv) - SET_SIZE(atomic_or_8_nv) - - ENTRY(atomic_or_16_nv) - ALTENTRY(atomic_or_ushort_nv) - movl 4(%esp), %edx - movw (%edx), %ax -1: - movl 8(%esp), %ecx - orw %ax, %cx - lock - cmpxchgw %cx, (%edx) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_or_ushort_nv) - SET_SIZE(atomic_or_16_nv) - - ENTRY(atomic_or_32_nv) - ALTENTRY(atomic_or_uint_nv) - ALTENTRY(atomic_or_ulong_nv) - movl 4(%esp), %edx - movl (%edx), %eax -1: - movl 8(%esp), %ecx - orl %eax, %ecx - lock - cmpxchgl %ecx, (%edx) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_or_ulong_nv) - SET_SIZE(atomic_or_uint_nv) - SET_SIZE(atomic_or_32_nv) - - /* - * NOTE: If atomic_or_64 and atomic_or_64_nv are ever - * separated, it is important to edit the libc i386 platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_or_64_nv. - */ - ENTRY(atomic_or_64) - ALTENTRY(atomic_or_64_nv) - pushl %edi - pushl %ebx - movl 12(%esp), %edi - movl (%edi), %eax - movl 4(%edi), %edx -1: - movl 16(%esp), %ebx - movl 20(%esp), %ecx - orl %eax, %ebx - orl %edx, %ecx - lock - cmpxchg8b (%edi) - jne 1b - movl %ebx, %eax - movl %ecx, %edx - popl %ebx - popl %edi - ret - SET_SIZE(atomic_or_64_nv) - SET_SIZE(atomic_or_64) - - ENTRY(atomic_and_8_nv) - ALTENTRY(atomic_and_uchar_nv) - movl 4(%esp), %edx - movb (%edx), %al -1: - movl 8(%esp), %ecx - andb %al, %cl - lock - cmpxchgb %cl, (%edx) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_and_uchar_nv) - SET_SIZE(atomic_and_8_nv) - - ENTRY(atomic_and_16_nv) - ALTENTRY(atomic_and_ushort_nv) - movl 4(%esp), %edx - movw (%edx), %ax -1: - movl 8(%esp), %ecx - andw %ax, %cx - lock - cmpxchgw %cx, (%edx) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_and_ushort_nv) - SET_SIZE(atomic_and_16_nv) - - ENTRY(atomic_and_32_nv) - ALTENTRY(atomic_and_uint_nv) - ALTENTRY(atomic_and_ulong_nv) - movl 4(%esp), %edx - movl (%edx), %eax -1: - movl 8(%esp), %ecx - andl %eax, %ecx - lock - cmpxchgl %ecx, (%edx) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_and_ulong_nv) - SET_SIZE(atomic_and_uint_nv) - SET_SIZE(atomic_and_32_nv) - - /* - * NOTE: If atomic_and_64 and atomic_and_64_nv are ever - * separated, it is important to edit the libc i386 platform - * specific mapfile and remove the NODYNSORT attribute - * from atomic_and_64_nv. - */ - ENTRY(atomic_and_64) - ALTENTRY(atomic_and_64_nv) - pushl %edi - pushl %ebx - movl 12(%esp), %edi - movl (%edi), %eax - movl 4(%edi), %edx -1: - movl 16(%esp), %ebx - movl 20(%esp), %ecx - andl %eax, %ebx - andl %edx, %ecx - lock - cmpxchg8b (%edi) - jne 1b - movl %ebx, %eax - movl %ecx, %edx - popl %ebx - popl %edi - ret - SET_SIZE(atomic_and_64_nv) - SET_SIZE(atomic_and_64) - - ENTRY(atomic_cas_8) - ALTENTRY(atomic_cas_uchar) - movl 4(%esp), %edx - movzbl 8(%esp), %eax - movb 12(%esp), %cl - lock - cmpxchgb %cl, (%edx) - ret - SET_SIZE(atomic_cas_uchar) - SET_SIZE(atomic_cas_8) - - ENTRY(atomic_cas_16) - ALTENTRY(atomic_cas_ushort) - movl 4(%esp), %edx - movzwl 8(%esp), %eax - movw 12(%esp), %cx - lock - cmpxchgw %cx, (%edx) - ret - SET_SIZE(atomic_cas_ushort) - SET_SIZE(atomic_cas_16) - - ENTRY(atomic_cas_32) - ALTENTRY(atomic_cas_uint) - ALTENTRY(atomic_cas_ulong) - ALTENTRY(atomic_cas_ptr) - movl 4(%esp), %edx - movl 8(%esp), %eax - movl 12(%esp), %ecx - lock - cmpxchgl %ecx, (%edx) - ret - SET_SIZE(atomic_cas_ptr) - SET_SIZE(atomic_cas_ulong) - SET_SIZE(atomic_cas_uint) - SET_SIZE(atomic_cas_32) - - ENTRY(atomic_cas_64) - pushl %ebx - pushl %esi - movl 12(%esp), %esi - movl 16(%esp), %eax - movl 20(%esp), %edx - movl 24(%esp), %ebx - movl 28(%esp), %ecx - lock - cmpxchg8b (%esi) - popl %esi - popl %ebx - ret - SET_SIZE(atomic_cas_64) - - ENTRY(atomic_swap_8) - ALTENTRY(atomic_swap_uchar) - movl 4(%esp), %edx - movzbl 8(%esp), %eax - lock - xchgb %al, (%edx) - ret - SET_SIZE(atomic_swap_uchar) - SET_SIZE(atomic_swap_8) - - ENTRY(atomic_swap_16) - ALTENTRY(atomic_swap_ushort) - movl 4(%esp), %edx - movzwl 8(%esp), %eax - lock - xchgw %ax, (%edx) - ret - SET_SIZE(atomic_swap_ushort) - SET_SIZE(atomic_swap_16) - - ENTRY(atomic_swap_32) - ALTENTRY(atomic_swap_uint) - ALTENTRY(atomic_swap_ptr) - ALTENTRY(atomic_swap_ulong) - movl 4(%esp), %edx - movl 8(%esp), %eax - lock - xchgl %eax, (%edx) - ret - SET_SIZE(atomic_swap_ulong) - SET_SIZE(atomic_swap_ptr) - SET_SIZE(atomic_swap_uint) - SET_SIZE(atomic_swap_32) - - ENTRY(atomic_swap_64) - pushl %esi - pushl %ebx - movl 12(%esp), %esi - movl 16(%esp), %ebx - movl 20(%esp), %ecx - movl (%esi), %eax - movl 4(%esi), %edx -1: - lock - cmpxchg8b (%esi) - jne 1b - popl %ebx - popl %esi - ret - SET_SIZE(atomic_swap_64) - - ENTRY(atomic_set_long_excl) - movl 4(%esp), %edx - movl 8(%esp), %ecx - xorl %eax, %eax - lock - btsl %ecx, (%edx) - jnc 1f - decl %eax -1: - ret - SET_SIZE(atomic_set_long_excl) - - ENTRY(atomic_clear_long_excl) - movl 4(%esp), %edx - movl 8(%esp), %ecx - xorl %eax, %eax - lock - btrl %ecx, (%edx) - jc 1f - decl %eax -1: - ret - SET_SIZE(atomic_clear_long_excl) - - /* - * NOTE: membar_enter, membar_exit, membar_producer, and - * membar_consumer are all identical routines. We define them - * separately, instead of using ALTENTRY definitions to alias them - * together, so that DTrace and debuggers will see a unique address - * for them, allowing more accurate tracing. - */ - - - ENTRY(membar_enter) - lock - xorl $0, (%esp) - ret - SET_SIZE(membar_enter) - - ENTRY(membar_exit) - lock - xorl $0, (%esp) - ret - SET_SIZE(membar_exit) - - ENTRY(membar_producer) - lock - xorl $0, (%esp) - ret - SET_SIZE(membar_producer) - - ENTRY(membar_consumer) - lock - xorl $0, (%esp) - ret - SET_SIZE(membar_consumer) - -#ifdef __ELF__ -.section .note.GNU-stack,"",%progbits -#endif diff --git a/sys/contrib/openzfs/lib/libspl/asm-x86_64/atomic.S b/sys/contrib/openzfs/lib/libspl/asm-x86_64/atomic.S deleted file mode 100644 index 50edfe878cc..00000000000 --- a/sys/contrib/openzfs/lib/libspl/asm-x86_64/atomic.S +++ /dev/null @@ -1,691 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - - .ident "%Z%%M% %I% %E% SMI" - - .file "%M%" - -#define _ASM -#ifdef __linux__ -#include -#elif __FreeBSD__ -#include -#define SET_SIZE(x) -#endif - ENTRY(atomic_inc_8) - ALTENTRY(atomic_inc_uchar) - lock - incb (%rdi) - ret - SET_SIZE(atomic_inc_uchar) - SET_SIZE(atomic_inc_8) - - ENTRY(atomic_inc_16) - ALTENTRY(atomic_inc_ushort) - lock - incw (%rdi) - ret - SET_SIZE(atomic_inc_ushort) - SET_SIZE(atomic_inc_16) - - ENTRY(atomic_inc_32) - ALTENTRY(atomic_inc_uint) - lock - incl (%rdi) - ret - SET_SIZE(atomic_inc_uint) - SET_SIZE(atomic_inc_32) - - ENTRY(atomic_inc_64) - ALTENTRY(atomic_inc_ulong) - lock - incq (%rdi) - ret - SET_SIZE(atomic_inc_ulong) - SET_SIZE(atomic_inc_64) - - ENTRY(atomic_inc_8_nv) - ALTENTRY(atomic_inc_uchar_nv) - movb (%rdi), %al -1: - leaq 1(%rax), %rcx - lock - cmpxchgb %cl, (%rdi) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_inc_uchar_nv) - SET_SIZE(atomic_inc_8_nv) - - ENTRY(atomic_inc_16_nv) - ALTENTRY(atomic_inc_ushort_nv) - movw (%rdi), %ax -1: - leaq 1(%rax), %rcx - lock - cmpxchgw %cx, (%rdi) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_inc_ushort_nv) - SET_SIZE(atomic_inc_16_nv) - - ENTRY(atomic_inc_32_nv) - ALTENTRY(atomic_inc_uint_nv) - movl (%rdi), %eax -1: - leaq 1(%rax), %rcx - lock - cmpxchgl %ecx, (%rdi) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_inc_uint_nv) - SET_SIZE(atomic_inc_32_nv) - - ENTRY(atomic_inc_64_nv) - ALTENTRY(atomic_inc_ulong_nv) - movq (%rdi), %rax -1: - leaq 1(%rax), %rcx - lock - cmpxchgq %rcx, (%rdi) - jne 1b - movq %rcx, %rax - ret - SET_SIZE(atomic_inc_ulong_nv) - SET_SIZE(atomic_inc_64_nv) - - ENTRY(atomic_dec_8) - ALTENTRY(atomic_dec_uchar) - lock - decb (%rdi) - ret - SET_SIZE(atomic_dec_uchar) - SET_SIZE(atomic_dec_8) - - ENTRY(atomic_dec_16) - ALTENTRY(atomic_dec_ushort) - lock - decw (%rdi) - ret - SET_SIZE(atomic_dec_ushort) - SET_SIZE(atomic_dec_16) - - ENTRY(atomic_dec_32) - ALTENTRY(atomic_dec_uint) - lock - decl (%rdi) - ret - SET_SIZE(atomic_dec_uint) - SET_SIZE(atomic_dec_32) - - ENTRY(atomic_dec_64) - ALTENTRY(atomic_dec_ulong) - lock - decq (%rdi) - ret - SET_SIZE(atomic_dec_ulong) - SET_SIZE(atomic_dec_64) - - ENTRY(atomic_dec_8_nv) - ALTENTRY(atomic_dec_uchar_nv) - movb (%rdi), %al -1: - leaq -1(%rax), %rcx - lock - cmpxchgb %cl, (%rdi) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_dec_uchar_nv) - SET_SIZE(atomic_dec_8_nv) - - ENTRY(atomic_dec_16_nv) - ALTENTRY(atomic_dec_ushort_nv) - movw (%rdi), %ax -1: - leaq -1(%rax), %rcx - lock - cmpxchgw %cx, (%rdi) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_dec_ushort_nv) - SET_SIZE(atomic_dec_16_nv) - - ENTRY(atomic_dec_32_nv) - ALTENTRY(atomic_dec_uint_nv) - movl (%rdi), %eax -1: - leaq -1(%rax), %rcx - lock - cmpxchgl %ecx, (%rdi) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_dec_uint_nv) - SET_SIZE(atomic_dec_32_nv) - - ENTRY(atomic_dec_64_nv) - ALTENTRY(atomic_dec_ulong_nv) - movq (%rdi), %rax -1: - leaq -1(%rax), %rcx - lock - cmpxchgq %rcx, (%rdi) - jne 1b - movq %rcx, %rax - ret - SET_SIZE(atomic_dec_ulong_nv) - SET_SIZE(atomic_dec_64_nv) - - ENTRY(atomic_add_8) - ALTENTRY(atomic_add_char) - lock - addb %sil, (%rdi) - ret - SET_SIZE(atomic_add_char) - SET_SIZE(atomic_add_8) - - ENTRY(atomic_add_16) - ALTENTRY(atomic_add_short) - lock - addw %si, (%rdi) - ret - SET_SIZE(atomic_add_short) - SET_SIZE(atomic_add_16) - - ENTRY(atomic_add_32) - ALTENTRY(atomic_add_int) - lock - addl %esi, (%rdi) - ret - SET_SIZE(atomic_add_int) - SET_SIZE(atomic_add_32) - - ENTRY(atomic_add_64) - ALTENTRY(atomic_add_ptr) - ALTENTRY(atomic_add_long) - lock - addq %rsi, (%rdi) - ret - SET_SIZE(atomic_add_long) - SET_SIZE(atomic_add_ptr) - SET_SIZE(atomic_add_64) - - ENTRY(atomic_sub_8) - ALTENTRY(atomic_sub_char) - lock - subb %sil, (%rdi) - ret - SET_SIZE(atomic_sub_char) - SET_SIZE(atomic_sub_8) - - ENTRY(atomic_sub_16) - ALTENTRY(atomic_sub_short) - lock - subw %si, (%rdi) - ret - SET_SIZE(atomic_sub_short) - SET_SIZE(atomic_sub_16) - - ENTRY(atomic_sub_32) - ALTENTRY(atomic_sub_int) - lock - subl %esi, (%rdi) - ret - SET_SIZE(atomic_sub_int) - SET_SIZE(atomic_sub_32) - - ENTRY(atomic_sub_64) - ALTENTRY(atomic_sub_ptr) - ALTENTRY(atomic_sub_long) - lock - subq %rsi, (%rdi) - ret - SET_SIZE(atomic_sub_long) - SET_SIZE(atomic_sub_ptr) - SET_SIZE(atomic_sub_64) - - ENTRY(atomic_or_8) - ALTENTRY(atomic_or_uchar) - lock - orb %sil, (%rdi) - ret - SET_SIZE(atomic_or_uchar) - SET_SIZE(atomic_or_8) - - ENTRY(atomic_or_16) - ALTENTRY(atomic_or_ushort) - lock - orw %si, (%rdi) - ret - SET_SIZE(atomic_or_ushort) - SET_SIZE(atomic_or_16) - - ENTRY(atomic_or_32) - ALTENTRY(atomic_or_uint) - lock - orl %esi, (%rdi) - ret - SET_SIZE(atomic_or_uint) - SET_SIZE(atomic_or_32) - - ENTRY(atomic_or_64) - ALTENTRY(atomic_or_ulong) - lock - orq %rsi, (%rdi) - ret - SET_SIZE(atomic_or_ulong) - SET_SIZE(atomic_or_64) - - ENTRY(atomic_and_8) - ALTENTRY(atomic_and_uchar) - lock - andb %sil, (%rdi) - ret - SET_SIZE(atomic_and_uchar) - SET_SIZE(atomic_and_8) - - ENTRY(atomic_and_16) - ALTENTRY(atomic_and_ushort) - lock - andw %si, (%rdi) - ret - SET_SIZE(atomic_and_ushort) - SET_SIZE(atomic_and_16) - - ENTRY(atomic_and_32) - ALTENTRY(atomic_and_uint) - lock - andl %esi, (%rdi) - ret - SET_SIZE(atomic_and_uint) - SET_SIZE(atomic_and_32) - - ENTRY(atomic_and_64) - ALTENTRY(atomic_and_ulong) - lock - andq %rsi, (%rdi) - ret - SET_SIZE(atomic_and_ulong) - SET_SIZE(atomic_and_64) - - ENTRY(atomic_add_8_nv) - ALTENTRY(atomic_add_char_nv) - movb (%rdi), %al -1: - movb %sil, %cl - addb %al, %cl - lock - cmpxchgb %cl, (%rdi) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_add_char_nv) - SET_SIZE(atomic_add_8_nv) - - ENTRY(atomic_add_16_nv) - ALTENTRY(atomic_add_short_nv) - movw (%rdi), %ax -1: - movw %si, %cx - addw %ax, %cx - lock - cmpxchgw %cx, (%rdi) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_add_short_nv) - SET_SIZE(atomic_add_16_nv) - - ENTRY(atomic_add_32_nv) - ALTENTRY(atomic_add_int_nv) - movl (%rdi), %eax -1: - movl %esi, %ecx - addl %eax, %ecx - lock - cmpxchgl %ecx, (%rdi) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_add_int_nv) - SET_SIZE(atomic_add_32_nv) - - ENTRY(atomic_add_64_nv) - ALTENTRY(atomic_add_ptr_nv) - ALTENTRY(atomic_add_long_nv) - movq (%rdi), %rax -1: - movq %rsi, %rcx - addq %rax, %rcx - lock - cmpxchgq %rcx, (%rdi) - jne 1b - movq %rcx, %rax - ret - SET_SIZE(atomic_add_long_nv) - SET_SIZE(atomic_add_ptr_nv) - SET_SIZE(atomic_add_64_nv) - - ENTRY(atomic_sub_8_nv) - ALTENTRY(atomic_sub_char_nv) - movb (%rdi), %al -1: - movb %sil, %cl - subb %al, %cl - lock - cmpxchgb %cl, (%rdi) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_sub_char_nv) - SET_SIZE(atomic_sub_8_nv) - - ENTRY(atomic_sub_16_nv) - ALTENTRY(atomic_sub_short_nv) - movw (%rdi), %ax -1: - movw %si, %cx - subw %ax, %cx - lock - cmpxchgw %cx, (%rdi) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_sub_short_nv) - SET_SIZE(atomic_sub_16_nv) - - ENTRY(atomic_sub_32_nv) - ALTENTRY(atomic_sub_int_nv) - movl (%rdi), %eax -1: - movl %esi, %ecx - subl %eax, %ecx - lock - cmpxchgl %ecx, (%rdi) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_sub_int_nv) - SET_SIZE(atomic_sub_32_nv) - - ENTRY(atomic_sub_64_nv) - ALTENTRY(atomic_sub_ptr_nv) - ALTENTRY(atomic_sub_long_nv) - movq (%rdi), %rax -1: - movq %rsi, %rcx - subq %rax, %rcx - lock - cmpxchgq %rcx, (%rdi) - jne 1b - movq %rcx, %rax - ret - SET_SIZE(atomic_sub_long_nv) - SET_SIZE(atomic_sub_ptr_nv) - SET_SIZE(atomic_sub_64_nv) - - ENTRY(atomic_and_8_nv) - ALTENTRY(atomic_and_uchar_nv) - movb (%rdi), %al -1: - movb %sil, %cl - andb %al, %cl - lock - cmpxchgb %cl, (%rdi) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_and_uchar_nv) - SET_SIZE(atomic_and_8_nv) - - ENTRY(atomic_and_16_nv) - ALTENTRY(atomic_and_ushort_nv) - movw (%rdi), %ax -1: - movw %si, %cx - andw %ax, %cx - lock - cmpxchgw %cx, (%rdi) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_and_ushort_nv) - SET_SIZE(atomic_and_16_nv) - - ENTRY(atomic_and_32_nv) - ALTENTRY(atomic_and_uint_nv) - movl (%rdi), %eax -1: - movl %esi, %ecx - andl %eax, %ecx - lock - cmpxchgl %ecx, (%rdi) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_and_uint_nv) - SET_SIZE(atomic_and_32_nv) - - ENTRY(atomic_and_64_nv) - ALTENTRY(atomic_and_ulong_nv) - movq (%rdi), %rax -1: - movq %rsi, %rcx - andq %rax, %rcx - lock - cmpxchgq %rcx, (%rdi) - jne 1b - movq %rcx, %rax - ret - SET_SIZE(atomic_and_ulong_nv) - SET_SIZE(atomic_and_64_nv) - - ENTRY(atomic_or_8_nv) - ALTENTRY(atomic_or_uchar_nv) - movb (%rdi), %al -1: - movb %sil, %cl - orb %al, %cl - lock - cmpxchgb %cl, (%rdi) - jne 1b - movzbl %cl, %eax - ret - SET_SIZE(atomic_and_uchar_nv) - SET_SIZE(atomic_and_8_nv) - - ENTRY(atomic_or_16_nv) - ALTENTRY(atomic_or_ushort_nv) - movw (%rdi), %ax -1: - movw %si, %cx - orw %ax, %cx - lock - cmpxchgw %cx, (%rdi) - jne 1b - movzwl %cx, %eax - ret - SET_SIZE(atomic_or_ushort_nv) - SET_SIZE(atomic_or_16_nv) - - ENTRY(atomic_or_32_nv) - ALTENTRY(atomic_or_uint_nv) - movl (%rdi), %eax -1: - movl %esi, %ecx - orl %eax, %ecx - lock - cmpxchgl %ecx, (%rdi) - jne 1b - movl %ecx, %eax - ret - SET_SIZE(atomic_or_uint_nv) - SET_SIZE(atomic_or_32_nv) - - ENTRY(atomic_or_64_nv) - ALTENTRY(atomic_or_ulong_nv) - movq (%rdi), %rax -1: - movq %rsi, %rcx - orq %rax, %rcx - lock - cmpxchgq %rcx, (%rdi) - jne 1b - movq %rcx, %rax - ret - SET_SIZE(atomic_or_ulong_nv) - SET_SIZE(atomic_or_64_nv) - - ENTRY(atomic_cas_8) - ALTENTRY(atomic_cas_uchar) - movzbl %sil, %eax - lock - cmpxchgb %dl, (%rdi) - ret - SET_SIZE(atomic_cas_uchar) - SET_SIZE(atomic_cas_8) - - ENTRY(atomic_cas_16) - ALTENTRY(atomic_cas_ushort) - movzwl %si, %eax - lock - cmpxchgw %dx, (%rdi) - ret - SET_SIZE(atomic_cas_ushort) - SET_SIZE(atomic_cas_16) - - ENTRY(atomic_cas_32) - ALTENTRY(atomic_cas_uint) - movl %esi, %eax - lock - cmpxchgl %edx, (%rdi) - ret - SET_SIZE(atomic_cas_uint) - SET_SIZE(atomic_cas_32) - - ENTRY(atomic_cas_64) - ALTENTRY(atomic_cas_ulong) - ALTENTRY(atomic_cas_ptr) - movq %rsi, %rax - lock - cmpxchgq %rdx, (%rdi) - ret - SET_SIZE(atomic_cas_ptr) - SET_SIZE(atomic_cas_ulong) - SET_SIZE(atomic_cas_64) - - ENTRY(atomic_swap_8) - ALTENTRY(atomic_swap_uchar) - movzbl %sil, %eax - lock - xchgb %al, (%rdi) - ret - SET_SIZE(atomic_swap_uchar) - SET_SIZE(atomic_swap_8) - - ENTRY(atomic_swap_16) - ALTENTRY(atomic_swap_ushort) - movzwl %si, %eax - lock - xchgw %ax, (%rdi) - ret - SET_SIZE(atomic_swap_ushort) - SET_SIZE(atomic_swap_16) - - ENTRY(atomic_swap_32) - ALTENTRY(atomic_swap_uint) - movl %esi, %eax - lock - xchgl %eax, (%rdi) - ret - SET_SIZE(atomic_swap_uint) - SET_SIZE(atomic_swap_32) - - ENTRY(atomic_swap_64) - ALTENTRY(atomic_swap_ulong) - ALTENTRY(atomic_swap_ptr) - movq %rsi, %rax - lock - xchgq %rax, (%rdi) - ret - SET_SIZE(atomic_swap_ptr) - SET_SIZE(atomic_swap_ulong) - SET_SIZE(atomic_swap_64) - - ENTRY(atomic_set_long_excl) - xorl %eax, %eax - lock - btsq %rsi, (%rdi) - jnc 1f - decl %eax -1: - ret - SET_SIZE(atomic_set_long_excl) - - ENTRY(atomic_clear_long_excl) - xorl %eax, %eax - lock - btrq %rsi, (%rdi) - jc 1f - decl %eax -1: - ret - SET_SIZE(atomic_clear_long_excl) - - /* - * NOTE: membar_enter, and membar_exit are identical routines. - * We define them separately, instead of using an ALTENTRY - * definitions to alias them together, so that DTrace and - * debuggers will see a unique address for them, allowing - * more accurate tracing. - */ - - ENTRY(membar_enter) - mfence - ret - SET_SIZE(membar_enter) - - ENTRY(membar_exit) - mfence - ret - SET_SIZE(membar_exit) - - ENTRY(membar_producer) - sfence - ret - SET_SIZE(membar_producer) - - ENTRY(membar_consumer) - lfence - ret - SET_SIZE(membar_consumer) - -#ifdef __ELF__ -.section .note.GNU-stack,"",%progbits -#endif diff --git a/sys/contrib/openzfs/lib/libspl/assert.c b/sys/contrib/openzfs/lib/libspl/assert.c index 94290ae13e0..8e4333976f9 100644 --- a/sys/contrib/openzfs/lib/libspl/assert.c +++ b/sys/contrib/openzfs/lib/libspl/assert.c @@ -25,7 +25,7 @@ #include -int aok = 0; +int libspl_assert_ok = 0; /* printf version of libspl_assert */ void @@ -39,7 +39,7 @@ libspl_assertf(const char *file, const char *func, int line, fprintf(stderr, "\n"); fprintf(stderr, "ASSERT at %s:%d:%s()", file, line, func); va_end(args); - if (aok) { + if (libspl_assert_ok) { return; } abort(); diff --git a/sys/contrib/openzfs/lib/libspl/asm-generic/atomic.c b/sys/contrib/openzfs/lib/libspl/atomic.c similarity index 58% rename from sys/contrib/openzfs/lib/libspl/asm-generic/atomic.c rename to sys/contrib/openzfs/lib/libspl/atomic.c index 35535ea49c7..4717d818ce5 100644 --- a/sys/contrib/openzfs/lib/libspl/asm-generic/atomic.c +++ b/sys/contrib/openzfs/lib/libspl/atomic.c @@ -25,16 +25,6 @@ */ #include -#include -#include - -/* - * All operations are implemented by serializing them through a global - * pthread mutex. This provides a correct generic implementation. - * However all supported architectures are encouraged to provide a - * native implementation is assembly for performance reasons. - */ -pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER; /* * These are the void returning variants @@ -43,9 +33,7 @@ pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER; #define ATOMIC_INC(name, type) \ void atomic_inc_##name(volatile type *target) \ { \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - (*target)++; \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ + (void) __atomic_add_fetch(target, 1, __ATOMIC_SEQ_CST); \ } ATOMIC_INC(8, uint8_t) @@ -61,9 +49,7 @@ ATOMIC_INC(64, uint64_t) #define ATOMIC_DEC(name, type) \ void atomic_dec_##name(volatile type *target) \ { \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - (*target)--; \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ + (void) __atomic_sub_fetch(target, 1, __ATOMIC_SEQ_CST); \ } ATOMIC_DEC(8, uint8_t) @@ -79,9 +65,7 @@ ATOMIC_DEC(64, uint64_t) #define ATOMIC_ADD(name, type1, type2) \ void atomic_add_##name(volatile type1 *target, type2 bits) \ { \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - *target += bits; \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ + (void) __atomic_add_fetch(target, bits, __ATOMIC_SEQ_CST); \ } ATOMIC_ADD(8, uint8_t, int8_t) @@ -96,18 +80,14 @@ ATOMIC_ADD(64, uint64_t, int64_t) void atomic_add_ptr(volatile void *target, ssize_t bits) { - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); - *(caddr_t *)target += bits; - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); + (void) __atomic_add_fetch((void **)target, bits, __ATOMIC_SEQ_CST); } #define ATOMIC_SUB(name, type1, type2) \ void atomic_sub_##name(volatile type1 *target, type2 bits) \ { \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - *target -= bits; \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ + (void) __atomic_sub_fetch(target, bits, __ATOMIC_SEQ_CST); \ } ATOMIC_SUB(8, uint8_t, int8_t) @@ -122,18 +102,14 @@ ATOMIC_SUB(64, uint64_t, int64_t) void atomic_sub_ptr(volatile void *target, ssize_t bits) { - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); - *(caddr_t *)target -= bits; - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); + (void) __atomic_sub_fetch((void **)target, bits, __ATOMIC_SEQ_CST); } #define ATOMIC_OR(name, type) \ void atomic_or_##name(volatile type *target, type bits) \ { \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - *target |= bits; \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ + (void) __atomic_or_fetch(target, bits, __ATOMIC_SEQ_CST); \ } ATOMIC_OR(8, uint8_t) @@ -149,9 +125,7 @@ ATOMIC_OR(64, uint64_t) #define ATOMIC_AND(name, type) \ void atomic_and_##name(volatile type *target, type bits) \ { \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - *target &= bits; \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ + (void) __atomic_and_fetch(target, bits, __ATOMIC_SEQ_CST); \ } ATOMIC_AND(8, uint8_t) @@ -171,11 +145,7 @@ ATOMIC_AND(64, uint64_t) #define ATOMIC_INC_NV(name, type) \ type atomic_inc_##name##_nv(volatile type *target) \ { \ - type rc; \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - rc = (++(*target)); \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ - return (rc); \ + return (__atomic_add_fetch(target, 1, __ATOMIC_SEQ_CST)); \ } ATOMIC_INC_NV(8, uint8_t) @@ -191,11 +161,7 @@ ATOMIC_INC_NV(64, uint64_t) #define ATOMIC_DEC_NV(name, type) \ type atomic_dec_##name##_nv(volatile type *target) \ { \ - type rc; \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - rc = (--(*target)); \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ - return (rc); \ + return (__atomic_sub_fetch(target, 1, __ATOMIC_SEQ_CST)); \ } ATOMIC_DEC_NV(8, uint8_t) @@ -209,13 +175,9 @@ ATOMIC_DEC_NV(64, uint64_t) #define ATOMIC_ADD_NV(name, type1, type2) \ - type1 atomic_add_##name##_nv(volatile type1 *target, type2 bits)\ + type1 atomic_add_##name##_nv(volatile type1 *target, type2 bits) \ { \ - type1 rc; \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - rc = (*target += bits); \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ - return (rc); \ + return (__atomic_add_fetch(target, bits, __ATOMIC_SEQ_CST)); \ } ATOMIC_ADD_NV(8, uint8_t, int8_t) @@ -230,24 +192,14 @@ ATOMIC_ADD_NV(64, uint64_t, int64_t) void * atomic_add_ptr_nv(volatile void *target, ssize_t bits) { - void *ptr; - - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); - ptr = (*(caddr_t *)target += bits); - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); - - return (ptr); + return (__atomic_add_fetch((void **)target, bits, __ATOMIC_SEQ_CST)); } #define ATOMIC_SUB_NV(name, type1, type2) \ - type1 atomic_sub_##name##_nv(volatile type1 *target, type2 bits)\ + type1 atomic_sub_##name##_nv(volatile type1 *target, type2 bits) \ { \ - type1 rc; \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - rc = (*target -= bits); \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ - return (rc); \ + return (__atomic_sub_fetch(target, bits, __ATOMIC_SEQ_CST)); \ } ATOMIC_SUB_NV(8, uint8_t, int8_t) @@ -262,24 +214,14 @@ ATOMIC_SUB_NV(64, uint64_t, int64_t) void * atomic_sub_ptr_nv(volatile void *target, ssize_t bits) { - void *ptr; - - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); - ptr = (*(caddr_t *)target -= bits); - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); - - return (ptr); + return (__atomic_sub_fetch((void **)target, bits, __ATOMIC_SEQ_CST)); } #define ATOMIC_OR_NV(name, type) \ type atomic_or_##name##_nv(volatile type *target, type bits) \ { \ - type rc; \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - rc = (*target |= bits); \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ - return (rc); \ + return (__atomic_or_fetch(target, bits, __ATOMIC_SEQ_CST)); \ } ATOMIC_OR_NV(8, uint8_t) @@ -295,11 +237,7 @@ ATOMIC_OR_NV(64, uint64_t) #define ATOMIC_AND_NV(name, type) \ type atomic_and_##name##_nv(volatile type *target, type bits) \ { \ - type rc; \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - rc = (*target &= bits); \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ - return (rc); \ + return (__atomic_and_fetch(target, bits, __ATOMIC_SEQ_CST)); \ } ATOMIC_AND_NV(8, uint8_t) @@ -313,19 +251,21 @@ ATOMIC_AND_NV(64, uint64_t) /* - * If *arg1 == arg2, set *arg1 = arg3; return old value + * If *tgt == exp, set *tgt = des; return old value + * + * This may not look right on the first pass (or the sixteenth), but, + * from https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html: + * > If they are not equal, the operation is a read + * > and the current contents of *ptr are written into *expected. + * And, in the converse case, exp is already *target by definition. */ #define ATOMIC_CAS(name, type) \ - type atomic_cas_##name(volatile type *target, type arg1, type arg2) \ + type atomic_cas_##name(volatile type *target, type exp, type des) \ { \ - type old; \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - old = *target; \ - if (old == arg1) \ - *target = arg2; \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ - return (old); \ + __atomic_compare_exchange_n(target, &exp, des, B_FALSE, \ + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \ + return (exp); \ } ATOMIC_CAS(8, uint8_t) @@ -338,17 +278,12 @@ ATOMIC_CAS(ulong, ulong_t) ATOMIC_CAS(64, uint64_t) void * -atomic_cas_ptr(volatile void *target, void *arg1, void *arg2) +atomic_cas_ptr(volatile void *target, void *exp, void *des) { - void *old; - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); - old = *(void **)target; - if (old == arg1) - *(void **)target = arg2; - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); - - return (old); + __atomic_compare_exchange_n((void **)target, &exp, des, B_FALSE, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return (exp); } @@ -359,12 +294,7 @@ atomic_cas_ptr(volatile void *target, void *arg1, void *arg2) #define ATOMIC_SWAP(name, type) \ type atomic_swap_##name(volatile type *target, type bits) \ { \ - type old; \ - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); \ - old = *target; \ - *target = bits; \ - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); \ - return (old); \ + return (__atomic_exchange_n(target, bits, __ATOMIC_SEQ_CST)); \ } ATOMIC_SWAP(8, uint8_t) @@ -380,71 +310,59 @@ ATOMIC_SWAP(64, uint64_t) void * atomic_swap_ptr(volatile void *target, void *bits) { - void *old; - - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); - old = *(void **)target; - *(void **)target = bits; - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); - - return (old); + return (__atomic_exchange_n((void **)target, bits, __ATOMIC_SEQ_CST)); } +#ifndef _LP64 +uint64_t +atomic_load_64(volatile uint64_t *target) +{ + return (__atomic_load_n(target, __ATOMIC_RELAXED)); +} + +void +atomic_store_64(volatile uint64_t *target, uint64_t bits) +{ + return (__atomic_store_n(target, bits, __ATOMIC_RELAXED)); +} +#endif int atomic_set_long_excl(volatile ulong_t *target, uint_t value) { - ulong_t bit; - - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); - bit = (1UL << value); - if ((*target & bit) != 0) { - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); - return (-1); - } - *target |= bit; - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); - - return (0); + ulong_t bit = 1UL << value; + ulong_t old = __atomic_fetch_or(target, bit, __ATOMIC_SEQ_CST); + return ((old & bit) ? -1 : 0); } int atomic_clear_long_excl(volatile ulong_t *target, uint_t value) { - ulong_t bit; - - VERIFY3S(pthread_mutex_lock(&atomic_lock), ==, 0); - bit = (1UL << value); - if ((*target & bit) == 0) { - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); - return (-1); - } - *target &= ~bit; - VERIFY3S(pthread_mutex_unlock(&atomic_lock), ==, 0); - - return (0); + ulong_t bit = 1UL << value; + ulong_t old = __atomic_fetch_and(target, ~bit, __ATOMIC_SEQ_CST); + return ((old & bit) ? 0 : -1); } void membar_enter(void) { - /* XXX - Implement me */ + __atomic_thread_fence(__ATOMIC_SEQ_CST); } void membar_exit(void) { - /* XXX - Implement me */ + __atomic_thread_fence(__ATOMIC_SEQ_CST); } void membar_producer(void) { - /* XXX - Implement me */ + __atomic_thread_fence(__ATOMIC_RELEASE); } void membar_consumer(void) { - /* XXX - Implement me */ + __atomic_thread_fence(__ATOMIC_ACQUIRE); } diff --git a/sys/contrib/openzfs/lib/libuutil/uu_open.c b/sys/contrib/openzfs/lib/libspl/getexecname.c similarity index 58% rename from sys/contrib/openzfs/lib/libuutil/uu_open.c rename to sys/contrib/openzfs/lib/libspl/getexecname.c index cf5c5450b82..dca7162034f 100644 --- a/sys/contrib/openzfs/lib/libuutil/uu_open.c +++ b/sys/contrib/openzfs/lib/libspl/getexecname.c @@ -20,51 +20,40 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - -#include "libuutil_common.h" - -#include - -#include -#include #include -#include +#include +#include +#include #include +#include "libspl_impl.h" -#ifdef _LP64 -#define TMPPATHFMT "%s/uu%ld" -#else /* _LP64 */ -#define TMPPATHFMT "%s/uu%lld" -#endif /* _LP64 */ -/*ARGSUSED*/ -int -uu_open_tmp(const char *dir, uint_t uflags) +const char * +getexecname(void) { - int f; - char *fname = uu_zalloc(PATH_MAX); + static char execname[PATH_MAX + 1] = ""; + static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; - if (fname == NULL) - return (-1); + char *ptr = execname; + ssize_t rc; - for (;;) { - (void) snprintf(fname, PATH_MAX, "%s/uu%lld", dir, gethrtime()); + (void) pthread_mutex_lock(&mtx); - f = open(fname, O_CREAT | O_EXCL | O_RDWR, 0600); - - if (f >= 0 || errno != EEXIST) - break; + if (strlen(execname) == 0) { + rc = getexecname_impl(execname); + if (rc == -1) { + execname[0] = '\0'; + ptr = NULL; + } else { + execname[rc] = '\0'; + } } - if (f >= 0) - (void) unlink(fname); - - uu_free(fname); - - return (f); + (void) pthread_mutex_unlock(&mtx); + return (ptr); } diff --git a/sys/contrib/openzfs/lib/libspl/include/assert.h b/sys/contrib/openzfs/lib/libspl/include/assert.h index 0503ce49218..84dbccdc4a1 100644 --- a/sys/contrib/openzfs/lib/libspl/include/assert.h +++ b/sys/contrib/openzfs/lib/libspl/include/assert.h @@ -34,7 +34,7 @@ #include /* Set to non-zero to avoid abort()ing on an assertion failure */ -extern int aok; +extern int libspl_assert_ok; /* printf version of libspl_assert */ extern void libspl_assertf(const char *file, const char *func, int line, diff --git a/sys/contrib/openzfs/lib/libspl/include/atomic.h b/sys/contrib/openzfs/lib/libspl/include/atomic.h index f8c257f9696..8dd1d654a48 100644 --- a/sys/contrib/openzfs/lib/libspl/include/atomic.h +++ b/sys/contrib/openzfs/lib/libspl/include/atomic.h @@ -245,6 +245,49 @@ extern ulong_t atomic_swap_ulong(volatile ulong_t *, ulong_t); extern uint64_t atomic_swap_64(volatile uint64_t *, uint64_t); #endif +/* + * Atomically read variable. + */ +#define atomic_load_char(p) (*(volatile uchar_t *)(p)) +#define atomic_load_short(p) (*(volatile ushort_t *)(p)) +#define atomic_load_int(p) (*(volatile uint_t *)(p)) +#define atomic_load_long(p) (*(volatile ulong_t *)(p)) +#define atomic_load_ptr(p) (*(volatile __typeof(*p) *)(p)) +#define atomic_load_8(p) (*(volatile uint8_t *)(p)) +#define atomic_load_16(p) (*(volatile uint16_t *)(p)) +#define atomic_load_32(p) (*(volatile uint32_t *)(p)) +#ifdef _LP64 +#define atomic_load_64(p) (*(volatile uint64_t *)(p)) +#elif defined(_INT64_TYPE) +extern uint64_t atomic_load_64(volatile uint64_t *); +#endif + +/* + * Atomically write variable. + */ +#define atomic_store_char(p, v) \ + (*(volatile uchar_t *)(p) = (uchar_t)(v)) +#define atomic_store_short(p, v) \ + (*(volatile ushort_t *)(p) = (ushort_t)(v)) +#define atomic_store_int(p, v) \ + (*(volatile uint_t *)(p) = (uint_t)(v)) +#define atomic_store_long(p, v) \ + (*(volatile ulong_t *)(p) = (ulong_t)(v)) +#define atomic_store_ptr(p, v) \ + (*(volatile __typeof(*p) *)(p) = (v)) +#define atomic_store_8(p, v) \ + (*(volatile uint8_t *)(p) = (uint8_t)(v)) +#define atomic_store_16(p, v) \ + (*(volatile uint16_t *)(p) = (uint16_t)(v)) +#define atomic_store_32(p, v) \ + (*(volatile uint32_t *)(p) = (uint32_t)(v)) +#ifdef _LP64 +#define atomic_store_64(p, v) \ + (*(volatile uint64_t *)(p) = (uint64_t)(v)) +#elif defined(_INT64_TYPE) +extern void atomic_store_64(volatile uint64_t *, uint64_t); +#endif + /* * Perform an exclusive atomic bit set/clear on a target. * Returns 0 if bit was successfully set/cleared, or -1 diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/sys/Makefile.am index 53a36f6bfbc..6816a012533 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/Makefile.am +++ b/sys/contrib/openzfs/lib/libspl/include/sys/Makefile.am @@ -44,4 +44,5 @@ libspl_HEADERS = \ varargs.h \ vnode.h \ vtoc.h \ + wmsum.h \ zone.h diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/wmsum.h b/sys/contrib/openzfs/lib/libspl/include/sys/wmsum.h new file mode 100644 index 00000000000..0679af73ce9 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/wmsum.h @@ -0,0 +1,68 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.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. + * + * CDDL HEADER END + */ + +/* + * wmsum counters are a reduced version of aggsum counters, optimized for + * write-mostly scenarios. They do not provide optimized read functions, + * but instead allow much cheaper add function. The primary usage is + * infrequently read statistic counters, not requiring exact precision. + * + * In user-space due to lack of better implementation mapped to aggsum. + */ + +#ifndef _SYS_WMSUM_H +#define _SYS_WMSUM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define wmsum_t aggsum_t + +static inline void +wmsum_init(wmsum_t *ws, uint64_t value) +{ + + aggsum_init(ws, value); +} + +static inline void +wmsum_fini(wmsum_t *ws) +{ + + aggsum_fini(ws); +} + +static inline uint64_t +wmsum_value(wmsum_t *ws) +{ + + return (aggsum_value(ws)); +} + +static inline void +wmsum_add(wmsum_t *ws, int64_t delta) +{ + + aggsum_add(ws, delta); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_WMSUM_H */ diff --git a/sys/contrib/openzfs/lib/libspl/libspl_impl.h b/sys/contrib/openzfs/lib/libspl/libspl_impl.h new file mode 100644 index 00000000000..cda56e64c96 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/libspl_impl.h @@ -0,0 +1,24 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (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 + */ + + +extern ssize_t getexecname_impl(char *execname); diff --git a/sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c b/sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c index 2b057cc7301..256b28c1b70 100644 --- a/sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c +++ b/sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c @@ -20,52 +20,21 @@ * CDDL HEADER END */ - -#include +#include #include -#include -#include -#include #include #include #include -#include +#include "../../libspl_impl.h" -const char * -getexecname(void) +__attribute__((visibility("hidden"))) ssize_t +getexecname_impl(char *execname) { - static char execname[PATH_MAX + 1] = ""; - static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; - char *ptr = NULL; - ssize_t rc; + size_t len = PATH_MAX; + int name[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; - (void) pthread_mutex_lock(&mtx); + if (sysctl(name, nitems(name), execname, &len, NULL, 0) != 0) + return (-1); - if (strlen(execname) == 0) { - int error, name[4]; - size_t len; - - name[0] = CTL_KERN; - name[1] = KERN_PROC; - name[2] = KERN_PROC_PATHNAME; - name[3] = -1; - len = PATH_MAX; - error = sysctl(name, nitems(name), execname, &len, NULL, 0); - if (error != 0) { - rc = -1; - } else { - rc = len; - } - if (rc == -1) { - execname[0] = '\0'; - } else { - execname[rc] = '\0'; - ptr = execname; - } - } else { - ptr = execname; - } - - (void) pthread_mutex_unlock(&mtx); - return (ptr); + return (len); } diff --git a/sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c b/sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c index 5b9e6429d9e..bd3e3e4e3ee 100644 --- a/sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c +++ b/sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c @@ -140,14 +140,14 @@ statfs_init(void) free(gsfs); gsfs = NULL; } - allfs = getfsstat(NULL, 0, MNT_WAIT); + allfs = getfsstat(NULL, 0, MNT_NOWAIT); if (allfs == -1) goto fail; gsfs = malloc(sizeof (gsfs[0]) * allfs * 2); if (gsfs == NULL) goto fail; allfs = getfsstat(gsfs, (long)(sizeof (gsfs[0]) * allfs * 2), - MNT_WAIT); + MNT_NOWAIT); if (allfs == -1) goto fail; sfs = realloc(gsfs, allfs * sizeof (gsfs[0])); diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c b/sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c index 6352a1a3401..a640556bcbe 100644 --- a/sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c +++ b/sys/contrib/openzfs/lib/libspl/os/linux/getexecname.c @@ -19,41 +19,14 @@ * * CDDL HEADER END */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include -#include -#include -#include +#include #include +#include "../../libspl_impl.h" -const char * -getexecname(void) +__attribute__((visibility("hidden"))) ssize_t +getexecname_impl(char *execname) { - static char execname[PATH_MAX + 1] = ""; - static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; - char *ptr = NULL; - ssize_t rc; - - (void) pthread_mutex_lock(&mtx); - - if (strlen(execname) == 0) { - rc = readlink("/proc/self/exe", - execname, sizeof (execname) - 1); - if (rc == -1) { - execname[0] = '\0'; - } else { - execname[rc] = '\0'; - ptr = execname; - } - } else { - ptr = execname; - } - - (void) pthread_mutex_unlock(&mtx); - return (ptr); + return (readlink("/proc/self/exe", execname, PATH_MAX)); } diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c b/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c index 1eb93f44114..c04b7fd3eef 100644 --- a/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c +++ b/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c @@ -40,47 +40,40 @@ get_spl_hostid(void) * Allow the hostid to be subverted for testing. */ env = getenv("ZFS_HOSTID"); - if (env) { - hostid = strtoull(env, NULL, 0); - return (hostid & HOSTID_MASK); - } + if (env) + return (strtoull(env, NULL, 0)); - f = fopen("/sys/module/spl/parameters/spl_hostid", "r"); + f = fopen("/proc/sys/kernel/spl/hostid", "re"); if (!f) return (0); - if (fscanf(f, "%lu", &hostid) != 1) + if (fscanf(f, "%lx", &hostid) != 1) hostid = 0; fclose(f); - return (hostid & HOSTID_MASK); + return (hostid); } unsigned long get_system_hostid(void) { - unsigned long system_hostid = get_spl_hostid(); + unsigned long hostid = get_spl_hostid(); + /* - * We do not use the library call gethostid() because - * it generates a hostid value that the kernel is - * unaware of, if the spl_hostid module parameter has not - * been set and there is no system hostid file (e.g. - * /etc/hostid). The kernel and userspace must agree. + * We do not use gethostid(3) because it can return a bogus ID, + * depending on the libc and /etc/hostid presence, + * and the kernel and userspace must agree. * See comments above hostid_read() in the SPL. */ - if (system_hostid == 0) { - int fd, rc; - unsigned long hostid; - int hostid_size = 4; /* 4 bytes regardless of arch */ - - fd = open("/etc/hostid", O_RDONLY); + if (hostid == 0) { + int fd = open("/etc/hostid", O_RDONLY | O_CLOEXEC); if (fd >= 0) { - rc = read(fd, &hostid, hostid_size); - if (rc > 0) - system_hostid = (hostid & HOSTID_MASK); - close(fd); + if (read(fd, &hostid, 4) < 0) + hostid = 0; + (void) close(fd); } } - return (system_hostid); + + return (hostid & HOSTID_MASK); } diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c b/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c index f42fcc04789..d458b28ad30 100644 --- a/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c +++ b/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c @@ -41,7 +41,7 @@ #define BUFSIZE (MNT_LINE_MAX + 2) -__thread char buf[BUFSIZE]; +static __thread char buf[BUFSIZE]; #define DIFF(xx) ( \ (mrefp->xx != NULL) && \ @@ -127,11 +127,7 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf) } -#ifdef HAVE_SETMNTENT - if ((fp = setmntent(MNTTAB, "r")) == NULL) { -#else - if ((fp = fopen(MNTTAB, "r")) == NULL) { -#endif + if ((fp = fopen(MNTTAB, "re")) == NULL) { (void) fprintf(stderr, "cannot open %s\n", MNTTAB); return (-1); } @@ -148,6 +144,7 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf) break; } } + (void) fclose(fp); if (!match) { (void) fprintf(stderr, "cannot find mountpoint for '%s'\n", diff --git a/sys/contrib/openzfs/lib/libspl/page.c b/sys/contrib/openzfs/lib/libspl/page.c index 06d9fcfa05c..ad9aad99823 100644 --- a/sys/contrib/openzfs/lib/libspl/page.c +++ b/sys/contrib/openzfs/lib/libspl/page.c @@ -22,7 +22,7 @@ #include -size_t pagesize = 0; +static size_t pagesize = 0; size_t spl_pagesize(void) diff --git a/sys/contrib/openzfs/lib/libuutil/Makefile.am b/sys/contrib/openzfs/lib/libuutil/Makefile.am index 16d5023451b..5a911f85f7d 100644 --- a/sys/contrib/openzfs/lib/libuutil/Makefile.am +++ b/sys/contrib/openzfs/lib/libuutil/Makefile.am @@ -7,11 +7,9 @@ include $(top_srcdir)/config/Abigail.am USER_C = \ uu_alloc.c \ uu_avl.c \ - uu_dprintf.c \ uu_ident.c \ uu_list.c \ uu_misc.c \ - uu_open.c \ uu_pname.c \ uu_string.c diff --git a/sys/contrib/openzfs/lib/libuutil/libuutil.abi b/sys/contrib/openzfs/lib/libuutil/libuutil.abi index c152289089c..5f0c8861171 100644 --- a/sys/contrib/openzfs/lib/libuutil/libuutil.abi +++ b/sys/contrib/openzfs/lib/libuutil/libuutil.abi @@ -1,27 +1,28 @@ + - - + + - + - - + + - + - + - + @@ -29,98 +30,98 @@ - + - - + + - - - + + + - - + + - + - + - - + + - + - - + + - - - - + + + + - + - + - + - - + + - - + + - - + + - - - + + + - - + + - - - + + + - - + + - - + + - + - - + + - + - - - - + + + + @@ -203,11 +204,6 @@ - - - - - @@ -241,7 +237,6 @@ - @@ -259,1044 +254,1654 @@ - - - + - - - - - - - + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - + - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - - - - - - + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - - + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - - + + + + + + + + + - + - + - + - + - + - + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - + + + + + + + + + + + + - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - + + + + + + + - - - - + + + - - - + + + - - - + + + - - + + - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - + + + + - - - - - - - + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + - - - - + + + - + - - - - - - - - - + - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + + + + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + - - - - + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - + + + + + - - - - + + + - - - - + + + + + + - - - - + + + + + + + - - - + + + + - - + + + + - - + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + - - - - + + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1304,305 +1909,540 @@ - + - + - + - + - - - - - - - + + + + + + + + - - - + + + - - - + + + + + - - - - + + + + - - - - + + + + + - - - - + + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + - + + + + - + + + + - - - - - - - - - - - - - - - - - - - - - + - + - - - - + - + - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sys/contrib/openzfs/lib/libuutil/uu_dprintf.c b/sys/contrib/openzfs/lib/libuutil/uu_dprintf.c deleted file mode 100644 index 6958057b29c..00000000000 --- a/sys/contrib/openzfs/lib/libuutil/uu_dprintf.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - - - -#include "libuutil_common.h" - -#include -#include -#include -#include -#include -#include -#include - -#define FACILITY_FMT "%s (%s): " - -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - -static const char * -strseverity(uu_dprintf_severity_t severity) -{ - switch (severity) { - case UU_DPRINTF_SILENT: - return (dgettext(TEXT_DOMAIN, "silent")); - case UU_DPRINTF_FATAL: - return (dgettext(TEXT_DOMAIN, "FATAL")); - case UU_DPRINTF_WARNING: - return (dgettext(TEXT_DOMAIN, "WARNING")); - case UU_DPRINTF_NOTICE: - return (dgettext(TEXT_DOMAIN, "note")); - case UU_DPRINTF_INFO: - return (dgettext(TEXT_DOMAIN, "info")); - case UU_DPRINTF_DEBUG: - return (dgettext(TEXT_DOMAIN, "debug")); - default: - return (dgettext(TEXT_DOMAIN, "unspecified")); - } -} - -uu_dprintf_t * -uu_dprintf_create(const char *name, uu_dprintf_severity_t severity, - uint_t flags) -{ - uu_dprintf_t *D; - - if (name != NULL && - uu_check_name(name, UU_NAME_DOMAIN) == -1) { - uu_set_error(UU_ERROR_INVALID_ARGUMENT); - return (NULL); - } - - if ((D = uu_zalloc(sizeof (uu_dprintf_t))) == NULL) - return (NULL); - - if (name != NULL) { - D->uud_name = strdup(name); - if (D->uud_name == NULL) { - uu_free(D); - return (NULL); - } - } else { - D->uud_name = NULL; - } - - D->uud_severity = severity; - D->uud_flags = flags; - - return (D); -} - -/*PRINTFLIKE3*/ -void -uu_dprintf(uu_dprintf_t *D, uu_dprintf_severity_t severity, - const char *format, ...) -{ - va_list alist; - - /* XXX Assert that severity is not UU_DPRINTF_SILENT. */ - - if (severity > D->uud_severity) - return; - - (void) fprintf(stderr, FACILITY_FMT, D->uud_name, - strseverity(severity)); - - va_start(alist, format); - (void) vfprintf(stderr, format, alist); - va_end(alist); -} - -void -uu_dprintf_destroy(uu_dprintf_t *D) -{ - if (D->uud_name) - free(D->uud_name); - - uu_free(D); -} - -const char * -uu_dprintf_getname(uu_dprintf_t *D) -{ - return (D->uud_name); -} diff --git a/sys/contrib/openzfs/lib/libuutil/uu_misc.c b/sys/contrib/openzfs/lib/libuutil/uu_misc.c index b10afd8eadf..a8478ace9a7 100644 --- a/sys/contrib/openzfs/lib/libuutil/uu_misc.c +++ b/sys/contrib/openzfs/lib/libuutil/uu_misc.c @@ -252,30 +252,3 @@ uu_init(void) _uu_main_thread = 1; (void) pthread_atfork(uu_lockup, uu_release, uu_release_child); } - -/* - * Dump a block of memory in hex+ascii, for debugging - */ -void -uu_dump(FILE *out, const char *prefix, const void *buf, size_t len) -{ - const unsigned char *p = buf; - int i; - - for (i = 0; i < len; i += 16) { - int j; - - (void) fprintf(out, "%s", prefix); - for (j = 0; j < 16 && i + j < len; j++) { - (void) fprintf(out, "%2.2x ", p[i + j]); - } - for (; j < 16; j++) { - (void) fprintf(out, " "); - } - for (j = 0; j < 16 && i + j < len; j++) { - (void) fprintf(out, "%c", - isprint(p[i + j]) ? p[i + j] : '.'); - } - (void) fprintf(out, "\n"); - } -} diff --git a/sys/contrib/openzfs/lib/libzfs/Makefile.am b/sys/contrib/openzfs/lib/libzfs/Makefile.am index 621021a1218..e3527ffe705 100644 --- a/sys/contrib/openzfs/lib/libzfs/Makefile.am +++ b/sys/contrib/openzfs/lib/libzfs/Makefile.am @@ -8,6 +8,7 @@ VPATH = \ # Suppress unused but set variable warnings often due to ASSERTs AM_CFLAGS += $(NO_UNUSED_BUT_SET_VARIABLE) AM_CFLAGS += $(LIBCRYPTO_CFLAGS) $(ZLIB_CFLAGS) +AM_CFLAGS += -fvisibility=hidden pkgconfig_DATA = libzfs.pc @@ -16,6 +17,7 @@ lib_LTLIBRARIES = libzfs.la include $(top_srcdir)/config/Abigail.am USER_C = \ + libzfs_impl.h \ libzfs_changelist.c \ libzfs_config.c \ libzfs_crypto.c \ @@ -75,7 +77,7 @@ libzfs_la_LIBADD = \ $(abs_top_builddir)/lib/libnvpair/libnvpair.la \ $(abs_top_builddir)/lib/libuutil/libuutil.la -libzfs_la_LIBADD += -lm $(LIBCRYPTO_LIBS) $(ZLIB_LIBS) $(LTLIBINTL) +libzfs_la_LIBADD += -lm $(LIBCRYPTO_LIBS) $(ZLIB_LIBS) $(LIBFETCH_LIBS) $(LTLIBINTL) libzfs_la_LDFLAGS = -pthread @@ -87,7 +89,7 @@ if BUILD_FREEBSD libzfs_la_LIBADD += -lutil -lgeom endif -libzfs_la_LDFLAGS += -version-info 4:0:0 +libzfs_la_LDFLAGS += -version-info 5:0:1 include $(top_srcdir)/config/CppCheck.am diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs.abi b/sys/contrib/openzfs/lib/libzfs/libzfs.abi index 6cd8fa9357f..3dd8b2b1451 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs.abi +++ b/sys/contrib/openzfs/lib/libzfs/libzfs.abi @@ -6,35 +6,18 @@ + - - - - - - - - - - - - - - - - - - @@ -51,8 +34,6 @@ - - @@ -64,7 +45,6 @@ - @@ -75,19 +55,11 @@ - - - - - - - - @@ -95,28 +67,18 @@ - - - - - - - - - - @@ -137,9 +99,6 @@ - - - @@ -152,16 +111,15 @@ + - - @@ -182,7 +140,6 @@ - @@ -221,7 +178,6 @@ - @@ -235,10 +191,8 @@ - - @@ -252,14 +206,11 @@ - - - @@ -268,7 +219,6 @@ - @@ -283,7 +233,7 @@ - + @@ -320,14 +270,11 @@ - - - @@ -350,18 +297,14 @@ - - - - @@ -378,14 +321,12 @@ - - @@ -409,10 +350,6 @@ - - - - @@ -421,45 +358,442 @@ - - + + + + + + + + + + + + + + + + + + + + + + - - - - + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -559,1311 +893,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -1871,1799 +902,712 @@ - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + - - - - + + - - - + + - - - - + + + - - - - - - - - - - + + + + + - - - - - + + + + + + + + - - - - + + + + + - - - - - - + + + + + - - - - + + + + + + + - - - + + + + + - - - + + + + + - - - + + + + + - - - - - + + + + + - - - - - + + + - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - - + + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - - + + - - - - - - - + + + + + + + - - - - + + + + + - - - - + + + + - - - - - - - - - - - + + - - - - - - + + + + + - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - + + + + + - - - + + + + + - - - - - - + + + + + + + + + - - - - - - + + + + - - - - + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + - - - - + + + - - - + + + + + - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -3700,479 +1644,2617 @@ - - - - - - - - + + + + + + + + + + + + + + - - - + + + + + - - - - + + + + + - - - - - + + + + + - - - + + + - - - + + + + + - - - - - - - - - - - - - - - + + + + + + - - + + + + - - + + + - - + + + + + - - + + + + + - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - + + + + + + + + + - + - - - - + - - - - + - - - - + - - - - + - - - - + - - - - + - - - - + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + - - - - - - + + + - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4204,881 +4286,85 @@ - + + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5116,125 +4402,2407 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - + + + + - - + + - - - - - + + + + - - - - - + + + - - - - + + + + + - - - + + + + - - - + + + + - - - - + + + + - + - - + + - - - - + + + + - - + + + + + + + + + + - - - + + + + - - - - - - - - - - - - - - - - - - - - + + + - - - - + + + - - - - - - + + + - - + + - + - + - - + + @@ -5268,16 +6836,34 @@ - - + + - - + + - - - + + + + + + + + + + + + + + + + + + + + + @@ -5290,959 +6876,929 @@ - - - - - - - - - - + + + + + + - - - - - - - - - - - - + + - + - + - + - + - + - + - + - + - - + + - - + + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - + + + + + - - + + + + + - - - - - - + + + + + - - - - + + + + + - - - - - - + + + - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - + + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + - - - - - + + + + + - - - - + + + + - - + + - - - + + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - + + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - + + + + + - - - - - + + + + + - - - + + + + - - - - - - - - - - - + + + + + - + - - + + - - - - + + + + - - - + + + + - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - + + + + + + + + - - - + + + + + + + + - - - + + + + + + + + + + + + + + - - - + + + - - - + + + - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - + - + - + + + + + + + + + + + + + + + + - - - - + - + - - - - - - - - - - - - - - - - + - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + - - + - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - + + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + - - + + + + - - + + + + - - - - - - - - - - - + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - - + + - - - - - - + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_changelist.c b/sys/contrib/openzfs/lib/libzfs/libzfs_changelist.c index 1592b75eb09..4d90a511f60 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_changelist.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_changelist.c @@ -284,7 +284,7 @@ changelist_postfix(prop_changelist_t *clp) /* * Is this "dataset" a child of "parent"? */ -boolean_t +static boolean_t isa_child_of(const char *dataset, const char *parent) { int len; diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c b/sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c index fe3a0f28360..c3cded24f6b 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c @@ -26,6 +26,16 @@ #include #include #include +#if LIBFETCH_DYNAMIC +#include +#endif +#if LIBFETCH_IS_FETCH +#include +#include +#include +#elif LIBFETCH_IS_LIBCURL +#include +#endif #include #include "libzfs_impl.h" #include "zfeature_common.h" @@ -51,12 +61,6 @@ * technically ok if the salt is known to the attacker). */ -typedef enum key_locator { - KEY_LOCATOR_NONE, - KEY_LOCATOR_PROMPT, - KEY_LOCATOR_URI -} key_locator_t; - #define MIN_PASSPHRASE_LEN 8 #define MAX_PASSPHRASE_LEN 512 #define MAX_KEY_PROMPT_ATTEMPTS 3 @@ -65,9 +69,13 @@ static int caught_interrupt; static int get_key_material_file(libzfs_handle_t *, const char *, const char *, zfs_keyformat_t, boolean_t, uint8_t **, size_t *); +static int get_key_material_https(libzfs_handle_t *, const char *, const char *, + zfs_keyformat_t, boolean_t, uint8_t **, size_t *); static zfs_uri_handler_t uri_handlers[] = { { "file", get_key_material_file }, + { "https", get_key_material_https }, + { "http", get_key_material_https }, { NULL, NULL } }; @@ -77,7 +85,7 @@ pkcs11_get_urandom(uint8_t *buf, size_t bytes) int rand; ssize_t bytes_read = 0; - rand = open("/dev/urandom", O_RDONLY); + rand = open("/dev/urandom", O_RDONLY | O_CLOEXEC); if (rand < 0) return (rand); @@ -474,7 +482,7 @@ get_key_material_file(libzfs_handle_t *hdl, const char *uri, if (strlen(uri) < 7) return (EINVAL); - if ((f = fopen(uri + 7, "r")) == NULL) { + if ((f = fopen(uri + 7, "re")) == NULL) { ret = errno; errno = 0; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, @@ -489,6 +497,178 @@ get_key_material_file(libzfs_handle_t *hdl, const char *uri, return (ret); } +static int +get_key_material_https(libzfs_handle_t *hdl, const char *uri, + const char *fsname, zfs_keyformat_t keyformat, boolean_t newkey, + uint8_t **restrict buf, size_t *restrict len_out) +{ + int ret = 0; + FILE *key = NULL; + boolean_t is_http = strncmp(uri, "http:", strlen("http:")) == 0; + + if (strlen(uri) < (is_http ? 7 : 8)) { + ret = EINVAL; + goto end; + } + +#if LIBFETCH_DYNAMIC +#define LOAD_FUNCTION(func) \ + __typeof__(func) *func = dlsym(hdl->libfetch, #func); + + if (hdl->libfetch == NULL) + hdl->libfetch = dlopen(LIBFETCH_SONAME, RTLD_LAZY); + + if (hdl->libfetch == NULL) { + hdl->libfetch = (void *)-1; + char *err = dlerror(); + if (err) + hdl->libfetch_load_error = strdup(err); + } + + if (hdl->libfetch == (void *)-1) { + ret = ENOSYS; + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "Couldn't load %s: %s"), + LIBFETCH_SONAME, hdl->libfetch_load_error ?: "(?)"); + goto end; + } + + boolean_t ok; +#if LIBFETCH_IS_FETCH + LOAD_FUNCTION(fetchGetURL); + char *fetchLastErrString = dlsym(hdl->libfetch, "fetchLastErrString"); + + ok = fetchGetURL && fetchLastErrString; +#elif LIBFETCH_IS_LIBCURL + LOAD_FUNCTION(curl_easy_init); + LOAD_FUNCTION(curl_easy_setopt); + LOAD_FUNCTION(curl_easy_perform); + LOAD_FUNCTION(curl_easy_cleanup); + LOAD_FUNCTION(curl_easy_strerror); + LOAD_FUNCTION(curl_easy_getinfo); + + ok = curl_easy_init && curl_easy_setopt && curl_easy_perform && + curl_easy_cleanup && curl_easy_strerror && curl_easy_getinfo; +#endif + if (!ok) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "keylocation=%s back-end %s missing symbols."), + is_http ? "http://" : "https://", LIBFETCH_SONAME); + ret = ENOSYS; + goto end; + } +#endif + +#if LIBFETCH_IS_FETCH + key = fetchGetURL(uri, ""); + if (key == NULL) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "Couldn't GET %s: %s"), + uri, fetchLastErrString); + ret = ENETDOWN; + } +#elif LIBFETCH_IS_LIBCURL + CURL *curl = curl_easy_init(); + if (curl == NULL) { + ret = ENOTSUP; + goto end; + } + + int kfd = -1; +#ifdef O_TMPFILE + kfd = open(getenv("TMPDIR") ?: "/tmp", + O_RDWR | O_TMPFILE | O_EXCL | O_CLOEXEC, 0600); + if (kfd != -1) + goto kfdok; +#endif + + char *path; + if (asprintf(&path, + "%s/libzfs-XXXXXXXX.https", getenv("TMPDIR") ?: "/tmp") == -1) { + ret = ENOMEM; + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s"), + strerror(ret)); + goto end; + } + + kfd = mkostemps(path, strlen(".https"), O_CLOEXEC); + if (kfd == -1) { + ret = errno; + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "Couldn't create temporary file %s: %s"), + path, strerror(ret)); + free(path); + goto end; + } + (void) unlink(path); + free(path); + +kfdok: + if ((key = fdopen(kfd, "r+")) == NULL) { + ret = errno; + free(path); + (void) close(kfd); + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "Couldn't reopen temporary file: %s"), strerror(ret)); + goto end; + } + + char errbuf[CURL_ERROR_SIZE] = ""; + char *cainfo = getenv("SSL_CA_CERT_FILE"); /* matches fetch(3) */ + char *capath = getenv("SSL_CA_CERT_PATH"); /* matches fetch(3) */ + char *clcert = getenv("SSL_CLIENT_CERT_FILE"); /* matches fetch(3) */ + char *clkey = getenv("SSL_CLIENT_KEY_FILE"); /* matches fetch(3) */ + (void) curl_easy_setopt(curl, CURLOPT_URL, uri); + (void) curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + (void) curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 30000L); + (void) curl_easy_setopt(curl, CURLOPT_WRITEDATA, key); + (void) curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf); + if (cainfo != NULL) + (void) curl_easy_setopt(curl, CURLOPT_CAINFO, cainfo); + if (capath != NULL) + (void) curl_easy_setopt(curl, CURLOPT_CAPATH, capath); + if (clcert != NULL) + (void) curl_easy_setopt(curl, CURLOPT_SSLCERT, clcert); + if (clkey != NULL) + (void) curl_easy_setopt(curl, CURLOPT_SSLKEY, clkey); + + CURLcode res = curl_easy_perform(curl); + + if (res != CURLE_OK) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "Failed to connect to %s: %s"), + uri, strlen(errbuf) ? errbuf : curl_easy_strerror(res)); + ret = ENETDOWN; + } else { + long resp = 200; + (void) curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &resp); + + if (resp < 200 || resp >= 300) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "Couldn't GET %s: %ld"), + uri, resp); + ret = ENOENT; + } else + rewind(key); + } + + curl_easy_cleanup(curl); +#else + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "No keylocation=%s back-end."), is_http ? "http://" : "https://"); + ret = ENOSYS; +#endif + +end: + if (ret == 0) + ret = get_key_material_raw(key, keyformat, buf, len_out); + + if (key != NULL) + fclose(key); + + return (ret); +} + /* * Attempts to fetch key material, no matter where it might live. The key * material is allocated and returned in km_out. *can_retry_out will be set @@ -518,7 +698,7 @@ get_key_material(libzfs_handle_t *hdl, boolean_t do_verify, boolean_t newkey, switch (keyloc) { case ZFS_KEYLOCATION_PROMPT: if (isatty(fileno(stdin))) { - can_retry = B_TRUE; + can_retry = keyformat != ZFS_KEYFORMAT_RAW; ret = get_key_interactive(hdl, fsname, keyformat, do_verify, newkey, &km, &kmlen); } else { @@ -960,7 +1140,7 @@ zfs_crypto_create(libzfs_handle_t *hdl, char *parent_name, nvlist_t *props, } ret = populate_create_encryption_params_nvlists(hdl, NULL, - B_FALSE, keyformat, keylocation, props, &wkeydata, + B_TRUE, keyformat, keylocation, props, &wkeydata, &wkeylen); if (ret != 0) goto out; diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c b/sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c index 4598e87f292..99e352dd488 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c @@ -32,6 +32,7 @@ * Copyright 2017-2018 RackTop Systems. * Copyright (c) 2019 Datto Inc. * Copyright (c) 2019, loli10K + * Copyright (c) 2021 Matt Fiddaman */ #include @@ -807,13 +808,13 @@ libzfs_mnttab_init(libzfs_handle_t *hdl) static int libzfs_mnttab_update(libzfs_handle_t *hdl) { + FILE *mnttab; struct mnttab entry; - /* Reopen MNTTAB to prevent reading stale data from open file */ - if (freopen(MNTTAB, "r", hdl->libzfs_mnttab) == NULL) + if ((mnttab = fopen(MNTTAB, "re")) == NULL) return (ENOENT); - while (getmntent(hdl->libzfs_mnttab, &entry) == 0) { + while (getmntent(mnttab, &entry) == 0) { mnttab_node_t *mtn; avl_index_t where; @@ -839,6 +840,7 @@ libzfs_mnttab_update(libzfs_handle_t *hdl) avl_add(&hdl->libzfs_mnttab_cache, mtn); } + (void) fclose(mnttab); return (0); } @@ -870,6 +872,7 @@ int libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname, struct mnttab *entry) { + FILE *mnttab; mnttab_node_t find; mnttab_node_t *mtn; int ret = ENOENT; @@ -880,16 +883,14 @@ libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname, if (avl_numnodes(&hdl->libzfs_mnttab_cache)) libzfs_mnttab_fini(hdl); - /* Reopen MNTTAB to prevent reading stale data from open file */ - if (freopen(MNTTAB, "r", hdl->libzfs_mnttab) == NULL) + if ((mnttab = fopen(MNTTAB, "re")) == NULL) return (ENOENT); srch.mnt_special = (char *)fsname; srch.mnt_fstype = MNTTYPE_ZFS; - if (getmntany(hdl->libzfs_mnttab, entry, &srch) == 0) - return (0); - else - return (ENOENT); + ret = getmntany(mnttab, entry, &srch) ? ENOENT : 0; + (void) fclose(mnttab); + return (ret); } pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock); @@ -1260,9 +1261,9 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl, intval > maxbs || !ISP2(intval))) { zfs_nicebytes(maxbs, buf, sizeof (buf)); zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "invalid '%s=%d' property: must be zero or " - "a power of 2 from 512B to %s"), propname, - intval, buf); + "invalid '%s=%llu' property: must be zero " + "or a power of 2 from 512B to %s"), + propname, (unsigned long long)intval, buf); (void) zfs_error(hdl, EZFS_BADPROP, errbuf); goto error; } @@ -1952,6 +1953,7 @@ zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received) if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0) return (zfs_standard_error(hdl, errno, errbuf)); + (void) get_stats(zhp); return (0); } @@ -2385,7 +2387,7 @@ get_clones_string(zfs_handle_t *zhp, char *propbuf, size_t proplen) nvpair_t *pair; value = zfs_get_clones_nvl(zhp); - if (value == NULL) + if (value == NULL || nvlist_empty(value)) return (-1); propbuf[0] = '\0'; @@ -3331,6 +3333,16 @@ zfs_get_type(const zfs_handle_t *zhp) return (zhp->zfs_type); } +/* + * Returns the type of the given zfs handle, + * or, if a snapshot, the type of the snapshotted dataset. + */ +zfs_type_t +zfs_get_underlying_type(const zfs_handle_t *zhp) +{ + return (zhp->zfs_head_type); +} + /* * Is one dataset name a child dataset of another? * @@ -4833,8 +4845,6 @@ zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type, zc.zc_nvlist_dst_size = sizeof (buf); if (zfs_ioctl(hdl, ZFS_IOC_USERSPACE_MANY, &zc) != 0) { - char errbuf[1024]; - if ((errno == ENOTSUP && (type == ZFS_PROP_USEROBJUSED || type == ZFS_PROP_GROUPOBJUSED || @@ -4846,10 +4856,9 @@ zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type, type == ZFS_PROP_PROJECTQUOTA))) break; - (void) snprintf(errbuf, sizeof (errbuf), + return (zfs_standard_error_fmt(hdl, errno, dgettext(TEXT_DOMAIN, - "cannot get used/quota for %s"), zc.zc_name); - return (zfs_standard_error_fmt(hdl, errno, errbuf)); + "cannot get used/quota for %s"), zc.zc_name)); } if (zc.zc_nvlist_dst_size == 0) break; @@ -5078,7 +5087,7 @@ zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag, (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); break; default: - (void) zfs_standard_error_fmt(hdl, errno, errbuf); + (void) zfs_standard_error(hdl, errno, errbuf); } } @@ -5097,7 +5106,7 @@ zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag, (void) zfs_error(hdl, EZFS_BADTYPE, errbuf); break; default: - (void) zfs_standard_error_fmt(hdl, + (void) zfs_standard_error(hdl, fnvpair_value_int32(elem), errbuf); } } @@ -5154,17 +5163,16 @@ tryagain: err = zfs_error(hdl, EZFS_NOENT, errbuf); break; default: - err = zfs_standard_error_fmt(hdl, errno, errbuf); + err = zfs_standard_error(hdl, errno, errbuf); break; } } else { /* success */ int rc = nvlist_unpack(nvbuf, zc.zc_nvlist_dst_size, nvl, 0); if (rc) { - (void) snprintf(errbuf, sizeof (errbuf), dgettext( + err = zfs_standard_error_fmt(hdl, rc, dgettext( TEXT_DOMAIN, "cannot get permissions on '%s'"), zc.zc_name); - err = zfs_standard_error_fmt(hdl, rc, errbuf); } } @@ -5217,7 +5225,7 @@ zfs_set_fsacl(zfs_handle_t *zhp, boolean_t un, nvlist_t *nvl) err = zfs_error(hdl, EZFS_NOENT, errbuf); break; default: - err = zfs_standard_error_fmt(hdl, errno, errbuf); + err = zfs_standard_error(hdl, errno, errbuf); break; } } @@ -5254,7 +5262,7 @@ zfs_get_holds(zfs_handle_t *zhp, nvlist_t **nvl) err = zfs_error(hdl, EZFS_NOENT, errbuf); break; default: - err = zfs_standard_error_fmt(hdl, errno, errbuf); + err = zfs_standard_error(hdl, errno, errbuf); break; } } @@ -5334,7 +5342,7 @@ zfs_get_holds(zfs_handle_t *zhp, nvlist_t **nvl) * 160k. Again, 128k is from SPA_OLD_MAXBLOCKSIZE and 160k is as calculated in * the 128k block example above. * - * The situtation is slightly different for dRAID since the minimum allocation + * The situation is slightly different for dRAID since the minimum allocation * size is the full group width. The same 8K block above would be written as * follows in a dRAID group: * diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c b/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c index 7941a588307..d46e23a2fc0 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c @@ -243,6 +243,7 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj) struct zfs_stat fsb, tsb; mode_t fmode, tmode; char fobjname[MAXPATHLEN], tobjname[MAXPATHLEN]; + boolean_t already_logged = B_FALSE; int fobjerr, tobjerr; int change; @@ -254,22 +255,36 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj) * we get ENOENT, then the object just didn't exist in that * snapshot. If we get ENOTSUP, then we tried to get * info on a non-ZPL object, which we don't care about anyway. + * For any other error we print a warning which includes the + * errno and continue. */ + fobjerr = get_stats_for_obj(di, di->fromsnap, dobj, fobjname, MAXPATHLEN, &fsb); - if (fobjerr && di->zerr != ENOENT && di->zerr != ENOTSUP) - return (-1); + if (fobjerr && di->zerr != ENOTSUP && di->zerr != ENOENT) { + zfs_error_aux(di->zhp->zfs_hdl, "%s", strerror(di->zerr)); + zfs_error(di->zhp->zfs_hdl, di->zerr, di->errbuf); + /* + * Let's not print an error for the same object more than + * once if it happens in both snapshots + */ + already_logged = B_TRUE; + } tobjerr = get_stats_for_obj(di, di->tosnap, dobj, tobjname, MAXPATHLEN, &tsb); - if (tobjerr && di->zerr != ENOENT && di->zerr != ENOTSUP) - return (-1); + if (tobjerr && di->zerr != ENOTSUP && di->zerr != ENOENT) { + if (!already_logged) { + zfs_error_aux(di->zhp->zfs_hdl, + "%s", strerror(di->zerr)); + zfs_error(di->zhp->zfs_hdl, di->zerr, di->errbuf); + } + } /* * Unallocated object sharing the same meta dnode block */ if (fobjerr && tobjerr) { - ASSERT(di->zerr == ENOENT || di->zerr == ENOTSUP); di->zerr = 0; return (0); } @@ -344,12 +359,11 @@ describe_free(FILE *fp, differ_info_t *di, uint64_t object, char *namebuf, { struct zfs_stat sb; - if (get_stats_for_obj(di, di->fromsnap, object, namebuf, - maxlen, &sb) != 0) { - return (-1); - } + (void) get_stats_for_obj(di, di->fromsnap, object, namebuf, + maxlen, &sb); + /* Don't print if in the delete queue on from side */ - if (di->zerr == ESTALE) { + if (di->zerr == ESTALE || di->zerr == ENOENT) { di->zerr = 0; return (0); } @@ -384,8 +398,6 @@ write_free_diffs(FILE *fp, differ_info_t *di, dmu_diff_record_t *dr) } err = describe_free(fp, di, zc.zc_obj, fobjname, MAXPATHLEN); - if (err) - break; } else if (errno == ESRCH) { break; } else { @@ -697,7 +709,7 @@ setup_differ_info(zfs_handle_t *zhp, const char *fromsnap, { di->zhp = zhp; - di->cleanupfd = open(ZFS_DEV, O_RDWR); + di->cleanupfd = open(ZFS_DEV, O_RDWR | O_CLOEXEC); VERIFY(di->cleanupfd >= 0); if (get_snapshot_names(di, fromsnap, tosnap) != 0) @@ -731,8 +743,8 @@ zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap, return (-1); } - if (pipe(pipefd)) { - zfs_error_aux(zhp->zfs_hdl, strerror(errno)); + if (pipe2(pipefd, O_CLOEXEC)) { + zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno)); teardown_differ_info(&di); return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED, errbuf)); } @@ -745,7 +757,7 @@ zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap, di.datafd = pipefd[0]; if (pthread_create(&tid, NULL, differ, &di)) { - zfs_error_aux(zhp->zfs_hdl, strerror(errno)); + zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno)); (void) close(pipefd[0]); (void) close(pipefd[1]); teardown_differ_info(&di); @@ -771,14 +783,14 @@ zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap, zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "\n Not an earlier snapshot from the same fs")); } else if (errno != EPIPE || di.zerr == 0) { - zfs_error_aux(zhp->zfs_hdl, strerror(errno)); + zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno)); } (void) close(pipefd[1]); (void) pthread_cancel(tid); (void) pthread_join(tid, NULL); teardown_differ_info(&di); if (di.zerr != 0 && di.zerr != EPIPE) { - zfs_error_aux(zhp->zfs_hdl, strerror(di.zerr)); + zfs_error_aux(zhp->zfs_hdl, "%s", strerror(di.zerr)); return (zfs_error(zhp->zfs_hdl, EZFS_DIFF, di.errbuf)); } else { return (zfs_error(zhp->zfs_hdl, EZFS_DIFFDATA, errbuf)); @@ -789,7 +801,7 @@ zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap, (void) pthread_join(tid, NULL); if (di.zerr != 0) { - zfs_error_aux(zhp->zfs_hdl, strerror(di.zerr)); + zfs_error_aux(zhp->zfs_hdl, "%s", strerror(di.zerr)); return (zfs_error(zhp->zfs_hdl, EZFS_DIFF, di.errbuf)); } teardown_differ_info(&di); diff --git a/sys/contrib/openzfs/include/libzfs_impl.h b/sys/contrib/openzfs/lib/libzfs/libzfs_impl.h similarity index 65% rename from sys/contrib/openzfs/include/libzfs_impl.h rename to sys/contrib/openzfs/lib/libzfs/libzfs_impl.h index dfb63285c1f..ce7373582f0 100644 --- a/sys/contrib/openzfs/include/libzfs_impl.h +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_impl.h @@ -30,7 +30,6 @@ #define _LIBZFS_IMPL_H #include -#include #include #include #include @@ -48,7 +47,6 @@ extern "C" { struct libzfs_handle { int libzfs_error; int libzfs_fd; - FILE *libzfs_mnttab; zpool_handle_t *libzfs_pool_handles; uu_avl_pool_t *libzfs_ns_avlpool; uu_avl_t *libzfs_ns_avl; @@ -57,7 +55,6 @@ struct libzfs_handle { char libzfs_action[1024]; char libzfs_desc[1024]; int libzfs_printerr; - int libzfs_storeerr; /* stuff error messages into buffer */ boolean_t libzfs_mnttab_enable; /* * We need a lock to handle the case where parallel mount @@ -68,10 +65,11 @@ struct libzfs_handle { pthread_mutex_t libzfs_mnttab_cache_lock; avl_tree_t libzfs_mnttab_cache; int libzfs_pool_iter; - char libzfs_chassis_id[256]; boolean_t libzfs_prop_debug; regex_t libzfs_urire; uint64_t libzfs_max_nvlist; + void *libfetch; + char *libfetch_load_error; }; struct zfs_handle { @@ -133,27 +131,31 @@ typedef struct zfs_uri_handler { #define CONFIG_BUF_MINSIZE 262144 -int zfs_error(libzfs_handle_t *, int, const char *); -int zfs_error_fmt(libzfs_handle_t *, int, const char *, ...); -void zfs_error_aux(libzfs_handle_t *, const char *, ...); -void *zfs_alloc(libzfs_handle_t *, size_t); -void *zfs_realloc(libzfs_handle_t *, void *, size_t, size_t); -char *zfs_asprintf(libzfs_handle_t *, const char *, ...); -char *zfs_strdup(libzfs_handle_t *, const char *); -int no_memory(libzfs_handle_t *); +extern int zfs_error(libzfs_handle_t *, int, const char *); +extern int zfs_error_fmt(libzfs_handle_t *, int, const char *, ...) + __attribute__((format(printf, 3, 4))); +extern void zfs_error_aux(libzfs_handle_t *, const char *, ...) + __attribute__((format(printf, 2, 3))); +extern void *zfs_alloc(libzfs_handle_t *, size_t); +extern void *zfs_realloc(libzfs_handle_t *, void *, size_t, size_t); +extern char *zfs_asprintf(libzfs_handle_t *, const char *, ...) + __attribute__((format(printf, 2, 3))); +extern char *zfs_strdup(libzfs_handle_t *, const char *); +extern int no_memory(libzfs_handle_t *); -int zfs_standard_error(libzfs_handle_t *, int, const char *); -int zfs_standard_error_fmt(libzfs_handle_t *, int, const char *, ...); -void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *); -int zpool_standard_error(libzfs_handle_t *, int, const char *); -int zpool_standard_error_fmt(libzfs_handle_t *, int, const char *, ...); +extern int zfs_standard_error_fmt(libzfs_handle_t *, int, const char *, ...) + __attribute__((format(printf, 3, 4))); +extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *); +extern int zpool_standard_error(libzfs_handle_t *, int, const char *); +extern int zpool_standard_error_fmt(libzfs_handle_t *, int, const char *, ...) + __attribute__((format(printf, 3, 4))); -zfs_handle_t *make_dataset_handle_zc(libzfs_handle_t *, zfs_cmd_t *); -zfs_handle_t *make_dataset_simple_handle_zc(zfs_handle_t *, zfs_cmd_t *); +extern zfs_handle_t *make_dataset_handle_zc(libzfs_handle_t *, zfs_cmd_t *); +extern zfs_handle_t *make_dataset_simple_handle_zc(zfs_handle_t *, zfs_cmd_t *); -int zprop_parse_value(libzfs_handle_t *, nvpair_t *, int, zfs_type_t, +extern int zprop_parse_value(libzfs_handle_t *, nvpair_t *, int, zfs_type_t, nvlist_t *, char **, uint64_t *, const char *); -int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp, +extern int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp, zfs_type_t type); /* @@ -173,44 +175,42 @@ int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp, typedef struct prop_changelist prop_changelist_t; -int zcmd_alloc_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, size_t); -int zcmd_write_src_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *); -int zcmd_write_conf_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *); -int zcmd_expand_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *); -int zcmd_read_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t **); -void zcmd_free_nvlists(zfs_cmd_t *); +extern int zcmd_alloc_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, size_t); +extern int zcmd_write_src_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *); +extern int zcmd_write_conf_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *); +extern int zcmd_expand_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *); +extern int zcmd_read_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t **); +extern void zcmd_free_nvlists(zfs_cmd_t *); -int changelist_prefix(prop_changelist_t *); -int changelist_postfix(prop_changelist_t *); -void changelist_rename(prop_changelist_t *, const char *, const char *); -void changelist_remove(prop_changelist_t *, const char *); -void changelist_free(prop_changelist_t *); -prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int, int); -int changelist_unshare(prop_changelist_t *, zfs_share_proto_t *); -int changelist_haszonedchild(prop_changelist_t *); +extern int changelist_prefix(prop_changelist_t *); +extern int changelist_postfix(prop_changelist_t *); +extern void changelist_rename(prop_changelist_t *, const char *, const char *); +extern void changelist_remove(prop_changelist_t *, const char *); +extern void changelist_free(prop_changelist_t *); +extern prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int, + int); +extern int changelist_unshare(prop_changelist_t *, zfs_share_proto_t *); +extern int changelist_haszonedchild(prop_changelist_t *); -void remove_mountpoint(zfs_handle_t *); -int create_parents(libzfs_handle_t *, char *, int); -boolean_t isa_child_of(const char *dataset, const char *parent); +extern void remove_mountpoint(zfs_handle_t *); +extern int create_parents(libzfs_handle_t *, char *, int); -zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *); -zfs_handle_t *make_bookmark_handle(zfs_handle_t *, const char *, +extern zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *); +extern zfs_handle_t *make_bookmark_handle(zfs_handle_t *, const char *, nvlist_t *props); -int zpool_open_silent(libzfs_handle_t *, const char *, zpool_handle_t **); +extern int zpool_open_silent(libzfs_handle_t *, const char *, + zpool_handle_t **); -boolean_t zpool_name_valid(libzfs_handle_t *, boolean_t, const char *); +extern boolean_t zpool_name_valid(libzfs_handle_t *, boolean_t, const char *); -int zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type, +extern int zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type, boolean_t modifying); -void namespace_clear(libzfs_handle_t *); +extern void namespace_clear(libzfs_handle_t *); extern int zfs_parse_options(char *, zfs_share_proto_t); -extern int zfs_unshare_proto(zfs_handle_t *, - const char *, zfs_share_proto_t *); - typedef struct { zfs_prop_t p_prop; char *p_name; @@ -244,8 +244,8 @@ extern proto_table_t proto_table[PROTO_END]; extern int do_mount(zfs_handle_t *zhp, const char *mntpt, char *opts, int flags); extern int do_unmount(const char *mntpt, int flags); -extern int zfs_mount_delegation_check(void); extern int zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto); +extern int zfs_unshare_proto(zfs_handle_t *, const char *, zfs_share_proto_t *); extern int unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint, zfs_share_proto_t proto); extern boolean_t zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen, diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_import.c b/sys/contrib/openzfs/lib/libzfs/libzfs_import.c index 64fa31c67d0..0d375b35516 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_import.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_import.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include "libzfs_impl.h" #include #include diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_iter.c b/sys/contrib/openzfs/lib/libzfs/libzfs_iter.c index 7ee326bc690..7806e21cd9a 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_iter.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_iter.c @@ -565,7 +565,7 @@ zfs_iter_mounted(zfs_handle_t *zhp, zfs_iter_f func, void *data) FILE *mnttab; int err = 0; - if ((mnttab = fopen(MNTTAB, "r")) == NULL) + if ((mnttab = fopen(MNTTAB, "re")) == NULL) return (ENOENT); while (err == 0 && getmntent(mnttab, &entry) == 0) { diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_mount.c b/sys/contrib/openzfs/lib/libzfs/libzfs_mount.c index 2a543daac9a..b074a6e6f37 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_mount.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_mount.c @@ -95,7 +95,7 @@ static int mount_tp_nthr = 512; /* tpool threads for multi-threaded mounting */ static void zfs_mount_task(void *); -zfs_share_type_t zfs_is_shared_proto(zfs_handle_t *, char **, +static zfs_share_type_t zfs_is_shared_proto(zfs_handle_t *, char **, zfs_share_proto_t); /* @@ -107,16 +107,16 @@ proto_table_t proto_table[PROTO_END] = { {ZFS_PROP_SHARESMB, "smb", EZFS_SHARESMBFAILED, EZFS_UNSHARESMBFAILED}, }; -zfs_share_proto_t nfs_only[] = { +static zfs_share_proto_t nfs_only[] = { PROTO_NFS, PROTO_END }; -zfs_share_proto_t smb_only[] = { +static zfs_share_proto_t smb_only[] = { PROTO_SMB, PROTO_END }; -zfs_share_proto_t share_all_proto[] = { +static zfs_share_proto_t share_all_proto[] = { PROTO_NFS, PROTO_SMB, PROTO_END @@ -385,6 +385,9 @@ zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags, struct stat buf; char mntopts[MNT_LINE_MAX]; char overlay[ZFS_MAXPROPLEN]; + char prop_encroot[MAXNAMELEN]; + boolean_t is_encroot; + zfs_handle_t *encroot_hp = zhp; libzfs_handle_t *hdl = zhp->zfs_hdl; uint64_t keystatus; int remount = 0, rc; @@ -443,7 +446,27 @@ zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags, */ if (keystatus == ZFS_KEYSTATUS_UNAVAILABLE) { if (flags & MS_CRYPT) { - rc = zfs_crypto_load_key(zhp, B_FALSE, NULL); + rc = zfs_crypto_get_encryption_root(zhp, + &is_encroot, prop_encroot); + if (rc) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "Failed to get encryption root for " + "'%s'."), zfs_get_name(zhp)); + return (rc); + } + + if (!is_encroot) { + encroot_hp = zfs_open(hdl, prop_encroot, + ZFS_TYPE_DATASET); + if (encroot_hp == NULL) + return (hdl->libzfs_error); + } + + rc = zfs_crypto_load_key(encroot_hp, + B_FALSE, NULL); + + if (!is_encroot) + zfs_close(encroot_hp); if (rc) return (rc); } else { @@ -515,19 +538,17 @@ zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags, zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Insufficient privileges")); } else if (rc == ENOTSUP) { - char buf[256]; int spa_version; VERIFY(zfs_spa_version(zhp, &spa_version) == 0); - (void) snprintf(buf, sizeof (buf), - dgettext(TEXT_DOMAIN, "Can't mount a version %lld " + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "Can't mount a version %llu " "file system on a version %d pool. Pool must be" " upgraded to mount this file system."), (u_longlong_t)zfs_prop_get_int(zhp, ZFS_PROP_VERSION), spa_version); - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, buf)); } else { - zfs_error_aux(hdl, strerror(rc)); + zfs_error_aux(hdl, "%s", strerror(rc)); } return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), @@ -797,7 +818,7 @@ zfs_unshare(zfs_handle_t *zhp) /* * Check to see if the filesystem is currently shared. */ -zfs_share_type_t +static zfs_share_type_t zfs_is_shared_proto(zfs_handle_t *zhp, char **where, zfs_share_proto_t proto) { char *mountpoint; @@ -1430,7 +1451,6 @@ zfs_foreach_mountpoint(libzfs_handle_t *hdl, zfs_handle_t **handles, * Mount and share all datasets within the given pool. This assumes that no * datasets within the pool are currently mounted. */ -#pragma weak zpool_mount_datasets = zpool_enable_datasets int zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags) { @@ -1492,8 +1512,6 @@ mountpoint_compare(const void *a, const void *b) return (strcmp(mountb, mounta)); } -/* alias for 2002/240 */ -#pragma weak zpool_unmount_datasets = zpool_disable_datasets /* * Unshare and unmount all datasets within the given pool. We don't want to * rely on traversing the DSL to discover the filesystems within the pool, @@ -1505,6 +1523,7 @@ int zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force) { int used, alloc; + FILE *mnttab; struct mnttab entry; size_t namelen; char **mountpoints = NULL; @@ -1516,12 +1535,11 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force) namelen = strlen(zhp->zpool_name); - /* Reopen MNTTAB to prevent reading stale data from open file */ - if (freopen(MNTTAB, "r", hdl->libzfs_mnttab) == NULL) + if ((mnttab = fopen(MNTTAB, "re")) == NULL) return (ENOENT); used = alloc = 0; - while (getmntent(hdl->libzfs_mnttab, &entry) == 0) { + while (getmntent(mnttab, &entry) == 0) { /* * Ignore non-ZFS entries. */ @@ -1623,6 +1641,7 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force) ret = 0; out: + (void) fclose(mnttab); for (i = 0; i < used; i++) { if (datasets[i]) zfs_close(datasets[i]); diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c b/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c index 9ef97cd677f..adc36c47f29 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c @@ -467,8 +467,7 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname, char *slash, *check; struct stat64 statbuf; zpool_handle_t *zhp; - char badword[ZFS_MAXPROPLEN]; - char badfile[MAXPATHLEN]; + char report[1024]; if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) { (void) no_memory(hdl); @@ -564,8 +563,8 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname, if (intval < version || !SPA_VERSION_IS_SUPPORTED(intval)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "property '%s' number %d is invalid."), - propname, intval); + "property '%s' number %llu is invalid."), + propname, (unsigned long long)intval); (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); goto error; } @@ -575,10 +574,11 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname, if (intval != 0 && (intval < ASHIFT_MIN || intval > ASHIFT_MAX)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "property '%s' number %d is invalid, only " - "values between %" PRId32 " and " - "%" PRId32 " are allowed."), - propname, intval, ASHIFT_MIN, ASHIFT_MAX); + "property '%s' number %llu is invalid, " + "only values between %" PRId32 " and %" + PRId32 " are allowed."), + propname, (unsigned long long)intval, + ASHIFT_MIN, ASHIFT_MAX); (void) zfs_error(hdl, EZFS_BADPROP, errbuf); goto error; } @@ -679,33 +679,14 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname, break; case ZPOOL_PROP_COMPATIBILITY: - switch (zpool_load_compat(strval, NULL, - badword, badfile)) { + switch (zpool_load_compat(strval, NULL, report, 1024)) { case ZPOOL_COMPATIBILITY_OK: + case ZPOOL_COMPATIBILITY_WARNTOKEN: break; - case ZPOOL_COMPATIBILITY_READERR: - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "error reading feature file '%s'"), - badfile); - (void) zfs_error(hdl, EZFS_BADPROP, errbuf); - goto error; case ZPOOL_COMPATIBILITY_BADFILE: - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "feature file '%s' too large or not " - "newline-terminated"), - badfile); - (void) zfs_error(hdl, EZFS_BADPROP, errbuf); - goto error; - case ZPOOL_COMPATIBILITY_BADWORD: - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "unknown feature '%s' in feature " - "file '%s'"), - badword, badfile); - (void) zfs_error(hdl, EZFS_BADPROP, errbuf); - goto error; + case ZPOOL_COMPATIBILITY_BADTOKEN: case ZPOOL_COMPATIBILITY_NOFILES: - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "no feature files specified")); + zfs_error_aux(hdl, "%s", report); (void) zfs_error(hdl, EZFS_BADPROP, errbuf); goto error; } @@ -1668,10 +1649,6 @@ zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce, const char *log_str) { zfs_cmd_t zc = {"\0"}; - char msg[1024]; - - (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, - "cannot export '%s'"), zhp->zpool_name); (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); zc.zc_cookie = force; @@ -1686,11 +1663,13 @@ zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce, "'%s' has an active shared spare which could be" " used by other pools once '%s' is exported."), zhp->zpool_name, zhp->zpool_name); - return (zfs_error(zhp->zpool_hdl, EZFS_ACTIVE_SPARE, - msg)); + return (zfs_error_fmt(zhp->zpool_hdl, EZFS_ACTIVE_SPARE, + dgettext(TEXT_DOMAIN, "cannot export '%s'"), + zhp->zpool_name)); default: return (zpool_standard_error_fmt(zhp->zpool_hdl, errno, - msg)); + dgettext(TEXT_DOMAIN, "cannot export '%s'"), + zhp->zpool_name)); } } @@ -2100,7 +2079,7 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, "the zgenhostid(8) command.\n")); } - (void) zfs_error_aux(hdl, aux); + (void) zfs_error_aux(hdl, "%s", aux); } (void) zfs_error(hdl, EZFS_ACTIVE_POOL, desc); break; @@ -4540,13 +4519,10 @@ int zpool_events_clear(libzfs_handle_t *hdl, int *count) { zfs_cmd_t zc = {"\0"}; - char msg[1024]; - - (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, - "cannot clear events")); if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_CLEAR, &zc) != 0) - return (zpool_standard_error_fmt(hdl, errno, msg)); + return (zpool_standard_error(hdl, errno, + dgettext(TEXT_DOMAIN, "cannot clear events"))); if (count != NULL) *count = (int)zc.zc_cookie; /* # of events cleared */ @@ -4742,8 +4718,8 @@ zpool_get_bootenv(zpool_handle_t *zhp, nvlist_t **nvlp) * Arguments: * compatibility : string containing feature filenames * features : either NULL or pointer to array of boolean - * badtoken : either NULL or pointer to char[ZFS_MAXPROPLEN] - * badfile : either NULL or pointer to char[MAXPATHLEN] + * report : either NULL or pointer to string buffer + * rlen : length of "report" buffer * * compatibility is NULL (unset), "", "off", "legacy", or list of * comma-separated filenames. filenames should either be absolute, @@ -4752,48 +4728,56 @@ zpool_get_bootenv(zpool_handle_t *zhp, nvlist_t **nvlp) * 2) ZPOOL_DATA_COMPAT_D (eg: /usr/share/zfs/compatibility.d). * (Unset), "" or "off" => enable all features * "legacy" => disable all features + * * Any feature names read from files which match unames in spa_feature_table * will have the corresponding boolean set in the features array (if non-NULL). * If more than one feature set specified, only features present in *all* of * them will be set. * - * An unreadable filename will be strlcpy'd to badfile (if non-NULL). - * An unrecognized feature will be strlcpy'd to badtoken (if non-NULL). + * "report" if not NULL will be populated with a suitable status message. * * Return values: * ZPOOL_COMPATIBILITY_OK : files read and parsed ok - * ZPOOL_COMPATIBILITY_READERR : file could not be opened / mmap'd * ZPOOL_COMPATIBILITY_BADFILE : file too big or not a text file - * ZPOOL_COMPATIBILITY_BADWORD : file contains invalid feature name - * ZPOOL_COMPATIBILITY_NOFILES : no file names found + * ZPOOL_COMPATIBILITY_BADTOKEN : SYSCONF file contains invalid feature name + * ZPOOL_COMPATIBILITY_WARNTOKEN : DATA file contains invalid feature name + * ZPOOL_COMPATIBILITY_NOFILES : no feature files found */ zpool_compat_status_t -zpool_load_compat(const char *compatibility, - boolean_t *features, char *badtoken, char *badfile) +zpool_load_compat(const char *compat, boolean_t *features, char *report, + size_t rlen) { int sdirfd, ddirfd, featfd; - int i; struct stat fs; - char *fc; /* mmap of file */ - char *ps, *ls, *ws; /* strtok state */ + char *fc; + char *ps, *ls, *ws; char *file, *line, *word; - char filenames[ZFS_MAXPROPLEN]; - int filecount = 0; + + char l_compat[ZFS_MAXPROPLEN]; + + boolean_t ret_nofiles = B_TRUE; + boolean_t ret_badfile = B_FALSE; + boolean_t ret_badtoken = B_FALSE; + boolean_t ret_warntoken = B_FALSE; /* special cases (unset), "" and "off" => enable all features */ - if (compatibility == NULL || compatibility[0] == '\0' || - strcmp(compatibility, ZPOOL_COMPAT_OFF) == 0) { + if (compat == NULL || compat[0] == '\0' || + strcmp(compat, ZPOOL_COMPAT_OFF) == 0) { if (features != NULL) - for (i = 0; i < SPA_FEATURES; i++) + for (uint_t i = 0; i < SPA_FEATURES; i++) features[i] = B_TRUE; + if (report != NULL) + strlcpy(report, gettext("all features enabled"), rlen); return (ZPOOL_COMPATIBILITY_OK); } /* Final special case "legacy" => disable all features */ - if (strcmp(compatibility, ZPOOL_COMPAT_LEGACY) == 0) { + if (strcmp(compat, ZPOOL_COMPAT_LEGACY) == 0) { if (features != NULL) - for (i = 0; i < SPA_FEATURES; i++) + for (uint_t i = 0; i < SPA_FEATURES; i++) features[i] = B_FALSE; + if (report != NULL) + strlcpy(report, gettext("all features disabled"), rlen); return (ZPOOL_COMPATIBILITY_OK); } @@ -4801,122 +4785,164 @@ zpool_load_compat(const char *compatibility, * Start with all true; will be ANDed with results from each file */ if (features != NULL) - for (i = 0; i < SPA_FEATURES; i++) + for (uint_t i = 0; i < SPA_FEATURES; i++) features[i] = B_TRUE; + char err_badfile[1024] = ""; + char err_badtoken[1024] = ""; + /* * We ignore errors from the directory open() * as they're only needed if the filename is relative * which will be checked during the openat(). */ -#ifdef O_PATH - sdirfd = open(ZPOOL_SYSCONF_COMPAT_D, O_DIRECTORY | O_PATH); - ddirfd = open(ZPOOL_DATA_COMPAT_D, O_DIRECTORY | O_PATH); + +/* O_PATH safer than O_RDONLY if system allows it */ +#if defined(O_PATH) +#define ZC_DIR_FLAGS (O_DIRECTORY | O_CLOEXEC | O_PATH) #else - sdirfd = open(ZPOOL_SYSCONF_COMPAT_D, O_DIRECTORY | O_RDONLY); - ddirfd = open(ZPOOL_DATA_COMPAT_D, O_DIRECTORY | O_RDONLY); +#define ZC_DIR_FLAGS (O_DIRECTORY | O_CLOEXEC | O_RDONLY) #endif - (void) strlcpy(filenames, compatibility, ZFS_MAXPROPLEN); - file = strtok_r(filenames, ",", &ps); - while (file != NULL) { - boolean_t features_local[SPA_FEATURES]; + sdirfd = open(ZPOOL_SYSCONF_COMPAT_D, ZC_DIR_FLAGS); + ddirfd = open(ZPOOL_DATA_COMPAT_D, ZC_DIR_FLAGS); + + (void) strlcpy(l_compat, compat, ZFS_MAXPROPLEN); + + for (file = strtok_r(l_compat, ",", &ps); + file != NULL; + file = strtok_r(NULL, ",", &ps)) { + + boolean_t l_features[SPA_FEATURES]; + + enum { Z_SYSCONF, Z_DATA } source; /* try sysconfdir first, then datadir */ - if ((featfd = openat(sdirfd, file, 0, O_RDONLY)) < 0) - featfd = openat(ddirfd, file, 0, O_RDONLY); - - if (featfd < 0 || fstat(featfd, &fs) < 0) { - (void) close(featfd); - (void) close(sdirfd); - (void) close(ddirfd); - if (badfile != NULL) - (void) strlcpy(badfile, file, MAXPATHLEN); - return (ZPOOL_COMPATIBILITY_READERR); + source = Z_SYSCONF; + if ((featfd = openat(sdirfd, file, O_RDONLY | O_CLOEXEC)) < 0) { + featfd = openat(ddirfd, file, O_RDONLY | O_CLOEXEC); + source = Z_DATA; } - /* Too big or too small */ - if (fs.st_size < 1 || fs.st_size > ZPOOL_COMPAT_MAXSIZE) { + /* File readable and correct size? */ + if (featfd < 0 || + fstat(featfd, &fs) < 0 || + fs.st_size < 1 || + fs.st_size > ZPOOL_COMPAT_MAXSIZE) { (void) close(featfd); - (void) close(sdirfd); - (void) close(ddirfd); - if (badfile != NULL) - (void) strlcpy(badfile, file, MAXPATHLEN); - return (ZPOOL_COMPATIBILITY_BADFILE); + strlcat(err_badfile, file, ZFS_MAXPROPLEN); + strlcat(err_badfile, " ", ZFS_MAXPROPLEN); + ret_badfile = B_TRUE; + continue; } +/* Prefault the file if system allows */ +#if defined(MAP_POPULATE) +#define ZC_MMAP_FLAGS (MAP_PRIVATE | MAP_POPULATE) +#elif defined(MAP_PREFAULT_READ) +#define ZC_MMAP_FLAGS (MAP_PRIVATE | MAP_PREFAULT_READ) +#else +#define ZC_MMAP_FLAGS (MAP_PRIVATE) +#endif + /* private mmap() so we can strtok safely */ - fc = (char *)mmap(NULL, fs.st_size, - PROT_READ|PROT_WRITE, MAP_PRIVATE, featfd, 0); + fc = (char *)mmap(NULL, fs.st_size, PROT_READ | PROT_WRITE, + ZC_MMAP_FLAGS, featfd, 0); (void) close(featfd); - if (fc < 0) { - (void) close(sdirfd); - (void) close(ddirfd); - if (badfile != NULL) - (void) strlcpy(badfile, file, MAXPATHLEN); - return (ZPOOL_COMPATIBILITY_READERR); - } - - /* Text file sanity check - last char should be newline */ - if (fc[fs.st_size - 1] != '\n') { + /* map ok, and last character == newline? */ + if (fc == MAP_FAILED || fc[fs.st_size - 1] != '\n') { (void) munmap((void *) fc, fs.st_size); - (void) close(sdirfd); - (void) close(ddirfd); - if (badfile != NULL) - (void) strlcpy(badfile, file, MAXPATHLEN); - return (ZPOOL_COMPATIBILITY_BADFILE); + strlcat(err_badfile, file, ZFS_MAXPROPLEN); + strlcat(err_badfile, " ", ZFS_MAXPROPLEN); + ret_badfile = B_TRUE; + continue; } - /* replace with NUL to ensure we have a delimiter */ + ret_nofiles = B_FALSE; + + for (uint_t i = 0; i < SPA_FEATURES; i++) + l_features[i] = B_FALSE; + + /* replace final newline with NULL to ensure string ends */ fc[fs.st_size - 1] = '\0'; - for (i = 0; i < SPA_FEATURES; i++) - features_local[i] = B_FALSE; - - line = strtok_r(fc, "\n", &ls); - while (line != NULL) { + for (line = strtok_r(fc, "\n", &ls); + line != NULL; + line = strtok_r(NULL, "\n", &ls)) { /* discard comments */ *(strchrnul(line, '#')) = '\0'; - word = strtok_r(line, ", \t", &ws); - while (word != NULL) { + for (word = strtok_r(line, ", \t", &ws); + word != NULL; + word = strtok_r(NULL, ", \t", &ws)) { /* Find matching feature name */ - for (i = 0; i < SPA_FEATURES; i++) { + uint_t f; + for (f = 0; f < SPA_FEATURES; f++) { zfeature_info_t *fi = - &spa_feature_table[i]; + &spa_feature_table[f]; if (strcmp(word, fi->fi_uname) == 0) { - features_local[i] = B_TRUE; + l_features[f] = B_TRUE; break; } } - if (i == SPA_FEATURES) { - if (badtoken != NULL) - (void) strlcpy(badtoken, word, - ZFS_MAXPROPLEN); - if (badfile != NULL) - (void) strlcpy(badfile, file, - MAXPATHLEN); - (void) munmap((void *) fc, fs.st_size); - (void) close(sdirfd); - (void) close(ddirfd); - return (ZPOOL_COMPATIBILITY_BADWORD); - } - word = strtok_r(NULL, ", \t", &ws); + if (f < SPA_FEATURES) + continue; + + /* found an unrecognized word */ + /* lightly sanitize it */ + if (strlen(word) > 32) + word[32] = '\0'; + for (char *c = word; *c != '\0'; c++) + if (!isprint(*c)) + *c = '?'; + + strlcat(err_badtoken, word, ZFS_MAXPROPLEN); + strlcat(err_badtoken, " ", ZFS_MAXPROPLEN); + if (source == Z_SYSCONF) + ret_badtoken = B_TRUE; + else + ret_warntoken = B_TRUE; } - line = strtok_r(NULL, "\n", &ls); } (void) munmap((void *) fc, fs.st_size); - if (features != NULL) { - for (i = 0; i < SPA_FEATURES; i++) - features[i] &= features_local[i]; - } - filecount++; - file = strtok_r(NULL, ",", &ps); + + if (features != NULL) + for (uint_t i = 0; i < SPA_FEATURES; i++) + features[i] &= l_features[i]; } (void) close(sdirfd); (void) close(ddirfd); - if (filecount == 0) + + /* Return the most serious error */ + if (ret_badfile) { + if (report != NULL) + snprintf(report, rlen, gettext("could not read/" + "parse feature file(s): %s"), err_badfile); + return (ZPOOL_COMPATIBILITY_BADFILE); + } + if (ret_nofiles) { + if (report != NULL) + strlcpy(report, + gettext("no valid compatibility files specified"), + rlen); return (ZPOOL_COMPATIBILITY_NOFILES); + } + if (ret_badtoken) { + if (report != NULL) + snprintf(report, rlen, gettext("invalid feature " + "name(s) in local compatibility files: %s"), + err_badtoken); + return (ZPOOL_COMPATIBILITY_BADTOKEN); + } + if (ret_warntoken) { + if (report != NULL) + snprintf(report, rlen, gettext("unrecognized feature " + "name(s) in distribution compatibility files: %s"), + err_badtoken); + return (ZPOOL_COMPATIBILITY_WARNTOKEN); + } + if (report != NULL) + strlcpy(report, gettext("compatibility set ok"), rlen); return (ZPOOL_COMPATIBILITY_OK); } diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c index bc887e72a23..2ba673fd09f 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c @@ -247,6 +247,7 @@ typedef struct send_data { boolean_t raw; boolean_t doall; boolean_t replicate; + boolean_t skipmissing; boolean_t verbose; boolean_t backup; boolean_t seenfrom; @@ -497,7 +498,8 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg) * - skip sending the current dataset if it was created later than * the parent tosnap * - return error if the current dataset was created earlier than - * the parent tosnap + * the parent tosnap, unless --skip-missing specified. Then + * just print a warning */ if (sd->tosnap != NULL && tosnap_txg == 0) { if (sd->tosnap_txg != 0 && txg > sd->tosnap_txg) { @@ -506,6 +508,11 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg) "skipping dataset %s: snapshot %s does " "not exist\n"), zhp->zfs_name, sd->tosnap); } + } else if (sd->skipmissing) { + (void) fprintf(stderr, dgettext(TEXT_DOMAIN, + "WARNING: skipping dataset %s and its children:" + " snapshot %s does not exist\n"), + zhp->zfs_name, sd->tosnap); } else { (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "cannot send %s@%s%s: snapshot %s@%s does not " @@ -649,8 +656,9 @@ out: static int gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap, const char *tosnap, boolean_t recursive, boolean_t raw, boolean_t doall, - boolean_t replicate, boolean_t verbose, boolean_t backup, boolean_t holds, - boolean_t props, nvlist_t **nvlp, avl_tree_t **avlp) + boolean_t replicate, boolean_t skipmissing, boolean_t verbose, + boolean_t backup, boolean_t holds, boolean_t props, nvlist_t **nvlp, + avl_tree_t **avlp) { zfs_handle_t *zhp; send_data_t sd = { 0 }; @@ -668,6 +676,7 @@ gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap, sd.raw = raw; sd.doall = doall; sd.replicate = replicate; + sd.skipmissing = skipmissing; sd.verbose = verbose; sd.backup = backup; sd.holds = holds; @@ -759,7 +768,7 @@ zfs_send_space(zfs_handle_t *zhp, const char *snapname, const char *from, case EFAULT: case EROFS: case EINVAL: - zfs_error_aux(hdl, strerror(error)); + zfs_error_aux(hdl, "%s", strerror(error)); return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); default: @@ -840,7 +849,7 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj, case ERANGE: case EFAULT: case EROFS: - zfs_error_aux(hdl, strerror(errno)); + zfs_error_aux(hdl, "%s", strerror(errno)); return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); default: @@ -1470,7 +1479,7 @@ estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags, err = pthread_create(&ptid, NULL, send_progress_thread, &pa); if (err != 0) { - zfs_error_aux(zhp->zfs_hdl, strerror(errno)); + zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno)); return (zfs_error(zhp->zfs_hdl, EZFS_THREADCREATEFAILED, errbuf)); } @@ -1496,7 +1505,7 @@ estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags, } if (err != 0) { - zfs_error_aux(zhp->zfs_hdl, strerror(err)); + zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err)); return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP, errbuf)); } @@ -1813,7 +1822,7 @@ zfs_send_resume_impl(libzfs_handle_t *hdl, sendflags_t *flags, int outfd, case ERANGE: case EFAULT: case EROFS: - zfs_error_aux(hdl, strerror(errno)); + zfs_error_aux(hdl, "%s", strerror(errno)); return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); default: @@ -1975,8 +1984,8 @@ send_conclusion_record(int fd, zio_cksum_t *zc) static int send_prelim_records(zfs_handle_t *zhp, const char *from, int fd, boolean_t gather_props, boolean_t recursive, boolean_t verbose, - boolean_t dryrun, boolean_t raw, boolean_t replicate, boolean_t backup, - boolean_t holds, boolean_t props, boolean_t doall, + boolean_t dryrun, boolean_t raw, boolean_t replicate, boolean_t skipmissing, + boolean_t backup, boolean_t holds, boolean_t props, boolean_t doall, nvlist_t **fssp, avl_tree_t **fsavlp) { int err = 0; @@ -2022,8 +2031,8 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd, } if ((err = gather_nvlist(zhp->zfs_hdl, tofs, - from, tosnap, recursive, raw, doall, replicate, verbose, - backup, holds, props, &fss, fsavlp)) != 0) { + from, tosnap, recursive, raw, doall, replicate, skipmissing, + verbose, backup, holds, props, &fss, fsavlp)) != 0) { return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP, errbuf)); } @@ -2073,13 +2082,13 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd, err = dump_record(&drr, packbuf, buflen, &zc, fd); free(packbuf); if (err != 0) { - zfs_error_aux(zhp->zfs_hdl, strerror(err)); + zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err)); return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP, errbuf)); } err = send_conclusion_record(fd, &zc); if (err != 0) { - zfs_error_aux(zhp->zfs_hdl, strerror(err)); + zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err)); return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP, errbuf)); } @@ -2119,7 +2128,6 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap, avl_tree_t *fsavl = NULL; static uint64_t holdseq; int spa_version; - int featureflags = 0; FILE *fout; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, @@ -2131,17 +2139,6 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap, return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf)); } - if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM) { - uint64_t version; - version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION); - if (version >= ZPL_VERSION_SA) { - featureflags |= DMU_BACKUP_FEATURE_SA_SPILL; - } - } - - if (flags->holds) - featureflags |= DMU_BACKUP_FEATURE_HOLDS; - if (flags->replicate || flags->doall || flags->props || flags->holds || flags->backup) { char full_tosnap_name[ZFS_MAX_DATASET_NAME_LEN]; @@ -2160,8 +2157,9 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap, err = send_prelim_records(tosnap, fromsnap, outfd, flags->replicate || flags->props || flags->holds, flags->replicate, flags->verbosity > 0, flags->dryrun, - flags->raw, flags->replicate, flags->backup, flags->holds, - flags->props, flags->doall, &fss, &fsavl); + flags->raw, flags->replicate, flags->skipmissing, + flags->backup, flags->holds, flags->props, flags->doall, + &fss, &fsavl); zfs_close(tosnap); if (err != 0) goto err_out; @@ -2207,7 +2205,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap, ++holdseq; (void) snprintf(sdd.holdtag, sizeof (sdd.holdtag), ".send-%d-%llu", getpid(), (u_longlong_t)holdseq); - sdd.cleanup_fd = open(ZFS_DEV, O_RDWR); + sdd.cleanup_fd = open(ZFS_DEV, O_RDWR | O_CLOEXEC); if (sdd.cleanup_fd < 0) { err = errno; goto stderr_out; @@ -2464,7 +2462,7 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags, */ err = send_prelim_records(zhp, NULL, fd, B_TRUE, B_FALSE, flags->verbosity > 0, flags->dryrun, flags->raw, - flags->replicate, flags->backup, flags->holds, + flags->replicate, B_FALSE, flags->backup, flags->holds, flags->props, flags->doall, NULL, NULL); if (err != 0) return (err); @@ -2497,7 +2495,7 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags, err = pthread_create(&ptid, NULL, send_progress_thread, &pa); if (err != 0) { - zfs_error_aux(zhp->zfs_hdl, strerror(errno)); + zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno)); return (zfs_error(zhp->zfs_hdl, EZFS_THREADCREATEFAILED, errbuf)); } @@ -2512,13 +2510,10 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags, (void) pthread_cancel(ptid); (void) pthread_join(ptid, &status); int error = (int)(uintptr_t)status; - if (error != 0 && status != PTHREAD_CANCELED) { - char errbuf[1024]; - (void) snprintf(errbuf, sizeof (errbuf), - dgettext(TEXT_DOMAIN, "progress thread exited " - "nonzero")); - return (zfs_standard_error(hdl, error, errbuf)); - } + if (error != 0 && status != PTHREAD_CANCELED) + return (zfs_standard_error_fmt(hdl, error, + dgettext(TEXT_DOMAIN, + "progress thread exited nonzero"))); } if (flags->props || flags->holds || flags->backup) { @@ -2566,7 +2561,7 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags, case EPIPE: case ERANGE: case EROFS: - zfs_error_aux(hdl, strerror(errno)); + zfs_error_aux(hdl, "%s", strerror(errno)); return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); default: @@ -3236,7 +3231,7 @@ again: deleted = fnvlist_alloc(); if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL, - recursive, B_TRUE, B_FALSE, recursive, B_FALSE, B_FALSE, + recursive, B_TRUE, B_FALSE, recursive, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_TRUE, &local_nv, &local_avl)) != 0) return (error); @@ -3941,24 +3936,6 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type, if (prop == ZFS_PROP_ORIGIN) continue; - /* - * we're trying to override or exclude a property that does not - * make sense for this type of dataset, but we don't want to - * fail if the receive is recursive: this comes in handy when - * the send stream contains, for instance, a child ZVOL and - * we're trying to receive it with "-o atime=on" - */ - if (!zfs_prop_valid_for_type(prop, type, B_FALSE) && - !zfs_prop_user(name)) { - if (recursive) - continue; - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "property '%s' does not apply to datasets of this " - "type"), name); - ret = zfs_error(hdl, EZFS_BADPROP, errbuf); - goto error; - } - /* raw streams can't override encryption properties */ if ((zfs_prop_encryption_key_param(prop) || prop == ZFS_PROP_ENCRYPTION) && raw) { @@ -3987,6 +3964,16 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type, * a property: this is done by forcing an explicit * inherit on the destination so the effective value is * not the one we received from the send stream. + */ + if (!zfs_prop_valid_for_type(prop, type, B_FALSE) && + !zfs_prop_user(name)) { + (void) fprintf(stderr, dgettext(TEXT_DOMAIN, + "Warning: %s: property '%s' does not " + "apply to datasets of this type\n"), + fsname, name); + continue; + } + /* * We do this only if the property is not already * locally-set, in which case its value will take * priority over the received anyway. @@ -4014,6 +4001,24 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type, fnvlist_add_nvpair(*oxprops, nvp); break; case DATA_TYPE_STRING: /* -o property=value */ + /* + * we're trying to override a property that does not + * make sense for this type of dataset, but we don't + * want to fail if the receive is recursive: this comes + * in handy when the send stream contains, for + * instance, a child ZVOL and we're trying to receive + * it with "-o atime=on" + */ + if (!zfs_prop_valid_for_type(prop, type, B_FALSE) && + !zfs_prop_user(name)) { + if (recursive) + continue; + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "property '%s' does not apply to datasets " + "of this type"), name); + ret = zfs_error(hdl, EZFS_BADPROP, errbuf); + goto error; + } fnvlist_add_nvpair(oprops, nvp); break; default: @@ -4576,26 +4581,6 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, (void) fflush(stdout); } - if (flags->dryrun) { - void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE); - - /* - * We have read the DRR_BEGIN record, but we have - * not yet read the payload. For non-dryrun sends - * this will be done by the kernel, so we must - * emulate that here, before attempting to read - * more records. - */ - err = recv_read(hdl, infd, buf, drr->drr_payloadlen, - flags->byteswap, NULL); - free(buf); - if (err != 0) - goto out; - - err = recv_skip(hdl, infd, flags->byteswap); - goto out; - } - /* * If this is the top-level dataset, record it so we can use it * for recursive operations later. @@ -4640,6 +4625,26 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, zfs_prop_to_name(ZFS_PROP_ENCRYPTION), ZIO_CRYPT_OFF); } + if (flags->dryrun) { + void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE); + + /* + * We have read the DRR_BEGIN record, but we have + * not yet read the payload. For non-dryrun sends + * this will be done by the kernel, so we must + * emulate that here, before attempting to read + * more records. + */ + err = recv_read(hdl, infd, buf, drr->drr_payloadlen, + flags->byteswap, NULL); + free(buf); + if (err != 0) + goto out; + + err = recv_skip(hdl, infd, flags->byteswap); + goto out; + } + err = ioctl_err = lzc_receive_with_cmdprops(destsnap, rcvprops, oxprops, wkeydata, wkeylen, origin, flags->force, flags->resumable, raw, infd, drr_noswap, -1, &read_bytes, &errflags, @@ -4729,8 +4734,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, */ *cp = '\0'; if (gather_nvlist(hdl, destsnap, NULL, NULL, B_FALSE, B_TRUE, - B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_TRUE, - &local_nv, &local_avl) == 0) { + B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, + B_TRUE, &local_nv, &local_avl) == 0) { *cp = '@'; fs = fsavl_find(local_avl, drrb->drr_toguid, NULL); fsavl_destroy(local_avl); @@ -5058,8 +5063,8 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, if (!DMU_STREAM_SUPPORTED(featureflags) || (hdrtype != DMU_SUBSTREAM && hdrtype != DMU_COMPOUNDSTREAM)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "stream has unsupported feature, feature flags = %lx"), - featureflags); + "stream has unsupported feature, feature flags = %llx"), + (unsigned long long)featureflags); return (zfs_error(hdl, EZFS_BADSTREAM, errbuf)); } diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_status.c b/sys/contrib/openzfs/lib/libzfs/libzfs_status.c index 5e5cb5f5d44..33d6e1bfdf8 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_status.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_status.c @@ -89,6 +89,7 @@ static char *zfs_msgid_table[] = { * ZPOOL_STATUS_REBUILDING * ZPOOL_STATUS_REBUILD_SCRUB * ZPOOL_STATUS_COMPATIBILITY_ERR + * ZPOOL_STATUS_INCOMPATIBLE_FEAT * ZPOOL_STATUS_OK */ }; @@ -453,11 +454,17 @@ check_status(nvlist_t *config, boolean_t isimport, /* * Outdated, but usable, version */ - if (SPA_VERSION_IS_SUPPORTED(version) && version != SPA_VERSION) - return (ZPOOL_STATUS_VERSION_OLDER); + if (SPA_VERSION_IS_SUPPORTED(version) && version != SPA_VERSION) { + /* "legacy" compatibility disables old version reporting */ + if (compat != NULL && strcmp(compat, ZPOOL_COMPAT_LEGACY) == 0) + return (ZPOOL_STATUS_OK); + else + return (ZPOOL_STATUS_VERSION_OLDER); + } /* - * Usable pool with disabled features + * Usable pool with disabled or superfluous features + * (superfluous = beyond what's requested by 'compatibility') */ if (version >= SPA_VERSION_FEATURES) { int i; @@ -475,18 +482,23 @@ check_status(nvlist_t *config, boolean_t isimport, } /* check against all features, or limited set? */ - boolean_t pool_features[SPA_FEATURES]; + boolean_t c_features[SPA_FEATURES]; - if (zpool_load_compat(compat, pool_features, NULL, NULL) != - ZPOOL_COMPATIBILITY_OK) + switch (zpool_load_compat(compat, c_features, NULL, 0)) { + case ZPOOL_COMPATIBILITY_OK: + case ZPOOL_COMPATIBILITY_WARNTOKEN: + break; + default: return (ZPOOL_STATUS_COMPATIBILITY_ERR); + } for (i = 0; i < SPA_FEATURES; i++) { zfeature_info_t *fi = &spa_feature_table[i]; if (!fi->fi_zfs_mod_supported) continue; - if (pool_features[i] && - !nvlist_exists(feat, fi->fi_guid)) + if (c_features[i] && !nvlist_exists(feat, fi->fi_guid)) return (ZPOOL_STATUS_FEAT_DISABLED); + if (!c_features[i] && nvlist_exists(feat, fi->fi_guid)) + return (ZPOOL_STATUS_INCOMPATIBLE_FEAT); } } diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_util.c b/sys/contrib/openzfs/lib/libzfs/libzfs_util.c index 95cb3295721..68e97e4830d 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_util.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_util.c @@ -44,6 +44,9 @@ #include #include #include +#if LIBFETCH_DYNAMIC +#include +#endif #include #include #include @@ -483,7 +486,7 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...) zfs_verror(hdl, EZFS_BADPROP, fmt, ap); break; default: - zfs_error_aux(hdl, strerror(error)); + zfs_error_aux(hdl, "%s", strerror(error)); zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap); break; } @@ -734,7 +737,7 @@ zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...) zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap); break; default: - zfs_error_aux(hdl, strerror(error)); + zfs_error_aux(hdl, "%s", strerror(error)); zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap); } @@ -782,8 +785,10 @@ zfs_asprintf(libzfs_handle_t *hdl, const char *fmt, ...) va_end(ap); - if (err < 0) + if (err < 0) { (void) no_memory(hdl); + ret = NULL; + } return (ret); } @@ -842,17 +847,13 @@ libzfs_read_stdout_from_fd(int fd, char **lines[]) size_t len = 0; char *line = NULL; char **tmp_lines = NULL, **tmp; - char *nl = NULL; - int rc; fp = fdopen(fd, "r"); - if (fp == NULL) + if (fp == NULL) { + close(fd); return (0); - while (1) { - rc = getline(&line, &len, fp); - if (rc == -1) - break; - + } + while (getline(&line, &len, fp) != -1) { tmp = realloc(tmp_lines, sizeof (*tmp_lines) * (lines_cnt + 1)); if (tmp == NULL) { /* Return the lines we were able to process */ @@ -860,13 +861,16 @@ libzfs_read_stdout_from_fd(int fd, char **lines[]) } tmp_lines = tmp; - /* Terminate newlines */ - if ((nl = strchr(line, '\n')) != NULL) - *nl = '\0'; - tmp_lines[lines_cnt] = line; - lines_cnt++; - line = NULL; + /* Remove newline if not EOF */ + if (line[strlen(line) - 1] == '\n') + line[strlen(line) - 1] = '\0'; + + tmp_lines[lines_cnt] = strdup(line); + if (tmp_lines[lines_cnt] == NULL) + break; + ++lines_cnt; } + free(line); fclose(fp); *lines = tmp_lines; return (lines_cnt); @@ -884,13 +888,13 @@ libzfs_run_process_impl(const char *path, char *argv[], char *env[], int flags, * Setup a pipe between our child and parent process if we're * reading stdout. */ - if ((lines != NULL) && pipe(link) == -1) + if (lines != NULL && pipe2(link, O_NONBLOCK | O_CLOEXEC) == -1) return (-EPIPE); - pid = vfork(); + pid = fork(); if (pid == 0) { /* Child process */ - devnull_fd = open("/dev/null", O_WRONLY); + devnull_fd = open("/dev/null", O_WRONLY | O_CLOEXEC); if (devnull_fd < 0) _exit(-1); @@ -900,15 +904,11 @@ libzfs_run_process_impl(const char *path, char *argv[], char *env[], int flags, else if (lines != NULL) { /* Save the output to lines[] */ dup2(link[1], STDOUT_FILENO); - close(link[0]); - close(link[1]); } if (!(flags & STDERR_VERBOSE)) (void) dup2(devnull_fd, STDERR_FILENO); - close(devnull_fd); - if (flags & NO_DEFAULT_PATH) { if (env == NULL) execv(path, argv); @@ -927,7 +927,8 @@ libzfs_run_process_impl(const char *path, char *argv[], char *env[], int flags, int status; while ((error = waitpid(pid, &status, 0)) == -1 && - errno == EINTR) { } + errno == EINTR) + ; if (error < 0 || !WIFEXITED(status)) return (-1); @@ -1024,24 +1025,13 @@ libzfs_init(void) return (NULL); } - if ((hdl->libzfs_fd = open(ZFS_DEV, O_RDWR|O_EXCL)) < 0) { - free(hdl); - return (NULL); - } - -#ifdef HAVE_SETMNTENT - if ((hdl->libzfs_mnttab = setmntent(MNTTAB, "r")) == NULL) { -#else - if ((hdl->libzfs_mnttab = fopen(MNTTAB, "r")) == NULL) { -#endif - (void) close(hdl->libzfs_fd); + if ((hdl->libzfs_fd = open(ZFS_DEV, O_RDWR|O_EXCL|O_CLOEXEC)) < 0) { free(hdl); return (NULL); } if (libzfs_core_init() != 0) { (void) close(hdl->libzfs_fd); - (void) fclose(hdl->libzfs_mnttab); free(hdl); return (NULL); } @@ -1060,7 +1050,6 @@ libzfs_init(void) &hdl->libzfs_max_nvlist))) { errno = error; (void) close(hdl->libzfs_fd); - (void) fclose(hdl->libzfs_mnttab); free(hdl); return (NULL); } @@ -1091,18 +1080,17 @@ void libzfs_fini(libzfs_handle_t *hdl) { (void) close(hdl->libzfs_fd); - if (hdl->libzfs_mnttab) -#ifdef HAVE_SETMNTENT - (void) endmntent(hdl->libzfs_mnttab); -#else - (void) fclose(hdl->libzfs_mnttab); -#endif zpool_free_handles(hdl); namespace_clear(hdl); libzfs_mnttab_fini(hdl); libzfs_core_fini(); regfree(&hdl->libzfs_urire); fletcher_4_fini(); +#if LIBFETCH_DYNAMIC + if (hdl->libfetch != (void *)-1 && hdl->libfetch != NULL) + (void) dlclose(hdl->libfetch); + free(hdl->libfetch_load_error); +#endif free(hdl); } @@ -1143,10 +1131,6 @@ zfs_path_to_zhandle(libzfs_handle_t *hdl, const char *path, zfs_type_t argtype) return (zfs_open(hdl, path, argtype)); } - /* Reopen MNTTAB to prevent reading stale data from open file */ - if (freopen(MNTTAB, "r", hdl->libzfs_mnttab) == NULL) - return (NULL); - if (getextmntent(path, &entry, &statbuf) != 0) return (NULL); diff --git a/sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_compat.c b/sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_compat.c index 0e8a3b12176..4d7421df8d3 100644 --- a/sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_compat.c +++ b/sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_compat.c @@ -23,7 +23,7 @@ * Copyright (c) 2013 Martin Matuska . All rights reserved. */ #include -#include +#include "../../libzfs_impl.h" #include #include #include @@ -52,8 +52,8 @@ execvPe(const char *name, const char *path, char * const *argv, const char **memp; size_t cnt, lp, ln; int eacces, save_errno; - char *cur, buf[MAXPATHLEN]; - const char *p, *bp; + char buf[MAXPATHLEN]; + const char *bp, *np, *op, *p; struct stat sb; eacces = 0; @@ -61,7 +61,7 @@ execvPe(const char *name, const char *path, char * const *argv, /* If it's an absolute or relative path name, it's easy. */ if (strchr(name, '/')) { bp = name; - cur = NULL; + op = NULL; goto retry; } bp = buf; @@ -72,23 +72,30 @@ execvPe(const char *name, const char *path, char * const *argv, return (-1); } - cur = alloca(strlen(path) + 1); - if (cur == NULL) { - errno = ENOMEM; - return (-1); - } - strcpy(cur, path); - while ((p = strsep(&cur, ":")) != NULL) { + op = path; + ln = strlen(name); + while (op != NULL) { + np = strchrnul(op, ':'); + /* * It's a SHELL path -- double, leading and trailing colons * mean the current directory. */ - if (*p == '\0') { + if (np == op) { + /* Empty component. */ p = "."; lp = 1; - } else - lp = strlen(p); - ln = strlen(name); + } else { + /* Non-empty component. */ + p = op; + lp = np - op; + } + + /* Advance to the next component or terminate after this. */ + if (*np == '\0') + op = NULL; + else + op = np + 1; /* * If the path is too long complain. This is a possible @@ -118,15 +125,31 @@ retry: (void) execve(bp, argv, envp); case ENOEXEC: for (cnt = 0; argv[cnt]; ++cnt) ; - memp = alloca((cnt + 2) * sizeof (char *)); + + /* + * cnt may be 0 above; always allocate at least + * 3 entries so that we can at least fit "sh", bp, and + * the NULL terminator. We can rely on cnt to take into + * account the NULL terminator in all other scenarios, + * as we drop argv[0]. + */ + memp = alloca(MAX(3, cnt + 2) * sizeof (char *)); if (memp == NULL) { /* errno = ENOMEM; XXX override ENOEXEC? */ goto done; } - memp[0] = "sh"; - memp[1] = bp; - bcopy(argv + 1, memp + 2, cnt * sizeof (char *)); - execve(_PATH_BSHELL, __DECONST(char **, memp), envp); + if (cnt > 0) { + memp[0] = argv[0]; + memp[1] = bp; + bcopy(argv + 1, memp + 2, + cnt * sizeof (char *)); + } else { + memp[0] = "sh"; + memp[1] = bp; + memp[2] = NULL; + } + (void) execve(_PATH_BSHELL, + __DECONST(char **, memp), envp); goto done; case ENOMEM: goto done; diff --git a/sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_zmount.c b/sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_zmount.c index e114b1e0ca6..e1febe6a2d9 100644 --- a/sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_zmount.c +++ b/sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_zmount.c @@ -43,7 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include "libzfs_impl.h" +#include "../../libzfs_impl.h" static void build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val, @@ -97,11 +97,6 @@ do_mount_(const char *spec, const char *dir, int mflag, char *fstype, iovlen = 0; if (strstr(optstr, MNTOPT_REMOUNT) != NULL) build_iovec(&iov, &iovlen, "update", NULL, 0); - if (strstr(optstr, MNTOPT_NOXATTR) == NULL && - strstr(optstr, MNTOPT_XATTR) == NULL && - strstr(optstr, MNTOPT_SAXATTR) == NULL && - strstr(optstr, MNTOPT_DIRXATTR) == NULL) - build_iovec(&iov, &iovlen, "xattr", NULL, 0); if (mflag & MS_RDONLY) build_iovec(&iov, &iovlen, "ro", NULL, 0); build_iovec(&iov, &iovlen, "fstype", fstype, (size_t)-1); diff --git a/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_mount_os.c b/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_mount_os.c index 21d64053862..547895d7e37 100644 --- a/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_mount_os.c +++ b/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_mount_os.c @@ -47,7 +47,7 @@ #include #include -#include "libzfs_impl.h" +#include "../../libzfs_impl.h" #include #define ZS_COMMENT 0x00000000 /* comment */ diff --git a/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_pool_os.c b/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_pool_os.c index e4f03aa43b4..90eb8db5079 100644 --- a/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_pool_os.c +++ b/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_pool_os.c @@ -49,7 +49,7 @@ #include "zfs_namecheck.h" #include "zfs_prop.h" -#include "libzfs_impl.h" +#include "../../libzfs_impl.h" #include "zfs_comutil.h" #include "zfeature_common.h" @@ -62,7 +62,7 @@ zpool_relabel_disk(libzfs_handle_t *hdl, const char *path, const char *msg) { int fd, error; - if ((fd = open(path, O_RDWR|O_DIRECT)) < 0) { + if ((fd = open(path, O_RDWR|O_DIRECT|O_CLOEXEC)) < 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot " "relabel '%s': unable to open device: %d"), path, errno); return (zfs_error(hdl, EZFS_OPENFAILED, msg)); @@ -107,7 +107,7 @@ read_efi_label(nvlist_t *config, diskaddr_t *sb) (void) snprintf(diskname, sizeof (diskname), "%s%s", DISK_ROOT, strrchr(path, '/')); - if ((fd = open(diskname, O_RDONLY|O_DIRECT)) >= 0) { + if ((fd = open(diskname, O_RDONLY|O_DIRECT|O_CLOEXEC)) >= 0) { struct dk_gpt *vtoc; if ((err = efi_alloc_and_read(fd, &vtoc)) >= 0) { @@ -159,7 +159,7 @@ zpool_label_disk_check(char *path) struct dk_gpt *vtoc; int fd, err; - if ((fd = open(path, O_RDONLY|O_DIRECT)) < 0) + if ((fd = open(path, O_RDONLY|O_DIRECT|O_CLOEXEC)) < 0) return (errno); if ((err = efi_alloc_and_read(fd, &vtoc)) != 0) { @@ -190,7 +190,7 @@ zpool_label_name(char *label_name, int label_size) uint64_t id = 0; int fd; - fd = open("/dev/urandom", O_RDONLY); + fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC); if (fd >= 0) { if (read(fd, &id, sizeof (id)) != sizeof (id)) id = 0; @@ -241,7 +241,7 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name) (void) snprintf(path, sizeof (path), "%s/%s", DISK_ROOT, name); - if ((fd = open(path, O_RDWR|O_DIRECT|O_EXCL)) < 0) { + if ((fd = open(path, O_RDWR|O_DIRECT|O_EXCL|O_CLOEXEC)) < 0) { /* * This shouldn't happen. We've long since verified that this * is a valid device. diff --git a/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_sendrecv_os.c b/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_sendrecv_os.c index eeb1f07f2de..593c38ec62d 100644 --- a/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_sendrecv_os.c +++ b/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_sendrecv_os.c @@ -22,7 +22,7 @@ #include -#include "libzfs_impl.h" +#include "../../libzfs_impl.h" #ifndef F_SETPIPE_SZ #define F_SETPIPE_SZ (F_SETLEASE + 7) @@ -35,7 +35,7 @@ void libzfs_set_pipe_max(int infd) { - FILE *procf = fopen("/proc/sys/fs/pipe-max-size", "r"); + FILE *procf = fopen("/proc/sys/fs/pipe-max-size", "re"); if (procf != NULL) { unsigned long max_psize; diff --git a/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c b/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c index 918a43f7d03..b116f92d97a 100644 --- a/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c +++ b/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c @@ -38,7 +38,7 @@ #include #include -#include "libzfs_impl.h" +#include "../../libzfs_impl.h" #include "zfs_prop.h" #include #include @@ -143,7 +143,7 @@ libzfs_load_module_impl(const char *module) start = gethrtime(); do { - fd = open(ZFS_DEV, O_RDWR); + fd = open(ZFS_DEV, O_RDWR | O_CLOEXEC); if (fd >= 0) { (void) close(fd); return (0); @@ -195,7 +195,7 @@ zfs_version_kernel(char *version, int len) int fd; int rlen; - if ((fd = open(ZFS_SYSFS_DIR "/version", O_RDONLY)) == -1) + if ((fd = open(ZFS_SYSFS_DIR "/version", O_RDONLY | O_CLOEXEC)) == -1) return (-1); if ((rlen = read(fd, version, len)) == -1) { diff --git a/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi b/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi index 02627e22941..574928cba08 100644 --- a/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi +++ b/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi @@ -1,12 +1,13 @@ + + - @@ -15,123 +16,123 @@ - + - + - - + + - + - + - - + + - + - + - + - - - + + + - - + + - + - + - - + + - + - + - - + + - - + + - + - + - - + + - + - - + + - + - - - - - + + + + + - + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - - + + @@ -286,147 +287,779 @@ - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - + - + - + + + + - + - + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - + - + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -440,148 +1073,115 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - + - - - - - - - + - - - - - - - - - - - - + - - - - + - - + + + + + + + - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + + @@ -658,2163 +1258,3305 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + - - + - + - + - - - - - - - - - - - - - - - - + - - + - + - - - - - - - - - - - - - - - + - + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + - - - - - - + + + + + + + - - - - + + + + + + + + - - - - - + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + - - - + + + + + + + - - - - - + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - - - - - - + + + + + - - - - - - - - + + - + - + - + - + - + - + - + - + - - + + + + - + - - - - - - - - - - - - - + + + + + + + + + + + + - - - - + + + + + - - + + + + + - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - + + - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - + - + - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + + + + + + + + - + - + - + - + - + - + - + - + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + - - - + + + - - - - + + + - - - - - + + + + + + + + diff --git a/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.c b/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.c index a3ba3b28427..ce33b215306 100644 --- a/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.c +++ b/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.c @@ -137,7 +137,7 @@ libzfs_core_init(void) { (void) pthread_mutex_lock(&g_lock); if (g_refcount == 0) { - g_fd = open(ZFS_DEV, O_RDWR); + g_fd = open(ZFS_DEV, O_RDWR|O_CLOEXEC); if (g_fd < 0) { (void) pthread_mutex_unlock(&g_lock); return (errno); @@ -158,8 +158,7 @@ libzfs_core_fini(void) (void) pthread_mutex_lock(&g_lock); ASSERT3S(g_refcount, >, 0); - if (g_refcount > 0) - g_refcount--; + g_refcount--; if (g_refcount == 0 && g_fd != -1) { (void) close(g_fd); @@ -323,6 +322,7 @@ lzc_rename(const char *source, const char *target) error = errno; return (error); } + int lzc_destroy(const char *fsname) { @@ -1025,7 +1025,8 @@ lzc_receive_with_header(const char *snapname, nvlist_t *props, * The 'errors' nvlist contains an entry for each unapplied received * property. Callers are responsible for freeing this nvlist. */ -int lzc_receive_one(const char *snapname, nvlist_t *props, +int +lzc_receive_one(const char *snapname, nvlist_t *props, const char *origin, boolean_t force, boolean_t resumable, boolean_t raw, int input_fd, const dmu_replay_record_t *begin_record, int cleanup_fd, uint64_t *read_bytes, uint64_t *errflags, uint64_t *action_handle, @@ -1044,7 +1045,8 @@ int lzc_receive_one(const char *snapname, nvlist_t *props, * exclude ('zfs receive -x') properties. Callers are responsible for freeing * this nvlist */ -int lzc_receive_with_cmdprops(const char *snapname, nvlist_t *props, +int +lzc_receive_with_cmdprops(const char *snapname, nvlist_t *props, nvlist_t *cmdprops, uint8_t *wkeydata, uint_t wkeylen, const char *origin, boolean_t force, boolean_t resumable, boolean_t raw, int input_fd, const dmu_replay_record_t *begin_record, int cleanup_fd, diff --git a/sys/contrib/openzfs/lib/libzfsbootenv/lzbe_device.c b/sys/contrib/openzfs/lib/libzfsbootenv/lzbe_device.c index 670efd8b060..2d8833b4fff 100644 --- a/sys/contrib/openzfs/lib/libzfsbootenv/lzbe_device.c +++ b/sys/contrib/openzfs/lib/libzfsbootenv/lzbe_device.c @@ -83,17 +83,16 @@ lzbe_set_boot_device(const char *pool, lzbe_flags_t flag, const char *device) } else { /* * Use device name directly if it does start with - * prefix "zfs:". Otherwise, add prefix and sufix. + * prefix "zfs:". Otherwise, add prefix and suffix. */ if (strncmp(device, "zfs:", 4) == 0) { fnvlist_add_string(nv, OS_BOOTONCE, device); } else { - descriptor = NULL; - if (asprintf(&descriptor, "zfs:%s:", device) > 0) + if (asprintf(&descriptor, "zfs:%s:", device) > 0) { fnvlist_add_string(nv, OS_BOOTONCE, descriptor); - else + free(descriptor); + } else rv = ENOMEM; - free(descriptor); } } diff --git a/sys/contrib/openzfs/lib/libzpool/Makefile.am b/sys/contrib/openzfs/lib/libzpool/Makefile.am index 929f5bed8b2..c9a55591e5c 100644 --- a/sys/contrib/openzfs/lib/libzpool/Makefile.am +++ b/sys/contrib/openzfs/lib/libzpool/Makefile.am @@ -230,7 +230,7 @@ if BUILD_FREEBSD libzpool_la_LIBADD += -lgeom endif -libzpool_la_LDFLAGS += -version-info 4:0:0 +libzpool_la_LDFLAGS += -version-info 5:0:0 if TARGET_CPU_POWERPC vdev_raidz_math_powerpc_altivec.$(OBJEXT): CFLAGS += -maltivec diff --git a/sys/contrib/openzfs/lib/libzpool/kernel.c b/sys/contrib/openzfs/lib/libzpool/kernel.c index ca357899367..e96a1d7521d 100644 --- a/sys/contrib/openzfs/lib/libzpool/kernel.c +++ b/sys/contrib/openzfs/lib/libzpool/kernel.c @@ -723,15 +723,15 @@ lowbit64(uint64_t i) return (__builtin_ffsll(i)); } -char *random_path = "/dev/random"; -char *urandom_path = "/dev/urandom"; +const char *random_path = "/dev/random"; +const char *urandom_path = "/dev/urandom"; static int random_fd = -1, urandom_fd = -1; void random_init(void) { - VERIFY((random_fd = open(random_path, O_RDONLY)) != -1); - VERIFY((urandom_fd = open(urandom_path, O_RDONLY)) != -1); + VERIFY((random_fd = open(random_path, O_RDONLY | O_CLOEXEC)) != -1); + VERIFY((urandom_fd = open(urandom_path, O_RDONLY | O_CLOEXEC)) != -1); } void diff --git a/sys/contrib/openzfs/lib/libzpool/util.c b/sys/contrib/openzfs/lib/libzpool/util.c index 2da2375a1d2..20cabe7c2e2 100644 --- a/sys/contrib/openzfs/lib/libzpool/util.c +++ b/sys/contrib/openzfs/lib/libzpool/util.c @@ -259,7 +259,7 @@ pool_active(void *unused, const char *name, uint64_t guid, * Use ZFS_IOC_POOL_SYNC to confirm if a pool is active */ - fd = open(ZFS_DEV, O_RDWR); + fd = open(ZFS_DEV, O_RDWR | O_CLOEXEC); if (fd < 0) return (-1); diff --git a/sys/contrib/openzfs/lib/libzutil/os/freebsd/zutil_import_os.c b/sys/contrib/openzfs/lib/libzutil/os/freebsd/zutil_import_os.c index ff2c0789b58..36c4d90aa4b 100644 --- a/sys/contrib/openzfs/lib/libzutil/os/freebsd/zutil_import_os.c +++ b/sys/contrib/openzfs/lib/libzutil/os/freebsd/zutil_import_os.c @@ -127,7 +127,7 @@ zpool_open_func(void *arg) /* * O_NONBLOCK so we don't hang trying to open things like serial ports. */ - if ((fd = open(rn->rn_name, O_RDONLY|O_NONBLOCK)) < 0) + if ((fd = open(rn->rn_name, O_RDONLY|O_NONBLOCK|O_CLOEXEC)) < 0) return; /* diff --git a/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c b/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c index 1f767bb7a6e..2a6f4ae2a22 100644 --- a/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c +++ b/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c @@ -195,10 +195,8 @@ zfs_get_enclosure_sysfs_path(const char *dev_name) } dp = opendir(tmp1); - if (dp == NULL) { - tmp1 = NULL; /* To make free() at the end a NOP */ + if (dp == NULL) goto end; - } /* * Look though all sysfs entries in /sys/block//device for @@ -209,18 +207,16 @@ zfs_get_enclosure_sysfs_path(const char *dev_name) if (strstr(ep->d_name, "enclosure_device") == NULL) continue; - if (asprintf(&tmp2, "%s/%s", tmp1, ep->d_name) == -1 || - tmp2 == NULL) + if (asprintf(&tmp2, "%s/%s", tmp1, ep->d_name) == -1) { + tmp2 = NULL; break; + } size = readlink(tmp2, buf, sizeof (buf)); /* Did readlink fail or crop the link name? */ - if (size == -1 || size >= sizeof (buf)) { - free(tmp2); - tmp2 = NULL; /* To make free() at the end a NOP */ + if (size == -1 || size >= sizeof (buf)) break; - } /* * We got a valid link. readlink() doesn't terminate strings @@ -306,9 +302,10 @@ dm_get_underlying_path(const char *dm_name) else dev_str = tmp; - size = asprintf(&tmp, "/sys/block/%s/slaves/", dev_str); - if (size == -1 || !tmp) + if ((size = asprintf(&tmp, "/sys/block/%s/slaves/", dev_str)) == -1) { + tmp = NULL; goto end; + } dp = opendir(tmp); if (dp == NULL) @@ -334,7 +331,9 @@ dm_get_underlying_path(const char *dm_name) if (!enclosure_path) continue; - size = asprintf(&path, "/dev/%s", ep->d_name); + if ((size = asprintf( + &path, "/dev/%s", ep->d_name)) == -1) + path = NULL; free(enclosure_path); break; } @@ -346,13 +345,14 @@ end: free(tmp); free(realp); - if (!path) { + if (!path && first_path) { /* * None of the underlying paths had a link back to their * enclosure devices. Throw up out hands and return the first * underlying path. */ - size = asprintf(&path, "/dev/%s", first_path); + if ((size = asprintf(&path, "/dev/%s", first_path)) == -1) + path = NULL; } free(first_path); @@ -390,7 +390,7 @@ zfs_dev_is_whole_disk(const char *dev_name) struct dk_gpt *label; int fd; - if ((fd = open(dev_name, O_RDONLY | O_DIRECT)) < 0) + if ((fd = open(dev_name, O_RDONLY | O_DIRECT | O_CLOEXEC)) < 0) return (B_FALSE); if (efi_alloc_and_init(fd, EFI_NUMPAR, &label) != 0) { diff --git a/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_import_os.c b/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_import_os.c index 2e0baecb3be..84c3cb44fec 100644 --- a/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_import_os.c +++ b/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_import_os.c @@ -136,9 +136,9 @@ zpool_open_func(void *arg) * cache which may be stale for multipath devices. An EINVAL errno * indicates O_DIRECT is unsupported so fallback to just O_RDONLY. */ - fd = open(rn->rn_name, O_RDONLY | O_DIRECT); + fd = open(rn->rn_name, O_RDONLY | O_DIRECT | O_CLOEXEC); if ((fd < 0) && (errno == EINVAL)) - fd = open(rn->rn_name, O_RDONLY); + fd = open(rn->rn_name, O_RDONLY | O_CLOEXEC); if ((fd < 0) && (errno == EACCES)) hdl->lpc_open_access_error = B_TRUE; if (fd < 0) @@ -283,21 +283,20 @@ zpool_default_search_paths(size_t *count) static int zfs_path_order(char *name, int *order) { - int i = 0, error = ENOENT; - char *dir, *env, *envdup; + int i, error = ENOENT; + char *dir, *env, *envdup, *tmp = NULL; env = getenv("ZPOOL_IMPORT_PATH"); if (env) { envdup = strdup(env); - dir = strtok(envdup, ":"); - while (dir) { + for (dir = strtok_r(envdup, ":", &tmp), i = 0; + dir != NULL; + dir = strtok_r(NULL, ":", &tmp), i++) { if (strncmp(name, dir, strlen(dir)) == 0) { *order = i; error = 0; break; } - dir = strtok(NULL, ":"); - i++; } free(envdup); } else { diff --git a/sys/contrib/openzfs/lib/libzutil/zutil_device_path.c b/sys/contrib/openzfs/lib/libzutil/zutil_device_path.c index 27ca80e5040..bcdc72baa68 100644 --- a/sys/contrib/openzfs/lib/libzutil/zutil_device_path.c +++ b/sys/contrib/openzfs/lib/libzutil/zutil_device_path.c @@ -41,18 +41,18 @@ int zfs_resolve_shortname(const char *name, char *path, size_t len) { int i, error = -1; - char *dir, *env, *envdup; + char *dir, *env, *envdup, *tmp = NULL; env = getenv("ZPOOL_IMPORT_PATH"); errno = ENOENT; if (env) { envdup = strdup(env); - dir = strtok(envdup, ":"); - while (dir && error) { + for (dir = strtok_r(envdup, ":", &tmp); + dir != NULL && error != 0; + dir = strtok_r(NULL, ":", &tmp)) { (void) snprintf(path, len, "%s/%s", dir, name); error = access(path, F_OK); - dir = strtok(NULL, ":"); } free(envdup); } else { @@ -82,21 +82,20 @@ static int zfs_strcmp_shortname(const char *name, const char *cmp_name, int wholedisk) { int path_len, cmp_len, i = 0, error = ENOENT; - char *dir, *env, *envdup = NULL; + char *dir, *env, *envdup = NULL, *tmp = NULL; char path_name[MAXPATHLEN]; - const char * const *zpool_default_import_path; + const char * const *zpool_default_import_path = NULL; size_t count; - zpool_default_import_path = zpool_default_search_paths(&count); - cmp_len = strlen(cmp_name); env = getenv("ZPOOL_IMPORT_PATH"); if (env) { envdup = strdup(env); - dir = strtok(envdup, ":"); + dir = strtok_r(envdup, ":", &tmp); } else { - dir = (char *)zpool_default_import_path[i]; + zpool_default_import_path = zpool_default_search_paths(&count); + dir = (char *)zpool_default_import_path[i]; } while (dir) { @@ -116,7 +115,7 @@ zfs_strcmp_shortname(const char *name, const char *cmp_name, int wholedisk) } if (env) { - dir = strtok(NULL, ":"); + dir = strtok_r(NULL, ":", &tmp); } else if (++i < count) { dir = (char *)zpool_default_import_path[i]; } else { @@ -141,18 +140,17 @@ zfs_strcmp_pathname(const char *name, const char *cmp, int wholedisk) int path_len, cmp_len; char path_name[MAXPATHLEN]; char cmp_name[MAXPATHLEN]; - char *dir, *dup; + char *dir, *tmp = NULL; - /* Strip redundant slashes if one exists due to ZPOOL_IMPORT_PATH */ - memset(cmp_name, 0, MAXPATHLEN); - dup = strdup(cmp); - dir = strtok(dup, "/"); - while (dir) { + /* Strip redundant slashes if they exist due to ZPOOL_IMPORT_PATH */ + cmp_name[0] = '\0'; + (void) strlcpy(path_name, cmp, sizeof (path_name)); + for (dir = strtok_r(path_name, "/", &tmp); + dir != NULL; + dir = strtok_r(NULL, "/", &tmp)) { strlcat(cmp_name, "/", sizeof (cmp_name)); strlcat(cmp_name, dir, sizeof (cmp_name)); - dir = strtok(NULL, "/"); } - free(dup); if (name[0] != '/') return (zfs_strcmp_shortname(name, cmp_name, wholedisk)); diff --git a/sys/contrib/openzfs/lib/libzutil/zutil_import.c b/sys/contrib/openzfs/lib/libzutil/zutil_import.c index 93d05354f30..9d7fcb8d968 100644 --- a/sys/contrib/openzfs/lib/libzutil/zutil_import.c +++ b/sys/contrib/openzfs/lib/libzutil/zutil_import.c @@ -888,6 +888,83 @@ label_offset(uint64_t size, int l) 0 : size - VDEV_LABELS * sizeof (vdev_label_t))); } +/* + * The same description applies as to zpool_read_label below, + * except here we do it without aio, presumably because an aio call + * errored out in a way we think not using it could circumvent. + */ +static int +zpool_read_label_slow(int fd, nvlist_t **config, int *num_labels) +{ + struct stat64 statbuf; + int l, count = 0; + vdev_phys_t *label; + nvlist_t *expected_config = NULL; + uint64_t expected_guid = 0, size; + int error; + + *config = NULL; + + if (fstat64_blk(fd, &statbuf) == -1) + return (0); + size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t); + + error = posix_memalign((void **)&label, PAGESIZE, sizeof (*label)); + if (error) + return (-1); + + for (l = 0; l < VDEV_LABELS; l++) { + uint64_t state, guid, txg; + off_t offset = label_offset(size, l) + VDEV_SKIP_SIZE; + + if (pread64(fd, label, sizeof (vdev_phys_t), + offset) != sizeof (vdev_phys_t)) + continue; + + if (nvlist_unpack(label->vp_nvlist, + sizeof (label->vp_nvlist), config, 0) != 0) + continue; + + if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_GUID, + &guid) != 0 || guid == 0) { + nvlist_free(*config); + continue; + } + + if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE, + &state) != 0 || state > POOL_STATE_L2CACHE) { + nvlist_free(*config); + continue; + } + + if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE && + (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG, + &txg) != 0 || txg == 0)) { + nvlist_free(*config); + continue; + } + + if (expected_guid) { + if (expected_guid == guid) + count++; + + nvlist_free(*config); + } else { + expected_config = *config; + expected_guid = guid; + count++; + } + } + + if (num_labels != NULL) + *num_labels = count; + + free(label); + *config = expected_config; + + return (0); +} + /* * Given a file descriptor, read the label information and return an nvlist * describing the configuration, if there is one. The number of valid @@ -929,6 +1006,8 @@ zpool_read_label(int fd, nvlist_t **config, int *num_labels) if (lio_listio(LIO_WAIT, aiocbps, VDEV_LABELS, NULL) != 0) { int saved_errno = errno; + boolean_t do_slow = B_FALSE; + error = -1; if (errno == EAGAIN || errno == EINTR || errno == EIO) { /* @@ -937,14 +1016,33 @@ zpool_read_label(int fd, nvlist_t **config, int *num_labels) */ for (l = 0; l < VDEV_LABELS; l++) { errno = 0; - int r = aio_error(&aiocbs[l]); - if (r != EINVAL) + switch (aio_error(&aiocbs[l])) { + case EINVAL: + break; + case EINPROGRESS: + // This shouldn't be possible to + // encounter, die if we do. + ASSERT(B_FALSE); + case EOPNOTSUPP: + case ENOSYS: + do_slow = B_TRUE; + case 0: + default: (void) aio_return(&aiocbs[l]); + } } } + if (do_slow) { + /* + * At least some IO involved access unsafe-for-AIO + * files. Let's try again, without AIO this time. + */ + error = zpool_read_label_slow(fd, config, num_labels); + saved_errno = errno; + } free(labels); errno = saved_errno; - return (-1); + return (error); } for (l = 0; l < VDEV_LABELS; l++) { @@ -1345,7 +1443,8 @@ zpool_find_import_impl(libpc_handle_t *hdl, importargs_t *iarg, * would prevent a zdb -e of active pools with * no cachefile. */ - fd = open(slice->rn_name, O_RDONLY | O_EXCL); + fd = open(slice->rn_name, + O_RDONLY | O_EXCL | O_CLOEXEC); if (fd >= 0 || iarg->can_be_active) { if (fd >= 0) close(fd); @@ -1408,7 +1507,7 @@ discover_cached_paths(libpc_handle_t *hdl, nvlist_t *nv, /* * Once we have the path, we need to add the directory to - * our directoy cache. + * our directory cache. */ if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) { return (zpool_find_import_scan_dir(hdl, lock, cache, @@ -1437,7 +1536,7 @@ zpool_find_import_cached(libpc_handle_t *hdl, importargs_t *iarg) verify(iarg->poolname == NULL || iarg->guid == 0); - if ((fd = open(iarg->cachefile, O_RDONLY)) < 0) { + if ((fd = open(iarg->cachefile, O_RDONLY | O_CLOEXEC)) < 0) { zutil_error_aux(hdl, "%s", strerror(errno)); (void) zutil_error(hdl, EZFS_BADCACHE, dgettext(TEXT_DOMAIN, "failed to open cache file")); @@ -1688,16 +1787,13 @@ zpool_find_config(void *hdl, const char *target, nvlist_t **configp, nvlist_t *match = NULL; nvlist_t *config = NULL; char *sepp = NULL; - char sep = '\0'; int count = 0; char *targetdup = strdup(target); *configp = NULL; - if ((sepp = strpbrk(targetdup, "/@")) != NULL) { - sep = *sepp; + if ((sepp = strpbrk(targetdup, "/@")) != NULL) *sepp = '\0'; - } pools = zpool_search_import(hdl, args, pco); diff --git a/sys/contrib/openzfs/lib/libzutil/zutil_nicenum.c b/sys/contrib/openzfs/lib/libzutil/zutil_nicenum.c index 306cec3cadd..1a19db0dfeb 100644 --- a/sys/contrib/openzfs/lib/libzutil/zutil_nicenum.c +++ b/sys/contrib/openzfs/lib/libzutil/zutil_nicenum.c @@ -35,6 +35,9 @@ boolean_t zfs_isnumber(const char *str) { + if (!*str) + return (B_FALSE); + for (; *str; str++) if (!(isdigit(*str) || (*str == '.'))) return (B_FALSE); diff --git a/sys/contrib/openzfs/man/man1/arcstat.1 b/sys/contrib/openzfs/man/man1/arcstat.1 index de63206e279..a0240e40e4b 100644 --- a/sys/contrib/openzfs/man/man1/arcstat.1 +++ b/sys/contrib/openzfs/man/man1/arcstat.1 @@ -8,603 +8,175 @@ .\" source. A copy of the CDDL is also available via the Internet at .\" http://www.illumos.org/license/CDDL. .\" -.\" .\" Copyright 2014 Adam Stevko. All rights reserved. .\" Copyright (c) 2015 by Delphix. All rights reserved. .\" Copyright (c) 2020 by AJ Jordan. All rights reserved. .\" -.TH ARCSTAT 1 "Oct 20, 2020" OpenZFS -.SH NAME -arcstat \- report ZFS ARC and L2ARC statistics -.SH SYNOPSIS -.LP -.nf -\fBarcstat\fR [\fB-havxp\fR] [\fB-f field[,field]...\fR] [\fB-o file\fR] [\fB-s string\fR] [\fBinterval\fR [\fBcount\fR]] -.fi - -.SH DESCRIPTION -.LP -The \fBarcstat\fR utility print various ZFS ARC and L2ARC statistics in -vmstat-like fashion. -.sp - -.sp -.LP -The \fBarcstat\fR command reports the following information: -.sp -.ne 2 - -.\" -.sp -.ne 1 -.na -\fBc \fR -.ad -.RS 14n +.Dd May 26, 2021 +.Dt ARCSTAT 1 +.Os +. +.Sh NAME +.Nm arcstat +.Nd report ZFS ARC and L2ARC statistics +.Sh SYNOPSIS +.Nm +.Op Fl havxp +.Op Fl f Ar field Ns Op , Ns Ar field Ns ... +.Op Fl o Ar file +.Op Fl s Ar string +.Op Ar interval +.Op Ar count +. +.Sh DESCRIPTION +.Nm +prints various ZFS ARC and L2ARC statistics in vmstat-like fashion: +.Bl -tag -width "l2asize" +.It Sy c ARC target size -.RE - -.sp -.ne 2 -.na -\fBdh% \fR -.ad -.RS 14n +.It Sy dh% Demand data hit percentage -.RE - -.sp -.ne 2 -.na -\fBdm% \fR -.ad -.RS 14n +.It Sy dm% Demand data miss percentage -.RE - -.sp -.ne 2 -.na -\fBmfu \fR -.ad -.RS 14n +.It Sy mfu MFU list hits per second -.RE - -.sp -.ne 2 -.na -\fBmh% \fR -.ad -.RS 14n +.It Sy mh% Metadata hit percentage -.RE - -.sp -.ne 2 -.na -\fBmm% \fR -.ad -.RS 14n +.It Sy mm% Metadata miss percentage -.RE - -.sp -.ne 2 -.na -\fBmru \fR -.ad -.RS 14n +.It Sy mru MRU list hits per second -.RE - -.sp -.ne 2 -.na -\fBph% \fR -.ad -.RS 14n +.It Sy ph% Prefetch hits percentage -.RE - -.sp -.ne 2 -.na -\fBpm% \fR -.ad -.RS 14n +.It Sy pm% Prefetch miss percentage -.RE - -.sp -.ne 2 -.na -\fBdhit \fR -.ad -.RS 14n +.It Sy dhit Demand data hits per second -.RE - -.sp -.ne 2 -.na -\fBdmis \fR -.ad -.RS 14n +.It Sy dmis Demand data misses per second -.RE - -.sp -.ne 2 -.na -\fBhit% \fR -.ad -.RS 14n +.It Sy hit% ARC hit percentage -.RE - -.sp -.ne 2 -.na -\fBhits \fR -.ad -.RS 14n +.It Sy hits ARC reads per second -.RE - -.sp -.ne 2 -.na -\fBmfug \fR -.ad -.RS 14n +.It Sy mfug MFU ghost list hits per second -.RE - -.sp -.ne 2 -.na -\fBmhit \fR -.ad -.RS 14n +.It Sy mhit Metadata hits per second -.RE - -.sp -.ne 2 -.na -\fBmiss \fR -.ad -.RS 14n +.It Sy miss ARC misses per second -.RE - -.sp -.ne 2 -.na -\fBmmis \fR -.ad -.RS 14n +.It Sy mmis Metadata misses per second -.RE - -.sp -.ne 2 -.na -\fBmrug \fR -.ad -.RS 14n +.It Sy mrug MRU ghost list hits per second -.RE - -.sp -.ne 2 -.na -\fBphit \fR -.ad -.RS 14n +.It Sy phit Prefetch hits per second -.RE - -.sp -.ne 2 -.na -\fBpmis \fR -.ad -.RS 14n +.It Sy pmis Prefetch misses per second -.RE - -.sp -.ne 2 -.na -\fBread \fR -.ad -.RS 14n +.It Sy read Total ARC accesses per second -.RE - -.sp -.ne 2 -.na -\fBtime \fR -.ad -.RS 14n -Time -.RE - -.sp -.ne 2 -.na -\fBsize \fR -.ad -.RS 14n +.It Sy time +Current time +.It Sy size ARC size -.RE - -.sp -.ne 2 -.na -\fBarcsz \fR -.ad -.RS 14n -Alias for \fBsize\fR -.RE - -.sp -.ne 2 -.na -\fBdread \fR -.ad -.RS 14n +.It Sy arcsz +Alias for +.Sy size +.It Sy dread Demand data accesses per second -.RE - -.sp -.ne 2 -.na -\fBeskip \fR -.ad -.RS 14n +.It Sy eskip evict_skip per second -.RE - -.sp -.ne 2 -.na -\fBmiss% \fR -.ad -.RS 14n +.It Sy miss% ARC miss percentage -.RE - -.sp -.ne 2 -.na -\fBmread \fR -.ad -.RS 14n +.It Sy mread Metadata accesses per second -.RE - -.sp -.ne 2 -.na -\fBpread \fR -.ad -.RS 14n +.It Sy pread Prefetch accesses per second -.RE - -.sp -.ne 2 -.na -\fBl2hit% \fR -.ad -.RS 14n +.It Sy l2hit% L2ARC access hit percentage -.RE - -.sp -.ne 2 -.na -\fBl2hits \fR -.ad -.RS 14n +.It Sy l2hits L2ARC hits per second -.RE - -.sp -.ne 2 -.na -\fBl2miss \fR -.ad -.RS 14n +.It Sy l2miss L2ARC misses per second -.RE - -.sp -.ne 2 -.na -\fBl2read \fR -.ad -.RS 14n +.It Sy l2read Total L2ARC accesses per second -.RE - -.sp -.ne 2 -.na -\fBl2pref \fR -.ad -.RS 14n +.It Sy l2pref L2ARC prefetch allocated size per second -.RE - -.sp -.ne 2 -.na -\fBl2pref% \fR -.ad -.RS 14n +.It Sy l2pref% L2ARC prefetch allocated size percentage -.RE - -.sp -.ne 2 -.na -\fBl2mfu \fR -.ad -.RS 14n +.It Sy l2mfu L2ARC MFU allocated size per second -.RE - -.sp -.ne 2 -.na -\fBl2mfu% \fR -.ad -.RS 14n +.It Sy l2mfu% L2ARC MFU allocated size percentage -.RE - -.sp -.ne 2 -.na -\fBl2mru \fR -.ad -.RS 14n +.It Sy l2mru L2ARC MRU allocated size per second -.RE - -.sp -.ne 2 -.na -\fBl2mru% \fR -.ad -.RS 14n +.It Sy l2mru% L2ARC MRU allocated size percentage -.RE - -.sp -.ne 2 -.na -\fBl2data \fR -.ad -.RS 14n +.It Sy l2data L2ARC data (buf content) allocated size per second -.RE - -.sp -.ne 2 -.na -\fBl2data% \fR -.ad -.RS 14n +.It Sy l2data% L2ARC data (buf content) allocated size percentage -.RE - -.sp -.ne 2 -.na -\fBl2meta \fR -.ad -.RS 14n +.It Sy l2meta L2ARC metadata (buf content) allocated size per second -.RE - -.sp -.ne 2 -.na -\fBl2meta% \fR -.ad -.RS 14n +.It Sy l2meta% L2ARC metadata (buf content) allocated size percentage -.RE - -.sp -.ne 2 -.na -\fBl2size \fR -.ad -.RS 14n +.It Sy l2size Size of the L2ARC -.RE - -.sp -.ne 2 -.na -\fBmtxmis \fR -.ad -.RS 14n +.It Sy mtxmis mutex_miss per second -.RE - -.sp -.ne 2 -.na -\fBl2bytes \fR -.ad -.RS 14n +.It Sy l2bytes Bytes read per second from the L2ARC -.RE - -.sp -.ne 2 -.na -\fBl2miss% \fR -.ad -.RS 14n +.It Sy l2miss% L2ARC access miss percentage -.RE - -.sp -.ne 2 -.na -\fBl2asize \fR -.ad -.RS 14n +.It Sy l2asize Actual (compressed) size of the L2ARC -.RE - -.sp -.ne 2 -.na -\fBgrow \fR -.ad -.RS 14n +.It Sy grow ARC grow disabled -.RE - -.sp -.ne 2 -.na -\fBneed \fR -.ad -.RS 14n +.It Sy need ARC reclaim needed -.RE - -.sp -.ne 2 -.na -\fBfree \fR -.ad -.RS 14n +.It Sy free The ARC's idea of how much free memory there is, which includes evictable memory in the page cache. -Since the ARC tries to keep \fBavail\fR above zero, \fBavail\fR is usually more instructive to observe than \fBfree\fR. -.RE - -.sp -.ne 2 -.na -\fBavail \fR -.ad -.RS 14n -The ARC's idea of how much free memory is available to it, which is a bit less than \fBfree\fR. -May temporarily be negative, in which case the ARC will reduce the target size \fBc\fR. -.RE -.\" - -.SH OPTIONS -.LP -The following options are supported: - -.sp -.ne 2 -.na -\fB\fB-a\fR\fR -.ad -.RS 12n +Since the ARC tries to keep +.Sy avail +above zero, +.Sy avail +is usually more instructive to observe than +.Sy free . +.It Sy avail +The ARC's idea of how much free memory is available to it, which is a bit less than +.Sy free . +May temporarily be negative, in which case the ARC will reduce the target size +.Sy c . +.El +. +.Sh OPTIONS +.Bl -tag -width "-v" +.It Fl a Print all possible stats. -.RE - -.sp -.ne 2 -.na -\fB\fB-f\fR\fR -.ad -.RS 12n -Display only specific fields. See \fBDESCRIPTION\fR for supported statistics. -.RE - -.sp -.ne 2 -.na -\fB\fB-h\fR\fR -.ad -.RS 12n +.It Fl f +Display only specific fields. +See +.Sy DESCRIPTION +for supported statistics. +.It Fl h Display help message. -.RE - -.sp -.ne 2 -.na -\fB\fB-o\fR\fR -.ad -.RS 12n +.It Fl o Report statistics to a file instead of the standard output. -.RE - -.sp -.ne 2 -.na -\fB\fB-p\fR\fR -.ad -.RS 12n +.It Fl p Disable auto-scaling of numerical fields (for raw, machine-parsable values). -.RE - -.sp -.ne 2 -.na -\fB\fB-s\fR\fR -.ad -.RS 12n +.It Fl s Display data with a specified separator (default: 2 spaces). -.RE - -.sp -.ne 2 -.na -\fB\fB-x\fR\fR -.ad -.RS 12n -Print extended stats (same as -f time,mfu,mru,mfug,mrug,eskip,mtxmis,dread,pread,read). -.RE - -.sp -.ne 2 -.na -\fB\fB-v\fR\fR -.ad -.RS 12n +.It Fl x +Print extended stats (same as +.Fl f Ar time,mfu,mru,mfug,mrug,eskip,mtxmis,dread,pread,read Ns No ). +.It Fl v Show field headers and definitions -.RE - -.SH OPERANDS -.LP +.El +. +.Sh OPERANDS The following operands are supported: -.sp -.ne 2 -.na -\fB\fIcount\fR\fR -.ad -.RS 12n -Display only \fIcount\fR reports. -.RE - -.sp -.ne 2 -.na -\fB\fIinterval\fR\fR -.ad -.RS 12n +.Bl -tag -width "interval" +.It Ar interval Specify the sampling interval in seconds. -.RE - -.SH AUTHORS -.LP -arcstat was originally written in Perl by Neelakanth Nadgir and supported only ZFS ARC statistics. -Mike Harsch updated it to support L2ARC statistics. -John Hixson ported it to Python for FreeNAS over some beer, after which many individuals from the OpenZFS community continued to maintain and improve it. +.It Ar count +Display only \fIcount\fR reports. +.El diff --git a/sys/contrib/openzfs/man/man1/cstyle.1 b/sys/contrib/openzfs/man/man1/cstyle.1 index 14175838a4f..16f47ba35c1 100644 --- a/sys/contrib/openzfs/man/man1/cstyle.1 +++ b/sys/contrib/openzfs/man/man1/cstyle.1 @@ -20,148 +20,142 @@ .\" .\" CDDL HEADER END .\" -.TH CSTYLE 1 "Aug 24, 2020" OpenZFS -.SH NAME -.I cstyle -\- check for some common stylistic errors in C source files -.SH SYNOPSIS -\fBcstyle [-chpvCP] [-o constructs] [file...]\fP -.LP -.SH DESCRIPTION -.IX "OS-Net build tools" "cstyle" "" "\fBcstyle\fP" -.LP -.I cstyle -inspects C source files (*.c and *.h) for common stylistic errors. It -attempts to check for the cstyle documented in -\fIhttp://www.cis.upenn.edu/~lee/06cse480/data/cstyle.ms.pdf\fP. +.Dd May 26, 2021 +.Dt CSTYLE 1 +.Os +. +.Sh NAME +.Nm cstyle +.Nd check for some common stylistic errors in C source files +.Sh SYNOPSIS +.Nm +.Op Fl chpvCP +.Op Fl o Ar construct Ns Op , Ns Ar construct Ns … +.Op Ar file… +.Sh DESCRIPTION +.Nm +inspects C source files (*.c and *.h) for common stylistic errors. +It attempts to check for the cstyle documented in +.Lk http://www.cis.upenn.edu/~lee/06cse480/data/cstyle.ms.pdf . Note that there is much in that document that -.I cannot -be checked for; just because your code is \fBcstyle(1)\fP clean does not -mean that you've followed Sun's C style. \fICaveat emptor\fP. -.LP -.SH OPTIONS -.LP +.Em cannot +be checked for; just because your code is +.Nm Ns -clean +does not mean that you've followed Sun's C style. +.Em Caveat emptor . +. +.Sh OPTIONS The following options are supported: -.TP 4 -.B \-c -Check continuation line indentation inside of functions. Sun's C style +.Bl -tag -width "-c" +.It Fl c +Check continuation line indentation inside of functions. +Sun's C style states that all statements must be indented to an appropriate tab stop, -and any continuation lines after them must be indented \fIexactly\fP four -spaces from the start line. This option enables a series of checks -designed to find continuation line problems within functions only. The -checks have some limitations; see CONTINUATION CHECKING, below. -.LP -.TP 4 -.B \-h -Performs heuristic checks that are sometimes wrong. Not generally used. -.LP -.TP 4 -.B \-p -Performs some of the more picky checks. Includes ANSI #else and #endif -rules, and tries to detect spaces after casts. Used as part of the -putback checks. -.LP -.TP 4 -.B \-v -Verbose output; includes the text of the line of error, and, for -\fB-c\fP, the first statement in the current continuation block. -.LP -.TP 4 -.B \-C +and any continuation lines after them must be indented +.Em exactly +four spaces from the start line. +This option enables a series of checks designed to find +continuation line problems within functions only. +The checks have some limitations; see +.Sy CONTINUATION CHECKING , +below. +.It Fl h +Performs heuristic checks that are sometimes wrong. +Not generally used. +.It Fl p +Performs some of the more picky checks. +Includes ANSI +.Sy #else +and +.Sy #endif +rules, and tries to detect spaces after casts. +Used as part of the putback checks. +.It Fl v +Verbose output; includes the text of the line of error, and, for +.Fl c , +the first statement in the current continuation block. +.It Fl C Ignore errors in header comments (i.e. block comments starting in the -first column). Not generally used. -.LP -.TP 4 -.B \-P -Check for use of non-POSIX types. Historically, types like "u_int" and -"u_long" were used, but they are now deprecated in favor of the POSIX -types uint_t, ulong_t, etc. This detects any use of the deprecated -types. Used as part of the putback checks. -.LP -.TP 4 -.B \-o \fIconstructs\fP -Allow a comma-separated list of additional constructs. Available -constructs include: -.LP -.TP 10 -.B doxygen -Allow doxygen-style block comments (\fB/**\fP and \fB/*!\fP) -.LP -.TP 10 -.B splint -Allow splint-style lint comments (\fB/*@...@*/\fP) -.LP -.SH NOTES -.LP -The cstyle rule for the OS/Net consolidation is that all new files must -be \fB-pP\fP clean. For existing files, the following invocations are -run against both the old and new files: -.LP -.TP 4 -\fBcstyle file\fB -.LP -.TP 4 -\fBcstyle -p file\fB -.LP -.TP 4 -\fBcstyle -pP file\fB -.LP -If the old file gave no errors for one of the invocations, the new file -must also give no errors. This way, files can only become more clean. -.LP -.SH CONTINUATION CHECKING -.LP +first column). +Not generally used. +.It Fl P +Check for use of non-POSIX types. +Historically, types like +.Sy u_int +and +.Sy u_long +were used, but they are now deprecated in favor of the POSIX +types +.Sy uint_t , +.Sy ulong_t , +etc. +This detects any use of the deprecated types. +Used as part of the putback checks. +.It Fl o Ar construct Ns Op , Ns Ar construct Ns … +Available constructs include: +.Bl -tag -compact -width "doxygen" +.It Sy doxygen +Allow doxygen-style block comments +.Pq Sy /** No and Sy /*!\& . +.It Sy splint +Allow splint-style lint comments +.Pq Sy /*@...@*/ . +.El +.El +. +.Sh CONTINUATION CHECKING The continuation checker is a reasonably simple state machine that knows something about how C is laid out, and can match parenthesis, etc. over -multiple lines. It does have some limitations: -.LP -.TP 4 -.B 1. +multiple lines. +It does have some limitations: +.Bl -enum +.It Preprocessor macros which cause unmatched parenthesis will confuse the -checker for that line. To fix this, you'll need to make sure that each -branch of the #if statement has balanced parenthesis. -.LP -.TP 4 -.B 2. -Some \fBcpp\fP macros do not require ;s after them. Any such macros -*must* be ALL_CAPS; any lower case letters will cause bad output. -.LP +checker for that line. +To fix this, you'll need to make sure that each branch of the +.Sy #if +statement has balanced parenthesis. +.It +Some +.Xr cpp 1 +macros do not require \fB;\fPs after them. +Any such macros +.Em must +be ALL_CAPS; any lower case letters will cause bad output. +.Pp The bad output will generally be corrected after the next \fB;\fP, -\fB{\fP, or \fB}\fP. -.LP -Some continuation error messages deserve some additional explanation -.LP -.TP 4 -.B -multiple statements continued over multiple lines -A multi-line statement which is not broken at statement -boundaries. For example: -.RS 4 -.HP 4 +.Sy { , +or +.Sy } . +.El +Some continuation error messages deserve some additional explanation: +.Bl -tag -width Ds +.It Sy multiple statements continued over multiple lines +A multi-line statement which is not broken at statement boundaries. +For example: +.Bd -literal if (this_is_a_long_variable == another_variable) a = -.br -b + c; -.LP -Will trigger this error. Instead, do: -.HP 8 + b + c; +.Ed +.Pp +Will trigger this error. +Instead, do: +.Bd -literal if (this_is_a_long_variable == another_variable) -.br -a = b + c; -.RE -.LP -.TP 4 -.B -empty if/for/while body not on its own line + a = b + c; +.Ed +.It Sy empty if/for/while body not on its own line For visibility, empty bodies for if, for, and while statements should be -on their own line. For example: -.RS 4 -.HP 4 +on their own line. +For example: +.Bd -literal while (do_something(&x) == 0); -.LP -Will trigger this error. Instead, do: -.HP 8 +.Ed +.Pp +Will trigger this error. +Instead, do: +.Bd -literal while (do_something(&x) == 0) -.br -; -.RE - + ; +.Ed +.El diff --git a/sys/contrib/openzfs/man/man1/raidz_test.1 b/sys/contrib/openzfs/man/man1/raidz_test.1 index 26e6b24ad81..1c61c7a8772 100644 --- a/sys/contrib/openzfs/man/man1/raidz_test.1 +++ b/sys/contrib/openzfs/man/man1/raidz_test.1 @@ -1,4 +1,3 @@ -'\" t .\" .\" CDDL HEADER START .\" @@ -19,88 +18,84 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2016 Gvozden Nešković. All rights reserved. .\" -.TH RAIDZ_TEST 1 "Aug 24, 2020" OpenZFS - -.SH NAME -\fBraidz_test\fR \- raidz implementation verification and benchmarking tool -.SH SYNOPSIS -.LP -.BI "raidz_test " -.SH DESCRIPTION -.LP -This manual page documents briefly the \fBraidz_test\fR command. -.LP -Purpose of this tool is to run all supported raidz implementation and verify -results of all methods. Tool also contains a parameter sweep option where all -parameters affecting RAIDZ block are verified (like ashift size, data offset, -data size, etc...). -The tool also supports a benchmarking mode using -B option. -.SH OPTION -.HP -.BI "\-h" "" -.IP +.Dd May 26, 2021 +.Dt RAIDZ_TEST 1 +.Os +. +.Sh NAME +.Nm raidz_test +.Nd raidz implementation verification and benchmarking tool +.Sh SYNOPSIS +.Nm +.Op Fl StBevTD +.Op Fl a Ar ashift +.Op Fl o Ar zio_off_shift +.Op Fl d Ar raidz_data_disks +.Op Fl s Ar zio_size_shift +.Op Fl r Ar reflow_offset +. +.Sh DESCRIPTION +The purpose of this tool is to run all supported raidz implementation and verify +the results of all methods. +It also contains a parameter sweep option where all +parameters affecting a RAIDZ block are verified (like ashift size, data offset, +data size, etc.). +The tool also supports a benchmarking mode using the +.Fl B +option. +. +.Sh OPTION +.Bl -tag -width "-B(enchmark)" +.It Fl h Print a help summary. -.HP -.BI "\-a" " ashift (default: 9)" -.IP +.It Fl a Ar ashift No (default: Sy 9 ) Ashift value. -.HP -.BI "\-o" " zio_off_shift" " (default: 0)" -.IP -Zio offset for raidz block. Offset value is 1 << (zio_off_shift) -.HP -.BI "\-d" " raidz_data_disks" " (default: 8)" -.IP -Number of raidz data disks to use. Additional disks for parity will be used -during testing. -.HP -.BI "\-s" " zio_size_shift" " (default: 19)" -.IP -Size of data for raidz block. Size is 1 << (zio_size_shift). -.HP -.BI "\-r" " reflow_offset" " (default: uint max)" -.IP -Set raidz expansion offset. The expanded raidz map allocation function will +.It Fl o Ar zio_off_shift No (default: Sy 0 ) +ZIO offset for each raidz block. +The offset's value is +.Sy 1 << zio_off_shift . +.It Fl d Ar raidz_data_disks No (default: Sy 8 ) +Number of raidz data disks to use. +Additional disks will be used for parity. +.It Fl s Ar zio_size_shift No (default: Sy 19 ) +Size of data for raidz block. +The real size is +.Sy 1 << zio_size_shift . +.It Fl r Ar reflow_offset No (default: Sy uint max ) +Set raidz expansion offset. +The expanded raidz map allocation function will produce different map configurations depending on this value. -.HP -.BI "\-S(weep)" -.IP -Sweep parameter space while verifying the raidz implementations. This option -will exhaust all most of valid values for -a -o -d -s options. Runtime using -this option will be long. -.HP -.BI "\-t(imeout)" -.IP -Wall time for sweep test in seconds. The actual runtime could be longer. -.HP -.BI "\-B(enchmark)" -.IP -This options starts the benchmark mode. All implementations are benchmarked -using increasing per disk data size. Results are given as throughput per disk, -measured in MiB/s. -.HP -.BI "\-e(xpansion)" -.IP +.It Fl S Ns No (weep) +Sweep parameter space while verifying the raidz implementations. +This option +will exhaust all most of valid values for the +.Fl aods +options. +Runtime using this option will be long. +.It Fl t Ns No (imeout) +Wall time for sweep test in seconds. +The actual runtime could be longer. +.It Fl B Ns No (enchmark) +All implementations are benchmarked using increasing per disk data size. +Results are given as throughput per disk, measured in MiB/s. +.It Fl e Ns No (xpansion) Use expanded raidz map allocation function. -.HP -.BI "\-v(erbose)" -.IP +.It Fl v Ns No (erbose) Increase verbosity. -.HP -.BI "\-T(est the test)" -.IP -Debugging option. When this option is specified tool is supposed to fail -all tests. This is to check if tests would properly verify bit-exactness. -.HP -.BI "\-D(ebug)" -.IP -Debugging option. Specify to attach gdb when SIGSEGV or SIGABRT are received. -.HP - -.SH "SEE ALSO" -.BR "ztest (1)" -.SH "AUTHORS" -vdev_raidz, created for OpenZFS by Gvozden Nešković +.It Fl T Ns No (est the test) +Debugging option: fail all tests. +This is to check if tests would properly verify bit-exactness. +.It Fl D Ns No (ebug) +Debugging option: attach +.Xr gdb 1 +when +.Sy SIGSEGV +or +.Sy SIGABRT +are received. +.El +. +.Sh "SEE ALSO" +.Xr ztest 1 diff --git a/sys/contrib/openzfs/man/man1/zhack.1 b/sys/contrib/openzfs/man/man1/zhack.1 index 3126007a5e0..e2fc189b4d0 100644 --- a/sys/contrib/openzfs/man/man1/zhack.1 +++ b/sys/contrib/openzfs/man/man1/zhack.1 @@ -1,4 +1,3 @@ -'\" t .\" .\" CDDL HEADER START .\" @@ -19,63 +18,108 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright 2013 Darik Horn . All rights reserved. .\" -.TH ZHACK 1 "Aug 24, 2020" OpenZFS - -.SH NAME -zhack \- libzpool debugging tool -.SH DESCRIPTION +.\" lint-ok: WARNING: sections out of conventional order: Sh SYNOPSIS +.\" +.Dd May 26, 2021 +.Dt ZHACK 1 +.Os +. +.Sh NAME +.Nm zhack +.Nd libzpool debugging tool +.Sh DESCRIPTION This utility pokes configuration changes directly into a ZFS pool, which is dangerous and can cause data corruption. -.SH SYNOPSIS -.LP -.BI "zhack [\-c " "cachefile" "] [\-d " "dir" "] <" "subcommand" "> [" "arguments" "]" -.SH OPTIONS -.HP -.BI "\-c" " cachefile" -.IP -Read the \fIpool\fR configuration from the \fIcachefile\fR, which is -/etc/zfs/zpool.cache by default. -.HP -.BI "\-d" " dir" -.IP -Search for \fIpool\fR members in the \fIdir\fR path. Can be specified -more than once. -.SH SUBCOMMANDS -.LP -.BI "feature stat " "pool" -.IP +.Sh SYNOPSIS +.Bl -tag -width Ds +.It Xo +.Nm zhack +.Cm feature stat +.Ar pool +.Xc List feature flags. -.LP -.BI "feature enable [\-d " "description" "] [\-r] " "pool guid" -.IP -Add a new feature to \fIpool\fR that is uniquely identified by -\fIguid\fR, which is specified in the same form as a zfs(8) user -property. -.IP -The \fIdescription\fR is a short human readable explanation of the new +. +.It Xo +.Nm zhack +.Cm feature enable +.Op Fl d Ar description +.Op Fl r +.Ar pool +.Ar guid +.Xc +Add a new feature to +.Ar pool +that is uniquely identified by +.Ar guid , +which is specified in the same form as a +.Xr zfs 8 +user property. +.Pp +The +.Ar description +is a short human readable explanation of the new feature. +.Pp +The +.Fl r +flag indicates that +.Ar pool +can be safely opened in read-only mode by a system that does not understand the +.Ar guid feature. -.IP -The \fB\-r\fR switch indicates that \fIpool\fR can be safely opened -in read-only mode by a system that does not have the \fIguid\fR -feature. -.LP -.BI "feature ref [\-d|\-m] " "pool guid" -.IP -Increment the reference count of the \fIguid\fR feature in \fIpool\fR. -.IP -The \fB\-d\fR switch decrements the reference count of the \fIguid\fR -feature in \fIpool\fR. -.IP -The \fB\-m\fR switch indicates that the \fIguid\fR feature is now -required to read the pool MOS. -.SH EXAMPLES -.LP -.nf +. +.It Xo +.Nm zhack +.Cm feature ref +.Op Fl d Ns | Ns Fl m +.Ar pool +.Ar guid +.Xc +Increment the reference count of the +.Ar guid +feature in +.Ar pool . +.Pp +The +.Fl d +flag decrements the reference count of the +.Ar guid +feature in +.Ar pool +instead. +.Pp +The +.Fl m +flag indicates that the +.Ar guid +feature is now required to read the pool MOS. +.El +. +.Sh GLOBAL OPTIONS +The following can be passed to all +.Nm +invocations before any subcommand: +.Bl -tag -width "-d dir" +.It Fl c Ar cachefile +Read +.Ar pool +configuration from the +.Ar cachefile , +which is +.Pa /etc/zfs/zpool.cache +by default. +.It Fl d Ar dir +Search for +.Ar pool +members in +.Ar dir . +Can be specified more than once. +.El +. +.Sh EXAMPLES +.Bd -literal # zhack feature stat tank - for_read_obj: org.illumos:lz4_compress = 0 for_write_obj: @@ -85,14 +129,14 @@ descriptions_obj: com.delphix:async_destroy = Destroy filesystems asynchronously. com.delphix:empty_bpobj = Snapshots use less space. org.illumos:lz4_compress = LZ4 compression algorithm support. -.LP + # zhack feature enable -d 'Predict future disk failures.' \\ tank com.example:clairvoyance -.LP + # zhack feature ref tank com.example:clairvoyance -.SH AUTHORS -This man page was written by Darik Horn . -.SH SEE ALSO -.BR zfs (8), -.BR zpool-features (5), -.BR ztest (1) +.Ed +. +.Sh SEE ALSO +.Xr ztest 1 , +.Xr zpool-features 5 , +.Xr zfs 8 diff --git a/sys/contrib/openzfs/man/man1/ztest.1 b/sys/contrib/openzfs/man/man1/ztest.1 index 3f30b3ed743..459486c286b 100644 --- a/sys/contrib/openzfs/man/man1/ztest.1 +++ b/sys/contrib/openzfs/man/man1/ztest.1 @@ -1,4 +1,3 @@ -'\" t .\" .\" CDDL HEADER START .\" @@ -19,178 +18,216 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved. .\" Copyright (c) 2009 Michael Gebetsroither . All rights .\" reserved. .\" Copyright (c) 2017, Intel Corporation. .\" -.TH ZTEST 1 "Aug 24, 2020" OpenZFS - -.SH NAME -\fBztest\fR \- was written by the ZFS Developers as a ZFS unit test. -.SH SYNOPSIS -.LP -.BI "ztest " -.SH DESCRIPTION -.LP -This manual page documents briefly the \fBztest\fR command. -.LP -\fBztest\fR was written by the ZFS Developers as a ZFS unit test. The -tool was developed in tandem with the ZFS functionality and was -executed nightly as one of the many regression test against the daily -build. As features were added to ZFS, unit tests were also added to -\fBztest\fR. In addition, a separate test development team wrote and +.Dd May 26, 2021 +.Dt ZTEST 1 +.Os +. +.Sh NAME +.Nm ztest +.Nd was written by the ZFS Developers as a ZFS unit test +.Sh SYNOPSIS +.Nm +.Op Fl VEG +.Op Fl v Ar vdevs +.Op Fl s Ar size_of_each_vdev +.Op Fl a Ar alignment_shift +.Op Fl m Ar mirror_copies +.Op Fl r Ar raidz_disks/draid_disks +.Op Fl R Ar raid_parity +.Op Fl K Ar raid_kind +.Op Fl D Ar draid_data +.Op Fl S Ar draid_spares +.Op Fl C Ar vdev_class_state +.Op Fl d Ar datasets +.Op Fl t Ar threads +.Op Fl g Ar gang_block_threshold +.Op Fl i Ar initialize_pool_i_times +.Op Fl k Ar kill_percentage +.Op Fl p Ar pool_name +.Op Fl T Ar time +.Op Fl z Ar zil_failure_rate +. +.Sh DESCRIPTION +.Nm +was written by the ZFS Developers as a ZFS unit test. +The tool was developed in tandem with the ZFS functionality and was +executed nightly as one of the many regression test against the daily build. +As features were added to ZFS, unit tests were also added to +.Nm . +In addition, a separate test development team wrote and executed more functional and stress tests. -.LP -By default \fBztest\fR runs for ten minutes and uses block files -(stored in /tmp) to create pools rather than using physical disks. -Block files afford \fBztest\fR its flexibility to play around with +. +.Pp +By default +.Nm +runs for ten minutes and uses block files +(stored in +.Pa /tmp ) +to create pools rather than using physical disks. +Block files afford +.Nm +its flexibility to play around with zpool components without requiring large hardware configurations. -However, storing the block files in /tmp may not work for you if you +However, storing the block files in +.Pa /tmp +may not work for you if you have a small tmp directory. -.LP -By default is non-verbose. This is why entering the command above will -result in \fBztest\fR quietly executing for 5 minutes. The -V option -can be used to increase the verbosity of the tool. Adding multiple -V -option is allowed and the more you add the more chatty \fBztest\fR +. +.Pp +By default is non-verbose. +This is why entering the command above will result in +.Nm +quietly executing for 5 minutes. +The +.Fl V +option can be used to increase the verbosity of the tool. +Adding multiple +.Fl V +options is allowed and the more you add the more chatty +.Nm becomes. -.LP -After the \fBztest\fR run completes, you should notice many ztest.* -files lying around. Once the run completes you can safely remove these -files. Note that you shouldn't remove these files during a run. You -can re-use these files in your next \fBztest\fR run by using the -E +. +.Pp +After the +.Nm +run completes, you should notice many +.Pa ztest.* +files lying around. +Once the run completes you can safely remove these files. +Note that you shouldn't remove these files during a run. +You can re-use these files in your next +.Nm +run by using the +.Fl E option. -.SH OPTIONS -.HP -.BI "\-?" "" -.IP +. +.Sh OPTIONS +.Bl -tag -width "-v v" +.It Fl h , \&? , -help Print a help summary. -.HP -.BI "\-v" " vdevs" " (default: 5) -.IP +.It Fl v , -vdevs Ns = (default: Sy 5 ) Number of vdevs. -.HP -.BI "\-s" " size_of_each_vdev" " (default: 64M)" -.IP +.It Fl s , -vdev-size Ns = (default: Sy 64M ) Size of each vdev. -.HP -.BI "\-a" " alignment_shift" " (default: 9) (use 0 for random)" -.IP -Used alignment in test. -.HP -.BI "\-m" " mirror_copies" " (default: 2)" -.IP +.It Fl a , -alignment-shift Ns = (default: Sy 9 ) No (use Sy 0 No for random) +Alignment shift used in test. +.It Fl m , -mirror-copies Ns = (default: Sy 2 ) Number of mirror copies. -.HP -.BI "\-r" " raidz_disks / draid_disks" " (default: 4 / 16)" -.IP -Number of raidz disks. -.HP -.BI "\-R" " raid_parity" " (default: 1)" -.IP +.It Fl r , -raid-disks Ns = (default: Sy 4 No for raidz/ Ns Sy 16 No for draid) +Number of raidz/draid disks. +.It Fl R , -raid-parity Ns = (default: Sy 1 ) Raid parity (raidz & draid). -.HP -.BI "\-K" " raid_kind" " (default: 'random') raidz|draid|random" -.IP -The kind of RAID config to use. With 'random' the kind alternates between raidz and draid. -.HP -.BI "\-D" " draid_data" " (default: 4)" -.IP +.It Fl K , -raid-kind Ns = Ns Sy raidz Ns | Ns Sy draid Ns | Ns Sy random No (default: Sy random ) +The kind of RAID config to use. +With +.Sy random +the kind alternates between raidz and draid. +.It Fl D , -draid-data Ns = (default: Sy 4 ) Number of data disks in a dRAID redundancy group. -.HP -.BI "\-S" " draid_spares" " (default: 1)" -.IP +.It Fl S , -draid-spares Ns = (default: Sy 1 ) Number of dRAID distributed spare disks. -.HP -.BI "\-C" " vdev_class_state" " (default: random)" -.IP -The vdev allocation class state: special=on|off|random. -.HP -.BI "\-d" " datasets" " (default: 7)" -.IP +.It Fl d , -datasets Ns = (default: Sy 7 ) Number of datasets. -.HP -.BI "\-t" " threads" " (default: 23)" -.IP +.It Fl t , -threads Ns = (default: Sy 23 ) Number of threads. -.HP -.BI "\-g" " gang_block_threshold" " (default: 32K)" -.IP +.It Fl g , -gang-block-threshold Ns = (default: Sy 32K ) Gang block threshold. -.HP -.BI "\-i" " initialize_pool_i_times" " (default: 1)" -.IP -Number of pool initialisations. -.HP -.BI "\-k" " kill_percentage" " (default: 70%)" -.IP +.It Fl i , -init-count Ns = (default: Sy 1 ) +Number of pool initializations. +.It Fl k , -kill-percentage Ns = (default: Sy 70% ) Kill percentage. -.HP -.BI "\-p" " pool_name" " (default: ztest)" -.IP +.It Fl p , -pool-name Ns = (default: Sy ztest ) Pool name. -.HP -.BI "\-V(erbose)" -.IP -Verbose (use multiple times for ever more blather). -.HP -.BI "\-E(xisting)" -.IP +.It Fl f , -vdev-file-directory Ns = (default: Pa /tmp ) +File directory for vdev files. +.It Fl M , -multi-host +Multi-host; simulate pool imported on remote host. +.It Fl E , -use-existing-pool Use existing pool (use existing pool instead of creating new one). -.HP -.BI "\-T" " time" " (default: 300 sec)" -.IP +.It Fl T , -run-time Ns = (default: Sy 300 Ns s) Total test run time. -.HP -.BI "\-z" " zil_failure_rate" " (default: fail every 2^5 allocs) -.IP -Injected failure rate. -.HP -.BI "\-G" -.IP -Dump zfs_dbgmsg buffer before exiting. -.SH "EXAMPLES" -.LP -To override /tmp as your location for block files, you can use the -f +.It Fl P , -pass-time Ns = (default: Sy 60 Ns s) +Time per pass. +.It Fl F , -freeze-loops Ns = (default: Sy 50 ) +Max loops in +.Fn spa_freeze . +.It Fl B , -alt-ztest Ns = +Alternate ztest path. +.It Fl C , -vdev-class-state Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Sy random No (default: Sy random ) +The vdev allocation class state. +.It Fl o , -option Ns = Ns Ar variable Ns = Ns Ar value +Set global +.Ar variable +to an unsigned 32-bit integer +.Ar value +(little-endian only). +.It Fl G , -dump-debug +Dump zfs_dbgmsg buffer before exiting due to an error. +.It Fl V , -verbose +Verbose (use multiple times for ever more verbosity). +.El +. +.Sh EXAMPLES +To override +.Pa /tmp +as your location for block files, you can use the +.Fl f option: -.IP -ztest -f / -.LP -To get an idea of what ztest is actually testing try this: -.IP -ztest -f / -VVV -.LP -Maybe you'd like to run ztest for longer? To do so simply use the -T +.Dl # ztest -f / +.Pp +To get an idea of what +.Nm +is actually testing try this: +.Dl # ztest -f / -VVV +.Pp +Maybe you'd like to run +.Nm ztest +for longer? To do so simply use the +.Fl T option and specify the runlength in seconds like so: -.IP -ztest -f / -V -T 120 - -.SH "ENVIRONMENT VARIABLES" -.TP -.B "ZFS_HOSTID=id" -Use \fBid\fR instead of the SPL hostid to identify this host. Intended for use -with ztest, but this environment variable will affect any utility which uses -libzpool, including \fBzpool(8)\fR. Since the kernel is unaware of this setting +.Dl # ztest -f / -V -T 120 +. +.Sh ENVIRONMENT VARIABLES +.Bl -tag -width "ZF" +.It Ev ZFS_HOSTID Ns = Ns Em id +Use +.Em id +instead of the SPL hostid to identify this host. +Intended for use with +.Nm , but this environment variable will affect any utility which uses +libzpool, including +.Xr zpool 8 . +Since the kernel is unaware of this setting, results with utilities other than ztest are undefined. -.TP -.B "ZFS_STACK_SIZE=stacksize" -Limit the default stack size to \fBstacksize\fR bytes for the purpose of -detecting and debugging kernel stack overflows. This value defaults to -\fB32K\fR which is double the default \fB16K\fR Linux kernel stack size. - +.It Ev ZFS_STACK_SIZE Ns = Ns Em stacksize +Limit the default stack size to +.Em stacksize +bytes for the purpose of +detecting and debugging kernel stack overflows. +This value defaults to +.Em 32K +which is double the default +.Em 16K +Linux kernel stack size. +.Pp In practice, setting the stack size slightly higher is needed because differences in stack usage between kernel and user space can lead to spurious -stack overflows (especially when debugging is enabled). The specified value +stack overflows (especially when debugging is enabled). +The specified value will be rounded up to a floor of PTHREAD_STACK_MIN which is the minimum stack required for a NULL procedure in user space. - -By default the stack size is limited to 256K. -.SH "SEE ALSO" -.BR "spl-module-parameters (5)" "," -.BR "zpool (1)" "," -.BR "zfs (1)" "," -.BR "zdb (1)" "," -.SH "AUTHOR" -This manual page was transferred to asciidoc by Michael Gebetsroither - from http://opensolaris.org/os/community/zfs/ztest/ +.Pp +By default the stack size is limited to +.Em 256K . +.El +. +.Sh SEE ALSO +.Xr zdb 1 , +.Xr zfs 1 , +.Xr zpool 1 , +.Xr spl-module-parameters 5 diff --git a/sys/contrib/openzfs/man/man1/zvol_wait.1 b/sys/contrib/openzfs/man/man1/zvol_wait.1 index 839e1f14475..0fb47ce7348 100644 --- a/sys/contrib/openzfs/man/man1/zvol_wait.1 +++ b/sys/contrib/openzfs/man/man1/zvol_wait.1 @@ -1,21 +1,32 @@ -.Dd July 5, 2019 -.Dt ZVOL_WAIT 1 SMM +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.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. +.\" +.Dd May 27, 2021 +.Dt ZVOL_WAIT 1 .Os +. .Sh NAME .Nm zvol_wait -.Nd Wait for ZFS volume links in -.Em /dev -to be created. +.Nd wait for ZFS volume links to appear in /dev .Sh SYNOPSIS .Nm +. .Sh DESCRIPTION -When a ZFS pool is imported, ZFS will register each ZFS volume -(zvol) as a disk device with the system. As the disks are registered, -.Xr \fBudev 7\fR -will asynchronously create symlinks under -.Em /dev/zvol -using the zvol's name. +When a ZFS pool is imported, the volumes within it will appear as block devices. +As they're registered, +.Xr udev 7 +asynchronously creates symlinks under +.Pa /dev/zvol +using the volumes' names. .Nm -will wait for all those symlinks to be created before returning. +will wait for all those symlinks to be created before exiting. +. .Sh SEE ALSO -.Xr \fBudev 7\fR +.Xr udev 7 diff --git a/sys/contrib/openzfs/man/man5/spl-module-parameters.5 b/sys/contrib/openzfs/man/man5/spl-module-parameters.5 index 5e28e694e04..88652a75ae4 100644 --- a/sys/contrib/openzfs/man/man5/spl-module-parameters.5 +++ b/sys/contrib/openzfs/man/man5/spl-module-parameters.5 @@ -1,326 +1,196 @@ -'\" te +.\" +.\" 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] .\" .\" Copyright 2013 Turbo Fredriksson . All rights reserved. .\" -.TH SPL-MODULE-PARAMETERS 5 "Aug 24, 2020" OpenZFS -.SH NAME -spl\-module\-parameters \- SPL module parameters -.SH DESCRIPTION -.sp -.LP -Description of the different parameters to the SPL module. - -.SS "Module parameters" -.sp -.LP - -.sp -.ne 2 -.na -\fBspl_kmem_cache_expire\fR (uint) -.ad -.RS 12n -Cache expiration is part of default Illumos cache behavior. The idea is -that objects in magazines which have not been recently accessed should be -returned to the slabs periodically. This is known as cache aging and -when enabled objects will be typically returned after 15 seconds. -.sp -On the other hand Linux slabs are designed to never move objects back to -the slabs unless there is memory pressure. This is possible because under -Linux the cache will be notified when memory is low and objects can be -released. -.sp -By default only the Linux method is enabled. It has been shown to improve -responsiveness on low memory systems and not negatively impact the performance -of systems with more memory. This policy may be changed by setting the -\fBspl_kmem_cache_expire\fR bit mask as follows, both policies may be enabled -concurrently. -.sp -0x01 - Aging (Illumos), 0x02 - Low memory (Linux) -.sp -Default value: \fB0x02\fR -.RE - -.sp -.ne 2 -.na -\fBspl_kmem_cache_kmem_threads\fR (uint) -.ad -.RS 12n -The number of threads created for the spl_kmem_cache task queue. This task -queue is responsible for allocating new slabs for use by the kmem caches. +.Dd August 24, 2020 +.Dt SPL-MODULE-PARAMETERS 5 +.Os +. +.Sh NAME +.Nm spl-module-parameters +.Nd parameters of the SPL kernel module +. +.Sh DESCRIPTION +.Bl -tag -width Ds +.It Sy spl_kmem_cache_kmem_threads Ns = Ns Sy 4 Pq uint +The number of threads created for the spl_kmem_cache task queue. +This task queue is responsible for allocating new slabs +for use by the kmem caches. For the majority of systems and workloads only a small number of threads are required. -.sp -Default value: \fB4\fR -.RE - -.sp -.ne 2 -.na -\fBspl_kmem_cache_reclaim\fR (uint) -.ad -.RS 12n +. +.It Sy spl_kmem_cache_reclaim Ns = Ns Sy 0 Pq uint When this is set it prevents Linux from being able to rapidly reclaim all the -memory held by the kmem caches. This may be useful in circumstances where -it's preferable that Linux reclaim memory from some other subsystem first. +memory held by the kmem caches. +This may be useful in circumstances where it's preferable that Linux +reclaim memory from some other subsystem first. Setting this will increase the likelihood out of memory events on a memory constrained system. -.sp -Default value: \fB0\fR -.RE - -.sp -.ne 2 -.na -\fBspl_kmem_cache_obj_per_slab\fR (uint) -.ad -.RS 12n -The preferred number of objects per slab in the cache. In general, a larger -value will increase the caches memory footprint while decreasing the time -required to perform an allocation. Conversely, a smaller value will minimize -the footprint and improve cache reclaim time but individual allocations may -take longer. -.sp -Default value: \fB8\fR -.RE - -.sp -.ne 2 -.na -\fBspl_kmem_cache_obj_per_slab_min\fR (uint) -.ad -.RS 12n -The minimum number of objects allowed per slab. Normally slabs will contain -\fBspl_kmem_cache_obj_per_slab\fR objects but for caches that contain very -large objects it's desirable to only have a few, or even just one, object per -slab. -.sp -Default value: \fB1\fR -.RE - -.sp -.ne 2 -.na -\fBspl_kmem_cache_max_size\fR (uint) -.ad -.RS 12n -The maximum size of a kmem cache slab in MiB. This effectively limits -the maximum cache object size to \fBspl_kmem_cache_max_size\fR / -\fBspl_kmem_cache_obj_per_slab\fR. Caches may not be created with +. +.It Sy spl_kmem_cache_obj_per_slab Ns = Ns Sy 8 Pq uint +The preferred number of objects per slab in the cache. +In general, a larger value will increase the caches memory footprint +while decreasing the time required to perform an allocation. +Conversely, a smaller value will minimize the footprint +and improve cache reclaim time but individual allocations may take longer. +. +.It Sy spl_kmem_cache_max_size Ns = Ns Sy 32 Po 64-bit Pc or Sy 4 Po 32-bit Pc Pq uint +The maximum size of a kmem cache slab in MiB. +This effectively limits the maximum cache object size to +.Sy spl_kmem_cache_max_size Ns / Ns Sy spl_kmem_cache_obj_per_slab . +.Pp +Caches may not be created with object sized larger than this limit. -.sp -Default value: \fB32 (64-bit) or 4 (32-bit)\fR -.RE - -.sp -.ne 2 -.na -\fBspl_kmem_cache_slab_limit\fR (uint) -.ad -.RS 12n +. +.It Sy spl_kmem_cache_slab_limit Ns = Ns Sy 16384 Pq uint For small objects the Linux slab allocator should be used to make the most -efficient use of the memory. However, large objects are not supported by -the Linux slab and therefore the SPL implementation is preferred. This -value is used to determine the cutoff between a small and large object. -.sp -Objects of \fBspl_kmem_cache_slab_limit\fR or smaller will be allocated -using the Linux slab allocator, large objects use the SPL allocator. A -cutoff of 16K was determined to be optimal for architectures using 4K pages. -.sp -Default value: \fB16,384\fR -.RE - -.sp -.ne 2 -.na -\fBspl_kmem_alloc_warn\fR (uint) -.ad -.RS 12n -As a general rule kmem_alloc() allocations should be small, preferably -just a few pages since they must by physically contiguous. Therefore, a -rate limited warning will be printed to the console for any kmem_alloc() +efficient use of the memory. +However, large objects are not supported by +the Linux slab and therefore the SPL implementation is preferred. +This value is used to determine the cutoff between a small and large object. +.Pp +Objects of size +.Sy spl_kmem_cache_slab_limit +or smaller will be allocated using the Linux slab allocator, +large objects use the SPL allocator. +A cutoff of 16K was determined to be optimal for architectures using 4K pages. +. +.It Sy spl_kmem_alloc_warn Ns = Ns Sy 32768 Pq uint +As a general rule +.Fn kmem_alloc +allocations should be small, +preferably just a few pages, since they must by physically contiguous. +Therefore, a rate limited warning will be printed to the console for any +.Fn kmem_alloc which exceeds a reasonable threshold. -.sp +.Pp The default warning threshold is set to eight pages but capped at 32K to -accommodate systems using large pages. This value was selected to be small -enough to ensure the largest allocations are quickly noticed and fixed. +accommodate systems using large pages. +This value was selected to be small enough to ensure +the largest allocations are quickly noticed and fixed. But large enough to avoid logging any warnings when a allocation size is -larger than optimal but not a serious concern. Since this value is tunable, -developers are encouraged to set it lower when testing so any new largish -allocations are quickly caught. These warnings may be disabled by setting -the threshold to zero. -.sp -Default value: \fB32,768\fR -.RE - -.sp -.ne 2 -.na -\fBspl_kmem_alloc_max\fR (uint) -.ad -.RS 12n -Large kmem_alloc() allocations will fail if they exceed KMALLOC_MAX_SIZE. +larger than optimal but not a serious concern. +Since this value is tunable, developers are encouraged to set it lower +when testing so any new largish allocations are quickly caught. +These warnings may be disabled by setting the threshold to zero. +. +.It Sy spl_kmem_alloc_max Ns = Ns Sy KMALLOC_MAX_SIZE Ns / Ns Sy 4 Pq uint +Large +.Fn kmem_alloc +allocations will fail if they exceed +.Sy KMALLOC_MAX_SIZE . Allocations which are marginally smaller than this limit may succeed but should still be avoided due to the expense of locating a contiguous range -of free pages. Therefore, a maximum kmem size with reasonable safely -margin of 4x is set. Kmem_alloc() allocations larger than this maximum -will quickly fail. Vmem_alloc() allocations less than or equal to this -value will use kmalloc(), but shift to vmalloc() when exceeding this value. -.sp -Default value: \fBKMALLOC_MAX_SIZE/4\fR -.RE - -.sp -.ne 2 -.na -\fBspl_kmem_cache_magazine_size\fR (uint) -.ad -.RS 12n +of free pages. +Therefore, a maximum kmem size with reasonable safely margin of 4x is set. +.Fn kmem_alloc +allocations larger than this maximum will quickly fail. +.Fn vmem_alloc +allocations less than or equal to this value will use +.Fn kmalloc , +but shift to +.Fn vmalloc +when exceeding this value. +. +.It Sy spl_kmem_cache_magazine_size Ns = Ns Sy 0 Pq uint Cache magazines are an optimization designed to minimize the cost of -allocating memory. They do this by keeping a per-cpu cache of recently -freed objects, which can then be reallocated without taking a lock. This -can improve performance on highly contended caches. However, because -objects in magazines will prevent otherwise empty slabs from being -immediately released this may not be ideal for low memory machines. -.sp -For this reason \fBspl_kmem_cache_magazine_size\fR can be used to set a -maximum magazine size. When this value is set to 0 the magazine size will -be automatically determined based on the object size. Otherwise magazines -will be limited to 2-256 objects per magazine (i.e per cpu). Magazines -may never be entirely disabled in this implementation. -.sp -Default value: \fB0\fR -.RE - -.sp -.ne 2 -.na -\fBspl_hostid\fR (ulong) -.ad -.RS 12n +allocating memory. +They do this by keeping a per-cpu cache of recently +freed objects, which can then be reallocated without taking a lock. +This can improve performance on highly contended caches. +However, because objects in magazines will prevent otherwise empty slabs +from being immediately released this may not be ideal for low memory machines. +.Pp +For this reason, +.Sy spl_kmem_cache_magazine_size +can be used to set a maximum magazine size. +When this value is set to 0 the magazine size will +be automatically determined based on the object size. +Otherwise magazines will be limited to 2-256 objects per magazine (i.e per cpu). +Magazines may never be entirely disabled in this implementation. +. +.It Sy spl_hostid Ns = Ns Sy 0 Pq ulong The system hostid, when set this can be used to uniquely identify a system. By default this value is set to zero which indicates the hostid is disabled. It can be explicitly enabled by placing a unique non-zero value in -\fB/etc/hostid/\fR. -.sp -Default value: \fB0\fR -.RE - -.sp -.ne 2 -.na -\fBspl_hostid_path\fR (charp) -.ad -.RS 12n -The expected path to locate the system hostid when specified. This value -may be overridden for non-standard configurations. -.sp -Default value: \fB/etc/hostid\fR -.RE - -.sp -.ne 2 -.na -\fBspl_panic_halt\fR (uint) -.ad -.RS 12n -Cause a kernel panic on assertion failures. When not enabled, the thread is -halted to facilitate further debugging. -.sp +.Pa /etc/hostid . +. +.It Sy spl_hostid_path Ns = Ns Pa /etc/hostid Pq charp +The expected path to locate the system hostid when specified. +This value may be overridden for non-standard configurations. +. +.It Sy spl_panic_halt Ns = Ns Sy 0 Pq uint +Cause a kernel panic on assertion failures. +When not enabled, the thread is halted to facilitate further debugging. +.Pp Set to a non-zero value to enable. -.sp -Default value: \fB0\fR -.RE - -.sp -.ne 2 -.na -\fBspl_taskq_kick\fR (uint) -.ad -.RS 12n -Kick stuck taskq to spawn threads. When writing a non-zero value to it, it will -scan all the taskqs. If any of them have a pending task more than 5 seconds old, -it will kick it to spawn more threads. This can be used if you find a rare +. +.It Sy spl_taskq_kick Ns = Ns Sy 0 Pq uint +Kick stuck taskq to spawn threads. +When writing a non-zero value to it, it will scan all the taskqs. +If any of them have a pending task more than 5 seconds old, +it will kick it to spawn more threads. +This can be used if you find a rare deadlock occurs because one or more taskqs didn't spawn a thread when it should. -.sp -Default value: \fB0\fR -.RE - -.sp -.ne 2 -.na -\fBspl_taskq_thread_bind\fR (int) -.ad -.RS 12n -Bind taskq threads to specific CPUs. When enabled all taskq threads will -be distributed evenly over the available CPUs. By default, this behavior -is disabled to allow the Linux scheduler the maximum flexibility to determine -where a thread should run. -.sp -Default value: \fB0\fR -.RE - -.sp -.ne 2 -.na -\fBspl_taskq_thread_dynamic\fR (int) -.ad -.RS 12n -Allow dynamic taskqs. When enabled taskqs which set the TASKQ_DYNAMIC flag -will by default create only a single thread. New threads will be created on -demand up to a maximum allowed number to facilitate the completion of -outstanding tasks. Threads which are no longer needed will be promptly -destroyed. By default this behavior is enabled but it can be disabled to +. +.It Sy spl_taskq_thread_bind Ns = Ns Sy 0 Pq int +Bind taskq threads to specific CPUs. +When enabled all taskq threads will be distributed evenly +across the available CPUs. +By default, this behavior is disabled to allow the Linux scheduler +the maximum flexibility to determine where a thread should run. +. +.It Sy spl_taskq_thread_dynamic Ns = Ns Sy 1 Pq int +Allow dynamic taskqs. +When enabled taskqs which set the +.Sy TASKQ_DYNAMIC +flag will by default create only a single thread. +New threads will be created on demand up to a maximum allowed number +to facilitate the completion of outstanding tasks. +Threads which are no longer needed will be promptly destroyed. +By default this behavior is enabled but it can be disabled to aid performance analysis or troubleshooting. -.sp -Default value: \fB1\fR -.RE - -.sp -.ne 2 -.na -\fBspl_taskq_thread_priority\fR (int) -.ad -.RS 12n +. +.It Sy spl_taskq_thread_priority Ns = Ns Sy 1 Pq int Allow newly created taskq threads to set a non-default scheduler priority. -When enabled the priority specified when a taskq is created will be applied -to all threads created by that taskq. When disabled all threads will use -the default Linux kernel thread priority. By default, this behavior is -enabled. -.sp -Default value: \fB1\fR -.RE - -.sp -.ne 2 -.na -\fBspl_taskq_thread_sequential\fR (int) -.ad -.RS 12n +When enabled, the priority specified when a taskq is created will be applied +to all threads created by that taskq. +When disabled all threads will use the default Linux kernel thread priority. +By default, this behavior is enabled. +. +.It Sy spl_taskq_thread_sequential Ns = Ns Sy 4 Pq int The number of items a taskq worker thread must handle without interruption -before requesting a new worker thread be spawned. This is used to control +before requesting a new worker thread be spawned. +This is used to control how quickly taskqs ramp up the number of threads processing the queue. Because Linux thread creation and destruction are relatively inexpensive a -small default value has been selected. This means that normally threads will -be created aggressively which is desirable. Increasing this value will +small default value has been selected. +This means that normally threads will be created aggressively which is desirable. +Increasing this value will result in a slower thread creation rate which may be preferable for some configurations. -.sp -Default value: \fB4\fR -.RE - -.sp -.ne 2 -.na -\fBspl_max_show_tasks\fR (uint) -.ad -.RS 12n +. +.It Sy spl_max_show_tasks Ns = Ns Sy 512 Pq uint The maximum number of tasks per pending list in each taskq shown in -/proc/spl/{taskq,taskq-all}. Write 0 to turn off the limit. The proc file will -walk the lists with lock held, reading it could cause a lock up if the list -grow too large without limiting the output. "(truncated)" will be shown if the -list is larger than the limit. -.sp -Default value: \fB512\fR -.RE +.Pa /proc/spl/taskq{,-all} . +Write +.Sy 0 +to turn off the limit. +The proc file will walk the lists with lock held, +reading it could cause a lock-up if the list grow too large +without limiting the output. +"(truncated)" will be shown if the list is larger than the limit. +. +.El diff --git a/sys/contrib/openzfs/man/man5/vdev_id.conf.5 b/sys/contrib/openzfs/man/man5/vdev_id.conf.5 index 9ae3865f7d3..1268114bdbc 100644 --- a/sys/contrib/openzfs/man/man5/vdev_id.conf.5 +++ b/sys/contrib/openzfs/man/man5/vdev_id.conf.5 @@ -1,222 +1,251 @@ -.TH VDEV_ID.CONF 5 "Aug 24, 2020" OpenZFS -.SH NAME -vdev_id.conf \- Configuration file for vdev_id -.SH DESCRIPTION -.I vdev_id.conf +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.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. +.\" +.Dd May 26, 2021 +.Dt VDEV_ID.CONF 5 +.Os +. +.Sh NAME +.Nm vdev_id.conf +.Nd Configuration file for vdev_id +.Sh DESCRIPTION +.Nm is the configuration file for -.BR vdev_id (8). +.Nm vdev_id Ns Sy (8) . It controls the default behavior of -.BR vdev_id (8) +.Nm vdev_id Ns Sy (8) while it is mapping a disk device name to an alias. -.PP +.Pp The -.I vdev_id.conf +.Nm file uses a simple format consisting of a keyword followed by one or -more values on a single line. Any line not beginning with a recognized -keyword is ignored. Comments may optionally begin with a hash -character. - +more values on a single line. +Any line not beginning with a recognized keyword is ignored. +Comments may optionally begin with a hash character. +.Pp The following keywords and values are used. -.TP -\fIalias\fR -Maps a device link in the /dev directory hierarchy to a new device -name. The udev rule defining the device link must have run prior to -.BR vdev_id (8). +.Bl -tag -width "-h" +.It Sy alias Ar name Ar devlink +Maps a device link in the +.Pa /dev +directory hierarchy to a new device name. +The udev rule defining the device link must have run prior to +.Nm vdev_id Ns Sy (8) . A defined alias takes precedence over a topology-derived name, but the -two naming methods can otherwise coexist. For example, one might name -drives in a JBOD with the sas_direct topology while naming an internal -L2ARC device with an alias. - -\fIname\fR - the name of the link to the device that will by created in -/dev/disk/by-vdev. - -\fIdevlink\fR - the name of the device link that has already been -defined by udev. This may be an absolute path or the base filename. - -.TP -\fIchannel\fR [pci_slot] +two naming methods can otherwise coexist. +For example, one might name drives in a JBOD with the +.Sy sas_direct +topology while naming an internal L2ARC device with an alias. +.Pp +.Ar name +is the name of the link to the device that will by created under +.Pa /dev/disk/by-vdev . +.Pp +.Ar devlink +is the name of the device link that has already been +defined by udev. +This may be an absolute path or the base filename. +. +.It Sy channel [ Ns Ar pci_slot ] Ar port Ar name Maps a physical path to a channel name (typically representing a single disk enclosure). - -.TP -\fIenclosure_symlinks\fR -Additionally create /dev/by-enclosure symlinks to the disk enclosure -sg devices using the naming scheme from vdev_id.conf. -\fIenclosure_symlinks\fR is only allowed for sas_direct mode. -.TP -\fIenclosure_symlinks_prefix\fR -Specify the prefix for the enclosure symlinks in the form of: - -/dev/by-enclosure/- - -Defaults to "enc" if not specified. -.TP -\fIpci_slot\fR - specifies the PCI SLOT of the HBA -hosting the disk enclosure being mapped, as found in the output of -.BR lspci (8). -This argument is not used in sas_switch mode. - -\fIport\fR - specifies the numeric identifier of the HBA or SAS switch port -connected to the disk enclosure being mapped. - -\fIname\fR - specifies the name of the channel. - -.TP -\fIslot\fR [channel] +. +.It Sy enclosure_symlinks Sy yes Ns | Ns Sy no +Additionally create +.Pa /dev/by-enclosure +symlinks to the disk enclosure +.Em sg +devices using the naming scheme from +.Pa vdev_id.conf . +.Sy enclosure_symlinks +is only allowed for +.Sy sas_direct +mode. +. +.It Sy enclosure_symlinks_prefix Ar prefix +Specify the prefix for the enclosure symlinks in the form +.Pa /dev/by-enclosure/ Ns Ao Ar prefix Ac Ns - Ns Ao Ar channel Ac Ns Aq Ar num +.Pp +Defaults to +.Dq Em enc . +. +.It Sy slot Ar prefix Ar new Op Ar channel Maps a disk slot number as reported by the operating system to an -alternative slot number. If the \fIchannel\fR parameter is specified +alternative slot number. +If the +.Ar channel +parameter is specified then the mapping is only applied to slots in the named channel, -otherwise the mapping is applied to all channels. The first-specified -\fIslot\fR rule that can match a slot takes precedence. Therefore a -channel-specific mapping for a given slot should generally appear before -a generic mapping for the same slot. In this way a custom mapping may -be applied to a particular channel and a default mapping applied to the -others. - -.TP -\fImultipath\fR +otherwise the mapping is applied to all channels. +The first-specified +.Ar slot +rule that can match a slot takes precedence. +Therefore a channel-specific mapping for a given slot should generally appear +before a generic mapping for the same slot. +In this way a custom mapping may be applied to a particular channel +and a default mapping applied to the others. +. +.It Sy multipath Sy yes Ns | Ns Sy no Specifies whether -.BR vdev_id (8) -will handle only dm-multipath devices. If set to "yes" then -.BR vdev_id (8) +.Nm vdev_id Ns Sy (8) +will handle only dm-multipath devices. +If set to +.Sy yes +then +.Nm vdev_id Ns Sy (8) will examine the first running component disk of a dm-multipath -device as listed by the -.BR multipath (8) -command to determine the physical path. -.TP -\fItopology\fR +device as provided by the driver command to determine the physical path. +. +.It Sy topology Sy sas_direct Ns | Ns Sy sas_switch Ns | Ns Sy scsi Identifies a physical topology that governs how physical paths are -mapped to channels. - -\fIsas_direct\fR - in this mode a channel is uniquely identified by -a PCI slot and a HBA port number - -\fIsas_switch\fR - in this mode a channel is uniquely identified by -a SAS switch port number - -.TP -\fIphys_per_port\fR +mapped to channels: +.Bl -tag -compact -width "sas_direct and scsi" +.It Sy sas_direct No and Sy scsi +channels are uniquely identified by a PCI slot and HBA port number +.It Sy sas_switch +channels are uniquely identified by a SAS switch port number +.El +. +.It Sy phys_per_port Ar num Specifies the number of PHY devices associated with a SAS HBA port or SAS switch port. -.BR vdev_id (8) +.Nm vdev_id Ns Sy (8) internally uses this value to determine which HBA or switch port a -device is connected to. The default is 4. - -.TP -\fIslot\fR +device is connected to. +The default is +.Sy 4 . +. +.It Sy slot Sy bay Ns | Ns Sy phy Ns | Ns Sy port Ns | Ns Sy id Ns | Ns Sy lun Ns | Ns Sy ses Specifies from which element of a SAS identifier the slot number is -taken. The default is bay. - -\fIbay\fR - read the slot number from the bay identifier. - -\fIphy\fR - read the slot number from the phy identifier. - -\fIport\fR - use the SAS port as the slot number. - -\fIid\fR - use the scsi id as the slot number. - -\fIlun\fR - use the scsi lun as the slot number. - -\fIses\fR - use the SCSI Enclosure Services (SES) enclosure device slot number, +taken. +The default is +.Sy bay : +.Bl -tag -compact -width "port" +.It Sy bay +read the slot number from the bay identifier. +.It Sy phy +read the slot number from the phy identifier. +.It Sy port +use the SAS port as the slot number. +.It Sy id +use the scsi id as the slot number. +.It Sy lun +use the scsi lun as the slot number. +.It Sy ses +use the SCSI Enclosure Services (SES) enclosure device slot number, as reported by -.BR sg_ses (8). -This is intended for use only on systems where \fIbay\fR is unsupported, -noting that \fIport\fR and \fIid\fR may be unstable across disk replacement. -.SH EXAMPLES -A non-multipath configuration with direct-attached SAS enclosures and an -arbitrary slot re-mapping. -.P -.nf - multipath no - topology sas_direct - phys_per_port 4 - slot bay - - # PCI_SLOT HBA PORT CHANNEL NAME - channel 85:00.0 1 A - channel 85:00.0 0 B - channel 86:00.0 1 C - channel 86:00.0 0 D - - # Custom mapping for Channel A - - # Linux Mapped - # Slot Slot Channel - slot 1 7 A - slot 2 10 A - slot 3 3 A - slot 4 6 A - - # Default mapping for B, C, and D - - slot 1 4 - slot 2 2 - slot 3 1 - slot 4 3 -.fi -.P -A SAS-switch topology. Note that the -.I channel -keyword takes only two arguments in this example. -.P -.nf - topology sas_switch - - # SWITCH PORT CHANNEL NAME - channel 1 A - channel 2 B - channel 3 C - channel 4 D -.fi -.P -A multipath configuration. Note that channel names have multiple -definitions - one per physical path. -.P -.nf - multipath yes - - # PCI_SLOT HBA PORT CHANNEL NAME - channel 85:00.0 1 A - channel 85:00.0 0 B - channel 86:00.0 1 A - channel 86:00.0 0 B -.fi -.P -A configuration with enclosure_symlinks enabled. -.P -.nf - multipath yes - enclosure_symlinks yes - - # PCI_ID HBA PORT CHANNEL NAME - channel 05:00.0 1 U - channel 05:00.0 0 L - channel 06:00.0 1 U - channel 06:00.0 0 L -.fi -In addition to the disks symlinks, this configuration will create: -.P -.nf - /dev/by-enclosure/enc-L0 - /dev/by-enclosure/enc-L1 - /dev/by-enclosure/enc-U0 - /dev/by-enclosure/enc-U1 -.fi -.P -A configuration using device link aliases. -.P -.nf - # by-vdev - # name fully qualified or base name of device link - alias d1 /dev/disk/by-id/wwn-0x5000c5002de3b9ca - alias d2 wwn-0x5000c5002def789e -.fi -.P - -.SH FILES -.TP -.I /etc/zfs/vdev_id.conf +.Xr sg_ses 8 . +Intended for use only on systems where +.Sy bay +is unsupported, +noting that +.Sy port +and +.Sy id +may be unstable across disk replacement. +.El +.El +. +.Sh FILES +.Bl -tag -width "-v v" +.It Pa /etc/zfs/vdev_id.conf The configuration file for -.BR vdev_id (8). -.SH SEE ALSO -.BR vdev_id (8) +.Nm vdev_id Ns Sy (8) . +.El +. +.Sh EXAMPLES +A non-multipath configuration with direct-attached SAS enclosures and an +arbitrary slot re-mapping: +.Bd -literal -offset Ds +multipath no +topology sas_direct +phys_per_port 4 +slot bay + +# PCI_SLOT HBA PORT CHANNEL NAME +channel 85:00.0 1 A +channel 85:00.0 0 B +channel 86:00.0 1 C +channel 86:00.0 0 D + +# Custom mapping for Channel A + +# Linux Mapped +# Slot Slot Channel +slot 1 7 A +slot 2 10 A +slot 3 3 A +slot 4 6 A + +# Default mapping for B, C, and D + +slot 1 4 +slot 2 2 +slot 3 1 +slot 4 3 +.Ed +.Pp +A SAS-switch topology. +Note, that the +.Ar channel +keyword takes only two arguments in this example. +.Bd -literal -offset Ds +topology sas_switch + +# SWITCH PORT CHANNEL NAME +channel 1 A +channel 2 B +channel 3 C +channel 4 D +.Ed +.Pp +A multipath configuration. +Note that channel names have multiple +definitions - one per physical path. +.Bd -literal -offset Ds +multipath yes + +# PCI_SLOT HBA PORT CHANNEL NAME +channel 85:00.0 1 A +channel 85:00.0 0 B +channel 86:00.0 1 A +channel 86:00.0 0 B +.Ed +.Pp +A configuration with enclosure_symlinks enabled. +.Bd -literal -offset Ds +multipath yes +enclosure_symlinks yes + +# PCI_ID HBA PORT CHANNEL NAME +channel 05:00.0 1 U +channel 05:00.0 0 L +channel 06:00.0 1 U +channel 06:00.0 0 L +.Ed +.Pp +In addition to the disks symlinks, this configuration will create: +.Bd -literal -offset Ds +/dev/by-enclosure/enc-L0 +/dev/by-enclosure/enc-L1 +/dev/by-enclosure/enc-U0 +/dev/by-enclosure/enc-U1 +.Ed +.Pp +A configuration using device link aliases. +.Bd -literal -offset Ds +# by-vdev +# name fully qualified or base name of device link +alias d1 /dev/disk/by-id/wwn-0x5000c5002de3b9ca +alias d2 wwn-0x5000c5002def789e +.Ed +. +.Sh SEE ALSO +.Xr vdev_id 8 diff --git a/sys/contrib/openzfs/man/man5/zfs-events.5 b/sys/contrib/openzfs/man/man5/zfs-events.5 index 0d0e1a9593d..846a7080d01 100644 --- a/sys/contrib/openzfs/man/man5/zfs-events.5 +++ b/sys/contrib/openzfs/man/man5/zfs-events.5 @@ -1,4 +1,4 @@ -'\" te +.\" .\" Copyright (c) 2013 by Turbo Fredriksson . All rights reserved. .\" Portions Copyright 2018 by Richard Elling .\" The contents of this file are subject to the terms of the Common Development @@ -13,865 +13,348 @@ .\" CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your .\" own identifying information: .\" Portions Copyright [yyyy] [name of copyright owner] -.TH ZFS-EVENTS 5 "Aug 24, 2020" OpenZFS -.SH NAME -zfs\-events \- Events created by the ZFS filesystem. -.SH DESCRIPTION -.sp -.LP +.\" +.Dd May 26, 2021 +.Dt ZFS-EVENTS 5 +.Os +. +.Sh NAME +.Nm zfs-events +.Nd Events created by the ZFS filesystem +.Sh DESCRIPTION Description of the different events generated by the ZFS stack. -.sp -Most of these don't have any description. The events generated by ZFS -have never been publicly documented. What is here is intended as a -starting point to provide documentation for all possible events. -.sp +.Pp +Most of these don't have any description. +The events generated by ZFS have never been publicly documented. +What is here is intended as a starting point to provide documentation +for all possible events. +.Pp To view all events created since the loading of the ZFS infrastructure (i.e, "the module"), run -.P -.nf -\fBzpool events\fR -.fi -.P +.Dl Nm zpool Cm events to get a short list, and -.P -.nf -\fBzpool events -v\fR -.fi -.P +.Dl Nm zpool Cm events Fl v to get a full detail of the events and what information is available about it. -.sp -This man page lists the different subclasses that are issued -in the case of an event. The full event name would be -\fIereport.fs.zfs.SUBCLASS\fR, but we only list the last -part here. - -.SS "EVENTS (SUBCLASS)" -.sp -.LP - -.sp -.ne 2 -.na -\fBchecksum\fR -.ad -.RS 12n +.Pp +This manual page lists the different subclasses that are issued +in the case of an event. +The full event name would be +.Sy ereport.fs.zfs.\& Ns Em SUBCLASS , +but we only list the last part here. +. +.Sh EVENTS (SUBCLASS) +.Bl -tag -compact -width "vdev.bad_guid_sum" +.It Sy checksum Issued when a checksum error has been detected. -.RE - -.sp -.ne 2 -.na -\fBio\fR -.ad -.RS 12n +.It Sy io Issued when there is an I/O error in a vdev in the pool. -.RE - -.sp -.ne 2 -.na -\fBdata\fR -.ad -.RS 12n +.It Sy data Issued when there have been data errors in the pool. -.RE - -.sp -.ne 2 -.na -\fBdeadman\fR -.ad -.RS 12n -Issued when an I/O is determined to be "hung", this can be caused by lost -completion events due to flaky hardware or drivers. See the -\fBzfs_deadman_failmode\fR module option description for additional -information regarding "hung" I/O detection and configuration. -.RE - -.sp -.ne 2 -.na -\fBdelay\fR -.ad -.RS 12n -Issued when a completed I/O exceeds the maximum allowed time specified -by the \fBzio_slow_io_ms\fR module option. This can be an indicator of -problems with the underlying storage device. The number of delay events is -ratelimited by the \fBzfs_slow_io_events_per_second\fR module parameter. -.RE - -.sp -.ne 2 -.na -\fBconfig.sync\fR -.ad -.RS 12n +.It Sy deadman +Issued when an I/O request is determined to be "hung", this can be caused +by lost completion events due to flaky hardware or drivers. +See +.Sy zfs_deadman_failmode +in +.Xr zfs-module-parameters 5 +for additional information regarding "hung" I/O detection and configuration. +.It Sy delay +Issued when a completed I/O request exceeds the maximum allowed time +specified by the +.Sy zio_slow_io_ms +module parameter. +This can be an indicator of problems with the underlying storage device. +The number of delay events is ratelimited by the +.Sy zfs_slow_io_events_per_second +module parameter. +.It Sy config Issued every time a vdev change have been done to the pool. -.RE - -.sp -.ne 2 -.na -\fBzpool\fR -.ad -.RS 12n +.It Sy zpool Issued when a pool cannot be imported. -.RE - -.sp -.ne 2 -.na -\fBzpool.destroy\fR -.ad -.RS 12n +.It Sy zpool.destroy Issued when a pool is destroyed. -.RE - -.sp -.ne 2 -.na -\fBzpool.export\fR -.ad -.RS 12n +.It Sy zpool.export Issued when a pool is exported. -.RE - -.sp -.ne 2 -.na -\fBzpool.import\fR -.ad -.RS 12n +.It Sy zpool.import Issued when a pool is imported. -.RE - -.sp -.ne 2 -.na -\fBzpool.reguid\fR -.ad -.RS 12n +.It Sy zpool.reguid Issued when a REGUID (new unique identifier for the pool have been regenerated) have been detected. -.RE - -.sp -.ne 2 -.na -\fBvdev.unknown\fR -.ad -.RS 12n -Issued when the vdev is unknown. Such as trying to clear device -errors on a vdev that have failed/been kicked from the system/pool -and is no longer available. -.RE - -.sp -.ne 2 -.na -\fBvdev.open_failed\fR -.ad -.RS 12n +.It Sy vdev.unknown +Issued when the vdev is unknown. +Such as trying to clear device errors on a vdev that have failed/been kicked +from the system/pool and is no longer available. +.It Sy vdev.open_failed Issued when a vdev could not be opened (because it didn't exist for example). -.RE - -.sp -.ne 2 -.na -\fBvdev.corrupt_data\fR -.ad -.RS 12n +.It Sy vdev.corrupt_data Issued when corrupt data have been detected on a vdev. -.RE - -.sp -.ne 2 -.na -\fBvdev.no_replicas\fR -.ad -.RS 12n +.It Sy vdev.no_replicas Issued when there are no more replicas to sustain the pool. -This would lead to the pool being \fIDEGRADED\fR. -.RE - -.sp -.ne 2 -.na -\fBvdev.bad_guid_sum\fR -.ad -.RS 12n +This would lead to the pool being +.Em DEGRADED . +.It Sy vdev.bad_guid_sum Issued when a missing device in the pool have been detected. -.RE - -.sp -.ne 2 -.na -\fBvdev.too_small\fR -.ad -.RS 12n +.It Sy vdev.too_small Issued when the system (kernel) have removed a device, and ZFS -notices that the device isn't there any more. This is usually -followed by a \fBprobe_failure\fR event. -.RE - -.sp -.ne 2 -.na -\fBvdev.bad_label\fR -.ad -.RS 12n +notices that the device isn't there any more. +This is usually followed by a +.Sy probe_failure +event. +.It Sy vdev.bad_label Issued when the label is OK but invalid. -.RE - -.sp -.ne 2 -.na -\fBvdev.bad_ashift\fR -.ad -.RS 12n +.It Sy vdev.bad_ashift Issued when the ashift alignment requirement has increased. -.RE - -.sp -.ne 2 -.na -\fBvdev.remove\fR -.ad -.RS 12n +.It Sy vdev.remove Issued when a vdev is detached from a mirror (or a spare detached from a vdev where it have been used to replace a failed drive - only works if the original drive have been readded). -.RE - -.sp -.ne 2 -.na -\fBvdev.clear\fR -.ad -.RS 12n -Issued when clearing device errors in a pool. Such as running \fBzpool clear\fR +.It Sy vdev.clear +Issued when clearing device errors in a pool. +Such as running +.Nm zpool Cm clear on a device in the pool. -.RE - -.sp -.ne 2 -.na -\fBvdev.check\fR -.ad -.RS 12n +.It Sy vdev.check Issued when a check to see if a given vdev could be opened is started. -.RE - -.sp -.ne 2 -.na -\fBvdev.spare\fR -.ad -.RS 12n +.It Sy vdev.spare Issued when a spare have kicked in to replace a failed device. -.RE - -.sp -.ne 2 -.na -\fBvdev.autoexpand\fR -.ad -.RS 12n +.It Sy vdev.autoexpand Issued when a vdev can be automatically expanded. -.RE - -.sp -.ne 2 -.na -\fBio_failure\fR -.ad -.RS 12n +.It Sy io_failure Issued when there is an I/O failure in a vdev in the pool. -.RE - -.sp -.ne 2 -.na -\fBprobe_failure\fR -.ad -.RS 12n -Issued when a probe fails on a vdev. This would occur if a vdev +.It Sy probe_failure +Issued when a probe fails on a vdev. +This would occur if a vdev have been kicked from the system outside of ZFS (such as the kernel have removed the device). -.RE - -.sp -.ne 2 -.na -\fBlog_replay\fR -.ad -.RS 12n -Issued when the intent log cannot be replayed. The can occur in the case -of a missing or damaged log device. -.RE - -.sp -.ne 2 -.na -\fBresilver.start\fR -.ad -.RS 12n +.It Sy log_replay +Issued when the intent log cannot be replayed. +The can occur in the case of a missing or damaged log device. +.It Sy resilver.start Issued when a resilver is started. -.RE - -.sp -.ne 2 -.na -\fBresilver.finish\fR -.ad -.RS 12n +.It Sy resilver.finish Issued when the running resilver have finished. -.RE - -.sp -.ne 2 -.na -\fBscrub.start\fR -.ad -.RS 12n +.It Sy scrub.start Issued when a scrub is started on a pool. -.RE - -.sp -.ne 2 -.na -\fBscrub.finish\fR -.ad -.RS 12n +.It Sy scrub.finish Issued when a pool has finished scrubbing. -.RE - -.sp -.ne 2 -.na -\fBscrub.abort\fR -.ad -.RS 12n +.It Sy scrub.abort Issued when a scrub is aborted on a pool. -.RE - -.sp -.ne 2 -.na -\fBscrub.resume\fR -.ad -.RS 12n +.It Sy scrub.resume Issued when a scrub is resumed on a pool. -.RE - -.sp -.ne 2 -.na -\fBscrub.paused\fR -.ad -.RS 12n +.It Sy scrub.paused Issued when a scrub is paused on a pool. -.RE - -.sp -.ne 2 -.na -\fBbootfs.vdev.attach\fR -.ad -.RS 12n -.RE - -.SS "PAYLOADS" -.sp -.LP +.It Sy bootfs.vdev.attach +.El +. +.Sh PAYLOADS This is the payload (data, information) that accompanies an event. -.sp +.Pp For -.BR zed (8), -these are set to uppercase and prefixed with \fBZEVENT_\fR. - -.sp -.ne 2 -.na -\fBpool\fR -.ad -.RS 12n +.Xr zed 8 , +these are set to uppercase and prefixed with +.Sy ZEVENT_ . +.Bl -tag -compact -width "vdev_cksum_errors" +.It Sy pool Pool name. -.RE - -.sp -.ne 2 -.na -\fBpool_failmode\fR -.ad -.RS 12n -Failmode - \fBwait\fR, \fBcontinue\fR or \fBpanic\fR. -See -.BR zpool (8) -(\fIfailmode\fR property) for more information. -.RE - -.sp -.ne 2 -.na -\fBpool_guid\fR -.ad -.RS 12n +.It Sy pool_failmode +Failmode - +.Sy wait , +.Sy continue , +or +.Sy panic . +See the +.Sy failmode +property in +.Xr zpoolprops 8 +for more information. +.It Sy pool_guid The GUID of the pool. -.RE - -.sp -.ne 2 -.na -\fBpool_context\fR -.ad -.RS 12n +.It Sy pool_context The load state for the pool (0=none, 1=open, 2=import, 3=tryimport, 4=recover 5=error). -.RE - -.sp -.ne 2 -.na -\fBvdev_guid\fR -.ad -.RS 12n +.It Sy vdev_guid The GUID of the vdev in question (the vdev failing or operated upon with -\fBzpool clear\fR etc). -.RE - -.sp -.ne 2 -.na -\fBvdev_type\fR -.ad -.RS 12n -Type of vdev - \fBdisk\fR, \fBfile\fR, \fBmirror\fR etc. See -.BR zpool (8) -under \fBVirtual Devices\fR for more information on possible values. -.RE - -.sp -.ne 2 -.na -\fBvdev_path\fR -.ad -.RS 12n -Full path of the vdev, including any \fI-partX\fR. -.RE - -.sp -.ne 2 -.na -\fBvdev_devid\fR -.ad -.RS 12n +.Nm zpool Cm clear , +etc.). +.It Sy vdev_type +Type of vdev - +.Sy disk , +.Sy file , +.Sy mirror , +etc. +See the +.Sy Virtual Devices +section of +.Xr zpoolconcepts 8 +for more information on possible values. +.It Sy vdev_path +Full path of the vdev, including any +.Em -partX . +.It Sy vdev_devid ID of vdev (if any). -.RE - -.sp -.ne 2 -.na -\fBvdev_fru\fR -.ad -.RS 12n +.It Sy vdev_fru Physical FRU location. -.RE - -.sp -.ne 2 -.na -\fBvdev_state\fR -.ad -.RS 12n +.It Sy vdev_state State of vdev (0=uninitialized, 1=closed, 2=offline, 3=removed, 4=failed to open, 5=faulted, 6=degraded, 7=healthy). -.RE - -.sp -.ne 2 -.na -\fBvdev_ashift\fR -.ad -.RS 12n +.It Sy vdev_ashift The ashift value of the vdev. -.RE - -.sp -.ne 2 -.na -\fBvdev_complete_ts\fR -.ad -.RS 12n -The time the last I/O completed for the specified vdev. -.RE - -.sp -.ne 2 -.na -\fBvdev_delta_ts\fR -.ad -.RS 12n -The time since the last I/O completed for the specified vdev. -.RE - -.sp -.ne 2 -.na -\fBvdev_spare_paths\fR -.ad -.RS 12n -List of spares, including full path and any \fI-partX\fR. -.RE - -.sp -.ne 2 -.na -\fBvdev_spare_guids\fR -.ad -.RS 12n +.It Sy vdev_complete_ts +The time the last I/O request completed for the specified vdev. +.It Sy vdev_delta_ts +The time since the last I/O request completed for the specified vdev. +.It Sy vdev_spare_paths +List of spares, including full path and any +.Em -partX . +.It Sy vdev_spare_guids GUID(s) of spares. -.RE - -.sp -.ne 2 -.na -\fBvdev_read_errors\fR -.ad -.RS 12n +.It Sy vdev_read_errors How many read errors that have been detected on the vdev. -.RE - -.sp -.ne 2 -.na -\fBvdev_write_errors\fR -.ad -.RS 12n +.It Sy vdev_write_errors How many write errors that have been detected on the vdev. -.RE - -.sp -.ne 2 -.na -\fBvdev_cksum_errors\fR -.ad -.RS 12n +.It Sy vdev_cksum_errors How many checksum errors that have been detected on the vdev. -.RE - -.sp -.ne 2 -.na -\fBparent_guid\fR -.ad -.RS 12n +.It Sy parent_guid GUID of the vdev parent. -.RE - -.sp -.ne 2 -.na -\fBparent_type\fR -.ad -.RS 12n -Type of parent. See \fBvdev_type\fR. -.RE - -.sp -.ne 2 -.na -\fBparent_path\fR -.ad -.RS 12n +.It Sy parent_type +Type of parent. +See +.Sy vdev_type . +.It Sy parent_path Path of the vdev parent (if any). -.RE - -.sp -.ne 2 -.na -\fBparent_devid\fR -.ad -.RS 12n +.It Sy parent_devid ID of the vdev parent (if any). -.RE - -.sp -.ne 2 -.na -\fBzio_objset\fR -.ad -.RS 12n -The object set number for a given I/O. -.RE - -.sp -.ne 2 -.na -\fBzio_object\fR -.ad -.RS 12n -The object number for a given I/O. -.RE - -.sp -.ne 2 -.na -\fBzio_level\fR -.ad -.RS 12n -The indirect level for the block. Level 0 is the lowest level and includes -data blocks. Values > 0 indicate metadata blocks at the appropriate level. -.RE - -.sp -.ne 2 -.na -\fBzio_blkid\fR -.ad -.RS 12n -The block ID for a given I/O. -.RE - -.sp -.ne 2 -.na -\fBzio_err\fR -.ad -.RS 12n -The errno for a failure when handling a given I/O. The errno is compatible -with \fBerrno\fR(3) with the value for EBADE (0x34) used to indicate ZFS -checksum error. -.RE - -.sp -.ne 2 -.na -\fBzio_offset\fR -.ad -.RS 12n -The offset in bytes of where to write the I/O for the specified vdev. -.RE - -.sp -.ne 2 -.na -\fBzio_size\fR -.ad -.RS 12n -The size in bytes of the I/O. -.RE - -.sp -.ne 2 -.na -\fBzio_flags\fR -.ad -.RS 12n -The current flags describing how the I/O should be handled. See the -\fBI/O FLAGS\fR section for the full list of I/O flags. -.RE - -.sp -.ne 2 -.na -\fBzio_stage\fR -.ad -.RS 12n -The current stage of the I/O in the pipeline. See the \fBI/O STAGES\fR +.It Sy zio_objset +The object set number for a given I/O request. +.It Sy zio_object +The object number for a given I/O request. +.It Sy zio_level +The indirect level for the block. +Level 0 is the lowest level and includes data blocks. +Values > 0 indicate metadata blocks at the appropriate level. +.It Sy zio_blkid +The block ID for a given I/O request. +.It Sy zio_err +The error number for a failure when handling a given I/O request, +compatible with +.Xr errno 3 +with the value of +.Sy EBADE +used to indicate a ZFS checksum error. +.It Sy zio_offset +The offset in bytes of where to write the I/O request for the specified vdev. +.It Sy zio_size +The size in bytes of the I/O request. +.It Sy zio_flags +The current flags describing how the I/O request should be handled. +See the +.Sy I/O FLAGS +section for the full list of I/O flags. +.It Sy zio_stage +The current stage of the I/O in the pipeline. +See the +.Sy I/O STAGES section for a full list of all the I/O stages. -.RE - -.sp -.ne 2 -.na -\fBzio_pipeline\fR -.ad -.RS 12n -The valid pipeline stages for the I/O. See the \fBI/O STAGES\fR section for a -full list of all the I/O stages. -.RE - -.sp -.ne 2 -.na -\fBzio_delay\fR -.ad -.RS 12n +.It Sy zio_pipeline +The valid pipeline stages for the I/O. +See the +.Sy I/O STAGES +section for a full list of all the I/O stages. +.It Sy zio_delay The time elapsed (in nanoseconds) waiting for the block layer to complete the -I/O. Unlike \fBzio_delta\fR this does not include any vdev queuing time and is +I/O request. +Unlike +.Sy zio_delta , +this does not include any vdev queuing time and is therefore solely a measure of the block layer performance. -.RE - -.sp -.ne 2 -.na -\fBzio_timestamp\fR -.ad -.RS 12n -The time when a given I/O was submitted. -.RE - -.sp -.ne 2 -.na -\fBzio_delta\fR -.ad -.RS 12n -The time required to service a given I/O. -.RE - -.sp -.ne 2 -.na -\fBprev_state\fR -.ad -.RS 12n +.It Sy zio_timestamp +The time when a given I/O request was submitted. +.It Sy zio_delta +The time required to service a given I/O request. +.It Sy prev_state The previous state of the vdev. -.RE - -.sp -.ne 2 -.na -\fBcksum_expected\fR -.ad -.RS 12n +.It Sy cksum_expected The expected checksum value for the block. -.RE - -.sp -.ne 2 -.na -\fBcksum_actual\fR -.ad -.RS 12n +.It Sy cksum_actual The actual checksum value for an errant block. -.RE - -.sp -.ne 2 -.na -\fBcksum_algorithm\fR -.ad -.RS 12n -Checksum algorithm used. See \fBzfs\fR(8) for more information on checksum -algorithms available. -.RE - -.sp -.ne 2 -.na -\fBcksum_byteswap\fR -.ad -.RS 12n +.It Sy cksum_algorithm +Checksum algorithm used. +See +.Xr zfsprops 8 +for more information on the available checksum algorithms. +.It Sy cksum_byteswap Whether or not the data is byteswapped. -.RE - -.sp -.ne 2 -.na -\fBbad_ranges\fR -.ad -.RS 12n -[start, end) pairs of corruption offsets. Offsets are always aligned on a -64-bit boundary, and can include some gaps of non-corruption. -(See \fBbad_ranges_min_gap\fR) -.RE - -.sp -.ne 2 -.na -\fBbad_ranges_min_gap\fR -.ad -.RS 12n -In order to bound the size of the \fBbad_ranges\fR array, gaps of non-corruption -less than or equal to \fBbad_ranges_min_gap\fR bytes have been merged with -adjacent corruption. Always at least 8 bytes, since corruption is detected -on a 64-bit word basis. -.RE - -.sp -.ne 2 -.na -\fBbad_range_sets\fR -.ad -.RS 12n -This array has one element per range in \fBbad_ranges\fR. Each element contains +.It Sy bad_ranges +.No [\& Ns Ar start , end ) +pairs of corruption offsets. +Offsets are always aligned on a 64-bit boundary, +and can include some gaps of non-corruption. +(See +.Sy bad_ranges_min_gap ) +.It Sy bad_ranges_min_gap +In order to bound the size of the +.Sy bad_ranges +array, gaps of non-corruption +less than or equal to +.Sy bad_ranges_min_gap +bytes have been merged with +adjacent corruption. +Always at least 8 bytes, since corruption is detected on a 64-bit word basis. +.It Sy bad_range_sets +This array has one element per range in +.Sy bad_ranges . +Each element contains the count of bits in that range which were clear in the good data and set in the bad data. -.RE - -.sp -.ne 2 -.na -\fBbad_range_clears\fR -.ad -.RS 12n -This array has one element per range in \fBbad_ranges\fR. Each element contains +.It Sy bad_range_clears +This array has one element per range in +.Sy bad_ranges . +Each element contains the count of bits for that range which were set in the good data and clear in the bad data. -.RE - -.sp -.ne 2 -.na -\fBbad_set_bits\fR -.ad -.RS 12n -If this field exists, it is an array of: (bad data & ~(good data)); that is, -the bits set in the bad data which are cleared in the good data. Each element -corresponds a byte whose offset is in a range in \fBbad_ranges\fR, and the -array is ordered by offset. Thus, the first element is the first byte in the -first \fBbad_ranges\fR range, and the last element is the last byte in the last -\fBbad_ranges\fR range. -.RE - -.sp -.ne 2 -.na -\fBbad_cleared_bits\fR -.ad -.RS 12n -Like \fBbad_set_bits\fR, but contains: (good data & ~(bad data)); that is, -the bits set in the good data which are cleared in the bad data. -.RE - -.sp -.ne 2 -.na -\fBbad_set_histogram\fR -.ad -.RS 12n -If this field exists, it is an array of counters. Each entry counts bits set -in a particular bit of a big-endian uint64 type. The first entry counts bits +.It Sy bad_set_bits +If this field exists, it is an array of +.Pq Ar bad data No & ~( Ns Ar good data ) ; +that is, the bits set in the bad data which are cleared in the good data. +Each element corresponds a byte whose offset is in a range in +.Sy bad_ranges , +and the array is ordered by offset. +Thus, the first element is the first byte in the first +.Sy bad_ranges +range, and the last element is the last byte in the last +.Sy bad_ranges +range. +.It Sy bad_cleared_bits +Like +.Sy bad_set_bits , +but contains +.Pq Ar good data No & ~( Ns Ar bad data ) ; +that is, the bits set in the good data which are cleared in the bad data. +.It Sy bad_set_histogram +If this field exists, it is an array of counters. +Each entry counts bits set in a particular bit of a big-endian uint64 type. +The first entry counts bits set in the high-order bit of the first byte, the 9th byte, etc, and the last entry counts bits set of the low-order bit of the 8th byte, the 16th byte, etc. This information is useful for observing a stuck bit in a parallel data path, such as IDE or parallel SCSI. -.RE - -.sp -.ne 2 -.na -\fBbad_cleared_histogram\fR -.ad -.RS 12n -If this field exists, it is an array of counters. Each entry counts bit clears -in a particular bit of a big-endian uint64 type. The first entry counts bits +.It Sy bad_cleared_histogram +If this field exists, it is an array of counters. +Each entry counts bit clears in a particular bit of a big-endian uint64 type. +The first entry counts bits clears of the high-order bit of the first byte, the 9th byte, etc, and the -last entry counts clears of the low-order bit of the 8th byte, the 16th byte, -etc. This information is useful for observing a stuck bit in a parallel data +last entry counts clears of the low-order bit of the 8th byte, the 16th byte, etc. +This information is useful for observing a stuck bit in a parallel data path, such as IDE or parallel SCSI. -.RE - -.SS "I/O STAGES" -.sp -.LP -The ZFS I/O pipeline is comprised of various stages which are defined -below. The individual stages are used to construct these basic I/O -operations: Read, Write, Free, Claim, and Ioctl. These stages may be -set on an event to describe the life cycle of a given I/O. - +.El +. +.Sh I/O STAGES +The ZFS I/O pipeline is comprised of various stages which are defined below. +The individual stages are used to construct these basic I/O +operations: Read, Write, Free, Claim, and Ioctl. +These stages may be +set on an event to describe the life cycle of a given I/O request. +.Pp .TS tab(:); l l l . @@ -913,14 +396,14 @@ ZIO_STAGE_CHECKSUM_VERIFY:0x00800000:R---- ZIO_STAGE_DONE:0x01000000:RWFCI .TE - -.SS "I/O FLAGS" -.sp -.LP -Every I/O in the pipeline contains a set of flags which describe its -function and are used to govern its behavior. These flags will be set -in an event as an \fBzio_flags\fR payload entry. - +. +.Sh I/O FLAGS +Every I/O request in the pipeline contains a set of flags which describe its +function and are used to govern its behavior. +These flags will be set in an event as a +.Sy zio_flags +payload entry. +.Pp .TS tab(:); l l . diff --git a/sys/contrib/openzfs/man/man5/zfs-module-parameters.5 b/sys/contrib/openzfs/man/man5/zfs-module-parameters.5 index 672afefd2bc..6dbf2749f3b 100644 --- a/sys/contrib/openzfs/man/man5/zfs-module-parameters.5 +++ b/sys/contrib/openzfs/man/man5/zfs-module-parameters.5 @@ -1,4 +1,4 @@ -'\" te +.\" .\" Copyright (c) 2013 by Turbo Fredriksson . All rights reserved. .\" Copyright (c) 2019, 2021 by Delphix. All rights reserved. .\" Copyright (c) 2019 Datto Inc. @@ -14,1730 +14,959 @@ .\" CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your .\" own identifying information: .\" Portions Copyright [yyyy] [name of copyright owner] -.TH ZFS-MODULE-PARAMETERS 5 "Aug 24, 2020" OpenZFS -.SH NAME -zfs\-module\-parameters \- ZFS module parameters -.SH DESCRIPTION -.sp -.LP -Description of the different parameters to the ZFS module. - -.SS "Module parameters" -.sp -.LP - -.sp -.ne 2 -.na -\fBdbuf_cache_max_bytes\fR (ulong) -.ad -.RS 12n -Maximum size in bytes of the dbuf cache. The target size is determined by the -MIN versus \fB1/2^dbuf_cache_shift\fR (1/32) of the target ARC size. The -behavior of the dbuf cache and its associated settings can be observed via the -\fB/proc/spl/kstat/zfs/dbufstats\fR kstat. -.sp -Default value: \fBULONG_MAX\fR. -.RE - -.sp -.ne 2 -.na -\fBdbuf_metadata_cache_max_bytes\fR (ulong) -.ad -.RS 12n -Maximum size in bytes of the metadata dbuf cache. The target size is -determined by the MIN versus \fB1/2^dbuf_metadata_cache_shift\fR (1/64) of the -target ARC size. The behavior of the metadata dbuf cache and its associated -settings can be observed via the \fB/proc/spl/kstat/zfs/dbufstats\fR kstat. -.sp -Default value: \fBULONG_MAX\fR. -.RE - -.sp -.ne 2 -.na -\fBdbuf_cache_hiwater_pct\fR (uint) -.ad -.RS 12n -The percentage over \fBdbuf_cache_max_bytes\fR when dbufs must be evicted -directly. -.sp -Default value: \fB10\fR%. -.RE - -.sp -.ne 2 -.na -\fBdbuf_cache_lowater_pct\fR (uint) -.ad -.RS 12n -The percentage below \fBdbuf_cache_max_bytes\fR when the evict thread stops -evicting dbufs. -.sp -Default value: \fB10\fR%. -.RE - -.sp -.ne 2 -.na -\fBdbuf_cache_shift\fR (int) -.ad -.RS 12n -Set the size of the dbuf cache, \fBdbuf_cache_max_bytes\fR, to a log2 fraction +.\" +.Dd June 1, 2021 +.Dt ZFS-MODULE-PARAMETERS 5 +.Os +. +.Sh NAME +.Nm zfs-module-parameters +.Nd parameters of the ZFS kernel module +. +.Sh DESCRIPTION +.Bl -tag -width Ds +.It Sy dbuf_cache_max_bytes Ns = Ns Sy ULONG_MAX Ns B Pq ulong +Maximum size in bytes of the dbuf cache. +The target size is determined by the MIN versus +.No 1/2^ Ns Sy dbuf_cache_shift Pq 1/32nd of the target ARC size. -.sp -Default value: \fB5\fR. -.RE - -.sp -.ne 2 -.na -\fBdbuf_metadata_cache_shift\fR (int) -.ad -.RS 12n -Set the size of the dbuf metadata cache, \fBdbuf_metadata_cache_max_bytes\fR, +The behavior of the dbuf cache and its associated settings +can be observed via the +.Pa /proc/spl/kstat/zfs/dbufstats +kstat. +. +.It Sy dbuf_metadata_cache_max_bytes Ns = Ns Sy ULONG_MAX Ns B Pq ulong +Maximum size in bytes of the metadata dbuf cache. +The target size is determined by the MIN versus +.No 1/2^ Ns Sy dbuf_metadata_cache_shift Pq 1/64th +of the target ARC size. +The behavior of the metadata dbuf cache and its associated settings +can be observed via the +.Pa /proc/spl/kstat/zfs/dbufstats +kstat. +. +.It Sy dbuf_cache_hiwater_pct Ns = Ns Sy 10 Ns % Pq uint +The percentage over +.Sy dbuf_cache_max_bytes +when dbufs must be evicted directly. +. +.It Sy dbuf_cache_lowater_pct Ns = Ns Sy 10 Ns % Pq uint +The percentage below +.Sy dbuf_cache_max_bytes +when the evict thread stops evicting dbufs. +. +.It Sy dbuf_cache_shift Ns = Ns Sy 5 Pq int +Set the size of the dbuf cache +.Pq Sy dbuf_cache_max_bytes to a log2 fraction of the target ARC size. -.sp -Default value: \fB6\fR. -.RE - -.sp -.ne 2 -.na -\fBdmu_object_alloc_chunk_shift\fR (int) -.ad -.RS 12n -dnode slots allocated in a single operation as a power of 2. The default value -minimizes lock contention for the bulk operation performed. -.sp -Default value: \fB7\fR (128). -.RE - -.sp -.ne 2 -.na -\fBdmu_prefetch_max\fR (int) -.ad -.RS 12n -Limit the amount we can prefetch with one call to this amount (in bytes). +. +.It Sy dbuf_metadata_cache_shift Ns = Ns Sy 6 Pq int +Set the size of the dbuf metadata cache +.Pq Sy dbuf_metadata_cache_max_bytes +to a log2 fraction of the target ARC size. +. +.It Sy dmu_object_alloc_chunk_shift Ns = Ns Sy 7 Po 128 Pc Pq int +dnode slots allocated in a single operation as a power of 2. +The default value minimizes lock contention for the bulk operation performed. +. +.It Sy dmu_prefetch_max Ns = Ns Sy 134217728 Ns B Po 128MB Pc Pq int +Limit the amount we can prefetch with one call to this amount in bytes. This helps to limit the amount of memory that can be used by prefetching. -.sp -Default value: \fB134,217,728\fR (128MB). -.RE - -.sp -.ne 2 -.na -\fBignore_hole_birth\fR (int) -.ad -.RS 12n -This is an alias for \fBsend_holes_without_birth_time\fR. -.RE - -.sp -.ne 2 -.na -\fBl2arc_feed_again\fR (int) -.ad -.RS 12n -Turbo L2ARC warm-up. When the L2ARC is cold the fill interval will be set as -fast as possible. -.sp -Use \fB1\fR for yes (default) and \fB0\fR to disable. -.RE - -.sp -.ne 2 -.na -\fBl2arc_feed_min_ms\fR (ulong) -.ad -.RS 12n -Min feed interval in milliseconds. Requires \fBl2arc_feed_again=1\fR and only -applicable in related situations. -.sp -Default value: \fB200\fR. -.RE - -.sp -.ne 2 -.na -\fBl2arc_feed_secs\fR (ulong) -.ad -.RS 12n -Seconds between L2ARC writing -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBl2arc_headroom\fR (ulong) -.ad -.RS 12n -How far through the ARC lists to search for L2ARC cacheable content, expressed -as a multiplier of \fBl2arc_write_max\fR. -ARC persistence across reboots can be achieved with persistent L2ARC by setting -this parameter to \fB0\fR allowing the full length of ARC lists to be searched -for cacheable content. -.sp -Default value: \fB2\fR. -.RE - -.sp -.ne 2 -.na -\fBl2arc_headroom_boost\fR (ulong) -.ad -.RS 12n -Scales \fBl2arc_headroom\fR by this percentage when L2ARC contents are being -successfully compressed before writing. A value of \fB100\fR disables this -feature. -.sp -Default value: \fB200\fR%. -.RE - -.sp -.ne 2 -.na -\fBl2arc_mfuonly\fR (int) -.ad -.RS 12n +. +.It Sy ignore_hole_birth Pq int +Alias for +.Sy send_holes_without_birth_time . +. +.It Sy l2arc_feed_again Ns = Ns Sy 1 Ns | Ns 0 Pq int +Turbo L2ARC warm-up. +When the L2ARC is cold the fill interval will be set as fast as possible. +. +.It Sy l2arc_feed_min_ms Ns = Ns Sy 200 Pq ulong +Min feed interval in milliseconds. +Requires +.Sy l2arc_feed_again Ns = Ns Ar 1 +and only applicable in related situations. +. +.It Sy l2arc_feed_secs Ns = Ns Sy 1 Pq ulong +Seconds between L2ARC writing. +. +.It Sy l2arc_headroom Ns = Ns Sy 2 Pq ulong +How far through the ARC lists to search for L2ARC cacheable content, +expressed as a multiplier of +.Sy l2arc_write_max . +ARC persistence across reboots can be achieved with persistent L2ARC +by setting this parameter to +.Sy 0 , +allowing the full length of ARC lists to be searched for cacheable content. +. +.It Sy l2arc_headroom_boost Ns = Ns Sy 200 Ns % Pq ulong +Scales +.Sy l2arc_headroom +by this percentage when L2ARC contents are being successfully compressed +before writing. +A value of +.Sy 100 +disables this feature. +. +.It Sy l2arc_mfuonly Ns = Ns Sy 0 Ns | Ns 1 Pq int Controls whether only MFU metadata and data are cached from ARC into L2ARC. This may be desired to avoid wasting space on L2ARC when reading/writing large -amounts of data that are not expected to be accessed more than once. The -default is \fB0\fR, meaning both MRU and MFU data and metadata are cached. -When turning off (\fB0\fR) this feature some MRU buffers will still be present -in ARC and eventually cached on L2ARC. If \fBl2arc_noprefetch\fR is set to 0, +amounts of data that are not expected to be accessed more than once. +.Pp +The default is off, +meaning both MRU and MFU data and metadata are cached. +When turning off this feature, some MRU buffers will still be present +in ARC and eventually cached on L2ARC. +.No If Sy l2arc_noprefetch Ns = Ns Sy 0 , some prefetched buffers will be cached to L2ARC, and those might later -transition to MRU, in which case the \fBl2arc_mru_asize\fR arcstat will not -be 0. Regardless of \fBl2arc_noprefetch\fR, some MFU buffers might be evicted -from ARC, accessed later on as prefetches and transition to MRU as prefetches. -If accessed again they are counted as MRU and the \fBl2arc_mru_asize\fR arcstat -will not be 0. The ARC status of L2ARC buffers when they were first cached in -L2ARC can be seen in the \fBl2arc_mru_asize\fR, \fBl2arc_mfu_asize\fR and -\fBl2arc_prefetch_asize\fR arcstats when importing the pool or onlining a cache -device if persistent L2ARC is enabled. The \fBevicted_l2_eligible_mru\fR +transition to MRU, in which case the +.Sy l2arc_mru_asize No arcstat will not be Sy 0 . +.Pp +Regardless of +.Sy l2arc_noprefetch , +some MFU buffers might be evicted from ARC, +accessed later on as prefetches and transition to MRU as prefetches. +If accessed again they are counted as MRU and the +.Sy l2arc_mru_asize No arcstat will not be Sy 0 . +.Pp +The ARC status of L2ARC buffers when they were first cached in +L2ARC can be seen in the +.Sy l2arc_mru_asize , Sy l2arc_mfu_asize , No and Sy l2arc_prefetch_asize +arcstats when importing the pool or onlining a cache +device if persistent L2ARC is enabled. +.Pp +The +.Sy evict_l2_eligible_mru arcstat does not take into account if this option is enabled as the information -provided by the evicted_l2_eligible_* arcstats can be used to decide if -toggling this option is appropriate for the current workload. -.sp -Use \fB0\fR for no (default) and \fB1\fR for yes. -.RE - -.sp -.ne 2 -.na -\fBl2arc_meta_percent\fR (int) -.ad -.RS 12n +provided by the +.Sy evict_l2_eligible_m[rf]u +arcstats can be used to decide if toggling this option is appropriate +for the current workload. +. +.It Sy l2arc_meta_percent Ns = Ns Sy 33 Ns % Pq int Percent of ARC size allowed for L2ARC-only headers. -Since L2ARC buffers are not evicted on memory pressure, too large amount of -headers on system with irrationaly large L2ARC can render it slow or unusable. -This parameter limits L2ARC writes and rebuild to achieve it. -.sp -Default value: \fB33\fR%. -.RE - -.sp -.ne 2 -.na -\fBl2arc_trim_ahead\fR (ulong) -.ad -.RS 12n -Trims ahead of the current write size (\fBl2arc_write_max\fR) on L2ARC devices -by this percentage of write size if we have filled the device. If set to -\fB100\fR we TRIM twice the space required to accommodate upcoming writes. A -minimum of 64MB will be trimmed. It also enables TRIM of the whole L2ARC device -upon creation or addition to an existing pool or if the header of the device is -invalid upon importing a pool or onlining a cache device. A value of \fB0\fR +Since L2ARC buffers are not evicted on memory pressure, +too many headers on a system with an irrationally large L2ARC +can render it slow or unusable. +This parameter limits L2ARC writes and rebuilds to achieve the target. +. +.It Sy l2arc_trim_ahead Ns = Ns Sy 0 Ns % Pq ulong +Trims ahead of the current write size +.Pq Sy l2arc_write_max +on L2ARC devices by this percentage of write size if we have filled the device. +If set to +.Sy 100 +we TRIM twice the space required to accommodate upcoming writes. +A minimum of +.Sy 64MB +will be trimmed. +It also enables TRIM of the whole L2ARC device upon creation +or addition to an existing pool or if the header of the device is +invalid upon importing a pool or onlining a cache device. +A value of +.Sy 0 disables TRIM on L2ARC altogether and is the default as it can put significant -stress on the underlying storage devices. This will vary depending of how well -the specific device handles these commands. -.sp -Default value: \fB0\fR%. -.RE - -.sp -.ne 2 -.na -\fBl2arc_noprefetch\fR (int) -.ad -.RS 12n +stress on the underlying storage devices. +This will vary depending of how well the specific device handles these commands. +. +.It Sy l2arc_noprefetch Ns = Ns Sy 1 Ns | Ns 0 Pq int Do not write buffers to L2ARC if they were prefetched but not used by -applications. In case there are prefetched buffers in L2ARC and this option -is later set to \fB1\fR, we do not read the prefetched buffers from L2ARC. -Setting this option to \fB0\fR is useful for caching sequential reads from the -disks to L2ARC and serve those reads from L2ARC later on. This may be beneficial -in case the L2ARC device is significantly faster in sequential reads than the -disks of the pool. -.sp -Use \fB1\fR to disable (default) and \fB0\fR to enable caching/reading -prefetches to/from L2ARC.. -.RE - -.sp -.ne 2 -.na -\fBl2arc_norw\fR (int) -.ad -.RS 12n +applications. +In case there are prefetched buffers in L2ARC and this option +is later set, we do not read the prefetched buffers from L2ARC. +Unsetting this option is useful for caching sequential reads from the +disks to L2ARC and serve those reads from L2ARC later on. +This may be beneficial in case the L2ARC device is significantly faster +in sequential reads than the disks of the pool. +.Pp +Use +.Sy 1 +to disable and +.Sy 0 +to enable caching/reading prefetches to/from L2ARC. +. +.It Sy l2arc_norw Ns = Ns Sy 0 Ns | Ns 1 Pq int No reads during writes. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBl2arc_write_boost\fR (ulong) -.ad -.RS 12n -Cold L2ARC devices will have \fBl2arc_write_max\fR increased by this amount -while they remain cold. -.sp -Default value: \fB8,388,608\fR. -.RE - -.sp -.ne 2 -.na -\fBl2arc_write_max\fR (ulong) -.ad -.RS 12n +. +.It Sy l2arc_write_boost Ns = Ns Sy 8388608 Ns B Po 8MB Pc Pq ulong +Cold L2ARC devices will have +.Sy l2arc_write_max +increased by this amount while they remain cold. +. +.It Sy l2arc_write_max Ns = Ns Sy 8388608 Ns B Po 8MB Pc Pq ulong Max write bytes per interval. -.sp -Default value: \fB8,388,608\fR. -.RE - -.sp -.ne 2 -.na -\fBl2arc_rebuild_enabled\fR (int) -.ad -.RS 12n -Rebuild the L2ARC when importing a pool (persistent L2ARC). This can be -disabled if there are problems importing a pool or attaching an L2ARC device -(e.g. the L2ARC device is slow in reading stored log metadata, or the metadata +. +.It Sy l2arc_rebuild_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int +Rebuild the L2ARC when importing a pool (persistent L2ARC). +This can be disabled if there are problems importing a pool +or attaching an L2ARC device (e.g. the L2ARC device is slow +in reading stored log metadata, or the metadata has become somehow fragmented/unusable). -.sp -Use \fB1\fR for yes (default) and \fB0\fR for no. -.RE - -.sp -.ne 2 -.na -\fBl2arc_rebuild_blocks_min_l2size\fR (ulong) -.ad -.RS 12n -Min size (in bytes) of an L2ARC device required in order to write log blocks -in it. The log blocks are used upon importing the pool to rebuild -the L2ARC (persistent L2ARC). Rationale: for L2ARC devices less than 1GB, the -amount of data l2arc_evict() evicts is significant compared to the amount of -restored L2ARC data. In this case do not write log blocks in L2ARC in order not -to waste space. -.sp -Default value: \fB1,073,741,824\fR (1GB). -.RE - -.sp -.ne 2 -.na -\fBmetaslab_aliquot\fR (ulong) -.ad -.RS 12n -Metaslab granularity, in bytes. This is roughly similar to what would be -referred to as the "stripe size" in traditional RAID arrays. In normal -operation, ZFS will try to write this amount of data to a top-level vdev -before moving on to the next one. -.sp -Default value: \fB524,288\fR. -.RE - -.sp -.ne 2 -.na -\fBmetaslab_bias_enabled\fR (int) -.ad -.RS 12n -Enable metaslab group biasing based on its vdev's over- or under-utilization +. +.It Sy l2arc_rebuild_blocks_min_l2size Ns = Ns Sy 1073741824 Ns B Po 1GB Pc Pq ulong +Mininum size of an L2ARC device required in order to write log blocks in it. +The log blocks are used upon importing the pool to rebuild the persistent L2ARC. +.Pp +For L2ARC devices less than 1GB, the amount of data +.Fn l2arc_evict +evicts is significant compared to the amount of restored L2ARC data. +In this case, do not write log blocks in L2ARC in order not to waste space. +. +.It Sy metaslab_aliquot Ns = Ns Sy 524288 Ns B Po 512kB Pc Pq ulong +Metaslab granularity, in bytes. +This is roughly similar to what would be referred to as the "stripe size" +in traditional RAID arrays. +In normal operation, ZFS will try to write this amount of data +to a top-level vdev before moving on to the next one. +. +.It Sy metaslab_bias_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int +Enable metaslab group biasing based on their vdevs' over- or under-utilization relative to the pool. -.sp -Use \fB1\fR for yes (default) and \fB0\fR for no. -.RE - -.sp -.ne 2 -.na -\fBmetaslab_force_ganging\fR (ulong) -.ad -.RS 12n -Make some blocks above a certain size be gang blocks. This option is used -by the test suite to facilitate testing. -.sp -Default value: \fB16,777,217\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_history_output_max\fR (int) -.ad -.RS 12n -When attempting to log the output nvlist of an ioctl in the on-disk history, the -output will not be stored if it is larger than size (in bytes). This must be -less then DMU_MAX_ACCESS (64MB). This applies primarily to -zfs_ioc_channel_program(). -.sp -Default value: \fB1MB\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_keep_log_spacemaps_at_export\fR (int) -.ad -.RS 12n +. +.It Sy metaslab_force_ganging Ns = Ns Sy 16777217 Ns B Ns B Po 16MB + 1B Pc Pq ulong +Make some blocks above a certain size be gang blocks. +This option is used by the test suite to facilitate testing. +. +.It Sy zfs_history_output_max Ns = Ns Sy 1048576 Ns B Ns B Po 1MB Pc Pq int +When attempting to log an output nvlist of an ioctl in the on-disk history, +the output will not be stored if it is larger than this size (in bytes). +This must be less than +.Sy DMU_MAX_ACCESS Pq 64MB . +This applies primarily to +.Fn zfs_ioc_channel_program Pq cf. Xr zfs-program 8 . +. +.It Sy zfs_keep_log_spacemaps_at_export Ns = Ns Sy 0 Ns | Ns 1 Pq int Prevent log spacemaps from being destroyed during pool exports and destroys. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_metaslab_segment_weight_enabled\fR (int) -.ad -.RS 12n +. +.It Sy zfs_metaslab_segment_weight_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int Enable/disable segment-based metaslab selection. -.sp -Use \fB1\fR for yes (default) and \fB0\fR for no. -.RE - -.sp -.ne 2 -.na -\fBzfs_metaslab_switch_threshold\fR (int) -.ad -.RS 12n +. +.It Sy zfs_metaslab_switch_threshold Ns = Ns Sy 2 Pq int When using segment-based metaslab selection, continue allocating -from the active metaslab until \fBzfs_metaslab_switch_threshold\fR +from the active metaslab until this option's worth of buckets have been exhausted. -.sp -Default value: \fB2\fR. -.RE - -.sp -.ne 2 -.na -\fBmetaslab_debug_load\fR (int) -.ad -.RS 12n +. +.It Sy metaslab_debug_load Ns = Ns Sy 0 Ns | Ns 1 Pq int Load all metaslabs during pool import. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBmetaslab_debug_unload\fR (int) -.ad -.RS 12n +. +.It Sy metaslab_debug_unload Ns = Ns Sy 0 Ns | Ns 1 Pq int Prevent metaslabs from being unloaded. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBmetaslab_fragmentation_factor_enabled\fR (int) -.ad -.RS 12n +. +.It Sy metaslab_fragmentation_factor_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int Enable use of the fragmentation metric in computing metaslab weights. -.sp -Use \fB1\fR for yes (default) and \fB0\fR for no. -.RE - -.sp -.ne 2 -.na -\fBmetaslab_df_max_search\fR (int) -.ad -.RS 12n -Maximum distance to search forward from the last offset. Without this limit, -fragmented pools can see >100,000 iterations and metaslab_block_picker() +. +.It Sy metaslab_df_max_search Ns = Ns Sy 16777216 Ns B Po 16MB Pc Pq int +Maximum distance to search forward from the last offset. +Without this limit, fragmented pools can see +.Em >100`000 +iterations and +.Fn metaslab_block_picker becomes the performance limiting factor on high-performance storage. - -With the default setting of 16MB, we typically see less than 500 iterations, -even with very fragmented, ashift=9 pools. The maximum number of iterations -possible is: \fBmetaslab_df_max_search / (2 * (1< physical sector size on new top-level vdevs. -.sp -Default value: \fBASHIFT_MAX\fR (16). -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_min_auto_ashift\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_vdev_min_auto_ashift Ns = Ns Sy ASHIFT_MIN Po 9 Pc Pq ulong Minimum ashift used when creating new top-level vdevs. -.sp -Default value: \fBASHIFT_MIN\fR (9). -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_min_ms_count\fR (int) -.ad -.RS 12n +. +.It Sy zfs_vdev_min_ms_count Ns = Ns Sy 16 Pq int Minimum number of metaslabs to create in a top-level vdev. -.sp -Default value: \fB16\fR. -.RE - -.sp -.ne 2 -.na -\fBvdev_validate_skip\fR (int) -.ad -.RS 12n -Skip label validation steps during pool import. Changing is not recommended -unless you know what you are doing and are recovering a damaged label. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_ms_count_limit\fR (int) -.ad -.RS 12n +. +.It Sy vdev_validate_skip Ns = Ns Sy 0 Ns | Ns 1 Pq int +Skip label validation steps during pool import. +Changing is not recommended unless you know what you're doing +and are recovering a damaged label. +. +.It Sy zfs_vdev_ms_count_limit Ns = Ns Sy 131072 Po 128k Pc Pq int Practical upper limit of total metaslabs per top-level vdev. -.sp -Default value: \fB131,072\fR. -.RE - -.sp -.ne 2 -.na -\fBmetaslab_preload_enabled\fR (int) -.ad -.RS 12n +. +.It Sy metaslab_preload_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int Enable metaslab group preloading. -.sp -Use \fB1\fR for yes (default) and \fB0\fR for no. -.RE - -.sp -.ne 2 -.na -\fBmetaslab_lba_weighting_enabled\fR (int) -.ad -.RS 12n -Give more weight to metaslabs with lower LBAs, assuming they have -greater bandwidth as is typically the case on a modern constant -angular velocity disk drive. -.sp -Use \fB1\fR for yes (default) and \fB0\fR for no. -.RE - -.sp -.ne 2 -.na -\fBmetaslab_unload_delay\fR (int) -.ad -.RS 12n -After a metaslab is used, we keep it loaded for this many txgs, to attempt to -reduce unnecessary reloading. Note that both this many txgs and -\fBmetaslab_unload_delay_ms\fR milliseconds must pass before unloading will -occur. -.sp -Default value: \fB32\fR. -.RE - -.sp -.ne 2 -.na -\fBmetaslab_unload_delay_ms\fR (int) -.ad -.RS 12n -After a metaslab is used, we keep it loaded for this many milliseconds, to -attempt to reduce unnecessary reloading. Note that both this many -milliseconds and \fBmetaslab_unload_delay\fR txgs must pass before unloading -will occur. -.sp -Default value: \fB600000\fR (ten minutes). -.RE - -.sp -.ne 2 -.na -\fBreference_history\fR (int) -.ad -.RS 12n -Maximum reference holders being tracked when reference_tracking_enable is -active. -.sp -Default value: \fB3\fR. -.RE - -.sp -.ne 2 -.na -\fBreference_tracking_enable\fR (int) -.ad -.RS 12n -Track reference holders to refcount_t objects (debug builds only). -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBsend_holes_without_birth_time\fR (int) -.ad -.RS 12n -When set, the hole_birth optimization will not be used, and all holes will -always be sent on zfs send. This is useful if you suspect your datasets are -affected by a bug in hole_birth. -.sp -Use \fB1\fR for on (default) and \fB0\fR for off. -.RE - -.sp -.ne 2 -.na -\fBspa_config_path\fR (charp) -.ad -.RS 12n -SPA config file -.sp -Default value: \fB/etc/zfs/zpool.cache\fR. -.RE - -.sp -.ne 2 -.na -\fBspa_asize_inflation\fR (int) -.ad -.RS 12n +. +.It Sy metaslab_lba_weighting_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int +Give more weight to metaslabs with lower LBAs, +assuming they have greater bandwidth, +as is typically the case on a modern constant angular velocity disk drive. +. +.It Sy metaslab_unload_delay Ns = Ns Sy 32 Pq int +After a metaslab is used, we keep it loaded for this many TXGs, to attempt to +reduce unnecessary reloading. +Note that both this many TXGs and +.Sy metaslab_unload_delay_ms +milliseconds must pass before unloading will occur. +. +.It Sy metaslab_unload_delay_ms Ns = Ns Sy 600000 Ns ms Po 10min Pc Pq int +After a metaslab is used, we keep it loaded for this many milliseconds, +to attempt to reduce unnecessary reloading. +Note, that both this many milliseconds and +.Sy metaslab_unload_delay +TXGs must pass before unloading will occur. +. +.It Sy reference_history Ns = Ns Sy 3 Pq int +Maximum reference holders being tracked when reference_tracking_enable is active. +. +.It Sy reference_tracking_enable Ns = Ns Sy 0 Ns | Ns 1 Pq int +Track reference holders to +.Sy refcount_t +objects (debug builds only). +. +.It Sy send_holes_without_birth_time Ns = Ns Sy 1 Ns | Ns 0 Pq int +When set, the +.Sy hole_birth +optimization will not be used, and all holes will always be sent during a +.Nm zfs Cm send . +This is useful if you suspect your datasets are affected by a bug in +.Sy hole_birth . +. +.It Sy spa_config_path Ns = Ns Pa /etc/zfs/zpool.cache Pq charp +SPA config file. +. +.It Sy spa_asize_inflation Ns = Ns Sy 24 Pq int Multiplication factor used to estimate actual disk consumption from the -size of data being written. The default value is a worst case estimate, -but lower values may be valid for a given pool depending on its -configuration. Pool administrators who understand the factors involved -may wish to specify a more realistic inflation factor, particularly if -they operate close to quota or capacity limits. -.sp -Default value: \fB24\fR. -.RE - -.sp -.ne 2 -.na -\fBspa_load_print_vdev_tree\fR (int) -.ad -.RS 12n +size of data being written. +The default value is a worst case estimate, +but lower values may be valid for a given pool depending on its configuration. +Pool administrators who understand the factors involved +may wish to specify a more realistic inflation factor, +particularly if they operate close to quota or capacity limits. +. +.It Sy spa_load_print_vdev_tree Ns = Ns Sy 0 Ns | Ns 1 Pq int Whether to print the vdev tree in the debugging message buffer during pool import. -Use 0 to disable and 1 to enable. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBspa_load_verify_data\fR (int) -.ad -.RS 12n -Whether to traverse data blocks during an "extreme rewind" (\fB-X\fR) -import. Use 0 to disable and 1 to enable. - +. +.It Sy spa_load_verify_data Ns = Ns Sy 1 Ns | Ns 0 Pq int +Whether to traverse data blocks during an "extreme rewind" +.Pq Fl X +import. +.Pp An extreme rewind import normally performs a full traversal of all -blocks in the pool for verification. If this parameter is set to 0, -the traversal skips non-metadata blocks. It can be toggled once the +blocks in the pool for verification. +If this parameter is unset, the traversal skips non-metadata blocks. +It can be toggled once the import has started to stop or start the traversal of non-metadata blocks. -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBspa_load_verify_metadata\fR (int) -.ad -.RS 12n -Whether to traverse blocks during an "extreme rewind" (\fB-X\fR) -pool import. Use 0 to disable and 1 to enable. - +. +.It Sy spa_load_verify_metadata Ns = Ns Sy 1 Ns | Ns 0 Pq int +Whether to traverse blocks during an "extreme rewind" +.Pq Fl X +pool import. +.Pp An extreme rewind import normally performs a full traversal of all -blocks in the pool for verification. If this parameter is set to 0, -the traversal is not performed. It can be toggled once the import has -started to stop or start the traversal. -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBspa_load_verify_shift\fR (int) -.ad -.RS 12n +blocks in the pool for verification. +If this parameter is unset, the traversal is not performed. +It can be toggled once the import has started to stop or start the traversal. +. +.It Sy spa_load_verify_shift Ns = Ns Sy 4 Po 1/16th Pc Pq int Sets the maximum number of bytes to consume during pool import to the log2 fraction of the target ARC size. -.sp -Default value: \fB4\fR. -.RE - -.sp -.ne 2 -.na -\fBspa_slop_shift\fR (int) -.ad -.RS 12n -Normally, we don't allow the last 3.2% (1/(2^spa_slop_shift)) of space -in the pool to be consumed. This ensures that we don't run the pool -completely out of space, due to unaccounted changes (e.g. to the MOS). -It also limits the worst-case time to allocate space. If we have -less than this amount of free space, most ZPL operations (e.g. write, -create) will return ENOSPC. -.sp -Default value: \fB5\fR. -.RE - -.sp -.ne 2 -.na -\fBvdev_removal_max_span\fR (int) -.ad -.RS 12n +. +.It Sy spa_slop_shift Ns = Ns Sy 5 Po 1/32nd Pc Pq int +Normally, we don't allow the last +.Sy 3.2% Pq Sy 1/2^spa_slop_shift +of space in the pool to be consumed. +This ensures that we don't run the pool completely out of space, +due to unaccounted changes (e.g. to the MOS). +It also limits the worst-case time to allocate space. +If we have less than this amount of free space, +most ZPL operations (e.g. write, create) will return +.Sy ENOSPC . +. +.It Sy vdev_removal_max_span Ns = Ns Sy 32768 Ns B Po 32kB Pc Pq int During top-level vdev removal, chunks of data are copied from the vdev which may include free space in order to trade bandwidth for IOPS. -This parameter determines the maximum span of free space (in bytes) +This parameter determines the maximum span of free space, in bytes, which will be included as "unnecessary" data in a chunk of copied data. - +.Pp The default value here was chosen to align with -\fBzfs_vdev_read_gap_limit\fR, which is a similar concept when doing +.Sy zfs_vdev_read_gap_limit , +which is a similar concept when doing regular reads (but there's no reason it has to be the same). -.sp -Default value: \fB32,768\fR. -.RE - -.sp -.ne 2 -.na -\fBvdev_file_logical_ashift\fR (ulong) -.ad -.RS 12n +. +.It Sy vdev_file_logical_ashift Ns = Ns Sy 9 Po 512B Pc Pq ulong Logical ashift for file-based devices. -.sp -Default value: \fB9\fR. -.RE - -.sp -.ne 2 -.na -\fBvdev_file_physical_ashift\fR (ulong) -.ad -.RS 12n +. +.It Sy vdev_file_physical_ashift Ns = Ns Sy 9 Po 512B Pc Pq ulong Physical ashift for file-based devices. -.sp -Default value: \fB9\fR. -.RE - -.sp -.ne 2 -.na -\fBzap_iterate_prefetch\fR (int) -.ad -.RS 12n -If this is set, when we start iterating over a ZAP object, zfs will prefetch -the entire object (all leaf blocks). However, this is limited by -\fBdmu_prefetch_max\fR. -.sp -Use \fB1\fR for on (default) and \fB0\fR for off. -.RE - -.sp -.ne 2 -.na -\fBzfetch_array_rd_sz\fR (ulong) -.ad -.RS 12n +. +.It Sy zap_iterate_prefetch Ns = Ns Sy 1 Ns | Ns 0 Pq int +If set, when we start iterating over a ZAP object, +prefetch the entire object (all leaf blocks). +However, this is limited by +.Sy dmu_prefetch_max . +. +.It Sy zfetch_array_rd_sz Ns = Ns Sy 1048576 Ns B Po 1MB Pc Pq ulong If prefetching is enabled, disable prefetching for reads larger than this size. -.sp -Default value: \fB1,048,576\fR. -.RE - -.sp -.ne 2 -.na -\fBzfetch_max_distance\fR (uint) -.ad -.RS 12n +. +.It Sy zfetch_max_distance Ns = Ns Sy 8388608 Ns B Po 8MB Pc Pq uint Max bytes to prefetch per stream. -.sp -Default value: \fB8,388,608\fR (8MB). -.RE - -.sp -.ne 2 -.na -\fBzfetch_max_idistance\fR (uint) -.ad -.RS 12n +. +.It Sy zfetch_max_idistance Ns = Ns Sy 67108864 Ns B Po 64MB Pc Pq uint Max bytes to prefetch indirects for per stream. -.sp -Default vaule: \fB67,108,864\fR (64MB). -.RE - -.sp -.ne 2 -.na -\fBzfetch_max_streams\fR (uint) -.ad -.RS 12n +. +.It Sy zfetch_max_streams Ns = Ns Sy 8 Pq uint Max number of streams per zfetch (prefetch streams per file). -.sp -Default value: \fB8\fR. -.RE - -.sp -.ne 2 -.na -\fBzfetch_min_sec_reap\fR (uint) -.ad -.RS 12n +. +.It Sy zfetch_min_sec_reap Ns = Ns Sy 2 Pq uint Min time before an active prefetch stream can be reclaimed -.sp -Default value: \fB2\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_abd_scatter_enabled\fR (int) -.ad -.RS 12n +. +.It Sy zfs_abd_scatter_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int Enables ARC from using scatter/gather lists and forces all allocations to be -linear in kernel memory. Disabling can improve performance in some code paths +linear in kernel memory. +Disabling can improve performance in some code paths at the expense of fragmented kernel memory. -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_abd_scatter_max_order\fR (iunt) -.ad -.RS 12n +. +.It Sy zfs_abd_scatter_max_order Ns = Ns Sy MAX_ORDER-1 Pq uint Maximum number of consecutive memory pages allocated in a single block for -scatter/gather lists. Default value is specified by the kernel itself. -.sp -Default value: \fB10\fR at the time of this writing. -.RE - -.sp -.ne 2 -.na -\fBzfs_abd_scatter_min_size\fR (uint) -.ad -.RS 12n -This is the minimum allocation size that will use scatter (page-based) -ABD's. Smaller allocations will use linear ABD's. -.sp -Default value: \fB1536\fR (512B and 1KB allocations will be linear). -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_dnode_limit\fR (ulong) -.ad -.RS 12n +scatter/gather lists. +.Pp +The value of +.Sy MAX_ORDER +depends on kernel configuration. +. +.It Sy zfs_abd_scatter_min_size Ns = Ns Sy 1536 Ns B Po 1.5kB Pc Pq uint +This is the minimum allocation size that will use scatter (page-based) ABDs. +Smaller allocations will use linear ABDs. +. +.It Sy zfs_arc_dnode_limit Ns = Ns Sy 0 Ns B Pq ulong When the number of bytes consumed by dnodes in the ARC exceeds this number of -bytes, try to unpin some of it in response to demand for non-metadata. This -value acts as a ceiling to the amount of dnode metadata, and defaults to 0 which -indicates that a percent which is based on \fBzfs_arc_dnode_limit_percent\fR of -the ARC meta buffers that may be used for dnodes. - -See also \fBzfs_arc_meta_prune\fR which serves a similar purpose but is used -when the amount of metadata in the ARC exceeds \fBzfs_arc_meta_limit\fR rather -than in response to overall demand for non-metadata. - -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_dnode_limit_percent\fR (ulong) -.ad -.RS 12n +bytes, try to unpin some of it in response to demand for non-metadata. +This value acts as a ceiling to the amount of dnode metadata, and defaults to +.Sy 0 , +which indicates that a percent which is based on +.Sy zfs_arc_dnode_limit_percent +of the ARC meta buffers that may be used for dnodes. +.Pp +Also see +.Sy zfs_arc_meta_prune +which serves a similar purpose but is used +when the amount of metadata in the ARC exceeds +.Sy zfs_arc_meta_limit +rather than in response to overall demand for non-metadata. +. +.It Sy zfs_arc_dnode_limit_percent Ns = Ns Sy 10 Ns % Pq ulong Percentage that can be consumed by dnodes of ARC meta buffers. -.sp -See also \fBzfs_arc_dnode_limit\fR which serves a similar purpose but has a -higher priority if set to nonzero value. -.sp -Default value: \fB10\fR%. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_dnode_reduce_percent\fR (ulong) -.ad -.RS 12n +.Pp +See also +.Sy zfs_arc_dnode_limit , +which serves a similar purpose but has a higher priority if nonzero. +. +.It Sy zfs_arc_dnode_reduce_percent Ns = Ns Sy 10 Ns % Pq ulong Percentage of ARC dnodes to try to scan in response to demand for non-metadata -when the number of bytes consumed by dnodes exceeds \fBzfs_arc_dnode_limit\fR. - -.sp -Default value: \fB10\fR% of the number of dnodes in the ARC. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_average_blocksize\fR (int) -.ad -.RS 12n +when the number of bytes consumed by dnodes exceeds +.Sy zfs_arc_dnode_limit . +. +.It Sy zfs_arc_average_blocksize Ns = Ns Sy 8192 Ns B Po 8kB Pc Pq int The ARC's buffer hash table is sized based on the assumption of an average -block size of \fBzfs_arc_average_blocksize\fR (default 8K). This works out -to roughly 1MB of hash table per 1GB of physical memory with 8-byte pointers. -For configurations with a known larger average block size this value can be -increased to reduce the memory footprint. - -.sp -Default value: \fB8192\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_eviction_pct\fR (int) -.ad -.RS 12n -When \fBarc_is_overflowing()\fR, \fBarc_get_data_impl()\fR waits for this -percent of the requested amount of data to be evicted. For example, by -default for every 2KB that's evicted, 1KB of it may be "reused" by a new -allocation. Since this is above 100%, it ensures that progress is made -towards getting \fBarc_size\fR under \fBarc_c\fR. Since this is finite, it -ensures that allocations can still happen, even during the potentially long -time that \fBarc_size\fR is more than \fBarc_c\fR. -.sp -Default value: \fB200\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_evict_batch_limit\fR (int) -.ad -.RS 12n +block size of this value. +This works out to roughly 1MB of hash table per 1GB of physical memory +with 8-byte pointers. +For configurations with a known larger average block size, +this value can be increased to reduce the memory footprint. +. +.It Sy zfs_arc_eviction_pct Ns = Ns Sy 200 Ns % Pq int +When +.Fn arc_is_overflowing , +.Fn arc_get_data_impl +waits for this percent of the requested amount of data to be evicted. +For example, by default, for every +.Em 2kB +that's evicted, +.Em 1kB +of it may be "reused" by a new allocation. +Since this is above +.Sy 100 Ns % , +it ensures that progress is made towards getting +.Sy arc_size No under Sy arc_c . +Since this is finite, it ensures that allocations can still happen, +even during the potentially long time that +.Sy arc_size No is more than Sy arc_c . +. +.It Sy zfs_arc_evict_batch_limit Ns = Ns Sy 10 Pq int Number ARC headers to evict per sub-list before proceeding to another sub-list. This batch-style operation prevents entire sub-lists from being evicted at once but comes at a cost of additional unlocking and locking. -.sp -Default value: \fB10\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_grow_retry\fR (int) -.ad -.RS 12n -If set to a non zero value, it will replace the arc_grow_retry value with this value. -The arc_grow_retry value (default 5) is the number of seconds the ARC will wait before +. +.It Sy zfs_arc_grow_retry Ns = Ns Sy 0 Ns s Pq int +If set to a non zero value, it will replace the +.Sy arc_grow_retry +value with this value. +The +.Sy arc_grow_retry +.No value Pq default Sy 5 Ns s +is the number of seconds the ARC will wait before trying to resume growth after a memory pressure event. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_lotsfree_percent\fR (int) -.ad -.RS 12n +. +.It Sy zfs_arc_lotsfree_percent Ns = Ns Sy 10 Ns % Pq int Throttle I/O when free system memory drops below this percentage of total -system memory. Setting this value to 0 will disable the throttle. -.sp -Default value: \fB10\fR%. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_max\fR (ulong) -.ad -.RS 12n -Max size of ARC in bytes. If set to 0 then the max size of ARC is determined -by the amount of system memory installed. For Linux, 1/2 of system memory will -be used as the limit. For FreeBSD, the larger of all system memory - 1GB or -5/8 of system memory will be used as the limit. This value must be at least -67108864 (64 megabytes). -.sp -This value can be changed dynamically with some caveats. It cannot be set back -to 0 while running and reducing it below the current ARC size will not cause +system memory. +Setting this value to +.Sy 0 +will disable the throttle. +. +.It Sy zfs_arc_max Ns = Ns Sy 0 Ns B Pq ulong +Max size of ARC in bytes. +If +.Sy 0 , +then the max size of ARC is determined by the amount of system memory installed. +Under Linux, half of system memory will be used as the limit. +Under +.Fx , +the larger of +.Sy all_system_memory - 1GB No and Sy 5/8 * all_system_memory +will be used as the limit. +This value must be at least +.Sy 67108864 Ns B Pq 64MB . +.Pp +This value can be changed dynamically, with some caveats. +It cannot be set back to +.Sy 0 +while running, and reducing it below the current ARC size will not cause the ARC to shrink without memory pressure to induce shrinking. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_meta_adjust_restarts\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_arc_meta_adjust_restarts Ns = Ns Sy 4096 Pq ulong The number of restart passes to make while scanning the ARC attempting -the free buffers in order to stay below the \fBzfs_arc_meta_limit\fR. +the free buffers in order to stay below the +.Sy fs_arc_meta_limit . This value should not need to be tuned but is available to facilitate performance analysis. -.sp -Default value: \fB4096\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_meta_limit\fR (ulong) -.ad -.RS 12n -The maximum allowed size in bytes that meta data buffers are allowed to -consume in the ARC. When this limit is reached meta data buffers will -be reclaimed even if the overall arc_c_max has not been reached. This -value defaults to 0 which indicates that a percent which is based on -\fBzfs_arc_meta_limit_percent\fR of the ARC may be used for meta data. -.sp -This value my be changed dynamically except that it cannot be set back to 0 -for a specific percent of the ARC; it must be set to an explicit value. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_meta_limit_percent\fR (ulong) -.ad -.RS 12n -Percentage of ARC buffers that can be used for meta data. - -See also \fBzfs_arc_meta_limit\fR which serves a similar purpose but has a -higher priority if set to nonzero value. - -.sp -Default value: \fB75\fR%. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_meta_min\fR (ulong) -.ad -.RS 12n -The minimum allowed size in bytes that meta data buffers may consume in -the ARC. This value defaults to 0 which disables a floor on the amount -of the ARC devoted meta data. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_meta_prune\fR (int) -.ad -.RS 12n +. +.It Sy zfs_arc_meta_limit Ns = Ns Sy 0 Ns B Pq ulong +The maximum allowed size in bytes that metadata buffers are allowed to +consume in the ARC. +When this limit is reached, metadata buffers will be reclaimed, +even if the overall +.Sy arc_c_max +has not been reached. +It defaults to +.Sy 0 , +which indicates that a percentage based on +.Sy zfs_arc_meta_limit_percent +of the ARC may be used for metadata. +.Pp +This value my be changed dynamically, except that must be set to an explicit value +.Pq cannot be set back to Sy 0 . +. +.It Sy zfs_arc_meta_limit_percent Ns = Ns Sy 75 Ns % Pq ulong +Percentage of ARC buffers that can be used for metadata. +.Pp +See also +.Sy zfs_arc_meta_limit , +which serves a similar purpose but has a higher priority if nonzero. +. +.It Sy zfs_arc_meta_min Ns = Ns Sy 0 Ns B Pq ulong +The minimum allowed size in bytes that metadata buffers may consume in +the ARC. +. +.It Sy zfs_arc_meta_prune Ns = Ns Sy 10000 Pq int The number of dentries and inodes to be scanned looking for entries -which can be dropped. This may be required when the ARC reaches the -\fBzfs_arc_meta_limit\fR because dentries and inodes can pin buffers -in the ARC. Increasing this value will cause to dentry and inode caches -to be pruned more aggressively. Setting this value to 0 will disable -pruning the inode and dentry caches. -.sp -Default value: \fB10,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_meta_strategy\fR (int) -.ad -.RS 12n -Define the strategy for ARC meta data buffer eviction (meta reclaim strategy). -A value of 0 (META_ONLY) will evict only the ARC meta data buffers. -A value of 1 (BALANCED) indicates that additional data buffers may be evicted if -that is required to in order to evict the required number of meta data buffers. -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_min\fR (ulong) -.ad -.RS 12n -Min size of ARC in bytes. If set to 0 then arc_c_min will default to -consuming the larger of 32M or 1/32 of total system memory. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_min_prefetch_ms\fR (int) -.ad -.RS 12n -Minimum time prefetched blocks are locked in the ARC, specified in ms. -A value of \fB0\fR will default to 1000 ms. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_min_prescient_prefetch_ms\fR (int) -.ad -.RS 12n -Minimum time "prescient prefetched" blocks are locked in the ARC, specified -in ms. These blocks are meant to be prefetched fairly aggressively ahead of -the code that may use them. A value of \fB0\fR will default to 6000 ms. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_max_missing_tvds\fR (int) -.ad -.RS 12n +which can be dropped. +This may be required when the ARC reaches the +.Sy zfs_arc_meta_limit +because dentries and inodes can pin buffers in the ARC. +Increasing this value will cause to dentry and inode caches +to be pruned more aggressively. +Setting this value to +.Sy 0 +will disable pruning the inode and dentry caches. +. +.It Sy zfs_arc_meta_strategy Ns = Ns Sy 1 Ns | Ns 0 Pq int +Define the strategy for ARC metadata buffer eviction (meta reclaim strategy): +.Bl -tag -compact -offset 4n -width "0 (META_ONLY)" +.It Sy 0 Pq META_ONLY +evict only the ARC metadata buffers +.It Sy 1 Pq BALANCED +additional data buffers may be evicted if required +to evict the required number of metadata buffers. +.El +. +.It Sy zfs_arc_min Ns = Ns Sy 0 Ns B Pq ulong +Min size of ARC in bytes. +.No If set to Sy 0 , arc_c_min +will default to consuming the larger of +.Sy 32MB No or Sy all_system_memory/32 . +. +.It Sy zfs_arc_min_prefetch_ms Ns = Ns Sy 0 Ns ms Ns Po Ns ≡ Ns 1s Pc Pq int +Minimum time prefetched blocks are locked in the ARC. +. +.It Sy zfs_arc_min_prescient_prefetch_ms Ns = Ns Sy 0 Ns ms Ns Po Ns ≡ Ns 6s Pc Pq int +Minimum time "prescient prefetched" blocks are locked in the ARC. +These blocks are meant to be prefetched fairly aggressively ahead of +the code that may use them. +. +.It Sy zfs_max_missing_tvds Ns = Ns Sy 0 Pq int Number of missing top-level vdevs which will be allowed during pool import (only in read-only mode). -.sp -Default value: \fB0\fR -.RE - -.sp -.ne 2 -.na -\fBzfs_max_nvlist_src_size\fR (ulong) -.ad -.RS 12n -Maximum size in bytes allowed to be passed as zc_nvlist_src_size for ioctls on -/dev/zfs. This prevents a user from causing the kernel to allocate an excessive -amount of memory. When the limit is exceeded, the ioctl fails with EINVAL and a -description of the error is sent to the zfs-dbgmsg log. This parameter should -not need to be touched under normal circumstances. On FreeBSD, the default is -based on the system limit on user wired memory. On Linux, the default is -\fB128MB\fR. -.sp -Default value: \fB0\fR (kernel decides) -.RE - -.sp -.ne 2 -.na -\fBzfs_multilist_num_sublists\fR (int) -.ad -.RS 12n +. +.It Sy zfs_max_nvlist_src_size Ns = Sy 0 Pq ulong +Maximum size in bytes allowed to be passed as +.Sy zc_nvlist_src_size +for ioctls on +.Pa /dev/zfs . +This prevents a user from causing the kernel to allocate +an excessive amount of memory. +When the limit is exceeded, the ioctl fails with +.Sy EINVAL +and a description of the error is sent to the +.Pa zfs-dbgmsg +log. +This parameter should not need to be touched under normal circumstances. +If +.Sy 0 , +equivalent to a quarter of the user-wired memory limit under +.Fx +and to +.Sy 134217728 Ns B Pq 128MB +under Linux. +. +.It Sy zfs_multilist_num_sublists Ns = Ns Sy 0 Pq int To allow more fine-grained locking, each ARC state contains a series -of lists for both data and meta data objects. Locking is performed at -the level of these "sub-lists". This parameters controls the number of -sub-lists per ARC state, and also applies to other uses of the -multilist data structure. -.sp -Default value: \fB4\fR or the number of online CPUs, whichever is greater -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_overflow_shift\fR (int) -.ad -.RS 12n +of lists for both data and metadata objects. +Locking is performed at the level of these "sub-lists". +This parameters controls the number of sub-lists per ARC state, +and also applies to other uses of the multilist data structure. +.Pp +If +.Sy 0 , +equivalent to the greater of the number of online CPUs and +.Sy 4 . +. +.It Sy zfs_arc_overflow_shift Ns = Ns Sy 8 Pq int The ARC size is considered to be overflowing if it exceeds the current -ARC target size (arc_c) by a threshold determined by this parameter. -The threshold is calculated as a fraction of arc_c using the formula -"arc_c >> \fBzfs_arc_overflow_shift\fR". - -The default value of 8 causes the ARC to be considered to be overflowing -if it exceeds the target size by 1/256th (0.3%) of the target size. - +ARC target size +.Pq Sy arc_c +by a threshold determined by this parameter. +The threshold is calculated as a fraction of +.Sy arc_c +using the formula +.Sy arc_c >> zfs_arc_overflow_shift . +.Pp +The default value of +.Sy 8 +causes the ARC to be considered overflowing if it exceeds the target size by +.Em 1/256th Pq Em 0.3% +of the target size. +.Pp When the ARC is overflowing, new buffer allocations are stalled until the reclaim thread catches up and the overflow condition no longer exists. -.sp -Default value: \fB8\fR. -.RE - -.sp -.ne 2 -.na - -\fBzfs_arc_p_min_shift\fR (int) -.ad -.RS 12n -If set to a non zero value, this will update arc_p_min_shift (default 4) +. +.It Sy zfs_arc_p_min_shift Ns = Ns Sy 0 Pq int +If nonzero, this will update +.Sy arc_p_min_shift Pq default Sy 4 with the new value. -arc_p_min_shift is used to shift of arc_c for calculating both min and max -max arc_p -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_p_dampener_disable\fR (int) -.ad -.RS 12n -Disable arc_p adapt dampener -.sp -Use \fB1\fR for yes (default) and \fB0\fR to disable. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_shrink_shift\fR (int) -.ad -.RS 12n -If set to a non zero value, this will update arc_shrink_shift (default 7) +.Sy arc_p_min_shift No is used as a shift of Sy arc_c +when calculating the minumum +.Sy arc_p No size. +. +.It Sy zfs_arc_p_dampener_disable Ns = Ns Sy 1 Ns | Ns 0 Pq int +Disable +.Sy arc_p +adapt dampener, which reduces the maximum single adjustment to +.Sy arc_p . +. +.It Sy zfs_arc_shrink_shift Ns = Ns Sy 0 Pq int +If nonzero, this will update +.Sy arc_shrink_shift Pq default Sy 7 with the new value. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_pc_percent\fR (uint) -.ad -.RS 12n -Percent of pagecache to reclaim arc to - -This tunable allows ZFS arc to play more nicely with the kernel's LRU -pagecache. It can guarantee that the ARC size won't collapse under scanning -pressure on the pagecache, yet still allows arc to be reclaimed down to -zfs_arc_min if necessary. This value is specified as percent of pagecache -size (as measured by NR_FILE_PAGES) where that percent may exceed 100. This +. +.It Sy zfs_arc_pc_percent Ns = Ns Sy 0 Ns % Po off Pc Pq uint +Percent of pagecache to reclaim ARC to. +.Pp +This tunable allows the ZFS ARC to play more nicely +with the kernel's LRU pagecache. +It can guarantee that the ARC size won't collapse under scanning +pressure on the pagecache, yet still allows the ARC to be reclaimed down to +.Sy zfs_arc_min +if necessary. +This value is specified as percent of pagecache size (as measured by +.Sy NR_FILE_PAGES ) , +where that percent may exceed +.Sy 100 . +This only operates during memory pressure/reclaim. -.sp -Default value: \fB0\fR% (disabled). -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_shrinker_limit\fR (int) -.ad -.RS 12n +. +.It Sy zfs_arc_shrinker_limit Ns = Ns Sy 10000 Pq int This is a limit on how many pages the ARC shrinker makes available for -eviction in response to one page allocation attempt. Note that in -practice, the kernel's shrinker can ask us to evict up to about 4x this -for one allocation attempt. -.sp -The default limit of 10,000 (in practice, 160MB per allocation attempt with -4K pages) limits the amount of time spent attempting to reclaim ARC memory to -less than 100ms per allocation attempt, even with a small average compressed -block size of ~8KB. -.sp -The parameter can be set to 0 (zero) to disable the limit. -.sp -This parameter only applies on Linux. -.sp -Default value: \fB10,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_arc_sys_free\fR (ulong) -.ad -.RS 12n +eviction in response to one page allocation attempt. +Note that in practice, the kernel's shrinker can ask us to evict +up to about four times this for one allocation attempt. +.Pp +The default limit of +.Sy 10000 Pq in practice, Em 160MB No per allocation attempt with 4kB pages +limits the amount of time spent attempting to reclaim ARC memory to +less than 100ms per allocation attempt, +even with a small average compressed block size of ~8kB. +.Pp +The parameter can be set to 0 (zero) to disable the limit, +and only applies on Linux. +. +.It Sy zfs_arc_sys_free Ns = Ns Sy 0 Ns B Pq ulong The target number of bytes the ARC should leave as free memory on the system. -Defaults to the larger of 1/64 of physical memory or 512K. Setting this -option to a non-zero value will override the default. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_autoimport_disable\fR (int) -.ad -.RS 12n -Disable pool import at module load by ignoring the cache file (typically \fB/etc/zfs/zpool.cache\fR). -.sp -Use \fB1\fR for yes (default) and \fB0\fR for no. -.RE - -.sp -.ne 2 -.na -\fBzfs_checksum_events_per_second\fR (uint) -.ad -.RS 12n -Rate limit checksum events to this many per second. Note that this should -not be set below the zed thresholds (currently 10 checksums over 10 sec) -or else zed may not trigger any action. -.sp -Default value: 20 -.RE - -.sp -.ne 2 -.na -\fBzfs_commit_timeout_pct\fR (int) -.ad -.RS 12n +If zero, equivalent to the bigger of +.Sy 512kB No and Sy all_system_memory/64 . +. +.It Sy zfs_autoimport_disable Ns = Ns Sy 1 Ns | Ns 0 Pq int +Disable pool import at module load by ignoring the cache file +.Pq Sy spa_config_path . +. +.It Sy zfs_checksum_events_per_second Ns = Ns Sy 20 Ns /s Pq uint +Rate limit checksum events to this many per second. +Note that this should not be set below the ZED thresholds +(currently 10 checksums over 10 seconds) +or else the daemon may not trigger any action. +. +.It Sy zfs_commit_timeout_pct Ns = Ns Sy 5 Ns % Pq int This controls the amount of time that a ZIL block (lwb) will remain "open" when it isn't "full", and it has a thread waiting for it to be committed to -stable storage. The timeout is scaled based on a percentage of the last lwb +stable storage. +The timeout is scaled based on a percentage of the last lwb latency to avoid significantly impacting the latency of each individual transaction record (itx). -.sp -Default value: \fB5\fR%. -.RE - -.sp -.ne 2 -.na -\fBzfs_condense_indirect_commit_entry_delay_ms\fR (int) -.ad -.RS 12n +. +.It Sy zfs_condense_indirect_commit_entry_delay_ms Ns = Ns Sy 0 Ns ms Pq int Vdev indirection layer (used for device removal) sleeps for this many -milliseconds during mapping generation. Intended for use with the test suite -to throttle vdev removal speed. -.sp -Default value: \fB0\fR (no throttle). -.RE - -.sp -.ne 2 -.na -\fBzfs_condense_indirect_vdevs_enable\fR (int) -.ad -.RS 12n -Enable condensing indirect vdev mappings. When set to a non-zero value, -attempt to condense indirect vdev mappings if the mapping uses more than -\fBzfs_condense_min_mapping_bytes\fR bytes of memory and if the obsolete -space map object uses more than \fBzfs_condense_max_obsolete_bytes\fR -bytes on-disk. The condensing process is an attempt to save memory by -removing obsolete mappings. -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_condense_max_obsolete_bytes\fR (ulong) -.ad -.RS 12n +milliseconds during mapping generation. +Intended for use with the test suite to throttle vdev removal speed. +. +.It Sy zfs_condense_indirect_obsolete_pct Ns = Ns Sy 25 Ns % Pq int +Minimum percent of obsolete bytes in vdev mapping required to attempt to condense +.Pq see Sy zfs_condense_indirect_vdevs_enable . +Intended for use with the test suite +to facilitate triggering condensing as needed. +. +.It Sy zfs_condense_indirect_vdevs_enable Ns = Ns Sy 1 Ns | Ns 0 Pq int +Enable condensing indirect vdev mappings. +When set, attempt to condense indirect vdev mappings +if the mapping uses more than +.Sy zfs_condense_min_mapping_bytes +bytes of memory and if the obsolete space map object uses more than +.Sy zfs_condense_max_obsolete_bytes +bytes on-disk. +The condensing process is an attempt to save memory by removing obsolete mappings. +. +.It Sy zfs_condense_max_obsolete_bytes Ns = Ns Sy 1073741824 Ns B Po 1GB Pc Pq ulong Only attempt to condense indirect vdev mappings if the on-disk size of the obsolete space map object is greater than this number of bytes -(see \fBfBzfs_condense_indirect_vdevs_enable\fR). -.sp -Default value: \fB1,073,741,824\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_condense_min_mapping_bytes\fR (ulong) -.ad -.RS 12n -Minimum size vdev mapping to attempt to condense (see -\fBzfs_condense_indirect_vdevs_enable\fR). -.sp -Default value: \fB131,072\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_dbgmsg_enable\fR (int) -.ad -.RS 12n -Internally ZFS keeps a small log to facilitate debugging. By default the log -is disabled, to enable it set this option to 1. The contents of the log can -be accessed by reading the /proc/spl/kstat/zfs/dbgmsg file. Writing 0 to -this proc file clears the log. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_dbgmsg_maxsize\fR (int) -.ad -.RS 12n -The maximum size in bytes of the internal ZFS debug log. -.sp -Default value: \fB4M\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_dbuf_state_index\fR (int) -.ad -.RS 12n -This feature is currently unused. It is normally used for controlling what -reporting is available under /proc/spl/kstat/zfs. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_deadman_enabled\fR (int) -.ad -.RS 12n -When a pool sync operation takes longer than \fBzfs_deadman_synctime_ms\fR -milliseconds, or when an individual I/O takes longer than -\fBzfs_deadman_ziotime_ms\fR milliseconds, then the operation is considered to -be "hung". If \fBzfs_deadman_enabled\fR is set then the deadman behavior is -invoked as described by the \fBzfs_deadman_failmode\fR module option. -By default the deadman is enabled and configured to \fBwait\fR which results -in "hung" I/Os only being logged. The deadman is automatically disabled -when a pool gets suspended. -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_deadman_failmode\fR (charp) -.ad -.RS 12n -Controls the failure behavior when the deadman detects a "hung" I/O. Valid -values are \fBwait\fR, \fBcontinue\fR, and \fBpanic\fR. -.sp -\fBwait\fR - Wait for a "hung" I/O to complete. For each "hung" I/O a -"deadman" event will be posted describing that I/O. -.sp -\fBcontinue\fR - Attempt to recover from a "hung" I/O by re-dispatching it +.Pq see Sy zfs_condense_indirect_vdevs_enable . +. +.It Sy zfs_condense_min_mapping_bytes Ns = Ns Sy 131072 Ns B Po 128kB Pc Pq ulong +Minimum size vdev mapping to attempt to condense +.Pq see Sy zfs_condense_indirect_vdevs_enable . +. +.It Sy zfs_dbgmsg_enable Ns = Ns Sy 1 Ns | Ns 0 Pq int +Internally ZFS keeps a small log to facilitate debugging. +The log is enabled by default, and can be disabled by unsetting this option. +The contents of the log can be accessed by reading +.Pa /proc/spl/kstat/zfs/dbgmsg . +Writing +.Sy 0 +to the file clears the log. +.Pp +This setting does not influence debug prints due to +.Sy zfs_flags . +. +.It Sy zfs_dbgmsg_maxsize Ns = Ns Sy 4194304 Ns B Po 4MB Pc Pq int +Maximum size of the internal ZFS debug log. +. +.It Sy zfs_dbuf_state_index Ns = Ns Sy 0 Pq int +Historically used for controlling what reporting was available under +.Pa /proc/spl/kstat/zfs . +No effect. +. +.It Sy zfs_deadman_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int +When a pool sync operation takes longer than +.Sy zfs_deadman_synctime_ms , +or when an individual I/O operation takes longer than +.Sy zfs_deadman_ziotime_ms , +then the operation is considered to be "hung". +If +.Sy zfs_deadman_enabled +is set, then the deadman behavior is invoked as described by +.Sy zfs_deadman_failmode . +By default, the deadman is enabled and set to +.Sy wait +which results in "hung" I/Os only being logged. +The deadman is automatically disabled when a pool gets suspended. +. +.It Sy zfs_deadman_failmode Ns = Ns Sy wait Pq charp +Controls the failure behavior when the deadman detects a "hung" I/O operation. +Valid values are: +.Bl -tag -compact -offset 4n -width "continue" +.It Sy wait +Wait for a "hung" operation to complete. +For each "hung" operation a "deadman" event will be posted +describing that operation. +.It Sy continue +Attempt to recover from a "hung" operation by re-dispatching it to the I/O pipeline if possible. -.sp -\fBpanic\fR - Panic the system. This can be used to facilitate an automatic -fail-over to a properly configured fail-over partner. -.sp -Default value: \fBwait\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_deadman_checktime_ms\fR (int) -.ad -.RS 12n -Check time in milliseconds. This defines the frequency at which we check -for hung I/O and potentially invoke the \fBzfs_deadman_failmode\fR behavior. -.sp -Default value: \fB60,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_deadman_synctime_ms\fR (ulong) -.ad -.RS 12n +.It Sy panic +Panic the system. +This can be used to facilitate automatic fail-over +to a properly configured fail-over partner. +.El +. +.It Sy zfs_deadman_checktime_ms Ns = Ns Sy 60000 Ns ms Po 1min Pc Pq int +Check time in milliseconds. +This defines the frequency at which we check for hung I/O requests +and potentially invoke the +.Sy zfs_deadman_failmode +behavior. +. +.It Sy zfs_deadman_synctime_ms Ns = Ns Sy 600000 Ns ms Po 10min Pc Pq ulong Interval in milliseconds after which the deadman is triggered and also the interval after which a pool sync operation is considered to be "hung". Once this limit is exceeded the deadman will be invoked every -\fBzfs_deadman_checktime_ms\fR milliseconds until the pool sync completes. -.sp -Default value: \fB600,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_deadman_ziotime_ms\fR (ulong) -.ad -.RS 12n +.Sy zfs_deadman_checktime_ms +milliseconds until the pool sync completes. +. +.It Sy zfs_deadman_ziotime_ms Ns = Ns Sy 300000 Ns ms Po 5min Pc Pq ulong Interval in milliseconds after which the deadman is triggered and an -individual I/O operation is considered to be "hung". As long as the I/O -remains "hung" the deadman will be invoked every \fBzfs_deadman_checktime_ms\fR -milliseconds until the I/O completes. -.sp -Default value: \fB300,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_dedup_prefetch\fR (int) -.ad -.RS 12n -Enable prefetching dedup-ed blks -.sp -Use \fB1\fR for yes and \fB0\fR to disable (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_delay_min_dirty_percent\fR (int) -.ad -.RS 12n +individual I/O operation is considered to be "hung". +As long as the operation remains "hung", +the deadman will be invoked every +.Sy zfs_deadman_checktime_ms +milliseconds until the operation completes. +. +.It Sy zfs_dedup_prefetch Ns = Ns Sy 0 Ns | Ns 1 Pq int +Enable prefetching dedup-ed blocks which are going to be freed. +. +.It Sy zfs_delay_min_dirty_percent Ns = Ns Sy 60 Ns % Pq int Start to delay each transaction once there is this amount of dirty data, -expressed as a percentage of \fBzfs_dirty_data_max\fR. -This value should be >= zfs_vdev_async_write_active_max_dirty_percent. -See the section "ZFS TRANSACTION DELAY". -.sp -Default value: \fB60\fR%. -.RE - -.sp -.ne 2 -.na -\fBzfs_delay_scale\fR (int) -.ad -.RS 12n +expressed as a percentage of +.Sy zfs_dirty_data_max . +This value should be at least +.Sy zfs_vdev_async_write_active_max_dirty_percent . +.No See Sx ZFS TRANSACTION DELAY . +. +.It Sy zfs_delay_scale Ns = Ns Sy 500000 Pq int This controls how quickly the transaction delay approaches infinity. Larger values cause longer delays for a given amount of dirty data. -.sp +.Pp For the smoothest delay, this value should be about 1 billion divided -by the maximum number of operations per second. This will smoothly -handle between 10x and 1/10th this number. -.sp -See the section "ZFS TRANSACTION DELAY". -.sp -Note: \fBzfs_delay_scale\fR * \fBzfs_dirty_data_max\fR must be < 2^64. -.sp -Default value: \fB500,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_disable_ivset_guid_check\fR (int) -.ad -.RS 12n -Disables requirement for IVset guids to be present and match when doing a raw -receive of encrypted datasets. Intended for users whose pools were created with +by the maximum number of operations per second. +This will smoothly handle between ten times and a tenth of this number. +.No See Sx ZFS TRANSACTION DELAY . +.Pp +.Sy zfs_delay_scale * zfs_dirty_data_max Em must be smaller than Sy 2^64 . +. +.It Sy zfs_disable_ivset_guid_check Ns = Ns Sy 0 Ns | Ns 1 Pq int +Disables requirement for IVset GUIDs to be present and match when doing a raw +receive of encrypted datasets. +Intended for users whose pools were created with OpenZFS pre-release versions and now have compatibility issues. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_key_max_salt_uses\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_key_max_salt_uses Ns = Ns Sy 400000000 Po 4*10^8 Pc Pq ulong Maximum number of uses of a single salt value before generating a new one for -encrypted datasets. The default value is also the maximum that will be -accepted. -.sp -Default value: \fB400,000,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_object_mutex_size\fR (uint) -.ad -.RS 12n +encrypted datasets. +The default value is also the maximum. +. +.It Sy zfs_object_mutex_size Ns = Ns Sy 64 Pq uint Size of the znode hashtable used for holds. - +.Pp Due to the need to hold locks on objects that may not exist yet, kernel mutexes are not created per-object and instead a hashtable is used where collisions will result in objects waiting when there is not actually contention on the same object. -.sp -Default value: \fB64\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_slow_io_events_per_second\fR (int) -.ad -.RS 12n -Rate limit delay zevents (which report slow I/Os) to this many per second. -.sp -Default value: 20 -.RE - -.sp -.ne 2 -.na -\fBzfs_unflushed_max_mem_amt\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_slow_io_events_per_second Ns = Ns Sy 20 Ns /s Pq int +Rate limit delay and deadman zevents (which report slow I/Os) to this many per +second. +. +.It Sy zfs_unflushed_max_mem_amt Ns = Ns Sy 1073741824 Ns B Po 1GB Pc Pq ulong Upper-bound limit for unflushed metadata changes to be held by the -log spacemap in memory (in bytes). -.sp -Default value: \fB1,073,741,824\fR (1GB). -.RE - -.sp -.ne 2 -.na -\fBzfs_unflushed_max_mem_ppm\fR (ulong) -.ad -.RS 12n -Percentage of the overall system memory that ZFS allows to be used -for unflushed metadata changes by the log spacemap. -(value is calculated over 1000000 for finer granularity). -.sp -Default value: \fB1000\fR (which is divided by 1000000, resulting in -the limit to be \fB0.1\fR% of memory) -.RE - -.sp -.ne 2 -.na -\fBzfs_unflushed_log_block_max\fR (ulong) -.ad -.RS 12n +log spacemap in memory, in bytes. +. +.It Sy zfs_unflushed_max_mem_ppm Ns = Ns Sy 1000 Ns ppm Po 0.1% Pc Pq ulong +Part of overall system memory that ZFS allows to be used +for unflushed metadata changes by the log spacemap, in millionths. +. +.It Sy zfs_unflushed_log_block_max Ns = Ns Sy 262144 Po 256k Pc Pq ulong Describes the maximum number of log spacemap blocks allowed for each pool. -The default value of 262144 means that the space in all the log spacemaps -can add up to no more than 262144 blocks (which means 32GB of logical -space before compression and ditto blocks, assuming that blocksize is -128k). -.sp +The default value means that the space in all the log spacemaps +can add up to no more than +.Sy 262144 +blocks (which means +.Em 32GB +of logical space before compression and ditto blocks, +assuming that blocksize is +.Em 128kB ) . +.Pp This tunable is important because it involves a trade-off between import time after an unclean export and the frequency of flushing metaslabs. The higher this number is, the more log blocks we allow when the pool is @@ -1746,2524 +975,1336 @@ the number of I/Os for spacemap updates per TXG. At the same time though, that means that in the event of an unclean export, there will be more log spacemap blocks for us to read, inducing overhead in the import time of the pool. -The lower the number, the amount of flushing increases destroying log +The lower the number, the amount of flushing increases, destroying log blocks quicker as they become obsolete faster, which leaves less blocks to be read during import time after a crash. -.sp +.Pp Each log spacemap block existing during pool import leads to approximately one extra logical I/O issued. This is the reason why this tunable is exposed in terms of blocks rather than space used. -.sp -Default value: \fB262144\fR (256K). -.RE - -.sp -.ne 2 -.na -\fBzfs_unflushed_log_block_min\fR (ulong) -.ad -.RS 12n -If the number of metaslabs is small and our incoming rate is high, we -could get into a situation that we are flushing all our metaslabs every -TXG. +. +.It Sy zfs_unflushed_log_block_min Ns = Ns Sy 1000 Pq ulong +If the number of metaslabs is small and our incoming rate is high, +we could get into a situation that we are flushing all our metaslabs every TXG. Thus we always allow at least this many log blocks. -.sp -Default value: \fB1000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_unflushed_log_block_pct\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_unflushed_log_block_pct Ns = Ns Sy 400 Ns % Pq ulong Tunable used to determine the number of blocks that can be used for the spacemap log, expressed as a percentage of the total number of metaslabs in the pool. -.sp -Default value: \fB400\fR (read as \fB400\fR% - meaning that the number -of log spacemap blocks are capped at 4 times the number of -metaslabs in the pool). -.RE - -.sp -.ne 2 -.na -\fBzfs_unlink_suspend_progress\fR (uint) -.ad -.RS 12n +. +.It Sy zfs_unlink_suspend_progress Ns = Ns Sy 0 Ns | Ns 1 Pq uint When enabled, files will not be asynchronously removed from the list of pending -unlinks and the space they consume will be leaked. Once this option has been -disabled and the dataset is remounted, the pending unlinks will be processed -and the freed space returned to the pool. -This option is used by the test suite to facilitate testing. -.sp -Uses \fB0\fR (default) to allow progress and \fB1\fR to pause progress. -.RE - -.sp -.ne 2 -.na -\fBzfs_delete_blocks\fR (ulong) -.ad -.RS 12n -This is the used to define a large file for the purposes of delete. Files -containing more than \fBzfs_delete_blocks\fR will be deleted asynchronously -while smaller files are deleted synchronously. Decreasing this value will -reduce the time spent in an unlink(2) system call at the expense of a longer -delay before the freed space is available. -.sp -Default value: \fB20,480\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_dirty_data_max\fR (int) -.ad -.RS 12n -Determines the dirty space limit in bytes. Once this limit is exceeded, new -writes are halted until space frees up. This parameter takes precedence -over \fBzfs_dirty_data_max_percent\fR. -See the section "ZFS TRANSACTION DELAY". -.sp -Default value: \fB10\fR% of physical RAM, capped at \fBzfs_dirty_data_max_max\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_dirty_data_max_max\fR (int) -.ad -.RS 12n -Maximum allowable value of \fBzfs_dirty_data_max\fR, expressed in bytes. +unlinks and the space they consume will be leaked. +Once this option has been disabled and the dataset is remounted, +the pending unlinks will be processed and the freed space returned to the pool. +This option is used by the test suite. +. +.It Sy zfs_delete_blocks Ns = Ns Sy 20480 Pq ulong +This is the used to define a large file for the purposes of deletion. +Files containing more than +.Sy zfs_delete_blocks +will be deleted asynchronously, while smaller files are deleted synchronously. +Decreasing this value will reduce the time spent in an +.Xr unlink 2 +system call, at the expense of a longer delay before the freed space is available. +. +.It Sy zfs_dirty_data_max Ns = Pq int +Determines the dirty space limit in bytes. +Once this limit is exceeded, new writes are halted until space frees up. +This parameter takes precedence over +.Sy zfs_dirty_data_max_percent . +.No See Sx ZFS TRANSACTION DELAY . +.Pp +Defaults to +.Sy physical_ram/10 , +capped at +.Sy zfs_dirty_data_max_max . +. +.It Sy zfs_dirty_data_max_max Ns = Pq int +Maximum allowable value of +.Sy zfs_dirty_data_max , +expressed in bytes. This limit is only enforced at module load time, and will be ignored if -\fBzfs_dirty_data_max\fR is later changed. This parameter takes -precedence over \fBzfs_dirty_data_max_max_percent\fR. See the section -"ZFS TRANSACTION DELAY". -.sp -Default value: \fB25\fR% of physical RAM. -.RE - -.sp -.ne 2 -.na -\fBzfs_dirty_data_max_max_percent\fR (int) -.ad -.RS 12n -Maximum allowable value of \fBzfs_dirty_data_max\fR, expressed as a -percentage of physical RAM. This limit is only enforced at module load -time, and will be ignored if \fBzfs_dirty_data_max\fR is later changed. -The parameter \fBzfs_dirty_data_max_max\fR takes precedence over this -one. See the section "ZFS TRANSACTION DELAY". -.sp -Default value: \fB25\fR%. -.RE - -.sp -.ne 2 -.na -\fBzfs_dirty_data_max_percent\fR (int) -.ad -.RS 12n -Determines the dirty space limit, expressed as a percentage of all -memory. Once this limit is exceeded, new writes are halted until space frees -up. The parameter \fBzfs_dirty_data_max\fR takes precedence over this -one. See the section "ZFS TRANSACTION DELAY". -.sp -Default value: \fB10\fR%, subject to \fBzfs_dirty_data_max_max\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_dirty_data_sync_percent\fR (int) -.ad -.RS 12n +.Sy zfs_dirty_data_max +is later changed. +This parameter takes precedence over +.Sy zfs_dirty_data_max_max_percent . +.No See Sx ZFS TRANSACTION DELAY . +.Pp +Defaults to +.Sy physical_ram/4 , +. +.It Sy zfs_dirty_data_max_max_percent Ns = Ns Sy 25 Ns % Pq int +Maximum allowable value of +.Sy zfs_dirty_data_max , +expressed as a percentage of physical RAM. +This limit is only enforced at module load time, and will be ignored if +.Sy zfs_dirty_data_max +is later changed. +The parameter +.Sy zfs_dirty_data_max_max +takes precedence over this one. +.No See Sx ZFS TRANSACTION DELAY . +. +.It Sy zfs_dirty_data_max_percent Ns = Ns Sy 10 Ns % Pq int +Determines the dirty space limit, expressed as a percentage of all memory. +Once this limit is exceeded, new writes are halted until space frees up. +The parameter +.Sy zfs_dirty_data_max +takes precedence over this one. +.No See Sx ZFS TRANSACTION DELAY . +.Pp +Subject to +.Sy zfs_dirty_data_max_max . +. +.It Sy zfs_dirty_data_sync_percent Ns = Ns Sy 20 Ns % Pq int Start syncing out a transaction group if there's at least this much dirty data -as a percentage of \fBzfs_dirty_data_max\fR. This should be less than -\fBzfs_vdev_async_write_active_min_dirty_percent\fR. -.sp -Default value: \fB20\fR% of \fBzfs_dirty_data_max\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_fallocate_reserve_percent\fR (uint) -.ad -.RS 12n +.Pq as a percentage of Sy zfs_dirty_data_max . +This should be less than +.Sy zfs_vdev_async_write_active_min_dirty_percent . +. +.It Sy zfs_fallocate_reserve_percent Ns = Ns Sy 110 Ns % Pq uint Since ZFS is a copy-on-write filesystem with snapshots, blocks cannot be preallocated for a file in order to guarantee that later writes will not -run out of space. Instead, fallocate() space preallocation only checks -that sufficient space is currently available in the pool or the user's -project quota allocation, and then creates a sparse file of the requested -size. The requested space is multiplied by \fBzfs_fallocate_reserve_percent\fR +run out of space. +Instead, +.Xr fallocate 2 +space preallocation only checks that sufficient space is currently available +in the pool or the user's project quota allocation, +and then creates a sparse file of the requested size. +The requested space is multiplied by +.Sy zfs_fallocate_reserve_percent to allow additional space for indirect blocks and other internal metadata. -Setting this value to 0 disables support for fallocate(2) and returns -EOPNOTSUPP for fallocate() space preallocation again. -.sp -Default value: \fB110\fR% -.RE - -.sp -.ne 2 -.na -\fBzfs_fletcher_4_impl\fR (string) -.ad -.RS 12n +Setting this to +.Sy 0 +disables support for +.Xr fallocate 2 +and causes it to return +.Sy EOPNOTSUPP . +. +.It Sy zfs_fletcher_4_impl Ns = Ns Sy fastest Pq string Select a fletcher 4 implementation. -.sp -Supported selectors are: \fBfastest\fR, \fBscalar\fR, \fBsse2\fR, \fBssse3\fR, -\fBavx2\fR, \fBavx512f\fR, \fBavx512bw\fR, and \fBaarch64_neon\fR. -All of the selectors except \fBfastest\fR and \fBscalar\fR require instruction -set extensions to be available and will only appear if ZFS detects that they are -present at runtime. If multiple implementations of fletcher 4 are available, -the \fBfastest\fR will be chosen using a micro benchmark. Selecting \fBscalar\fR -results in the original, CPU based calculation, being used. Selecting any option -other than \fBfastest\fR and \fBscalar\fR results in vector instructions from -the respective CPU instruction set being used. -.sp -Default value: \fBfastest\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_free_bpobj_enabled\fR (int) -.ad -.RS 12n +.Pp +Supported selectors are: +.Sy fastest , scalar , sse2 , ssse3 , avx2 , avx512f , avx512bw , +.No and Sy aarch64_neon . +All except +.Sy fastest No and Sy scalar +require instruction set extensions to be available, +and will only appear if ZFS detects that they are present at runtime. +If multiple implementations of fletcher 4 are available, the +.Sy fastest +will be chosen using a micro benchmark. +Selecting +.Sy scalar +results in the original CPU-based calculation being used. +Selecting any option other than +.Sy fastest No or Sy scalar +results in vector instructions +from the respective CPU instruction set being used. +. +.It Sy zfs_free_bpobj_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int Enable/disable the processing of the free_bpobj object. -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_async_block_max_blocks\fR (ulong) -.ad -.RS 12n -Maximum number of blocks freed in a single txg. -.sp -Default value: \fBULONG_MAX\fR (unlimited). -.RE - -.sp -.ne 2 -.na -\fBzfs_max_async_dedup_frees\fR (ulong) -.ad -.RS 12n -Maximum number of dedup blocks freed in a single txg. -.sp -Default value: \fB100,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_override_estimate_recordsize\fR (ulong) -.ad -.RS 12n -Record size calculation override for zfs send estimates. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_async_read_max_active\fR (int) -.ad -.RS 12n -Maximum asynchronous read I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB3\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_async_read_min_active\fR (int) -.ad -.RS 12n -Minimum asynchronous read I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_async_write_active_max_dirty_percent\fR (int) -.ad -.RS 12n -When the pool has more than -\fBzfs_vdev_async_write_active_max_dirty_percent\fR dirty data, use -\fBzfs_vdev_async_write_max_active\fR to limit active async writes. If -the dirty data is between min and max, the active I/O limit is linearly -interpolated. See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB60\fR%. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_async_write_active_min_dirty_percent\fR (int) -.ad -.RS 12n -When the pool has less than -\fBzfs_vdev_async_write_active_min_dirty_percent\fR dirty data, use -\fBzfs_vdev_async_write_min_active\fR to limit active async writes. If -the dirty data is between min and max, the active I/O limit is linearly -interpolated. See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB30\fR%. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_async_write_max_active\fR (int) -.ad -.RS 12n -Maximum asynchronous write I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB10\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_async_write_min_active\fR (int) -.ad -.RS 12n -Minimum asynchronous write I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp +. +.It Sy zfs_async_block_max_blocks Ns = Ns Sy ULONG_MAX Po unlimited Pc Pq ulong +Maximum number of blocks freed in a single TXG. +. +.It Sy zfs_max_async_dedup_frees Ns = Ns Sy 100000 Po 10^5 Pc Pq ulong +Maximum number of dedup blocks freed in a single TXG. +. +.It Sy zfs_override_estimate_recordsize Ns = Ns Sy 0 Pq ulong +If nonzer, override record size calculation for +.Nm zfs Cm send +estimates. +. +.It Sy zfs_vdev_async_read_max_active Ns = Ns Sy 3 Pq int +Maximum asynchronous read I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_async_read_min_active Ns = Ns Sy 1 Pq int +Minimum asynchronous read I/O operation active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_async_write_active_max_dirty_percent Ns = Ns Sy 60 Ns % Pq int +When the pool has more than this much dirty data, use +.Sy zfs_vdev_async_write_max_active +to limit active async writes. +If the dirty data is between the minimum and maximum, +the active I/O limit is linearly interpolated. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_async_write_active_min_dirty_percent Ns = Ns Sy 30 Ns % Pq int +When the pool has less than this much dirty data, use +.Sy zfs_vdev_async_write_min_active +to limit active async writes. +If the dirty data is between the minimum and maximum, +the active I/O limit is linearly +interpolated. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_async_write_max_active Ns = Ns Sy 30 Pq int +Maximum asynchronous write I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_async_write_min_active Ns = Ns Sy 2 Pq int +Minimum asynchronous write I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +.Pp Lower values are associated with better latency on rotational media but poorer -resilver performance. The default value of 2 was chosen as a compromise. A -value of 3 has been shown to improve resilver performance further at a cost of +resilver performance. +The default value of +.Sy 2 +was chosen as a compromise. +A value of +.Sy 3 +has been shown to improve resilver performance further at a cost of further increasing latency. -.sp -Default value: \fB2\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_initializing_max_active\fR (int) -.ad -.RS 12n -Maximum initializing I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_initializing_min_active\fR (int) -.ad -.RS 12n -Minimum initializing I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_max_active\fR (int) -.ad -.RS 12n -The maximum number of I/Os active to each device. Ideally, this will be >= -the sum of each queue's max_active. See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB1,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_rebuild_max_active\fR (int) -.ad -.RS 12n -Maximum sequential resilver I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB3\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_rebuild_min_active\fR (int) -.ad -.RS 12n -Minimum sequential resilver I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_removal_max_active\fR (int) -.ad -.RS 12n -Maximum removal I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB2\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_removal_min_active\fR (int) -.ad -.RS 12n -Minimum removal I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_scrub_max_active\fR (int) -.ad -.RS 12n -Maximum scrub I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB2\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_scrub_min_active\fR (int) -.ad -.RS 12n -Minimum scrub I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_sync_read_max_active\fR (int) -.ad -.RS 12n -Maximum synchronous read I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB10\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_sync_read_min_active\fR (int) -.ad -.RS 12n -Minimum synchronous read I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB10\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_sync_write_max_active\fR (int) -.ad -.RS 12n -Maximum synchronous write I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB10\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_sync_write_min_active\fR (int) -.ad -.RS 12n -Minimum synchronous write I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB10\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_trim_max_active\fR (int) -.ad -.RS 12n -Maximum trim/discard I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB2\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_trim_min_active\fR (int) -.ad -.RS 12n -Minimum trim/discard I/Os active to each device. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_nia_delay\fR (int) -.ad -.RS 12n +. +.It Sy zfs_vdev_initializing_max_active Ns = Ns Sy 1 Pq int +Maximum initializing I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_initializing_min_active Ns = Ns Sy 1 Pq int +Minimum initializing I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_max_active Ns = Ns Sy 1000 Pq int +The maximum number of I/O operations active to each device. +Ideally, this will be at least the sum of each queue's +.Sy max_active . +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_rebuild_max_active Ns = Ns Sy 3 Pq int +Maximum sequential resilver I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_rebuild_min_active Ns = Ns Sy 1 Pq int +Minimum sequential resilver I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_removal_max_active Ns = Ns Sy 2 Pq int +Maximum removal I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_removal_min_active Ns = Ns Sy 1 Pq int +Minimum removal I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_scrub_max_active Ns = Ns Sy 2 Pq int +Maximum scrub I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_scrub_min_active Ns = Ns Sy 1 Pq int +Minimum scrub I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_sync_read_max_active Ns = Ns Sy 10 Pq int +Maximum synchronous read I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_sync_read_min_active Ns = Ns Sy 10 Pq int +Minimum synchronous read I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_sync_write_max_active Ns = Ns Sy 10 Pq int +Maximum synchronous write I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_sync_write_min_active Ns = Ns Sy 10 Pq int +Minimum synchronous write I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_trim_max_active Ns = Ns Sy 2 Pq int +Maximum trim/discard I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_trim_min_active Ns = Ns Sy 1 Pq int +Minimum trim/discard I/O operations active to each device. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_nia_delay Ns = Ns Sy 5 Pq int For non-interactive I/O (scrub, resilver, removal, initialize and rebuild), -the number of concurrently-active I/O's is limited to *_min_active, unless -the vdev is "idle". When there are no interactive I/Os active (sync or -async), and zfs_vdev_nia_delay I/Os have completed since the last -interactive I/O, then the vdev is considered to be "idle", and the number -of concurrently-active non-interactive I/O's is increased to *_max_active. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB5\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_nia_credit\fR (int) -.ad -.RS 12n -Some HDDs tend to prioritize sequential I/O so high, that concurrent -random I/O latency reaches several seconds. On some HDDs it happens -even if sequential I/Os are submitted one at a time, and so setting -*_max_active to 1 does not help. To prevent non-interactive I/Os, like -scrub, from monopolizing the device no more than zfs_vdev_nia_credit -I/Os can be sent while there are outstanding incomplete interactive -I/Os. This enforced wait ensures the HDD services the interactive I/O +the number of concurrently-active I/O operations is limited to +.Sy zfs_*_min_active , +unless the vdev is "idle". +When there are no interactive I/O operatinons active (synchronous or otherwise), +and +.Sy zfs_vdev_nia_delay +operations have completed since the last interactive operation, +then the vdev is considered to be "idle", +and the number of concurrently-active non-interactive operations is increased to +.Sy zfs_*_max_active . +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_nia_credit Ns = Ns Sy 5 Pq int +Some HDDs tend to prioritize sequential I/O so strongly, that concurrent +random I/O latency reaches several seconds. +On some HDDs this happens even if sequential I/O operations +are submitted one at a time, and so setting +.Sy zfs_*_max_active Ns = Sy 1 +does not help. +To prevent non-interactive I/O, like scrub, +from monopolizing the device, no more than +.Sy zfs_vdev_nia_credit operations can be sent +while there are outstanding incomplete interactive operations. +This enforced wait ensures the HDD services the interactive I/O within a reasonable amount of time. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB5\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_queue_depth_pct\fR (int) -.ad -.RS 12n +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_queue_depth_pct Ns = Ns Sy 1000 Ns % Pq int Maximum number of queued allocations per top-level vdev expressed as -a percentage of \fBzfs_vdev_async_write_max_active\fR which allows the -system to detect devices that are more capable of handling allocations -and to allocate more blocks to those devices. It allows for dynamic -allocation distribution when devices are imbalanced as fuller devices -will tend to be slower than empty devices. - -See also \fBzio_dva_throttle_enabled\fR. -.sp -Default value: \fB1000\fR%. -.RE - -.sp -.ne 2 -.na -\fBzfs_expire_snapshot\fR (int) -.ad -.RS 12n -Seconds to expire .zfs/snapshot -.sp -Default value: \fB300\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_admin_snapshot\fR (int) -.ad -.RS 12n -Allow the creation, removal, or renaming of entries in the .zfs/snapshot +a percentage of +.Sy zfs_vdev_async_write_max_active , +which allows the system to detect devices that are more capable +of handling allocations and to allocate more blocks to those devices. +This allows for dynamic allocation distribution when devices are imbalanced, +as fuller devices will tend to be slower than empty devices. +.Pp +Also see +.Sy zio_dva_throttle_enabled . +. +.It Sy zfs_expire_snapshot Ns = Ns Sy 300 Ns s Pq int +Time before expiring +.Pa .zfs/snapshot . +. +.It Sy zfs_admin_snapshot Ns = Ns Sy 0 Ns | Ns 1 Pq int +Allow the creation, removal, or renaming of entries in the +.Sy .zfs/snapshot directory to cause the creation, destruction, or renaming of snapshots. -When enabled this functionality works both locally and over NFS exports -which have the 'no_root_squash' option set. This functionality is disabled -by default. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_flags\fR (int) -.ad -.RS 12n -Set additional debugging flags. The following flags may be bitwise-or'd -together. -.sp +When enabled, this functionality works both locally and over NFS exports +which have the +.Em no_root_squash +option set. +. +.It Sy zfs_flags Ns = Ns Sy 0 Pq int +Set additional debugging flags. +The following flags may be bitwise-ored together: .TS box; -rB lB -lB lB -r l. -Value Symbolic Name - Description +lbz r l l . + Value Symbolic Name Description _ -1 ZFS_DEBUG_DPRINTF - Enable dprintf entries in the debug log. -_ -2 ZFS_DEBUG_DBUF_VERIFY * - Enable extra dbuf verifications. -_ -4 ZFS_DEBUG_DNODE_VERIFY * - Enable extra dnode verifications. -_ -8 ZFS_DEBUG_SNAPNAMES - Enable snapshot name verification. -_ -16 ZFS_DEBUG_MODIFY - Check for illegally modified ARC buffers. -_ -64 ZFS_DEBUG_ZIO_FREE - Enable verification of block frees. -_ -128 ZFS_DEBUG_HISTOGRAM_VERIFY - Enable extra spacemap histogram verifications. -_ -256 ZFS_DEBUG_METASLAB_VERIFY - Verify space accounting on disk matches in-core range_trees. -_ -512 ZFS_DEBUG_SET_ERROR - Enable SET_ERROR and dprintf entries in the debug log. -_ -1024 ZFS_DEBUG_INDIRECT_REMAP - Verify split blocks created by device removal. -_ -2048 ZFS_DEBUG_TRIM - Verify TRIM ranges are always within the allocatable range tree. -_ -4096 ZFS_DEBUG_LOG_SPACEMAP - Verify that the log summary is consistent with the spacemap log - and enable zfs_dbgmsgs for metaslab loading and flushing. + 1 ZFS_DEBUG_DPRINTF Enable dprintf entries in the debug log. +* 2 ZFS_DEBUG_DBUF_VERIFY Enable extra dbuf verifications. +* 4 ZFS_DEBUG_DNODE_VERIFY Enable extra dnode verifications. + 8 ZFS_DEBUG_SNAPNAMES Enable snapshot name verification. + 16 ZFS_DEBUG_MODIFY Check for illegally modified ARC buffers. + 64 ZFS_DEBUG_ZIO_FREE Enable verification of block frees. + 128 ZFS_DEBUG_HISTOGRAM_VERIFY Enable extra spacemap histogram verifications. + 256 ZFS_DEBUG_METASLAB_VERIFY Verify space accounting on disk matches in-memory \fBrange_trees\fP. + 512 ZFS_DEBUG_SET_ERROR Enable \fBSET_ERROR\fP and dprintf entries in the debug log. + 1024 ZFS_DEBUG_INDIRECT_REMAP Verify split blocks created by device removal. + 2048 ZFS_DEBUG_TRIM Verify TRIM ranges are always within the allocatable range tree. + 4096 ZFS_DEBUG_LOG_SPACEMAP Verify that the log summary is consistent with the spacemap log + and enable \fBzfs_dbgmsgs\fP for metaslab loading and flushing. .TE -.sp -* Requires debug build. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_free_leak_on_eio\fR (int) -.ad -.RS 12n -If destroy encounters an EIO while reading metadata (e.g. indirect -blocks), space referenced by the missing metadata can not be freed. -Normally this causes the background destroy to become "stalled", as -it is unable to make forward progress. While in this stalled state, -all remaining space to free from the error-encountering filesystem is -"temporarily leaked". Set this flag to cause it to ignore the EIO, +.Sy \& * No Requires debug build. +. +.It Sy zfs_free_leak_on_eio Ns = Ns Sy 0 Ns | Ns 1 Pq int +If destroy encounters an +.Sy EIO +while reading metadata (e.g. indirect blocks), +space referenced by the missing metadata can not be freed. +Normally this causes the background destroy to become "stalled", +as it is unable to make forward progress. +While in this stalled state, all remaining space to free +from the error-encountering filesystem is "temporarily leaked". +Set this flag to cause it to ignore the +.Sy EIO , permanently leak the space from indirect blocks that can not be read, and continue to free everything else that it can. - -The default, "stalling" behavior is useful if the storage partially -fails (i.e. some but not all i/os fail), and then later recovers. In -this case, we will be able to continue pool operations while it is +.Pp +The default "stalling" behavior is useful if the storage partially +fails (i.e. some but not all I/O operations fail), and then later recovers. +In this case, we will be able to continue pool operations while it is partially failed, and when it recovers, we can continue to free the -space, with no leaks. However, note that this case is actually -fairly rare. - -Typically pools either (a) fail completely (but perhaps temporarily, -e.g. a top-level vdev going offline), or (b) have localized, -permanent errors (e.g. disk returns the wrong data due to bit flip or -firmware bug). In case (a), this setting does not matter because the +space, with no leaks. +Note, however, that this case is actually fairly rare. +.Pp +Typically pools either +.Bl -enum -compact -offset 4n -width "1." +.It +fail completely (but perhaps temporarily, +e.g. due to a top-level vdev going offline), or +.It +have localized, permanent errors (e.g. disk returns the wrong data +due to bit flip or firmware bug). +.El +In the former case, this setting does not matter because the pool will be suspended and the sync thread will not be able to make -forward progress regardless. In case (b), because the error is -permanent, the best we can do is leak the minimum amount of space, -which is what setting this flag will do. Therefore, it is reasonable -for this flag to normally be set, but we chose the more conservative -approach of not setting it, so that there is no possibility of +forward progress regardless. +In the latter, because the error is permanent, the best we can do +is leak the minimum amount of space, +which is what setting this flag will do. +It is therefore reasonable for this flag to normally be set, +but we chose the more conservative approach of not setting it, +so that there is no possibility of leaking space in the "partial temporary" failure case. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_free_min_time_ms\fR (int) -.ad -.RS 12n -During a \fBzfs destroy\fR operation using \fBfeature@async_destroy\fR a minimum -of this much time will be spent working on freeing blocks per txg. -.sp -Default value: \fB1,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_obsolete_min_time_ms\fR (int) -.ad -.RS 12n -Similar to \fBzfs_free_min_time_ms\fR but for cleanup of old indirection records -for removed vdevs. -.sp -Default value: \fB500\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_immediate_write_sz\fR (long) -.ad -.RS 12n -Largest data block to write to zil. Larger blocks will be treated as if the -dataset being written to had the property setting \fBlogbias=throughput\fR. -.sp -Default value: \fB32,768\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_initialize_value\fR (ulong) -.ad -.RS 12n -Pattern written to vdev free space by \fBzpool initialize\fR. -.sp -Default value: \fB16,045,690,984,833,335,022\fR (0xdeadbeefdeadbeee). -.RE - -.sp -.ne 2 -.na -\fBzfs_initialize_chunk_size\fR (ulong) -.ad -.RS 12n -Size of writes used by \fBzpool initialize\fR. -This option is used by the test suite to facilitate testing. -.sp -Default value: \fB1,048,576\fR -.RE - -.sp -.ne 2 -.na -\fBzfs_livelist_max_entries\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_free_min_time_ms Ns = Ns Sy 1000 Ns ms Po 1s Pc Pq int +During a +.Nm zfs Cm destroy +operation using the +.Sy async_destroy +feature, +a minimum of this much time will be spent working on freeing blocks per TXG. +. +.It Sy zfs_obsolete_min_time_ms Ns = Ns Sy 500 Ns ms Pq int +Similar to +.Sy zfs_free_min_time_ms , +but for cleanup of old indirection records for removed vdevs. +. +.It Sy zfs_immediate_write_sz Ns = Ns Sy 32768 Ns B Po 32kB Pc Pq long +Largest data block to write to the ZIL. +Larger blocks will be treated as if the dataset being written to had the +.Sy logbias Ns = Ns Sy throughput +property set. +. +.It Sy zfs_initialize_value Ns = Ns Sy 16045690984833335022 Po 0xDEADBEEFDEADBEEE Pc Pq ulong +Pattern written to vdev free space by +.Xr zpool-initialize 8 . +. +.It Sy zfs_initialize_chunk_size Ns = Ns Sy 1048576 Ns B Po 1MB Pc Pq ulong +Size of writes used by +.Xr zpool-initialize 8 . +This option is used by the test suite. +. +.It Sy zfs_livelist_max_entries Ns = Ns Sy 500000 Po 5*10^5 Pc Pq ulong The threshold size (in block pointers) at which we create a new sub-livelist. Larger sublists are more costly from a memory perspective but the fewer sublists there are, the lower the cost of insertion. -.sp -Default value: \fB500,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_livelist_min_percent_shared\fR (int) -.ad -.RS 12n +. +.It Sy zfs_livelist_min_percent_shared Ns = Ns Sy 75 Ns % Pq int If the amount of shared space between a snapshot and its clone drops below -this threshold, the clone turns off the livelist and reverts to the old deletion -method. This is in place because once a clone has been overwritten enough -livelists no long give us a benefit. -.sp -Default value: \fB75\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_livelist_condense_new_alloc\fR (int) -.ad -.RS 12n +this threshold, the clone turns off the livelist and reverts to the old +deletion method. +This is in place because livelists no long give us a benefit +once a clone has been overwritten enough. +. +.It Sy zfs_livelist_condense_new_alloc Ns = Ns Sy 0 Pq int Incremented each time an extra ALLOC blkptr is added to a livelist entry while it is being condensed. This option is used by the test suite to track race conditions. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_livelist_condense_sync_cancel\fR (int) -.ad -.RS 12n +. +.It Sy zfs_livelist_condense_sync_cancel Ns = Ns Sy 0 Pq int Incremented each time livelist condensing is canceled while in -spa_livelist_condense_sync. +.Fn spa_livelist_condense_sync . This option is used by the test suite to track race conditions. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_livelist_condense_sync_pause\fR (int) -.ad -.RS 12n +. +.It Sy zfs_livelist_condense_sync_pause Ns = Ns Sy 0 Ns | Ns 1 Pq int When set, the livelist condense process pauses indefinitely before -executing the synctask - spa_livelist_condense_sync. +executing the synctask - +.Fn spa_livelist_condense_sync . This option is used by the test suite to trigger race conditions. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_livelist_condense_zthr_cancel\fR (int) -.ad -.RS 12n +. +.It Sy zfs_livelist_condense_zthr_cancel Ns = Ns Sy 0 Pq int Incremented each time livelist condensing is canceled while in -spa_livelist_condense_cb. +.Fn spa_livelist_condense_cb . This option is used by the test suite to track race conditions. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_livelist_condense_zthr_pause\fR (int) -.ad -.RS 12n +. +.It Sy zfs_livelist_condense_zthr_pause Ns = Ns Sy 0 Ns | Ns 1 Pq int When set, the livelist condense process pauses indefinitely before -executing the open context condensing work in spa_livelist_condense_cb. +executing the open context condensing work in +.Fn spa_livelist_condense_cb . This option is used by the test suite to trigger race conditions. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_lua_max_instrlimit\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_lua_max_instrlimit Ns = Ns Sy 100000000 Po 10^8 Pc Pq ulong The maximum execution time limit that can be set for a ZFS channel program, specified as a number of Lua instructions. -.sp -Default value: \fB100,000,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_lua_max_memlimit\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_lua_max_memlimit Ns = Ns Sy 104857600 Po 100MB Pc Pq ulong The maximum memory limit that can be set for a ZFS channel program, specified in bytes. -.sp -Default value: \fB104,857,600\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_max_dataset_nesting\fR (int) -.ad -.RS 12n -The maximum depth of nested datasets. This value can be tuned temporarily to +. +.It Sy zfs_max_dataset_nesting Ns = Ns Sy 50 Pq int +The maximum depth of nested datasets. +This value can be tuned temporarily to fix existing datasets that exceed the predefined limit. -.sp -Default value: \fB50\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_max_log_walking\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_max_log_walking Ns = Ns Sy 5 Pq ulong The number of past TXGs that the flushing algorithm of the log spacemap feature uses to estimate incoming log blocks. -.sp -Default value: \fB5\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_max_logsm_summary_length\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_max_logsm_summary_length Ns = Ns Sy 10 Pq ulong Maximum number of rows allowed in the summary of the spacemap log. -.sp -Default value: \fB10\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_max_recordsize\fR (int) -.ad -.RS 12n -We currently support block sizes from 512 bytes to 16MB. The benefits of -larger blocks, and thus larger I/O, need to be weighed against the cost of -COWing a giant block to modify one byte. Additionally, very large blocks -can have an impact on i/o latency, and also potentially on the memory -allocator. Therefore, we do not allow the recordsize to be set larger than -zfs_max_recordsize (default 1MB). Larger blocks can be created by changing -this tunable, and pools with larger blocks can always be imported and used, +. +.It Sy zfs_max_recordsize Ns = Ns Sy 1048576 Po 1MB Pc Pq int +We currently support block sizes from +.Em 512B No to Em 16MB . +The benefits of larger blocks, and thus larger I/O, +need to be weighed against the cost of COWing a giant block to modify one byte. +Additionally, very large blocks can have an impact on I/O latency, +and also potentially on the memory allocator. +Therefore, we do not allow the recordsize to be set larger than this tunable. +Larger blocks can be created by changing it, +and pools with larger blocks can always be imported and used, regardless of this setting. -.sp -Default value: \fB1,048,576\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_allow_redacted_dataset_mount\fR (int) -.ad -.RS 12n -Allow datasets received with redacted send/receive to be mounted. Normally -disabled because these datasets may be missing key data. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_min_metaslabs_to_flush\fR (ulong) -.ad -.RS 12n -Minimum number of metaslabs to flush per dirty TXG -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_metaslab_fragmentation_threshold\fR (int) -.ad -.RS 12n +. +.It Sy zfs_allow_redacted_dataset_mount Ns = Ns Sy 0 Ns | Ns 1 Pq int +Allow datasets received with redacted send/receive to be mounted. +Normally disabled because these datasets may be missing key data. +. +.It Sy zfs_min_metaslabs_to_flush Ns = Ns Sy 1 Pq ulong +Minimum number of metaslabs to flush per dirty TXG. +. +.It Sy zfs_metaslab_fragmentation_threshold Ns = Ns Sy 70 Ns % Pq int Allow metaslabs to keep their active state as long as their fragmentation -percentage is less than or equal to this value. An active metaslab that -exceeds this threshold will no longer keep its active status allowing -better metaslabs to be selected. -.sp -Default value: \fB70\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_mg_fragmentation_threshold\fR (int) -.ad -.RS 12n +percentage is no more than this value. +An active metaslab that exceeds this threshold +will no longer keep its active status allowing better metaslabs to be selected. +. +.It Sy zfs_mg_fragmentation_threshold Ns = Ns Sy 95 Ns % Pq int Metaslab groups are considered eligible for allocations if their fragmentation metric (measured as a percentage) is less than or equal to -this value. If a metaslab group exceeds this threshold then it will be +this value. +If a metaslab group exceeds this threshold then it will be skipped unless all metaslab groups within the metaslab class have also crossed this threshold. -.sp -Default value: \fB95\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_mg_noalloc_threshold\fR (int) -.ad -.RS 12n -Defines a threshold at which metaslab groups should be eligible for -allocations. The value is expressed as a percentage of free space +. +.It Sy zfs_mg_noalloc_threshold Ns = Ns Sy 0 Ns % Pq int +Defines a threshold at which metaslab groups should be eligible for allocations. +The value is expressed as a percentage of free space beyond which a metaslab group is always eligible for allocations. If a metaslab group's free space is less than or equal to the threshold, the allocator will avoid allocating to that group -unless all groups in the pool have reached the threshold. Once all -groups have reached the threshold, all groups are allowed to accept -allocations. The default value of 0 disables the feature and causes -all metaslab groups to be eligible for allocations. - +unless all groups in the pool have reached the threshold. +Once all groups have reached the threshold, all groups are allowed to accept +allocations. +The default value of +.Sy 0 +disables the feature and causes all metaslab groups to be eligible for allocations. +.Pp This parameter allows one to deal with pools having heavily imbalanced vdevs such as would be the case when a new vdev has been added. Setting the threshold to a non-zero percentage will stop allocations from being made to vdevs that aren't filled to the specified percentage and allow lesser filled vdevs to acquire more allocations than they -otherwise would under the old \fBzfs_mg_alloc_failures\fR facility. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_ddt_data_is_special\fR (int) -.ad -.RS 12n +otherwise would under the old +.Sy zfs_mg_alloc_failures +facility. +. +.It Sy zfs_ddt_data_is_special Ns = Ns Sy 1 Ns | Ns 0 Pq int If enabled, ZFS will place DDT data into the special allocation class. -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_user_indirect_is_special\fR (int) -.ad -.RS 12n -If enabled, ZFS will place user data (both file and zvol) indirect blocks +. +.It Sy zfs_user_indirect_is_special Ns = Ns Sy 1 Ns | Ns 0 Pq int +If enabled, ZFS will place user data indirect blocks into the special allocation class. -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_multihost_history\fR (int) -.ad -.RS 12n -Historical statistics for the last N multihost updates will be available in -\fB/proc/spl/kstat/zfs//multihost\fR -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_multihost_interval\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_multihost_history Ns = Ns Sy 0 Pq int +Historical statistics for this many latest multihost updates will be available in +.Pa /proc/spl/kstat/zfs/ Ns Ao Ar pool Ac Ns Pa /multihost . +. +.It Sy zfs_multihost_interval Ns = Ns Sy 1000 Ns ms Po 1s Pc Pq ulong Used to control the frequency of multihost writes which are performed when the -\fBmultihost\fR pool property is on. This is one factor used to determine the +.Sy multihost +pool property is on. +This is one of the factors used to determine the length of the activity check during import. -.sp -The multihost write period is \fBzfs_multihost_interval / leaf-vdevs\fR -milliseconds. On average a multihost write will be issued for each leaf vdev -every \fBzfs_multihost_interval\fR milliseconds. In practice, the observed -period can vary with the I/O load and this observed value is the delay which is -stored in the uberblock. -.sp -Default value: \fB1000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_multihost_import_intervals\fR (uint) -.ad -.RS 12n -Used to control the duration of the activity test on import. Smaller values of -\fBzfs_multihost_import_intervals\fR will reduce the import time but increase -the risk of failing to detect an active pool. The total activity check time is -never allowed to drop below one second. -.sp +.Pp +The multihost write period is +.Sy zfs_multihost_interval / leaf-vdevs . +On average a multihost write will be issued for each leaf vdev +every +.Sy zfs_multihost_interval +milliseconds. +In practice, the observed period can vary with the I/O load +and this observed value is the delay which is stored in the uberblock. +. +.It Sy zfs_multihost_import_intervals Ns = Ns Sy 20 Pq uint +Used to control the duration of the activity test on import. +Smaller values of +.Sy zfs_multihost_import_intervals +will reduce the import time but increase +the risk of failing to detect an active pool. +The total activity check time is never allowed to drop below one second. +.Pp On import the activity check waits a minimum amount of time determined by -\fBzfs_multihost_interval * zfs_multihost_import_intervals\fR, or the same -product computed on the host which last had the pool imported (whichever is -greater). The activity check time may be further extended if the value of mmp +.Sy zfs_multihost_interval * zfs_multihost_import_intervals , +or the same product computed on the host which last had the pool imported, +whichever is greater. +The activity check time may be further extended if the value of MMP delay found in the best uberblock indicates actual multihost updates happened -at longer intervals than \fBzfs_multihost_interval\fR. A minimum value of -\fB100ms\fR is enforced. -.sp -A value of 0 is ignored and treated as if it was set to 1. -.sp -Default value: \fB20\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_multihost_fail_intervals\fR (uint) -.ad -.RS 12n +at longer intervals than +.Sy zfs_multihost_interval . +A minimum of +.Em 100ms +is enforced. +.Pp +.Sy 0 No is equivalent to Sy 1 . +. +.It Sy zfs_multihost_fail_intervals Ns = Ns Sy 10 Pq uint Controls the behavior of the pool when multihost write failures or delays are detected. -.sp -When \fBzfs_multihost_fail_intervals = 0\fR, multihost write failures or delays -are ignored. The failures will still be reported to the ZED which depending on +.Pp +When +.Sy 0 , +multihost write failures or delays are ignored. +The failures will still be reported to the ZED which depending on its configuration may take action such as suspending the pool or offlining a device. - -.sp -When \fBzfs_multihost_fail_intervals > 0\fR, the pool will be suspended if -\fBzfs_multihost_fail_intervals * zfs_multihost_interval\fR milliseconds pass -without a successful mmp write. This guarantees the activity test will see -mmp writes if the pool is imported. A value of 1 is ignored and treated as -if it was set to 2. This is necessary to prevent the pool from being suspended +.Pp +Otherwise, the pool will be suspended if +.Sy zfs_multihost_fail_intervals * zfs_multihost_interval +milliseconds pass without a successful MMP write. +This guarantees the activity test will see MMP writes if the pool is imported. +.Sy 1 No is equivalent to Sy 2 ; +this is necessary to prevent the pool from being suspended due to normal, small I/O latency variations. - -.sp -Default value: \fB10\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_no_scrub_io\fR (int) -.ad -.RS 12n -Set for no scrub I/O. This results in scrubs not actually scrubbing data and +. +.It Sy zfs_no_scrub_io Ns = Ns Sy 0 Ns | Ns 1 Pq int +Set to disable scrub I/O. +This results in scrubs not actually scrubbing data and simply doing a metadata crawl of the pool instead. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_no_scrub_prefetch\fR (int) -.ad -.RS 12n +. +.It Sy zfs_no_scrub_prefetch Ns = Ns Sy 0 Ns | Ns 1 Pq int Set to disable block prefetching for scrubs. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_nocacheflush\fR (int) -.ad -.RS 12n -Disable cache flush operations on disks when writing. Setting this will -cause pool corruption on power loss if a volatile out-of-order write cache -is enabled. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_nopwrite_enabled\fR (int) -.ad -.RS 12n -Enable NOP writes -.sp -Use \fB1\fR for yes (default) and \fB0\fR to disable. -.RE - -.sp -.ne 2 -.na -\fBzfs_dmu_offset_next_sync\fR (int) -.ad -.RS 12n -Enable forcing txg sync to find holes. When enabled forces ZFS to act -like prior versions when SEEK_HOLE or SEEK_DATA flags are used, which -when a dnode is dirty causes txg's to be synced so that this data can be -found. -.sp -Use \fB1\fR for yes and \fB0\fR to disable (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_pd_bytes_max\fR (int) -.ad -.RS 12n -The number of bytes which should be prefetched during a pool traversal -(eg: \fBzfs send\fR or other data crawling operations) -.sp -Default value: \fB52,428,800\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_per_txg_dirty_frees_percent \fR (ulong) -.ad -.RS 12n -Tunable to control percentage of dirtied indirect blocks from frees allowed -into one TXG. After this threshold is crossed, additional frees will wait until -the next TXG. -A value of zero will disable this throttle. -.sp -Default value: \fB5\fR, set to \fB0\fR to disable. -.RE - -.sp -.ne 2 -.na -\fBzfs_prefetch_disable\fR (int) -.ad -.RS 12n -This tunable disables predictive prefetch. Note that it leaves "prescient" -prefetch (e.g. prefetch for zfs send) intact. Unlike predictive prefetch, -prescient prefetch never issues i/os that end up not being needed, so it -can't hurt performance. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_qat_checksum_disable\fR (int) -.ad -.RS 12n -This tunable disables qat hardware acceleration for sha256 checksums. It -may be set after the zfs modules have been loaded to initialize the qat -hardware as long as support is compiled in and the qat driver is present. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_qat_compress_disable\fR (int) -.ad -.RS 12n -This tunable disables qat hardware acceleration for gzip compression. It -may be set after the zfs modules have been loaded to initialize the qat -hardware as long as support is compiled in and the qat driver is present. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_qat_encrypt_disable\fR (int) -.ad -.RS 12n -This tunable disables qat hardware acceleration for AES-GCM encryption. It -may be set after the zfs modules have been loaded to initialize the qat -hardware as long as support is compiled in and the qat driver is present. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_read_chunk_size\fR (long) -.ad -.RS 12n -Bytes to read per chunk -.sp -Default value: \fB1,048,576\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_read_history\fR (int) -.ad -.RS 12n -Historical statistics for the last N reads will be available in -\fB/proc/spl/kstat/zfs//reads\fR -.sp -Default value: \fB0\fR (no data is kept). -.RE - -.sp -.ne 2 -.na -\fBzfs_read_history_hits\fR (int) -.ad -.RS 12n +. +.It Sy zfs_nocacheflush Ns = Ns Sy 0 Ns | Ns 1 Pq int +Disable cache flush operations on disks when writing. +Setting this will cause pool corruption on power loss +if a volatile out-of-order write cache is enabled. +. +.It Sy zfs_nopwrite_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int +Allow no-operation writes. +The occurrence of nopwrites will further depend on other pool properties +.Pq i.a. the checksumming and compression algorithms . +. +.It Sy zfs_dmu_offset_next_sync Ns = Ns Sy 0 Ns | ns 1 Pq int +Enable forcing TXG sync to find holes. +When enabled forces ZFS to act like prior versions when +.Sy SEEK_HOLE No or Sy SEEK_DATA +flags are used, which, when a dnode is dirty, +causes TXGs to be synced so that this data can be found. +. +.It Sy zfs_pd_bytes_max Ns = Ns Sy 52428800 Ns B Po 50MB Pc Pq int +The number of bytes which should be prefetched during a pool traversal, like +.Nm zfs Cm send +or other data crawling operations. +. +.It Sy zfs_traverse_indirect_prefetch_limit Ns = Ns Sy 32 Pq int +The number of blocks pointed by indirect (non-L0) block which should be +prefetched during a pool traversal, like +.Nm zfs Cm send +or other data crawling operations. +. +.It Sy zfs_per_txg_dirty_frees_percent Ns = Ns Sy 5 Ns % Pq ulong +Control percentage of dirtied indirect blocks from frees allowed into one TXG. +After this threshold is crossed, additional frees will wait until the next TXG. +.Sy 0 No disables this throttle. +. +.It Sy zfs_prefetch_disable Ns = Ns Sy 0 Ns | Ns 1 Pq int +Disable predictive prefetch. +Note that it leaves "prescient" prefetch (for. e.g.\& +.Nm zfs Cm send ) +intact. +Unlike predictive prefetch, prescient prefetch never issues I/O +that ends up not being needed, so it can't hurt performance. +. +.It Sy zfs_qat_checksum_disable Ns = Ns Sy 0 Ns | Ns 1 Pq int +Disable QAT hardware acceleration for SHA256 checksums. +May be unset after the ZFS modules have been loaded to initialize the QAT +hardware as long as support is compiled in and the QAT driver is present. +. +.It Sy zfs_qat_compress_disable Ns = Ns Sy 0 Ns | Ns 1 Pq int +Disable QAT hardware acceleration for gzip compression. +May be unset after the ZFS modules have been loaded to initialize the QAT +hardware as long as support is compiled in and the QAT driver is present. +. +.It Sy zfs_qat_encrypt_disable Ns = Ns Sy 0 Ns | Ns 1 Pq int +Disable QAT hardware acceleration for AES-GCM encryption. +May be unset after the ZFS modules have been loaded to initialize the QAT +hardware as long as support is compiled in and the QAT driver is present. +. +.It Sy zfs_vnops_read_chunk_size Ns = Ns Sy 1048576 Ns B Po 1MB Pc Pq long +Bytes to read per chunk. +. +.It Sy zfs_read_history Ns = Ns Sy 0 Pq int +Historical statistics for this many latest reads will be available in +.Pa /proc/spl/kstat/zfs/ Ns Ao Ar pool Ac Ns Pa /reads . +. +.It Sy zfs_read_history_hits Ns = Ns Sy 0 Ns | Ns 1 Pq int Include cache hits in read history -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_rebuild_max_segment\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_rebuild_max_segment Ns = Ns Sy 1048576 Ns B Po 1MB Pc Pq ulong Maximum read segment size to issue when sequentially resilvering a top-level vdev. -.sp -Default value: \fB1,048,576\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_rebuild_scrub_enabled\fR (int) -.ad -.RS 12n +. +.It Sy zfs_rebuild_scrub_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int Automatically start a pool scrub when the last active sequential resilver completes in order to verify the checksums of all blocks which have been -resilvered. This option is enabled by default and is strongly recommended. -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_rebuild_vdev_limit\fR (ulong) -.ad -.RS 12n -Maximum amount of i/o that can be concurrently issued for a sequential +resilvered. +This is enabled by default and strongly recommended. +. +.It Sy zfs_rebuild_vdev_limit Ns = Ns Sy 33554432 Ns B Po 32MB Pc Pq ulong +Maximum amount of I/O that can be concurrently issued for a sequential resilver per leaf device, given in bytes. -.sp -Default value: \fB33,554,432\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_reconstruct_indirect_combinations_max\fR (int) -.ad -.RS 12na +. +.It Sy zfs_reconstruct_indirect_combinations_max Ns = Ns Sy 4096 Pq int If an indirect split block contains more than this many possible unique combinations when being reconstructed, consider it too computationally -expensive to check them all. Instead, try at most -\fBzfs_reconstruct_indirect_combinations_max\fR randomly-selected -combinations each time the block is accessed. This allows all segment -copies to participate fairly in the reconstruction when all combinations +expensive to check them all. +Instead, try at most this many randomly selected +combinations each time the block is accessed. +This allows all segment copies to participate fairly +in the reconstruction when all combinations cannot be checked and prevents repeated use of one bad copy. -.sp -Default value: \fB4096\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_recover\fR (int) -.ad -.RS 12n -Set to attempt to recover from fatal errors. This should only be used as a -last resort, as it typically results in leaked space, or worse. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_removal_ignore_errors\fR (int) -.ad -.RS 12n -.sp -Ignore hard IO errors during device removal. When set, if a device encounters -a hard IO error during the removal process the removal will not be cancelled. +. +.It Sy zfs_recover Ns = Ns Sy 0 Ns | Ns 1 Pq int +Set to attempt to recover from fatal errors. +This should only be used as a last resort, +as it typically results in leaked space, or worse. +. +.It Sy zfs_removal_ignore_errors Ns = Ns Sy 0 Ns | Ns 1 Pq int +Ignore hard IO errors during device removal. +When set, if a device encounters a hard IO error during the removal process +the removal will not be cancelled. This can result in a normally recoverable block becoming permanently damaged -and is not recommended. This should only be used as a last resort when the +and is hence not recommended. +This should only be used as a last resort when the pool cannot be returned to a healthy state prior to removing the device. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_removal_suspend_progress\fR (int) -.ad -.RS 12n -.sp +. +.It Sy zfs_removal_suspend_progress Ns = Ns Sy 0 Ns | Ns 1 Pq int This is used by the test suite so that it can ensure that certain actions happen while in the middle of a removal. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_remove_max_segment\fR (int) -.ad -.RS 12n -.sp +. +.It Sy zfs_remove_max_segment Ns = Ns Sy 16777216 Ns B Po 16MB Pc Pq int The largest contiguous segment that we will attempt to allocate when removing -a device. This can be no larger than 16MB. If there is a performance -problem with attempting to allocate large blocks, consider decreasing this. -.sp -Default value: \fB16,777,216\fR (16MB). -.RE - -.sp -.ne 2 -.na -\fBzfs_resilver_disable_defer\fR (int) -.ad -.RS 12n -Disables the \fBresilver_defer\fR feature, causing an operation that would -start a resilver to restart one in progress immediately. -.sp -Default value: \fB0\fR (feature enabled). -.RE - -.sp -.ne 2 -.na -\fBzfs_resilver_min_time_ms\fR (int) -.ad -.RS 12n -Resilvers are processed by the sync thread. While resilvering it will spend -at least this much time working on a resilver between txg flushes. -.sp -Default value: \fB3,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_scan_ignore_errors\fR (int) -.ad -.RS 12n -If set to a nonzero value, remove the DTL (dirty time list) upon -completion of a pool scan (scrub) even if there were unrepairable -errors. It is intended to be used during pool repair or recovery to +a device. +If there is a performance problem with attempting to allocate large blocks, +consider decreasing this. +The default value is also the maximum. +. +.It Sy zfs_resilver_disable_defer Ns = Ns Sy 0 Ns | Ns 1 Pq int +Ignore the +.Sy resilver_defer +feature, causing an operation that would start a resilver to +immediately restart the one in progress. +. +.It Sy zfs_resilver_min_time_ms Ns = Ns Sy 3000 Ns ms Po 3s Pc Pq int +Resilvers are processed by the sync thread. +While resilvering, it will spend at least this much time +working on a resilver between TXG flushes. +. +.It Sy zfs_scan_ignore_errors Ns = Ns Sy 0 Ns | Ns 1 Pq int +If set, remove the DTL (dirty time list) upon completion of a pool scan (scrub), +even if there were unrepairable errors. +Intended to be used during pool repair or recovery to stop resilvering when the pool is next imported. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_scrub_min_time_ms\fR (int) -.ad -.RS 12n -Scrubs are processed by the sync thread. While scrubbing it will spend -at least this much time working on a scrub between txg flushes. -.sp -Default value: \fB1,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_scan_checkpoint_intval\fR (int) -.ad -.RS 12n -To preserve progress across reboots the sequential scan algorithm periodically -needs to stop metadata scanning and issue all the verifications I/Os to disk. -The frequency of this flushing is determined by the -\fBzfs_scan_checkpoint_intval\fR tunable. -.sp -Default value: \fB7200\fR seconds (every 2 hours). -.RE - -.sp -.ne 2 -.na -\fBzfs_scan_fill_weight\fR (int) -.ad -.RS 12n -This tunable affects how scrub and resilver I/O segments are ordered. A higher -number indicates that we care more about how filled in a segment is, while a -lower number indicates we care more about the size of the extent without -considering the gaps within a segment. This value is only tunable upon module -insertion. Changing the value afterwards will have no affect on scrub or -resilver performance. -.sp -Default value: \fB3\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_scan_issue_strategy\fR (int) -.ad -.RS 12n -Determines the order that data will be verified while scrubbing or resilvering. -If set to \fB1\fR, data will be verified as sequentially as possible, given the -amount of memory reserved for scrubbing (see \fBzfs_scan_mem_lim_fact\fR). This -may improve scrub performance if the pool's data is very fragmented. If set to -\fB2\fR, the largest mostly-contiguous chunk of found data will be verified -first. By deferring scrubbing of small segments, we may later find adjacent data -to coalesce and increase the segment size. If set to \fB0\fR, zfs will use -strategy \fB1\fR during normal verification and strategy \fB2\fR while taking a -checkpoint. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_scan_legacy\fR (int) -.ad -.RS 12n -A value of 0 indicates that scrubs and resilvers will gather metadata in -memory before issuing sequential I/O. A value of 1 indicates that the legacy -algorithm will be used where I/O is initiated as soon as it is discovered. -Changing this value to 0 will not affect scrubs or resilvers that are already -in progress. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_scan_max_ext_gap\fR (int) -.ad -.RS 12n -Indicates the largest gap in bytes between scrub / resilver I/Os that will still -be considered sequential for sorting purposes. Changing this value will not +. +.It Sy zfs_scrub_min_time_ms Ns = Ns Sy 1000 Ns ms Po 1s Pc Pq int +Scrubs are processed by the sync thread. +While scrubbing, it will spend at least this much time +working on a scrub between TXG flushes. +. +.It Sy zfs_scan_checkpoint_intval Ns = Ns Sy 7200 Ns s Po 2h Pc Pq int +To preserve progress across reboots, the sequential scan algorithm periodically +needs to stop metadata scanning and issue all the verification I/O to disk. +The frequency of this flushing is determined by this tunable. +. +.It Sy zfs_scan_fill_weight Ns = Ns Sy 3 Pq int +This tunable affects how scrub and resilver I/O segments are ordered. +A higher number indicates that we care more about how filled in a segment is, +while a lower number indicates we care more about the size of the extent without +considering the gaps within a segment. +This value is only tunable upon module insertion. +Changing the value afterwards will have no affect on scrub or resilver performance. +. +.It Sy zfs_scan_issue_strategy Ns = Ns Sy 0 Pq int +Determines the order that data will be verified while scrubbing or resilvering: +.Bl -tag -compact -offset 4n -width "a" +.It Sy 1 +Data will be verified as sequentially as possible, given the +amount of memory reserved for scrubbing +.Pq see Sy zfs_scan_mem_lim_fact . +This may improve scrub performance if the pool's data is very fragmented. +.It Sy 2 +The largest mostly-contiguous chunk of found data will be verified first. +By deferring scrubbing of small segments, we may later find adjacent data +to coalesce and increase the segment size. +.It Sy 0 +.No Use strategy Sy 1 No during normal verification +.No and strategy Sy 2 No while taking a checkpoint. +.El +. +.It Sy zfs_scan_legacy Ns = Ns Sy 0 Ns | Ns 1 Pq int +If unset, indicates that scrubs and resilvers will gather metadata in +memory before issuing sequential I/O. +Otherwise indicates that the legacy algorithm will be used, +where I/O is initiated as soon as it is discovered. +Unsetting will not affect scrubs or resilvers that are already in progress. +. +.It Sy zfs_scan_max_ext_gap Ns = Ns Sy 2097152 Ns B Po 2MB Pc Pq int +Sets the largest gap in bytes between scrub/resilver I/O operations +that will still be considered sequential for sorting purposes. +Changing this value will not affect scrubs or resilvers that are already in progress. -.sp -Default value: \fB2097152 (2 MB)\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_scan_mem_lim_fact\fR (int) -.ad -.RS 12n +. +.It Sy zfs_scan_mem_lim_fact Ns = Ns Sy 20 Ns ^-1 Pq int Maximum fraction of RAM used for I/O sorting by sequential scan algorithm. This tunable determines the hard limit for I/O sorting memory usage. When the hard limit is reached we stop scanning metadata and start issuing -data verification I/O. This is done until we get below the soft limit. -.sp -Default value: \fB20\fR which is 5% of RAM (1/20). -.RE - -.sp -.ne 2 -.na -\fBzfs_scan_mem_lim_soft_fact\fR (int) -.ad -.RS 12n +data verification I/O. +This is done until we get below the soft limit. +. +.It Sy zfs_scan_mem_lim_soft_fact Ns = Ns Sy 20 Ns ^-1 Pq int The fraction of the hard limit used to determined the soft limit for I/O sorting -by the sequential scan algorithm. When we cross this limit from below no action -is taken. When we cross this limit from above it is because we are issuing -verification I/O. In this case (unless the metadata scan is done) we stop -issuing verification I/O and start scanning metadata again until we get to the -hard limit. -.sp -Default value: \fB20\fR which is 5% of the hard limit (1/20). -.RE - -.sp -.ne 2 -.na -\fBzfs_scan_strict_mem_lim\fR (int) -.ad -.RS 12n -Enforces tight memory limits on pool scans when a sequential scan is in -progress. When disabled the memory limit may be exceeded by fast disks. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_scan_suspend_progress\fR (int) -.ad -.RS 12n -Freezes a scrub/resilver in progress without actually pausing it. Intended for -testing/debugging. -.sp -Default value: \fB0\fR. -.RE - - -.sp -.ne 2 -.na -\fBzfs_scan_vdev_limit\fR (int) -.ad -.RS 12n +by the sequential scan algorithm. +When we cross this limit from below no action is taken. +When we cross this limit from above it is because we are issuing verification I/O. +In this case (unless the metadata scan is done) we stop issuing verification I/O +and start scanning metadata again until we get to the hard limit. +. +.It Sy zfs_scan_strict_mem_lim Ns = Ns Sy 0 Ns | Ns 1 Pq int +Enforce tight memory limits on pool scans when a sequential scan is in progress. +When disabled, the memory limit may be exceeded by fast disks. +. +.It Sy zfs_scan_suspend_progress Ns = Ns Sy 0 Ns | Ns 1 Pq int +Freezes a scrub/resilver in progress without actually pausing it. +Intended for testing/debugging. +. +.It Sy zfs_scan_vdev_limit Ns = Ns Sy 4194304 Ns B Po 4MB Pc Pq int Maximum amount of data that can be concurrently issued at once for scrubs and resilvers per leaf device, given in bytes. -.sp -Default value: \fB41943040\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_send_corrupt_data\fR (int) -.ad -.RS 12n -Allow sending of corrupt data (ignore read/checksum errors when sending data) -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_send_unmodified_spill_blocks\fR (int) -.ad -.RS 12n -Include unmodified spill blocks in the send stream. Under certain circumstances -previous versions of ZFS could incorrectly remove the spill block from an -existing object. Including unmodified copies of the spill blocks creates a -backwards compatible stream which will recreate a spill block if it was -incorrectly removed. -.sp -Use \fB1\fR for yes (default) and \fB0\fR for no. -.RE - -.sp -.ne 2 -.na -\fBzfs_send_no_prefetch_queue_ff\fR (int) -.ad -.RS 12n -The fill fraction of the \fBzfs send\fR internal queues. The fill fraction -controls the timing with which internal threads are woken up. -.sp -Default value: \fB20\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_send_no_prefetch_queue_length\fR (int) -.ad -.RS 12n -The maximum number of bytes allowed in \fBzfs send\fR's internal queues. -.sp -Default value: \fB1,048,576\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_send_queue_ff\fR (int) -.ad -.RS 12n -The fill fraction of the \fBzfs send\fR prefetch queue. The fill fraction -controls the timing with which internal threads are woken up. -.sp -Default value: \fB20\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_send_queue_length\fR (int) -.ad -.RS 12n -The maximum number of bytes allowed that will be prefetched by \fBzfs send\fR. +. +.It Sy zfs_send_corrupt_data Ns = Ns Sy 0 Ns | Ns 1 Pq int +Allow sending of corrupt data (ignore read/checksum errors when sending). +. +.It Sy zfs_send_unmodified_spill_blocks Ns = Ns Sy 1 Ns | Ns 0 Pq int +Include unmodified spill blocks in the send stream. +Under certain circumstances, previous versions of ZFS could incorrectly +remove the spill block from an existing object. +Including unmodified copies of the spill blocks creates a backwards-compatible +stream which will recreate a spill block if it was incorrectly removed. +. +.It Sy zfs_send_no_prefetch_queue_ff Ns = Ns Sy 20 Ns ^-1 Pq int +The fill fraction of the +.Nm zfs Cm send +internal queues. +The fill fraction controls the timing with which internal threads are woken up. +. +.It Sy zfs_send_no_prefetch_queue_length Ns = Ns Sy 1048576 Ns B Po 1MB Pc Pq int +The maximum number of bytes allowed in +.Nm zfs Cm send Ns 's +internal queues. +. +.It Sy zfs_send_queue_ff Ns = Ns Sy 20 Ns ^-1 Pq int +The fill fraction of the +.Nm zfs Cm send +prefetch queue. +The fill fraction controls the timing with which internal threads are woken up. +. +.It Sy zfs_send_queue_length Ns = Ns Sy 16777216 Ns B Po 16MB Pc Pq int +The maximum number of bytes allowed that will be prefetched by +.Nm zfs Cm send . This value must be at least twice the maximum block size in use. -.sp -Default value: \fB16,777,216\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_recv_queue_ff\fR (int) -.ad -.RS 12n -The fill fraction of the \fBzfs receive\fR queue. The fill fraction -controls the timing with which internal threads are woken up. -.sp -Default value: \fB20\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_recv_queue_length\fR (int) -.ad -.RS 12n -The maximum number of bytes allowed in the \fBzfs receive\fR queue. This value -must be at least twice the maximum block size in use. -.sp -Default value: \fB16,777,216\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_recv_write_batch_size\fR (int) -.ad -.RS 12n -The maximum amount of data (in bytes) that \fBzfs receive\fR will write in -one DMU transaction. This is the uncompressed size, even when receiving a -compressed send stream. This setting will not reduce the write size below -a single block. Capped at a maximum of 32MB -.sp -Default value: \fB1MB\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_override_estimate_recordsize\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_recv_queue_ff Ns = Ns Sy 20 Ns ^-1 Pq int +The fill fraction of the +.Nm zfs Cm receive +queue. +The fill fraction controls the timing with which internal threads are woken up. +. +.It Sy zfs_recv_queue_length Ns = Ns Sy 16777216 Ns B Po 16MB Pc Pq int +The maximum number of bytes allowed in the +.Nm zfs Cm receive +queue. +This value must be at least twice the maximum block size in use. +. +.It Sy zfs_recv_write_batch_size Ns = Ns Sy 1048576 Ns B Po 1MB Pc Pq int +The maximum amount of data, in bytes, that +.Nm zfs Cm receive +will write in one DMU transaction. +This is the uncompressed size, even when receiving a compressed send stream. +This setting will not reduce the write size below a single block. +Capped at a maximum of +.Sy 32MB . +. +.It Sy zfs_override_estimate_recordsize Ns = Ns Sy 0 Ns | Ns 1 Pq ulong Setting this variable overrides the default logic for estimating block -sizes when doing a zfs send. The default heuristic is that the average -block size will be the current recordsize. Override this value if most data -in your dataset is not of that size and you require accurate zfs send size -estimates. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_sync_pass_deferred_free\fR (int) -.ad -.RS 12n -Flushing of data to disk is done in passes. Defer frees starting in this pass -.sp -Default value: \fB2\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_spa_discard_memory_limit\fR (int) -.ad -.RS 12n +sizes when doing a +.Nm zfs Cm send . +The default heuristic is that the average block size +will be the current recordsize. +Override this value if most data in your dataset is not of that size +and you require accurate zfs send size estimates. +. +.It Sy zfs_sync_pass_deferred_free Ns = Ns Sy 2 Pq int +Flushing of data to disk is done in passes. +Defer frees starting in this pass. +. +.It Sy zfs_spa_discard_memory_limit Ns = Ns Sy 16777216 Ns B Po 16MB Pc Pq int Maximum memory used for prefetching a checkpoint's space map on each vdev while discarding the checkpoint. -.sp -Default value: \fB16,777,216\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_special_class_metadata_reserve_pct\fR (int) -.ad -.RS 12n +. +.It Sy zfs_special_class_metadata_reserve_pct Ns = Ns Sy 25 Ns % Pq int Only allow small data blocks to be allocated on the special and dedup vdev -types when the available free space percentage on these vdevs exceeds this -value. This ensures reserved space is available for pool meta data as the +types when the available free space percentage on these vdevs exceeds this value. +This ensures reserved space is available for pool metadata as the special vdevs approach capacity. -.sp -Default value: \fB25\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_sync_pass_dont_compress\fR (int) -.ad -.RS 12n -Starting in this sync pass, we disable compression (including of metadata). +. +.It Sy zfs_sync_pass_dont_compress Ns = Ns Sy 8 Pq int +Starting in this sync pass, disable compression (including of metadata). With the default setting, in practice, we don't have this many sync passes, so this has no effect. -.sp +.Pp The original intent was that disabling compression would help the sync passes -to converge. However, in practice disabling compression increases the average -number of sync passes, because when we turn compression off, a lot of block's -size will change and thus we have to re-allocate (not overwrite) them. It -also increases the number of 128KB allocations (e.g. for indirect blocks and -spacemaps) because these will not be compressed. The 128K allocations are -especially detrimental to performance on highly fragmented systems, which may -have very few free segments of this size, and may need to load new metaslabs -to satisfy 128K allocations. -.sp -Default value: \fB8\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_sync_pass_rewrite\fR (int) -.ad -.RS 12n -Rewrite new block pointers starting in this pass -.sp -Default value: \fB2\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_sync_taskq_batch_pct\fR (int) -.ad -.RS 12n -This controls the number of threads used by the dp_sync_taskq. The default -value of 75% will create a maximum of one thread per cpu. -.sp -Default value: \fB75\fR%. -.RE - -.sp -.ne 2 -.na -\fBzfs_trim_extent_bytes_max\fR (uint) -.ad -.RS 12n -Maximum size of TRIM command. Ranges larger than this will be split in to -chunks no larger than \fBzfs_trim_extent_bytes_max\fR bytes before being -issued to the device. -.sp -Default value: \fB134,217,728\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_trim_extent_bytes_min\fR (uint) -.ad -.RS 12n -Minimum size of TRIM commands. TRIM ranges smaller than this will be skipped -unless they're part of a larger range which was broken in to chunks. This is -done because it's common for these small TRIMs to negatively impact overall -performance. This value can be set to 0 to TRIM all unallocated space. -.sp -Default value: \fB32,768\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_trim_metaslab_skip\fR (uint) -.ad -.RS 12n -Skip uninitialized metaslabs during the TRIM process. This option is useful -for pools constructed from large thinly-provisioned devices where TRIM -operations are slow. As a pool ages an increasing fraction of the pools -metaslabs will be initialized progressively degrading the usefulness of -this option. This setting is stored when starting a manual TRIM and will +to converge. +However, in practice, disabling compression increases +the average number of sync passes; because when we turn compression off, +many blocks' size will change, and thus we have to re-allocate +(not overwrite) them. +It also increases the number of +.Em 128kB +allocations (e.g. for indirect blocks and spacemaps) +because these will not be compressed. +The +.Em 128kB +allocations are especially detrimental to performance +on highly fragmented systems, which may have very few free segments of this size, +and may need to load new metaslabs to satisfy these allocations. +. +.It Sy zfs_sync_pass_rewrite Ns = Ns Sy 2 Pq int +Rewrite new block pointers starting in this pass. +. +.It Sy zfs_sync_taskq_batch_pct Ns = Ns Sy 75 Ns % Pq int +This controls the number of threads used by +.Sy dp_sync_taskq . +The default value of +.Sy 75% +will create a maximum of one thread per CPU. +. +.It Sy zfs_trim_extent_bytes_max Ns = Ns Sy 134217728 Ns B Po 128MB Pc Pq uint +Maximum size of TRIM command. +Larger ranges will be split into chunks no larger than this value before issuing. +. +.It Sy zfs_trim_extent_bytes_min Ns = Ns Sy 32768 Ns B Po 32kB Pc Pq uint +Minimum size of TRIM commands. +TRIM ranges smaller than this will be skipped, +unless they're part of a larger range which was chunked. +This is done because it's common for these small TRIMs +to negatively impact overall performance. +. +.It Sy zfs_trim_metaslab_skip Ns = Ns Sy 0 Ns | Ns 1 Pq uint +Skip uninitialized metaslabs during the TRIM process. +This option is useful for pools constructed from large thinly-provisioned devices +where TRIM operations are slow. +As a pool ages, an increasing fraction of the pool's metaslabs +will be initialized, progressively degrading the usefulness of this option. +This setting is stored when starting a manual TRIM and will persist for the duration of the requested TRIM. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_trim_queue_limit\fR (uint) -.ad -.RS 12n -Maximum number of queued TRIMs outstanding per leaf vdev. The number of -concurrent TRIM commands issued to the device is controlled by the -\fBzfs_vdev_trim_min_active\fR and \fBzfs_vdev_trim_max_active\fR module -options. -.sp -Default value: \fB10\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_trim_txg_batch\fR (uint) -.ad -.RS 12n -The number of transaction groups worth of frees which should be aggregated -before TRIM operations are issued to the device. This setting represents a -trade-off between issuing larger, more efficient TRIM operations and the -delay before the recently trimmed space is available for use by the device. -.sp +. +.It Sy zfs_trim_queue_limit Ns = Ns Sy 10 Pq uint +Maximum number of queued TRIMs outstanding per leaf vdev. +The number of concurrent TRIM commands issued to the device is controlled by +.Sy zfs_vdev_trim_min_active No and Sy zfs_vdev_trim_max_active . +. +.It Sy zfs_trim_txg_batch Ns = Ns Sy 32 Pq uint +The number of transaction groups' worth of frees which should be aggregated +before TRIM operations are issued to the device. +This setting represents a trade-off between issuing larger, +more efficient TRIM operations and the delay +before the recently trimmed space is available for use by the device. +.Pp Increasing this value will allow frees to be aggregated for a longer time. -This will result is larger TRIM operations and potentially increased memory -usage. Decreasing this value will have the opposite effect. The default -value of 32 was determined to be a reasonable compromise. -.sp -Default value: \fB32\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_txg_history\fR (int) -.ad -.RS 12n -Historical statistics for the last N txgs will be available in -\fB/proc/spl/kstat/zfs//txgs\fR -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_txg_timeout\fR (int) -.ad -.RS 12n -Flush dirty data to disk at least every N seconds (maximum txg duration) -.sp -Default value: \fB5\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_aggregate_trim\fR (int) -.ad -.RS 12n -Allow TRIM I/Os to be aggregated. This is normally not helpful because -the extents to be trimmed will have been already been aggregated by the -metaslab. This option is provided for debugging and performance analysis. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_aggregation_limit\fR (int) -.ad -.RS 12n -Max vdev I/O aggregation size -.sp -Default value: \fB1,048,576\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_aggregation_limit_non_rotating\fR (int) -.ad -.RS 12n -Max vdev I/O aggregation size for non-rotating media -.sp -Default value: \fB131,072\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_cache_bshift\fR (int) -.ad -.RS 12n -Shift size to inflate reads too -.sp -Default value: \fB16\fR (effectively 65536). -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_cache_max\fR (int) -.ad -.RS 12n -Inflate reads smaller than this value to meet the \fBzfs_vdev_cache_bshift\fR -size (default 64k). -.sp -Default value: \fB16384\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_cache_size\fR (int) -.ad -.RS 12n +This will result is larger TRIM operations and potentially increased memory usage. +Decreasing this value will have the opposite effect. +The default of +.Sy 32 +was determined to be a reasonable compromise. +. +.It Sy zfs_txg_history Ns = Ns Sy 0 Pq int +Historical statistics for this many latest TXGs will be available in +.Pa /proc/spl/kstat/zfs/ Ns Ao Ar pool Ac Ns Pa /TXGs . +. +.It Sy zfs_txg_timeout Ns = Ns Sy 5 Ns s Pq int +Flush dirty data to disk at least every this many seconds (maximum TXG duration). +. +.It Sy zfs_vdev_aggregate_trim Ns = Ns Sy 0 Ns | Ns 1 Pq int +Allow TRIM I/Os to be aggregated. +This is normally not helpful because the extents to be trimmed +will have been already been aggregated by the metaslab. +This option is provided for debugging and performance analysis. +. +.It Sy zfs_vdev_aggregation_limit Ns = Ns Sy 1048576 Ns B Po 1MB Pc Pq int +Max vdev I/O aggregation size. +. +.It Sy zfs_vdev_aggregation_limit_non_rotating Ns = Ns Sy 131072 Ns B Po 128kB Pc Pq int +Max vdev I/O aggregation size for non-rotating media. +. +.It Sy zfs_vdev_cache_bshift Ns = Ns Sy 16 Po 64kB Pc Pq int +Shift size to inflate reads to. +. +.It Sy zfs_vdev_cache_max Ns = Ns Sy 16384 Ns B Po 16kB Pc Pq int +Inflate reads smaller than this value to meet the +.Sy zfs_vdev_cache_bshift +size +.Pq default Sy 64kB . +. +.It Sy zfs_vdev_cache_size Ns = Ns Sy 0 Pq int Total size of the per-disk cache in bytes. -.sp -Currently this feature is disabled as it has been found to not be helpful +.Pp +Currently this feature is disabled, as it has been found to not be helpful for performance and in some cases harmful. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_mirror_rotating_inc\fR (int) -.ad -.RS 12n +. +.It Sy zfs_vdev_mirror_rotating_inc Ns = Ns Sy 0 Pq int A number by which the balancing algorithm increments the load calculation for -the purpose of selecting the least busy mirror member when an I/O immediately -follows its predecessor on rotational vdevs for the purpose of making decisions -based on load. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_mirror_rotating_seek_inc\fR (int) -.ad -.RS 12n +the purpose of selecting the least busy mirror member when an I/O operation +immediately follows its predecessor on rotational vdevs +for the purpose of making decisions based on load. +. +.It Sy zfs_vdev_mirror_rotating_seek_inc Ns = Ns Sy 5 Pq int A number by which the balancing algorithm increments the load calculation for -the purpose of selecting the least busy mirror member when an I/O lacks -locality as defined by the zfs_vdev_mirror_rotating_seek_offset. I/Os within -this that are not immediately following the previous I/O are incremented by -half. -.sp -Default value: \fB5\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_mirror_rotating_seek_offset\fR (int) -.ad -.RS 12n -The maximum distance for the last queued I/O in which the balancing algorithm -considers an I/O to have locality. -See the section "ZFS I/O SCHEDULER". -.sp -Default value: \fB1048576\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_mirror_non_rotating_inc\fR (int) -.ad -.RS 12n +the purpose of selecting the least busy mirror member when an I/O operation +lacks locality as defined by +.Sy zfs_vdev_mirror_rotating_seek_offset . +Operations within this that are not immediately following the previous operation +are incremented by half. +. +.It Sy zfs_vdev_mirror_rotating_seek_offset Ns = Ns Sy 1048576 Ns B Po 1MB Pc Pq int +The maximum distance for the last queued I/O operation in which +the balancing algorithm considers an operation to have locality. +.No See Sx ZFS I/O SCHEDULER . +. +.It Sy zfs_vdev_mirror_non_rotating_inc Ns = Ns Sy 0 Pq int A number by which the balancing algorithm increments the load calculation for the purpose of selecting the least busy mirror member on non-rotational vdevs -when I/Os do not immediately follow one another. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_mirror_non_rotating_seek_inc\fR (int) -.ad -.RS 12n +when I/O operations do not immediately follow one another. +. +.It Sy zfs_vdev_mirror_non_rotating_seek_inc Ns = Ns Sy 1 Pq int A number by which the balancing algorithm increments the load calculation for -the purpose of selecting the least busy mirror member when an I/O lacks -locality as defined by the zfs_vdev_mirror_rotating_seek_offset. I/Os within -this that are not immediately following the previous I/O are incremented by -half. -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_read_gap_limit\fR (int) -.ad -.RS 12n -Aggregate read I/O operations if the gap on-disk between them is within this +the purpose of selecting the least busy mirror member when an I/O operation lacks +locality as defined by the +.Sy zfs_vdev_mirror_rotating_seek_offset . +Operations within this that are not immediately following the previous operation +are incremented by half. +. +.It Sy zfs_vdev_read_gap_limit Ns = Ns Sy 32768 Ns B Po 32kB Pc Pq int +Aggregate read I/O operations if the on-disk gap between them is within this threshold. -.sp -Default value: \fB32,768\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_write_gap_limit\fR (int) -.ad -.RS 12n -Aggregate write I/O over gap -.sp -Default value: \fB4,096\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_raidz_impl\fR (string) -.ad -.RS 12n -Parameter for selecting raidz parity implementation to use. - -Options marked (always) below may be selected on module load as they are -supported on all systems. -The remaining options may only be set after the module is loaded, as they -are available only if the implementations are compiled in and supported -on the running system. - -Once the module is loaded, the content of -/sys/module/zfs/parameters/zfs_vdev_raidz_impl will show available options -with the currently selected one enclosed in []. -Possible options are: - fastest - (always) implementation selected using built-in benchmark - original - (always) original raidz implementation - scalar - (always) scalar raidz implementation - sse2 - implementation using SSE2 instruction set (64bit x86 only) - ssse3 - implementation using SSSE3 instruction set (64bit x86 only) - avx2 - implementation using AVX2 instruction set (64bit x86 only) - avx512f - implementation using AVX512F instruction set (64bit x86 only) - avx512bw - implementation using AVX512F & AVX512BW instruction sets (64bit x86 only) - aarch64_neon - implementation using NEON (Aarch64/64 bit ARMv8 only) - aarch64_neonx2 - implementation using NEON with more unrolling (Aarch64/64 bit ARMv8 only) - powerpc_altivec - implementation using Altivec (PowerPC only) -.sp -Default value: \fBfastest\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_vdev_scheduler\fR (charp) -.ad -.RS 12n -\fBDEPRECATED\fR: This option exists for compatibility with older user -configurations. It does nothing except print a warning to the kernel log if -set. -.sp -.RE - -.sp -.ne 2 -.na -\fBzfs_zevent_cols\fR (int) -.ad -.RS 12n -When zevents are logged to the console use this as the word wrap width. -.sp -Default value: \fB80\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_zevent_console\fR (int) -.ad -.RS 12n -Log events to the console -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzfs_zevent_len_max\fR (int) -.ad -.RS 12n -Max event queue length. A value of 0 will result in a calculated value which -increases with the number of CPUs in the system (minimum 64 events). Events -in the queue can be viewed with the \fBzpool events\fR command. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_zevent_retain_max\fR (int) -.ad -.RS 12n -Maximum recent zevent records to retain for duplicate checking. Setting -this value to zero disables duplicate detection. -.sp -Default value: \fB2000\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_zevent_retain_expire_secs\fR (int) -.ad -.RS 12n +. +.It Sy zfs_vdev_write_gap_limit Ns = Ns Sy 4096 Ns B Po 4kB Pc Pq int +Aggregate write I/O operations if the on-disk gap between them is within this +threshold. +. +.It Sy zfs_vdev_raidz_impl Ns = Ns Sy fastest Pq string +Select the raidz parity implementation to use. +.Pp +Variants that don't depend on CPU-specific features +may be selected on module load, as they are supported on all systems. +The remaining options may only be set after the module is loaded, +as they are available only if the implementations are compiled in +and supported on the running system. +.Pp +Once the module is loaded, +.Pa /sys/module/zfs/parameters/zfs_vdev_raidz_impl +will show the available options, +with the currently selected one enclosed in square brackets. +.Pp +.TS +lb l l . +fastest selected by built-in benchmark +original original implementation +scalar scalar implementation +sse2 SSE2 instruction set 64-bit x86 +ssse3 SSSE3 instruction set 64-bit x86 +avx2 AVX2 instruction set 64-bit x86 +avx512f AVX512F instruction set 64-bit x86 +avx512bw AVX512F & AVX512BW instruction sets 64-bit x86 +aarch64_neon NEON Aarch64/64-bit ARMv8 +aarch64_neonx2 NEON with more unrolling Aarch64/64-bit ARMv8 +powerpc_altivec Altivec PowerPC +.TE +. +.It Sy zfs_vdev_scheduler Pq charp +.Sy DEPRECATED . +Prints warning to kernel log for compatiblity. +. +.It Sy zfs_zevent_len_max Ns = Ns Sy 512 Pq int +Max event queue length. +Events in the queue can be viewed with +.Xr zpool-events 8 . +. +.It Sy zfs_zevent_retain_max Ns = Ns Sy 2000 Pq int +Maximum recent zevent records to retain for duplicate checking. +Setting this to +.Sy 0 +disables duplicate detection. +. +.It Sy zfs_zevent_retain_expire_secs Ns = Ns Sy 900 Ns s Po 15min Pc Pq int Lifespan for a recent ereport that was retained for duplicate checking. -.sp -Default value: \fB900\fR. -.RE - -.na -\fBzfs_zil_clean_taskq_maxalloc\fR (int) -.ad -.RS 12n -The maximum number of taskq entries that are allowed to be cached. When this -limit is exceeded transaction records (itxs) will be cleaned synchronously. -.sp -Default value: \fB1048576\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_zil_clean_taskq_minalloc\fR (int) -.ad -.RS 12n +. +.It Sy zfs_zil_clean_taskq_maxalloc Ns = Ns Sy 1048576 Pq int +The maximum number of taskq entries that are allowed to be cached. +When this limit is exceeded transaction records (itxs) +will be cleaned synchronously. +. +.It Sy zfs_zil_clean_taskq_minalloc Ns = Ns Sy 1024 Pq int The number of taskq entries that are pre-populated when the taskq is first created and are immediately available for use. -.sp -Default value: \fB1024\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_zil_clean_taskq_nthr_pct\fR (int) -.ad -.RS 12n -This controls the number of threads used by the dp_zil_clean_taskq. The default -value of 100% will create a maximum of one thread per cpu. -.sp -Default value: \fB100\fR%. -.RE - -.sp -.ne 2 -.na -\fBzil_maxblocksize\fR (int) -.ad -.RS 12n -This sets the maximum block size used by the ZIL. On very fragmented pools, -lowering this (typically to 36KB) can improve performance. -.sp -Default value: \fB131072\fR (128KB). -.RE - -.sp -.ne 2 -.na -\fBzil_nocacheflush\fR (int) -.ad -.RS 12n -Disable the cache flush commands that are normally sent to the disk(s) by -the ZIL after an LWB write has completed. Setting this will cause ZIL -corruption on power loss if a volatile out-of-order write cache is enabled. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzil_replay_disable\fR (int) -.ad -.RS 12n -Disable intent logging replay. Can be disabled for recovery from corrupted -ZIL -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzil_slog_bulk\fR (ulong) -.ad -.RS 12n +. +.It Sy zfs_zil_clean_taskq_nthr_pct Ns = Ns Sy 100 Ns % Pq int +This controls the number of threads used by +.Sy dp_zil_clean_taskq . +The default value of +.Sy 100% +will create a maximum of one thread per cpu. +. +.It Sy zil_maxblocksize Ns = Ns Sy 131072 Ns B Po 128kB Pc Pq int +This sets the maximum block size used by the ZIL. +On very fragmented pools, lowering this +.Pq typically to Sy 36kB +can improve performance. +. +.It Sy zil_nocacheflush Ns = Ns Sy 0 Ns | Ns 1 Pq int +Disable the cache flush commands that are normally sent to disk by +the ZIL after an LWB write has completed. +Setting this will cause ZIL corruption on power loss +if a volatile out-of-order write cache is enabled. +. +.It Sy zil_replay_disable Ns = Ns Sy 0 Ns | Ns 1 Pq int +Disable intent logging replay. +Can be disabled for recovery from corrupted ZIL. +. +.It Sy zil_slog_bulk Ns = Ns Sy 786432 Ns B Po 768kB Pc Pq ulong Limit SLOG write size per commit executed with synchronous priority. Any writes above that will be executed with lower (asynchronous) priority to limit potential SLOG device abuse by single active ZIL writer. -.sp -Default value: \fB786,432\fR. -.RE - -.sp -.ne 2 -.na -\fBzfs_embedded_slog_min_ms\fR (int) -.ad -.RS 12n -Usually, one metaslab from each (normal-class) vdev is dedicated for use by -the ZIL (to log synchronous writes). -However, if there are fewer than zfs_embedded_slog_min_ms metaslabs in the -vdev, this functionality is disabled. -This ensures that we don't set aside an unreasonable amount of space for the -ZIL. -.sp -Default value: \fB64\fR. -.RE - -.sp -.ne 2 -.na -\fBzio_deadman_log_all\fR (int) -.ad -.RS 12n -If non-zero, the zio deadman will produce debugging messages (see -\fBzfs_dbgmsg_enable\fR) for all zios, rather than only for leaf -zios possessing a vdev. This is meant to be used by developers to gain +. +.It Sy zfs_embedded_slog_min_ms Ns = Ns Sy 64 Pq int +Usually, one metaslab from each normal-class vdev is dedicated for use by +the ZIL to log synchronous writes. +However, if there are fewer than +.Sy zfs_embedded_slog_min_ms +metaslabs in the vdev, this functionality is disabled. +This ensures that we don't set aside an unreasonable amount of space for the ZIL. +. +.It Sy zio_deadman_log_all Ns = Ns Sy 0 Ns | Ns 1 Pq int +If non-zero, the zio deadman will produce debugging messages +.Pq see Sy zfs_dbgmsg_enable +for all zios, rather than only for leaf zios possessing a vdev. +This is meant to be used by developers to gain diagnostic information for hang conditions which don't involve a mutex -or other locking primitive; typically conditions in which a thread in +or other locking primitive: typically conditions in which a thread in the zio pipeline is looping indefinitely. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzio_decompress_fail_fraction\fR (int) -.ad -.RS 12n -If non-zero, this value represents the denominator of the probability that zfs -should induce a decompression failure. For instance, for a 5% decompression -failure rate, this value should be set to 20. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzio_slow_io_ms\fR (int) -.ad -.RS 12n -When an I/O operation takes more than \fBzio_slow_io_ms\fR milliseconds to -complete is marked as a slow I/O. Each slow I/O causes a delay zevent. Slow -I/O counters can be seen with "zpool status -s". - -.sp -Default value: \fB30,000\fR. -.RE - -.sp -.ne 2 -.na -\fBzio_dva_throttle_enabled\fR (int) -.ad -.RS 12n -Throttle block allocations in the I/O pipeline. This allows for -dynamic allocation distribution when devices are imbalanced. +. +.It Sy zio_slow_io_ms Ns = Ns Sy 30000 Ns ms Po 30s Pc Pq int +When an I/O operation takes more than this much time to complete, +it's marked as slow. +Each slow operation causes a delay zevent. +Slow I/O counters can be seen with +.Nm zpool Cm status Fl s . +. +.It Sy zio_dva_throttle_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int +Throttle block allocations in the I/O pipeline. +This allows for dynamic allocation distribution when devices are imbalanced. When enabled, the maximum number of pending allocations per top-level vdev -is limited by \fBzfs_vdev_queue_depth_pct\fR. -.sp -Default value: \fB1\fR. -.RE - -.sp -.ne 2 -.na -\fBzio_requeue_io_start_cut_in_line\fR (int) -.ad -.RS 12n -Prioritize requeued I/O -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzio_taskq_batch_pct\fR (uint) -.ad -.RS 12n -Percentage of online CPUs (or CPU cores, etc) which will run a worker thread -for I/O. These workers are responsible for I/O work such as compression and -checksum calculations. Fractional number of CPUs will be rounded down. -.sp -The default value of 75 was chosen to avoid using all CPUs which can result in -latency issues and inconsistent application performance, especially when high -compression is enabled. -.sp -Default value: \fB75\fR. -.RE - -.sp -.ne 2 -.na -\fBzvol_inhibit_dev\fR (uint) -.ad -.RS 12n -Do not create zvol device nodes. This may slightly improve startup time on +is limited by +.Sy zfs_vdev_queue_depth_pct . +. +.It Sy zio_requeue_io_start_cut_in_line Ns = Ns Sy 0 Ns | Ns 1 Pq int +Prioritize requeued I/O. +. +.It Sy zio_taskq_batch_pct Ns = Ns Sy 80 Ns % Pq uint +Percentage of online CPUs which will run a worker thread for I/O. +These workers are responsible for I/O work such as compression and +checksum calculations. +Fractional number of CPUs will be rounded down. +.Pp +The default value of +.Sy 80% +was chosen to avoid using all CPUs which can result in +latency issues and inconsistent application performance, +especially when slower compression and/or checksumming is enabled. +. +.It Sy zio_taskq_batch_tpq Ns = Ns Sy 0 Pq uint +Number of worker threads per taskq. +Lower values improve I/O ordering and CPU utilization, +while higher reduces lock contention. +.Pp +If +.Sy 0 , +generate a system-dependent value close to 6 threads per taskq. +. +.It Sy zvol_inhibit_dev Ns = Ns Sy 0 Ns | Ns 1 Pq uint +Do not create zvol device nodes. +This may slightly improve startup time on systems with a very large number of zvols. -.sp -Use \fB1\fR for yes and \fB0\fR for no (default). -.RE - -.sp -.ne 2 -.na -\fBzvol_major\fR (uint) -.ad -.RS 12n -Major number for zvol block devices -.sp -Default value: \fB230\fR. -.RE - -.sp -.ne 2 -.na -\fBzvol_max_discard_blocks\fR (ulong) -.ad -.RS 12n -Discard (aka TRIM) operations done on zvols will be done in batches of this -many blocks, where block size is determined by the \fBvolblocksize\fR property -of a zvol. -.sp -Default value: \fB16,384\fR. -.RE - -.sp -.ne 2 -.na -\fBzvol_prefetch_bytes\fR (uint) -.ad -.RS 12n -When adding a zvol to the system prefetch \fBzvol_prefetch_bytes\fR -from the start and end of the volume. Prefetching these regions -of the volume is desirable because they are likely to be accessed -immediately by \fBblkid(8)\fR or by the kernel scanning for a partition -table. -.sp -Default value: \fB131,072\fR. -.RE - -.sp -.ne 2 -.na -\fBzvol_request_sync\fR (uint) -.ad -.RS 12n -When processing I/O requests for a zvol submit them synchronously. This -effectively limits the queue depth to 1 for each I/O submitter. When set -to 0 requests are handled asynchronously by a thread pool. The number of -requests which can be handled concurrently is controller by \fBzvol_threads\fR. -.sp -Default value: \fB0\fR. -.RE - -.sp -.ne 2 -.na -\fBzvol_threads\fR (uint) -.ad -.RS 12n +. +.It Sy zvol_major Ns = Ns Sy 230 Pq uint +Major number for zvol block devices. +. +.It Sy zvol_max_discard_blocks Ns = Ns Sy 16384 Pq ulong +Discard (TRIM) operations done on zvols will be done in batches of this +many blocks, where block size is determined by the +.Sy volblocksize +property of a zvol. +. +.It Sy zvol_prefetch_bytes Ns = Ns Sy 131072 Ns B Po 128kB Pc Pq uint +When adding a zvol to the system, prefetch this many bytes +from the start and end of the volume. +Prefetching these regions of the volume is desirable, +because they are likely to be accessed immediately by +.Xr blkid 8 +or the kernel partitioner. +. +.It Sy zvol_request_sync Ns = Ns Sy 0 Ns | Ns 1 Pq uint +When processing I/O requests for a zvol, submit them synchronously. +This effectively limits the queue depth to +.Em 1 +for each I/O submitter. +When unset, requests are handled asynchronously by a thread pool. +The number of requests which can be handled concurrently is controlled by +.Sy zvol_threads . +. +.It Sy zvol_threads Ns = Ns Sy 32 Pq uint Max number of threads which can handle zvol I/O requests concurrently. -.sp -Default value: \fB32\fR. -.RE - -.sp -.ne 2 -.na -\fBzvol_volmode\fR (uint) -.ad -.RS 12n -Defines zvol block devices behaviour when \fBvolmode\fR is set to \fBdefault\fR. -Valid values are \fB1\fR (full), \fB2\fR (dev) and \fB3\fR (none). -.sp -Default value: \fB1\fR. -.RE - -.SH ZFS I/O SCHEDULER -ZFS issues I/O operations to leaf vdevs to satisfy and complete I/Os. -The I/O scheduler determines when and in what order those operations are -issued. The I/O scheduler divides operations into five I/O classes +. +.It Sy zvol_volmode Ns = Ns Sy 1 Pq uint +Defines zvol block devices behaviour when +.Sy volmode Ns = Ns Sy default : +.Bl -tag -compact -offset 4n -width "a" +.It Sy 1 +.No equivalent to Sy full +.It Sy 2 +.No equivalent to Sy dev +.It Sy 3 +.No equivalent to Sy none +.El +.El +. +.Sh ZFS I/O SCHEDULER +ZFS issues I/O operations to leaf vdevs to satisfy and complete I/O operations. +The scheduler determines when and in what order those operations are issued. +The scheduler divides operations into five I/O classes, prioritized in the following order: sync read, sync write, async read, -async write, and scrub/resilver. Each queue defines the minimum and -maximum number of concurrent operations that may be issued to the -device. In addition, the device has an aggregate maximum, -\fBzfs_vdev_max_active\fR. Note that the sum of the per-queue minimums -must not exceed the aggregate maximum. If the sum of the per-queue -maximums exceeds the aggregate maximum, then the number of active I/Os -may reach \fBzfs_vdev_max_active\fR, in which case no further I/Os will -be issued regardless of whether all per-queue minimums have been met. -.sp +async write, and scrub/resilver. +Each queue defines the minimum and maximum number of concurrent operations +that may be issued to the device. +In addition, the device has an aggregate maximum, +.Sy zfs_vdev_max_active . +Note that the sum of the per-queue minima must not exceed the aggregate maximum. +If the sum of the per-queue maxima exceeds the aggregate maximum, +then the number of active operations may reach +.Sy zfs_vdev_max_active , +in which case no further operations will be issued, +regardless of whether all per-queue minima have been met. +.Pp For many physical devices, throughput increases with the number of -concurrent operations, but latency typically suffers. Further, physical -devices typically have a limit at which more concurrent operations have no +concurrent operations, but latency typically suffers. +Furthermore, physical devices typically have a limit +at which more concurrent operations have no effect on throughput or can actually cause it to decrease. -.sp +.Pp The scheduler selects the next operation to issue by first looking for an -I/O class whose minimum has not been satisfied. Once all are satisfied and -the aggregate maximum has not been hit, the scheduler looks for classes -whose maximum has not been satisfied. Iteration through the I/O classes is -done in the order specified above. No further operations are issued if the -aggregate maximum number of concurrent operations has been hit or if there -are no operations queued for an I/O class that has not hit its maximum. -Every time an I/O is queued or an operation completes, the I/O scheduler -looks for new operations to issue. -.sp -In general, smaller max_active's will lead to lower latency of synchronous -operations. Larger max_active's may lead to higher overall throughput, -depending on underlying storage. -.sp -The ratio of the queues' max_actives determines the balance of performance -between reads, writes, and scrubs. E.g., increasing -\fBzfs_vdev_scrub_max_active\fR will cause the scrub or resilver to complete -more quickly, but reads and writes to have higher latency and lower throughput. -.sp -All I/O classes have a fixed maximum number of outstanding operations -except for the async write class. Asynchronous writes represent the data -that is committed to stable storage during the syncing stage for -transaction groups. Transaction groups enter the syncing state -periodically so the number of queued async writes will quickly burst up -and then bleed down to zero. Rather than servicing them as quickly as -possible, the I/O scheduler changes the maximum number of active async -write I/Os according to the amount of dirty data in the pool. Since -both throughput and latency typically increase with the number of +I/O class whose minimum has not been satisfied. +Once all are satisfied and the aggregate maximum has not been hit, +the scheduler looks for classes whose maximum has not been satisfied. +Iteration through the I/O classes is done in the order specified above. +No further operations are issued +if the aggregate maximum number of concurrent operations has been hit, +or if there are no operations queued for an I/O class that has not hit its maximum. +Every time an I/O operation is queued or an operation completes, +the scheduler looks for new operations to issue. +.Pp +In general, smaller +.Sy max_active Ns s +will lead to lower latency of synchronous operations. +Larger +.Sy max_active Ns s +may lead to higher overall throughput, depending on underlying storage. +.Pp +The ratio of the queues' +.Sy max_active Ns s +determines the balance of performance between reads, writes, and scrubs. +For example, increasing +.Sy zfs_vdev_scrub_max_active +will cause the scrub or resilver to complete more quickly, +but reads and writes to have higher latency and lower throughput. +.Pp +All I/O classes have a fixed maximum number of outstanding operations, +except for the async write class. +Asynchronous writes represent the data that is committed to stable storage +during the syncing stage for transaction groups. +Transaction groups enter the syncing state periodically, +so the number of queued async writes will quickly burst up +and then bleed down to zero. +Rather than servicing them as quickly as possible, +the I/O scheduler changes the maximum number of active async write operations +according to the amount of dirty data in the pool. +Since both throughput and latency typically increase with the number of concurrent operations issued to physical devices, reducing the burstiness in the number of concurrent operations also stabilizes the -response time of operations from other -- and in particular synchronous --- queues. In broad strokes, the I/O scheduler will issue more -concurrent operations from the async write queue as there's more dirty -data in the pool. -.sp -Async Writes -.sp +response time of operations from other – and in particular synchronous – queues. +In broad strokes, the I/O scheduler will issue more concurrent operations +from the async write queue as there's more dirty data in the pool. +. +.Ss Async Writes The number of concurrent operations issued for the async write I/O class -follows a piece-wise linear function defined by a few adjustable points. -.nf - - | o---------| <-- zfs_vdev_async_write_max_active +follows a piece-wise linear function defined by a few adjustable points: +.Bd -literal + | o---------| <-- \fBzfs_vdev_async_write_max_active\fP ^ | /^ | | | / | | active | / | | I/O | / | | count | / | | | / | | - |-------o | | <-- zfs_vdev_async_write_min_active + |-------o | | <-- \fBzfs_vdev_async_write_min_active\fP 0|_______^______|_________| - 0% | | 100% of zfs_dirty_data_max + 0% | | 100% of \fBzfs_dirty_data_max\fP | | - | `-- zfs_vdev_async_write_active_max_dirty_percent - `--------- zfs_vdev_async_write_active_min_dirty_percent - -.fi + | `-- \fBzfs_vdev_async_write_active_max_dirty_percent\fP + `--------- \fBzfs_vdev_async_write_active_min_dirty_percent\fP +.Ed +.Pp Until the amount of dirty data exceeds a minimum percentage of the dirty data allowed in the pool, the I/O scheduler will limit the number of -concurrent operations to the minimum. As that threshold is crossed, the -number of concurrent operations issued increases linearly to the maximum at -the specified maximum percentage of the dirty data allowed in the pool. -.sp +concurrent operations to the minimum. +As that threshold is crossed, the number of concurrent operations issued +increases linearly to the maximum at the specified maximum percentage +of the dirty data allowed in the pool. +.Pp Ideally, the amount of dirty data on a busy pool will stay in the sloped -part of the function between \fBzfs_vdev_async_write_active_min_dirty_percent\fR -and \fBzfs_vdev_async_write_active_max_dirty_percent\fR. If it exceeds the -maximum percentage, this indicates that the rate of incoming data is -greater than the rate that the backend storage can handle. In this case, we -must further throttle incoming writes, as described in the next section. - -.SH ZFS TRANSACTION DELAY +part of the function between +.Sy zfs_vdev_async_write_active_min_dirty_percent +and +.Sy zfs_vdev_async_write_active_max_dirty_percent . +If it exceeds the maximum percentage, +this indicates that the rate of incoming data is +greater than the rate that the backend storage can handle. +In this case, we must further throttle incoming writes, +as described in the next section. +. +.Sh ZFS TRANSACTION DELAY We delay transactions when we've determined that the backend storage isn't able to accommodate the rate of incoming writes. -.sp +.Pp If there is already a transaction waiting, we delay relative to when -that transaction will finish waiting. This way the calculated delay time -is independent of the number of threads concurrently executing -transactions. -.sp -If we are the only waiter, wait relative to when the transaction -started, rather than the current time. This credits the transaction for -"time already served", e.g. reading indirect blocks. -.sp -The minimum time for a transaction to take is calculated as: -.nf - min_time = zfs_delay_scale * (dirty - min) / (max - dirty) - min_time is then capped at 100 milliseconds. -.fi -.sp -The delay has two degrees of freedom that can be adjusted via tunables. The -percentage of dirty data at which we start to delay is defined by -\fBzfs_delay_min_dirty_percent\fR. This should typically be at or above -\fBzfs_vdev_async_write_active_max_dirty_percent\fR so that we only start to -delay after writing at full speed has failed to keep up with the incoming write -rate. The scale of the curve is defined by \fBzfs_delay_scale\fR. Roughly speaking, -this variable determines the amount of delay at the midpoint of the curve. -.sp -.nf +that transaction will finish waiting. +This way the calculated delay time +is independent of the number of threads concurrently executing transactions. +.Pp +If we are the only waiter, wait relative to when the transaction started, +rather than the current time. +This credits the transaction for "time already served", +e.g. reading indirect blocks. +.Pp +The minimum time for a transaction to take is calculated as +.Dl min_time = min( Ns Sy zfs_delay_scale No * (dirty - min) / (max - dirty), 100ms) +.Pp +The delay has two degrees of freedom that can be adjusted via tunables. +The percentage of dirty data at which we start to delay is defined by +.Sy zfs_delay_min_dirty_percent . +This should typically be at or above +.Sy zfs_vdev_async_write_active_max_dirty_percent , +so that we only start to delay after writing at full speed +has failed to keep up with the incoming write rate. +The scale of the curve is defined by +.Sy zfs_delay_scale . +Roughly speaking, this variable determines the amount of delay at the midpoint of the curve. +.Bd -literal delay 10ms +-------------------------------------------------------------*+ | *| @@ -4284,22 +2325,25 @@ delay 2ms + (midpoint) * + | | ** | 1ms + v *** + - | zfs_delay_scale ----------> ******** | + | \fBzfs_delay_scale\fP ----------> ******** | 0 +-------------------------------------*********----------------+ - 0% <- zfs_dirty_data_max -> 100% -.fi -.sp -Note that since the delay is added to the outstanding time remaining on the -most recent transaction, the delay is effectively the inverse of IOPS. -Here the midpoint of 500us translates to 2000 IOPS. The shape of the curve + 0% <- \fBzfs_dirty_data_max\fP -> 100% +.Ed +.Pp +Note, that since the delay is added to the outstanding time remaining on the +most recent transaction it's effectively the inverse of IOPS. +Here, the midpoint of +.Em 500us +translates to +.Em 2000 IOPS . +The shape of the curve was chosen such that small changes in the amount of accumulated dirty data -in the first 3/4 of the curve yield relatively small differences in the -amount of delay. -.sp +in the first three quarters of the curve yield relatively small differences +in the amount of delay. +.Pp The effects can be easier to understand when the amount of delay is -represented on a log scale: -.sp -.nf +represented on a logarithmic scale: +.Bd -literal delay 100ms +-------------------------------------------------------------++ + + @@ -4310,7 +2354,7 @@ delay | (midpoint) ** | + | ** + 1ms + v **** + - + zfs_delay_scale ----------> ***** + + + \fBzfs_delay_scale\fP ----------> ***** + | **** | + **** + 100us + ** + @@ -4322,12 +2366,14 @@ delay | | + + +--------------------------------------------------------------+ - 0% <- zfs_dirty_data_max -> 100% -.fi -.sp + 0% <- \fBzfs_dirty_data_max\fP -> 100% +.Ed +.Pp Note here that only as the amount of dirty data approaches its limit does -the delay start to increase rapidly. The goal of a properly tuned system -should be to keep the amount of dirty data out of that range by first -ensuring that the appropriate limits are set for the I/O scheduler to reach -optimal throughput on the backend storage, and then by changing the value -of \fBzfs_delay_scale\fR to increase the steepness of the curve. +the delay start to increase rapidly. +The goal of a properly tuned system should be to keep the amount of dirty data +out of that range by first ensuring that the appropriate limits are set +for the I/O scheduler to reach optimal throughput on the back-end storage, +and then by changing the value of +.Sy zfs_delay_scale +to increase the steepness of the curve. diff --git a/sys/contrib/openzfs/man/man5/zpool-features.5 b/sys/contrib/openzfs/man/man5/zpool-features.5 index c56b31e2d71..2b4cee545e8 100644 --- a/sys/contrib/openzfs/man/man5/zpool-features.5 +++ b/sys/contrib/openzfs/man/man5/zpool-features.5 @@ -1,4 +1,4 @@ -'\" te +.\" .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved. .\" Copyright (c) 2014, Joyent, Inc. All rights reserved. @@ -17,168 +17,195 @@ .\" Copyright (c) 2019, Klara Inc. .\" Copyright (c) 2019, Allan Jude .\" Copyright (c) 2021, Colm Buckley -.TH ZPOOL-FEATURES 5 "Aug 24, 2020" OpenZFS -.SH NAME -zpool\-features \- ZFS pool feature descriptions -.SH DESCRIPTION -.sp -.LP -ZFS pool on\-disk format versions are specified via "features" which replace -the old on\-disk format numbers (the last supported on\-disk format number is -28). To enable a feature on a pool use the \fBupgrade\fR subcommand of the -zpool(8) command, or set the \fBfeature@\fR\fIfeature_name\fR property -to \fBenabled\fR. Please also see the \fB"Compatibility feature sets"\fR +.\" +.Dd May 31, 2021 +.Dt ZPOOL-FEATURES 5 +.Os +. +.Sh NAME +.Nm zpool-features +.Nd description of ZFS pool features +. +.Sh DESCRIPTION +ZFS pool on-disk format versions are specified via "features" which replace +the old on-disk format numbers (the last supported on-disk format number is 28). +To enable a feature on a pool use the +.Nm zpool Cm upgrade , +or set the +.Sy feature Ns @ Ns Ar feature-name +property to +.Sy enabled . +Please also see the +.Sx Compatibility feature sets section for information on how sets of features may be enabled together. -.sp -.LP +.Pp The pool format does not affect file system version compatibility or the ability to send file systems between pools. -.sp -.LP -Since most features can be enabled independently of each other the on\-disk +.Pp +Since most features can be enabled independently of each other, the on-disk format of the pool is specified by the set of all features marked as -\fBactive\fR on the pool. If the pool was created by another software version +.Sy active +on the pool. +If the pool was created by another software version this set may include unsupported features. -.SS "Identifying features" -.sp -.LP -Every feature has a GUID of the form \fIcom.example:feature_name\fR. The -reversed DNS name ensures that the feature's GUID is unique across all ZFS -implementations. When unsupported features are encountered on a pool they will -be identified by their GUIDs. Refer to the documentation for the ZFS +. +.Ss Identifying features +Every feature has a GUID of the form +.Ar com.example : Ns Ar feature-name . +The reversed DNS name ensures that the feature's GUID is unique across all ZFS +implementations. +When unsupported features are encountered on a pool they will +be identified by their GUIDs. +Refer to the documentation for the ZFS implementation that created the pool for information about those features. -.sp -.LP -Each supported feature also has a short name. By convention a feature's short -name is the portion of its GUID which follows the ':' (e.g. -\fIcom.example:feature_name\fR would have the short name \fIfeature_name\fR), +.Pp +Each supported feature also has a short name. +By convention a feature's short name is the portion of its GUID which follows the +.Sq \&: +(i.e. +.Ar com.example : Ns Ar feature-name +would have the short name +.Ar feature-name ) , however a feature's short name may differ across ZFS implementations if following the convention would result in name conflicts. -.SS "Feature states" -.sp -.LP +. +.Ss Feature states Features can be in one of three states: -.sp -.ne 2 -.na -\fBactive\fR -.ad -.RS 12n -This feature's on\-disk format changes are in effect on the pool. Support for -this feature is required to import the pool in read\-write mode. If this -feature is not read-only compatible, support is also required to import the pool -in read\-only mode (see "Read\-only compatibility"). -.RE - -.sp -.ne 2 -.na -\fBenabled\fR -.ad -.RS 12n +.Bl -tag -width "disabled" +.It Sy active +This feature's on-disk format changes are in effect on the pool. +Support for this feature is required to import the pool in read-write mode. +If this feature is not read-only compatible, +support is also required to import the pool in read-only mode +.Pq see Sx Read-only compatibility . +.It Sy enabled An administrator has marked this feature as enabled on the pool, but the -feature's on\-disk format changes have not been made yet. The pool can still be -imported by software that does not support this feature, but changes may be made -to the on\-disk format at any time which will move the feature to the -\fBactive\fR state. Some features may support returning to the \fBenabled\fR -state after becoming \fBactive\fR. See feature\-specific documentation for -details. -.RE - -.sp -.ne 2 -.na -\fBdisabled\fR -.ad -.RS 12n -This feature's on\-disk format changes have not been made and will not be made -unless an administrator moves the feature to the \fBenabled\fR state. Features -cannot be disabled once they have been enabled. -.RE - -.sp -.LP +feature's on-disk format changes have not been made yet. +The pool can still be imported by software that does not support this feature, +but changes may be made to the on-disk format at any time +which will move the feature to the +.Sy active +state. +Some features may support returning to the +.Sy enabled +state after becoming +.Sy active . +See feature-specific documentation for details. +.It Sy disabled +This feature's on-disk format changes have not been made and will not be made +unless an administrator moves the feature to the +.Sy enabled +state. +Features cannot be disabled once they have been enabled. +.El +.Pp The state of supported features is exposed through pool properties of the form -\fIfeature@short_name\fR. -.SS "Read\-only compatibility" -.sp -.LP -Some features may make on\-disk format changes that do not interfere with other -software's ability to read from the pool. These features are referred to as -"read\-only compatible". If all unsupported features on a pool are read\-only -compatible, the pool can be imported in read\-only mode by setting the -\fBreadonly\fR property during import (see zpool(8) for details on -importing pools). -.SS "Unsupported features" -.sp -.LP -For each unsupported feature enabled on an imported pool a pool property -named \fIunsupported@feature_name\fR will indicate why the import was allowed -despite the unsupported feature. Possible values for this property are: - -.sp -.ne 2 -.na -\fBinactive\fR -.ad -.RS 12n -The feature is in the \fBenabled\fR state and therefore the pool's on\-disk +.Sy feature Ns @ Ns Ar short-name . +. +.Ss Read-only compatibility +Some features may make on-disk format changes that do not interfere with other +software's ability to read from the pool. +These features are referred to as +.Dq read-only compatible . +If all unsupported features on a pool are read-only compatible, +the pool can be imported in read-only mode by setting the +.Sy readonly +property during import (see +.Xr zpool-import 8 +for details on importing pools). +. +.Ss Unsupported features +For each unsupported feature enabled on an imported pool, a pool property +named +.Sy unsupported Ns @ Ns Ar feature-name +will indicate why the import was allowed despite the unsupported feature. +Possible values for this property are: +.Bl -tag -width "readonly" +.It Sy inactive +The feature is in the +.Sy enabled +state and therefore the pool's on-disk format is still compatible with software that does not support this feature. -.RE - -.sp -.ne 2 -.na -\fBreadonly\fR -.ad -.RS 12n -The feature is read\-only compatible and the pool has been imported in -read\-only mode. -.RE - -.SS "Feature dependencies" -.sp -.LP -Some features depend on other features being enabled in order to function -properly. Enabling a feature will automatically enable any features it -depends on. - -.SS "Compatibility feature sets" -.sp -.LP +.It Sy readonly +The feature is read-only compatible and the pool has been imported in +read-only mode. +.El +. +.Ss Feature dependencies +Some features depend on other features being enabled in order to function. +Enabling a feature will automatically enable any features it depends on. +. +.Ss Compatibility feature sets It is sometimes necessary for a pool to maintain compatibility with a -specific on\-disk format, by enabling and disabling particular features. The -\fBcompatibility\fR feature facilitates this by allowing feature sets to -be read from text files. When set to \fBoff\fR (the default); compatibility -feature sets are disabled (ie: all features are enabled); when set to -\fBlegacy\fR; no features are enabled. When set to a comma\-separated list -of filenames (each filename may either be an absolute path, or relative to -\fB/etc/zfs/compatibility.d\fR or \fB/usr/share/zfs/compatibility.d\fR) -the lists of requested features are read from those files, separated by -whitespace and/or commas. Only features present in all files are enabled. -.LP -Simple sanity checks are applied to the files; they must be between 1 and -16,384 bytes in size, and must end with a newline character. -.LP +specific on-disk format, by enabling and disabling particular features. +The +.Sy compatibility +feature facilitates this by allowing feature sets to be read from text files. +When set to +.Sy off +(the default), compatibility feature sets are disabled +(i.e. all features are enabled); when set to +.Sy legacy , +no features are enabled. +When set to a comma-separated list of filenames +(each filename may either be an absolute path, or relative to +.Pa /etc/zfs/compatibility.d +or +.Pa /usr/share/zfs/compatibility.d ) , +the lists of requested features are read from those files, +separated by whitespace and/or commas. +Only features present in all files are enabled. +.Pp +Simple sanity checks are applied to the files: +they must be between 1B and 16kB in size, and must end with a newline character. +.Pp The requested features are applied when a pool is created using -\fBzpool create \-o compatibility=...\fR and controls which features are -enabled when using \fBzpool upgrade\fR. \fBzpool status\fR +.Nm zpool Cm create Fl o Sy compatibility Ns = Ns Ar … +and controls which features are enabled when using +.Nm zpool Cm upgrade . +.Nm zpool Cm status will not show a warning about disabled features which are not part of the requested feature set. -.LP -By convention, compatibility files in \fB/usr/share/zfs/compatibility.d\fR -are provided by the distribution package, and include feature sets -supported by important versions of popular distribtions, and feature -sets commonly supported at the start of each year. Compatibility files -in \fB/etc/zfs/compatibility.d\fR, if present, will take precedence over -files with the same name in \fB/usr/share/zfs/compatibility.d\fR. -.LP -Compatibility files may include comments; any text from \fB#\fR to the end -of the line is ignored. -.LP -\fBExample:\fR -.EX -# \fBcat /usr/share/zfs/compatibility.d/grub2\fR +.Pp +The special value +.Sy legacy +prevents any features from being enabled, either via +.Nm zpool Cm upgrade +or +.Nm zpool Cm set Sy feature Ns @ Ns Ar feature-name Ns = Ns Sy enabled . +This setting also prevents pools from being upgraded to newer on-disk versions. +This is a safety measure to prevent new features from being +accidentally enabled, breaking compatibility. +.Pp +By convention, compatibility files in +.Pa /usr/share/zfs/compatibility.d +are provided by the distribution, and include feature sets +supported by important versions of popular distributions, and feature +sets commonly supported at the start of each year. +Compatibility files in +.Pa /etc/zfs/compatibility.d , +if present, will take precedence over files with the same name in +.Pa /usr/share/zfs/compatibility.d . +.Pp +If an unrecognized feature is found in these files, an error message will +be shown. +If the unrecognized feature is in a file in +.Pa /etc/zfs/compatibility.d , +this is treated as an error and processing will stop. +If the unrecognized feature is under +.Pa /usr/share/zfs/compatibility.d , +this is treated as a warning and processing will continue. +This difference is to allow distributions to include features +which might not be recognized by the currently-installed binaries. +.Pp +Compatibility files may include comments: +any text from +.Sq # +to the end of the line is ignored. +.Pp +.Sy Example : +.Bd -literal -compact -offset 4n +.No example# Nm cat Pa /usr/share/zfs/compatibility.d/grub2 # Features which are supported by GRUB2 async_destroy bookmarks @@ -192,875 +219,624 @@ large_blocks lz4_compress spacemap_histogram -# \fBzpool create \-o compatibility=grub2 bootpool vdev\fR -.EE -.LP -See \fBzpool\-create(8)\fR and \fBzpool\-upgrade(8)\fR for more information -on how these commands are affected by feature sets. -.SH FEATURES -.sp -.LP +.No example# Nm zpool Cm create Fl o Sy compatibility Ns = Ns Ar grub2 Ar bootpool Ar vdev +.Ed +.Pp +See +.Xr zpool-create 8 +and +.Xr zpool-upgrade 8 +for more information on how these commands are affected by feature sets. +. +.de feature +.It Sy \\$2 +.Bl -tag -compact -width "READ-ONLY COMPATIBLE" +.It GUID +.Sy \\$1:\\$2 +.if !"\\$4"" \{\ +.It DEPENDENCIES +\fB\\$4\fP\c +.if !"\\$5"" , \fB\\$5\fP\c +.if !"\\$6"" , \fB\\$6\fP\c +.if !"\\$7"" , \fB\\$7\fP\c +.if !"\\$8"" , \fB\\$8\fP\c +.if !"\\$9"" , \fB\\$9\fP\c +.\} +.It READ-ONLY COMPATIBLE +\\$3 +.El +.Pp +.. +. +.ds instant-never \ +.No This feature becomes Sy active No as soon as it is enabled \ +and will never return to being Sy enabled . +. +.ds remount-upgrade \ +.No Each filesystem will be upgraded automatically when remounted, \ +or when a new file is created under that filesystem. \ +The upgrade can also be triggered on filesystems via \ +Nm zfs Cm set Sy version Ns = Ns Sy current Ar fs . \ +No The upgrade process runs in the background and may take a while to complete \ +for filesystems containing large amounts of files. +. +.de checksum-spiel +When the +.Sy \\$1 +feature is set to +.Sy enabled , +the administrator can turn on the +.Sy \\$1 +checksum on any dataset using +.Nm zfs Cm set Sy checksum Ns = Ns Sy \\$1 Ar dset +.Po see Xr zfs-set 8 Pc . +This feature becomes +.Sy active +once a +.Sy checksum +property has been set to +.Sy \\$1 , +and will return to being +.Sy enabled +once all filesystems that have ever had their checksum set to +.Sy \\$1 +are destroyed. +.. +. +.Sh FEATURES The following features are supported on this system: - -.sp -.ne 2 -.na -\fBallocation_classes\fR -.ad -.RS 4n -.TS -l l . -GUID org.zfsonlinux:allocation_classes -READ\-ONLY COMPATIBLE yes -DEPENDENCIES none -.TE - +.Bl -tag -width Ds +.feature org.zfsonlinux allocation_classes yes This feature enables support for separate allocation classes. - -This feature becomes \fBactive\fR when a dedicated allocation class vdev -(dedup or special) is created with the \fBzpool create\fR or \fBzpool add\fR -subcommands. With device removal, it can be returned to the \fBenabled\fR +.Pp +This feature becomes +.Sy active +when a dedicated allocation class vdev (dedup or special) is created with the +.Nm zpool Cm create No or Nm zpool Cm add No commands . +With device removal, it can be returned to the +.Sy enabled state if all the dedicated allocation class vdevs are removed. -.RE - -.sp -.ne 2 -.na -\fBasync_destroy\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:async_destroy -READ\-ONLY COMPATIBLE yes -DEPENDENCIES none -.TE - +. +.feature com.delphix async_destroy yes Destroying a file system requires traversing all of its data in order to -return its used space to the pool. Without \fBasync_destroy\fR the file system -is not fully removed until all space has been reclaimed. If the destroy -operation is interrupted by a reboot or power outage the next attempt to open -the pool will need to complete the destroy operation synchronously. - -When \fBasync_destroy\fR is enabled the file system's data will be reclaimed -by a background process, allowing the destroy operation to complete without -traversing the entire file system. The background process is able to resume +return its used space to the pool. +Without +.Sy async_destroy , +the file system is not fully removed until all space has been reclaimed. +If the destroy operation is interrupted by a reboot or power outage, +the next attempt to open the pool will need to complete the destroy +operation synchronously. +.Pp +When +.Sy async_destroy +is enabled, the file system's data will be reclaimed by a background process, +allowing the destroy operation to complete +without traversing the entire file system. +The background process is able to resume interrupted destroys after the pool has been opened, eliminating the need -to finish interrupted destroys as part of the open operation. The amount -of space remaining to be reclaimed by the background process is available -through the \fBfreeing\fR property. - -This feature is only \fBactive\fR while \fBfreeing\fR is non\-zero. -.RE - -.sp -.ne 2 -.na -\fBbookmarks\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:bookmarks -READ\-ONLY COMPATIBLE yes -DEPENDENCIES extensible_dataset -.TE - -This feature enables use of the \fBzfs bookmark\fR subcommand. - -This feature is \fBactive\fR while any bookmarks exist in the pool. +to finish interrupted destroys as part of the open operation. +The amount of space remaining to be reclaimed by the background process +is available through the +.Sy freeing +property. +.Pp +This feature is only +.Sy active +while +.Sy freeing +is non-zero. +. +.feature com.delphix bookmarks yes extensible_dataset +This feature enables use of the +.Nm zfs Cm bookmark +command. +.Pp +This feature is +.Sy active +while any bookmarks exist in the pool. All bookmarks in the pool can be listed by running -\fBzfs list -t bookmark -r \fIpoolname\fR\fR. -.RE - -.sp -.ne 2 -.na -\fBbookmark_v2\fR -.ad -.RS 4n -.TS -l l . -GUID com.datto:bookmark_v2 -READ\-ONLY COMPATIBLE no -DEPENDENCIES bookmark, extensible_dataset -.TE - +.Nm zfs Cm list Fl t Sy bookmark Fl r Ar poolname . +. +.feature com.datto bookmark_v2 no bookmark extensible_dataset This feature enables the creation and management of larger bookmarks which are needed for other features in ZFS. - -This feature becomes \fBactive\fR when a v2 bookmark is created and will be -returned to the \fBenabled\fR state when all v2 bookmarks are destroyed. -.RE - -.sp -.ne 2 -.na -\fBbookmark_written\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:bookmark_written -READ\-ONLY COMPATIBLE no -DEPENDENCIES bookmark, extensible_dataset, bookmark_v2 -.TE - +.Pp +This feature becomes +.Sy active +when a v2 bookmark is created and will be returned to the +.Sy enabled +state when all v2 bookmarks are destroyed. +. +.feature com.delphix bookmark_written no bookmark extensible_dataset bookmark_v2 This feature enables additional bookmark accounting fields, enabling the -written# property (space written since a bookmark) and estimates of +.Sy written Ns # Ns Ar bookmark +property (space written since a bookmark) and estimates of send stream sizes for incrementals from bookmarks. - -This feature becomes \fBactive\fR when a bookmark is created and will be -returned to the \fBenabled\fR state when all bookmarks with these fields are destroyed. -.RE - -.sp -.ne 2 -.na -\fBdevice_rebuild\fR -.ad -.RS 4n -.TS -l l . -GUID org.openzfs:device_rebuild -READ\-ONLY COMPATIBLE yes -DEPENDENCIES none -.TE - -This feature enables the ability for the \fBzpool attach\fR and \fBzpool -replace\fR subcommands to perform sequential reconstruction (instead of -healing reconstruction) when resilvering. - +.Pp +This feature becomes +.Sy active +when a bookmark is created and will be +returned to the +.Sy enabled +state when all bookmarks with these fields are destroyed. +. +.feature org.openzfs device_rebuild yes +This feature enables the ability for the +.Nm zpool Cm attach +and +.Nm zpool Cm replace +commands to perform sequential reconstruction +(instead of healing reconstruction) when resilvering. +.Pp Sequential reconstruction resilvers a device in LBA order without immediately -verifying the checksums. Once complete a scrub is started which then verifies -the checksums. This approach allows full redundancy to be restored to the pool -in the minimum amount of time. This two phase approach will take longer than a -healing resilver when the time to verify the checksums is included. However, -unless there is additional pool damage no checksum errors should be reported -by the scrub. This feature is incompatible with raidz configurations. - -This feature becomes \fBactive\fR while a sequential resilver is in progress, -and returns to \fBenabled\fR when the resilver completes. -.RE - -.sp -.ne 2 -.na -\fBdevice_removal\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:device_removal -READ\-ONLY COMPATIBLE no -DEPENDENCIES none -.TE - -This feature enables the \fBzpool remove\fR subcommand to remove top-level -vdevs, evacuating them to reduce the total size of the pool. - -This feature becomes \fBactive\fR when the \fBzpool remove\fR subcommand is used -on a top-level vdev, and will never return to being \fBenabled\fR. -.RE - -.sp -.ne 2 -.na -\fBdraid\fR -.ad -.RS 4n -.TS -l l . -GUID org.openzfs:draid -READ\-ONLY COMPATIBLE no -DEPENDENCIES none -.TE - -This feature enables use of the \fBdraid\fR vdev type. dRAID is a variant -of raidz which provides integrated distributed hot spares that allow faster -resilvering while retaining the benefits of raidz. Data, parity, and spare -space are organized in redundancy groups and distributed evenly over all of -the devices. - -This feature becomes \fBactive\fR when creating a pool which uses the -\fBdraid\fR vdev type, or when adding a new \fBdraid\fR vdev to an -existing pool. -.RE - -.sp -.ne 2 -.na -\fBedonr\fR -.ad -.RS 4n -.TS -l l . -GUID org.illumos:edonr -READ\-ONLY COMPATIBLE no -DEPENDENCIES extensible_dataset -.TE - +verifying the checksums. +Once complete, a scrub is started, which then verifies the checksums. +This approach allows full redundancy to be restored to the pool +in the minimum amount of time. +This two-phase approach will take longer than a healing resilver +when the time to verify the checksums is included. +However, unless there is additional pool damage, +no checksum errors should be reported by the scrub. +This feature is incompatible with raidz configurations. +. +This feature becomes +.Sy active +while a sequential resilver is in progress, and returns to +.Sy enabled +when the resilver completes. +. +.feature com.delphix device_removal no +This feature enables the +.Nm zpool Cm remove +command to remove top-level vdevs, +evacuating them to reduce the total size of the pool. +.Pp +This feature becomes +.Sy active +when the +.Nm zpool Cm remove +command is used +on a top-level vdev, and will never return to being +.Sy enabled . +. +.feature org.openzfs draid no +This feature enables use of the +.Sy draid +vdev type. +dRAID is a variant of raidz which provides integrated distributed +hot spares that allow faster resilvering while retaining the benefits of raidz. +Data, parity, and spare space are organized in redundancy groups +and distributed evenly over all of the devices. +.Pp +This feature becomes +.Sy active +when creating a pool which uses the +.Sy draid +vdev type, or when adding a new +.Sy draid +vdev to an existing pool. +. +.feature org.illumos edonr no extensible_dataset This feature enables the use of the Edon-R hash algorithm for checksum, including for nopwrite (if compression is also enabled, an overwrite of a block whose checksum matches the data being written will be ignored). In an abundance of caution, Edon-R requires verification when used with -dedup: \fBzfs set dedup=edonr,verify\fR. See \fBzfs\fR(8). - +dedup: +.Nm zfs Cm set Sy dedup Ns = Ns Sy edonr , Ns Sy verify +.Po see Xr zfs-set 8 Pc . +.Pp Edon-R is a very high-performance hash algorithm that was part -of the NIST SHA-3 competition. It provides extremely high hash -performance (over 350% faster than SHA-256), but was not selected -because of its unsuitability as a general purpose secure hash algorithm. +of the NIST SHA-3 competition. +It provides extremely high hash performance (over 350% faster than SHA-256), +but was not selected because of its unsuitability +as a general purpose secure hash algorithm. This implementation utilizes the new salted checksumming functionality in ZFS, which means that the checksum is pre-seeded with a secret 256-bit random key (stored on the pool) before being fed the data block -to be checksummed. Thus the produced checksums are unique to a given -pool. - -When the \fBedonr\fR feature is set to \fBenabled\fR, the administrator -can turn on the \fBedonr\fR checksum on any dataset using the -\fBzfs set checksum=edonr\fR. See zfs(8). This feature becomes -\fBactive\fR once a \fBchecksum\fR property has been set to \fBedonr\fR, -and will return to being \fBenabled\fR once all filesystems that have -ever had their checksum set to \fBedonr\fR are destroyed. - -FreeBSD does not support the \fBedonr\fR feature. -.RE - -.sp -.ne 2 -.na -\fBembedded_data\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:embedded_data -READ\-ONLY COMPATIBLE no -DEPENDENCIES none -.TE - +to be checksummed. +Thus the produced checksums are unique to a given pool, +preventing hash collision attacks on systems with dedup. +.Pp +.checksum-spiel edonr +.Pp +.Fx does not support the Sy edonr No feature. +. +.feature com.delphix embedded_data no This feature improves the performance and compression ratio of -highly-compressible blocks. Blocks whose contents can compress to 112 bytes +highly-compressible blocks. +Blocks whose contents can compress to 112 bytes or smaller can take advantage of this feature. - +.Pp When this feature is enabled, the contents of highly-compressible blocks are stored in the block "pointer" itself (a misnomer in this case, as it contains -the compressed data, rather than a pointer to its location on disk). Thus -the space of the block (one sector, typically 512 bytes or 4KB) is saved, -and no additional i/o is needed to read and write the data block. - -This feature becomes \fBactive\fR as soon as it is enabled and will -never return to being \fBenabled\fR. -.RE - -.sp -.ne 2 -.na -\fBempty_bpobj\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:empty_bpobj -READ\-ONLY COMPATIBLE yes -DEPENDENCIES none -.TE - +the compressed data, rather than a pointer to its location on disk). +Thus the space of the block (one sector, typically 512B or 4kB) is saved, +and no additional I/O is needed to read and write the data block. +. +\*[instant-never] +. +.feature com.delphix empty_bpobj yes This feature increases the performance of creating and using a large number of snapshots of a single filesystem or volume, and also reduces the disk space required. - +.Pp When there are many snapshots, each snapshot uses many Block Pointer -Objects (bpobj's) to track blocks associated with that snapshot. -However, in common use cases, most of these bpobj's are empty. This -feature allows us to create each bpobj on-demand, thus eliminating the -empty bpobjs. - -This feature is \fBactive\fR while there are any filesystems, volumes, +Objects (bpobjs) to track blocks associated with that snapshot. +However, in common use cases, most of these bpobjs are empty. +This feature allows us to create each bpobj on-demand, +thus eliminating the empty bpobjs. +.Pp +This feature is +.Sy active +while there are any filesystems, volumes, or snapshots which were created after enabling this feature. -.RE - -.sp -.ne 2 -.na -\fBenabled_txg\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:enabled_txg -READ\-ONLY COMPATIBLE yes -DEPENDENCIES none -.TE - -Once this feature is enabled ZFS records the transaction group number -in which new features are enabled. This has no user-visible impact, -but other features may depend on this feature. - -This feature becomes \fBactive\fR as soon as it is enabled and will -never return to being \fBenabled\fB. -.RE - -.sp -.ne 2 -.na -\fBencryption\fR -.ad -.RS 4n -.TS -l l . -GUID com.datto:encryption -READ\-ONLY COMPATIBLE no -DEPENDENCIES bookmark_v2, extensible_dataset -.TE - +. +.feature com.delphix enabled_txg yes +Once this feature is enabled, ZFS records the transaction group number +in which new features are enabled. +This has no user-visible impact, but other features may depend on this feature. +.Pp +This feature becomes +.Sy active + as soon as it is enabled and will +never return to being +.Sy enabled . +. +.feature com.datto encryption no bookmark_v2 extensible_dataset This feature enables the creation and management of natively encrypted datasets. - -This feature becomes \fBactive\fR when an encrypted dataset is created and will -be returned to the \fBenabled\fR state when all datasets that use this feature -are destroyed. -.RE - -.sp -.ne 2 -.na -\fBextensible_dataset\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:extensible_dataset -READ\-ONLY COMPATIBLE no -DEPENDENCIES none -.TE - +.Pp +This feature becomes +.Sy active +when an encrypted dataset is created and will be returned to the +.Sy enabled +state when all datasets that use this feature are destroyed. +. +.feature com.delphix extensible_dataset no This feature allows more flexible use of internal ZFS data structures, and exists for other features to depend on. - -This feature will be \fBactive\fR when the first dependent feature uses it, -and will be returned to the \fBenabled\fR state when all datasets that use -this feature are destroyed. -.RE - -.sp -.ne 2 -.na -\fBfilesystem_limits\fR -.ad -.RS 4n -.TS -l l . -GUID com.joyent:filesystem_limits -READ\-ONLY COMPATIBLE yes -DEPENDENCIES extensible_dataset -.TE - -This feature enables filesystem and snapshot limits. These limits can be used -to control how many filesystems and/or snapshots can be created at the point in -the tree on which the limits are set. - -This feature is \fBactive\fR once either of the limit properties has been -set on a dataset. Once activated the feature is never deactivated. -.RE - -.sp -.ne 2 -.na -\fBhole_birth\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:hole_birth -READ\-ONLY COMPATIBLE no -DEPENDENCIES enabled_txg -.TE - +.Pp +This feature will be +.Sy active +when the first dependent feature uses it, and will be returned to the +.Sy enabled +state when all datasets that use this feature are destroyed. +. +.feature com.joyent filesystem_limits yes extensible_dataset +This feature enables filesystem and snapshot limits. +These limits can be used to control how many filesystems and/or snapshots +can be created at the point in the tree on which the limits are set. +.Pp +This feature is +.Sy active +once either of the limit properties has been set on a dataset. +Once activated the feature is never deactivated. +. +.feature com.delphix hole_birth no enabled_txg This feature has/had bugs, the result of which is that, if you do a -\fBzfs send -i\fR (or \fB-R\fR, since it uses \fB-i\fR) from an affected -dataset, the receiver will not see any checksum or other errors, but the -resulting destination snapshot will not match the source. Its use by -\fBzfs send -i\fR has been disabled by default. See the -\fBsend_holes_without_birth_time\fR module parameter in -zfs-module-parameters(5). - -This feature improves performance of incremental sends (\fBzfs send -i\fR) -and receives for objects with many holes. The most common case of -hole-filled objects is zvols. - -An incremental send stream from snapshot \fBA\fR to snapshot \fBB\fR -contains information about every block that changed between \fBA\fR and -\fBB\fR. Blocks which did not change between those snapshots can be +.Nm zfs Cm send Fl i +.Pq or Fl R , No since it uses Fl i +from an affected dataset, the receiving party will not see any checksum +or other errors, but the resulting destination snapshot +will not match the source. +Its use by +.Nm zfs Cm send Fl i +has been disabled by default +.Pq see Sy send_holes_without_birth_time No in Xr zfs-module-parameters 5 . +.Pp +This feature improves performance of incremental sends +.Pq Nm zfs Cm send Fl i +and receives for objects with many holes. +The most common case of hole-filled objects is zvols. +.Pp +An incremental send stream from snapshot +.Sy A No to snapshot Sy B +contains information about every block that changed between +.Sy A No and Sy B . +Blocks which did not change between those snapshots can be identified and omitted from the stream using a piece of metadata called -the 'block birth time', but birth times are not recorded for holes (blocks -filled only with zeroes). Since holes created after \fBA\fR cannot be -distinguished from holes created before \fBA\fR, information about every -hole in the entire filesystem or zvol is included in the send stream. - -For workloads where holes are rare this is not a problem. However, when -incrementally replicating filesystems or zvols with many holes (for -example a zvol formatted with another filesystem) a lot of time will +the "block birth time", but birth times are not recorded for holes +(blocks filled only with zeroes). +Since holes created after +.Sy A No cannot be distinguished from holes created before Sy A , +information about every hole in the entire filesystem or zvol +is included in the send stream. +.Pp +For workloads where holes are rare this is not a problem. +However, when incrementally replicating filesystems or zvols with many holes +(for example a zvol formatted with another filesystem) a lot of time will be spent sending and receiving unnecessary information about holes that already exist on the receiving side. - -Once the \fBhole_birth\fR feature has been enabled the block birth times -of all new holes will be recorded. Incremental sends between snapshots -created after this feature is enabled will use this new metadata to avoid -sending information about holes that already exist on the receiving side. - -This feature becomes \fBactive\fR as soon as it is enabled and will -never return to being \fBenabled\fB. -.RE - -.sp -.ne 2 -.na -\fBlarge_blocks\fR -.ad -.RS 4n -.TS -l l . -GUID org.open-zfs:large_blocks -READ\-ONLY COMPATIBLE no -DEPENDENCIES extensible_dataset -.TE - -The \fBlarge_block\fR feature allows the record size on a dataset to be -set larger than 128KB. - -This feature becomes \fBactive\fR once a dataset contains a file with -a block size larger than 128KB, and will return to being \fBenabled\fR once all -filesystems that have ever had their recordsize larger than 128KB are destroyed. -.RE - -.sp -.ne 2 -.na -\fBlarge_dnode\fR -.ad -.RS 4n -.TS -l l . -GUID org.zfsonlinux:large_dnode -READ\-ONLY COMPATIBLE no -DEPENDENCIES extensible_dataset -.TE - -The \fBlarge_dnode\fR feature allows the size of dnodes in a dataset to be -set larger than 512B. - -This feature becomes \fBactive\fR once a dataset contains an object with -a dnode larger than 512B, which occurs as a result of setting the -\fBdnodesize\fR dataset property to a value other than \fBlegacy\fR. The -feature will return to being \fBenabled\fR once all filesystems that -have ever contained a dnode larger than 512B are destroyed. Large dnodes -allow more data to be stored in the bonus buffer, thus potentially -improving performance by avoiding the use of spill blocks. -.RE - -.sp -.ne 2 -.na -\fB\fBlivelist\fR\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:livelist -READ\-ONLY COMPATIBLE yes -DEPENDENCIES none -.TE +.Pp +Once the +.Sy hole_birth +feature has been enabled the block birth times +of all new holes will be recorded. +Incremental sends between snapshots created after this feature is enabled +will use this new metadata to avoid sending information about holes that +already exist on the receiving side. +.Pp +\*[instant-never] +. +.feature org.open-zfs large_blocks no extensible_dataset +This feature allows the record size on a dataset to be set larger than 128kB. +.Pp +This feature becomes +.Sy active +once a dataset contains a file with a block size larger than 128kB, +and will return to being +.Sy enabled +once all filesystems that have ever had their recordsize larger than 128kB +are destroyed. +. +.feature org.zfsonlinux large_dnode no extensible_dataset +This feature allows the size of dnodes in a dataset to be set larger than 512B. +. +This feature becomes +.Sy active +once a dataset contains an object with a dnode larger than 512B, +which occurs as a result of setting the +.Sy dnodesize +dataset property to a value other than +.Sy legacy . +The feature will return to being +.Sy enabled +once all filesystems that have ever contained a dnode larger than 512B +are destroyed. +Large dnodes allow more data to be stored in the bonus buffer, +thus potentially improving performance by avoiding the use of spill blocks. +. +.feature com.delphix livelist yes This feature allows clones to be deleted faster than the traditional method when a large number of random/sparse writes have been made to the clone. All blocks allocated and freed after a clone is created are tracked by the the clone's livelist which is referenced during the deletion of the clone. -The feature is activated when a clone is created and remains active until all -clones have been destroyed. -.RE - -.sp -.ne 2 -.na -\fBlog_spacemap\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:log_spacemap -READ\-ONLY COMPATIBLE yes -DEPENDENCIES com.delphix:spacemap_v2 -.TE - +The feature is activated when a clone is created and remains +.Sy active +until all clones have been destroyed. +. +.feature com.delphix log_spacemap yes com.delphix:spacemap_v2 This feature improves performance for heavily-fragmented pools, -especially when workloads are heavy in random-writes. It does so by -logging all the metaslab changes on a single spacemap every TXG +especially when workloads are heavy in random-writes. +It does so by logging all the metaslab changes on a single spacemap every TXG instead of scattering multiple writes to all the metaslab spacemaps. - -This feature becomes \fBactive\fR as soon as it is enabled and will never -return to being \fBenabled\fR. -.RE - -.sp -.ne 2 -.na -\fBlz4_compress\fR -.ad -.RS 4n -.TS -l l . -GUID org.illumos:lz4_compress -READ\-ONLY COMPATIBLE no -DEPENDENCIES none -.TE - -\fBlz4\fR is a high-performance real-time compression algorithm that +.Pp +\*[instant-never] +. +.feature org.illumos lz4_compress no +.Sy lz4 +is a high-performance real-time compression algorithm that features significantly faster compression and decompression as well as a -higher compression ratio than the older \fBlzjb\fR compression. -Typically, \fBlz4\fR compression is approximately 50% faster on -compressible data and 200% faster on incompressible data than -\fBlzjb\fR. It is also approximately 80% faster on decompression, while -giving approximately 10% better compression ratio. - -When the \fBlz4_compress\fR feature is set to \fBenabled\fR, the -administrator can turn on \fBlz4\fR compression on any dataset on the -pool using the zfs(8) command. Please note that doing so will -immediately activate the \fBlz4_compress\fR feature on the underlying -pool using the zfs(8) command. Also, all newly written metadata -will be compressed with \fBlz4\fR algorithm. Since this feature is not -read-only compatible, this operation will render the pool unimportable -on systems without support for the \fBlz4_compress\fR feature. - -Booting off of \fBlz4\fR-compressed root pools is supported. - -This feature becomes \fBactive\fR as soon as it is enabled and will -never return to being \fBenabled\fB. -.RE - -.sp -.ne 2 -.na -\fBmulti_vdev_crash_dump\fR -.ad -.RS 4n -.TS -l l . -GUID com.joyent:multi_vdev_crash_dump -READ\-ONLY COMPATIBLE no -DEPENDENCIES none -.TE - +higher compression ratio than the older +.Sy lzjb +compression. +Typically, +.Sy lz4 +compression is approximately 50% faster on compressible data and 200% faster +on incompressible data than +.Sy lzjb . +It is also approximately 80% faster on decompression, +while giving approximately a 10% better compression ratio. +.Pp +When the +.Sy lz4_compress +feature is set to +.Sy enabled , +the administrator can turn on +.Sy lz4 +compression on any dataset on the pool using the +.Xr zfs-set 8 +command. +All newly written metadata will be compressed with the +.Sy lz4 +algorithm. +.Pp +\*[instant-never] +. +.feature com.joyent multi_vdev_crash_dump no This feature allows a dump device to be configured with a pool comprised -of multiple vdevs. Those vdevs may be arranged in any mirrored or raidz -configuration. - -When the \fBmulti_vdev_crash_dump\fR feature is set to \fBenabled\fR, -the administrator can use the \fBdumpadm\fR(1M) command to configure a -dump device on a pool comprised of multiple vdevs. - -Under FreeBSD and Linux this feature is registered for compatibility but not -used. New pools created under FreeBSD and Linux will have the feature -\fBenabled\fR but will never transition to \fB\fBactive\fR. This functionality -is not required in order to support crash dumps under FreeBSD and Linux. -Existing pools where this feature is \fB\fBactive\fR can be imported. -.RE - -.sp -.ne 2 -.na -\fBobsolete_counts\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:obsolete_counts -READ\-ONLY COMPATIBLE yes -DEPENDENCIES device_removal -.TE - -This feature is an enhancement of device_removal, which will over time -reduce the memory used to track removed devices. When indirect blocks -are freed or remapped, we note that their part of the indirect mapping -is "obsolete", i.e. no longer needed. - -This feature becomes \fBactive\fR when the \fBzpool remove\fR subcommand is -used on a top-level vdev, and will never return to being \fBenabled\fR. -.RE - -.sp -.ne 2 -.na -\fBproject_quota\fR -.ad -.RS 4n -.TS -l l . -GUID org.zfsonlinux:project_quota -READ\-ONLY COMPATIBLE yes -DEPENDENCIES extensible_dataset -.TE - +of multiple vdevs. +Those vdevs may be arranged in any mirrored or raidz configuration. +.Pp +When the +.Sy multi_vdev_crash_dump +feature is set to +.Sy enabled , +the administrator can use +.Xr dumpadm 1M +to configure a dump device on a pool comprised of multiple vdevs. +.Pp +Under +.Fx +and Linux this feature is unused, but registered for compatibility. +New pools created on these systems will have the feature +.Sy enabled +but will never transition to +.Sy active , +as this functionality is not required for crash dump support. +Existing pools where this feature is +.Sy active +can be imported. +. +.feature com.delphix obsolete_counts yes device_removal +This feature is an enhancement of +.Sy device_removal , +which will over time reduce the memory used to track removed devices. +When indirect blocks are freed or remapped, +we note that their part of the indirect mapping is "obsolete" – no longer needed. +.Pp +This feature becomes +.Sy active +when the +.Nm zpool Cm remove +command is used on a top-level vdev, and will never return to being +.Sy enabled . +. +.feature org.zfsonlinux project_quota yes extensible_dataset This feature allows administrators to account the spaces and objects usage information against the project identifier (ID). - -The project ID is new object-based attribute. When upgrading an existing -filesystem, object without project ID attribute will be assigned a zero -project ID. After this feature is enabled, newly created object will inherit -its parent directory's project ID if the parent inherit flag is set (via -\fBchattr +/-P\fR or \fBzfs project [-s|-C]\fR). Otherwise, the new object's -project ID will be set as zero. An object's project ID can be changed at -anytime by the owner (or privileged user) via \fBchattr -p $prjid\fR or -\fBzfs project -p $prjid\fR. - -This feature will become \fBactive\fR as soon as it is enabled and will never -return to being \fBdisabled\fR. Each filesystem will be upgraded automatically -when remounted or when new file is created under that filesystem. The upgrade -can also be triggered on filesystems via `zfs set version=current `. -The upgrade process runs in the background and may take a while to complete -for the filesystems containing a large number of files. -.RE - -.sp -.ne 2 -.na -\fB\fBredaction_bookmarks\fR\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:redaction_bookmarks -READ\-ONLY COMPATIBLE no -DEPENDENCIES bookmarks, extensible_dataset -.TE - -This feature enables the use of the redacted zfs send. Redacted \fBzfs send\fR -creates redaction bookmarks, which store the list of blocks redacted by the -send that created them. For more information about redacted send, -see \fBzfs\fR(8). - -.RE - -.sp -.ne 2 -.na -\fB\fBredacted_datasets\fR\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:redacted_datasets -READ\-ONLY COMPATIBLE no -DEPENDENCIES extensible_dataset -.TE - -This feature enables the receiving of redacted zfs send streams. Redacted zfs -send streams create redacted datasets when received. These datasets are -missing some of their blocks, and so cannot be safely mounted, and their -contents cannot be safely read. For more information about redacted receive, -see \fBzfs\fR(8). -.RE - -.sp -.ne 2 -.na -\fBresilver_defer\fR -.ad -.RS 4n -.TS -l l . -GUID com.datto:resilver_defer -READ\-ONLY COMPATIBLE yes -DEPENDENCIES none -.TE - -This feature allows zfs to postpone new resilvers if an existing one is already -in progress. Without this feature, any new resilvers will cause the currently +.Pp +The project ID is an object-based attribute. +When upgrading an existing filesystem, +objects without a project ID will be assigned a zero project ID. +When this feature is enabled, newly created objects inherit +their parent directories' project ID if the parent's inherit flag is set +.Pq via Nm chattr Sy [+-]P No or Nm zfs Cm project Fl s Ns | Ns Fl C . +Otherwise, the new object's project ID will be zero. +An object's project ID can be changed at any time by the owner +(or privileged user) via +.Nm chattr Fl p Ar prjid +or +.Nm zfs Cm project Fl p Ar prjid . +.Pp +This feature will become +.Sy active +as soon as it is enabled and will never return to being +.Sy disabled . +\*[remount-upgrade] +. +.feature com.delphix redaction_bookmarks no bookmarks extensible_dataset +This feature enables the use of redacted +.Nm zfs Cm send Ns s , +which create redaction bookmarks storing the list of blocks +redacted by the send that created them. +For more information about redacted sends, see +.Xr zfs-send 8 . +. +.feature com.delphix redacted_datasets no extensible_dataset +This feature enables the receiving of redacted +.Nm zfs Cm send Ns +streams. which create redacted datasets when received. +These datasets are missing some of their blocks, +and so cannot be safely mounted, and their contents cannot be safely read. +For more information about redacted receives, see +.Xr zfs-send 8 . +. +.feature com.datto resilver_defer yes +This feature allows ZFS to postpone new resilvers if an existing one is already +in progress. +Without this feature, any new resilvers will cause the currently running one to be immediately restarted from the beginning. - -This feature becomes \fBactive\fR once a resilver has been deferred, and -returns to being \fBenabled\fR when the deferred resilver begins. -.RE - -.sp -.ne 2 -.na -\fBsha512\fR -.ad -.RS 4n -.TS -l l . -GUID org.illumos:sha512 -READ\-ONLY COMPATIBLE no -DEPENDENCIES extensible_dataset -.TE - +.Pp +This feature becomes +.Sy active +once a resilver has been deferred, and returns to being +.Sy enabled +when the deferred resilver begins. +. +.feature org.illumos sha512 no extensible_dataset This feature enables the use of the SHA-512/256 truncated hash algorithm -(FIPS 180-4) for checksum and dedup. The native 64-bit arithmetic of -SHA-512 provides an approximate 50% performance boost over SHA-256 on -64-bit hardware and is thus a good minimum-change replacement candidate -for systems where hash performance is important, but these systems -cannot for whatever reason utilize the faster \fBskein\fR and -\fBedonr\fR algorithms. - -When the \fBsha512\fR feature is set to \fBenabled\fR, the administrator -can turn on the \fBsha512\fR checksum on any dataset using -\fBzfs set checksum=sha512\fR. See zfs(8). This feature becomes -\fBactive\fR once a \fBchecksum\fR property has been set to \fBsha512\fR, -and will return to being \fBenabled\fR once all filesystems that have -ever had their checksum set to \fBsha512\fR are destroyed. -.RE - -.sp -.ne 2 -.na -\fBskein\fR -.ad -.RS 4n -.TS -l l . -GUID org.illumos:skein -READ\-ONLY COMPATIBLE no -DEPENDENCIES extensible_dataset -.TE - -This feature enables the use of the Skein hash algorithm for checksum -and dedup. Skein is a high-performance secure hash algorithm that was a -finalist in the NIST SHA-3 competition. It provides a very high security -margin and high performance on 64-bit hardware (80% faster than -SHA-256). This implementation also utilizes the new salted checksumming +(FIPS 180-4) for checksum and dedup. +The native 64-bit arithmetic of SHA-512 provides an approximate 50% +performance boost over SHA-256 on 64-bit hardware +and is thus a good minimum-change replacement candidate +for systems where hash performance is important, +but these systems cannot for whatever reason utilize the faster +.Sy skein No and Sy edonr +algorithms. +.Pp +.checksum-spiel sha512 +. +.feature org.illumos skein no extensible_dataset +This feature enables the use of the Skein hash algorithm for checksum and dedup. +Skein is a high-performance secure hash algorithm that was a +finalist in the NIST SHA-3 competition. +It provides a very high security margin and high performance on 64-bit hardware +(80% faster than SHA-256). +This implementation also utilizes the new salted checksumming functionality in ZFS, which means that the checksum is pre-seeded with a secret 256-bit random key (stored on the pool) before being fed the data -block to be checksummed. Thus the produced checksums are unique to a -given pool, preventing hash collision attacks on systems with dedup. - -When the \fBskein\fR feature is set to \fBenabled\fR, the administrator -can turn on the \fBskein\fR checksum on any dataset using -\fBzfs set checksum=skein\fR. See zfs(8). This feature becomes -\fBactive\fR once a \fBchecksum\fR property has been set to \fBskein\fR, -and will return to being \fBenabled\fR once all filesystems that have -ever had their checksum set to \fBskein\fR are destroyed. -.RE - -.sp -.ne 2 -.na -\fBspacemap_histogram\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:spacemap_histogram -READ\-ONLY COMPATIBLE yes -DEPENDENCIES none -.TE - +block to be checksummed. +Thus the produced checksums are unique to a given pool, +preventing hash collision attacks on systems with dedup. +.Pp +.checksum-spiel skein +. +.feature com.delphix spacemap_histogram yes This features allows ZFS to maintain more information about how free space -is organized within the pool. If this feature is \fBenabled\fR, ZFS will -set this feature to \fBactive\fR when a new space map object is created or -an existing space map is upgraded to the new format. Once the feature is -\fBactive\fR, it will remain in that state until the pool is destroyed. -.RE - -.sp -.ne 2 -.na -\fBspacemap_v2\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:spacemap_v2 -READ\-ONLY COMPATIBLE yes -DEPENDENCIES none -.TE - +is organized within the pool. +If this feature is +.Sy enabled , +it will be activated when a new space map object is created, or +an existing space map is upgraded to the new format, +and never returns back to being +.Sy enabled . +. +.feature com.delphix spacemap_v2 yes This feature enables the use of the new space map encoding which consists of two words (instead of one) whenever it is advantageous. The new encoding allows space maps to represent large regions of space more efficiently on-disk while also increasing their maximum addressable offset. - -This feature becomes \fBactive\fR once it is \fBenabled\fR, and never -returns back to being \fBenabled\fR. -.RE - -.sp -.ne 2 -.na -\fBuserobj_accounting\fR -.ad -.RS 4n -.TS -l l . -GUID org.zfsonlinux:userobj_accounting -READ\-ONLY COMPATIBLE yes -DEPENDENCIES extensible_dataset -.TE - +.Pp +This feature becomes +.Sy active +once it is +.Sy enabled , +and never returns back to being +.Sy enabled . +. +.feature org.zfsonlinux userobj_accounting yes extensible_dataset This feature allows administrators to account the object usage information by user and group. - -This feature becomes \fBactive\fR as soon as it is enabled and will never -return to being \fBenabled\fR. Each filesystem will be upgraded automatically -when remounted, or when new files are created under that filesystem. -The upgrade can also be started manually on filesystems by running -`zfs set version=current `. The upgrade process runs in the background -and may take a while to complete for filesystems containing a large number of -files. -.RE - -.sp -.ne 2 -.na -\fBzpool_checkpoint\fR -.ad -.RS 4n -.TS -l l . -GUID com.delphix:zpool_checkpoint -READ\-ONLY COMPATIBLE yes -DEPENDENCIES none -.TE - -This feature enables the \fBzpool checkpoint\fR subcommand that can -checkpoint the state of the pool at the time it was issued and later -rewind back to it or discard it. - -This feature becomes \fBactive\fR when the \fBzpool checkpoint\fR subcommand -is used to checkpoint the pool. -The feature will only return back to being \fBenabled\fR when the pool -is rewound or the checkpoint has been discarded. -.RE - -.sp -.ne 2 -.na -\fBzstd_compress\fR -.ad -.RS 4n -.TS -l l . -GUID org.freebsd:zstd_compress -READ\-ONLY COMPATIBLE no -DEPENDENCIES extensible_dataset -.TE - -\fBzstd\fR is a high-performance compression algorithm that features a -combination of high compression ratios and high speed. Compared to \fBgzip\fR, -\fBzstd\fR offers slighty better compression at much higher speeds. Compared -to \fBlz4\fR, \fBzstd\fR offers much better compression while being only -modestly slower. Typically, \fBzstd\fR compression speed ranges from 250 to 500 -MB/s per thread and decompression speed is over 1 GB/s per thread. - -When the \fBzstd\fR feature is set to \fBenabled\fR, the administrator can turn -on \fBzstd\fR compression of any dataset by running -`zfs set compress=zstd `. - -This feature becomes \fBactive\fR once a \fBcompress\fR property has been set to -\fBzstd\fR, and will return to being \fBenabled\fR once all filesystems that -have ever had their compress property set to \fBzstd\fR are destroyed. - -Booting off of \fBzstd\fR-compressed root pools is not yet supported. -.RE - -.SH "SEE ALSO" -zpool(8) +.Pp +\*[instant-never] +\*[remount-upgrade] +. +.feature com.delphix zpool_checkpoint yes +This feature enables the +.Nm zpool Cm checkpoint +command that can checkpoint the state of the pool +at the time it was issued and later rewind back to it or discard it. +.Pp +This feature becomes +.Sy active +when the +.Nm zpool Cm checkpoint +command is used to checkpoint the pool. +The feature will only return back to being +.Sy enabled +when the pool is rewound or the checkpoint has been discarded. +. +.feature org.freebsd zstd_compress no extensible_dataset +.Sy zstd +is a high-performance compression algorithm that features a +combination of high compression ratios and high speed. +Compared to +.Sy gzip , +.Sy zstd +offers slightly better compression at much higher speeds. +Compared to +.Sy lz4 , +.Sy zstd +offers much better compression while being only modestly slower. +Typically, +.Sy zstd +compression speed ranges from 250 to 500 MB/s per thread +and decompression speed is over 1 GB/s per thread. +.Pp +When the +.Sy zstd +feature is set to +.Sy enabled , +the administrator can turn on +.Sy zstd +compression of any dataset using +.Nm zfs Cm set Sy compress Ns = Ns Sy zstd Ar dset +.Po see Xr zfs-set 8 Pc . +This feature becomes +.Sy active +once a +.Sy compress +property has been set to +.Sy zstd , +and will return to being +.Sy enabled +once all filesystems that have ever had their +.Sy compress +property set to +.Sy zstd +are destroyed. +.El +. +.Sh SEE ALSO +.Xr zpool 8 diff --git a/sys/contrib/openzfs/man/man8/fsck.zfs.8 b/sys/contrib/openzfs/man/man8/fsck.zfs.8 index f681c2502eb..b88dd847b1b 100644 --- a/sys/contrib/openzfs/man/man8/fsck.zfs.8 +++ b/sys/contrib/openzfs/man/man8/fsck.zfs.8 @@ -1,4 +1,3 @@ -'\" t .\" .\" CDDL HEADER START .\" @@ -19,49 +18,56 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright 2013 Darik Horn . All rights reserved. .\" -.TH FSCK.ZFS 8 "Aug 24, 2020" OpenZFS - -.SH NAME -fsck.zfs \- Dummy ZFS filesystem checker. - -.SH SYNOPSIS -.LP -.BI "fsck.zfs [" "options" "] <" "dataset" ">" - -.SH DESCRIPTION -.LP -\fBfsck.zfs\fR is a shell stub that does nothing and always returns -true. It is installed by ZoL because some Linux distributions expect -a fsck helper for all filesystems. - -.SH OPTIONS -.HP -All \fIoptions\fR and the \fIdataset\fR are ignored. - -.SH "NOTES" -.LP -ZFS datasets are checked by running \fBzpool scrub\fR on the -containing pool. An individual ZFS dataset is never checked -independently of its pool, which is unlike a regular filesystem. - -.SH "BUGS" -.LP -On some systems, if the \fIdataset\fR is in a degraded pool, then it -might be appropriate for \fBfsck.zfs\fR to return exit code 4 to -indicate an uncorrected filesystem error. -.LP -Similarly, if the \fIdataset\fR is in a faulted pool and has a legacy -/etc/fstab record, then \fBfsck.zfs\fR should return exit code 8 to -indicate a fatal operational error. - -.SH "AUTHORS" -.LP -Darik Horn . - -.SH "SEE ALSO" -.BR fsck (8), -.BR fstab (5), -.BR zpool-scrub (8) +.Dd May 26, 2021 +.Dt FSCK.ZFS 8 +.Os +. +.Sh NAME +.Nm fsck.zfs +.Nd dummy ZFS filesystem checker +.Sh SYNOPSIS +.Nm +.Op Ar options +.Ar dataset Ns No … +. +.Sh DESCRIPTION +.Nm +is a thin shell wrapper that at most checks the status of a dataset's container pool. +It is installed by OpenZFS because some Linux +distributions expect a fsck helper for all filesystems. +.Pp +If more than one +.Ar dataset +is specified, each is checked in turn and the results binary-ored. +. +.Sh OPTIONS +Ignored. +. +.Sh NOTES +ZFS datasets are checked by running +.Nm zpool Cm scrub +on the containing pool. +An individual ZFS dataset is never checked independently of its pool, +which is unlike a regular filesystem. +.Pp +However, the +.Xr fsck 8 +interface still allows it to communicate some errors: if the +.Ar dataset +is in a degraded pool, then +.Nm +will return exit code 4 to indicate an uncorrected filesystem error. +.Pp +Similarly, if the +.Ar dataset +is in a faulted pool and has a legacy +.Pa /etc/fstab +record, then +.Nm +will return exit code 8 to indicate a fatal operational error. +.Sh SEE ALSO +.Xr fstab 5 , +.Xr fsck 8 , +.Xr zpool-scrub 8 diff --git a/sys/contrib/openzfs/man/man8/mount.zfs.8 b/sys/contrib/openzfs/man/man8/mount.zfs.8 index 016a909c26a..5d36dbdb169 100644 --- a/sys/contrib/openzfs/man/man8/mount.zfs.8 +++ b/sys/contrib/openzfs/man/man8/mount.zfs.8 @@ -1,4 +1,3 @@ -'\" t .\" .\" CDDL HEADER START .\" @@ -19,126 +18,75 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright 2013 Darik Horn . All rights reserved. .\" -.TH MOUNT.ZFS 8 "Aug 24, 2020" OpenZFS - -.SH NAME -mount.zfs \- mount a ZFS filesystem -.SH SYNOPSIS -.LP -.BI "mount.zfs [\-sfnvh] [\-o " options "]" " dataset mountpoint - -.SH DESCRIPTION -.BR mount.zfs -is part of the zfsutils package for Linux. It is a helper program that -is usually invoked by the -.BR mount (8) +.Dd May 24, 2021 +.Dt MOUNT.ZFS 8 +.Os +. +.Sh NAME +.Nm mount.zfs +.Nd mount ZFS filesystem +.Sh SYNOPSIS +.Nm +.Op Fl sfnvh +.Op Fl o Ar options +.Ar dataset +.Ar mountpoint +. +.Sh DESCRIPTION +The +.Nm +helper is used by +.Xr mount 8 +to mount filesystem snapshots and +.Sy mountpoint= Ns Ar legacy +ZFS filesystems, as well as by +.Xr zfs 8 +when the +.Sy ZFS_MOUNT_HELPER +environment variable is not set. +Users should should invoke either +.Xr mount 8 or -.BR zfs (8) -commands to mount a ZFS dataset. - -All -.I options -are handled according to the FILESYSTEM INDEPENDENT MOUNT OPTIONS -section in the -.BR mount (8) -manual, except for those described below. - -The -.I dataset -parameter is a ZFS filesystem name, as output by the -.B "zfs list -H -o name -command. This parameter never has a leading slash character and is -not a device name. - -The -.I mountpoint -parameter is the path name of a directory. - - -.SH OPTIONS -.TP -.BI "\-s" -Ignore bad or sloppy mount options. -.TP -.BI "\-f" -Do a fake mount; do not perform the mount operation. -.TP -.BI "\-n" -Do not update the /etc/mtab file. -.TP -.BI "\-v" -Increase verbosity. -.TP -.BI "\-h" +.Xr zfs 8 +in most cases. +.Pp +.Ar options +are handled according to the +.Em Temporary Mount Point Properties +section in +.Xr zfsprops 8 , +except for those described below. +.Pp +If +.Pa /etc/mtab +is a regular file and +.Fl n +was not specified, it will be updated via libmount. +. +.Sh OPTIONS +.Bl -tag -width "-o xa" +.It Fl s +Ignore unknown (sloppy) mount options. +.It Fl f +Do everything except actually executing the system call. +.It Fl n +Never update +.Pa /etc/mtab . +.It Fl v +Print resolved mount options and parser state. +.It Fl h Print the usage message. -.TP -.BI "\-o context" -This flag sets the SELinux context for all files in the filesystem -under that mountpoint. -.TP -.BI "\-o fscontext" -This flag sets the SELinux context for the filesystem being mounted. -.TP -.BI "\-o defcontext" -This flag sets the SELinux context for unlabeled files. -.TP -.BI "\-o rootcontext" -This flag sets the SELinux context for the root inode of the filesystem. -.TP -.BI "\-o legacy" -This private flag indicates that the -.I dataset -has an entry in the /etc/fstab file. -.TP -.BI "\-o noxattr" -This private flag disables extended attributes. -.TP -.BI "\-o xattr -This private flag enables directory-based extended attributes and, if -appropriate, adds a ZFS context to the selinux system policy. -.TP -.BI "\-o saxattr -This private flag enables system attributed-based extended attributes and, if -appropriate, adds a ZFS context to the selinux system policy. -.TP -.BI "\-o dirxattr -Equivalent to -.BR xattr . -.TP -.BI "\-o zfsutil" +.It Fl o Ar zfsutil This private flag indicates that -.BR mount (8) +.Xr mount 8 is being called by the -.BR zfs (8) +.Xr zfs 8 command. - -.SH NOTES -ZFS conventionally requires that the -.I mountpoint -be an empty directory, but the Linux implementation inconsistently -enforces the requirement. - -The -.BR mount.zfs -helper does not mount the contents of zvols. - -.SH FILES -.TP 18n -.I /etc/fstab -The static filesystem table. -.TP -.I /etc/mtab -The mounted filesystem table. -.SH "AUTHORS" -The primary author of -.BR mount.zfs -is Brian Behlendorf . - -This man page was written by Darik Horn . -.SH "SEE ALSO" -.BR fstab (5), -.BR mount (8), -.BR zfs (8) +.El +. +.Sh SEE ALSO +.Xr fstab 5 , +.Xr mount 8 , +.Xr zfs-mount 8 diff --git a/sys/contrib/openzfs/man/man8/vdev_id.8 b/sys/contrib/openzfs/man/man8/vdev_id.8 index 6de3d18fe57..2b327b3192a 100644 --- a/sys/contrib/openzfs/man/man8/vdev_id.8 +++ b/sys/contrib/openzfs/man/man8/vdev_id.8 @@ -1,77 +1,93 @@ -.TH VDEV_ID 8 "Aug 24, 2020" OpenZFS -.SH NAME -vdev_id \- generate user-friendly names for JBOD disks -.SH SYNOPSIS -.LP -.nf -\fBvdev_id\fR <-d dev> [-c config_file] [-g sas_direct|sas_switch] - [-m] [-p phys_per_port] -\fBvdev_id\fR -h -.fi -.SH DESCRIPTION -The \fBvdev_id\fR command is a udev helper which parses the file -.BR /etc/zfs/vdev_id.conf (5) -to map a physical path in a storage topology to a channel name. The -channel name is combined with a disk enclosure slot number to create an -alias that reflects the physical location of the drive. This is -particularly helpful when it comes to tasks like replacing failed -drives. Slot numbers may also be re-mapped in case the default -numbering is unsatisfactory. The drive aliases will be created as -symbolic links in /dev/disk/by-vdev. - -The currently supported topologies are sas_direct and sas_switch. A -multipath mode is supported in which dm-mpath devices are handled by -examining the first-listed running component disk as reported by the -.BR multipath (8) -command. In multipath mode the configuration file should contain a +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.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. +.\" +.Dd May 26, 2021 +.Dt VDEV_ID 8 +.Os +. +.Sh NAME +.Nm vdev_id +.Nd generate user-friendly names for JBOD disks +.Sh SYNOPSIS +.Nm +.Fl d Ar dev +.Fl c Ar config_file +.Fl g Sy sas_direct Ns | Ns Sy sas_switch Ns | Ns Sy scsi +.Fl m +.Fl p Ar phys_per_port +. +.Sh DESCRIPTION +.Nm +is an udev helper which parses +.Xr vdev_id.conf 5 +to map a physical path in a storage topology to a channel name. +The channel name is combined with a disk enclosure slot number to create +an alias that reflects the physical location of the drive. +This is particularly helpful when it comes to tasks like replacing failed drives. +Slot numbers may also be remapped in case the default numbering is unsatisfactory. +The drive aliases will be created as symbolic links in +.Pa /dev/disk/by-vdev . +.Pp +The currently supported topologies are +.Sy sas_direct , +.Sy sas_switch , +and +.Sy scsi . +A multipath mode is supported in which dm-mpath devices are handled by +examining the first running component disk as reported by the driver. +In multipath mode the configuration file should contain a channel definition with the same name for each path to a given enclosure. - -.BR vdev_id +.Pp +.Nm also supports creating aliases based on existing udev links in the /dev -hierarchy using the \fIalias\fR configuration file keyword. See the -.BR vdev_id.conf (5) -man page for details. - -.SH OPTIONS -.TP -\fB\-c\fR -Specifies the path to an alternate configuration file. The default is -/etc/zfs/vdev_id.conf. -.TP -\fB\-d\fR -This is the only mandatory argument. Specifies the name of a device -in /dev, i.e. "sda". -.TP -\fB\-g\fR +hierarchy using the +.Sy alias +configuration file keyword. +See +.Xr vdev_id.conf 5 +for details. +. +.Sh OPTIONS +.Bl -tag -width "-m" +.It Fl d Ar device +The device node to classify, like +.Pa /dev/sda . +.It Fl c Ar config_file +Specifies the path to an alternate configuration file. +The default is +.Pa /etc/zfs/vdev_id.conf . +.It Fl g Sy sas_direct Ns | Ns Sy sas_switch Ns | Ns Sy scsi Identifies a physical topology that governs how physical paths are -mapped to channels. - -\fIsas_direct\fR - in this mode a channel is uniquely identified by -a PCI slot and a HBA port number - -\fIsas_switch\fR - in this mode a channel is uniquely identified by -a SAS switch port number -.TP -\fB\-m\fR -Specifies that -.BR vdev_id (8) -will handle only dm-multipath devices. If set to "yes" then -.BR vdev_id (8) -will examine the first running component disk of a dm-multipath -device as listed by the -.BR multipath (8) -command to determine the physical path. -.TP -\fB\-p\fR +mapped to channels: +.Bl -tag -compact -width "sas_direct and scsi" +.It Sy sas_direct No and Sy scsi +channels are uniquely identified by a PCI slot and HBA port number +.It Sy sas_switch +channels are uniquely identified by a SAS switch port number +.El +.It Fl m +Only handle dm-multipath devices. +If specified, examine the first running component disk of a dm-multipath +device as provided by the driver to determine the physical path. +.It Fl p Ar phys_per_port Specifies the number of PHY devices associated with a SAS HBA port or SAS switch port. -.BR vdev_id (8) +.Nm internally uses this value to determine which HBA or switch port a -device is connected to. The default is 4. -.TP -\fB\-h\fR +device is connected to. +The default is +.Sy 4 . +.It Fl h Print a usage summary. -.SH SEE ALSO -.LP -\fBvdev_id.conf\fR(5) +.El +. +.Sh SEE ALSO +.Xr vdev_id.conf 5 diff --git a/sys/contrib/openzfs/man/man8/zdb.8 b/sys/contrib/openzfs/man/man8/zdb.8 index 36fe6de547b..a8a94421907 100644 --- a/sys/contrib/openzfs/man/man8/zdb.8 +++ b/sys/contrib/openzfs/man/man8/zdb.8 @@ -8,7 +8,6 @@ .\" source. A copy of the CDDL is also available via the Internet at .\" http://www.illumos.org/license/CDDL. .\" -.\" .\" Copyright 2012, Richard Lowe. .\" Copyright (c) 2012, 2019 by Delphix. All rights reserved. .\" Copyright 2017 Nexenta Systems, Inc. @@ -16,27 +15,29 @@ .\" Copyright (c) 2017 Intel Corporation. .\" .Dd October 7, 2020 -.Dt ZDB 8 SMM +.Dt ZDB 8 .Os +. .Sh NAME .Nm zdb -.Nd display zpool debugging and consistency information +.Nd display ZFS storage pool debugging and consistency information .Sh SYNOPSIS .Nm .Op Fl AbcdDFGhikLMPsvXYy -.Op Fl e Oo Fl V Oc Op Fl p Ar path ... +.Op Fl e Oo Fl V Oc Oo Fl p Ar path Oc Ns … .Op Fl I Ar inflight I/Os -.Oo Fl o Ar var Ns = Ns Ar value Oc Ns ... +.Oo Fl o Ar var Ns = Ns Ar value Oc Ns … .Op Fl t Ar txg .Op Fl U Ar cache .Op Fl x Ar dumpdir -.Op Ar poolname[/dataset | objset ID] -.Op Ar object | range ... +.Op Ar poolname Ns Op / Ns Ar dataset | objset ID +.Op Ar object Ns | Ns Ar range Ns … .Nm .Op Fl AdiPv -.Op Fl e Oo Fl V Oc Op Fl p Ar path ... +.Op Fl e Oo Fl V Oc Oo Fl p Ar path Oc Ns … .Op Fl U Ar cache -.Ar poolname[/dataset | objset ID] Op Ar object | range ... +.Ar poolname Ns Op Ar / Ns Ar dataset | objset ID +.Op Ar object Ns | Ns Ar range Ns … .Nm .Fl C .Op Fl A @@ -44,7 +45,7 @@ .Nm .Fl E .Op Fl A -.Ar word0 Ns \&: Ns Ar word1 Ns :...: Ns Ar word15 +.Ar word0 : Ns Ar word1 Ns :…: Ns Ar word15 .Nm .Fl l .Op Fl Aqu @@ -52,10 +53,10 @@ .Nm .Fl m .Op Fl AFLPXY -.Op Fl e Oo Fl V Oc Op Fl p Ar path ... +.Op Fl e Oo Fl V Oc Oo Fl p Ar path Oc Ns … .Op Fl t Ar txg .Op Fl U Ar cache -.Ar poolname Op Ar vdev Op Ar metaslab ... +.Ar poolname Op Ar vdev Oo Ar metaslab Oc Ns … .Nm .Fl O .Ar dataset path @@ -65,15 +66,16 @@ .Nm .Fl R .Op Fl A -.Op Fl e Oo Fl V Oc Op Fl p Ar path ... +.Op Fl e Oo Fl V Oc Oo Fl p Ar path Oc Ns … .Op Fl U Ar cache -.Ar poolname vdev Ns \&: Ns Ar offset Ns \&: Ns Ar [/] Ns Op : Ns Ar flags +.Ar poolname vdev : Ns Ar offset : Ns Oo Ar lsize Ns / Oc Ns Ar psize Ns Op : Ns Ar flags .Nm .Fl S .Op Fl AP -.Op Fl e Oo Fl V Oc Op Fl p Ar path ... +.Op Fl e Oo Fl V Oc Oo Fl p Ar path Oc Ns … .Op Fl U Ar cache .Ar poolname +. .Sh DESCRIPTION The .Nm @@ -99,11 +101,11 @@ or .Qq Sy @ characters, it is interpreted as a pool name. The root dataset can be specified as -.Ar pool Ns / -.Pq pool name followed by a slash . +.Qq Ar pool Ns / . .Pp When operating on an imported and active pool it is possible, though unlikely, that zdb may interpret inconsistent pool data and behave erratically. +. .Sh OPTIONS Display options: .Bl -tag -width Ds @@ -143,27 +145,30 @@ those specific objects or ranges only. .Pp An object ID range is specified in terms of a colon-separated tuple of the form -.Ao start Ac Ns : Ns Ao end Ac Ns Op Ns : Ns Ao flags Ac Ns . +.Ao start Ac : Ns Ao end Ac Ns Op : Ns Ao flags Ac . The fields .Ar start and .Ar end are integer object identifiers that denote the upper and lower bounds -of the range. An +of the range. +An .Ar end -value of -1 specifies a range with no upper bound. The +value of -1 specifies a range with no upper bound. +The .Ar flags field optionally specifies a set of flags, described below, that control -which object types are dumped. By default, all object types are dumped. A minus -sign +which object types are dumped. +By default, all object types are dumped. +A minus sign .Pq - negates the effect of the flag that follows it and has no effect unless preceded by the .Ar A -flag. For example, the range 0:-1:A-d will dump all object types except -for directories. +flag. +For example, the range 0:-1:A-d will dump all object types except for directories. .Pp -.Bl -tag -compact +.Bl -tag -compact -width Ds .It Sy A Dump all objects (this is the default) .It Sy d @@ -198,7 +203,7 @@ Display the statistics independently for each deduplication table. Dump the contents of the deduplication tables describing duplicate blocks. .It Fl DDDDD Also dump the contents of the deduplication tables describing unique blocks. -.It Fl E Ar word0 Ns \&: Ns Ar word1 Ns :...: Ns Ar word15 +.It Fl E Ar word0 : Ns Ar word1 Ns :…: Ns Ar word15 Decode and display block from an embedded block pointer specified by the .Ar word arguments. @@ -218,18 +223,21 @@ Note, the on disk format of the pool is not reverted to the checkpointed state. Read the vdev labels and L2ARC header from the specified device. .Nm Fl l will return 0 if valid label was found, 1 if error occurred, and 2 if no valid -labels were found. The presence of L2ARC header is indicated by a specific -sequence (L2ARC_DEV_HDR_MAGIC). If there is an accounting error in the size -or the number of L2ARC log blocks +labels were found. +The presence of L2ARC header is indicated by a specific +sequence (L2ARC_DEV_HDR_MAGIC). +If there is an accounting error in the size or the number of L2ARC log blocks .Nm Fl l -will return 1. Each unique configuration is displayed only -once. +will return 1. +Each unique configuration is displayed only once. .It Fl ll Ar device -In addition display label space usage stats. If a valid L2ARC header was found +In addition display label space usage stats. +If a valid L2ARC header was found also display the properties of log blocks used for restoring L2ARC contents (persistent L2ARC). .It Fl lll Ar device -Display every configuration, unique or not. If a valid L2ARC header was found +Display every configuration, unique or not. +If a valid L2ARC header was found also display the properties of log entries in log blocks used for restoring L2ARC contents (persistent L2ARC). .Pp @@ -239,8 +247,8 @@ option is also specified, don't print the labels or the L2ARC header. .Pp If the .Fl u -option is also specified, also display the uberblocks on this device. Specify -multiple times to increase verbosity. +option is also specified, also display the uberblocks on this device. +Specify multiple times to increase verbosity. .It Fl L Disable leak detection and the loading of space maps. By default, @@ -291,7 +299,7 @@ This option can be combined with .Fl v for increasing verbosity. .It Xo -.Fl R Ar poolname vdev Ns \&: Ns Ar offset Ns \&: Ns Ar [/] Ns Op : Ns Ar flags +.Fl R Ar poolname vdev : Ns Ar offset : Ns Oo Ar lsize Ns / Oc Ns Ar psize Ns Op : Ns Ar flags .Xc Read and display a block from the specified device. By default the block is displayed as a hex dump, but see the description of the @@ -315,7 +323,8 @@ Print block pointer at hex offset .It Sy c Calculate and display checksums .It Sy d -Decompress the block. Set environment variable +Decompress the block. +Set environment variable .Nm ZDB_NO_ZLE to skip zle when guessing. .It Sy e @@ -352,7 +361,7 @@ Enable panic recovery, certain errors which would otherwise be fatal are demoted to warnings. .It Fl AAA Do not abort if asserts fail and also enable panic recovery. -.It Fl e Op Fl p Ar path ... +.It Fl e Oo Fl p Ar path Oc Ns … Operate on an exported pool, not present in .Pa /etc/zfs/zpool.cache . The @@ -382,14 +391,16 @@ The default value is 200. This option affects the performance of the .Fl c option. -.It Fl o Ar var Ns = Ns Ar value ... +.It Fl o Ar var Ns = Ns Ar value … Set the given global libzpool variable to the provided value. The value must be an unsigned 32-bit integer. Currently only little-endian systems are supported to avoid accidentally setting the high 32 bits of 64-bit variables. .It Fl P -Print numbers in an unscaled form more amenable to parsing, eg. 1000000 rather -than 1M. +Print numbers in an unscaled form more amenable to parsing, e.g.\& +.Sy 1000000 +rather than +.Sy 1M . .It Fl t Ar transaction Specify the highest transaction to use when searching for uberblocks. See also the @@ -432,51 +443,51 @@ option, with more occurrences enabling more verbosity. .Pp If no options are specified, all information about the named pool will be displayed at default verbosity. +. .Sh EXAMPLES .Bl -tag -width Ds .It Xo -.Sy Example 1 +.Sy Example 1 : Display the configuration of imported pool -.Pa rpool +.Ar rpool .Xc .Bd -literal -# zdb -C rpool - +.No # Nm zdb Fl C Ar rpool MOS Configuration: version: 28 name: 'rpool' - ... + … .Ed .It Xo -.Sy Example 2 +.Sy Example 2 : Display basic dataset information about -.Pa rpool +.Ar rpool .Xc .Bd -literal -# zdb -d rpool +.No # Nm zdb Fl d Ar rpool Dataset mos [META], ID 0, cr_txg 4, 26.9M, 1051 objects Dataset rpool/swap [ZVOL], ID 59, cr_txg 356, 486M, 2 objects - ... + … .Ed .It Xo -.Sy Example 3 +.Sy Example 3 : Display basic information about object 0 in -.Pa rpool/export/home +.Ar rpool/export/home .Xc .Bd -literal -# zdb -d rpool/export/home 0 +.No # Nm zdb Fl d Ar rpool/export/home 0 Dataset rpool/export/home [ZPL], ID 137, cr_txg 1546, 32K, 8 objects Object lvl iblk dblk dsize lsize %full type 0 7 16K 16K 15.0K 16K 25.00 DMU dnode .Ed .It Xo -.Sy Example 4 +.Sy Example 4 : Display the predicted effect of enabling deduplication on -.Pa rpool +.Ar rpool .Xc .Bd -literal -# zdb -S rpool +.No # Nm zdb Fl S Ar rpool Simulated DDT histogram: bucket allocated referenced @@ -485,10 +496,11 @@ refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE ------ ------ ----- ----- ----- ------ ----- ----- ----- 1 694K 27.1G 15.0G 15.0G 694K 27.1G 15.0G 15.0G 2 35.0K 1.33G 699M 699M 74.7K 2.79G 1.45G 1.45G - ... + … dedup = 1.11, compress = 1.80, copies = 1.00, dedup * compress / copies = 2.00 .Ed .El +. .Sh SEE ALSO .Xr zfs 8 , .Xr zpool 8 diff --git a/sys/contrib/openzfs/man/man8/zed.8.in b/sys/contrib/openzfs/man/man8/zed.8.in index e32a89de8a0..e0d9f04043d 100644 --- a/sys/contrib/openzfs/man/man8/zed.8.in +++ b/sys/contrib/openzfs/man/man8/zed.8.in @@ -2,7 +2,7 @@ .\" This file is part of the ZFS Event Daemon (ZED). .\" Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). .\" Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. -.\" Refer to the ZoL git commit log for authoritative copyright attribution. +.\" Refer to the OpenZFS git commit log for authoritative copyright attribution. .\" .\" The contents of this file are subject to the terms of the .\" Common Development and Distribution License Version 1.0 (CDDL-1.0). @@ -10,258 +10,247 @@ .\" "OPENSOLARIS.LICENSE" or at . .\" You may not use this file except in compliance with the license. .\" -.TH ZED 8 "Aug 24, 2020" OpenZFS - -.SH NAME -ZED \- ZFS Event Daemon - -.SH SYNOPSIS -.HP -.B zed -.\" [\fB\-c\fR \fIconfigfile\fR] -[\fB\-d\fR \fIzedletdir\fR] -[\fB\-f\fR] -[\fB\-F\fR] -[\fB\-h\fR] -[\fB\-I\fR] -[\fB\-L\fR] -[\fB\-M\fR] -[\fB\-p\fR \fIpidfile\fR] -[\fB\-P\fR \fIpath\fR] -[\fB\-s\fR \fIstatefile\fR] -[\fB\-v\fR] -[\fB\-V\fR] -[\fB\-Z\fR] - -.SH DESCRIPTION -.PP -\fBZED\fR (ZFS Event Daemon) monitors events generated by the ZFS kernel -module. When a zevent (ZFS Event) is posted, \fBZED\fR will run any ZEDLETs -(ZFS Event Daemon Linkage for Executable Tasks) that have been enabled for the -corresponding zevent class. - -.SH OPTIONS -.TP -.BI \-h +.\" Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049) +.\" +.Dd May 26, 2021 +.Dt ZED 8 +.Os +. +.Sh NAME +.Nm ZED +.Nd ZFS Event Daemon +.Sh SYNOPSIS +.Nm +.Op Fl fFhILMvVZ +.Op Fl d Ar zedletdir +.Op Fl p Ar pidfile +.Op Fl P Ar path +.Op Fl s Ar statefile +.Op Fl j Ar jobs +. +.Sh DESCRIPTION +The +.Nm +(ZFS Event Daemon) monitors events generated by the ZFS kernel +module. +When a zevent (ZFS Event) is posted, the +.Nm +will run any ZEDLETs (ZFS Event Daemon Linkage for Executable Tasks) +that have been enabled for the corresponding zevent class. +. +.Sh OPTIONS +.Bl -tag -width "-h" +.It Fl h Display a summary of the command-line options. -.TP -.BI \-L +.It Fl L Display license information. -.TP -.BI \-V +.It Fl V Display version information. -.TP -.BI \-v +.It Fl v Be verbose. -.TP -.BI \-f +.It Fl f Force the daemon to run if at all possible, disabling security checks and -throwing caution to the wind. Not recommended for use in production. -.TP -.BI \-F -Run the daemon in the foreground. -.TP -.BI \-M +throwing caution to the wind. +Not recommended for use in production. +.It Fl F +Don't daemonise: remain attached to the controlling terminal, +log to the standard I/O streams. +.It Fl M Lock all current and future pages in the virtual memory address space. This may help the daemon remain responsive when the system is under heavy memory pressure. -.TP -.BI \-I -Request that the daemon idle rather than exit when the kernel modules are -not loaded. Processing of events will start, or resume, when the kernel -modules are (re)loaded. Under Linux the kernel modules cannot be unloaded -while the daemon is running. -.TP -.BI \-Z +.It Fl I +Request that the daemon idle rather than exit when the kernel modules are not loaded. +Processing of events will start, or resume, when the kernel modules are (re)loaded. +Under Linux the kernel modules cannot be unloaded while the daemon is running. +.It Fl Z Zero the daemon's state, thereby allowing zevents still within the kernel to be reprocessed. -.\" .TP -.\" .BI \-c\ configfile -.\" Read the configuration from the specified file. -.TP -.BI \-d\ zedletdir +.It Fl d Ar zedletdir Read the enabled ZEDLETs from the specified directory. -.TP -.BI \-p\ pidfile +.It Fl p Ar pidfile Write the daemon's process ID to the specified file. -.TP -.BI \-P\ path -Custom $PATH for zedlets to use. Normally zedlets run in a locked-down -environment, with hardcoded paths to the ZFS commands ($ZFS, $ZPOOL, $ZED, ...), -and a hardcoded $PATH. This is done for security reasons. However, the -ZFS test suite uses a custom PATH for its ZFS commands, and passes it to zed -with -P. In short, -P is only to be used by the ZFS test suite; never use +.It Fl P Ar path +Custom +.Ev $PATH +for zedlets to use. +Normally zedlets run in a locked-down environment, with hardcoded paths to the ZFS commands +.Pq Ev $ZFS , $ZPOOL , $ZED , ... , +and a hard-coded +.Ev $PATH . +This is done for security reasons. +However, the ZFS test suite uses a custom PATH for its ZFS commands, and passes it to +.Nm +with +.Fl P . +In short, +.Fl P +is only to be used by the ZFS test suite; never use it in production! -.TP -.BI \-s\ statefile +.It Fl s Ar statefile Write the daemon's state to the specified file. -.SH ZEVENTS -.PP -A zevent is comprised of a list of nvpairs (name/value pairs). Each zevent -contains an EID (Event IDentifier) that uniquely identifies it throughout +.It Fl j Ar jobs +Allow at most +.Ar jobs +ZEDLETs to run concurrently, +delaying execution of new ones until they finish. +Defaults to +.Sy 16 . +.El +.Sh ZEVENTS +A zevent is comprised of a list of nvpairs (name/value pairs). +Each zevent contains an EID (Event IDentifier) that uniquely identifies it throughout the lifetime of the loaded ZFS kernel module; this EID is a monotonically increasing integer that resets to 1 each time the kernel module is loaded. Each zevent also contains a class string that identifies the type of event. For brevity, a subclass string is defined that omits the leading components -of the class string. Additional nvpairs exist to provide event details. -.PP +of the class string. +Additional nvpairs exist to provide event details. +.Pp The kernel maintains a list of recent zevents that can be viewed (along with -their associated lists of nvpairs) using the "\fBzpool events \-v\fR" command. - -.SH CONFIGURATION -.PP +their associated lists of nvpairs) using the +.Nm zpool Cm events Fl v +command. +. +.Sh CONFIGURATION ZEDLETs to be invoked in response to zevents are located in the -\fIenabled-zedlets\fR directory. These can be symlinked or copied from the -\fIinstalled-zedlets\fR directory; symlinks allow for automatic updates +.Em enabled-zedlets +directory +.Pq Ar zedletdir . +These can be symlinked or copied from the +.Em installed-zedlets +directory; symlinks allow for automatic updates from the installed ZEDLETs, whereas copies preserve local modifications. -As a security measure, ZEDLETs must be owned by root. They must have -execute permissions for the user, but they must not have write permissions -for group or other. Dotfiles are ignored. -.PP +As a security measure, since ownership change is a privileged operation, +ZEDLETs must be owned by root. +They must have execute permissions for the user, +but they must not have write permissions for group or other. +Dotfiles are ignored. +.Pp ZEDLETs are named after the zevent class for which they should be invoked. In particular, a ZEDLET will be invoked for a given zevent if either its class or subclass string is a prefix of its filename (and is followed by -a non-alphabetic character). As a special case, the prefix "all" matches -all zevents. Multiple ZEDLETs may be invoked for a given zevent. - -.SH ZEDLETS -.PP +a non-alphabetic character). +As a special case, the prefix +.Sy all +matches all zevents. +Multiple ZEDLETs may be invoked for a given zevent. +. +.Sh ZEDLETS ZEDLETs are executables invoked by the ZED in response to a given zevent. They should be written under the presumption they can be invoked concurrently, and they should use appropriate locking to access any shared resources. Common variables used by ZEDLETs can be stored in the default rc file which -is sourced by scripts; these variables should be prefixed with "ZED_". -.PP +is sourced by scripts; these variables should be prefixed with +.Sy ZED_ . +.Pp The zevent nvpairs are passed to ZEDLETs as environment variables. Each nvpair name is converted to an environment variable in the following -manner: 1) it is prefixed with "ZEVENT_", 2) it is converted to uppercase, -and 3) each non-alphanumeric character is converted to an underscore. +manner: +.Bl -enum +.It +it is prefixed with +.Sy ZEVENT_ , +.It +it is converted to uppercase, and +.It +each non-alphanumeric character is converted to an underscore. +.El +.Pp Some additional environment variables have been defined to present certain -nvpair values in a more convenient form. An incomplete list of zevent -environment variables is as follows: -.TP -.B -ZEVENT_EID +nvpair values in a more convenient form. +An incomplete list of zevent environment variables is as follows: +.Bl -tag -width "ZEVENT_TIME_STRING" +.It Sy ZEVENT_EID The Event IDentifier. -.TP -.B -ZEVENT_CLASS +.It Sy ZEVENT_CLASS The zevent class string. -.TP -.B -ZEVENT_SUBCLASS +.It Sy ZEVENT_SUBCLASS The zevent subclass string. -.TP -.B -ZEVENT_TIME +.It Sy ZEVENT_TIME The time at which the zevent was posted as -"\fIseconds\fR\ \fInanoseconds\fR" since the Epoch. -.TP -.B -ZEVENT_TIME_SECS -The \fIseconds\fR component of ZEVENT_TIME. -.TP -.B -ZEVENT_TIME_NSECS -The \fInanoseconds\fR component of ZEVENT_TIME. -.TP -.B -ZEVENT_TIME_STRING -An almost-RFC3339-compliant string for ZEVENT_TIME. -.PP +.Dq Em seconds nanoseconds +since the Epoch. +.It Sy ZEVENT_TIME_SECS +The +.Em seconds +component of +.Sy ZEVENT_TIME . +.It Sy ZEVENT_TIME_NSECS +The +.Em nanoseconds +component of +.Sy ZEVENT_TIME . +.It Sy ZEVENT_TIME_STRING +An almost-RFC3339-compliant string for +.Sy ZEVENT_TIME . +.El +.Pp Additionally, the following ZED & ZFS variables are defined: -.TP -.B -ZED_PID +.Bl -tag -width "ZEVENT_TIME_STRING" +.It Sy ZED_PID The daemon's process ID. -.TP -.B -ZED_ZEDLET_DIR -The daemon's current \fIenabled-zedlets\fR directory. -.TP -.B -ZFS_ALIAS -The ZFS alias (\fIname-version-release\fR) string used to build the daemon. -.TP -.B -ZFS_VERSION -The ZFS version used to build the daemon. -.TP -.B -ZFS_RELEASE -The ZFS release used to build the daemon. -.PP -ZEDLETs may need to call other ZFS commands. The installation paths of -the following executables are defined: \fBZDB\fR, \fBZED\fR, \fBZFS\fR, -\fBZINJECT\fR, and \fBZPOOL\fR. These variables can be overridden in the -rc file if needed. - -.SH FILES -.\" .TP -.\" @sysconfdir@/zfs/zed.conf -.\" The default configuration file for the daemon. -.TP -.I @sysconfdir@/zfs/zed.d +.It Sy ZED_ZEDLET_DIR +The daemon's current +.Em enabled-zedlets +directory. +.It Sy ZFS_ALIAS +The alias +.Pq Dq Em name Ns - Ns Em version Ns - Ns Em release +string of the ZFS distribution the daemon is part of. +.It Sy ZFS_VERSION +The ZFS version the daemon is part of. +.It Sy ZFS_RELEASE +The ZFS release the daemon is part of. +.El +.Pp +ZEDLETs may need to call other ZFS commands. +The installation paths of the following executables are defined as environment variables: +.Sy ZDB , +.Sy ZED , +.Sy ZFS , +.Sy ZINJECT , +and +.Sy ZPOOL . +These variables may be overridden in the rc file. +. +.Sh FILES +.Bl -tag -width "-c" +.It Pa @sysconfdir@/zfs/zed.d The default directory for enabled ZEDLETs. -.TP -.I @sysconfdir@/zfs/zed.d/zed.rc +.It Pa @sysconfdir@/zfs/zed.d/zed.rc The default rc file for common variables used by ZEDLETs. -.TP -.I @zfsexecdir@/zed.d +.It Pa @zfsexecdir@/zed.d The default directory for installed ZEDLETs. -.TP -.I @runstatedir@/zed.pid +.It Pa @runstatedir@/zed.pid The default file containing the daemon's process ID. -.TP -.I @runstatedir@/zed.state +.It Pa @runstatedir@/zed.state The default file containing the daemon's state. - -.SH SIGNALS -.TP -.B HUP +.El +. +.Sh SIGNALS +.Bl -tag -width "-c" +.It Sy SIGHUP Reconfigure the daemon and rescan the directory for enabled ZEDLETs. -.TP -.B TERM +.It Sy SIGTERM , SIGINT Terminate the daemon. - -.SH NOTES -.PP -\fBZED\fR requires root privileges. -.\" Do not taunt zed. - -.SH BUGS -.PP -Events are processed synchronously by a single thread. This can delay the -processing of simultaneous zevents. -.PP -ZEDLETs are killed after a maximum of ten seconds. -This can lead to a violation of a ZEDLET's atomicity assumptions. -.PP -The ownership and permissions of the \fIenabled-zedlets\fR directory (along -with all parent directories) are not checked. If any of these directories -are improperly owned or permissioned, an unprivileged user could insert a -ZEDLET to be executed as root. The requirement that ZEDLETs be owned by -root mitigates this to some extent. -.PP +.El +. +.Sh SEE ALSO +.Xr zfs-events 5 , +.Xr zfs 8 , +.Xr zpool 8 , +.Xr zpool-events 8 +. +.Sh NOTES +The +.Nm +requires root privileges. +.Pp +Do not taunt the +.Nm . +. +.Sh BUGS ZEDLETs are unable to return state/status information to the kernel. -.PP -Some zevent nvpair types are not handled. These are denoted by zevent -environment variables having a "_NOT_IMPLEMENTED_" value. -.PP +.Pp Internationalization support via gettext has not been added. -.PP -The configuration file is not yet implemented. -.PP -The diagnosis engine is not yet implemented. - -.SH LICENSE -.PP -\fBZED\fR (ZFS Event Daemon) is distributed under the terms of the -Common Development and Distribution License Version 1.0 (CDDL\-1.0). -.PP -Developed at Lawrence Livermore National Laboratory (LLNL\-CODE\-403049). - -.SH SEE ALSO -.BR zfs (8), -.BR zpool (8) -.BR zpool-events (8) diff --git a/sys/contrib/openzfs/man/man8/zfs-allow.8 b/sys/contrib/openzfs/man/man8/zfs-allow.8 index 1925112256c..070161be541 100644 --- a/sys/contrib/openzfs/man/man8/zfs-allow.8 +++ b/sys/contrib/openzfs/man/man8/zfs-allow.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -30,67 +29,69 @@ .\" Copyright 2018 Nexenta Systems, Inc. .\" Copyright 2019 Joyent, Inc. .\" -.Dd June 30, 2019 +.Dd May 27, 2021 .Dt ZFS-ALLOW 8 .Os +. .Sh NAME .Nm zfs-allow -.Nd Delegates ZFS administration permission for the file systems to non-privileged users. +.Nd delegate ZFS administration permissions to unprivileged users .Sh SYNOPSIS .Nm zfs .Cm allow .Op Fl dglu -.Ar user Ns | Ns Ar group Ns Oo , Ns Ar user Ns | Ns Ar group Oc Ns ... +.Ar user Ns | Ns Ar group Ns Oo , Ns Ar user Ns | Ns Ar group Oc Ns … .Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... +.Ar setname Oc Ns … .Ar filesystem Ns | Ns Ar volume .Nm zfs .Cm allow .Op Fl dl .Fl e Ns | Ns Sy everyone .Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... +.Ar setname Oc Ns … .Ar filesystem Ns | Ns Ar volume .Nm zfs .Cm allow .Fl c .Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... +.Ar setname Oc Ns … .Ar filesystem Ns | Ns Ar volume .Nm zfs .Cm allow .Fl s No @ Ns Ar setname .Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... +.Ar setname Oc Ns … .Ar filesystem Ns | Ns Ar volume .Nm zfs .Cm unallow .Op Fl dglru -.Ar user Ns | Ns Ar group Ns Oo , Ns Ar user Ns | Ns Ar group Oc Ns ... +.Ar user Ns | Ns Ar group Ns Oo , Ns Ar user Ns | Ns Ar group Oc Ns … .Oo Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... Oc +.Ar setname Oc Ns … Oc .Ar filesystem Ns | Ns Ar volume .Nm zfs .Cm unallow .Op Fl dlr .Fl e Ns | Ns Sy everyone .Oo Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... Oc +.Ar setname Oc Ns … Oc .Ar filesystem Ns | Ns Ar volume .Nm zfs .Cm unallow .Op Fl r .Fl c .Oo Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... Oc +.Ar setname Oc Ns … Oc .Ar filesystem Ns | Ns Ar volume .Nm zfs .Cm unallow .Op Fl r .Fl s No @ Ns Ar setname .Oo Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... Oc +.Ar setname Oc Ns … Oc .Ar filesystem Ns | Ns Ar volume +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo @@ -119,9 +120,9 @@ command restricts modifications of the global namespace to the root user. .Nm zfs .Cm allow .Op Fl dglu -.Ar user Ns | Ns Ar group Ns Oo , Ns Ar user Ns | Ns Ar group Oc Ns ... +.Ar user Ns | Ns Ar group Ns Oo , Ns Ar user Ns | Ns Ar group Oc Ns … .Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... +.Ar setname Oc Ns … .Ar filesystem Ns | Ns Ar volume .Xc .It Xo @@ -130,7 +131,7 @@ command restricts modifications of the global namespace to the root user. .Op Fl dl .Fl e Ns | Ns Sy everyone .Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... +.Ar setname Oc Ns … .Ar filesystem Ns | Ns Ar volume .Xc Delegates ZFS administration permission for the file systems to non-privileged @@ -140,15 +141,15 @@ users. Allow only for the descendent file systems. .It Fl e Ns | Ns Sy everyone Specifies that the permissions be delegated to everyone. -.It Fl g Ar group Ns Oo , Ns Ar group Oc Ns ... +.It Fl g Ar group Ns Oo , Ns Ar group Oc Ns … Explicitly specify that permissions are delegated to the group. .It Fl l Allow .Qq locally only for the specified file system. -.It Fl u Ar user Ns Oo , Ns Ar user Oc Ns ... +.It Fl u Ar user Ns Oo , Ns Ar user Oc Ns … Explicitly specify that permissions are delegated to the user. -.It Ar user Ns | Ns Ar group Ns Oo , Ns Ar user Ns | Ns Ar group Oc Ns ... +.It Ar user Ns | Ns Ar group Ns Oo , Ns Ar user Ns | Ns Ar group Oc Ns … Specifies to whom the permissions are delegated. Multiple entities can be specified as a comma-separated list. If neither of the @@ -169,7 +170,7 @@ To specify a group with the same name as a user, use the options. .It Xo .Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... +.Ar setname Oc Ns … .Xc The permissions to delegate. Multiple permissions may be specified as a comma-separated list. @@ -191,94 +192,80 @@ file system or volume, and all of its descendents. Permissions are generally the ability to use a ZFS subcommand or change a ZFS property. The following permissions are available: -.Bd -literal -NAME TYPE NOTES -allow subcommand Must also have the permission that is - being allowed -clone subcommand Must also have the 'create' ability and - 'mount' ability in the origin file system -create subcommand Must also have the 'mount' ability. - Must also have the 'refreservation' ability to - create a non-sparse volume. -destroy subcommand Must also have the 'mount' ability -diff subcommand Allows lookup of paths within a dataset - given an object number, and the ability - to create snapshots necessary to - 'zfs diff'. -hold subcommand Allows adding a user hold to a snapshot -load-key subcommand Allows loading and unloading of encryption key - (see 'zfs load-key' and 'zfs unload-key'). -change-key subcommand Allows changing an encryption key via - 'zfs change-key'. -mount subcommand Allows mount/umount of ZFS datasets -promote subcommand Must also have the 'mount' and 'promote' - ability in the origin file system -receive subcommand Must also have the 'mount' and 'create' - ability -release subcommand Allows releasing a user hold which might - destroy the snapshot -rename subcommand Must also have the 'mount' and 'create' - ability in the new parent -rollback subcommand Must also have the 'mount' ability -send subcommand -share subcommand Allows sharing file systems over NFS - or SMB protocols -snapshot subcommand Must also have the 'mount' ability +.TS +l l l . +NAME TYPE NOTES +_ _ _ +allow subcommand Must also have the permission that is being allowed +bookmark subcommand +clone subcommand Must also have the \fBcreate\fR ability and \fBmount\fR ability in the origin file system +create subcommand Must also have the \fBmount\fR ability. Must also have the \fBrefreservation\fR ability to create a non-sparse volume. +destroy subcommand Must also have the \fBmount\fR ability +diff subcommand Allows lookup of paths within a dataset given an object number, and the ability to create snapshots necessary to \fBzfs diff\fR. +hold subcommand Allows adding a user hold to a snapshot +load subcommand Allows loading and unloading of encryption key (see \fBzfs load-key\fR and \fBzfs unload-key\fR). +change subcommand Allows changing an encryption key via \fBzfs change-key\fR. +mount subcommand Allows mounting/umounting ZFS datasets +promote subcommand Must also have the \fBmount\fR and \fBpromote\fR ability in the origin file system +receive subcommand Must also have the \fBmount\fR and \fBcreate\fR ability +release subcommand Allows releasing a user hold which might destroy the snapshot +rename subcommand Must also have the \fBmount\fR and \fBcreate\fR ability in the new parent +rollback subcommand Must also have the \fBmount\fR ability +send subcommand +share subcommand Allows sharing file systems over NFS or SMB protocols +snapshot subcommand Must also have the \fBmount\fR ability -groupquota other Allows accessing any groupquota@... - property -groupused other Allows reading any groupused@... property -userprop other Allows changing any user property -userquota other Allows accessing any userquota@... - property -userused other Allows reading any userused@... property -projectobjquota other Allows accessing any projectobjquota@... - property -projectquota other Allows accessing any projectquota@... property -projectobjused other Allows reading any projectobjused@... property -projectused other Allows reading any projectused@... property +groupquota other Allows accessing any \fBgroupquota@\fI...\fR property +groupused other Allows reading any \fBgroupused@\fI...\fR property +userprop other Allows changing any user property +userquota other Allows accessing any \fBuserquota@\fI...\fR property +userused other Allows reading any \fBuserused@\fI...\fR property +projectobjquota other Allows accessing any \fBprojectobjquota@\fI...\fR property +projectquota other Allows accessing any \fBprojectquota@\fI...\fR property +projectobjused other Allows reading any \fBprojectobjused@\fI...\fR property +projectused other Allows reading any \fBprojectused@\fI...\fR property -aclinherit property -acltype property -atime property -canmount property -casesensitivity property -checksum property -compression property -copies property -devices property -exec property -filesystem_limit property -mountpoint property -nbmand property -normalization property -primarycache property -quota property -readonly property -recordsize property -refquota property -refreservation property -reservation property -secondarycache property -setuid property -sharenfs property -sharesmb property -snapdir property -snapshot_limit property -utf8only property -version property -volblocksize property -volsize property -vscan property -xattr property -zoned property -.Ed +aclinherit property +acltype property +atime property +canmount property +casesensitivity property +checksum property +compression property +copies property +devices property +exec property +filesystem_limit property +mountpoint property +nbmand property +normalization property +primarycache property +quota property +readonly property +recordsize property +refquota property +refreservation property +reservation property +secondarycache property +setuid property +sharenfs property +sharesmb property +snapdir property +snapshot_limit property +utf8only property +version property +volblocksize property +volsize property +vscan property +xattr property +zoned property +.TE .It Xo .Nm zfs .Cm allow .Fl c .Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... +.Ar setname Oc Ns … .Ar filesystem Ns | Ns Ar volume .Xc Sets @@ -292,7 +279,7 @@ to the creator of any newly-created descendent file system. .Cm allow .Fl s No @ Ns Ar setname .Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... +.Ar setname Oc Ns … .Ar filesystem Ns | Ns Ar volume .Xc Defines or adds permissions to a permission set. @@ -308,9 +295,9 @@ and can be no more than 64 characters long. .Nm zfs .Cm unallow .Op Fl dglru -.Ar user Ns | Ns Ar group Ns Oo , Ns Ar user Ns | Ns Ar group Oc Ns ... +.Ar user Ns | Ns Ar group Ns Oo , Ns Ar user Ns | Ns Ar group Oc Ns … .Oo Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... Oc +.Ar setname Oc Ns … Oc .Ar filesystem Ns | Ns Ar volume .Xc .It Xo @@ -319,7 +306,7 @@ and can be no more than 64 characters long. .Op Fl dlr .Fl e Ns | Ns Sy everyone .Oo Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... Oc +.Ar setname Oc Ns … Oc .Ar filesystem Ns | Ns Ar volume .Xc .It Xo @@ -328,7 +315,7 @@ and can be no more than 64 characters long. .Op Fl r .Fl c .Oo Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... Oc +.Ar setname Oc Ns … Oc .Ar filesystem Ns | Ns Ar volume .Xc Removes permissions that were granted with the @@ -366,7 +353,7 @@ Recursively remove the permissions from this file system and all descendents. .Op Fl r .Fl s No @ Ns Ar setname .Oo Ar perm Ns | Ns @ Ns Ar setname Ns Oo , Ns Ar perm Ns | Ns @ Ns -.Ar setname Oc Ns ... Oc +.Ar setname Oc Ns … Oc .Ar filesystem Ns | Ns Ar volume .Xc Removes permissions from a permission set. diff --git a/sys/contrib/openzfs/man/man8/zfs-bookmark.8 b/sys/contrib/openzfs/man/man8/zfs-bookmark.8 index 042ddf50443..d8833c3fbc7 100644 --- a/sys/contrib/openzfs/man/man8/zfs-bookmark.8 +++ b/sys/contrib/openzfs/man/man8/zfs-bookmark.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -31,29 +30,28 @@ .\" Copyright 2019 Joyent, Inc. .\" Copyright (c) 2019, 2020 by Christian Schwarz. All Rights Reserved. .\" -.Dd June 30, 2019 -.Dt ZFS-BOOKMARK 8 SMM +.Dd May 27, 2021 +.Dt ZFS-BOOKMARK 8 .Os +. .Sh NAME .Nm zfs-bookmark -.Nd Creates a bookmark of the given snapshot. +.Nd create bookmark of ZFS snapshot .Sh SYNOPSIS -.Sh DESCRIPTION -.Bl -tag -width "" -.It Xo .Nm zfs .Cm bookmark -.Ar snapshot Ns | Ns Ar bookmark newbookmark -.Xc +.Ar snapshot Ns | Ns Ar bookmark +.Ar newbookmark +. +.Sh DESCRIPTION Creates a new bookmark of the given snapshot or bookmark. Bookmarks mark the point in time when the snapshot was created, and can be used as the incremental source for a -.Xr zfs-send 8 -command. +.Nm zfs Cm send . .Pp When creating a bookmark from an existing redaction bookmark, the resulting bookmark is -.Sy not +.Em not a redaction bookmark. .Pp This feature must be enabled to be used. @@ -62,7 +60,7 @@ See for details on ZFS feature flags and the .Sy bookmarks feature. -.El +. .Sh SEE ALSO .Xr zfs-destroy 8 , .Xr zfs-send 8 , diff --git a/sys/contrib/openzfs/man/man8/zfs-clone.8 b/sys/contrib/openzfs/man/man8/zfs-clone.8 index 9cb84d3c56d..24784ecb9aa 100644 --- a/sys/contrib/openzfs/man/man8/zfs-clone.8 +++ b/sys/contrib/openzfs/man/man8/zfs-clone.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -30,35 +29,29 @@ .\" Copyright 2018 Nexenta Systems, Inc. .\" Copyright 2019 Joyent, Inc. .\" -.Dd June 30, 2019 +.Dd May 27, 2021 .Dt ZFS-CLONE 8 .Os +. .Sh NAME .Nm zfs-clone -.Nd Creates a clone of the given snapshot. +.Nd clone snapshot of ZFS dataset .Sh SYNOPSIS .Nm zfs .Cm clone .Op Fl p -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... +.Oo Fl o Ar property Ns = Ns Ar value Oc Ns … .Ar snapshot Ar filesystem Ns | Ns Ar volume +. .Sh DESCRIPTION -.Bl -tag -width "" -.It Xo -.Nm zfs -.Cm clone -.Op Fl p -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... -.Ar snapshot Ar filesystem Ns | Ns Ar volume -.Xc See the -.Em Clones +.Sx Clones section of .Xr zfsconcepts 8 for details. -The target dataset can be located anywhere in the ZFS hierarchy, and is created -as the same type as the original. -.Bl -tag -width "-o" +The target dataset can be located anywhere in the ZFS hierarchy, +and is created as the same type as the original. +.Bl -tag -width Ds .It Fl o Ar property Ns = Ns Ar value Sets the specified property; see .Nm zfs Cm create @@ -71,7 +64,7 @@ property inherited from their parent. If the target filesystem or volume already exists, the operation completes successfully. .El -.El +. .Sh SEE ALSO .Xr zfs-promote 8 , .Xr zfs-snapshot 8 diff --git a/sys/contrib/openzfs/man/man8/zfs-create.8 b/sys/contrib/openzfs/man/man8/zfs-create.8 index 5a4f9a32afa..100a6deeda5 100644 --- a/sys/contrib/openzfs/man/man8/zfs-create.8 +++ b/sys/contrib/openzfs/man/man8/zfs-create.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -33,28 +32,30 @@ .Dd December 1, 2020 .Dt ZFS-CREATE 8 .Os +. .Sh NAME .Nm zfs-create -.Nd Creates a new ZFS file system. +.Nd create ZFS dataset .Sh SYNOPSIS .Nm zfs .Cm create .Op Fl Pnpuv -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... +.Oo Fl o Ar property Ns = Ns Ar value Oc Ns … .Ar filesystem .Nm zfs .Cm create .Op Fl ps .Op Fl b Ar blocksize -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... +.Oo Fl o Ar property Ns = Ns Ar value Oc Ns … .Fl V Ar size Ar volume +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo .Nm zfs .Cm create .Op Fl Pnpuv -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... +.Oo Fl o Ar property Ns = Ns Ar value Oc Ns … .Ar filesystem .Xc Creates a new ZFS file system. @@ -134,7 +135,7 @@ Print verbose information about the created dataset. .Cm create .Op Fl ps .Op Fl b Ar blocksize -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... +.Oo Fl o Ar property Ns = Ns Ar value Oc Ns … .Fl V Ar size Ar volume .Xc Creates a volume of the given size. @@ -234,14 +235,14 @@ Print verbose information about the created dataset. .El .El .Ss ZFS Volumes as Swap -ZFS volumes may be used as swap devices. After creating the volume with the +ZFS volumes may be used as swap devices. +After creating the volume with the .Nm zfs Cm create Fl V -command set up and enable the swap area using the -.Xr mkswap 8 -and +enable the swap area using the .Xr swapon 8 -commands. Do not swap to a file on a ZFS file system. A ZFS swap file -configuration is not supported. +command. +Swapping to files on ZFS filesystems is not supported. +. .Sh SEE ALSO .Xr zfs-destroy 8 , .Xr zfs-list 8 , diff --git a/sys/contrib/openzfs/man/man8/zfs-destroy.8 b/sys/contrib/openzfs/man/man8/zfs-destroy.8 index b0365cc82a9..51d9b7ab8e7 100644 --- a/sys/contrib/openzfs/man/man8/zfs-destroy.8 +++ b/sys/contrib/openzfs/man/man8/zfs-destroy.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -33,9 +32,10 @@ .Dd June 30, 2019 .Dt ZFS-DESTROY 8 .Os +. .Sh NAME .Nm zfs-destroy -.Nd Destroys the given dataset(s), snapshot(s), or bookmark. +.Nd destroy ZFS dataset, snapshots, or bookmark .Sh SYNOPSIS .Nm zfs .Cm destroy @@ -45,10 +45,11 @@ .Cm destroy .Op Fl Rdnprv .Ar filesystem Ns | Ns Ar volume Ns @ Ns Ar snap Ns -.Oo % Ns Ar snap Ns Oo , Ns Ar snap Ns Oo % Ns Ar snap Oc Oc Oc Ns ... +.Oo % Ns Ar snap Ns Oo , Ns Ar snap Ns Oo % Ns Ar snap Oc Oc Oc Ns … .Nm zfs .Cm destroy .Ar filesystem Ns | Ns Ar volume Ns # Ns Ar bookmark +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo @@ -67,9 +68,7 @@ dataset that has active dependents Recursively destroy all dependents, including cloned file systems outside the target hierarchy. .It Fl f -Force an unmount of any file systems using the -.Nm unmount Fl f -command. +Forcibly unmount file systems. This option has no effect on non-file systems or unmounted file systems. .It Fl n Do a dry-run @@ -100,10 +99,10 @@ behavior for mounted file systems in use. .Cm destroy .Op Fl Rdnprv .Ar filesystem Ns | Ns Ar volume Ns @ Ns Ar snap Ns -.Oo % Ns Ar snap Ns Oo , Ns Ar snap Ns Oo % Ns Ar snap Oc Oc Oc Ns ... +.Oo % Ns Ar snap Ns Oo , Ns Ar snap Ns Oo % Ns Ar snap Oc Oc Oc Ns … .Xc The given snapshots are destroyed immediately if and only if the -.Ql zfs destroy +.Nm zfs Cm destroy command without the .Fl d option would have destroyed it. @@ -138,8 +137,8 @@ If this flag is specified, the .Fl d flag will have no effect. .It Fl d -Destroy immediately. If a snapshot cannot be destroyed now, mark it for -deferred destruction. +Destroy immediately. +If a snapshot cannot be destroyed now, mark it for deferred destruction. .It Fl n Do a dry-run .Pq Qq No-op @@ -173,6 +172,7 @@ behavior for mounted file systems in use. .Xc The given bookmark is destroyed. .El +. .Sh SEE ALSO .Xr zfs-create 8 , .Xr zfs-hold 8 diff --git a/sys/contrib/openzfs/man/man8/zfs-diff.8 b/sys/contrib/openzfs/man/man8/zfs-diff.8 index c7b9e138d84..49443bf47d1 100644 --- a/sys/contrib/openzfs/man/man8/zfs-diff.8 +++ b/sys/contrib/openzfs/man/man8/zfs-diff.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -30,25 +29,20 @@ .\" Copyright 2018 Nexenta Systems, Inc. .\" Copyright 2019 Joyent, Inc. .\" -.Dd June 30, 2019 +.Dd May 29, 2021 .Dt ZFS-DIFF 8 .Os +. .Sh NAME .Nm zfs-diff -.Nd Display the difference between two snapshots of a given filesystem. +.Nd show difference between ZFS snapshots .Sh SYNOPSIS .Nm zfs .Cm diff .Op Fl FHt .Ar snapshot Ar snapshot Ns | Ns Ar filesystem +. .Sh DESCRIPTION -.Bl -tag -width "" -.It Xo -.Nm zfs -.Cm diff -.Op Fl FHt -.Ar snapshot Ar snapshot Ns | Ns Ar filesystem -.Xc Display the difference between a snapshot of a given filesystem and another snapshot of that filesystem from a later time or the current contents of the filesystem. @@ -57,35 +51,48 @@ indicate pathname, new pathname .Pq in case of rename , change in link count, and optionally file type and/or change time. The types of change are: -.Bd -literal -- The path has been removed -+ The path has been created -M The path has been modified -R The path has been renamed -.Ed +.Bl -tag -compact -offset Ds -width "M" +.It Sy - +The path has been removed +.It Sy + +The path has been created +.It Sy M +The path has been modified +.It Sy R +The path has been renamed +.El .Bl -tag -width "-F" .It Fl F Display an indication of the type of file, in a manner similar to the .Fl F option of .Xr ls 1 . -.Bd -literal -B Block device -C Character device -/ Directory -> Door -| Named pipe -@ Symbolic link -P Event port -= Socket -F Regular file -.Ed +.Bl -tag -compact -offset 2n -width "B" +.It Sy B +Block device +.It Sy C +Character device +.It Sy / +Directory +.It Sy > +Door +.It Sy |\& +Named pipe +.It Sy @ +Symbolic link +.It Sy P +Event port +.It Sy = +Socket +.It Sy F +Regular file +.El .It Fl H Give more parsable tab-separated output, without header lines and without arrows. .It Fl t Display the path's inode change time as the first column of output. .El -.El +. .Sh SEE ALSO .Xr zfs-snapshot 8 diff --git a/sys/contrib/openzfs/man/man8/zfs-hold.8 b/sys/contrib/openzfs/man/man8/zfs-hold.8 index ac56fc4a434..5e4652092e8 100644 --- a/sys/contrib/openzfs/man/man8/zfs-hold.8 +++ b/sys/contrib/openzfs/man/man8/zfs-hold.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -33,40 +32,42 @@ .Dd June 30, 2019 .Dt ZFS-HOLD 8 .Os +. .Sh NAME .Nm zfs-hold -.Nd Hold a snapshot to prevent it being removed with the zfs destroy command. +.Nd hold ZFS snapshots to prevent their removal .Sh SYNOPSIS .Nm zfs .Cm hold .Op Fl r -.Ar tag Ar snapshot Ns ... +.Ar tag Ar snapshot Ns … .Nm zfs .Cm holds .Op Fl rH -.Ar snapshot Ns ... +.Ar snapshot Ns … .Nm zfs .Cm release .Op Fl r -.Ar tag Ar snapshot Ns ... +.Ar tag Ar snapshot Ns … +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo .Nm zfs .Cm hold .Op Fl r -.Ar tag Ar snapshot Ns ... +.Ar tag Ar snapshot Ns … .Xc Adds a single reference, named with the .Ar tag -argument, to the specified snapshot or snapshots. +argument, to the specified snapshots. Each snapshot has its own tag namespace, and tags must be unique within that space. .Pp If a hold exists on a snapshot, attempts to destroy that snapshot by using the .Nm zfs Cm destroy command return -.Er EBUSY . +.Sy EBUSY . .Bl -tag -width "-r" .It Fl r Specifies that a hold with the given tag is applied recursively to the snapshots @@ -76,7 +77,7 @@ of all descendent file systems. .Nm zfs .Cm holds .Op Fl rH -.Ar snapshot Ns ... +.Ar snapshot Ns … .Xc Lists all existing user references for the given snapshot or snapshots. .Bl -tag -width "-r" @@ -90,7 +91,7 @@ Do not print headers, use tab-delimited output. .Nm zfs .Cm release .Op Fl r -.Ar tag Ar snapshot Ns ... +.Ar tag Ar snapshot Ns … .Xc Removes a single reference, named with the .Ar tag @@ -99,12 +100,13 @@ The tag must already exist for each snapshot. If a hold exists on a snapshot, attempts to destroy that snapshot by using the .Nm zfs Cm destroy command return -.Er EBUSY . +.Sy EBUSY . .Bl -tag -width "-r" .It Fl r Recursively releases a hold with the given tag on the snapshots of all descendent file systems. .El .El +. .Sh SEE ALSO .Xr zfs-destroy 8 diff --git a/sys/contrib/openzfs/man/man8/zfs-jail.8 b/sys/contrib/openzfs/man/man8/zfs-jail.8 index 4c439d53f0d..d4a04073edb 100644 --- a/sys/contrib/openzfs/man/man8/zfs-jail.8 +++ b/sys/contrib/openzfs/man/man8/zfs-jail.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -37,82 +36,87 @@ .\" Copyright 2018 Nexenta Systems, Inc. .\" Copyright 2019 Joyent, Inc. .\" -.Dd December 9, 2019 +.Dd May 27, 2021 .Dt ZFS-JAIL 8 -.Os FreeBSD +.Os +. .Sh NAME .Nm zfs-jail -.Nd Attaches and detaches ZFS filesystems from FreeBSD jails. -.No A Tn ZFS -dataset can be attached to a jail by using the -.Qq Nm Cm jail -subcommand. You cannot attach a dataset to one jail and the children of the -same dataset to another jail. You can also not attach the root file system -of the jail or any dataset which needs to be mounted before the zfs rc script -is run inside the jail, as it would be attached unmounted until it is -mounted from the rc script inside the jail. To allow management of the -dataset from within a jail, the -.Sy jailed -property has to be set and the jail needs access to the -.Pa /dev/zfs -device. The -.Sy quota -property cannot be changed from within a jail. See -.Xr jail 8 -for information on how to allow mounting -.Tn ZFS -datasets from within a jail. -.Pp -.No A Tn ZFS -dataset can be detached from a jail using the -.Qq Nm Cm unjail -subcommand. -.Pp -After a dataset is attached to a jail and the jailed property is set, a jailed -file system cannot be mounted outside the jail, since the jail administrator -might have set the mount point to an unacceptable value. +.Nd attach or detach ZFS filesystem from FreeBSD jail .Sh SYNOPSIS -.Nm zfs -.Cm jail -.Ar jailid Ns | Ns Ar jailname filesystem -.Nm zfs -.Cm unjail -.Ar jailid Ns | Ns Ar jailname filesystem +.Nm zfs Cm jail +.Ar jailid Ns | Ns Ar jailname +.Ar filesystem +.Nm zfs Cm unjail +.Ar jailid Ns | Ns Ar jailname +.Ar filesystem +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo .Nm zfs .Cm jail -.Ar jailid filesystem +.Ar jailid Ns | Ns Ar jailname +.Ar filesystem .Xc -.Pp -Attaches the specified +Attach the specified .Ar filesystem to the jail identified by JID -.Ar jailid . +.Ar jailid +or name +.Ar jailname . From now on this file system tree can be managed from within a jail if the .Sy jailed -property has been set. To use this functuinality, the jail needs the -.Va allow.mount +property has been set. +To use this functionality, the jail needs the +.Sy allow.mount and -.Va allow.mount.zfs -parameters set to 1 and the -.Va enforce_statfs -parameter set to a value lower than 2. +.Sy allow.mount.zfs +parameters set to +.Sy 1 +and the +.Sy enforce_statfs +parameter set to a value lower than +.Sy 2 . +.Pp +You cannot attach a jailed dataset's children to another jail. +You can also not attach the root file system +of the jail or any dataset which needs to be mounted before the zfs rc script +is run inside the jail, as it would be attached unmounted until it is +mounted from the rc script inside the jail. +.Pp +To allow management of the dataset from within a jail, the +.Sy jailed +property has to be set and the jail needs access to the +.Pa /dev/zfs +device. +The +.Sy quota +property cannot be changed from within a jail. +.Pp +After a dataset is attached to a jail and the +.Sy jailed +property is set, a jailed file system cannot be mounted outside the jail, +since the jail administrator might have set the mount point to an unacceptable value. .Pp See .Xr jail 8 -for more information on managing jails and configuring the parameters above. +for more information on managing jails. +Jails are a +.Fx +feature and are not relevant on other platforms. .It Xo .Nm zfs .Cm unjail -.Ar jailid filesystem +.Ar jailid Ns | Ns Ar jailname +.Ar filesystem .Xc -.Pp Detaches the specified .Ar filesystem from the jail identified by JID -.Ar jailid . +.Ar jailid +or name +.Ar jailname . .El .Sh SEE ALSO .Xr jail 8 , diff --git a/sys/contrib/openzfs/man/man8/zfs-list.8 b/sys/contrib/openzfs/man/man8/zfs-list.8 index 3ed74955e94..0313b3a14ec 100644 --- a/sys/contrib/openzfs/man/man8/zfs-list.8 +++ b/sys/contrib/openzfs/man/man8/zfs-list.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -30,35 +29,25 @@ .\" Copyright 2018 Nexenta Systems, Inc. .\" Copyright 2019 Joyent, Inc. .\" -.Dd June 30, 2019 +.Dd May 27, 2021 .Dt ZFS-LIST 8 .Os +. .Sh NAME .Nm zfs-list -.Nd Lists the property information for the given datasets in tabular form. +.Nd list properties of ZFS datasets .Sh SYNOPSIS .Nm zfs .Cm list .Op Fl r Ns | Ns Fl d Ar depth .Op Fl Hp -.Oo Fl o Ar property Ns Oo , Ns Ar property Oc Ns ... Oc -.Oo Fl s Ar property Oc Ns ... -.Oo Fl S Ar property Oc Ns ... -.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc -.Oo Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Oc Ns ... +.Oo Fl o Ar property Ns Oo , Ns Ar property Oc Ns … Oc +.Oo Fl s Ar property Oc Ns … +.Oo Fl S Ar property Oc Ns … +.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns … Oc +.Oo Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Oc Ns … +. .Sh DESCRIPTION -.Bl -tag -width "" -.It Xo -.Nm zfs -.Cm list -.Op Fl r Ns | Ns Fl d Ar depth -.Op Fl Hp -.Oo Fl o Ar property Ns Oo , Ns Ar property Oc Ns ... Oc -.Oo Fl s Ar property Oc Ns ... -.Oo Fl S Ar property Oc Ns ... -.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc -.Oo Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Oc Ns ... -.Xc If specified, you can list property information by the absolute pathname or the relative pathname. By default, all file systems and volumes are displayed. @@ -75,7 +64,7 @@ or .Fl t Sy all options are specified. The following fields are displayed: -.Sy name Ns \&, Sy used Ns \&, Sy available Ns \&, Sy referenced Ns \&, Sy mountpoint Ns . +.Sy name , Sy used , Sy available , Sy referenced , Sy mountpoint . .Bl -tag -width "-H" .It Fl H Used for scripting mode. @@ -96,10 +85,10 @@ will display only the dataset and its direct children. .It Fl o Ar property A comma-separated list of properties to display. The property must be: -.Bl -bullet +.Bl -bullet -compact .It One of the properties described in the -.Em Native Properties +.Sx Native Properties section of .Xr zfsprops 8 .It @@ -113,10 +102,9 @@ The value .Sy space to display space usage properties on file systems and volumes. This is a shortcut for specifying -.Fl o Sy name Ns \&, Ns Sy avail Ns \&, Ns Sy used Ns \&, Ns Sy usedsnap Ns \&, Ns -.Sy usedds Ns \&, Ns Sy usedrefreserv Ns \&, Ns Sy usedchild Fl t -.Sy filesystem Ns \&, Ns Sy volume -syntax. +.Fl o Ns \ \& Ns Sy name , Ns Sy avail , Ns Sy used , Ns Sy usedsnap , Ns +.Sy usedds , Ns Sy usedrefreserv , Ns Sy usedchild +.Fl t Sy filesystem , Ns Sy volume . .El .It Fl p Display numbers in parsable @@ -128,7 +116,7 @@ Recursively display any children of the dataset on the command line. A property for sorting the output by column in ascending order based on the value of the property. The property must be one of the properties described in the -.Em Properties +.Sx Properties section of .Xr zfsprops 8 or the value @@ -141,7 +129,7 @@ Multiple .Fl s options are evaluated from left to right in decreasing order of importance. The following is a list of sorting criteria: -.Bl -bullet +.Bl -bullet -compact .It Numeric types sort in numeric order. .It @@ -168,7 +156,7 @@ For example, specifying .Fl t Sy snapshot displays only snapshots. .El -.El +. .Sh SEE ALSO .Xr zfs-get 8 , .Xr zfsprops 8 diff --git a/sys/contrib/openzfs/man/man8/zfs-load-key.8 b/sys/contrib/openzfs/man/man8/zfs-load-key.8 index 7d273ddd53b..f29d3df824f 100644 --- a/sys/contrib/openzfs/man/man8/zfs-load-key.8 +++ b/sys/contrib/openzfs/man/man8/zfs-load-key.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -33,19 +32,20 @@ .Dd January 13, 2020 .Dt ZFS-LOAD-KEY 8 .Os +. .Sh NAME .Nm zfs-load-key -.Nd Load, unload, or change the encryption key used to access a dataset. +.Nd load, unload, or change encryption key of ZFS dataset .Sh SYNOPSIS .Nm zfs .Cm load-key .Op Fl nr .Op Fl L Ar keylocation -.Fl a | Ar filesystem +.Fl a Ns | Ns Ar filesystem .Nm zfs .Cm unload-key .Op Fl r -.Fl a | Ar filesystem +.Fl a Ns | Ns Ar filesystem .Nm zfs .Cm change-key .Op Fl l @@ -58,6 +58,7 @@ .Fl i .Op Fl l .Ar filesystem +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo @@ -65,23 +66,26 @@ .Cm load-key .Op Fl nr .Op Fl L Ar keylocation -.Fl a | Ar filesystem +.Fl a Ns | Ns Ar filesystem .Xc Load the key for .Ar filesystem , allowing it and all children that inherit the .Sy keylocation -property to be accessed. The key will be expected in the format specified by the +property to be accessed. +The key will be expected in the format specified by the .Sy keyformat and location specified by the .Sy keylocation -property. Note that if the +property. +Note that if the .Sy keylocation is set to .Sy prompt -the terminal will interactively wait for the key to be entered. Loading a key -will not automatically mount the dataset. If that functionality is desired, -.Nm zfs Cm mount Sy -l +the terminal will interactively wait for the key to be entered. +Loading a key will not automatically mount the dataset. +If that functionality is desired, +.Nm zfs Cm mount Fl l will ask for the key and mount the dataset .Po see @@ -100,16 +104,19 @@ Loads the keys for all encryption roots in all imported pools. .It Fl n Do a dry-run .Pq Qq No-op -load-key. This will cause zfs to simply check that the -provided key is correct. This command may be run even if the key is already -loaded. +.Cm load-key . +This will cause +.Nm zfs +to simply check that the provided key is correct. +This command may be run even if the key is already loaded. .It Fl L Ar keylocation Use .Ar keylocation instead of the .Sy keylocation -property. This will not change the value of the property on the dataset. Note -that if used with either +property. +This will not change the value of the property on the dataset. +Note that if used with either .Fl r or .Fl a , @@ -121,13 +128,14 @@ may only be given as .Nm zfs .Cm unload-key .Op Fl r -.Fl a | Ar filesystem +.Fl a Ns | Ns Ar filesystem .Xc Unloads a key from ZFS, removing the ability to access the dataset and all of its children that inherit the .Sy keylocation -property. This requires that the dataset is not currently open or mounted. Once -the key is unloaded the +property. +This requires that the dataset is not currently open or mounted. +Once the key is unloaded the .Sy keystatus property will become .Sy unavailable . @@ -154,15 +162,16 @@ Unloads the keys for all encryption roots in all imported pools. .Op Fl l .Ar filesystem .Xc -Changes the user's key (e.g. a passphrase) used to access a dataset. This -command requires that the existing key for the dataset is already loaded into -ZFS. This command may also be used to change the +Changes the user's key (e.g. a passphrase) used to access a dataset. +This command requires that the existing key for the dataset is already loaded. +This command may also be used to change the .Sy keylocation , .Sy keyformat , and .Sy pbkdf2iters -properties as needed. If the dataset was not previously an encryption root it -will become one. Alternatively, the +properties as needed. +If the dataset was not previously an encryption root it will become one. +Alternatively, the .Fl i flag may be provided to cause an encryption root to inherit the parent's key instead. @@ -171,36 +180,33 @@ If the user's key is compromised, .Nm zfs Cm change-key does not necessarily protect existing or newly-written data from attack. Newly-written data will continue to be encrypted with the same master key as -the existing data. The master key is compromised if an attacker obtains a -user key and the corresponding wrapped master key. Currently, +the existing data. +The master key is compromised if an attacker obtains a +user key and the corresponding wrapped master key. +Currently, .Nm zfs Cm change-key does not overwrite the previous wrapped master key on disk, so it is accessible via forensic analysis for an indeterminate length of time. .Pp In the event of a master key compromise, ideally the drives should be securely erased to remove all the old data (which is readable using the compromised -master key), a new pool created, and the data copied back. This can be -approximated in place by creating new datasets, copying the data -(e.g. using -.Nm zfs Cm send -| -.Nm zfs Cm recv Ns -), and then clearing the free space with -.Nm zpool Cm trim --secure +master key), a new pool created, and the data copied back. +This can be approximated in place by creating new datasets, copying the data +.Pq e.g. using Nm zfs Cm send | Nm zfs Cm recv , +and then clearing the free space with +.Nm zpool Cm trim Fl -secure if supported by your hardware, otherwise -.Nm zpool Cm initialize Ns . +.Nm zpool Cm initialize . .Bl -tag -width "-r" .It Fl l -Ensures the key is loaded before attempting to change the key. This is -effectively equivalent to -.Qq Nm zfs Cm load-key Ar filesystem ; Nm zfs Cm change-key Ar filesystem +Ensures the key is loaded before attempting to change the key. +This is effectively equivalent to runnin +.Nm zfs Cm load-key Ar filesystem ; Nm zfs Cm change-key Ar filesystem .It Fl o Ar property Ns = Ns Ar value -Allows the user to set encryption key properties ( -.Sy keyformat , -.Sy keylocation , -and -.Sy pbkdf2iters -) while changing the key. This is the only way to alter +Allows the user to set encryption key properties +.Pq Sy keyformat , keylocation , No and Sy pbkdf2iters +while changing the key. +This is the only way to alter .Sy keyformat and .Sy pbkdf2iters @@ -208,44 +214,43 @@ after the dataset has been created. .It Fl i Indicates that zfs should make .Ar filesystem -inherit the key of its parent. Note that this command can only be run on an -encryption root that has an encrypted parent. +inherit the key of its parent. +Note that this command can only be run on an encryption root +that has an encrypted parent. .El .El .Ss Encryption Enabling the .Sy encryption -feature allows for the creation of encrypted filesystems and volumes. ZFS -will encrypt file and zvol data, file attributes, ACLs, permission bits, +feature allows for the creation of encrypted filesystems and volumes. +ZFS will encrypt file and volume data, file attributes, ACLs, permission bits, directory listings, FUID mappings, and -.Sy userused -/ -.Sy groupused -data. ZFS will not encrypt metadata related to the pool structure, including +.Sy userused Ns / Ns Sy groupused +data. +ZFS will not encrypt metadata related to the pool structure, including dataset and snapshot names, dataset hierarchy, properties, file size, file holes, and deduplication tables (though the deduplicated data itself is encrypted). .Pp -Key rotation is managed by ZFS. Changing the user's key (e.g. a passphrase) -does not require re-encrypting the entire dataset. Datasets can be scrubbed, +Key rotation is managed by ZFS. +Changing the user's key (e.g. a passphrase) +does not require re-encrypting the entire dataset. +Datasets can be scrubbed, resilvered, renamed, and deleted without the encryption keys being loaded (see the -.Nm zfs Cm load-key +.Cm load-key subcommand for more info on key loading). .Pp Creating an encrypted dataset requires specifying the -.Sy encryption -and -.Sy keyformat +.Sy encryption No and Sy keyformat properties at creation time, along with an optional -.Sy keylocation -and -.Sy pbkdf2iters . +.Sy keylocation No and Sy pbkdf2iters . After entering an encryption key, the -created dataset will become an encryption root. Any descendant datasets will +created dataset will become an encryption root. +Any descendant datasets will inherit their encryption key from the encryption root by default, meaning that loading, unloading, or changing the key for the encryption root will implicitly -do the same for all inheriting datasets. If this inheritance is not desired, -simply supply a +do the same for all inheriting datasets. +If this inheritance is not desired, simply supply a .Sy keyformat when creating the child dataset or use .Nm zfs Cm change-key @@ -256,39 +261,40 @@ may match that of the parent while still creating a new encryption root, and that changing the .Sy encryption property alone does not create a new encryption root; this would simply use a -different cipher suite with the same key as its encryption root. The one -exception is that clones will always use their origin's encryption key. -As a result of this exception, some encryption-related properties (namely -.Sy keystatus , -.Sy keyformat , -.Sy keylocation , -and -.Sy pbkdf2iters ) +different cipher suite with the same key as its encryption root. +The one exception is that clones will always use their origin's encryption key. +As a result of this exception, some encryption-related properties +.Pq namely Sy keystatus , keyformat , keylocation , No and Sy pbkdf2iters do not inherit like other ZFS properties and instead use the value determined -by their encryption root. Encryption root inheritance can be tracked via the -read-only +by their encryption root. +Encryption root inheritance can be tracked via the read-only .Sy encryptionroot property. .Pp Encryption changes the behavior of a few ZFS -operations. Encryption is applied after compression so compression ratios are -preserved. Normally checksums in ZFS are 256 bits long, but for encrypted data +operations. +Encryption is applied after compression so compression ratios are preserved. +Normally checksums in ZFS are 256 bits long, but for encrypted data the checksum is 128 bits of the user-chosen checksum and 128 bits of MAC from the encryption suite, which provides additional protection against maliciously -altered data. Deduplication is still possible with encryption enabled but for -security, datasets will only dedup against themselves, their snapshots, and -their clones. +altered data. +Deduplication is still possible with encryption enabled but for security, +datasets will only deduplicate against themselves, their snapshots, +and their clones. .Pp -There are a few limitations on encrypted datasets. Encrypted data cannot be -embedded via the +There are a few limitations on encrypted datasets. +Encrypted data cannot be embedded via the .Sy embedded_data -feature. Encrypted datasets may not have +feature. +Encrypted datasets may not have .Sy copies Ns = Ns Em 3 since the implementation stores some encryption metadata where the third copy -would normally be. Since compression is applied before encryption datasets may -be vulnerable to a CRIME-like attack if applications accessing the data allow -for it. Deduplication with encryption will leak information about which blocks -are equivalent in a dataset and will incur an extra CPU cost per block written. +would normally be. +Since compression is applied before encryption, datasets may +be vulnerable to a CRIME-like attack if applications accessing the data allow for it. +Deduplication with encryption will leak information about which blocks +are equivalent in a dataset and will incur an extra CPU cost for each block written. +. .Sh SEE ALSO .Xr zfs-create 8 , .Xr zfs-set 8 , diff --git a/sys/contrib/openzfs/man/man8/zfs-mount-generator.8.in b/sys/contrib/openzfs/man/man8/zfs-mount-generator.8.in index 3b8c9c3ae24..e4117101beb 100644 --- a/sys/contrib/openzfs/man/man8/zfs-mount-generator.8.in +++ b/sys/contrib/openzfs/man/man8/zfs-mount-generator.8.in @@ -21,228 +21,172 @@ .\" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION .\" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION .\" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -.TH ZFS-MOUNT-GENERATOR 8 "Aug 24, 2020" OpenZFS - -.SH "NAME" -zfs\-mount\-generator \- generates systemd mount units for ZFS -.SH SYNOPSIS -.B @systemdgeneratordir@/zfs\-mount\-generator -.sp -.SH DESCRIPTION -zfs\-mount\-generator implements the \fBGenerators Specification\fP -of -.BR systemd (1), -and is called during early boot to generate -.BR systemd.mount (5) -units for automatically mounted datasets. Mount ordering and dependencies -are created for all tracked pools (see below). - -.SS ENCRYPTION KEYS -If the dataset is an encryption root, a service that loads the associated key (either from file or through a -.BR systemd\-ask\-password (1) -prompt) will be created. This service -. BR RequiresMountsFor -the path of the key (if file-based) and also copies the mount unit's -.BR After , -.BR Before -and -.BR Requires . -All mount units of encrypted datasets add the key\-load service for their encryption root to their -.BR Wants -and -.BR After . -The service will not be -.BR Want ed -or -.BR Require d -by -.BR local-fs.target -directly, and so will only be started manually or as a dependency of a started mount unit. - -.SS UNIT ORDERING AND DEPENDENCIES -mount unit's -.BR Before -\-> -key\-load service (if any) -\-> -mount unit -\-> -mount unit's -.BR After - -It is worth nothing that when a mount unit is activated, it activates all available mount units for parent paths to its mountpoint, i.e. activating the mount unit for /tmp/foo/1/2/3 automatically activates all available mount units for /tmp, /tmp/foo, /tmp/foo/1, and /tmp/foo/1/2. This is true for any combination of mount units from any sources, not just ZFS. - -.SS CACHE FILE -Because ZFS pools may not be available very early in the boot process, -information on ZFS mountpoints must be stored separately. The output of the command -.PP -.RS 4 -zfs list -H -o name,mountpoint,canmount,atime,relatime,devices,exec,readonly,setuid,nbmand,encroot,keylocation,org.openzfs.systemd:requires,org.openzfs.systemd:requires-mounts-for,org.openzfs.systemd:before,org.openzfs.systemd:after,org.openzfs.systemd:wanted-by,org.openzfs.systemd:required-by,org.openzfs.systemd:nofail,org.openzfs.systemd:ignore - -.RE -.PP -for datasets that should be mounted by systemd, should be kept -separate from the pool, at -.PP -.RS 4 -.RI @sysconfdir@/zfs/zfs-list.cache/ POOLNAME +.\" +.Dd May 31, 2021 +.Dt ZFS-MOUNT-GENERATOR 8 +.Os . -.RE -.PP -The cache file, if writeable, will be kept synchronized with the pool -state by the ZEDLET -.PP -.RS 4 -history_event-zfs-list-cacher.sh . -.RE -.PP -.sp -.SS PROPERTIES -The behavior of the generator script can be influenced by the following dataset properties: -.sp -.TP 4 -.BR canmount = on | off | noauto -If a dataset has -.BR mountpoint -set and -.BR canmount -is not -.BR off , -a mount unit will be generated. -Additionally, if -.BR canmount -is -.BR on , -.BR local-fs.target -will gain a dependency on the mount unit. - -This behavior is equal to the -.BR auto +.Sh NAME +.Nm zfs-mount-generator +.Nd generate systemd mount units for ZFS filesystems +.Sh SYNOPSIS +.Pa @systemdgeneratordir@/zfs-mount-generator +. +.Sh DESCRIPTION +.Nm +is a +.Xr systemd.generator 7 +that generates native +.Xr systemd.mount 5 +units for configured ZFS datasets. +. +.Ss Properties +.Bl -tag -compact -width "org.openzfs.systemd:required-by=unit[ unit]…" +.It Sy mountpoint Ns = +.No Skipped if Sy legacy No or Sy none . +. +.It Sy canmount Ns = +.No Skipped if Sy off . +.No Skipped if only Sy noauto +datasets exist for a given mountpoint and there's more than one. +.No Datasets with Sy yes No take precedence over ones with Sy noauto No for the same mountpoint. +.No Sets logical Em noauto No flag if Sy noauto . +Encryption roots always generate +.Sy zfs-load-key@ Ns Ar root Ns Sy .service , +even if +.Sy off . +. +.It Sy atime Ns = , Sy relatime Ns = , Sy devices Ns = , Sy exec Ns = , Sy readonly Ns = , Sy setuid Ns = , Sy nbmand Ns = +Used to generate mount options equivalent to +.Nm zfs Cm mount . +. +.It Sy encroot Ns = , Sy keylocation Ns = +If the dataset is an encryption root, its mount unit will bind to +.Sy zfs-load-key@ Ns Ar root Ns Sy .service , +with additional dependencies as follows: +.Bl -tag -compact -offset Ds -width "keylocation=https://URL (et al.)" +.It Sy keylocation Ns = Ns Sy prompt +None, uses +.Xr systemd-ask-password 1 +.It Sy keylocation Ns = Ns Sy https:// Ns Ar URL Pq et al.\& +.Sy Wants Ns = , Sy After Ns = : Pa network-online.target +.It Sy keylocation Ns = Ns Sy file:// Ns < Ns Ar path Ns > +.Sy RequiresMountsFor Ns = Ns Ar path +.El +. +The service also uses the same +.Sy Wants Ns = , +.Sy After Ns = , +.Sy Requires Ns = , No and +.Sy RequiresMountsFor Ns = , +as the mount unit. +. +.It Sy org.openzfs.systemd:requires Ns = Ns Pa path Ns Oo " " Ns Pa path Oc Ns … +.No Sets Sy Requires Ns = for the mount- and key-loading unit. +. +.It Sy org.openzfs.systemd:requires-mounts-for Ns = Ns Pa path Ns Oo " " Ns Pa path Oc Ns … +.No Sets Sy RequiresMountsFor Ns = for the mount- and key-loading unit. +. +.It Sy org.openzfs.systemd:before Ns = Ns Pa unit Ns Oo " " Ns Pa unit Oc Ns … +.No Sets Sy Before Ns = for the mount unit. +. +.It Sy org.openzfs.systemd:after Ns = Ns Pa unit Ns Oo " " Ns Pa unit Oc Ns … +.No Sets Sy After Ns = for the mount unit. +. +.It Sy org.openzfs.systemd:wanted-by Ns = Ns Pa unit Ns Oo " " Ns Pa unit Oc Ns … +.No Sets logical Em noauto No flag (see below). +.No If not Sy none , No sets Sy WantedBy Ns = for the mount unit. +.It Sy org.openzfs.systemd:required-by Ns = Ns Pa unit Ns Oo " " Ns Pa unit Oc Ns … +.No Sets logical Em noauto No flag (see below). +.No If not Sy none , No sets Sy RequiredBy Ns = for the mount unit. +. +.It Sy org.openzfs.systemd:nofail Ns = Ns (unset) Ns | Ns Sy on Ns | Ns Sy off +Waxes or wanes strength of default reverse dependencies of the mount unit, see below. +. +.It Sy org.openzfs.systemd:ignore Ns = Ns Sy on Ns | Ns Sy off +.No Skip if Sy on . +.No Defaults to Sy off . +.El +. +.Ss Unit Ordering And Dependencies +Additionally, unless the pool the dataset resides on +is imported at generation time, both units gain +.Sy Wants Ns = Ns Pa zfs-import.target and -.BR noauto -legacy mount options, see -.BR systemd.mount (5). - -Encryption roots always generate a key-load service, even for -.BR canmount=off . -.TP 4 -.BR org.openzfs.systemd:requires\-mounts\-for = \fIpath\fR... -Space\-separated list of mountpoints to require to be mounted for this mount unit -.TP 4 -.BR org.openzfs.systemd:before = \fIunit\fR... -The mount unit and associated key\-load service will be ordered before this space\-separated list of units. -.TP 4 -.BR org.openzfs.systemd:after = \fIunit\fR... -The mount unit and associated key\-load service will be ordered after this space\-separated list of units. -.TP 4 -.BR org.openzfs.systemd:wanted\-by = \fIunit\fR... -Space-separated list of units that will gain a -.BR Wants -dependency on this mount unit. -Setting this property implies -.BR noauto . -.TP 4 -.BR org.openzfs.systemd:required\-by = \fIunit\fR... -Space-separated list of units that will gain a -.BR Requires -dependency on this mount unit. -Setting this property implies -.BR noauto . -.TP 4 -.BR org.openzfs.systemd:nofail = unset | on | off -Toggles between a -.BR Wants -and -.BR Requires -type of dependency between the mount unit and -.BR local-fs.target , -if -.BR noauto -isn't set or implied. - -.BR on : -Mount will be -.BR WantedBy -local-fs.target - -.BR off : -Mount will be -.BR Before -and -.BR RequiredBy -local-fs.target - -.BR unset : -Mount will be -.BR Before -and -.BR WantedBy -local-fs.target -.TP 4 -.BR org.openzfs.systemd:ignore = on | off -If set to -.BR on , -do not generate a mount unit for this dataset. - -.RE -See also -.BR systemd.mount (5) - -.PP -.SH EXAMPLE +.Sy After Ns = Ns Pa zfs-import.target . +.Pp +Additionally, unless the logical +.Em noauto +flag is set, the mount unit gains a reverse-dependency for +.Pa local-fs.target +of strength +.Bl -tag -compact -offset Ds -width "(unset)" +.It (unset) +.Sy WantedBy Ns = No + Sy Before Ns = +.It Sy on +.Sy WantedBy Ns = +.It Sy off +.Sy RequiredBy Ns = No + Sy Before Ns = +.El +. +.Ss Cache File +Because ZFS pools may not be available very early in the boot process, +information on ZFS mountpoints must be stored separately. +The output of +.Dl Nm zfs Cm list Fl Ho Ar name , Ns Aq every property above in order +for datasets that should be mounted by systemd should be kept at +.Pa @sysconfdir@/zfs/zfs-list.cache/ Ns Ar poolname , +and, if writeable, will be kept synchronized for the entire pool by the +.Pa history_event-zfs-list-cacher.sh +ZEDLET, if enabled +.Pq see Xr zed 8 . +. +.Sh ENVIRONMENT +The +.Sy ZFS_DEBUG +environment variable can either be +.Sy 0 +(default), +.Sy 1 +(print summary accounting information at the end), or at least +.Sy 2 +(print accounting information for each subprocess as it finishes). +. +If not present, +.Pa /proc/cmdline +is additionally checked for +.Qq debug , +in which case the debug level is set to +.Sy 2 . +. +.Sh EXAMPLES To begin, enable tracking for the pool: -.PP -.RS 4 -touch -.RI @sysconfdir@/zfs/zfs-list.cache/ POOLNAME -.RE -.PP -Then, enable the tracking ZEDLET: -.PP -.RS 4 -ln -s "@zfsexecdir@/zed.d/history_event-zfs-list-cacher.sh" "@sysconfdir@/zfs/zed.d" - -systemctl enable zfs-zed.service - -systemctl restart zfs-zed.service -.RE -.PP -Force the running of the ZEDLET by setting a monitored property, e.g. -.BR canmount , -for at least one dataset in the pool: -.PP -.RS 4 -zfs set canmount=on -.I DATASET -.RE -.PP -This forces an update to the stale cache file. - -To test the generator output, run -.PP -.RS 4 -@systemdgeneratordir@/zfs-mount-generator /tmp/zfs-mount-generator . . -.RE -.PP -This will generate units and dependencies in -.I /tmp/zfs-mount-generator -for you to inspect them. The second and third argument are ignored. - -If you're satisfied with the generated units, instruct systemd to re-run all generators: -.PP -.RS 4 -systemctl daemon-reload -.RE -.PP - -.sp -.SH SEE ALSO -.BR zfs (5) -.BR zfs-events (5) -.BR zed (8) -.BR zpool (5) -.BR systemd (1) -.BR systemd.target (5) -.BR systemd.special (7) -.BR systemd.mount (7) +.Dl # Nm touch Pa @sysconfdir@/zfs/zfs-list.cache/ Ns Ar poolname +Then enable the tracking ZEDLET: +.Dl # Nm ln Fl s Pa @zfsexecdir@/zed.d/history_event-zfs-list-cacher.sh @sysconfdir@/zfs/zed.d +.Dl # Nm systemctl Cm enable Pa zfs-zed.service +.Dl # Nm systemctl Cm restart Pa zfs-zed.service +.Pp +If no history event is in the queue, +inject one to ensure the ZEDLET runs to refresh the cache file +by setting a monitored property somewhere on the pool: +.Dl # Nm zfs Cm set Sy relatime Ns = Ns Sy off Ar poolname/dset +.Dl # Nm zfs Cm inherit Sy relatime Ar poolname/dset +.Pp +To test the generator output: +.Dl $ Nm mkdir Pa /tmp/zfs-mount-generator +.Dl $ Nm @systemdgeneratordir@/zfs-mount-generator Pa /tmp/zfs-mount-generator +. +If the generated units are satisfactory, instruct +.Nm systemd +to re-run all generators: +.Dl # Nm systemctl daemon-reload +. +.Sh SEE ALSO +.Xr systemd.mount 5 , +.Xr systemd.target 5 , +.Xr zfs 5 , +.Xr zfs-events 5 , +.Xr systemd.generator 7 , +.Xr systemd.special 7 , +.Xr zed 8 diff --git a/sys/contrib/openzfs/man/man8/zfs-mount.8 b/sys/contrib/openzfs/man/man8/zfs-mount.8 index 00fb37c786e..62275242c9f 100644 --- a/sys/contrib/openzfs/man/man8/zfs-mount.8 +++ b/sys/contrib/openzfs/man/man8/zfs-mount.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -33,9 +32,10 @@ .Dd February 16, 2019 .Dt ZFS-MOUNT 8 .Os +. .Sh NAME .Nm zfs-mount -.Nd Manage mount state of ZFS file systems. +.Nd manage mount state of ZFS filesystems .Sh SYNOPSIS .Nm zfs .Cm mount @@ -43,11 +43,12 @@ .Cm mount .Op Fl Oflv .Op Fl o Ar options -.Fl a | Ar filesystem +.Fl a Ns | Ns Ar filesystem .Nm zfs .Cm unmount .Op Fl fu -.Fl a | Ar filesystem Ns | Ns Ar mountpoint +.Fl a Ns | Ns Ar filesystem Ns | Ns Ar mountpoint +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo @@ -60,11 +61,12 @@ Displays all ZFS file systems currently mounted. .Cm mount .Op Fl Oflv .Op Fl o Ar options -.Fl a | Ar filesystem +.Fl a Ns | Ns Ar filesystem .Xc Mount ZFS filesystem on a path described by its .Sy mountpoint -property, if the path exists and is empty. If +property, if the path exists and is empty. +If .Sy mountpoint is set to .Em legacy , @@ -72,7 +74,8 @@ the filesystem should be instead mounted using .Xr mount 8 . .Bl -tag -width "-O" .It Fl O -Perform an overlay mount. Allows mounting in non-empty +Perform an overlay mount. +Allows mounting in non-empty .Sy mountpoint . See .Xr mount 8 @@ -91,13 +94,12 @@ section of .Xr zfsprops 8 for details. .It Fl l -Load keys for encrypted filesystems as they are being mounted. This is -equivalent to executing +Load keys for encrypted filesystems as they are being mounted. +This is equivalent to executing .Nm zfs Cm load-key -on each encryption root before mounting it. Note that if a filesystem has a -.Sy keylocation -of -.Sy prompt +on each encryption root before mounting it. +Note that if a filesystem has +.Sy keylocation Ns = Ns Sy prompt , this will cause the terminal to interactively block after asking for the key. .It Fl v Report mount progress. @@ -108,7 +110,7 @@ Attempt to force mounting of all filesystems, even those that couldn't normally .Nm zfs .Cm unmount .Op Fl fu -.Fl a | Ar filesystem Ns | Ns Ar mountpoint +.Fl a Ns | Ns Ar filesystem Ns | Ns Ar mountpoint .Xc Unmounts currently mounted ZFS file systems. .Bl -tag -width "-a" diff --git a/sys/contrib/openzfs/man/man8/zfs-program.8 b/sys/contrib/openzfs/man/man8/zfs-program.8 index de708e12cec..4a9718cdcfc 100644 --- a/sys/contrib/openzfs/man/man8/zfs-program.8 +++ b/sys/contrib/openzfs/man/man8/zfs-program.8 @@ -1,3 +1,4 @@ +.\" .\" This file and its contents are supplied under the terms of the .\" Common Development and Distribution License ("CDDL"), version 1.0. .\" You may only use this file in accordance with the terms of version @@ -7,17 +8,17 @@ .\" source. A copy of the CDDL is also available via the Internet at .\" http://www.illumos.org/license/CDDL. .\" -.\" .\" Copyright (c) 2016, 2019 by Delphix. All Rights Reserved. .\" Copyright (c) 2019, 2020 by Christian Schwarz. All Rights Reserved. .\" Copyright 2020 Joyent, Inc. .\" -.Dd January 26, 2021 +.Dd May 27, 2021 .Dt ZFS-PROGRAM 8 .Os +. .Sh NAME .Nm zfs-program -.Nd executes ZFS channel programs +.Nd execute ZFS channel programs .Sh SYNOPSIS .Nm zfs .Cm program @@ -26,7 +27,8 @@ .Op Fl m Ar memory-limit .Ar pool .Ar script -.\".Op Ar optional arguments to channel program +.Op Ar script arguments +. .Sh DESCRIPTION The ZFS channel program interface allows ZFS administrative operations to be run programmatically as a Lua script. @@ -37,22 +39,22 @@ Channel programs may only be run with root privileges. .Pp A modified version of the Lua 5.2 interpreter is used to run channel program scripts. -The Lua 5.2 manual can be found at: -.Bd -centered -offset indent +The Lua 5.2 manual can be found at .Lk http://www.lua.org/manual/5.2/ -.Ed .Pp The channel program given by .Ar script will be run on .Ar pool , and any attempts to access or modify other pools will cause an error. +. .Sh OPTIONS .Bl -tag -width "-t" .It Fl j -Display channel program output in JSON format. When this flag is specified and -standard output is empty - channel program encountered an error. The details of -such an error will be printed to standard error in plain text. +Display channel program output in JSON format. +When this flag is specified and standard output is empty - +channel program encountered an error. +The details of such an error will be printed to standard error in plain text. .It Fl n Executes a read-only channel program, which runs faster. The program cannot change on-disk state by calling functions from the @@ -78,15 +80,17 @@ All remaining argument strings will be passed directly to the Lua script as described in the .Sx LUA INTERFACE section below. +. .Sh LUA INTERFACE A channel program can be invoked either from the command line, or via a library call to .Fn lzc_channel_program . +. .Ss Arguments Arguments passed to the channel program are converted to a Lua table. If invoked from the command line, extra arguments to the Lua script will be accessible as an array stored in the argument table with the key 'argv': -.Bd -literal -offset indent +.Bd -literal -compact -offset indent args = ... argv = args["argv"] -- argv == {1="arg1", 2="arg2", ...} @@ -95,7 +99,7 @@ argv = args["argv"] If invoked from the libZFS interface, an arbitrary argument list can be passed to the channel program, which is accessible via the same "..." syntax in Lua: -.Bd -literal -offset indent +.Bd -literal -compact -offset indent args = ... -- args == {"foo"="bar", "baz"={...}, ...} .Ed @@ -108,37 +112,35 @@ in in a C array passed to a channel program will be stored in .Va arr[1] when accessed from Lua. +. .Ss Return Values Lua return statements take the form: -.Bd -literal -offset indent -return ret0, ret1, ret2, ... -.Ed +.Dl return ret0, ret1, ret2, ... .Pp Return statements returning multiple values are permitted internally in a channel program script, but attempting to return more than one value from the top level of the channel program is not permitted and will throw an error. However, tables containing multiple values can still be returned. If invoked from the command line, a return statement: -.Bd -literal -offset indent +.Bd -literal -compact -offset indent a = {foo="bar", baz=2} return a .Ed .Pp Will be output formatted as: -.Bd -literal -offset indent +.Bd -literal -compact -offset indent Channel program fully executed with return value: return: baz: 2 foo: 'bar' .Ed +. .Ss Fatal Errors If the channel program encounters a fatal error while running, a non-zero exit status will be returned. If more information about the error is available, a singleton list will be returned detailing the error: -.Bd -literal -offset indent -error: "error string, including Lua stack trace" -.Ed +.Dl error: \&"error string, including Lua stack trace" .Pp If a fatal error is returned, the channel program may have not executed at all, may have partially executed, or may have fully executed but failed to pass a @@ -162,6 +164,7 @@ return an error code and the channel program continues executing. See the .Sx ZFS API section below for function-specific details on error return codes. +. .Ss Lua to C Value Conversion When invoking a channel program via the libZFS interface, it is necessary to translate arguments and return values from Lua values to their C equivalents, @@ -171,37 +174,37 @@ There is a correspondence between nvlist values in C and Lua tables. A Lua table which is returned from the channel program will be recursively converted to an nvlist, with table values converted to their natural equivalents: -.Bd -literal -offset indent -string -> string -number -> int64 -boolean -> boolean_value -nil -> boolean (no value) -table -> nvlist -.Ed +.TS +cw3 l c l . + string -> string + number -> int64 + boolean -> boolean_value + nil -> boolean (no value) + table -> nvlist +.TE .Pp Likewise, table keys are replaced by string equivalents as follows: -.Bd -literal -offset indent -string -> no change -number -> signed decimal string ("%lld") -boolean -> "true" | "false" -.Ed +.TS +cw3 l c l . + string -> no change + number -> signed decimal string ("%lld") + boolean -> "true" | "false" +.TE .Pp Any collision of table key strings (for example, the string "true" and a true boolean value) will cause a fatal error. .Pp Lua numbers are represented internally as signed 64-bit integers. +. .Sh LUA STANDARD LIBRARY The following Lua built-in base library functions are available: -.Bd -literal -offset indent -assert rawlen -collectgarbage rawget -error rawset -getmetatable select -ipairs setmetatable -next tonumber -pairs tostring -rawequal type -.Ed +.TS +cw3 l l l l . + assert rawlen collectgarbage rawget + error rawset getmetatable select + ipairs setmetatable next tonumber + pairs tostring rawequal type +.TE .Pp All functions in the .Em coroutine , @@ -214,15 +217,13 @@ manual. .Pp The following functions base library functions have been disabled and are not available for use in channel programs: -.Bd -literal -offset indent -dofile -loadfile -load -pcall -print -xpcall -.Ed +.TS +cw3 l l l l l l . + dofile loadfile load pcall print xpcall +.TE +. .Sh ZFS API +. .Ss Function Arguments Each API function takes a fixed set of required positional arguments and optional keyword arguments. @@ -231,22 +232,17 @@ For example, the destroy function takes a single positional string argument argument. When using parentheses to specify the arguments to a Lua function, only positional arguments can be used: -.Bd -literal -offset indent -zfs.sync.destroy("rpool@snap") -.Ed +.Dl Sy zfs.sync.destroy Ns Pq \&"rpool@snap" .Pp To use keyword arguments, functions must be called with a single argument that is a Lua table containing entries mapping integers to positional arguments and strings to keyword arguments: -.Bd -literal -offset indent -zfs.sync.destroy({1="rpool@snap", defer=true}) -.Ed +.Dl Sy zfs.sync.destroy Ns Pq {1="rpool@snap", defer=true} .Pp The Lua language allows curly braces to be used in place of parenthesis as syntactic sugar for this calling convention: -.Bd -literal -offset indent -zfs.sync.snapshot{"rpool@snap", defer=true} -.Ed +.Dl Sy zfs.sync.snapshot Ns {"rpool@snap", defer=true} +. .Ss Function Return Values If an API function succeeds, it returns 0. If it fails, it returns an error code and the channel program continues @@ -261,13 +257,11 @@ Lua table, or Nil if no error details were returned. Different keys will exist in the error details table depending on the function and error case. Any such function may be called expecting a single return value: -.Bd -literal -offset indent -errno = zfs.sync.promote(dataset) -.Ed +.Dl errno = Sy zfs.sync.promote Ns Pq dataset .Pp Or, the error details can be retrieved: -.Bd -literal -offset indent -errno, details = zfs.sync.promote(dataset) +.Bd -literal -compact -offset indent +.No errno, details = Sy zfs.sync.promote Ns Pq dataset if (errno == EEXIST) then assert(details ~= Nil) list_of_conflicting_snapshots = details @@ -276,48 +270,46 @@ end .Pp The following global aliases for API function error return codes are defined for use in channel programs: -.Bd -literal -offset indent -EPERM ECHILD ENODEV ENOSPC -ENOENT EAGAIN ENOTDIR ESPIPE -ESRCH ENOMEM EISDIR EROFS -EINTR EACCES EINVAL EMLINK -EIO EFAULT ENFILE EPIPE -ENXIO ENOTBLK EMFILE EDOM -E2BIG EBUSY ENOTTY ERANGE -ENOEXEC EEXIST ETXTBSY EDQUOT -EBADF EXDEV EFBIG -.Ed +.TS +cw3 l l l l l l l . + EPERM ECHILD ENODEV ENOSPC ENOENT EAGAIN ENOTDIR + ESPIPE ESRCH ENOMEM EISDIR EROFS EINTR EACCES + EINVAL EMLINK EIO EFAULT ENFILE EPIPE ENXIO + ENOTBLK EMFILE EDOM E2BIG EBUSY ENOTTY ERANGE + ENOEXEC EEXIST ETXTBSY EDQUOT EBADF EXDEV EFBIG +.TE +. .Ss API Functions -For detailed descriptions of the exact behavior of any zfs administrative +For detailed descriptions of the exact behavior of any ZFS administrative operations, see the main .Xr zfs 8 manual page. .Bl -tag -width "xx" -.It Em zfs.debug(msg) +.It Fn zfs.debug msg Record a debug message in the zfs_dbgmsg log. A log of these messages can be printed via mdb's "::zfs_dbgmsg" command, or -can be monitored live by running: -.Bd -literal -offset indent - dtrace -n 'zfs-dbgmsg{trace(stringof(arg0))}' -.Ed +can be monitored live by running +.Dl dtrace -n 'zfs-dbgmsg{trace(stringof(arg0))}' .Pp -msg (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "property (string)" +.It Ar msg Pq string Debug message to be printed. -.Ed -.It Em zfs.exists(dataset) +.El +.It Fn zfs.exists dataset Returns true if the given dataset exists, or false if it doesn't. A fatal error will be thrown if the dataset is not in the target pool. That is, in a channel program running on rpool, -zfs.exists("rpool/nonexistent_fs") returns false, but -zfs.exists("somepool/fs_that_may_exist") will error. +.Sy zfs.exists Ns Pq \&"rpool/nonexistent_fs" +returns false, but +.Sy zfs.exists Ns Pq \&"somepool/fs_that_may_exist" +will error. .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "property (string)" +.It Ar dataset Pq string Dataset to check for existence. Must be in the target pool. -.Ed -.It Em zfs.get_prop(dataset, property) +.El +.It Fn zfs.get_prop dataset property Returns two values. First, a string, number or table containing the property value for the given dataset. @@ -326,22 +318,25 @@ dataset in which it was set or nil if it is readonly). Throws a Lua error if the dataset is invalid or the property doesn't exist. Note that Lua only supports int64 number types whereas ZFS number properties are uint64. -This means very large values (like guid) may wrap around and appear negative. +This means very large values (like GUIDs) may wrap around and appear negative. .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "property (string)" +.It Ar dataset Pq string Filesystem or snapshot path to retrieve properties from. -.Ed -.Pp -property (string) -.Bd -ragged -compact -offset "xxxx" +.It Ar property Pq string Name of property to retrieve. -All filesystem, snapshot and volume properties are supported except -for 'mounted' and 'iscsioptions.' -Also supports the 'written@snap' and 'written#bookmark' properties and -the '@id' properties, though the id must be in numeric -form. -.Ed +All filesystem, snapshot and volume properties are supported except for +.Sy mounted +and +.Sy iscsioptions . +Also supports the +.Sy written@ Ns Ar snap +and +.Sy written# Ns Ar bookmark +properties and the +.Ao Sy user Ns | Ns Sy group Ac Ns Ao Sy quota Ns | Ns Sy used Ac Ns Sy @ Ns Ar id +properties, though the id must be in numeric form. +.El .El .Bl -tag -width "xx" .It Sy zfs.sync submodule @@ -350,86 +345,73 @@ They are executed in "syncing context". .Pp The available sync submodule functions are as follows: .Bl -tag -width "xx" -.It Em zfs.sync.destroy(dataset, [defer=true|false]) +.It Sy zfs.sync.destroy Ns Pq Ar dataset , Op Ar defer Ns = Ns Sy true Ns | Ns Sy false Destroy the given dataset. Returns 0 on successful destroy, or a nonzero error code if the dataset could not be destroyed (for example, if the dataset has any active children or clones). .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "newbookmark (string)" +.It Ar dataset Pq string Filesystem or snapshot to be destroyed. -.Ed -.Pp -[optional] defer (boolean) -.Bd -ragged -compact -offset "xxxx" +.It Op Ar defer Pq boolean Valid only for destroying snapshots. If set to true, and the snapshot has holds or clones, allows the snapshot to be marked for deferred deletion rather than failing. -.Ed -.It Em zfs.sync.inherit(dataset, property) +.El +.It Fn zfs.sync.inherit dataset property Clears the specified property in the given dataset, causing it to be inherited from an ancestor, or restored to the default if no ancestor property is set. The -.Ql zfs inherit -S +.Nm zfs Cm inherit Fl S option has not been implemented. Returns 0 on success, or a nonzero error code if the property could not be cleared. .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "newbookmark (string)" +.It Ar dataset Pq string Filesystem or snapshot containing the property to clear. -.Ed -.Pp -property (string) -.Bd -ragged -compact -offset "xxxx" +.It Ar property Pq string The property to clear. Allowed properties are the same as those for the .Nm zfs Cm inherit command. -.Ed -.It Em zfs.sync.promote(dataset) +.El +.It Fn zfs.sync.promote dataset Promote the given clone to a filesystem. Returns 0 on successful promotion, or a nonzero error code otherwise. If EEXIST is returned, the second return value will be an array of the clone's snapshots whose names collide with snapshots of the parent filesystem. .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "newbookmark (string)" +.It Ar dataset Pq string Clone to be promoted. -.Ed -.It Em zfs.sync.rollback(filesystem) +.El +.It Fn zfs.sync.rollback filesystem Rollback to the previous snapshot for a dataset. Returns 0 on successful rollback, or a nonzero error code otherwise. Rollbacks can be performed on filesystems or zvols, but not on snapshots or mounted datasets. EBUSY is returned in the case where the filesystem is mounted. .Pp -filesystem (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "newbookmark (string)" +.It Ar filesystem Pq string Filesystem to rollback. -.Ed -.It Em zfs.sync.set_prop(dataset, property, value) +.El +.It Fn zfs.sync.set_prop dataset property value Sets the given property on a dataset. Currently only user properties are supported. Returns 0 if the property was set, or a nonzero error code otherwise. .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "newbookmark (string)" +.It Ar dataset Pq string The dataset where the property will be set. -.Ed -.Pp -property (string) -.Bd -ragged -compact -offset "xxxx" +.It Ar property Pq string The property to set. -Only user properties are supported. -.Ed -.Pp -value (string) -.Bd -ragged -compact -offset "xxxx" +.It Ar value Pq string The value of the property to be set. -.Ed -.It Em zfs.sync.snapshot(dataset) +.El +.It Fn zfs.sync.snapshot dataset Create a snapshot of a filesystem. Returns 0 if the snapshot was successfully created, and a nonzero error code otherwise. @@ -437,131 +419,142 @@ and a nonzero error code otherwise. Note: Taking a snapshot will fail on any pool older than legacy version 27. To enable taking snapshots from ZCP scripts, the pool must be upgraded. .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "newbookmark (string)" +.It Ar dataset Pq string Name of snapshot to create. -.Ed -.It Em zfs.sync.bookmark(source, newbookmark) +.El +.It Fn zfs.sync.bookmark source newbookmark Create a bookmark of an existing source snapshot or bookmark. Returns 0 if the new bookmark was successfully created, and a nonzero error code otherwise. .Pp Note: Bookmarking requires the corresponding pool feature to be enabled. .Pp -source (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "newbookmark (string)" +.It Ar source Pq string Full name of the existing snapshot or bookmark. -.Ed -.Pp -newbookmark (string) -.Bd -ragged -compact -offset "xxxx" +.It Ar newbookmark Pq string Full name of the new bookmark. .El +.El .It Sy zfs.check submodule -For each function in the zfs.sync submodule, there is a corresponding zfs.check +For each function in the +.Sy zfs.sync +submodule, there is a corresponding +.Sy zfs.check function which performs a "dry run" of the same operation. -Each takes the same arguments as its zfs.sync counterpart and returns 0 if the -operation would succeed, or a non-zero error code if it would fail, along with -any other error details. +Each takes the same arguments as its +.Sy zfs.sync +counterpart and returns 0 if the operation would succeed, +or a non-zero error code if it would fail, along with any other error details. That is, each has the same behavior as the corresponding sync function except for actually executing the requested change. For example, -.Em zfs.check.destroy("fs") +.Fn zfs.check.destroy \&"fs" returns 0 if -.Em zfs.sync.destroy("fs") +.Fn zfs.sync.destroy \&"fs" would successfully destroy the dataset. .Pp -The available zfs.check functions are: -.Bl -tag -width "xx" -.It Em zfs.check.destroy(dataset, [defer=true|false]) -.It Em zfs.check.promote(dataset) -.It Em zfs.check.rollback(filesystem) -.It Em zfs.check.set_property(dataset, property, value) -.It Em zfs.check.snapshot(dataset) +The available +.Sy zfs.check +functions are: +.Bl -tag -compact -width "xx" +.It Sy zfs.check.destroy Ns Pq Ar dataset , Op Ar defer Ns = Ns Sy true Ns | Ns Sy false +.It Fn zfs.check.promote dataset +.It Fn zfs.check.rollback filesystem +.It Fn zfs.check.set_property dataset property value +.It Fn zfs.check.snapshot dataset .El .It Sy zfs.list submodule The zfs.list submodule provides functions for iterating over datasets and properties. Rather than returning tables, these functions act as Lua iterators, and are generally used as follows: -.Bd -literal -offset indent -for child in zfs.list.children("rpool") do +.Bd -literal -compact -offset indent +.No for child in Fn zfs.list.children \&"rpool" No do ... end .Ed .Pp -The available zfs.list functions are: +The available +.Sy zfs.list +functions are: .Bl -tag -width "xx" -.It Em zfs.list.clones(snapshot) +.It Fn zfs.list.clones snapshot Iterate through all clones of the given snapshot. .Pp -snapshot (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "snapshot (string)" +.It Ar snapshot Pq string Must be a valid snapshot path in the current pool. -.Ed -.It Em zfs.list.snapshots(dataset) +.El +.It Fn zfs.list.snapshots dataset Iterate through all snapshots of the given dataset. -Each snapshot is returned as a string containing the full dataset name, e.g. -"pool/fs@snap". +Each snapshot is returned as a string containing the full dataset name, +e.g. "pool/fs@snap". .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "snapshot (string)" +.It Ar dataset Pq string Must be a valid filesystem or volume. -.Ed -.It Em zfs.list.children(dataset) +.El +.It Fn zfs.list.children dataset Iterate through all direct children of the given dataset. -Each child is returned as a string containing the full dataset name, e.g. -"pool/fs/child". +Each child is returned as a string containing the full dataset name, +e.g. "pool/fs/child". .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "snapshot (string)" +.It Ar dataset Pq string Must be a valid filesystem or volume. -.Ed -.It Em zfs.list.bookmarks(dataset) -Iterate through all bookmarks of the given dataset. Each bookmark is returned -as a string containing the full dataset name, e.g. "pool/fs#bookmark". +.El +.It Fn zfs.list.bookmarks dataset +Iterate through all bookmarks of the given dataset. +Each bookmark is returned as a string containing the full dataset name, +e.g. "pool/fs#bookmark". .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "snapshot (string)" +.It Ar dataset Pq string Must be a valid filesystem or volume. -.Ed -.It Em zfs.list.holds(snapshot) -Iterate through all user holds on the given snapshot. Each hold is returned +.El +.It Fn zfs.list.holds snapshot +Iterate through all user holds on the given snapshot. +Each hold is returned as a pair of the hold's tag and the timestamp (in seconds since the epoch) at which it was created. .Pp -snapshot (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "snapshot (string)" +.It Ar snapshot Pq string Must be a valid snapshot. -.Ed -.It Em zfs.list.properties(dataset) +.El +.It Fn zfs.list.properties dataset An alias for zfs.list.user_properties (see relevant entry). .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "snapshot (string)" +.It Ar dataset Pq string Must be a valid filesystem, snapshot, or volume. -.Ed -.It Em zfs.list.user_properties(dataset) -Iterate through all user properties for the given dataset. For each -step of the iteration, output the property name, its value, and its source. +.El +.It Fn zfs.list.user_properties dataset +Iterate through all user properties for the given dataset. +For each step of the iteration, output the property name, its value, +and its source. Throws a Lua error if the dataset is invalid. .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "snapshot (string)" +.It Ar dataset Pq string Must be a valid filesystem, snapshot, or volume. -.Ed -.It Em zfs.list.system_properties(dataset) +.El +.It Fn zfs.list.system_properties dataset Returns an array of strings, the names of the valid system (non-user defined) properties for the given dataset. Throws a Lua error if the dataset is invalid. .Pp -dataset (string) -.Bd -ragged -compact -offset "xxxx" +.Bl -tag -compact -width "snapshot (string)" +.It Ar dataset Pq string Must be a valid filesystem, snapshot or volume. -.Ed .El .El +.El +. .Sh EXAMPLES +. .Ss Example 1 The following channel program recursively destroys a filesystem and all its snapshots and children in a naive manner. @@ -578,6 +571,7 @@ function destroy_recursive(root) end destroy_recursive("pool/somefs") .Ed +. .Ss Example 2 A more verbose and robust version of the same channel program, which properly detects and reports errors, and also takes the dataset to destroy @@ -616,6 +610,7 @@ results["succeeded"] = succeeded results["failed"] = failed return results .Ed +. .Ss Example 3 The following function performs a forced promote operation by attempting to promote the given clone and destroying any conflicting snapshots. diff --git a/sys/contrib/openzfs/man/man8/zfs-project.8 b/sys/contrib/openzfs/man/man8/zfs-project.8 index 21c300f83df..f264a110fc0 100644 --- a/sys/contrib/openzfs/man/man8/zfs-project.8 +++ b/sys/contrib/openzfs/man/man8/zfs-project.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -30,68 +29,65 @@ .\" Copyright 2018 Nexenta Systems, Inc. .\" Copyright 2019 Joyent, Inc. .\" -.Dd June 30, 2019 +.Dd May 27, 2021 .Dt ZFS-PROJECT 8 .Os +. .Sh NAME .Nm zfs-project -.Nd List, set, or clear project ID and/or inherit flag on the file(s) or directories. +.Nd manage projects in ZFS filesystem .Sh SYNOPSIS .Nm zfs .Cm project .Oo Fl d Ns | Ns Fl r Ns Oc -.Ar file Ns | Ns Ar directory Ns ... +.Ar file Ns | Ns Ar directory Ns … .Nm zfs .Cm project .Fl C .Oo Fl kr Ns Oc -.Ar file Ns | Ns Ar directory Ns ... +.Ar file Ns | Ns Ar directory Ns … .Nm zfs .Cm project .Fl c .Oo Fl 0 Ns Oc .Oo Fl d Ns | Ns Fl r Ns Oc .Op Fl p Ar id -.Ar file Ns | Ns Ar directory Ns ... +.Ar file Ns | Ns Ar directory Ns … .Nm zfs .Cm project .Op Fl p Ar id .Oo Fl rs Ns Oc -.Ar file Ns | Ns Ar directory Ns ... +.Ar file Ns | Ns Ar directory Ns … +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo .Nm zfs .Cm project .Oo Fl d Ns | Ns Fl r Ns Oc -.Ar file Ns | Ns Ar directory Ns ... +.Ar file Ns | Ns Ar directory Ns … .Xc -List project identifier (ID) and inherit flag of file(s) or directories. +List project identifier (ID) and inherit flag of files and directories. .Bl -tag -width "-d" .It Fl d -Show the directory project ID and inherit flag, not its children. It will -overwrite the former specified -.Fl r -option. +Show the directory project ID and inherit flag, not its children. .It Fl r -Show on subdirectories recursively. It will overwrite the former specified -.Fl d -option. +List subdirectories recursively. .El .It Xo .Nm zfs .Cm project .Fl C .Oo Fl kr Ns Oc -.Ar file Ns | Ns Ar directory Ns ... +.Ar file Ns | Ns Ar directory Ns … .Xc -Clear project inherit flag and/or ID on the file(s) or directories. +Clear project inherit flag and/or ID on the files and directories. .Bl -tag -width "-k" .It Fl k -Keep the project ID unchanged. If not specified, the project ID will be reset -as zero. +Keep the project ID unchanged. +If not specified, the project ID will be reset to zero. .It Fl r -Clear on subdirectories recursively. +Clear subdirectories' flags recursively. .El .It Xo .Nm zfs @@ -100,54 +96,46 @@ Clear on subdirectories recursively. .Oo Fl 0 Ns Oc .Oo Fl d Ns | Ns Fl r Ns Oc .Op Fl p Ar id -.Ar file Ns | Ns Ar directory Ns ... +.Ar file Ns | Ns Ar directory Ns … .Xc -Check project ID and inherit flag on the file(s) or directories, report the -entries without project inherit flag or with different project IDs from the -specified (via -.Fl p -option) value or the target directory's project ID. -.Bl -tag -width "-0" +Check project ID and inherit flag on the files and directories: +report entries without the project inherit flag, or with project IDs different from the +target directory's project ID or the one specified with +.Fl p . +.Bl -tag -width "-p id" .It Fl 0 -Print file name with a trailing NUL instead of newline (by default), like -"find -print0". +Delimit filenames with a NUL byte instead of newline. .It Fl d -Check the directory project ID and inherit flag, not its children. It will -overwrite the former specified -.Fl r -option. -.It Fl p -Specify the referenced ID for comparing with the target file(s) or directories' -project IDs. If not specified, the target (top) directory's project ID will be -used as the referenced one. +Check the directory project ID and inherit flag, not its children. +.It Fl p Ar id +Compare to +.Ar id +instead of the target files and directories' project IDs. .It Fl r -Check on subdirectories recursively. It will overwrite the former specified -.Fl d -option. +Check subdirectories recursively. .El .It Xo .Nm zfs .Cm project -.Op Fl p Ar id +.Fl p Ar id .Oo Fl rs Ns Oc -.Ar file Ns | Ns Ar directory Ns ... +.Ar file Ns | Ns Ar directory Ns … .Xc -Set project ID and/or inherit flag on the file(s) or directories. -.Bl -tag -width "-p" -.It Fl p -Set the file(s)' or directories' project ID with the given value. +Set project ID and/or inherit flag on the files and directories. +.Bl -tag -width "-p id" +.It Fl p Ar id +Set the project ID to the given value. .It Fl r Set on subdirectories recursively. .It Fl s -Set project inherit flag on the given file(s) or directories. It is usually used -for setup tree quota on the directory target with -.Fl r -option specified together. When setup tree quota, by default the directory's -project ID will be set to all its descendants unless you specify the project -ID via -.Fl p -option explicitly. +Set project inherit flag on the given files and directories. +This is usually used for setting up tree quotas with +.Fl r . +In that case, the directory's project ID +will be set for all its descendants, unless specified explicitly with +.Fl p . .El .El +. .Sh SEE ALSO .Xr zfs-projectspace 8 diff --git a/sys/contrib/openzfs/man/man8/zfs-promote.8 b/sys/contrib/openzfs/man/man8/zfs-promote.8 index 64c124c11b6..ba8cd5f6da8 100644 --- a/sys/contrib/openzfs/man/man8/zfs-promote.8 +++ b/sys/contrib/openzfs/man/man8/zfs-promote.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -33,37 +32,33 @@ .Dd June 30, 2019 .Dt ZFS-PROMOTE 8 .Os +. .Sh NAME .Nm zfs-promote -.Nd Promotes a clone file system to no longer be dependent on its origin snapshot. +.Nd promote clone dataset to no longer depend on origin snapshot .Sh SYNOPSIS .Nm zfs .Cm promote -.Ar clone-filesystem +.Ar clone +. .Sh DESCRIPTION -.Bl -tag -width "" -.It Xo -.Nm zfs -.Cm promote -.Ar clone-filesystem -.Xc The -.Cm promote -command makes it possible to destroy the file system that the clone was created -from. +.Nm zfs Cm promote +command makes it possible to destroy the dataset that the clone was created from. The clone parent-child dependency relationship is reversed, so that the origin -file system becomes a clone of the specified file system. +dataset becomes a clone of the specified dataset. .Pp The snapshot that was cloned, and any snapshots previous to this snapshot, are now owned by the promoted clone. -The space they use moves from the origin file system to the promoted clone, so +The space they use moves from the origin dataset to the promoted clone, so enough space must be available to accommodate these snapshots. No new space is consumed by this operation, but the space accounting is adjusted. The promoted clone must not have any conflicting snapshot names of its own. The -.Xr zfs-rename 8 +.Nm zfs Cm rename subcommand can be used to rename any conflicting snapshots. -.El +. .Sh SEE ALSO -.Xr zfs-clone 8 +.Xr zfs-clone 8 , +.Xr zfs-rename 8 diff --git a/sys/contrib/openzfs/man/man8/zfs-receive.8 b/sys/contrib/openzfs/man/man8/zfs-receive.8 index 36ed2050683..ceb6e64ce57 100644 --- a/sys/contrib/openzfs/man/man8/zfs-receive.8 +++ b/sys/contrib/openzfs/man/man8/zfs-receive.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -33,9 +32,10 @@ .Dd February 16, 2020 .Dt ZFS-RECEIVE 8 .Os +. .Sh NAME .Nm zfs-receive -.Nd Creates a snapshot whose contents are as specified in the stream provided on standard input. +.Nd create snapshot from backup stream .Sh SYNOPSIS .Nm zfs .Cm receive @@ -56,6 +56,7 @@ .Cm receive .Fl A .Ar filesystem Ns | Ns Ar volume +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo @@ -85,7 +86,7 @@ Streams are created using the subcommand, which by default creates a full stream. .Nm zfs Cm recv can be used as an alias for -.Nm zfs Cm receive. +.Nm zfs Cm receive . .Pp If an incremental stream is received, then the destination file system must already exist, and its most recent snapshot must match the incremental stream's @@ -116,15 +117,17 @@ If or .Fl x Em property is specified, it applies to the effective value of the property throughout -the entire subtree of replicated datasets. Effective property values will be -set ( -.Fl o -) or inherited ( -.Fl x -) on the topmost in the replicated subtree. In descendant datasets, if the +the entire subtree of replicated datasets. +Effective property values will be set +.Pq Fl o +or inherited +.Pq Fl x +on the topmost in the replicated subtree. +In descendant datasets, if the property is set by the send stream, it will be overridden by forcing the -property to be inherited from the top‐most file system. Received properties -are retained in spite of being overridden and may be restored with +property to be inherited from the top‐most file system. +Received properties are retained in spite of being overridden +and may be restored with .Nm zfs Cm inherit Fl S . Specifying .Fl o Sy origin Ns = Ns Em snapshot @@ -134,41 +137,51 @@ is a read-only property and cannot be set, it's allowed to receive the send stream as a clone of the given snapshot. .Pp Raw encrypted send streams (created with -.Nm zfs Cm send Fl w -) may only be received as is, and cannot be re-encrypted, decrypted, or -recompressed by the receive process. Unencrypted streams can be received as +.Nm zfs Cm send Fl w ) +may only be received as is, and cannot be re-encrypted, decrypted, or +recompressed by the receive process. +Unencrypted streams can be received as encrypted datasets, either through inheritance or by specifying encryption parameters with the .Fl o -options. Note that the +options. +Note that the .Sy keylocation property cannot be overridden to .Sy prompt -during a receive. This is because the receive process itself is already using -stdin for the send stream. Instead, the property can be overridden after the -receive completes. +during a receive. +This is because the receive process itself is already using +the standard input for the send stream. +Instead, the property can be overridden after the receive completes. .Pp The added security provided by raw sends adds some restrictions to the send -and receive process. ZFS will not allow a mix of raw receives and non-raw -receives. Specifically, any raw incremental receives that are attempted after -a non-raw receive will fail. Non-raw receives do not have this restriction and, -therefore, are always possible. Because of this, it is best practice to always +and receive process. +ZFS will not allow a mix of raw receives and non-raw receives. +Specifically, any raw incremental receives that are attempted after +a non-raw receive will fail. +Non-raw receives do not have this restriction and, +therefore, are always possible. +Because of this, it is best practice to always use either raw sends for their security benefits or non-raw sends for their flexibility when working with encrypted datasets, but not a combination. .Pp The reason for this restriction stems from the inherent restrictions of the -AEAD ciphers that ZFS uses to encrypt data. When using ZFS native encryption, +AEAD ciphers that ZFS uses to encrypt data. +When using ZFS native encryption, each block of data is encrypted against a randomly generated number known as the "initialization vector" (IV), which is stored in the filesystem metadata. This number is required by the encryption algorithms whenever the data is to -be decrypted. Together, all of the IVs provided for all of the blocks in a -given snapshot are collectively called an "IV set". When ZFS performs a raw -send, the IV set is transferred from the source to the destination in the send -stream. When ZFS performs a non-raw send, the data is decrypted by the source +be decrypted. +Together, all of the IVs provided for all of the blocks in a +given snapshot are collectively called an "IV set". +When ZFS performs a raw send, the IV set is transferred from the source +to the destination in the send stream. +When ZFS performs a non-raw send, the data is decrypted by the source system and re-encrypted by the destination system, creating a snapshot with -effectively the same data, but a different IV set. In order for decryption to -work after a raw send, ZFS must ensure that the IV set used on both the source -and destination side match. When an incremental raw receive is performed on +effectively the same data, but a different IV set. +In order for decryption to work after a raw send, ZFS must ensure that +the IV set used on both the source and destination side match. +When an incremental raw receive is performed on top of an existing snapshot, ZFS will check to confirm that the "from" snapshot on both the source and destination were using the same IV set, ensuring the new IV set is consistent. @@ -234,7 +247,8 @@ Discard all but the last element of the sent snapshot's file system name, using that element to determine the name of the target file system for the new snapshot as described in the paragraph above. .It Fl h -Skip the receive of holds. There is no effect if holds are not sent. +Skip the receive of holds. +There is no effect if holds are not sent. .It Fl M Force an unmount of the file system while receiving a snapshot. This option is not supported on Linux. @@ -254,7 +268,8 @@ performed. .It Fl o Em property Ns = Ns Ar value Sets the specified property as if the command .Nm zfs Cm set Em property Ns = Ns Ar value -was invoked immediately before the receive. When receiving a stream from +was invoked immediately before the receive. +When receiving a stream from .Nm zfs Cm send Fl R , causes the property to be inherited by all descendant datasets, as through .Nm zfs Cm inherit Em property @@ -267,11 +282,13 @@ then overriding the .Sy compression property will have no affect on received data but the .Sy compression -property will be set. To have the data recompressed on receive remove the +property will be set. +To have the data recompressed on receive remove the .Fl c flag from the send stream. .Pp -Any editable property can be set at receive time. Set-once properties bound +Any editable property can be set at receive time. +Set-once properties bound to the received data, such as .Sy normalization and @@ -286,8 +303,8 @@ cannot be set at receive time. .Pp The .Fl o -option may be specified multiple times, for different properties. An error -results if the same property is specified in multiple +option may be specified multiple times, for different properties. +An error results if the same property is specified in multiple .Fl o or .Fl x @@ -295,30 +312,27 @@ options. .Pp The .Fl o -option may also be used to override encryption properties upon initial -receive. This allows unencrypted streams to be received as encrypted datasets. +option may also be used to override encryption properties upon initial receive. +This allows unencrypted streams to be received as encrypted datasets. To cause the received dataset (or root dataset of a recursive stream) to be received as an encryption root, specify encryption properties in the same manner as is required for -.Nm zfs -.Cm create . +.Nm zfs Cm create . For instance: -.Bd -literal -# zfs send tank/test@snap1 | zfs recv -o encryption=on -o keyformat=passphrase -o keylocation=file:///path/to/keyfile -.Ed +.Dl # Nm zfs Cm send Pa tank/test@snap1 | Nm zfs Cm recv Fl o Sy encryption Ns = Ns Sy on Fl o keyformat=passphrase Fl o Sy keylocation Ns = Ns Pa file:///path/to/keyfile .Pp Note that -.Op Fl o Ar keylocation Ns = Ns Ar prompt -may not be specified here, since stdin is already being utilized for the send -stream. Once the receive has completed, you can use -.Nm zfs -.Cm set -to change this setting after the fact. Similarly, you can receive a dataset as -an encrypted child by specifying +.Fl o Sy keylocation Ns = Ns Sy prompt +may not be specified here, since the standard input +is already being utilized for the send stream. +Once the receive has completed, you can use +.Nm zfs Cm set +to change this setting after the fact. +Similarly, you can receive a dataset as an encrypted child by specifying .Op Fl x Ar encryption -to force the property to be inherited. Overriding encryption properties (except -for -.Sy keylocation Ns ) +to force the property to be inherited. +Overriding encryption properties (except for +.Sy keylocation ) is not possible with raw send streams. .It Fl s If the receive is interrupted, save the partially received state, rather @@ -380,6 +394,7 @@ Abort an interrupted .Nm zfs Cm receive Fl s , deleting its saved partially received state. .El +. .Sh SEE ALSO -.Xr zfs-send 8 +.Xr zfs-send 8 , .Xr zstream 8 diff --git a/sys/contrib/openzfs/man/man8/zfs-rename.8 b/sys/contrib/openzfs/man/man8/zfs-rename.8 index f57bcd8441f..6caee50657e 100644 --- a/sys/contrib/openzfs/man/man8/zfs-rename.8 +++ b/sys/contrib/openzfs/man/man8/zfs-rename.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -33,9 +32,10 @@ .Dd September 1, 2020 .Dt ZFS-RENAME 8 .Os +. .Sh NAME .Nm zfs-rename -.Nd Renames the given dataset (filesystem or snapshot). +.Nd rename ZFS dataset .Sh SYNOPSIS .Nm zfs .Cm rename @@ -57,6 +57,7 @@ .Cm rename .Fl r .Ar snapshot Ar snapshot +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo diff --git a/sys/contrib/openzfs/man/man8/zfs-rollback.8 b/sys/contrib/openzfs/man/man8/zfs-rollback.8 index 8a7cb6621fa..08e914b4765 100644 --- a/sys/contrib/openzfs/man/man8/zfs-rollback.8 +++ b/sys/contrib/openzfs/man/man8/zfs-rollback.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -30,25 +29,20 @@ .\" Copyright 2018 Nexenta Systems, Inc. .\" Copyright 2019 Joyent, Inc. .\" -.Dd June 30, 2019 +.Dd May 27, 2021 .Dt ZFS-ROLLBACK 8 .Os +. .Sh NAME .Nm zfs-rollback -.Nd Roll back the given dataset to a previous snapshot. +.Nd roll ZFS dataset back to snapshot .Sh SYNOPSIS .Nm zfs .Cm rollback .Op Fl Rfr .Ar snapshot +. .Sh DESCRIPTION -.Bl -tag -width "" -.It Xo -.Nm zfs -.Cm rollback -.Op Fl Rfr -.Ar snapshot -.Xc When a dataset is rolled back, all data that has changed since the snapshot is discarded, and the dataset reverts to the state at the time of the snapshot. By default, the command refuses to roll back to a snapshot other than the most @@ -63,7 +57,7 @@ The options do not recursively destroy the child snapshots of a recursive snapshot. Only direct snapshots of the specified filesystem are destroyed by either of these options. -To completely roll back a recursive snapshot, you must rollback the individual +To completely roll back a recursive snapshot, you must roll back the individual child snapshots. .Bl -tag -width "-R" .It Fl R @@ -76,6 +70,6 @@ option to force an unmount of any clone file systems that are to be destroyed. .It Fl r Destroy any snapshots and bookmarks more recent than the one specified. .El -.El +. .Sh SEE ALSO .Xr zfs-snapshot 8 diff --git a/sys/contrib/openzfs/man/man8/zfs-send.8 b/sys/contrib/openzfs/man/man8/zfs-send.8 index 4156db4f6b4..47b6c47ad03 100644 --- a/sys/contrib/openzfs/man/man8/zfs-send.8 +++ b/sys/contrib/openzfs/man/man8/zfs-send.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -30,28 +29,28 @@ .\" Copyright 2018 Nexenta Systems, Inc. .\" Copyright 2019 Joyent, Inc. .\" -.Dd June 30, 2019 +.Dd April 15, 2021 .Dt ZFS-SEND 8 .Os +. .Sh NAME .Nm zfs-send -.Nd Generate a send stream, which may be of a filesystem, and may be incremental from a bookmark. +.Nd generate backup stream of ZFS dataset .Sh SYNOPSIS .Nm zfs .Cm send -.Op Fl DLPRbcehnpvw +.Op Fl DLPRbcehnpsvw .Op Oo Fl I Ns | Ns Fl i Oc Ar snapshot .Ar snapshot .Nm zfs .Cm send -.Op Fl DLPRcenpvw +.Op Fl DLPRcenpsvw .Op Fl i Ar snapshot Ns | Ns Ar bookmark .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot .Nm zfs .Cm send .Fl -redact Ar redaction_bookmark .Op Fl DLPcenpv -.br .Op Fl i Ar snapshot Ns | Ns Ar bookmark .Ar snapshot .Nm zfs @@ -66,7 +65,8 @@ .Nm zfs .Cm redact .Ar snapshot redaction_bookmark -.Ar redaction_snapshot Ns ... +.Ar redaction_snapshot Ns … +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo @@ -85,7 +85,7 @@ The output can be redirected to a file or to a different system .Pc . By default, a full stream is generated. .Bl -tag -width "-D" -.It Fl D, -dedup +.It Fl D , -dedup Deduplicated send is no longer supported. This flag is accepted for backwards compatibility, but a regular, non-deduplicated stream will be generated. @@ -99,7 +99,7 @@ is similar to The incremental source may be specified as with the .Fl i option. -.It Fl L, -large-block +.It Fl L , -large-block Generate a stream which may contain blocks larger than 128KB. This flag has no effect if the .Sy large_blocks @@ -114,9 +114,9 @@ See for details on ZFS feature flags and the .Sy large_blocks feature. -.It Fl P, -parsable +.It Fl P , -parsable Print machine-parsable verbose information about the stream package generated. -.It Fl R, -replicate +.It Fl R , -replicate Generate a replication stream package, which will replicate the specified file system, and all descendent file systems, up to the named snapshot. When received, all properties, snapshots, descendent file systems, and clones @@ -134,12 +134,13 @@ set when the stream is received. If the .Fl F flag is specified when this stream is received, snapshots and file systems that -do not exist on the sending side are destroyed. If the +do not exist on the sending side are destroyed. +If the .Fl R flag is used to send encrypted datasets, then .Fl w must also be specified. -.It Fl e, -embed +.It Fl e , -embed Generate a more compact stream by using .Sy WRITE_EMBEDDED records for blocks which are stored more compactly on disk by the @@ -154,7 +155,8 @@ feature enabled. If the .Sy lz4_compress feature is active on the sending system, then the receiving system must have -that feature enabled as well. Datasets that are sent with this flag may not be +that feature enabled as well. +Datasets that are sent with this flag may not be received as an encrypted dataset, since encrypted datasets cannot use the .Sy embedded_data feature. @@ -163,15 +165,15 @@ See for details on ZFS feature flags and the .Sy embedded_data feature. -.It Fl b, -backup +.It Fl b , -backup Sends only received property values whether or not they are overridden by local -settings, but only if the dataset has ever been received. Use this option when -you want +settings, but only if the dataset has ever been received. +Use this option when you want .Nm zfs Cm receive to restore received properties backed up on the sent dataset and to avoid sending local settings that may have nothing to do with the source dataset, but only with how the data is backed up. -.It Fl c, -compressed +.It Fl c , -compressed Generate a more compact stream by using compressed WRITE records for blocks which are compressed on disk and in memory .Po see the @@ -189,34 +191,36 @@ feature is enabled on the sending system but the option is not supplied in conjunction with .Fl c , then the data will be decompressed before sending so it can be split into -smaller block sizes. Streams sent with +smaller block sizes. +Streams sent with .Fl c will not have their data recompressed on the receiver side using -.Fl o compress=value. -The data will stay compressed as it was from the sender. The new compression -property will be set for future data. -.It Fl w, -raw -For encrypted datasets, send data exactly as it exists on disk. This allows -backups to be taken even if encryption keys are not currently loaded. The -backup may then be received on an untrusted machine since that machine will +.Fl o Sy compress Ns = Ar value . +The data will stay compressed as it was from the sender. +The new compression property will be set for future data. +.It Fl w , -raw +For encrypted datasets, send data exactly as it exists on disk. +This allows backups to be taken even if encryption keys are not currently loaded. +The backup may then be received on an untrusted machine since that machine will not have the encryption keys to read the protected data or alter it without -being detected. Upon being received, the dataset will have the same encryption +being detected. +Upon being received, the dataset will have the same encryption keys as it did on the send side, although the .Sy keylocation property will be defaulted to .Sy prompt -if not otherwise provided. For unencrypted datasets, this flag will be -equivalent to +if not otherwise provided. +For unencrypted datasets, this flag will be equivalent to .Fl Lec . Note that if you do not use this flag for sending encrypted datasets, data will be sent unencrypted and may be re-encrypted with a different encryption key on the receiving system, which will disable the ability to do a raw send to that system for incrementals. -.It Fl h, -holds +.It Fl h , -holds Generate a stream package that includes any snapshot holds (created with the -.Sy zfs hold +.Nm zfs Cm hold command), and indicating to -.Sy zfs receive +.Nm zfs Cm receive that the holds be applied to the dataset on the receiving system. .It Fl i Ar snapshot Generate an incremental stream from the first @@ -240,7 +244,7 @@ be fully specified not just .Em @origin .Pc . -.It Fl n, -dryrun +.It Fl n , -dryrun Do a dry-run .Pq Qq No-op send. @@ -254,16 +258,24 @@ In this case, the verbose output will be written to standard output .Po contrast with a non-dry-run, where the stream is written to standard output and the verbose output goes to standard error .Pc . -.It Fl p, -props +.It Fl p , -props Include the dataset's properties in the stream. This flag is implicit when .Fl R is specified. -The receiving system must also support this feature. Sends of encrypted datasets -must use +The receiving system must also support this feature. +Sends of encrypted datasets must use .Fl w when using this flag. -.It Fl v, -verbose +.It Fl s , -skip-missing +Allows sending a replication stream even when there are snapshots missing in the +hierarchy. +When a snapshot is missing, instead of throwing an error and aborting the send, +a warning is printed to the standard error stream and the dataset to which it belongs +and its descendents are skipped. +This flag can only be used in conjunction with +.Fl R . +.It Fl v , -verbose Print verbose information about the stream package generated. This information includes a per-second report of how much data has been sent. .Pp @@ -285,7 +297,7 @@ When the stream generated from a filesystem or volume is received, the default snapshot name will be .Qq --head-- . .Bl -tag -width "-L" -.It Fl L, -large-block +.It Fl L , -large-block Generate a stream which may contain blocks larger than 128KB. This flag has no effect if the .Sy large_blocks @@ -300,9 +312,9 @@ See for details on ZFS feature flags and the .Sy large_blocks feature. -.It Fl P, -parsable +.It Fl P , -parsable Print machine-parsable verbose information about the stream package generated. -.It Fl c, -compressed +.It Fl c , -compressed Generate a more compact stream by using compressed WRITE records for blocks which are compressed on disk and in memory .Po see the @@ -321,24 +333,25 @@ option is not supplied in conjunction with .Fl c , then the data will be decompressed before sending so it can be split into smaller block sizes. -.It Fl w, -raw -For encrypted datasets, send data exactly as it exists on disk. This allows -backups to be taken even if encryption keys are not currently loaded. The -backup may then be received on an untrusted machine since that machine will +.It Fl w , -raw +For encrypted datasets, send data exactly as it exists on disk. +This allows backups to be taken even if encryption keys are not currently loaded. +The backup may then be received on an untrusted machine since that machine will not have the encryption keys to read the protected data or alter it without -being detected. Upon being received, the dataset will have the same encryption +being detected. +Upon being received, the dataset will have the same encryption keys as it did on the send side, although the .Sy keylocation property will be defaulted to .Sy prompt -if not otherwise provided. For unencrypted datasets, this flag will be -equivalent to +if not otherwise provided. +For unencrypted datasets, this flag will be equivalent to .Fl Lec . Note that if you do not use this flag for sending encrypted datasets, data will be sent unencrypted and may be re-encrypted with a different encryption key on the receiving system, which will disable the ability to do a raw send to that system for incrementals. -.It Fl e, -embed +.It Fl e , -embed Generate a more compact stream by using .Sy WRITE_EMBEDDED records for blocks which are stored more compactly on disk by the @@ -353,8 +366,9 @@ feature enabled. If the .Sy lz4_compress feature is active on the sending system, then the receiving system must have -that feature enabled as well. Datasets that are sent with this flag may not be -received as an encrypted dataset, since encrypted datasets cannot use the +that feature enabled as well. +Datasets that are sent with this flag may not be received as an encrypted dataset, +since encrypted datasets cannot use the .Sy embedded_data feature. See @@ -377,7 +391,7 @@ character and following If the incremental target is a clone, the incremental source can be the origin snapshot, or an earlier snapshot in the origin's filesystem, or the origin's origin, etc. -.It Fl n, -dryrun +.It Fl n , -dryrun Do a dry-run .Pq Qq No-op send. @@ -391,7 +405,7 @@ In this case, the verbose output will be written to standard output .Po contrast with a non-dry-run, where the stream is written to standard output and the verbose output goes to standard error .Pc . -.It Fl v, -verbose +.It Fl v , -verbose Print verbose information about the stream package generated. This information includes a per-second report of how much data has been sent. .El @@ -400,7 +414,6 @@ This information includes a per-second report of how much data has been sent. .Cm send .Fl -redact Ar redaction_bookmark .Op Fl DLPcenpv -.br .Op Fl i Ar snapshot Ns | Ns Ar bookmark .Ar snapshot .Xc @@ -409,15 +422,15 @@ This send stream contains all blocks from the snapshot being sent that aren't included in the redaction list contained in the bookmark specified by the .Fl -redact (or -.Fl -d -) flag. +.Fl d ) +flag. The resulting send stream is said to be redacted with respect to the snapshots the bookmark specified by the .Fl -redact No flag was created with. The bookmark must have been created by running -.Sy zfs redact +.Nm zfs Cm redact on the snapshot being sent. -.sp +.Pp This feature can be used to allow clones of a filesystem to be made available on a remote system, in the case where their parent need not (or needs to not) be usable. @@ -433,21 +446,23 @@ parent, that block will not be sent; but if one or more snapshots have not modified a block in the parent, they will still reference the parent's block, so that block will be sent. Note that only user data will be redacted. -.sp +.Pp When the redacted send stream is received, we will generate a redacted snapshot. Due to the nature of redaction, a redacted dataset can only be used in the following ways: -.sp -1. To receive, as a clone, an incremental send from the original snapshot to one +.Bl -enum -width "a." +.It +To receive, as a clone, an incremental send from the original snapshot to one of the snapshots it was redacted with respect to. In this case, the stream will produce a valid dataset when received because all blocks that were redacted in the parent are guaranteed to be present in the child's send stream. This use case will produce a normal snapshot, which can be used just like other snapshots. -.sp -2. To receive an incremental send from the original snapshot to something +. +.It +To receive an incremental send from the original snapshot to something redacted with respect to a subset of the set of snapshots the initial snapshot was redacted with respect to. In this case, each block that was redacted in the original is still redacted @@ -455,8 +470,8 @@ In this case, each block that was redacted in the original is still redacted (because the snapshots define what is permitted, and everything else is redacted)). This use case will produce a new redacted snapshot. -.sp -3. To receive an incremental send from a redaction bookmark of the original +.It +To receive an incremental send from a redaction bookmark of the original snapshot that was created when redacting with respect to a subset of the set of snapshots the initial snapshot was created with respect to anything else. @@ -465,27 +480,30 @@ necessary to fill in any redacted data, should it be needed, because the sending system is aware of what blocks were originally redacted. This will either produce a normal snapshot or a redacted one, depending on whether the new send stream is redacted. -.sp -4. To receive an incremental send from a redacted version of the initial +.It +To receive an incremental send from a redacted version of the initial snapshot that is redacted with respect to a subject of the set of snapshots the initial snapshot was created with respect to. A send stream from a compatible redacted dataset will contain all of the blocks necessary to fill in any redacted data. This will either produce a normal snapshot or a redacted one, depending on whether the new send stream is redacted. -.sp -5. To receive a full send as a clone of the redacted snapshot. +.It +To receive a full send as a clone of the redacted snapshot. Since the stream is a full send, it definitionally contains all the data needed to create a new dataset. This use case will either produce a normal snapshot or a redacted one, depending on whether the full send stream was redacted. -.sp -These restrictions are detected and enforced by \fBzfs receive\fR; a -redacted send stream will contain the list of snapshots that the stream is +.El +.Pp +These restrictions are detected and enforced by +.Nm zfs Cm receive ; +a redacted send stream will contain the list of snapshots that the stream is redacted with respect to. These are stored with the redacted snapshot, and are used to detect and -correctly handle the cases above. Note that for technical reasons, raw sends -and redacted sends cannot be combined at this time. +correctly handle the cases above. +Note that for technical reasons, +raw sends and redacted sends cannot be combined at this time. .It Xo .Nm zfs .Cm send @@ -499,7 +517,7 @@ The is the value of this property on the filesystem or volume that was being received into. See the documentation for -.Sy zfs receive -s +.Nm zfs Cm receive Fl s for more details. .It Xo .Nm zfs @@ -511,18 +529,19 @@ for more details. .Xc Generate a send stream from a dataset that has been partially received. .Bl -tag -width "-L" -.It Fl S, -saved +.It Fl S , -saved This flag requires that the specified filesystem previously received a resumable -send that did not finish and was interrupted. In such scenarios this flag -enables the user to send this partially received state. Using this flag will -always use the last fully received snapshot as the incremental source if it -exists. +send that did not finish and was interrupted. +In such scenarios this flag +enables the user to send this partially received state. +Using this flag will always use the last fully received snapshot +as the incremental source if it exists. .El .It Xo .Nm zfs .Cm redact .Ar snapshot redaction_bookmark -.Ar redaction_snapshot Ns ... +.Ar redaction_snapshot Ns … .Xc Generate a new redaction bookmark. In addition to the typical bookmark information, a redaction bookmark contains @@ -532,81 +551,96 @@ of the redaction snapshots. These blocks are found by iterating over the metadata in each redaction snapshot to determine what has been changed since the target snapshot. Redaction is designed to support redacted zfs sends; see the entry for -.Sy zfs send +.Nm zfs Cm send for more information on the purpose of this operation. If a redact operation fails partway through (due to an error or a system failure), the redaction can be resumed by rerunning the same command. .El .Ss Redaction ZFS has support for a limited version of data subsetting, in the form of -redaction. Using the -.Sy zfs redact +redaction. +Using the +.Nm zfs Cm redact command, a .Sy redaction bookmark -can be created that stores a list of blocks containing sensitive information. When -provided to -.Sy zfs -.Sy send , +can be created that stores a list of blocks containing sensitive information. +When provided to +.Nm zfs Cm send , this causes a .Sy redacted send -to occur. Redacted sends omit the blocks containing sensitive information, -replacing them with REDACT records. When these send streams are received, a +to occur. +Redacted sends omit the blocks containing sensitive information, +replacing them with REDACT records. +When these send streams are received, a .Sy redacted dataset -is created. A redacted dataset cannot be mounted by default, since it is -incomplete. It can be used to receive other send streams. In this way datasets -can be used for data backup and replication, with all the benefits that zfs send -and receive have to offer, while protecting sensitive information from being +is created. +A redacted dataset cannot be mounted by default, since it is incomplete. +It can be used to receive other send streams. +In this way datasets can be used for data backup and replication, +with all the benefits that zfs send and receive have to offer, +while protecting sensitive information from being stored on less-trusted machines or services. .Pp -For the purposes of redaction, there are two steps to the process. A redact -step, and a send/receive step. First, a redaction bookmark is created. This is -done by providing the -.Sy zfs redact +For the purposes of redaction, there are two steps to the process. +A redact step, and a send/receive step. +First, a redaction bookmark is created. +This is done by providing the +.Nm zfs Cm redact command with a parent snapshot, a bookmark to be created, and a number of -redaction snapshots. These redaction snapshots must be descendants of the -parent snapshot, and they should modify data that is considered sensitive in -some way. Any blocks of data modified by all of the redaction snapshots will +redaction snapshots. +These redaction snapshots must be descendants of the parent snapshot, +and they should modify data that is considered sensitive in some way. +Any blocks of data modified by all of the redaction snapshots will be listed in the redaction bookmark, because it represents the truly sensitive -information. When it comes to the send step, the send process will not send +information. +When it comes to the send step, the send process will not send the blocks listed in the redaction bookmark, instead replacing them with -REDACT records. When received on the target system, this will create a +REDACT records. +When received on the target system, this will create a redacted dataset, missing the data that corresponds to the blocks in the -redaction bookmark on the sending system. The incremental send streams from +redaction bookmark on the sending system. +The incremental send streams from the original parent to the redaction snapshots can then also be received on the target system, and this will produce a complete snapshot that can be used -normally. Incrementals from one snapshot on the parent filesystem and another +normally. +Incrementals from one snapshot on the parent filesystem and another can also be done by sending from the redaction bookmark, rather than the snapshots themselves. .Pp -In order to make the purpose of the feature more clear, an example is -provided. Consider a zfs filesystem containing four files. These files -represent information for an online shopping service. One file contains a list -of usernames and passwords, another contains purchase histories, a third -contains click tracking data, and a fourth contains user preferences. The -owner of this data wants to make it available for their development teams to -test against, and their market research teams to do analysis on. The -development teams need information about user preferences and the click +In order to make the purpose of the feature more clear, an example is provided. +Consider a zfs filesystem containing four files. +These files represent information for an online shopping service. +One file contains a list of usernames and passwords, another contains purchase histories, +a third contains click tracking data, and a fourth contains user preferences. +The owner of this data wants to make it available for their development teams to +test against, and their market research teams to do analysis on. +The development teams need information about user preferences and the click tracking data, while the market research teams need information about purchase -histories and user preferences. Neither needs access to the usernames and -passwords. However, because all of this data is stored in one ZFS filesystem, -it must all be sent and received together. In addition, the owner of the data +histories and user preferences. +Neither needs access to the usernames and passwords. +However, because all of this data is stored in one ZFS filesystem, +it must all be sent and received together. +In addition, the owner of the data wants to take advantage of features like compression, checksumming, and -snapshots, so they do want to continue to use ZFS to store and transmit their -data. Redaction can help them do so. First, they would make two clones of a -snapshot of the data on the source. In one clone, they create the setup they -want their market research team to see; they delete the usernames and -passwords file, and overwrite the click tracking data with dummy -information. In another, they create the setup they want the development teams +snapshots, so they do want to continue to use ZFS to store and transmit their data. +Redaction can help them do so. +First, they would make two clones of a snapshot of the data on the source. +In one clone, they create the setup they want their market research team to see; +they delete the usernames and passwords file, +and overwrite the click tracking data with dummy information. +In another, they create the setup they want the development teams to see, by replacing the passwords with fake information and replacing the -purchase histories with randomly generated ones. They would then create a -redaction bookmark on the parent snapshot, using snapshots on the two clones -as redaction snapshots. The parent can then be sent, redacted, to the target -server where the research and development teams have access. Finally, -incremental sends from the parent snapshot to each of the clones can be send +purchase histories with randomly generated ones. +They would then create a redaction bookmark on the parent snapshot, +using snapshots on the two clones as redaction snapshots. +The parent can then be sent, redacted, to the target +server where the research and development teams have access. +Finally, incremental sends from the parent snapshot to each of the clones can be sent to and received on the target server; these snapshots are identical to the ones on the source, and are ready to be used, while the parent snapshot on the target contains none of the username and password data present on the source, because it was removed by the redacted send operation. +. .Sh SEE ALSO .Xr zfs-bookmark 8 , .Xr zfs-receive 8 , diff --git a/sys/contrib/openzfs/man/man8/zfs-set.8 b/sys/contrib/openzfs/man/man8/zfs-set.8 index 74a7a61d0e2..83709fa6149 100644 --- a/sys/contrib/openzfs/man/man8/zfs-set.8 +++ b/sys/contrib/openzfs/man/man8/zfs-set.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -30,37 +29,39 @@ .\" Copyright 2018 Nexenta Systems, Inc. .\" Copyright 2019 Joyent, Inc. .\" -.Dd June 30, 2019 +.Dd June 2, 2021 .Dt ZFS-SET 8 .Os +. .Sh NAME .Nm zfs-set -.Nd Sets the property or list of properties to the given value(s) for each dataset. +.Nd set properties on ZFS datasets .Sh SYNOPSIS .Nm zfs .Cm set -.Ar property Ns = Ns Ar value Oo Ar property Ns = Ns Ar value Oc Ns ... -.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ... +.Ar property Ns = Ns Ar value Oo Ar property Ns = Ns Ar value Oc Ns … +.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns … .Nm zfs .Cm get .Op Fl r Ns | Ns Fl d Ar depth .Op Fl Hp -.Oo Fl o Ar field Ns Oo , Ns Ar field Oc Ns ... Oc -.Oo Fl s Ar source Ns Oo , Ns Ar source Oc Ns ... Oc -.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc -.Cm all | Ar property Ns Oo , Ns Ar property Oc Ns ... -.Oo Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns | Ns Ar bookmark Oc Ns ... +.Oo Fl o Ar field Ns Oo , Ns Ar field Oc Ns … Oc +.Oo Fl s Ar source Ns Oo , Ns Ar source Oc Ns … Oc +.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns … Oc +.Cm all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns … +.Oo Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns | Ns Ar bookmark Oc Ns … .Nm zfs .Cm inherit .Op Fl rS -.Ar property Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ... +.Ar property Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns … +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo .Nm zfs .Cm set -.Ar property Ns = Ns Ar value Oo Ar property Ns = Ns Ar value Oc Ns ... -.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ... +.Ar property Ns = Ns Ar value Oo Ar property Ns = Ns Ar value Oc Ns … +.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns … .Xc Only some properties can be edited. See @@ -83,39 +84,43 @@ section of .Cm get .Op Fl r Ns | Ns Fl d Ar depth .Op Fl Hp -.Oo Fl o Ar field Ns Oo , Ns Ar field Oc Ns ... Oc -.Oo Fl s Ar source Ns Oo , Ns Ar source Oc Ns ... Oc -.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc -.Cm all | Ar property Ns Oo , Ns Ar property Oc Ns ... -.Oo Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns | Ns Ar bookmark Oc Ns ... +.Oo Fl o Ar field Ns Oo , Ns Ar field Oc Ns … Oc +.Oo Fl s Ar source Ns Oo , Ns Ar source Oc Ns … Oc +.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns … Oc +.Cm all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns … +.Oo Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns | Ns Ar bookmark Oc Ns … .Xc Displays properties for the given datasets. If no datasets are specified, then the command displays properties for all datasets on the system. For each property, the following columns are displayed: -.Bd -literal - name Dataset name - property Property name - value Property value - source Property source \fBlocal\fP, \fBdefault\fP, \fBinherited\fP, - \fBtemporary\fP, \fBreceived\fP or none (\fB-\fP). -.Ed +.Bl -tag -compact -offset 4n -width "property" +.It Sy name +Dataset name +.It Sy property +Property name +.It Sy value +Property value +.It Sy source +Property source +.Sy local , default , inherited , temporary , received , No or Sy - Pq none . +.El .Pp All columns are displayed by default, though this can be controlled by using the .Fl o option. This command takes a comma-separated list of properties as described in the -.Em Native Properties +.Sx Native Properties and -.Em User Properties +.Sx User Properties sections of .Xr zfsprops 8 . .Pp The value .Sy all can be used to display all properties that apply to the given dataset's type -.Pq filesystem, volume, snapshot, or bookmark . -.Bl -tag -width "-H" +.Pq Sy filesystem , volume , snapshot , No or Sy bookmark . +.Bl -tag -width "-s source" .It Fl H Display output in a form more easily parsed by scripts. Any headers are omitted, and fields are explicitly separated by a single tab @@ -127,9 +132,8 @@ A depth of .Sy 1 will display only the dataset and its direct children. .It Fl o Ar field -A comma-separated list of columns to display. -.Sy name Ns \&, Ns Sy property Ns \&, Ns Sy value Ns \&, Ns Sy source -is the default value. +A comma-separated list of columns to display, defaults to +.Sy name , Ns Sy property , Ns Sy value , Ns Sy source . .It Fl p Display numbers in parsable .Pq exact @@ -140,30 +144,19 @@ Recursively display properties for any children. A comma-separated list of sources to display. Those properties coming from a source other than those in this list are ignored. Each source must be one of the following: -.Sy local , -.Sy default , -.Sy inherited , -.Sy temporary , -.Sy received , -and -.Sy none . +.Sy local , default , inherited , temporary , received , No or Sy none . The default value is all sources. .It Fl t Ar type A comma-separated list of types to display, where .Ar type is one of -.Sy filesystem , -.Sy snapshot , -.Sy volume , -.Sy bookmark , -or -.Sy all . +.Sy filesystem , snapshot , volume , bookmark , No or Sy all . .El .It Xo .Nm zfs .Cm inherit .Op Fl rS -.Ar property Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ... +.Ar property Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns … .Xc Clears the specified property, causing it to be inherited from an ancestor, restored to default if no ancestor has the property set, or with the @@ -183,6 +176,7 @@ if the option was not specified. .El .El +. .Sh SEE ALSO .Xr zfs-list 8 , .Xr zfsprops 8 diff --git a/sys/contrib/openzfs/man/man8/zfs-share.8 b/sys/contrib/openzfs/man/man8/zfs-share.8 index ce35accdbf7..369f667c9d0 100644 --- a/sys/contrib/openzfs/man/man8/zfs-share.8 +++ b/sys/contrib/openzfs/man/man8/zfs-share.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -33,22 +32,24 @@ .Dd June 30, 2019 .Dt ZFS-SHARE 8 .Os +. .Sh NAME .Nm zfs-share -.Nd Shares and unshares available ZFS filesystems. +.Nd share and unshare ZFS filesystems .Sh SYNOPSIS .Nm zfs .Cm share -.Fl a | Ar filesystem +.Fl a Ns | Ns Ar filesystem .Nm zfs .Cm unshare -.Fl a | Ar filesystem Ns | Ns Ar mountpoint +.Fl a Ns | Ns Ar filesystem Ns | Ns Ar mountpoint +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo .Nm zfs .Cm share -.Fl a | Ar filesystem +.Fl a Ns | Ns Ar filesystem .Xc Shares available ZFS file systems. .Bl -tag -width "-a" @@ -70,7 +71,7 @@ property is set. .It Xo .Nm zfs .Cm unshare -.Fl a | Ar filesystem Ns | Ns Ar mountpoint +.Fl a Ns | Ns Ar filesystem Ns | Ns Ar mountpoint .Xc Unshares currently shared ZFS file systems. .Bl -tag -width "-a" @@ -82,6 +83,7 @@ Unshare the specified filesystem. The command can also be given a path to a ZFS file system shared on the system. .El .El +. .Sh SEE ALSO .Xr exports 5 , .Xr smb.conf 5 , diff --git a/sys/contrib/openzfs/man/man8/zfs-snapshot.8 b/sys/contrib/openzfs/man/man8/zfs-snapshot.8 index b677bc73d2b..fdff39fbc4b 100644 --- a/sys/contrib/openzfs/man/man8/zfs-snapshot.8 +++ b/sys/contrib/openzfs/man/man8/zfs-snapshot.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -30,48 +29,42 @@ .\" Copyright 2018 Nexenta Systems, Inc. .\" Copyright 2019 Joyent, Inc. .\" -.Dd June 30, 2019 +.Dd May 27, 2021 .Dt ZFS-SNAPSHOT 8 .Os +. .Sh NAME .Nm zfs-snapshot -.Nd Creates snapshots with the given names. +.Nd create snapshots of ZFS datasets .Sh SYNOPSIS .Nm zfs .Cm snapshot .Op Fl r -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... -.Ar filesystem Ns @ Ns Ar snapname Ns | Ns Ar volume Ns @ Ns Ar snapname Ns ... +.Oo Fl o Ar property Ns = Ns Ar value Oc Ns … +.Ar dataset Ns @ Ns Ar snapname Ns … +. .Sh DESCRIPTION -.Bl -tag -width "" -.It Xo -.Nm zfs -.Cm snapshot -.Op Fl r -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... -.Ar filesystem Ns @ Ns Ar snapname Ns | Ns Ar volume Ns @ Ns Ar snapname Ns ... -.Xc All previous modifications by successful system calls to the file system are part of the snapshots. Snapshots are taken atomically, so that all snapshots correspond to the same moment in time. .Nm zfs Cm snap can be used as an alias for -.Nm zfs Cm snapshot. +.Nm zfs Cm snapshot . See the -.Em Snapshots +.Sx Snapshots section of .Xr zfsconcepts 8 for details. .Bl -tag -width "-o" .It Fl o Ar property Ns = Ns Ar value -Sets the specified property; see +Set the specified property; see .Nm zfs Cm create for details. .It Fl r Recursively create snapshots of all descendent datasets .El -.El +. .Sh SEE ALSO .Xr zfs-bookmark 8 , .Xr zfs-clone 8 , diff --git a/sys/contrib/openzfs/man/man8/zfs-upgrade.8 b/sys/contrib/openzfs/man/man8/zfs-upgrade.8 index 6a79f3ea77f..0ba276dc6ad 100644 --- a/sys/contrib/openzfs/man/man8/zfs-upgrade.8 +++ b/sys/contrib/openzfs/man/man8/zfs-upgrade.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -33,9 +32,10 @@ .Dd June 30, 2019 .Dt ZFS-UPGRADE 8 .Os +. .Sh NAME .Nm zfs-upgrade -.Nd Manage upgrading the on-disk version of filesystems. +.Nd manage on-disk version of ZFS filesystems .Sh SYNOPSIS .Nm zfs .Cm upgrade @@ -46,7 +46,8 @@ .Cm upgrade .Op Fl r .Op Fl V Ar version -.Fl a | Ar filesystem +.Fl a Ns | Ns Ar filesystem +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo @@ -65,35 +66,31 @@ Displays a list of currently supported file system versions. .Cm upgrade .Op Fl r .Op Fl V Ar version -.Fl a | Ar filesystem +.Fl a Ns | Ns Ar filesystem .Xc Upgrades file systems to a new on-disk version. Once this is done, the file systems will no longer be accessible on systems -running older versions of the software. +running older versions of ZFS. .Nm zfs Cm send streams generated from new snapshots of these file systems cannot be accessed on -systems running older versions of the software. +systems running older versions of ZFS. .Pp In general, the file system version is independent of the pool version. See -.Xr zpool 8 -for information on the -.Nm zpool Cm upgrade -command. +.Xr zpool-features 5 +for information on features of ZFS storage pools. .Pp In some cases, the file system version and the pool version are interrelated and the pool version must be upgraded before the file system version can be upgraded. -.Bl -tag -width "-V" +.Bl -tag -width "filesystem" .It Fl V Ar version -Upgrade to the specified +Upgrade to .Ar version . -If the -.Fl V -flag is not specified, this command upgrades to the most recent version. +If not specified, upgrade to the most recent version. This option can only be used to increase the version number, and only up to the most -recent version supported by this software. +recent version supported by this version of ZFS. .It Fl a Upgrade all file systems on all imported pools. .It Ar filesystem diff --git a/sys/contrib/openzfs/man/man8/zfs-userspace.8 b/sys/contrib/openzfs/man/man8/zfs-userspace.8 index 0a9977a61c6..d09e35e1fdd 100644 --- a/sys/contrib/openzfs/man/man8/zfs-userspace.8 +++ b/sys/contrib/openzfs/man/man8/zfs-userspace.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -33,43 +32,45 @@ .Dd June 30, 2019 .Dt ZFS-USERSPACE 8 .Os +. .Sh NAME .Nm zfs-userspace -.Nd Displays space consumed by, and quotas on, each user or group in the specified filesystem or snapshot. +.Nd display space and quotas of ZFS dataset .Sh SYNOPSIS .Nm zfs .Cm userspace .Op Fl Hinp -.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 ... -.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc +.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 … +.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns … Oc .Ar filesystem Ns | Ns Ar snapshot Ns | Ns Ar path .Nm zfs .Cm groupspace .Op Fl Hinp -.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 ... -.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc +.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 … +.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns … Oc .Ar filesystem Ns | Ns Ar snapshot Ns | Ns Ar path .Nm zfs .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 ... +.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 Ns | Ns Ar path +. .Sh DESCRIPTION .Bl -tag -width "" .It Xo .Nm zfs .Cm userspace .Op Fl Hinp -.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 ... -.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc +.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 … +.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns … Oc .Ar filesystem Ns | Ns Ar snapshot Ns | Ns Ar path .Xc Displays space consumed by, and quotas on, each user in the specified filesystem, @@ -78,11 +79,11 @@ 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 , -.Sy userquota@ Ns Em user, +.Sy userquota@ Ns Em user , and .Sy userobjquota@ Ns Em user properties. -.Bl -tag -width "-H" +.Bl -tag -width "-S field" .It Fl H Do not print headers, use tab-delimited output. .It Fl S Ar field @@ -93,10 +94,7 @@ See Translate SID to POSIX ID. The POSIX ID may be ephemeral if no mapping exists. Normal POSIX interfaces -.Po for example, -.Xr stat 2 , -.Nm ls Fl l -.Pc +.Pq like Xr stat 2 , Nm ls Fl l perform this translation, so the .Fl i option allows the output from @@ -113,7 +111,7 @@ However, the option will report that the POSIX entity has the total usage and quota for both. .It Fl n Print numeric ID instead of user/group name. -.It Fl o Ar field Ns Oo , Ns Ar field Oc Ns ... +.It Fl o Ar field Ns Oo , Ns Ar field Oc Ns … Display only the specified fields from the following set: .Sy type , .Sy name , @@ -134,7 +132,7 @@ flags may be specified multiple times to sort first by one field, then by another. The default is .Fl s Sy type Fl s Sy name . -.It Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... +.It Fl t Ar type Ns Oo , Ns Ar type Oc Ns … Print only the specified types from the following set: .Sy all , .Sy posixuser , @@ -142,17 +140,17 @@ Print only the specified types from the following set: .Sy posixgroup , .Sy smbgroup . The default is -.Fl t Sy posixuser Ns \&, Ns Sy smbuser . +.Fl t Sy posixuser , Ns Sy smbuser . The default can be changed to include group types. .El .It Xo .Nm zfs .Cm groupspace .Op Fl Hinp -.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 ... -.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc +.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 … +.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns … Oc .Ar filesystem Ns | Ns Ar snapshot .Xc Displays space consumed by, and quotas on, each group in the specified @@ -160,28 +158,30 @@ filesystem or snapshot. This subcommand is identical to .Cm userspace , except that the default types to display are -.Fl t Sy posixgroup Ns \&, Ns Sy smbgroup . +.Fl t Sy posixgroup , Ns Sy smbgroup . .It Xo .Nm zfs .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 ... +.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 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 +filesystem or snapshot. +This subcommand is identical to .Cm userspace , -except that the project identifier is numeral, not name. So need neither -the option -.Sy -i +except that the project identifier is a numeral, not a name. +So need neither the option +.Fl i for SID to POSIX ID nor -.Sy -n +.Fl n for numeric ID, nor -.Sy -t +.Fl t for types. .El +. .Sh SEE ALSO .Xr zfs-set 8 , .Xr zfsprops 8 diff --git a/sys/contrib/openzfs/man/man8/zfs-wait.8 b/sys/contrib/openzfs/man/man8/zfs-wait.8 index c3a85e29c6c..81bc1563654 100644 --- a/sys/contrib/openzfs/man/man8/zfs-wait.8 +++ b/sys/contrib/openzfs/man/man8/zfs-wait.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,25 +26,20 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd May 31, 2021 .Dt ZFS-WAIT 8 .Os +. .Sh NAME .Nm zfs-wait -.Nd Wait for background activity to stop in a ZFS filesystem +.Nd wait for activity in ZFS filesystem to stop .Sh SYNOPSIS .Nm zfs .Cm wait -.Op Fl t Ar activity Ns Oo , Ns Ar activity Ns Oc Ns ... -.Ar fs +.Op Fl t Ar activity Ns Oo , Ns Ar activity Ns Oc Ns … +.Ar filesystem +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zfs -.Cm wait -.Op Fl t Ar activity Ns Oo , Ns Ar activity Ns Oc Ns ... -.Ar fs -.Xc Waits until all background activity of the given types has ceased in the given filesystem. The activity could cease because it has completed or because the filesystem has @@ -58,14 +52,14 @@ immediately. These are the possible values for .Ar activity , along with what each one waits for: -.Bd -literal - deleteq The filesystem's internal delete queue to empty -.Ed +.Bl -tag -compact -offset Ds -width "deleteq" +.It Sy deleteq +The filesystem's internal delete queue to empty +.El .Pp Note that the internal delete queue does not finish draining until all large files have had time to be fully destroyed and all open file handles to unlinked files are closed. -.El -.El +. .Sh SEE ALSO -.Xr lsof 8 +.Xr lsof 8 diff --git a/sys/contrib/openzfs/man/man8/zfs.8 b/sys/contrib/openzfs/man/man8/zfs.8 index 4cff97792a9..16c874eb20d 100644 --- a/sys/contrib/openzfs/man/man8/zfs.8 +++ b/sys/contrib/openzfs/man/man8/zfs.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -40,17 +39,19 @@ .Dd June 30, 2019 .Dt ZFS 8 .Os +. .Sh NAME .Nm zfs -.Nd configures ZFS file systems +.Nd configure ZFS datasets .Sh SYNOPSIS .Nm .Fl ?V .Nm .Cm version .Nm -.Cm -.Op Ar +.Cm subcommand +.Op Ar arguments +. .Sh DESCRIPTION The .Nm @@ -58,23 +59,18 @@ command configures ZFS datasets within a ZFS storage pool, as described in .Xr zpool 8 . A dataset is identified by a unique path within the ZFS namespace. For example: -.Bd -literal -pool/{filesystem,volume,snapshot} -.Ed +.Dl pool/{filesystem,volume,snapshot} .Pp where the maximum length of a dataset name is -.Dv MAXNAMELEN -.Pq 256 bytes +.Sy MAXNAMELEN Pq 256B and the maximum amount of nesting allowed in a path is 50 levels deep. .Pp A dataset can be one of the following: -.Bl -tag -width "file system" +.Bl -tag -offset Ds -width "file system" .It Sy file system -A ZFS dataset of type -.Sy filesystem -can be mounted within the standard system namespace and behaves like other file +Can be mounted within the standard system namespace and behaves like other file systems. -While ZFS file systems are designed to be POSIX compliant, known issues exist +While ZFS file systems are designed to be POSIX-compliant, known issues exist that prevent compliance in some cases. Applications that depend on standards conformance might fail due to non-standard behavior when checking file system free space. @@ -92,38 +88,39 @@ or Much like a .Sy snapshot , but without the hold on on-disk data. -It can be used as the source of a send (but not for a receive). It is specified as +It can be used as the source of a send (but not for a receive). +It is specified as .Ar filesystem Ns # Ns Ar name or .Ar volume Ns # Ns Ar name . .El .Pp -For details see -.Xr zfsconcepts 8 . +See +.Xr zfsconcepts 8 +for details. +. .Ss Properties -Properties are divided into two types, native properties and user-defined -.Po or -.Qq user -.Pc +Properties are divided into two types: native properties and user-defined +.Pq or Qq user properties. Native properties either export internal statistics or control ZFS behavior. In addition, native properties are either editable or read-only. User properties have no effect on ZFS behavior, but you can use them to annotate datasets in a way that is meaningful in your environment. -For more information about properties, see the -.Xr zfsprops 8 man page. +For more information about properties, see +.Xr zfsprops 8 . +. .Ss Encryption Enabling the .Sy encryption feature allows for the creation of encrypted filesystems and volumes. ZFS will encrypt file and zvol data, file attributes, ACLs, permission bits, directory listings, FUID mappings, and -.Sy userused -/ -.Sy groupused +.Sy userused Ns / Ns Sy groupused Ns / Ns Sy projectused data. -For an overview of encryption see the -.Xr zfs-load-key 8 command manual. +For an overview of encryption, see +.Xr zfs-load-key 8 . +. .Sh SUBCOMMANDS All subcommands that modify state are logged persistently to the pool in their original form. @@ -134,9 +131,6 @@ Displays a help message. .Nm .Fl V , -version .Xc -An alias for the -.Nm zfs Cm version -subcommand. .It Xo .Nm .Cm version @@ -145,6 +139,7 @@ Displays the software version of the .Nm userland utility and the zfs kernel module. .El +. .Ss Dataset Management .Bl -tag -width "" .It Xr zfs-list 8 @@ -158,26 +153,25 @@ Renames the given dataset (filesystem or snapshot). .It Xr zfs-upgrade 8 Manage upgrading the on-disk version of filesystems. .El +. .Ss Snapshots .Bl -tag -width "" .It Xr zfs-snapshot 8 Creates snapshots with the given names. .It Xr zfs-rollback 8 Roll back the given dataset to a previous snapshot. -.It Xo -.Xr zfs-hold 8 / -.Xr zfs-release 8 -.Xc +.It Xr zfs-hold 8 Ns / Ns Xr zfs-release 8 Add or remove a hold reference to the specified snapshot or snapshots. If a hold exists on a snapshot, attempts to destroy that snapshot by using the .Nm zfs Cm destroy command return -.Er EBUSY . +.Sy EBUSY . .It Xr zfs-diff 8 Display the difference between a snapshot of a given filesystem and another snapshot of that filesystem from a later time or the current contents of the filesystem. .El +. .Ss Clones .Bl -tag -width "" .It Xr zfs-clone 8 @@ -187,6 +181,7 @@ Promotes a clone file system to no longer be dependent on its .Qq origin snapshot. .El +. .Ss Send & Receive .Bl -tag -width "" .It Xr zfs-send 8 @@ -211,6 +206,7 @@ This feature can be used to allow clones of a filesystem to be made available on a remote system, in the case where their parent need not (or needs to not) be usable. .El +. .Ss Properties .Bl -tag -width "" .It Xr zfs-get 8 @@ -223,18 +219,16 @@ restored to default if no ancestor has the property set, or with the .Fl S option reverted to the received value if one exists. .El +. .Ss Quotas .Bl -tag -width "" -.It Xo -.Xr zfs-userspace 8 / -.Xr zfs-groupspace 8 / -.Xr zfs-projectspace 8 -.Xc +.It Xr zfs-userspace 8 Ns / Ns Xr zfs-groupspace 8 Ns / Ns Xr zfs-projectspace 8 Displays space consumed by, and quotas on, each user, group, or project in the specified filesystem or snapshot. .It Xr zfs-project 8 List, set, or clear project ID and/or inherit flag on the file(s) or directories. .El +. .Ss Mountpoints .Bl -tag -width "" .It Xr zfs-mount 8 @@ -245,6 +239,7 @@ property. .It Xr zfs-unmount 8 Unmounts currently mounted ZFS file systems. .El +. .Ss Shares .Bl -tag -width "" .It Xr zfs-share 8 @@ -252,6 +247,7 @@ Shares available ZFS file systems. .It Xr zfs-unshare 8 Unshares currently shared ZFS file systems. .El +. .Ss Delegated Administration .Bl -tag -width "" .It Xr zfs-allow 8 @@ -259,6 +255,7 @@ Delegate permissions on the specified filesystem or volume. .It Xr zfs-unallow 8 Remove delegated permissions on the specified filesystem or volume. .El +. .Ss Encryption .Bl -tag -width "" .It Xr zfs-change-key 8 @@ -268,12 +265,14 @@ Load the key for the specified encrypted dataset, enabling access. .It Xr zfs-unload-key 8 Unload a key for the specified dataset, removing the ability to access the dataset. .El +. .Ss Channel Programs .Bl -tag -width "" .It Xr zfs-program 8 Execute ZFS administrative operations programmatically via a Lua script-language channel program. .El +. .Ss Jails .Bl -tag -width "" .It Xr zfs-jail 8 @@ -281,100 +280,101 @@ Attaches a filesystem to a jail. .It Xr zfs-unjail 8 Detaches a filesystem from a jail. .El +. .Ss Waiting .Bl -tag -width "" .It Xr zfs-wait 8 Wait for background activity in a filesystem to complete. .El +. .Sh EXIT STATUS The .Nm -utility exits 0 on success, 1 if an error occurs, and 2 if invalid command line -options were specified. +utility exits +.Sy 0 +on success, +.Sy 1 +if an error occurs, and +.Sy 2 +if invalid command line options were specified. +. .Sh EXAMPLES .Bl -tag -width "" -.It Sy Example 1 No Creating a ZFS File System Hierarchy +. +.It Sy Example 1 : No Creating a ZFS File System Hierarchy The following commands create a file system named -.Em pool/home +.Ar pool/home and a file system named -.Em pool/home/bob . +.Ar pool/home/bob . The mount point .Pa /export/home is set for the parent file system, and is automatically inherited by the child file system. -.Bd -literal -# zfs create pool/home -# zfs set mountpoint=/export/home pool/home -# zfs create pool/home/bob -.Ed -.It Sy Example 2 No Creating a ZFS Snapshot +.Dl # Nm zfs Cm create Ar pool/home +.Dl # Nm zfs Cm set Sy mountpoint Ns = Ns Ar /export/home pool/home +.Dl # Nm zfs Cm create Ar pool/home/bob +. +.It Sy Example 2 : No Creating a ZFS Snapshot The following command creates a snapshot named -.Sy yesterday . +.Ar yesterday . This snapshot is mounted on demand in the .Pa .zfs/snapshot directory at the root of the -.Em pool/home/bob +.Ar pool/home/bob file system. -.Bd -literal -# zfs snapshot pool/home/bob@yesterday -.Ed -.It Sy Example 3 No Creating and Destroying Multiple Snapshots +.Dl # Nm zfs Cm snapshot Ar pool/home/bob Ns @ Ns Ar yesterday +. +.It Sy Example 3 : No Creating and Destroying Multiple Snapshots The following command creates snapshots named -.Sy yesterday -of -.Em pool/home +.Ar yesterday No of Ar pool/home and all of its descendent file systems. Each snapshot is mounted on demand in the .Pa .zfs/snapshot directory at the root of its file system. The second command destroys the newly created snapshots. -.Bd -literal -# zfs snapshot -r pool/home@yesterday -# zfs destroy -r pool/home@yesterday -.Ed -.It Sy Example 4 No Disabling and Enabling File System Compression +.Dl # Nm zfs Cm snapshot Fl r Ar pool/home Ns @ Ns Ar yesterday +.Dl # Nm zfs Cm destroy Fl r Ar pool/home Ns @ Ns Ar yesterday +. +.It Sy Example 4 : No Disabling and Enabling File System Compression The following command disables the .Sy compression property for all file systems under -.Em pool/home . +.Ar pool/home . The next command explicitly enables .Sy compression for -.Em pool/home/anne . -.Bd -literal -# zfs set compression=off pool/home -# zfs set compression=on pool/home/anne -.Ed -.It Sy Example 5 No Listing ZFS Datasets +.Ar pool/home/anne . +.Dl # Nm zfs Cm set Sy compression Ns = Ns Sy off Ar pool/home +.Dl # Nm zfs Cm set Sy compression Ns = Ns Sy on Ar pool/home/anne +. +.It Sy Example 5 : No Listing ZFS Datasets The following command lists all active file systems and volumes in the system. -Snapshots are displayed if the -.Sy listsnaps -property is -.Sy on . +Snapshots are displayed if +.Sy listsnaps Ns = Ns Sy on . The default is .Sy off . See -.Xr zpool 8 +.Xr zpoolprops 8 for more information on pool properties. -.Bd -literal -# zfs list +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm list NAME USED AVAIL REFER MOUNTPOINT pool 450K 457G 18K /pool pool/home 315K 457G 21K /export/home pool/home/anne 18K 457G 18K /export/home/anne pool/home/bob 276K 457G 276K /export/home/bob .Ed -.It Sy Example 6 No Setting a Quota on a ZFS File System +. +.It Sy Example 6 : No Setting a Quota on a ZFS File System The following command sets a quota of 50 Gbytes for -.Em pool/home/bob . -.Bd -literal -# zfs set quota=50G pool/home/bob -.Ed -.It Sy Example 7 No Listing ZFS Properties +.Ar pool/home/bob : +.Dl # Nm zfs Cm set Sy quota Ns = Ns Ar 50G pool/home/bob +. +.It Sy Example 7 : No Listing ZFS Properties The following command lists all properties for -.Em pool/home/bob . -.Bd -literal -# zfs get all pool/home/bob +.Ar pool/home/bob : +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm get Sy all Ar pool/home/bob NAME PROPERTY VALUE SOURCE pool/home/bob type filesystem - pool/home/bob creation Tue Jul 21 15:53 2009 - @@ -420,63 +420,61 @@ pool/home/bob usedbychildren 0 - pool/home/bob usedbyrefreservation 0 - .Ed .Pp -The following command gets a single property value. -.Bd -literal -# zfs get -H -o value compression pool/home/bob +The following command gets a single property value: +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm get Fl H o Sy value compression Ar pool/home/bob on .Ed +.Pp The following command lists all properties with local settings for -.Em pool/home/bob . -.Bd -literal -# zfs get -r -s local -o name,property,value all pool/home/bob +.Ar pool/home/bob : +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm get Fl r s Sy local Fl o Sy name , Ns Sy property , Ns Sy value all Ar pool/home/bob NAME PROPERTY VALUE pool/home/bob quota 20G pool/home/bob compression on .Ed -.It Sy Example 8 No Rolling Back a ZFS File System +. +.It Sy Example 8 : No Rolling Back a ZFS File System The following command reverts the contents of -.Em pool/home/anne +.Ar pool/home/anne to the snapshot named -.Sy yesterday , -deleting all intermediate snapshots. -.Bd -literal -# zfs rollback -r pool/home/anne@yesterday -.Ed -.It Sy Example 9 No Creating a ZFS Clone +.Ar yesterday , +deleting all intermediate snapshots: +.Dl # Nm zfs Cm rollback Fl r Ar pool/home/anne Ns @ Ns Ar yesterday +. +.It Sy Example 9 : No Creating a ZFS Clone The following command creates a writable file system whose initial contents are the same as -.Em pool/home/bob@yesterday . -.Bd -literal -# zfs clone pool/home/bob@yesterday pool/clone -.Ed -.It Sy Example 10 No Promoting a ZFS Clone +.Ar pool/home/bob@yesterday . +.Dl # Nm zfs Cm clone Ar pool/home/bob@yesterday pool/clone +. +.It Sy Example 10 : No Promoting a ZFS Clone The following commands illustrate how to test out changes to a file system, and then replace the original file system with the changed one, using clones, clone promotion, and renaming: -.Bd -literal -# zfs create pool/project/production +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm create Ar pool/project/production populate /pool/project/production with data -# zfs snapshot pool/project/production@today -# zfs clone pool/project/production@today pool/project/beta +.No # Nm zfs Cm snapshot Ar pool/project/production Ns @ Ns Ar today +.No # Nm zfs Cm clone Ar pool/project/production@today pool/project/beta make changes to /pool/project/beta and test them -# zfs promote pool/project/beta -# zfs rename pool/project/production pool/project/legacy -# zfs rename pool/project/beta pool/project/production +.No # Nm zfs Cm promote Ar pool/project/beta +.No # Nm zfs Cm rename Ar pool/project/production pool/project/legacy +.No # Nm zfs Cm rename Ar pool/project/beta pool/project/production once the legacy version is no longer needed, it can be destroyed -# zfs destroy pool/project/legacy +.No # Nm zfs Cm destroy Ar pool/project/legacy .Ed -.It Sy Example 11 No Inheriting ZFS Properties +. +.It Sy Example 11 : No Inheriting ZFS Properties The following command causes -.Em pool/home/bob -and -.Em pool/home/anne +.Ar pool/home/bob No and Ar pool/home/anne to inherit the .Sy checksum property from their parent. -.Bd -literal -# zfs inherit checksum pool/home/bob pool/home/anne -.Ed -.It Sy Example 12 No Remotely Replicating ZFS Data +.Dl # Nm zfs Cm inherit Sy checksum Ar pool/home/bob pool/home/anne +. +.It Sy Example 12 : No Remotely Replicating ZFS Data The following commands send a full stream and then an incremental stream to a remote machine, restoring them into .Em poolB/received/fs@a @@ -488,147 +486,145 @@ must contain the file system .Em poolB/received , and must not initially contain .Em poolB/received/fs . -.Bd -literal -# zfs send pool/fs@a | \e - ssh host zfs receive poolB/received/fs@a -# zfs send -i a pool/fs@b | \e - ssh host zfs receive poolB/received/fs +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm send Ar pool/fs@a | +.No " " Nm ssh Ar host Nm zfs Cm receive Ar poolB/received/fs Ns @ Ns Ar a +.No # Nm zfs Cm send Fl i Ar a pool/fs@b | +.No " " Nm ssh Ar host Nm zfs Cm receive Ar poolB/received/fs .Ed -.It Sy Example 13 No Using the zfs receive -d Option +. +.It Sy Example 13 : No Using the Nm zfs Cm receive Fl d No Option The following command sends a full stream of -.Em poolA/fsA/fsB@snap +.Ar poolA/fsA/fsB@snap to a remote machine, receiving it into -.Em poolB/received/fsA/fsB@snap . +.Ar poolB/received/fsA/fsB@snap . The -.Em fsA/fsB@snap +.Ar fsA/fsB@snap portion of the received snapshot's name is determined from the name of the sent snapshot. -.Em poolB +.Ar poolB must contain the file system -.Em poolB/received . +.Ar poolB/received . If -.Em poolB/received/fsA +.Ar poolB/received/fsA does not exist, it is created as an empty file system. -.Bd -literal -# zfs send poolA/fsA/fsB@snap | \e - ssh host zfs receive -d poolB/received +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm send Ar poolA/fsA/fsB@snap | +.No " " Nm ssh Ar host Nm zfs Cm receive Fl d Ar poolB/received .Ed -.It Sy Example 14 No Setting User Properties +. +.It Sy Example 14 : No Setting User Properties The following example sets the user-defined -.Sy com.example:department -property for a dataset. -.Bd -literal -# zfs set com.example:department=12345 tank/accounting -.Ed -.It Sy Example 15 No Performing a Rolling Snapshot +.Ar com.example : Ns Ar department +property for a dataset: +.Dl # Nm zfs Cm set Ar com.example : Ns Ar department Ns = Ns Ar 12345 tank/accounting +. +.It Sy Example 15 : No Performing a Rolling Snapshot The following example shows how to maintain a history of snapshots with a consistent naming scheme. To keep a week's worth of snapshots, the user destroys the oldest snapshot, renames the remaining snapshots, and then creates a new snapshot, as follows: -.Bd -literal -# zfs destroy -r pool/users@7daysago -# zfs rename -r pool/users@6daysago @7daysago -# zfs rename -r pool/users@5daysago @6daysago -# zfs rename -r pool/users@4daysago @5daysago -# zfs rename -r pool/users@3daysago @4daysago -# zfs rename -r pool/users@2daysago @3daysago -# zfs rename -r pool/users@yesterday @2daysago -# zfs rename -r pool/users@today @yesterday -# zfs snapshot -r pool/users@today +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm destroy Fl r Ar pool/users@7daysago +.No # Nm zfs Cm rename Fl r Ar pool/users@6daysago No @ Ns Ar 7daysago +.No # Nm zfs Cm rename Fl r Ar pool/users@5daysago No @ Ns Ar 6daysago +.No # Nm zfs Cm rename Fl r Ar pool/users@4daysago No @ Ns Ar 5daysago +.No # Nm zfs Cm rename Fl r Ar pool/users@3daysago No @ Ns Ar 4daysago +.No # Nm zfs Cm rename Fl r Ar pool/users@2daysago No @ Ns Ar 3daysago +.No # Nm zfs Cm rename Fl r Ar pool/users@yesterday No @ Ns Ar 2daysago +.No # Nm zfs Cm rename Fl r Ar pool/users@today No @ Ns Ar yesterday +.No # Nm zfs Cm snapshot Fl r Ar pool/users Ns @ Ns Ar today .Ed -.It Sy Example 16 No Setting sharenfs Property Options on a ZFS File System +. +.It Sy Example 16 : No Setting sharenfs Property Options on a ZFS File System The following commands show how to set .Sy sharenfs -property options to enable -.Sy rw -access for a set of -.Sy IP -addresses and to enable root access for system -.Sy neo +property options to enable read-write +access for a set of IP addresses and to enable root access for system +.Qq neo on the -.Em tank/home -file system. -.Bd -literal -# zfs set sharenfs='rw=@123.123.0.0/16,root=neo' tank/home -.Ed +.Ar tank/home +file system: +.Dl # Nm zfs Cm set Sy sharenfs Ns = Ns ' Ns Ar rw Ns =@123.123.0.0/16,root= Ns Ar neo Ns ' tank/home .Pp -If you are using -.Sy DNS -for host name resolution, specify the fully qualified hostname. -.It Sy Example 17 No Delegating ZFS Administration Permissions on a ZFS Dataset +If you are using DNS for host name resolution, +specify the fully-qualified hostname. +. +.It Sy Example 17 : No Delegating ZFS Administration Permissions on a ZFS Dataset The following example shows how to set permissions so that user -.Sy cindys +.Ar cindys can create, destroy, mount, and take snapshots on -.Em tank/cindys . +.Ar tank/cindys . The permissions on -.Em tank/cindys +.Ar tank/cindys are also displayed. -.Bd -literal -# zfs allow cindys create,destroy,mount,snapshot tank/cindys -# zfs allow tank/cindys +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm allow Sy cindys create , Ns Sy destroy , Ns Sy mount , Ns Sy snapshot Ar tank/cindys +.No # Nm zfs Cm allow Ar tank/cindys ---- Permissions on tank/cindys -------------------------------------- Local+Descendent permissions: user cindys create,destroy,mount,snapshot .Ed .Pp Because the -.Em tank/cindys +.Ar tank/cindys mount point permission is set to 755 by default, user -.Sy cindys +.Ar cindys will be unable to mount file systems under -.Em tank/cindys . +.Ar tank/cindys . Add an ACE similar to the following syntax to provide mount point access: -.Bd -literal -# chmod A+user:cindys:add_subdirectory:allow /tank/cindys -.Ed -.It Sy Example 18 No Delegating Create Time Permissions on a ZFS Dataset +.Dl # Cm chmod No A+user: Ns Ar cindys Ns :add_subdirectory:allow Ar /tank/cindys +. +.It Sy Example 18 : No Delegating Create Time Permissions on a ZFS Dataset The following example shows how to grant anyone in the group -.Sy staff +.Ar staff to create file systems in -.Em tank/users . +.Ar tank/users . This syntax also allows staff members to destroy their own file systems, but not destroy anyone else's file system. The permissions on -.Em tank/users +.Ar tank/users are also displayed. -.Bd -literal -# zfs allow staff create,mount tank/users -# zfs allow -c destroy tank/users -# zfs allow tank/users +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm allow Ar staff Sy create , Ns Sy mount Ar tank/users +.No # Nm zfs Cm allow Fl c Sy destroy Ar tank/users +.No # Nm zfs Cm allow Ar tank/users ---- Permissions on tank/users --------------------------------------- Permission sets: destroy Local+Descendent permissions: group staff create,mount .Ed -.It Sy Example 19 No Defining and Granting a Permission Set on a ZFS Dataset +. +.It Sy Example 19 : No Defining and Granting a Permission Set on a ZFS Dataset The following example shows how to define and grant a permission set on the -.Em tank/users +.Ar tank/users file system. The permissions on -.Em tank/users +.Ar tank/users are also displayed. -.Bd -literal -# zfs allow -s @pset create,destroy,snapshot,mount tank/users -# zfs allow staff @pset tank/users -# zfs allow tank/users +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm allow Fl s No @ Ns Ar pset Sy create , Ns Sy destroy , Ns Sy snapshot , Ns Sy mount Ar tank/users +.No # Nm zfs Cm allow staff No @ Ns Ar pset tank/users +.No # Nm zfs Cm allow Ar tank/users ---- Permissions on tank/users --------------------------------------- Permission sets: @pset create,destroy,mount,snapshot Local+Descendent permissions: group staff @pset .Ed -.It Sy Example 20 No Delegating Property Permissions on a ZFS Dataset +. +.It Sy Example 20 : No Delegating Property Permissions on a ZFS Dataset The following example shows to grant the ability to set quotas and reservations on the -.Em users/home +.Ar users/home file system. The permissions on -.Em users/home +.Ar users/home are also displayed. -.Bd -literal -# zfs allow cindys quota,reservation users/home -# zfs allow users/home +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm allow Ar cindys Sy quota , Ns Sy reservation Ar users/home +.No # Nm zfs Cm allow Ar users/home ---- Permissions on users/home --------------------------------------- Local+Descendent permissions: user cindys quota,reservation @@ -637,32 +633,34 @@ cindys% zfs get quota users/home/marks NAME PROPERTY VALUE SOURCE users/home/marks quota 10G local .Ed -.It Sy Example 21 No Removing ZFS Delegated Permissions on a ZFS Dataset +. +.It Sy Example 21 : No Removing ZFS Delegated Permissions on a ZFS Dataset The following example shows how to remove the snapshot permission from the -.Sy staff +.Ar staff group on the -.Em tank/users +.Sy tank/users file system. The permissions on -.Em tank/users +.Sy tank/users are also displayed. -.Bd -literal -# zfs unallow staff snapshot tank/users -# zfs allow tank/users +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm unallow Ar staff Sy snapshot Ar tank/users +.No # Nm zfs Cm allow Ar tank/users ---- Permissions on tank/users --------------------------------------- Permission sets: @pset create,destroy,mount,snapshot Local+Descendent permissions: group staff @pset .Ed -.It Sy Example 22 No Showing the differences between a snapshot and a ZFS Dataset +. +.It Sy Example 22 : No Showing the differences between a snapshot and a ZFS Dataset The following example shows how to see what has changed between a prior snapshot of a ZFS dataset and its current state. The .Fl F option is used to indicate type information for the files affected. -.Bd -literal -# zfs diff -F tank/test@before tank/test +.Bd -literal -compact -offset Ds +.No # Nm zfs Cm diff Fl F Ar tank/test@before tank/test M / /tank/test/ M F /tank/test/linked (+1) R F /tank/test/oldname -> /tank/test/newname @@ -670,57 +668,55 @@ R F /tank/test/oldname -> /tank/test/newname + F /tank/test/created M F /tank/test/modified .Ed -.It Sy Example 23 No Creating a bookmark +. +.It Sy Example 23 : No Creating a bookmark The following example create a bookmark to a snapshot. This bookmark can then be used instead of snapshot in send streams. -.Bd -literal -# zfs bookmark rpool@snapshot rpool#bookmark -.Ed -.It Sy Example 24 No Setting sharesmb Property Options on a ZFS File System +.Dl # Nm zfs Cm bookmark Ar rpool Ns @ Ns Ar snapshot rpool Ns # Ns Ar bookmark +. +.It Sy Example 24 : No Setting Sy sharesmb No Property Options on a ZFS File System The following example show how to share SMB filesystem through ZFS. -Note that that a user and his/her password must be given. -.Bd -literal -# smbmount //127.0.0.1/share_tmp /mnt/tmp \\ - -o user=workgroup/turbo,password=obrut,uid=1000 -.Ed +Note that a user and their password must be given. +.Dl # Nm smbmount Ar //127.0.0.1/share_tmp /mnt/tmp Fl o No user=workgroup/turbo,password=obrut,uid=1000 .Pp Minimal -.Em /etc/samba/smb.conf -configuration required: +.Pa /etc/samba/smb.conf +configuration is required, as follows. .Pp -Samba will need to listen to 'localhost' (127.0.0.1) for the ZFS utilities to +Samba will need to bind to the loopback interface for the ZFS utilities to communicate with Samba. This is the default behavior for most Linux distributions. .Pp Samba must be able to authenticate a user. -This can be done in a number of ways, depending on if using the system password file, LDAP or the Samba -specific smbpasswd file. -How to do this is outside the scope of this manual. -Please refer to the +This can be done in a number of ways +.Pq Xr passwd 5 , LDAP , Xr smbpasswd 5 , &c.\& . +How to do this is outside the scope of this document – refer to .Xr smb.conf 5 -man page for more information. +for more information. .Pp See the -.Sy USERSHARE section -of the -.Xr smb.conf 5 -man page for all configuration options in case you need to modify any options -to the share afterwards. +.Sx USERSHARES +section for all configuration options, +in case you need to modify any options of the share afterwards. Do note that any changes done with the .Xr net 8 -command will be undone if the share is ever unshared (such as at a reboot etc). +command will be undone if the share is ever unshared (like via a reboot). .El +. .Sh ENVIRONMENT VARIABLES .Bl -tag -width "ZFS_MOUNT_HELPER" -.It Ev ZFS_MOUNT_HELPER +.It Sy ZFS_MOUNT_HELPER Cause -.Nm zfs mount +.Nm zfs Cm mount to use -.Em /bin/mount -to mount zfs datasets. This option is provided for backwards compatibility with older zfs versions. +.Xr mount 8 +to mount ZFS datasets. +This option is provided for backwards compatibility with older ZFS versions. .El +. .Sh INTERFACE STABILITY .Sy Committed . +. .Sh SEE ALSO .Xr attr 1 , .Xr gzip 1 , diff --git a/sys/contrib/openzfs/man/man8/zfs_ids_to_path.8 b/sys/contrib/openzfs/man/man8/zfs_ids_to_path.8 index 9d6a4976efa..d5b74678b29 100644 --- a/sys/contrib/openzfs/man/man8/zfs_ids_to_path.8 +++ b/sys/contrib/openzfs/man/man8/zfs_ids_to_path.8 @@ -18,11 +18,12 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2020 by Delphix. All rights reserved. +.\" .Dd April 17, 2020 .Dt ZFS_IDS_TO_PATH 8 .Os +. .Sh NAME .Nm zfs_ids_to_path .Nd convert objset and object ids to names and paths @@ -30,21 +31,21 @@ .Nm .Op Fl v .Ar pool -.Ar objset id -.Ar object id -.Nm +.Ar objset-id +.Ar object-id +. .Sh DESCRIPTION -.Pp -.LP The .Sy zfs_ids_to_path -utility converts a provided objset and object id into a path to the file that -those ids refer to. +utility converts a provided objset and object ids +into a path to the file they refer to. .Bl -tag -width "-D" .It Fl v Verbose. -Print the dataset name and the file path within the dataset separately. This -will work correctly even if the dataset is not mounted. +Print the dataset name and the file path within the dataset separately. +This will work correctly even if the dataset is not mounted. +.El +. .Sh SEE ALSO -.Xr zfs 8 , -.Xr zdb 8 +.Xr zdb 8 , +.Xr zfs 8 diff --git a/sys/contrib/openzfs/man/man8/zfsconcepts.8 b/sys/contrib/openzfs/man/man8/zfsconcepts.8 index 8e0e6867878..3403d53bf8e 100644 --- a/sys/contrib/openzfs/man/man8/zfsconcepts.8 +++ b/sys/contrib/openzfs/man/man8/zfsconcepts.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -33,9 +32,11 @@ .Dd June 30, 2019 .Dt ZFSCONCEPTS 8 .Os +. .Sh NAME .Nm zfsconcepts -.Nd An overview of ZFS concepts. +.Nd overview of ZFS concepts +. .Sh DESCRIPTION .Ss ZFS File System Hierarchy A ZFS storage pool is a logical collection of devices that provide space for @@ -77,15 +78,15 @@ property. .Ss Bookmarks A bookmark is like a snapshot, a read-only copy of a file system or volume. Bookmarks can be created extremely quickly, compared to snapshots, and they -consume no additional space within the pool. Bookmarks can also have arbitrary -names, much like snapshots. +consume no additional space within the pool. +Bookmarks can also have arbitrary names, much like snapshots. .Pp -Unlike snapshots, bookmarks can not be accessed through the filesystem in any -way. From a storage standpoint a bookmark just provides a way to reference -when a snapshot was created as a distinct object. Bookmarks are initially -tied to a snapshot, not the filesystem or volume, and they will survive if the -snapshot itself is destroyed. Since they are very light weight there's little -incentive to destroy them. +Unlike snapshots, bookmarks can not be accessed through the filesystem in any way. +From a storage standpoint a bookmark just provides a way to reference +when a snapshot was created as a distinct object. +Bookmarks are initially tied to a snapshot, not the filesystem or volume, +and they will survive if the snapshot itself is destroyed. +Since they are very light weight there's little incentive to destroy them. .Ss Clones A clone is a writable volume or file system whose initial contents are the same as another dataset. @@ -162,37 +163,44 @@ If needed, ZFS file systems can also be managed with traditional tools If a file system's mount point is set to .Sy legacy , ZFS makes no attempt to manage the file system, and the administrator is -responsible for mounting and unmounting the file system. Because pools must +responsible for mounting and unmounting the file system. +Because pools must be imported before a legacy mount can succeed, administrators should ensure that legacy mounts are only attempted after the zpool import process -finishes at boot time. For example, on machines using systemd, the mount -option +finishes at boot time. +For example, on machines using systemd, the mount option .Pp .Nm x-systemd.requires=zfs-import.target .Pp will ensure that the zfs-import completes before systemd attempts mounting -the filesystem. See systemd.mount(5) for details. +the filesystem. +See +.Xr systemd.mount 5 +for details. .Ss Deduplication Deduplication is the process for removing redundant data at the block level, -reducing the total amount of data stored. If a file system has the +reducing the total amount of data stored. +If a file system has the .Sy dedup -property enabled, duplicate data blocks are removed synchronously. The result +property enabled, duplicate data blocks are removed synchronously. +The result is that only unique data is stored and common components are shared among files. .Pp -Deduplicating data is a very resource-intensive operation. It is generally -recommended that you have at least 1.25 GiB of RAM per 1 TiB of storage when -you enable deduplication. Calculating the exact requirement depends heavily +Deduplicating data is a very resource-intensive operation. +It is generally recommended that you have at least 1.25 GiB of RAM +per 1 TiB of storage when you enable deduplication. +Calculating the exact requirement depends heavily on the type of data stored in the pool. .Pp Enabling deduplication on an improperly-designed system can result in -performance issues (slow IO and administrative operations). It can potentially -lead to problems importing a pool due to memory exhaustion. Deduplication -can consume significant processing power (CPU) and memory as well as generate -additional disk IO. +performance issues (slow IO and administrative operations). +It can potentially lead to problems importing a pool due to memory exhaustion. +Deduplication can consume significant processing power (CPU) and memory as well +as generate additional disk IO. .Pp Before creating a pool with deduplication enabled, ensure that you have planned your hardware requirements appropriately and implemented appropriate recovery -practices, such as regular backups. As an alternative to deduplication -consider using -.Sy compression=on , -as a less resource-intensive alternative. +practices, such as regular backups. +Consider using the +.Sy compression +property as a less resource-intensive alternative. diff --git a/sys/contrib/openzfs/man/man8/zfsprops.8 b/sys/contrib/openzfs/man/man8/zfsprops.8 index 0255ac5c607..1b985c98e24 100644 --- a/sys/contrib/openzfs/man/man8/zfsprops.8 +++ b/sys/contrib/openzfs/man/man8/zfsprops.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2011 Joshua M. Clulow .\" Copyright (c) 2011, 2019 by Delphix. All rights reserved. @@ -38,12 +37,14 @@ .\" Copyright 2019 Joyent, Inc. .\" Copyright (c) 2019, Kjeld Schouten-Lebbing .\" -.Dd September 1, 2020 +.Dd May 24, 2021 .Dt ZFSPROPS 8 .Os +. .Sh NAME .Nm zfsprops -.Nd Native properties and user-defined of ZFS datasets. +.Nd native and user-defined properties of ZFS datasets +. .Sh DESCRIPTION Properties are divided into two types, native properties and user-defined .Po or @@ -57,6 +58,7 @@ datasets in a way that is meaningful in your environment. For more information about user properties, see the .Sx User Properties section, below. +. .Ss Native Properties Every dataset has a set of properties that export statistics about the dataset as well as control various behaviors. @@ -118,11 +120,12 @@ Compression can be turned on by running: The default value is .Sy off . .It Sy createtxg -The transaction group (txg) in which the dataset was created. Bookmarks have -the same +The transaction group (txg) in which the dataset was created. +Bookmarks have the same .Sy createtxg -as the snapshot they are initially tied to. This property is suitable for -ordering a list of snapshots, e.g. for incremental send and receive. +as the snapshot they are initially tied to. +This property is suitable for ordering a list of snapshots, +e.g. for incremental send and receive. .It Sy creation The time this dataset was created. .It Sy clones @@ -153,7 +156,8 @@ Otherwise, the property is .Sy off . .It Sy encryptionroot For encrypted datasets, indicates where the dataset is currently inheriting its -encryption key from. Loading or unloading a key for the +encryption key from. +Loading or unloading a key for the .Sy encryptionroot will implicitly load / unload the key for any inheriting datasets (see .Nm zfs Cm load-key @@ -161,8 +165,9 @@ and .Nm zfs Cm unload-key for details). Clones will always share an -encryption key with their origin. See the -.Em Encryption +encryption key with their origin. +See the +.Sx Encryption section of .Xr zfs-load-key 8 for details. @@ -173,8 +178,8 @@ This value is only available when a .Sy filesystem_limit has been set somewhere in the tree under which the dataset resides. .It Sy keystatus -Indicates if an encryption key is currently loaded into ZFS. The possible -values are +Indicates if an encryption key is currently loaded into ZFS. +The possible values are .Sy none , .Sy available , and @@ -185,8 +190,9 @@ and .Nm zfs Cm unload-key . .It Sy guid The 64 bit GUID of this dataset or bookmark which does not change over its -entire lifetime. When a snapshot is sent to another pool, the received -snapshot has the same GUID. Thus, the +entire lifetime. +When a snapshot is sent to another pool, the received snapshot has the same GUID. +Thus, the .Sy guid is suitable to identify a snapshot across pools. .It Sy logicalreferenced @@ -230,10 +236,9 @@ This property can be either or .Sy no . .It Sy objsetid -A unique identifier for this dataset within the pool. Unlike the dataset's -.Sy guid -, the -.Sy objsetid +A unique identifier for this dataset within the pool. +Unlike the dataset's +.Sy guid , No the Sy objsetid of a dataset is not transferred to other pools when the snapshot is copied with a send/receive operation. The @@ -247,11 +252,11 @@ See also the property. .It Sy receive_resume_token For filesystems or volumes which have saved partially-completed state from -.Sy zfs receive -s , +.Nm zfs Cm receive Fl s , this opaque token can be provided to -.Sy zfs send -t +.Nm zfs Cm send Fl t to resume and complete the -.Sy zfs receive . +.Nm zfs Cm receive . .It Sy redact_snaps For bookmarks, this is the list of snapshot guids the bookmark contains a redaction list for. @@ -297,7 +302,7 @@ greater of its space used and its reservation. .Pp The used space of a snapshot .Po see the -.Em Snapshots +.Sx Snapshots section of .Xr zfsconcepts 8 .Pc @@ -323,7 +328,7 @@ Pending changes are generally accounted for within a few seconds. Committing a change to a disk using .Xr fsync 2 or -.Dv O_SYNC +.Sy O_SYNC does not necessarily guarantee that the space usage information is updated immediately. .It Sy usedby* @@ -365,17 +370,15 @@ dataset's snapshots were destroyed. Note that this is not simply the sum of the snapshots' .Sy used properties because space can be shared by multiple snapshots. -.It Sy userused Ns @ Ns Em user +.It Sy userused Ns @ Ns Ar user The amount of space consumed by the specified user in this dataset. Space is charged to the owner of each file, as displayed by .Nm ls Fl l . The amount of space charged is displayed by -.Nm du -and -.Nm ls Fl s . +.Nm du No and Nm ls Fl s . See the .Nm zfs Cm userspace -subcommand for more information. +command for more information. .Pp Unprivileged users can access only their own space usage. The root user, or a user who has been granted the @@ -385,66 +388,60 @@ privilege with can access everyone's usage. .Pp The -.Sy userused Ns @ Ns Em ... +.Sy userused Ns @ Ns Ar ... properties are not displayed by .Nm zfs Cm get Sy all . -The user's name must be appended after the @ symbol, using one of the following -forms: -.Bl -bullet -width "" +The user's name must be appended after the +.Sy @ +symbol, using one of the following forms: +.Bl -bullet -compact -offset 4n .It -.Em POSIX name -.Po for example, -.Sy joe -.Pc +POSIX name +.Pq Qq joe .It -.Em POSIX numeric ID -.Po for example, -.Sy 789 -.Pc +POSIX numeric ID +.Pq Qq 789 .It -.Em SID name -.Po for example, -.Sy joe.smith@mydomain -.Pc +SID name +.Pq Qq joe.smith@mydomain .It -.Em SID numeric ID -.Po for example, -.Sy S-1-123-456-789 -.Pc +SID numeric ID +.Pq Qq S-1-123-456-789 .El .Pp Files created on Linux always have POSIX owners. -.It Sy userobjused Ns @ Ns Em user +.It Sy userobjused Ns @ Ns Ar user The .Sy userobjused property is similar to .Sy userused -but instead it counts the number of objects consumed by a user. This property -counts all objects allocated on behalf of the user, it may differ from the -results of system tools such as +but instead it counts the number of objects consumed by a user. +This property counts all objects allocated on behalf of the user, +it may differ from the results of system tools such as .Nm df Fl i . .Pp When the property -.Sy xattr=on +.Sy xattr Ns = Ns Sy on is set on a file system additional objects will be created per-file to store -extended attributes. These additional objects are reflected in the +extended attributes. +These additional objects are reflected in the .Sy userobjused value and are counted against the user's .Sy userobjquota . When a file system is configured to use -.Sy xattr=sa +.Sy xattr Ns = Ns Sy sa no additional internal objects are normally required. .It Sy userrefs This property is set to the number of user holds on this snapshot. User holds are set by using the .Nm zfs Cm hold command. -.It Sy groupused Ns @ Ns Em group +.It Sy groupused Ns @ Ns Ar group The amount of space consumed by the specified group in this dataset. Space is charged to the group of each file, as displayed by .Nm ls Fl l . See the -.Sy userused Ns @ Ns Em user +.Sy userused Ns @ Ns Ar user property for more information. .Pp Unprivileged users can only access their own groups' space usage. @@ -453,11 +450,12 @@ The root user, or a user who has been granted the privilege with .Nm zfs Cm allow , can access all groups' usage. -.It Sy groupobjused Ns @ Ns Em group +.It Sy groupobjused Ns @ Ns Ar group The number of objects consumed by the specified group in this dataset. Multiple objects may be charged to the group for each file when extended -attributes are in use. See the -.Sy userobjused Ns @ Ns Em user +attributes are in use. +See the +.Sy userobjused Ns @ Ns Ar user property for more information. .Pp Unprivileged users can only access their own groups' space usage. @@ -466,25 +464,28 @@ The root user, or a user who has been granted the privilege with .Nm zfs Cm allow , can access all groups' usage. -.It Sy projectused Ns @ Ns Em project -The amount of space consumed by the specified project in this dataset. Project -is identified via the project identifier (ID) that is object-based numeral -attribute. An object can inherit the project ID from its parent object (if the +.It Sy projectused Ns @ Ns Ar project +The amount of space consumed by the specified project in this dataset. +Project is identified via the project identifier (ID) that is object-based +numeral attribute. +An object can inherit the project ID from its parent object (if the parent has the flag of inherit project ID that can be set and changed via .Nm chattr Fl /+P or .Nm zfs project Fl s ) -when being created. The privileged user can set and change object's project +when being created. +The privileged user can set and change object's project ID via .Nm chattr Fl p or .Nm zfs project Fl s -anytime. Space is charged to the project of each file, as displayed by +anytime. +Space is charged to the project of each file, as displayed by .Nm lsattr Fl p or .Nm zfs project . See the -.Sy userused Ns @ Ns Em user +.Sy userused Ns @ Ns Ar user property for more information. .Pp The root user, or a user who has been granted the @@ -492,23 +493,25 @@ The root user, or a user who has been granted the privilege with .Nm zfs allow , can access all projects' usage. -.It Sy projectobjused Ns @ Ns Em project +.It Sy projectobjused Ns @ Ns Ar project The .Sy projectobjused is similar to .Sy projectused -but instead it counts the number of objects consumed by project. When the -property -.Sy xattr=on +but instead it counts the number of objects consumed by project. +When the property +.Sy xattr Ns = Ns Sy on is set on a fileset, ZFS will create additional objects per-file to store -extended attributes. These additional objects are reflected in the +extended attributes. +These additional objects are reflected in the .Sy projectobjused value and are counted against the project's .Sy projectobjquota . When a filesystem is configured to use -.Sy xattr=sa -no additional internal objects are required. See the -.Sy userobjused Ns @ Ns Em user +.Sy xattr Ns = Ns Sy sa +no additional internal objects are required. +See the +.Sy userobjused Ns @ Ns Ar user property for more information. .Pp The root user, or a user who has been granted the @@ -534,7 +537,7 @@ The amount of space .Sy referenced by this dataset, that was written since the previous snapshot .Pq i.e. that is not referenced by the previous snapshot . -.It Sy written Ns @ Ns Em snapshot +.It Sy written Ns @ Ns Ar snapshot The amount of .Sy referenced space written to this dataset since the specified snapshot. @@ -542,17 +545,15 @@ This is the space that is referenced by this dataset but was not referenced by the specified snapshot. .Pp The -.Em snapshot +.Ar snapshot may be specified as a short snapshot name -.Po just the part after the -.Sy @ -.Pc , +.Pq just the part after the Sy @ , in which case it will be interpreted as a snapshot in the same filesystem as this dataset. The -.Em snapshot +.Ar snapshot may be a full snapshot name -.Po Em filesystem Ns @ Ns Em snapshot Pc , +.Pq Ar filesystem Ns @ Ns Ar snapshot , which for clones may be a snapshot in the origin's filesystem .Pq or the origin of the origin's filesystem, etc. .El @@ -565,7 +566,7 @@ dataset. .Sy restricted Ns | Ns Sy passthrough Ns | Ns Sy passthrough-x .Xc Controls how ACEs are inherited when files and directories are created. -.Bl -tag -width "passthrough-x" +.Bl -tag -compact -offset 4n -width "passthrough-x" .It Sy discard does not inherit any ACEs. .It Sy noallow @@ -584,10 +585,7 @@ inherits all inheritable ACEs without any modifications. same meaning as .Sy passthrough , except that the -.Sy owner@ , -.Sy group@ , -and -.Sy everyone@ +.Sy owner@ , group@ , No and Sy everyone@ ACEs inherit the execute permission only if the file creation mode also requests the execute bit. .El @@ -606,8 +604,8 @@ property does not apply to POSIX ACLs. .Sy passthrough Ns | Ns Sy restricted Ns .Xc Controls how an ACL is modified during chmod(2) and how inherited ACEs -are modified by the file creation mode. -.Bl -tag -width "passthrough" +are modified by the file creation mode: +.Bl -tag -compact -offset 4n -width "passthrough" .It Sy discard default, deletes all .Sy ACEs @@ -622,41 +620,30 @@ entries found in the such that they are no greater than the group permissions specified by .Xr chmod 2 . .It Sy passthrough -indicates that no changes are made to the -.Tn ACL -other than creating or updating the necessary -.Tn ACL -entries to represent the new mode of the file or directory. +indicates that no changes are made to the ACL other than creating or updating +the necessary ACL entries to represent the new mode of the file or directory. .It Sy restricted will cause the .Xr chmod 2 operation to return an error when used on any file or directory which has -a non-trivial -.Tn ACL -whose entries can not be represented by a mode. +a non-trivial ACL whose entries can not be represented by a mode. .Xr chmod 2 is required to change the set user ID, set group ID, or sticky bits on a file -or directory, as they do not have equivalent -.Tn ACL -entries. +or directory, as they do not have equivalent ACL entries. In order to use .Xr chmod 2 -on a file or directory with a non-trivial -.Tn ACL -when +on a file or directory with a non-trivial ACL when .Sy aclmode is set to .Sy restricted , -you must first remove all -.Tn ACL -entries which do not represent the current mode. +you must first remove all ACL entries which do not represent the current mode. .El .It Sy acltype Ns = Ns Sy off Ns | Ns Sy nfsv4 Ns | Ns Sy posix Controls whether ACLs are enabled and if so what type of ACL to use. When this property is set to a type of ACL not supported by the current platform, the behavior is the same as if it were set to .Sy off . -.Bl -tag -width "posixacl" +.Bl -tag -compact -offset 4n -width "posixacl" .It Sy off default on Linux, when a file system has the .Sy acltype @@ -665,17 +652,20 @@ property set to off then ACLs are disabled. an alias for .Sy off .It Sy nfsv4 -default on FreeBSD, indicates that NFSv4-style ZFS ACLs should be used. +default on +.Fx , +indicates that NFSv4-style ZFS ACLs should be used. These ACLs can be managed with the .Xr getfacl 1 and -.Xr setfacl 1 -commands on FreeBSD. The +.Xr setfacl 1 . +The .Sy nfsv4 ZFS ACL type is not yet supported on Linux. .It Sy posix -indicates POSIX ACLs should be used. POSIX ACLs are specific to Linux and are -not functional on other platforms. POSIX ACLs are stored as an extended +indicates POSIX ACLs should be used. +POSIX ACLs are specific to Linux and are not functional on other platforms. +POSIX ACLs are stored as an extended attribute and therefore will not overwrite any existing NFSv4 ACLs which may be set. .It Sy posixacl @@ -686,19 +676,22 @@ an alias for To obtain the best performance when setting .Sy posix users are strongly encouraged to set the -.Sy xattr=sa -property. This will result in the POSIX ACL being stored more efficiently on -disk. But as a consequence, all new extended attributes will only be +.Sy xattr Ns = Ns Sy sa +property. +This will result in the POSIX ACL being stored more efficiently on disk. +But as a consequence, all new extended attributes will only be accessible from OpenZFS implementations which support the -.Sy xattr=sa -property. See the +.Sy xattr Ns = Ns Sy sa +property. +See the .Sy xattr property for more details. .It Sy atime Ns = Ns Sy on Ns | Ns Sy off Controls whether the access time for files is updated when they are read. Turning this property off avoids producing write traffic when reading files and can result in significant performance gains, though it might confuse mailers -and other similar utilities. The values +and other similar utilities. +The values .Sy on and .Sy off @@ -706,7 +699,8 @@ are equivalent to the .Sy atime and .Sy noatime -mount options. The default value is +mount options. +The default value is .Sy on . See also .Sy relatime @@ -768,7 +762,7 @@ not only disables integrity but also disables maintaining parity for user data. This setting is used internally by a dump device residing on a RAID-Z pool and should not be used by any other dataset. Disabling checksums is -.Sy NOT +.Em NOT a recommended practice. .Pp The @@ -777,7 +771,8 @@ The and .Sy edonr checksum algorithms require enabling the appropriate features on the pool. -FreeBSD does not support the +.Fx +does not support the .Sy edonr algorithm. .Pp @@ -788,8 +783,8 @@ for more information on these algorithms. Changing this property affects only newly-written data. .It Xo .Sy compression Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Sy gzip Ns | Ns -.Sy gzip- Ns Em N Ns | Ns Sy lz4 Ns | Ns Sy lzjb Ns | Ns Sy zle Ns | Ns Sy zstd Ns | Ns -.Sy zstd- Ns Em N Ns | Ns Sy zstd-fast Ns | Ns Sy zstd-fast- Ns Em N +.Sy gzip- Ns Ar N Ns | Ns Sy lz4 Ns | Ns Sy lzjb Ns | Ns Sy zle Ns | Ns Sy zstd Ns | Ns +.Sy zstd- Ns Ar N Ns | Ns Sy zstd-fast Ns | Ns Sy zstd-fast- Ns Ar N .Xc Controls the compression algorithm used for this dataset. .Pp @@ -841,9 +836,9 @@ command. You can specify the .Sy gzip level by using the value -.Sy gzip- Ns Em N , +.Sy gzip- Ns Ar N , where -.Em N +.Ar N is an integer from 1 .Pq fastest to 9 @@ -858,13 +853,13 @@ is equivalent to .Pp The .Sy zstd -compression algorithm provides both high compression ratios and good -performance. You can specify the +compression algorithm provides both high compression ratios and good performance. +You can specify the .Sy zstd level by using the value -.Sy zstd- Ns Em N , +.Sy zstd- Ns Ar N , where -.Em N +.Ar N is an integer from 1 .Pq fastest to 19 @@ -876,14 +871,16 @@ is equivalent to Faster speeds at the cost of the compression ratio can be requested by setting a negative .Sy zstd -level. This is done using -.Sy zstd-fast- Ns Em N , +level. +This is done using +.Sy zstd-fast- Ns Ar N , where -.Em N +.Ar N is an integer in [1-9,10,20,30,...,100,500,1000] which maps to a negative .Sy zstd -level. The lower the level the faster the compression - 1000 provides -the fastest compression and lowest compression ratio. +level. +The lower the level the faster the compression - +.Ar 1000 No provides the fastest compression and lowest compression ratio. .Sy zstd-fast is equivalent to .Sy zstd-fast-1 . @@ -899,43 +896,49 @@ Changing this property affects only newly-written data. When any setting except .Sy off is selected, compression will explicitly check for blocks consisting of only -zeroes (the NUL byte). When a zero-filled block is detected, it is stored as +zeroes (the NUL byte). +When a zero-filled block is detected, it is stored as a hole and not compressed using the indicated compression algorithm. .Pp Any block being compressed must be no larger than 7/8 of its original size after compression, otherwise the compression will not be considered worthwhile -and the block saved uncompressed. Note that when the logical block is less than +and the block saved uncompressed. +Note that when the logical block is less than 8 times the disk sector size this effectively reduces the necessary compression -ratio; for example 8k blocks on disks with 4k disk sectors must compress to 1/2 +ratio; for example, 8kB blocks on disks with 4kB disk sectors must compress to 1/2 or less of their original size. .It Xo .Sy context Ns = Ns Sy none Ns | Ns -.Em SELinux_User:SElinux_Role:Selinux_Type:Sensitivity_Level +.Ar SELinux-User : Ns Ar SElinux-Role : Ns Ar Selinux-Type : Ns Ar Sensitivity-Level .Xc This flag sets the SELinux context for all files in the file system under -a mount point for that file system. See +a mount point for that file system. +See .Xr selinux 8 for more information. .It Xo .Sy fscontext Ns = Ns Sy none Ns | Ns -.Em SELinux_User:SElinux_Role:Selinux_Type:Sensitivity_Level +.Ar SELinux-User : Ns Ar SElinux-Role : Ns Ar Selinux-Type : Ns Ar Sensitivity-Level .Xc This flag sets the SELinux context for the file system file system being -mounted. See +mounted. +See .Xr selinux 8 for more information. .It Xo .Sy defcontext Ns = Ns Sy none Ns | Ns -.Em SELinux_User:SElinux_Role:Selinux_Type:Sensitivity_Level +.Ar SELinux-User : Ns Ar SElinux-Role : Ns Ar Selinux-Type : Ns Ar Sensitivity-Level .Xc -This flag sets the SELinux default context for unlabeled files. See +This flag sets the SELinux default context for unlabeled files. +See .Xr selinux 8 for more information. .It Xo .Sy rootcontext Ns = Ns Sy none Ns | Ns -.Em SELinux_User:SElinux_Role:Selinux_Type:Sensitivity_Level +.Ar SELinux-User : Ns Ar SElinux-Role : Ns Ar Selinux-Type : Ns Ar Sensitivity-Level .Xc -This flag sets the SELinux context for the root inode of the file system. See +This flag sets the SELinux context for the root inode of the file system. +See .Xr selinux 8 for more information. .It Sy copies Ns = Ns Sy 1 Ns | Ns Sy 2 Ns | Ns Sy 3 @@ -953,16 +956,17 @@ Therefore, set this property at file system creation time by using the .Fl o Sy copies Ns = Ns Ar N option. .Pp -Remember that ZFS will not import a pool with a missing top-level vdev. Do -.Sy NOT +Remember that ZFS will not import a pool with a missing top-level vdev. +Do +.Em NOT create, for example a two-disk striped pool and set -.Sy copies=2 -on some datasets thinking you have setup redundancy for them. When a disk -fails you will not be able to import the pool and will have lost all of your -data. +.Sy copies Ns = Ns Ar 2 +on some datasets thinking you have setup redundancy for them. +When a disk fails you will not be able to import the pool +and will have lost all of your data. .Pp Encrypted datasets may not have -.Sy copies Ns = Ns Em 3 +.Sy copies Ns = Ns Ar 3 since the implementation stores some encryption metadata where the third copy would normally be. .It Sy devices Ns = Ns Sy on Ns | Ns Sy off @@ -980,33 +984,40 @@ and mount options. .It Xo .Sy dedup Ns = Ns Sy off Ns | Ns Sy on Ns | Ns Sy verify Ns | Ns -.Sy sha256[,verify] Ns | Ns Sy sha512[,verify] Ns | Ns Sy skein[,verify] Ns | Ns -.Sy edonr,verify +.Sy sha256 Ns Oo , Ns Sy verify Oc Ns | Ns Sy sha512 Ns Oo , Ns Sy verify Oc Ns | Ns Sy skein Ns Oo , Ns Sy verify Oc Ns | Ns +.Sy edonr , Ns Sy verify .Xc -Configures deduplication for a dataset. The default value is +Configures deduplication for a dataset. +The default value is .Sy off . The default deduplication checksum is .Sy sha256 -(this may change in the future). When +(this may change in the future). +When .Sy dedup is enabled, the checksum defined here overrides the .Sy checksum -property. Setting the value to +property. +Setting the value to .Sy verify has the same effect as the setting -.Sy sha256,verify. +.Sy sha256 , Ns Sy verify . .Pp If set to .Sy verify , ZFS will do a byte-to-byte comparison in case of two blocks having the same -signature to make sure the block contents are identical. Specifying +signature to make sure the block contents are identical. +Specifying .Sy verify is mandatory for the .Sy edonr algorithm. .Pp -Unless necessary, deduplication should NOT be enabled on a system. See the -.Em Deduplication +Unless necessary, deduplication should +.Em not +be enabled on a system. +See the +.Sx Deduplication section of .Xr zfsconcepts 8 . .It Xo @@ -1014,21 +1025,23 @@ section of .Sy 2k Ns | Ns Sy 4k Ns | Ns Sy 8k Ns | Ns Sy 16k .Xc Specifies a compatibility mode or literal value for the size of dnodes in the -file system. The default value is +file system. +The default value is .Sy legacy . Setting this property to a value other than -.Sy legacy -requires the large_dnode pool feature to be enabled. +.Sy legacy No requires the Sy large_dnode No pool feature to be enabled. .Pp Consider setting .Sy dnodesize to .Sy auto if the dataset uses the -.Sy xattr=sa -property setting and the workload makes heavy use of extended attributes. This +.Sy xattr Ns = Ns Sy sa +property setting and the workload makes heavy use of extended attributes. +This may be applicable to SELinux-enabled systems, Lustre servers, and Samba -servers, for example. Literal values are supported for cases where the optimal +servers, for example. +Literal values are supported for cases where the optimal size is known in advance and for performance testing. .Pp Leave @@ -1036,8 +1049,10 @@ Leave set to .Sy legacy if you need to receive a send stream of this dataset on a pool that doesn't -enable the large_dnode feature, or if you need to import this pool on a system -that doesn't support the large_dnode feature. +enable the +.Sy large_dnode +feature, or if you need to import this pool on a system that doesn't support the +.Sy large_dnode No feature. .Pp This property can also be referred to by its shortened column name, .Sy dnsize . @@ -1047,7 +1062,8 @@ This property can also be referred to by its shortened column name, .Sy aes-192-gcm Ns | Ns Sy aes-256-gcm .Xc Controls the encryption cipher suite (block cipher, key length, and mode) used -for this dataset. Requires the +for this dataset. +Requires the .Sy encryption feature to be enabled on the pool. Requires a @@ -1063,38 +1079,36 @@ In order to provide consistent data protection, encryption must be specified at dataset creation time and it cannot be changed afterwards. .Pp For more details and caveats about encryption see the -.Em Encryption +.Sx Encryption section of .Xr zfs-load-key 8 . .It Sy keyformat Ns = Ns Sy raw Ns | Ns Sy hex Ns | Ns Sy passphrase -Controls what format the user's encryption key will be provided as. This -property is only set when the dataset is encrypted. +Controls what format the user's encryption key will be provided as. +This property is only set when the dataset is encrypted. .Pp Raw keys and hex keys must be 32 bytes long (regardless of the chosen -encryption suite) and must be randomly generated. A raw key can be generated -with the following command: -.Bd -literal -# dd if=/dev/urandom of=/path/to/output/key bs=32 count=1 -.Ed +encryption suite) and must be randomly generated. +A raw key can be generated with the following command: +.Dl # Nm dd Sy if=/dev/urandom bs=32 count=1 Sy of= Ns Pa /path/to/output/key .Pp Passphrases must be between 8 and 512 bytes long and will be processed through PBKDF2 before being used (see the .Sy pbkdf2iters -property). Even though the -encryption suite cannot be changed after dataset creation, the keyformat can be -with +property). +Even though the encryption suite cannot be changed after dataset creation, +the keyformat can be with .Nm zfs Cm change-key . .It Xo -.Sy keylocation Ns = Ns Sy prompt Ns | Ns Sy file:// Ns Em +.Sy keylocation Ns = Ns Sy prompt Ns | Ns Sy file:// Ns Ar /absolute/file/path Ns | Ns Sy https:// Ns Ar address Ns | Ns Sy http:// Ns Ar address .Xc Controls where the user's encryption key will be loaded from by default for commands such as .Nm zfs Cm load-key and -.Nm zfs Cm mount Cm -l . -This property is only set for encrypted datasets which are encryption roots. If -unspecified, the default is -.Sy prompt. +.Nm zfs Cm mount Fl l . +This property is only set for encrypted datasets which are encryption roots. +If unspecified, the default is +.Sy prompt . .Pp Even though the encryption suite cannot be changed after dataset creation, the keylocation can be with either @@ -1106,24 +1120,45 @@ If is selected ZFS will ask for the key at the command prompt when it is required to access the encrypted data (see .Nm zfs Cm load-key -for details). This setting will also allow the key to be passed in via STDIN, +for details). +This setting will also allow the key to be passed in via the standard input stream, but users should be careful not to place keys which should be kept secret on -the command line. If a file URI is selected, the key will be loaded from the +the command line. +If a file URI is selected, the key will be loaded from the specified absolute file path. +If an HTTPS or HTTP URL is selected, it will be GETted using +.Xr fetch 3 , +libcurl, or nothing, depending on compile-time configuration and run-time availability. +The +.Sy SSL_CA_CERT_FILE +environment variable can be set to set the location +of the concatenated certificate store. +The +.Sy SSL_CA_CERT_PATH +environment variable can be set to override the location +of the directory containing the certificate authority bundle. +The +.Sy SSL_CLIENT_CERT_FILE +and +.Sy SSL_CLIENT_KEY_FILE +environment variables can be set to configure the path +to the client certificate and its key. .It Sy pbkdf2iters Ns = Ns Ar iterations Controls the number of PBKDF2 iterations that a .Sy passphrase encryption key should be run through when processing it into an encryption key. This property is only defined when encryption is enabled and a keyformat of .Sy passphrase -is selected. The goal of PBKDF2 is to significantly increase the -computational difficulty needed to brute force a user's passphrase. This is -accomplished by forcing the attacker to run each passphrase through a +is selected. +The goal of PBKDF2 is to significantly increase the +computational difficulty needed to brute force a user's passphrase. +This is accomplished by forcing the attacker to run each passphrase through a computationally expensive hashing function many times before they arrive at the -resulting key. A user who actually knows the passphrase will only have to pay -this cost once. As CPUs become better at processing, this number should be -raised to ensure that a brute force attack is still not possible. The current -default is +resulting key. +A user who actually knows the passphrase will only have to pay this cost once. +As CPUs become better at processing, this number should be +raised to ensure that a brute force attack is still not possible. +The current default is .Sy 350000 and the minimum is .Sy 100000 . @@ -1142,7 +1177,7 @@ are equivalent to the and .Sy noexec mount options. -.It Sy filesystem_limit Ns = Ns Em count Ns | Ns Sy none +.It Sy filesystem_limit Ns = Ns Ar count Ns | Ns Sy none Limits the number of filesystems and volumes that can exist under this point in the dataset tree. The limit is not enforced if the user is allowed to change the limit. @@ -1159,22 +1194,25 @@ This feature must be enabled to be used .Po see .Xr zpool-features 5 .Pc . -.It Sy special_small_blocks Ns = Ns Em size +.It Sy special_small_blocks Ns = Ns Ar size This value represents the threshold block size for including small file -blocks into the special allocation class. Blocks smaller than or equal to this +blocks into the special allocation class. +Blocks smaller than or equal to this value will be assigned to the special allocation class while greater blocks -will be assigned to the regular class. Valid values are zero or a power of two -from 512B up to 1M. The default size is 0 which means no small file blocks +will be assigned to the regular class. +Valid values are zero or a power of two from 512B up to 1M. +The default size is 0 which means no small file blocks will be allocated in the special class. .Pp Before setting this property, a special class vdev must be added to the -pool. See -.Xr zpool 8 +pool. +See +.Xr zpoolconcepts 8 for more details on the special allocation class. .It Sy mountpoint Ns = Ns Pa path Ns | Ns Sy none Ns | Ns Sy legacy Controls the mount point used for this file system. See the -.Em Mount Points +.Sx Mount Points section of .Xr zfsconcepts 8 for more information on how this property is used. @@ -1197,19 +1235,17 @@ location. .It Sy nbmand Ns = Ns Sy on Ns | Ns Sy off Controls whether the file system should be mounted with .Sy nbmand -.Pq Non Blocking mandatory locks . +.Pq Non-blocking mandatory locks . This is used for SMB clients. Changes to this property only take effect when the file system is umounted and remounted. -See -.Xr mount 8 -for more information on -.Sy nbmand -mounts. This property is not used on Linux. +Support for these locks is scarce and not described by POSIX. .It Sy overlay Ns = Ns Sy on Ns | Ns Sy off Allow mounting on a busy directory or a directory which already contains files or directories. -This is the default mount behavior for Linux and FreeBSD file systems. +This is the default mount behavior for Linux and +.Fx +file systems. On these platforms the property is .Sy on by default. @@ -1230,7 +1266,7 @@ If this property is set to then only metadata is cached. The default value is .Sy all . -.It Sy quota Ns = Ns Em size Ns | Ns Sy none +.It Sy quota Ns = Ns Ar size Ns | Ns Sy none Limits the amount of space a dataset and its descendents can consume. This property enforces a hard limit on the amount of space used. This includes all space consumed by descendents, including file systems and @@ -1241,7 +1277,7 @@ override the ancestor's quota, but rather imposes an additional limit. Quotas cannot be set on volumes, as the .Sy volsize property acts as an implicit quota. -.It Sy snapshot_limit Ns = Ns Em count Ns | Ns Sy none +.It Sy snapshot_limit Ns = Ns Ar count Ns | Ns Sy none Limits the number of snapshots that can be created on a dataset and its descendents. Setting a @@ -1258,10 +1294,10 @@ This feature must be enabled to be used .Po see .Xr zpool-features 5 .Pc . -.It Sy userquota@ Ns Em user Ns = Ns Em size Ns | Ns Sy none +.It Sy userquota@ Ns Ar user Ns = Ns Ar size Ns | Ns Sy none Limits the amount of space consumed by the specified user. User space consumption is identified by the -.Sy userspace@ Ns Em user +.Sy userspace@ Ns Ar user property. .Pp Enforcement of user quotas may be delayed by several seconds. @@ -1271,7 +1307,7 @@ that they are over quota and begins to refuse additional writes with the error message. See the .Nm zfs Cm userspace -subcommand for more information. +command for more information. .Pp Unprivileged users can only access their own groups' space usage. The root user, or a user who has been granted the @@ -1283,48 +1319,41 @@ can get and set everyone's quota. This property is not available on volumes, on file systems before version 4, or on pools before version 15. The -.Sy userquota@ Ns Em ... +.Sy userquota@ Ns Ar ... properties are not displayed by .Nm zfs Cm get Sy all . The user's name must be appended after the .Sy @ symbol, using one of the following forms: -.Bl -bullet +.Bl -bullet -compact -offset 4n .It -.Em POSIX name -.Po for example, -.Sy joe -.Pc +POSIX name +.Pq Qq joe .It -.Em POSIX numeric ID -.Po for example, -.Sy 789 -.Pc +POSIX numeric ID +.Pq Qq 789 .It -.Em SID name -.Po for example, -.Sy joe.smith@mydomain -.Pc +SID name +.Pq Qq joe.smith@mydomain .It -.Em SID numeric ID -.Po for example, -.Sy S-1-123-456-789 -.Pc +SID numeric ID +.Pq Qq S-1-123-456-789 .El .Pp Files created on Linux always have POSIX owners. -.It Sy userobjquota@ Ns Em user Ns = Ns Em size Ns | Ns Sy none +.It Sy userobjquota@ Ns Ar user Ns = Ns Ar size Ns | Ns Sy none The .Sy userobjquota is similar to .Sy userquota -but it limits the number of objects a user can create. Please refer to +but it limits the number of objects a user can create. +Please refer to .Sy userobjused for more information about how objects are counted. -.It Sy groupquota@ Ns Em group Ns = Ns Em size Ns | Ns Sy none +.It Sy groupquota@ Ns Ar group Ns = Ns Ar size Ns | Ns Sy none Limits the amount of space consumed by the specified group. Group space consumption is identified by the -.Sy groupused@ Ns Em group +.Sy groupused@ Ns Ar group property. .Pp Unprivileged users can access only their own groups' space usage. @@ -1333,19 +1362,21 @@ The root user, or a user who has been granted the privilege with .Nm zfs Cm allow , can get and set all groups' quotas. -.It Sy groupobjquota@ Ns Em group Ns = Ns Em size Ns | Ns Sy none +.It Sy groupobjquota@ Ns Ar group Ns = Ns Ar size Ns | Ns Sy none The .Sy groupobjquota is similar to .Sy groupquota -but it limits number of objects a group can consume. Please refer to +but it limits number of objects a group can consume. +Please refer to .Sy userobjused for more information about how objects are counted. -.It Sy projectquota@ Ns Em project Ns = Ns Em size Ns | Ns Sy none -Limits the amount of space consumed by the specified project. Project -space consumption is identified by the -.Sy projectused@ Ns Em project -property. Please refer to +.It Sy projectquota@ Ns Ar project Ns = Ns Ar size Ns | Ns Sy none +Limits the amount of space consumed by the specified project. +Project space consumption is identified by the +.Sy projectused@ Ns Ar project +property. +Please refer to .Sy projectused for more information about how project is identified and set/changed. .Pp @@ -1354,12 +1385,13 @@ The root user, or a user who has been granted the privilege with .Nm zfs allow , can access all projects' quota. -.It Sy projectobjquota@ Ns Em project Ns = Ns Em size Ns | Ns Sy none +.It Sy projectobjquota@ Ns Ar project Ns = Ns Ar size Ns | Ns Sy none The .Sy projectobjquota is similar to .Sy projectquota -but it limits number of objects a project can consume. Please refer to +but it limits number of objects a project can consume. +Please refer to .Sy userobjused for more information about how objects are counted. .It Sy readonly Ns = Ns Sy on Ns | Ns Sy off @@ -1378,7 +1410,7 @@ mount options. .Pp This property can also be referred to by its shortened column name, .Sy rdonly . -.It Sy recordsize Ns = Ns Em size +.It Sy recordsize Ns = Ns Ar size Specifies a suggested block size for files in the file system. This property is designed solely for use with database workloads that access files in fixed-size records. @@ -1394,11 +1426,14 @@ significant performance gains. Use of this property for general purpose file systems is strongly discouraged, and may adversely affect performance. .Pp -The size specified must be a power of two greater than or equal to 512 and less -than or equal to 128 Kbytes. +The size specified must be a power of two greater than or equal to +.Ar 512B +and less than or equal to +.Ar 128kB . If the .Sy large_blocks -feature is enabled on the pool, the size may be up to 1 Mbyte. +feature is enabled on the pool, the size may be up to +.Ar 1MB . See .Xr zpool-features 5 for details on ZFS feature flags. @@ -1452,12 +1487,12 @@ future releases. .Pp The default value is .Sy all . -.It Sy refquota Ns = Ns Em size Ns | Ns Sy none +.It Sy refquota Ns = Ns Ar size Ns | Ns Sy none Limits the amount of space a dataset can consume. This property enforces a hard limit on the amount of space used. This hard limit does not include space used by descendents, including file systems and snapshots. -.It Sy refreservation Ns = Ns Em size Ns | Ns Sy none Ns | Ns Sy auto +.It Sy refreservation Ns = Ns Ar size Ns | Ns Sy none Ns | Ns Sy auto The minimum amount of space guaranteed to a dataset, not including its descendents. When the amount of space used is below this value, the dataset is treated as if @@ -1495,12 +1530,14 @@ This property can also be referred to by its shortened column name, .Sy refreserv . .It Sy relatime Ns = Ns Sy on Ns | Ns Sy off Controls the manner in which the access time is updated when -.Sy atime=on -is set. Turning this property on causes the access time to be updated relative -to the modify or change time. Access time is only updated if the previous +.Sy atime Ns = Ns Sy on +is set. +Turning this property on causes the access time to be updated relative +to the modify or change time. +Access time is only updated if the previous access time was earlier than the current modify or change time or if the -existing access time hasn't been updated within the past 24 hours. The default -value is +existing access time hasn't been updated within the past 24 hours. +The default value is .Sy off . The values .Sy on @@ -1511,7 +1548,7 @@ are equivalent to the and .Sy norelatime mount options. -.It Sy reservation Ns = Ns Em size Ns | Ns Sy none +.It Sy reservation Ns = Ns Ar size Ns | Ns Sy none The minimum amount of space guaranteed to a dataset and its descendants. When the amount of space used is below this value, the dataset is treated as if it were taking up the amount of space specified by its reservation. @@ -1547,21 +1584,23 @@ are equivalent to the and .Sy nosuid mount options. -.It Sy sharesmb Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Em opts +.It Sy sharesmb Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Ar opts Controls whether the file system is shared by using .Sy Samba USERSHARES -and what options are to be used. Otherwise, the file system is automatically -shared and unshared with the +and what options are to be used. +Otherwise, the file system is automatically shared and unshared with the .Nm zfs Cm share and .Nm zfs Cm unshare -commands. If the property is set to on, the +commands. +If the property is set to on, the .Xr net 8 command is invoked to create a .Sy USERSHARE . .Pp Because SMB shares requires a resource name, a unique resource name is -constructed from the dataset name. The constructed name is a copy of the +constructed from the dataset name. +The constructed name is a copy of the dataset name except that the characters in the dataset name, which would be invalid in the resource name, are replaced with underscore (_) characters. Linux does not currently support additional options which might be available @@ -1574,12 +1613,12 @@ property is set to the file systems are unshared. .Pp The share is created with the ACL (Access Control List) "Everyone:F" ("F" -stands for "full permissions", ie. read and write permissions) and no guest +stands for "full permissions", i.e. read and write permissions) and no guest access (which means Samba must be able to authenticate a real user, system -passwd/shadow, LDAP or smbpasswd based) by default. This means that any -additional access control (disallow specific user specific access etc) must -be done on the underlying file system. -.It Sy sharenfs Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Em opts +passwd/shadow, LDAP or smbpasswd based) by default. +This means that any additional access control +(disallow specific user specific access etc) must be done on the underlying file system. +.It Sy sharenfs Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Ar opts Controls whether the file system is shared via NFS, and what options are to be used. A file system with a @@ -1589,7 +1628,7 @@ property of is managed with the .Xr exportfs 8 command and entries in the -.Em /etc/exports +.Pa /etc/exports file. Otherwise, the file system is automatically shared and unshared with the .Nm zfs Cm share @@ -1599,12 +1638,12 @@ commands. If the property is set to .Sy on , the dataset is shared using the default options: -.Pp -.Em sec=sys,rw,crossmnt,no_subtree_check +.Dl sec=sys,rw,crossmnt,no_subtree_check .Pp See .Xr exports 5 -for the meaning of the default options. Otherwise, the +for the meaning of the default options. +Otherwise, the .Xr exportfs 8 command is invoked with options equivalent to the contents of this property. .Pp @@ -1636,15 +1675,16 @@ ZFS will instead optimize synchronous operations for global pool throughput and efficient use of resources. .It Sy snapdev Ns = Ns Sy hidden Ns | Ns Sy visible Controls whether the volume snapshot devices under -.Em /dev/zvol/ -are hidden or visible. The default value is +.Pa /dev/zvol/ Ns Aq Ar pool +are hidden or visible. +The default value is .Sy hidden . .It Sy snapdir Ns = Ns Sy hidden Ns | Ns Sy visible Controls whether the .Pa .zfs directory is hidden or visible in the root of the file system as discussed in the -.Em Snapshots +.Sx Snapshots section of .Xr zfsconcepts 8 . The default value is @@ -1653,11 +1693,9 @@ The default value is Controls the behavior of synchronous requests .Pq e.g. fsync, O_DSYNC . .Sy standard -is the -.Tn POSIX -specified behavior of ensuring all synchronous requests are written to stable -storage and all devices are flushed to ensure data is not cached by device -controllers +is the POSIX-specified behavior of ensuring all synchronous requests +are written to stable storage and all devices are flushed to ensure +data is not cached by device controllers .Pq this is the default . .Sy always causes every file system transaction to be written and flushed before its @@ -1670,14 +1708,14 @@ This option will give the highest performance. However, it is very dangerous as ZFS would be ignoring the synchronous transaction demands of applications such as databases or NFS. Administrators should only use this option when the risks are understood. -.It Sy version Ns = Ns Em N Ns | Ns Sy current +.It Sy version Ns = Ns Ar N Ns | Ns Sy current The on-disk version of this file system, which is independent of the pool version. This property can only be set to later supported versions. See the .Nm zfs Cm upgrade command. -.It Sy volsize Ns = Ns Em size +.It Sy volsize Ns = Ns Ar size For volumes, specifies the logical size of the volume. By default, creating a volume establishes a reservation of equal size. For storage pools with a version number of 9 or higher, a @@ -1686,9 +1724,7 @@ is set instead. Any changes to .Sy volsize are reflected in an equivalent change to the reservation -.Po or -.Sy refreservation -.Pc . +.Pq or Sy refreservation . The .Sy volsize can only be set to a multiple of @@ -1732,19 +1768,20 @@ when the pool is low on space. For a sparse volume, changes to .Sy volsize are not reflected in the -.Sy refreservation. +.Sy refreservation . A volume that is not sparse is said to be .Qq thick provisioned . A sparse volume can become thick provisioned by setting .Sy refreservation to .Sy auto . -.It Sy volmode Ns = Ns Cm default | full | geom | dev | none +.It Sy volmode Ns = Ns Sy default Ns | Ns Sy full Ns | Ns Sy geom Ns | Ns Sy dev Ns | Ns Sy none This property specifies how volumes should be exposed to the OS. Setting it to .Sy full exposes volumes as fully fledged block devices, providing maximal -functionality. The value +functionality. +The value .Sy geom is just an alias for .Sy full @@ -1759,7 +1796,7 @@ that can be suitable for backup purposes. Value .Sy default means that volumes exposition is controlled by system-wide tunable -.Va zvol_volmode , +.Sy zvol_volmode , where .Sy full , .Sy dev @@ -1775,37 +1812,46 @@ In addition to enabling this property, the virus scan service must also be enabled for virus scanning to occur. The default value is .Sy off . -This property is not used on Linux. +This property is not used by OpenZFS. .It Sy xattr Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Sy sa -Controls whether extended attributes are enabled for this file system. Two -styles of extended attributes are supported either directory based or system -attribute based. +Controls whether extended attributes are enabled for this file system. +Two styles of extended attributes are supported: either directory based +or system attribute based. .Pp The default value of .Sy on -enables directory based extended attributes. This style of extended attribute -imposes no practical limit on either the size or number of attributes which -can be set on a file. Although under Linux the +enables directory based extended attributes. +This style of extended attribute imposes no practical limit +on either the size or number of attributes which can be set on a file. +Although under Linux the .Xr getxattr 2 and .Xr setxattr 2 -system calls limit the maximum size to 64K. This is the most compatible -style of extended attribute and is supported by all OpenZFS implementations. +system calls limit the maximum size to 64K. +This is the most compatible +style of extended attribute and is supported by all ZFS implementations. .Pp System attribute based xattrs can be enabled by setting the value to .Sy sa . -The key advantage of this type of xattr is improved performance. Storing -extended attributes as system attributes significantly decreases the amount of -disk IO required. Up to 64K of data may be stored per-file in the space -reserved for system attributes. If there is not enough space available for -an extended attribute then it will be automatically written as a directory -based xattr. System attribute based extended attributes are not accessible +The key advantage of this type of xattr is improved performance. +Storing extended attributes as system attributes +significantly decreases the amount of disk IO required. +Up to 64K of data may be stored per-file in the space reserved for system attributes. +If there is not enough space available for an extended attribute +then it will be automatically written as a directory based xattr. +System attribute based extended attributes are not accessible on platforms which do not support the -.Sy xattr=sa +.Sy xattr Ns = Ns Sy sa feature. +OpenZFS supports +.Sy xattr Ns = Ns Sy sa +on both +.Fx +and Linux. .Pp The use of system attribute based xattrs is strongly encouraged for users of -SELinux or POSIX ACLs. Both of these features heavily rely on extended +SELinux or POSIX ACLs. +Both of these features heavily rely on extended attributes and benefit significantly from the reduced access time. .Pp The values @@ -1817,17 +1863,20 @@ are equivalent to the and .Sy noxattr mount options. -.It Sy jailed Ns = Ns Cm off | on -Controls whether the dataset is managed from a jail. See the -.Qq Sx Jails -section in -.Xr zfs 8 -for more information. Jails are a FreeBSD feature and are not relevant on -other platforms. The default value is -.Cm off . +.It Sy jailed Ns = Ns Sy off Ns | Ns Sy on +Controls whether the dataset is managed from a jail. +See +.Xr zfs-jail 8 +for more information. +Jails are a +.Fx +feature and are not relevant on other platforms. +The default value is +.Sy off . .It Sy zoned Ns = Ns Sy on Ns | Ns Sy off -Controls whether the dataset is managed from a non-global zone. Zones are a -Solaris feature and are not relevant on other platforms. The default value is +Controls whether the dataset is managed from a non-global zone. +Zones are a Solaris feature and are not relevant on other platforms. +The default value is .Sy off . .El .Pp @@ -1855,9 +1904,7 @@ property is .Sy sensitive . Traditionally, .Ux -and -.Tn POSIX -file systems have case-sensitive file names. +and POSIX file systems have case-sensitive file names. .Pp The .Sy mixed @@ -1916,7 +1963,8 @@ and .Sy utf8only properties are also new permissions that can be assigned to non-privileged users by using the ZFS delegated administration feature. -.Ss "Temporary Mount Point Properties" +. +.Ss Temporary Mount Point Properties When a file system is mounted, either through .Xr mount 8 for legacy mounts or the @@ -1924,17 +1972,34 @@ for legacy mounts or the command for normal file systems, its mount options are set according to its properties. The correlation between properties and mount options is as follows: -.Bd -literal - PROPERTY MOUNT OPTION - atime atime/noatime - canmount auto/noauto - devices dev/nodev - exec exec/noexec - readonly ro/rw - relatime relatime/norelatime - setuid suid/nosuid - xattr xattr/noxattr -.Ed +.Bl -tag -compact -offset Ds -width "rootcontext=" +.It Sy atime +atime/noatime +.It Sy canmount +auto/noauto +.It Sy devices +dev/nodev +.It Sy exec +exec/noexec +.It Sy readonly +ro/rw +.It Sy relatime +relatime/norelatime +.It Sy setuid +suid/nosuid +.It Sy xattr +xattr/noxattr +.It Sy nbmand +mand/nomand +.It Sy context Ns = +context= +.It Sy fscontext Ns = +fscontext= +.It Sy defcontext Ns = +defcontext= +.It Sy rootcontext Ns = +rootcontext= +.El .Pp In addition, these options can be set on a per-mount basis using the .Fl o @@ -1944,7 +2009,7 @@ dataset. The .Sy nosuid option is an alias for -.Sy nodevices Ns \&, Ns Sy nosetuid . +.Sy nodevices , Ns Sy nosetuid . These properties are reported as .Qq temporary by the @@ -1952,7 +2017,8 @@ by the command. If the properties are changed while the dataset is mounted, the new setting overrides any temporary settings. -.Ss "User Properties" +. +.Ss User Properties In addition to the standard native properties, ZFS supports arbitrary user properties. User properties have no effect on ZFS behavior, but applications or @@ -1973,16 +2039,14 @@ and underscore .Pq Qq Sy _ . The expected convention is that the property name is divided into two portions such as -.Em module Ns \&: Ns Em property , +.Ar module : Ns Ar property , but this namespace is not enforced by ZFS. User property names can be at most 256 characters, and cannot begin with a dash .Pq Qq Sy - . .Pp When making programmatic use of user properties, it is strongly suggested to use -a reversed -.Sy DNS -domain name for the -.Em module +a reversed DNS domain name for the +.Ar module component of property names to reduce the chance that two independently-developed packages use the same property name for different purposes. diff --git a/sys/contrib/openzfs/man/man8/zgenhostid.8 b/sys/contrib/openzfs/man/man8/zgenhostid.8 index eb0fde748eb..4f926f473b9 100644 --- a/sys/contrib/openzfs/man/man8/zgenhostid.8 +++ b/sys/contrib/openzfs/man/man8/zgenhostid.8 @@ -21,7 +21,7 @@ .\" .\" Copyright (c) 2017 by Lawrence Livermore National Security, LLC. .\" -.Dd March 18, 2021 +.Dd May 26, 2021 .Dt ZGENHOSTID 8 SMM .Os .Sh NAME @@ -71,22 +71,13 @@ digits long, optionally prefixed by .Sh EXAMPLES .Bl -tag -width Bd .It Generate a random hostid and store it -.Bd -literal -# zgenhostid -.Ed +.Dl # zgenhostid .It Record the libc-generated hostid in Pa /etc/hostid -.Bd -literal -# zgenhostid "$(hostid)" -.Ed +.Dl # zgenhostid "$(hostid)" .It Record a custom hostid (0xdeadbeef) in Pa /etc/hostid -.Bd -literal -# zgenhostid deadbeef -.Ed -.It Record a custom hostid (0x01234567) in Pa /tmp/hostid -and ovewrite the file if it exists -.Bd -literal -# zgenhostid -f -o /tmp/hostid 0x01234567 -.Ed +.Dl # zgenhostid deadbeef +.It Record a custom hostid (0x01234567) in Pa /tmp/hostid No and ovewrite the file if it exists +.Dl # zgenhostid -f -o /tmp/hostid 0x01234567 .El .Sh SEE ALSO .Xr genhostid 1 , @@ -98,6 +89,6 @@ and ovewrite the file if it exists emulates the .Xr genhostid 1 utility and is provided for use on systems which -do not include the utility or do not provide +do not include the utility or do not provide the .Xr sethostid 3 call. diff --git a/sys/contrib/openzfs/man/man8/zinject.8 b/sys/contrib/openzfs/man/man8/zinject.8 index ee6776fe764..a2934692998 100644 --- a/sys/contrib/openzfs/man/man8/zinject.8 +++ b/sys/contrib/openzfs/man/man8/zinject.8 @@ -1,4 +1,3 @@ -'\" t .\" .\" CDDL HEADER START .\" @@ -19,180 +18,279 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright 2013 Darik Horn . All rights reserved. .\" -.TH ZINJECT 8 "Aug 24, 2020" OpenZFS - -.SH NAME -zinject \- ZFS Fault Injector -.SH DESCRIPTION -.BR zinject -creates artificial problems in a ZFS pool by simulating data corruption or device failures. This program is dangerous. -.SH SYNOPSIS -.TP -.B "zinject" +.\" lint-ok: WARNING: sections out of conventional order: Sh SYNOPSIS +.\" +.Dd May 26, 2021 +.Dt ZINJECT 8 +.Os +. +.Sh NAME +.Nm zinject +.Nd ZFS Fault Injector +.Sh DESCRIPTION +.Nm +creates artificial problems in a ZFS pool by simulating data corruption +or device failures. +This program is dangerous. +. +.Sh SYNOPSIS +.Bl -tag -width Ds +.It Xo +.Nm zinject +.Xc List injection records. -.TP -.B "zinject \-b \fIobjset:object:level:blkd\fB [\-f \fIfrequency\fB] [\-amu] \fIpool\fB" +. +.It Xo +.Nm zinject +.Fl b Ar objset : Ns Ar object : Ns Ar level : Ns Ar start : Ns Ar end +.Op Fl f Ar frequency +.Fl amu +.Op pool +.Xc Force an error into the pool at a bookmark. -.TP -.B "zinject \-c <\fIid\fB | all> +. +.It Xo +.Nm zinject +.Fl c Ar id Ns | Ns Sy all +.Xc Cancel injection records. -.TP -.B "zinject \-d \fIvdev\fB \-A \fIpool\fB +. +.It Xo +.Nm zinject +.Fl d Ar vdev +.Fl A Sy degrade Ns | Ns Sy fault +.Ar pool +.Xc Force a vdev into the DEGRADED or FAULTED state. -.TP -.B "zinject -d \fIvdev\fB -D latency:lanes \fIpool\fB - +. +.It Xo +.Nm zinject +.Fl d Ar vdev +.Fl D Ar latency : Ns Ar lanes +.Ar pool +.Xc Add an artificial delay to IO requests on a particular -device, such that the requests take a minimum of 'latency' -milliseconds to complete. Each delay has an associated -number of 'lanes' which defines the number of concurrent +device, such that the requests take a minimum of +.Ar latency +milliseconds to complete. +Each delay has an associated number of +.Ar lanes +which defines the number of concurrent IO requests that can be processed. - -For example, with a single lane delay of 10 ms (-D 10:1), +.Pp +For example, with a single lane delay of 10 ms +.No (\& Ns Fl D Ar 10 : Ns Ar 1 ) , the device will only be able to service a single IO request -at a time with each request taking 10 ms to complete. So, -if only a single request is submitted every 10 ms, the +at a time with each request taking 10 ms to complete. +So, if only a single request is submitted every 10 ms, the average latency will be 10 ms; but if more than one request is submitted every 10 ms, the average latency will be more than 10 ms. - +.Pp Similarly, if a delay of 10 ms is specified to have two -lanes (-D 10:2), then the device will be able to service -two requests at a time, each with a minimum latency of -10 ms. So, if two requests are submitted every 10 ms, then +lanes +.No (\& Ns Fl D Ar 10 : Ns Ar 2 ) , +then the device will be able to service +two requests at a time, each with a minimum latency of 10 ms. +So, if two requests are submitted every 10 ms, then the average latency will be 10 ms; but if more than two requests are submitted every 10 ms, the average latency will be more than 10 ms. - -Also note, these delays are additive. So two invocations -of '-D 10:1', is roughly equivalent to a single invocation -of '-D 10:2'. This also means, one can specify multiple -lanes with differing target latencies. For example, an -invocation of '-D 10:1' followed by '-D 25:2' will -create 3 lanes on the device; one lane with a latency +.Pp +Also note, these delays are additive. +So two invocations of +.Fl D Ar 10 : Ns Ar 1 +are roughly equivalent to a single invocation of +.Fl D Ar 10 : Ns Ar 2 . +This also means, that one can specify multiple +lanes with differing target latencies. +For example, an invocation of +.Fl D Ar 10 : Ns Ar 1 +followed by +.Fl D Ar 25 : Ns Ar 2 +will create 3 lanes on the device: one lane with a latency of 10 ms and two lanes with a 25 ms latency. - -.TP -.B "zinject \-d \fIvdev\fB [\-e \fIdevice_error\fB] [\-L \fIlabel_error\fB] [\-T \fIfailure\fB] [\-f \fIfrequency\fB] [\-F] \fIpool\fB" +. +.It Xo +.Nm zinject +.Fl d Ar vdev +.Op Fl e Ar device_error +.Op Fl L Ar label_error +.Op Fl T Ar failure +.Op Fl f Ar frequency +.Op Fl F +.Ar pool +.Xc Force a vdev error. -.TP -.B "zinject \-I [\-s \fIseconds\fB | \-g \fItxgs\fB] \fIpool\fB" +. +.It Xo +.Nm zinject +.Fl I +.Op Fl s Ar seconds Ns | Ns Fl g Ar txgs +.Ar pool +.Xc Simulate a hardware failure that fails to honor a cache flush. -.TP -.B "zinject \-p \fIfunction\fB \fIpool\fB +. +.It Xo +.Nm zinject +.Fl p Ar function +.Ar pool +.Xc Panic inside the specified function. -.TP -.B "zinject \-t data [\-C \fIdvas\fB] [\-e \fIdevice_error\fB] [\-f \fIfrequency\fB] [\-l \fIlevel\fB] [\-r \fIrange\fB] [\-amq] \fIpath\fB" +. +.It Xo +.Nm zinject +.Fl t Sy data +.Fl C Ar dvas +.Op Fl e Ar device_error +.Op Fl f Ar frequency +.Op Fl l Ar level +.Op Fl r Ar range +.Op Fl amq +.Ar path +.Xc Force an error into the contents of a file. -.TP -.B "zinject \-t dnode [\-C \fIdvas\fB] [\-e \fIdevice_error\fB] [\-f \fIfrequency\fB] [\-l \fIlevel\fB] [\-amq] \fIpath\fB" +. +.It Xo +.Nm zinject +.Fl t Sy dnode +.Fl C Ar dvas +.Op Fl e Ar device_error +.Op Fl f Ar frequency +.Op Fl l Ar level +.Op Fl amq +.Ar path +.Xc Force an error into the metadnode for a file or directory. -.TP -.B "zinject \-t \fImos_type\fB [\-C \fIdvas\fB] [\-e \fIdevice_error\fB] [\-f \fIfrequency\fB] [\-l \fIlevel\fB] [\-r \fIrange\fB] [\-amqu] \fIpool\fB" +. +.It Xo +.Nm zinject +.Fl t Ar mos_type +.Fl C Ar dvas +.Op Fl e Ar device_error +.Op Fl f Ar frequency +.Op Fl l Ar level +.Op Fl r Ar range +.Op Fl amqu +.Ar pool +.Xc Force an error into the MOS of a pool. -.SH OPTIONS -.TP -.BI "\-a" +.El +.Sh OPTIONS +.Bl -tag -width "-C dvas" +.It Fl a Flush the ARC before injection. -.TP -.BI "\-b" " objset:object:level:start:end" -Force an error into the pool at this bookmark tuple. Each number is -in hexadecimal, and only one block can be specified. -.TP -.BI "\-C" " dvas" -Inject the given error only into specific DVAs. The mask should be -specified as a list of 0-indexed DVAs separated by commas (ex. '0,2'). This -option is not applicable to logical data errors such as -.BR "decompress" +.It Fl b Ar objset : Ns Ar object : Ns Ar level : Ns Ar start : Ns Ar end +Force an error into the pool at this bookmark tuple. +Each number is in hexadecimal, and only one block can be specified. +.It Fl C Ar dvas +Inject the given error only into specific DVAs. +The mask should be specified as a list of 0-indexed DVAs separated by commas +.No (ex. Ar 0,2 Ns No ). +This option is not applicable to logical data errors such as +.Sy decompress and -.BR "decrypt" . -.TP -.BI "\-d" " vdev" +.Sy decrypt . +.It Fl d Ar vdev A vdev specified by path or GUID. -.TP -.BI "\-e" " device_error" +.It Fl e Ar device_error Specify -.BR "checksum" " for an ECKSUM error," -.BR "decompress" " for a data decompression error," -.BR "decrypt" " for a data decryption error," -.BR "corrupt" " to flip a bit in the data after a read," -.BR "dtl" " for an ECHILD error," -.BR "io" " for an EIO error where reopening the device will succeed, or" -.BR "nxio" " for an ENXIO error where reopening the device will fail." -For EIO and ENXIO, the "failed" reads or writes still occur. The probe simply -sets the error value reported by the I/O pipeline so it appears the read or -write failed. Decryption errors only currently work with file data. -.TP -.BI "\-f" " frequency" -Only inject errors a fraction of the time. Expressed as a real number -percentage between 0.0001 and 100. -.TP -.BI "\-F" -Fail faster. Do fewer checks. -.TP -.BI "\-g" " txgs" +.Bl -tag -compact -width "decompress" +.It Sy checksum +for an ECKSUM error, +.It Sy decompress +for a data decompression error, +.It Sy decrypt +for a data decryption error, +.It Sy corrupt +to flip a bit in the data after a read, +.It Sy dtl +for an ECHILD error, +.It Sy io +for an EIO error where reopening the device will succeed, or +.It Sy nxio +for an ENXIO error where reopening the device will fail. +.El +.Pp +For EIO and ENXIO, the "failed" reads or writes still occur. +The probe simply sets the error value reported by the I/O pipeline +so it appears the read or write failed. +Decryption errors only currently work with file data. +.It Fl f Ar frequency +Only inject errors a fraction of the time. +Expressed as a real number percentage between +.Sy 0.0001 +and +.Sy 100 . +.It Fl F +Fail faster. +Do fewer checks. +.It Fl f Ar txgs Run for this many transaction groups before reporting failure. -.TP -.BI "\-h" +.It Fl h Print the usage message. -.TP -.BI "\-l" " level" -Inject an error at a particular block level. The default is 0. -.TP -.BI "\-L" " label_error" +.It Fl l Ar level +Inject an error at a particular block level. +The default is +.Sy 0 . +.It Fl L Ar label_error Set the label error region to one of -.BR " nvlist" "," -.BR " pad1" "," -.BR " pad2" ", or" -.BR " uber" "." -.TP -.BI "\-m" +.Sy nvlist , +.Sy pad1 , +.Sy pad2 , +or +.Sy uber . +.It Fl m Automatically remount the underlying filesystem. -.TP -.BI "\-q" -Quiet mode. Only print the handler number added. -.TP -.BI "\-r" " range" +.It Fl q +Quiet mode. +Only print the handler number added. +.It Fl r Ar range Inject an error over a particular logical range of an object, which will be translated to the appropriate blkid range according to the object's properties. -.TP -.BI "\-s" " seconds" +.It Fl s Ar seconds Run for this many seconds before reporting failure. -.TP -.BI "\-T" " failure" +.It Fl T Ar failure Set the failure type to one of -.BR " all" "," -.BR " claim" "," -.BR " free" "," -.BR " read" ", or" -.BR " write" "." -.TP -.BI "\-t" " mos_type" +.Sy all , +.Sy claim , +.Sy free , +.Sy read , +or +.Sy write . +.It Fl t Ar mos_type Set this to -.BR "mos " "for any data in the MOS," -.BR "mosdir " "for an object directory," -.BR "config " "for the pool configuration," -.BR "bpobj " "for the block pointer list," -.BR "spacemap " "for the space map," -.BR "metaslab " "for the metaslab, or" -.BR "errlog " "for the persistent error log." -.TP -.BI "\-u" +.Bl -tag -compact -width "spacemap" +.It Sy mos +for any data in the MOS, +.It Sy mosdir +for an object directory, +.It Sy config +for the pool configuration, +.It Sy bpobj +for the block pointer list, +.It Sy spacemap +for the space map, +.It Sy metaslab +for the metaslab, or +.It Sy errlog +for the persistent error log. +.El +.It Fl u Unload the pool after injection. - -.SH "ENVIRONMENT VARIABLES" -.TP -.B "ZINJECT_DEBUG" -Run \fBzinject\fR in debug mode. - -.SH "AUTHORS" -This man page was written by Darik Horn -excerpting the \fBzinject\fR usage message and source code. - -.SH "SEE ALSO" -.BR zpool (8), -.BR zfs (8) +.El +. +.Sh ENVIRONMENT VARIABLES +.Bl -tag -width "ZF" +.It Ev ZFS_HOSTID +Run +.Nm +in debug mode. +.El +. +.Sh SEE ALSO +.Xr zfs 8 , +.Xr zpool 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-add.8 b/sys/contrib/openzfs/man/man8/zpool-add.8 index cf1630435eb..a0f15076f23 100644 --- a/sys/contrib/openzfs/man/man8/zpool-add.8 +++ b/sys/contrib/openzfs/man/man8/zpool-add.8 @@ -17,7 +17,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -26,34 +25,28 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd May 27, 2021 .Dt ZPOOL-ADD 8 .Os +. .Sh NAME .Nm zpool-add -.Nd Adds specified virtual devices to a ZFS storage pool +.Nd add vdevs to ZFS storage pool .Sh SYNOPSIS .Nm zpool .Cm add .Op Fl fgLnP .Oo Fl o Ar property Ns = Ns Ar value Oc -.Ar pool vdev Ns ... +.Ar pool vdev Ns … +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm add -.Op Fl fgLnP -.Oo Fl o Ar property Ns = Ns Ar value Oc -.Ar pool vdev Ns ... -.Xc Adds the specified virtual devices to the given pool. The .Ar vdev specification is described in the .Em Virtual Devices section of -.Xr zpoolconcepts 8. +.Xr zpoolconcepts 8 . The behavior of the .Fl f option, and the device checks performed are described in the @@ -68,13 +61,17 @@ Not all devices can be overridden in this manner. .It Fl g Display .Ar vdev , -GUIDs instead of the normal device names. These GUIDs can be used in place of +GUIDs instead of the normal device names. +These GUIDs can be used in place of device names for the zpool detach/offline/remove/replace commands. .It Fl L Display real paths for .Ar vdev Ns s -resolving all symbolic links. This can be used to look up the current block -device name regardless of the /dev/disk/ path used to open it. +resolving all symbolic links. +This can be used to look up the current block +device name regardless of the +.Pa /dev/disk +path used to open it. .It Fl n Displays the configuration that would be used without actually adding the .Ar vdev Ns s . @@ -83,20 +80,22 @@ device sharing. .It Fl P Display real paths for .Ar vdev Ns s -instead of only the last component of the path. This can be used in -conjunction with the +instead of only the last component of the path. +This can be used in conjunction with the .Fl L flag. .It Fl o Ar property Ns = Ns Ar value -Sets the given pool properties. See the +Sets the given pool properties. +See the .Xr zpoolprops 8 -manual page for a list of valid properties that can be set. The only property -supported at the moment is ashift. -.El +manual page for a list of valid properties that can be set. +The only property supported at the moment is +.Sy ashift . .El +. .Sh SEE ALSO -.Xr zpool-remove 8 , .Xr zpool-attach 8 , .Xr zpool-import 8 , .Xr zpool-initialize 8 , -.Xr zpool-online 8 +.Xr zpool-online 8 , +.Xr zpool-remove 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-attach.8 b/sys/contrib/openzfs/man/man8/zpool-attach.8 index 41b6a6b613d..04c0fca21d0 100644 --- a/sys/contrib/openzfs/man/man8/zpool-attach.8 +++ b/sys/contrib/openzfs/man/man8/zpool-attach.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -30,24 +29,18 @@ .Dd May 15, 2020 .Dt ZPOOL-ATTACH 8 .Os +. .Sh NAME .Nm zpool-attach -.Nd Attach a new device to an existing ZFS virtual device (vdev). +.Nd attach new device to existing ZFS vdev .Sh SYNOPSIS .Nm zpool .Cm attach .Op Fl fsw .Oo Fl o Ar property Ns = Ns Ar value Oc .Ar pool device new_device +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm attach -.Op Fl fsw -.Oo Fl o Ar property Ns = Ns Ar value Oc -.Ar pool device new_device -.Xc Attaches .Ar new_device to the existing @@ -76,10 +69,12 @@ Forces use of even if it appears to be in use. Not all devices can be overridden in this manner. .It Fl o Ar property Ns = Ns Ar value -Sets the given pool properties. See the +Sets the given pool properties. +See the .Xr zpoolprops 8 -manual page for a list of valid properties that can be set. The only property -supported at the moment is ashift. +manual page for a list of valid properties that can be set. +The only property supported at the moment is +.Sy ashift . .It Fl s The .Ar new_device @@ -92,10 +87,10 @@ Waits until .Ar new_device has finished resilvering before returning. .El -.El +. .Sh SEE ALSO -.Xr zpool-detach 8 , .Xr zpool-add 8 , +.Xr zpool-detach 8 , .Xr zpool-import 8 , .Xr zpool-initialize 8 , .Xr zpool-online 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-checkpoint.8 b/sys/contrib/openzfs/man/man8/zpool-checkpoint.8 index 128970ee66a..d5add14aed2 100644 --- a/sys/contrib/openzfs/man/man8/zpool-checkpoint.8 +++ b/sys/contrib/openzfs/man/man8/zpool-checkpoint.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,56 +26,47 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd May 27, 2021 .Dt ZPOOL-CHECKPOINT 8 .Os +. .Sh NAME .Nm zpool-checkpoint -.Nd Checkpoints the current state of a ZFS storage pool +.Nd check-point current ZFS storage pool state .Sh SYNOPSIS .Nm zpool .Cm checkpoint -.Op Fl d, -discard Oo Fl w, -wait Oc +.Op Fl d Op Fl w .Ar pool +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm checkpoint -.Op Fl d, -discard Oo Fl w, -wait Oc -.Ar pool -.Xc Checkpoints the current state of .Ar pool , which can be later restored by .Nm zpool Cm import --rewind-to-checkpoint . The existence of a checkpoint in a pool prohibits the following .Nm zpool -commands: -.Cm remove , -.Cm attach , -.Cm detach , -.Cm split , -and -.Cm reguid . +subcommands: +.Cm remove , attach , detach , split , No and Cm reguid . In addition, it may break reservation boundaries if the pool lacks free space. The .Nm zpool Cm status command indicates the existence of a checkpoint or the progress of discarding a checkpoint from a pool. -The .Nm zpool Cm list -command reports how much space the checkpoint takes from the pool. +can be used to check how much space the checkpoint takes from the pool. +. +.Sh OPTIONS .Bl -tag -width Ds -.It Fl d, -discard +.It Fl d , -discard Discards an existing checkpoint from .Ar pool . -.It Fl w, -wait +.It Fl w , -wait Waits until the checkpoint has finished being discarded before returning. .El -.El +. .Sh SEE ALSO +.Xr zfs-snapshot 8 , .Xr zpool-import 8 , -.Xr zpool-status 8 , -.Xr zfs-snapshot 8 +.Xr zpool-status 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-clear.8 b/sys/contrib/openzfs/man/man8/zpool-clear.8 index e00eb760af6..6e41566ca6d 100644 --- a/sys/contrib/openzfs/man/man8/zpool-clear.8 +++ b/sys/contrib/openzfs/man/man8/zpool-clear.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,33 +26,30 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd May 27, 2021 .Dt ZPOOL-CLEAR 8 .Os +. .Sh NAME .Nm zpool-clear -.Nd Clears device errors in a ZFS storage pool. +.Nd clear device errors in ZFS storage pool .Sh SYNOPSIS .Nm zpool .Cm clear .Ar pool -.Op Ar device +.Oo Ar device Oc Ns … +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm clear -.Ar pool -.Op Ar device -.Xc Clears device errors in a pool. If no arguments are specified, all device errors within the pool are cleared. If one or more devices is specified, only those errors associated with the specified device or devices are cleared. -If multihost is enabled, and the pool has been suspended, this will not -resume I/O. While the pool was suspended, it may have been imported on +If +.Sy multihost +is enabled and the pool has been suspended, this will not resume I/O. +While the pool was suspended, it may have been imported on another host, and resuming I/O could result in pool damage. -.El +. .Sh SEE ALSO .Xr zdb 8 , .Xr zpool-reopen 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-create.8 b/sys/contrib/openzfs/man/man8/zpool-create.8 index fe35ab8db3e..91e6f427d83 100644 --- a/sys/contrib/openzfs/man/man8/zpool-create.8 +++ b/sys/contrib/openzfs/man/man8/zpool-create.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -28,42 +27,32 @@ .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" Copyright (c) 2021, Colm Buckley .\" -.Dd August 9, 2019 +.Dd June 2, 2021 .Dt ZPOOL-CREATE 8 .Os +. .Sh NAME .Nm zpool-create -.Nd Creates a new ZFS storage pool +.Nd create ZFS storage pool .Sh SYNOPSIS .Nm zpool .Cm create .Op Fl dfn .Op Fl m Ar mountpoint -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... -.Oo Fl o Ar feature@feature Ns = Ns Ar value Oc -.Op Fl o Ar compatibility Ns = Ns Ar off | legacy | file Bq , Ns Ar file Ns ... -.Oo Fl O Ar file-system-property Ns = Ns Ar value Oc Ns ... -.Op Fl R Ar root -.Ar pool vdev Ns ... -.Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm create -.Op Fl dfn -.Op Fl m Ar mountpoint -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... -.Oo Fl o Ar feature@feature Ns = Ns Ar value Oc Ns ... -.Op Fl o Ar compatibility Ns = Ns Ar off | legacy | file Bq , Ns Ar file Ns ... -.Oo Fl O Ar file-system-property Ns = Ns Ar value Oc Ns ... +.Oo Fl o Ar property Ns = Ns Ar value Oc Ns … +.Oo Fl o Sy feature@ Ns Ar feature Ns = Ns Ar value Oc +.Op Fl o Ar compatibility Ns = Ns Sy off Ns | Ns Sy legacy Ns | Ns Ar file Ns Oo , Ns Ar file Oc Ns … +.Oo Fl O Ar file-system-property Ns = Ns Ar value Oc Ns … .Op Fl R Ar root .Op Fl t Ar tname -.Ar pool vdev Ns ... -.Xc +.Ar pool +.Ar vdev Ns … +. +.Sh DESCRIPTION Creates a new storage pool containing the virtual devices specified on the command line. The pool name must begin with a letter, and can only contain -alphanumeric characters as well as underscore +alphanumeric characters as well as the underscore .Pq Qq Sy _ , dash .Pq Qq Sy \&- , @@ -84,46 +73,41 @@ are reserved, as are names beginning with .Sy mirror , .Sy raidz , .Sy draid , -.Sy spare , -and the pattern -.Sy c[0-9] . +and +.Sy spare . The .Ar vdev specification is described in the -.Em Virtual Devices +.Sx Virtual Devices section of -.Xr zpoolconcepts. +.Xr zpoolconcepts 8 . .Pp The command attempts to verify that each device specified is accessible and not -currently in use by another subsystem. However this check is not robust enough +currently in use by another subsystem. +However this check is not robust enough to detect simultaneous attempts to use a new device in different pools, even if -.Sy multihost -is -.Sy enabled. -The -administrator must ensure that simultaneous invocations of any combination of -.Sy zpool replace , -.Sy zpool create , -.Sy zpool add , +.Sy multihost Ns = Sy enabled . +The administrator must ensure, that simultaneous invocations of any combination of +.Nm zpool Cm replace , +.Nm zpool Cm create , +.Nm zpool Cm add , or -.Sy zpool labelclear , -do not refer to the same device. Using the same device in two pools will -result in pool corruption. +.Nm zpool Cm labelclear , +do not refer to the same device. +Using the same device in two pools will result in pool corruption. .Pp There are some uses, such as being currently mounted, or specified as the dedicated dump device, that prevents a device from ever being used by ZFS. Other uses, such as having a preexisting UFS file system, can be overridden with -the -.Fl f -option. +.Fl f . .Pp The command also checks that the replication strategy for the pool is consistent. -An attempt to combine redundant and non-redundant storage in a single pool, or -to mix disks and files, results in an error unless +An attempt to combine redundant and non-redundant storage in a single pool, +or to mix disks and files, results in an error unless .Fl f is specified. -The use of differently sized devices within a single raidz or mirror group is +The use of differently-sized devices within a single raidz or mirror group is also flagged as an error unless .Fl f is specified. @@ -133,27 +117,27 @@ Unless the option is specified, the default mount point is .Pa / Ns Ar pool . The mount point must not exist or must be empty, or else the root dataset -cannot be mounted. +will not be able to be be mounted. This can be overridden with the .Fl m option. .Pp -By default all supported features are enabled on the new pool. The +By default all supported features are enabled on the new pool. +The .Fl d -option or the +option and the .Fl o Ar compatibility -property (eg: -.Fl o Ar compatibility=2020 -) can be used to restrict the features that are enabled, so that the -pool can be imported on other releases of the ZFS software. -.Bl -tag -width Ds +property +.Pq e.g Fl o Sy compatibility Ns = Ns Ar 2020 +can be used to restrict the features that are enabled, so that the +pool can be imported on other releases of ZFS. +.Bl -tag -width "-t tname" .It Fl d Do not enable any features on the new pool. Individual features can be enabled by setting their corresponding properties to .Sy enabled -with the -.Fl o -option. +with +.Fl o . See .Xr zpool-features 5 for details about feature properties. @@ -169,14 +153,14 @@ The default mount point is or .Pa altroot/pool if -.Ar altroot +.Sy altroot is specified. The mount point must be an absolute path, .Sy legacy , or .Sy none . For more information on dataset mount points, see -.Xr zfs 8 . +.Xr zfsprops 8 . .It Fl n Displays the configuration that would be used without actually creating the pool. @@ -184,37 +168,43 @@ The actual pool creation can still fail due to insufficient privileges or device sharing. .It Fl o Ar property Ns = Ns Ar value Sets the given pool properties. -See the -.Xr zpoolprops -manual page for a list of valid properties that can be set. -.It Fl o Ar compatibility Ns = Ns Ar off | legacy | file Bq , Ns Ar file Ns ... -Specifies compatibility feature sets. See +See +.Xr zpoolprops 8 +for a list of valid properties that can be set. +.It Fl o Ar compatibility Ns = Ns Sy off Ns | Ns Sy legacy Ns | Ns Ar file Ns Oo , Ns Ar file Oc Ns … +Specifies compatibility feature sets. +See .Xr zpool-features 5 for more information about compatibility feature sets. -.It Fl o Ar feature@feature Ns = Ns Ar value -Sets the given pool feature. See the +.It Fl o Sy feature@ Ns Ar feature Ns = Ns Ar value +Sets the given pool feature. +See the .Xr zpool-features 5 section for a list of valid features that can be set. Value can be either disabled or enabled. .It Fl O Ar file-system-property Ns = Ns Ar value Sets the given file system properties in the root file system of the pool. -See the +See .Xr zfsprops 8 -manual page for a list of valid properties that can be set. +for a list of valid properties that can be set. .It Fl R Ar root Equivalent to .Fl o Sy cachefile Ns = Ns Sy none Fl o Sy altroot Ns = Ns Ar root .It Fl t Ar tname Sets the in-core pool name to -.Sy tname -while the on-disk name will be the name specified as the pool name -.Sy pool . -This will set the default cachefile property to none. This is intended +.Ar tname +while the on-disk name will be the name specified as +.Ar pool . +This will set the default of the +.Sy cachefile +property to +.Sy none . +This is intended to handle name space collisions when creating pools for other systems, such as virtual machines or physical machines whose pools live on network block devices. .El -.El +. .Sh SEE ALSO .Xr zpool-destroy 8 , .Xr zpool-export 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-destroy.8 b/sys/contrib/openzfs/man/man8/zpool-destroy.8 index d4fc21eaec0..a2f6729c8a7 100644 --- a/sys/contrib/openzfs/man/man8/zpool-destroy.8 +++ b/sys/contrib/openzfs/man/man8/zpool-destroy.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,29 +26,23 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd May 31, 2021 .Dt ZPOOL-DESTROY 8 .Os +. .Sh NAME .Nm zpool-destroy -.Nd Destroys the given ZFS storage pool, freeing up any devices for other use +.Nd destroy ZFS storage pool .Sh SYNOPSIS .Nm zpool .Cm destroy .Op Fl f .Ar pool +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm destroy -.Op Fl f -.Ar pool -.Xc Destroys the given pool, freeing up any devices for other use. This command tries to unmount any active datasets before destroying the pool. .Bl -tag -width Ds .It Fl f -Forces any active datasets contained within the pool to be unmounted. -.El +Forcefully unmount all active datasets. .El diff --git a/sys/contrib/openzfs/man/man8/zpool-detach.8 b/sys/contrib/openzfs/man/man8/zpool-detach.8 index 75a5786d5a3..952dd7882a9 100644 --- a/sys/contrib/openzfs/man/man8/zpool-detach.8 +++ b/sys/contrib/openzfs/man/man8/zpool-detach.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -30,32 +29,30 @@ .Dd August 9, 2019 .Dt ZPOOL-DETACH 8 .Os +. .Sh NAME .Nm zpool-detach -.Nd Detaches a device from a ZFS mirror vdev (virtual device) +.Nd detach device from ZFS mirror .Sh SYNOPSIS .Nm zpool .Cm detach .Ar pool device +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm detach -.Ar pool device -.Xc Detaches .Ar device from a mirror. The operation is refused if there are no other valid replicas of the data. -If device may be re-added to the pool later on then consider the -.Sy zpool offline +If +.Ar device +may be re-added to the pool later on then consider the +.Nm zpool Cm offline command instead. -.El +. .Sh SEE ALSO .Xr zpool-attach 8 , -.Xr zpool-offline 8 , .Xr zpool-labelclear 8 , +.Xr zpool-offline 8 , .Xr zpool-remove 8 , .Xr zpool-replace 8 , .Xr zpool-split 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-events.8 b/sys/contrib/openzfs/man/man8/zpool-events.8 index 3a6ff884016..a95ce48d93a 100644 --- a/sys/contrib/openzfs/man/man8/zpool-events.8 +++ b/sys/contrib/openzfs/man/man8/zpool-events.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,45 +26,48 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd May 27, 2021 .Dt ZPOOL-EVENTS 8 .Os +. .Sh NAME .Nm zpool-events -.Nd Lists all recent events generated by the ZFS kernel modules +.Nd list recent events generated by kernel .Sh SYNOPSIS .Nm zpool .Cm events -.Op Fl vHf Oo Ar pool Oc | Fl c -.Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo +.Op Fl vHf +.Op Ar pool .Nm zpool .Cm events -.Op Fl vHf Oo Ar pool Oc | Fl c -.Xc -Lists all recent events generated by the ZFS kernel modules. These events -are consumed by the +.Fl c +. +.Sh DESCRIPTION +Lists all recent events generated by the ZFS kernel modules. +These events are consumed by the .Xr zed 8 and used to automate administrative tasks such as replacing a failed device -with a hot spare. For more information about the subclasses and event payloads +with a hot spare. +For more information about the subclasses and event payloads that can be generated see the .Xr zfs-events 5 man page. -.Bl -tag -width Ds +.Pp +.Bl -tag -compact -width Ds .It Fl c Clear all previous events. .It Fl f Follow mode. .It Fl H -Scripted mode. Do not display headers, and separate fields by a +Scripted mode. +Do not display headers, and separate fields by a single tab instead of arbitrary space. .It Fl v Print the entire payload for each event. .El -.El +. .Sh SEE ALSO -.Xr zed 8 , -.Xr zpool-wait 8 , .Xr zfs-events 5 , -.Xr zfs-module-parameters 5 +.Xr zfs-module-parameters 5 , +.Xr zed 8 , +.Xr zpool-wait 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-export.8 b/sys/contrib/openzfs/man/man8/zpool-export.8 index 1b8077ba19f..a15291a1f59 100644 --- a/sys/contrib/openzfs/man/man8/zpool-export.8 +++ b/sys/contrib/openzfs/man/man8/zpool-export.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -30,24 +29,17 @@ .Dd February 16, 2020 .Dt ZPOOL-EXPORT 8 .Os +. .Sh NAME .Nm zpool-export -.Nd Exports the given ZFS storage pools from the system +.Nd export ZFS storage pools .Sh SYNOPSIS .Nm zpool .Cm export -.Op Fl a .Op Fl f -.Ar pool Ns ... +.Fl a Ns | Ns Ar pool Ns … +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm export -.Op Fl a -.Op Fl f -.Ar pool Ns ... -.Xc Exports the given pools from the system. All devices are marked as exported, but are still considered in use by other subsystems. @@ -69,15 +61,12 @@ the disks. .It Fl a Exports all pools imported on the system. .It Fl f -Forcefully unmount all datasets, using the -.Nm unmount Fl f -command. -This option is not supported on Linux. +Forcefully unmount all datasets, and allow export of pools with active shared spares. .Pp This command will forcefully export the pool even if it has a shared spare that is currently being used. This may lead to potential data corruption. .El -.El +. .Sh SEE ALSO .Xr zpool-import 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-get.8 b/sys/contrib/openzfs/man/man8/zpool-get.8 index c514bb0c5e8..06908238999 100644 --- a/sys/contrib/openzfs/man/man8/zpool-get.8 +++ b/sys/contrib/openzfs/man/man8/zpool-get.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -30,29 +29,31 @@ .Dd August 9, 2019 .Dt ZPOOL-GET 8 .Os +. .Sh NAME .Nm zpool-get -.Nd Retrieves properties for the specified ZFS storage pool(s) +.Nd retrieve properties of ZFS storage pools .Sh SYNOPSIS .Nm zpool .Cm get .Op Fl Hp -.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns ... -.Sy all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns ... -.Oo Ar pool Oc Ns ... +.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns … +.Sy all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns … +.Oo Ar pool Oc Ns … .Nm zpool .Cm set .Ar property Ns = Ns Ar value .Ar pool +. .Sh DESCRIPTION .Bl -tag -width Ds .It Xo .Nm zpool .Cm get .Op Fl Hp -.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns ... -.Sy all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns ... -.Oo Ar pool Oc Ns ... +.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns … +.Sy all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns … +.Oo Ar pool Oc Ns … .Xc Retrieves the given list of properties .Po @@ -62,25 +63,29 @@ is used .Pc for the specified storage pool(s). These properties are displayed with the following fields: -.Bd -literal - name Name of storage pool - property Property name - value Property value - source Property source, either 'default' or 'local'. -.Ed +.Bl -tag -compact -offset Ds -width "property" +.It Sy name +Name of storage pool. +.It Sy property +Property name. +.It Sy value +Property value. +.It Sy source +Property source, either +.Sy default No or Sy local . +.El .Pp See the -.Xr zpoolprops +.Xr zpoolprops 8 manual page for more information on the available pool properties. -.Bl -tag -width Ds +.Bl -tag -compact -offset Ds -width "-o field" .It Fl H Scripted mode. Do not display headers, and separate fields by a single tab instead of arbitrary space. .It Fl o Ar field -A comma-separated list of columns to display. -.Sy name Ns \&, Ns Sy property Ns \&, Ns Sy value Ns \&, Ns Sy source -is the default value. +A comma-separated list of columns to display, defaults to +.Sy name , Ns Sy property , Ns Sy value , Ns Sy source . .It Fl p Display numbers in parsable (exact) values. .El @@ -92,11 +97,12 @@ Display numbers in parsable (exact) values. .Xc Sets the given property on the specified pool. See the -.Xr zpoolprops +.Xr zpoolprops 8 manual page for more information on what properties can be set and acceptable values. .El +. .Sh SEE ALSO -.Xr zpoolprops 8 , +.Xr zpool-features 5 , .Xr zpool-list 8 , -.Xr zpool-features 5 +.Xr zpoolprops 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-history.8 b/sys/contrib/openzfs/man/man8/zpool-history.8 index 5b0a102f382..2a2d500b8b8 100644 --- a/sys/contrib/openzfs/man/man8/zpool-history.8 +++ b/sys/contrib/openzfs/man/man8/zpool-history.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -30,22 +29,17 @@ .Dd August 9, 2019 .Dt ZPOOL-HISTORY 8 .Os +. .Sh NAME .Nm zpool-history -.Nd Displays the command history of the specified ZFS storage pool(s) +.Nd inspect command history of ZFS storage pools .Sh SYNOPSIS .Nm zpool .Cm history .Op Fl il -.Oo Ar pool Oc Ns ... +.Oo Ar pool Oc Ns … +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm history -.Op Fl il -.Oo Ar pool Oc Ns ... -.Xc Displays the command history of the specified pool(s) or all pools if no pool is specified. .Bl -tag -width Ds @@ -56,7 +50,7 @@ Displays log records in long format, which in addition to standard format includes, the user name, the hostname, and the zone in which the operation was performed. .El -.El +. .Sh SEE ALSO .Xr zpool-checkpoint 8 , .Xr zpool-events 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-import.8 b/sys/contrib/openzfs/man/man8/zpool-import.8 index ac349574309..1b1f3c5ae5b 100644 --- a/sys/contrib/openzfs/man/man8/zpool-import.8 +++ b/sys/contrib/openzfs/man/man8/zpool-import.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -30,50 +29,53 @@ .Dd August 9, 2019 .Dt ZPOOL-IMPORT 8 .Os +. .Sh NAME .Nm zpool-import -.Nd Lists ZFS storage pools available to import or import the specified pools +.Nd import ZFS storage pools or list available pools .Sh SYNOPSIS .Nm zpool .Cm import .Op Fl D -.Op Fl d Ar dir Ns | Ns device +.Oo Fl d Ar dir Ns | Ns Ar device Oc Ns … .Nm zpool .Cm import .Fl a .Op Fl DflmN -.Op Fl F Oo Fl n Oc Oo Fl T Oc Oo Fl X Oc +.Op Fl F Op Fl nTX .Op Fl -rewind-to-checkpoint -.Op Fl c Ar cachefile Ns | Ns Fl d Ar dir Ns | Ns device +.Op Fl c Ar cachefile Ns | Ns Fl d Ar dir Ns | Ns Ar device .Op Fl o Ar mntopts -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... +.Oo Fl o Ar property Ns = Ns Ar value Oc Ns … .Op Fl R Ar root .Nm zpool .Cm import -.Op Fl Dflm -.Op Fl F Oo Fl n Oc Oo Fl T Oc Oo Fl X Oc +.Op Fl Dflmt +.Op Fl F Op Fl nTX .Op Fl -rewind-to-checkpoint -.Op Fl c Ar cachefile Ns | Ns Fl d Ar dir Ns | Ns device +.Op Fl c Ar cachefile Ns | Ns Fl d Ar dir Ns | Ns Ar device .Op Fl o Ar mntopts -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... +.Oo Fl o Ar property Ns = Ns Ar value Oc Ns … .Op Fl R Ar root .Op Fl s .Ar pool Ns | Ns Ar id -.Op Ar newpool Oo Fl t Oc +.Op Ar newpool +. .Sh DESCRIPTION .Bl -tag -width Ds .It Xo .Nm zpool .Cm import .Op Fl D -.Op Fl d Ar dir Ns | Ns device +.Oo Fl d Ar dir Ns | Ns Ar device Oc Ns … .Xc Lists pools available to import. If the .Fl d or .Fl c options are not specified, this command searches for devices using libblkid -on Linux and geom on FreeBSD. +on Linux and geom on +.Fx . The .Fl d option can be specified multiple times, and all directories are searched. @@ -114,10 +116,10 @@ Lists destroyed pools only. .Cm import .Fl a .Op Fl DflmN -.Op Fl F Oo Fl n Oc Oo Fl T Oc Oo Fl X Oc -.Op Fl c Ar cachefile Ns | Ns Fl d Ar dir Ns | Ns device +.Op Fl F Op Fl nTX +.Op Fl c Ar cachefile Ns | Ns Fl d Ar dir Ns | Ns Ar device .Op Fl o Ar mntopts -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... +.Oo Fl o Ar property Ns = Ns Ar value Oc Ns … .Op Fl R Ar root .Op Fl s .Xc @@ -168,12 +170,13 @@ If successful, the data from the discarded transactions is irretrievably lost. This option is ignored if the pool is importable or already imported. .It Fl l Indicates that this command will request encryption keys for all encrypted -datasets it attempts to mount as it is bringing the pool online. Note that if -any datasets have a +datasets it attempts to mount as it is bringing the pool online. +Note that if any datasets have a .Sy keylocation of .Sy prompt -this command will block waiting for the keys to be entered. Without this flag +this command will block waiting for the keys to be entered. +Without this flag encrypted datasets will be left unavailable until the keys are loaded. .It Fl m Allows a pool to import when there is a missing log device. @@ -198,7 +201,7 @@ for a description of dataset properties and mount options. .It Fl o Ar property Ns = Ns Ar value Sets the specified property on the imported pool. See the -.Xr zpoolprops +.Xr zpoolprops 8 manual page for more information on the available pool properties. .It Fl R Ar root Sets the @@ -221,36 +224,42 @@ administrator can see how the pool would look like if they were to fully rewind. .It Fl s Scan using the default search path, the libblkid cache will not be -consulted. A custom search path may be specified by setting the -ZPOOL_IMPORT_PATH environment variable. +consulted. +A custom search path may be specified by setting the +.Sy ZPOOL_IMPORT_PATH +environment variable. .It Fl X Used with the .Fl F -recovery option. Determines whether extreme -measures to find a valid txg should take place. This allows the pool to +recovery option. +Determines whether extreme measures to find a valid txg should take place. +This allows the pool to be rolled back to a txg which is no longer guaranteed to be consistent. -Pools imported at an inconsistent txg may contain uncorrectable -checksum errors. For more details about pool recovery mode, see the +Pools imported at an inconsistent txg may contain uncorrectable checksum errors. +For more details about pool recovery mode, see the .Fl F -option, above. WARNING: This option can be extremely hazardous to the +option, above. +WARNING: This option can be extremely hazardous to the health of your pool and should only be used as a last resort. .It Fl T -Specify the txg to use for rollback. Implies +Specify the txg to use for rollback. +Implies .Fl FX . For more details about pool recovery mode, see the .Fl X -option, above. WARNING: This option can be extremely hazardous to the +option, above. +WARNING: This option can be extremely hazardous to the health of your pool and should only be used as a last resort. .El .It Xo .Nm zpool .Cm import -.Op Fl Dflm -.Op Fl F Oo Fl n Oc Oo Fl t Oc Oo Fl T Oc Oo Fl X Oc -.Op Fl c Ar cachefile Ns | Ns Fl d Ar dir Ns | Ns device +.Op Fl Dflmt +.Op Fl F Op Fl nTX +.Op Fl c Ar cachefile Ns | Ns Fl d Ar dir Ns | Ns Ar device .Op Fl o Ar mntopts -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... +.Oo Fl o Ar property Ns = Ns Ar value Oc Ns … .Op Fl R Ar root .Op Fl s .Ar pool Ns | Ns Ar id @@ -309,12 +318,13 @@ If successful, the data from the discarded transactions is irretrievably lost. This option is ignored if the pool is importable or already imported. .It Fl l Indicates that this command will request encryption keys for all encrypted -datasets it attempts to mount as it is bringing the pool online. Note that if -any datasets have a +datasets it attempts to mount as it is bringing the pool online. +Note that if any datasets have a .Sy keylocation of .Sy prompt -this command will block waiting for the keys to be entered. Without this flag +this command will block waiting for the keys to be entered. +Without this flag encrypted datasets will be left unavailable until the keys are loaded. .It Fl m Allows a pool to import when there is a missing log device. @@ -337,7 +347,7 @@ for a description of dataset properties and mount options. .It Fl o Ar property Ns = Ns Ar value Sets the specified property on the imported pool. See the -.Xr zpoolprops +.Xr zpoolprops 8 manual page for more information on the available pool properties. .It Fl R Ar root Sets the @@ -350,38 +360,49 @@ property to .Ar root . .It Fl s Scan using the default search path, the libblkid cache will not be -consulted. A custom search path may be specified by setting the -ZPOOL_IMPORT_PATH environment variable. +consulted. +A custom search path may be specified by setting the +.Sy ZPOOL_IMPORT_PATH +environment variable. .It Fl X Used with the .Fl F -recovery option. Determines whether extreme -measures to find a valid txg should take place. This allows the pool to +recovery option. +Determines whether extreme measures to find a valid txg should take place. +This allows the pool to be rolled back to a txg which is no longer guaranteed to be consistent. Pools imported at an inconsistent txg may contain uncorrectable -checksum errors. For more details about pool recovery mode, see the +checksum errors. +For more details about pool recovery mode, see the .Fl F -option, above. WARNING: This option can be extremely hazardous to the +option, above. +WARNING: This option can be extremely hazardous to the health of your pool and should only be used as a last resort. .It Fl T -Specify the txg to use for rollback. Implies +Specify the txg to use for rollback. +Implies .Fl FX . For more details about pool recovery mode, see the .Fl X -option, above. WARNING: This option can be extremely hazardous to the +option, above. +WARNING: This option can be extremely hazardous to the health of your pool and should only be used as a last resort. .It Fl t Used with .Sy newpool . Specifies that .Sy newpool -is temporary. Temporary pool names last until export. Ensures that -the original pool name will be used in all label updates and therefore -is retained upon export. -Will also set -o cachefile=none when not explicitly specified. +is temporary. +Temporary pool names last until export. +Ensures that the original pool name will be used +in all label updates and therefore is retained upon export. +Will also set +.Fl o Sy cachefile Ns = Ns Sy none +when not explicitly specified. .El .El +. .Sh SEE ALSO .Xr zpool-export 8 , .Xr zpool-list 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-initialize.8 b/sys/contrib/openzfs/man/man8/zpool-initialize.8 index 2734c1b340b..0a108180dbb 100644 --- a/sys/contrib/openzfs/man/man8/zpool-initialize.8 +++ b/sys/contrib/openzfs/man/man8/zpool-initialize.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,40 +26,33 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd May 27, 2021 .Dt ZPOOL-INITIALIZE 8 .Os +. .Sh NAME .Nm zpool-initialize -.Nd Write to all unallocated regions of eligible devices in a ZFS storage pool +.Nd write to unallocated regions of ZFS storage pool .Sh SYNOPSIS .Nm zpool .Cm initialize -.Op Fl c | Fl s +.Op Fl c Ns | Ns Fl s .Op Fl w .Ar pool -.Op Ar device Ns ... +.Oo Ar device Oc Ns … +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm initialize -.Op Fl c | Fl s -.Op Fl w -.Ar pool -.Op Ar device Ns ... -.Xc Begins initializing by writing to all unallocated regions on the specified devices, or all eligible devices in the pool if no individual devices are specified. Only leaf data or log devices may be initialized. .Bl -tag -width Ds -.It Fl c, -cancel +.It Fl c , -cancel Cancel initializing on the specified devices, or all eligible devices if none are specified. If one or more target devices are invalid or are not currently being initialized, the command will fail and no cancellation will occur on any device. -.It Fl s -suspend +.It Fl s , -suspend Suspend initializing on the specified devices, or all eligible devices if none are specified. If one or more target devices are invalid or are not currently being @@ -68,10 +60,10 @@ initialized, the command will fail and no suspension will occur on any device. Initializing can then be resumed by running .Nm zpool Cm initialize with no flags on the relevant target devices. -.It Fl w, -wait +.It Fl w , -wait Wait until the devices have finished initializing before returning. .El -.El +. .Sh SEE ALSO .Xr zpool-add 8 , .Xr zpool-attach 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-iostat.8 b/sys/contrib/openzfs/man/man8/zpool-iostat.8 index e457eb142ab..0e64aa71b1d 100644 --- a/sys/contrib/openzfs/man/man8/zpool-iostat.8 +++ b/sys/contrib/openzfs/man/man8/zpool-iostat.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,79 +26,85 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd May 27, 2021 .Dt ZPOOL-IOSTAT 8 .Os +. .Sh NAME .Nm zpool-iostat -.Nd Display logical I/O statistics for the given ZFS storage pools/vdevs +.Nd display logical I/O statistics for ZFS storage pools .Sh SYNOPSIS .Nm zpool .Cm iostat .Op Oo Oo Fl c Ar SCRIPT Oc Oo Fl lq Oc Oc Ns | Ns Fl rw .Op Fl T Sy u Ns | Ns Sy d .Op Fl ghHLnpPvy -.Oo Oo Ar pool Ns ... Oc Ns | Ns Oo Ar pool vdev Ns ... Oc Ns | Ns Oo Ar vdev Ns ... Oc Oc +.Oo Ar pool Ns … Ns | Ns Oo Ar pool vdev Ns … Oc Ns | Ns Ar vdev Ns … Oc .Op Ar interval Op Ar count +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm iostat -.Op Oo Oo Fl c Ar SCRIPT Oc Oo Fl lq Oc Oc Ns | Ns Fl rw -.Op Fl T Sy u Ns | Ns Sy d -.Op Fl ghHLnpPvy -.Oo Oo Ar pool Ns ... Oc Ns | Ns Oo Ar pool vdev Ns ... Oc Ns | Ns Oo Ar vdev Ns ... Oc Oc -.Op Ar interval Op Ar count -.Xc -Displays logical I/O statistics for the given pools/vdevs. Physical I/Os may -be observed via +Displays logical I/O statistics for the given pools/vdevs. +Physical I/O statistics may be observed via .Xr iostat 1 . If writes are located nearby, they may be merged into a single -larger operation. Additional I/O may be generated depending on the level of -vdev redundancy. +larger operation. +Additional I/O may be generated depending on the level of vdev redundancy. To filter output, you may pass in a list of pools, a pool and list of vdevs -in that pool, or a list of any vdevs from any pool. If no items are specified, -statistics for every pool in the system are shown. +in that pool, or a list of any vdevs from any pool. +If no items are specified, statistics for every pool in the system are shown. When given an .Ar interval , the statistics are printed every .Ar interval -seconds until ^C is pressed. If +seconds until killed. +If .Fl n flag is specified the headers are displayed only once, otherwise they are -displayed periodically. If count is specified, the command exits -after count reports are printed. The first report printed is always -the statistics since boot regardless of whether +displayed periodically. +If +.Ar count +is specified, the command exits after +.Ar count +reports are printed. +The first report printed is always the statistics since boot regardless of whether .Ar interval and .Ar count -are passed. However, this behavior can be suppressed with the +are passed. +However, this behavior can be suppressed with the .Fl y -flag. Also note that the units of +flag. +Also note that the units of .Sy K , .Sy M , -.Sy G ... -that are printed in the report are in base 1024. To get the raw -values, use the +.Sy G Ns … +that are printed in the report are in base 1024. +To get the raw values, use the .Fl p flag. .Bl -tag -width Ds -.It Fl c Op Ar SCRIPT1 Ns Oo , Ns Ar SCRIPT2 Oc Ns ... +.It Fl c Op Ar SCRIPT1 Ns Oo , Ns Ar SCRIPT2 Oc Ns … Run a script (or scripts) on each vdev and include the output as a new column in the .Nm zpool Cm iostat -output. Users can run any script found in their +output. +Users can run any script found in their .Pa ~/.zpool.d directory or from the system .Pa /etc/zfs/zpool.d -directory. Script names containing the slash (/) character are not allowed. +directory. +Script names containing the slash +.Pq Sy / +character are not allowed. The default search path can be overridden by setting the -ZPOOL_SCRIPTS_PATH environment variable. A privileged user can run +.Sy ZPOOL_SCRIPTS_PATH +environment variable. +A privileged user can only run .Fl c -if they have the ZPOOL_SCRIPTS_AS_ROOT -environment variable set. If a script requires the use of a privileged -command, like +if they have the +.Sy ZPOOL_SCRIPTS_AS_ROOT +environment variable set. +If a script requires the use of a privileged command, like .Xr smartctl 8 , then it's recommended you allow the user access to it in .Pa /etc/sudoers @@ -114,25 +119,23 @@ is passed without a script name, it prints a list of all scripts. also sets verbose mode .No \&( Ns Fl v Ns No \&). .Pp -Script output should be in the form of "name=value". The column name is -set to "name" and the value is set to "value". Multiple lines can be -used to output multiple columns. The first line of output not in the -"name=value" format is displayed without a column title, and no more -output after that is displayed. This can be useful for printing error -messages. Blank or NULL values are printed as a '-' to make output -awk-able. +Script output should be in the form of "name=value". +The column name is set to "name" and the value is set to "value". +Multiple lines can be used to output multiple columns. +The first line of output not in the +"name=value" format is displayed without a column title, +and no more output after that is displayed. +This can be useful for printing error messages. +Blank or NULL values are printed as a '-' to make output AWKable. .Pp The following environment variables are set before running each script: -.Bl -tag -width "VDEV_PATH" +.Bl -tag -compact -width "VDEV_ENC_SYSFS_PATH" .It Sy VDEV_PATH Full path to the vdev -.El -.Bl -tag -width "VDEV_UPATH" .It Sy VDEV_UPATH -Underlying path to the vdev (/dev/sd*). For use with device mapper, -multipath, or partitioned vdevs. -.El -.Bl -tag -width "VDEV_ENC_SYSFS_PATH" +Underlying path to the vdev +.Pq Pa /dev/sd* . +For use with device mapper, multipath, or partitioned vdevs. .It Sy VDEV_ENC_SYSFS_PATH The sysfs path to the enclosure for the vdev (if any). .El @@ -149,99 +152,106 @@ for standard date format. See .Xr date 1 . .It Fl g -Display vdev GUIDs instead of the normal device names. These GUIDs -can be used in place of device names for the zpool +Display vdev GUIDs instead of the normal device names. +These GUIDs can be used in place of device names for the zpool detach/offline/remove/replace commands. .It Fl H -Scripted mode. Do not display headers, and separate fields by a +Scripted mode. +Do not display headers, and separate fields by a single tab instead of arbitrary space. .It Fl L -Display real paths for vdevs resolving all symbolic links. This can -be used to look up the current block device name regardless of the +Display real paths for vdevs resolving all symbolic links. +This can be used to look up the current block device name regardless of the .Pa /dev/disk/ path used to open it. .It Fl n Print headers only once when passed .It Fl p -Display numbers in parsable (exact) values. Time values are in -nanoseconds. +Display numbers in parsable (exact) values. +Time values are in nanoseconds. .It Fl P -Display full paths for vdevs instead of only the last component of -the path. This can be used in conjunction with the +Display full paths for vdevs instead of only the last component of the path. +This can be used in conjunction with the .Fl L flag. .It Fl r -Print request size histograms for the leaf vdev's IO. This includes -histograms of individual IOs (ind) and aggregate IOs (agg). These stats -can be useful for observing how well IO aggregation is working. Note -that TRIM IOs may exceed 16M, but will be counted as 16M. +Print request size histograms for the leaf vdev's I/O. +This includes histograms of individual I/O (ind) and aggregate I/O (agg). +These stats can be useful for observing how well I/O aggregation is working. +Note that TRIM I/O may exceed 16M, but will be counted as 16M. .It Fl v Verbose statistics Reports usage statistics for individual vdevs within the pool, in addition to the pool-wide statistics. .It Fl y -Omit statistics since boot. -Normally the first line of output reports the statistics since boot. -This option suppresses that first line of output. -.Ar interval +Normally the first line of output reports the statistics since boot: +suppress it. .It Fl w Display latency histograms: -.Pp -.Ar total_wait : -Total IO time (queuing + disk IO time). -.Ar disk_wait : -Disk IO time (time reading/writing the disk). -.Ar syncq_wait : -Amount of time IO spent in synchronous priority queues. Does not include -disk time. -.Ar asyncq_wait : -Amount of time IO spent in asynchronous priority queues. Does not include -disk time. -.Ar scrub : -Amount of time IO spent in scrub queue. Does not include disk time. +.Bl -tag -compact -width "asyncq_read/write" +.It Sy total_wait +Total I/O time (queuing + disk I/O time). +.It Sy disk_wait +Disk I/O time (time reading/writing the disk). +.It Sy syncq_wait +Amount of time I/O spent in synchronous priority queues. +Does not include disk time. +.It Sy asyncq_wait +Amount of time I/O spent in asynchronous priority queues. +Does not include disk time. +.It Sy scrub +Amount of time I/O spent in scrub queue. +Does not include disk time. +.El .It Fl l Include average latency statistics: -.Pp -.Ar total_wait : -Average total IO time (queuing + disk IO time). -.Ar disk_wait : -Average disk IO time (time reading/writing the disk). -.Ar syncq_wait : -Average amount of time IO spent in synchronous priority queues. Does -not include disk time. -.Ar asyncq_wait : -Average amount of time IO spent in asynchronous priority queues. +.Bl -tag -compact -width "asyncq_read/write" +.It Sy total_wait +Average total I/O time (queuing + disk I/O time). +.It Sy disk_wait +Average disk I/O time (time reading/writing the disk). +.It Sy syncq_wait +Average amount of time I/O spent in synchronous priority queues. Does not include disk time. -.Ar scrub : -Average queuing time in scrub queue. Does not include disk time. -.Ar trim : -Average queuing time in trim queue. Does not include disk time. +.It Sy asyncq_wait +Average amount of time I/O spent in asynchronous priority queues. +Does not include disk time. +.It Sy scrub +Average queuing time in scrub queue. +Does not include disk time. +.It Sy trim +Average queuing time in trim queue. +Does not include disk time. +.El .It Fl q -Include active queue statistics. Each priority queue has both -pending ( -.Ar pend ) -and active ( -.Ar activ ) -IOs. Pending IOs are waiting to -be issued to the disk, and active IOs have been issued to disk and are -waiting for completion. These stats are broken out by priority queue: -.Pp -.Ar syncq_read/write : +Include active queue statistics. +Each priority queue has both pending +.Sy ( pend ) +and active +.Sy ( activ ) +I/O requests. +Pending requests are waiting to be issued to the disk, +and active requests have been issued to disk and are waiting for completion. +These stats are broken out by priority queue: +.Bl -tag -compact -width "asyncq_read/write" +.It Sy syncq_read/write Current number of entries in synchronous priority queues. -.Ar asyncq_read/write : +.It Sy asyncq_read/write Current number of entries in asynchronous priority queues. -.Ar scrubq_read : +.It Sy scrubq_read Current number of entries in scrub queue. -.Ar trimq_write : +.It Sy trimq_write Current number of entries in trim queue. +.El .Pp All queue statistics are instantaneous measurements of the number of -entries in the queues. If you specify an interval, the measurements -will be sampled from the end of the interval. -.El +entries in the queues. +If you specify an interval, +the measurements will be sampled from the end of the interval. .El +. .Sh SEE ALSO -.Xr zpool-list 8 , -.Xr zpool-status 8 , .Xr iostat 1 , -.Xr smartctl 8 +.Xr smartctl 8 , +.Xr zpool-list 8 , +.Xr zpool-status 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-labelclear.8 b/sys/contrib/openzfs/man/man8/zpool-labelclear.8 index 576eee21c50..c7edc911604 100644 --- a/sys/contrib/openzfs/man/man8/zpool-labelclear.8 +++ b/sys/contrib/openzfs/man/man8/zpool-labelclear.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,25 +26,20 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd May 31, 2021 .Dt ZPOOL-LABELCLEAR 8 .Os +. .Sh NAME .Nm zpool-labelclear -.Nd Removes ZFS label information from the specified physical device +.Nd remove ZFS label information from device .Sh SYNOPSIS .Nm zpool .Cm labelclear .Op Fl f .Ar device +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm labelclear -.Op Fl f -.Ar device -.Xc Removes ZFS label information from the specified .Ar device . If the @@ -58,7 +52,7 @@ must not be part of an active pool configuration. .It Fl f Treat exported or foreign devices as inactive. .El -.El +. .Sh SEE ALSO .Xr zpool-destroy 8 , .Xr zpool-detach 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-list.8 b/sys/contrib/openzfs/man/man8/zpool-list.8 index 068a6889346..3dec7370c5e 100644 --- a/sys/contrib/openzfs/man/man8/zpool-list.8 +++ b/sys/contrib/openzfs/man/man8/zpool-list.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -30,28 +29,20 @@ .Dd August 9, 2019 .Dt ZPOOL-LIST 8 .Os +. .Sh NAME .Nm zpool-list -.Nd Lists ZFS storage pools along with a health status and space usage +.Nd list information about ZFS storage pools .Sh SYNOPSIS .Nm zpool .Cm list .Op Fl HgLpPv -.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ... +.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns … .Op Fl T Sy u Ns | Ns Sy d -.Oo Ar pool Oc Ns ... +.Oo Ar pool Oc Ns … .Op Ar interval Op Ar count +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm list -.Op Fl HgLpPv -.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ... -.Op Fl T Sy u Ns | Ns Sy d -.Oo Ar pool Oc Ns ... -.Op Ar interval Op Ar count -.Xc Lists the given pools along with a health status and space usage. If no .Ar pool Ns s @@ -60,7 +51,7 @@ When given an .Ar interval , the information is printed every .Ar interval -seconds until ^C is pressed. +seconds until killed. If .Ar count is specified, the command exits after @@ -68,8 +59,8 @@ is specified, the command exits after reports are printed. .Bl -tag -width Ds .It Fl g -Display vdev GUIDs instead of the normal device names. These GUIDs -can be used in place of device names for the zpool +Display vdev GUIDs instead of the normal device names. +These GUIDs can be used in place of device names for the zpool detach/offline/remove/replace commands. .It Fl H Scripted mode. @@ -78,22 +69,24 @@ space. .It Fl o Ar property Comma-separated list of properties to display. See the -.Xr zpoolprops +.Xr zpoolprops 8 manual page for a list of valid properties. The default list is -.Cm name , size , allocated , free , checkpoint, expandsize , fragmentation , -.Cm capacity , dedupratio , health , altroot . +.Sy name , size , allocated , free , checkpoint, expandsize , fragmentation , +.Sy capacity , dedupratio , health , altroot . .It Fl L -Display real paths for vdevs resolving all symbolic links. This can -be used to look up the current block device name regardless of the -/dev/disk/ path used to open it. +Display real paths for vdevs resolving all symbolic links. +This can be used to look up the current block device name regardless of the +.Pa /dev/disk +path used to open it. .It Fl p Display numbers in parsable .Pq exact values. .It Fl P Display full paths for vdevs instead of only the last component of -the path. This can be used in conjunction with the +the path. +This can be used in conjunction with the .Fl L flag. .It Fl T Sy u Ns | Ns Sy d @@ -113,7 +106,7 @@ Verbose statistics. Reports usage statistics for individual vdevs within the pool, in addition to the pool-wide statistics. .El -.El +. .Sh SEE ALSO .Xr zpool-import 8 , .Xr zpool-status 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-offline.8 b/sys/contrib/openzfs/man/man8/zpool-offline.8 index 3bf3bae7254..9b2cf59cf41 100644 --- a/sys/contrib/openzfs/man/man8/zpool-offline.8 +++ b/sys/contrib/openzfs/man/man8/zpool-offline.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -30,27 +29,30 @@ .Dd August 9, 2019 .Dt ZPOOL-OFFLINE 8 .Os +. .Sh NAME .Nm zpool-offline -.Nd Take a physical device in a ZFS storage pool offline +.Nd take physical devices offline in ZFS storage pool .Sh SYNOPSIS .Nm zpool .Cm offline -.Op Fl f -.Op Fl t -.Ar pool Ar device Ns ... +.Op Fl ft +.Ar pool +.Ar device Ns … .Nm zpool .Cm online .Op Fl e -.Ar pool Ar device Ns ... +.Ar pool +.Ar device Ns … +. .Sh DESCRIPTION .Bl -tag -width Ds .It Xo .Nm zpool .Cm offline -.Op Fl f -.Op Fl t -.Ar pool Ar device Ns ... +.Op Fl ft +.Ar pool +.Ar device Ns … .Xc Takes the specified physical device offline. While the @@ -59,8 +61,9 @@ is offline, no attempt is made to read or write to the device. This command is not applicable to spares. .Bl -tag -width Ds .It Fl f -Force fault. Instead of offlining the disk, put it into a faulted -state. The fault will persist across imports unless the +Force fault. +Instead of offlining the disk, put it into a faulted state. +The fault will persist across imports unless the .Fl t flag was specified. .It Fl t @@ -71,7 +74,8 @@ Upon reboot, the specified physical device reverts to its previous state. .Nm zpool .Cm online .Op Fl e -.Ar pool Ar device Ns ... +.Ar pool +.Ar device Ns … .Xc Brings the specified physical device online. This command is not applicable to spares. @@ -82,6 +86,7 @@ If the device is part of a mirror or raidz then all devices must be expanded before the new space will become available to the pool. .El .El +. .Sh SEE ALSO .Xr zpool-detach 8 , .Xr zpool-remove 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-reguid.8 b/sys/contrib/openzfs/man/man8/zpool-reguid.8 index f5c4a33f694..7bb7c1c726b 100644 --- a/sys/contrib/openzfs/man/man8/zpool-reguid.8 +++ b/sys/contrib/openzfs/man/man8/zpool-reguid.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,27 +26,23 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd May 31, 2021 .Dt ZPOOL-REGUID 8 .Os +. .Sh NAME .Nm zpool-reguid -.Nd Generate a new unique identifier for a ZFS storage pool +.Nd generate new unique identifier for ZFS storage pool .Sh SYNOPSIS .Nm zpool .Cm reguid .Ar pool +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm reguid -.Ar pool -.Xc Generates a new unique identifier for the pool. You must ensure that all devices in this pool are online and healthy before performing this action. -.El +. .Sh SEE ALSO .Xr zpool-export 8 , .Xr zpool-import 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-remove.8 b/sys/contrib/openzfs/man/man8/zpool-remove.8 index f491cd40ac5..5d866cb50d4 100644 --- a/sys/contrib/openzfs/man/man8/zpool-remove.8 +++ b/sys/contrib/openzfs/man/man8/zpool-remove.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -32,12 +31,12 @@ .Os .Sh NAME .Nm zpool-remove -.Nd Remove a device from a ZFS storage pool +.Nd remove devices from ZFS storage pool .Sh SYNOPSIS .Nm zpool .Cm remove .Op Fl npw -.Ar pool Ar device Ns ... +.Ar pool Ar device Ns … .Nm zpool .Cm remove .Fl s @@ -48,7 +47,7 @@ .Nm zpool .Cm remove .Op Fl npw -.Ar pool Ar device Ns ... +.Ar pool Ar device Ns … .Xc Removes the specified device from the pool. This command supports removing hot spare, cache, log, and both mirrored and @@ -57,7 +56,7 @@ 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 +.Pp 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 the other devices in the pool. @@ -67,8 +66,8 @@ command initiates the removal and returns, while the evacuation continues in the background. The removal progress can be monitored with .Nm zpool Cm status . -If an IO error is encountered during the removal process it will be -cancelled. The +If an IO error is encountered during the removal process it will be cancelled. +The .Sy device_removal feature flag must be enabled to remove a top-level vdev, see .Xr zpool-features 5 . @@ -81,7 +80,8 @@ the command. .Bl -tag -width Ds .It Fl n -Do not actually perform the removal ("no-op"). +Do not actually perform the removal +.Pq Qq No-op . Instead, print the estimated amount of memory that will be used by the mapping table after the removal completes. This is nonzero only for top-level vdevs. @@ -105,7 +105,7 @@ Stops and cancels an in-progress removal of a top-level vdev. .Sh SEE ALSO .Xr zpool-add 8 , .Xr zpool-detach 8 , -.Xr zpool-offline 8 , .Xr zpool-labelclear 8 , +.Xr zpool-offline 8 , .Xr zpool-replace 8 , .Xr zpool-split 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-reopen.8 b/sys/contrib/openzfs/man/man8/zpool-reopen.8 index 6f804cc7e5f..f1f8606f12c 100644 --- a/sys/contrib/openzfs/man/man8/zpool-reopen.8 +++ b/sys/contrib/openzfs/man/man8/zpool-reopen.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,29 +26,27 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd June 2, 2021 .Dt ZPOOL-REOPEN 8 .Os +. .Sh NAME .Nm zpool-reopen -.Nd Reopen all virtual devices (vdevs) associated with a ZFS storage pool +.Nd reopen vdevs associated with ZFS storage pools .Sh SYNOPSIS .Nm zpool .Cm reopen .Op Fl n -.Ar pool +.Oo Ar pool Oc Ns … +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm reopen -.Op Fl n -.Ar pool -.Xc -Reopen all the vdevs associated with the pool. -.Bl -tag -width Ds +Reopen all vdevs associated with the specified pools, +or all pools if none specified. +. +.Sh OPTIONS +.Bl -tag -width "-n" .It Fl n -Do not restart an in-progress scrub operation. This is not recommended and can +Do not restart an in-progress scrub operation. +This is not recommended and can result in partially resilvered devices unless a second scrub is performed. .El -.El diff --git a/sys/contrib/openzfs/man/man8/zpool-replace.8 b/sys/contrib/openzfs/man/man8/zpool-replace.8 index b8527a3862c..eadb5681895 100644 --- a/sys/contrib/openzfs/man/man8/zpool-replace.8 +++ b/sys/contrib/openzfs/man/man8/zpool-replace.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,48 +26,42 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd May 15, 2020 +.Dd May 29, 2021 .Dt ZPOOL-REPLACE 8 .Os +. .Sh NAME .Nm zpool-replace -.Nd Replace one device with another in a ZFS storage pool +.Nd replace one device with another in ZFS storage pool .Sh SYNOPSIS .Nm zpool .Cm replace .Op Fl fsw .Oo Fl o Ar property Ns = Ns Ar value Oc -.Ar pool Ar device Op Ar new_device +.Ar pool Ar device Op Ar new-device +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm replace -.Op Fl fsw -.Op Fl o Ar property Ns = Ns Ar value -.Ar pool Ar device Op Ar new_device -.Xc Replaces -.Ar old_device +.Ar device with -.Ar new_device . +.Ar new-device . This is equivalent to attaching -.Ar new_device , +.Ar new-device , waiting for it to resilver, and then detaching -.Ar old_device . +.Ar device . Any in progress scrub will be cancelled. .Pp The size of -.Ar new_device +.Ar new-device must be greater than or equal to the minimum size of all the devices in a mirror or raidz configuration. .Pp -.Ar new_device +.Ar new-device is required if the pool is not redundant. If -.Ar new_device +.Ar new-device is not specified, it defaults to -.Ar old_device . +.Ar device . This form of replacement is useful after an existing disk has failed and has been physically replaced. In this case, the new disk may have the same @@ -78,18 +71,19 @@ ZFS recognizes this. .Bl -tag -width Ds .It Fl f Forces use of -.Ar new_device , +.Ar new-device , even if it appears to be in use. Not all devices can be overridden in this manner. .It Fl o Ar property Ns = Ns Ar value -Sets the given pool properties. See the -.Xr zpoolprops +Sets the given pool properties. +See the +.Xr zpoolprops 8 manual page for a list of valid properties that can be set. The only property supported at the moment is .Sy ashift . .It Fl s The -.Ar new_device +.Ar new-device is reconstructed sequentially to restore redundancy as quickly as possible. Checksums are not verfied during sequential reconstruction so a scrub is started when the resilver completes. @@ -97,7 +91,7 @@ Sequential reconstruction is not supported for raidz configurations. .It Fl w Waits until the replacement has completed before returning. .El -.El +. .Sh SEE ALSO .Xr zpool-detach 8 , .Xr zpool-initialize 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-resilver.8 b/sys/contrib/openzfs/man/man8/zpool-resilver.8 index 602e296fea1..1ef316ac182 100644 --- a/sys/contrib/openzfs/man/man8/zpool-resilver.8 +++ b/sys/contrib/openzfs/man/man8/zpool-resilver.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,29 +26,27 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd May 27, 2021 .Dt ZPOOL-RESILVER 8 .Os +. .Sh NAME .Nm zpool-resilver -.Nd Start a resilver of a device in a ZFS storage pool +.Nd resilver devices in ZFS storage pools .Sh SYNOPSIS .Nm zpool .Cm resilver -.Ar pool Ns ... +.Ar pool Ns … +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm resilver -.Ar pool Ns ... -.Xc -Starts a resilver. If an existing resilver is already running it will be -restarted from the beginning. Any drives that were scheduled for a deferred -resilver will be added to the new one. This requires the +Starts a resilver of the specified pools. +If an existing resilver is already running it will be restarted from the beginning. +Any drives that were scheduled for a deferred +resilver will be added to the new one. +This requires the .Sy resilver_defer -feature. -.El +pool feature. +. .Sh SEE ALSO .Xr zpool-iostat 8 , .Xr zpool-online 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-scrub.8 b/sys/contrib/openzfs/man/man8/zpool-scrub.8 index 6ff2eb26101..10375b6393a 100644 --- a/sys/contrib/openzfs/man/man8/zpool-scrub.8 +++ b/sys/contrib/openzfs/man/man8/zpool-scrub.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,27 +26,21 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd May 27, 2021 .Dt ZPOOL-SCRUB 8 .Os +. .Sh NAME .Nm zpool-scrub -.Nd Begin a scrub or resume a paused scrub of a ZFS storage pool +.Nd begin or resume scrub of ZFS storage pools .Sh SYNOPSIS .Nm zpool .Cm scrub -.Op Fl s | Fl p +.Op Fl s Ns | Ns Fl p .Op Fl w -.Ar pool Ns ... +.Ar pool Ns … +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm scrub -.Op Fl s | Fl p -.Op Fl w -.Ar pool Ns ... -.Xc Begins a scrub or resumes a paused scrub. The scrub examines all data in the specified pools to verify that it checksums correctly. @@ -78,13 +71,13 @@ If a resilver is in progress, ZFS does not allow a scrub to be started until the resilver completes. .Pp Note that, due to changes in pool data on a live system, it is possible for -scrubs to progress slightly beyond 100% completion. During this period, no -completion time estimate will be provided. -.Bl -tag -width Ds +scrubs to progress slightly beyond 100% completion. +During this period, no completion time estimate will be provided. +. +.Sh OPTIONS +.Bl -tag -width "-s" .It Fl s Stop scrubbing. -.El -.Bl -tag -width Ds .It Fl p Pause scrubbing. Scrub pause state and progress are periodically synced to disk. @@ -98,7 +91,7 @@ again. .It Fl w Wait until scrub has completed before returning. .El -.El +. .Sh SEE ALSO .Xr zpool-iostat 8 , .Xr zpool-resilver 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-split.8 b/sys/contrib/openzfs/man/man8/zpool-split.8 index 609cbe6bad2..7a1a13d5db4 100644 --- a/sys/contrib/openzfs/man/man8/zpool-split.8 +++ b/sys/contrib/openzfs/man/man8/zpool-split.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,31 +26,23 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd June 2, 2021 .Dt ZPOOL-SPLIT 8 .Os +. .Sh NAME .Nm zpool-split -.Nd Split devices off a ZFS storage pool creating a new pool +.Nd split devices off ZFS storage pool, creating new pool .Sh SYNOPSIS .Nm zpool .Cm split .Op Fl gLlnP -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... +.Oo Fl o Ar property Ns = Ns Ar value Oc Ns … .Op Fl R Ar root .Ar pool newpool -.Oo Ar device Oc Ns ... +.Oo Ar device Oc Ns … +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm split -.Op Fl gLlnP -.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... -.Op Fl R Ar root -.Ar pool newpool -.Op Ar device ... -.Xc Splits devices off .Ar pool creating @@ -76,37 +67,38 @@ and, should any devices remain unspecified, the last device in each mirror is used as would be by default. .Bl -tag -width Ds .It Fl g -Display vdev GUIDs instead of the normal device names. These GUIDs -can be used in place of device names for the zpool +Display vdev GUIDs instead of the normal device names. +These GUIDs can be used in place of device names for the zpool detach/offline/remove/replace commands. .It Fl L -Display real paths for vdevs resolving all symbolic links. This can -be used to look up the current block device name regardless of the +Display real paths for vdevs resolving all symbolic links. +This can be used to look up the current block device name regardless of the .Pa /dev/disk/ path used to open it. .It Fl l Indicates that this command will request encryption keys for all encrypted -datasets it attempts to mount as it is bringing the new pool online. Note that -if any datasets have a -.Sy keylocation -of -.Sy prompt -this command will block waiting for the keys to be entered. Without this flag -encrypted datasets will be left unavailable until the keys are loaded. +datasets it attempts to mount as it is bringing the new pool online. +Note that if any datasets have +.Sy keylocation Ns = Ns Sy prompt , +this command will block waiting for the keys to be entered. +Without this flag, encrypted datasets will be left unavailable until the keys are loaded. .It Fl n -Do dry run, do not actually perform the split. +Do a dry-run +.Pq Qq No-op +split: do not actually perform it. Print out the expected configuration of .Ar newpool . .It Fl P Display full paths for vdevs instead of only the last component of -the path. This can be used in conjunction with the +the path. +This can be used in conjunction with the .Fl L flag. .It Fl o Ar property Ns = Ns Ar value Sets the specified property for .Ar newpool . See the -.Xr zpoolprops +.Xr zpoolprops 8 manual page for more information on the available pool properties. .It Fl R Ar root Set @@ -117,7 +109,7 @@ to .Ar root and automatically import it. .El -.El +. .Sh SEE ALSO .Xr zpool-import 8 , .Xr zpool-list 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-status.8 b/sys/contrib/openzfs/man/man8/zpool-status.8 index 54f0987b80c..da5f95e29cd 100644 --- a/sys/contrib/openzfs/man/man8/zpool-status.8 +++ b/sys/contrib/openzfs/man/man8/zpool-status.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,37 +26,29 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd May 15, 2020 +.Dd June 2, 2021 .Dt ZPOOL-STATUS 8 .Os +. .Sh NAME .Nm zpool-status -.Nd Display detailed health status for the given ZFS storage pools +.Nd show detailed health status for ZFS storage pools .Sh SYNOPSIS .Nm zpool .Cm status -.Oo Fl c Ar SCRIPT Oc .Op Fl DigLpPstvx .Op Fl T Sy u Ns | Ns Sy d -.Oo Ar pool Oc Ns ... +.Op Fl c Op Ar SCRIPT1 Ns Oo , Ns Ar SCRIPT2 Oc Ns … +.Oo Ar pool Oc Ns … .Op Ar interval Op Ar count +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm status -.Op Fl c Op Ar SCRIPT1 Ns Oo , Ns Ar SCRIPT2 Oc Ns ... -.Op Fl DigLpPstvx -.Op Fl T Sy u Ns | Ns Sy d -.Oo Ar pool Oc Ns ... -.Op Ar interval Op Ar count -.Xc Displays the detailed health status for the given pools. If no .Ar pool is specified, then the status of each pool in the system is displayed. For more information on pool and device health, see the -.Em Device Failure and Recovery +.Sx Device Failure and Recovery section of .Xr zpoolconcepts 8 . .Pp @@ -66,11 +57,12 @@ and the estimated time to completion. Both of these are only approximate, because the amount of data in the pool and the other workloads on the system can change. .Bl -tag -width Ds -.It Fl c Op Ar SCRIPT1 Ns Oo , Ns Ar SCRIPT2 Oc Ns ... +.It Fl c Op Ar SCRIPT1 Ns Oo , Ns Ar SCRIPT2 Oc Ns … Run a script (or scripts) on each vdev and include the output as a new column in the .Nm zpool Cm status -output. See the +output. +See the .Fl c option of .Nm zpool Cm iostat @@ -78,19 +70,20 @@ for complete details. .It Fl i Display vdev initialization status. .It Fl g -Display vdev GUIDs instead of the normal device names. These GUIDs -can be used in place of device names for the zpool +Display vdev GUIDs instead of the normal device names +These GUIDs can be used in place of device names for the zpool detach/offline/remove/replace commands. .It Fl L -Display real paths for vdevs resolving all symbolic links. This can -be used to look up the current block device name regardless of the +Display real paths for vdevs resolving all symbolic links. +This can be used to look up the current block device name regardless of the .Pa /dev/disk/ path used to open it. .It Fl p Display numbers in parsable (exact) values. .It Fl P Display full paths for vdevs instead of only the last component of -the path. This can be used in conjunction with the +the path. +This can be used in conjunction with the .Fl L flag. .It Fl D @@ -100,11 +93,14 @@ and referenced .Pq logically referenced in the pool block counts and sizes by reference count. .It Fl s -Display the number of leaf VDEV slow IOs. This is the number of IOs that -didn't complete in \fBzio_slow_io_ms\fR milliseconds (default 30 seconds). +Display the number of leaf VDEV slow IOs. +This is the number of IOs that +didn't complete in +.Sy zio_slow_io_ms +milliseconds (default 30 seconds). This does not necessarily mean the IOs failed to complete, just took an -unreasonably long amount of time. This may indicate a problem with the -underlying storage. +unreasonably long amount of time. +This may indicate a problem with the underlying storage. .It Fl t Display vdev TRIM status. .It Fl T Sy u Ns | Ns Sy d @@ -127,7 +123,7 @@ Only display status for pools that are exhibiting errors or are otherwise unavailable. Warnings about pools not using the latest on-disk format will not be included. .El -.El +. .Sh SEE ALSO .Xr zpool-events 8 , .Xr zpool-history 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-sync.8 b/sys/contrib/openzfs/man/man8/zpool-sync.8 index 027d129d181..6d4aa2c29c4 100644 --- a/sys/contrib/openzfs/man/man8/zpool-sync.8 +++ b/sys/contrib/openzfs/man/man8/zpool-sync.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -30,28 +29,25 @@ .Dd August 9, 2019 .Dt ZPOOL-SYNC 8 .Os +. .Sh NAME .Nm zpool-sync -.Nd Force data to be written to primary storage of a ZFS storage pool and update reporting data +.Nd flush data to primary storage of ZFS storage pools .Sh SYNOPSIS .Nm zpool .Cm sync -.Oo Ar pool Oc Ns ... +.Oo Ar pool Oc Ns … +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm sync -.Op Ar pool ... -.Xc This command forces all in-core dirty data to be written to the primary -pool storage and not the ZIL. It will also update administrative -information including quota reporting. Without arguments, -.Sy zpool sync -will sync all pools on the system. Otherwise, it will sync only the -specified pool(s). -.El +pool storage and not the ZIL. +It will also update administrative information including quota reporting. +Without arguments, +.Nm zpool Cm sync +will sync all pools on the system. +Otherwise, it will sync only the specified pools. +. .Sh SEE ALSO -.Xr zpoolconcepts 8 , .Xr zpool-export 8 , -.Xr zpool-iostat 8 +.Xr zpool-iostat 8 , +.Xr zpoolconcepts 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-trim.8 b/sys/contrib/openzfs/man/man8/zpool-trim.8 index 1d8bc6e44a2..f709dd85414 100644 --- a/sys/contrib/openzfs/man/man8/zpool-trim.8 +++ b/sys/contrib/openzfs/man/man8/zpool-trim.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,56 +26,54 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd February 25, 2020 +.Dd May 27, 2021 .Dt ZPOOL-TRIM 8 .Os +. .Sh NAME .Nm zpool-trim -.Nd Initiate immediate TRIM operations for all free space in a ZFS storage pool +.Nd initiate TRIM of free space in ZFS storage pool .Sh SYNOPSIS .Nm zpool .Cm trim .Op Fl dw .Op Fl r Ar rate -.Op Fl c | Fl s +.Op Fl c Ns | Ns Fl s .Ar pool -.Op Ar device Ns ... +.Oo Ar device Ns Oc Ns … +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm trim -.Op Fl dw -.Op Fl c | Fl s -.Ar pool -.Op Ar device Ns ... -.Xc Initiates an immediate on-demand TRIM operation for all of the free space in -a pool. This operation informs the underlying storage devices of all blocks +a pool. +This operation informs the underlying storage devices of all blocks in the pool which are no longer allocated and allows thinly provisioned devices to reclaim the space. .Pp A manual on-demand TRIM operation can be initiated irrespective of the .Sy autotrim -pool property setting. See the documentation for the +pool property setting. +See the documentation for the .Sy autotrim property above for the types of vdev devices which can be trimmed. .Bl -tag -width Ds -.It Fl d -secure -Causes a secure TRIM to be initiated. When performing a secure TRIM, the +.It Fl d , -secure +Causes a secure TRIM to be initiated. +When performing a secure TRIM, the device guarantees that data stored on the trimmed blocks has been erased. This requires support from the device and is not supported by all SSDs. -.It Fl r -rate Ar rate -Controls the rate at which the TRIM operation progresses. Without this -option TRIM is executed as quickly as possible. The rate, expressed in bytes +.It Fl r , -rate Ar rate +Controls the rate at which the TRIM operation progresses. +Without this +option TRIM is executed as quickly as possible. +The rate, expressed in bytes per second, is applied on a per-vdev basis and may be set differently for each leaf vdev. -.It Fl c, -cancel +.It Fl c , -cancel Cancel trimming on the specified devices, or all eligible devices if none are specified. If one or more target devices are invalid or are not currently being trimmed, the command will fail and no cancellation will occur on any device. -.It Fl s -suspend +.It Fl s , -suspend Suspend trimming on the specified devices, or all eligible devices if none are specified. If one or more target devices are invalid or are not currently being @@ -84,10 +81,10 @@ trimmed, the command will fail and no suspension will occur on any device. Trimming can then be resumed by running .Nm zpool Cm trim with no flags on the relevant target devices. -.It Fl w -wait +.It Fl w , -wait Wait until the devices are done being trimmed before returning. .El -.El +. .Sh SEE ALSO .Xr zpool-initialize 8 , .Xr zpool-wait 8 , diff --git a/sys/contrib/openzfs/man/man8/zpool-upgrade.8 b/sys/contrib/openzfs/man/man8/zpool-upgrade.8 index face5b138ff..0e67e7884c7 100644 --- a/sys/contrib/openzfs/man/man8/zpool-upgrade.8 +++ b/sys/contrib/openzfs/man/man8/zpool-upgrade.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -31,9 +30,10 @@ .Dd August 9, 2019 .Dt ZPOOL-UPGRADE 8 .Os +. .Sh NAME .Nm zpool-upgrade -.Nd Manage version and feature flags of ZFS storage pools +.Nd manage version and feature flags of ZFS storage pools .Sh SYNOPSIS .Nm zpool .Cm upgrade @@ -43,7 +43,8 @@ .Nm zpool .Cm upgrade .Op Fl V Ar version -.Fl a Ns | Ns Ar pool Ns ... +.Fl a Ns | Ns Ar pool Ns … +. .Sh DESCRIPTION .Bl -tag -width Ds .It Xo @@ -55,31 +56,34 @@ formatted using a legacy ZFS version number. These pools can continue to be used, but some features may not be available. Use .Nm zpool Cm upgrade Fl a -to enable all features on all pools. (If a pool has specified compatibility -feature sets using the -.Fl o Ar compatibility -property, only the features present in all requested compatibility sets will -be enabled on that pool.) +to enable all features on all pools (subject to the +.Fl o Sy compatibility +property). .It Xo .Nm zpool .Cm upgrade .Fl v .Xc -Displays legacy ZFS versions supported by the current software. +Displays legacy ZFS versions supported by the this version of ZFS. See .Xr zpool-features 5 -for a description of feature flags features supported by the current software. +for a description of feature flags features supported by this version of ZFS. .It Xo .Nm zpool .Cm upgrade .Op Fl V Ar version -.Fl a Ns | Ns Ar pool Ns ... +.Fl a Ns | Ns Ar pool Ns … .Xc -Enables all supported features on the given pool. (If the pool has specified -compatibility feature sets using the -.Fl o Ar compatibility +Enables all supported features on the given pool. +.Pp +If the pool has specified compatibility feature sets using the +.Fl o Sy compatibility property, only the features present in all requested compatibility sets will be -enabled.) +enabled. +If this property is set to +.Ar legacy +then no upgrade will take place. +.Pp Once this is done, the pool will no longer be accessible on systems that do not support feature flags. See @@ -92,15 +96,14 @@ Enables all supported features (from specified compatibility sets, if any) on al pools. .It Fl V Ar version Upgrade to the specified legacy version. -If the -.Fl V -flag is specified, no features will be enabled on the pool. +If specified, no features will be enabled on the pool. This option can only be used to increase the version number up to the last supported legacy version number. .El .El +. .Sh SEE ALSO .Xr zpool-features 5 , +.Xr zpool-history 8 , .Xr zpoolconcepts 8 , -.Xr zpoolprops 8 , -.Xr zpool-history 8 +.Xr zpoolprops 8 diff --git a/sys/contrib/openzfs/man/man8/zpool-wait.8 b/sys/contrib/openzfs/man/man8/zpool-wait.8 index ff6d992243b..38f4812ace1 100644 --- a/sys/contrib/openzfs/man/man8/zpool-wait.8 +++ b/sys/contrib/openzfs/man/man8/zpool-wait.8 @@ -27,31 +27,23 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd February 25, 2020 +.Dd May 27, 2021 .Dt ZPOOL-WAIT 8 .Os +. .Sh NAME .Nm zpool-wait -.Nd Wait for background activity to stop in a ZFS storage pool +.Nd wait for activity to stop in a ZFS storage pool .Sh SYNOPSIS .Nm zpool .Cm wait .Op Fl Hp .Op Fl T Sy u Ns | Ns Sy d -.Op Fl t Ar activity Ns Oo , Ns Ar activity Ns Oc Ns ... +.Op Fl t Ar activity Ns Oo , Ns Ar activity Ns Oc Ns … .Ar pool .Op Ar interval +. .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm wait -.Op Fl Hp -.Op Fl T Sy u Ns | Ns Sy d -.Op Fl t Ar activity Ns Oo , Ns Ar activity Ns Oc Ns ... -.Ar pool -.Op Ar interval -.Xc Waits until all background activity of the given types has ceased in the given pool. The activity could cease because it has completed, or because it has been @@ -65,16 +57,26 @@ immediately. These are the possible values for .Ar activity , along with what each one waits for: -.Bd -literal - discard Checkpoint to be discarded - free 'freeing' property to become 0 - initialize All initializations to cease - replace All device replacements to cease - remove Device removal to cease - resilver Resilver to cease - scrub Scrub to cease - trim Manual trim to cease -.Ed +.Bl -tag -compact -offset Ds -width "initialize" +.It Sy discard +Checkpoint to be discarded +.It Sy free +.Sy freeing +property to become +.Sy 0 +.It Sy initialize +All initializations to cease +.It Sy replace +All device replacements to cease +.It Sy remove +Device removal to cease +.It Sy resilver +Resilver to cease +.It Sy scrub +Scrub to cease +.It Sy trim +Manual trim to cease +.El .Pp If an .Ar interval @@ -102,13 +104,13 @@ for standard date format. See .Xr date 1 . .El -.El +. .Sh SEE ALSO -.Xr zpool-status 8 , .Xr zpool-checkpoint 8 , .Xr zpool-initialize 8 , -.Xr zpool-replace 8 , .Xr zpool-remove 8 , +.Xr zpool-replace 8 , .Xr zpool-resilver 8 , .Xr zpool-scrub 8 , +.Xr zpool-status 8 , .Xr zpool-trim 8 diff --git a/sys/contrib/openzfs/man/man8/zpool.8 b/sys/contrib/openzfs/man/man8/zpool.8 index 15e50838fee..dac35eee77b 100644 --- a/sys/contrib/openzfs/man/man8/zpool.8 +++ b/sys/contrib/openzfs/man/man8/zpool.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,9 +26,10 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd June 2, 2021 .Dt ZPOOL 8 .Os +. .Sh NAME .Nm zpool .Nd configure ZFS storage pools @@ -39,8 +39,9 @@ .Nm .Cm version .Nm -.Cm -.Op Ar +.Cm subcommand +.Op Ar argumentss +. .Sh DESCRIPTION The .Nm @@ -55,6 +56,7 @@ for information on managing datasets. For an overview of creating and managing ZFS storage pools see the .Xr zpoolconcepts 8 manual page. +. .Sh SUBCOMMANDS All subcommands that modify state are logged persistently to the pool in their original form. @@ -67,24 +69,22 @@ The following subcommands are supported: .Bl -tag -width Ds .It Xo .Nm -.Fl ? +.Fl ?\& .Xc Displays a help message. .It Xo .Nm -.Fl V, -version +.Fl V , -version .Xc -An alias for the -.Nm zpool Cm version -subcommand. .It Xo .Nm .Cm version .Xc Displays the software version of the .Nm -userland utility and the zfs kernel module. +userland utility and the ZFS kernel module. .El +. .Ss Creation .Bl -tag -width Ds .It Xr zpool-create 8 @@ -95,6 +95,7 @@ Begins initializing by writing to all unallocated regions on the specified devices, or all eligible devices in the pool if no individual devices are specified. .El +. .Ss Destruction .Bl -tag -width Ds .It Xr zpool-destroy 8 @@ -103,18 +104,17 @@ Destroys the given pool, freeing up any devices for other use. Removes ZFS label information from the specified .Ar device . .El +. .Ss Virtual Devices .Bl -tag -width Ds .It Xo -.Xr zpool-attach 8 / -.Xr zpool-detach 8 +.Xr zpool-attach 8 Ns / Ns Xr zpool-detach 8 .Xc Increases or decreases redundancy by -.Cm attach Ns -ing or -.Cm detach Ns -ing a device on an existing vdev (virtual device). +.Cm attach Ns ing or +.Cm detach Ns ing a device on an existing vdev (virtual device). .It Xo -.Xr zpool-add 8 / -.Xr zpool-remove 8 +.Xr zpool-add 8 Ns / Ns Xr zpool-remove 8 .Xc Adds the specified virtual devices to the given pool, or removes the specified device from the pool. @@ -123,6 +123,7 @@ Replaces an existing device (which may be faulted) with a new one. .It Xr zpool-split 8 Creates a new pool by splitting all mirrors in an existing pool (which decreases its redundancy). .El +. .Ss Properties Available pool properties listed in the .Xr zpoolprops 8 @@ -131,8 +132,7 @@ manual page. .It Xr zpool-list 8 Lists the given pools along with a health status and space usage. .It Xo -.Xr zpool-get 8 / -.Xr zpool-set 8 +.Xr zpool-get 8 Ns / Ns Xr zpool-set 8 .Xc Retrieves the given list of properties .Po @@ -142,6 +142,7 @@ is used .Pc for the specified storage pool(s). .El +. .Ss Monitoring .Bl -tag -width Ds .It Xr zpool-status 8 @@ -151,11 +152,12 @@ Displays logical I/O statistics for the given pools/vdevs. Physical I/Os may be observed via .Xr iostat 1 . .It Xr zpool-events 8 -Lists all recent events generated by the ZFS kernel modules. These events -are consumed by the +Lists all recent events generated by the ZFS kernel modules. +These events are consumed by the .Xr zed 8 and used to automate administrative tasks such as replacing a failed device -with a hot spare. For more information about the subclasses and event payloads +with a hot spare. +For more information about the subclasses and event payloads that can be generated see the .Xr zfs-events 5 man page. @@ -163,48 +165,51 @@ man page. Displays the command history of the specified pool(s) or all pools if no pool is specified. .El +. .Ss Maintenance .Bl -tag -width Ds .It Xr zpool-scrub 8 Begins a scrub or resumes a paused scrub. .It Xr zpool-checkpoint 8 Checkpoints the current state of -.Ar pool -, which can be later restored by -.Nm zpool Cm import --rewind-to-checkpoint . +.Ar pool , +which can be later restored by +.Nm zpool Cm import Fl -rewind-to-checkpoint . .It Xr zpool-trim 8 -Initiates an immediate on-demand TRIM operation for all of the free space in -a pool. This operation informs the underlying storage devices of all blocks +Initiates an immediate on-demand TRIM operation for all of the free space in a pool. +This operation informs the underlying storage devices of all blocks in the pool which are no longer allocated and allows thinly provisioned devices to reclaim the space. .It Xr zpool-sync 8 This command forces all in-core dirty data to be written to the primary -pool storage and not the ZIL. It will also update administrative -information including quota reporting. Without arguments, -.Sy zpool sync -will sync all pools on the system. Otherwise, it will sync only the -specified pool(s). +pool storage and not the ZIL. +It will also update administrative information including quota reporting. +Without arguments, +.Nm zpool Cm sync +will sync all pools on the system. +Otherwise, it will sync only the specified pool(s). .It Xr zpool-upgrade 8 Manage the on-disk format version of storage pools. .It Xr zpool-wait 8 Waits until all background activity of the given types has ceased in the given pool. .El +. .Ss Fault Resolution .Bl -tag -width Ds .It Xo -.Xr zpool-offline 8 -.Xr zpool-online 8 +.Xr zpool-offline 8 Ns / Ns Xr zpool-online 8 .Xc Takes the specified physical device offline or brings it online. .It Xr zpool-resilver 8 -Starts a resilver. If an existing resilver is already running it will be -restarted from the beginning. +Starts a resilver. +If an existing resilver is already running it will be restarted from the beginning. .It Xr zpool-reopen 8 Reopen all the vdevs associated with the pool. .It Xr zpool-clear 8 Clears device errors in a pool. .El +. .Ss Import & Export .Bl -tag -width Ds .It Xr zpool-import 8 @@ -214,9 +219,10 @@ Exports the given pools from the system. .It Xr zpool-reguid 8 Generates a new unique identifier for the pool. .El +. .Sh EXIT STATUS The following exit values are returned: -.Bl -tag -width Ds +.Bl -tag -compact -offset 4n -width "a" .It Sy 0 Successful completion. .It Sy 1 @@ -224,74 +230,69 @@ An error occurred. .It Sy 2 Invalid command line options were specified. .El +. .Sh EXAMPLES -.Bl -tag -width Ds -.It Sy Example 1 No Creating a RAID-Z Storage Pool +.Bl -tag -width "Exam" +.It Sy Example 1 : No Creating a RAID-Z Storage Pool The following command creates a pool with a single raidz root vdev that -consists of six disks. -.Bd -literal -# zpool create tank raidz sda sdb sdc sdd sde sdf -.Ed -.It Sy Example 2 No Creating a Mirrored Storage Pool +consists of six disks: +.Dl # Nm zpool Cm create Ar tank Sy raidz Ar sda sdb sdc sdd sde sdf +. +.It Sy Example 2 : No Creating a Mirrored Storage Pool The following command creates a pool with two mirrors, where each mirror -contains two disks. -.Bd -literal -# zpool create tank mirror sda sdb mirror sdc sdd -.Ed -.It Sy Example 3 No Creating a ZFS Storage Pool by Using Partitions -The following command creates an unmirrored pool using two disk partitions. -.Bd -literal -# zpool create tank sda1 sdb2 -.Ed -.It Sy Example 4 No Creating a ZFS Storage Pool by Using Files +contains two disks: +.Dl # Nm zpool Cm create Ar tank Sy mirror Ar sda sdb Sy mirror Ar sdc sdd +. +.It Sy Example 3 : No Creating a ZFS Storage Pool by Using Partitions +The following command creates an unmirrored pool using two disk partitions: +.Dl # Nm zpool Cm create Ar tank sda1 sdb2 +. +.It Sy Example 4 : No Creating a ZFS Storage Pool by Using Files The following command creates an unmirrored pool using files. While not recommended, a pool based on files can be useful for experimental purposes. -.Bd -literal -# zpool create tank /path/to/file/a /path/to/file/b -.Ed -.It Sy Example 5 No Adding a Mirror to a ZFS Storage Pool +.Dl # Nm zpool Cm create Ar tank /path/to/file/a /path/to/file/b +. +.It Sy Example 5 : No Adding a Mirror to a ZFS Storage Pool The following command adds two mirrored disks to the pool -.Em tank , +.Ar tank , assuming the pool is already made up of two-way mirrors. The additional space is immediately available to any datasets within the pool. -.Bd -literal -# zpool add tank mirror sda sdb -.Ed -.It Sy Example 6 No Listing Available ZFS Storage Pools +.Dl # Nm zpool Cm add Ar tank Sy mirror Ar sda sdb +. +.It Sy Example 6 : No Listing Available ZFS Storage Pools The following command lists all available pools on the system. In this case, the pool -.Em zion +.Ar zion is faulted due to a missing device. The results from this command are similar to the following: -.Bd -literal -# zpool list +.Bd -literal -compact -offset Ds +.No # Nm zpool Cm list NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT rpool 19.9G 8.43G 11.4G - 33% 42% 1.00x ONLINE - tank 61.5G 20.0G 41.5G - 48% 32% 1.00x ONLINE - zion - - - - - - - FAULTED - .Ed -.It Sy Example 7 No Destroying a ZFS Storage Pool +. +.It Sy Example 7 : No Destroying a ZFS Storage Pool The following command destroys the pool -.Em tank -and any datasets contained within. -.Bd -literal -# zpool destroy -f tank -.Ed -.It Sy Example 8 No Exporting a ZFS Storage Pool +.Ar tank +and any datasets contained within: +.Dl # Nm zpool Cm destroy Fl f Ar tank +. +.It Sy Example 8 : No Exporting a ZFS Storage Pool The following command exports the devices in pool -.Em tank -so that they can be relocated or later imported. -.Bd -literal -# zpool export tank -.Ed -.It Sy Example 9 No Importing a ZFS Storage Pool +.Ar tank +so that they can be relocated or later imported: +.Dl # Nm zpool Cm export Ar tank +. +.It Sy Example 9 : No Importing a ZFS Storage Pool The following command displays available pools, and then imports the pool -.Em tank +.Ar tank for use on the system. The results from this command are similar to the following: -.Bd -literal -# zpool import +.Bd -literal -compact -offset Ds +.No # Nm zpool Cm import pool: tank id: 15451357997522795478 state: ONLINE @@ -303,66 +304,58 @@ config: sda ONLINE sdb ONLINE -# zpool import tank +.No # Nm zpool Cm import Ar tank .Ed -.It Sy Example 10 No Upgrading All ZFS Storage Pools to the Current Version +. +.It Sy Example 10 : No Upgrading All ZFS Storage Pools to the Current Version The following command upgrades all ZFS Storage pools to the current version of -the software. -.Bd -literal -# zpool upgrade -a +the software: +.Bd -literal -compact -offset Ds +.No # Nm zpool Cm upgrade Fl a This system is currently running ZFS version 2. .Ed -.It Sy Example 11 No Managing Hot Spares +. +.It Sy Example 11 : No Managing Hot Spares The following command creates a new pool with an available hot spare: -.Bd -literal -# zpool create tank mirror sda sdb spare sdc -.Ed +.Dl # Nm zpool Cm create Ar tank Sy mirror Ar sda sdb Sy spare Ar sdc .Pp If one of the disks were to fail, the pool would be reduced to the degraded state. The failed device can be replaced using the following command: -.Bd -literal -# zpool replace tank sda sdd -.Ed +.Dl # Nm zpool Cm replace Ar tank sda sdd .Pp Once the data has been resilvered, the spare is automatically removed and is made available for use should another device fail. The hot spare can be permanently removed from the pool using the following command: -.Bd -literal -# zpool remove tank sdc -.Ed -.It Sy Example 12 No Creating a ZFS Pool with Mirrored Separate Intent Logs +.Dl # Nm zpool Cm remove Ar tank sdc +. +.It Sy Example 12 : No Creating a ZFS Pool with Mirrored Separate Intent Logs The following command creates a ZFS storage pool consisting of two, two-way mirrors and mirrored log devices: -.Bd -literal -# zpool create pool mirror sda sdb mirror sdc sdd log mirror \\ - sde sdf -.Ed -.It Sy Example 13 No Adding Cache Devices to a ZFS Pool +.Dl # Nm zpool Cm create Ar pool Sy mirror Ar sda sdb Sy mirror Ar sdc sdd Sy log mirror Ar sde sdf +. +.It Sy Example 13 : No Adding Cache Devices to a ZFS Pool The following command adds two disks for use as cache devices to a ZFS storage pool: -.Bd -literal -# zpool add pool cache sdc sdd -.Ed +.Dl # Nm zpool Cm add Ar pool Sy cache Ar sdc sdd .Pp Once added, the cache devices gradually fill with content from main memory. Depending on the size of your cache devices, it could take over an hour for them to fill. Capacity and reads can be monitored using the .Cm iostat -option as follows: -.Bd -literal -# zpool iostat -v pool 5 -.Ed -.It Sy Example 14 No Removing a Mirrored top-level (Log or Data) Device +subcommand as follows: +.Dl # Nm zpool Cm iostat Fl v Ar pool 5 +. +.It Sy Example 14 : No Removing a Mirrored top-level (Log or Data) Device The following commands remove the mirrored log device .Sy mirror-2 and mirrored top-level data device .Sy mirror-1 . .Pp Given this configuration: -.Bd -literal +.Bd -literal -compact -offset Ds pool: tank state: ONLINE scrub: none requested @@ -383,27 +376,22 @@ config: .Ed .Pp The command to remove the mirrored log -.Sy mirror-2 -is: -.Bd -literal -# zpool remove tank mirror-2 -.Ed +.Ar mirror-2 No is: +.Dl # Nm zpool Cm remove Ar tank mirror-2 .Pp The command to remove the mirrored data -.Sy mirror-1 -is: -.Bd -literal -# zpool remove tank mirror-1 -.Ed -.It Sy Example 15 No Displaying expanded space on a device +.Ar mirror-1 No is: +.Dl # Nm zpool Cm remove Ar tank mirror-1 +. +.It Sy Example 15 : No Displaying expanded space on a device The following command displays the detailed information for the pool -.Em data . +.Ar data . This pool is comprised of a single raidz vdev where one of its devices increased its capacity by 10GB. In this example, the pool will not be able to utilize this extra capacity until all the devices under the raidz vdev have been expanded. -.Bd -literal -# zpool list -v data +.Bd -literal -compact -offset Ds +.No # Nm zpool Cm list Fl v Ar data NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT data 23.9G 14.6G 9.30G - 48% 61% 1.00x ONLINE - raidz1 23.9G 14.6G 9.30G - 48% @@ -411,16 +399,12 @@ data 23.9G 14.6G 9.30G - 48% 61% 1.00x ONLINE - sdb - - - 10G - sdc - - - - - .Ed -.It Sy Example 16 No Adding output columns +. +.It Sy Example 16 : No Adding output columns Additional columns can be added to the -.Nm zpool Cm status -and -.Nm zpool Cm iostat -output with -.Fl c -option. -.Bd -literal -# zpool status -c vendor,model,size +.Nm zpool Cm status No and Nm zpool Cm iostat No output with Fl c . +.Bd -literal -compact -offset Ds +.No # Nm zpool Cm status Fl c Ar vendor , Ns Ar model , Ns Ar size NAME STATE READ WRITE CKSUM vendor model size tank ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 @@ -431,7 +415,7 @@ option. U13 ONLINE 0 0 0 SEAGATE ST8000NM0075 7.3T U14 ONLINE 0 0 0 SEAGATE ST8000NM0075 7.3T -# zpool iostat -vc size +.No # Nm zpool Cm iostat Fl vc Ar size capacity operations bandwidth pool alloc free read write read write size ---------- ----- ----- ----- ----- ----- ----- ---- @@ -440,124 +424,104 @@ rpool 14.6G 54.9G 4 55 250K 2.69M ---------- ----- ----- ----- ----- ----- ----- ---- .Ed .El +. .Sh ENVIRONMENT VARIABLES -.Bl -tag -width "ZFS_ABORT" -.It Ev ZFS_ABORT +.Bl -tag -compact -width "ZPOOL_IMPORT_UDEV_TIMEOUT_MS" +.It Sy ZFS_ABORT Cause -.Nm zpool +.Nm to dump core on exit for the purposes of running .Sy ::findleaks . -.El -.Bl -tag -width "ZFS_COLOR" -.It Ev ZFS_COLOR +.It Sy ZFS_COLOR Use ANSI color in .Nm zpool status output. -.El -.Bl -tag -width "ZPOOL_IMPORT_PATH" -.It Ev ZPOOL_IMPORT_PATH -The search path for devices or files to use with the pool. This is a colon-separated list of directories in which -.Nm zpool +.It Sy ZPOOL_IMPORT_PATH +The search path for devices or files to use with the pool. +This is a colon-separated list of directories in which +.Nm looks for device nodes and files. Similar to the .Fl d option in .Nm zpool import . -.El -.Bl -tag -width "ZPOOL_IMPORT_UDEV_TIMEOUT_MS" -.It Ev ZPOOL_IMPORT_UDEV_TIMEOUT_MS +.It Sy ZPOOL_IMPORT_UDEV_TIMEOUT_MS The maximum time in milliseconds that .Nm zpool import will wait for an expected device to be available. -.El -.Bl -tag -width "ZPOOL_STATUS_NON_NATIVE_ASHIFT_IGNORE" -.It Ev ZPOOL_STATUS_NON_NATIVE_ASHIFT_IGNORE +.It Sy ZPOOL_STATUS_NON_NATIVE_ASHIFT_IGNORE If set, suppress warning about non-native vdev ashift in .Nm zpool status . The value is not used, only the presence or absence of the variable matters. -.El -.Bl -tag -width "ZPOOL_VDEV_NAME_GUID" -.It Ev ZPOOL_VDEV_NAME_GUID +.It Sy ZPOOL_VDEV_NAME_GUID Cause -.Nm zpool -subcommands to output vdev guids by default. This behavior is identical to the -.Nm zpool status -g +.Nm +subcommands to output vdev guids by default. +This behavior is identical to the +.Nm zpool Cm status Fl g command line option. -.El -.Bl -tag -width "ZPOOL_VDEV_NAME_FOLLOW_LINKS" -.It Ev ZPOOL_VDEV_NAME_FOLLOW_LINKS +.It Sy ZPOOL_VDEV_NAME_FOLLOW_LINKS Cause -.Nm zpool -subcommands to follow links for vdev names by default. This behavior is identical to the -.Nm zpool status -L +.Nm +subcommands to follow links for vdev names by default. +This behavior is identical to the +.Nm zpool Cm status Fl L command line option. -.El -.Bl -tag -width "ZPOOL_VDEV_NAME_PATH" -.It Ev ZPOOL_VDEV_NAME_PATH +.It Sy ZPOOL_VDEV_NAME_PATH Cause -.Nm zpool -subcommands to output full vdev path names by default. This -behavior is identical to the -.Nm zpool status -P +.Nm +subcommands to output full vdev path names by default. +This behavior is identical to the +.Nm zpool Cm status Fl P command line option. -.El -.Bl -tag -width "ZFS_VDEV_DEVID_OPT_OUT" -.It Ev ZFS_VDEV_DEVID_OPT_OUT +.It Sy ZFS_VDEV_DEVID_OPT_OUT Older OpenZFS implementations had issues when attempting to display pool config VDEV names if a .Sy devid NVP value is present in the pool's config. .Pp -For example, a pool that originated on illumos platform would have a devid +For example, a pool that originated on illumos platform would have a +.Sy devid value in the config and .Nm zpool status would fail when listing the config. -This would also be true for future Linux based pools. +This would also be true for future Linux-based pools. .Pp A pool can be stripped of any .Sy devid values on import or prevented from adding them on -.Nm zpool create +.Nm zpool Cm create or -.Nm zpool add +.Nm zpool Cm add by setting .Sy ZFS_VDEV_DEVID_OPT_OUT . -.El -.Bl -tag -width "ZPOOL_SCRIPTS_AS_ROOT" -.It Ev ZPOOL_SCRIPTS_AS_ROOT -Allow a privileged user to run the -.Nm zpool status/iostat -with the -.Fl c -option. Normally, only unprivileged users are allowed to run +.Pp +.It Sy ZPOOL_SCRIPTS_AS_ROOT +Allow a privileged user to run +.Nm zpool status/iostat Fl c . +Normally, only unprivileged users are allowed to run .Fl c . -.El -.Bl -tag -width "ZPOOL_SCRIPTS_PATH" -.It Ev ZPOOL_SCRIPTS_PATH +.It Sy ZPOOL_SCRIPTS_PATH The search path for scripts when running -.Nm zpool status/iostat -with the -.Fl c -option. This is a colon-separated list of directories and overrides the default +.Nm zpool status/iostat Fl c . +This is a colon-separated list of directories and overrides the default .Pa ~/.zpool.d and .Pa /etc/zfs/zpool.d search paths. -.El -.Bl -tag -width "ZPOOL_SCRIPTS_ENABLED" -.It Ev ZPOOL_SCRIPTS_ENABLED +.It Sy ZPOOL_SCRIPTS_ENABLED Allow a user to run -.Nm zpool status/iostat -with the -.Fl c -option. If +.Nm zpool status/iostat Fl c . +If .Sy ZPOOL_SCRIPTS_ENABLED is not set, it is assumed that the user is allowed to run -.Nm zpool status/iostat -c . +.Nm zpool Cm status Ns / Ns Cm iostat Fl c . .El +. .Sh INTERFACE STABILITY .Sy Evolving +. .Sh SEE ALSO .Xr zfs-events 5 , .Xr zfs-module-parameters 5 , diff --git a/sys/contrib/openzfs/man/man8/zpool_influxdb.8 b/sys/contrib/openzfs/man/man8/zpool_influxdb.8 index bd899dbe90a..a4e417078fd 100644 --- a/sys/contrib/openzfs/man/man8/zpool_influxdb.8 +++ b/sys/contrib/openzfs/man/man8/zpool_influxdb.8 @@ -18,76 +18,81 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright 2020 Richard Elling -.\" .Dd June 14, 2020 -.TH zpool_influxdb 8 -.SH NAME -zpool_influxdb \- collect zpool statistics in influxdb line protocol format -.SH SYNOPSIS -.LP -.nf -\fBzpool_influxdb\fR [--execd] [--no-histogram] [--sum-histogram-buckets] -[--tags key=value] [pool] -\fBzpool_influxdb\fR --help -.fi -.SH DESCRIPTION -The \fBzpool_influxdb\fR command produces influxdb line protocol compatible -metrics from zpools. Like the \fBzpool\fR command, \fBzpool_influxdb\fR -reads the current pool status and statistics. Unlike the \fBzpool\fR -command which is intended for humans, \fBzpool_influxdb\fR formats the -output in influxdb line protocol. The expected use is as a plugin to a -metrics collector or aggregator, such as telegraf. - -By default, \fBzpool_influxdb\fR prints pool metrics and status in the -influxdb line protocol format. All pools are printed, similar to -the \fBzpool status\fR command. Providing a pool name restricts the -output to the named pool. - -Like the \fBzpool\fR command, \fBzpool_influxdb\fR uses internal data -structures that can change over time as new ZFS releases are made. -Therefore, the \fBzpool_influxdb\fR command must be compiled against the -ZFS source. It is expected that later releases of ZFS includes compatible -\fBzpool_influxdb\fR and \fBzpool\fR commands. - -.SH OPTIONS -.TP -\fB\--execd\fR, \fB-e\fR -Run in daemon mode compatible with telegraf`s \fBexecd\fR plugin. -In this mode, the pools are sampled every time there is a [return] on stdin. -Once a sample printed, \fBzpool_influxdb\fR waits for another [return]. -When run on a terminal, use [ctrl+C] to exit. -.TP -\fB\--no-histogram\fR, \fB-n\fR -Do not print latency and I/O size histograms. This can reduce the total +.\" +.Dd May 26, 2021 +.Dt ZPOOL_INFLUXDB 8 +.Os +. +.Sh NAME +.Nm zpool_influxdb +.Nd collect ZFS pool statistics in InfluxDB line protocol format +.Sh SYNOPSIS +.Nm +.Op Fl e Ns | Ns Fl -execd +.Op Fl n Ns | Ns Fl -no-histogram +.Op Fl s Ns | Ns Fl -sum-histogram-buckets +.Op Fl t Ns | Ns Fl -tags Ar key Ns = Ns Ar value Ns Op , Ns Ar key Ns = Ns Ar value Ns … +.Op Ar pool +. +.Sh DESCRIPTION +.Nm +produces InfluxDB-line-protocol-compatible metrics from zpools. +Like the +.Nm zpool +command, +.Nm +reads the current pool status and statistics. +Unlike the +.Nm zpool +command which is intended for humans, +.Nm +formats the output in the InfluxDB line protocol. +The expected use is as a plugin to a +metrics collector or aggregator, such as Telegraf. +.Pp +By default, +.Nm +prints pool metrics and status in the InfluxDB line protocol format. +All pools are printed, similar to the +.Nm zpool Cm status +command. +Providing a pool name restricts the output to the named pool. +. +.Sh OPTIONS +.Bl -tag -width "-e, --execd" +.It Fl e , -execd +Run in daemon mode compatible with Telegraf's +.Nm execd +plugin. +In this mode, the pools are sampled every time a +newline appears on the standard input. +.It Fl n , -no-histogram +Do not print latency and I/O size histograms. +This can reduce the total amount of data, but one should consider the value brought by the insights -that latency and I/O size distributions provide. The resulting values -are suitable for graphing with grafana's heatmap plugin. -.TP -\fB--sum-histogram-buckets\fR, \fB-s\fR -Accumulates bucket values. By default, the values are not accumulated and -the raw data appears as shown by \fBzpool iostat\fR. This works well for -grafana's heatmap plugin. Summing the buckets produces output similar to -prometheus histograms. -.TP -\fB--tags\fR, \fB-t\fR -Adds specified tags to the tag set. Tags are key=value pairs and multiple -tags are separated by commas. No sanity checking is performed. +that latency and I/O size distributions provide. +The resulting values +are suitable for graphing with Grafana's heatmap plugin. +.It Fl s , -sum-histogram-buckets +Accumulates bucket values. +By default, the values are not accumulated and the raw data appears as shown by +.Nm zpool Cm iostat . +This works well for Grafana's heatmap plugin. +Summing the buckets produces output similar to Prometheus histograms. +.It Fl t , Fl -tags Ar key Ns = Ns Ar value Ns Op , Ns Ar key Ns = Ns Ar value Ns … +Adds specified tags to the tag set. +No sanity checking is performed. See the InfluxDB Line Protocol format documentation for details on escaping special characters used in tags. -.TP -\fB\--help\fR, \fB\-h\fR +.It Fl h , -help Print a usage summary. - -.SH SEE ALSO -.LP -\fBzpool-status\fR(8) -\fBzpool-iostat\fR(8) -.PP -Influxdb https://github.com/influxdata/influxdb -.PP -Telegraf https://github.com/influxdata/telegraf -.PP -Grafana https://grafana.com -.PP -Prometheus https://prometheus.io +.El +. +.Sh SEE ALSO +.Xr zpool-iostat 8 , +.Xr zpool-status 8 , +.Lk https://github.com/influxdata/influxdb "InfluxDB" , +.Lk https://github.com/influxdata/telegraf "Telegraf" , +.Lk https://grafana.com "Grafana" , +.Lk https://prometheus.io "Prometheus" diff --git a/sys/contrib/openzfs/man/man8/zpoolconcepts.8 b/sys/contrib/openzfs/man/man8/zpoolconcepts.8 index b1081714eac..80a1885fb1c 100644 --- a/sys/contrib/openzfs/man/man8/zpoolconcepts.8 +++ b/sys/contrib/openzfs/man/man8/zpoolconcepts.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -27,18 +26,20 @@ .\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" -.Dd August 9, 2019 +.Dd June 2, 2021 .Dt ZPOOLCONCEPTS 8 .Os +. .Sh NAME .Nm zpoolconcepts .Nd overview of ZFS storage pools +. .Sh DESCRIPTION .Ss Virtual Devices (vdevs) A "virtual device" describes a single device or a collection of devices organized according to certain performance and fault characteristics. The following virtual devices are supported: -.Bl -tag -width Ds +.Bl -tag -width "special" .It Sy disk A block device, typically located under .Pa /dev . @@ -58,13 +59,14 @@ When given a whole disk, ZFS automatically labels the disk, if necessary. A regular file. The use of files as a backing store is strongly discouraged. It is designed primarily for experimental purposes, as the fault tolerance of a -file is only as good as the file system of which it is a part. +file is only as good as the file system on which it resides. A file must be specified by a full path. .It Sy mirror A mirror of two or more devices. Data is replicated in an identical fashion across all components of a mirror. -A mirror with N disks of size X can hold X bytes and can withstand (N-1) devices -failing without losing data. +A mirror with +.Em N No disks of size Em X No can hold Em X No bytes and can withstand Em N-1 +devices failing without losing data. .It Sy raidz , raidz1 , raidz2 , raidz3 A variation on RAID-5 that allows for better distribution of parity and eliminates the RAID-5 @@ -72,7 +74,7 @@ eliminates the RAID-5 .Pq in which data and parity become inconsistent after a power loss . Data and parity is striped across all disks within a raidz group. .Pp -A raidz group can have single-, double-, or triple-parity, meaning that the +A raidz group can have single, double, or triple parity, meaning that the raidz group can sustain one, two, or three failures, respectively, without losing any data. The @@ -87,39 +89,42 @@ The vdev type is an alias for .Sy raidz1 . .Pp -A raidz group with N disks of size X with P parity disks can hold approximately -(N-P)*X bytes and can withstand P device(s) failing without losing data. +A raidz group with +.Em N No disks of size Em X No with Em P No parity disks can hold approximately +.Em (N-P)*X No bytes and can withstand Em P No devices failing without losing data. The minimum number of devices in a raidz group is one more than the number of parity disks. The recommended number is between 3 and 9 to help increase performance. .It Sy draid , draid1 , draid2 , draid3 A variant of raidz that provides integrated distributed hot spares which allows for faster resilvering while retaining the benefits of raidz. -A dRAID vdev is constructed from multiple internal raidz groups, each with D -data devices and P parity devices. +A dRAID vdev is constructed from multiple internal raidz groups, each with +.Em D No data devices and Em P No parity devices. These groups are distributed over all of the children in order to fully utilize the available disk performance. .Pp Unlike raidz, dRAID uses a fixed stripe width (padding as necessary with zeros) to allow fully sequential resilvering. This fixed stripe width significantly effects both usable capacity and IOPS. -For example, with the default D=8 and 4k disk sectors the minimum allocation -size is 32k. +For example, with the default +.Em D=8 No and Em 4kB No disk sectors the minimum allocation size is Em 32kB . If using compression, this relatively large allocation size can reduce the effective compression ratio. -When using ZFS volumes and dRAID the default volblocksize property is increased -to account for the allocation size. +When using ZFS volumes and dRAID, the default of the +.Sy volblocksize +property is increased to account for the allocation size. If a dRAID pool will hold a significant amount of small blocks, it is recommended to also add a mirrored .Sy special vdev to store those blocks. .Pp -In regards to IO/s, performance is similar to raidz since for any read all D -data disks must be accessed. +In regards to I/O, performance is similar to raidz since for any read all +.Em D No data disks must be accessed. Delivered random IOPS can be reasonably approximated as -floor((N-S)/(D+P))*. +.Sy floor((N-S)/(D+P))*single_drive_IOPS . .Pp -Like raidz a dRAID can have single-, double-, or triple-parity. The +Like raidzm a dRAID can have single-, double-, or triple-parity. +The .Sy draid1 , .Sy draid2 , and @@ -130,33 +135,34 @@ The vdev type is an alias for .Sy draid1 . .Pp -A dRAID with N disks of size X, D data disks per redundancy group, P parity -level, and S distributed hot spares can hold approximately (N-S)*(D/(D+P))*X -bytes and can withstand P device(s) failing without losing data. -.It Sy draid[][:d][:c][:s] +A dRAID with +.Em N No disks of size Em X , D No data disks per redundancy group, Em P +.No parity level, and Em S No distributed hot spares can hold approximately +.Em (N-S)*(D/(D+P))*X No bytes and can withstand Em P +devices failing without losing data. +.It Sy draid Ns Oo Ar parity Oc Ns Oo Sy \&: Ns Ar data Ns Sy d Oc Ns Oo Sy \&: Ns Ar children Ns Sy c Oc Ns Oo Sy \&: Ns Ar spares Ns Sy s Oc A non-default dRAID configuration can be specified by appending one or more of the following optional arguments to the .Sy draid -keyword. -.Pp -.Em parity -- The parity level (1-3). -.Pp -.Em data -- The number of data devices per redundancy group. -In general a smaller value of D will increase IOPS, improve the compression ratio, and speed up resilvering at the expense of total usable capacity. -Defaults to 8, unless N-P-S is less than 8. -.Pp -.Em children -- The expected number of children. +keyword: +.Bl -tag -compact -width "children" +.It Ar parity +The parity level (1-3). +.It Ar data +The number of data devices per redundancy group. +In general, a smaller value of +.Em D No will increase IOPS, improve the compression ratio, +and speed up resilvering at the expense of total usable capacity. +Defaults to +.Em 8 , No unless Em N-P-S No is less than Em 8 . +.It Ar children +The expected number of children. Useful as a cross-check when listing a large number of devices. An error is returned when the provided number of children differs. -.Pp -.Em spares -- The number of distributed hot spares. +.It Ar spares +The number of distributed hot spares. Defaults to zero. -.Pp -.Pp +.El .It Sy spare A pseudo-vdev which keeps track of available hot spares for a pool. For more information, see the @@ -174,13 +180,15 @@ section. .It Sy dedup A device dedicated solely for deduplication tables. The redundancy of this device should match the redundancy of the other normal -devices in the pool. If more than one dedup device is specified, then +devices in the pool. +If more than one dedup device is specified, then allocations are load-balanced between those devices. .It Sy special A device dedicated solely for allocating various kinds of internal metadata, and optionally small file blocks. The redundancy of this device should match the redundancy of the other normal -devices in the pool. If more than one special device is specified, then +devices in the pool. +If more than one special device is specified, then allocations are load-balanced between those devices. .Pp For more information on special allocations, see the @@ -209,17 +217,15 @@ among devices. As new virtual devices are added, ZFS automatically places data on the newly available devices. .Pp -Virtual devices are specified one at a time on the command line, separated by -whitespace. -The keywords -.Sy mirror -and -.Sy raidz +Virtual devices are specified one at a time on the command line, +separated by whitespace. +Keywords like +.Sy mirror No and Sy raidz are used to distinguish where a group ends and another begins. -For example, the following creates two root vdevs, each a mirror of two disks: -.Bd -literal -# zpool create mypool mirror sda sdb mirror sdc sdd -.Ed +For example, the following creates a pool with two root vdevs, +each a mirror of two disks: +.Dl # Nm zpool Cm create Ar mypool Sy mirror Ar sda sdb Sy mirror Ar sdc sdd +. .Ss Device Failure and Recovery ZFS supports a rich set of mechanisms for handling device failure and data corruption. @@ -232,17 +238,17 @@ While ZFS supports running in a non-redundant configuration, where each root vdev is simply a disk or file, this is strongly discouraged. A single case of bit corruption can render some or all of your data unavailable. .Pp -A pool's health status is described by one of three states: online, degraded, -or faulted. +A pool's health status is described by one of three states: +.Sy online , degraded , No or Sy faulted . An online pool has all devices operating normally. A degraded pool is one in which one or more devices have failed, but the data is still available due to a redundant configuration. A faulted pool has corrupted metadata, or one or more faulted devices, and insufficient replicas to continue functioning. .Pp -The health of the top-level vdev, such as mirror or raidz device, is -potentially impacted by the state of its associated vdevs, or component -devices. +The health of the top-level vdev, such as a mirror or raidz device, +is potentially impacted by the state of its associated vdevs, +or component devices. A top-level vdev or component device is in one of the following states: .Bl -tag -width "DEGRADED" .It Sy DEGRADED @@ -253,7 +259,7 @@ Sufficient replicas exist to continue functioning. One or more component devices is in the degraded or faulted state, but sufficient replicas exist to continue functioning. The underlying conditions are as follows: -.Bl -bullet +.Bl -bullet -compact .It The number of checksum errors exceeds acceptable levels and the device is degraded as an indication that something may be wrong. @@ -271,7 +277,7 @@ Insufficient replicas exist to continue functioning. One or more component devices is in the faulted state, and insufficient replicas exist to continue functioning. The underlying conditions are as follows: -.Bl -bullet +.Bl -bullet -compact .It The device could be opened, but the contents did not match expected values. .It @@ -303,19 +309,20 @@ The checksum errors are reported in and .Nm zpool Cm events . When a block is stored redundantly, a damaged block may be reconstructed -(e.g. from RAIDZ parity or a mirrored copy). +(e.g. from raidz parity or a mirrored copy). In this case, ZFS reports the checksum error against the disks that contained damaged data. If a block is unable to be reconstructed (e.g. due to 3 disks being damaged -in a RAIDZ2 group), it is not possible to determine which disks were silently +in a raidz2 group), it is not possible to determine which disks were silently corrupted. In this case, checksum errors are reported for all disks on which the block is stored. .Pp -If a device is removed and later re-attached to the system, ZFS attempts -to put the device online automatically. -Device attach detection is hardware-dependent and might not be supported on all -platforms. +If a device is removed and later re-attached to the system, +ZFS attempts online the device automatically. +Device attachment detection is hardware-dependent +and might not be supported on all platforms. +. .Ss Hot Spares ZFS allows devices to be associated with pools as .Qq hot spares . @@ -325,9 +332,7 @@ To create a pool with hot spares, specify a .Sy spare vdev with any number of devices. For example, -.Bd -literal -# zpool create pool mirror sda sdb spare sdc sdd -.Ed +.Dl # Nm zpool Cm create Ar pool Sy mirror Ar sda sdb Sy spare Ar sdc sdd .Pp Spares can be shared across multiple pools, and can be added with the .Nm zpool Cm add @@ -344,10 +349,11 @@ If a pool has a shared spare that is currently being used, the pool can not be exported since other pools may use this shared spare, which may lead to potential data corruption. .Pp -Shared spares add some risk. If the pools are imported on different hosts, and -both pools suffer a device failure at the same time, both could attempt to use -the spare at the same time. This may not be detected, resulting in data -corruption. +Shared spares add some risk. +If the pools are imported on different hosts, +and both pools suffer a device failure at the same time, +both could attempt to use the spare at the same time. +This may not be detected, resulting in data corruption. .Pp An in-progress spare replacement can be cancelled by detaching the hot spare. If the original faulted device is detached, then the hot spare assumes its @@ -357,12 +363,14 @@ pools. The .Sy draid vdev type provides distributed hot spares. -These hot spares are named after the dRAID vdev they're a part of ( -.Qq draid1-2-3 specifies spare 3 of vdev 2, which is a single parity dRAID -) and may only be used by that dRAID vdev. +These hot spares are named after the dRAID vdev they're a part of +.Po Sy draid1 Ns - Ns Ar 2 Ns - Ns Ar 3 No specifies spare Ar 3 No of vdev Ar 2 , +.No which is a single parity dRAID Pc +and may only be used by that dRAID vdev. Otherwise, they behave the same as normal hot spares. .Pp Spares cannot replace log devices. +. .Ss Intent Log The ZFS Intent Log (ZIL) satisfies POSIX requirements for synchronous transactions. @@ -375,26 +383,25 @@ By default, the intent log is allocated from blocks within the main pool. However, it might be possible to get better performance using separate intent log devices such as NVRAM or a dedicated disk. For example: -.Bd -literal -# zpool create pool sda sdb log sdc -.Ed +.Dl # Nm zpool Cm create Ar pool sda sdb Sy log Ar sdc .Pp Multiple log devices can also be specified, and they can be mirrored. See the .Sx EXAMPLES section for an example of mirroring multiple log devices. .Pp -Log devices can be added, replaced, attached, detached and removed. In -addition, log devices are imported and exported as part of the pool +Log devices can be added, replaced, attached, detached and removed. +In addition, log devices are imported and exported as part of the pool that contains them. Mirrored devices can be removed by specifying the top-level mirror vdev. +. .Ss Cache Devices Devices can be added to a storage pool as .Qq cache devices . These devices provide an additional layer of caching between main memory and disk. For read-heavy workloads, where the working set size is much larger than what -can be cached in main memory, using cache devices allow much more of this +can be cached in main memory, using cache devices allows much more of this working set to be served from low latency media. Using cache devices provides the greatest performance improvement for random read-workloads of mostly static content. @@ -403,9 +410,7 @@ To create a pool with cache devices, specify a .Sy cache vdev with any number of devices. For example: -.Bd -literal -# zpool create pool sda sdb cache sdc sdd -.Ed +.Dl # Nm zpool Cm create Ar pool sda sdb Sy cache Ar sdc sdd .Pp Cache devices cannot be mirrored or part of a raidz configuration. If a read error is encountered on a cache device, that read I/O is reissued to @@ -415,29 +420,36 @@ configuration. The content of the cache devices is persistent across reboots and restored asynchronously when importing the pool in L2ARC (persistent L2ARC). This can be disabled by setting -.Sy l2arc_rebuild_enabled = 0 . -For cache devices smaller than 1GB we do not write the metadata structures -required for rebuilding the L2ARC in order not to waste space. This can be -changed with +.Sy l2arc_rebuild_enabled Ns = Ns Sy 0 . +For cache devices smaller than +.Em 1GB , +we do not write the metadata structures +required for rebuilding the L2ARC in order not to waste space. +This can be changed with .Sy l2arc_rebuild_blocks_min_l2size . -The cache device header (512 bytes) is updated even if no metadata structures -are written. Setting -.Sy l2arc_headroom = 0 +The cache device header +.Pq Em 512B +is updated even if no metadata structures are written. +Setting +.Sy l2arc_headroom Ns = Ns Sy 0 will result in scanning the full-length ARC lists for cacheable content to be -written in L2ARC (persistent ARC). If a cache device is added with +written in L2ARC (persistent ARC). +If a cache device is added with .Nm zpool Cm add its label and header will be overwritten and its contents are not going to be -restored in L2ARC, even if the device was previously part of the pool. If a -cache device is onlined with +restored in L2ARC, even if the device was previously part of the pool. +If a cache device is onlined with .Nm zpool Cm online -its contents will be restored in L2ARC. This is useful in case of memory pressure +its contents will be restored in L2ARC. +This is useful in case of memory pressure where the contents of the cache device are not fully restored in L2ARC. -The user can off/online the cache device when there is less memory pressure +The user can off- and online the cache device when there is less memory pressure in order to fully restore its contents to L2ARC. +. .Ss Pool checkpoint -Before starting critical procedures that include destructive actions (e.g -.Nm zfs Cm destroy -), an administrator can checkpoint the pool's state and in the case of a +Before starting critical procedures that include destructive actions +.Pq like Nm zfs Cm destroy , +an administrator can checkpoint the pool's state and in the case of a mistake or failure, rewind the entire pool back to the checkpoint. Otherwise, the checkpoint can be discarded when the procedure has completed successfully. @@ -445,59 +457,56 @@ successfully. A pool checkpoint can be thought of as a pool-wide snapshot and should be used with care as it contains every part of the pool's state, from properties to vdev configuration. -Thus, while a pool has a checkpoint certain operations are not allowed. +Thus, certain operations are not allowed while a pool has a checkpoint. Specifically, vdev removal/attach/detach, mirror splitting, and -changing the pool's guid. -Adding a new vdev is supported but in the case of a rewind it will have to be +changing the pool's GUID. +Adding a new vdev is supported, but in the case of a rewind it will have to be added again. Finally, users of this feature should keep in mind that scrubs in a pool that has a checkpoint do not repair checkpointed data. .Pp To create a checkpoint for a pool: -.Bd -literal -# zpool checkpoint pool -.Ed +.Dl # Nm zpool Cm checkpoint Ar pool .Pp To later rewind to its checkpointed state, you need to first export it and then rewind it during import: -.Bd -literal -# zpool export pool -# zpool import --rewind-to-checkpoint pool -.Ed +.Dl # Nm zpool Cm export Ar pool +.Dl # Nm zpool Cm import Fl -rewind-to-checkpoint Ar pool .Pp To discard the checkpoint from a pool: -.Bd -literal -# zpool checkpoint -d pool -.Ed +.Dl # Nm zpool Cm checkpoint Fl d Ar pool .Pp Dataset reservations (controlled by the -.Nm reservation -or -.Nm refreservation -zfs properties) may be unenforceable while a checkpoint exists, because the +.Sy reservation No and Sy refreservation +properties) may be unenforceable while a checkpoint exists, because the checkpoint is allowed to consume the dataset's reservation. Finally, data that is part of the checkpoint but has been freed in the current state of the pool won't be scanned during a scrub. +. .Ss Special Allocation Class -The allocations in the special class are dedicated to specific block types. +Allocations in the special class are dedicated to specific block types. By default this includes all metadata, the indirect blocks of user data, and -any deduplication tables. The class can also be provisioned to accept -small file blocks. +any deduplication tables. +The class can also be provisioned to accept small file blocks. .Pp -A pool must always have at least one normal (non-dedup/special) vdev before -other devices can be assigned to the special class. If the special class -becomes full, then allocations intended for it will spill back into the -normal class. +A pool must always have at least one normal +.Pq non- Ns Sy dedup Ns /- Ns Sy special +vdev before +other devices can be assigned to the special class. +If the +.Sy special +class becomes full, then allocations intended for it +will spill back into the normal class. .Pp -Deduplication tables can be excluded from the special class by setting the +Deduplication tables can be excluded from the special class by unsetting the .Sy zfs_ddt_data_is_special -zfs module parameter to false (0). +ZFS module parameter. .Pp -Inclusion of small file blocks in the special class is opt-in. Each dataset -can control the size of small file blocks allowed in the special class by -setting the +Inclusion of small file blocks in the special class is opt-in. +Each dataset can control the size of small file blocks allowed +in the special class by setting the .Sy special_small_blocks -dataset property. It defaults to zero, so you must opt-in by setting it to a -non-zero value. See -.Xr zfs 8 -for more info on setting this property. +property to nonzero. +See +.Xr zfsprops 8 +for more info on this property. diff --git a/sys/contrib/openzfs/man/man8/zpoolprops.8 b/sys/contrib/openzfs/man/man8/zpoolprops.8 index 20e0d74421a..050a0507288 100644 --- a/sys/contrib/openzfs/man/man8/zpoolprops.8 +++ b/sys/contrib/openzfs/man/man8/zpoolprops.8 @@ -18,7 +18,6 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2012, 2018 by Delphix. All rights reserved. .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved. @@ -28,19 +27,21 @@ .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" Copyright (c) 2021, Colm Buckley .\" -.Dd August 9, 2019 +.Dd May 27, 2021 .Dt ZPOOLPROPS 8 .Os +. .Sh NAME .Nm zpoolprops -.Nd available properties for ZFS storage pools +.Nd properties of ZFS storage pools +. .Sh DESCRIPTION Each pool has several properties associated with it. Some properties are read-only statistics while others are configurable and change the behavior of the pool. .Pp The following are read-only properties: -.Bl -tag -width Ds +.Bl -tag -width "unsupported@guid" .It Cm allocated Amount of storage used within the pool. See @@ -65,11 +66,13 @@ The space can be claimed for the pool by bringing it online with or using .Nm zpool Cm online Fl e . .It Sy fragmentation -The amount of fragmentation in the pool. As the amount of space +The amount of fragmentation in the pool. +As the amount of space .Sy allocated increases, it becomes more difficult to locate .Sy free -space. This may result in lower write performance compared to pools with more +space. +This may result in lower write performance compared to pools with more unfragmented free space. .It Sy free The amount of free space available in the pool. @@ -81,8 +84,9 @@ The zpool .Sy free property is not generally useful for this purpose, and can be substantially more than the zfs .Sy available -space. This discrepancy is due to several factors, including raidz parity; zfs -reservation, quota, refreservation, and refquota properties; and space set aside by +space. +This discrepancy is due to several factors, including raidz parity; +zfs reservation, quota, refreservation, and refquota properties; and space set aside by .Sy spa_slop_shift (see .Xr zfs-module-parameters 5 @@ -107,14 +111,14 @@ A unique identifier for the pool. A unique identifier for the pool. Unlike the .Sy guid -property, this identifier is generated every time we load the pool (e.g. does +property, this identifier is generated every time we load the pool (i.e. does not persist across imports/exports) and never changes while the pool is loaded (even if a .Sy reguid operation takes place). .It Sy size Total size of the storage pool. -.It Sy unsupported@ Ns Em feature_guid +.It Sy unsupported@ Ns Em guid Information about unsupported features that are enabled on the pool. See .Xr zpool-features 5 @@ -173,22 +177,27 @@ command: Pool sector size exponent, to the power of .Sy 2 (internally referred to as -.Sy ashift -). Values from 9 to 16, inclusive, are valid; also, the +.Sy ashift ) . +Values from 9 to 16, inclusive, are valid; also, the value 0 (the default) means to auto-detect using the kernel's block -layer and a ZFS internal exception list. I/O operations will be aligned -to the specified size boundaries. Additionally, the minimum (disk) +layer and a ZFS internal exception list. +I/O operations will be aligned to the specified size boundaries. +Additionally, the minimum (disk) write size will be set to the specified size, so this represents a -space vs. performance trade-off. For optimal performance, the pool -sector size should be greater than or equal to the sector size of the -underlying disks. The typical case for setting this property is when +space vs. performance trade-off. +For optimal performance, the pool sector size should be greater than +or equal to the sector size of the underlying disks. +The typical case for setting this property is when performance is important and the underlying disks use 4KiB sectors but report 512B sectors to the OS (for compatibility reasons); in that case, set -.Sy ashift=12 -(which is 1<<12 = 4096). When set, this property is +.Sy ashift Ns = Ns Sy 12 +(which is +.Sy 1<<12 No = Sy 4096 ) . +When set, this property is used as the default hint value in subsequent vdev operations (add, -attach and replace). Changing this value will not modify any existing +attach and replace). +Changing this value will not modify any existing vdev, not even on disk replacement; however it can be used, for instance, to replace a dying 512B sectors disk with a newer 4KiB sectors device: this will probably result in bad performance but at the @@ -222,40 +231,44 @@ This property can also be referred to by its shortened column name, .Sy replace . Autoreplace can also be used with virtual disks (like device mapper) provided that you use the /dev/disk/by-vdev paths setup by -vdev_id.conf. See the +vdev_id.conf. +See the .Xr vdev_id 8 -man page for more details. +manual page for more details. Autoreplace and autoonline require the ZFS Event Daemon be configured and -running. See the +running. +See the .Xr zed 8 -man page for more details. +manual page for more details. .It Sy autotrim Ns = Ns Sy on Ns | Ns Sy off When set to .Sy on space which has been recently freed, and is no longer allocated by the pool, -will be periodically trimmed. This allows block device vdevs which support +will be periodically trimmed. +This allows block device vdevs which support BLKDISCARD, such as SSDs, or file vdevs on which the underlying file system -supports hole-punching, to reclaim unused blocks. The default setting for -this property is +supports hole-punching, to reclaim unused blocks. +The default value for this property is .Sy off . .Pp -Automatic TRIM does not immediately reclaim blocks after a free. Instead, -it will optimistically delay allowing smaller ranges to be aggregated in to -a few larger ones. These can then be issued more efficiently to the storage. +Automatic TRIM does not immediately reclaim blocks after a free. +Instead, it will optimistically delay allowing smaller ranges to be aggregated +into a few larger ones. +These can then be issued more efficiently to the storage. TRIM on L2ARC devices is enabled by setting .Sy l2arc_trim_ahead > 0 . .Pp Be aware that automatic trimming of recently freed data blocks can put -significant stress on the underlying storage devices. This will vary -depending of how well the specific device handles these commands. For -lower end devices it is often possible to achieve most of the benefits +significant stress on the underlying storage devices. +This will vary depending of how well the specific device handles these commands. +For lower-end devices it is often possible to achieve most of the benefits of automatic trimming by running an on-demand (manual) TRIM periodically using the .Nm zpool Cm trim command. -.It Sy bootfs Ns = Ns Sy (unset) Ns | Ns Ar pool Ns / Ns Ar dataset -Identifies the default bootable dataset for the root pool. This property is -expected to be set mainly by the installation and upgrade programs. +.It Sy bootfs Ns = Ns Sy (unset) Ns | Ns Ar pool Ns Op / Ns Ar dataset +Identifies the default bootable dataset for the root pool. +This property is expected to be set mainly by the installation and upgrade programs. Not all Linux distribution boot processes use the bootfs property. .It Sy cachefile Ns = Ns Ar path Ns | Ns Sy none Controls the location of where the pool configuration is cached. @@ -286,20 +299,24 @@ A text string consisting of printable ASCII characters that will be stored such that it is available even if the pool becomes faulted. An administrator can provide additional information about a pool using this property. -.It Sy compatibility Ns = Ns Ar off | legacy | file Bq , Ns Ar file Ns ... +.It Sy compatibility Ns = Ns Sy off Ns | Ns Sy legacy Ns | Ns Ar file Ns Oo , Ns Ar file Oc Ns … Specifies that the pool maintain compatibility with specific feature sets. When set to .Sy off -(or unset); compatibility is disabled (all features are enabled); when set to -.Sy legacy Ns ; -no features are enabled. When set to a comma-separated list of -filenames (each filename may either be an absolute path, or relative to -.Pa /etc/zfs/compatibility.d or Pa /usr/share/zfs/compatibility.d Ns ) +(or unset) compatibility is disabled (all features may be enabled); when set to +.Sy legacy Ns +no features may be enabled. +When set to a comma-separated list of filenames +(each filename may either be an absolute path, or relative to +.Pa /etc/zfs/compatibility.d +or +.Pa /usr/share/zfs/compatibility.d ) the lists of requested features are read from those files, separated by -whitespace and/or commas. Only features present in all files are enabled. - +whitespace and/or commas. +Only features present in all files may be enabled. +.Pp See -.Xr zpool-features 5 Ns , +.Xr zpool-features 5 , .Xr zpool-create 8 and .Xr zpool-upgrade 8 @@ -358,25 +375,30 @@ Controls whether a pool activity check should be performed during .Nm zpool Cm import . When a pool is determined to be active it cannot be imported, even with the .Fl f -option. This property is intended to be used in failover configurations +option. +This property is intended to be used in failover configurations where multiple hosts have access to a pool on shared storage. .Pp -Multihost provides protection on import only. It does not protect against an +Multihost provides protection on import only. +It does not protect against an individual device being used in multiple pools, regardless of the type of vdev. See the discussion under -.Sy zpool create. +.Nm zpool Cm create . .Pp When this property is on, periodic writes to storage occur to show the pool is -in use. See +in use. +See .Sy zfs_multihost_interval in the .Xr zfs-module-parameters 5 -man page. In order to enable this property each host must set a unique hostid. +manual page. +In order to enable this property each host must set a unique hostid. See .Xr genhostid 1 .Xr zgenhostid 8 .Xr spl-module-parameters 5 -for additional details. The default value is +for additional details. +The default value is .Sy off . .It Sy version Ns = Ns Ar version The current on-disk version of the pool. diff --git a/sys/contrib/openzfs/man/man8/zstream.8 b/sys/contrib/openzfs/man/man8/zstream.8 index 6056e097b0e..c0322ee3ace 100644 --- a/sys/contrib/openzfs/man/man8/zstream.8 +++ b/sys/contrib/openzfs/man/man8/zstream.8 @@ -18,14 +18,15 @@ .\" .\" CDDL HEADER END .\" -.\" .\" Copyright (c) 2020 by Delphix. All rights reserved. -.Dd March 25, 2020 +.\" +.Dd May 8, 2021 .Dt ZSTREAM 8 .Os +. .Sh NAME .Nm zstream -.Nd manipulate zfs send streams +.Nd manipulate ZFS send streams .Sh SYNOPSIS .Nm .Cm dump @@ -38,12 +39,11 @@ .Nm .Cm token .Ar resume_token +. .Sh DESCRIPTION -.sp -.LP The .Sy zstream -utility manipulates zfs send streams, which are the output of the +utility manipulates ZFS send streams output by the .Sy zfs send command. .Bl -tag -width "" @@ -68,6 +68,12 @@ Print metadata for each record. Dump data contained in each record. Implies verbose. .El +.Pp +The +.Nm zstreamdump +alias is provided for compatibility and is equivalent to running +.Nm +.Cm dump . .It Xo .Nm .Cm token @@ -97,14 +103,15 @@ command is provided a containing a deduplicated send stream, and outputs an equivalent non-deduplicated send stream on standard output. Therefore, a deduplicated send stream can be received by running: -.Bd -literal -# zstream redup DEDUP_STREAM_FILE | zfs receive ... -.Ed +.Dl # Nm zstream Cm redup Pa DEDUP_STREAM_FILE | Nm zfs Cm receive No … .Bl -tag -width "-D" .It Fl v Verbose. Print summary of converted records. +.El +.El +. .Sh SEE ALSO .Xr zfs 8 , -.Xr zfs-send 8 , -.Xr zfs-receive 8 +.Xr zfs-receive 8 , +.Xr zfs-send 8 diff --git a/sys/contrib/openzfs/man/man8/zstreamdump.8 b/sys/contrib/openzfs/man/man8/zstreamdump.8 deleted file mode 100644 index f499be442a4..00000000000 --- a/sys/contrib/openzfs/man/man8/zstreamdump.8 +++ /dev/null @@ -1,58 +0,0 @@ -'\" te -.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved -.\" 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] -.TH ZSTREAMDUMP 8 "Aug 24, 2020" OpenZFS -.SH NAME -zstreamdump \- filter data in zfs send stream -.SH SYNOPSIS -.LP -.nf -\fBzstreamdump\fR [\fB-C\fR] [\fB-v\fR] [\fB-d\fR] -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBzstreamdump\fR utility reads from the output of the \fBzfs send\fR -command, then displays headers and some statistics from that output. See -\fBzfs\fR(8). -.SH OPTIONS -.sp -.LP -The following options are supported: -.sp -.ne 2 -.na -\fB-C\fR -.ad -.sp .6 -.RS 4n -Suppress the validation of checksums. -.RE - -.sp -.ne 2 -.na -\fB-v\fR -.ad -.sp .6 -.RS 4n -Verbose. Dump all headers, not only begin and end headers. -.RE - -.sp -.ne 2 -.na -\fB-d\fR -.ad -.sp .6 -.RS 4n -Dump contents of blocks modified. Implies verbose. -.RE - -.SH SEE ALSO -.sp -.LP -\fBzfs\fR(8) diff --git a/sys/contrib/openzfs/man/man8/zstreamdump.8 b/sys/contrib/openzfs/man/man8/zstreamdump.8 new file mode 120000 index 00000000000..c6721daf11d --- /dev/null +++ b/sys/contrib/openzfs/man/man8/zstreamdump.8 @@ -0,0 +1 @@ +zstream.8 \ No newline at end of file diff --git a/sys/contrib/openzfs/module/avl/avl.c b/sys/contrib/openzfs/module/avl/avl.c index d0473d883b3..1a95092bc2b 100644 --- a/sys/contrib/openzfs/module/avl/avl.c +++ b/sys/contrib/openzfs/module/avl/avl.c @@ -1008,7 +1008,7 @@ avl_destroy_nodes(avl_tree_t *tree, void **cookie) --tree->avl_numnodes; /* - * If we just did a right child or there isn't one, go up to parent. + * If we just removed a right child or there isn't one, go up to parent. */ if (child == 1 || parent->avl_child[1] == NULL) { node = parent; diff --git a/sys/contrib/openzfs/module/icp/Makefile.in b/sys/contrib/openzfs/module/icp/Makefile.in index 7a01b2f08b8..858c5a610c2 100644 --- a/sys/contrib/openzfs/module/icp/Makefile.in +++ b/sys/contrib/openzfs/module/icp/Makefile.in @@ -45,7 +45,6 @@ $(MODULE)-objs += algs/aes/aes_modes.o $(MODULE)-objs += algs/edonr/edonr.o $(MODULE)-objs += algs/sha1/sha1.o $(MODULE)-objs += algs/sha2/sha2.o -$(MODULE)-objs += algs/sha1/sha1.o $(MODULE)-objs += algs/skein/skein.o $(MODULE)-objs += algs/skein/skein_block.o $(MODULE)-objs += algs/skein/skein_iv.o @@ -70,6 +69,12 @@ $(MODULE)-$(CONFIG_X86) += algs/aes/aes_impl_x86-64.o # utility tries to interpret them as opcodes and obviously fails doing so. OBJECT_FILES_NON_STANDARD_aesni-gcm-x86_64.o := y OBJECT_FILES_NON_STANDARD_ghash-x86_64.o := y +# Suppress objtool "unsupported stack pointer realignment" warnings. We are +# not using a DRAP register while aligning the stack to a 64 byte boundary. +# See #6950 for the reasoning. +OBJECT_FILES_NON_STANDARD_sha1-x86_64.o := y +OBJECT_FILES_NON_STANDARD_sha256_impl.o := y +OBJECT_FILES_NON_STANDARD_sha512_impl.o := y ICP_DIRS = \ api \ diff --git a/sys/contrib/openzfs/module/icp/algs/edonr/edonr.c b/sys/contrib/openzfs/module/icp/algs/edonr/edonr.c index 7c677095f1e..ee96e692ef0 100644 --- a/sys/contrib/openzfs/module/icp/algs/edonr/edonr.c +++ b/sys/contrib/openzfs/module/icp/algs/edonr/edonr.c @@ -337,7 +337,7 @@ Q256(size_t bitlen, const uint32_t *data, uint32_t *restrict p) * * Checksum functions like this one can go over the stack frame size check * Linux imposes on 32-bit platforms (-Wframe-larger-than=1024). We can - * safely ignore the compiler error since we know that in ZoL, that + * safely ignore the compiler error since we know that in OpenZFS, that * the function will be called from a worker thread that won't be using * much stack. The only function that goes over the 1k limit is Q512(), * which only goes over it by a hair (1248 bytes on ARM32). diff --git a/sys/contrib/openzfs/module/icp/algs/modes/gcm.c b/sys/contrib/openzfs/module/icp/algs/modes/gcm.c index 23686c59e8c..7332834cbe3 100644 --- a/sys/contrib/openzfs/module/icp/algs/modes/gcm.c +++ b/sys/contrib/openzfs/module/icp/algs/modes/gcm.c @@ -1399,7 +1399,7 @@ gcm_decrypt_final_avx(gcm_ctx_t *ctx, crypto_data_t *out, size_t block_size) } datap += done; } - /* Decrypt remainder, which is less then chunk size, in one go. */ + /* Decrypt remainder, which is less than chunk size, in one go. */ kfpu_begin(); if (bleft >= GCM_AVX_MIN_DECRYPT_BYTES) { done = aesni_gcm_decrypt(datap, datap, bleft, @@ -1415,7 +1415,7 @@ gcm_decrypt_final_avx(gcm_ctx_t *ctx, crypto_data_t *out, size_t block_size) ASSERT(bleft < GCM_AVX_MIN_DECRYPT_BYTES); /* - * Now less then GCM_AVX_MIN_DECRYPT_BYTES bytes remain, + * Now less than GCM_AVX_MIN_DECRYPT_BYTES bytes remain, * decrypt them block by block. */ while (bleft > 0) { diff --git a/sys/contrib/openzfs/module/icp/asm-x86_64/sha1/sha1-x86_64.S b/sys/contrib/openzfs/module/icp/asm-x86_64/sha1/sha1-x86_64.S index cb923784a73..fc844cd8c74 100644 --- a/sys/contrib/openzfs/module/icp/asm-x86_64/sha1/sha1-x86_64.S +++ b/sys/contrib/openzfs/module/icp/asm-x86_64/sha1/sha1-x86_64.S @@ -69,16 +69,27 @@ sha1_block_data_order(SHA1_CTX *ctx, const void *inpp, size_t blocks) #define _ASM #include ENTRY_NP(sha1_block_data_order) - push %rbx - push %rbp - push %r12 +.cfi_startproc mov %rsp,%rax +.cfi_def_cfa_register %rax + push %rbx +.cfi_offset %rbx,-16 + push %rbp +.cfi_offset %rbp,-24 + push %r12 +.cfi_offset %r12,-32 mov %rdi,%r8 # reassigned argument +.cfi_register %rdi, %r8 sub $72,%rsp mov %rsi,%r9 # reassigned argument +.cfi_register %rsi, %r9 and $-64,%rsp mov %rdx,%r10 # reassigned argument +.cfi_register %rdx, %r10 mov %rax,64(%rsp) +# echo ".cfi_cfa_expression %rsp+64,deref,+8" | +# openssl/crypto/perlasm/x86_64-xlate.pl +.cfi_escape 0x0f,0x06,0x77,0xc0,0x00,0x06,0x23,0x08 mov 0(%r8),%edx mov 4(%r8),%esi @@ -1337,10 +1348,15 @@ ENTRY_NP(sha1_block_data_order) sub $1,%r10 jnz .Lloop mov 64(%rsp),%rsp - pop %r12 - pop %rbp - pop %rbx +.cfi_def_cfa %rsp,8 + movq -24(%rsp),%r12 +.cfi_restore %r12 + movq -16(%rsp),%rbp +.cfi_restore %rbp + movq -8(%rsp),%rbx +.cfi_restore %rbx ret +.cfi_endproc SET_SIZE(sha1_block_data_order) .data diff --git a/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha256_impl.S b/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha256_impl.S index 766b75355f0..28b048d2db2 100644 --- a/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha256_impl.S +++ b/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha256_impl.S @@ -83,12 +83,21 @@ SHA256TransformBlocks(SHA2_CTX *ctx, const void *in, size_t num) #include ENTRY_NP(SHA256TransformBlocks) +.cfi_startproc + movq %rsp, %rax +.cfi_def_cfa_register %rax push %rbx +.cfi_offset %rbx,-16 push %rbp +.cfi_offset %rbp,-24 push %r12 +.cfi_offset %r12,-32 push %r13 +.cfi_offset %r13,-40 push %r14 +.cfi_offset %r14,-48 push %r15 +.cfi_offset %r15,-56 mov %rsp,%rbp # copy %rsp shl $4,%rdx # num*16 sub $16*4+4*8,%rsp @@ -99,6 +108,9 @@ ENTRY_NP(SHA256TransformBlocks) mov %rsi,16*4+1*8(%rsp) # save inp, 2nd arg mov %rdx,16*4+2*8(%rsp) # save end pointer, "3rd" arg mov %rbp,16*4+3*8(%rsp) # save copy of %rsp +# echo ".cfi_cfa_expression %rsp+88,deref,+56" | +# openssl/crypto/perlasm/x86_64-xlate.pl +.cfi_escape 0x0f,0x06,0x77,0xd8,0x00,0x06,0x23,0x38 #.picmeup %rbp # The .picmeup pseudo-directive, from perlasm/x86_64_xlate.pl, puts @@ -2026,14 +2038,28 @@ ENTRY_NP(SHA256TransformBlocks) jb .Lloop mov 16*4+3*8(%rsp),%rsp +.cfi_def_cfa %rsp,56 pop %r15 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r15 pop %r14 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r14 pop %r13 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r13 pop %r12 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r12 pop %rbp +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbp pop %rbx +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbx ret +.cfi_endproc SET_SIZE(SHA256TransformBlocks) .data diff --git a/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha512_impl.S b/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha512_impl.S index 6e37618761b..746c85a9856 100644 --- a/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha512_impl.S +++ b/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha512_impl.S @@ -84,12 +84,21 @@ SHA512TransformBlocks(SHA2_CTX *ctx, const void *in, size_t num) #include ENTRY_NP(SHA512TransformBlocks) +.cfi_startproc + movq %rsp, %rax +.cfi_def_cfa_register %rax push %rbx +.cfi_offset %rbx,-16 push %rbp +.cfi_offset %rbp,-24 push %r12 +.cfi_offset %r12,-32 push %r13 +.cfi_offset %r13,-40 push %r14 +.cfi_offset %r14,-48 push %r15 +.cfi_offset %r15,-56 mov %rsp,%rbp # copy %rsp shl $4,%rdx # num*16 sub $16*8+4*8,%rsp @@ -100,6 +109,9 @@ ENTRY_NP(SHA512TransformBlocks) mov %rsi,16*8+1*8(%rsp) # save inp, 2nd arg mov %rdx,16*8+2*8(%rsp) # save end pointer, "3rd" arg mov %rbp,16*8+3*8(%rsp) # save copy of %rsp +# echo ".cfi_cfa_expression %rsp+152,deref,+56" | +# openssl/crypto/perlasm/x86_64-xlate.pl +.cfi_escape 0x0f,0x06,0x77,0x98,0x01,0x06,0x23,0x38 #.picmeup %rbp # The .picmeup pseudo-directive, from perlasm/x86_64_xlate.pl, puts @@ -2027,14 +2039,28 @@ ENTRY_NP(SHA512TransformBlocks) jb .Lloop mov 16*8+3*8(%rsp),%rsp +.cfi_def_cfa %rsp,56 pop %r15 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r15 pop %r14 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r14 pop %r13 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r13 pop %r12 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r12 pop %rbp +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbp pop %rbx +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbx ret +.cfi_endproc SET_SIZE(SHA512TransformBlocks) .data diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/acl_common.c b/sys/contrib/openzfs/module/os/freebsd/spl/acl_common.c index 66e27cefa39..7fd0e36e1ba 100644 --- a/sys/contrib/openzfs/module/os/freebsd/spl/acl_common.c +++ b/sys/contrib/openzfs/module/os/freebsd/spl/acl_common.c @@ -43,7 +43,6 @@ #include #include #include -#define ASSERT assert #endif #define ACE_POSIX_SUPPORTED_BITS (ACE_READ_DATA | \ @@ -170,8 +169,9 @@ ksort(caddr_t v, int n, int s, int (*f)(void *, void *)) return; /* Sanity check on arguments */ - ASSERT(((uintptr_t)v & 0x3) == 0 && (s & 0x3) == 0); - ASSERT(s > 0); + ASSERT3U(((uintptr_t)v & 0x3), ==, 0); + ASSERT3S((s & 0x3), ==, 0); + ASSERT3S(s, >, 0); for (g = n / 2; g > 0; g /= 2) { for (i = g; i < n; i++) { for (j = i - g; j >= 0 && diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/callb.c b/sys/contrib/openzfs/module/os/freebsd/spl/callb.c index fffa85b6b91..0b7fefc89a2 100644 --- a/sys/contrib/openzfs/module/os/freebsd/spl/callb.c +++ b/sys/contrib/openzfs/module/os/freebsd/spl/callb.c @@ -75,7 +75,7 @@ typedef struct callb { typedef struct callb_table { kmutex_t ct_lock; /* protect all callb states */ callb_t *ct_freelist; /* free callb structures */ - int ct_busy; /* != 0 prevents additions */ + boolean_t ct_busy; /* B_TRUE prevents additions */ kcondvar_t ct_busy_cv; /* to wait for not busy */ int ct_ncallb; /* num of callbs allocated */ callb_t *ct_first_cb[NCBCLASS]; /* ptr to 1st callb in a class */ @@ -98,7 +98,7 @@ callb_cpr_t callb_cprinfo_safe = { static void callb_init(void *dummy __unused) { - callb_table.ct_busy = 0; /* mark table open for additions */ + callb_table.ct_busy = B_FALSE; /* mark table open for additions */ mutex_init(&callb_safe_mutex, NULL, MUTEX_DEFAULT, NULL); mutex_init(&callb_table.ct_lock, NULL, MUTEX_DEFAULT, NULL); } @@ -139,7 +139,7 @@ callb_add_common(boolean_t (*func)(void *arg, int code), { callb_t *cp; - ASSERT(class < NCBCLASS); + ASSERT3S(class, <, NCBCLASS); mutex_enter(&ct->ct_lock); while (ct->ct_busy) @@ -259,7 +259,7 @@ callb_execute_class(int class, int code) callb_t *cp; void *ret = NULL; - ASSERT(class < NCBCLASS); + ASSERT3S(class, <, NCBCLASS); mutex_enter(&ct->ct_lock); @@ -351,8 +351,8 @@ void callb_lock_table(void) { mutex_enter(&ct->ct_lock); - ASSERT(ct->ct_busy == 0); - ct->ct_busy = 1; + ASSERT(!ct->ct_busy); + ct->ct_busy = B_TRUE; mutex_exit(&ct->ct_lock); } @@ -363,8 +363,8 @@ void callb_unlock_table(void) { mutex_enter(&ct->ct_lock); - ASSERT(ct->ct_busy != 0); - ct->ct_busy = 0; + ASSERT(ct->ct_busy); + ct->ct_busy = B_FALSE; cv_broadcast(&ct->ct_busy_cv); mutex_exit(&ct->ct_lock); } diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/list.c b/sys/contrib/openzfs/module/os/freebsd/spl/list.c index 0f5ae629126..62374a41770 100644 --- a/sys/contrib/openzfs/module/os/freebsd/spl/list.c +++ b/sys/contrib/openzfs/module/os/freebsd/spl/list.c @@ -61,9 +61,8 @@ void list_create(list_t *list, size_t size, size_t offset) { - ASSERT(list); - ASSERT(size > 0); - ASSERT(size >= offset + sizeof (list_node_t)); + ASSERT3P(list, !=, NULL); + ASSERT3U(size, >=, offset + sizeof (list_node_t)); list->list_size = size; list->list_offset = offset; @@ -76,9 +75,9 @@ list_destroy(list_t *list) { list_node_t *node = &list->list_head; - ASSERT(list); - ASSERT(list->list_head.list_next == node); - ASSERT(list->list_head.list_prev == node); + ASSERT3P(list, !=, NULL); + ASSERT3P(list->list_head.list_next, ==, node); + ASSERT3P(list->list_head.list_prev, ==, node); node->list_next = node->list_prev = NULL; } @@ -124,7 +123,7 @@ list_remove(list_t *list, void *object) { list_node_t *lold = list_d2l(list, object); ASSERT(!list_empty(list)); - ASSERT(lold->list_next != NULL); + ASSERT3P(lold->list_next, !=, NULL); list_remove_node(lold); } @@ -195,8 +194,8 @@ list_move_tail(list_t *dst, list_t *src) list_node_t *dstnode = &dst->list_head; list_node_t *srcnode = &src->list_head; - ASSERT(dst->list_size == src->list_size); - ASSERT(dst->list_offset == src->list_offset); + ASSERT3U(dst->list_size, ==, src->list_size); + ASSERT3U(dst->list_offset, ==, src->list_offset); if (list_empty(src)) return; diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/spl_kmem.c b/sys/contrib/openzfs/module/os/freebsd/spl/spl_kmem.c index cfc61dd7fc2..ee8f1d851a4 100644 --- a/sys/contrib/openzfs/module/os/freebsd/spl/spl_kmem.c +++ b/sys/contrib/openzfs/module/os/freebsd/spl/spl_kmem.c @@ -112,7 +112,7 @@ zfs_kmem_free(void *buf, size_t size __unused) if (i == buf) break; } - ASSERT(i != NULL); + ASSERT3P(i, !=, NULL); LIST_REMOVE(i, next); mtx_unlock(&kmem_items_mtx); memset(buf, 0xDC, MAX(size, 16)); @@ -162,7 +162,7 @@ kmem_cache_create(char *name, size_t bufsize, size_t align, { kmem_cache_t *cache; - ASSERT(vmp == NULL); + ASSERT3P(vmp, ==, NULL); cache = kmem_alloc(sizeof (*cache), KM_SLEEP); strlcpy(cache->kc_name, name, sizeof (cache->kc_name)); @@ -324,7 +324,7 @@ void spl_kmem_cache_set_move(kmem_cache_t *skc, kmem_cbrc_t (move)(void *, void *, size_t, void *)) { - ASSERT(move != NULL); + ASSERT3P(move, !=, NULL); } #ifdef KMEM_DEBUG diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/spl_kstat.c b/sys/contrib/openzfs/module/os/freebsd/spl/spl_kstat.c index 43ce358298b..e591921ace1 100644 --- a/sys/contrib/openzfs/module/os/freebsd/spl/spl_kstat.c +++ b/sys/contrib/openzfs/module/os/freebsd/spl/spl_kstat.c @@ -69,7 +69,7 @@ __kstat_set_seq_raw_ops(kstat_t *ksp, static int kstat_default_update(kstat_t *ksp, int rw) { - ASSERT(ksp != NULL); + ASSERT3P(ksp, !=, NULL); if (rw == KSTAT_WRITE) return (EACCES); @@ -223,7 +223,7 @@ restart: sbuf_printf(sb, "%s", ksp->ks_raw_buf); } else { - ASSERT(ksp->ks_ndata == 1); + ASSERT3U(ksp->ks_ndata, ==, 1); sbuf_hexdump(sb, ksp->ks_data, ksp->ks_data_size, NULL, 0); } @@ -250,7 +250,7 @@ __kstat_create(const char *module, int instance, const char *name, KASSERT(instance == 0, ("instance=%d", instance)); if ((ks_type == KSTAT_TYPE_INTR) || (ks_type == KSTAT_TYPE_IO)) - ASSERT(ks_ndata == 1); + ASSERT3U(ks_ndata, ==, 1); if (class == NULL) class = "misc"; @@ -461,7 +461,7 @@ kstat_install(kstat_t *ksp) struct sysctl_oid *root; if (ksp->ks_ndata == UINT32_MAX) - VERIFY(ksp->ks_type == KSTAT_TYPE_RAW); + VERIFY3U(ksp->ks_type, ==, KSTAT_TYPE_RAW); switch (ksp->ks_type) { case KSTAT_TYPE_NAMED: @@ -493,7 +493,7 @@ kstat_install(kstat_t *ksp) default: panic("unsupported kstat type %d\n", ksp->ks_type); } - VERIFY(root != NULL); + VERIFY3P(root, !=, NULL); ksp->ks_sysctl_root = root; } @@ -535,7 +535,7 @@ kstat_waitq_exit(kstat_io_t *kiop) delta = new - kiop->wlastupdate; kiop->wlastupdate = new; wcnt = kiop->wcnt--; - ASSERT((int)wcnt > 0); + ASSERT3S(wcnt, >, 0); kiop->wlentime += delta * wcnt; kiop->wtime += delta; } @@ -566,7 +566,7 @@ kstat_runq_exit(kstat_io_t *kiop) delta = new - kiop->rlastupdate; kiop->rlastupdate = new; rcnt = kiop->rcnt--; - ASSERT((int)rcnt > 0); + ASSERT3S(rcnt, >, 0); kiop->rlentime += delta * rcnt; kiop->rtime += delta; } diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/spl_string.c b/sys/contrib/openzfs/module/os/freebsd/spl/spl_string.c index d13b64b4cd2..00b1df766ab 100644 --- a/sys/contrib/openzfs/module/os/freebsd/spl/spl_string.c +++ b/sys/contrib/openzfs/module/os/freebsd/spl/spl_string.c @@ -102,6 +102,6 @@ kmem_asprintf(const char *fmt, ...) void kmem_strfree(char *str) { - ASSERT(str != NULL); + ASSERT3P(str, !=, NULL); kmem_free(str, strlen(str) + 1); } diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/spl_sysevent.c b/sys/contrib/openzfs/module/os/freebsd/spl/spl_sysevent.c index 8c0e495681e..d5d50080faf 100644 --- a/sys/contrib/openzfs/module/os/freebsd/spl/spl_sysevent.c +++ b/sys/contrib/openzfs/module/os/freebsd/spl/spl_sysevent.c @@ -245,7 +245,7 @@ sysevent_worker(void *arg __unused) if (error == ESHUTDOWN) break; } else { - VERIFY(event != NULL); + VERIFY3P(event, !=, NULL); log_sysevent(event); nvlist_free(event); } diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/spl_uio.c b/sys/contrib/openzfs/module/os/freebsd/spl/spl_uio.c index 59a781ee1b6..0bf251a1eda 100644 --- a/sys/contrib/openzfs/module/os/freebsd/spl/spl_uio.c +++ b/sys/contrib/openzfs/module/os/freebsd/spl/spl_uio.c @@ -48,7 +48,7 @@ int zfs_uiomove(void *cp, size_t n, zfs_uio_rw_t dir, zfs_uio_t *uio) { - ASSERT(zfs_uio_rw(uio) == dir); + ASSERT3U(zfs_uio_rw(uio), ==, dir); return (uiomove(cp, (int)n, GET_UIO_STRUCT(uio))); } @@ -102,6 +102,6 @@ zfs_uioskip(zfs_uio_t *uio, size_t n) int zfs_uio_fault_move(void *p, size_t n, zfs_uio_rw_t dir, zfs_uio_t *uio) { - ASSERT(zfs_uio_rw(uio) == dir); + ASSERT3U(zfs_uio_rw(uio), ==, dir); return (vn_io_fault_uiomove(p, n, GET_UIO_STRUCT(uio))); } diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/spl_vfs.c b/sys/contrib/openzfs/module/os/freebsd/spl/spl_vfs.c index 09c8401267d..60ea627e975 100644 --- a/sys/contrib/openzfs/module/os/freebsd/spl/spl_vfs.c +++ b/sys/contrib/openzfs/module/os/freebsd/spl/spl_vfs.c @@ -275,13 +275,13 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath, void vn_rele_async(vnode_t *vp, taskq_t *taskq) { - VERIFY(vp->v_count > 0); + VERIFY3U(vp->v_usecount, >, 0); if (refcount_release_if_not_last(&vp->v_usecount)) { #if __FreeBSD_version < 1300045 vdrop(vp); #endif return; } - VERIFY(taskq_dispatch((taskq_t *)taskq, - (task_func_t *)vrele, vp, TQ_SLEEP) != 0); + VERIFY3U(taskq_dispatch((taskq_t *)taskq, + (task_func_t *)vrele, vp, TQ_SLEEP), !=, 0); } diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/abd_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/abd_os.c index ff4d80ef1df..00aa21c6c9e 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/abd_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/abd_os.c @@ -168,8 +168,7 @@ abd_verify_scatter(abd_t *abd) * if an error if the ABD has been marked as a linear page. */ ASSERT(!abd_is_linear_page(abd)); - ASSERT3U(ABD_SCATTER(abd).abd_offset, <, - zfs_abd_chunk_size); + ASSERT3U(ABD_SCATTER(abd).abd_offset, <, zfs_abd_chunk_size); n = abd_scatter_chunkcnt(abd); for (i = 0; i < n; i++) { ASSERT3P(ABD_SCATTER(abd).abd_chunks[i], !=, NULL); @@ -306,7 +305,7 @@ void abd_free_linear_page(abd_t *abd) { /* - * FreeBSD does not have have scatter linear pages + * FreeBSD does not have scatter linear pages * so there is an error. */ VERIFY(0); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/arc_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/arc_os.c index e73efd810e5..05377bb7ed9 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/arc_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/arc_os.c @@ -158,11 +158,7 @@ arc_default_max(uint64_t min, uint64_t allmem) static void arc_prune_task(void *arg) { -#ifdef __LP64__ - int64_t nr_scan = (int64_t)arg; -#else - int64_t nr_scan = (int32_t)arg; -#endif + int64_t nr_scan = (intptr_t)arg; arc_reduce_target_size(ptob(nr_scan)); #if __FreeBSD_version >= 1300139 @@ -188,15 +184,13 @@ arc_prune_task(void *arg) void arc_prune_async(int64_t adjust) { - int64_t *adjustptr; #ifndef __LP64__ - if (adjust > __LONG_MAX) - adjust = __LONG_MAX; + if (adjust > INTPTR_MAX) + adjust = INTPTR_MAX; #endif - - adjustptr = (void *)adjust; - taskq_dispatch(arc_prune_taskq, arc_prune_task, adjustptr, TQ_SLEEP); + taskq_dispatch(arc_prune_taskq, arc_prune_task, + (void *)(intptr_t)adjust, TQ_SLEEP); ARCSTAT_BUMP(arcstat_prune); } diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/crypto_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/crypto_os.c index 03d14ed7cf5..6a67dbc9f61 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/crypto_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/crypto_os.c @@ -172,11 +172,13 @@ zfs_crypto_dispatch(freebsd_crypt_session_t *session, struct cryptop *crp) break; mtx_lock(&session->fs_lock); while (session->fs_done == false) - msleep(crp, &session->fs_lock, PRIBIO, - "zfs_crypto", hz/5); + msleep(crp, &session->fs_lock, 0, + "zfs_crypto", 0); mtx_unlock(&session->fs_lock); - if (crp->crp_etype != EAGAIN) { + if (crp->crp_etype == ENOMEM) { + pause("zcrnomem", 1); + } else if (crp->crp_etype != EAGAIN) { error = crp->crp_etype; break; } diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c index fb8f560316e..2cf54a3cef6 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c @@ -120,7 +120,7 @@ dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_buf_t *db = dbp[i]; caddr_t va; - ASSERT(size > 0); + ASSERT3U(size, >, 0); ASSERT3U(db->db_size, >=, PAGESIZE); bufoff = offset - db->db_offset; @@ -170,7 +170,7 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count, int err; ASSERT3U(ma[0]->pindex + count - 1, ==, ma[count - 1]->pindex); - ASSERT(last_size <= PAGE_SIZE); + ASSERT3S(last_size, <=, PAGE_SIZE); err = dmu_buf_hold_array(os, object, IDX_TO_OFF(ma[0]->pindex), IDX_TO_OFF(count - 1) + last_size, TRUE, FTAG, &numbufs, &dbp); @@ -182,7 +182,7 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count, if (dbp[0]->db_offset != 0 || numbufs > 1) { for (i = 0; i < numbufs; i++) { ASSERT(ISP2(dbp[i]->db_size)); - ASSERT((dbp[i]->db_offset % dbp[i]->db_size) == 0); + ASSERT3U((dbp[i]->db_offset % dbp[i]->db_size), ==, 0); ASSERT3U(dbp[i]->db_size, ==, dbp[0]->db_size); } } @@ -202,10 +202,10 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count, vm_page_do_sunbusy(m); break; } - ASSERT(m->dirty == 0); + ASSERT3U(m->dirty, ==, 0); ASSERT(!pmap_page_is_write_mapped(m)); - ASSERT(db->db_size > PAGE_SIZE); + ASSERT3U(db->db_size, >, PAGE_SIZE); bufoff = IDX_TO_OFF(m->pindex) % db->db_size; va = zfs_map_page(m, &sf); bcopy((char *)db->db_data + bufoff, va, PAGESIZE); @@ -229,7 +229,7 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count, if (m != bogus_page) { vm_page_assert_xbusied(m); ASSERT(vm_page_none_valid(m)); - ASSERT(m->dirty == 0); + ASSERT3U(m->dirty, ==, 0); ASSERT(!pmap_page_is_write_mapped(m)); va = zfs_map_page(m, &sf); } @@ -248,25 +248,28 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count, * end of file anyway. */ tocpy = MIN(db->db_size - bufoff, PAGESIZE - pgoff); + ASSERT3S(tocpy, >=, 0); if (m != bogus_page) bcopy((char *)db->db_data + bufoff, va + pgoff, tocpy); pgoff += tocpy; - ASSERT(pgoff <= PAGESIZE); + ASSERT3S(pgoff, >=, 0); + ASSERT3S(pgoff, <=, PAGESIZE); if (pgoff == PAGESIZE) { if (m != bogus_page) { zfs_unmap_page(sf); vm_page_valid(m); } - ASSERT(mi < count); + ASSERT3S(mi, <, count); mi++; pgoff = 0; } bufoff += tocpy; - ASSERT(bufoff <= db->db_size); + ASSERT3S(bufoff, >=, 0); + ASSERT3S(bufoff, <=, db->db_size); if (bufoff == db->db_size) { - ASSERT(di < numbufs); + ASSERT3S(di, <, numbufs); di++; bufoff = 0; } @@ -286,23 +289,23 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count, * with a size that is not a multiple of the page size. */ if (mi == count) { - ASSERT(di >= numbufs - 1); + ASSERT3S(di, >=, numbufs - 1); IMPLY(*rahead != 0, di == numbufs - 1); IMPLY(*rahead != 0, bufoff != 0); - ASSERT(pgoff == 0); + ASSERT0(pgoff); } if (di == numbufs) { - ASSERT(mi >= count - 1); - ASSERT(*rahead == 0); + ASSERT3S(mi, >=, count - 1); + ASSERT0(*rahead); IMPLY(pgoff == 0, mi == count); if (pgoff != 0) { - ASSERT(mi == count - 1); - ASSERT((dbp[0]->db_size & PAGE_MASK) != 0); + ASSERT3S(mi, ==, count - 1); + ASSERT3U((dbp[0]->db_size & PAGE_MASK), !=, 0); } } #endif if (pgoff != 0) { - ASSERT(m != bogus_page); + ASSERT3P(m, !=, bogus_page); bzero(va + pgoff, PAGESIZE - pgoff); zfs_unmap_page(sf); vm_page_valid(m); @@ -318,17 +321,17 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count, vm_page_do_sunbusy(m); break; } - ASSERT(m->dirty == 0); + ASSERT3U(m->dirty, ==, 0); ASSERT(!pmap_page_is_write_mapped(m)); - ASSERT(db->db_size > PAGE_SIZE); + ASSERT3U(db->db_size, >, PAGE_SIZE); bufoff = IDX_TO_OFF(m->pindex) % db->db_size; tocpy = MIN(db->db_size - bufoff, PAGESIZE); va = zfs_map_page(m, &sf); bcopy((char *)db->db_data + bufoff, va, tocpy); if (tocpy < PAGESIZE) { - ASSERT(i == *rahead - 1); - ASSERT((db->db_size & PAGE_MASK) != 0); + ASSERT3S(i, ==, *rahead - 1); + ASSERT3U((db->db_size & PAGE_MASK), !=, 0); bzero(va + tocpy, PAGESIZE - tocpy); } zfs_unmap_page(sf); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c b/sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c index d5ba0d93a56..d9096575d85 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c @@ -113,7 +113,6 @@ static int zfs__fini(void); static void zfs_shutdown(void *, int); static eventhandler_tag zfs_shutdown_event_tag; -extern zfsdev_state_t *zfsdev_state_list; #define ZFS_MIN_KSTACK_PAGES 4 @@ -182,70 +181,29 @@ out: static void zfsdev_close(void *data) { - zfsdev_state_t *zs = data; - - ASSERT(zs != NULL); - - mutex_enter(&zfsdev_state_lock); - - ASSERT(zs->zs_minor != 0); - - zs->zs_minor = -1; - zfs_onexit_destroy(zs->zs_onexit); - zfs_zevent_destroy(zs->zs_zevent); - zs->zs_onexit = NULL; - zs->zs_zevent = NULL; - - mutex_exit(&zfsdev_state_lock); + zfsdev_state_destroy(data); } -static int -zfs_ctldev_init(struct cdev *devp) +void +zfsdev_private_set_state(void *priv __unused, zfsdev_state_t *zs) { - boolean_t newzs = B_FALSE; - minor_t minor; - zfsdev_state_t *zs, *zsprev = NULL; - - ASSERT(MUTEX_HELD(&zfsdev_state_lock)); - - minor = zfsdev_minor_alloc(); - if (minor == 0) - return (SET_ERROR(ENXIO)); - - for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) { - if (zs->zs_minor == -1) - break; - zsprev = zs; - } - - if (!zs) { - zs = kmem_zalloc(sizeof (zfsdev_state_t), KM_SLEEP); - newzs = B_TRUE; - } - devfs_set_cdevpriv(zs, zfsdev_close); +} - zfs_onexit_init((zfs_onexit_t **)&zs->zs_onexit); - zfs_zevent_init((zfs_zevent_t **)&zs->zs_zevent); - - if (newzs) { - zs->zs_minor = minor; - wmb(); - zsprev->zs_next = zs; - } else { - wmb(); - zs->zs_minor = minor; - } - return (0); +zfsdev_state_t * +zfsdev_private_get_state(void *priv) +{ + return (priv); } static int -zfsdev_open(struct cdev *devp, int flag, int mode, struct thread *td) +zfsdev_open(struct cdev *devp __unused, int flag __unused, int mode __unused, + struct thread *td __unused) { int error; mutex_enter(&zfsdev_state_lock); - error = zfs_ctldev_init(devp); + error = zfsdev_state_init(NULL); mutex_exit(&zfsdev_state_lock); return (error); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c index 2bc78cb451e..070e7a5b9f1 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c @@ -95,8 +95,7 @@ spa_generate_rootconf(const char *name) for (i = 0; i < count; i++) { uint64_t txg; - VERIFY(nvlist_lookup_uint64(configs[i], ZPOOL_CONFIG_POOL_TXG, - &txg) == 0); + txg = fnvlist_lookup_uint64(configs[i], ZPOOL_CONFIG_POOL_TXG); if (txg > best_txg) { best_txg = txg; best_cfg = configs[i]; @@ -115,72 +114,66 @@ spa_generate_rootconf(const char *name) break; if (configs[i] == NULL) continue; - VERIFY(nvlist_lookup_nvlist(configs[i], ZPOOL_CONFIG_VDEV_TREE, - &nvtop) == 0); - nvlist_dup(nvtop, &tops[i], KM_SLEEP); + nvtop = fnvlist_lookup_nvlist(configs[i], + ZPOOL_CONFIG_VDEV_TREE); + tops[i] = fnvlist_dup(nvtop); } for (i = 0; holes != NULL && i < nholes; i++) { if (i >= nchildren) continue; if (tops[holes[i]] != NULL) continue; - nvlist_alloc(&tops[holes[i]], NV_UNIQUE_NAME, KM_SLEEP); - VERIFY(nvlist_add_string(tops[holes[i]], ZPOOL_CONFIG_TYPE, - VDEV_TYPE_HOLE) == 0); - VERIFY(nvlist_add_uint64(tops[holes[i]], ZPOOL_CONFIG_ID, - holes[i]) == 0); - VERIFY(nvlist_add_uint64(tops[holes[i]], ZPOOL_CONFIG_GUID, - 0) == 0); + tops[holes[i]] = fnvlist_alloc(); + fnvlist_add_string(tops[holes[i]], ZPOOL_CONFIG_TYPE, + VDEV_TYPE_HOLE); + fnvlist_add_uint64(tops[holes[i]], ZPOOL_CONFIG_ID, holes[i]); + fnvlist_add_uint64(tops[holes[i]], ZPOOL_CONFIG_GUID, 0); } for (i = 0; i < nchildren; i++) { if (tops[i] != NULL) continue; - nvlist_alloc(&tops[i], NV_UNIQUE_NAME, KM_SLEEP); - VERIFY(nvlist_add_string(tops[i], ZPOOL_CONFIG_TYPE, - VDEV_TYPE_MISSING) == 0); - VERIFY(nvlist_add_uint64(tops[i], ZPOOL_CONFIG_ID, - i) == 0); - VERIFY(nvlist_add_uint64(tops[i], ZPOOL_CONFIG_GUID, - 0) == 0); + tops[i] = fnvlist_alloc(); + fnvlist_add_string(tops[i], ZPOOL_CONFIG_TYPE, + VDEV_TYPE_MISSING); + fnvlist_add_uint64(tops[i], ZPOOL_CONFIG_ID, i); + fnvlist_add_uint64(tops[i], ZPOOL_CONFIG_GUID, 0); } /* * Create pool config based on the best vdev config. */ - nvlist_dup(best_cfg, &config, KM_SLEEP); + config = fnvlist_dup(best_cfg); /* * Put this pool's top-level vdevs into a root vdev. */ - VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, - &pgid) == 0); - VERIFY(nvlist_alloc(&nvroot, NV_UNIQUE_NAME, KM_SLEEP) == 0); - VERIFY(nvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE, - VDEV_TYPE_ROOT) == 0); - VERIFY(nvlist_add_uint64(nvroot, ZPOOL_CONFIG_ID, 0ULL) == 0); - VERIFY(nvlist_add_uint64(nvroot, ZPOOL_CONFIG_GUID, pgid) == 0); - VERIFY(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, - tops, nchildren) == 0); + pgid = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID); + nvroot = fnvlist_alloc(); + fnvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE, VDEV_TYPE_ROOT); + fnvlist_add_uint64(nvroot, ZPOOL_CONFIG_ID, 0ULL); + fnvlist_add_uint64(nvroot, ZPOOL_CONFIG_GUID, pgid); + fnvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, tops, + nchildren); /* * Replace the existing vdev_tree with the new root vdev in * this pool's configuration (remove the old, add the new). */ - VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot) == 0); + fnvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot); /* * Drop vdev config elements that should not be present at pool level. */ - nvlist_remove(config, ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64); - nvlist_remove(config, ZPOOL_CONFIG_TOP_GUID, DATA_TYPE_UINT64); + fnvlist_remove(config, ZPOOL_CONFIG_GUID); + fnvlist_remove(config, ZPOOL_CONFIG_TOP_GUID); for (i = 0; i < count; i++) - nvlist_free(configs[i]); + fnvlist_free(configs[i]); kmem_free(configs, count * sizeof (void *)); for (i = 0; i < nchildren; i++) - nvlist_free(tops[i]); + fnvlist_free(tops[i]); kmem_free(tops, nchildren * sizeof (void *)); - nvlist_free(nvroot); + fnvlist_free(nvroot); return (config); } @@ -201,10 +194,9 @@ spa_import_rootpool(const char *name, bool checkpointrewind) mutex_enter(&spa_namespace_lock); if (config != NULL) { - VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, - &pname) == 0 && strcmp(name, pname) == 0); - VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, &txg) - == 0); + pname = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME); + VERIFY0(strcmp(name, pname)); + txg = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG); if ((spa = spa_lookup(pname)) != NULL) { /* @@ -213,7 +205,7 @@ spa_import_rootpool(const char *name, bool checkpointrewind) */ if (spa->spa_state == POOL_STATE_ACTIVE) { mutex_exit(&spa_namespace_lock); - nvlist_free(config); + fnvlist_free(config); return (0); } @@ -235,12 +227,12 @@ spa_import_rootpool(const char *name, bool checkpointrewind) spa->spa_ubsync.ub_version = SPA_VERSION_INITIAL; } else if ((spa = spa_lookup(name)) == NULL) { mutex_exit(&spa_namespace_lock); - nvlist_free(config); + fnvlist_free(config); cmn_err(CE_NOTE, "Cannot find the pool label for '%s'", name); return (EIO); } else { - VERIFY(nvlist_dup(spa->spa_config, &config, KM_SLEEP) == 0); + config = fnvlist_dup(spa->spa_config); } spa->spa_is_root = B_TRUE; spa->spa_import_flags = ZFS_IMPORT_VERBATIM; @@ -251,15 +243,14 @@ spa_import_rootpool(const char *name, bool checkpointrewind) /* * Build up a vdev tree based on the boot device's label config. */ - VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, - &nvtop) == 0); + nvtop = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); error = spa_config_parse(spa, &rvd, nvtop, NULL, 0, VDEV_ALLOC_ROOTPOOL); spa_config_exit(spa, SCL_ALL, FTAG); if (error) { mutex_exit(&spa_namespace_lock); - nvlist_free(config); + fnvlist_free(config); cmn_err(CE_NOTE, "Can not parse the config for pool '%s'", pname); return (error); @@ -270,7 +261,7 @@ spa_import_rootpool(const char *name, bool checkpointrewind) spa_config_exit(spa, SCL_ALL, FTAG); mutex_exit(&spa_namespace_lock); - nvlist_free(config); + fnvlist_free(config); return (0); } diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_file.c b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_file.c index 825bd706e0c..fc04a747615 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_file.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_file.c @@ -59,13 +59,13 @@ vdev_file_fini(void) static void vdev_file_hold(vdev_t *vd) { - ASSERT(vd->vdev_path != NULL); + ASSERT3P(vd->vdev_path, !=, NULL); } static void vdev_file_rele(vdev_t *vd) { - ASSERT(vd->vdev_path != NULL); + ASSERT3P(vd->vdev_path, !=, NULL); } static mode_t @@ -137,7 +137,8 @@ vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, * administrator has already decided that the pool should be available * to local zone users, so the underlying devices should be as well. */ - ASSERT(vd->vdev_path != NULL && vd->vdev_path[0] == '/'); + ASSERT3P(vd->vdev_path, !=, NULL); + ASSERT(vd->vdev_path[0] == '/'); error = zfs_file_open(vd->vdev_path, vdev_file_open_mode(spa_mode(vd->vdev_spa)), 0, &fp); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_geom.c b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_geom.c index c9e8e21982c..3853b2b5c90 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_geom.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_geom.c @@ -396,8 +396,8 @@ vdev_geom_io(struct g_consumer *cp, int *cmds, void **datas, off_t *offsets, p = datas[i]; s = sizes[i]; end = off + s; - ASSERT((off % cp->provider->sectorsize) == 0); - ASSERT((s % cp->provider->sectorsize) == 0); + ASSERT0(off % cp->provider->sectorsize); + ASSERT0(s % cp->provider->sectorsize); for (; off < end; off += maxio, p += maxio, s -= maxio, j++) { bios[j] = g_alloc_bio(); @@ -409,7 +409,7 @@ vdev_geom_io(struct g_consumer *cp, int *cmds, void **datas, off_t *offsets, g_io_request(bios[j], cp); } } - ASSERT(j == n_bios); + ASSERT3S(j, ==, n_bios); /* Wait for all of the bios to complete, and clean them up */ for (i = j = 0; i < ncmds; i++) { @@ -467,7 +467,7 @@ vdev_geom_read_config(struct g_consumer *cp, nvlist_t **configp) offsets[l] = vdev_label_offset(psize, l, 0) + VDEV_SKIP_SIZE; sizes[l] = size; errors[l] = 0; - ASSERT(offsets[l] % pp->sectorsize == 0); + ASSERT0(offsets[l] % pp->sectorsize); } /* Issue the IO requests */ @@ -557,7 +557,7 @@ process_vdev_config(nvlist_t ***configs, uint64_t *count, nvlist_t *cfg, if (nvlist_lookup_uint64(vdev_tree, ZPOOL_CONFIG_ID, &id) != 0) goto ignore; - VERIFY(nvlist_lookup_uint64(cfg, ZPOOL_CONFIG_POOL_TXG, &txg) == 0); + txg = fnvlist_lookup_uint64(cfg, ZPOOL_CONFIG_POOL_TXG); if (*known_pool_guid != 0) { if (pool_guid != *known_pool_guid) @@ -568,8 +568,8 @@ process_vdev_config(nvlist_t ***configs, uint64_t *count, nvlist_t *cfg, resize_configs(configs, count, id); if ((*configs)[id] != NULL) { - VERIFY(nvlist_lookup_uint64((*configs)[id], - ZPOOL_CONFIG_POOL_TXG, &known_txg) == 0); + known_txg = fnvlist_lookup_uint64((*configs)[id], + ZPOOL_CONFIG_POOL_TXG); if (txg <= known_txg) goto ignore; nvlist_free((*configs)[id]); @@ -813,7 +813,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, * Set the TLS to indicate downstack that we * should not access zvols */ - VERIFY(tsd_set(zfs_geom_probe_vdev_key, vd) == 0); + VERIFY0(tsd_set(zfs_geom_probe_vdev_key, vd)); /* * We must have a pathname, and it must be absolute. @@ -873,7 +873,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, } /* Clear the TLS now that tasting is done */ - VERIFY(tsd_set(zfs_geom_probe_vdev_key, NULL) == 0); + VERIFY0(tsd_set(zfs_geom_probe_vdev_key, NULL)); if (cp == NULL) { ZFS_LOG(1, "Vdev %s not found.", vd->vdev_path); @@ -1160,7 +1160,7 @@ vdev_geom_io_done(zio_t *zio) struct bio *bp = zio->io_bio; if (zio->io_type != ZIO_TYPE_READ && zio->io_type != ZIO_TYPE_WRITE) { - ASSERT(bp == NULL); + ASSERT3P(bp, ==, NULL); return; } diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c index 97cb201934d..48f58807e80 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c @@ -52,7 +52,7 @@ vdev_label_write_pad2(vdev_t *vd, const char *buf, size_t size) if (vdev_is_dead(vd)) return (ENXIO); - ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); + ASSERT3U(spa_config_held(spa, SCL_ALL, RW_WRITER), ==, SCL_ALL); pad2 = abd_alloc_for_io(VDEV_PAD_SIZE, B_TRUE); abd_zero(pad2, VDEV_PAD_SIZE); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c index 7089d0e0e88..9b410863019 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c @@ -354,7 +354,8 @@ zfs_external_acl(znode_t *zp) * after upgrade the SA_ZPL_ZNODE_ACL should have been * removed */ - VERIFY(zp->z_is_sa && error == ENOENT); + VERIFY(zp->z_is_sa); + VERIFY3S(error, ==, ENOENT); return (0); } } @@ -427,7 +428,8 @@ zfs_znode_acl_version(znode_t *zp) * After upgrade SA_ZPL_ZNODE_ACL should have * been removed. */ - VERIFY(zp->z_is_sa && error == ENOENT); + VERIFY(zp->z_is_sa); + VERIFY3S(error, ==, ENOENT); return (ZFS_ACL_VERSION_FUID); } } @@ -575,7 +577,7 @@ zfs_acl_next_ace(zfs_acl_t *aclp, void *start, uint64_t *who, { zfs_acl_node_t *aclnode; - ASSERT(aclp); + ASSERT3P(aclp, !=, NULL); if (start == NULL) { aclnode = list_head(&aclp->z_acl); @@ -804,7 +806,7 @@ zfs_acl_xform(znode_t *zp, zfs_acl_t *aclp, cred_t *cr) void *cookie = NULL; zfs_acl_node_t *newaclnode; - ASSERT(aclp->z_version == ZFS_ACL_VERSION_INITIAL); + ASSERT3U(aclp->z_version, ==, ZFS_ACL_VERSION_INITIAL); /* * First create the ACE in a contiguous piece of memory * for zfs_copy_ace_2_fuid(). @@ -826,9 +828,9 @@ zfs_acl_xform(znode_t *zp, zfs_acl_t *aclp, cred_t *cr) newaclnode = zfs_acl_node_alloc(aclp->z_acl_count * sizeof (zfs_object_ace_t)); aclp->z_ops = &zfs_acl_fuid_ops; - VERIFY(zfs_copy_ace_2_fuid(zp->z_zfsvfs, ZTOV(zp)->v_type, aclp, + VERIFY0(zfs_copy_ace_2_fuid(zp->z_zfsvfs, ZTOV(zp)->v_type, aclp, oldaclp, newaclnode->z_acldata, aclp->z_acl_count, - &newaclnode->z_size, NULL, cr) == 0); + &newaclnode->z_size, NULL, cr)); newaclnode->z_ace_count = aclp->z_acl_count; aclp->z_version = ZFS_ACL_VERSION; kmem_free(oldaclp, aclp->z_acl_count * sizeof (zfs_oldace_t)); @@ -1204,7 +1206,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) if ((aclp->z_version == ZFS_ACL_VERSION_INITIAL) && (zfsvfs->z_version >= ZPL_VERSION_FUID)) zfs_acl_xform(zp, aclp, cr); - ASSERT(aclp->z_version >= ZFS_ACL_VERSION_FUID); + ASSERT3U(aclp->z_version, >=, ZFS_ACL_VERSION_FUID); otype = DMU_OT_ACL; } @@ -1560,8 +1562,8 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp, * Copy special opaque data if any */ if ((data1sz = paclp->z_ops->ace_data(pacep, &data1)) != 0) { - VERIFY((data2sz = aclp->z_ops->ace_data(acep, - &data2)) == data1sz); + data2sz = aclp->z_ops->ace_data(acep, &data2); + VERIFY3U(data2sz, ==, data1sz); bcopy(data1, data2, data2sz); } @@ -1630,7 +1632,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, if (zfsvfs->z_replay == B_FALSE) ASSERT_VOP_ELOCKED(ZTOV(dzp), __func__); } else - ASSERT(dzp->z_vnode == NULL); + ASSERT3P(dzp->z_vnode, ==, NULL); bzero(acl_ids, sizeof (zfs_acl_ids_t)); acl_ids->z_mode = MAKEIMODE(vap->va_type, vap->va_mode); @@ -1849,8 +1851,8 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) aclnode->z_size); start = (caddr_t)start + aclnode->z_size; } - ASSERT((caddr_t)start - (caddr_t)vsecp->vsa_aclentp == - aclp->z_acl_bytes); + ASSERT3U((caddr_t)start - (caddr_t)vsecp->vsa_aclentp, + ==, aclp->z_acl_bytes); } } if (mask & VSA_ACE_ACLFLAGS) { @@ -2009,8 +2011,8 @@ top: } error = zfs_aclset_common(zp, aclp, cr, tx); - ASSERT(error == 0); - ASSERT(zp->z_acl_cached == NULL); + ASSERT0(error); + ASSERT3P(zp->z_acl_cached, ==, NULL); zp->z_acl_cached = aclp; if (fuid_dirtied) @@ -2123,7 +2125,7 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode, return (error); } - ASSERT(zp->z_acl_cached); + ASSERT3P(zp->z_acl_cached, !=, NULL); while ((acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask, &iflags, &type))) { @@ -2349,7 +2351,6 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) is_attr = ((zp->z_pflags & ZFS_XATTR) && (ZTOV(zp)->v_type == VDIR)); -#ifdef __FreeBSD_kernel__ /* * In FreeBSD, we don't care about permissions of individual ADS. * Note that not checking them is not just an optimization - without @@ -2357,42 +2358,9 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) */ if (zp->z_pflags & ZFS_XATTR) return (0); -#else - /* - * If attribute then validate against base file - */ - if (is_attr) { - uint64_t parent; - - if ((error = sa_lookup(zp->z_sa_hdl, - SA_ZPL_PARENT(zp->z_zfsvfs), &parent, - sizeof (parent))) != 0) - return (error); - - if ((error = zfs_zget(zp->z_zfsvfs, - parent, &xzp)) != 0) { - return (error); - } - - check_zp = xzp; - - /* - * fixup mode to map to xattr perms - */ - - if (mode & (ACE_WRITE_DATA|ACE_APPEND_DATA)) { - mode &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA); - mode |= ACE_WRITE_NAMED_ATTRS; - } - - if (mode & (ACE_READ_DATA|ACE_EXECUTE)) { - mode &= ~(ACE_READ_DATA|ACE_EXECUTE); - mode |= ACE_READ_NAMED_ATTRS; - } - } -#endif owner = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER); + /* * Map the bits required to the standard vnode flags VREAD|VWRITE|VEXEC * in needed_bits. Map the bits mapped by working_mode (currently @@ -2444,7 +2412,7 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) */ error = 0; - ASSERT(working_mode != 0); + ASSERT3U(working_mode, !=, 0); if ((working_mode & (ACE_READ_ACL|ACE_READ_ATTRIBUTES) && owner == crgetuid(cr))) @@ -2610,7 +2578,8 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) &zpcheck_privs, B_FALSE, cr)) == 0) return (0); - ASSERT(dzp_error && zp_error); + ASSERT(dzp_error); + ASSERT(zp_error); if (!dzpcheck_privs) return (dzp_error); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c index 3ab4502bbc2..a9fe1b64723 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c @@ -352,7 +352,7 @@ zfsctl_create(zfsvfs_t *zfsvfs) vnode_t *rvp; uint64_t crtime[2]; - ASSERT(zfsvfs->z_ctldir == NULL); + ASSERT3P(zfsvfs->z_ctldir, ==, NULL); snapdir = sfs_alloc_node(sizeof (*snapdir), "snapshot", ZFSCTL_INO_ROOT, ZFSCTL_INO_SNAPDIR); @@ -360,8 +360,8 @@ zfsctl_create(zfsvfs_t *zfsvfs) ZFSCTL_INO_ROOT); dot_zfs->snapdir = snapdir; - VERIFY(VFS_ROOT(zfsvfs->z_vfs, LK_EXCLUSIVE, &rvp) == 0); - VERIFY(0 == sa_lookup(VTOZ(rvp)->z_sa_hdl, SA_ZPL_CRTIME(zfsvfs), + VERIFY0(VFS_ROOT(zfsvfs->z_vfs, LK_EXCLUSIVE, &rvp)); + VERIFY0(sa_lookup(VTOZ(rvp)->z_sa_hdl, SA_ZPL_CRTIME(zfsvfs), &crtime, sizeof (crtime))); ZFS_TIME_DECODE(&dot_zfs->cmtime, crtime); vput(rvp); @@ -637,7 +637,7 @@ zfsctl_root_lookup(struct vop_lookup_args *ap) int nameiop = ap->a_cnp->cn_nameiop; int err; - ASSERT(dvp->v_type == VDIR); + ASSERT3S(dvp->v_type, ==, VDIR); if ((flags & ISLASTCN) != 0 && nameiop != LOOKUP) return (SET_ERROR(ENOTSUP)); @@ -673,7 +673,7 @@ zfsctl_root_readdir(struct vop_readdir_args *ap) zfs_uio_init(&uio, ap->a_uio); - ASSERT(vp->v_type == VDIR); + ASSERT3S(vp->v_type, ==, VDIR); error = sfs_readdir_common(zfsvfs->z_root, ZFSCTL_INO_ROOT, ap, &uio, &dots_offset); @@ -918,7 +918,7 @@ zfsctl_snapdir_lookup(struct vop_lookup_args *ap) int flags = cnp->cn_flags; int err; - ASSERT(dvp->v_type == VDIR); + ASSERT3S(dvp->v_type, ==, VDIR); if ((flags & ISLASTCN) != 0 && nameiop != LOOKUP) return (SET_ERROR(ENOTSUP)); @@ -1013,7 +1013,7 @@ zfsctl_snapdir_lookup(struct vop_lookup_args *ap) * make .zfs/snapshot/ accessible over NFS * without requiring manual mounts of . */ - ASSERT(VTOZ(*vpp)->z_zfsvfs != zfsvfs); + ASSERT3P(VTOZ(*vpp)->z_zfsvfs, !=, zfsvfs); VTOZ(*vpp)->z_zfsvfs->z_parent = zfsvfs; /* Clear the root flag (set via VFS_ROOT) as well. */ @@ -1039,7 +1039,7 @@ zfsctl_snapdir_readdir(struct vop_readdir_args *ap) zfs_uio_init(&uio, ap->a_uio); - ASSERT(vp->v_type == VDIR); + ASSERT3S(vp->v_type, ==, VDIR); error = sfs_readdir_common(ZFSCTL_INO_ROOT, ZFSCTL_INO_SNAPDIR, ap, &uio, &dots_offset); @@ -1143,7 +1143,7 @@ zfsctl_snapshot_inactive(struct vop_inactive_args *ap) { vnode_t *vp = ap->a_vp; - VERIFY(vrecycle(vp) == 1); + VERIFY3S(vrecycle(vp), ==, 1); return (0); } @@ -1248,7 +1248,7 @@ zfsctl_lookup_objset(vfs_t *vfsp, uint64_t objsetid, zfsvfs_t **zfsvfsp) vnode_t *vp; int error; - ASSERT(zfsvfs->z_ctldir != NULL); + ASSERT3P(zfsvfs->z_ctldir, !=, NULL); *zfsvfsp = NULL; error = sfs_vnode_get(vfsp, LK_EXCLUSIVE, ZFSCTL_INO_SNAPDIR, objsetid, &vp); @@ -1280,7 +1280,7 @@ zfsctl_umount_snapshots(vfs_t *vfsp, int fflags, cred_t *cr) uint64_t cookie; int error; - ASSERT(zfsvfs->z_ctldir != NULL); + ASSERT3P(zfsvfs->z_ctldir, !=, NULL); cookie = 0; for (;;) { diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_debug.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_debug.c index 74742ad3669..7239db80851 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_debug.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_debug.c @@ -42,9 +42,12 @@ kstat_t *zfs_dbgmsg_kstat; /* * Internal ZFS debug messages are enabled by default. * - * # Print debug messages + * # Print debug messages as they're logged * dtrace -n 'zfs-dbgmsg { print(stringof(arg0)); }' * + * # Print all logged dbgmsg entries + * sysctl kstat.zfs.misc.dbgmsg + * * # Disable the kernel debug message log. * sysctl vfs.zfs.dbgmsg_enable=0 */ diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c index de145a67760..7fff329a939 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c @@ -273,10 +273,9 @@ zfs_unlinked_add(znode_t *zp, dmu_tx_t *tx) zfsvfs_t *zfsvfs = zp->z_zfsvfs; ASSERT(zp->z_unlinked); - ASSERT(zp->z_links == 0); + ASSERT3U(zp->z_links, ==, 0); - VERIFY3U(0, ==, - zap_add_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx)); + VERIFY0(zap_add_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx)); dataset_kstats_update_nunlinks_kstat(&zfsvfs->z_kstat, 1); } @@ -433,7 +432,7 @@ zfs_rmnode(znode_t *zp) uint64_t count; int error; - ASSERT(zp->z_links == 0); + ASSERT3U(zp->z_links, ==, 0); if (zfsvfs->z_replay == B_FALSE) ASSERT_VOP_ELOCKED(ZTOV(zp), __func__); @@ -599,7 +598,7 @@ zfs_link_create(znode_t *dzp, const char *name, znode_t *zp, dmu_tx_t *tx, &zp->z_links, sizeof (zp->z_links)); } else { - ASSERT(zp->z_unlinked == 0); + ASSERT(!zp->z_unlinked); } value = zfs_dirent(zp, zp->z_mode); error = zap_add(zp->z_zfsvfs->z_os, dzp->z_id, name, @@ -758,7 +757,7 @@ zfs_link_destroy(znode_t *dzp, const char *name, znode_t *zp, dmu_tx_t *tx, count = 0; ASSERT0(error); } else { - ASSERT(zp->z_unlinked == 0); + ASSERT(!zp->z_unlinked); error = zfs_dropname(dzp, name, zp, tx, flag); if (error != 0) return (error); @@ -806,7 +805,7 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xvpp, cred_t *cr) int error; zfs_acl_ids_t acl_ids; boolean_t fuid_dirtied; - uint64_t parent __unused; + uint64_t parent __maybe_unused; *xvpp = NULL; @@ -840,17 +839,15 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xvpp, cred_t *cr) if (fuid_dirtied) zfs_fuid_sync(zfsvfs, tx); -#ifdef ZFS_DEBUG - error = sa_lookup(xzp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs), - &parent, sizeof (parent)); - ASSERT(error == 0 && parent == zp->z_id); -#endif + ASSERT0(sa_lookup(xzp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs), &parent, + sizeof (parent))); + ASSERT3U(parent, ==, zp->z_id); - VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), &xzp->z_id, + VERIFY0(sa_update(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), &xzp->z_id, sizeof (xzp->z_id), tx)); - (void) zfs_log_create(zfsvfs->z_log, tx, TX_MKXATTR, zp, - xzp, "", NULL, acl_ids.z_fuidp, vap); + zfs_log_create(zfsvfs->z_log, tx, TX_MKXATTR, zp, xzp, "", NULL, + acl_ids.z_fuidp, vap); zfs_acl_ids_free(&acl_ids); dmu_tx_commit(tx); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_file_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_file_os.c index 06546c12e42..908cff6810e 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_file_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_file_os.c @@ -295,14 +295,12 @@ zfs_file_unlink(const char *fnamep) #if __FreeBSD_version >= 1300018 rc = kern_funlinkat(curthread, AT_FDCWD, fnamep, FD_NONE, seg, 0, 0); -#else -#ifdef AT_BENEATH +#elif __FreeBSD_version >= 1202504 || defined(AT_BENEATH) rc = kern_unlinkat(curthread, AT_FDCWD, __DECONST(char *, fnamep), seg, 0, 0); #else rc = kern_unlinkat(curthread, AT_FDCWD, __DECONST(char *, fnamep), seg, 0); -#endif #endif return (SET_ERROR(rc)); } diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c index 0e0c16033b1..7f7e2b72c51 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c @@ -138,6 +138,23 @@ zfs_ioc_nextboot(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) return (error); } +/* Update the VFS's cache of mountpoint properties */ +void +zfs_ioctl_update_mount_cache(const char *dsname) +{ + zfsvfs_t *zfsvfs; + + if (getzfsvfs(dsname, &zfsvfs) == 0) { + struct mount *mp = zfsvfs->z_vfs; + VFS_STATFS(mp, &mp->mnt_stat); + zfs_vfs_rele(zfsvfs); + } + /* + * Ignore errors; we can't do anything useful if either getzfsvfs or + * VFS_STATFS fails. + */ +} + uint64_t zfs_max_nvlist_src_size_os(void) { diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c index 4f2d7df87fc..4e22206de32 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c @@ -584,14 +584,6 @@ snapdir_changed_cb(void *arg, uint64_t newval) zfsvfs->z_show_ctldir = newval; } -static void -vscan_changed_cb(void *arg, uint64_t newval) -{ - zfsvfs_t *zfsvfs = arg; - - zfsvfs->z_vscan = newval; -} - static void acl_mode_changed_cb(void *arg, uint64_t newval) { @@ -635,9 +627,9 @@ zfs_register_callbacks(vfs_t *vfsp) boolean_t do_xattr = B_FALSE; int error = 0; - ASSERT(vfsp); + ASSERT3P(vfsp, !=, NULL); zfsvfs = vfsp->vfs_data; - ASSERT(zfsvfs); + ASSERT3P(zfsvfs, !=, NULL); os = zfsvfs->z_os; /* @@ -753,8 +745,6 @@ zfs_register_callbacks(vfs_t *vfsp) error = error ? error : dsl_prop_register(ds, zfs_prop_to_name(ZFS_PROP_ACLINHERIT), acl_inherit_changed_cb, zfsvfs); - error = error ? error : dsl_prop_register(ds, - zfs_prop_to_name(ZFS_PROP_VSCAN), vscan_changed_cb, zfsvfs); dsl_pool_config_exit(dmu_objset_pool(os), FTAG); if (error) goto unregister; @@ -846,6 +836,10 @@ zfsvfs_init(zfsvfs_t *zfsvfs, objset_t *os) &sa_obj); if (error != 0) return (error); + + error = zfs_get_zplprop(os, ZFS_PROP_XATTR, &val); + if (error == 0 && val == ZFS_XATTR_SA) + zfsvfs->z_xattr_sa = B_TRUE; } error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END, @@ -860,7 +854,7 @@ zfsvfs_init(zfsvfs_t *zfsvfs, objset_t *os) &zfsvfs->z_root); if (error != 0) return (error); - ASSERT(zfsvfs->z_root != 0); + ASSERT3U(zfsvfs->z_root, !=, 0); error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_UNLINKED_SET, 8, 1, &zfsvfs->z_unlinkedobj); @@ -1139,7 +1133,7 @@ zfsvfs_free(zfsvfs_t *zfsvfs) mutex_destroy(&zfsvfs->z_znodes_lock); mutex_destroy(&zfsvfs->z_lock); - ASSERT(zfsvfs->z_nr_znodes == 0); + ASSERT3U(zfsvfs->z_nr_znodes, ==, 0); list_destroy(&zfsvfs->z_all_znodes); ZFS_TEARDOWN_DESTROY(zfsvfs); ZFS_TEARDOWN_INACTIVE_DESTROY(zfsvfs); @@ -1181,8 +1175,8 @@ zfs_domount(vfs_t *vfsp, char *osname) int error = 0; zfsvfs_t *zfsvfs; - ASSERT(vfsp); - ASSERT(osname); + ASSERT3P(vfsp, !=, NULL); + ASSERT3P(osname, !=, NULL); error = zfsvfs_create(osname, vfsp->mnt_flag & MNT_RDONLY, &zfsvfs); if (error) @@ -1220,9 +1214,9 @@ zfs_domount(vfs_t *vfsp, char *osname) * because that's where other Solaris filesystems put it. */ fsid_guid = dmu_objset_fsid_guid(zfsvfs->z_os); - ASSERT((fsid_guid & ~((1ULL<<56)-1)) == 0); + ASSERT3U((fsid_guid & ~((1ULL << 56) - 1)), ==, 0); vfsp->vfs_fsid.val[0] = fsid_guid; - vfsp->vfs_fsid.val[1] = ((fsid_guid>>32) << 8) | + vfsp->vfs_fsid.val[1] = ((fsid_guid >> 32) << 8) | (vfsp->mnt_vfc->vfc_typenum & 0xFF); /* @@ -1606,11 +1600,11 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting) */ mutex_enter(&zfsvfs->z_znodes_lock); for (zp = list_head(&zfsvfs->z_all_znodes); zp != NULL; - zp = list_next(&zfsvfs->z_all_znodes, zp)) - if (zp->z_sa_hdl) { - ASSERT(ZTOV(zp)->v_count >= 0); + zp = list_next(&zfsvfs->z_all_znodes, zp)) { + if (zp->z_sa_hdl != NULL) { zfs_znode_dmu_fini(zp); } + } mutex_exit(&zfsvfs->z_znodes_lock); /* @@ -1697,7 +1691,7 @@ zfs_umount(vfs_t *vfsp, int fflag) taskqueue_drain(zfsvfs_taskq->tq_queue, &zfsvfs->z_unlinked_drain_task); - VERIFY(zfsvfs_teardown(zfsvfs, B_TRUE) == 0); + VERIFY0(zfsvfs_teardown(zfsvfs, B_TRUE)); os = zfsvfs->z_os; /* @@ -1959,7 +1953,7 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds) goto bail; ds->ds_dir->dd_activity_cancelled = B_FALSE; - VERIFY(zfsvfs_setup(zfsvfs, B_FALSE) == 0); + VERIFY0(zfsvfs_setup(zfsvfs, B_FALSE)); zfs_set_fuid_feature(zfsvfs); @@ -2172,7 +2166,7 @@ zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers) ZFS_SA_ATTRS, 8, 1, &sa_obj, tx); ASSERT0(error); - VERIFY(0 == sa_set_sa_object(os, sa_obj)); + VERIFY0(sa_set_sa_object(os, sa_obj)); sa_register_update_callback(os, zfs_sa_upgrade); } @@ -2286,7 +2280,7 @@ zfs_get_vfs_flag_unmounted(objset_t *os) zfsvfs_t *zfvp; boolean_t unmounted = B_FALSE; - ASSERT(dmu_objset_type(os) == DMU_OST_ZFS); + ASSERT3U(dmu_objset_type(os), ==, DMU_OST_ZFS); mutex_enter(&os->os_user_ptr_lock); zfvp = dmu_objset_get_user(os); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c index f915b0ab1f0..46a632b0385 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c @@ -231,15 +231,6 @@ zfs_open(vnode_t **vpp, int flag, cred_t *cr) return (SET_ERROR(EPERM)); } - if (!zfs_has_ctldir(zp) && zp->z_zfsvfs->z_vscan && - ZTOV(zp)->v_type == VREG && - !(zp->z_pflags & ZFS_AV_QUARANTINED) && zp->z_size > 0) { - if (fs_vscan(*vpp, cr, 0) != 0) { - ZFS_EXIT(zfsvfs); - return (SET_ERROR(EACCES)); - } - } - /* Keep a count of the synchronous opens in the znode */ if (flag & (FSYNC | FDSYNC)) atomic_inc_32(&zp->z_sync_cnt); @@ -262,11 +253,6 @@ zfs_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr) if ((flag & (FSYNC | FDSYNC)) && (count == 1)) atomic_dec_32(&zp->z_sync_cnt); - if (!zfs_has_ctldir(zp) && zp->z_zfsvfs->z_vscan && - ZTOV(zp)->v_type == VREG && - !(zp->z_pflags & ZFS_AV_QUARANTINED) && zp->z_size > 0) - VERIFY(fs_vscan(vp, cr, 1) == 0); - ZFS_EXIT(zfsvfs); return (0); } @@ -473,9 +459,9 @@ update_pages(znode_t *zp, int64_t start, int len, objset_t *os) caddr_t va; int off; - ASSERT(vp->v_mount != NULL); + ASSERT3P(vp->v_mount, !=, NULL); obj = vp->v_object; - ASSERT(obj != NULL); + ASSERT3P(obj, !=, NULL); off = start & PAGEOFFSET; zfs_vmobject_wlock_12(obj); @@ -530,11 +516,11 @@ mappedread_sf(znode_t *zp, int nbytes, zfs_uio_t *uio) int len = nbytes; int error = 0; - ASSERT(zfs_uio_segflg(uio) == UIO_NOCOPY); - ASSERT(vp->v_mount != NULL); + ASSERT3U(zfs_uio_segflg(uio), ==, UIO_NOCOPY); + ASSERT3P(vp->v_mount, !=, NULL); obj = vp->v_object; - ASSERT(obj != NULL); - ASSERT((zfs_uio_offset(uio) & PAGEOFFSET) == 0); + ASSERT3P(obj, !=, NULL); + ASSERT0(zfs_uio_offset(uio) & PAGEOFFSET); zfs_vmobject_wlock_12(obj); for (start = zfs_uio_offset(uio); len > 0; start += PAGESIZE) { @@ -611,9 +597,9 @@ mappedread(znode_t *zp, int nbytes, zfs_uio_t *uio) int off; int error = 0; - ASSERT(vp->v_mount != NULL); + ASSERT3P(vp->v_mount, !=, NULL); obj = vp->v_object; - ASSERT(obj != NULL); + ASSERT3P(obj, !=, NULL); start = zfs_uio_offset(uio); off = start & PAGEOFFSET; @@ -781,7 +767,9 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp, znode_t *zdp = VTOZ(dvp); znode_t *zp; zfsvfs_t *zfsvfs = zdp->z_zfsvfs; +#if __FreeBSD_version > 1300124 seqc_t dvp_seqc; +#endif int error = 0; /* @@ -807,7 +795,9 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp, ZFS_ENTER(zfsvfs); ZFS_VERIFY_ZP(zdp); +#if __FreeBSD_version > 1300124 dvp_seqc = vn_seqc_read_notmodify(dvp); +#endif *vpp = NULL; @@ -978,6 +968,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp, } } +#if __FreeBSD_version > 1300124 if ((cnp->cn_flags & ISDOTDOT) != 0) { /* * FIXME: zfs_lookup_lock relocks vnodes and does nothing to @@ -995,6 +986,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp, cnp->cn_flags &= ~MAKEENTRY; } } +#endif /* Insert name into cache (as non-existent) if appropriate. */ if (zfsvfs->z_use_namecache && !zfsvfs->z_replay && @@ -1407,7 +1399,7 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp, zfs_acl_ids_t acl_ids; boolean_t fuid_dirtied; - ASSERT(vap->va_type == VDIR); + ASSERT3U(vap->va_type, ==, VDIR); /* * If we have an ephemeral id, ACL, or XVATTR then @@ -1915,7 +1907,7 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp, } outcount += reclen; - ASSERT(outcount <= bufsize); + ASSERT3S(outcount, <=, bufsize); /* Prefetch znode */ if (prefetch) @@ -2775,12 +2767,12 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) new_mode = zp->z_mode; } err = zfs_acl_chown_setattr(zp); - ASSERT(err == 0); + ASSERT0(err); if (attrzp) { vn_seqc_write_begin(ZTOV(attrzp)); err = zfs_acl_chown_setattr(attrzp); vn_seqc_write_end(ZTOV(attrzp)); - ASSERT(err == 0); + ASSERT0(err); } } @@ -2788,7 +2780,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, &new_mode, sizeof (new_mode)); zp->z_mode = new_mode; - ASSERT3U((uintptr_t)aclp, !=, 0); + ASSERT3P(aclp, !=, NULL); err = zfs_aclset_common(zp, aclp, cr, tx); ASSERT0(err); if (zp->z_acl_cached) @@ -2874,7 +2866,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) } if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) - ASSERT(vp->v_type == VREG); + ASSERT3S(vp->v_type, ==, VREG); zfs_xvattr_set(zp, xvap, tx); } @@ -2896,7 +2888,7 @@ out: if (err == 0 && attrzp) { err2 = sa_bulk_update(attrzp->z_sa_hdl, xattr_bulk, xattr_count, tx); - ASSERT(err2 == 0); + ASSERT0(err2); } if (attrzp) @@ -3424,8 +3416,8 @@ zfs_rename_(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp, * succeed; fortunately, it is very unlikely to * fail, since we just created it. */ - VERIFY3U(zfs_link_destroy(tdzp, tnm, szp, tx, - ZRENAMING, NULL), ==, 0); + VERIFY0(zfs_link_destroy(tdzp, tnm, szp, tx, + ZRENAMING, NULL)); } } if (error == 0) { @@ -3529,7 +3521,7 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap, boolean_t fuid_dirtied; uint64_t txtype = TX_SYMLINK; - ASSERT(vap->va_type == VLNK); + ASSERT3S(vap->va_type, ==, VLNK); ZFS_ENTER(zfsvfs); ZFS_VERIFY_ZP(dzp); @@ -3600,7 +3592,7 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap, /* * Create a new object for the symlink. - * for version 4 ZPL datsets the symlink will be an SA attribute + * for version 4 ZPL datasets the symlink will be an SA attribute */ zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids); @@ -3703,7 +3695,7 @@ zfs_link(znode_t *tdzp, znode_t *szp, const char *name, cred_t *cr, uint64_t parent; uid_t owner; - ASSERT(ZTOV(tdzp)->v_type == VDIR); + ASSERT3S(ZTOV(tdzp)->v_type, ==, VDIR); ZFS_ENTER(zfsvfs); ZFS_VERIFY_ZP(tdzp); @@ -4489,6 +4481,7 @@ zfs_freebsd_fplookup_vexec(struct vop_fplookup_vexec_args *v) } #endif +#if __FreeBSD_version >= 1300139 static int zfs_freebsd_fplookup_symlink(struct vop_fplookup_symlink_args *v) { @@ -4508,6 +4501,7 @@ zfs_freebsd_fplookup_symlink(struct vop_fplookup_symlink_args *v) } return (cache_symlink_resolve(v->a_fpl, target, strlen(target))); } +#endif #ifndef _SYS_SYSPROTO_H_ struct vop_access_args { @@ -4581,7 +4575,7 @@ zfs_freebsd_lookup(struct vop_lookup_args *ap, boolean_t cached) struct componentname *cnp = ap->a_cnp; char nm[NAME_MAX + 1]; - ASSERT(cnp->cn_namelen < sizeof (nm)); + ASSERT3U(cnp->cn_namelen, <, sizeof (nm)); strlcpy(nm, cnp->cn_nameptr, MIN(cnp->cn_namelen + 1, sizeof (nm))); return (zfs_lookup(ap->a_dvp, nm, ap->a_vpp, cnp, cnp->cn_nameiop, @@ -4996,8 +4990,10 @@ zfs_freebsd_symlink(struct vop_symlink_args *ap) struct componentname *cnp = ap->a_cnp; vattr_t *vap = ap->a_vap; znode_t *zp = NULL; +#if __FreeBSD_version >= 1300139 char *symlink; size_t symlink_len; +#endif int rc; ASSERT(cnp->cn_flags & SAVENAME); @@ -5011,6 +5007,7 @@ zfs_freebsd_symlink(struct vop_symlink_args *ap) if (rc == 0) { *ap->a_vpp = ZTOV(zp); ASSERT_VOP_ELOCKED(ZTOV(zp), __func__); +#if __FreeBSD_version >= 1300139 MPASS(zp->z_cached_symlink == NULL); symlink_len = strlen(ap->a_target); symlink = cache_symlink_alloc(symlink_len + 1, M_WAITOK); @@ -5020,6 +5017,7 @@ zfs_freebsd_symlink(struct vop_symlink_args *ap) atomic_store_rel_ptr((uintptr_t *)&zp->z_cached_symlink, (uintptr_t)symlink); } +#endif } return (rc); } @@ -5036,13 +5034,16 @@ static int zfs_freebsd_readlink(struct vop_readlink_args *ap) { zfs_uio_t uio; + int error; +#if __FreeBSD_version >= 1300139 znode_t *zp = VTOZ(ap->a_vp); char *symlink, *base; size_t symlink_len; - int error; bool trycache; +#endif zfs_uio_init(&uio, ap->a_uio); +#if __FreeBSD_version >= 1300139 trycache = false; if (zfs_uio_segflg(&uio) == UIO_SYSSPACE && zfs_uio_iovcnt(&uio) == 1) { @@ -5050,7 +5051,9 @@ zfs_freebsd_readlink(struct vop_readlink_args *ap) symlink_len = zfs_uio_iovlen(&uio, 0); trycache = true; } +#endif error = zfs_readlink(ap->a_vp, &uio, ap->a_cred, NULL); +#if __FreeBSD_version >= 1300139 if (atomic_load_ptr(&zp->z_cached_symlink) != NULL || error != 0 || !trycache) { return (error); @@ -5065,6 +5068,7 @@ zfs_freebsd_readlink(struct vop_readlink_args *ap) cache_symlink_free(symlink, symlink_len + 1); } } +#endif return (error); } @@ -5154,7 +5158,7 @@ zfs_freebsd_reclaim(struct vop_reclaim_args *ap) znode_t *zp = VTOZ(vp); zfsvfs_t *zfsvfs = zp->z_zfsvfs; - ASSERT(zp != NULL); + ASSERT3P(zp, !=, NULL); #if __FreeBSD_version < 1300042 /* Destroy the vm object and flush associated pages. */ @@ -5246,10 +5250,10 @@ zfs_create_attrname(int attrnamespace, const char *name, char *attrname, /* We don't allow '/' character in attribute name. */ if (strchr(name, '/') != NULL) - return (EINVAL); + return (SET_ERROR(EINVAL)); /* We don't allow attribute names that start with "freebsd:" string. */ if (strncmp(name, "freebsd:", 8) == 0) - return (EINVAL); + return (SET_ERROR(EINVAL)); bzero(attrname, size); @@ -5274,15 +5278,38 @@ zfs_create_attrname(int attrnamespace, const char *name, char *attrname, break; case EXTATTR_NAMESPACE_EMPTY: default: - return (EINVAL); + return (SET_ERROR(EINVAL)); } if (snprintf(attrname, size, "%s%s%s%s", prefix, namespace, suffix, name) >= size) { - return (ENAMETOOLONG); + return (SET_ERROR(ENAMETOOLONG)); } return (0); } +static int +zfs_ensure_xattr_cached(znode_t *zp) +{ + int error = 0; + + ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock)); + + if (zp->z_xattr_cached != NULL) + return (0); + + if (rw_write_held(&zp->z_xattr_lock)) + return (zfs_sa_get_xattr(zp)); + + if (!rw_tryupgrade(&zp->z_xattr_lock)) { + rw_exit(&zp->z_xattr_lock); + rw_enter(&zp->z_xattr_lock, RW_WRITER); + } + if (zp->z_xattr_cached == NULL) + error = zfs_sa_get_xattr(zp); + rw_downgrade(&zp->z_xattr_lock); + return (error); +} + #ifndef _SYS_SYSPROTO_H_ struct vop_getextattr { IN struct vnode *a_vp; @@ -5295,26 +5322,85 @@ struct vop_getextattr { }; #endif -/* - * Vnode operating to retrieve a named extended attribute. - */ static int -zfs_getextattr(struct vop_getextattr_args *ap) +zfs_getextattr_dir(struct vop_getextattr_args *ap, const char *attrname) { - zfsvfs_t *zfsvfs = VTOZ(ap->a_vp)->z_zfsvfs; struct thread *td = ap->a_td; struct nameidata nd; - char attrname[255]; struct vattr va; vnode_t *xvp = NULL, *vp; int error, flags; + error = zfs_lookup(ap->a_vp, NULL, &xvp, NULL, 0, ap->a_cred, td, + LOOKUP_XATTR, B_FALSE); + if (error != 0) + return (error); + + flags = FREAD; + NDINIT_ATVP(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, attrname, + xvp, td); + error = vn_open_cred(&nd, &flags, 0, VN_OPEN_INVFS, ap->a_cred, NULL); + vp = nd.ni_vp; + NDFREE(&nd, NDF_ONLY_PNBUF); + if (error != 0) + return (error); + + if (ap->a_size != NULL) { + error = VOP_GETATTR(vp, &va, ap->a_cred); + if (error == 0) + *ap->a_size = (size_t)va.va_size; + } else if (ap->a_uio != NULL) + error = VOP_READ(vp, ap->a_uio, IO_UNIT, ap->a_cred); + + VOP_UNLOCK1(vp); + vn_close(vp, flags, ap->a_cred, td); + return (error); +} + +static int +zfs_getextattr_sa(struct vop_getextattr_args *ap, const char *attrname) +{ + znode_t *zp = VTOZ(ap->a_vp); + uchar_t *nv_value; + uint_t nv_size; + int error; + + error = zfs_ensure_xattr_cached(zp); + if (error != 0) + return (error); + + ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock)); + ASSERT3P(zp->z_xattr_cached, !=, NULL); + + error = nvlist_lookup_byte_array(zp->z_xattr_cached, attrname, + &nv_value, &nv_size); + if (error) + return (error); + + if (ap->a_size != NULL) + *ap->a_size = nv_size; + else if (ap->a_uio != NULL) + error = uiomove(nv_value, nv_size, ap->a_uio); + + return (error); +} + +/* + * Vnode operation to retrieve a named extended attribute. + */ +static int +zfs_getextattr(struct vop_getextattr_args *ap) +{ + znode_t *zp = VTOZ(ap->a_vp); + zfsvfs_t *zfsvfs = ZTOZSB(zp); + char attrname[EXTATTR_MAXNAMELEN+1]; + int error; + /* * If the xattr property is off, refuse the request. */ - if (!(zfsvfs->z_flags & ZSB_XATTR)) { + if (!(zfsvfs->z_flags & ZSB_XATTR)) return (SET_ERROR(EOPNOTSUPP)); - } error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace, ap->a_cred, ap->a_td, VREAD); @@ -5326,38 +5412,18 @@ zfs_getextattr(struct vop_getextattr_args *ap) if (error != 0) return (error); + error = ENOENT; ZFS_ENTER(zfsvfs); - - error = zfs_lookup(ap->a_vp, NULL, &xvp, NULL, 0, ap->a_cred, td, - LOOKUP_XATTR, B_FALSE); - if (error != 0) { - ZFS_EXIT(zfsvfs); - return (error); - } - - flags = FREAD; - NDINIT_ATVP(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, attrname, - xvp, td); - error = vn_open_cred(&nd, &flags, 0, VN_OPEN_INVFS, ap->a_cred, NULL); - vp = nd.ni_vp; - NDFREE(&nd, NDF_ONLY_PNBUF); - if (error != 0) { - ZFS_EXIT(zfsvfs); - if (error == ENOENT) - error = ENOATTR; - return (error); - } - - if (ap->a_size != NULL) { - error = VOP_GETATTR(vp, &va, ap->a_cred); - if (error == 0) - *ap->a_size = (size_t)va.va_size; - } else if (ap->a_uio != NULL) - error = VOP_READ(vp, ap->a_uio, IO_UNIT, ap->a_cred); - - VOP_UNLOCK1(vp); - vn_close(vp, flags, ap->a_cred, td); + ZFS_VERIFY_ZP(zp) + rw_enter(&zp->z_xattr_lock, RW_READER); + if (zfsvfs->z_use_sa && zp->z_is_sa) + error = zfs_getextattr_sa(ap, attrname); + if (error == ENOENT) + error = zfs_getextattr_dir(ap, attrname); + rw_exit(&zp->z_xattr_lock); ZFS_EXIT(zfsvfs); + if (error == ENOENT) + error = SET_ERROR(ENOATTR); return (error); } @@ -5371,54 +5437,25 @@ struct vop_deleteextattr { }; #endif -/* - * Vnode operation to remove a named attribute. - */ static int -zfs_deleteextattr(struct vop_deleteextattr_args *ap) +zfs_deleteextattr_dir(struct vop_deleteextattr_args *ap, const char *attrname) { - zfsvfs_t *zfsvfs = VTOZ(ap->a_vp)->z_zfsvfs; struct thread *td = ap->a_td; struct nameidata nd; - char attrname[255]; vnode_t *xvp = NULL, *vp; int error; - /* - * If the xattr property is off, refuse the request. - */ - if (!(zfsvfs->z_flags & ZSB_XATTR)) { - return (SET_ERROR(EOPNOTSUPP)); - } - - error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace, - ap->a_cred, ap->a_td, VWRITE); - if (error != 0) - return (error); - - error = zfs_create_attrname(ap->a_attrnamespace, ap->a_name, attrname, - sizeof (attrname)); - if (error != 0) - return (error); - - ZFS_ENTER(zfsvfs); - error = zfs_lookup(ap->a_vp, NULL, &xvp, NULL, 0, ap->a_cred, td, LOOKUP_XATTR, B_FALSE); - if (error != 0) { - ZFS_EXIT(zfsvfs); + if (error != 0) return (error); - } NDINIT_ATVP(&nd, DELETE, NOFOLLOW | LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, attrname, xvp, td); error = namei(&nd); vp = nd.ni_vp; if (error != 0) { - ZFS_EXIT(zfsvfs); NDFREE(&nd, NDF_ONLY_PNBUF); - if (error == ENOENT) - error = ENOATTR; return (error); } @@ -5430,11 +5467,90 @@ zfs_deleteextattr(struct vop_deleteextattr_args *ap) vrele(vp); else vput(vp); - ZFS_EXIT(zfsvfs); return (error); } +static int +zfs_deleteextattr_sa(struct vop_deleteextattr_args *ap, const char *attrname) +{ + znode_t *zp = VTOZ(ap->a_vp); + nvlist_t *nvl; + int error; + + error = zfs_ensure_xattr_cached(zp); + if (error != 0) + return (error); + + ASSERT(RW_WRITE_HELD(&zp->z_xattr_lock)); + ASSERT3P(zp->z_xattr_cached, !=, NULL); + + nvl = zp->z_xattr_cached; + error = nvlist_remove(nvl, attrname, DATA_TYPE_BYTE_ARRAY); + if (error == 0) + error = zfs_sa_set_xattr(zp); + if (error != 0) { + zp->z_xattr_cached = NULL; + nvlist_free(nvl); + } + return (error); +} + +/* + * Vnode operation to remove a named attribute. + */ +static int +zfs_deleteextattr(struct vop_deleteextattr_args *ap) +{ + znode_t *zp = VTOZ(ap->a_vp); + zfsvfs_t *zfsvfs = ZTOZSB(zp); + char attrname[EXTATTR_MAXNAMELEN+1]; + int error; + + /* + * If the xattr property is off, refuse the request. + */ + if (!(zfsvfs->z_flags & ZSB_XATTR)) + return (SET_ERROR(EOPNOTSUPP)); + + error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace, + ap->a_cred, ap->a_td, VWRITE); + if (error != 0) + return (error); + + error = zfs_create_attrname(ap->a_attrnamespace, ap->a_name, attrname, + sizeof (attrname)); + if (error != 0) + return (error); + + size_t size = 0; + struct vop_getextattr_args vga = { + .a_vp = ap->a_vp, + .a_size = &size, + .a_cred = ap->a_cred, + .a_td = ap->a_td, + }; + error = ENOENT; + ZFS_ENTER(zfsvfs); + ZFS_VERIFY_ZP(zp); + rw_enter(&zp->z_xattr_lock, RW_WRITER); + if (zfsvfs->z_use_sa && zp->z_is_sa) { + error = zfs_getextattr_sa(&vga, attrname); + if (error == 0) + error = zfs_deleteextattr_sa(ap, attrname); + } + if (error == ENOENT) { + error = zfs_getextattr_dir(&vga, attrname); + if (error == 0) + error = zfs_deleteextattr_dir(ap, attrname); + } + rw_exit(&zp->z_xattr_lock); + ZFS_EXIT(zfsvfs); + if (error == ENOENT) + error = SET_ERROR(ENOATTR); + return (error); +} + #ifndef _SYS_SYSPROTO_H_ struct vop_setextattr { IN struct vnode *a_vp; @@ -5446,56 +5562,28 @@ struct vop_setextattr { }; #endif -/* - * Vnode operation to set a named attribute. - */ static int -zfs_setextattr(struct vop_setextattr_args *ap) +zfs_setextattr_dir(struct vop_setextattr_args *ap, const char *attrname) { - zfsvfs_t *zfsvfs = VTOZ(ap->a_vp)->z_zfsvfs; struct thread *td = ap->a_td; struct nameidata nd; - char attrname[255]; struct vattr va; vnode_t *xvp = NULL, *vp; int error, flags; - /* - * If the xattr property is off, refuse the request. - */ - if (!(zfsvfs->z_flags & ZSB_XATTR)) { - return (SET_ERROR(EOPNOTSUPP)); - } - - error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace, - ap->a_cred, ap->a_td, VWRITE); - if (error != 0) - return (error); - error = zfs_create_attrname(ap->a_attrnamespace, ap->a_name, attrname, - sizeof (attrname)); - if (error != 0) - return (error); - - ZFS_ENTER(zfsvfs); - error = zfs_lookup(ap->a_vp, NULL, &xvp, NULL, 0, ap->a_cred, td, LOOKUP_XATTR | CREATE_XATTR_DIR, B_FALSE); - if (error != 0) { - ZFS_EXIT(zfsvfs); + if (error != 0) return (error); - } flags = FFLAGS(O_WRONLY | O_CREAT); - NDINIT_ATVP(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, attrname, - xvp, td); + NDINIT_ATVP(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, attrname, xvp, td); error = vn_open_cred(&nd, &flags, 0600, VN_OPEN_INVFS, ap->a_cred, NULL); vp = nd.ni_vp; NDFREE(&nd, NDF_ONLY_PNBUF); - if (error != 0) { - ZFS_EXIT(zfsvfs); + if (error != 0) return (error); - } VATTR_NULL(&va); va.va_size = 0; @@ -5505,6 +5593,102 @@ zfs_setextattr(struct vop_setextattr_args *ap) VOP_UNLOCK1(vp); vn_close(vp, flags, ap->a_cred, td); + return (error); +} + +static int +zfs_setextattr_sa(struct vop_setextattr_args *ap, const char *attrname) +{ + znode_t *zp = VTOZ(ap->a_vp); + nvlist_t *nvl; + size_t sa_size; + int error; + + error = zfs_ensure_xattr_cached(zp); + if (error != 0) + return (error); + + ASSERT(RW_WRITE_HELD(&zp->z_xattr_lock)); + ASSERT3P(zp->z_xattr_cached, !=, NULL); + + nvl = zp->z_xattr_cached; + size_t entry_size = ap->a_uio->uio_resid; + if (entry_size > DXATTR_MAX_ENTRY_SIZE) + return (SET_ERROR(EFBIG)); + error = nvlist_size(nvl, &sa_size, NV_ENCODE_XDR); + if (error != 0) + return (error); + if (sa_size > DXATTR_MAX_SA_SIZE) + return (SET_ERROR(EFBIG)); + uchar_t *buf = kmem_alloc(entry_size, KM_SLEEP); + error = uiomove(buf, entry_size, ap->a_uio); + if (error == 0) + error = nvlist_add_byte_array(nvl, attrname, buf, entry_size); + kmem_free(buf, entry_size); + if (error == 0) + error = zfs_sa_set_xattr(zp); + if (error != 0) { + zp->z_xattr_cached = NULL; + nvlist_free(nvl); + } + return (error); +} + +/* + * Vnode operation to set a named attribute. + */ +static int +zfs_setextattr(struct vop_setextattr_args *ap) +{ + znode_t *zp = VTOZ(ap->a_vp); + zfsvfs_t *zfsvfs = ZTOZSB(zp); + char attrname[EXTATTR_MAXNAMELEN+1]; + int error; + + /* + * If the xattr property is off, refuse the request. + */ + if (!(zfsvfs->z_flags & ZSB_XATTR)) + return (SET_ERROR(EOPNOTSUPP)); + + error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace, + ap->a_cred, ap->a_td, VWRITE); + if (error != 0) + return (error); + + error = zfs_create_attrname(ap->a_attrnamespace, ap->a_name, attrname, + sizeof (attrname)); + if (error != 0) + return (error); + + struct vop_deleteextattr_args vda = { + .a_vp = ap->a_vp, + .a_cred = ap->a_cred, + .a_td = ap->a_td, + }; + error = ENOENT; + ZFS_ENTER(zfsvfs); + ZFS_VERIFY_ZP(zp); + rw_enter(&zp->z_xattr_lock, RW_WRITER); + if (zfsvfs->z_use_sa && zp->z_is_sa && zfsvfs->z_xattr_sa) { + error = zfs_setextattr_sa(ap, attrname); + if (error == 0) + /* + * Successfully put into SA, we need to clear the one + * in dir if present. + */ + zfs_deleteextattr_dir(&vda, attrname); + } + if (error) { + error = zfs_setextattr_dir(ap, attrname); + if (error == 0) + /* + * Successfully put into dir, we need to clear the one + * in SA if present. + */ + zfs_deleteextattr_sa(&vda, attrname); + } + rw_exit(&zp->z_xattr_lock); ZFS_EXIT(zfsvfs); return (error); } @@ -5520,55 +5704,20 @@ struct vop_listextattr { }; #endif -/* - * Vnode operation to retrieve extended attributes on a vnode. - */ static int -zfs_listextattr(struct vop_listextattr_args *ap) +zfs_listextattr_dir(struct vop_listextattr_args *ap, const char *attrprefix) { - zfsvfs_t *zfsvfs = VTOZ(ap->a_vp)->z_zfsvfs; struct thread *td = ap->a_td; struct nameidata nd; - char attrprefix[16]; uint8_t dirbuf[sizeof (struct dirent)]; - struct dirent *dp; struct iovec aiov; struct uio auio; - size_t *sizep = ap->a_size; - size_t plen; vnode_t *xvp = NULL, *vp; - int done, error, eof, pos; - zfs_uio_t uio; - - zfs_uio_init(&uio, ap->a_uio); - - /* - * If the xattr property is off, refuse the request. - */ - if (!(zfsvfs->z_flags & ZSB_XATTR)) { - return (SET_ERROR(EOPNOTSUPP)); - } - - error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace, - ap->a_cred, ap->a_td, VREAD); - if (error != 0) - return (error); - - error = zfs_create_attrname(ap->a_attrnamespace, "", attrprefix, - sizeof (attrprefix)); - if (error != 0) - return (error); - plen = strlen(attrprefix); - - ZFS_ENTER(zfsvfs); - - if (sizep != NULL) - *sizep = 0; + int error, eof; error = zfs_lookup(ap->a_vp, NULL, &xvp, NULL, 0, ap->a_cred, td, LOOKUP_XATTR, B_FALSE); if (error != 0) { - ZFS_EXIT(zfsvfs); /* * ENOATTR means that the EA directory does not yet exist, * i.e. there are no extended attributes there. @@ -5583,10 +5732,8 @@ zfs_listextattr(struct vop_listextattr_args *ap) error = namei(&nd); vp = nd.ni_vp; NDFREE(&nd, NDF_ONLY_PNBUF); - if (error != 0) { - ZFS_EXIT(zfsvfs); + if (error != 0) return (error); - } auio.uio_iov = &aiov; auio.uio_iovcnt = 1; @@ -5595,18 +5742,18 @@ zfs_listextattr(struct vop_listextattr_args *ap) auio.uio_rw = UIO_READ; auio.uio_offset = 0; - do { - uint8_t nlen; + size_t plen = strlen(attrprefix); + do { aiov.iov_base = (void *)dirbuf; aiov.iov_len = sizeof (dirbuf); auio.uio_resid = sizeof (dirbuf); error = VOP_READDIR(vp, &auio, ap->a_cred, &eof, NULL, NULL); - done = sizeof (dirbuf) - auio.uio_resid; if (error != 0) break; - for (pos = 0; pos < done; ) { - dp = (struct dirent *)(dirbuf + pos); + int done = sizeof (dirbuf) - auio.uio_resid; + for (int pos = 0; pos < done; ) { + struct dirent *dp = (struct dirent *)(dirbuf + pos); pos += dp->d_reclen; /* * XXX: Temporarily we also accept DT_UNKNOWN, as this @@ -5614,24 +5761,23 @@ zfs_listextattr(struct vop_listextattr_args *ap) */ if (dp->d_type != DT_REG && dp->d_type != DT_UNKNOWN) continue; - if (plen == 0 && + else if (plen == 0 && strncmp(dp->d_name, "freebsd:", 8) == 0) continue; else if (strncmp(dp->d_name, attrprefix, plen) != 0) continue; - nlen = dp->d_namlen - plen; - if (sizep != NULL) - *sizep += 1 + nlen; - else if (GET_UIO_STRUCT(&uio) != NULL) { + uint8_t nlen = dp->d_namlen - plen; + if (ap->a_size != NULL) { + *ap->a_size += 1 + nlen; + } else if (ap->a_uio != NULL) { /* * Format of extattr name entry is one byte for * length and the rest for name. */ - error = zfs_uiomove(&nlen, 1, zfs_uio_rw(&uio), - &uio); + error = uiomove(&nlen, 1, ap->a_uio); if (error == 0) { - error = zfs_uiomove(dp->d_name + plen, - nlen, zfs_uio_rw(&uio), &uio); + char *namep = dp->d_name + plen; + error = uiomove(namep, nlen, ap->a_uio); } if (error != 0) break; @@ -5640,8 +5786,92 @@ zfs_listextattr(struct vop_listextattr_args *ap) } while (!eof && error == 0); vput(vp); - ZFS_EXIT(zfsvfs); + return (error); +} +static int +zfs_listextattr_sa(struct vop_listextattr_args *ap, const char *attrprefix) +{ + znode_t *zp = VTOZ(ap->a_vp); + int error; + + error = zfs_ensure_xattr_cached(zp); + if (error != 0) + return (error); + + ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock)); + ASSERT3P(zp->z_xattr_cached, !=, NULL); + + size_t plen = strlen(attrprefix); + nvpair_t *nvp = NULL; + while ((nvp = nvlist_next_nvpair(zp->z_xattr_cached, nvp)) != NULL) { + ASSERT3U(nvpair_type(nvp), ==, DATA_TYPE_BYTE_ARRAY); + + const char *name = nvpair_name(nvp); + if (plen == 0 && strncmp(name, "freebsd:", 8) == 0) + continue; + else if (strncmp(name, attrprefix, plen) != 0) + continue; + uint8_t nlen = strlen(name) - plen; + if (ap->a_size != NULL) { + *ap->a_size += 1 + nlen; + } else if (ap->a_uio != NULL) { + /* + * Format of extattr name entry is one byte for + * length and the rest for name. + */ + error = uiomove(&nlen, 1, ap->a_uio); + if (error == 0) { + char *namep = __DECONST(char *, name) + plen; + error = uiomove(namep, nlen, ap->a_uio); + } + if (error != 0) + break; + } + } + + return (error); +} + +/* + * Vnode operation to retrieve extended attributes on a vnode. + */ +static int +zfs_listextattr(struct vop_listextattr_args *ap) +{ + znode_t *zp = VTOZ(ap->a_vp); + zfsvfs_t *zfsvfs = ZTOZSB(zp); + char attrprefix[16]; + int error; + + if (ap->a_size != NULL) + *ap->a_size = 0; + + /* + * If the xattr property is off, refuse the request. + */ + if (!(zfsvfs->z_flags & ZSB_XATTR)) + return (SET_ERROR(EOPNOTSUPP)); + + error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace, + ap->a_cred, ap->a_td, VREAD); + if (error != 0) + return (error); + + error = zfs_create_attrname(ap->a_attrnamespace, "", attrprefix, + sizeof (attrprefix)); + if (error != 0) + return (error); + + ZFS_ENTER(zfsvfs); + ZFS_VERIFY_ZP(zp); + rw_enter(&zp->z_xattr_lock, RW_READER); + if (zfsvfs->z_use_sa && zp->z_is_sa) + error = zfs_listextattr_sa(ap, attrprefix); + if (error == 0) + error = zfs_listextattr_dir(ap, attrprefix); + rw_exit(&zp->z_xattr_lock); + ZFS_EXIT(zfsvfs); return (error); } @@ -5828,7 +6058,9 @@ struct vop_vector zfs_vnodeops = { #if __FreeBSD_version >= 1300102 .vop_fplookup_vexec = zfs_freebsd_fplookup_vexec, #endif +#if __FreeBSD_version >= 1300139 .vop_fplookup_symlink = zfs_freebsd_fplookup_symlink, +#endif .vop_access = zfs_freebsd_access, .vop_allocate = VOP_EINVAL, .vop_lookup = zfs_cache_lookup, @@ -5878,7 +6110,9 @@ struct vop_vector zfs_fifoops = { #if __FreeBSD_version >= 1300102 .vop_fplookup_vexec = zfs_freebsd_fplookup_vexec, #endif +#if __FreeBSD_version >= 1300139 .vop_fplookup_symlink = zfs_freebsd_fplookup_symlink, +#endif .vop_access = zfs_freebsd_access, .vop_getattr = zfs_freebsd_getattr, .vop_inactive = zfs_freebsd_inactive, @@ -5902,7 +6136,9 @@ struct vop_vector zfs_shareops = { #if __FreeBSD_version >= 1300121 .vop_fplookup_vexec = VOP_EAGAIN, #endif +#if __FreeBSD_version >= 1300139 .vop_fplookup_symlink = VOP_EAGAIN, +#endif .vop_access = zfs_freebsd_access, .vop_inactive = zfs_freebsd_inactive, .vop_reclaim = zfs_freebsd_reclaim, diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c index 0491b2ff3e2..3eb5cd490d0 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c @@ -143,11 +143,15 @@ zfs_znode_cache_constructor(void *buf, void *arg, int kmflags) list_link_init(&zp->z_link_node); + mutex_init(&zp->z_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&zp->z_acl_lock, NULL, MUTEX_DEFAULT, NULL); + rw_init(&zp->z_xattr_lock, NULL, RW_DEFAULT, NULL); zfs_rangelock_init(&zp->z_rangelock, zfs_rangelock_cb, zp); zp->z_acl_cached = NULL; + zp->z_xattr_cached = NULL; + zp->z_xattr_parent = 0; zp->z_vnode = NULL; return (0); } @@ -161,10 +165,13 @@ zfs_znode_cache_destructor(void *buf, void *arg) ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); ASSERT3P(zp->z_vnode, ==, NULL); ASSERT(!list_link_active(&zp->z_link_node)); + mutex_destroy(&zp->z_lock); mutex_destroy(&zp->z_acl_lock); + rw_destroy(&zp->z_xattr_lock); zfs_rangelock_fini(&zp->z_rangelock); - ASSERT(zp->z_acl_cached == NULL); + ASSERT3P(zp->z_acl_cached, ==, NULL); + ASSERT3P(zp->z_xattr_cached, ==, NULL); } @@ -175,14 +182,12 @@ static int zfs_znode_cache_constructor_smr(void *mem, int size __unused, void *private, int flags) { - return (zfs_znode_cache_constructor(mem, private, flags)); } static void zfs_znode_cache_destructor_smr(void *mem, int size __unused, void *private) { - zfs_znode_cache_destructor(mem, private); } @@ -192,7 +197,7 @@ zfs_znode_init(void) /* * Initialize zcache */ - ASSERT(znode_uma_zone == NULL); + ASSERT3P(znode_uma_zone, ==, NULL); znode_uma_zone = uma_zcreate("zfs_znode_cache", sizeof (znode_t), zfs_znode_cache_constructor_smr, zfs_znode_cache_destructor_smr, NULL, NULL, 0, 0); @@ -202,14 +207,16 @@ zfs_znode_init(void) static znode_t * zfs_znode_alloc_kmem(int flags) { - return (uma_zalloc_smr(znode_uma_zone, flags)); } static void zfs_znode_free_kmem(znode_t *zp) { - + if (zp->z_xattr_cached) { + nvlist_free(zp->z_xattr_cached); + zp->z_xattr_cached = NULL; + } uma_zfree_smr(znode_uma_zone, zp); } #else @@ -219,7 +226,7 @@ zfs_znode_init(void) /* * Initialize zcache */ - ASSERT(znode_cache == NULL); + ASSERT3P(znode_cache, ==, NULL); znode_cache = kmem_cache_create("zfs_znode_cache", sizeof (znode_t), 0, zfs_znode_cache_constructor, zfs_znode_cache_destructor, NULL, NULL, NULL, 0); @@ -228,14 +235,16 @@ zfs_znode_init(void) static znode_t * zfs_znode_alloc_kmem(int flags) { - return (kmem_cache_alloc(znode_cache, flags)); } static void zfs_znode_free_kmem(znode_t *zp) { - + if (zp->z_xattr_cached) { + nvlist_free(zp->z_xattr_cached); + zp->z_xattr_cached = NULL; + } kmem_cache_free(znode_cache, zp); } #endif @@ -282,7 +291,7 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) sharezp->z_zfsvfs = zfsvfs; sharezp->z_is_sa = zfsvfs->z_use_sa; - VERIFY(0 == zfs_acl_ids_create(sharezp, IS_ROOT_NODE, &vattr, + VERIFY0(zfs_acl_ids_create(sharezp, IS_ROOT_NODE, &vattr, kcred, NULL, &acl_ids)); zfs_mknode(sharezp, &vattr, tx, kcred, IS_ROOT_NODE, &zp, &acl_ids); ASSERT3P(zp, ==, sharezp); @@ -345,10 +354,10 @@ zfs_znode_sa_init(zfsvfs_t *zfsvfs, znode_t *zp, ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs) || (zfsvfs == zp->z_zfsvfs)); ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zfsvfs, zp->z_id))); - ASSERT(zp->z_sa_hdl == NULL); - ASSERT(zp->z_acl_cached == NULL); + ASSERT3P(zp->z_sa_hdl, ==, NULL); + ASSERT3P(zp->z_acl_cached, ==, NULL); if (sa_hdl == NULL) { - VERIFY(0 == sa_handle_get_from_db(zfsvfs->z_os, db, zp, + VERIFY0(sa_handle_get_from_db(zfsvfs->z_os, db, zp, SA_HDL_SHARED, &zp->z_sa_hdl)); } else { zp->z_sa_hdl = sa_hdl; @@ -444,7 +453,9 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, zp->z_blksz = blksz; zp->z_seq = 0x7A4653; zp->z_sync_cnt = 0; +#if __FreeBSD_version >= 1300139 atomic_store_ptr(&zp->z_cached_symlink, NULL); +#endif vp = ZTOV(zp); @@ -502,7 +513,8 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, break; case VREG: if (parent == zfsvfs->z_shares_dir) { - ASSERT(zp->z_uid == 0 && zp->z_gid == 0); + ASSERT0(zp->z_uid); + ASSERT0(zp->z_gid); vp->v_op = &zfs_shareops; } break; @@ -568,7 +580,8 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, int cnt = 0; zfs_acl_locator_cb_t locate = { 0 }; - ASSERT(vap && ((vap->va_mask & AT_MODE) == AT_MODE)); + ASSERT3P(vap, !=, NULL); + ASSERT3U((vap->va_mask & AT_MODE), ==, AT_MODE); if (zfsvfs->z_replay) { obj = vap->va_nodeid; @@ -621,7 +634,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, } ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); - VERIFY(0 == sa_buf_hold(zfsvfs->z_os, obj, NULL, &db)); + VERIFY0(sa_buf_hold(zfsvfs->z_os, obj, NULL, &db)); /* * If this is the root, fix up the half-initialized parent pointer @@ -684,7 +697,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, } /* Now add in all of the "SA" attributes */ - VERIFY(0 == sa_handle_get_from_db(zfsvfs->z_os, db, NULL, SA_HDL_SHARED, + VERIFY0(sa_handle_get_from_db(zfsvfs->z_os, db, NULL, SA_HDL_SHARED, &sa_hdl)); /* @@ -771,11 +784,11 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, acl_ids->z_fuid, acl_ids->z_fgid); } - VERIFY(sa_replace_all_by_template(sa_hdl, sa_attrs, cnt, tx) == 0); + VERIFY0(sa_replace_all_by_template(sa_hdl, sa_attrs, cnt, tx)); if (!(flag & IS_ROOT_NODE)) { *zpp = zfs_znode_alloc(zfsvfs, db, 0, obj_type, sa_hdl); - ASSERT(*zpp != NULL); + ASSERT3P(*zpp, !=, NULL); } else { /* * If we are creating the root node, the "parent" we @@ -820,7 +833,7 @@ zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) xoptattr_t *xoap; xoap = xva_getxoptattr(xvap); - ASSERT(xoap); + ASSERT3P(xoap, !=, NULL); ASSERT_VOP_IN_SEQC(ZTOV(zp)); @@ -1077,9 +1090,16 @@ zfs_rezget(znode_t *zp) zfs_acl_free(zp->z_acl_cached); zp->z_acl_cached = NULL; } - mutex_exit(&zp->z_acl_lock); - ASSERT(zp->z_sa_hdl == NULL); + + rw_enter(&zp->z_xattr_lock, RW_WRITER); + if (zp->z_xattr_cached) { + nvlist_free(zp->z_xattr_cached); + zp->z_xattr_cached = NULL; + } + rw_exit(&zp->z_xattr_lock); + + ASSERT3P(zp->z_sa_hdl, ==, NULL); err = sa_buf_hold(zfsvfs->z_os, obj_num, NULL, &db); if (err) { ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); @@ -1191,9 +1211,9 @@ zfs_znode_delete(znode_t *zp, dmu_tx_t *tx) ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); if (acl_obj) { VERIFY(!zp->z_is_sa); - VERIFY(0 == dmu_object_free(os, acl_obj, tx)); + VERIFY0(dmu_object_free(os, acl_obj, tx)); } - VERIFY(0 == dmu_object_free(os, obj, tx)); + VERIFY0(dmu_object_free(os, obj, tx)); zfs_znode_dmu_fini(zp); ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); zfs_znode_free(zp); @@ -1205,7 +1225,7 @@ zfs_zinactive(znode_t *zp) zfsvfs_t *zfsvfs = zp->z_zfsvfs; uint64_t z_id = zp->z_id; - ASSERT(zp->z_sa_hdl); + ASSERT3P(zp->z_sa_hdl, !=, NULL); /* * Don't allow a zfs_zget() while were trying to release this znode @@ -1238,9 +1258,11 @@ void zfs_znode_free(znode_t *zp) { zfsvfs_t *zfsvfs = zp->z_zfsvfs; +#if __FreeBSD_version >= 1300139 char *symlink; +#endif - ASSERT(zp->z_sa_hdl == NULL); + ASSERT3P(zp->z_sa_hdl, ==, NULL); zp->z_vnode = NULL; mutex_enter(&zfsvfs->z_znodes_lock); POINTER_INVALIDATE(&zp->z_zfsvfs); @@ -1253,6 +1275,15 @@ zfs_znode_free(znode_t *zp) cache_symlink_free(symlink, strlen(symlink) + 1); } +#if __FreeBSD_version >= 1300139 + symlink = atomic_load_ptr(&zp->z_cached_symlink); + if (symlink != NULL) { + atomic_store_rel_ptr((uintptr_t *)&zp->z_cached_symlink, + (uintptr_t)NULL); + cache_symlink_free(symlink, strlen(symlink) + 1); + } +#endif + if (zp->z_acl_cached) { zfs_acl_free(zp->z_acl_cached); zp->z_acl_cached = NULL; @@ -1403,7 +1434,7 @@ zfs_extend(znode_t *zp, uint64_t end) zp->z_size = end; - VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zp->z_zfsvfs), + VERIFY0(sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zp->z_zfsvfs), &zp->z_size, sizeof (zp->z_size), tx)); vnode_pager_setsize(ZTOV(zp), end); @@ -1521,7 +1552,7 @@ zfs_trunc(znode_t *zp, uint64_t end) SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, &zp->z_pflags, 8); } - VERIFY(sa_bulk_update(zp->z_sa_hdl, bulk, count, tx) == 0); + VERIFY0(sa_bulk_update(zp->z_sa_hdl, bulk, count, tx)); dmu_tx_commit(tx); @@ -1598,7 +1629,7 @@ log: NULL, &zp->z_pflags, 8); zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime); error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); - ASSERT(error == 0); + ASSERT0(error); zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len); @@ -1631,7 +1662,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) moid = MASTER_NODE_OBJ; error = zap_create_claim(os, moid, DMU_OT_MASTER_NODE, DMU_OT_NONE, 0, tx); - ASSERT(error == 0); + ASSERT0(error); /* * Set starting attributes. @@ -1643,8 +1674,8 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) uint64_t val; char *name; - ASSERT(nvpair_type(elem) == DATA_TYPE_UINT64); - VERIFY(nvpair_value_uint64(elem, &val) == 0); + ASSERT3S(nvpair_type(elem), ==, DATA_TYPE_UINT64); + val = fnvpair_value_uint64(elem); name = nvpair_name(elem); if (strcmp(name, zfs_prop_to_name(ZFS_PROP_VERSION)) == 0) { if (val < version) @@ -1652,13 +1683,13 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) } else { error = zap_update(os, moid, name, 8, 1, &val, tx); } - ASSERT(error == 0); + ASSERT0(error); if (strcmp(name, zfs_prop_to_name(ZFS_PROP_NORMALIZE)) == 0) norm = val; else if (strcmp(name, zfs_prop_to_name(ZFS_PROP_CASE)) == 0) sense = val; } - ASSERT(version != 0); + ASSERT3U(version, !=, 0); error = zap_update(os, moid, ZPL_VERSION_STR, 8, 1, &version, tx); /* @@ -1669,7 +1700,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) sa_obj = zap_create(os, DMU_OT_SA_MASTER_NODE, DMU_OT_NONE, 0, tx); error = zap_add(os, moid, ZFS_SA_ATTRS, 8, 1, &sa_obj, tx); - ASSERT(error == 0); + ASSERT0(error); } else { sa_obj = 0; } @@ -1679,7 +1710,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) obj = zap_create(os, DMU_OT_UNLINKED_SET, DMU_OT_NONE, 0, tx); error = zap_add(os, moid, ZFS_UNLINKED_SET, 8, 1, &obj, tx); - ASSERT(error == 0); + ASSERT0(error); /* * Create root znode. Create minimal znode/vnode/zfsvfs @@ -1710,7 +1741,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END, &zfsvfs->z_attr_table); - ASSERT(error == 0); + ASSERT0(error); /* * Fold case on file systems that are always or sometimes case @@ -1727,12 +1758,12 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL); rootzp->z_zfsvfs = zfsvfs; - VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr, + VERIFY0(zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr, cr, NULL, &acl_ids)); zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, &acl_ids); ASSERT3P(zp, ==, rootzp); error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &rootzp->z_id, tx); - ASSERT(error == 0); + ASSERT0(error); zfs_acl_ids_free(&acl_ids); POINTER_INVALIDATE(&rootzp->z_zfsvfs); @@ -1745,7 +1776,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) error = zfs_create_share_dir(zfsvfs, tx); - ASSERT(error == 0); + ASSERT0(error); for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) mutex_destroy(&zfsvfs->z_hold_mtx[i]); @@ -1913,7 +1944,7 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl, int is_xattrdir; if (prevdb) { - ASSERT(prevhdl != NULL); + ASSERT3P(prevhdl, !=, NULL); zfs_release_sa_handle(prevhdl, prevdb, FTAG); } @@ -1939,7 +1970,7 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl, complen = strlen(component); path -= complen; - ASSERT(path >= buf); + ASSERT3P(path, >=, buf); bcopy(component, path, complen); obj = pobj; @@ -1956,7 +1987,7 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl, } if (sa_hdl != NULL && sa_hdl != hdl) { - ASSERT(sa_db != NULL); + ASSERT3P(sa_db, !=, NULL); zfs_release_sa_handle(sa_hdl, sa_db, FTAG); } diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c index 9fe678d2574..aeb42b304e7 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c @@ -114,7 +114,7 @@ * Similarly to ZIL blocks, the core part of each dnode_phys_t needs to be left * in plaintext for scrubbing and claiming, but the bonus buffers might contain * sensitive user data. The function zio_crypt_init_uios_dnode() handles parsing - * which which pieces of the block need to be encrypted. For more details about + * which pieces of the block need to be encrypted. For more details about * dnode authentication and encryption, see zio_crypt_init_uios_dnode(). * * OBJECT SET AUTHENTICATION: @@ -239,7 +239,7 @@ zio_crypt_key_init(uint64_t crypt, zio_crypt_key_t *key) uint_t keydata_len; zio_crypt_info_t *ci = NULL; - ASSERT(key != NULL); + ASSERT3P(key, !=, NULL); ASSERT3U(crypt, <, ZIO_CRYPT_FUNCTIONS); ci = &zio_crypt_table[crypt]; @@ -1076,16 +1076,6 @@ zio_crypt_do_objset_hmacs(zio_crypt_key_t *key, void *data, uint_t datalen, bcopy(raw_portable_mac, portable_mac, ZIO_OBJSET_MAC_LEN); - /* - * This is necessary here as we check next whether - * OBJSET_FLAG_USERACCOUNTING_COMPLETE or - * OBJSET_FLAG_USEROBJACCOUNTING are set in order to - * decide if the local_mac should be zeroed out. - */ - intval = osp->os_flags; - if (should_bswap) - intval = BSWAP_64(intval); - /* * The local MAC protects the user, group and project accounting. * If these objects are not present, the local MAC is zeroed out. @@ -1097,10 +1087,7 @@ zio_crypt_do_objset_hmacs(zio_crypt_key_t *key, void *data, uint_t datalen, (datalen >= OBJSET_PHYS_SIZE_V2 && osp->os_userused_dnode.dn_type == DMU_OT_NONE && osp->os_groupused_dnode.dn_type == DMU_OT_NONE) || - (datalen <= OBJSET_PHYS_SIZE_V1) || - (((intval & OBJSET_FLAG_USERACCOUNTING_COMPLETE) == 0 || - (intval & OBJSET_FLAG_USEROBJACCOUNTING_COMPLETE) == 0) && - key->zk_version > 0)) { + (datalen <= OBJSET_PHYS_SIZE_V1)) { bzero(local_mac, ZIO_OBJSET_MAC_LEN); return (0); } diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c index ba315f10473..aecb9f4c7d8 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c @@ -420,7 +420,7 @@ zvol_geom_destroy(zvol_state_t *zv) g_topology_assert(); mutex_enter(&zv->zv_state_lock); - VERIFY(zsg->zsg_state == ZVOL_GEOM_RUNNING); + VERIFY3S(zsg->zsg_state, ==, ZVOL_GEOM_RUNNING); mutex_exit(&zv->zv_state_lock); zsg->zsg_provider = NULL; g_wither_geom(pp->geom, ENXIO); @@ -761,12 +761,13 @@ zvol_cdev_read(struct cdev *dev, struct uio *uio_s, int ioflag) volsize = zv->zv_volsize; /* * uio_loffset == volsize isn't an error as - * its required for EOF processing. + * it's required for EOF processing. */ if (zfs_uio_resid(&uio) > 0 && (zfs_uio_offset(&uio) < 0 || zfs_uio_offset(&uio) > volsize)) return (SET_ERROR(EIO)); + ssize_t start_resid = zfs_uio_resid(&uio); lr = zfs_rangelock_enter(&zv->zv_rangelock, zfs_uio_offset(&uio), zfs_uio_resid(&uio), RL_READER); while (zfs_uio_resid(&uio) > 0 && zfs_uio_offset(&uio) < volsize) { @@ -785,6 +786,8 @@ zvol_cdev_read(struct cdev *dev, struct uio *uio_s, int ioflag) } } zfs_rangelock_exit(lr); + int64_t nread = start_resid - zfs_uio_resid(&uio); + dataset_kstats_update_read_kstats(&zv->zv_kstat, nread); return (error); } @@ -809,6 +812,7 @@ zvol_cdev_write(struct cdev *dev, struct uio *uio_s, int ioflag) (zfs_uio_offset(&uio) < 0 || zfs_uio_offset(&uio) > volsize)) return (SET_ERROR(EIO)); + ssize_t start_resid = zfs_uio_resid(&uio); sync = (ioflag & IO_SYNC) || (zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS); @@ -840,6 +844,8 @@ zvol_cdev_write(struct cdev *dev, struct uio *uio_s, int ioflag) break; } zfs_rangelock_exit(lr); + int64_t nwritten = start_resid - zfs_uio_resid(&uio); + dataset_kstats_update_write_kstats(&zv->zv_kstat, nwritten); if (sync) zil_commit(zv->zv_zilog, ZVOL_OBJ); rw_exit(&zv->zv_suspend_lock); @@ -1164,8 +1170,8 @@ zvol_ensure_zilog(zvol_state_t *zv) zvol_get_data); zv->zv_flags |= ZVOL_WRITTEN_TO; /* replay / destroy done in zvol_create_minor_impl() */ - VERIFY0((zv->zv_zilog->zl_header->zh_flags & - ZIL_REPLAY_NEEDED)); + VERIFY0(zv->zv_zilog->zl_header->zh_flags & + ZIL_REPLAY_NEEDED); } rw_downgrade(&zv->zv_suspend_lock); } diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-generic.c b/sys/contrib/openzfs/module/os/linux/spl/spl-generic.c index 36fdff72a13..91eeaccfdc4 100644 --- a/sys/contrib/openzfs/module/os/linux/spl/spl-generic.c +++ b/sys/contrib/openzfs/module/os/linux/spl/spl-generic.c @@ -586,8 +586,10 @@ spl_getattr(struct file *filp, struct kstat *stat) AT_STATX_SYNC_AS_STAT); #elif defined(HAVE_2ARGS_VFS_GETATTR) rc = vfs_getattr(&filp->f_path, stat); -#else +#elif defined(HAVE_3ARGS_VFS_GETATTR) rc = vfs_getattr(filp->f_path.mnt, filp->f_dentry, stat); +#else +#error "No available vfs_getattr()" #endif if (rc) return (-rc); diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-kmem-cache.c b/sys/contrib/openzfs/module/os/linux/spl/spl-kmem-cache.c index 6b3d559ffc1..2151ef008fd 100644 --- a/sys/contrib/openzfs/module/os/linux/spl/spl-kmem-cache.c +++ b/sys/contrib/openzfs/module/os/linux/spl/spl-kmem-cache.c @@ -100,13 +100,10 @@ MODULE_PARM_DESC(spl_kmem_cache_max_size, "Maximum size of slab in MB"); * For small objects the Linux slab allocator should be used to make the most * efficient use of the memory. However, large objects are not supported by * the Linux slab and therefore the SPL implementation is preferred. A cutoff - * of 16K was determined to be optimal for architectures using 4K pages. + * of 16K was determined to be optimal for architectures using 4K pages and + * to also work well on architecutres using larger 64K page sizes. */ -#if PAGE_SIZE == 4096 unsigned int spl_kmem_cache_slab_limit = 16384; -#else -unsigned int spl_kmem_cache_slab_limit = 0; -#endif module_param(spl_kmem_cache_slab_limit, uint, 0644); MODULE_PARM_DESC(spl_kmem_cache_slab_limit, "Objects less than N bytes use the Linux slab"); @@ -527,9 +524,7 @@ spl_cache_flush(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flush) * Size a slab based on the size of each aligned object plus spl_kmem_obj_t. * When on-slab we want to target spl_kmem_cache_obj_per_slab. However, * for very small objects we may end up with more than this so as not - * to waste space in the minimal allocation of a single page. Also for - * very large objects we may use as few as spl_kmem_cache_obj_per_slab_min, - * lower than this and we will fail. + * to waste space in the minimal allocation of a single page. */ static int spl_slab_size(spl_kmem_cache_t *skc, uint32_t *objs, uint32_t *size) diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-kmem.c b/sys/contrib/openzfs/module/os/linux/spl/spl-kmem.c index 943966cbb17..2b342140d0e 100644 --- a/sys/contrib/openzfs/module/os/linux/spl/spl-kmem.c +++ b/sys/contrib/openzfs/module/os/linux/spl/spl-kmem.c @@ -245,7 +245,21 @@ spl_kmem_alloc_impl(size_t size, int flags, int node) return (NULL); } } else { + /* + * We use kmalloc when doing kmem_alloc(KM_NOSLEEP), + * because kvmalloc/vmalloc may sleep. We also use + * kmalloc on systems with limited kernel VA space (e.g. + * 32-bit), which have HIGHMEM. Otherwise we use + * kvmalloc, which tries to get contiguous physical + * memory (fast, like kmalloc) and falls back on using + * virtual memory to stitch together pages (slow, like + * vmalloc). + */ +#ifdef CONFIG_HIGHMEM if (flags & KM_VMEM) { +#else + if ((flags & KM_VMEM) || !(flags & KM_NOSLEEP)) { +#endif ptr = spl_kvmalloc(size, lflags); } else { ptr = kmalloc_node(size, lflags, node); diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-proc.c b/sys/contrib/openzfs/module/os/linux/spl/spl-proc.c index 3e58598d43f..c4af27a7fcd 100644 --- a/sys/contrib/openzfs/module/os/linux/spl/spl-proc.c +++ b/sys/contrib/openzfs/module/os/linux/spl/spl-proc.c @@ -53,73 +53,19 @@ static struct proc_dir_entry *proc_spl_taskq_all = NULL; static struct proc_dir_entry *proc_spl_taskq = NULL; struct proc_dir_entry *proc_spl_kstat = NULL; -static int -proc_copyin_string(char *kbuffer, int kbuffer_size, const char *ubuffer, - int ubuffer_size) -{ - int size; - - if (ubuffer_size > kbuffer_size) - return (-EOVERFLOW); - - if (copy_from_user((void *)kbuffer, (void *)ubuffer, ubuffer_size)) - return (-EFAULT); - - /* strip trailing whitespace */ - size = strnlen(kbuffer, ubuffer_size); - while (size-- >= 0) - if (!isspace(kbuffer[size])) - break; - - /* empty string */ - if (size < 0) - return (-EINVAL); - - /* no space to terminate */ - if (size == kbuffer_size) - return (-EOVERFLOW); - - kbuffer[size + 1] = 0; - return (0); -} - -static int -proc_copyout_string(char *ubuffer, int ubuffer_size, const char *kbuffer, - char *append) -{ - /* - * NB if 'append' != NULL, it's a single character to append to the - * copied out string - usually "\n", for /proc entries and - * (i.e. a terminating zero byte) for sysctl entries - */ - int size = MIN(strlen(kbuffer), ubuffer_size); - - if (copy_to_user(ubuffer, kbuffer, size)) - return (-EFAULT); - - if (append != NULL && size < ubuffer_size) { - if (copy_to_user(ubuffer + size, append, 1)) - return (-EFAULT); - - size++; - } - - return (size); -} - #ifdef DEBUG_KMEM static int proc_domemused(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { int rc = 0; - unsigned long min = 0, max = ~0, val; + unsigned long val; spl_ctl_table dummy = *table; dummy.data = &val; dummy.proc_handler = &proc_dointvec; - dummy.extra1 = &min; - dummy.extra2 = &max; + dummy.extra1 = &table_min; + dummy.extra2 = &table_max; if (write) { *ppos += *lenp; @@ -141,14 +87,14 @@ proc_doslab(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { int rc = 0; - unsigned long min = 0, max = ~0, val = 0, mask; + unsigned long val = 0, mask; spl_ctl_table dummy = *table; spl_kmem_cache_t *skc = NULL; dummy.data = &val; dummy.proc_handler = &proc_dointvec; - dummy.extra1 = &min; - dummy.extra2 = &max; + dummy.extra1 = &table_min; + dummy.extra2 = &table_max; if (write) { *ppos += *lenp; @@ -187,39 +133,34 @@ static int proc_dohostid(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - int len, rc = 0; char *end, str[32]; + unsigned long hid; + spl_ctl_table dummy = *table; + + dummy.data = str; + dummy.maxlen = sizeof (str) - 1; + + if (!write) + snprintf(str, sizeof (str), "%lx", + (unsigned long) zone_get_hostid(NULL)); + + /* always returns 0 */ + proc_dostring(&dummy, write, buffer, lenp, ppos); if (write) { /* * We can't use proc_doulongvec_minmax() in the write - * case here because hostid while a hex value has no - * leading 0x which confuses the helper function. + * case here because hostid, while a hex value, has no + * leading 0x, which confuses the helper function. */ - rc = proc_copyin_string(str, sizeof (str), buffer, *lenp); - if (rc < 0) - return (rc); - spl_hostid = simple_strtoul(str, &end, 16); + hid = simple_strtoul(str, &end, 16); if (str == end) return (-EINVAL); - - } else { - len = snprintf(str, sizeof (str), "%lx", - (unsigned long) zone_get_hostid(NULL)); - if (*ppos >= len) - rc = 0; - else - rc = proc_copyout_string(buffer, - *lenp, str + *ppos, "\n"); - - if (rc >= 0) { - *lenp = rc; - *ppos += rc; - } + spl_hostid = hid; } - return (rc); + return (0); } static void diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-thread.c b/sys/contrib/openzfs/module/os/linux/spl/spl-thread.c index db23fb64a29..834c527117a 100644 --- a/sys/contrib/openzfs/module/os/linux/spl/spl-thread.c +++ b/sys/contrib/openzfs/module/os/linux/spl/spl-thread.c @@ -158,3 +158,54 @@ spl_kthread_create(int (*func)(void *), void *data, const char namefmt[], ...) } while (1); } EXPORT_SYMBOL(spl_kthread_create); + +/* + * The "why" argument indicates the allowable side-effects of the call: + * + * FORREAL: Extract the next pending signal from p_sig into p_cursig; + * stop the process if a stop has been requested or if a traced signal + * is pending. + * + * JUSTLOOKING: Don't stop the process, just indicate whether or not + * a signal might be pending (FORREAL is needed to tell for sure). + */ +int +issig(int why) +{ + ASSERT(why == FORREAL || why == JUSTLOOKING); + + if (!signal_pending(current)) + return (0); + + if (why != FORREAL) + return (1); + + struct task_struct *task = current; + spl_kernel_siginfo_t __info; + sigset_t set; + siginitsetinv(&set, 1ULL << (SIGSTOP - 1) | 1ULL << (SIGTSTP - 1)); + sigorsets(&set, &task->blocked, &set); + + spin_lock_irq(&task->sighand->siglock); + int ret; + if ((ret = dequeue_signal(task, &set, &__info)) != 0) { +#ifdef HAVE_SIGNAL_STOP + spin_unlock_irq(&task->sighand->siglock); + kernel_signal_stop(); +#else + if (current->jobctl & JOBCTL_STOP_DEQUEUED) + spl_set_special_state(TASK_STOPPED); + + spin_unlock_irq(¤t->sighand->siglock); + + schedule(); +#endif + return (0); + } + + spin_unlock_irq(&task->sighand->siglock); + + return (1); +} + +EXPORT_SYMBOL(issig); diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_dir.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_dir.c index 207a51d75bc..82b32d1cc3f 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_dir.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_dir.c @@ -1106,8 +1106,8 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xzpp, cred_t *cr) sizeof (xzp->z_id), tx)); if (!zp->z_unlinked) - (void) zfs_log_create(zfsvfs->z_log, tx, TX_MKXATTR, zp, - xzp, "", NULL, acl_ids.z_fuidp, vap); + zfs_log_create(zfsvfs->z_log, tx, TX_MKXATTR, zp, xzp, "", NULL, + acl_ids.z_fuidp, vap); zfs_acl_ids_free(&acl_ids); dmu_tx_commit(tx); diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_file_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_file_os.c index 99c6ffc9594..35e647375d9 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_file_os.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_file_os.c @@ -279,8 +279,10 @@ zfs_file_getattr(zfs_file_t *filp, zfs_file_attr_t *zfattr) AT_STATX_SYNC_AS_STAT); #elif defined(HAVE_2ARGS_VFS_GETATTR) rc = vfs_getattr(&filp->f_path, &stat); -#else +#elif defined(HAVE_3ARGS_VFS_GETATTR) rc = vfs_getattr(filp->f_path.mnt, filp->f_dentry, &stat); +#else +#error "No available vfs_getattr()" #endif if (rc) return (-rc); diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_ioctl_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_ioctl_os.c index 6f5cff1770e..fee3fe540b9 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_ioctl_os.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_ioctl_os.c @@ -87,71 +87,20 @@ zfs_vfs_rele(zfsvfs_t *zfsvfs) deactivate_super(zfsvfs->z_sb); } -static int -zfsdev_state_init(struct file *filp) +void +zfsdev_private_set_state(void *priv, zfsdev_state_t *zs) { - zfsdev_state_t *zs, *zsprev = NULL; - minor_t minor; - boolean_t newzs = B_FALSE; - - ASSERT(MUTEX_HELD(&zfsdev_state_lock)); - - minor = zfsdev_minor_alloc(); - if (minor == 0) - return (SET_ERROR(ENXIO)); - - for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) { - if (zs->zs_minor == -1) - break; - zsprev = zs; - } - - if (!zs) { - zs = kmem_zalloc(sizeof (zfsdev_state_t), KM_SLEEP); - newzs = B_TRUE; - } + struct file *filp = priv; filp->private_data = zs; - - zfs_onexit_init((zfs_onexit_t **)&zs->zs_onexit); - zfs_zevent_init((zfs_zevent_t **)&zs->zs_zevent); - - /* - * In order to provide for lock-free concurrent read access - * to the minor list in zfsdev_get_state_impl(), new entries - * must be completely written before linking them into the - * list whereas existing entries are already linked; the last - * operation must be updating zs_minor (from -1 to the new - * value). - */ - if (newzs) { - zs->zs_minor = minor; - smp_wmb(); - zsprev->zs_next = zs; - } else { - smp_wmb(); - zs->zs_minor = minor; - } - - return (0); } -static int -zfsdev_state_destroy(struct file *filp) +zfsdev_state_t * +zfsdev_private_get_state(void *priv) { - zfsdev_state_t *zs; + struct file *filp = priv; - ASSERT(MUTEX_HELD(&zfsdev_state_lock)); - ASSERT(filp->private_data != NULL); - - zs = filp->private_data; - zs->zs_minor = -1; - zfs_onexit_destroy(zs->zs_onexit); - zfs_zevent_destroy(zs->zs_zevent); - zs->zs_onexit = NULL; - zs->zs_zevent = NULL; - - return (0); + return (filp->private_data); } static int @@ -169,13 +118,9 @@ zfsdev_open(struct inode *ino, struct file *filp) static int zfsdev_release(struct inode *ino, struct file *filp) { - int error; + zfsdev_state_destroy(filp); - mutex_enter(&zfsdev_state_lock); - error = zfsdev_state_destroy(filp); - mutex_exit(&zfsdev_state_lock); - - return (-error); + return (0); } static long @@ -212,6 +157,12 @@ zfs_max_nvlist_src_size_os(void) return (MIN(ptob(zfs_totalram_pages) / 4, 128 * 1024 * 1024)); } +/* Update the VFS's cache of mountpoint properties */ +void +zfs_ioctl_update_mount_cache(const char *dsname) +{ +} + void zfs_ioctl_init_os(void) { @@ -283,7 +234,7 @@ zfsdev_detach(void) #endif static int __init -_init(void) +openzfs_init(void) { int error; @@ -309,7 +260,7 @@ _init(void) } static void __exit -_fini(void) +openzfs_fini(void) { zfs_sysfs_fini(); zfs_kmod_fini(); @@ -319,8 +270,8 @@ _fini(void) } #if defined(_KERNEL) -module_init(_init); -module_exit(_fini); +module_init(openzfs_init); +module_exit(openzfs_fini); #endif ZFS_MODULE_DESCRIPTION("ZFS"); diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c index 5d672af0e8a..ff0b0d9df8f 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c @@ -433,12 +433,6 @@ snapdir_changed_cb(void *arg, uint64_t newval) ((zfsvfs_t *)arg)->z_show_ctldir = newval; } -static void -vscan_changed_cb(void *arg, uint64_t newval) -{ - ((zfsvfs_t *)arg)->z_vscan = newval; -} - static void acl_mode_changed_cb(void *arg, uint64_t newval) { @@ -511,8 +505,6 @@ zfs_register_callbacks(vfs_t *vfsp) error = error ? error : dsl_prop_register(ds, zfs_prop_to_name(ZFS_PROP_ACLINHERIT), acl_inherit_changed_cb, zfsvfs); - error = error ? error : dsl_prop_register(ds, - zfs_prop_to_name(ZFS_PROP_VSCAN), vscan_changed_cb, zfsvfs); error = error ? error : dsl_prop_register(ds, zfs_prop_to_name(ZFS_PROP_NBMAND), nbmand_changed_cb, zfsvfs); dsl_pool_config_exit(dmu_objset_pool(os), FTAG); diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c index 8aeed6f568c..24c016c5fcf 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c @@ -175,18 +175,6 @@ * return (error); // done, report error */ -/* - * Virus scanning is unsupported. It would be possible to add a hook - * here to performance the required virus scan. This could be done - * entirely in the kernel or potentially as an update to invoke a - * scanning utility. - */ -static int -zfs_vscan(struct inode *ip, cred_t *cr, int async) -{ - return (0); -} - /* ARGSUSED */ int zfs_open(struct inode *ip, int mode, int flag, cred_t *cr) @@ -204,15 +192,6 @@ zfs_open(struct inode *ip, int mode, int flag, cred_t *cr) return (SET_ERROR(EPERM)); } - /* Virus scan eligible files on open */ - if (!zfs_has_ctldir(zp) && zfsvfs->z_vscan && S_ISREG(ip->i_mode) && - !(zp->z_pflags & ZFS_AV_QUARANTINED) && zp->z_size > 0) { - if (zfs_vscan(ip, cr, 0) != 0) { - ZFS_EXIT(zfsvfs); - return (SET_ERROR(EACCES)); - } - } - /* Keep a count of the synchronous opens in the znode */ if (flag & O_SYNC) atomic_inc_32(&zp->z_sync_cnt); @@ -235,10 +214,6 @@ zfs_close(struct inode *ip, int flag, cred_t *cr) if (flag & O_SYNC) atomic_dec_32(&zp->z_sync_cnt); - if (!zfs_has_ctldir(zp) && zfsvfs->z_vscan && S_ISREG(ip->i_mode) && - !(zp->z_pflags & ZFS_AV_QUARANTINED) && zp->z_size > 0) - VERIFY(zfs_vscan(ip, cr, 1) == 0); - ZFS_EXIT(zfsvfs); return (0); } @@ -3140,7 +3115,7 @@ top: /* * Create a new object for the symlink. - * for version 4 ZPL datsets the symlink will be an SA attribute + * for version 4 ZPL datasets the symlink will be an SA attribute */ zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids); @@ -3950,6 +3925,13 @@ zfs_fid(struct inode *ip, fid_t *fidp) int size, i, error; ZFS_ENTER(zfsvfs); + + if (fidp->fid_len < SHORT_FID_LEN) { + fidp->fid_len = SHORT_FID_LEN; + ZFS_EXIT(zfsvfs); + return (SET_ERROR(ENOSPC)); + } + ZFS_VERIFY_ZP(zp); if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zfsvfs), diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode.c index d59c1bb0716..6015aea62dc 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode.c @@ -151,9 +151,9 @@ zfs_znode_cache_destructor(void *buf, void *arg) rw_destroy(&zp->z_xattr_lock); zfs_rangelock_fini(&zp->z_rangelock); - ASSERT(zp->z_dirlocks == NULL); - ASSERT(zp->z_acl_cached == NULL); - ASSERT(zp->z_xattr_cached == NULL); + ASSERT3P(zp->z_dirlocks, ==, NULL); + ASSERT3P(zp->z_acl_cached, ==, NULL); + ASSERT3P(zp->z_xattr_cached, ==, NULL); } static int @@ -217,7 +217,7 @@ zfs_znode_fini(void) * created or destroyed. This kind of locking would normally reside in the * znode itself but in this case that's impossible because the znode and SA * buffer may not yet exist. Therefore the locking is handled externally - * with an array of mutexs and AVLs trees which contain per-object locks. + * with an array of mutexes and AVLs trees which contain per-object locks. * * In zfs_znode_hold_enter() a per-object lock is created as needed, inserted * in to the correct AVL tree and finally the per-object lock is held. In diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c b/sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c index 2c58fecb206..94406999cb8 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c @@ -115,7 +115,7 @@ * Similarly to ZIL blocks, the core part of each dnode_phys_t needs to be left * in plaintext for scrubbing and claiming, but the bonus buffers might contain * sensitive user data. The function zio_crypt_init_uios_dnode() handles parsing - * which which pieces of the block need to be encrypted. For more details about + * which pieces of the block need to be encrypted. For more details about * dnode authentication and encryption, see zio_crypt_init_uios_dnode(). * * OBJECT SET AUTHENTICATION: @@ -1197,16 +1197,6 @@ zio_crypt_do_objset_hmacs(zio_crypt_key_t *key, void *data, uint_t datalen, bcopy(raw_portable_mac, portable_mac, ZIO_OBJSET_MAC_LEN); - /* - * This is necessary here as we check next whether - * OBJSET_FLAG_USERACCOUNTING_COMPLETE or - * OBJSET_FLAG_USEROBJACCOUNTING are set in order to - * decide if the local_mac should be zeroed out. - */ - intval = osp->os_flags; - if (should_bswap) - intval = BSWAP_64(intval); - /* * The local MAC protects the user, group and project accounting. * If these objects are not present, the local MAC is zeroed out. @@ -1218,10 +1208,7 @@ zio_crypt_do_objset_hmacs(zio_crypt_key_t *key, void *data, uint_t datalen, (datalen >= OBJSET_PHYS_SIZE_V2 && osp->os_userused_dnode.dn_type == DMU_OT_NONE && osp->os_groupused_dnode.dn_type == DMU_OT_NONE) || - (datalen <= OBJSET_PHYS_SIZE_V1) || - (((intval & OBJSET_FLAG_USERACCOUNTING_COMPLETE) == 0 || - (intval & OBJSET_FLAG_USEROBJACCOUNTING_COMPLETE) == 0) && - key->zk_version > 0)) { + (datalen <= OBJSET_PHYS_SIZE_V1)) { bzero(local_mac, ZIO_OBJSET_MAC_LEN); return (0); } diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_export.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_export.c index eaf048c38db..5be63532d32 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_export.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_export.c @@ -41,15 +41,19 @@ zpl_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, int connectable) struct inode *ip = dentry->d_inode; #endif /* HAVE_ENCODE_FH_WITH_INODE */ fstrans_cookie_t cookie; - fid_t *fid = (fid_t *)fh; + ushort_t empty_fid = 0; + fid_t *fid; int len_bytes, rc; len_bytes = *max_len * sizeof (__u32); - if (len_bytes < offsetof(fid_t, fid_data)) - return (255); + if (len_bytes < offsetof(fid_t, fid_data)) { + fid = (fid_t *)&empty_fid; + } else { + fid = (fid_t *)fh; + fid->fid_len = len_bytes - offsetof(fid_t, fid_data); + } - fid->fid_len = len_bytes - offsetof(fid_t, fid_data); cookie = spl_fstrans_mark(); if (zfsctl_is_node(ip)) diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c index d042783da1b..524c43dcded 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c @@ -148,7 +148,7 @@ zpl_aio_fsync(struct kiocb *kiocb, int datasync) #elif defined(HAVE_FSYNC_RANGE) /* - * Linux 3.1 - 3.x API, + * Linux 3.1 API, * As of 3.1 the responsibility to call filemap_write_and_wait_range() has * been pushed down in to the .fsync() vfs hook. Additionally, the i_mutex * lock is no longer held by the caller, for zfs we don't require the lock @@ -342,9 +342,6 @@ zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from) ssize_t wrote = count - uio.uio_resid; kiocb->ki_pos += wrote; - if (wrote > 0) - iov_iter_advance(from, wrote); - return (wrote); } diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c index cf0eab3e8c9..98c2fb3a0c9 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c @@ -149,14 +149,17 @@ zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag) error = -zfs_create(ITOZ(dir), dname(dentry), vap, 0, mode, &zp, cr, 0, NULL); if (error == 0) { - d_instantiate(dentry, ZTOI(zp)); - error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name); if (error == 0) error = zpl_init_acl(ZTOI(zp), dir); - if (error) + if (error) { (void) zfs_remove(ITOZ(dir), dname(dentry), cr, 0); + remove_inode_hash(ZTOI(zp)); + iput(ZTOI(zp)); + } else { + d_instantiate(dentry, ZTOI(zp)); + } } spl_fstrans_unmark(cookie); @@ -198,14 +201,17 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, error = -zfs_create(ITOZ(dir), dname(dentry), vap, 0, mode, &zp, cr, 0, NULL); if (error == 0) { - d_instantiate(dentry, ZTOI(zp)); - error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name); if (error == 0) error = zpl_init_acl(ZTOI(zp), dir); - if (error) + if (error) { (void) zfs_remove(ITOZ(dir), dname(dentry), cr, 0); + remove_inode_hash(ZTOI(zp)); + iput(ZTOI(zp)); + } else { + d_instantiate(dentry, ZTOI(zp)); + } } spl_fstrans_unmark(cookie); @@ -218,7 +224,12 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, #ifdef HAVE_TMPFILE static int +#ifdef HAVE_TMPFILE_USERNS +zpl_tmpfile(struct user_namespace *userns, struct inode *dir, + struct dentry *dentry, umode_t mode) +#else zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) +#endif { cred_t *cr = CRED(); struct inode *ip; @@ -308,14 +319,17 @@ zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) cookie = spl_fstrans_mark(); error = -zfs_mkdir(ITOZ(dir), dname(dentry), vap, &zp, cr, 0, NULL); if (error == 0) { - d_instantiate(dentry, ZTOI(zp)); - error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name); if (error == 0) error = zpl_init_acl(ZTOI(zp), dir); - if (error) + if (error) { (void) zfs_rmdir(ITOZ(dir), dname(dentry), NULL, cr, 0); + remove_inode_hash(ZTOI(zp)); + iput(ZTOI(zp)); + } else { + d_instantiate(dentry, ZTOI(zp)); + } } spl_fstrans_unmark(cookie); @@ -488,11 +502,14 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name) error = -zfs_symlink(ITOZ(dir), dname(dentry), vap, (char *)name, &zp, cr, 0); if (error == 0) { - d_instantiate(dentry, ZTOI(zp)); - error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name); - if (error) + if (error) { (void) zfs_remove(ITOZ(dir), dname(dentry), cr, 0); + remove_inode_hash(ZTOI(zp)); + iput(ZTOI(zp)); + } else { + d_instantiate(dentry, ZTOI(zp)); + } } spl_fstrans_unmark(cookie); diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_xattr.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_xattr.c index 971cd6ad031..66f197e4c77 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_xattr.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_xattr.c @@ -605,7 +605,7 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value, cookie = spl_fstrans_mark(); ZPL_ENTER(zfsvfs); ZPL_VERIFY_ZP(zp); - rw_enter(&ITOZ(ip)->z_xattr_lock, RW_WRITER); + rw_enter(&zp->z_xattr_lock, RW_WRITER); /* * Before setting the xattr check to see if it already exists. @@ -656,7 +656,7 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value, if (error == 0 && (where & XATTR_IN_SA)) zpl_xattr_set_sa(ip, name, NULL, 0, 0, cr); out: - rw_exit(&ITOZ(ip)->z_xattr_lock); + rw_exit(&zp->z_xattr_lock); ZPL_EXIT(zfsvfs); spl_fstrans_unmark(cookie); crfree(cr); @@ -926,11 +926,8 @@ xattr_handler_t zpl_xattr_security_handler = { * attribute implemented by filesystems in the kernel." - xattr(7) */ #ifdef CONFIG_FS_POSIX_ACL -#ifndef HAVE_SET_ACL -static -#endif -int -zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type) +static int +zpl_set_acl_impl(struct inode *ip, struct posix_acl *acl, int type) { char *name, *value = NULL; int error = 0; @@ -1002,6 +999,19 @@ zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type) return (error); } +#ifdef HAVE_SET_ACL +int +#ifdef HAVE_SET_ACL_USERNS +zpl_set_acl(struct user_namespace *userns, struct inode *ip, + struct posix_acl *acl, int type) +#else +zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type) +#endif /* HAVE_SET_ACL_USERNS */ +{ + return (zpl_set_acl_impl(ip, acl, type)); +} +#endif /* HAVE_SET_ACL */ + struct posix_acl * zpl_get_acl(struct inode *ip, int type) { @@ -1083,7 +1093,7 @@ zpl_init_acl(struct inode *ip, struct inode *dir) umode_t mode; if (S_ISDIR(ip->i_mode)) { - error = zpl_set_acl(ip, acl, ACL_TYPE_DEFAULT); + error = zpl_set_acl_impl(ip, acl, ACL_TYPE_DEFAULT); if (error) goto out; } @@ -1093,8 +1103,10 @@ zpl_init_acl(struct inode *ip, struct inode *dir) if (error >= 0) { ip->i_mode = mode; zfs_mark_inode_dirty(ip); - if (error > 0) - error = zpl_set_acl(ip, acl, ACL_TYPE_ACCESS); + if (error > 0) { + error = zpl_set_acl_impl(ip, acl, + ACL_TYPE_ACCESS); + } } } out: @@ -1121,7 +1133,7 @@ zpl_chmod_acl(struct inode *ip) error = __posix_acl_chmod(&acl, GFP_KERNEL, ip->i_mode); if (!error) - error = zpl_set_acl(ip, acl, ACL_TYPE_ACCESS); + error = zpl_set_acl_impl(ip, acl, ACL_TYPE_ACCESS); zpl_posix_acl_release(acl); @@ -1250,8 +1262,7 @@ __zpl_xattr_acl_set_access(struct inode *ip, const char *name, } else { acl = NULL; } - - error = zpl_set_acl(ip, acl, type); + error = zpl_set_acl_impl(ip, acl, type); zpl_posix_acl_release(acl); return (error); @@ -1291,7 +1302,7 @@ __zpl_xattr_acl_set_default(struct inode *ip, const char *name, acl = NULL; } - error = zpl_set_acl(ip, acl, type); + error = zpl_set_acl_impl(ip, acl, type); zpl_posix_acl_release(acl); return (error); diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c index 7756d819fde..741979f11af 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c @@ -756,7 +756,9 @@ static struct block_device_operations zvol_ops = { .ioctl = zvol_ioctl, .compat_ioctl = zvol_compat_ioctl, .check_events = zvol_check_events, +#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK .revalidate_disk = zvol_revalidate_disk, +#endif .getgeo = zvol_getgeo, .owner = THIS_MODULE, #ifdef HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS diff --git a/sys/contrib/openzfs/module/unicode/u8_textprep.c b/sys/contrib/openzfs/module/unicode/u8_textprep.c index be816d72835..c1d9a325f51 100644 --- a/sys/contrib/openzfs/module/unicode/u8_textprep.c +++ b/sys/contrib/openzfs/module/unicode/u8_textprep.c @@ -884,7 +884,7 @@ do_decomp(size_t uv, uchar_t *u8s, uchar_t *s, int sz, * | B0| B1| ... | Bm| * +---+---+-...-+---+ * - * The first byte, B0, is always less then 0xF5 (U8_DECOMP_BOTH). + * The first byte, B0, is always less than 0xF5 (U8_DECOMP_BOTH). * * (2) Canonical decomposition mappings: * diff --git a/sys/contrib/openzfs/module/zcommon/zfs_comutil.c b/sys/contrib/openzfs/module/zcommon/zfs_comutil.c index 1cec60ac1d6..886167759be 100644 --- a/sys/contrib/openzfs/module/zcommon/zfs_comutil.c +++ b/sys/contrib/openzfs/module/zcommon/zfs_comutil.c @@ -26,7 +26,7 @@ /* * This file is intended for functions that ought to be common between user * land (libzfs) and the kernel. When many common routines need to be shared - * then a separate file should to be created. + * then a separate file should be created. */ #if !defined(_KERNEL) diff --git a/sys/contrib/openzfs/module/zcommon/zfs_fletcher_avx512.c b/sys/contrib/openzfs/module/zcommon/zfs_fletcher_avx512.c index 300ec4c1fb6..963f089b04f 100644 --- a/sys/contrib/openzfs/module/zcommon/zfs_fletcher_avx512.c +++ b/sys/contrib/openzfs/module/zcommon/zfs_fletcher_avx512.c @@ -210,6 +210,12 @@ fletcher_4_avx512bw_byteswap(fletcher_4_ctx_t *ctx, const void *buf, } STACK_FRAME_NON_STANDARD(fletcher_4_avx512bw_byteswap); +static boolean_t +fletcher_4_avx512bw_valid(void) +{ + return (fletcher_4_avx512f_valid() && zfs_avx512bw_available()); +} + const fletcher_4_ops_t fletcher_4_avx512bw_ops = { .init_native = fletcher_4_avx512f_init, .fini_native = fletcher_4_avx512f_fini, @@ -217,7 +223,7 @@ const fletcher_4_ops_t fletcher_4_avx512bw_ops = { .init_byteswap = fletcher_4_avx512f_init, .fini_byteswap = fletcher_4_avx512f_fini, .compute_byteswap = fletcher_4_avx512bw_byteswap, - .valid = fletcher_4_avx512f_valid, + .valid = fletcher_4_avx512bw_valid, .name = "avx512bw" }; #endif diff --git a/sys/contrib/openzfs/module/zcommon/zfs_namecheck.c b/sys/contrib/openzfs/module/zcommon/zfs_namecheck.c index 0011a971cac..7ecce451b42 100644 --- a/sys/contrib/openzfs/module/zcommon/zfs_namecheck.c +++ b/sys/contrib/openzfs/module/zcommon/zfs_namecheck.c @@ -450,12 +450,6 @@ pool_namecheck(const char *pool, namecheck_err_t *why, char *what) return (-1); } - if (pool[0] == 'c' && (pool[1] >= '0' && pool[1] <= '9')) { - if (why) - *why = NAME_ERR_DISKLIKE; - return (-1); - } - return (0); } diff --git a/sys/contrib/openzfs/module/zcommon/zfs_prop.c b/sys/contrib/openzfs/module/zcommon/zfs_prop.c index 402d749c1ae..d1732199080 100644 --- a/sys/contrib/openzfs/module/zcommon/zfs_prop.c +++ b/sys/contrib/openzfs/module/zcommon/zfs_prop.c @@ -583,7 +583,7 @@ zfs_prop_init(void) "ENCROOT"); zprop_register_string(ZFS_PROP_KEYLOCATION, "keylocation", "none", PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, - "prompt | ", "KEYLOCATION"); + "prompt | | | ", "KEYLOCATION"); zprop_register_string(ZFS_PROP_REDACT_SNAPS, "redact_snaps", NULL, PROP_READONLY, ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "[,...]", @@ -936,6 +936,10 @@ zfs_prop_valid_keylocation(const char *str, boolean_t encrypted) return (B_TRUE); else if (strlen(str) > 8 && strncmp("file:///", str, 8) == 0) return (B_TRUE); + else if (strlen(str) > 8 && strncmp("https://", str, 8) == 0) + return (B_TRUE); + else if (strlen(str) > 7 && strncmp("http://", str, 7) == 0) + return (B_TRUE); return (B_FALSE); } diff --git a/sys/contrib/openzfs/module/zfs/abd.c b/sys/contrib/openzfs/module/zfs/abd.c index 1e6645c90c9..2d1be9752d4 100644 --- a/sys/contrib/openzfs/module/zfs/abd.c +++ b/sys/contrib/openzfs/module/zfs/abd.c @@ -381,7 +381,7 @@ abd_gang_add_gang(abd_t *pabd, abd_t *cabd, boolean_t free_on_free) child = list_next(&ABD_GANG(cabd).abd_gang_chain, child)) { /* * We always pass B_FALSE for free_on_free as it is the - * original child gang ABDs responsibilty to determine + * original child gang ABDs responsibility to determine * if any of its child ABDs should be free'd on the call * to abd_free(). */ diff --git a/sys/contrib/openzfs/module/zfs/aggsum.c b/sys/contrib/openzfs/module/zfs/aggsum.c index e46da95f676..c4ea4f86fc5 100644 --- a/sys/contrib/openzfs/module/zfs/aggsum.c +++ b/sys/contrib/openzfs/module/zfs/aggsum.c @@ -78,11 +78,11 @@ */ /* - * We will borrow aggsum_borrow_multiplier times the current request, so we will - * have to get the as_lock approximately every aggsum_borrow_multiplier calls to - * aggsum_delta(). + * We will borrow 2^aggsum_borrow_shift times the current request, so we will + * have to get the as_lock approximately every 2^aggsum_borrow_shift calls to + * aggsum_add(). */ -static uint_t aggsum_borrow_multiplier = 10; +static uint_t aggsum_borrow_shift = 4; void aggsum_init(aggsum_t *as, uint64_t value) @@ -90,9 +90,14 @@ aggsum_init(aggsum_t *as, uint64_t value) bzero(as, sizeof (*as)); as->as_lower_bound = as->as_upper_bound = value; mutex_init(&as->as_lock, NULL, MUTEX_DEFAULT, NULL); - as->as_numbuckets = boot_ncpus; - as->as_buckets = kmem_zalloc(boot_ncpus * sizeof (aggsum_bucket_t), - KM_SLEEP); + /* + * Too many buckets may hurt read performance without improving + * write. From 12 CPUs use bucket per 2 CPUs, from 48 per 4, etc. + */ + as->as_bucketshift = highbit64(boot_ncpus / 6) / 2; + as->as_numbuckets = ((boot_ncpus - 1) >> as->as_bucketshift) + 1; + as->as_buckets = kmem_zalloc(as->as_numbuckets * + sizeof (aggsum_bucket_t), KM_SLEEP); for (int i = 0; i < as->as_numbuckets; i++) { mutex_init(&as->as_buckets[i].asc_lock, NULL, MUTEX_DEFAULT, NULL); @@ -111,59 +116,49 @@ aggsum_fini(aggsum_t *as) int64_t aggsum_lower_bound(aggsum_t *as) { - return (as->as_lower_bound); + return (atomic_load_64((volatile uint64_t *)&as->as_lower_bound)); } -int64_t +uint64_t aggsum_upper_bound(aggsum_t *as) { - return (as->as_upper_bound); -} - -static void -aggsum_flush_bucket(aggsum_t *as, struct aggsum_bucket *asb) -{ - ASSERT(MUTEX_HELD(&as->as_lock)); - ASSERT(MUTEX_HELD(&asb->asc_lock)); - - /* - * We use atomic instructions for this because we read the upper and - * lower bounds without the lock, so we need stores to be atomic. - */ - atomic_add_64((volatile uint64_t *)&as->as_lower_bound, - asb->asc_delta + asb->asc_borrowed); - atomic_add_64((volatile uint64_t *)&as->as_upper_bound, - asb->asc_delta - asb->asc_borrowed); - asb->asc_delta = 0; - asb->asc_borrowed = 0; + return (atomic_load_64(&as->as_upper_bound)); } uint64_t aggsum_value(aggsum_t *as) { - int64_t rv; + int64_t lb; + uint64_t ub; mutex_enter(&as->as_lock); - if (as->as_lower_bound == as->as_upper_bound) { - rv = as->as_lower_bound; + lb = as->as_lower_bound; + ub = as->as_upper_bound; + if (lb == ub) { for (int i = 0; i < as->as_numbuckets; i++) { ASSERT0(as->as_buckets[i].asc_delta); ASSERT0(as->as_buckets[i].asc_borrowed); } mutex_exit(&as->as_lock); - return (rv); + return (lb); } for (int i = 0; i < as->as_numbuckets; i++) { struct aggsum_bucket *asb = &as->as_buckets[i]; + if (asb->asc_borrowed == 0) + continue; mutex_enter(&asb->asc_lock); - aggsum_flush_bucket(as, asb); + lb += asb->asc_delta + asb->asc_borrowed; + ub += asb->asc_delta - asb->asc_borrowed; + asb->asc_delta = 0; + asb->asc_borrowed = 0; mutex_exit(&asb->asc_lock); } - VERIFY3U(as->as_lower_bound, ==, as->as_upper_bound); - rv = as->as_lower_bound; + ASSERT3U(lb, ==, ub); + atomic_store_64((volatile uint64_t *)&as->as_lower_bound, lb); + atomic_store_64(&as->as_upper_bound, lb); mutex_exit(&as->as_lock); - return (rv); + return (lb); } void @@ -172,7 +167,8 @@ aggsum_add(aggsum_t *as, int64_t delta) struct aggsum_bucket *asb; int64_t borrow; - asb = &as->as_buckets[CPU_SEQID_UNSTABLE % as->as_numbuckets]; + asb = &as->as_buckets[(CPU_SEQID_UNSTABLE >> as->as_bucketshift) % + as->as_numbuckets]; /* Try fast path if we already borrowed enough before. */ mutex_enter(&asb->asc_lock); @@ -188,21 +184,22 @@ aggsum_add(aggsum_t *as, int64_t delta) * We haven't borrowed enough. Take the global lock and borrow * considering what is requested now and what we borrowed before. */ - borrow = (delta < 0 ? -delta : delta) * aggsum_borrow_multiplier; + borrow = (delta < 0 ? -delta : delta); + borrow <<= aggsum_borrow_shift + as->as_bucketshift; mutex_enter(&as->as_lock); - mutex_enter(&asb->asc_lock); - delta += asb->asc_delta; - asb->asc_delta = 0; if (borrow >= asb->asc_borrowed) borrow -= asb->asc_borrowed; else borrow = (borrow - (int64_t)asb->asc_borrowed) / 4; + mutex_enter(&asb->asc_lock); + delta += asb->asc_delta; + asb->asc_delta = 0; asb->asc_borrowed += borrow; - atomic_add_64((volatile uint64_t *)&as->as_lower_bound, - delta - borrow); - atomic_add_64((volatile uint64_t *)&as->as_upper_bound, - delta + borrow); mutex_exit(&asb->asc_lock); + atomic_store_64((volatile uint64_t *)&as->as_lower_bound, + as->as_lower_bound + delta - borrow); + atomic_store_64(&as->as_upper_bound, + as->as_upper_bound + delta + borrow); mutex_exit(&as->as_lock); } @@ -214,27 +211,35 @@ aggsum_add(aggsum_t *as, int64_t delta) int aggsum_compare(aggsum_t *as, uint64_t target) { - if (as->as_upper_bound < target) + int64_t lb; + uint64_t ub; + int i; + + if (atomic_load_64(&as->as_upper_bound) < target) return (-1); - if (as->as_lower_bound > target) + lb = atomic_load_64((volatile uint64_t *)&as->as_lower_bound); + if (lb > 0 && (uint64_t)lb > target) return (1); mutex_enter(&as->as_lock); - for (int i = 0; i < as->as_numbuckets; i++) { + lb = as->as_lower_bound; + ub = as->as_upper_bound; + for (i = 0; i < as->as_numbuckets; i++) { struct aggsum_bucket *asb = &as->as_buckets[i]; + if (asb->asc_borrowed == 0) + continue; mutex_enter(&asb->asc_lock); - aggsum_flush_bucket(as, asb); + lb += asb->asc_delta + asb->asc_borrowed; + ub += asb->asc_delta - asb->asc_borrowed; + asb->asc_delta = 0; + asb->asc_borrowed = 0; mutex_exit(&asb->asc_lock); - if (as->as_upper_bound < target) { - mutex_exit(&as->as_lock); - return (-1); - } - if (as->as_lower_bound > target) { - mutex_exit(&as->as_lock); - return (1); - } + if (ub < target || (lb > 0 && (uint64_t)lb > target)) + break; } - VERIFY3U(as->as_lower_bound, ==, as->as_upper_bound); - ASSERT3U(as->as_lower_bound, ==, target); + if (i >= as->as_numbuckets) + ASSERT3U(lb, ==, ub); + atomic_store_64((volatile uint64_t *)&as->as_lower_bound, lb); + atomic_store_64(&as->as_upper_bound, ub); mutex_exit(&as->as_lock); - return (0); + return (ub < target ? -1 : (uint64_t)lb > target ? 1 : 0); } diff --git a/sys/contrib/openzfs/module/zfs/arc.c b/sys/contrib/openzfs/module/zfs/arc.c index 55c71a3829c..5526cae378f 100644 --- a/sys/contrib/openzfs/module/zfs/arc.c +++ b/sys/contrib/openzfs/module/zfs/arc.c @@ -305,6 +305,7 @@ #include #include #include +#include #include #include #include @@ -692,14 +693,14 @@ arc_state_t *arc_mfu; */ aggsum_t arc_size; aggsum_t arc_meta_used; -aggsum_t astat_data_size; -aggsum_t astat_metadata_size; -aggsum_t astat_dbuf_size; +wmsum_t astat_data_size; +wmsum_t astat_metadata_size; +wmsum_t astat_dbuf_size; aggsum_t astat_dnode_size; -aggsum_t astat_bonus_size; -aggsum_t astat_hdr_size; +wmsum_t astat_bonus_size; +wmsum_t astat_hdr_size; aggsum_t astat_l2_hdr_size; -aggsum_t astat_abd_chunk_waste_size; +wmsum_t astat_abd_chunk_waste_size; hrtime_t arc_growtime; list_t arc_prune_list; @@ -2645,22 +2646,22 @@ arc_space_consume(uint64_t space, arc_space_type_t type) default: break; case ARC_SPACE_DATA: - aggsum_add(&astat_data_size, space); + wmsum_add(&astat_data_size, space); break; case ARC_SPACE_META: - aggsum_add(&astat_metadata_size, space); + wmsum_add(&astat_metadata_size, space); break; case ARC_SPACE_BONUS: - aggsum_add(&astat_bonus_size, space); + wmsum_add(&astat_bonus_size, space); break; case ARC_SPACE_DNODE: aggsum_add(&astat_dnode_size, space); break; case ARC_SPACE_DBUF: - aggsum_add(&astat_dbuf_size, space); + wmsum_add(&astat_dbuf_size, space); break; case ARC_SPACE_HDRS: - aggsum_add(&astat_hdr_size, space); + wmsum_add(&astat_hdr_size, space); break; case ARC_SPACE_L2HDRS: aggsum_add(&astat_l2_hdr_size, space); @@ -2672,7 +2673,7 @@ arc_space_consume(uint64_t space, arc_space_type_t type) * scatter ABD's come from the ARC, because other users are * very short-lived. */ - aggsum_add(&astat_abd_chunk_waste_size, space); + wmsum_add(&astat_abd_chunk_waste_size, space); break; } @@ -2691,28 +2692,28 @@ arc_space_return(uint64_t space, arc_space_type_t type) default: break; case ARC_SPACE_DATA: - aggsum_add(&astat_data_size, -space); + wmsum_add(&astat_data_size, -space); break; case ARC_SPACE_META: - aggsum_add(&astat_metadata_size, -space); + wmsum_add(&astat_metadata_size, -space); break; case ARC_SPACE_BONUS: - aggsum_add(&astat_bonus_size, -space); + wmsum_add(&astat_bonus_size, -space); break; case ARC_SPACE_DNODE: aggsum_add(&astat_dnode_size, -space); break; case ARC_SPACE_DBUF: - aggsum_add(&astat_dbuf_size, -space); + wmsum_add(&astat_dbuf_size, -space); break; case ARC_SPACE_HDRS: - aggsum_add(&astat_hdr_size, -space); + wmsum_add(&astat_hdr_size, -space); break; case ARC_SPACE_L2HDRS: aggsum_add(&astat_l2_hdr_size, -space); break; case ARC_SPACE_ABD_CHUNK_WASTE: - aggsum_add(&astat_abd_chunk_waste_size, -space); + wmsum_add(&astat_abd_chunk_waste_size, -space); break; } @@ -3468,7 +3469,6 @@ arc_hdr_realloc_crypt(arc_buf_hdr_t *hdr, boolean_t need_crypt) arc_buf_hdr_t *nhdr; arc_buf_t *buf; kmem_cache_t *ncache, *ocache; - unsigned nsize, osize; /* * This function requires that hdr is in the arc_anon state. @@ -3485,14 +3485,10 @@ arc_hdr_realloc_crypt(arc_buf_hdr_t *hdr, boolean_t need_crypt) if (need_crypt) { ncache = hdr_full_crypt_cache; - nsize = sizeof (hdr->b_crypt_hdr); ocache = hdr_full_cache; - osize = HDR_FULL_SIZE; } else { ncache = hdr_full_cache; - nsize = HDR_FULL_SIZE; ocache = hdr_full_crypt_cache; - osize = sizeof (hdr->b_crypt_hdr); } nhdr = kmem_cache_alloc(ncache, KM_PUSHPAGE); @@ -5036,7 +5032,7 @@ arc_reap_cb(void *arg, zthr_t *zthr) * memory in the system at a fraction of the arc_size (1/128th by * default). If oversubscribed (free_memory < 0) then reduce the * target arc_size by the deficit amount plus the fractional - * amount. If free memory is positive but less then the fractional + * amount. If free memory is positive but less than the fractional * amount, reduce by what is needed to hit the fractional amount. */ free_memory = arc_available_memory(); @@ -7275,21 +7271,21 @@ arc_kstat_update(kstat_t *ksp, int rw) ARCSTAT(arcstat_size) = aggsum_value(&arc_size); ARCSTAT(arcstat_meta_used) = aggsum_value(&arc_meta_used); - ARCSTAT(arcstat_data_size) = aggsum_value(&astat_data_size); + ARCSTAT(arcstat_data_size) = wmsum_value(&astat_data_size); ARCSTAT(arcstat_metadata_size) = - aggsum_value(&astat_metadata_size); - ARCSTAT(arcstat_hdr_size) = aggsum_value(&astat_hdr_size); + wmsum_value(&astat_metadata_size); + ARCSTAT(arcstat_hdr_size) = wmsum_value(&astat_hdr_size); ARCSTAT(arcstat_l2_hdr_size) = aggsum_value(&astat_l2_hdr_size); - ARCSTAT(arcstat_dbuf_size) = aggsum_value(&astat_dbuf_size); + ARCSTAT(arcstat_dbuf_size) = wmsum_value(&astat_dbuf_size); #if defined(COMPAT_FREEBSD11) - ARCSTAT(arcstat_other_size) = aggsum_value(&astat_bonus_size) + + ARCSTAT(arcstat_other_size) = wmsum_value(&astat_bonus_size) + aggsum_value(&astat_dnode_size) + - aggsum_value(&astat_dbuf_size); + wmsum_value(&astat_dbuf_size); #endif ARCSTAT(arcstat_dnode_size) = aggsum_value(&astat_dnode_size); - ARCSTAT(arcstat_bonus_size) = aggsum_value(&astat_bonus_size); + ARCSTAT(arcstat_bonus_size) = wmsum_value(&astat_bonus_size); ARCSTAT(arcstat_abd_chunk_waste_size) = - aggsum_value(&astat_abd_chunk_waste_size); + wmsum_value(&astat_abd_chunk_waste_size); as->arcstat_memory_all_bytes.value.ui64 = arc_all_memory(); @@ -7522,14 +7518,14 @@ arc_state_init(void) aggsum_init(&arc_meta_used, 0); aggsum_init(&arc_size, 0); - aggsum_init(&astat_data_size, 0); - aggsum_init(&astat_metadata_size, 0); - aggsum_init(&astat_hdr_size, 0); + wmsum_init(&astat_data_size, 0); + wmsum_init(&astat_metadata_size, 0); + wmsum_init(&astat_hdr_size, 0); aggsum_init(&astat_l2_hdr_size, 0); - aggsum_init(&astat_bonus_size, 0); + wmsum_init(&astat_bonus_size, 0); aggsum_init(&astat_dnode_size, 0); - aggsum_init(&astat_dbuf_size, 0); - aggsum_init(&astat_abd_chunk_waste_size, 0); + wmsum_init(&astat_dbuf_size, 0); + wmsum_init(&astat_abd_chunk_waste_size, 0); arc_anon->arcs_state = ARC_STATE_ANON; arc_mru->arcs_state = ARC_STATE_MRU; @@ -7575,14 +7571,14 @@ arc_state_fini(void) aggsum_fini(&arc_meta_used); aggsum_fini(&arc_size); - aggsum_fini(&astat_data_size); - aggsum_fini(&astat_metadata_size); - aggsum_fini(&astat_hdr_size); + wmsum_fini(&astat_data_size); + wmsum_fini(&astat_metadata_size); + wmsum_fini(&astat_hdr_size); aggsum_fini(&astat_l2_hdr_size); - aggsum_fini(&astat_bonus_size); + wmsum_fini(&astat_bonus_size); aggsum_fini(&astat_dnode_size); - aggsum_fini(&astat_dbuf_size); - aggsum_fini(&astat_abd_chunk_waste_size); + wmsum_fini(&astat_dbuf_size); + wmsum_fini(&astat_abd_chunk_waste_size); } uint64_t diff --git a/sys/contrib/openzfs/module/zfs/dataset_kstats.c b/sys/contrib/openzfs/module/zfs/dataset_kstats.c index e46a0926d55..3fbb24ddef5 100644 --- a/sys/contrib/openzfs/module/zfs/dataset_kstats.c +++ b/sys/contrib/openzfs/module/zfs/dataset_kstats.c @@ -50,17 +50,17 @@ dataset_kstats_update(kstat_t *ksp, int rw) dataset_kstat_values_t *dkv = dk->dk_kstats->ks_data; dkv->dkv_writes.value.ui64 = - aggsum_value(&dk->dk_aggsums.das_writes); + wmsum_value(&dk->dk_sums.dss_writes); dkv->dkv_nwritten.value.ui64 = - aggsum_value(&dk->dk_aggsums.das_nwritten); + wmsum_value(&dk->dk_sums.dss_nwritten); dkv->dkv_reads.value.ui64 = - aggsum_value(&dk->dk_aggsums.das_reads); + wmsum_value(&dk->dk_sums.dss_reads); dkv->dkv_nread.value.ui64 = - aggsum_value(&dk->dk_aggsums.das_nread); + wmsum_value(&dk->dk_sums.dss_nread); dkv->dkv_nunlinks.value.ui64 = - aggsum_value(&dk->dk_aggsums.das_nunlinks); + wmsum_value(&dk->dk_sums.dss_nunlinks); dkv->dkv_nunlinked.value.ui64 = - aggsum_value(&dk->dk_aggsums.das_nunlinked); + wmsum_value(&dk->dk_sums.dss_nunlinked); return (0); } @@ -140,12 +140,12 @@ dataset_kstats_create(dataset_kstats_t *dk, objset_t *objset) kstat_install(kstat); dk->dk_kstats = kstat; - aggsum_init(&dk->dk_aggsums.das_writes, 0); - aggsum_init(&dk->dk_aggsums.das_nwritten, 0); - aggsum_init(&dk->dk_aggsums.das_reads, 0); - aggsum_init(&dk->dk_aggsums.das_nread, 0); - aggsum_init(&dk->dk_aggsums.das_nunlinks, 0); - aggsum_init(&dk->dk_aggsums.das_nunlinked, 0); + wmsum_init(&dk->dk_sums.dss_writes, 0); + wmsum_init(&dk->dk_sums.dss_nwritten, 0); + wmsum_init(&dk->dk_sums.dss_reads, 0); + wmsum_init(&dk->dk_sums.dss_nread, 0); + wmsum_init(&dk->dk_sums.dss_nunlinks, 0); + wmsum_init(&dk->dk_sums.dss_nunlinked, 0); } void @@ -162,12 +162,12 @@ dataset_kstats_destroy(dataset_kstats_t *dk) kstat_delete(dk->dk_kstats); dk->dk_kstats = NULL; - aggsum_fini(&dk->dk_aggsums.das_writes); - aggsum_fini(&dk->dk_aggsums.das_nwritten); - aggsum_fini(&dk->dk_aggsums.das_reads); - aggsum_fini(&dk->dk_aggsums.das_nread); - aggsum_fini(&dk->dk_aggsums.das_nunlinks); - aggsum_fini(&dk->dk_aggsums.das_nunlinked); + wmsum_fini(&dk->dk_sums.dss_writes); + wmsum_fini(&dk->dk_sums.dss_nwritten); + wmsum_fini(&dk->dk_sums.dss_reads); + wmsum_fini(&dk->dk_sums.dss_nread); + wmsum_fini(&dk->dk_sums.dss_nunlinks); + wmsum_fini(&dk->dk_sums.dss_nunlinked); } void @@ -179,8 +179,8 @@ dataset_kstats_update_write_kstats(dataset_kstats_t *dk, if (dk->dk_kstats == NULL) return; - aggsum_add(&dk->dk_aggsums.das_writes, 1); - aggsum_add(&dk->dk_aggsums.das_nwritten, nwritten); + wmsum_add(&dk->dk_sums.dss_writes, 1); + wmsum_add(&dk->dk_sums.dss_nwritten, nwritten); } void @@ -192,8 +192,8 @@ dataset_kstats_update_read_kstats(dataset_kstats_t *dk, if (dk->dk_kstats == NULL) return; - aggsum_add(&dk->dk_aggsums.das_reads, 1); - aggsum_add(&dk->dk_aggsums.das_nread, nread); + wmsum_add(&dk->dk_sums.dss_reads, 1); + wmsum_add(&dk->dk_sums.dss_nread, nread); } void @@ -202,7 +202,7 @@ dataset_kstats_update_nunlinks_kstat(dataset_kstats_t *dk, int64_t delta) if (dk->dk_kstats == NULL) return; - aggsum_add(&dk->dk_aggsums.das_nunlinks, delta); + wmsum_add(&dk->dk_sums.dss_nunlinks, delta); } void @@ -211,5 +211,5 @@ dataset_kstats_update_nunlinked_kstat(dataset_kstats_t *dk, int64_t delta) if (dk->dk_kstats == NULL) return; - aggsum_add(&dk->dk_aggsums.das_nunlinked, delta); + wmsum_add(&dk->dk_sums.dss_nunlinked, delta); } diff --git a/sys/contrib/openzfs/module/zfs/dbuf.c b/sys/contrib/openzfs/module/zfs/dbuf.c index d48dc7943a2..764383b2d03 100644 --- a/sys/contrib/openzfs/module/zfs/dbuf.c +++ b/sys/contrib/openzfs/module/zfs/dbuf.c @@ -1442,10 +1442,8 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags, zbookmark_phys_t zb; uint32_t aflags = ARC_FLAG_NOWAIT; int err, zio_flags; - boolean_t bonus_read; err = zio_flags = 0; - bonus_read = B_FALSE; DB_DNODE_ENTER(db); dn = DB_DNODE(db); ASSERT(!zfs_refcount_is_zero(&db->db_holds)); diff --git a/sys/contrib/openzfs/module/zfs/dmu_recv.c b/sys/contrib/openzfs/module/zfs/dmu_recv.c index 123ea05b043..a713e132902 100644 --- a/sys/contrib/openzfs/module/zfs/dmu_recv.c +++ b/sys/contrib/openzfs/module/zfs/dmu_recv.c @@ -2880,8 +2880,8 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp) int err = 0; struct receive_writer_arg *rwa = kmem_zalloc(sizeof (*rwa), KM_SLEEP); - if (dsl_dataset_is_zapified(drc->drc_ds)) { - uint64_t bytes; + if (dsl_dataset_has_resume_receive_state(drc->drc_ds)) { + uint64_t bytes = 0; (void) zap_lookup(drc->drc_ds->ds_dir->dd_pool->dp_meta_objset, drc->drc_ds->ds_object, DS_FIELD_RESUME_BYTES, sizeof (bytes), 1, &bytes); diff --git a/sys/contrib/openzfs/module/zfs/dmu_traverse.c b/sys/contrib/openzfs/module/zfs/dmu_traverse.c index 31db49dae68..862c0bf404a 100644 --- a/sys/contrib/openzfs/module/zfs/dmu_traverse.c +++ b/sys/contrib/openzfs/module/zfs/dmu_traverse.c @@ -41,6 +41,7 @@ int32_t zfs_pd_bytes_max = 50 * 1024 * 1024; /* 50MB */ int32_t send_holes_without_birth_time = 1; +int32_t zfs_traverse_indirect_prefetch_limit = 32; typedef struct prefetch_data { kmutex_t pd_mtx; @@ -176,7 +177,10 @@ resume_skip_check(traverse_data_t *td, const dnode_phys_t *dnp, return (RESUME_SKIP_NONE); } -static void +/* + * Returns B_TRUE, if prefetch read is issued, otherwise B_FALSE. + */ +static boolean_t traverse_prefetch_metadata(traverse_data_t *td, const blkptr_t *bp, const zbookmark_phys_t *zb) { @@ -184,18 +188,18 @@ traverse_prefetch_metadata(traverse_data_t *td, int zio_flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE; if (!(td->td_flags & TRAVERSE_PREFETCH_METADATA)) - return; + return (B_FALSE); /* * If we are in the process of resuming, don't prefetch, because * some children will not be needed (and in fact may have already * been freed). */ if (td->td_resume != NULL && !ZB_IS_ZERO(td->td_resume)) - return; + return (B_FALSE); if (BP_IS_HOLE(bp) || bp->blk_birth <= td->td_min_txg) - return; + return (B_FALSE); if (BP_GET_LEVEL(bp) == 0 && BP_GET_TYPE(bp) != DMU_OT_DNODE) - return; + return (B_FALSE); ASSERT(!BP_IS_REDACTED(bp)); if ((td->td_flags & TRAVERSE_NO_DECRYPT) && BP_IS_PROTECTED(bp)) @@ -203,6 +207,7 @@ traverse_prefetch_metadata(traverse_data_t *td, (void) arc_read(NULL, td->td_spa, bp, NULL, NULL, ZIO_PRIORITY_ASYNC_READ, zio_flags, &flags, zb); + return (B_TRUE); } static boolean_t @@ -295,7 +300,8 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp, if (BP_GET_LEVEL(bp) > 0) { uint32_t flags = ARC_FLAG_WAIT; - int32_t i; + int32_t i, ptidx, pidx; + uint32_t prefetchlimit; int32_t epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT; zbookmark_phys_t *czb; @@ -308,16 +314,46 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp, czb = kmem_alloc(sizeof (zbookmark_phys_t), KM_SLEEP); + /* + * When performing a traversal it is beneficial to + * asynchronously read-ahead the upcoming indirect + * blocks since they will be needed shortly. However, + * since a 128k indirect (non-L0) block may contain up + * to 1024 128-byte block pointers, its preferable to not + * prefetch them all at once. Issuing a large number of + * async reads may effect performance, and the earlier + * the indirect blocks are prefetched the less likely + * they are to still be resident in the ARC when needed. + * Therefore, prefetching indirect blocks is limited to + * zfs_traverse_indirect_prefetch_limit=32 blocks by + * default. + * + * pidx: Index for which next prefetch to be issued. + * ptidx: Index at which next prefetch to be triggered. + */ + ptidx = 0; + pidx = 1; + prefetchlimit = zfs_traverse_indirect_prefetch_limit; for (i = 0; i < epb; i++) { - SET_BOOKMARK(czb, zb->zb_objset, zb->zb_object, - zb->zb_level - 1, - zb->zb_blkid * epb + i); - traverse_prefetch_metadata(td, - &((blkptr_t *)buf->b_data)[i], czb); - } + if (prefetchlimit && i == ptidx) { + ASSERT3S(ptidx, <=, pidx); + for (uint32_t prefetched = 0; pidx < epb && + prefetched < prefetchlimit; pidx++) { + SET_BOOKMARK(czb, zb->zb_objset, + zb->zb_object, zb->zb_level - 1, + zb->zb_blkid * epb + pidx); + if (traverse_prefetch_metadata(td, + &((blkptr_t *)buf->b_data)[pidx], + czb) == B_TRUE) { + prefetched++; + if (prefetched == + MAX(prefetchlimit / 2, 1)) + ptidx = pidx; + } + } + } - /* recursively visitbp() blocks below this */ - for (i = 0; i < epb; i++) { + /* recursively visitbp() blocks below this */ SET_BOOKMARK(czb, zb->zb_objset, zb->zb_object, zb->zb_level - 1, zb->zb_blkid * epb + i); @@ -777,6 +813,9 @@ EXPORT_SYMBOL(traverse_pool); ZFS_MODULE_PARAM(zfs, zfs_, pd_bytes_max, INT, ZMOD_RW, "Max number of bytes to prefetch"); +ZFS_MODULE_PARAM(zfs, zfs_, traverse_indirect_prefetch_limit, INT, ZMOD_RW, + "Traverse prefetch number of blocks pointed by indirect block"); + #if defined(_KERNEL) module_param_named(ignore_hole_birth, send_holes_without_birth_time, int, 0644); MODULE_PARM_DESC(ignore_hole_birth, diff --git a/sys/contrib/openzfs/module/zfs/dnode.c b/sys/contrib/openzfs/module/zfs/dnode.c index eaba9c0c0e7..0fc788e28fe 100644 --- a/sys/contrib/openzfs/module/zfs/dnode.c +++ b/sys/contrib/openzfs/module/zfs/dnode.c @@ -754,7 +754,6 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn) ASSERT(!RW_LOCK_HELD(&odn->dn_struct_rwlock)); ASSERT(MUTEX_NOT_HELD(&odn->dn_mtx)); ASSERT(MUTEX_NOT_HELD(&odn->dn_dbufs_mtx)); - ASSERT(!MUTEX_HELD(&odn->dn_zfetch.zf_lock)); /* Copy fields. */ ndn->dn_objset = odn->dn_objset; @@ -822,9 +821,7 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn) ndn->dn_newgid = odn->dn_newgid; ndn->dn_newprojid = odn->dn_newprojid; ndn->dn_id_flags = odn->dn_id_flags; - dmu_zfetch_init(&ndn->dn_zfetch, NULL); - list_move_tail(&ndn->dn_zfetch.zf_stream, &odn->dn_zfetch.zf_stream); - ndn->dn_zfetch.zf_dnode = odn->dn_zfetch.zf_dnode; + dmu_zfetch_init(&ndn->dn_zfetch, ndn); /* * Update back pointers. Updating the handle fixes the back pointer of @@ -832,9 +829,6 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn) */ ASSERT(ndn->dn_handle->dnh_dnode == odn); ndn->dn_handle->dnh_dnode = ndn; - if (ndn->dn_zfetch.zf_dnode == odn) { - ndn->dn_zfetch.zf_dnode = ndn; - } /* * Invalidate the original dnode by clearing all of its back pointers. diff --git a/sys/contrib/openzfs/module/zfs/dsl_bookmark.c b/sys/contrib/openzfs/module/zfs/dsl_bookmark.c index 2faf1af5299..bead7da2237 100644 --- a/sys/contrib/openzfs/module/zfs/dsl_bookmark.c +++ b/sys/contrib/openzfs/module/zfs/dsl_bookmark.c @@ -236,7 +236,7 @@ dsl_bookmark_create_check_impl(dsl_pool_t *dp, error = SET_ERROR(EEXIST); goto eholdnewbmds; default: - /* dsl_bookmark_lookup_impl already did SET_ERRROR */ + /* dsl_bookmark_lookup_impl already did SET_ERROR */ goto eholdnewbmds; } @@ -271,7 +271,7 @@ dsl_bookmark_create_check_impl(dsl_pool_t *dp, error = SET_ERROR(ZFS_ERR_BOOKMARK_SOURCE_NOT_ANCESTOR); break; default: - /* dsl_bookmark_lookup already did SET_ERRROR */ + /* dsl_bookmark_lookup already did SET_ERROR */ break; } } else { @@ -536,7 +536,7 @@ dsl_bookmark_create_sync_impl_book( * Reasoning: * - The zbm_redaction_obj would be referred to by both source and new * bookmark, but would be destroyed once either source or new is - * destroyed, resulting in use-after-free of the referrred object. + * destroyed, resulting in use-after-free of the referred object. * - User expectation when issuing the `zfs bookmark` command is that * a normal bookmark of the source is created * diff --git a/sys/contrib/openzfs/module/zfs/dsl_crypt.c b/sys/contrib/openzfs/module/zfs/dsl_crypt.c index e38ec0cae82..26d4c2fe7e3 100644 --- a/sys/contrib/openzfs/module/zfs/dsl_crypt.c +++ b/sys/contrib/openzfs/module/zfs/dsl_crypt.c @@ -2007,6 +2007,14 @@ dsl_crypto_recv_raw_objset_check(dsl_dataset_t *ds, dsl_dataset_t *fromds, if (ret != 0) return (ret); + /* + * Useraccounting is not portable and must be done with the keys loaded. + * Therefore, whenever we do any kind of receive the useraccounting + * must not be present. + */ + ASSERT0(os->os_flags & OBJSET_FLAG_USERACCOUNTING_COMPLETE); + ASSERT0(os->os_flags & OBJSET_FLAG_USEROBJACCOUNTING_COMPLETE); + mdn = DMU_META_DNODE(os); /* @@ -2097,9 +2105,6 @@ dsl_crypto_recv_raw_objset_sync(dsl_dataset_t *ds, dmu_objset_type_t ostype, */ arc_release(os->os_phys_buf, &os->os_phys_buf); bcopy(portable_mac, os->os_phys->os_portable_mac, ZIO_OBJSET_MAC_LEN); - os->os_phys->os_flags &= ~OBJSET_FLAG_USERACCOUNTING_COMPLETE; - os->os_phys->os_flags &= ~OBJSET_FLAG_USEROBJACCOUNTING_COMPLETE; - os->os_flags = os->os_phys->os_flags; bzero(os->os_phys->os_local_mac, ZIO_OBJSET_MAC_LEN); os->os_next_write_raw[tx->tx_txg & TXG_MASK] = B_TRUE; diff --git a/sys/contrib/openzfs/module/zfs/dsl_deadlist.c b/sys/contrib/openzfs/module/zfs/dsl_deadlist.c index bad2d56eefd..a77e381520d 100644 --- a/sys/contrib/openzfs/module/zfs/dsl_deadlist.c +++ b/sys/contrib/openzfs/module/zfs/dsl_deadlist.c @@ -909,15 +909,16 @@ dsl_deadlist_move_bpobj(dsl_deadlist_t *dl, bpobj_t *bpo, uint64_t mintxg, } typedef struct livelist_entry { - const blkptr_t *le_bp; + blkptr_t le_bp; + uint32_t le_refcnt; avl_node_t le_node; } livelist_entry_t; static int livelist_compare(const void *larg, const void *rarg) { - const blkptr_t *l = ((livelist_entry_t *)larg)->le_bp; - const blkptr_t *r = ((livelist_entry_t *)rarg)->le_bp; + const blkptr_t *l = &((livelist_entry_t *)larg)->le_bp; + const blkptr_t *r = &((livelist_entry_t *)rarg)->le_bp; /* Sort them according to dva[0] */ uint64_t l_dva0_vdev = DVA_GET_VDEV(&l->blk_dva[0]); @@ -944,6 +945,11 @@ struct livelist_iter_arg { * Expects an AVL tree which is incrementally filled will FREE blkptrs * and used to match up ALLOC/FREE pairs. ALLOC'd blkptrs without a * corresponding FREE are stored in the supplied bplist. + * + * Note that multiple FREE and ALLOC entries for the same blkptr may + * be encountered when dedup is involved. For this reason we keep a + * refcount for all the FREE entries of each blkptr and ensure that + * each of those FREE entries has a corresponding ALLOC preceding it. */ static int dsl_livelist_iterate(void *arg, const blkptr_t *bp, boolean_t bp_freed, @@ -957,23 +963,47 @@ dsl_livelist_iterate(void *arg, const blkptr_t *bp, boolean_t bp_freed, if ((t != NULL) && (zthr_has_waiters(t) || zthr_iscancelled(t))) return (SET_ERROR(EINTR)); + + livelist_entry_t node; + node.le_bp = *bp; + livelist_entry_t *found = avl_find(avl, &node, NULL); if (bp_freed) { - livelist_entry_t *node = kmem_alloc(sizeof (livelist_entry_t), - KM_SLEEP); - blkptr_t *temp_bp = kmem_alloc(sizeof (blkptr_t), KM_SLEEP); - *temp_bp = *bp; - node->le_bp = temp_bp; - avl_add(avl, node); - } else { - livelist_entry_t node; - node.le_bp = bp; - livelist_entry_t *found = avl_find(avl, &node, NULL); - if (found != NULL) { - avl_remove(avl, found); - kmem_free((blkptr_t *)found->le_bp, sizeof (blkptr_t)); - kmem_free(found, sizeof (livelist_entry_t)); + if (found == NULL) { + /* first free entry for this blkptr */ + livelist_entry_t *e = + kmem_alloc(sizeof (livelist_entry_t), KM_SLEEP); + e->le_bp = *bp; + e->le_refcnt = 1; + avl_add(avl, e); } else { + /* dedup block free */ + ASSERT(BP_GET_DEDUP(bp)); + ASSERT3U(BP_GET_CHECKSUM(bp), ==, + BP_GET_CHECKSUM(&found->le_bp)); + ASSERT3U(found->le_refcnt + 1, >, found->le_refcnt); + found->le_refcnt++; + } + } else { + if (found == NULL) { + /* block is currently marked as allocated */ bplist_append(to_free, bp); + } else { + /* alloc matches a free entry */ + ASSERT3U(found->le_refcnt, !=, 0); + found->le_refcnt--; + if (found->le_refcnt == 0) { + /* all tracked free pairs have been matched */ + avl_remove(avl, found); + kmem_free(found, sizeof (livelist_entry_t)); + } else { + /* + * This is definitely a deduped blkptr so + * let's validate it. + */ + ASSERT(BP_GET_DEDUP(bp)); + ASSERT3U(BP_GET_CHECKSUM(bp), ==, + BP_GET_CHECKSUM(&found->le_bp)); + } } } return (0); @@ -999,6 +1029,7 @@ dsl_process_sub_livelist(bpobj_t *bpobj, bplist_t *to_free, zthr_t *t, }; int err = bpobj_iterate_nofree(bpobj, dsl_livelist_iterate, &arg, size); + VERIFY0(avl_numnodes(&avl)); avl_destroy(&avl); return (err); } diff --git a/sys/contrib/openzfs/module/zfs/dsl_scan.c b/sys/contrib/openzfs/module/zfs/dsl_scan.c index a54cd6ca800..62ee9bb9ab6 100644 --- a/sys/contrib/openzfs/module/zfs/dsl_scan.c +++ b/sys/contrib/openzfs/module/zfs/dsl_scan.c @@ -126,7 +126,7 @@ static boolean_t scan_ds_queue_contains(dsl_scan_t *scn, uint64_t dsobj, static void scan_ds_queue_insert(dsl_scan_t *scn, uint64_t dsobj, uint64_t txg); static void scan_ds_queue_remove(dsl_scan_t *scn, uint64_t dsobj); static void scan_ds_queue_sync(dsl_scan_t *scn, dmu_tx_t *tx); -static uint64_t dsl_scan_count_leaves(vdev_t *vd); +static uint64_t dsl_scan_count_data_disks(vdev_t *vd); extern int zfs_vdev_async_write_active_min_dirty_percent; @@ -451,7 +451,7 @@ dsl_scan_init(dsl_pool_t *dp, uint64_t txg) * phase are done per top-level vdev and are handled separately. */ scn->scn_maxinflight_bytes = MAX(zfs_scan_vdev_limit * - dsl_scan_count_leaves(spa->spa_root_vdev), 1ULL << 20); + dsl_scan_count_data_disks(spa->spa_root_vdev), 1ULL << 20); avl_create(&scn->scn_queue, scan_ds_queue_compare, sizeof (scan_ds_t), offsetof(scan_ds_t, sds_node)); @@ -701,7 +701,7 @@ dsl_scan_sync_state(dsl_scan_t *scn, dmu_tx_t *tx, state_sync_type_t sync_type) } /* ARGSUSED */ -static int +int dsl_scan_setup_check(void *arg, dmu_tx_t *tx) { dsl_scan_t *scn = dmu_tx_pool(tx)->dp_scan; @@ -2759,22 +2759,16 @@ dsl_scan_visit(dsl_scan_t *scn, dmu_tx_t *tx) } static uint64_t -dsl_scan_count_leaves(vdev_t *vd) +dsl_scan_count_data_disks(vdev_t *rvd) { uint64_t i, leaves = 0; - /* we only count leaves that belong to the main pool and are readable */ - if (vd->vdev_islog || vd->vdev_isspare || - vd->vdev_isl2cache || !vdev_readable(vd)) - return (0); - - if (vd->vdev_ops->vdev_op_leaf) - return (1); - - for (i = 0; i < vd->vdev_children; i++) { - leaves += dsl_scan_count_leaves(vd->vdev_child[i]); + for (i = 0; i < rvd->vdev_children; i++) { + vdev_t *vd = rvd->vdev_child[i]; + if (vd->vdev_islog || vd->vdev_isspare || vd->vdev_isl2cache) + continue; + leaves += vdev_get_ndisks(vd) - vdev_get_nparity(vd); } - return (leaves); } @@ -3017,8 +3011,6 @@ scan_io_queues_run_one(void *arg) range_seg_t *rs = NULL; scan_io_t *sio = NULL; list_t sio_list; - uint64_t bytes_per_leaf = zfs_scan_vdev_limit; - uint64_t nr_leaves = dsl_scan_count_leaves(queue->q_vd); ASSERT(queue->q_scn->scn_is_sorted); @@ -3026,9 +3018,9 @@ scan_io_queues_run_one(void *arg) offsetof(scan_io_t, sio_nodes.sio_list_node)); mutex_enter(q_lock); - /* calculate maximum in-flight bytes for this txg (min 1MB) */ - queue->q_maxinflight_bytes = - MAX(nr_leaves * bytes_per_leaf, 1ULL << 20); + /* Calculate maximum in-flight bytes for this vdev. */ + queue->q_maxinflight_bytes = MAX(1, zfs_scan_vdev_limit * + (vdev_get_ndisks(queue->q_vd) - vdev_get_nparity(queue->q_vd))); /* reset per-queue scan statistics for this txg */ queue->q_total_seg_size_this_txg = 0; @@ -3665,16 +3657,14 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx) /* Need to scan metadata for more blocks to scrub */ dsl_scan_phys_t *scnp = &scn->scn_phys; taskqid_t prefetch_tqid; - uint64_t bytes_per_leaf = zfs_scan_vdev_limit; - uint64_t nr_leaves = dsl_scan_count_leaves(spa->spa_root_vdev); /* * Recalculate the max number of in-flight bytes for pool-wide * scanning operations (minimum 1MB). Limits for the issuing * phase are done per top-level vdev and are handled separately. */ - scn->scn_maxinflight_bytes = - MAX(nr_leaves * bytes_per_leaf, 1ULL << 20); + scn->scn_maxinflight_bytes = MAX(zfs_scan_vdev_limit * + dsl_scan_count_data_disks(spa->spa_root_vdev), 1ULL << 20); if (scnp->scn_ddt_bookmark.ddb_class <= scnp->scn_ddt_class_max) { @@ -4050,9 +4040,8 @@ scan_exec_io(dsl_pool_t *dp, const blkptr_t *bp, int zio_flags, size_t size = BP_GET_PSIZE(bp); abd_t *data = abd_alloc_for_io(size, B_FALSE); - ASSERT3U(scn->scn_maxinflight_bytes, >, 0); - if (queue == NULL) { + ASSERT3U(scn->scn_maxinflight_bytes, >, 0); mutex_enter(&spa->spa_scrub_lock); while (spa->spa_scrub_inflight >= scn->scn_maxinflight_bytes) cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock); @@ -4061,6 +4050,7 @@ scan_exec_io(dsl_pool_t *dp, const blkptr_t *bp, int zio_flags, } else { kmutex_t *q_lock = &queue->q_vd->vdev_scan_io_queue_lock; + ASSERT3U(queue->q_maxinflight_bytes, >, 0); mutex_enter(q_lock); while (queue->q_inflight_bytes >= queue->q_maxinflight_bytes) cv_wait(&queue->q_zio_cv, q_lock); diff --git a/sys/contrib/openzfs/module/zfs/fm.c b/sys/contrib/openzfs/module/zfs/fm.c index 3070cab1e49..dff7d8ece4b 100644 --- a/sys/contrib/openzfs/module/zfs/fm.c +++ b/sys/contrib/openzfs/module/zfs/fm.c @@ -66,12 +66,9 @@ #ifdef _KERNEL #include #include -#include #include -int zfs_zevent_len_max = 0; -int zfs_zevent_cols = 80; -int zfs_zevent_console = 0; +int zfs_zevent_len_max = 512; static int zevent_len_cur = 0; static int zevent_waiters = 0; @@ -118,307 +115,6 @@ kstat_t *fm_ksp; #ifdef _KERNEL -/* - * Formatting utility function for fm_nvprintr. We attempt to wrap chunks of - * output so they aren't split across console lines, and return the end column. - */ -/*PRINTFLIKE4*/ -static int -fm_printf(int depth, int c, int cols, const char *format, ...) -{ - va_list ap; - int width; - char c1; - - va_start(ap, format); - width = vsnprintf(&c1, sizeof (c1), format, ap); - va_end(ap); - - if (c + width >= cols) { - console_printf("\n"); - c = 0; - if (format[0] != ' ' && depth > 0) { - console_printf(" "); - c++; - } - } - - va_start(ap, format); - console_vprintf(format, ap); - va_end(ap); - - return ((c + width) % cols); -} - -/* - * Recursively print an nvlist in the specified column width and return the - * column we end up in. This function is called recursively by fm_nvprint(), - * below. We generically format the entire nvpair using hexadecimal - * integers and strings, and elide any integer arrays. Arrays are basically - * used for cache dumps right now, so we suppress them so as not to overwhelm - * the amount of console output we produce at panic time. This can be further - * enhanced as FMA technology grows based upon the needs of consumers. All - * FMA telemetry is logged using the dump device transport, so the console - * output serves only as a fallback in case this procedure is unsuccessful. - */ -static int -fm_nvprintr(nvlist_t *nvl, int d, int c, int cols) -{ - nvpair_t *nvp; - - for (nvp = nvlist_next_nvpair(nvl, NULL); - nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) { - - data_type_t type = nvpair_type(nvp); - const char *name = nvpair_name(nvp); - - boolean_t b; - uint8_t i8; - uint16_t i16; - uint32_t i32; - uint64_t i64; - char *str; - nvlist_t *cnv; - - if (strcmp(name, FM_CLASS) == 0) - continue; /* already printed by caller */ - - c = fm_printf(d, c, cols, " %s=", name); - - switch (type) { - case DATA_TYPE_BOOLEAN: - c = fm_printf(d + 1, c, cols, " 1"); - break; - - case DATA_TYPE_BOOLEAN_VALUE: - (void) nvpair_value_boolean_value(nvp, &b); - c = fm_printf(d + 1, c, cols, b ? "1" : "0"); - break; - - case DATA_TYPE_BYTE: - (void) nvpair_value_byte(nvp, &i8); - c = fm_printf(d + 1, c, cols, "0x%x", i8); - break; - - case DATA_TYPE_INT8: - (void) nvpair_value_int8(nvp, (void *)&i8); - c = fm_printf(d + 1, c, cols, "0x%x", i8); - break; - - case DATA_TYPE_UINT8: - (void) nvpair_value_uint8(nvp, &i8); - c = fm_printf(d + 1, c, cols, "0x%x", i8); - break; - - case DATA_TYPE_INT16: - (void) nvpair_value_int16(nvp, (void *)&i16); - c = fm_printf(d + 1, c, cols, "0x%x", i16); - break; - - case DATA_TYPE_UINT16: - (void) nvpair_value_uint16(nvp, &i16); - c = fm_printf(d + 1, c, cols, "0x%x", i16); - break; - - case DATA_TYPE_INT32: - (void) nvpair_value_int32(nvp, (void *)&i32); - c = fm_printf(d + 1, c, cols, "0x%x", i32); - break; - - case DATA_TYPE_UINT32: - (void) nvpair_value_uint32(nvp, &i32); - c = fm_printf(d + 1, c, cols, "0x%x", i32); - break; - - case DATA_TYPE_INT64: - (void) nvpair_value_int64(nvp, (void *)&i64); - c = fm_printf(d + 1, c, cols, "0x%llx", - (u_longlong_t)i64); - break; - - case DATA_TYPE_UINT64: - (void) nvpair_value_uint64(nvp, &i64); - c = fm_printf(d + 1, c, cols, "0x%llx", - (u_longlong_t)i64); - break; - - case DATA_TYPE_HRTIME: - (void) nvpair_value_hrtime(nvp, (void *)&i64); - c = fm_printf(d + 1, c, cols, "0x%llx", - (u_longlong_t)i64); - break; - - case DATA_TYPE_STRING: - (void) nvpair_value_string(nvp, &str); - c = fm_printf(d + 1, c, cols, "\"%s\"", - str ? str : ""); - break; - - case DATA_TYPE_NVLIST: - c = fm_printf(d + 1, c, cols, "["); - (void) nvpair_value_nvlist(nvp, &cnv); - c = fm_nvprintr(cnv, d + 1, c, cols); - c = fm_printf(d + 1, c, cols, " ]"); - break; - - case DATA_TYPE_NVLIST_ARRAY: { - nvlist_t **val; - uint_t i, nelem; - - c = fm_printf(d + 1, c, cols, "["); - (void) nvpair_value_nvlist_array(nvp, &val, &nelem); - for (i = 0; i < nelem; i++) { - c = fm_nvprintr(val[i], d + 1, c, cols); - } - c = fm_printf(d + 1, c, cols, " ]"); - } - break; - - case DATA_TYPE_INT8_ARRAY: { - int8_t *val; - uint_t i, nelem; - - c = fm_printf(d + 1, c, cols, "[ "); - (void) nvpair_value_int8_array(nvp, &val, &nelem); - for (i = 0; i < nelem; i++) - c = fm_printf(d + 1, c, cols, "0x%llx ", - (u_longlong_t)val[i]); - - c = fm_printf(d + 1, c, cols, "]"); - break; - } - - case DATA_TYPE_UINT8_ARRAY: { - uint8_t *val; - uint_t i, nelem; - - c = fm_printf(d + 1, c, cols, "[ "); - (void) nvpair_value_uint8_array(nvp, &val, &nelem); - for (i = 0; i < nelem; i++) - c = fm_printf(d + 1, c, cols, "0x%llx ", - (u_longlong_t)val[i]); - - c = fm_printf(d + 1, c, cols, "]"); - break; - } - - case DATA_TYPE_INT16_ARRAY: { - int16_t *val; - uint_t i, nelem; - - c = fm_printf(d + 1, c, cols, "[ "); - (void) nvpair_value_int16_array(nvp, &val, &nelem); - for (i = 0; i < nelem; i++) - c = fm_printf(d + 1, c, cols, "0x%llx ", - (u_longlong_t)val[i]); - - c = fm_printf(d + 1, c, cols, "]"); - break; - } - - case DATA_TYPE_UINT16_ARRAY: { - uint16_t *val; - uint_t i, nelem; - - c = fm_printf(d + 1, c, cols, "[ "); - (void) nvpair_value_uint16_array(nvp, &val, &nelem); - for (i = 0; i < nelem; i++) - c = fm_printf(d + 1, c, cols, "0x%llx ", - (u_longlong_t)val[i]); - - c = fm_printf(d + 1, c, cols, "]"); - break; - } - - case DATA_TYPE_INT32_ARRAY: { - int32_t *val; - uint_t i, nelem; - - c = fm_printf(d + 1, c, cols, "[ "); - (void) nvpair_value_int32_array(nvp, &val, &nelem); - for (i = 0; i < nelem; i++) - c = fm_printf(d + 1, c, cols, "0x%llx ", - (u_longlong_t)val[i]); - - c = fm_printf(d + 1, c, cols, "]"); - break; - } - - case DATA_TYPE_UINT32_ARRAY: { - uint32_t *val; - uint_t i, nelem; - - c = fm_printf(d + 1, c, cols, "[ "); - (void) nvpair_value_uint32_array(nvp, &val, &nelem); - for (i = 0; i < nelem; i++) - c = fm_printf(d + 1, c, cols, "0x%llx ", - (u_longlong_t)val[i]); - - c = fm_printf(d + 1, c, cols, "]"); - break; - } - - case DATA_TYPE_INT64_ARRAY: { - int64_t *val; - uint_t i, nelem; - - c = fm_printf(d + 1, c, cols, "[ "); - (void) nvpair_value_int64_array(nvp, &val, &nelem); - for (i = 0; i < nelem; i++) - c = fm_printf(d + 1, c, cols, "0x%llx ", - (u_longlong_t)val[i]); - - c = fm_printf(d + 1, c, cols, "]"); - break; - } - - case DATA_TYPE_UINT64_ARRAY: { - uint64_t *val; - uint_t i, nelem; - - c = fm_printf(d + 1, c, cols, "[ "); - (void) nvpair_value_uint64_array(nvp, &val, &nelem); - for (i = 0; i < nelem; i++) - c = fm_printf(d + 1, c, cols, "0x%llx ", - (u_longlong_t)val[i]); - - c = fm_printf(d + 1, c, cols, "]"); - break; - } - - case DATA_TYPE_STRING_ARRAY: - case DATA_TYPE_BOOLEAN_ARRAY: - case DATA_TYPE_BYTE_ARRAY: - c = fm_printf(d + 1, c, cols, "[...]"); - break; - - case DATA_TYPE_UNKNOWN: - case DATA_TYPE_DONTCARE: - c = fm_printf(d + 1, c, cols, ""); - break; - } - } - - return (c); -} - -void -fm_nvprint(nvlist_t *nvl) -{ - char *class; - int c = 0; - - console_printf("\n"); - - if (nvlist_lookup_string(nvl, FM_CLASS, &class) == 0) - c = fm_printf(0, c, zfs_zevent_cols, "%s", class); - - if (fm_nvprintr(nvl, 0, c, zfs_zevent_cols) != 0) - console_printf("\n"); - - console_printf("\n"); -} - static zevent_t * zfs_zevent_alloc(void) { @@ -542,9 +238,6 @@ zfs_zevent_post(nvlist_t *nvl, nvlist_t *detector, zevent_cb_t *cb) goto out; } - if (zfs_zevent_console) - fm_nvprint(nvl); - ev = zfs_zevent_alloc(); if (ev == NULL) { atomic_inc_64(&erpt_kstat_data.erpt_dropped.value.ui64); @@ -657,8 +350,7 @@ zfs_zevent_next(zfs_zevent_t *ze, nvlist_t **event, uint64_t *event_size, #ifdef _KERNEL /* Include events dropped due to rate limiting */ - *dropped += ratelimit_dropped; - ratelimit_dropped = 0; + *dropped += atomic_swap_64(&ratelimit_dropped, 0); #endif ze->ze_dropped = 0; out: @@ -1621,9 +1313,6 @@ fm_init(void) zevent_len_cur = 0; zevent_flags = 0; - if (zfs_zevent_len_max == 0) - zfs_zevent_len_max = ERPT_MAX_ERRS * MAX(max_ncpus, 4); - /* Initialize zevent allocation and generation kstats */ fm_ksp = kstat_create("zfs", 0, "fm", "misc", KSTAT_TYPE_NAMED, sizeof (struct erpt_kstat) / sizeof (kstat_named_t), @@ -1677,9 +1366,3 @@ fm_fini(void) ZFS_MODULE_PARAM(zfs_zevent, zfs_zevent_, len_max, INT, ZMOD_RW, "Max event queue length"); - -ZFS_MODULE_PARAM(zfs_zevent, zfs_zevent_, cols, INT, ZMOD_RW, - "Max event column width"); - -ZFS_MODULE_PARAM(zfs_zevent, zfs_zevent_, console, INT, ZMOD_RW, - "Log events to the console"); diff --git a/sys/contrib/openzfs/module/zfs/spa.c b/sys/contrib/openzfs/module/zfs/spa.c index 5170c9ca226..26995575ada 100644 --- a/sys/contrib/openzfs/module/zfs/spa.c +++ b/sys/contrib/openzfs/module/zfs/spa.c @@ -108,6 +108,7 @@ int zfs_ccw_retry_interval = 300; typedef enum zti_modes { ZTI_MODE_FIXED, /* value is # of threads (min 1) */ ZTI_MODE_BATCH, /* cpu-intensive; value is ignored */ + ZTI_MODE_SCALE, /* Taskqs scale with CPUs. */ ZTI_MODE_NULL, /* don't create a taskq */ ZTI_NMODES } zti_modes_t; @@ -115,6 +116,7 @@ typedef enum zti_modes { #define ZTI_P(n, q) { ZTI_MODE_FIXED, (n), (q) } #define ZTI_PCT(n) { ZTI_MODE_ONLINE_PERCENT, (n), 1 } #define ZTI_BATCH { ZTI_MODE_BATCH, 0, 1 } +#define ZTI_SCALE { ZTI_MODE_SCALE, 0, 1 } #define ZTI_NULL { ZTI_MODE_NULL, 0, 0 } #define ZTI_N(n) ZTI_P(n, 1) @@ -141,7 +143,8 @@ static const char *const zio_taskq_types[ZIO_TASKQ_TYPES] = { * point of lock contention. The ZTI_P(#, #) macro indicates that we need an * additional degree of parallelism specified by the number of threads per- * taskq and the number of taskqs; when dispatching an event in this case, the - * particular taskq is chosen at random. + * particular taskq is chosen at random. ZTI_SCALE is similar to ZTI_BATCH, + * but with number of taskqs also scaling with number of CPUs. * * The different taskq priorities are to handle the different contexts (issue * and interrupt) and then to reserve threads for ZIO_PRIORITY_NOW I/Os that @@ -150,9 +153,9 @@ static const char *const zio_taskq_types[ZIO_TASKQ_TYPES] = { const zio_taskq_info_t zio_taskqs[ZIO_TYPES][ZIO_TASKQ_TYPES] = { /* ISSUE ISSUE_HIGH INTR INTR_HIGH */ { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* NULL */ - { ZTI_N(8), ZTI_NULL, ZTI_P(12, 8), ZTI_NULL }, /* READ */ - { ZTI_BATCH, ZTI_N(5), ZTI_P(12, 8), ZTI_N(5) }, /* WRITE */ - { ZTI_P(12, 8), ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* FREE */ + { ZTI_N(8), ZTI_NULL, ZTI_SCALE, ZTI_NULL }, /* READ */ + { ZTI_BATCH, ZTI_N(5), ZTI_SCALE, ZTI_N(5) }, /* WRITE */ + { ZTI_SCALE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* FREE */ { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* CLAIM */ { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* IOCTL */ { ZTI_N(4), ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* TRIM */ @@ -164,7 +167,8 @@ static boolean_t spa_has_active_shared_spare(spa_t *spa); static int spa_load_impl(spa_t *spa, spa_import_type_t type, char **ereport); static void spa_vdev_resilver_done(spa_t *spa); -uint_t zio_taskq_batch_pct = 75; /* 1 thread per cpu in pset */ +uint_t zio_taskq_batch_pct = 80; /* 1 thread per cpu in pset */ +uint_t zio_taskq_batch_tpq; /* threads per taskq */ boolean_t zio_taskq_sysdc = B_TRUE; /* use SDC scheduling class */ uint_t zio_taskq_basedc = 80; /* base duty cycle */ @@ -957,25 +961,12 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q) uint_t value = ztip->zti_value; uint_t count = ztip->zti_count; spa_taskqs_t *tqs = &spa->spa_zio_taskq[t][q]; - uint_t flags = 0; + uint_t cpus, flags = TASKQ_DYNAMIC; boolean_t batch = B_FALSE; - if (mode == ZTI_MODE_NULL) { - tqs->stqs_count = 0; - tqs->stqs_taskq = NULL; - return; - } - - ASSERT3U(count, >, 0); - - tqs->stqs_count = count; - tqs->stqs_taskq = kmem_alloc(count * sizeof (taskq_t *), KM_SLEEP); - switch (mode) { case ZTI_MODE_FIXED: - ASSERT3U(value, >=, 1); - value = MAX(value, 1); - flags |= TASKQ_DYNAMIC; + ASSERT3U(value, >, 0); break; case ZTI_MODE_BATCH: @@ -984,6 +975,48 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q) value = MIN(zio_taskq_batch_pct, 100); break; + case ZTI_MODE_SCALE: + flags |= TASKQ_THREADS_CPU_PCT; + /* + * We want more taskqs to reduce lock contention, but we want + * less for better request ordering and CPU utilization. + */ + cpus = MAX(1, boot_ncpus * zio_taskq_batch_pct / 100); + if (zio_taskq_batch_tpq > 0) { + count = MAX(1, (cpus + zio_taskq_batch_tpq / 2) / + zio_taskq_batch_tpq); + } else { + /* + * Prefer 6 threads per taskq, but no more taskqs + * than threads in them on large systems. For 80%: + * + * taskq taskq total + * cpus taskqs percent threads threads + * ------- ------- ------- ------- ------- + * 1 1 80% 1 1 + * 2 1 80% 1 1 + * 4 1 80% 3 3 + * 8 2 40% 3 6 + * 16 3 27% 4 12 + * 32 5 16% 5 25 + * 64 7 11% 7 49 + * 128 10 8% 10 100 + * 256 14 6% 15 210 + */ + count = 1 + cpus / 6; + while (count * count > cpus) + count--; + } + /* Limit each taskq within 100% to not trigger assertion. */ + count = MAX(count, (zio_taskq_batch_pct + 99) / 100); + value = (zio_taskq_batch_pct + count / 2) / count; + break; + + case ZTI_MODE_NULL: + tqs->stqs_count = 0; + tqs->stqs_taskq = NULL; + return; + default: panic("unrecognized mode for %s_%s taskq (%u:%u) in " "spa_activate()", @@ -991,12 +1024,20 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q) break; } + ASSERT3U(count, >, 0); + tqs->stqs_count = count; + tqs->stqs_taskq = kmem_alloc(count * sizeof (taskq_t *), KM_SLEEP); + for (uint_t i = 0; i < count; i++) { taskq_t *tq; char name[32]; - (void) snprintf(name, sizeof (name), "%s_%s", - zio_type_name[t], zio_taskq_types[q]); + if (count > 1) + (void) snprintf(name, sizeof (name), "%s_%s_%u", + zio_type_name[t], zio_taskq_types[q], i); + else + (void) snprintf(name, sizeof (name), "%s_%s", + zio_type_name[t], zio_taskq_types[q]); if (zio_taskq_sysdc && spa->spa_proc != &p0) { if (batch) @@ -6496,7 +6537,7 @@ spa_vdev_add(spa_t *spa, nvlist_t *nvroot) /* * The virtual dRAID spares must be added after vdev tree is created - * and the vdev guids are generated. The guid of their assoicated + * and the vdev guids are generated. The guid of their associated * dRAID is stored in the config and used when opening the spare. */ if ((error = vdev_draid_spare_create(nvroot, vd, &ndraid, @@ -9848,7 +9889,7 @@ EXPORT_SYMBOL(spa_event_notify); /* BEGIN CSTYLED */ ZFS_MODULE_PARAM(zfs_spa, spa_, load_verify_shift, INT, ZMOD_RW, - "log2(fraction of arc that can be used by inflight I/Os when " + "log2 fraction of arc that can be used by inflight I/Os when " "verifying pool during import"); ZFS_MODULE_PARAM(zfs_spa, spa_, load_verify_metadata, INT, ZMOD_RW, @@ -9863,6 +9904,9 @@ ZFS_MODULE_PARAM(zfs_spa, spa_, load_print_vdev_tree, INT, ZMOD_RW, ZFS_MODULE_PARAM(zfs_zio, zio_, taskq_batch_pct, UINT, ZMOD_RD, "Percentage of CPUs to run an IO worker thread"); +ZFS_MODULE_PARAM(zfs_zio, zio_, taskq_batch_tpq, UINT, ZMOD_RD, + "Number of threads per IO worker taskqueue"); + ZFS_MODULE_PARAM(zfs, zfs_, max_missing_tvds, ULONG, ZMOD_RW, "Allow importing pool with up to this number of missing top-level " "vdevs (in read-only mode)"); diff --git a/sys/contrib/openzfs/module/zfs/spa_log_spacemap.c b/sys/contrib/openzfs/module/zfs/spa_log_spacemap.c index 5c55d32ec06..f4c2910ad7f 100644 --- a/sys/contrib/openzfs/module/zfs/spa_log_spacemap.c +++ b/sys/contrib/openzfs/module/zfs/spa_log_spacemap.c @@ -1290,7 +1290,7 @@ ZFS_MODULE_PARAM(zfs, zfs_, unflushed_max_mem_amt, ULONG, ZMOD_RW, ZFS_MODULE_PARAM(zfs, zfs_, unflushed_max_mem_ppm, ULONG, ZMOD_RW, "Percentage of the overall system memory that ZFS allows to be " "used for unflushed changes (value is calculated over 1000000 for " - "finer granularity"); + "finer granularity)"); ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_max, ULONG, ZMOD_RW, "Hard limit (upper-bound) in the size of the space map log " diff --git a/sys/contrib/openzfs/module/zfs/vdev.c b/sys/contrib/openzfs/module/zfs/vdev.c index c536a1c6cda..5e14d71f194 100644 --- a/sys/contrib/openzfs/module/zfs/vdev.c +++ b/sys/contrib/openzfs/module/zfs/vdev.c @@ -28,6 +28,7 @@ * Copyright 2017 Joyent, Inc. * Copyright (c) 2017, Intel Corporation. * Copyright (c) 2019, Datto Inc. All rights reserved. + * Copyright [2021] Hewlett Packard Enterprise Development LP */ #include @@ -625,6 +626,8 @@ vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops) */ zfs_ratelimit_init(&vd->vdev_delay_rl, &zfs_slow_io_events_per_second, 1); + zfs_ratelimit_init(&vd->vdev_deadman_rl, &zfs_slow_io_events_per_second, + 1); zfs_ratelimit_init(&vd->vdev_checksum_rl, &zfs_checksum_events_per_second, 1); @@ -1106,6 +1109,7 @@ vdev_free(vdev_t *vd) cv_destroy(&vd->vdev_rebuild_cv); zfs_ratelimit_fini(&vd->vdev_delay_rl); + zfs_ratelimit_fini(&vd->vdev_deadman_rl); zfs_ratelimit_fini(&vd->vdev_checksum_rl); if (vd == spa->spa_root_vdev) @@ -1372,7 +1376,7 @@ vdev_metaslab_group_create(vdev_t *vd) /* * The spa ashift min/max only apply for the normal metaslab - * class. Class destination is late binding so ashift boundry + * class. Class destination is late binding so ashift boundary * setting had to wait until now. */ if (vd->vdev_top == vd && vd->vdev_ashift != 0 && @@ -2046,7 +2050,7 @@ vdev_open(vdev_t *vd) vd->vdev_max_asize = max_asize; /* - * If the vdev_ashift was not overriden at creation time, + * If the vdev_ashift was not overridden at creation time, * then set it the logical ashift and optimize the ashift. */ if (vd->vdev_ashift == 0) { @@ -2116,7 +2120,7 @@ vdev_open(vdev_t *vd) } /* - * Track the the minimum allocation size. + * Track the minimum allocation size. */ if (vd->vdev_top == vd && vd->vdev_ashift != 0 && vd->vdev_islog == 0 && vd->vdev_aux == NULL) { @@ -2219,7 +2223,7 @@ vdev_validate(vdev_t *vd) txg = spa_last_synced_txg(spa); if ((label = vdev_label_read_config(vd, txg)) == NULL) { - vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN, + vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN, VDEV_AUX_BAD_LABEL); vdev_dbgmsg(vd, "vdev_validate: failed reading config for " "txg %llu", (u_longlong_t)txg); @@ -4570,7 +4574,7 @@ vdev_stat_update(zio_t *zio, uint64_t psize) /* * Solely for the purposes of 'zpool iostat -lqrw' - * reporting use the priority to catagorize the IO. + * reporting use the priority to categorize the IO. * Only the following are reported to user space: * * ZIO_PRIORITY_SYNC_READ, diff --git a/sys/contrib/openzfs/module/zfs/vdev_draid.c b/sys/contrib/openzfs/module/zfs/vdev_draid.c index fb2143e9468..20b1457f0ce 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_draid.c +++ b/sys/contrib/openzfs/module/zfs/vdev_draid.c @@ -812,7 +812,12 @@ vdev_draid_map_alloc_empty(zio_t *zio, raidz_row_t *rr) /* this is a "big column", nothing to add */ ASSERT3P(rc->rc_abd, !=, NULL); } else { - /* short data column, add a skip sector */ + /* + * short data column, add a skip sector and clear + * rc_tried to force the entire column to be re-read + * thereby including the missing skip sector data + * which is needed for reconstruction. + */ ASSERT3U(rc->rc_size + skip_size, ==, parity_size); ASSERT3U(rr->rr_nempty, !=, 0); ASSERT3P(rc->rc_abd, !=, NULL); @@ -823,6 +828,7 @@ vdev_draid_map_alloc_empty(zio_t *zio, raidz_row_t *rr) abd_gang_add(rc->rc_abd, abd_get_offset_size( rr->rr_abd_empty, skip_off, skip_size), B_TRUE); skip_off += skip_size; + rc->rc_tried = 0; } /* @@ -1003,7 +1009,8 @@ vdev_draid_map_alloc_row(zio_t *zio, raidz_row_t **rrp, uint64_t io_offset, rc->rc_error = 0; rc->rc_tried = 0; rc->rc_skipped = 0; - rc->rc_repair = 0; + rc->rc_force_repair = 0; + rc->rc_allow_repair = 1; rc->rc_need_orig_restore = B_FALSE; if (q == 0 && i >= bc) @@ -1884,6 +1891,36 @@ vdev_draid_io_start_read(zio_t *zio, raidz_row_t *rr) if (zio->io_flags & ZIO_FLAG_RESILVER) { vdev_t *svd; + /* + * Sequential rebuilds need to always consider the data + * on the child being rebuilt to be stale. This is + * important when all columns are available to aid + * known reconstruction in identifing which columns + * contain incorrect data. + * + * Furthermore, all repairs need to be constrained to + * the devices being rebuilt because without a checksum + * we cannot verify the data is actually correct and + * performing an incorrect repair could result in + * locking in damage and making the data unrecoverable. + */ + if (zio->io_priority == ZIO_PRIORITY_REBUILD) { + if (vdev_draid_rebuilding(cvd)) { + if (c >= rr->rr_firstdatacol) + rr->rr_missingdata++; + else + rr->rr_missingparity++; + rc->rc_error = SET_ERROR(ESTALE); + rc->rc_skipped = 1; + rc->rc_allow_repair = 1; + continue; + } else { + rc->rc_allow_repair = 0; + } + } else { + rc->rc_allow_repair = 1; + } + /* * If this child is a distributed spare then the * offset might reside on the vdev being replaced. @@ -1897,7 +1934,10 @@ vdev_draid_io_start_read(zio_t *zio, raidz_row_t *rr) rc->rc_offset); if (svd && (svd->vdev_ops == &vdev_spare_ops || svd->vdev_ops == &vdev_replacing_ops)) { - rc->rc_repair = 1; + rc->rc_force_repair = 1; + + if (vdev_draid_rebuilding(svd)) + rc->rc_allow_repair = 1; } } @@ -1908,7 +1948,8 @@ vdev_draid_io_start_read(zio_t *zio, raidz_row_t *rr) if ((cvd->vdev_ops == &vdev_spare_ops || cvd->vdev_ops == &vdev_replacing_ops) && vdev_draid_rebuilding(cvd)) { - rc->rc_repair = 1; + rc->rc_force_repair = 1; + rc->rc_allow_repair = 1; } } } diff --git a/sys/contrib/openzfs/module/zfs/vdev_indirect.c b/sys/contrib/openzfs/module/zfs/vdev_indirect.c index bafb2c767b2..e539e9aa2d7 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_indirect.c +++ b/sys/contrib/openzfs/module/zfs/vdev_indirect.c @@ -181,7 +181,7 @@ int zfs_condense_indirect_vdevs_enable = B_TRUE; * condenses. Higher values will condense less often (causing less * i/o); lower values will reduce the mapping size more quickly. */ -int zfs_indirect_condense_obsolete_pct = 25; +int zfs_condense_indirect_obsolete_pct = 25; /* * Condense if the obsolete space map takes up more than this amount of @@ -445,7 +445,7 @@ vdev_indirect_should_condense(vdev_t *vd) * by the mapping. */ if (bytes_obsolete * 100 / bytes_mapped >= - zfs_indirect_condense_obsolete_pct && + zfs_condense_indirect_obsolete_pct && mapping_size > zfs_condense_min_mapping_bytes) { zfs_dbgmsg("should condense vdev %llu because obsolete " "spacemap covers %d%% of %lluMB mapping", @@ -1424,11 +1424,6 @@ vdev_indirect_repair(zio_t *zio) { indirect_vsd_t *iv = zio->io_vsd; - enum zio_flag flags = ZIO_FLAG_IO_REPAIR; - - if (!(zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER))) - flags |= ZIO_FLAG_SELF_HEAL; - if (!spa_writeable(zio->io_spa)) return; @@ -1892,6 +1887,9 @@ EXPORT_SYMBOL(vdev_obsolete_sm_object); ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, indirect_vdevs_enable, INT, ZMOD_RW, "Whether to attempt condensing indirect vdev mappings"); +ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, indirect_obsolete_pct, INT, ZMOD_RW, + "Minimum obsolete percent of bytes in the mapping to attempt condensing"); + ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, min_mapping_bytes, ULONG, ZMOD_RW, "Don't bother condensing if the mapping uses less than this amount of " "memory"); diff --git a/sys/contrib/openzfs/module/zfs/vdev_mirror.c b/sys/contrib/openzfs/module/zfs/vdev_mirror.c index f360a18c004..106678a8708 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_mirror.c +++ b/sys/contrib/openzfs/module/zfs/vdev_mirror.c @@ -649,6 +649,15 @@ vdev_mirror_io_start(zio_t *zio) */ for (c = 0; c < mm->mm_children; c++) { mc = &mm->mm_child[c]; + + /* Don't issue ZIOs to offline children */ + if (!vdev_mirror_child_readable(mc)) { + mc->mc_error = SET_ERROR(ENXIO); + mc->mc_tried = 1; + mc->mc_skipped = 1; + continue; + } + zio_nowait(zio_vdev_child_io(zio, zio->io_bp, mc->mc_vd, mc->mc_offset, abd_alloc_sametype(zio->io_abd, diff --git a/sys/contrib/openzfs/module/zfs/vdev_raidz.c b/sys/contrib/openzfs/module/zfs/vdev_raidz.c index db753ec16fd..1feebf7089b 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_raidz.c +++ b/sys/contrib/openzfs/module/zfs/vdev_raidz.c @@ -269,7 +269,8 @@ vdev_raidz_map_alloc(zio_t *zio, uint64_t ashift, uint64_t dcols, rc->rc_error = 0; rc->rc_tried = 0; rc->rc_skipped = 0; - rc->rc_repair = 0; + rc->rc_force_repair = 0; + rc->rc_allow_repair = 1; rc->rc_need_orig_restore = B_FALSE; if (c >= acols) @@ -1811,8 +1812,10 @@ vdev_raidz_io_done_verified(zio_t *zio, raidz_row_t *rr) vdev_t *vd = zio->io_vd; vdev_t *cvd = vd->vdev_child[rc->rc_devidx]; - if ((rc->rc_error == 0 || rc->rc_size == 0) && - (rc->rc_repair == 0)) { + if (!rc->rc_allow_repair) { + continue; + } else if (!rc->rc_force_repair && + (rc->rc_error == 0 || rc->rc_size == 0)) { continue; } @@ -1984,7 +1987,7 @@ raidz_reconstruct(zio_t *zio, int *ltgts, int ntgts, int nparity) * 2 4 5 first: increment to 3 * 3 4 5 done * - * This strategy works for dRAID but is less effecient when there are a large + * This strategy works for dRAID but is less efficient when there are a large * number of child vdevs and therefore permutations to check. Furthermore, * since the raidz_map_t rows likely do not overlap reconstruction would be * possible as long as there are no more than nparity data errors per row. diff --git a/sys/contrib/openzfs/module/zfs/vdev_rebuild.c b/sys/contrib/openzfs/module/zfs/vdev_rebuild.c index a77ff99faa9..4d7de0c6c44 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_rebuild.c +++ b/sys/contrib/openzfs/module/zfs/vdev_rebuild.c @@ -81,7 +81,7 @@ * Advantages: * * - Sequential reconstruction is performed in LBA order which may be faster - * than healing reconstruction particularly when using using HDDs (or + * than healing reconstruction particularly when using HDDs (or * especially with SMR devices). Only allocated capacity is resilvered. * * - Sequential reconstruction is not constrained by ZFS block boundaries. @@ -331,9 +331,9 @@ vdev_rebuild_complete_sync(void *arg, dmu_tx_t *tx) * While we're in syncing context take the opportunity to * setup the scrub when there are no more active rebuilds. */ - if (!vdev_rebuild_active(spa->spa_root_vdev) && + pool_scan_func_t func = POOL_SCAN_SCRUB; + if (dsl_scan_setup_check(&func, tx) == 0 && zfs_rebuild_scrub_enabled) { - pool_scan_func_t func = POOL_SCAN_SCRUB; dsl_scan_setup_sync(&func, tx); } diff --git a/sys/contrib/openzfs/module/zfs/vdev_removal.c b/sys/contrib/openzfs/module/zfs/vdev_removal.c index a758fe4fb34..d7c0641c8c2 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_removal.c +++ b/sys/contrib/openzfs/module/zfs/vdev_removal.c @@ -1514,10 +1514,6 @@ spa_vdev_remove_thread(void *arg) * specified by zfs_removal_suspend_progress. We do this * solely from the test suite or during debugging. */ - uint64_t bytes_copied = - spa->spa_removing_phys.sr_copied; - for (int i = 0; i < TXG_SIZE; i++) - bytes_copied += svr->svr_bytes_done[i]; while (zfs_removal_suspend_progress && !svr->svr_thread_exit) delay(hz); diff --git a/sys/contrib/openzfs/module/zfs/zfs_fm.c b/sys/contrib/openzfs/module/zfs/zfs_fm.c index f0f953405cb..60e631567a8 100644 --- a/sys/contrib/openzfs/module/zfs/zfs_fm.c +++ b/sys/contrib/openzfs/module/zfs/zfs_fm.c @@ -395,8 +395,8 @@ zfs_zevent_post_cb(nvlist_t *nvl, nvlist_t *detector) } /* - * We want to rate limit ZIO delay and checksum events so as to not - * flood ZED when a disk is acting up. + * We want to rate limit ZIO delay, deadman, and checksum events so as to not + * flood zevent consumers when a disk is acting up. * * Returns 1 if we're ratelimiting, 0 if not. */ @@ -405,11 +405,13 @@ zfs_is_ratelimiting_event(const char *subclass, vdev_t *vd) { int rc = 0; /* - * __ratelimit() returns 1 if we're *not* ratelimiting and 0 if we + * zfs_ratelimit() returns 1 if we're *not* ratelimiting and 0 if we * are. Invert it to get our return value. */ if (strcmp(subclass, FM_EREPORT_ZFS_DELAY) == 0) { rc = !zfs_ratelimit(&vd->vdev_delay_rl); + } else if (strcmp(subclass, FM_EREPORT_ZFS_DEADMAN) == 0) { + rc = !zfs_ratelimit(&vd->vdev_deadman_rl); } else if (strcmp(subclass, FM_EREPORT_ZFS_CHECKSUM) == 0) { rc = !zfs_ratelimit(&vd->vdev_checksum_rl); } diff --git a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c index 5f291d067be..0d5536cf7cb 100644 --- a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c +++ b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c @@ -233,7 +233,7 @@ unsigned long zfs_max_nvlist_src_size = 0; /* * When logging the output nvlist of an ioctl in the on-disk history, limit - * the logged size to this many bytes. This must be less then DMU_MAX_ACCESS. + * the logged size to this many bytes. This must be less than DMU_MAX_ACCESS. * This applies primarily to zfs_ioc_channel_program(). */ unsigned long zfs_history_output_max = 1024 * 1024; @@ -2521,6 +2521,26 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source, return (err); } +static boolean_t +zfs_is_namespace_prop(zfs_prop_t prop) +{ + switch (prop) { + + case ZFS_PROP_ATIME: + case ZFS_PROP_RELATIME: + case ZFS_PROP_DEVICES: + case ZFS_PROP_EXEC: + case ZFS_PROP_SETUID: + case ZFS_PROP_READONLY: + case ZFS_PROP_XATTR: + case ZFS_PROP_NBMAND: + return (B_TRUE); + + default: + return (B_FALSE); + } +} + /* * This function is best effort. If it fails to set any of the given properties, * it continues to set as many as it can and returns the last error @@ -2540,6 +2560,7 @@ zfs_set_prop_nvlist(const char *dsname, zprop_source_t source, nvlist_t *nvl, int rv = 0; uint64_t intval; const char *strval; + boolean_t should_update_mount_cache = B_FALSE; nvlist_t *genericnvl = fnvlist_alloc(); nvlist_t *retrynvl = fnvlist_alloc(); @@ -2637,6 +2658,9 @@ retry: fnvlist_add_int32(errlist, propname, err); rv = err; } + + if (zfs_is_namespace_prop(prop)) + should_update_mount_cache = B_TRUE; } if (nvl != retrynvl && !nvlist_empty(retrynvl)) { @@ -2685,6 +2709,9 @@ retry: } } } + if (should_update_mount_cache) + zfs_ioctl_update_mount_cache(dsname); + nvlist_free(genericnvl); nvlist_free(retrynvl); @@ -7352,8 +7379,8 @@ zfsdev_getminor(int fd, minor_t *minorp) return (SET_ERROR(EBADF)); } -static void * -zfsdev_get_state_impl(minor_t minor, enum zfsdev_state_type which) +void * +zfsdev_get_state(minor_t minor, enum zfsdev_state_type which) { zfsdev_state_t *zs; @@ -7374,21 +7401,11 @@ zfsdev_get_state_impl(minor_t minor, enum zfsdev_state_type which) return (NULL); } -void * -zfsdev_get_state(minor_t minor, enum zfsdev_state_type which) -{ - void *ptr; - - ptr = zfsdev_get_state_impl(minor, which); - - return (ptr); -} - /* * Find a free minor number. The zfsdev_state_list is expected to * be short since it is only a list of currently open file handles. */ -minor_t +static minor_t zfsdev_minor_alloc(void) { static minor_t last_minor = 0; @@ -7399,7 +7416,7 @@ zfsdev_minor_alloc(void) for (m = last_minor + 1; m != last_minor; m++) { if (m > ZFSDEV_MAX_MINOR) m = 1; - if (zfsdev_get_state_impl(m, ZST_ALL) == NULL) { + if (zfsdev_get_state(m, ZST_ALL) == NULL) { last_minor = m; return (m); } @@ -7408,6 +7425,79 @@ zfsdev_minor_alloc(void) return (0); } +int +zfsdev_state_init(void *priv) +{ + zfsdev_state_t *zs, *zsprev = NULL; + minor_t minor; + boolean_t newzs = B_FALSE; + + ASSERT(MUTEX_HELD(&zfsdev_state_lock)); + + minor = zfsdev_minor_alloc(); + if (minor == 0) + return (SET_ERROR(ENXIO)); + + for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) { + if (zs->zs_minor == -1) + break; + zsprev = zs; + } + + if (!zs) { + zs = kmem_zalloc(sizeof (zfsdev_state_t), KM_SLEEP); + newzs = B_TRUE; + } + + zfsdev_private_set_state(priv, zs); + + zfs_onexit_init((zfs_onexit_t **)&zs->zs_onexit); + zfs_zevent_init((zfs_zevent_t **)&zs->zs_zevent); + + /* + * In order to provide for lock-free concurrent read access + * to the minor list in zfsdev_get_state(), new entries + * must be completely written before linking them into the + * list whereas existing entries are already linked; the last + * operation must be updating zs_minor (from -1 to the new + * value). + */ + if (newzs) { + zs->zs_minor = minor; + membar_producer(); + zsprev->zs_next = zs; + } else { + membar_producer(); + zs->zs_minor = minor; + } + + return (0); +} + +void +zfsdev_state_destroy(void *priv) +{ + zfsdev_state_t *zs = zfsdev_private_get_state(priv); + + ASSERT(zs != NULL); + ASSERT3S(zs->zs_minor, >, 0); + + /* + * The last reference to this zfsdev file descriptor is being dropped. + * We don't have to worry about lookup grabbing this state object, and + * zfsdev_state_init() will not try to reuse this object until it is + * invalidated by setting zs_minor to -1. Invalidation must be done + * last, with a memory barrier to ensure ordering. This lets us avoid + * taking the global zfsdev state lock around destruction. + */ + zfs_onexit_destroy(zs->zs_onexit); + zfs_zevent_destroy(zs->zs_zevent); + zs->zs_onexit = NULL; + zs->zs_zevent = NULL; + membar_producer(); + zs->zs_minor = -1; +} + long zfsdev_ioctl_common(uint_t vecnum, zfs_cmd_t *zc, int flag) { diff --git a/sys/contrib/openzfs/module/zfs/zio.c b/sys/contrib/openzfs/module/zfs/zio.c index 26e40716710..87ccb686185 100644 --- a/sys/contrib/openzfs/module/zfs/zio.c +++ b/sys/contrib/openzfs/module/zfs/zio.c @@ -25,6 +25,7 @@ * Copyright (c) 2017, Intel Corporation. * Copyright (c) 2019, Klara Inc. * Copyright (c) 2019, Allan Jude + * Copyright (c) 2021, Datto, Inc. */ #include @@ -247,13 +248,10 @@ zio_init(void) void zio_fini(void) { - size_t i, j, n; - kmem_cache_t *cache; - - n = SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; + size_t n = SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; #if defined(ZFS_DEBUG) && !defined(_KERNEL) - for (i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { if (zio_buf_cache_allocs[i] != zio_buf_cache_frees[i]) (void) printf("zio_fini: [%d] %llu != %llu\n", (int)((i + 1) << SPA_MINBLOCKSHIFT), @@ -267,11 +265,11 @@ zio_fini(void) * and zio_data_buf_cache. Do a wasteful but trivially correct scan to * sort it out. */ - for (i = 0; i < n; i++) { - cache = zio_buf_cache[i]; + for (size_t i = 0; i < n; i++) { + kmem_cache_t *cache = zio_buf_cache[i]; if (cache == NULL) continue; - for (j = i; j < n; j++) { + for (size_t j = i; j < n; j++) { if (cache == zio_buf_cache[j]) zio_buf_cache[j] = NULL; if (cache == zio_data_buf_cache[j]) @@ -280,22 +278,20 @@ zio_fini(void) kmem_cache_destroy(cache); } - for (i = 0; i < n; i++) { - cache = zio_data_buf_cache[i]; + for (size_t i = 0; i < n; i++) { + kmem_cache_t *cache = zio_data_buf_cache[i]; if (cache == NULL) continue; - for (j = i; j < n; j++) { + for (size_t j = i; j < n; j++) { if (cache == zio_data_buf_cache[j]) zio_data_buf_cache[j] = NULL; } kmem_cache_destroy(cache); } - for (i = 0; i < n; i++) { - if (zio_buf_cache[i] != NULL) - panic("zio_fini: zio_buf_cache[%zd] != NULL", i); - if (zio_data_buf_cache[i] != NULL) - panic("zio_fini: zio_data_buf_cache[%zd] != NULL", i); + for (size_t i = 0; i < n; i++) { + VERIFY3P(zio_buf_cache[i], ==, NULL); + VERIFY3P(zio_data_buf_cache[i], ==, NULL); } kmem_cache_destroy(zio_link_cache); @@ -4570,7 +4566,7 @@ zio_done(zio_t *zio) uint64_t asize = P2ROUNDUP(psize, align); abd_t *adata = zio->io_abd; - if (asize != psize) { + if (adata != NULL && asize != psize) { adata = abd_alloc(asize, B_TRUE); abd_copy(adata, zio->io_abd, psize); abd_zero_off(adata, psize, asize - psize); @@ -4581,7 +4577,7 @@ zio_done(zio_t *zio) zcr->zcr_finish(zcr, adata); zfs_ereport_free_checksum(zcr); - if (asize != psize) + if (adata != NULL && asize != psize) abd_free(adata); } } diff --git a/sys/contrib/openzfs/module/zfs/zvol.c b/sys/contrib/openzfs/module/zfs/zvol.c index b6609363f04..23df0e1541a 100644 --- a/sys/contrib/openzfs/module/zfs/zvol.c +++ b/sys/contrib/openzfs/module/zfs/zvol.c @@ -1383,10 +1383,6 @@ zvol_set_snapdev_impl(char *name, uint64_t snapdev) spl_fstrans_unmark(cookie); } -typedef struct zvol_volmode_cb_arg { - uint64_t volmode; -} zvol_volmode_cb_arg_t; - static void zvol_set_volmode_impl(char *name, uint64_t volmode) { diff --git a/sys/contrib/openzfs/module/zstd/README.md b/sys/contrib/openzfs/module/zstd/README.md index f8e127736aa..eed229e2f78 100644 --- a/sys/contrib/openzfs/module/zstd/README.md +++ b/sys/contrib/openzfs/module/zstd/README.md @@ -10,7 +10,7 @@ library, besides upgrading to a newer ZSTD release. Tree structure: * `zfs_zstd.c` is the actual `zzstd` kernel module. -* `lib/` contains the the unmodified, [_"amalgamated"_](https://github.com/facebook/zstd/blob/dev/contrib/single_file_libs/README.md) +* `lib/` contains the unmodified, [_"amalgamated"_](https://github.com/facebook/zstd/blob/dev/contrib/single_file_libs/README.md) version of the `Zstandard` library, generated from our template file * `zstd-in.c` is our template file for generating the library * `include/`: This directory contains supplemental includes for platform diff --git a/sys/contrib/openzfs/module/zstd/include/zstd_compat_wrapper.h b/sys/contrib/openzfs/module/zstd/include/zstd_compat_wrapper.h index 5cca517b550..71adc78040f 100644 --- a/sys/contrib/openzfs/module/zstd/include/zstd_compat_wrapper.h +++ b/sys/contrib/openzfs/module/zstd/include/zstd_compat_wrapper.h @@ -34,7 +34,7 @@ /* * This wrapper fixes a problem, in case the ZFS filesystem driver, is compiled - * staticly into the kernel. + * statically into the kernel. * This will cause a symbol collision with the older in-kernel zstd library. * The following macros will simply rename all local zstd symbols and references * diff --git a/sys/contrib/openzfs/module/zstd/zfs_zstd.c b/sys/contrib/openzfs/module/zstd/zfs_zstd.c index 69ebf252d1b..78616c08ba7 100644 --- a/sys/contrib/openzfs/module/zstd/zfs_zstd.c +++ b/sys/contrib/openzfs/module/zstd/zfs_zstd.c @@ -258,7 +258,7 @@ zstd_mempool_alloc(struct zstd_pool *zstd_mempool, size_t size) for (int i = 0; i < ZSTD_POOL_MAX; i++) { pool = &zstd_mempool[i]; /* - * This lock is simply a marker for a pool object beeing in use. + * This lock is simply a marker for a pool object being in use. * If it's already hold, it will be skipped. * * We need to create it before checking it to avoid race @@ -488,7 +488,7 @@ zfs_zstd_decompress_level(void *s_start, void *d_start, size_t s_len, /* * NOTE: We ignore the ZSTD version for now. As soon as any - * incompatibility occurrs, it has to be handled accordingly. + * incompatibility occurs, it has to be handled accordingly. * The version can be accessed via `hdr_copy.version`. */ diff --git a/sys/contrib/openzfs/rpm/generic/zfs-dkms.spec.in b/sys/contrib/openzfs/rpm/generic/zfs-dkms.spec.in index 6cdc224fcd8..0a6935516c6 100644 --- a/sys/contrib/openzfs/rpm/generic/zfs-dkms.spec.in +++ b/sys/contrib/openzfs/rpm/generic/zfs-dkms.spec.in @@ -26,7 +26,7 @@ BuildArch: noarch Requires: dkms >= 2.2.0.3 Requires: gcc, make, perl, diffutils %if 0%{?rhel}%{?fedora}%{?mageia}%{?suse_version} -Requires: kernel-devel +Requires: kernel-devel >= @ZFS_META_KVER_MIN@, kernel-devel <= @ZFS_META_KVER_MAX@.999 Obsoletes: spl-dkms %endif Provides: %{module}-kmod = %{version} diff --git a/sys/contrib/openzfs/rpm/generic/zfs.spec.in b/sys/contrib/openzfs/rpm/generic/zfs.spec.in index f46a633db6b..b1750942f53 100644 --- a/sys/contrib/openzfs/rpm/generic/zfs.spec.in +++ b/sys/contrib/openzfs/rpm/generic/zfs.spec.in @@ -120,16 +120,16 @@ License: @ZFS_META_LICENSE@ URL: https://github.com/openzfs/zfs Source0: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Requires: libzpool4 = %{version} +Requires: libzpool5 = %{version} Requires: libnvpair3 = %{version} Requires: libuutil3 = %{version} -Requires: libzfs4 = %{version} +Requires: libzfs5 = %{version} Requires: %{name}-kmod = %{version} Provides: %{name}-kmod-common = %{version} Obsoletes: spl -# zfs-fuse provides the same commands and man pages that ZoL does. Renaming -# those on either side would conflict with all available documentation. +# zfs-fuse provides the same commands and man pages that OpenZFS does. +# Renaming those on either side would conflict with all available documentation. Conflicts: zfs-fuse %if 0%{?rhel}%{?fedora}%{?suse_version} @@ -162,17 +162,22 @@ Requires: sysstat %description This package contains the core ZFS command line utilities. -%package -n libzpool4 +%package -n libzpool5 Summary: Native ZFS pool library for Linux Group: System Environment/Kernel Obsoletes: libzpool2 +Obsoletes: libzpool4 -%description -n libzpool4 +%description -n libzpool5 This package contains the zpool library, which provides support for managing zpools -%post -n libzpool4 -p /sbin/ldconfig -%postun -n libzpool4 -p /sbin/ldconfig +%if %{defined ldconfig_scriptlets} +%ldconfig_scriptlets -n libzpool5 +%else +%post -n libzpool5 -p /sbin/ldconfig +%postun -n libzpool5 -p /sbin/ldconfig +%endif %package -n libnvpair3 Summary: Solaris name-value library for Linux @@ -185,8 +190,12 @@ pairs. This functionality is used to portably transport data across process boundaries, between kernel and user space, and can be used to write self describing data structures on disk. +%if %{defined ldconfig_scriptlets} +%ldconfig_scriptlets -n libnvpair3 +%else %post -n libnvpair3 -p /sbin/ldconfig %postun -n libnvpair3 -p /sbin/ldconfig +%endif %package -n libuutil3 Summary: Solaris userland utility library for Linux @@ -204,34 +213,47 @@ This library provides a variety of compatibility functions for OpenZFS: partitioning. * libshare: NFS, SMB, and iSCSI service integration for ZFS. +%if %{defined ldconfig_scriptlets} +%ldconfig_scriptlets -n libuutil3 +%else %post -n libuutil3 -p /sbin/ldconfig %postun -n libuutil3 -p /sbin/ldconfig +%endif -%package -n libzfs4 +# The library version is encoded in the package name. When updating the +# version information it is important to add an obsoletes line below for +# the previous version of the package. +%package -n libzfs5 Summary: Native ZFS filesystem library for Linux Group: System Environment/Kernel Obsoletes: libzfs2 +Obsoletes: libzfs4 -%description -n libzfs4 +%description -n libzfs5 This package provides support for managing ZFS filesystems -%post -n libzfs4 -p /sbin/ldconfig -%postun -n libzfs4 -p /sbin/ldconfig +%if %{defined ldconfig_scriptlets} +%ldconfig_scriptlets -n libzfs5 +%else +%post -n libzfs5 -p /sbin/ldconfig +%postun -n libzfs5 -p /sbin/ldconfig +%endif -%package -n libzfs4-devel +%package -n libzfs5-devel Summary: Development headers Group: System Environment/Kernel -Requires: libzfs4 = %{version} -Requires: libzpool4 = %{version} +Requires: libzfs5 = %{version} +Requires: libzpool5 = %{version} Requires: libnvpair3 = %{version} Requires: libuutil3 = %{version} -Provides: libzpool4-devel +Provides: libzpool5-devel Provides: libnvpair3-devel Provides: libuutil3-devel Obsoletes: zfs-devel Obsoletes: libzfs2-devel +Obsoletes: libzfs4-devel -%description -n libzfs4-devel +%description -n libzfs5-devel This package contains the header files needed for building additional applications against the ZFS libraries. @@ -278,7 +300,7 @@ Summary: Python %{python_version} wrapper for libzfs_core Group: Development/Languages/Python License: Apache-2.0 BuildArch: noarch -Requires: libzfs4 = %{version} +Requires: libzfs5 = %{version} Requires: libnvpair3 = %{version} Requires: libffi Requires: python%{__python_pkg_version} @@ -483,7 +505,7 @@ systemctl --system daemon-reload >/dev/null || true %{_datadir}/pam-configs/* %endif -%files -n libzpool4 +%files -n libzpool5 %{_libdir}/libzpool.so.* %files -n libnvpair3 @@ -492,10 +514,10 @@ systemctl --system daemon-reload >/dev/null || true %files -n libuutil3 %{_libdir}/libuutil.so.* -%files -n libzfs4 +%files -n libzfs5 %{_libdir}/libzfs*.so.* -%files -n libzfs4-devel +%files -n libzfs5-devel %{_pkgconfigdir}/libzfs.pc %{_pkgconfigdir}/libzfsbootenv.pc %{_pkgconfigdir}/libzfs_core.pc diff --git a/sys/contrib/openzfs/rpm/redhat/zfs-kmod.spec.in b/sys/contrib/openzfs/rpm/redhat/zfs-kmod.spec.in index 9bc756c5aae..eb93aeeb2ef 100644 --- a/sys/contrib/openzfs/rpm/redhat/zfs-kmod.spec.in +++ b/sys/contrib/openzfs/rpm/redhat/zfs-kmod.spec.in @@ -17,8 +17,9 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) # by generating a preamble text file which kmodtool can append to the spec file. %(/bin/echo -e "\ Requires: @PACKAGE@ = %{version}\n\ -Conflicts: @PACKAGE@-dkms\n\n" > %{_sourcedir}/kmod-preamble\n\ -Obsoletes: spl-kmod) +Conflicts: @PACKAGE@-dkms\n\ +Obsoletes: kmod-spl\n\ +Obsoletes: spl-kmod\n\n" > %{_sourcedir}/kmod-preamble) # LDFLAGS are not sanitized by arch/*/Makefile for these architectures. %ifarch ppc ppc64 ppc64le aarch64 diff --git a/sys/contrib/openzfs/scripts/Makefile.am b/sys/contrib/openzfs/scripts/Makefile.am index f59826fe6bc..6c59fd7d4fa 100644 --- a/sys/contrib/openzfs/scripts/Makefile.am +++ b/sys/contrib/openzfs/scripts/Makefile.am @@ -1,3 +1,5 @@ +include $(top_srcdir)/config/Shellcheck.am + pkgdatadir = $(datadir)/@PACKAGE@ dist_pkgdata_SCRIPTS = \ @@ -7,19 +9,26 @@ dist_pkgdata_SCRIPTS = \ zloop.sh \ zfs-helpers.sh -EXTRA_DIST = \ +EXTRA_SCRIPTS = \ commitcheck.sh \ common.sh.in \ - cstyle.pl \ dkms.mkconf \ dkms.postbuild \ - enum-extract.pl \ kmodtool \ make_gitrev.sh \ man-dates.sh \ paxcheck.sh \ + mancheck.sh + +EXTRA_DIST = \ + cstyle.pl \ + enum-extract.pl \ zfs2zol-patch.sed \ - zol2zfs-patch.sed + zol2zfs-patch.sed \ + $(EXTRA_SCRIPTS) + +SHELLCHECK_IGNORE = ,SC1117 +SHELLCHECKSCRIPTS = $(EXTRA_SCRIPTS) define EXTRA_ENVIRONMENT diff --git a/sys/contrib/openzfs/scripts/commitcheck.sh b/sys/contrib/openzfs/scripts/commitcheck.sh index 71cf521666a..0077eb6b040 100755 --- a/sys/contrib/openzfs/scripts/commitcheck.sh +++ b/sys/contrib/openzfs/scripts/commitcheck.sh @@ -87,9 +87,7 @@ coverity_fix_commit() IFS=' ' for line in $(git log -n 1 --pretty=%b "$REF" | grep -E '^CID'); do - echo "$line" | grep -E '^CID [[:digit:]]+: ([[:graph:]]+|[[:space:]])+ \(([[:upper:]]|\_)+\)' > /dev/null - # shellcheck disable=SC2181 - if [ $? -ne 0 ]; then + if ! echo "$line" | grep -qE '^CID [[:digit:]]+: ([[:graph:]]+|[[:space:]])+ \(([[:upper:]]|\_)+\)'; then echo "error: commit message has an improperly formatted CID defect line" error=1 fi diff --git a/sys/contrib/openzfs/scripts/dkms.mkconf b/sys/contrib/openzfs/scripts/dkms.mkconf index 8649b93183a..9d12a8c3b3f 100755 --- a/sys/contrib/openzfs/scripts/dkms.mkconf +++ b/sys/contrib/openzfs/scripts/dkms.mkconf @@ -6,19 +6,21 @@ pkgcfg=/etc/sysconfig/zfs while getopts "n:v:c:f:" opt; do case $opt in - n) pkgname=$OPTARG ;; - v) pkgver=$OPTARG ;; - c) pkgcfg=$OPTARG ;; + n) pkgname=$OPTARG ;; + v) pkgver=$OPTARG ;; + c) pkgcfg=$OPTARG ;; f) filename=$OPTARG ;; + *) err=1 ;; esac done -if [ -z "${pkgname}" ] || [ -z "${pkgver}" ] || [ -z "${filename}" ]; then +if [ -z "${pkgname}" ] || [ -z "${pkgver}" ] || [ -z "${filename}" ] || + [ -n "${err}" ]; then echo "Usage: $PROG -n -v -c -f " exit 1 fi -cat >${filename} <"${filename}" < -k -n " \ - "-t -v " + "-t -v " exit 1 fi -cp "${tree}/${pkgname}/${pkgver}/build/zfs_config.h" \ +exec cp "${tree}/${pkgname}/${pkgver}/build/zfs_config.h" \ "${tree}/${pkgname}/${pkgver}/build/module/Module.symvers" \ "${tree}/${pkgname}/${pkgver}/${kver}/${arch}/" diff --git a/sys/contrib/openzfs/scripts/kmodtool b/sys/contrib/openzfs/scripts/kmodtool index 240cde3106a..26bacf5991d 100755 --- a/sys/contrib/openzfs/scripts/kmodtool +++ b/sys/contrib/openzfs/scripts/kmodtool @@ -1,4 +1,5 @@ #!/usr/bin/env bash +# shellcheck disable=SC2086 # kmodtool - Helper script for building kernel module RPMs # Copyright (c) 2003-2012 Ville Skyttä , @@ -38,15 +39,16 @@ prefix= filterfile= target= buildroot= +dashvariant= error_out() { local errorlevel=${1} shift - echo "Error: $@" >&2 + echo "Error: $*" >&2 # the next line is not multi-line safe -- not needed *yet* - echo "%global kmodtool_check echo \"kmodtool error: $@\"; exit ${errorlevel};" - exit ${errorlevel} + echo "%global kmodtool_check echo \"kmodtool error: $*\"; exit ${errorlevel};" + exit "${errorlevel}" } print_rpmtemplate_header() @@ -182,9 +184,21 @@ BuildRequires: kernel-devel-uname-r = ${kernel_uname_r} %{?KmodsRequires:Requires: %{KmodsRequires}-uname-r = ${kernel_uname_r}} %{?KmodsRequires:BuildRequires: %{KmodsRequires}-uname-r = ${kernel_uname_r}} %post -n kmod-${kmodname}-${kernel_uname_r} -${prefix}${depmod_path} -aeF /boot/System.map-${kernel_uname_r} ${kernel_uname_r} > /dev/null || : +if [[ -f "/boot/System.map-${kernel_uname_r}" ]]; then + ${prefix}${depmod_path} -aeF /boot/System.map-${kernel_uname_r} ${kernel_uname_r} > /dev/null || : +elif [[ -f "/lib/modules/${kernel_uname_r}/System.map" ]]; then + ${prefix}${depmod_path} -aeF /lib/modules/${kernel_uname_r}/System.map ${kernel_uname_r} > /dev/null || : +else + ${prefix}${depmod_path} -ae ${kernel_uname_r} &> /dev/null || : +fi %postun -n kmod-${kmodname}-${kernel_uname_r} -${prefix}${depmod_path} -aF /boot/System.map-${kernel_uname_r} ${kernel_uname_r} &> /dev/null || : +if [[ -f "/boot/System.map-${kernel_uname_r}" ]]; then + ${prefix}${depmod_path} -aF /boot/System.map-${kernel_uname_r} ${kernel_uname_r} &> /dev/null || : +elif [[ -f "/lib/modules/${kernel_uname_r}/System.map" ]]; then + ${prefix}${depmod_path} -aF /lib/modules/${kernel_uname_r}/System.map ${kernel_uname_r} &> /dev/null || : +else + ${prefix}${depmod_path} -a ${kernel_uname_r} &> /dev/null || : +fi EOF else @@ -567,7 +581,7 @@ elif [[ ! "${kmodname}" ]]; then error_out 2 "please pass kmodname with --kmodname" elif [[ ! "${kernels_known_variants}" ]] ; then error_out 2 "could not determine known variants" -elif ( [[ "${obsolete_name}" ]] && [[ ! "${obsolete_version}" ]] ) || ( [[ ! "${obsolete_name}" ]] && [[ "${obsolete_version}" ]] ) ; then +elif { [[ "${obsolete_name}" ]] && [[ ! "${obsolete_version}" ]]; } || { [[ ! "${obsolete_name}" ]] && [[ "${obsolete_version}" ]]; } ; then error_out 2 "you need to provide both --obsolete-name and --obsolete-version" fi @@ -585,7 +599,7 @@ else # we need more sanity checks in this case if [[ ! "${repo}" ]]; then error_out 2 "please provide repo name with --repo" - elif ! $(which buildsys-build-${repo}-kerneldevpkgs &> /dev/null) ; then + elif ! command -v "buildsys-build-${repo}-kerneldevpkgs" &> /dev/null ; then error_out 2 "buildsys-build-${repo}-kerneldevpkgs not found" fi @@ -599,7 +613,7 @@ else kernel_versions_to_build_for="$(buildsys-build-${repo}-kerneldevpkgs --${build_kernels} ${cmdoptions})" returncode=$? - if (( ${returncode} != 0 )); then + if (( returncode != 0 )); then error_out 2 "buildsys-build-${repo}-kerneldevpkgs failed: $(buildsys-build-${repo}-kerneldevpkgs --${build_kernels} ${cmdoptions})" fi diff --git a/sys/contrib/openzfs/scripts/make_gitrev.sh b/sys/contrib/openzfs/scripts/make_gitrev.sh index f5c743b1379..da21455332a 100755 --- a/sys/contrib/openzfs/scripts/make_gitrev.sh +++ b/sys/contrib/openzfs/scripts/make_gitrev.sh @@ -56,9 +56,9 @@ then # already exists (in the source) if [ -f "${top_srcdir}/${GITREV}" ] then - ZFS_GITREV="$(sed -n \ + ZFS_GITREV=$(sed -n \ '1s/^#define[[:blank:]]ZFS_META_GITREV "\([^"]*\)"$/\1/p' \ - "${top_srcdir}/${GITREV}")" + "${top_srcdir}/${GITREV}") fi elif [ ${dist} = yes ] then diff --git a/sys/contrib/openzfs/scripts/mancheck.sh b/sys/contrib/openzfs/scripts/mancheck.sh new file mode 100755 index 00000000000..6ae1fc5becf --- /dev/null +++ b/sys/contrib/openzfs/scripts/mancheck.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN +# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# shellcheck disable=SC2086 + +if [ "$#" -eq 0 ]; then + echo "Usage: $0 manpage-directory..." + exit 1 +fi + +if ! command -v mandoc > /dev/null; then + echo "skipping mancheck because mandoc is not installed" + exit 0 +fi + +IFS=" +" + +files="$(find "$@" -type f -name '*[1-9]*')" || exit 1 + +add_excl="$(awk ' + /^.\\" lint-ok:/ { + print "-e" + $1 = "mandoc:" + $2 = FILENAME ":[[:digit:]]+:[[:digit:]]+:" + print + }' $files)" + +# Redirect to file instead of 2>&1ing because mandoc flushes inconsistently(?) which tears lines +# https://github.com/openzfs/zfs/pull/12129/checks?check_run_id=2701608671#step:5:3 +etmp="$(mktemp)" +! { mandoc -Tlint $files 2>"$etmp"; cat "$etmp"; rm -f "$etmp"; } | + grep -vE -e 'mandoc: outdated mandoc.db' -e 'STYLE: referenced manual not found' $add_excl >&2 diff --git a/sys/contrib/openzfs/scripts/paxcheck.sh b/sys/contrib/openzfs/scripts/paxcheck.sh index 87e817500b1..27acc95364a 100755 --- a/sys/contrib/openzfs/scripts/paxcheck.sh +++ b/sys/contrib/openzfs/scripts/paxcheck.sh @@ -1,7 +1,6 @@ #!/bin/sh -# shellcheck disable=SC2039 -if ! type scanelf > /dev/null 2>&1; then +if ! command -v scanelf > /dev/null; then echo "scanelf (from pax-utils) is required for these checks." >&2 exit 3 fi diff --git a/sys/contrib/openzfs/scripts/zfs-tests.sh b/sys/contrib/openzfs/scripts/zfs-tests.sh index 45e08473d35..edb9c9f106c 100755 --- a/sys/contrib/openzfs/scripts/zfs-tests.sh +++ b/sys/contrib/openzfs/scripts/zfs-tests.sh @@ -355,7 +355,6 @@ while getopts 'hvqxkfScn:d:s:r:?t:T:u:I:' OPTION; do exit 1 ;; v) - # shellcheck disable=SC2034 VERBOSE="yes" ;; q) diff --git a/sys/contrib/openzfs/scripts/zfs.sh b/sys/contrib/openzfs/scripts/zfs.sh index 2f5f3f8fdb5..39c49d71e59 100755 --- a/sys/contrib/openzfs/scripts/zfs.sh +++ b/sys/contrib/openzfs/scripts/zfs.sh @@ -120,9 +120,7 @@ load_module_linux() { echo "Loading: $FILE ($VERSION)" fi - $LDMOD "$KMOD" >/dev/null 2>&1 - # shellcheck disable=SC2181 - if [ $? -ne 0 ]; then + if ! $LDMOD "$KMOD" >/dev/null 2>&1; then echo "Failed to load $KMOD" return 1 fi diff --git a/sys/contrib/openzfs/scripts/zimport.sh b/sys/contrib/openzfs/scripts/zimport.sh index 56dfbadae47..0e9c01182b8 100755 --- a/sys/contrib/openzfs/scripts/zimport.sh +++ b/sys/contrib/openzfs/scripts/zimport.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash # # Verify that an assortment of known good reference pools can be imported -# using different versions of the ZoL code. +# using different versions of OpenZFS code. # # By default references pools for the major ZFS implementation will be -# checked against the most recent ZoL tags and the master development branch. +# checked against the most recent OpenZFS tags and the master development branch. # Alternate tags or branches may be verified with the '-s option. # Passing the keyword "installed" will instruct the script to test whatever # version is installed. @@ -98,7 +98,7 @@ OPTIONS: -c No color -k Keep temporary directory -r Source repository ($REPO) - -s ... Verify ZoL versions with the listed tags + -s ... Verify OpenZFS versions with the listed tags -i Pool image directory -p ... Verify pools created with the listed tags -f Temporary directory to use @@ -164,15 +164,13 @@ populate() { local MAX_DIR_SIZE=$2 local MAX_FILE_SIZE=$3 - # shellcheck disable=SC2086 - mkdir -p $ROOT/{a,b,c,d,e,f,g}/{h,i} + mkdir -p "$ROOT"/{a,b,c,d,e,f,g}/{h,i} DIRS=$(find "$ROOT") for DIR in $DIRS; do COUNT=$((RANDOM % MAX_DIR_SIZE)) - # shellcheck disable=SC2034 - for i in $(seq $COUNT); do + for _ in $(seq $COUNT); do FILE=$(mktemp -p "$DIR") SIZE=$((RANDOM % MAX_FILE_SIZE)) dd if=/dev/urandom of="$FILE" bs=1k \ @@ -334,9 +332,8 @@ fi for TAG in $POOL_TAGS; do if [ "$TAG" = "all" ]; then - # shellcheck disable=SC2010 - ALL_TAGS=$(ls "$IMAGES_DIR" | grep "tar.bz2" | \ - sed 's/.tar.bz2//' | tr '\n' ' ') + ALL_TAGS=$(echo "$IMAGES_DIR"/*.tar.bz2 | \ + sed "s|$IMAGES_DIR/||g;s|.tar.bz2||g") NEW_TAGS="$NEW_TAGS $ALL_TAGS" else NEW_TAGS="$NEW_TAGS $TAG" @@ -491,10 +488,8 @@ for TAG in $POOL_TAGS; do POOL_NAME=$($ZPOOL_CMD import -d "$POOL_DIR_COPY" | \ awk '/pool:/ { print $2; exit 0 }') - $ZPOOL_CMD import -N -d "$POOL_DIR_COPY" \ - "$POOL_NAME" &>/dev/null - # shellcheck disable=SC2181 - if [ $? -ne 0 ]; then + if ! $ZPOOL_CMD import -N -d "$POOL_DIR_COPY" + "$POOL_NAME" &>/dev/null; then fail_nonewline ERROR=1 else diff --git a/sys/contrib/openzfs/scripts/zloop.sh b/sys/contrib/openzfs/scripts/zloop.sh index bbe326aa07e..546e7001776 100755 --- a/sys/contrib/openzfs/scripts/zloop.sh +++ b/sys/contrib/openzfs/scripts/zloop.sh @@ -62,11 +62,8 @@ function usage function or_die { # shellcheck disable=SC2068 - $@ - # shellcheck disable=SC2181 - if [[ $? -ne 0 ]]; then - # shellcheck disable=SC2145 - echo "Command failed: $@" + if ! $@; then + echo "Command failed: $*" exit 1 fi } @@ -94,8 +91,8 @@ esac function core_file { - # shellcheck disable=SC2012 disable=2086 - printf "%s" "$(ls -tr1 $coreglob 2> /dev/null | head -1)" + # shellcheck disable=SC2012,SC2086 + ls -tr1 $coreglob 2>/dev/null | head -1 } function core_prog @@ -103,8 +100,7 @@ function core_prog prog=$ZTEST core_id=$($GDB --batch -c "$1" | grep "Core was generated by" | \ tr \' ' ') - # shellcheck disable=SC2076 - if [[ "$core_id" =~ "zdb " ]]; then + if [[ "$core_id" == *"zdb "* ]]; then prog=$ZDB fi printf "%s" "$prog" @@ -306,8 +302,7 @@ while [[ $timeout -eq 0 ]] || [[ $curtime -le $((starttime + timeout)) ]]; do zopt="$zopt -s $size" zopt="$zopt -f $workdir" - # shellcheck disable=SC2124 - cmd="$ZTEST $zopt $@" + cmd="$ZTEST $zopt $*" desc="$(date '+%m/%d %T') $cmd" echo "$desc" | tee -a ztest.history echo "$desc" >>ztest.out diff --git a/sys/contrib/openzfs/tests/Makefile.am b/sys/contrib/openzfs/tests/Makefile.am index f13b19613b0..4bdde9c4508 100644 --- a/sys/contrib/openzfs/tests/Makefile.am +++ b/sys/contrib/openzfs/tests/Makefile.am @@ -1,3 +1,8 @@ +include $(top_srcdir)/config/Shellcheck.am + SUBDIRS = runfiles test-runner zfs-tests EXTRA_DIST = README.md + +SHELLCHECKSCRIPTS = $$(find -name '*.sh') +.PHONY: $(SHELLCHECKSCRIPTS) diff --git a/sys/contrib/openzfs/tests/runfiles/common.run b/sys/contrib/openzfs/tests/runfiles/common.run index cc241455084..e87c1cd641f 100644 --- a/sys/contrib/openzfs/tests/runfiles/common.run +++ b/sys/contrib/openzfs/tests/runfiles/common.run @@ -166,8 +166,8 @@ tags = ['functional', 'cli_root', 'zfs_create'] [tests/functional/cli_root/zfs_destroy] tests = ['zfs_clone_livelist_condense_and_disable', - 'zfs_clone_livelist_condense_races', 'zfs_destroy_001_pos', - 'zfs_destroy_002_pos', 'zfs_destroy_003_pos', + 'zfs_clone_livelist_condense_races', 'zfs_clone_livelist_dedup', + 'zfs_destroy_001_pos', 'zfs_destroy_002_pos', 'zfs_destroy_003_pos', 'zfs_destroy_004_pos', 'zfs_destroy_005_neg', 'zfs_destroy_006_neg', 'zfs_destroy_007_neg', 'zfs_destroy_008_pos', 'zfs_destroy_009_pos', 'zfs_destroy_010_pos', 'zfs_destroy_011_pos', 'zfs_destroy_012_pos', @@ -198,7 +198,8 @@ tags = ['functional', 'cli_root', 'zfs_inherit'] [tests/functional/cli_root/zfs_load-key] tests = ['zfs_load-key', 'zfs_load-key_all', 'zfs_load-key_file', - 'zfs_load-key_location', 'zfs_load-key_noop', 'zfs_load-key_recursive'] + 'zfs_load-key_https', 'zfs_load-key_location', 'zfs_load-key_noop', + 'zfs_load-key_recursive'] tags = ['functional', 'cli_root', 'zfs_load-key'] [tests/functional/cli_root/zfs_mount] @@ -258,7 +259,7 @@ tags = ['functional', 'cli_root', 'zfs_rollback'] tests = ['zfs_send_001_pos', 'zfs_send_002_pos', 'zfs_send_003_pos', 'zfs_send_004_neg', 'zfs_send_005_pos', 'zfs_send_006_pos', 'zfs_send_007_pos', 'zfs_send_encrypted', 'zfs_send_raw', - 'zfs_send_sparse', 'zfs_send-b'] + 'zfs_send_sparse', 'zfs_send-b', 'zfs_send_skip_missing'] tags = ['functional', 'cli_root', 'zfs_send'] [tests/functional/cli_root/zfs_set] @@ -577,6 +578,12 @@ tags = ['functional', 'cp_files'] tests = ['ctime_001_pos' ] tags = ['functional', 'ctime'] +[tests/functional/deadman] +tests = ['deadman_ratelimit', 'deadman_sync', 'deadman_zio'] +pre = +post = +tags = ['functional', 'deadman'] + [tests/functional/delegate] tests = ['zfs_allow_001_pos', 'zfs_allow_002_pos', 'zfs_allow_003_pos', 'zfs_allow_004_pos', 'zfs_allow_005_pos', 'zfs_allow_006_pos', @@ -735,12 +742,13 @@ tests = ['raidz_001_neg', 'raidz_002_pos', 'raidz_003_pos', 'raidz_004_pos'] tags = ['functional', 'raidz'] [tests/functional/redundancy] -tests = ['redundancy_draid1', 'redundancy_draid2', 'redundancy_draid3', - 'redundancy_draid_spare1', 'redundancy_draid_spare2', - 'redundancy_draid_spare3', 'redundancy_mirror', 'redundancy_raidz', - 'redundancy_raidz1', 'redundancy_raidz2', 'redundancy_raidz3', - 'redundancy_stripe'] +tests = ['redundancy_draid', 'redundancy_draid1', 'redundancy_draid2', + 'redundancy_draid3', 'redundancy_draid_damaged', 'redundancy_draid_spare1', + 'redundancy_draid_spare2', 'redundancy_draid_spare3', 'redundancy_mirror', + 'redundancy_raidz', 'redundancy_raidz1', 'redundancy_raidz2', + 'redundancy_raidz3', 'redundancy_stripe'] tags = ['functional', 'redundancy'] +timeout = 1200 [tests/functional/refquota] tests = ['refquota_001_pos', 'refquota_002_pos', 'refquota_003_pos', @@ -877,8 +885,7 @@ tests = [ 'userquota_004_pos', 'userquota_005_neg', 'userquota_006_pos', 'userquota_007_pos', 'userquota_008_pos', 'userquota_009_pos', 'userquota_010_pos', 'userquota_011_pos', 'userquota_012_neg', - 'userspace_001_pos', 'userspace_002_pos', 'userspace_encrypted', - 'userspace_send_encrypted'] + 'userspace_001_pos', 'userspace_002_pos', 'userspace_encrypted'] tags = ['functional', 'userquota'] [tests/functional/vdev_zaps] diff --git a/sys/contrib/openzfs/tests/runfiles/linux.run b/sys/contrib/openzfs/tests/runfiles/linux.run index 9f6bd856aa0..c6d4f5f6d34 100644 --- a/sys/contrib/openzfs/tests/runfiles/linux.run +++ b/sys/contrib/openzfs/tests/runfiles/linux.run @@ -85,18 +85,12 @@ tags = ['functional', 'cli_root', 'zpool_split'] tests = ['compress_004_pos'] tags = ['functional', 'compression'] -[tests/functional/deadman:Linux] -tests = ['deadman_sync', 'deadman_zio'] -pre = -post = -tags = ['functional', 'deadman'] - [tests/functional/devices:Linux] tests = ['devices_001_pos', 'devices_002_neg', 'devices_003_pos'] tags = ['functional', 'devices'] [tests/functional/events:Linux] -tests = ['events_001_pos', 'events_002_pos', 'zed_rc_filter'] +tests = ['events_001_pos', 'events_002_pos', 'zed_rc_filter', 'zed_fd_spill'] tags = ['functional', 'events'] [tests/functional/fallocate:Linux] diff --git a/sys/contrib/openzfs/tests/runfiles/sanity.run b/sys/contrib/openzfs/tests/runfiles/sanity.run index e32cf5f6228..ad4495144cd 100644 --- a/sys/contrib/openzfs/tests/runfiles/sanity.run +++ b/sys/contrib/openzfs/tests/runfiles/sanity.run @@ -12,7 +12,7 @@ # as much functionality as possible while still executing relatively # quickly. The included tests should take no more than a few seconds # each to run at most. This provides a convenient way to sanity test a -# change before commiting to a full test run which takes several hours. +# change before committing to a full test run which takes several hours. # # Approximate run time: 15 minutes # @@ -146,7 +146,8 @@ tags = ['functional', 'cli_root', 'zfs_inherit'] [tests/functional/cli_root/zfs_load-key] tests = ['zfs_load-key', 'zfs_load-key_all', 'zfs_load-key_file', - 'zfs_load-key_location', 'zfs_load-key_noop', 'zfs_load-key_recursive'] + 'zfs_load-key_https', 'zfs_load-key_location', 'zfs_load-key_noop', + 'zfs_load-key_recursive'] tags = ['functional', 'cli_root', 'zfs_load-key'] [tests/functional/cli_root/zfs_mount] diff --git a/sys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in b/sys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in index c5a1011c102..a3e9f2a82e6 100755 --- a/sys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in +++ b/sys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in @@ -194,8 +194,12 @@ elif sys.platform.startswith('linux'): maybe = { 'chattr/setup': ['SKIP', exec_reason], 'cli_root/zdb/zdb_006_pos': ['FAIL', known_reason], + 'cli_root/zfs_destroy/zfs_destroy_dev_removal_condense': + ['FAIL', known_reason], 'cli_root/zfs_get/zfs_get_004_pos': ['FAIL', known_reason], 'cli_root/zfs_get/zfs_get_009_pos': ['SKIP', '5479'], + 'cli_root/zfs_rollback/zfs_rollback_001_pos': ['FAIL', known_reason], + 'cli_root/zfs_rollback/zfs_rollback_002_pos': ['FAIL', known_reason], 'cli_root/zfs_share/setup': ['SKIP', share_reason], 'cli_root/zfs_snapshot/zfs_snapshot_002_neg': ['FAIL', known_reason], 'cli_root/zfs_unshare/setup': ['SKIP', share_reason], @@ -206,6 +210,10 @@ maybe = { 'cli_root/zpool_import/import_rewind_config_changed': ['FAIL', rewind_reason], 'cli_root/zpool_import/zpool_import_missing_003_pos': ['SKIP', '6839'], + 'cli_root/zpool_initialize/zpool_initialize_import_export': + ['FAIL', '11948'], + 'cli_root/zpool_labelclear/zpool_labelclear_removed': + ['FAIL', known_reason], 'cli_root/zpool_trim/setup': ['SKIP', trim_reason], 'cli_root/zpool_upgrade/zpool_upgrade_004_pos': ['FAIL', '6141'], 'delegate/setup': ['SKIP', exec_reason], @@ -215,13 +223,17 @@ maybe = { 'history/history_008_pos': ['FAIL', known_reason], 'history/history_010_pos': ['SKIP', exec_reason], 'io/mmap': ['SKIP', fio_reason], + 'l2arc/persist_l2arc_005_pos': ['FAIL', known_reason], + 'l2arc/persist_l2arc_007_pos': ['FAIL', '11887'], 'largest_pool/largest_pool_001_pos': ['FAIL', known_reason], 'mmp/mmp_on_uberblocks': ['FAIL', known_reason], 'pyzfs/pyzfs_unittest': ['SKIP', python_deps_reason], 'no_space/enospc_002_pos': ['FAIL', enospc_reason], + 'pool_checkpoint/checkpoint_discard_busy': ['FAIL', '11946'], 'projectquota/setup': ['SKIP', exec_reason], 'redundancy/redundancy_004_neg': ['FAIL', '7290'], 'redundancy/redundancy_draid_spare3': ['SKIP', known_reason], + 'removal/removal_condense_export': ['FAIL', known_reason], 'reservation/reservation_008_pos': ['FAIL', '7741'], 'reservation/reservation_018_pos': ['FAIL', '5642'], 'rsend/rsend_019_pos': ['FAIL', '6086'], @@ -253,9 +265,15 @@ if sys.platform.startswith('freebsd'): 'cli_root/zfs_share/zfs_share_concurrent_shares': ['FAIL', known_reason], 'cli_root/zpool_import/zpool_import_012_pos': ['FAIL', known_reason], + 'cli_root/zpool_import/zpool_import_features_001_pos': + ['FAIL', '11854'], + 'cli_root/zpool_import/zpool_import_features_002_neg': + ['FAIL', '11854'], + 'cli_root/zpool_import/zpool_import_features_003_pos': + ['FAIL', '11854'], 'delegate/zfs_allow_003_pos': ['FAIL', known_reason], - 'removal/removal_condense_export': ['FAIL', known_reason], - 'removal/removal_with_export': ['FAIL', known_reason], + 'inheritance/inherit_001_pos': ['FAIL', '11829'], + 'pool_checkpoint/checkpoint_zhack_feat': ['FAIL', '11854'], 'resilver/resilver_restart_001': ['FAIL', known_reason], 'zvol/zvol_misc/zvol_misc_volmode': ['FAIL', known_reason], }) @@ -264,13 +282,16 @@ elif sys.platform.startswith('linux'): 'alloc_class/alloc_class_009_pos': ['FAIL', known_reason], 'alloc_class/alloc_class_010_pos': ['FAIL', known_reason], 'alloc_class/alloc_class_011_neg': ['FAIL', known_reason], + 'alloc_class/alloc_class_013_pos': ['FAIL', '11888'], 'cli_root/zfs_rename/zfs_rename_002_pos': ['FAIL', known_reason], 'cli_root/zpool_expand/zpool_expand_001_pos': ['FAIL', known_reason], 'cli_root/zpool_expand/zpool_expand_005_pos': ['FAIL', known_reason], 'cli_root/zpool_reopen/zpool_reopen_003_pos': ['FAIL', known_reason], + 'fault/auto_spare_shared': ['FAIL', '11889'], 'io/io_uring': ['SKIP', 'io_uring support required'], 'limits/filesystem_limit': ['SKIP', known_reason], 'limits/snapshot_limit': ['SKIP', known_reason], + 'mmp/mmp_active_import': ['FAIL', known_reason], 'mmp/mmp_exported_import': ['FAIL', known_reason], 'mmp/mmp_inactive_import': ['FAIL', known_reason], 'refreserv/refreserv_raidz': ['FAIL', known_reason], diff --git a/sys/contrib/openzfs/tests/test-runner/man/test-runner.1 b/sys/contrib/openzfs/tests/test-runner/man/test-runner.1 index 19c636c8cb7..f7cbcbc5b9e 100644 --- a/sys/contrib/openzfs/tests/test-runner/man/test-runner.1 +++ b/sys/contrib/openzfs/tests/test-runner/man/test-runner.1 @@ -8,316 +8,255 @@ .\" source. A copy of the CDDL is also available via the Internet at .\" http://www.illumos.org/license/CDDL. .\" -.\" .\" Copyright (c) 2012 by Delphix. All rights reserved. .\" -.TH run 1 "23 Sep 2012" -.SH NAME -run \- find, execute, and log the results of tests -.SH SYNOPSIS -.LP -.nf -\fBrun\fR [\fB-dgq] [\fB-o\fR \fIoutputdir\fR] [\fB-pP\fR \fIscript\fR] [\fB-t\fR \fIseconds\fR] [\fB-uxX\fR \fIusername\fR] - \fIpathname\fR ... -.fi - -.LP -.nf -\fBrun\fR \fB-w\fR \fIrunfile\fR [\fB-gq\fR] [\fB-o\fR \fIoutputdir\fR] [\fB-pP\fR \fIscript\fR] [\fB-t\fR \fIseconds\fR] - [\fB-uxX\fR \fIusername\fR] \fIpathname\fR ... -.fi - -.LP -.nf -\fBrun\fR \fB-c\fR \fIrunfile\fR [\fB-dq\fR] -.fi - -.LP -.nf -\fBrun\fR [\fB-h\fR] -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBrun\fR command has three basic modes of operation. With neither the -\fB-c\fR nor the \fB-w\fR option, \fBrun\fR processes the arguments provided on -the command line, adding them to the list for this run. If a specified -\fIpathname\fR is an executable file, it is added as a test. If a specified -\fIpathname\fR is a directory, the behavior depends upon the \fB-g\fR option. -If \fB-g\fR is specified, the directory is treated as a test group. See the -section on "Test Groups" below. Without the \fB-g\fR option, \fBrun\fR simply -descends into the directory looking for executable files. The tests are then -executed, and the results are logged. - -With the \fB-w\fR option, \fBrun\fR finds tests in the manner described above. +.Dd May 26, 2021 +.Dt RUN 1 +.Os +. +.Sh NAME +.Nm run +.Nd find, execute, and log the results of tests +.Sh SYNOPSIS +.Nm +.Op Fl dgq +.Op Fl o Ar outputdir +.Op Fl pP Ar script +.Op Fl t seconds +.Op Fl uxX Ar username +.Ar pathname Ns No … +.Pp +.Nm +.Fl w Ar runfile +.Op Fl gq +.Op Fl o Ar outputdir +.Op Fl pP Ar script +.Op Fl t seconds +.Op Fl uxX Ar username +.Ar pathname Ns No … +.Pp +.Nm +.Fl c Ar runfile +.Op Fl dq +.Pp +.Nm +.Op Fl h +. +.Sh DESCRIPTION +.Nm +command has three basic modes of operation. +With neither +.Fl c +nor +.Fl w , +.Nm +processes the arguments provided on +the command line, adding them to the list for this run. +If a specified +.Ar pathname +is an executable file, it is added as a test. +If a specified +.Ar pathname +is a directory, the behavior depends upon the presence of +.Fl g . +If +.Fl g +is specified, the directory is treated as a test group. +See the section on +.Sy Test Groups +below. +Without +.Fl g , +.Nm +simply descends into the directory looking for executable files. +The tests are then executed, and the results are logged. +.Pp +With +.Fl w , +.Nm +finds tests in the manner described above. Rather than executing the tests and logging the results, the test configuration -is stored in a \fIrunfile\fR which can be used in future invocations, or edited -to modify which tests are executed and which options are applied. Options -included on the command line with \fB-w\fR become defaults in the -\fIrunfile\fR. - -With the \fB-c\fR option, \fBrun\fR parses a \fIrunfile\fR, which can specify a -series of tests and test groups to be executed. The tests are then executed, -and the results are logged. -.sp -.SS "Test Groups" -.sp -.LP +is stored in a +.Ar runfile , +which can be used in future invocations, or edited +to modify which tests are executed and which options are applied. +Options included on the command line with +.Fl w +become defaults in the +.Ar runfile . +.Pp +With +.Fl c , +.Nm +parses a +.Ar runfile , +which can specify a series of tests and test groups to be executed. +The tests are then executed, and the results are logged. +. +.Ss Test Groups A test group is comprised of a set of executable files, all of which exist in -one directory. The options specified on the command line or in a \fIrunfile\fR -apply to individual tests in the group. The exception is options pertaining to -pre and post scripts, which act on all tests as a group. Rather than running -before and after each test, these scripts are run only once each at the start -and end of the test group. -.SS "Test Execution" -.sp -.LP +one directory. +The options specified on the command line or in a +.Ar runfile +apply to individual tests in the group. +The exception is options pertaining to pre and post scripts, which act on all tests as a group. +Rather than running before and after each test, +these scripts are run only once each at the start and end of the test group. +.Ss Test Execution The specified tests run serially, and are typically assigned results according -to exit values. Tests that exit zero and non-zero are marked "PASS" and "FAIL" -respectively. When a pre script fails for a test group, only the post script is -executed, and the remaining tests are marked "SKIPPED." Any test that exceeds -its \fItimeout\fR is terminated, and marked "KILLED." - -By default, tests are executed with the credentials of the \fBrun\fR script. -Executing tests with other credentials is done via \fBsudo\fR(1m), which must -be configured to allow execution without prompting for a password. Environment -variables from the calling shell are available to individual tests. During test -execution, the working directory is changed to \fIoutputdir\fR. -.SS "Output Logging" -.sp -.LP -By default, \fBrun\fR will print one line on standard output at the conclusion -of each test indicating the test name, result and elapsed time. Additionally, -for each invocation of \fBrun\fR, a directory is created using the ISO 8601 -date format. Within this directory is a file named \fIlog\fR containing all the -test output with timestamps, and a directory for each test. Within the test -directories, there is one file each for standard output, standard error and -merged output. The default location for the \fIoutputdir\fR is -\fI/var/tmp/test_results\fR. -.SS "Runfiles" -.sp -.LP -The \fIrunfile\fR is an ini style configuration file that describes a test run. -The file has one section named "DEFAULT," which contains configuration option -names and their values in "name = value" format. The values in this section -apply to all the subsequent sections, unless they are also specified there, in -which case the default is overridden. The remaining section names are the -absolute pathnames of files and directories, describing tests and test groups -respectively. The legal option names are: -.sp -.ne 2 -.na -\fBoutputdir\fR = \fIpathname\fR -.ad -.sp .6 -.RS 4n +to exit values. +Tests that exit zero and non-zero are marked +.Sy PASS +and +.Sy FAIL , +respectively. +When a pre script fails for a test group, only the post script is executed, +and the remaining tests are marked +.Sy SKIPPED . +Any test that exceeds +its +.Ar timeout +is terminated, and marked +.Sy KILLED . +.Pp +By default, tests are executed with the credentials of the +.Nm +script. +Executing tests with other credentials is done via +.Xr sudo 1m , +which must +be configured to allow execution without prompting for a password. +Environment variables from the calling shell are available to individual tests. +During test execution, the working directory is changed to +.Ar outputdir . +. +.Ss Output Logging +By default, +.Nm +will print one line on standard output at the conclusion +of each test indicating the test name, result and elapsed time. +Additionally, for each invocation of +.Nm , +a directory is created using the ISO 8601 date format. +Within this directory is a file named +.Sy log +containing all the +test output with timestamps, and a directory for each test. +Within the test directories, there is one file each for standard output, +standard error and merged output. +The default location for the +.Ar outputdir +is +.Pa /var/tmp/test_results . +.Ss "Runfiles" +The +.Ar runfile +is an INI-style configuration file that describes a test run. +The file has one section named +.Sy DEFAULT , +which contains configuration option +names and their values in +.Sy name No = Ar value +format. +The values in this section apply to all the subsequent sections, +unless they are also specified there, in which case the default is overridden. +The remaining section names are the absolute pathnames of files and directories, +describing tests and test groups respectively. +The legal option names are: +.Bl -tag -width "tests = ['filename', …]" +.It Sy outputdir No = Ar pathname The name of the directory that holds test logs. -.RE -.sp -.ne 2 -.na -\fBpre\fR = \fIscript\fR -.ad -.sp .6 -.RS 4n -Run \fIscript\fR prior to the test or test group. -.RE -.sp -.ne 2 -.na -\fBpre_user\fR = \fIusername\fR -.ad -.sp .6 -.RS 4n -Execute the pre script as \fIusername\fR. -.RE -.sp -.ne 2 -.na -\fBpost\fR = \fIscript\fR -.ad -.sp .6 -.RS 4n -Run \fIscript\fR after the test or test group. -.RE -.sp -.ne 2 -.na -\fBpost_user\fR = \fIusername\fR -.ad -.sp .6 -.RS 4n -Execute the post script as \fIusername\fR. -.RE -.sp -.ne 2 -.na -\fBquiet\fR = [\fITrue\fR|\fIFalse\fR] -.ad -.sp .6 -.RS 4n -If set to True, only the results summary is printed to standard out. -.RE -.sp -.ne 2 -.na -\fBtests\fR = [\fI'filename'\fR [,...]] -.ad -.sp .6 -.RS 4n -Specify a list of \fIfilenames\fR for this test group. Only the basename of the -absolute path is required. This option is only valid for test groups, and each -\fIfilename\fR must be single quoted. -.RE -.sp -.ne 2 -.na -\fBtimeout\fR = \fIn\fR -.ad -.sp .6 -.RS 4n -A timeout value of \fIn\fR seconds. -.RE -.sp -.ne 2 -.na -\fBuser\fR = \fIusername\fR -.ad -.sp .6 -.RS 4n -Execute the test or test group as \fIusername\fR. -.RE - -.SH OPTIONS -.sp -.LP -The following options are available for the \fBrun\fR command. -.sp -.ne 2 -.na -\fB-c\fR \fIrunfile\fR -.ad -.RS 6n -Specify a \fIrunfile\fR to be consumed by the run command. -.RE - -.ne 2 -.na -\fB-d\fR -.ad -.RS 6n -Dry run mode. Execute no tests, but print a description of each test that would -have been run. -.RE - -.ne 2 -.na -\fB-g\fR -.ad -.RS 6n +.It Sy pre No = Ar script +Run +.Ar script +prior to the test or test group. +.It Sy pre_user No = Ar username +Execute the pre script as +.Ar username . +.It Sy post No = Ar script +Run +.Ar script +after the test or test group. +.It Sy post_user No = Ar username +Execute the post script as +.Ar username . +.It Sy quiet No = Sy True Ns | Ns Sy False +If +.Sy True , +only the results summary is printed to standard out. +.It Sy tests No = [ Ns Ar 'filename' , No … ] +Specify a list of +.Ar filenames +for this test group. +Only the basename of the absolute path is required. +This option is only valid for test groups, and each +.Ar filename +must be single quoted. +.It Sy timeout No = Ar n +A timeout value of +.Ar n +seconds. +.It Sy user No = Ar username +Execute the test or test group as +.Ar username . +.El +. +.Sh OPTIONS +.Bl -tag -width "-o outputdir" +.It Fl c Ar runfile +Specify a +.Ar runfile +to be consumed by the run command. +.It Fl d +Dry run mode. +Execute no tests, but print a description of each test that would have been run. +.It Fl g Create test groups from any directories found while searching for tests. -.RE - -.ne 2 -.na -\fB-o\fR \fIoutputdir\fR -.ad -.RS 6n +.It Fl o Ar outputdir Specify the directory in which to write test results. -.RE - -.ne 2 -.na -\fB-p\fR \fIscript\fR -.ad -.RS 6n -Run \fIscript\fR prior to any test or test group. -.RE - -.ne 2 -.na -\fB-P\fR \fIscript\fR -.ad -.RS 6n -Run \fIscript\fR after any test or test group. -.RE - -.ne 2 -.na -\fB-q\fR -.ad -.RS 6n +.It Fl p Ar script +Run +.Ar script +prior to any test or test group. +.It Fl P Ar script +Run +.Ar script +after any test or test group. +.It Fl q Print only the results summary to the standard output. -.RE - -.ne 2 -.na -\fB-s\fR \fIscript\fR -.ad -.RS 6n -Run \fIscript\fR as a failsafe after any test is killed. -.RE - -.ne 2 -.na -\fB-S\fR \fIusername\fR -.ad -.RS 6n -Execute the failsafe script as \fIusername\fR. -.RE - -.ne 2 -.na -\fB-t\fR \fIn\fR -.ad -.RS 6n -Specify a timeout value of \fIn\fR seconds per test. -.RE - -.ne 2 -.na -\fB-u\fR \fIusername\fR -.ad -.RS 6n -Execute tests or test groups as \fIusername\fR. -.RE - -.ne 2 -.na -\fB-w\fR \fIrunfile\fR -.ad -.RS 6n -Specify the name of the \fIrunfile\fR to create. -.RE - -.ne 2 -.na -\fB-x\fR \fIusername\fR -.ad -.RS 6n -Execute the pre script as \fIusername\fR. -.RE - -.ne 2 -.na -\fB-X\fR \fIusername\fR -.ad -.RS 6n -Execute the post script as \fIusername\fR. -.RE - -.SH EXAMPLES -.LP -\fBExample 1\fR Running ad-hoc tests. -.sp -.LP -This example demonstrates the simplest invocation of \fBrun\fR. - -.sp -.in +2 -.nf -% \fBrun my-tests\fR +.It Fl s Ar script +Run +.Ar script +as a failsafe after any test is killed. +.It Fl S Ar username +Execute the failsafe script as +.Ar username . +.It Fl t Ar n +Specify a timeout value of +.Ar n +seconds per test. +.It Fl u Ar username +Execute tests or test groups as +.Ar username . +.It Fl w Ar runfile +Specify the name of the +.Ar runfile +to create. +.It Fl x Ar username +Execute the pre script as +.Ar username . +.It Fl X Ar username +Execute the post script as +.Ar username . +.El +. +.Sh EXAMPLES +.Bl -tag -width "-h" +.It Sy Example 1 : No Running ad-hoc tests. +This example demonstrates the simplest invocation of +.Nm . +.Bd -literal +.No % Nm run Ar my-tests Test: /home/jkennedy/my-tests/test-01 [00:02] [PASS] Test: /home/jkennedy/my-tests/test-02 [00:04] [PASS] Test: /home/jkennedy/my-tests/test-03 [00:01] [PASS] @@ -328,20 +267,14 @@ PASS 3 Running Time: 00:00:07 Percent passed: 100.0% Log directory: /var/tmp/test_results/20120923T180654 -.fi -.in -2 - -.LP -\fBExample 2\fR Creating a \fIrunfile\fR for future use. -.sp -.LP -This example demonstrates creating a \fIrunfile\fR with non default options. - -.sp -.in +2 -.nf -% \fBrun -p setup -x root -g -w new-tests.run new-tests\fR -% \fBcat new-tests.run\fR +.Ed +.It Sy Example 2 : No Creating a Ar runfile No for future use. +This example demonstrates creating a +.Ar runfile +with non-default options. +.Bd -literal +.No % Nm run Fl p Ar setup Fl x Ar root Fl g Fl w Ar new-tests.run Ar new-tests +.No % Nm cat Pa new-tests.run [DEFAULT] pre = setup post_user = @@ -354,33 +287,8 @@ outputdir = /var/tmp/test_results [/home/jkennedy/new-tests] tests = ['test-01', 'test-02', 'test-03'] -.fi -.in -2 - -.SH EXIT STATUS -.sp -.LP -The following exit values are returned: -.sp -.ne 2 -.na -\fB\fB0\fR\fR -.ad -.sp .6 -.RS 4n -Successful completion. -.RE -.sp -.ne 2 -.na -\fB\fB1\fR\fR -.ad -.sp .6 -.RS 4n -An error occurred. -.RE - -.SH SEE ALSO -.sp -.LP -\fBsudo\fR(1m) +.Ed +.El +. +.Sh SEE ALSO +.Xr sudo 1m diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/draid/draid.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/draid/draid.c index 861c6ba1a8c..57261348b3c 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/cmd/draid/draid.c +++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/draid/draid.c @@ -626,7 +626,7 @@ eval_decluster(draid_map_t *map, double *worst_ratiop, double *avg_ratiop) uint64_t faults = nspares; /* - * Score groupwidths up to 19. This value was choosen as the + * Score groupwidths up to 19. This value was chosen as the * largest reasonable width (16d+3p). dRAID pools may be still * be created with wider stripes but they are not considered in * this analysis in order to optimize for the most common cases. @@ -727,7 +727,7 @@ eval_maps(uint64_t children, int passes, uint64_t *map_seed, * Consider maps with a lower worst_ratio to be of higher * quality. Some maps may have a lower avg_ratio but they * are discarded since they might include some particularly - * imbalanced permuations. The average is tracked to in + * imbalanced permutations. The average is tracked to in * order to get a sense of the average permutation quality. */ eval_decluster(map, &worst_ratio, &avg_ratio); @@ -1194,8 +1194,8 @@ draid_dump(int argc, char *argv[]) } /* - * Print all of the mappings as a C formated draid_map_t array. This table - * is found in the module/zcommon/zfs_draid.c file and is the definative + * Print all of the mappings as a C formatted draid_map_t array. This table + * is found in the module/zcommon/zfs_draid.c file and is the definitive * source for all mapping used by dRAID. It cannot be updated without * changing the dRAID on disk format. */ diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/file_check/file_check.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/file_check/file_check.c index 5df0ea735bf..3d3db753f3d 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/cmd/file_check/file_check.c +++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/file_check/file_check.c @@ -40,7 +40,6 @@ main(int argc, char **argv) long i, n; unsigned char fillchar = DATA; int bigbuffersize = BIGBUFFERSIZE; - int64_t read_count = 0; /* * Validate arguments @@ -78,8 +77,6 @@ main(int argc, char **argv) exit(1); } } - - read_count += n; } while (n == bigbuffersize); return (0); diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/file_write/file_write.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/file_write/file_write.c index 45d296db43c..60893c34fbc 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/cmd/file_write/file_write.c +++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/file_write/file_write.c @@ -44,7 +44,7 @@ static unsigned char bigbuffer[BIGBUFFERSIZE]; static void usage(char *); /* - * psudo-randomize the buffer + * pseudo-randomize the buffer */ static void randomize_buffer(int block_size) { int i; diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/xattrtest/xattrtest.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/xattrtest/xattrtest.c index 8c4cb88955e..0b68126c032 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/cmd/xattrtest/xattrtest.c +++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/xattrtest/xattrtest.c @@ -262,7 +262,7 @@ run_process(const char *path, char *argv[]) pid_t pid; int rc, devnull_fd; - pid = vfork(); + pid = fork(); if (pid == 0) { devnull_fd = open("/dev/null", O_WRONLY); diff --git a/sys/contrib/openzfs/tests/zfs-tests/include/libtest.shlib b/sys/contrib/openzfs/tests/zfs-tests/include/libtest.shlib index bd77bae7d96..5a360bd5e70 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/include/libtest.shlib +++ b/sys/contrib/openzfs/tests/zfs-tests/include/libtest.shlib @@ -1897,13 +1897,11 @@ function zfs_zones_setup #zone_name zone_root zone_ip block_device_wait # - # If current system support slog, add slog device for pool + # Add slog device for pool # - if verify_slog_support ; then - typeset sdevs="$TEST_BASE_DIR/sdev1 $TEST_BASE_DIR/sdev2" - log_must mkfile $MINVDEVSIZE $sdevs - log_must zpool add $pool_name log mirror $sdevs - fi + typeset sdevs="$TEST_BASE_DIR/sdev1 $TEST_BASE_DIR/sdev2" + log_must mkfile $MINVDEVSIZE $sdevs + log_must zpool add $pool_name log mirror $sdevs # this isn't supported just yet. # Create a filesystem. In order to add this to @@ -3067,28 +3065,6 @@ function random_get _random_get "$#" "$@" } -# -# Detect if the current system support slog -# -function verify_slog_support -{ - typeset dir=$TEST_BASE_DIR/disk.$$ - typeset pool=foo.$$ - typeset vdev=$dir/a - typeset sdev=$dir/b - - mkdir -p $dir - mkfile $MINVDEVSIZE $vdev $sdev - - typeset -i ret=0 - if ! zpool create -n $pool $vdev log $sdev > /dev/null 2>&1; then - ret=1 - fi - rm -r $dir - - return $ret -} - # # The function will generate a dataset name with specific length # $1, the length of the name @@ -3577,16 +3553,11 @@ function wait_replacing #pool # Wait for a pool to be scrubbed # # $1 pool name -# $2 number of seconds to wait (optional) -# -# Returns true when pool has been scrubbed, or false if there's a timeout or if -# no scrub was done. # function wait_scrubbed { typeset pool=${1:-$TESTPOOL} - while true ; do - is_pool_scrubbed $pool && break + while ! is_pool_scrubbed $pool ; do sleep 1 done } @@ -3705,8 +3676,8 @@ function zed_start # run ZED in the background and redirect foreground logging # output to $ZED_LOG. log_must truncate -s 0 $ZED_DEBUG_LOG - log_must eval "zed -vF -d $ZEDLET_DIR -p $ZEDLET_DIR/zed.pid -P $PATH" \ - "-s $ZEDLET_DIR/state 2>$ZED_LOG &" + log_must eval "zed -vF -d $ZEDLET_DIR -P $PATH" \ + "-s $ZEDLET_DIR/state -j 1 2>$ZED_LOG &" fi return 0 @@ -3722,14 +3693,13 @@ function zed_stop fi log_note "Stopping ZED" - if [[ -f ${ZEDLET_DIR}/zed.pid ]]; then - zedpid=$(<${ZEDLET_DIR}/zed.pid) - kill $zedpid - while ps -p $zedpid > /dev/null; do - sleep 1 - done - rm -f ${ZEDLET_DIR}/zed.pid - fi + while true; do + zedpids="$(pgrep -x zed)" + [ "$?" -ne 0 ] && break + + log_must kill $zedpids + sleep 1 + done return 0 } diff --git a/sys/contrib/openzfs/tests/zfs-tests/include/tunables.cfg b/sys/contrib/openzfs/tests/zfs-tests/include/tunables.cfg index 1cef60b0d63..a1b75a48292 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/include/tunables.cfg +++ b/sys/contrib/openzfs/tests/zfs-tests/include/tunables.cfg @@ -25,6 +25,7 @@ CHECKSUM_EVENTS_PER_SECOND checksum_events_per_second zfs_checksum_events_per_se COMMIT_TIMEOUT_PCT commit_timeout_pct zfs_commit_timeout_pct COMPRESSED_ARC_ENABLED compressed_arc_enabled zfs_compressed_arc_enabled CONDENSE_INDIRECT_COMMIT_ENTRY_DELAY_MS condense.indirect_commit_entry_delay_ms zfs_condense_indirect_commit_entry_delay_ms +CONDENSE_INDIRECT_OBSOLETE_PCT condense.indirect_obsolete_pct zfs_condense_indirect_obsolete_pct CONDENSE_MIN_MAPPING_BYTES condense.min_mapping_bytes zfs_condense_min_mapping_bytes DBUF_CACHE_MAX_BYTES dbuf_cache.max_bytes dbuf_cache_max_bytes DEADMAN_CHECKTIME_MS deadman.checktime_ms zfs_deadman_checktime_ms diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/atime/root_atime_off.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/atime/root_atime_off.ksh index 2fbf06b1377..7eb2ed93728 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/atime/root_atime_off.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/atime/root_atime_off.ksh @@ -53,7 +53,7 @@ log_onexit cleanup # # Create $TESTFILE, snapshot and clone. -# Same as 002 except that atime applies to root dataset (ZoL#8675). +# Same as 002 except that atime applies to root dataset (OpenZFS#8675). # setup_snap_clone reset_atime diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/atime/root_atime_on.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/atime/root_atime_on.ksh index 3976523b0b1..44d471a2128 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/atime/root_atime_on.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/atime/root_atime_on.ksh @@ -52,7 +52,7 @@ log_onexit cleanup # # Create $TESTFILE, snapshot and clone. -# Same as 001 except that atime/relatime applies to root dataset (ZoL#8675). +# Same as 001 except that atime/relatime applies to root dataset (OpenZFS#8675). # setup_snap_clone reset_atime diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/atime/root_relatime_on.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/atime/root_relatime_on.ksh index c919e9f2988..120129425af 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/atime/root_relatime_on.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/atime/root_relatime_on.ksh @@ -53,7 +53,7 @@ log_onexit cleanup # # Create $TESTFILE, snapshot and clone. -# Same as 003 except that atime/relatime applies to root dataset (ZoL#8675). +# Same as 003 except that atime/relatime applies to root dataset (OpenZFS#8675). # setup_snap_clone reset_atime diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_checksum.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_checksum.ksh index eeff6575f0f..4f661262a72 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_checksum.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_checksum.ksh @@ -50,6 +50,7 @@ listing=$(ls -i $init_data) set -A array $listing obj=${array[0]} log_note "file $init_data has object number $obj" +sync_pool $TESTPOOL output=$(zdb -ddddddbbbbbb $TESTPOOL/$TESTFS $obj 2> /dev/null \ |grep -m 1 "L0 DVA" |head -n1) diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_objset_id.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_objset_id.ksh index f0c1076c97b..d23cc43c90e 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_objset_id.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_objset_id.ksh @@ -57,6 +57,7 @@ listing=$(ls -i $init_data) set -A array $listing obj=${array[0]} log_note "file $init_data has object number $obj" +sync_pool $TESTPOOL output=$(zdb -d $TESTPOOL/$TESTFS) objset_id=$(echo $output | awk '{split($0,array,",")} END{print array[2]}' | diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_clone_livelist_dedup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_clone_livelist_dedup.ksh new file mode 100755 index 00000000000..5f356967a45 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_clone_livelist_dedup.ksh @@ -0,0 +1,88 @@ +#!/bin/ksh -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.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. +# + +# +# Copyright (c) 2021 by Delphix. All rights reserved. +# + +# DESCRIPTION +# Verify zfs destroy test for clones with livelists that contain +# dedup blocks. This test is a baseline regression test created +# to ensure that past bugs that we've encountered between dedup +# and the livelist logic don't resurface. + +# STRATEGY +# 1. Create a clone from a test filesystem and enable dedup. +# 2. Write some data and create a livelist. +# 3. Copy the data within the clone to create dedup blocks. +# 4. Remove some of the dedup data to create multiple free +# entries for the same block pointers. +# 5. Process all the livelist entries by destroying the clone. + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/cli_root/zfs_destroy/zfs_destroy_common.kshlib + +function cleanup +{ + log_must zfs destroy -Rf $TESTPOOL/$TESTFS1 + # Reset the minimum percent shared to 75 + set_tunable32 LIVELIST_MIN_PERCENT_SHARED $ORIGINAL_MIN_SHARED +} + +function test_dedup +{ + # Set a small percent shared threshold so the livelist is not disabled + set_tunable32 LIVELIST_MIN_PERCENT_SHARED 10 + clone_dataset $TESTFS1 snap $TESTCLONE + + # Enable dedup + log_must zfs set dedup=on $TESTPOOL/$TESTCLONE + + # Create some data to be deduped + log_must dd if=/dev/urandom of="/$TESTPOOL/$TESTCLONE/data" bs=512 count=10k + + # Create dedup blocks + # Note: We sync before and after so all dedup blocks belong to the + # same TXG, otherwise they won't look identical to the livelist + # iterator due to their logical birth TXG being different. + log_must zpool sync $TESTPOOL + log_must cp /$TESTPOOL/$TESTCLONE/data /$TESTPOOL/$TESTCLONE/data-dup-0 + log_must cp /$TESTPOOL/$TESTCLONE/data /$TESTPOOL/$TESTCLONE/data-dup-1 + log_must cp /$TESTPOOL/$TESTCLONE/data /$TESTPOOL/$TESTCLONE/data-dup-2 + log_must cp /$TESTPOOL/$TESTCLONE/data /$TESTPOOL/$TESTCLONE/data-dup-3 + log_must zpool sync $TESTPOOL + check_livelist_exists $TESTCLONE + + # Introduce "double frees" + # We want to introduce consecutive FREEs of the same block as this + # was what triggered past panics. + # Note: Similarly to the previouys step we sync before and after our + # our deletions so all the entries end up in the same TXG. + log_must zpool sync $TESTPOOL + log_must rm /$TESTPOOL/$TESTCLONE/data-dup-2 + log_must rm /$TESTPOOL/$TESTCLONE/data-dup-3 + log_must zpool sync $TESTPOOL + check_livelist_exists $TESTCLONE + + log_must zfs destroy $TESTPOOL/$TESTCLONE + check_livelist_gone +} + +ORIGINAL_MIN_SHARED=$(get_tunable LIVELIST_MIN_PERCENT_SHARED) + +log_onexit cleanup +log_must zfs create $TESTPOOL/$TESTFS1 +log_must mkfile 5m /$TESTPOOL/$TESTFS1/atestfile +log_must zfs snapshot $TESTPOOL/$TESTFS1@snap +test_dedup + +log_pass "Clone's livelist processes dedup blocks as expected." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_destroy_015_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_destroy_015_pos.ksh index f399ad27063..fb29e4acda1 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_destroy_015_pos.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_destroy/zfs_destroy_015_pos.ksh @@ -19,7 +19,7 @@ # snapshots from the same datasets # # STRATEGY -# 1. Create multiple snapshots for the same datset +# 1. Create multiple snapshots for the same dataset # 2. Run zfs destroy for these snapshots for a mix of valid and # invalid snapshot names # 3. Run zfs destroy for snapshots from different datasets and diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_001_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_001_pos.ksh index eeae5390f08..3547fb76c69 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_001_pos.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_001_pos.ksh @@ -27,6 +27,7 @@ # # Copyright (c) 2016 by Delphix. All rights reserved. +# Copyright (c) 2021 Matt Fiddaman # . $STF_SUITE/tests/functional/cli_root/zfs_get/zfs_get_common.kshlib @@ -72,7 +73,8 @@ typeset all_props=("${zfs_props[@]}" \ "${zfs_props_os[@]}" \ "${userquota_props[@]}") typeset dataset=($TESTPOOL/$TESTCTR $TESTPOOL/$TESTFS $TESTPOOL/$TESTVOL \ - $TESTPOOL/$TESTFS@$TESTSNAP $TESTPOOL/$TESTVOL@$TESTSNAP) + $TESTPOOL/$TESTFS@$TESTSNAP $TESTPOOL/$TESTVOL@$TESTSNAP + $TESTPOOL/$TESTFS@$TESTSNAP1 $TESTPOOL/$TESTCLONE) typeset bookmark_props=(creation) typeset bookmark=($TESTPOOL/$TESTFS#$TESTBKMARK $TESTPOOL/$TESTVOL#$TESTBKMARK) @@ -102,6 +104,7 @@ function check_return_value if [[ $item == $p ]]; then ((found += 1)) + cols=$(echo $line | awk '{print NF}') break fi done < $TESTDIR/$TESTFILE0 @@ -109,6 +112,9 @@ function check_return_value if ((found == 0)); then log_fail "'zfs get $opt $props $dst' return " \ "error message.'$p' haven't been found." + elif [[ "$opt" == "-p" ]] && ((cols != 4)); then + log_fail "'zfs get $opt $props $dst' returned " \ + "$cols columns instead of 4." fi done @@ -123,6 +129,10 @@ log_onexit cleanup create_snapshot $TESTPOOL/$TESTFS $TESTSNAP create_snapshot $TESTPOOL/$TESTVOL $TESTSNAP +# Create second snapshot and clone it +create_snapshot $TESTPOOL/$TESTFS $TESTSNAP1 +create_clone $TESTPOOL/$TESTFS@$TESTSNAP1 $TESTPOOL/$TESTCLONE + # Create filesystem and volume's bookmark create_bookmark $TESTPOOL/$TESTFS $TESTSNAP $TESTBKMARK create_bookmark $TESTPOOL/$TESTVOL $TESTSNAP $TESTBKMARK diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_common.kshlib b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_common.kshlib index d8cb9af028e..9b4eecf3712 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_common.kshlib +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_common.kshlib @@ -26,6 +26,7 @@ # # Copyright (c) 2016 by Delphix. All rights reserved. +# Copyright (c) 2021 Matt Fiddaman # . $STF_SUITE/include/libtest.shlib @@ -87,8 +88,8 @@ function gen_option_str # $elements $prefix $separator $counter } # -# Cleanup the volume snapshot, filesystem snapshot, volume bookmark, and -# filesystem bookmark that were created for this test case. +# Cleanup the volume snapshot, filesystem snapshots, clone, volume bookmark, +# and filesystem bookmark that were created for this test case. # function cleanup { @@ -97,6 +98,11 @@ function cleanup datasetexists $TESTPOOL/$TESTFS@$TESTSNAP && \ destroy_snapshot $TESTPOOL/$TESTFS@$TESTSNAP + datasetexists $TESTPOOL/$TESTCLONE && \ + destroy_clone $TESTPOOL/$TESTCLONE + datasetexists $TESTPOOL/$TESTFS@$TESTSNAP1 && \ + destroy_snapshot $TESTPOOL/$TESTFS@$TESTSNAP1 + bkmarkexists $TESTPOOL/$TESTVOL#$TESTBKMARK && \ destroy_bookmark $TESTPOOL/$TESTVOL#$TESTBKMARK bkmarkexists $TESTPOOL/$TESTFS#$TESTBKMARK && \ diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/HEXKEY b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/HEXKEY new file mode 100644 index 00000000000..95ed1c051a2 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/HEXKEY @@ -0,0 +1 @@ +000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/Makefile.am index 06b4239a6d9..7dfec435ce7 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/Makefile.am +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/Makefile.am @@ -5,10 +5,14 @@ dist_pkgdata_SCRIPTS = \ zfs_load-key.ksh \ zfs_load-key_all.ksh \ zfs_load-key_file.ksh \ + zfs_load-key_https.ksh \ zfs_load-key_location.ksh \ zfs_load-key_noop.ksh \ zfs_load-key_recursive.ksh dist_pkgdata_DATA = \ zfs_load-key.cfg \ - zfs_load-key_common.kshlib + zfs_load-key_common.kshlib \ + PASSPHRASE \ + HEXKEY \ + RAWKEY diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/PASSPHRASE b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/PASSPHRASE new file mode 100644 index 00000000000..f3097ab1308 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/PASSPHRASE @@ -0,0 +1 @@ +password diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/RAWKEY b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/RAWKEY new file mode 100644 index 00000000000..f2d4cbf581c --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/RAWKEY @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ No newline at end of file diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/cleanup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/cleanup.ksh index 79cd6e9f908..d397bcf4e9f 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/cleanup.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/cleanup.ksh @@ -26,5 +26,7 @@ # . $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib +cleanup_https default_cleanup diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/setup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/setup.ksh index 6a9af3bc28c..6cc5528ce5d 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/setup.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/setup.ksh @@ -26,7 +26,10 @@ # . $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib DISK=${DISKS%% *} -default_setup $DISK +default_setup_noexit $DISK +setup_https +log_pass diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg index 90d9f63f1db..cc1e3b33054 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg @@ -17,6 +17,9 @@ # Copyright (c) 2017 Datto, Inc. All rights reserved. # +# $PASSPHRASE, $HEXKEY, and $RAWKEY must be kept in sync +# with the corresponding files in this directory + export PASSPHRASE="password" export PASSPHRASE1="password1" export PASSPHRASE2="password2" @@ -24,3 +27,31 @@ export HEXKEY="000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F" export HEXKEY1="201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A090807060504030201" export RAWKEY="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" export RAWKEY1="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + +export SSL_CA_CERT_FILE="/$TESTPOOL/snakeoil.crt" +export HTTPS_PORT_FILE="/$TESTPOOL/snakeoil.port" +export HTTPS_HOSTNAME="localhost" +export HTTPS_PORT= +export HTTPS_BASE_URL= + +function get_https_port +{ + if [ -z "$HTTPS_PORT" ]; then + read -r HTTPS_PORT < "$HTTPS_PORT_FILE" || return + fi + + echo "$HTTPS_PORT" +} + +function get_https_base_url +{ + if [ -z "$HTTPS_BASE_URL" ]; then + HTTPS_BASE_URL="https://$HTTPS_HOSTNAME:$(get_https_port)" || { + typeset ret=$? + HTTPS_BASE_URL= + return $ret + } + fi + + echo "$HTTPS_BASE_URL" +} diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_all.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_all.ksh index 5e331fd1200..96710bf9a80 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_all.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_all.ksh @@ -39,6 +39,8 @@ function cleanup { datasetexists $TESTPOOL/$TESTFS1 && \ log_must zfs destroy $TESTPOOL/$TESTFS1 + datasetexists $TESTPOOL/$TESTFS2 && \ + log_must zfs destroy $TESTPOOL/$TESTFS2 datasetexists $TESTPOOL/zvol && log_must zfs destroy $TESTPOOL/zvol poolexists $TESTPOOL1 && log_must destroy_pool $TESTPOOL1 } @@ -50,6 +52,9 @@ log_must eval "echo $PASSPHRASE1 > /$TESTPOOL/pkey" log_must zfs create -o encryption=on -o keyformat=passphrase \ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1 +log_must zfs create -o encryption=on -o keyformat=passphrase \ + -o keylocation=$(get_https_base_url)/PASSPHRASE $TESTPOOL/$TESTFS2 + log_must zfs create -V 64M -o encryption=on -o keyformat=passphrase \ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/zvol @@ -60,6 +65,9 @@ log_must zpool create -O encryption=on -O keyformat=passphrase \ log_must zfs unmount $TESTPOOL/$TESTFS1 log_must zfs unload-key $TESTPOOL/$TESTFS1 +log_must zfs unmount $TESTPOOL/$TESTFS2 +log_must zfs unload-key $TESTPOOL/$TESTFS2 + log_must zfs unload-key $TESTPOOL/zvol log_must zfs unmount $TESTPOOL1 @@ -70,8 +78,10 @@ log_must zfs load-key -a log_must key_available $TESTPOOL1 log_must key_available $TESTPOOL/zvol log_must key_available $TESTPOOL/$TESTFS1 +log_must key_available $TESTPOOL/$TESTFS2 log_must zfs mount $TESTPOOL1 log_must zfs mount $TESTPOOL/$TESTFS1 +log_must zfs mount $TESTPOOL/$TESTFS2 log_pass "'zfs load-key -a' loads keys for all datasets" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib index d9066f9cbf5..f7461437c61 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib @@ -99,3 +99,66 @@ function verify_origin return 0 } + +function setup_https +{ + log_must openssl req -x509 -newkey rsa:4096 -sha256 -days 1 -nodes -keyout "/$TESTPOOL/snakeoil.key" -out "$SSL_CA_CERT_FILE" -subj "/CN=$HTTPS_HOSTNAME" + + python3 -uc " +import http.server, ssl, sys, os, time, random + +sys.stdin.close() + +httpd, err, port = None, None, None +for i in range(1, 100): + port = random.randint(0xC000, 0xFFFF) # ephemeral range + try: + httpd = http.server.HTTPServer(('$HTTPS_HOSTNAME', port), http.server.SimpleHTTPRequestHandler) + break + except: + err = sys.exc_info()[1] + time.sleep(i / 100) +if not httpd: + raise err + +with open('$HTTPS_PORT_FILE', 'w') as portf: + print(port, file=portf) + +httpd.socket = ssl.wrap_socket(httpd.socket, server_side=True, keyfile='/$TESTPOOL/snakeoil.key', certfile='$SSL_CA_CERT_FILE', ssl_version=ssl.PROTOCOL_TLS) + +os.chdir('$STF_SUITE/tests/functional/cli_root/zfs_load-key') + +with open('/$TESTPOOL/snakeoil.pid', 'w') as pidf: + if os.fork() != 0: + os._exit(0) + print(os.getpid(), file=pidf) + +sys.stdout.close() +sys.stderr.close() +try: + sys.stdout = sys.stderr = open('/tmp/ZTS-snakeoil.log', 'w', buffering=1) # line +except: + sys.stdout = sys.stderr = open('/dev/null', 'w') + +print('{} start on {}'.format(os.getpid(), port)) +httpd.serve_forever() +" || log_fail + + typeset https_pid= + for d in $(seq 0 0.1 5); do + read -r https_pid 2>/dev/null < "/$TESTPOOL/snakeoil.pid" && [ -n "$https_pid" ] && break + sleep "$d" + done + [ -z "$https_pid" ] && log_fail "Couldn't start HTTPS server" + log_note "Started HTTPS server as $https_pid on port $(get_https_port)" +} + +function cleanup_https +{ + typeset https_pid= + read -r https_pid 2>/dev/null < "/$TESTPOOL/snakeoil.pid" || return 0 + + log_must kill "$https_pid" + cat /tmp/ZTS-snakeoil.log + rm -f "/$TESTPOOL/snakeoil.pid" "/tmp/ZTS-snakeoil.log" +} diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_https.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_https.ksh new file mode 100755 index 00000000000..cac9c414032 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_https.ksh @@ -0,0 +1,78 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.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. +# +# CDDL HEADER END +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib + +# +# DESCRIPTION: +# 'zfs load-key' should load a dataset's key from an https:// URL, +# but fail to do so if the domain doesn't exist or the file 404s. +# +# STRATEGY: +# 1. Try to create a dataset pointing to an RFC6761-guaranteed unresolvable domain, +# one to the sshd port (which will be either unoccupied (ECONNREFUSED) +# or have sshd on it ("wrong version number")). +# and one pointing to an URL that will always 404. +# 2. Create encrypted datasets with keylocation=https://address +# 3. Unmount the datasets and unload their keys +# 4. Attempt to load the keys +# 5. Verify the keys are loaded +# 6. Attempt to mount the datasets +# + +verify_runnable "both" + +function cleanup +{ + for fs in "$TESTFS1" "$TESTFS2" "$TESTFS3"; do + datasetexists $TESTPOOL/$fs && \ + log_must zfs destroy $TESTPOOL/$fs + done +} +log_onexit cleanup + +log_assert "'zfs load-key' should load a key from a file" + +log_mustnot zfs create -o encryption=on -o keyformat=passphrase \ + -o keylocation=https://invalid./where-ever $TESTPOOL/$TESTFS1 + +log_mustnot zfs create -o encryption=on -o keyformat=passphrase \ + -o keylocation=https://$HTTPS_HOSTNAME:22 $TESTPOOL/$TESTFS1 + +log_mustnot zfs create -o encryption=on -o keyformat=passphrase \ + -o keylocation=$(get_https_base_url)/ENOENT $TESTPOOL/$TESTFS1 + +log_must zfs create -o encryption=on -o keyformat=passphrase \ + -o keylocation=$(get_https_base_url)/PASSPHRASE $TESTPOOL/$TESTFS1 + +log_must zfs create -o encryption=on -o keyformat=hex \ + -o keylocation=$(get_https_base_url)/HEXKEY $TESTPOOL/$TESTFS2 + +log_must zfs create -o encryption=on -o keyformat=raw \ + -o keylocation=$(get_https_base_url)/RAWKEY $TESTPOOL/$TESTFS3 + +for fs in "$TESTFS1" "$TESTFS2" "$TESTFS3"; do + log_must zfs unmount $TESTPOOL/$fs + log_must zfs unload-key $TESTPOOL/$fs +done +for fs in "$TESTFS1" "$TESTFS2" "$TESTFS3"; do + log_must zfs load-key $TESTPOOL/$fs + log_must key_available $TESTPOOL/$fs + log_must zfs mount $TESTPOOL/$fs +done + +log_pass "'zfs load-key' loads a key from a file" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_location.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_location.ksh index d0b1cdb20ec..2b0a6a292ee 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_location.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_location.ksh @@ -70,4 +70,9 @@ log_must eval "echo $PASSPHRASE | zfs load-key -L prompt $TESTPOOL/$TESTFS1" log_must key_available $TESTPOOL/$TESTFS1 log_must verify_keylocation $TESTPOOL/$TESTFS1 "file://$key_location" +log_must zfs unload-key $TESTPOOL/$TESTFS1 +log_must zfs load-key -L $(get_https_base_url)/PASSPHRASE $TESTPOOL/$TESTFS1 +log_must key_available $TESTPOOL/$TESTFS1 +log_must verify_keylocation $TESTPOOL/$TESTFS1 "file://$key_location" + log_pass "'zfs load-key -L' overrides keylocation with provided value" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_recursive.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_recursive.ksh index 7385b69cf5f..0435383ad0c 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_recursive.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_recursive.ksh @@ -52,15 +52,21 @@ log_must zfs create -o encryption=on -o keyformat=passphrase \ log_must zfs create -o keyformat=passphrase \ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1/child +log_must zfs create -o keyformat=passphrase \ + -o keylocation=$(get_https_base_url)/PASSPHRASE $TESTPOOL/$TESTFS1/child/child + log_must zfs unmount $TESTPOOL/$TESTFS1 +log_must zfs unload-key $TESTPOOL/$TESTFS1/child/child log_must zfs unload-key $TESTPOOL/$TESTFS1/child log_must zfs unload-key $TESTPOOL/$TESTFS1 log_must zfs load-key -r $TESTPOOL log_must key_available $TESTPOOL/$TESTFS1 log_must key_available $TESTPOOL/$TESTFS1/child +log_must key_available $TESTPOOL/$TESTFS1/child/child log_must zfs mount $TESTPOOL/$TESTFS1 log_must zfs mount $TESTPOOL/$TESTFS1/child +log_must zfs mount $TESTPOOL/$TESTFS1/child/child log_pass "'zfs load-key -r' recursively loads keys" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_test_race.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_test_race.ksh index 135b31354f0..3a5793d0707 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_test_race.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_test_race.ksh @@ -87,10 +87,11 @@ log_must zfs set mountpoint=$MNTPT $TESTPOOL2 # At this point, layout of datasets in two pools will look like below. # Previously, on next `zfs mount -a`, pthreads assigned to TESTFS1 and TESTFS2 -# could race, and TESTFS2 usually (actually always) won in ZoL. Note that the -# problem is how two or more threads could initially be assigned to the same -# top level directory, not this specific layout. This layout is just an example -# that can reproduce race, and is also the layout reported in #8833. +# could race, and TESTFS2 usually (actually always) won in OpenZFS. +# Note that the problem is how two or more threads could initially be assigned +# to the same top level directory, not this specific layout. +# This layout is just an example that can reproduce race, +# and is also the layout reported in #8833. # # NAME MOUNTED MOUNTPOINT # ---------------------------------------------- diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_receive/receive-o-x_props_override.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_receive/receive-o-x_props_override.ksh index 6f897a96f3e..2d3c15c62fc 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_receive/receive-o-x_props_override.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_receive/receive-o-x_props_override.ksh @@ -259,16 +259,21 @@ log_must zfs destroy -r -f $orig log_must zfs destroy -r -f $dest # -# 3.7 Verify we can't receive a send stream overriding or excluding properties -# invalid for the dataset type unless the stream it's recursive, in which -# case only the appropriate properties are set on the destination. -# +# 3.7 Verify we can receive a send stream excluding but not overriding +# properties invalid for the dataset type, in which case only the +# appropriate properties are set on the destination. log_must zfs create -V 128K -s $orig log_must zfs snapshot $orig@snap1 log_must eval "zfs send $orig@snap1 > $streamfile_full" -log_mustnot eval "zfs receive -x atime $dest < $streamfile_full" log_mustnot eval "zfs receive -o atime=off $dest < $streamfile_full" +log_mustnot eval "zfs receive -o atime=off -x canmount $dest < $streamfile_full" +log_must eval "zfs receive -x atime -x canmount $dest < $streamfile_full" +log_must eval "check_prop_source $dest type volume -" +log_must eval "check_prop_source $dest atime - -" +log_must eval "check_prop_source $dest canmount - -" log_must_busy zfs destroy -r -f $orig +log_must_busy zfs destroy -r -f $dest +# Recursive sends also accept (and ignore) such overrides log_must zfs create $orig log_must zfs create -V 128K -s $origsub log_must zfs snapshot -r $orig@snap1 diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_send/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_send/Makefile.am index 9a492f32311..25c7065670f 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_send/Makefile.am +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_send/Makefile.am @@ -13,7 +13,8 @@ dist_pkgdata_SCRIPTS = \ zfs_send_encrypted_unloaded.ksh \ zfs_send_raw.ksh \ zfs_send_sparse.ksh \ - zfs_send-b.ksh + zfs_send-b.ksh \ + zfs_send_skip_missing.ksh dist_pkgdata_DATA = \ zfs_send.cfg diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_skip_missing.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_skip_missing.ksh new file mode 100755 index 00000000000..b367cef9c4a --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_skip_missing.ksh @@ -0,0 +1,77 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2016, loli10K. All rights reserved. +# Copyright (c) 2021, Pablo Correa Gómez. All rights reserved. +# + +. $STF_SUITE/tests/functional/cli_root/cli_common.kshlib +. $STF_SUITE/tests/functional/cli_root/zfs_send/zfs_send.cfg + +# +# DESCRIPTION: +# Verify 'zfs send' will avoid sending replication send +# streams when we're missing snapshots in the dataset +# hierarchy, unless -s|--skip-missing provided +# +# STRATEGY: +# 1. Create a parent and child fs and then only snapshot the parent +# 2. Verify sending with replication will fail +# 3. Verify sending with skip-missing will print a warning but succeed +# + +verify_runnable "both" + +function cleanup +{ + snapexists $SNAP && log_must zfs destroy -f $SNAP + + datasetexists $PARENT && log_must zfs destroy -rf $PARENT + + [[ -e $WARNF ]] && log_must rm -f $WARNF + rm -f $TEST_BASE_DIR/devnull +} + +log_assert "Verify 'zfs send -Rs' works as expected." +log_onexit cleanup + +PARENT=$TESTPOOL/parent +CHILD=$PARENT/child +SNAP=$PARENT@snap +WARNF=$TEST_BASE_DIR/warn.2 + +log_note "Verify 'zfs send -R' fails to generate replication stream"\ + " for datasets created before" + +log_must zfs create $PARENT +log_must zfs create $CHILD +log_must zfs snapshot $SNAP +log_mustnot eval "zfs send -R $SNAP >$TEST_BASE_DIR/devnull" + +log_note "Verify 'zfs send -Rs' warns about missing snapshots, "\ + "but still succeeds" + +log_must eval "zfs send -Rs $SNAP 2> $WARNF >$TEST_BASE_DIR/devnull" +log_must eval "[[ -s $WARNF ]]" + +log_pass "Verify 'zfs send -Rs' works as expected." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_keylocation.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_keylocation.ksh index 0d2e7ab8f29..7a6bf75dace 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_keylocation.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_keylocation.ksh @@ -46,11 +46,12 @@ function cleanup { datasetexists $TESTPOOL/$TESTFS1 && \ log_must zfs destroy -r $TESTPOOL/$TESTFS1 + cleanup_https } log_onexit cleanup -log_assert "Key location can only be 'prompt' or a file path for encryption" \ - "roots, and 'none' for unencrypted volumes" +log_assert "Key location can only be 'prompt', 'file://', or 'https://'" \ + "for encryption roots, and 'none' for unencrypted volumes" log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey" @@ -64,19 +65,15 @@ log_must zfs create -o encryption=on -o keyformat=passphrase \ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1 log_mustnot zfs set keylocation=none $TESTPOOL/$TESTFS1 -if true; then - log_mustnot zfs set keylocation=/$TESTPOOL/pkey $TESTPOOL/$TESTFS1 -else - ### SOON: ### - # file:///$TESTPOOL/pkey and /$TESTPOOL/pkey are equivalent on FreeBSD - # thanks to libfetch. Eventually we want to make the other platforms - # work this way as well, either by porting libfetch or by other means. - log_must zfs set keylocation=/$TESTPOOL/pkey $TESTPOOL/$TESTFS1 -fi +log_mustnot zfs set keylocation=/$TESTPOOL/pkey $TESTPOOL/$TESTFS1 log_must zfs set keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1 log_must verify_keylocation $TESTPOOL/$TESTFS1 "file:///$TESTPOOL/pkey" +setup_https +log_must zfs set keylocation=$(get_https_base_url)/PASSPHRASE $TESTPOOL/$TESTFS1 +log_must verify_keylocation $TESTPOOL/$TESTFS1 "$(get_https_base_url)/PASSPHRASE" + log_must zfs set keylocation=prompt $TESTPOOL/$TESTFS1 log_must verify_keylocation $TESTPOOL/$TESTFS1 "prompt" @@ -97,5 +94,5 @@ log_mustnot zfs set keylocation=/$TESTPOOL/pkey $TESTPOOL/$TESTFS1/child log_must verify_keylocation $TESTPOOL/$TESTFS1/child "none" -log_pass "Key location can only be 'prompt' or a file path for encryption" \ - "roots, and 'none' for unencrypted volumes" +log_pass "Key location can only be 'prompt', 'file://', or 'https://'" \ + "for encryption roots, and 'none' for unencrypted volumes" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/zpool_add_dryrun_output.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/zpool_add_dryrun_output.ksh index dbf81262ee1..73dec924032 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/zpool_add_dryrun_output.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/zpool_add_dryrun_output.ksh @@ -36,7 +36,7 @@ typeset VDEV_PREFIX="$TEST_BASE_DIR/filedev" # STRATEGY: # 1. Create different storage pools, use -n to add devices to the pool and # verify the output is as expected. -# 2. Create a pool whith a hole vdev and verify it's not listed with add -n. +# 2. Create a pool with a hole vdev and verify it's not listed with add -n. # typeset -a dev=( @@ -163,7 +163,7 @@ for (( i=0; i < ${#tests[@]}; i+=1 )); do log_must destroy_pool "$TESTPOOL" done -# Make sure hole vdevs are skiped in output. +# Make sure hole vdevs are skipped in output. log_must eval "zpool create '$TESTPOOL' '${dev[0]}' log '${dev[1]}' \ cache '${dev[2]}'" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_events/zpool_events_duplicates.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_events/zpool_events_duplicates.ksh index d4194a5b8f5..595eacf5b4b 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_events/zpool_events_duplicates.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_events/zpool_events_duplicates.ksh @@ -102,8 +102,7 @@ function do_dup_test # Read the file a few times to generate some # duplicate errors of the same blocks - # shellcheck disable=SC2034 - for i in {1..15}; do + for _ in {1..15}; do dd if=$FILEPATH of=/dev/null bs=128K > /dev/null 2>&1 done log_must zinject -c all diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/misc/arc_summary_001_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/misc/arc_summary_001_pos.ksh index a445fbb48cf..befbea986e1 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/misc/arc_summary_001_pos.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/misc/arc_summary_001_pos.ksh @@ -48,6 +48,9 @@ else set -A args "" "-a" "-d" "-p 1" fi +# Without this, the below checks aren't going to work the way we hope... +set -o pipefail + typeset -i i=0 while [[ $i -lt ${#args[*]} ]]; do log_must eval "arc_summary ${args[i]} > /dev/null" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zfs_list/zfs_list_002_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zfs_list/zfs_list_002_pos.ksh index 382b2cb7f0b..4951097aca5 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zfs_list/zfs_list_002_pos.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zfs_list/zfs_list_002_pos.ksh @@ -74,7 +74,7 @@ else fi # -# datsets ordered by checksum options (note, Orange, Carrot & Banana have the +# datasets ordered by checksum options (note, Orange, Carrot & Banana have the # same checksum options, so ZFS should revert to sorting them alphabetically by # name) # diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_iostat/zpool_iostat_-c_homedir.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_iostat/zpool_iostat_-c_homedir.ksh index 5cb50fde6fb..22450d89dfd 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_iostat/zpool_iostat_-c_homedir.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_iostat/zpool_iostat_-c_homedir.ksh @@ -30,7 +30,7 @@ # # STRATEGY: # 1. Change HOME to /var/tmp -# 2. Make a simple script that echos a key value pair +# 2. Make a simple script that echoes a key value pair # in /var/tmp/.zpool.d # 3. Make sure it can be run with -c # 4. Remove the script we created diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_iostat/zpool_iostat_-c_searchpath.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_iostat/zpool_iostat_-c_searchpath.ksh index 1197ea2d117..11f51350af5 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_iostat/zpool_iostat_-c_searchpath.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_iostat/zpool_iostat_-c_searchpath.ksh @@ -30,7 +30,7 @@ # # STRATEGY: # 1. Set ZPOOL_SCRIPTS_PATH to contain a couple of non-default dirs -# 2. Make a simple script that echos a key value pair in each dir +# 2. Make a simple script that echoes a key value pair in each dir # 3. Make sure scripts can be run with -c # 4. Remove the scripts we created diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_status/zpool_status_-c_homedir.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_status/zpool_status_-c_homedir.ksh index 4cc3deb6dad..5363043a830 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_status/zpool_status_-c_homedir.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_status/zpool_status_-c_homedir.ksh @@ -30,7 +30,7 @@ # # STRATEGY: # 1. Change HOME to /var/tmp -# 2. Make a simple script that echos a key value pair +# 2. Make a simple script that echoes a key value pair # in /var/tmp/.zpool.d # 3. Make sure it can be run with -c # 4. Remove the script we created diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_status/zpool_status_-c_searchpath.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_status/zpool_status_-c_searchpath.ksh index a075b9a0c18..3f64fdf1a70 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_status/zpool_status_-c_searchpath.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_user/zpool_status/zpool_status_-c_searchpath.ksh @@ -30,7 +30,7 @@ # # STRATEGY: # 1. Set ZPOOL_SCRIPTS_PATH to contain a couple of non-default dirs -# 2. Make a simple script that echos a key value pair in each dir +# 2. Make a simple script that echoes a key value pair in each dir # 3. Make sure scripts can be run with -c # 4. Remove the scripts we created diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/deadman/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/deadman/Makefile.am index 7b70ca09df5..097f23e8840 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/deadman/Makefile.am +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/deadman/Makefile.am @@ -1,5 +1,6 @@ pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/deadman dist_pkgdata_SCRIPTS = \ + deadman_ratelimit.ksh \ deadman_sync.ksh \ deadman_zio.ksh diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/deadman/deadman_ratelimit.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/deadman/deadman_ratelimit.ksh new file mode 100755 index 00000000000..469117a56cc --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/deadman/deadman_ratelimit.ksh @@ -0,0 +1,78 @@ +#!/bin/ksh -p +# +# 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 2021 iXsystems, Inc. +# + +# DESCRIPTION: +# Verify spa deadman events are rate limited +# +# STRATEGY: +# 1. Reduce the zfs_slow_io_events_per_second to 1. +# 2. Reduce the zfs_deadman_ziotime_ms to 1ms. +# 3. Write data to a pool and read it back. +# 4. Verify deadman events have been produced at a reasonable rate. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/deadman/deadman.cfg + +verify_runnable "both" + +function cleanup +{ + zinject -c all + default_cleanup_noexit + + set_tunable64 SLOW_IO_EVENTS_PER_SECOND $OLD_SLOW_IO_EVENTS + set_tunable64 DEADMAN_ZIOTIME_MS $ZIOTIME_DEFAULT +} + +log_assert "Verify spa deadman events are rate limited" +log_onexit cleanup + +OLD_SLOW_IO_EVENTS=$(get_tunable SLOW_IO_EVENTS_PER_SECOND) +log_must set_tunable64 SLOW_IO_EVENTS_PER_SECOND 1 +log_must set_tunable64 DEADMAN_ZIOTIME_MS 1 + +# Create a new pool in order to use the updated deadman settings. +default_setup_noexit $DISK1 +log_must zpool events -c + +mntpnt=$(get_prop mountpoint $TESTPOOL/$TESTFS) +log_must file_write -b 1048576 -c 8 -o create -d 0 -f $mntpnt/file +log_must zpool export $TESTPOOL +log_must zpool import $TESTPOOL +log_must zinject -d $DISK1 -D 5:1 $TESTPOOL +log_must dd if=$mntpnt/file of=$TEST_BASE_DIR/devnull oflag=sync + +events=$(zpool events $TESTPOOL | grep -c ereport.fs.zfs.deadman) +log_note "events=$events" +if [ "$events" -lt 1 ]; then + log_fail "Expect >= 1 deadman events, $events found" +fi +if [ "$events" -gt 10 ]; then + log_fail "Expect <= 10 deadman events, $events found" +fi + +log_pass "Verify spa deadman events are rate limited" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/deadman/deadman_sync.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/deadman/deadman_sync.ksh index 5d803af85be..b0b03f5d523 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/deadman/deadman_sync.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/deadman/deadman_sync.ksh @@ -73,7 +73,11 @@ log_must zinject -c all log_must zpool sync # Log txg sync times for reference and the zpool event summary. -log_must cat /proc/spl/kstat/zfs/$TESTPOOL/txgs +if is_freebsd; then + log_must sysctl -n kstat.zfs.$TESTPOOL.txgs +else + log_must cat /proc/spl/kstat/zfs/$TESTPOOL/txgs +fi log_must zpool events # Verify at least 5 deadman events were logged. The first after 5 seconds, diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/.gitignore b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/.gitignore new file mode 100644 index 00000000000..ed5af03a109 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/.gitignore @@ -0,0 +1 @@ +/zed_fd_spill-zedlet diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/Makefile.am index e1fe490812b..92ce5dbc382 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/Makefile.am +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/Makefile.am @@ -1,11 +1,18 @@ +include $(top_srcdir)/config/Rules.am + pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/events dist_pkgdata_SCRIPTS = \ setup.ksh \ cleanup.ksh \ events_001_pos.ksh \ events_002_pos.ksh \ - zed_rc_filter.ksh + zed_rc_filter.ksh \ + zed_fd_spill.ksh dist_pkgdata_DATA = \ events.cfg \ events_common.kshlib + +pkgexecdir = $(pkgdatadir) +pkgexec_PROGRAMS = zed_fd_spill-zedlet +zed_fd_spill_zedlet_SOURCES = zed_fd_spill-zedlet.c diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/cleanup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/cleanup.ksh index 4905342b713..699bc282334 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/cleanup.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/cleanup.ksh @@ -26,6 +26,6 @@ . $STF_SUITE/include/libtest.shlib -zed_cleanup all-debug.sh all-syslog.sh +zed_cleanup all-debug.sh all-syslog.sh all-dumpfds default_cleanup diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/events_002_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/events_002_pos.ksh index 586eaa9e1fd..af2be33dbc7 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/events_002_pos.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/events_002_pos.ksh @@ -50,11 +50,11 @@ function cleanup [[ -f $file ]] && rm -f $file done - log_must rm -f $TMP_EVENTS_ZED $TMP_EVENTS_ZED + log_must rm -f $TMP_EVENTS_ZED log_must zed_stop } -log_assert "Verify ZED handles missed events on when starting" +log_assert "Verify ZED handles missed events when starting" log_onexit cleanup log_must truncate -s $MINVDEVSIZE $VDEV1 $VDEV2 diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_fd_spill-zedlet.c b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_fd_spill-zedlet.c new file mode 100644 index 00000000000..c072f906d23 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_fd_spill-zedlet.c @@ -0,0 +1,36 @@ +/* + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +int main(void) { + if (fork()) { + int err; + wait(&err); + return (err); + } + + char buf[64]; + sprintf(buf, "/tmp/zts-zed_fd_spill-logdir/%d", getppid()); + dup2(creat(buf, 0644), STDOUT_FILENO); + + snprintf(buf, sizeof (buf), "/proc/%d/fd", getppid()); + execlp("ls", "ls", buf, NULL); + _exit(127); +} diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_fd_spill.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_fd_spill.ksh new file mode 100755 index 00000000000..8736a7fdf7e --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_fd_spill.ksh @@ -0,0 +1,77 @@ +#!/bin/ksh -p +# +# 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 +# + +# DESCRIPTION: +# Verify ZEDLETs only inherit the fds specified in the manpage +# +# STRATEGY: +# 1. Inject a ZEDLET that dumps the fds it gets to a file. +# 2. Generate some events. +# 3. Read back the generated files and assert that there is no fd past 3, +# and there are exactly 4 fds. + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/events/events_common.kshlib + +verify_runnable "both" + +function cleanup +{ + log_must rm -rf "$logdir" + log_must rm "/tmp/zts-zed_fd_spill-logdir" + log_must zed_stop +} + +log_assert "Verify ZEDLETs inherit only the fds specified" +log_onexit cleanup + +logdir="$(mktemp -d)" +log_must ln -s "$logdir" /tmp/zts-zed_fd_spill-logdir + +self="$(readlink -f "$0")" +log_must ln -s "${self%/*}/zed_fd_spill-zedlet" "${ZEDLET_DIR}/all-dumpfds" + +log_must zpool events -c +log_must zed_stop +log_must zed_start + +log_must truncate -s 0 $ZED_DEBUG_LOG +log_must zpool scrub $TESTPOOL +log_must zfs set compression=off $TESTPOOL/$TESTFS +log_must wait_scrubbed $TESTPOOL +log_must file_wait $ZED_DEBUG_LOG 3 + +if [ -n "$(find "$logdir" -maxdepth 0 -empty)" ]; then + log_fail "Our ZEDLET didn't run!" +fi +log_must awk ' + !/^[0123]$/ { + print FILENAME ": " $0 + err=1 + } + END { + exit err + } +' "$logdir"/* +wc -l "$logdir"/* | log_must awk '$1 != "4" && $2 != "total" {print; exit 1}' + +log_pass "ZED doesn't leak fds to ZEDLETs" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_rc_filter.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_rc_filter.ksh index 44652ee4cf1..0bef0ef1f96 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_rc_filter.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_rc_filter.ksh @@ -49,6 +49,7 @@ log_assert "Verify zpool sub-commands generate expected events" log_onexit cleanup log_must zpool events -c +log_must zed_stop log_must zed_start # Backup our zed.rc diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh index 0abe1e2ce59..86916bf906f 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh @@ -30,7 +30,7 @@ # STRATEGY: # 1. Create a pool # 2. Simulate physical removal of one device -# 3. Verify the device is unvailable +# 3. Verify the device is unavailable # 4. Reattach the device # 5. Verify the device is onlined # 6. Repeat the same tests with a spare device: @@ -104,7 +104,7 @@ do log_must mkfile 1m $mntpnt/file log_must zpool sync $TESTPOOL - # 3. Verify the device is unvailable. + # 3. Verify the device is unavailable. log_must wait_vdev_state $TESTPOOL $removedev "UNAVAIL" # 4. Reattach the device diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_big_rewind.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_big_rewind.ksh index f915d2ad418..7e523ef9087 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_big_rewind.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_big_rewind.ksh @@ -52,6 +52,7 @@ fragment_after_checkpoint_and_verify log_must zpool export $NESTEDPOOL log_must zpool import -d $FILEDISKDIR --rewind-to-checkpoint $NESTEDPOOL -log_must zdb $NESTEDPOOL +log_must zpool export $NESTEDPOOL +log_must zdb -e -p $FILEDISKDIR $NESTEDPOOL log_pass "Rewind to checkpoint on a stressed pool." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_capacity.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_capacity.ksh index 15afc4adf4b..b6d34307b3f 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_capacity.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_capacity.ksh @@ -80,13 +80,14 @@ log_mustnot dd if=/dev/urandom of=$NESTEDFS0FILE bs=1M count=300 # log_must zpool list $NESTEDPOOL -log_must zdb -kc $NESTEDPOOL - log_must zpool export $NESTEDPOOL +log_must zdb -e -p $FILEDISKDIR -kc $NESTEDPOOL + log_must zpool import -d $FILEDISKDIR --rewind-to-checkpoint $NESTEDPOOL log_must [ "$(head -c 100 $NESTEDFS0FILE)" = "$FILE0INTRO" ] -log_must zdb $NESTEDPOOL +log_must zpool export $NESTEDPOOL +log_must zdb -e -p $FILEDISKDIR $NESTEDPOOL log_pass "Do not reuse checkpointed space at low capacity." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_discard_busy.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_discard_busy.ksh index ae099ff270f..f970935f5bd 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_discard_busy.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_discard_busy.ksh @@ -104,7 +104,8 @@ set_tunable64 SPA_DISCARD_MEMORY_LIMIT 16777216 nested_wait_discard_finish -log_must zdb $NESTEDPOOL +log_must zpool export $NESTEDPOOL +log_must zdb -e -p $FILEDISKDIR $NESTEDPOOL log_pass "Can export/import but not rewind/checkpoint/discard or " \ "change pool's config while discarding." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/pool_checkpoint.kshlib b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/pool_checkpoint.kshlib index ea6c03e9d59..bb8bab6cdf4 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/pool_checkpoint.kshlib +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_checkpoint/pool_checkpoint.kshlib @@ -154,13 +154,18 @@ function setup_nested_pools function cleanup_nested_pool { - log_must zpool destroy $NESTEDPOOL + if poolexists $NESTEDPOOL; then + log_must zpool destroy $NESTEDPOOL + fi + log_must rm -f $FILEDISKS } function cleanup_test_pool { - log_must zpool destroy $TESTPOOL + if poolexists $TESTPOOL; then + log_must zpool destroy $TESTPOOL + fi # # We always clear the labels of all disks diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_names/pool_names_002_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_names/pool_names_002_neg.ksh index 0c96e1999ef..4b6744563d0 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_names/pool_names_002_neg.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/pool_names/pool_names_002_neg.ksh @@ -106,14 +106,14 @@ do done log_note "Verify invalid pool names fail" -set -A POOLNAME "c0t0d0s0" "c0t0d0" "c0t0d19" "c0t50000E0108D279d0" \ +set -A POOLNAME \ "mirror" "raidz" ",," ",,,,,,,,,,,,,,,,,,,,,,,,," \ "2222222222222222222" "mirror_pool" "raidz_pool" \ "mirror-pool" "raidz-pool" "spare" "spare_pool" \ "spare-pool" "raidz1-" "raidz2:" ":aaa" "-bbb" "_ccc" ".ddd" -if verify_slog_support ; then - POOLNAME[${#POOLNAME[@]}]='log' -fi + +POOLNAME[${#POOLNAME[@]}]='log' + typeset -i i=0 while ((i < ${#POOLNAME[@]})); do log_mustnot zpool create -m $TESTDIR ${POOLNAME[$i]} $DISK diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/Makefile.am index 7b85d6a1bf5..42c11c4aa95 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/Makefile.am +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/Makefile.am @@ -2,9 +2,11 @@ pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/redundancy dist_pkgdata_SCRIPTS = \ setup.ksh \ cleanup.ksh \ + redundancy_draid.ksh \ redundancy_draid1.ksh \ redundancy_draid2.ksh \ redundancy_draid3.ksh \ + redundancy_draid_damaged.ksh \ redundancy_draid_spare1.ksh \ redundancy_draid_spare2.ksh \ redundancy_draid_spare3.ksh \ diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy.kshlib b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy.kshlib index 26ded8720d1..baee8269b1e 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy.kshlib +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy.kshlib @@ -146,7 +146,7 @@ function setup_test_env typeset -i i=0 typeset file=$TESTDIR/file typeset -i limit - (( limit = $(get_prop available $pool) / 4 )) + (( limit = $(get_prop available $pool) / 2 )) while true ; do [[ $(get_prop available $pool) -lt $limit ]] && break @@ -162,6 +162,7 @@ function setup_test_env function refill_test_env { log_note "Re-filling the filesystem ..." + typeset pool=$1 typeset -i ret=0 typeset -i i=0 typeset mntpnt @@ -217,8 +218,13 @@ function is_data_valid { typeset pool=$1 + log_must zpool scrub -w $pool + record_data $pool $PST_RECORD_FILE if ! diff $PRE_RECORD_FILE $PST_RECORD_FILE > /dev/null 2>&1; then + log_must cat $PRE_RECORD_FILE + log_must cat $PST_RECORD_FILE + diff -u $PRE_RECORD_FILE $PST_RECORD_FILE return 1 fi @@ -237,7 +243,7 @@ function get_vdevs #pool cnt typeset -i cnt=$2 typeset all_devs=$(zpool iostat -v $pool | awk '{print $1}'| \ - egrep -v "^pool$|^capacity$|^mirror$|^raidz1$|^raidz2$|---" | \ + egrep -v "^pool$|^capacity$|^mirror$|^raidz1$|^raidz2$|^raidz3$|^draid1.*|^draid2.*|^draid3.*|---" | \ egrep -v "/old$|^$pool$") typeset -i i=0 typeset vdevs @@ -265,9 +271,9 @@ function replace_missing_devs typeset vdev for vdev in $@; do - log_must gnudd if=/dev/zero of=$vdev \ - bs=1024k count=$(($MINDEVSIZE / (1024 * 1024))) \ - oflag=fdatasync + log_must dd if=/dev/zero of=$vdev \ + bs=1024k count=$((MINVDEVSIZE / (1024 * 1024))) \ + conv=fdatasync log_must zpool replace -wf $pool $vdev $vdev done } @@ -286,19 +292,19 @@ function damage_devs typeset -i cnt=$2 typeset label="$3" typeset vdevs - typeset -i bs_count=$((64 * 1024)) + typeset -i bs_count=$(((MINVDEVSIZE / 1024) - 4096)) vdevs=$(get_vdevs $pool $cnt) typeset dev if [[ -n $label ]]; then for dev in $vdevs; do - dd if=/dev/zero of=$dev seek=512 bs=1024 \ + log_must dd if=/dev/zero of=$dev seek=512 bs=1024 \ count=$bs_count conv=notrunc >/dev/null 2>&1 done else for dev in $vdevs; do - dd if=/dev/zero of=$dev bs=1024 count=$bs_count \ - conv=notrunc >/dev/null 2>&1 + log_must dd if=/dev/zero of=$dev bs=1024 \ + count=$bs_count conv=notrunc >/dev/null 2>&1 done fi diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid.ksh new file mode 100755 index 00000000000..8015e682c89 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid.ksh @@ -0,0 +1,248 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2020 by vStack. All rights reserved. +# Copyright (c) 2021 by Delphix. All rights reserved. +# Copyright (c) 2021 by Lawrence Livermore National Security, LLC. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/redundancy/redundancy.kshlib + +# +# DESCRIPTION: +# dRAID should provide redundancy +# +# STRATEGY: +# 1. Create block device files for the test draid pool +# 2. For each parity value [1..3] +# - create draid pool +# - fill it with some directories/files +# - verify self-healing by overwriting devices +# - verify resilver by replacing devices +# - verify scrub by zeroing devices +# - destroy the draid pool + +typeset -r devs=6 +typeset -r dev_size_mb=512 + +typeset -a disks + +prefetch_disable=$(get_tunable PREFETCH_DISABLE) + +function cleanup +{ + poolexists "$TESTPOOL" && destroy_pool "$TESTPOOL" + + for i in {0..$devs}; do + rm -f "$TEST_BASE_DIR/dev-$i" + done + + set_tunable32 PREFETCH_DISABLE $prefetch_disable +} + +function test_selfheal # +{ + typeset pool=$1 + typeset nparity=$2 + typeset dir=$3 + + log_must zpool export $pool + + for (( i=0; i<$nparity; i=i+1 )); do + log_must dd conv=notrunc if=/dev/zero of=$dir/dev-$i \ + bs=1M seek=4 count=$(($dev_size_mb-4)) + done + + log_must zpool import -o cachefile=none -d $dir $pool + + typeset mntpnt=$(get_prop mountpoint $pool/fs) + log_must find $mntpnt -type f -exec cksum {} + >> /dev/null 2>&1 + log_must check_pool_status $pool "errors" "No known data errors" + + # + # Scrub the pool because the find command will only self-heal blocks + # from the files which were read. Before overwriting additional + # devices we need to repair all of the blocks in the pool. + # + log_must zpool scrub -w $pool + log_must check_pool_status $pool "errors" "No known data errors" + + log_must zpool clear $pool + + log_must zpool export $pool + + for (( i=$nparity; i<$nparity*2; i=i+1 )); do + log_must dd conv=notrunc if=/dev/zero of=$dir/dev-$i \ + bs=1M seek=4 count=$(($dev_size_mb-4)) + done + + log_must zpool import -o cachefile=none -d $dir $pool + + typeset mntpnt=$(get_prop mountpoint $pool/fs) + log_must find $mntpnt -type f -exec cksum {} + >> /dev/null 2>&1 + log_must check_pool_status $pool "errors" "No known data errors" + + log_must zpool scrub -w $pool + log_must check_pool_status $pool "errors" "No known data errors" + + log_must zpool clear $pool +} + +function test_resilver # +{ + typeset pool=$1 + typeset nparity=$2 + typeset dir=$3 + + for (( i=0; i<$nparity; i=i+1 )); do + log_must zpool offline $pool $dir/dev-$i + done + + log_must zpool export $pool + + for (( i=0; i<$nparity; i=i+1 )); do + log_must zpool labelclear -f $dir/dev-$i + done + + log_must zpool import -o cachefile=none -d $dir $pool + + for (( i=0; i<$nparity; i=i+1 )); do + log_must zpool replace -fw $pool $dir/dev-$i + done + + log_must check_pool_status $pool "errors" "No known data errors" + resilver_cksum=$(cksum_pool $pool) + if [[ $resilver_cksum != 0 ]]; then + log_must zpool status -v $pool + log_fail "resilver cksum errors: $resilver_cksum" + fi + + log_must zpool clear $pool + + for (( i=$nparity; i<$nparity*2; i=i+1 )); do + log_must zpool offline $pool $dir/dev-$i + done + + log_must zpool export $pool + + for (( i=$nparity; i<$nparity*2; i=i+1 )); do + log_must zpool labelclear -f $dir/dev-$i + done + + log_must zpool import -o cachefile=none -d $dir $pool + + for (( i=$nparity; i<$nparity*2; i=i+1 )); do + log_must zpool replace -fw $pool $dir/dev-$i + done + + log_must check_pool_status $pool "errors" "No known data errors" + resilver_cksum=$(cksum_pool $pool) + if [[ $resilver_cksum != 0 ]]; then + log_must zpool status -v $pool + log_fail "resilver cksum errors: $resilver_cksum" + fi + + log_must zpool clear $pool +} + +function test_scrub # +{ + typeset pool=$1 + typeset nparity=$2 + typeset dir=$3 + + log_must zpool export $pool + + for (( i=0; i<$nparity; i=i+1 )); do + dd conv=notrunc if=/dev/zero of=$dir/dev-$i \ + bs=1M seek=4 count=$(($dev_size_mb-4)) + done + + log_must zpool import -o cachefile=none -d $dir $pool + + log_must zpool scrub -w $pool + log_must check_pool_status $pool "errors" "No known data errors" + + log_must zpool clear $pool + + log_must zpool export $pool + + for (( i=$nparity; i<$nparity*2; i=i+1 )); do + dd conv=notrunc if=/dev/zero of=$dir/dev-$i \ + bs=1M seek=4 count=$(($dev_size_mb-4)) + done + + log_must zpool import -o cachefile=none -d $dir $pool + + log_must zpool scrub -w $pool + log_must check_pool_status $pool "errors" "No known data errors" + + log_must zpool clear $pool +} + +log_onexit cleanup + +log_must set_tunable32 PREFETCH_DISABLE 1 + +# Disk files which will be used by pool +for i in {0..$(($devs - 1))}; do + device=$TEST_BASE_DIR/dev-$i + log_must truncate -s ${dev_size_mb}M $device + disks[${#disks[*]}+1]=$device +done + +# Disk file which will be attached +log_must truncate -s 512M $TEST_BASE_DIR/dev-$devs + +for nparity in 1 2 3; do + raid=draid$nparity + dir=$TEST_BASE_DIR + + log_must zpool create -f -o cachefile=none $TESTPOOL $raid ${disks[@]} + log_must zfs set primarycache=metadata $TESTPOOL + + log_must zfs create $TESTPOOL/fs + log_must fill_fs /$TESTPOOL/fs 1 512 100 1024 R + + log_must zfs create -o compress=on $TESTPOOL/fs2 + log_must fill_fs /$TESTPOOL/fs2 1 512 100 1024 R + + log_must zfs create -o compress=on -o recordsize=8k $TESTPOOL/fs3 + log_must fill_fs /$TESTPOOL/fs3 1 512 100 1024 R + + typeset pool_size=$(get_pool_prop size $TESTPOOL) + + log_must zpool export $TESTPOOL + log_must zpool import -o cachefile=none -d $dir $TESTPOOL + + log_must check_pool_status $TESTPOOL "errors" "No known data errors" + + test_selfheal $TESTPOOL $nparity $dir + test_resilver $TESTPOOL $nparity $dir + test_scrub $TESTPOOL $nparity $dir + + log_must zpool destroy "$TESTPOOL" +done + +log_pass "draid redundancy test succeeded." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid3.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid3.ksh index bddd150d0c9..d4c823ed9b3 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid3.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid3.ksh @@ -42,7 +42,7 @@ # 2. Create draid3 pool based on the virtual disk files. # 3. Fill the filesystem with directories and files. # 4. Record all the files and directories checksum information. -# 5. Damaged at most two of the virtual disk files. +# 5. Damaged at most three of the virtual disk files. # 6. Verify the data is correct to prove draid3 can withstand 3 devices # are failing. # diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_damaged.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_damaged.ksh new file mode 100755 index 00000000000..6796cc78a1b --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_damaged.ksh @@ -0,0 +1,153 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2021 by Lawrence Livermore National Security, LLC. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/redundancy/redundancy.kshlib + +# +# DESCRIPTION: +# When sequentially resilvering a dRAID pool with multiple vdevs +# that contain silent damage a sequential resilver should never +# introduce additional unrecoverable damage. +# +# STRATEGY: +# 1. Create block device files for the test draid pool +# 2. For each parity value [1..3] +# - create draid pool +# - fill it with some directories/files +# - overwrite the maximum number of repairable devices +# - sequentially resilver each overwritten device one at a time; +# the device will not be correctly repaired because the silent +# damage on the other vdevs will cause the parity calculations +# to generate incorrect data for the resilvering vdev. +# - verify that only the resilvering devices had invalid data +# written and that a scrub is still able to repair the pool +# - destroy the draid pool +# + +typeset -r devs=7 +typeset -r dev_size_mb=512 + +typeset -a disks + +prefetch_disable=$(get_tunable PREFETCH_DISABLE) +rebuild_scrub_enabled=$(get_tunable REBUILD_SCRUB_ENABLED) + +function cleanup +{ + poolexists "$TESTPOOL" && destroy_pool "$TESTPOOL" + + for i in {0..$devs}; do + rm -f "$TEST_BASE_DIR/dev-$i" + done + + set_tunable32 PREFETCH_DISABLE $prefetch_disable + set_tunable32 REBUILD_SCRUB_ENABLED $rebuild_scrub_enabled +} + +function test_sequential_resilver # +{ + typeset pool=$1 + typeset nparity=$2 + typeset dir=$3 + + log_must zpool export $pool + + for (( i=0; i<$nparity; i=i+1 )); do + log_must dd conv=notrunc if=/dev/zero of=$dir/dev-$i \ + bs=1M seek=4 count=$(($dev_size_mb-4)) + done + + log_must zpool import -o cachefile=none -d $dir $pool + + for (( i=0; i<$nparity; i=i+1 )); do + spare=draid${nparity}-0-$i + log_must zpool replace -fsw $pool $dir/dev-$i $spare + done + + log_must zpool scrub -w $pool + + # When only a single child was overwritten the sequential resilver + # can fully repair the damange from parity and the scrub will have + # nothing to repair. When multiple children are silently damaged + # the sequential resilver will calculate the wrong data since only + # the parity information is used and it cannot be verified with + # the checksum. However, since only the resilvering devices are + # written to with the bad data a subsequent scrub will be able to + # fully repair the pool. + # + if [[ $nparity == 1 ]]; then + log_must check_pool_status $pool "scan" "repaired 0B" + else + log_mustnot check_pool_status $pool "scan" "repaired 0B" + fi + + log_must check_pool_status $pool "errors" "No known data errors" + log_must check_pool_status $pool "scan" "with 0 errors" +} + +log_onexit cleanup + +log_must set_tunable32 PREFETCH_DISABLE 1 +log_must set_tunable32 REBUILD_SCRUB_ENABLED 0 + +# Disk files which will be used by pool +for i in {0..$(($devs - 1))}; do + device=$TEST_BASE_DIR/dev-$i + log_must truncate -s ${dev_size_mb}M $device + disks[${#disks[*]}+1]=$device +done + +# Disk file which will be attached +log_must truncate -s 512M $TEST_BASE_DIR/dev-$devs + +for nparity in 1 2 3; do + raid=draid${nparity}:${nparity}s + dir=$TEST_BASE_DIR + + log_must zpool create -f -o cachefile=none $TESTPOOL $raid ${disks[@]} + log_must zfs set primarycache=metadata $TESTPOOL + + log_must zfs create $TESTPOOL/fs + log_must fill_fs /$TESTPOOL/fs 1 512 100 1024 R + + log_must zfs create -o compress=on $TESTPOOL/fs2 + log_must fill_fs /$TESTPOOL/fs2 1 512 100 1024 R + + log_must zfs create -o compress=on -o recordsize=8k $TESTPOOL/fs3 + log_must fill_fs /$TESTPOOL/fs3 1 512 100 1024 R + + log_must zpool export $TESTPOOL + log_must zpool import -o cachefile=none -d $dir $TESTPOOL + + log_must check_pool_status $TESTPOOL "errors" "No known data errors" + + test_sequential_resilver $TESTPOOL $nparity $dir + + log_must zpool destroy "$TESTPOOL" +done + +log_pass "draid damaged device(s) test succeeded." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_spare1.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_spare1.ksh index 3b7951596db..8acee156795 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_spare1.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_spare1.ksh @@ -40,7 +40,15 @@ log_assert "Verify resilver to dRAID distributed spares" -log_onexit cleanup +function cleanup_tunable +{ + log_must set_tunable32 REBUILD_SCRUB_ENABLED 1 + cleanup +} + +log_onexit cleanup_tunable + +log_must set_tunable32 REBUILD_SCRUB_ENABLED 0 for replace_mode in "healing" "sequential"; do @@ -74,32 +82,15 @@ for replace_mode in "healing" "sequential"; do log_must check_vdev_state $spare_vdev "ONLINE" log_must check_hotspare_state $TESTPOOL $spare_vdev "INUSE" log_must zpool detach $TESTPOOL $fault_vdev - - resilver_cksum=$(cksum_pool $TESTPOOL) - if [[ $resilver_cksum != 0 ]]; then - log_must zpool status -v $TESTPOOL - log_fail "$replace_mode resilver " - "cksum errors: $resilver_cksum" - fi - - if [[ "$replace_mode" = "healing" ]]; then - log_must zpool scrub $TESTPOOL - fi - - log_must wait_scrubbed $TESTPOOL + log_must verify_pool $TESTPOOL log_must check_pool_status $TESTPOOL "scan" "repaired 0B" log_must check_pool_status $TESTPOOL "scan" "with 0 errors" - scrub_cksum=$(cksum_pool $TESTPOOL) - if [[ $scrub_cksum != 0 ]]; then - log_must zpool status -v $TESTPOOL - log_fail "scrub cksum errors: $scrub_cksum" - fi - (( i += 1 )) done log_must is_data_valid $TESTPOOL + log_must check_pool_status $TESTPOOL "errors" "No known data errors" cleanup done diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_spare3.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_spare3.ksh index 587a1be0a66..28e8e3c6d70 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_spare3.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_spare3.ksh @@ -114,6 +114,9 @@ for replace_mode in "healing" "sequential"; do log_must zpool detach $TESTPOOL $BASEDIR/vdev7 log_must check_vdev_state $TESTPOOL draid1-0-0 "ONLINE" log_must check_hotspare_state $TESTPOOL draid1-0-0 "INUSE" + log_must verify_pool $TESTPOOL + log_must check_pool_status $TESTPOOL "scan" "repaired 0B" + log_must check_pool_status $TESTPOOL "scan" "with 0 errors" # Distributed spare in mirror with original device faulted log_must zpool offline -f $TESTPOOL $BASEDIR/vdev8 @@ -122,6 +125,9 @@ for replace_mode in "healing" "sequential"; do log_must check_vdev_state $TESTPOOL spare-8 "DEGRADED" log_must check_vdev_state $TESTPOOL draid1-0-1 "ONLINE" log_must check_hotspare_state $TESTPOOL draid1-0-1 "INUSE" + log_must verify_pool $TESTPOOL + log_must check_pool_status $TESTPOOL "scan" "repaired 0B" + log_must check_pool_status $TESTPOOL "scan" "with 0 errors" # Distributed spare in mirror with original device still online log_must check_vdev_state $TESTPOOL $BASEDIR/vdev9 "ONLINE" @@ -129,6 +135,9 @@ for replace_mode in "healing" "sequential"; do log_must check_vdev_state $TESTPOOL spare-9 "ONLINE" log_must check_vdev_state $TESTPOOL draid1-0-2 "ONLINE" log_must check_hotspare_state $TESTPOOL draid1-0-2 "INUSE" + log_must verify_pool $TESTPOOL + log_must check_pool_status $TESTPOOL "scan" "repaired 0B" + log_must check_pool_status $TESTPOOL "scan" "with 0 errors" # Normal faulted device replacement new_vdev0="$BASEDIR/new_vdev0" @@ -137,6 +146,9 @@ for replace_mode in "healing" "sequential"; do log_must check_vdev_state $TESTPOOL $BASEDIR/vdev0 "FAULTED" log_must zpool replace -w $flags $TESTPOOL $BASEDIR/vdev0 $new_vdev0 log_must check_vdev_state $TESTPOOL $new_vdev0 "ONLINE" + log_must verify_pool $TESTPOOL + log_must check_pool_status $TESTPOOL "scan" "repaired 0B" + log_must check_pool_status $TESTPOOL "scan" "with 0 errors" # Distributed spare faulted device replacement log_must zpool offline -f $TESTPOOL $BASEDIR/vdev2 @@ -145,6 +157,9 @@ for replace_mode in "healing" "sequential"; do log_must check_vdev_state $TESTPOOL spare-2 "DEGRADED" log_must check_vdev_state $TESTPOOL draid1-0-3 "ONLINE" log_must check_hotspare_state $TESTPOOL draid1-0-3 "INUSE" + log_must verify_pool $TESTPOOL + log_must check_pool_status $TESTPOOL "scan" "repaired 0B" + log_must check_pool_status $TESTPOOL "scan" "with 0 errors" # Normal online device replacement new_vdev1="$BASEDIR/new_vdev1" @@ -152,6 +167,9 @@ for replace_mode in "healing" "sequential"; do log_must check_vdev_state $TESTPOOL $BASEDIR/vdev1 "ONLINE" log_must zpool replace -w $flags $TESTPOOL $BASEDIR/vdev1 $new_vdev1 log_must check_vdev_state $TESTPOOL $new_vdev1 "ONLINE" + log_must verify_pool $TESTPOOL + log_must check_pool_status $TESTPOOL "scan" "repaired 0B" + log_must check_pool_status $TESTPOOL "scan" "with 0 errors" # Distributed spare online device replacement (then fault) log_must zpool replace -w $flags $TESTPOOL $BASEDIR/vdev3 draid1-0-4 @@ -161,35 +179,13 @@ for replace_mode in "healing" "sequential"; do log_must zpool offline -f $TESTPOOL $BASEDIR/vdev3 log_must check_vdev_state $TESTPOOL $BASEDIR/vdev3 "FAULTED" log_must check_vdev_state $TESTPOOL spare-3 "DEGRADED" - - resilver_cksum=$(cksum_pool $TESTPOOL) - if [[ $resilver_cksum != 0 ]]; then - log_must zpool status -v $TESTPOOL - log_fail "$replace_mode resilver cksum errors: $resilver_cksum" - fi - - if [[ "$replace_mode" = "healing" ]]; then - log_must zpool scrub -w $TESTPOOL - else - if [[ $(get_tunable REBUILD_SCRUB_ENABLED) -eq 0 ]]; then - log_must zpool scrub -w $TESTPOOL - else - log_must wait_scrubbed $TESTPOOL - fi - fi - - log_must is_pool_scrubbed $TESTPOOL - - scrub_cksum=$(cksum_pool $TESTPOOL) - if [[ $scrub_cksum != 0 ]]; then - log_must zpool status -v $TESTPOOL - log_fail "scrub cksum errors: $scrub_cksum" - fi - + log_must verify_pool $TESTPOOL log_must check_pool_status $TESTPOOL "scan" "repaired 0B" log_must check_pool_status $TESTPOOL "scan" "with 0 errors" + # Verify the original data is valid log_must is_data_valid $TESTPOOL + log_must check_pool_status $TESTPOOL "errors" "No known data errors" cleanup done diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_raidz.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_raidz.ksh index 8d32e0603ae..d7368839162 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_raidz.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_raidz.ksh @@ -23,6 +23,7 @@ # # Copyright (c) 2020 by vStack. All rights reserved. # Copyright (c) 2021 by Delphix. All rights reserved. +# Copyright (c) 2021 by Lawrence Livermore National Security, LLC. # . $STF_SUITE/include/libtest.shlib @@ -37,6 +38,7 @@ # 2. For each parity value [1..3] # - create raidz pool # - fill it with some directories/files +# - verify self-healing by overwriting devices # - verify resilver by replacing devices # - verify scrub by zeroing devices # - destroy the raidz pool @@ -59,6 +61,54 @@ function cleanup set_tunable32 PREFETCH_DISABLE $prefetch_disable } +function test_selfheal # +{ + typeset pool=$1 + typeset nparity=$2 + typeset dir=$3 + + log_must zpool export $pool + + for (( i=0; i<$nparity; i=i+1 )); do + log_must dd conv=notrunc if=/dev/zero of=$dir/dev-$i \ + bs=1M seek=4 count=$(($dev_size_mb-4)) + done + + log_must zpool import -o cachefile=none -d $dir $pool + + typeset mntpnt=$(get_prop mountpoint $pool/fs) + log_must find $mntpnt -type f -exec cksum {} + >> /dev/null 2>&1 + log_must check_pool_status $pool "errors" "No known data errors" + + # + # Scrub the pool because the find command will only self-heal blocks + # from the files which were read. Before overwriting additional + # devices we need to repair all of the blocks in the pool. + # + log_must zpool scrub -w $pool + log_must check_pool_status $pool "errors" "No known data errors" + + log_must zpool clear $pool + + log_must zpool export $pool + + for (( i=$nparity; i<$nparity*2; i=i+1 )); do + log_must dd conv=notrunc if=/dev/zero of=$dir/dev-$i \ + bs=1M seek=4 count=$(($dev_size_mb-4)) + done + + log_must zpool import -o cachefile=none -d $dir $pool + + typeset mntpnt=$(get_prop mountpoint $pool/fs) + log_must find $mntpnt -type f -exec cksum {} + >> /dev/null 2>&1 + log_must check_pool_status $pool "errors" "No known data errors" + + log_must zpool scrub -w $pool + log_must check_pool_status $pool "errors" "No known data errors" + + log_must zpool clear $pool +} + function test_resilver # { typeset pool=$1 @@ -121,7 +171,6 @@ function test_scrub # typeset pool=$1 typeset nparity=$2 typeset dir=$3 - typeset combrec=$4 log_must zpool export $pool @@ -189,6 +238,7 @@ for nparity in 1 2 3; do log_must check_pool_status $TESTPOOL "errors" "No known data errors" + test_selfheal $TESTPOOL $nparity $dir test_resilver $TESTPOOL $nparity $dir test_scrub $TESTPOOL $nparity $dir diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_stripe.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_stripe.ksh index 7ee51051ea1..b2c4a85febe 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_stripe.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy_stripe.ksh @@ -57,6 +57,8 @@ setup_test_env $TESTPOOL "" $cnt damage_devs $TESTPOOL 1 "keep_label" log_must zpool scrub -w $TESTPOOL -log_mustnot is_healthy $TESTPOOL +if is_healthy $TESTPOOL ; then + log_fail "$pool should not be healthy." +fi log_pass "Striped pool has no data redundancy as expected." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/removal/removal_condense_export.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/removal/removal_condense_export.ksh index 7648900acf1..8de17ff2e8a 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/removal/removal_condense_export.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/removal/removal_condense_export.ksh @@ -24,6 +24,7 @@ function reset { log_must set_tunable64 CONDENSE_INDIRECT_COMMIT_ENTRY_DELAY_MS 0 + log_must set_tunable64 CONDENSE_INDIRECT_OBSOLETE_PCT 25 log_must set_tunable64 CONDENSE_MIN_MAPPING_BYTES 131072 default_cleanup_noexit } @@ -31,6 +32,7 @@ function reset default_setup_noexit "$DISKS" "true" log_onexit reset log_must set_tunable64 CONDENSE_INDIRECT_COMMIT_ENTRY_DELAY_MS 5000 +log_must set_tunable64 CONDENSE_INDIRECT_OBSOLETE_PCT 5 log_must set_tunable64 CONDENSE_MIN_MAPPING_BYTES 1 log_must zfs set recordsize=512 $TESTPOOL/$TESTFS diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/removal/removal_with_export.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/removal/removal_with_export.ksh index 0ec358aadba..f76f76d34f5 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/removal/removal_with_export.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/removal/removal_with_export.ksh @@ -26,7 +26,7 @@ log_onexit default_cleanup_noexit function callback { - is_linux && test_removal_with_operation_kill + test_removal_with_operation_kill log_must zpool export $TESTPOOL # diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/replacement/attach_multiple.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/replacement/attach_multiple.ksh index b3192b2bfbd..5c383534917 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/replacement/attach_multiple.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/replacement/attach_multiple.ksh @@ -44,7 +44,7 @@ function cleanup rm -f ${VDEV_FILES[@]} } -log_assert "Verify attach/detech with multiple vdevs" +log_assert "Verify attach/detach with multiple vdevs" ORIG_SCAN_SUSPEND_PROGRESS=$(get_tunable SCAN_SUSPEND_PROGRESS) @@ -79,7 +79,7 @@ for replace_mode in "healing" "sequential"; do ${VDEV_FILES[1]} ${VDEV_FILES[2]} log_must is_pool_resilvering $TESTPOOL1 - # Original vdev cannot be detached until there is sufficent redundancy. + # Original vdev cannot be detached until there is sufficient redundancy. log_mustnot zpool detach $TESTPOOL1 ${VDEV_FILES[0]} # Detach first vdev (resilver keeps running) @@ -108,4 +108,4 @@ for replace_mode in "healing" "sequential"; do log_must zpool wait $TESTPOOL1 done -log_pass "Verify attach/detech with multiple vdevs" +log_pass "Verify attach/detach with multiple vdevs" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/replacement/replace_import.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/replacement/replace_import.ksh index 35d51d93938..37d3c6645c3 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/replacement/replace_import.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/replacement/replace_import.ksh @@ -26,7 +26,7 @@ # Strategy: # 1. For both healing and sequential resilvering replace: # a. Create a pool -# b. Repalce a vdev with 'zpool replace' to resilver (-s) it. +# b. Replace a vdev with 'zpool replace' to resilver (-s) it. # c. Export the pool # d. Import the pool # e. Verify the 'zpool replace' resumed resilvering. diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/replacement/resilver_restart_001.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/replacement/resilver_restart_001.ksh index 7896b2dbe1d..7e96ab51877 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/replacement/resilver_restart_001.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/replacement/resilver_restart_001.ksh @@ -36,7 +36,7 @@ # a. Replace a vdev with a spare & suspend resilver immediately # b. Verify resilver starts properly # c. Offline / online another vdev to introduce a new DTL range -# d. Verify resilver restart restart or defer +# d. Verify resilver restart or defer # e. Inject read errors on vdev that was offlined / onlned # f. Verify that resilver did not restart # g. Unsuspend resilver and wait for it to finish diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/reservation/reservation_006_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/reservation/reservation_006_pos.ksh index ec1986c4547..da0d36a35d3 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/reservation/reservation_006_pos.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/reservation/reservation_006_pos.ksh @@ -39,7 +39,7 @@ # for a dataset. Unlike quotas however there should be no restrictions # on accessing space outside of the limits of the reservation (if the # space is available in the pool). Verify that in a filesystem with a -# reservation set that its possible to create files both within the +# reservation set that it's possible to create files both within the # reserved space and also outside. # # STRATEGY: diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh index f89cb3b31be..1fd21cbf7ef 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh @@ -84,7 +84,7 @@ log_must mkdir -p /$TESTPOOL/$TESTFS2/xattrsadir log_must zfs set xattr=sa $TESTPOOL/$TESTFS2 log_must xattrtest -f 10 -x 3 -s 32768 -r -k -p /$TESTPOOL/$TESTFS2/xattrsadir -# ZoL issue #7432 +# OpenZFS issue #7432 log_must zfs set compression=on xattr=sa $TESTPOOL/$TESTFS2 log_must touch /$TESTPOOL/$TESTFS2/attrs log_must eval "python -c 'print \"a\" * 4096' | \ diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/cleanup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/cleanup.ksh index ac301f386f7..92bc4aa59d8 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/cleanup.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/cleanup.ksh @@ -34,10 +34,6 @@ verify_runnable "global" -if ! verify_slog_support ; then - log_unsupported "This system doesn't support separate intent logs" -fi - if datasetexists $TESTPOOL ; then log_must zpool destroy -f $TESTPOOL fi diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/setup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/setup.ksh index 8e8d214d823..4278fc69786 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/setup.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/setup.ksh @@ -34,8 +34,4 @@ verify_runnable "global" -if ! verify_slog_support ; then - log_unsupported "This system doesn't support separate intent logs" -fi - log_pass diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/Makefile.am index 2c94d3e1521..9100e4adadc 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/Makefile.am +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/Makefile.am @@ -21,8 +21,7 @@ dist_pkgdata_SCRIPTS = \ userspace_001_pos.ksh \ userspace_002_pos.ksh \ userspace_003_pos.ksh \ - userspace_encrypted.ksh \ - userspace_send_encrypted.ksh + userspace_encrypted.ksh dist_pkgdata_DATA = \ userquota.cfg \ diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/userspace_send_encrypted.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/userspace_send_encrypted.ksh deleted file mode 100755 index fbd2cc99b55..00000000000 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/userspace_send_encrypted.ksh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/ksh -p -# -# This file and its contents are supplied under the terms of the -# Common Development and Distribution License ("CDDL"), version 1.0. -# You may only use this file in accordance with the terms of version -# 1.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. -# - -# -# Copyright 2020, George Amanakis . All rights reserved. -# - -. $STF_SUITE/include/libtest.shlib -. $STF_SUITE/tests/functional/userquota/userquota_common.kshlib - -# -# DESCRIPTION: -# Sending raw encrypted datasets back to the source dataset succeeds. -# -# -# STRATEGY: -# 1. Create encrypted source dataset, set userquota and write a file -# 2. Create base and an additional snapshot (s1) -# 3. Unmount the source dataset -# 4. Raw send the base snapshot to a new target dataset -# 5. Raw send incrementally the s1 snapshot to the new target dataset -# 6. Mount both source and target datasets -# 7. Verify encrypted datasets support 'zfs userspace' and 'zfs groupspace' -# and the accounting is done correctly -# - -function cleanup -{ - destroy_pool $POOLNAME - rm -f $FILEDEV -} - -function log_must_unsupported -{ - log_must_retry "unsupported" 3 "$@" - (( $? != 0 )) && log_fail -} - -log_onexit cleanup - -FILEDEV="$TEST_BASE_DIR/userspace_encrypted" -POOLNAME="testpool$$" -ENC_SOURCE="$POOLNAME/source" -ENC_TARGET="$POOLNAME/target" - -log_assert "Sending raw encrypted datasets back to the source dataset succeeds." - -# Setup -truncate -s 200m $FILEDEV -log_must zpool create -o feature@encryption=enabled $POOLNAME \ - $FILEDEV - -# Create encrypted source dataset -log_must eval "echo 'password' | zfs create -o encryption=on" \ - "-o keyformat=passphrase -o keylocation=prompt " \ - "$ENC_SOURCE" - -# Set user quota and write file -log_must zfs set userquota@$QUSER1=50m $ENC_SOURCE -mkmount_writable $ENC_SOURCE -mntpnt=$(get_prop mountpoint $ENC_SOURCE) -log_must user_run $QUSER1 mkfile 20m /$mntpnt/file -sync - -# Snapshot, raw send to new dataset -log_must zfs snap $ENC_SOURCE@base -log_must zfs snap $ENC_SOURCE@s1 -log_must zfs umount $ENC_SOURCE -log_must eval "zfs send -w $ENC_SOURCE@base | zfs recv " \ - "$ENC_TARGET" - -log_must eval "zfs send -w -i @base $ENC_SOURCE@s1 | zfs recv " \ - "$ENC_TARGET" - -log_must zfs destroy $ENC_SOURCE@s1 -log_must eval "zfs send -w -i @base $ENC_TARGET@s1 | zfs recv " \ - "$ENC_SOURCE" - -# Mount encrypted datasets and verify they support 'zfs userspace' and -# 'zfs groupspace' and the accounting is done correctly -log_must zfs mount $ENC_SOURCE -log_must eval "echo password | zfs load-key $ENC_TARGET" -log_must zfs mount $ENC_TARGET -sync - -src_uspace=$(( $(zfs userspace -Hp $ENC_SOURCE | grep $QUSER1 | \ - awk '{print $4}')/1024/1024)) -tgt_uspace=$(( $(zfs userspace -Hp $ENC_TARGET | grep $QUSER1 | \ - awk '{print $4}')/1024/1024)) -log_must test "$src_uspace" -eq "$tgt_uspace" - -src_uquota=$(zfs userspace -Hp $ENC_SOURCE | grep $QUSER1 | awk '{print $5}') -tgt_uquota=$(zfs userspace -Hp $ENC_TARGET | grep $QUSER1 | awk '{print $5}') -log_must test "$src_uquota" -eq "$tgt_uquota" - -# Cleanup -cleanup - -log_pass "Sending raw encrypted datasets back to the source dataset succeeds." diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/xattr/xattr_002_neg.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/xattr/xattr_002_neg.ksh index e379d1586ea..4393774cb1a 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/xattr/xattr_002_neg.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/xattr/xattr_002_neg.ksh @@ -57,6 +57,6 @@ for arg in ${args[*]}; do # create a file log_must touch $TESTDIR/myfile.$$ log_mustnot eval "cat $TESTDIR/myfile.$$ not-here.txt > /dev/null 2>&1" - - log_pass "A read of a non-existent xattr fails" done + +log_pass "A read of a non-existent xattr fails" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/perf/scripts/prefetch_io.sh b/sys/contrib/openzfs/tests/zfs-tests/tests/perf/scripts/prefetch_io.sh index b8d8ae8859d..07688ef21b5 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/perf/scripts/prefetch_io.sh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/perf/scripts/prefetch_io.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +# shellcheck disable=SC1004 # # This file and its contents are supplied under the terms of the @@ -24,38 +25,37 @@ zfs_kstats="/proc/spl/kstat/zfs" function get_prefetch_ios { - typeset -l data_misses=`awk '$1 == "prefetch_data_misses" \ - { print $3 }' $zfs_kstats/arcstats` - typeset -l metadata_misses=`awk '$1 == "prefetch_metadata_misses" \ - { print $3 }' $zfs_kstats/arcstats` - typeset -l total_misses=$(( $data_misses + $metadata_misses )) + typeset -l data_misses="$(awk '$1 == "prefetch_data_misses" \ + { print $3; exit }' "$zfs_kstats/arcstats")" + typeset -l metadata_misses="$(awk '$1 == "prefetch_metadata_misses" \ + { print $3; exit }' "$zfs_kstats/arcstats")" + typeset -l total_misses=$(( data_misses + metadata_misses )) - echo $total_misses + echo "$total_misses" } function get_prefetched_demand_reads { - typeset -l demand_reads=`awk '$1 == "demand_hit_predictive_prefetch" \ - { print $3 }' $zfs_kstats/arcstats` + typeset -l demand_reads="$(awk '$1 == "demand_hit_predictive_prefetch" \ + { print $3; exit }' "$zfs_kstats/arcstats")" - echo $demand_reads + echo "$demand_reads" } function get_async_upgrade_sync { - typeset -l sync_wait=`awk '$1 == "async_upgrade_sync" \ - { print $3 }' $zfs_kstats/arcstats` + typeset -l sync_wait="$(awk '$1 == "async_upgrade_sync" \ + { print $3; exit }' "$zfs_kstats/arcstats")" - echo $sync_wait + echo "$sync_wait" } if [ $# -ne 2 ] then - echo "Usage: `basename $0` interval" >&2 + echo "Usage: ${0##*/} poolname interval" >&2 exit 1 fi -poolname=$1 interval=$2 prefetch_ios=$(get_prefetch_ios) prefetched_demand_reads=$(get_prefetched_demand_reads) @@ -64,19 +64,19 @@ async_upgrade_sync=$(get_async_upgrade_sync) while true do new_prefetch_ios=$(get_prefetch_ios) - printf "%u\n%-24s\t%u\n" $(date +%s) "prefetch_ios" \ - $(( $new_prefetch_ios - $prefetch_ios )) + printf '%u\n%-24s\t%u\n' "$(date +%s)" "prefetch_ios" \ + $(( new_prefetch_ios - prefetch_ios )) prefetch_ios=$new_prefetch_ios new_prefetched_demand_reads=$(get_prefetched_demand_reads) - printf "%-24s\t%u\n" "prefetched_demand_reads" \ - $(( $new_prefetched_demand_reads - $prefetched_demand_reads )) + printf '%-24s\t%u\n' "prefetched_demand_reads" \ + $(( new_prefetched_demand_reads - prefetched_demand_reads )) prefetched_demand_reads=$new_prefetched_demand_reads new_async_upgrade_sync=$(get_async_upgrade_sync) - printf "%-24s\t%u\n" "async_upgrade_sync" \ - $(( $new_async_upgrade_sync - $async_upgrade_sync )) + printf '%-24s\t%u\n' "async_upgrade_sync" \ + $(( new_async_upgrade_sync - async_upgrade_sync )) async_upgrade_sync=$new_async_upgrade_sync - sleep $interval + sleep "$interval" done diff --git a/sys/contrib/openzfs/udev/rules.d/.gitignore b/sys/contrib/openzfs/udev/rules.d/.gitignore index e7f7be8f380..aba25616f5e 100644 --- a/sys/contrib/openzfs/udev/rules.d/.gitignore +++ b/sys/contrib/openzfs/udev/rules.d/.gitignore @@ -1,4 +1 @@ -69-vdev.rules -60-zpool.rules -60-zvol.rules -90-zfs.rules +*.rules diff --git a/sys/modules/zfs/zfs_config.h b/sys/modules/zfs/zfs_config.h index ebc9bbe9059..1400d9fe92c 100644 --- a/sys/modules/zfs/zfs_config.h +++ b/sys/modules/zfs/zfs_config.h @@ -734,7 +734,7 @@ /* #undef ZFS_IS_GPL_COMPATIBLE */ /* Define the project alias string. */ -#define ZFS_META_ALIAS "zfs-2.1.0-FreeBSD_g3522f57b6" +#define ZFS_META_ALIAS "zfs-2.1.99-FreeBSD_g75b4cbf62" /* Define the project author. */ #define ZFS_META_AUTHOR "OpenZFS" @@ -764,10 +764,10 @@ #define ZFS_META_NAME "zfs" /* Define the project release. */ -#define ZFS_META_RELEASE "FreeBSD_g3522f57b6" +#define ZFS_META_RELEASE "FreeBSD_g75b4cbf62" /* Define the project version. */ -#define ZFS_META_VERSION "2.1.0" +#define ZFS_META_VERSION "2.1.99" /* count is located in percpu_ref.data */ /* #undef ZFS_PERCPU_REF_COUNT_IN_DATA */